@tscircuit/core 0.0.1434 → 0.0.1435

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.
Files changed (2) hide show
  1. package/dist/index.js +174 -94
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -18981,8 +18981,48 @@ function Group_doInitialSchematicLayoutMatchAdapt(group) {
18981
18981
  // lib/components/primitive-components/Group/applySchematicMatchPackLayoutToTree.ts
18982
18982
  import "@tscircuit/circuit-json-util";
18983
18983
  import { LayoutPipelineSolver } from "@tscircuit/matchpack";
18984
+ import { getBoundFromCenteredRect as getBoundFromCenteredRect2 } from "@tscircuit/math-utils";
18984
18985
  import Debug8 from "debug";
18985
18986
 
18987
+ // lib/utils/schematic/getRotatedSymbolName.ts
18988
+ function rotateDirection(direction, ccwRotationDegrees) {
18989
+ const directions = ["right", "up", "left", "down"];
18990
+ const currentIndex = directions.indexOf(direction);
18991
+ if (currentIndex === -1) return direction;
18992
+ const steps = Math.round(ccwRotationDegrees / 90);
18993
+ const newIndex = (currentIndex + steps) % 4;
18994
+ return directions[newIndex < 0 ? newIndex + 4 : newIndex];
18995
+ }
18996
+ function getRotatedSymbolName(symbolName, ccwRotationDegrees) {
18997
+ if (!symbolName) return symbolName;
18998
+ let rotatedSymbolName = symbolName;
18999
+ const schematicSymbolDirection = rotatedSymbolName.match(
19000
+ /_(right|left|up|down)$/
19001
+ );
19002
+ if (schematicSymbolDirection) {
19003
+ rotatedSymbolName = rotatedSymbolName.replace(
19004
+ schematicSymbolDirection[0],
19005
+ `_${rotateDirection(schematicSymbolDirection[1], ccwRotationDegrees)}`
19006
+ );
19007
+ }
19008
+ const schematicSymbolOrientation = rotatedSymbolName.match(/_(horz|vert)$/);
19009
+ if (schematicSymbolOrientation && shouldSwapOrientation(ccwRotationDegrees)) {
19010
+ rotatedSymbolName = rotatedSymbolName.replace(
19011
+ schematicSymbolOrientation[0],
19012
+ schematicSymbolOrientation[1] === "horz" ? "_vert" : "_horz"
19013
+ );
19014
+ }
19015
+ return rotatedSymbolName;
19016
+ }
19017
+ function shouldSwapOrientation(ccwRotationDegrees) {
19018
+ const normalizedRotation = (Math.round(ccwRotationDegrees) % 360 + 360) % 360;
19019
+ return normalizedRotation === 90 || normalizedRotation === 270;
19020
+ }
19021
+ function getRotatedSize(size, ccwRotationDegrees) {
19022
+ if (!shouldSwapOrientation(ccwRotationDegrees)) return size;
19023
+ return { width: size.height, height: size.width };
19024
+ }
19025
+
18986
19026
  // lib/utils/schematic/getSchematicComponentWithTextBounds.ts
18987
19027
  import { getBoundFromCenteredRect } from "@tscircuit/math-utils";
18988
19028
  import { symbols as symbols3 } from "schematic-symbols";
@@ -19011,7 +19051,8 @@ var TEXT_BOX_ENABLED_FTYPES = /* @__PURE__ */ new Set([
19011
19051
  "simple_led",
19012
19052
  "simple_transistor",
19013
19053
  "simple_mosfet",
19014
- "simple_op_amp"
19054
+ "simple_op_amp",
19055
+ "simple_voltage_source"
19015
19056
  ]);
19016
19057
  function getTextBounds({
19017
19058
  text,
@@ -19116,14 +19157,34 @@ function getSchematicComponentTextInclusiveBounds(db, schematicComponent) {
19116
19157
  }
19117
19158
  return bounds;
19118
19159
  }
19119
- function getSchematicComponentWithTextBounds(db, schematicComponent) {
19160
+ function getOrientedSchematicComponent(schematicComponent, ccwRotationDegrees) {
19161
+ let size = schematicComponent.size;
19162
+ if (size) size = getRotatedSize(size, ccwRotationDegrees);
19163
+ return {
19164
+ ...schematicComponent,
19165
+ symbol_name: getRotatedSymbolName(
19166
+ schematicComponent.symbol_name,
19167
+ ccwRotationDegrees
19168
+ ),
19169
+ size
19170
+ };
19171
+ }
19172
+ function getSchematicComponentWithTextBounds({
19173
+ db,
19174
+ schematicComponent,
19175
+ ccwRotationDegrees = 0
19176
+ }) {
19177
+ const orientedComponent = getOrientedSchematicComponent(
19178
+ schematicComponent,
19179
+ ccwRotationDegrees
19180
+ );
19120
19181
  const textBounds = getSchematicComponentTextInclusiveBounds(
19121
19182
  db,
19122
- schematicComponent
19183
+ orientedComponent
19123
19184
  );
19124
19185
  if (!textBounds) return null;
19125
- const boxBounds = getSymbolBoxBounds(schematicComponent);
19126
- const isVertical = schematicComponent.size.height > schematicComponent.size.width;
19186
+ const boxBounds = getSymbolBoxBounds(orientedComponent);
19187
+ const isVertical = orientedComponent.size.height > orientedComponent.size.width;
19127
19188
  if (isVertical) return textBounds;
19128
19189
  const padLeft = Math.max(0, boxBounds.minX - textBounds.minX);
19129
19190
  const padRight = Math.max(0, textBounds.maxX - boxBounds.maxX);
@@ -19150,7 +19211,6 @@ function getSchematicComponentWithTextBounds(db, schematicComponent) {
19150
19211
  }
19151
19212
 
19152
19213
  // lib/components/primitive-components/Group/applySchematicMatchPackLayoutToTree.ts
19153
- import { getBoundFromCenteredRect as getBoundFromCenteredRect2 } from "@tscircuit/math-utils";
19154
19214
  var debug6 = Debug8("Group_doInitialSchematicLayoutMatchpack");
19155
19215
  var DEFAULT_AVAILABLE_ROTATIONS = [0, 90, 180, 270];
19156
19216
  var ROTATION_TO_PLACE_SIDE_ON_TOP = {
@@ -19173,40 +19233,90 @@ function facingDirectionToSide(facingDirection) {
19173
19233
  return "y+";
19174
19234
  }
19175
19235
  }
19176
- function applyPowerGroundRotationConstraints(problem) {
19177
- for (const chip of Object.values(problem.chipMap)) {
19178
- if (chip.pins.length !== 2) continue;
19179
- if (chip.availableRotations?.length !== DEFAULT_AVAILABLE_ROTATIONS.length)
19180
- continue;
19181
- const powerGroundRotations = /* @__PURE__ */ new Set();
19182
- for (const pinId of chip.pins) {
19183
- const pin = problem.chipPinMap[pinId];
19184
- if (!pin) continue;
19185
- for (const [netId, net] of Object.entries(problem.netMap)) {
19186
- if (!problem.netConnMap[`${pinId}-${netId}`]) continue;
19187
- if (net.isPositiveVoltageSource === net.isGround) continue;
19188
- const rotationToPlacePinOnTop = ROTATION_TO_PLACE_SIDE_ON_TOP[pin.side];
19189
- const rotation4 = net.isPositiveVoltageSource ? rotationToPlacePinOnTop : (rotationToPlacePinOnTop + 180) % 360;
19190
- powerGroundRotations.add(rotation4);
19191
- }
19192
- }
19193
- if (powerGroundRotations.size === 1) {
19194
- chip.availableRotations = [powerGroundRotations.values().next().value];
19195
- }
19236
+ function getPowerGroundForcedRotation(db, ports) {
19237
+ if (ports.length !== 2) return null;
19238
+ const powerGroundRotations = /* @__PURE__ */ new Set();
19239
+ for (const port of ports) {
19240
+ const sourcePort = db.source_port.get(port.source_port_id);
19241
+ const connectivityKey = sourcePort?.subcircuit_connectivity_map_key;
19242
+ if (!connectivityKey) continue;
19243
+ const net = db.source_net.getWhere({
19244
+ subcircuit_connectivity_map_key: connectivityKey
19245
+ });
19246
+ if (!net) continue;
19247
+ const isGround = net.is_ground ?? false;
19248
+ const isPositiveVoltageSource = net.is_power === true || net.is_positive_voltage_source === true;
19249
+ if (isPositiveVoltageSource === isGround) continue;
19250
+ const rotationToPlacePinOnTop = ROTATION_TO_PLACE_SIDE_ON_TOP[facingDirectionToSide(port.facing_direction)];
19251
+ const rotation4 = isPositiveVoltageSource ? rotationToPlacePinOnTop : (rotationToPlacePinOnTop + 180) % 360;
19252
+ powerGroundRotations.add(rotation4);
19253
+ }
19254
+ return powerGroundRotations.size === 1 ? powerGroundRotations.values().next().value : null;
19255
+ }
19256
+ function getChipSize({
19257
+ db,
19258
+ schematicComponent,
19259
+ component,
19260
+ ccwRotationDegrees
19261
+ }) {
19262
+ let orientedSymbolSize = schematicComponent.size;
19263
+ if (orientedSymbolSize) {
19264
+ orientedSymbolSize = getRotatedSize(orientedSymbolSize, ccwRotationDegrees);
19196
19265
  }
19266
+ const componentWithTextBounds = getSchematicComponentWithTextBounds({
19267
+ db,
19268
+ schematicComponent,
19269
+ ccwRotationDegrees
19270
+ });
19271
+ let textPadLeft = 0;
19272
+ let textPadRight = 0;
19273
+ let textPadTop = 0;
19274
+ let textPadBottom = 0;
19275
+ if (componentWithTextBounds && schematicComponent.center) {
19276
+ const halfWidth = (orientedSymbolSize?.width ?? 0) / 2;
19277
+ const halfHeight = (orientedSymbolSize?.height ?? 0) / 2;
19278
+ textPadLeft = schematicComponent.center.x - halfWidth - componentWithTextBounds.minX;
19279
+ textPadRight = componentWithTextBounds.maxX - (schematicComponent.center.x + halfWidth);
19280
+ textPadTop = componentWithTextBounds.maxY - (schematicComponent.center.y + halfHeight);
19281
+ textPadBottom = schematicComponent.center.y - halfHeight - componentWithTextBounds.minY;
19282
+ }
19283
+ const marginLeft = (component?._parsedProps?.schMarginLeft ?? component?._parsedProps?.schMarginX ?? 0) + textPadLeft;
19284
+ const marginRight = (component?._parsedProps?.schMarginRight ?? component?._parsedProps?.schMarginX ?? 0) + textPadRight;
19285
+ let marginTop = (component?._parsedProps?.schMarginTop ?? component?._parsedProps?.schMarginY ?? 0) + textPadTop;
19286
+ let marginBottom = (component?._parsedProps?.schMarginBottom ?? component?._parsedProps?.schMarginY ?? 0) + textPadBottom;
19287
+ if (component?.config.shouldRenderAsSchematicBox) {
19288
+ marginTop += 0.4;
19289
+ marginBottom += 0.4;
19290
+ }
19291
+ const orientedFootprint = {
19292
+ width: (orientedSymbolSize?.width || 1) + marginLeft + marginRight,
19293
+ height: (orientedSymbolSize?.height || 1) + marginTop + marginBottom
19294
+ };
19295
+ const chipSize = getRotatedSize(orientedFootprint, ccwRotationDegrees);
19296
+ return { x: chipSize.width, y: chipSize.height };
19197
19297
  }
19198
- function rotateDirection(direction, degrees) {
19199
- const directions = [
19200
- "right",
19201
- "up",
19202
- "left",
19203
- "down"
19204
- ];
19205
- const currentIndex = directions.indexOf(direction);
19206
- if (currentIndex === -1) return direction;
19207
- const steps = Math.round(degrees / 90);
19208
- const newIndex = (currentIndex + steps) % 4;
19209
- return directions[newIndex < 0 ? newIndex + 4 : newIndex];
19298
+ function getReservedChipSize({
19299
+ db,
19300
+ schematicComponent,
19301
+ component,
19302
+ ccwRotationDegrees,
19303
+ chipGap
19304
+ }) {
19305
+ const unrotatedSize = getChipSize({
19306
+ db,
19307
+ schematicComponent,
19308
+ component,
19309
+ ccwRotationDegrees: 0
19310
+ });
19311
+ if (!shouldSwapOrientation(ccwRotationDegrees)) return unrotatedSize;
19312
+ const rotatedSize = getChipSize({
19313
+ db,
19314
+ schematicComponent,
19315
+ component,
19316
+ ccwRotationDegrees
19317
+ });
19318
+ const growsPastGap = rotatedSize.x - unrotatedSize.x >= chipGap || rotatedSize.y - unrotatedSize.y >= chipGap;
19319
+ return growsPastGap ? rotatedSize : unrotatedSize;
19210
19320
  }
19211
19321
  function isTreeChildExplicitlyPositioned(treeChild, group) {
19212
19322
  if (treeChild.nodeType === "component" && treeChild.sourceComponent) {
@@ -19272,6 +19382,9 @@ function convertTreeToMatchPackInputProblem(tree, db, group) {
19272
19382
  const component = group.children.find(
19273
19383
  (groupChild) => groupChild.source_component_id === child.sourceComponent?.source_component_id
19274
19384
  );
19385
+ const ports = db.schematic_port.list({
19386
+ schematic_component_id: schematicComponent.schematic_component_id
19387
+ });
19275
19388
  let availableRotations = [
19276
19389
  ...DEFAULT_AVAILABLE_ROTATIONS
19277
19390
  ];
@@ -19290,39 +19403,21 @@ function convertTreeToMatchPackInputProblem(tree, db, group) {
19290
19403
  if (component?.componentName === "Chip") {
19291
19404
  availableRotations = [0];
19292
19405
  }
19293
- const componentWithTextBounds = getSchematicComponentWithTextBounds(
19294
- db,
19295
- schematicComponent
19296
- );
19297
- let textPadLeft = 0;
19298
- let textPadRight = 0;
19299
- let textPadTop = 0;
19300
- let textPadBottom = 0;
19301
- if (componentWithTextBounds && schematicComponent.center) {
19302
- const halfWidth = (schematicComponent.size?.width ?? 0) / 2;
19303
- const halfHeight = (schematicComponent.size?.height ?? 0) / 2;
19304
- textPadLeft = schematicComponent.center.x - halfWidth - componentWithTextBounds.minX;
19305
- textPadRight = componentWithTextBounds.maxX - (schematicComponent.center.x + halfWidth);
19306
- textPadTop = componentWithTextBounds.maxY - (schematicComponent.center.y + halfHeight);
19307
- textPadBottom = schematicComponent.center.y - halfHeight - componentWithTextBounds.minY;
19308
- }
19309
- const marginLeft = (component?._parsedProps?.schMarginLeft ?? component?._parsedProps?.schMarginX ?? 0) + textPadLeft;
19310
- const marginRight = (component?._parsedProps?.schMarginRight ?? component?._parsedProps?.schMarginX ?? 0) + textPadRight;
19311
- let marginTop = (component?._parsedProps?.schMarginTop ?? component?._parsedProps?.schMarginY ?? 0) + textPadTop;
19312
- let marginBottom = (component?._parsedProps?.schMarginBottom ?? component?._parsedProps?.schMarginY ?? 0) + textPadBottom;
19313
- if (component?.config.shouldRenderAsSchematicBox) {
19314
- marginTop += 0.4;
19315
- marginBottom += 0.4;
19316
- }
19317
- const marginXShift = (marginRight - marginLeft) / 2;
19318
- const marginYShift = (marginTop - marginBottom) / 2;
19406
+ if (availableRotations.length === DEFAULT_AVAILABLE_ROTATIONS.length) {
19407
+ const forcedRotation = getPowerGroundForcedRotation(db, ports);
19408
+ if (forcedRotation !== null) availableRotations = [forcedRotation];
19409
+ }
19410
+ const ccwRotationDegrees = availableRotations.length === 1 ? availableRotations[0] : 0;
19319
19411
  problem.chipMap[chipId] = {
19320
19412
  chipId,
19321
19413
  pins: [],
19322
- size: {
19323
- x: (schematicComponent.size?.width || 1) + marginLeft + marginRight,
19324
- y: (schematicComponent.size?.height || 1) + marginTop + marginBottom
19325
- },
19414
+ size: getReservedChipSize({
19415
+ db,
19416
+ schematicComponent,
19417
+ component,
19418
+ ccwRotationDegrees,
19419
+ chipGap: problem.chipGap
19420
+ }),
19326
19421
  isCapacitor: child.sourceComponent.ftype === "simple_capacitor",
19327
19422
  availableRotations,
19328
19423
  ...explicitlyPositioned && {
@@ -19332,9 +19427,6 @@ function convertTreeToMatchPackInputProblem(tree, db, group) {
19332
19427
  }
19333
19428
  }
19334
19429
  };
19335
- const ports = db.schematic_port.list({
19336
- schematic_component_id: schematicComponent.schematic_component_id
19337
- });
19338
19430
  for (const port of ports) {
19339
19431
  const sourcePort = db.source_port.get(port.source_port_id);
19340
19432
  if (!sourcePort) continue;
@@ -19380,7 +19472,10 @@ function convertTreeToMatchPackInputProblem(tree, db, group) {
19380
19472
  for (const comp of groupComponents) {
19381
19473
  if (comp.center && comp.size) {
19382
19474
  hasValidBounds = true;
19383
- const compBounds = getSchematicComponentWithTextBounds(db, comp) ?? getBoundFromCenteredRect2({
19475
+ const compBounds = getSchematicComponentWithTextBounds({
19476
+ db,
19477
+ schematicComponent: comp
19478
+ }) ?? getBoundFromCenteredRect2({
19384
19479
  center: comp.center,
19385
19480
  width: comp.size.width,
19386
19481
  height: comp.size.height
@@ -19586,7 +19681,6 @@ function convertTreeToMatchPackInputProblem(tree, db, group) {
19586
19681
  );
19587
19682
  }
19588
19683
  }
19589
- applyPowerGroundRotationConstraints(problem);
19590
19684
  return problem;
19591
19685
  }
19592
19686
  function applySchematicMatchPackLayoutToTree(group, tree) {
@@ -19755,24 +19849,10 @@ function applySchematicMatchPackLayoutToTree(group, tree) {
19755
19849
  text.position.y = newCenter.y + rotatedDy;
19756
19850
  }
19757
19851
  if (schematicComponent.symbol_name) {
19758
- const schematicSymbolDirection = schematicComponent.symbol_name.match(/_(right|left|up|down)$/);
19759
- if (schematicSymbolDirection) {
19760
- schematicComponent.symbol_name = schematicComponent.symbol_name.replace(
19761
- schematicSymbolDirection[0],
19762
- `_${rotateDirection(schematicSymbolDirection[1], placement.ccwRotationDegrees)}`
19763
- );
19764
- }
19765
- const schematicSymbolOrientation = schematicComponent.symbol_name.match(/_(horz|vert)$/);
19766
- if (schematicSymbolOrientation) {
19767
- const normalizedRot = (placement.ccwRotationDegrees % 360 + 360) % 360;
19768
- const shouldSwapOrientation = normalizedRot === 90 || normalizedRot === 270;
19769
- if (shouldSwapOrientation) {
19770
- schematicComponent.symbol_name = schematicComponent.symbol_name.replace(
19771
- schematicSymbolOrientation[0],
19772
- schematicSymbolOrientation[1] === "horz" ? "_vert" : "_horz"
19773
- );
19774
- }
19775
- }
19852
+ schematicComponent.symbol_name = getRotatedSymbolName(
19853
+ schematicComponent.symbol_name,
19854
+ placement.ccwRotationDegrees
19855
+ );
19776
19856
  }
19777
19857
  }
19778
19858
  }
@@ -20321,7 +20401,7 @@ function createSchematicTraceSolverInputProblem(group) {
20321
20401
  if (sourceComponent?.name) {
20322
20402
  sectionId = componentNameToSectionId.get(sourceComponent.name);
20323
20403
  }
20324
- const layoutBounds = getSchematicComponentWithTextBounds(db, schematicComponent) ?? getBoundFromCenteredRect4({
20404
+ const layoutBounds = getSchematicComponentWithTextBounds({ db, schematicComponent }) ?? getBoundFromCenteredRect4({
20325
20405
  center: schematicComponent.center,
20326
20406
  width: schematicComponent.size.width,
20327
20407
  height: schematicComponent.size.height
@@ -21008,7 +21088,7 @@ function applyTracesFromSolverOutput(args) {
21008
21088
  const { db } = group.root;
21009
21089
  const eligiblePortIds = /* @__PURE__ */ new Set();
21010
21090
  for (const schematicComponent of db.schematic_component.list()) {
21011
- if (!getSchematicComponentWithTextBounds(db, schematicComponent)) {
21091
+ if (!getSchematicComponentWithTextBounds({ db, schematicComponent })) {
21012
21092
  continue;
21013
21093
  }
21014
21094
  for (const port of db.schematic_port.list({
@@ -22396,7 +22476,7 @@ function Group_getRoutingPhasePlans(group) {
22396
22476
  var package_default = {
22397
22477
  name: "@tscircuit/core",
22398
22478
  type: "module",
22399
- version: "0.0.1433",
22479
+ version: "0.0.1434",
22400
22480
  types: "dist/index.d.ts",
22401
22481
  main: "dist/index.js",
22402
22482
  module: "dist/index.js",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.1434",
4
+ "version": "0.0.1435",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",