@tscircuit/core 0.0.1306 → 0.0.1308
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1548 -1522
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9170,1617 +9170,1647 @@ var SmtPad = class extends PrimitiveComponent2 {
|
|
|
9170
9170
|
}
|
|
9171
9171
|
};
|
|
9172
9172
|
|
|
9173
|
-
// lib/
|
|
9174
|
-
|
|
9175
|
-
|
|
9176
|
-
|
|
9177
|
-
|
|
9178
|
-
|
|
9179
|
-
|
|
9180
|
-
|
|
9173
|
+
// lib/utils/get-relative-direction.ts
|
|
9174
|
+
function getRelativeDirection(pointA, pointB) {
|
|
9175
|
+
const dx = pointB.x - pointA.x;
|
|
9176
|
+
const dy = pointB.y - pointA.y;
|
|
9177
|
+
if (Math.abs(dx) > Math.abs(dy)) {
|
|
9178
|
+
return dx >= 0 ? "right" : "left";
|
|
9179
|
+
}
|
|
9180
|
+
return dy >= 0 ? "up" : "down";
|
|
9181
|
+
}
|
|
9182
|
+
|
|
9183
|
+
// lib/components/primitive-components/Port/Port.ts
|
|
9184
|
+
import "schematic-symbols";
|
|
9185
|
+
import { applyToPoint as applyToPoint22, compose as compose3, translate as translate2 } from "transformation-matrix";
|
|
9186
|
+
import "zod";
|
|
9187
|
+
|
|
9188
|
+
// lib/components/primitive-components/Port/getCenterOfPcbPrimitives.ts
|
|
9189
|
+
var getCenterOfPcbPrimitives = (pcbPrimitives) => {
|
|
9190
|
+
if (pcbPrimitives.length === 0) {
|
|
9191
|
+
throw new Error("Cannot get center of empty PCB primitives array");
|
|
9192
|
+
}
|
|
9193
|
+
const positions = pcbPrimitives.map((p) => p._getPcbCircuitJsonBounds().center).filter(Boolean);
|
|
9194
|
+
const sumX = positions.reduce((sum, pos) => sum + pos.x, 0);
|
|
9195
|
+
const sumY = positions.reduce((sum, pos) => sum + pos.y, 0);
|
|
9196
|
+
return {
|
|
9197
|
+
x: sumX / positions.length,
|
|
9198
|
+
y: sumY / positions.length
|
|
9199
|
+
};
|
|
9200
|
+
};
|
|
9201
|
+
|
|
9202
|
+
// lib/components/primitive-components/Port/Port.ts
|
|
9203
|
+
import { portProps } from "@tscircuit/props";
|
|
9204
|
+
|
|
9205
|
+
// lib/components/primitive-components/Port/apply-pin-attributes-to-source-port.ts
|
|
9206
|
+
var applyPinAttributesToSourcePort = (sourcePortProps, attributes) => {
|
|
9207
|
+
if (attributes.mustBeConnected !== void 0) {
|
|
9208
|
+
sourcePortProps.must_be_connected = attributes.mustBeConnected;
|
|
9209
|
+
}
|
|
9210
|
+
if (attributes.providesPower !== void 0) {
|
|
9211
|
+
sourcePortProps.provides_power = attributes.providesPower;
|
|
9212
|
+
}
|
|
9213
|
+
if (attributes.requiresPower !== void 0) {
|
|
9214
|
+
sourcePortProps.requires_power = attributes.requiresPower;
|
|
9215
|
+
}
|
|
9216
|
+
if (attributes.providesGround !== void 0) {
|
|
9217
|
+
sourcePortProps.provides_ground = attributes.providesGround;
|
|
9218
|
+
}
|
|
9219
|
+
if (attributes.requiresGround !== void 0) {
|
|
9220
|
+
sourcePortProps.requires_ground = attributes.requiresGround;
|
|
9221
|
+
}
|
|
9222
|
+
if (attributes.providesVoltage !== void 0) {
|
|
9223
|
+
sourcePortProps.provides_voltage = attributes.providesVoltage;
|
|
9224
|
+
}
|
|
9225
|
+
if (attributes.requiresVoltage !== void 0) {
|
|
9226
|
+
sourcePortProps.requires_voltage = attributes.requiresVoltage;
|
|
9227
|
+
}
|
|
9228
|
+
if (attributes.doNotConnect !== void 0) {
|
|
9229
|
+
sourcePortProps.do_not_connect = attributes.doNotConnect;
|
|
9230
|
+
}
|
|
9231
|
+
if (attributes.includeInBoardPinout !== void 0) {
|
|
9232
|
+
sourcePortProps.include_in_board_pinout = attributes.includeInBoardPinout;
|
|
9233
|
+
}
|
|
9234
|
+
if (attributes.canUseInternalPullup !== void 0) {
|
|
9235
|
+
sourcePortProps.can_use_internal_pullup = attributes.canUseInternalPullup;
|
|
9236
|
+
}
|
|
9237
|
+
if (attributes.isUsingInternalPullup !== void 0) {
|
|
9238
|
+
sourcePortProps.is_using_internal_pullup = attributes.isUsingInternalPullup;
|
|
9239
|
+
}
|
|
9240
|
+
if (attributes.needsExternalPullup !== void 0) {
|
|
9241
|
+
sourcePortProps.needs_external_pullup = attributes.needsExternalPullup;
|
|
9242
|
+
}
|
|
9243
|
+
if (attributes.canUseInternalPulldown !== void 0) {
|
|
9244
|
+
sourcePortProps.can_use_internal_pulldown = attributes.canUseInternalPulldown;
|
|
9245
|
+
}
|
|
9246
|
+
if (attributes.isUsingInternalPulldown !== void 0) {
|
|
9247
|
+
sourcePortProps.is_using_internal_pulldown = attributes.isUsingInternalPulldown;
|
|
9248
|
+
}
|
|
9249
|
+
if (attributes.needsExternalPulldown !== void 0) {
|
|
9250
|
+
sourcePortProps.needs_external_pulldown = attributes.needsExternalPulldown;
|
|
9251
|
+
}
|
|
9252
|
+
if (attributes.canUseOpenDrain !== void 0) {
|
|
9253
|
+
sourcePortProps.can_use_open_drain = attributes.canUseOpenDrain;
|
|
9254
|
+
}
|
|
9255
|
+
if (attributes.isUsingOpenDrain !== void 0) {
|
|
9256
|
+
sourcePortProps.is_using_open_drain = attributes.isUsingOpenDrain;
|
|
9257
|
+
}
|
|
9258
|
+
if (attributes.canUsePushPull !== void 0) {
|
|
9259
|
+
sourcePortProps.can_use_push_pull = attributes.canUsePushPull;
|
|
9260
|
+
}
|
|
9261
|
+
if (attributes.isUsingPushPull !== void 0) {
|
|
9262
|
+
sourcePortProps.is_using_push_pull = attributes.isUsingPushPull;
|
|
9263
|
+
}
|
|
9264
|
+
if (attributes.shouldHaveDecouplingCapacitor !== void 0) {
|
|
9265
|
+
sourcePortProps.should_have_decoupling_capacitor = attributes.shouldHaveDecouplingCapacitor;
|
|
9266
|
+
}
|
|
9267
|
+
if (attributes.recommendedDecouplingCapacitorCapacitance !== void 0) {
|
|
9268
|
+
sourcePortProps.recommended_decoupling_capacitor_capacitance = attributes.recommendedDecouplingCapacitorCapacitance;
|
|
9269
|
+
}
|
|
9270
|
+
};
|
|
9271
|
+
|
|
9272
|
+
// lib/components/primitive-components/Port/Port.ts
|
|
9273
|
+
var Port = class extends PrimitiveComponent2 {
|
|
9274
|
+
source_port_id = null;
|
|
9275
|
+
pcb_port_id = null;
|
|
9276
|
+
schematic_port_id = null;
|
|
9277
|
+
schematic_stem_line_id = null;
|
|
9278
|
+
schematicSymbolPortDef = null;
|
|
9279
|
+
matchedComponents;
|
|
9280
|
+
_isPrimaryPort = true;
|
|
9281
|
+
_primaryPinNumber = null;
|
|
9282
|
+
facingDirection = null;
|
|
9283
|
+
originDescription = null;
|
|
9181
9284
|
get config() {
|
|
9182
9285
|
return {
|
|
9183
|
-
componentName: "
|
|
9184
|
-
zodProps:
|
|
9286
|
+
componentName: "Port",
|
|
9287
|
+
zodProps: portProps
|
|
9185
9288
|
};
|
|
9186
9289
|
}
|
|
9187
|
-
|
|
9188
|
-
|
|
9189
|
-
|
|
9290
|
+
constructor(props, opts = {}) {
|
|
9291
|
+
if (!props.name && props.pinNumber !== void 0)
|
|
9292
|
+
props.name = `pin${props.pinNumber}`;
|
|
9293
|
+
if (!props.name) {
|
|
9294
|
+
throw new Error("Port must have a name or a pinNumber");
|
|
9295
|
+
}
|
|
9296
|
+
super(props);
|
|
9297
|
+
if (opts.originDescription) {
|
|
9298
|
+
this.originDescription = opts.originDescription;
|
|
9299
|
+
}
|
|
9300
|
+
this.matchedComponents = [];
|
|
9190
9301
|
}
|
|
9191
|
-
|
|
9192
|
-
|
|
9193
|
-
|
|
9194
|
-
|
|
9195
|
-
|
|
9196
|
-
|
|
9197
|
-
|
|
9198
|
-
const { db } = this.root;
|
|
9302
|
+
isGroupPort() {
|
|
9303
|
+
return this.parent?.componentName === "Group";
|
|
9304
|
+
}
|
|
9305
|
+
isComponentPort() {
|
|
9306
|
+
return !this.isGroupPort();
|
|
9307
|
+
}
|
|
9308
|
+
_getConnectedPortsFromConnectsTo() {
|
|
9199
9309
|
const { _parsedProps: props } = this;
|
|
9200
|
-
const
|
|
9201
|
-
|
|
9202
|
-
const
|
|
9203
|
-
|
|
9204
|
-
|
|
9205
|
-
|
|
9206
|
-
|
|
9310
|
+
const connectsTo = props.connectsTo;
|
|
9311
|
+
if (!connectsTo) return [];
|
|
9312
|
+
const connectedPorts = [];
|
|
9313
|
+
const connectsToArray = Array.isArray(connectsTo) ? connectsTo : [connectsTo];
|
|
9314
|
+
for (const connection of connectsToArray) {
|
|
9315
|
+
const port = this.getSubcircuit().selectOne(connection, {
|
|
9316
|
+
type: "port"
|
|
9317
|
+
});
|
|
9318
|
+
if (port) {
|
|
9319
|
+
connectedPorts.push(port);
|
|
9320
|
+
}
|
|
9321
|
+
}
|
|
9322
|
+
return connectedPorts;
|
|
9207
9323
|
}
|
|
9208
|
-
|
|
9209
|
-
|
|
9210
|
-
|
|
9324
|
+
_isBoardPinoutFromAttributes() {
|
|
9325
|
+
const parent = this.parent;
|
|
9326
|
+
if (parent?._parsedProps?.pinAttributes) {
|
|
9327
|
+
const pinAttributes = parent._parsedProps.pinAttributes;
|
|
9328
|
+
for (const alias of this.getNameAndAliases()) {
|
|
9329
|
+
if (pinAttributes[alias]?.includeInBoardPinout) {
|
|
9330
|
+
return true;
|
|
9331
|
+
}
|
|
9332
|
+
}
|
|
9211
9333
|
}
|
|
9212
|
-
this._computeSchematicSymbolBounds();
|
|
9213
|
-
return this.schematicSymbolBoundsInUserCoordinates ?? null;
|
|
9214
9334
|
}
|
|
9215
|
-
|
|
9216
|
-
|
|
9217
|
-
|
|
9335
|
+
_getGlobalPcbPositionBeforeLayout() {
|
|
9336
|
+
const matchedPcbElm = this.matchedComponents.find((c) => c.isPcbPrimitive);
|
|
9337
|
+
const parentComponent = this.parent;
|
|
9338
|
+
if (parentComponent && !parentComponent.props.footprint) {
|
|
9339
|
+
throw new Error(
|
|
9340
|
+
`${parentComponent.componentName} "${parentComponent.props.name}" does not have a footprint. Add a footprint prop, e.g. <${parentComponent.componentName.toLowerCase()} footprint="..." />`
|
|
9341
|
+
);
|
|
9218
9342
|
}
|
|
9219
|
-
if (
|
|
9220
|
-
|
|
9343
|
+
if (!matchedPcbElm) {
|
|
9344
|
+
throw new Error(
|
|
9345
|
+
`Port ${this} has no matching PCB primitives. This often means the footprint's pads lack matching port hints.`
|
|
9346
|
+
);
|
|
9221
9347
|
}
|
|
9222
|
-
|
|
9223
|
-
return this.userCoordinateToResizedSymbolTransformMat ?? null;
|
|
9348
|
+
return matchedPcbElm?._getGlobalPcbPositionBeforeLayout() ?? { x: 0, y: 0 };
|
|
9224
9349
|
}
|
|
9225
|
-
|
|
9226
|
-
if (this.
|
|
9350
|
+
_getPcbCircuitJsonBounds() {
|
|
9351
|
+
if (!this.pcb_port_id) {
|
|
9352
|
+
return super._getPcbCircuitJsonBounds();
|
|
9353
|
+
}
|
|
9227
9354
|
const { db } = this.root;
|
|
9228
|
-
const
|
|
9229
|
-
|
|
9230
|
-
|
|
9231
|
-
|
|
9232
|
-
|
|
9233
|
-
|
|
9234
|
-
|
|
9235
|
-
|
|
9236
|
-
|
|
9355
|
+
const pcb_port = db.pcb_port.get(this.pcb_port_id);
|
|
9356
|
+
return {
|
|
9357
|
+
center: { x: pcb_port.x, y: pcb_port.y },
|
|
9358
|
+
bounds: { left: 0, top: 0, right: 0, bottom: 0 },
|
|
9359
|
+
width: 0,
|
|
9360
|
+
height: 0
|
|
9361
|
+
};
|
|
9362
|
+
}
|
|
9363
|
+
_getGlobalPcbPositionAfterLayout() {
|
|
9364
|
+
return this._getPcbCircuitJsonBounds().center;
|
|
9365
|
+
}
|
|
9366
|
+
_getPortsInternallyConnectedToThisPort() {
|
|
9367
|
+
const parent = this.parent;
|
|
9368
|
+
if (!parent || !parent._getInternallyConnectedPins) return [];
|
|
9369
|
+
const internallyConnectedPorts = parent._getInternallyConnectedPins();
|
|
9370
|
+
for (const ports of internallyConnectedPorts) {
|
|
9371
|
+
if (ports.some((port) => port === this)) {
|
|
9372
|
+
return ports;
|
|
9237
9373
|
}
|
|
9238
|
-
|
|
9239
|
-
|
|
9240
|
-
|
|
9241
|
-
|
|
9242
|
-
|
|
9243
|
-
|
|
9244
|
-
|
|
9245
|
-
|
|
9246
|
-
|
|
9247
|
-
|
|
9248
|
-
|
|
9249
|
-
|
|
9250
|
-
|
|
9251
|
-
|
|
9252
|
-
|
|
9253
|
-
|
|
9254
|
-
|
|
9255
|
-
|
|
9256
|
-
|
|
9257
|
-
|
|
9258
|
-
|
|
9259
|
-
|
|
9260
|
-
|
|
9261
|
-
|
|
9262
|
-
|
|
9374
|
+
}
|
|
9375
|
+
return [];
|
|
9376
|
+
}
|
|
9377
|
+
/**
|
|
9378
|
+
* Return true if this port has a schematic representation and can be rendered
|
|
9379
|
+
* to the schematic.
|
|
9380
|
+
*
|
|
9381
|
+
* Sometimes things like mounting holes don't have a schematic representation
|
|
9382
|
+
* and aren't rendered to the schematic.
|
|
9383
|
+
*
|
|
9384
|
+
* It's common for a schematic symbol to not have a representation for all of
|
|
9385
|
+
* the pins on a footprint, e.g. a pushbutton has 4 pins but is typically
|
|
9386
|
+
* represented by a two-pin symbol. In these cases, it's best to use
|
|
9387
|
+
* internallyConnectedPorts or externallyConnectedPorts to ensure the things
|
|
9388
|
+
* are rendered properly.
|
|
9389
|
+
*/
|
|
9390
|
+
_hasSchematicPort() {
|
|
9391
|
+
const { schX, schY } = this._parsedProps;
|
|
9392
|
+
if (schX !== void 0 && schY !== void 0) {
|
|
9393
|
+
return true;
|
|
9394
|
+
}
|
|
9395
|
+
const parentNormalComponent = this.getParentNormalComponent();
|
|
9396
|
+
const symbol = parentNormalComponent?.getSchematicSymbol();
|
|
9397
|
+
if (symbol) {
|
|
9398
|
+
if (this.schematicSymbolPortDef) return true;
|
|
9399
|
+
const portsInternallyConnectedToThisPort = this._getPortsInternallyConnectedToThisPort();
|
|
9400
|
+
if (portsInternallyConnectedToThisPort.some((p) => p.schematicSymbolPortDef))
|
|
9401
|
+
return true;
|
|
9402
|
+
return false;
|
|
9403
|
+
}
|
|
9404
|
+
const parentBoxDim = parentNormalComponent?._getSchematicBoxDimensions();
|
|
9405
|
+
if (parentBoxDim && this._parsedProps.pinNumber !== void 0) {
|
|
9406
|
+
const localPortPosition = parentBoxDim.getPortPositionByPinNumber(
|
|
9407
|
+
this._parsedProps.pinNumber
|
|
9408
|
+
);
|
|
9409
|
+
if (localPortPosition) return true;
|
|
9410
|
+
}
|
|
9411
|
+
return false;
|
|
9412
|
+
}
|
|
9413
|
+
_getGlobalSchematicPositionBeforeLayout() {
|
|
9414
|
+
const { schX, schY } = this._parsedProps;
|
|
9415
|
+
if (schX !== void 0 && schY !== void 0) {
|
|
9416
|
+
return { x: schX, y: schY };
|
|
9417
|
+
}
|
|
9418
|
+
const parentNormalComponent = this.getParentNormalComponent();
|
|
9419
|
+
const symbol = parentNormalComponent?.getSchematicSymbol();
|
|
9420
|
+
if (symbol) {
|
|
9421
|
+
let schematicSymbolPortDef = this.schematicSymbolPortDef;
|
|
9422
|
+
if (!schematicSymbolPortDef) {
|
|
9423
|
+
schematicSymbolPortDef = this._getPortsInternallyConnectedToThisPort().find(
|
|
9424
|
+
(p) => p.schematicSymbolPortDef
|
|
9425
|
+
)?.schematicSymbolPortDef ?? null;
|
|
9426
|
+
if (!schematicSymbolPortDef) {
|
|
9427
|
+
throw new Error(
|
|
9428
|
+
`Couldn't find schematicSymbolPortDef for port ${this.getString()}, searched internally connected ports and none had a schematicSymbolPortDef. Why are we trying to get the schematic position of this port?`
|
|
9429
|
+
);
|
|
9263
9430
|
}
|
|
9264
9431
|
}
|
|
9432
|
+
const transform = compose3(
|
|
9433
|
+
parentNormalComponent.computeSchematicGlobalTransform(),
|
|
9434
|
+
translate2(-symbol.center.x, -symbol.center.y)
|
|
9435
|
+
);
|
|
9436
|
+
return applyToPoint22(transform, schematicSymbolPortDef);
|
|
9437
|
+
}
|
|
9438
|
+
const parentBoxDim = parentNormalComponent?._getSchematicBoxDimensions();
|
|
9439
|
+
if (parentBoxDim && this._parsedProps.pinNumber !== void 0) {
|
|
9440
|
+
const localPortPosition = parentBoxDim.getPortPositionByPinNumber(
|
|
9441
|
+
this._parsedProps.pinNumber
|
|
9442
|
+
);
|
|
9443
|
+
if (!localPortPosition) {
|
|
9444
|
+
throw new Error(
|
|
9445
|
+
`Couldn't find position for schematic_port for port ${this.getString()} inside of the schematic box`
|
|
9446
|
+
);
|
|
9447
|
+
}
|
|
9448
|
+
return applyToPoint22(
|
|
9449
|
+
parentNormalComponent.computeSchematicGlobalTransform(),
|
|
9450
|
+
localPortPosition
|
|
9451
|
+
);
|
|
9265
9452
|
}
|
|
9266
|
-
|
|
9267
|
-
|
|
9268
|
-
this.schematicSymbolBoundsInUserCoordinates = bounds;
|
|
9269
|
-
}
|
|
9270
|
-
_computeUserCoordinateToResizedSymbolTransform() {
|
|
9271
|
-
const bounds = this.getSchematicSymbolBounds();
|
|
9272
|
-
if (!bounds) return;
|
|
9273
|
-
const { _parsedProps: props } = this;
|
|
9274
|
-
const targetWidth = props.width;
|
|
9275
|
-
const targetHeight = props.height;
|
|
9276
|
-
if (targetWidth === void 0 && targetHeight === void 0) return;
|
|
9277
|
-
const currentWidth = bounds.maxX - bounds.minX;
|
|
9278
|
-
const currentHeight = bounds.maxY - bounds.minY;
|
|
9279
|
-
if (currentWidth === 0 && currentHeight === 0) return;
|
|
9280
|
-
const currentCenterX = (bounds.minX + bounds.maxX) / 2;
|
|
9281
|
-
const currentCenterY = (bounds.minY + bounds.maxY) / 2;
|
|
9282
|
-
const scaleX = targetWidth !== void 0 && currentWidth > 0 ? targetWidth / currentWidth : 1;
|
|
9283
|
-
const scaleY = targetHeight !== void 0 && currentHeight > 0 ? targetHeight / currentHeight : 1;
|
|
9284
|
-
const globalPos = this._getGlobalSchematicPositionBeforeLayout();
|
|
9285
|
-
this.userCoordinateToResizedSymbolTransformMat = compose3(
|
|
9286
|
-
translate2(globalPos.x, globalPos.y),
|
|
9287
|
-
scale(scaleX, scaleY),
|
|
9288
|
-
translate2(-currentCenterX, -currentCenterY)
|
|
9453
|
+
throw new Error(
|
|
9454
|
+
`Couldn't find position for schematic_port for port ${this.getString()}`
|
|
9289
9455
|
);
|
|
9290
9456
|
}
|
|
9291
|
-
|
|
9292
|
-
|
|
9293
|
-
|
|
9294
|
-
|
|
9295
|
-
|
|
9296
|
-
|
|
9297
|
-
|
|
9298
|
-
|
|
9299
|
-
|
|
9300
|
-
|
|
9301
|
-
|
|
9302
|
-
|
|
9303
|
-
|
|
9304
|
-
const index = parseInt(pinNum.replace(/[^\d]/g, ""), 10) - 1;
|
|
9305
|
-
label = String(pinLabels[index] ?? pinNum);
|
|
9306
|
-
} else if (typeof pinLabels === "object") {
|
|
9307
|
-
label = String(pinLabels[pinNum] ?? pinNum);
|
|
9308
|
-
}
|
|
9309
|
-
const silkscreenText = new SilkscreenText({
|
|
9310
|
-
anchorAlignment: anchorAlignment || "center",
|
|
9311
|
-
text: label ?? pinNum,
|
|
9312
|
-
layer: layer || "top",
|
|
9313
|
-
pcbX: isNaN(elm.anchor_position.x) ? 0 : elm.anchor_position.x,
|
|
9314
|
-
pcbY: elm.anchor_position.y,
|
|
9315
|
-
pcbRotation: readableRotation ?? 0
|
|
9316
|
-
});
|
|
9317
|
-
silkscreenText._footprinterFontSize = elm.font_size + 0.2;
|
|
9318
|
-
return silkscreenText;
|
|
9319
|
-
};
|
|
9320
|
-
|
|
9321
|
-
// lib/utils/createComponentsFromCircuitJson.ts
|
|
9322
|
-
var calculateCcwRotation = (componentRotationStr, elementCcwRotation) => {
|
|
9323
|
-
const componentAngle = parseInt(componentRotationStr || "0", 10);
|
|
9324
|
-
let totalRotation;
|
|
9325
|
-
if (elementCcwRotation !== void 0 && elementCcwRotation !== null) {
|
|
9326
|
-
totalRotation = elementCcwRotation - componentAngle;
|
|
9327
|
-
} else {
|
|
9328
|
-
totalRotation = componentAngle;
|
|
9457
|
+
_getGlobalSchematicPositionAfterLayout() {
|
|
9458
|
+
const { db } = this.root;
|
|
9459
|
+
if (!this.schematic_port_id) {
|
|
9460
|
+
throw new Error(
|
|
9461
|
+
`Can't get schematic port position after layout for "${this.getString()}", no schematic_port_id`
|
|
9462
|
+
);
|
|
9463
|
+
}
|
|
9464
|
+
const schematic_port = db.schematic_port.get(this.schematic_port_id);
|
|
9465
|
+
if (!schematic_port)
|
|
9466
|
+
throw new Error(
|
|
9467
|
+
`Schematic port not found when trying to get post-layout position: ${this.schematic_port_id}`
|
|
9468
|
+
);
|
|
9469
|
+
return schematic_port.center;
|
|
9329
9470
|
}
|
|
9330
|
-
|
|
9331
|
-
|
|
9332
|
-
|
|
9333
|
-
|
|
9334
|
-
|
|
9335
|
-
|
|
9336
|
-
|
|
9337
|
-
case "right":
|
|
9338
|
-
return side;
|
|
9339
|
-
case "top":
|
|
9340
|
-
return "up";
|
|
9341
|
-
case "bottom":
|
|
9342
|
-
return "down";
|
|
9471
|
+
/**
|
|
9472
|
+
* Smtpads and platedholes call this method to register themselves as a match
|
|
9473
|
+
* for this port. All the matching is done by primitives other than the Port,
|
|
9474
|
+
* but everyone registers themselves as a match with their Port.
|
|
9475
|
+
*/
|
|
9476
|
+
registerMatch(component) {
|
|
9477
|
+
this.matchedComponents.push(component);
|
|
9343
9478
|
}
|
|
9344
|
-
|
|
9345
|
-
};
|
|
9346
|
-
|
|
9347
|
-
|
|
9348
|
-
|
|
9349
|
-
|
|
9350
|
-
|
|
9351
|
-
|
|
9352
|
-
]
|
|
9353
|
-
|
|
9354
|
-
elm.type
|
|
9355
|
-
);
|
|
9356
|
-
var getSchematicSymbolId = (elm) => {
|
|
9357
|
-
if (!("schematic_symbol_id" in elm)) return void 0;
|
|
9358
|
-
return typeof elm.schematic_symbol_id === "string" ? elm.schematic_symbol_id : void 0;
|
|
9359
|
-
};
|
|
9360
|
-
var createComponentsFromCircuitJson = ({
|
|
9361
|
-
componentName,
|
|
9362
|
-
componentRotation,
|
|
9363
|
-
footprinterString,
|
|
9364
|
-
pinLabels,
|
|
9365
|
-
pcbPinLabels
|
|
9366
|
-
}, circuitJson) => {
|
|
9367
|
-
const components = [];
|
|
9368
|
-
const schematicSymbolsByImportedId = /* @__PURE__ */ new Map();
|
|
9369
|
-
const schematicComponentsByImportedId = /* @__PURE__ */ new Map();
|
|
9370
|
-
const schematicStrokeWidthBySymbolId = /* @__PURE__ */ new Map();
|
|
9371
|
-
for (const elm of circuitJson) {
|
|
9372
|
-
if (elm.type !== "schematic_symbol") continue;
|
|
9373
|
-
const schematicSymbol = new SymbolComponent({
|
|
9374
|
-
name: elm.name
|
|
9375
|
-
});
|
|
9376
|
-
schematicSymbolsByImportedId.set(elm.schematic_symbol_id, schematicSymbol);
|
|
9377
|
-
components.push(schematicSymbol);
|
|
9479
|
+
getNameAndAliases() {
|
|
9480
|
+
const { _parsedProps: props } = this;
|
|
9481
|
+
return Array.from(
|
|
9482
|
+
/* @__PURE__ */ new Set([
|
|
9483
|
+
...props.name ? [props.name] : [],
|
|
9484
|
+
...props.aliases ?? [],
|
|
9485
|
+
...typeof props.pinNumber === "number" ? [`pin${props.pinNumber}`, props.pinNumber.toString()] : [],
|
|
9486
|
+
...this.externallyAddedAliases ?? []
|
|
9487
|
+
])
|
|
9488
|
+
);
|
|
9378
9489
|
}
|
|
9379
|
-
|
|
9380
|
-
|
|
9381
|
-
const
|
|
9382
|
-
const
|
|
9383
|
-
|
|
9384
|
-
|
|
9490
|
+
_getMatchingPinAttributes() {
|
|
9491
|
+
const parentProps = this.parent?._parsedProps;
|
|
9492
|
+
const pinAttributes = parentProps?.pinAttributes;
|
|
9493
|
+
const noConnect = parentProps?.noConnect;
|
|
9494
|
+
const matches = [];
|
|
9495
|
+
for (const alias of this.getNameAndAliases()) {
|
|
9496
|
+
if (pinAttributes) {
|
|
9497
|
+
const attributes = pinAttributes[alias];
|
|
9498
|
+
if (attributes) {
|
|
9499
|
+
matches.push(attributes);
|
|
9500
|
+
}
|
|
9501
|
+
}
|
|
9502
|
+
if (noConnect?.includes(alias)) {
|
|
9503
|
+
matches.push({ doNotConnect: true });
|
|
9504
|
+
}
|
|
9385
9505
|
}
|
|
9386
|
-
|
|
9506
|
+
if (matches.length === 0) {
|
|
9507
|
+
return [];
|
|
9508
|
+
}
|
|
9509
|
+
return matches;
|
|
9387
9510
|
}
|
|
9388
|
-
|
|
9389
|
-
|
|
9390
|
-
|
|
9511
|
+
_shouldIncludeInBoardPinout() {
|
|
9512
|
+
return this._getMatchingPinAttributes().some(
|
|
9513
|
+
(attributes) => attributes.includeInBoardPinout === true
|
|
9514
|
+
);
|
|
9391
9515
|
}
|
|
9392
|
-
|
|
9393
|
-
|
|
9394
|
-
|
|
9395
|
-
|
|
9396
|
-
|
|
9397
|
-
}
|
|
9398
|
-
|
|
9516
|
+
isMatchingPort(port) {
|
|
9517
|
+
return this.isMatchingAnyOf(port.getNameAndAliases());
|
|
9518
|
+
}
|
|
9519
|
+
getPortSelector() {
|
|
9520
|
+
const parentComponent = this.getParentNormalComponent() ?? this.parent;
|
|
9521
|
+
return `.${parentComponent?.props.name} > port.${this.props.name}`;
|
|
9522
|
+
}
|
|
9523
|
+
getAvailablePcbLayers() {
|
|
9524
|
+
const { layer, layers } = this._parsedProps;
|
|
9525
|
+
if (layers) return layers;
|
|
9526
|
+
if (layer) return [layer];
|
|
9527
|
+
return Array.from(
|
|
9528
|
+
new Set(this.matchedComponents.flatMap((c) => c.getAvailablePcbLayers()))
|
|
9529
|
+
);
|
|
9530
|
+
}
|
|
9531
|
+
/**
|
|
9532
|
+
* Return traces that are explicitly connected to this port (not via a net)
|
|
9533
|
+
*/
|
|
9534
|
+
_getDirectlyConnectedTraces() {
|
|
9535
|
+
const allSubcircuitTraces = this.getSubcircuit().selectAll(
|
|
9536
|
+
"trace"
|
|
9537
|
+
);
|
|
9538
|
+
const connectedTraces = allSubcircuitTraces.filter((trace) => !trace._couldNotFindPort).filter((trace) => trace._isExplicitlyConnectedToPort(this));
|
|
9539
|
+
return connectedTraces;
|
|
9540
|
+
}
|
|
9541
|
+
doInitialSourceRender() {
|
|
9542
|
+
const { db } = this.root;
|
|
9543
|
+
const { _parsedProps: props } = this;
|
|
9544
|
+
const port_hints = this.getNameAndAliases();
|
|
9545
|
+
const parentNormalComponent = this.getParentNormalComponent();
|
|
9546
|
+
const parentWithSourceId = this.parent?.source_component_id ? this.parent : parentNormalComponent;
|
|
9547
|
+
const source_component_id = parentWithSourceId?.source_component_id ?? null;
|
|
9548
|
+
const pinAttributes = this._getMatchingPinAttributes();
|
|
9549
|
+
const portAttributesFromParent = {};
|
|
9550
|
+
for (const attributes of pinAttributes) {
|
|
9551
|
+
applyPinAttributesToSourcePort(portAttributesFromParent, attributes);
|
|
9399
9552
|
}
|
|
9400
|
-
|
|
9401
|
-
|
|
9402
|
-
|
|
9403
|
-
|
|
9404
|
-
|
|
9405
|
-
|
|
9406
|
-
|
|
9407
|
-
|
|
9408
|
-
|
|
9409
|
-
|
|
9410
|
-
|
|
9411
|
-
|
|
9412
|
-
|
|
9413
|
-
|
|
9414
|
-
|
|
9415
|
-
|
|
9416
|
-
|
|
9417
|
-
|
|
9418
|
-
|
|
9419
|
-
|
|
9420
|
-
|
|
9421
|
-
|
|
9422
|
-
|
|
9423
|
-
|
|
9424
|
-
})
|
|
9425
|
-
);
|
|
9426
|
-
} else if (elm.type === "pcb_smtpad" && elm.shape === "pill") {
|
|
9427
|
-
components.push(
|
|
9428
|
-
new SmtPad({
|
|
9429
|
-
shape: "pill",
|
|
9430
|
-
height: elm.height,
|
|
9431
|
-
width: elm.width,
|
|
9432
|
-
radius: elm.radius,
|
|
9433
|
-
portHints: elm.port_hints,
|
|
9434
|
-
pcbX: elm.x,
|
|
9435
|
-
pcbY: elm.y,
|
|
9436
|
-
layer: elm.layer
|
|
9437
|
-
})
|
|
9438
|
-
);
|
|
9439
|
-
} else if (elm.type === "pcb_smtpad" && elm.shape === "polygon") {
|
|
9440
|
-
components.push(
|
|
9441
|
-
new SmtPad({
|
|
9442
|
-
shape: "polygon",
|
|
9443
|
-
points: elm.points,
|
|
9444
|
-
portHints: elm.port_hints,
|
|
9445
|
-
layer: elm.layer
|
|
9446
|
-
})
|
|
9447
|
-
);
|
|
9448
|
-
} else if (elm.type === "pcb_silkscreen_path") {
|
|
9449
|
-
components.push(
|
|
9450
|
-
new SilkscreenPath({
|
|
9451
|
-
layer: elm.layer,
|
|
9452
|
-
route: elm.route,
|
|
9453
|
-
strokeWidth: elm.stroke_width
|
|
9454
|
-
})
|
|
9553
|
+
const source_port = db.source_port.insert({
|
|
9554
|
+
name: props.name,
|
|
9555
|
+
pin_number: props.pinNumber,
|
|
9556
|
+
port_hints,
|
|
9557
|
+
source_component_id,
|
|
9558
|
+
subcircuit_id: this.getSubcircuit()?.subcircuit_id,
|
|
9559
|
+
...portAttributesFromParent
|
|
9560
|
+
});
|
|
9561
|
+
this.source_port_id = source_port.source_port_id;
|
|
9562
|
+
}
|
|
9563
|
+
doInitialSourceParentAttachment() {
|
|
9564
|
+
const { db } = this.root;
|
|
9565
|
+
const parentNormalComponent = this.getParentNormalComponent();
|
|
9566
|
+
const parentWithSourceId = this.parent?.source_component_id ? this.parent : parentNormalComponent;
|
|
9567
|
+
if (this.isGroupPort()) {
|
|
9568
|
+
db.source_port.update(this.source_port_id, {
|
|
9569
|
+
source_component_id: null,
|
|
9570
|
+
subcircuit_id: this.getSubcircuit()?.subcircuit_id
|
|
9571
|
+
});
|
|
9572
|
+
return;
|
|
9573
|
+
}
|
|
9574
|
+
if (!parentWithSourceId?.source_component_id) {
|
|
9575
|
+
throw new Error(
|
|
9576
|
+
`${this.getString()} has no parent source component (parent: ${this.parent?.getString()})`
|
|
9455
9577
|
);
|
|
9456
|
-
}
|
|
9457
|
-
|
|
9458
|
-
|
|
9459
|
-
|
|
9460
|
-
|
|
9461
|
-
|
|
9462
|
-
|
|
9463
|
-
|
|
9464
|
-
|
|
9465
|
-
|
|
9466
|
-
|
|
9467
|
-
|
|
9468
|
-
|
|
9578
|
+
}
|
|
9579
|
+
db.source_port.update(this.source_port_id, {
|
|
9580
|
+
source_component_id: parentWithSourceId.source_component_id,
|
|
9581
|
+
subcircuit_id: this.getSubcircuit()?.subcircuit_id
|
|
9582
|
+
});
|
|
9583
|
+
this.source_component_id = parentWithSourceId.source_component_id;
|
|
9584
|
+
}
|
|
9585
|
+
doInitialPcbPortRender() {
|
|
9586
|
+
if (this.root?.pcbDisabled) return;
|
|
9587
|
+
const { db } = this.root;
|
|
9588
|
+
const { matchedComponents } = this;
|
|
9589
|
+
if (this.isGroupPort()) {
|
|
9590
|
+
const connectedPorts = this._getConnectedPortsFromConnectsTo();
|
|
9591
|
+
if (connectedPorts.length === 0) {
|
|
9592
|
+
return;
|
|
9593
|
+
}
|
|
9594
|
+
const connectedPort = connectedPorts[0];
|
|
9595
|
+
if (!connectedPort.pcb_port_id) {
|
|
9596
|
+
return;
|
|
9597
|
+
}
|
|
9598
|
+
const connectedPcbPort = db.pcb_port.get(connectedPort.pcb_port_id);
|
|
9599
|
+
const matchCenter2 = { x: connectedPcbPort.x, y: connectedPcbPort.y };
|
|
9600
|
+
const subcircuit = this.getSubcircuit();
|
|
9601
|
+
const pcb_port = db.pcb_port.insert({
|
|
9602
|
+
pcb_component_id: void 0,
|
|
9603
|
+
layers: connectedPort.getAvailablePcbLayers(),
|
|
9604
|
+
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
9605
|
+
pcb_group_id: this.getGroup()?.pcb_group_id ?? void 0,
|
|
9606
|
+
...matchCenter2,
|
|
9607
|
+
source_port_id: this.source_port_id,
|
|
9608
|
+
is_board_pinout: false
|
|
9609
|
+
});
|
|
9610
|
+
this.pcb_port_id = pcb_port.pcb_port_id;
|
|
9611
|
+
return;
|
|
9612
|
+
}
|
|
9613
|
+
const parentNormalComponent = this.getParentNormalComponent();
|
|
9614
|
+
const parentWithPcbComponentId = this.parent?.pcb_component_id ? this.parent : parentNormalComponent;
|
|
9615
|
+
if (!parentWithPcbComponentId?.pcb_component_id) {
|
|
9616
|
+
throw new Error(
|
|
9617
|
+
`${this.getString()} has no parent pcb component, cannot render pcb_port (parent: ${this.parent?.getString()}, parentNormalComponent: ${parentNormalComponent?.getString()})`
|
|
9469
9618
|
);
|
|
9470
|
-
}
|
|
9471
|
-
|
|
9472
|
-
|
|
9473
|
-
|
|
9474
|
-
|
|
9475
|
-
|
|
9476
|
-
|
|
9477
|
-
|
|
9478
|
-
|
|
9479
|
-
|
|
9480
|
-
|
|
9481
|
-
)
|
|
9482
|
-
|
|
9483
|
-
components.push(
|
|
9484
|
-
new PlatedHole({
|
|
9485
|
-
pcbX: elm.x,
|
|
9486
|
-
pcbY: elm.y,
|
|
9487
|
-
shape: "circular_hole_with_rect_pad",
|
|
9488
|
-
holeDiameter: elm.hole_diameter,
|
|
9489
|
-
rectPadHeight: elm.rect_pad_height,
|
|
9490
|
-
rectPadWidth: elm.rect_pad_width,
|
|
9491
|
-
portHints: elm.port_hints,
|
|
9492
|
-
rectBorderRadius: elm.rect_border_radius,
|
|
9493
|
-
holeOffsetX: elm.hole_offset_x,
|
|
9494
|
-
holeOffsetY: elm.hole_offset_y
|
|
9495
|
-
})
|
|
9496
|
-
);
|
|
9497
|
-
} else if (elm.shape === "pill" || elm.shape === "oval") {
|
|
9498
|
-
components.push(
|
|
9499
|
-
new PlatedHole({
|
|
9500
|
-
pcbX: elm.x,
|
|
9501
|
-
pcbY: elm.y,
|
|
9502
|
-
shape: elm.shape,
|
|
9503
|
-
holeWidth: elm.hole_width,
|
|
9504
|
-
holeHeight: elm.hole_height,
|
|
9505
|
-
outerWidth: elm.outer_width,
|
|
9506
|
-
outerHeight: elm.outer_height,
|
|
9507
|
-
portHints: elm.port_hints
|
|
9508
|
-
})
|
|
9509
|
-
);
|
|
9510
|
-
} else if (elm.shape === "pill_hole_with_rect_pad") {
|
|
9511
|
-
components.push(
|
|
9512
|
-
new PlatedHole({
|
|
9513
|
-
pcbX: elm.x,
|
|
9514
|
-
pcbY: elm.y,
|
|
9515
|
-
shape: "pill_hole_with_rect_pad",
|
|
9516
|
-
holeShape: "pill",
|
|
9517
|
-
padShape: "rect",
|
|
9518
|
-
holeWidth: elm.hole_width,
|
|
9519
|
-
holeHeight: elm.hole_height,
|
|
9520
|
-
rectPadWidth: elm.rect_pad_width,
|
|
9521
|
-
rectPadHeight: elm.rect_pad_height,
|
|
9522
|
-
rectBorderRadius: elm.rect_border_radius,
|
|
9523
|
-
portHints: elm.port_hints,
|
|
9524
|
-
holeOffsetX: elm.hole_offset_x,
|
|
9525
|
-
holeOffsetY: elm.hole_offset_y
|
|
9526
|
-
})
|
|
9619
|
+
}
|
|
9620
|
+
const pcbMatches = matchedComponents.filter((c) => c.isPcbPrimitive);
|
|
9621
|
+
if (pcbMatches.length === 0) return;
|
|
9622
|
+
let matchCenter = null;
|
|
9623
|
+
if (pcbMatches.length === 1) {
|
|
9624
|
+
matchCenter = pcbMatches[0]._getPcbCircuitJsonBounds().center;
|
|
9625
|
+
}
|
|
9626
|
+
if (pcbMatches.length > 1) {
|
|
9627
|
+
if (!areAllPcbPrimitivesOverlapping(pcbMatches)) {
|
|
9628
|
+
const portName = this.props.name;
|
|
9629
|
+
const componentName = this.getParentNormalComponent()?.props.name ?? "unknown";
|
|
9630
|
+
const altAliases = this.getNameAndAliases().filter(
|
|
9631
|
+
(h) => h !== portName
|
|
9527
9632
|
);
|
|
9528
|
-
|
|
9529
|
-
|
|
9530
|
-
|
|
9531
|
-
|
|
9532
|
-
|
|
9533
|
-
|
|
9534
|
-
holeShape: "pill",
|
|
9535
|
-
padShape: "rect",
|
|
9536
|
-
holeWidth: elm.hole_width,
|
|
9537
|
-
holeHeight: elm.hole_height,
|
|
9538
|
-
rectPadWidth: elm.rect_pad_width,
|
|
9539
|
-
rectPadHeight: elm.rect_pad_height,
|
|
9540
|
-
rectBorderRadius: elm.rect_border_radius,
|
|
9541
|
-
portHints: elm.port_hints,
|
|
9542
|
-
holeOffsetX: elm.hole_offset_x,
|
|
9543
|
-
holeOffsetY: elm.hole_offset_y,
|
|
9544
|
-
pcbRotation: elm.hole_ccw_rotation
|
|
9545
|
-
})
|
|
9546
|
-
);
|
|
9547
|
-
} else if (elm.shape === "hole_with_polygon_pad") {
|
|
9548
|
-
components.push(
|
|
9549
|
-
new PlatedHole({
|
|
9550
|
-
pcbX: elm.x,
|
|
9551
|
-
pcbY: elm.y,
|
|
9552
|
-
shape: "hole_with_polygon_pad",
|
|
9553
|
-
holeShape: elm.hole_shape || "circle",
|
|
9554
|
-
holeDiameter: elm.hole_diameter,
|
|
9555
|
-
holeWidth: elm.hole_width,
|
|
9556
|
-
holeHeight: elm.hole_height,
|
|
9557
|
-
padOutline: elm.pad_outline || [],
|
|
9558
|
-
holeOffsetX: elm.hole_offset_x,
|
|
9559
|
-
holeOffsetY: elm.hole_offset_y,
|
|
9560
|
-
portHints: elm.port_hints
|
|
9561
|
-
})
|
|
9562
|
-
);
|
|
9563
|
-
}
|
|
9564
|
-
} else if (elm.type === "pcb_keepout" && elm.shape === "circle") {
|
|
9565
|
-
components.push(
|
|
9566
|
-
new Keepout({
|
|
9567
|
-
pcbX: elm.center.x,
|
|
9568
|
-
pcbY: elm.center.y,
|
|
9569
|
-
shape: "circle",
|
|
9570
|
-
radius: elm.radius
|
|
9571
|
-
})
|
|
9572
|
-
);
|
|
9573
|
-
} else if (elm.type === "pcb_keepout" && elm.shape === "rect") {
|
|
9574
|
-
components.push(
|
|
9575
|
-
new Keepout({
|
|
9576
|
-
pcbX: elm.center.x,
|
|
9577
|
-
pcbY: elm.center.y,
|
|
9578
|
-
shape: "rect",
|
|
9579
|
-
width: elm.width,
|
|
9580
|
-
height: elm.height
|
|
9581
|
-
})
|
|
9582
|
-
);
|
|
9583
|
-
} else if (elm.type === "pcb_hole" && elm.hole_shape === "circle") {
|
|
9584
|
-
components.push(
|
|
9585
|
-
new Hole({
|
|
9586
|
-
pcbX: elm.x,
|
|
9587
|
-
pcbY: elm.y,
|
|
9588
|
-
diameter: elm.hole_diameter
|
|
9589
|
-
})
|
|
9590
|
-
);
|
|
9591
|
-
} else if (elm.type === "pcb_hole" && elm.hole_shape === "rect") {
|
|
9592
|
-
components.push(
|
|
9593
|
-
new Hole({
|
|
9594
|
-
pcbX: elm.x,
|
|
9595
|
-
pcbY: elm.y,
|
|
9596
|
-
shape: "rect",
|
|
9597
|
-
width: elm.hole_width,
|
|
9598
|
-
height: elm.hole_height
|
|
9599
|
-
})
|
|
9600
|
-
);
|
|
9601
|
-
} else if (elm.type === "pcb_hole" && elm.hole_shape === "pill") {
|
|
9602
|
-
components.push(
|
|
9603
|
-
new Hole({
|
|
9604
|
-
pcbX: elm.x,
|
|
9605
|
-
pcbY: elm.y,
|
|
9606
|
-
shape: "pill",
|
|
9607
|
-
width: elm.hole_width,
|
|
9608
|
-
height: elm.hole_height
|
|
9609
|
-
})
|
|
9610
|
-
);
|
|
9611
|
-
} else if (elm.type === "pcb_hole" && elm.hole_shape === "oval") {
|
|
9612
|
-
components.push(
|
|
9613
|
-
new Hole({
|
|
9614
|
-
pcbX: elm.x,
|
|
9615
|
-
pcbY: elm.y,
|
|
9616
|
-
shape: "oval",
|
|
9617
|
-
width: elm.hole_width,
|
|
9618
|
-
height: elm.hole_height
|
|
9619
|
-
})
|
|
9620
|
-
);
|
|
9621
|
-
} else if (elm.type === "pcb_hole" && elm.hole_shape === "rotated_pill") {
|
|
9622
|
-
components.push(
|
|
9623
|
-
new Hole({
|
|
9624
|
-
pcbX: elm.x,
|
|
9625
|
-
pcbY: elm.y,
|
|
9626
|
-
shape: "pill",
|
|
9627
|
-
width: elm.hole_width,
|
|
9628
|
-
height: elm.hole_height,
|
|
9629
|
-
pcbRotation: elm.ccw_rotation
|
|
9630
|
-
})
|
|
9631
|
-
);
|
|
9632
|
-
} else if (elm.type === "pcb_cutout") {
|
|
9633
|
-
if (elm.shape === "rect") {
|
|
9634
|
-
components.push(
|
|
9635
|
-
new Cutout({
|
|
9636
|
-
pcbX: elm.center.x,
|
|
9637
|
-
pcbY: elm.center.y,
|
|
9638
|
-
shape: "rect",
|
|
9639
|
-
width: elm.width,
|
|
9640
|
-
height: elm.height
|
|
9641
|
-
})
|
|
9642
|
-
);
|
|
9643
|
-
} else if (elm.shape === "circle") {
|
|
9644
|
-
components.push(
|
|
9645
|
-
new Cutout({
|
|
9646
|
-
pcbX: elm.center.x,
|
|
9647
|
-
pcbY: elm.center.y,
|
|
9648
|
-
shape: "circle",
|
|
9649
|
-
radius: elm.radius
|
|
9650
|
-
})
|
|
9651
|
-
);
|
|
9652
|
-
} else if (elm.shape === "polygon") {
|
|
9653
|
-
components.push(
|
|
9654
|
-
new Cutout({
|
|
9655
|
-
shape: "polygon",
|
|
9656
|
-
points: elm.points
|
|
9657
|
-
})
|
|
9658
|
-
);
|
|
9659
|
-
}
|
|
9660
|
-
} else if (elm.type === "pcb_silkscreen_text") {
|
|
9661
|
-
const ccwRotation = calculateCcwRotation(
|
|
9662
|
-
componentRotation,
|
|
9663
|
-
elm.ccw_rotation
|
|
9664
|
-
);
|
|
9665
|
-
if (footprinterString?.includes("pinrow") && elm.text.includes("PIN")) {
|
|
9666
|
-
components.push(
|
|
9667
|
-
createPinrowSilkscreenText({
|
|
9668
|
-
elm,
|
|
9669
|
-
pinLabels: pcbPinLabels ?? pinLabels ?? {},
|
|
9670
|
-
layer: elm.layer,
|
|
9671
|
-
readableRotation: ccwRotation,
|
|
9672
|
-
anchorAlignment: elm.anchor_alignment
|
|
9673
|
-
})
|
|
9674
|
-
);
|
|
9675
|
-
} else {
|
|
9676
|
-
const silkscreenText = new SilkscreenText({
|
|
9677
|
-
anchorAlignment: elm.anchor_alignment || "center",
|
|
9678
|
-
text: componentName || elm.text,
|
|
9679
|
-
pcbX: Number.isNaN(elm.anchor_position.x) ? 0 : elm.anchor_position.x,
|
|
9680
|
-
pcbY: elm.anchor_position.y,
|
|
9681
|
-
pcbRotation: ccwRotation ?? 0
|
|
9633
|
+
const altMsg = altAliases.length > 0 ? ` (consider using alternate aliases: ${altAliases.join(", ")})` : "";
|
|
9634
|
+
db.source_ambiguous_port_reference.insert({
|
|
9635
|
+
error_type: "source_ambiguous_port_reference",
|
|
9636
|
+
message: `${componentName}.${portName} is ambiguous: ${componentName}.${portName} references multiple non-overlapping pads: ${pcbMatches.map((c) => c.getString()).join(", ")}${altMsg}`,
|
|
9637
|
+
source_port_id: this.source_port_id ?? void 0,
|
|
9638
|
+
source_component_id: this.getParentNormalComponent()?.source_component_id ?? void 0
|
|
9682
9639
|
});
|
|
9683
|
-
|
|
9684
|
-
components.push(silkscreenText);
|
|
9640
|
+
return;
|
|
9685
9641
|
}
|
|
9686
|
-
|
|
9687
|
-
|
|
9688
|
-
|
|
9689
|
-
|
|
9690
|
-
|
|
9691
|
-
|
|
9692
|
-
|
|
9693
|
-
|
|
9694
|
-
|
|
9695
|
-
|
|
9696
|
-
|
|
9697
|
-
|
|
9698
|
-
|
|
9699
|
-
|
|
9700
|
-
toLayer: elm.to_layer ?? layers[layers.length - 1],
|
|
9701
|
-
layers,
|
|
9702
|
-
netIsAssignable: elm.net_is_assignable,
|
|
9703
|
-
isTented: elm.is_tented
|
|
9642
|
+
matchCenter = getCenterOfPcbPrimitives(pcbMatches);
|
|
9643
|
+
}
|
|
9644
|
+
if (matchCenter) {
|
|
9645
|
+
const subcircuit = this.getSubcircuit();
|
|
9646
|
+
const isBoardPinout = this._shouldIncludeInBoardPinout();
|
|
9647
|
+
const pcb_port = db.pcb_port.insert({
|
|
9648
|
+
pcb_component_id: parentWithPcbComponentId.pcb_component_id,
|
|
9649
|
+
layers: this.getAvailablePcbLayers(),
|
|
9650
|
+
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
9651
|
+
pcb_group_id: this.getGroup()?.pcb_group_id ?? void 0,
|
|
9652
|
+
...isBoardPinout ? { is_board_pinout: true } : {},
|
|
9653
|
+
...matchCenter,
|
|
9654
|
+
source_port_id: this.source_port_id,
|
|
9655
|
+
is_board_pinout: this._isBoardPinoutFromAttributes()
|
|
9704
9656
|
});
|
|
9705
|
-
|
|
9706
|
-
|
|
9707
|
-
|
|
9708
|
-
|
|
9709
|
-
|
|
9710
|
-
pcbX: elm.center.x,
|
|
9711
|
-
pcbY: elm.center.y,
|
|
9712
|
-
width: elm.width,
|
|
9713
|
-
height: elm.height,
|
|
9714
|
-
layer: elm.layer,
|
|
9715
|
-
strokeWidth: elm.stroke_width,
|
|
9716
|
-
filled: elm.is_filled,
|
|
9717
|
-
cornerRadius: elm.corner_radius
|
|
9718
|
-
})
|
|
9719
|
-
);
|
|
9720
|
-
} else if (elm.type === "pcb_silkscreen_circle") {
|
|
9721
|
-
components.push(
|
|
9722
|
-
new SilkscreenCircle({
|
|
9723
|
-
pcbX: elm.center.x,
|
|
9724
|
-
pcbY: elm.center.y,
|
|
9725
|
-
radius: elm.radius,
|
|
9726
|
-
layer: elm.layer,
|
|
9727
|
-
strokeWidth: elm.stroke_width
|
|
9728
|
-
})
|
|
9729
|
-
);
|
|
9730
|
-
} else if (elm.type === "pcb_silkscreen_line") {
|
|
9731
|
-
components.push(
|
|
9732
|
-
new SilkscreenLine({
|
|
9733
|
-
x1: elm.x1,
|
|
9734
|
-
y1: elm.y1,
|
|
9735
|
-
x2: elm.x2,
|
|
9736
|
-
y2: elm.y2,
|
|
9737
|
-
layer: elm.layer,
|
|
9738
|
-
strokeWidth: elm.stroke_width
|
|
9739
|
-
})
|
|
9740
|
-
);
|
|
9741
|
-
} else if (elm.type === "pcb_fabrication_note_text") {
|
|
9742
|
-
components.push(
|
|
9743
|
-
new FabricationNoteText({
|
|
9744
|
-
pcbX: elm.anchor_position.x,
|
|
9745
|
-
pcbY: elm.anchor_position.y,
|
|
9746
|
-
text: elm.text,
|
|
9747
|
-
fontSize: elm.font_size,
|
|
9748
|
-
anchorAlignment: elm.anchor_alignment,
|
|
9749
|
-
color: elm.color,
|
|
9750
|
-
font: elm.font
|
|
9751
|
-
})
|
|
9752
|
-
);
|
|
9753
|
-
} else if (elm.type === "pcb_fabrication_note_path") {
|
|
9754
|
-
components.push(
|
|
9755
|
-
new FabricationNotePath({
|
|
9756
|
-
route: elm.route,
|
|
9757
|
-
strokeWidth: elm.stroke_width,
|
|
9758
|
-
color: elm.color,
|
|
9759
|
-
layer: elm.layer
|
|
9760
|
-
})
|
|
9761
|
-
);
|
|
9762
|
-
} else if (elm.type === "pcb_fabrication_note_rect") {
|
|
9763
|
-
components.push(
|
|
9764
|
-
new FabricationNoteRect({
|
|
9765
|
-
pcbX: elm.center.x,
|
|
9766
|
-
pcbY: elm.center.y,
|
|
9767
|
-
width: elm.width,
|
|
9768
|
-
height: elm.height,
|
|
9769
|
-
strokeWidth: elm.stroke_width,
|
|
9770
|
-
isFilled: elm.is_filled,
|
|
9771
|
-
color: elm.color,
|
|
9772
|
-
layer: elm.layer,
|
|
9773
|
-
cornerRadius: elm.corner_radius,
|
|
9774
|
-
hasStroke: elm.has_stroke,
|
|
9775
|
-
isStrokeDashed: elm.is_stroke_dashed
|
|
9776
|
-
})
|
|
9657
|
+
this.pcb_port_id = pcb_port.pcb_port_id;
|
|
9658
|
+
} else {
|
|
9659
|
+
const pcbMatch = pcbMatches[0];
|
|
9660
|
+
throw new Error(
|
|
9661
|
+
`${pcbMatch.getString()} does not have a center or _getGlobalPcbPositionBeforeLayout method (needed for pcb_port placement)`
|
|
9777
9662
|
);
|
|
9778
|
-
} else if (elm.type === "pcb_note_text") {
|
|
9779
|
-
components.push(
|
|
9780
|
-
new PcbNoteText({
|
|
9781
|
-
pcbX: elm.anchor_position.x,
|
|
9782
|
-
pcbY: elm.anchor_position.y,
|
|
9783
|
-
text: elm.text ?? "",
|
|
9784
|
-
fontSize: elm.font_size,
|
|
9785
|
-
anchorAlignment: elm.anchor_alignment,
|
|
9786
|
-
color: elm.color,
|
|
9787
|
-
font: elm.font
|
|
9788
|
-
})
|
|
9789
|
-
);
|
|
9790
|
-
} else if (elm.type === "pcb_note_rect") {
|
|
9791
|
-
components.push(
|
|
9792
|
-
new PcbNoteRect({
|
|
9793
|
-
pcbX: elm.center.x,
|
|
9794
|
-
pcbY: elm.center.y,
|
|
9795
|
-
width: elm.width,
|
|
9796
|
-
height: elm.height,
|
|
9797
|
-
strokeWidth: elm.stroke_width,
|
|
9798
|
-
isFilled: elm.is_filled,
|
|
9799
|
-
color: elm.color,
|
|
9800
|
-
cornerRadius: elm.corner_radius,
|
|
9801
|
-
hasStroke: elm.has_stroke,
|
|
9802
|
-
isStrokeDashed: elm.is_stroke_dashed
|
|
9803
|
-
})
|
|
9804
|
-
);
|
|
9805
|
-
} else if (elm.type === "pcb_note_path") {
|
|
9806
|
-
components.push(
|
|
9807
|
-
new PcbNotePath({
|
|
9808
|
-
route: elm.route,
|
|
9809
|
-
strokeWidth: elm.stroke_width,
|
|
9810
|
-
color: elm.color
|
|
9811
|
-
})
|
|
9812
|
-
);
|
|
9813
|
-
} else if (elm.type === "pcb_note_line") {
|
|
9814
|
-
components.push(
|
|
9815
|
-
new PcbNoteLine({
|
|
9816
|
-
x1: elm.x1,
|
|
9817
|
-
y1: elm.y1,
|
|
9818
|
-
x2: elm.x2,
|
|
9819
|
-
y2: elm.y2,
|
|
9820
|
-
strokeWidth: elm.stroke_width,
|
|
9821
|
-
color: elm.color,
|
|
9822
|
-
isDashed: elm.is_dashed
|
|
9823
|
-
})
|
|
9824
|
-
);
|
|
9825
|
-
} else if (elm.type === "pcb_courtyard_rect") {
|
|
9826
|
-
components.push(
|
|
9827
|
-
new CourtyardRect({
|
|
9828
|
-
pcbX: elm.center.x,
|
|
9829
|
-
pcbY: elm.center.y,
|
|
9830
|
-
width: elm.width,
|
|
9831
|
-
height: elm.height,
|
|
9832
|
-
layer: elm.layer
|
|
9833
|
-
})
|
|
9834
|
-
);
|
|
9835
|
-
} else if (elm.type === "pcb_courtyard_circle") {
|
|
9836
|
-
components.push(
|
|
9837
|
-
new CourtyardCircle({
|
|
9838
|
-
pcbX: elm.center.x,
|
|
9839
|
-
pcbY: elm.center.y,
|
|
9840
|
-
radius: elm.radius,
|
|
9841
|
-
layer: elm.layer
|
|
9842
|
-
})
|
|
9843
|
-
);
|
|
9844
|
-
} else if (elm.type === "pcb_courtyard_outline") {
|
|
9845
|
-
components.push(
|
|
9846
|
-
new CourtyardOutline({
|
|
9847
|
-
outline: elm.outline,
|
|
9848
|
-
layer: elm.layer
|
|
9849
|
-
})
|
|
9850
|
-
);
|
|
9851
|
-
} else if (elm.type === "schematic_line") {
|
|
9852
|
-
addSchematicPrimitive(
|
|
9853
|
-
elm,
|
|
9854
|
-
new SchematicLine({
|
|
9855
|
-
x1: elm.x1,
|
|
9856
|
-
y1: elm.y1,
|
|
9857
|
-
x2: elm.x2,
|
|
9858
|
-
y2: elm.y2,
|
|
9859
|
-
strokeWidth: optional(elm.stroke_width),
|
|
9860
|
-
color: elm.color,
|
|
9861
|
-
isDashed: elm.is_dashed
|
|
9862
|
-
})
|
|
9863
|
-
);
|
|
9864
|
-
} else if (elm.type === "schematic_rect") {
|
|
9865
|
-
addSchematicPrimitive(
|
|
9866
|
-
elm,
|
|
9867
|
-
new SchematicRect({
|
|
9868
|
-
schX: elm.center.x,
|
|
9869
|
-
schY: elm.center.y,
|
|
9870
|
-
width: elm.width,
|
|
9871
|
-
height: elm.height,
|
|
9872
|
-
rotation: elm.rotation,
|
|
9873
|
-
strokeWidth: optional(elm.stroke_width),
|
|
9874
|
-
color: elm.color,
|
|
9875
|
-
isFilled: elm.is_filled,
|
|
9876
|
-
fillColor: elm.fill_color,
|
|
9877
|
-
isDashed: elm.is_dashed
|
|
9878
|
-
})
|
|
9879
|
-
);
|
|
9880
|
-
} else if (elm.type === "schematic_circle") {
|
|
9881
|
-
addSchematicPrimitive(
|
|
9882
|
-
elm,
|
|
9883
|
-
new SchematicCircle({
|
|
9884
|
-
center: elm.center,
|
|
9885
|
-
radius: elm.radius,
|
|
9886
|
-
strokeWidth: optional(elm.stroke_width),
|
|
9887
|
-
color: elm.color,
|
|
9888
|
-
isFilled: elm.is_filled,
|
|
9889
|
-
fillColor: elm.fill_color,
|
|
9890
|
-
isDashed: elm.is_dashed
|
|
9891
|
-
})
|
|
9892
|
-
);
|
|
9893
|
-
} else if (elm.type === "schematic_arc") {
|
|
9894
|
-
addSchematicPrimitive(
|
|
9895
|
-
elm,
|
|
9896
|
-
new SchematicArc({
|
|
9897
|
-
center: elm.center,
|
|
9898
|
-
radius: elm.radius,
|
|
9899
|
-
startAngleDegrees: elm.start_angle_degrees,
|
|
9900
|
-
endAngleDegrees: elm.end_angle_degrees,
|
|
9901
|
-
direction: elm.direction,
|
|
9902
|
-
strokeWidth: optional(elm.stroke_width),
|
|
9903
|
-
color: elm.color,
|
|
9904
|
-
isDashed: elm.is_dashed
|
|
9905
|
-
})
|
|
9906
|
-
);
|
|
9907
|
-
} else if (elm.type === "schematic_text") {
|
|
9908
|
-
addSchematicPrimitive(
|
|
9909
|
-
elm,
|
|
9910
|
-
new SchematicText({
|
|
9911
|
-
schX: elm.position.x,
|
|
9912
|
-
schY: elm.position.y,
|
|
9913
|
-
text: elm.text,
|
|
9914
|
-
fontSize: elm.font_size,
|
|
9915
|
-
anchor: elm.anchor,
|
|
9916
|
-
color: elm.color,
|
|
9917
|
-
schRotation: elm.rotation
|
|
9918
|
-
})
|
|
9919
|
-
);
|
|
9920
|
-
} else if (elm.type === "schematic_path") {
|
|
9921
|
-
addSchematicPrimitive(
|
|
9922
|
-
elm,
|
|
9923
|
-
new SchematicPath({
|
|
9924
|
-
points: elm.points,
|
|
9925
|
-
strokeWidth: optional(elm.stroke_width),
|
|
9926
|
-
strokeColor: elm.stroke_color,
|
|
9927
|
-
dashLength: elm.dash_length,
|
|
9928
|
-
dashGap: elm.dash_gap,
|
|
9929
|
-
isFilled: elm.is_filled,
|
|
9930
|
-
fillColor: elm.fill_color
|
|
9931
|
-
})
|
|
9932
|
-
);
|
|
9933
|
-
} else if (elm.type === "schematic_port") {
|
|
9934
|
-
const schematicComponentId = elm.schematic_component_id;
|
|
9935
|
-
if (typeof schematicComponentId !== "string") continue;
|
|
9936
|
-
const schematicComponent = schematicComponentsByImportedId.get(schematicComponentId);
|
|
9937
|
-
const schematicSymbolId = schematicComponent?.schematic_symbol_id;
|
|
9938
|
-
const parentSymbol = typeof schematicSymbolId === "string" ? schematicSymbolsByImportedId.get(schematicSymbolId) : void 0;
|
|
9939
|
-
if (parentSymbol && schematicComponent?.is_box_with_pins === true && elm.center && elm.side_of_component) {
|
|
9940
|
-
const distance19 = elm.distance_from_component_edge;
|
|
9941
|
-
const facingDirection = getFacingDirectionFromSide(
|
|
9942
|
-
elm.side_of_component
|
|
9943
|
-
);
|
|
9944
|
-
if (!facingDirection) continue;
|
|
9945
|
-
const directionVector = getUnitVectorFromDirection2(facingDirection);
|
|
9946
|
-
const stemDirection = elm.facing_direction === facingDirection ? 1 : -1;
|
|
9947
|
-
const portCenter = {
|
|
9948
|
-
x: elm.center.x + directionVector.x * distance19 * stemDirection,
|
|
9949
|
-
y: elm.center.y + directionVector.y * distance19 * stemDirection
|
|
9950
|
-
};
|
|
9951
|
-
parentSymbol.add(
|
|
9952
|
-
new SchematicLine({
|
|
9953
|
-
x1: elm.center.x,
|
|
9954
|
-
y1: elm.center.y,
|
|
9955
|
-
x2: portCenter.x,
|
|
9956
|
-
y2: portCenter.y,
|
|
9957
|
-
strokeWidth: typeof schematicSymbolId === "string" ? optional(
|
|
9958
|
-
schematicStrokeWidthBySymbolId.get(schematicSymbolId)
|
|
9959
|
-
) : void 0,
|
|
9960
|
-
isDashed: false
|
|
9961
|
-
})
|
|
9962
|
-
);
|
|
9963
|
-
}
|
|
9964
9663
|
}
|
|
9965
9664
|
}
|
|
9966
|
-
|
|
9967
|
-
|
|
9968
|
-
|
|
9969
|
-
|
|
9970
|
-
|
|
9971
|
-
|
|
9972
|
-
|
|
9973
|
-
|
|
9974
|
-
|
|
9975
|
-
|
|
9976
|
-
|
|
9977
|
-
|
|
9978
|
-
|
|
9979
|
-
|
|
9980
|
-
|
|
9981
|
-
|
|
9982
|
-
|
|
9983
|
-
|
|
9984
|
-
|
|
9985
|
-
|
|
9986
|
-
|
|
9987
|
-
|
|
9988
|
-
|
|
9989
|
-
}
|
|
9665
|
+
updatePcbPortRender() {
|
|
9666
|
+
if (this.root?.pcbDisabled) return;
|
|
9667
|
+
const { db } = this.root;
|
|
9668
|
+
if (this.pcb_port_id) return;
|
|
9669
|
+
if (this.isGroupPort()) {
|
|
9670
|
+
const connectedPorts = this._getConnectedPortsFromConnectsTo();
|
|
9671
|
+
if (connectedPorts.length === 0) return;
|
|
9672
|
+
const connectedPort = connectedPorts[0];
|
|
9673
|
+
if (!connectedPort.pcb_port_id) return;
|
|
9674
|
+
const connectedPcbPort = db.pcb_port.get(connectedPort.pcb_port_id);
|
|
9675
|
+
const matchCenter2 = { x: connectedPcbPort.x, y: connectedPcbPort.y };
|
|
9676
|
+
const subcircuit2 = this.getSubcircuit();
|
|
9677
|
+
const pcb_port2 = db.pcb_port.insert({
|
|
9678
|
+
pcb_component_id: void 0,
|
|
9679
|
+
layers: connectedPort.getAvailablePcbLayers(),
|
|
9680
|
+
subcircuit_id: subcircuit2?.subcircuit_id ?? void 0,
|
|
9681
|
+
pcb_group_id: this.getGroup()?.pcb_group_id ?? void 0,
|
|
9682
|
+
...matchCenter2,
|
|
9683
|
+
source_port_id: this.source_port_id,
|
|
9684
|
+
is_board_pinout: false
|
|
9685
|
+
});
|
|
9686
|
+
this.pcb_port_id = pcb_port2.pcb_port_id;
|
|
9687
|
+
return;
|
|
9990
9688
|
}
|
|
9991
|
-
|
|
9992
|
-
|
|
9689
|
+
const pcbMatches = this.matchedComponents.filter((c) => c.isPcbPrimitive);
|
|
9690
|
+
if (pcbMatches.length === 0) return;
|
|
9691
|
+
let matchCenter = null;
|
|
9692
|
+
if (pcbMatches.length === 1) {
|
|
9693
|
+
matchCenter = pcbMatches[0]._getPcbCircuitJsonBounds().center;
|
|
9993
9694
|
}
|
|
9994
|
-
|
|
9995
|
-
|
|
9996
|
-
|
|
9997
|
-
|
|
9998
|
-
|
|
9999
|
-
}
|
|
10000
|
-
function isValidPinLabel(pin, label) {
|
|
10001
|
-
try {
|
|
10002
|
-
const testProps = {
|
|
10003
|
-
name: "test",
|
|
10004
|
-
footprint: "test",
|
|
10005
|
-
pinLabels: { [pin]: label }
|
|
10006
|
-
};
|
|
10007
|
-
const result = chipProps.safeParse(testProps);
|
|
10008
|
-
return result.success;
|
|
10009
|
-
} catch (error) {
|
|
10010
|
-
return false;
|
|
10011
|
-
}
|
|
10012
|
-
}
|
|
10013
|
-
|
|
10014
|
-
// lib/utils/get-bounds-of-pcb-components.ts
|
|
10015
|
-
var NON_PHYSICAL_PCB_PRIMITIVE_PREFIXES = [
|
|
10016
|
-
"Silkscreen",
|
|
10017
|
-
"PcbNote",
|
|
10018
|
-
"Courtyard",
|
|
10019
|
-
"FabricationNote"
|
|
10020
|
-
];
|
|
10021
|
-
function getBoundsOfPcbComponents(components) {
|
|
10022
|
-
let minX = Infinity;
|
|
10023
|
-
let minY = Infinity;
|
|
10024
|
-
let maxX = -Infinity;
|
|
10025
|
-
let maxY = -Infinity;
|
|
10026
|
-
let hasValidComponents = false;
|
|
10027
|
-
for (const child of components) {
|
|
10028
|
-
if (child.isPcbPrimitive && !NON_PHYSICAL_PCB_PRIMITIVE_PREFIXES.some(
|
|
10029
|
-
(prefix) => child.componentName.startsWith(prefix)
|
|
10030
|
-
)) {
|
|
10031
|
-
const { x, y } = child._getGlobalPcbPositionBeforeLayout();
|
|
10032
|
-
const { width: width2, height: height2 } = child.getPcbSize();
|
|
10033
|
-
minX = Math.min(minX, x - width2 / 2);
|
|
10034
|
-
minY = Math.min(minY, y - height2 / 2);
|
|
10035
|
-
maxX = Math.max(maxX, x + width2 / 2);
|
|
10036
|
-
maxY = Math.max(maxY, y + height2 / 2);
|
|
10037
|
-
hasValidComponents = true;
|
|
10038
|
-
} else if (child.children.length > 0) {
|
|
10039
|
-
const childBounds = getBoundsOfPcbComponents(child.children);
|
|
10040
|
-
if (childBounds.width > 0 || childBounds.height > 0) {
|
|
10041
|
-
minX = Math.min(minX, childBounds.minX);
|
|
10042
|
-
minY = Math.min(minY, childBounds.minY);
|
|
10043
|
-
maxX = Math.max(maxX, childBounds.maxX);
|
|
10044
|
-
maxY = Math.max(maxY, childBounds.maxY);
|
|
10045
|
-
hasValidComponents = true;
|
|
9695
|
+
if (pcbMatches.length > 1) {
|
|
9696
|
+
try {
|
|
9697
|
+
if (areAllPcbPrimitivesOverlapping(pcbMatches)) {
|
|
9698
|
+
matchCenter = getCenterOfPcbPrimitives(pcbMatches);
|
|
9699
|
+
}
|
|
9700
|
+
} catch {
|
|
10046
9701
|
}
|
|
10047
9702
|
}
|
|
9703
|
+
if (!matchCenter) return;
|
|
9704
|
+
const parentNormalComponent = this.getParentNormalComponent();
|
|
9705
|
+
const parentWithPcbComponentId = this.parent?.pcb_component_id ? this.parent : parentNormalComponent;
|
|
9706
|
+
const subcircuit = this.getSubcircuit();
|
|
9707
|
+
const isBoardPinout = this._shouldIncludeInBoardPinout();
|
|
9708
|
+
const pcb_port = db.pcb_port.insert({
|
|
9709
|
+
pcb_component_id: parentWithPcbComponentId?.pcb_component_id,
|
|
9710
|
+
layers: this.getAvailablePcbLayers(),
|
|
9711
|
+
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
9712
|
+
pcb_group_id: this.getGroup()?.pcb_group_id ?? void 0,
|
|
9713
|
+
...isBoardPinout ? { is_board_pinout: true } : {},
|
|
9714
|
+
...matchCenter,
|
|
9715
|
+
source_port_id: this.source_port_id,
|
|
9716
|
+
is_board_pinout: this._isBoardPinoutFromAttributes()
|
|
9717
|
+
});
|
|
9718
|
+
this.pcb_port_id = pcb_port.pcb_port_id;
|
|
10048
9719
|
}
|
|
10049
|
-
|
|
10050
|
-
|
|
10051
|
-
|
|
10052
|
-
|
|
10053
|
-
|
|
10054
|
-
|
|
10055
|
-
|
|
10056
|
-
|
|
10057
|
-
|
|
10058
|
-
|
|
10059
|
-
|
|
10060
|
-
|
|
10061
|
-
|
|
10062
|
-
if (height < 0) height = 0;
|
|
10063
|
-
return {
|
|
10064
|
-
minX,
|
|
10065
|
-
minY,
|
|
10066
|
-
maxX,
|
|
10067
|
-
maxY,
|
|
10068
|
-
width,
|
|
10069
|
-
height
|
|
10070
|
-
};
|
|
10071
|
-
}
|
|
10072
|
-
|
|
10073
|
-
// lib/utils/get-relative-direction.ts
|
|
10074
|
-
function getRelativeDirection(pointA, pointB) {
|
|
10075
|
-
const dx = pointB.x - pointA.x;
|
|
10076
|
-
const dy = pointB.y - pointA.y;
|
|
10077
|
-
if (Math.abs(dx) > Math.abs(dy)) {
|
|
10078
|
-
return dx >= 0 ? "right" : "left";
|
|
10079
|
-
}
|
|
10080
|
-
return dy >= 0 ? "up" : "down";
|
|
10081
|
-
}
|
|
10082
|
-
|
|
10083
|
-
// lib/components/primitive-components/Port/Port.ts
|
|
10084
|
-
import "schematic-symbols";
|
|
10085
|
-
import { applyToPoint as applyToPoint22, compose as compose4, translate as translate3 } from "transformation-matrix";
|
|
10086
|
-
import "zod";
|
|
10087
|
-
|
|
10088
|
-
// lib/components/primitive-components/Port/getCenterOfPcbPrimitives.ts
|
|
10089
|
-
var getCenterOfPcbPrimitives = (pcbPrimitives) => {
|
|
10090
|
-
if (pcbPrimitives.length === 0) {
|
|
10091
|
-
throw new Error("Cannot get center of empty PCB primitives array");
|
|
10092
|
-
}
|
|
10093
|
-
const positions = pcbPrimitives.map((p) => p._getPcbCircuitJsonBounds().center).filter(Boolean);
|
|
10094
|
-
const sumX = positions.reduce((sum, pos) => sum + pos.x, 0);
|
|
10095
|
-
const sumY = positions.reduce((sum, pos) => sum + pos.y, 0);
|
|
10096
|
-
return {
|
|
10097
|
-
x: sumX / positions.length,
|
|
10098
|
-
y: sumY / positions.length
|
|
10099
|
-
};
|
|
10100
|
-
};
|
|
10101
|
-
|
|
10102
|
-
// lib/components/primitive-components/Port/Port.ts
|
|
10103
|
-
import { portProps } from "@tscircuit/props";
|
|
10104
|
-
|
|
10105
|
-
// lib/components/primitive-components/Port/apply-pin-attributes-to-source-port.ts
|
|
10106
|
-
var applyPinAttributesToSourcePort = (sourcePortProps, attributes) => {
|
|
10107
|
-
if (attributes.mustBeConnected !== void 0) {
|
|
10108
|
-
sourcePortProps.must_be_connected = attributes.mustBeConnected;
|
|
10109
|
-
}
|
|
10110
|
-
if (attributes.providesPower !== void 0) {
|
|
10111
|
-
sourcePortProps.provides_power = attributes.providesPower;
|
|
10112
|
-
}
|
|
10113
|
-
if (attributes.requiresPower !== void 0) {
|
|
10114
|
-
sourcePortProps.requires_power = attributes.requiresPower;
|
|
10115
|
-
}
|
|
10116
|
-
if (attributes.providesGround !== void 0) {
|
|
10117
|
-
sourcePortProps.provides_ground = attributes.providesGround;
|
|
10118
|
-
}
|
|
10119
|
-
if (attributes.requiresGround !== void 0) {
|
|
10120
|
-
sourcePortProps.requires_ground = attributes.requiresGround;
|
|
10121
|
-
}
|
|
10122
|
-
if (attributes.providesVoltage !== void 0) {
|
|
10123
|
-
sourcePortProps.provides_voltage = attributes.providesVoltage;
|
|
10124
|
-
}
|
|
10125
|
-
if (attributes.requiresVoltage !== void 0) {
|
|
10126
|
-
sourcePortProps.requires_voltage = attributes.requiresVoltage;
|
|
10127
|
-
}
|
|
10128
|
-
if (attributes.doNotConnect !== void 0) {
|
|
10129
|
-
sourcePortProps.do_not_connect = attributes.doNotConnect;
|
|
10130
|
-
}
|
|
10131
|
-
if (attributes.includeInBoardPinout !== void 0) {
|
|
10132
|
-
sourcePortProps.include_in_board_pinout = attributes.includeInBoardPinout;
|
|
10133
|
-
}
|
|
10134
|
-
if (attributes.canUseInternalPullup !== void 0) {
|
|
10135
|
-
sourcePortProps.can_use_internal_pullup = attributes.canUseInternalPullup;
|
|
10136
|
-
}
|
|
10137
|
-
if (attributes.isUsingInternalPullup !== void 0) {
|
|
10138
|
-
sourcePortProps.is_using_internal_pullup = attributes.isUsingInternalPullup;
|
|
10139
|
-
}
|
|
10140
|
-
if (attributes.needsExternalPullup !== void 0) {
|
|
10141
|
-
sourcePortProps.needs_external_pullup = attributes.needsExternalPullup;
|
|
10142
|
-
}
|
|
10143
|
-
if (attributes.canUseInternalPulldown !== void 0) {
|
|
10144
|
-
sourcePortProps.can_use_internal_pulldown = attributes.canUseInternalPulldown;
|
|
10145
|
-
}
|
|
10146
|
-
if (attributes.isUsingInternalPulldown !== void 0) {
|
|
10147
|
-
sourcePortProps.is_using_internal_pulldown = attributes.isUsingInternalPulldown;
|
|
10148
|
-
}
|
|
10149
|
-
if (attributes.needsExternalPulldown !== void 0) {
|
|
10150
|
-
sourcePortProps.needs_external_pulldown = attributes.needsExternalPulldown;
|
|
10151
|
-
}
|
|
10152
|
-
if (attributes.canUseOpenDrain !== void 0) {
|
|
10153
|
-
sourcePortProps.can_use_open_drain = attributes.canUseOpenDrain;
|
|
10154
|
-
}
|
|
10155
|
-
if (attributes.isUsingOpenDrain !== void 0) {
|
|
10156
|
-
sourcePortProps.is_using_open_drain = attributes.isUsingOpenDrain;
|
|
10157
|
-
}
|
|
10158
|
-
if (attributes.canUsePushPull !== void 0) {
|
|
10159
|
-
sourcePortProps.can_use_push_pull = attributes.canUsePushPull;
|
|
10160
|
-
}
|
|
10161
|
-
if (attributes.isUsingPushPull !== void 0) {
|
|
10162
|
-
sourcePortProps.is_using_push_pull = attributes.isUsingPushPull;
|
|
10163
|
-
}
|
|
10164
|
-
if (attributes.shouldHaveDecouplingCapacitor !== void 0) {
|
|
10165
|
-
sourcePortProps.should_have_decoupling_capacitor = attributes.shouldHaveDecouplingCapacitor;
|
|
10166
|
-
}
|
|
10167
|
-
if (attributes.recommendedDecouplingCapacitorCapacitance !== void 0) {
|
|
10168
|
-
sourcePortProps.recommended_decoupling_capacitor_capacitance = attributes.recommendedDecouplingCapacitorCapacitance;
|
|
10169
|
-
}
|
|
10170
|
-
};
|
|
10171
|
-
|
|
10172
|
-
// lib/components/primitive-components/Port/Port.ts
|
|
10173
|
-
var Port = class extends PrimitiveComponent2 {
|
|
10174
|
-
source_port_id = null;
|
|
10175
|
-
pcb_port_id = null;
|
|
10176
|
-
schematic_port_id = null;
|
|
10177
|
-
schematic_stem_line_id = null;
|
|
10178
|
-
schematicSymbolPortDef = null;
|
|
10179
|
-
matchedComponents;
|
|
10180
|
-
_isPrimaryPort = true;
|
|
10181
|
-
_primaryPinNumber = null;
|
|
10182
|
-
facingDirection = null;
|
|
10183
|
-
originDescription = null;
|
|
10184
|
-
get config() {
|
|
10185
|
-
return {
|
|
10186
|
-
componentName: "Port",
|
|
10187
|
-
zodProps: portProps
|
|
10188
|
-
};
|
|
10189
|
-
}
|
|
10190
|
-
constructor(props, opts = {}) {
|
|
10191
|
-
if (!props.name && props.pinNumber !== void 0)
|
|
10192
|
-
props.name = `pin${props.pinNumber}`;
|
|
10193
|
-
if (!props.name) {
|
|
10194
|
-
throw new Error("Port must have a name or a pinNumber");
|
|
9720
|
+
/**
|
|
9721
|
+
* Get the best display label for this port based on port_hints
|
|
9722
|
+
* Filters out generic patterns and applies showPinAliases logic
|
|
9723
|
+
*/
|
|
9724
|
+
_getBestDisplayPinLabel() {
|
|
9725
|
+
const { db } = this.root;
|
|
9726
|
+
const sourcePort = db.source_port.get(this.source_port_id);
|
|
9727
|
+
const labelHints = [];
|
|
9728
|
+
for (const portHint of sourcePort?.port_hints ?? []) {
|
|
9729
|
+
if (portHint.match(/^(pin)?\d+$/)) continue;
|
|
9730
|
+
if (portHint.match(/^(left|right)/) && !sourcePort?.name.match(/^(left|right)/))
|
|
9731
|
+
continue;
|
|
9732
|
+
labelHints.push(portHint);
|
|
10195
9733
|
}
|
|
10196
|
-
|
|
10197
|
-
|
|
10198
|
-
|
|
9734
|
+
const parentNormalComponent = this.getParentNormalComponent();
|
|
9735
|
+
const showPinAliases = parentNormalComponent?.props?.showPinAliases;
|
|
9736
|
+
if (showPinAliases && labelHints.length > 0) {
|
|
9737
|
+
return labelHints.join("/");
|
|
9738
|
+
} else if (labelHints.length > 0) {
|
|
9739
|
+
return labelHints[0];
|
|
10199
9740
|
}
|
|
10200
|
-
|
|
10201
|
-
}
|
|
10202
|
-
isGroupPort() {
|
|
10203
|
-
return this.parent?.componentName === "Group";
|
|
10204
|
-
}
|
|
10205
|
-
isComponentPort() {
|
|
10206
|
-
return !this.isGroupPort();
|
|
9741
|
+
return void 0;
|
|
10207
9742
|
}
|
|
10208
|
-
|
|
9743
|
+
doInitialSchematicPortRender() {
|
|
9744
|
+
const collapsedAncestor = this.getCollapsedSchematicBoxAncestor();
|
|
9745
|
+
if (collapsedAncestor && this.parent !== collapsedAncestor) return;
|
|
9746
|
+
const { db } = this.root;
|
|
10209
9747
|
const { _parsedProps: props } = this;
|
|
10210
|
-
const
|
|
10211
|
-
|
|
10212
|
-
|
|
10213
|
-
|
|
10214
|
-
|
|
10215
|
-
|
|
10216
|
-
|
|
10217
|
-
|
|
10218
|
-
|
|
10219
|
-
|
|
10220
|
-
}
|
|
10221
|
-
}
|
|
10222
|
-
return connectedPorts;
|
|
10223
|
-
}
|
|
10224
|
-
_isBoardPinoutFromAttributes() {
|
|
10225
|
-
const parent = this.parent;
|
|
10226
|
-
if (parent?._parsedProps?.pinAttributes) {
|
|
10227
|
-
const pinAttributes = parent._parsedProps.pinAttributes;
|
|
10228
|
-
for (const alias of this.getNameAndAliases()) {
|
|
10229
|
-
if (pinAttributes[alias]?.includeInBoardPinout) {
|
|
10230
|
-
return true;
|
|
10231
|
-
}
|
|
10232
|
-
}
|
|
10233
|
-
}
|
|
10234
|
-
}
|
|
10235
|
-
_getGlobalPcbPositionBeforeLayout() {
|
|
10236
|
-
const matchedPcbElm = this.matchedComponents.find((c) => c.isPcbPrimitive);
|
|
10237
|
-
const parentComponent = this.parent;
|
|
10238
|
-
if (parentComponent && !parentComponent.props.footprint) {
|
|
10239
|
-
throw new Error(
|
|
10240
|
-
`${parentComponent.componentName} "${parentComponent.props.name}" does not have a footprint. Add a footprint prop, e.g. <${parentComponent.componentName.toLowerCase()} footprint="..." />`
|
|
10241
|
-
);
|
|
9748
|
+
const { schX, schY } = props;
|
|
9749
|
+
const container = schX !== void 0 && schY !== void 0 ? this.getParentNormalComponent() : this.getPrimitiveContainer();
|
|
9750
|
+
if (!container) return;
|
|
9751
|
+
if (!this._hasSchematicPort()) return;
|
|
9752
|
+
const containerCenter = container._getGlobalSchematicPositionBeforeLayout();
|
|
9753
|
+
const portCenter = this._getGlobalSchematicPositionBeforeLayout();
|
|
9754
|
+
let localPortInfo = null;
|
|
9755
|
+
const containerDims = container._getSchematicBoxDimensions();
|
|
9756
|
+
if (containerDims && props.pinNumber !== void 0) {
|
|
9757
|
+
localPortInfo = containerDims.getPortPositionByPinNumber(props.pinNumber);
|
|
10242
9758
|
}
|
|
10243
|
-
if (
|
|
10244
|
-
|
|
10245
|
-
|
|
10246
|
-
|
|
9759
|
+
if (this.getSubcircuit().props._schDebugObjectsEnabled) {
|
|
9760
|
+
db.schematic_debug_object.insert({
|
|
9761
|
+
shape: "rect",
|
|
9762
|
+
center: portCenter,
|
|
9763
|
+
size: {
|
|
9764
|
+
width: 0.1,
|
|
9765
|
+
height: 0.1
|
|
9766
|
+
},
|
|
9767
|
+
label: "obstacle"
|
|
9768
|
+
});
|
|
10247
9769
|
}
|
|
10248
|
-
|
|
10249
|
-
|
|
10250
|
-
|
|
10251
|
-
|
|
10252
|
-
|
|
9770
|
+
if (!localPortInfo?.side) {
|
|
9771
|
+
this.facingDirection = getRelativeDirection(containerCenter, portCenter);
|
|
9772
|
+
} else {
|
|
9773
|
+
this.facingDirection = {
|
|
9774
|
+
left: "left",
|
|
9775
|
+
right: "right",
|
|
9776
|
+
top: "up",
|
|
9777
|
+
bottom: "down"
|
|
9778
|
+
}[localPortInfo.side];
|
|
10253
9779
|
}
|
|
10254
|
-
const
|
|
10255
|
-
const
|
|
10256
|
-
|
|
10257
|
-
|
|
10258
|
-
|
|
10259
|
-
|
|
10260
|
-
|
|
9780
|
+
const bestDisplayPinLabel = this._getBestDisplayPinLabel();
|
|
9781
|
+
const parentNormalComponent = this.getParentNormalComponent();
|
|
9782
|
+
const sideOfComponent = localPortInfo?.side ?? (props.direction === "up" ? "top" : props.direction === "down" ? "bottom" : props.direction);
|
|
9783
|
+
const schematicPortInsertProps = {
|
|
9784
|
+
type: "schematic_port",
|
|
9785
|
+
schematic_component_id: parentNormalComponent?.schematic_component_id,
|
|
9786
|
+
center: portCenter,
|
|
9787
|
+
source_port_id: this.source_port_id,
|
|
9788
|
+
facing_direction: this.facingDirection,
|
|
9789
|
+
distance_from_component_edge: props.schStemLength ?? 0.4,
|
|
9790
|
+
side_of_component: sideOfComponent,
|
|
9791
|
+
pin_number: props.pinNumber,
|
|
9792
|
+
true_ccw_index: localPortInfo?.trueIndex,
|
|
9793
|
+
display_pin_label: bestDisplayPinLabel,
|
|
9794
|
+
is_connected: false
|
|
10261
9795
|
};
|
|
10262
|
-
|
|
10263
|
-
|
|
10264
|
-
|
|
10265
|
-
|
|
10266
|
-
|
|
10267
|
-
|
|
10268
|
-
if (!parent || !parent._getInternallyConnectedPins) return [];
|
|
10269
|
-
const internallyConnectedPorts = parent._getInternallyConnectedPins();
|
|
10270
|
-
for (const ports of internallyConnectedPorts) {
|
|
10271
|
-
if (ports.some((port) => port === this)) {
|
|
10272
|
-
return ports;
|
|
9796
|
+
for (const attributes of this._getMatchingPinAttributes()) {
|
|
9797
|
+
if (attributes.requiresPower) {
|
|
9798
|
+
schematicPortInsertProps.has_input_arrow = true;
|
|
9799
|
+
}
|
|
9800
|
+
if (attributes.providesPower) {
|
|
9801
|
+
schematicPortInsertProps.has_output_arrow = true;
|
|
10273
9802
|
}
|
|
10274
9803
|
}
|
|
10275
|
-
|
|
10276
|
-
|
|
10277
|
-
|
|
10278
|
-
|
|
10279
|
-
|
|
10280
|
-
|
|
10281
|
-
|
|
10282
|
-
|
|
10283
|
-
|
|
10284
|
-
|
|
10285
|
-
|
|
10286
|
-
|
|
10287
|
-
|
|
10288
|
-
|
|
10289
|
-
|
|
10290
|
-
|
|
10291
|
-
|
|
10292
|
-
|
|
10293
|
-
|
|
10294
|
-
|
|
10295
|
-
|
|
10296
|
-
const symbol = parentNormalComponent?.getSchematicSymbol();
|
|
10297
|
-
if (symbol) {
|
|
10298
|
-
if (this.schematicSymbolPortDef) return true;
|
|
10299
|
-
const portsInternallyConnectedToThisPort = this._getPortsInternallyConnectedToThisPort();
|
|
10300
|
-
if (portsInternallyConnectedToThisPort.some((p) => p.schematicSymbolPortDef))
|
|
10301
|
-
return true;
|
|
10302
|
-
return false;
|
|
10303
|
-
}
|
|
10304
|
-
const parentBoxDim = parentNormalComponent?._getSchematicBoxDimensions();
|
|
10305
|
-
if (parentBoxDim && this._parsedProps.pinNumber !== void 0) {
|
|
10306
|
-
const localPortPosition = parentBoxDim.getPortPositionByPinNumber(
|
|
10307
|
-
this._parsedProps.pinNumber
|
|
10308
|
-
);
|
|
10309
|
-
if (localPortPosition) return true;
|
|
9804
|
+
const schematic_port = db.schematic_port.insert(schematicPortInsertProps);
|
|
9805
|
+
this.schematic_port_id = schematic_port.schematic_port_id;
|
|
9806
|
+
if (props.schStemLength !== void 0 && props.schStemLength !== 0) {
|
|
9807
|
+
const { schStemLength, direction } = props;
|
|
9808
|
+
let x2 = portCenter.x;
|
|
9809
|
+
let y2 = portCenter.y;
|
|
9810
|
+
if (direction === "right") x2 -= schStemLength;
|
|
9811
|
+
else if (direction === "left") x2 += schStemLength;
|
|
9812
|
+
else if (direction === "up") y2 -= schStemLength;
|
|
9813
|
+
else if (direction === "down") y2 += schStemLength;
|
|
9814
|
+
const stemLine = db.schematic_line.insert({
|
|
9815
|
+
schematic_component_id: parentNormalComponent?.schematic_component_id,
|
|
9816
|
+
x1: portCenter.x,
|
|
9817
|
+
y1: portCenter.y,
|
|
9818
|
+
x2,
|
|
9819
|
+
y2,
|
|
9820
|
+
stroke_width: 0.02,
|
|
9821
|
+
color: SCHEMATIC_COMPONENT_OUTLINE_COLOR,
|
|
9822
|
+
is_dashed: false
|
|
9823
|
+
});
|
|
9824
|
+
this.schematic_stem_line_id = stemLine.schematic_line_id;
|
|
10310
9825
|
}
|
|
10311
|
-
return false;
|
|
10312
9826
|
}
|
|
10313
|
-
|
|
10314
|
-
|
|
10315
|
-
if (
|
|
10316
|
-
|
|
10317
|
-
|
|
10318
|
-
|
|
10319
|
-
const
|
|
10320
|
-
|
|
10321
|
-
|
|
10322
|
-
|
|
10323
|
-
|
|
10324
|
-
|
|
10325
|
-
|
|
10326
|
-
|
|
10327
|
-
|
|
10328
|
-
|
|
9827
|
+
doInitialSchematicSymbolResize() {
|
|
9828
|
+
if (this.root?.schematicDisabled) return;
|
|
9829
|
+
if (!this.schematic_port_id) return;
|
|
9830
|
+
const symbol = this._getSymbolAncestor();
|
|
9831
|
+
const transform = symbol?.getUserCoordinateToResizedSymbolTransform();
|
|
9832
|
+
if (!transform) return;
|
|
9833
|
+
const { db } = this.root;
|
|
9834
|
+
const schPort = db.schematic_port.get(this.schematic_port_id);
|
|
9835
|
+
if (schPort) {
|
|
9836
|
+
const newCenter = applyToPoint22(transform, schPort.center);
|
|
9837
|
+
db.schematic_port.update(this.schematic_port_id, {
|
|
9838
|
+
center: newCenter
|
|
9839
|
+
});
|
|
9840
|
+
if (this.schematic_stem_line_id) {
|
|
9841
|
+
const line = db.schematic_line.get(this.schematic_stem_line_id);
|
|
9842
|
+
if (line) {
|
|
9843
|
+
const p1 = applyToPoint22(transform, { x: line.x1, y: line.y1 });
|
|
9844
|
+
const p2 = applyToPoint22(transform, { x: line.x2, y: line.y2 });
|
|
9845
|
+
db.schematic_line.update(this.schematic_stem_line_id, {
|
|
9846
|
+
x1: p1.x,
|
|
9847
|
+
y1: p1.y,
|
|
9848
|
+
x2: p2.x,
|
|
9849
|
+
y2: p2.y
|
|
9850
|
+
});
|
|
9851
|
+
const scaledStemLength = Math.sqrt(
|
|
9852
|
+
(p1.x - p2.x) ** 2 + (p1.y - p2.y) ** 2
|
|
10329
9853
|
);
|
|
9854
|
+
db.schematic_port.update(this.schematic_port_id, {
|
|
9855
|
+
distance_from_component_edge: scaledStemLength
|
|
9856
|
+
});
|
|
10330
9857
|
}
|
|
10331
9858
|
}
|
|
10332
|
-
const transform = compose4(
|
|
10333
|
-
parentNormalComponent.computeSchematicGlobalTransform(),
|
|
10334
|
-
translate3(-symbol.center.x, -symbol.center.y)
|
|
10335
|
-
);
|
|
10336
|
-
return applyToPoint22(transform, schematicSymbolPortDef);
|
|
10337
|
-
}
|
|
10338
|
-
const parentBoxDim = parentNormalComponent?._getSchematicBoxDimensions();
|
|
10339
|
-
if (parentBoxDim && this._parsedProps.pinNumber !== void 0) {
|
|
10340
|
-
const localPortPosition = parentBoxDim.getPortPositionByPinNumber(
|
|
10341
|
-
this._parsedProps.pinNumber
|
|
10342
|
-
);
|
|
10343
|
-
if (!localPortPosition) {
|
|
10344
|
-
throw new Error(
|
|
10345
|
-
`Couldn't find position for schematic_port for port ${this.getString()} inside of the schematic box`
|
|
10346
|
-
);
|
|
10347
|
-
}
|
|
10348
|
-
return applyToPoint22(
|
|
10349
|
-
parentNormalComponent.computeSchematicGlobalTransform(),
|
|
10350
|
-
localPortPosition
|
|
10351
|
-
);
|
|
10352
9859
|
}
|
|
10353
|
-
throw new Error(
|
|
10354
|
-
`Couldn't find position for schematic_port for port ${this.getString()}`
|
|
10355
|
-
);
|
|
10356
9860
|
}
|
|
10357
|
-
|
|
9861
|
+
_getSubcircuitConnectivityKey() {
|
|
9862
|
+
return this.root?.db.source_port.get(this.source_port_id)?.subcircuit_connectivity_map_key;
|
|
9863
|
+
}
|
|
9864
|
+
_setPositionFromLayout(newCenter) {
|
|
10358
9865
|
const { db } = this.root;
|
|
10359
|
-
if (!this.
|
|
10360
|
-
|
|
10361
|
-
|
|
10362
|
-
|
|
10363
|
-
}
|
|
10364
|
-
|
|
10365
|
-
|
|
10366
|
-
|
|
10367
|
-
`Schematic port not found when trying to get post-layout position: ${this.schematic_port_id}`
|
|
10368
|
-
);
|
|
10369
|
-
return schematic_port.center;
|
|
9866
|
+
if (!this.pcb_port_id) return;
|
|
9867
|
+
db.pcb_port.update(this.pcb_port_id, {
|
|
9868
|
+
x: newCenter.x,
|
|
9869
|
+
y: newCenter.y
|
|
9870
|
+
});
|
|
9871
|
+
}
|
|
9872
|
+
_hasMatchedPcbPrimitive() {
|
|
9873
|
+
return this.matchedComponents.some((c) => c.isPcbPrimitive);
|
|
10370
9874
|
}
|
|
10371
9875
|
/**
|
|
10372
|
-
*
|
|
10373
|
-
*
|
|
10374
|
-
* but
|
|
9876
|
+
* Return the text that should be used for the net label for this port if a
|
|
9877
|
+
* trace can't be drawn. This net label text usually doesn't appear at this
|
|
9878
|
+
* port, but appears at the port it connects to.
|
|
10375
9879
|
*/
|
|
10376
|
-
|
|
10377
|
-
this.
|
|
9880
|
+
_getNetLabelText() {
|
|
9881
|
+
return `${this.parent?.props.name}_${this.props.name}`;
|
|
10378
9882
|
}
|
|
10379
|
-
|
|
10380
|
-
|
|
10381
|
-
|
|
10382
|
-
|
|
10383
|
-
|
|
10384
|
-
|
|
10385
|
-
|
|
10386
|
-
|
|
10387
|
-
|
|
10388
|
-
|
|
10389
|
-
|
|
10390
|
-
|
|
10391
|
-
|
|
10392
|
-
|
|
10393
|
-
|
|
10394
|
-
const matches = [];
|
|
10395
|
-
for (const alias of this.getNameAndAliases()) {
|
|
10396
|
-
if (pinAttributes) {
|
|
10397
|
-
const attributes = pinAttributes[alias];
|
|
10398
|
-
if (attributes) {
|
|
10399
|
-
matches.push(attributes);
|
|
10400
|
-
}
|
|
10401
|
-
}
|
|
10402
|
-
if (noConnect?.includes(alias)) {
|
|
10403
|
-
matches.push({ doNotConnect: true });
|
|
10404
|
-
}
|
|
10405
|
-
}
|
|
10406
|
-
if (matches.length === 0) {
|
|
10407
|
-
return [];
|
|
10408
|
-
}
|
|
10409
|
-
return matches;
|
|
10410
|
-
}
|
|
10411
|
-
_shouldIncludeInBoardPinout() {
|
|
10412
|
-
return this._getMatchingPinAttributes().some(
|
|
10413
|
-
(attributes) => attributes.includeInBoardPinout === true
|
|
10414
|
-
);
|
|
10415
|
-
}
|
|
10416
|
-
isMatchingPort(port) {
|
|
10417
|
-
return this.isMatchingAnyOf(port.getNameAndAliases());
|
|
10418
|
-
}
|
|
10419
|
-
getPortSelector() {
|
|
10420
|
-
const parentComponent = this.getParentNormalComponent() ?? this.parent;
|
|
10421
|
-
return `.${parentComponent?.props.name} > port.${this.props.name}`;
|
|
9883
|
+
};
|
|
9884
|
+
|
|
9885
|
+
// lib/components/primitive-components/Symbol/Symbol.ts
|
|
9886
|
+
import { symbolProps } from "@tscircuit/props";
|
|
9887
|
+
import { compose as compose4, translate as translate3, scale } from "transformation-matrix";
|
|
9888
|
+
var SymbolComponent = class extends PrimitiveComponent2 {
|
|
9889
|
+
isPrimitiveContainer = true;
|
|
9890
|
+
schematic_symbol_id;
|
|
9891
|
+
userCoordinateToResizedSymbolTransformMat;
|
|
9892
|
+
schematicSymbolBoundsInUserCoordinates;
|
|
9893
|
+
get config() {
|
|
9894
|
+
return {
|
|
9895
|
+
componentName: "Symbol",
|
|
9896
|
+
zodProps: symbolProps
|
|
9897
|
+
};
|
|
10422
9898
|
}
|
|
10423
|
-
|
|
10424
|
-
const {
|
|
10425
|
-
|
|
10426
|
-
if (layer) return [layer];
|
|
10427
|
-
return Array.from(
|
|
10428
|
-
new Set(this.matchedComponents.flatMap((c) => c.getAvailablePcbLayers()))
|
|
10429
|
-
);
|
|
9899
|
+
hasExplicitSize() {
|
|
9900
|
+
const { _parsedProps: props } = this;
|
|
9901
|
+
return props.width !== void 0 || props.height !== void 0;
|
|
10430
9902
|
}
|
|
10431
9903
|
/**
|
|
10432
|
-
*
|
|
9904
|
+
* Create the schematic_symbol element in SymbolContainerRender phase.
|
|
9905
|
+
* This runs before SchematicPrimitiveRender, ensuring children can
|
|
9906
|
+
* reference the schematic_symbol_id when they render.
|
|
10433
9907
|
*/
|
|
10434
|
-
|
|
10435
|
-
|
|
10436
|
-
"trace"
|
|
10437
|
-
);
|
|
10438
|
-
const connectedTraces = allSubcircuitTraces.filter((trace) => !trace._couldNotFindPort).filter((trace) => trace._isExplicitlyConnectedToPort(this));
|
|
10439
|
-
return connectedTraces;
|
|
10440
|
-
}
|
|
10441
|
-
doInitialSourceRender() {
|
|
9908
|
+
doInitialSymbolContainerRender() {
|
|
9909
|
+
if (this.root?.schematicDisabled) return;
|
|
10442
9910
|
const { db } = this.root;
|
|
10443
9911
|
const { _parsedProps: props } = this;
|
|
10444
|
-
const
|
|
10445
|
-
const
|
|
10446
|
-
const
|
|
10447
|
-
const source_component_id = parentWithSourceId?.source_component_id ?? null;
|
|
10448
|
-
const pinAttributes = this._getMatchingPinAttributes();
|
|
10449
|
-
const portAttributesFromParent = {};
|
|
10450
|
-
for (const attributes of pinAttributes) {
|
|
10451
|
-
applyPinAttributesToSourcePort(portAttributesFromParent, attributes);
|
|
10452
|
-
}
|
|
10453
|
-
const source_port = db.source_port.insert({
|
|
9912
|
+
const parentNormal = this.getParentNormalComponent();
|
|
9913
|
+
const kicadSymbolMetadata = parentNormal?._parsedProps?.kicadSymbolMetadata;
|
|
9914
|
+
const schematic_symbol = db.schematic_symbol.insert({
|
|
10454
9915
|
name: props.name,
|
|
10455
|
-
|
|
10456
|
-
port_hints,
|
|
10457
|
-
source_component_id,
|
|
10458
|
-
subcircuit_id: this.getSubcircuit()?.subcircuit_id,
|
|
10459
|
-
...portAttributesFromParent
|
|
9916
|
+
metadata: kicadSymbolMetadata ? { kicad_symbol: kicadSymbolMetadata } : void 0
|
|
10460
9917
|
});
|
|
10461
|
-
this.
|
|
9918
|
+
this.schematic_symbol_id = schematic_symbol.schematic_symbol_id;
|
|
10462
9919
|
}
|
|
10463
|
-
|
|
10464
|
-
|
|
10465
|
-
|
|
10466
|
-
const parentWithSourceId = this.parent?.source_component_id ? this.parent : parentNormalComponent;
|
|
10467
|
-
if (this.isGroupPort()) {
|
|
10468
|
-
db.source_port.update(this.source_port_id, {
|
|
10469
|
-
source_component_id: null,
|
|
10470
|
-
subcircuit_id: this.getSubcircuit()?.subcircuit_id
|
|
10471
|
-
});
|
|
10472
|
-
return;
|
|
9920
|
+
getSchematicSymbolBounds() {
|
|
9921
|
+
if (this.schematicSymbolBoundsInUserCoordinates) {
|
|
9922
|
+
return this.schematicSymbolBoundsInUserCoordinates;
|
|
10473
9923
|
}
|
|
10474
|
-
|
|
10475
|
-
|
|
10476
|
-
|
|
10477
|
-
|
|
9924
|
+
this._computeSchematicSymbolBounds();
|
|
9925
|
+
return this.schematicSymbolBoundsInUserCoordinates ?? null;
|
|
9926
|
+
}
|
|
9927
|
+
getUserCoordinateToResizedSymbolTransform() {
|
|
9928
|
+
if (!this.hasExplicitSize()) {
|
|
9929
|
+
return null;
|
|
10478
9930
|
}
|
|
10479
|
-
|
|
10480
|
-
|
|
10481
|
-
|
|
10482
|
-
|
|
10483
|
-
this.
|
|
9931
|
+
if (this.userCoordinateToResizedSymbolTransformMat) {
|
|
9932
|
+
return this.userCoordinateToResizedSymbolTransformMat;
|
|
9933
|
+
}
|
|
9934
|
+
this._computeUserCoordinateToResizedSymbolTransform();
|
|
9935
|
+
return this.userCoordinateToResizedSymbolTransformMat ?? null;
|
|
10484
9936
|
}
|
|
10485
|
-
|
|
10486
|
-
if (this.root?.
|
|
9937
|
+
_computeSchematicSymbolBounds() {
|
|
9938
|
+
if (this.root?.schematicDisabled) return;
|
|
10487
9939
|
const { db } = this.root;
|
|
10488
|
-
const
|
|
10489
|
-
|
|
10490
|
-
|
|
10491
|
-
|
|
10492
|
-
|
|
10493
|
-
|
|
10494
|
-
|
|
10495
|
-
|
|
10496
|
-
|
|
9940
|
+
const schematicElements = [];
|
|
9941
|
+
for (const child of this.children) {
|
|
9942
|
+
if (child.componentName === "Port") {
|
|
9943
|
+
const portId = child.schematic_port_id;
|
|
9944
|
+
if (portId) {
|
|
9945
|
+
const port = db.schematic_port.get(portId);
|
|
9946
|
+
if (port) schematicElements.push(port);
|
|
9947
|
+
}
|
|
9948
|
+
continue;
|
|
10497
9949
|
}
|
|
10498
|
-
|
|
10499
|
-
|
|
10500
|
-
|
|
10501
|
-
|
|
10502
|
-
|
|
10503
|
-
|
|
10504
|
-
|
|
10505
|
-
|
|
10506
|
-
|
|
10507
|
-
|
|
10508
|
-
is_board_pinout: false
|
|
10509
|
-
});
|
|
10510
|
-
this.pcb_port_id = pcb_port.pcb_port_id;
|
|
10511
|
-
return;
|
|
10512
|
-
}
|
|
10513
|
-
const parentNormalComponent = this.getParentNormalComponent();
|
|
10514
|
-
const parentWithPcbComponentId = this.parent?.pcb_component_id ? this.parent : parentNormalComponent;
|
|
10515
|
-
if (!parentWithPcbComponentId?.pcb_component_id) {
|
|
10516
|
-
throw new Error(
|
|
10517
|
-
`${this.getString()} has no parent pcb component, cannot render pcb_port (parent: ${this.parent?.getString()}, parentNormalComponent: ${parentNormalComponent?.getString()})`
|
|
10518
|
-
);
|
|
10519
|
-
}
|
|
10520
|
-
const pcbMatches = matchedComponents.filter((c) => c.isPcbPrimitive);
|
|
10521
|
-
if (pcbMatches.length === 0) return;
|
|
10522
|
-
let matchCenter = null;
|
|
10523
|
-
if (pcbMatches.length === 1) {
|
|
10524
|
-
matchCenter = pcbMatches[0]._getPcbCircuitJsonBounds().center;
|
|
10525
|
-
}
|
|
10526
|
-
if (pcbMatches.length > 1) {
|
|
10527
|
-
if (!areAllPcbPrimitivesOverlapping(pcbMatches)) {
|
|
10528
|
-
const portName = this.props.name;
|
|
10529
|
-
const componentName = this.getParentNormalComponent()?.props.name ?? "unknown";
|
|
10530
|
-
const altAliases = this.getNameAndAliases().filter(
|
|
10531
|
-
(h) => h !== portName
|
|
9950
|
+
if (!child.isSchematicPrimitive) continue;
|
|
9951
|
+
if (child.componentName === "SchematicLine") {
|
|
9952
|
+
const line = db.schematic_line.get(child.schematic_line_id);
|
|
9953
|
+
if (line) schematicElements.push(line);
|
|
9954
|
+
} else if (child.componentName === "SchematicRect") {
|
|
9955
|
+
const rect = db.schematic_rect.get(child.schematic_rect_id);
|
|
9956
|
+
if (rect) schematicElements.push(rect);
|
|
9957
|
+
} else if (child.componentName === "SchematicCircle") {
|
|
9958
|
+
const circle = db.schematic_circle.get(
|
|
9959
|
+
child.schematic_circle_id
|
|
10532
9960
|
);
|
|
10533
|
-
|
|
10534
|
-
|
|
10535
|
-
|
|
10536
|
-
|
|
10537
|
-
|
|
10538
|
-
|
|
10539
|
-
|
|
10540
|
-
|
|
9961
|
+
if (circle) schematicElements.push(circle);
|
|
9962
|
+
} else if (child.componentName === "SchematicArc") {
|
|
9963
|
+
const arc = db.schematic_arc.get(child.schematic_arc_id);
|
|
9964
|
+
if (arc) schematicElements.push(arc);
|
|
9965
|
+
} else if (child.componentName === "SchematicText") {
|
|
9966
|
+
const text = db.schematic_text.get(child.schematic_text_id);
|
|
9967
|
+
if (text) schematicElements.push(text);
|
|
9968
|
+
} else if (child.componentName === "SchematicPath") {
|
|
9969
|
+
const pathIds = child.schematic_path_ids;
|
|
9970
|
+
if (pathIds) {
|
|
9971
|
+
for (const pathId of pathIds) {
|
|
9972
|
+
const path = db.schematic_path.get(pathId);
|
|
9973
|
+
if (path) schematicElements.push(path);
|
|
9974
|
+
}
|
|
9975
|
+
}
|
|
10541
9976
|
}
|
|
10542
|
-
matchCenter = getCenterOfPcbPrimitives(pcbMatches);
|
|
10543
|
-
}
|
|
10544
|
-
if (matchCenter) {
|
|
10545
|
-
const subcircuit = this.getSubcircuit();
|
|
10546
|
-
const isBoardPinout = this._shouldIncludeInBoardPinout();
|
|
10547
|
-
const pcb_port = db.pcb_port.insert({
|
|
10548
|
-
pcb_component_id: parentWithPcbComponentId.pcb_component_id,
|
|
10549
|
-
layers: this.getAvailablePcbLayers(),
|
|
10550
|
-
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
10551
|
-
pcb_group_id: this.getGroup()?.pcb_group_id ?? void 0,
|
|
10552
|
-
...isBoardPinout ? { is_board_pinout: true } : {},
|
|
10553
|
-
...matchCenter,
|
|
10554
|
-
source_port_id: this.source_port_id,
|
|
10555
|
-
is_board_pinout: this._isBoardPinoutFromAttributes()
|
|
10556
|
-
});
|
|
10557
|
-
this.pcb_port_id = pcb_port.pcb_port_id;
|
|
10558
|
-
} else {
|
|
10559
|
-
const pcbMatch = pcbMatches[0];
|
|
10560
|
-
throw new Error(
|
|
10561
|
-
`${pcbMatch.getString()} does not have a center or _getGlobalPcbPositionBeforeLayout method (needed for pcb_port placement)`
|
|
10562
|
-
);
|
|
10563
9977
|
}
|
|
9978
|
+
if (schematicElements.length === 0) return;
|
|
9979
|
+
const bounds = getBoundsForSchematic(schematicElements);
|
|
9980
|
+
this.schematicSymbolBoundsInUserCoordinates = bounds;
|
|
10564
9981
|
}
|
|
10565
|
-
|
|
10566
|
-
|
|
10567
|
-
|
|
10568
|
-
|
|
10569
|
-
|
|
10570
|
-
|
|
10571
|
-
|
|
10572
|
-
|
|
10573
|
-
|
|
10574
|
-
|
|
10575
|
-
|
|
10576
|
-
|
|
10577
|
-
|
|
10578
|
-
|
|
10579
|
-
|
|
10580
|
-
|
|
10581
|
-
|
|
10582
|
-
|
|
10583
|
-
|
|
10584
|
-
|
|
10585
|
-
|
|
10586
|
-
|
|
10587
|
-
|
|
10588
|
-
|
|
10589
|
-
|
|
10590
|
-
|
|
10591
|
-
|
|
10592
|
-
|
|
10593
|
-
|
|
10594
|
-
|
|
10595
|
-
|
|
10596
|
-
|
|
10597
|
-
|
|
10598
|
-
|
|
10599
|
-
|
|
10600
|
-
|
|
10601
|
-
|
|
9982
|
+
_computeUserCoordinateToResizedSymbolTransform() {
|
|
9983
|
+
const bounds = this.getSchematicSymbolBounds();
|
|
9984
|
+
if (!bounds) return;
|
|
9985
|
+
const { _parsedProps: props } = this;
|
|
9986
|
+
const targetWidth = props.width;
|
|
9987
|
+
const targetHeight = props.height;
|
|
9988
|
+
if (targetWidth === void 0 && targetHeight === void 0) return;
|
|
9989
|
+
const currentWidth = bounds.maxX - bounds.minX;
|
|
9990
|
+
const currentHeight = bounds.maxY - bounds.minY;
|
|
9991
|
+
if (currentWidth === 0 && currentHeight === 0) return;
|
|
9992
|
+
const currentCenterX = (bounds.minX + bounds.maxX) / 2;
|
|
9993
|
+
const currentCenterY = (bounds.minY + bounds.maxY) / 2;
|
|
9994
|
+
const scaleX = targetWidth !== void 0 && currentWidth > 0 ? targetWidth / currentWidth : 1;
|
|
9995
|
+
const scaleY = targetHeight !== void 0 && currentHeight > 0 ? targetHeight / currentHeight : 1;
|
|
9996
|
+
const globalPos = this._getGlobalSchematicPositionBeforeLayout();
|
|
9997
|
+
this.userCoordinateToResizedSymbolTransformMat = compose4(
|
|
9998
|
+
translate3(globalPos.x, globalPos.y),
|
|
9999
|
+
scale(scaleX, scaleY),
|
|
10000
|
+
translate3(-currentCenterX, -currentCenterY)
|
|
10001
|
+
);
|
|
10002
|
+
}
|
|
10003
|
+
};
|
|
10004
|
+
|
|
10005
|
+
// lib/utils/createPinrowSilkscreenText.ts
|
|
10006
|
+
var createPinrowSilkscreenText = ({
|
|
10007
|
+
elm,
|
|
10008
|
+
pinLabels,
|
|
10009
|
+
layer,
|
|
10010
|
+
readableRotation,
|
|
10011
|
+
anchorAlignment
|
|
10012
|
+
}) => {
|
|
10013
|
+
const pinNum = elm.text.replace(/[{}]/g, "").toLowerCase();
|
|
10014
|
+
let label = pinNum;
|
|
10015
|
+
if (Array.isArray(pinLabels)) {
|
|
10016
|
+
const index = parseInt(pinNum.replace(/[^\d]/g, ""), 10) - 1;
|
|
10017
|
+
label = String(pinLabels[index] ?? pinNum);
|
|
10018
|
+
} else if (typeof pinLabels === "object") {
|
|
10019
|
+
label = String(pinLabels[pinNum] ?? pinNum);
|
|
10020
|
+
}
|
|
10021
|
+
const silkscreenText = new SilkscreenText({
|
|
10022
|
+
anchorAlignment: anchorAlignment || "center",
|
|
10023
|
+
text: label ?? pinNum,
|
|
10024
|
+
layer: layer || "top",
|
|
10025
|
+
pcbX: isNaN(elm.anchor_position.x) ? 0 : elm.anchor_position.x,
|
|
10026
|
+
pcbY: elm.anchor_position.y,
|
|
10027
|
+
pcbRotation: readableRotation ?? 0
|
|
10028
|
+
});
|
|
10029
|
+
silkscreenText._footprinterFontSize = elm.font_size + 0.2;
|
|
10030
|
+
return silkscreenText;
|
|
10031
|
+
};
|
|
10032
|
+
|
|
10033
|
+
// lib/utils/createComponentsFromCircuitJson.ts
|
|
10034
|
+
var calculateCcwRotation = (componentRotationStr, elementCcwRotation) => {
|
|
10035
|
+
const componentAngle = parseInt(componentRotationStr || "0", 10);
|
|
10036
|
+
let totalRotation;
|
|
10037
|
+
if (elementCcwRotation !== void 0 && elementCcwRotation !== null) {
|
|
10038
|
+
totalRotation = elementCcwRotation - componentAngle;
|
|
10039
|
+
} else {
|
|
10040
|
+
totalRotation = componentAngle;
|
|
10041
|
+
}
|
|
10042
|
+
const normalizedRotation = (totalRotation % 360 + 360) % 360;
|
|
10043
|
+
return normalizedRotation;
|
|
10044
|
+
};
|
|
10045
|
+
var optional = (value) => value ?? void 0;
|
|
10046
|
+
var getFacingDirectionFromSide = (side) => {
|
|
10047
|
+
switch (side) {
|
|
10048
|
+
case "left":
|
|
10049
|
+
case "right":
|
|
10050
|
+
return side;
|
|
10051
|
+
case "top":
|
|
10052
|
+
return "up";
|
|
10053
|
+
case "bottom":
|
|
10054
|
+
return "down";
|
|
10055
|
+
}
|
|
10056
|
+
return null;
|
|
10057
|
+
};
|
|
10058
|
+
var schematicPrimitiveTypesWithStrokeWidth = [
|
|
10059
|
+
"schematic_line",
|
|
10060
|
+
"schematic_rect",
|
|
10061
|
+
"schematic_circle",
|
|
10062
|
+
"schematic_arc",
|
|
10063
|
+
"schematic_path"
|
|
10064
|
+
];
|
|
10065
|
+
var isSchematicPrimitiveWithStrokeWidth = (elm) => schematicPrimitiveTypesWithStrokeWidth.includes(
|
|
10066
|
+
elm.type
|
|
10067
|
+
);
|
|
10068
|
+
var getSchematicSymbolId = (elm) => {
|
|
10069
|
+
if (!("schematic_symbol_id" in elm)) return void 0;
|
|
10070
|
+
return typeof elm.schematic_symbol_id === "string" ? elm.schematic_symbol_id : void 0;
|
|
10071
|
+
};
|
|
10072
|
+
var createComponentsFromCircuitJson = ({
|
|
10073
|
+
componentName,
|
|
10074
|
+
componentRotation,
|
|
10075
|
+
footprinterString,
|
|
10076
|
+
pinLabels,
|
|
10077
|
+
pcbPinLabels
|
|
10078
|
+
}, circuitJson) => {
|
|
10079
|
+
const components = [];
|
|
10080
|
+
const schematicSymbolsByImportedId = /* @__PURE__ */ new Map();
|
|
10081
|
+
const schematicComponentsByImportedId = /* @__PURE__ */ new Map();
|
|
10082
|
+
const sourcePortsByImportedId = /* @__PURE__ */ new Map();
|
|
10083
|
+
const schematicStrokeWidthBySymbolId = /* @__PURE__ */ new Map();
|
|
10084
|
+
for (const elm of circuitJson) {
|
|
10085
|
+
if (elm.type === "source_port") {
|
|
10086
|
+
sourcePortsByImportedId.set(elm.source_port_id, elm);
|
|
10602
10087
|
}
|
|
10603
|
-
|
|
10604
|
-
|
|
10605
|
-
|
|
10606
|
-
const
|
|
10607
|
-
|
|
10608
|
-
const pcb_port = db.pcb_port.insert({
|
|
10609
|
-
pcb_component_id: parentWithPcbComponentId?.pcb_component_id,
|
|
10610
|
-
layers: this.getAvailablePcbLayers(),
|
|
10611
|
-
subcircuit_id: subcircuit?.subcircuit_id ?? void 0,
|
|
10612
|
-
pcb_group_id: this.getGroup()?.pcb_group_id ?? void 0,
|
|
10613
|
-
...isBoardPinout ? { is_board_pinout: true } : {},
|
|
10614
|
-
...matchCenter,
|
|
10615
|
-
source_port_id: this.source_port_id,
|
|
10616
|
-
is_board_pinout: this._isBoardPinoutFromAttributes()
|
|
10088
|
+
}
|
|
10089
|
+
for (const elm of circuitJson) {
|
|
10090
|
+
if (elm.type !== "schematic_symbol") continue;
|
|
10091
|
+
const schematicSymbol = new SymbolComponent({
|
|
10092
|
+
name: elm.name
|
|
10617
10093
|
});
|
|
10618
|
-
|
|
10094
|
+
schematicSymbolsByImportedId.set(elm.schematic_symbol_id, schematicSymbol);
|
|
10095
|
+
components.push(schematicSymbol);
|
|
10619
10096
|
}
|
|
10620
|
-
|
|
10621
|
-
|
|
10622
|
-
|
|
10623
|
-
|
|
10624
|
-
|
|
10625
|
-
|
|
10626
|
-
const sourcePort = db.source_port.get(this.source_port_id);
|
|
10627
|
-
const labelHints = [];
|
|
10628
|
-
for (const portHint of sourcePort?.port_hints ?? []) {
|
|
10629
|
-
if (portHint.match(/^(pin)?\d+$/)) continue;
|
|
10630
|
-
if (portHint.match(/^(left|right)/) && !sourcePort?.name.match(/^(left|right)/))
|
|
10631
|
-
continue;
|
|
10632
|
-
labelHints.push(portHint);
|
|
10097
|
+
for (const elm of circuitJson) {
|
|
10098
|
+
if (!isSchematicPrimitiveWithStrokeWidth(elm)) continue;
|
|
10099
|
+
const schematicSymbolId = getSchematicSymbolId(elm);
|
|
10100
|
+
const strokeWidth = elm.stroke_width;
|
|
10101
|
+
if (!schematicSymbolId || typeof strokeWidth !== "number" || !Number.isFinite(strokeWidth) || schematicStrokeWidthBySymbolId.has(schematicSymbolId)) {
|
|
10102
|
+
continue;
|
|
10633
10103
|
}
|
|
10634
|
-
|
|
10635
|
-
|
|
10636
|
-
|
|
10637
|
-
|
|
10638
|
-
|
|
10639
|
-
|
|
10104
|
+
schematicStrokeWidthBySymbolId.set(schematicSymbolId, strokeWidth);
|
|
10105
|
+
}
|
|
10106
|
+
for (const elm of circuitJson) {
|
|
10107
|
+
if (elm.type !== "schematic_component") continue;
|
|
10108
|
+
schematicComponentsByImportedId.set(elm.schematic_component_id, elm);
|
|
10109
|
+
}
|
|
10110
|
+
const addSchematicPrimitive = (elm, primitive) => {
|
|
10111
|
+
const schematicSymbolId = getSchematicSymbolId(elm);
|
|
10112
|
+
const parentSymbol = schematicSymbolId ? schematicSymbolsByImportedId.get(schematicSymbolId) : void 0;
|
|
10113
|
+
if (parentSymbol) {
|
|
10114
|
+
parentSymbol.add(primitive);
|
|
10115
|
+
} else {
|
|
10116
|
+
components.push(primitive);
|
|
10117
|
+
}
|
|
10118
|
+
};
|
|
10119
|
+
for (const elm of circuitJson) {
|
|
10120
|
+
if (elm.type === "pcb_smtpad" && elm.shape === "rect") {
|
|
10121
|
+
components.push(
|
|
10122
|
+
new SmtPad({
|
|
10123
|
+
pcbX: elm.x,
|
|
10124
|
+
pcbY: elm.y,
|
|
10125
|
+
layer: elm.layer,
|
|
10126
|
+
shape: "rect",
|
|
10127
|
+
height: elm.height,
|
|
10128
|
+
width: elm.width,
|
|
10129
|
+
portHints: elm.port_hints,
|
|
10130
|
+
rectBorderRadius: elm.rect_border_radius
|
|
10131
|
+
})
|
|
10132
|
+
);
|
|
10133
|
+
} else if (elm.type === "pcb_smtpad" && elm.shape === "circle") {
|
|
10134
|
+
components.push(
|
|
10135
|
+
new SmtPad({
|
|
10136
|
+
pcbX: elm.x,
|
|
10137
|
+
pcbY: elm.y,
|
|
10138
|
+
layer: elm.layer,
|
|
10139
|
+
shape: "circle",
|
|
10140
|
+
radius: elm.radius,
|
|
10141
|
+
portHints: elm.port_hints
|
|
10142
|
+
})
|
|
10143
|
+
);
|
|
10144
|
+
} else if (elm.type === "pcb_smtpad" && elm.shape === "pill") {
|
|
10145
|
+
components.push(
|
|
10146
|
+
new SmtPad({
|
|
10147
|
+
shape: "pill",
|
|
10148
|
+
height: elm.height,
|
|
10149
|
+
width: elm.width,
|
|
10150
|
+
radius: elm.radius,
|
|
10151
|
+
portHints: elm.port_hints,
|
|
10152
|
+
pcbX: elm.x,
|
|
10153
|
+
pcbY: elm.y,
|
|
10154
|
+
layer: elm.layer
|
|
10155
|
+
})
|
|
10156
|
+
);
|
|
10157
|
+
} else if (elm.type === "pcb_smtpad" && elm.shape === "polygon") {
|
|
10158
|
+
components.push(
|
|
10159
|
+
new SmtPad({
|
|
10160
|
+
shape: "polygon",
|
|
10161
|
+
points: elm.points,
|
|
10162
|
+
portHints: elm.port_hints,
|
|
10163
|
+
layer: elm.layer
|
|
10164
|
+
})
|
|
10165
|
+
);
|
|
10166
|
+
} else if (elm.type === "pcb_silkscreen_path") {
|
|
10167
|
+
components.push(
|
|
10168
|
+
new SilkscreenPath({
|
|
10169
|
+
layer: elm.layer,
|
|
10170
|
+
route: elm.route,
|
|
10171
|
+
strokeWidth: elm.stroke_width
|
|
10172
|
+
})
|
|
10173
|
+
);
|
|
10174
|
+
} else if (elm.type === "pcb_copper_text") {
|
|
10175
|
+
components.push(
|
|
10176
|
+
new CopperText({
|
|
10177
|
+
text: elm.text,
|
|
10178
|
+
pcbX: elm.anchor_position.x,
|
|
10179
|
+
pcbY: elm.anchor_position.y,
|
|
10180
|
+
pcbRotation: elm.ccw_rotation,
|
|
10181
|
+
anchorAlignment: elm.anchor_alignment,
|
|
10182
|
+
fontSize: elm.font_size,
|
|
10183
|
+
layer: elm.layer,
|
|
10184
|
+
mirrored: elm.is_mirrored,
|
|
10185
|
+
knockout: elm.is_knockout
|
|
10186
|
+
})
|
|
10187
|
+
);
|
|
10188
|
+
} else if (elm.type === "pcb_plated_hole") {
|
|
10189
|
+
if (elm.shape === "circle") {
|
|
10190
|
+
components.push(
|
|
10191
|
+
new PlatedHole({
|
|
10192
|
+
pcbX: elm.x,
|
|
10193
|
+
pcbY: elm.y,
|
|
10194
|
+
shape: "circle",
|
|
10195
|
+
holeDiameter: elm.hole_diameter,
|
|
10196
|
+
outerDiameter: elm.outer_diameter,
|
|
10197
|
+
portHints: elm.port_hints
|
|
10198
|
+
})
|
|
10199
|
+
);
|
|
10200
|
+
} else if (elm.shape === "circular_hole_with_rect_pad") {
|
|
10201
|
+
components.push(
|
|
10202
|
+
new PlatedHole({
|
|
10203
|
+
pcbX: elm.x,
|
|
10204
|
+
pcbY: elm.y,
|
|
10205
|
+
shape: "circular_hole_with_rect_pad",
|
|
10206
|
+
holeDiameter: elm.hole_diameter,
|
|
10207
|
+
rectPadHeight: elm.rect_pad_height,
|
|
10208
|
+
rectPadWidth: elm.rect_pad_width,
|
|
10209
|
+
portHints: elm.port_hints,
|
|
10210
|
+
rectBorderRadius: elm.rect_border_radius,
|
|
10211
|
+
holeOffsetX: elm.hole_offset_x,
|
|
10212
|
+
holeOffsetY: elm.hole_offset_y
|
|
10213
|
+
})
|
|
10214
|
+
);
|
|
10215
|
+
} else if (elm.shape === "pill" || elm.shape === "oval") {
|
|
10216
|
+
components.push(
|
|
10217
|
+
new PlatedHole({
|
|
10218
|
+
pcbX: elm.x,
|
|
10219
|
+
pcbY: elm.y,
|
|
10220
|
+
shape: elm.shape,
|
|
10221
|
+
holeWidth: elm.hole_width,
|
|
10222
|
+
holeHeight: elm.hole_height,
|
|
10223
|
+
outerWidth: elm.outer_width,
|
|
10224
|
+
outerHeight: elm.outer_height,
|
|
10225
|
+
portHints: elm.port_hints
|
|
10226
|
+
})
|
|
10227
|
+
);
|
|
10228
|
+
} else if (elm.shape === "pill_hole_with_rect_pad") {
|
|
10229
|
+
components.push(
|
|
10230
|
+
new PlatedHole({
|
|
10231
|
+
pcbX: elm.x,
|
|
10232
|
+
pcbY: elm.y,
|
|
10233
|
+
shape: "pill_hole_with_rect_pad",
|
|
10234
|
+
holeShape: "pill",
|
|
10235
|
+
padShape: "rect",
|
|
10236
|
+
holeWidth: elm.hole_width,
|
|
10237
|
+
holeHeight: elm.hole_height,
|
|
10238
|
+
rectPadWidth: elm.rect_pad_width,
|
|
10239
|
+
rectPadHeight: elm.rect_pad_height,
|
|
10240
|
+
rectBorderRadius: elm.rect_border_radius,
|
|
10241
|
+
portHints: elm.port_hints,
|
|
10242
|
+
holeOffsetX: elm.hole_offset_x,
|
|
10243
|
+
holeOffsetY: elm.hole_offset_y
|
|
10244
|
+
})
|
|
10245
|
+
);
|
|
10246
|
+
} else if (elm.shape === "rotated_pill_hole_with_rect_pad") {
|
|
10247
|
+
components.push(
|
|
10248
|
+
new PlatedHole({
|
|
10249
|
+
pcbX: elm.x,
|
|
10250
|
+
pcbY: elm.y,
|
|
10251
|
+
shape: "pill_hole_with_rect_pad",
|
|
10252
|
+
holeShape: "pill",
|
|
10253
|
+
padShape: "rect",
|
|
10254
|
+
holeWidth: elm.hole_width,
|
|
10255
|
+
holeHeight: elm.hole_height,
|
|
10256
|
+
rectPadWidth: elm.rect_pad_width,
|
|
10257
|
+
rectPadHeight: elm.rect_pad_height,
|
|
10258
|
+
rectBorderRadius: elm.rect_border_radius,
|
|
10259
|
+
portHints: elm.port_hints,
|
|
10260
|
+
holeOffsetX: elm.hole_offset_x,
|
|
10261
|
+
holeOffsetY: elm.hole_offset_y,
|
|
10262
|
+
pcbRotation: elm.hole_ccw_rotation
|
|
10263
|
+
})
|
|
10264
|
+
);
|
|
10265
|
+
} else if (elm.shape === "hole_with_polygon_pad") {
|
|
10266
|
+
components.push(
|
|
10267
|
+
new PlatedHole({
|
|
10268
|
+
pcbX: elm.x,
|
|
10269
|
+
pcbY: elm.y,
|
|
10270
|
+
shape: "hole_with_polygon_pad",
|
|
10271
|
+
holeShape: elm.hole_shape || "circle",
|
|
10272
|
+
holeDiameter: elm.hole_diameter,
|
|
10273
|
+
holeWidth: elm.hole_width,
|
|
10274
|
+
holeHeight: elm.hole_height,
|
|
10275
|
+
padOutline: elm.pad_outline || [],
|
|
10276
|
+
holeOffsetX: elm.hole_offset_x,
|
|
10277
|
+
holeOffsetY: elm.hole_offset_y,
|
|
10278
|
+
portHints: elm.port_hints
|
|
10279
|
+
})
|
|
10280
|
+
);
|
|
10281
|
+
}
|
|
10282
|
+
} else if (elm.type === "pcb_keepout" && elm.shape === "circle") {
|
|
10283
|
+
components.push(
|
|
10284
|
+
new Keepout({
|
|
10285
|
+
pcbX: elm.center.x,
|
|
10286
|
+
pcbY: elm.center.y,
|
|
10287
|
+
shape: "circle",
|
|
10288
|
+
radius: elm.radius
|
|
10289
|
+
})
|
|
10290
|
+
);
|
|
10291
|
+
} else if (elm.type === "pcb_keepout" && elm.shape === "rect") {
|
|
10292
|
+
components.push(
|
|
10293
|
+
new Keepout({
|
|
10294
|
+
pcbX: elm.center.x,
|
|
10295
|
+
pcbY: elm.center.y,
|
|
10296
|
+
shape: "rect",
|
|
10297
|
+
width: elm.width,
|
|
10298
|
+
height: elm.height
|
|
10299
|
+
})
|
|
10300
|
+
);
|
|
10301
|
+
} else if (elm.type === "pcb_hole" && elm.hole_shape === "circle") {
|
|
10302
|
+
components.push(
|
|
10303
|
+
new Hole({
|
|
10304
|
+
pcbX: elm.x,
|
|
10305
|
+
pcbY: elm.y,
|
|
10306
|
+
diameter: elm.hole_diameter
|
|
10307
|
+
})
|
|
10308
|
+
);
|
|
10309
|
+
} else if (elm.type === "pcb_hole" && elm.hole_shape === "rect") {
|
|
10310
|
+
components.push(
|
|
10311
|
+
new Hole({
|
|
10312
|
+
pcbX: elm.x,
|
|
10313
|
+
pcbY: elm.y,
|
|
10314
|
+
shape: "rect",
|
|
10315
|
+
width: elm.hole_width,
|
|
10316
|
+
height: elm.hole_height
|
|
10317
|
+
})
|
|
10318
|
+
);
|
|
10319
|
+
} else if (elm.type === "pcb_hole" && elm.hole_shape === "pill") {
|
|
10320
|
+
components.push(
|
|
10321
|
+
new Hole({
|
|
10322
|
+
pcbX: elm.x,
|
|
10323
|
+
pcbY: elm.y,
|
|
10324
|
+
shape: "pill",
|
|
10325
|
+
width: elm.hole_width,
|
|
10326
|
+
height: elm.hole_height
|
|
10327
|
+
})
|
|
10328
|
+
);
|
|
10329
|
+
} else if (elm.type === "pcb_hole" && elm.hole_shape === "oval") {
|
|
10330
|
+
components.push(
|
|
10331
|
+
new Hole({
|
|
10332
|
+
pcbX: elm.x,
|
|
10333
|
+
pcbY: elm.y,
|
|
10334
|
+
shape: "oval",
|
|
10335
|
+
width: elm.hole_width,
|
|
10336
|
+
height: elm.hole_height
|
|
10337
|
+
})
|
|
10338
|
+
);
|
|
10339
|
+
} else if (elm.type === "pcb_hole" && elm.hole_shape === "rotated_pill") {
|
|
10340
|
+
components.push(
|
|
10341
|
+
new Hole({
|
|
10342
|
+
pcbX: elm.x,
|
|
10343
|
+
pcbY: elm.y,
|
|
10344
|
+
shape: "pill",
|
|
10345
|
+
width: elm.hole_width,
|
|
10346
|
+
height: elm.hole_height,
|
|
10347
|
+
pcbRotation: elm.ccw_rotation
|
|
10348
|
+
})
|
|
10349
|
+
);
|
|
10350
|
+
} else if (elm.type === "pcb_cutout") {
|
|
10351
|
+
if (elm.shape === "rect") {
|
|
10352
|
+
components.push(
|
|
10353
|
+
new Cutout({
|
|
10354
|
+
pcbX: elm.center.x,
|
|
10355
|
+
pcbY: elm.center.y,
|
|
10356
|
+
shape: "rect",
|
|
10357
|
+
width: elm.width,
|
|
10358
|
+
height: elm.height
|
|
10359
|
+
})
|
|
10360
|
+
);
|
|
10361
|
+
} else if (elm.shape === "circle") {
|
|
10362
|
+
components.push(
|
|
10363
|
+
new Cutout({
|
|
10364
|
+
pcbX: elm.center.x,
|
|
10365
|
+
pcbY: elm.center.y,
|
|
10366
|
+
shape: "circle",
|
|
10367
|
+
radius: elm.radius
|
|
10368
|
+
})
|
|
10369
|
+
);
|
|
10370
|
+
} else if (elm.shape === "polygon") {
|
|
10371
|
+
components.push(
|
|
10372
|
+
new Cutout({
|
|
10373
|
+
shape: "polygon",
|
|
10374
|
+
points: elm.points
|
|
10375
|
+
})
|
|
10376
|
+
);
|
|
10377
|
+
}
|
|
10378
|
+
} else if (elm.type === "pcb_silkscreen_text") {
|
|
10379
|
+
const ccwRotation = calculateCcwRotation(
|
|
10380
|
+
componentRotation,
|
|
10381
|
+
elm.ccw_rotation
|
|
10382
|
+
);
|
|
10383
|
+
if (footprinterString?.includes("pinrow") && elm.text.includes("PIN")) {
|
|
10384
|
+
components.push(
|
|
10385
|
+
createPinrowSilkscreenText({
|
|
10386
|
+
elm,
|
|
10387
|
+
pinLabels: pcbPinLabels ?? pinLabels ?? {},
|
|
10388
|
+
layer: elm.layer,
|
|
10389
|
+
readableRotation: ccwRotation,
|
|
10390
|
+
anchorAlignment: elm.anchor_alignment
|
|
10391
|
+
})
|
|
10392
|
+
);
|
|
10393
|
+
} else {
|
|
10394
|
+
const silkscreenText = new SilkscreenText({
|
|
10395
|
+
anchorAlignment: elm.anchor_alignment || "center",
|
|
10396
|
+
text: componentName || elm.text,
|
|
10397
|
+
pcbX: Number.isNaN(elm.anchor_position.x) ? 0 : elm.anchor_position.x,
|
|
10398
|
+
pcbY: elm.anchor_position.y,
|
|
10399
|
+
pcbRotation: ccwRotation ?? 0
|
|
10400
|
+
});
|
|
10401
|
+
silkscreenText._footprinterFontSize = elm.font_size + 0.2;
|
|
10402
|
+
components.push(silkscreenText);
|
|
10403
|
+
}
|
|
10404
|
+
} else if (elm.type === "pcb_trace") {
|
|
10405
|
+
components.push(
|
|
10406
|
+
new PcbTrace({
|
|
10407
|
+
route: elm.route
|
|
10408
|
+
})
|
|
10409
|
+
);
|
|
10410
|
+
} else if (elm.type === "pcb_via") {
|
|
10411
|
+
const layers = elm.layers ?? [];
|
|
10412
|
+
const pcbVia = new PcbVia({
|
|
10413
|
+
pcbX: elm.x,
|
|
10414
|
+
pcbY: elm.y,
|
|
10415
|
+
holeDiameter: elm.hole_diameter,
|
|
10416
|
+
outerDiameter: elm.outer_diameter,
|
|
10417
|
+
fromLayer: elm.from_layer ?? layers[0],
|
|
10418
|
+
toLayer: elm.to_layer ?? layers[layers.length - 1],
|
|
10419
|
+
layers,
|
|
10420
|
+
netIsAssignable: elm.net_is_assignable,
|
|
10421
|
+
isTented: elm.is_tented
|
|
10422
|
+
});
|
|
10423
|
+
pcbVia._importedPcbTraceId = elm.pcb_trace_id;
|
|
10424
|
+
components.push(pcbVia);
|
|
10425
|
+
} else if (elm.type === "pcb_silkscreen_rect") {
|
|
10426
|
+
components.push(
|
|
10427
|
+
new SilkscreenRect({
|
|
10428
|
+
pcbX: elm.center.x,
|
|
10429
|
+
pcbY: elm.center.y,
|
|
10430
|
+
width: elm.width,
|
|
10431
|
+
height: elm.height,
|
|
10432
|
+
layer: elm.layer,
|
|
10433
|
+
strokeWidth: elm.stroke_width,
|
|
10434
|
+
filled: elm.is_filled,
|
|
10435
|
+
cornerRadius: elm.corner_radius
|
|
10436
|
+
})
|
|
10437
|
+
);
|
|
10438
|
+
} else if (elm.type === "pcb_silkscreen_circle") {
|
|
10439
|
+
components.push(
|
|
10440
|
+
new SilkscreenCircle({
|
|
10441
|
+
pcbX: elm.center.x,
|
|
10442
|
+
pcbY: elm.center.y,
|
|
10443
|
+
radius: elm.radius,
|
|
10444
|
+
layer: elm.layer,
|
|
10445
|
+
strokeWidth: elm.stroke_width
|
|
10446
|
+
})
|
|
10447
|
+
);
|
|
10448
|
+
} else if (elm.type === "pcb_silkscreen_line") {
|
|
10449
|
+
components.push(
|
|
10450
|
+
new SilkscreenLine({
|
|
10451
|
+
x1: elm.x1,
|
|
10452
|
+
y1: elm.y1,
|
|
10453
|
+
x2: elm.x2,
|
|
10454
|
+
y2: elm.y2,
|
|
10455
|
+
layer: elm.layer,
|
|
10456
|
+
strokeWidth: elm.stroke_width
|
|
10457
|
+
})
|
|
10458
|
+
);
|
|
10459
|
+
} else if (elm.type === "pcb_fabrication_note_text") {
|
|
10460
|
+
components.push(
|
|
10461
|
+
new FabricationNoteText({
|
|
10462
|
+
pcbX: elm.anchor_position.x,
|
|
10463
|
+
pcbY: elm.anchor_position.y,
|
|
10464
|
+
text: elm.text,
|
|
10465
|
+
fontSize: elm.font_size,
|
|
10466
|
+
anchorAlignment: elm.anchor_alignment,
|
|
10467
|
+
color: elm.color,
|
|
10468
|
+
font: elm.font
|
|
10469
|
+
})
|
|
10470
|
+
);
|
|
10471
|
+
} else if (elm.type === "pcb_fabrication_note_path") {
|
|
10472
|
+
components.push(
|
|
10473
|
+
new FabricationNotePath({
|
|
10474
|
+
route: elm.route,
|
|
10475
|
+
strokeWidth: elm.stroke_width,
|
|
10476
|
+
color: elm.color,
|
|
10477
|
+
layer: elm.layer
|
|
10478
|
+
})
|
|
10479
|
+
);
|
|
10480
|
+
} else if (elm.type === "pcb_fabrication_note_rect") {
|
|
10481
|
+
components.push(
|
|
10482
|
+
new FabricationNoteRect({
|
|
10483
|
+
pcbX: elm.center.x,
|
|
10484
|
+
pcbY: elm.center.y,
|
|
10485
|
+
width: elm.width,
|
|
10486
|
+
height: elm.height,
|
|
10487
|
+
strokeWidth: elm.stroke_width,
|
|
10488
|
+
isFilled: elm.is_filled,
|
|
10489
|
+
color: elm.color,
|
|
10490
|
+
layer: elm.layer,
|
|
10491
|
+
cornerRadius: elm.corner_radius,
|
|
10492
|
+
hasStroke: elm.has_stroke,
|
|
10493
|
+
isStrokeDashed: elm.is_stroke_dashed
|
|
10494
|
+
})
|
|
10495
|
+
);
|
|
10496
|
+
} else if (elm.type === "pcb_note_text") {
|
|
10497
|
+
components.push(
|
|
10498
|
+
new PcbNoteText({
|
|
10499
|
+
pcbX: elm.anchor_position.x,
|
|
10500
|
+
pcbY: elm.anchor_position.y,
|
|
10501
|
+
text: elm.text ?? "",
|
|
10502
|
+
fontSize: elm.font_size,
|
|
10503
|
+
anchorAlignment: elm.anchor_alignment,
|
|
10504
|
+
color: elm.color,
|
|
10505
|
+
font: elm.font
|
|
10506
|
+
})
|
|
10507
|
+
);
|
|
10508
|
+
} else if (elm.type === "pcb_note_rect") {
|
|
10509
|
+
components.push(
|
|
10510
|
+
new PcbNoteRect({
|
|
10511
|
+
pcbX: elm.center.x,
|
|
10512
|
+
pcbY: elm.center.y,
|
|
10513
|
+
width: elm.width,
|
|
10514
|
+
height: elm.height,
|
|
10515
|
+
strokeWidth: elm.stroke_width,
|
|
10516
|
+
isFilled: elm.is_filled,
|
|
10517
|
+
color: elm.color,
|
|
10518
|
+
cornerRadius: elm.corner_radius,
|
|
10519
|
+
hasStroke: elm.has_stroke,
|
|
10520
|
+
isStrokeDashed: elm.is_stroke_dashed
|
|
10521
|
+
})
|
|
10522
|
+
);
|
|
10523
|
+
} else if (elm.type === "pcb_note_path") {
|
|
10524
|
+
components.push(
|
|
10525
|
+
new PcbNotePath({
|
|
10526
|
+
route: elm.route,
|
|
10527
|
+
strokeWidth: elm.stroke_width,
|
|
10528
|
+
color: elm.color
|
|
10529
|
+
})
|
|
10530
|
+
);
|
|
10531
|
+
} else if (elm.type === "pcb_note_line") {
|
|
10532
|
+
components.push(
|
|
10533
|
+
new PcbNoteLine({
|
|
10534
|
+
x1: elm.x1,
|
|
10535
|
+
y1: elm.y1,
|
|
10536
|
+
x2: elm.x2,
|
|
10537
|
+
y2: elm.y2,
|
|
10538
|
+
strokeWidth: elm.stroke_width,
|
|
10539
|
+
color: elm.color,
|
|
10540
|
+
isDashed: elm.is_dashed
|
|
10541
|
+
})
|
|
10542
|
+
);
|
|
10543
|
+
} else if (elm.type === "pcb_courtyard_rect") {
|
|
10544
|
+
components.push(
|
|
10545
|
+
new CourtyardRect({
|
|
10546
|
+
pcbX: elm.center.x,
|
|
10547
|
+
pcbY: elm.center.y,
|
|
10548
|
+
width: elm.width,
|
|
10549
|
+
height: elm.height,
|
|
10550
|
+
layer: elm.layer
|
|
10551
|
+
})
|
|
10552
|
+
);
|
|
10553
|
+
} else if (elm.type === "pcb_courtyard_circle") {
|
|
10554
|
+
components.push(
|
|
10555
|
+
new CourtyardCircle({
|
|
10556
|
+
pcbX: elm.center.x,
|
|
10557
|
+
pcbY: elm.center.y,
|
|
10558
|
+
radius: elm.radius,
|
|
10559
|
+
layer: elm.layer
|
|
10560
|
+
})
|
|
10561
|
+
);
|
|
10562
|
+
} else if (elm.type === "pcb_courtyard_outline") {
|
|
10563
|
+
components.push(
|
|
10564
|
+
new CourtyardOutline({
|
|
10565
|
+
outline: elm.outline,
|
|
10566
|
+
layer: elm.layer
|
|
10567
|
+
})
|
|
10568
|
+
);
|
|
10569
|
+
} else if (elm.type === "schematic_line") {
|
|
10570
|
+
addSchematicPrimitive(
|
|
10571
|
+
elm,
|
|
10572
|
+
new SchematicLine({
|
|
10573
|
+
x1: elm.x1,
|
|
10574
|
+
y1: elm.y1,
|
|
10575
|
+
x2: elm.x2,
|
|
10576
|
+
y2: elm.y2,
|
|
10577
|
+
strokeWidth: optional(elm.stroke_width),
|
|
10578
|
+
color: elm.color,
|
|
10579
|
+
isDashed: elm.is_dashed
|
|
10580
|
+
})
|
|
10581
|
+
);
|
|
10582
|
+
} else if (elm.type === "schematic_rect") {
|
|
10583
|
+
addSchematicPrimitive(
|
|
10584
|
+
elm,
|
|
10585
|
+
new SchematicRect({
|
|
10586
|
+
schX: elm.center.x,
|
|
10587
|
+
schY: elm.center.y,
|
|
10588
|
+
width: elm.width,
|
|
10589
|
+
height: elm.height,
|
|
10590
|
+
rotation: elm.rotation,
|
|
10591
|
+
strokeWidth: optional(elm.stroke_width),
|
|
10592
|
+
color: elm.color,
|
|
10593
|
+
isFilled: elm.is_filled,
|
|
10594
|
+
fillColor: elm.fill_color,
|
|
10595
|
+
isDashed: elm.is_dashed
|
|
10596
|
+
})
|
|
10597
|
+
);
|
|
10598
|
+
} else if (elm.type === "schematic_circle") {
|
|
10599
|
+
addSchematicPrimitive(
|
|
10600
|
+
elm,
|
|
10601
|
+
new SchematicCircle({
|
|
10602
|
+
center: elm.center,
|
|
10603
|
+
radius: elm.radius,
|
|
10604
|
+
strokeWidth: optional(elm.stroke_width),
|
|
10605
|
+
color: elm.color,
|
|
10606
|
+
isFilled: elm.is_filled,
|
|
10607
|
+
fillColor: elm.fill_color,
|
|
10608
|
+
isDashed: elm.is_dashed
|
|
10609
|
+
})
|
|
10610
|
+
);
|
|
10611
|
+
} else if (elm.type === "schematic_arc") {
|
|
10612
|
+
addSchematicPrimitive(
|
|
10613
|
+
elm,
|
|
10614
|
+
new SchematicArc({
|
|
10615
|
+
center: elm.center,
|
|
10616
|
+
radius: elm.radius,
|
|
10617
|
+
startAngleDegrees: elm.start_angle_degrees,
|
|
10618
|
+
endAngleDegrees: elm.end_angle_degrees,
|
|
10619
|
+
direction: elm.direction,
|
|
10620
|
+
strokeWidth: optional(elm.stroke_width),
|
|
10621
|
+
color: elm.color,
|
|
10622
|
+
isDashed: elm.is_dashed
|
|
10623
|
+
})
|
|
10624
|
+
);
|
|
10625
|
+
} else if (elm.type === "schematic_text") {
|
|
10626
|
+
addSchematicPrimitive(
|
|
10627
|
+
elm,
|
|
10628
|
+
new SchematicText({
|
|
10629
|
+
schX: elm.position.x,
|
|
10630
|
+
schY: elm.position.y,
|
|
10631
|
+
text: elm.text,
|
|
10632
|
+
fontSize: elm.font_size,
|
|
10633
|
+
anchor: elm.anchor,
|
|
10634
|
+
color: elm.color,
|
|
10635
|
+
schRotation: elm.rotation
|
|
10636
|
+
})
|
|
10637
|
+
);
|
|
10638
|
+
} else if (elm.type === "schematic_path") {
|
|
10639
|
+
addSchematicPrimitive(
|
|
10640
|
+
elm,
|
|
10641
|
+
new SchematicPath({
|
|
10642
|
+
points: elm.points,
|
|
10643
|
+
strokeWidth: optional(elm.stroke_width),
|
|
10644
|
+
strokeColor: elm.stroke_color,
|
|
10645
|
+
dashLength: elm.dash_length,
|
|
10646
|
+
dashGap: elm.dash_gap,
|
|
10647
|
+
isFilled: elm.is_filled,
|
|
10648
|
+
fillColor: elm.fill_color
|
|
10649
|
+
})
|
|
10650
|
+
);
|
|
10651
|
+
} else if (elm.type === "schematic_port") {
|
|
10652
|
+
const schematicComponentId = elm.schematic_component_id;
|
|
10653
|
+
if (typeof schematicComponentId !== "string") continue;
|
|
10654
|
+
const schematicComponent = schematicComponentsByImportedId.get(schematicComponentId);
|
|
10655
|
+
const schematicSymbolId = schematicComponent?.schematic_symbol_id;
|
|
10656
|
+
const parentSymbol = typeof schematicSymbolId === "string" ? schematicSymbolsByImportedId.get(schematicSymbolId) : void 0;
|
|
10657
|
+
if (parentSymbol && schematicComponent?.is_box_with_pins === true && elm.center && elm.side_of_component) {
|
|
10658
|
+
const distance19 = elm.distance_from_component_edge;
|
|
10659
|
+
const facingDirection = getFacingDirectionFromSide(
|
|
10660
|
+
elm.side_of_component
|
|
10661
|
+
);
|
|
10662
|
+
if (!facingDirection) continue;
|
|
10663
|
+
const directionVector = getUnitVectorFromDirection2(facingDirection);
|
|
10664
|
+
const stemDirection = elm.facing_direction === facingDirection ? 1 : -1;
|
|
10665
|
+
const portCenter = {
|
|
10666
|
+
x: elm.center.x + directionVector.x * distance19 * stemDirection,
|
|
10667
|
+
y: elm.center.y + directionVector.y * distance19 * stemDirection
|
|
10668
|
+
};
|
|
10669
|
+
const sourcePort = sourcePortsByImportedId.get(elm.source_port_id);
|
|
10670
|
+
const aliases = Array.from(
|
|
10671
|
+
new Set(
|
|
10672
|
+
[
|
|
10673
|
+
elm.display_pin_label,
|
|
10674
|
+
sourcePort?.name,
|
|
10675
|
+
...sourcePort?.port_hints ?? []
|
|
10676
|
+
].filter(
|
|
10677
|
+
(alias) => typeof alias === "string" && alias.length > 0
|
|
10678
|
+
)
|
|
10679
|
+
)
|
|
10680
|
+
);
|
|
10681
|
+
const fallbackPortName = elm.pin_number ? `pin${elm.pin_number}` : elm.schematic_port_id;
|
|
10682
|
+
const portName = aliases[0] ?? elm.source_port_id ?? fallbackPortName;
|
|
10683
|
+
parentSymbol.add(
|
|
10684
|
+
new Port({
|
|
10685
|
+
pinNumber: elm.pin_number,
|
|
10686
|
+
name: portName,
|
|
10687
|
+
aliases,
|
|
10688
|
+
schX: elm.center.x,
|
|
10689
|
+
schY: elm.center.y,
|
|
10690
|
+
direction: facingDirection
|
|
10691
|
+
})
|
|
10692
|
+
);
|
|
10693
|
+
parentSymbol.add(
|
|
10694
|
+
new SchematicLine({
|
|
10695
|
+
x1: elm.center.x,
|
|
10696
|
+
y1: elm.center.y,
|
|
10697
|
+
x2: portCenter.x,
|
|
10698
|
+
y2: portCenter.y,
|
|
10699
|
+
strokeWidth: typeof schematicSymbolId === "string" ? optional(
|
|
10700
|
+
schematicStrokeWidthBySymbolId.get(schematicSymbolId)
|
|
10701
|
+
) : void 0,
|
|
10702
|
+
isDashed: false
|
|
10703
|
+
})
|
|
10704
|
+
);
|
|
10705
|
+
}
|
|
10640
10706
|
}
|
|
10641
|
-
return void 0;
|
|
10642
10707
|
}
|
|
10643
|
-
|
|
10644
|
-
|
|
10645
|
-
|
|
10646
|
-
|
|
10647
|
-
|
|
10648
|
-
|
|
10649
|
-
|
|
10650
|
-
|
|
10651
|
-
|
|
10652
|
-
|
|
10653
|
-
const portCenter = this._getGlobalSchematicPositionBeforeLayout();
|
|
10654
|
-
let localPortInfo = null;
|
|
10655
|
-
const containerDims = container._getSchematicBoxDimensions();
|
|
10656
|
-
if (containerDims && props.pinNumber !== void 0) {
|
|
10657
|
-
localPortInfo = containerDims.getPortPositionByPinNumber(props.pinNumber);
|
|
10658
|
-
}
|
|
10659
|
-
if (this.getSubcircuit().props._schDebugObjectsEnabled) {
|
|
10660
|
-
db.schematic_debug_object.insert({
|
|
10661
|
-
shape: "rect",
|
|
10662
|
-
center: portCenter,
|
|
10663
|
-
size: {
|
|
10664
|
-
width: 0.1,
|
|
10665
|
-
height: 0.1
|
|
10666
|
-
},
|
|
10667
|
-
label: "obstacle"
|
|
10668
|
-
});
|
|
10669
|
-
}
|
|
10670
|
-
if (!localPortInfo?.side) {
|
|
10671
|
-
this.facingDirection = getRelativeDirection(containerCenter, portCenter);
|
|
10672
|
-
} else {
|
|
10673
|
-
this.facingDirection = {
|
|
10674
|
-
left: "left",
|
|
10675
|
-
right: "right",
|
|
10676
|
-
top: "up",
|
|
10677
|
-
bottom: "down"
|
|
10678
|
-
}[localPortInfo.side];
|
|
10679
|
-
}
|
|
10680
|
-
const bestDisplayPinLabel = this._getBestDisplayPinLabel();
|
|
10681
|
-
const parentNormalComponent = this.getParentNormalComponent();
|
|
10682
|
-
const sideOfComponent = localPortInfo?.side ?? (props.direction === "up" ? "top" : props.direction === "down" ? "bottom" : props.direction);
|
|
10683
|
-
const schematicPortInsertProps = {
|
|
10684
|
-
type: "schematic_port",
|
|
10685
|
-
schematic_component_id: parentNormalComponent?.schematic_component_id,
|
|
10686
|
-
center: portCenter,
|
|
10687
|
-
source_port_id: this.source_port_id,
|
|
10688
|
-
facing_direction: this.facingDirection,
|
|
10689
|
-
distance_from_component_edge: props.schStemLength ?? 0.4,
|
|
10690
|
-
side_of_component: sideOfComponent,
|
|
10691
|
-
pin_number: props.pinNumber,
|
|
10692
|
-
true_ccw_index: localPortInfo?.trueIndex,
|
|
10693
|
-
display_pin_label: bestDisplayPinLabel,
|
|
10694
|
-
is_connected: false
|
|
10708
|
+
return components;
|
|
10709
|
+
};
|
|
10710
|
+
|
|
10711
|
+
// lib/utils/filterPinLabels.ts
|
|
10712
|
+
import { chipProps } from "@tscircuit/props";
|
|
10713
|
+
function filterPinLabels(pinLabels) {
|
|
10714
|
+
if (!pinLabels)
|
|
10715
|
+
return {
|
|
10716
|
+
validPinLabels: pinLabels,
|
|
10717
|
+
invalidPinLabelsMessages: []
|
|
10695
10718
|
};
|
|
10696
|
-
|
|
10697
|
-
|
|
10698
|
-
|
|
10699
|
-
|
|
10700
|
-
|
|
10701
|
-
|
|
10719
|
+
const validPinLabels = {};
|
|
10720
|
+
const invalidPinLabelsMessages = [];
|
|
10721
|
+
for (const [pin, labelOrLabels] of Object.entries(pinLabels)) {
|
|
10722
|
+
const labels = Array.isArray(labelOrLabels) ? labelOrLabels.slice() : [labelOrLabels];
|
|
10723
|
+
const validLabels = [];
|
|
10724
|
+
for (const label of labels) {
|
|
10725
|
+
if (isValidPinLabel(pin, label)) {
|
|
10726
|
+
validLabels.push(label);
|
|
10727
|
+
} else {
|
|
10728
|
+
invalidPinLabelsMessages.push(
|
|
10729
|
+
`Invalid pin label: ${pin} = '${label}' - excluding from component. Pin labels can only contain letters, numbers and underscores.`
|
|
10730
|
+
);
|
|
10702
10731
|
}
|
|
10703
10732
|
}
|
|
10704
|
-
|
|
10705
|
-
|
|
10706
|
-
if (props.schStemLength !== void 0 && props.schStemLength !== 0) {
|
|
10707
|
-
const { schStemLength, direction } = props;
|
|
10708
|
-
let x2 = portCenter.x;
|
|
10709
|
-
let y2 = portCenter.y;
|
|
10710
|
-
if (direction === "right") x2 -= schStemLength;
|
|
10711
|
-
else if (direction === "left") x2 += schStemLength;
|
|
10712
|
-
else if (direction === "up") y2 -= schStemLength;
|
|
10713
|
-
else if (direction === "down") y2 += schStemLength;
|
|
10714
|
-
const stemLine = db.schematic_line.insert({
|
|
10715
|
-
schematic_component_id: parentNormalComponent?.schematic_component_id,
|
|
10716
|
-
x1: portCenter.x,
|
|
10717
|
-
y1: portCenter.y,
|
|
10718
|
-
x2,
|
|
10719
|
-
y2,
|
|
10720
|
-
stroke_width: 0.02,
|
|
10721
|
-
color: SCHEMATIC_COMPONENT_OUTLINE_COLOR,
|
|
10722
|
-
is_dashed: false
|
|
10723
|
-
});
|
|
10724
|
-
this.schematic_stem_line_id = stemLine.schematic_line_id;
|
|
10733
|
+
if (validLabels.length > 0) {
|
|
10734
|
+
validPinLabels[pin] = Array.isArray(labelOrLabels) ? validLabels : validLabels[0];
|
|
10725
10735
|
}
|
|
10726
10736
|
}
|
|
10727
|
-
|
|
10728
|
-
|
|
10729
|
-
|
|
10730
|
-
|
|
10731
|
-
|
|
10732
|
-
|
|
10733
|
-
|
|
10734
|
-
const
|
|
10735
|
-
|
|
10736
|
-
|
|
10737
|
-
|
|
10738
|
-
|
|
10739
|
-
|
|
10740
|
-
|
|
10741
|
-
|
|
10742
|
-
|
|
10743
|
-
|
|
10744
|
-
|
|
10745
|
-
|
|
10746
|
-
|
|
10747
|
-
|
|
10748
|
-
|
|
10749
|
-
|
|
10750
|
-
|
|
10751
|
-
|
|
10752
|
-
|
|
10753
|
-
|
|
10754
|
-
|
|
10755
|
-
|
|
10756
|
-
|
|
10757
|
-
|
|
10737
|
+
return {
|
|
10738
|
+
validPinLabels: Object.keys(validPinLabels).length > 0 ? validPinLabels : void 0,
|
|
10739
|
+
invalidPinLabelsMessages
|
|
10740
|
+
};
|
|
10741
|
+
}
|
|
10742
|
+
function isValidPinLabel(pin, label) {
|
|
10743
|
+
try {
|
|
10744
|
+
const testProps = {
|
|
10745
|
+
name: "test",
|
|
10746
|
+
footprint: "test",
|
|
10747
|
+
pinLabels: { [pin]: label }
|
|
10748
|
+
};
|
|
10749
|
+
const result = chipProps.safeParse(testProps);
|
|
10750
|
+
return result.success;
|
|
10751
|
+
} catch (error) {
|
|
10752
|
+
return false;
|
|
10753
|
+
}
|
|
10754
|
+
}
|
|
10755
|
+
|
|
10756
|
+
// lib/utils/get-bounds-of-pcb-components.ts
|
|
10757
|
+
var NON_PHYSICAL_PCB_PRIMITIVE_PREFIXES = [
|
|
10758
|
+
"Silkscreen",
|
|
10759
|
+
"PcbNote",
|
|
10760
|
+
"Courtyard",
|
|
10761
|
+
"FabricationNote"
|
|
10762
|
+
];
|
|
10763
|
+
function getBoundsOfPcbComponents(components) {
|
|
10764
|
+
let minX = Infinity;
|
|
10765
|
+
let minY = Infinity;
|
|
10766
|
+
let maxX = -Infinity;
|
|
10767
|
+
let maxY = -Infinity;
|
|
10768
|
+
let hasValidComponents = false;
|
|
10769
|
+
for (const child of components) {
|
|
10770
|
+
if (child.isPcbPrimitive && !NON_PHYSICAL_PCB_PRIMITIVE_PREFIXES.some(
|
|
10771
|
+
(prefix) => child.componentName.startsWith(prefix)
|
|
10772
|
+
)) {
|
|
10773
|
+
const { x, y } = child._getGlobalPcbPositionBeforeLayout();
|
|
10774
|
+
const { width: width2, height: height2 } = child.getPcbSize();
|
|
10775
|
+
minX = Math.min(minX, x - width2 / 2);
|
|
10776
|
+
minY = Math.min(minY, y - height2 / 2);
|
|
10777
|
+
maxX = Math.max(maxX, x + width2 / 2);
|
|
10778
|
+
maxY = Math.max(maxY, y + height2 / 2);
|
|
10779
|
+
hasValidComponents = true;
|
|
10780
|
+
} else if (child.children.length > 0) {
|
|
10781
|
+
const childBounds = getBoundsOfPcbComponents(child.children);
|
|
10782
|
+
if (childBounds.width > 0 || childBounds.height > 0) {
|
|
10783
|
+
minX = Math.min(minX, childBounds.minX);
|
|
10784
|
+
minY = Math.min(minY, childBounds.minY);
|
|
10785
|
+
maxX = Math.max(maxX, childBounds.maxX);
|
|
10786
|
+
maxY = Math.max(maxY, childBounds.maxY);
|
|
10787
|
+
hasValidComponents = true;
|
|
10758
10788
|
}
|
|
10759
10789
|
}
|
|
10760
10790
|
}
|
|
10761
|
-
|
|
10762
|
-
return
|
|
10763
|
-
|
|
10764
|
-
|
|
10765
|
-
|
|
10766
|
-
|
|
10767
|
-
|
|
10768
|
-
|
|
10769
|
-
|
|
10770
|
-
});
|
|
10771
|
-
}
|
|
10772
|
-
_hasMatchedPcbPrimitive() {
|
|
10773
|
-
return this.matchedComponents.some((c) => c.isPcbPrimitive);
|
|
10774
|
-
}
|
|
10775
|
-
/**
|
|
10776
|
-
* Return the text that should be used for the net label for this port if a
|
|
10777
|
-
* trace can't be drawn. This net label text usually doesn't appear at this
|
|
10778
|
-
* port, but appears at the port it connects to.
|
|
10779
|
-
*/
|
|
10780
|
-
_getNetLabelText() {
|
|
10781
|
-
return `${this.parent?.props.name}_${this.props.name}`;
|
|
10791
|
+
if (!hasValidComponents) {
|
|
10792
|
+
return {
|
|
10793
|
+
minX: 0,
|
|
10794
|
+
minY: 0,
|
|
10795
|
+
maxX: 0,
|
|
10796
|
+
maxY: 0,
|
|
10797
|
+
width: 0,
|
|
10798
|
+
height: 0
|
|
10799
|
+
};
|
|
10782
10800
|
}
|
|
10783
|
-
|
|
10801
|
+
let width = maxX - minX;
|
|
10802
|
+
let height = maxY - minY;
|
|
10803
|
+
if (width < 0) width = 0;
|
|
10804
|
+
if (height < 0) height = 0;
|
|
10805
|
+
return {
|
|
10806
|
+
minX,
|
|
10807
|
+
minY,
|
|
10808
|
+
maxX,
|
|
10809
|
+
maxY,
|
|
10810
|
+
width,
|
|
10811
|
+
height
|
|
10812
|
+
};
|
|
10813
|
+
}
|
|
10784
10814
|
|
|
10785
10815
|
// lib/utils/getPortFromHints.ts
|
|
10786
10816
|
var getPinNumberFromLabels = (labels) => {
|
|
@@ -18960,11 +18990,7 @@ function createSchematicTraceSolverInputProblem(group) {
|
|
|
18960
18990
|
const directConnections = [];
|
|
18961
18991
|
const connectedPairKeys = /* @__PURE__ */ new Set();
|
|
18962
18992
|
const connKeysWithExplicitPortNetTraces = /* @__PURE__ */ new Set();
|
|
18963
|
-
for (const
|
|
18964
|
-
if (trace.parent !== group) continue;
|
|
18965
|
-
const sourceTraceId = trace.source_trace_id;
|
|
18966
|
-
if (!sourceTraceId) continue;
|
|
18967
|
-
const sourceTrace = db.source_trace.get(sourceTraceId);
|
|
18993
|
+
for (const sourceTrace of tracesInScope) {
|
|
18968
18994
|
if (sourceTrace?.subcircuit_connectivity_map_key && (sourceTrace.connected_source_port_ids?.length ?? 0) > 0 && (sourceTrace.connected_source_net_ids?.length ?? 0) > 0) {
|
|
18969
18995
|
connKeysWithExplicitPortNetTraces.add(
|
|
18970
18996
|
sourceTrace.subcircuit_connectivity_map_key
|
|
@@ -23456,7 +23482,7 @@ import { identity as identity5 } from "transformation-matrix";
|
|
|
23456
23482
|
var package_default = {
|
|
23457
23483
|
name: "@tscircuit/core",
|
|
23458
23484
|
type: "module",
|
|
23459
|
-
version: "0.0.
|
|
23485
|
+
version: "0.0.1307",
|
|
23460
23486
|
types: "dist/index.d.ts",
|
|
23461
23487
|
main: "dist/index.js",
|
|
23462
23488
|
module: "dist/index.js",
|