@weasel-js/labkit 1.6.0 → 1.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/dist/_dts/{CanvasStackContext-DQgcH1ny.d.ts → CanvasStackContext-Wo6OwIVM.d.ts} +1 -1
  2. package/dist/_dts/FloatingPanel-7j0IcXwz.d.ts +30 -0
  3. package/dist/_dts/{LayerList.d-2c9yup5Y.d.ts → LayerList.d-BoELAMsM.d.ts} +2 -2
  4. package/dist/_dts/{index-DINmCuLA.d.ts → PropertyField.d-D0ndfIIt.d.ts} +34 -83
  5. package/dist/_dts/{Select.d-BchGMC2Y.d.ts → Select.d-Cr8-zoup.d.ts} +4 -5
  6. package/dist/_dts/{usePanZoom-Bq73pwFe.d.ts → Stage-DWBBi8IU.d.ts} +80 -35
  7. package/dist/_dts/{index-B0--8PEM.d.ts → index-CKyX0ME_.d.ts} +12 -13
  8. package/dist/_dts/{frac-DTRq7Xpb.d.ts → types-B7yBTTF9.d.ts} +699 -649
  9. package/dist/_dts/{types-B7y8hX1D.d.ts → types-DTuViBvc.d.ts} +20 -1
  10. package/dist/_dts/{useTrialState-CP4jfuKl.d.ts → useTrialState-CMaV6UD4.d.ts} +2 -3
  11. package/dist/canvas/index.d.ts +39 -7
  12. package/dist/canvas/index.js +5 -3
  13. package/dist/chrome/index.d.ts +4 -5
  14. package/dist/chrome/index.js +8 -6
  15. package/dist/chunk-24W5VEJW.js +18 -0
  16. package/dist/chunk-24W5VEJW.js.map +1 -0
  17. package/dist/chunk-3RY6WL5T.js +38 -0
  18. package/dist/chunk-3RY6WL5T.js.map +1 -0
  19. package/dist/{chunk-H5VIV7MQ.js → chunk-4TT3PNPR.js} +60 -51
  20. package/dist/chunk-4TT3PNPR.js.map +1 -0
  21. package/dist/{chunk-ZORVNOKX.js → chunk-6FLXL3I7.js} +9 -145
  22. package/dist/chunk-6FLXL3I7.js.map +1 -0
  23. package/dist/{chunk-HFRE4QQV.js → chunk-ASOK76ZH.js} +53 -22
  24. package/dist/chunk-ASOK76ZH.js.map +1 -0
  25. package/dist/chunk-AWQG7FCC.js +19 -0
  26. package/dist/chunk-AWQG7FCC.js.map +1 -0
  27. package/dist/chunk-CGHF6RZV.js +300 -0
  28. package/dist/chunk-CGHF6RZV.js.map +1 -0
  29. package/dist/chunk-DWMSB4CA.js +228 -0
  30. package/dist/chunk-DWMSB4CA.js.map +1 -0
  31. package/dist/{chunk-USO6TERP.js → chunk-GHGO52SO.js} +11 -9
  32. package/dist/chunk-GHGO52SO.js.map +1 -0
  33. package/dist/{chunk-MOLIUNVH.js → chunk-HKV7LRHY.js} +4 -4
  34. package/dist/{chunk-MOLIUNVH.js.map → chunk-HKV7LRHY.js.map} +1 -1
  35. package/dist/{chunk-VQ47KWD5.js → chunk-IRTGUQ5O.js} +5 -4
  36. package/dist/chunk-IRTGUQ5O.js.map +1 -0
  37. package/dist/{chunk-H6ZAOWNE.js → chunk-JVBYV6TL.js} +3 -3
  38. package/dist/{chunk-H6ZAOWNE.js.map → chunk-JVBYV6TL.js.map} +1 -1
  39. package/dist/chunk-KHK5FGER.js +145 -0
  40. package/dist/chunk-KHK5FGER.js.map +1 -0
  41. package/dist/chunk-NEXR37YJ.js +144 -0
  42. package/dist/chunk-NEXR37YJ.js.map +1 -0
  43. package/dist/{chunk-BVL7Y574.js → chunk-O6FFFOHS.js} +14 -6
  44. package/dist/chunk-O6FFFOHS.js.map +1 -0
  45. package/dist/chunk-QGMOA2YE.js +731 -0
  46. package/dist/chunk-QGMOA2YE.js.map +1 -0
  47. package/dist/{chunk-ERFMC6WU.js → chunk-S4NCI32V.js} +19 -10
  48. package/dist/chunk-S4NCI32V.js.map +1 -0
  49. package/dist/{chunk-3FI7Y4R4.js → chunk-SLAQPUI4.js} +4 -4
  50. package/dist/{chunk-3FI7Y4R4.js.map → chunk-SLAQPUI4.js.map} +1 -1
  51. package/dist/{chunk-AWH3SRPW.js → chunk-TJ77A4A3.js} +3 -31
  52. package/dist/chunk-TJ77A4A3.js.map +1 -0
  53. package/dist/{chunk-WUJXJC5O.js → chunk-TYN6MLXX.js} +691 -1395
  54. package/dist/chunk-TYN6MLXX.js.map +1 -0
  55. package/dist/{chunk-RS3HRQWU.js → chunk-WPLAANH4.js} +4 -3
  56. package/dist/chunk-WPLAANH4.js.map +1 -0
  57. package/dist/config/index.d.ts +36 -35
  58. package/dist/config/index.js +4 -5
  59. package/dist/controls/index.d.ts +91 -7
  60. package/dist/controls/index.js +5 -4
  61. package/dist/dragdrop/index.d.ts +8 -6
  62. package/dist/dragdrop/index.js +3 -2
  63. package/dist/index.d.ts +50 -77
  64. package/dist/index.js +138 -254
  65. package/dist/index.js.map +1 -1
  66. package/dist/layers/index.d.ts +3 -4
  67. package/dist/layers/index.js +2 -1
  68. package/dist/loupe/index.d.ts +19 -16
  69. package/dist/loupe/index.js +5 -3
  70. package/dist/overview/index.d.ts +56 -0
  71. package/dist/overview/index.js +288 -0
  72. package/dist/overview/index.js.map +1 -0
  73. package/dist/passthrough/weasel-ui.d.ts +38 -38
  74. package/dist/passthrough/weasel-ui.js +2 -1
  75. package/dist/primitives/index.d.ts +19 -43
  76. package/dist/primitives/index.js +5 -3
  77. package/dist/state/index.d.ts +7 -7
  78. package/dist/state/index.js +4 -5
  79. package/dist/state/index.js.map +1 -1
  80. package/dist/styles.css +63 -1
  81. package/dist/undo/index.d.ts +3 -3
  82. package/package.json +13 -9
  83. package/src/annotations/index.ts +1 -0
  84. package/src/annotations/store.test.ts +26 -0
  85. package/src/annotations/store.ts +25 -6
  86. package/src/annotations/toolMap.test.ts +37 -2
  87. package/src/annotations/toolMap.ts +13 -0
  88. package/src/annotations/types.ts +27 -0
  89. package/src/canvas/AGENTS.md +8 -10
  90. package/src/canvas/CameraInput.test.tsx +136 -0
  91. package/src/canvas/CameraInput.tsx +311 -0
  92. package/src/canvas/CanvasStack.tsx +42 -58
  93. package/src/canvas/LinkedCursor.less +16 -0
  94. package/src/canvas/LinkedCursor.tsx +54 -0
  95. package/src/canvas/Stage.tsx +42 -37
  96. package/src/canvas/cameraView.test.ts +60 -0
  97. package/src/canvas/cameraView.ts +61 -0
  98. package/src/canvas/index.ts +11 -2
  99. package/src/chrome/regions/SidebarRegion.test.tsx +9 -2
  100. package/src/config/builder.ts +3 -3
  101. package/src/config/entry.test.ts +3 -1
  102. package/src/config/fromConfigField.ts +1 -0
  103. package/src/config/index.ts +4 -1
  104. package/src/config/resolve.ts +11 -1
  105. package/src/config/sectionTree.test.ts +12 -6
  106. package/src/config/sectionTree.ts +15 -5
  107. package/src/config/types.ts +21 -0
  108. package/src/controls/ControlPanel.test.tsx +12 -2
  109. package/src/controls/ControlPanel.tsx +28 -9
  110. package/src/controls/inDialog.test.tsx +18 -0
  111. package/src/controls/inDialog.tsx +2 -10
  112. package/src/index.test.ts +1 -1
  113. package/src/index.ts +8 -4
  114. package/src/instrument/SineWave.smoke.test.tsx +2 -0
  115. package/src/instrument/types.ts +10 -1
  116. package/src/lab/Lab.nebula.test.tsx +11 -2
  117. package/src/lab/Lab.test.tsx +3 -1
  118. package/src/lab/Lab.tsx +4 -4
  119. package/src/loupe/AGENTS.md +7 -6
  120. package/src/loupe/LoupeGestures.tsx +14 -9
  121. package/src/loupe/TrialLoupe.tsx +5 -5
  122. package/src/loupe/index.ts +1 -0
  123. package/src/loupe/loupeActions.ts +6 -2
  124. package/src/overview/AGENTS.md +38 -0
  125. package/src/overview/OverviewMarks.test.tsx +100 -0
  126. package/src/overview/OverviewMarks.tsx +93 -0
  127. package/src/overview/TrialOverview.less +53 -0
  128. package/src/overview/TrialOverview.stories.tsx +50 -0
  129. package/src/overview/TrialOverview.test.tsx +116 -0
  130. package/src/overview/TrialOverview.tsx +374 -0
  131. package/src/overview/index.ts +2 -0
  132. package/src/passthrough/weasel-ui.ts +7 -0
  133. package/src/specimen/Specimen.tsx +19 -2
  134. package/src/state/labRecords.test.ts +4 -1
  135. package/src/state/store.test.ts +4 -4
  136. package/src/state/useTrialState.test.tsx +1 -1
  137. package/src/styles.less +2 -0
  138. package/src/theme/Interstellar.stories.tsx +1 -5
  139. package/src/tools/labTool.ts +6 -2
  140. package/src/trial/Trial.annotations.test.tsx +16 -0
  141. package/src/trial/Trial.loupe.test.tsx +73 -1
  142. package/src/trial/Trial.stories.tsx +2 -0
  143. package/src/trial/Trial.tsx +17 -1
  144. package/src/trial/trialOps.test.ts +4 -4
  145. package/dist/_dts/inDialog-D5ZKGjiD.d.ts +0 -23
  146. package/dist/_dts/number.d-OeQYQoUO.d.ts +0 -28
  147. package/dist/chunk-2AYGEN57.js +0 -32
  148. package/dist/chunk-2AYGEN57.js.map +0 -1
  149. package/dist/chunk-AWH3SRPW.js.map +0 -1
  150. package/dist/chunk-BVL7Y574.js.map +0 -1
  151. package/dist/chunk-ERFMC6WU.js.map +0 -1
  152. package/dist/chunk-H5VIV7MQ.js.map +0 -1
  153. package/dist/chunk-HFRE4QQV.js.map +0 -1
  154. package/dist/chunk-RS3HRQWU.js.map +0 -1
  155. package/dist/chunk-TT5C5S6R.js +0 -368
  156. package/dist/chunk-TT5C5S6R.js.map +0 -1
  157. package/dist/chunk-USO6TERP.js.map +0 -1
  158. package/dist/chunk-VQ47KWD5.js.map +0 -1
  159. package/dist/chunk-WUJXJC5O.js.map +0 -1
  160. package/dist/chunk-ZORVNOKX.js.map +0 -1
  161. package/src/canvas/usePanZoom.test.ts +0 -244
  162. package/src/canvas/usePanZoom.ts +0 -147
