@tscircuit/schematic-viewer 2.0.69 → 2.0.70
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -2
- package/dist/index.js +122 -905
- package/dist/index.js.map +1 -1
- package/package.json +4 -10
- package/dist/workers/spice-simulation.worker.js +0 -1
package/dist/index.js
CHANGED
|
@@ -589,7 +589,7 @@ var enableDebug = () => {
|
|
|
589
589
|
var debug_default = debug;
|
|
590
590
|
|
|
591
591
|
// lib/components/SchematicViewer.tsx
|
|
592
|
-
import { useCallback as useCallback6, useEffect as
|
|
592
|
+
import { useCallback as useCallback6, useEffect as useEffect11, useMemo as useMemo4, useRef as useRef8, useState as useState6 } from "react";
|
|
593
593
|
import {
|
|
594
594
|
fromString,
|
|
595
595
|
identity,
|
|
@@ -807,7 +807,6 @@ var useComponentDragging = ({
|
|
|
807
807
|
var zIndexMap = {
|
|
808
808
|
schematicEditIcon: 50,
|
|
809
809
|
schematicGridIcon: 49,
|
|
810
|
-
spiceSimulationIcon: 50,
|
|
811
810
|
viewMenuIcon: 48,
|
|
812
811
|
viewMenu: 55,
|
|
813
812
|
viewMenuBackdrop: 54,
|
|
@@ -921,16 +920,14 @@ import * as DropdownMenu from "@radix-ui/react-dropdown-menu";
|
|
|
921
920
|
// package.json
|
|
922
921
|
var package_default = {
|
|
923
922
|
name: "@tscircuit/schematic-viewer",
|
|
924
|
-
version: "2.0.
|
|
923
|
+
version: "2.0.69",
|
|
925
924
|
main: "dist/index.js",
|
|
926
925
|
type: "module",
|
|
927
926
|
scripts: {
|
|
928
927
|
start: "cosmos",
|
|
929
|
-
|
|
930
|
-
"build:blob-url": "bun scripts/build-worker-blob-url.ts",
|
|
931
|
-
build: "bun run build:webworker && bun run build:blob-url && tsup-node ./lib/index.ts --dts --format esm --sourcemap",
|
|
928
|
+
build: "tsup-node ./lib/index.ts --dts --format esm --sourcemap",
|
|
932
929
|
"build:site": "cosmos-export",
|
|
933
|
-
"vercel-build": "bun run build:
|
|
930
|
+
"vercel-build": "bun run build:site",
|
|
934
931
|
format: "biome format --write .",
|
|
935
932
|
"format:check": "biome format ."
|
|
936
933
|
},
|
|
@@ -943,7 +940,6 @@ var package_default = {
|
|
|
943
940
|
"@types/debug": "^4.1.12",
|
|
944
941
|
"@types/react": "^19.0.1",
|
|
945
942
|
"@types/react-dom": "^19.0.2",
|
|
946
|
-
"@types/recharts": "^2.0.1",
|
|
947
943
|
"@vitejs/plugin-react": "^4.3.4",
|
|
948
944
|
react: "^19.1.0",
|
|
949
945
|
"react-cosmos": "^6.2.1",
|
|
@@ -957,15 +953,12 @@ var package_default = {
|
|
|
957
953
|
},
|
|
958
954
|
peerDependencies: {
|
|
959
955
|
typescript: "^5.0.0",
|
|
960
|
-
tscircuit: "*"
|
|
961
|
-
"circuit-json-to-spice": "*"
|
|
956
|
+
tscircuit: "*"
|
|
962
957
|
},
|
|
963
958
|
dependencies: {
|
|
964
959
|
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
965
|
-
"chart.js": "^4.5.0",
|
|
966
960
|
debug: "^4.4.0",
|
|
967
961
|
"performance-now": "^2.1.0",
|
|
968
|
-
"react-chartjs-2": "^5.3.0",
|
|
969
962
|
"use-mouse-matrix-transform": "^1.2.2"
|
|
970
963
|
}
|
|
971
964
|
};
|
|
@@ -1181,713 +1174,6 @@ var ViewMenu = ({
|
|
|
1181
1174
|
] });
|
|
1182
1175
|
};
|
|
1183
1176
|
|
|
1184
|
-
// lib/components/SpiceIcon.tsx
|
|
1185
|
-
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
1186
|
-
var SpiceIcon = () => /* @__PURE__ */ jsx5(
|
|
1187
|
-
"svg",
|
|
1188
|
-
{
|
|
1189
|
-
width: "16",
|
|
1190
|
-
height: "16",
|
|
1191
|
-
viewBox: "0 0 24 24",
|
|
1192
|
-
fill: "none",
|
|
1193
|
-
stroke: "currentColor",
|
|
1194
|
-
strokeWidth: "2",
|
|
1195
|
-
strokeLinecap: "round",
|
|
1196
|
-
strokeLinejoin: "round",
|
|
1197
|
-
children: /* @__PURE__ */ jsx5("path", { d: "M3 12h2.5l2.5-9 4 18 4-9h5.5" })
|
|
1198
|
-
}
|
|
1199
|
-
);
|
|
1200
|
-
|
|
1201
|
-
// lib/components/SpiceSimulationIcon.tsx
|
|
1202
|
-
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1203
|
-
var SpiceSimulationIcon = ({
|
|
1204
|
-
onClick
|
|
1205
|
-
}) => {
|
|
1206
|
-
return /* @__PURE__ */ jsx6(
|
|
1207
|
-
"div",
|
|
1208
|
-
{
|
|
1209
|
-
onClick,
|
|
1210
|
-
title: "Run SPICE simulation",
|
|
1211
|
-
style: {
|
|
1212
|
-
position: "absolute",
|
|
1213
|
-
top: "16px",
|
|
1214
|
-
right: "112px",
|
|
1215
|
-
backgroundColor: "#fff",
|
|
1216
|
-
color: "#000",
|
|
1217
|
-
padding: "8px",
|
|
1218
|
-
borderRadius: "4px",
|
|
1219
|
-
cursor: "pointer",
|
|
1220
|
-
boxShadow: "0 2px 4px rgba(0,0,0,0.1)",
|
|
1221
|
-
display: "flex",
|
|
1222
|
-
alignItems: "center",
|
|
1223
|
-
gap: "4px",
|
|
1224
|
-
zIndex: zIndexMap.spiceSimulationIcon
|
|
1225
|
-
},
|
|
1226
|
-
children: /* @__PURE__ */ jsx6(SpiceIcon, {})
|
|
1227
|
-
}
|
|
1228
|
-
);
|
|
1229
|
-
};
|
|
1230
|
-
|
|
1231
|
-
// lib/components/SpicePlot.tsx
|
|
1232
|
-
import { useMemo as useMemo2 } from "react";
|
|
1233
|
-
import {
|
|
1234
|
-
Chart as ChartJS,
|
|
1235
|
-
CategoryScale,
|
|
1236
|
-
LinearScale,
|
|
1237
|
-
PointElement,
|
|
1238
|
-
LineElement,
|
|
1239
|
-
Title,
|
|
1240
|
-
Tooltip,
|
|
1241
|
-
Legend
|
|
1242
|
-
} from "chart.js";
|
|
1243
|
-
import { Line } from "react-chartjs-2";
|
|
1244
|
-
import { jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1245
|
-
ChartJS.register(
|
|
1246
|
-
CategoryScale,
|
|
1247
|
-
LinearScale,
|
|
1248
|
-
PointElement,
|
|
1249
|
-
LineElement,
|
|
1250
|
-
Title,
|
|
1251
|
-
Tooltip,
|
|
1252
|
-
Legend
|
|
1253
|
-
);
|
|
1254
|
-
var colors = ["#8884d8", "#82ca9d", "#ffc658", "#ff7300", "#387908"];
|
|
1255
|
-
var formatTimeWithUnits = (seconds) => {
|
|
1256
|
-
if (seconds === 0) return "0s";
|
|
1257
|
-
const absSeconds = Math.abs(seconds);
|
|
1258
|
-
let unit = "s";
|
|
1259
|
-
let scale = 1;
|
|
1260
|
-
if (absSeconds < 1e-12) {
|
|
1261
|
-
unit = "fs";
|
|
1262
|
-
scale = 1e15;
|
|
1263
|
-
} else if (absSeconds < 1e-9) {
|
|
1264
|
-
unit = "ps";
|
|
1265
|
-
scale = 1e12;
|
|
1266
|
-
} else if (absSeconds < 1e-6) {
|
|
1267
|
-
unit = "ns";
|
|
1268
|
-
scale = 1e9;
|
|
1269
|
-
} else if (absSeconds < 1e-3) {
|
|
1270
|
-
unit = "us";
|
|
1271
|
-
scale = 1e6;
|
|
1272
|
-
} else if (absSeconds < 1) {
|
|
1273
|
-
unit = "ms";
|
|
1274
|
-
scale = 1e3;
|
|
1275
|
-
}
|
|
1276
|
-
return `${parseFloat((seconds * scale).toPrecision(3))}${unit}`;
|
|
1277
|
-
};
|
|
1278
|
-
var SpicePlot = ({
|
|
1279
|
-
plotData,
|
|
1280
|
-
nodes,
|
|
1281
|
-
isLoading,
|
|
1282
|
-
error,
|
|
1283
|
-
hasRun
|
|
1284
|
-
}) => {
|
|
1285
|
-
const yAxisLabel = useMemo2(() => {
|
|
1286
|
-
const hasVoltage = nodes.some((n) => n.toLowerCase().startsWith("v("));
|
|
1287
|
-
const hasCurrent = nodes.some((n) => n.toLowerCase().startsWith("i("));
|
|
1288
|
-
if (hasVoltage && hasCurrent) return "Value";
|
|
1289
|
-
if (hasVoltage) return "Voltage (V)";
|
|
1290
|
-
if (hasCurrent) return "Current (A)";
|
|
1291
|
-
return "Value";
|
|
1292
|
-
}, [nodes]);
|
|
1293
|
-
if (isLoading) {
|
|
1294
|
-
return /* @__PURE__ */ jsx7(
|
|
1295
|
-
"div",
|
|
1296
|
-
{
|
|
1297
|
-
style: {
|
|
1298
|
-
height: "300px",
|
|
1299
|
-
width: "100%",
|
|
1300
|
-
display: "flex",
|
|
1301
|
-
alignItems: "center",
|
|
1302
|
-
justifyContent: "center"
|
|
1303
|
-
},
|
|
1304
|
-
children: "Running simulation..."
|
|
1305
|
-
}
|
|
1306
|
-
);
|
|
1307
|
-
}
|
|
1308
|
-
if (!hasRun) {
|
|
1309
|
-
return /* @__PURE__ */ jsx7(
|
|
1310
|
-
"div",
|
|
1311
|
-
{
|
|
1312
|
-
style: {
|
|
1313
|
-
height: "300px",
|
|
1314
|
-
width: "100%",
|
|
1315
|
-
display: "flex",
|
|
1316
|
-
alignItems: "center",
|
|
1317
|
-
justifyContent: "center"
|
|
1318
|
-
},
|
|
1319
|
-
children: 'Click "Run" to start the simulation.'
|
|
1320
|
-
}
|
|
1321
|
-
);
|
|
1322
|
-
}
|
|
1323
|
-
if (error) {
|
|
1324
|
-
return /* @__PURE__ */ jsxs4(
|
|
1325
|
-
"div",
|
|
1326
|
-
{
|
|
1327
|
-
style: {
|
|
1328
|
-
height: "300px",
|
|
1329
|
-
width: "100%",
|
|
1330
|
-
display: "flex",
|
|
1331
|
-
alignItems: "center",
|
|
1332
|
-
justifyContent: "center",
|
|
1333
|
-
color: "red"
|
|
1334
|
-
},
|
|
1335
|
-
children: [
|
|
1336
|
-
"Error: ",
|
|
1337
|
-
error
|
|
1338
|
-
]
|
|
1339
|
-
}
|
|
1340
|
-
);
|
|
1341
|
-
}
|
|
1342
|
-
if (plotData.length === 0) {
|
|
1343
|
-
return /* @__PURE__ */ jsx7(
|
|
1344
|
-
"div",
|
|
1345
|
-
{
|
|
1346
|
-
style: {
|
|
1347
|
-
height: "300px",
|
|
1348
|
-
width: "100%",
|
|
1349
|
-
display: "flex",
|
|
1350
|
-
alignItems: "center",
|
|
1351
|
-
justifyContent: "center"
|
|
1352
|
-
},
|
|
1353
|
-
children: "No data to plot. Check simulation output or SPICE netlist."
|
|
1354
|
-
}
|
|
1355
|
-
);
|
|
1356
|
-
}
|
|
1357
|
-
const chartData = {
|
|
1358
|
-
datasets: nodes.map((node, i) => ({
|
|
1359
|
-
label: node,
|
|
1360
|
-
data: plotData.map((p) => ({
|
|
1361
|
-
x: Number(p.name),
|
|
1362
|
-
y: p[node]
|
|
1363
|
-
})),
|
|
1364
|
-
borderColor: colors[i % colors.length],
|
|
1365
|
-
backgroundColor: colors[i % colors.length],
|
|
1366
|
-
fill: false,
|
|
1367
|
-
tension: 0.1
|
|
1368
|
-
}))
|
|
1369
|
-
};
|
|
1370
|
-
const options = {
|
|
1371
|
-
responsive: true,
|
|
1372
|
-
maintainAspectRatio: false,
|
|
1373
|
-
plugins: {
|
|
1374
|
-
legend: {
|
|
1375
|
-
position: "top",
|
|
1376
|
-
labels: {
|
|
1377
|
-
font: {
|
|
1378
|
-
family: "sans-serif"
|
|
1379
|
-
}
|
|
1380
|
-
}
|
|
1381
|
-
},
|
|
1382
|
-
title: {
|
|
1383
|
-
display: false
|
|
1384
|
-
},
|
|
1385
|
-
tooltip: {
|
|
1386
|
-
callbacks: {
|
|
1387
|
-
title: (tooltipItems) => {
|
|
1388
|
-
if (tooltipItems.length > 0) {
|
|
1389
|
-
const item = tooltipItems[0];
|
|
1390
|
-
return formatTimeWithUnits(item.parsed.x);
|
|
1391
|
-
}
|
|
1392
|
-
return "";
|
|
1393
|
-
}
|
|
1394
|
-
}
|
|
1395
|
-
}
|
|
1396
|
-
},
|
|
1397
|
-
scales: {
|
|
1398
|
-
x: {
|
|
1399
|
-
type: "linear",
|
|
1400
|
-
title: {
|
|
1401
|
-
display: true,
|
|
1402
|
-
text: "Time",
|
|
1403
|
-
font: {
|
|
1404
|
-
family: "sans-serif"
|
|
1405
|
-
}
|
|
1406
|
-
},
|
|
1407
|
-
ticks: {
|
|
1408
|
-
callback: (value) => formatTimeWithUnits(value),
|
|
1409
|
-
font: {
|
|
1410
|
-
family: "sans-serif"
|
|
1411
|
-
}
|
|
1412
|
-
}
|
|
1413
|
-
},
|
|
1414
|
-
y: {
|
|
1415
|
-
title: {
|
|
1416
|
-
display: true,
|
|
1417
|
-
text: yAxisLabel,
|
|
1418
|
-
font: {
|
|
1419
|
-
family: "sans-serif"
|
|
1420
|
-
}
|
|
1421
|
-
},
|
|
1422
|
-
ticks: {
|
|
1423
|
-
font: {
|
|
1424
|
-
family: "sans-serif"
|
|
1425
|
-
}
|
|
1426
|
-
}
|
|
1427
|
-
}
|
|
1428
|
-
}
|
|
1429
|
-
};
|
|
1430
|
-
return /* @__PURE__ */ jsx7("div", { style: { position: "relative", height: "300px", width: "100%" }, children: /* @__PURE__ */ jsx7(Line, { options, data: chartData }) });
|
|
1431
|
-
};
|
|
1432
|
-
|
|
1433
|
-
// lib/components/SpiceSimulationOverlay.tsx
|
|
1434
|
-
import { useEffect as useEffect7, useState as useState3 } from "react";
|
|
1435
|
-
import { jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1436
|
-
var SpiceSimulationOverlay = ({
|
|
1437
|
-
spiceString,
|
|
1438
|
-
onClose,
|
|
1439
|
-
plotData,
|
|
1440
|
-
nodes,
|
|
1441
|
-
isLoading,
|
|
1442
|
-
error,
|
|
1443
|
-
simOptions,
|
|
1444
|
-
onSimOptionsChange,
|
|
1445
|
-
hasRun
|
|
1446
|
-
}) => {
|
|
1447
|
-
const [startTimeDraft, setStartTimeDraft] = useState3(
|
|
1448
|
-
String(simOptions.startTime)
|
|
1449
|
-
);
|
|
1450
|
-
const [durationDraft, setDurationDraft] = useState3(
|
|
1451
|
-
String(simOptions.duration)
|
|
1452
|
-
);
|
|
1453
|
-
useEffect7(() => {
|
|
1454
|
-
setStartTimeDraft(String(simOptions.startTime));
|
|
1455
|
-
setDurationDraft(String(simOptions.duration));
|
|
1456
|
-
}, [simOptions.startTime, simOptions.duration]);
|
|
1457
|
-
const handleRerun = () => {
|
|
1458
|
-
onSimOptionsChange({
|
|
1459
|
-
...simOptions,
|
|
1460
|
-
startTime: Number(startTimeDraft),
|
|
1461
|
-
duration: Number(durationDraft)
|
|
1462
|
-
});
|
|
1463
|
-
};
|
|
1464
|
-
const filteredNodes = nodes.filter((node) => {
|
|
1465
|
-
const isVoltage = node.toLowerCase().startsWith("v(");
|
|
1466
|
-
const isCurrent = node.toLowerCase().startsWith("i(");
|
|
1467
|
-
if (simOptions.showVoltage && isVoltage) return true;
|
|
1468
|
-
if (simOptions.showCurrent && isCurrent) return true;
|
|
1469
|
-
return false;
|
|
1470
|
-
});
|
|
1471
|
-
return /* @__PURE__ */ jsx8(
|
|
1472
|
-
"div",
|
|
1473
|
-
{
|
|
1474
|
-
style: {
|
|
1475
|
-
position: "fixed",
|
|
1476
|
-
top: 0,
|
|
1477
|
-
left: 0,
|
|
1478
|
-
right: 0,
|
|
1479
|
-
bottom: 0,
|
|
1480
|
-
backgroundColor: "rgba(0, 0, 0, 0.5)",
|
|
1481
|
-
display: "flex",
|
|
1482
|
-
alignItems: "center",
|
|
1483
|
-
justifyContent: "center",
|
|
1484
|
-
zIndex: 1002,
|
|
1485
|
-
fontFamily: "sans-serif"
|
|
1486
|
-
},
|
|
1487
|
-
children: /* @__PURE__ */ jsxs5(
|
|
1488
|
-
"div",
|
|
1489
|
-
{
|
|
1490
|
-
style: {
|
|
1491
|
-
backgroundColor: "white",
|
|
1492
|
-
padding: "24px",
|
|
1493
|
-
borderRadius: "12px",
|
|
1494
|
-
width: "90%",
|
|
1495
|
-
maxWidth: "900px",
|
|
1496
|
-
boxShadow: "0 4px 20px rgba(0, 0, 0, 0.15)"
|
|
1497
|
-
},
|
|
1498
|
-
children: [
|
|
1499
|
-
/* @__PURE__ */ jsxs5(
|
|
1500
|
-
"div",
|
|
1501
|
-
{
|
|
1502
|
-
style: {
|
|
1503
|
-
display: "flex",
|
|
1504
|
-
justifyContent: "space-between",
|
|
1505
|
-
alignItems: "center",
|
|
1506
|
-
marginBottom: "24px",
|
|
1507
|
-
borderBottom: "1px solid #eee",
|
|
1508
|
-
paddingBottom: "16px"
|
|
1509
|
-
},
|
|
1510
|
-
children: [
|
|
1511
|
-
/* @__PURE__ */ jsx8(
|
|
1512
|
-
"h2",
|
|
1513
|
-
{
|
|
1514
|
-
style: {
|
|
1515
|
-
margin: 0,
|
|
1516
|
-
fontSize: "22px",
|
|
1517
|
-
fontWeight: 600,
|
|
1518
|
-
color: "#333"
|
|
1519
|
-
},
|
|
1520
|
-
children: "SPICE Simulation"
|
|
1521
|
-
}
|
|
1522
|
-
),
|
|
1523
|
-
/* @__PURE__ */ jsx8(
|
|
1524
|
-
"button",
|
|
1525
|
-
{
|
|
1526
|
-
onClick: onClose,
|
|
1527
|
-
style: {
|
|
1528
|
-
background: "none",
|
|
1529
|
-
border: "none",
|
|
1530
|
-
fontSize: "28px",
|
|
1531
|
-
cursor: "pointer",
|
|
1532
|
-
color: "#888",
|
|
1533
|
-
padding: 0,
|
|
1534
|
-
lineHeight: 1
|
|
1535
|
-
},
|
|
1536
|
-
children: "\xD7"
|
|
1537
|
-
}
|
|
1538
|
-
)
|
|
1539
|
-
]
|
|
1540
|
-
}
|
|
1541
|
-
),
|
|
1542
|
-
/* @__PURE__ */ jsx8("div", { children: /* @__PURE__ */ jsx8(
|
|
1543
|
-
SpicePlot,
|
|
1544
|
-
{
|
|
1545
|
-
plotData,
|
|
1546
|
-
nodes: filteredNodes,
|
|
1547
|
-
isLoading,
|
|
1548
|
-
error,
|
|
1549
|
-
hasRun
|
|
1550
|
-
}
|
|
1551
|
-
) }),
|
|
1552
|
-
/* @__PURE__ */ jsxs5(
|
|
1553
|
-
"div",
|
|
1554
|
-
{
|
|
1555
|
-
style: {
|
|
1556
|
-
marginTop: "16px",
|
|
1557
|
-
padding: "12px",
|
|
1558
|
-
backgroundColor: "#f7f7f7",
|
|
1559
|
-
borderRadius: "6px",
|
|
1560
|
-
display: "flex",
|
|
1561
|
-
flexWrap: "wrap",
|
|
1562
|
-
gap: "24px",
|
|
1563
|
-
alignItems: "center",
|
|
1564
|
-
fontSize: "14px"
|
|
1565
|
-
},
|
|
1566
|
-
children: [
|
|
1567
|
-
/* @__PURE__ */ jsxs5("div", { style: { display: "flex", gap: "16px" }, children: [
|
|
1568
|
-
/* @__PURE__ */ jsxs5(
|
|
1569
|
-
"label",
|
|
1570
|
-
{
|
|
1571
|
-
style: { display: "flex", alignItems: "center", gap: "6px" },
|
|
1572
|
-
children: [
|
|
1573
|
-
/* @__PURE__ */ jsx8(
|
|
1574
|
-
"input",
|
|
1575
|
-
{
|
|
1576
|
-
type: "checkbox",
|
|
1577
|
-
checked: simOptions.showVoltage,
|
|
1578
|
-
onChange: (e) => onSimOptionsChange({
|
|
1579
|
-
...simOptions,
|
|
1580
|
-
showVoltage: e.target.checked
|
|
1581
|
-
})
|
|
1582
|
-
}
|
|
1583
|
-
),
|
|
1584
|
-
"Voltage"
|
|
1585
|
-
]
|
|
1586
|
-
}
|
|
1587
|
-
),
|
|
1588
|
-
/* @__PURE__ */ jsxs5(
|
|
1589
|
-
"label",
|
|
1590
|
-
{
|
|
1591
|
-
style: { display: "flex", alignItems: "center", gap: "6px" },
|
|
1592
|
-
children: [
|
|
1593
|
-
/* @__PURE__ */ jsx8(
|
|
1594
|
-
"input",
|
|
1595
|
-
{
|
|
1596
|
-
type: "checkbox",
|
|
1597
|
-
checked: simOptions.showCurrent,
|
|
1598
|
-
onChange: (e) => onSimOptionsChange({
|
|
1599
|
-
...simOptions,
|
|
1600
|
-
showCurrent: e.target.checked
|
|
1601
|
-
})
|
|
1602
|
-
}
|
|
1603
|
-
),
|
|
1604
|
-
"Current"
|
|
1605
|
-
]
|
|
1606
|
-
}
|
|
1607
|
-
)
|
|
1608
|
-
] }),
|
|
1609
|
-
/* @__PURE__ */ jsxs5("div", { style: { display: "flex", gap: "16px", alignItems: "center" }, children: [
|
|
1610
|
-
/* @__PURE__ */ jsx8("label", { htmlFor: "startTime", children: "Start Time (ms):" }),
|
|
1611
|
-
/* @__PURE__ */ jsx8(
|
|
1612
|
-
"input",
|
|
1613
|
-
{
|
|
1614
|
-
id: "startTime",
|
|
1615
|
-
type: "number",
|
|
1616
|
-
value: startTimeDraft,
|
|
1617
|
-
onChange: (e) => setStartTimeDraft(e.target.value),
|
|
1618
|
-
style: {
|
|
1619
|
-
width: "80px",
|
|
1620
|
-
padding: "4px 8px",
|
|
1621
|
-
borderRadius: "4px",
|
|
1622
|
-
border: "1px solid #ccc"
|
|
1623
|
-
}
|
|
1624
|
-
}
|
|
1625
|
-
),
|
|
1626
|
-
/* @__PURE__ */ jsx8("label", { htmlFor: "duration", children: "Duration (ms):" }),
|
|
1627
|
-
/* @__PURE__ */ jsx8(
|
|
1628
|
-
"input",
|
|
1629
|
-
{
|
|
1630
|
-
id: "duration",
|
|
1631
|
-
type: "number",
|
|
1632
|
-
value: durationDraft,
|
|
1633
|
-
onChange: (e) => setDurationDraft(e.target.value),
|
|
1634
|
-
style: {
|
|
1635
|
-
width: "80px",
|
|
1636
|
-
padding: "4px 8px",
|
|
1637
|
-
borderRadius: "4px",
|
|
1638
|
-
border: "1px solid #ccc"
|
|
1639
|
-
}
|
|
1640
|
-
}
|
|
1641
|
-
),
|
|
1642
|
-
/* @__PURE__ */ jsx8(
|
|
1643
|
-
"button",
|
|
1644
|
-
{
|
|
1645
|
-
onClick: handleRerun,
|
|
1646
|
-
style: {
|
|
1647
|
-
padding: "4px 12px",
|
|
1648
|
-
borderRadius: "4px",
|
|
1649
|
-
border: "1px solid #ccc",
|
|
1650
|
-
backgroundColor: "#f0f0f0",
|
|
1651
|
-
cursor: "pointer"
|
|
1652
|
-
},
|
|
1653
|
-
children: hasRun ? "Rerun" : "Run"
|
|
1654
|
-
}
|
|
1655
|
-
)
|
|
1656
|
-
] })
|
|
1657
|
-
]
|
|
1658
|
-
}
|
|
1659
|
-
),
|
|
1660
|
-
/* @__PURE__ */ jsxs5("div", { style: { marginTop: "24px" }, children: [
|
|
1661
|
-
/* @__PURE__ */ jsx8(
|
|
1662
|
-
"h3",
|
|
1663
|
-
{
|
|
1664
|
-
style: {
|
|
1665
|
-
marginTop: 0,
|
|
1666
|
-
marginBottom: "12px",
|
|
1667
|
-
fontSize: "18px",
|
|
1668
|
-
fontWeight: 600,
|
|
1669
|
-
color: "#333"
|
|
1670
|
-
},
|
|
1671
|
-
children: "SPICE Netlist"
|
|
1672
|
-
}
|
|
1673
|
-
),
|
|
1674
|
-
/* @__PURE__ */ jsx8(
|
|
1675
|
-
"pre",
|
|
1676
|
-
{
|
|
1677
|
-
style: {
|
|
1678
|
-
backgroundColor: "#fafafa",
|
|
1679
|
-
padding: "16px",
|
|
1680
|
-
borderRadius: "6px",
|
|
1681
|
-
maxHeight: "150px",
|
|
1682
|
-
overflowY: "auto",
|
|
1683
|
-
border: "1px solid #eee",
|
|
1684
|
-
color: "#333",
|
|
1685
|
-
fontSize: "13px",
|
|
1686
|
-
fontFamily: "monospace"
|
|
1687
|
-
},
|
|
1688
|
-
children: spiceString
|
|
1689
|
-
}
|
|
1690
|
-
)
|
|
1691
|
-
] })
|
|
1692
|
-
]
|
|
1693
|
-
}
|
|
1694
|
-
)
|
|
1695
|
-
}
|
|
1696
|
-
);
|
|
1697
|
-
};
|
|
1698
|
-
|
|
1699
|
-
// lib/hooks/useSpiceSimulation.ts
|
|
1700
|
-
import { useState as useState4, useEffect as useEffect8 } from "react";
|
|
1701
|
-
|
|
1702
|
-
// lib/workers/spice-simulation.worker.blob.js
|
|
1703
|
-
var b64 = "dmFyIGU9bnVsbCxzPWFzeW5jKCk9Pihhd2FpdCBpbXBvcnQoImh0dHBzOi8vY2RuLmpzZGVsaXZyLm5ldC9ucG0vZWVjaXJjdWl0LWVuZ2luZUAxLjUuMi8rZXNtIikpLlNpbXVsYXRpb24sYz1hc3luYygpPT57aWYoZSYmZS5pc0luaXRpYWxpemVkKCkpcmV0dXJuO2xldCBpPWF3YWl0IHMoKTtlPW5ldyBpLGF3YWl0IGUuc3RhcnQoKX07c2VsZi5vbm1lc3NhZ2U9YXN5bmMgaT0+e3RyeXtpZihhd2FpdCBjKCksIWUpdGhyb3cgbmV3IEVycm9yKCJTaW11bGF0aW9uIG5vdCBpbml0aWFsaXplZCIpO2xldCB0PWkuZGF0YS5zcGljZVN0cmluZyxhPXQubWF0Y2goL3dyZGF0YVxzKyhcUyspXHMrKC4qKS9pKTtpZihhKXtsZXQgbz1gLnByb2JlICR7YVsyXS50cmltKCkuc3BsaXQoL1xzKy8pLmpvaW4oIiAiKX1gO3Q9dC5yZXBsYWNlKC93cmRhdGEuKi9pLG8pfWVsc2UgaWYoIXQubWF0Y2goL1wucHJvYmUvaSkpdGhyb3cgdC5tYXRjaCgvcGxvdFxzKyguKikvaSk/bmV3IEVycm9yKCJUaGUgJ3Bsb3QnIGNvbW1hbmQgaXMgbm90IHN1cHBvcnRlZCBmb3IgZGF0YSBleHRyYWN0aW9uLiBQbGVhc2UgdXNlICd3cmRhdGEgPGZpbGVuYW1lPiA8dmFyMT4gLi4uJyBvciAnLnByb2JlIDx2YXIxPiAuLi4nIGluc3RlYWQuIik6bmV3IEVycm9yKCJObyAnLnByb2JlJyBvciAnd3JkYXRhJyBjb21tYW5kIGZvdW5kIGluIFNQSUNFIGZpbGUuIFVzZSAnd3JkYXRhIDxmaWxlbmFtZT4gPHZhcjE+IC4uLicgdG8gc3BlY2lmeSBvdXRwdXQuIik7ZS5zZXROZXRMaXN0KHQpO2xldCBuPWF3YWl0IGUucnVuU2ltKCk7c2VsZi5wb3N0TWVzc2FnZSh7dHlwZToicmVzdWx0IixyZXN1bHQ6bn0pfWNhdGNoKHQpe3NlbGYucG9zdE1lc3NhZ2Uoe3R5cGU6ImVycm9yIixlcnJvcjp0Lm1lc3NhZ2V9KX19Owo=";
|
|
1704
|
-
var blobUrl = null;
|
|
1705
|
-
var getSpiceSimulationWorkerBlobUrl = () => {
|
|
1706
|
-
if (typeof window === "undefined") return null;
|
|
1707
|
-
if (blobUrl) return blobUrl;
|
|
1708
|
-
try {
|
|
1709
|
-
const blob = new Blob([atob(b64)], { type: "application/javascript" });
|
|
1710
|
-
blobUrl = URL.createObjectURL(blob);
|
|
1711
|
-
return blobUrl;
|
|
1712
|
-
} catch (e) {
|
|
1713
|
-
console.error("Failed to create blob URL for worker", e);
|
|
1714
|
-
return null;
|
|
1715
|
-
}
|
|
1716
|
-
};
|
|
1717
|
-
|
|
1718
|
-
// lib/hooks/useSpiceSimulation.ts
|
|
1719
|
-
var parseEecEngineOutput = (result) => {
|
|
1720
|
-
const columnData = {};
|
|
1721
|
-
if (result.dataType === "real") {
|
|
1722
|
-
result.data.forEach((col) => {
|
|
1723
|
-
columnData[col.name] = col.values;
|
|
1724
|
-
});
|
|
1725
|
-
} else if (result.dataType === "complex") {
|
|
1726
|
-
result.data.forEach((col) => {
|
|
1727
|
-
columnData[col.name] = col.values.map((v) => v.real);
|
|
1728
|
-
});
|
|
1729
|
-
} else {
|
|
1730
|
-
throw new Error("Unsupported data type in simulation result");
|
|
1731
|
-
}
|
|
1732
|
-
const timeKey = Object.keys(columnData).find(
|
|
1733
|
-
(k) => k.toLowerCase() === "time" || k.toLowerCase() === "frequency"
|
|
1734
|
-
);
|
|
1735
|
-
if (!timeKey) {
|
|
1736
|
-
throw new Error("No time or frequency data in simulation result");
|
|
1737
|
-
}
|
|
1738
|
-
const timeValues = columnData[timeKey];
|
|
1739
|
-
const probedVariables = Object.keys(columnData).filter((k) => k !== timeKey);
|
|
1740
|
-
const plotableNodes = probedVariables;
|
|
1741
|
-
const plotData = timeValues.map((t, i) => {
|
|
1742
|
-
const point = { name: t.toExponential(2) };
|
|
1743
|
-
probedVariables.forEach((variable) => {
|
|
1744
|
-
point[variable] = columnData[variable][i];
|
|
1745
|
-
});
|
|
1746
|
-
return point;
|
|
1747
|
-
});
|
|
1748
|
-
return { plotData, nodes: plotableNodes };
|
|
1749
|
-
};
|
|
1750
|
-
var useSpiceSimulation = (spiceString) => {
|
|
1751
|
-
const [plotData, setPlotData] = useState4([]);
|
|
1752
|
-
const [nodes, setNodes] = useState4([]);
|
|
1753
|
-
const [isLoading, setIsLoading] = useState4(true);
|
|
1754
|
-
const [error, setError] = useState4(null);
|
|
1755
|
-
useEffect8(() => {
|
|
1756
|
-
if (!spiceString) {
|
|
1757
|
-
setIsLoading(false);
|
|
1758
|
-
setPlotData([]);
|
|
1759
|
-
setNodes([]);
|
|
1760
|
-
setError(null);
|
|
1761
|
-
return;
|
|
1762
|
-
}
|
|
1763
|
-
setIsLoading(true);
|
|
1764
|
-
setError(null);
|
|
1765
|
-
setPlotData([]);
|
|
1766
|
-
setNodes([]);
|
|
1767
|
-
const workerUrl = getSpiceSimulationWorkerBlobUrl();
|
|
1768
|
-
if (!workerUrl) {
|
|
1769
|
-
setError("Could not create SPICE simulation worker.");
|
|
1770
|
-
setIsLoading(false);
|
|
1771
|
-
return;
|
|
1772
|
-
}
|
|
1773
|
-
const worker = new Worker(workerUrl, { type: "module" });
|
|
1774
|
-
worker.onmessage = (event) => {
|
|
1775
|
-
if (event.data.type === "result") {
|
|
1776
|
-
try {
|
|
1777
|
-
const { plotData: parsedData, nodes: parsedNodes } = parseEecEngineOutput(event.data.result);
|
|
1778
|
-
setPlotData(parsedData);
|
|
1779
|
-
setNodes(parsedNodes);
|
|
1780
|
-
} catch (e) {
|
|
1781
|
-
setError(e.message || "Failed to parse simulation result");
|
|
1782
|
-
console.error(e);
|
|
1783
|
-
}
|
|
1784
|
-
} else if (event.data.type === "error") {
|
|
1785
|
-
setError(event.data.error);
|
|
1786
|
-
}
|
|
1787
|
-
setIsLoading(false);
|
|
1788
|
-
};
|
|
1789
|
-
worker.onerror = (err) => {
|
|
1790
|
-
setError(err.message);
|
|
1791
|
-
setIsLoading(false);
|
|
1792
|
-
};
|
|
1793
|
-
worker.postMessage({ spiceString });
|
|
1794
|
-
return () => {
|
|
1795
|
-
worker.terminate();
|
|
1796
|
-
};
|
|
1797
|
-
}, [spiceString]);
|
|
1798
|
-
return { plotData, nodes, isLoading, error };
|
|
1799
|
-
};
|
|
1800
|
-
|
|
1801
|
-
// lib/utils/spice-utils.ts
|
|
1802
|
-
import { circuitJsonToSpice } from "circuit-json-to-spice";
|
|
1803
|
-
var formatSimTime = (seconds) => {
|
|
1804
|
-
if (seconds === 0) return "0";
|
|
1805
|
-
const absSeconds = Math.abs(seconds);
|
|
1806
|
-
const precision = (v) => v.toPrecision(4);
|
|
1807
|
-
if (absSeconds >= 1) return precision(seconds);
|
|
1808
|
-
if (absSeconds >= 1e-3) return `${precision(seconds * 1e3)}m`;
|
|
1809
|
-
if (absSeconds >= 1e-6) return `${precision(seconds * 1e6)}u`;
|
|
1810
|
-
if (absSeconds >= 1e-9) return `${precision(seconds * 1e9)}n`;
|
|
1811
|
-
if (absSeconds >= 1e-12) return `${precision(seconds * 1e12)}p`;
|
|
1812
|
-
if (absSeconds >= 1e-15) return `${precision(seconds * 1e15)}f`;
|
|
1813
|
-
return seconds.toExponential(3);
|
|
1814
|
-
};
|
|
1815
|
-
var getSpiceFromCircuitJson = (circuitJson, options) => {
|
|
1816
|
-
const spiceNetlist = circuitJsonToSpice(circuitJson);
|
|
1817
|
-
const baseSpiceString = spiceNetlist.toSpiceString();
|
|
1818
|
-
const lines = baseSpiceString.split("\n").filter((l) => l.trim() !== "");
|
|
1819
|
-
const componentLines = lines.filter(
|
|
1820
|
-
(l) => !l.startsWith("*") && !l.startsWith(".") && l.trim() !== ""
|
|
1821
|
-
);
|
|
1822
|
-
const allNodes = /* @__PURE__ */ new Set();
|
|
1823
|
-
const capacitorNodes = /* @__PURE__ */ new Set();
|
|
1824
|
-
const componentNamesToProbeCurrent = /* @__PURE__ */ new Set();
|
|
1825
|
-
for (const line of componentLines) {
|
|
1826
|
-
const parts = line.trim().split(/\s+/);
|
|
1827
|
-
if (parts.length < 3) continue;
|
|
1828
|
-
const componentName = parts[0];
|
|
1829
|
-
const componentType = componentName[0].toUpperCase();
|
|
1830
|
-
let nodesOnLine = [];
|
|
1831
|
-
if (["R", "C", "L", "V", "I", "D"].includes(componentType)) {
|
|
1832
|
-
nodesOnLine = parts.slice(1, 3);
|
|
1833
|
-
if (componentType === "V") {
|
|
1834
|
-
componentNamesToProbeCurrent.add(componentName);
|
|
1835
|
-
}
|
|
1836
|
-
} else if (componentType === "Q" && parts.length >= 4) {
|
|
1837
|
-
nodesOnLine = parts.slice(1, 4);
|
|
1838
|
-
} else if (componentType === "M" && parts.length >= 5) {
|
|
1839
|
-
nodesOnLine = parts.slice(1, 5);
|
|
1840
|
-
} else if (componentType === "X") {
|
|
1841
|
-
nodesOnLine = parts.slice(1, -1);
|
|
1842
|
-
} else {
|
|
1843
|
-
continue;
|
|
1844
|
-
}
|
|
1845
|
-
nodesOnLine.forEach((node) => allNodes.add(node));
|
|
1846
|
-
if (componentType === "C") {
|
|
1847
|
-
nodesOnLine.forEach((node) => capacitorNodes.add(node));
|
|
1848
|
-
}
|
|
1849
|
-
}
|
|
1850
|
-
allNodes.delete("0");
|
|
1851
|
-
capacitorNodes.delete("0");
|
|
1852
|
-
const icLines = Array.from(capacitorNodes).map((node) => `.ic V(${node})=0`);
|
|
1853
|
-
const probes = [];
|
|
1854
|
-
const probeVoltages = Array.from(allNodes).map((node) => `V(${node})`);
|
|
1855
|
-
probes.push(...probeVoltages);
|
|
1856
|
-
const probeCurrents = Array.from(componentNamesToProbeCurrent).map(
|
|
1857
|
-
(name) => `I(${name})`
|
|
1858
|
-
);
|
|
1859
|
-
probes.push(...probeCurrents);
|
|
1860
|
-
const probeLine = probes.length > 0 ? `.probe ${probes.join(" ")}` : "";
|
|
1861
|
-
const tstart_ms = options?.startTime ?? 0;
|
|
1862
|
-
const duration_ms = options?.duration ?? 20;
|
|
1863
|
-
const tstart = tstart_ms * 1e-3;
|
|
1864
|
-
const duration = duration_ms * 1e-3;
|
|
1865
|
-
const tstop = tstart + duration;
|
|
1866
|
-
const tstep = duration / 50;
|
|
1867
|
-
const tranLine = `.tran ${formatSimTime(tstep)} ${formatSimTime(
|
|
1868
|
-
tstop
|
|
1869
|
-
)} ${formatSimTime(tstart)} UIC`;
|
|
1870
|
-
const endStatement = ".end";
|
|
1871
|
-
const originalLines = baseSpiceString.split("\n");
|
|
1872
|
-
let endIndex = -1;
|
|
1873
|
-
for (let i = originalLines.length - 1; i >= 0; i--) {
|
|
1874
|
-
if (originalLines[i].trim().toLowerCase().startsWith(endStatement)) {
|
|
1875
|
-
endIndex = i;
|
|
1876
|
-
break;
|
|
1877
|
-
}
|
|
1878
|
-
}
|
|
1879
|
-
const injectionLines = [...icLines, probeLine, tranLine].filter(Boolean);
|
|
1880
|
-
let finalLines;
|
|
1881
|
-
if (endIndex !== -1) {
|
|
1882
|
-
const beforeEnd = originalLines.slice(0, endIndex);
|
|
1883
|
-
const endLineAndAfter = originalLines.slice(endIndex);
|
|
1884
|
-
finalLines = [...beforeEnd, ...injectionLines, ...endLineAndAfter];
|
|
1885
|
-
} else {
|
|
1886
|
-
finalLines = [...originalLines, ...injectionLines, endStatement];
|
|
1887
|
-
}
|
|
1888
|
-
return finalLines.join("\n");
|
|
1889
|
-
};
|
|
1890
|
-
|
|
1891
1177
|
// lib/hooks/useLocalStorage.ts
|
|
1892
1178
|
import { useCallback as useCallback2 } from "react";
|
|
1893
1179
|
var STORAGE_KEYS = {
|
|
@@ -1931,11 +1217,11 @@ import {
|
|
|
1931
1217
|
createContext,
|
|
1932
1218
|
useCallback as useCallback3,
|
|
1933
1219
|
useContext,
|
|
1934
|
-
useEffect as
|
|
1935
|
-
useMemo as
|
|
1220
|
+
useEffect as useEffect7,
|
|
1221
|
+
useMemo as useMemo2,
|
|
1936
1222
|
useRef as useRef4
|
|
1937
1223
|
} from "react";
|
|
1938
|
-
import { Fragment, jsx as
|
|
1224
|
+
import { Fragment, jsx as jsx5 } from "react/jsx-runtime";
|
|
1939
1225
|
var MouseTrackerContext = createContext(null);
|
|
1940
1226
|
var DRAG_THRESHOLD_PX = 5;
|
|
1941
1227
|
var boundsAreEqual = (a, b) => {
|
|
@@ -1946,7 +1232,7 @@ var boundsAreEqual = (a, b) => {
|
|
|
1946
1232
|
var MouseTracker = ({ children }) => {
|
|
1947
1233
|
const existingContext = useContext(MouseTrackerContext);
|
|
1948
1234
|
if (existingContext) {
|
|
1949
|
-
return /* @__PURE__ */
|
|
1235
|
+
return /* @__PURE__ */ jsx5(Fragment, { children });
|
|
1950
1236
|
}
|
|
1951
1237
|
const storeRef = useRef4({
|
|
1952
1238
|
pointer: null,
|
|
@@ -2015,7 +1301,7 @@ var MouseTracker = ({ children }) => {
|
|
|
2015
1301
|
const isHovering = useCallback3((id) => {
|
|
2016
1302
|
return storeRef.current.hoveringIds.has(id);
|
|
2017
1303
|
}, []);
|
|
2018
|
-
|
|
1304
|
+
useEffect7(() => {
|
|
2019
1305
|
const handlePointerPosition = (event) => {
|
|
2020
1306
|
const { clientX, clientY } = event;
|
|
2021
1307
|
const pointer = storeRef.current.pointer;
|
|
@@ -2083,7 +1369,7 @@ var MouseTracker = ({ children }) => {
|
|
|
2083
1369
|
window.removeEventListener("click", handleClick);
|
|
2084
1370
|
};
|
|
2085
1371
|
}, [updateHovering]);
|
|
2086
|
-
const value =
|
|
1372
|
+
const value = useMemo2(
|
|
2087
1373
|
() => ({
|
|
2088
1374
|
registerBoundingBox,
|
|
2089
1375
|
updateBoundingBox,
|
|
@@ -2099,18 +1385,18 @@ var MouseTracker = ({ children }) => {
|
|
|
2099
1385
|
isHovering
|
|
2100
1386
|
]
|
|
2101
1387
|
);
|
|
2102
|
-
return /* @__PURE__ */
|
|
1388
|
+
return /* @__PURE__ */ jsx5(MouseTrackerContext.Provider, { value, children });
|
|
2103
1389
|
};
|
|
2104
1390
|
|
|
2105
1391
|
// lib/components/SchematicComponentMouseTarget.tsx
|
|
2106
|
-
import { useCallback as useCallback4, useEffect as
|
|
1392
|
+
import { useCallback as useCallback4, useEffect as useEffect9, useRef as useRef6, useState as useState3 } from "react";
|
|
2107
1393
|
|
|
2108
1394
|
// lib/hooks/useMouseEventsOverBoundingBox.ts
|
|
2109
1395
|
import {
|
|
2110
1396
|
useContext as useContext2,
|
|
2111
|
-
useEffect as
|
|
1397
|
+
useEffect as useEffect8,
|
|
2112
1398
|
useId,
|
|
2113
|
-
useMemo as
|
|
1399
|
+
useMemo as useMemo3,
|
|
2114
1400
|
useRef as useRef5,
|
|
2115
1401
|
useSyncExternalStore
|
|
2116
1402
|
} from "react";
|
|
@@ -2124,13 +1410,13 @@ var useMouseEventsOverBoundingBox = (options) => {
|
|
|
2124
1410
|
const id = useId();
|
|
2125
1411
|
const latestOptionsRef = useRef5(options);
|
|
2126
1412
|
latestOptionsRef.current = options;
|
|
2127
|
-
const handleClick =
|
|
1413
|
+
const handleClick = useMemo3(
|
|
2128
1414
|
() => (event) => {
|
|
2129
1415
|
latestOptionsRef.current.onClick?.(event);
|
|
2130
1416
|
},
|
|
2131
1417
|
[]
|
|
2132
1418
|
);
|
|
2133
|
-
|
|
1419
|
+
useEffect8(() => {
|
|
2134
1420
|
context.registerBoundingBox(id, {
|
|
2135
1421
|
bounds: latestOptionsRef.current.bounds,
|
|
2136
1422
|
onClick: latestOptionsRef.current.onClick ? handleClick : void 0
|
|
@@ -2139,7 +1425,7 @@ var useMouseEventsOverBoundingBox = (options) => {
|
|
|
2139
1425
|
context.unregisterBoundingBox(id);
|
|
2140
1426
|
};
|
|
2141
1427
|
}, [context, handleClick, id]);
|
|
2142
|
-
|
|
1428
|
+
useEffect8(() => {
|
|
2143
1429
|
context.updateBoundingBox(id, {
|
|
2144
1430
|
bounds: latestOptionsRef.current.bounds,
|
|
2145
1431
|
onClick: latestOptionsRef.current.onClick ? handleClick : void 0
|
|
@@ -2163,7 +1449,7 @@ var useMouseEventsOverBoundingBox = (options) => {
|
|
|
2163
1449
|
};
|
|
2164
1450
|
|
|
2165
1451
|
// lib/components/SchematicComponentMouseTarget.tsx
|
|
2166
|
-
import { jsx as
|
|
1452
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
2167
1453
|
var areMeasurementsEqual = (a, b) => {
|
|
2168
1454
|
if (!a && !b) return true;
|
|
2169
1455
|
if (!a || !b) return false;
|
|
@@ -2178,7 +1464,7 @@ var SchematicComponentMouseTarget = ({
|
|
|
2178
1464
|
showOutline,
|
|
2179
1465
|
circuitJsonKey
|
|
2180
1466
|
}) => {
|
|
2181
|
-
const [measurement, setMeasurement] =
|
|
1467
|
+
const [measurement, setMeasurement] = useState3(null);
|
|
2182
1468
|
const frameRef = useRef6(null);
|
|
2183
1469
|
const measure = useCallback4(() => {
|
|
2184
1470
|
frameRef.current = null;
|
|
@@ -2219,10 +1505,10 @@ var SchematicComponentMouseTarget = ({
|
|
|
2219
1505
|
if (frameRef.current !== null) return;
|
|
2220
1506
|
frameRef.current = window.requestAnimationFrame(measure);
|
|
2221
1507
|
}, [measure]);
|
|
2222
|
-
|
|
1508
|
+
useEffect9(() => {
|
|
2223
1509
|
scheduleMeasure();
|
|
2224
1510
|
}, [scheduleMeasure, circuitJsonKey]);
|
|
2225
|
-
|
|
1511
|
+
useEffect9(() => {
|
|
2226
1512
|
scheduleMeasure();
|
|
2227
1513
|
const svgDiv = svgDivRef.current;
|
|
2228
1514
|
const container = containerRef.current;
|
|
@@ -2267,7 +1553,7 @@ var SchematicComponentMouseTarget = ({
|
|
|
2267
1553
|
bounds,
|
|
2268
1554
|
onClick: onComponentClick ? handleClick : void 0
|
|
2269
1555
|
});
|
|
2270
|
-
|
|
1556
|
+
useEffect9(() => {
|
|
2271
1557
|
if (onHoverChange) {
|
|
2272
1558
|
onHoverChange(componentId, hovering);
|
|
2273
1559
|
}
|
|
@@ -2276,7 +1562,7 @@ var SchematicComponentMouseTarget = ({
|
|
|
2276
1562
|
return null;
|
|
2277
1563
|
}
|
|
2278
1564
|
const rect = measurement.rect;
|
|
2279
|
-
return /* @__PURE__ */
|
|
1565
|
+
return /* @__PURE__ */ jsx6(
|
|
2280
1566
|
"div",
|
|
2281
1567
|
{
|
|
2282
1568
|
style: {
|
|
@@ -2294,8 +1580,8 @@ var SchematicComponentMouseTarget = ({
|
|
|
2294
1580
|
};
|
|
2295
1581
|
|
|
2296
1582
|
// lib/components/SchematicPortMouseTarget.tsx
|
|
2297
|
-
import { useCallback as useCallback5, useEffect as
|
|
2298
|
-
import { Fragment as Fragment2, jsx as
|
|
1583
|
+
import { useCallback as useCallback5, useEffect as useEffect10, useRef as useRef7, useState as useState4 } from "react";
|
|
1584
|
+
import { Fragment as Fragment2, jsx as jsx7, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
2299
1585
|
var areMeasurementsEqual2 = (a, b) => {
|
|
2300
1586
|
if (!a && !b) return true;
|
|
2301
1587
|
if (!a || !b) return false;
|
|
@@ -2311,7 +1597,7 @@ var SchematicPortMouseTarget = ({
|
|
|
2311
1597
|
showOutline,
|
|
2312
1598
|
circuitJsonKey
|
|
2313
1599
|
}) => {
|
|
2314
|
-
const [measurement, setMeasurement] =
|
|
1600
|
+
const [measurement, setMeasurement] = useState4(null);
|
|
2315
1601
|
const frameRef = useRef7(null);
|
|
2316
1602
|
const measure = useCallback5(() => {
|
|
2317
1603
|
frameRef.current = null;
|
|
@@ -2353,10 +1639,10 @@ var SchematicPortMouseTarget = ({
|
|
|
2353
1639
|
if (frameRef.current !== null) return;
|
|
2354
1640
|
frameRef.current = window.requestAnimationFrame(measure);
|
|
2355
1641
|
}, [measure]);
|
|
2356
|
-
|
|
1642
|
+
useEffect10(() => {
|
|
2357
1643
|
scheduleMeasure();
|
|
2358
1644
|
}, [scheduleMeasure, circuitJsonKey]);
|
|
2359
|
-
|
|
1645
|
+
useEffect10(() => {
|
|
2360
1646
|
scheduleMeasure();
|
|
2361
1647
|
const svgDiv = svgDivRef.current;
|
|
2362
1648
|
const container = containerRef.current;
|
|
@@ -2401,7 +1687,7 @@ var SchematicPortMouseTarget = ({
|
|
|
2401
1687
|
bounds,
|
|
2402
1688
|
onClick: onPortClick ? handleClick : void 0
|
|
2403
1689
|
});
|
|
2404
|
-
|
|
1690
|
+
useEffect10(() => {
|
|
2405
1691
|
if (onHoverChange) {
|
|
2406
1692
|
onHoverChange(portId, hovering);
|
|
2407
1693
|
}
|
|
@@ -2410,8 +1696,8 @@ var SchematicPortMouseTarget = ({
|
|
|
2410
1696
|
return null;
|
|
2411
1697
|
}
|
|
2412
1698
|
const rect = measurement.rect;
|
|
2413
|
-
return /* @__PURE__ */
|
|
2414
|
-
/* @__PURE__ */
|
|
1699
|
+
return /* @__PURE__ */ jsxs4(Fragment2, { children: [
|
|
1700
|
+
/* @__PURE__ */ jsx7(
|
|
2415
1701
|
"div",
|
|
2416
1702
|
{
|
|
2417
1703
|
style: {
|
|
@@ -2429,7 +1715,7 @@ var SchematicPortMouseTarget = ({
|
|
|
2429
1715
|
}
|
|
2430
1716
|
}
|
|
2431
1717
|
),
|
|
2432
|
-
hovering && portLabel && /* @__PURE__ */
|
|
1718
|
+
hovering && portLabel && /* @__PURE__ */ jsx7(
|
|
2433
1719
|
"div",
|
|
2434
1720
|
{
|
|
2435
1721
|
style: {
|
|
@@ -2454,9 +1740,9 @@ var SchematicPortMouseTarget = ({
|
|
|
2454
1740
|
};
|
|
2455
1741
|
|
|
2456
1742
|
// lib/components/SchematicSheetSelector.tsx
|
|
2457
|
-
import { useState as
|
|
1743
|
+
import { useState as useState5 } from "react";
|
|
2458
1744
|
import * as DropdownMenu2 from "@radix-ui/react-dropdown-menu";
|
|
2459
|
-
import { Fragment as Fragment3, jsx as
|
|
1745
|
+
import { Fragment as Fragment3, jsx as jsx8, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2460
1746
|
var FONT_FAMILY2 = 'system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif';
|
|
2461
1747
|
var contentStyles2 = {
|
|
2462
1748
|
backgroundColor: "#ffffff",
|
|
@@ -2506,7 +1792,7 @@ var MENU_CSS = `
|
|
|
2506
1792
|
.sv-sheet-chevron { transition: transform 0.2s ease; }
|
|
2507
1793
|
[data-state="open"] > .sv-sheet-chevron { transform: rotate(180deg); }
|
|
2508
1794
|
`;
|
|
2509
|
-
var CheckIcon2 = () => /* @__PURE__ */
|
|
1795
|
+
var CheckIcon2 = () => /* @__PURE__ */ jsx8(
|
|
2510
1796
|
"svg",
|
|
2511
1797
|
{
|
|
2512
1798
|
width: "14",
|
|
@@ -2518,10 +1804,10 @@ var CheckIcon2 = () => /* @__PURE__ */ jsx12(
|
|
|
2518
1804
|
strokeLinecap: "round",
|
|
2519
1805
|
strokeLinejoin: "round",
|
|
2520
1806
|
"aria-hidden": "true",
|
|
2521
|
-
children: /* @__PURE__ */
|
|
1807
|
+
children: /* @__PURE__ */ jsx8("path", { d: "M20 6 9 17l-5-5" })
|
|
2522
1808
|
}
|
|
2523
1809
|
);
|
|
2524
|
-
var ChevronDownIcon = ({ className }) => /* @__PURE__ */
|
|
1810
|
+
var ChevronDownIcon = ({ className }) => /* @__PURE__ */ jsx8(
|
|
2525
1811
|
"svg",
|
|
2526
1812
|
{
|
|
2527
1813
|
className,
|
|
@@ -2535,7 +1821,7 @@ var ChevronDownIcon = ({ className }) => /* @__PURE__ */ jsx12(
|
|
|
2535
1821
|
strokeLinejoin: "round",
|
|
2536
1822
|
style: { opacity: 0.6, flexShrink: 0 },
|
|
2537
1823
|
"aria-hidden": "true",
|
|
2538
|
-
children: /* @__PURE__ */
|
|
1824
|
+
children: /* @__PURE__ */ jsx8("path", { d: "m6 9 6 6 6-6" })
|
|
2539
1825
|
}
|
|
2540
1826
|
);
|
|
2541
1827
|
var SchematicSheetSelector = ({
|
|
@@ -2543,16 +1829,16 @@ var SchematicSheetSelector = ({
|
|
|
2543
1829
|
selectedSheetId,
|
|
2544
1830
|
onSelectSheet
|
|
2545
1831
|
}) => {
|
|
2546
|
-
const [open, setOpen] =
|
|
1832
|
+
const [open, setOpen] = useState5(false);
|
|
2547
1833
|
if (sheets.length <= 1) return null;
|
|
2548
1834
|
const selectedSheet = sheets.find(
|
|
2549
1835
|
(s) => s.schematic_sheet_id === selectedSheetId
|
|
2550
1836
|
);
|
|
2551
1837
|
const selectedLabel = selectedSheet?.name ?? "Select sheet";
|
|
2552
|
-
return /* @__PURE__ */
|
|
2553
|
-
/* @__PURE__ */
|
|
2554
|
-
/* @__PURE__ */
|
|
2555
|
-
/* @__PURE__ */
|
|
1838
|
+
return /* @__PURE__ */ jsxs5(Fragment3, { children: [
|
|
1839
|
+
/* @__PURE__ */ jsx8("style", { children: MENU_CSS }),
|
|
1840
|
+
/* @__PURE__ */ jsxs5(DropdownMenu2.Root, { open, onOpenChange: setOpen, modal: false, children: [
|
|
1841
|
+
/* @__PURE__ */ jsx8(DropdownMenu2.Trigger, { asChild: true, children: /* @__PURE__ */ jsxs5(
|
|
2556
1842
|
"button",
|
|
2557
1843
|
{
|
|
2558
1844
|
type: "button",
|
|
@@ -2579,13 +1865,13 @@ var SchematicSheetSelector = ({
|
|
|
2579
1865
|
zIndex: zIndexMap.viewMenuIcon
|
|
2580
1866
|
},
|
|
2581
1867
|
children: [
|
|
2582
|
-
/* @__PURE__ */
|
|
2583
|
-
/* @__PURE__ */
|
|
2584
|
-
/* @__PURE__ */
|
|
1868
|
+
/* @__PURE__ */ jsx8("span", { style: { color: "#888888", flexShrink: 0 }, children: "Sheet:" }),
|
|
1869
|
+
/* @__PURE__ */ jsx8("span", { style: { ...ellipsisStyles, minWidth: 0 }, children: selectedLabel }),
|
|
1870
|
+
/* @__PURE__ */ jsx8(ChevronDownIcon, { className: "sv-sheet-chevron" })
|
|
2585
1871
|
]
|
|
2586
1872
|
}
|
|
2587
1873
|
) }),
|
|
2588
|
-
/* @__PURE__ */
|
|
1874
|
+
/* @__PURE__ */ jsx8(DropdownMenu2.Portal, { children: /* @__PURE__ */ jsx8(
|
|
2589
1875
|
DropdownMenu2.Content,
|
|
2590
1876
|
{
|
|
2591
1877
|
style: contentStyles2,
|
|
@@ -2595,7 +1881,7 @@ var SchematicSheetSelector = ({
|
|
|
2595
1881
|
collisionPadding: 10,
|
|
2596
1882
|
children: sheets.map((sheet) => {
|
|
2597
1883
|
const selected = sheet.schematic_sheet_id === selectedSheetId;
|
|
2598
|
-
return /* @__PURE__ */
|
|
1884
|
+
return /* @__PURE__ */ jsxs5(
|
|
2599
1885
|
DropdownMenu2.Item,
|
|
2600
1886
|
{
|
|
2601
1887
|
className: "sv-sheet-item",
|
|
@@ -2607,8 +1893,8 @@ var SchematicSheetSelector = ({
|
|
|
2607
1893
|
setOpen(false);
|
|
2608
1894
|
},
|
|
2609
1895
|
children: [
|
|
2610
|
-
/* @__PURE__ */
|
|
2611
|
-
/* @__PURE__ */
|
|
1896
|
+
/* @__PURE__ */ jsx8("span", { style: iconSlotStyles2, children: selected && /* @__PURE__ */ jsx8(CheckIcon2, {}) }),
|
|
1897
|
+
/* @__PURE__ */ jsx8("span", { style: { ...ellipsisStyles, minWidth: 0 }, children: sheet.name })
|
|
2612
1898
|
]
|
|
2613
1899
|
},
|
|
2614
1900
|
sheet.schematic_sheet_id
|
|
@@ -2621,7 +1907,7 @@ var SchematicSheetSelector = ({
|
|
|
2621
1907
|
};
|
|
2622
1908
|
|
|
2623
1909
|
// lib/components/SchematicViewer.tsx
|
|
2624
|
-
import { jsx as
|
|
1910
|
+
import { jsx as jsx9, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2625
1911
|
var SchematicViewer = ({
|
|
2626
1912
|
circuitJson,
|
|
2627
1913
|
containerStyle,
|
|
@@ -2633,7 +1919,6 @@ var SchematicViewer = ({
|
|
|
2633
1919
|
debug: debug3 = false,
|
|
2634
1920
|
clickToInteractEnabled = false,
|
|
2635
1921
|
colorOverrides,
|
|
2636
|
-
spiceSimulationEnabled = false,
|
|
2637
1922
|
disableGroups = false,
|
|
2638
1923
|
netHoverHighlightEnabled = true,
|
|
2639
1924
|
onSchematicComponentClicked,
|
|
@@ -2646,23 +1931,14 @@ var SchematicViewer = ({
|
|
|
2646
1931
|
if (debug3) {
|
|
2647
1932
|
enableDebug();
|
|
2648
1933
|
}
|
|
2649
|
-
const [showSpiceOverlay, setShowSpiceOverlay] = useState8(false);
|
|
2650
|
-
const [spiceSimOptions, setSpiceSimOptions] = useState8({
|
|
2651
|
-
showVoltage: true,
|
|
2652
|
-
showCurrent: false,
|
|
2653
|
-
startTime: 0,
|
|
2654
|
-
// in ms
|
|
2655
|
-
duration: 20
|
|
2656
|
-
// in ms
|
|
2657
|
-
});
|
|
2658
1934
|
const getCircuitHash = (circuitJson2) => {
|
|
2659
1935
|
return `${circuitJson2?.length || 0}_${circuitJson2?.editCount || 0}`;
|
|
2660
1936
|
};
|
|
2661
|
-
const circuitJsonKey =
|
|
1937
|
+
const circuitJsonKey = useMemo4(
|
|
2662
1938
|
() => getCircuitHash(circuitJson),
|
|
2663
1939
|
[circuitJson]
|
|
2664
1940
|
);
|
|
2665
|
-
const schematicSheets =
|
|
1941
|
+
const schematicSheets = useMemo4(() => {
|
|
2666
1942
|
try {
|
|
2667
1943
|
return circuitJson.filter((elm) => elm?.type === "schematic_sheet").slice().sort((a, b) => (a.sheet_index ?? 0) - (b.sheet_index ?? 0));
|
|
2668
1944
|
} catch (err) {
|
|
@@ -2672,7 +1948,7 @@ var SchematicViewer = ({
|
|
|
2672
1948
|
}, [circuitJsonKey]);
|
|
2673
1949
|
const hasMultipleSheets = schematicSheets.length > 1;
|
|
2674
1950
|
const defaultSheetId = schematicSheets[0]?.schematic_sheet_id;
|
|
2675
|
-
const [selectedSheetId, setSelectedSheetId] =
|
|
1951
|
+
const [selectedSheetId, setSelectedSheetId] = useState6(
|
|
2676
1952
|
() => {
|
|
2677
1953
|
const stored = getStoredString(STORAGE_KEYS.SELECTED_SCHEMATIC_SHEET);
|
|
2678
1954
|
if (stored && schematicSheets.some((s) => s.schematic_sheet_id === stored)) {
|
|
@@ -2681,7 +1957,7 @@ var SchematicViewer = ({
|
|
|
2681
1957
|
return defaultSheetId;
|
|
2682
1958
|
}
|
|
2683
1959
|
);
|
|
2684
|
-
|
|
1960
|
+
useEffect11(() => {
|
|
2685
1961
|
const stillExists = selectedSheetId !== void 0 && schematicSheets.some((s) => s.schematic_sheet_id === selectedSheetId);
|
|
2686
1962
|
if (!stillExists) {
|
|
2687
1963
|
setSelectedSheetId(defaultSheetId);
|
|
@@ -2696,43 +1972,19 @@ var SchematicViewer = ({
|
|
|
2696
1972
|
},
|
|
2697
1973
|
[onSchematicSheetChange]
|
|
2698
1974
|
);
|
|
2699
|
-
const
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
return getSpiceFromCircuitJson(circuitJson, spiceSimOptions);
|
|
2703
|
-
} catch (e) {
|
|
2704
|
-
console.error("Failed to generate SPICE string", e);
|
|
2705
|
-
return null;
|
|
2706
|
-
}
|
|
2707
|
-
}, [
|
|
2708
|
-
circuitJsonKey,
|
|
2709
|
-
spiceSimulationEnabled,
|
|
2710
|
-
spiceSimOptions.startTime,
|
|
2711
|
-
spiceSimOptions.duration
|
|
2712
|
-
]);
|
|
2713
|
-
const [hasSpiceSimRun, setHasSpiceSimRun] = useState8(false);
|
|
2714
|
-
useEffect13(() => {
|
|
2715
|
-
setHasSpiceSimRun(false);
|
|
2716
|
-
}, [circuitJsonKey]);
|
|
2717
|
-
const {
|
|
2718
|
-
plotData,
|
|
2719
|
-
nodes,
|
|
2720
|
-
isLoading: isSpiceSimLoading,
|
|
2721
|
-
error: spiceSimError
|
|
2722
|
-
} = useSpiceSimulation(hasSpiceSimRun ? spiceString : null);
|
|
2723
|
-
const [editModeEnabled, setEditModeEnabled] = useState8(defaultEditMode);
|
|
2724
|
-
const [snapToGrid, setSnapToGrid] = useState8(true);
|
|
2725
|
-
const [showGridInternal, setShowGridInternal] = useState8(false);
|
|
1975
|
+
const [editModeEnabled, setEditModeEnabled] = useState6(defaultEditMode);
|
|
1976
|
+
const [snapToGrid, setSnapToGrid] = useState6(true);
|
|
1977
|
+
const [showGridInternal, setShowGridInternal] = useState6(false);
|
|
2726
1978
|
const showGrid = debugGrid || showGridInternal;
|
|
2727
|
-
const [isInteractionEnabled, setIsInteractionEnabled] =
|
|
1979
|
+
const [isInteractionEnabled, setIsInteractionEnabled] = useState6(
|
|
2728
1980
|
!clickToInteractEnabled
|
|
2729
1981
|
);
|
|
2730
|
-
const [showViewMenu, setShowViewMenu] =
|
|
2731
|
-
const [showSchematicGroups, setShowSchematicGroups] =
|
|
1982
|
+
const [showViewMenu, setShowViewMenu] = useState6(false);
|
|
1983
|
+
const [showSchematicGroups, setShowSchematicGroups] = useState6(() => {
|
|
2732
1984
|
if (disableGroups) return false;
|
|
2733
1985
|
return getStoredBoolean("schematic_viewer_show_groups", false);
|
|
2734
1986
|
});
|
|
2735
|
-
const [isHoveringClickableComponent, setIsHoveringClickableComponent] =
|
|
1987
|
+
const [isHoveringClickableComponent, setIsHoveringClickableComponent] = useState6(false);
|
|
2736
1988
|
const hoveringComponentsRef = useRef8(/* @__PURE__ */ new Set());
|
|
2737
1989
|
const handleComponentHoverChange = useCallback6(
|
|
2738
1990
|
(componentId, isHovering) => {
|
|
@@ -2745,7 +1997,7 @@ var SchematicViewer = ({
|
|
|
2745
1997
|
},
|
|
2746
1998
|
[]
|
|
2747
1999
|
);
|
|
2748
|
-
const [isHoveringClickablePort, setIsHoveringClickablePort] =
|
|
2000
|
+
const [isHoveringClickablePort, setIsHoveringClickablePort] = useState6(false);
|
|
2749
2001
|
const hoveringPortsRef = useRef8(/* @__PURE__ */ new Set());
|
|
2750
2002
|
const handlePortHoverChange = useCallback6(
|
|
2751
2003
|
(portId, isHovering) => {
|
|
@@ -2760,7 +2012,7 @@ var SchematicViewer = ({
|
|
|
2760
2012
|
);
|
|
2761
2013
|
const svgDivRef = useRef8(null);
|
|
2762
2014
|
const touchStartRef = useRef8(null);
|
|
2763
|
-
const schematicComponentIds =
|
|
2015
|
+
const schematicComponentIds = useMemo4(() => {
|
|
2764
2016
|
try {
|
|
2765
2017
|
const components = su7(circuitJson).schematic_component?.list() ?? [];
|
|
2766
2018
|
return components.filter(
|
|
@@ -2771,7 +2023,7 @@ var SchematicViewer = ({
|
|
|
2771
2023
|
return [];
|
|
2772
2024
|
}
|
|
2773
2025
|
}, [circuitJsonKey, circuitJson, activeSheetId]);
|
|
2774
|
-
const schematicPortsInfo =
|
|
2026
|
+
const schematicPortsInfo = useMemo4(() => {
|
|
2775
2027
|
if (!showSchematicPorts) return [];
|
|
2776
2028
|
try {
|
|
2777
2029
|
const ports = (su7(circuitJson).schematic_port?.list() ?? []).filter(
|
|
@@ -2811,9 +2063,9 @@ var SchematicViewer = ({
|
|
|
2811
2063
|
}
|
|
2812
2064
|
touchStartRef.current = null;
|
|
2813
2065
|
};
|
|
2814
|
-
const [internalEditEvents, setInternalEditEvents] =
|
|
2066
|
+
const [internalEditEvents, setInternalEditEvents] = useState6([]);
|
|
2815
2067
|
const circuitJsonRef = useRef8(circuitJson);
|
|
2816
|
-
|
|
2068
|
+
useEffect11(() => {
|
|
2817
2069
|
const circuitHash = getCircuitHash(circuitJson);
|
|
2818
2070
|
const circuitHashRef = getCircuitHash(circuitJsonRef.current);
|
|
2819
2071
|
if (circuitHash !== circuitHashRef) {
|
|
@@ -2831,10 +2083,10 @@ var SchematicViewer = ({
|
|
|
2831
2083
|
svgDivRef.current.style.transform = transformToString(transform);
|
|
2832
2084
|
},
|
|
2833
2085
|
// @ts-ignore disabled is a valid prop but not typed
|
|
2834
|
-
enabled: isInteractionEnabled
|
|
2086
|
+
enabled: isInteractionEnabled
|
|
2835
2087
|
});
|
|
2836
2088
|
const { containerWidth, containerHeight } = useResizeHandling(containerRef);
|
|
2837
|
-
const svgString =
|
|
2089
|
+
const svgString = useMemo4(() => {
|
|
2838
2090
|
if (!containerWidth || !containerHeight) return "";
|
|
2839
2091
|
return convertCircuitJsonToSchematicSvg(circuitJson, {
|
|
2840
2092
|
width: containerWidth,
|
|
@@ -2857,13 +2109,13 @@ var SchematicViewer = ({
|
|
|
2857
2109
|
showSchematicPorts,
|
|
2858
2110
|
activeSheetId
|
|
2859
2111
|
]);
|
|
2860
|
-
const containerBackgroundColor =
|
|
2112
|
+
const containerBackgroundColor = useMemo4(() => {
|
|
2861
2113
|
const match = svgString.match(
|
|
2862
2114
|
/<svg[^>]*style="[^"]*background-color:\s*([^;\"]+)/i
|
|
2863
2115
|
);
|
|
2864
2116
|
return match?.[1] ?? "transparent";
|
|
2865
2117
|
}, [svgString]);
|
|
2866
|
-
const realToSvgProjection =
|
|
2118
|
+
const realToSvgProjection = useMemo4(() => {
|
|
2867
2119
|
if (!svgString) return identity();
|
|
2868
2120
|
const transformString = svgString.match(
|
|
2869
2121
|
/data-real-to-screen-transform="([^"]+)"/
|
|
@@ -2881,7 +2133,7 @@ var SchematicViewer = ({
|
|
|
2881
2133
|
onEditEvent(event);
|
|
2882
2134
|
}
|
|
2883
2135
|
};
|
|
2884
|
-
const editEventsWithUnappliedEditEvents =
|
|
2136
|
+
const editEventsWithUnappliedEditEvents = useMemo4(() => {
|
|
2885
2137
|
return [...unappliedEditEvents, ...internalEditEvents];
|
|
2886
2138
|
}, [unappliedEditEvents, internalEditEvents]);
|
|
2887
2139
|
const {
|
|
@@ -2896,7 +2148,7 @@ var SchematicViewer = ({
|
|
|
2896
2148
|
svgToScreenProjection,
|
|
2897
2149
|
circuitJson,
|
|
2898
2150
|
editEvents: editEventsWithUnappliedEditEvents,
|
|
2899
|
-
enabled: editModeEnabled && isInteractionEnabled
|
|
2151
|
+
enabled: editModeEnabled && isInteractionEnabled,
|
|
2900
2152
|
snapToGrid
|
|
2901
2153
|
});
|
|
2902
2154
|
useChangeSchematicComponentLocationsInSvg({
|
|
@@ -2925,11 +2177,11 @@ var SchematicViewer = ({
|
|
|
2925
2177
|
enabled: netHoverHighlightEnabled
|
|
2926
2178
|
});
|
|
2927
2179
|
const handleComponentTouchStartRef = useRef8(handleComponentTouchStart);
|
|
2928
|
-
|
|
2180
|
+
useEffect11(() => {
|
|
2929
2181
|
handleComponentTouchStartRef.current = handleComponentTouchStart;
|
|
2930
2182
|
}, [handleComponentTouchStart]);
|
|
2931
|
-
const svgDiv =
|
|
2932
|
-
() => /* @__PURE__ */
|
|
2183
|
+
const svgDiv = useMemo4(
|
|
2184
|
+
() => /* @__PURE__ */ jsx9(
|
|
2933
2185
|
"div",
|
|
2934
2186
|
{
|
|
2935
2187
|
ref: svgDivRef,
|
|
@@ -2939,27 +2191,21 @@ var SchematicViewer = ({
|
|
|
2939
2191
|
},
|
|
2940
2192
|
className: onSchematicComponentClicked ? "schematic-component-clickable" : void 0,
|
|
2941
2193
|
onTouchStart: (e) => {
|
|
2942
|
-
if (editModeEnabled && isInteractionEnabled
|
|
2194
|
+
if (editModeEnabled && isInteractionEnabled) {
|
|
2943
2195
|
handleComponentTouchStartRef.current(e);
|
|
2944
2196
|
}
|
|
2945
2197
|
},
|
|
2946
2198
|
dangerouslySetInnerHTML: { __html: svgString }
|
|
2947
2199
|
}
|
|
2948
2200
|
),
|
|
2949
|
-
[
|
|
2950
|
-
svgString,
|
|
2951
|
-
isInteractionEnabled,
|
|
2952
|
-
clickToInteractEnabled,
|
|
2953
|
-
editModeEnabled,
|
|
2954
|
-
showSpiceOverlay
|
|
2955
|
-
]
|
|
2201
|
+
[svgString, isInteractionEnabled, clickToInteractEnabled, editModeEnabled]
|
|
2956
2202
|
);
|
|
2957
|
-
return /* @__PURE__ */
|
|
2958
|
-
netHoverHighlightEnabled && /* @__PURE__ */
|
|
2203
|
+
return /* @__PURE__ */ jsxs6(MouseTracker, { children: [
|
|
2204
|
+
netHoverHighlightEnabled && /* @__PURE__ */ jsx9("style", { children: `.sch-net-faded { opacity: 0.35; }
|
|
2959
2205
|
svg :is(g.trace, g.trace-overlays, g[data-schematic-component-id], [data-schematic-net-label-id]) { transition: opacity 0.12s ease-in-out; }` }),
|
|
2960
|
-
onSchematicComponentClicked && /* @__PURE__ */
|
|
2961
|
-
onSchematicPortClicked && /* @__PURE__ */
|
|
2962
|
-
/* @__PURE__ */
|
|
2206
|
+
onSchematicComponentClicked && /* @__PURE__ */ jsx9("style", { children: `.schematic-component-clickable [data-schematic-component-id]:hover { cursor: pointer !important; }` }),
|
|
2207
|
+
onSchematicPortClicked && /* @__PURE__ */ jsx9("style", { children: `[data-schematic-port-id]:hover { cursor: pointer !important; }` }),
|
|
2208
|
+
/* @__PURE__ */ jsxs6(
|
|
2963
2209
|
"div",
|
|
2964
2210
|
{
|
|
2965
2211
|
ref: containerRef,
|
|
@@ -2967,15 +2213,10 @@ var SchematicViewer = ({
|
|
|
2967
2213
|
position: "relative",
|
|
2968
2214
|
backgroundColor: containerBackgroundColor,
|
|
2969
2215
|
overflow: "hidden",
|
|
2970
|
-
cursor:
|
|
2216
|
+
cursor: isDragging ? "grabbing" : clickToInteractEnabled && !isInteractionEnabled ? "pointer" : isHoveringClickableComponent && onSchematicComponentClicked ? "pointer" : isHoveringClickablePort && onSchematicPortClicked ? "pointer" : "grab",
|
|
2971
2217
|
minHeight: "300px",
|
|
2972
2218
|
...containerStyle
|
|
2973
2219
|
},
|
|
2974
|
-
onWheelCapture: (e) => {
|
|
2975
|
-
if (showSpiceOverlay) {
|
|
2976
|
-
e.stopPropagation();
|
|
2977
|
-
}
|
|
2978
|
-
},
|
|
2979
2220
|
onMouseDown: (e) => {
|
|
2980
2221
|
if (clickToInteractEnabled && !isInteractionEnabled) {
|
|
2981
2222
|
e.preventDefault();
|
|
@@ -2991,16 +2232,10 @@ var SchematicViewer = ({
|
|
|
2991
2232
|
return;
|
|
2992
2233
|
}
|
|
2993
2234
|
},
|
|
2994
|
-
onTouchStart:
|
|
2995
|
-
|
|
2996
|
-
handleTouchStart(e);
|
|
2997
|
-
},
|
|
2998
|
-
onTouchEnd: (e) => {
|
|
2999
|
-
if (showSpiceOverlay) return;
|
|
3000
|
-
handleTouchEnd(e);
|
|
3001
|
-
},
|
|
2235
|
+
onTouchStart: handleTouchStart,
|
|
2236
|
+
onTouchEnd: handleTouchEnd,
|
|
3002
2237
|
children: [
|
|
3003
|
-
!isInteractionEnabled && clickToInteractEnabled && /* @__PURE__ */
|
|
2238
|
+
!isInteractionEnabled && clickToInteractEnabled && /* @__PURE__ */ jsx9(
|
|
3004
2239
|
"div",
|
|
3005
2240
|
{
|
|
3006
2241
|
onClick: (e) => {
|
|
@@ -3019,7 +2254,7 @@ var SchematicViewer = ({
|
|
|
3019
2254
|
pointerEvents: "all",
|
|
3020
2255
|
touchAction: "pan-x pan-y pinch-zoom"
|
|
3021
2256
|
},
|
|
3022
|
-
children: /* @__PURE__ */
|
|
2257
|
+
children: /* @__PURE__ */ jsx9(
|
|
3023
2258
|
"div",
|
|
3024
2259
|
{
|
|
3025
2260
|
style: {
|
|
@@ -3036,21 +2271,21 @@ var SchematicViewer = ({
|
|
|
3036
2271
|
)
|
|
3037
2272
|
}
|
|
3038
2273
|
),
|
|
3039
|
-
editingEnabled && /* @__PURE__ */
|
|
2274
|
+
editingEnabled && /* @__PURE__ */ jsx9(
|
|
3040
2275
|
EditIcon,
|
|
3041
2276
|
{
|
|
3042
2277
|
active: editModeEnabled,
|
|
3043
2278
|
onClick: () => setEditModeEnabled(!editModeEnabled)
|
|
3044
2279
|
}
|
|
3045
2280
|
),
|
|
3046
|
-
editingEnabled && editModeEnabled && /* @__PURE__ */
|
|
2281
|
+
editingEnabled && editModeEnabled && /* @__PURE__ */ jsx9(
|
|
3047
2282
|
GridIcon,
|
|
3048
2283
|
{
|
|
3049
2284
|
active: snapToGrid,
|
|
3050
2285
|
onClick: () => setSnapToGrid(!snapToGrid)
|
|
3051
2286
|
}
|
|
3052
2287
|
),
|
|
3053
|
-
/* @__PURE__ */
|
|
2288
|
+
/* @__PURE__ */ jsx9(
|
|
3054
2289
|
ViewMenu,
|
|
3055
2290
|
{
|
|
3056
2291
|
circuitJson,
|
|
@@ -3068,7 +2303,7 @@ var SchematicViewer = ({
|
|
|
3068
2303
|
onToggleGrid: setShowGridInternal
|
|
3069
2304
|
}
|
|
3070
2305
|
),
|
|
3071
|
-
/* @__PURE__ */
|
|
2306
|
+
/* @__PURE__ */ jsx9(
|
|
3072
2307
|
SchematicSheetSelector,
|
|
3073
2308
|
{
|
|
3074
2309
|
sheets: schematicSheets,
|
|
@@ -3076,25 +2311,7 @@ var SchematicViewer = ({
|
|
|
3076
2311
|
onSelectSheet: handleSelectSheet
|
|
3077
2312
|
}
|
|
3078
2313
|
),
|
|
3079
|
-
|
|
3080
|
-
showSpiceOverlay && /* @__PURE__ */ jsx13(
|
|
3081
|
-
SpiceSimulationOverlay,
|
|
3082
|
-
{
|
|
3083
|
-
spiceString,
|
|
3084
|
-
onClose: () => setShowSpiceOverlay(false),
|
|
3085
|
-
plotData,
|
|
3086
|
-
nodes,
|
|
3087
|
-
isLoading: isSpiceSimLoading,
|
|
3088
|
-
error: spiceSimError,
|
|
3089
|
-
simOptions: spiceSimOptions,
|
|
3090
|
-
onSimOptionsChange: (options) => {
|
|
3091
|
-
setHasSpiceSimRun(true);
|
|
3092
|
-
setSpiceSimOptions(options);
|
|
3093
|
-
},
|
|
3094
|
-
hasRun: hasSpiceSimRun
|
|
3095
|
-
}
|
|
3096
|
-
),
|
|
3097
|
-
onSchematicComponentClicked && schematicComponentIds.map((componentId) => /* @__PURE__ */ jsx13(
|
|
2314
|
+
onSchematicComponentClicked && schematicComponentIds.map((componentId) => /* @__PURE__ */ jsx9(
|
|
3098
2315
|
SchematicComponentMouseTarget,
|
|
3099
2316
|
{
|
|
3100
2317
|
componentId,
|
|
@@ -3113,7 +2330,7 @@ var SchematicViewer = ({
|
|
|
3113
2330
|
componentId
|
|
3114
2331
|
)),
|
|
3115
2332
|
svgDiv,
|
|
3116
|
-
showSchematicPorts && schematicPortsInfo.map(({ portId, label }) => /* @__PURE__ */
|
|
2333
|
+
showSchematicPorts && schematicPortsInfo.map(({ portId, label }) => /* @__PURE__ */ jsx9(
|
|
3117
2334
|
SchematicPortMouseTarget,
|
|
3118
2335
|
{
|
|
3119
2336
|
portId,
|
|
@@ -3142,10 +2359,10 @@ var SchematicViewer = ({
|
|
|
3142
2359
|
import {
|
|
3143
2360
|
convertCircuitJsonToSchematicSimulationSvg
|
|
3144
2361
|
} from "circuit-to-svg";
|
|
3145
|
-
import { useEffect as
|
|
2362
|
+
import { useEffect as useEffect12, useState as useState7, useMemo as useMemo5, useRef as useRef9 } from "react";
|
|
3146
2363
|
import { useMouseMatrixTransform as useMouseMatrixTransform2 } from "use-mouse-matrix-transform";
|
|
3147
2364
|
import { toString as transformToString2 } from "transformation-matrix";
|
|
3148
|
-
import { jsx as
|
|
2365
|
+
import { jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
3149
2366
|
var DEFAULT_RENDER_WIDTH = 1200;
|
|
3150
2367
|
var DEFAULT_RENDER_ASPECT_RATIO = 1;
|
|
3151
2368
|
var AnalogSimulationViewer = ({
|
|
@@ -3156,16 +2373,16 @@ var AnalogSimulationViewer = ({
|
|
|
3156
2373
|
height,
|
|
3157
2374
|
className
|
|
3158
2375
|
}) => {
|
|
3159
|
-
const [circuitJson, setCircuitJson] =
|
|
3160
|
-
const [isLoading, setIsLoading] =
|
|
3161
|
-
const [error, setError] =
|
|
3162
|
-
const [svgObjectUrl, setSvgObjectUrl] =
|
|
2376
|
+
const [circuitJson, setCircuitJson] = useState7(null);
|
|
2377
|
+
const [isLoading, setIsLoading] = useState7(true);
|
|
2378
|
+
const [error, setError] = useState7(null);
|
|
2379
|
+
const [svgObjectUrl, setSvgObjectUrl] = useState7(null);
|
|
3163
2380
|
const containerRef = useRef9(null);
|
|
3164
2381
|
const imgRef = useRef9(null);
|
|
3165
2382
|
const { containerWidth } = useResizeHandling(
|
|
3166
2383
|
containerRef
|
|
3167
2384
|
);
|
|
3168
|
-
const [isDragging, setIsDragging] =
|
|
2385
|
+
const [isDragging, setIsDragging] = useState7(false);
|
|
3169
2386
|
const {
|
|
3170
2387
|
ref: transformRef,
|
|
3171
2388
|
cancelDrag: _cancelDrag,
|
|
@@ -3180,28 +2397,28 @@ var AnalogSimulationViewer = ({
|
|
|
3180
2397
|
const renderAspectRatio = width && height ? width / height : DEFAULT_RENDER_ASPECT_RATIO;
|
|
3181
2398
|
const effectiveWidth = width || (height ? height * renderAspectRatio : containerWidth) || DEFAULT_RENDER_WIDTH;
|
|
3182
2399
|
const effectiveHeight = height || effectiveWidth / renderAspectRatio;
|
|
3183
|
-
|
|
2400
|
+
useEffect12(() => {
|
|
3184
2401
|
setIsLoading(true);
|
|
3185
2402
|
setError(null);
|
|
3186
2403
|
setCircuitJson(inputCircuitJson);
|
|
3187
2404
|
setIsLoading(false);
|
|
3188
2405
|
}, [inputCircuitJson]);
|
|
3189
|
-
const simulationExperimentId =
|
|
2406
|
+
const simulationExperimentId = useMemo5(() => {
|
|
3190
2407
|
if (!circuitJson) return null;
|
|
3191
2408
|
const simulationElement = circuitJson.find(
|
|
3192
2409
|
(el) => el.type === "simulation_experiment"
|
|
3193
2410
|
);
|
|
3194
2411
|
return simulationElement?.simulation_experiment_id || null;
|
|
3195
2412
|
}, [circuitJson]);
|
|
3196
|
-
const simulationVoltageGraphIds =
|
|
2413
|
+
const simulationVoltageGraphIds = useMemo5(() => {
|
|
3197
2414
|
if (!circuitJson) return [];
|
|
3198
2415
|
return circuitJson.filter((el) => el.type === "simulation_transient_voltage_graph").map((el) => el.simulation_transient_voltage_graph_id);
|
|
3199
2416
|
}, [circuitJson]);
|
|
3200
|
-
const simulationCurrentGraphIds =
|
|
2417
|
+
const simulationCurrentGraphIds = useMemo5(() => {
|
|
3201
2418
|
if (!circuitJson) return [];
|
|
3202
2419
|
return circuitJson.filter((el) => el.type === "simulation_transient_current_graph").map((el) => el.simulation_transient_current_graph_id);
|
|
3203
2420
|
}, [circuitJson]);
|
|
3204
|
-
const simulationSvg =
|
|
2421
|
+
const simulationSvg = useMemo5(() => {
|
|
3205
2422
|
if (!circuitJson || !effectiveWidth || !effectiveHeight || !simulationExperimentId)
|
|
3206
2423
|
return "";
|
|
3207
2424
|
try {
|
|
@@ -3227,7 +2444,7 @@ var AnalogSimulationViewer = ({
|
|
|
3227
2444
|
simulationCurrentGraphIds,
|
|
3228
2445
|
simulationVoltageGraphIds
|
|
3229
2446
|
]);
|
|
3230
|
-
|
|
2447
|
+
useEffect12(() => {
|
|
3231
2448
|
if (!simulationSvg) {
|
|
3232
2449
|
setSvgObjectUrl(null);
|
|
3233
2450
|
return;
|
|
@@ -3244,7 +2461,7 @@ var AnalogSimulationViewer = ({
|
|
|
3244
2461
|
setSvgObjectUrl(null);
|
|
3245
2462
|
}
|
|
3246
2463
|
}, [simulationSvg]);
|
|
3247
|
-
const containerBackgroundColor =
|
|
2464
|
+
const containerBackgroundColor = useMemo5(() => {
|
|
3248
2465
|
if (!simulationSvg) return "transparent";
|
|
3249
2466
|
const match = simulationSvg.match(
|
|
3250
2467
|
/<svg[^>]*style="[^"]*background-color:\s*([^;\"]+)/i
|
|
@@ -3257,7 +2474,7 @@ var AnalogSimulationViewer = ({
|
|
|
3257
2474
|
const handleTouchStart = (_e) => {
|
|
3258
2475
|
setIsDragging(true);
|
|
3259
2476
|
};
|
|
3260
|
-
|
|
2477
|
+
useEffect12(() => {
|
|
3261
2478
|
const handleMouseUp = () => {
|
|
3262
2479
|
setIsDragging(false);
|
|
3263
2480
|
};
|
|
@@ -3272,7 +2489,7 @@ var AnalogSimulationViewer = ({
|
|
|
3272
2489
|
};
|
|
3273
2490
|
}, []);
|
|
3274
2491
|
if (isLoading) {
|
|
3275
|
-
return /* @__PURE__ */
|
|
2492
|
+
return /* @__PURE__ */ jsx10(
|
|
3276
2493
|
"div",
|
|
3277
2494
|
{
|
|
3278
2495
|
style: {
|
|
@@ -3292,7 +2509,7 @@ var AnalogSimulationViewer = ({
|
|
|
3292
2509
|
);
|
|
3293
2510
|
}
|
|
3294
2511
|
if (error) {
|
|
3295
|
-
return /* @__PURE__ */
|
|
2512
|
+
return /* @__PURE__ */ jsx10(
|
|
3296
2513
|
"div",
|
|
3297
2514
|
{
|
|
3298
2515
|
style: {
|
|
@@ -3307,15 +2524,15 @@ var AnalogSimulationViewer = ({
|
|
|
3307
2524
|
...containerStyle
|
|
3308
2525
|
},
|
|
3309
2526
|
className,
|
|
3310
|
-
children: /* @__PURE__ */
|
|
3311
|
-
/* @__PURE__ */
|
|
3312
|
-
/* @__PURE__ */
|
|
2527
|
+
children: /* @__PURE__ */ jsxs7("div", { style: { textAlign: "center", padding: "20px" }, children: [
|
|
2528
|
+
/* @__PURE__ */ jsx10("div", { style: { fontWeight: "bold", marginBottom: "8px" }, children: "Circuit Conversion Error" }),
|
|
2529
|
+
/* @__PURE__ */ jsx10("div", { style: { fontSize: "14px" }, children: error })
|
|
3313
2530
|
] })
|
|
3314
2531
|
}
|
|
3315
2532
|
);
|
|
3316
2533
|
}
|
|
3317
2534
|
if (!simulationSvg) {
|
|
3318
|
-
return /* @__PURE__ */
|
|
2535
|
+
return /* @__PURE__ */ jsxs7(
|
|
3319
2536
|
"div",
|
|
3320
2537
|
{
|
|
3321
2538
|
style: {
|
|
@@ -3331,11 +2548,11 @@ var AnalogSimulationViewer = ({
|
|
|
3331
2548
|
},
|
|
3332
2549
|
className,
|
|
3333
2550
|
children: [
|
|
3334
|
-
/* @__PURE__ */
|
|
3335
|
-
/* @__PURE__ */
|
|
2551
|
+
/* @__PURE__ */ jsx10("div", { style: { fontSize: "16px", color: "#475569", fontWeight: 500 }, children: "No Simulation Found" }),
|
|
2552
|
+
/* @__PURE__ */ jsxs7("div", { style: { fontSize: "14px", color: "#64748b" }, children: [
|
|
3336
2553
|
"Use",
|
|
3337
2554
|
" ",
|
|
3338
|
-
/* @__PURE__ */
|
|
2555
|
+
/* @__PURE__ */ jsx10(
|
|
3339
2556
|
"code",
|
|
3340
2557
|
{
|
|
3341
2558
|
style: {
|
|
@@ -3355,7 +2572,7 @@ var AnalogSimulationViewer = ({
|
|
|
3355
2572
|
}
|
|
3356
2573
|
);
|
|
3357
2574
|
}
|
|
3358
|
-
return /* @__PURE__ */
|
|
2575
|
+
return /* @__PURE__ */ jsx10(
|
|
3359
2576
|
"div",
|
|
3360
2577
|
{
|
|
3361
2578
|
ref: (node) => {
|
|
@@ -3373,7 +2590,7 @@ var AnalogSimulationViewer = ({
|
|
|
3373
2590
|
className,
|
|
3374
2591
|
onMouseDown: handleMouseDown,
|
|
3375
2592
|
onTouchStart: handleTouchStart,
|
|
3376
|
-
children: svgObjectUrl ? /* @__PURE__ */
|
|
2593
|
+
children: svgObjectUrl ? /* @__PURE__ */ jsx10(
|
|
3377
2594
|
"img",
|
|
3378
2595
|
{
|
|
3379
2596
|
ref: imgRef,
|
|
@@ -3387,7 +2604,7 @@ var AnalogSimulationViewer = ({
|
|
|
3387
2604
|
objectFit: "contain"
|
|
3388
2605
|
}
|
|
3389
2606
|
}
|
|
3390
|
-
) : /* @__PURE__ */
|
|
2607
|
+
) : /* @__PURE__ */ jsx10(
|
|
3391
2608
|
"div",
|
|
3392
2609
|
{
|
|
3393
2610
|
style: {
|