@tscircuit/schematic-viewer 1.2.14 → 1.4.0

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/.github/workflows/chromatic.yml +30 -0
  2. package/.github/workflows/npm-build.yml +26 -0
  3. package/.github/workflows/npm-typecheck.yml +26 -0
  4. package/README.md +1 -1
  5. package/dist/index.d.ts +6 -7
  6. package/dist/index.js +690 -664
  7. package/dist/index.js.map +1 -1
  8. package/package.json +21 -12
  9. package/renovate.json +12 -1
  10. package/src/Schematic.tsx +148 -77
  11. package/src/lib/types/core.ts +14 -49
  12. package/src/lib/types/source-component.ts +6 -0
  13. package/src/lib/utils/collect-element-refs.ts +4 -3
  14. package/src/lib/utils/colors.ts +236 -0
  15. package/src/schematic-components/SVGPathComponent.tsx +84 -144
  16. package/src/schematic-components/SchematicChip.tsx +183 -0
  17. package/src/schematic-components/SchematicComponent.tsx +18 -24
  18. package/src/schematic-components/SchematicComponentFromSymbol.tsx +44 -0
  19. package/src/schematic-components/SchematicElement.tsx +4 -38
  20. package/src/schematic-components/SchematicTrace.tsx +4 -3
  21. package/src/schematic-components/index.tsx +7 -14
  22. package/src/stories/basics/schematic-net-label.stories.tsx +112 -166
  23. package/src/stories/basics/schematic-net-labels-2.stories.tsx +22 -20
  24. package/src/stories/bug-connections.stories.tsx +9 -6
  25. package/src/stories/bug-high-port-numbers.stories.tsx +99 -82
  26. package/src/stories/bug-pin-spacing.stories.tsx +1 -0
  27. package/src/stories/bugs/bug1-y-flip.stories.tsx +3 -2
  28. package/src/stories/bugs/bug3-scaling-trace.stories.tsx +11 -5
  29. package/src/stories/bugs/bug4-schematic-line.stories.tsx +0 -1
  30. package/src/stories/bugs/bug5-diode.stories.tsx +0 -1
  31. package/src/stories/bugs/bug8-autolayout.stories.tsx +22 -31
  32. package/src/stories/circuit-components/diode.stories.tsx +3 -1
  33. package/src/stories/circuit-components/resistor.stories.tsx +3 -1
  34. package/src/stories/component-drawing-example.stories.tsx +2 -2
  35. package/src/stories/led-circuit-react.stories.tsx +40 -45
  36. package/src/stories/net-alias.stories.tsx +1 -1
  37. package/src/stories/off-center-render.stories.tsx +6 -6
  38. package/src/stories/rotated-resistor.stories.tsx +1 -1
  39. package/src/stories/schematic-path.stories.tsx +1 -1
  40. package/src/stories/three-sided-bug.stories.tsx +8 -8
  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 -90
  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,7 +939,8 @@ __export(src_exports, {
939
939
  module.exports = __toCommonJS(src_exports);
940
940
 
941
941
  // src/Schematic.tsx
942
- var import_react9 = require("react");
942
+ var import_core = require("@tscircuit/core");
943
+ var import_soup_util = require("@tscircuit/soup-util");
943
944
 
944
945
  // node_modules/zustand/esm/vanilla.mjs
945
946
  var import_meta = {};
@@ -1011,6 +1012,20 @@ function applyToPoint(matrix, point) {
1011
1012
  };
1012
1013
  }
1013
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
+
1014
1029
  // node_modules/transformation-matrix/src/utils.js
1015
1030
  function isUndefined(val) {
1016
1031
  return typeof val === "undefined";
@@ -1221,14 +1236,274 @@ peg$SyntaxError.buildMessage = function(expected, found) {
1221
1236
  };
1222
1237
 
1223
1238
  // src/lib/render-context/index.ts
1239
+ var import_react6 = require("react");
1240
+
1241
+ // src/schematic-components/ContextProviders.tsx
1224
1242
  var import_react2 = require("react");
1225
- var createRenderContextStore = () => createStore((set) => ({
1226
- camera_transform: compose(scale(100, 100, 0, 0)),
1227
- setCameraTransform: (transform2) => set({ camera_transform: transform2 })
1228
- }));
1229
- var useGlobalStore = (s) => {
1230
- const store = (0, import_react2.useContext)(StoreContext);
1231
- return useStore(store, s);
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
+ }
1232
1507
  };
1233
1508
 
1234
1509
  // src/lib/utils/get-svg-path-bounds.ts
@@ -1249,8 +1524,8 @@ function getSVGPathBounds(ds) {
1249
1524
  var get_svg_path_bounds_default = getSVGPathBounds;
1250
1525
 
1251
1526
  // src/schematic-components/SVGPathComponent.tsx
1252
- var import_react3 = require("react");
1253
- var import_jsx_runtime = require("react/jsx-runtime");
1527
+ var import_react4 = require("react");
1528
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1254
1529
  var SVGPathComponent = ({
1255
1530
  size,
1256
1531
  center,
@@ -1262,14 +1537,8 @@ var SVGPathComponent = ({
1262
1537
  hoverContent
1263
1538
  }) => {
1264
1539
  const ct = useGlobalStore((s) => s.camera_transform);
1265
- const pathBounds = get_svg_path_bounds_default(paths.map((p) => p.d));
1266
- const badRatio = Math.abs(pathBounds.width / pathBounds.height - size.width / size.height) > 0.01;
1267
- if (badRatio) {
1268
- }
1269
- const padding = {
1270
- x: 0,
1271
- y: 0
1272
- };
1540
+ const pathBounds = get_svg_path_bounds_default(paths.filter((p) => p.type !== "circle").map((p) => p.d));
1541
+ const padding = { x: 0, y: 0 };
1273
1542
  const absoluteCenter = applyToPoint(ct, center);
1274
1543
  const innerSize = {
1275
1544
  width: size.width * ct.a,
@@ -1279,81 +1548,50 @@ var SVGPathComponent = ({
1279
1548
  width: innerSize.width + padding.x * 2,
1280
1549
  height: innerSize.height + padding.y * 2
1281
1550
  };
1282
- const [hovering, setHovering] = (0, import_react3.useState)(false);
1551
+ const [hovering, setHovering] = (0, import_react4.useState)(false);
1283
1552
  const svgLeft = absoluteCenter.x - fullSize.width / 2;
1284
1553
  const svgTop = absoluteCenter.y - fullSize.height / 2;
1285
1554
  const preferredRatio = pathBounds.width === 0 ? innerSize.height / pathBounds.height : innerSize.width / pathBounds.width;
1286
1555
  const svgToScreen = compose(
1287
- // translate(0, 0)
1288
1556
  scale(
1289
1557
  pathBounds.width === 0 ? preferredRatio : fullSize.width / pathBounds.width,
1290
1558
  pathBounds.height === 0 ? preferredRatio : fullSize.height / pathBounds.height
1291
1559
  ),
1292
1560
  translate(-pathBounds.minX, -pathBounds.minY)
1293
- // translate(center.x, center.y)
1294
1561
  );
1295
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1296
- hovering && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
1297
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1298
- "div",
1299
- {
1300
- style: {
1301
- position: "absolute",
1302
- left: svgLeft - 6,
1303
- top: svgTop - 6,
1304
- pointerEvents: "none",
1305
- width: fullSize.width + 12,
1306
- height: fullSize.height + 12,
1307
- border: "1px red solid",
1308
- mixBlendMode: "difference",
1309
- zIndex: 1e3
1310
- }
1311
- }
1312
- ),
1313
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1314
- "div",
1315
- {
1316
- style: {
1317
- position: "absolute",
1318
- left: svgLeft + fullSize.width + 10,
1319
- pointerEvents: "none",
1320
- zIndex: 1e3,
1321
- color: "red",
1322
- mixBlendMode: "difference",
1323
- top: svgTop,
1324
- fontFamily: "monospace",
1325
- fontSize: 14
1562
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1563
+ "svg",
1564
+ {
1565
+ onMouseOver: () => setHovering(Boolean(hoverContent)),
1566
+ onMouseOut: () => setHovering(false),
1567
+ style: {
1568
+ position: "absolute",
1569
+ cursor: hovering ? "pointer" : void 0,
1570
+ zIndex,
1571
+ transform: [
1572
+ invertY ? "scale(1, 1)" : "scale(1, -1)",
1573
+ shiftToBottom ? "translate(0, 100%)" : "",
1574
+ rotation === 0 ? "" : `rotate(${rotation}deg)`
1575
+ ].join(" "),
1576
+ left: svgLeft,
1577
+ top: svgTop
1578
+ },
1579
+ overflow: "visible",
1580
+ width: fullSize.width,
1581
+ height: fullSize.height,
1582
+ children: paths.map(
1583
+ (p, i) => p.type === "circle" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1584
+ "circle",
1585
+ {
1586
+ cx: p.cx,
1587
+ cy: p.cy,
1588
+ r: p.r,
1589
+ fill: p.fill ?? "none",
1590
+ strokeWidth: 1.5 * (p.strokeWidth || 1),
1591
+ stroke: p.stroke || "red"
1326
1592
  },
1327
- children: hoverContent
1328
- }
1329
- )
1330
- ] }),
1331
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1332
- "svg",
1333
- {
1334
- onMouseOver: () => setHovering(Boolean(hoverContent)),
1335
- onMouseOut: () => setHovering(false),
1336
- style: {
1337
- position: "absolute",
1338
- // backgroundColor: hovering ? "rgba(0, 0, 255, 0.5)" : "transparent",
1339
- cursor: hovering ? "pointer" : void 0,
1340
- zIndex,
1341
- transform: [
1342
- invertY ? "scale(1, 1)" : "scale(1, -1)",
1343
- // TODO based on ct.d
1344
- shiftToBottom ? "translate(0, 100%)" : "",
1345
- rotation === 0 ? "" : `rotate(${rotation}rad)`
1346
- ].join(" "),
1347
- left: svgLeft,
1348
- top: svgTop
1349
- // overflow: "hidden",
1350
- // backgroundColor: badRatio ? "rgba(255, 0, 0, 0.1)" : "transparent",
1351
- // backgroundColor: "rgba(255, 0, 0, 0.1)",
1352
- },
1353
- overflow: "visible",
1354
- width: fullSize.width,
1355
- height: fullSize.height,
1356
- children: paths.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
1593
+ i
1594
+ ) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1357
1595
  "path",
1358
1596
  {
1359
1597
  transform: toSVG(svgToScreen),
@@ -1361,154 +1599,15 @@ var SVGPathComponent = ({
1361
1599
  strokeLinecap: "round",
1362
1600
  strokeWidth: 1.5 * (p.strokeWidth || 1),
1363
1601
  stroke: p.stroke || "red",
1364
- d: p.d
1602
+ d: p.d || ""
1365
1603
  },
1366
1604
  i
1367
- ))
1368
- }
1369
- )
1370
- ] });
1371
- };
1372
- var SVGPathComponent_default = SVGPathComponent;
1373
-
1374
- // src/schematic-components/SimpleResistor.tsx
1375
- var import_jsx_runtime2 = require("react/jsx-runtime");
1376
- var SimpleResistor = ({ component: { source, schematic } }) => {
1377
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
1378
- SVGPathComponent_default,
1379
- {
1380
- rotation: schematic.rotation,
1381
- center: schematic.center,
1382
- size: schematic.size,
1383
- paths: [
1384
- {
1385
- stroke: "red",
1386
- strokeWidth: 1,
1387
- 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"
1388
- }
1389
- ]
1390
- }
1391
- );
1392
- };
1393
-
1394
- // src/schematic-components/SimpleCapacitor.tsx
1395
- var import_jsx_runtime3 = require("react/jsx-runtime");
1396
- var SimpleCapacitor = ({
1397
- component: { source, schematic }
1398
- }) => {
1399
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1400
- SVGPathComponent_default,
1401
- {
1402
- rotation: schematic.rotation,
1403
- center: schematic.center,
1404
- size: schematic.size,
1405
- paths: [
1406
- { stroke: "red", strokeWidth: 1, d: "M 0 15 l 12 0" },
1407
- { stroke: "red", strokeWidth: 1, d: "M 12 0 l 0 30" },
1408
- { stroke: "red", strokeWidth: 1, d: "M 18 0 l 0 30" },
1409
- { stroke: "red", strokeWidth: 1, d: "M 18 15 l 12 0" }
1410
- ]
1411
- }
1412
- );
1413
- };
1414
-
1415
- // src/lib/hooks/use-maybe-promise.ts
1416
- var import_react4 = require("react");
1417
-
1418
- // src/schematic-components/ProjectComponent.tsx
1419
- var import_builder = require("@tscircuit/builder");
1420
- var import_jsx_runtime4 = require("react/jsx-runtime");
1421
-
1422
- // src/schematic-components/SchematicComponent.tsx
1423
- var import_jsx_runtime5 = require("react/jsx-runtime");
1424
- var SchematicComponent = ({ component }) => {
1425
- const { source, schematic } = component;
1426
- if (!source.ftype)
1427
- return null;
1428
- switch (source.ftype) {
1429
- case "simple_resistor": {
1430
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SimpleResistor, { component: { source, schematic } });
1431
- }
1432
- case "simple_capacitor": {
1433
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SimpleCapacitor, { component: { source, schematic } });
1434
- }
1435
- case "simple_power_source": {
1436
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SimplePowerSource, { component: { source, schematic } });
1437
- }
1438
- case "simple_ground": {
1439
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SimpleGround, { component: { source, schematic } });
1440
- }
1441
- case "simple_inductor": {
1442
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SimpleInductor, { component: { source, schematic } });
1443
- }
1444
- case "simple_bug": {
1445
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SchematicBug, { component: { source, schematic } });
1446
- }
1447
- case "simple_diode": {
1448
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SimpleDiode, { component: { source, schematic } });
1449
- }
1450
- default: {
1451
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { children: [
1452
- "unknown ftype: ",
1453
- component.source.ftype
1454
- ] });
1455
- }
1456
- }
1457
- };
1458
- var SchematicComponent_default = SchematicComponent;
1459
-
1460
- // src/lib/utils/direction-to-vec.ts
1461
- var directionToVec = (direction) => {
1462
- if (direction === "up")
1463
- return { x: 0, y: 1 };
1464
- else if (direction === "down")
1465
- return { x: 0, y: -1 };
1466
- else if (direction === "left")
1467
- return { x: -1, y: 0 };
1468
- else if (direction === "right")
1469
- return { x: 1, y: 0 };
1470
- else
1471
- throw new Error(`Invalid direction "${direction}"`);
1472
- };
1473
-
1474
- // src/schematic-components/SchematicPort.tsx
1475
- var import_jsx_runtime6 = require("react/jsx-runtime");
1476
- var SchematicPort = ({
1477
- port: { source_port, source_component, schematic }
1478
- }) => {
1479
- const hoverName = source_component?.name ? `.${source_component.name} > .${source_port?.name ?? source_port?.pin_number}` : `.${source_port?.name ?? source_port?.pin_number}`;
1480
- const vec = directionToVec(schematic.facing_direction);
1481
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(
1482
- SVGPathComponent,
1483
- {
1484
- rotation: 0,
1485
- hoverContent: /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1486
- hoverName,
1487
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("br", {}),
1488
- source_port?.pin_number && `Pin ${source_port.pin_number}`
1489
- ] }),
1490
- center: schematic.center,
1491
- size: {
1492
- width: 0.2 + Math.abs(vec.x) * 0.04,
1493
- height: 0.2 + Math.abs(vec.y) * 0.04
1494
- },
1495
- zIndex: 10,
1496
- paths: [
1497
- {
1498
- stroke: "blue",
1499
- strokeWidth: 1,
1500
- d: "M 0 0 l 10 0 l 0 10 l -10 0 z"
1501
- },
1502
- schematic.facing_direction ? {
1503
- stroke: "blue",
1504
- strokeWidth: 0.5,
1505
- d: `M 5 5 l ${vec.x * 7} ${vec.y * 7}`
1506
- } : null
1507
- ].filter(Boolean)
1605
+ )
1606
+ )
1508
1607
  }