package/dist/index.js CHANGED
@@ -1,48 +1,58 @@
1
- import { resolveLoupe, TrialLoupe } from './chunk-ERFMC6WU.js';
2
- export { CanvasLoupe, DomLoupe, LOUPE_DEFAULTS, LOUPE_MAGNIFY_ID, LOUPE_PEEK_ID, LoupeBubble, LoupeGestures, TrialLoupe, createLoupeActions, drawCanvasLens, lensCamera, lensSourceRect, resolveLoupe, sampleStack, useLoupe } from './chunk-ERFMC6WU.js';
1
+ import { resolveLoupe, TrialLoupe } from './chunk-S4NCI32V.js';
2
+ export { CanvasLoupe, DomLoupe, LOUPE_DEFAULTS, LOUPE_MAGNIFY_ID, LOUPE_PEEK_ID, LoupeBubble, LoupeGestures, TrialLoupe, createLoupeActions, drawCanvasLens, lensCamera, lensSourceRect, resolveLoupe, sampleStack, useLoupe } from './chunk-S4NCI32V.js';
3
3
  import { createEventBus, pushSnapshot, redo, undo } from './chunk-RL2LOLNI.js';
4
4
  export { clearUndo, createEventBus, emptyStack, pushSnapshot, redo, undo } from './chunk-RL2LOLNI.js';
5
- import { useDragDrop, DragOverlay, Palette } from './chunk-RS3HRQWU.js';
5
+ import { useDragDrop, DragOverlay, Palette } from './chunk-WPLAANH4.js';
6
6
  import { useTiledSurface } from './chunk-IJJUK4FU.js';
7
7
  export { composeRects, rectsEqual, toDeviceRect, useTiledSurface } from './chunk-IJJUK4FU.js';
8
8
  import { useJob } from './chunk-HXXTULDN.js';
9
9
  export { useJob } from './chunk-HXXTULDN.js';
10
- import { suppressContributions, mergeContributions, builtinContributions, TitleBarRegion, ToolbarRegion, PaletteRegion, ViewportRegion, SidebarRegion, StatusRegion, resolveLabTool, AnnotationsContext, useLabChromeContext, labContributions, LabHeaderRegion, LabFooterRegion, LabAsideRegion, LabSidebarRegion } from './chunk-H5VIV7MQ.js';
11
- export { AnnotationsContext, ExportMenu, LabAsideRegion, LabFooterRegion, LabHeaderRegion, LabSidebarRegion, MarkList, PaletteRegion, SidebarRegion, StatusRegion, TitleBarRegion, ToolbarRegion, ViewportRegion, builtinContributions, contributionsIn, labContributions, mergeContributions, suppressContributions, toolContributions, useAnnotations, useAnnotationsOptional, useLabChromeContext } from './chunk-H5VIV7MQ.js';
12
- import { Split, JobProgress, Legend, FloatingPanel } from './chunk-ZORVNOKX.js';
13
- export { FloatingPanel, JobProgress, Legend, Split } from './chunk-ZORVNOKX.js';
14
- import { Toolbar, StatusBar, ScaleIndicator, ZoomControl } from './chunk-3FI7Y4R4.js';
15
- export { FpsMeter, ScaleIndicator, StatusBar, Toolbar, ZoomControl } from './chunk-3FI7Y4R4.js';
10
+ import { markCommands, markSvgNodes } from './chunk-KHK5FGER.js';
11
+ export { markCommands, markSvgNodes } from './chunk-KHK5FGER.js';
12
+ import { ANNOTATION_WEASEL_TOOLS, annotationToolInfo, suppressContributions, mergeContributions, builtinContributions, TitleBarRegion, ToolbarRegion, PaletteRegion, ViewportRegion, SidebarRegion, StatusRegion, resolveLabTool, useLabChromeContext, labContributions, labAnnotationTools, LabHeaderRegion, LabFooterRegion, LabAsideRegion, LabSidebarRegion } from './chunk-4TT3PNPR.js';
13
+ export { ANNOTATION_TOOLS, ANNOTATION_WEASEL_TOOLS, ExportMenu, LabAsideRegion, LabFooterRegion, LabHeaderRegion, LabSidebarRegion, MarkList, PaletteRegion, SidebarRegion, StatusRegion, TitleBarRegion, ToolbarRegion, ViewportRegion, annotationToolInfo, builtinContributions, contributionsIn, labContributions, mergeContributions, suppressContributions, toolContributions, useLabChromeContext } from './chunk-4TT3PNPR.js';
14
+ import { AnnotationsContext } from './chunk-3RY6WL5T.js';
15
+ export { AnnotationsContext, useAnnotations, useAnnotationsOptional } from './chunk-3RY6WL5T.js';
16
+ import { Split, JobProgress, Legend } from './chunk-6FLXL3I7.js';
17
+ export { JobProgress, Legend, Split } from './chunk-6FLXL3I7.js';
18
+ import { FloatingPanel } from './chunk-NEXR37YJ.js';
19
+ export { FloatingPanel } from './chunk-NEXR37YJ.js';
20
+ import { Toolbar, StatusBar, ScaleIndicator, ZoomControl } from './chunk-SLAQPUI4.js';
21
+ export { FpsMeter, ScaleIndicator, StatusBar, Toolbar, ZoomControl } from './chunk-SLAQPUI4.js';
16
22
  import './chunk-SBXNQW4G.js';
