@weasel-js/ui 1.8.0 → 1.8.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 (247) hide show
  1. package/dist/chunks/{ActionBar-xA73vzzF.js → ActionBar-CfXS7-9f.js} +2 -2
  2. package/dist/chunks/{ActionBar-xA73vzzF.js.map → ActionBar-CfXS7-9f.js.map} +1 -1
  3. package/dist/chunks/{Badge-jYQjrTKc.js → Badge-4ShpqA0h.js} +2 -2
  4. package/dist/chunks/{Badge-jYQjrTKc.js.map → Badge-4ShpqA0h.js.map} +1 -1
  5. package/dist/chunks/{Badge-CTc9Lkwn.js → Badge-qkV9EqKs.js} +6 -2
  6. package/dist/chunks/Badge-qkV9EqKs.js.map +1 -0
  7. package/dist/chunks/{Button-XB-T75YL.js → Button-CQA-K1g9.js} +17 -17
  8. package/dist/chunks/Button-CQA-K1g9.js.map +1 -0
  9. package/dist/chunks/Button-KF-qSGtA.js +11 -0
  10. package/dist/chunks/Button-KF-qSGtA.js.map +1 -0
  11. package/dist/chunks/{ButtonBar-CIMKPPRS.js → ButtonBar-B-cYuoem.js} +10 -4
  12. package/dist/chunks/ButtonBar-B-cYuoem.js.map +1 -0
  13. package/dist/chunks/{Callout-DpTO3fkb.js → Callout-VyYDIP7w.js} +18 -18
  14. package/dist/chunks/Callout-VyYDIP7w.js.map +1 -0
  15. package/dist/chunks/{CloseButton-wb7Or5Eg.js → CloseButton-CKarkTT9.js} +3 -3
  16. package/dist/chunks/{CloseButton-wb7Or5Eg.js.map → CloseButton-CKarkTT9.js.map} +1 -1
  17. package/dist/chunks/{Code-AsKpgnv6.js → Code-ChwKP1V0.js} +8 -2
  18. package/dist/chunks/Code-ChwKP1V0.js.map +1 -0
  19. package/dist/chunks/{ColorModeControl-DET6Itwq.js → ColorModeControl-CH9PmDlT.js} +6 -6
  20. package/dist/chunks/{ColorModeControl-DET6Itwq.js.map → ColorModeControl-CH9PmDlT.js.map} +1 -1
  21. package/dist/chunks/{ComboBox-DKln_mOd.js → ComboBox-BMj_IKBj.js} +4 -4
  22. package/dist/chunks/ComboBox-BMj_IKBj.js.map +1 -0
  23. package/dist/chunks/{DataGrid-B6IS9vUk.js → DataGrid-CjiVKoaA.js} +2 -2
  24. package/dist/chunks/{DataGrid-B6IS9vUk.js.map → DataGrid-CjiVKoaA.js.map} +1 -1
  25. package/dist/chunks/{Dialog-h-5MeYpu.js → Dialog-Du4POZ52.js} +5 -5
  26. package/dist/chunks/Dialog-Du4POZ52.js.map +1 -0
  27. package/dist/chunks/{DragGhost-BeYDJyLZ.js → DragGhost-_IpuN_xM.js} +2 -2
  28. package/dist/chunks/{DragGhost-BeYDJyLZ.js.map → DragGhost-_IpuN_xM.js.map} +1 -1
  29. package/dist/chunks/{FallthroughDiagram-CS1IhQaU.js → FallthroughDiagram-Cn6QLWKA.js} +9 -9
  30. package/dist/chunks/{FallthroughDiagram-CS1IhQaU.js.map → FallthroughDiagram-Cn6QLWKA.js.map} +1 -1
  31. package/dist/chunks/{FillStrokeSwatch-C4h3rUFM.js → FillStrokeSwatch-BkUhlpQL.js} +2 -2
  32. package/dist/chunks/{FillStrokeSwatch-C4h3rUFM.js.map → FillStrokeSwatch-BkUhlpQL.js.map} +1 -1
  33. package/dist/chunks/{FontFamilySelect-DEvMXyZd.js → FontFamilySelect-CXN7O2-p.js} +2 -2
  34. package/dist/chunks/{FontFamilySelect-DEvMXyZd.js.map → FontFamilySelect-CXN7O2-p.js.map} +1 -1
  35. package/dist/chunks/{FontWeightSelect-BLQ_LMJF.js → FontWeightSelect-BBuJGe_2.js} +2 -2
  36. package/dist/chunks/{FontWeightSelect-BLQ_LMJF.js.map → FontWeightSelect-BBuJGe_2.js.map} +1 -1
  37. package/dist/chunks/{GestureRoute-BXESrHI0.js → GestureRoute-BqHUrGeQ.js} +13 -13
  38. package/dist/chunks/{GestureRoute-BXESrHI0.js.map → GestureRoute-BqHUrGeQ.js.map} +1 -1
  39. package/dist/chunks/{GradientEditor-vz771M-N.js → GradientEditor-DX4sb1Hf.js} +3 -3
  40. package/dist/chunks/{GradientEditor-vz771M-N.js.map → GradientEditor-DX4sb1Hf.js.map} +1 -1
  41. package/dist/chunks/{Icon-DPRUIo3G.js → Icon-BfqYtAX5.js} +30 -1
  42. package/dist/chunks/Icon-BfqYtAX5.js.map +1 -0
  43. package/dist/chunks/{ItemList-CRu9y7hL.js → ItemList-nbakLf3N.js} +32 -32
  44. package/dist/chunks/ItemList-nbakLf3N.js.map +1 -0
  45. package/dist/chunks/{Jog-TE6QI9i1.js → Jog-BU0xuM3G.js} +6 -6
  46. package/dist/chunks/{Jog-TE6QI9i1.js.map → Jog-BU0xuM3G.js.map} +1 -1
  47. package/dist/chunks/{Keycaps-C-FJyG8k.js → Keycaps-CM-gOj0e.js} +8 -2
  48. package/dist/chunks/Keycaps-CM-gOj0e.js.map +1 -0
  49. package/dist/chunks/LayerList-vfAoImxX.js +432 -0
  50. package/dist/chunks/LayerList-vfAoImxX.js.map +1 -0
  51. package/dist/chunks/{ListEditor-DGtwj99m.js → ListEditor-BAKs47bN.js} +3 -3
  52. package/dist/chunks/{ListEditor-DGtwj99m.js.map → ListEditor-BAKs47bN.js.map} +1 -1
  53. package/dist/chunks/{MenuButton-TAFg88Lp.js → MenuButton-CJGdhwGr.js} +5 -5
  54. package/dist/chunks/MenuButton-CJGdhwGr.js.map +1 -0
  55. package/dist/chunks/{MeshEditor-8CRsu-Td.js → MeshEditor-rhf7cXfG.js} +2 -2
  56. package/dist/chunks/{MeshEditor-8CRsu-Td.js.map → MeshEditor-rhf7cXfG.js.map} +1 -1
  57. package/dist/chunks/{OptionsBar-DeTAjVb7.js → OptionsBar-DyTXbev-.js} +9 -3
  58. package/dist/chunks/OptionsBar-DyTXbev-.js.map +1 -0
  59. package/dist/chunks/{PaintField-DX4uYlF9.js → PaintField--GbF8sL7.js} +7 -7
  60. package/dist/chunks/PaintField--GbF8sL7.js.map +1 -0
  61. package/dist/chunks/{PaintInput-CWyOJXUM.js → PaintInput-DSS5IjXn.js} +5 -5
  62. package/dist/chunks/{PaintInput-CWyOJXUM.js.map → PaintInput-DSS5IjXn.js.map} +1 -1
  63. package/dist/chunks/{PatternPicker-0j51aDJ3.js → PatternPicker-82DCUvUk.js} +2 -2
  64. package/dist/chunks/{PatternPicker-0j51aDJ3.js.map → PatternPicker-82DCUvUk.js.map} +1 -1
  65. package/dist/chunks/{Powerline-6wIFmDik.js → Powerline-CogJv9VU.js} +2 -2
  66. package/dist/chunks/{Powerline-6wIFmDik.js.map → Powerline-CogJv9VU.js.map} +1 -1
  67. package/dist/chunks/{Prefs-gbjYqvSD.js → Prefs-BSSKOvPa.js} +41 -41
  68. package/dist/chunks/Prefs-BSSKOvPa.js.map +1 -0
  69. package/dist/chunks/{Properties-BbNuMiic.js → Properties-DteSVEWs.js} +4 -4
  70. package/dist/chunks/{Properties-BbNuMiic.js.map → Properties-DteSVEWs.js.map} +1 -1
  71. package/dist/chunks/{PropertyField-CWUtNK1w.js → PropertyField-CLbUOynA.js} +67 -67
  72. package/dist/chunks/PropertyField-CLbUOynA.js.map +1 -0
  73. package/dist/chunks/{Select-ouV8O6cp.js → Select-BhHwjNsb.js} +13 -13
  74. package/dist/chunks/Select-BhHwjNsb.js.map +1 -0
  75. package/dist/chunks/{SelectionPanel-BpUqP75b.js → SelectionPanel-B6HinSdB.js} +2 -2
  76. package/dist/chunks/{SelectionPanel-BpUqP75b.js.map → SelectionPanel-B6HinSdB.js.map} +1 -1
  77. package/dist/chunks/{SidebarPanel--dJ-k9-V.js → SidebarPanel-P3a8tIIj.js} +2 -2
  78. package/dist/chunks/{SidebarPanel--dJ-k9-V.js.map → SidebarPanel-P3a8tIIj.js.map} +1 -1
  79. package/dist/chunks/{StatusBar-BEOfOX0D.js → StatusBar-DEh7J2Gj.js} +14 -9
  80. package/dist/chunks/StatusBar-DEh7J2Gj.js.map +1 -0
  81. package/dist/chunks/{SwatchStrip-BY6A511W.js → SwatchStrip-D7YNn_p0.js} +2 -2
  82. package/dist/chunks/{SwatchStrip-BY6A511W.js.map → SwatchStrip-D7YNn_p0.js.map} +1 -1
  83. package/dist/chunks/{ThemeSwitcher-tnATkIo1.js → ThemeSwitcher-BJWP1l87.js} +6 -6
  84. package/dist/chunks/{ThemeSwitcher-tnATkIo1.js.map → ThemeSwitcher-BJWP1l87.js.map} +1 -1
  85. package/dist/chunks/{Timeline-FlLUm8nd.js → Timeline-CisRg82u.js} +2 -2
  86. package/dist/chunks/{Timeline-FlLUm8nd.js.map → Timeline-CisRg82u.js.map} +1 -1
  87. package/dist/chunks/{Toast-CuHkT0x0.js → Toast-DhkU9Z0b.js} +3 -3
  88. package/dist/chunks/{Toast-CuHkT0x0.js.map → Toast-DhkU9Z0b.js.map} +1 -1
  89. package/dist/chunks/ToggleBar-CRc2k89_.js +10 -0
  90. package/dist/chunks/ToggleBar-CRc2k89_.js.map +1 -0
  91. package/dist/chunks/{ToggleBar-BZ4Gk1IU.js → ToggleBar-CfYbMK3x.js} +9 -9
  92. package/dist/chunks/ToggleBar-CfYbMK3x.js.map +1 -0
  93. package/dist/chunks/{TokenPanel-DongdiZM.js → TokenPanel-cL37E39j.js} +5 -5
  94. package/dist/chunks/{TokenPanel-DongdiZM.js.map → TokenPanel-cL37E39j.js.map} +1 -1
  95. package/dist/chunks/{ToolButton-BURp4YIO.js → ToolButton-Bo7WH1wt.js} +2 -2
  96. package/dist/chunks/{ToolButton-BURp4YIO.js.map → ToolButton-Bo7WH1wt.js.map} +1 -1
  97. package/dist/chunks/{ToolOptionsBar-wTPJFfOn.js → ToolOptionsBar-DmhzrOmd.js} +2 -2
  98. package/dist/chunks/{ToolOptionsBar-wTPJFfOn.js.map → ToolOptionsBar-DmhzrOmd.js.map} +1 -1
  99. package/dist/chunks/{ToolPalette-DKDFWOX-.js → ToolPalette-BTD84k9C.js} +2 -2
  100. package/dist/chunks/{ToolPalette-DKDFWOX-.js.map → ToolPalette-BTD84k9C.js.map} +1 -1
  101. package/dist/chunks/{Tooltip-C6eFCYxw.js → Tooltip-DljsPEQG.js} +4 -4
  102. package/dist/chunks/Tooltip-DljsPEQG.js.map +1 -0
  103. package/dist/chunks/Tree-B_PW6K-W.js +215 -0
  104. package/dist/chunks/Tree-B_PW6K-W.js.map +1 -0
  105. package/dist/chunks/{icons-CofIOTiI.js → icons-B_fPKEis.js} +52 -43
  106. package/dist/chunks/icons-B_fPKEis.js.map +1 -0
  107. package/dist/chunks/{model-qQj8Ny9w.js → model-Ca0f95r0.js} +5 -5
  108. package/dist/chunks/{model-qQj8Ny9w.js.map → model-Ca0f95r0.js.map} +1 -1
  109. package/dist/chunks/{portalHost-CE70wLzo.js → portalHost-RUQPxIoW.js} +3 -2
  110. package/dist/chunks/{portalHost-CE70wLzo.js.map → portalHost-RUQPxIoW.js.map} +1 -1
  111. package/dist/chunks/{prefField-CCm_nzlM.js → prefField-DPPbAmRR.js} +3 -3
  112. package/dist/chunks/{prefField-CCm_nzlM.js.map → prefField-DPPbAmRR.js.map} +1 -1
  113. package/dist/chunks/{segmentTooltip-CGxCOWNz.js → segmentTooltip-8VBPNgEc.js} +2 -2
  114. package/dist/chunks/{segmentTooltip-CGxCOWNz.js.map → segmentTooltip-8VBPNgEc.js.map} +1 -1
  115. package/dist/chunks/segmentedControl.module-62qjNWJk.js +11 -0
  116. package/dist/chunks/{segmentedControl.module-BzGXUL5G.js.map → segmentedControl.module-62qjNWJk.js.map} +1 -1
  117. package/dist/chunks/{useReorderDragList-CStYKjHl.js → useReorderDragList-DnqqvRGK.js} +38 -30
  118. package/dist/chunks/useReorderDragList-DnqqvRGK.js.map +1 -0
  119. package/dist/components/ActionBar/index.js +1 -1
  120. package/dist/components/Badge/index.d.ts +1 -0
  121. package/dist/components/Badge/index.d.ts.map +1 -1
  122. package/dist/components/Badge/index.js +3 -3
  123. package/dist/components/Badge/variantIcons.d.ts +5 -0
  124. package/dist/components/Badge/variantIcons.d.ts.map +1 -0
  125. package/dist/components/Button/index.d.ts +1 -0
  126. package/dist/components/Button/index.d.ts.map +1 -1
  127. package/dist/components/Button/index.js +3 -2
  128. package/dist/components/Button/variantIcons.d.ts +5 -0
  129. package/dist/components/Button/variantIcons.d.ts.map +1 -0
  130. package/dist/components/ButtonBar/index.d.ts +1 -0
  131. package/dist/components/ButtonBar/index.d.ts.map +1 -1
  132. package/dist/components/ButtonBar/index.js +2 -2
  133. package/dist/components/ButtonBar/variantIcons.d.ts +5 -0
  134. package/dist/components/ButtonBar/variantIcons.d.ts.map +1 -0
  135. package/dist/components/Callout/Callout.d.ts.map +1 -1
  136. package/dist/components/Callout/index.js +1 -1
  137. package/dist/components/CloseButton/index.js +1 -1
  138. package/dist/components/Code/index.d.ts +1 -0
  139. package/dist/components/Code/index.d.ts.map +1 -1
  140. package/dist/components/Code/index.js +2 -2
  141. package/dist/components/Code/variantIcons.d.ts +5 -0
  142. package/dist/components/Code/variantIcons.d.ts.map +1 -0
  143. package/dist/components/ColorModeControl/index.js +1 -1
  144. package/dist/components/ComboBox/ComboBox.d.ts.map +1 -1
  145. package/dist/components/ComboBox/index.js +1 -1
  146. package/dist/components/DataGrid/index.js +1 -1
  147. package/dist/components/Dialog/Dialog.d.ts.map +1 -1
  148. package/dist/components/Dialog/index.js +1 -1
  149. package/dist/components/DragGhost/index.js +1 -1
  150. package/dist/components/FallthroughDiagram/index.js +1 -1
  151. package/dist/components/FillStrokeSwatch/index.js +1 -1
  152. package/dist/components/FontFamilySelect/index.js +1 -1
  153. package/dist/components/FontWeightSelect/index.js +1 -1
  154. package/dist/components/GestureRoute/index.js +1 -1
  155. package/dist/components/GradientEditor/index.js +1 -1
  156. package/dist/components/ItemList/index.js +1 -1
  157. package/dist/components/Jog/index.js +1 -1
  158. package/dist/components/Keycaps/index.d.ts +1 -0
  159. package/dist/components/Keycaps/index.d.ts.map +1 -1
  160. package/dist/components/Keycaps/index.js +2 -2
  161. package/dist/components/Keycaps/variantIcons.d.ts +5 -0
  162. package/dist/components/Keycaps/variantIcons.d.ts.map +1 -0
  163. package/dist/components/LayerList/LayerList.d.ts.map +1 -1
  164. package/dist/components/LayerList/index.js +1 -1
  165. package/dist/components/ListEditor/index.js +1 -1
  166. package/dist/components/MenuButton/MenuButton.d.ts.map +1 -1
  167. package/dist/components/MenuButton/index.js +1 -1
  168. package/dist/components/MeshEditor/index.js +1 -1
  169. package/dist/components/OptionsBar/index.d.ts +1 -0
  170. package/dist/components/OptionsBar/index.d.ts.map +1 -1
  171. package/dist/components/OptionsBar/index.js +2 -2
  172. package/dist/components/OptionsBar/variantIcons.d.ts +5 -0
  173. package/dist/components/OptionsBar/variantIcons.d.ts.map +1 -0
  174. package/dist/components/PaintField/PaintField.d.ts.map +1 -1
  175. package/dist/components/PaintField/index.js +1 -1
  176. package/dist/components/PaintInput/index.js +1 -1
  177. package/dist/components/PatternPicker/index.js +1 -1
  178. package/dist/components/Powerline/index.js +2 -2
  179. package/dist/components/Prefs/index.js +2 -2
  180. package/dist/components/Properties/index.js +2 -2
  181. package/dist/components/Select/Select.d.ts.map +1 -1
  182. package/dist/components/Select/index.js +1 -1
  183. package/dist/components/SelectionPanel/index.js +2 -2
  184. package/dist/components/SidebarPanel/index.js +1 -1
  185. package/dist/components/StatusBar/StatusBar.d.ts +2 -0
  186. package/dist/components/StatusBar/StatusBar.d.ts.map +1 -1
  187. package/dist/components/StatusBar/index.js +1 -1
  188. package/dist/components/SwatchStrip/index.js +1 -1
  189. package/dist/components/ThemeSwitcher/index.js +1 -1
  190. package/dist/components/Timeline/index.js +1 -1
  191. package/dist/components/Toast/index.js +1 -1
  192. package/dist/components/ToggleBar/index.d.ts +1 -0
  193. package/dist/components/ToggleBar/index.d.ts.map +1 -1
  194. package/dist/components/ToggleBar/index.js +3 -2
  195. package/dist/components/ToggleBar/variantIcons.d.ts +5 -0
  196. package/dist/components/ToggleBar/variantIcons.d.ts.map +1 -0
  197. package/dist/components/TokenPanel/index.js +1 -1
  198. package/dist/components/ToolButton/index.js +1 -1
  199. package/dist/components/ToolOptionsBar/index.js +1 -1
  200. package/dist/components/ToolPalette/index.js +1 -1
  201. package/dist/components/Tooltip/Tooltip.d.ts.map +1 -1
  202. package/dist/components/Tooltip/index.js +1 -1
  203. package/dist/components/Tree/Tree.d.ts +1 -1
  204. package/dist/components/Tree/Tree.d.ts.map +1 -1
  205. package/dist/components/Tree/index.js +1 -1
  206. package/dist/icons/index.d.ts +6 -0
  207. package/dist/icons/index.d.ts.map +1 -1
  208. package/dist/icons/paths.d.ts +12 -0
  209. package/dist/icons/paths.d.ts.map +1 -1
  210. package/dist/index.js +100 -98
  211. package/dist/index.js.map +1 -1
  212. package/dist/overlays/portalHost.d.ts +10 -4
  213. package/dist/overlays/portalHost.d.ts.map +1 -1
  214. package/dist/style.css +1 -1
  215. package/dist/useReorderDragList.d.ts +3 -0
  216. package/dist/useReorderDragList.d.ts.map +1 -1
  217. package/package.json +10 -9
  218. package/dist/chunks/Badge-CTc9Lkwn.js.map +0 -1
  219. package/dist/chunks/Button-XB-T75YL.js.map +0 -1
  220. package/dist/chunks/ButtonBar-CIMKPPRS.js.map +0 -1
  221. package/dist/chunks/Callout-DpTO3fkb.js.map +0 -1
  222. package/dist/chunks/Code-AsKpgnv6.js.map +0 -1
  223. package/dist/chunks/ComboBox-DKln_mOd.js.map +0 -1
  224. package/dist/chunks/Dialog-h-5MeYpu.js.map +0 -1
  225. package/dist/chunks/Icon-DPRUIo3G.js.map +0 -1
  226. package/dist/chunks/ItemList-CRu9y7hL.js.map +0 -1
  227. package/dist/chunks/Keycaps-C-FJyG8k.js.map +0 -1
  228. package/dist/chunks/LayerList-BXTAjK-4.js +0 -421
  229. package/dist/chunks/LayerList-BXTAjK-4.js.map +0 -1
  230. package/dist/chunks/MenuButton-TAFg88Lp.js.map +0 -1
  231. package/dist/chunks/OptionsBar-DeTAjVb7.js.map +0 -1
  232. package/dist/chunks/PaintField-DX4uYlF9.js.map +0 -1
  233. package/dist/chunks/Prefs-gbjYqvSD.js.map +0 -1
  234. package/dist/chunks/PropertyField-CWUtNK1w.js.map +0 -1
  235. package/dist/chunks/Select-ouV8O6cp.js.map +0 -1
  236. package/dist/chunks/StatusBar-BEOfOX0D.js.map +0 -1
  237. package/dist/chunks/ToggleBar-BZ4Gk1IU.js.map +0 -1
  238. package/dist/chunks/Tooltip-C6eFCYxw.js.map +0 -1
  239. package/dist/chunks/Tree-hzIbj2q1.js +0 -203
  240. package/dist/chunks/Tree-hzIbj2q1.js.map +0 -1
  241. package/dist/chunks/icons-CofIOTiI.js.map +0 -1
  242. package/dist/chunks/interactiveTarget-BNZmTow2.js +0 -24
  243. package/dist/chunks/interactiveTarget-BNZmTow2.js.map +0 -1
  244. package/dist/chunks/segmentedControl.module-BzGXUL5G.js +0 -11
  245. package/dist/chunks/useReorderDragList-CStYKjHl.js.map +0 -1
  246. package/dist/interactiveTarget.d.ts +0 -9
  247. package/dist/interactiveTarget.d.ts.map +0 -1
