@tscircuit/core 0.0.1810 → 0.0.1812

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
@@ -1799,6 +1799,20 @@ declare abstract class PrimitiveComponent<ZodProps extends ZodType = any> extend
1799
1799
  width: number;
1800
1800
  height: number;
1801
1801
  };
1802
+ /**
1803
+ * Bounds in the primitive's footprint-local PCB frame before parent
1804
+ * transforms are applied. This is a right-handed frame with +X right, +Y
1805
+ * toward the top of the board, +Z above the board, and all values in mm.
1806
+ *
1807
+ * Most primitives are centered on their local origin. Path-like primitives
1808
+ * can override this when their authored coordinates are not centered.
1809
+ */
1810
+ _getPcbLocalBoundsBeforeLayout(): {
1811
+ left: number;
1812
+ right: number;
1813
+ top: number;
1814
+ bottom: number;
1815
+ };
1802
1816
  protected _getPcbComponentLayer(): LayerRef | undefined;
1803
1817
  /**
1804
1818
  * Determine if this pcb primitive should be flipped because the primitive
@@ -15472,7 +15486,7 @@ declare class Capacitor extends NormalComponent<typeof capacitorProps, Polarized
15472
15486
  doInitialSourceRender(): void;
15473
15487
  }
15474
15488
 
15475
- declare class Antenna extends NormalComponent<typeof antennaProps, "pin1" | "feed"> {
15489
+ declare class Antenna extends NormalComponent<typeof antennaProps, "pin1" | "feed" | "pin2" | "ground" | "gnd" | "feed2"> {
15476
15490
  get config(): {
15477
15491
  componentName: string;
15478
15492
  zodProps: zod.ZodObject<{
@@ -19353,6 +19367,8 @@ declare class Antenna extends NormalComponent<typeof antennaProps, "pin1" | "fee
19353
19367
  mfn: zod.ZodOptional<zod.ZodString>;
19354
19368
  manufacturerPartNumber: zod.ZodOptional<zod.ZodString>;
19355
19369
  } & {
19370
+ antennaShape: zod.ZodOptional<zod.ZodEnum<["2.4ghz_quarter_wave_monopole", "2.4ghz_meandered_monopole", "2.4ghz_inverted_f", "2.4ghz_meandered_inverted_f", "2.4ghz_folded_dipole"]>>;
19371
+ frequencyBand: zod.ZodOptional<zod.ZodEnum<["2.4ghz", "5ghz", "6ghz", "dual_band_2.4ghz_5ghz", "tri_band_2.4ghz_5ghz_6ghz"]>>;
19356
19372
  pcbPath: zod.ZodOptional<zod.ZodArray<zod.ZodUnion<[zod.ZodEffects<zod.ZodObject<{
19357
19373
  x: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
19358
19374
  y: zod.ZodEffects<zod.ZodUnion<[zod.ZodString, zod.ZodNumber]>, number, string | number>;
@@ -20071,6 +20087,8 @@ declare class Antenna extends NormalComponent<typeof antennaProps, "pin1" | "fee
20071
20087
  manufacturerPartNumber?: string | undefined;
20072
20088
  schSectionName?: string | undefined;
20073
20089
  schSheetName?: string | undefined;
20090
+ antennaShape?: "2.4ghz_quarter_wave_monopole" | "2.4ghz_meandered_monopole" | "2.4ghz_inverted_f" | "2.4ghz_meandered_inverted_f" | "2.4ghz_folded_dipole" | undefined;
20091
+ frequencyBand?: "2.4ghz" | "5ghz" | "6ghz" | "dual_band_2.4ghz_5ghz" | "tri_band_2.4ghz_5ghz_6ghz" | undefined;
20074
20092
  pcbPath?: (string | {
20075
20093
  x: number;
20076
20094
  y: number;
@@ -20742,6 +20760,8 @@ declare class Antenna extends NormalComponent<typeof antennaProps, "pin1" | "fee
20742
20760
  manufacturerPartNumber?: string | undefined;
20743
20761
  schSectionName?: string | undefined;
20744
20762
  schSheetName?: string | undefined;
20763
+ antennaShape?: "2.4ghz_quarter_wave_monopole" | "2.4ghz_meandered_monopole" | "2.4ghz_inverted_f" | "2.4ghz_meandered_inverted_f" | "2.4ghz_folded_dipole" | undefined;
20764
+ frequencyBand?: "2.4ghz" | "5ghz" | "6ghz" | "dual_band_2.4ghz_5ghz" | "tri_band_2.4ghz_5ghz_6ghz" | undefined;
20745
20765
  pcbPath?: (string | {
20746
20766
  x: string | number;
20747
20767
  y: string | number;
@@ -20759,6 +20779,7 @@ declare class Antenna extends NormalComponent<typeof antennaProps, "pin1" | "fee
20759
20779
  };
20760
20780
  getRefDesPrefixes(): string[];
20761
20781
  initPorts(): void;
20782
+ doInitialReactSubtreesRender(): void;
20762
20783
  doInitialCreateTracesFromProps(): void;
20763
20784
  }
20764
20785
 
@@ -106767,6 +106788,17 @@ declare class PcbTrace extends PrimitiveComponent<typeof pcbTraceProps> {
106767
106788
  width: number;
106768
106789
  height: number;
106769
106790
  };
106791
+ /**
106792
+ * The route points are authored in the containing footprint's right-handed
106793
+ * local PCB frame: +X right, +Y toward the top of the board, +Z above the
106794
+ * board, with coordinates and widths in mm.
106795
+ */
106796
+ _getPcbLocalBoundsBeforeLayout(): {
106797
+ left: number;
106798
+ right: number;
106799
+ top: number;
106800
+ bottom: number;
106801
+ };
106770
106802
  }