1509
1608
  );
1510
1609
  };
1511
- var SchematicPort_default = SchematicPort;
1610
+ var SVGPathComponent_default = SVGPathComponent;
1512
1611
 
1513
1612
  // node_modules/react-use-measure/dist/web.js
1514
1613
  var import_react5 = require("react");
@@ -1661,7 +1760,7 @@ var keys = ["x", "y", "top", "bottom", "left", "right", "width", "height"];
1661
1760
  var areBoundsEqual = (a, b) => keys.every((key) => a[key] === b[key]);
1662
1761
 
1663
1762
  // src/schematic-components/SchematicText.tsx
1664
- var import_jsx_runtime7 = require("react/jsx-runtime");
1763
+ var import_jsx_runtime4 = require("react/jsx-runtime");
1665
1764
  var SchematicText = ({ schematic_text }) => {
1666
1765
  const ct = useGlobalStore((s) => s.camera_transform);
1667
1766
  const { text, position, anchor } = schematic_text;
@@ -1677,7 +1776,7 @@ var SchematicText = ({ schematic_text }) => {
1677
1776
  }
1678
1777
  const fontTransformRatio = 0.15;
1679
1778
  const projectedTextSize = fontTransformRatio * ct.a;
1680
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1779
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
1681
1780
  "div",
1682
1781
  {
1683
1782
  ref: boundsRef,
@@ -1694,85 +1793,222 @@ var SchematicText = ({ schematic_text }) => {
1694
1793
  };
1695
1794
  var SchematicText_default = SchematicText;
1696
1795
 
1697
- // src/schematic-components/SchematicTrace.tsx
1698
- var import_svg_path_generator = __toESM(require_svg_path_generator2());
1699
-
1700
- // src/schematic-components/RenderError.tsx
1701
- var import_jsx_runtime8 = require("react/jsx-runtime");
1702
- var RenderError_default = ({ text }) => {
1703
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
1704
- "div",
1705
- {
1706
- style: {
1707
- position: "fixed",
1708
- backgroundColor: "red",
1709
- color: "white",
1710
- fontSize: 14,
1711
- fontFamily: "sans-serif",
1712
- padding: 5,
1713
- right: 0,
1714
- top: 0,
1715
- opacity: 0.75
1796
+ // src/schematic-components/SchematicChip.tsx
1797
+ var import_jsx_runtime5 = require("react/jsx-runtime");
1798
+ var SchematicChip = ({ component: { source, schematic, allElements } }) => {
1799
+ const { center, size, rotation, schematic_component_id } = schematic;
1800
+ const { manufacturerPartNumber, name } = source;
1801
+ const chipWidth = size.width;
1802
+ const chipHeight = size.height;
1803
+ const paths = [];
1804
+ paths.push({
1805
+ type: "path",
1806
+ strokeWidth: 0.02,
1807
+ stroke: colorMap.schematic.component_outline,
1808
+ fill: colorMap.schematic.component_body,
1809
+ d: `M ${-chipWidth / 2},${-chipHeight / 2} h ${chipWidth} v ${chipHeight} h ${-chipWidth} Z`
1810
+ });
1811
+ const schematicPorts = allElements.filter(
1812
+ (item) => item.type === "schematic_port" && item.schematic_component_id === schematic_component_id
1813
+ );
1814
+ const portLength = 0.2;
1815
+ const circleRadius = 0.05;
1816
+ const labelOffset = 0.1;
1817
+ const pinLabels = [];
1818
+ schematicPorts.forEach((port) => {
1819
+ const { side, pinNumber, distanceFromEdge } = port.center;
1820
+ let x = 0, y = 0, endX = 0, endY = 0;
1821
+ let labelX = 0, labelY = 0;
1822
+ let textAnchor = "middle";
1823
+ switch (side) {
1824
+ case "left":
1825
+ x = -chipWidth / 2;
1826
+ y = -chipHeight / 2 + distanceFromEdge;
1827
+ endX = x - portLength;
1828
+ endY = y;
1829
+ labelX = endX;
1830
+ labelY = y + labelOffset;
1831
+ textAnchor = "end";
1832
+ break;
1833
+ case "right":
1834
+ x = chipWidth / 2;
1835
+ y = chipHeight / 2 - distanceFromEdge;
1836
+ endX = x + portLength;
1837
+ endY = y;
1838
+ labelX = endX - labelOffset;
1839
+ labelY = y + labelOffset;
1840
+ textAnchor = "start";
1841
+ break;
1842
+ case "bottom":
1843
+ x = -chipWidth / 2 + distanceFromEdge;
1844
+ y = -chipHeight / 2;
1845
+ endX = x;
1846
+ endY = y - portLength;
1847
+ labelX = x;
1848
+ labelY = endY + labelOffset;
1849
+ break;
1850
+ case "top":
1851
+ x = chipWidth / 2 - distanceFromEdge;
1852
+ y = chipHeight / 2;
1853
+ endX = x;
1854
+ endY = y + portLength;
1855
+ labelX = x;
1856
+ labelY = endY + labelOffset;
1857
+ break;
1858
+ }
1859
+ paths.push({
1860
+ type: "path",
1861
+ strokeWidth: 0.02,
1862
+ stroke: colorMap.schematic.component_outline,
1863
+ d: `M ${x},${y} L ${endX},${endY}`
1864
+ });
1865
+ paths.push({
1866
+ type: "circle",
1867
+ cx: endX,
1868
+ cy: endY,
1869
+ r: circleRadius,
1870
+ strokeWidth: 0.01,
1871
+ stroke: colorMap.schematic.component_outline,
1872
+ fill: colorMap.schematic.component_outline
1873
+ });
1874
+ if (pinNumber !== void 0) {
1875
+ pinLabels.push({
1876
+ x: labelX,
1877
+ y: labelY,
1878
+ text: `${pinNumber}`,
1879
+ anchor: textAnchor
1880
+ });
1881
+ }
1882
+ });
1883
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
1884
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1885
+ SVGPathComponent_default,
1886
+ {
1887
+ rotation,
1888
+ center,
1889
+ size,
1890
+ paths
1891
+ }
1892
+ ),
1893
+ pinLabels.map((label, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1894
+ SchematicText_default,
1895
+ {
1896
+ schematic_text: {
1897
+ anchor: label.anchor,
1898
+ position: {
1899
+ x: center.x + label.x,
1900
+ y: center.y + label.y
1901
+ },
1902
+ schematic_component_id: "SYNTHETIC",
1903
+ schematic_text_id: `PIN_LABEL_${index}`,
1904
+ text: label.text,
1905
+ type: "schematic_text"
1906
+ }
1716
1907
  },
1717
- children: text
1908
+ index
1909
+ )),
1910
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1911
+ SchematicText_default,
1912
+ {
1913
+ schematic_text: {
1914
+ anchor: "center",
1915
+ position: {
1916
+ x: center.x,
1917
+ y: center.y - chipHeight / 2 - 0.2
1918
+ },
1919
+ schematic_component_id: "SYNTHETIC",
1920
+ schematic_text_id: "SYNTHETIC_MPN",
1921
+ text: manufacturerPartNumber,
1922
+ type: "schematic_text"
1923
+ }
1924
+ }
1925
+ ),
1926
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
1927
+ SchematicText_default,
1928
+ {
1929
+ schematic_text: {
1930
+ anchor: "center",
1931
+ position: {
1932
+ x: center.x,
1933
+ y: center.y + chipHeight / 2 + 0.2
1934
+ },
1935
+ schematic_component_id: "SYNTHETIC",
1936
+ schematic_text_id: "SYNTHETIC_NAME",
1937
+ text: name,
1938
+ type: "schematic_text"
1939
+ }
1940
+ }
1941
+ )
1942
+ ] });
1943
+ };
1944
+
1945
+ // src/schematic-components/SchematicComponent.tsx
1946
+ var import_jsx_runtime6 = require("react/jsx-runtime");
1947
+ var SchematicComponent = ({ component }) => {
1948
+ const { source, schematic, allElements } = component;
1949
+ if (!source.ftype)
1950
+ return null;
1951
+ switch (source.ftype) {
1952
+ case "simple_resistor":
1953
+ case "simple_capacitor":
1954
+ case "simple_power_source":
1955
+ case "simple_ground":
1956
+ case "simple_inductor":
1957
+ case "simple_diode": {
1958
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SchematicComponentFromSymbol, { component: { source, schematic } });
1718
1959
  }
1719
- );
1960
+ case "simple_chip":
1961
+ case "simple_bug": {
1962
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(SchematicChip, { component: { source, schematic, allElements } });
1963
+ }
1964
+ default: {
1965
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("div", { children: [
1966
+ "unknown ftype: ",
1967
+ component.source.ftype
1968
+ ] });
1969
+ }
1970
+ }
1720
1971
  };