@@ -1,6 +1,6 @@
1
- import { n as e, t } from "./interactiveTarget-BNZmTow2.js";
2
- import { t as n } from "./DragGhost-BeYDJyLZ.js";
3
- import { t as r } from "./ItemList.module-BSpCSxan.js";
1
+ import { t as e } from "./DragGhost-_IpuN_xM.js";
2
+ import { t } from "./ItemList.module-BSpCSxan.js";
3
+ import { CONTROL_SELECTOR as n, isInControlWithin as r } from "@weasel-js/core";
4
4
  import { Fragment as i, jsx as a, jsxs as o } from "react/jsx-runtime";
5
5
  import { forwardRef as s, useCallback as c, useLayoutEffect as l, useRef as u, useState as d } from "react";
6
6
  //#region src/components/ItemList/ItemList.tsx
@@ -28,15 +28,15 @@ var f = {
28
28
  let t = j.current.get(e);
29
29
  t && document.activeElement !== t && t.focus();
30
30
  }), l(() => {
31
- if (E === "grid") for (let e of j.current.values()) (e.parentElement?.querySelector(`.${r.trailing}`))?.querySelectorAll(t).forEach((e) => e.setAttribute("tabindex", "-1"));
31
+ if (E === "grid") for (let e of j.current.values()) (e.parentElement?.querySelector(`.${t.trailing}`))?.querySelectorAll(n).forEach((e) => e.setAttribute("tabindex", "-1"));
32
32
  });
33
- let R = [r.list, g].filter(Boolean).join(" ");
33
+ let R = [t.list, g].filter(Boolean).join(" ");
34
34
  if (s.length === 0) return /* @__PURE__ */ a("div", {
35
35
  className: R,
36
36
  ref: A,
37
37
  ...C,
38
38
  children: /* @__PURE__ */ a("div", {
39
- className: r.empty,
39
+ className: t.empty,
40
40
  children: p ?? "—"
41
41
  })
42
42
  });
