@tscircuit/core 0.0.146 → 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 +60 -39
- package/dist/index.js +749 -763
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -790,6 +790,20 @@ var PrimitiveComponent = class extends Renderable {
|
|
|
790
790
|
}
|
|
791
791
|
return descendants;
|
|
792
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
|
+
}
|
|
793
807
|
// TODO we shouldn't need to override this, errors can be rendered and handled
|
|
794
808
|
// by the Renderable class, however, the Renderable class currently doesn't
|
|
795
809
|
// have access to the database or cleanup
|
|
@@ -1615,23 +1629,28 @@ var Port = class extends PrimitiveComponent {
|
|
|
1615
1629
|
return this._getPcbCircuitJsonBounds().center;
|
|
1616
1630
|
}
|
|
1617
1631
|
_getGlobalSchematicPositionBeforeLayout() {
|
|
1618
|
-
if (!this.schematicSymbolPortDef) {
|
|
1619
|
-
return applyToPoint4(this.parent.computeSchematicGlobalTransform(), {
|
|
1620
|
-
x: 0,
|
|
1621
|
-
y: 0
|
|
1622
|
-
});
|
|
1623
|
-
}
|
|
1624
1632
|
const symbol = this.parent?.getSchematicSymbol();
|
|
1625
|
-
if (
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
)
|
|
1634
|
-
|
|
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 };
|
|
1635
1654
|
}
|
|
1636
1655
|
_getGlobalSchematicPositionAfterLayout() {
|
|
1637
1656
|
const { db } = this.root;
|
|
@@ -1749,17 +1768,16 @@ var Port = class extends PrimitiveComponent {
|
|
|
1749
1768
|
const container = this.getPrimitiveContainer();
|
|
1750
1769
|
if (!container) return;
|
|
1751
1770
|
const containerCenter = container._getGlobalSchematicPositionBeforeLayout();
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
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);
|
|
1758
1776
|
}
|
|
1759
1777
|
if (this.getSubcircuit().props._schDebugObjectsEnabled) {
|
|
1760
1778
|
db.schematic_debug_object.insert({
|
|
1761
1779
|
shape: "rect",
|
|
1762
|
-
center,
|
|
1780
|
+
center: portCenter,
|
|
1763
1781
|
size: {
|
|
1764
1782
|
width: 0.1,
|
|
1765
1783
|
height: 0.1
|
|
@@ -1767,12 +1785,16 @@ var Port = class extends PrimitiveComponent {
|
|
|
1767
1785
|
label: "obstacle"
|
|
1768
1786
|
});
|
|
1769
1787
|
}
|
|
1770
|
-
this.facingDirection = getRelativeDirection(containerCenter,
|
|
1788
|
+
this.facingDirection = getRelativeDirection(containerCenter, portCenter);
|
|
1771
1789
|
const schematic_port = db.schematic_port.insert({
|
|
1772
1790
|
schematic_component_id: this.parent?.schematic_component_id,
|
|
1773
|
-
center,
|
|
1791
|
+
center: portCenter,
|
|
1774
1792
|
source_port_id: this.source_port_id,
|
|
1775
|
-
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
|
|
1776
1798
|
});
|
|
1777
1799
|
this.schematic_port_id = schematic_port.schematic_port_id;
|
|
1778
1800
|
}
|
|
@@ -1805,7 +1827,7 @@ import {
|
|
|
1805
1827
|
isValidElement
|
|
1806
1828
|
} from "react";
|
|
1807
1829
|
import { symbols as symbols2 } from "schematic-symbols";
|
|
1808
|
-
import { z as
|
|
1830
|
+
import { z as z5 } from "zod";
|
|
1809
1831
|
|
|
1810
1832
|
// lib/components/primitive-components/Footprint.ts
|
|
1811
1833
|
import { footprintProps } from "@tscircuit/props";
|
|
@@ -2016,259 +2038,569 @@ var Footprint = class extends PrimitiveComponent {
|
|
|
2016
2038
|
}
|
|
2017
2039
|
};
|
|
2018
2040
|
|
|
2019
|
-
// lib/
|
|
2020
|
-
var
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
this._addChildrenFromStringFootprint();
|
|
2033
|
-
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
|
+
}
|
|
2034
2054
|
}
|
|
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
|
-
}
|
|
2070
|
-
}
|
|
2071
|
-
const sides = ["left", "right", "top", "bottom"];
|
|
2072
|
-
let pinNum = 1;
|
|
2073
|
-
for (const side of sides) {
|
|
2074
|
-
const size = schPortArrangement[`${side}Size`];
|
|
2075
|
-
for (let i = 0; i < size; i++) {
|
|
2076
|
-
portsToCreate.push(
|
|
2077
|
-
new Port(
|
|
2078
|
-
{
|
|
2079
|
-
pinNumber: pinNum++
|
|
2080
|
-
},
|
|
2081
|
-
{
|
|
2082
|
-
originDescription: `schPortArrangement:${side}`
|
|
2083
|
-
}
|
|
2084
|
-
)
|
|
2085
|
-
);
|
|
2086
|
-
}
|
|
2087
|
-
}
|
|
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");
|
|
2088
2089
|
}
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
|
|
2106
|
-
|
|
2107
|
-
|
|
2108
|
-
|
|
2109
|
-
|
|
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);
|
|
2110
2125
|
} else {
|
|
2111
|
-
|
|
2112
|
-
existingPort.props.name = primaryLabel;
|
|
2126
|
+
totalMargin += (pinStyle.leftMargin ?? 0) + (pinStyle.rightMargin ?? 0);
|
|
2113
2127
|
}
|
|
2114
2128
|
}
|
|
2115
2129
|
}
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
|
|
2119
|
-
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
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
|
+
}
|
|
2125
2151
|
}
|
|
2126
2152
|
}
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
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
|
+
}
|
|
2134
2175
|
}
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
this.addAll(portsToCreate);
|
|
2138
|
-
}
|
|
2139
|
-
}
|
|
2140
|
-
_getImpliedFootprintString() {
|
|
2141
|
-
return null;
|
|
2142
|
-
}
|
|
2143
|
-
_addChildrenFromStringFootprint() {
|
|
2144
|
-
let { footprint } = this.props;
|
|
2145
|
-
footprint ??= this._getImpliedFootprintString?.();
|
|
2146
|
-
if (!footprint) return;
|
|
2147
|
-
if (typeof footprint === "string") {
|
|
2148
|
-
const fpSoup = fp.string(footprint).soup();
|
|
2149
|
-
const fpComponents = createComponentsFromSoup(fpSoup);
|
|
2150
|
-
this.addAll(fpComponents);
|
|
2151
|
-
}
|
|
2152
|
-
}
|
|
2153
|
-
get portMap() {
|
|
2154
|
-
return new Proxy(
|
|
2155
|
-
{},
|
|
2156
|
-
{
|
|
2157
|
-
get: (target, prop) => {
|
|
2158
|
-
const port = this.children.find(
|
|
2159
|
-
(c) => c.componentName === "Port" && c.isMatchingNameOrAlias(prop)
|
|
2160
|
-
);
|
|
2161
|
-
if (!port) {
|
|
2162
|
-
throw new Error(
|
|
2163
|
-
`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`
|
|
2164
|
-
);
|
|
2165
|
-
}
|
|
2166
|
-
return port;
|
|
2167
|
-
}
|
|
2168
|
-
}
|
|
2169
|
-
);
|
|
2170
|
-
}
|
|
2171
|
-
getInstanceForReactElement(element) {
|
|
2172
|
-
for (const subtree of this.reactSubtrees) {
|
|
2173
|
-
if (subtree.element === element) return subtree.component;
|
|
2174
|
-
}
|
|
2175
|
-
return null;
|
|
2176
|
-
}
|
|
2177
|
-
doInitialSourceRender() {
|
|
2178
|
-
const ftype = this.config.sourceFtype;
|
|
2179
|
-
if (!ftype) return;
|
|
2180
|
-
const { db } = this.root;
|
|
2181
|
-
const { _parsedProps: props } = this;
|
|
2182
|
-
const source_component = db.source_component.insert({
|
|
2183
|
-
ftype,
|
|
2184
|
-
name: props.name,
|
|
2185
|
-
manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
|
|
2186
|
-
supplier_part_numbers: props.supplierPartNumbers
|
|
2176
|
+
currentDistanceFromEdge += spacing;
|
|
2177
|
+
truePinIndex++;
|
|
2187
2178
|
});
|
|
2188
|
-
|
|
2189
|
-
}
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
doInitialSchematicComponentRender() {
|
|
2197
|
-
const { db } = this.root;
|
|
2198
|
-
const { schematicSymbolName } = this.config;
|
|
2199
|
-
if (!schematicSymbolName) return;
|
|
2200
|
-
const base_symbol_name = this.config.schematicSymbolName;
|
|
2201
|
-
const symbol_name_horz = `${base_symbol_name}_horz`;
|
|
2202
|
-
let symbol_name;
|
|
2203
|
-
if (!base_symbol_name) {
|
|
2204
|
-
throw new Error(
|
|
2205
|
-
"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"
|
|
2206
2187
|
);
|
|
2207
2188
|
}
|
|
2208
|
-
if (
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
|
|
2213
|
-
|
|
2189
|
+
if (params.schPortArrangement.rightSide) {
|
|
2190
|
+
processSide(
|
|
2191
|
+
"right",
|
|
2192
|
+
params.schPortArrangement.rightSide.pins,
|
|
2193
|
+
params.schPortArrangement.rightSide.direction ?? "bottom-to-top"
|
|
2194
|
+
);
|
|
2214
2195
|
}
|
|
2215
|
-
|
|
2216
|
-
|
|
2217
|
-
|
|
2196
|
+
if (params.schPortArrangement.topSide) {
|
|
2197
|
+
processSide(
|
|
2198
|
+
"top",
|
|
2199
|
+
params.schPortArrangement.topSide.pins,
|
|
2200
|
+
params.schPortArrangement.topSide.direction ?? "left-to-right"
|
|
2201
|
+
);
|
|
2218
2202
|
}
|
|
2219
|
-
|
|
2220
|
-
|
|
2221
|
-
|
|
2222
|
-
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
}
|
|
2226
|
-
|
|
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");
|
|
2227
2233
|
}
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
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
|
+
};
|
|
2241
2283
|
}
|
|
2242
|
-
|
|
2243
|
-
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
const { db } = this.root;
|
|
2249
|
-
const { _parsedProps: props } = this;
|
|
2250
|
-
const bounds = getBoundsOfPcbComponents(this.children);
|
|
2251
|
-
if (bounds.width === 0 || bounds.height === 0) return;
|
|
2252
|
-
const center = {
|
|
2253
|
-
x: (bounds.minX + bounds.maxX) / 2,
|
|
2254
|
-
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
|
|
2255
2290
|
};
|
|
2256
|
-
db.pcb_component.update(this.pcb_component_id, {
|
|
2257
|
-
center,
|
|
2258
|
-
width: bounds.width,
|
|
2259
|
-
height: bounds.height
|
|
2260
|
-
});
|
|
2261
2291
|
}
|
|
2262
|
-
|
|
2292
|
+
if ("leftSize" in portArrangement || "rightSize" in portArrangement || "topSize" in portArrangement || "bottomSize" in portArrangement) {
|
|
2263
2293
|
return {
|
|
2264
|
-
|
|
2265
|
-
|
|
2294
|
+
left_size: portArrangement.leftSize,
|
|
2295
|
+
right_size: portArrangement.rightSize,
|
|
2296
|
+
top_size: portArrangement.topSize,
|
|
2297
|
+
bottom_size: portArrangement.bottomSize
|
|
2266
2298
|
};
|
|
2267
2299
|
}
|
|
2268
|
-
|
|
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();
|
|
2269
2334
|
this.initPorts();
|
|
2270
2335
|
}
|
|
2271
|
-
|
|
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() {
|
|
2272
2604
|
if (isReactElement(this.props.footprint)) {
|
|
2273
2605
|
if (this.reactSubtrees.some((rs) => rs.element === this.props.footprint))
|
|
2274
2606
|
return;
|
|
@@ -2426,13 +2758,42 @@ var NormalComponent = class extends PrimitiveComponent {
|
|
|
2426
2758
|
height: pcb_component.height
|
|
2427
2759
|
};
|
|
2428
2760
|
}
|
|
2429
|
-
|
|
2430
|
-
const
|
|
2431
|
-
const
|
|
2432
|
-
const
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
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;
|
|
2792
|
+
const { boardThickness = 0 } = this.root?._getBoard() ?? {};
|
|
2793
|
+
const cadModel = this._parsedProps.cadModel;
|
|
2794
|
+
if (!this.pcb_component_id) return;
|
|
2795
|
+
if (!cadModel && !this.props.footprint) return;
|
|
2796
|
+
const bounds = this._getPcbCircuitJsonBounds();
|
|
2436
2797
|
const pcb_component = db.pcb_component.get(this.pcb_component_id);
|
|
2437
2798
|
if (typeof cadModel === "string") {
|
|
2438
2799
|
throw new Error("String cadModel not yet implemented");
|
|
@@ -3421,431 +3782,136 @@ searched component ${targetComponent.getString()}, which has ports: ${targetComp
|
|
|
3421
3782
|
const portsWithPosition = ports.map(({ port }) => ({
|
|
3422
3783
|
port,
|
|
3423
3784
|
position: port._getGlobalSchematicPositionAfterLayout(),
|
|
3424
|
-
schematic_port_id: port.schematic_port_id ?? void 0,
|
|
3425
|
-
facingDirection: port.facingDirection
|
|
3426
|
-
}));
|
|
3427
|
-
if (portsWithPosition.length < 2) {
|
|
3428
|
-
return;
|
|
3429
|
-
}
|
|
3430
|
-
connection.pointsToConnect = portsWithPosition.map(({ position }) => ({
|
|
3431
|
-
...position,
|
|
3432
|
-
layer: "top"
|
|
3433
|
-
}));
|
|
3434
|
-
const bounds = computeObstacleBounds(obstacles);
|
|
3435
|
-
const simpleRouteJsonInput = {
|
|
3436
|
-
minTraceWidth: 0.1,
|
|
3437
|
-
obstacles,
|
|
3438
|
-
connections: [connection],
|
|
3439
|
-
bounds,
|
|
3440
|
-
layerCount: 1
|
|
3441
|
-
};
|
|
3442
|
-
let Autorouter = MultilayerIjump;
|
|
3443
|
-
if (this.getSubcircuit().props._schDirectLineRoutingEnabled) {
|
|
3444
|
-
Autorouter = DirectLineRouter;
|
|
3445
|
-
}
|
|
3446
|
-
const autorouter = new Autorouter({
|
|
3447
|
-
input: simpleRouteJsonInput,
|
|
3448
|
-
OBSTACLE_MARGIN: 0.1,
|
|
3449
|
-
isRemovePathLoopsEnabled: true
|
|
3450
|
-
});
|
|
3451
|
-
const results = autorouter.solveAndMapToTraces();
|
|
3452
|
-
if (results.length === 0) return;
|
|
3453
|
-
const [result] = results;
|
|
3454
|
-
const { route } = result;
|
|
3455
|
-
const edges = [];
|
|
3456
|
-
for (let i = 0; i < route.length - 1; i++) {
|
|
3457
|
-
edges.push({
|
|
3458
|
-
from: route[i],
|
|
3459
|
-
to: route[i + 1]
|
|
3460
|
-
});
|
|
3461
|
-
}
|
|
3462
|
-
const STUB_LENGTH = 0.15;
|
|
3463
|
-
edges.unshift({
|
|
3464
|
-
from: {
|
|
3465
|
-
...projectPointInDirection(
|
|
3466
|
-
route[0],
|
|
3467
|
-
portsWithPosition[0].facingDirection,
|
|
3468
|
-
STUB_LENGTH
|
|
3469
|
-
)
|
|
3470
|
-
},
|
|
3471
|
-
to: route[0],
|
|
3472
|
-
from_schematic_port_id: portsWithPosition[0].schematic_port_id
|
|
3473
|
-
});
|
|
3474
|
-
edges.push({
|
|
3475
|
-
from: route[route.length - 1],
|
|
3476
|
-
to: {
|
|
3477
|
-
...projectPointInOppositeDirection(
|
|
3478
|
-
route[route.length - 1],
|
|
3479
|
-
portsWithPosition[1].facingDirection,
|
|
3480
|
-
STUB_LENGTH
|
|
3481
|
-
)
|
|
3482
|
-
},
|
|
3483
|
-
from_schematic_port_id: portsWithPosition[1].schematic_port_id
|
|
3484
|
-
});
|
|
3485
|
-
const trace = db.schematic_trace.insert({
|
|
3486
|
-
source_trace_id: this.source_trace_id,
|
|
3487
|
-
edges
|
|
3488
|
-
});
|
|
3489
|
-
this.schematic_trace_id = trace.schematic_trace_id;
|
|
3490
|
-
}
|
|
3491
|
-
};
|
|
3492
|
-
|
|
3493
|
-
// lib/components/normal-components/Capacitor.ts
|
|
3494
|
-
var Capacitor = class extends NormalComponent {
|
|
3495
|
-
// @ts-ignore (cause the symbolName is string and not fixed)
|
|
3496
|
-
get config() {
|
|
3497
|
-
return {
|
|
3498
|
-
componentName: "Capacitor",
|
|
3499
|
-
schematicSymbolName: this.props.symbolName ?? "capacitor_horz",
|
|
3500
|
-
zodProps: capacitorProps,
|
|
3501
|
-
sourceFtype: FTYPE.simple_capacitor
|
|
3502
|
-
};
|
|
3503
|
-
}
|
|
3504
|
-
initPorts() {
|
|
3505
|
-
this.add(new Port({ name: "pin1", pinNumber: 1, aliases: ["anode", "pos", "left"] }));
|
|
3506
|
-
this.add(new Port({ name: "pin2", pinNumber: 2, aliases: ["cathode", "neg", "right"] }));
|
|
3507
|
-
}
|
|
3508
|
-
doInitialCreateNetsFromProps() {
|
|
3509
|
-
this._createNetsFromProps([
|
|
3510
|
-
this.props.decouplingFor,
|
|
3511
|
-
this.props.decouplingTo
|
|
3512
|
-
]);
|
|
3513
|
-
}
|
|
3514
|
-
doInitialCreateTracesFromProps() {
|
|
3515
|
-
if (this.props.decouplingFor && this.props.decouplingTo) {
|
|
3516
|
-
this.add(
|
|
3517
|
-
new Trace({
|
|
3518
|
-
from: `${this.getSubcircuitSelector()} > port.1`,
|
|
3519
|
-
to: this.props.decouplingFor
|
|
3520
|
-
})
|
|
3521
|
-
);
|
|
3522
|
-
this.add(
|
|
3523
|
-
new Trace({
|
|
3524
|
-
from: `${this.getSubcircuitSelector()} > port.2`,
|
|
3525
|
-
to: this.props.decouplingTo
|
|
3526
|
-
})
|
|
3527
|
-
);
|
|
3528
|
-
}
|
|
3529
|
-
}
|
|
3530
|
-
doInitialSourceRender() {
|
|
3531
|
-
const { db } = this.root;
|
|
3532
|
-
const { _parsedProps: props } = this;
|
|
3533
|
-
const source_component = db.source_component.insert({
|
|
3534
|
-
ftype: "simple_capacitor",
|
|
3535
|
-
name: props.name,
|
|
3536
|
-
// @ts-ignore
|
|
3537
|
-
manufacturer_part_number: props.manufacturerPartNumber ?? props.mfn,
|
|
3538
|
-
supplier_part_numbers: props.supplierPartNumbers,
|
|
3539
|
-
capacitance: props.capacitance
|
|
3540
|
-
});
|
|
3541
|
-
this.source_component_id = source_component.source_component_id;
|
|
3542
|
-
}
|
|
3543
|
-
};
|
|
3544
|
-
|
|
3545
|
-
// lib/components/normal-components/Chip.ts
|
|
3546
|
-
import { chipProps } from "@tscircuit/props";
|
|
3547
|
-
|
|
3548
|
-
// lib/soup/underscorifyPinStyles.ts
|
|
3549
|
-
import "circuit-json";
|
|
3550
|
-
import "zod";
|
|
3551
|
-
var underscorifyPinStyles = (pinStyles) => {
|
|
3552
|
-
if (!pinStyles) return void 0;
|
|
3553
|
-
const underscorePinStyles = {};
|
|
3554
|
-
for (const [pinName, pinStyle] of Object.entries(pinStyles)) {
|
|
3555
|
-
underscorePinStyles[pinName] = {
|
|
3556
|
-
bottom_margin: pinStyle.bottomMargin,
|
|
3557
|
-
left_margin: pinStyle.leftMargin,
|
|
3558
|
-
right_margin: pinStyle.rightMargin,
|
|
3559
|
-
top_margin: pinStyle.topMargin
|
|
3560
|
-
};
|
|
3561
|
-
}
|
|
3562
|
-
return underscorePinStyles;
|
|
3563
|
-
};
|
|
3564
|
-
|
|
3565
|
-
// lib/soup/underscorifyPortArrangement.ts
|
|
3566
|
-
var underscorifyPortArrangement = (portArrangement) => {
|
|
3567
|
-
if (!portArrangement) return void 0;
|
|
3568
|
-
if ("leftSide" in portArrangement || "rightSide" in portArrangement || "topSide" in portArrangement || "bottomSide" in portArrangement) {
|
|
3569
|
-
return {
|
|
3570
|
-
left_side: portArrangement.leftSide,
|
|
3571
|
-
right_side: portArrangement.rightSide,
|
|
3572
|
-
top_side: portArrangement.topSide,
|
|
3573
|
-
bottom_side: portArrangement.bottomSide
|
|
3574
|
-
};
|
|
3575
|
-
}
|
|
3576
|
-
if ("leftPinCount" in portArrangement || "rightPinCount" in portArrangement || "topPinCount" in portArrangement || "bottomPinCount" in portArrangement) {
|
|
3577
|
-
return {
|
|
3578
|
-
left_size: portArrangement.leftPinCount,
|
|
3579
|
-
right_size: portArrangement.rightPinCount,
|
|
3580
|
-
top_size: portArrangement.topPinCount,
|
|
3581
|
-
bottom_size: portArrangement.bottomPinCount
|
|
3582
|
-
};
|
|
3583
|
-
}
|
|
3584
|
-
if ("leftSize" in portArrangement || "rightSize" in portArrangement || "topSize" in portArrangement || "bottomSize" in portArrangement) {
|
|
3585
|
-
return {
|
|
3586
|
-
left_size: portArrangement.leftSize,
|
|
3587
|
-
right_size: portArrangement.rightSize,
|
|
3588
|
-
top_size: portArrangement.topSize,
|
|
3589
|
-
bottom_size: portArrangement.bottomSize
|
|
3590
|
-
};
|
|
3591
|
-
}
|
|
3592
|
-
return void 0;
|
|
3593
|
-
};
|
|
3594
|
-
|
|
3595
|
-
// lib/utils/schematic/getSizeOfSidesFromPortArrangement.ts
|
|
3596
|
-
var hasExplicitPinMapping = (pa) => {
|
|
3597
|
-
for (const side of [
|
|
3598
|
-
"leftSide",
|
|
3599
|
-
"rightSide",
|
|
3600
|
-
"topSide",
|
|
3601
|
-
"bottomSide"
|
|
3602
|
-
]) {
|
|
3603
|
-
if (side in pa && typeof pa[side] === "number") {
|
|
3604
|
-
throw new Error(
|
|
3605
|
-
`A number was specified for "${side}", you probably meant to use "size" not "side"`
|
|
3606
|
-
);
|
|
3607
|
-
}
|
|
3608
|
-
}
|
|
3609
|
-
return "leftSide" in pa || "rightSide" in pa || "topSide" in pa || "bottomSide" in pa;
|
|
3610
|
-
};
|
|
3611
|
-
var getSizeOfSidesFromPortArrangement = (pa) => {
|
|
3612
|
-
if (hasExplicitPinMapping(pa)) {
|
|
3613
|
-
return {
|
|
3614
|
-
leftSize: pa.leftSide?.pins.length ?? 0,
|
|
3615
|
-
rightSize: pa.rightSide?.pins.length ?? 0,
|
|
3616
|
-
topSize: pa.topSide?.pins.length ?? 0,
|
|
3617
|
-
bottomSize: pa.bottomSide?.pins.length ?? 0
|
|
3618
|
-
};
|
|
3619
|
-
}
|
|
3620
|
-
const { leftSize = 0, rightSize = 0, topSize = 0, bottomSize = 0 } = pa;
|
|
3621
|
-
return { leftSize, rightSize, topSize, bottomSize };
|
|
3622
|
-
};
|
|
3623
|
-
|
|
3624
|
-
// lib/utils/schematic/getAllDimensionsForSchematicBox.ts
|
|
3625
|
-
function isExplicitPinMappingArrangement(arrangement) {
|
|
3626
|
-
return arrangement.leftSide !== void 0;
|
|
3627
|
-
}
|
|
3628
|
-
var getAllDimensionsForSchematicBox = (params) => {
|
|
3629
|
-
const componentMargin = params.schPinSpacing;
|
|
3630
|
-
let sidePinCounts = params.schPortArrangement ? getSizeOfSidesFromPortArrangement(params.schPortArrangement) : null;
|
|
3631
|
-
const sideLengths = {
|
|
3632
|
-
left: 0,
|
|
3633
|
-
right: 0,
|
|
3634
|
-
top: 0,
|
|
3635
|
-
bottom: 0
|
|
3636
|
-
};
|
|
3637
|
-
let pinCount = params.pinCount ?? null;
|
|
3638
|
-
if (pinCount === null) {
|
|
3639
|
-
if (sidePinCounts) {
|
|
3640
|
-
pinCount = sidePinCounts.leftSize + sidePinCounts.rightSize + sidePinCounts.topSize + sidePinCounts.bottomSize;
|
|
3641
|
-
} else {
|
|
3642
|
-
throw new Error("Could not determine pin count for the schematic box");
|
|
3643
|
-
}
|
|
3644
|
-
}
|
|
3645
|
-
if (pinCount && !sidePinCounts) {
|
|
3646
|
-
const rightSize = Math.floor(pinCount / 2);
|
|
3647
|
-
sidePinCounts = {
|
|
3648
|
-
leftSize: pinCount - rightSize,
|
|
3649
|
-
rightSize,
|
|
3650
|
-
topSize: 0,
|
|
3651
|
-
bottomSize: 0
|
|
3652
|
-
};
|
|
3653
|
-
}
|
|
3654
|
-
if (!sidePinCounts) {
|
|
3655
|
-
sidePinCounts = {
|
|
3656
|
-
leftSize: 0,
|
|
3657
|
-
rightSize: 0,
|
|
3658
|
-
topSize: 0,
|
|
3659
|
-
bottomSize: 0
|
|
3660
|
-
};
|
|
3661
|
-
}
|
|
3662
|
-
const schWidth = params.schWidth ?? Math.max(sidePinCounts.topSize, sidePinCounts.bottomSize) * params.schPinSpacing + 2 * componentMargin;
|
|
3663
|
-
const schHeight = params.schHeight ?? Math.max(sidePinCounts.leftSize, sidePinCounts.rightSize) * params.schPinSpacing + 2 * componentMargin;
|
|
3664
|
-
const distributePorts = (sideSize, sideLength, totalMargin) => {
|
|
3665
|
-
if (sideSize <= 1) return 0;
|
|
3666
|
-
return (sideLength - totalMargin) / (sideSize - 1);
|
|
3667
|
-
};
|
|
3668
|
-
const orderedTruePorts = [];
|
|
3669
|
-
let truePinIndex = 0;
|
|
3670
|
-
const processSide = (side, pins, direction) => {
|
|
3671
|
-
const isVertical = side === "left" || side === "right";
|
|
3672
|
-
const sideLength = isVertical ? schHeight : schWidth;
|
|
3673
|
-
let totalMargin = 0;
|
|
3674
|
-
for (const pin of pins) {
|
|
3675
|
-
const pinStyle = params.schPinStyle?.[`pin${pin}`] ?? params.schPinStyle?.[pin];
|
|
3676
|
-
if (pinStyle) {
|
|
3677
|
-
if (isVertical) {
|
|
3678
|
-
totalMargin += (pinStyle.topMargin ?? 0) + (pinStyle.bottomMargin ?? 0);
|
|
3679
|
-
} else {
|
|
3680
|
-
totalMargin += (pinStyle.leftMargin ?? 0) + (pinStyle.rightMargin ?? 0);
|
|
3681
|
-
}
|
|
3682
|
-
}
|
|
3683
|
-
}
|
|
3684
|
-
const spacing = distributePorts(
|
|
3685
|
-
pins.length,
|
|
3686
|
-
sideLength - 2 * componentMargin,
|
|
3687
|
-
totalMargin
|
|
3688
|
-
);
|
|
3689
|
-
let currentDistanceFromEdge = componentMargin;
|
|
3690
|
-
pins.forEach((pinNumber, index) => {
|
|
3691
|
-
const pinStyle = params.schPinStyle?.[`pin${pinNumber}`] ?? params.schPinStyle?.[pinNumber];
|
|
3692
|
-
if (pinStyle) {
|
|
3693
|
-
if (isVertical) {
|
|
3694
|
-
if (side === "left") {
|
|
3695
|
-
currentDistanceFromEdge += direction === "top-to-bottom" ? pinStyle.topMargin ?? 0 : pinStyle.bottomMargin ?? 0;
|
|
3696
|
-
} else {
|
|
3697
|
-
currentDistanceFromEdge += direction === "top-to-bottom" ? pinStyle.bottomMargin ?? 0 : pinStyle.topMargin ?? 0;
|
|
3698
|
-
}
|
|
3699
|
-
} else {
|
|
3700
|
-
if (side === "top") {
|
|
3701
|
-
currentDistanceFromEdge += direction === "left-to-right" ? pinStyle.leftMargin ?? 0 : pinStyle.rightMargin ?? 0;
|
|
3702
|
-
} else {
|
|
3703
|
-
currentDistanceFromEdge += direction === "left-to-right" ? pinStyle.rightMargin ?? 0 : pinStyle.leftMargin ?? 0;
|
|
3704
|
-
}
|
|
3705
|
-
}
|
|
3706
|
-
}
|
|
3707
|
-
orderedTruePorts.push({
|
|
3708
|
-
trueIndex: truePinIndex,
|
|
3709
|
-
pinNumber,
|
|
3710
|
-
side,
|
|
3711
|
-
distanceFromEdge: currentDistanceFromEdge,
|
|
3712
|
-
x: 0,
|
|
3713
|
-
y: 0
|
|
3714
|
-
});
|
|
3715
|
-
if (pinStyle) {
|
|
3716
|
-
if (isVertical) {
|
|
3717
|
-
if (side === "left") {
|
|
3718
|
-
currentDistanceFromEdge += direction === "top-to-bottom" ? pinStyle.bottomMargin ?? 0 : pinStyle.topMargin ?? 0;
|
|
3719
|
-
} else {
|
|
3720
|
-
currentDistanceFromEdge += direction === "top-to-bottom" ? pinStyle.topMargin ?? 0 : pinStyle.bottomMargin ?? 0;
|
|
3721
|
-
}
|
|
3722
|
-
} else {
|
|
3723
|
-
if (side === "top") {
|
|
3724
|
-
currentDistanceFromEdge += direction === "left-to-right" ? pinStyle.rightMargin ?? 0 : pinStyle.leftMargin ?? 0;
|
|
3725
|
-
} else {
|
|
3726
|
-
currentDistanceFromEdge += direction === "left-to-right" ? pinStyle.leftMargin ?? 0 : pinStyle.rightMargin ?? 0;
|
|
3727
|
-
}
|
|
3728
|
-
}
|
|
3729
|
-
}
|
|
3730
|
-
currentDistanceFromEdge += spacing;
|
|
3731
|
-
truePinIndex++;
|
|
3732
|
-
});
|
|
3733
|
-
sideLengths[side] = sideLength;
|
|
3734
|
-
};
|
|
3735
|
-
if (params.schPortArrangement && isExplicitPinMappingArrangement(params.schPortArrangement)) {
|
|
3736
|
-
if (params.schPortArrangement.leftSide) {
|
|
3737
|
-
processSide(
|
|
3738
|
-
"left",
|
|
3739
|
-
params.schPortArrangement.leftSide.pins,
|
|
3740
|
-
params.schPortArrangement.leftSide.direction ?? "top-to-bottom"
|
|
3741
|
-
);
|
|
3742
|
-
}
|
|
3743
|
-
if (params.schPortArrangement.rightSide) {
|
|
3744
|
-
processSide(
|
|
3745
|
-
"right",
|
|
3746
|
-
params.schPortArrangement.rightSide.pins,
|
|
3747
|
-
params.schPortArrangement.rightSide.direction ?? "bottom-to-top"
|
|
3748
|
-
);
|
|
3785
|
+
schematic_port_id: port.schematic_port_id ?? void 0,
|
|
3786
|
+
facingDirection: port.facingDirection
|
|
3787
|
+
}));
|
|
3788
|
+
if (portsWithPosition.length < 2) {
|
|
3789
|
+
return;
|
|
3749
3790
|
}
|
|
3750
|
-
|
|
3751
|
-
|
|
3752
|
-
|
|
3753
|
-
|
|
3754
|
-
|
|
3755
|
-
|
|
3791
|
+
connection.pointsToConnect = portsWithPosition.map(({ position }) => ({
|
|
3792
|
+
...position,
|
|
3793
|
+
layer: "top"
|
|
3794
|
+
}));
|
|
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;
|
|
3756
3806
|
}
|
|
3757
|
-
|
|
3758
|
-
|
|
3759
|
-
|
|
3760
|
-
|
|
3761
|
-
|
|
3762
|
-
|
|
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
|
+
});
|
|
3763
3822
|
}
|
|
3764
|
-
|
|
3765
|
-
|
|
3766
|
-
|
|
3767
|
-
|
|
3768
|
-
|
|
3769
|
-
|
|
3770
|
-
|
|
3771
|
-
|
|
3772
|
-
);
|
|
3773
|
-
const topSide = Array.from(
|
|
3774
|
-
{ length: sidePinCounts.topSize },
|
|
3775
|
-
(_, i) => i + sidePinCounts.leftSize + sidePinCounts.rightSize + 1
|
|
3776
|
-
);
|
|
3777
|
-
const bottomSide = Array.from(
|
|
3778
|
-
{
|
|
3779
|
-
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
|
+
)
|
|
3780
3831
|
},
|
|
3781
|
-
|
|
3782
|
-
|
|
3783
|
-
|
|
3784
|
-
|
|
3785
|
-
|
|
3786
|
-
|
|
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;
|
|
3787
3851
|
}
|
|
3788
|
-
|
|
3789
|
-
|
|
3790
|
-
|
|
3791
|
-
|
|
3792
|
-
|
|
3793
|
-
|
|
3794
|
-
const trueEdgeTraversalDirections = {
|
|
3795
|
-
left: { x: 0, y: -1 },
|
|
3796
|
-
right: { x: 0, y: 1 },
|
|
3797
|
-
top: { x: -1, y: 0 },
|
|
3798
|
-
bottom: { x: 1, y: 0 }
|
|
3799
|
-
};
|
|
3800
|
-
const truePortsWithPositions = orderedTruePorts.map((p) => {
|
|
3801
|
-
const { distanceFromEdge, side } = p;
|
|
3802
|
-
if (side === "center") {
|
|
3803
|
-
return {
|
|
3804
|
-
...p,
|
|
3805
|
-
x: 0,
|
|
3806
|
-
y: 0
|
|
3807
|
-
};
|
|
3808
|
-
}
|
|
3809
|
-
const edgePos = trueEdgePositions[side];
|
|
3810
|
-
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() {
|
|
3811
3858
|
return {
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3859
|
+
componentName: "Capacitor",
|
|
3860
|
+
schematicSymbolName: this.props.symbolName ?? "capacitor_horz",
|
|
3861
|
+
zodProps: capacitorProps,
|
|
3862
|
+
sourceFtype: FTYPE.simple_capacitor
|
|
3815
3863
|
};
|
|
3816
|
-
}
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
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
|
+
})
|
|
3821
3882
|
);
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
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
|
+
}
|
|
3840
3904
|
};
|
|
3841
3905
|
|
|
3842
3906
|
// lib/components/normal-components/Chip.ts
|
|
3907
|
+
import { chipProps } from "@tscircuit/props";
|
|
3843
3908
|
var Chip = class extends NormalComponent {
|
|
3844
|
-
|
|
3909
|
+
schematicBoxDimensions = null;
|
|
3845
3910
|
get config() {
|
|
3846
3911
|
return {
|
|
3847
3912
|
componentName: "Chip",
|
|
3848
|
-
zodProps: chipProps
|
|
3913
|
+
zodProps: chipProps,
|
|
3914
|
+
shouldRenderAsSchematicBox: true
|
|
3849
3915
|
};
|
|
3850
3916
|
}
|
|
3851
3917
|
doInitialSourceRender() {
|
|
@@ -3859,43 +3925,6 @@ var Chip = class extends NormalComponent {
|
|
|
3859
3925
|
});
|
|
3860
3926
|
this.source_component_id = source_component.source_component_id;
|
|
3861
3927
|
}
|
|
3862
|
-
doInitialSchematicComponentRender() {
|
|
3863
|
-
const { db } = this.root;
|
|
3864
|
-
const { _parsedProps: props } = this;
|
|
3865
|
-
const pinCountFromSchArrangement = (props.schPortArrangement?.leftSize ?? 0) + (props.schPortArrangement?.rightSize ?? 0) + (props.schPortArrangement?.topSize ?? 0) + (props.schPortArrangement?.bottomSize ?? 0);
|
|
3866
|
-
const pinCount = pinCountFromSchArrangement || this.getPortsFromFootprint().length;
|
|
3867
|
-
const pinSpacing = props.schPinSpacing ?? 0.2;
|
|
3868
|
-
const dimensions = getAllDimensionsForSchematicBox({
|
|
3869
|
-
schWidth: props.schWidth,
|
|
3870
|
-
schHeight: props.schHeight,
|
|
3871
|
-
schPinSpacing: pinSpacing,
|
|
3872
|
-
schPinStyle: props.schPinStyle,
|
|
3873
|
-
pinCount,
|
|
3874
|
-
// @ts-ignore there's a subtley in the definition difference with
|
|
3875
|
-
// leftSide/rightSide/topSide/bottomSide in how the direction is defined
|
|
3876
|
-
// that doesn't really matter
|
|
3877
|
-
schPortArrangement: props.schPortArrangement
|
|
3878
|
-
});
|
|
3879
|
-
this.schematicDimensions = dimensions;
|
|
3880
|
-
const primaryPortLabels = {};
|
|
3881
|
-
for (const [port, label] of Object.entries(props.pinLabels ?? {})) {
|
|
3882
|
-
primaryPortLabels[port] = Array.isArray(label) ? label[0] : label;
|
|
3883
|
-
}
|
|
3884
|
-
const schematic_component2 = db.schematic_component.insert({
|
|
3885
|
-
center: { x: props.schX ?? 0, y: props.schY ?? 0 },
|
|
3886
|
-
rotation: props.schRotation ?? 0,
|
|
3887
|
-
size: dimensions.getSize(),
|
|
3888
|
-
port_arrangement: underscorifyPortArrangement(
|
|
3889
|
-
props.schPortArrangement
|
|
3890
|
-
),
|
|
3891
|
-
pin_spacing: pinSpacing,
|
|
3892
|
-
// @ts-ignore soup needs to support distance for pin_styles
|
|
3893
|
-
pin_styles: underscorifyPinStyles(props.schPinStyle),
|
|
3894
|
-
port_labels: primaryPortLabels,
|
|
3895
|
-
source_component_id: this.source_component_id
|
|
3896
|
-
});
|
|
3897
|
-
this.schematic_component_id = schematic_component2.schematic_component_id;
|
|
3898
|
-
}
|
|
3899
3928
|
doInitialPcbComponentRender() {
|
|
3900
3929
|
const { db } = this.root;
|
|
3901
3930
|
const { _parsedProps: props } = this;
|
|
@@ -3946,7 +3975,8 @@ var Jumper = class extends NormalComponent {
|
|
|
3946
3975
|
get config() {
|
|
3947
3976
|
return {
|
|
3948
3977
|
componentName: "Jumper",
|
|
3949
|
-
zodProps: jumperProps
|
|
3978
|
+
zodProps: jumperProps,
|
|
3979
|
+
shouldRenderAsSchematicBox: true
|
|
3950
3980
|
};
|
|
3951
3981
|
}
|
|
3952
3982
|
doInitialSourceRender() {
|
|
@@ -3961,41 +3991,6 @@ var Jumper = class extends NormalComponent {
|
|
|
3961
3991
|
});
|
|
3962
3992
|
this.source_component_id = source_component.source_component_id;
|
|
3963
3993
|
}
|
|
3964
|
-
doInitialSchematicComponentRender() {
|
|
3965
|
-
const { db } = this.root;
|
|
3966
|
-
const { _parsedProps: props } = this;
|
|
3967
|
-
const ports = this.children.filter((child) => child instanceof Port);
|
|
3968
|
-
const pinSpacing = props.schPinSpacing ?? 0.2;
|
|
3969
|
-
const dimensions = getAllDimensionsForSchematicBox({
|
|
3970
|
-
schWidth: props.schWidth,
|
|
3971
|
-
schHeight: props.schHeight,
|
|
3972
|
-
schPinSpacing: pinSpacing,
|
|
3973
|
-
schPinStyle: props.schPinStyle,
|
|
3974
|
-
pinCount: ports.length,
|
|
3975
|
-
// @ts-ignore there's a subtley in the definition difference with
|
|
3976
|
-
// leftSide/rightSide/topSide/bottomSide in how the direction is defined
|
|
3977
|
-
// that doesn't really matter
|
|
3978
|
-
schPortArrangement: {
|
|
3979
|
-
// TODO use schematic direction or schPortArrangement
|
|
3980
|
-
rightSize: ports.length
|
|
3981
|
-
}
|
|
3982
|
-
});
|
|
3983
|
-
this.schematicDimensions = dimensions;
|
|
3984
|
-
const schematic_component2 = db.schematic_component.insert({
|
|
3985
|
-
center: { x: props.schX ?? 0, y: props.schY ?? 0 },
|
|
3986
|
-
rotation: props.schRotation ?? 0,
|
|
3987
|
-
size: dimensions.getSize(),
|
|
3988
|
-
port_arrangement: underscorifyPortArrangement(
|
|
3989
|
-
props.schPortArrangement
|
|
3990
|
-
),
|
|
3991
|
-
pin_spacing: pinSpacing,
|
|
3992
|
-
// @ts-ignore soup needs to support distance for pin_styles
|
|
3993
|
-
pin_styles: underscorifyPinStyles(props.schPinStyle),
|
|
3994
|
-
port_labels: props.pinLabels,
|
|
3995
|
-
source_component_id: this.source_component_id
|
|
3996
|
-
});
|
|
3997
|
-
this.schematic_component_id = schematic_component2.schematic_component_id;
|
|
3998
|
-
}
|
|
3999
3994
|
doInitialPcbComponentRender() {
|
|
4000
3995
|
const { db } = this.root;
|
|
4001
3996
|
const { _parsedProps: props } = this;
|
|
@@ -4501,7 +4496,7 @@ var PinHeader = class extends NormalComponent {
|
|
|
4501
4496
|
return {
|
|
4502
4497
|
componentName: "PinHeader",
|
|
4503
4498
|
zodProps: pinHeaderProps,
|
|
4504
|
-
|
|
4499
|
+
shouldRenderAsSchematicBox: true
|
|
4505
4500
|
};
|
|
4506
4501
|
}
|
|
4507
4502
|
_getImpliedFootprintString() {
|
|
@@ -4529,6 +4524,12 @@ var PinHeader = class extends NormalComponent {
|
|
|
4529
4524
|
);
|
|
4530
4525
|
}
|
|
4531
4526
|
}
|
|
4527
|
+
_getSchematicPortArrangement() {
|
|
4528
|
+
return {
|
|
4529
|
+
leftSize: 0,
|
|
4530
|
+
rightSize: this._parsedProps.pinCount ?? 1
|
|
4531
|
+
};
|
|
4532
|
+
}
|
|
4532
4533
|
doInitialSourceRender() {
|
|
4533
4534
|
const { db } = this.root;
|
|
4534
4535
|
const { _parsedProps: props } = this;
|
|
@@ -4542,21 +4543,6 @@ var PinHeader = class extends NormalComponent {
|
|
|
4542
4543
|
});
|
|
4543
4544
|
this.source_component_id = source_component.source_component_id;
|
|
4544
4545
|
}
|
|
4545
|
-
doInitialSchematicComponentRender() {
|
|
4546
|
-
const { db } = this.root;
|
|
4547
|
-
const { _parsedProps: props } = this;
|
|
4548
|
-
const schematic_component2 = db.schematic_component.insert({
|
|
4549
|
-
center: { x: props.schX ?? 0, y: props.schY ?? 0 },
|
|
4550
|
-
rotation: props.schRotation ?? 0,
|
|
4551
|
-
size: { width: 2, height: props.pinCount ?? 1 },
|
|
4552
|
-
source_component_id: this.source_component_id,
|
|
4553
|
-
port_arrangement: {
|
|
4554
|
-
left_size: 0,
|
|
4555
|
-
right_size: props.pinCount ?? 1
|
|
4556
|
-
}
|
|
4557
|
-
});
|
|
4558
|
-
this.schematic_component_id = schematic_component2.schematic_component_id;
|
|
4559
|
-
}
|
|
4560
4546
|
};
|
|
4561
4547
|
|
|
4562
4548
|
// lib/components/normal-components/Inductor.ts
|