@tscircuit/core 0.0.2163 → 0.0.2164

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 (3) hide show
  1. package/dist/index.d.ts +34 -33
  2. package/dist/index.js +713 -570
  3. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -138,6 +138,629 @@ __export(components_exports, {
138
138
  VoltageSource: () => VoltageSource
139
139
  });
140
140
 
141
+ // lib/components/base-components/NormalComponent/NormalComponent_doInitialSourcePinSpecificationChecks.ts
142
+ import {
143
+ checkAllPinsInComponentAreUnderspecified,
144
+ checkNoGroundPinDefined,
145
+ checkNoPowerPinDefined
146
+ } from "@tscircuit/checks";
147
+
148
+ // lib/components/primitive-components/Port/apply-pin-attributes-to-source-port.ts
149
+ import { voltage } from "circuit-json";
150
+ var setSupportedCapability = (sourcePortProps, capability) => {
151
+ switch (capability) {
152
+ case "i2c_sda":
153
+ sourcePortProps.supports_i2c_sda = true;
154
+ return;
155
+ case "i2c_scl":
156
+ sourcePortProps.supports_i2c_scl = true;
157
+ return;
158
+ case "spi_cs":
159
+ sourcePortProps.supports_spi_cs = true;
160
+ return;
161
+ case "spi_sck":
162
+ sourcePortProps.supports_spi_sck = true;
163
+ return;
164
+ case "spi_mosi":
165
+ sourcePortProps.supports_spi_mosi = true;
166
+ return;
167
+ case "spi_miso":
168
+ sourcePortProps.supports_spi_miso = true;
169
+ return;
170
+ case "uart_tx":
171
+ sourcePortProps.supports_uart_tx = true;
172
+ return;
173
+ case "uart_rx":
174
+ sourcePortProps.supports_uart_rx = true;
175
+ return;
176
+ default: {
177
+ const unhandledCapability = capability;
178
+ throw new Error(`Unhandled pin capability: ${unhandledCapability}`);
179
+ }
180
+ }
181
+ };
182
+ var setConfiguredCapability = (sourcePortProps, capability) => {
183
+ switch (capability) {
184
+ case "i2c_sda":
185
+ sourcePortProps.is_configured_for_i2c_sda = true;
186
+ return;
187
+ case "i2c_scl":
188
+ sourcePortProps.is_configured_for_i2c_scl = true;
189
+ return;
190
+ case "spi_cs":
191
+ sourcePortProps.is_configured_for_spi_cs = true;
192
+ return;
193
+ case "spi_sck":
194
+ sourcePortProps.is_configured_for_spi_sck = true;
195
+ return;
196
+ case "spi_mosi":
197
+ sourcePortProps.is_configured_for_spi_mosi = true;
198
+ return;
199
+ case "spi_miso":
200
+ sourcePortProps.is_configured_for_spi_miso = true;
201
+ return;
202
+ case "uart_tx":
203
+ sourcePortProps.is_configured_for_uart_tx = true;
204
+ return;
205
+ case "uart_rx":
206
+ sourcePortProps.is_configured_for_uart_rx = true;
207
+ return;
208
+ default: {
209
+ const unhandledCapability = capability;
210
+ throw new Error(
211
+ `Unhandled configured pin capability: ${unhandledCapability}`
212
+ );
213
+ }
214
+ }
215
+ };
216
+ var applyPinAttributesToSourcePort = (sourcePortProps, attributes) => {
217
+ if (attributes.isInput !== void 0) {
218
+ sourcePortProps.is_input = attributes.isInput;
219
+ }
220
+ if (attributes.isOutput !== void 0) {
221
+ sourcePortProps.is_output = attributes.isOutput;
222
+ }
223
+ if (attributes.isBidirectional !== void 0) {
224
+ sourcePortProps.is_bidirectional = attributes.isBidirectional;
225
+ }
226
+ if (attributes.isPassive !== void 0) {
227
+ sourcePortProps.is_passive = attributes.isPassive;
228
+ }
229
+ if (attributes.canUseTriState !== void 0) {
230
+ sourcePortProps.can_use_tri_state = attributes.canUseTriState;
231
+ }
232
+ if (attributes.isUsingTriState !== void 0) {
233
+ sourcePortProps.is_using_tri_state = attributes.isUsingTriState;
234
+ }
235
+ if (attributes.canUseOpenCollector !== void 0) {
236
+ sourcePortProps.can_use_open_collector = attributes.canUseOpenCollector;
237
+ }
238
+ if (attributes.isUsingOpenCollector !== void 0) {
239
+ sourcePortProps.is_using_open_collector = attributes.isUsingOpenCollector;
240
+ }
241
+ if (attributes.canUseOpenEmitter !== void 0) {
242
+ sourcePortProps.can_use_open_emitter = attributes.canUseOpenEmitter;
243
+ }
244
+ if (attributes.isUsingOpenEmitter !== void 0) {
245
+ sourcePortProps.is_using_open_emitter = attributes.isUsingOpenEmitter;
246
+ }
247
+ if (attributes.isGpio !== void 0) {
248
+ sourcePortProps.is_gpio = attributes.isGpio;
249
+ }
250
+ if (attributes.highlightColor !== void 0) {
251
+ sourcePortProps.highlight_color = attributes.highlightColor;
252
+ }
253
+ for (const capability of attributes.capabilities ?? []) {
254
+ setSupportedCapability(sourcePortProps, capability);
255
+ }
256
+ const configuredCapabilities = /* @__PURE__ */ new Set([
257
+ ...attributes.activeCapabilities ?? [],
258
+ ...attributes.activeCapability ? [attributes.activeCapability] : []
259
+ ]);
260
+ for (const capability of configuredCapabilities) {
261
+ setConfiguredCapability(sourcePortProps, capability);
262
+ }
263
+ if (attributes.mustBeConnected !== void 0) {
264
+ sourcePortProps.must_be_connected = attributes.mustBeConnected;
265
+ }
266
+ if (attributes.providesPower !== void 0) {
267
+ sourcePortProps.provides_power = attributes.providesPower;
268
+ }
269
+ if (attributes.requiresPower !== void 0) {
270
+ sourcePortProps.requires_power = attributes.requiresPower;
271
+ }
272
+ if (attributes.providesGround !== void 0) {
273
+ sourcePortProps.provides_ground = attributes.providesGround;
274
+ }
275
+ if (attributes.requiresGround !== void 0) {
276
+ sourcePortProps.requires_ground = attributes.requiresGround;
277
+ }
278
+ if (attributes.providesVoltage !== void 0) {
279
+ sourcePortProps.provides_voltage = voltage.parse(attributes.providesVoltage);
280
+ }
281
+ if (attributes.requiresVoltage !== void 0) {
282
+ sourcePortProps.requires_voltage = voltage.parse(attributes.requiresVoltage);
283
+ }
284
+ if (attributes.doNotConnect !== void 0) {
285
+ sourcePortProps.do_not_connect = attributes.doNotConnect;
286
+ }
287
+ if (attributes.includeInBoardPinout !== void 0) {
288
+ sourcePortProps.include_in_board_pinout = attributes.includeInBoardPinout;
289
+ }
290
+ if (attributes.canUseInternalPullup !== void 0) {
291
+ sourcePortProps.can_use_internal_pullup = attributes.canUseInternalPullup;
292
+ }
293
+ if (attributes.isUsingInternalPullup !== void 0) {
294
+ sourcePortProps.is_using_internal_pullup = attributes.isUsingInternalPullup;
295
+ }
296
+ if (attributes.needsExternalPullup !== void 0) {
297
+ sourcePortProps.needs_external_pullup = attributes.needsExternalPullup;
298
+ }
299
+ if (attributes.canUseInternalPulldown !== void 0) {
300
+ sourcePortProps.can_use_internal_pulldown = attributes.canUseInternalPulldown;
301
+ }
302
+ if (attributes.isUsingInternalPulldown !== void 0) {
303
+ sourcePortProps.is_using_internal_pulldown = attributes.isUsingInternalPulldown;
304
+ }
305
+ if (attributes.needsExternalPulldown !== void 0) {
306
+ sourcePortProps.needs_external_pulldown = attributes.needsExternalPulldown;
307
+ }
308
+ if (attributes.canUseOpenDrain !== void 0) {
309
+ sourcePortProps.can_use_open_drain = attributes.canUseOpenDrain;
310
+ }
311
+ if (attributes.isUsingOpenDrain !== void 0) {
312
+ sourcePortProps.is_using_open_drain = attributes.isUsingOpenDrain;
313
+ }
314
+ if (attributes.canUsePushPull !== void 0) {
315
+ sourcePortProps.can_use_push_pull = attributes.canUsePushPull;
316
+ }
317
+ if (attributes.isUsingPushPull !== void 0) {
318
+ sourcePortProps.is_using_push_pull = attributes.isUsingPushPull;
319
+ }
320
+ if (attributes.shouldHaveDecouplingCapacitor !== void 0) {
321
+ sourcePortProps.should_have_decoupling_capacitor = attributes.shouldHaveDecouplingCapacitor;
322
+ }
323
+ if (attributes.recommendedDecouplingCapacitorCapacitance !== void 0) {
324
+ sourcePortProps.recommended_decoupling_capacitor_capacitance = attributes.recommendedDecouplingCapacitorCapacitance;
325
+ }
326
+ };
327
+
328
+ // lib/components/primitive-components/Port/get-pin-attribute-mismatches.ts
329
+ var getPinAttributeMismatches = (declared, imported) => {
330
+ const mismatches = [];
331
+ for (const propName of Object.keys(declared)) {
332
+ if (propName === "highlightColor" || propName === "includeInBoardPinout")
333
+ continue;
334
+ const normalized = {};
335
+ applyPinAttributesToSourcePort(normalized, {
336
+ [propName]: declared[propName]
337
+ });
338
+ if (propName === "capabilities") {
339
+ for (const attributeName of Object.keys(
340
+ imported
341
+ )) {
342
+ if (attributeName.startsWith("supports_"))
343
+ Object.assign(normalized, {
344
+ [attributeName]: normalized[attributeName] ?? false
345
+ });
346
+ }
347
+ }
348
+ for (const attributeName of Object.keys(
349
+ normalized
350
+ )) {
351
+ const declaredValue = normalized[attributeName];
352
+ const supportedAttributeName = attributeName.startsWith(
353
+ "is_configured_for_"
354
+ ) ? attributeName.replace("is_configured_for_", "supports_") : attributeName.startsWith("is_using_") ? attributeName.replace("is_using_", "can_use_") : void 0;
355
+ if (supportedAttributeName) {
356
+ if (declaredValue === true && imported[supportedAttributeName] === false)
357
+ mismatches.push(
358
+ `${propName}: ${JSON.stringify(declared[propName])}, fetched ${supportedAttributeName}: false`
359
+ );
360
+ continue;
361
+ }
362
+ const importedValue = imported[attributeName];
363
+ const valuesMatch = typeof importedValue === "number" && typeof declaredValue === "number" ? Math.abs(importedValue - declaredValue) <= Number.EPSILON * 8 * Math.max(1, Math.abs(importedValue), Math.abs(declaredValue)) : importedValue === declaredValue;
364
+ if (importedValue !== void 0 && declaredValue !== void 0 && !valuesMatch)
365
+ mismatches.push(
366
+ `${propName}: ${JSON.stringify(declared[propName])}, fetched ${attributeName}: ${JSON.stringify(importedValue)}`
367
+ );
368
+ }
369
+ }
370
+ return mismatches;
371
+ };
372
+
373
+ // lib/components/primitive-components/Port/resolve-port-source-pin-attributes.ts
374
+ import {
375
+ source_pin_attributes
376
+ } from "circuit-json";
377
+ var getImportedSourcePinAttributes = (port, importedSourcePorts) => {
378
+ if (new Set(
379
+ importedSourcePorts.map((sourcePort) => sourcePort.source_component_id)
380
+ ).size > 1)
381
+ return {};
382
+ const pinNumber = port.props.pinNumber;
383
+ const physicalMatches = pinNumber === void 0 ? [] : importedSourcePorts.filter(
384
+ (sourcePort) => sourcePort.pin_number === pinNumber
385
+ );
386
+ const aliases = port.getNameAndAliases();
387
+ const matches = physicalMatches.length > 0 ? physicalMatches : importedSourcePorts.filter(
388
+ (sourcePort) => [sourcePort.name, ...sourcePort.port_hints ?? []].some(
389
+ (alias) => aliases.includes(alias)
390
+ )
391
+ );
392
+ if (matches.length !== 1) return {};
393
+ const attributes = source_pin_attributes.parse(matches[0]);
394
+ for (const attributeName of Object.keys(
395
+ attributes
396
+ )) {
397
+ if (attributes[attributeName] === void 0)
398
+ delete attributes[attributeName];
399
+ }
400
+ return attributes;
401
+ };
402
+ var resolvePortSourcePinAttributes = (port) => {
403
+ const attributes = getImportedSourcePinAttributes(
404
+ port,
405
+ port.getParentNormalComponent()?._importedSourcePorts ?? []
406
+ );
407
+ for (const pinAttributes of port._getMatchingPinAttributes()) {
408
+ for (const attributeName of Object.keys(
409
+ attributes
410
+ )) {
411
+ if (pinAttributes.capabilities !== void 0 && attributeName.startsWith("supports_") || (pinAttributes.activeCapability !== void 0 || pinAttributes.activeCapabilities !== void 0) && attributeName.startsWith("is_configured_for_"))
412
+ delete attributes[attributeName];
413
+ }
414
+ applyPinAttributesToSourcePort(attributes, pinAttributes);
415
+ }
416
+ return attributes;
417
+ };
418
+
419
+ // lib/utils/get-datasheet-internal-connection-warnings.ts
420
+ var getDatasheetInternalConnectionWarnings = (component) => {
421
+ const reported = component._fetchedInternallyConnectedPinNames ?? component._importedInternallyConnectedPinNames ?? [];
422
+ const ports = component._getAllPortsFromChildren();
423
+ const resolvePort = (identifier) => {
424
+ const name = String(identifier);
425
+ const physical = ports.find(
426
+ (port) => port.physicalPinName === name || port.props.pinNumber !== void 0 && (String(port.props.pinNumber) === name || `pin${port.props.pinNumber}` === name)
427
+ );
428
+ if (physical) return physical;
429
+ const matches = ports.filter((port) => {
430
+ const aliases = port.getNameAndAliases();
431
+ return aliases.includes(name) || name.startsWith("pin") && aliases.includes(name.slice(3));
432
+ });
433
+ return matches.length === 1 ? matches[0] : void 0;
434
+ };
435
+ const declared = component._parsedProps.internallyConnectedPins;
436
+ const declaredGroups = (declared ?? []).map(
437
+ (group) => group.map(resolvePort).filter((port) => port !== void 0)
438
+ );
439
+ return reported.flatMap((group) => {
440
+ const resolved = group.map(resolvePort);
441
+ if (resolved.some((port) => !port)) return [];
442
+ const reportedPorts = [...new Set(resolved)];
443
+ if (reportedPorts.length < 2) return [];
444
+ const connected = /* @__PURE__ */ new Set([reportedPorts[0]]);
445
+ let changed = true;
446
+ while (changed) {
447
+ changed = false;
448
+ for (const group2 of declaredGroups) {
449
+ if (!group2.some((port) => connected.has(port))) continue;
450
+ for (const port of group2) {
451
+ if (!connected.has(port)) {
452
+ connected.add(port);
453
+ changed = true;
454
+ }
455
+ }
456
+ }
457
+ }
458
+ if (reportedPorts.every((port) => connected.has(port))) return [];
459
+ const pinNames = reportedPorts.map((port) => {
460
+ const aliases = port.getNameAndAliases();
461
+ return aliases.find((name) => !/^(?:pin)?\d+$/.test(name)) ?? aliases[0] ?? "unnamed pin";
462
+ });
463
+ const names = pinNames.length === 2 ? pinNames.join(" and ") : `${pinNames.slice(0, -1).join(", ")} and ${pinNames.at(-1)}`;
464
+ return [
465
+ {
466
+ message: `The datasheet reports pins ${names} are internally connected, but ${declared === void 0 ? `the internallyConnectedPins prop isn't set on ${component.getDisplayName()}` : `internallyConnectedPins on ${component.getDisplayName()} does not declare that connection`}.`,
467
+ sourcePortIds: reportedPorts.flatMap(
468
+ (port) => port.source_port_id ? [port.source_port_id] : []
469
+ )
470
+ }
471
+ ];
472
+ });
473
+ };
474
+
475
+ // lib/components/base-components/NormalComponent/NormalComponent_fetchDatasheetForValidation.ts
476
+ import {
477
+ resolveManufacturerPartNumber,
478
+ supplierProps
479
+ } from "@tscircuit/props";
480
+ import { source_pin_attributes as source_pin_attributes2 } from "circuit-json";
481
+
482
+ // lib/utils/fetch-part-circuit-json-with-datasheet.ts
483
+ import { ZodError } from "zod";
484
+ var chipDatasheetPartFetches = /* @__PURE__ */ new WeakMap();
485
+ var fetchDatasheetPart = async (fetchPartCircuitJson, request) => {
486
+ const { supplierPartNumber, manufacturerPartNumber, platformFetch } = request;
487
+ const legacyRequest = {
488
+ supplierPartNumber,
489
+ manufacturerPartNumber,
490
+ platformFetch
491
+ };
492
+ try {
493
+ return { circuitJson: await fetchPartCircuitJson(request) };
494
+ } catch (error) {
495
+ if (!request.includeDatasheetInformation && !(error instanceof ZodError && error.issues.some(
496
+ (issue) => issue.code === "unrecognized_keys" && issue.keys.includes("includeDatasheetInformation")
497
+ )))
498
+ throw error;
499
+ const fallbackRequest = {
500
+ ...request,
501
+ includeDatasheetInformation: false
502
+ };
503
+ let circuitJson;
504
+ let usedLegacyRequest = false;
505
+ try {
506
+ usedLegacyRequest = !request.includeDatasheetInformation;
507
+ circuitJson = await fetchPartCircuitJson(
508
+ usedLegacyRequest ? legacyRequest : fallbackRequest
509
+ );
510
+ } catch {
511
+ if (usedLegacyRequest) throw error;
512
+ circuitJson = await fetchPartCircuitJson(legacyRequest);
513
+ usedLegacyRequest = true;
514
+ }
515
+ if (!circuitJson?.length) throw error;
516
+ const manufacturerPartNumbers = circuitJson.flatMap(
517
+ (element) => element.type === "source_component" && element.manufacturer_part_number ? [element.manufacturer_part_number] : []
518
+ );
519
+ if (manufacturerPartNumber && manufacturerPartNumbers.some(
520
+ (importedManufacturerPartNumber) => importedManufacturerPartNumber.trim().toLowerCase() !== manufacturerPartNumber.trim().toLowerCase()
521
+ ))
522
+ throw error;
523
+ const reason = usedLegacyRequest ? "the parts engine only accepted a request without the datasheet option" : error instanceof Error ? error.message : String(error);
524
+ return { circuitJson, datasheetFailureReason: reason };
525
+ }
526
+ };
527
+ var fetchPartCircuitJsonWithoutDatasheet = async (fetchPartCircuitJson, request) => {
528
+ const { circuitJson } = await fetchDatasheetPart(fetchPartCircuitJson, {
529
+ ...request,
530
+ includeDatasheetInformation: false
531
+ });
532
+ return circuitJson;
533
+ };
534
+ var fetchPartCircuitJsonWithDatasheet = async ({
535
+ fetchPartCircuitJson,
536
+ supplierPartNumber,
537
+ manufacturerPartNumber
538
+ }, sourcePortOwner) => {
539
+ const includeDatasheetInformation = sourcePortOwner.config.componentName === "Chip" || sourcePortOwner.config.componentName === "OpAmp" || sourcePortOwner.config.componentName === "PushButton";
540
+ const request = {
541
+ supplierPartNumber,
542
+ manufacturerPartNumber,
543
+ platformFetch: sourcePortOwner.root?.platform?.platformFetch,
544
+ includeDatasheetInformation
545
+ };
546
+ let partFetch;
547
+ const circuit = sourcePortOwner.root;
548
+ if (sourcePortOwner.config.componentName === "Chip" && circuit) {
549
+ let partFetchesByEngine = chipDatasheetPartFetches.get(circuit);
550
+ if (!partFetchesByEngine) {
551
+ partFetchesByEngine = /* @__PURE__ */ new WeakMap();
552
+ chipDatasheetPartFetches.set(circuit, partFetchesByEngine);
553
+ }
554
+ let partFetches = partFetchesByEngine.get(fetchPartCircuitJson);
555
+ if (!partFetches) {
556
+ partFetches = /* @__PURE__ */ new Map();
557
+ partFetchesByEngine.set(fetchPartCircuitJson, partFetches);
558
+ }
559
+ const partCacheKey = `datasheet_part:${JSON.stringify(
560
+ [supplierPartNumber, manufacturerPartNumber]
561
+ )}`;
562
+ partFetch = partFetches.get(partCacheKey) ?? fetchDatasheetPart(fetchPartCircuitJson, request);
563
+ partFetches.set(partCacheKey, partFetch);
564
+ } else {
565
+ partFetch = fetchDatasheetPart(fetchPartCircuitJson, request);
566
+ }
567
+ const { circuitJson, datasheetFailureReason } = await partFetch;
568
+ if (includeDatasheetInformation && datasheetFailureReason !== void 0) {
569
+ const message = `Datasheet information for ${sourcePortOwner.getDisplayName()} could not be fetched: ${datasheetFailureReason}. Pin attributes may not be populated.`;
570
+ if (sourcePortOwner.source_component_id && sourcePortOwner.root) {
571
+ sourcePortOwner.root.db.source_property_ignored_warning.insert({
572
+ source_component_id: sourcePortOwner.source_component_id,
573
+ property_name: "pinAttributes",
574
+ message,
575
+ error_type: "source_property_ignored_warning"
576
+ });
577
+ } else {
578
+ console.warn(message);
579
+ }
580
+ }
581
+ return circuitJson;
582
+ };
583
+
584
+ // lib/utils/get-imported-internally-connected-pin-names.ts
585
+ var getImportedInternallyConnectedPinNames = (circuitJson) => {
586
+ const ports = circuitJson.filter((element) => element.type === "source_port");
587
+ const components = circuitJson.filter((element) => element.type === "source_component").filter(
588
+ (component) => component.internally_connected_source_port_ids !== void 0
589
+ );
590
+ if (!components.length) return void 0;
591
+ return components.flatMap(
592
+ (component) => (component.internally_connected_source_port_ids ?? []).flatMap((group) => {
593
+ const resolved = group.map(
594
+ (id) => ports.find(
595
+ (port) => port.source_port_id === id && port.source_component_id === component.source_component_id
596
+ )
597
+ );
598
+ if (resolved.some((port) => !port)) return [];
599
+ return [
600
+ resolved.map(
601
+ (port) => port.pin_number !== void 0 ? `pin${port.pin_number}` : port.name
602
+ )
603
+ ];
604
+ })
605
+ );
606
+ };
607
+
608
+ // lib/components/base-components/NormalComponent/NormalComponent_fetchDatasheetForValidation.ts
609
+ var NormalComponent_fetchDatasheetForValidation = (component) => {
610
+ if (!["Chip", "PushButton", "OpAmp"].includes(component.config.componentName))
611
+ return;
612
+ if (component._hasStartedPinAttributesFetch) return;
613
+ if (component.getInheritedProperty("partsEngineDisabled")) return;
614
+ if (component.getInheritedProperty("bomDisabled")) return;
615
+ if (component._importedInternallyConnectedPinNames !== void 0) return;
616
+ if (component._importedSourcePorts.some(
617
+ (port) => Object.values(source_pin_attributes2.parse(port)).some(
618
+ (value) => value !== void 0
619
+ )
620
+ ))
621
+ return;
622
+ const partsEngine = component.getInheritedProperty("partsEngine");
623
+ if (!partsEngine?.fetchPartCircuitJson) return;
624
+ const footprint = component.resolveFootprint();
625
+ const supplierPartNumbers = component._parsedProps.supplierPartNumbers;
626
+ if (supplierProps.shape.supplierPartNumbers.unwrap().keySchema.options.some(
627
+ (supplierName) => typeof component.root?.platform?.footprintLibraryMap?.[supplierName] !== "function" && supplierPartNumbers?.[supplierName]?.some(
628
+ (partNumber) => footprint === `${supplierName}:${partNumber}`
629
+ )
630
+ ))
631
+ return;
632
+ const supplierPartNumber = Object.values(supplierPartNumbers ?? {}).flat()[0];
633
+ const manufacturerPartNumber = resolveManufacturerPartNumber(
634
+ component._parsedProps
635
+ );
636
+ if (!supplierPartNumber && !manufacturerPartNumber) return;
637
+ component._hasStartedPinAttributesFetch = true;
638
+ component._queueAsyncEffect(
639
+ "fetch-datasheet-validation-metadata",
640
+ async () => {
641
+ try {
642
+ const partCircuitJson = await fetchPartCircuitJsonWithDatasheet(
643
+ {
644
+ fetchPartCircuitJson: partsEngine.fetchPartCircuitJson,
645
+ supplierPartNumber,
646
+ manufacturerPartNumber
647
+ },
648
+ component
649
+ );
650
+ component._fetchedSourcePortsForPinAttributes = partCircuitJson?.filter(
651
+ (element) => element.type === "source_port"
652
+ ) ?? [];
653
+ component._fetchedInternallyConnectedPinNames = getImportedInternallyConnectedPinNames(partCircuitJson ?? []);
654
+ component._markDirty("SourceDesignRuleChecks");
655
+ } catch {
656
+ }
657
+ }
658
+ );
659
+ };
660
+
661
+ // lib/components/base-components/NormalComponent/NormalComponent_doInitialSourcePinSpecificationChecks.ts
662
+ var NormalComponent_doInitialSourcePinSpecificationChecks = (component) => {
663
+ if (!["Chip", "PushButton", "OpAmp"].includes(component.config.componentName))
664
+ return;
665
+ const isChip = component.config.componentName === "Chip";
666
+ if (!component.source_component_id) return;
667
+ const { db: db2 } = component.root;
668
+ const existingWarning = db2.source_component_pins_underspecified_warning.getWhere({
669
+ source_component_id: component.source_component_id
670
+ });
671
+ const drcChecksDisabled = component.root?.platform?.drcChecksDisabled ?? component.getInheritedProperty("drcChecksDisabled");
672
+ const pinSpecificationDrcChecksDisabled = component.root?.platform?.pinSpecificationDrcChecksDisabled ?? component.getInheritedProperty("pinSpecificationDrcChecksDisabled");
673
+ const checksDisabled = drcChecksDisabled || pinSpecificationDrcChecksDisabled;
674
+ if (!checksDisabled) NormalComponent_fetchDatasheetForValidation(component);
675
+ const sourcePorts = checksDisabled ? [] : component.selectAll("port").flatMap((port) => {
676
+ if (!port.source_port_id) return [];
677
+ const sourcePort = db2.source_port.get(port.source_port_id);
678
+ return sourcePort?.source_component_id === component.source_component_id ? [sourcePort] : [];
679
+ });
680
+ const sourceComponent = checksDisabled ? null : db2.source_component.get(component.source_component_id);
681
+ const chipCircuitJson = sourceComponent ? [sourceComponent, ...sourcePorts] : [];
682
+ const issues = [];
683
+ if (!checksDisabled && isChip) {
684
+ for (const port of component.selectAll("port")) {
685
+ const sourcePort = sourcePorts.find(
686
+ (sourcePort2) => sourcePort2.source_port_id === port.source_port_id
687
+ );
688
+ if (!sourcePort) continue;
689
+ const declared = {};
690
+ for (const alias of port.getNameAndAliases()) {
691
+ Object.assign(declared, component._parsedProps.pinAttributes?.[alias]);
692
+ }
693
+ const imported = getImportedSourcePinAttributes(
694
+ port,
695
+ component._fetchedSourcePortsForPinAttributes.length ? component._fetchedSourcePortsForPinAttributes : component._importedSourcePorts
696
+ );
697
+ const reasons2 = getPinAttributeMismatches(declared, imported);
698
+ if (reasons2.length)
699
+ issues.push({
700
+ pinName: sourcePort.name || "unnamed pin",
701
+ reasons: reasons2,
702
+ sourcePort
703
+ });
704
+ }
705
+ }
706
+ for (const [warningTable, check] of [
707
+ [db2.source_no_power_pin_defined_warning, checkNoPowerPinDefined],
708
+ [db2.source_no_ground_pin_defined_warning, checkNoGroundPinDefined]
709
+ ]) {
710
+ const existing = warningTable.getWhere({
711
+ source_component_id: component.source_component_id
712
+ });
713
+ const existingId = existing?.type === "source_no_power_pin_defined_warning" ? existing.source_no_power_pin_defined_warning_id : existing?.source_no_ground_pin_defined_warning_id;
714
+ const [warning2] = checksDisabled || !isChip || issues.length ? [] : check(chipCircuitJson);
715
+ if (warning2) {
716
+ if (existingId) {
717
+ warningTable.update(existingId, {
718
+ message: warning2.message,
719
+ source_port_ids: warning2.source_port_ids,
720
+ subcircuit_id: warning2.subcircuit_id
721
+ });
722
+ } else {
723
+ db2.insertAll([warning2]);
724
+ }
725
+ } else if (existingId) {
726
+ warningTable.delete(existingId);
727
+ }
728
+ }
729
+ const [underspecifiedWarning] = checksDisabled || !isChip ? [] : checkAllPinsInComponentAreUnderspecified(chipCircuitJson);
730
+ const internalWarnings = checksDisabled ? [] : getDatasheetInternalConnectionWarnings(component);
731
+ if (!issues.length && !underspecifiedWarning && !internalWarnings.length) {
732
+ if (existingWarning) {
733
+ db2.source_component_pins_underspecified_warning.delete(
734
+ existingWarning.source_component_pins_underspecified_warning_id
735
+ );
736
+ }
737
+ return;
738
+ }
739
+ const examples = issues.slice(0, 3).map(({ pinName, reasons: reasons2 }) => `${pinName} (${reasons2.join("; ")})`).join(", ");
740
+ const remaining = issues.length > 3 ? `, and ${issues.length - 3} more` : "";
741
+ const pinMessage = issues.length ? `Chip ${component.name || "unnamed chip"} has pinAttributes that conflict with fetched pin metadata on ${issues.length} pin${issues.length === 1 ? "" : "s"}: ${examples}${remaining}. Check the chip configuration against the part datasheet.` : underspecifiedWarning?.message;
742
+ const warning = {
743
+ source_component_id: component.source_component_id,
744
+ source_port_ids: [
745
+ .../* @__PURE__ */ new Set([
746
+ ...issues.length ? issues.map(({ sourcePort }) => sourcePort.source_port_id) : underspecifiedWarning?.source_port_ids ?? [],
747
+ ...internalWarnings.flatMap((warning2) => warning2.sourcePortIds)
748
+ ])
749
+ ],
750
+ subcircuit_id: component.getSubcircuit().subcircuit_id ?? void 0,
751
+ warning_type: "source_component_pins_underspecified_warning",
752
+ message: [pinMessage, ...internalWarnings.map((warning2) => warning2.message)].filter(Boolean).join(" ")
753
+ };
754
+ if (existingWarning) {
755
+ db2.source_component_pins_underspecified_warning.update(
756
+ existingWarning.source_component_pins_underspecified_warning_id,
757
+ warning
758
+ );
759
+ } else {
760
+ db2.source_component_pins_underspecified_warning.insert(warning);
761
+ }
762
+ };
763
+
141
764
  // lib/utils/schematic/getPinNumberFromPinLabelsKey.ts