1972
+ var SchematicComponent_default = SchematicComponent;
1721
1973
 
1722
- // src/schematic-components/SVGPathComponent2.tsx
1723
- var import_jsx_runtime9 = require("react/jsx-runtime");
1724
- var SVGPathComponent2 = ({
1725
- size,
1726
- center,
1727
- rotation,
1728
- paths,
1729
- zIndex,
1730
- invertY,
1731
- shiftToBottom,
1732
- hoverContent
1733
- }) => {
1734
- const ct = useGlobalStore((c) => c.camera_transform);
1735
- const pathBounds = get_svg_path_bounds_default(paths.map((p) => p.d));
1736
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1737
- "svg",
1974
+ // src/schematic-components/SchematicComponentFromSymbol.tsx
1975
+ var import_schematic_symbols = require("schematic-symbols");
1976
+ var import_jsx_runtime7 = require("react/jsx-runtime");
1977
+ var SchematicComponentFromSymbol = ({ component: { source, schematic } }) => {
1978
+ const { center, rotation } = schematic;
1979
+ const symbol = import_schematic_symbols.symbols[schematic.symbol_name];
1980
+ const paths = symbol.primitives.filter((p) => p.type === "path").map((p) => ({
1981
+ stroke: colorMap.schematic.component_outline,
1982
+ strokeWidth: 0.02,
1983
+ d: p.points.reduce(
1984
+ (acc, point, index) => {
1985
+ const command = index === 0 ? "M" : "L";
1986
+ return `${acc} ${command} ${point.x} ${point.y}`;
1987
+ },
1988
+ ""
1989
+ )
1990
+ }));
1991
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1992
+ SVGPathComponent_default,
1738
1993
  {
1739
- style: {
1740
- position: "absolute",
1741
- left: 0,
1742
- top: 0,
1743
- right: 0,
1744
- bottom: 0,
1745
- // backgroundColor: hovering ? "rgba(0, 0, 255, 0.5)" : "transparent",
1746
- pointerEvents: "none",
1747
- zIndex
1748
- // overflow: "hidden",
1749
- // backgroundColor: badRatio ? "rgba(255, 0, 0, 0.1)" : "transparent",
1750
- // backgroundColor: "rgba(255, 0, 0, 0.1)",
1994
+ rotation,
1995
+ center,
1996
+ size: {
1997
+ width: symbol?.size.width,
1998
+ height: symbol?.size.height
1751
1999
  },
1752
- overflow: "visible",
1753
- children: paths.map((p, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
1754
- "path",
1755
- {
1756
- transform: toSVG(ct),
1757
- fill: p.fill ?? "none",
1758
- strokeLinecap: "round",
1759
- strokeWidth: 1.5 * (p.strokeWidth || 1),
1760
- stroke: p.stroke || "red",
1761
- d: p.d
1762
- },
1763
- i
1764
- ))
2000
+ paths
1765
2001
  }
1766
2002
  );
1767
2003
  };
1768
- var SVGPathComponent2_default = SVGPathComponent2;
1769
2004
 
1770
2005
  // src/schematic-components/SchematicTrace.tsx
1771
- var import_jsx_runtime10 = require("react/jsx-runtime");
2006
+ var import_svg_path_generator = __toESM(require_svg_path_generator2());
2007
+ var import_jsx_runtime8 = require("react/jsx-runtime");
1772
2008
  var SchematicTrace = ({ trace: { source, schematic } }) => {
1773
2009
  const edges = schematic.edges;
1774
2010
  if (edges.length === 0) {
1775
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(RenderError_default, { text: `Route with 0 edges (${source.source_trace_id})` });
2011
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(RenderError_default, { text: `Route with 0 edges (${source.source_trace_id})` });
1776
2012
  }
1777
2013
  const path = (0, import_svg_path_generator.default)();
1778
2014
  for (let i = 0; i < edges.length; i++) {
@@ -1787,16 +2023,16 @@ var SchematicTrace = ({ trace: { source, schematic } }) => {
1787
2023
  x: pathBounds.minX + pathBounds.width / 2,
1788
2024
  y: pathBounds.minY + pathBounds.height / 2
1789
2025
  };
1790
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
1791
- SVGPathComponent2_default,
2026
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
2027
+ SVGPathComponent_default,
1792
2028
  {
1793
2029
  rotation: 0,
1794
2030
  center,
1795
2031
  size: pathBounds,
1796
2032
  paths: [
1797
2033
  {
1798
- stroke: "green",
1799
- strokeWidth: 0.02,
2034
+ stroke: colorMap.schematic.wire,
2035
+ strokeWidth: 0.01,
1800
2036
  d
1801
2037
  }
1802
2038
  ]
@@ -1805,184 +2041,20 @@ var SchematicTrace = ({ trace: { source, schematic } }) => {
1805
2041
  };
1806
2042
  var SchematicTrace_default = SchematicTrace;
1807
2043
 
1808
- // src/schematic-components/SchematicBug.tsx
1809
- var import_builder2 = require("@tscircuit/builder");
1810
- var import_jsx_runtime11 = require("react/jsx-runtime");
1811
- var SchematicBug = ({ component: { source, schematic } }) => {
1812
- const port_arrangement = {
1813
- top_size: 0,
1814
- bottom_size: 0,
1815
- ...schematic.port_arrangement
1816
- };
1817
- let bugw = schematic.size.width;
1818
- let bugh = schematic.size.height;
1819
- const { total_ports, width, height } = (0, import_builder2.getPortArrangementSize)(port_arrangement);
1820
- const port_indices = (0, import_builder2.getPortIndices)(port_arrangement);
1821
- if (isNaN(bugw))
1822
- bugw = width;
1823
- if (isNaN(bugh))
1824
- bugh = height;
1825
- const paths = [
1826
- {
1827
- stroke: "red",
1828
- strokeWidth: 0.02,
1829
- d: `M ${-bugw / 2} ${-bugh / 2} L ${bugw / 2} ${-bugh / 2} L ${bugw / 2} ${bugh / 2} L ${-bugw / 2} ${bugh / 2}Z`
1830
- },
1831
- ...port_indices.map((portNum) => {
1832
- const pos = (0, import_builder2.getPortPosition)(
1833
- { ...port_arrangement, pin_spacing: schematic.pin_spacing },
1834
- portNum
1835
- );
1836
- const x2 = pos.side === "left" ? -bugw / 2 : pos.side === "right" ? bugw / 2 : pos.x;
1837
- const y2 = pos.side === "top" ? bugh / 2 : pos.side === "bottom" ? -bugh / 2 : pos.y;
1838
- return {
1839
- stroke: "red",
1840
- strokeWidth: 0.02,
1841
- d: `M ${pos.x} ${pos.y} L ${x2} ${y2}`
1842
- };
1843
- })
1844
- ];
1845
- const actualSize = get_svg_path_bounds_default(paths.map((p) => p.d).join(" "));
1846
- const actualCenter = {
1847
- x: schematic.center.x + (actualSize.minX + actualSize.maxX) / 2,
1848
- y: schematic.center.y + (actualSize.minY + actualSize.maxY) / 2
1849
- };
1850
- return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
1851
- SVGPathComponent_default,
1852
- {
1853
- rotation: schematic.rotation,
1854
- center: actualCenter,
1855
- size: actualSize,
1856
- paths
1857
- }
1858
- );
1859
- };
1860
-
1861
- // src/schematic-components/SimplePowerSource.tsx
1862
- var import_jsx_runtime12 = require("react/jsx-runtime");
1863
- var SimplePowerSource = ({
1864
- component: { source, schematic }
1865
- }) => {
1866
- return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
1867
- SVGPathComponent_default,
1868
- {
1869
- rotation: schematic.rotation,
1870
- center: schematic.center,
1871
- size: schematic.size,
1872
- invertY: true,
1873
- paths: [
1874
- {
1875
- stroke: "red",
1876
- strokeWidth: 1,
1877
- 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"
1878
- },
1879
- // positive symbol
1880
- {
1881
- stroke: "red",
1882
- strokeWidth: 0.5,
1883
- d: "M 8 -9 L 8 -6 M 9.5 -7.5 L 6.5 -7.5"
1884
- },
1885
- // negative symbol
1886
- {
1887
- stroke: "red",
1888
- strokeWidth: 0.5,
1889
- d: "M 9.5 7.5 L 6.5 7.5"
1890
- }
1891
- ]
1892
- }
1893
- );
1894
- };
1895
-
1896
- // src/schematic-components/SimpleGround.tsx
1897
- var import_jsx_runtime13 = require("react/jsx-runtime");
1898
- var SimpleGround = ({ component: { source, schematic } }) => {
1899
- return /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
1900
- SVGPathComponent_default,
1901
- {
1902
- rotation: schematic.rotation,
1903
- center: schematic.center,
1904
- size: schematic.size,
1905
- invertY: true,
1906
- shiftToBottom: true,
1907
- paths: [
1908
- {
1909
- stroke: "red",
1910
- strokeWidth: 0.7,
1911
- 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"
1912
- }
1913
- ]
1914
- }
1915
- );
1916
- };
1917
-
1918
- // src/schematic-components/SimpleInductor.tsx
1919
- var import_jsx_runtime14 = require("react/jsx-runtime");
1920
- var SimpleInductor = ({ component: { source, schematic } }) => {
1921
- return /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(
1922
- SVGPathComponent_default,
1923
- {
1924
- rotation: schematic.rotation,
1925
- center: schematic.center,
1926
- size: schematic.size,
1927
- paths: [
1928
- {
1929
- stroke: "red",
1930
- strokeWidth: 1,
1931
- // https://commons.wikimedia.org/wiki/File:Electrical_symbols_library.svg
1932
- 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"
1933
- }
1934
- ]
1935
- }
1936
- );
1937
- };
1938
-
1939
- // src/schematic-components/SimpleDiode.tsx
1940
- var import_jsx_runtime15 = require("react/jsx-runtime");
1941
- var SimpleDiode = ({ component: { source, schematic } }) => {
1942
- return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)(
1943
- SVGPathComponent_default,
1944
- {
1945
- rotation: schematic.rotation,
1946
- center: schematic.center,
1947
- size: {
1948
- height: 0.5,
1949
- width: 1
1950
- },
1951
- paths: [
1952
- { stroke: "red", strokeWidth: 2, d: "M 0,0 H 21" },
1953
- { stroke: "red", strokeWidth: 2, d: "M 49,0 H 59" },
1954
- { stroke: "red", strokeWidth: 2, d: "M 49,0 L 21 14 V -14 Z" },
1955
- { stroke: "red", strokeWidth: 2, d: "M 49,-14 V 14" }
1956
- // For LEDs
1957
- // {
1958
- // stroke: "red",
1959
- // strokeWidth: 2,
1960
- // d: "M 35 -32 l 7 5.25 l 1.75 -9.625 z m 3.5 2.625 l -5.25 7",
1961
- // },
1962
- // {
1963
- // stroke: "red",
1964
- // strokeWidth: 2,
1965
- // d: "M 52 -26 l 7 5.25 l 1.75 -9.625 z m 3.5 2.625 l -5.25 7",
1966
- // },
1967
- ]
1968
- }
1969
- );
1970
- };
1971
-
1972
- // src/schematic-components/ContextProviders.tsx
1973
- var import_react6 = require("react");
1974
- var import_react7 = require("react");
1975
- var import_jsx_runtime16 = require("react/jsx-runtime");
1976
- var StoreContext = (0, import_react7.createContext)(null);
1977
- var ContextProviders = ({ children }) => {
1978
- const store = (0, import_react6.useMemo)(() => createRenderContextStore(), []);
1979
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(StoreContext.Provider, { value: store, children });
2044
+ // src/lib/render-context/index.ts
2045
+ var createRenderContextStore = () => createStore((set) => ({
2046
+ camera_transform: compose(scale(100, 100, 0, 0)),
2047
+ setCameraTransform: (transform2) => set({ camera_transform: transform2 })
2048
+ }));
2049
+ var useGlobalStore = (s) => {
2050
+ const store = (0, import_react6.useContext)(StoreContext);
2051
+ return useStore(store, s);
1980
2052
  };
1981
2053
 
1982
2054
  // src/Schematic.tsx
2055
+ var import_react8 = require("react");
2056
+ var import_react_error_boundary = require("react-error-boundary");
1983
2057
  var import_react_supergrid = require("react-supergrid");
1984
- var import_builder3 = require("@tscircuit/builder");
1985
- var import_react_fiber = __toESM(require("@tscircuit/react-fiber"));
1986
2058
 
1987
2059
  // src/lib/utils/collect-element-refs.ts
1988
2060
  var collectElementRefs = (elm, allElms) => {
@@ -2009,110 +2081,13 @@ var collectElementRefs = (elm, allElms) => {
2009
2081
  schematic: elm,
2010
2082
  source: source_component,
2011
2083
  source_component,
2012
- source_port
2084
+ source_port,
2085
+ allElements: allElms
2013
2086
  };
2014
2087
  }
2015
2088
  return null;
2016
2089
  };