17
- import { unruledConfigSchema, createLabStore, openLabStore, panelKey } from './chunk-MOLIUNVH.js';
18
- export { CURRENT_DOCUMENT_VERSION, dockPanel, labDocumentKey, openLabStore, panelKey, quarantineKey, undockPanel, useTrialState } from './chunk-MOLIUNVH.js';
23
+ import { unruledConfigSchema, createLabStore, openLabStore, panelKey } from './chunk-HKV7LRHY.js';
24
+ export { CURRENT_DOCUMENT_VERSION, dockPanel, labDocumentKey, openLabStore, panelKey, quarantineKey, undockPanel, useTrialState } from './chunk-HKV7LRHY.js';
19
25
  import { newId, useWarnIgnoredChange, useOpenOnce, PersistenceContext, createRecordCache, noneAdapter, defaultStorage, usePersistedState } from './chunk-RWNDDKOH.js';
20
26
  export { Persistence, createIndexedDbAdapter, createMemoryAdapter, indexedDbAdapter, localStorageAdapter, noneAdapter, sessionStorageAdapter, urlHashAdapter, usePersistedState } from './chunk-RWNDDKOH.js';
21
- export { ControlPanel } from './chunk-HFRE4QQV.js';
22
- import { useConfigSchema } from './chunk-USO6TERP.js';
23
- export { sectionTree, useConfigSchema } from './chunk-USO6TERP.js';
27
+ export { ControlPanel, inDialog, summarizeValue } from './chunk-ASOK76ZH.js';
28
+ import { useConfigSchema } from './chunk-GHGO52SO.js';
29
+ export { sectionTree, useConfigSchema } from './chunk-GHGO52SO.js';
24
30
  import { useLabContext, LabContext } from './chunk-Z76KEZAX.js';
25
31
  export { LabContext, useLabContext } from './chunk-Z76KEZAX.js';
26
- import { useResolvedConfig } from './chunk-BVL7Y574.js';
27
- export { BaseNode, BooleanNode, ColorNode, CustomNode, EnumNode, GroupNode, ListNode, NumberNode, StringNode, ValueNode, applyRules, builtinRules, f, isConfigBranch, resolveConfigSchema, titleCase, useResolvedConfig } from './chunk-BVL7Y574.js';
28
- export { fromConfigFields, isLeafVisible } from './chunk-VQ47KWD5.js';
29
- import { hasConfigPath, schemaNodeAtPath, applyConfigWrite, resolveAutoConfig, isAuto, isRecord, autoPathsOf, fillConfigDefaults } from './chunk-AWH3SRPW.js';
30
- export { auto, autoPathsOf, fillConfigDefaults, hasConfigPath, inDialog, isAuto, resolveAutoConfig, schemaNodeAtPath, summarizeValue, valueAtPath, withValueAtPath } from './chunk-AWH3SRPW.js';
31
- import { CameraWheelContext, as2DView, DEFAULT_VIEW, CanvasStack, Stage, withZoom, fitStage } from './chunk-TT5C5S6R.js';
32
- export { CanvasStack, DEFAULT_VIEW, Stage, as2DView, fitStage, usePanZoom } from './chunk-TT5C5S6R.js';
33
- export { centerOn, zoomAt } from './chunk-H6ZAOWNE.js';
34
- import { applyCamera } from './chunk-2AYGEN57.js';
35
- export { DEFAULT_FRAME, applyCamera, resolveFrame, screenToWorld, worldToScreen } from './chunk-2AYGEN57.js';
32
+ import { useResolvedConfig } from './chunk-O6FFFOHS.js';
33
+ export { BaseNode, BooleanNode, ColorNode, CustomNode, EnumNode, GroupNode, ListNode, NumberNode, StringNode, ValueNode, applyRules, builtinRules, f, isConfigBranch, resolveConfigSchema, titleCase, useResolvedConfig } from './chunk-O6FFFOHS.js';
34
+ export { fromConfigFields, isLeafVisible } from './chunk-IRTGUQ5O.js';
35
+ import { hasConfigPath, schemaNodeAtPath, applyConfigWrite, resolveAutoConfig, isAuto, isRecord, autoPathsOf, fillConfigDefaults } from './chunk-TJ77A4A3.js';
36
+ export { auto, autoPathsOf, fillConfigDefaults, hasConfigPath, isAuto, resolveAutoConfig, schemaNodeAtPath, valueAtPath, withValueAtPath } from './chunk-TJ77A4A3.js';
37
+ import { CanvasStack, Stage, fitStage } from './chunk-CGHF6RZV.js';
38
+ export { CanvasStack, Stage, fitStage } from './chunk-CGHF6RZV.js';
39
+ export { centerOn, zoomAt } from './chunk-JVBYV6TL.js';
40
+ export { screenToWorld, worldToScreen } from './chunk-AWQG7FCC.js';
36
41
  import { useSurfaceOptional, useSurfaceCanvas, useTileId, SurfaceContext, SurfaceCanvasContext } from './chunk-WIG6XHJ7.js';
37
42
  export { SurfaceCanvasContext, SurfaceContext, useSurface, useSurfaceCanvas, useSurfaceOptional, useSurfaceTile, useTileId } from './chunk-WIG6XHJ7.js';
43
+ import { CameraWheelContext, as2DView, DEFAULT_VIEW, CameraScopeContext, withZoom } from './chunk-DWMSB4CA.js';
44
+ export { CameraContext, CameraInput, CameraScope, DEFAULT_VIEW, as2DView } from './chunk-DWMSB4CA.js';
45
+ import { applyCamera } from './chunk-24W5VEJW.js';
46
+ export { DEFAULT_FRAME, applyCamera, resolveFrame } from './chunk-24W5VEJW.js';
38
47
  import { CanvasStackContext } from './chunk-CQLQPQ4P.js';
39
48
  export { CanvasStackContext } from './chunk-CQLQPQ4P.js';
40
49
  import { LabStoreContext, TrialIdProvider, TrialIdContext } from './chunk-2YILQ7Y5.js';
41
50
  export { LabStoreContext, LabStoreProvider, TrialIdContext, TrialIdProvider, useLabStore, useTrialId } from './chunk-2YILQ7Y5.js';
42
51
  import './chunk-2RVCB2PT.js';
