@tscircuit/cli 0.1.220 → 0.1.222
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/README.md +1 -0
- package/dist/main.js +1097 -303
- package/package.json +4 -3
package/dist/main.js
CHANGED
|
@@ -58032,7 +58032,39 @@ var require_dist7 = __commonJS((exports2, module2) => {
|
|
|
58032
58032
|
return figureOutCommandPath(program3, commandPath.concat([nextCommandName]));
|
|
58033
58033
|
});
|
|
58034
58034
|
var import_prompts22 = __toESM3(require_prompts3());
|
|
58035
|
-
var
|
|
58035
|
+
var camelToKebab = (str) => str.replace(/([A-Z])/g, "-$1").toLowerCase().replace(/^-/, "");
|
|
58036
|
+
var findOptionByKey = (command, key) => {
|
|
58037
|
+
var _a;
|
|
58038
|
+
return (_a = command == null ? undefined : command.options) == null ? undefined : _a.find((o) => {
|
|
58039
|
+
var _a2, _b;
|
|
58040
|
+
const longFlag = (_a2 = o.long) == null ? undefined : _a2.replace(/^--/, "");
|
|
58041
|
+
const shortFlag = (_b = o.short) == null ? undefined : _b.replace(/^-/, "");
|
|
58042
|
+
if (longFlag === key || shortFlag === key) {
|
|
58043
|
+
return true;
|
|
58044
|
+
}
|
|
58045
|
+
if (longFlag === camelToKebab(key)) {
|
|
58046
|
+
return true;
|
|
58047
|
+
}
|
|
58048
|
+
return false;
|
|
58049
|
+
});
|
|
58050
|
+
};
|
|
58051
|
+
var getOptionFlagName = (command, key) => {
|
|
58052
|
+
var _a, _b;
|
|
58053
|
+
const option = findOptionByKey(command, key);
|
|
58054
|
+
if (option) {
|
|
58055
|
+
return ((_a = option.long) == null ? undefined : _a.replace(/^--/, "")) || ((_b = option.short) == null ? undefined : _b.replace(/^-/, "")) || "";
|
|
58056
|
+
}
|
|
58057
|
+
return camelToKebab(key);
|
|
58058
|
+
};
|
|
58059
|
+
var stringifyOptions = (options, command) => Object.entries(options).filter((opt) => opt[0] !== "_").map(([key, value]) => {
|
|
58060
|
+
var _a;
|
|
58061
|
+
const option = findOptionByKey(command, key);
|
|
58062
|
+
const flagName = getOptionFlagName(command, key);
|
|
58063
|
+
if ((_a = option == null ? undefined : option.isBoolean) == null ? undefined : _a.call(option)) {
|
|
58064
|
+
return value ? `--${flagName}` : "";
|
|
58065
|
+
}
|
|
58066
|
+
return `--${flagName} ${value}`;
|
|
58067
|
+
}).filter(Boolean).join(" ");
|
|
58036
58068
|
var getOptionKey = (o) => {
|
|
58037
58069
|
var _a;
|
|
58038
58070
|
return ((_a = o.long) != null ? _a : o.short).replace(/^--/, "");
|
|
@@ -58057,8 +58089,8 @@ var require_dist7 = __commonJS((exports2, module2) => {
|
|
|
58057
58089
|
if (command.options.length === 0) {
|
|
58058
58090
|
return options;
|
|
58059
58091
|
}
|
|
58060
|
-
console.log(`> ${[program3.name(), ...commandPath].filter(Boolean).join(" ")} ${stringifyOptions(options)}`);
|
|
58061
|
-
const hasRequiredOptions = command.options.filter((o) => o.mandatory).every((o) =>
|
|
58092
|
+
console.log(`> ${[program3.name(), ...commandPath].filter(Boolean).join(" ")} ${stringifyOptions(options, command)}`);
|
|
58093
|
+
const hasRequiredOptions = command.options.filter((o) => o.mandatory).every((o) => (getOptionKey(o) in options));
|
|
58062
58094
|
const { optionToEdit } = yield (0, import_prompts22.default)({
|
|
58063
58095
|
type: "autocomplete",
|
|
58064
58096
|
name: "optionToEdit",
|
|
@@ -58077,7 +58109,7 @@ var require_dist7 = __commonJS((exports2, module2) => {
|
|
|
58077
58109
|
return {
|
|
58078
58110
|
title: `${o.long}${o.mandatory ? "*" : ""}`,
|
|
58079
58111
|
value: optionName,
|
|
58080
|
-
description:
|
|
58112
|
+
description: optionName in options ? `[${options[optionName]}]` : o.description
|
|
58081
58113
|
};
|
|
58082
58114
|
})
|
|
58083
58115
|
].filter((elm) => Boolean(elm))
|
|
@@ -58116,7 +58148,7 @@ var require_dist7 = __commonJS((exports2, module2) => {
|
|
|
58116
58148
|
var stringifyCommandWithOptions = (program3, commandPath, options) => {
|
|
58117
58149
|
var _a, _b;
|
|
58118
58150
|
const command = getCommandFromPath(program3, commandPath);
|
|
58119
|
-
return `${[program3.name(), ...commandPath].filter(Boolean).join(" ")}${((_a = options == null ? undefined : options._) == null ? undefined : _a.length) > 0 ? ` ${(_b = options == null ? undefined : options._) == null ? undefined : _b.join(" ")}` : ""} ${stringifyOptions(options)}`;
|
|
58151
|
+
return `${[program3.name(), ...commandPath].filter(Boolean).join(" ")}${((_a = options == null ? undefined : options._) == null ? undefined : _a.length) > 0 ? ` ${(_b = options == null ? undefined : options._) == null ? undefined : _b.join(" ")}` : ""} ${stringifyOptions(options, command)}`;
|
|
58120
58152
|
};
|
|
58121
58153
|
var doesProgramHaveAllRequiredArgs = (program3, _, passedArgs) => {
|
|
58122
58154
|
const command = getCommandFromPath(program3, _);
|
|
@@ -58181,10 +58213,19 @@ var require_dist7 = __commonJS((exports2, module2) => {
|
|
|
58181
58213
|
const fullCommandString = stringifyCommandWithOptions(program3, commandPath, options);
|
|
58182
58214
|
console.log(`> ${fullCommandString}`);
|
|
58183
58215
|
const strictCommandPath = getStrictCommandPath(program3, commandPath);
|
|
58216
|
+
const optionArgs = Object.entries(options).filter((opt) => opt[0] !== "_").flatMap(([optKey, optVal]) => {
|
|
58217
|
+
var _a2;
|
|
58218
|
+
const option = findOptionByKey(command, optKey);
|
|
58219
|
+
const flagName = getOptionFlagName(command, optKey);
|
|
58220
|
+
if ((_a2 = option == null ? undefined : option.isBoolean) == null ? undefined : _a2.call(option)) {
|
|
58221
|
+
return optVal ? [`--${flagName}`] : [];
|
|
58222
|
+
}
|
|
58223
|
+
return [`--${flagName}`, optVal];
|
|
58224
|
+
});
|
|
58184
58225
|
yield program3.parseAsync([
|
|
58185
58226
|
...process.argv.slice(0, 2),
|
|
58186
58227
|
...strictCommandPath.concat((_b = options._) != null ? _b : []),
|
|
58187
|
-
...
|
|
58228
|
+
...optionArgs
|
|
58188
58229
|
]);
|
|
58189
58230
|
});
|
|
58190
58231
|
});
|
|
@@ -63215,7 +63256,7 @@ var getGlobalDepsInstallCommand = (packageManager, deps) => {
|
|
|
63215
63256
|
import { execSync as execSync2 } from "node:child_process";
|
|
63216
63257
|
var import_semver2 = __toESM2(require_semver2(), 1);
|
|
63217
63258
|
// package.json
|
|
63218
|
-
var version = "0.1.
|
|
63259
|
+
var version = "0.1.221";
|
|
63219
63260
|
var package_default = {
|
|
63220
63261
|
name: "@tscircuit/cli",
|
|
63221
63262
|
version,
|
|
@@ -63262,7 +63303,7 @@ var package_default = {
|
|
|
63262
63303
|
ky: "^1.7.4",
|
|
63263
63304
|
"looks-same": "^9.0.1",
|
|
63264
63305
|
"make-vfs": "^1.0.15",
|
|
63265
|
-
"perfect-cli": "^1.0.
|
|
63306
|
+
"perfect-cli": "^1.0.21",
|
|
63266
63307
|
prompts: "^2.4.2",
|
|
63267
63308
|
redaxios: "^0.5.1",
|
|
63268
63309
|
semver: "^7.6.3",
|
|
@@ -63271,7 +63312,8 @@ var package_default = {
|
|
|
63271
63312
|
tscircuit: "^0.0.650-libonly",
|
|
63272
63313
|
tsx: "^4.7.1",
|
|
63273
63314
|
"typed-ky": "^0.0.4",
|
|
63274
|
-
zod: "3"
|
|
63315
|
+
zod: "3",
|
|
63316
|
+
"circuit-json-to-spice": "^0.0.10"
|
|
63275
63317
|
},
|
|
63276
63318
|
peerDependencies: {
|
|
63277
63319
|
tscircuit: "*"
|
|
@@ -68241,25 +68283,6 @@ var registerClone = (program3) => {
|
|
|
68241
68283
|
throw new Error("No valid match found");
|
|
68242
68284
|
const [, author, packageName] = match;
|
|
68243
68285
|
console.log(`Cloning ${author}/${packageName}...`);
|
|
68244
|
-
const ky2 = getRegistryApiKy();
|
|
68245
|
-
let packageFileList = {
|
|
68246
|
-
package_files: []
|
|
68247
|
-
};
|
|
68248
|
-
try {
|
|
68249
|
-
packageFileList = await ky2.post("package_files/list", {
|
|
68250
|
-
json: {
|
|
68251
|
-
package_name: `${author}/${packageName}`,
|
|
68252
|
-
use_latest_version: true
|
|
68253
|
-
}
|
|
68254
|
-
}).json();
|
|
68255
|
-
} catch (error) {
|
|
68256
|
-
if (typeof error === "object" && error !== null && "response" in error && typeof error.response === "object" && error.response?.status === 404) {
|
|
68257
|
-
console.error(`Package "${author}/${packageName}" not found. Please check the name and try again.`);
|
|
68258
|
-
process.exit(1);
|
|
68259
|
-
}
|
|
68260
|
-
console.error("Failed to fetch package files:", error instanceof Error ? error.message : error);
|
|
68261
|
-
process.exit(1);
|
|
68262
|
-
}
|
|
68263
68286
|
const userSettingToIncludeAuthor = options.includeAuthor || cliConfig.get("alwaysCloneWithAuthorName");
|
|
68264
68287
|
const dirPath = userSettingToIncludeAuthor ? path20.resolve(`${author}.${packageName}`) : path20.resolve(packageName);
|
|
68265
68288
|
if (fs20.existsSync(dirPath)) {
|
|
@@ -68288,6 +68311,25 @@ var registerClone = (program3) => {
|
|
|
68288
68311
|
console.log(`Merging files into existing directory: ${dirPath}`);
|
|
68289
68312
|
}
|
|
68290
68313
|
}
|
|
68314
|
+
const ky2 = getRegistryApiKy();
|
|
68315
|
+
let packageFileList = {
|
|
68316
|
+
package_files: []
|
|
68317
|
+
};
|
|
68318
|
+
try {
|
|
68319
|
+
packageFileList = await ky2.post("package_files/list", {
|
|
68320
|
+
json: {
|
|
68321
|
+
package_name: `${author}/${packageName}`,
|
|
68322
|
+
use_latest_version: true
|
|
68323
|
+
}
|
|
68324
|
+
}).json();
|
|
68325
|
+
} catch (error) {
|
|
68326
|
+
if (typeof error === "object" && error !== null && "response" in error && typeof error.response === "object" && error.response?.status === 404) {
|
|
68327
|
+
console.error(`Package "${author}/${packageName}" not found. Please check the name and try again.`);
|
|
68328
|
+
process.exit(1);
|
|
68329
|
+
}
|
|
68330
|
+
console.error("Failed to fetch package files:", error instanceof Error ? error.message : error);
|
|
68331
|
+
process.exit(1);
|
|
68332
|
+
}
|
|
68291
68333
|
fs20.mkdirSync(dirPath, { recursive: true });
|
|
68292
68334
|
for (const fileInfo of packageFileList.package_files) {
|
|
68293
68335
|
const filePath = fileInfo.file_path.replace(/^\/|dist\//g, "");
|
|
@@ -71588,12 +71630,680 @@ var exportSnippet = async ({
|
|
|
71588
71630
|
});
|
|
71589
71631
|
};
|
|
71590
71632
|
|
|
71633
|
+
// node_modules/circuit-json-to-spice/dist/index.js
|
|
71634
|
+
import { getSourcePortConnectivityMapFromCircuitJson } from "circuit-json-to-connectivity-map";
|
|
71635
|
+
var convertSpiceNetlistToString = (netlist) => {
|
|
71636
|
+
const lines = [];
|
|
71637
|
+
lines.push(netlist.title);
|
|
71638
|
+
if (netlist.models.size > 0) {
|
|
71639
|
+
lines.push(...Array.from(netlist.models.values()));
|
|
71640
|
+
}
|
|
71641
|
+
for (const component of netlist.components) {
|
|
71642
|
+
lines.push(component.toSpiceString());
|
|
71643
|
+
}
|
|
71644
|
+
for (const subcircuit of netlist.subcircuits) {
|
|
71645
|
+
lines.push(subcircuit.toSpiceString());
|
|
71646
|
+
}
|
|
71647
|
+
if (netlist.controls.length > 0) {
|
|
71648
|
+
lines.push(".control");
|
|
71649
|
+
lines.push(...netlist.controls);
|
|
71650
|
+
lines.push(".endc");
|
|
71651
|
+
}
|
|
71652
|
+
lines.push(".END");
|
|
71653
|
+
return lines.join(`
|
|
71654
|
+
`);
|
|
71655
|
+
};
|
|
71656
|
+
var SpiceNetlist = class {
|
|
71657
|
+
title;
|
|
71658
|
+
components;
|
|
71659
|
+
nodes;
|
|
71660
|
+
controls;
|
|
71661
|
+
subcircuits;
|
|
71662
|
+
models;
|
|
71663
|
+
constructor(title = "Circuit Netlist") {
|
|
71664
|
+
this.title = title;
|
|
71665
|
+
this.components = [];
|
|
71666
|
+
this.nodes = /* @__PURE__ */ new Set;
|
|
71667
|
+
this.controls = [];
|
|
71668
|
+
this.subcircuits = [];
|
|
71669
|
+
this.models = /* @__PURE__ */ new Map;
|
|
71670
|
+
}
|
|
71671
|
+
addComponent(component) {
|
|
71672
|
+
this.components.push(component);
|
|
71673
|
+
for (const node of component.nodes) {
|
|
71674
|
+
this.nodes.add(node);
|
|
71675
|
+
}
|
|
71676
|
+
}
|
|
71677
|
+
addSubcircuit(subcircuit) {
|
|
71678
|
+
if (this.subcircuits.find((s) => s.name === subcircuit.name))
|
|
71679
|
+
return;
|
|
71680
|
+
this.subcircuits.push(subcircuit);
|
|
71681
|
+
}
|
|
71682
|
+
toSpiceString() {
|
|
71683
|
+
return convertSpiceNetlistToString(this);
|
|
71684
|
+
}
|
|
71685
|
+
};
|
|
71686
|
+
var SpiceComponent = class {
|
|
71687
|
+
name;
|
|
71688
|
+
command;
|
|
71689
|
+
nodes;
|
|
71690
|
+
constructor(name, command, nodes) {
|
|
71691
|
+
this.name = name;
|
|
71692
|
+
this.command = command;
|
|
71693
|
+
this.nodes = nodes;
|
|
71694
|
+
}
|
|
71695
|
+
toSpiceString() {
|
|
71696
|
+
return this.command.toSpiceString();
|
|
71697
|
+
}
|
|
71698
|
+
};
|
|
71699
|
+
var ResistorCommand = class {
|
|
71700
|
+
commandName = "resistor";
|
|
71701
|
+
props;
|
|
71702
|
+
constructor(props) {
|
|
71703
|
+
this.props = props;
|
|
71704
|
+
}
|
|
71705
|
+
toSpiceString() {
|
|
71706
|
+
const { name, positiveNode, negativeNode, model, value } = this.props;
|
|
71707
|
+
let spiceString = `R${name} ${positiveNode} ${negativeNode}`;
|
|
71708
|
+
if (model) {
|
|
71709
|
+
spiceString += ` ${model}`;
|
|
71710
|
+
}
|
|
71711
|
+
spiceString += ` ${value}`;
|
|
71712
|
+
return spiceString;
|
|
71713
|
+
}
|
|
71714
|
+
};
|
|
71715
|
+
var CapacitorCommand = class {
|
|
71716
|
+
commandName = "capacitor";
|
|
71717
|
+
props;
|
|
71718
|
+
constructor(props) {
|
|
71719
|
+
this.props = props;
|
|
71720
|
+
}
|
|
71721
|
+
toSpiceString() {
|
|
71722
|
+
const {
|
|
71723
|
+
name,
|
|
71724
|
+
positiveNode,
|
|
71725
|
+
negativeNode,
|
|
71726
|
+
modelName,
|
|
71727
|
+
value,
|
|
71728
|
+
initialCondition
|
|
71729
|
+
} = this.props;
|
|
71730
|
+
let spiceString = `C${name} ${positiveNode} ${negativeNode}`;
|
|
71731
|
+
if (modelName) {
|
|
71732
|
+
spiceString += ` ${modelName}`;
|
|
71733
|
+
}
|
|
71734
|
+
spiceString += ` ${value}`;
|
|
71735
|
+
if (initialCondition) {
|
|
71736
|
+
spiceString += ` IC=${initialCondition}`;
|
|
71737
|
+
}
|
|
71738
|
+
return spiceString;
|
|
71739
|
+
}
|
|
71740
|
+
};
|
|
71741
|
+
var VoltageSourceCommand = class {
|
|
71742
|
+
commandName = "voltage_source";
|
|
71743
|
+
props;
|
|
71744
|
+
constructor(props) {
|
|
71745
|
+
this.props = props;
|
|
71746
|
+
}
|
|
71747
|
+
toSpiceString() {
|
|
71748
|
+
const { name, positiveNode, negativeNode, value, acMagnitude, acPhase } = this.props;
|
|
71749
|
+
let spiceString = `V${name} ${positiveNode} ${negativeNode}`;
|
|
71750
|
+
if (value) {
|
|
71751
|
+
spiceString += ` ${value}`;
|
|
71752
|
+
}
|
|
71753
|
+
if (acMagnitude) {
|
|
71754
|
+
spiceString += ` AC ${acMagnitude}`;
|
|
71755
|
+
if (acPhase) {
|
|
71756
|
+
spiceString += ` ${acPhase}`;
|
|
71757
|
+
}
|
|
71758
|
+
}
|
|
71759
|
+
return spiceString;
|
|
71760
|
+
}
|
|
71761
|
+
};
|
|
71762
|
+
var DiodeCommand = class {
|
|
71763
|
+
commandName = "diode";
|
|
71764
|
+
props;
|
|
71765
|
+
constructor(props) {
|
|
71766
|
+
this.props = props;
|
|
71767
|
+
}
|
|
71768
|
+
toSpiceString() {
|
|
71769
|
+
const { name, positiveNode, negativeNode, model, area } = this.props;
|
|
71770
|
+
let spiceString = `D${name} ${positiveNode} ${negativeNode} ${model}`;
|
|
71771
|
+
if (area) {
|
|
71772
|
+
spiceString += ` ${area}`;
|
|
71773
|
+
}
|
|
71774
|
+
return spiceString;
|
|
71775
|
+
}
|
|
71776
|
+
};
|
|
71777
|
+
var InductorCommand = class {
|
|
71778
|
+
commandName = "inductor";
|
|
71779
|
+
props;
|
|
71780
|
+
constructor(props) {
|
|
71781
|
+
this.props = props;
|
|
71782
|
+
}
|
|
71783
|
+
toSpiceString() {
|
|
71784
|
+
const { name, positiveNode, negativeNode, model, value, initialCondition } = this.props;
|
|
71785
|
+
let spiceString = `L${name} ${positiveNode} ${negativeNode}`;
|
|
71786
|
+
if (model) {
|
|
71787
|
+
spiceString += ` ${model}`;
|
|
71788
|
+
}
|
|
71789
|
+
spiceString += ` ${value}`;
|
|
71790
|
+
if (initialCondition) {
|
|
71791
|
+
spiceString += ` IC=${initialCondition}`;
|
|
71792
|
+
}
|
|
71793
|
+
return spiceString;
|
|
71794
|
+
}
|
|
71795
|
+
};
|
|
71796
|
+
var VoltageControlledSwitchCommand = class {
|
|
71797
|
+
commandName = "voltage_controlled_switch";
|
|
71798
|
+
props;
|
|
71799
|
+
constructor(props) {
|
|
71800
|
+
this.props = props;
|
|
71801
|
+
}
|
|
71802
|
+
toSpiceString() {
|
|
71803
|
+
const {
|
|
71804
|
+
name,
|
|
71805
|
+
positiveNode,
|
|
71806
|
+
negativeNode,
|
|
71807
|
+
positiveControl,
|
|
71808
|
+
negativeControl,
|
|
71809
|
+
model
|
|
71810
|
+
} = this.props;
|
|
71811
|
+
return `S${name} ${positiveNode} ${negativeNode} ${positiveControl} ${negativeControl} ${model}`;
|
|
71812
|
+
}
|
|
71813
|
+
};
|
|
71814
|
+
function circuitJsonToSpice(circuitJson) {
|
|
71815
|
+
const netlist = new SpiceNetlist("* Circuit JSON to SPICE Netlist");
|
|
71816
|
+
const sourceComponents = su_default(circuitJson).source_component.list();
|
|
71817
|
+
const sourcePorts = su_default(circuitJson).source_port.list();
|
|
71818
|
+
const connMap = getSourcePortConnectivityMapFromCircuitJson(circuitJson);
|
|
71819
|
+
const nodeMap = /* @__PURE__ */ new Map;
|
|
71820
|
+
const netToNodeName = /* @__PURE__ */ new Map;
|
|
71821
|
+
let nodeCounter = 1;
|
|
71822
|
+
const groundNets = /* @__PURE__ */ new Set;
|
|
71823
|
+
const gndSourceNetIds = new Set(su_default(circuitJson).source_net.list().filter((sn) => sn.name?.toLowerCase().includes("gnd")).map((sn) => sn.source_net_id));
|
|
71824
|
+
if (gndSourceNetIds.size > 0) {
|
|
71825
|
+
for (const trace of su_default(circuitJson).source_trace.list()) {
|
|
71826
|
+
if (trace.connected_source_port_ids.length > 0) {
|
|
71827
|
+
const isOnGndNet = trace.connected_source_net_ids.some((netId) => gndSourceNetIds.has(netId));
|
|
71828
|
+
if (isOnGndNet) {
|
|
71829
|
+
const aPortOnGnd = trace.connected_source_port_ids[0];
|
|
71830
|
+
const gndNet = connMap.getNetConnectedToId(aPortOnGnd);
|
|
71831
|
+
if (gndNet) {
|
|
71832
|
+
groundNets.add(gndNet);
|
|
71833
|
+
}
|
|
71834
|
+
}
|
|
71835
|
+
}
|
|
71836
|
+
}
|
|
71837
|
+
}
|
|
71838
|
+
const groundPorts = sourcePorts.filter((p) => p.name?.toLowerCase() === "gnd");
|
|
71839
|
+
for (const groundPort of groundPorts) {
|
|
71840
|
+
const groundNet = connMap.getNetConnectedToId(groundPort.source_port_id);
|
|
71841
|
+
if (groundNet) {
|
|
71842
|
+
groundNets.add(groundNet);
|
|
71843
|
+
}
|
|
71844
|
+
}
|
|
71845
|
+
for (const simSource of su_default(circuitJson).simulation_voltage_source.list()) {
|
|
71846
|
+
const neg_port_id = simSource.negative_source_port_id ?? simSource.terminal2_source_port_id;
|
|
71847
|
+
if (neg_port_id) {
|
|
71848
|
+
const gnd_net = connMap.getNetConnectedToId(neg_port_id);
|
|
71849
|
+
if (gnd_net) {
|
|
71850
|
+
groundNets.add(gnd_net);
|
|
71851
|
+
}
|
|
71852
|
+
}
|
|
71853
|
+
}
|
|
71854
|
+
for (const groundNet of groundNets) {
|
|
71855
|
+
netToNodeName.set(groundNet, "0");
|
|
71856
|
+
}
|
|
71857
|
+
for (const port of sourcePorts) {
|
|
71858
|
+
const portId = port.source_port_id;
|
|
71859
|
+
const net2 = connMap.getNetConnectedToId(portId);
|
|
71860
|
+
if (net2) {
|
|
71861
|
+
if (!netToNodeName.has(net2)) {
|
|
71862
|
+
netToNodeName.set(net2, `N${nodeCounter++}`);
|
|
71863
|
+
}
|
|
71864
|
+
nodeMap.set(portId, netToNodeName.get(net2));
|
|
71865
|
+
}
|
|
71866
|
+
}
|
|
71867
|
+
for (const port of sourcePorts) {
|
|
71868
|
+
const portId = port.source_port_id;
|
|
71869
|
+
if (!nodeMap.has(portId)) {
|
|
71870
|
+
nodeMap.set(portId, `N${nodeCounter++}`);
|
|
71871
|
+
}
|
|
71872
|
+
}
|
|
71873
|
+
for (const component of sourceComponents) {
|
|
71874
|
+
if (component.type !== "source_component")
|
|
71875
|
+
continue;
|
|
71876
|
+
const componentPorts = su_default(circuitJson).source_port.list({
|
|
71877
|
+
source_component_id: component.source_component_id
|
|
71878
|
+
}).sort((a, b) => (a.pin_number ?? 0) - (b.pin_number ?? 0));
|
|
71879
|
+
const nodes = componentPorts.map((port) => {
|
|
71880
|
+
return nodeMap.get(port.source_port_id) || "0";
|
|
71881
|
+
});
|
|
71882
|
+
if ("ftype" in component) {
|
|
71883
|
+
let spiceComponent = null;
|
|
71884
|
+
switch (component.ftype) {
|
|
71885
|
+
case "simple_resistor": {
|
|
71886
|
+
if ("resistance" in component && "name" in component) {
|
|
71887
|
+
const resistorCmd = new ResistorCommand({
|
|
71888
|
+
name: component.name,
|
|
71889
|
+
positiveNode: nodes[0] || "0",
|
|
71890
|
+
negativeNode: nodes[1] || "0",
|
|
71891
|
+
value: formatResistance(component.resistance)
|
|
71892
|
+
});
|
|
71893
|
+
spiceComponent = new SpiceComponent(component.name, resistorCmd, nodes);
|
|
71894
|
+
}
|
|
71895
|
+
break;
|
|
71896
|
+
}
|
|
71897
|
+
case "simple_capacitor": {
|
|
71898
|
+
if ("capacitance" in component && "name" in component) {
|
|
71899
|
+
const capacitorCmd = new CapacitorCommand({
|
|
71900
|
+
name: component.name,
|
|
71901
|
+
positiveNode: nodes[0] || "0",
|
|
71902
|
+
negativeNode: nodes[1] || "0",
|
|
71903
|
+
value: formatCapacitance(component.capacitance)
|
|
71904
|
+
});
|
|
71905
|
+
spiceComponent = new SpiceComponent(component.name, capacitorCmd, nodes);
|
|
71906
|
+
}
|
|
71907
|
+
break;
|
|
71908
|
+
}
|
|
71909
|
+
case "simple_diode": {
|
|
71910
|
+
if ("name" in component) {
|
|
71911
|
+
const anodePort = componentPorts.find((p) => p.name?.toLowerCase() === "anode" || p.port_hints?.includes("anode"));
|
|
71912
|
+
const cathodePort = componentPorts.find((p) => p.name?.toLowerCase() === "cathode" || p.port_hints?.includes("cathode"));
|
|
71913
|
+
const positiveNode = nodeMap.get(anodePort?.source_port_id ?? "") || "0";
|
|
71914
|
+
const negativeNode = nodeMap.get(cathodePort?.source_port_id ?? "") || "0";
|
|
71915
|
+
const modelName = "D";
|
|
71916
|
+
const diodeCmd = new DiodeCommand({
|
|
71917
|
+
name: component.name,
|
|
71918
|
+
positiveNode,
|
|
71919
|
+
negativeNode,
|
|
71920
|
+
model: modelName
|
|
71921
|
+
});
|
|
71922
|
+
netlist.models.set(modelName, `.MODEL ${modelName} D`);
|
|
71923
|
+
spiceComponent = new SpiceComponent(component.name, diodeCmd, [
|
|
71924
|
+
positiveNode,
|
|
71925
|
+
negativeNode
|
|
71926
|
+
]);
|
|
71927
|
+
}
|
|
71928
|
+
break;
|
|
71929
|
+
}
|
|
71930
|
+
case "simple_inductor": {
|
|
71931
|
+
if ("inductance" in component && "name" in component) {
|
|
71932
|
+
const inductorCmd = new InductorCommand({
|
|
71933
|
+
name: component.name,
|
|
71934
|
+
positiveNode: nodes[0] || "0",
|
|
71935
|
+
negativeNode: nodes[1] || "0",
|
|
71936
|
+
value: formatInductance(component.inductance)
|
|
71937
|
+
});
|
|
71938
|
+
spiceComponent = new SpiceComponent(component.name, inductorCmd, nodes);
|
|
71939
|
+
}
|
|
71940
|
+
break;
|
|
71941
|
+
}
|
|
71942
|
+
case "simple_mosfet": {
|
|
71943
|
+
if ("name" in component) {
|
|
71944
|
+
const drainPort = componentPorts.find((p) => p.name?.toLowerCase() === "drain" || p.port_hints?.includes("drain"));
|
|
71945
|
+
const gatePort = componentPorts.find((p) => p.name?.toLowerCase() === "gate" || p.port_hints?.includes("gate"));
|
|
71946
|
+
const sourcePort = componentPorts.find((p) => p.name?.toLowerCase() === "source" || p.port_hints?.includes("source"));
|
|
71947
|
+
const drainNode = nodeMap.get(drainPort?.source_port_id ?? "") || "0";
|
|
71948
|
+
const gateNode = nodeMap.get(gatePort?.source_port_id ?? "") || "0";
|
|
71949
|
+
const sourceNode = nodeMap.get(sourcePort?.source_port_id ?? "") || "0";
|
|
71950
|
+
const modelName = "SWMOD";
|
|
71951
|
+
const switchCmd = new VoltageControlledSwitchCommand({
|
|
71952
|
+
name: component.name,
|
|
71953
|
+
positiveNode: drainNode,
|
|
71954
|
+
negativeNode: sourceNode,
|
|
71955
|
+
positiveControl: gateNode,
|
|
71956
|
+
negativeControl: sourceNode,
|
|
71957
|
+
model: modelName
|
|
71958
|
+
});
|
|
71959
|
+
netlist.models.set(modelName, `.MODEL ${modelName} SW`);
|
|
71960
|
+
spiceComponent = new SpiceComponent(component.name, switchCmd, [
|
|
71961
|
+
drainNode,
|
|
71962
|
+
gateNode,
|
|
71963
|
+
sourceNode
|
|
71964
|
+
]);
|
|
71965
|
+
}
|
|
71966
|
+
break;
|
|
71967
|
+
}
|
|
71968
|
+
}
|
|
71969
|
+
if (spiceComponent) {
|
|
71970
|
+
netlist.addComponent(spiceComponent);
|
|
71971
|
+
}
|
|
71972
|
+
}
|
|
71973
|
+
}
|
|
71974
|
+
const simulationVoltageSources = su_default(circuitJson).simulation_voltage_source.list();
|
|
71975
|
+
for (const simSource of simulationVoltageSources) {
|
|
71976
|
+
if (simSource.type !== "simulation_voltage_source")
|
|
71977
|
+
continue;
|
|
71978
|
+
if (simSource.is_dc_source === false) {
|
|
71979
|
+
if ("terminal1_source_port_id" in simSource && "terminal2_source_port_id" in simSource && simSource.terminal1_source_port_id && simSource.terminal2_source_port_id) {
|
|
71980
|
+
const positiveNode = nodeMap.get(simSource.terminal1_source_port_id) || "0";
|
|
71981
|
+
const negativeNode = nodeMap.get(simSource.terminal2_source_port_id) || "0";
|
|
71982
|
+
let value = "";
|
|
71983
|
+
const wave_shape = simSource.wave_shape;
|
|
71984
|
+
if (wave_shape === "sinewave") {
|
|
71985
|
+
const v_offset = 0;
|
|
71986
|
+
const v_peak = simSource.voltage ?? 0;
|
|
71987
|
+
const freq = simSource.frequency ?? 0;
|
|
71988
|
+
const delay3 = 0;
|
|
71989
|
+
const damping_factor = 0;
|
|
71990
|
+
const phase = simSource.phase ?? 0;
|
|
71991
|
+
if (freq > 0) {
|
|
71992
|
+
value = `SIN(${v_offset} ${v_peak} ${freq} ${delay3} ${damping_factor} ${phase})`;
|
|
71993
|
+
} else {
|
|
71994
|
+
value = `DC ${simSource.voltage ?? 0}`;
|
|
71995
|
+
}
|
|
71996
|
+
} else if (wave_shape === "square") {
|
|
71997
|
+
const v_initial = 0;
|
|
71998
|
+
const v_pulsed = simSource.voltage ?? 0;
|
|
71999
|
+
const freq = simSource.frequency ?? 0;
|
|
72000
|
+
const period_from_freq = freq === 0 ? Infinity : 1 / freq;
|
|
72001
|
+
const period = simSource.period ?? period_from_freq;
|
|
72002
|
+
const duty_cycle = simSource.duty_cycle ?? 0.5;
|
|
72003
|
+
const pulse_width = period * duty_cycle;
|
|
72004
|
+
const delay3 = 0;
|
|
72005
|
+
const rise_time = "1n";
|
|
72006
|
+
const fall_time = "1n";
|
|
72007
|
+
value = `PULSE(${v_initial} ${v_pulsed} ${delay3} ${rise_time} ${fall_time} ${pulse_width} ${period})`;
|
|
72008
|
+
} else if (simSource.voltage !== undefined) {
|
|
72009
|
+
value = `DC ${simSource.voltage}`;
|
|
72010
|
+
}
|
|
72011
|
+
if (value) {
|
|
72012
|
+
const voltageSourceCmd = new VoltageSourceCommand({
|
|
72013
|
+
name: simSource.simulation_voltage_source_id,
|
|
72014
|
+
positiveNode,
|
|
72015
|
+
negativeNode,
|
|
72016
|
+
value
|
|
72017
|
+
});
|
|
72018
|
+
const spiceComponent = new SpiceComponent(simSource.simulation_voltage_source_id, voltageSourceCmd, [positiveNode, negativeNode]);
|
|
72019
|
+
netlist.addComponent(spiceComponent);
|
|
72020
|
+
}
|
|
72021
|
+
}
|
|
72022
|
+
} else {
|
|
72023
|
+
const positivePortId = simSource.positive_source_port_id ?? simSource.terminal1_source_port_id;
|
|
72024
|
+
const negativePortId = simSource.negative_source_port_id ?? simSource.terminal2_source_port_id;
|
|
72025
|
+
if (positivePortId && negativePortId && "voltage" in simSource && simSource.voltage !== undefined) {
|
|
72026
|
+
const positiveNode = nodeMap.get(positivePortId) || "0";
|
|
72027
|
+
const negativeNode = nodeMap.get(negativePortId) || "0";
|
|
72028
|
+
const voltageSourceCmd = new VoltageSourceCommand({
|
|
72029
|
+
name: simSource.simulation_voltage_source_id,
|
|
72030
|
+
positiveNode,
|
|
72031
|
+
negativeNode,
|
|
72032
|
+
value: `DC ${simSource.voltage}`
|
|
72033
|
+
});
|
|
72034
|
+
const spiceComponent = new SpiceComponent(simSource.simulation_voltage_source_id, voltageSourceCmd, [positiveNode, negativeNode]);
|
|
72035
|
+
netlist.addComponent(spiceComponent);
|
|
72036
|
+
}
|
|
72037
|
+
}
|
|
72038
|
+
}
|
|
72039
|
+
return netlist;
|
|
72040
|
+
}
|
|
72041
|
+
function formatResistance(resistance) {
|
|
72042
|
+
if (resistance >= 1e6)
|
|
72043
|
+
return `${resistance / 1e6}MEG`;
|
|
72044
|
+
if (resistance >= 1000)
|
|
72045
|
+
return `${resistance / 1000}K`;
|
|
72046
|
+
return resistance.toString();
|
|
72047
|
+
}
|
|
72048
|
+
function formatCapacitance(capacitance) {
|
|
72049
|
+
if (capacitance >= 0.001)
|
|
72050
|
+
return `${capacitance * 1000}M`;
|
|
72051
|
+
if (capacitance >= 0.000001)
|
|
72052
|
+
return `${capacitance * 1e6}U`;
|
|
72053
|
+
if (capacitance >= 0.000000001)
|
|
72054
|
+
return `${capacitance * 1e9}N`;
|
|
72055
|
+
if (capacitance >= 0.000000000001)
|
|
72056
|
+
return `${capacitance * 1000000000000}P`;
|
|
72057
|
+
return capacitance.toString();
|
|
72058
|
+
}
|
|
72059
|
+
function formatInductance(inductance) {
|
|
72060
|
+
if (inductance >= 1)
|
|
72061
|
+
return inductance.toString();
|
|
72062
|
+
if (inductance >= 0.001)
|
|
72063
|
+
return `${inductance * 1000}m`;
|
|
72064
|
+
if (inductance >= 0.000001)
|
|
72065
|
+
return `${inductance * 1e6}u`;
|
|
72066
|
+
if (inductance >= 0.000000001)
|
|
72067
|
+
return `${inductance * 1e9}n`;
|
|
72068
|
+
if (inductance >= 0.000000000001)
|
|
72069
|
+
return `${inductance * 1000000000000}p`;
|
|
72070
|
+
return inductance.toString();
|
|
72071
|
+
}
|
|
72072
|
+
|
|
72073
|
+
// lib/shared/get-spice-with-sim.ts
|
|
72074
|
+
var formatSimTime = (seconds) => {
|
|
72075
|
+
if (seconds === 0)
|
|
72076
|
+
return "0";
|
|
72077
|
+
const absSeconds = Math.abs(seconds);
|
|
72078
|
+
const precision = (v) => v.toPrecision(4);
|
|
72079
|
+
if (absSeconds >= 1)
|
|
72080
|
+
return precision(seconds);
|
|
72081
|
+
if (absSeconds >= 0.001)
|
|
72082
|
+
return `${precision(seconds * 1000)}m`;
|
|
72083
|
+
if (absSeconds >= 0.000001)
|
|
72084
|
+
return `${precision(seconds * 1e6)}u`;
|
|
72085
|
+
if (absSeconds >= 0.000000001)
|
|
72086
|
+
return `${precision(seconds * 1e9)}n`;
|
|
72087
|
+
if (absSeconds >= 0.000000000001)
|
|
72088
|
+
return `${precision(seconds * 1000000000000)}p`;
|
|
72089
|
+
if (absSeconds >= 0.000000000000001)
|
|
72090
|
+
return `${precision(seconds * 1000000000000000)}f`;
|
|
72091
|
+
return seconds.toExponential(3);
|
|
72092
|
+
};
|
|
72093
|
+
var getSpiceWithPaddedSim = (circuitJson, options) => {
|
|
72094
|
+
const spiceNetlist = circuitJsonToSpice(circuitJson);
|
|
72095
|
+
const baseSpiceString = spiceNetlist.toSpiceString();
|
|
72096
|
+
const hasAnalysis = /\.tran|\.ac|\.dc|\.op/i.test(baseSpiceString);
|
|
72097
|
+
const hasOutput = /\.probe|\.plot|wrdata/i.test(baseSpiceString);
|
|
72098
|
+
const lines = baseSpiceString.split(`
|
|
72099
|
+
`).filter((l) => l.trim() !== "");
|
|
72100
|
+
const componentLines = lines.filter((l) => !l.startsWith("*") && !l.startsWith(".") && l.trim() !== "");
|
|
72101
|
+
const allNodes = new Set;
|
|
72102
|
+
const capacitorNodes = new Set;
|
|
72103
|
+
const componentNamesToProbeCurrent = new Set;
|
|
72104
|
+
for (const line of componentLines) {
|
|
72105
|
+
const parts = line.trim().split(/\s+/);
|
|
72106
|
+
if (parts.length < 3)
|
|
72107
|
+
continue;
|
|
72108
|
+
const componentName = parts[0];
|
|
72109
|
+
const componentType = componentName[0].toUpperCase();
|
|
72110
|
+
let nodesOnLine = [];
|
|
72111
|
+
if (["R", "C", "L", "V", "I", "D"].includes(componentType)) {
|
|
72112
|
+
nodesOnLine = parts.slice(1, 3);
|
|
72113
|
+
if (componentType === "V") {
|
|
72114
|
+
componentNamesToProbeCurrent.add(componentName);
|
|
72115
|
+
}
|
|
72116
|
+
} else if (componentType === "Q" && parts.length >= 4) {
|
|
72117
|
+
nodesOnLine = parts.slice(1, 4);
|
|
72118
|
+
} else if (componentType === "M" && parts.length >= 5) {
|
|
72119
|
+
nodesOnLine = parts.slice(1, 5);
|
|
72120
|
+
} else if (componentType === "X") {
|
|
72121
|
+
nodesOnLine = parts.slice(1, -1);
|
|
72122
|
+
} else {
|
|
72123
|
+
continue;
|
|
72124
|
+
}
|
|
72125
|
+
nodesOnLine.forEach((node) => allNodes.add(node));
|
|
72126
|
+
if (componentType === "C") {
|
|
72127
|
+
nodesOnLine.forEach((node) => capacitorNodes.add(node));
|
|
72128
|
+
}
|
|
72129
|
+
}
|
|
72130
|
+
allNodes.delete("0");
|
|
72131
|
+
capacitorNodes.delete("0");
|
|
72132
|
+
const icLines = Array.from(capacitorNodes).map((node) => `.ic V(${node})=0`);
|
|
72133
|
+
let probeLine = "";
|
|
72134
|
+
if (!hasOutput) {
|
|
72135
|
+
const probes = [];
|
|
72136
|
+
const probeVoltages = Array.from(allNodes).map((node) => `V(${node})`);
|
|
72137
|
+
probes.push(...probeVoltages);
|
|
72138
|
+
const probeCurrents = Array.from(componentNamesToProbeCurrent).map((name) => `I(${name})`);
|
|
72139
|
+
probes.push(...probeCurrents);
|
|
72140
|
+
probeLine = probes.length > 0 ? `.probe ${probes.join(" ")}` : "";
|
|
72141
|
+
}
|
|
72142
|
+
let tranLine = "";
|
|
72143
|
+
if (!hasAnalysis) {
|
|
72144
|
+
const tstart_ms = options?.startTime ?? 0;
|
|
72145
|
+
const duration_ms = options?.duration ?? 20;
|
|
72146
|
+
const tstart = tstart_ms * 0.001;
|
|
72147
|
+
const duration = duration_ms * 0.001;
|
|
72148
|
+
const tstop = tstart + duration;
|
|
72149
|
+
const tstep = duration / 50;
|
|
72150
|
+
tranLine = `.tran ${formatSimTime(tstep)} ${formatSimTime(tstop)} ${formatSimTime(tstart)} UIC`;
|
|
72151
|
+
}
|
|
72152
|
+
const endStatement = ".end";
|
|
72153
|
+
const originalLines = baseSpiceString.split(`
|
|
72154
|
+
`);
|
|
72155
|
+
let endIndex = -1;
|
|
72156
|
+
for (let i = originalLines.length - 1;i >= 0; i--) {
|
|
72157
|
+
if (originalLines[i].trim().toLowerCase().startsWith(endStatement)) {
|
|
72158
|
+
endIndex = i;
|
|
72159
|
+
break;
|
|
72160
|
+
}
|
|
72161
|
+
}
|
|
72162
|
+
const injectionLines = [
|
|
72163
|
+
...icLines.length > 0 && !/\.ic/i.test(baseSpiceString) ? icLines : [],
|
|
72164
|
+
probeLine,
|
|
72165
|
+
tranLine
|
|
72166
|
+
].filter(Boolean);
|
|
72167
|
+
if (injectionLines.length === 0) {
|
|
72168
|
+
return baseSpiceString;
|
|
72169
|
+
}
|
|
72170
|
+
let finalLines;
|
|
72171
|
+
if (endIndex !== -1) {
|
|
72172
|
+
const beforeEnd = originalLines.slice(0, endIndex);
|
|
72173
|
+
const endLineAndAfter = originalLines.slice(endIndex);
|
|
72174
|
+
finalLines = [...beforeEnd, ...injectionLines, ...endLineAndAfter];
|
|
72175
|
+
} else {
|
|
72176
|
+
finalLines = [...originalLines, ...injectionLines, endStatement];
|
|
72177
|
+
}
|
|
72178
|
+
return finalLines.join(`
|
|
72179
|
+
`);
|
|
72180
|
+
};
|
|
72181
|
+
|
|
72182
|
+
// lib/eecircuit-engine/run-simulation.ts
|
|
72183
|
+
import { promises as fs23, existsSync as existsSync9 } from "node:fs";
|
|
72184
|
+
import path23 from "node:path";
|
|
72185
|
+
import os3 from "node:os";
|
|
72186
|
+
var sim = null;
|
|
72187
|
+
var fetchSimulation = async () => {
|
|
72188
|
+
const tempFilePath = path23.join(os3.tmpdir(), "eecircuit-engine-1.5.2.mjs");
|
|
72189
|
+
if (!existsSync9(tempFilePath)) {
|
|
72190
|
+
const url = "https://cdn.jsdelivr.net/npm/eecircuit-engine@1.5.2/+esm";
|
|
72191
|
+
const response = await fetch(url);
|
|
72192
|
+
if (!response.ok) {
|
|
72193
|
+
throw new Error(`Failed to fetch eecircuit-engine from ${url}: ${response.statusText}`);
|
|
72194
|
+
}
|
|
72195
|
+
const scriptContent = await response.text();
|
|
72196
|
+
await fs23.writeFile(tempFilePath, scriptContent);
|
|
72197
|
+
}
|
|
72198
|
+
const module2 = await import(tempFilePath);
|
|
72199
|
+
return module2.Simulation;
|
|
72200
|
+
};
|
|
72201
|
+
var initializeSimulation = async () => {
|
|
72202
|
+
if (sim && sim.isInitialized())
|
|
72203
|
+
return;
|
|
72204
|
+
const Simulation = await fetchSimulation();
|
|
72205
|
+
sim = new Simulation;
|
|
72206
|
+
sim.start();
|
|
72207
|
+
const startTime = Date.now();
|
|
72208
|
+
const timeout2 = 15000;
|
|
72209
|
+
while (!sim.isInitialized()) {
|
|
72210
|
+
if (Date.now() - startTime > timeout2) {
|
|
72211
|
+
console.error("Error: Simulation engine initialization timed out.");
|
|
72212
|
+
const initInfo = sim.getInitInfo();
|
|
72213
|
+
if (initInfo) {
|
|
72214
|
+
console.error("Initialization Info:", initInfo);
|
|
72215
|
+
}
|
|
72216
|
+
const errors = sim.getError();
|
|
72217
|
+
if (errors && errors.length > 0) {
|
|
72218
|
+
console.error("Errors:", errors.join(`
|
|
72219
|
+
`));
|
|
72220
|
+
}
|
|
72221
|
+
throw new Error("Simulation engine initialization timed out.");
|
|
72222
|
+
}
|
|
72223
|
+
await new Promise((resolve10) => setTimeout(resolve10, 200));
|
|
72224
|
+
}
|
|
72225
|
+
};
|
|
72226
|
+
var runSimulation = async (spiceString) => {
|
|
72227
|
+
await initializeSimulation();
|
|
72228
|
+
if (!sim)
|
|
72229
|
+
throw new Error("Simulation not initialized");
|
|
72230
|
+
let engineSpiceString = spiceString;
|
|
72231
|
+
const wrdataMatch = engineSpiceString.match(/wrdata\s+(\S+)\s+(.*)/i);
|
|
72232
|
+
if (wrdataMatch) {
|
|
72233
|
+
const variables = wrdataMatch[2].trim().split(/\s+/);
|
|
72234
|
+
const probeLine = `.probe ${variables.join(" ")}`;
|
|
72235
|
+
engineSpiceString = engineSpiceString.replace(/wrdata.*/i, probeLine);
|
|
72236
|
+
} else if (!engineSpiceString.match(/\.probe/i)) {
|
|
72237
|
+
const plotMatch = engineSpiceString.match(/plot\s+(.*)/i);
|
|
72238
|
+
if (plotMatch) {
|
|
72239
|
+
throw new Error("The 'plot' command is not supported for data extraction. Please use 'wrdata <filename> <var1> ...' or '.probe <var1> ...' instead.");
|
|
72240
|
+
}
|
|
72241
|
+
throw new Error("No '.probe' or 'wrdata' command found in SPICE file. Use 'wrdata <filename> <var1> ...' to specify output.");
|
|
72242
|
+
}
|
|
72243
|
+
sim.setNetList(engineSpiceString);
|
|
72244
|
+
const result = await sim.runSim();
|
|
72245
|
+
return {
|
|
72246
|
+
result,
|
|
72247
|
+
info: sim.getInfo(),
|
|
72248
|
+
errors: sim.getError()
|
|
72249
|
+
};
|
|
72250
|
+
};
|
|
72251
|
+
|
|
72252
|
+
// lib/shared/result-to-csv.ts
|
|
72253
|
+
var resultToCsv = (result) => {
|
|
72254
|
+
const uniqueHeaders = [];
|
|
72255
|
+
const uniqueData = [];
|
|
72256
|
+
const seenHeaders = new Set;
|
|
72257
|
+
result.variableNames.forEach((header, index) => {
|
|
72258
|
+
if (!seenHeaders.has(header)) {
|
|
72259
|
+
seenHeaders.add(header);
|
|
72260
|
+
uniqueHeaders.push(header);
|
|
72261
|
+
uniqueData.push(result.data[index]);
|
|
72262
|
+
}
|
|
72263
|
+
});
|
|
72264
|
+
if (result.dataType === "real") {
|
|
72265
|
+
const headers2 = uniqueHeaders.join(",");
|
|
72266
|
+
const rows2 = [];
|
|
72267
|
+
for (let i = 0;i < result.numPoints; i++) {
|
|
72268
|
+
const row = uniqueData.map((d) => d.values[i]).join(",");
|
|
72269
|
+
rows2.push(row);
|
|
72270
|
+
}
|
|
72271
|
+
return [headers2, ...rows2].join(`
|
|
72272
|
+
`);
|
|
72273
|
+
}
|
|
72274
|
+
const headers = uniqueHeaders.flatMap((v) => [`${v}_real`, `${v}_img`]).join(",");
|
|
72275
|
+
const rows = [];
|
|
72276
|
+
for (let i = 0;i < result.numPoints; i++) {
|
|
72277
|
+
const row = uniqueData.flatMap((d) => [d.values[i].real, d.values[i].img]).join(",");
|
|
72278
|
+
rows.push(row);
|
|
72279
|
+
}
|
|
72280
|
+
return [headers, ...rows].join(`
|
|
72281
|
+
`);
|
|
72282
|
+
};
|
|
72283
|
+
|
|
71591
72284
|
// cli/export/register.ts
|
|
72285
|
+
import path24 from "node:path";
|
|
72286
|
+
import { promises as fs24 } from "node:fs";
|
|
71592
72287
|
var registerExport = (program3) => {
|
|
71593
72288
|
program3.command("export").description("Export tscircuit code to various formats").argument("<file>", "Path to the package file").option("-f, --format <format>", "Output format").option("-o, --output <path>", "Output file path").action(async (file, options) => {
|
|
72289
|
+
const format = options.format ?? "json";
|
|
72290
|
+
if (format === "spice") {
|
|
72291
|
+
const { circuitJson } = await generateCircuitJson({ filePath: file });
|
|
72292
|
+
if (circuitJson) {
|
|
72293
|
+
const spiceString = getSpiceWithPaddedSim(circuitJson);
|
|
72294
|
+
const outputSpicePath = options.output ?? path24.join(path24.dirname(file), `${path24.basename(file, path24.extname(file))}.spice.cir`);
|
|
72295
|
+
await fs24.writeFile(outputSpicePath, spiceString);
|
|
72296
|
+
const { result } = await runSimulation(spiceString);
|
|
72297
|
+
const csvContent = resultToCsv(result);
|
|
72298
|
+
const outputCsvPath = outputSpicePath.replace(/\.spice\.cir$/, ".csv");
|
|
72299
|
+
await fs24.writeFile(outputCsvPath, csvContent);
|
|
72300
|
+
console.log(`Exported to ${outputSpicePath} and ${outputCsvPath} (simulation results)!`);
|
|
72301
|
+
}
|
|
72302
|
+
return;
|
|
72303
|
+
}
|
|
71594
72304
|
await exportSnippet({
|
|
71595
72305
|
filePath: file,
|
|
71596
|
-
format
|
|
72306
|
+
format,
|
|
71597
72307
|
outputPath: options.output,
|
|
71598
72308
|
onExit: (code) => process.exit(code),
|
|
71599
72309
|
onError: (message) => console.error(message),
|
|
@@ -71774,14 +72484,14 @@ class KeyStore {
|
|
|
71774
72484
|
}
|
|
71775
72485
|
}
|
|
71776
72486
|
function createKey(key) {
|
|
71777
|
-
let
|
|
72487
|
+
let path25 = null;
|
|
71778
72488
|
let id = null;
|
|
71779
72489
|
let src = null;
|
|
71780
72490
|
let weight = 1;
|
|
71781
72491
|
let getFn = null;
|
|
71782
72492
|
if (isString2(key) || isArray(key)) {
|
|
71783
72493
|
src = key;
|
|
71784
|
-
|
|
72494
|
+
path25 = createKeyPath(key);
|
|
71785
72495
|
id = createKeyId(key);
|
|
71786
72496
|
} else {
|
|
71787
72497
|
if (!hasOwn.call(key, "name")) {
|
|
@@ -71795,11 +72505,11 @@ function createKey(key) {
|
|
|
71795
72505
|
throw new Error(INVALID_KEY_WEIGHT_VALUE(name));
|
|
71796
72506
|
}
|
|
71797
72507
|
}
|
|
71798
|
-
|
|
72508
|
+
path25 = createKeyPath(name);
|
|
71799
72509
|
id = createKeyId(name);
|
|
71800
72510
|
getFn = key.getFn;
|
|
71801
72511
|
}
|
|
71802
|
-
return { path:
|
|
72512
|
+
return { path: path25, id, weight, src, getFn };
|
|
71803
72513
|
}
|
|
71804
72514
|
function createKeyPath(key) {
|
|
71805
72515
|
return isArray(key) ? key : key.split(".");
|
|
@@ -71807,34 +72517,34 @@ function createKeyPath(key) {
|
|
|
71807
72517
|
function createKeyId(key) {
|
|
71808
72518
|
return isArray(key) ? key.join(".") : key;
|
|
71809
72519
|
}
|
|
71810
|
-
function get(obj,
|
|
72520
|
+
function get(obj, path25) {
|
|
71811
72521
|
let list = [];
|
|
71812
72522
|
let arr = false;
|
|
71813
|
-
const deepGet = (obj2,
|
|
72523
|
+
const deepGet = (obj2, path26, index) => {
|
|
71814
72524
|
if (!isDefined(obj2)) {
|
|
71815
72525
|
return;
|
|
71816
72526
|
}
|
|
71817
|
-
if (!
|
|
72527
|
+
if (!path26[index]) {
|
|
71818
72528
|
list.push(obj2);
|
|
71819
72529
|
} else {
|
|
71820
|
-
let key =
|
|
72530
|
+
let key = path26[index];
|
|
71821
72531
|
const value = obj2[key];
|
|
71822
72532
|
if (!isDefined(value)) {
|
|
71823
72533
|
return;
|
|
71824
72534
|
}
|
|
71825
|
-
if (index ===
|
|
72535
|
+
if (index === path26.length - 1 && (isString2(value) || isNumber(value) || isBoolean(value))) {
|
|
71826
72536
|
list.push(toString(value));
|
|
71827
72537
|
} else if (isArray(value)) {
|
|
71828
72538
|
arr = true;
|
|
71829
72539
|
for (let i = 0, len = value.length;i < len; i += 1) {
|
|
71830
|
-
deepGet(value[i],
|
|
72540
|
+
deepGet(value[i], path26, index + 1);
|
|
71831
72541
|
}
|
|
71832
|
-
} else if (
|
|
71833
|
-
deepGet(value,
|
|
72542
|
+
} else if (path26.length) {
|
|
72543
|
+
deepGet(value, path26, index + 1);
|
|
71834
72544
|
}
|
|
71835
72545
|
}
|
|
71836
72546
|
};
|
|
71837
|
-
deepGet(obj, isString2(
|
|
72547
|
+
deepGet(obj, isString2(path25) ? path25.split(".") : path25, 0);
|
|
71838
72548
|
return arr ? list : list[0];
|
|
71839
72549
|
}
|
|
71840
72550
|
var MatchOptions = {
|
|
@@ -73026,8 +73736,8 @@ var registerSearch = (program3) => {
|
|
|
73026
73736
|
}
|
|
73027
73737
|
if (kicadResults.length) {
|
|
73028
73738
|
console.log(kleur_default.bold().underline(`Found ${kicadResults.length} footprint(s) from KiCad:`));
|
|
73029
|
-
kicadResults.forEach((
|
|
73030
|
-
console.log(`${(idx + 1).toString().padStart(2, " ")}. kicad:${
|
|
73739
|
+
kicadResults.forEach((path25, idx) => {
|
|
73740
|
+
console.log(`${(idx + 1).toString().padStart(2, " ")}. kicad:${path25.replace(".kicad_mod", "").replace(".pretty", "")}`);
|
|
73031
73741
|
});
|
|
73032
73742
|
}
|
|
73033
73743
|
if (!onlyKicad && results.packages.length) {
|
|
@@ -78185,7 +78895,7 @@ var zo = rs.find((t2) => t2.text === "{REF}");
|
|
|
78185
78895
|
zo.y = 0;
|
|
78186
78896
|
zo.x = 0.35;
|
|
78187
78897
|
zo.anchor = "middle_left";
|
|
78188
|
-
var
|
|
78898
|
+
var os4 = es;
|
|
78189
78899
|
var is = { paths: { path11: { type: "path", points: [{ x: -0.39, y: 0 }, { x: 0.06, y: -0.01 }], color: "primary", fill: false }, path40: { type: "path", points: [{ x: 0.07, y: 0.19 }, { x: 0.07, y: -0.18 }], color: "primary", fill: false }, "path12-1": { type: "path", points: [{ x: 0.28, y: 0.53 }, { x: 0.28, y: 0.11 }], color: "primary", fill: false }, "path12-1-5": { type: "path", points: [{ x: 0.29, y: -0.53 }, { x: 0.29, y: -0.1 }], color: "primary", fill: false }, path2: { type: "path", points: [{ x: 0.07, y: 0.11 }, { x: 0.29, y: 0.11 }], color: "primary", fill: false }, "path2-5": { type: "path", points: [{ x: 0.07, y: -0.1 }, { x: 0.29, y: -0.1 }], color: "primary", fill: false }, path15: { type: "path", points: [{ x: -0.08, y: 0.06 }, { x: -0.08, y: -0.07 }, { x: 0.01, y: 0 }, { x: -0.08, y: 0.06 }], color: "primary", fill: true } }, texts: { top1: { type: "text", text: "{REF}", x: -0.15, y: 0.36 }, bottom1: { type: "text", text: "{VAL}", x: 0.04, y: -0.42 } }, refblocks: { top1: { x: 0.28, y: 0.55 }, bottom1: { x: 0.29, y: -0.55 }, left1: { x: -0.4, y: 0 } }, bounds: { minX: -0.43, maxX: 0.43, minY: -0.58, maxY: 0.58, width: 0.85, height: 1.16, centerX: 0, centerY: 0 }, circles: { path1: { type: "circle", x: 0.14, y: 0, radius: 0.29, color: "primary", fill: false } } };
|
|
78190
78900
|
var { paths: ud, texts: ls, bounds: Ke, refblocks: Oo, circles: vd } = is;
|
|
78191
78901
|
var t0 = s({ primitives: [...Object.values(ud), ...Object.values(vd), { ...ls.top1, anchor: "middle_right", x: 0 }, { ...ls.bottom1, anchor: "middle_right", x: 0 }], ports: [{ ...Oo.top1, labels: ["1", "drain"] }, { ...Oo.bottom1, labels: ["2", "source"] }, { ...Oo.left1, labels: ["3", "gate"] }], size: { width: Ke.width, height: Ke.height }, center: { x: Ke.centerX, y: Ke.centerY } });
|
|
@@ -78205,7 +78915,7 @@ var { paths: Ad, bounds: ss, refblocks: Pd } = xs;
|
|
|
78205
78915
|
var U = e({ primitives: [...Object.values(Ad)], ports: [{ ...Pd.left1, labels: ["1"] }], center: { x: ss.centerX, y: ss.centerY } }).rotateRightFacingSymbol("right").labelPort("left1", ["1"]).build();
|
|
78206
78916
|
var ms = r(U, "down");
|
|
78207
78917
|
var ns = r(U, "left");
|
|
78208
|
-
var
|
|
78918
|
+
var fs25 = r(U, "up");
|
|
78209
78919
|
var g = { paths: { path11: { type: "path", points: [{ x: -0.39, y: 0 }, { x: 0.06, y: -0.01 }], color: "primary", fill: false }, "path40-0": { type: "path", points: [{ x: 0.07, y: 0.27 }, { x: 0.07, y: -0.28 }], color: "primary", fill: false }, "path40-0-5": { type: "path", points: [{ x: 0.28, y: 0.24 }, { x: 0.08, y: 0.11 }], color: "primary", fill: false }, "path40-0-5-0": { type: "path", points: [{ x: 0.29, y: -0.24 }, { x: 0.09, y: -0.11 }], color: "primary", fill: false }, "path12-1-5": { type: "path", points: [{ x: 0.29, y: 0.25 }, { x: 0.29, y: 0.54 }], color: "primary", fill: false }, "path12-1-5-3": { type: "path", points: [{ x: 0.29, y: -0.54 }, { x: 0.29, y: -0.25 }], color: "primary", fill: false }, path15: { type: "path", points: [{ x: 0.19, y: -0.1 }, { x: 0.12, y: -0.2 }, { x: 0.22, y: -0.2 }, { x: 0.19, y: -0.1 }], color: "primary", fill: true } }, texts: { top1: { type: "text", text: "{REF}", x: -0.08, y: 0.36 }, bottom1: { type: "text", text: "{VAL}", x: -0.07, y: -0.41 } }, refblocks: { top1: { x: 0.29, y: 0.55 }, bottom1: { x: 0.29, y: -0.55 }, left1: { x: -0.4, y: 0 } }, bounds: { minX: -0.43, maxX: 0.43, minY: -0.58, maxY: 0.58, width: 0.85, height: 1.16, centerX: 0, centerY: 0 }, circles: { "path1-0": { type: "circle", x: 0.14, y: 0, radius: 0.29, color: "primary", fill: false } } };
|
|
78210
78920
|
var { paths: Fd, texts: XA, bounds: e0, refblocks: Mo, circles: Rd } = g;
|
|
78211
78921
|
var hs = e({ primitives: [...Object.values(Fd), ...Object.values(Rd), { type: "text", text: "{REF}", x: -0.1, y: 0.3094553499999995 }, { type: "text", text: "{VAL}", x: -0.1, y: -0.3094553499999995 }], ports: [{ ...Mo.top1, labels: ["1", "collector"] }, { ...Mo.bottom1, labels: ["2", "emitter"] }, { ...Mo.left1, labels: ["3", "base"] }], size: { width: e0.width, height: e0.height }, center: { x: e0.centerX, y: e0.centerY } }).rotateRightFacingSymbol("right").changeTextAnchor("{REF}", "middle_right").changeTextAnchor("{VAL}", "middle_right").build();
|
|
@@ -78774,7 +79484,7 @@ var mb = Cl.primitives.find((t3) => t3.type === "text" && t3.text === "{VAL}");
|
|
|
78774
79484
|
sb.anchor = "middle_left";
|
|
78775
79485
|
mb.anchor = "middle_right";
|
|
78776
79486
|
var B1 = Cl;
|
|
78777
|
-
var q1 = { ac_voltmeter_down: Ul, ac_voltmeter_horz: Wl, ac_voltmeter_left: Zl, ac_voltmeter_right: Kl, ac_voltmeter_up: ep, ac_voltmeter_vert: op, avalanche_diode_down: lp, avalanche_diode_horz: pp, avalanche_diode_left: yp, avalanche_diode_right: xp, avalanche_diode_up: mp, avalanche_diode_vert: fp, backward_diode_down: cp, backward_diode_left: Dt, backward_diode_right: _p, backward_diode_up: gp, battery_horz: Wt, battery_vert: Ap, boxresistor_down: Fp, boxresistor_left: Ep, boxresistor_right: Lp, boxresistor_small_down: jp, boxresistor_small_left: zp, boxresistor_small_right: Jp, boxresistor_small_up: Mp, boxresistor_up: Ip, bridged_ground_down: Dp, bridged_ground_left: Wp, bridged_ground_right: te, bridged_ground_up: Qp, capacitor_down: ta, capacitor_left: ea, capacitor_polarized_down: oa, capacitor_polarized_left: ia, capacitor_polarized_right: pa, capacitor_polarized_up: ya, capacitor_right: xa, capacitor_up: ma, constant_current_diode_down: fa, constant_current_diode_horz: ha, constant_current_diode_left: da, constant_current_diode_right: ba, constant_current_diode_up: ga, constant_current_diode_vert: va, crystal_4pin_down: wa, crystal_4pin_left: Aa, crystal_4pin_right: Pa, crystal_4pin_up: Sa, crystal_down: Ra, crystal_left: Ta, crystal_right: Ea, crystal_up: Xa, darlington_pair_transistor_down: La, darlington_pair_transistor_horz: Va, darlington_pair_transistor_left: ja, darlington_pair_transistor_right: ka, darlington_pair_transistor_up: za, darlington_pair_transistor_vert: Oa, dc_ammeter_horz: wt, dc_ammeter_vert: Ca, dc_voltmeter_down: Ia, dc_voltmeter_horz: qa, dc_voltmeter_left: Ua, dc_voltmeter_right: Wa, dc_voltmeter_up: Za, dc_voltmeter_vert: Ka, diac_down: ty, diac_horz: ey, diac_left: ry, diac_right: oy, diac_up: iy, diac_vert: ly, diode_down: ay, diode_left: yy, diode_right: $2, diode_up: xy, dpdt_normally_closed_switch_down: my, dpdt_normally_closed_switch_left: ny, dpdt_normally_closed_switch_right: M, dpdt_normally_closed_switch_up: fy, dpdt_switch_down: cy, dpdt_switch_left: dy, dpdt_switch_right: C, dpdt_switch_up: by, dpst_normally_closed_switch_down: gy, dpst_normally_closed_switch_left: uy, dpst_normally_closed_switch_right: N, dpst_normally_closed_switch_up: vy, dpst_switch_down: Ay, dpst_switch_left: Py, dpst_switch_right: I, dpst_switch_up: Sy, ferrite_bead_down: Ry, ferrite_bead_left: Ty, ferrite_bead_right: Fe, ferrite_bead_up: Se, filled_diode_down: Yy, filled_diode_horz: Ly, filled_diode_left: jy, filled_diode_right: zy, filled_diode_up: Jy, filled_diode_vert: My, frequency_meter_horz: At, frequency_meter_vert: By, fuse_horz: ke, fuse_vert: Uy, ground_down: Gy, ground_horz: Wy, ground_left: Hy, ground_right: Zy, ground_up: Qy, ground_vert: Ky2, ground2_down: ex, ground2_left: ox, ground2_right: lx, ground2_up: ax, gunn_diode_horz: yx, gunn_diode_vert: xx, icled_down: mx, icled_left: nx, icled_right: q, icled_up: fx, igbt_transistor_horz: ze, igbt_transistor_vert: dx, illuminated_push_button_normally_open_horz: Oe, illuminated_push_button_normally_open_vert: ux, inductor_down: Px, inductor_left: Sx, inductor_right: _t, inductor_up: $e, laser_diode_down: Fx, laser_diode_left: Rx, laser_diode_right: D, laser_diode_up: Tx, led_down: Lx, led_left: Vx, led_right: gt, led_up: Ce, light_dependent_resistor_horz: Ie, light_dependent_resistor_vert: $x, mosfet_depletion_normally_on_horz: qe, mosfet_depletion_normally_on_vert: Ix, mushroom_head_normally_open_momentary_horz: Ue, mushroom_head_normally_open_momentary_vert: Ux, n_channel_d_mosfet_transistor_horz: He, n_channel_d_mosfet_transistor_vert: Qx, n_channel_e_mosfet_transistor_horz: Qe, n_channel_e_mosfet_transistor_vert:
|
|
79487
|
+
var q1 = { ac_voltmeter_down: Ul, ac_voltmeter_horz: Wl, ac_voltmeter_left: Zl, ac_voltmeter_right: Kl, ac_voltmeter_up: ep, ac_voltmeter_vert: op, avalanche_diode_down: lp, avalanche_diode_horz: pp, avalanche_diode_left: yp, avalanche_diode_right: xp, avalanche_diode_up: mp, avalanche_diode_vert: fp, backward_diode_down: cp, backward_diode_left: Dt, backward_diode_right: _p, backward_diode_up: gp, battery_horz: Wt, battery_vert: Ap, boxresistor_down: Fp, boxresistor_left: Ep, boxresistor_right: Lp, boxresistor_small_down: jp, boxresistor_small_left: zp, boxresistor_small_right: Jp, boxresistor_small_up: Mp, boxresistor_up: Ip, bridged_ground_down: Dp, bridged_ground_left: Wp, bridged_ground_right: te, bridged_ground_up: Qp, capacitor_down: ta, capacitor_left: ea, capacitor_polarized_down: oa, capacitor_polarized_left: ia, capacitor_polarized_right: pa, capacitor_polarized_up: ya, capacitor_right: xa, capacitor_up: ma, constant_current_diode_down: fa, constant_current_diode_horz: ha, constant_current_diode_left: da, constant_current_diode_right: ba, constant_current_diode_up: ga, constant_current_diode_vert: va, crystal_4pin_down: wa, crystal_4pin_left: Aa, crystal_4pin_right: Pa, crystal_4pin_up: Sa, crystal_down: Ra, crystal_left: Ta, crystal_right: Ea, crystal_up: Xa, darlington_pair_transistor_down: La, darlington_pair_transistor_horz: Va, darlington_pair_transistor_left: ja, darlington_pair_transistor_right: ka, darlington_pair_transistor_up: za, darlington_pair_transistor_vert: Oa, dc_ammeter_horz: wt, dc_ammeter_vert: Ca, dc_voltmeter_down: Ia, dc_voltmeter_horz: qa, dc_voltmeter_left: Ua, dc_voltmeter_right: Wa, dc_voltmeter_up: Za, dc_voltmeter_vert: Ka, diac_down: ty, diac_horz: ey, diac_left: ry, diac_right: oy, diac_up: iy, diac_vert: ly, diode_down: ay, diode_left: yy, diode_right: $2, diode_up: xy, dpdt_normally_closed_switch_down: my, dpdt_normally_closed_switch_left: ny, dpdt_normally_closed_switch_right: M, dpdt_normally_closed_switch_up: fy, dpdt_switch_down: cy, dpdt_switch_left: dy, dpdt_switch_right: C, dpdt_switch_up: by, dpst_normally_closed_switch_down: gy, dpst_normally_closed_switch_left: uy, dpst_normally_closed_switch_right: N, dpst_normally_closed_switch_up: vy, dpst_switch_down: Ay, dpst_switch_left: Py, dpst_switch_right: I, dpst_switch_up: Sy, ferrite_bead_down: Ry, ferrite_bead_left: Ty, ferrite_bead_right: Fe, ferrite_bead_up: Se, filled_diode_down: Yy, filled_diode_horz: Ly, filled_diode_left: jy, filled_diode_right: zy, filled_diode_up: Jy, filled_diode_vert: My, frequency_meter_horz: At, frequency_meter_vert: By, fuse_horz: ke, fuse_vert: Uy, ground_down: Gy, ground_horz: Wy, ground_left: Hy, ground_right: Zy, ground_up: Qy, ground_vert: Ky2, ground2_down: ex, ground2_left: ox, ground2_right: lx, ground2_up: ax, gunn_diode_horz: yx, gunn_diode_vert: xx, icled_down: mx, icled_left: nx, icled_right: q, icled_up: fx, igbt_transistor_horz: ze, igbt_transistor_vert: dx, illuminated_push_button_normally_open_horz: Oe, illuminated_push_button_normally_open_vert: ux, inductor_down: Px, inductor_left: Sx, inductor_right: _t, inductor_up: $e, laser_diode_down: Fx, laser_diode_left: Rx, laser_diode_right: D, laser_diode_up: Tx, led_down: Lx, led_left: Vx, led_right: gt, led_up: Ce, light_dependent_resistor_horz: Ie, light_dependent_resistor_vert: $x, mosfet_depletion_normally_on_horz: qe, mosfet_depletion_normally_on_vert: Ix, mushroom_head_normally_open_momentary_horz: Ue, mushroom_head_normally_open_momentary_vert: Ux, n_channel_d_mosfet_transistor_horz: He, n_channel_d_mosfet_transistor_vert: Qx, n_channel_e_mosfet_transistor_horz: Qe, n_channel_e_mosfet_transistor_vert: os4, njfet_transistor_horz: t0, njfet_transistor_vert: ys, not_connected_down: ms, not_connected_left: ns, not_connected_right: U, not_connected_up: fs25, npn_bipolar_transistor_down: hs, npn_bipolar_transistor_horz: cs, npn_bipolar_transistor_left: ds, npn_bipolar_transistor_right: bs, npn_bipolar_transistor_up: _s, npn_bipolar_transistor_vert: gs, opamp_no_power_down: vs, opamp_no_power_left: ws, opamp_no_power_right: G, opamp_no_power_up: As, opamp_with_power_down: Ss, opamp_with_power_left: Fs, opamp_with_power_right: W, opamp_with_power_up: Rs, p_channel_d_mosfet_transistor_horz: a0, p_channel_d_mosfet_transistor_vert: Ls, p_channel_e_mosfet_transistor_horz: x0, p_channel_e_mosfet_transistor_vert: Os, photodiode_horz: s0, photodiode_vert: Cs, pjfet_transistor_horz: n0, pjfet_transistor_vert: Ds, pnp_bipolar_transistor_down: Us, pnp_bipolar_transistor_horz: Gs, pnp_bipolar_transistor_left: Ws, pnp_bipolar_transistor_right: Hs, pnp_bipolar_transistor_up: Zs, pnp_bipolar_transistor_vert: Qs, potentiometer_horz: g0, potentiometer_vert: rm, potentiometer2_down: pm, potentiometer2_left: am, potentiometer2_right: H, potentiometer2_up: ym, potentiometer3_down: xm, potentiometer3_left: sm, potentiometer3_right: mm, potentiometer3_up: nm, power_factor_meter_horz: S0, power_factor_meter_vert: dm, push_button_normally_closed_momentary_horz: R0, push_button_normally_closed_momentary_vert: um, push_button_normally_open_momentary_horz: E0, push_button_normally_open_momentary_vert: Pm, rectifier_diode_horz: L0, rectifier_diode_vert: Rm, resistor_down: Em, resistor_left: Xm, resistor_right: Vm, resistor_up: km, resonator_down: Om, resonator_horz: M0, resonator_left: Jm, resonator_right: K, resonator_up: $m, resonator_vert: Mm, schottky_diode_down: Nm, schottky_diode_left: Im, schottky_diode_right: tt, schottky_diode_up: Bm, silicon_controlled_rectifier_horz: C0, silicon_controlled_rectifier_vert: Um, solderjumper2_bridged12_down: Gm, solderjumper2_bridged12_left: Wm, solderjumper2_bridged12_right: Hm, solderjumper2_bridged12_up: Zm, solderjumper2_down: Qm, solderjumper2_left: Km, solderjumper2_right: tn, solderjumper2_up: en, solderjumper3_bridged12_down: rn, solderjumper3_bridged12_left: on2, solderjumper3_bridged12_right: ln, solderjumper3_bridged12_up: pn, solderjumper3_bridged123_down: an, solderjumper3_bridged123_left: yn, solderjumper3_bridged123_right: xn, solderjumper3_bridged123_up: sn, solderjumper3_bridged23_down: mn, solderjumper3_bridged23_left: nn, solderjumper3_bridged23_right: fn, solderjumper3_bridged23_up: hn, solderjumper3_down: cn, solderjumper3_left: dn, solderjumper3_right: bn, solderjumper3_up: _n, spdt_normally_closed_switch_down: un, spdt_normally_closed_switch_left: vn, spdt_normally_closed_switch_right: at, spdt_normally_closed_switch_up: wn, spdt_switch_down: Pn, spdt_switch_left: Sn, spdt_switch_right: yt, spdt_switch_up: Fn, spst_normally_closed_switch_down: Rn, spst_normally_closed_switch_left: Tn, spst_normally_closed_switch_right: xt, spst_normally_closed_switch_up: En, spst_switch_down: Yn, spst_switch_left: Xn, spst_switch_right: st, spst_switch_up: Ln, square_wave_down: Vn, square_wave_left: jn, square_wave_right: kn, square_wave_up: zn, step_recovery_diode_horz: N0, step_recovery_diode_vert: On, tachometer_horz: Tt, tachometer_vert: Cn, testpoint_down: Bn, testpoint_left: qn, testpoint_right: nt, testpoint_up: Gn, tilted_ground_down: Hn, tilted_ground_left: Zn, tilted_ground_right: ut, tilted_ground_up: B0, triac_horz: q0, triac_vert: t1, tunnel_diode_horz: U0, tunnel_diode_vert: i1, unijunction_transistor_horz: W0, unijunction_transistor_vert: s1, usbc: n1, var_meter_horz: Z0, var_meter_vert: c1, varactor_diode_horz: K0, varactor_diode_vert: g1, varistor_horz: er, varistor_vert: A1, varmeter_horz: Et, varmeter_vert: R1, vcc_down: T1, vcc_left: E1, vcc_right: Y1, vcc_up: X1, volt_meter_horz: or, volt_meter_vert: L1, watt_hour_meter_horz: Yt, watt_hour_meter_vert: z1, wattmeter_horz: Xt, wattmeter_vert: M1, zener_diode_horz: ar, zener_diode_vert: B1 };
|
|
78778
79488
|
var Y$ = Object.fromEntries(Object.keys(q1).map((t3) => [t3, t3]));
|
|
78779
79489
|
function doesLineIntersectLine([a12, a22], [b12, b22], {
|
|
78780
79490
|
lineThickness = 0
|
|
@@ -80804,11 +81514,11 @@ var require_react_reconciler_development = __commonJS2({
|
|
|
80804
81514
|
fiber = fiber.next, id2--;
|
|
80805
81515
|
return fiber;
|
|
80806
81516
|
}
|
|
80807
|
-
function copyWithSetImpl(obj,
|
|
80808
|
-
if (index >=
|
|
81517
|
+
function copyWithSetImpl(obj, path25, index, value) {
|
|
81518
|
+
if (index >= path25.length)
|
|
80809
81519
|
return value;
|
|
80810
|
-
var key =
|
|
80811
|
-
updated[key] = copyWithSetImpl(obj[key],
|
|
81520
|
+
var key = path25[index], updated = isArrayImpl(obj) ? obj.slice() : assign2({}, obj);
|
|
81521
|
+
updated[key] = copyWithSetImpl(obj[key], path25, index + 1, value);
|
|
80812
81522
|
return updated;
|
|
80813
81523
|
}
|
|
80814
81524
|
function copyWithRename(obj, oldPath, newPath) {
|
|
@@ -80828,11 +81538,11 @@ var require_react_reconciler_development = __commonJS2({
|
|
|
80828
81538
|
index + 1 === oldPath.length ? (updated[newPath[index]] = updated[oldKey], isArrayImpl(updated) ? updated.splice(oldKey, 1) : delete updated[oldKey]) : updated[oldKey] = copyWithRenameImpl(obj[oldKey], oldPath, newPath, index + 1);
|
|
80829
81539
|
return updated;
|
|
80830
81540
|
}
|
|
80831
|
-
function copyWithDeleteImpl(obj,
|
|
80832
|
-
var key =
|
|
80833
|
-
if (index + 1 ===
|
|
81541
|
+
function copyWithDeleteImpl(obj, path25, index) {
|
|
81542
|
+
var key = path25[index], updated = isArrayImpl(obj) ? obj.slice() : assign2({}, obj);
|
|
81543
|
+
if (index + 1 === path25.length)
|
|
80834
81544
|
return isArrayImpl(updated) ? updated.splice(key, 1) : delete updated[key], updated;
|
|
80835
|
-
updated[key] = copyWithDeleteImpl(obj[key],
|
|
81545
|
+
updated[key] = copyWithDeleteImpl(obj[key], path25, index + 1);
|
|
80836
81546
|
return updated;
|
|
80837
81547
|
}
|
|
80838
81548
|
function shouldSuspendImpl() {
|
|
@@ -89863,29 +90573,29 @@ Check the top-level render call using <` + componentName2 + ">.");
|
|
|
89863
90573
|
var didWarnAboutNestedUpdates = false;
|
|
89864
90574
|
var didWarnAboutFindNodeInStrictMode = {};
|
|
89865
90575
|
var overrideHookState = null, overrideHookStateDeletePath = null, overrideHookStateRenamePath = null, overrideProps = null, overridePropsDeletePath = null, overridePropsRenamePath = null, scheduleUpdate = null, setErrorHandler = null, setSuspenseHandler = null;
|
|
89866
|
-
overrideHookState = function(fiber, id2,
|
|
90576
|
+
overrideHookState = function(fiber, id2, path25, value) {
|
|
89867
90577
|
id2 = findHook(fiber, id2);
|
|
89868
|
-
id2 !== null && (
|
|
90578
|
+
id2 !== null && (path25 = copyWithSetImpl(id2.memoizedState, path25, 0, value), id2.memoizedState = path25, id2.baseState = path25, fiber.memoizedProps = assign2({}, fiber.memoizedProps), path25 = enqueueConcurrentRenderForLane(fiber, 2), path25 !== null && scheduleUpdateOnFiber(path25, fiber, 2));
|
|
89869
90579
|
};
|
|
89870
|
-
overrideHookStateDeletePath = function(fiber, id2,
|
|
90580
|
+
overrideHookStateDeletePath = function(fiber, id2, path25) {
|
|
89871
90581
|
id2 = findHook(fiber, id2);
|
|
89872
|
-
id2 !== null && (
|
|
90582
|
+
id2 !== null && (path25 = copyWithDeleteImpl(id2.memoizedState, path25, 0), id2.memoizedState = path25, id2.baseState = path25, fiber.memoizedProps = assign2({}, fiber.memoizedProps), path25 = enqueueConcurrentRenderForLane(fiber, 2), path25 !== null && scheduleUpdateOnFiber(path25, fiber, 2));
|
|
89873
90583
|
};
|
|
89874
90584
|
overrideHookStateRenamePath = function(fiber, id2, oldPath, newPath) {
|
|
89875
90585
|
id2 = findHook(fiber, id2);
|
|
89876
90586
|
id2 !== null && (oldPath = copyWithRename(id2.memoizedState, oldPath, newPath), id2.memoizedState = oldPath, id2.baseState = oldPath, fiber.memoizedProps = assign2({}, fiber.memoizedProps), oldPath = enqueueConcurrentRenderForLane(fiber, 2), oldPath !== null && scheduleUpdateOnFiber(oldPath, fiber, 2));
|
|
89877
90587
|
};
|
|
89878
|
-
overrideProps = function(fiber,
|
|
89879
|
-
fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps,
|
|
90588
|
+
overrideProps = function(fiber, path25, value) {
|
|
90589
|
+
fiber.pendingProps = copyWithSetImpl(fiber.memoizedProps, path25, 0, value);
|
|
89880
90590
|
fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
|
|
89881
|
-
|
|
89882
|
-
|
|
90591
|
+
path25 = enqueueConcurrentRenderForLane(fiber, 2);
|
|
90592
|
+
path25 !== null && scheduleUpdateOnFiber(path25, fiber, 2);
|
|
89883
90593
|
};
|
|
89884
|
-
overridePropsDeletePath = function(fiber,
|
|
89885
|
-
fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps,
|
|
90594
|
+
overridePropsDeletePath = function(fiber, path25) {
|
|
90595
|
+
fiber.pendingProps = copyWithDeleteImpl(fiber.memoizedProps, path25, 0);
|
|
89886
90596
|
fiber.alternate && (fiber.alternate.pendingProps = fiber.pendingProps);
|
|
89887
|
-
|
|
89888
|
-
|
|
90597
|
+
path25 = enqueueConcurrentRenderForLane(fiber, 2);
|
|
90598
|
+
path25 !== null && scheduleUpdateOnFiber(path25, fiber, 2);
|
|
89889
90599
|
};
|
|
89890
90600
|
overridePropsRenamePath = function(fiber, oldPath, newPath) {
|
|
89891
90601
|
fiber.pendingProps = copyWithRename(fiber.memoizedProps, oldPath, newPath);
|
|
@@ -105222,10 +105932,10 @@ Check the render method of %s.`, getComponentNameFromFiber(current2) || "Unknown
|
|
|
105222
105932
|
var setErrorHandler = null;
|
|
105223
105933
|
var setSuspenseHandler = null;
|
|
105224
105934
|
{
|
|
105225
|
-
var copyWithDeleteImpl = function(obj,
|
|
105226
|
-
var key =
|
|
105935
|
+
var copyWithDeleteImpl = function(obj, path25, index2) {
|
|
105936
|
+
var key = path25[index2];
|
|
105227
105937
|
var updated = isArray2(obj) ? obj.slice() : assign2({}, obj);
|
|
105228
|
-
if (index2 + 1 ===
|
|
105938
|
+
if (index2 + 1 === path25.length) {
|
|
105229
105939
|
if (isArray2(updated)) {
|
|
105230
105940
|
updated.splice(key, 1);
|
|
105231
105941
|
} else {
|
|
@@ -105233,11 +105943,11 @@ Check the render method of %s.`, getComponentNameFromFiber(current2) || "Unknown
|
|
|
105233
105943
|
}
|
|
105234
105944
|
return updated;
|
|
105235
105945
|
}
|
|
105236
|
-
updated[key] = copyWithDeleteImpl(obj[key],
|
|
105946
|
+
updated[key] = copyWithDeleteImpl(obj[key], path25, index2 + 1);
|
|
105237
105947
|
return updated;
|
|
105238
105948
|
};
|
|
105239
|
-
var copyWithDelete = function(obj,
|
|
105240
|
-
return copyWithDeleteImpl(obj,
|
|
105949
|
+
var copyWithDelete = function(obj, path25) {
|
|
105950
|
+
return copyWithDeleteImpl(obj, path25, 0);
|
|
105241
105951
|
};
|
|
105242
105952
|
var copyWithRenameImpl = function(obj, oldPath, newPath, index2) {
|
|
105243
105953
|
var oldKey = oldPath[index2];
|
|
@@ -105269,17 +105979,17 @@ Check the render method of %s.`, getComponentNameFromFiber(current2) || "Unknown
|
|
|
105269
105979
|
}
|
|
105270
105980
|
return copyWithRenameImpl(obj, oldPath, newPath, 0);
|
|
105271
105981
|
};
|
|
105272
|
-
var copyWithSetImpl = function(obj,
|
|
105273
|
-
if (index2 >=
|
|
105982
|
+
var copyWithSetImpl = function(obj, path25, index2, value) {
|
|
105983
|
+
if (index2 >= path25.length) {
|
|
105274
105984
|
return value;
|
|
105275
105985
|
}
|
|
105276
|
-
var key =
|
|
105986
|
+
var key = path25[index2];
|
|
105277
105987
|
var updated = isArray2(obj) ? obj.slice() : assign2({}, obj);
|
|
105278
|
-
updated[key] = copyWithSetImpl(obj[key],
|
|
105988
|
+
updated[key] = copyWithSetImpl(obj[key], path25, index2 + 1, value);
|
|
105279
105989
|
return updated;
|
|
105280
105990
|
};
|
|
105281
|
-
var copyWithSet = function(obj,
|
|
105282
|
-
return copyWithSetImpl(obj,
|
|
105991
|
+
var copyWithSet = function(obj, path25, value) {
|
|
105992
|
+
return copyWithSetImpl(obj, path25, 0, value);
|
|
105283
105993
|
};
|
|
105284
105994
|
var findHook = function(fiber, id2) {
|
|
105285
105995
|
var currentHook2 = fiber.memoizedState;
|
|
@@ -105289,10 +105999,10 @@ Check the render method of %s.`, getComponentNameFromFiber(current2) || "Unknown
|
|
|
105289
105999
|
}
|
|
105290
106000
|
return currentHook2;
|
|
105291
106001
|
};
|
|
105292
|
-
overrideHookState = function(fiber, id2,
|
|
106002
|
+
overrideHookState = function(fiber, id2, path25, value) {
|
|
105293
106003
|
var hook = findHook(fiber, id2);
|
|
105294
106004
|
if (hook !== null) {
|
|
105295
|
-
var newState = copyWithSet(hook.memoizedState,
|
|
106005
|
+
var newState = copyWithSet(hook.memoizedState, path25, value);
|
|
105296
106006
|
hook.memoizedState = newState;
|
|
105297
106007
|
hook.baseState = newState;
|
|
105298
106008
|
fiber.memoizedProps = assign2({}, fiber.memoizedProps);
|
|
@@ -105302,10 +106012,10 @@ Check the render method of %s.`, getComponentNameFromFiber(current2) || "Unknown
|
|
|
105302
106012
|
}
|
|
105303
106013
|
}
|
|
105304
106014
|
};
|
|
105305
|
-
overrideHookStateDeletePath = function(fiber, id2,
|
|
106015
|
+
overrideHookStateDeletePath = function(fiber, id2, path25) {
|
|
105306
106016
|
var hook = findHook(fiber, id2);
|
|
105307
106017
|
if (hook !== null) {
|
|
105308
|
-
var newState = copyWithDelete(hook.memoizedState,
|
|
106018
|
+
var newState = copyWithDelete(hook.memoizedState, path25);
|
|
105309
106019
|
hook.memoizedState = newState;
|
|
105310
106020
|
hook.baseState = newState;
|
|
105311
106021
|
fiber.memoizedProps = assign2({}, fiber.memoizedProps);
|
|
@@ -105328,8 +106038,8 @@ Check the render method of %s.`, getComponentNameFromFiber(current2) || "Unknown
|
|
|
105328
106038
|
}
|
|
105329
106039
|
}
|
|
105330
106040
|
};
|
|
105331
|
-
overrideProps = function(fiber,
|
|
105332
|
-
fiber.pendingProps = copyWithSet(fiber.memoizedProps,
|
|
106041
|
+
overrideProps = function(fiber, path25, value) {
|
|
106042
|
+
fiber.pendingProps = copyWithSet(fiber.memoizedProps, path25, value);
|
|
105333
106043
|
if (fiber.alternate) {
|
|
105334
106044
|
fiber.alternate.pendingProps = fiber.pendingProps;
|
|
105335
106045
|
}
|
|
@@ -105338,8 +106048,8 @@ Check the render method of %s.`, getComponentNameFromFiber(current2) || "Unknown
|
|
|
105338
106048
|
scheduleUpdateOnFiber(root, fiber, SyncLane, NoTimestamp);
|
|
105339
106049
|
}
|
|
105340
106050
|
};
|
|
105341
|
-
overridePropsDeletePath = function(fiber,
|
|
105342
|
-
fiber.pendingProps = copyWithDelete(fiber.memoizedProps,
|
|
106051
|
+
overridePropsDeletePath = function(fiber, path25) {
|
|
106052
|
+
fiber.pendingProps = copyWithDelete(fiber.memoizedProps, path25);
|
|
105343
106053
|
if (fiber.alternate) {
|
|
105344
106054
|
fiber.alternate.pendingProps = fiber.pendingProps;
|
|
105345
106055
|
}
|
|
@@ -111390,7 +112100,7 @@ var parsePin = (pinString) => {
|
|
|
111390
112100
|
const colorMatch = pinString.match(/#[0-9A-F]{6}/);
|
|
111391
112101
|
const labelColor = colorMatch ? colorMatch[0] : "";
|
|
111392
112102
|
const pathMatch = pinString.match(/\^\^([^~]+)/);
|
|
111393
|
-
const
|
|
112103
|
+
const path25 = pathMatch ? pathMatch[1] : "";
|
|
111394
112104
|
const arrowMatch = pinString.match(/\^\^0~(.+)$/);
|
|
111395
112105
|
const arrow = arrowMatch ? arrowMatch[1] : "";
|
|
111396
112106
|
const r3 = Number.parseFloat(rotation2);
|
|
@@ -111404,7 +112114,7 @@ var parsePin = (pinString) => {
|
|
|
111404
112114
|
rotation: Number.isNaN(r3) ? 0 : r3,
|
|
111405
112115
|
label,
|
|
111406
112116
|
labelColor,
|
|
111407
|
-
path:
|
|
112117
|
+
path: path25,
|
|
111408
112118
|
arrow
|
|
111409
112119
|
};
|
|
111410
112120
|
};
|
|
@@ -111844,15 +112554,15 @@ function generateArcFromSweep(startX, startY, endX, endY, radius, largeArcFlag,
|
|
|
111844
112554
|
}
|
|
111845
112555
|
}
|
|
111846
112556
|
const numPoints = Math.max(2, Math.ceil(Math.abs(endAngle - startAngle) * radius));
|
|
111847
|
-
const
|
|
112557
|
+
const path25 = [];
|
|
111848
112558
|
for (let i = 0;i <= numPoints; i++) {
|
|
111849
112559
|
const t3 = i / numPoints;
|
|
111850
112560
|
const angle2 = startAngle + t3 * (endAngle - startAngle);
|
|
111851
112561
|
const x = centerX + radius * Math.cos(angle2);
|
|
111852
112562
|
const y = centerY + radius * Math.sin(angle2);
|
|
111853
|
-
|
|
112563
|
+
path25.push({ x, y });
|
|
111854
112564
|
}
|
|
111855
|
-
return
|
|
112565
|
+
return path25;
|
|
111856
112566
|
}
|
|
111857
112567
|
var __defProp4 = Object.defineProperty;
|
|
111858
112568
|
var __export22 = (target, all) => {
|
|
@@ -113270,7 +113980,7 @@ var platedHoleWithRectPad = (pn2, x, y, holeDiameter, rectPadWidth, rectPadHeigh
|
|
|
113270
113980
|
};
|
|
113271
113981
|
};
|
|
113272
113982
|
var silkscreenPin = ({
|
|
113273
|
-
fs:
|
|
113983
|
+
fs: fs26,
|
|
113274
113984
|
pn: pn2,
|
|
113275
113985
|
anchor_x,
|
|
113276
113986
|
anchor_y,
|
|
@@ -113313,7 +114023,7 @@ var silkscreenPin = ({
|
|
|
113313
114023
|
type: "pcb_silkscreen_text",
|
|
113314
114024
|
pcb_silkscreen_text_id: "silkscreen_text_1",
|
|
113315
114025
|
font: "tscircuit2024",
|
|
113316
|
-
font_size:
|
|
114026
|
+
font_size: fs26,
|
|
113317
114027
|
pcb_component_id: "pcb_component_1",
|
|
113318
114028
|
text: `{PIN${pn2}}`,
|
|
113319
114029
|
layer,
|
|
@@ -120929,17 +121639,17 @@ var ObstacleList = class {
|
|
|
120929
121639
|
return obstacles;
|
|
120930
121640
|
}
|
|
120931
121641
|
};
|
|
120932
|
-
function removePathLoops(
|
|
120933
|
-
if (
|
|
120934
|
-
return
|
|
120935
|
-
const result = [{ ...
|
|
120936
|
-
let currentLayer =
|
|
120937
|
-
for (let i = 1;i <
|
|
120938
|
-
const currentSegment = { start:
|
|
120939
|
-
const isVia =
|
|
120940
|
-
if (
|
|
120941
|
-
result.push({ ...
|
|
120942
|
-
currentLayer =
|
|
121642
|
+
function removePathLoops(path25) {
|
|
121643
|
+
if (path25.length < 4)
|
|
121644
|
+
return path25;
|
|
121645
|
+
const result = [{ ...path25[0] }];
|
|
121646
|
+
let currentLayer = path25[0].layer;
|
|
121647
|
+
for (let i = 1;i < path25.length; i++) {
|
|
121648
|
+
const currentSegment = { start: path25[i - 1], end: path25[i] };
|
|
121649
|
+
const isVia = path25[i].route_type === "via" || path25[i - 1].route_type === "via";
|
|
121650
|
+
if (path25[i].layer !== currentLayer || isVia) {
|
|
121651
|
+
result.push({ ...path25[i] });
|
|
121652
|
+
currentLayer = path25[i].layer;
|
|
120943
121653
|
continue;
|
|
120944
121654
|
}
|
|
120945
121655
|
let intersectionFound = false;
|
|
@@ -120968,8 +121678,8 @@ function removePathLoops(path23) {
|
|
|
120968
121678
|
result.push(intersectionPoint);
|
|
120969
121679
|
}
|
|
120970
121680
|
const lastPoint = result[result.length - 1];
|
|
120971
|
-
if (lastPoint.x !==
|
|
120972
|
-
result.push(
|
|
121681
|
+
if (lastPoint.x !== path25[i].x || lastPoint.y !== path25[i].y) {
|
|
121682
|
+
result.push(path25[i]);
|
|
120973
121683
|
}
|
|
120974
121684
|
}
|
|
120975
121685
|
return result;
|
|
@@ -121458,10 +122168,10 @@ var GeneralizedAstarAutorouter = class {
|
|
|
121458
122168
|
});
|
|
121459
122169
|
}
|
|
121460
122170
|
if (current2.parent) {
|
|
121461
|
-
const
|
|
122171
|
+
const path25 = [];
|
|
121462
122172
|
let p = current2;
|
|
121463
122173
|
while (p) {
|
|
121464
|
-
|
|
122174
|
+
path25.unshift(p);
|
|
121465
122175
|
p = p.parent;
|
|
121466
122176
|
}
|
|
121467
122177
|
debugSolution.push({
|
|
@@ -121469,7 +122179,7 @@ var GeneralizedAstarAutorouter = class {
|
|
|
121469
122179
|
pcb_component_id: "",
|
|
121470
122180
|
pcb_fabrication_note_path_id: `note_path_${current2.x}_${current2.y}`,
|
|
121471
122181
|
layer: "top",
|
|
121472
|
-
route:
|
|
122182
|
+
route: path25,
|
|
121473
122183
|
stroke_width: 0.01
|
|
121474
122184
|
});
|
|
121475
122185
|
}
|
|
@@ -126391,13 +127101,13 @@ var RBush = class {
|
|
|
126391
127101
|
return this;
|
|
126392
127102
|
let node = this.data;
|
|
126393
127103
|
const bbox = this.toBBox(item);
|
|
126394
|
-
const
|
|
127104
|
+
const path25 = [];
|
|
126395
127105
|
const indexes = [];
|
|
126396
127106
|
let i, parent, goingUp;
|
|
126397
|
-
while (node ||
|
|
127107
|
+
while (node || path25.length) {
|
|
126398
127108
|
if (!node) {
|
|
126399
|
-
node =
|
|
126400
|
-
parent =
|
|
127109
|
+
node = path25.pop();
|
|
127110
|
+
parent = path25[path25.length - 1];
|
|
126401
127111
|
i = indexes.pop();
|
|
126402
127112
|
goingUp = true;
|
|
126403
127113
|
}
|
|
@@ -126405,13 +127115,13 @@ var RBush = class {
|
|
|
126405
127115
|
const index = findItem(item, node.children, equalsFn);
|
|
126406
127116
|
if (index !== -1) {
|
|
126407
127117
|
node.children.splice(index, 1);
|
|
126408
|
-
|
|
126409
|
-
this._condense(
|
|
127118
|
+
path25.push(node);
|
|
127119
|
+
this._condense(path25);
|
|
126410
127120
|
return this;
|
|
126411
127121
|
}
|
|
126412
127122
|
}
|
|
126413
127123
|
if (!goingUp && !node.leaf && contains(node, bbox)) {
|
|
126414
|
-
|
|
127124
|
+
path25.push(node);
|
|
126415
127125
|
indexes.push(i);
|
|
126416
127126
|
i = 0;
|
|
126417
127127
|
parent = node;
|
|
@@ -126482,10 +127192,10 @@ var RBush = class {
|
|
|
126482
127192
|
calcBBox(node, this.toBBox);
|
|
126483
127193
|
return node;
|
|
126484
127194
|
}
|
|
126485
|
-
_chooseSubtree(bbox, node, level,
|
|
127195
|
+
_chooseSubtree(bbox, node, level, path25) {
|
|
126486
127196
|
while (true) {
|
|
126487
|
-
|
|
126488
|
-
if (node.leaf ||
|
|
127197
|
+
path25.push(node);
|
|
127198
|
+
if (node.leaf || path25.length - 1 === level)
|
|
126489
127199
|
break;
|
|
126490
127200
|
let minArea = Infinity;
|
|
126491
127201
|
let minEnlargement = Infinity;
|
|
@@ -126594,21 +127304,21 @@ var RBush = class {
|
|
|
126594
127304
|
}
|
|
126595
127305
|
return margin;
|
|
126596
127306
|
}
|
|
126597
|
-
_adjustParentBBoxes(bbox,
|
|
127307
|
+
_adjustParentBBoxes(bbox, path25, level) {
|
|
126598
127308
|
for (let i = level;i >= 0; i--) {
|
|
126599
|
-
extend(
|
|
127309
|
+
extend(path25[i], bbox);
|
|
126600
127310
|
}
|
|
126601
127311
|
}
|
|
126602
|
-
_condense(
|
|
126603
|
-
for (let i =
|
|
126604
|
-
if (
|
|
127312
|
+
_condense(path25) {
|
|
127313
|
+
for (let i = path25.length - 1, siblings;i >= 0; i--) {
|
|
127314
|
+
if (path25[i].children.length === 0) {
|
|
126605
127315
|
if (i > 0) {
|
|
126606
|
-
siblings =
|
|
126607
|
-
siblings.splice(siblings.indexOf(
|
|
127316
|
+
siblings = path25[i - 1].children;
|
|
127317
|
+
siblings.splice(siblings.indexOf(path25[i]), 1);
|
|
126608
127318
|
} else
|
|
126609
127319
|
this.clear();
|
|
126610
127320
|
} else
|
|
126611
|
-
calcBBox(
|
|
127321
|
+
calcBBox(path25[i], this.toBBox);
|
|
126612
127322
|
}
|
|
126613
127323
|
}
|
|
126614
127324
|
};
|
|
@@ -127753,7 +128463,7 @@ var CapacityEdgeToPortSegmentSolver = class extends BaseSolver {
|
|
|
127753
128463
|
this.capacityPaths = capacityPaths;
|
|
127754
128464
|
this.colorMap = colorMap ?? {};
|
|
127755
128465
|
this.unprocessedNodeIds = [
|
|
127756
|
-
...new Set(capacityPaths.flatMap((
|
|
128466
|
+
...new Set(capacityPaths.flatMap((path25) => path25.nodeIds))
|
|
127757
128467
|
];
|
|
127758
128468
|
this.nodePortSegments = /* @__PURE__ */ new Map;
|
|
127759
128469
|
}
|
|
@@ -127764,17 +128474,17 @@ var CapacityEdgeToPortSegmentSolver = class extends BaseSolver {
|
|
|
127764
128474
|
return;
|
|
127765
128475
|
}
|
|
127766
128476
|
const pathsGoingThroughNode = [];
|
|
127767
|
-
for (const
|
|
127768
|
-
const indexOfNodeInPath =
|
|
128477
|
+
for (const path25 of this.capacityPaths) {
|
|
128478
|
+
const indexOfNodeInPath = path25.nodeIds.indexOf(nodeId);
|
|
127769
128479
|
if (indexOfNodeInPath !== -1) {
|
|
127770
|
-
pathsGoingThroughNode.push({ path:
|
|
128480
|
+
pathsGoingThroughNode.push({ path: path25, indexOfNodeInPath });
|
|
127771
128481
|
}
|
|
127772
128482
|
}
|
|
127773
128483
|
const node = this.nodeMap.get(nodeId);
|
|
127774
128484
|
const nodePortSegments = [];
|
|
127775
|
-
for (const { path:
|
|
127776
|
-
const entryNodeId =
|
|
127777
|
-
const exitNodeId =
|
|
128485
|
+
for (const { path: path25, indexOfNodeInPath } of pathsGoingThroughNode) {
|
|
128486
|
+
const entryNodeId = path25.nodeIds[indexOfNodeInPath - 1];
|
|
128487
|
+
const exitNodeId = path25.nodeIds[indexOfNodeInPath + 1];
|
|
127778
128488
|
for (const adjNodeId of [entryNodeId, exitNodeId]) {
|
|
127779
128489
|
const adjNode = this.nodeMap.get(adjNodeId);
|
|
127780
128490
|
if (!adjNode)
|
|
@@ -127787,7 +128497,7 @@ var CapacityEdgeToPortSegmentSolver = class extends BaseSolver {
|
|
|
127787
128497
|
capacityMeshNodeId: nodeId,
|
|
127788
128498
|
start: segment2.start,
|
|
127789
128499
|
end: segment2.end,
|
|
127790
|
-
connectionNames: [
|
|
128500
|
+
connectionNames: [path25.connectionName],
|
|
127791
128501
|
availableZ: mutuallyAvailableZ
|
|
127792
128502
|
};
|
|
127793
128503
|
nodePortSegments.push(portSegment);
|
|
@@ -128593,37 +129303,37 @@ var SingleHighDensityRouteSolver = class extends BaseSolver {
|
|
|
128593
129303
|
return neighbors;
|
|
128594
129304
|
}
|
|
128595
129305
|
getNodePath(node) {
|
|
128596
|
-
const
|
|
129306
|
+
const path25 = [];
|
|
128597
129307
|
while (node) {
|
|
128598
|
-
|
|
129308
|
+
path25.push(node);
|
|
128599
129309
|
node = node.parent;
|
|
128600
129310
|
}
|
|
128601
|
-
return
|
|
129311
|
+
return path25;
|
|
128602
129312
|
}
|
|
128603
129313
|
getViasInNodePath(node) {
|
|
128604
|
-
const
|
|
129314
|
+
const path25 = this.getNodePath(node);
|
|
128605
129315
|
const vias = [];
|
|
128606
|
-
for (let i = 0;i <
|
|
128607
|
-
if (
|
|
128608
|
-
vias.push({ x:
|
|
129316
|
+
for (let i = 0;i < path25.length - 1; i++) {
|
|
129317
|
+
if (path25[i].z !== path25[i + 1].z) {
|
|
129318
|
+
vias.push({ x: path25[i].x, y: path25[i].y });
|
|
128609
129319
|
}
|
|
128610
129320
|
}
|
|
128611
129321
|
return vias;
|
|
128612
129322
|
}
|
|
128613
129323
|
setSolvedPath(node) {
|
|
128614
|
-
const
|
|
128615
|
-
|
|
129324
|
+
const path25 = this.getNodePath(node);
|
|
129325
|
+
path25.reverse();
|
|
128616
129326
|
const vias = [];
|
|
128617
|
-
for (let i = 0;i <
|
|
128618
|
-
if (
|
|
128619
|
-
vias.push({ x:
|
|
129327
|
+
for (let i = 0;i < path25.length - 1; i++) {
|
|
129328
|
+
if (path25[i].z !== path25[i + 1].z) {
|
|
129329
|
+
vias.push({ x: path25[i].x, y: path25[i].y });
|
|
128620
129330
|
}
|
|
128621
129331
|
}
|
|
128622
129332
|
this.solvedPath = {
|
|
128623
129333
|
connectionName: this.connectionName,
|
|
128624
129334
|
traceThickness: this.traceThickness,
|
|
128625
129335
|
viaDiameter: this.viaDiameter,
|
|
128626
|
-
route:
|
|
129336
|
+
route: path25.map((node2) => ({ x: node2.x, y: node2.y, z: node2.z })).concat([this.B]),
|
|
128627
129337
|
vias
|
|
128628
129338
|
};
|
|
128629
129339
|
}
|
|
@@ -129362,14 +130072,14 @@ function computeDumbbellPaths({
|
|
|
129362
130072
|
const u3 = (dx2 * d1y - dy2 * d1x) / det;
|
|
129363
130073
|
return t3 > 0 && t3 < 1 && u3 > 0 && u3 < 1;
|
|
129364
130074
|
};
|
|
129365
|
-
const doPathsIntersect = (path1,
|
|
130075
|
+
const doPathsIntersect = (path1, path25) => {
|
|
129366
130076
|
const segments1 = [];
|
|
129367
130077
|
for (let i = 0;i < path1.length - 1; i++) {
|
|
129368
130078
|
segments1.push({ start: path1[i], end: path1[i + 1] });
|
|
129369
130079
|
}
|
|
129370
130080
|
const segments2 = [];
|
|
129371
|
-
for (let i = 0;i <
|
|
129372
|
-
segments2.push({ start:
|
|
130081
|
+
for (let i = 0;i < path25.length - 1; i++) {
|
|
130082
|
+
segments2.push({ start: path25[i], end: path25[i + 1] });
|
|
129373
130083
|
}
|
|
129374
130084
|
for (const seg1 of segments1) {
|
|
129375
130085
|
for (const seg2 of segments2) {
|
|
@@ -129431,12 +130141,12 @@ function computeDumbbellPaths({
|
|
|
129431
130141
|
specialType: circleCenter === A3 ? "A" : "B"
|
|
129432
130142
|
};
|
|
129433
130143
|
};
|
|
129434
|
-
const subdivideOptimalPath = (
|
|
129435
|
-
if (
|
|
129436
|
-
return
|
|
129437
|
-
const result = [
|
|
129438
|
-
for (let i = 0;i <
|
|
129439
|
-
const segment2 = { start:
|
|
130144
|
+
const subdivideOptimalPath = (path25, numSubdivisions) => {
|
|
130145
|
+
if (path25.length < 2)
|
|
130146
|
+
return path25;
|
|
130147
|
+
const result = [path25[0]];
|
|
130148
|
+
for (let i = 0;i < path25.length - 1; i++) {
|
|
130149
|
+
const segment2 = { start: path25[i], end: path25[i + 1] };
|
|
129440
130150
|
const segmentMidpoint = {
|
|
129441
130151
|
x: (segment2.start.x + segment2.end.x) / 2,
|
|
129442
130152
|
y: (segment2.start.y + segment2.end.y) / 2
|
|
@@ -129498,7 +130208,7 @@ function computeDumbbellPaths({
|
|
|
129498
130208
|
}
|
|
129499
130209
|
subdivisionPoints.forEach((p) => result.push(p));
|
|
129500
130210
|
}
|
|
129501
|
-
result.push(
|
|
130211
|
+
result.push(path25[i + 1]);
|
|
129502
130212
|
}
|
|
129503
130213
|
if (result.length > 1) {
|
|
129504
130214
|
const filteredResult = [result[0]];
|
|
@@ -129733,13 +130443,13 @@ function computeDumbbellPaths({
|
|
|
129733
130443
|
].map((l, index) => ({ ...l, index }));
|
|
129734
130444
|
};
|
|
129735
130445
|
const subdivideJLinePath = (jLine, oppositePoint, r3, m2, numSubdivisions) => {
|
|
129736
|
-
const
|
|
129737
|
-
if (
|
|
129738
|
-
return
|
|
130446
|
+
const path25 = jLine.points;
|
|
130447
|
+
if (path25.length < 2)
|
|
130448
|
+
return path25;
|
|
129739
130449
|
const minDistThreshold = r3 + m2;
|
|
129740
|
-
const result = [
|
|
129741
|
-
for (let i = 0;i <
|
|
129742
|
-
const segment2 = { start:
|
|
130450
|
+
const result = [path25[0]];
|
|
130451
|
+
for (let i = 0;i < path25.length - 1; i++) {
|
|
130452
|
+
const segment2 = { start: path25[i], end: path25[i + 1] };
|
|
129743
130453
|
const distToOpposite = pointToSegmentDistance22(oppositePoint, segment2.start, segment2.end);
|
|
129744
130454
|
if (distToOpposite < minDistThreshold) {
|
|
129745
130455
|
const closestPt = closestPointOnSegment(segment2, oppositePoint);
|
|
@@ -129789,18 +130499,18 @@ function computeDumbbellPaths({
|
|
|
129789
130499
|
const paths = getPaths();
|
|
129790
130500
|
const validPaths = [];
|
|
129791
130501
|
for (let i = 0;i < paths.length; i++) {
|
|
129792
|
-
const
|
|
129793
|
-
const firstSeg = { start:
|
|
130502
|
+
const path26 = paths[i];
|
|
130503
|
+
const firstSeg = { start: path26[0], end: path26[1] };
|
|
129794
130504
|
const lastSeg = {
|
|
129795
|
-
start:
|
|
129796
|
-
end:
|
|
130505
|
+
start: path26[path26.length - 2],
|
|
130506
|
+
end: path26[path26.length - 1]
|
|
129797
130507
|
};
|
|
129798
|
-
const midSeg = { start:
|
|
130508
|
+
const midSeg = { start: path26[3], end: path26[4] };
|
|
129799
130509
|
if (!intersect2(firstSeg, lastSeg) && !intersect2(firstSeg, midSeg) && !intersect2(lastSeg, midSeg)) {
|
|
129800
130510
|
validPaths.push({
|
|
129801
130511
|
index: i + 1,
|
|
129802
|
-
path:
|
|
129803
|
-
length: pathLength(
|
|
130512
|
+
path: path26,
|
|
130513
|
+
length: pathLength(path26)
|
|
129804
130514
|
});
|
|
129805
130515
|
}
|
|
129806
130516
|
}
|
|
@@ -129808,26 +130518,26 @@ function computeDumbbellPaths({
|
|
|
129808
130518
|
return { index: 0, path: [] };
|
|
129809
130519
|
}
|
|
129810
130520
|
const optimalPath2 = validPaths.sort((a, b3) => a.length - b3.length)[0];
|
|
129811
|
-
const
|
|
129812
|
-
const firstPoint =
|
|
129813
|
-
const dist3 = distance3(firstPoint,
|
|
129814
|
-
const dist4 = distance3(firstPoint,
|
|
130521
|
+
const path25 = [...optimalPath2.path];
|
|
130522
|
+
const firstPoint = path25[0];
|
|
130523
|
+
const dist3 = distance3(firstPoint, path25[2]);
|
|
130524
|
+
const dist4 = distance3(firstPoint, path25[3]);
|
|
129815
130525
|
const closerIdx = dist3 < dist4 ? 2 : 3;
|
|
129816
|
-
if (dist3 < distance3(firstPoint,
|
|
129817
|
-
|
|
130526
|
+
if (dist3 < distance3(firstPoint, path25[1]) || dist4 < distance3(firstPoint, path25[1])) {
|
|
130527
|
+
path25.splice(1, closerIdx - 1);
|
|
129818
130528
|
}
|
|
129819
|
-
const lastPoint =
|
|
129820
|
-
const distM3 = distance3(lastPoint,
|
|
129821
|
-
const distM4 = distance3(lastPoint,
|
|
129822
|
-
const closerLastIdx = distM3 < distM4 ?
|
|
129823
|
-
if (distM3 < distance3(lastPoint,
|
|
129824
|
-
|
|
130529
|
+
const lastPoint = path25[path25.length - 1];
|
|
130530
|
+
const distM3 = distance3(lastPoint, path25[path25.length - 3]);
|
|
130531
|
+
const distM4 = distance3(lastPoint, path25[path25.length - 4]);
|
|
130532
|
+
const closerLastIdx = distM3 < distM4 ? path25.length - 3 : path25.length - 4;
|
|
130533
|
+
if (distM3 < distance3(lastPoint, path25[path25.length - 2]) || distM4 < distance3(lastPoint, path25[path25.length - 2])) {
|
|
130534
|
+
path25.splice(closerLastIdx + 1, path25.length - closerLastIdx - 2);
|
|
129825
130535
|
}
|
|
129826
130536
|
return {
|
|
129827
130537
|
index: optimalPath2.index,
|
|
129828
|
-
path:
|
|
129829
|
-
startsAt:
|
|
129830
|
-
goesTo:
|
|
130538
|
+
path: path25,
|
|
130539
|
+
startsAt: path25[0] === C2 ? "C" : "D",
|
|
130540
|
+
goesTo: path25[path25.length - 1] === C2 ? "C" : "D"
|
|
129831
130541
|
};
|
|
129832
130542
|
};
|
|
129833
130543
|
const optimalPath = findOptimalPath();
|
|
@@ -131247,9 +131957,9 @@ var ViaPossibilitiesSolver2 = class extends BaseSolver {
|
|
|
131247
131957
|
let closestIntersection = null;
|
|
131248
131958
|
let intersectedSegmentZ = null;
|
|
131249
131959
|
const checkIntersectionsWithPathMap = (pathMap) => {
|
|
131250
|
-
for (const
|
|
131251
|
-
for (let i = 0;i <
|
|
131252
|
-
const segment2 = [
|
|
131960
|
+
for (const path25 of pathMap.values()) {
|
|
131961
|
+
for (let i = 0;i < path25.length - 1; i++) {
|
|
131962
|
+
const segment2 = [path25[i], path25[i + 1]];
|
|
131253
131963
|
if (segment2[0].x === segment2[1].x && segment2[0].y === segment2[1].y) {
|
|
131254
131964
|
continue;
|
|
131255
131965
|
}
|
|
@@ -131379,11 +132089,11 @@ var ViaPossibilitiesSolver2 = class extends BaseSolver {
|
|
|
131379
132089
|
});
|
|
131380
132090
|
}
|
|
131381
132091
|
const drawPath = (pathMap, labelPrefix) => {
|
|
131382
|
-
for (const [connectionName,
|
|
132092
|
+
for (const [connectionName, path25] of pathMap.entries()) {
|
|
131383
132093
|
const color = colorMap[connectionName] ?? "black";
|
|
131384
|
-
for (let i = 0;i <
|
|
131385
|
-
const p12 =
|
|
131386
|
-
const p2 =
|
|
132094
|
+
for (let i = 0;i < path25.length - 1; i++) {
|
|
132095
|
+
const p12 = path25[i];
|
|
132096
|
+
const p2 = path25[i + 1];
|
|
131387
132097
|
if (p12.x === p2.x && p12.y === p2.y && p12.z !== p2.z) {
|
|
131388
132098
|
graphics.circles.push({
|
|
131389
132099
|
center: { x: p12.x, y: p12.y },
|
|
@@ -131981,10 +132691,10 @@ function detectMultiConnectionClosedFacesWithoutVias(polyLines, bounds) {
|
|
|
131981
132691
|
const allSegments = [];
|
|
131982
132692
|
const viaPoints = /* @__PURE__ */ new Map;
|
|
131983
132693
|
for (const polyLine of polyLines) {
|
|
131984
|
-
const
|
|
131985
|
-
for (let i = 0;i <
|
|
131986
|
-
const p12 =
|
|
131987
|
-
const p2 =
|
|
132694
|
+
const path25 = [polyLine.start, ...polyLine.mPoints, polyLine.end];
|
|
132695
|
+
for (let i = 0;i < path25.length - 1; i++) {
|
|
132696
|
+
const p12 = path25[i];
|
|
132697
|
+
const p2 = path25[i + 1];
|
|
131988
132698
|
const layer = p12.z2;
|
|
131989
132699
|
allSegments.push({
|
|
131990
132700
|
start: { x: p12.x, y: p12.y },
|
|
@@ -132002,7 +132712,7 @@ function detectMultiConnectionClosedFacesWithoutVias(polyLines, bounds) {
|
|
|
132002
132712
|
}
|
|
132003
132713
|
}
|
|
132004
132714
|
}
|
|
132005
|
-
const lastPoint =
|
|
132715
|
+
const lastPoint = path25[path25.length - 1];
|
|
132006
132716
|
if (lastPoint.z1 !== lastPoint.z2) {
|
|
132007
132717
|
const key = pointKey2(lastPoint);
|
|
132008
132718
|
if (!viaPoints.has(key)) {
|
|
@@ -132301,14 +133011,14 @@ var MultiHeadPolyLineIntraNodeSolver = class extends BaseSolver {
|
|
|
132301
133011
|
const polyLineVias = [];
|
|
132302
133012
|
for (let i = 0;i < polyLines.length; i++) {
|
|
132303
133013
|
const polyLine = polyLines[i];
|
|
132304
|
-
const
|
|
133014
|
+
const path25 = [polyLine.start, ...polyLine.mPoints, polyLine.end];
|
|
132305
133015
|
const segmentsByLayer = new Map(this.availableZ.map((z852) => [z852, []]));
|
|
132306
|
-
for (let i22 = 0;i22 <
|
|
132307
|
-
const segment2 = [
|
|
133016
|
+
for (let i22 = 0;i22 < path25.length - 1; i22++) {
|
|
133017
|
+
const segment2 = [path25[i22], path25[i22 + 1]];
|
|
132308
133018
|
segmentsByLayer.get(segment2[0].z2).push(segment2);
|
|
132309
133019
|
}
|
|
132310
133020
|
polyLineSegmentsByLayer.push(segmentsByLayer);
|
|
132311
|
-
polyLineVias.push(
|
|
133021
|
+
polyLineVias.push(path25.filter((p) => p.z1 !== p.z2));
|
|
132312
133022
|
}
|
|
132313
133023
|
for (let i = 0;i < polyLines.length; i++) {
|
|
132314
133024
|
const path1SegmentsByLayer = polyLineSegmentsByLayer[i];
|
|
@@ -133737,7 +134447,7 @@ var HighDensitySolver = class extends BaseSolver {
|
|
|
133737
134447
|
if (this.failedSolvers.length > 0) {
|
|
133738
134448
|
this.solved = false;
|
|
133739
134449
|
this.failed = true;
|
|
133740
|
-
this.error = `Failed to solve ${this.failedSolvers.length} nodes, ${this.failedSolvers.slice(0, 5).map((
|
|
134450
|
+
this.error = `Failed to solve ${this.failedSolvers.length} nodes, ${this.failedSolvers.slice(0, 5).map((fs26) => fs26.nodeWithPortPoints.capacityMeshNodeId)}. err0: ${this.failedSolvers[0].error}.`;
|
|
133741
134451
|
return;
|
|
133742
134452
|
}
|
|
133743
134453
|
this.solved = true;
|
|
@@ -136518,13 +137228,13 @@ var CapacityPathingSolver = class extends BaseSolver {
|
|
|
136518
137228
|
return this.getDistanceBetweenNodes(node, endGoal);
|
|
136519
137229
|
}
|
|
136520
137230
|
getBacktrackedPath(candidate) {
|
|
136521
|
-
const
|
|
137231
|
+
const path25 = [];
|
|
136522
137232
|
let currentCandidate = candidate;
|
|
136523
137233
|
while (currentCandidate) {
|
|
136524
|
-
|
|
137234
|
+
path25.push(currentCandidate.node);
|
|
136525
137235
|
currentCandidate = currentCandidate.prevCandidate;
|
|
136526
137236
|
}
|
|
136527
|
-
return
|
|
137237
|
+
return path25;
|
|
136528
137238
|
}
|
|
136529
137239
|
getNeighboringNodes(node) {
|
|
136530
137240
|
return this.nodeEdgeMap.get(node.capacityMeshNodeId).flatMap((edge) => edge.nodeIds.filter((n3) => n3 !== node.capacityMeshNodeId)).map((n3) => this.nodeMap.get(n3));
|
|
@@ -136532,12 +137242,12 @@ var CapacityPathingSolver = class extends BaseSolver {
|
|
|
136532
137242
|
getCapacityPaths() {
|
|
136533
137243
|
const capacityPaths = [];
|
|
136534
137244
|
for (const connection of this.connectionsWithNodes) {
|
|
136535
|
-
const
|
|
136536
|
-
if (
|
|
137245
|
+
const path25 = connection.path;
|
|
137246
|
+
if (path25) {
|
|
136537
137247
|
capacityPaths.push({
|
|
136538
137248
|
capacityPathId: connection.connection.name,
|
|
136539
137249
|
connectionName: connection.connection.name,
|
|
136540
|
-
nodeIds:
|
|
137250
|
+
nodeIds: path25.map((node) => node.capacityMeshNodeId)
|
|
136541
137251
|
});
|
|
136542
137252
|
}
|
|
136543
137253
|
}
|
|
@@ -137222,10 +137932,10 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
|
|
|
137222
137932
|
return this.getDistanceBetweenNodes(node, endGoal) + this.getNodeCapacityPenalty(node);
|
|
137223
137933
|
}
|
|
137224
137934
|
getBacktrackedPath(candidate) {
|
|
137225
|
-
const
|
|
137935
|
+
const path25 = [];
|
|
137226
137936
|
let currentCandidate = candidate;
|
|
137227
137937
|
while (currentCandidate) {
|
|
137228
|
-
|
|
137938
|
+
path25.push(currentCandidate.node);
|
|
137229
137939
|
if (this.nodeMap.has(currentCandidate.node.capacityMeshNodeId)) {
|
|
137230
137940
|
currentCandidate = currentCandidate.prevCandidate;
|
|
137231
137941
|
} else {
|
|
@@ -137233,7 +137943,7 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
|
|
|
137233
137943
|
break;
|
|
137234
137944
|
}
|
|
137235
137945
|
}
|
|
137236
|
-
return
|
|
137946
|
+
return path25.reverse();
|
|
137237
137947
|
}
|
|
137238
137948
|
getNeighboringNodes(node) {
|
|
137239
137949
|
if (!this.nodeMap.has(node.capacityMeshNodeId))
|
|
@@ -137248,8 +137958,8 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
|
|
|
137248
137958
|
doesNodeHaveCapacityForTrace(node, prevNode) {
|
|
137249
137959
|
return true;
|
|
137250
137960
|
}
|
|
137251
|
-
reduceCapacityAlongPath(
|
|
137252
|
-
for (const pathNode of
|
|
137961
|
+
reduceCapacityAlongPath(path25) {
|
|
137962
|
+
for (const pathNode of path25) {
|
|
137253
137963
|
if (this.usedNodeCapacityMap.has(pathNode.capacityMeshNodeId)) {
|
|
137254
137964
|
const nodeId = pathNode.capacityMeshNodeId;
|
|
137255
137965
|
const nodeInSection = this.nodeMap.get(nodeId);
|
|
@@ -137378,9 +138088,9 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
|
|
|
137378
138088
|
this.queuedNodes = null;
|
|
137379
138089
|
}
|
|
137380
138090
|
_handleGoalReached(currentCandidate, currentTerminal, endNode) {
|
|
137381
|
-
const
|
|
137382
|
-
currentTerminal.path =
|
|
137383
|
-
this.reduceCapacityAlongPath(
|
|
138091
|
+
const path25 = this.getBacktrackedPath(currentCandidate);
|
|
138092
|
+
currentTerminal.path = path25;
|
|
138093
|
+
this.reduceCapacityAlongPath(path25);
|
|
137384
138094
|
this.currentConnectionIndex++;
|
|
137385
138095
|
this.candidates = null;
|
|
137386
138096
|
this.visitedNodes = null;
|
|
@@ -137429,10 +138139,10 @@ var CapacityPathingSingleSectionSolver = class extends BaseSolver {
|
|
|
137429
138139
|
const connectionColor = this.colorMap[connectionName] ?? "purple";
|
|
137430
138140
|
topCandidates.forEach((candidate, index) => {
|
|
137431
138141
|
const opacity = 0.8 * (1 - index / 5);
|
|
137432
|
-
const
|
|
137433
|
-
if (
|
|
138142
|
+
const path25 = this.getBacktrackedPath(candidate);
|
|
138143
|
+
if (path25.length > 0) {
|
|
137434
138144
|
baseGraphics.lines.push({
|
|
137435
|
-
points:
|
|
138145
|
+
points: path25.map(({ center: { x, y } }) => ({ x, y })),
|
|
137436
138146
|
strokeColor: safeTransparentize(connectionColor, 1 - opacity),
|
|
137437
138147
|
strokeWidth: 0.05
|
|
137438
138148
|
});
|
|
@@ -138121,12 +138831,12 @@ var CapacityPathingMultiSectionSolver = class extends BaseSolver {
|
|
|
138121
138831
|
getCapacityPaths() {
|
|
138122
138832
|
const capacityPaths = [];
|
|
138123
138833
|
for (const connection of this.connectionsWithNodes) {
|
|
138124
|
-
const
|
|
138125
|
-
if (
|
|
138834
|
+
const path25 = connection.path;
|
|
138835
|
+
if (path25) {
|
|
138126
138836
|
capacityPaths.push({
|
|
138127
138837
|
capacityPathId: connection.connection.name,
|
|
138128
138838
|
connectionName: connection.connection.name,
|
|
138129
|
-
nodeIds:
|
|
138839
|
+
nodeIds: path25.map((node) => node.capacityMeshNodeId)
|
|
138130
138840
|
});
|
|
138131
138841
|
}
|
|
138132
138842
|
}
|
|
@@ -139147,22 +139857,22 @@ var SingleSimplifiedPathSolver5 = class extends SingleSimplifiedPathSolver {
|
|
|
139147
139857
|
return null;
|
|
139148
139858
|
}
|
|
139149
139859
|
const possiblePaths = calculate45DegreePaths({ x: start.x, y: start.y }, { x: end.x, y: end.y });
|
|
139150
|
-
for (const
|
|
139151
|
-
const fullPath =
|
|
139860
|
+
for (const path25 of possiblePaths) {
|
|
139861
|
+
const fullPath = path25.map((p) => ({ x: p.x, y: p.y, z: start.z }));
|
|
139152
139862
|
if (this.isValidPath(fullPath)) {
|
|
139153
139863
|
return fullPath;
|
|
139154
139864
|
}
|
|
139155
139865
|
}
|
|
139156
139866
|
return null;
|
|
139157
139867
|
}
|
|
139158
|
-
addPathToResult(
|
|
139159
|
-
if (
|
|
139868
|
+
addPathToResult(path25) {
|
|
139869
|
+
if (path25.length === 0)
|
|
139160
139870
|
return;
|
|
139161
|
-
for (let i = 0;i <
|
|
139162
|
-
if (i === 0 && this.newRoute.length > 0 && this.arePointsEqual(this.newRoute[this.newRoute.length - 1],
|
|
139871
|
+
for (let i = 0;i < path25.length; i++) {
|
|
139872
|
+
if (i === 0 && this.newRoute.length > 0 && this.arePointsEqual(this.newRoute[this.newRoute.length - 1], path25[i])) {
|
|
139163
139873
|
continue;
|
|
139164
139874
|
}
|
|
139165
|
-
this.newRoute.push(
|
|
139875
|
+
this.newRoute.push(path25[i]);
|
|
139166
139876
|
}
|
|
139167
139877
|
this.currentStepSize = this.maxStepSize;
|
|
139168
139878
|
}
|
|
@@ -166569,7 +167279,7 @@ var Trace_doInitialSchematicTraceRender = (trace) => {
|
|
|
166569
167279
|
for (let i = 0;i < portsWithPosition.length - 1; i++) {
|
|
166570
167280
|
const start = portsWithPosition[i];
|
|
166571
167281
|
const end = portsWithPosition[i + 1];
|
|
166572
|
-
const
|
|
167282
|
+
const path25 = calculateElbow({
|
|
166573
167283
|
x: start.position.x,
|
|
166574
167284
|
y: start.position.y,
|
|
166575
167285
|
facingDirection: convertFacingDirectionToElbowDirection(start.facingDirection)
|
|
@@ -166578,8 +167288,8 @@ var Trace_doInitialSchematicTraceRender = (trace) => {
|
|
|
166578
167288
|
y: end.position.y,
|
|
166579
167289
|
facingDirection: convertFacingDirectionToElbowDirection(end.facingDirection)
|
|
166580
167290
|
});
|
|
166581
|
-
for (let j4 = 0;j4 <
|
|
166582
|
-
elbowEdges.push({ from:
|
|
167291
|
+
for (let j4 = 0;j4 < path25.length - 1; j4++) {
|
|
167292
|
+
elbowEdges.push({ from: path25[j4], to: path25[j4 + 1] });
|
|
166583
167293
|
}
|
|
166584
167294
|
}
|
|
166585
167295
|
const doesSegmentIntersectRect = (edge, rect) => {
|
|
@@ -172767,8 +173477,8 @@ react/cjs/react-jsx-runtime.development.js:
|
|
|
172767
173477
|
*/
|
|
172768
173478
|
|
|
172769
173479
|
// lib/import/import-component-from-jlcpcb.ts
|
|
172770
|
-
import
|
|
172771
|
-
import
|
|
173480
|
+
import fs26 from "node:fs/promises";
|
|
173481
|
+
import path25 from "node:path";
|
|
172772
173482
|
var importComponentFromJlcpcb = async (jlcpcbPartNumber, projectDir = process.cwd()) => {
|
|
172773
173483
|
const component = await fetchEasyEDAComponent(jlcpcbPartNumber);
|
|
172774
173484
|
const tsx = await convertRawEasyToTsx(component);
|
|
@@ -172776,10 +173486,10 @@ var importComponentFromJlcpcb = async (jlcpcbPartNumber, projectDir = process.cw
|
|
|
172776
173486
|
if (!fileName) {
|
|
172777
173487
|
throw new Error("Could not determine file name of converted component");
|
|
172778
173488
|
}
|
|
172779
|
-
const importsDir =
|
|
172780
|
-
await
|
|
172781
|
-
const filePath =
|
|
172782
|
-
await
|
|
173489
|
+
const importsDir = path25.join(projectDir, "imports");
|
|
173490
|
+
await fs26.mkdir(importsDir, { recursive: true });
|
|
173491
|
+
const filePath = path25.join(importsDir, `${fileName}.tsx`);
|
|
173492
|
+
await fs26.writeFile(filePath, tsx);
|
|
172783
173493
|
return { filePath };
|
|
172784
173494
|
};
|
|
172785
173495
|
|
|
@@ -172880,12 +173590,12 @@ var registerRemove = (program3) => {
|
|
|
172880
173590
|
};
|
|
172881
173591
|
|
|
172882
173592
|
// cli/build/register.ts
|
|
172883
|
-
import
|
|
172884
|
-
import
|
|
173593
|
+
import path28 from "node:path";
|
|
173594
|
+
import fs29 from "node:fs";
|
|
172885
173595
|
|
|
172886
173596
|
// cli/build/build-file.ts
|
|
172887
|
-
import
|
|
172888
|
-
import
|
|
173597
|
+
import path26 from "node:path";
|
|
173598
|
+
import fs27 from "node:fs";
|
|
172889
173599
|
|
|
172890
173600
|
// lib/shared/circuit-json-diagnostics.ts
|
|
172891
173601
|
function analyzeCircuitJson(circuitJson) {
|
|
@@ -172916,9 +173626,9 @@ var buildFile = async (input, output, projectDir, options) => {
|
|
|
172916
173626
|
filePath: input,
|
|
172917
173627
|
platformConfig: options?.platformConfig
|
|
172918
173628
|
});
|
|
172919
|
-
|
|
172920
|
-
|
|
172921
|
-
console.log(`Circuit JSON written to ${
|
|
173629
|
+
fs27.mkdirSync(path26.dirname(output), { recursive: true });
|
|
173630
|
+
fs27.writeFileSync(output, JSON.stringify(result.circuitJson, null, 2));
|
|
173631
|
+
console.log(`Circuit JSON written to ${path26.relative(projectDir, output)}`);
|
|
172922
173632
|
const { errors, warnings } = analyzeCircuitJson(result.circuitJson);
|
|
172923
173633
|
if (!options?.ignoreWarnings) {
|
|
172924
173634
|
for (const warn of warnings) {
|
|
@@ -172946,16 +173656,16 @@ var buildFile = async (input, output, projectDir, options) => {
|
|
|
172946
173656
|
};
|
|
172947
173657
|
|
|
172948
173658
|
// cli/build/get-build-entrypoints.ts
|
|
172949
|
-
import
|
|
172950
|
-
import
|
|
173659
|
+
import fs28 from "node:fs";
|
|
173660
|
+
import path27 from "node:path";
|
|
172951
173661
|
async function getBuildEntrypoints({
|
|
172952
173662
|
fileOrDir,
|
|
172953
173663
|
rootDir = process.cwd()
|
|
172954
173664
|
}) {
|
|
172955
|
-
const resolvedRoot =
|
|
173665
|
+
const resolvedRoot = path27.resolve(rootDir);
|
|
172956
173666
|
if (fileOrDir) {
|
|
172957
|
-
const resolved =
|
|
172958
|
-
if (
|
|
173667
|
+
const resolved = path27.resolve(resolvedRoot, fileOrDir);
|
|
173668
|
+
if (fs28.existsSync(resolved) && fs28.statSync(resolved).isDirectory()) {
|
|
172959
173669
|
const projectDir2 = resolved;
|
|
172960
173670
|
const files2 = globbySync(["**/*.board.tsx", "**/*.circuit.tsx"], {
|
|
172961
173671
|
cwd: projectDir2,
|
|
@@ -172963,10 +173673,10 @@ async function getBuildEntrypoints({
|
|
|
172963
173673
|
});
|
|
172964
173674
|
return {
|
|
172965
173675
|
projectDir: projectDir2,
|
|
172966
|
-
circuitFiles: files2.map((f) =>
|
|
173676
|
+
circuitFiles: files2.map((f) => path27.join(projectDir2, f))
|
|
172967
173677
|
};
|
|
172968
173678
|
}
|
|
172969
|
-
return { projectDir:
|
|
173679
|
+
return { projectDir: path27.dirname(resolved), circuitFiles: [resolved] };
|
|
172970
173680
|
}
|
|
172971
173681
|
const projectDir = resolvedRoot;
|
|
172972
173682
|
const files = globbySync(["**/*.board.tsx", "**/*.circuit.tsx"], {
|
|
@@ -172975,7 +173685,7 @@ async function getBuildEntrypoints({
|
|
|
172975
173685
|
});
|
|
172976
173686
|
return {
|
|
172977
173687
|
projectDir,
|
|
172978
|
-
circuitFiles: files.map((f) =>
|
|
173688
|
+
circuitFiles: files.map((f) => path27.join(projectDir, f))
|
|
172979
173689
|
};
|
|
172980
173690
|
}
|
|
172981
173691
|
|
|
@@ -172983,13 +173693,13 @@ async function getBuildEntrypoints({
|
|
|
172983
173693
|
var registerBuild = (program3) => {
|
|
172984
173694
|
program3.command("build").description("Run tscircuit eval and output circuit json").argument("[file]", "Path to the entry file").option("--ignore-errors", "Do not exit with code 1 on errors").option("--ignore-warnings", "Do not log warnings").option("--disable-pcb", "Disable PCB outputs").action(async (file, options) => {
|
|
172985
173695
|
const { projectDir, mainEntrypoint, circuitFiles } = await getBuildEntrypoints({ fileOrDir: file });
|
|
172986
|
-
const distDir =
|
|
172987
|
-
|
|
173696
|
+
const distDir = path28.join(projectDir, "dist");
|
|
173697
|
+
fs29.mkdirSync(distDir, { recursive: true });
|
|
172988
173698
|
let hasErrors = false;
|
|
172989
173699
|
for (const filePath of circuitFiles) {
|
|
172990
|
-
const relative9 =
|
|
173700
|
+
const relative9 = path28.relative(projectDir, filePath);
|
|
172991
173701
|
const outputDirName = relative9.replace(/(\.board|\.circuit)?\.tsx$/, "");
|
|
172992
|
-
const outputPath =
|
|
173702
|
+
const outputPath = path28.join(distDir, outputDirName, "circuit.json");
|
|
172993
173703
|
const ok = await buildFile(filePath, outputPath, projectDir, options);
|
|
172994
173704
|
if (!ok)
|
|
172995
173705
|
hasErrors = true;
|
|
@@ -173001,8 +173711,8 @@ var registerBuild = (program3) => {
|
|
|
173001
173711
|
};
|
|
173002
173712
|
|
|
173003
173713
|
// lib/shared/snapshot-project.ts
|
|
173004
|
-
import
|
|
173005
|
-
import
|
|
173714
|
+
import fs31 from "node:fs";
|
|
173715
|
+
import path29 from "node:path";
|
|
173006
173716
|
import looksSame2 from "looks-same";
|
|
173007
173717
|
import sharp from "sharp";
|
|
173008
173718
|
import {
|
|
@@ -173013,7 +173723,7 @@ import { convertCircuitJsonToSimple3dSvg } from "circuit-json-to-simple-3d";
|
|
|
173013
173723
|
|
|
173014
173724
|
// lib/shared/compare-images.ts
|
|
173015
173725
|
import looksSame from "looks-same";
|
|
173016
|
-
import
|
|
173726
|
+
import fs30 from "node:fs/promises";
|
|
173017
173727
|
var compareAndCreateDiff = async (buffer1, buffer2, diffPath) => {
|
|
173018
173728
|
const { equal: equal2 } = await looksSame(buffer1, buffer2, {
|
|
173019
173729
|
strict: false,
|
|
@@ -173029,7 +173739,7 @@ var compareAndCreateDiff = async (buffer1, buffer2, diffPath) => {
|
|
|
173029
173739
|
tolerance: 2
|
|
173030
173740
|
});
|
|
173031
173741
|
} else {
|
|
173032
|
-
await
|
|
173742
|
+
await fs30.writeFile(diffPath, buffer2);
|
|
173033
173743
|
}
|
|
173034
173744
|
}
|
|
173035
173745
|
return { equal: equal2 };
|
|
@@ -173053,19 +173763,19 @@ var snapshotProject = async ({
|
|
|
173053
173763
|
...DEFAULT_IGNORED_PATTERNS,
|
|
173054
173764
|
...ignored.map(normalizeIgnorePattern)
|
|
173055
173765
|
];
|
|
173056
|
-
const resolvedPaths = filePaths.map((f) =>
|
|
173766
|
+
const resolvedPaths = filePaths.map((f) => path29.resolve(projectDir, f));
|
|
173057
173767
|
const boardFiles = resolvedPaths.length > 0 ? resolvedPaths.flatMap((p) => {
|
|
173058
|
-
if (
|
|
173768
|
+
if (fs31.existsSync(p) && fs31.statSync(p).isDirectory()) {
|
|
173059
173769
|
return globbySync(["**/*.board.tsx", "**/*.circuit.tsx"], {
|
|
173060
173770
|
cwd: p,
|
|
173061
173771
|
ignore
|
|
173062
|
-
}).map((f) =>
|
|
173772
|
+
}).map((f) => path29.join(p, f));
|
|
173063
173773
|
}
|
|
173064
173774
|
return [p];
|
|
173065
173775
|
}) : globbySync(["**/*.board.tsx", "**/*.circuit.tsx"], {
|
|
173066
173776
|
cwd: projectDir,
|
|
173067
173777
|
ignore
|
|
173068
|
-
}).map((f) =>
|
|
173778
|
+
}).map((f) => path29.join(projectDir, f));
|
|
173069
173779
|
if (boardFiles.length === 0) {
|
|
173070
173780
|
console.log("No entrypoint found. Run 'tsci init' to bootstrap a project or specify a file with 'tsci snapshot <file>'");
|
|
173071
173781
|
return onExit(0);
|
|
@@ -173077,9 +173787,9 @@ var snapshotProject = async ({
|
|
|
173077
173787
|
const pcbSvg = convertCircuitJsonToPcbSvg3(circuitJson);
|
|
173078
173788
|
const schSvg = convertCircuitJsonToSchematicSvg2(circuitJson);
|
|
173079
173789
|
const svg3d = threeD ? await convertCircuitJsonToSimple3dSvg(circuitJson) : null;
|
|
173080
|
-
const snapDir =
|
|
173081
|
-
|
|
173082
|
-
const base =
|
|
173790
|
+
const snapDir = path29.join(path29.dirname(file), "__snapshots__");
|
|
173791
|
+
fs31.mkdirSync(snapDir, { recursive: true });
|
|
173792
|
+
const base = path29.basename(file).replace(/\.tsx$/, "");
|
|
173083
173793
|
const pairs3 = [];
|
|
173084
173794
|
if (pcbOnly || !schematicOnly)
|
|
173085
173795
|
pairs3.push(["pcb", pcbSvg]);
|
|
@@ -173093,31 +173803,31 @@ var snapshotProject = async ({
|
|
|
173093
173803
|
}
|
|
173094
173804
|
for (const [type, newSvg] of pairs3) {
|
|
173095
173805
|
const is3d = type === "3d";
|
|
173096
|
-
const snapPath =
|
|
173097
|
-
const existing =
|
|
173806
|
+
const snapPath = path29.join(snapDir, `${base}-${type}.snap.${is3d ? "png" : "svg"}`);
|
|
173807
|
+
const existing = fs31.existsSync(snapPath);
|
|
173098
173808
|
const newContentBuffer = is3d ? await sharp(Buffer.from(newSvg)).png().toBuffer() : Buffer.from(newSvg, "utf8");
|
|
173099
173809
|
const newContentForFile = is3d ? newContentBuffer : newSvg;
|
|
173100
173810
|
if (!existing) {
|
|
173101
|
-
|
|
173102
|
-
console.log("✅", kleur_default.gray(
|
|
173811
|
+
fs31.writeFileSync(snapPath, newContentForFile);
|
|
173812
|
+
console.log("✅", kleur_default.gray(path29.relative(projectDir, snapPath)));
|
|
173103
173813
|
didUpdate = true;
|
|
173104
173814
|
continue;
|
|
173105
173815
|
}
|
|
173106
|
-
const oldContentBuffer =
|
|
173816
|
+
const oldContentBuffer = fs31.readFileSync(snapPath);
|
|
173107
173817
|
const diffPath = snapPath.replace(is3d ? ".snap.png" : ".snap.svg", is3d ? ".diff.png" : ".diff.svg");
|
|
173108
173818
|
const { equal: equal2 } = await compareAndCreateDiff(oldContentBuffer, newContentBuffer, diffPath);
|
|
173109
173819
|
if (update) {
|
|
173110
173820
|
if (!forceUpdate && equal2) {
|
|
173111
|
-
console.log("✅", kleur_default.gray(
|
|
173821
|
+
console.log("✅", kleur_default.gray(path29.relative(projectDir, snapPath)));
|
|
173112
173822
|
} else {
|
|
173113
|
-
|
|
173114
|
-
console.log("✅", kleur_default.gray(
|
|
173823
|
+
fs31.writeFileSync(snapPath, newContentForFile);
|
|
173824
|
+
console.log("✅", kleur_default.gray(path29.relative(projectDir, snapPath)));
|
|
173115
173825
|
didUpdate = true;
|
|
173116
173826
|
}
|
|
173117
173827
|
} else if (!equal2) {
|
|
173118
173828
|
mismatches.push(`${snapPath} (diff: ${diffPath})`);
|
|
173119
173829
|
} else {
|
|
173120
|
-
console.log("✅", kleur_default.gray(
|
|
173830
|
+
console.log("✅", kleur_default.gray(path29.relative(projectDir, snapPath)));
|
|
173121
173831
|
}
|
|
173122
173832
|
}
|
|
173123
173833
|
}
|
|
@@ -173155,22 +173865,22 @@ var registerSnapshot = (program3) => {
|
|
|
173155
173865
|
};
|
|
173156
173866
|
|
|
173157
173867
|
// lib/shared/setup-github-actions.ts
|
|
173158
|
-
import
|
|
173159
|
-
import
|
|
173868
|
+
import fs32 from "node:fs";
|
|
173869
|
+
import path30 from "node:path";
|
|
173160
173870
|
var setupGithubActions = (projectDir = process.cwd()) => {
|
|
173161
173871
|
const findGitRoot = (startDir) => {
|
|
173162
|
-
let dir =
|
|
173163
|
-
while (dir !==
|
|
173164
|
-
if (
|
|
173872
|
+
let dir = path30.resolve(startDir);
|
|
173873
|
+
while (dir !== path30.parse(dir).root) {
|
|
173874
|
+
if (fs32.existsSync(path30.join(dir, ".git"))) {
|
|
173165
173875
|
return dir;
|
|
173166
173876
|
}
|
|
173167
|
-
dir =
|
|
173877
|
+
dir = path30.dirname(dir);
|
|
173168
173878
|
}
|
|
173169
173879
|
return null;
|
|
173170
173880
|
};
|
|
173171
173881
|
const gitRoot = findGitRoot(projectDir) ?? projectDir;
|
|
173172
|
-
const workflowsDir =
|
|
173173
|
-
|
|
173882
|
+
const workflowsDir = path30.join(gitRoot, ".github", "workflows");
|
|
173883
|
+
fs32.mkdirSync(workflowsDir, { recursive: true });
|
|
173174
173884
|
const buildWorkflow = `name: tscircuit Build
|
|
173175
173885
|
|
|
173176
173886
|
on:
|
|
@@ -173209,8 +173919,8 @@ jobs:
|
|
|
173209
173919
|
- run: bun install
|
|
173210
173920
|
- run: bunx tsci snapshot
|
|
173211
173921
|
`;
|
|
173212
|
-
writeFileIfNotExists(
|
|
173213
|
-
writeFileIfNotExists(
|
|
173922
|
+
writeFileIfNotExists(path30.join(workflowsDir, "tscircuit-build.yml"), buildWorkflow);
|
|
173923
|
+
writeFileIfNotExists(path30.join(workflowsDir, "tscircuit-snapshot.yml"), snapshotWorkflow);
|
|
173214
173924
|
};
|
|
173215
173925
|
|
|
173216
173926
|
// cli/setup/register.ts
|
|
@@ -173236,8 +173946,8 @@ var registerSetup = (program3) => {
|
|
|
173236
173946
|
};
|
|
173237
173947
|
|
|
173238
173948
|
// cli/convert/register.ts
|
|
173239
|
-
import
|
|
173240
|
-
import
|
|
173949
|
+
import fs33 from "node:fs/promises";
|
|
173950
|
+
import path31 from "node:path";
|
|
173241
173951
|
|
|
173242
173952
|
// node_modules/kicad-component-converter/dist/index.js
|
|
173243
173953
|
var __create4 = Object.create;
|
|
@@ -174549,8 +175259,8 @@ function getErrorMap() {
|
|
|
174549
175259
|
return overrideErrorMap;
|
|
174550
175260
|
}
|
|
174551
175261
|
var makeIssue = (params2) => {
|
|
174552
|
-
const { data, path:
|
|
174553
|
-
const fullPath = [...
|
|
175262
|
+
const { data, path: path31, errorMaps, issueData } = params2;
|
|
175263
|
+
const fullPath = [...path31, ...issueData.path || []];
|
|
174554
175264
|
const fullIssue = {
|
|
174555
175265
|
...issueData,
|
|
174556
175266
|
path: fullPath
|
|
@@ -174658,11 +175368,11 @@ var errorUtil;
|
|
|
174658
175368
|
errorUtil2.toString = (message) => typeof message === "string" ? message : message?.message;
|
|
174659
175369
|
})(errorUtil || (errorUtil = {}));
|
|
174660
175370
|
var ParseInputLazyPath = class {
|
|
174661
|
-
constructor(parent, value,
|
|
175371
|
+
constructor(parent, value, path31, key) {
|
|
174662
175372
|
this._cachedPath = [];
|
|
174663
175373
|
this.parent = parent;
|
|
174664
175374
|
this.data = value;
|
|
174665
|
-
this._path =
|
|
175375
|
+
this._path = path31;
|
|
174666
175376
|
this._key = key;
|
|
174667
175377
|
}
|
|
174668
175378
|
get path() {
|
|
@@ -178451,14 +179161,14 @@ function generateArcPath(start, mid, end, numPoints) {
|
|
|
178451
179161
|
if (angleDelta < 0) {
|
|
178452
179162
|
angleDelta += 2 * Math.PI;
|
|
178453
179163
|
}
|
|
178454
|
-
const
|
|
179164
|
+
const path31 = [];
|
|
178455
179165
|
for (let i = 0;i <= numPoints; i++) {
|
|
178456
179166
|
const angle = angleStart + i / numPoints * angleDelta;
|
|
178457
179167
|
const x = center2.x + radius * Math.cos(angle);
|
|
178458
179168
|
const y = center2.y + radius * Math.sin(angle);
|
|
178459
|
-
|
|
179169
|
+
path31.push({ x, y });
|
|
178460
179170
|
}
|
|
178461
|
-
return
|
|
179171
|
+
return path31;
|
|
178462
179172
|
}
|
|
178463
179173
|
var makePoint = (p) => {
|
|
178464
179174
|
if (Array.isArray(p)) {
|
|
@@ -178902,15 +179612,15 @@ var convertCircuitJsonToTscircuit = (circuitJson, opts) => {
|
|
|
178902
179612
|
var registerConvert = (program3) => {
|
|
178903
179613
|
program3.command("convert").description("Convert a .kicad_mod footprint to a tscircuit component").argument("<file>", "Path to the .kicad_mod file").option("-o, --output <path>", "Output TSX file path").option("-n, --name <component>", "Component name for export").action(async (file, options) => {
|
|
178904
179614
|
try {
|
|
178905
|
-
const inputPath =
|
|
178906
|
-
const modContent = await
|
|
179615
|
+
const inputPath = path31.resolve(file);
|
|
179616
|
+
const modContent = await fs33.readFile(inputPath, "utf-8");
|
|
178907
179617
|
const circuitJson = await parseKicadModToCircuitJson(modContent);
|
|
178908
|
-
const componentName = options.name ??
|
|
179618
|
+
const componentName = options.name ?? path31.basename(inputPath, ".kicad_mod");
|
|
178909
179619
|
const tsx = convertCircuitJsonToTscircuit(circuitJson, {
|
|
178910
179620
|
componentName
|
|
178911
179621
|
});
|
|
178912
|
-
const outputPath = options.output ?
|
|
178913
|
-
await
|
|
179622
|
+
const outputPath = options.output ? path31.resolve(options.output) : path31.join(path31.dirname(inputPath), `${componentName}.tsx`);
|
|
179623
|
+
await fs33.writeFile(outputPath, tsx);
|
|
178914
179624
|
console.log(kleur_default.green(`Converted ${outputPath}`));
|
|
178915
179625
|
} catch (error) {
|
|
178916
179626
|
console.error(kleur_default.red("Failed to convert footprint:"), error instanceof Error ? error.message : error);
|
|
@@ -178919,6 +179629,89 @@ var registerConvert = (program3) => {
|
|
|
178919
179629
|
});
|
|
178920
179630
|
};
|
|
178921
179631
|
|
|
179632
|
+
// lib/shared/result-to-table.ts
|
|
179633
|
+
var formatNumber = (n3) => {
|
|
179634
|
+
return n3.toExponential(6);
|
|
179635
|
+
};
|
|
179636
|
+
function formatRows(rows) {
|
|
179637
|
+
if (rows.length === 0)
|
|
179638
|
+
return "";
|
|
179639
|
+
const colWidths = Array(rows[0].length).fill(0);
|
|
179640
|
+
for (const row of rows) {
|
|
179641
|
+
for (let i = 0;i < row.length; i++) {
|
|
179642
|
+
colWidths[i] = Math.max(colWidths[i], row[i].length);
|
|
179643
|
+
}
|
|
179644
|
+
}
|
|
179645
|
+
return rows.map((row) => row.map((cell, i) => cell.padEnd(colWidths[i])).join(" ")).join(`
|
|
179646
|
+
`);
|
|
179647
|
+
}
|
|
179648
|
+
var resultToTable = (result) => {
|
|
179649
|
+
const uniqueHeaders = [];
|
|
179650
|
+
const uniqueData = [];
|
|
179651
|
+
const seenHeaders = new Set;
|
|
179652
|
+
result.variableNames.forEach((header, index) => {
|
|
179653
|
+
if (!seenHeaders.has(header)) {
|
|
179654
|
+
seenHeaders.add(header);
|
|
179655
|
+
uniqueHeaders.push(header);
|
|
179656
|
+
uniqueData.push(result.data[index]);
|
|
179657
|
+
}
|
|
179658
|
+
});
|
|
179659
|
+
if (result.dataType === "real") {
|
|
179660
|
+
const headers2 = ["Index", ...uniqueHeaders];
|
|
179661
|
+
const dataRows2 = [];
|
|
179662
|
+
for (let i = 0;i < result.numPoints; i++) {
|
|
179663
|
+
const row = [
|
|
179664
|
+
i.toString(),
|
|
179665
|
+
...uniqueData.map((d) => formatNumber(d.values[i]))
|
|
179666
|
+
];
|
|
179667
|
+
dataRows2.push(row);
|
|
179668
|
+
}
|
|
179669
|
+
return formatRows([headers2, ...dataRows2]);
|
|
179670
|
+
}
|
|
179671
|
+
const headers = [
|
|
179672
|
+
"Index",
|
|
179673
|
+
...uniqueHeaders.flatMap((v2) => [`${v2}_real`, `${v2}_img`])
|
|
179674
|
+
];
|
|
179675
|
+
const dataRows = [];
|
|
179676
|
+
for (let i = 0;i < result.numPoints; i++) {
|
|
179677
|
+
const row = [
|
|
179678
|
+
i.toString(),
|
|
179679
|
+
...uniqueData.flatMap((d) => [
|
|
179680
|
+
formatNumber(d.values[i].real),
|
|
179681
|
+
formatNumber(d.values[i].img)
|
|
179682
|
+
])
|
|
179683
|
+
];
|
|
179684
|
+
dataRows.push(row);
|
|
179685
|
+
}
|
|
179686
|
+
return formatRows([headers, ...dataRows]);
|
|
179687
|
+
};
|
|
179688
|
+
|
|
179689
|
+
// cli/simulate/register.ts
|
|
179690
|
+
var registerSimulate = (program3) => {
|
|
179691
|
+
const simulateCommand = program3.command("simulate").description("Run a simulation");
|
|
179692
|
+
simulateCommand.command("analog").description("Run an analog SPICE simulation").argument("<file>", "Path to tscircuit tsx or circuit json file").action(async (file) => {
|
|
179693
|
+
const { circuitJson } = await generateCircuitJson({
|
|
179694
|
+
filePath: file,
|
|
179695
|
+
saveToFile: false
|
|
179696
|
+
});
|
|
179697
|
+
if (!circuitJson) {
|
|
179698
|
+
console.log("error: Failed to generate circuit JSON");
|
|
179699
|
+
return;
|
|
179700
|
+
}
|
|
179701
|
+
const spiceString = getSpiceWithPaddedSim(circuitJson);
|
|
179702
|
+
const { result, info, errors } = await runSimulation(spiceString);
|
|
179703
|
+
if (errors?.length > 0) {
|
|
179704
|
+
console.error(errors.join(`
|
|
179705
|
+
`));
|
|
179706
|
+
}
|
|
179707
|
+
if (info) {
|
|
179708
|
+
console.log(info);
|
|
179709
|
+
}
|
|
179710
|
+
const tableContent = resultToTable(result);
|
|
179711
|
+
console.log(tableContent);
|
|
179712
|
+
});
|
|
179713
|
+
};
|
|
179714
|
+
|
|
178922
179715
|
// cli/main.ts
|
|
178923
179716
|
var program2 = new Command;
|
|
178924
179717
|
program2.name("tsci").description("CLI for developing tscircuit packages");
|
|
@@ -178944,6 +179737,7 @@ registerUpgradeCommand(program2);
|
|
|
178944
179737
|
registerSearch(program2);
|
|
178945
179738
|
registerImport(program2);
|
|
178946
179739
|
registerConvert(program2);
|
|
179740
|
+
registerSimulate(program2);
|
|
178947
179741
|
if (process.argv.includes("--version") || process.argv.includes("-v") || process.argv.includes("-V")) {
|
|
178948
179742
|
console.log(getVersion());
|
|
178949
179743
|
process.exit(0);
|