@tscircuit/schematic-viewer 1.3.0 → 1.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. package/README.md +1 -1
  2. package/biome.json +45 -0
  3. package/dist/index.d.ts +3 -4
  4. package/dist/index.js +734 -688
  5. package/dist/index.js.map +1 -1
  6. package/package.json +8 -7
  7. package/src/Schematic.tsx +141 -65
  8. package/src/lib/render-context/index.ts +1 -1
  9. package/src/lib/types/core.ts +14 -49
  10. package/src/lib/types/source-component.ts +6 -1
  11. package/src/lib/utils/collect-element-refs.ts +5 -4
  12. package/src/lib/utils/colors.ts +235 -0
  13. package/src/lib/utils/direction-to-vec.ts +3 -3
  14. package/src/schematic-components/SVGPathComponent.tsx +71 -112
  15. package/src/schematic-components/SchematicChip.tsx +222 -0
  16. package/src/schematic-components/SchematicComponent.tsx +25 -22
  17. package/src/schematic-components/SchematicComponentFromSymbol.tsx +46 -0
  18. package/src/schematic-components/SchematicElement.tsx +0 -28
  19. package/src/schematic-components/SchematicNetLabel.tsx +3 -0
  20. package/src/schematic-components/SchematicText.tsx +4 -6
  21. package/src/schematic-components/SchematicTrace.tsx +4 -3
  22. package/src/schematic-components/TableViewer.tsx +1 -1
  23. package/src/schematic-components/index.tsx +6 -14
  24. package/src/stories/basics/schematic-net-label.stories.tsx +2 -0
  25. package/src/stories/basics/schematic-net-labels-2.stories.tsx +22 -20
  26. package/src/stories/bug-connections.stories.tsx +18 -13
  27. package/src/stories/bug-high-port-numbers.stories.tsx +107 -85
  28. package/src/stories/bug-one-sided.stories.tsx +17 -15
  29. package/src/stories/bug-pin-spacing.stories.tsx +19 -17
  30. package/src/stories/bugs/bug1-y-flip.stories.tsx +7 -5
  31. package/src/stories/bugs/bug3-scaling-trace.stories.tsx +11 -5
  32. package/src/stories/bugs/bug4-schematic-line.stories.tsx +0 -1
  33. package/src/stories/bugs/bug5-diode.stories.tsx +3 -2
  34. package/src/stories/bugs/bug6-trace-scaling.stories.tsx +5 -41
  35. package/src/stories/bugs/bug8-autolayout.stories.tsx +20 -29
  36. package/src/stories/circuit-components/diode.stories.tsx +3 -1
  37. package/src/stories/circuit-components/resistor.stories.tsx +3 -1
  38. package/src/stories/led-circuit-react.stories.tsx +35 -48
  39. package/src/stories/rotated-resistor.stories.tsx +10 -8
  40. package/src/stories/three-sided-bug.stories.tsx +17 -15
  41. package/src/pages/led-circuit.tsx +0 -96
  42. package/src/schematic-components/ProjectComponent.tsx +0 -70
  43. package/src/schematic-components/SchematicBox.tsx +0 -29
  44. package/src/schematic-components/SchematicBug.tsx +0 -107
  45. package/src/schematic-components/SchematicLine.tsx +0 -48
  46. package/src/schematic-components/SchematicPath.tsx +0 -51
  47. package/src/schematic-components/SchematicPort.tsx +0 -63
  48. package/src/schematic-components/SimpleCapacitor.tsx +0 -29
  49. package/src/schematic-components/SimpleDiode.tsx +0 -42
  50. package/src/schematic-components/SimpleGround.tsx +0 -30
  51. package/src/schematic-components/SimpleInductor.tsx +0 -29
  52. package/src/schematic-components/SimplePowerSource.tsx +0 -43
  53. package/src/schematic-components/SimpleResistor.tsx +0 -28
  54. package/src/stories/led-circuit-builder.stories.tsx +0 -104