2017
2090
 
2018
- // src/schematic-components/SchematicBox.tsx
2019
- var import_jsx_runtime17 = require("react/jsx-runtime");
2020
- var SchematicBox = ({ box: { schematic } }) => {
2021
- const { width: w, height: h } = schematic;
2022
- return /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
2023
- SVGPathComponent,
2024
- {
2025
- rotation: 0,
2026
- center: schematic,
2027
- size: { width: schematic.width, height: schematic.height },
2028
- paths: [
2029
- {
2030
- stroke: "red",
2031
- strokeWidth: 0.02,
2032
- d: `M 0 0 l ${w} 0 l 0 ${h} l -${w} 0 z`
2033
- }
2034
- ]
2035
- }
2036
- );
2037
- };
2038
- var SchematicBox_default = SchematicBox;
2039
-
2040
- // src/schematic-components/SchematicLine.tsx
2041
- var import_svg_path_generator2 = __toESM(require_svg_path_generator2());
2042
- var import_jsx_runtime18 = require("react/jsx-runtime");
2043
- var SchematicLine = ({ line: { schematic } }) => {
2044
- const { x1, x2, y1, y2 } = schematic;
2045
- const dx = x2 - x1;
2046
- const dy = y2 - y1;
2047
- const path = (0, import_svg_path_generator2.default)();
2048
- path.moveTo(x1, y1);
2049
- path.lineTo(x2, y2);
2050
- const d = path.toString();
2051
- const pathBounds = get_svg_path_bounds_default(d);
2052
- const center = {
2053
- x: pathBounds.minX + pathBounds.width / 2,
2054
- y: pathBounds.minY + pathBounds.height / 2
2055
- };
2056
- return /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
2057
- SVGPathComponent,
2058
- {
2059
- rotation: 0,
2060
- center,
2061
- size: pathBounds,
2062
- paths: [
2063
- {
2064
- stroke: "red",
2065
- strokeWidth: 0.02,
2066
- d
2067
- }
2068
- ]
2069
- }
2070
- );
2071
- };
2072
- var SchematicLine_default = SchematicLine;
2073
-
2074
- // src/schematic-components/SchematicPath.tsx
2075
- var import_svg_path_generator3 = __toESM(require_svg_path_generator2());
2076
- var import_jsx_runtime19 = require("react/jsx-runtime");
2077
- var SchematicPath = (props) => {
2078
- const { points, is_filled, is_closed, fill_color } = props.path.schematic;
2079
- if (points.length === 0)
2080
- return null;
2081
- const path = (0, import_svg_path_generator3.default)();
2082
- path.moveTo(points[0].x, points[0].y);
2083
- for (const point of points.slice(1)) {
2084
- path.lineTo(point.x, point.y);
2085
- }
2086
- if (is_closed) {
2087
- path.closePath();
2088
- }
2089
- const d = path.toString();
2090
- const pathBounds = get_svg_path_bounds_default(d);
2091
- pathBounds.height = Math.max(pathBounds.height, 1);
2092
- pathBounds.width = Math.max(pathBounds.width, 1);
2093
- const center = {
2094
- x: pathBounds.minX + pathBounds.width / 2,
2095
- y: pathBounds.minY + pathBounds.height / 2
2096
- };
2097
- return /* @__PURE__ */ (0, import_jsx_runtime19.jsx)(
2098
- SVGPathComponent,
2099
- {
2100
- rotation: 0,
2101
- center,
2102
- size: pathBounds,
2103
- paths: [
2104
- {
2105
- stroke: is_filled ? "none" : fill_color ?? "red",
2106
- strokeWidth: 0.02,
2107
- fill: is_filled ? fill_color ?? "red" : void 0,
2108
- d
2109
- }
2110
- ]
2111
- }
2112
- );
2113
- };
2114
- var SchematicPath_default = SchematicPath;
2115
-
2116
2091
  // src/lib/utils/get-rotation-from-anchor-side.ts
