@tscircuit/core 0.0.1246 → 0.0.1248

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 CHANGED
@@ -131711,6 +131711,7 @@ declare class Mosfet extends NormalComponent<typeof mosfetProps> {
131711
131711
  }
131712
131712
 
131713
131713
  declare class OpAmp extends NormalComponent<typeof opampProps, OpAmpPinLabels> {
131714
+ getSchematicSymbolName(): BaseSymbolName;
131714
131715
  get config(): {
131715
131716
  componentName: string;
131716
131717
  schematicSymbolName: BaseSymbolName;
package/dist/index.js CHANGED
@@ -35,7 +35,7 @@ __export(components_exports, {
35
35
  Fiducial: () => Fiducial,
36
36
  Footprint: () => Footprint,
37
37
  Fuse: () => Fuse,
38
- Group: () => Group6,
38
+ Group: () => Group5,
39
39
  Hole: () => Hole,
40
40
  Inductor: () => Inductor,
41
41
  Interconnect: () => Interconnect,
@@ -2226,8 +2226,8 @@ var Net = class extends PrimitiveComponent2 {
2226
2226
  doInitialSourceRender() {
2227
2227
  const { db } = this.root;
2228
2228
  const { _parsedProps: props } = this;
2229
- const isGround = props.name.startsWith("GND");
2230
- const isPositiveVoltageSource = props.name.startsWith("V");
2229
+ const isGround = props.isGroundNet ?? props.name.startsWith("GND");
2230
+ const isPositiveVoltageSource = props.isPowerNet ?? props.name.startsWith("V");
2231
2231
  const net = db.source_net.insert({
2232
2232
  name: props.name,
2233
2233
  member_source_group_ids: [],
@@ -3104,14 +3104,22 @@ var getObstaclesFromCircuitJson = (circuitJson, connMap) => {
3104
3104
  };
3105
3105
 
3106
3106
  // lib/utils/schematic/computeSchematicNetLabelCenter.ts
3107
+ var getSchematicNetLabelTextWidth = ({
3108
+ text,
3109
+ font_size = 0.18
3110
+ }) => {
3111
+ const fontScale = font_size / 0.18;
3112
+ const charWidth = 0.12 * fontScale;
3113
+ const horizontalPadding = 0.12 * fontScale;
3114
+ return text.length * charWidth + horizontalPadding;
3115
+ };
3107
3116
  var computeSchematicNetLabelCenter = ({
3108
3117
  anchor_position,
3109
3118
  anchor_side,
3110
3119
  text,
3111
3120
  font_size = 0.18
3112
3121
  }) => {
3113
- const charWidth = 0.1 * (font_size / 0.18);
3114
- const width = text.length * charWidth;
3122
+ const width = getSchematicNetLabelTextWidth({ text, font_size });
3115
3123
  const height = font_size;
3116
3124
  const center = { ...anchor_position };
3117
3125
  switch (anchor_side) {
@@ -17425,20 +17433,15 @@ var Group_doInitialSchematicBoxComponentRender = (group) => {
17425
17433
  };
17426
17434
 
17427
17435
  // lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/Group_doInitialSchematicTraceRender.ts
17428
- import { SchematicTracePipelineSolver as SchematicTracePipelineSolver4 } from "@tscircuit/schematic-trace-solver";
17436
+ import { SchematicTracePipelineSolver as SchematicTracePipelineSolver3 } from "@tscircuit/schematic-trace-solver";
17429
17437
  import Debug11 from "debug";
17430
17438
 
17431
17439
  // lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/createSchematicTraceSolverInputProblem.ts
17432
17440
  import "@tscircuit/schematic-trace-solver";
17433
17441
  function createSchematicTraceSolverInputProblem(group) {
17434
17442
  const { db } = group.root;
17435
- const sckToSourceNet = /* @__PURE__ */ new Map();
17436
- const sckToUserNetId = /* @__PURE__ */ new Map();
17437
- const allScks = /* @__PURE__ */ new Set();
17443
+ const connKeyToSourceNet = /* @__PURE__ */ new Map();
17438
17444
  const traces = group.selectAll("trace");
17439
- const displayLabelTraces = traces.filter(
17440
- (t) => t._parsedProps?.schDisplayLabel
17441
- );
17442
17445
  const childGroups = group.selectAll("group");
17443
17446
  const allSchematicGroupIds = [
17444
17447
  group.schematic_group_id,
@@ -17495,7 +17498,7 @@ function createSchematicTraceSolverInputProblem(group) {
17495
17498
  const allSourceAndSchematicPortIdsInScope = /* @__PURE__ */ new Set();
17496
17499
  const schPortIdToSourcePortId = /* @__PURE__ */ new Map();
17497
17500
  const sourcePortIdToSchPortId = /* @__PURE__ */ new Map();
17498
- const userNetIdToSck = /* @__PURE__ */ new Map();
17501
+ const userNetIdToConnKey = /* @__PURE__ */ new Map();
17499
17502
  for (const sc of schematicComponents) {
17500
17503
  const ports = db.schematic_port.list({
17501
17504
  schematic_component_id: sc.schematic_component_id
@@ -17530,7 +17533,19 @@ function createSchematicTraceSolverInputProblem(group) {
17530
17533
  }
17531
17534
  }
17532
17535
  const directConnections = [];
17533
- const pairKeyToSourceTraceId = /* @__PURE__ */ new Map();
17536
+ const connectedPairKeys = /* @__PURE__ */ new Set();
17537
+ const connKeysWithExplicitPortNetTraces = /* @__PURE__ */ new Set();
17538
+ for (const trace of traces) {
17539
+ if (trace.parent !== group) continue;
17540
+ const sourceTraceId = trace.source_trace_id;
17541
+ if (!sourceTraceId) continue;
17542
+ const sourceTrace = db.source_trace.get(sourceTraceId);
17543
+ if (sourceTrace?.subcircuit_connectivity_map_key && (sourceTrace.connected_source_port_ids?.length ?? 0) > 0 && (sourceTrace.connected_source_net_ids?.length ?? 0) > 0) {
17544
+ connKeysWithExplicitPortNetTraces.add(
17545
+ sourceTrace.subcircuit_connectivity_map_key
17546
+ );
17547
+ }
17548
+ }
17534
17549
  for (const st of db.source_trace.list()) {
17535
17550
  if (st.subcircuit_id && !allowedSubcircuitIds.has(st.subcircuit_id)) {
17536
17551
  continue;
@@ -17541,13 +17556,11 @@ function createSchematicTraceSolverInputProblem(group) {
17541
17556
  if (connected.length >= 2) {
17542
17557
  const [a, b] = connected.slice(0, 2);
17543
17558
  const pairKey = [a, b].sort().join("::");
17544
- if (!pairKeyToSourceTraceId.has(pairKey)) {
17545
- pairKeyToSourceTraceId.set(pairKey, st.source_trace_id);
17559
+ if (!connectedPairKeys.has(pairKey)) {
17560
+ connectedPairKeys.add(pairKey);
17546
17561
  const userNetId = st.display_name ?? st.source_trace_id;
17547
17562
  if (st.subcircuit_connectivity_map_key) {
17548
- allScks.add(st.subcircuit_connectivity_map_key);
17549
- userNetIdToSck.set(userNetId, st.subcircuit_connectivity_map_key);
17550
- sckToUserNetId.set(st.subcircuit_connectivity_map_key, userNetId);
17563
+ userNetIdToConnKey.set(userNetId, st.subcircuit_connectivity_map_key);
17551
17564
  }
17552
17565
  directConnections.push({
17553
17566
  pinIds: [a, b].map((id) => schematicPortIdToPinId.get(id)),
@@ -17561,31 +17574,26 @@ function createSchematicTraceSolverInputProblem(group) {
17561
17574
  (n) => !n.subcircuit_id || allowedSubcircuitIds.has(n.subcircuit_id)
17562
17575
  )) {
17563
17576
  if (net.subcircuit_connectivity_map_key) {
17564
- allScks.add(net.subcircuit_connectivity_map_key);
17565
- sckToSourceNet.set(net.subcircuit_connectivity_map_key, net);
17577
+ connKeyToSourceNet.set(net.subcircuit_connectivity_map_key, net);
17566
17578
  }
17567
17579
  }
17568
- const sckToPinIds = /* @__PURE__ */ new Map();
17580
+ const connKeyToPinIds = /* @__PURE__ */ new Map();
17569
17581
  for (const [schId, srcPortId] of schPortIdToSourcePortId) {
17570
17582
  const sp = db.source_port.get(srcPortId);
17571
17583
  if (!sp?.subcircuit_connectivity_map_key) continue;
17572
- const sck = sp.subcircuit_connectivity_map_key;
17573
- allScks.add(sck);
17574
- if (!sckToPinIds.has(sck)) sckToPinIds.set(sck, []);
17575
- sckToPinIds.get(sck).push(schId);
17576
- }
17577
- for (const [subcircuitConnectivityKey, schematicPortIds] of sckToPinIds) {
17578
- const sourceNet = sckToSourceNet.get(subcircuitConnectivityKey);
17579
- if (sourceNet && schematicPortIds.length >= 2) {
17584
+ const connKey = sp.subcircuit_connectivity_map_key;
17585
+ if (!connKeyToPinIds.has(connKey)) connKeyToPinIds.set(connKey, []);
17586
+ connKeyToPinIds.get(connKey).push(schId);
17587
+ }
17588
+ for (const [connKey, schematicPortIds] of connKeyToPinIds) {
17589
+ const sourceNet = connKeyToSourceNet.get(connKey);
17590
+ if (sourceNet && schematicPortIds.length >= 1) {
17580
17591
  const userNetId = String(
17581
- sourceNet.name || sourceNet.source_net_id || subcircuitConnectivityKey
17592
+ sourceNet.name || sourceNet.source_net_id || connKey
17582
17593
  );
17583
- userNetIdToSck.set(userNetId, subcircuitConnectivityKey);
17584
- sckToUserNetId.set(subcircuitConnectivityKey, userNetId);
17585
- const fontSize = 0.18;
17586
- const charWidth = 0.1 * (fontSize / 0.18);
17594
+ userNetIdToConnKey.set(userNetId, connKey);
17587
17595
  const netLabelWidth = Number(
17588
- (String(userNetId).length * charWidth).toFixed(2)
17596
+ getSchematicNetLabelTextWidth({ text: String(userNetId) }).toFixed(2)
17589
17597
  );
17590
17598
  netConnections.push({
17591
17599
  netId: userNetId,
@@ -17604,9 +17612,9 @@ function createSchematicTraceSolverInputProblem(group) {
17604
17612
  )) {
17605
17613
  if (!net.name) continue;
17606
17614
  if (!presentNetIds.has(net.name)) continue;
17607
- if (net.is_ground || net.name.toLowerCase().startsWith("gnd")) {
17615
+ if (net.is_ground) {
17608
17616
  netToAllowedOrientations[net.name] = ["y-"];
17609
- } else if (net.is_power || net.name.toLowerCase().startsWith("v")) {
17617
+ } else if (net.is_power) {
17610
17618
  netToAllowedOrientations[net.name] = ["y+"];
17611
17619
  } else {
17612
17620
  netToAllowedOrientations[net.name] = ["x-", "x+"];
@@ -17624,14 +17632,11 @@ function createSchematicTraceSolverInputProblem(group) {
17624
17632
  return {
17625
17633
  inputProblem,
17626
17634
  pinIdToSchematicPortId,
17627
- pairKeyToSourceTraceId,
17628
- sckToSourceNet,
17629
- sckToUserNetId,
17630
- userNetIdToSck,
17635
+ connKeyToSourceNet,
17636
+ userNetIdToConnKey,
17637
+ connKeysWithExplicitPortNetTraces,
17631
17638
  allSourceAndSchematicPortIdsInScope,
17632
- schPortIdToSourcePortId,
17633
- displayLabelTraces,
17634
- allScks
17639
+ schPortIdToSourcePortId
17635
17640
  };
17636
17641
  }
17637
17642
 
@@ -17962,12 +17967,29 @@ function computeJunctions(traces, opts = {}) {
17962
17967
  import Debug9 from "debug";
17963
17968
  var debug7 = Debug9("Group_doInitialSchematicTraceRender");
17964
17969
  function applyTracesFromSolverOutput(args) {
17965
- const { group, solver, pinIdToSchematicPortId, userNetIdToSck } = args;
17970
+ const {
17971
+ group,
17972
+ solver,
17973
+ pinIdToSchematicPortId,
17974
+ userNetIdToConnKey,
17975
+ schematicPortIdsWithPreExistingNetLabels
17976
+ } = args;
17966
17977
  const { db } = group.root;
17967
- const traces = solver.traceCleanupSolver?.getOutput().traces ?? solver.traceLabelOverlapAvoidanceSolver?.getOutput().traces ?? solver.schematicTraceLinesSolver?.solvedTracePaths;
17978
+ const traces = solver.netLabelTraceCollisionSolver?.getOutput().traces ?? solver.traceCleanupSolver?.getOutput().traces ?? solver.traceLabelOverlapAvoidanceSolver?.getOutput().traces ?? solver.schematicTraceLinesSolver?.solvedTracePaths;
17968
17979
  const pendingTraces = [];
17969
17980
  debug7(`Traces inside SchematicTraceSolver output: ${(traces ?? []).length}`);
17970
17981
  for (const solvedTracePath of traces ?? []) {
17982
+ const uniquePinIds = Array.from(new Set(solvedTracePath.pinIds ?? []));
17983
+ const solvedTraceSchematicPortIds = uniquePinIds.map((pinId) => pinIdToSchematicPortId.get(pinId)).filter((id) => Boolean(id));
17984
+ const isNetLabelStubTrace = uniquePinIds.length <= 1 && solvedTraceSchematicPortIds.length > 0 && solvedTraceSchematicPortIds.every(
17985
+ (id) => schematicPortIdsWithPreExistingNetLabels.has(id)
17986
+ );
17987
+ if (isNetLabelStubTrace) {
17988
+ debug7(
17989
+ `Skipping solver netlabel stub trace ${solvedTracePath?.mspPairId} because schematic port already has a netlabel`
17990
+ );
17991
+ continue;
17992
+ }
17971
17993
  const points = solvedTracePath?.tracePath;
17972
17994
  if (!Array.isArray(points) || points.length < 2) {
17973
17995
  debug7(
@@ -17982,7 +18004,7 @@ function applyTracesFromSolverOutput(args) {
17982
18004
  to: { x: points[i + 1].x, y: points[i + 1].y }
17983
18005
  });
17984
18006
  }
17985
- let source_trace_id = null;
18007
+ const source_trace_id = String(solvedTracePath?.mspPairId);
17986
18008
  let subcircuit_connectivity_map_key;
17987
18009
  if (Array.isArray(solvedTracePath?.pins) && solvedTracePath.pins.length === 2) {
17988
18010
  const pA = pinIdToSchematicPortId.get(solvedTracePath.pins[0]?.pinId);
@@ -17992,14 +18014,13 @@ function applyTracesFromSolverOutput(args) {
17992
18014
  const existing = db.schematic_port.get(schPid);
17993
18015
  if (existing) db.schematic_port.update(schPid, { is_connected: true });
17994
18016
  }
17995
- subcircuit_connectivity_map_key = userNetIdToSck.get(
18017
+ subcircuit_connectivity_map_key = userNetIdToConnKey.get(
17996
18018
  String(solvedTracePath.userNetId)
17997
18019
  );
17998
18020
  }
17999
18021
  }
18000
- if (!source_trace_id) {
18001
- source_trace_id = `solver_${solvedTracePath?.mspPairId}`;
18002
- subcircuit_connectivity_map_key = userNetIdToSck.get(
18022
+ if (!subcircuit_connectivity_map_key) {
18023
+ subcircuit_connectivity_map_key = userNetIdToConnKey.get(
18003
18024
  String(solvedTracePath.userNetId)
18004
18025
  );
18005
18026
  }
@@ -18078,17 +18099,15 @@ function applyNetLabelPlacements(args) {
18078
18099
  const {
18079
18100
  group,
18080
18101
  solver,
18081
- sckToSourceNet,
18082
- allScks,
18083
- allSourceAndSchematicPortIdsInScope,
18084
- schPortIdToSourcePortId,
18085
- userNetIdToSck,
18102
+ connKeyToSourceNet,
18103
+ userNetIdToConnKey,
18086
18104
  pinIdToSchematicPortId,
18105
+ connKeysWithExplicitPortNetTraces,
18087
18106
  schematicPortIdsWithPreExistingNetLabels,
18088
18107
  schematicPortIdsWithRoutedTraces
18089
18108
  } = args;
18090
18109
  const { db } = group.root;
18091
- const netLabelPlacements = solver.netLabelPlacementSolver?.netLabelPlacements ?? solver.traceLabelOverlapAvoidanceSolver?.getOutput().netLabelPlacements ?? [];
18110
+ const netLabelPlacements = solver.netLabelTraceCollisionSolver?.getOutput().netLabelPlacements ?? solver.netLabelPlacementSolver?.netLabelPlacements ?? solver.traceLabelOverlapAvoidanceSolver?.getOutput().netLabelPlacements ?? [];
18092
18111
  const netLabelPlacementCountByGlobalNetId = /* @__PURE__ */ new Map();
18093
18112
  for (const placement of netLabelPlacements) {
18094
18113
  netLabelPlacementCountByGlobalNetId.set(
@@ -18099,12 +18118,15 @@ function applyNetLabelPlacements(args) {
18099
18118
  const globalConnMap = solver.mspConnectionPairSolver.globalConnMap;
18100
18119
  for (const placement of netLabelPlacements) {
18101
18120
  debug8(`processing placement: ${placement.netId}`);
18102
- const placementUserNetId = globalConnMap.getIdsConnectedToNet(placement.globalConnNetId).find((id) => userNetIdToSck.get(id));
18103
- const placementSck = userNetIdToSck.get(placementUserNetId);
18121
+ const placementUserNetId = globalConnMap.getIdsConnectedToNet(placement.globalConnNetId).find((id) => userNetIdToConnKey.get(id));
18122
+ const placementConnKey = userNetIdToConnKey.get(placementUserNetId);
18104
18123
  const anchor_position = placement.anchorPoint;
18105
18124
  const orientation = placement.orientation;
18106
18125
  const anchor_side = oppositeSide(orientation);
18107
- const sourceNet = placementSck ? sckToSourceNet.get(placementSck) : void 0;
18126
+ let sourceNet;
18127
+ if (placementConnKey) {
18128
+ sourceNet = connKeyToSourceNet.get(placementConnKey);
18129
+ }
18108
18130
  const schPortIds = placement.pinIds.map(
18109
18131
  (pinId) => pinIdToSchematicPortId.get(pinId)
18110
18132
  );
@@ -18117,22 +18139,38 @@ function applyNetLabelPlacements(args) {
18117
18139
  continue;
18118
18140
  }
18119
18141
  if (sourceNet) {
18142
+ const isPowerOrGroundNet = sourceNet.is_ground || sourceNet.is_power;
18143
+ const hasExplicitPortNetTrace = connKeysWithExplicitPortNetTraces.has(
18144
+ placementConnKey
18145
+ );
18146
+ const hasRoutedTraceForPlacementPort = schPortIds.some(
18147
+ (id) => schematicPortIdsWithRoutedTraces.has(id)
18148
+ );
18149
+ const hasSingleLabelPlacement = (netLabelPlacementCountByGlobalNetId.get(placement.globalConnNetId) ?? 0) <= 1;
18150
+ const shouldSkipImplicitSignalNetLabel = !hasExplicitPortNetTrace && !isPowerOrGroundNet && hasRoutedTraceForPlacementPort && hasSingleLabelPlacement;
18151
+ if (shouldSkipImplicitSignalNetLabel) {
18152
+ debug8(
18153
+ `skipping net label placement for "${placement.netId}" REASON:schematic port has routed trace`
18154
+ );
18155
+ continue;
18156
+ }
18120
18157
  const text2 = sourceNet.name;
18121
18158
  const center2 = computeSchematicNetLabelCenter({
18122
18159
  anchor_position,
18123
18160
  anchor_side,
18124
18161
  text: text2
18125
18162
  });
18126
- db.schematic_net_label.insert({
18163
+ const netLabel2 = {
18127
18164
  text: text2,
18165
+ source_net_id: sourceNet.source_net_id,
18128
18166
  anchor_position,
18129
18167
  center: center2,
18130
- anchor_side,
18131
- ...sourceNet?.source_net_id ? { source_net_id: sourceNet.source_net_id } : {}
18132
- });
18168
+ anchor_side
18169
+ };
18170
+ db.schematic_net_label.insert(netLabel2);
18133
18171
  continue;
18134
18172
  }
18135
- const ports = group.selectAll("port").filter((p) => p._getSubcircuitConnectivityKey() === placementSck);
18173
+ const ports = group.selectAll("port").filter((p) => p._getSubcircuitConnectivityKey() === placementConnKey);
18136
18174
  const { name: text, wasAssignedDisplayLabel } = getNetNameFromPorts(ports);
18137
18175
  if (!wasAssignedDisplayLabel && (netLabelPlacementCountByGlobalNetId.get(placement.globalConnNetId) ?? 0) <= 1 && schPortIds.some(
18138
18176
  (schPortId) => schematicPortIdsWithRoutedTraces.has(schPortId)
@@ -18147,26 +18185,25 @@ function applyNetLabelPlacements(args) {
18147
18185
  anchor_side,
18148
18186
  text
18149
18187
  });
18150
- db.schematic_net_label.insert({
18188
+ const netLabel = {
18151
18189
  text,
18190
+ source_net_id: placementConnKey ?? placement.netId ?? placement.globalConnNetId,
18152
18191
  anchor_position,
18153
18192
  center,
18154
18193
  anchor_side
18155
- });
18194
+ };
18195
+ db.schematic_net_label.insert(netLabel);
18156
18196
  }
18157
18197
  }
18158
18198
 
18159
- // lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/insertNetLabelsForTracesExcludedFromRouting.ts
18160
- import "@tscircuit/schematic-trace-solver";
18161
-
18162
18199
  // lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/insertNetLabelsForPortsMissingTrace.ts
18200
+ var NEAR_EXISTING_NET_LABEL_DISTANCE = 0.5;
18201
+ var SAME_ANCHOR_POSITION_DISTANCE = 0.1;
18163
18202
  var insertNetLabelsForPortsMissingTrace = ({
18164
18203
  allSourceAndSchematicPortIdsInScope,
18165
18204
  group,
18166
18205
  schPortIdToSourcePortId,
18167
- sckToSourceNet: connKeyToNet,
18168
- pinIdToSchematicPortId,
18169
- schematicPortIdsWithPreExistingNetLabels
18206
+ connKeyToSourceNet
18170
18207
  }) => {
18171
18208
  const { db } = group.root;
18172
18209
  for (const schOrSrcPortId of Array.from(
@@ -18178,37 +18215,87 @@ var insertNetLabelsForPortsMissingTrace = ({
18178
18215
  const srcPortId = schPortIdToSourcePortId.get(schOrSrcPortId);
18179
18216
  if (!srcPortId) continue;
18180
18217
  const sourcePort = db.source_port.get(srcPortId);
18181
- const key = sourcePort?.subcircuit_connectivity_map_key;
18182
- if (!key) continue;
18183
- const sourceNet = connKeyToNet.get(key);
18218
+ const connKey = sourcePort?.subcircuit_connectivity_map_key;
18219
+ if (!connKey) continue;
18220
+ const sourceNet = connKeyToSourceNet.get(connKey);
18184
18221
  if (!sourceNet) {
18185
18222
  continue;
18186
18223
  }
18187
- const existingAtPort = db.schematic_net_label.list().some((nl) => {
18188
- const samePos = Math.abs(nl.anchor_position.x - schPort.center.x) < 0.1 && Math.abs(nl.anchor_position.y - schPort.center.y) < 0.1;
18189
- if (!samePos) return false;
18190
- if (sourceNet.source_net_id && nl.source_net_id) {
18191
- return nl.source_net_id === sourceNet.source_net_id;
18192
- }
18193
- return nl.text === (sourceNet.name || key);
18194
- });
18195
- if (existingAtPort) continue;
18196
- const text = sourceNet.name || sourceNet.source_net_id || key;
18197
- const side = getEnteringEdgeFromDirection(
18198
- schPort.facing_direction || "right"
18199
- ) || "right";
18224
+ const text = sourceNet.name || sourceNet.source_net_id || connKey;
18225
+ const connectedPortCountForKey = Array.from(
18226
+ allSourceAndSchematicPortIdsInScope
18227
+ ).filter((portId) => {
18228
+ const sourcePortId = schPortIdToSourcePortId.get(portId);
18229
+ if (!sourcePortId) return false;
18230
+ return db.source_port.get(sourcePortId)?.subcircuit_connectivity_map_key === connKey;
18231
+ }).length;
18232
+ const isGndNet = sourceNet.is_ground;
18233
+ const isPowerNet = !isGndNet && sourceNet.is_power;
18234
+ const usePowerSymbolSide = connectedPortCountForKey > 1;
18235
+ let side;
18236
+ if (usePowerSymbolSide && isGndNet) {
18237
+ side = "top";
18238
+ } else if (usePowerSymbolSide && isPowerNet) {
18239
+ side = "bottom";
18240
+ } else {
18241
+ side = getEnteringEdgeFromDirection(
18242
+ schPort.facing_direction || "right"
18243
+ ) || "right";
18244
+ }
18200
18245
  const center = computeSchematicNetLabelCenter({
18201
18246
  anchor_position: schPort.center,
18202
18247
  anchor_side: side,
18203
18248
  text
18204
18249
  });
18205
- db.schematic_net_label.insert({
18250
+ const sameNetLabel = db.schematic_net_label.list().find((nl) => {
18251
+ if (sourceNet.source_net_id && nl.source_net_id) {
18252
+ return nl.source_net_id === sourceNet.source_net_id;
18253
+ }
18254
+ return nl.text === (sourceNet.name || connKey);
18255
+ });
18256
+ if (sameNetLabel && connectedPortCountForKey <= 1) {
18257
+ db.schematic_net_label.update(sameNetLabel.schematic_net_label_id, {
18258
+ text,
18259
+ anchor_position: schPort.center,
18260
+ center,
18261
+ anchor_side: side
18262
+ });
18263
+ continue;
18264
+ }
18265
+ if (sameNetLabel) {
18266
+ const dx = sameNetLabel.anchor_position.x - schPort.center.x;
18267
+ const dy = sameNetLabel.anchor_position.y - schPort.center.y;
18268
+ const labelIsNearPort = dx * dx + dy * dy < NEAR_EXISTING_NET_LABEL_DISTANCE * NEAR_EXISTING_NET_LABEL_DISTANCE;
18269
+ if (labelIsNearPort && sourceNet.is_ground) {
18270
+ db.schematic_net_label.update(sameNetLabel.schematic_net_label_id, {
18271
+ text,
18272
+ anchor_position: schPort.center,
18273
+ center,
18274
+ anchor_side: side
18275
+ });
18276
+ continue;
18277
+ }
18278
+ const existingAtPort = db.schematic_net_label.list().some((nl) => {
18279
+ const dx2 = nl.anchor_position.x - schPort.center.x;
18280
+ const dy2 = nl.anchor_position.y - schPort.center.y;
18281
+ if (dx2 * dx2 + dy2 * dy2 >= SAME_ANCHOR_POSITION_DISTANCE * SAME_ANCHOR_POSITION_DISTANCE) {
18282
+ return false;
18283
+ }
18284
+ if (sourceNet.source_net_id && nl.source_net_id) {
18285
+ return nl.source_net_id === sourceNet.source_net_id;
18286
+ }
18287
+ return nl.text === (sourceNet.name || connKey);
18288
+ });
18289
+ if (existingAtPort) continue;
18290
+ }
18291
+ const netLabel = {
18206
18292
  text,
18293
+ source_net_id: sourceNet.source_net_id,
18207
18294
  anchor_position: schPort.center,
18208
18295
  center,
18209
- anchor_side: side,
18210
- ...sourceNet.source_net_id ? { source_net_id: sourceNet.source_net_id } : {}
18211
- });
18296
+ anchor_side: side
18297
+ };
18298
+ db.schematic_net_label.insert(netLabel);
18212
18299
  }
18213
18300
  };
18214
18301
 
@@ -18256,13 +18343,11 @@ var Group_doInitialSchematicTraceRender = (group) => {
18256
18343
  const {
18257
18344
  inputProblem,
18258
18345
  pinIdToSchematicPortId,
18259
- pairKeyToSourceTraceId,
18260
- sckToSourceNet,
18346
+ connKeyToSourceNet,
18261
18347
  allSourceAndSchematicPortIdsInScope,
18262
18348
  schPortIdToSourcePortId,
18263
- displayLabelTraces,
18264
- allScks,
18265
- userNetIdToSck
18349
+ userNetIdToConnKey,
18350
+ connKeysWithExplicitPortNetTraces
18266
18351
  } = createSchematicTraceSolverInputProblem(group);
18267
18352
  if (inputProblem.chips.length === 0) return;
18268
18353
  const schematicPortIdsWithPreExistingNetLabels = getSchematicPortIdsWithAssignedNetLabels(group);
@@ -18272,9 +18357,7 @@ var Group_doInitialSchematicTraceRender = (group) => {
18272
18357
  group,
18273
18358
  allSourceAndSchematicPortIdsInScope,
18274
18359
  schPortIdToSourcePortId,
18275
- sckToSourceNet,
18276
- pinIdToSchematicPortId,
18277
- schematicPortIdsWithPreExistingNetLabels
18360
+ connKeyToSourceNet
18278
18361
  });
18279
18362
  return;
18280
18363
  }
@@ -18285,7 +18368,7 @@ var Group_doInitialSchematicTraceRender = (group) => {
18285
18368
  content: JSON.stringify(inputProblem, null, 2)
18286
18369
  });
18287
18370
  }
18288
- const solver = new SchematicTracePipelineSolver4(inputProblem);
18371
+ const solver = new SchematicTracePipelineSolver3(inputProblem);
18289
18372
  solver.solve();
18290
18373
  const schematicPortIdsWithRoutedTraces = getSchematicPortIdsWithRoutedTraces({
18291
18374
  solver,
@@ -18295,17 +18378,16 @@ var Group_doInitialSchematicTraceRender = (group) => {
18295
18378
  group,
18296
18379
  solver,
18297
18380
  pinIdToSchematicPortId,
18298
- userNetIdToSck
18381
+ userNetIdToConnKey,
18382
+ schematicPortIdsWithPreExistingNetLabels
18299
18383
  });
18300
18384
  applyNetLabelPlacements({
18301
18385
  group,
18302
18386
  solver,
18303
- sckToSourceNet,
18304
- allSourceAndSchematicPortIdsInScope,
18305
- schPortIdToSourcePortId,
18387
+ connKeyToSourceNet,
18306
18388
  pinIdToSchematicPortId,
18307
- allScks,
18308
- userNetIdToSck,
18389
+ userNetIdToConnKey,
18390
+ connKeysWithExplicitPortNetTraces,
18309
18391
  schematicPortIdsWithPreExistingNetLabels,
18310
18392
  schematicPortIdsWithRoutedTraces
18311
18393
  });
@@ -18313,9 +18395,7 @@ var Group_doInitialSchematicTraceRender = (group) => {
18313
18395
  group,
18314
18396
  allSourceAndSchematicPortIdsInScope,
18315
18397
  schPortIdToSourcePortId,
18316
- sckToSourceNet,
18317
- pinIdToSchematicPortId,
18318
- schematicPortIdsWithPreExistingNetLabels
18398
+ connKeyToSourceNet
18319
18399
  });
18320
18400
  };
18321
18401
 
@@ -19202,9 +19282,13 @@ function getExistingPcbTracesForReroute(group) {
19202
19282
  function addPossibleReplacementSourceTraceId(sourceTraceIds, value) {
19203
19283
  if (typeof value !== "string" || value.length === 0) return;
19204
19284
  sourceTraceIds.add(value);
19205
- const rerouteSuffixIndex = value.indexOf("_reroute_");
19206
- if (rerouteSuffixIndex > 0) {
19207
- sourceTraceIds.add(value.slice(0, rerouteSuffixIndex));
19285
+ for (const connectionNamePart of value.split("__")) {
19286
+ if (connectionNamePart.length === 0) continue;
19287
+ sourceTraceIds.add(connectionNamePart);
19288
+ const rerouteSuffixIndex = connectionNamePart.indexOf("_reroute_");
19289
+ if (rerouteSuffixIndex > 0) {
19290
+ sourceTraceIds.add(connectionNamePart.slice(0, rerouteSuffixIndex));
19291
+ }
19208
19292
  }
19209
19293
  }
19210
19294
  function deleteExistingPcbTracesReplacedBy({
@@ -19348,7 +19432,7 @@ function computeCenterFromAnchorPosition(anchorPosition, ctx) {
19348
19432
  }
19349
19433
 
19350
19434
  // lib/components/primitive-components/Group/Group.ts
19351
- var Group6 = class extends NormalComponent3 {
19435
+ var Group5 = class extends NormalComponent3 {
19352
19436
  pcb_group_id = null;
19353
19437
  schematic_group_id = null;
19354
19438
  subcircuit_id = null;
@@ -20555,7 +20639,7 @@ function inflateSourceGroup(sourceGroup, inflatorContext) {
20555
20639
  if (pcbGroup?.anchor_alignment) {
20556
20640
  groupProps2.pcbAnchorAlignment = pcbGroup.anchor_alignment;
20557
20641
  }
20558
- const group = new Group6(groupProps2);
20642
+ const group = new Group5(groupProps2);
20559
20643
  group._isInflatedFromCircuitJson = true;
20560
20644
  group.source_group_id = sourceGroup.source_group_id;
20561
20645
  if (groupsMap) {
@@ -21243,7 +21327,7 @@ import { identity as identity5 } from "transformation-matrix";
21243
21327
  var package_default = {
21244
21328
  name: "@tscircuit/core",
21245
21329
  type: "module",
21246
- version: "0.0.1245",
21330
+ version: "0.0.1247",
21247
21331
  types: "dist/index.d.ts",
21248
21332
  main: "dist/index.js",
21249
21333
  module: "dist/index.js",
@@ -21291,7 +21375,7 @@ var package_default = {
21291
21375
  "@tscircuit/ngspice-spice-engine": "^0.0.8",
21292
21376
  "@tscircuit/props": "^0.0.531",
21293
21377
  "@tscircuit/schematic-match-adapt": "^0.0.16",
21294
- "@tscircuit/schematic-trace-solver": "^0.0.55",
21378
+ "@tscircuit/schematic-trace-solver": "^0.0.57",
21295
21379
  "@tscircuit/solver-utils": "^0.0.3",
21296
21380
  "@tscircuit/soup-util": "^0.0.41",
21297
21381
  "@types/bun": "^1.2.16",
@@ -21488,7 +21572,7 @@ var IsolatedCircuit = class {
21488
21572
  this.firstChild = this.children[0];
21489
21573
  return;
21490
21574
  }
21491
- const group = new Group6({ subcircuit: true });
21575
+ const group = new Group5({ subcircuit: true });
21492
21576
  group.parent = this;
21493
21577
  group.addAll(this.children);
21494
21578
  this.children = [group];
@@ -21854,7 +21938,7 @@ var getRoundedRectOutline = (width, height, radius) => {
21854
21938
  }
21855
21939
  return outline;
21856
21940
  };
21857
- var Board = class extends Group6 {
21941
+ var Board = class extends Group5 {
21858
21942
  pcb_board_id = null;
21859
21943
  source_board_id = null;
21860
21944
  _drcChecksComplete = false;
@@ -22297,7 +22381,7 @@ import { mountedboardProps } from "@tscircuit/props";
22297
22381
 
22298
22382
  // lib/components/primitive-components/Group/Subcircuit/Subcircuit.ts
22299
22383
  import "@tscircuit/props";
22300
- var Subcircuit = class extends Group6 {
22384
+ var Subcircuit = class extends Group5 {
22301
22385
  constructor(props) {
22302
22386
  super({
22303
22387
  ...props,
@@ -22826,7 +22910,7 @@ function getItemDimensions(item, db) {
22826
22910
  }
22827
22911
 
22828
22912
  // lib/components/normal-components/Subpanel.ts
22829
- var Subpanel = class _Subpanel extends Group6 {
22913
+ var Subpanel = class _Subpanel extends Group5 {
22830
22914
  pcb_panel_id = null;
22831
22915
  _tabsAndMouseBitesGenerated = false;
22832
22916
  get config() {
@@ -24234,7 +24318,7 @@ var PcbNoteDimension = class extends PrimitiveComponent2 {
24234
24318
 
24235
24319
  // lib/components/primitive-components/Breakout/Breakout.ts
24236
24320
  import "@tscircuit/props";
24237
- var Breakout = class extends Group6 {
24321
+ var Breakout = class extends Group5 {
24238
24322
  constructor(props) {
24239
24323
  super({
24240
24324
  ...props,
@@ -24383,10 +24467,23 @@ var NetLabel = class extends PrimitiveComponent2 {
24383
24467
  if (props.anchorSide) return props.anchorSide;
24384
24468
  const connectsTo = this._resolveConnectsTo();
24385
24469
  if (!connectsTo) return "right";
24470
+ const net = this.getSubcircuit().selectOne(
24471
+ `net.${this._getNetName()}`
24472
+ );
24473
+ let sourceNet;
24474
+ if (net?.source_net_id) {
24475
+ sourceNet = this.root?.db.source_net.get(net.source_net_id);
24476
+ }
24477
+ if (sourceNet?.is_ground) return "top";
24478
+ if (sourceNet?.is_power) return "bottom";
24386
24479
  const anchorPos = this._getGlobalSchematicPositionBeforeLayout();
24387
24480
  const connectedPorts = this._getConnectedPorts();
24388
24481
  if (connectedPorts.length === 0) return "right";
24389
- const connectedPortPosition = connectedPorts[0]._getGlobalSchematicPositionBeforeLayout();
24482
+ const port = connectedPorts[0];
24483
+ if (port.facingDirection) {
24484
+ return getEnteringEdgeFromDirection(port.facingDirection);
24485
+ }
24486
+ const connectedPortPosition = port._getGlobalSchematicPositionBeforeLayout();
24390
24487
  const dx = connectedPortPosition.x - anchorPos.x;
24391
24488
  const dy = connectedPortPosition.y - anchorPos.y;
24392
24489
  if (Math.abs(dx) > Math.abs(dy)) {
@@ -24434,7 +24531,7 @@ var NetLabel = class extends PrimitiveComponent2 {
24434
24531
  const net = this.getSubcircuit().selectOne(
24435
24532
  `net.${this._getNetName()}`
24436
24533
  );
24437
- const anchorSide = props.anchorSide ?? "right";
24534
+ const anchorSide = this._getAnchorSide();
24438
24535
  const center = computeSchematicNetLabelCenter({
24439
24536
  anchor_position: anchorPos,
24440
24537
  anchor_side: anchorSide,
@@ -24445,7 +24542,7 @@ var NetLabel = class extends PrimitiveComponent2 {
24445
24542
  source_net_id: net.source_net_id,
24446
24543
  anchor_position: anchorPos,
24447
24544
  center,
24448
- anchor_side: this._getAnchorSide()
24545
+ anchor_side: anchorSide
24449
24546
  });
24450
24547
  this.source_net_label_id = netLabel.source_net_id;
24451
24548
  }
@@ -25903,26 +26000,46 @@ var Mosfet = class extends NormalComponent3 {
25903
26000
  // lib/components/normal-components/OpAmp.ts
25904
26001
  import { opampProps } from "@tscircuit/props";
25905
26002
  var OpAmp = class extends NormalComponent3 {
25906
- get config() {
26003
+ getSchematicSymbolName() {
26004
+ if (this.props.symbolName) {
26005
+ return this.props.symbolName;
26006
+ }
25907
26007
  const hasPowerConnections = this.props.connections?.positive_supply || this.props.connections?.negative_supply;
25908
- const symbolName = this.props.symbolName ? this.props.symbolName : hasPowerConnections ? "opamp_with_power" : "opamp_no_power";
26008
+ if (hasPowerConnections) {
26009
+ return "opamp_with_power";
26010
+ }
26011
+ return "opamp_no_power";
26012
+ }
26013
+ get config() {
25909
26014
  return {
25910
26015
  componentName: "OpAmp",
25911
- schematicSymbolName: symbolName,
26016
+ schematicSymbolName: this.getSchematicSymbolName(),
25912
26017
  zodProps: opampProps,
25913
26018
  sourceFtype: "simple_op_amp"
25914
26019
  };
25915
26020
  }
25916
26021
  initPorts() {
25917
- super.initPorts({
25918
- pinCount: 5,
25919
- additionalAliases: {
25920
- pin1: ["non_inverting_input"],
25921
- pin2: ["inverting_input"],
26022
+ const additionalAliases = {
26023
+ pin1: ["non_inverting_input"],
26024
+ pin2: ["inverting_input"]
26025
+ };
26026
+ const hasPowerSymbol = this.getSchematicSymbolName() === "opamp_with_power";
26027
+ if (hasPowerSymbol) {
26028
+ Object.assign(additionalAliases, {
26029
+ pin4: ["output"],
26030
+ pin5: ["positive_supply", "vcc", "vdd"],
26031
+ pin3: ["negative_supply", "vee", "vss", "gnd"]
26032
+ });
26033
+ } else {
26034
+ Object.assign(additionalAliases, {
25922
26035
  pin3: ["output"],
25923
26036
  pin4: ["positive_supply", "vcc", "vdd"],
25924
26037
  pin5: ["negative_supply", "vee", "vss", "gnd"]
25925
- }
26038
+ });
26039
+ }
26040
+ super.initPorts({
26041
+ pinCount: 5,
26042
+ additionalAliases
25926
26043
  });
25927
26044
  }
25928
26045
  doInitialSourceRender() {
@@ -27768,7 +27885,7 @@ export {
27768
27885
  Fiducial,
27769
27886
  Footprint,
27770
27887
  Fuse,
27771
- Group6 as Group,
27888
+ Group5 as Group,
27772
27889
  Hole,
27773
27890
  Inductor,
27774
27891
  Interconnect,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.1246",
4
+ "version": "0.0.1248",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -49,7 +49,7 @@
49
49
  "@tscircuit/ngspice-spice-engine": "^0.0.8",
50
50
  "@tscircuit/props": "^0.0.531",
51
51
  "@tscircuit/schematic-match-adapt": "^0.0.16",
52
- "@tscircuit/schematic-trace-solver": "^0.0.55",
52
+ "@tscircuit/schematic-trace-solver": "^0.0.57",
53
53
  "@tscircuit/solver-utils": "^0.0.3",
54
54
  "@tscircuit/soup-util": "^0.0.41",
55
55
  "@types/bun": "^1.2.16",