@@ -51,17 +51,17 @@ var f = {
51
51
  }
52
52
  let i = s.findIndex((e) => e.id === F.current);
53
53
  i < 0 && (F.current = e.id, i = s.indexOf(e)), I.current = s[r].id, z(r), I.current = null, b(s.slice(Math.min(i, r), Math.max(i, r) + 1).map((e) => e.id));
54
- }, H = (e, n) => (i) => {
54
+ }, H = (e, r) => (i) => {
55
55
  if (e.rowProps?.onKeyDown?.(i), i.defaultPrevented) return;
56
56
  let a = j.current.get(e.id);
57
57
  if (!a) return;
58
- let o = i.target === a, c = E === "grid" ? i.currentTarget.querySelector(`.${r.trailing}`) : null;
58
+ let o = i.target === a, c = E === "grid" ? i.currentTarget.querySelector(`.${t.trailing}`) : null;
59
59
  if (o || c?.contains(i.target)) switch (i.key) {
60
60
  case "ArrowDown":
61
61
  case "ArrowUp": {
62
62
  i.preventDefault();
63
63
  let t = i.key === "ArrowDown" ? 1 : -1;
64
- i.altKey && y && o ? (P.current = e.id, y(e.id, n, t)) : V(e, n + t, i.shiftKey);
64
+ i.altKey && y && o ? (P.current = e.id, y(e.id, r, t)) : V(e, r + t, i.shiftKey);
65
65
  return;
66
66
  }
67
67
  case "Home":
@@ -72,26 +72,26 @@ var f = {
72
72
  case "Enter":
73
73
  case " ":
74
74
  if (!o) return;
75
- i.preventDefault(), F.current = e.id, v?.(e.id, n, m(i));
75
+ i.preventDefault(), F.current = e.id, v?.(e.id, r, m(i));
76
76
  return;
77
77
  case "ArrowRight":
78
78
  case "ArrowLeft":
79
79
  case "Escape": {
80
80
  if (!c) return;
81
- let e = Array.from(c.querySelectorAll(t)).filter((e) => !e.matches(":disabled"));
81
+ let e = Array.from(c.querySelectorAll(n)).filter((e) => !e.matches(":disabled"));
82
82
  if (o) {
83
83
  if (i.key !== "ArrowRight" || !e[0]) return;
84
84
  i.preventDefault(), e[0].focus();
85
85
  return;
86
86
  }
87
87
  i.preventDefault();
88
- let n = e.findIndex((e) => e.contains(i.target));
89
- i.key === "ArrowRight" ? e[n + 1]?.focus() : i.key === "ArrowLeft" && n > 0 ? e[n - 1]?.focus() : a.focus();
88
+ let t = e.findIndex((e) => e.contains(i.target));
89
+ i.key === "ArrowRight" ? e[t + 1]?.focus() : i.key === "ArrowLeft" && t > 0 ? e[t - 1]?.focus() : a.focus();
90
90
  return;
91
91
  }
92
92
  }
93
- }, U = (t, n) => (r) => {
94
- t.rowProps?.onClick?.(r), !(r.defaultPrevented || e(r.target, r.currentTarget)) && (F.current = t.id, v?.(t.id, n, m(r)));
93
+ }, U = (e, t) => (n) => {
94
+ e.rowProps?.onClick?.(n), !(n.defaultPrevented || r(n.target, n.currentTarget)) && (F.current = e.id, v?.(e.id, t, m(n)));
95
95
  }, W = (e) => (t) => {
96
96
  e.rowProps?.onFocus?.(t), t.target === j.current.get(e.id) && (N(e.id), I.current !== e.id && (F.current = e.id));
97
97
  }, G = (e) => (t) => {
@@ -105,48 +105,48 @@ var f = {
105
105
  "aria-multiselectable": _ === "multi" && E !== "list" || void 0,
106
106
  children: [
107
107
  S,
108
- w && O ? /* @__PURE__ */ a(n, {
108
+ w && O ? /* @__PURE__ */ a(e, {
109
109
  at: w,
110
110
  from: O,
111
111
  children: s.filter((e) => w.ids.includes(e.id)).map((e) => /* @__PURE__ */ o("div", {
112
- className: [r.row, e.selected && r.selected].filter(Boolean).join(" "),
112
+ className: [t.row, e.selected && t.selected].filter(Boolean).join(" "),
113
113
  children: [e.leading, /* @__PURE__ */ a("span", {
114
- className: r.label,
114
+ className: t.label,
115
115
  children: e.label
116
116
  })]
117
117
  }, e.id))
118
118
  }) : null,
119
- s.map((e, t) => {
120
- let n = D ? e.id === L ? 0 : -1 : void 0, c = /* @__PURE__ */ o(i, { children: [e.leading, /* @__PURE__ */ a("span", {
121
- className: r.label,
119
+ s.map((e, n) => {
120
+ let r = D ? e.id === L ? 0 : -1 : void 0, c = /* @__PURE__ */ o(i, { children: [e.leading, /* @__PURE__ */ a("span", {
121
+ className: t.label,
122
122
  children: e.label
123
123
  })] });
124
124
  return /* @__PURE__ */ a("div", {
125
125
  className: [
126
- r.row,
127
- e.selected && r.selected,
128
- e.muted && r.muted,
126
+ t.row,
127
+ e.selected && t.selected,
128
+ e.muted && t.muted,
129
129
  e.className
130
130
  ].filter(Boolean).join(" "),
131
131
  ...e.rowProps,
132
132
  role: K.row,
133
133
  "aria-selected": _ && E !== "list" ? !!e.selected : void 0,
134
134
  ref: E === "listbox" ? G(e.id) : void 0,
135
- tabIndex: E === "listbox" ? n : e.rowProps?.tabIndex,
136
- onKeyDown: D ? H(e, t) : e.rowProps?.onKeyDown,
137
- onClick: D ? U(e, t) : e.rowProps?.onClick,
135
+ tabIndex: E === "listbox" ? r : e.rowProps?.tabIndex,
136
+ onKeyDown: D ? H(e, n) : e.rowProps?.onKeyDown,
137
+ onClick: D ? U(e, n) : e.rowProps?.onClick,
138
138
  onFocus: D ? W(e) : e.rowProps?.onFocus,
139
- "data-drop": h(x, t, s.length),
139
+ "data-drop": h(x, n, s.length),
140
140
  "data-dragging": e.dragging ? "true" : void 0,
141
141
  children: E === "grid" ? /* @__PURE__ */ o(i, { children: [/* @__PURE__ */ a("div", {
142
142
  role: "gridcell",
143
- className: r.cell,
143
+ className: t.cell,
144
144
  ref: G(e.id),
145
- tabIndex: n,
145
+ tabIndex: r,
146
146
  children: c
147
147
  }), e.trailing != null && /* @__PURE__ */ a("div", {
148
148
  role: "gridcell",
149
- className: r.trailing,
149
+ className: t.trailing,
150
150
  children: e.trailing
151
151
  })] }) : c
152
152
  }, e.id);
@@ -171,4 +171,4 @@ function h(e, t, n) {
171
171
  //#endregion
172
172
  export { p as t };
173
173
 
174
- //# sourceMappingURL=ItemList-CRu9y7hL.js.map
174
+ //# sourceMappingURL=ItemList-nbakLf3N.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ItemList-nbakLf3N.js","names":["s","_Fragment","DragGhost","ROLES","ItemList","forwardRef","mode","rows","r","onActivate","selection","interactive","container","setContainer","useState","setRefs","useCallback","el","ref","targets","useRef","focusId","setFocusId","pendingFocus","anchor","extending","stopId","useLayoutEffect","id","target","ItemList_module_default","CONTROL_SELECTOR","c","cls","className","containerProps","empty","focusRow","row","index","ranges","onSelectRange","moveTo","to","extend","at","from","onKeyDown","e","onTarget","controlCell","delta","onNudge","i","modsOf","controls","onClick","isInControlWithin","onFocus","targetRef","roles","overlay","ghost","tabIndex","content","Fragment","dropSide","dropIndex","count"],"sources":["../../src/components/ItemList/ItemList.tsx"],"sourcesContent":["import {\n forwardRef,\n useCallback,\n useLayoutEffect,\n useRef,\n useState,\n type FocusEvent,\n type HTMLAttributes,\n type KeyboardEvent,\n type MouseEvent,\n type ReactNode,\n type Ref,\n} from 'react';\nimport { CONTROL_SELECTOR, isInControlWithin } from '@weasel-js/core';\nimport type { PressModifiers, ReorderGhost } from '../../useReorderDragList';\nimport { DragGhost } from '../DragGhost';\nimport s from './ItemList.module.css';\n\n/** One row. `id` is the React key. */\nexport interface ItemListRow {\n id: string;\n label: ReactNode;\n /** Fixed-size decoration before the label — a color swatch. Not a control:\n * those go in `trailing`. */\n leading?: ReactNode;\n /** Buttons and toggles after the label — visibility, lock. They keep their\n * own clicks and keys, and turn the list into a grid. A control that edits\n * with the arrow keys does not belong here. */\n trailing?: ReactNode;\n /** The row the list considers current. With `selection` set this is also\n * `aria-selected`. */\n selected?: boolean;\n /** Present but not in effect — history's redo entries. */\n muted?: boolean;\n /** Part of a drag in progress — `useReorderDragList`'s `state.draggedIds`. */\n dragging?: boolean;\n /** Consumer classes for states this component has no opinion about. */\n className?: string;\n /** Handlers and data attributes for this row's element. `data-*` is\n * spelled out because `HTMLAttributes` does not admit it, and every\n * consumer here marks its rows up with one. A handler here runs before the\n * list's own, and `preventDefault()` in it keeps the list out. */\n rowProps?: HTMLAttributes<HTMLDivElement> & Record<`data-${string}`, unknown>;\n}\n\n/** Props for {@link ItemList}. */\nexport interface ItemListProps {\n rows: readonly ItemListRow[];\n /** Shown in place of the rows when there are none. */\n empty?: ReactNode;\n className?: string;\n /**\n * Whether rows are selectable, and how many at once. The list reports\n * `selected` to assistive tech; choosing what is selected stays with\n * `onActivate`.\n */\n selection?: 'single' | 'multi';\n /**\n * A row was clicked, or Enter/Space was pressed on it, with the modifiers\n * held. Clicks and keys on a row's `trailing` controls do not reach this.\n */\n onActivate?(id: string, index: number, mods: PressModifiers): void;\n /**\n * Alt+Up (`-1`) or Alt+Down (`1`) on a row: move it. Focus stays on the\n * row wherever it lands. `useReorderDragList`'s `nudge` fits as-is.\n */\n onNudge?(id: string, index: number, delta: -1 | 1): void;\n /**\n * With `selection=\"multi\"`: Shift+Up/Down or Shift+Home/End moved focus,\n * and `ids` is every row from the anchor to the newly focused one, in list\n * order. The anchor is the row last focused or activated other than by a\n * range move, so a click or a plain arrow move re-anchors. What the range does to\n * the selection stays with the consumer, as with `onActivate`. Without it,\n * Shift+Arrow only moves focus.\n */\n onSelectRange?(ids: string[]): void;\n /**\n * Where a drop would land, as an insertion index: `0` is above the first\n * row, `rows.length` below the last. The list draws the seam itself, from\n * the rows' own boxes, so it follows whatever height the density gives\n * them. `useReorderDragList`'s `state.targetIndex` goes here as-is.\n */\n dropIndex?: number | null;\n /** Rendered inside the container ahead of the rows. */\n overlay?: ReactNode;\n /** Spread onto the container: pointer handlers for a drag, `aria-label`. */\n containerProps?: HTMLAttributes<HTMLDivElement>;\n /** Rows to draw again under the pointer during a drag — `useReorderDragList`'s `state.ghost`. */\n ghost?: ReorderGhost | null;\n}\n\ntype Mode = 'list' | 'listbox' | 'grid';\n\nconst ROLES: Record<Mode, { container: string; row: string }> = {\n list: { container: 'list', row: 'listitem' },\n listbox: { container: 'listbox', row: 'option' },\n grid: { container: 'grid', row: 'row' },\n};\n\n/**\n * The row chrome behind a sidebar list — layers, history, anything that is a\n * flat column of selectable rows in a panel.\n *\n * It owns the container, the row box, the empty state, the list's semantics\n * and its keyboard; what a row *means* stays with the consumer. History dims\n * its redo entries and rules a line under the current one; a layer list drags\n * to reorder and leads each row with a swatch. Both reach that through\n * `className` and `rowProps` rather than through options here, so this does\n * not grow a flag per consumer.\n *\n * Rows are one height and one inset for every list, which is the point: two\n * panels stacked in the same sidebar have to agree, and they did not while\n * each owned a private copy of the same CSS.\n *\n * **Semantics.** The role follows what the list can do:\n * - nothing to select or activate → `list` / `listitem`, and no row is focusable;\n * - `selection` with no row controls → `listbox` / `option`, `aria-selected`;\n * - any row with `trailing` controls, or `onActivate` without `selection` →\n * `grid` / `row`, with the leading content and label in one `gridcell` and\n * the controls in a second. An option may not contain interactive content,\n * so a list whose rows host toggles cannot be a listbox.\n *\n * **Keyboard.** One row is in the tab order: the one last focused, else the\n * first selected, else the first. Up/Down and Home/End move between rows,\n * Enter/Space activate, carrying modifiers so Shift+Space is Shift+click, and\n * Alt+Up/Down call `onNudge`. In a multi-select list with `onSelectRange`,\n * Shift+Up/Down and Shift+Home/End move focus and report the rows from the\n * anchor — the row last focused or activated other than by a range — to it. In a grid, Right steps from the row into its\n * controls, Left and Escape step back; the controls leave the tab order.\n */\nexport const ItemList = forwardRef(function ItemList(\n {\n rows, empty, className, selection, onActivate, onNudge, onSelectRange, dropIndex, overlay,\n containerProps, ghost,\n }: ItemListProps,\n ref: Ref<HTMLDivElement>,\n) {\n const hasTrailing = rows.some((r) => r.trailing != null);\n const mode: Mode = hasTrailing || (onActivate && !selection)\n ? 'grid'\n : selection ? 'listbox' : 'list';\n const interactive = mode !== 'list';\n\n const [container, setContainer] = useState<HTMLDivElement | null>(null);\n const setRefs = useCallback(\n (el: HTMLDivElement | null) => {\n setContainer(el);\n if (typeof ref === 'function') ref(el);\n else if (ref) ref.current = el;\n },\n [ref],\n );\n\n /** The element of each row that takes focus: the row itself, or in a grid its label cell. */\n const targets = useRef(new Map<string, HTMLElement>());\n const [focusId, setFocusId] = useState<string | null>(null);\n const pendingFocus = useRef<string | null>(null);\n const anchor = useRef<string | null>(null);\n /** The row a range move is focusing, whose focus must not re-anchor. */\n const extending = useRef<string | null>(null);\n\n const stopId = rows.some((r) => r.id === focusId)\n ? focusId\n : (rows.find((r) => r.selected) ?? rows[0])?.id;\n\n useLayoutEffect(() => {\n const id = pendingFocus.current;\n if (id == null) return;\n pendingFocus.current = null;\n const el = targets.current.get(id);\n if (el && document.activeElement !== el) el.focus();\n });\n\n useLayoutEffect(() => {\n if (mode !== 'grid') return;\n for (const target of targets.current.values()) {\n const cell = target.parentElement?.querySelector(`.${s.trailing}`);\n cell?.querySelectorAll(CONTROL_SELECTOR).forEach((c) => c.setAttribute('tabindex', '-1'));\n }\n });\n\n const cls = [s.list, className].filter(Boolean).join(' ');\n if (rows.length === 0) {\n return (\n <div className={cls} ref={setRefs} {...containerProps}>\n <div className={s.empty}>{empty ?? '—'}</div>\n </div>\n );\n }\n\n const focusRow = (index: number) => {\n const row = rows[Math.max(0, Math.min(rows.length - 1, index))];\n if (row) targets.current.get(row.id)?.focus();\n };\n\n const ranges = selection === 'multi' && onSelectRange !== undefined;\n\n /** Moves focus to `index`: a range from the anchor when `extend`, else a plain move. */\n const moveTo = (from: ItemListRow, index: number, extend: boolean) => {\n const to = Math.max(0, Math.min(rows.length - 1, index));\n if (!extend || !ranges) {\n focusRow(to);\n return;\n }\n let at = rows.findIndex((r) => r.id === anchor.current);\n if (at < 0) {\n anchor.current = from.id;\n at = rows.indexOf(from);\n }\n extending.current = rows[to]!.id;\n focusRow(to);\n extending.current = null;\n onSelectRange(rows.slice(Math.min(at, to), Math.max(at, to) + 1).map((r) => r.id));\n };\n\n const onKeyDown = (row: ItemListRow, i: number) => (e: KeyboardEvent<HTMLDivElement>) => {\n row.rowProps?.onKeyDown?.(e);\n if (e.defaultPrevented) return;\n const target = targets.current.get(row.id);\n if (!target) return;\n const onTarget = e.target === target;\n const controlCell = mode === 'grid'\n ? e.currentTarget.querySelector<HTMLElement>(`.${s.trailing}`)\n : null;\n if (!onTarget && !controlCell?.contains(e.target as Node)) return;\n\n switch (e.key) {\n case 'ArrowDown':\n case 'ArrowUp': {\n e.preventDefault();\n const delta = e.key === 'ArrowDown' ? 1 : -1;\n if (e.altKey && onNudge && onTarget) {\n pendingFocus.current = row.id;\n onNudge(row.id, i, delta);\n } else {\n moveTo(row, i + delta, e.shiftKey);\n }\n return;\n }\n case 'Home':\n case 'End':\n if (!onTarget) return;\n e.preventDefault();\n moveTo(row, e.key === 'Home' ? 0 : rows.length - 1, e.shiftKey);\n return;\n case 'Enter':\n case ' ':\n if (!onTarget) return;\n e.preventDefault();\n anchor.current = row.id;\n onActivate?.(row.id, i, modsOf(e));\n return;\n case 'ArrowRight':\n case 'ArrowLeft':\n case 'Escape': {\n if (!controlCell) return;\n const controls = Array.from(controlCell.querySelectorAll<HTMLElement>(CONTROL_SELECTOR))\n .filter((c) => !c.matches(':disabled'));\n if (onTarget) {\n if (e.key !== 'ArrowRight' || !controls[0]) return;\n e.preventDefault();\n controls[0].focus();\n return;\n }\n e.preventDefault();\n const at = controls.findIndex((c) => c.contains(e.target as Node));\n if (e.key === 'ArrowRight') controls[at + 1]?.focus();\n else if (e.key === 'ArrowLeft' && at > 0) controls[at - 1]?.focus();\n else target.focus();\n return;\n }\n default:\n }\n };\n\n const onClick = (row: ItemListRow, i: number) => (e: MouseEvent<HTMLDivElement>) => {\n row.rowProps?.onClick?.(e);\n if (e.defaultPrevented || isInControlWithin(e.target, e.currentTarget)) return;\n anchor.current = row.id;\n onActivate?.(row.id, i, modsOf(e));\n };\n\n const onFocus = (row: ItemListRow) => (e: FocusEvent<HTMLDivElement>) => {\n row.rowProps?.onFocus?.(e);\n if (e.target !== targets.current.get(row.id)) return;\n setFocusId(row.id);\n if (extending.current !== row.id) anchor.current = row.id;\n };\n\n const targetRef = (id: string) => (el: HTMLElement | null) => {\n if (el) targets.current.set(id, el);\n else targets.current.delete(id);\n };\n\n const roles = ROLES[mode];\n return (\n <div\n className={cls}\n ref={setRefs}\n {...containerProps}\n role={roles.container}\n aria-multiselectable={selection === 'multi' && mode !== 'list' ? true : undefined}\n >\n {overlay}\n {ghost && container ? (\n <DragGhost at={ghost} from={container}>\n {rows\n .filter((row) => ghost.ids.includes(row.id))\n .map((row) => (\n <div key={row.id} className={[s.row, row.selected && s.selected].filter(Boolean).join(' ')}>\n {row.leading}\n <span className={s.label}>{row.label}</span>\n </div>\n ))}\n </DragGhost>\n ) : null}\n {rows.map((row, i) => {\n const tabIndex = interactive ? (row.id === stopId ? 0 : -1) : undefined;\n const content = (\n <>\n {row.leading}\n <span className={s.label}>{row.label}</span>\n </>\n );\n return (\n <div\n key={row.id}\n className={[\n s.row,\n row.selected && s.selected,\n row.muted && s.muted,\n row.className,\n ].filter(Boolean).join(' ')}\n {...row.rowProps}\n role={roles.row}\n aria-selected={selection && mode !== 'list' ? !!row.selected : undefined}\n ref={mode === 'listbox' ? targetRef(row.id) : undefined}\n tabIndex={mode === 'listbox' ? tabIndex : row.rowProps?.tabIndex}\n onKeyDown={interactive ? onKeyDown(row, i) : row.rowProps?.onKeyDown}\n onClick={interactive ? onClick(row, i) : row.rowProps?.onClick}\n onFocus={interactive ? onFocus(row) : row.rowProps?.onFocus}\n data-drop={dropSide(dropIndex, i, rows.length)}\n data-dragging={row.dragging ? 'true' : undefined}\n >\n {mode === 'grid' ? (\n <>\n <div role=\"gridcell\" className={s.cell} ref={targetRef(row.id)} tabIndex={tabIndex}>\n {content}\n </div>\n {row.trailing != null && (\n <div role=\"gridcell\" className={s.trailing}>{row.trailing}</div>\n )}\n </>\n ) : content}\n </div>\n );\n })}\n </div>\n );\n});\n\nfunction modsOf(e: { shiftKey: boolean; ctrlKey: boolean; metaKey: boolean; altKey: boolean }): PressModifiers {\n return { shiftKey: e.shiftKey, ctrlKey: e.ctrlKey, metaKey: e.metaKey, altKey: e.altKey };\n}\n\n/** Which edge of row `i` carries the seam for `dropIndex`, if any. */\nfunction dropSide(\n dropIndex: number | null | undefined,\n i: number,\n count: number,\n): 'before' | 'after' | undefined {\n if (dropIndex == null) return undefined;\n if (dropIndex === i) return 'before';\n if (dropIndex >= count && i === count - 1) return 'after';\n return undefined;\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
- import { Ct as e, rt as t, st as n, wt as r } from "./icons-CofIOTiI.js";
2
- import { t as i } from "./Button-XB-T75YL.js";
1
+ import { Dt as e, Et as t, ot as n, ut as r } from "./icons-B_fPKEis.js";
2
+ import { t as i } from "./Button-CQA-K1g9.js";
3
3
  import { t as a } from "./Slider-CHBQ8uUC.js";
4
4
  import { jsx as o, jsxs as s } from "react/jsx-runtime";
5
5
  var c = {
@@ -22,7 +22,7 @@ function l(l) {
22
22
  ariaLabel: `Previous ${_.toLowerCase()}`,
23
23
  disabled: x <= 0,
24
24
  onClick: () => h(-1),
25
- children: /* @__PURE__ */ o(e, { size: 14 })
25
+ children: /* @__PURE__ */ o(t, { size: 14 })
26
26
  }),
27
27
  /* @__PURE__ */ o(i, {
28
28
  iconOnly: !0,
@@ -31,7 +31,7 @@ function l(l) {
31
31
  ariaLabel: p ? "Pause" : "Play",
32
32
  disabled: f < 2,
33
33
  onClick: () => m(!p),
34
- children: o(p ? t : n, { size: 14 })
34
+ children: o(p ? n : r, { size: 14 })
35
35
  }),
36
36
  /* @__PURE__ */ o(i, {
37
37
  iconOnly: !0,
@@ -40,7 +40,7 @@ function l(l) {
40
40
  ariaLabel: `Next ${_.toLowerCase()}`,
41
41
  disabled: x >= b,
42
42
  onClick: () => h(1),
43
- children: /* @__PURE__ */ o(r, { size: 14 })
43
+ children: /* @__PURE__ */ o(e, { size: 14 })
44
44
  }),
45
45
  g && /* @__PURE__ */ o(a, {
46
46
  className: c.scrub,
@@ -78,4 +78,4 @@ function u(e, t) {
78
78
  //#endregion
79
79
  export { l as t };
80
80
 
81
- //# sourceMappingURL=Jog-TE6QI9i1.js.map
81
+ //# sourceMappingURL=Jog-BU0xuM3G.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Jog-TE6QI9i1.js","names":["s","StepBackIcon","PauseIcon","PlayIcon","StepForwardIcon","Button","Slider","Jog_module_default","Jog","props","last","count","at","index","spoken","unit","className","onStep","playing","onPlay","jsx","onScrub","next","pad","caption","value"],"sources":["../../src/components/Jog/Jog.module.css","../../src/components/Jog/Jog.tsx"],"sourcesContent":["/* A row of transport controls on the panel surface, sized to sit in a bar\n * beside a title or a caption rather than to own a strip of its own. */\n\n.jog {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-2);\n color: var(--wzl-fg);\n}\n\n.scrub {\n flex: 1 1 auto;\n min-width: 80px;\n margin-inline: var(--wzl-space-2);\n}\n\n.readout {\n composes: numeric from '@weasel-js/theme/numeric.module.css';\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-muted);\n white-space: pre;\n}\n\n.caption {\n overflow: hidden;\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-muted);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","import type { ReactNode } from 'react';\nimport { PauseIcon, PlayIcon, StepBackIcon, StepForwardIcon } from '../../icons';\nimport { Button } from '../Button';\nimport { Slider } from '../Slider/Slider';\nimport s from './Jog.module.css';\n\n/** Props for {@link Jog}. */\nexport interface JogProps {\n /** Which step is showing, 0-based. */\n index: number;\n /** How many steps there are. */\n count: number;\n playing: boolean;\n onPlay: (playing: boolean) => void;\n /** Move one step, back or forward. */\n onStep: (by: -1 | 1) => void;\n /** Jump to a step. Left out, no scrubber is drawn. */\n onScrub?: (index: number) => void;\n /** What one step is called, for the spoken labels. Defaults to `Step`. */\n unit?: string;\n /** Drawn after the readout — a beat's caption, a snapshot's date. */\n caption?: ReactNode;\n className?: string;\n}\n\n/**\n * Transport for something counted rather than timed: beat 3 of 24, not 4.20s of 12.00s.\n * `<Transport>` is the continuous-time one, and wants a playhead in milliseconds, a rate and\n * a loop, none of which a list of steps has.\n *\n * Named for the jog of jog/shuttle — moving one frame at a time, as against running at speed.\n */\nexport function Jog(props: JogProps) {\n const { index, count, playing, onPlay, onStep, onScrub, unit = 'Step', caption, className } =\n props;\n\n const last = Math.max(0, count - 1);\n const at = Math.min(Math.max(index, 0), last);\n const spoken = `${unit} ${at + 1} of ${count}`;\n\n return (\n <div className={[s.jog, className].filter(Boolean).join(' ')}>\n <Button\n iconOnly\n size=\"sm\"\n variant=\"ghost\"\n ariaLabel={`Previous ${unit.toLowerCase()}`}\n disabled={at <= 0}\n onClick={() => onStep(-1)}\n >\n <StepBackIcon size={14} />\n </Button>\n <Button\n iconOnly\n size=\"sm\"\n variant=\"ghost\"\n ariaLabel={playing ? 'Pause' : 'Play'}\n disabled={count < 2}\n onClick={() => onPlay(!playing)}\n >\n {playing ? <PauseIcon size={14} /> : <PlayIcon size={14} />}\n </Button>\n <Button\n iconOnly\n size=\"sm\"\n variant=\"ghost\"\n ariaLabel={`Next ${unit.toLowerCase()}`}\n disabled={at >= last}\n onClick={() => onStep(1)}\n >\n <StepForwardIcon size={14} />\n </Button>\n\n {onScrub && (\n <Slider\n className={s.scrub}\n min={0}\n max={last}\n step={1}\n snap=\"strict\"\n density=\"slim\"\n ariaLabel={unit}\n thumbs={[{ value: at, valueText: spoken }]}\n onInput={(next) => onScrub(Math.round(next[0]?.value ?? 0))}\n />\n )}\n\n <span className={s.readout} data-testid=\"jog-readout\">\n {pad(at + 1, count)}/{count}\n </span>\n {caption ? <span className={s.caption}>{caption}</span> : null}\n </div>\n );\n}\n\n/**\n * Figure spaces, not regular ones: the readout updates every beat, and a run from 9 to 10 that\n * widens by a digit shoves whatever follows it along the row. `tabular-nums` fixes the width of\n * a digit and not how many there are, so the padding is what holds the row still.\n */\nfunction pad(value: number, count: number): string {\n return String(value).padStart(String(count).length, ' ');\n}\n"],"mappings":";;;;;;;;;;;;ACgCA,SAAgBQ,EAAI,GAAiB;CACnC,IAAM,EAAE,UAAO,UAAO,YAAS,WAAQ,WAAQ,YAAS,UAAO,QAAQ,YAAS,iBAC9EC,GAEIC,IAAO,KAAK,IAAI,GAAGC,IAAQ,CAAC,GAC5BC,IAAK,KAAK,IAAI,KAAK,IAAIC,GAAO,CAAC,GAAGH,CAAI,GACtCI,IAAS,GAAGC,EAAK,GAAGH,IAAK,EAAE,MAAMD;CAEvC,OACE,kBAAC,OAAD;EAAK,WAAW,CAACX,EAAE,KAAKgB,CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;EAA3D,UAAA;GACE,kBAACX,GAAD;IACE,UAAA;IACA,MAAK;IACL,SAAQ;IACR,WAAW,YAAYU,EAAK,YAAY;IACxC,UAAUH,KAAM;IAChB,eAAeK,EAAO,EAAE;IAExB,UAAA,kBAAChB,GAAD,EAAc,MAAM,GAAK,CAAA;GACnB,CAAA;GACR,kBAACI,GAAD;IACE,UAAA;IACA,MAAK;IACL,SAAQ;IACR,WAAWa,IAAU,UAAU;IAC/B,UAAUP,IAAQ;IAClB,eAAeQ,EAAO,CAACD,CAAO;IAE7B,UAAUE,EAAVF,IAAWhB,IAA0BC,GAA3B,EAAW,MAAM,GAAK,CAAyB;GACpD,CAAA;GACR,kBAACE,GAAD;IACE,UAAA;IACA,MAAK;IACL,SAAQ;IACR,WAAW,QAAQU,EAAK,YAAY;IACpC,UAAUH,KAAMF;IAChB,eAAeO,EAAO,CAAC;IAEvB,UAAA,kBAACb,GAAD,EAAiB,MAAM,GAAK,CAAA;GACtB,CAAA;GAEPiB,KACC,kBAACf,GAAD;IACE,WAAWN,EAAE;IACb,KAAK;IACL,KAAKU;IACL,MAAM;IACN,MAAK;IACL,SAAQ;IACR,WAAWK;IACX,QAAQ,CAAC;KAAE,OAAOH;KAAI,WAAWE;IAAO,CAAC;IACzC,UAAU,MAASO,EAAQ,KAAK,MAAMC,EAAK,EAAE,EAAE,SAAS,CAAC,CAAC;GAC3D,CAAA;GAGH,kBAAC,QAAD;IAAM,WAAWtB,EAAE;IAAS,eAAY;IAAxC,UAAA;KACGuB,EAAIX,IAAK,GAAGD,CAAK;KAAE;KAAEA;IAClB;;GACLa,IAAU,kBAAC,QAAD;IAAM,WAAWxB,EAAE;IAAU,UAAAwB;GAAc,CAAA,IAAI;EACvD;;AAET;AAOA,SAASD,EAAI,GAAe,GAAuB;CACjD,OAAO,OAAOE,CAAK,CAAC,CAAC,SAAS,OAAOd,CAAK,CAAC,CAAC,QAAQ,GAAG;AACzD"}
1
+ {"version":3,"file":"Jog-BU0xuM3G.js","names":["s","StepForwardIcon","StepBackIcon","PauseIcon","PlayIcon","Button","Slider","Jog_module_default","Jog","props","last","count","at","index","spoken","unit","className","onStep","playing","onPlay","jsx","onScrub","next","pad","caption","value"],"sources":["../../src/components/Jog/Jog.module.css","../../src/components/Jog/Jog.tsx"],"sourcesContent":["/* A row of transport controls on the panel surface, sized to sit in a bar\n * beside a title or a caption rather than to own a strip of its own. */\n\n.jog {\n display: flex;\n align-items: center;\n gap: var(--wzl-space-2);\n color: var(--wzl-fg);\n}\n\n.scrub {\n flex: 1 1 auto;\n min-width: 80px;\n margin-inline: var(--wzl-space-2);\n}\n\n.readout {\n composes: numeric from '@weasel-js/theme/numeric.module.css';\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-muted);\n white-space: pre;\n}\n\n.caption {\n overflow: hidden;\n font-size: var(--wzl-font-size-sm);\n color: var(--wzl-fg-muted);\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n","import type { ReactNode } from 'react';\nimport { PauseIcon, PlayIcon, StepBackIcon, StepForwardIcon } from '../../icons';\nimport { Button } from '../Button';\nimport { Slider } from '../Slider/Slider';\nimport s from './Jog.module.css';\n\n/** Props for {@link Jog}. */\nexport interface JogProps {\n /** Which step is showing, 0-based. */\n index: number;\n /** How many steps there are. */\n count: number;\n playing: boolean;\n onPlay: (playing: boolean) => void;\n /** Move one step, back or forward. */\n onStep: (by: -1 | 1) => void;\n /** Jump to a step. Left out, no scrubber is drawn. */\n onScrub?: (index: number) => void;\n /** What one step is called, for the spoken labels. Defaults to `Step`. */\n unit?: string;\n /** Drawn after the readout — a beat's caption, a snapshot's date. */\n caption?: ReactNode;\n className?: string;\n}\n\n/**\n * Transport for something counted rather than timed: beat 3 of 24, not 4.20s of 12.00s.\n * `<Transport>` is the continuous-time one, and wants a playhead in milliseconds, a rate and\n * a loop, none of which a list of steps has.\n *\n * Named for the jog of jog/shuttle — moving one frame at a time, as against running at speed.\n */\nexport function Jog(props: JogProps) {\n const { index, count, playing, onPlay, onStep, onScrub, unit = 'Step', caption, className } =\n props;\n\n const last = Math.max(0, count - 1);\n const at = Math.min(Math.max(index, 0), last);\n const spoken = `${unit} ${at + 1} of ${count}`;\n\n return (\n <div className={[s.jog, className].filter(Boolean).join(' ')}>\n <Button\n iconOnly\n size=\"sm\"\n variant=\"ghost\"\n ariaLabel={`Previous ${unit.toLowerCase()}`}\n disabled={at <= 0}\n onClick={() => onStep(-1)}\n >\n <StepBackIcon size={14} />\n </Button>\n <Button\n iconOnly\n size=\"sm\"\n variant=\"ghost\"\n ariaLabel={playing ? 'Pause' : 'Play'}\n disabled={count < 2}\n onClick={() => onPlay(!playing)}\n >\n {playing ? <PauseIcon size={14} /> : <PlayIcon size={14} />}\n </Button>\n <Button\n iconOnly\n size=\"sm\"\n variant=\"ghost\"\n ariaLabel={`Next ${unit.toLowerCase()}`}\n disabled={at >= last}\n onClick={() => onStep(1)}\n >\n <StepForwardIcon size={14} />\n </Button>\n\n {onScrub && (\n <Slider\n className={s.scrub}\n min={0}\n max={last}\n step={1}\n snap=\"strict\"\n density=\"slim\"\n ariaLabel={unit}\n thumbs={[{ value: at, valueText: spoken }]}\n onInput={(next) => onScrub(Math.round(next[0]?.value ?? 0))}\n />\n )}\n\n <span className={s.readout} data-testid=\"jog-readout\">\n {pad(at + 1, count)}/{count}\n </span>\n {caption ? <span className={s.caption}>{caption}</span> : null}\n </div>\n );\n}\n\n/**\n * Figure spaces, not regular ones: the readout updates every beat, and a run from 9 to 10 that\n * widens by a digit shoves whatever follows it along the row. `tabular-nums` fixes the width of\n * a digit and not how many there are, so the padding is what holds the row still.\n */\nfunction pad(value: number, count: number): string {\n return String(value).padStart(String(count).length, ' ');\n}\n"],"mappings":";;;;;;;;;;;;ACgCA,SAAgBQ,EAAI,GAAiB;CACnC,IAAM,EAAE,UAAO,UAAO,YAAS,WAAQ,WAAQ,YAAS,UAAO,QAAQ,YAAS,iBAC9EC,GAEIC,IAAO,KAAK,IAAI,GAAGC,IAAQ,CAAC,GAC5BC,IAAK,KAAK,IAAI,KAAK,IAAIC,GAAO,CAAC,GAAGH,CAAI,GACtCI,IAAS,GAAGC,EAAK,GAAGH,IAAK,EAAE,MAAMD;CAEvC,OACE,kBAAC,OAAD;EAAK,WAAW,CAACX,EAAE,KAAKgB,CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;EAA3D,UAAA;GACE,kBAACX,GAAD;IACE,UAAA;IACA,MAAK;IACL,SAAQ;IACR,WAAW,YAAYU,EAAK,YAAY;IACxC,UAAUH,KAAM;IAChB,eAAeK,EAAO,EAAE;IAExB,UAAA,kBAACf,GAAD,EAAc,MAAM,GAAK,CAAA;GACnB,CAAA;GACR,kBAACG,GAAD;IACE,UAAA;IACA,MAAK;IACL,SAAQ;IACR,WAAWa,IAAU,UAAU;IAC/B,UAAUP,IAAQ;IAClB,eAAeQ,EAAO,CAACD,CAAO;IAE7B,UAAUE,EAAVF,IAAWf,IAA0BC,GAA3B,EAAW,MAAM,GAAK,CAAyB;GACpD,CAAA;GACR,kBAACC,GAAD;IACE,UAAA;IACA,MAAK;IACL,SAAQ;IACR,WAAW,QAAQU,EAAK,YAAY;IACpC,UAAUH,KAAMF;IAChB,eAAeO,EAAO,CAAC;IAEvB,UAAA,kBAAChB,GAAD,EAAiB,MAAM,GAAK,CAAA;GACtB,CAAA;GAEPoB,KACC,kBAACf,GAAD;IACE,WAAWN,EAAE;IACb,KAAK;IACL,KAAKU;IACL,MAAM;IACN,MAAK;IACL,SAAQ;IACR,WAAWK;IACX,QAAQ,CAAC;KAAE,OAAOH;KAAI,WAAWE;IAAO,CAAC;IACzC,UAAU,MAASO,EAAQ,KAAK,MAAMC,EAAK,EAAE,EAAE,SAAS,CAAC,CAAC;GAC3D,CAAA;GAGH,kBAAC,QAAD;IAAM,WAAWtB,EAAE;IAAS,eAAY;IAAxC,UAAA;KACGuB,EAAIX,IAAK,GAAGD,CAAK;KAAE;KAAEA;IAClB;;GACLa,IAAU,kBAAC,QAAD;IAAM,WAAWxB,EAAE;IAAU,UAAAwB;GAAc,CAAA,IAAI;EACvD;;AAET;AAOA,SAASD,EAAI,GAAe,GAAuB;CACjD,OAAO,OAAOE,CAAK,CAAC,CAAC,SAAS,OAAOd,CAAK,CAAC,CAAC,QAAQ,GAAG;AACzD"}
@@ -398,6 +398,12 @@ function m(e, t = {}) {
398
398
  return r === void 0 ? i : [...i, l(r, t)];
399
399
  }
400
400
  //#endregion
401
- export { o as a, d as i, p as n, l as o, f as r, s, m as t };
401
+ //#region src/components/Keycaps/variantIcons.ts
402
+ var h = {
403
+ default: "variantSolid",
404
+ minimal: "variantOutline"
405
+ };
406
+ //#endregion
407
+ export { d as a, s as c, f as i, m as n, o, p as r, l as s, h as t };
402
408
 
403
- //# sourceMappingURL=Keycaps-C-FJyG8k.js.map
409
+ //# sourceMappingURL=Keycaps-CM-gOj0e.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Keycaps-CM-gOj0e.js","names":["s","s","Fragment","Fragment$1","Keycaps_module_default","MOD_BY_PLATFORM","MODIFIER_LABELS","byPlatform","byLegend","detectPlatform","raw","keySpecsFromMods","platform","opts","legend","mods","label","m","NAMED_KEY","keySpecFromKey","entry","WIDE_GLYPHS","inferKeycapKind","KeyCap","resolvedStyle","font","style","className","variant","inverted","KeySequence","keys","ordered","a","b","k","sepBefore","i","joins","separator","keySpecsFromShortcut","shortcut","key","KEYCAP_VARIANT_ICONS"],"sources":["../../src/components/Keycaps/Keycaps.module.css","../../src/components/Keycaps/keySpecsFromMods.ts","../../src/components/Keycaps/Keycap.tsx","../../src/components/Keycaps/Keycaps.tsx","../../src/components/Keycaps/keySpecsFromShortcut.ts","../../src/components/Keycaps/variantIcons.ts"],"sourcesContent":["/* Keystroke \"key cap\" styling — each modifier and key in its own bordered chip. */\n.keys,\n.key {\n --key-h: var(--wzl-control-h-xs);\n}\n\n.keys {\n display: inline-flex;\n gap: 3px;\n /* Bottom-align so chips with text labels and chips with icon glyphs\n (arrows, modifier symbols) line up at the same bottom edge. Baseline\n drifts because text baselines sit above icon centers. */\n align-items: flex-end;\n /* When this whole sequence sits inline in surrounding text (e.g.\n \"Press <KeySequence> to confirm.\"), the row anchors to the\n surrounding line's bottom edge, not its baseline. */\n vertical-align: bottom;\n flex-wrap: wrap;\n}\n\n.keysEmpty {\n color: var(--wzl-fg-muted);\n}\n\n.sep {\n /* A key's height, so the glyph centers on the keys rather than riding the\n row's bottom edge. */\n display: inline-flex;\n align-items: center;\n height: var(--key-h);\n color: var(--wzl-fg-muted);\n font-size: var(--wzl-font-size-sm);\n line-height: 1;\n}\n\n.key {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n box-sizing: border-box;\n height: var(--key-h);\n padding: 0 var(--wzl-space-2);\n /* Light face, slightly-darker-than-face border, dark glyph — reads as\n a real keycap rather than a recessed slot in the panel. */\n background: var(--wzl-fg);\n border: 1px solid #25272c;\n border-bottom-width: 2px;\n border-radius: var(--wzl-radius-sm);\n color: var(--wzl-surface);\n /* Keycaps are a deliberate exception to the site theme — the design-\n system UI font (often a display face like Oswald) is wrong for\n keyboard chips. Use a neutral sans stack so labels read like real\n key legends. Consumers wanting a specific face per chip pass the\n `font` prop on KeyCap. */\n font-family: ui-sans-serif, system-ui, sans-serif;\n font-size: var(--wzl-font-size-sm);\n font-weight: var(--wzl-font-weight-bold);\n line-height: 1;\n}\n\n/* Default chip is square — letters, digits, and single glyphs (⎋ ⌫ ↑ etc.)\n sit in a uniform key-cap box. */\n.key[data-kind='square'] {\n width: var(--key-h);\n padding: 0;\n}\n\n/* Modifiers (⌘ ⇪ ⌥ ⌃) are wider to match the visual weight of how they\n appear on a real keyboard — and to differentiate them from the keys\n they modify in a stack. */\n.key[data-kind='modifier'] {\n min-width: 26px;\n padding: 0 var(--wzl-space-3);\n}\n\n/* Tab / Enter / Space — actual wide keys on a real keyboard. */\n.key[data-kind='wide'] {\n min-width: 32px;\n padding: 0 var(--wzl-space-4);\n}\n\n/* Optional/inverted (default variant): face flips to dark; legend drops\n to 60% opacity; dotted border drops to 40% opacity. Three soft cues\n stacked for \"may be held but isn't required.\" */\n.key[data-inverted] {\n background: var(--wzl-surface);\n color: color-mix(in srgb, var(--wzl-fg) 60%, transparent);\n border-style: dotted;\n border-color: color-mix(in srgb, var(--wzl-fg) 40%, transparent);\n border-width: 1.5px;\n border-bottom-width: 1.5px;\n}\n\n/* Minimal variant — no fill, borders and legend follow currentColor.\n Useful inline in colored prose / next to colored badges where the\n chip should take the surrounding text color. */\n.key[data-variant='minimal'] {\n background: transparent;\n border-color: currentColor;\n color: currentColor;\n}\n\n/* Optional + minimal: dotted border at full currentColor, legend at full\n currentColor. The dotted pattern alone carries the \"optional\" cue here\n — minimal's whole point is to defer color to the surrounding context,\n so dimming would fight that. (Default variant uses graded opacity as a\n stacked cue; minimal keeps it crisp.) */\n.key[data-variant='minimal'][data-inverted] {\n border-style: dotted;\n border-color: currentColor;\n color: currentColor;\n border-width: 1.5px;\n border-bottom-width: 1.5px;\n}\n","import type { KeySpec } from './Keycaps';\n\n/** Logical modifier name. Matches the kit's `ModifierKey` in shape — kept as a\n * local type so `weasel-ui` stays independent of `@weasel-js/core`. */\nexport type LogicalMod = 'mod' | 'shift' | 'alt' | 'ctrl' | 'meta';\n\n/** Detected (or overridden) platform. `'mod'` resolves to ⌘ on macOS,\n * Ctrl on Windows / Linux. */\nexport type Platform = 'macos' | 'windows' | 'linux';\n\n/** Visual form of a modifier or named-key label.\n *\n * - `'auto'` (default): the per-entry, per-platform default — whatever\n * label is actually printed on the physical key. macOS keys show the\n * Apple glyphs (⌘ ⌥ ⌃ ⇧ ⎋ ↵ ⇥). Windows keys mostly show text\n * (Ctrl, Alt, Shift) BUT the Win key shows its logo (⊞) and the\n * context-menu key shows ▤. Linux mirrors Windows with Super (⊞).\n * - `'symbol'` forces the Apple-style glyph everywhere a symbolic form\n * exists. Entries without a widely-recognized symbol still fall\n * back to text.\n * - `'text'` always spells the label out (Cmd / Option / Esc / Enter). */\nexport type LegendStyle = 'auto' | 'symbol' | 'text';\n\n/** A modifier to render, named platform-independently. */\nexport interface LogicalModSpec {\n name: LogicalMod;\n /** Marks this modifier as optional (may be held but isn't required).\n * Forwarded as the resulting `KeySpec.optional`. */\n optional?: boolean;\n}\n\n/** Options for {@link keySpecsFromMods}. */\nexport interface KeySpecsFromModsOptions {\n /** Override OS detection. Defaults to the detected platform, or\n * `'macos'` when detection is unavailable (e.g. in tests, or when\n * `navigator` is missing). */\n platform?: Platform;\n /** Defaults to `'auto'` (symbol on macOS, text everywhere else). Pass\n * `'symbol'` or `'text'` to force a specific style regardless of\n * platform. */\n legend?: LegendStyle;\n}\n\nconst MOD_BY_PLATFORM: Record<LogicalMod, Record<Platform, Record<LegendStyle, string>>> = {\n mod: {\n macos: { auto: '⌘', symbol: '⌘', text: 'Cmd' },\n windows: { auto: 'Ctrl', symbol: 'Ctrl', text: 'Ctrl' },\n linux: { auto: 'Ctrl', symbol: 'Ctrl', text: 'Ctrl' },\n },\n shift: {\n macos: { auto: '⇧', symbol: '⇧', text: 'Shift' },\n windows: { auto: '⇧', symbol: '⇧', text: 'Shift' },\n linux: { auto: '⇧', symbol: '⇧', text: 'Shift' },\n },\n alt: {\n macos: { auto: '⌥', symbol: '⌥', text: 'Option' },\n windows: { auto: 'Alt', symbol: 'Alt', text: 'Alt' },\n linux: { auto: 'Alt', symbol: 'Alt', text: 'Alt' },\n },\n ctrl: {\n macos: { auto: '⌃', symbol: '⌃', text: 'Control' },\n windows: { auto: 'Ctrl', symbol: 'Ctrl', text: 'Ctrl' },\n linux: { auto: 'Ctrl', symbol: 'Ctrl', text: 'Ctrl' },\n },\n // Windows/Linux Meta has a recognized symbol on the physical key (⊞ Win\n // logo / Super logo), so `auto` shows it. Use `text` for Win / Super.\n meta: {\n macos: { auto: '⌘', symbol: '⌘', text: 'Cmd' },\n windows: { auto: '⊞', symbol: '⊞', text: 'Win' },\n linux: { auto: '⊞', symbol: '⊞', text: 'Super' },\n },\n};\n\n/** Every label {@link keySpecsFromMods} can produce, on any platform and legend. */\nexport const MODIFIER_LABELS: ReadonlySet<string> = new Set(\n Object.values(MOD_BY_PLATFORM).flatMap((byPlatform) =>\n Object.values(byPlatform).flatMap((byLegend) => Object.values(byLegend)),\n ),\n);\n\n/** Detect the user's OS from the browser environment. UA sniffing — not\n * 100% reliable, but adequate for picking a modifier-glyph convention.\n * Falls back to `'macos'` (matches the kit's docs convention) when\n * `navigator` is unavailable. */\nexport function detectPlatform(): Platform {\n if (typeof navigator === 'undefined') return 'macos';\n // Prefer the modern userAgentData when available (Chromium-only today).\n const uaData = (navigator as Navigator & { userAgentData?: { platform?: string } }).userAgentData;\n const raw = (uaData?.platform ?? navigator.userAgent ?? '').toLowerCase();\n if (raw.includes('mac') || raw.includes('darwin') || raw.includes('iphone') || raw.includes('ipad')) return 'macos';\n if (raw.includes('win')) return 'windows';\n if (raw.includes('linux') || raw.includes('x11')) return 'linux';\n return 'macos';\n}\n\n/**\n * Map a list of **logical** modifiers (`'mod'`, `'shift'`, …) to **visual**\n * `KeySpec`s appropriate for the current platform.\n *\n * The kit-side gesture grammar uses logical names so the same route reads\n * correctly on every OS — `'mod'` means \"Cmd on Mac, Ctrl on Win/Linux\".\n * `KeySequence` is purely visual and renders the labels you give it; this\n * helper is the bridge.\n *\n * ```ts\n * <KeySequence\n * keys={keySpecsFromMods([{ name: 'mod' }, { name: 'shift', optional: true }])}\n * />\n * ```\n *\n * On a Mac: renders `⌘ ⇧`. On Windows: renders `Ctrl Shift`. Pass an\n * explicit `platform` to override detection (e.g. for docs that always\n * show the macOS form). Pass `legend: 'text'` to force \"Cmd\" over \"⌘\"\n * even on macOS.\n */\nexport function keySpecsFromMods(\n mods: readonly LogicalModSpec[],\n opts: KeySpecsFromModsOptions = {},\n): readonly KeySpec[] {\n const platform = opts.platform ?? detectPlatform();\n const legend = opts.legend ?? 'auto';\n return mods.map((m) => {\n const label = MOD_BY_PLATFORM[m.name][platform][legend];\n return m.optional ? { label, optional: true } : { label };\n });\n}\n\n/** Per-platform × per-legend table for named, non-modifier keys. `auto`\n * is whatever's printed on the physical key for that platform. Arrows\n * are universal symbols on every platform. */\nconst NAMED_KEY: Record<string, Record<Platform, Record<LegendStyle, string>>> = {\n Escape: { macos: { auto: '⎋', symbol: '⎋', text: 'Esc' }, windows: { auto: 'Esc', symbol: 'Esc', text: 'Esc' }, linux: { auto: 'Esc', symbol: 'Esc', text: 'Esc' } },\n Enter: { macos: { auto: '↵', symbol: '↵', text: 'Return' }, windows: { auto: 'Enter', symbol: 'Enter', text: 'Enter' }, linux: { auto: 'Enter', symbol: 'Enter', text: 'Enter' } },\n Return: { macos: { auto: '↵', symbol: '↵', text: 'Return' }, windows: { auto: 'Enter', symbol: 'Enter', text: 'Enter' }, linux: { auto: 'Enter', symbol: 'Enter', text: 'Enter' } },\n Tab: { macos: { auto: '⇥', symbol: '⇥', text: 'Tab' }, windows: { auto: 'Tab', symbol: 'Tab', text: 'Tab' }, linux: { auto: 'Tab', symbol: 'Tab', text: 'Tab' } },\n Space: { macos: { auto: '␣', symbol: '␣', text: 'Space' }, windows: { auto: 'Space', symbol: 'Space', text: 'Space' }, linux: { auto: 'Space', symbol: 'Space', text: 'Space' } },\n ' ': { macos: { auto: '␣', symbol: '␣', text: 'Space' }, windows: { auto: 'Space', symbol: 'Space', text: 'Space' }, linux: { auto: 'Space', symbol: 'Space', text: 'Space' } },\n Backspace: { macos: { auto: '⌫', symbol: '⌫', text: 'Backspace' }, windows: { auto: 'Backspace', symbol: 'Backspace', text: 'Backspace' }, linux: { auto: 'Backspace', symbol: 'Backspace', text: 'Backspace' } },\n Delete: { macos: { auto: '⌦', symbol: '⌦', text: 'Delete' }, windows: { auto: 'Delete', symbol: 'Delete', text: 'Delete' }, linux: { auto: 'Delete', symbol: 'Delete', text: 'Delete' } },\n // Context-menu key (the right-Ctrl-area key on Windows / Linux keyboards\n // with a ▤ icon). Mac has no equivalent; falls back to text 'Menu'.\n ContextMenu: { macos: { auto: 'Menu', symbol: 'Menu', text: 'Menu' }, windows: { auto: '▤', symbol: '▤', text: 'Menu' }, linux: { auto: '▤', symbol: '▤', text: 'Menu' } },\n ArrowUp: { macos: { auto: '↑', symbol: '↑', text: '↑' }, windows: { auto: '↑', symbol: '↑', text: '↑' }, linux: { auto: '↑', symbol: '↑', text: '↑' } },\n ArrowDown: { macos: { auto: '↓', symbol: '↓', text: '↓' }, windows: { auto: '↓', symbol: '↓', text: '↓' }, linux: { auto: '↓', symbol: '↓', text: '↓' } },\n ArrowLeft: { macos: { auto: '←', symbol: '←', text: '←' }, windows: { auto: '←', symbol: '←', text: '←' }, linux: { auto: '←', symbol: '←', text: '←' } },\n ArrowRight: { macos: { auto: '→', symbol: '→', text: '→' }, windows: { auto: '→', symbol: '→', text: '→' }, linux: { auto: '→', symbol: '→', text: '→' } },\n};\n\n/**\n * Render a raw `KeyboardEvent.key` value as a platform-appropriate\n * `KeySpec`. Named non-modifier keys (Esc, Enter, Tab, Space, Backspace,\n * Delete, arrows) get the platform's conventional form. Letter / digit /\n * other keys pass through upper-cased.\n *\n * ```ts\n * keySpecFromKey('Escape', { platform: 'macos' }) // { label: '⎋' }\n * keySpecFromKey('Escape', { platform: 'windows' }) // { label: 'Esc' }\n * keySpecFromKey('p') // { label: 'P' }\n * ```\n *\n * Symbol mode is only meaningful on macOS — Windows / Linux keyboards\n * print the text form on the physical key, so symbol mode there falls\n * back to text.\n */\nexport function keySpecFromKey(\n raw: string,\n opts: KeySpecsFromModsOptions & { optional?: boolean } = {},\n): KeySpec {\n const platform = opts.platform ?? detectPlatform();\n const legend = opts.legend ?? 'auto';\n const entry = NAMED_KEY[raw];\n const label = entry ? entry[platform][legend] : raw.length === 1 ? raw.toUpperCase() : raw;\n return opts.optional ? { label, optional: true } : { label };\n}\n","import type { CSSProperties } from 'react';\nimport s from './Keycaps.module.css';\nimport { MODIFIER_LABELS } from './keySpecsFromMods';\n\nconst WIDE_GLYPHS = new Set(['⇥', '↵', '␣']);\n\n/**\n * Width class of a keycap: a modifier glyph, a multi-character legend that\n * needs a wider chip, or a single character in a square one.\n */\nexport type KeycapKind = 'modifier' | 'wide' | 'square';\n\n/**\n * Picks the chip width for a legend — modifier glyphs and anything longer\n * than one character get the wider forms.\n */\nexport function inferKeycapKind(label: string): KeycapKind {\n if (label === '⇪' || MODIFIER_LABELS.has(label)) return 'modifier';\n if (WIDE_GLYPHS.has(label)) return 'wide';\n if (label.length > 1) return 'wide';\n return 'square';\n}\n\n/** Visual style of a keycap chip. */\nexport type KeyCapVariant = 'default' | 'minimal';\n\n/** Props for {@link KeyCap}. */\nexport interface KeyCapProps {\n /** Glyph rendered in the chip (modifier or key). */\n label: string;\n /** Marks the chip as not required to trigger the action. In the default\n * variant the chip face inverts (dark face / light glyph) for\n * emphasis. In the `'minimal'` variant the chip's border becomes\n * dotted to read as \"may be held, but isn't required.\" */\n inverted?: boolean;\n /** Visual style. `'default'` (default) renders a filled chip; `'minimal'`\n * renders an unfilled chip whose border and legend are `currentColor`\n * — useful inline in colored prose / next to colored badges where the\n * chip should take the surrounding text color. */\n variant?: KeyCapVariant;\n className?: string;\n /** Optional inline style. Useful for one-off width overrides (e.g.\n * building a keyboard-layout where the space bar spans several\n * standard-key widths). The component sets no inline styles of its\n * own — everything else comes from the CSS module. */\n style?: CSSProperties;\n /** Override the chip's font-family. Accepts any CSS font-family\n * string. When omitted, the chip inherits from the design-system\n * UI font token (`--wzl-font-ui`). Useful for one-off cases where\n * a different face is desired — though the canonical move is to\n * override the CSS variable at the consumer's scope, not the prop. */\n font?: string;\n}\n\n/** Single bordered keycap chip for one glyph (modifier or key). Use\n * `KeySequence` to render a full shortcut. */\nexport function KeyCap({ label, inverted = false, variant = 'default', className, style, font }: KeyCapProps) {\n const resolvedStyle = font ? { ...style, fontFamily: font } : style;\n return (\n <kbd\n className={[s.key, className].filter(Boolean).join(' ')}\n data-kind={inferKeycapKind(label)}\n data-variant={variant === 'default' ? undefined : variant}\n data-inverted={inverted || undefined}\n style={resolvedStyle}\n >\n {label}\n </kbd>\n );\n}\n","import { Fragment } from 'react';\nimport s from './Keycaps.module.css';\nimport { KeyCap, inferKeycapKind, type KeyCapVariant } from './Keycap';\n\n/** One key in a shortcut. */\nexport interface KeySpec {\n /** Glyph rendered in the chip (modifier or key). */\n label: string;\n /** When true, the chip renders inverted to mark it as not required to\n * trigger the action (e.g. an optional modifier). Defaults to false. */\n optional?: boolean;\n}\n\n/** Where {@link KeySequence} draws its separator. */\nexport type KeySequenceJoins = 'all' | 'key' | 'none';\n\n/** Props for {@link KeySequence}. */\nexport interface KeySequenceProps {\n /** Keys to render. `undefined` or empty renders a muted em-dash.\n * Modifiers are always rendered first regardless of input order; relative\n * order within each group is preserved. */\n keys: readonly KeySpec[] | undefined;\n /** Glyph drawn wherever {@link joins} places a separator. Defaults to `'+'`. */\n separator?: string;\n /** Where the separator goes. Defaults to `'key'`.\n * - `'all'`: between every pair of chips — `⌘ + ⇧ + K`, `⌘ + ⇧`, `A + B`.\n * - `'key'`: before every non-modifier — `⌘ ⇧ + K`, `⌘ + K + L`, `A + B`.\n * Modifiers stay unjoined, so `⌘ ⇧` gets none.\n * - `'none'`: never. */\n joins?: KeySequenceJoins;\n /** Forwarded to every `KeyCap` in the sequence. `'minimal'` renders\n * unfilled chips whose border + legend are `currentColor`. */\n variant?: KeyCapVariant;\n /** Forwarded to every `KeyCap` in the sequence. Overrides the design-\n * system UI font for that chip only. */\n font?: string;\n className?: string;\n}\n\n/** Renders a shortcut as a row of `KeyCap` chips, one per key. Optional\n * keys render inverted to distinguish them from required ones. */\nexport function KeySequence({ keys, separator = '+', joins = 'key', variant = 'default', font, className }: KeySequenceProps) {\n if (!keys || keys.length === 0) {\n return <span className={[s.keysEmpty, className].filter(Boolean).join(' ')}>—</span>;\n }\n const ordered = keys\n .map((k, i) => ({ k, i }))\n .sort((a, b) => {\n const am = inferKeycapKind(a.k.label) === 'modifier' ? 0 : 1;\n const bm = inferKeycapKind(b.k.label) === 'modifier' ? 0 : 1;\n return am - bm || a.i - b.i;\n })\n .map(({ k }) => k);\n const sepBefore = (i: number): boolean =>\n i > 0 &&\n (joins === 'all' || (joins === 'key' && inferKeycapKind(ordered[i]!.label) !== 'modifier'));\n return (\n <span className={[s.keys, className].filter(Boolean).join(' ')}>\n {ordered.map((k, i) => (\n <Fragment key={i}>\n {sepBefore(i) ? <span className={s.sep}>{separator}</span> : null}\n <KeyCap label={k.label} inverted={k.optional ?? false} variant={variant} font={font} />\n </Fragment>\n ))}\n </span>\n );\n}\n","import type { ShortcutInput } from '../ToolPalette/formatShortcut';\nimport type { KeySpec } from './Keycaps';\nimport { keySpecFromKey, keySpecsFromMods, type KeySpecsFromModsOptions, type LogicalModSpec } from './keySpecsFromMods';\n\n/**\n * A shortcut as `KeySequence` keys, one per key: mod, shift, alt, then the\n * key, each in the platform's own legend (`⌘` on macOS, `Ctrl` elsewhere).\n * The `KeySpec` counterpart of `formatShortcutParts`, which always prints\n * macOS glyphs. `shift: 'optional'` becomes an optional key; a key list\n * renders its first key. Returns `undefined` for no shortcut.\n *\n * ```tsx\n * <KeySequence keys={keySpecsFromShortcut({ key: 'z', mod: true, shift: true })} />\n * ```\n */\nexport function keySpecsFromShortcut(\n shortcut: ShortcutInput | undefined,\n opts: KeySpecsFromModsOptions = {},\n): readonly KeySpec[] | undefined {\n if (!shortcut) return undefined;\n const mods: LogicalModSpec[] = [];\n if (shortcut.mod) mods.push({ name: 'mod' });\n if (shortcut.shift) mods.push(shortcut.shift === 'optional' ? { name: 'shift', optional: true } : { name: 'shift' });\n if (shortcut.alt) mods.push({ name: 'alt' });\n const key = typeof shortcut.key === 'string' ? shortcut.key : shortcut.key[0];\n const keys = keySpecsFromMods(mods, opts);\n return key === undefined ? keys : [...keys, keySpecFromKey(key, opts)];\n}\n","import type { IconName } from '../../icons/paths';\nimport type { KeyCapVariant } from './Keycap';\n\n/** The glyph for each variant, for a picker that shows them. */\nexport const KEYCAP_VARIANT_ICONS: Readonly<Record<KeyCapVariant, IconName>> = {\n default: 'variantSolid',\n minimal: 'variantOutline',\n};\n"],"mappings":";;;;;;;GC2CMK,IAAqF;CACzF,KAAK;EACH,OAAS;GAAE,MAAM;GAAQ,QAAQ;GAAQ,MAAM;EAAM;EACrD,SAAS;GAAE,MAAM;GAAQ,QAAQ;GAAQ,MAAM;EAAO;EACtD,OAAS;GAAE,MAAM;GAAQ,QAAQ;GAAQ,MAAM;EAAO;CACxD;CACA,OAAO;EACL,OAAS;GAAE,MAAM;GAAK,QAAQ;GAAK,MAAM;EAAQ;EACjD,SAAS;GAAE,MAAM;GAAK,QAAQ;GAAK,MAAM;EAAQ;EACjD,OAAS;GAAE,MAAM;GAAK,QAAQ;GAAK,MAAM;EAAQ;CACnD;CACA,KAAK;EACH,OAAS;GAAE,MAAM;GAAO,QAAQ;GAAO,MAAM;EAAS;EACtD,SAAS;GAAE,MAAM;GAAO,QAAQ;GAAO,MAAM;EAAM;EACnD,OAAS;GAAE,MAAM;GAAO,QAAQ;GAAO,MAAM;EAAM;CACrD;CACA,MAAM;EACJ,OAAS;GAAE,MAAM;GAAQ,QAAQ;GAAQ,MAAM;EAAU;EACzD,SAAS;GAAE,MAAM;GAAQ,QAAQ;GAAQ,MAAM;EAAO;EACtD,OAAS;GAAE,MAAM;GAAQ,QAAQ;GAAQ,MAAM;EAAO;CACxD;CAGA,MAAM;EACJ,OAAS;GAAE,MAAM;GAAK,QAAQ;GAAK,MAAM;EAAM;EAC/C,SAAS;GAAE,MAAM;GAAK,QAAQ;GAAK,MAAM;EAAM;EAC/C,OAAS;GAAE,MAAM;GAAK,QAAQ;GAAK,MAAM;EAAQ;CACnD;AACF,GAGaC,IAAuC,IAAI,IACtD,OAAO,OAAOD,CAAe,CAAC,CAAC,SAAS,MACtC,OAAO,OAAOE,CAAU,CAAC,CAAC,SAAS,MAAa,OAAO,OAAOC,CAAQ,CAAC,CACzE,CACF;AAMA,SAAgBC,IAA2B;CACzC,IAAI,OAAO,YAAc,KAAa,OAAO;CAG7C,IAAMC,KADU,UAAoE,eAC/D,YAAY,UAAU,aAAa,GAAA,CAAI,YAAY;CAIxE,OAHIA,EAAI,SAAS,KAAK,KAAKA,EAAI,SAAS,QAAQ,KAAKA,EAAI,SAAS,QAAQ,KAAKA,EAAI,SAAS,MAAM,IAAU,UACxGA,EAAI,SAAS,KAAK,IAAU,YAC5BA,EAAI,SAAS,OAAO,KAAKA,EAAI,SAAS,KAAK,IAAU,UAClD;AACT;AAsBA,SAAgBC,EACd,GACA,IAAgC,CAAC,GACb;CACpB,IAAMC,IAAWC,EAAK,YAAYJ,EAAe,GAC3CK,IAASD,EAAK,UAAU;CAC9B,OAAOE,EAAK,KAAK,MAAM;EACrB,IAAMC,IAAQX,EAAgBY,EAAE,KAAK,CAACL,EAAS,CAACE;EAChD,OAAOG,EAAE,WAAW;GAAE;GAAO,UAAU;EAAK,IAAI,EAAE,SAAM;CAC1D,CAAC;AACH;AAKA,IAAMC,IAA2E;CAC/E,QAAa;EAAE,OAAO;GAAE,MAAM;GAAQ,QAAQ;GAAY,MAAM;EAAM;EAAS,SAAS;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAM;EAAS,OAAO;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAM;CAAE;CACtN,OAAa;EAAE,OAAO;GAAE,MAAM;GAAQ,QAAQ;GAAY,MAAM;EAAS;EAAM,SAAS;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAQ;EAAO,OAAO;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAQ;CAAE;CACxN,QAAa;EAAE,OAAO;GAAE,MAAM;GAAQ,QAAQ;GAAY,MAAM;EAAS;EAAM,SAAS;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAQ;EAAO,OAAO;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAQ;CAAE;CACxN,KAAa;EAAE,OAAO;GAAE,MAAM;GAAQ,QAAQ;GAAY,MAAM;EAAM;EAAS,SAAS;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAM;EAAS,OAAO;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAM;CAAE;CACtN,OAAa;EAAE,OAAO;GAAE,MAAM;GAAQ,QAAQ;GAAY,MAAM;EAAQ;EAAO,SAAS;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAQ;EAAO,OAAO;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAQ;CAAE;CACxN,KAAa;EAAE,OAAO;GAAE,MAAM;GAAQ,QAAQ;GAAY,MAAM;EAAQ;EAAO,SAAS;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAQ;EAAO,OAAO;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAQ;CAAE;CACxN,WAAa;EAAE,OAAO;GAAE,MAAM;GAAQ,QAAQ;GAAY,MAAM;EAAY;EAAG,SAAS;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAY;EAAG,OAAO;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAY;CAAE;CAC5N,QAAa;EAAE,OAAO;GAAE,MAAM;GAAQ,QAAQ;GAAY,MAAM;EAAS;EAAM,SAAS;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAS;EAAM,OAAO;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAS;CAAE;CAGzN,aAAa;EAAE,OAAO;GAAE,MAAM;GAAQ,QAAQ;GAAY,MAAM;EAAO;EAAQ,SAAS;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAO;EAAQ,OAAO;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAO;CAAE;CACvN,SAAa;EAAE,OAAO;GAAE,MAAM;GAAQ,QAAQ;GAAY,MAAM;EAAI;EAAW,SAAS;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAI;EAAW,OAAO;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAI;CAAE;CACpN,WAAa;EAAE,OAAO;GAAE,MAAM;GAAQ,QAAQ;GAAY,MAAM;EAAI;EAAW,SAAS;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAI;EAAW,OAAO;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAI;CAAE;CACpN,WAAa;EAAE,OAAO;GAAE,MAAM;GAAQ,QAAQ;GAAY,MAAM;EAAI;EAAW,SAAS;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAI;EAAW,OAAO;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAI;CAAE;CACpN,YAAa;EAAE,OAAO;GAAE,MAAM;GAAQ,QAAQ;GAAY,MAAM;EAAI;EAAW,SAAS;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAI;EAAW,OAAO;GAAE,MAAM;GAAa,QAAQ;GAAa,MAAM;EAAI;CAAE;AACtN;AAkBA,SAAgBC,EACd,GACA,IAAyD,CAAC,GACjD;CACT,IAAMP,IAAWC,EAAK,YAAYJ,EAAe,GAC3CK,IAASD,EAAK,UAAU,QACxBO,IAAQF,EAAUR,IAClBM,IAAQI,IAAQA,EAAMR,EAAS,CAACE,KAAUJ,EAAI,WAAW,IAAIA,EAAI,YAAY,IAAIA;CACvF,OAAOG,EAAK,WAAW;EAAE;EAAO,UAAU;CAAK,IAAI,EAAE,SAAM;AAC7D;;;ACzKA,IAAMQ,oBAAc,IAAI,IAAI;CAAC;CAAK;CAAK;AAAG,CAAC;AAY3C,SAAgBC,EAAgB,GAA2B;CAIzD,OAHIN,MAAU,OAAOV,EAAgB,IAAIU,CAAK,IAAU,aACpDK,EAAY,IAAIL,CAAK,KACrBA,EAAM,SAAS,IAAU,SACtB;AACT;AAmCA,SAAgBO,EAAO,EAAE,UAAO,cAAW,IAAO,aAAU,WAAW,cAAW,UAAO,WAAqB;CAC5G,IAAMC,IAAgBC,IAAO;EAAE,GAAGC;EAAO,YAAYD;CAAK,IAAIC;CAC9D,OACE,kBAAC,OAAD;EACE,WAAW,CAAC1B,EAAE,KAAK2B,CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;EACtD,aAAWL,EAAgBN,CAAK;EAChC,gBAAcY,MAAY,YAAY,KAAA,IAAYA;EAClD,iBAAeC,KAAY,KAAA;EAC3B,OAAOL;EAEN,UAAAR;CACE,CAAA;AAET;;;AC5BA,SAAgBc,EAAY,EAAE,SAAM,eAAY,KAAK,WAAQ,OAAO,aAAU,WAAW,SAAM,gBAA+B;CAC5H,IAAI,CAACC,KAAQA,EAAK,WAAW,GAC3B,OAAO,kBAAC,QAAD;EAAM,WAAW,CAAC9B,EAAE,WAAW0B,CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;EAAG,UAAA;CAAO,CAAA;CAErF,IAAMK,IAAUD,EACb,KAAK,GAAG,OAAO;EAAE;EAAG;CAAE,EAAE,CAAC,CACzB,MAAM,GAAG,OACGT,EAAgBW,EAAE,EAAE,KAAK,MAAM,aAAa,IAAI,MAChDX,EAAgBY,EAAE,EAAE,KAAK,MAAM,aAAa,IAAI,MACzCD,EAAE,IAAIC,EAAE,CAC3B,CAAC,CACD,KAAK,EAAE,WAAQC,CAAC,GACbC,KAAa,MACjBC,IAAI,MACHC,MAAU,SAAUA,MAAU,SAAShB,EAAgBU,EAAQK,EAAE,CAAE,KAAK,MAAM;CACjF,OACE,kBAAC,QAAD;EAAM,WAAW,CAACpC,EAAE,MAAM0B,CAAS,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG;EAC1D,UAAAK,EAAQ,KAAK,GAAG,MACf,kBAAC9B,GAAD,EAAA,UAAA,CACGkC,EAAUC,CAAC,IAAI,kBAAC,QAAD;GAAM,WAAWpC,EAAE;GAAM,UAAAsC;EAAgB,CAAA,IAAI,MAC7D,kBAAChB,GAAD;GAAQ,OAAOY,EAAE;GAAO,UAAUA,EAAE,YAAY;GAAgB;GAAe;EAAO,CAAA,CAC9E,EAAA,GAHKE,CAGL,CACX;CACG,CAAA;AAEV;;;ACnDA,SAAgBG,EACd,GACA,IAAgC,CAAC,GACD;CAChC,IAAI,CAACC,GAAU;CACf,IAAM1B,IAAyB,CAAC;CAGhC,AAFI0B,EAAS,OAAK1B,EAAK,KAAK,EAAE,MAAM,MAAM,CAAC,GACvC0B,EAAS,SAAO1B,EAAK,KAAK0B,EAAS,UAAU,aAAa;EAAE,MAAM;EAAS,UAAU;CAAK,IAAI,EAAE,MAAM,QAAQ,CAAC,GAC/GA,EAAS,OAAK1B,EAAK,KAAK,EAAE,MAAM,MAAM,CAAC;CAC3C,IAAM2B,IAAM,OAAOD,EAAS,OAAQ,WAAWA,EAAS,MAAMA,EAAS,IAAI,IACrEV,IAAOpB,EAAiBI,GAAMF,CAAI;CACxC,OAAO6B,MAAQ,KAAA,IAAYX,IAAO,CAAC,GAAGA,GAAMZ,EAAeuB,GAAK7B,CAAI,CAAC;AACvE;;;ACvBA,IAAa8B,IAAkE;CAC7E,SAAS;CACT,SAAS;AACX"}