@tscircuit/core 0.0.2180 → 0.0.2181
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +290 -24
- package/dist/index.js +614 -11
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -18,6 +18,8 @@ __export(components_exports, {
|
|
|
18
18
|
AnalogAnalysisSimulation: () => AnalogAnalysisSimulation,
|
|
19
19
|
AnalogDcOperatingPointSimulation: () => AnalogDcOperatingPointSimulation,
|
|
20
20
|
AnalogDcSweepSimulation: () => AnalogDcSweepSimulation,
|
|
21
|
+
AnalogDigitalStimulus: () => AnalogDigitalStimulus,
|
|
22
|
+
AnalogEyeDiagram: () => AnalogEyeDiagram,
|
|
21
23
|
AnalogSimulation: () => AnalogSimulation,
|
|
22
24
|
AnalogSweepParameter: () => AnalogSweepParameter,
|
|
23
25
|
AnalogTransientSimulation: () => AnalogTransientSimulation,
|
|
@@ -66,6 +68,7 @@ __export(components_exports, {
|
|
|
66
68
|
Fuse: () => Fuse,
|
|
67
69
|
Group: () => Group5,
|
|
68
70
|
Hole: () => Hole,
|
|
71
|
+
IbisModel: () => IbisModel,
|
|
69
72
|
Inductor: () => Inductor,
|
|
70
73
|
Interconnect: () => Interconnect,
|
|
71
74
|
Jumper: () => Jumper,
|
|
@@ -1751,6 +1754,11 @@ var renderPhaseIndexMap = new Map(
|
|
|
1751
1754
|
var asyncPhaseDependencies = {
|
|
1752
1755
|
InflateSubcircuitCircuitJson: ["RenderIsolatedSubcircuits"],
|
|
1753
1756
|
ResolveFootprintPinLabels: ["PcbFootprintStringRender", "FetchPartFootprint"],
|
|
1757
|
+
SimulationRender: ["PcbFootprintStringRender", "FetchPartFootprint"],
|
|
1758
|
+
SimulationSpiceEngineRender: [
|
|
1759
|
+
"PcbFootprintStringRender",
|
|
1760
|
+
"FetchPartFootprint"
|
|
1761
|
+
],
|
|
1754
1762
|
SchematicComponentRender: ["PcbFootprintStringRender", "FetchPartFootprint"],
|
|
1755
1763
|
SchematicPortRender: ["PcbFootprintStringRender", "FetchPartFootprint"],
|
|
1756
1764
|
SymbolContainerRender: ["PcbFootprintStringRender", "FetchPartFootprint"],
|
|
@@ -20450,6 +20458,139 @@ function inflatePcbBoard(pcbBoard, inflatorContext) {
|
|
|
20450
20458
|
return board;
|
|
20451
20459
|
}
|
|
20452
20460
|
|
|
20461
|
+
// lib/components/primitive-components/Group/Subcircuit/inflators/inflateSimulation.ts
|
|
20462
|
+
import { getElementId } from "@tscircuit/circuit-json-util";
|
|
20463
|
+
var ibisSimulationTypes = [
|
|
20464
|
+
"simulation_ibis_model",
|
|
20465
|
+
"simulation_ibis_pin_state",
|
|
20466
|
+
"simulation_digital_stimulus",
|
|
20467
|
+
"simulation_eye_diagram"
|
|
20468
|
+
];
|
|
20469
|
+
var simulationTypes = [
|
|
20470
|
+
"simulation_experiment",
|
|
20471
|
+
"simulation_voltage_probe",
|
|
20472
|
+
...ibisSimulationTypes
|
|
20473
|
+
];
|
|
20474
|
+
var InflatedSimulation = class extends PrimitiveComponent2 {
|
|
20475
|
+
constructor(inflationCtx) {
|
|
20476
|
+
super({});
|
|
20477
|
+
this.inflationCtx = inflationCtx;
|
|
20478
|
+
}
|
|
20479
|
+
inflationCtx;
|
|
20480
|
+
get config() {
|
|
20481
|
+
return { ...super.config, componentName: "InflatedSimulation" };
|
|
20482
|
+
}
|
|
20483
|
+
doInitialSimulationRender() {
|
|
20484
|
+
if (this.getInheritedProperty("analogSimulationDisabled")) return;
|
|
20485
|
+
restoreSimulationRecords(this.inflationCtx);
|
|
20486
|
+
}
|
|
20487
|
+
};
|
|
20488
|
+
function restoreSimulationRecords({
|
|
20489
|
+
injectionDb,
|
|
20490
|
+
subcircuit,
|
|
20491
|
+
groupsMap
|
|
20492
|
+
}) {
|
|
20493
|
+
const { db: db2 } = subcircuit.root;
|
|
20494
|
+
const eyes = injectionDb.simulation_eye_diagram.list();
|
|
20495
|
+
const experimentIds = new Set(
|
|
20496
|
+
[
|
|
20497
|
+
...injectionDb.simulation_ibis_pin_state.list(),
|
|
20498
|
+
...injectionDb.simulation_digital_stimulus.list(),
|
|
20499
|
+
...eyes
|
|
20500
|
+
].map((record) => record.simulation_experiment_id)
|
|
20501
|
+
);
|
|
20502
|
+
const probeIds = new Set(eyes.map((eye) => eye.simulation_voltage_probe_id));
|
|
20503
|
+
const restoredIds = /* @__PURE__ */ new Map();
|
|
20504
|
+
const remapId = (originalId, field) => {
|
|
20505
|
+
const restoredId = restoredIds.get(originalId);
|
|
20506
|
+
if (restoredId) return restoredId;
|
|
20507
|
+
let matchedId;
|
|
20508
|
+
if (field === "subcircuit_id") {
|
|
20509
|
+
const sourceGroup = injectionDb.source_group.list().find((group2) => group2.subcircuit_id === originalId);
|
|
20510
|
+
const group = sourceGroup && groupsMap?.get(sourceGroup.source_group_id);
|
|
20511
|
+
matchedId = group?.getSubcircuit().subcircuit_id ?? void 0;
|
|
20512
|
+
} else if (field === "source_component_id") {
|
|
20513
|
+
const original = injectionDb.source_component.get(originalId);
|
|
20514
|
+
const group = original?.source_group_id ? groupsMap?.get(original.source_group_id) : subcircuit;
|
|
20515
|
+
if (original && group?.source_group_id) {
|
|
20516
|
+
const components = db2.source_component.list({
|
|
20517
|
+
source_group_id: group.source_group_id,
|
|
20518
|
+
name: original.name
|
|
20519
|
+
});
|
|
20520
|
+
if (components.length === 1)
|
|
20521
|
+
matchedId = components[0].source_component_id;
|
|
20522
|
+
}
|
|
20523
|
+
} else if (field.endsWith("source_port_id")) {
|
|
20524
|
+
const original = injectionDb.source_port.get(originalId);
|
|
20525
|
+
if (original?.source_component_id) {
|
|
20526
|
+
const componentId = remapId(
|
|
20527
|
+
original.source_component_id,
|
|
20528
|
+
"source_component_id"
|
|
20529
|
+
);
|
|
20530
|
+
const ports = db2.source_port.list({ source_component_id: componentId }).filter(
|
|
20531
|
+
(port) => original.pin_number !== void 0 ? port.pin_number === original.pin_number : port.name === original.name
|
|
20532
|
+
);
|
|
20533
|
+
if (ports.length === 1) matchedId = ports[0].source_port_id;
|
|
20534
|
+
}
|
|
20535
|
+
} else if (field.endsWith("source_net_id")) {
|
|
20536
|
+
const original = injectionDb.source_net.get(originalId);
|
|
20537
|
+
if (original) {
|
|
20538
|
+
const nets = db2.source_net.list({
|
|
20539
|
+
name: original.name,
|
|
20540
|
+
subcircuit_id: original.subcircuit_id ? remapId(original.subcircuit_id, "subcircuit_id") : subcircuit.subcircuit_id
|
|
20541
|
+
});
|
|
20542
|
+
if (nets.length === 1) matchedId = nets[0].source_net_id;
|
|
20543
|
+
}
|
|
20544
|
+
}
|
|
20545
|
+
if (!matchedId) {
|
|
20546
|
+
throw new Error(
|
|
20547
|
+
`Cannot restore simulation records: unable to remap ${field} safely.`
|
|
20548
|
+
);
|
|
20549
|
+
}
|
|
20550
|
+
restoredIds.set(originalId, matchedId);
|
|
20551
|
+
return matchedId;
|
|
20552
|
+
};
|
|
20553
|
+
const remapReferences = (value, field) => {
|
|
20554
|
+
if (typeof value === "string" && field.endsWith("_id"))
|
|
20555
|
+
return remapId(value, field);
|
|
20556
|
+
if (Array.isArray(value))
|
|
20557
|
+
return value.map((entry) => remapReferences(entry, field));
|
|
20558
|
+
if (value && typeof value === "object") {
|
|
20559
|
+
return Object.fromEntries(
|
|
20560
|
+
Object.entries(value).map(([key, entry]) => [
|
|
20561
|
+
key,
|
|
20562
|
+
remapReferences(
|
|
20563
|
+
entry,
|
|
20564
|
+
field === "ibis_pin_name_to_source_port_id" ? "source_port_id" : key
|
|
20565
|
+
)
|
|
20566
|
+
])
|
|
20567
|
+
);
|
|
20568
|
+
}
|
|
20569
|
+
return value;
|
|
20570
|
+
};
|
|
20571
|
+
for (const type of simulationTypes) {
|
|
20572
|
+
for (const record of injectionDb[type].list()) {
|
|
20573
|
+
if (record.type === "simulation_experiment" && !experimentIds.has(record.simulation_experiment_id) || record.type === "simulation_voltage_probe" && !probeIds.has(record.simulation_voltage_probe_id))
|
|
20574
|
+
continue;
|
|
20575
|
+
const primaryIdField = `${type}_id`;
|
|
20576
|
+
const fields = Object.fromEntries(
|
|
20577
|
+
Object.entries(record).filter(([key]) => key !== primaryIdField)
|
|
20578
|
+
);
|
|
20579
|
+
const restored = db2.insert(
|
|
20580
|
+
remapReferences(fields, "")
|
|
20581
|
+
);
|
|
20582
|
+
restoredIds.set(getElementId(record), getElementId(restored));
|
|
20583
|
+
}
|
|
20584
|
+
}
|
|
20585
|
+
}
|
|
20586
|
+
function inflateSimulation(inflationCtx) {
|
|
20587
|
+
if (!ibisSimulationTypes.some(
|
|
20588
|
+
(type) => inflationCtx.injectionDb[type].list().length > 0
|
|
20589
|
+
))
|
|
20590
|
+
return;
|
|
20591
|
+
inflationCtx.subcircuit.add(new InflatedSimulation(inflationCtx));
|
|
20592
|
+
}
|
|
20593
|
+
|
|
20453
20594
|
// lib/components/normal-components/Capacitor.ts
|
|
20454
20595
|
import { capacitorProps, resolveManufacturerPartNumber as resolveManufacturerPartNumber4 } from "@tscircuit/props";
|
|
20455
20596
|
import { formatSiUnit } from "format-si-unit";
|
|
@@ -85433,7 +85574,7 @@ var buildPowerPourPolygons = (problem) => {
|
|
|
85433
85574
|
var getLayerColor = (layer) => layer === "top" ? "#c2453a" : layer === "bottom" ? "#5b7fd8" : "#c58b43";
|
|
85434
85575
|
|
|
85435
85576
|
// node_modules/@tscircuit/implicit-copper-pour-solver/lib/prepare-circuit-json.ts
|
|
85436
|
-
import { getElementId } from "@tscircuit/circuit-json-util";
|
|
85577
|
+
import { getElementId as getElementId2 } from "@tscircuit/circuit-json-util";
|
|
85437
85578
|
import {
|
|
85438
85579
|
getBoundFromCenteredRect,
|
|
85439
85580
|
getBoundsFromPoints as getBoundsFromPoints8
|
|
@@ -85756,7 +85897,7 @@ var prepareCircuitJson = (input) => {
|
|
|
85756
85897
|
);
|
|
85757
85898
|
const netIndexByConnectivityNetwork = /* @__PURE__ */ new Map();
|
|
85758
85899
|
const getConnectivityNetIndex = (element) => {
|
|
85759
|
-
const elementId =
|
|
85900
|
+
const elementId = getElementId2(element);
|
|
85760
85901
|
const connectivityNetworkId = connectivityMap.getNetConnectedToId(elementId);
|
|
85761
85902
|
if (connectivityNetworkId) {
|
|
85762
85903
|
const connectedSourceNetIndexes = sourceNets.flatMap(
|
|
@@ -85797,7 +85938,7 @@ var prepareCircuitJson = (input) => {
|
|
|
85797
85938
|
}
|
|
85798
85939
|
const connectivityNetIndex = getConnectivityNetIndex(element);
|
|
85799
85940
|
if (connectivityNetIndex !== void 0) return connectivityNetIndex;
|
|
85800
|
-
const elementId =
|
|
85941
|
+
const elementId = getElementId2(element);
|
|
85801
85942
|
return getOrCreateImplicitNetIndex(
|
|
85802
85943
|
`${element.type}:${elementId}`,
|
|
85803
85944
|
elementId
|
|
@@ -118479,6 +118620,10 @@ function Group_doInitialSimulationSpiceEngineRender(group) {
|
|
|
118479
118620
|
debug12("No simulation experiment found, skipping simulation");
|
|
118480
118621
|
continue;
|
|
118481
118622
|
}
|
|
118623
|
+
if (simulationExperiment.spice_engine === "pcb_spice" && (!spiceEngineMap.pcb_spice || isExternalIbisExperiment(root.db, simulationExperimentId))) {
|
|
118624
|
+
debug12("Skipping external pcb_spice experiment during rendering");
|
|
118625
|
+
continue;
|
|
118626
|
+
}
|
|
118482
118627
|
const simulationScope = analogSimulation.getGroup() ?? group;
|
|
118483
118628
|
const voltageProbes = simulationScope.selectAll("voltageprobe");
|
|
118484
118629
|
const ammeters = simulationScope.selectAll("ammeter");
|
|
@@ -118687,6 +118832,10 @@ ${simulationRuns.map((simulationRun) => simulationRun.spiceString).join("\n")}`
|
|
|
118687
118832
|
});
|
|
118688
118833
|
}
|
|
118689
118834
|
}
|
|
118835
|
+
function isExternalIbisExperiment(db2, simulationExperimentId) {
|
|
118836
|
+
const belongsToExperiment = (record) => record.simulation_experiment_id === simulationExperimentId;
|
|
118837
|
+
return db2.simulation_ibis_pin_state.list().some(belongsToExperiment) || db2.simulation_digital_stimulus.list().some(belongsToExperiment) || db2.simulation_eye_diagram.list().some(belongsToExperiment);
|
|
118838
|
+
}
|
|
118690
118839
|
|
|
118691
118840
|
// lib/components/primitive-components/Group/Group_doInitialSourceAddConnectivityMapKey.ts
|
|
118692
118841
|
import { ConnectivityMap as ConnectivityMap5 } from "circuit-json-to-connectivity-map";
|
|
@@ -119560,7 +119709,7 @@ var RoutingPhasePreparationError = class extends Error {
|
|
|
119560
119709
|
var package_default = {
|
|
119561
119710
|
name: "@tscircuit/core",
|
|
119562
119711
|
type: "module",
|
|
119563
|
-
version: "0.0.
|
|
119712
|
+
version: "0.0.2180",
|
|
119564
119713
|
types: "dist/index.d.ts",
|
|
119565
119714
|
main: "dist/index.js",
|
|
119566
119715
|
module: "dist/index.js",
|
|
@@ -119619,7 +119768,7 @@ var package_default = {
|
|
|
119619
119768
|
"@tscircuit/miniflex": "^0.0.4",
|
|
119620
119769
|
"@tscircuit/modelprinter": "^0.0.18",
|
|
119621
119770
|
"@tscircuit/ngspice-spice-engine": "^0.0.20",
|
|
119622
|
-
"@tscircuit/props": "^0.0.
|
|
119771
|
+
"@tscircuit/props": "^0.0.705",
|
|
119623
119772
|
"@tscircuit/schematic-match-adapt": "^0.0.18",
|
|
119624
119773
|
"@tscircuit/schematic-trace-solver": "https://jscdn.tscircuit.com/@tscircuit/schematic-trace-solver/0.0.230.tgz",
|
|
119625
119774
|
"@tscircuit/solver-utils": "^0.0.16",
|
|
@@ -119635,7 +119784,7 @@ var package_default = {
|
|
|
119635
119784
|
"bun-match-svg": "0.0.12",
|
|
119636
119785
|
"calculate-elbow": "^0.0.12",
|
|
119637
119786
|
"chokidar-cli": "^3.0.0",
|
|
119638
|
-
"circuit-json": "^0.0.
|
|
119787
|
+
"circuit-json": "^0.0.529",
|
|
119639
119788
|
"circuit-json-to-bpc": "^0.0.13",
|
|
119640
119789
|
"circuit-json-to-connectivity-map": "^0.0.33",
|
|
119641
119790
|
"circuit-json-to-gltf": "^0.0.151",
|
|
@@ -119702,8 +119851,8 @@ var package_default = {
|
|
|
119702
119851
|
"jscad-fiber": "^0.0.88"
|
|
119703
119852
|
},
|
|
119704
119853
|
overrides: {
|
|
119705
|
-
"@tscircuit/props": "^0.0.
|
|
119706
|
-
"circuit-json": "^0.0.
|
|
119854
|
+
"@tscircuit/props": "^0.0.705",
|
|
119855
|
+
"circuit-json": "^0.0.529",
|
|
119707
119856
|
"@tscircuit/cableprinter": "^0.0.6"
|
|
119708
119857
|
}
|
|
119709
119858
|
};
|
|
@@ -124079,6 +124228,7 @@ var inflateCircuitJson = (target, circuitJson, children) => {
|
|
|
124079
124228
|
inflateSourceTrace(sourceTrace, inflationCtx);
|
|
124080
124229
|
}
|
|
124081
124230
|
inflateStandalonePcbPrimitives(inflationCtx);
|
|
124231
|
+
inflateSimulation(inflationCtx);
|
|
124082
124232
|
};
|
|
124083
124233
|
|
|
124084
124234
|
// lib/components/primitive-components/resolve-board-motor-mount.ts
|
|
@@ -134097,6 +134247,80 @@ var AnalogAnalysisSimulation = class extends PrimitiveComponent2 {
|
|
|
134097
134247
|
|
|
134098
134248
|
// lib/components/primitive-components/AnalogTransientSimulation.ts
|
|
134099
134249
|
import { analogTransientSimulationProps } from "@tscircuit/props";
|
|
134250
|
+
|
|
134251
|
+
// lib/utils/simulation/resolveExternalSimulation.ts
|
|
134252
|
+
function resolveExternalSimulationPort({
|
|
134253
|
+
declaration,
|
|
134254
|
+
selector
|
|
134255
|
+
}) {
|
|
134256
|
+
const ports = declaration.getSubcircuit().selectAll(selector).filter((port2) => port2.componentName === "Port");
|
|
134257
|
+
if (ports.length !== 1 || !ports[0].source_port_id) {
|
|
134258
|
+
throw new Error(
|
|
134259
|
+
`Simulation pin selector "${selector}" must identify exactly one physical source pin.`
|
|
134260
|
+
);
|
|
134261
|
+
}
|
|
134262
|
+
const port = ports[0];
|
|
134263
|
+
if (port.getSubcircuit() !== declaration.getSubcircuit()) {
|
|
134264
|
+
throw new Error(
|
|
134265
|
+
`Simulation pin "${selector}" must belong to the same subcircuit as its declaration.`
|
|
134266
|
+
);
|
|
134267
|
+
}
|
|
134268
|
+
return port;
|
|
134269
|
+
}
|
|
134270
|
+
function resolveExternalTransientSimulation({
|
|
134271
|
+
declaration,
|
|
134272
|
+
selector
|
|
134273
|
+
}) {
|
|
134274
|
+
const simulations = declaration.getSubcircuit().selectAll(selector).filter(
|
|
134275
|
+
(simulation3) => simulation3.componentName === "AnalogTransientSimulation"
|
|
134276
|
+
);
|
|
134277
|
+
if (simulations.length !== 1 || simulations[0].getSubcircuit() !== declaration.getSubcircuit()) {
|
|
134278
|
+
throw new Error(
|
|
134279
|
+
`Simulation selector "${selector}" must identify one transient in the same subcircuit.`
|
|
134280
|
+
);
|
|
134281
|
+
}
|
|
134282
|
+
const simulation2 = simulations[0];
|
|
134283
|
+
if (simulation2.getSpiceEngineName() !== "pcb_spice") {
|
|
134284
|
+
throw new Error(
|
|
134285
|
+
`Simulation "${selector}" requires spiceEngine="pcb_spice" for IBIS declarations.`
|
|
134286
|
+
);
|
|
134287
|
+
}
|
|
134288
|
+
simulation2.getOrCreateSimulationExperiment();
|
|
134289
|
+
return simulation2;
|
|
134290
|
+
}
|
|
134291
|
+
|
|
134292
|
+
// lib/components/primitive-components/AnalogTransientSimulation_validateIbisBindings.ts
|
|
134293
|
+
function AnalogTransientSimulation_validateIbisBindings(simulation2) {
|
|
134294
|
+
if (simulation2.getSpiceEngineName() !== "pcb_spice") return;
|
|
134295
|
+
const subcircuit = simulation2.getSubcircuit();
|
|
134296
|
+
const models = subcircuit.selectAll("ibismodel").filter(
|
|
134297
|
+
(model) => !model.shouldBeRemoved && model.getSubcircuit() === subcircuit
|
|
134298
|
+
).map(
|
|
134299
|
+
(model) => simulation2.root.db.simulation_ibis_model.get(
|
|
134300
|
+
model.simulation_ibis_model_id
|
|
134301
|
+
)
|
|
134302
|
+
);
|
|
134303
|
+
for (const selector of Object.keys(
|
|
134304
|
+
simulation2._parsedProps.ibisPinStates ?? {}
|
|
134305
|
+
)) {
|
|
134306
|
+
const port = resolveExternalSimulationPort({
|
|
134307
|
+
declaration: simulation2,
|
|
134308
|
+
selector
|
|
134309
|
+
});
|
|
134310
|
+
const bindings = models.filter(
|
|
134311
|
+
(model) => Object.values(model.ibis_pin_name_to_source_port_id).includes(
|
|
134312
|
+
port.source_port_id
|
|
134313
|
+
)
|
|
134314
|
+
);
|
|
134315
|
+
if (bindings.length !== 1) {
|
|
134316
|
+
throw new Error(
|
|
134317
|
+
`Simulation "${simulation2._parsedProps.name ?? "transient"}" pin "${selector}" requires exactly one IBIS model binding in this subcircuit.`
|
|
134318
|
+
);
|
|
134319
|
+
}
|
|
134320
|
+
}
|
|
134321
|
+
}
|
|
134322
|
+
|
|
134323
|
+
// lib/components/primitive-components/AnalogTransientSimulation.ts
|
|
134100
134324
|
var AnalogTransientSimulation = class extends AnalogAnalysisSimulation {
|
|
134101
134325
|
get config() {
|
|
134102
134326
|
return {
|
|
@@ -134104,17 +134328,389 @@ var AnalogTransientSimulation = class extends AnalogAnalysisSimulation {
|
|
|
134104
134328
|
zodProps: analogTransientSimulationProps
|
|
134105
134329
|
};
|
|
134106
134330
|
}
|
|
134331
|
+
doInitialSimulationSpiceEngineRender() {
|
|
134332
|
+
if (this.getInheritedProperty("analogSimulationDisabled")) return;
|
|
134333
|
+
AnalogTransientSimulation_validateIbisBindings(this);
|
|
134334
|
+
}
|
|
134335
|
+
updateSimulationSpiceEngineRender() {
|
|
134336
|
+
this.doInitialSimulationSpiceEngineRender();
|
|
134337
|
+
}
|
|
134338
|
+
onPropsChange() {
|
|
134339
|
+
this._markDirty("SimulationRender");
|
|
134340
|
+
if (!this.simulation_experiment_id) return;
|
|
134341
|
+
const subcircuit = this.getSubcircuit();
|
|
134342
|
+
for (const declaration of [
|
|
134343
|
+
...subcircuit.selectAll("analogdigitalstimulus"),
|
|
134344
|
+
...subcircuit.selectAll("analogeyediagram")
|
|
134345
|
+
]) {
|
|
134346
|
+
if (declaration.getSubcircuit() === subcircuit)
|
|
134347
|
+
declaration._markDirty("SimulationSpiceEngineRender");
|
|
134348
|
+
}
|
|
134349
|
+
}
|
|
134350
|
+
updateSimulationRender() {
|
|
134351
|
+
this.insertSimulationExperiment();
|
|
134352
|
+
}
|
|
134353
|
+
removeIbisPinStates() {
|
|
134354
|
+
for (const state of this.root.db.simulation_ibis_pin_state.list({
|
|
134355
|
+
simulation_experiment_id: this.simulation_experiment_id
|
|
134356
|
+
})) {
|
|
134357
|
+
this.root.db.simulation_ibis_pin_state.delete(
|
|
134358
|
+
state.simulation_ibis_pin_state_id
|
|
134359
|
+
);
|
|
134360
|
+
}
|
|
134361
|
+
}
|
|
134362
|
+
removeSimulationRender() {
|
|
134363
|
+
if (!this.simulation_experiment_id) return;
|
|
134364
|
+
this.removeIbisPinStates();
|
|
134365
|
+
this.root.db.simulation_experiment.delete(this.simulation_experiment_id);
|
|
134366
|
+
this.simulation_experiment_id = null;
|
|
134367
|
+
}
|
|
134107
134368
|
insertSimulationExperiment() {
|
|
134108
134369
|
const { db: db2 } = this.root;
|
|
134109
134370
|
const { duration, name, startTime, timePerStep, spiceOptions } = this._parsedProps;
|
|
134110
|
-
|
|
134371
|
+
const ibisPinStates = this.getInheritedProperty("analogSimulationDisabled") ? {} : this._parsedProps.ibisPinStates;
|
|
134372
|
+
const pins = Object.entries(ibisPinStates ?? {}).map(
|
|
134373
|
+
([selector, state]) => {
|
|
134374
|
+
const pin = {
|
|
134375
|
+
source_port_id: resolveExternalSimulationPort({
|
|
134376
|
+
declaration: this,
|
|
134377
|
+
selector
|
|
134378
|
+
}).source_port_id,
|
|
134379
|
+
is_output: state.isOutput
|
|
134380
|
+
};
|
|
134381
|
+
if (state.isOutput)
|
|
134382
|
+
return { ...pin, is_output_enabled: state.isOutputEnabled };
|
|
134383
|
+
return pin;
|
|
134384
|
+
}
|
|
134385
|
+
);
|
|
134386
|
+
if (new Set(pins.map((pin) => pin.source_port_id)).size !== pins.length) {
|
|
134387
|
+
throw new Error(
|
|
134388
|
+
`Simulation "${name ?? "transient"}" assigns multiple states to the same physical pin.`
|
|
134389
|
+
);
|
|
134390
|
+
}
|
|
134391
|
+
const experimentProps = {
|
|
134111
134392
|
name: name ?? "spice_transient_analysis",
|
|
134112
134393
|
experiment_type: "spice_transient_analysis",
|
|
134113
134394
|
end_time_ms: duration,
|
|
134114
134395
|
start_time_ms: startTime,
|
|
134115
134396
|
time_per_step: timePerStep,
|
|
134116
|
-
spice_options: spiceOptions
|
|
134117
|
-
|
|
134397
|
+
spice_options: spiceOptions,
|
|
134398
|
+
spice_engine: this.getSpiceEngineName(),
|
|
134399
|
+
subcircuit_id: this.getSubcircuit().subcircuit_id
|
|
134400
|
+
};
|
|
134401
|
+
const experiment = this.simulation_experiment_id ? db2.simulation_experiment.update(
|
|
134402
|
+
this.simulation_experiment_id,
|
|
134403
|
+
experimentProps
|
|
134404
|
+
) : db2.simulation_experiment.insert(experimentProps);
|
|
134405
|
+
if (this.simulation_experiment_id) this.removeIbisPinStates();
|
|
134406
|
+
for (const pin of pins) {
|
|
134407
|
+
db2.simulation_ibis_pin_state.insert({
|
|
134408
|
+
simulation_experiment_id: experiment.simulation_experiment_id,
|
|
134409
|
+
...pin
|
|
134410
|
+
});
|
|
134411
|
+
}
|
|
134412
|
+
return experiment;
|
|
134413
|
+
}
|
|
134414
|
+
};
|
|
134415
|
+
|
|
134416
|
+
// lib/components/primitive-components/AnalogDigitalStimulus.ts
|
|
134417
|
+
import { analogDigitalStimulusProps } from "@tscircuit/props";
|
|
134418
|
+
|
|
134419
|
+
// lib/components/primitive-components/AnalogDigitalStimulus_getSimulationDigitalStimulus.ts
|
|
134420
|
+
function AnalogDigitalStimulus_getSimulationDigitalStimulus(declaration) {
|
|
134421
|
+
const props = declaration._parsedProps;
|
|
134422
|
+
const simulation2 = resolveExternalTransientSimulation({
|
|
134423
|
+
declaration,
|
|
134424
|
+
selector: props.simulationRef
|
|
134425
|
+
});
|
|
134426
|
+
const port = resolveExternalSimulationPort({
|
|
134427
|
+
declaration,
|
|
134428
|
+
selector: props.sourcePinRef
|
|
134429
|
+
});
|
|
134430
|
+
const experiment = simulation2.getOrCreateSimulationExperiment();
|
|
134431
|
+
if (props.startTime >= experiment.end_time_ms)
|
|
134432
|
+
throw new Error(`Stimulus "${props.name}" starts outside its simulation.`);
|
|
134433
|
+
const pinState = declaration.root.db.simulation_ibis_pin_state.list({
|
|
134434
|
+
simulation_experiment_id: experiment.simulation_experiment_id
|
|
134435
|
+
}).find((state) => state.source_port_id === port.source_port_id);
|
|
134436
|
+
if (pinState?.is_output !== true || pinState.is_output_enabled !== true) {
|
|
134437
|
+
throw new Error(
|
|
134438
|
+
`Stimulus "${props.name}" must drive a pin declared as an enabled output in its simulation.`
|
|
134439
|
+
);
|
|
134440
|
+
}
|
|
134441
|
+
if (declaration.root.db.simulation_digital_stimulus.list({
|
|
134442
|
+
simulation_experiment_id: experiment.simulation_experiment_id
|
|
134443
|
+
}).some(
|
|
134444
|
+
(stimulus) => stimulus.simulation_digital_stimulus_id !== declaration.simulation_digital_stimulus_id && (stimulus.source_port_id === port.source_port_id || stimulus.name === props.name)
|
|
134445
|
+
)) {
|
|
134446
|
+
throw new Error(
|
|
134447
|
+
`Stimulus "${props.name}" duplicates a driven pin or stimulus name in this simulation.`
|
|
134448
|
+
);
|
|
134449
|
+
}
|
|
134450
|
+
return {
|
|
134451
|
+
type: "simulation_digital_stimulus",
|
|
134452
|
+
name: props.name,
|
|
134453
|
+
simulation_experiment_id: experiment.simulation_experiment_id,
|
|
134454
|
+
source_port_id: port.source_port_id,
|
|
134455
|
+
bit_duration_ms: props.bitDuration,
|
|
134456
|
+
start_time_ms: props.startTime,
|
|
134457
|
+
initial_state: props.initialState,
|
|
134458
|
+
inverted: props.inverted,
|
|
134459
|
+
transmission_pattern: {
|
|
134460
|
+
transmission_type: props.transmittedData.transmissionType,
|
|
134461
|
+
bits: props.transmittedData.bits,
|
|
134462
|
+
repeat: props.transmittedData.repeat
|
|
134463
|
+
}
|
|
134464
|
+
};
|
|
134465
|
+
}
|
|
134466
|
+
|
|
134467
|
+
// lib/components/primitive-components/AnalogDigitalStimulus.ts
|
|
134468
|
+
var AnalogDigitalStimulus = class extends PrimitiveComponent2 {
|
|
134469
|
+
simulation_digital_stimulus_id = null;
|
|
134470
|
+
get config() {
|
|
134471
|
+
return {
|
|
134472
|
+
componentName: "AnalogDigitalStimulus",
|
|
134473
|
+
zodProps: analogDigitalStimulusProps
|
|
134474
|
+
};
|
|
134475
|
+
}
|
|
134476
|
+
doInitialSimulationRender() {
|
|
134477
|
+
if (this.getInheritedProperty("analogSimulationDisabled")) return;
|
|
134478
|
+
const stimulus = AnalogDigitalStimulus_getSimulationDigitalStimulus(this);
|
|
134479
|
+
if (this.simulation_digital_stimulus_id)
|
|
134480
|
+
this.root.db.simulation_digital_stimulus.update(
|
|
134481
|
+
this.simulation_digital_stimulus_id,
|
|
134482
|
+
stimulus
|
|
134483
|
+
);
|
|
134484
|
+
else
|
|
134485
|
+
this.simulation_digital_stimulus_id = this.root.db.simulation_digital_stimulus.insert(
|
|
134486
|
+
stimulus
|
|
134487
|
+
).simulation_digital_stimulus_id;
|
|
134488
|
+
}
|
|
134489
|
+
onPropsChange() {
|
|
134490
|
+
this._markDirty("SimulationSpiceEngineRender");
|
|
134491
|
+
}
|
|
134492
|
+
// Refresh traffic after every experiment has updated its pin states.
|
|
134493
|
+
updateSimulationSpiceEngineRender() {
|
|
134494
|
+
this.doInitialSimulationRender();
|
|
134495
|
+
}
|
|
134496
|
+
removeSimulationRender() {
|
|
134497
|
+
if (this.simulation_digital_stimulus_id)
|
|
134498
|
+
this.root.db.simulation_digital_stimulus.delete(
|
|
134499
|
+
this.simulation_digital_stimulus_id
|
|
134500
|
+
);
|
|
134501
|
+
this.simulation_digital_stimulus_id = null;
|
|
134502
|
+
}
|
|
134503
|
+
};
|
|
134504
|
+
|
|
134505
|
+
// lib/components/primitive-components/AnalogEyeDiagram.ts
|
|
134506
|
+
import { analogEyeDiagramProps } from "@tscircuit/props";
|
|
134507
|
+
|
|
134508
|
+
// lib/components/primitive-components/AnalogEyeDiagram_getSimulationEyeDiagram.ts
|
|
134509
|
+
function AnalogEyeDiagram_getSimulationEyeDiagram(declaration) {
|
|
134510
|
+
const props = declaration._parsedProps;
|
|
134511
|
+
const simulation2 = resolveExternalTransientSimulation({
|
|
134512
|
+
declaration,
|
|
134513
|
+
selector: props.simulationRef
|
|
134514
|
+
});
|
|
134515
|
+
const experiment = simulation2.getOrCreateSimulationExperiment();
|
|
134516
|
+
const probes = declaration.getSubcircuit().selectAll(props.probeRef).filter((probe2) => probe2.componentName === "VoltageProbe");
|
|
134517
|
+
if (probes.length !== 1 || probes[0].getSubcircuit() !== declaration.getSubcircuit()) {
|
|
134518
|
+
throw new Error(
|
|
134519
|
+
`Eye probe selector "${props.probeRef}" must identify one voltage probe in this subcircuit.`
|
|
134520
|
+
);
|
|
134521
|
+
}
|
|
134522
|
+
const probe = probes[0];
|
|
134523
|
+
if (!probe.simulation_voltage_probe_id) {
|
|
134524
|
+
throw new Error(
|
|
134525
|
+
`Eye probe "${props.probeRef}" did not render a voltage probe.`
|
|
134526
|
+
);
|
|
134527
|
+
}
|
|
134528
|
+
const start = props.startTime ?? experiment.start_time_ms ?? 0, end = props.endTime ?? experiment.end_time_ms;
|
|
134529
|
+
const firstBoundary = (start - props.timeOrigin) / props.unitInterval + 0.5;
|
|
134530
|
+
const lastBoundary = (end - props.timeOrigin) / props.unitInterval - 1.5;
|
|
134531
|
+
const roundingTolerance = 8 * Number.EPSILON * Math.max(1, Math.abs(firstBoundary), Math.abs(lastBoundary));
|
|
134532
|
+
if (start < (experiment.start_time_ms ?? 0) || end > experiment.end_time_ms || end <= start || Math.ceil(firstBoundary - roundingTolerance) > Math.floor(lastBoundary + roundingTolerance)) {
|
|
134533
|
+
throw new Error(
|
|
134534
|
+
`Eye "${props.name}" needs a gate within its simulation containing at least two bit intervals forming a complete two-UI eye window aligned to timeOrigin after recording starts.`
|
|
134535
|
+
);
|
|
134536
|
+
}
|
|
134537
|
+
return {
|
|
134538
|
+
type: "simulation_eye_diagram",
|
|
134539
|
+
name: props.name,
|
|
134540
|
+
simulation_experiment_id: experiment.simulation_experiment_id,
|
|
134541
|
+
simulation_voltage_probe_id: probe.simulation_voltage_probe_id,
|
|
134542
|
+
unit_interval_ms: props.unitInterval,
|
|
134543
|
+
time_origin_ms: props.timeOrigin,
|
|
134544
|
+
start_time_ms: start,
|
|
134545
|
+
end_time_ms: end
|
|
134546
|
+
};
|
|
134547
|
+
}
|
|
134548
|
+
|
|
134549
|
+
// lib/components/primitive-components/AnalogEyeDiagram.ts
|
|
134550
|
+
var AnalogEyeDiagram = class extends PrimitiveComponent2 {
|
|
134551
|
+
simulation_eye_diagram_id = null;
|
|
134552
|
+
get config() {
|
|
134553
|
+
return {
|
|
134554
|
+
componentName: "AnalogEyeDiagram",
|
|
134555
|
+
zodProps: analogEyeDiagramProps
|
|
134556
|
+
};
|
|
134557
|
+
}
|
|
134558
|
+
// Probes have finished SimulationRender before this phase, independent of JSX order.
|
|
134559
|
+
doInitialSimulationSpiceEngineRender() {
|
|
134560
|
+
if (this.getInheritedProperty("analogSimulationDisabled")) return;
|
|
134561
|
+
const eye = AnalogEyeDiagram_getSimulationEyeDiagram(this);
|
|
134562
|
+
if (this.simulation_eye_diagram_id)
|
|
134563
|
+
this.root.db.simulation_eye_diagram.update(
|
|
134564
|
+
this.simulation_eye_diagram_id,
|
|
134565
|
+
eye
|
|
134566
|
+
);
|
|
134567
|
+
else
|
|
134568
|
+
this.simulation_eye_diagram_id = this.root.db.simulation_eye_diagram.insert(
|
|
134569
|
+
eye
|
|
134570
|
+
).simulation_eye_diagram_id;
|
|
134571
|
+
}
|
|
134572
|
+
onPropsChange() {
|
|
134573
|
+
this._markDirty("SimulationSpiceEngineRender");
|
|
134574
|
+
}
|
|
134575
|
+
updateSimulationSpiceEngineRender() {
|
|
134576
|
+
this.doInitialSimulationSpiceEngineRender();
|
|
134577
|
+
}
|
|
134578
|
+
removeSimulationSpiceEngineRender() {
|
|
134579
|
+
if (this.simulation_eye_diagram_id)
|
|
134580
|
+
this.root.db.simulation_eye_diagram.delete(
|
|
134581
|
+
this.simulation_eye_diagram_id
|
|
134582
|
+
);
|
|
134583
|
+
this.simulation_eye_diagram_id = null;
|
|
134584
|
+
}
|
|
134585
|
+
};
|
|
134586
|
+
|
|
134587
|
+
// lib/components/primitive-components/IbisModel.ts
|
|
134588
|
+
import { ibisModelProps } from "@tscircuit/props";
|
|
134589
|
+
|
|
134590
|
+
// lib/components/primitive-components/IbisModel_getSimulationIbisModel.ts
|
|
134591
|
+
function IbisModel_getSimulationIbisModel(declaration) {
|
|
134592
|
+
const props = declaration._parsedProps;
|
|
134593
|
+
const chips = declaration.getSubcircuit().selectAll(props.componentRef).filter((chip2) => chip2.source_component_id);
|
|
134594
|
+
if (chips.length !== 1 || chips[0].getSubcircuit() !== declaration.getSubcircuit()) {
|
|
134595
|
+
throw new Error(
|
|
134596
|
+
`IBIS component selector "${props.componentRef}" must identify one component in this subcircuit.`
|
|
134597
|
+
);
|
|
134598
|
+
}
|
|
134599
|
+
const chip = chips[0];
|
|
134600
|
+
if (declaration.root.db.simulation_ibis_model.list({
|
|
134601
|
+
source_component_id: chip.source_component_id
|
|
134602
|
+
}).some(
|
|
134603
|
+
(model) => model.simulation_ibis_model_id !== declaration.simulation_ibis_model_id
|
|
134604
|
+
)) {
|
|
134605
|
+
throw new Error(
|
|
134606
|
+
`Component "${props.componentRef}" already has an IBIS model.`
|
|
134607
|
+
);
|
|
134608
|
+
}
|
|
134609
|
+
const pinMap = Object.fromEntries(
|
|
134610
|
+
Object.entries(props.ibisPinNameToPortLabel).map(([pin, label]) => [
|
|
134611
|
+
pin,
|
|
134612
|
+
resolveExternalSimulationPort({
|
|
134613
|
+
declaration,
|
|
134614
|
+
selector: `${props.componentRef} > .${label}`
|
|
134615
|
+
}).source_port_id
|
|
134616
|
+
])
|
|
134617
|
+
);
|
|
134618
|
+
const ibisPinNameBySourcePortId = /* @__PURE__ */ new Map();
|
|
134619
|
+
for (const [pin, sourcePortId] of Object.entries(pinMap)) {
|
|
134620
|
+
const previousPin = ibisPinNameBySourcePortId.get(sourcePortId);
|
|
134621
|
+
if (previousPin !== void 0) {
|
|
134622
|
+
throw new Error(
|
|
134623
|
+
`IBIS pins "${previousPin}" and "${pin}" on "${props.componentRef}" resolve to the same physical pin.`
|
|
134624
|
+
);
|
|
134625
|
+
}
|
|
134626
|
+
ibisPinNameBySourcePortId.set(sourcePortId, pin);
|
|
134627
|
+
}
|
|
134628
|
+
for (const pin of [
|
|
134629
|
+
...Object.keys(props.ibisPinNameToReferencePortLabels ?? {}),
|
|
134630
|
+
...Object.keys(props.ibisPinNameToModelName ?? {})
|
|
134631
|
+
]) {
|
|
134632
|
+
if (!Object.hasOwn(props.ibisPinNameToPortLabel, pin)) {
|
|
134633
|
+
throw new Error(
|
|
134634
|
+
`IBIS pin "${pin}" is referenced but not present in ibisPinNameToPortLabel.`
|
|
134635
|
+
);
|
|
134636
|
+
}
|
|
134637
|
+
}
|
|
134638
|
+
let references;
|
|
134639
|
+
if (props.ibisPinNameToReferencePortLabels) {
|
|
134640
|
+
references = {};
|
|
134641
|
+
for (const [pin, pinReferences] of Object.entries(
|
|
134642
|
+
props.ibisPinNameToReferencePortLabels
|
|
134643
|
+
)) {
|
|
134644
|
+
references[pin] = {};
|
|
134645
|
+
for (const [role, sourcePortIdField] of [
|
|
134646
|
+
["pullup", "pullup_reference_source_port_id"],
|
|
134647
|
+
["pulldown", "pulldown_reference_source_port_id"],
|
|
134648
|
+
["powerClamp", "power_clamp_reference_source_port_id"],
|
|
134649
|
+
["groundClamp", "ground_clamp_reference_source_port_id"],
|
|
134650
|
+
["external", "external_reference_source_port_id"]
|
|
134651
|
+
]) {
|
|
134652
|
+
const label = pinReferences[role];
|
|
134653
|
+
if (label === void 0) continue;
|
|
134654
|
+
references[pin][sourcePortIdField] = resolveExternalSimulationPort({
|
|
134655
|
+
declaration,
|
|
134656
|
+
selector: `${props.componentRef} > .${label}`
|
|
134657
|
+
}).source_port_id;
|
|
134658
|
+
}
|
|
134659
|
+
}
|
|
134660
|
+
}
|
|
134661
|
+
return {
|
|
134662
|
+
type: "simulation_ibis_model",
|
|
134663
|
+
source_component_id: chip.source_component_id,
|
|
134664
|
+
ibis_model_asset: props.ibisModelAsset,
|
|
134665
|
+
ibis_component_name: props.ibisComponentName,
|
|
134666
|
+
model_value_corner: props.modelValueCorner,
|
|
134667
|
+
include_package_parasitics: props.includePackageParasitics,
|
|
134668
|
+
ibis_pin_name_to_model_name: props.ibisPinNameToModelName,
|
|
134669
|
+
ibis_pin_name_to_source_port_id: pinMap,
|
|
134670
|
+
ibis_pin_name_to_reference_source_port_ids: references
|
|
134671
|
+
};
|
|
134672
|
+
}
|
|
134673
|
+
|
|
134674
|
+
// lib/components/primitive-components/IbisModel.ts
|
|
134675
|
+
var IbisModel = class extends PrimitiveComponent2 {
|
|
134676
|
+
simulation_ibis_model_id = null;
|
|
134677
|
+
get config() {
|
|
134678
|
+
return { componentName: "IbisModel", zodProps: ibisModelProps };
|
|
134679
|
+
}
|
|
134680
|
+
onPropsChange() {
|
|
134681
|
+
this._markDirty("SimulationRender");
|
|
134682
|
+
}
|
|
134683
|
+
markIbisBindingsDirty() {
|
|
134684
|
+
const subcircuit = this.getSubcircuit();
|
|
134685
|
+
for (const simulation2 of subcircuit.selectAll(
|
|
134686
|
+
"analogtransientsimulation"
|
|
134687
|
+
)) {
|
|
134688
|
+
if (simulation2.getSubcircuit() === subcircuit)
|
|
134689
|
+
simulation2._markDirty("SimulationSpiceEngineRender");
|
|
134690
|
+
}
|
|
134691
|
+
}
|
|
134692
|
+
doInitialSimulationRender() {
|
|
134693
|
+
if (this.getInheritedProperty("analogSimulationDisabled")) return;
|
|
134694
|
+
const model = IbisModel_getSimulationIbisModel(this);
|
|
134695
|
+
if (this.simulation_ibis_model_id)
|
|
134696
|
+
this.root.db.simulation_ibis_model.update(
|
|
134697
|
+
this.simulation_ibis_model_id,
|
|
134698
|
+
model
|
|
134699
|
+
);
|
|
134700
|
+
else
|
|
134701
|
+
this.simulation_ibis_model_id = this.root.db.simulation_ibis_model.insert(
|
|
134702
|
+
model
|
|
134703
|
+
).simulation_ibis_model_id;
|
|
134704
|
+
this.markIbisBindingsDirty();
|
|
134705
|
+
}
|
|
134706
|
+
updateSimulationRender() {
|
|
134707
|
+
this.doInitialSimulationRender();
|
|
134708
|
+
}
|
|
134709
|
+
removeSimulationRender() {
|
|
134710
|
+
if (this.simulation_ibis_model_id)
|
|
134711
|
+
this.root.db.simulation_ibis_model.delete(this.simulation_ibis_model_id);
|
|
134712
|
+
this.simulation_ibis_model_id = null;
|
|
134713
|
+
this.markIbisBindingsDirty();
|
|
134118
134714
|
}
|
|
134119
134715
|
};
|
|
134120
134716
|
|
|
@@ -136050,6 +136646,10 @@ var createNamespacedElement = (hostType) => {
|
|
|
136050
136646
|
|
|
136051
136647
|
// lib/namespaced-elements/analog.ts
|
|
136052
136648
|
var analog = {
|
|
136649
|
+
digitalstimulus: createNamespacedElement(
|
|
136650
|
+
"analogdigitalstimulus"
|
|
136651
|
+
),
|
|
136652
|
+
eyediagram: createNamespacedElement("analogeyediagram"),
|
|
136053
136653
|
transientsimulation: createNamespacedElement(
|
|
136054
136654
|
"analogtransientsimulation"
|
|
136055
136655
|
),
|
|
@@ -136359,6 +136959,8 @@ export {
|
|
|
136359
136959
|
AnalogAnalysisSimulation,
|
|
136360
136960
|
AnalogDcOperatingPointSimulation,
|
|
136361
136961
|
AnalogDcSweepSimulation,
|
|
136962
|
+
AnalogDigitalStimulus,
|
|
136963
|
+
AnalogEyeDiagram,
|
|
136362
136964
|
AnalogSimulation,
|
|
136363
136965
|
AnalogSweepParameter,
|
|
136364
136966
|
AnalogTransientSimulation,
|
|
@@ -136408,6 +137010,7 @@ export {
|
|
|
136408
137010
|
Fuse,
|
|
136409
137011
|
Group5 as Group,
|
|
136410
137012
|
Hole,
|
|
137013
|
+
IbisModel,
|
|
136411
137014
|
Inductor,
|
|
136412
137015
|
Interconnect,
|
|
136413
137016
|
IsolatedCircuit,
|