2117
2092
  var getRotationFromAnchorSide = (anchor_side) => {
2118
2093
  if (anchor_side === "left")
@@ -2140,7 +2115,7 @@ var getVecFromAnchorSide = (anchor_side) => {
2140
2115
  };
2141
2116
 
2142
2117
  // src/schematic-components/SchematicNetLabel.tsx
2143
- var import_jsx_runtime20 = require("react/jsx-runtime");
2118
+ var import_jsx_runtime9 = require("react/jsx-runtime");
2144
2119
  var SchematicNetLabel = ({
2145
2120
  net_label
2146
2121
  }) => {
@@ -2152,8 +2127,8 @@ var SchematicNetLabel = ({
2152
2127
  const anchor_dist = is_vertical ? 0.04 : text_width / 4;
2153
2128
  anchor_vec.x *= anchor_dist;
2154
2129
  anchor_vec.y *= anchor_dist;
2155
- return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
2156
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2130
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
2131
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2157
2132
  SVGPathComponent_default,
2158
2133
  {
2159
2134
  rotation: getRotationFromAnchorSide(anchor_side),
@@ -2172,7 +2147,7 @@ var SchematicNetLabel = ({
2172
2147
  ]
2173
2148
  }
2174
2149
  ),
2175
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
2150
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
2176
2151
  SchematicText_default,
2177
2152
  {
2178
2153
  schematic_text: {
@@ -2192,13 +2167,13 @@ var SchematicNetLabel = ({
2192
2167
  };
2193
2168
 
2194
2169
  // src/schematic-components/SchematicElement.tsx
2195
- var import_jsx_runtime21 = require("react/jsx-runtime");
2170
+ var import_jsx_runtime10 = require("react/jsx-runtime");
2196
2171
  var SchematicElement = ({
2197
2172
  element,
2198
2173
  allElements
2199
2174
  }) => {
2200
2175
  if (element.type === "schematic_component") {
2201
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
2176
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2202
2177
  SchematicComponent_default,
2203
2178
  {
2204
2179
  component: collectElementRefs(element, allElements)
@@ -2206,51 +2181,32 @@ var SchematicElement = ({
2206
2181
  );
2207
2182
  }
2208
2183
  if (element.type === "schematic_trace") {
2209
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SchematicTrace_default, { trace: collectElementRefs(element, allElements) });
2210
- }
2211
- if (element.type === "schematic_port") {
2212
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SchematicPort_default, { port: collectElementRefs(element, allElements) });
2213
- }
2214
- if (element.type === "schematic_box") {
2215
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SchematicBox_default, { box: collectElementRefs(element, allElements) });
2216
- }
2217
- if (element.type === "schematic_line") {
2218
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SchematicLine_default, { line: collectElementRefs(element, allElements) });
2219
- }
2220
- if (element.type === "schematic_path") {
2221
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SchematicPath_default, { path: collectElementRefs(element, allElements) });
2184
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SchematicTrace_default, { trace: collectElementRefs(element, allElements) });
2222
2185
  }
2223
2186
  if (element.type === "schematic_text") {
2224
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SchematicText_default, { schematic_text: element });
2187
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SchematicText_default, { schematic_text: element });
2225
2188
  }
2226
2189
  if (element.type === "schematic_net_label") {
2227
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(SchematicNetLabel, { net_label: element });
2228
- }
2229
- if (element.type === "source_error") {
2230
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(RenderError_default, { text: element.message });
2190
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(SchematicNetLabel, { net_label: element });
2231
2191
  }
2232
2192
  return null;
2233
2193
  };
2234
2194
 
2235
- // src/Schematic.tsx
2236
- var import_use_mouse_matrix_transform = require("use-mouse-matrix-transform");
2237
- var import_react_error_boundary = require("react-error-boundary");
2238
-
2239
2195
  // src/schematic-components/TableViewer.tsx
2240
- var import_react8 = require("react");
2241
- var import_jsx_runtime22 = require("react/jsx-runtime");
2242
- var LazyTableViewer = (0, import_react8.lazy)(
2196
+ var import_react7 = require("react");
2197
+ var import_jsx_runtime11 = require("react/jsx-runtime");
2198
+ var LazyTableViewer = (0, import_react7.lazy)(
2243
2199
  () => import("@tscircuit/table-viewer").then((m) => ({
2244
2200
  default: m.SoupTableViewer
2245
2201
  }))
2246
2202
  );
2247
- 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 }) });
2203
+ 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 }) });
2248
2204
 