106771
106803
 
106772
106804
  declare const pcbViaProps: z.ZodObject<{
package/dist/index.js CHANGED
@@ -1872,6 +1872,23 @@ var PrimitiveComponent2 = class extends Renderable {
1872
1872
  height: 0
1873
1873
  };
1874
1874
  }
1875
+ /**
1876
+ * Bounds in the primitive's footprint-local PCB frame before parent
1877
+ * transforms are applied. This is a right-handed frame with +X right, +Y
1878
+ * toward the top of the board, +Z above the board, and all values in mm.
1879
+ *
1880
+ * Most primitives are centered on their local origin. Path-like primitives
1881
+ * can override this when their authored coordinates are not centered.
1882
+ */
1883
+ _getPcbLocalBoundsBeforeLayout() {
1884
+ const { width, height } = this.getPcbSize();
1885
+ return {
1886
+ left: -width / 2,
1887
+ right: width / 2,
1888
+ top: height / 2,
1889
+ bottom: -height / 2
1890
+ };
1891
+ }
1875
1892
  _getPcbComponentLayer() {
1876
1893
  return this._parsedProps.layer;
1877
1894
  }
@@ -9240,9 +9257,9 @@ var PcbNoteText = class extends PrimitiveComponent2 {
9240
9257
  };
9241
9258
 
9242
9259
  // lib/components/primitive-components/PcbTrace.ts
9243
- import { z as z7 } from "zod";
9244
9260
  import { pcb_trace_route_point } from "circuit-json";
9245
9261
  import { applyToPoint as applyToPoint13 } from "transformation-matrix";
9262
+ import { z as z7 } from "zod";
9246
9263
  var pcbTraceProps = z7.object({
9247
9264
  route: z7.array(pcb_trace_route_point),
9248
9265
  // If this primitive PcbTrace needs to be associated with a source_trace_id
@@ -9304,11 +9321,26 @@ var PcbTrace = class extends PrimitiveComponent2 {
9304
9321
  this.pcb_trace_id = pcb_trace.pcb_trace_id;
9305
9322
  }
9306
9323
  getPcbSize() {
9324
+ const bounds = this._getPcbLocalBoundsBeforeLayout();
9325
+ return {
9326
+ width: bounds.right - bounds.left,
9327
+ height: bounds.top - bounds.bottom
9328
+ };
9329
+ }
9330
+ /**
9331
+ * The route points are authored in the containing footprint's right-handed
9332
+ * local PCB frame: +X right, +Y toward the top of the board, +Z above the
9333
+ * board, with coordinates and widths in mm.
9334
+ */
9335
+ _getPcbLocalBoundsBeforeLayout() {
9307
9336
  const { _parsedProps: props } = this;
9308
9337
  if (!props.route || props.route.length === 0) {
9309
- return { width: 0, height: 0 };
9338
+ return { left: 0, right: 0, top: 0, bottom: 0 };
9310
9339
  }
9311
- let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
9340
+ let minX = Infinity;
9341
+ let maxX = -Infinity;
9342
+ let minY = Infinity;
9343
+ let maxY = -Infinity;
9312
9344
  for (const point6 of props.route) {
9313
9345
  if (point6.route_type === "through_pad") {
9314
9346
  minX = Math.min(minX, point6.start.x, point6.end.x);
@@ -9350,11 +9382,13 @@ var PcbTrace = class extends PrimitiveComponent2 {
9350
9382
  }
9351
9383
  }
9352
9384
  if (minX === Infinity || maxX === -Infinity || minY === Infinity || maxY === -Infinity) {
9353
- return { width: 0, height: 0 };
9385
+ return { left: 0, right: 0, top: 0, bottom: 0 };
9354
9386
  }
9355
9387
  return {
9356
- width: maxX - minX,
9357
- height: maxY - minY
9388
+ left: minX,
9389
+ right: maxX,
9390
+ top: maxY,
9391
+ bottom: minY
9358
9392
  };
9359
9393
  }
9360
9394
  };
@@ -12261,12 +12295,12 @@ function getBoundsOfPcbComponents(components) {
12261
12295
  if (child.isPcbPrimitive && !NON_PHYSICAL_PCB_PRIMITIVE_PREFIXES.some(
12262
12296
  (prefix) => child.componentName.startsWith(prefix)
12263
12297
  )) {
12264
- const { width: width2, height: height2 } = child.getPcbSize();
12298
+ const localBounds = child._getPcbLocalBoundsBeforeLayout();
12265
12299
  const footprintLocalCorners = [
12266
- { x: -width2 / 2, y: -height2 / 2 },
12267
- { x: width2 / 2, y: -height2 / 2 },
12268
- { x: width2 / 2, y: height2 / 2 },
12269
- { x: -width2 / 2, y: height2 / 2 }
12300
+ { x: localBounds.left, y: localBounds.bottom },
12301
+ { x: localBounds.right, y: localBounds.bottom },
12302
+ { x: localBounds.right, y: localBounds.top },
12303
+ { x: localBounds.left, y: localBounds.top }
12270
12304
  ];
12271
12305
  const boardWorldCorners = footprintLocalCorners.map(
12272
12306
  (corner) => applyToPoint24(child._computePcbGlobalTransformBeforeLayout(), corner)
@@ -35747,12 +35781,12 @@ var applyComponentConstraintClusters = (group, packInput) => {
35747
35781
  };
35748
35782
 
35749
35783
  // lib/components/primitive-components/Group/Group_doInitialPcbLayoutPack/applyPackOutput.ts
35750
- import { translate as translate6, rotate as rotate4, compose as compose7 } from "transformation-matrix";
35751
35784
  import {
35752
35785
  findBoundsAndCenter,
35753
35786
  transformPCBElements as transformPCBElements2
35754
35787
  } from "@tscircuit/circuit-json-util";
35755
35788
  import { normalizeDegrees as normalizeDegrees4 } from "@tscircuit/math-utils";
35789
+ import { compose as compose7, rotate as rotate4, translate as translate6 } from "transformation-matrix";
35756
35790
  var updateCadRotation = ({
35757
35791
  db,
35758
35792
  pcbComponentId,
@@ -35785,6 +35819,7 @@ var isDescendantGroup = (db, groupId, ancestorId) => {
35785
35819
  var applyPackOutput = (group, packOutput, clusterMap, initialPackOutput) => {
35786
35820
  const { db } = group.root;
35787
35821
  for (const packedComponent of packOutput.components) {
35822
+ if (packedComponent.isStatic) continue;
35788
35823
  const { center, componentId, ccwRotationOffset, ccwRotationDegrees } = packedComponent;
35789
35824
  const cluster = clusterMap[componentId];
35790
35825
  if (cluster) {
@@ -35968,6 +36003,40 @@ var getPackInputsByPcbLayer = (packInput, db) => {
35968
36003
  // lib/components/primitive-components/Group/Group_doInitialPcbLayoutPack/Group_doInitialPcbLayoutPack.ts
35969
36004
  var DEFAULT_MIN_GAP = "1mm";
35970
36005
  var debug4 = Debug6("Group_doInitialPcbLayoutPack");
36006
+ var getCollisionObstacleForStaticComponent = (component) => {
36007
+ if (component.courtyard && component.center) {
36008
+ return {
36009
+ obstacleId: component.componentId,
36010
+ absoluteCenter: {
36011
+ x: component.center.x + component.courtyard.offsetFromCenter.x,
36012
+ y: component.center.y + component.courtyard.offsetFromCenter.y
36013
+ },
36014
+ width: component.courtyard.width,
36015
+ height: component.courtyard.height
36016
+ };
36017
+ }
36018
+ if (component.pads.length === 0) return void 0;
36019
+ let minX = Infinity;
36020
+ let minY = Infinity;
36021
+ let maxX = -Infinity;
36022
+ let maxY = -Infinity;
36023
+ for (const pad of component.pads) {
36024
+ const absoluteCenter = pad.absoluteCenter ?? (component.center ? {
36025
+ x: component.center.x + pad.offset.x,
36026
+ y: component.center.y + pad.offset.y
36027
+ } : pad.offset);
36028
+ minX = Math.min(minX, absoluteCenter.x - pad.size.x / 2);
36029
+ minY = Math.min(minY, absoluteCenter.y - pad.size.y / 2);
36030
+ maxX = Math.max(maxX, absoluteCenter.x + pad.size.x / 2);
36031
+ maxY = Math.max(maxY, absoluteCenter.y + pad.size.y / 2);
36032
+ }
36033
+ return {
36034
+ obstacleId: component.componentId,
36035
+ absoluteCenter: { x: (minX + maxX) / 2, y: (minY + maxY) / 2 },
36036
+ width: maxX - minX,
36037
+ height: maxY - minY
36038
+ };
36039
+ };
35971
36040
  var Group_doInitialPcbLayoutPack = (group) => {
35972
36041
  const { db } = group.root;
35973
36042
  const { _parsedProps: props } = group;
@@ -36105,8 +36174,48 @@ var Group_doInitialPcbLayoutPack = (group) => {
36105
36174
  const componentIdsForLayer = new Set(
36106
36175
  layerPackInput.components.map((component) => component.componentId)
36107
36176
  );
36108
- const networkReferenceComponents = packOutput.components.map(
36109
- (component) => ({
36177
+ const staticLayerObstacles = layerPackInput.components.flatMap(
36178
+ (component) => {
36179
+ if (!component.isStatic) return [];
36180
+ const obstacle = getCollisionObstacleForStaticComponent(component);
36181
+ return obstacle ? [obstacle] : [];
36182
+ }
36183
+ );
36184
+ const canUseCrossLayerNetworkReferences = layerPackInput.components.every(
36185
+ (component) => Boolean(db.pcb_component.get(component.componentId)) && !clusterMap[component.componentId]
36186
+ );
36187
+ const crossLayerStaticComponents = packInput.components.filter(
36188
+ (component) => component.isStatic && !componentIdsForLayer.has(component.componentId)
36189
+ );
36190
+ const fallbackCrossLayerObstacles = canUseCrossLayerNetworkReferences ? [] : crossLayerStaticComponents.flatMap((component) => {
36191
+ const obstacle = getCollisionObstacleForStaticComponent(component);
36192
+ return obstacle ? [obstacle] : [];
36193
+ });
36194
+ const collisionOnlyPadIds = new Set(
36195
+ [
36196
+ ...layerPackInput.components.filter(
36197
+ (component) => component.isStatic
36198
+ ),
36199
+ ...canUseCrossLayerNetworkReferences ? [] : crossLayerStaticComponents
36200
+ ].flatMap((component) => component.pads.map((pad) => pad.padId))
36201
+ );
36202
+ const networkReferenceSources = new Map([
36203
+ ...packOutput.components.map(
36204
+ (component) => [
36205
+ component.componentId,
36206
+ { component, courtyardSize: Number.EPSILON }
36207
+ ]
36208
+ ),
36209
+ ...canUseCrossLayerNetworkReferences ? crossLayerStaticComponents.map(
36210
+ (component) => [
36211
+ component.componentId,
36212
+ { component, courtyardSize: 1e-6 }
36213
+ ]
36214
+ ) : []
36215
+ ]);
36216
+ const networkReferenceComponents = Array.from(
36217
+ networkReferenceSources.values(),
36218
+ ({ component, courtyardSize }) => ({
36110
36219
  ...component,
36111
36220
  componentId: `network_reference_${component.componentId}`,
36112
36221
  isStatic: true,
@@ -36114,16 +36223,26 @@ var Group_doInitialPcbLayoutPack = (group) => {
36114
36223
  // reducing their collision geometry to a point at the component center.
36115
36224
  courtyard: {
36116
36225
  offsetFromCenter: { x: 0, y: 0 },
36117
- width: Number.EPSILON,
36118
- height: Number.EPSILON
36226
+ width: courtyardSize,
36227
+ height: courtyardSize
36119
36228
  }
36120
36229
  })
36121
36230
  );
36122
36231
  const solverInput = {
36123
36232
  ...layerPackInput,
36233
+ weightedConnections: layerPackInput.weightedConnections?.filter(
36234
+ (connection) => connection.padIds.every((padId) => !collisionOnlyPadIds.has(padId))
36235
+ ),
36236
+ obstacles: [
36237
+ ...layerPackInput.obstacles ?? [],
36238
+ ...staticLayerObstacles,
36239
+ ...fallbackCrossLayerObstacles
36240
+ ],
36124
36241
  components: [
36125
36242
  ...networkReferenceComponents,
36126
- ...layerPackInput.components
36243
+ ...layerPackInput.components.filter(
36244
+ (component) => !component.isStatic
36245
+ )
36127
36246
  ]
36128
36247
  };
36129
36248
  const solver = new PackSolver22(solverInput);
@@ -42174,7 +42293,7 @@ function Group_getRoutingPhasePlans(group) {
42174
42293
  var package_default = {
42175
42294
  name: "@tscircuit/core",
42176
42295
  type: "module",
42177
- version: "0.0.1809",
42296
+ version: "0.0.1811",
42178
42297
  types: "dist/index.d.ts",
42179
42298
  main: "dist/index.js",
42180
42299
  module: "dist/index.js",
@@ -42227,7 +42346,7 @@ var package_default = {
42227
42346
  "@tscircuit/math-utils": "^0.0.36",
42228
42347
  "@tscircuit/miniflex": "^0.0.4",
42229
42348
  "@tscircuit/ngspice-spice-engine": "^0.0.20",
42230
- "@tscircuit/props": "^0.0.643",
42349
+ "@tscircuit/props": "^0.0.644",
42231
42350
  "@tscircuit/schematic-match-adapt": "^0.0.18",
42232
42351
  "@tscircuit/schematic-trace-solver": "^0.0.173",
42233
42352
  "@tscircuit/solver-utils": "^0.0.16",
@@ -42293,7 +42412,7 @@ var package_default = {
42293
42412
  "@flatten-js/core": "^1.6.2",
42294
42413
  "@lume/kiwi": "^0.4.3",
42295
42414
  "calculate-cell-boundaries": "^0.0.19",
42296
- "calculate-packing": "^0.0.86",
42415
+ "calculate-packing": "^0.0.89",
42297
42416
  "css-select": "5.1.0",
42298
42417
  "format-si-unit": "^0.0.12",
42299
42418
  nanoid: "^5.0.7",
@@ -42305,7 +42424,7 @@ var package_default = {
42305
42424
  },
42306
42425
  overrides: {
42307
42426
  "@tscircuit/circuit-json-util": "^0.0.106",
42308
- "@tscircuit/props": "^0.0.643",
42427
+ "@tscircuit/props": "^0.0.644",
42309
42428
  "circuit-json": "^0.0.479"
42310
42429
  }
42311
42430
  };
@@ -49051,6 +49170,96 @@ var Panel = class extends Subpanel {
49051
49170
 
49052
49171
  // lib/components/normal-components/Antenna.ts
49053
49172
  import { antennaProps } from "@tscircuit/props";
49173
+
49174
+ // lib/components/normal-components/get-generated-antenna-geometry.ts
49175
+ var getGeneratedAntennaGeometry = (antennaShape) => {
49176
+ switch (antennaShape) {
49177
+ case "2.4ghz_quarter_wave_monopole":
49178
+ return {
49179
+ traceWidth: 0.6,
49180
+ feedPoint: { x: 0, y: 0 },
49181
+ route: [
49182
+ { x: 0, y: 0 },
49183
+ { x: 31, y: 0 }
49184
+ ]
49185
+ };
49186
+ case "2.4ghz_meandered_monopole":
49187
+ return {
49188
+ traceWidth: 0.5,
49189
+ feedPoint: { x: 0, y: 0 },
49190
+ route: [
49191
+ { x: 0, y: 0 },
49192
+ { x: 0, y: 6 },
49193
+ { x: 3, y: 6 },
49194
+ { x: 3, y: 1.5 },
49195
+ { x: 6, y: 1.5 },
49196
+ { x: 6, y: 6 },
49197
+ { x: 9, y: 6 },
49198
+ { x: 9, y: 1.5 },
49199
+ { x: 12, y: 1.5 },
49200
+ { x: 12, y: 6 },
49201
+ { x: 15, y: 6 }
49202
+ ]
49203
+ };
49204
+ case "2.4ghz_inverted_f":
49205
+ return {
49206
+ traceWidth: 0.8,
49207
+ feedPoint: { x: 0, y: 0 },
49208
+ secondaryPort: { point: { x: -4, y: 0 }, role: "ground" },
49209
+ groundViaPoint: { x: -4, y: 0 },
49210
+ route: [
49211
+ { x: -4, y: 0 },
49212
+ { x: -4, y: 3 },
49213
+ { x: 0, y: 3 },
49214
+ { x: 0, y: 0 },
49215
+ { x: 0, y: 3 },
49216
+ { x: -4, y: 3 },
49217
+ { x: -4, y: 8 },
49218
+ { x: 22, y: 8 }
49219
+ ]
49220
+ };
49221
+ case "2.4ghz_meandered_inverted_f":
49222
+ return {
49223
+ traceWidth: 0.5,
49224
+ feedPoint: { x: 0, y: 0 },
49225
+ secondaryPort: { point: { x: -1.7, y: 0 }, role: "ground" },
49226
+ groundViaPoint: { x: -1.7, y: 0 },
49227
+ route: [
49228
+ { x: -1.7, y: 0 },
49229
+ { x: -1.7, y: 4.9 },
49230
+ { x: 0, y: 4.9 },
49231
+ { x: 0, y: 0 },
49232
+ { x: 0, y: 4.9 },
49233
+ { x: -1.7, y: 4.9 },
49234
+ { x: 2.3, y: 4.9 },
49235
+ { x: 2.3, y: 1.4 },
49236
+ { x: 5.3, y: 1.4 },
49237
+ { x: 5.3, y: 4.9 },
49238
+ { x: 8.3, y: 4.9 },
49239
+ { x: 8.3, y: 1.4 },
49240
+ { x: 11.3, y: 1.4 },
49241
+ { x: 11.3, y: 4.9 },
49242
+ { x: 13.3, y: 4.9 }
49243
+ ]
49244
+ };
49245
+ case "2.4ghz_folded_dipole":
49246
+ return {
49247
+ traceWidth: 0.9,
49248
+ feedPoint: { x: 0, y: 0 },
49249
+ secondaryPort: { point: { x: 1.2, y: 0 }, role: "feed2" },
49250
+ route: [
49251
+ { x: 0, y: 0 },
49252
+ { x: -22.4, y: 0 },
49253
+ { x: -22.4, y: 9 },
49254
+ { x: 23.6, y: 9 },
49255
+ { x: 23.6, y: 0 },
49256
+ { x: 1.2, y: 0 }
49257
+ ]
49258
+ };
49259
+ }
49260
+ };
49261
+
49262
+ // lib/components/normal-components/Antenna.ts
49054
49263
  var Antenna = class extends NormalComponent3 {
49055
49264
  get config() {
49056
49265
  return {
@@ -49064,11 +49273,82 @@ var Antenna = class extends NormalComponent3 {
49064
49273
  return ["ANT"];
49065
49274
  }
49066
49275
  initPorts() {
49276
+ const { antennaShape, pcbPath } = this._parsedProps;
49277
+ const secondaryPortRole = pcbPath ? void 0 : antennaShape === "2.4ghz_inverted_f" || antennaShape === "2.4ghz_meandered_inverted_f" ? "ground" : antennaShape === "2.4ghz_folded_dipole" ? "feed2" : void 0;
49067
49278
  super.initPorts({
49068
- pinCount: 1,
49069
- additionalAliases: { pin1: ["feed"] }
49279
+ pinCount: secondaryPortRole ? 2 : 1,
49280
+ additionalAliases: {
49281
+ pin1: ["feed"],
49282
+ ...secondaryPortRole === "ground" ? { pin2: ["ground", "gnd"] } : secondaryPortRole === "feed2" ? { pin2: ["feed2"] } : {}
49283
+ }
49070
49284
  });
49071
49285
  }
49286
+ doInitialReactSubtreesRender() {
49287
+ super.doInitialReactSubtreesRender();
49288
+ const { antennaShape, pcbPath } = this._parsedProps;
49289
+ if (!antennaShape) return;
49290
+ const hasFootprint = this.children.some(
49291
+ (child) => child.componentName === "Footprint"
49292
+ );
49293
+ if (pcbPath && hasFootprint) return;
49294
+ const geometry = pcbPath ? void 0 : getGeneratedAntennaGeometry(antennaShape);
49295
+ const generatedFootprint = new Footprint({
49296
+ name: `${this.name}_generated_antenna`
49297
+ });
49298
+ if (!hasFootprint) {
49299
+ generatedFootprint.add(
49300
+ new SmtPad({
49301
+ shape: "rect",
49302
+ width: 0.8,
49303
+ height: 0.8,
49304
+ pcbX: geometry?.feedPoint.x ?? 0,
49305
+ pcbY: geometry?.feedPoint.y ?? 0,
49306
+ layer: "top",
49307
+ portHints: ["pin1"],
49308
+ coveredWithSolderMask: true
49309
+ })
49310
+ );
49311
+ }
49312
+ if (geometry) {
49313
+ generatedFootprint.add(
49314
+ new PcbTrace({
49315
+ route: geometry.route.map((point6) => ({
49316
+ route_type: "wire",
49317
+ ...point6,
49318
+ width: geometry.traceWidth,
49319
+ layer: "top"
49320
+ }))
49321
+ })
49322
+ );
49323
+ if (geometry.secondaryPort && !hasFootprint) {
49324
+ generatedFootprint.add(
49325
+ new SmtPad({
49326
+ shape: "rect",
49327
+ width: 0.8,
49328
+ height: 0.8,
49329
+ pcbX: geometry.secondaryPort.point.x,
49330
+ pcbY: geometry.secondaryPort.point.y,
49331
+ layer: "top",
49332
+ portHints: ["pin2"],
49333
+ coveredWithSolderMask: true
49334
+ })
49335
+ );
49336
+ }
49337
+ if (geometry.groundViaPoint) {
49338
+ generatedFootprint.add(
49339
+ new PcbVia({
49340
+ pcbX: geometry.groundViaPoint.x,
49341
+ pcbY: geometry.groundViaPoint.y,
49342
+ holeDiameter: 0.3,
49343
+ outerDiameter: 0.7,
49344
+ isTented: true,
49345
+ netIsAssignable: true
49346
+ })
49347
+ );
49348
+ }
49349
+ }
49350
+ this.add(generatedFootprint);
49351
+ }
49072
49352
  doInitialCreateTracesFromProps() {
49073
49353
  super.doInitialCreateTracesFromProps();
49074
49354
  const { pcbPath } = this._parsedProps;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.1810",
4
+ "version": "0.0.1812",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -54,7 +54,7 @@
54
54
  "@tscircuit/math-utils": "^0.0.36",
55
55
  "@tscircuit/miniflex": "^0.0.4",
56
56
  "@tscircuit/ngspice-spice-engine": "^0.0.20",
57
- "@tscircuit/props": "^0.0.643",
57
+ "@tscircuit/props": "^0.0.644",
58
58
  "@tscircuit/schematic-match-adapt": "^0.0.18",
59
59
  "@tscircuit/schematic-trace-solver": "^0.0.173",
60
60
  "@tscircuit/solver-utils": "^0.0.16",
@@ -120,7 +120,7 @@
120
120
  "@flatten-js/core": "^1.6.2",
121
121
  "@lume/kiwi": "^0.4.3",
122
122
  "calculate-cell-boundaries": "^0.0.19",
123
- "calculate-packing": "^0.0.86",
123
+ "calculate-packing": "^0.0.89",
124
124
  "css-select": "5.1.0",
125
125
  "format-si-unit": "^0.0.12",
126
126
  "nanoid": "^5.0.7",
@@ -132,7 +132,7 @@
132
132
  },
133
133
  "overrides": {
134
134
  "@tscircuit/circuit-json-util": "^0.0.106",
135
- "@tscircuit/props": "^0.0.643",
135
+ "@tscircuit/props": "^0.0.644",
136
136
  "circuit-json": "^0.0.479"
137
137
  }
138
138
  }