@isothrum/editor 0.0.0-stage → 0.1.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 (293) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +8 -0
  3. package/PUBLISHING.md +93 -0
  4. package/README.md +106 -2
  5. package/desktop-editor/editor.css +11 -0
  6. package/desktop-editor/index.html +14 -0
  7. package/desktop-editor/main.tsx +26 -0
  8. package/dist/desktop/editor.css +1 -0
  9. package/dist/desktop/editor.js +181 -0
  10. package/dist/desktop/fonts/geist-cyrillic-ext-wght-normal-RO72NYA2.woff2 +0 -0
  11. package/dist/desktop/fonts/geist-cyrillic-wght-normal-CK2XY27K.woff2 +0 -0
  12. package/dist/desktop/fonts/geist-latin-ext-wght-normal-XEQ56JUF.woff2 +0 -0
  13. package/dist/desktop/fonts/geist-latin-wght-normal-T72VVCUW.woff2 +0 -0
  14. package/dist/desktop/fonts/geist-mono-cyrillic-ext-wght-normal-QXKVIKFD.woff2 +0 -0
  15. package/dist/desktop/fonts/geist-mono-cyrillic-wght-normal-GOIAQAGU.woff2 +0 -0
  16. package/dist/desktop/fonts/geist-mono-latin-ext-wght-normal-HU3ZAWN6.woff2 +0 -0
  17. package/dist/desktop/fonts/geist-mono-latin-wght-normal-CJNQKXUG.woff2 +0 -0
  18. package/dist/desktop/fonts/geist-mono-symbols2-wght-normal-WZJJVLQO.woff2 +0 -0
  19. package/dist/desktop/fonts/geist-mono-vietnamese-wght-normal-KW5NM6YV.woff2 +0 -0
  20. package/dist/desktop/fonts/geist-vietnamese-wght-normal-Y2R7JZKV.woff2 +0 -0
  21. package/dist/desktop/fonts/shantell-sans-cyrillic-ext-wght-normal-ILPQWRJJ.woff2 +0 -0
  22. package/dist/desktop/fonts/shantell-sans-cyrillic-wght-normal-RKC6NDPM.woff2 +0 -0
  23. package/dist/desktop/fonts/shantell-sans-latin-ext-wght-normal-SNKHG3LM.woff2 +0 -0
  24. package/dist/desktop/fonts/shantell-sans-latin-wght-normal-7CHHGC3N.woff2 +0 -0
  25. package/dist/desktop/fonts/shantell-sans-vietnamese-wght-normal-IPFAQSBA.woff2 +0 -0
  26. package/dist/desktop/index.html +14 -0
  27. package/dist/desktop/styles.css +2 -0
  28. package/dist/desktop/wasm/isothrum_wasm.d.ts +60 -0
  29. package/dist/desktop/wasm/isothrum_wasm.js +312 -0
  30. package/dist/desktop/wasm/isothrum_wasm_bg.wasm +0 -0
  31. package/dist/index.js +7059 -0
  32. package/dist/index.js.map +7 -0
  33. package/dist/model.js +745 -0
  34. package/dist/model.js.map +7 -0
  35. package/dist/types/components/tool/canvas/cable-edge.d.ts +4 -0
  36. package/dist/types/components/tool/canvas/contexts.d.ts +12 -0
  37. package/dist/types/components/tool/canvas/device-icon.d.ts +17 -0
  38. package/dist/types/components/tool/canvas/inline-text.d.ts +15 -0
  39. package/dist/types/components/tool/canvas/lan-node.d.ts +8 -0
  40. package/dist/types/components/tool/canvas/machine-addresses.d.ts +14 -0
  41. package/dist/types/components/tool/canvas/machine-node.d.ts +4 -0
  42. package/dist/types/components/tool/canvas/note-node.d.ts +7 -0
  43. package/dist/types/components/tool/canvas/port-led.d.ts +10 -0
  44. package/dist/types/components/tool/canvas/router-node.d.ts +8 -0
  45. package/dist/types/components/tool/canvas/sketch.d.ts +50 -0
  46. package/dist/types/components/tool/canvas/status-dot.d.ts +5 -0
  47. package/dist/types/components/tool/canvas/switch-node.d.ts +8 -0
  48. package/dist/types/components/tool/canvas/use-measured-ports.d.ts +7 -0
  49. package/dist/types/components/tool/context-menus.d.ts +5 -0
  50. package/dist/types/components/tool/device-block.d.ts +12 -0
  51. package/dist/types/components/tool/editor-menu.d.ts +28 -0
  52. package/dist/types/components/tool/export/copy-button.d.ts +9 -0
  53. package/dist/types/components/tool/export/export-panel.d.ts +17 -0
  54. package/dist/types/components/tool/export/target-list.d.ts +15 -0
  55. package/dist/types/components/tool/floating-window.d.ts +13 -0
  56. package/dist/types/components/tool/flow-canvas.d.ts +6 -0
  57. package/dist/types/components/tool/hooks/use-cabling.d.ts +23 -0
  58. package/dist/types/components/tool/hooks/use-captures.d.ts +9 -0
  59. package/dist/types/components/tool/hooks/use-clipboard.d.ts +12 -0
  60. package/dist/types/components/tool/hooks/use-context-menus.d.ts +25 -0
  61. package/dist/types/components/tool/hooks/use-design.d.ts +10 -0
  62. package/dist/types/components/tool/hooks/use-desktop.d.ts +50 -0
  63. package/dist/types/components/tool/hooks/use-devices.d.ts +17 -0
  64. package/dist/types/components/tool/hooks/use-downloads.d.ts +9 -0
  65. package/dist/types/components/tool/hooks/use-editor.d.ts +609 -0
  66. package/dist/types/components/tool/hooks/use-engine.d.ts +9 -0
  67. package/dist/types/components/tool/hooks/use-history.d.ts +9 -0
  68. package/dist/types/components/tool/hooks/use-lab-actions.d.ts +25 -0
  69. package/dist/types/components/tool/hooks/use-lab-run.d.ts +25 -0
  70. package/dist/types/components/tool/hooks/use-lab.d.ts +18 -0
  71. package/dist/types/components/tool/hooks/use-lan-carry.d.ts +8 -0
  72. package/dist/types/components/tool/hooks/use-machine-actions.d.ts +26 -0
  73. package/dist/types/components/tool/hooks/use-placement.d.ts +27 -0
  74. package/dist/types/components/tool/hooks/use-project.d.ts +25 -0
  75. package/dist/types/components/tool/hooks/use-projects.d.ts +34 -0
  76. package/dist/types/components/tool/hooks/use-shared-link.d.ts +23 -0
  77. package/dist/types/components/tool/hooks/use-toast.d.ts +2 -0
  78. package/dist/types/components/tool/hooks/use-tools.d.ts +17 -0
  79. package/dist/types/components/tool/lab-canvas.d.ts +18 -0
  80. package/dist/types/components/tool/overlays.d.ts +5 -0
  81. package/dist/types/components/tool/projects-list.d.ts +9 -0
  82. package/dist/types/components/tool/text.d.ts +418 -0
  83. package/dist/types/components/tool/toolbar.d.ts +5 -0
  84. package/dist/types/components/tool/top-bars.d.ts +10 -0
  85. package/dist/types/components/tool/windows/conditions-fields.d.ts +6 -0
  86. package/dist/types/components/tool/windows/editor-windows.d.ts +5 -0
  87. package/dist/types/components/tool/windows/fields.d.ts +4 -0
  88. package/dist/types/components/tool/windows/lab-status.d.ts +6 -0
  89. package/dist/types/components/tool/windows/lab-windows.d.ts +13 -0
  90. package/dist/types/components/tool/windows/link-controls.d.ts +21 -0
  91. package/dist/types/components/tool/windows/machine-controls.d.ts +16 -0
  92. package/dist/types/components/tool/windows/machine-inspector.d.ts +11 -0
  93. package/dist/types/components/tool/windows/runs-fields.d.ts +18 -0
  94. package/dist/types/components/tool/windows/selected-windows.d.ts +21 -0
  95. package/dist/types/components/ui/button.d.ts +8 -0
  96. package/dist/types/components/ui/dropdown-menu.d.ts +21 -0
  97. package/dist/types/index.d.ts +7 -0
  98. package/dist/types/lib/auth.d.ts +38 -0
  99. package/dist/types/lib/brand.d.ts +19 -0
  100. package/dist/types/lib/i18n.d.ts +19 -0
  101. package/dist/types/lib/tool/blocks.d.ts +35 -0
  102. package/dist/types/lib/tool/cables.d.ts +48 -0
  103. package/dist/types/lib/tool/clone.d.ts +12 -0
  104. package/dist/types/lib/tool/conditions.d.ts +31 -0
  105. package/dist/types/lib/tool/create.d.ts +22 -0
  106. package/dist/types/lib/tool/desktop.d.ts +63 -0
  107. package/dist/types/lib/tool/draft.d.ts +20 -0
  108. package/dist/types/lib/tool/engine.d.ts +33 -0
  109. package/dist/types/lib/tool/examples.d.ts +11 -0
  110. package/dist/types/lib/tool/export-targets.d.ts +21 -0
  111. package/dist/types/lib/tool/facing.d.ts +9 -0
  112. package/dist/types/lib/tool/geometry.d.ts +36 -0
  113. package/dist/types/lib/tool/gns3-cables.d.ts +17 -0
  114. package/dist/types/lib/tool/gns3-import.d.ts +15 -0
  115. package/dist/types/lib/tool/gns3-parts.d.ts +25 -0
  116. package/dist/types/lib/tool/issues.d.ts +12 -0
  117. package/dist/types/lib/tool/layout.d.ts +52 -0
  118. package/dist/types/lib/tool/live.d.ts +21 -0
  119. package/dist/types/lib/tool/logos.d.ts +7 -0
  120. package/dist/types/lib/tool/model.d.ts +173 -0
  121. package/dist/types/lib/tool/os.d.ts +20 -0
  122. package/dist/types/lib/tool/pins.d.ts +5 -0
  123. package/dist/types/lib/tool/placement.d.ts +21 -0
  124. package/dist/types/lib/tool/ports.d.ts +21 -0
  125. package/dist/types/lib/tool/presets.d.ts +21 -0
  126. package/dist/types/lib/tool/projects-api.d.ts +37 -0
  127. package/dist/types/lib/tool/router-ports.d.ts +22 -0
  128. package/dist/types/lib/tool/selection.d.ts +19 -0
  129. package/dist/types/lib/tool/storage.d.ts +25 -0
  130. package/dist/types/lib/tool/switch-edit.d.ts +17 -0
  131. package/dist/types/lib/tool/text/de.d.ts +2 -0
  132. package/dist/types/lib/tool/text/en.d.ts +429 -0
  133. package/dist/types/lib/tool/text/es.d.ts +2 -0
  134. package/dist/types/lib/tool/text/fr.d.ts +2 -0
  135. package/dist/types/lib/tool/text/index.d.ts +419 -0
  136. package/dist/types/lib/tool/topology.d.ts +2 -0
  137. package/dist/types/lib/tool/vlans.d.ts +24 -0
  138. package/dist/types/lib/utils.d.ts +2 -0
  139. package/dist/types/model.d.ts +13 -0
  140. package/package.json +88 -4
  141. package/scripts/build-desktop-editor.mjs +43 -0
  142. package/scripts/build-lib.mjs +38 -0
  143. package/src/components/tool/canvas/cable-edge.tsx +112 -0
  144. package/src/components/tool/canvas/contexts.ts +18 -0
  145. package/src/components/tool/canvas/device-icon.tsx +105 -0
  146. package/src/components/tool/canvas/inline-text.tsx +69 -0
  147. package/src/components/tool/canvas/lan-node.tsx +148 -0
  148. package/src/components/tool/canvas/machine-addresses.tsx +117 -0
  149. package/src/components/tool/canvas/machine-node.tsx +114 -0
  150. package/src/components/tool/canvas/note-node.tsx +109 -0
  151. package/src/components/tool/canvas/port-led.tsx +21 -0
  152. package/src/components/tool/canvas/router-node.tsx +114 -0
  153. package/src/components/tool/canvas/sketch.tsx +130 -0
  154. package/src/components/tool/canvas/status-dot.tsx +29 -0
  155. package/src/components/tool/canvas/switch-node.tsx +143 -0
  156. package/src/components/tool/canvas/use-measured-ports.ts +25 -0
  157. package/src/components/tool/context-menus.tsx +142 -0
  158. package/src/components/tool/device-block.tsx +107 -0
  159. package/src/components/tool/editor-menu.tsx +191 -0
  160. package/src/components/tool/export/copy-button.tsx +45 -0
  161. package/src/components/tool/export/export-panel.tsx +127 -0
  162. package/src/components/tool/export/target-list.tsx +87 -0
  163. package/src/components/tool/floating-window.tsx +69 -0
  164. package/src/components/tool/flow-canvas.tsx +138 -0
  165. package/src/components/tool/hooks/use-cabling.ts +66 -0
  166. package/src/components/tool/hooks/use-captures.ts +24 -0
  167. package/src/components/tool/hooks/use-clipboard.ts +54 -0
  168. package/src/components/tool/hooks/use-context-menus.ts +37 -0
  169. package/src/components/tool/hooks/use-design.ts +24 -0
  170. package/src/components/tool/hooks/use-desktop.ts +100 -0
  171. package/src/components/tool/hooks/use-devices.ts +58 -0
  172. package/src/components/tool/hooks/use-downloads.ts +42 -0
  173. package/src/components/tool/hooks/use-editor.ts +114 -0
  174. package/src/components/tool/hooks/use-engine.ts +29 -0
  175. package/src/components/tool/hooks/use-history.ts +107 -0
  176. package/src/components/tool/hooks/use-lab-actions.ts +57 -0
  177. package/src/components/tool/hooks/use-lab-run.ts +61 -0
  178. package/src/components/tool/hooks/use-lab.ts +32 -0
  179. package/src/components/tool/hooks/use-lan-carry.ts +43 -0
  180. package/src/components/tool/hooks/use-machine-actions.ts +57 -0
  181. package/src/components/tool/hooks/use-placement.ts +80 -0
  182. package/src/components/tool/hooks/use-project.ts +112 -0
  183. package/src/components/tool/hooks/use-projects.ts +85 -0
  184. package/src/components/tool/hooks/use-shared-link.ts +64 -0
  185. package/src/components/tool/hooks/use-toast.ts +16 -0
  186. package/src/components/tool/hooks/use-tools.ts +60 -0
  187. package/src/components/tool/lab-canvas.tsx +96 -0
  188. package/src/components/tool/overlays.tsx +104 -0
  189. package/src/components/tool/projects-list.tsx +96 -0
  190. package/src/components/tool/text.ts +9 -0
  191. package/src/components/tool/toolbar.tsx +106 -0
  192. package/src/components/tool/top-bars.tsx +90 -0
  193. package/src/components/tool/windows/conditions-fields.tsx +43 -0
  194. package/src/components/tool/windows/editor-windows.tsx +73 -0
  195. package/src/components/tool/windows/fields.ts +6 -0
  196. package/src/components/tool/windows/lab-status.tsx +68 -0
  197. package/src/components/tool/windows/lab-windows.tsx +130 -0
  198. package/src/components/tool/windows/link-controls.tsx +69 -0
  199. package/src/components/tool/windows/machine-controls.tsx +116 -0
  200. package/src/components/tool/windows/machine-inspector.tsx +83 -0
  201. package/src/components/tool/windows/runs-fields.tsx +127 -0
  202. package/src/components/tool/windows/selected-windows.tsx +147 -0
  203. package/src/components/ui/button.tsx +59 -0
  204. package/src/components/ui/dropdown-menu.tsx +185 -0
  205. package/src/index.ts +21 -0
  206. package/src/lib/auth.tsx +43 -0
  207. package/src/lib/brand.tsx +46 -0
  208. package/src/lib/i18n.ts +53 -0
  209. package/src/lib/tool/blocks.test.ts +64 -0
  210. package/src/lib/tool/blocks.ts +78 -0
  211. package/src/lib/tool/cable-wiring.test.ts +74 -0
  212. package/src/lib/tool/cables.test.ts +75 -0
  213. package/src/lib/tool/cables.ts +215 -0
  214. package/src/lib/tool/clone.test.ts +54 -0
  215. package/src/lib/tool/clone.ts +48 -0
  216. package/src/lib/tool/conditions.test.ts +170 -0
  217. package/src/lib/tool/conditions.ts +132 -0
  218. package/src/lib/tool/create.test.ts +67 -0
  219. package/src/lib/tool/create.ts +83 -0
  220. package/src/lib/tool/desktop.test.ts +59 -0
  221. package/src/lib/tool/desktop.ts +99 -0
  222. package/src/lib/tool/draft.test.ts +150 -0
  223. package/src/lib/tool/draft.ts +109 -0
  224. package/src/lib/tool/engine.test.ts +39 -0
  225. package/src/lib/tool/engine.ts +58 -0
  226. package/src/lib/tool/examples.test.ts +35 -0
  227. package/src/lib/tool/examples.ts +71 -0
  228. package/src/lib/tool/export-targets.test.ts +47 -0
  229. package/src/lib/tool/export-targets.ts +84 -0
  230. package/src/lib/tool/facing.test.ts +72 -0
  231. package/src/lib/tool/facing.ts +100 -0
  232. package/src/lib/tool/geometry.test.ts +80 -0
  233. package/src/lib/tool/geometry.ts +109 -0
  234. package/src/lib/tool/gns3-cables.test.ts +47 -0
  235. package/src/lib/tool/gns3-cables.ts +81 -0
  236. package/src/lib/tool/gns3-import.test.ts +102 -0
  237. package/src/lib/tool/gns3-import.ts +198 -0
  238. package/src/lib/tool/gns3-layout.test.ts +62 -0
  239. package/src/lib/tool/gns3-parts.test.ts +47 -0
  240. package/src/lib/tool/gns3-parts.ts +68 -0
  241. package/src/lib/tool/issues.test.ts +35 -0
  242. package/src/lib/tool/issues.ts +60 -0
  243. package/src/lib/tool/layout.test.ts +128 -0
  244. package/src/lib/tool/layout.ts +229 -0
  245. package/src/lib/tool/live.test.ts +46 -0
  246. package/src/lib/tool/live.ts +49 -0
  247. package/src/lib/tool/logos.test.ts +30 -0
  248. package/src/lib/tool/logos.ts +99 -0
  249. package/src/lib/tool/model.test.ts +128 -0
  250. package/src/lib/tool/model.ts +238 -0
  251. package/src/lib/tool/os.test.ts +45 -0
  252. package/src/lib/tool/os.ts +57 -0
  253. package/src/lib/tool/parity.test.ts +145 -0
  254. package/src/lib/tool/pins.test.ts +24 -0
  255. package/src/lib/tool/pins.ts +11 -0
  256. package/src/lib/tool/placement.test.ts +79 -0
  257. package/src/lib/tool/placement.ts +60 -0
  258. package/src/lib/tool/ports.test.ts +39 -0
  259. package/src/lib/tool/ports.ts +48 -0
  260. package/src/lib/tool/presets.test.ts +50 -0
  261. package/src/lib/tool/presets.ts +77 -0
  262. package/src/lib/tool/projects-api.test.ts +59 -0
  263. package/src/lib/tool/projects-api.ts +47 -0
  264. package/src/lib/tool/router-ports.test.ts +63 -0
  265. package/src/lib/tool/router-ports.ts +88 -0
  266. package/src/lib/tool/selection.test.ts +44 -0
  267. package/src/lib/tool/selection.ts +34 -0
  268. package/src/lib/tool/storage.test.ts +123 -0
  269. package/src/lib/tool/storage.ts +127 -0
  270. package/src/lib/tool/switch-edit.test.ts +49 -0
  271. package/src/lib/tool/switch-edit.ts +38 -0
  272. package/src/lib/tool/text/de.ts +358 -0
  273. package/src/lib/tool/text/en.ts +371 -0
  274. package/src/lib/tool/text/es.ts +358 -0
  275. package/src/lib/tool/text/fr.ts +358 -0
  276. package/src/lib/tool/text/index.ts +21 -0
  277. package/src/lib/tool/text/text.test.ts +33 -0
  278. package/src/lib/tool/topology.test.ts +108 -0
  279. package/src/lib/tool/topology.ts +116 -0
  280. package/src/lib/tool/vlans.test.ts +64 -0
  281. package/src/lib/tool/vlans.ts +79 -0
  282. package/src/lib/utils.ts +6 -0
  283. package/src/model.ts +13 -0
  284. package/src/test/arbitrary.ts +41 -0
  285. package/src/test/engine.ts +48 -0
  286. package/src/test/lab.ts +101 -0
  287. package/styles/globals.css +258 -0
  288. package/styles/theme.css +192 -0
  289. package/tsconfig.build.json +12 -0
  290. package/tsconfig.json +22 -0
  291. package/wasm/isothrum_wasm.d.ts +60 -0
  292. package/wasm/isothrum_wasm.js +312 -0
  293. package/wasm/isothrum_wasm_bg.wasm +0 -0
