@tscircuit/core 0.0.1350 → 0.0.1352

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/index.js +208 -71
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -19796,6 +19796,111 @@ function computeJunctions(traces, opts = {}) {
19796
19796
  return result;
19797
19797
  }
19798
19798
 
19799
+ // lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/remove-overlapping-same-net-crossing-segments.ts
19800
+ var TOL3 = 1e-6;
19801
+ function isCollinear(a, b, tol = TOL3) {
19802
+ const adx = a.to.x - a.from.x;
19803
+ const ady = a.to.y - a.from.y;
19804
+ const bdx = b.to.x - b.from.x;
19805
+ const bdy = b.to.y - b.from.y;
19806
+ const aLen = Math.hypot(adx, ady);
19807
+ const bLen = Math.hypot(bdx, bdy);
19808
+ if (aLen <= tol || bLen <= tol) return false;
19809
+ const directionCross = adx * bdy - ady * bdx;
19810
+ if (Math.abs(directionCross) > tol * aLen * bLen) return false;
19811
+ const offsetCross = adx * (b.from.y - a.from.y) - ady * (b.from.x - a.from.x);
19812
+ return Math.abs(offsetCross) <= tol * aLen;
19813
+ }
19814
+ function splitEdgeAroundIntervals(edge, intervals) {
19815
+ const merged = mergeIntervals(intervals);
19816
+ if (merged.length === 0) return [edge];
19817
+ const edgeLength = length6(edge.from, edge.to);
19818
+ if (edgeLength <= TOL3) return [edge];
19819
+ const result = [];
19820
+ let cursor = 0;
19821
+ for (const interval of merged) {
19822
+ if (interval.start - cursor > TOL3) {
19823
+ result.push({
19824
+ from: pointAt(edge.from, edge.to, cursor / edgeLength),
19825
+ to: pointAt(edge.from, edge.to, interval.start / edgeLength)
19826
+ });
19827
+ }
19828
+ if (interval.end - interval.start > TOL3) {
19829
+ result.push({
19830
+ from: pointAt(edge.from, edge.to, interval.start / edgeLength),
19831
+ to: pointAt(edge.from, edge.to, interval.end / edgeLength),
19832
+ is_crossing: true
19833
+ });
19834
+ }
19835
+ cursor = Math.max(cursor, interval.end);
19836
+ }
19837
+ if (edgeLength - cursor > TOL3) {
19838
+ result.push({
19839
+ from: pointAt(edge.from, edge.to, cursor / edgeLength),
19840
+ to: edge.to
19841
+ });
19842
+ }
19843
+ return result;
19844
+ }
19845
+ function removeOverlappingSameNetCrossingSegments(traces) {
19846
+ const intervalsToRemove = /* @__PURE__ */ new Map();
19847
+ for (let crossingTraceIndex = 0; crossingTraceIndex < traces.length; crossingTraceIndex++) {
19848
+ const crossingTrace = traces[crossingTraceIndex];
19849
+ if (!crossingTrace.connectivity_key) continue;
19850
+ for (const crossingEdge of crossingTrace.edges) {
19851
+ if (!crossingEdge.is_crossing || length6(crossingEdge.from, crossingEdge.to) <= TOL3)
19852
+ continue;
19853
+ for (let traceIndex = 0; traceIndex < traces.length; traceIndex++) {
19854
+ const candidateTrace = traces[traceIndex];
19855
+ if (traceIndex === crossingTraceIndex || candidateTrace.connectivity_key !== crossingTrace.connectivity_key) {
19856
+ continue;
19857
+ }
19858
+ for (let edgeIndex = 0; edgeIndex < candidateTrace.edges.length; edgeIndex++) {
19859
+ const candidateEdge = candidateTrace.edges[edgeIndex];
19860
+ const candidateLength = length6(candidateEdge.from, candidateEdge.to);
19861
+ if (candidateEdge.is_crossing || candidateLength <= TOL3) continue;
19862
+ if (!isCollinear(candidateEdge, crossingEdge)) continue;
19863
+ const start = Math.max(
19864
+ 0,
19865
+ Math.min(
19866
+ paramAlong(
19867
+ candidateEdge.from,
19868
+ candidateEdge.to,
19869
+ crossingEdge.from
19870
+ ),
19871
+ paramAlong(candidateEdge.from, candidateEdge.to, crossingEdge.to)
19872
+ )
19873
+ );
19874
+ const end = Math.min(
19875
+ candidateLength,
19876
+ Math.max(
19877
+ paramAlong(
19878
+ candidateEdge.from,
19879
+ candidateEdge.to,
19880
+ crossingEdge.from
19881
+ ),
19882
+ paramAlong(candidateEdge.from, candidateEdge.to, crossingEdge.to)
19883
+ )
19884
+ );
19885
+ if (end - start <= TOL3) continue;
19886
+ const key = `${traceIndex}:${edgeIndex}`;
19887
+ const intervals = intervalsToRemove.get(key) ?? [];
19888
+ intervals.push({ start, end });
19889
+ intervalsToRemove.set(key, intervals);
19890
+ }
19891
+ }
19892
+ }
19893
+ }
19894
+ if (intervalsToRemove.size === 0) return traces;
19895
+ return traces.map((trace, traceIndex) => ({
19896
+ ...trace,
19897
+ edges: trace.edges.flatMap((edge, edgeIndex) => {
19898
+ const intervals = intervalsToRemove.get(`${traceIndex}:${edgeIndex}`);
19899
+ return intervals ? splitEdgeAroundIntervals(edge, intervals) : [edge];
19900
+ })
19901
+ }));
19902
+ }
19903
+
19799
19904
  // lib/components/primitive-components/Group/Group_doInitialSchematicTraceRender/applyTracesFromSolverOutput.ts
