circuit-to-svg 0.0.152 → 0.0.153

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
@@ -2527,197 +2527,27 @@ function drawSchematicLabeledPoints(params) {
2527
2527
  };
2528
2528
  }
2529
2529
 
2530
- // lib/sch/get-schematic-bounds-from-circuit-json.ts
2531
- function getSchematicBoundsFromCircuitJson(soup, padding = 0.5) {
2532
- let minX = Number.POSITIVE_INFINITY;
2533
- let minY = Number.POSITIVE_INFINITY;
2534
- let maxX = Number.NEGATIVE_INFINITY;
2535
- let maxY = Number.NEGATIVE_INFINITY;
2536
- const portSize = 0.2;
2537
- for (const item of soup) {
2538
- if (item.type === "schematic_component") {
2539
- updateBounds(item.center, item.size, 0);
2540
- } else if (item.type === "schematic_port") {
2541
- updateBounds(item.center, { width: portSize, height: portSize }, 0);
2542
- } else if (item.type === "schematic_debug_object") {
2543
- if (item.shape === "rect") {
2544
- updateBounds(item.center, item.size, 0);
2545
- } else if (item.shape === "line") {
2546
- updateBounds(item.start, { width: 0.1, height: 0.1 }, 0);
2547
- updateBounds(item.end, { width: 0.1, height: 0.1 }, 0);
2548
- }
2549
- } else if (item.type === "schematic_net_label") {
2550
- updateBounds(item.center, { width: 1, height: 1 }, 0);
2551
- } else if (item.type === "schematic_trace") {
2552
- for (const edge of item.edges) {
2553
- updateBounds(edge.from, { width: 0.1, height: 0.1 }, 0);
2554
- updateBounds(edge.to, { width: 0.1, height: 0.1 }, 0);
2555
- }
2556
- } else if (item.type === "schematic_text") {
2557
- const textType = "reference_designator";
2558
- const fontSize = getSchMmFontSize(textType, item.font_size) ?? 0.18;
2559
- const text = item.text ?? "";
2560
- const width = text.length * fontSize;
2561
- const height = fontSize;
2562
- updateBounds(item.position, { width, height }, item.rotation ?? 0);
2563
- } else if (item.type === "schematic_voltage_probe") {
2564
- updateBounds(item.position, { width: 0.2, height: 0.4 }, 0);
2565
- } else if (item.type === "schematic_box") {
2566
- updateBounds(
2567
- {
2568
- x: item.x + item.width / 2,
2569
- y: item.y + item.height / 2
2570
- },
2571
- { width: item.width, height: item.height },
2572
- 0
2573
- );
2574
- }
2575
- }
2576
- minX -= padding;
2577
- minY -= padding;
2578
- maxX += padding;
2579
- maxY += padding;
2580
- return { minX, minY, maxX, maxY };
2581
- function updateBounds(center, size, rotation) {
2582
- const corners = [
2583
- { x: -size.width / 2, y: -size.height / 2 },
2584
- { x: size.width / 2, y: -size.height / 2 },
2585
- { x: size.width / 2, y: size.height / 2 },
2586
- { x: -size.width / 2, y: size.height / 2 }
2587
- ];
2588
- for (const corner of corners) {
2589
- const rotatedX = corner.x * Math.cos(rotation) - corner.y * Math.sin(rotation) + center.x;
2590
- const rotatedY = corner.x * Math.sin(rotation) + corner.y * Math.cos(rotation) + center.y;
2591
- minX = Math.min(minX, rotatedX);
2592
- minY = Math.min(minY, rotatedY);
2593
- maxX = Math.max(maxX, rotatedX);
2594
- maxY = Math.max(maxY, rotatedY);
2595
- }
2596
- }
2597
- }
2598
-
2599
- // lib/sch/svg-object-fns/create-svg-objects-from-sch-component-with-symbol.ts
2600
- import { su as su4 } from "@tscircuit/circuit-json-util";
2601
- import { symbols } from "schematic-symbols";
2602
- import "svgson";
2603
- import {
2604
- applyToPoint as applyToPoint26,
2605
- compose as compose7
2606
- } from "transformation-matrix";
2607
-
2608
- // lib/utils/get-sch-stroke-size.ts
2609
- var getSchStrokeSize = (transform) => {
2610
- return Math.abs(transform.a) * 0.02;
2611
- };
2612
-
2613
- // lib/utils/match-sch-ports-with-symbol-ports.ts
2614
- var getAngularDifference = (angle1, angle2) => {
2615
- const a1 = angle1 < 0 ? angle1 + 2 * Math.PI : angle1;
2616
- const a2 = angle2 < 0 ? angle2 + 2 * Math.PI : angle2;
2617
- let diff = Math.abs(a1 - a2);
2618
- if (diff > Math.PI) {
2619
- diff = 2 * Math.PI - diff;
2620
- }
2621
- return diff;
2622
- };
2623
- var matchSchPortsToSymbolPorts = ({
2624
- schPorts,
2625
- symbol,
2626
- schComponent
2627
- }) => {
2628
- const schPortAngles = schPorts.map((port) => {
2629
- const dx = port.center.x - schComponent.center.x;
2630
- const dy = port.center.y - schComponent.center.y;
2631
- return {
2632
- port,
2633
- angle: Math.atan2(dy, dx)
2634
- };
2635
- });
2636
- const symbolPortAngles = symbol.ports.map((port) => {
2637
- const dx = port.x - symbol.center.x;
2638
- const dy = port.y - symbol.center.y;
2639
- return {
2640
- port,
2641
- angle: Math.atan2(dy, dx)
2642
- };
2643
- });
2644
- schPortAngles.sort((a, b) => a.angle - b.angle);
2645
- symbolPortAngles.sort((a, b) => a.angle - b.angle);
2646
- const matches = [];
2647
- const usedSymbolPorts = /* @__PURE__ */ new Set();
2648
- for (const schPortAngle of schPortAngles) {
2649
- let bestMatch = null;
2650
- for (const symbolPortAngle of symbolPortAngles) {
2651
- if (usedSymbolPorts.has(symbolPortAngle.port)) continue;
2652
- const angleDiff = getAngularDifference(
2653
- schPortAngle.angle,
2654
- symbolPortAngle.angle
2655
- );
2656
- if (bestMatch === null || angleDiff < bestMatch.angleDiff) {
2657
- bestMatch = {
2658
- symbolPort: symbolPortAngle.port,
2659
- angleDiff
2660
- };
2661
- }
2662
- }
2663
- if (bestMatch && bestMatch.angleDiff < Math.PI / 4) {
2664
- matches.push({
2665
- schPort: schPortAngle.port,
2666
- symbolPort: bestMatch.symbolPort
2667
- });
2668
- usedSymbolPorts.add(bestMatch.symbolPort);
2669
- }
2530
+ // lib/utils/get-unit-vector-from-outside-to-edge.ts
2531
+ var getUnitVectorFromOutsideToEdge = (side) => {
2532
+ switch (side) {
2533
+ case "top":
2534
+ return { x: 0, y: -1 };
2535
+ case "bottom":
2536
+ return { x: 0, y: 1 };
2537
+ case "left":
2538
+ return { x: 1, y: 0 };
2539
+ case "right":
2540
+ return { x: -1, y: 0 };
2670
2541
  }
2671
- return matches;
2672
- };
2673
-
2674
- // lib/utils/point-pairs-to-matrix.ts
2675
- import { compose as compose6, scale as scale4, translate as translate6 } from "transformation-matrix";
2676
- function pointPairsToMatrix(a1, a2, b1, b2) {
2677
- const tx = a2.x - a1.x;
2678
- const ty = a2.y - a1.y;
2679
- const originalDistance = Math.sqrt((b1.x - a1.x) ** 2 + (b1.y - a1.y) ** 2);
2680
- const transformedDistance = Math.sqrt((b2.x - a2.x) ** 2 + (b2.y - a2.y) ** 2);
2681
- const a = transformedDistance / originalDistance;
2682
- const translateMatrix = translate6(tx, ty);
2683
- const scaleMatrix = scale4(a, a);
2684
- return compose6(translateMatrix, scaleMatrix);
2685
- }
2686
-
2687
- // lib/sch/svg-object-fns/create-svg-error-text.ts
2688
- import { applyToPoint as applyToPoint25 } from "transformation-matrix";
2689
- var createSvgSchErrorText = ({
2690
- text,
2691
- realCenter,
2692
- realToScreenTransform
2693
- }) => {
2694
- const screenCenter = applyToPoint25(realToScreenTransform, realCenter);
2695
- return {
2696
- type: "element",
2697
- name: "text",
2698
- value: "",
2699
- attributes: {
2700
- x: screenCenter.x.toString(),
2701
- y: screenCenter.y.toString(),
2702
- fill: "red",
2703
- "text-anchor": "middle",
2704
- "dominant-baseline": "middle",
2705
- "font-family": "sans-serif",
2706
- "font-size": `${getSchScreenFontSize(realToScreenTransform, "error")}px`
2707
- },
2708
- children: [
2709
- {
2710
- type: "text",
2711
- value: text,
2712
- name: "",
2713
- attributes: {},
2714
- children: []
2715
- }
2716
- ]
2717
- };
2542
+ throw new Error(`Invalid side: ${side}`);
2718
2543
  };
2719
2544
 
2720
- // lib/sch/svg-object-fns/create-svg-objects-from-sch-component-with-symbol.ts
2545
+ // lib/utils/net-label-utils.ts
2546
+ import "transformation-matrix";
2547
+ import "schematic-symbols";
2548
+ var ARROW_POINT_WIDTH_FSR = 0.3;
2549
+ var END_PADDING_FSR = 0.3;
2550
+ var END_PADDING_EXTRA_PER_CHARACTER_FSR = 0.06;
2721
2551
  var ninePointAnchorToTextAnchor = {
2722
2552
  top_left: "start",
2723
2553
  top_right: "end",
@@ -2729,923 +2559,36 @@ var ninePointAnchorToTextAnchor = {
2729
2559
  middle_top: "middle",
2730
2560
  middle_bottom: "middle"
2731
2561
  };
2732
- var createSvgObjectsFromSchematicComponentWithSymbol = ({
2733
- component: schComponent,
2734
- transform: realToScreenTransform,
2735
- circuitJson,
2736
- colorMap: colorMap2
2737
- }) => {
2738
- const svgObjects = [];
2739
- const symbol = symbols[schComponent.symbol_name];
2740
- if (!symbol) {
2741
- return [
2742
- createSvgSchErrorText({
2743
- text: `Symbol not found: ${schComponent.symbol_name}`,
2744
- realCenter: schComponent.center,
2745
- realToScreenTransform
2746
- })
2747
- ];
2748
- }
2749
- const schPorts = su4(circuitJson).schematic_port.list({
2750
- schematic_component_id: schComponent.schematic_component_id
2751
- });
2752
- const srcComponent = su4(circuitJson).source_component.get(
2753
- schComponent.source_component_id
2562
+ var ninePointAnchorToDominantBaseline = {
2563
+ top_left: "hanging",
2564
+ top_right: "hanging",
2565
+ bottom_left: "ideographic",
2566
+ bottom_right: "ideographic",
2567
+ center: "middle",
2568
+ middle_left: "middle",
2569
+ middle_right: "middle",
2570
+ middle_top: "hanging",
2571
+ middle_bottom: "ideographic"
2572
+ };
2573
+ function getPathRotation(anchorSide) {
2574
+ const rotationMap = {
2575
+ left: 180,
2576
+ top: 90,
2577
+ bottom: -90,
2578
+ right: 0
2579
+ };
2580
+ return rotationMap[anchorSide] ?? 0;
2581
+ }
2582
+ function calculateAnchorPosition(schNetLabel, fontSizeMm, textWidthFSR) {
2583
+ const fullWidthFsr = textWidthFSR + ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_EXTRA_PER_CHARACTER_FSR * schNetLabel.text.length + END_PADDING_FSR;
2584
+ const realTextGrowthVec = getUnitVectorFromOutsideToEdge(
2585
+ schNetLabel.anchor_side
2754
2586
  );
2755
- const schPortsWithSymbolPorts = matchSchPortsToSymbolPorts({
2756
- schPorts,
2757
- symbol,
2758
- schComponent
2759
- });
2760
- if (!schPortsWithSymbolPorts[0]) {
2761
- return [
2762
- createSvgSchErrorText({
2763
- text: `Could not match ports for symbol ${schComponent.symbol_name}`,
2764
- realCenter: schComponent.center,
2765
- realToScreenTransform
2766
- })
2767
- ];
2768
- }
2769
- const transformFromSymbolToReal = pointPairsToMatrix(
2770
- schPortsWithSymbolPorts[1]?.symbolPort ?? symbol.center,
2771
- schPortsWithSymbolPorts[1]?.schPort.center ?? schComponent.center,
2772
- schPortsWithSymbolPorts[0].symbolPort,
2773
- schPortsWithSymbolPorts[0].schPort.center
2774
- );
2775
- const paths = symbol.primitives.filter((p) => p.type === "path");
2776
- const texts = symbol.primitives.filter((p) => p.type === "text");
2777
- const circles = symbol.primitives.filter((p) => p.type === "circle");
2778
- const boxes = symbol.primitives.filter((p) => p.type === "box");
2779
- const bounds = {
2780
- minX: Math.min(...paths.flatMap((p) => p.points.map((pt) => pt.x))),
2781
- maxX: Math.max(...paths.flatMap((p) => p.points.map((pt) => pt.x))),
2782
- minY: Math.min(...paths.flatMap((p) => p.points.map((pt) => pt.y))),
2783
- maxY: Math.max(...paths.flatMap((p) => p.points.map((pt) => pt.y)))
2587
+ return schNetLabel.anchor_position ?? {
2588
+ x: schNetLabel.center.x - realTextGrowthVec.x * fullWidthFsr * fontSizeMm / 2,
2589
+ y: schNetLabel.center.y - realTextGrowthVec.y * fullWidthFsr * fontSizeMm / 2
2784
2590
  };
2785
- const [screenMinX, screenMinY] = applyToPoint26(
2786
- compose7(realToScreenTransform, transformFromSymbolToReal),
2787
- [bounds.minX, bounds.minY]
2788
- );
2789
- const [screenMaxX, screenMaxY] = applyToPoint26(
2790
- compose7(realToScreenTransform, transformFromSymbolToReal),
2791
- [bounds.maxX, bounds.maxY]
2792
- );
2793
- const rectHeight = Math.abs(screenMaxY - screenMinY);
2794
- const rectY = Math.min(screenMinY, screenMaxY);
2795
- const rectWidth = Math.abs(screenMaxX - screenMinX);
2796
- const rectX = Math.min(screenMinX, screenMaxX);
2797
- svgObjects.push({
2798
- name: "rect",
2799
- type: "element",
2800
- value: "",
2801
- attributes: {
2802
- class: "component-overlay",
2803
- x: rectX.toString(),
2804
- y: rectY.toString(),
2805
- width: rectWidth.toString(),
2806
- height: rectHeight.toString(),
2807
- fill: "transparent"
2808
- },
2809
- children: []
2810
- });
2811
- for (const path of paths) {
2812
- const { points, color, closed, fill } = path;
2813
- svgObjects.push({
2814
- type: "element",
2815
- name: "path",
2816
- attributes: {
2817
- d: points.map((p, i) => {
2818
- const [x, y] = applyToPoint26(
2819
- compose7(realToScreenTransform, transformFromSymbolToReal),
2820
- [p.x, p.y]
2821
- );
2822
- return `${i === 0 ? "M" : "L"} ${x} ${y}`;
2823
- }).join(" ") + (closed ? " Z" : ""),
2824
- stroke: colorMap2.schematic.component_outline,
2825
- fill: "none",
2826
- "stroke-width": `${getSchStrokeSize(realToScreenTransform)}px`
2827
- },
2828
- value: "",
2829
- children: []
2830
- });
2831
- }
2832
- for (const text of texts) {
2833
- const screenTextPos = applyToPoint26(
2834
- compose7(realToScreenTransform, transformFromSymbolToReal),
2835
- text
2836
- );
2837
- let textValue = "";
2838
- if (text.text === "{REF}") {
2839
- textValue = srcComponent?.name ?? "";
2840
- } else if (text.text === "{VAL}") {
2841
- textValue = schComponent.symbol_display_value ?? "";
2842
- }
2843
- const symbolHeight = Math.abs(bounds.maxY - bounds.minY);
2844
- const offsetFactor = 0.1;
2845
- const baseOffset = symbolHeight * offsetFactor;
2846
- const transformScale = Math.abs(transformFromSymbolToReal.a);
2847
- let verticalOffset = 0;
2848
- if (text.anchor.includes("bottom")) {
2849
- verticalOffset = baseOffset * transformScale;
2850
- } else if (text.anchor.includes("top")) {
2851
- verticalOffset = -baseOffset * transformScale;
2852
- }
2853
- const dominantBaseline = text.anchor.includes("bottom") ? "auto" : text.anchor.includes("top") ? "hanging" : "middle";
2854
- svgObjects.push({
2855
- name: "text",
2856
- type: "element",
2857
- attributes: {
2858
- x: screenTextPos.x.toString(),
2859
- y: (screenTextPos.y + verticalOffset).toString(),
2860
- fill: colorMap2.schematic.label_local,
2861
- "font-family": "sans-serif",
2862
- "text-anchor": ninePointAnchorToTextAnchor[text.anchor],
2863
- "dominant-baseline": dominantBaseline,
2864
- "font-size": `${getSchScreenFontSize(realToScreenTransform, "reference_designator")}px`
2865
- },
2866
- value: "",
2867
- children: [
2868
- {
2869
- type: "text",
2870
- value: textValue,
2871
- name: "",
2872
- attributes: {},
2873
- children: []
2874
- }
2875
- ]
2876
- });
2877
- }
2878
- for (const box of boxes) {
2879
- const screenBoxPos = applyToPoint26(
2880
- compose7(realToScreenTransform, transformFromSymbolToReal),
2881
- box
2882
- );
2883
- const symbolToScreenScale = compose7(
2884
- realToScreenTransform,
2885
- transformFromSymbolToReal
2886
- ).a;
2887
- svgObjects.push({
2888
- name: "rect",
2889
- type: "element",
2890
- attributes: {
2891
- x: screenBoxPos.x.toString(),
2892
- y: screenBoxPos.y.toString(),
2893
- width: (box.width * symbolToScreenScale).toString(),
2894
- height: (box.height * symbolToScreenScale).toString(),
2895
- fill: "red"
2896
- },
2897
- value: "",
2898
- children: []
2899
- });
2900
- }
2901
- for (const port of symbol.ports) {
2902
- const screenPortPos = applyToPoint26(
2903
- compose7(realToScreenTransform, transformFromSymbolToReal),
2904
- port
2905
- );
2906
- svgObjects.push({
2907
- type: "element",
2908
- name: "circle",
2909
- attributes: {
2910
- cx: screenPortPos.x.toString(),
2911
- cy: screenPortPos.y.toString(),
2912
- r: `${Math.abs(realToScreenTransform.a) * 0.02}px`,
2913
- "stroke-width": `${getSchStrokeSize(realToScreenTransform)}px`,
2914
- fill: "none",
2915
- stroke: colorMap2.schematic.component_outline
2916
- },
2917
- value: "",
2918
- children: []
2919
- });
2920
- }
2921
- for (const circle of circles) {
2922
- const screenCirclePos = applyToPoint26(
2923
- compose7(realToScreenTransform, transformFromSymbolToReal),
2924
- circle
2925
- );
2926
- const screenRadius = Math.abs(circle.radius * realToScreenTransform.a);
2927
- svgObjects.push({
2928
- type: "element",
2929
- name: "circle",
2930
- attributes: {
2931
- cx: screenCirclePos.x.toString(),
2932
- cy: screenCirclePos.y.toString(),
2933
- r: `${screenRadius}px`,
2934
- "stroke-width": `${getSchStrokeSize(realToScreenTransform)}px`,
2935
- fill: "none",
2936
- stroke: colorMap2.schematic.component_outline
2937
- },
2938
- value: "",
2939
- children: []
2940
- });
2941
- }
2942
- return svgObjects;
2943
- };
2944
-
2945
- // lib/sch/svg-object-fns/create-svg-objects-from-sch-component-with-box.ts
2946
- import { su as su7 } from "@tscircuit/circuit-json-util";
2947
- import "schematic-symbols";
2948
- import "svgson";
2949
- import { applyToPoint as applyToPoint32 } from "transformation-matrix";
2950
-
2951
- // lib/sch/svg-object-fns/create-svg-objects-from-sch-port-on-box.ts
2952
- import "transformation-matrix";
2953
- import "@tscircuit/circuit-json-util";
2954
-
2955
- // lib/sch/svg-object-fns/create-svg-objects-for-sch-port-box-line.ts
2956
- import { applyToPoint as applyToPoint27 } from "transformation-matrix";
2957
- import { su as su5 } from "@tscircuit/circuit-json-util";
2958
- var PIN_CIRCLE_RADIUS_MM = 0.02;
2959
- var createSvgObjectsForSchPortBoxLine = ({
2960
- schPort,
2961
- schComponent,
2962
- transform,
2963
- circuitJson
2964
- }) => {
2965
- const svgObjects = [];
2966
- const srcPort = su5(circuitJson).source_port.get(schPort.source_port_id);
2967
- const realEdgePos = {
2968
- x: schPort.center.x,
2969
- y: schPort.center.y
2970
- };
2971
- const realPinLineLength = schPort.distance_from_component_edge ?? 0.4;
2972
- switch (schPort.side_of_component) {
2973
- case "left":
2974
- realEdgePos.x += realPinLineLength;
2975
- break;
2976
- case "right":
2977
- realEdgePos.x -= realPinLineLength;
2978
- break;
2979
- case "top":
2980
- realEdgePos.y -= realPinLineLength;
2981
- break;
2982
- case "bottom":
2983
- realEdgePos.y += realPinLineLength;
2984
- break;
2985
- }
2986
- const screenSchPortPos = applyToPoint27(transform, schPort.center);
2987
- const screenRealEdgePos = applyToPoint27(transform, realEdgePos);
2988
- const realLineEnd = { ...schPort.center };
2989
- switch (schPort.side_of_component) {
2990
- case "left":
2991
- realLineEnd.x += PIN_CIRCLE_RADIUS_MM;
2992
- break;
2993
- case "right":
2994
- realLineEnd.x -= PIN_CIRCLE_RADIUS_MM;
2995
- break;
2996
- case "top":
2997
- realLineEnd.y -= PIN_CIRCLE_RADIUS_MM;
2998
- break;
2999
- case "bottom":
3000
- realLineEnd.y += PIN_CIRCLE_RADIUS_MM;
3001
- break;
3002
- }
3003
- const screenLineEnd = applyToPoint27(transform, realLineEnd);
3004
- svgObjects.push({
3005
- name: "line",
3006
- type: "element",
3007
- attributes: {
3008
- class: "component-pin",
3009
- x1: screenLineEnd.x.toString(),
3010
- y1: screenLineEnd.y.toString(),
3011
- x2: screenRealEdgePos.x.toString(),
3012
- y2: screenRealEdgePos.y.toString(),
3013
- "stroke-width": `${getSchStrokeSize(transform)}px`
3014
- },
3015
- value: "",
3016
- children: []
3017
- });
3018
- svgObjects.push({
3019
- name: "circle",
3020
- type: "element",
3021
- attributes: {
3022
- class: "component-pin",
3023
- cx: screenSchPortPos.x.toString(),
3024
- cy: screenSchPortPos.y.toString(),
3025
- r: (Math.abs(transform.a) * PIN_CIRCLE_RADIUS_MM).toString(),
3026
- "stroke-width": `${getSchStrokeSize(transform)}px`
3027
- },
3028
- value: "",
3029
- children: []
3030
- });
3031
- return svgObjects;
3032
- };
3033
-
3034
- // lib/utils/get-unit-vector-from-outside-to-edge.ts
3035
- var getUnitVectorFromOutsideToEdge = (side) => {
3036
- switch (side) {
3037
- case "top":
3038
- return { x: 0, y: -1 };
3039
- case "bottom":
3040
- return { x: 0, y: 1 };
3041
- case "left":
3042
- return { x: 1, y: 0 };
3043
- case "right":
3044
- return { x: -1, y: 0 };
3045
- }
3046
- throw new Error(`Invalid side: ${side}`);
3047
- };
3048
-
3049
- // lib/sch/svg-object-fns/create-svg-objects-for-sch-port-pin-number-text.ts
3050
- import { applyToPoint as applyToPoint28 } from "transformation-matrix";
3051
- var createSvgObjectsForSchPortPinNumberText = (params) => {
3052
- const svgObjects = [];
3053
- const { schPort, schComponent, transform, circuitJson } = params;
3054
- const realPinNumberPos = {
3055
- x: schPort.center.x,
3056
- y: schPort.center.y
3057
- };
3058
- if (!schPort.side_of_component) return [];
3059
- const vecToEdge = getUnitVectorFromOutsideToEdge(schPort.side_of_component);
3060
- const realPinEdgeDistance = schPort.distance_from_component_edge ?? 0.4;
3061
- realPinNumberPos.x += vecToEdge.x * realPinEdgeDistance / 2;
3062
- realPinNumberPos.y += vecToEdge.y * realPinEdgeDistance / 2;
3063
- if (schPort.side_of_component === "top" || schPort.side_of_component === "bottom") {
3064
- realPinNumberPos.x -= 0.02;
3065
- } else {
3066
- realPinNumberPos.y += 0.02;
3067
- }
3068
- const screenPinNumberTextPos = applyToPoint28(transform, realPinNumberPos);
3069
- svgObjects.push({
3070
- name: "text",
3071
- type: "element",
3072
- attributes: {
3073
- class: "pin-number",
3074
- x: screenPinNumberTextPos.x.toString(),
3075
- y: screenPinNumberTextPos.y.toString(),
3076
- style: "font-family: sans-serif;",
3077
- fill: colorMap.schematic.pin_number,
3078
- "text-anchor": "middle",
3079
- "dominant-baseline": "auto",
3080
- "font-size": `${getSchScreenFontSize(transform, "pin_number")}px`,
3081
- transform: schPort.side_of_component === "top" || schPort.side_of_component === "bottom" ? `rotate(-90 ${screenPinNumberTextPos.x} ${screenPinNumberTextPos.y})` : ""
3082
- },
3083
- children: [
3084
- {
3085
- type: "text",
3086
- value: schPort.pin_number?.toString() || "",
3087
- name: "",
3088
- attributes: {},
3089
- children: []
3090
- }
3091
- ],
3092
- value: ""
3093
- });
3094
- return svgObjects;
3095
- };
3096
-
3097
- // lib/sch/svg-object-fns/create-svg-objects-for-sch-port-pin-label.ts
3098
- import { applyToPoint as applyToPoint29 } from "transformation-matrix";
3099
- var LABEL_DIST_FROM_EDGE_MM = 0.1;
3100
- var createSvgObjectsForSchPortPinLabel = (params) => {
3101
- const svgObjects = [];
3102
- const { schPort, schComponent, transform, circuitJson } = params;
3103
- const realPinNumberPos = {
3104
- x: schPort.center.x,
3105
- y: schPort.center.y
3106
- };
3107
- if (!schPort.side_of_component) return [];
3108
- const vecToEdge = getUnitVectorFromOutsideToEdge(schPort.side_of_component);
3109
- const realPinEdgeDistance = schPort.distance_from_component_edge ?? 0.4;
3110
- realPinNumberPos.x += vecToEdge.x * (realPinEdgeDistance + LABEL_DIST_FROM_EDGE_MM);
3111
- realPinNumberPos.y += vecToEdge.y * (realPinEdgeDistance + LABEL_DIST_FROM_EDGE_MM);
3112
- const screenPinNumberTextPos = applyToPoint29(transform, realPinNumberPos);
3113
- const label = schPort.display_pin_label ?? schComponent.port_labels?.[`${schPort.pin_number}`];
3114
- if (!label) return [];
3115
- svgObjects.push({
3116
- name: "text",
3117
- type: "element",
3118
- attributes: {
3119
- class: "pin-number",
3120
- x: screenPinNumberTextPos.x.toString(),
3121
- y: screenPinNumberTextPos.y.toString(),
3122
- style: "font-family: sans-serif;",
3123
- fill: colorMap.schematic.pin_number,
3124
- "text-anchor": schPort.side_of_component === "left" || schPort.side_of_component === "bottom" ? "start" : "end",
3125
- "dominant-baseline": "middle",
3126
- "font-size": `${getSchScreenFontSize(transform, "pin_number")}px`,
3127
- transform: schPort.side_of_component === "top" || schPort.side_of_component === "bottom" ? `rotate(-90 ${screenPinNumberTextPos.x} ${screenPinNumberTextPos.y})` : ""
3128
- },
3129
- children: [
3130
- {
3131
- type: "text",
3132
- value: label || "",
3133
- name: "",
3134
- attributes: {},
3135
- children: []
3136
- }
3137
- ],
3138
- value: ""
3139
- });
3140
- return svgObjects;
3141
- };
3142
-
3143
- // lib/sch/svg-object-fns/create-svg-objects-from-sch-port-on-box.ts
3144
- var createSvgObjectsFromSchPortOnBox = (params) => {
3145
- const svgObjects = [];
3146
- const { schPort, schComponent, transform, circuitJson } = params;
3147
- svgObjects.push(...createSvgObjectsForSchPortBoxLine(params));
3148
- svgObjects.push(...createSvgObjectsForSchPortPinNumberText(params));
3149
- svgObjects.push(...createSvgObjectsForSchPortPinLabel(params));
3150
- return svgObjects;
3151
- };
3152
-
3153
- // lib/sch/svg-object-fns/create-svg-objects-for-sch-text.ts
3154
- import { applyToPoint as applyToPoint31 } from "transformation-matrix";
3155
- var createSvgSchText = ({
3156
- elm,
3157
- transform,
3158
- colorMap: colorMap2
3159
- }) => {
3160
- const center = applyToPoint31(transform, elm.position);
3161
- const textAnchorMap = {
3162
- center: "middle",
3163
- center_right: "end",
3164
- bottom_left: "start",
3165
- bottom_center: "middle",
3166
- bottom_right: "end",
3167
- left: "start",
3168
- right: "end",
3169
- top: "middle",
3170
- bottom: "middle",
3171
- top_left: "start",
3172
- top_center: "middle",
3173
- top_right: "end",
3174
- center_left: "start"
3175
- };
3176
- const dominantBaselineMap = {
3177
- center: "middle",
3178
- center_right: "middle",
3179
- bottom_left: "ideographic",
3180
- bottom_center: "ideographic",
3181
- bottom_right: "ideographic",
3182
- left: "middle",
3183
- right: "middle",
3184
- top: "hanging",
3185
- bottom: "ideographic",
3186
- top_left: "hanging",
3187
- top_center: "hanging",
3188
- top_right: "hanging",
3189
- center_left: "middle"
3190
- };
3191
- return {
3192
- type: "element",
3193
- name: "text",
3194
- value: "",
3195
- attributes: {
3196
- x: center.x.toString(),
3197
- y: center.y.toString(),
3198
- fill: elm.color ?? colorMap2.schematic.sheet_label,
3199
- "text-anchor": textAnchorMap[elm.anchor],
3200
- "dominant-baseline": dominantBaselineMap[elm.anchor],
3201
- "font-family": "sans-serif",
3202
- "font-size": `${getSchScreenFontSize(transform, "reference_designator", elm.font_size)}px`,
3203
- transform: `rotate(${elm.rotation}, ${center.x}, ${center.y})`
3204
- },
3205
- children: [
3206
- {
3207
- type: "text",
3208
- value: elm.text,
3209
- name: elm.schematic_text_id,
3210
- attributes: {},
3211
- children: []
3212
- }
3213
- ]
3214
- };
3215
- };
3216
-
3217
- // lib/sch/svg-object-fns/create-svg-objects-from-sch-component-with-box.ts
3218
- var createSvgObjectsFromSchematicComponentWithBox = ({
3219
- component: schComponent,
3220
- transform,
3221
- circuitJson,
3222
- colorMap: colorMap2
3223
- }) => {
3224
- const svgObjects = [];
3225
- const componentScreenTopLeft = applyToPoint32(transform, {
3226
- x: schComponent.center.x - schComponent.size.width / 2,
3227
- y: schComponent.center.y + schComponent.size.height / 2
3228
- });
3229
- const componentScreenBottomRight = applyToPoint32(transform, {
3230
- x: schComponent.center.x + schComponent.size.width / 2,
3231
- y: schComponent.center.y - schComponent.size.height / 2
3232
- });
3233
- const componentScreenWidth = componentScreenBottomRight.x - componentScreenTopLeft.x;
3234
- const componentScreenHeight = componentScreenBottomRight.y - componentScreenTopLeft.y;
3235
- svgObjects.push({
3236
- name: "rect",
3237
- type: "element",
3238
- value: "",
3239
- attributes: {
3240
- class: "component chip",
3241
- x: componentScreenTopLeft.x.toString(),
3242
- y: componentScreenTopLeft.y.toString(),
3243
- width: componentScreenWidth.toString(),
3244
- height: componentScreenHeight.toString(),
3245
- "stroke-width": `${getSchStrokeSize(transform)}px`,
3246
- fill: colorMap2.schematic.component_body,
3247
- stroke: colorMap2.schematic.component_outline
3248
- },
3249
- children: []
3250
- });
3251
- svgObjects.push({
3252
- name: "rect",
3253
- type: "element",
3254
- value: "",
3255
- attributes: {
3256
- class: "component-overlay",
3257
- x: componentScreenTopLeft.x.toString(),
3258
- y: componentScreenTopLeft.y.toString(),
3259
- width: componentScreenWidth.toString(),
3260
- height: componentScreenHeight.toString(),
3261
- fill: "transparent"
3262
- },
3263
- children: []
3264
- });
3265
- const schTexts = su7(circuitJson).schematic_text.list();
3266
- for (const schText of schTexts) {
3267
- if (schText.schematic_component_id === schComponent.schematic_component_id) {
3268
- svgObjects.push(
3269
- createSvgSchText({
3270
- elm: schText,
3271
- transform,
3272
- colorMap: colorMap2
3273
- })
3274
- );
3275
- }
3276
- }
3277
- const schematicPorts = su7(circuitJson).schematic_port.list({
3278
- schematic_component_id: schComponent.schematic_component_id
3279
- });
3280
- for (const schPort of schematicPorts) {
3281
- svgObjects.push(
3282
- ...createSvgObjectsFromSchPortOnBox({
3283
- schPort,
3284
- schComponent,
3285
- transform,
3286
- circuitJson
3287
- })
3288
- );
3289
- }
3290
- return svgObjects;
3291
- };
3292
-
3293
- // lib/sch/svg-object-fns/create-svg-objects-from-sch-component.ts
3294
- function createSvgObjectsFromSchematicComponent(params) {
3295
- const { component } = params;
3296
- const innerElements = component.symbol_name ? createSvgObjectsFromSchematicComponentWithSymbol(params) : createSvgObjectsFromSchematicComponentWithBox(params);
3297
- return [
3298
- {
3299
- type: "element",
3300
- name: "g",
3301
- attributes: {
3302
- "data-circuit-json-type": "schematic_component",
3303
- "data-schematic-component-id": component.schematic_component_id
3304
- },
3305
- children: innerElements,
3306
- value: ""
3307
- }
3308
- ];
3309
- }
3310
-
3311
- // lib/sch/svg-object-fns/create-svg-objects-from-sch-voltage-probe.ts
3312
- import { applyToPoint as applyToPoint33 } from "transformation-matrix";
3313
- function createSvgObjectsFromSchVoltageProbe({
3314
- probe,
3315
- transform,
3316
- colorMap: colorMap2
3317
- }) {
3318
- const [screenX, screenY] = applyToPoint33(transform, [
3319
- probe.position.x,
3320
- probe.position.y
3321
- ]);
3322
- const arrowLength = Math.abs(transform.a) * 0.6;
3323
- const arrowWidth = Math.abs(transform.a) * 0.28;
3324
- const baseX = screenX + arrowLength * Math.cos(-50 * Math.PI / 180);
3325
- const baseY = screenY + arrowLength * Math.sin(-50 * Math.PI / 180);
3326
- const tipX = screenX;
3327
- const tipY = screenY;
3328
- const arrowPath = [
3329
- `M ${baseX},${baseY}`,
3330
- `L ${tipX},${tipY}`,
3331
- `M ${tipX},${tipY}`,
3332
- `L ${tipX - arrowWidth * Math.cos((-50 + 150) * Math.PI / 180)},${tipY - arrowWidth * Math.sin((-50 + 150) * Math.PI / 180)}`,
3333
- `L ${tipX - arrowWidth * Math.cos((-50 + 210) * Math.PI / 180)},${tipY - arrowWidth * Math.sin((-50 + 210) * Math.PI / 180)}`,
3334
- "Z"
3335
- ].join(" ");
3336
- return [
3337
- {
3338
- name: "path",
3339
- type: "element",
3340
- attributes: {
3341
- d: arrowPath,
3342
- stroke: colorMap2.schematic.reference,
3343
- fill: colorMap2.schematic.reference,
3344
- "stroke-width": `${getSchStrokeSize(transform)}px`
3345
- },
3346
- value: "",
3347
- children: []
3348
- },
3349
- {
3350
- type: "element",
3351
- name: "text",
3352
- value: "",
3353
- attributes: {
3354
- x: (baseX + 8 - (baseX - baseX)).toString(),
3355
- y: (baseY - 10 + (baseY - baseY)).toString(),
3356
- fill: colorMap2.schematic.reference,
3357
- "text-anchor": "middle",
3358
- "dominant-baseline": "middle",
3359
- "font-family": "sans-serif",
3360
- "font-size": `${getSchScreenFontSize(transform, "reference_designator")}px`,
3361
- "font-weight": "bold",
3362
- "data-schematic-voltage-probe-id": probe.schematic_voltage_probe_id
3363
- },
3364
- children: [
3365
- {
3366
- type: "text",
3367
- value: probe.voltage ? `${probe.voltage}V` : "",
3368
- name: "",
3369
- attributes: {},
3370
- children: []
3371
- }
3372
- ]
3373
- }
3374
- ];
3375
- }
3376
-
3377
- // lib/sch/svg-object-fns/create-svg-objects-from-sch-debug-object.ts
3378
- import { applyToPoint as applyToPoint34 } from "transformation-matrix";
3379
- function createSvgObjectsFromSchDebugObject({
3380
- debugObject,
3381
- transform
3382
- }) {
3383
- if (debugObject.shape === "rect") {
3384
- let [screenLeft, screenTop] = applyToPoint34(transform, [
3385
- debugObject.center.x - debugObject.size.width / 2,
3386
- debugObject.center.y - debugObject.size.height / 2
3387
- ]);
3388
- let [screenRight, screenBottom] = applyToPoint34(transform, [
3389
- debugObject.center.x + debugObject.size.width / 2,
3390
- debugObject.center.y + debugObject.size.height / 2
3391
- ]);
3392
- [screenTop, screenBottom] = [
3393
- Math.min(screenTop, screenBottom),
3394
- Math.max(screenTop, screenBottom)
3395
- ];
3396
- const width = Math.abs(screenRight - screenLeft);
3397
- const height = Math.abs(screenBottom - screenTop);
3398
- const [screenCenterX, screenCenterY] = applyToPoint34(transform, [
3399
- debugObject.center.x,
3400
- debugObject.center.y
3401
- ]);
3402
- return [
3403
- {
3404
- name: "rect",
3405
- type: "element",
3406
- value: "",
3407
- attributes: {
3408
- x: screenLeft.toString(),
3409
- y: screenTop.toString(),
3410
- width: width.toString(),
3411
- height: height.toString(),
3412
- fill: "none",
3413
- stroke: "red",
3414
- "stroke-width": (0.02 * Math.abs(transform.a)).toString(),
3415
- "stroke-dasharray": "5,5"
3416
- },
3417
- children: debugObject.label ? [
3418
- {
3419
- name: "text",
3420
- type: "element",
3421
- value: "",
3422
- attributes: {
3423
- x: screenCenterX.toString(),
3424
- y: (screenCenterY - 10).toString(),
3425
- "text-anchor": "middle",
3426
- "font-size": (0.2 * Math.abs(transform.a)).toString(),
3427
- fill: "red"
3428
- },
3429
- children: [
3430
- {
3431
- type: "text",
3432
- value: debugObject.label,
3433
- name: "",
3434
- attributes: {},
3435
- children: []
3436
- }
3437
- ]
3438
- }
3439
- ] : []
3440
- }
3441
- ];
3442
- }
3443
- if (debugObject.shape === "line") {
3444
- const [screenStartX, screenStartY] = applyToPoint34(transform, [
3445
- debugObject.start.x,
3446
- debugObject.start.y
3447
- ]);
3448
- const [screenEndX, screenEndY] = applyToPoint34(transform, [
3449
- debugObject.end.x,
3450
- debugObject.end.y
3451
- ]);
3452
- const screenMidX = (screenStartX + screenEndX) / 2;
3453
- const screenMidY = (screenStartY + screenEndY) / 2;
3454
- return [
3455
- {
3456
- name: "line",
3457
- type: "element",
3458
- value: "",
3459
- attributes: {
3460
- x1: screenStartX.toString(),
3461
- y1: screenStartY.toString(),
3462
- x2: screenEndX.toString(),
3463
- y2: screenEndY.toString(),
3464
- stroke: "red",
3465
- "stroke-width": (0.02 * Math.abs(transform.a)).toString(),
3466
- "stroke-dasharray": "5,5"
3467
- },
3468
- children: debugObject.label ? [
3469
- {
3470
- name: "text",
3471
- type: "element",
3472
- value: "",
3473
- attributes: {
3474
- x: screenMidX.toString(),
3475
- y: (screenMidY - 10).toString(),
3476
- "text-anchor": "middle",
3477
- "font-size": (0.2 * Math.abs(transform.a)).toString(),
3478
- fill: "red"
3479
- },
3480
- children: [
3481
- {
3482
- type: "text",
3483
- value: debugObject.label,
3484
- name: "",
3485
- attributes: {},
3486
- children: []
3487
- }
3488
- ]
3489
- }
3490
- ] : []
3491
- }
3492
- ];
3493
- }
3494
- return [];
3495
- }
3496
-
3497
- // lib/sch/svg-object-fns/create-svg-objects-from-sch-trace.ts
3498
- import { applyToPoint as applyToPoint35 } from "transformation-matrix";
3499
- function createSchematicTrace({
3500
- trace,
3501
- transform,
3502
- colorMap: colorMap2
3503
- }) {
3504
- const edges = trace.edges;
3505
- if (edges.length === 0) return [];
3506
- const svgObjects = [];
3507
- let path = "";
3508
- for (let edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
3509
- const edge = edges[edgeIndex];
3510
- if (edge.is_crossing) continue;
3511
- const [screenFromX, screenFromY] = applyToPoint35(transform, [
3512
- edge.from.x,
3513
- edge.from.y
3514
- ]);
3515
- const [screenToX, screenToY] = applyToPoint35(transform, [
3516
- edge.to.x,
3517
- edge.to.y
3518
- ]);
3519
- if (edgeIndex === 0 || edges[edgeIndex - 1]?.is_crossing) {
3520
- path += `M ${screenFromX} ${screenFromY} L ${screenToX} ${screenToY}`;
3521
- } else {
3522
- path += ` L ${screenToX} ${screenToY}`;
3523
- }
3524
- }
3525
- for (const edge of edges) {
3526
- if (!edge.is_crossing) continue;
3527
- const [screenFromX, screenFromY] = applyToPoint35(transform, [
3528
- edge.from.x,
3529
- edge.from.y
3530
- ]);
3531
- const [screenToX, screenToY] = applyToPoint35(transform, [
3532
- edge.to.x,
3533
- edge.to.y
3534
- ]);
3535
- const midX = (screenFromX + screenToX) / 2;
3536
- const midY = (screenFromY + screenToY) / 2;
3537
- const dx = screenToX - screenFromX;
3538
- const dy = screenToY - screenFromY;
3539
- const len = Math.sqrt(dx * dx + dy * dy);
3540
- const hopHeight = len * 0.7;
3541
- const perpX = -dy / len * hopHeight;
3542
- const perpY = dx / len * hopHeight;
3543
- const controlX = midX + perpX;
3544
- const controlY = midY - Math.abs(perpY);
3545
- svgObjects.push({
3546
- name: "path",
3547
- type: "element",
3548
- attributes: {
3549
- class: "trace-crossing-outline",
3550
- d: `M ${screenFromX} ${screenFromY} Q ${controlX} ${controlY} ${screenToX} ${screenToY}`,
3551
- stroke: colorMap2.schematic.background,
3552
- fill: "none",
3553
- "stroke-width": `${getSchStrokeSize(transform) * 1.5}px`,
3554
- "stroke-linecap": "round"
3555
- },
3556
- value: "",
3557
- children: []
3558
- });
3559
- svgObjects.push({
3560
- name: "path",
3561
- type: "element",
3562
- attributes: {
3563
- d: `M ${screenFromX} ${screenFromY} Q ${controlX} ${controlY} ${screenToX} ${screenToY}`,
3564
- stroke: colorMap2.schematic.wire,
3565
- fill: "none",
3566
- "stroke-width": `${getSchStrokeSize(transform)}px`,
3567
- "stroke-linecap": "round"
3568
- },
3569
- value: "",
3570
- children: []
3571
- });
3572
- }
3573
- if (path) {
3574
- svgObjects.push({
3575
- name: "path",
3576
- type: "element",
3577
- attributes: {
3578
- d: path,
3579
- class: "trace-invisible-hover-outline",
3580
- stroke: colorMap2.schematic.wire,
3581
- fill: "none",
3582
- "stroke-width": `${getSchStrokeSize(transform) * 8}px`,
3583
- "stroke-linecap": "round",
3584
- opacity: "0",
3585
- "stroke-linejoin": "round"
3586
- },
3587
- value: "",
3588
- children: []
3589
- });
3590
- svgObjects.push({
3591
- name: "path",
3592
- type: "element",
3593
- attributes: {
3594
- d: path,
3595
- stroke: colorMap2.schematic.wire,
3596
- fill: "none",
3597
- "stroke-width": `${getSchStrokeSize(transform)}px`,
3598
- "stroke-linecap": "round",
3599
- "stroke-linejoin": "round"
3600
- },
3601
- value: "",
3602
- children: []
3603
- });
3604
- }
3605
- if (trace.junctions) {
3606
- for (const junction of trace.junctions) {
3607
- const [screenX, screenY] = applyToPoint35(transform, [
3608
- junction.x,
3609
- junction.y
3610
- ]);
3611
- svgObjects.push({
3612
- name: "circle",
3613
- type: "element",
3614
- attributes: {
3615
- cx: screenX.toString(),
3616
- cy: screenY.toString(),
3617
- r: (Math.abs(transform.a) * 0.03).toString(),
3618
- class: "trace-junction",
3619
- fill: colorMap2.schematic.junction
3620
- },
3621
- value: "",
3622
- children: []
3623
- });
3624
- }
3625
- }
3626
- return [
3627
- {
3628
- name: "g",
3629
- type: "element",
3630
- value: "",
3631
- attributes: {
3632
- class: "trace",
3633
- "data-circuit-json-type": "schematic_trace",
3634
- "data-schematic-trace-id": trace.schematic_trace_id
3635
- },
3636
- children: svgObjects
3637
- }
3638
- ];
3639
- }
3640
-
3641
- // lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label.ts
3642
- import {
3643
- applyToPoint as applyToPoint37,
3644
- compose as compose9,
3645
- rotate as rotate5,
3646
- scale as scale6,
3647
- translate as translate9
3648
- } from "transformation-matrix";
2591
+ }
3649
2592
 
3650
2593
  // lib/sch/arial-text-metrics.ts
3651
2594
  var arialTextMetrics = {
@@ -4409,22 +3352,1143 @@ var arialTextMetrics = {
4409
3352
  left: -1,
4410
3353
  right: 13
4411
3354
  }
4412
- };
3355
+ };
3356
+
3357
+ // lib/sch/estimate-text-width.ts
3358
+ var estimateTextWidth = (text) => {
3359
+ if (!text) return 0;
3360
+ let totalWidth = 0;
3361
+ for (const char of text) {
3362
+ const metrics = arialTextMetrics[char];
3363
+ if (metrics) {
3364
+ totalWidth += metrics.width;
3365
+ } else {
3366
+ totalWidth += arialTextMetrics["?"].width;
3367
+ }
3368
+ }
3369
+ return totalWidth / 27;
3370
+ };
3371
+
3372
+ // lib/sch/get-schematic-bounds-from-circuit-json.ts
3373
+ function getSchematicBoundsFromCircuitJson(soup, padding = 0.5) {
3374
+ let minX = Number.POSITIVE_INFINITY;
3375
+ let minY = Number.POSITIVE_INFINITY;
3376
+ let maxX = Number.NEGATIVE_INFINITY;
3377
+ let maxY = Number.NEGATIVE_INFINITY;
3378
+ const portSize = 0.2;
3379
+ for (const item of soup) {
3380
+ if (item.type === "schematic_component") {
3381
+ updateBounds(item.center, item.size, 0);
3382
+ } else if (item.type === "schematic_port") {
3383
+ updateBounds(item.center, { width: portSize, height: portSize }, 0);
3384
+ } else if (item.type === "schematic_debug_object") {
3385
+ if (item.shape === "rect") {
3386
+ updateBounds(item.center, item.size, 0);
3387
+ } else if (item.shape === "line") {
3388
+ updateBounds(item.start, { width: 0.1, height: 0.1 }, 0);
3389
+ updateBounds(item.end, { width: 0.1, height: 0.1 }, 0);
3390
+ }
3391
+ } else if (item.type === "schematic_net_label") {
3392
+ const fontSizeMm = getSchMmFontSize("net_label");
3393
+ const textWidth = estimateTextWidth(item.text || "");
3394
+ const fullWidthFsr = textWidth + ARROW_POINT_WIDTH_FSR * 2 + END_PADDING_EXTRA_PER_CHARACTER_FSR * (item.text?.length || 0) + END_PADDING_FSR;
3395
+ const width = fullWidthFsr * fontSizeMm;
3396
+ const height = 1.2 * fontSizeMm;
3397
+ const rotation = getPathRotation(item.anchor_side) / 180 * Math.PI;
3398
+ const anchorPosition = calculateAnchorPosition(
3399
+ item,
3400
+ fontSizeMm,
3401
+ textWidth
3402
+ );
3403
+ const growthVec = getUnitVectorFromOutsideToEdge(item.anchor_side);
3404
+ const center = {
3405
+ x: anchorPosition.x + growthVec.x * width / 2,
3406
+ y: anchorPosition.y + growthVec.y * width / 2
3407
+ };
3408
+ updateBounds(center, { width, height }, rotation);
3409
+ } else if (item.type === "schematic_trace") {
3410
+ for (const edge of item.edges) {
3411
+ updateBounds(edge.from, { width: 0.1, height: 0.1 }, 0);
3412
+ updateBounds(edge.to, { width: 0.1, height: 0.1 }, 0);
3413
+ }
3414
+ } else if (item.type === "schematic_text") {
3415
+ const textType = "reference_designator";
3416
+ const fontSize = getSchMmFontSize(textType, item.font_size) ?? 0.18;
3417
+ const text = item.text ?? "";
3418
+ const width = text.length * fontSize;
3419
+ const height = fontSize;
3420
+ updateBounds(item.position, { width, height }, item.rotation ?? 0);
3421
+ } else if (item.type === "schematic_voltage_probe") {
3422
+ updateBounds(item.position, { width: 0.2, height: 0.4 }, 0);
3423
+ } else if (item.type === "schematic_box") {
3424
+ updateBounds(
3425
+ {
3426
+ x: item.x + item.width / 2,
3427
+ y: item.y + item.height / 2
3428
+ },
3429
+ { width: item.width, height: item.height },
3430
+ 0
3431
+ );
3432
+ }
3433
+ }
3434
+ minX -= padding;
3435
+ minY -= padding;
3436
+ maxX += padding;
3437
+ maxY += padding;
3438
+ return { minX, minY, maxX, maxY };
3439
+ function updateBounds(center, size, rotation) {
3440
+ const corners = [
3441
+ { x: -size.width / 2, y: -size.height / 2 },
3442
+ { x: size.width / 2, y: -size.height / 2 },
3443
+ { x: size.width / 2, y: size.height / 2 },
3444
+ { x: -size.width / 2, y: size.height / 2 }
3445
+ ];
3446
+ for (const corner of corners) {
3447
+ const rotatedX = corner.x * Math.cos(rotation) - corner.y * Math.sin(rotation) + center.x;
3448
+ const rotatedY = corner.x * Math.sin(rotation) + corner.y * Math.cos(rotation) + center.y;
3449
+ minX = Math.min(minX, rotatedX);
3450
+ minY = Math.min(minY, rotatedY);
3451
+ maxX = Math.max(maxX, rotatedX);
3452
+ maxY = Math.max(maxY, rotatedY);
3453
+ }
3454
+ }
3455
+ }
3456
+
3457
+ // lib/sch/svg-object-fns/create-svg-objects-from-sch-component-with-symbol.ts
3458
+ import { su as su4 } from "@tscircuit/circuit-json-util";
3459
+ import { symbols } from "schematic-symbols";
3460
+ import "svgson";
3461
+ import {
3462
+ applyToPoint as applyToPoint26,
3463
+ compose as compose7
3464
+ } from "transformation-matrix";
3465
+
3466
+ // lib/utils/get-sch-stroke-size.ts
3467
+ var getSchStrokeSize = (transform) => {
3468
+ return Math.abs(transform.a) * 0.02;
3469
+ };
3470
+
3471
+ // lib/utils/match-sch-ports-with-symbol-ports.ts
3472
+ var getAngularDifference = (angle1, angle2) => {
3473
+ const a1 = angle1 < 0 ? angle1 + 2 * Math.PI : angle1;
3474
+ const a2 = angle2 < 0 ? angle2 + 2 * Math.PI : angle2;
3475
+ let diff = Math.abs(a1 - a2);
3476
+ if (diff > Math.PI) {
3477
+ diff = 2 * Math.PI - diff;
3478
+ }
3479
+ return diff;
3480
+ };
3481
+ var matchSchPortsToSymbolPorts = ({
3482
+ schPorts,
3483
+ symbol,
3484
+ schComponent
3485
+ }) => {
3486
+ const schPortAngles = schPorts.map((port) => {
3487
+ const dx = port.center.x - schComponent.center.x;
3488
+ const dy = port.center.y - schComponent.center.y;
3489
+ return {
3490
+ port,
3491
+ angle: Math.atan2(dy, dx)
3492
+ };
3493
+ });
3494
+ const symbolPortAngles = symbol.ports.map((port) => {
3495
+ const dx = port.x - symbol.center.x;
3496
+ const dy = port.y - symbol.center.y;
3497
+ return {
3498
+ port,
3499
+ angle: Math.atan2(dy, dx)
3500
+ };
3501
+ });
3502
+ schPortAngles.sort((a, b) => a.angle - b.angle);
3503
+ symbolPortAngles.sort((a, b) => a.angle - b.angle);
3504
+ const matches = [];
3505
+ const usedSymbolPorts = /* @__PURE__ */ new Set();
3506
+ for (const schPortAngle of schPortAngles) {
3507
+ let bestMatch = null;
3508
+ for (const symbolPortAngle of symbolPortAngles) {
3509
+ if (usedSymbolPorts.has(symbolPortAngle.port)) continue;
3510
+ const angleDiff = getAngularDifference(
3511
+ schPortAngle.angle,
3512
+ symbolPortAngle.angle
3513
+ );
3514
+ if (bestMatch === null || angleDiff < bestMatch.angleDiff) {
3515
+ bestMatch = {
3516
+ symbolPort: symbolPortAngle.port,
3517
+ angleDiff
3518
+ };
3519
+ }
3520
+ }
3521
+ if (bestMatch && bestMatch.angleDiff < Math.PI / 4) {
3522
+ matches.push({
3523
+ schPort: schPortAngle.port,
3524
+ symbolPort: bestMatch.symbolPort
3525
+ });
3526
+ usedSymbolPorts.add(bestMatch.symbolPort);
3527
+ }
3528
+ }
3529
+ return matches;
3530
+ };
3531
+
3532
+ // lib/utils/point-pairs-to-matrix.ts
3533
+ import { compose as compose6, scale as scale4, translate as translate6 } from "transformation-matrix";
3534
+ function pointPairsToMatrix(a1, a2, b1, b2) {
3535
+ const tx = a2.x - a1.x;
3536
+ const ty = a2.y - a1.y;
3537
+ const originalDistance = Math.sqrt((b1.x - a1.x) ** 2 + (b1.y - a1.y) ** 2);
3538
+ const transformedDistance = Math.sqrt((b2.x - a2.x) ** 2 + (b2.y - a2.y) ** 2);
3539
+ const a = transformedDistance / originalDistance;
3540
+ const translateMatrix = translate6(tx, ty);
3541
+ const scaleMatrix = scale4(a, a);
3542
+ return compose6(translateMatrix, scaleMatrix);
3543
+ }
3544
+
3545
+ // lib/sch/svg-object-fns/create-svg-error-text.ts
3546
+ import { applyToPoint as applyToPoint25 } from "transformation-matrix";
3547
+ var createSvgSchErrorText = ({
3548
+ text,
3549
+ realCenter,
3550
+ realToScreenTransform
3551
+ }) => {
3552
+ const screenCenter = applyToPoint25(realToScreenTransform, realCenter);
3553
+ return {
3554
+ type: "element",
3555
+ name: "text",
3556
+ value: "",
3557
+ attributes: {
3558
+ x: screenCenter.x.toString(),
3559
+ y: screenCenter.y.toString(),
3560
+ fill: "red",
3561
+ "text-anchor": "middle",
3562
+ "dominant-baseline": "middle",
3563
+ "font-family": "sans-serif",
3564
+ "font-size": `${getSchScreenFontSize(realToScreenTransform, "error")}px`
3565
+ },
3566
+ children: [
3567
+ {
3568
+ type: "text",
3569
+ value: text,
3570
+ name: "",
3571
+ attributes: {},
3572
+ children: []
3573
+ }
3574
+ ]
3575
+ };
3576
+ };
3577
+
3578
+ // lib/sch/svg-object-fns/create-svg-objects-from-sch-component-with-symbol.ts
3579
+ var ninePointAnchorToTextAnchor2 = {
3580
+ top_left: "start",
3581
+ top_right: "end",
3582
+ middle_left: "start",
3583
+ middle_right: "end",
3584
+ bottom_left: "start",
3585
+ bottom_right: "end",
3586
+ center: "middle",
3587
+ middle_top: "middle",
3588
+ middle_bottom: "middle"
3589
+ };
3590
+ var createSvgObjectsFromSchematicComponentWithSymbol = ({
3591
+ component: schComponent,
3592
+ transform: realToScreenTransform,
3593
+ circuitJson,
3594
+ colorMap: colorMap2
3595
+ }) => {
3596
+ const svgObjects = [];
3597
+ const symbol = symbols[schComponent.symbol_name];
3598
+ if (!symbol) {
3599
+ return [
3600
+ createSvgSchErrorText({
3601
+ text: `Symbol not found: ${schComponent.symbol_name}`,
3602
+ realCenter: schComponent.center,
3603
+ realToScreenTransform
3604
+ })
3605
+ ];
3606
+ }
3607
+ const schPorts = su4(circuitJson).schematic_port.list({
3608
+ schematic_component_id: schComponent.schematic_component_id
3609
+ });
3610
+ const srcComponent = su4(circuitJson).source_component.get(
3611
+ schComponent.source_component_id
3612
+ );
3613
+ const schPortsWithSymbolPorts = matchSchPortsToSymbolPorts({
3614
+ schPorts,
3615
+ symbol,
3616
+ schComponent
3617
+ });
3618
+ if (!schPortsWithSymbolPorts[0]) {
3619
+ return [
3620
+ createSvgSchErrorText({
3621
+ text: `Could not match ports for symbol ${schComponent.symbol_name}`,
3622
+ realCenter: schComponent.center,
3623
+ realToScreenTransform
3624
+ })
3625
+ ];
3626
+ }
3627
+ const transformFromSymbolToReal = pointPairsToMatrix(
3628
+ schPortsWithSymbolPorts[1]?.symbolPort ?? symbol.center,
3629
+ schPortsWithSymbolPorts[1]?.schPort.center ?? schComponent.center,
3630
+ schPortsWithSymbolPorts[0].symbolPort,
3631
+ schPortsWithSymbolPorts[0].schPort.center
3632
+ );
3633
+ const paths = symbol.primitives.filter((p) => p.type === "path");
3634
+ const texts = symbol.primitives.filter((p) => p.type === "text");
3635
+ const circles = symbol.primitives.filter((p) => p.type === "circle");
3636
+ const boxes = symbol.primitives.filter((p) => p.type === "box");
3637
+ const bounds = {
3638
+ minX: Math.min(...paths.flatMap((p) => p.points.map((pt) => pt.x))),
3639
+ maxX: Math.max(...paths.flatMap((p) => p.points.map((pt) => pt.x))),
3640
+ minY: Math.min(...paths.flatMap((p) => p.points.map((pt) => pt.y))),
3641
+ maxY: Math.max(...paths.flatMap((p) => p.points.map((pt) => pt.y)))
3642
+ };
3643
+ const [screenMinX, screenMinY] = applyToPoint26(
3644
+ compose7(realToScreenTransform, transformFromSymbolToReal),
3645
+ [bounds.minX, bounds.minY]
3646
+ );
3647
+ const [screenMaxX, screenMaxY] = applyToPoint26(
3648
+ compose7(realToScreenTransform, transformFromSymbolToReal),
3649
+ [bounds.maxX, bounds.maxY]
3650
+ );
3651
+ const rectHeight = Math.abs(screenMaxY - screenMinY);
3652
+ const rectY = Math.min(screenMinY, screenMaxY);
3653
+ const rectWidth = Math.abs(screenMaxX - screenMinX);
3654
+ const rectX = Math.min(screenMinX, screenMaxX);
3655
+ svgObjects.push({
3656
+ name: "rect",
3657
+ type: "element",
3658
+ value: "",
3659
+ attributes: {
3660
+ class: "component-overlay",
3661
+ x: rectX.toString(),
3662
+ y: rectY.toString(),
3663
+ width: rectWidth.toString(),
3664
+ height: rectHeight.toString(),
3665
+ fill: "transparent"
3666
+ },
3667
+ children: []
3668
+ });
3669
+ for (const path of paths) {
3670
+ const { points, color, closed, fill } = path;
3671
+ svgObjects.push({
3672
+ type: "element",
3673
+ name: "path",
3674
+ attributes: {
3675
+ d: points.map((p, i) => {
3676
+ const [x, y] = applyToPoint26(
3677
+ compose7(realToScreenTransform, transformFromSymbolToReal),
3678
+ [p.x, p.y]
3679
+ );
3680
+ return `${i === 0 ? "M" : "L"} ${x} ${y}`;
3681
+ }).join(" ") + (closed ? " Z" : ""),
3682
+ stroke: colorMap2.schematic.component_outline,
3683
+ fill: "none",
3684
+ "stroke-width": `${getSchStrokeSize(realToScreenTransform)}px`
3685
+ },
3686
+ value: "",
3687
+ children: []
3688
+ });
3689
+ }
3690
+ for (const text of texts) {
3691
+ const screenTextPos = applyToPoint26(
3692
+ compose7(realToScreenTransform, transformFromSymbolToReal),
3693
+ text
3694
+ );
3695
+ let textValue = "";
3696
+ if (text.text === "{REF}") {
3697
+ textValue = srcComponent?.name ?? "";
3698
+ } else if (text.text === "{VAL}") {
3699
+ textValue = schComponent.symbol_display_value ?? "";
3700
+ }
3701
+ const symbolHeight = Math.abs(bounds.maxY - bounds.minY);
3702
+ const offsetFactor = 0.1;
3703
+ const baseOffset = symbolHeight * offsetFactor;
3704
+ const transformScale = Math.abs(transformFromSymbolToReal.a);
3705
+ let verticalOffset = 0;
3706
+ if (text.anchor.includes("bottom")) {
3707
+ verticalOffset = baseOffset * transformScale;
3708
+ } else if (text.anchor.includes("top")) {
3709
+ verticalOffset = -baseOffset * transformScale;
3710
+ }
3711
+ const dominantBaseline = text.anchor.includes("bottom") ? "auto" : text.anchor.includes("top") ? "hanging" : "middle";
3712
+ svgObjects.push({
3713
+ name: "text",
3714
+ type: "element",
3715
+ attributes: {
3716
+ x: screenTextPos.x.toString(),
3717
+ y: (screenTextPos.y + verticalOffset).toString(),
3718
+ fill: colorMap2.schematic.label_local,
3719
+ "font-family": "sans-serif",
3720
+ "text-anchor": ninePointAnchorToTextAnchor2[text.anchor],
3721
+ "dominant-baseline": dominantBaseline,
3722
+ "font-size": `${getSchScreenFontSize(realToScreenTransform, "reference_designator")}px`
3723
+ },
3724
+ value: "",
3725
+ children: [
3726
+ {
3727
+ type: "text",
3728
+ value: textValue,
3729
+ name: "",
3730
+ attributes: {},
3731
+ children: []
3732
+ }
3733
+ ]
3734
+ });
3735
+ }
3736
+ for (const box of boxes) {
3737
+ const screenBoxPos = applyToPoint26(
3738
+ compose7(realToScreenTransform, transformFromSymbolToReal),
3739
+ box
3740
+ );
3741
+ const symbolToScreenScale = compose7(
3742
+ realToScreenTransform,
3743
+ transformFromSymbolToReal
3744
+ ).a;
3745
+ svgObjects.push({
3746
+ name: "rect",
3747
+ type: "element",
3748
+ attributes: {
3749
+ x: screenBoxPos.x.toString(),
3750
+ y: screenBoxPos.y.toString(),
3751
+ width: (box.width * symbolToScreenScale).toString(),
3752
+ height: (box.height * symbolToScreenScale).toString(),
3753
+ fill: "red"
3754
+ },
3755
+ value: "",
3756
+ children: []
3757
+ });
3758
+ }
3759
+ for (const port of symbol.ports) {
3760
+ const screenPortPos = applyToPoint26(
3761
+ compose7(realToScreenTransform, transformFromSymbolToReal),
3762
+ port
3763
+ );
3764
+ svgObjects.push({
3765
+ type: "element",
3766
+ name: "circle",
3767
+ attributes: {
3768
+ cx: screenPortPos.x.toString(),
3769
+ cy: screenPortPos.y.toString(),
3770
+ r: `${Math.abs(realToScreenTransform.a) * 0.02}px`,
3771
+ "stroke-width": `${getSchStrokeSize(realToScreenTransform)}px`,
3772
+ fill: "none",
3773
+ stroke: colorMap2.schematic.component_outline
3774
+ },
3775
+ value: "",
3776
+ children: []
3777
+ });
3778
+ }
3779
+ for (const circle of circles) {
3780
+ const screenCirclePos = applyToPoint26(
3781
+ compose7(realToScreenTransform, transformFromSymbolToReal),
3782
+ circle
3783
+ );
3784
+ const screenRadius = Math.abs(circle.radius * realToScreenTransform.a);
3785
+ svgObjects.push({
3786
+ type: "element",
3787
+ name: "circle",
3788
+ attributes: {
3789
+ cx: screenCirclePos.x.toString(),
3790
+ cy: screenCirclePos.y.toString(),
3791
+ r: `${screenRadius}px`,
3792
+ "stroke-width": `${getSchStrokeSize(realToScreenTransform)}px`,
3793
+ fill: "none",
3794
+ stroke: colorMap2.schematic.component_outline
3795
+ },
3796
+ value: "",
3797
+ children: []
3798
+ });
3799
+ }
3800
+ return svgObjects;
3801
+ };
3802
+
3803
+ // lib/sch/svg-object-fns/create-svg-objects-from-sch-component-with-box.ts
3804
+ import { su as su7 } from "@tscircuit/circuit-json-util";
3805
+ import "schematic-symbols";
3806
+ import "svgson";
3807
+ import { applyToPoint as applyToPoint32 } from "transformation-matrix";
3808
+
3809
+ // lib/sch/svg-object-fns/create-svg-objects-from-sch-port-on-box.ts
3810
+ import "transformation-matrix";
3811
+ import "@tscircuit/circuit-json-util";
3812
+
3813
+ // lib/sch/svg-object-fns/create-svg-objects-for-sch-port-box-line.ts
3814
+ import { applyToPoint as applyToPoint27 } from "transformation-matrix";
3815
+ import { su as su5 } from "@tscircuit/circuit-json-util";
3816
+ var PIN_CIRCLE_RADIUS_MM = 0.02;
3817
+ var createSvgObjectsForSchPortBoxLine = ({
3818
+ schPort,
3819
+ schComponent,
3820
+ transform,
3821
+ circuitJson
3822
+ }) => {
3823
+ const svgObjects = [];
3824
+ const srcPort = su5(circuitJson).source_port.get(schPort.source_port_id);
3825
+ const realEdgePos = {
3826
+ x: schPort.center.x,
3827
+ y: schPort.center.y
3828
+ };
3829
+ const realPinLineLength = schPort.distance_from_component_edge ?? 0.4;
3830
+ switch (schPort.side_of_component) {
3831
+ case "left":
3832
+ realEdgePos.x += realPinLineLength;
3833
+ break;
3834
+ case "right":
3835
+ realEdgePos.x -= realPinLineLength;
3836
+ break;
3837
+ case "top":
3838
+ realEdgePos.y -= realPinLineLength;
3839
+ break;
3840
+ case "bottom":
3841
+ realEdgePos.y += realPinLineLength;
3842
+ break;
3843
+ }
3844
+ const screenSchPortPos = applyToPoint27(transform, schPort.center);
3845
+ const screenRealEdgePos = applyToPoint27(transform, realEdgePos);
3846
+ const realLineEnd = { ...schPort.center };
3847
+ switch (schPort.side_of_component) {
3848
+ case "left":
3849
+ realLineEnd.x += PIN_CIRCLE_RADIUS_MM;
3850
+ break;
3851
+ case "right":
3852
+ realLineEnd.x -= PIN_CIRCLE_RADIUS_MM;
3853
+ break;
3854
+ case "top":
3855
+ realLineEnd.y -= PIN_CIRCLE_RADIUS_MM;
3856
+ break;
3857
+ case "bottom":
3858
+ realLineEnd.y += PIN_CIRCLE_RADIUS_MM;
3859
+ break;
3860
+ }
3861
+ const screenLineEnd = applyToPoint27(transform, realLineEnd);
3862
+ svgObjects.push({
3863
+ name: "line",
3864
+ type: "element",
3865
+ attributes: {
3866
+ class: "component-pin",
3867
+ x1: screenLineEnd.x.toString(),
3868
+ y1: screenLineEnd.y.toString(),
3869
+ x2: screenRealEdgePos.x.toString(),
3870
+ y2: screenRealEdgePos.y.toString(),
3871
+ "stroke-width": `${getSchStrokeSize(transform)}px`
3872
+ },
3873
+ value: "",
3874
+ children: []
3875
+ });
3876
+ svgObjects.push({
3877
+ name: "circle",
3878
+ type: "element",
3879
+ attributes: {
3880
+ class: "component-pin",
3881
+ cx: screenSchPortPos.x.toString(),
3882
+ cy: screenSchPortPos.y.toString(),
3883
+ r: (Math.abs(transform.a) * PIN_CIRCLE_RADIUS_MM).toString(),
3884
+ "stroke-width": `${getSchStrokeSize(transform)}px`
3885
+ },
3886
+ value: "",
3887
+ children: []
3888
+ });
3889
+ return svgObjects;
3890
+ };
3891
+
3892
+ // lib/sch/svg-object-fns/create-svg-objects-for-sch-port-pin-number-text.ts
3893
+ import { applyToPoint as applyToPoint28 } from "transformation-matrix";
3894
+ var createSvgObjectsForSchPortPinNumberText = (params) => {
3895
+ const svgObjects = [];
3896
+ const { schPort, schComponent, transform, circuitJson } = params;
3897
+ const realPinNumberPos = {
3898
+ x: schPort.center.x,
3899
+ y: schPort.center.y
3900
+ };
3901
+ if (!schPort.side_of_component) return [];
3902
+ const vecToEdge = getUnitVectorFromOutsideToEdge(schPort.side_of_component);
3903
+ const realPinEdgeDistance = schPort.distance_from_component_edge ?? 0.4;
3904
+ realPinNumberPos.x += vecToEdge.x * realPinEdgeDistance / 2;
3905
+ realPinNumberPos.y += vecToEdge.y * realPinEdgeDistance / 2;
3906
+ if (schPort.side_of_component === "top" || schPort.side_of_component === "bottom") {
3907
+ realPinNumberPos.x -= 0.02;
3908
+ } else {
3909
+ realPinNumberPos.y += 0.02;
3910
+ }
3911
+ const screenPinNumberTextPos = applyToPoint28(transform, realPinNumberPos);
3912
+ svgObjects.push({
3913
+ name: "text",
3914
+ type: "element",
3915
+ attributes: {
3916
+ class: "pin-number",
3917
+ x: screenPinNumberTextPos.x.toString(),
3918
+ y: screenPinNumberTextPos.y.toString(),
3919
+ style: "font-family: sans-serif;",
3920
+ fill: colorMap.schematic.pin_number,
3921
+ "text-anchor": "middle",
3922
+ "dominant-baseline": "auto",
3923
+ "font-size": `${getSchScreenFontSize(transform, "pin_number")}px`,
3924
+ transform: schPort.side_of_component === "top" || schPort.side_of_component === "bottom" ? `rotate(-90 ${screenPinNumberTextPos.x} ${screenPinNumberTextPos.y})` : ""
3925
+ },
3926
+ children: [
3927
+ {
3928
+ type: "text",
3929
+ value: schPort.pin_number?.toString() || "",
3930
+ name: "",
3931
+ attributes: {},
3932
+ children: []
3933
+ }
3934
+ ],
3935
+ value: ""
3936
+ });
3937
+ return svgObjects;
3938
+ };
3939
+
3940
+ // lib/sch/svg-object-fns/create-svg-objects-for-sch-port-pin-label.ts
3941
+ import { applyToPoint as applyToPoint29 } from "transformation-matrix";
3942
+ var LABEL_DIST_FROM_EDGE_MM = 0.1;
3943
+ var createSvgObjectsForSchPortPinLabel = (params) => {
3944
+ const svgObjects = [];
3945
+ const { schPort, schComponent, transform, circuitJson } = params;
3946
+ const realPinNumberPos = {
3947
+ x: schPort.center.x,
3948
+ y: schPort.center.y
3949
+ };
3950
+ if (!schPort.side_of_component) return [];
3951
+ const vecToEdge = getUnitVectorFromOutsideToEdge(schPort.side_of_component);
3952
+ const realPinEdgeDistance = schPort.distance_from_component_edge ?? 0.4;
3953
+ realPinNumberPos.x += vecToEdge.x * (realPinEdgeDistance + LABEL_DIST_FROM_EDGE_MM);
3954
+ realPinNumberPos.y += vecToEdge.y * (realPinEdgeDistance + LABEL_DIST_FROM_EDGE_MM);
3955
+ const screenPinNumberTextPos = applyToPoint29(transform, realPinNumberPos);
3956
+ const label = schPort.display_pin_label ?? schComponent.port_labels?.[`${schPort.pin_number}`];
3957
+ if (!label) return [];
3958
+ svgObjects.push({
3959
+ name: "text",
3960
+ type: "element",
3961
+ attributes: {
3962
+ class: "pin-number",
3963
+ x: screenPinNumberTextPos.x.toString(),
3964
+ y: screenPinNumberTextPos.y.toString(),
3965
+ style: "font-family: sans-serif;",
3966
+ fill: colorMap.schematic.pin_number,
3967
+ "text-anchor": schPort.side_of_component === "left" || schPort.side_of_component === "bottom" ? "start" : "end",
3968
+ "dominant-baseline": "middle",
3969
+ "font-size": `${getSchScreenFontSize(transform, "pin_number")}px`,
3970
+ transform: schPort.side_of_component === "top" || schPort.side_of_component === "bottom" ? `rotate(-90 ${screenPinNumberTextPos.x} ${screenPinNumberTextPos.y})` : ""
3971
+ },
3972
+ children: [
3973
+ {
3974
+ type: "text",
3975
+ value: label || "",
3976
+ name: "",
3977
+ attributes: {},
3978
+ children: []
3979
+ }
3980
+ ],
3981
+ value: ""
3982
+ });
3983
+ return svgObjects;
3984
+ };
3985
+
3986
+ // lib/sch/svg-object-fns/create-svg-objects-from-sch-port-on-box.ts
3987
+ var createSvgObjectsFromSchPortOnBox = (params) => {
3988
+ const svgObjects = [];
3989
+ const { schPort, schComponent, transform, circuitJson } = params;
3990
+ svgObjects.push(...createSvgObjectsForSchPortBoxLine(params));
3991
+ svgObjects.push(...createSvgObjectsForSchPortPinNumberText(params));
3992
+ svgObjects.push(...createSvgObjectsForSchPortPinLabel(params));
3993
+ return svgObjects;
3994
+ };
3995
+
3996
+ // lib/sch/svg-object-fns/create-svg-objects-for-sch-text.ts
3997
+ import { applyToPoint as applyToPoint31 } from "transformation-matrix";
3998
+ var createSvgSchText = ({
3999
+ elm,
4000
+ transform,
4001
+ colorMap: colorMap2
4002
+ }) => {
4003
+ const center = applyToPoint31(transform, elm.position);
4004
+ const textAnchorMap = {
4005
+ center: "middle",
4006
+ center_right: "end",
4007
+ bottom_left: "start",
4008
+ bottom_center: "middle",
4009
+ bottom_right: "end",
4010
+ left: "start",
4011
+ right: "end",
4012
+ top: "middle",
4013
+ bottom: "middle",
4014
+ top_left: "start",
4015
+ top_center: "middle",
4016
+ top_right: "end",
4017
+ center_left: "start"
4018
+ };
4019
+ const dominantBaselineMap = {
4020
+ center: "middle",
4021
+ center_right: "middle",
4022
+ bottom_left: "ideographic",
4023
+ bottom_center: "ideographic",
4024
+ bottom_right: "ideographic",
4025
+ left: "middle",
4026
+ right: "middle",
4027
+ top: "hanging",
4028
+ bottom: "ideographic",
4029
+ top_left: "hanging",
4030
+ top_center: "hanging",
4031
+ top_right: "hanging",
4032
+ center_left: "middle"
4033
+ };
4034
+ return {
4035
+ type: "element",
4036
+ name: "text",
4037
+ value: "",
4038
+ attributes: {
4039
+ x: center.x.toString(),
4040
+ y: center.y.toString(),
4041
+ fill: elm.color ?? colorMap2.schematic.sheet_label,
4042
+ "text-anchor": textAnchorMap[elm.anchor],
4043
+ "dominant-baseline": dominantBaselineMap[elm.anchor],
4044
+ "font-family": "sans-serif",
4045
+ "font-size": `${getSchScreenFontSize(transform, "reference_designator", elm.font_size)}px`,
4046
+ transform: `rotate(${elm.rotation}, ${center.x}, ${center.y})`
4047
+ },
4048
+ children: [
4049
+ {
4050
+ type: "text",
4051
+ value: elm.text,
4052
+ name: elm.schematic_text_id,
4053
+ attributes: {},
4054
+ children: []
4055
+ }
4056
+ ]
4057
+ };
4058
+ };
4059
+
4060
+ // lib/sch/svg-object-fns/create-svg-objects-from-sch-component-with-box.ts
4061
+ var createSvgObjectsFromSchematicComponentWithBox = ({
4062
+ component: schComponent,
4063
+ transform,
4064
+ circuitJson,
4065
+ colorMap: colorMap2
4066
+ }) => {
4067
+ const svgObjects = [];
4068
+ const componentScreenTopLeft = applyToPoint32(transform, {
4069
+ x: schComponent.center.x - schComponent.size.width / 2,
4070
+ y: schComponent.center.y + schComponent.size.height / 2
4071
+ });
4072
+ const componentScreenBottomRight = applyToPoint32(transform, {
4073
+ x: schComponent.center.x + schComponent.size.width / 2,
4074
+ y: schComponent.center.y - schComponent.size.height / 2
4075
+ });
4076
+ const componentScreenWidth = componentScreenBottomRight.x - componentScreenTopLeft.x;
4077
+ const componentScreenHeight = componentScreenBottomRight.y - componentScreenTopLeft.y;
4078
+ svgObjects.push({
4079
+ name: "rect",
4080
+ type: "element",
4081
+ value: "",
4082
+ attributes: {
4083
+ class: "component chip",
4084
+ x: componentScreenTopLeft.x.toString(),
4085
+ y: componentScreenTopLeft.y.toString(),
4086
+ width: componentScreenWidth.toString(),
4087
+ height: componentScreenHeight.toString(),
4088
+ "stroke-width": `${getSchStrokeSize(transform)}px`,
4089
+ fill: colorMap2.schematic.component_body,
4090
+ stroke: colorMap2.schematic.component_outline
4091
+ },
4092
+ children: []
4093
+ });
4094
+ svgObjects.push({
4095
+ name: "rect",
4096
+ type: "element",
4097
+ value: "",
4098
+ attributes: {
4099
+ class: "component-overlay",
4100
+ x: componentScreenTopLeft.x.toString(),
4101
+ y: componentScreenTopLeft.y.toString(),
4102
+ width: componentScreenWidth.toString(),
4103
+ height: componentScreenHeight.toString(),
4104
+ fill: "transparent"
4105
+ },
4106
+ children: []
4107
+ });
4108
+ const schTexts = su7(circuitJson).schematic_text.list();
4109
+ for (const schText of schTexts) {
4110
+ if (schText.schematic_component_id === schComponent.schematic_component_id) {
4111
+ svgObjects.push(
4112
+ createSvgSchText({
4113
+ elm: schText,
4114
+ transform,
4115
+ colorMap: colorMap2
4116
+ })
4117
+ );
4118
+ }
4119
+ }
4120
+ const schematicPorts = su7(circuitJson).schematic_port.list({
4121
+ schematic_component_id: schComponent.schematic_component_id
4122
+ });
4123
+ for (const schPort of schematicPorts) {
4124
+ svgObjects.push(
4125
+ ...createSvgObjectsFromSchPortOnBox({
4126
+ schPort,
4127
+ schComponent,
4128
+ transform,
4129
+ circuitJson
4130
+ })
4131
+ );
4132
+ }
4133
+ return svgObjects;
4134
+ };
4135
+
4136
+ // lib/sch/svg-object-fns/create-svg-objects-from-sch-component.ts
4137
+ function createSvgObjectsFromSchematicComponent(params) {
4138
+ const { component } = params;
4139
+ const innerElements = component.symbol_name ? createSvgObjectsFromSchematicComponentWithSymbol(params) : createSvgObjectsFromSchematicComponentWithBox(params);
4140
+ return [
4141
+ {
4142
+ type: "element",
4143
+ name: "g",
4144
+ attributes: {
4145
+ "data-circuit-json-type": "schematic_component",
4146
+ "data-schematic-component-id": component.schematic_component_id
4147
+ },
4148
+ children: innerElements,
4149
+ value: ""
4150
+ }
4151
+ ];
4152
+ }
4153
+
4154
+ // lib/sch/svg-object-fns/create-svg-objects-from-sch-voltage-probe.ts
4155
+ import { applyToPoint as applyToPoint33 } from "transformation-matrix";
4156
+ function createSvgObjectsFromSchVoltageProbe({
4157
+ probe,
4158
+ transform,
4159
+ colorMap: colorMap2
4160
+ }) {
4161
+ const [screenX, screenY] = applyToPoint33(transform, [
4162
+ probe.position.x,
4163
+ probe.position.y
4164
+ ]);
4165
+ const arrowLength = Math.abs(transform.a) * 0.6;
4166
+ const arrowWidth = Math.abs(transform.a) * 0.28;
4167
+ const baseX = screenX + arrowLength * Math.cos(-50 * Math.PI / 180);
4168
+ const baseY = screenY + arrowLength * Math.sin(-50 * Math.PI / 180);
4169
+ const tipX = screenX;
4170
+ const tipY = screenY;
4171
+ const arrowPath = [
4172
+ `M ${baseX},${baseY}`,
4173
+ `L ${tipX},${tipY}`,
4174
+ `M ${tipX},${tipY}`,
4175
+ `L ${tipX - arrowWidth * Math.cos((-50 + 150) * Math.PI / 180)},${tipY - arrowWidth * Math.sin((-50 + 150) * Math.PI / 180)}`,
4176
+ `L ${tipX - arrowWidth * Math.cos((-50 + 210) * Math.PI / 180)},${tipY - arrowWidth * Math.sin((-50 + 210) * Math.PI / 180)}`,
4177
+ "Z"
4178
+ ].join(" ");
4179
+ return [
4180
+ {
4181
+ name: "path",
4182
+ type: "element",
4183
+ attributes: {
4184
+ d: arrowPath,
4185
+ stroke: colorMap2.schematic.reference,
4186
+ fill: colorMap2.schematic.reference,
4187
+ "stroke-width": `${getSchStrokeSize(transform)}px`
4188
+ },
4189
+ value: "",
4190
+ children: []
4191
+ },
4192
+ {
4193
+ type: "element",
4194
+ name: "text",
4195
+ value: "",
4196
+ attributes: {
4197
+ x: (baseX + 8 - (baseX - baseX)).toString(),
4198
+ y: (baseY - 10 + (baseY - baseY)).toString(),
4199
+ fill: colorMap2.schematic.reference,
4200
+ "text-anchor": "middle",
4201
+ "dominant-baseline": "middle",
4202
+ "font-family": "sans-serif",
4203
+ "font-size": `${getSchScreenFontSize(transform, "reference_designator")}px`,
4204
+ "font-weight": "bold",
4205
+ "data-schematic-voltage-probe-id": probe.schematic_voltage_probe_id
4206
+ },
4207
+ children: [
4208
+ {
4209
+ type: "text",
4210
+ value: probe.voltage ? `${probe.voltage}V` : "",
4211
+ name: "",
4212
+ attributes: {},
4213
+ children: []
4214
+ }
4215
+ ]
4216
+ }
4217
+ ];
4218
+ }
4219
+
4220
+ // lib/sch/svg-object-fns/create-svg-objects-from-sch-debug-object.ts
4221
+ import { applyToPoint as applyToPoint34 } from "transformation-matrix";
4222
+ function createSvgObjectsFromSchDebugObject({
4223
+ debugObject,
4224
+ transform
4225
+ }) {
4226
+ if (debugObject.shape === "rect") {
4227
+ let [screenLeft, screenTop] = applyToPoint34(transform, [
4228
+ debugObject.center.x - debugObject.size.width / 2,
4229
+ debugObject.center.y - debugObject.size.height / 2
4230
+ ]);
4231
+ let [screenRight, screenBottom] = applyToPoint34(transform, [
4232
+ debugObject.center.x + debugObject.size.width / 2,
4233
+ debugObject.center.y + debugObject.size.height / 2
4234
+ ]);
4235
+ [screenTop, screenBottom] = [
4236
+ Math.min(screenTop, screenBottom),
4237
+ Math.max(screenTop, screenBottom)
4238
+ ];
4239
+ const width = Math.abs(screenRight - screenLeft);
4240
+ const height = Math.abs(screenBottom - screenTop);
4241
+ const [screenCenterX, screenCenterY] = applyToPoint34(transform, [
4242
+ debugObject.center.x,
4243
+ debugObject.center.y
4244
+ ]);
4245
+ return [
4246
+ {
4247
+ name: "rect",
4248
+ type: "element",
4249
+ value: "",
4250
+ attributes: {
4251
+ x: screenLeft.toString(),
4252
+ y: screenTop.toString(),
4253
+ width: width.toString(),
4254
+ height: height.toString(),
4255
+ fill: "none",
4256
+ stroke: "red",
4257
+ "stroke-width": (0.02 * Math.abs(transform.a)).toString(),
4258
+ "stroke-dasharray": "5,5"
4259
+ },
4260
+ children: debugObject.label ? [
4261
+ {
4262
+ name: "text",
4263
+ type: "element",
4264
+ value: "",
4265
+ attributes: {
4266
+ x: screenCenterX.toString(),
4267
+ y: (screenCenterY - 10).toString(),
4268
+ "text-anchor": "middle",
4269
+ "font-size": (0.2 * Math.abs(transform.a)).toString(),
4270
+ fill: "red"
4271
+ },
4272
+ children: [
4273
+ {
4274
+ type: "text",
4275
+ value: debugObject.label,
4276
+ name: "",
4277
+ attributes: {},
4278
+ children: []
4279
+ }
4280
+ ]
4281
+ }
4282
+ ] : []
4283
+ }
4284
+ ];
4285
+ }
4286
+ if (debugObject.shape === "line") {
4287
+ const [screenStartX, screenStartY] = applyToPoint34(transform, [
4288
+ debugObject.start.x,
4289
+ debugObject.start.y
4290
+ ]);
4291
+ const [screenEndX, screenEndY] = applyToPoint34(transform, [
4292
+ debugObject.end.x,
4293
+ debugObject.end.y
4294
+ ]);
4295
+ const screenMidX = (screenStartX + screenEndX) / 2;
4296
+ const screenMidY = (screenStartY + screenEndY) / 2;
4297
+ return [
4298
+ {
4299
+ name: "line",
4300
+ type: "element",
4301
+ value: "",
4302
+ attributes: {
4303
+ x1: screenStartX.toString(),
4304
+ y1: screenStartY.toString(),
4305
+ x2: screenEndX.toString(),
4306
+ y2: screenEndY.toString(),
4307
+ stroke: "red",
4308
+ "stroke-width": (0.02 * Math.abs(transform.a)).toString(),
4309
+ "stroke-dasharray": "5,5"
4310
+ },
4311
+ children: debugObject.label ? [
4312
+ {
4313
+ name: "text",
4314
+ type: "element",
4315
+ value: "",
4316
+ attributes: {
4317
+ x: screenMidX.toString(),
4318
+ y: (screenMidY - 10).toString(),
4319
+ "text-anchor": "middle",
4320
+ "font-size": (0.2 * Math.abs(transform.a)).toString(),
4321
+ fill: "red"
4322
+ },
4323
+ children: [
4324
+ {
4325
+ type: "text",
4326
+ value: debugObject.label,
4327
+ name: "",
4328
+ attributes: {},
4329
+ children: []
4330
+ }
4331
+ ]
4332
+ }
4333
+ ] : []
4334
+ }
4335
+ ];
4336
+ }
4337
+ return [];
4338
+ }
4413
4339
 
4414
- // lib/sch/estimate-text-width.ts
4415
- var estimateTextWidth = (text) => {
4416
- if (!text) return 0;
4417
- let totalWidth = 0;
4418
- for (const char of text) {
4419
- const metrics = arialTextMetrics[char];
4420
- if (metrics) {
4421
- totalWidth += metrics.width;
4340
+ // lib/sch/svg-object-fns/create-svg-objects-from-sch-trace.ts
4341
+ import { applyToPoint as applyToPoint35 } from "transformation-matrix";
4342
+ function createSchematicTrace({
4343
+ trace,
4344
+ transform,
4345
+ colorMap: colorMap2
4346
+ }) {
4347
+ const edges = trace.edges;
4348
+ if (edges.length === 0) return [];
4349
+ const svgObjects = [];
4350
+ let path = "";
4351
+ for (let edgeIndex = 0; edgeIndex < edges.length; edgeIndex++) {
4352
+ const edge = edges[edgeIndex];
4353
+ if (edge.is_crossing) continue;
4354
+ const [screenFromX, screenFromY] = applyToPoint35(transform, [
4355
+ edge.from.x,
4356
+ edge.from.y
4357
+ ]);
4358
+ const [screenToX, screenToY] = applyToPoint35(transform, [
4359
+ edge.to.x,
4360
+ edge.to.y
4361
+ ]);
4362
+ if (edgeIndex === 0 || edges[edgeIndex - 1]?.is_crossing) {
4363
+ path += `M ${screenFromX} ${screenFromY} L ${screenToX} ${screenToY}`;
4422
4364
  } else {
4423
- totalWidth += arialTextMetrics["?"].width;
4365
+ path += ` L ${screenToX} ${screenToY}`;
4424
4366
  }
4425
4367
  }
4426
- return totalWidth / 27;
4427
- };
4368
+ for (const edge of edges) {
4369
+ if (!edge.is_crossing) continue;
4370
+ const [screenFromX, screenFromY] = applyToPoint35(transform, [
4371
+ edge.from.x,
4372
+ edge.from.y
4373
+ ]);
4374
+ const [screenToX, screenToY] = applyToPoint35(transform, [
4375
+ edge.to.x,
4376
+ edge.to.y
4377
+ ]);
4378
+ const midX = (screenFromX + screenToX) / 2;
4379
+ const midY = (screenFromY + screenToY) / 2;
4380
+ const dx = screenToX - screenFromX;
4381
+ const dy = screenToY - screenFromY;
4382
+ const len = Math.sqrt(dx * dx + dy * dy);
4383
+ const hopHeight = len * 0.7;
4384
+ const perpX = -dy / len * hopHeight;
4385
+ const perpY = dx / len * hopHeight;
4386
+ const controlX = midX + perpX;
4387
+ const controlY = midY - Math.abs(perpY);
4388
+ svgObjects.push({
4389
+ name: "path",
4390
+ type: "element",
4391
+ attributes: {
4392
+ class: "trace-crossing-outline",
4393
+ d: `M ${screenFromX} ${screenFromY} Q ${controlX} ${controlY} ${screenToX} ${screenToY}`,
4394
+ stroke: colorMap2.schematic.background,
4395
+ fill: "none",
4396
+ "stroke-width": `${getSchStrokeSize(transform) * 1.5}px`,
4397
+ "stroke-linecap": "round"
4398
+ },
4399
+ value: "",
4400
+ children: []
4401
+ });
4402
+ svgObjects.push({
4403
+ name: "path",
4404
+ type: "element",
4405
+ attributes: {
4406
+ d: `M ${screenFromX} ${screenFromY} Q ${controlX} ${controlY} ${screenToX} ${screenToY}`,
4407
+ stroke: colorMap2.schematic.wire,
4408
+ fill: "none",
4409
+ "stroke-width": `${getSchStrokeSize(transform)}px`,
4410
+ "stroke-linecap": "round"
4411
+ },
4412
+ value: "",
4413
+ children: []
4414
+ });
4415
+ }
4416
+ if (path) {
4417
+ svgObjects.push({
4418
+ name: "path",
4419
+ type: "element",
4420
+ attributes: {
4421
+ d: path,
4422
+ class: "trace-invisible-hover-outline",
4423
+ stroke: colorMap2.schematic.wire,
4424
+ fill: "none",
4425
+ "stroke-width": `${getSchStrokeSize(transform) * 8}px`,
4426
+ "stroke-linecap": "round",
4427
+ opacity: "0",
4428
+ "stroke-linejoin": "round"
4429
+ },
4430
+ value: "",
4431
+ children: []
4432
+ });
4433
+ svgObjects.push({
4434
+ name: "path",
4435
+ type: "element",
4436
+ attributes: {
4437
+ d: path,
4438
+ stroke: colorMap2.schematic.wire,
4439
+ fill: "none",
4440
+ "stroke-width": `${getSchStrokeSize(transform)}px`,
4441
+ "stroke-linecap": "round",
4442
+ "stroke-linejoin": "round"
4443
+ },
4444
+ value: "",
4445
+ children: []
4446
+ });
4447
+ }
4448
+ if (trace.junctions) {
4449
+ for (const junction of trace.junctions) {
4450
+ const [screenX, screenY] = applyToPoint35(transform, [
4451
+ junction.x,
4452
+ junction.y
4453
+ ]);
4454
+ svgObjects.push({
4455
+ name: "circle",
4456
+ type: "element",
4457
+ attributes: {
4458
+ cx: screenX.toString(),
4459
+ cy: screenY.toString(),
4460
+ r: (Math.abs(transform.a) * 0.03).toString(),
4461
+ class: "trace-junction",
4462
+ fill: colorMap2.schematic.junction
4463
+ },
4464
+ value: "",
4465
+ children: []
4466
+ });
4467
+ }
4468
+ }
4469
+ return [
4470
+ {
4471
+ name: "g",
4472
+ type: "element",
4473
+ value: "",
4474
+ attributes: {
4475
+ class: "trace",
4476
+ "data-circuit-json-type": "schematic_trace",
4477
+ "data-schematic-trace-id": trace.schematic_trace_id
4478
+ },
4479
+ children: svgObjects
4480
+ }
4481
+ ];
4482
+ }
4483
+
4484
+ // lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label.ts
4485
+ import {
4486
+ applyToPoint as applyToPoint37,
4487
+ compose as compose9,
4488
+ rotate as rotate5,
4489
+ scale as scale6,
4490
+ translate as translate9
4491
+ } from "transformation-matrix";
4428
4492
 
4429
4493
  // lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label-with-symbol.ts
4430
4494
  import {
@@ -4435,37 +4499,6 @@ import {
4435
4499
  translate as translate8
4436
4500
  } from "transformation-matrix";
4437
4501
  import { symbols as symbols3 } from "schematic-symbols";
4438
-
4439
- // lib/utils/net-label-utils.ts
4440
- import "transformation-matrix";
4441
- import "schematic-symbols";
4442
- var ARROW_POINT_WIDTH_FSR = 0.3;
4443
- var END_PADDING_FSR = 0.3;
4444
- var END_PADDING_EXTRA_PER_CHARACTER_FSR = 0.06;
4445
- var ninePointAnchorToTextAnchor2 = {
4446
- top_left: "start",
4447
- top_right: "end",
4448
- middle_left: "start",
4449
- middle_right: "end",
4450
- bottom_left: "start",
4451
- bottom_right: "end",
4452
- center: "middle",
4453
- middle_top: "middle",
4454
- middle_bottom: "middle"
4455
- };
4456
- var ninePointAnchorToDominantBaseline = {
4457
- top_left: "hanging",
4458
- top_right: "hanging",
4459
- bottom_left: "ideographic",
4460
- bottom_right: "ideographic",
4461
- center: "middle",
4462
- middle_left: "middle",
4463
- middle_right: "middle",
4464
- middle_top: "hanging",
4465
- middle_bottom: "ideographic"
4466
- };
4467
-
4468
- // lib/sch/svg-object-fns/create-svg-objects-for-sch-net-label-with-symbol.ts
4469
4502
  var createSvgObjectsForSchNetLabelWithSymbol = ({
4470
4503
  schNetLabel,
4471
4504
  realToScreenTransform,
@@ -4614,7 +4647,7 @@ var createSvgObjectsForSchNetLabelWithSymbol = ({
4614
4647
  y: offsetScreenPos.y.toString(),
4615
4648
  fill: colorMap2.schematic.label_local,
4616
4649
  "font-family": "sans-serif",
4617
- "text-anchor": ninePointAnchorToTextAnchor2[text.anchor],
4650
+ "text-anchor": ninePointAnchorToTextAnchor[text.anchor],
4618
4651
  "dominant-baseline": ninePointAnchorToDominantBaseline[text.anchor],
4619
4652
  "font-size": `${getSchScreenFontSize(realToScreenTransform, "reference_designator")}px`
4620
4653
  },