@@ -0,0 +1,18 @@
1
+ import type { CableEdge, Draft, LabNode } from "../../../lib/tool/model.js";
2
+ /** The lab on the canvas: its name, nodes and cables, kept in this browser as it changes. */
3
+ export declare function useLab(): {
4
+ initial: Draft;
5
+ labName: string;
6
+ setLabName: import("react").Dispatch<import("react").SetStateAction<string>>;
7
+ nodes: LabNode[];
8
+ setNodes: import("react").Dispatch<import("react").SetStateAction<LabNode[]>>;
9
+ onNodesChange: import("@xyflow/react").OnNodesChange<LabNode>;
10
+ edges: CableEdge[];
11
+ setEdges: import("react").Dispatch<import("react").SetStateAction<CableEdge[]>>;
12
+ onEdgesChange: import("@xyflow/react").OnEdgesChange<CableEdge>;
13
+ };
14
+ export type Lab = ReturnType<typeof useLab>;
15
+ /** Saves the lab as it changes. */
16
+ export declare function useDraftSaving(lab: Lab): void;
17
+ /** Replaces the whole lab (an example, a shared link, a project, a GNS3 import). */
18
+ export declare function replaceLab(lab: Lab, next: Draft): void;
@@ -0,0 +1,8 @@
1
+ import { type LabNode } from "../../../lib/tool/model.js";
2
+ import type { Lab } from "./use-lab";
3
+ /** Moving a LAN carries the machines inside it, as Excalidraw frames do. */
4
+ export declare function useLanCarry(lab: Lab): {
5
+ onNodeDragStart: (_: unknown, node: LabNode) => void;
6
+ onNodeDrag: (_: unknown, node: LabNode) => void;
7
+ onNodeDragStop: () => void;
8
+ };
@@ -0,0 +1,26 @@
1
+ import type { Invoke } from "../../../lib/tool/desktop.js";
2
+ import type { EditorText } from "../../../lib/tool/text/index.js";
3
+ import type { LiveLab } from "./use-desktop";
4
+ export type MachineAction = "start" | "stop" | "restart";
5
+ export type LinkAction = "suspend" | "resume";
6
+ interface Deps {
7
+ invoke: Invoke | null;
8
+ labName: string;
9
+ live: LiveLab;
10
+ setToast: (message: string) => void;
11
+ t: EditorText;
12
+ }
13
+ /**
14
+ * One machine of the running lab (desktop): a console, its screen, starting or stopping it, its
15
+ * snapshots, and cutting or reconnecting its links. A failure shows as a toast.
16
+ */
17
+ export declare function useMachineActions({ invoke, labName, live, setToast, t }: Deps): {
18
+ busy: boolean;
19
+ snapshotDo: (command: string, args: Record<string, unknown>) => Promise<void>;
20
+ machineAct: (machine: string, action: MachineAction) => Promise<void>;
21
+ /** Cuts or reconnects the ports of `machines` on `network` (every machine's, when not named). */
22
+ linkAct: (network: string, machines: string[] | undefined, action: LinkAction) => Promise<void>;
23
+ machineConsole: (machine: string) => Promise<void>;
24
+ machineDisplay: (machine: string) => Promise<void>;
25
+ };
26
+ export {};
@@ -0,0 +1,27 @@
1
+ import type { DragEvent, MouseEvent, RefObject } from "react";
2
+ import type { XYPosition } from "@xyflow/react";
3
+ import { type LabNode, type LanNode } from "../../../lib/tool/model.js";
4
+ import type { Preset } from "../../../lib/tool/presets.js";
5
+ import type { Lab } from "./use-lab";
6
+ import type { Tools } from "./use-tools";
7
+ /** The drag-and-drop type of a device dragged from the toolbar. */
8
+ export declare const PRESET_MIME = "application/x-isothrum-preset";
9
+ interface Deps {
10
+ lab: Lab;
11
+ lans: LanNode[];
12
+ tools: Tools;
13
+ presets: Preset[];
14
+ canvasRef: RefObject<HTMLDivElement | null>;
15
+ screenToFlowPosition: (p: XYPosition) => XYPosition;
16
+ /** Closes the right-click menus (a click on the canvas does). */
17
+ closeMenus: () => void;
18
+ /** Opens a dropped GNS3 project. */
19
+ importGns3: (file: File) => void;
20
+ }
21
+ /** Placing devices, LANs, switches and notes: by a click on the canvas with a tool, or a drop. */
22
+ export declare function usePlacement({ lab, lans, tools, presets, canvasRef, screenToFlowPosition, closeMenus, importGns3 }: Deps): {
23
+ onPaneClick: (e: MouseEvent) => void;
24
+ onNodeClick: (e: MouseEvent, node: LabNode) => void;
25
+ onDrop: (e: DragEvent) => void;
26
+ };
27
+ export {};
@@ -0,0 +1,25 @@
1
+ import type { Draft } from "../../../lib/tool/model.js";
2
+ import { type ProjectRef } from "../../../lib/tool/storage.js";
3
+ /**
4
+ * Saved projects (isoloom/isothrum#31): the lab on the signed-in user's account. Once a lab is
5
+ * saved as a project, every change saves itself (a moment after the last one); each save keeps
6
+ * the previous version. The browser draft stays the working copy, signed in or not.
7
+ */
8
+ export type SaveState = "idle" | "saving" | "saved" | "error";
9
+ interface Deps {
10
+ signedIn: boolean;
11
+ /** The lab as it is now (its identity changes on every edit). */
12
+ draft: Draft;
13
+ /** The isoloom.yml the engine generated for it. */
14
+ yml: string | null;
15
+ }
16
+ /** The project the editor is attached to, and saving it. */
17
+ export declare function useProject({ signedIn, draft, yml }: Deps): {
18
+ project: ProjectRef | null;
19
+ state: SaveState;
20
+ save: (asNew?: boolean, name?: string) => Promise<ProjectRef | null>;
21
+ detach: () => void;
22
+ /** After opening a project: attached to it, nothing to save yet. */
23
+ opened: (p: ProjectRef, d: Draft) => void;
24
+ };
25
+ export {};
@@ -0,0 +1,34 @@
1
+ import type { Design, Draft } from "../../../lib/tool/model.js";
2
+ import type { Plan } from "../../../lib/tool/engine.js";
3
+ import type { ProjectRef } from "../../../lib/tool/storage.js";
4
+ import type { EditorText } from "../../../lib/tool/text/index.js";
5
+ import { type Lab } from "./use-lab";
6
+ interface Deps {
7
+ /** Accounts are on (the desktop's bundled editor has no site to ask). */
8
+ accounts: boolean;
9
+ lab: Lab;
10
+ design: Design;
11
+ setDesign: (d: Design) => void;
12
+ plan: Plan | null;
13
+ setToast: (message: string) => void;
14
+ fitWhenDrawn: () => void;
15
+ t: EditorText;
16
+ }
17
+ /** Saved projects, for a signed-in user (see `useProject`): opening, saving, Ctrl/⌘ S. */
18
+ export declare function useProjects({ accounts, lab, design, setDesign, plan, setToast, fitWhenDrawn, t }: Deps): {
19
+ signedIn: boolean;
20
+ setSignedInNow: import("react").Dispatch<import("react").SetStateAction<boolean>>;
21
+ proj: {
22
+ project: ProjectRef | null;
23
+ state: import("./use-project").SaveState;
24
+ save: (asNew?: boolean, name?: string) => Promise<ProjectRef | null>;
25
+ detach: () => void;
26
+ opened: (p: ProjectRef, d: Draft) => void;
27
+ };
28
+ projectsOpen: boolean;
29
+ setProjectsOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
30
+ openDraft: (d: Draft) => void;
31
+ openProject: (p: ProjectRef, d: Draft) => void;
32
+ saveAs: () => Promise<void>;
33
+ };
34
+ export {};
@@ -0,0 +1,23 @@
1
+ import { encodeLab } from "../../../lib/tool/draft.js";
2
+ import type { Design } from "../../../lib/tool/model.js";
3
+ import type { EditorText } from "../../../lib/tool/text/index.js";
4
+ import { type Lab } from "./use-lab";
5
+ /** Removes the `#…` part of the address once it has been read. */
6
+ export declare function clearHash(): void;
7
+ interface Deps {
8
+ lab: Lab;
9
+ setDesign: (d: Design) => void;
10
+ setToast: (message: string) => void;
11
+ /** Fits the view once React Flow has measured the new lab. */
12
+ fitWhenDrawn: () => void;
13
+ t: EditorText;
14
+ }
15
+ /**
16
+ * A shared lab (#lab=… in the address) opens on arrival, and when a link is pasted into a tab
17
+ * already on the editor (only the part after # changes then, and the browser doesn't reload).
18
+ * Undo brings back what was there.
19
+ */
20
+ export declare function useSharedLink({ lab, setDesign, setToast, fitWhenDrawn, t }: Deps): void;
21
+ /** Copies a link that opens this lab (its JSON, deflated, after `#lab=`). */
22
+ export declare function copyShareLink(draft: Parameters<typeof encodeLab>[0], lang: string, setToast: (message: string) => void, t: EditorText): Promise<void>;
23
+ export {};
@@ -0,0 +1,2 @@
1
+ /** A message at the bottom of the canvas, for a few seconds (longer when it is long). */
2
+ export declare function useToast(): [string | null, (message: string | null) => void];
@@ -0,0 +1,17 @@
1
+ /** Excalidraw's two modes: select (drag a box, Shift-click, Delete) or hand (drag moves the canvas). */
2
+ export type Mode = "select" | "hand";
3
+ /**
4
+ * The device being placed (Excalidraw-style tool): the next click on the canvas drops it there.
5
+ * Picking a tool selects again; picking the same one twice puts it down.
6
+ */
7
+ export declare function useTools(): {
8
+ activeTool: string | null;
9
+ setActiveTool: import("react").Dispatch<import("react").SetStateAction<string | null>>;
10
+ mode: Mode;
11
+ setMode: import("react").Dispatch<import("react").SetStateAction<Mode>>;
12
+ pick: (tool: string) => void;
13
+ setModeOnly: (m: Mode) => void;
14
+ };
15
+ export type Tools = ReturnType<typeof useTools>;
16
+ /** Keyboard: 1–9 and 0 pick a device, S, L, T a switch, LAN or note, V selects, H the hand, Escape puts it down. Not while typing in a field. */
17
+ export declare function useToolKeys(tools: Tools): void;
@@ -0,0 +1,18 @@
1
+ import { type AuthClient } from "../../lib/auth.js";
2
+ import { type BrandMark } from "../../lib/brand.js";
3
+ /** The props of the lab editor. */
4
+ export interface LabCanvasProps {
5
+ /** The editor's language (one of the editor's locales); anything else falls back to English. */
6
+ lang: string;
7
+ /**
8
+ * Whether the accounts UI (sign in, save to projects) is shown. When `true`, pass `auth`.
9
+ * Defaults to `false`, for hosts without accounts (the desktop app, a standalone embed).
10
+ */
11
+ accounts?: boolean;
12
+ /** The host's auth client, required when `accounts` is `true`; ignored otherwise. */
13
+ auth?: AuthClient | null;
14
+ /** A product mark for the empty canvas; defaults to the Isothrum mark. */
15
+ brandMark?: BrandMark;
16
+ }
17
+ /** The lab editor: the editor's words in the page's language, for every part of it (windows, canvas, export). */
18
+ export declare function LabCanvas({ lang, accounts, auth, brandMark }: LabCanvasProps): import("react").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import type { EditorModel } from "./hooks/use-editor";
2
+ /** What floats over the canvas's bottom: the welcome, an update, a toast, an engine that didn't load. */
3
+ export declare function Overlays({ e }: {
4
+ e: EditorModel;
5
+ }): import("react").JSX.Element;
@@ -0,0 +1,9 @@
1
+ import type { Draft } from "../../lib/tool/model.js";
2
+ import type { ProjectRef } from "../../lib/tool/storage.js";
3
+ /** The user's projects, to open or delete one; and the open project's earlier versions. */
4
+ export declare function ProjectsList({ current, onOpen, onOpenVersion, onDeleted }: {
5
+ current: ProjectRef | null;
6
+ onOpen: (p: ProjectRef, draft: Draft) => void;
7
+ onOpenVersion: (draft: Draft) => void;
8
+ onDeleted: (id: string) => void;
9
+ }): import("react").JSX.Element;
@@ -0,0 +1,418 @@
1
+ import { type EditorText } from "../../lib/tool/text/index.js";
2
+ /** The editor's words, set once by the editor from the page's language; English outside it. */
3
+ export declare const EditorTextContext: import("react").Context<{
4
+ toolbar: {
5
+ blocks: {
6
+ switch: string;
7
+ router: string;
8
+ firewall: string;
9
+ container: string;
10
+ vm: string;
11
+ mine: string;
12
+ };
13
+ kindsOf: (block: string) => string;
14
+ devices: string;
15
+ hand: string;
16
+ select: string;
17
+ lan: string;
18
+ lanTitle: string;
19
+ switch: string;
20
+ switchTitle: string;
21
+ note: string;
22
+ noteTitle: string;
23
+ forget: (device: string) => string;
24
+ forgetLabel: (device: string) => string;
25
+ undo: string;
26
+ undoTitle: string;
27
+ redo: string;
28
+ redoTitle: string;
29
+ };
30
+ hints: {
31
+ lan: string;
32
+ note: string;
33
+ place: (device: string) => string;
34
+ hand: string;
35
+ cable: string;
36
+ select: string;
37
+ };
38
+ devices: {
39
+ router: {
40
+ label: string;
41
+ hint: string;
42
+ };
43
+ "router-frr": {
44
+ label: string;
45
+ hint: string;
46
+ };
47
+ firewall: {
48
+ label: string;
49
+ hint: string;
50
+ };
51
+ container: {
52
+ label: string;
53
+ };
54
+ web: {
55
+ label: string;
56
+ hint: string;
57
+ };
58
+ database: {
59
+ label: string;
60
+ hint: string;
61
+ };
62
+ desktop: {
63
+ label: string;
64
+ hint: string;
65
+ };
66
+ "linux-vm": {
67
+ label: string;
68
+ };
69
+ "ubuntu-vm": {
70
+ label: string;
71
+ };
72
+ "kali-vm": {
73
+ label: string;
74
+ };
75
+ "windows-vm": {
76
+ label: string;
77
+ };
78
+ workstation: {
79
+ label: string;
80
+ hint: string;
81
+ };
82
+ "cisco-iol": {
83
+ label: string;
84
+ hint: string;
85
+ };
86
+ "cisco-iol-l2": {
87
+ label: string;
88
+ hint: string;
89
+ };
90
+ };
91
+ myDevice: (what: string) => string;
92
+ myDeviceRouter: string;
93
+ status: {
94
+ loading: string;
95
+ toFix: (count: number) => string;
96
+ valid: string;
97
+ };
98
+ run: {
99
+ autoStart: string;
100
+ autoStartNote: string;
101
+ statusTitle: (up: number, total: number) => string;
102
+ probed: string;
103
+ inferred: string;
104
+ run: string;
105
+ starting: string;
106
+ stop: string;
107
+ stopping: string;
108
+ vmsTitle: string;
109
+ runVmsTitle: string;
110
+ startingVmsLog: string;
111
+ runTitle: string;
112
+ startingLog: string;
113
+ window: string;
114
+ running: string;
115
+ stopped: string;
116
+ noDocker: string;
117
+ noLiveCapture: (wireshark: boolean, dir: string) => string;
118
+ };
119
+ capture: {
120
+ capturing: (network: string) => string;
121
+ writingTo: string;
122
+ live: string;
123
+ stop: string;
124
+ start: string;
125
+ runFirst: string;
126
+ };
127
+ link: {
128
+ suspend: string;
129
+ resume: string;
130
+ suspendAll: string;
131
+ resumeAll: string;
132
+ cableSuspended: string;
133
+ lanSuspended: (ports: number) => string;
134
+ runFirst: string;
135
+ };
136
+ export: string;
137
+ engineDidntLoad: (error: string) => string;
138
+ engineFailed: (error: string) => string;
139
+ toasts: {
140
+ brokenLink: string;
141
+ openedShared: (lab: string) => string;
142
+ linkCopied: string;
143
+ copyPrompt: string;
144
+ savedDevice: (device: string) => string;
145
+ gns3Opened: (lab: string, machines: number, lans: number) => string;
146
+ undoBringsBack: string;
147
+ gns3Unreadable: string;
148
+ };
149
+ windows: {
150
+ machine: string;
151
+ lan: (lan: string) => string;
152
+ cable: (a: string, b: string) => string;
153
+ portOn: (machine: string) => string;
154
+ cableNote: string;
155
+ removeCable: string;
156
+ conditions: {
157
+ title: string;
158
+ delay: string;
159
+ jitter: string;
160
+ loss: string;
161
+ rate: string;
162
+ hint: string;
163
+ onLan: string;
164
+ onVlan: string;
165
+ };
166
+ selected: (count: number) => string;
167
+ selection: (items: number, cables: number) => string;
168
+ deleteSelection: (count: number) => string;
169
+ close: string;
170
+ };
171
+ lab: {
172
+ title: string;
173
+ containers: string;
174
+ vms: string;
175
+ lans: string;
176
+ cables: string;
177
+ toFix: string;
178
+ valid: string;
179
+ routing: string;
180
+ };
181
+ menu: {
182
+ menu: string;
183
+ example: string;
184
+ vlanExample: string;
185
+ gns3: string;
186
+ gns3File: string;
187
+ share: string;
188
+ fit: string;
189
+ clear: string;
190
+ light: string;
191
+ dark: string;
192
+ style: string;
193
+ styles: {
194
+ sketch: string;
195
+ business: string;
196
+ };
197
+ language: string;
198
+ about: string;
199
+ blog: string;
200
+ };
201
+ welcome: {
202
+ menuHint: string;
203
+ toolbarHint: string;
204
+ pitch: string;
205
+ example: string;
206
+ how: string;
207
+ };
208
+ inspector: {
209
+ name: string;
210
+ runsAs: string;
211
+ automaticRouter: string;
212
+ container: string;
213
+ vm: string;
214
+ routerNote: string;
215
+ image: string;
216
+ keepRunning: string;
217
+ applianceNote: string;
218
+ ciscoOs: string;
219
+ needsKvm: string;
220
+ dynamipsFirmware: (name: string) => string;
221
+ iosConfig: string;
222
+ iosConfigHint: string;
223
+ keepRunningHint: string;
224
+ os: string;
225
+ provision: string;
226
+ ports: string;
227
+ access: string;
228
+ cables: string;
229
+ noCables: string;
230
+ saveTitle: string;
231
+ save: string;
232
+ remove: string;
233
+ };
234
+ canvas: {
235
+ imageShort: string;
236
+ hosts: (n: number) => string;
237
+ roles: {
238
+ router: string;
239
+ firewall: string;
240
+ workstation: string;
241
+ server: string;
242
+ desktop: string;
243
+ host: string;
244
+ };
245
+ switchModel: (ports: number) => string;
246
+ live: {
247
+ up: string;
248
+ starting: string;
249
+ unhealthy: string;
250
+ down: string;
251
+ portUp: string;
252
+ portDown: string;
253
+ portUnknown: string;
254
+ lanPorts: (up: number, total: number) => string;
255
+ cable: {
256
+ up: string;
257
+ cut: string;
258
+ down: string;
259
+ };
260
+ cableShort: {
261
+ cut: string;
262
+ down: string;
263
+ };
264
+ };
265
+ editTitle: (what: string) => string;
266
+ unnamed: string;
267
+ machineName: string;
268
+ vm: string;
269
+ automatic: string;
270
+ container: string;
271
+ access: string;
272
+ addressTitle: (network: string, fixed: boolean) => string;
273
+ fixed: string;
274
+ addressOn: (network: string) => string;
275
+ lanName: string;
276
+ addressBlock: string;
277
+ internetOnTitle: string;
278
+ internetOffTitle: string;
279
+ internetOn: string;
280
+ internetOff: string;
281
+ showAreaTitle: string;
282
+ hideAreaTitle: string;
283
+ showArea: string;
284
+ hideArea: string;
285
+ switchName: string;
286
+ port: (n: number) => string;
287
+ trunkPort: string;
288
+ trunkCarries: (vlans: string) => string;
289
+ noVlan: string;
290
+ clickToChange: string;
291
+ vlanNumber: string;
292
+ vlanBlock: string;
293
+ remove: (what: string) => string;
294
+ routerName: string;
295
+ portFree: (port: string) => string;
296
+ textOnly: string;
297
+ box: string;
298
+ ellipse: string;
299
+ colors: {
300
+ yellow: string;
301
+ red: string;
302
+ blue: string;
303
+ green: string;
304
+ violet: string;
305
+ };
306
+ color: (color: string) => string;
307
+ write: string;
308
+ note: string;
309
+ noteName: string;
310
+ };
311
+ exportPanel: {
312
+ copy: string;
313
+ copied: string;
314
+ labName: string;
315
+ fixFirst: string;
316
+ download: (lab: string) => string;
317
+ onlySpec: string;
318
+ where: string;
319
+ whereIntro: string;
320
+ mixed: string;
321
+ install: string;
322
+ files: (count: number) => string;
323
+ downloadOnly: (target: string) => string;
324
+ downloadTarget: (target: string) => string;
325
+ withIsoloom: string;
326
+ withTool: string;
327
+ run: string;
328
+ specIntro: string;
329
+ showSpec: string;
330
+ hideSpec: string;
331
+ containersAndVms: string;
332
+ dockerOnOneVm: string;
333
+ oneVmPerMachine: string;
334
+ };
335
+ issues: {
336
+ vlanBlocks: (vlan: string, block: string, other: string, sw: string) => string;
337
+ areaBlock: (lan: string, block: string, switches: string) => string;
338
+ noName: {
339
+ machine: string;
340
+ lan: string;
341
+ switch: string;
342
+ };
343
+ sameName: {
344
+ machine: (name: string) => string;
345
+ lan: (name: string) => string;
346
+ switch: (name: string) => string;
347
+ };
348
+ badPort: (machine: string, entry: string) => string;
349
+ };
350
+ gns3: {
351
+ notGns3: string;
352
+ noTopology: string;
353
+ cisco: (node: string, kind: string) => string;
354
+ firewall: (node: string) => string;
355
+ noEquivalent: (node: string, type: string) => string;
356
+ noNodes: string;
357
+ };
358
+ account: {
359
+ signIn: string;
360
+ signOut: string;
361
+ signedInAs: (name: string) => string;
362
+ };
363
+ projects: {
364
+ save: string;
365
+ saveAs: string;
366
+ openList: string;
367
+ saveAsPrompt: string;
368
+ windowTitle: string;
369
+ loading: string;
370
+ none: string;
371
+ open: string;
372
+ openButton: string;
373
+ delete: (name: string) => string;
374
+ confirmDelete: (name: string) => string;
375
+ failed: (error: string) => string;
376
+ history: (name: string) => string;
377
+ noVersions: string;
378
+ restore: string;
379
+ historyHint: string;
380
+ opened: (name: string) => string;
381
+ status: {
382
+ idle: (name: string) => string;
383
+ saving: (name: string) => string;
384
+ saved: (name: string) => string;
385
+ error: (name: string) => string;
386
+ };
387
+ };
388
+ machineRun: {
389
+ display: string;
390
+ displayTitle: string;
391
+ displayOpened: (what: string) => string;
392
+ consoleHint: string;
393
+ runFirst: string;
394
+ running: string;
395
+ stopped: string;
396
+ unknown: string;
397
+ console: string;
398
+ restart: string;
399
+ stop: string;
400
+ start: string;
401
+ snapshots: string;
402
+ takeSnapshot: string;
403
+ snapshotHint: string;
404
+ snapshotPrompt: string;
405
+ noSnapshots: string;
406
+ restore: string;
407
+ inUse: string;
408
+ ownImage: string;
409
+ deleteSnapshot: (label: string) => string;
410
+ };
411
+ update: {
412
+ available: (version: string) => string;
413
+ restart: string;
414
+ installing: string;
415
+ later: string;
416
+ };
417
+ }>;
418
+ export declare function useText(): EditorText;
@@ -0,0 +1,5 @@
1
+ import type { EditorModel } from "./hooks/use-editor";
2
+ /** Top center: the devices, grouped as network, containers, VMs; the line under it says what a click does. */
3
+ export declare function Toolbar({ e }: {
4
+ e: EditorModel;
5
+ }): import("react").JSX.Element;
@@ -0,0 +1,10 @@
1
+ import type { EditorModel } from "./hooks/use-editor";
2
+ /** Top left: the menu, and where the lab is saved. */
3
+ export declare function TopLeft({ e, onImportGns3 }: {
4
+ e: EditorModel;
5
+ onImportGns3: () => void;
6
+ }): import("react").JSX.Element;
7
+ /** Top right: the lab's status, Run (desktop app), and Export. */
8
+ export declare function TopRight({ e }: {
9
+ e: EditorModel;
10
+ }): import("react").JSX.Element;
@@ -0,0 +1,6 @@
1
+ import type { LinkConditions } from "../../../lib/tool/model.js";
2
+ /** How a cable or a LAN behaves: four optional numbers (empty: none). */
3
+ export declare function ConditionsFields({ value, onChange }: {
4
+ value: LinkConditions | undefined;
5
+ onChange: (tc: LinkConditions | undefined) => void;
6
+ }): import("react").JSX.Element;
@@ -0,0 +1,5 @@
1
+ import type { EditorModel } from "../hooks/use-editor";
2
+ /** The windows floating over the canvas: what is selected, projects, the lab's status, Run, Export. */
3
+ export declare function EditorWindows({ e }: {
4
+ e: EditorModel;
5
+ }): import("react").JSX.Element;
@@ -0,0 +1,4 @@
1
+ /** A text field in the editor's windows. */
2
+ export declare const field = "h-8 w-full rounded-md border border-input bg-background px-2 text-sm outline-none focus-visible:ring-2 focus-visible:ring-ring";
3
+ /** A multi-line field (provisioning steps, an appliance's configuration). */
4
+ export declare const area = "w-full rounded-md border border-input bg-background px-2 py-1.5 font-mono text-xs outline-none focus-visible:ring-2 focus-visible:ring-ring";