@tscircuit/core 0.0.145 → 0.0.147
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.d.ts +491 -38
- package/dist/index.js +793 -735
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -25,6 +25,7 @@ __export(components_exports, {
|
|
|
25
25
|
Net: () => Net,
|
|
26
26
|
NetAlias: () => NetAlias,
|
|
27
27
|
NormalComponent: () => NormalComponent,
|
|
28
|
+
PinHeader: () => PinHeader,
|
|
28
29
|
PlatedHole: () => PlatedHole,
|
|
29
30
|
Port: () => Port,
|
|
30
31
|
PowerSource: () => PowerSource,
|
|
@@ -789,6 +790,20 @@ var PrimitiveComponent = class extends Renderable {
|
|
|
789
790
|
}
|
|
790
791
|
return descendants;
|
|
791
792
|
}
|
|
793
|
+
/**
|
|
794
|
+
* Return the number of pins in this component, this is important for
|
|
795
|
+
* NormalComponents
|
|
796
|
+
*/
|
|
797
|
+
_getPinCount() {
|
|
798
|
+
return 0;
|
|
799
|
+
}
|
|
800
|
+
/**
|
|
801
|
+
* If this component represents a SchematicBox (like a Chip), return the
|
|
802
|
+
* dimensions of the box, which allows computing the position of ports etc.
|
|
803
|
+
*/
|
|
804
|
+
_getSchematicBoxDimensions() {
|
|
805
|
+
return null;
|
|
806
|
+
}
|
|
792
807
|
// TODO we shouldn't need to override this, errors can be rendered and handled
|
|
793
808
|
// by the Renderable class, however, the Renderable class currently doesn't
|
|
794
809
|
// have access to the database or cleanup
|
|
@@ -1614,23 +1629,28 @@ var Port = class extends PrimitiveComponent {
|
|
|
1614
1629
|
return this._getPcbCircuitJsonBounds().center;
|
|
1615
1630
|
}
|
|
1616
1631
|
_getGlobalSchematicPositionBeforeLayout() {
|
|
1617
|
-
if (!this.schematicSymbolPortDef) {
|
|
1618
|
-
return applyToPoint4(this.parent.computeSchematicGlobalTransform(), {
|
|
1619
|
-
x: 0,
|
|
1620
|
-
y: 0
|
|
1621
|
-
});
|
|
1622
|
-
}
|
|
1623
1632
|
const symbol = this.parent?.getSchematicSymbol();
|
|
1624
|
-
if (
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
)
|
|
1633
|
-
|
|
1633
|
+
if (symbol && this.schematicSymbolPortDef) {
|
|
1634
|
+
const transform = compose3(
|
|
1635
|
+
this.parent.computeSchematicGlobalTransform(),
|
|
1636
|
+
translate3(-symbol.center.x, -symbol.center.y)
|
|
1637
|
+
);
|
|
1638
|
+
return applyToPoint4(transform, this.schematicSymbolPortDef);
|
|
1639
|
+
}
|
|
1640
|
+
const parentBoxDim = this?.parent?._getSchematicBoxDimensions();
|
|
1641
|
+
if (parentBoxDim && this.props.pinNumber !== void 0) {
|
|
1642
|
+
const localPortPosition = parentBoxDim.getPortPositionByPinNumber(
|
|
1643
|
+
this.props.pinNumber
|
|
1644
|
+
);
|
|
1645
|
+
if (!localPortPosition) {
|
|
1646
|
+
return { x: 0, y: 0 };
|
|
1647
|
+
}
|
|
1648
|
+
return applyToPoint4(
|
|
1649
|
+
this.parent.computeSchematicGlobalTransform(),
|
|
1650
|
+
localPortPosition
|
|
1651
|
+
);
|
|
1652
|
+
}
|
|
1653
|
+
return { x: 0, y: 0 };
|
|
1634
1654
|
}
|
|
1635
1655
|
_getGlobalSchematicPositionAfterLayout() {
|
|
1636
1656
|
const { db } = this.root;
|
|
@@ -1748,17 +1768,16 @@ var Port = class extends PrimitiveComponent {
|
|
|
1748
1768
|
const container = this.getPrimitiveContainer();
|
|
1749
1769
|
if (!container) return;
|
|
1750
1770
|
const containerCenter = container._getGlobalSchematicPositionBeforeLayout();
|
|
1751
|
-
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
center.y += containerCenter.y;
|
|
1771
|
+
const portCenter = this._getGlobalSchematicPositionBeforeLayout();
|
|
1772
|
+
let localPortInfo = null;
|
|
1773
|
+
const containerDims = container._getSchematicBoxDimensions();
|
|
1774
|
+
if (containerDims && props.pinNumber !== void 0) {
|
|
1775
|
+
localPortInfo = containerDims.getPortPositionByPinNumber(props.pinNumber);
|
|
1757
1776
|
}
|
|
1758
1777
|
if (this.getSubcircuit().props._schDebugObjectsEnabled) {
|
|
1759
1778
|
db.schematic_debug_object.insert({
|
|
1760
1779
|
shape: "rect",
|
|
1761
|
-
center,
|
|
1780
|
+
center: portCenter,
|
|
1762
1781
|
size: {
|
|
1763
1782
|
width: 0.1,
|
|
1764
1783
|
height: 0.1
|
|
@@ -1766,12 +1785,16 @@ var Port = class extends PrimitiveComponent {
|
|
|
1766
1785
|
label: "obstacle"
|
|
1767
1786
|
});
|
|
1768
1787
|
}
|
|
1769
|
-
this.facingDirection = getRelativeDirection(containerCenter,
|
|
1788
|
+
this.facingDirection = getRelativeDirection(containerCenter, portCenter);
|
|
1770
1789
|
const schematic_port = db.schematic_port.insert({
|
|
1771
1790
|
schematic_component_id: this.parent?.schematic_component_id,
|
|
1772
|
-
center,
|
|
1791
|
+
center: portCenter,
|
|
1773
1792
|
source_port_id: this.source_port_id,
|
|
1774
|
-
facing_direction: this.facingDirection
|
|
1793
|
+
facing_direction: this.facingDirection,
|
|
1794
|
+
distance_from_component_edge: localPortInfo?.distanceFromEdge,
|
|
1795
|
+
side_of_component: localPortInfo?.side,
|
|
1796
|
+
pin_number: props.pinNumber,
|
|
1797
|
+
true_ccw_index: localPortInfo?.trueIndex
|
|
1775
1798
|
});
|
|
1776
1799
|
this.schematic_port_id = schematic_port.schematic_port_id;
|
|
1777
1800
|
}
|
|
@@ -1804,7 +1827,7 @@ import {
|
|
|
1804
1827
|
isValidElement
|
|
1805
1828
|
} from "react";
|
|
1806
1829
|
import { symbols as symbols2 } from "schematic-symbols";
|
|
1807
|
-
import { z as
|
|
1830
|
+
import { z as z5 } from "zod";
|
|
1808
1831
|
|
|
1809
1832
|
// lib/components/primitive-components/Footprint.ts
|
|
1810
1833
|
import { footprintProps } from "@tscircuit/props";
|
|
@@ -2015,261 +2038,576 @@ var Footprint = class extends PrimitiveComponent {
|
|
|
2015
2038
|
}
|
|
2016
2039
|
};
|
|
2017
2040
|
|
|
2018
|
-
// lib/
|
|
2019
|
-
var
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
this.initPorts();
|
|
2041
|
+
// lib/utils/schematic/getSizeOfSidesFromPortArrangement.ts
|
|
2042
|
+
var hasExplicitPinMapping = (pa) => {
|
|
2043
|
+
for (const side of [
|
|
2044
|
+
"leftSide",
|
|
2045
|
+
"rightSide",
|
|
2046
|
+
"topSide",
|
|
2047
|
+
"bottomSide"
|
|
2048
|
+
]) {
|
|
2049
|
+
if (side in pa && typeof pa[side] === "number") {
|
|
2050
|
+
throw new Error(
|
|
2051
|
+
`A number was specified for "${side}", you probably meant to use "size" not "side"`
|
|
2052
|
+
);
|
|
2053
|
+
}
|
|
2032
2054
|
}
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
|
|
2063
|
-
|
|
2064
|
-
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
}
|
|
2068
|
-
}
|
|
2069
|
-
const sides = ["left", "right", "top", "bottom"];
|
|
2070
|
-
let pinNum = 1;
|
|
2071
|
-
for (const side of sides) {
|
|
2072
|
-
const size = schPortArrangement[`${side}Size`];
|
|
2073
|
-
for (let i = 0; i < size; i++) {
|
|
2074
|
-
portsToCreate.push(
|
|
2075
|
-
new Port(
|
|
2076
|
-
{
|
|
2077
|
-
pinNumber: pinNum++
|
|
2078
|
-
},
|
|
2079
|
-
{
|
|
2080
|
-
originDescription: `schPortArrangement:${side}`
|
|
2081
|
-
}
|
|
2082
|
-
)
|
|
2083
|
-
);
|
|
2084
|
-
}
|
|
2085
|
-
}
|
|
2055
|
+
return "leftSide" in pa || "rightSide" in pa || "topSide" in pa || "bottomSide" in pa;
|
|
2056
|
+
};
|
|
2057
|
+
var getSizeOfSidesFromPortArrangement = (pa) => {
|
|
2058
|
+
if (hasExplicitPinMapping(pa)) {
|
|
2059
|
+
return {
|
|
2060
|
+
leftSize: pa.leftSide?.pins.length ?? 0,
|
|
2061
|
+
rightSize: pa.rightSide?.pins.length ?? 0,
|
|
2062
|
+
topSize: pa.topSide?.pins.length ?? 0,
|
|
2063
|
+
bottomSize: pa.bottomSide?.pins.length ?? 0
|
|
2064
|
+
};
|
|
2065
|
+
}
|
|
2066
|
+
const { leftSize = 0, rightSize = 0, topSize = 0, bottomSize = 0 } = pa;
|
|
2067
|
+
return { leftSize, rightSize, topSize, bottomSize };
|
|
2068
|
+
};
|
|
2069
|
+
|
|
2070
|
+
// lib/utils/schematic/getAllDimensionsForSchematicBox.ts
|
|
2071
|
+
function isExplicitPinMappingArrangement(arrangement) {
|
|
2072
|
+
return arrangement.leftSide !== void 0;
|
|
2073
|
+
}
|
|
2074
|
+
var getAllDimensionsForSchematicBox = (params) => {
|
|
2075
|
+
const componentMargin = params.schPinSpacing;
|
|
2076
|
+
let sidePinCounts = params.schPortArrangement ? getSizeOfSidesFromPortArrangement(params.schPortArrangement) : null;
|
|
2077
|
+
const sideLengths = {
|
|
2078
|
+
left: 0,
|
|
2079
|
+
right: 0,
|
|
2080
|
+
top: 0,
|
|
2081
|
+
bottom: 0
|
|
2082
|
+
};
|
|
2083
|
+
let pinCount = params.pinCount ?? null;
|
|
2084
|
+
if (pinCount === null) {
|
|
2085
|
+
if (sidePinCounts) {
|
|
2086
|
+
pinCount = sidePinCounts.leftSize + sidePinCounts.rightSize + sidePinCounts.topSize + sidePinCounts.bottomSize;
|
|
2087
|
+
} else {
|
|
2088
|
+
throw new Error("Could not determine pin count for the schematic box");
|
|
2086
2089
|
}
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2090
|
+
}
|
|
2091
|
+
if (pinCount && !sidePinCounts) {
|
|
2092
|
+
const rightSize = Math.floor(pinCount / 2);
|
|
2093
|
+
sidePinCounts = {
|
|
2094
|
+
leftSize: pinCount - rightSize,
|
|
2095
|
+
rightSize,
|
|
2096
|
+
topSize: 0,
|
|
2097
|
+
bottomSize: 0
|
|
2098
|
+
};
|
|
2099
|
+
}
|
|
2100
|
+
if (!sidePinCounts) {
|
|
2101
|
+
sidePinCounts = {
|
|
2102
|
+
leftSize: 0,
|
|
2103
|
+
rightSize: 0,
|
|
2104
|
+
topSize: 0,
|
|
2105
|
+
bottomSize: 0
|
|
2106
|
+
};
|
|
2107
|
+
}
|
|
2108
|
+
const schWidth = params.schWidth ?? Math.max(sidePinCounts.topSize, sidePinCounts.bottomSize) * params.schPinSpacing + 2 * componentMargin;
|
|
2109
|
+
const schHeight = params.schHeight ?? Math.max(sidePinCounts.leftSize, sidePinCounts.rightSize) * params.schPinSpacing + 2 * componentMargin;
|
|
2110
|
+
const distributePorts = (sideSize, sideLength, totalMargin) => {
|
|
2111
|
+
if (sideSize <= 1) return 0;
|
|
2112
|
+
return (sideLength - totalMargin) / (sideSize - 1);
|
|
2113
|
+
};
|
|
2114
|
+
const orderedTruePorts = [];
|
|
2115
|
+
let truePinIndex = 0;
|
|
2116
|
+
const processSide = (side, pins, direction) => {
|
|
2117
|
+
const isVertical = side === "left" || side === "right";
|
|
2118
|
+
const sideLength = isVertical ? schHeight : schWidth;
|
|
2119
|
+
let totalMargin = 0;
|
|
2120
|
+
for (const pin of pins) {
|
|
2121
|
+
const pinStyle = params.schPinStyle?.[`pin${pin}`] ?? params.schPinStyle?.[pin];
|
|
2122
|
+
if (pinStyle) {
|
|
2123
|
+
if (isVertical) {
|
|
2124
|
+
totalMargin += (pinStyle.topMargin ?? 0) + (pinStyle.bottomMargin ?? 0);
|
|
2108
2125
|
} else {
|
|
2109
|
-
|
|
2110
|
-
existingPort.props.name = primaryLabel;
|
|
2126
|
+
totalMargin += (pinStyle.leftMargin ?? 0) + (pinStyle.rightMargin ?? 0);
|
|
2111
2127
|
}
|
|
2112
2128
|
}
|
|
2113
2129
|
}
|
|
2114
|
-
|
|
2115
|
-
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2130
|
+
const spacing = distributePorts(
|
|
2131
|
+
pins.length,
|
|
2132
|
+
sideLength - 2 * componentMargin,
|
|
2133
|
+
totalMargin
|
|
2134
|
+
);
|
|
2135
|
+
let currentDistanceFromEdge = componentMargin;
|
|
2136
|
+
pins.forEach((pinNumber, index) => {
|
|
2137
|
+
const pinStyle = params.schPinStyle?.[`pin${pinNumber}`] ?? params.schPinStyle?.[pinNumber];
|
|
2138
|
+
if (pinStyle) {
|
|
2139
|
+
if (isVertical) {
|
|
2140
|
+
if (side === "left") {
|
|
2141
|
+
currentDistanceFromEdge += direction === "top-to-bottom" ? pinStyle.topMargin ?? 0 : pinStyle.bottomMargin ?? 0;
|
|
2142
|
+
} else {
|
|
2143
|
+
currentDistanceFromEdge += direction === "top-to-bottom" ? pinStyle.bottomMargin ?? 0 : pinStyle.topMargin ?? 0;
|
|
2144
|
+
}
|
|
2145
|
+
} else {
|
|
2146
|
+
if (side === "top") {
|
|
2147
|
+
currentDistanceFromEdge += direction === "left-to-right" ? pinStyle.leftMargin ?? 0 : pinStyle.rightMargin ?? 0;
|
|
2148
|
+
} else {
|
|
2149
|
+
currentDistanceFromEdge += direction === "left-to-right" ? pinStyle.rightMargin ?? 0 : pinStyle.leftMargin ?? 0;
|
|
2150
|
+
}
|
|
2123
2151
|
}
|
|
2124
2152
|
}
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2153
|
+
orderedTruePorts.push({
|
|
2154
|
+
trueIndex: truePinIndex,
|
|
2155
|
+
pinNumber,
|
|
2156
|
+
side,
|
|
2157
|
+
distanceFromEdge: currentDistanceFromEdge,
|
|
2158
|
+
x: 0,
|
|
2159
|
+
y: 0
|
|
2160
|
+
});
|
|
2161
|
+
if (pinStyle) {
|
|
2162
|
+
if (isVertical) {
|
|
2163
|
+
if (side === "left") {
|
|
2164
|
+
currentDistanceFromEdge += direction === "top-to-bottom" ? pinStyle.bottomMargin ?? 0 : pinStyle.topMargin ?? 0;
|
|
2165
|
+
} else {
|
|
2166
|
+
currentDistanceFromEdge += direction === "top-to-bottom" ? pinStyle.topMargin ?? 0 : pinStyle.bottomMargin ?? 0;
|
|
2167
|
+
}
|
|
2168
|
+
} else {
|
|
2169
|
+
if (side === "top") {
|
|
2170
|
+
currentDistanceFromEdge += direction === "left-to-right" ? pinStyle.rightMargin ?? 0 : pinStyle.leftMargin ?? 0;
|
|
2171
|
+
} else {
|
|
2172
|
+
currentDistanceFromEdge += direction === "left-to-right" ? pinStyle.leftMargin ?? 0 : pinStyle.rightMargin ?? 0;
|
|
2173
|
+
}
|
|
2174
|
+
}
|
|
2132
2175
|
}
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
this.addAll(portsToCreate);
|
|
2136
|
-
}
|
|
2137
|
-
}
|
|
2138
|
-
_addChildrenFromStringFootprint() {
|
|
2139
|
-
const { footprint } = this.props;
|
|
2140
|
-
if (!footprint) return;
|
|
2141
|
-
if (typeof footprint === "string") {
|
|
2142
|
-
const fpSoup = fp.string(footprint).soup();
|
|
2143
|
-
const fpComponents = createComponentsFromSoup(fpSoup);
|
|
2144
|
-
this.addAll(fpComponents);
|
|
2145
|
-
}
|
|
2146
|
-
}
|
|
2147
|
-
get portMap() {
|
|
2148
|
-
return new Proxy(
|
|
2149
|
-
{},
|
|
2150
|
-
{
|
|
2151
|
-
get: (target, prop) => {
|
|
2152
|
-
const port = this.children.find(
|
|
2153
|
-
(c) => c.componentName === "Port" && c.isMatchingNameOrAlias(prop)
|
|
2154
|
-
);
|
|
2155
|
-
if (!port) {
|
|
2156
|
-
throw new Error(
|
|
2157
|
-
`There was an issue finding the port "${prop.toString()}" inside of a ${this.componentName} component with name: "${this.props.name}". This is a bug in @tscircuit/core`
|
|
2158
|
-
);
|
|
2159
|
-
}
|
|
2160
|
-
return port;
|
|
2161
|
-
}
|
|
2162
|
-
}
|
|
2163
|
-
);
|
|
2164
|
-
}
|
|
2165
|
-
getInstanceForReactElement(element) {
|
|
2166
|
-
for (const subtree of this.reactSubtrees) {
|
|
2167
|
-
if (subtree.element === element) return subtree.component;
|
|
2168
|
-
}
|
|
2169
|
-
return null;
|
|
2170
|
-
}
|
|
2171
|
-
doInitialSourceRender() {
|
|
2172
|
-
const ftype = this.config.sourceFtype;
|
|
2173
|
-
if (!ftype) return;
|
|
2174
|
-
const { db } = this.root;
|
|
2175
|
-
const { _parsedProps: props } = this;
|
|
2176
|
-
const source_component = db.source_component.insert({
|
|
2177
|
-
ftype,
|
|
2178
|
-
name: props.name,
|
|
2179
|
-
manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
|
|
2180
|
-
supplier_part_numbers: props.supplierPartNumbers
|
|
2176
|
+
currentDistanceFromEdge += spacing;
|
|
2177
|
+
truePinIndex++;
|
|
2181
2178
|
});
|
|
2182
|
-
|
|
2183
|
-
}
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
doInitialSchematicComponentRender() {
|
|
2191
|
-
const { db } = this.root;
|
|
2192
|
-
const { schematicSymbolName } = this.config;
|
|
2193
|
-
if (!schematicSymbolName) return;
|
|
2194
|
-
const base_symbol_name = this.config.schematicSymbolName;
|
|
2195
|
-
const symbol_name_horz = `${base_symbol_name}_horz`;
|
|
2196
|
-
let symbol_name;
|
|
2197
|
-
if (!base_symbol_name) {
|
|
2198
|
-
throw new Error(
|
|
2199
|
-
"No schematic symbol defined (schematicSymbolName not provided)"
|
|
2179
|
+
sideLengths[side] = sideLength;
|
|
2180
|
+
};
|
|
2181
|
+
if (params.schPortArrangement && isExplicitPinMappingArrangement(params.schPortArrangement)) {
|
|
2182
|
+
if (params.schPortArrangement.leftSide) {
|
|
2183
|
+
processSide(
|
|
2184
|
+
"left",
|
|
2185
|
+
params.schPortArrangement.leftSide.pins,
|
|
2186
|
+
params.schPortArrangement.leftSide.direction ?? "top-to-bottom"
|
|
2200
2187
|
);
|
|
2201
2188
|
}
|
|
2202
|
-
if (
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2189
|
+
if (params.schPortArrangement.rightSide) {
|
|
2190
|
+
processSide(
|
|
2191
|
+
"right",
|
|
2192
|
+
params.schPortArrangement.rightSide.pins,
|
|
2193
|
+
params.schPortArrangement.rightSide.direction ?? "bottom-to-top"
|
|
2194
|
+
);
|
|
2208
2195
|
}
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2196
|
+
if (params.schPortArrangement.topSide) {
|
|
2197
|
+
processSide(
|
|
2198
|
+
"top",
|
|
2199
|
+
params.schPortArrangement.topSide.pins,
|
|
2200
|
+
params.schPortArrangement.topSide.direction ?? "left-to-right"
|
|
2201
|
+
);
|
|
2212
2202
|
}
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
}
|
|
2220
|
-
|
|
2203
|
+
if (params.schPortArrangement.bottomSide) {
|
|
2204
|
+
processSide(
|
|
2205
|
+
"bottom",
|
|
2206
|
+
params.schPortArrangement.bottomSide.pins,
|
|
2207
|
+
params.schPortArrangement.bottomSide.direction ?? "left-to-right"
|
|
2208
|
+
);
|
|
2209
|
+
}
|
|
2210
|
+
} else {
|
|
2211
|
+
const leftSide = Array.from(
|
|
2212
|
+
{ length: sidePinCounts.leftSize },
|
|
2213
|
+
(_, i) => i + 1
|
|
2214
|
+
);
|
|
2215
|
+
const rightSide = Array.from(
|
|
2216
|
+
{ length: sidePinCounts.rightSize },
|
|
2217
|
+
(_, i) => i + sidePinCounts.leftSize + 1
|
|
2218
|
+
);
|
|
2219
|
+
const topSide = Array.from(
|
|
2220
|
+
{ length: sidePinCounts.topSize },
|
|
2221
|
+
(_, i) => i + sidePinCounts.leftSize + sidePinCounts.rightSize + 1
|
|
2222
|
+
);
|
|
2223
|
+
const bottomSide = Array.from(
|
|
2224
|
+
{
|
|
2225
|
+
length: pinCount - sidePinCounts.leftSize - sidePinCounts.rightSize - sidePinCounts.topSize
|
|
2226
|
+
},
|
|
2227
|
+
(_, i) => i + sidePinCounts.leftSize + sidePinCounts.rightSize + sidePinCounts.topSize + 1
|
|
2228
|
+
);
|
|
2229
|
+
processSide("left", leftSide, "top-to-bottom");
|
|
2230
|
+
processSide("right", rightSide, "top-to-bottom");
|
|
2231
|
+
processSide("top", topSide, "left-to-right");
|
|
2232
|
+
processSide("bottom", bottomSide, "left-to-right");
|
|
2221
2233
|
}
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2226
|
-
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2234
|
+
const trueEdgePositions = {
|
|
2235
|
+
left: { x: -schWidth / 2 - 0.2, y: schHeight / 2 },
|
|
2236
|
+
bottom: { x: -schWidth / 2, y: schHeight / 2 + 0.2 },
|
|
2237
|
+
right: { x: schWidth / 2 + 0.2, y: -schHeight / 2 },
|
|
2238
|
+
top: { x: schWidth / 2, y: -schHeight / 2 - 0.2 }
|
|
2239
|
+
};
|
|
2240
|
+
const trueEdgeTraversalDirections = {
|
|
2241
|
+
left: { x: 0, y: -1 },
|
|
2242
|
+
right: { x: 0, y: 1 },
|
|
2243
|
+
top: { x: -1, y: 0 },
|
|
2244
|
+
bottom: { x: 1, y: 0 }
|
|
2245
|
+
};
|
|
2246
|
+
const truePortsWithPositions = orderedTruePorts.map((p) => {
|
|
2247
|
+
const { distanceFromEdge, side } = p;
|
|
2248
|
+
const edgePos = trueEdgePositions[side];
|
|
2249
|
+
const edgeDir = trueEdgeTraversalDirections[side];
|
|
2250
|
+
return {
|
|
2251
|
+
...p,
|
|
2252
|
+
x: edgePos.x + distanceFromEdge * edgeDir.x,
|
|
2253
|
+
y: edgePos.y + distanceFromEdge * edgeDir.y
|
|
2254
|
+
};
|
|
2255
|
+
});
|
|
2256
|
+
return {
|
|
2257
|
+
getPortPositionByPinNumber(pinNumber) {
|
|
2258
|
+
const port = truePortsWithPositions.find(
|
|
2259
|
+
(p) => p.pinNumber.toString() === pinNumber.toString()
|
|
2260
|
+
);
|
|
2261
|
+
if (!port) {
|
|
2262
|
+
return null;
|
|
2263
|
+
}
|
|
2264
|
+
return port;
|
|
2265
|
+
},
|
|
2266
|
+
getSize() {
|
|
2267
|
+
return { width: schWidth, height: schHeight };
|
|
2268
|
+
},
|
|
2269
|
+
pinCount
|
|
2270
|
+
};
|
|
2271
|
+
};
|
|
2272
|
+
|
|
2273
|
+
// lib/soup/underscorifyPortArrangement.ts
|
|
2274
|
+
var underscorifyPortArrangement = (portArrangement) => {
|
|
2275
|
+
if (!portArrangement) return void 0;
|
|
2276
|
+
if ("leftSide" in portArrangement || "rightSide" in portArrangement || "topSide" in portArrangement || "bottomSide" in portArrangement) {
|
|
2277
|
+
return {
|
|
2278
|
+
left_side: portArrangement.leftSide,
|
|
2279
|
+
right_side: portArrangement.rightSide,
|
|
2280
|
+
top_side: portArrangement.topSide,
|
|
2281
|
+
bottom_side: portArrangement.bottomSide
|
|
2282
|
+
};
|
|
2235
2283
|
}
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
const { db } = this.root;
|
|
2243
|
-
const { _parsedProps: props } = this;
|
|
2244
|
-
const bounds = getBoundsOfPcbComponents(this.children);
|
|
2245
|
-
if (bounds.width === 0 || bounds.height === 0) return;
|
|
2246
|
-
const center = {
|
|
2247
|
-
x: (bounds.minX + bounds.maxX) / 2,
|
|
2248
|
-
y: (bounds.minY + bounds.maxY) / 2
|
|
2284
|
+
if ("leftPinCount" in portArrangement || "rightPinCount" in portArrangement || "topPinCount" in portArrangement || "bottomPinCount" in portArrangement) {
|
|
2285
|
+
return {
|
|
2286
|
+
left_size: portArrangement.leftPinCount,
|
|
2287
|
+
right_size: portArrangement.rightPinCount,
|
|
2288
|
+
top_size: portArrangement.topPinCount,
|
|
2289
|
+
bottom_size: portArrangement.bottomPinCount
|
|
2249
2290
|
};
|
|
2250
|
-
db.pcb_component.update(this.pcb_component_id, {
|
|
2251
|
-
center,
|
|
2252
|
-
width: bounds.width,
|
|
2253
|
-
height: bounds.height
|
|
2254
|
-
});
|
|
2255
2291
|
}
|
|
2256
|
-
|
|
2292
|
+
if ("leftSize" in portArrangement || "rightSize" in portArrangement || "topSize" in portArrangement || "bottomSize" in portArrangement) {
|
|
2257
2293
|
return {
|
|
2258
|
-
|
|
2259
|
-
|
|
2294
|
+
left_size: portArrangement.leftSize,
|
|
2295
|
+
right_size: portArrangement.rightSize,
|
|
2296
|
+
top_size: portArrangement.topSize,
|
|
2297
|
+
bottom_size: portArrangement.bottomSize
|
|
2260
2298
|
};
|
|
2261
2299
|
}
|
|
2262
|
-
|
|
2300
|
+
return void 0;
|
|
2301
|
+
};
|
|
2302
|
+
|
|
2303
|
+
// lib/soup/underscorifyPinStyles.ts
|
|
2304
|
+
import "circuit-json";
|
|
2305
|
+
import "zod";
|
|
2306
|
+
var underscorifyPinStyles = (pinStyles) => {
|
|
2307
|
+
if (!pinStyles) return void 0;
|
|
2308
|
+
const underscorePinStyles = {};
|
|
2309
|
+
for (const [pinName, pinStyle] of Object.entries(pinStyles)) {
|
|
2310
|
+
underscorePinStyles[pinName] = {
|
|
2311
|
+
bottom_margin: pinStyle.bottomMargin,
|
|
2312
|
+
left_margin: pinStyle.leftMargin,
|
|
2313
|
+
right_margin: pinStyle.rightMargin,
|
|
2314
|
+
top_margin: pinStyle.topMargin
|
|
2315
|
+
};
|
|
2316
|
+
}
|
|
2317
|
+
return underscorePinStyles;
|
|
2318
|
+
};
|
|
2319
|
+
|
|
2320
|
+
// lib/components/base-components/NormalComponent.ts
|
|
2321
|
+
var debug2 = Debug2("tscircuit:core");
|
|
2322
|
+
var rotation3 = z5.object({
|
|
2323
|
+
x: rotation,
|
|
2324
|
+
y: rotation,
|
|
2325
|
+
z: rotation
|
|
2326
|
+
});
|
|
2327
|
+
var NormalComponent = class extends PrimitiveComponent {
|
|
2328
|
+
reactSubtrees = [];
|
|
2329
|
+
_impliedFootprint;
|
|
2330
|
+
isPrimitiveContainer = true;
|
|
2331
|
+
constructor(props) {
|
|
2332
|
+
super(props);
|
|
2333
|
+
this._addChildrenFromStringFootprint();
|
|
2263
2334
|
this.initPorts();
|
|
2264
2335
|
}
|
|
2265
|
-
|
|
2266
|
-
|
|
2267
|
-
|
|
2268
|
-
|
|
2269
|
-
|
|
2270
|
-
|
|
2271
|
-
|
|
2272
|
-
|
|
2336
|
+
/**
|
|
2337
|
+
* Override this method for better control over the auto-discovery of ports.
|
|
2338
|
+
*
|
|
2339
|
+
* If you override this method just do something like:
|
|
2340
|
+
* initPorts() {
|
|
2341
|
+
* this.add(new Port({ pinNumber: 1, aliases: ["anode", "pos"] }))
|
|
2342
|
+
* this.add(new Port({ pinNumber: 2, aliases: ["cathode", "neg"] }))
|
|
2343
|
+
* }
|
|
2344
|
+
*
|
|
2345
|
+
* By default, we'll pull the ports from the first place we find them:
|
|
2346
|
+
* 1. `config.schematicSymbolName`
|
|
2347
|
+
* 2. `props.footprint`
|
|
2348
|
+
*
|
|
2349
|
+
*/
|
|
2350
|
+
initPorts() {
|
|
2351
|
+
const { config } = this;
|
|
2352
|
+
const portsToCreate = [];
|
|
2353
|
+
const schPortArrangement = this._parsedProps.schPortArrangement;
|
|
2354
|
+
if (schPortArrangement) {
|
|
2355
|
+
for (const side in schPortArrangement) {
|
|
2356
|
+
const pins = schPortArrangement[side].pins;
|
|
2357
|
+
if (Array.isArray(pins)) {
|
|
2358
|
+
for (const pinNumber of pins) {
|
|
2359
|
+
portsToCreate.push(
|
|
2360
|
+
new Port(
|
|
2361
|
+
{
|
|
2362
|
+
pinNumber
|
|
2363
|
+
},
|
|
2364
|
+
{
|
|
2365
|
+
originDescription: `schPortArrangement:${side}`
|
|
2366
|
+
}
|
|
2367
|
+
)
|
|
2368
|
+
);
|
|
2369
|
+
}
|
|
2370
|
+
}
|
|
2371
|
+
}
|
|
2372
|
+
const sides = ["left", "right", "top", "bottom"];
|
|
2373
|
+
let pinNum = 1;
|
|
2374
|
+
for (const side of sides) {
|
|
2375
|
+
const size = schPortArrangement[`${side}Size`];
|
|
2376
|
+
for (let i = 0; i < size; i++) {
|
|
2377
|
+
portsToCreate.push(
|
|
2378
|
+
new Port(
|
|
2379
|
+
{
|
|
2380
|
+
pinNumber: pinNum++
|
|
2381
|
+
},
|
|
2382
|
+
{
|
|
2383
|
+
originDescription: `schPortArrangement:${side}`
|
|
2384
|
+
}
|
|
2385
|
+
)
|
|
2386
|
+
);
|
|
2387
|
+
}
|
|
2388
|
+
}
|
|
2389
|
+
}
|
|
2390
|
+
const pinLabels = this._parsedProps.pinLabels;
|
|
2391
|
+
if (pinLabels) {
|
|
2392
|
+
for (let [pinNumber, label] of Object.entries(pinLabels)) {
|
|
2393
|
+
pinNumber = pinNumber.replace("pin", "");
|
|
2394
|
+
let existingPort = portsToCreate.find(
|
|
2395
|
+
(p) => p._parsedProps.pinNumber === Number(pinNumber)
|
|
2396
|
+
);
|
|
2397
|
+
const primaryLabel = Array.isArray(label) ? label[0] : label;
|
|
2398
|
+
const otherLabels = Array.isArray(label) ? label.slice(1) : [];
|
|
2399
|
+
if (!existingPort) {
|
|
2400
|
+
existingPort = new Port(
|
|
2401
|
+
{
|
|
2402
|
+
pinNumber: parseInt(pinNumber),
|
|
2403
|
+
name: primaryLabel,
|
|
2404
|
+
aliases: otherLabels
|
|
2405
|
+
},
|
|
2406
|
+
{
|
|
2407
|
+
originDescription: `pinLabels:pin${pinNumber}`
|
|
2408
|
+
}
|
|
2409
|
+
);
|
|
2410
|
+
portsToCreate.push(existingPort);
|
|
2411
|
+
} else {
|
|
2412
|
+
existingPort.externallyAddedAliases.push(primaryLabel, ...otherLabels);
|
|
2413
|
+
existingPort.props.name = primaryLabel;
|
|
2414
|
+
}
|
|
2415
|
+
}
|
|
2416
|
+
}
|
|
2417
|
+
if (config.schematicSymbolName) {
|
|
2418
|
+
const sym = symbols2[`${config.schematicSymbolName}_horz`];
|
|
2419
|
+
if (!sym) return;
|
|
2420
|
+
for (const symPort of sym.ports) {
|
|
2421
|
+
const port = getPortFromHints(symPort.labels);
|
|
2422
|
+
if (port) {
|
|
2423
|
+
port.originDescription = `schematicSymbol:labels[0]:${symPort.labels[0]}`;
|
|
2424
|
+
port.schematicSymbolPortDef = symPort;
|
|
2425
|
+
portsToCreate.push(port);
|
|
2426
|
+
}
|
|
2427
|
+
}
|
|
2428
|
+
this.addAll(portsToCreate);
|
|
2429
|
+
return;
|
|
2430
|
+
}
|
|
2431
|
+
const portsFromFootprint = this.getPortsFromFootprint();
|
|
2432
|
+
for (const port of portsFromFootprint) {
|
|
2433
|
+
if (!portsToCreate.some((p) => p.isMatchingAnyOf(port.getNameAndAliases()))) {
|
|
2434
|
+
portsToCreate.push(port);
|
|
2435
|
+
}
|
|
2436
|
+
}
|
|
2437
|
+
if (portsToCreate.length > 0) {
|
|
2438
|
+
this.addAll(portsToCreate);
|
|
2439
|
+
}
|
|
2440
|
+
}
|
|
2441
|
+
_getImpliedFootprintString() {
|
|
2442
|
+
return null;
|
|
2443
|
+
}
|
|
2444
|
+
_addChildrenFromStringFootprint() {
|
|
2445
|
+
let { footprint } = this.props;
|
|
2446
|
+
footprint ??= this._getImpliedFootprintString?.();
|
|
2447
|
+
if (!footprint) return;
|
|
2448
|
+
if (typeof footprint === "string") {
|
|
2449
|
+
const fpSoup = fp.string(footprint).soup();
|
|
2450
|
+
const fpComponents = createComponentsFromSoup(fpSoup);
|
|
2451
|
+
this.addAll(fpComponents);
|
|
2452
|
+
}
|
|
2453
|
+
}
|
|
2454
|
+
get portMap() {
|
|
2455
|
+
return new Proxy(
|
|
2456
|
+
{},
|
|
2457
|
+
{
|
|
2458
|
+
get: (target, prop) => {
|
|
2459
|
+
const port = this.children.find(
|
|
2460
|
+
(c) => c.componentName === "Port" && c.isMatchingNameOrAlias(prop)
|
|
2461
|
+
);
|
|
2462
|
+
if (!port) {
|
|
2463
|
+
throw new Error(
|
|
2464
|
+
`There was an issue finding the port "${prop.toString()}" inside of a ${this.componentName} component with name: "${this.props.name}". This is a bug in @tscircuit/core`
|
|
2465
|
+
);
|
|
2466
|
+
}
|
|
2467
|
+
return port;
|
|
2468
|
+
}
|
|
2469
|
+
}
|
|
2470
|
+
);
|
|
2471
|
+
}
|
|
2472
|
+
getInstanceForReactElement(element) {
|
|
2473
|
+
for (const subtree of this.reactSubtrees) {
|
|
2474
|
+
if (subtree.element === element) return subtree.component;
|
|
2475
|
+
}
|
|
2476
|
+
return null;
|
|
2477
|
+
}
|
|
2478
|
+
doInitialSourceRender() {
|
|
2479
|
+
const ftype = this.config.sourceFtype;
|
|
2480
|
+
if (!ftype) return;
|
|
2481
|
+
const { db } = this.root;
|
|
2482
|
+
const { _parsedProps: props } = this;
|
|
2483
|
+
const source_component = db.source_component.insert({
|
|
2484
|
+
ftype,
|
|
2485
|
+
name: props.name,
|
|
2486
|
+
manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
|
|
2487
|
+
supplier_part_numbers: props.supplierPartNumbers
|
|
2488
|
+
});
|
|
2489
|
+
this.source_component_id = source_component.source_component_id;
|
|
2490
|
+
}
|
|
2491
|
+
/**
|
|
2492
|
+
* Render the schematic component for this NormalComponent using the
|
|
2493
|
+
* config.schematicSymbolName if it exists, or create a generic box if
|
|
2494
|
+
* no symbol is defined.
|
|
2495
|
+
*
|
|
2496
|
+
* You can override this method to do more complicated things.
|
|
2497
|
+
*/
|
|
2498
|
+
doInitialSchematicComponentRender() {
|
|
2499
|
+
const { schematicSymbolName } = this.config;
|
|
2500
|
+
if (schematicSymbolName) {
|
|
2501
|
+
return this._doInitialSchematicComponentRenderWithSymbol();
|
|
2502
|
+
}
|
|
2503
|
+
const dimensions = this._getSchematicBoxDimensions();
|
|
2504
|
+
if (dimensions) {
|
|
2505
|
+
return this._doInitialSchematicComponentRenderWithSchematicBoxDimensions();
|
|
2506
|
+
}
|
|
2507
|
+
}
|
|
2508
|
+
_doInitialSchematicComponentRenderWithSymbol() {
|
|
2509
|
+
const { db } = this.root;
|
|
2510
|
+
const base_symbol_name = this.config.schematicSymbolName;
|
|
2511
|
+
const symbol_name_horz = `${base_symbol_name}_horz`;
|
|
2512
|
+
let symbol_name;
|
|
2513
|
+
if (!base_symbol_name) {
|
|
2514
|
+
throw new Error(
|
|
2515
|
+
"No schematic symbol defined (schematicSymbolName not provided)"
|
|
2516
|
+
);
|
|
2517
|
+
}
|
|
2518
|
+
if (base_symbol_name in symbols2) {
|
|
2519
|
+
symbol_name = base_symbol_name;
|
|
2520
|
+
} else if (symbol_name_horz in symbols2) {
|
|
2521
|
+
symbol_name = symbol_name_horz;
|
|
2522
|
+
} else {
|
|
2523
|
+
throw new Error(`Could not find schematic-symbol: "${base_symbol_name}"`);
|
|
2524
|
+
}
|
|
2525
|
+
const symbol = symbols2[symbol_name];
|
|
2526
|
+
if (symbol) {
|
|
2527
|
+
const schematic_component2 = db.schematic_component.insert({
|
|
2528
|
+
center: { x: this.props.schX ?? 0, y: this.props.schY ?? 0 },
|
|
2529
|
+
rotation: this.props.schRotation ?? 0,
|
|
2530
|
+
size: symbol.size,
|
|
2531
|
+
source_component_id: this.source_component_id,
|
|
2532
|
+
symbol_name
|
|
2533
|
+
});
|
|
2534
|
+
this.schematic_component_id = schematic_component2.schematic_component_id;
|
|
2535
|
+
}
|
|
2536
|
+
}
|
|
2537
|
+
_doInitialSchematicComponentRenderWithSchematicBoxDimensions() {
|
|
2538
|
+
const { db } = this.root;
|
|
2539
|
+
const { _parsedProps: props } = this;
|
|
2540
|
+
const dimensions = this._getSchematicBoxDimensions();
|
|
2541
|
+
const primaryPortLabels = {};
|
|
2542
|
+
for (const [port, label] of Object.entries(props.pinLabels ?? {})) {
|
|
2543
|
+
primaryPortLabels[port] = Array.isArray(label) ? label[0] : label;
|
|
2544
|
+
}
|
|
2545
|
+
const schematic_component2 = db.schematic_component.insert({
|
|
2546
|
+
center: { x: props.schX ?? 0, y: props.schY ?? 0 },
|
|
2547
|
+
rotation: props.schRotation ?? 0,
|
|
2548
|
+
size: dimensions.getSize(),
|
|
2549
|
+
port_arrangement: underscorifyPortArrangement(
|
|
2550
|
+
props.schPortArrangement
|
|
2551
|
+
),
|
|
2552
|
+
pin_spacing: props.schPinSpacing ?? 0.2,
|
|
2553
|
+
// @ts-ignore soup needs to support distance for pin_styles
|
|
2554
|
+
pin_styles: underscorifyPinStyles(props.schPinStyle),
|
|
2555
|
+
port_labels: primaryPortLabels,
|
|
2556
|
+
source_component_id: this.source_component_id
|
|
2557
|
+
});
|
|
2558
|
+
this.schematic_component_id = schematic_component2.schematic_component_id;
|
|
2559
|
+
}
|
|
2560
|
+
doInitialPcbComponentRender() {
|
|
2561
|
+
const { db } = this.root;
|
|
2562
|
+
const { _parsedProps: props } = this;
|
|
2563
|
+
const pcb_component = db.pcb_component.insert({
|
|
2564
|
+
center: this._getGlobalPcbPositionBeforeLayout(),
|
|
2565
|
+
// width/height are computed in the PcbComponentSizeCalculation phase
|
|
2566
|
+
width: 0,
|
|
2567
|
+
height: 0,
|
|
2568
|
+
layer: props.layer ?? "top",
|
|
2569
|
+
rotation: props.pcbRotation ?? 0,
|
|
2570
|
+
source_component_id: this.source_component_id
|
|
2571
|
+
});
|
|
2572
|
+
this.pcb_component_id = pcb_component.pcb_component_id;
|
|
2573
|
+
}
|
|
2574
|
+
/**
|
|
2575
|
+
* At this stage, the smtpads/pcb primitives are placed, so we can compute
|
|
2576
|
+
* the width/height of the component
|
|
2577
|
+
*/
|
|
2578
|
+
doInitialPcbComponentSizeCalculation() {
|
|
2579
|
+
if (!this.pcb_component_id) return;
|
|
2580
|
+
const { db } = this.root;
|
|
2581
|
+
const { _parsedProps: props } = this;
|
|
2582
|
+
const bounds = getBoundsOfPcbComponents(this.children);
|
|
2583
|
+
if (bounds.width === 0 || bounds.height === 0) return;
|
|
2584
|
+
const center = {
|
|
2585
|
+
x: (bounds.minX + bounds.maxX) / 2,
|
|
2586
|
+
y: (bounds.minY + bounds.maxY) / 2
|
|
2587
|
+
};
|
|
2588
|
+
db.pcb_component.update(this.pcb_component_id, {
|
|
2589
|
+
center,
|
|
2590
|
+
width: bounds.width,
|
|
2591
|
+
height: bounds.height
|
|
2592
|
+
});
|
|
2593
|
+
}
|
|
2594
|
+
_renderReactSubtree(element) {
|
|
2595
|
+
return {
|
|
2596
|
+
element,
|
|
2597
|
+
component: createInstanceFromReactElement(element)
|
|
2598
|
+
};
|
|
2599
|
+
}
|
|
2600
|
+
doInitialInitializePortsFromChildren() {
|
|
2601
|
+
this.initPorts();
|
|
2602
|
+
}
|
|
2603
|
+
doInitialReactSubtreesRender() {
|
|
2604
|
+
if (isReactElement(this.props.footprint)) {
|
|
2605
|
+
if (this.reactSubtrees.some((rs) => rs.element === this.props.footprint))
|
|
2606
|
+
return;
|
|
2607
|
+
const subtree = this._renderReactSubtree(this.props.footprint);
|
|
2608
|
+
this.reactSubtrees.push(subtree);
|
|
2609
|
+
this.add(subtree.component);
|
|
2610
|
+
}
|
|
2273
2611
|
}
|
|
2274
2612
|
_hasExistingPortExactly(port1) {
|
|
2275
2613
|
const existingPorts = this.children.filter(
|
|
@@ -2420,8 +2758,37 @@ var NormalComponent = class extends PrimitiveComponent {
|
|
|
2420
2758
|
height: pcb_component.height
|
|
2421
2759
|
};
|
|
2422
2760
|
}
|
|
2423
|
-
|
|
2424
|
-
const
|
|
2761
|
+
_getPinCount() {
|
|
2762
|
+
const schPortArrangement = this._getSchematicPortArrangement();
|
|
2763
|
+
const pinCountFromSchArrangement = (schPortArrangement?.leftSize ?? 0) + (schPortArrangement?.rightSize ?? 0) + (schPortArrangement?.topSize ?? 0) + (schPortArrangement?.bottomSize ?? 0);
|
|
2764
|
+
const pinCount = pinCountFromSchArrangement || this.getPortsFromFootprint().length;
|
|
2765
|
+
return pinCount;
|
|
2766
|
+
}
|
|
2767
|
+
/**
|
|
2768
|
+
* Override the schematic port arrangement if you want to customize where pins
|
|
2769
|
+
* appear on a schematic box, e.g. for a pin header
|
|
2770
|
+
*/
|
|
2771
|
+
_getSchematicPortArrangement() {
|
|
2772
|
+
return this._parsedProps.schPortArrangement;
|
|
2773
|
+
}
|
|
2774
|
+
_getSchematicBoxDimensions() {
|
|
2775
|
+
if (this.getSchematicSymbol()) return null;
|
|
2776
|
+
if (!this.config.shouldRenderAsSchematicBox) return null;
|
|
2777
|
+
const { _parsedProps: props } = this;
|
|
2778
|
+
const pinCount = this._getPinCount();
|
|
2779
|
+
const pinSpacing = props.schPinSpacing ?? 0.2;
|
|
2780
|
+
const dimensions = getAllDimensionsForSchematicBox({
|
|
2781
|
+
schWidth: props.schWidth,
|
|
2782
|
+
schHeight: props.schHeight,
|
|
2783
|
+
schPinSpacing: pinSpacing,
|
|
2784
|
+
schPinStyle: props.schPinStyle,
|
|
2785
|
+
pinCount,
|
|
2786
|
+
schPortArrangement: this._getSchematicPortArrangement()
|
|
2787
|
+
});
|
|
2788
|
+
return dimensions;
|
|
2789
|
+
}
|
|
2790
|
+
doInitialCadModelRender() {
|
|
2791
|
+
const { db } = this.root;
|
|
2425
2792
|
const { boardThickness = 0 } = this.root?._getBoard() ?? {};
|
|
2426
2793
|
const cadModel = this._parsedProps.cadModel;
|
|
2427
2794
|
if (!this.pcb_component_id) return;
|
|
@@ -3425,421 +3792,126 @@ searched component ${targetComponent.getString()}, which has ports: ${targetComp
|
|
|
3425
3792
|
...position,
|
|
3426
3793
|
layer: "top"
|
|
3427
3794
|
}));
|
|
3428
|
-
const bounds = computeObstacleBounds(obstacles);
|
|
3429
|
-
const simpleRouteJsonInput = {
|
|
3430
|
-
minTraceWidth: 0.1,
|
|
3431
|
-
obstacles,
|
|
3432
|
-
connections: [connection],
|
|
3433
|
-
bounds,
|
|
3434
|
-
layerCount: 1
|
|
3435
|
-
};
|
|
3436
|
-
let Autorouter = MultilayerIjump;
|
|
3437
|
-
if (this.getSubcircuit().props._schDirectLineRoutingEnabled) {
|
|
3438
|
-
Autorouter = DirectLineRouter;
|
|
3439
|
-
}
|
|
3440
|
-
const autorouter = new Autorouter({
|
|
3441
|
-
input: simpleRouteJsonInput,
|
|
3442
|
-
OBSTACLE_MARGIN: 0.1,
|
|
3443
|
-
isRemovePathLoopsEnabled: true
|
|
3444
|
-
});
|
|
3445
|
-
const results = autorouter.solveAndMapToTraces();
|
|
3446
|
-
if (results.length === 0) return;
|
|
3447
|
-
const [result] = results;
|
|
3448
|
-
const { route } = result;
|
|
3449
|
-
const edges = [];
|
|
3450
|
-
for (let i = 0; i < route.length - 1; i++) {
|
|
3451
|
-
edges.push({
|
|
3452
|
-
from: route[i],
|
|
3453
|
-
to: route[i + 1]
|
|
3454
|
-
});
|
|
3455
|
-
}
|
|
3456
|
-
const STUB_LENGTH = 0.15;
|
|
3457
|
-
edges.unshift({
|
|
3458
|
-
from: {
|
|
3459
|
-
...projectPointInDirection(
|
|
3460
|
-
route[0],
|
|
3461
|
-
portsWithPosition[0].facingDirection,
|
|
3462
|
-
STUB_LENGTH
|
|
3463
|
-
)
|
|
3464
|
-
},
|
|
3465
|
-
to: route[0],
|
|
3466
|
-
from_schematic_port_id: portsWithPosition[0].schematic_port_id
|
|
3467
|
-
});
|
|
3468
|
-
edges.push({
|
|
3469
|
-
from: route[route.length - 1],
|
|
3470
|
-
to: {
|
|
3471
|
-
...projectPointInOppositeDirection(
|
|
3472
|
-
route[route.length - 1],
|
|
3473
|
-
portsWithPosition[1].facingDirection,
|
|
3474
|
-
STUB_LENGTH
|
|
3475
|
-
)
|
|
3476
|
-
},
|
|
3477
|
-
from_schematic_port_id: portsWithPosition[1].schematic_port_id
|
|
3478
|
-
});
|
|
3479
|
-
const trace = db.schematic_trace.insert({
|
|
3480
|
-
source_trace_id: this.source_trace_id,
|
|
3481
|
-
edges
|
|
3482
|
-
});
|
|
3483
|
-
this.schematic_trace_id = trace.schematic_trace_id;
|
|
3484
|
-
}
|
|
3485
|
-
};
|
|
3486
|
-
|
|
3487
|
-
// lib/components/normal-components/Capacitor.ts
|
|
3488
|
-
var Capacitor = class extends NormalComponent {
|
|
3489
|
-
// @ts-ignore (cause the symbolName is string and not fixed)
|
|
3490
|
-
get config() {
|
|
3491
|
-
return {
|
|
3492
|
-
componentName: "Capacitor",
|
|
3493
|
-
schematicSymbolName: this.props.symbolName ?? "capacitor_horz",
|
|
3494
|
-
zodProps: capacitorProps,
|
|
3495
|
-
sourceFtype: FTYPE.simple_capacitor
|
|
3496
|
-
};
|
|
3497
|
-
}
|
|
3498
|
-
initPorts() {
|
|
3499
|
-
this.add(new Port({ name: "pin1", pinNumber: 1, aliases: ["anode", "pos", "left"] }));
|
|
3500
|
-
this.add(new Port({ name: "pin2", pinNumber: 2, aliases: ["cathode", "neg", "right"] }));
|
|
3501
|
-
}
|
|
3502
|
-
doInitialCreateNetsFromProps() {
|
|
3503
|
-
this._createNetsFromProps([
|
|
3504
|
-
this.props.decouplingFor,
|
|
3505
|
-
this.props.decouplingTo
|
|
3506
|
-
]);
|
|
3507
|
-
}
|
|
3508
|
-
doInitialCreateTracesFromProps() {
|
|
3509
|
-
if (this.props.decouplingFor && this.props.decouplingTo) {
|
|
3510
|
-
this.add(
|
|
3511
|
-
new Trace({
|
|
3512
|
-
from: `${this.getSubcircuitSelector()} > port.1`,
|
|
3513
|
-
to: this.props.decouplingFor
|
|
3514
|
-
})
|
|
3515
|
-
);
|
|
3516
|
-
this.add(
|
|
3517
|
-
new Trace({
|
|
3518
|
-
from: `${this.getSubcircuitSelector()} > port.2`,
|
|
3519
|
-
to: this.props.decouplingTo
|
|
3520
|
-
})
|
|
3521
|
-
);
|
|
3522
|
-
}
|
|
3523
|
-
}
|
|
3524
|
-
doInitialSourceRender() {
|
|
3525
|
-
const { db } = this.root;
|
|
3526
|
-
const { _parsedProps: props } = this;
|
|
3527
|
-
const source_component = db.source_component.insert({
|
|
3528
|
-
ftype: "simple_capacitor",
|
|
3529
|
-
name: props.name,
|
|
3530
|
-
// @ts-ignore
|
|
3531
|
-
manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
|
|
3532
|
-
supplier_part_numbers: props.supplierPartNumbers,
|
|
3533
|
-
capacitance: props.capacitance
|
|
3534
|
-
});
|
|
3535
|
-
this.source_component_id = source_component.source_component_id;
|
|
3536
|
-
}
|
|
3537
|
-
};
|
|
3538
|
-
|
|
3539
|
-
// lib/components/normal-components/Chip.ts
|
|
3540
|
-
import { chipProps } from "@tscircuit/props";
|
|
3541
|
-
|
|
3542
|
-
// lib/soup/underscorifyPinStyles.ts
|
|
3543
|
-
import "circuit-json";
|
|
3544
|
-
import "zod";
|
|
3545
|
-
var underscorifyPinStyles = (pinStyles) => {
|
|
3546
|
-
if (!pinStyles) return void 0;
|
|
3547
|
-
const underscorePinStyles = {};
|
|
3548
|
-
for (const [pinName, pinStyle] of Object.entries(pinStyles)) {
|
|
3549
|
-
underscorePinStyles[pinName] = {
|
|
3550
|
-
bottom_margin: pinStyle.bottomMargin,
|
|
3551
|
-
left_margin: pinStyle.leftMargin,
|
|
3552
|
-
right_margin: pinStyle.rightMargin,
|
|
3553
|
-
top_margin: pinStyle.topMargin
|
|
3554
|
-
};
|
|
3555
|
-
}
|
|
3556
|
-
return underscorePinStyles;
|
|
3557
|
-
};
|
|
3558
|
-
|
|
3559
|
-
// lib/soup/underscorifyPortArrangement.ts
|
|
3560
|
-
var underscorifyPortArrangement = (portArrangement) => {
|
|
3561
|
-
if (!portArrangement) return void 0;
|
|
3562
|
-
if ("leftSide" in portArrangement || "rightSide" in portArrangement || "topSide" in portArrangement || "bottomSide" in portArrangement) {
|
|
3563
|
-
return {
|
|
3564
|
-
left_side: portArrangement.leftSide,
|
|
3565
|
-
right_side: portArrangement.rightSide,
|
|
3566
|
-
top_side: portArrangement.topSide,
|
|
3567
|
-
bottom_side: portArrangement.bottomSide
|
|
3568
|
-
};
|
|
3569
|
-
}
|
|
3570
|
-
if ("leftPinCount" in portArrangement || "rightPinCount" in portArrangement || "topPinCount" in portArrangement || "bottomPinCount" in portArrangement) {
|
|
3571
|
-
return {
|
|
3572
|
-
left_size: portArrangement.leftPinCount,
|
|
3573
|
-
right_size: portArrangement.rightPinCount,
|
|
3574
|
-
top_size: portArrangement.topPinCount,
|
|
3575
|
-
bottom_size: portArrangement.bottomPinCount
|
|
3576
|
-
};
|
|
3577
|
-
}
|
|
3578
|
-
if ("leftSize" in portArrangement || "rightSize" in portArrangement || "topSize" in portArrangement || "bottomSize" in portArrangement) {
|
|
3579
|
-
return {
|
|
3580
|
-
left_size: portArrangement.leftSize,
|
|
3581
|
-
right_size: portArrangement.rightSize,
|
|
3582
|
-
top_size: portArrangement.topSize,
|
|
3583
|
-
bottom_size: portArrangement.bottomSize
|
|
3584
|
-
};
|
|
3585
|
-
}
|
|
3586
|
-
return void 0;
|
|
3587
|
-
};
|
|
3588
|
-
|
|
3589
|
-
// lib/utils/schematic/getSizeOfSidesFromPortArrangement.ts
|
|
3590
|
-
var hasExplicitPinMapping = (pa) => {
|
|
3591
|
-
for (const side of [
|
|
3592
|
-
"leftSide",
|
|
3593
|
-
"rightSide",
|
|
3594
|
-
"topSide",
|
|
3595
|
-
"bottomSide"
|
|
3596
|
-
]) {
|
|
3597
|
-
if (side in pa && typeof pa[side] === "number") {
|
|
3598
|
-
throw new Error(
|
|
3599
|
-
`A number was specified for "${side}", you probably meant to use "size" not "side"`
|
|
3600
|
-
);
|
|
3601
|
-
}
|
|
3602
|
-
}
|
|
3603
|
-
return "leftSide" in pa || "rightSide" in pa || "topSide" in pa || "bottomSide" in pa;
|
|
3604
|
-
};
|
|
3605
|
-
var getSizeOfSidesFromPortArrangement = (pa) => {
|
|
3606
|
-
if (hasExplicitPinMapping(pa)) {
|
|
3607
|
-
return {
|
|
3608
|
-
leftSize: pa.leftSide?.pins.length ?? 0,
|
|
3609
|
-
rightSize: pa.rightSide?.pins.length ?? 0,
|
|
3610
|
-
topSize: pa.topSide?.pins.length ?? 0,
|
|
3611
|
-
bottomSize: pa.bottomSide?.pins.length ?? 0
|
|
3612
|
-
};
|
|
3613
|
-
}
|
|
3614
|
-
const { leftSize = 0, rightSize = 0, topSize = 0, bottomSize = 0 } = pa;
|
|
3615
|
-
return { leftSize, rightSize, topSize, bottomSize };
|
|
3616
|
-
};
|
|
3617
|
-
|
|
3618
|
-
// lib/utils/schematic/getAllDimensionsForSchematicBox.ts
|
|
3619
|
-
function isExplicitPinMappingArrangement(arrangement) {
|
|
3620
|
-
return arrangement.leftSide !== void 0;
|
|
3621
|
-
}
|
|
3622
|
-
var getAllDimensionsForSchematicBox = (params) => {
|
|
3623
|
-
const componentMargin = params.schPinSpacing;
|
|
3624
|
-
let sidePinCounts = params.schPortArrangement ? getSizeOfSidesFromPortArrangement(params.schPortArrangement) : null;
|
|
3625
|
-
const sideLengths = {
|
|
3626
|
-
left: 0,
|
|
3627
|
-
right: 0,
|
|
3628
|
-
top: 0,
|
|
3629
|
-
bottom: 0
|
|
3630
|
-
};
|
|
3631
|
-
let pinCount = params.pinCount ?? null;
|
|
3632
|
-
if (pinCount === null) {
|
|
3633
|
-
if (sidePinCounts) {
|
|
3634
|
-
pinCount = sidePinCounts.leftSize + sidePinCounts.rightSize + sidePinCounts.topSize + sidePinCounts.bottomSize;
|
|
3635
|
-
} else {
|
|
3636
|
-
throw new Error("Could not determine pin count for the schematic box");
|
|
3637
|
-
}
|
|
3638
|
-
}
|
|
3639
|
-
if (pinCount && !sidePinCounts) {
|
|
3640
|
-
const rightSize = Math.floor(pinCount / 2);
|
|
3641
|
-
sidePinCounts = {
|
|
3642
|
-
leftSize: pinCount - rightSize,
|
|
3643
|
-
rightSize,
|
|
3644
|
-
topSize: 0,
|
|
3645
|
-
bottomSize: 0
|
|
3646
|
-
};
|
|
3647
|
-
}
|
|
3648
|
-
if (!sidePinCounts) {
|
|
3649
|
-
sidePinCounts = {
|
|
3650
|
-
leftSize: 0,
|
|
3651
|
-
rightSize: 0,
|
|
3652
|
-
topSize: 0,
|
|
3653
|
-
bottomSize: 0
|
|
3654
|
-
};
|
|
3655
|
-
}
|
|
3656
|
-
const schWidth = params.schWidth ?? Math.max(sidePinCounts.topSize, sidePinCounts.bottomSize) * params.schPinSpacing + 2 * componentMargin;
|
|
3657
|
-
const schHeight = params.schHeight ?? Math.max(sidePinCounts.leftSize, sidePinCounts.rightSize) * params.schPinSpacing + 2 * componentMargin;
|
|
3658
|
-
const distributePorts = (sideSize, sideLength, totalMargin) => {
|
|
3659
|
-
if (sideSize <= 1) return 0;
|
|
3660
|
-
return (sideLength - totalMargin) / (sideSize - 1);
|
|
3661
|
-
};
|
|
3662
|
-
const orderedTruePorts = [];
|
|
3663
|
-
let truePinIndex = 0;
|
|
3664
|
-
const processSide = (side, pins, direction) => {
|
|
3665
|
-
const isVertical = side === "left" || side === "right";
|
|
3666
|
-
const sideLength = isVertical ? schHeight : schWidth;
|
|
3667
|
-
let totalMargin = 0;
|
|
3668
|
-
for (const pin of pins) {
|
|
3669
|
-
const pinStyle = params.schPinStyle?.[`pin${pin}`] ?? params.schPinStyle?.[pin];
|
|
3670
|
-
if (pinStyle) {
|
|
3671
|
-
if (isVertical) {
|
|
3672
|
-
totalMargin += (pinStyle.topMargin ?? 0) + (pinStyle.bottomMargin ?? 0);
|
|
3673
|
-
} else {
|
|
3674
|
-
totalMargin += (pinStyle.leftMargin ?? 0) + (pinStyle.rightMargin ?? 0);
|
|
3675
|
-
}
|
|
3676
|
-
}
|
|
3677
|
-
}
|
|
3678
|
-
const spacing = distributePorts(
|
|
3679
|
-
pins.length,
|
|
3680
|
-
sideLength - 2 * componentMargin,
|
|
3681
|
-
totalMargin
|
|
3682
|
-
);
|
|
3683
|
-
let currentDistanceFromEdge = componentMargin;
|
|
3684
|
-
pins.forEach((pinNumber, index) => {
|
|
3685
|
-
const pinStyle = params.schPinStyle?.[`pin${pinNumber}`] ?? params.schPinStyle?.[pinNumber];
|
|
3686
|
-
if (pinStyle) {
|
|
3687
|
-
if (isVertical) {
|
|
3688
|
-
if (side === "left") {
|
|
3689
|
-
currentDistanceFromEdge += direction === "top-to-bottom" ? pinStyle.topMargin ?? 0 : pinStyle.bottomMargin ?? 0;
|
|
3690
|
-
} else {
|
|
3691
|
-
currentDistanceFromEdge += direction === "top-to-bottom" ? pinStyle.bottomMargin ?? 0 : pinStyle.topMargin ?? 0;
|
|
3692
|
-
}
|
|
3693
|
-
} else {
|
|
3694
|
-
if (side === "top") {
|
|
3695
|
-
currentDistanceFromEdge += direction === "left-to-right" ? pinStyle.leftMargin ?? 0 : pinStyle.rightMargin ?? 0;
|
|
3696
|
-
} else {
|
|
3697
|
-
currentDistanceFromEdge += direction === "left-to-right" ? pinStyle.rightMargin ?? 0 : pinStyle.leftMargin ?? 0;
|
|
3698
|
-
}
|
|
3699
|
-
}
|
|
3700
|
-
}
|
|
3701
|
-
orderedTruePorts.push({
|
|
3702
|
-
trueIndex: truePinIndex,
|
|
3703
|
-
pinNumber,
|
|
3704
|
-
side,
|
|
3705
|
-
distanceFromEdge: currentDistanceFromEdge,
|
|
3706
|
-
x: 0,
|
|
3707
|
-
y: 0
|
|
3708
|
-
});
|
|
3709
|
-
if (pinStyle) {
|
|
3710
|
-
if (isVertical) {
|
|
3711
|
-
if (side === "left") {
|
|
3712
|
-
currentDistanceFromEdge += direction === "top-to-bottom" ? pinStyle.bottomMargin ?? 0 : pinStyle.topMargin ?? 0;
|
|
3713
|
-
} else {
|
|
3714
|
-
currentDistanceFromEdge += direction === "top-to-bottom" ? pinStyle.topMargin ?? 0 : pinStyle.bottomMargin ?? 0;
|
|
3715
|
-
}
|
|
3716
|
-
} else {
|
|
3717
|
-
if (side === "top") {
|
|
3718
|
-
currentDistanceFromEdge += direction === "left-to-right" ? pinStyle.rightMargin ?? 0 : pinStyle.leftMargin ?? 0;
|
|
3719
|
-
} else {
|
|
3720
|
-
currentDistanceFromEdge += direction === "left-to-right" ? pinStyle.leftMargin ?? 0 : pinStyle.rightMargin ?? 0;
|
|
3721
|
-
}
|
|
3722
|
-
}
|
|
3723
|
-
}
|
|
3724
|
-
currentDistanceFromEdge += spacing;
|
|
3725
|
-
truePinIndex++;
|
|
3726
|
-
});
|
|
3727
|
-
sideLengths[side] = sideLength;
|
|
3728
|
-
};
|
|
3729
|
-
if (params.schPortArrangement && isExplicitPinMappingArrangement(params.schPortArrangement)) {
|
|
3730
|
-
if (params.schPortArrangement.leftSide) {
|
|
3731
|
-
processSide(
|
|
3732
|
-
"left",
|
|
3733
|
-
params.schPortArrangement.leftSide.pins,
|
|
3734
|
-
params.schPortArrangement.leftSide.direction ?? "top-to-bottom"
|
|
3735
|
-
);
|
|
3736
|
-
}
|
|
3737
|
-
if (params.schPortArrangement.rightSide) {
|
|
3738
|
-
processSide(
|
|
3739
|
-
"right",
|
|
3740
|
-
params.schPortArrangement.rightSide.pins,
|
|
3741
|
-
params.schPortArrangement.rightSide.direction ?? "bottom-to-top"
|
|
3742
|
-
);
|
|
3743
|
-
}
|
|
3744
|
-
if (params.schPortArrangement.topSide) {
|
|
3745
|
-
processSide(
|
|
3746
|
-
"top",
|
|
3747
|
-
params.schPortArrangement.topSide.pins,
|
|
3748
|
-
params.schPortArrangement.topSide.direction ?? "left-to-right"
|
|
3749
|
-
);
|
|
3795
|
+
const bounds = computeObstacleBounds(obstacles);
|
|
3796
|
+
const simpleRouteJsonInput = {
|
|
3797
|
+
minTraceWidth: 0.1,
|
|
3798
|
+
obstacles,
|
|
3799
|
+
connections: [connection],
|
|
3800
|
+
bounds,
|
|
3801
|
+
layerCount: 1
|
|
3802
|
+
};
|
|
3803
|
+
let Autorouter = MultilayerIjump;
|
|
3804
|
+
if (this.getSubcircuit().props._schDirectLineRoutingEnabled) {
|
|
3805
|
+
Autorouter = DirectLineRouter;
|
|
3750
3806
|
}
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3756
|
-
|
|
3807
|
+
const autorouter = new Autorouter({
|
|
3808
|
+
input: simpleRouteJsonInput,
|
|
3809
|
+
OBSTACLE_MARGIN: 0.1,
|
|
3810
|
+
isRemovePathLoopsEnabled: true
|
|
3811
|
+
});
|
|
3812
|
+
const results = autorouter.solveAndMapToTraces();
|
|
3813
|
+
if (results.length === 0) return;
|
|
3814
|
+
const [result] = results;
|
|
3815
|
+
const { route } = result;
|
|
3816
|
+
const edges = [];
|
|
3817
|
+
for (let i = 0; i < route.length - 1; i++) {
|
|
3818
|
+
edges.push({
|
|
3819
|
+
from: route[i],
|
|
3820
|
+
to: route[i + 1]
|
|
3821
|
+
});
|
|
3757
3822
|
}
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
3763
|
-
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
);
|
|
3767
|
-
const topSide = Array.from(
|
|
3768
|
-
{ length: sidePinCounts.topSize },
|
|
3769
|
-
(_, i) => i + sidePinCounts.leftSize + sidePinCounts.rightSize + 1
|
|
3770
|
-
);
|
|
3771
|
-
const bottomSide = Array.from(
|
|
3772
|
-
{
|
|
3773
|
-
length: pinCount - sidePinCounts.leftSize - sidePinCounts.rightSize - sidePinCounts.topSize
|
|
3823
|
+
const STUB_LENGTH = 0.15;
|
|
3824
|
+
edges.unshift({
|
|
3825
|
+
from: {
|
|
3826
|
+
...projectPointInDirection(
|
|
3827
|
+
route[0],
|
|
3828
|
+
portsWithPosition[0].facingDirection,
|
|
3829
|
+
STUB_LENGTH
|
|
3830
|
+
)
|
|
3774
3831
|
},
|
|
3775
|
-
|
|
3776
|
-
|
|
3777
|
-
|
|
3778
|
-
|
|
3779
|
-
|
|
3780
|
-
|
|
3832
|
+
to: route[0],
|
|
3833
|
+
from_schematic_port_id: portsWithPosition[0].schematic_port_id
|
|
3834
|
+
});
|
|
3835
|
+
edges.push({
|
|
3836
|
+
from: route[route.length - 1],
|
|
3837
|
+
to: {
|
|
3838
|
+
...projectPointInOppositeDirection(
|
|
3839
|
+
route[route.length - 1],
|
|
3840
|
+
portsWithPosition[1].facingDirection,
|
|
3841
|
+
STUB_LENGTH
|
|
3842
|
+
)
|
|
3843
|
+
},
|
|
3844
|
+
from_schematic_port_id: portsWithPosition[1].schematic_port_id
|
|
3845
|
+
});
|
|
3846
|
+
const trace = db.schematic_trace.insert({
|
|
3847
|
+
source_trace_id: this.source_trace_id,
|
|
3848
|
+
edges
|
|
3849
|
+
});
|
|
3850
|
+
this.schematic_trace_id = trace.schematic_trace_id;
|
|
3781
3851
|
}
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
3787
|
-
|
|
3788
|
-
const trueEdgeTraversalDirections = {
|
|
3789
|
-
left: { x: 0, y: -1 },
|
|
3790
|
-
right: { x: 0, y: 1 },
|
|
3791
|
-
top: { x: -1, y: 0 },
|
|
3792
|
-
bottom: { x: 1, y: 0 }
|
|
3793
|
-
};
|
|
3794
|
-
const truePortsWithPositions = orderedTruePorts.map((p) => {
|
|
3795
|
-
const { distanceFromEdge, side } = p;
|
|
3796
|
-
if (side === "center") {
|
|
3797
|
-
return {
|
|
3798
|
-
...p,
|
|
3799
|
-
x: 0,
|
|
3800
|
-
y: 0
|
|
3801
|
-
};
|
|
3802
|
-
}
|
|
3803
|
-
const edgePos = trueEdgePositions[side];
|
|
3804
|
-
const edgeDir = trueEdgeTraversalDirections[side];
|
|
3852
|
+
};
|
|
3853
|
+
|
|
3854
|
+
// lib/components/normal-components/Capacitor.ts
|
|
3855
|
+
var Capacitor = class extends NormalComponent {
|
|
3856
|
+
// @ts-ignore (cause the symbolName is string and not fixed)
|
|
3857
|
+
get config() {
|
|
3805
3858
|
return {
|
|
3806
|
-
|
|
3807
|
-
|
|
3808
|
-
|
|
3859
|
+
componentName: "Capacitor",
|
|
3860
|
+
schematicSymbolName: this.props.symbolName ?? "capacitor_horz",
|
|
3861
|
+
zodProps: capacitorProps,
|
|
3862
|
+
sourceFtype: FTYPE.simple_capacitor
|
|
3809
3863
|
};
|
|
3810
|
-
}
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3864
|
+
}
|
|
3865
|
+
initPorts() {
|
|
3866
|
+
this.add(new Port({ name: "pin1", pinNumber: 1, aliases: ["anode", "pos", "left"] }));
|
|
3867
|
+
this.add(new Port({ name: "pin2", pinNumber: 2, aliases: ["cathode", "neg", "right"] }));
|
|
3868
|
+
}
|
|
3869
|
+
doInitialCreateNetsFromProps() {
|
|
3870
|
+
this._createNetsFromProps([
|
|
3871
|
+
this.props.decouplingFor,
|
|
3872
|
+
this.props.decouplingTo
|
|
3873
|
+
]);
|
|
3874
|
+
}
|
|
3875
|
+
doInitialCreateTracesFromProps() {
|
|
3876
|
+
if (this.props.decouplingFor && this.props.decouplingTo) {
|
|
3877
|
+
this.add(
|
|
3878
|
+
new Trace({
|
|
3879
|
+
from: `${this.getSubcircuitSelector()} > port.1`,
|
|
3880
|
+
to: this.props.decouplingFor
|
|
3881
|
+
})
|
|
3815
3882
|
);
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3883
|
+
this.add(
|
|
3884
|
+
new Trace({
|
|
3885
|
+
from: `${this.getSubcircuitSelector()} > port.2`,
|
|
3886
|
+
to: this.props.decouplingTo
|
|
3887
|
+
})
|
|
3888
|
+
);
|
|
3889
|
+
}
|
|
3890
|
+
}
|
|
3891
|
+
doInitialSourceRender() {
|
|
3892
|
+
const { db } = this.root;
|
|
3893
|
+
const { _parsedProps: props } = this;
|
|
3894
|
+
const source_component = db.source_component.insert({
|
|
3895
|
+
ftype: "simple_capacitor",
|
|
3896
|
+
name: props.name,
|
|
3897
|
+
// @ts-ignore
|
|
3898
|
+
manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
|
|
3899
|
+
supplier_part_numbers: props.supplierPartNumbers,
|
|
3900
|
+
capacitance: props.capacitance
|
|
3901
|
+
});
|
|
3902
|
+
this.source_component_id = source_component.source_component_id;
|
|
3903
|
+
}
|
|
3834
3904
|
};
|
|
3835
3905
|
|
|
3836
3906
|
// lib/components/normal-components/Chip.ts
|
|
3907
|
+
import { chipProps } from "@tscircuit/props";
|
|
3837
3908
|
var Chip = class extends NormalComponent {
|
|
3838
|
-
|
|
3909
|
+
schematicBoxDimensions = null;
|
|
3839
3910
|
get config() {
|
|
3840
3911
|
return {
|
|
3841
3912
|
componentName: "Chip",
|
|
3842
|
-
zodProps: chipProps
|
|
3913
|
+
zodProps: chipProps,
|
|
3914
|
+
shouldRenderAsSchematicBox: true
|
|
3843
3915
|
};
|
|
3844
3916
|
}
|
|
3845
3917
|
doInitialSourceRender() {
|
|
@@ -3853,43 +3925,6 @@ var Chip = class extends NormalComponent {
|
|
|
3853
3925
|
});
|
|
3854
3926
|
this.source_component_id = source_component.source_component_id;
|
|
3855
3927
|
}
|
|
3856
|
-
doInitialSchematicComponentRender() {
|
|
3857
|
-
const { db } = this.root;
|
|
3858
|
-
const { _parsedProps: props } = this;
|
|
3859
|
-
const pinCountFromSchArrangement = (props.schPortArrangement?.leftSize ?? 0) + (props.schPortArrangement?.rightSize ?? 0) + (props.schPortArrangement?.topSize ?? 0) + (props.schPortArrangement?.bottomSize ?? 0);
|
|
3860
|
-
const pinCount = pinCountFromSchArrangement || this.getPortsFromFootprint().length;
|
|
3861
|
-
const pinSpacing = props.schPinSpacing ?? 0.2;
|
|
3862
|
-
const dimensions = getAllDimensionsForSchematicBox({
|
|
3863
|
-
schWidth: props.schWidth,
|
|
3864
|
-
schHeight: props.schHeight,
|
|
3865
|
-
schPinSpacing: pinSpacing,
|
|
3866
|
-
schPinStyle: props.schPinStyle,
|
|
3867
|
-
pinCount,
|
|
3868
|
-
// @ts-ignore there's a subtley in the definition difference with
|
|
3869
|
-
// leftSide/rightSide/topSide/bottomSide in how the direction is defined
|
|
3870
|
-
// that doesn't really matter
|
|
3871
|
-
schPortArrangement: props.schPortArrangement
|
|
3872
|
-
});
|
|
3873
|
-
this.schematicDimensions = dimensions;
|
|
3874
|
-
const primaryPortLabels = {};
|
|
3875
|
-
for (const [port, label] of Object.entries(props.pinLabels ?? {})) {
|
|
3876
|
-
primaryPortLabels[port] = Array.isArray(label) ? label[0] : label;
|
|
3877
|
-
}
|
|
3878
|
-
const schematic_component2 = db.schematic_component.insert({
|
|
3879
|
-
center: { x: props.schX ?? 0, y: props.schY ?? 0 },
|
|
3880
|
-
rotation: props.schRotation ?? 0,
|
|
3881
|
-
size: dimensions.getSize(),
|
|
3882
|
-
port_arrangement: underscorifyPortArrangement(
|
|
3883
|
-
props.schPortArrangement
|
|
3884
|
-
),
|
|
3885
|
-
pin_spacing: pinSpacing,
|
|
3886
|
-
// @ts-ignore soup needs to support distance for pin_styles
|
|
3887
|
-
pin_styles: underscorifyPinStyles(props.schPinStyle),
|
|
3888
|
-
port_labels: primaryPortLabels,
|
|
3889
|
-
source_component_id: this.source_component_id
|
|
3890
|
-
});
|
|
3891
|
-
this.schematic_component_id = schematic_component2.schematic_component_id;
|
|
3892
|
-
}
|
|
3893
3928
|
doInitialPcbComponentRender() {
|
|
3894
3929
|
const { db } = this.root;
|
|
3895
3930
|
const { _parsedProps: props } = this;
|
|
@@ -3940,7 +3975,8 @@ var Jumper = class extends NormalComponent {
|
|
|
3940
3975
|
get config() {
|
|
3941
3976
|
return {
|
|
3942
3977
|
componentName: "Jumper",
|
|
3943
|
-
zodProps: jumperProps
|
|
3978
|
+
zodProps: jumperProps,
|
|
3979
|
+
shouldRenderAsSchematicBox: true
|
|
3944
3980
|
};
|
|
3945
3981
|
}
|
|
3946
3982
|
doInitialSourceRender() {
|
|
@@ -3955,41 +3991,6 @@ var Jumper = class extends NormalComponent {
|
|
|
3955
3991
|
});
|
|
3956
3992
|
this.source_component_id = source_component.source_component_id;
|
|
3957
3993
|
}
|
|
3958
|
-
doInitialSchematicComponentRender() {
|
|
3959
|
-
const { db } = this.root;
|
|
3960
|
-
const { _parsedProps: props } = this;
|
|
3961
|
-
const ports = this.children.filter((child) => child instanceof Port);
|
|
3962
|
-
const pinSpacing = props.schPinSpacing ?? 0.2;
|
|
3963
|
-
const dimensions = getAllDimensionsForSchematicBox({
|
|
3964
|
-
schWidth: props.schWidth,
|
|
3965
|
-
schHeight: props.schHeight,
|
|
3966
|
-
schPinSpacing: pinSpacing,
|
|
3967
|
-
schPinStyle: props.schPinStyle,
|
|
3968
|
-
pinCount: ports.length,
|
|
3969
|
-
// @ts-ignore there's a subtley in the definition difference with
|
|
3970
|
-
// leftSide/rightSide/topSide/bottomSide in how the direction is defined
|
|
3971
|
-
// that doesn't really matter
|
|
3972
|
-
schPortArrangement: {
|
|
3973
|
-
// TODO use schematic direction or schPortArrangement
|
|
3974
|
-
rightSize: ports.length
|
|
3975
|
-
}
|
|
3976
|
-
});
|
|
3977
|
-
this.schematicDimensions = dimensions;
|
|
3978
|
-
const schematic_component2 = db.schematic_component.insert({
|
|
3979
|
-
center: { x: props.schX ?? 0, y: props.schY ?? 0 },
|
|
3980
|
-
rotation: props.schRotation ?? 0,
|
|
3981
|
-
size: dimensions.getSize(),
|
|
3982
|
-
port_arrangement: underscorifyPortArrangement(
|
|
3983
|
-
props.schPortArrangement
|
|
3984
|
-
),
|
|
3985
|
-
pin_spacing: pinSpacing,
|
|
3986
|
-
// @ts-ignore soup needs to support distance for pin_styles
|
|
3987
|
-
pin_styles: underscorifyPinStyles(props.schPinStyle),
|
|
3988
|
-
port_labels: props.pinLabels,
|
|
3989
|
-
source_component_id: this.source_component_id
|
|
3990
|
-
});
|
|
3991
|
-
this.schematic_component_id = schematic_component2.schematic_component_id;
|
|
3992
|
-
}
|
|
3993
3994
|
doInitialPcbComponentRender() {
|
|
3994
3995
|
const { db } = this.root;
|
|
3995
3996
|
const { _parsedProps: props } = this;
|
|
@@ -4488,6 +4489,62 @@ var Battery = class extends NormalComponent {
|
|
|
4488
4489
|
}
|
|
4489
4490
|
};
|
|
4490
4491
|
|
|
4492
|
+
// lib/components/normal-components/PinHeader.ts
|
|
4493
|
+
import { pinHeaderProps } from "@tscircuit/props";
|
|
4494
|
+
var PinHeader = class extends NormalComponent {
|
|
4495
|
+
get config() {
|
|
4496
|
+
return {
|
|
4497
|
+
componentName: "PinHeader",
|
|
4498
|
+
zodProps: pinHeaderProps,
|
|
4499
|
+
shouldRenderAsSchematicBox: true
|
|
4500
|
+
};
|
|
4501
|
+
}
|
|
4502
|
+
_getImpliedFootprintString() {
|
|
4503
|
+
const pinCount = this._parsedProps.pinCount ?? this._parsedProps.pinLabels?.length ?? 0;
|
|
4504
|
+
const holeDiameter = this._parsedProps.holeDiameter;
|
|
4505
|
+
const platedDiameter = this._parsedProps.platedDiameter;
|
|
4506
|
+
const pitch = this._parsedProps.pitch;
|
|
4507
|
+
if (pinCount > 0 && pitch) {
|
|
4508
|
+
if (!holeDiameter && !platedDiameter) {
|
|
4509
|
+
return `pinrow${pinCount}_p${pitch}`;
|
|
4510
|
+
}
|
|
4511
|
+
return `pinrow${pinCount}_p${pitch}_id${holeDiameter}_od${platedDiameter}`;
|
|
4512
|
+
}
|
|
4513
|
+
return null;
|
|
4514
|
+
}
|
|
4515
|
+
initPorts() {
|
|
4516
|
+
const pinCount = this._parsedProps.pinCount ?? this._parsedProps.pinLabels?.length ?? 1;
|
|
4517
|
+
for (let i = 1; i <= pinCount; i++) {
|
|
4518
|
+
this.add(
|
|
4519
|
+
new Port({
|
|
4520
|
+
name: `pin${i}`,
|
|
4521
|
+
pinNumber: i,
|
|
4522
|
+
aliases: []
|
|
4523
|
+
})
|
|
4524
|
+
);
|
|
4525
|
+
}
|
|
4526
|
+
}
|
|
4527
|
+
_getSchematicPortArrangement() {
|
|
4528
|
+
return {
|
|
4529
|
+
leftSize: 0,
|
|
4530
|
+
rightSize: this._parsedProps.pinCount ?? 1
|
|
4531
|
+
};
|
|
4532
|
+
}
|
|
4533
|
+
doInitialSourceRender() {
|
|
4534
|
+
const { db } = this.root;
|
|
4535
|
+
const { _parsedProps: props } = this;
|
|
4536
|
+
const source_component = db.source_component.insert({
|
|
4537
|
+
ftype: "simple_chip",
|
|
4538
|
+
name: props.name,
|
|
4539
|
+
// manufacturer_part_number: props.,
|
|
4540
|
+
supplier_part_numbers: props.supplierPartNumbers
|
|
4541
|
+
// gender: props.gender,
|
|
4542
|
+
// pitch: props.pitch,
|
|
4543
|
+
});
|
|
4544
|
+
this.source_component_id = source_component.source_component_id;
|
|
4545
|
+
}
|
|
4546
|
+
};
|
|
4547
|
+
|
|
4491
4548
|
// lib/components/normal-components/Inductor.ts
|
|
4492
4549
|
import { inductorProps } from "@tscircuit/props";
|
|
4493
4550
|
var Inductor = class extends NormalComponent {
|
|
@@ -4783,6 +4840,7 @@ export {
|
|
|
4783
4840
|
Net,
|
|
4784
4841
|
NetAlias,
|
|
4785
4842
|
NormalComponent,
|
|
4843
|
+
PinHeader,
|
|
4786
4844
|
PlatedHole,
|
|
4787
4845
|
Port,
|
|
4788
4846
|
PowerSource,
|