2249
2205
  // src/Schematic.tsx
2250
- var import_jsx_runtime23 = require("react/jsx-runtime");
2206
+ var import_jsx_runtime12 = require("react/jsx-runtime");
2251
2207
  var ErrorBoundary = import_react_error_boundary.ErrorBoundary;
2252
2208
  var fallbackRender = (elm) => ({ error, resetErrorBoundary }) => {
2253
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { style: { color: "red" }, children: [
2209
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { style: { color: "red" }, children: [
2254
2210
  "error rendering ",
2255
2211
  elm.type,
2256
2212
  ": ",
@@ -2259,70 +2215,136 @@ var fallbackRender = (elm) => ({ error, resetErrorBoundary }) => {
2259
2215
  };
2260
2216
  var toMMSINeg = (v, z) => v >= 0 ? (0, import_react_supergrid.toMMSI)(v, z) : `-${(0, import_react_supergrid.toMMSI)(-v, z)}`;
2261
2217
  var Schematic = (props) => {
2262
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ContextProviders, { children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(SchematicWithoutContext, { ...props }) });
2218
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ContextProviders, { children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(SchematicWithoutContext, { ...props }) });
2263
2219
  };
2264
2220
  var SchematicWithoutContext = ({
2265
2221
  children,
2266
- elements: initialElements,
2267
- soup: initialSoup,
2222
+ soup,
2268
2223
  style,
2269
2224
  showTable = false,
2270
2225
  _soupPostProcessor
2271
2226
  }) => {
2272
- initialSoup = initialSoup ?? initialElements ?? [];
2273
- const [elements, setElements] = (0, import_react9.useState)(initialSoup ?? []);
2274
- const [project, setProject] = (0, import_react9.useState)(null);
2275
- const { setCameraTransform, camera_transform: cameraTransform } = useGlobalStore();
2227
+ const {
2228
+ circuitJson: circuitJsonFromChildren,
2229
+ error: errorFromChildren,
2230
+ isLoading
2231
+ } = (0, import_core.useRenderedCircuit)(children);
2232
+ const [elements, setElements] = (0, import_react8.useState)([]);
2233
+ const { setCameraTransform } = useGlobalStore();
2276
2234
  const [boundsRef, bounds] = useMeasure();
2277
- const { ref, setTransform } = (0, import_use_mouse_matrix_transform.useMouseMatrixTransform)({
2278
- onSetTransform: (transform2) => {
2279
- setCameraTransform(transform2);
2235
+ const containerRef = (0, import_react8.useRef)(null);
2236
+ const transformRef = (0, import_react8.useRef)(compose(translate(0, 0), scale(1, 1)));
2237
+ const isDraggingRef = (0, import_react8.useRef)(false);
2238
+ const lastMousePosRef = (0, import_react8.useRef)({ x: 0, y: 0 });
2239
+ const [, forceUpdate] = (0, import_react8.useState)({});
2240
+ const updateTransform = (0, import_react8.useCallback)(
2241
+ (newTransform) => {
2242
+ transformRef.current = newTransform;
2243
+ setCameraTransform(newTransform);
2244
+ forceUpdate({});
2245
+ },
2246
+ [setCameraTransform]
2247
+ );
2248
+ (0, import_react8.useEffect)(() => {
2249
+ let processedElements = [];
2250
+ if (circuitJsonFromChildren && (!soup || soup.length === 0)) {
2251
+ processedElements = circuitJsonFromChildren;
2252
+ } else if (soup && soup.length > 0) {
2253
+ processedElements = soup;
2280
2254
  }
2281
- // initialTransform: compose(scale(100, 100, 0, 0)),
2282
- });
2283
- const setElementsAndCamera = (0, import_react9.useCallback)(
2284
- (elements2) => {
2285
- const elmBounds = ref.current.getBoundingClientRect();
2286
- const { center, width, height } = elements2.some(
2255
+ if (processedElements.length > 0) {
2256
+ if (_soupPostProcessor) {
2257
+ processedElements = _soupPostProcessor(processedElements);
2258
+ }
2259
+ setElements(processedElements);
2260
+ }
2261
+ }, [circuitJsonFromChildren, soup, _soupPostProcessor]);
2262
+ (0, import_react8.useEffect)(() => {
2263
+ if (elements.length > 0 && containerRef.current) {
2264
+ const elmBounds = containerRef.current.getBoundingClientRect();
2265
+ const { center, width, height } = elements.some(
2287
2266
  (e) => e.type.startsWith("schematic_")
2288
- ) ? (0, import_builder3.findBoundsAndCenter)(
2289
- elements2.filter((e) => e.type.startsWith("schematic_"))
2267
+ ) ? (0, import_soup_util.findBoundsAndCenter)(
2268
+ elements.filter((e) => e.type.startsWith("schematic_"))
2290
2269
  ) : { center: { x: 0, y: 0 }, width: 1e-3, height: 1e-3 };
2291
2270
  const scaleFactor = Math.min(
2292
2271
  (elmBounds.width ?? 0) / width,
2293
2272
  (elmBounds.height ?? 0) / height,
2294
2273
  100
2295
2274
  );
2296
- setElements(elements2);
2297
- setProject((0, import_builder3.createProjectFromElements)(elements2));
2298
- setTransform(
2299
- compose(
2300
- translate((elmBounds.width ?? 0) / 2, (elmBounds.height ?? 0) / 2),
2301
- scale(scaleFactor, -scaleFactor, 0, 0),
2302
- translate(-center.x, -center.y)
2303
- )
2275
+ const newTransform = compose(
2276
+ translate((elmBounds.width ?? 0) / 2, (elmBounds.height ?? 0) / 2),
2277
+ scale(scaleFactor, -scaleFactor, 0, 0),
2278
+ translate(-center.x, -center.y)
2304
2279
  );
2280
+ updateTransform(newTransform);
2281
+ }
2282
+ }, [elements, bounds.width, bounds.height, updateTransform]);
2283
+ const handleMouseDown = (0, import_react8.useCallback)((e) => {
2284
+ isDraggingRef.current = true;
2285
+ lastMousePosRef.current = { x: e.clientX, y: e.clientY };
2286
+ }, []);
2287
+ const handleMouseMove = (0, import_react8.useCallback)(
2288
+ (e) => {
2289
+ if (!isDraggingRef.current)
2290
+ return;
2291
+ const dx = e.clientX - lastMousePosRef.current.x;
2292
+ const dy = e.clientY - lastMousePosRef.current.y;
2293
+ lastMousePosRef.current = { x: e.clientX, y: e.clientY };
2294
+ const scale2 = transformRef.current.a;
2295
+ const dragSensitivity = 150 / scale2;
2296
+ const newTransform = compose(
2297
+ translate(dx * dragSensitivity, dy * dragSensitivity),
2298
+ transformRef.current
2299
+ );
2300
+ updateTransform(newTransform);
2305
2301
  },
2306
- [setElements, setTransform]
2302
+ [updateTransform]
2307
2303
  );
2308
- (0, import_react9.useEffect)(() => {
2309
- if (initialSoup.length > 0) {
2310
- setElementsAndCamera(initialSoup);
2311
- return;
2312
- }
2313
- const projectBuilder = (0, import_builder3.createProjectBuilder)();
2314
- (import_react_fiber.createRoot ?? import_react_fiber.default.createRoot)().render(children, projectBuilder).then(async (elements2) => {
2315
- if (_soupPostProcessor) {
2316
- elements2 = _soupPostProcessor(elements2);
2304
+ const handleMouseUp = (0, import_react8.useCallback)(() => {
2305
+ isDraggingRef.current = false;
2306
+ }, []);
2307
+ const handleWheel = (0, import_react8.useCallback)(
2308
+ (e) => {
2309
+ e.preventDefault();
2310
+ const scaleMultiplier = Math.pow(0.999, e.deltaY);
2311
+ if (containerRef.current) {
2312
+ const rect = containerRef.current.getBoundingClientRect();
2313
+ const mouseX = e.clientX - rect.left;
2314
+ const mouseY = e.clientY - rect.top;
2315
+ const inverseTransform = inverse(transformRef.current);
2316
+ const transformedPoint = applyToPoint(inverseTransform, {
2317
+ x: mouseX,
2318
+ y: mouseY
2319
+ });
2320
+ const newTransform = compose(
2321
+ transformRef.current,
2322
+ translate(transformedPoint.x, transformedPoint.y),
2323
+ scale(scaleMultiplier, scaleMultiplier),
2324
+ translate(-transformedPoint.x, -transformedPoint.y)
2325
+ );
2326
+ updateTransform(newTransform);
2317
2327
  }
2318
- setElementsAndCamera(elements2);
2319
- }).catch((e) => {
2320
- console.error("ERROR RENDERING CIRCUIT");
2321
- throw e;
2322
- });
2323
- }, [children]);
2324
- return /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(import_jsx_runtime23.Fragment, { children: [
2325
- /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)(
2328
+ },
2329
+ [updateTransform]
2330
+ );
2331
+ (0, import_react8.useEffect)(() => {
2332
+ const container = containerRef.current;
2333
+ if (container) {
2334
+ container.addEventListener("wheel", handleWheel, { passive: false });
2335
+ return () => {
2336
+ container.removeEventListener("wheel", handleWheel);
2337
+ };
2338
+ }
2339
+ }, [handleWheel]);
2340
+ if (errorFromChildren) {
2341
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)("div", { children: [
2342
+ "Error: ",
2343
+ errorFromChildren.message
2344
+ ] });
2345
+ }
2346
+ return /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
2347
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(
2326
2348
  "div",
2327
2349
  {
2328
2350
  style: {
@@ -2332,15 +2354,19 @@ var SchematicWithoutContext = ({
2332
2354
  overflow: "hidden",
2333
2355
  position: "relative",
2334
2356
  isolation: "isolate",
2335
- cursor: "grab",
2357
+ cursor: isDraggingRef.current ? "grabbing" : "grab",
2336
2358
  ...style
2337
2359
  },
2338
2360
  ref: (el) => {
2339
- ref.current = el;
2361
+ containerRef.current = el;
2340
2362
  boundsRef(el);
2341
2363
  },
2364
+ onMouseDown: handleMouseDown,
2365
+ onMouseMove: handleMouseMove,
2366
+ onMouseUp: handleMouseUp,
2367
+ onMouseLeave: handleMouseUp,
2342
2368
  children: [
2343
- /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2369
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2344
2370
  import_react_supergrid.SuperGrid,
2345
2371
  {
2346
2372
  stringifyCoord: (x, y, z) => {
@@ -2350,10 +2376,10 @@ var SchematicWithoutContext = ({
2350
2376
  },
2351
2377
  width: bounds.width,
2352
2378
  height: bounds.height,
2353
- transform: cameraTransform
2379
+ transform: transformRef.current
2354
2380
  }
2355
2381
  ),
2356
- elements?.map((elm, i) => /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(ErrorBoundary, { fallbackRender: fallbackRender(elm), children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
2382
+ elements?.map((elm, i) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ErrorBoundary, { fallbackRender: fallbackRender(elm), children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2357
2383
  SchematicElement,
2358
2384
  {
2359
2385
  element: elm,
@@ -2364,7 +2390,7 @@ var SchematicWithoutContext = ({
2364
2390
  ]
2365
2391
  }
2366
2392
  ),
2367
- showTable !== false && elements && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(TableViewer, { elements })
2393
+ showTable !== false && elements && /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(TableViewer, { elements })
2368
2394
  ] });
2369
2395
  };
2370
2396
  // Annotate the CommonJS export names for ESM import in node: