circuit-json-to-tscircuit 0.0.93 → 0.0.95
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/{chunk-B7377FUZ.js → chunk-KYTTH2AG.js} +717 -147
- package/dist/cli/main.js +3 -3
- package/dist/lib/index.js +1 -1
- package/lib/board-converter/get-pin-labels.ts +6 -1
- package/lib/generate-board-schematic-tsx/convert-components.ts +67 -12
- package/lib/generate-board-schematic-tsx/convert-native-symbol-pin-numbers.ts +81 -0
- package/lib/generate-board-schematic-tsx/convert-primitives.ts +28 -5
- package/lib/generate-board-schematic-tsx/convert-symbol-primitives.ts +65 -22
- package/lib/generate-board-schematic-tsx/get-native-symbol-port-matching-inputs.ts +131 -0
- package/lib/generate-board-schematic-tsx/get-native-symbol-text-replacement-candidate.ts +153 -0
- package/lib/generate-board-schematic-tsx/get-native-symbol-text-replacements.ts +82 -0
- package/lib/generate-board-schematic-tsx/get-nearest-schematic-text.ts +104 -0
- package/lib/generate-board-schematic-tsx/get-replaced-schematic-component-ids.ts +21 -0
- package/lib/generate-board-schematic-tsx/get-schematic-primitive-paint.ts +2 -2
- package/lib/generate-board-schematic-tsx/get-schematic-primitives-in-render-order.ts +9 -2
- package/lib/generate-board-schematic-tsx/get-symbol-to-schematic-transform.ts +8 -1
- package/lib/generate-board-schematic-tsx/has-multiple-native-symbol-units.ts +23 -0
- package/lib/generate-board-schematic-tsx/has-preserved-package-value-text.ts +32 -0
- package/lib/generate-board-schematic-tsx/is-pin-designator-for-port.ts +32 -0
- package/lib/generate-board-schematic-tsx/match-symbol-ports-by-pin-identity.ts +9 -1
- package/lib/generate-board-schematic-tsx/resolve-native-schematic-symbol-name.ts +114 -0
- package/package.json +2 -2
- package/tests/__snapshots__/board-imported-bga-pin-labels-orangecrab-bga-pin-labels.snap.svg +1 -0
- package/tests/board-imported-bga-pin-labels.test.ts +145 -0
- package/tests/explicit-native-symbol-content.test.ts +60 -0
- package/tests/ti-evms/__snapshots__/ti-lm251772evm-pd-roundtrip-schematic-comparison.snap.svg +2 -2
- package/tests/ti-evms/__snapshots__/ti-lm251772evm-pd-roundtrip.test.tsx.snap +16 -20
- package/tests/ti-evms/__snapshots__/ti-lm5155evm-fly-roundtrip-schematic-comparison.snap.svg +1 -1
- package/tests/ti-evms/__snapshots__/ti-lmg342x-bb-evm-roundtrip-schematic-comparison.snap.svg +1 -1
- package/tests/ti-evms/__snapshots__/ti-lmg342x-bb-evm-roundtrip.test.tsx.snap +80 -128
- package/tests/ti-evms/ti-lm5155evm-fly-roundtrip.test.tsx +42 -81
- package/tests/ti-native-symbols.test.ts +528 -0
|
@@ -1126,55 +1126,6 @@ ${schematicElements.join("\n")}
|
|
|
1126
1126
|
// lib/generate-board-schematic-tsx/convert-primitives.ts
|
|
1127
1127
|
import { schematic_text } from "circuit-json";
|
|
1128
1128
|
|
|
1129
|
-
// lib/generate-board-schematic-tsx/convert-rect.ts
|
|
1130
|
-
import {
|
|
1131
|
-
applyToPoint,
|
|
1132
|
-
compose,
|
|
1133
|
-
rotateDEG,
|
|
1134
|
-
translate
|
|
1135
|
-
} from "transformation-matrix";
|
|
1136
|
-
|
|
1137
|
-
// lib/generate-board-schematic-tsx/format-attributes.ts
|
|
1138
|
-
var formatAttributes = (attributes) => Object.entries(attributes).filter(([, attribute]) => attribute !== void 0 && attribute !== null).map(([name, attribute]) => `${name}={${JSON.stringify(attribute)}}`).join(" ");
|
|
1139
|
-
var formatElement = (tagName, attributes) => `<${tagName} ${formatAttributes(attributes)} />`;
|
|
1140
|
-
|
|
1141
|
-
// lib/generate-board-schematic-tsx/convert-rect.ts
|
|
1142
|
-
var DEFAULT_SCHEMATIC_STROKE_WIDTH = 0.02;
|
|
1143
|
-
var DASH_LENGTH_TO_STROKE_WIDTH_RATIO = 3;
|
|
1144
|
-
var convertRect = ({
|
|
1145
|
-
center,
|
|
1146
|
-
width,
|
|
1147
|
-
height,
|
|
1148
|
-
ccwRotationDegrees,
|
|
1149
|
-
strokeWidth,
|
|
1150
|
-
color,
|
|
1151
|
-
fillColor,
|
|
1152
|
-
isFilled,
|
|
1153
|
-
isDashed
|
|
1154
|
-
}) => {
|
|
1155
|
-
const rectToSchematicTransform = compose(
|
|
1156
|
-
translate(center.x, center.y),
|
|
1157
|
-
rotateDEG(ccwRotationDegrees ?? 0)
|
|
1158
|
-
);
|
|
1159
|
-
const points = [
|
|
1160
|
-
{ x: -width / 2, y: -height / 2 },
|
|
1161
|
-
{ x: width / 2, y: -height / 2 },
|
|
1162
|
-
{ x: width / 2, y: height / 2 },
|
|
1163
|
-
{ x: -width / 2, y: height / 2 },
|
|
1164
|
-
{ x: -width / 2, y: -height / 2 }
|
|
1165
|
-
].map((point) => applyToPoint(rectToSchematicTransform, point));
|
|
1166
|
-
const dashLength = isDashed ? (strokeWidth ?? DEFAULT_SCHEMATIC_STROKE_WIDTH) * DASH_LENGTH_TO_STROKE_WIDTH_RATIO : void 0;
|
|
1167
|
-
return formatElement("schematicpath", {
|
|
1168
|
-
points,
|
|
1169
|
-
strokeWidth,
|
|
1170
|
-
strokeColor: color,
|
|
1171
|
-
fillColor,
|
|
1172
|
-
isFilled,
|
|
1173
|
-
dashLength,
|
|
1174
|
-
dashGap: dashLength
|
|
1175
|
-
});
|
|
1176
|
-
};
|
|
1177
|
-
|
|
1178
1129
|
// lib/generate-symbol-tsx.ts
|
|
1179
1130
|
import { su } from "@tscircuit/soup-util";
|
|
1180
1131
|
var escapeJsxText = (text) => text.replace(/\\/g, "\\\\").replace(/"/g, '\\"');
|
|
@@ -1394,46 +1345,381 @@ var generateSymbolTsx = (circuitJson) => {
|
|
|
1394
1345
|
`.trim();
|
|
1395
1346
|
};
|
|
1396
1347
|
|
|
1397
|
-
// lib/generate-board-schematic-tsx/
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1348
|
+
// lib/generate-board-schematic-tsx/convert-rect.ts
|
|
1349
|
+
import {
|
|
1350
|
+
applyToPoint,
|
|
1351
|
+
compose,
|
|
1352
|
+
rotateDEG,
|
|
1353
|
+
translate
|
|
1354
|
+
} from "transformation-matrix";
|
|
1355
|
+
|
|
1356
|
+
// lib/generate-board-schematic-tsx/format-attributes.ts
|
|
1357
|
+
var formatAttributes = (attributes) => Object.entries(attributes).filter(([, attribute]) => attribute !== void 0 && attribute !== null).map(([name, attribute]) => `${name}={${JSON.stringify(attribute)}}`).join(" ");
|
|
1358
|
+
var formatElement = (tagName, attributes) => `<${tagName} ${formatAttributes(attributes)} />`;
|
|
1359
|
+
|
|
1360
|
+
// lib/generate-board-schematic-tsx/convert-rect.ts
|
|
1361
|
+
var DEFAULT_SCHEMATIC_STROKE_WIDTH = 0.02;
|
|
1362
|
+
var DASH_LENGTH_TO_STROKE_WIDTH_RATIO = 3;
|
|
1363
|
+
var convertRect = ({
|
|
1364
|
+
center,
|
|
1365
|
+
width,
|
|
1366
|
+
height,
|
|
1367
|
+
ccwRotationDegrees,
|
|
1368
|
+
strokeWidth,
|
|
1369
|
+
color,
|
|
1370
|
+
fillColor,
|
|
1371
|
+
isFilled,
|
|
1372
|
+
isDashed
|
|
1373
|
+
}) => {
|
|
1374
|
+
const rectToSchematicTransform = compose(
|
|
1375
|
+
translate(center.x, center.y),
|
|
1376
|
+
rotateDEG(ccwRotationDegrees ?? 0)
|
|
1377
|
+
);
|
|
1378
|
+
const points = [
|
|
1379
|
+
{ x: -width / 2, y: -height / 2 },
|
|
1380
|
+
{ x: width / 2, y: -height / 2 },
|
|
1381
|
+
{ x: width / 2, y: height / 2 },
|
|
1382
|
+
{ x: -width / 2, y: height / 2 },
|
|
1383
|
+
{ x: -width / 2, y: -height / 2 }
|
|
1384
|
+
].map((point) => applyToPoint(rectToSchematicTransform, point));
|
|
1385
|
+
const dashLength = isDashed ? (strokeWidth ?? DEFAULT_SCHEMATIC_STROKE_WIDTH) * DASH_LENGTH_TO_STROKE_WIDTH_RATIO : void 0;
|
|
1386
|
+
return formatElement("schematicpath", {
|
|
1387
|
+
points,
|
|
1388
|
+
strokeWidth,
|
|
1389
|
+
strokeColor: color,
|
|
1390
|
+
fillColor,
|
|
1391
|
+
isFilled,
|
|
1392
|
+
dashLength,
|
|
1393
|
+
dashGap: dashLength
|
|
1394
|
+
});
|
|
1395
|
+
};
|
|
1396
|
+
|
|
1397
|
+
// lib/generate-board-schematic-tsx/get-nearest-schematic-text.ts
|
|
1398
|
+
var DEGREES_TO_RADIANS = Math.PI / 180;
|
|
1399
|
+
var distanceFromComponentCenter = ({
|
|
1400
|
+
schematicText,
|
|
1401
|
+
schematicComponent
|
|
1402
|
+
}) => Math.hypot(
|
|
1403
|
+
schematicText.position.x - schematicComponent.center.x,
|
|
1404
|
+
schematicText.position.y - schematicComponent.center.y
|
|
1405
|
+
);
|
|
1406
|
+
var getNearestSchematicText = ({
|
|
1407
|
+
schematicTexts,
|
|
1408
|
+
schematicComponent
|
|
1409
|
+
}) => schematicTexts.toSorted(
|
|
1410
|
+
(firstText, secondText) => distanceFromComponentCenter({
|
|
1411
|
+
schematicText: firstText,
|
|
1412
|
+
schematicComponent
|
|
1413
|
+
}) - distanceFromComponentCenter({
|
|
1414
|
+
schematicText: secondText,
|
|
1415
|
+
schematicComponent
|
|
1416
|
+
})
|
|
1417
|
+
)[0];
|
|
1418
|
+
var getSchematicTextAxisDistances = ({
|
|
1419
|
+
schematicText,
|
|
1420
|
+
schematicComponent
|
|
1421
|
+
}) => {
|
|
1422
|
+
const rotationRadians = schematicText.rotation * DEGREES_TO_RADIANS;
|
|
1423
|
+
const deltaX = schematicComponent.center.x - schematicText.position.x;
|
|
1424
|
+
const deltaY = schematicComponent.center.y - schematicText.position.y;
|
|
1425
|
+
return {
|
|
1426
|
+
alongAxis: deltaX * Math.cos(rotationRadians) + deltaY * Math.sin(rotationRadians),
|
|
1427
|
+
acrossAxis: Math.abs(
|
|
1428
|
+
-deltaX * Math.sin(rotationRadians) + deltaY * Math.cos(rotationRadians)
|
|
1429
|
+
)
|
|
1430
|
+
};
|
|
1431
|
+
};
|
|
1432
|
+
var getSchematicTextAxisRange = ({
|
|
1433
|
+
schematicText,
|
|
1434
|
+
maximumDistance
|
|
1435
|
+
}) => {
|
|
1436
|
+
const maximumTextAdvance = Array.from(schematicText.text).length * schematicText.font_size;
|
|
1437
|
+
if (schematicText.anchor.includes("left")) {
|
|
1438
|
+
return {
|
|
1439
|
+
minimum: -maximumDistance,
|
|
1440
|
+
maximum: maximumTextAdvance + maximumDistance
|
|
1441
|
+
};
|
|
1409
1442
|
}
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
}
|
|
1416
|
-
const component = customComponentById.get(primitive.schematic_component_id);
|
|
1417
|
-
if (component && isCustomComponentBody({ component, rect: primitive })) {
|
|
1418
|
-
componentBodyById.set(primitive.schematic_component_id, primitive);
|
|
1419
|
-
}
|
|
1443
|
+
if (schematicText.anchor.includes("right")) {
|
|
1444
|
+
return {
|
|
1445
|
+
minimum: -maximumTextAdvance - maximumDistance,
|
|
1446
|
+
maximum: maximumDistance
|
|
1447
|
+
};
|
|
1420
1448
|
}
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1449
|
+
return {
|
|
1450
|
+
minimum: -maximumTextAdvance / 2 - maximumDistance,
|
|
1451
|
+
maximum: maximumTextAdvance / 2 + maximumDistance
|
|
1452
|
+
};
|
|
1453
|
+
};
|
|
1454
|
+
var isSchematicTextWithinComponentLabelRange = ({
|
|
1455
|
+
schematicText,
|
|
1456
|
+
schematicComponent,
|
|
1457
|
+
maximumDistance
|
|
1458
|
+
}) => {
|
|
1459
|
+
const distance = getSchematicTextAxisDistances({
|
|
1460
|
+
schematicText,
|
|
1461
|
+
schematicComponent
|
|
1462
|
+
});
|
|
1463
|
+
const textAxisRange = getSchematicTextAxisRange({
|
|
1464
|
+
schematicText,
|
|
1465
|
+
maximumDistance
|
|
1466
|
+
});
|
|
1467
|
+
return distance.alongAxis >= textAxisRange.minimum && distance.alongAxis <= textAxisRange.maximum && distance.acrossAxis <= maximumDistance;
|
|
1468
|
+
};
|
|
1469
|
+
|
|
1470
|
+
// lib/generate-board-schematic-tsx/resolve-native-schematic-symbol-name.ts
|
|
1471
|
+
var normalizePortName = (portName) => portName.toLowerCase().replace(/[^a-z0-9]/gu, "");
|
|
1472
|
+
var hasExactPortNames = (sourcePortNames, expectedPortNames) => sourcePortNames.size === expectedPortNames.length && expectedPortNames.every((portName) => sourcePortNames.has(portName));
|
|
1473
|
+
var resolveNativeSchematicSymbolName = ({
|
|
1474
|
+
circuitJson,
|
|
1475
|
+
schematicComponent
|
|
1476
|
+
}) => {
|
|
1477
|
+
if (schematicComponent.symbol_name) return schematicComponent.symbol_name;
|
|
1478
|
+
const sourceComponent = circuitJson.find(
|
|
1479
|
+
(element) => element.type === "source_component" && element.source_component_id === schematicComponent.source_component_id
|
|
1480
|
+
);
|
|
1481
|
+
if (sourceComponent?.type !== "source_component") return void 0;
|
|
1482
|
+
const sourcePorts = circuitJson.filter(
|
|
1483
|
+
(element) => element.type === "source_port" && element.source_component_id === sourceComponent.source_component_id
|
|
1484
|
+
);
|
|
1485
|
+
const sourcePortNames = new Set(
|
|
1486
|
+
sourcePorts.map((sourcePort) => normalizePortName(sourcePort.name))
|
|
1487
|
+
);
|
|
1488
|
+
const schematicPorts = circuitJson.filter(
|
|
1489
|
+
(element) => element.type === "schematic_port" && element.schematic_component_id === schematicComponent.schematic_component_id
|
|
1490
|
+
);
|
|
1491
|
+
const schematicSourcePortNames = new Set(
|
|
1492
|
+
schematicPorts.flatMap((schematicPort) => {
|
|
1493
|
+
const sourcePort = sourcePorts.find(
|
|
1494
|
+
(candidate) => candidate.source_port_id === schematicPort.source_port_id
|
|
1495
|
+
);
|
|
1496
|
+
return sourcePort ? [normalizePortName(sourcePort.name)] : [];
|
|
1497
|
+
})
|
|
1498
|
+
);
|
|
1499
|
+
const logicPortNames = new Set(
|
|
1500
|
+
[...schematicSourcePortNames].map(
|
|
1501
|
+
(portName) => portName.replace(/^\d+([aby])$/u, "$1")
|
|
1502
|
+
)
|
|
1503
|
+
);
|
|
1504
|
+
const designator = sourceComponent.display_name ?? "";
|
|
1505
|
+
const componentValue = sourceComponent.display_value?.toUpperCase() ?? "";
|
|
1506
|
+
if (componentValue.startsWith("SN74LVC2G08") && hasExactPortNames(logicPortNames, ["a", "b", "y"])) {
|
|
1507
|
+
return "and_gate_right";
|
|
1508
|
+
}
|
|
1509
|
+
if (/^SN74LVC[23]G14/u.test(componentValue) && hasExactPortNames(logicPortNames, ["a", "y"])) {
|
|
1510
|
+
return "schmitt_trigger_inverter_right";
|
|
1511
|
+
}
|
|
1512
|
+
if (designator.startsWith("U") && hasExactPortNames(sourcePortNames, ["a", "k", "c", "e"])) {
|
|
1513
|
+
return "phototransistor_optocoupler_right";
|
|
1514
|
+
}
|
|
1515
|
+
if (designator.startsWith("T") && hasExactPortNames(sourcePortNames, [
|
|
1516
|
+
"1",
|
|
1517
|
+
"2",
|
|
1518
|
+
"3",
|
|
1519
|
+
"5",
|
|
1520
|
+
"6",
|
|
1521
|
+
"7",
|
|
1522
|
+
"9",
|
|
1523
|
+
"10"
|
|
1524
|
+
])) {
|
|
1525
|
+
return "transformer_4_winding_right";
|
|
1526
|
+
}
|
|
1527
|
+
if (designator.startsWith("D") && hasExactPortNames(sourcePortNames, ["1anode", "2cathode", "1cathode2anode"])) {
|
|
1528
|
+
return "dual_series_schottky_diode_right";
|
|
1529
|
+
}
|
|
1530
|
+
return void 0;
|
|
1531
|
+
};
|
|
1532
|
+
|
|
1533
|
+
// lib/generate-board-schematic-tsx/has-multiple-native-symbol-units.ts
|
|
1534
|
+
var hasMultipleNativeSymbolUnits = ({
|
|
1535
|
+
circuitJson,
|
|
1536
|
+
schematicComponent,
|
|
1537
|
+
symbolName
|
|
1538
|
+
}) => circuitJson.filter(
|
|
1539
|
+
(candidate) => candidate.type === "schematic_component" && candidate.source_component_id === schematicComponent.source_component_id && !candidate.symbol_name && resolveNativeSchematicSymbolName({
|
|
1540
|
+
circuitJson,
|
|
1541
|
+
schematicComponent: candidate
|
|
1542
|
+
}) === symbolName
|
|
1543
|
+
).length > 1;
|
|
1544
|
+
|
|
1545
|
+
// lib/generate-board-schematic-tsx/has-preserved-package-value-text.ts
|
|
1546
|
+
var hasPreservedPackageValueText = ({
|
|
1547
|
+
circuitJson,
|
|
1548
|
+
schematicComponent,
|
|
1549
|
+
schematicComponents,
|
|
1550
|
+
replacedSchematicComponentIds,
|
|
1551
|
+
displayTexts
|
|
1552
|
+
}) => circuitJson.some((candidate) => {
|
|
1553
|
+
if (candidate.type !== "schematic_text" || !candidate.schematic_component_id || !displayTexts.has(candidate.text) || replacedSchematicComponentIds.has(candidate.schematic_component_id)) {
|
|
1554
|
+
return false;
|
|
1555
|
+
}
|
|
1556
|
+
return schematicComponents.some(
|
|
1557
|
+
(component) => component.schematic_component_id === candidate.schematic_component_id && component.source_component_id === schematicComponent.source_component_id
|
|
1558
|
+
);
|
|
1559
|
+
});
|
|
1560
|
+
|
|
1561
|
+
// lib/generate-board-schematic-tsx/is-pin-designator-for-port.ts
|
|
1562
|
+
var isPinDesignatorForPort = ({
|
|
1563
|
+
schematicText,
|
|
1564
|
+
schematicPort,
|
|
1565
|
+
schematicComponent
|
|
1566
|
+
}) => {
|
|
1567
|
+
if (schematicText.text !== String(schematicPort.pin_number)) return false;
|
|
1568
|
+
const portToCenter = {
|
|
1569
|
+
x: schematicComponent.center.x - schematicPort.center.x,
|
|
1570
|
+
y: schematicComponent.center.y - schematicPort.center.y
|
|
1571
|
+
};
|
|
1572
|
+
const portToText = {
|
|
1573
|
+
x: schematicText.position.x - schematicPort.center.x,
|
|
1574
|
+
y: schematicText.position.y - schematicPort.center.y
|
|
1575
|
+
};
|
|
1576
|
+
const portDistance = Math.hypot(portToCenter.x, portToCenter.y);
|
|
1577
|
+
const textDistance = Math.hypot(portToText.x, portToText.y);
|
|
1578
|
+
const pointsTowardComponent = portToCenter.x * portToText.x + portToCenter.y * portToText.y >= 0;
|
|
1579
|
+
return pointsTowardComponent && textDistance <= Math.min(0.3, portDistance * 0.6);
|
|
1580
|
+
};
|
|
1581
|
+
|
|
1582
|
+
// lib/generate-board-schematic-tsx/get-native-symbol-text-replacement-candidate.ts
|
|
1583
|
+
var distanceBetween = (firstPoint, secondPoint) => Math.hypot(firstPoint.x - secondPoint.x, firstPoint.y - secondPoint.y);
|
|
1584
|
+
var getNativeSymbolTextReplacementCandidate = (context) => {
|
|
1585
|
+
const { circuitJson, schematicComponent, unownedSchematicTexts } = context;
|
|
1586
|
+
if (schematicComponent.symbol_name) return void 0;
|
|
1587
|
+
const symbolName = resolveNativeSchematicSymbolName({
|
|
1588
|
+
circuitJson,
|
|
1589
|
+
schematicComponent
|
|
1590
|
+
});
|
|
1591
|
+
if (!symbolName) return void 0;
|
|
1592
|
+
const sourceComponent = circuitJson.find(
|
|
1593
|
+
(candidate) => candidate.type === "source_component" && candidate.source_component_id === schematicComponent.source_component_id
|
|
1594
|
+
);
|
|
1595
|
+
const reference = sourceComponent?.display_name ?? sourceComponent?.name;
|
|
1596
|
+
const displayTexts = new Set(
|
|
1597
|
+
[
|
|
1598
|
+
sourceComponent?.display_value,
|
|
1599
|
+
schematicComponent.symbol_display_value
|
|
1600
|
+
].filter((displayText) => Boolean(displayText))
|
|
1601
|
+
);
|
|
1602
|
+
const labelSearchDistance = Math.max(schematicComponent.size.width, schematicComponent.size.height) / 2 + 0.3;
|
|
1603
|
+
const referenceTexts = unownedSchematicTexts.filter(
|
|
1604
|
+
(schematicText) => schematicText.text === reference && distanceBetween(schematicText.position, schematicComponent.center) <= labelSearchDistance
|
|
1605
|
+
);
|
|
1606
|
+
const displayValueTextsInRange = unownedSchematicTexts.filter(
|
|
1607
|
+
(schematicText) => displayTexts.has(schematicText.text) && isSchematicTextWithinComponentLabelRange({
|
|
1608
|
+
schematicText,
|
|
1609
|
+
schematicComponent,
|
|
1610
|
+
maximumDistance: labelSearchDistance
|
|
1611
|
+
})
|
|
1612
|
+
);
|
|
1613
|
+
const nearestDisplayValueText = getNearestSchematicText({
|
|
1614
|
+
schematicTexts: displayValueTextsInRange,
|
|
1615
|
+
schematicComponent
|
|
1616
|
+
});
|
|
1617
|
+
const displayValueTexts = nearestDisplayValueText ? [nearestDisplayValueText] : [];
|
|
1618
|
+
const schematicPorts = circuitJson.filter(
|
|
1619
|
+
(candidate) => candidate.type === "schematic_port" && candidate.schematic_component_id === schematicComponent.schematic_component_id
|
|
1620
|
+
);
|
|
1621
|
+
const replacedPinPortIds = /* @__PURE__ */ new Set();
|
|
1622
|
+
const pinDesignatorTexts = schematicPorts.flatMap((schematicPort) => {
|
|
1623
|
+
const matches = unownedSchematicTexts.filter(
|
|
1624
|
+
(schematicText) => isPinDesignatorForPort({
|
|
1625
|
+
schematicText,
|
|
1626
|
+
schematicPort,
|
|
1627
|
+
schematicComponent
|
|
1628
|
+
})
|
|
1629
|
+
);
|
|
1630
|
+
if (matches.length > 0)
|
|
1631
|
+
replacedPinPortIds.add(schematicPort.schematic_port_id);
|
|
1632
|
+
return matches;
|
|
1633
|
+
});
|
|
1634
|
+
return {
|
|
1635
|
+
schematicComponentId: schematicComponent.schematic_component_id,
|
|
1636
|
+
importedTextIds: new Set(
|
|
1637
|
+
[...referenceTexts, ...displayValueTexts, ...pinDesignatorTexts].map(
|
|
1638
|
+
(schematicText) => schematicText.schematic_text_id
|
|
1639
|
+
)
|
|
1640
|
+
),
|
|
1641
|
+
replacedPinPortIds,
|
|
1642
|
+
replacesReference: referenceTexts.length > 0,
|
|
1643
|
+
includeNativeDisplayText: false,
|
|
1644
|
+
referenceFontSize: getNearestSchematicText({
|
|
1645
|
+
schematicTexts: referenceTexts,
|
|
1646
|
+
schematicComponent
|
|
1647
|
+
})?.font_size,
|
|
1648
|
+
displayTextFontSize: nearestDisplayValueText?.font_size,
|
|
1649
|
+
sourceComponentId: schematicComponent.source_component_id,
|
|
1650
|
+
symbolName,
|
|
1651
|
+
displayValueTextIds: new Set(
|
|
1652
|
+
displayValueTexts.map((schematicText) => schematicText.schematic_text_id)
|
|
1653
|
+
),
|
|
1654
|
+
isMultiUnitSymbol: hasMultipleNativeSymbolUnits({
|
|
1655
|
+
circuitJson,
|
|
1656
|
+
schematicComponent,
|
|
1657
|
+
symbolName
|
|
1658
|
+
}),
|
|
1659
|
+
hasPreservedPackageValueText: hasPreservedPackageValueText({
|
|
1660
|
+
circuitJson,
|
|
1661
|
+
schematicComponent,
|
|
1662
|
+
schematicComponents: context.schematicComponents,
|
|
1663
|
+
replacedSchematicComponentIds: context.replacedSchematicComponentIds,
|
|
1664
|
+
displayTexts
|
|
1665
|
+
})
|
|
1666
|
+
};
|
|
1667
|
+
};
|
|
1668
|
+
|
|
1669
|
+
// lib/generate-board-schematic-tsx/get-replaced-schematic-component-ids.ts
|
|
1670
|
+
import { symbols } from "schematic-symbols";
|
|
1671
|
+
var getReplacedSchematicComponentIds = (circuitJson) => {
|
|
1672
|
+
const replacedSchematicComponentIds = /* @__PURE__ */ new Set();
|
|
1673
|
+
for (const element of circuitJson) {
|
|
1674
|
+
if (element.type !== "schematic_component" || element.symbol_name) continue;
|
|
1675
|
+
const inferredSymbolName = resolveNativeSchematicSymbolName({
|
|
1676
|
+
circuitJson,
|
|
1677
|
+
schematicComponent: element
|
|
1678
|
+
});
|
|
1679
|
+
if (inferredSymbolName && inferredSymbolName in symbols) {
|
|
1680
|
+
replacedSchematicComponentIds.add(element.schematic_component_id);
|
|
1433
1681
|
}
|
|
1434
|
-
if (primitive !== componentBody) result.push(primitive);
|
|
1435
1682
|
}
|
|
1436
|
-
return
|
|
1683
|
+
return replacedSchematicComponentIds;
|
|
1684
|
+
};
|
|
1685
|
+
|
|
1686
|
+
// lib/generate-board-schematic-tsx/get-native-symbol-text-replacements.ts
|
|
1687
|
+
var isFirstUnitWithDisplayValue = ({
|
|
1688
|
+
candidate,
|
|
1689
|
+
allCandidates
|
|
1690
|
+
}) => allCandidates.find(
|
|
1691
|
+
(otherCandidate) => otherCandidate.sourceComponentId === candidate.sourceComponentId && otherCandidate.symbolName === candidate.symbolName && otherCandidate.displayValueTextIds.size > 0
|
|
1692
|
+
)?.schematicComponentId === candidate.schematicComponentId;
|
|
1693
|
+
var getNativeSymbolTextReplacements = (circuitJson) => {
|
|
1694
|
+
const unownedSchematicTexts = circuitJson.filter(
|
|
1695
|
+
(element) => element.type === "schematic_text" && element.schematic_component_id === void 0
|
|
1696
|
+
);
|
|
1697
|
+
const replacedSchematicComponentIds = getReplacedSchematicComponentIds(circuitJson);
|
|
1698
|
+
const schematicComponents = circuitJson.filter(
|
|
1699
|
+
(element) => element.type === "schematic_component"
|
|
1700
|
+
);
|
|
1701
|
+
const candidates = schematicComponents.flatMap((schematicComponent) => {
|
|
1702
|
+
const candidate = getNativeSymbolTextReplacementCandidate({
|
|
1703
|
+
circuitJson,
|
|
1704
|
+
schematicComponent,
|
|
1705
|
+
unownedSchematicTexts,
|
|
1706
|
+
replacedSchematicComponentIds,
|
|
1707
|
+
schematicComponents
|
|
1708
|
+
});
|
|
1709
|
+
return candidate ? [candidate] : [];
|
|
1710
|
+
});
|
|
1711
|
+
return candidates.map((candidate) => ({
|
|
1712
|
+
schematicComponentId: candidate.schematicComponentId,
|
|
1713
|
+
importedTextIds: candidate.importedTextIds,
|
|
1714
|
+
replacedPinPortIds: candidate.replacedPinPortIds,
|
|
1715
|
+
replacesReference: candidate.replacesReference,
|
|
1716
|
+
includeNativeDisplayText: candidate.displayValueTextIds.size > 0 && (!candidate.isMultiUnitSymbol || !candidate.hasPreservedPackageValueText && isFirstUnitWithDisplayValue({
|
|
1717
|
+
candidate,
|
|
1718
|
+
allCandidates: candidates
|
|
1719
|
+
})),
|
|
1720
|
+
referenceFontSize: candidate.referenceFontSize,
|
|
1721
|
+
displayTextFontSize: candidate.displayTextFontSize
|
|
1722
|
+
}));
|
|
1437
1723
|
};
|
|
1438
1724
|
|
|
1439
1725
|
// lib/generate-board-schematic-tsx/get-schematic-primitive-paint.ts
|
|
@@ -1518,14 +1804,71 @@ var getSchematicPrimitivePaint = (primitive) => {
|
|
|
1518
1804
|
};
|
|
1519
1805
|
};
|
|
1520
1806
|
|
|
1807
|
+
// lib/generate-board-schematic-tsx/get-schematic-primitives-in-render-order.ts
|
|
1808
|
+
var isSchematicPrimitive = (element) => element.type === "schematic_text" || element.type === "schematic_path" || element.type === "schematic_rect" || element.type === "schematic_line" || element.type === "schematic_circle" || element.type === "schematic_arc" || element.type === "schematic_box";
|
|
1809
|
+
var isCustomComponentBody = ({
|
|
1810
|
+
component,
|
|
1811
|
+
rect
|
|
1812
|
+
}) => component.is_box_with_pins === false && rect.is_filled && rect.center.x === component.center.x && rect.center.y === component.center.y && rect.width === component.size.width && rect.height === component.size.height;
|
|
1813
|
+
var getSchematicPrimitivesInRenderOrder = (circuitJson, nativeComponentIds = /* @__PURE__ */ new Set()) => {
|
|
1814
|
+
const customComponentById = /* @__PURE__ */ new Map();
|
|
1815
|
+
for (const element of circuitJson) {
|
|
1816
|
+
if (element.type === "schematic_component" && element.is_box_with_pins === false) {
|
|
1817
|
+
customComponentById.set(element.schematic_component_id, element);
|
|
1818
|
+
}
|
|
1819
|
+
}
|
|
1820
|
+
const primitives = circuitJson.filter(isSchematicPrimitive).filter(
|
|
1821
|
+
(primitive) => !primitive.schematic_component_id || !nativeComponentIds.has(primitive.schematic_component_id)
|
|
1822
|
+
);
|
|
1823
|
+
const componentBodyById = /* @__PURE__ */ new Map();
|
|
1824
|
+
for (const primitive of primitives) {
|
|
1825
|
+
if (primitive.type !== "schematic_rect" || !primitive.schematic_component_id) {
|
|
1826
|
+
continue;
|
|
1827
|
+
}
|
|
1828
|
+
const component = customComponentById.get(primitive.schematic_component_id);
|
|
1829
|
+
if (component && isCustomComponentBody({ component, rect: primitive })) {
|
|
1830
|
+
componentBodyById.set(primitive.schematic_component_id, primitive);
|
|
1831
|
+
}
|
|
1832
|
+
}
|
|
1833
|
+
const emittedComponentBodies = /* @__PURE__ */ new Set();
|
|
1834
|
+
const result = [];
|
|
1835
|
+
for (const primitive of primitives) {
|
|
1836
|
+
const componentId = primitive.schematic_component_id;
|
|
1837
|
+
const componentBody = componentId ? componentBodyById.get(componentId) : void 0;
|
|
1838
|
+
if (!componentId || !componentBody) {
|
|
1839
|
+
result.push(primitive);
|
|
1840
|
+
continue;
|
|
1841
|
+
}
|
|
1842
|
+
if (!emittedComponentBodies.has(componentId)) {
|
|
1843
|
+
result.push(componentBody);
|
|
1844
|
+
emittedComponentBodies.add(componentId);
|
|
1845
|
+
}
|
|
1846
|
+
if (primitive !== componentBody) result.push(primitive);
|
|
1847
|
+
}
|
|
1848
|
+
return result;
|
|
1849
|
+
};
|
|
1850
|
+
|
|
1521
1851
|
// lib/generate-board-schematic-tsx/convert-primitives.ts
|
|
1852
|
+
var getRenderablePrimitives = (circuitJson) => {
|
|
1853
|
+
const replacedTextIds = new Set(
|
|
1854
|
+
getNativeSymbolTextReplacements(circuitJson).flatMap((replacement) => [
|
|
1855
|
+
...replacement.importedTextIds
|
|
1856
|
+
])
|
|
1857
|
+
);
|
|
1858
|
+
return getSchematicPrimitivesInRenderOrder(
|
|
1859
|
+
circuitJson,
|
|
1860
|
+
getReplacedSchematicComponentIds(circuitJson)
|
|
1861
|
+
).filter(
|
|
1862
|
+
(primitive) => primitive.type !== "schematic_text" || !replacedTextIds.has(primitive.schematic_text_id)
|
|
1863
|
+
);
|
|
1864
|
+
};
|
|
1522
1865
|
var convertPrimitives = (circuitJson) => [
|
|
1523
1866
|
...generateSymbolElements(
|
|
1524
1867
|
circuitJson.filter(
|
|
1525
1868
|
(element) => element.type === "schematic_table" || element.type === "schematic_table_cell"
|
|
1526
1869
|
)
|
|
1527
1870
|
),
|
|
1528
|
-
...
|
|
1871
|
+
...getRenderablePrimitives(circuitJson).flatMap((element) => {
|
|
1529
1872
|
const paint = getSchematicPrimitivePaint(element);
|
|
1530
1873
|
switch (element.type) {
|
|
1531
1874
|
case "schematic_text":
|
|
@@ -1623,7 +1966,7 @@ var convertPrimitives = (circuitJson) => [
|
|
|
1623
1966
|
|
|
1624
1967
|
// lib/generate-board-schematic-tsx/convert-components.ts
|
|
1625
1968
|
import { su as su3 } from "@tscircuit/soup-util";
|
|
1626
|
-
import { symbols } from "schematic-symbols";
|
|
1969
|
+
import { symbols as symbols2 } from "schematic-symbols";
|
|
1627
1970
|
|
|
1628
1971
|
// lib/generate-board-schematic-tsx/get-symbol-to-schematic-transform.ts
|
|
1629
1972
|
import { fromTriangles as fromTriangles2 } from "transformation-matrix";
|
|
@@ -1801,18 +2144,21 @@ var isRigidUniformTransform = (transform) => {
|
|
|
1801
2144
|
};
|
|
1802
2145
|
|
|
1803
2146
|
// lib/generate-board-schematic-tsx/match-symbol-ports-by-pin-identity.ts
|
|
2147
|
+
var getLogicUnitPortAlias = (portName) => portName?.match(/^\d*([aby])$/iu)?.[1]?.toLowerCase();
|
|
1804
2148
|
var matchSymbolPortsByPinIdentity = ({
|
|
1805
2149
|
schematicPorts,
|
|
1806
2150
|
sourcePorts,
|
|
1807
|
-
symbol
|
|
2151
|
+
symbol,
|
|
2152
|
+
includeSchematicPinNumbers = true
|
|
1808
2153
|
}) => symbol.ports.flatMap((symbolPort) => {
|
|
1809
2154
|
const candidates = schematicPorts.filter((schematicPort) => {
|
|
1810
2155
|
const sourcePort = sourcePorts.find(
|
|
1811
2156
|
(port) => port.source_port_id === schematicPort.source_port_id
|
|
1812
2157
|
);
|
|
1813
|
-
const pinNumber = schematicPort.pin_number ?? sourcePort?.pin_number;
|
|
2158
|
+
const pinNumber = includeSchematicPinNumbers ? schematicPort.pin_number ?? sourcePort?.pin_number : sourcePort?.pin_number;
|
|
1814
2159
|
const portIdentities = [
|
|
1815
2160
|
sourcePort?.name,
|
|
2161
|
+
getLogicUnitPortAlias(sourcePort?.name),
|
|
1816
2162
|
...sourcePort?.port_hints ?? [],
|
|
1817
2163
|
...pinNumber === void 0 ? [] : [String(pinNumber), `pin${pinNumber}`]
|
|
1818
2164
|
];
|
|
@@ -1828,12 +2174,17 @@ var getSymbolToSchematicTransform = ({
|
|
|
1828
2174
|
symbol,
|
|
1829
2175
|
schematicComponent,
|
|
1830
2176
|
schematicPorts,
|
|
1831
|
-
sourcePorts
|
|
2177
|
+
sourcePorts,
|
|
2178
|
+
includeSchematicPinNumbers
|
|
1832
2179
|
}) => {
|
|
2180
|
+
const componentSourcePorts = sourcePorts.filter(
|
|
2181
|
+
(sourcePort) => sourcePort.source_component_id === schematicComponent.source_component_id
|
|
2182
|
+
);
|
|
1833
2183
|
const pinIdentityMatches = matchSymbolPortsByPinIdentity({
|
|
1834
2184
|
schematicPorts,
|
|
1835
|
-
sourcePorts,
|
|
1836
|
-
symbol
|
|
2185
|
+
sourcePorts: componentSourcePorts,
|
|
2186
|
+
symbol,
|
|
2187
|
+
includeSchematicPinNumbers
|
|
1837
2188
|
});
|
|
1838
2189
|
const rigidPinIdentityTransform = getRigidPinIdentityTransform(pinIdentityMatches);
|
|
1839
2190
|
if (rigidPinIdentityTransform) return rigidPinIdentityTransform;
|
|
@@ -1869,6 +2220,17 @@ var getSymbolToSchematicTransform = ({
|
|
|
1869
2220
|
import { schematic_text as schematic_text2 } from "circuit-json";
|
|
1870
2221
|
import { applyToPoint as applyToPoint4 } from "transformation-matrix";
|
|
1871
2222
|
var SYMBOL_OUTLINE_STROKE_WIDTH = 0.02;
|
|
2223
|
+
var MINIMUM_FILL_AREA = 1e-12;
|
|
2224
|
+
var pathHasFillArea = (points) => {
|
|
2225
|
+
if (points.length < 3) return false;
|
|
2226
|
+
let doubledArea = 0;
|
|
2227
|
+
for (const [pointIndex, point] of points.entries()) {
|
|
2228
|
+
const nextPoint = points[(pointIndex + 1) % points.length];
|
|
2229
|
+
if (!nextPoint) continue;
|
|
2230
|
+
doubledArea += point.x * nextPoint.y - nextPoint.x * point.y;
|
|
2231
|
+
}
|
|
2232
|
+
return Math.abs(doubledArea) > MINIMUM_FILL_AREA;
|
|
2233
|
+
};
|
|
1872
2234
|
var anchors = {
|
|
1873
2235
|
middle_top: "top_center",
|
|
1874
2236
|
middle_bottom: "bottom_center",
|
|
@@ -1884,8 +2246,13 @@ var convertSymbolPrimitives = ({
|
|
|
1884
2246
|
symbol,
|
|
1885
2247
|
symbolToSchematicTransform,
|
|
1886
2248
|
reference,
|
|
1887
|
-
displayText
|
|
1888
|
-
|
|
2249
|
+
displayText,
|
|
2250
|
+
includeReference = true,
|
|
2251
|
+
includeDisplayText = true,
|
|
2252
|
+
referenceFontSize,
|
|
2253
|
+
displayTextFontSize,
|
|
2254
|
+
filledPrimitiveColor
|
|
2255
|
+
}) => symbol.primitives.flatMap((primitive) => {
|
|
1889
2256
|
if (primitive.type === "path") {
|
|
1890
2257
|
const points = primitive.points.map(
|
|
1891
2258
|
(point) => applyToPoint4(symbolToSchematicTransform, point)
|
|
@@ -1894,19 +2261,25 @@ var convertSymbolPrimitives = ({
|
|
|
1894
2261
|
return formatElement("schematicpath", {
|
|
1895
2262
|
points,
|
|
1896
2263
|
strokeWidth: SYMBOL_OUTLINE_STROKE_WIDTH,
|
|
2264
|
+
fillColor: primitive.fill && pathHasFillArea(points) ? filledPrimitiveColor : void 0,
|
|
1897
2265
|
isFilled: primitive.fill
|
|
1898
2266
|
});
|
|
1899
2267
|
}
|
|
1900
2268
|
const center = applyToPoint4(symbolToSchematicTransform, primitive);
|
|
1901
2269
|
if (primitive.type === "text") {
|
|
2270
|
+
if (!includeReference && primitive.text === "{REF}") return [];
|
|
2271
|
+
if (!includeDisplayText && primitive.text === "{VAL}") return [];
|
|
1902
2272
|
const text = primitive.text === "{REF}" ? reference : primitive.text === "{VAL}" ? displayText : primitive.text;
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
2273
|
+
const importedFontSize = primitive.text === "{REF}" ? referenceFontSize : primitive.text === "{VAL}" ? displayTextFontSize : void 0;
|
|
2274
|
+
return [
|
|
2275
|
+
formatElement("schematictext", {
|
|
2276
|
+
text,
|
|
2277
|
+
schX: center.x,
|
|
2278
|
+
schY: center.y,
|
|
2279
|
+
anchor: anchors[primitive.anchor],
|
|
2280
|
+
fontSize: importedFontSize ?? primitive.fontSize ?? schematic_text2.shape.font_size.parse(void 0)
|
|
2281
|
+
})
|
|
2282
|
+
];
|
|
1910
2283
|
}
|
|
1911
2284
|
const symbolToSchematicVectorTransform = {
|
|
1912
2285
|
...symbolToSchematicTransform,
|
|
@@ -1918,12 +2291,15 @@ var convertSymbolPrimitives = ({
|
|
|
1918
2291
|
x: primitive.radius,
|
|
1919
2292
|
y: 0
|
|
1920
2293
|
});
|
|
1921
|
-
return
|
|
1922
|
-
|
|
1923
|
-
|
|
1924
|
-
|
|
1925
|
-
|
|
1926
|
-
|
|
2294
|
+
return [
|
|
2295
|
+
formatElement("schematiccircle", {
|
|
2296
|
+
center,
|
|
2297
|
+
radius: Math.hypot(radiusVector.x, radiusVector.y),
|
|
2298
|
+
strokeWidth: SYMBOL_OUTLINE_STROKE_WIDTH,
|
|
2299
|
+
fillColor: primitive.fill ? filledPrimitiveColor : void 0,
|
|
2300
|
+
isFilled: primitive.fill
|
|
2301
|
+
})
|
|
2302
|
+
];
|
|
1927
2303
|
}
|
|
1928
2304
|
const widthVector = applyToPoint4(symbolToSchematicVectorTransform, {
|
|
1929
2305
|
x: primitive.width,
|
|
@@ -1934,13 +2310,15 @@ var convertSymbolPrimitives = ({
|
|
|
1934
2310
|
y: primitive.height
|
|
1935
2311
|
});
|
|
1936
2312
|
const ccwRotationDegrees = Math.atan2(widthVector.y, widthVector.x) * 180 / Math.PI;
|
|
1937
|
-
return
|
|
1938
|
-
|
|
1939
|
-
|
|
1940
|
-
|
|
1941
|
-
|
|
1942
|
-
|
|
1943
|
-
|
|
2313
|
+
return [
|
|
2314
|
+
formatElement("schematicrect", {
|
|
2315
|
+
schX: center.x,
|
|
2316
|
+
schY: center.y,
|
|
2317
|
+
width: Math.hypot(widthVector.x, widthVector.y),
|
|
2318
|
+
height: Math.hypot(heightVector.x, heightVector.y),
|
|
2319
|
+
rotation: ccwRotationDegrees
|
|
2320
|
+
})
|
|
2321
|
+
];
|
|
1944
2322
|
});
|
|
1945
2323
|
|
|
1946
2324
|
// lib/generate-board-schematic-tsx/convert-box-components.ts
|
|
@@ -2171,33 +2549,222 @@ var convertBoxComponent = ({
|
|
|
2171
2549
|
return primitives;
|
|
2172
2550
|
};
|
|
2173
2551
|
|
|
2174
|
-
// lib/generate-board-schematic-tsx/convert-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
return convertSymbolPrimitives({
|
|
2192
|
-
symbol,
|
|
2193
|
-
symbolToSchematicTransform,
|
|
2194
|
-
reference: sourceComponent?.display_name ?? sourceComponent?.name ?? "",
|
|
2195
|
-
displayText: schematicComponent.symbol_display_value ?? ""
|
|
2196
|
-
});
|
|
2552
|
+
// lib/generate-board-schematic-tsx/convert-native-symbol-pin-numbers.ts
|
|
2553
|
+
import { applyToPoint as applyToPoint5 } from "transformation-matrix";
|
|
2554
|
+
var PIN_TEXT_FONT_SIZE = 0.15;
|
|
2555
|
+
var PIN_TEXT_COLOR = "#a90000";
|
|
2556
|
+
var PIN_NUMBER_BASELINE_OFFSET = 0.02;
|
|
2557
|
+
var SYMBOL_POINT_TOLERANCE = 1e-6;
|
|
2558
|
+
var pointsMatch = (firstPoint, secondPoint) => Math.hypot(firstPoint.x - secondPoint.x, firstPoint.y - secondPoint.y) < SYMBOL_POINT_TOLERANCE;
|
|
2559
|
+
var getPortLeadInnerPoint = ({
|
|
2560
|
+
symbol,
|
|
2561
|
+
symbolPort
|
|
2562
|
+
}) => {
|
|
2563
|
+
for (const primitive of symbol.primitives) {
|
|
2564
|
+
if (primitive.type !== "path" || primitive.points.length < 2) continue;
|
|
2565
|
+
const firstPoint = primitive.points[0];
|
|
2566
|
+
const lastPoint = primitive.points.at(-1);
|
|
2567
|
+
if (pointsMatch(firstPoint, symbolPort)) return primitive.points[1];
|
|
2568
|
+
if (pointsMatch(lastPoint, symbolPort)) return primitive.points.at(-2);
|
|
2197
2569
|
}
|
|
2198
|
-
return
|
|
2570
|
+
return void 0;
|
|
2571
|
+
};
|
|
2572
|
+
var convertNativeSymbolPinNumbers = ({
|
|
2573
|
+
symbol,
|
|
2574
|
+
symbolToSchematicTransform,
|
|
2575
|
+
portMatches,
|
|
2576
|
+
replacedPinPortIds
|
|
2577
|
+
}) => portMatches.flatMap(({ schematicPort, symbolPort }) => {
|
|
2578
|
+
if (schematicPort.pin_number === void 0 || !replacedPinPortIds.has(schematicPort.schematic_port_id)) {
|
|
2579
|
+
return [];
|
|
2580
|
+
}
|
|
2581
|
+
const leadInnerPoint = getPortLeadInnerPoint({ symbol, symbolPort });
|
|
2582
|
+
if (!leadInnerPoint) return [];
|
|
2583
|
+
const portCenter = applyToPoint5(symbolToSchematicTransform, symbolPort);
|
|
2584
|
+
const leadInnerCenter = applyToPoint5(
|
|
2585
|
+
symbolToSchematicTransform,
|
|
2586
|
+
leadInnerPoint
|
|
2587
|
+
);
|
|
2588
|
+
const pinNumberPosition = {
|
|
2589
|
+
x: (portCenter.x + leadInnerCenter.x) / 2,
|
|
2590
|
+
y: (portCenter.y + leadInnerCenter.y) / 2
|
|
2591
|
+
};
|
|
2592
|
+
const isVerticalLead = Math.abs(leadInnerCenter.y - portCenter.y) > Math.abs(leadInnerCenter.x - portCenter.x);
|
|
2593
|
+
if (isVerticalLead) pinNumberPosition.x -= PIN_NUMBER_BASELINE_OFFSET;
|
|
2594
|
+
else pinNumberPosition.y += PIN_NUMBER_BASELINE_OFFSET;
|
|
2595
|
+
return [
|
|
2596
|
+
formatElement("schematictext", {
|
|
2597
|
+
text: String(schematicPort.pin_number),
|
|
2598
|
+
schX: pinNumberPosition.x,
|
|
2599
|
+
schY: pinNumberPosition.y,
|
|
2600
|
+
anchor: "bottom_center",
|
|
2601
|
+
fontSize: PIN_TEXT_FONT_SIZE,
|
|
2602
|
+
color: PIN_TEXT_COLOR,
|
|
2603
|
+
schRotation: isVerticalLead ? -90 : void 0
|
|
2604
|
+
})
|
|
2605
|
+
];
|
|
2199
2606
|
});
|
|
2200
2607
|
|
|
2608
|
+
// lib/generate-board-schematic-tsx/get-native-symbol-port-matching-inputs.ts
|
|
2609
|
+
var getNumericPortHint = (sourcePort) => {
|
|
2610
|
+
const numericPortHint = sourcePort.port_hints?.find(
|
|
2611
|
+
(portHint) => /^(?:pin)?\d+$/.test(portHint)
|
|
2612
|
+
);
|
|
2613
|
+
return numericPortHint?.replace(/^pin/, "");
|
|
2614
|
+
};
|
|
2615
|
+
var getNumericPortName = (sourcePort) => /^\d+$/.test(sourcePort.name) ? sourcePort.name : void 0;
|
|
2616
|
+
var getSourcePinNumber = ({
|
|
2617
|
+
sourcePort,
|
|
2618
|
+
schematicPorts
|
|
2619
|
+
}) => {
|
|
2620
|
+
const linkedSchematicPort = schematicPorts.find(
|
|
2621
|
+
(schematicPort) => schematicPort.source_port_id === sourcePort.source_port_id
|
|
2622
|
+
);
|
|
2623
|
+
const sourcePinNumber = sourcePort.pin_number ?? linkedSchematicPort?.pin_number ?? getNumericPortHint(sourcePort) ?? getNumericPortName(sourcePort);
|
|
2624
|
+
return sourcePinNumber === void 0 ? void 0 : String(sourcePinNumber);
|
|
2625
|
+
};
|
|
2626
|
+
var getFourWindingTransformerAlias = (sourcePinNumber) => {
|
|
2627
|
+
switch (sourcePinNumber) {
|
|
2628
|
+
case "1":
|
|
2629
|
+
return "primary_end";
|
|
2630
|
+
case "2":
|
|
2631
|
+
return "primary_start";
|
|
2632
|
+
case "5":
|
|
2633
|
+
return "auxiliary_end";
|
|
2634
|
+
case "3":
|
|
2635
|
+
return "auxiliary_start";
|
|
2636
|
+
case "9":
|
|
2637
|
+
return "secondary1_end";
|
|
2638
|
+
case "10":
|
|
2639
|
+
return "secondary1_start";
|
|
2640
|
+
case "6":
|
|
2641
|
+
return "secondary2_end";
|
|
2642
|
+
case "7":
|
|
2643
|
+
return "secondary2_start";
|
|
2644
|
+
default:
|
|
2645
|
+
return void 0;
|
|
2646
|
+
}
|
|
2647
|
+
};
|
|
2648
|
+
var getDualSeriesSchottkyAlias = (sourcePinNumber) => {
|
|
2649
|
+
switch (sourcePinNumber) {
|
|
2650
|
+
case "1":
|
|
2651
|
+
return "anode";
|
|
2652
|
+
case "2":
|
|
2653
|
+
return "cathode";
|
|
2654
|
+
case "3":
|
|
2655
|
+
return "common";
|
|
2656
|
+
default:
|
|
2657
|
+
return void 0;
|
|
2658
|
+
}
|
|
2659
|
+
};
|
|
2660
|
+
var getInferredPortAlias = ({
|
|
2661
|
+
symbolName,
|
|
2662
|
+
sourcePinNumber
|
|
2663
|
+
}) => {
|
|
2664
|
+
if (symbolName === "transformer_4_winding_right") {
|
|
2665
|
+
return getFourWindingTransformerAlias(sourcePinNumber);
|
|
2666
|
+
}
|
|
2667
|
+
if (symbolName === "dual_series_schottky_diode_right") {
|
|
2668
|
+
return getDualSeriesSchottkyAlias(sourcePinNumber);
|
|
2669
|
+
}
|
|
2670
|
+
return void 0;
|
|
2671
|
+
};
|
|
2672
|
+
var getNativeSymbolPortMatchingInputs = ({
|
|
2673
|
+
symbolName,
|
|
2674
|
+
sourcePorts,
|
|
2675
|
+
schematicPorts,
|
|
2676
|
+
isInferredSymbol
|
|
2677
|
+
}) => {
|
|
2678
|
+
const usesInferredPortAliases = symbolName === "transformer_4_winding_right" || symbolName === "dual_series_schottky_diode_right";
|
|
2679
|
+
if (!isInferredSymbol || !usesInferredPortAliases) {
|
|
2680
|
+
return { sourcePorts, includeSchematicPinNumbers: true };
|
|
2681
|
+
}
|
|
2682
|
+
const aliasedSourcePorts = sourcePorts.map((sourcePort) => {
|
|
2683
|
+
const sourcePinNumber = getSourcePinNumber({ sourcePort, schematicPorts });
|
|
2684
|
+
if (!sourcePinNumber) return sourcePort;
|
|
2685
|
+
const inferredPortAlias = getInferredPortAlias({
|
|
2686
|
+
symbolName,
|
|
2687
|
+
sourcePinNumber
|
|
2688
|
+
});
|
|
2689
|
+
if (!inferredPortAlias) return sourcePort;
|
|
2690
|
+
return {
|
|
2691
|
+
...sourcePort,
|
|
2692
|
+
name: inferredPortAlias,
|
|
2693
|
+
port_hints: [inferredPortAlias],
|
|
2694
|
+
pin_number: void 0
|
|
2695
|
+
};
|
|
2696
|
+
});
|
|
2697
|
+
return {
|
|
2698
|
+
sourcePorts: aliasedSourcePorts,
|
|
2699
|
+
includeSchematicPinNumbers: false
|
|
2700
|
+
};
|
|
2701
|
+
};
|
|
2702
|
+
|
|
2703
|
+
// lib/generate-board-schematic-tsx/convert-components.ts
|
|
2704
|
+
var convertComponents = (circuitJson) => {
|
|
2705
|
+
const textReplacements = getNativeSymbolTextReplacements(circuitJson);
|
|
2706
|
+
return su3(circuitJson).schematic_component.list().flatMap((schematicComponent) => {
|
|
2707
|
+
const symbolName = resolveNativeSchematicSymbolName({
|
|
2708
|
+
circuitJson,
|
|
2709
|
+
schematicComponent
|
|
2710
|
+
});
|
|
2711
|
+
if (symbolName && symbolName in symbols2) {
|
|
2712
|
+
const symbol = symbols2[symbolName];
|
|
2713
|
+
if (!symbol) return [];
|
|
2714
|
+
const isInferredSymbol = !schematicComponent.symbol_name;
|
|
2715
|
+
const sourceComponent = su3(circuitJson).source_component.get(
|
|
2716
|
+
schematicComponent.source_component_id ?? ""
|
|
2717
|
+
);
|
|
2718
|
+
const schematicPorts = su3(circuitJson).schematic_port.list({
|
|
2719
|
+
schematic_component_id: schematicComponent.schematic_component_id
|
|
2720
|
+
});
|
|
2721
|
+
const sourcePorts = su3(circuitJson).source_port.list({
|
|
2722
|
+
source_component_id: schematicComponent.source_component_id
|
|
2723
|
+
});
|
|
2724
|
+
const portMatchingInputs = getNativeSymbolPortMatchingInputs({
|
|
2725
|
+
symbolName,
|
|
2726
|
+
sourcePorts,
|
|
2727
|
+
schematicPorts,
|
|
2728
|
+
isInferredSymbol
|
|
2729
|
+
});
|
|
2730
|
+
const symbolToSchematicTransform = getSymbolToSchematicTransform({
|
|
2731
|
+
symbol,
|
|
2732
|
+
schematicComponent,
|
|
2733
|
+
schematicPorts,
|
|
2734
|
+
...portMatchingInputs
|
|
2735
|
+
});
|
|
2736
|
+
const textReplacement = textReplacements.find(
|
|
2737
|
+
(replacement) => replacement.schematicComponentId === schematicComponent.schematic_component_id
|
|
2738
|
+
);
|
|
2739
|
+
const portMatches = matchSymbolPortsByPinIdentity({
|
|
2740
|
+
schematicPorts,
|
|
2741
|
+
symbol,
|
|
2742
|
+
...portMatchingInputs
|
|
2743
|
+
});
|
|
2744
|
+
return [
|
|
2745
|
+
...convertSymbolPrimitives({
|
|
2746
|
+
symbol,
|
|
2747
|
+
symbolToSchematicTransform,
|
|
2748
|
+
reference: sourceComponent?.display_name ?? sourceComponent?.name ?? "",
|
|
2749
|
+
displayText: isInferredSymbol ? sourceComponent?.display_value ?? schematicComponent.symbol_display_value ?? "" : schematicComponent.symbol_display_value ?? "",
|
|
2750
|
+
includeReference: !isInferredSymbol || textReplacement?.replacesReference,
|
|
2751
|
+
includeDisplayText: !isInferredSymbol || textReplacement?.includeNativeDisplayText,
|
|
2752
|
+
referenceFontSize: textReplacement?.referenceFontSize,
|
|
2753
|
+
displayTextFontSize: textReplacement?.displayTextFontSize,
|
|
2754
|
+
filledPrimitiveColor: isInferredSymbol ? COMPONENT_OUTLINE_COLOR : void 0
|
|
2755
|
+
}),
|
|
2756
|
+
...isInferredSymbol && textReplacement ? convertNativeSymbolPinNumbers({
|
|
2757
|
+
symbol,
|
|
2758
|
+
symbolToSchematicTransform,
|
|
2759
|
+
portMatches,
|
|
2760
|
+
replacedPinPortIds: textReplacement.replacedPinPortIds
|
|
2761
|
+
}) : []
|
|
2762
|
+
];
|
|
2763
|
+
}
|
|
2764
|
+
return schematicComponent.is_box_with_pins ? convertBoxComponent({ circuitJson, schematicComponent }) : [];
|
|
2765
|
+
});
|
|
2766
|
+
};
|
|
2767
|
+
|
|
2201
2768
|
// lib/generate-board-schematic-tsx/convert-schematic-graphics.ts
|
|
2202
2769
|
var convertSchematicGraphics = (circuitJson) => circuitJson.flatMap((element) => {
|
|
2203
2770
|
if (element.type !== "schematic_graphic") return [];
|
|
@@ -2214,7 +2781,7 @@ var convertSchematicGraphics = (circuitJson) => circuitJson.flatMap((element) =>
|
|
|
2214
2781
|
// lib/generate-board-schematic-tsx/convert-net-labels.ts
|
|
2215
2782
|
import { su as su4 } from "@tscircuit/soup-util";
|
|
2216
2783
|
import { schematic_text as schematic_text3 } from "circuit-json";
|
|
2217
|
-
import { symbols as
|
|
2784
|
+
import { symbols as symbols3 } from "schematic-symbols";
|
|
2218
2785
|
|
|
2219
2786
|
// lib/generate-board-schematic-tsx/get-net-label-symbol-to-schematic-transform.ts
|
|
2220
2787
|
import {
|
|
@@ -2243,8 +2810,8 @@ function canRenderNativeNetLabel(name) {
|
|
|
2243
2810
|
var convertNetLabels = (circuitJson) => su4(circuitJson).schematic_net_label.list().flatMap((schematicNetLabel) => {
|
|
2244
2811
|
const anchorPosition = schematicNetLabel.anchor_position ?? schematicNetLabel.center;
|
|
2245
2812
|
const symbolName = schematicNetLabel.symbol_name;
|
|
2246
|
-
if (symbolName && symbolName in
|
|
2247
|
-
const symbol =
|
|
2813
|
+
if (symbolName && symbolName in symbols3) {
|
|
2814
|
+
const symbol = symbols3[symbolName];
|
|
2248
2815
|
if (symbol)
|
|
2249
2816
|
return convertSymbolPrimitives({
|
|
2250
2817
|
symbol,
|
|
@@ -3453,7 +4020,7 @@ var generateFootprintTsx = (circuitJson, context) => {
|
|
|
3453
4020
|
|
|
3454
4021
|
// lib/board-converter/get-pcb-component-render-placement.ts
|
|
3455
4022
|
import { getBoundsOfPcbElements } from "@tscircuit/circuit-json-util";
|
|
3456
|
-
import { applyToPoint as
|
|
4023
|
+
import { applyToPoint as applyToPoint6, inverse, translate as translate5 } from "transformation-matrix";
|
|
3457
4024
|
var physicalPcbElementTypes = /* @__PURE__ */ new Set([
|
|
3458
4025
|
"pcb_copper_text",
|
|
3459
4026
|
"pcb_cutout",
|
|
@@ -3479,7 +4046,7 @@ var getPcbComponentRenderPlacement = ({
|
|
|
3479
4046
|
pcbBoard,
|
|
3480
4047
|
pcbComponent
|
|
3481
4048
|
}) => {
|
|
3482
|
-
const componentPosition =
|
|
4049
|
+
const componentPosition = applyToPoint6(
|
|
3483
4050
|
inverse(translate5(pcbBoard.center.x, pcbBoard.center.y)),
|
|
3484
4051
|
pcbComponent.center
|
|
3485
4052
|
);
|
|
@@ -3508,7 +4075,10 @@ var getPcbComponentRenderPlacement = ({
|
|
|
3508
4075
|
|
|
3509
4076
|
// lib/board-converter/get-pin-labels.ts
|
|
3510
4077
|
var getCompoundPinNumber = (sourcePort) => {
|
|
3511
|
-
if (sourcePort.pin_number !== void 0)
|
|
4078
|
+
if (sourcePort.pin_number !== void 0) {
|
|
4079
|
+
const pinNumber = Number(sourcePort.pin_number);
|
|
4080
|
+
return Number.isSafeInteger(pinNumber) && pinNumber >= 0 ? pinNumber : void 0;
|
|
4081
|
+
}
|
|
3512
4082
|
const firstPinNumber = /^\d+/u.exec(sourcePort.name)?.[0];
|
|
3513
4083
|
return firstPinNumber ? Number.parseInt(firstPinNumber, 10) : void 0;
|
|
3514
4084
|
};
|
|
@@ -3594,7 +4164,7 @@ var getSchematicComponentsForPcbComponent = ({
|
|
|
3594
4164
|
// lib/board-converter/localize-pcb-component-elements.ts
|
|
3595
4165
|
import { transformPCBElements } from "@tscircuit/circuit-json-util";
|
|
3596
4166
|
import {
|
|
3597
|
-
applyToPoint as
|
|
4167
|
+
applyToPoint as applyToPoint7,
|
|
3598
4168
|
compose as compose4,
|
|
3599
4169
|
decomposeTSR,
|
|
3600
4170
|
flipY,
|
|
@@ -3636,13 +4206,13 @@ var transformSilkscreenGraphic = ({
|
|
|
3636
4206
|
}) => {
|
|
3637
4207
|
if (graphic.shape !== "brep") return;
|
|
3638
4208
|
graphic.brep_shape.outer_ring.vertices = graphic.brep_shape.outer_ring.vertices.map(
|
|
3639
|
-
(vertex) =>
|
|
4209
|
+
(vertex) => applyToPoint7(absoluteToComponentLocalTransform, vertex)
|
|
3640
4210
|
);
|
|
3641
4211
|
graphic.brep_shape.inner_rings = graphic.brep_shape.inner_rings.map(
|
|
3642
4212
|
(ring) => ({
|
|
3643
4213
|
...ring,
|
|
3644
4214
|
vertices: ring.vertices.map(
|
|
3645
|
-
(vertex) =>
|
|
4215
|
+
(vertex) => applyToPoint7(absoluteToComponentLocalTransform, vertex)
|
|
3646
4216
|
)
|
|
3647
4217
|
})
|
|
3648
4218
|
);
|