43
- import { y, I, A, T, i2, P, m, H, serializeSvg, D, S2, oe, d2, s3, c, Ht, o2, a6, l5, u5, a5, r3, a7, i3, o4, s6, c5, l7, p, f2, u4, g, T2, y2, l8, b, c6, i4, l4, C, S, ae, oe2, B, b2, A2, n6, s5, m4, l2, u, g2, u3, S4, r4, n7, r5, i5, p2, f, n8, o3, c3, c4, w, L, n9, k, $2 } from './chunk-WUJXJC5O.js';
44
- export { c as Button, re as CloseIcon, Pe as CollapseIcon, _ as CurveField, Fe as ExpandIcon, l as Icon, u4 as Input, l9 as Jog, D as LayerList, ge as PauseIcon, he as PlayIcon, V as PropertyControl, B as PropertyField, b2 as PropertyGroup, oe2 as PropertyList, ae as PropertyPanel, L3 as PropertyRow, se as PropertySpan, Z as ResetIcon, T2 as Select, ve as StepBackIcon, $ as StepForwardIcon, _e as StopIcon, x as Subpanel, a5 as ToggleBar, oe3 as TokenPanel, H2 as inferTokenType, S2 as moveLayers, O as refitScale } from './chunk-WUJXJC5O.js';
45
- import { textCommand, ellipsePath, linePath, markerDrawCommands, rectPath, createScene, asNodeId as asNodeId$1, WeaselProvider, SceneCanvas, sceneFromJSON, PathBuilder, renderSceneToPixels, useActiveToolContext } from '@weasel-js/core';
52
+ import { D, S2, G, d2, s3, c, Ht, o3, a6, l5, u5, a5, r3, a7, i2, o5, s6, c5, l7, p, f2, u4, g, T, y2, l8, y, c6, i3, l4, C2, S, ae2, oe, B2, b2, A2, n6, s5, m3, l2, u, g2, u3, S4, r4, n7, r5, i4, p2, f, n8, o4, c3, c4, w, L, n9, k2, $2 } from './chunk-TYN6MLXX.js';
53
+ export { c as Button, V as CloseIcon, xe as CollapseIcon, _ as CurveField, Se as ExpandIcon, l as Icon, u4 as Input, l9 as Jog, D as LayerList, re as PauseIcon, ne as PlayIcon, V2 as PropertyControl, B2 as PropertyField, b2 as PropertyGroup, oe as PropertyList, ae2 as PropertyPanel, L3 as PropertyRow, se as PropertySpan, B as ResetIcon, T as Select, ae as StepBackIcon, $ as StepForwardIcon, ie as StopIcon, x as Subpanel, a5 as ToggleBar, oe2 as TokenPanel, H2 as inferTokenType, S2 as moveLayers, O2 as refitScale } from './chunk-TYN6MLXX.js';
54
+ import { serializeSvg } from './chunk-QGMOA2YE.js';
55
+ import { createScene, asNodeId as asNodeId$1, WeaselProvider, SceneCanvas, createPointerStore, PointerContextProvider, sceneFromJSON, renderSceneToPixels, useActiveToolContext } from '@weasel-js/core';
46
56
  import { createContext, useState, useRef, useEffect, useCallback, useContext, useMemo, useId, Children, useLayoutEffect, useSyncExternalStore } from 'react';
47
57
  import { flushSync, createPortal } from 'react-dom';