package/dist/index.js CHANGED
@@ -89,8 +89,8 @@ var require_use_sync_external_store_shim_development = __commonJS({
89
89
  if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === "function") {
90
90
  __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
91
91
  }
92
- var React = require("react");
93
- var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
92
+ var React2 = require("react");
93
+ var ReactSharedInternals = React2.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;
94
94
  function error(format) {
95
95
  {
96
96
  {
@@ -120,13 +120,13 @@ var require_use_sync_external_store_shim_development = __commonJS({
120
120
  return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y;
121
121
  }
122
122
  var objectIs = typeof Object.is === "function" ? Object.is : is;
123
- var useState5 = React.useState, useEffect4 = React.useEffect, useLayoutEffect = React.useLayoutEffect, useDebugValue2 = React.useDebugValue;
123
+ var useState4 = React2.useState, useEffect3 = React2.useEffect, useLayoutEffect = React2.useLayoutEffect, useDebugValue2 = React2.useDebugValue;
124
124
  var didWarnOld18Alpha = false;
125
125
  var didWarnUncachedGetSnapshot = false;
126
126
  function useSyncExternalStore(subscribe, getSnapshot, getServerSnapshot) {
127
127
  {
128
128
  if (!didWarnOld18Alpha) {
129
- if (React.startTransition !== void 0) {
129
+ if (React2.startTransition !== void 0) {
130
130
  didWarnOld18Alpha = true;
131
131
  error("You are using an outdated, pre-release alpha of React 18 that does not support useSyncExternalStore. The use-sync-external-store shim will not work correctly. Upgrade to a newer pre-release.");
132
132
  }
@@ -142,7 +142,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
142
142
  }
143
143
  }
144
144
  }
145
- var _useState = useState5({
145
+ var _useState = useState4({
146
146
  inst: {
147
147
  value,
148
148
  getSnapshot
@@ -157,7 +157,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
157
157
  });
158
158
  }
159
159
  }, [subscribe, value, getSnapshot]);
160
- useEffect4(function() {
160
+ useEffect3(function() {
161
161
  if (checkIfSnapshotChanged(inst)) {
162
162
  forceUpdate({
163
163
  inst
@@ -191,7 +191,7 @@ var require_use_sync_external_store_shim_development = __commonJS({
191
191
  var canUseDOM = !!(typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.document.createElement !== "undefined");
192
192
  var isServerEnvironment = !canUseDOM;
193
193
  var shim = isServerEnvironment ? useSyncExternalStore$1 : useSyncExternalStore;
194
- var useSyncExternalStore$2 = React.useSyncExternalStore !== void 0 ? React.useSyncExternalStore : shim;
194
+ var useSyncExternalStore$2 = React2.useSyncExternalStore !== void 0 ? React2.useSyncExternalStore : shim;
195
195
  exports.useSyncExternalStore = useSyncExternalStore$2;
196
196
  if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop === "function") {
197
197
  __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStop(new Error());
@@ -285,16 +285,16 @@ var require_with_selector_development = __commonJS({
285
285
  if (typeof __REACT_DEVTOOLS_GLOBAL_HOOK__ !== "undefined" && typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart === "function") {
286
286
  __REACT_DEVTOOLS_GLOBAL_HOOK__.registerInternalModuleStart(new Error());
287
287
  }
288
- var React = require("react");
288
+ var React2 = require("react");
289
289
  var shim = require_shim();
290
290
  function is(x, y) {
291
291
  return x === y && (x !== 0 || 1 / x === 1 / y) || x !== x && y !== y;
292
292
  }
293
293
  var objectIs = typeof Object.is === "function" ? Object.is : is;
294
294
  var useSyncExternalStore = shim.useSyncExternalStore;
295
- var useRef2 = React.useRef, useEffect4 = React.useEffect, useMemo3 = React.useMemo, useDebugValue2 = React.useDebugValue;
295
+ var useRef3 = React2.useRef, useEffect3 = React2.useEffect, useMemo3 = React2.useMemo, useDebugValue2 = React2.useDebugValue;
296
296
  function useSyncExternalStoreWithSelector2(subscribe, getSnapshot, getServerSnapshot, selector, isEqual) {
297
- var instRef = useRef2(null);
297
+ var instRef = useRef3(null);
298
298
  var inst;
299
299
  if (instRef.current === null) {
300
300
  inst = {
@@ -349,7 +349,7 @@ var require_with_selector_development = __commonJS({
349
349
  return [getSnapshotWithSelector, getServerSnapshotWithSelector];
350
350
  }, [getSnapshot, getServerSnapshot, selector, isEqual]), getSelection = _useMemo[0], getServerSelection = _useMemo[1];
351
351
  var value = useSyncExternalStore(subscribe, getSelection, getServerSelection);
352
- useEffect4(function() {
352
+ useEffect3(function() {
353
353
  inst.hasValue = true;
354
354
  inst.value = value;
355
355
  }, [value]);
@@ -939,8 +939,8 @@ __export(src_exports, {
939
939
  module.exports = __toCommonJS(src_exports);
940
940
 
941
941
  // src/Schematic.tsx
942
- var import_builder3 = require("@tscircuit/builder");
943
- var import_react_fiber = __toESM(require("@tscircuit/react-fiber"));
942
+ var import_core = require("@tscircuit/core");
943
+ var import_soup_util = require("@tscircuit/soup-util");
944
944
 
945
945
  // node_modules/zustand/esm/vanilla.mjs
946
946
  var import_meta = {};
@@ -1012,6 +1012,20 @@ function applyToPoint(matrix, point) {
1012
1012
  };
1013
1013
  }
1014
1014
 
1015
+ // node_modules/transformation-matrix/src/inverse.js
1016
+ function inverse(matrix) {
1017
+ const { a, b, c, d, e, f } = matrix;
1018
+ const denom = a * d - b * c;
1019
+ return {
1020
+ a: d / denom,
1021
+ b: b / -denom,
1022
+ c: c / -denom,
1023
+ d: a / denom,
1024
+ e: (d * e - c * f) / -denom,
1025
+ f: (b * e - a * f) / denom
1026
+ };
1027
+ }
1028
+
1015
1029
  // node_modules/transformation-matrix/src/utils.js
1016
1030
  function isUndefined(val) {
1017
1031
  return typeof val === "undefined";
@@ -1222,7 +1236,275 @@ peg$SyntaxError.buildMessage = function(expected, found) {
1222
1236
  };
1223
1237
 
1224
1238
  // src/lib/render-context/index.ts
1225
- var import_react7 = require("react");
1239
+ var import_react6 = require("react");
1240
+
1241
+ // src/schematic-components/ContextProviders.tsx
1242
+ var import_react2 = require("react");
1243
+ var import_react3 = require("react");
1244
+ var import_jsx_runtime = require("react/jsx-runtime");
1245
+ var StoreContext = (0, import_react3.createContext)(null);
1246
+ var ContextProviders = ({ children }) => {
1247
+ const store = (0, import_react2.useMemo)(() => createRenderContextStore(), []);
1248
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(StoreContext.Provider, { value: store, children });
1249
+ };
1250
+
1251
+ // src/schematic-components/RenderError.tsx
1252
+ var import_jsx_runtime2 = require("react/jsx-runtime");
1253
+ var RenderError_default = ({ text }) => {
1254
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1255
+ "div",
1256
+ {
1257
+ style: {
1258
+ position: "fixed",
1259
+ backgroundColor: "red",
1260
+ color: "white",
1261
+ fontSize: 14,
1262
+ fontFamily: "sans-serif",
1263
+ padding: 5,
1264
+ right: 0,
1265
+ top: 0,
1266
+ opacity: 0.75
1267
+ },
1268
+ children: text
1269
+ }
1270
+ );
1271
+ };
1272
+
1273
+ // src/lib/utils/colors.ts
1274
+ var colorMap = {
1275
+ "3d_viewer": {
1276
+ background_bottom: "rgb(102, 102, 128)",
1277
+ background_top: "rgb(204, 204, 230)",
1278
+ board: "rgb(51, 43, 23)",
1279
+ copper: "rgb(179, 156, 0)",
1280
+ silkscreen_bottom: "rgb(230, 230, 230)",
1281
+ silkscreen_top: "rgb(230, 230, 230)",
1282
+ soldermask: "rgb(20, 51, 36)",
1283
+ solderpaste: "rgb(128, 128, 128)"
1284
+ },
1285
+ board: {
1286
+ anchor: "rgb(255, 38, 226)",
1287
+ aux_items: "rgb(255, 255, 255)",
1288
+ b_adhes: "rgb(0, 0, 132)",
1289
+ b_crtyd: "rgb(255, 38, 226)",
1290
+ b_fab: "rgb(88, 93, 132)",
1291
+ b_mask: "rgba(2, 255, 238, 0.400)",
1292
+ b_paste: "rgb(0, 194, 194)",
1293
+ b_silks: "rgb(232, 178, 167)",
1294
+ background: "rgb(0, 16, 35)",
1295
+ cmts_user: "rgb(89, 148, 220)",
1296
+ copper: {
1297
+ b: "rgb(77, 127, 196)",
1298
+ f: "rgb(200, 52, 52)",
1299
+ in1: "rgb(127, 200, 127)",
1300
+ in10: "rgb(237, 124, 51)",
1301
+ in11: "rgb(91, 195, 235)",
1302
+ in12: "rgb(247, 111, 142)",
1303
+ in13: "rgb(167, 165, 198)",
1304
+ in14: "rgb(40, 204, 217)",
1305
+ in15: "rgb(232, 178, 167)",
1306
+ in16: "rgb(242, 237, 161)",
1307
+ in17: "rgb(237, 124, 51)",
1308
+ in18: "rgb(91, 195, 235)",
1309
+ in19: "rgb(247, 111, 142)",
1310
+ in2: "rgb(206, 125, 44)",
1311
+ in20: "rgb(167, 165, 198)",
1312
+ in21: "rgb(40, 204, 217)",
1313
+ in22: "rgb(232, 178, 167)",
1314
+ in23: "rgb(242, 237, 161)",
1315
+ in24: "rgb(237, 124, 51)",
1316
+ in25: "rgb(91, 195, 235)",
1317
+ in26: "rgb(247, 111, 142)",
1318
+ in27: "rgb(167, 165, 198)",
1319
+ in28: "rgb(40, 204, 217)",
1320
+ in29: "rgb(232, 178, 167)",
1321
+ in3: "rgb(79, 203, 203)",
1322
+ in30: "rgb(242, 237, 161)",
1323
+ in4: "rgb(219, 98, 139)",
1324
+ in5: "rgb(167, 165, 198)",
1325
+ in6: "rgb(40, 204, 217)",
1326
+ in7: "rgb(232, 178, 167)",
1327
+ in8: "rgb(242, 237, 161)",
1328
+ in9: "rgb(141, 203, 129)"
1329
+ },
1330
+ cursor: "rgb(255, 255, 255)",
1331
+ drc: "rgb(194, 194, 194)",
1332
+ drc_error: "rgba(215, 91, 107, 0.800)",
1333
+ drc_exclusion: "rgb(255, 255, 255)",
1334
+ drc_warning: "rgba(255, 208, 66, 0.902)",
1335
+ dwgs_user: "rgb(194, 194, 194)",
1336
+ eco1_user: "rgb(180, 219, 210)",
1337
+ eco2_user: "rgb(216, 200, 82)",
1338
+ edge_cuts: "rgb(208, 210, 205)",
1339
+ f_adhes: "rgb(132, 0, 132)",
1340
+ f_crtyd: "rgb(255, 0, 245)",
1341
+ f_fab: "rgb(175, 175, 175)",
1342
+ f_mask: "rgba(216, 100, 255, 0.400)",
1343
+ f_paste: "rgba(180, 160, 154, 0.902)",
1344
+ f_silks: "rgb(242, 237, 161)",
1345
+ footprint_text_back: "rgb(0, 0, 132)",
1346
+ footprint_text_front: "rgb(194, 194, 194)",
1347
+ footprint_text_invisible: "rgb(132, 132, 132)",
1348
+ grid: "rgb(132, 132, 132)",
1349
+ grid_axes: "rgb(194, 194, 194)",
1350
+ margin: "rgb(255, 38, 226)",
1351
+ microvia: "rgb(0, 132, 132)",
1352
+ no_connect: "rgb(0, 0, 132)",
1353
+ pad_back: "rgb(77, 127, 196)",
1354
+ pad_front: "rgb(200, 52, 52)",
1355
+ pad_plated_hole: "rgb(194, 194, 0)",
1356
+ pad_through_hole: "rgb(227, 183, 46)",
1357
+ plated_hole: "rgb(26, 196, 210)",
1358
+ ratsnest: "rgba(245, 255, 213, 0.702)",
1359
+ select_overlay: "rgb(4, 255, 67)",
1360
+ through_via: "rgb(236, 236, 236)",
1361
+ user_1: "rgb(194, 194, 194)",
1362
+ user_2: "rgb(89, 148, 220)",
1363
+ user_3: "rgb(180, 219, 210)",
1364
+ user_4: "rgb(216, 200, 82)",
1365
+ user_5: "rgb(194, 194, 194)",
1366
+ user_6: "rgb(89, 148, 220)",
1367
+ user_7: "rgb(180, 219, 210)",
1368
+ user_8: "rgb(216, 200, 82)",
1369
+ user_9: "rgb(232, 178, 167)",
1370
+ via_blind_buried: "rgb(187, 151, 38)",
1371
+ via_hole: "rgb(227, 183, 46)",
1372
+ via_micro: "rgb(0, 132, 132)",
1373
+ via_through: "rgb(236, 236, 236)",
1374
+ worksheet: "rgb(200, 114, 171)"
1375
+ },
1376
+ gerbview: {
1377
+ axes: "rgb(0, 0, 132)",
1378
+ background: "rgb(0, 0, 0)",
1379
+ dcodes: "rgb(255, 255, 255)",
1380
+ grid: "rgb(132, 132, 132)",
1381
+ layers: [
1382
+ "rgb(132, 0, 0)",
1383
+ "rgb(194, 194, 0)",
1384
+ "rgb(194, 0, 194)",
1385
+ "rgb(194, 0, 0)",
1386
+ "rgb(0, 132, 132)",
1387
+ "rgb(0, 132, 0)",
1388
+ "rgb(0, 0, 132)",
1389
+ "rgb(132, 132, 132)",
1390
+ "rgb(132, 0, 132)",
1391
+ "rgb(194, 194, 194)",
1392
+ "rgb(132, 0, 132)",
1393
+ "rgb(132, 0, 0)",
1394
+ "rgb(132, 132, 0)",
1395
+ "rgb(194, 194, 194)",
1396
+ "rgb(0, 0, 132)",
1397
+ "rgb(0, 132, 0)",
1398
+ "rgb(132, 0, 0)",
1399
+ "rgb(194, 194, 0)",
1400
+ "rgb(194, 0, 194)",
1401
+ "rgb(194, 0, 0)",
1402
+ "rgb(0, 132, 132)",
1403
+ "rgb(0, 132, 0)",
1404
+ "rgb(0, 0, 132)",
1405
+ "rgb(132, 132, 132)",
1406
+ "rgb(132, 0, 132)",
1407
+ "rgb(194, 194, 194)",
1408
+ "rgb(132, 0, 132)",
1409
+ "rgb(132, 0, 0)",
1410
+ "rgb(132, 132, 0)",
1411
+ "rgb(194, 194, 194)",
1412
+ "rgb(0, 0, 132)",
1413
+ "rgb(0, 132, 0)",
1414
+ "rgb(132, 0, 0)",
1415
+ "rgb(194, 194, 0)",
1416
+ "rgb(194, 0, 194)",
1417
+ "rgb(194, 0, 0)",
1418
+ "rgb(0, 132, 132)",
1419
+ "rgb(0, 132, 0)",
1420
+ "rgb(0, 0, 132)",
1421
+ "rgb(132, 132, 132)",
1422
+ "rgb(132, 0, 132)",
1423
+ "rgb(194, 194, 194)",
1424
+ "rgb(132, 0, 132)",
1425
+ "rgb(132, 0, 0)",
1426
+ "rgb(132, 132, 0)",
1427
+ "rgb(194, 194, 194)",
1428
+ "rgb(0, 0, 132)",
1429
+ "rgb(0, 132, 0)",
1430
+ "rgb(132, 0, 0)",
1431
+ "rgb(194, 194, 0)",
1432
+ "rgb(194, 0, 194)",
1433
+ "rgb(194, 0, 0)",
1434
+ "rgb(0, 132, 132)",
1435
+ "rgb(0, 132, 0)",
1436
+ "rgb(0, 0, 132)",
1437
+ "rgb(132, 132, 132)",
1438
+ "rgb(132, 0, 132)",
1439
+ "rgb(194, 194, 194)",
1440
+ "rgb(132, 0, 132)",
1441
+ "rgb(132, 0, 0)"
1442
+ ],
1443
+ negative_objects: "rgb(132, 132, 132)",
1444
+ worksheet: "rgb(0, 0, 132)"
1445
+ },
1446
+ meta: {
1447
+ filename: "kicad_2020",
1448
+ name: "KiCad 2020",
1449
+ version: 2
1450
+ },
1451
+ palette: [
1452
+ "rgb(132, 0, 0)",
1453
+ "rgb(194, 194, 0)",
1454
+ "rgb(194, 0, 194)",
1455
+ "rgb(194, 0, 0)",
1456
+ "rgb(0, 132, 132)",
1457
+ "rgb(0, 132, 0)",
1458
+ "rgb(0, 0, 132)",
1459
+ "rgb(132, 132, 132)",
1460
+ "rgb(132, 0, 132)",
1461
+ "rgb(194, 194, 194)",
1462
+ "rgb(132, 0, 132)",
1463
+ "rgb(132, 0, 0)",
1464
+ "rgb(132, 132, 0)",
1465
+ "rgb(194, 194, 194)",
1466
+ "rgb(0, 0, 132)",
1467
+ "rgb(0, 132, 0)"
1468
+ ],
1469
+ schematic: {
1470
+ aux_items: "rgb(46, 46, 46)",
1471
+ background: "rgb(245, 241, 237)",
1472
+ brightened: "rgb(255, 0, 255)",
1473
+ bus: "rgb(0, 0, 132)",
1474
+ bus_junction: "rgb(0, 0, 132)",
1475
+ component_body: "rgb(255, 255, 194)",
1476
+ component_outline: "rgb(132, 0, 0)",
1477
+ cursor: "rgb(15, 15, 15)",
1478
+ erc_error: "rgba(230, 9, 13, 0.800)",
1479
+ erc_warning: "rgba(209, 146, 0, 0.800)",
1480
+ fields: "rgb(132, 0, 132)",
1481
+ grid: "rgb(181, 181, 181)",
1482
+ grid_axes: "rgb(0, 0, 132)",
1483
+ hidden: "rgb(194, 194, 194)",
1484
+ junction: "rgb(0, 150, 0)",
1485
+ label_global: "rgb(132, 0, 0)",
1486
+ label_hier: "rgb(114, 86, 0)",
1487
+ label_local: "rgb(15, 15, 15)",
1488
+ net_name: "rgb(132, 132, 132)",
1489
+ no_connect: "rgb(0, 0, 132)",
1490
+ note: "rgb(0, 0, 194)",
1491
+ override_item_colors: false,
1492
+ pin: "rgb(132, 0, 0)",
1493
+ pin_name: "rgb(0, 100, 100)",
1494
+ pin_number: "rgb(169, 0, 0)",
1495
+ reference: "rgb(0, 100, 100)",
1496
+ shadow: "rgba(102, 179, 255, 0.800)",
1497
+ sheet: "rgb(132, 0, 0)",
1498
+ sheet_background: "rgba(253, 255, 231, 0.000)",
1499
+ sheet_fields: "rgb(132, 0, 132)",
1500
+ sheet_filename: "rgb(114, 86, 0)",
1501
+ sheet_label: "rgb(0, 100, 100)",
1502
+ sheet_name: "rgb(0, 100, 100)",
1503
+ value: "rgb(0, 100, 100)",
1504
+ wire: "rgb(0, 150, 0)",
1505
+ worksheet: "rgb(132, 0, 0)"
1506
+ }
1507
+ };
1226
1508
 
1227
1509
  // src/lib/utils/get-svg-path-bounds.ts
1228
1510
  var import_svg_path_bounds = __toESM(require_svg_path_bounds());
@@ -1242,8 +1524,8 @@ function getSVGPathBounds(ds) {
1242
1524
  var get_svg_path_bounds_default = getSVGPathBounds;
1243
1525
 
1244
1526
  // src/schematic-components/SVGPathComponent.tsx
1245
- var import_react2 = require("react");
1246
- var import_jsx_runtime = require("react/jsx-runtime");
1527
+ var import_react4 = require("react");
1528
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1247
1529
  var SVGPathComponent = ({
1248
1530
  size,
1249
1531
  center,
@@ -1255,14 +1537,10 @@ var SVGPathComponent = ({
1255
1537
  hoverContent
1256
1538
  }) => {
1257
1539
  const ct = useGlobalStore((s) => s.camera_transform);
1258
- const pathBounds = get_svg_path_bounds_default(paths.map((p) => p.d));
1259
- const badRatio = Math.abs(pathBounds.width / pathBounds.height - size.width / size.height) > 0.01;
1260
- if (badRatio) {
1261
- }
1262
- const padding = {
1263
- x: 0,
1264
- y: 0
1265
- };
1540
+ const pathBounds = get_svg_path_bounds_default(
1541
+ paths.filter((p) => p.type !== "circle").map((p) => p.d)
1542
+ );
1543
+ const padding = { x: 0, y: 0 };
1266
1544
  const absoluteCenter = applyToPoint(ct, center);
1267
1545
  const innerSize = {
1268
1546
  width: size.width * ct.a,
@@ -1272,81 +1550,57 @@ var SVGPathComponent = ({
1272
1550
  width: innerSize.width + padding.x * 2,
1273
1551
  height: innerSize.height + padding.y * 2
1274
1552
  };
1275
- const [hovering, setHovering] = (0, import_react2.useState)(false);
1553
+ const [hovering, setHovering] = (0, import_react4.useState)(false);
1276
1554
  const svgLeft = absoluteCenter.x - fullSize.width / 2;
1277
1555
  const svgTop = absoluteCenter.y - fullSize.height / 2;
1278
1556
  const preferredRatio = pathBounds.width === 0 ? innerSize.height / pathBounds.height : innerSize.width / pathBounds.width;
1279
1557
  const svgToScreen = compose(
1280
- // translate(0, 0)
1281
1558
  scale(
1282
1559
  pathBounds.width === 0 ? preferredRatio : fullSize.width / pathBounds.width,
1283
1560
  pathBounds.height === 0 ? preferredRatio : fullSize.height / pathBounds.height
1284
1561
  ),
1285
1562
  translate(-pathBounds.minX, -pathBounds.minY)
1286
- // translate(center.x, center.y)
1287
1563
  );
1288
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1289
- hovering && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1290
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1291
- "div",
1292
- {
1293
- style: {
1294
- position: "absolute",
1295
- left: svgLeft - 6,
1296
- top: svgTop - 6,
1297
- pointerEvents: "none",
1298
- width: fullSize.width + 12,
1299
- height: fullSize.height + 12,
1300
- border: "1px red solid",
1301
- mixBlendMode: "difference",
1302
- zIndex: 1e3
1303
- }
1304
- }
1305
- ),
1306
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1307
- "div",
1308
- {
1309
- style: {
1310
- position: "absolute",
1311
- left: svgLeft + fullSize.width + 10,
1312
- pointerEvents: "none",
1313
- zIndex: 1e3,
1314
- color: "red",
1315
- mixBlendMode: "difference",
1316
- top: svgTop,
1317
- fontFamily: "monospace",
1318
- fontSize: 14
1564
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1565
+ "svg",
1566
+ {
1567
+ onMouseOver: () => setHovering(Boolean(hoverContent)),
1568
+ onMouseOut: () => setHovering(false),
1569
+ style: {
1570
+ position: "absolute",
1571
+ cursor: hovering ? "pointer" : void 0,
1572
+ zIndex,
1573
+ transform: [
1574
+ invertY ? "scale(1, 1)" : "scale(1, -1)",
1575
+ shiftToBottom ? "translate(0, 100%)" : "",
1576
+ rotation === 0 ? "" : `rotate(${rotation}deg)`
1577
+ ].join(" "),
1578
+ left: svgLeft,
1579
+ top: svgTop
1580
+ },
1581
+ overflow: "visible",
1582
+ width: fullSize.width,
1583
+ height: fullSize.height,
1584
+ children: paths.map(
1585
+ (p, i) => p.type === "circle" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1586
+ "circle",
1587
+ {
1588
+ transform: toSVG(
1589
+ compose(
1590
+ scale(1, 1),
1591
+ // Add a smaller scale factor for circles
1592
+ svgToScreen
1593
+ )
1594
+ ),
1595
+ cx: p.cx,
1596
+ cy: p.cy,
1597
+ r: p.r,
1598
+ fill: "none",
1599
+ strokeWidth: 2.25 * (p.strokeWidth || 1),
1600
+ stroke: p.stroke || "red"
1319
1601
  },
1320
- children: hoverContent
1321
- }
1322
- )
1323
- ] }),
1324
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1325
- "svg",
1326
- {
1327
- onMouseOver: () => setHovering(Boolean(hoverContent)),
1328
- onMouseOut: () => setHovering(false),
1329
- style: {
1330
- position: "absolute",
1331
- // backgroundColor: hovering ? "rgba(0, 0, 255, 0.5)" : "transparent",
1332
- cursor: hovering ? "pointer" : void 0,
1333
- zIndex,
1334
- transform: [
1335
- invertY ? "scale(1, 1)" : "scale(1, -1)",
1336
- // TODO based on ct.d
1337
- shiftToBottom ? "translate(0, 100%)" : "",
1338
- rotation === 0 ? "" : `rotate(${rotation}rad)`
1339
- ].join(" "),
1340
- left: svgLeft,
1341
- top: svgTop
1342
- // overflow: "hidden",
1343
- // backgroundColor: badRatio ? "rgba(255, 0, 0, 0.1)" : "transparent",
1344
- // backgroundColor: "rgba(255, 0, 0, 0.1)",
1345
- },
1346
- overflow: "visible",
1347
- width: fullSize.width,
1348
- height: fullSize.height,
1349
- children: paths.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1602
+ i
1603
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1350
1604
  "path",
1351
1605
  {
1352
1606
  transform: toSVG(svgToScreen),
@@ -1354,157 +1608,18 @@ var SVGPathComponent = ({
1354
1608
  strokeLinecap: "round",
1355
1609
  strokeWidth: 1.5 * (p.strokeWidth || 1),
1356
1610
  stroke: p.stroke || "red",
1357
- d: p.d
1611
+ d: p.d || ""
1358
1612
  },
1359
1613
  i
1360
- ))
1361
- }
1362
- )
1363
- ] });
1364
- };
1365
- var SVGPathComponent_default = SVGPathComponent;
1366
-
1367
- // src/schematic-components/SimpleResistor.tsx
1368
- var import_jsx_runtime2 = require("react/jsx-runtime");
1369
- var SimpleResistor = ({ component: { source, schematic } }) => {
1370
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1371
- SVGPathComponent_default,
1372
- {
1373
- rotation: schematic.rotation,
1374
- center: schematic.center,
1375
- size: schematic.size,
1376
- paths: [
1377
- {
1378
- stroke: "red",
1379
- strokeWidth: 1,
1380
- d: "M 0 15 l 10 0 l 0 -6 l 20 0 l 0 12 l -20 0 l 0 -6 m 20 0 l 10 0"
1381
- }
1382
- ]
1383
- }
1384
- );
1385
- };
1386
-
1387
- // src/schematic-components/SimpleCapacitor.tsx
1388
- var import_jsx_runtime3 = require("react/jsx-runtime");
1389
- var SimpleCapacitor = ({
1390
- component: { source, schematic }
1391
- }) => {
1392
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1393
- SVGPathComponent_default,
1394
- {
1395
- rotation: schematic.rotation,
1396
- center: schematic.center,
1397
- size: schematic.size,
1398
- paths: [
1399
- { stroke: "red", strokeWidth: 1, d: "M 0 15 l 12 0" },
1400
- { stroke: "red", strokeWidth: 1, d: "M 12 0 l 0 30" },
1401
- { stroke: "red", strokeWidth: 1, d: "M 18 0 l 0 30" },
1402
- { stroke: "red", strokeWidth: 1, d: "M 18 15 l 12 0" }
1403
- ]
1404
- }
1405
- );
1406
- };
1407
-
1408
- // src/lib/hooks/use-maybe-promise.ts
1409
- var import_react3 = require("react");
1410
-
1411
- // src/schematic-components/ProjectComponent.tsx
1412
- var import_builder = require("@tscircuit/builder");
1413
- var import_jsx_runtime4 = require("react/jsx-runtime");
1414
-
1415
- // src/schematic-components/SchematicComponent.tsx
1416
- var import_jsx_runtime5 = require("react/jsx-runtime");
1417
- var SchematicComponent = ({ component }) => {
1418
- const { source, schematic } = component;
1419
- if (!source.ftype)
1420
- return null;
1421
- switch (source.ftype) {
1422
- case "simple_resistor": {
1423
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SimpleResistor, { component: { source, schematic } });
1424
- }
1425
- case "simple_capacitor": {
1426
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SimpleCapacitor, { component: { source, schematic } });
1427
- }
1428
- case "simple_power_source": {
1429
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SimplePowerSource, { component: { source, schematic } });
1430
- }
1431
- case "simple_ground": {
1432
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SimpleGround, { component: { source, schematic } });
1433
- }
1434
- case "simple_inductor": {
1435
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SimpleInductor, { component: { source, schematic } });
1436
- }
1437
- case "simple_bug": {
1438
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SchematicBug, { component: { source, schematic } });
1439
- }
1440
- case "simple_diode": {
1441
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SimpleDiode, { component: { source, schematic } });
1442
- }
1443
- default: {
1444
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1445
- "unknown ftype: ",
1446
- component.source.ftype
1447
- ] });
1448
- }
1449
- }
1450
- };
1451
- var SchematicComponent_default = SchematicComponent;
1452
-
1453
- // src/lib/utils/direction-to-vec.ts
1454
- var directionToVec = (direction) => {
1455
- if (direction === "up")
1456
- return { x: 0, y: 1 };
1457
- else if (direction === "down")
1458
- return { x: 0, y: -1 };
1459
- else if (direction === "left")
1460
- return { x: -1, y: 0 };
1461
- else if (direction === "right")
1462
- return { x: 1, y: 0 };
1463
- else
1464
- throw new Error(`Invalid direction "${direction}"`);
1465
- };
1466
-
1467
- // src/schematic-components/SchematicPort.tsx
1468
- var import_jsx_runtime6 = require("react/jsx-runtime");
1469
- var SchematicPort = ({
1470
- port: { source_port, source_component, schematic }
1471
- }) => {
1472
- const hoverName = source_component?.name ? `.${source_component.name} > .${source_port?.name ?? source_port?.pin_number}` : `.${source_port?.name ?? source_port?.pin_number}`;
1473
- const vec = directionToVec(schematic.facing_direction);
1474
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1475
- SVGPathComponent,
1476
- {
1477
- rotation: 0,
1478
- hoverContent: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1479
- hoverName,
1480
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("br", {}),
1481
- source_port?.pin_number && `Pin ${source_port.pin_number}`
1482
- ] }),
1483
- center: schematic.center,
1484
- size: {
1485
- width: 0.2 + Math.abs(vec.x) * 0.04,
1486
- height: 0.2 + Math.abs(vec.y) * 0.04
1487
- },
1488
- zIndex: 10,
1489
- paths: [
1490
- {
1491
- stroke: "blue",
1492
- strokeWidth: 1,
1493
- d: "M 0 0 l 10 0 l 0 10 l -10 0 z"
1494
- },
1495
- schematic.facing_direction ? {
1496
- stroke: "blue",
1497
- strokeWidth: 0.5,
1498
- d: `M 5 5 l ${vec.x * 7} ${vec.y * 7}`
1499
- } : null
1500
- ].filter(Boolean)
1614
+ )
1615
+ )
1501
1616
  }
1502
1617
  );
1503
1618
  };
1504
- var SchematicPort_default = SchematicPort;
1619
+ var SVGPathComponent_default = SVGPathComponent;
1505
1620
 
1506
1621
  // node_modules/react-use-measure/dist/web.js
1507
- var import_react4 = require("react");
1622
+ var import_react5 = require("react");
1508
1623
  var import_debounce = __toESM(require_debounce());
1509
1624
  function useMeasure(_temp) {
1510
1625
  let {
@@ -1522,7 +1637,7 @@ function useMeasure(_temp) {
1522
1637
  if (!ResizeObserver) {
1523
1638
  throw new Error("This browser does not support ResizeObserver out of the box. See: https://github.com/react-spring/react-use-measure/#resize-observer-polyfills");
1524
1639
  }
1525
- const [bounds, set] = (0, import_react4.useState)({
1640
+ const [bounds, set] = (0, import_react5.useState)({
1526
1641
  left: 0,
1527
1642
  top: 0,
1528
1643
  width: 0,
@@ -1532,7 +1647,7 @@ function useMeasure(_temp) {
1532
1647
  x: 0,
1533
1648
  y: 0
1534
1649
  });
1535
- const state = (0, import_react4.useRef)({
1650
+ const state = (0, import_react5.useRef)({
1536
1651
  element: null,
1537
1652
  scrollContainers: null,
1538
1653
  resizeObserver: null,
@@ -1540,12 +1655,12 @@ function useMeasure(_temp) {
1540
1655
  });
1541
1656
  const scrollDebounce = debounce ? typeof debounce === "number" ? debounce : debounce.scroll : null;
1542
1657
  const resizeDebounce = debounce ? typeof debounce === "number" ? debounce : debounce.resize : null;
1543
- const mounted = (0, import_react4.useRef)(false);
1544
- (0, import_react4.useEffect)(() => {
1658
+ const mounted = (0, import_react5.useRef)(false);
1659
+ (0, import_react5.useEffect)(() => {
1545
1660
  mounted.current = true;
1546
1661
  return () => void (mounted.current = false);
1547
1662
  });
1548
- const [forceRefresh, resizeChange, scrollChange] = (0, import_react4.useMemo)(() => {
1663
+ const [forceRefresh, resizeChange, scrollChange] = (0, import_react5.useMemo)(() => {
1549
1664
  const callback = () => {
1550
1665
  if (!state.current.element)
1551
1666
  return;
@@ -1611,22 +1726,22 @@ function useMeasure(_temp) {
1611
1726
  };
1612
1727
  useOnWindowScroll(scrollChange, Boolean(scroll));
1613
1728
  useOnWindowResize(resizeChange);
1614
- (0, import_react4.useEffect)(() => {
1729
+ (0, import_react5.useEffect)(() => {
1615
1730
  removeListeners();
1616
1731
  addListeners();
1617
1732
  }, [scroll, scrollChange, resizeChange]);
1618
- (0, import_react4.useEffect)(() => removeListeners, []);
1733
+ (0, import_react5.useEffect)(() => removeListeners, []);
1619
1734
  return [ref, bounds, forceRefresh];
1620
1735
  }
1621
1736
  function useOnWindowResize(onWindowResize) {
1622
- (0, import_react4.useEffect)(() => {
1737
+ (0, import_react5.useEffect)(() => {
1623
1738
  const cb = onWindowResize;
1624
1739
  window.addEventListener("resize", cb);
1625
1740
  return () => void window.removeEventListener("resize", cb);
1626
1741
  }, [onWindowResize]);
1627
1742
  }
1628
1743
  function useOnWindowScroll(onScroll, enabled) {
1629
- (0, import_react4.useEffect)(() => {
1744
+ (0, import_react5.useEffect)(() => {
1630
1745
  if (enabled) {
1631
1746
  const cb = onScroll;
1632
1747
  window.addEventListener("scroll", cb, {
@@ -1654,7 +1769,7 @@ var keys = ["x", "y", "top", "bottom", "left", "right", "width", "height"];
1654
1769
  var areBoundsEqual = (a, b) => keys.every((key) => a[key] === b[key]);
1655
1770
 
1656
1771
  // src/schematic-components/SchematicText.tsx
1657
- var import_jsx_runtime7 = require("react/jsx-runtime");
1772
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1658
1773
  var SchematicText = ({ schematic_text }) => {
1659
1774
  const ct = useGlobalStore((s) => s.camera_transform);
1660
1775
  const { text, position, anchor } = schematic_text;
@@ -1670,7 +1785,7 @@ var SchematicText = ({ schematic_text }) => {
1670
1785
  }
1671
1786
  const fontTransformRatio = 0.15;
1672
1787
  const projectedTextSize = fontTransformRatio * ct.a;
1673
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1788
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1674
1789
  "div",
1675
1790
  {
1676
1791
  ref: boundsRef,
@@ -1679,7 +1794,8 @@ var SchematicText = ({ schematic_text }) => {
1679
1794
  position: "absolute",
1680
1795
  fontSize: projectedTextSize,
1681
1796
  left: tPos.x + offset[0],
1682
- top: tPos.y + offset[1]
1797
+ top: tPos.y + offset[1],
1798
+ color: schematic_text.color
1683
1799
  },
1684
1800
  children: text
1685
1801
  }
@@ -1687,310 +1803,280 @@ var SchematicText = ({ schematic_text }) => {
1687
1803
  };
1688
1804
  var SchematicText_default = SchematicText;
1689
1805
 
1690
- // src/schematic-components/SchematicTrace.tsx
1691
- var import_svg_path_generator = __toESM(require_svg_path_generator2());
1692
-
1693
- // src/schematic-components/RenderError.tsx
1694
- var import_jsx_runtime8 = require("react/jsx-runtime");
1695
- var RenderError_default = ({ text }) => {
1696
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1697
- "div",
1698
- {
1699
- style: {
1700
- position: "fixed",
1701
- backgroundColor: "red",
1702
- color: "white",
1703
- fontSize: 14,
1704
- fontFamily: "sans-serif",
1705
- padding: 5,
1706
- right: 0,
1707
- top: 0,
1708
- opacity: 0.75
1709
- },
1710
- children: text
1711
- }
1712
- );
1713
- };
1714
-
1715
- // src/schematic-components/SVGPathComponent2.tsx
1716
- var import_jsx_runtime9 = require("react/jsx-runtime");
1717
- var SVGPathComponent2 = ({
1718
- size,
1719
- center,
1720
- rotation,
1721
- paths,
1722
- zIndex,
1723
- invertY,
1724
- shiftToBottom,
1725
- hoverContent
1806
+ // src/schematic-components/SchematicChip.tsx
1807
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1808
+ var SchematicChip = ({
1809
+ component: { source, schematic, allElements }
1726
1810
  }) => {
1727
- const ct = useGlobalStore((c) => c.camera_transform);
1728
- const pathBounds = get_svg_path_bounds_default(paths.map((p) => p.d));
1729
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1730
- "svg",
1731
- {
1732
- style: {
1733
- position: "absolute",
1734
- left: 0,
1735
- top: 0,
1736
- right: 0,
1737
- bottom: 0,
1738
- // backgroundColor: hovering ? "rgba(0, 0, 255, 0.5)" : "transparent",
1739
- pointerEvents: "none",
1740
- zIndex
1741
- // overflow: "hidden",
1742
- // backgroundColor: badRatio ? "rgba(255, 0, 0, 0.1)" : "transparent",
1743
- // backgroundColor: "rgba(255, 0, 0, 0.1)",
1744
- },
1745
- overflow: "visible",
1746
- children: paths.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1747
- "path",
1748
- {
1749
- transform: toSVG(ct),
1750
- fill: p.fill ?? "none",
1751
- strokeLinecap: "round",
1752
- strokeWidth: 1.5 * (p.strokeWidth || 1),
1753
- stroke: p.stroke || "red",
1754
- d: p.d
1755
- },
1756
- i
1757
- ))
1758
- }
1811
+ const { center, size, rotation, schematic_component_id } = schematic;
1812
+ const { manufacturerPartNumber, name } = source;
1813
+ const chipWidth = size.width;
1814
+ const chipHeight = size.height;
1815
+ const paths = [];
1816
+ paths.push({
1817
+ type: "path",
1818
+ strokeWidth: 0.02,
1819
+ stroke: colorMap.schematic.component_outline,
1820
+ fill: colorMap.schematic.component_body,
1821
+ d: `M ${-chipWidth / 2},${-chipHeight / 2} h ${chipWidth} v ${chipHeight} h ${-chipWidth} Z`
1822
+ });
1823
+ const schematicPorts = allElements.filter(
1824
+ (item) => item.type === "schematic_port" && item.schematic_component_id === schematic_component_id
1759
1825
  );
1760
- };
1761
- var SVGPathComponent2_default = SVGPathComponent2;
1762
-
1763
- // src/schematic-components/SchematicTrace.tsx
1764
- var import_jsx_runtime10 = require("react/jsx-runtime");
1765
- var SchematicTrace = ({ trace: { source, schematic } }) => {
1766
- const edges = schematic.edges;
1767
- if (edges.length === 0) {
1768
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(RenderError_default, { text: `Route with 0 edges (${source.source_trace_id})` });
1769
- }
1770
- const path = (0, import_svg_path_generator.default)();
1771
- for (let i = 0; i < edges.length; i++) {
1772
- path.moveTo(edges[i].from.x, edges[i].from.y);
1773
- path.lineTo(edges[i].to.x, edges[i].to.y);
1774
- }
1775
- const d = path.toString();
1776
- const pathBounds = get_svg_path_bounds_default(d);
1777
- pathBounds.height = Math.max(pathBounds.height, 1);
1778
- pathBounds.width = Math.max(pathBounds.width, 1);
1779
- const center = {
1780
- x: pathBounds.minX + pathBounds.width / 2,
1781
- y: pathBounds.minY + pathBounds.height / 2
1782
- };
1783
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1784
- SVGPathComponent2_default,
1785
- {
1786
- rotation: 0,
1787
- center,
1788
- size: pathBounds,
1789
- paths: [
1790
- {
1791
- stroke: "green",
1792
- strokeWidth: 0.02,
1793
- d
1794
- }
1795
- ]
1826
+ const portLength = 0.2;
1827
+ const circleRadius = 0.05;
1828
+ const labelOffset = 0.1;
1829
+ const pinLabels = [];
1830
+ schematicPorts.forEach((port) => {
1831
+ const { side, pinNumber, distanceFromEdge } = port.center;
1832
+ let x = 0, y = 0, endX = 0, endY = 0;
1833
+ let labelX = 0, labelY = 0;
1834
+ let textAnchor = "middle";
1835
+ let rotation2 = 0;
1836
+ if (side === "center") {
1837
+ return;
1796
1838
  }
1797
- );
1798
- };
1799
- var SchematicTrace_default = SchematicTrace;
1800
-
1801
- // src/schematic-components/SchematicBug.tsx
1802
- var import_builder2 = require("@tscircuit/builder");
1803
- var import_jsx_runtime11 = require("react/jsx-runtime");
1804
- var SchematicBug = ({ component: { source, schematic } }) => {
1805
- const location = schematic.center;
1806
- const port_arrangement = {
1807
- top_size: 0,
1808
- bottom_size: 0,
1809
- ...schematic.port_arrangement
1810
- };
1811
- const manufacturerPartNumber = source.manufacturerPartNumber;
1812
- let bugw = schematic.size.width;
1813
- let bugh = schematic.size.height;
1814
- const { total_ports, width, height } = (0, import_builder2.getPortArrangementSize)(port_arrangement);
1815
- const port_indices = (0, import_builder2.getPortIndices)(port_arrangement);
1816
- if (isNaN(bugw))
1817
- bugw = width;
1818
- if (isNaN(bugh))
1819
- bugh = height;
1820
- const paths = [
1821
- {
1822
- stroke: "red",
1823
- strokeWidth: 0.02,
1824
- d: `M ${-bugw / 2} ${-bugh / 2} L ${bugw / 2} ${-bugh / 2} L ${bugw / 2} ${bugh / 2} L ${-bugw / 2} ${bugh / 2}Z`
1825
- },
1826
- ...port_indices.map((portNum) => {
1827
- const pos = (0, import_builder2.getPortPosition)(
1828
- { ...port_arrangement, pin_spacing: schematic.pin_spacing },
1829
- portNum
1830
- );
1831
- const x2 = pos.side === "left" ? -bugw / 2 : pos.side === "right" ? bugw / 2 : pos.x;
1832
- const y2 = pos.side === "top" ? bugh / 2 : pos.side === "bottom" ? -bugh / 2 : pos.y;
1833
- return {
1834
- stroke: "red",
1835
- strokeWidth: 0.02,
1836
- d: `M ${pos.x} ${pos.y} L ${x2} ${y2}`
1837
- };
1838
- })
1839
- ];
1840
- const actualSize = get_svg_path_bounds_default(paths.map((p) => p.d).join(" "));
1841
- const actualCenter = {
1842
- x: schematic.center.x + (actualSize.minX + actualSize.maxX) / 2,
1843
- y: schematic.center.y + (actualSize.minY + actualSize.maxY) / 2
1844
- };
1845
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
1846
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1839
+ switch (side) {
1840
+ case "left":
1841
+ x = -chipWidth / 2;
1842
+ y = -chipHeight / 2 + distanceFromEdge;
1843
+ endX = x - portLength;
1844
+ endY = y;
1845
+ labelX = endX;
1846
+ labelY = y + labelOffset;
1847
+ textAnchor = "end";
1848
+ break;
1849
+ case "right":
1850
+ x = chipWidth / 2;
1851
+ y = chipHeight / 2 - distanceFromEdge;
1852
+ endX = x + portLength;
1853
+ endY = y;
1854
+ labelX = endX - labelOffset;
1855
+ labelY = y + labelOffset;
1856
+ textAnchor = "start";
1857
+ break;
1858
+ case "bottom":
1859
+ x = -chipWidth / 2 + distanceFromEdge;
1860
+ y = -chipHeight / 2;
1861
+ endX = x;
1862
+ endY = y - portLength;
1863
+ labelX = x;
1864
+ labelY = endY + labelOffset;
1865
+ rotation2 = -90;
1866
+ break;
1867
+ case "top":
1868
+ x = chipWidth / 2 - distanceFromEdge;
1869
+ y = chipHeight / 2;
1870
+ endX = x;
1871
+ endY = y + portLength;
1872
+ labelX = x;
1873
+ labelY = endY + labelOffset;
1874
+ rotation2 = -90;
1875
+ break;
1876
+ }
1877
+ paths.push({
1878
+ type: "path",
1879
+ strokeWidth: 0.015,
1880
+ stroke: colorMap.schematic.component_outline,
1881
+ d: `M ${x},${y} L ${endX},${endY}`
1882
+ });
1883
+ paths.push({
1884
+ type: "circle",
1885
+ cx: endX,
1886
+ cy: endY,
1887
+ r: circleRadius,
1888
+ strokeWidth: 0.01,
1889
+ stroke: colorMap.schematic.component_outline,
1890
+ fill: colorMap.schematic.component_outline
1891
+ });
1892
+ if (pinNumber !== void 0) {
1893
+ pinLabels.push({
1894
+ x: labelX,
1895
+ y: labelY,
1896
+ text: `${pinNumber}`,
1897
+ anchor: textAnchor,
1898
+ rotation: rotation2
1899
+ });
1900
+ }
1901
+ });
1902
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1903
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1847
1904
  SVGPathComponent_default,
1848
1905
  {
1849
- rotation: schematic.rotation,
1850
- center: actualCenter,
1851
- size: actualSize,
1906
+ rotation,
1907
+ center,
1908
+ size,
1852
1909
  paths
1853
1910
  }
1854
1911
  ),
1855
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1912
+ pinLabels.map((label, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1856
1913
  SchematicText_default,
1857
1914
  {
1858
1915
  schematic_text: {
1859
- anchor: "bottom",
1916
+ anchor: label.anchor,
1917
+ rotation: 0,
1860
1918
  position: {
1861
- x: location.x + actualSize.minX / 1.5,
1862
- y: location.y + actualSize.minY
1919
+ x: center.x + label.x,
1920
+ y: center.y + label.y
1863
1921
  },
1864
1922
  schematic_component_id: "SYNTHETIC",
1865
- schematic_text_id: "SYNTHETIC",
1923
+ schematic_text_id: `PIN_LABEL_${index}`,
1924
+ text: label.text,
1925
+ type: "schematic_text",
1926
+ color: colorMap.schematic.pin_number
1927
+ }
1928
+ },
1929
+ index
1930
+ )),
1931
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1932
+ SchematicText_default,
1933
+ {
1934
+ schematic_text: {
1935
+ anchor: "right",
1936
+ rotation: 0,
1937
+ position: {
1938
+ x: center.x,
1939
+ y: center.y - chipHeight / 2 - 0.2
1940
+ },
1941
+ schematic_component_id: "SYNTHETIC",
1942
+ schematic_text_id: "SYNTHETIC_MPN",
1866
1943
  text: manufacturerPartNumber,
1867
- type: "schematic_text"
1944
+ type: "schematic_text",
1945
+ color: colorMap.schematic.reference
1946
+ }
1947
+ }
1948
+ ),
1949
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1950
+ SchematicText_default,
1951
+ {
1952
+ schematic_text: {
1953
+ anchor: "right",
1954
+ rotation: 0,
1955
+ position: {
1956
+ x: center.x,
1957
+ y: center.y + chipHeight / 2 + 0.2
1958
+ },
1959
+ schematic_component_id: "SYNTHETIC",
1960
+ schematic_text_id: "SYNTHETIC_NAME",
1961
+ text: name,
1962
+ type: "schematic_text",
1963
+ color: colorMap.schematic.reference
1868
1964
  }
1869
1965
  }
1870
1966
  )
1871
1967
  ] });
1872
1968
  };
1873
1969
 
1874
- // src/schematic-components/SimplePowerSource.tsx
1875
- var import_jsx_runtime12 = require("react/jsx-runtime");
1876
- var SimplePowerSource = ({
1877
- component: { source, schematic }
1878
- }) => {
1879
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1880
- SVGPathComponent_default,
1881
- {
1882
- rotation: schematic.rotation,
1883
- center: schematic.center,
1884
- size: schematic.size,
1885
- invertY: true,
1886
- paths: [
1887
- {
1888
- stroke: "red",
1889
- strokeWidth: 1,
1890
- d: "M 0 -17 L 0 -3 M -8 3 L 8 3 M 0 17 L 0 3 M -12 -3 L 12 -3"
1891
- },
1892
- // positive symbol
1893
- {
1894
- stroke: "red",
1895
- strokeWidth: 0.5,
1896
- d: "M 8 -9 L 8 -6 M 9.5 -7.5 L 6.5 -7.5"
1897
- },
1898
- // negative symbol
1970
+ // src/schematic-components/SchematicComponent.tsx
1971
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1972
+ var SchematicComponent = ({ component }) => {
1973
+ const { source, schematic, allElements } = component;
1974
+ if (!source.ftype)
1975
+ return null;
1976
+ switch (source.ftype) {
1977
+ case "simple_resistor":
1978
+ case "simple_capacitor":
1979
+ case "simple_power_source":
1980
+ case "simple_ground":
1981
+ case "simple_inductor":
1982
+ case "simple_diode": {
1983
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1984
+ SchematicComponentFromSymbol,
1899
1985
  {
1900
- stroke: "red",
1901
- strokeWidth: 0.5,
1902
- d: "M 9.5 7.5 L 6.5 7.5"
1986
+ component: { source, schematic }
1903
1987
  }
1904
- ]
1988
+ );
1905
1989
  }
1906
- );
1907
- };
1908
-
1909
- // src/schematic-components/SimpleGround.tsx
1910
- var import_jsx_runtime13 = require("react/jsx-runtime");
1911
- var SimpleGround = ({ component: { source, schematic } }) => {
1912
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1913
- SVGPathComponent_default,
1914
- {
1915
- rotation: schematic.rotation,
1916
- center: schematic.center,
1917
- size: schematic.size,
1918
- invertY: true,
1919
- shiftToBottom: true,
1920
- paths: [
1990
+ case "simple_chip":
1991
+ case "simple_bug": {
1992
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1993
+ SchematicChip,
1921
1994
  {
1922
- stroke: "red",
1923
- strokeWidth: 0.7,
1924
- d: "M -3 3 L 3 3 M -6 0 L 6 0 M -9 -3 L 9 -3 M 0 -3 L 0 -12"
1995
+ component: { source, schematic, allElements }
1925
1996
  }
1926
- ]
1997
+ );
1927
1998
  }
1928
- );
1999
+ default: {
2000
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
2001
+ "unknown ftype: ",
2002
+ component.source.ftype
2003
+ ] });
2004
+ }
2005
+ }
1929
2006
  };
2007
+ var SchematicComponent_default = SchematicComponent;
1930
2008
 
1931
- // src/schematic-components/SimpleInductor.tsx
1932
- var import_jsx_runtime14 = require("react/jsx-runtime");
1933
- var SimpleInductor = ({ component: { source, schematic } }) => {
1934
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
2009
+ // src/schematic-components/SchematicComponentFromSymbol.tsx
2010
+ var import_schematic_symbols = require("schematic-symbols");
2011
+ var import_jsx_runtime7 = require("react/jsx-runtime");
2012
+ var SchematicComponentFromSymbol = ({
2013
+ component: { source, schematic }
2014
+ }) => {
2015
+ const { center, rotation } = schematic;
2016
+ const symbol = import_schematic_symbols.symbols[schematic.symbol_name];
2017
+ const paths = symbol.primitives.filter((p) => p.type === "path").map((p) => ({
2018
+ stroke: colorMap.schematic.component_outline,
2019
+ strokeWidth: 0.02,
2020
+ d: p.points.reduce(
2021
+ (acc, point, index) => {
2022
+ const command = index === 0 ? "M" : "L";
2023
+ return `${acc} ${command} ${point.x} ${point.y}`;
2024
+ },
2025
+ ""
2026
+ )
2027
+ }));
2028
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1935
2029
  SVGPathComponent_default,
1936
2030
  {
1937
- rotation: schematic.rotation,
1938
- center: schematic.center,
1939
- size: schematic.size,
1940
- paths: [
1941
- {
1942
- stroke: "red",
1943
- strokeWidth: 1,
1944
- // https://commons.wikimedia.org/wiki/File:Electrical_symbols_library.svg
1945
- d: "m 371,710.41665 h -14 c -0.0421,-16.39898 -14.02104,-16.39898 -14,0 -0.021,-16.399 -14.04182,-16.34072 -14,0 -2.6e-4,-16.45722 -14.04236,-16.45722 -14,0 2.8e-4,-16.3407 -13.97896,-16.39898 -14,0 -0.0421,-16.39898 -13.91338,-16.39898 -13.91338,0 H 273"
1946
- }
1947
- ]
2031
+ rotation,
2032
+ center,
2033
+ size: {
2034
+ width: symbol?.size.width,
2035
+ height: symbol?.size.height
2036
+ },
2037
+ paths
1948
2038
  }
1949
2039
  );
1950
2040
  };
1951
2041
 
1952
- // src/schematic-components/SimpleDiode.tsx
1953
- var import_jsx_runtime15 = require("react/jsx-runtime");
1954
- var SimpleDiode = ({ component: { source, schematic } }) => {
1955
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
2042
+ // src/schematic-components/SchematicTrace.tsx
2043
+ var import_svg_path_generator = __toESM(require_svg_path_generator2());
2044
+ var import_jsx_runtime8 = require("react/jsx-runtime");
2045
+ var SchematicTrace = ({ trace: { source, schematic } }) => {
2046
+ const edges = schematic.edges;
2047
+ if (edges.length === 0) {
2048
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(RenderError_default, { text: `Route with 0 edges (${source.source_trace_id})` });
2049
+ }
2050
+ const path = (0, import_svg_path_generator.default)();
2051
+ for (let i = 0; i < edges.length; i++) {
2052
+ path.moveTo(edges[i].from.x, edges[i].from.y);
2053
+ path.lineTo(edges[i].to.x, edges[i].to.y);
2054
+ }
2055
+ const d = path.toString();
2056
+ const pathBounds = get_svg_path_bounds_default(d);
2057
+ pathBounds.height = Math.max(pathBounds.height, 1);
2058
+ pathBounds.width = Math.max(pathBounds.width, 1);
2059
+ const center = {
2060
+ x: pathBounds.minX + pathBounds.width / 2,
2061
+ y: pathBounds.minY + pathBounds.height / 2
2062
+ };
2063
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1956
2064
  SVGPathComponent_default,
1957
2065
  {
1958
- rotation: schematic.rotation,
1959
- center: schematic.center,
1960
- size: {
1961
- height: 0.5,
1962
- width: 1
1963
- },
2066
+ rotation: 0,
2067
+ center,
2068
+ size: pathBounds,
1964
2069
  paths: [
1965
- { stroke: "red", strokeWidth: 2, d: "M 0,0 H 21" },
1966
- { stroke: "red", strokeWidth: 2, d: "M 49,0 H 59" },
1967
- { stroke: "red", strokeWidth: 2, d: "M 49,0 L 21 14 V -14 Z" },
1968
- { stroke: "red", strokeWidth: 2, d: "M 49,-14 V 14" }
1969
- // For LEDs
1970
- // {
1971
- // stroke: "red",
1972
- // strokeWidth: 2,
1973
- // d: "M 35 -32 l 7 5.25 l 1.75 -9.625 z m 3.5 2.625 l -5.25 7",
1974
- // },
1975
- // {
1976
- // stroke: "red",
1977
- // strokeWidth: 2,
1978
- // d: "M 52 -26 l 7 5.25 l 1.75 -9.625 z m 3.5 2.625 l -5.25 7",
1979
- // },
2070
+ {
2071
+ stroke: colorMap.schematic.wire,
2072
+ strokeWidth: 0.01,
2073
+ d
2074
+ }
1980
2075
  ]
1981
2076
  }
1982
2077
  );
1983
2078
  };
1984
-
1985
- // src/schematic-components/ContextProviders.tsx
1986
- var import_react5 = require("react");
1987
- var import_react6 = require("react");
1988
- var import_jsx_runtime16 = require("react/jsx-runtime");
1989
- var StoreContext = (0, import_react6.createContext)(null);
1990
- var ContextProviders = ({ children }) => {
1991
- const store = (0, import_react5.useMemo)(() => createRenderContextStore(), []);
1992
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(StoreContext.Provider, { value: store, children });
1993
- };
2079
+ var SchematicTrace_default = SchematicTrace;
1994
2080
 
1995
2081
  // src/lib/render-context/index.ts
1996
2082
  var createRenderContextStore = () => createStore((set) => ({
@@ -1998,12 +2084,12 @@ var createRenderContextStore = () => createStore((set) => ({
1998
2084
  setCameraTransform: (transform2) => set({ camera_transform: transform2 })
1999
2085
  }));
2000
2086
  var useGlobalStore = (s) => {
2001
- const store = (0, import_react7.useContext)(StoreContext);
2087
+ const store = (0, import_react6.useContext)(StoreContext);
2002
2088
  return useStore(store, s);
2003
2089
  };
2004
2090
 
2005
2091
  // src/Schematic.tsx
2006
- var import_react9 = require("react");
2092
+ var import_react8 = require("react");
2007
2093
  var import_react_error_boundary = require("react-error-boundary");
2008
2094
  var import_react_supergrid = require("react-supergrid");
2009
2095
 
@@ -2032,68 +2118,13 @@ var collectElementRefs = (elm, allElms) => {
2032
2118
  schematic: elm,
2033
2119
  source: source_component,
2034
2120
  source_component,
2035
- source_port
2121
+ source_port,
2122
+ allElements: allElms
2036
2123
  };
2037
2124
  }
2038
2125
  return null;
2039
2126
  };
2040
2127
 
2041
- // src/schematic-components/SchematicBox.tsx
2042
- var import_jsx_runtime17 = require("react/jsx-runtime");
2043
- var SchematicBox = ({ box: { schematic } }) => {
2044
- const { width: w, height: h } = schematic;
2045
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2046
- SVGPathComponent,
2047
- {
2048
- rotation: 0,
2049
- center: schematic,
2050
- size: { width: schematic.width, height: schematic.height },
2051
- paths: [
2052
- {
2053
- stroke: "red",
2054
- strokeWidth: 0.02,
2055
- d: `M 0 0 l ${w} 0 l 0 ${h} l -${w} 0 z`
2056
- }
2057
- ]
2058
- }
2059
- );
2060
- };
2061
- var SchematicBox_default = SchematicBox;
2062
-
2063
- // src/schematic-components/SchematicLine.tsx
2064
- var import_svg_path_generator2 = __toESM(require_svg_path_generator2());
2065
- var import_jsx_runtime18 = require("react/jsx-runtime");
2066
- var SchematicLine = ({ line: { schematic } }) => {
2067
- const { x1, x2, y1, y2 } = schematic;
2068
- const dx = x2 - x1;
2069
- const dy = y2 - y1;
2070
- const path = (0, import_svg_path_generator2.default)();
2071
- path.moveTo(x1, y1);
2072
- path.lineTo(x2, y2);
2073
- const d = path.toString();
2074
- const pathBounds = get_svg_path_bounds_default(d);
2075
- const center = {
2076
- x: pathBounds.minX + pathBounds.width / 2,
2077
- y: pathBounds.minY + pathBounds.height / 2
2078
- };
2079
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2080
- SVGPathComponent,
2081
- {
2082
- rotation: 0,
2083
- center,
2084
- size: pathBounds,
2085
- paths: [
2086
- {
2087
- stroke: "red",
2088
- strokeWidth: 0.02,
2089
- d
2090
- }
2091
- ]
2092
- }
2093
- );
2094
- };
2095
- var SchematicLine_default = SchematicLine;
2096
-
2097
2128
  // src/lib/utils/get-rotation-from-anchor-side.ts
2098
2129
  var getRotationFromAnchorSide = (anchor_side) => {
2099
2130
  if (anchor_side === "left")
@@ -2121,7 +2152,7 @@ var getVecFromAnchorSide = (anchor_side) => {
2121
2152
  };
2122
2153
 
2123
2154
  // src/schematic-components/SchematicNetLabel.tsx
2124
- var import_jsx_runtime19 = require("react/jsx-runtime");
2155
+ var import_jsx_runtime9 = require("react/jsx-runtime");
2125
2156
  var SchematicNetLabel = ({
2126
2157
  net_label
2127
2158
  }) => {
@@ -2133,8 +2164,8 @@ var SchematicNetLabel = ({
2133
2164
  const anchor_dist = is_vertical ? 0.04 : text_width / 4;
2134
2165
  anchor_vec.x *= anchor_dist;
2135
2166
  anchor_vec.y *= anchor_dist;
2136
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsxs)(import_jsx_runtime19.Fragment, { children: [
2137
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2167
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
2168
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2138
2169
  SVGPathComponent_default,
2139
2170
  {
2140
2171
  rotation: getRotationFromAnchorSide(anchor_side),
@@ -2153,10 +2184,11 @@ var SchematicNetLabel = ({
2153
2184
  ]
2154
2185
  }
2155
2186
  ),
2156
- /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2187
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2157
2188
  SchematicText_default,
2158
2189
  {
2159
2190
  schematic_text: {
2191
+ rotation: is_vertical ? 0 : getRotationFromAnchorSide(anchor_side),
2160
2192
  anchor: is_vertical ? "center" : anchor_side,
2161
2193
  position: {
2162
2194
  x: net_label.center.x + anchor_vec.x,
@@ -2165,63 +2197,22 @@ var SchematicNetLabel = ({
2165
2197
  schematic_component_id: "SYNTHETIC",
2166
2198
  schematic_text_id: "SYNTHETIC",
2167
2199
  text: net_label.text,
2168
- type: "schematic_text"
2200
+ type: "schematic_text",
2201
+ color: colorMap.schematic.net_name
2169
2202
  }
2170
2203
  }
2171
2204
  )
2172
2205
  ] });
2173
2206
  };
2174
2207
 
2175
- // src/schematic-components/SchematicPath.tsx
2176
- var import_svg_path_generator3 = __toESM(require_svg_path_generator2());
2177
- var import_jsx_runtime20 = require("react/jsx-runtime");
2178
- var SchematicPath = (props) => {
2179
- const { points, is_filled, is_closed, fill_color } = props.path.schematic;
2180
- if (points.length === 0)
2181
- return null;
2182
- const path = (0, import_svg_path_generator3.default)();
2183
- path.moveTo(points[0].x, points[0].y);
2184
- for (const point of points.slice(1)) {
2185
- path.lineTo(point.x, point.y);
2186
- }
2187
- if (is_closed) {
2188
- path.closePath();
2189
- }
2190
- const d = path.toString();
2191
- const pathBounds = get_svg_path_bounds_default(d);
2192
- pathBounds.height = Math.max(pathBounds.height, 1);
2193
- pathBounds.width = Math.max(pathBounds.width, 1);
2194
- const center = {
2195
- x: pathBounds.minX + pathBounds.width / 2,
2196
- y: pathBounds.minY + pathBounds.height / 2
2197
- };
2198
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2199
- SVGPathComponent,
2200
- {
2201
- rotation: 0,
2202
- center,
2203
- size: pathBounds,
2204
- paths: [
2205
- {
2206
- stroke: is_filled ? "none" : fill_color ?? "red",
2207
- strokeWidth: 0.02,
2208
- fill: is_filled ? fill_color ?? "red" : void 0,
2209
- d
2210
- }
2211
- ]
2212
- }
2213
- );
2214
- };
2215
- var SchematicPath_default = SchematicPath;
2216
-
2217
2208
  // src/schematic-components/SchematicElement.tsx
2218
- var import_jsx_runtime21 = require("react/jsx-runtime");
2209
+ var import_jsx_runtime10 = require("react/jsx-runtime");
2219
2210
  var SchematicElement = ({
2220
2211
  element,
2221
2212
  allElements
2222
2213
  }) => {
2223
2214
  if (element.type === "schematic_component") {
2224
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2215
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2225
2216
  SchematicComponent_default,
2226
2217
  {
2227
2218
  component: collectElementRefs(element, allElements)
@@ -2229,47 +2220,32 @@ var SchematicElement = ({
2229
2220
  );
2230
2221
  }
2231
2222
  if (element.type === "schematic_trace") {
2232
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SchematicTrace_default, { trace: collectElementRefs(element, allElements) });
2233
- }
2234
- if (element.type === "schematic_port") {
2235
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SchematicPort_default, { port: collectElementRefs(element, allElements) });
2236
- }
2237
- if (element.type === "schematic_box") {
2238
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SchematicBox_default, { box: collectElementRefs(element, allElements) });
2239
- }
2240
- if (element.type === "schematic_line") {
2241
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SchematicLine_default, { line: collectElementRefs(element, allElements) });
2242
- }
2243
- if (element.type === "schematic_path") {
2244
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SchematicPath_default, { path: collectElementRefs(element, allElements) });
2223
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SchematicTrace_default, { trace: collectElementRefs(element, allElements) });
2245
2224
  }
2246
2225
  if (element.type === "schematic_text") {
2247
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SchematicText_default, { schematic_text: element });
2226
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SchematicText_default, { schematic_text: element });
2248
2227
  }
2249
2228
  if (element.type === "schematic_net_label") {
2250
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SchematicNetLabel, { net_label: element });
2229
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SchematicNetLabel, { net_label: element });
2251
2230
  }
2252
2231
  return null;
2253
2232
  };
2254
2233
 
2255
- // src/Schematic.tsx
2256
- var import_use_mouse_matrix_transform = require("use-mouse-matrix-transform");
2257
-
2258
2234
  // src/schematic-components/TableViewer.tsx
2259
- var import_react8 = require("react");
2260
- var import_jsx_runtime22 = require("react/jsx-runtime");
2261
- var LazyTableViewer = (0, import_react8.lazy)(
2235
+ var import_react7 = require("react");
2236
+ var import_jsx_runtime11 = require("react/jsx-runtime");
2237
+ var LazyTableViewer = (0, import_react7.lazy)(
2262
2238
  () => import("@tscircuit/table-viewer").then((m) => ({
2263
2239
  default: m.SoupTableViewer
2264
2240
  }))
2265
2241
  );
2266
- var TableViewer = (params) => /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(import_react8.Suspense, { fallback: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)("div", { children: "Loading..." }), children: /* @__PURE__ */ (0, import_jsx_runtime22.jsx)(LazyTableViewer, { ...params }) });
2242
+ var TableViewer = (params) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_react7.Suspense, { fallback: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { children: "Loading..." }), children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(LazyTableViewer, { ...params }) });
2267
2243
 
2268
2244
  // src/Schematic.tsx
2269
- var import_jsx_runtime23 = require("react/jsx-runtime");
2245
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2270
2246
  var ErrorBoundary = import_react_error_boundary.ErrorBoundary;
2271
2247
  var fallbackRender = (elm) => ({ error, resetErrorBoundary }) => {
2272
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { color: "red" }, children: [
2248
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: { color: "red" }, children: [
2273
2249
  "error rendering ",
2274
2250
  elm.type,
2275
2251
  ": ",
@@ -2278,70 +2254,136 @@ var fallbackRender = (elm) => ({ error, resetErrorBoundary }) => {
2278
2254
  };
2279
2255
  var toMMSINeg = (v, z) => v >= 0 ? (0, import_react_supergrid.toMMSI)(v, z) : `-${(0, import_react_supergrid.toMMSI)(-v, z)}`;
2280
2256
  var Schematic = (props) => {
2281
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ContextProviders, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SchematicWithoutContext, { ...props }) });
2257
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ContextProviders, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SchematicWithoutContext, { ...props }) });
2282
2258
  };
2283
2259
  var SchematicWithoutContext = ({
2284
2260
  children,
2285
- elements: initialElements,
2286
- soup: initialSoup,
2261
+ soup,
2287
2262
  style,
2288
2263
  showTable = false,
2289
2264
  _soupPostProcessor
2290
2265
  }) => {
2291
- initialSoup = initialSoup ?? initialElements ?? [];
2292
- const [elements, setElements] = (0, import_react9.useState)(initialSoup ?? []);
2293
- const [project, setProject] = (0, import_react9.useState)(null);
2294
- const { setCameraTransform, camera_transform: cameraTransform } = useGlobalStore();
2266
+ const {
2267
+ circuitJson: circuitJsonFromChildren,
2268
+ error: errorFromChildren,
2269
+ isLoading
2270
+ } = (0, import_core.useRenderedCircuit)(children);
2271
+ const [elements, setElements] = (0, import_react8.useState)([]);
2272
+ const { setCameraTransform } = useGlobalStore();
2295
2273
  const [boundsRef, bounds] = useMeasure();
2296
- const { ref, setTransform } = (0, import_use_mouse_matrix_transform.useMouseMatrixTransform)({
2297
- onSetTransform: (transform2) => {
2298
- setCameraTransform(transform2);
2274
+ const containerRef = (0, import_react8.useRef)(null);
2275
+ const transformRef = (0, import_react8.useRef)(compose(translate(0, 0), scale(1, 1)));
2276
+ const isDraggingRef = (0, import_react8.useRef)(false);
2277
+ const lastMousePosRef = (0, import_react8.useRef)({ x: 0, y: 0 });
2278
+ const [, forceUpdate] = (0, import_react8.useState)({});
2279
+ const updateTransform = (0, import_react8.useCallback)(
2280
+ (newTransform) => {
2281
+ transformRef.current = newTransform;
2282
+ setCameraTransform(newTransform);
2283
+ forceUpdate({});
2284
+ },
2285
+ [setCameraTransform]
2286
+ );
2287
+ (0, import_react8.useEffect)(() => {
2288
+ let processedElements = [];
2289
+ if (circuitJsonFromChildren && (!soup || soup.length === 0)) {
2290
+ processedElements = circuitJsonFromChildren;
2291
+ } else if (soup && soup.length > 0) {
2292
+ processedElements = soup;
2299
2293
  }
2300
- // initialTransform: compose(scale(100, 100, 0, 0)),
2301
- });
2302
- const setElementsAndCamera = (0, import_react9.useCallback)(
2303
- (elements2) => {
2304
- const elmBounds = ref.current.getBoundingClientRect();
2305
- const { center, width, height } = elements2.some(
2294
+ if (processedElements.length > 0) {
2295
+ if (_soupPostProcessor) {
2296
+ processedElements = _soupPostProcessor(processedElements);
2297
+ }
2298
+ setElements(processedElements);
2299
+ }
2300
+ }, [circuitJsonFromChildren, soup, _soupPostProcessor]);
2301
+ (0, import_react8.useEffect)(() => {
2302
+ if (elements.length > 0 && containerRef.current) {
2303
+ const elmBounds = containerRef.current.getBoundingClientRect();
2304
+ const { center, width, height } = elements.some(
2306
2305
  (e) => e.type.startsWith("schematic_")
2307
- ) ? (0, import_builder3.findBoundsAndCenter)(
2308
- elements2.filter((e) => e.type.startsWith("schematic_"))
2306
+ ) ? (0, import_soup_util.findBoundsAndCenter)(
2307
+ elements.filter((e) => e.type.startsWith("schematic_"))
2309
2308
  ) : { center: { x: 0, y: 0 }, width: 1e-3, height: 1e-3 };
2310
2309
  const scaleFactor = Math.min(
2311
2310
  (elmBounds.width ?? 0) / width,
2312
2311
  (elmBounds.height ?? 0) / height,
2313
2312
  100
2314
2313
  );
2315
- setElements(elements2);
2316
- setProject((0, import_builder3.createProjectFromElements)(elements2));
2317
- setTransform(
2318
- compose(
2319
- translate((elmBounds.width ?? 0) / 2, (elmBounds.height ?? 0) / 2),
2320
- scale(scaleFactor, -scaleFactor, 0, 0),
2321
- translate(-center.x, -center.y)
2322
- )
2314
+ const newTransform = compose(
2315
+ translate((elmBounds.width ?? 0) / 2, (elmBounds.height ?? 0) / 2),
2316
+ scale(scaleFactor, -scaleFactor, 0, 0),
2317
+ translate(-center.x, -center.y)
2323
2318
  );
2319
+ updateTransform(newTransform);
2320
+ }
2321
+ }, [elements, bounds.width, bounds.height, updateTransform]);
2322
+ const handleMouseDown = (0, import_react8.useCallback)((e) => {
2323
+ isDraggingRef.current = true;
2324
+ lastMousePosRef.current = { x: e.clientX, y: e.clientY };
2325
+ }, []);
2326
+ const handleMouseMove = (0, import_react8.useCallback)(
2327
+ (e) => {
2328
+ if (!isDraggingRef.current)
2329
+ return;
2330
+ const dx = e.clientX - lastMousePosRef.current.x;
2331
+ const dy = e.clientY - lastMousePosRef.current.y;
2332
+ lastMousePosRef.current = { x: e.clientX, y: e.clientY };
2333
+ const scale2 = transformRef.current.a;
2334
+ const dragSensitivity = 150 / scale2;
2335
+ const newTransform = compose(
2336
+ translate(dx * dragSensitivity, dy * dragSensitivity),
2337
+ transformRef.current
2338
+ );
2339
+ updateTransform(newTransform);
2324
2340
  },
2325
- [setElements, setTransform]
2341
+ [updateTransform]
2326
2342
  );
2327
- (0, import_react9.useEffect)(() => {
2328
- if (initialSoup.length > 0) {
2329
- setElementsAndCamera(initialSoup);
2330
- return;
2331
- }
2332
- const projectBuilder = (0, import_builder3.createProjectBuilder)();
2333
- (import_react_fiber.createRoot ?? import_react_fiber.default.createRoot)().render(children, projectBuilder).then(async (elements2) => {
2334
- if (_soupPostProcessor) {
2335
- elements2 = _soupPostProcessor(elements2);
2343
+ const handleMouseUp = (0, import_react8.useCallback)(() => {
2344
+ isDraggingRef.current = false;
2345
+ }, []);
2346
+ const handleWheel = (0, import_react8.useCallback)(
2347
+ (e) => {
2348
+ e.preventDefault();
2349
+ const scaleMultiplier = Math.pow(0.999, e.deltaY);
2350
+ if (containerRef.current) {
2351
+ const rect = containerRef.current.getBoundingClientRect();
2352
+ const mouseX = e.clientX - rect.left;
2353
+ const mouseY = e.clientY - rect.top;
2354
+ const inverseTransform = inverse(transformRef.current);
2355
+ const transformedPoint = applyToPoint(inverseTransform, {
2356
+ x: mouseX,
2357
+ y: mouseY
2358
+ });
2359
+ const newTransform = compose(
2360
+ transformRef.current,
2361
+ translate(transformedPoint.x, transformedPoint.y),
2362
+ scale(scaleMultiplier, scaleMultiplier),
2363
+ translate(-transformedPoint.x, -transformedPoint.y)
2364
+ );
2365
+ updateTransform(newTransform);
2336
2366
  }
2337
- setElementsAndCamera(elements2);
2338
- }).catch((e) => {
2339
- console.error("ERROR RENDERING CIRCUIT");
2340
- throw e;
2341
- });
2342
- }, [children]);
2343
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
2344
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2367
+ },
2368
+ [updateTransform]
2369
+ );
2370
+ (0, import_react8.useEffect)(() => {
2371
+ const container = containerRef.current;
2372
+ if (container) {
2373
+ container.addEventListener("wheel", handleWheel, { passive: false });
2374
+ return () => {
2375
+ container.removeEventListener("wheel", handleWheel);
2376
+ };
2377
+ }
2378
+ }, [handleWheel]);
2379
+ if (errorFromChildren) {
2380
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
2381
+ "Error: ",
2382
+ errorFromChildren.message
2383
+ ] });
2384
+ }
2385
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
2386
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2345
2387
  "div",
2346
2388
  {
2347
2389
  style: {
@@ -2351,15 +2393,19 @@ var SchematicWithoutContext = ({
2351
2393
  overflow: "hidden",
2352
2394
  position: "relative",
2353
2395
  isolation: "isolate",
2354
- cursor: "grab",
2396
+ cursor: isDraggingRef.current ? "grabbing" : "grab",
2355
2397
  ...style
2356
2398
  },
2357
2399
  ref: (el) => {
2358
- ref.current = el;
2400
+ containerRef.current = el;
2359
2401
  boundsRef(el);
2360
2402
  },
2403
+ onMouseDown: handleMouseDown,
2404
+ onMouseMove: handleMouseMove,
2405
+ onMouseUp: handleMouseUp,
2406
+ onMouseLeave: handleMouseUp,
2361
2407
  children: [
2362
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2408
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2363
2409
  import_react_supergrid.SuperGrid,
2364
2410
  {
2365
2411
  stringifyCoord: (x, y, z) => {
@@ -2369,10 +2415,10 @@ var SchematicWithoutContext = ({
2369
2415
  },
2370
2416
  width: bounds.width,
2371
2417
  height: bounds.height,
2372
- transform: cameraTransform
2418
+ transform: transformRef.current
2373
2419
  }
2374
2420
  ),
2375
- elements?.map((elm, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ErrorBoundary, { fallbackRender: fallbackRender(elm), children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2421
+ elements?.map((elm, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ErrorBoundary, { fallbackRender: fallbackRender(elm), children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2376
2422
  SchematicElement,
2377
2423
  {
2378
2424
  element: elm,
@@ -2383,7 +2429,7 @@ var SchematicWithoutContext = ({
2383
2429
  ]
2384
2430
  }
2385
2431
  ),
2386
- showTable !== false && elements && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TableViewer, { elements })
2432
+ showTable !== false && elements && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TableViewer, { elements })
2387
2433
  ] });
2388
2434
  };
2389
2435
  // Annotate the CommonJS export names for ESM import in node: