@tscircuit/core 0.0.2145 → 0.0.2147
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 +117 -6
- package/dist/index.js +222 -73
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -137,6 +137,68 @@ __export(components_exports, {
|
|
|
137
137
|
VoltageSource: () => VoltageSource
|
|
138
138
|
});
|
|
139
139
|
|
|
140
|
+
// lib/utils/schematic/getPinNumberFromPinLabelsKey.ts
|
|
141
|
+
var PIN_LABELS_KEY_RE = /^(?:pin)?(\d+)$/;
|
|
142
|
+
var getPinNumberFromPinLabelsKey = (pinKey) => {
|
|
143
|
+
const match = pinKey.match(PIN_LABELS_KEY_RE);
|
|
144
|
+
if (!match) return null;
|
|
145
|
+
return Number.parseInt(match[1], 10);
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// lib/utils/schematic/resolvePinLabels.ts
|
|
149
|
+
var isPhysicalPinName = (name) => /^[A-Z]+[1-9]\d*$/.test(name);
|
|
150
|
+
function resolvePinLabels(pinLabels) {
|
|
151
|
+
const usedPinNumbers = new Set(
|
|
152
|
+
Object.keys(pinLabels).flatMap((key) => {
|
|
153
|
+
const pinNumber = getPinNumberFromPinLabelsKey(key);
|
|
154
|
+
return pinNumber === null ? [] : [pinNumber];
|
|
155
|
+
})
|
|
156
|
+
);
|
|
157
|
+
const physicalNames = Object.keys(pinLabels).filter(isPhysicalPinName).sort((a2, b2) => {
|
|
158
|
+
const [, rowA, columnA] = a2.match(/^([A-Z]+)(\d+)$/);
|
|
159
|
+
const [, rowB, columnB] = b2.match(/^([A-Z]+)(\d+)$/);
|
|
160
|
+
return rowA.length - rowB.length || (rowA < rowB ? -1 : rowA > rowB ? 1 : 0) || Number(columnA) - Number(columnB);
|
|
161
|
+
});
|
|
162
|
+
const physicalPins = [];
|
|
163
|
+
let nextPinNumber = 1;
|
|
164
|
+
for (const name of physicalNames) {
|
|
165
|
+
while (usedPinNumbers.has(nextPinNumber)) nextPinNumber++;
|
|
166
|
+
physicalPins.push({ physicalPinName: name, pinNumber: nextPinNumber++ });
|
|
167
|
+
}
|
|
168
|
+
return Object.entries(pinLabels).map(([key, labels]) => {
|
|
169
|
+
const numericPinNumber = getPinNumberFromPinLabelsKey(key);
|
|
170
|
+
const pinNumber = numericPinNumber ?? physicalPins.find((pin) => pin.physicalPinName === key)?.pinNumber;
|
|
171
|
+
if (pinNumber === void 0) {
|
|
172
|
+
throw new Error(
|
|
173
|
+
`Invalid pinLabels key "${key}". Expected a numeric pin (e.g. pin1) or physical ball name (e.g. A1).`
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
return {
|
|
177
|
+
pinNumber,
|
|
178
|
+
physicalPinName: numericPinNumber === null ? key : void 0,
|
|
179
|
+
labels: typeof labels === "string" ? [labels] : [...labels]
|
|
180
|
+
};
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
function getNumericPinLabels(pinLabels) {
|
|
184
|
+
if (!Object.keys(pinLabels).some(isPhysicalPinName)) {
|
|
185
|
+
return Object.fromEntries(
|
|
186
|
+
Object.entries(pinLabels).map(([key, labels]) => [
|
|
187
|
+
key,
|
|
188
|
+
typeof labels === "string" ? labels : [...labels]
|
|
189
|
+
])
|
|
190
|
+
);
|
|
191
|
+
}
|
|
192
|
+
return Object.fromEntries(
|
|
193
|
+
resolvePinLabels(pinLabels).map(
|
|
194
|
+
({ pinNumber, physicalPinName, labels }) => [
|
|
195
|
+
`pin${pinNumber}`,
|
|
196
|
+
physicalPinName ? [...labels, physicalPinName] : labels
|
|
197
|
+
]
|
|
198
|
+
)
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
|
|
140
202
|
// lib/components/base-components/NormalComponent/NormalComponent.ts
|
|
141
203
|
import { resolveManufacturerPartNumber as resolveManufacturerPartNumber2 } from "@tscircuit/props";
|
|
142
204
|
|
|
@@ -937,6 +999,18 @@ var mergeRoutes = (routes) => {
|
|
|
937
999
|
// lib/components/primitive-components/Net.ts
|
|
938
1000
|
import { netProps } from "@tscircuit/props";
|
|
939
1001
|
|
|
1002
|
+
// lib/components/primitive-components/Port/assertUnambiguousPhysicalPortSelection.ts
|
|
1003
|
+
function assertUnambiguousPhysicalPortSelection(ports, selector) {
|
|
1004
|
+
if (ports.length < 2 || !ports.some((port) => port.physicalPinName)) return;
|
|
1005
|
+
const names = ports.map((port) => {
|
|
1006
|
+
const componentName = port.getParentNormalComponent()?.name ?? "unnamed component";
|
|
1007
|
+
return `${componentName}.${port.physicalPinName ?? port.name}`;
|
|
1008
|
+
});
|
|
1009
|
+
throw new Error(
|
|
1010
|
+
`Ambiguous port "${selector}"; use a physical ball name: ${names.join(", ")}.`
|
|
1011
|
+
);
|
|
1012
|
+
}
|
|
1013
|
+
|
|
940
1014
|
// lib/components/base-components/PrimitiveComponent/get-construction-props-schema.ts
|
|
941
1015
|
var constructionSchemas = /* @__PURE__ */ new WeakMap();
|
|
942
1016
|
var getConstructionPropsSchema = (schema) => {
|
|
@@ -2431,6 +2505,11 @@ var PrimitiveComponent2 = class extends Renderable {
|
|
|
2431
2505
|
if (this.isPrimitiveContainer) return this;
|
|
2432
2506
|
return this.parent?.getPrimitiveContainer?.() ?? null;
|
|
2433
2507
|
}
|
|
2508
|
+
/** Resolve mounting intent from the container owning this primitive. */
|
|
2509
|
+
_getIsSmt() {
|
|
2510
|
+
const container = this.getPrimitiveContainer();
|
|
2511
|
+
return container && container !== this ? container._getIsSmt() : true;
|
|
2512
|
+
}
|
|
2434
2513
|
/**
|
|
2435
2514
|
* Get the Symbol ancestor if this component is inside a Symbol primitive container.
|
|
2436
2515
|
* Used by schematic primitives to access the symbol's resize transform.
|
|
@@ -2999,9 +3078,16 @@ var PrimitiveComponent2 = class extends Renderable {
|
|
|
2999
3078
|
this,
|
|
3000
3079
|
cssSelectOptionsInsideSubcircuit
|
|
3001
3080
|
);
|
|
3002
|
-
|
|
3081
|
+
const matchingComponents = allMatching.filter(
|
|
3003
3082
|
(n2) => n2.lowercaseComponentName === options.type
|
|
3004
3083
|
);
|
|
3084
|
+
if (options.type === "port") {
|
|
3085
|
+
assertUnambiguousPhysicalPortSelection(
|
|
3086
|
+
matchingComponents,
|
|
3087
|
+
selectorRaw
|
|
3088
|
+
);
|
|
3089
|
+
}
|
|
3090
|
+
result = matchingComponents[0] ?? null;
|
|
3005
3091
|
}
|
|
3006
3092
|
if (!options?.type) {
|
|
3007
3093
|
result ??= selectOne(
|
|
@@ -3011,6 +3097,14 @@ var PrimitiveComponent2 = class extends Renderable {
|
|
|
3011
3097
|
);
|
|
3012
3098
|
}
|
|
3013
3099
|
if (result) {
|
|
3100
|
+
if (!options?.type && result.componentName === "Port") {
|
|
3101
|
+
assertUnambiguousPhysicalPortSelection(
|
|
3102
|
+
this.selectAll(selectorRaw).filter(
|
|
3103
|
+
(component) => component.componentName === "Port"
|
|
3104
|
+
),
|
|
3105
|
+
selectorRaw
|
|
3106
|
+
);
|
|
3107
|
+
}
|
|
3014
3108
|
this._cachedSelectOneQueries.set(selectorRaw, result);
|
|
3015
3109
|
return result;
|
|
3016
3110
|
}
|
|
@@ -5211,10 +5305,13 @@ var Port = class extends PrimitiveComponent2 {
|
|
|
5211
5305
|
registerMatch(component) {
|
|
5212
5306
|
this.matchedComponents.push(component);
|
|
5213
5307
|
}
|
|
5308
|
+
/** Physical package ball name; pinNumber remains a schematic layout ordinal. */
|
|
5309
|
+
physicalPinName;
|
|
5214
5310
|
getNameAndAliases() {
|
|
5215
5311
|
const { _parsedProps: props } = this;
|
|
5216
5312
|
return Array.from(
|
|
5217
5313
|
/* @__PURE__ */ new Set([
|
|
5314
|
+
...this.physicalPinName ? [this.physicalPinName] : [],
|
|
5218
5315
|
...props.name ? [props.name] : [],
|
|
5219
5316
|
...props.aliases ?? [],
|
|
5220
5317
|
...typeof props.pinNumber === "number" ? [`pin${props.pinNumber}`, props.pinNumber.toString()] : [],
|
|
@@ -5308,8 +5405,10 @@ var Port = class extends PrimitiveComponent2 {
|
|
|
5308
5405
|
const source_component_id = parentWithSourceId?.source_component_id ?? null;
|
|
5309
5406
|
const portAttributesFromParent = resolvePortSourcePinAttributes(this);
|
|
5310
5407
|
const source_port = db2.source_port.insert({
|
|
5311
|
-
name: props.name,
|
|
5312
|
-
|
|
5408
|
+
name: this.physicalPinName ?? props.name,
|
|
5409
|
+
// Physical balls have a string package identity. Keep their numeric
|
|
5410
|
+
// layout ordinal on schematic_port, not the physical source pin number.
|
|
5411
|
+
pin_number: this.physicalPinName ? void 0 : props.pinNumber,
|
|
5313
5412
|
port_hints,
|
|
5314
5413
|
source_component_id,
|
|
5315
5414
|
subcircuit_id: this.getSubcircuit()?.subcircuit_id,
|
|
@@ -9242,14 +9341,6 @@ var createInstanceFromReactElement = (reactElm) => {
|
|
|
9242
9341
|
import "circuit-json";
|
|
9243
9342
|
import "zod";
|
|
9244
9343
|
|
|
9245
|
-
// lib/utils/schematic/getPinNumberFromPinLabelsKey.ts
|
|
9246
|
-
var PIN_LABELS_KEY_RE = /^(?:pin)?(\d+)$/;
|
|
9247
|
-
var getPinNumberFromPinLabelsKey = (pinKey) => {
|
|
9248
|
-
const match = pinKey.match(PIN_LABELS_KEY_RE);
|
|
9249
|
-
if (!match) return null;
|
|
9250
|
-
return Number.parseInt(match[1], 10);
|
|
9251
|
-
};
|
|
9252
|
-
|
|
9253
9344
|
// lib/utils/filterPinLabels.ts
|
|
9254
9345
|
function filterPinLabels(pinLabels) {
|
|
9255
9346
|
if (!pinLabels)
|
|
@@ -9323,18 +9414,20 @@ var parsePinNumberFromLabelsOrThrow = (pinNumberOrLabel, pinLabels) => {
|
|
|
9323
9414
|
if (!pinLabels) {
|
|
9324
9415
|
throw new Error(getInvalidPinLabelMessage(pinNumberOrLabel));
|
|
9325
9416
|
}
|
|
9326
|
-
|
|
9327
|
-
|
|
9328
|
-
|
|
9329
|
-
|
|
9330
|
-
|
|
9331
|
-
|
|
9332
|
-
|
|
9333
|
-
|
|
9334
|
-
|
|
9335
|
-
|
|
9336
|
-
|
|
9417
|
+
const resolvedPins = resolvePinLabels(pinLabels);
|
|
9418
|
+
const physicalPin = resolvedPins.find(
|
|
9419
|
+
(pin) => pin.physicalPinName === pinNumberOrLabel
|
|
9420
|
+
);
|
|
9421
|
+
if (physicalPin) return physicalPin.pinNumber;
|
|
9422
|
+
const matches = resolvedPins.filter(
|
|
9423
|
+
(pin) => pin.labels.includes(pinNumberOrLabel)
|
|
9424
|
+
);
|
|
9425
|
+
if (matches.length > 1 && matches.some((pin) => pin.physicalPinName)) {
|
|
9426
|
+
throw new Error(
|
|
9427
|
+
`Ambiguous pin label "${pinNumberOrLabel}"; use a physical ball name: ${matches.map((pin) => pin.physicalPinName ?? `pin${pin.pinNumber}`).join(", ")}.`
|
|
9428
|
+
);
|
|
9337
9429
|
}
|
|
9430
|
+
if (matches.length > 0) return matches[0].pinNumber;
|
|
9338
9431
|
throw new Error(getInvalidPinLabelMessage(pinNumberOrLabel));
|
|
9339
9432
|
};
|
|
9340
9433
|
|
|
@@ -11078,10 +11171,15 @@ function selectPortForPcbPrimitive(ports, primitive, hints) {
|
|
|
11078
11171
|
const pinNumber = getPinNumberFromHints(hints);
|
|
11079
11172
|
const matchingPorts = ports.filter((port) => port.isMatchingAnyOf(hints));
|
|
11080
11173
|
if (matchingPorts.length === 0) return null;
|
|
11174
|
+
const physicalCandidates = matchingPorts.filter(
|
|
11175
|
+
(port) => port.physicalPinName && hints.includes(port.physicalPinName)
|
|
11176
|
+
);
|
|
11177
|
+
if (physicalCandidates.length === 1) return physicalCandidates[0];
|
|
11081
11178
|
const pinMatchedPorts = pinNumber === null ? matchingPorts : matchingPorts.filter(
|
|
11082
11179
|
(port) => port._parsedProps.pinNumber === pinNumber || port._primaryPinNumber === pinNumber
|
|
11083
11180
|
);
|
|
11084
11181
|
const candidates = pinMatchedPorts.length > 0 ? pinMatchedPorts : matchingPorts;
|
|
11182
|
+
assertUnambiguousPhysicalPortSelection(candidates, hints.join(", "));
|
|
11085
11183
|
const overlappingPort = candidates.find(
|
|
11086
11184
|
(port) => port.matchedComponents.some(
|
|
11087
11185
|
(component) => component.isPcbPrimitive && doPcbPrimitivesOverlapBeforeRender(component, primitive)
|
|
@@ -11191,6 +11289,7 @@ var PlatedHole = class extends PrimitiveComponent2 {
|
|
|
11191
11289
|
const position = this._getGlobalPcbPositionBeforeLayout();
|
|
11192
11290
|
const pcb_component_id = this.parent?.pcb_component_id ?? this.getPrimitiveContainer()?.pcb_component_id;
|
|
11193
11291
|
const subcircuit = this.getSubcircuit();
|
|
11292
|
+
const shouldCreateSolderPaste = this._getIsSmt();
|
|
11194
11293
|
const platedHoleLayers = this.getAvailablePcbLayers();
|
|
11195
11294
|
const soldermaskMargin = props.solderMaskMargin;
|
|
11196
11295
|
const isCoveredWithSolderMask = props.coveredWithSolderMask ?? false;
|
|
@@ -11219,26 +11318,28 @@ var PlatedHole = class extends PrimitiveComponent2 {
|
|
|
11219
11318
|
pcb_group_id: this.getGroup()?.pcb_group_id ?? void 0
|
|
11220
11319
|
});
|
|
11221
11320
|
this.pcb_plated_hole_id = pcb_plated_hole.pcb_plated_hole_id;
|
|
11222
|
-
|
|
11223
|
-
|
|
11224
|
-
|
|
11225
|
-
|
|
11226
|
-
|
|
11227
|
-
|
|
11228
|
-
|
|
11229
|
-
|
|
11230
|
-
|
|
11231
|
-
|
|
11232
|
-
|
|
11233
|
-
|
|
11234
|
-
|
|
11235
|
-
|
|
11236
|
-
|
|
11237
|
-
|
|
11238
|
-
|
|
11239
|
-
|
|
11240
|
-
|
|
11241
|
-
|
|
11321
|
+
if (shouldCreateSolderPaste) {
|
|
11322
|
+
db2.pcb_solder_paste.insert({
|
|
11323
|
+
layer: "top",
|
|
11324
|
+
shape: "circle",
|
|
11325
|
+
// @ts-ignore: no idea why this is triggering
|
|
11326
|
+
radius: props.outerDiameter / 2,
|
|
11327
|
+
x: position.x,
|
|
11328
|
+
y: position.y,
|
|
11329
|
+
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
11330
|
+
pcb_group_id: this.getGroup()?.pcb_group_id ?? void 0
|
|
11331
|
+
});
|
|
11332
|
+
db2.pcb_solder_paste.insert({
|
|
11333
|
+
layer: "bottom",
|
|
11334
|
+
shape: "circle",
|
|
11335
|
+
// @ts-ignore: no idea why this is triggering
|
|
11336
|
+
radius: props.outerDiameter / 2,
|
|
11337
|
+
x: position.x,
|
|
11338
|
+
y: position.y,
|
|
11339
|
+
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
11340
|
+
pcb_group_id: this.getGroup()?.pcb_group_id ?? void 0
|
|
11341
|
+
});
|
|
11342
|
+
}
|
|
11242
11343
|
} else if (props.shape === "pill" && props.rectPad) {
|
|
11243
11344
|
const pcb_plated_hole = db2.pcb_plated_hole.insert({
|
|
11244
11345
|
pcb_component_id,
|
|
@@ -11288,7 +11389,7 @@ var PlatedHole = class extends PrimitiveComponent2 {
|
|
|
11288
11389
|
// NOTE: currently PcbPlatedHoleOval erroneously includes both the shape "pill" and "oval"
|
|
11289
11390
|
});
|
|
11290
11391
|
this.pcb_plated_hole_id = pcb_plated_hole.pcb_plated_hole_id;
|
|
11291
|
-
if (props.shape === "pill") {
|
|
11392
|
+
if (props.shape === "pill" && shouldCreateSolderPaste) {
|
|
11292
11393
|
db2.pcb_solder_paste.insert({
|
|
11293
11394
|
layer: "top",
|
|
11294
11395
|
shape: "rotated_pill",
|
|
@@ -11313,7 +11414,7 @@ var PlatedHole = class extends PrimitiveComponent2 {
|
|
|
11313
11414
|
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
11314
11415
|
pcb_group_id: this.getGroup()?.pcb_group_id ?? void 0
|
|
11315
11416
|
});
|
|
11316
|
-
} else if (props.shape === "oval") {
|
|
11417
|
+
} else if (props.shape === "oval" && shouldCreateSolderPaste) {
|
|
11317
11418
|
db2.pcb_solder_paste.insert({
|
|
11318
11419
|
layer: "top",
|
|
11319
11420
|
shape: "oval",
|
|
@@ -12667,7 +12768,7 @@ var SmtPad = class extends PrimitiveComponent2 {
|
|
|
12667
12768
|
const { db: db2 } = this.root;
|
|
12668
12769
|
const { _parsedProps: props } = this;
|
|
12669
12770
|
const isCoveredWithSolderMask = props.coveredWithSolderMask ?? false;
|
|
12670
|
-
const shouldCreateSolderPaste = !isCoveredWithSolderMask;
|
|
12771
|
+
const shouldCreateSolderPaste = !isCoveredWithSolderMask && this._getIsSmt();
|
|
12671
12772
|
const soldermaskMargin = props.solderMaskMargin;
|
|
12672
12773
|
const solderPasteMargin = props.solderPasteMargin;
|
|
12673
12774
|
const getSolderPasteSize = (padSize2, marginScale = 2) => solderPasteMargin !== void 0 ? Math.max(padSize2 + marginScale * solderPasteMargin, 0) : padSize2 * 0.7;
|
|
@@ -17499,6 +17600,15 @@ function getPrimaryPortsFromPortHintGroups(portHintGroups, opts) {
|
|
|
17499
17600
|
);
|
|
17500
17601
|
if (filteredPortHints.length === 0) continue;
|
|
17501
17602
|
let portHintsList = filteredPortHints;
|
|
17603
|
+
const physicalPinNumber = portHintsList.map((hint) => opts?.implicitPinNumberByHint?.get(hint)).find(
|
|
17604
|
+
(pinNumber2) => pinNumber2 !== void 0 && portHintsList.includes(opts?.getPhysicalPinName?.(pinNumber2) ?? "")
|
|
17605
|
+
);
|
|
17606
|
+
if (physicalPinNumber !== void 0) {
|
|
17607
|
+
portHintsList = [
|
|
17608
|
+
...portHintsList.filter((hint) => !/^(?:pin)?\d+$/.test(hint)),
|
|
17609
|
+
`pin${physicalPinNumber}`
|
|
17610
|
+
];
|
|
17611
|
+
}
|
|
17502
17612
|
const hasPinIdentifier = portHintsList.some(
|
|
17503
17613
|
(hint) => hint.startsWith("pin") || /^(?:pin)?\d+$/.test(hint)
|
|
17504
17614
|
);
|
|
@@ -17518,6 +17628,7 @@ function getPrimaryPortsFromPortHintGroups(portHintGroups, opts) {
|
|
|
17518
17628
|
newPort.originDescription = portHintGroup.originDescription;
|
|
17519
17629
|
const pinNumber = newPort._parsedProps.pinNumber;
|
|
17520
17630
|
if (pinNumber === void 0) continue;
|
|
17631
|
+
newPort.physicalPinName = opts?.getPhysicalPinName?.(pinNumber);
|
|
17521
17632
|
if (!entriesByPinNumber.has(pinNumber))
|
|
17522
17633
|
entriesByPinNumber.set(pinNumber, []);
|
|
17523
17634
|
entriesByPinNumber.get(pinNumber).push({
|
|
@@ -17579,7 +17690,7 @@ function getPrimaryPortsFromPortHintGroups(portHintGroups, opts) {
|
|
|
17579
17690
|
}
|
|
17580
17691
|
opts?.inferredInternallyConnectedPinNames?.push(internallyConnectedPinNames);
|
|
17581
17692
|
}
|
|
17582
|
-
if (opts?.inferredInternallyConnectedPinNames) {
|
|
17693
|
+
if (opts?.inferredInternallyConnectedPinNames && opts.inferSharedAliases !== false) {
|
|
17583
17694
|
inferInternallyConnectedPinNamesFromPorts(
|
|
17584
17695
|
ports,
|
|
17585
17696
|
opts.inferredInternallyConnectedPinNames
|
|
@@ -17603,6 +17714,12 @@ var NormalComponent = class extends PrimitiveComponent2 {
|
|
|
17603
17714
|
_resolvedPcbCalcOffsetY;
|
|
17604
17715
|
isPrimitiveContainer = true;
|
|
17605
17716
|
_isNormalComponent = true;
|
|
17717
|
+
_getIsSmt() {
|
|
17718
|
+
if (this._parsedProps.isSmt !== void 0) return this._parsedProps.isSmt;
|
|
17719
|
+
return this.selectAll("smtpad").some(
|
|
17720
|
+
(pad) => pad.getPrimitiveContainer() === this
|
|
17721
|
+
);
|
|
17722
|
+
}
|
|
17606
17723
|
// Mapping from camelCase attribute names to their lowercase equivalents
|
|
17607
17724
|
// This is used by the CSS selector adapter for fast attribute lookups
|
|
17608
17725
|
// Reverse mapping from lowercase to camelCase for O(1) lookups
|
|
@@ -17653,14 +17770,14 @@ var NormalComponent = class extends PrimitiveComponent2 {
|
|
|
17653
17770
|
super(filteredProps);
|
|
17654
17771
|
if (filteredProps.pinLabels && !Array.isArray(filteredProps.pinLabels)) {
|
|
17655
17772
|
const invalidPinKey = Object.keys(filteredProps.pinLabels).find(
|
|
17656
|
-
(pinKey) => getPinNumberFromPinLabelsKey(pinKey) === null
|
|
17773
|
+
(pinKey) => getPinNumberFromPinLabelsKey(pinKey) === null && !isPhysicalPinName(pinKey)
|
|
17657
17774
|
);
|
|
17658
17775
|
if (invalidPinKey) {
|
|
17659
17776
|
throw new InvalidProps(this.lowercaseComponentName, this.props, {
|
|
17660
17777
|
_errors: [],
|
|
17661
17778
|
pinLabels: {
|
|
17662
17779
|
_errors: [
|
|
17663
|
-
`Invalid pinLabels key "${invalidPinKey}". Expected "pin\${number}" (e.g. pin1, pin2).`
|
|
17780
|
+
`Invalid pinLabels key "${invalidPinKey}". Expected "pin\${number}" (e.g. pin1, pin2) or a physical ball name (e.g. A1).`
|
|
17664
17781
|
]
|
|
17665
17782
|
}
|
|
17666
17783
|
});
|
|
@@ -17720,7 +17837,7 @@ var NormalComponent = class extends PrimitiveComponent2 {
|
|
|
17720
17837
|
const propsPinLabels = this._parsedProps.pinLabels;
|
|
17721
17838
|
const pinLabelsFromProps = propsPinLabels && Array.isArray(propsPinLabels) ? Object.fromEntries(
|
|
17722
17839
|
propsPinLabels.map((label, index2) => [`pin${index2 + 1}`, label])
|
|
17723
|
-
) : propsPinLabels;
|
|
17840
|
+
) : propsPinLabels ? getNumericPinLabels(propsPinLabels) : void 0;
|
|
17724
17841
|
const existingChildPorts = this._getAllPortsFromChildren();
|
|
17725
17842
|
const hasExistingOrQueuedPortWithPinNumber = (pinNumber) => existingChildPorts.some((p2) => p2._parsedProps.pinNumber === pinNumber) || portsToCreate.some((p2) => p2._parsedProps.pinNumber === pinNumber);
|
|
17726
17843
|
const schPortArrangement = this._getSchematicPortArrangement();
|
|
@@ -17774,7 +17891,7 @@ var NormalComponent = class extends PrimitiveComponent2 {
|
|
|
17774
17891
|
const pinNumber = getPinNumberFromPinLabelsKey(pinKey);
|
|
17775
17892
|
if (pinNumber === null) {
|
|
17776
17893
|
throw new Error(
|
|
17777
|
-
`Invalid pinLabels key "${pinKey}". Expected "pin\${number}" (e.g. pin1, pin2).`
|
|
17894
|
+
`Invalid pinLabels key "${pinKey}". Expected "pin\${number}" (e.g. pin1, pin2) or a physical ball name (e.g. A1).`
|
|
17778
17895
|
);
|
|
17779
17896
|
}
|
|
17780
17897
|
let existingPort = existingChildPorts.find(
|
|
@@ -17783,8 +17900,9 @@ var NormalComponent = class extends PrimitiveComponent2 {
|
|
|
17783
17900
|
const labelList = Array.isArray(label) ? label : [label];
|
|
17784
17901
|
const propLabel = pinLabelsFromProps?.[pinKey];
|
|
17785
17902
|
const hasPropLabel = propLabel !== void 0;
|
|
17786
|
-
const
|
|
17787
|
-
const
|
|
17903
|
+
const physicalPinName = this._getPhysicalPinName(pinNumber);
|
|
17904
|
+
const primaryLabel = physicalPinName ?? (hasPropLabel ? labelList[0] : `pin${pinNumber}`);
|
|
17905
|
+
const otherLabels = physicalPinName ? labelList : hasPropLabel ? labelList.slice(1) : labelList;
|
|
17788
17906
|
if (!existingPort) {
|
|
17789
17907
|
existingPort = new Port(
|
|
17790
17908
|
{
|
|
@@ -17804,6 +17922,7 @@ var NormalComponent = class extends PrimitiveComponent2 {
|
|
|
17804
17922
|
} else {
|
|
17805
17923
|
existingPort.externallyAddedAliases.push(primaryLabel, ...otherLabels);
|
|
17806
17924
|
}
|
|
17925
|
+
existingPort.physicalPinName = physicalPinName;
|
|
17807
17926
|
}
|
|
17808
17927
|
}
|
|
17809
17928
|
if (config.schematicSymbolName && !opts.ignoreSymbolPorts) {
|
|
@@ -17935,7 +18054,11 @@ var NormalComponent = class extends PrimitiveComponent2 {
|
|
|
17935
18054
|
}
|
|
17936
18055
|
inferInternallyConnectedPinNamesFromPorts(
|
|
17937
18056
|
Array.from(
|
|
17938
|
-
|
|
18057
|
+
new Set(
|
|
18058
|
+
[...this._getAllPortsFromChildren(), ...portsToCreate].filter(
|
|
18059
|
+
(port) => !port.physicalPinName
|
|
18060
|
+
)
|
|
18061
|
+
)
|
|
17939
18062
|
),
|
|
17940
18063
|
this._inferredInternallyConnectedPinNames
|
|
17941
18064
|
);
|
|
@@ -17947,7 +18070,7 @@ var NormalComponent = class extends PrimitiveComponent2 {
|
|
|
17947
18070
|
const pinLabels = this._parsedProps.pinLabels;
|
|
17948
18071
|
const parsedPinLabels = pinLabels && Array.isArray(pinLabels) ? Object.fromEntries(
|
|
17949
18072
|
pinLabels.map((label, index2) => [`pin${index2 + 1}`, label])
|
|
17950
|
-
) : pinLabels;
|
|
18073
|
+
) : pinLabels ? getNumericPinLabels(pinLabels) : void 0;
|
|
17951
18074
|
const resolvedPinLabels = {
|
|
17952
18075
|
...this._impliedFootprintPinLabels ?? {},
|
|
17953
18076
|
...parsedPinLabels ?? {}
|
|
@@ -17955,6 +18078,14 @@ var NormalComponent = class extends PrimitiveComponent2 {
|
|
|
17955
18078
|
if (Object.keys(resolvedPinLabels).length === 0) return void 0;
|
|
17956
18079
|
return resolvedPinLabels;
|
|
17957
18080
|
}
|
|
18081
|
+
_resolvedPackagePins;
|
|
18082
|
+
/** Physical package name, separate from the internal schematic ordinal. */
|
|
18083
|
+
_getPhysicalPinName(pinNumber) {
|
|
18084
|
+
const pinLabels = this._parsedProps?.pinLabels ?? this.props.pinLabels;
|
|
18085
|
+
if (!pinLabels || Array.isArray(pinLabels)) return void 0;
|
|
18086
|
+
this._resolvedPackagePins ??= resolvePinLabels(pinLabels);
|
|
18087
|
+
return this._resolvedPackagePins.find((pin) => pin.pinNumber === pinNumber)?.physicalPinName;
|
|
18088
|
+
}
|
|
17958
18089
|
_getImpliedFootprintString() {
|
|
17959
18090
|
return null;
|
|
17960
18091
|
}
|
|
@@ -18634,8 +18765,12 @@ var NormalComponent = class extends PrimitiveComponent2 {
|
|
|
18634
18765
|
if (opts?.collectInferredInternallyConnectedPins) {
|
|
18635
18766
|
inferredInternallyConnectedPinNames = this._inferredInternallyConnectedPinNames;
|
|
18636
18767
|
}
|
|
18768
|
+
const physicalPinLabels = this._parsedProps?.pinLabels ?? this.props.pinLabels;
|
|
18769
|
+
const hasPhysicalPins = physicalPinLabels && !Array.isArray(physicalPinLabels) && Object.keys(physicalPinLabels).some(isPhysicalPinName);
|
|
18637
18770
|
const implicitPinNumberByHint = /* @__PURE__ */ new Map();
|
|
18638
|
-
const
|
|
18771
|
+
const ambiguousHints = /* @__PURE__ */ new Set();
|
|
18772
|
+
const rawExplicitPinLabels = this._parsedProps?.pinLabels ?? this.props.pinLabels;
|
|
18773
|
+
const explicitPinLabels = rawExplicitPinLabels && !Array.isArray(rawExplicitPinLabels) ? getNumericPinLabels(rawExplicitPinLabels) : rawExplicitPinLabels;
|
|
18639
18774
|
if (explicitPinLabels) {
|
|
18640
18775
|
const pinLabelEntries = Array.isArray(explicitPinLabels) ? explicitPinLabels.map((label, index2) => [`pin${index2 + 1}`, label]) : Object.entries(explicitPinLabels);
|
|
18641
18776
|
for (const [pinKey, labelOrLabels] of pinLabelEntries) {
|
|
@@ -18644,13 +18779,20 @@ var NormalComponent = class extends PrimitiveComponent2 {
|
|
|
18644
18779
|
const labels = Array.isArray(labelOrLabels) ? labelOrLabels : [labelOrLabels];
|
|
18645
18780
|
for (const label of labels) {
|
|
18646
18781
|
if (typeof label === "string" && label.length > 0) {
|
|
18782
|
+
const previousPinNumber = implicitPinNumberByHint.get(label);
|
|
18783
|
+
if (hasPhysicalPins && previousPinNumber !== void 0 && previousPinNumber !== pinNumber) {
|
|
18784
|
+
ambiguousHints.add(label);
|
|
18785
|
+
}
|
|
18647
18786
|
implicitPinNumberByHint.set(label, pinNumber);
|
|
18648
18787
|
}
|
|
18649
18788
|
}
|
|
18650
18789
|
}
|
|
18651
18790
|
}
|
|
18791
|
+
for (const hint of ambiguousHints) implicitPinNumberByHint.delete(hint);
|
|
18652
18792
|
const primaryPortOpts = {
|
|
18653
18793
|
...opts,
|
|
18794
|
+
inferSharedAliases: !hasPhysicalPins,
|
|
18795
|
+
getPhysicalPinName: (pinNumber) => this._getPhysicalPinName(pinNumber),
|
|
18654
18796
|
inferredInternallyConnectedPinNames,
|
|
18655
18797
|
implicitPinNumberByHint
|
|
18656
18798
|
};
|
|
@@ -18896,19 +19038,24 @@ var NormalComponent = class extends PrimitiveComponent2 {
|
|
|
18896
19038
|
`pin${pinIndex + 1}`,
|
|
18897
19039
|
label
|
|
18898
19040
|
])
|
|
18899
|
-
) : props.pinLabels;
|
|
19041
|
+
) : props.pinLabels ? getNumericPinLabels(props.pinLabels) : void 0;
|
|
18900
19042
|
const allPinLabels = {
|
|
18901
19043
|
...pinLabelsFromPorts,
|
|
18902
19044
|
...pinLabelsFromProps
|
|
18903
19045
|
};
|
|
18904
19046
|
const schPortArrangement = this._getSchematicPortArrangement() ?? this._getImplicitSparseSchematicPortArrangement(pinCount);
|
|
19047
|
+
if (props.pinLabels && !Array.isArray(props.pinLabels) && Object.keys(props.pinLabels).some(isPhysicalPinName) && schPortArrangement) {
|
|
19048
|
+
for (const pin of getPinsFromPortArrangement(schPortArrangement)) {
|
|
19049
|
+
parsePinNumberFromLabelsOrThrow(pin, props.pinLabels);
|
|
19050
|
+
}
|
|
19051
|
+
}
|
|
18905
19052
|
return getAllDimensionsForSchematicBox({
|
|
18906
19053
|
schWidth: props.schWidth,
|
|
18907
19054
|
schHeight: props.schHeight,
|
|
18908
19055
|
schPinSpacing: pinSpacing,
|
|
18909
19056
|
numericSchPinStyle: getNumericSchPinStyle(
|
|
18910
19057
|
props.schPinStyle,
|
|
18911
|
-
allPinLabels
|
|
19058
|
+
!Array.isArray(props.pinLabels) ? props.pinLabels ?? allPinLabels : allPinLabels
|
|
18912
19059
|
),
|
|
18913
19060
|
pinCount,
|
|
18914
19061
|
schPortArrangement,
|
|
@@ -110242,20 +110389,22 @@ function getTitleAnchorAndPosition({
|
|
|
110242
110389
|
// lib/components/primitive-components/SchematicBox/SchematicBox_doInitialSchematicComponentRender.ts
|
|
110243
110390
|
var getSchematicBoxPinLabels = (pinLabels) => {
|
|
110244
110391
|
if (!pinLabels) return [];
|
|
110245
|
-
return Object.entries(pinLabels).map(
|
|
110246
|
-
|
|
110247
|
-
|
|
110248
|
-
|
|
110249
|
-
|
|
110250
|
-
|
|
110392
|
+
return Object.entries(getNumericPinLabels(pinLabels)).map(
|
|
110393
|
+
([pinKey, pinLabel]) => {
|
|
110394
|
+
const pinNumber = getPinNumberFromPinLabelsKey(pinKey);
|
|
110395
|
+
if (pinNumber === null) {
|
|
110396
|
+
throw new Error(
|
|
110397
|
+
`Invalid schematicbox pinLabels key "${pinKey}". Expected pin<number>.`
|
|
110398
|
+
);
|
|
110399
|
+
}
|
|
110400
|
+
const pinAliases = typeof pinLabel === "string" ? [pinLabel] : [...pinLabel];
|
|
110401
|
+
return {
|
|
110402
|
+
pinNumber,
|
|
110403
|
+
displayPinLabel: pinAliases[0] ?? pinKey,
|
|
110404
|
+
pinAliases
|
|
110405
|
+
};
|
|
110251
110406
|
}
|
|
110252
|
-
|
|
110253
|
-
return {
|
|
110254
|
-
pinNumber,
|
|
110255
|
-
displayPinLabel: pinAliases[0] ?? pinKey,
|
|
110256
|
-
pinAliases
|
|
110257
|
-
};
|
|
110258
|
-
});
|
|
110407
|
+
);
|
|
110259
110408
|
};
|
|
110260
110409
|
var getSchematicBoxPinStyleFromReferencedChip = ({
|
|
110261
110410
|
referencedChip,
|
|
@@ -118543,7 +118692,7 @@ var RoutingPhasePreparationError = class extends Error {
|
|
|
118543
118692
|
var package_default = {
|
|
118544
118693
|
name: "@tscircuit/core",
|
|
118545
118694
|
type: "module",
|
|
118546
|
-
version: "0.0.
|
|
118695
|
+
version: "0.0.2146",
|
|
118547
118696
|
types: "dist/index.d.ts",
|
|
118548
118697
|
main: "dist/index.js",
|
|
118549
118698
|
module: "dist/index.js",
|
|
@@ -118602,7 +118751,7 @@ var package_default = {
|
|
|
118602
118751
|
"@tscircuit/miniflex": "^0.0.4",
|
|
118603
118752
|
"@tscircuit/modelprinter": "^0.0.18",
|
|
118604
118753
|
"@tscircuit/ngspice-spice-engine": "^0.0.20",
|
|
118605
|
-
"@tscircuit/props": "^0.0.
|
|
118754
|
+
"@tscircuit/props": "^0.0.701",
|
|
118606
118755
|
"@tscircuit/schematic-match-adapt": "^0.0.18",
|
|
118607
118756
|
"@tscircuit/schematic-trace-solver": "https://jscdn.tscircuit.com/@tscircuit/schematic-trace-solver/0.0.230.tgz",
|
|
118608
118757
|
"@tscircuit/solver-utils": "^0.0.16",
|
|
@@ -118686,7 +118835,7 @@ var package_default = {
|
|
|
118686
118835
|
},
|
|
118687
118836
|
overrides: {
|
|
118688
118837
|
"@tscircuit/circuit-json-util": "^0.0.121",
|
|
118689
|
-
"@tscircuit/props": "^0.0.
|
|
118838
|
+
"@tscircuit/props": "^0.0.701",
|
|
118690
118839
|
"circuit-json": "^0.0.525",
|
|
118691
118840
|
"@tscircuit/cableprinter": "^0.0.6"
|
|
118692
118841
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tscircuit/core",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.2147",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"module": "dist/index.js",
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"@tscircuit/miniflex": "^0.0.4",
|
|
61
61
|
"@tscircuit/modelprinter": "^0.0.18",
|
|
62
62
|
"@tscircuit/ngspice-spice-engine": "^0.0.20",
|
|
63
|
-
"@tscircuit/props": "^0.0.
|
|
63
|
+
"@tscircuit/props": "^0.0.701",
|
|
64
64
|
"@tscircuit/schematic-match-adapt": "^0.0.18",
|
|
65
65
|
"@tscircuit/schematic-trace-solver": "https://jscdn.tscircuit.com/@tscircuit/schematic-trace-solver/0.0.230.tgz",
|
|
66
66
|
"@tscircuit/solver-utils": "^0.0.16",
|
|
@@ -144,7 +144,7 @@
|
|
|
144
144
|
},
|
|
145
145
|
"overrides": {
|
|
146
146
|
"@tscircuit/circuit-json-util": "^0.0.121",
|
|
147
|
-
"@tscircuit/props": "^0.0.
|
|
147
|
+
"@tscircuit/props": "^0.0.701",
|
|
148
148
|
"circuit-json": "^0.0.525",
|
|
149
149
|
"@tscircuit/cableprinter": "^0.0.6"
|
|
150
150
|
}
|