48
58
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
@@ -53,94 +63,6 @@ import { Provider, StrategyRegistryProvider, DragProvider, Container, useDragHan
53
63
  import { asNodeId, Store, createNode, floatingStrategy, gridStrategy } from 'windease';
54
64
  import { Focusable } from 'react-aria-components';
55
65
 
56
- var MARK_COLOR = "#e5484d";
57
- var MARK_WIDTH = 2;
58
- var TEXT_SIZE = 14;
59
- var POINT_RADIUS = 4;
60
- var toWorld = (p3, content) => ({
61
- x: p3.x * content.w,
62
- y: p3.y * content.h
63
- });
64
- function vertices(m3, content) {
65
- const stored = m3.data.points;
66
- if (stored && stored.length >= 2) return stored.map((p3) => toWorld(p3, content));
67
- const { x: x2, y: y3, width, height } = m3.pose;
68
- return [
69
- { x: x2, y: y3 },
70
- { x: x2 + width, y: y3 + height }
71
- ];
72
- }
73
- function polyline(points) {
74
- const b3 = new PathBuilder();
75
- const first = points[0];
76
- if (!first) return rectPath(0, 0, 0, 0);
77
- b3.moveTo(first.x, first.y);
78
- for (const p3 of points.slice(1)) b3.lineTo(p3.x, p3.y);
79
- return b3.build();
80
- }
81
- function markCommands(m3, content, style = {}) {
82
- const color = style.color ?? MARK_COLOR;
83
- const stroke = {
84
- paint: { color },
85
- width: MARK_WIDTH,
86
- cap: "round",
87
- join: "round",
88
- ...style.stale ? { dash: [6, 4] } : {}
89
- };
90
- switch (m3.data.kind) {
91
- case "rect":
92
- return [
93
- { kind: "path", path: rectPath(m3.pose.x, m3.pose.y, m3.pose.width, m3.pose.height), stroke }
94
- ];
95
- case "ellipse":
96
- return [{ kind: "path", path: ellipsePath(m3.pose), stroke }];
97
- case "line": {
98
- const [a4, b3] = vertices(m3, content);
99
- return [{ kind: "path", path: linePath(a4, b3), stroke }];
100
- }
101
- case "arrow": {
102
- const [a4, b3] = vertices(m3, content);
103
- const marked = { ...stroke, markerEnd: "arrow" };
104
- const path = linePath(a4, b3);
105
- return [
106
- { kind: "path", path, stroke: marked },
107
- ...markerDrawCommands(path, marked, MARK_WIDTH, void 0)
108
- ];
109
- }
110
- case "stroke":
111
- return [{ kind: "path", path: polyline(vertices(m3, content)), stroke }];
112
- case "point": {
113
- const stored = m3.data.points?.[0];
114
- const c6 = stored ? toWorld(stored, content) : { x: m3.pose.x, y: m3.pose.y };
115
- const ring = {
116
- x: c6.x - POINT_RADIUS,
117
- y: c6.y - POINT_RADIUS,
118
- width: 2 * POINT_RADIUS,
119
- height: 2 * POINT_RADIUS
120
- };
121
- return [{ kind: "path", path: ellipsePath(ring), stroke }];
122
- }
123
- case "text": {
124
- const text = m3.data.title;
125
- if (!text) return [];
126
- return [
127
- textCommand(
128
- m3.pose.x,
129
- m3.pose.y,
130
- text,
131
- { fontSize: TEXT_SIZE },
132
- void 0,
133
- void 0,
134
- void 0,
135
- {
136
- fill: { color }
137
- }
138
- )
139
- ];
140
- }
141
- }
142
- }
143
-
144
66
  // src/annotations/staleness.ts
145
67
  function seenFrom(config, keys) {
146
68
  const out = {};
@@ -175,57 +97,6 @@ function resolveMarkStyle(data, opts) {
175
97
  };
176
98
  }
177
99
 
178
- // src/annotations/svgNodes.ts
179
- var NO_PAINT = { kind: "none" };
180
- function toSvgPaint(paint) {
181
- if (!paint) return NO_PAINT;
182
- if ("color" in paint && typeof paint.color === "string") {
183
- return {
184
- kind: "solid",
185
- color: paint.color,
186
- ...paint.opacity != null ? { opacity: paint.opacity } : {}
187
- };
188
- }
189
- return { kind: "gradient", paint };
190
- }
191
- function toSvgStroke(stroke) {
192
- return {
193
- paint: toSvgPaint(stroke.paint),
194
- width: stroke.width ?? 1,
195
- ...stroke.cap ? { cap: stroke.cap } : {},
196
- ...stroke.join ? { join: stroke.join } : {},
197
- ...stroke.dash ? { dash: [...stroke.dash] } : {},
198
- ...stroke.miterLimit != null ? { miterLimit: stroke.miterLimit } : {},
199
- ...stroke.align ? { align: stroke.align } : {}
200
- };
201
- }
202
- function toSvgNode(cmd, m3) {
203
- if (cmd.kind === "path") {
204
- return {
205
- kind: "path",
206
- path: cmd.path,
207
- fill: toSvgPaint(cmd.fill),
208
- ...cmd.stroke ? { stroke: toSvgStroke(cmd.stroke) } : {}
209
- };
210
- }
211
- if (cmd.kind === "text") {
212
- return {
213
- kind: "text",
214
- x: cmd.x,
215
- y: cmd.y,
216
- width: m3.pose.width,
217
- height: m3.pose.height,
218
- text: cmd.runs.map((run) => run.text).join(""),
219
- style: cmd.style,
220
- ...cmd.runs[0]?.fill ? { fill: cmd.runs[0].fill } : {}
221
- };
222
- }
223
- throw new Error(`[labkit] a mark drew a '${cmd.kind}' command, which has no vector form`);
224
- }
225
- function markSvgNodes(m3, content, style = {}) {
226
- return markCommands(m3, content, style).map((cmd) => toSvgNode(cmd, m3));
227
- }
228
-
229
100
  // src/annotations/capture.ts
230
101
  var SVG_NS = "http://www.w3.org/2000/svg";
231
102
  function capturePlan(base, format) {
@@ -429,8 +300,8 @@ var MarkHistory = class {
429
300
  /** The target `undo` would act on, skipping any whose scene has nothing
430
301
  * left — a scene can drop entries this ordering still lists. */
431
302
  next(stack, can, at) {
432
- for (let i5 = stack.length - 1; i5 >= 0; i5--) {
433
- const target = stack[i5];
303
+ for (let i4 = stack.length - 1; i4 >= 0; i4--) {
304
+ const target = stack[i4];
434
305
  if (target === void 0) continue;
435
306
  const scene = at(target);
436
307
  if (scene && can(scene)) return target;
@@ -467,9 +338,9 @@ var MarkHistory = class {
467
338
  }
468
339
  };
469
340
  function drop(stack, value) {
470
- for (let i5 = stack.length - 1; i5 >= 0; i5--) {
471
- if (stack[i5] === value) {
472
- stack.splice(i5, 1);
341
+ for (let i4 = stack.length - 1; i4 >= 0; i4--) {
342
+ if (stack[i4] === value) {
343
+ stack.splice(i4, 1);
473
344
  return;
474
345
  }
475
346
  }
@@ -510,6 +381,12 @@ function createAnnotationStore(opts) {
510
381
  for (const target of Object.keys(restore ?? {})) sceneFor(target);
511
382
  const targetOf = (id) => targets().find((t) => t.id === id);
512
383
  const contentOf = (id) => targetOf(id)?.content ?? NO_CONTENT;
384
+ const drawOptionsFor = (info) => ({
385
+ content: info.content,
386
+ positionDependsOn: info.positionDependsOn,
387
+ config: opts.config?.(),
388
+ meaning: typeof opts.meaning === "function" ? opts.meaning() : opts.meaning
389
+ });
513
390
  const project = (target, node) => {
514
391
  const found = scenes.get(target)?.get(asNodeId$1(node));
515
392
  if (!found) return void 0;
@@ -610,7 +487,7 @@ function createAnnotationStore(opts) {
610
487
  for (const [target, scene] of scenes) {
611
488
  const next = wanted.get(target) ?? [];
612
489
  const now = scene.getSelection();
613
- if (now.length === next.length && next.every((n5, i5) => String(now[i5]) === n5)) continue;
490
+ if (now.length === next.length && next.every((n5, i4) => String(now[i4]) === n5)) continue;
614
491
  scene.setSelection(next.map(asNodeId$1));
615
492
  }
616
493
  },
@@ -661,6 +538,20 @@ function createAnnotationStore(opts) {
661
538
  const found = nodeOf(id);
662
539
  if (found) found.scene.remove(asNodeId$1(found.node.id));
663
540
  },
541
+ paintedMarks(target) {
542
+ const info = targetOf(target);
543
+ const scene = scenes.get(target);
544
+ if (!info || !scene) return [];
545
+ const draw = drawOptionsFor(info);
546
+ return [...scene.renderOrder()].flatMap((id) => {
547
+ const node = scene.get(asNodeId$1(String(id)));
548
+ if (!node) return [];
549
+ const data = node.data;
550
+ return [
551
+ { mark: { pose: node.pose, data }, style: resolveMarkStyle(data, draw) }
552
+ ];
553
+ });
554
+ },
664
555
  async capture(target, captureOpts) {
665
556
  const info = targetOf(target);
666
557
  if (!info) throw new Error(`[labkit] no annotation target called '${target}'`);
@@ -668,12 +559,7 @@ function createAnnotationStore(opts) {
668
559
  {
669
560
  target,
670
561
  scene: sceneFor(target),
671
- draw: {
672
- content: info.content,
673
- positionDependsOn: info.positionDependsOn,
674
- config: opts.config?.(),
675
- meaning: typeof opts.meaning === "function" ? opts.meaning() : opts.meaning
676
- },
562
+ draw: drawOptionsFor(info),
677
563
  base: info.base,
678
564
  onWarn: (message) => console.warn(`[labkit] capture: ${message}`)
679
565
  },
@@ -695,34 +581,6 @@ function annotationsFromJSON(raw, targets, rest = {}) {
695
581
  return createAnnotationStore({ targets, restore: doc.scenes, ...rest });
696
582
  }
697
583
 
698
- // src/annotations/toolMap.ts
699
- var TOOLS = {
700
- select: { weaselTool: "select" },
701
- stroke: { weaselTool: "pencil", kind: "stroke" },
702
- line: { weaselTool: "line", kind: "line" },
703
- arrow: { weaselTool: "line", kind: "arrow" },
704
- rect: { weaselTool: "rect", kind: "rect" },
705
- ellipse: { weaselTool: "ellipse", kind: "ellipse" },
706
- text: { weaselTool: "text", kind: "text" }
707
- };
708
- var ANNOTATION_TOOLS = [
709
- // Not in `TOOLS`: an id the map does not carry is what leaves the overlay idle.
710
- { id: "pointer", label: "Interact", icon: y, group: "annotate" },
711
- { id: "select", label: "Select", icon: I, group: "annotate" },
712
- { id: "stroke", label: "Freehand", icon: A, group: "annotate" },
713
- { id: "line", label: "Line", icon: T, group: "annotate" },
714
- { id: "arrow", label: "Arrow", icon: i2, group: "annotate" },
715
- { id: "rect", label: "Rectangle", icon: P, group: "annotate" },
716
- { id: "ellipse", label: "Ellipse", icon: m, group: "annotate" },
717
- { id: "text", label: "Text", icon: H, group: "annotate" }
718
- ];
719
- function annotationToolInfo(id) {
720
- return id === null ? void 0 : TOOLS[id];
721
- }
722
- var ANNOTATION_WEASEL_TOOLS = [
723
- ...new Set(Object.values(TOOLS).map((t) => t.weaselTool))
724
- ];
725
-
726
584
  // src/annotations/view.ts
727
585
  function toWeaselView(v) {
728
586
  return { x: v.pan.x, y: v.pan.y, scale: { x: v.zoom, y: v.zoom } };
@@ -734,7 +592,7 @@ function fitView(content, pane) {
734
592
  const zoom = content.w > 0 && content.h > 0 ? Math.min(pane.w / content.w, pane.h / content.h) : 1;
735
593
  return { zoom: Number.isFinite(zoom) && zoom > 0 ? zoom : 1, pan: { x: 0, y: 0 } };
736
594
  }
737
- var sameRect = (a4, b3) => a4 !== null && a4.x === b3.x && a4.y === b3.y && a4.w === b3.w && a4.h === b3.h;
595
+ var sameRect = (a4, b2) => a4 !== null && a4.x === b2.x && a4.y === b2.y && a4.w === b2.w && a4.h === b2.h;
738
596
  function ToolBridge({ toolId }) {
739
597
  const tools = useActiveToolContext();
740
598
  const setActive = tools.setActive;
@@ -1412,7 +1270,7 @@ function Trial({ id, chrome, suppress }) {
1412
1270
  if (!storeCtx) throw new Error("[labkit] <Trial> requires <LabStoreProvider>");
1413
1271
  const instruments = useStore(storeCtx.store, (s4) => s4.instruments) ?? lab.instruments;
1414
1272
  const record = useStore(storeCtx.store, (s4) => s4.trials.find((w2) => w2.id === id));
1415
- const instrument = record ? instruments.find((i5) => i5.name === record.instrumentName) : void 0;
1273
+ const instrument = record ? instruments.find((i4) => i4.name === record.instrumentName) : void 0;
1416
1274
  const kept = useKeptMarks(instrument?.annotations?.storage, id);
1417
1275
  if (!record) {
1418
1276
  return /* @__PURE__ */ jsxs("div", { className: "lk-trial lk-trial--unknown", children: [
@@ -1476,6 +1334,7 @@ function TrialRuntime({
1476
1334
  suppress
1477
1335
  }) {
1478
1336
  const wheelSlot = useRef(null);
1337
+ const [pointer] = useState(createPointerStore);
1479
1338
  const canvasContainerRef = useRef(null);
1480
1339
  const loupeHostRef = useRef(null);
1481
1340
  const updateTrialState = useStore(store, (s4) => s4.updateTrialState);
@@ -1615,7 +1474,8 @@ function TrialRuntime({
1615
1474
  updateTrialView(record.id, withZoom(view2d, z));
1616
1475
  },
1617
1476
  activeToolId: resolvedToolId,
1618
- visibleLayers
1477
+ visibleLayers,
1478
+ pointer
1619
1479
  },
1620
1480
  emit: (event) => {
1621
1481
  snapshotIfNeeded(event);
@@ -1656,7 +1516,7 @@ function TrialRuntime({
1656
1516
  const canvasLayers = useMemo(() => {
1657
1517
  if (!instrument.canvas) return [];
1658
1518
  const baseLayers = instrument.canvas.layers;
1659
- const ordered = layerOrder ? [...baseLayers].sort((a4, b3) => layerOrder.indexOf(a4.id) - layerOrder.indexOf(b3.id)) : baseLayers;
1519
+ const ordered = layerOrder ? [...baseLayers].sort((a4, b2) => layerOrder.indexOf(a4.id) - layerOrder.indexOf(b2.id)) : baseLayers;
1660
1520
  return ordered.map((layer) => ({
1661
1521
  id: layer.id,
1662
1522
  visible: layerVisibility[layer.id] !== false,
@@ -1671,7 +1531,7 @@ function TrialRuntime({
1671
1531
  return instrument.layers.ids.map((l8) => typeof l8 === "string" ? { id: l8, label: l8 } : l8);
1672
1532
  }, [instrument.layers]);
1673
1533
  const layerItems = useMemo(() => {
1674
- const ordered = layerOrder ? [...layerDescriptors].sort((a4, b3) => layerOrder.indexOf(a4.id) - layerOrder.indexOf(b3.id)) : layerDescriptors;
1534
+ const ordered = layerOrder ? [...layerDescriptors].sort((a4, b2) => layerOrder.indexOf(a4.id) - layerOrder.indexOf(b2.id)) : layerDescriptors;
1675
1535
  const pinnedLast = [
1676
1536
  ...ordered.filter((l8) => !l8.alwaysOn),
1677
1537
  ...ordered.filter((l8) => l8.alwaysOn)
@@ -1838,6 +1698,7 @@ function TrialRuntime({
1838
1698
  activeToolId: labTool
1839
1699
  }
1840
1700
  ) : null;
1701
+ const scopedBody = /* @__PURE__ */ jsx(WeaselProvider, { isolate: true, children: /* @__PURE__ */ jsx(PointerContextProvider, { store: pointer, children: /* @__PURE__ */ jsx(CameraScopeContext.Provider, { value: true, children: body }) }) });
1841
1702
  return /* @__PURE__ */ jsx(TrialIdProvider, { trialId: record.id, children: /* @__PURE__ */ jsx(AnnotationsContext.Provider, { value: annotationsCap ? annotations : null, children: /* @__PURE__ */ jsx(CameraWheelContext.Provider, { value: wheelSlot, children: /* @__PURE__ */ jsxs(
1842
1703
  TrialChrome,
1843
1704
  {
@@ -1854,7 +1715,7 @@ function TrialRuntime({
1854
1715
  activeToolId: resolvedToolId,
1855
1716
  setActiveTool,
1856
1717
  children: [
1857
- body,
1718
+ scopedBody,
1858
1719
  annotationOverlays
1859
1720
  ]
1860
1721
  }
@@ -1864,7 +1725,7 @@ function TrialRuntime({
1864
1725
  // src/trial/trialOps.ts
1865
1726
  var DEFAULT_VIEW2 = { zoom: 1, pan: { x: 0, y: 0 } };
1866
1727
  function findInstrument(instruments, name) {
1867
- const found = instruments.find((i5) => i5.name === name);
1728
+ const found = instruments.find((i4) => i4.name === name);
1868
1729
  if (!found) {
1869
1730
  throw new Error(`[labkit] Unknown instrument: "${name}"`);
1870
1731
  }
@@ -2062,7 +1923,7 @@ function LabHeader({ addTrial: addTrial2 = true }) {
2062
1923
  className: "lk-lab-header__add",
2063
1924
  onClick: () => lab.addTrial(only.name),
2064
1925
  children: [
2065
- /* @__PURE__ */ jsx(oe, { size: 16 }),
1926
+ /* @__PURE__ */ jsx(G, { size: 16 }),
2066
1927
  /* @__PURE__ */ jsx("span", { children: "Add trial" })
2067
1928
  ]
2068
1929
  }
@@ -2071,7 +1932,7 @@ function LabHeader({ addTrial: addTrial2 = true }) {
2071
1932
  {
2072
1933
  "aria-label": "Add trial",
2073
1934
  label: "Add trial\u2026",
2074
- items: lab.instruments.map((i5) => ({ value: i5.name, label: i5.title ?? i5.name })),
1935
+ items: lab.instruments.map((i4) => ({ value: i4.name, label: i4.title ?? i4.name })),
2075
1936
  onAction: (name) => lab.addTrial(name)
2076
1937
  }
2077
1938
  ),
@@ -2162,13 +2023,13 @@ function LabSwitcher({ title, pages, path, className }) {
2162
2023
  ]
2163
2024
  }
2164
2025
  ) }),
2165
- open && /* @__PURE__ */ jsx("div", { className: "lk-switcher-menu", id: menuId, role: "menu", children: pages.map((page, i5) => /* @__PURE__ */ jsx(
2026
+ open && /* @__PURE__ */ jsx("div", { className: "lk-switcher-menu", id: menuId, role: "menu", children: pages.map((page, i4) => /* @__PURE__ */ jsx(
2166
2027
  "a",
2167
2028
  {
2168
2029
  href: page.href,
2169
2030
  role: "menuitem",
2170
2031
  className: "lk-switcher-item",
2171
- "aria-current": i5 === here ? "page" : void 0,
2032
+ "aria-current": i4 === here ? "page" : void 0,
2172
2033
  onClick: close,
2173
2034
  children: page.label
2174
2035
  },
@@ -2237,7 +2098,7 @@ function Workspace({
2237
2098
  const tilePanels = useMemo(() => (panels ?? []).filter((p3) => p3.as === "tile"), [panels]);
2238
2099
  const floatPanels = useMemo(() => (panels ?? []).filter((p3) => p3.as === "floating"), [panels]);
2239
2100
  const wantedIds = [
2240
- ...items.map((_2, i5) => ids?.[i5] ?? `lk-ws-${i5}`),
2101
+ ...items.map((_2, i4) => ids?.[i4] ?? `lk-ws-${i4}`),
2241
2102
  ...tilePanels.map((p3) => `lk-panel-${p3.key}`)
2242
2103
  ];
2243
2104
  const idKey = wantedIds.join(",");
@@ -2313,7 +2174,7 @@ function Workspace({
2313
2174
  [onReorder]
2314
2175
  );
2315
2176
  const chrome = useMemo(() => {
2316
- const byId = new Map(nodeIds.map((id, i5) => [id, items[i5]]));
2177
+ const byId = new Map(nodeIds.map((id, i4) => [id, items[i4]]));
2317
2178
  const panelByNode = new Map(
2318
2179
  tilePanels.map((p3) => [`lk-panel-${p3.key}`, p3])
2319
2180
  );
@@ -2379,7 +2240,7 @@ async function openStoredLab({ instruments, defaultInstrument, mode }, storageKe
2379
2240
  const marks = /* @__PURE__ */ new Map();
2380
2241
  await Promise.all(
2381
2242
  opened.store.getState().trials.map(async (trial) => {
2382
- const kept = instruments.find((i5) => i5.name === trial.instrumentName)?.annotations?.storage;
2243
+ const kept = instruments.find((i4) => i4.name === trial.instrumentName)?.annotations?.storage;
2383
2244
  if (!kept) return;
2384
2245
  try {
2385
2246
  marks.set(trial.id, await kept.load());
@@ -2429,9 +2290,9 @@ var NEBULA_SLOTS = [
2429
2290
  function buildNebula(list, theme, mode, density) {
2430
2291
  const ctx = { theme, resolved: resolveTheme(theme, { mode, density }) };
2431
2292
  const n5 = colorCount(list, ctx) ?? NEBULA_SLOTS.length;
2432
- const colors = Array.from({ length: n5 }, (_2, i5) => colorAt(list, i5, ctx));
2433
- const blobs = colors.map((c6, i5) => {
2434
- const p3 = NEBULA_SLOTS[i5 % NEBULA_SLOTS.length];
2293
+ const colors = Array.from({ length: n5 }, (_2, i4) => colorAt(list, i4, ctx));
2294
+ const blobs = colors.map((c6, i4) => {
2295
+ const p3 = NEBULA_SLOTS[i4 % NEBULA_SLOTS.length];
2435
2296
  return `radial-gradient(ellipse ${p3.sx} ${p3.sy} at ${p3.cx} ${p3.cy}, color-mix(in srgb, ${c6} 22%, transparent), transparent ${p3.stop})`;
2436
2297
  });
2437
2298
  blobs.push("radial-gradient(ellipse at center, #0a0a18 0%, #02020a 100%)");
@@ -2626,10 +2487,10 @@ function LabRuntime({
2626
2487
  [undockedPanels]
2627
2488
  );
2628
2489
  const resolvedMode = useResolvedColorMode(modeValue);
2629
- const annotates = instruments.some((i5) => i5.annotations != null);
2490
+ const annotationTools = useMemo(() => labAnnotationTools(instruments), [instruments]);
2630
2491
  const labChromeAll = useMemo(
2631
- () => labContributions([...annotates ? ANNOTATION_TOOLS : [], ...tools ?? []], labChrome),
2632
- [annotates, tools, labChrome]
2492
+ () => labContributions([...annotationTools, ...tools ?? []], labChrome),
2493
+ [annotationTools, tools, labChrome]
2633
2494
  );
2634
2495
  const hasFooterChrome = labChromeAll.some((c6) => c6.region === "footer");
2635
2496
  const hasPaneChrome = labChromeAll.some((c6) => c6.region === "sidebar" || c6.region === "aside");
@@ -2702,8 +2563,8 @@ function LabRuntime({
2702
2563
  store.getState().deleteSnapshot(snapshotId);
2703
2564
  },
2704
2565
  mode: modeValue,
2705
- setMode: (m3) => {
2706
- store.getState().setMode(m3);
2566
+ setMode: (m2) => {
2567
+ store.getState().setMode(m2);
2707
2568
  },
2708
2569
  configRules,
2709
2570
  controls
@@ -2915,8 +2776,8 @@ function ButtonsAndToggles() {
2915
2776
  /* @__PURE__ */ jsx(Ht, { status: "muted", children: "MUTED" })
2916
2777
  ] }) }),
2917
2778
  /* @__PURE__ */ jsx(Cell, { label: "Checkbox, Switch", children: /* @__PURE__ */ jsxs("div", { className: "lk-specimen__row", children: [
2918
- /* @__PURE__ */ jsx(o2, { isSelected: snap, onChange: setSnap, children: "Snap to grid" }),
2919
- /* @__PURE__ */ jsx(o2, { isIndeterminate: true, children: "Mixed" }),
2779
+ /* @__PURE__ */ jsx(o3, { isSelected: snap, onChange: setSnap, children: "Snap to grid" }),
2780
+ /* @__PURE__ */ jsx(o3, { isIndeterminate: true, children: "Mixed" }),
2920
2781
  /* @__PURE__ */ jsx(a6, { isSelected: wifi, onChange: setWifi, children: "Wifi" })
2921
2782
  ] }) }),
2922
2783
  /* @__PURE__ */ jsx(Cell, { label: "RadioGroup", children: /* @__PURE__ */ jsxs(l5, { label: "Snap mode", orientation: "horizontal", defaultValue: "grid", children: [
@@ -2989,9 +2850,9 @@ function ButtonsAndToggles() {
2989
2850
  ]
2990
2851
  }
2991
2852
  ),
2992
- /* @__PURE__ */ jsx(i3, { open, onToggle: () => setOpen((o4) => !o4), label: "Shapes" })
2853
+ /* @__PURE__ */ jsx(i2, { open, onToggle: () => setOpen((o4) => !o4), label: "Shapes" })
2993
2854
  ] }) }),
2994
- /* @__PURE__ */ jsx(Cell, { label: "Tabs", children: /* @__PURE__ */ jsxs(o4, { children: [
2855
+ /* @__PURE__ */ jsx(Cell, { label: "Tabs", children: /* @__PURE__ */ jsxs(o5, { children: [
2995
2856
  /* @__PURE__ */ jsxs(s6, { "aria-label": "Sections", children: [
2996
2857
  /* @__PURE__ */ jsx(c5, { id: "props", children: "Props" }),
2997
2858
  /* @__PURE__ */ jsx(c5, { id: "events", children: "Events" }),
@@ -3040,7 +2901,7 @@ function FieldsAndPickers() {
3040
2901
  /* @__PURE__ */ jsxs(Cell, { label: "NumberField, Select, ComboBox", children: [
3041
2902
  /* @__PURE__ */ jsx(g, { label: "Opacity", minValue: 0, maxValue: 100, step: 5, defaultValue: 80 }),
3042
2903
  /* @__PURE__ */ jsx(
3043
- T2,
2904
+ T,
3044
2905
  {
3045
2906
  label: "Color",
3046
2907
  defaultSelectedKey: "g",
@@ -3076,7 +2937,7 @@ function FieldsAndPickers() {
3076
2937
  }
3077
2938
  ),
3078
2939
  /* @__PURE__ */ jsx(
3079
- b,
2940
+ y,
3080
2941
  {
3081
2942
  ariaLabel: "Pair",
3082
2943
  min: 0,
@@ -3102,7 +2963,7 @@ function FieldsAndPickers() {
3102
2963
  }
3103
2964
  ),
3104
2965
  /* @__PURE__ */ jsx(
3105
- i4,
2966
+ i3,
3106
2967
  {
3107
2968
  "aria-label": "Width",
3108
2969
  min: 0,
@@ -3114,7 +2975,7 @@ function FieldsAndPickers() {
3114
2975
  ] }),
3115
2976
  /* @__PURE__ */ jsxs(Cell, { label: "ColorField, GradientEditor", children: [
3116
2977
  /* @__PURE__ */ jsx(l4, { value: color, alpha: true, onInput: setColor, onChange: setColor, "aria-label": "Color" }),
3117
- /* @__PURE__ */ jsx(C, { value: gradient, onInput: setGradient, onChange: setGradient, kindSwitch: true })
2978
+ /* @__PURE__ */ jsx(C2, { value: gradient, onInput: setGradient, onChange: setGradient, kindSwitch: true })
3118
2979
  ] }),
3119
2980
  /* @__PURE__ */ jsx(Cell, { label: "PaintInput", children: /* @__PURE__ */ jsx(
3120
2981
  S,
@@ -3146,9 +3007,9 @@ function PanelsAndRows() {
3146
3007
  ]);
3147
3008
  const [panelCollapsed, setPanelCollapsed] = useState(false);
3148
3009
  return /* @__PURE__ */ jsxs(Section, { title: "Panels & property rows", children: [
3149
- /* @__PURE__ */ jsx(Cell, { label: "PropertyPanel", children: /* @__PURE__ */ jsx(ae, { title: "Shape", children: /* @__PURE__ */ jsxs(oe2, { children: [
3010
+ /* @__PURE__ */ jsx(Cell, { label: "PropertyPanel", children: /* @__PURE__ */ jsx(ae2, { title: "Shape", children: /* @__PURE__ */ jsxs(oe, { children: [
3150
3011
  /* @__PURE__ */ jsx(
3151
- B,
3012
+ B2,
3152
3013
  {
3153
3014
  kind: "number",
3154
3015
  control: "slider",
@@ -3161,7 +3022,7 @@ function PanelsAndRows() {
3161
3022
  }
3162
3023
  ),
3163
3024
  /* @__PURE__ */ jsx(
3164
- B,
3025
+ B2,
3165
3026
  {
3166
3027
  kind: "number",
3167
3028
  control: "slider",
@@ -3174,7 +3035,7 @@ function PanelsAndRows() {
3174
3035
  }
3175
3036
  ),
3176
3037
  /* @__PURE__ */ jsx(
3177
- B,
3038
+ B2,
3178
3039
  {
3179
3040
  kind: "color",
3180
3041
  label: "Fill",
@@ -3184,10 +3045,21 @@ function PanelsAndRows() {
3184
3045
  onAlphaChange: setAlpha
3185
3046
  }
3186
3047
  ),
3187
- /* @__PURE__ */ jsx(B, { kind: "color", label: "Stroke", value: stroke, onChange: setStroke }),
3188
- /* @__PURE__ */ jsx(B, { kind: "number", label: "Count", value: count, min: 0, max: 100, step: 1, onChange: setCount }),
3048
+ /* @__PURE__ */ jsx(B2, { kind: "color", label: "Stroke", value: stroke, onChange: setStroke }),
3189
3049
  /* @__PURE__ */ jsx(
3190
- B,
3050
+ B2,
3051
+ {
3052
+ kind: "number",
3053
+ label: "Count",
3054
+ value: count,
3055
+ min: 0,
3056
+ max: 100,
3057
+ step: 1,
3058
+ onChange: setCount
3059
+ }
3060
+ ),
3061
+ /* @__PURE__ */ jsx(
3062
+ B2,
3191
3063
  {
3192
3064
  kind: "enum",
3193
3065
  label: "Line cap",
@@ -3200,7 +3072,7 @@ function PanelsAndRows() {
3200
3072
  }
3201
3073
  ),
3202
3074
  /* @__PURE__ */ jsx(
3203
- B,
3075
+ B2,
3204
3076
  {
3205
3077
  kind: "enum",
3206
3078
  control: "toggle",
@@ -3214,10 +3086,22 @@ function PanelsAndRows() {
3214
3086
  ]
3215
3087
  }
3216
3088
  ),
3217
- /* @__PURE__ */ jsx(B, { kind: "string", label: "Label", value: label, onChange: setLabel }),
3218
- /* @__PURE__ */ jsx(B, { kind: "boolean", label: "Visible", value: visible, onChange: setVisible }),
3219
- /* @__PURE__ */ jsx(b2, { title: "Bevel", defaultCollapsed: true, children: /* @__PURE__ */ jsx(B, { kind: "number", control: "slider", label: "Rings", value: 32, min: 4, max: 96, step: 1, onChange: () => {
3220
- } }) })
3089
+ /* @__PURE__ */ jsx(B2, { kind: "string", label: "Label", value: label, onChange: setLabel }),
3090
+ /* @__PURE__ */ jsx(B2, { kind: "boolean", label: "Visible", value: visible, onChange: setVisible }),
3091
+ /* @__PURE__ */ jsx(b2, { title: "Bevel", defaultCollapsed: true, children: /* @__PURE__ */ jsx(
3092
+ B2,
3093
+ {
3094
+ kind: "number",
3095
+ control: "slider",
3096
+ label: "Rings",
3097
+ value: 32,
3098
+ min: 4,
3099
+ max: 96,
3100
+ step: 1,
3101
+ onChange: () => {
3102
+ }
3103
+ }
3104
+ ) })
3221
3105
  ] }) }) }),
3222
3106
  /* @__PURE__ */ jsx(Cell, { label: "PrefsForm", children: /* @__PURE__ */ jsx(
3223
3107
  A2,
@@ -3255,7 +3139,7 @@ function OverlaysAndFeedback() {
3255
3139
  const calloutAnchor = useRef(null);
3256
3140
  const [calloutOpen, setCalloutOpen] = useState(false);
3257
3141
  const [dialogOpen, setDialogOpen] = useState(false);
3258
- const toasts = useMemo(() => m4(), []);
3142
+ const toasts = useMemo(() => m3(), []);
3259
3143
  return /* @__PURE__ */ jsxs(Section, { title: "Overlays & feedback", children: [
3260
3144
  /* @__PURE__ */ jsx(Cell, { label: "Tooltip, Callout, Dialog, Toast", children: /* @__PURE__ */ jsxs("div", { className: "lk-specimen__row", children: [
3261
3145
  /* @__PURE__ */ jsxs(l2, { children: [
@@ -3309,7 +3193,7 @@ function OverlaysAndFeedback() {
3309
3193
  /* @__PURE__ */ jsx(Cell, { label: "StatusBar", children: /* @__PURE__ */ jsxs(n7, { ariaLabel: "Editor status", children: [
3310
3194
  /* @__PURE__ */ jsx(r5, { children: "tool: select" }),
3311
3195
  /* @__PURE__ */ jsx(r5, { children: "sel: 3" }),
3312
- /* @__PURE__ */ jsx(i5, {}),
3196
+ /* @__PURE__ */ jsx(i4, {}),
3313
3197
  /* @__PURE__ */ jsx(r5, { muted: true, children: "0.7.0" })
3314
3198
  ] }) })
3315
3199
  ] });
@@ -3349,7 +3233,7 @@ function ToolChrome() {
3349
3233
  const [paneWidth, setPaneWidth] = useState(160);
3350
3234
  return /* @__PURE__ */ jsxs(Section, { title: "Tool chrome", children: [
3351
3235
  /* @__PURE__ */ jsx(Cell, { label: "ToolGroup, ToolButton", children: /* @__PURE__ */ jsx(n8, { orientation: "horizontal", ariaLabel: "Tools", children: ["select", "rect", "ellipse"].map((id) => /* @__PURE__ */ jsx(
3352
- o3,
3236
+ o4,
3353
3237
  {
3354
3238
  icon: /* @__PURE__ */ jsx(Dot, {}),
3355
3239
  label: id,
@@ -3476,7 +3360,7 @@ function EditorsAndPlots() {
3476
3360
  }
3477
3361
  ) }),
3478
3362
  /* @__PURE__ */ jsx(Cell, { label: "BandEditor", wide: true, children: /* @__PURE__ */ jsx(
3479
- k,
3363
+ k2,
3480
3364
  {
3481
3365
  min: 1 / 64,
3482
3366
  max: 1 / 2,
@@ -3486,7 +3370,7 @@ function EditorsAndPlots() {
3486
3370
  onChange: setBands,
3487
3371
  selectedIndex: band,
3488
3372
  onSelect: setBand,
3489
- renderBand: (b3) => b3.data.name,
3373
+ renderBand: (b2) => b2.data.name,
3490
3374
  ticks: [1 / 24, 1 / 12, 1 / 6].map((at) => ({ at, label: `1/${Math.round(1 / at)}` }))
3491
3375
  }
3492
3376
  ) }),
@@ -3554,6 +3438,6 @@ function Specimen({ className }) {
3554
3438
  ] });
3555
3439
  }
3556
3440
 
3557
- export { ANNOTATION_TOOLS, ANNOTATION_WEASEL_TOOLS, AnnotationOverlay, AnnotationTargets, Lab, LabBoundary, LabPalette, LabRoot, LabShell, LabSwitcher, SPECIMEN_SECTIONS, Specimen, Trial, TrialBody, TrialChrome, Workspace, addTrial, annotationToolInfo, annotationsFromJSON, capturePlan, captureTarget, cloneTrial, closeTrial, composeCaptureSvg, createAnnotationScene, createAnnotationStore, createMarkDrawOne, currentPage, defineInstrument, fitView, fracContains, fracEncloses, fracToWorld, fromWeaselView, interstellarTheme, isStale, markCommands, markSvgNodes, reorderTrials, resetTrial, resolveMarkStyle, roundFrac, seenFrom, toWeaselView, validateConfigSchema, worldToFrac };
3441
+ export { AnnotationOverlay, AnnotationTargets, Lab, LabBoundary, LabPalette, LabRoot, LabShell, LabSwitcher, SPECIMEN_SECTIONS, Specimen, Trial, TrialBody, TrialChrome, Workspace, addTrial, annotationsFromJSON, capturePlan, captureTarget, cloneTrial, closeTrial, composeCaptureSvg, createAnnotationScene, createAnnotationStore, createMarkDrawOne, currentPage, defineInstrument, fitView, fracContains, fracEncloses, fracToWorld, fromWeaselView, interstellarTheme, isStale, reorderTrials, resetTrial, resolveMarkStyle, roundFrac, seenFrom, toWeaselView, validateConfigSchema, worldToFrac };
3558
3442
  //# sourceMappingURL=index.js.map
3559
3443
  //# sourceMappingURL=index.js.map