19800
19905
  import Debug10 from "debug";
19801
19906
  var debug8 = Debug10("Group_doInitialSchematicTraceRender");
@@ -19950,19 +20055,37 @@ function applyTracesFromSolverOutput(args) {
19950
20055
  );
19951
20056
  const existingTracesForJunctions = [];
19952
20057
  for (const t of db.schematic_trace.list()) {
19953
- if (!t.source_trace_id || t.edges.length === 0) continue;
19954
- const sourceTrace = db.source_trace.get(t.source_trace_id);
20058
+ if (t.edges.length === 0) continue;
20059
+ const sourceTrace = t.source_trace_id ? db.source_trace.get(t.source_trace_id) : void 0;
19955
20060
  existingTracesForJunctions.push({
19956
- source_trace_id: t.source_trace_id,
20061
+ schematic_trace_id: t.schematic_trace_id,
20062
+ source_trace_id: t.source_trace_id ?? t.schematic_trace_id,
19957
20063
  edges: t.edges,
19958
20064
  connectivity_key: t.subcircuit_connectivity_map_key ?? sourceTrace?.subcircuit_connectivity_map_key
19959
20065
  });
19960
20066
  }
19961
- const junctionsById = computeJunctions([
20067
+ const tracesWithTrimmedCrossingOverlaps = removeOverlappingSameNetCrossingSegments([
19962
20068
  ...withCrossings,
19963
20069
  ...existingTracesForJunctions
19964
20070
  ]);
19965
- for (const t of withCrossings) {
20071
+ const visibleTraces = tracesWithTrimmedCrossingOverlaps.slice(
20072
+ 0,
20073
+ withCrossings.length
20074
+ );
20075
+ const visibleExistingTraces = tracesWithTrimmedCrossingOverlaps.slice(
20076
+ withCrossings.length
20077
+ );
20078
+ for (const trace of visibleExistingTraces) {
20079
+ if (!trace.schematic_trace_id) continue;
20080
+ db.schematic_trace.update(trace.schematic_trace_id, {
20081
+ edges: trace.edges
20082
+ });
20083
+ }
20084
+ const junctionsById = computeJunctions([
20085
+ ...visibleTraces,
20086
+ ...visibleExistingTraces
20087
+ ]);
20088
+ for (const t of visibleTraces) {
19966
20089
  db.schematic_trace.insert({
19967
20090
  source_trace_id: t.source_trace_id,
19968
20091
  edges: t.edges,
@@ -20427,24 +20550,19 @@ var Group_doInitialSchematicTraceRender = (group) => {
20427
20550
  import { circuitJsonToSpice } from "circuit-json-to-spice";
20428
20551
  import Debug13 from "debug";
20429
20552
 
20430
- // lib/spice/get-spicey-engine.ts
20431
- import { simulate, spiceyTranToVGraphs } from "spicey";
20432
- var getSpiceyEngine = () => {
20433
- return {
20434
- async simulate(spiceString) {
20435
- const simulation_experiment_id = "spice-experiment-1";
20436
- const { circuit: parsedCircuit, tran } = simulate(spiceString);
20437
- const voltageGraphs = spiceyTranToVGraphs(
20438
- tran,
20439
- parsedCircuit,
20440
- simulation_experiment_id
20441
- );
20442
- return {
20443
- simulationResultCircuitJson: voltageGraphs
20444
- };
20553
+ // lib/utils/simulation/get-transient-voltage-graph-names-from-spice-netlist.ts
20554
+ function getTransientVoltageGraphNamesFromSpiceNetlist(spiceNetlist) {
20555
+ const graphNames = [];
20556
+ for (const printStatement of spiceNetlist.printStatements) {
20557
+ const match = printStatement.match(/^\.PRINT\s+TRAN\s+(.+)$/i);
20558
+ if (!match) continue;
20559
+ for (const voltageExpression of match[1].match(/V\(([^)]+)\)/g) ?? []) {
20560
+ const nodeList = voltageExpression.slice(2, -1);
20561
+ graphNames.push(nodeList.replace(",", "-"));
20445
20562
  }
20446
- };
20447
- };
20563
+ }
20564
+ return graphNames;
20565
+ }
20448
20566
 
20449
20567
  // lib/utils/simulation/getSimulationColorForId.ts
20450
20568
  var SIMULATION_COLOR_PALETTE = [
@@ -20483,19 +20601,24 @@ function resetSimulationColorState() {
20483
20601
  colorIndex = 0;
20484
20602
  }
20485
20603
 
20486
- // lib/utils/simulation/get-transient-voltage-graph-names-from-spice-netlist.ts
20487
- function getTransientVoltageGraphNamesFromSpiceNetlist(spiceNetlist) {
20488
- const graphNames = [];
20489
- for (const printStatement of spiceNetlist.printStatements) {
20490
- const match = printStatement.match(/^\.PRINT\s+TRAN\s+(.+)$/i);
20491
- if (!match) continue;
20492
- for (const voltageExpression of match[1].match(/V\(([^)]+)\)/g) ?? []) {
20493
- const nodeList = voltageExpression.slice(2, -1);
20494
- graphNames.push(nodeList.replace(",", "-"));
20604
+ // lib/spice/get-spicey-engine.ts
20605
+ import { simulate, spiceyTranToVGraphs } from "spicey";
20606
+ var getSpiceyEngine = () => {
20607
+ return {
20608
+ async simulate(spiceString) {
20609
+ const simulation_experiment_id = "spice-experiment-1";
20610
+ const { circuit: parsedCircuit, tran } = simulate(spiceString);
20611
+ const voltageGraphs = spiceyTranToVGraphs(
20612
+ tran,
20613
+ parsedCircuit,
20614
+ simulation_experiment_id
20615
+ );
20616
+ return {
20617
+ simulationResultCircuitJson: voltageGraphs
20618
+ };
20495
20619
  }
20496
- }
20497
- return graphNames;
20498
- }
20620
+ };
20621
+ };
20499
20622
 
20500
20623
  // lib/components/primitive-components/Group/Group_doInitialSimulationSpiceEngineRender.ts
20501
20624
  var debug11 = Debug13("tscircuit:core:Group_doInitialSimulationSpiceEngineRender");
@@ -20535,6 +20658,9 @@ ${spiceString}`);
20535
20658
  const currentProbesById = new Map(
20536
20659
  root.db.simulation_current_probe.list().map((probe) => [probe.simulation_current_probe_id, probe])
20537
20660
  );
20661
+ const currentProbesByName = new Map(
20662
+ root.db.simulation_current_probe.list().filter((probe) => probe.name).map((probe) => [probe.name, probe])
20663
+ );
20538
20664
  const orderedSimulationProbes = root.db.simulation_voltage_probe.list().filter((probe) => voltageProbesById.has(probe.simulation_voltage_probe_id));
20539
20665
  const graphNamesFromNetlist = getTransientVoltageGraphNamesFromSpiceNetlist(spiceNetlist);
20540
20666
  if (graphNamesFromNetlist.length === orderedSimulationProbes.length) {
@@ -20582,12 +20708,18 @@ ${spiceString}`);
20582
20708
  if (element.type === "simulation_transient_voltage_graph") {
20583
20709
  element.simulation_experiment_id = simulationExperiment.simulation_experiment_id;
20584
20710
  const probeMatch = element.name ? graphNameToProbe.get(element.name) : void 0;
20585
- if (probeMatch) element.color = probeMatch.color;
20711
+ if (probeMatch) {
20712
+ element.color = probeMatch.color;
20713
+ element.source_probe_id = probeMatch.simulation_voltage_probe_id;
20714
+ }
20586
20715
  }
20587
20716
  if (element.type === "simulation_transient_current_graph") {
20588
20717
  element.simulation_experiment_id = simulationExperiment.simulation_experiment_id;
20589
- const probeMatch = element.source_probe_id ? currentProbesById.get(element.source_probe_id) : void 0;
20590
- if (probeMatch) element.color = probeMatch.color;
20718
+ const probeMatch = (element.source_probe_id ? currentProbesById.get(element.source_probe_id) : void 0) ?? (element.name ? currentProbesByName.get(element.name) : void 0);
20719
+ if (probeMatch) {
20720
+ element.color = probeMatch.color;
20721
+ element.source_probe_id = probeMatch.simulation_current_probe_id;
20722
+ }
20591
20723
  }
20592
20724
  const elementType = element.type;
20593
20725
  if (elementType && root.db[elementType]) {
@@ -24065,7 +24197,7 @@ import { identity as identity5 } from "transformation-matrix";
24065
24197
  var package_default = {
24066
24198
  name: "@tscircuit/core",
24067
24199
  type: "module",
24068
- version: "0.0.1349",
24200
+ version: "0.0.1351",
24069
24201
  types: "dist/index.d.ts",
24070
24202
  main: "dist/index.js",
24071
24203
  module: "dist/index.js",
@@ -24128,13 +24260,13 @@ var package_default = {
24128
24260
  "bun-match-svg": "0.0.12",
24129
24261
  "calculate-elbow": "^0.0.12",
24130
24262
  "chokidar-cli": "^3.0.0",
24131
- "circuit-json": "^0.0.437",
24263
+ "circuit-json": "^0.0.438",
24132
24264
  "circuit-json-to-bpc": "^0.0.13",
24133
24265
  "circuit-json-to-connectivity-map": "^0.0.23",
24134
24266
  "circuit-json-to-gltf": "^0.0.105",
24135
24267
  "circuit-json-to-simple-3d": "^0.0.9",
24136
24268
  "circuit-json-to-spice": "^0.0.39",
24137
- "circuit-to-svg": "^0.0.358",
24269
+ "circuit-to-svg": "^0.0.360",
24138
24270
  concurrently: "^9.1.2",
24139
24271
  "connectivity-map": "^1.0.0",
24140
24272
  debug: "^4.3.6",
@@ -26799,36 +26931,39 @@ var Ammeter = class extends NormalComponent3 {
26799
26931
  }
26800
26932
  doInitialSourceRender() {
26801
26933
  const { db } = this.root;
26802
- const { _parsedProps: props } = this;
26934
+ const { supplierPartNumbers, displayName, color, display } = this._parsedProps;
26803
26935
  const source_component = db.source_component.insert({
26804
26936
  ftype: "simple_ammeter",
26805
26937
  name: this.name,
26806
- supplier_part_numbers: props.supplierPartNumbers,
26807
- display_name: props.displayName
26938
+ supplier_part_numbers: supplierPartNumbers,
26939
+ display_name: displayName
26808
26940
  });
26809
26941
  this.source_component_id = source_component.source_component_id;
26810
26942
  }
26811
26943
  doInitialSimulationRender() {
26812
26944
  const { db } = this.root;
26813
- const { _parsedProps: props } = this;
26945
+ const { color, display } = this._parsedProps;
26814
26946
  const posPort = this.portMap.pos;
26815
26947
  const negPort = this.portMap.neg;
26816
- const displayOptions = props.display;
26817
- db.simulation_current_probe.insert({
26948
+ const { simulation_current_probe_id } = db.simulation_current_probe.insert({
26818
26949
  type: "simulation_current_probe",
26819
26950
  name: this.name,
26820
26951
  source_component_id: this.source_component_id,
26821
26952
  positive_source_port_id: posPort.source_port_id,
26822
26953
  negative_source_port_id: negPort.source_port_id,
26823
26954
  subcircuit_id: this.getSubcircuit()?.subcircuit_id ?? void 0,
26824
- color: props.color,
26825
- display_options: displayOptions ? {
26826
- label: displayOptions.label,
26827
- center: displayOptions.center,
26828
- offset_divs: displayOptions.offsetDivs,
26829
- units_per_div: displayOptions.unitsPerDiv
26830
- } : void 0
26831
- });
26955
+ color
26956
+ });
26957
+ if (display) {
26958
+ db.simulation_oscilloscope_trace.insert({
26959
+ simulation_current_probe_id,
26960
+ display_name: display.label,
26961
+ color,
26962
+ display_center_value: display.center,
26963
+ display_center_offset_divs: display.offsetDivs,
26964
+ amps_per_div: display.unitsPerDiv
26965
+ });
26966
+ }
26832
26967
  }
26833
26968
  pos = this.portMap.pos;
26834
26969
  neg = this.portMap.neg;
@@ -30330,7 +30465,7 @@ var SchematicSection = class _SchematicSection extends PrimitiveComponent2 {
30330
30465
  const PADDING = 0.5;
30331
30466
  const LABEL_PADDING = 0.2;
30332
30467
  const STROKE_WIDTH = 0.02;
30333
- const TOL3 = 1e-3;
30468
+ const TOL4 = 1e-3;
30334
30469
  const namedSectionsWithBounds = allSections.map((section) => {
30335
30470
  const bounds = section._computeSectionBounds(
30336
30471
  board,
@@ -30387,10 +30522,10 @@ var SchematicSection = class _SchematicSection extends PrimitiveComponent2 {
30387
30522
  });
30388
30523
  }
30389
30524
  const hDividers = dividers.filter(
30390
- (l) => Math.abs(l.start.y - l.end.y) < TOL3
30525
+ (l) => Math.abs(l.start.y - l.end.y) < TOL4
30391
30526
  );
30392
30527
  const vDividers = dividers.filter(
30393
- (l) => Math.abs(l.start.x - l.end.x) < TOL3
30528
+ (l) => Math.abs(l.start.x - l.end.x) < TOL4
30394
30529
  );
30395
30530
  for (const {
30396
30531
  displayName,
@@ -30573,9 +30708,7 @@ var SchematicCell = class extends PrimitiveComponent2 {
30573
30708
  };
30574
30709
 
30575
30710
  // lib/components/primitive-components/AnalogSimulation.ts
30576
- import {
30577
- analogSimulationProps
30578
- } from "@tscircuit/props";
30711
+ import { analogSimulationProps } from "@tscircuit/props";
30579
30712
  var AnalogSimulation = class extends PrimitiveComponent2 {
30580
30713
  get config() {
30581
30714
  return {
@@ -30585,11 +30718,11 @@ var AnalogSimulation = class extends PrimitiveComponent2 {
30585
30718
  }
30586
30719
  doInitialSimulationRender() {
30587
30720
  const { db } = this.root;
30588
- const { duration, startTime, timePerStep, spiceOptions } = this._parsedProps;
30721
+ const { duration, name, startTime, timePerStep, spiceOptions } = this._parsedProps;
30589
30722
  const durationMs = duration || 10;
30590
30723
  const timePerStepMs = timePerStep || 0.01;
30591
30724
  db.simulation_experiment.insert({
30592
- name: "spice_transient_analysis",
30725
+ name: name ?? "spice_transient_analysis",
30593
30726
  experiment_type: "spice_transient_analysis",
30594
30727
  end_time_ms: durationMs,
30595
30728
  start_time_ms: startTime,
@@ -30601,7 +30734,6 @@ var AnalogSimulation = class extends PrimitiveComponent2 {
30601
30734
 
30602
30735
  // lib/components/primitive-components/VoltageProbe.ts
30603
30736
  import { voltageProbeProps } from "@tscircuit/props";
30604
- import "zod";
30605
30737
 
30606
30738
  // lib/utils/schematic/selectBestLabelAlignment.ts
30607
30739
  import { doBoundsOverlap as doBoundsOverlap2 } from "@tscircuit/math-utils";
@@ -30723,6 +30855,7 @@ function selectBestLabelAlignment({
30723
30855
  }
30724
30856
 
30725
30857
  // lib/components/primitive-components/VoltageProbe.ts
30858
+ import "zod";
30726
30859
  var VoltageProbe = class extends PrimitiveComponent2 {
30727
30860
  simulation_voltage_probe_id = null;
30728
30861
  schematic_voltage_probe_id = null;
@@ -30766,7 +30899,7 @@ var VoltageProbe = class extends PrimitiveComponent2 {
30766
30899
  }
30767
30900
  const connectedId = port?.source_port_id ?? net?.source_net_id;
30768
30901
  if (!connectedId) {
30769
- this.renderError(`Could not identify connected source for VoltageProbe`);
30902
+ this.renderError("Could not identify connected source for VoltageProbe");
30770
30903
  return;
30771
30904
  }
30772
30905
  let referencePort = null;
@@ -30810,15 +30943,19 @@ var VoltageProbe = class extends PrimitiveComponent2 {
30810
30943
  reference_input_source_port_id: referencePort?.source_port_id ?? void 0,
30811
30944
  reference_input_source_net_id: referenceNet?.source_net_id ?? void 0,
30812
30945
  subcircuit_id: subcircuit.subcircuit_id || void 0,
30813
- color: this.color,
30814
- display_options: display ? {
30815
- label: display.label,
30816
- center: display.center,
30817
- offset_divs: display.offsetDivs,
30818
- units_per_div: display.unitsPerDiv
30819
- } : void 0
30946
+ color: this.color
30820
30947
  });
30821
30948
  this.simulation_voltage_probe_id = simulation_voltage_probe_id;
30949
+ if (display) {
30950
+ db.simulation_oscilloscope_trace.insert({
30951
+ simulation_voltage_probe_id,
30952
+ display_name: display.label,
30953
+ color: color ?? void 0,
30954
+ display_center_value: display.center,
30955
+ display_center_offset_divs: display.offsetDivs,
30956
+ volts_per_div: display.unitsPerDiv
30957
+ });
30958
+ }
30822
30959
  }
30823
30960
  doInitialSchematicReplaceNetLabelsWithSymbols() {
30824
30961
  if (this.root?.schematicDisabled) return;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tscircuit/core",
3
3
  "type": "module",
4
- "version": "0.0.1350",
4
+ "version": "0.0.1352",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -64,13 +64,13 @@
64
64
  "bun-match-svg": "0.0.12",
65
65
  "calculate-elbow": "^0.0.12",
66
66
  "chokidar-cli": "^3.0.0",
67
- "circuit-json": "^0.0.437",
67
+ "circuit-json": "^0.0.438",
68
68
  "circuit-json-to-bpc": "^0.0.13",
69
69
  "circuit-json-to-connectivity-map": "^0.0.23",
70
70
  "circuit-json-to-gltf": "^0.0.105",
71
71
  "circuit-json-to-simple-3d": "^0.0.9",
72
72
  "circuit-json-to-spice": "^0.0.39",
73
- "circuit-to-svg": "^0.0.358",
73
+ "circuit-to-svg": "^0.0.360",
74
74
  "concurrently": "^9.1.2",
75
75
  "connectivity-map": "^1.0.0",
76
76
  "debug": "^4.3.6",