142
765
  var PIN_LABELS_KEY_RE = /^(?:pin)?(\d+)$/;
143
766
  var getPinNumberFromPinLabelsKey = (pinKey) => {
@@ -201,7 +824,7 @@ function getNumericPinLabels(pinLabels) {
201
824
  }
202
825
 
203
826
  // lib/components/base-components/NormalComponent/NormalComponent.ts
204
- import { resolveManufacturerPartNumber as resolveManufacturerPartNumber2 } from "@tscircuit/props";
827
+ import { resolveManufacturerPartNumber as resolveManufacturerPartNumber3 } from "@tscircuit/props";
205
828
 
206
829
  // lib/utils/cad/compose-cad-model-rotation.ts
207
830
  import { normalizeDegrees } from "@tscircuit/math-utils";
@@ -4614,234 +5237,6 @@ var getCenterOfPcbPrimitives = (pcbPrimitives) => {
4614
5237
  // lib/components/primitive-components/Port/Port.ts
4615
5238
  import { portProps } from "@tscircuit/props";
4616
5239
 
4617
- // lib/components/primitive-components/Port/resolve-port-source-pin-attributes.ts
4618
- import {
4619
- source_pin_attributes
4620
- } from "circuit-json";
4621
-
4622
- // lib/components/primitive-components/Port/apply-pin-attributes-to-source-port.ts
4623
- import { voltage } from "circuit-json";
4624
- var setSupportedCapability = (sourcePortProps, capability) => {
4625
- switch (capability) {
4626
- case "i2c_sda":
4627
- sourcePortProps.supports_i2c_sda = true;
4628
- return;
4629
- case "i2c_scl":
4630
- sourcePortProps.supports_i2c_scl = true;
4631
- return;
4632
- case "spi_cs":
4633
- sourcePortProps.supports_spi_cs = true;
4634
- return;
4635
- case "spi_sck":
4636
- sourcePortProps.supports_spi_sck = true;
4637
- return;
4638
- case "spi_mosi":
4639
- sourcePortProps.supports_spi_mosi = true;
4640
- return;
4641
- case "spi_miso":
4642
- sourcePortProps.supports_spi_miso = true;
4643
- return;
4644
- case "uart_tx":
4645
- sourcePortProps.supports_uart_tx = true;
4646
- return;
4647
- case "uart_rx":
4648
- sourcePortProps.supports_uart_rx = true;
4649
- return;
4650
- default: {
4651
- const unhandledCapability = capability;
4652
- throw new Error(`Unhandled pin capability: ${unhandledCapability}`);
4653
- }
4654
- }
4655
- };
4656
- var setConfiguredCapability = (sourcePortProps, capability) => {
4657
- switch (capability) {
4658
- case "i2c_sda":
4659
- sourcePortProps.is_configured_for_i2c_sda = true;
4660
- return;
4661
- case "i2c_scl":
4662
- sourcePortProps.is_configured_for_i2c_scl = true;
4663
- return;
4664
- case "spi_cs":
4665
- sourcePortProps.is_configured_for_spi_cs = true;
4666
- return;
4667
- case "spi_sck":
4668
- sourcePortProps.is_configured_for_spi_sck = true;
4669
- return;
4670
- case "spi_mosi":
4671
- sourcePortProps.is_configured_for_spi_mosi = true;
4672
- return;
4673
- case "spi_miso":
4674
- sourcePortProps.is_configured_for_spi_miso = true;
4675
- return;
4676
- case "uart_tx":
4677
- sourcePortProps.is_configured_for_uart_tx = true;
4678
- return;
4679
- case "uart_rx":
4680
- sourcePortProps.is_configured_for_uart_rx = true;
4681
- return;
4682
- default: {
4683
- const unhandledCapability = capability;
4684
- throw new Error(
4685
- `Unhandled configured pin capability: ${unhandledCapability}`
4686
- );
4687
- }
4688
- }
4689
- };
4690
- var applyPinAttributesToSourcePort = (sourcePortProps, attributes) => {
4691
- if (attributes.isInput !== void 0) {
4692
- sourcePortProps.is_input = attributes.isInput;
4693
- }
4694
- if (attributes.isOutput !== void 0) {
4695
- sourcePortProps.is_output = attributes.isOutput;
4696
- }
4697
- if (attributes.isBidirectional !== void 0) {
4698
- sourcePortProps.is_bidirectional = attributes.isBidirectional;
4699
- }
4700
- if (attributes.isPassive !== void 0) {
4701
- sourcePortProps.is_passive = attributes.isPassive;
4702
- }
4703
- if (attributes.canUseTriState !== void 0) {
4704
- sourcePortProps.can_use_tri_state = attributes.canUseTriState;
4705
- }
4706
- if (attributes.isUsingTriState !== void 0) {
4707
- sourcePortProps.is_using_tri_state = attributes.isUsingTriState;
4708
- }
4709
- if (attributes.canUseOpenCollector !== void 0) {
4710
- sourcePortProps.can_use_open_collector = attributes.canUseOpenCollector;
4711
- }
4712
- if (attributes.isUsingOpenCollector !== void 0) {
4713
- sourcePortProps.is_using_open_collector = attributes.isUsingOpenCollector;
4714
- }
4715
- if (attributes.canUseOpenEmitter !== void 0) {
4716
- sourcePortProps.can_use_open_emitter = attributes.canUseOpenEmitter;
4717
- }
4718
- if (attributes.isUsingOpenEmitter !== void 0) {
4719
- sourcePortProps.is_using_open_emitter = attributes.isUsingOpenEmitter;
4720
- }
4721
- if (attributes.isGpio !== void 0) {
4722
- sourcePortProps.is_gpio = attributes.isGpio;
4723
- }
4724
- if (attributes.highlightColor !== void 0) {
4725
- sourcePortProps.highlight_color = attributes.highlightColor;
4726
- }
4727
- for (const capability of attributes.capabilities ?? []) {
4728
- setSupportedCapability(sourcePortProps, capability);
4729
- }
4730
- const configuredCapabilities = /* @__PURE__ */ new Set([
4731
- ...attributes.activeCapabilities ?? [],
4732
- ...attributes.activeCapability ? [attributes.activeCapability] : []
4733
- ]);
4734
- for (const capability of configuredCapabilities) {
4735
- setConfiguredCapability(sourcePortProps, capability);
4736
- }
4737
- if (attributes.mustBeConnected !== void 0) {
4738
- sourcePortProps.must_be_connected = attributes.mustBeConnected;
4739
- }
4740
- if (attributes.providesPower !== void 0) {
4741
- sourcePortProps.provides_power = attributes.providesPower;
4742
- }
4743
- if (attributes.requiresPower !== void 0) {
4744
- sourcePortProps.requires_power = attributes.requiresPower;
4745
- }
4746
- if (attributes.providesGround !== void 0) {
4747
- sourcePortProps.provides_ground = attributes.providesGround;
4748
- }
4749
- if (attributes.requiresGround !== void 0) {
4750
- sourcePortProps.requires_ground = attributes.requiresGround;
4751
- }
4752
- if (attributes.providesVoltage !== void 0) {
4753
- sourcePortProps.provides_voltage = voltage.parse(attributes.providesVoltage);
4754
- }
4755
- if (attributes.requiresVoltage !== void 0) {
4756
- sourcePortProps.requires_voltage = voltage.parse(attributes.requiresVoltage);
4757
- }
4758
- if (attributes.doNotConnect !== void 0) {
4759
- sourcePortProps.do_not_connect = attributes.doNotConnect;
4760
- }
4761
- if (attributes.includeInBoardPinout !== void 0) {
4762
- sourcePortProps.include_in_board_pinout = attributes.includeInBoardPinout;
4763
- }
4764
- if (attributes.canUseInternalPullup !== void 0) {
4765
- sourcePortProps.can_use_internal_pullup = attributes.canUseInternalPullup;
4766
- }
4767
- if (attributes.isUsingInternalPullup !== void 0) {
4768
- sourcePortProps.is_using_internal_pullup = attributes.isUsingInternalPullup;
4769
- }
4770
- if (attributes.needsExternalPullup !== void 0) {
4771
- sourcePortProps.needs_external_pullup = attributes.needsExternalPullup;
4772
- }
4773
- if (attributes.canUseInternalPulldown !== void 0) {
4774
- sourcePortProps.can_use_internal_pulldown = attributes.canUseInternalPulldown;
4775
- }
4776
- if (attributes.isUsingInternalPulldown !== void 0) {
4777
- sourcePortProps.is_using_internal_pulldown = attributes.isUsingInternalPulldown;
4778
- }
4779
- if (attributes.needsExternalPulldown !== void 0) {
4780
- sourcePortProps.needs_external_pulldown = attributes.needsExternalPulldown;
4781
- }
4782
- if (attributes.canUseOpenDrain !== void 0) {
4783
- sourcePortProps.can_use_open_drain = attributes.canUseOpenDrain;
4784
- }
4785
- if (attributes.isUsingOpenDrain !== void 0) {
4786
- sourcePortProps.is_using_open_drain = attributes.isUsingOpenDrain;
4787
- }
4788
- if (attributes.canUsePushPull !== void 0) {
4789
- sourcePortProps.can_use_push_pull = attributes.canUsePushPull;
4790
- }
4791
- if (attributes.isUsingPushPull !== void 0) {
4792
- sourcePortProps.is_using_push_pull = attributes.isUsingPushPull;
4793
- }
4794
- if (attributes.shouldHaveDecouplingCapacitor !== void 0) {
4795
- sourcePortProps.should_have_decoupling_capacitor = attributes.shouldHaveDecouplingCapacitor;
4796
- }
4797
- if (attributes.recommendedDecouplingCapacitorCapacitance !== void 0) {
4798
- sourcePortProps.recommended_decoupling_capacitor_capacitance = attributes.recommendedDecouplingCapacitorCapacitance;
4799
- }
4800
- };
4801
-
4802
- // lib/components/primitive-components/Port/resolve-port-source-pin-attributes.ts
4803
- var getImportedSourcePinAttributes = (port, importedSourcePorts) => {
4804
- if (new Set(
4805
- importedSourcePorts.map((sourcePort) => sourcePort.source_component_id)
4806
- ).size > 1)
4807
- return {};
4808
- const pinNumber = port.props.pinNumber;
4809
- const physicalMatches = pinNumber === void 0 ? [] : importedSourcePorts.filter(
4810
- (sourcePort) => sourcePort.pin_number === pinNumber
4811
- );
4812
- const aliases = port.getNameAndAliases();
4813
- const matches = physicalMatches.length > 0 ? physicalMatches : importedSourcePorts.filter(
4814
- (sourcePort) => [sourcePort.name, ...sourcePort.port_hints ?? []].some(
4815
- (alias) => aliases.includes(alias)
4816
- )
4817
- );
4818
- if (matches.length !== 1) return {};
4819
- const attributes = source_pin_attributes.parse(matches[0]);
4820
- for (const attributeName of Object.keys(
4821
- attributes
4822
- )) {
4823
- if (attributes[attributeName] === void 0)
4824
- delete attributes[attributeName];
4825
- }
4826
- return attributes;
4827
- };
4828
- var resolvePortSourcePinAttributes = (port) => {
4829
- const attributes = getImportedSourcePinAttributes(
4830
- port,
4831
- port.getParentNormalComponent()?._importedSourcePorts ?? []
4832
- );
4833
- for (const pinAttributes of port._getMatchingPinAttributes()) {
4834
- for (const attributeName of Object.keys(
4835
- attributes
4836
- )) {
4837
- if (pinAttributes.capabilities !== void 0 && attributeName.startsWith("supports_") || (pinAttributes.activeCapability !== void 0 || pinAttributes.activeCapabilities !== void 0) && attributeName.startsWith("is_configured_for_"))
4838
- delete attributes[attributeName];
4839
- }
4840
- applyPinAttributesToSourcePort(attributes, pinAttributes);
4841
- }
4842
- return attributes;
4843
- };
4844
-
4845
5240
  // lib/components/primitive-components/Port/Port_doInitialCreateTracesFromProps.ts
4846
5241
  var getConnectionTargets = (target) => {
4847
5242
  if (!target) return [];
@@ -4888,10 +5283,25 @@ function netIsGround(net) {
4888
5283
  return net._parsedProps.isGroundNet ?? GROUND_NET_REGEX.test(net._parsedProps.name);
4889
5284
  }
4890
5285
  function Port_isConnectedToGround(port) {
4891
- for (const connectedTrace of port._getDirectlyConnectedTraces()) {
5286
+ const internallyConnectedPorts = /* @__PURE__ */ new Set([
5287
+ port,
5288
+ ...port._getPortsInternallyConnectedToThisPort()
5289
+ ]);
5290
+ const traces = new Set(
5291
+ [...internallyConnectedPorts].flatMap(
5292
+ (connectedPort) => connectedPort._getDirectlyConnectedTraces()
5293
+ )
5294
+ );
5295
+ for (const connectedTrace of traces) {
4892
5296
  const connectedPorts = connectedTrace._findConnectedPorts().ports ?? [];
4893
- for (const connectedPort of connectedPorts) {
4894
- if (connectedPort === port) continue;
5297
+ const connectedPortGroup = new Set(
5298
+ connectedPorts.flatMap((connectedPort) => [
5299
+ connectedPort,
5300
+ ...connectedPort._getPortsInternallyConnectedToThisPort()
5301
+ ])
5302
+ );
5303
+ for (const connectedPort of connectedPortGroup) {
5304
+ if (internallyConnectedPorts.has(connectedPort)) continue;
4895
5305
  if (portIsGround(connectedPort)) return true;
4896
5306
  }
4897
5307
  for (const connectedNet of connectedTrace._findConnectedNets().nets) {
@@ -4912,16 +5322,35 @@ function portShouldHaveDecouplingCapacitor(port) {
4912
5322
  }
4913
5323
  if (attributes.requires_power !== void 0) return attributes.requires_power;
4914
5324
  if (attributes.provides_power === true) return false;
4915
- for (const portName of port.getNameAndAliases()) {
5325
+ const aliases = port.getNameAndAliases();
5326
+ if (attributes.requires_ground === true || attributes.provides_ground === true || aliases.some((alias) => GROUND_NET_REGEX.test(alias)))
5327
+ return false;
5328
+ for (const portName of aliases) {
5329
+ if (portName === port.physicalPinName) continue;
4916
5330
  if (POWER_NET_REGEX.test(portName)) return true;
4917
5331
  }
4918
5332
  return false;
4919
5333
  }
4920
5334
  function Port_isConnectedToPower(port) {
4921
- for (const connectedTrace of port._getDirectlyConnectedTraces()) {
5335
+ const internallyConnectedPorts = /* @__PURE__ */ new Set([
5336
+ port,
5337
+ ...port._getPortsInternallyConnectedToThisPort()
5338
+ ]);
5339
+ const traces = new Set(
5340
+ [...internallyConnectedPorts].flatMap(
5341
+ (connectedPort) => connectedPort._getDirectlyConnectedTraces()
5342
+ )
5343
+ );
5344
+ for (const connectedTrace of traces) {
4922
5345
  const connectedPorts = connectedTrace._findConnectedPorts().ports ?? [];
4923
- for (const connectedPort of connectedPorts) {
4924
- if (connectedPort === port) continue;
5346
+ const connectedPortGroup = new Set(
5347
+ connectedPorts.flatMap((connectedPort) => [
5348
+ connectedPort,
5349
+ ...connectedPort._getPortsInternallyConnectedToThisPort()
5350
+ ])
5351
+ );
5352
+ for (const connectedPort of connectedPortGroup) {
5353
+ if (internallyConnectedPorts.has(connectedPort)) continue;
4925
5354
  if (portShouldHaveDecouplingCapacitor(connectedPort)) return true;
4926
5355
  }
4927
5356
  }
@@ -5138,12 +5567,21 @@ var Port = class extends PrimitiveComponent2 {
5138
5567
  const parent = this.parent;
5139
5568
  if (!parent || !parent._getInternallyConnectedPins) return [];
5140
5569
  const internallyConnectedPorts = parent._getInternallyConnectedPins();
5141
- for (const ports of internallyConnectedPorts) {
5142
- if (ports.some((port) => port === this)) {
5143
- return ports;
5570
+ const connected = /* @__PURE__ */ new Set([this]);
5571
+ let changed = true;
5572
+ while (changed) {
5573
+ changed = false;
5574
+ for (const ports of internallyConnectedPorts) {
5575
+ if (!ports.some((port) => connected.has(port))) continue;
5576
+ for (const port of ports) {
5577
+ if (!connected.has(port)) {
5578
+ connected.add(port);
5579
+ changed = true;
5580
+ }
5581
+ }
5144
5582
  }
5145
5583
  }
5146
- return [];
5584
+ return connected.size > 1 ? [...connected] : [];
5147
5585
  }
5148
5586
  /**
5149
5587
  * Return true if this port has a schematic representation and can be rendered
@@ -13780,6 +14218,12 @@ var createComponentsFromCircuitJson = ({
13780
14218
  const importedSourcePorts = circuitJson.filter(
13781
14219
  (elm) => elm.type === "source_port"
13782
14220
  );
14221
+ if (sourcePortOwner) {
14222
+ const internalGroups = getImportedInternallyConnectedPinNames(circuitJson);
14223
+ if (internalGroups !== void 0) {
14224
+ sourcePortOwner._importedInternallyConnectedPinNames = internalGroups;
14225
+ }
14226
+ }
13783
14227
  if (sourcePortOwner && importedSourcePorts.length > 0) {
13784
14228
  sourcePortOwner._importedSourcePorts = importedSourcePorts;
13785
14229
  for (const port of sourcePortOwner._getAllPortsFromChildren()) {
@@ -16545,110 +16989,6 @@ import {
16545
16989
  pcb_pin1_location,
16546
16990
  source_component_misconfigured_error
16547
16991
  } from "circuit-json";
16548
-
16549
- // lib/utils/fetch-part-circuit-json-with-datasheet.ts
16550
- import { ZodError } from "zod";
16551
- var chipDatasheetPartFetches = /* @__PURE__ */ new WeakMap();
16552
- var fetchDatasheetPart = async (fetchPartCircuitJson, request) => {
16553
- const { supplierPartNumber, manufacturerPartNumber, platformFetch } = request;
16554
- const legacyRequest = {
16555
- supplierPartNumber,
16556
- manufacturerPartNumber,
16557
- platformFetch
16558
- };
16559
- try {
16560
- return { circuitJson: await fetchPartCircuitJson(request) };
16561
- } catch (error) {
16562
- if (!request.includeDatasheetInformation && !(error instanceof ZodError && error.issues.some(
16563
- (issue) => issue.code === "unrecognized_keys" && issue.keys.includes("includeDatasheetInformation")
16564
- )))
16565
- throw error;
16566
- const fallbackRequest = {
16567
- ...request,
16568
- includeDatasheetInformation: false
16569
- };
16570
- let circuitJson;
16571
- let usedLegacyRequest = false;
16572
- try {
16573
- usedLegacyRequest = !request.includeDatasheetInformation;
16574
- circuitJson = await fetchPartCircuitJson(
16575
- usedLegacyRequest ? legacyRequest : fallbackRequest
16576
- );
16577
- } catch {
16578
- if (usedLegacyRequest) throw error;
16579
- circuitJson = await fetchPartCircuitJson(legacyRequest);
16580
- usedLegacyRequest = true;
16581
- }
16582
- if (!circuitJson?.length) throw error;
16583
- const manufacturerPartNumbers = circuitJson.flatMap(
16584
- (element) => element.type === "source_component" && element.manufacturer_part_number ? [element.manufacturer_part_number] : []
16585
- );
16586
- if (manufacturerPartNumber && manufacturerPartNumbers.some(
16587
- (importedManufacturerPartNumber) => importedManufacturerPartNumber.trim().toLowerCase() !== manufacturerPartNumber.trim().toLowerCase()
16588
- ))
16589
- throw error;
16590
- const reason = usedLegacyRequest ? "the parts engine only accepted a request without the datasheet option" : error instanceof Error ? error.message : String(error);
16591
- return { circuitJson, datasheetFailureReason: reason };
16592
- }
16593
- };
16594
- var fetchPartCircuitJsonWithoutDatasheet = async (fetchPartCircuitJson, request) => {
16595
- const { circuitJson } = await fetchDatasheetPart(fetchPartCircuitJson, {
16596
- ...request,
16597
- includeDatasheetInformation: false
16598
- });
16599
- return circuitJson;
16600
- };
16601
- var fetchPartCircuitJsonWithDatasheet = async ({
16602
- fetchPartCircuitJson,
16603
- supplierPartNumber,
16604
- manufacturerPartNumber
16605
- }, sourcePortOwner) => {
16606
- const includeDatasheetInformation = sourcePortOwner.config.componentName === "Chip" || sourcePortOwner.config.componentName === "OpAmp";
16607
- const request = {
16608
- supplierPartNumber,
16609
- manufacturerPartNumber,
16610
- platformFetch: sourcePortOwner.root?.platform?.platformFetch,
16611
- includeDatasheetInformation
16612
- };
16613
- let partFetch;
16614
- const circuit = sourcePortOwner.root;
16615
- if (sourcePortOwner.config.componentName === "Chip" && circuit) {
16616
- let partFetchesByEngine = chipDatasheetPartFetches.get(circuit);
16617
- if (!partFetchesByEngine) {
16618
- partFetchesByEngine = /* @__PURE__ */ new WeakMap();
16619
- chipDatasheetPartFetches.set(circuit, partFetchesByEngine);
16620
- }
16621
- let partFetches = partFetchesByEngine.get(fetchPartCircuitJson);
16622
- if (!partFetches) {
16623
- partFetches = /* @__PURE__ */ new Map();
16624
- partFetchesByEngine.set(fetchPartCircuitJson, partFetches);
16625
- }
16626
- const partCacheKey = `datasheet_part:${JSON.stringify(
16627
- [supplierPartNumber, manufacturerPartNumber]
16628
- )}`;
16629
- partFetch = partFetches.get(partCacheKey) ?? fetchDatasheetPart(fetchPartCircuitJson, request);
16630
- partFetches.set(partCacheKey, partFetch);
16631
- } else {
16632
- partFetch = fetchDatasheetPart(fetchPartCircuitJson, request);
16633
- }
16634
- const { circuitJson, datasheetFailureReason } = await partFetch;
16635
- if (includeDatasheetInformation && datasheetFailureReason !== void 0) {
16636
- const message = `Datasheet information for ${sourcePortOwner.getDisplayName()} could not be fetched: ${datasheetFailureReason}. Pin attributes may not be populated.`;
16637
- if (sourcePortOwner.source_component_id && sourcePortOwner.root) {
16638
- sourcePortOwner.root.db.source_property_ignored_warning.insert({
16639
- source_component_id: sourcePortOwner.source_component_id,
16640
- property_name: "pinAttributes",
16641
- message,
16642
- error_type: "source_property_ignored_warning"
16643
- });
16644
- } else {
16645
- console.warn(message);
16646
- }
16647
- }
16648
- return circuitJson;
16649
- };
16650
-
16651
- // lib/components/base-components/NormalComponent/NormalComponent_doInitialPartOrientationAnalysis.ts
16652
16992
  var pendingSupplierPartOrientationAnalyses = /* @__PURE__ */ new WeakMap();
16653
16993
  var getPendingSupplierPartOrientationAnalyses = (partsEngine) => {
16654
16994
  const existing = pendingSupplierPartOrientationAnalyses.get(partsEngine);
@@ -16980,8 +17320,8 @@ function NormalComponent_doInitialPcbComponentAnchorAlignment(component) {
16980
17320
 
16981
17321
  // lib/components/base-components/NormalComponent/NormalComponent_doInitialPcbFootprintStringRender.ts
16982
17322
  import {
16983
- supplierProps,
16984
- resolveManufacturerPartNumber
17323
+ supplierProps as supplierProps2,
17324
+ resolveManufacturerPartNumber as resolveManufacturerPartNumber2
16985
17325
  } from "@tscircuit/props";
16986
17326
  import {
16987
17327
  circuit_json_footprint_load_error,
@@ -17067,7 +17407,7 @@ var parseLibraryFootprintRef = (s2) => {
17067
17407
  };
17068
17408
 
17069
17409
  // lib/components/base-components/NormalComponent/NormalComponent_doInitialPcbFootprintStringRender.ts
17070
- var supplierNames = supplierProps.shape.supplierPartNumbers.unwrap().keySchema.options;
17410
+ var supplierNames = supplierProps2.shape.supplierPartNumbers.unwrap().keySchema.options;
17071
17411
  var shouldAddOutsideFootprintWrapper = (component) => component.componentName === "Symbol" || component.isSchematicPrimitive;
17072
17412
  var getSupplierPartCircuitJsonResolver = (component, footprintLibrary, footprintName) => {
17073
17413
  if (component.getInheritedProperty("partsEngineDisabled")) return;
@@ -17086,7 +17426,7 @@ var getSupplierPartCircuitJsonResolver = (component, footprintLibrary, footprint
17086
17426
  {
17087
17427
  fetchPartCircuitJson,
17088
17428
  supplierPartNumber,
17089
- manufacturerPartNumber: resolveManufacturerPartNumber(component.props)
17429
+ manufacturerPartNumber: resolveManufacturerPartNumber2(component.props)
17090
17430
  },
17091
17431
  component
17092
17432
  );
@@ -17662,7 +18002,7 @@ var NormalComponent_doInitialMissingManufacturerPartNumberWarning = (component)
17662
18002
 
17663
18003
  // lib/components/base-components/NormalComponent/NormalComponent_doInitialComponentAvailabilityWarning.ts
17664
18004
  import {
17665
- supplierProps as supplierProps2
18005
+ supplierProps as supplierProps3
17666
18006
  } from "@tscircuit/props";
17667
18007
  import { source_component_availability_warning } from "circuit-json";
17668
18008
 
@@ -17720,7 +18060,7 @@ var checkPartAvailability = (circuit, {
17720
18060
 
17721
18061
  // lib/components/base-components/NormalComponent/NormalComponent_doInitialComponentAvailabilityWarning.ts
17722
18062
  var availabilityChecks = /* @__PURE__ */ new WeakMap();
17723
- var supplierNames2 = supplierProps2.shape.supplierPartNumbers.unwrap().keySchema.options;
18063
+ var supplierNames2 = supplierProps3.shape.supplierPartNumbers.unwrap().keySchema.options;
17724
18064
  function NormalComponent_doInitialComponentAvailabilityWarning(component, { refresh = false } = {}) {
17725
18065
  const root = component.root;
17726
18066
  const sourceComponentId = component.source_component_id;
@@ -17796,14 +18136,14 @@ function NormalComponent_doInitialComponentAvailabilityWarning(component, { refr
17796
18136
  // lib/components/base-components/NormalComponent/NormalComponent_doInitialSupplierFootprintMismatchWarning.ts
17797
18137
  import { getBoundsOfPcbElements } from "@tscircuit/circuit-json-util";
17798
18138
  import {
17799
- supplierProps as supplierProps3
18139
+ supplierProps as supplierProps4
17800
18140
  } from "@tscircuit/props";
17801
18141
  import {
17802
18142
  source_part_not_found_warning,
17803
18143
  supplier_footprint_mismatch_warning
17804
18144
  } from "circuit-json";
17805
18145
  var SUPPLIER_FOOTPRINT_IOU_WARNING_THRESHOLD = 0.8;
17806
- var supplierNames3 = supplierProps3.shape.supplierPartNumbers.unwrap().keySchema.options;
18146
+ var supplierNames3 = supplierProps4.shape.supplierPartNumbers.unwrap().keySchema.options;
17807
18147
  var isCopperElement = (elm) => elm.type === "pcb_smtpad" || elm.type === "pcb_plated_hole";
17808
18148
  var isValidBounds = (bounds) => Number.isFinite(bounds.minX) && Number.isFinite(bounds.minY) && Number.isFinite(bounds.maxX) && Number.isFinite(bounds.maxY) && bounds.maxX > bounds.minX && bounds.maxY > bounds.minY;
17809
18149
  var getCopperBounds = (elements) => {
@@ -18127,6 +18467,11 @@ var NormalComponent = class extends PrimitiveComponent2 {
18127
18467
  _asyncFootprintCadModel;
18128
18468
  /** Electrical attributes from imported ports; user props remain authoritative. */
18129
18469
  _importedSourcePorts = [];
18470
+ _importedInternallyConnectedPinNames;
18471
+ /** Optional datasheet facts fetched solely for source-level validation. */
18472
+ _fetchedSourcePortsForPinAttributes = [];
18473
+ _fetchedInternallyConnectedPinNames;
18474
+ _hasStartedPinAttributesFetch = false;
18130
18475
  _isCadModelChild;
18131
18476
  _inferredInternallyConnectedPinNames = [];
18132
18477
  pcb_missing_footprint_error_id;
@@ -18149,7 +18494,7 @@ var NormalComponent = class extends PrimitiveComponent2 {
18149
18494
  return [];
18150
18495
  }
18151
18496
  get internallyConnectedPinNames() {
18152
- const rawPins = this._parsedProps.internallyConnectedPins ?? this.defaultInternallyConnectedPinNames;
18497
+ const rawPins = this._parsedProps.internallyConnectedPins ?? this._importedInternallyConnectedPinNames ?? this.defaultInternallyConnectedPinNames;
18153
18498
  return [...rawPins, ...this._inferredInternallyConnectedPinNames].map(
18154
18499
  (pinGroup) => pinGroup.map(
18155
18500
  (pin) => typeof pin === "number" ? `pin${pin}` : pin
@@ -18596,7 +18941,7 @@ var NormalComponent = class extends PrimitiveComponent2 {
18596
18941
  const source_component = db2.source_component.insert({
18597
18942
  ftype,
18598
18943
  name: this.name,
18599
- manufacturer_part_number: resolveManufacturerPartNumber2(props),
18944
+ manufacturer_part_number: resolveManufacturerPartNumber3(props),
18600
18945
  supplier_part_numbers: props.supplierPartNumbers,
18601
18946
  display_name: props.displayName
18602
18947
  });
@@ -18663,7 +19008,8 @@ var NormalComponent = class extends PrimitiveComponent2 {
18663
19008
  for (const netPortNames of this.internallyConnectedPinNames) {
18664
19009
  const ports = [];
18665
19010
  for (const portName of netPortNames) {
18666
- ports.push(this.portMap[portName]);
19011
+ const port = this.portMap[portName] ?? this.portMap[`pin${portName}`];
19012
+ if (port) ports.push(port);
18667
19013
  }
18668
19014
  internallyConnectedPorts.push(ports);
18669
19015
  }
@@ -18742,7 +19088,7 @@ var NormalComponent = class extends PrimitiveComponent2 {
18742
19088
  const schematic_box_width = dimensions?.getSize().width;
18743
19089
  const schematic_box_height = dimensions?.getSize().height;
18744
19090
  const manufacturer_part_number_schematic_text = db2.schematic_text.insert({
18745
- text: resolveManufacturerPartNumber2(props) ?? "",
19091
+ text: resolveManufacturerPartNumber3(props) ?? "",
18746
19092
  schematic_component_id: schematic_component2.schematic_component_id,
18747
19093
  anchor: "left",
18748
19094
  rotation: 0,
@@ -19764,6 +20110,10 @@ var NormalComponent = class extends PrimitiveComponent2 {
19764
20110
  }
19765
20111
  doInitialSourceDesignRuleChecks() {
19766
20112
  NormalComponent_doInitialSourceDesignRuleChecks(this);
20113
+ NormalComponent_doInitialSourcePinSpecificationChecks(this);
20114
+ }
20115
+ updateSourceDesignRuleChecks() {
20116
+ NormalComponent_doInitialSourcePinSpecificationChecks(this);
19767
20117
  }
19768
20118
  doInitialSourceComponentPropertyValidation() {
19769
20119
  this._insertInvalidFootprintPropErrors();
@@ -19990,7 +20340,7 @@ function inflatePcbBoard(pcbBoard, inflatorContext) {
19990
20340
  }
19991
20341
 
19992
20342
  // lib/components/normal-components/Capacitor.ts
19993
- import { capacitorProps, resolveManufacturerPartNumber as resolveManufacturerPartNumber3 } from "@tscircuit/props";
20343
+ import { capacitorProps, resolveManufacturerPartNumber as resolveManufacturerPartNumber4 } from "@tscircuit/props";
19994
20344
  import { formatSiUnit } from "format-si-unit";
19995
20345
  import { symbols as symbols3 } from "schematic-symbols";
19996
20346
 
@@ -20176,7 +20526,7 @@ var Capacitor = class extends NormalComponent {
20176
20526
  const source_component = db2.source_component.insert({
20177
20527
  ftype: "simple_capacitor",
20178
20528
  name: this.name,
20179
- manufacturer_part_number: resolveManufacturerPartNumber3(props),
20529
+ manufacturer_part_number: resolveManufacturerPartNumber4(props),
20180
20530
  supplier_part_numbers: props.supplierPartNumbers,
20181
20531
  capacitance: props.capacitance,
20182
20532
  max_voltage_rating: props.maxVoltageRating,
@@ -20309,9 +20659,7 @@ function inflateSourceCapacitor(sourceElm, inflatorContext) {
20309
20659
  // lib/components/normal-components/Chip.ts
20310
20660
  import { normalizeDegrees as normalizeDegrees6 } from "@tscircuit/math-utils";
20311
20661
  import { chipProps, resolveManufacturerPartNumber as resolveManufacturerPartNumber5 } from "@tscircuit/props";
20312
- import {
20313
- pcb_component_invalid_layer_error as pcb_component_invalid_layer_error2
20314
- } from "circuit-json";
20662
+ import { pcb_component_invalid_layer_error as pcb_component_invalid_layer_error2 } from "circuit-json";
20315
20663
 
20316
20664
  // lib/components/normal-components/Chip_doInitialPcbPlacementDesignRuleChecks.ts
20317
20665
  import { checkConnectorAccessibleOrientation } from "@tscircuit/checks";
@@ -20375,209 +20723,8 @@ var Chip_doInitialPcbPlacementDesignRuleChecks = (chip) => {
20375
20723
  db2.insertAll([orientationWarning]);
20376
20724
  };
20377
20725
 
20378
- // lib/components/normal-components/Chip_doInitialSourcePinSpecificationChecks.ts
20379
- import {
20380
- checkAllPinsInComponentAreUnderspecified,
20381
- checkNoGroundPinDefined,
20382
- checkNoPowerPinDefined
20383
- } from "@tscircuit/checks";
20384
-
20385
- // lib/components/primitive-components/Port/get-pin-attribute-mismatches.ts
20386
- var getPinAttributeMismatches = (declared, imported) => {
20387
- const mismatches = [];
20388
- for (const propName of Object.keys(declared)) {
20389
- if (propName === "highlightColor" || propName === "includeInBoardPinout")
20390
- continue;
20391
- const normalized = {};
20392
- applyPinAttributesToSourcePort(normalized, {
20393
- [propName]: declared[propName]
20394
- });
20395
- if (propName === "capabilities") {
20396
- for (const attributeName of Object.keys(
20397
- imported
20398
- )) {
20399
- if (attributeName.startsWith("supports_"))
20400
- Object.assign(normalized, {
20401
- [attributeName]: normalized[attributeName] ?? false
20402
- });
20403
- }
20404
- }
20405
- for (const attributeName of Object.keys(
20406
- normalized
20407
- )) {
20408
- const declaredValue = normalized[attributeName];
20409
- const supportedAttributeName = attributeName.startsWith(
20410
- "is_configured_for_"
20411
- ) ? attributeName.replace("is_configured_for_", "supports_") : attributeName.startsWith("is_using_") ? attributeName.replace("is_using_", "can_use_") : void 0;
20412
- if (supportedAttributeName) {
20413
- if (declaredValue === true && imported[supportedAttributeName] === false)
20414
- mismatches.push(
20415
- `${propName}: ${JSON.stringify(declared[propName])}, fetched ${supportedAttributeName}: false`
20416
- );
20417
- continue;
20418
- }
20419
- const importedValue = imported[attributeName];
20420
- const valuesMatch = typeof importedValue === "number" && typeof declaredValue === "number" ? Math.abs(importedValue - declaredValue) <= Number.EPSILON * 8 * Math.max(1, Math.abs(importedValue), Math.abs(declaredValue)) : importedValue === declaredValue;
20421
- if (importedValue !== void 0 && declaredValue !== void 0 && !valuesMatch)
20422
- mismatches.push(
20423
- `${propName}: ${JSON.stringify(declared[propName])}, fetched ${attributeName}: ${JSON.stringify(importedValue)}`
20424
- );
20425
- }
20426
- }
20427
- return mismatches;
20428
- };
20429
-
20430
- // lib/components/normal-components/Chip_fetchPinAttributesForValidation.ts
20431
- import {
20432
- resolveManufacturerPartNumber as resolveManufacturerPartNumber4,
20433
- supplierProps as supplierProps4
20434
- } from "@tscircuit/props";
20435
- import { source_pin_attributes as source_pin_attributes2 } from "circuit-json";
20436
- var Chip_fetchPinAttributesForValidation = (chip) => {
20437
- if (chip.config.componentName !== "Chip") return;
20438
- if (chip._hasStartedPinAttributesFetch) return;
20439
- if (!Object.keys(chip._parsedProps.pinAttributes ?? {}).length) return;
20440
- if (chip.getInheritedProperty("partsEngineDisabled")) return;
20441
- if (chip.getInheritedProperty("bomDisabled")) return;
20442
- if (chip._importedSourcePorts.some(
20443
- (port) => Object.values(source_pin_attributes2.parse(port)).some(
20444
- (value) => value !== void 0
20445
- )
20446
- ))
20447
- return;
20448
- const partsEngine = chip.getInheritedProperty("partsEngine");
20449
- if (!partsEngine?.fetchPartCircuitJson) return;
20450
- const footprint = chip.resolveFootprint();
20451
- if (supplierProps4.shape.supplierPartNumbers.unwrap().keySchema.options.some(
20452
- (supplierName) => typeof chip.root?.platform?.footprintLibraryMap?.[supplierName] !== "function" && chip._parsedProps.supplierPartNumbers?.[supplierName]?.some(
20453
- (partNumber) => footprint === `${supplierName}:${partNumber}`
20454
- )
20455
- ))
20456
- return;
20457
- const supplierPartNumber = Object.values(
20458
- chip._parsedProps.supplierPartNumbers ?? {}
20459
- ).flat()[0];
20460
- const manufacturerPartNumber = resolveManufacturerPartNumber4(
20461
- chip._parsedProps
20462
- );
20463
- if (!supplierPartNumber && !manufacturerPartNumber) return;
20464
- chip._hasStartedPinAttributesFetch = true;
20465
- chip._queueAsyncEffect("fetch-chip-pin-metadata", async () => {
20466
- try {
20467
- const partCircuitJson = await fetchPartCircuitJsonWithDatasheet(
20468
- {
20469
- fetchPartCircuitJson: partsEngine.fetchPartCircuitJson,
20470
- supplierPartNumber,
20471
- manufacturerPartNumber
20472
- },
20473
- chip
20474
- );
20475
- chip._fetchedSourcePortsForPinAttributes = partCircuitJson?.filter((element) => element.type === "source_port") ?? [];
20476
- chip._markDirty("SourceDesignRuleChecks");
20477
- } catch {
20478
- }
20479
- });
20480
- };
20481
-
20482
- // lib/components/normal-components/Chip_doInitialSourcePinSpecificationChecks.ts
20483
- var Chip_doInitialSourcePinSpecificationChecks = (chip) => {
20484
- if (chip.config.componentName !== "Chip") return;
20485
- if (!chip.source_component_id) return;
20486
- const { db: db2 } = chip.root;
20487
- const existingWarning = db2.source_component_pins_underspecified_warning.getWhere({
20488
- source_component_id: chip.source_component_id
20489
- });
20490
- const drcChecksDisabled = chip.root?.platform?.drcChecksDisabled ?? chip.getInheritedProperty("drcChecksDisabled");
20491
- const pinSpecificationDrcChecksDisabled = chip.root?.platform?.pinSpecificationDrcChecksDisabled ?? chip.getInheritedProperty("pinSpecificationDrcChecksDisabled");
20492
- const checksDisabled = drcChecksDisabled || pinSpecificationDrcChecksDisabled;
20493
- if (!checksDisabled) Chip_fetchPinAttributesForValidation(chip);
20494
- const sourcePorts = checksDisabled ? [] : chip.selectAll("port").flatMap((port) => {
20495
- if (!port.source_port_id) return [];
20496
- const sourcePort = db2.source_port.get(port.source_port_id);
20497
- return sourcePort?.source_component_id === chip.source_component_id ? [sourcePort] : [];
20498
- });
20499
- const sourceComponent = checksDisabled ? null : db2.source_component.get(chip.source_component_id);
20500
- const chipCircuitJson = sourceComponent ? [sourceComponent, ...sourcePorts] : [];
20501
- const issues = [];
20502
- if (!checksDisabled) {
20503
- for (const port of chip.selectAll("port")) {
20504
- const sourcePort = sourcePorts.find(
20505
- (sourcePort2) => sourcePort2.source_port_id === port.source_port_id
20506
- );
20507
- if (!sourcePort) continue;
20508
- const declared = {};
20509
- for (const alias of port.getNameAndAliases()) {
20510
- Object.assign(declared, chip._parsedProps.pinAttributes?.[alias]);
20511
- }
20512
- const imported = getImportedSourcePinAttributes(
20513
- port,
20514
- chip._fetchedSourcePortsForPinAttributes.length ? chip._fetchedSourcePortsForPinAttributes : chip._importedSourcePorts
20515
- );
20516
- const reasons2 = getPinAttributeMismatches(declared, imported);
20517
- if (reasons2.length)
20518
- issues.push({
20519
- pinName: sourcePort.name || "unnamed pin",
20520
- reasons: reasons2,
20521
- sourcePort
20522
- });
20523
- }
20524
- }
20525
- for (const [warningTable, check] of [
20526
- [db2.source_no_power_pin_defined_warning, checkNoPowerPinDefined],
20527
- [db2.source_no_ground_pin_defined_warning, checkNoGroundPinDefined]
20528
- ]) {
20529
- const existing = warningTable.getWhere({
20530
- source_component_id: chip.source_component_id
20531
- });
20532
- const existingId = existing?.type === "source_no_power_pin_defined_warning" ? existing.source_no_power_pin_defined_warning_id : existing?.source_no_ground_pin_defined_warning_id;
20533
- const [warning2] = checksDisabled || issues.length ? [] : check(chipCircuitJson);
20534
- if (warning2) {
20535
- if (existingId) {
20536
- warningTable.update(existingId, {
20537
- message: warning2.message,
20538
- source_port_ids: warning2.source_port_ids,
20539
- subcircuit_id: warning2.subcircuit_id
20540
- });
20541
- } else {
20542
- db2.insertAll([warning2]);
20543
- }
20544
- } else if (existingId) {
20545
- warningTable.delete(existingId);
20546
- }
20547
- }
20548
- const [underspecifiedWarning] = checksDisabled ? [] : checkAllPinsInComponentAreUnderspecified(chipCircuitJson);
20549
- if (!issues.length && !underspecifiedWarning) {
20550
- if (existingWarning) {
20551
- db2.source_component_pins_underspecified_warning.delete(
20552
- existingWarning.source_component_pins_underspecified_warning_id
20553
- );
20554
- }
20555
- return;
20556
- }
20557
- const examples = issues.slice(0, 3).map(({ pinName, reasons: reasons2 }) => `${pinName} (${reasons2.join("; ")})`).join(", ");
20558
- const remaining = issues.length > 3 ? `, and ${issues.length - 3} more` : "";
20559
- const warning = {
20560
- source_component_id: chip.source_component_id,
20561
- source_port_ids: issues.length ? issues.map(({ sourcePort }) => sourcePort.source_port_id) : underspecifiedWarning.source_port_ids,
20562
- subcircuit_id: chip.getSubcircuit().subcircuit_id ?? void 0,
20563
- warning_type: "source_component_pins_underspecified_warning",
20564
- message: issues.length ? `Chip ${chip.name || "unnamed chip"} has pinAttributes that conflict with fetched pin metadata on ${issues.length} pin${issues.length === 1 ? "" : "s"}: ${examples}${remaining}. Check the chip configuration against the part datasheet.` : underspecifiedWarning.message
20565
- };
20566
- if (existingWarning) {
20567
- db2.source_component_pins_underspecified_warning.update(
20568
- existingWarning.source_component_pins_underspecified_warning_id,
20569
- warning
20570
- );
20571
- } else {
20572
- db2.source_component_pins_underspecified_warning.insert(warning);
20573
- }
20574
- };
20575
-
20576
20726
  // lib/components/normal-components/Chip.ts
20577
20727
  var Chip = class extends NormalComponent {
20578
- /** Fetched facts used only for comparison when the user supplies a custom footprint. */
20579
- _fetchedSourcePortsForPinAttributes = [];
20580
- _hasStartedPinAttributesFetch = false;
20581
20728
  get config() {
20582
20729
  return {
20583
20730
  componentName: "Chip",
@@ -20632,13 +20779,6 @@ var Chip = class extends NormalComponent {
20632
20779
  });
20633
20780
  this.source_component_id = source_component.source_component_id;
20634
20781
  }
20635
- doInitialSourceDesignRuleChecks() {
20636
- super.doInitialSourceDesignRuleChecks();
20637
- Chip_doInitialSourcePinSpecificationChecks(this);
20638
- }
20639
- updateSourceDesignRuleChecks() {
20640
- Chip_doInitialSourcePinSpecificationChecks(this);
20641
- }
20642
20782
  doInitialPcbComponentRender() {
20643
20783
  if (this.root?.pcbDisabled) return;
20644
20784
  const { db: db2 } = this.root;
@@ -119121,7 +119261,7 @@ var RoutingPhasePreparationError = class extends Error {
119121
119261
  var package_default = {
119122
119262
  name: "@tscircuit/core",
119123
119263
  type: "module",
119124
- version: "0.0.2162",
119264
+ version: "0.0.2163",
119125
119265
  types: "dist/index.d.ts",
119126
119266
  main: "dist/index.js",
119127
119267
  module: "dist/index.js",
@@ -121814,6 +121954,9 @@ var Group5 = class extends NormalComponent {
121814
121954
  const debug13 = Debug15("tscircuit:core:updatePcbTraceRender");
121815
121955
  debug13(`[${this.getString()}] updating...`);
121816
121956
  if (!this.isSubcircuit) return;
121957
+ if (this.root?.pcbDisabled) return;
121958
+ if (this.root?.pcbRoutingDisabled || this.getInheritedProperty("routingDisabled"))
121959
+ return;
121817
121960
  if (this._isInflatedFromCircuitJson) return;
121818
121961
  if (this._isLegacyAutorouterDisabled()) return;
121819
121962
  if (this._shouldRouteAsync() && this._hasTracesToRoute() && !this._hasStartedAsyncAutorouting) {