@gabvdl/ui 0.0.14

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 (330) hide show
  1. package/README.md +95 -0
  2. package/dist/components/button/button.d.ts +39 -0
  3. package/dist/components/button/button.d.ts.map +1 -0
  4. package/dist/components/button/button.js +72 -0
  5. package/dist/components/button/button.js.map +1 -0
  6. package/dist/components/button/index.d.ts +5 -0
  7. package/dist/components/button/index.d.ts.map +1 -0
  8. package/dist/components/button/tooltip.d.ts +31 -0
  9. package/dist/components/button/tooltip.d.ts.map +1 -0
  10. package/dist/components/button/tooltip.js +83 -0
  11. package/dist/components/button/tooltip.js.map +1 -0
  12. package/dist/components/changelog/changelog.d.ts +52 -0
  13. package/dist/components/changelog/changelog.d.ts.map +1 -0
  14. package/dist/components/changelog/changelog.js +164 -0
  15. package/dist/components/changelog/changelog.js.map +1 -0
  16. package/dist/components/changelog/index.d.ts +3 -0
  17. package/dist/components/changelog/index.d.ts.map +1 -0
  18. package/dist/components/copy-button/copy-button.d.ts +16 -0
  19. package/dist/components/copy-button/copy-button.d.ts.map +1 -0
  20. package/dist/components/copy-button/copy-button.js +40 -0
  21. package/dist/components/copy-button/copy-button.js.map +1 -0
  22. package/dist/components/copy-button/index.d.ts +3 -0
  23. package/dist/components/copy-button/index.d.ts.map +1 -0
  24. package/dist/components/drop-zone/drop-zone.d.ts +20 -0
  25. package/dist/components/drop-zone/drop-zone.d.ts.map +1 -0
  26. package/dist/components/drop-zone/drop-zone.js +54 -0
  27. package/dist/components/drop-zone/drop-zone.js.map +1 -0
  28. package/dist/components/drop-zone/index.d.ts +5 -0
  29. package/dist/components/drop-zone/index.d.ts.map +1 -0
  30. package/dist/components/drop-zone/use-file-drop.d.ts +45 -0
  31. package/dist/components/drop-zone/use-file-drop.d.ts.map +1 -0
  32. package/dist/components/drop-zone/use-file-drop.js +97 -0
  33. package/dist/components/drop-zone/use-file-drop.js.map +1 -0
  34. package/dist/components/element-picker/element-picker-field.d.ts +30 -0
  35. package/dist/components/element-picker/element-picker-field.d.ts.map +1 -0
  36. package/dist/components/element-picker/element-picker-field.js +273 -0
  37. package/dist/components/element-picker/element-picker-field.js.map +1 -0
  38. package/dist/components/element-picker/element-picker.d.ts +45 -0
  39. package/dist/components/element-picker/element-picker.d.ts.map +1 -0
  40. package/dist/components/element-picker/element-picker.js +179 -0
  41. package/dist/components/element-picker/element-picker.js.map +1 -0
  42. package/dist/components/element-picker/element-preview.d.ts +23 -0
  43. package/dist/components/element-picker/element-preview.d.ts.map +1 -0
  44. package/dist/components/element-picker/element-preview.js +72 -0
  45. package/dist/components/element-picker/element-preview.js.map +1 -0
  46. package/dist/components/element-picker/index.d.ts +12 -0
  47. package/dist/components/element-picker/index.d.ts.map +1 -0
  48. package/dist/components/element-picker/parse.d.ts +32 -0
  49. package/dist/components/element-picker/parse.d.ts.map +1 -0
  50. package/dist/components/element-picker/parse.js +230 -0
  51. package/dist/components/element-picker/parse.js.map +1 -0
  52. package/dist/components/element-picker/types.d.ts +72 -0
  53. package/dist/components/element-picker/types.d.ts.map +1 -0
  54. package/dist/components/element-picker/use-element-picker.d.ts +56 -0
  55. package/dist/components/element-picker/use-element-picker.d.ts.map +1 -0
  56. package/dist/components/element-picker/use-element-picker.js +201 -0
  57. package/dist/components/element-picker/use-element-picker.js.map +1 -0
  58. package/dist/components/empty-state/empty-state.d.ts +16 -0
  59. package/dist/components/empty-state/empty-state.d.ts.map +1 -0
  60. package/dist/components/empty-state/empty-state.js +41 -0
  61. package/dist/components/empty-state/empty-state.js.map +1 -0
  62. package/dist/components/empty-state/index.d.ts +3 -0
  63. package/dist/components/empty-state/index.d.ts.map +1 -0
  64. package/dist/components/floating-panel/dock-context.d.ts +66 -0
  65. package/dist/components/floating-panel/dock-context.d.ts.map +1 -0
  66. package/dist/components/floating-panel/dock-context.js +96 -0
  67. package/dist/components/floating-panel/dock-context.js.map +1 -0
  68. package/dist/components/floating-panel/dock.d.ts +26 -0
  69. package/dist/components/floating-panel/dock.d.ts.map +1 -0
  70. package/dist/components/floating-panel/dock.js +46 -0
  71. package/dist/components/floating-panel/dock.js.map +1 -0
  72. package/dist/components/floating-panel/floating-panel.d.ts +69 -0
  73. package/dist/components/floating-panel/floating-panel.d.ts.map +1 -0
  74. package/dist/components/floating-panel/floating-panel.js +285 -0
  75. package/dist/components/floating-panel/floating-panel.js.map +1 -0
  76. package/dist/components/floating-panel/index.d.ts +7 -0
  77. package/dist/components/floating-panel/index.d.ts.map +1 -0
  78. package/dist/components/fuzzy-list/fuzzy-list.d.ts +96 -0
  79. package/dist/components/fuzzy-list/fuzzy-list.d.ts.map +1 -0
  80. package/dist/components/fuzzy-list/fuzzy-list.js +127 -0
  81. package/dist/components/fuzzy-list/fuzzy-list.js.map +1 -0
  82. package/dist/components/fuzzy-list/index.d.ts +4 -0
  83. package/dist/components/fuzzy-list/index.d.ts.map +1 -0
  84. package/dist/components/global-search/global-search.d.ts +78 -0
  85. package/dist/components/global-search/global-search.d.ts.map +1 -0
  86. package/dist/components/global-search/global-search.js +181 -0
  87. package/dist/components/global-search/global-search.js.map +1 -0
  88. package/dist/components/global-search/hotkey.d.ts +23 -0
  89. package/dist/components/global-search/hotkey.d.ts.map +1 -0
  90. package/dist/components/global-search/hotkey.js +41 -0
  91. package/dist/components/global-search/hotkey.js.map +1 -0
  92. package/dist/components/global-search/index.d.ts +5 -0
  93. package/dist/components/global-search/index.d.ts.map +1 -0
  94. package/dist/components/iframe-preview/iframe-preview.d.ts +64 -0
  95. package/dist/components/iframe-preview/iframe-preview.d.ts.map +1 -0
  96. package/dist/components/iframe-preview/iframe-preview.js +257 -0
  97. package/dist/components/iframe-preview/iframe-preview.js.map +1 -0
  98. package/dist/components/iframe-preview/index.d.ts +3 -0
  99. package/dist/components/iframe-preview/index.d.ts.map +1 -0
  100. package/dist/components/image-viewer/image-viewer.d.ts +30 -0
  101. package/dist/components/image-viewer/image-viewer.d.ts.map +1 -0
  102. package/dist/components/image-viewer/image-viewer.js +226 -0
  103. package/dist/components/image-viewer/image-viewer.js.map +1 -0
  104. package/dist/components/image-viewer/index.d.ts +4 -0
  105. package/dist/components/image-viewer/index.d.ts.map +1 -0
  106. package/dist/components/image-viewer/progressive-image.d.ts +20 -0
  107. package/dist/components/image-viewer/progressive-image.d.ts.map +1 -0
  108. package/dist/components/image-viewer/progressive-image.js +62 -0
  109. package/dist/components/image-viewer/progressive-image.js.map +1 -0
  110. package/dist/components/image-viewer/viewable-image.d.ts +17 -0
  111. package/dist/components/image-viewer/viewable-image.d.ts.map +1 -0
  112. package/dist/components/image-viewer/viewable-image.js +38 -0
  113. package/dist/components/image-viewer/viewable-image.js.map +1 -0
  114. package/dist/components/input/index.d.ts +3 -0
  115. package/dist/components/input/index.d.ts.map +1 -0
  116. package/dist/components/input/input.d.ts +15 -0
  117. package/dist/components/input/input.d.ts.map +1 -0
  118. package/dist/components/input/input.js +56 -0
  119. package/dist/components/input/input.js.map +1 -0
  120. package/dist/components/modal/index.d.ts +5 -0
  121. package/dist/components/modal/index.d.ts.map +1 -0
  122. package/dist/components/modal/modal-context.d.ts +37 -0
  123. package/dist/components/modal/modal-context.d.ts.map +1 -0
  124. package/dist/components/modal/modal-context.js +81 -0
  125. package/dist/components/modal/modal-context.js.map +1 -0
  126. package/dist/components/modal/modal.d.ts +28 -0
  127. package/dist/components/modal/modal.d.ts.map +1 -0
  128. package/dist/components/modal/modal.js +94 -0
  129. package/dist/components/modal/modal.js.map +1 -0
  130. package/dist/components/nav-2d/index.d.ts +3 -0
  131. package/dist/components/nav-2d/index.d.ts.map +1 -0
  132. package/dist/components/nav-2d/nav-2d.d.ts +59 -0
  133. package/dist/components/nav-2d/nav-2d.d.ts.map +1 -0
  134. package/dist/components/nav-2d/nav-2d.js +290 -0
  135. package/dist/components/nav-2d/nav-2d.js.map +1 -0
  136. package/dist/components/phone-preview/index.d.ts +3 -0
  137. package/dist/components/phone-preview/index.d.ts.map +1 -0
  138. package/dist/components/phone-preview/phone-preview.d.ts +45 -0
  139. package/dist/components/phone-preview/phone-preview.d.ts.map +1 -0
  140. package/dist/components/phone-preview/phone-preview.js +117 -0
  141. package/dist/components/phone-preview/phone-preview.js.map +1 -0
  142. package/dist/components/progressive-bash/index.d.ts +7 -0
  143. package/dist/components/progressive-bash/index.d.ts.map +1 -0
  144. package/dist/components/progressive-bash/parse.d.ts +88 -0
  145. package/dist/components/progressive-bash/parse.d.ts.map +1 -0
  146. package/dist/components/progressive-bash/parse.js +120 -0
  147. package/dist/components/progressive-bash/parse.js.map +1 -0
  148. package/dist/components/progressive-bash/playback.d.ts +50 -0
  149. package/dist/components/progressive-bash/playback.d.ts.map +1 -0
  150. package/dist/components/progressive-bash/playback.js +19 -0
  151. package/dist/components/progressive-bash/playback.js.map +1 -0
  152. package/dist/components/progressive-bash/progressive-bash.d.ts +97 -0
  153. package/dist/components/progressive-bash/progressive-bash.d.ts.map +1 -0
  154. package/dist/components/progressive-bash/progressive-bash.js +377 -0
  155. package/dist/components/progressive-bash/progressive-bash.js.map +1 -0
  156. package/dist/components/progressive-list/index.d.ts +3 -0
  157. package/dist/components/progressive-list/index.d.ts.map +1 -0
  158. package/dist/components/progressive-list/progressive-list.d.ts +55 -0
  159. package/dist/components/progressive-list/progressive-list.d.ts.map +1 -0
  160. package/dist/components/progressive-list/progressive-list.js +83 -0
  161. package/dist/components/progressive-list/progressive-list.js.map +1 -0
  162. package/dist/components/progressive-table/index.d.ts +3 -0
  163. package/dist/components/progressive-table/index.d.ts.map +1 -0
  164. package/dist/components/progressive-table/progressive-table.d.ts +58 -0
  165. package/dist/components/progressive-table/progressive-table.d.ts.map +1 -0
  166. package/dist/components/progressive-table/progressive-table.js +86 -0
  167. package/dist/components/progressive-table/progressive-table.js.map +1 -0
  168. package/dist/components/progressive-text/index.d.ts +3 -0
  169. package/dist/components/progressive-text/index.d.ts.map +1 -0
  170. package/dist/components/progressive-text/progressive-text.d.ts +54 -0
  171. package/dist/components/progressive-text/progressive-text.d.ts.map +1 -0
  172. package/dist/components/progressive-text/progressive-text.js +97 -0
  173. package/dist/components/progressive-text/progressive-text.js.map +1 -0
  174. package/dist/components/progressive-timeline/index.d.ts +3 -0
  175. package/dist/components/progressive-timeline/index.d.ts.map +1 -0
  176. package/dist/components/progressive-timeline/progressive-timeline.d.ts +46 -0
  177. package/dist/components/progressive-timeline/progressive-timeline.d.ts.map +1 -0
  178. package/dist/components/progressive-timeline/progressive-timeline.js +62 -0
  179. package/dist/components/progressive-timeline/progressive-timeline.js.map +1 -0
  180. package/dist/components/relative-time/index.d.ts +3 -0
  181. package/dist/components/relative-time/index.d.ts.map +1 -0
  182. package/dist/components/relative-time/relative-time.d.ts +14 -0
  183. package/dist/components/relative-time/relative-time.d.ts.map +1 -0
  184. package/dist/components/relative-time/relative-time.js +15 -0
  185. package/dist/components/relative-time/relative-time.js.map +1 -0
  186. package/dist/components/resizable-layout/index.d.ts +3 -0
  187. package/dist/components/resizable-layout/index.d.ts.map +1 -0
  188. package/dist/components/resizable-layout/resizable-layout.d.ts +113 -0
  189. package/dist/components/resizable-layout/resizable-layout.d.ts.map +1 -0
  190. package/dist/components/resizable-layout/resizable-layout.js +398 -0
  191. package/dist/components/resizable-layout/resizable-layout.js.map +1 -0
  192. package/dist/components/rich-input/compose.d.ts +13 -0
  193. package/dist/components/rich-input/compose.d.ts.map +1 -0
  194. package/dist/components/rich-input/compose.js +28 -0
  195. package/dist/components/rich-input/compose.js.map +1 -0
  196. package/dist/components/rich-input/index.d.ts +5 -0
  197. package/dist/components/rich-input/index.d.ts.map +1 -0
  198. package/dist/components/rich-input/parts.d.ts +53 -0
  199. package/dist/components/rich-input/parts.d.ts.map +1 -0
  200. package/dist/components/rich-input/parts.js +285 -0
  201. package/dist/components/rich-input/parts.js.map +1 -0
  202. package/dist/components/rich-input/rich-input.d.ts +64 -0
  203. package/dist/components/rich-input/rich-input.d.ts.map +1 -0
  204. package/dist/components/rich-input/rich-input.js +351 -0
  205. package/dist/components/rich-input/rich-input.js.map +1 -0
  206. package/dist/components/rich-input/types.d.ts +92 -0
  207. package/dist/components/rich-input/types.d.ts.map +1 -0
  208. package/dist/components/rich-input/use-draft.d.ts +9 -0
  209. package/dist/components/rich-input/use-draft.d.ts.map +1 -0
  210. package/dist/components/rich-input/use-draft.js +47 -0
  211. package/dist/components/rich-input/use-draft.js.map +1 -0
  212. package/dist/components/rich-input/use-file-upload.d.ts +18 -0
  213. package/dist/components/rich-input/use-file-upload.d.ts.map +1 -0
  214. package/dist/components/rich-input/use-file-upload.js +88 -0
  215. package/dist/components/rich-input/use-file-upload.js.map +1 -0
  216. package/dist/components/rich-input/use-guidelines.d.ts +16 -0
  217. package/dist/components/rich-input/use-guidelines.d.ts.map +1 -0
  218. package/dist/components/rich-input/use-guidelines.js +85 -0
  219. package/dist/components/rich-input/use-guidelines.js.map +1 -0
  220. package/dist/components/rich-input/use-input-history.d.ts +22 -0
  221. package/dist/components/rich-input/use-input-history.d.ts.map +1 -0
  222. package/dist/components/rich-input/use-input-history.js +61 -0
  223. package/dist/components/rich-input/use-input-history.js.map +1 -0
  224. package/dist/components/rich-input/use-mention.d.ts +24 -0
  225. package/dist/components/rich-input/use-mention.d.ts.map +1 -0
  226. package/dist/components/rich-input/use-mention.js +54 -0
  227. package/dist/components/rich-input/use-mention.js.map +1 -0
  228. package/dist/components/search-input/index.d.ts +3 -0
  229. package/dist/components/search-input/index.d.ts.map +1 -0
  230. package/dist/components/search-input/search-input.d.ts +14 -0
  231. package/dist/components/search-input/search-input.d.ts.map +1 -0
  232. package/dist/components/search-input/search-input.js +63 -0
  233. package/dist/components/search-input/search-input.js.map +1 -0
  234. package/dist/components/skeleton/index.d.ts +3 -0
  235. package/dist/components/skeleton/index.d.ts.map +1 -0
  236. package/dist/components/skeleton/skeleton.d.ts +19 -0
  237. package/dist/components/skeleton/skeleton.d.ts.map +1 -0
  238. package/dist/components/skeleton/skeleton.js +29 -0
  239. package/dist/components/skeleton/skeleton.js.map +1 -0
  240. package/dist/components/spinner/index.d.ts +3 -0
  241. package/dist/components/spinner/index.d.ts.map +1 -0
  242. package/dist/components/spinner/spinner.d.ts +11 -0
  243. package/dist/components/spinner/spinner.d.ts.map +1 -0
  244. package/dist/components/spinner/spinner.js +32 -0
  245. package/dist/components/spinner/spinner.js.map +1 -0
  246. package/dist/components/status-badge/index.d.ts +3 -0
  247. package/dist/components/status-badge/index.d.ts.map +1 -0
  248. package/dist/components/status-badge/status-badge.d.ts +31 -0
  249. package/dist/components/status-badge/status-badge.d.ts.map +1 -0
  250. package/dist/components/status-badge/status-badge.js +53 -0
  251. package/dist/components/status-badge/status-badge.js.map +1 -0
  252. package/dist/components/theme/index.d.ts +5 -0
  253. package/dist/components/theme/index.d.ts.map +1 -0
  254. package/dist/components/theme/theme-toggle.d.ts +11 -0
  255. package/dist/components/theme/theme-toggle.d.ts.map +1 -0
  256. package/dist/components/theme/theme-toggle.js +57 -0
  257. package/dist/components/theme/theme-toggle.js.map +1 -0
  258. package/dist/components/theme/theme.d.ts +29 -0
  259. package/dist/components/theme/theme.d.ts.map +1 -0
  260. package/dist/components/theme/theme.js +70 -0
  261. package/dist/components/theme/theme.js.map +1 -0
  262. package/dist/components/toast/index.d.ts +3 -0
  263. package/dist/components/toast/index.d.ts.map +1 -0
  264. package/dist/components/toast/toast.d.ts +64 -0
  265. package/dist/components/toast/toast.d.ts.map +1 -0
  266. package/dist/components/toast/toast.js +155 -0
  267. package/dist/components/toast/toast.js.map +1 -0
  268. package/dist/components/virtual-list/index.d.ts +3 -0
  269. package/dist/components/virtual-list/index.d.ts.map +1 -0
  270. package/dist/components/virtual-list/virtual-list.d.ts +71 -0
  271. package/dist/components/virtual-list/virtual-list.d.ts.map +1 -0
  272. package/dist/components/virtual-list/virtual-list.js +65 -0
  273. package/dist/components/virtual-list/virtual-list.js.map +1 -0
  274. package/dist/hooks/index.d.ts +12 -0
  275. package/dist/hooks/index.d.ts.map +1 -0
  276. package/dist/hooks/use-copy-to-clipboard.d.ts +26 -0
  277. package/dist/hooks/use-copy-to-clipboard.d.ts.map +1 -0
  278. package/dist/hooks/use-copy-to-clipboard.js +36 -0
  279. package/dist/hooks/use-copy-to-clipboard.js.map +1 -0
  280. package/dist/hooks/use-debounced-value.d.ts +23 -0
  281. package/dist/hooks/use-debounced-value.d.ts.map +1 -0
  282. package/dist/hooks/use-debounced-value.js +19 -0
  283. package/dist/hooks/use-debounced-value.js.map +1 -0
  284. package/dist/hooks/use-intersection.d.ts +25 -0
  285. package/dist/hooks/use-intersection.d.ts.map +1 -0
  286. package/dist/hooks/use-intersection.js +38 -0
  287. package/dist/hooks/use-intersection.js.map +1 -0
  288. package/dist/hooks/use-local-storage.d.ts +12 -0
  289. package/dist/hooks/use-local-storage.d.ts.map +1 -0
  290. package/dist/hooks/use-local-storage.js +43 -0
  291. package/dist/hooks/use-local-storage.js.map +1 -0
  292. package/dist/hooks/use-long-press.d.ts +37 -0
  293. package/dist/hooks/use-long-press.d.ts.map +1 -0
  294. package/dist/hooks/use-long-press.js +39 -0
  295. package/dist/hooks/use-long-press.js.map +1 -0
  296. package/dist/hooks/use-media-query.d.ts +17 -0
  297. package/dist/hooks/use-media-query.d.ts.map +1 -0
  298. package/dist/hooks/use-media-query.js +37 -0
  299. package/dist/hooks/use-media-query.js.map +1 -0
  300. package/dist/hooks/use-overlay.d.ts +20 -0
  301. package/dist/hooks/use-overlay.d.ts.map +1 -0
  302. package/dist/hooks/use-overlay.js +42 -0
  303. package/dist/hooks/use-overlay.js.map +1 -0
  304. package/dist/image-viewer.css +152 -0
  305. package/dist/index.d.ts +67 -0
  306. package/dist/index.d.ts.map +1 -0
  307. package/dist/index.js +161 -0
  308. package/dist/index.js.map +1 -0
  309. package/dist/lib/format.d.ts +19 -0
  310. package/dist/lib/format.d.ts.map +1 -0
  311. package/dist/lib/format.js +62 -0
  312. package/dist/lib/format.js.map +1 -0
  313. package/dist/lib/highlight.d.ts +15 -0
  314. package/dist/lib/highlight.d.ts.map +1 -0
  315. package/dist/lib/highlight.js +39 -0
  316. package/dist/lib/highlight.js.map +1 -0
  317. package/dist/lib/search.d.ts +40 -0
  318. package/dist/lib/search.d.ts.map +1 -0
  319. package/dist/lib/search.js +91 -0
  320. package/dist/lib/search.js.map +1 -0
  321. package/dist/lib/utils.d.ts +4 -0
  322. package/dist/lib/utils.d.ts.map +1 -0
  323. package/dist/lib/utils.js +9 -0
  324. package/dist/lib/utils.js.map +1 -0
  325. package/dist/overlay.css +78 -0
  326. package/dist/styles.css +6 -0
  327. package/dist/theme.css +81 -0
  328. package/dist/tooltip.css +53 -0
  329. package/dist/virtual-list.css +29 -0
  330. package/package.json +77 -0
@@ -0,0 +1,290 @@
1
+ import { jsx as c, jsxs as S, Fragment as F } from "react/jsx-runtime";
2
+ import { useId as Z, useRef as P, useLayoutEffect as $, useEffect as J, useState as O, useCallback as I, useMemo as ee, useContext as te, createContext as ne } from "react";
3
+ import { createPortal as G } from "react-dom";
4
+ const K = ne(null);
5
+ function re() {
6
+ const e = te(K);
7
+ if (!e) throw new Error("useNav2D must be used within <Nav2DProvider>");
8
+ return e;
9
+ }
10
+ const oe = 12, E = 56, ie = 55, se = 1.6, ce = 320, le = 34, ae = (e) => Math.cos(e * Math.PI / 180);
11
+ function ue(e, o, a, w) {
12
+ const f = Math.hypot(o.x, o.y);
13
+ if (f < 1e-3) return null;
14
+ const d = o.x / f, u = o.y / f, l = ae(ie);
15
+ let h = null, p = 1 / 0;
16
+ for (const g of a) {
17
+ if (g.id === w) continue;
18
+ const s = g.el.getBoundingClientRect();
19
+ if (s.width === 0 && s.height === 0) continue;
20
+ const M = s.left + s.width / 2, y = s.top + s.height / 2, X = M - e.x, b = y - e.y, Y = Math.hypot(X, b);
21
+ if (Y < 1) continue;
22
+ const m = X * d + b * u;
23
+ if (m <= 0 || m / Y < l) continue;
24
+ const k = Math.abs(X * u - b * d), D = m + k * se;
25
+ D < p && (p = D, h = { id: g.id, cx: M, cy: y });
26
+ }
27
+ return h;
28
+ }
29
+ function de(e, o, a) {
30
+ let w = null;
31
+ for (const f of a) {
32
+ const d = f.el.getBoundingClientRect();
33
+ e >= d.left && e <= d.right && o >= d.top && o <= d.bottom && (w = f.id);
34
+ }
35
+ return w;
36
+ }
37
+ const W = (e) => {
38
+ const o = e.getBoundingClientRect();
39
+ return { x: o.left + o.width / 2, y: o.top + o.height / 2 };
40
+ };
41
+ function he({
42
+ children: e,
43
+ defaultSelectedId: o = null,
44
+ defaultEnabled: a = !0,
45
+ bounds: w = "viewport",
46
+ onSelect: f,
47
+ onActivate: d
48
+ }) {
49
+ const u = P(/* @__PURE__ */ new Map()), [l, h] = O(o), [p, g] = O(null), [s, M] = O(a), [y, X] = O(null), b = P(l);
50
+ b.current = l;
51
+ const Y = P(f);
52
+ Y.current = f;
53
+ const m = P(d);
54
+ m.current = d;
55
+ const k = I((t) => {
56
+ h((n) => {
57
+ var r;
58
+ return n !== t && ((r = Y.current) == null || r.call(Y, t)), t;
59
+ });
60
+ }, []), D = I((t) => {
61
+ var i, C;
62
+ const n = t ?? b.current;
63
+ if (!n) return;
64
+ const r = u.current.get(n);
65
+ (i = r == null ? void 0 : r.onActivate) == null || i.call(r), (C = m.current) == null || C.call(m, n);
66
+ }, []), A = I((t, n, r) => (u.current.set(t, { id: t, el: n, onActivate: r }), h((i) => i ?? t), () => {
67
+ u.current.delete(t), h((i) => i === t ? null : i), g((i) => i === t ? null : i);
68
+ }), []), L = I((t, n) => {
69
+ const r = u.current.get(t);
70
+ r && (r.onActivate = n);
71
+ }, []), R = P(null), _ = P(null), V = I((t) => {
72
+ t.preventDefault(), t.currentTarget.setPointerCapture(t.pointerId);
73
+ const n = b.current ? u.current.get(b.current) : null, r = n ? W(n.el) : { x: t.clientX, y: t.clientY };
74
+ R.current = {
75
+ baseX: t.clientX,
76
+ baseY: t.clientY,
77
+ origin: r,
78
+ dragging: !1,
79
+ preview: null
80
+ }, X({
81
+ baseX: t.clientX,
82
+ baseY: t.clientY,
83
+ knobX: t.clientX,
84
+ knobY: t.clientY,
85
+ originX: r.x,
86
+ originY: r.y,
87
+ targetX: null,
88
+ targetY: null,
89
+ active: !1
90
+ });
91
+ }, []), q = I((t) => {
92
+ const n = R.current;
93
+ if (!n) return;
94
+ const r = t.clientX - n.baseX, i = t.clientY - n.baseY;
95
+ if (!n.dragging && Math.hypot(r, i) < oe) return;
96
+ n.dragging = !0;
97
+ const C = b.current ? u.current.get(b.current) : null, x = C ? W(C.el) : { x: n.baseX, y: n.baseY };
98
+ n.origin = x;
99
+ const v = ue(x, { x: r, y: i }, [...u.current.values()], b.current);
100
+ n.preview = (v == null ? void 0 : v.id) ?? null, g((v == null ? void 0 : v.id) ?? null);
101
+ const T = Math.hypot(r, i), B = T > E ? E / T : 1;
102
+ X({
103
+ baseX: n.baseX,
104
+ baseY: n.baseY,
105
+ knobX: n.baseX + r * B,
106
+ knobY: n.baseY + i * B,
107
+ originX: x.x,
108
+ originY: x.y,
109
+ targetX: (v == null ? void 0 : v.cx) ?? x.x + (r / T || 0) * 360,
110
+ targetY: (v == null ? void 0 : v.cy) ?? x.y + (i / T || 0) * 360,
111
+ active: !0
112
+ });
113
+ }, []), N = I((t) => {
114
+ const n = R.current;
115
+ if (R.current = null, X(null), g(null), !n) return;
116
+ if (n.dragging) {
117
+ n.preview && k(n.preview);
118
+ return;
119
+ }
120
+ const r = performance.now(), i = _.current;
121
+ if (i && r - i.t < ce && Math.hypot(t.clientX - i.x, t.clientY - i.y) < le)
122
+ D(), _.current = null;
123
+ else {
124
+ const x = de(t.clientX, t.clientY, [...u.current.values()]);
125
+ x && k(x), _.current = { t: r, x: t.clientX, y: t.clientY };
126
+ }
127
+ }, [k, D]), Q = ee(
128
+ () => ({ selectedId: l, previewId: p, enabled: s, setEnabled: M, select: k, activate: D, register: A, setActivate: L }),
129
+ [l, p, s, k, D, A, L]
130
+ ), U = {
131
+ onPointerDown: V,
132
+ onPointerMove: q,
133
+ onPointerUp: N,
134
+ onPointerCancel: N
135
+ }, j = typeof document < "u";
136
+ return /* @__PURE__ */ S(K.Provider, { value: Q, children: [
137
+ /* @__PURE__ */ c(pe, {}),
138
+ w === "container" ? /* @__PURE__ */ S("div", { style: { position: "relative" }, children: [
139
+ e,
140
+ s && /* @__PURE__ */ c(z, { mode: "absolute", active: !!(y != null && y.active), handlers: U })
141
+ ] }) : /* @__PURE__ */ S(F, { children: [
142
+ e,
143
+ s && j && G(/* @__PURE__ */ c(z, { mode: "fixed", active: !!(y != null && y.active), handlers: U }), document.body)
144
+ ] }),
145
+ s && j && G(/* @__PURE__ */ c(ve, { drag: y }), document.body)
146
+ ] });
147
+ }
148
+ function z({
149
+ mode: e,
150
+ active: o,
151
+ handlers: a
152
+ }) {
153
+ return /* @__PURE__ */ c(
154
+ "div",
155
+ {
156
+ "aria-hidden": !0,
157
+ ...a,
158
+ style: {
159
+ position: e,
160
+ inset: 0,
161
+ zIndex: 2147483e3,
162
+ touchAction: "none",
163
+ cursor: o ? "grabbing" : "default",
164
+ background: "transparent",
165
+ userSelect: "none",
166
+ WebkitUserSelect: "none"
167
+ }
168
+ }
169
+ );
170
+ }
171
+ function ve({ drag: e }) {
172
+ return e != null && e.active ? /* @__PURE__ */ c("div", { style: { position: "fixed", inset: 0, zIndex: 2147483001, pointerEvents: "none" }, children: /* @__PURE__ */ S(F, { children: [
173
+ /* @__PURE__ */ S(
174
+ "svg",
175
+ {
176
+ width: "100%",
177
+ height: "100%",
178
+ style: { position: "absolute", inset: 0, pointerEvents: "none", overflow: "visible" },
179
+ children: [
180
+ /* @__PURE__ */ c("defs", { children: /* @__PURE__ */ S("linearGradient", { id: "ds-nav2d-ray", gradientUnits: "userSpaceOnUse", x1: e.originX, y1: e.originY, x2: e.targetX ?? e.originX, y2: e.targetY ?? e.originY, children: [
181
+ /* @__PURE__ */ c("stop", { offset: "0%", stopColor: "var(--ds-nav2d-ray-from, rgba(94,198,232,0.15))" }),
182
+ /* @__PURE__ */ c("stop", { offset: "100%", stopColor: "var(--ds-nav2d-ray-to, rgba(245,166,35,0.9))" })
183
+ ] }) }),
184
+ /* @__PURE__ */ c(
185
+ "line",
186
+ {
187
+ x1: e.originX,
188
+ y1: e.originY,
189
+ x2: e.targetX ?? e.originX,
190
+ y2: e.targetY ?? e.originY,
191
+ stroke: "url(#ds-nav2d-ray)",
192
+ strokeWidth: 3,
193
+ strokeLinecap: "round",
194
+ strokeDasharray: "2 8"
195
+ }
196
+ ),
197
+ /* @__PURE__ */ c("circle", { cx: e.originX, cy: e.originY, r: 5, fill: "var(--ds-nav2d-selected, #5ec6e8)" }),
198
+ e.targetX != null && e.targetY != null && /* @__PURE__ */ c("circle", { cx: e.targetX, cy: e.targetY, r: 7, fill: "none", stroke: "var(--ds-nav2d-preview, #f5a623)", strokeWidth: 2 })
199
+ ]
200
+ }
201
+ ),
202
+ /* @__PURE__ */ c(
203
+ "div",
204
+ {
205
+ style: {
206
+ position: "absolute",
207
+ left: e.baseX,
208
+ top: e.baseY,
209
+ width: E * 2,
210
+ height: E * 2,
211
+ marginLeft: -E,
212
+ marginTop: -E,
213
+ borderRadius: "50%",
214
+ border: "1.5px solid var(--ds-nav2d-joystick, rgba(94,198,232,0.4))",
215
+ background: "radial-gradient(circle, rgba(94,198,232,0.08), transparent 70%)",
216
+ pointerEvents: "none"
217
+ }
218
+ }
219
+ ),
220
+ /* @__PURE__ */ c(
221
+ "div",
222
+ {
223
+ style: {
224
+ position: "absolute",
225
+ left: e.knobX,
226
+ top: e.knobY,
227
+ width: 44,
228
+ height: 44,
229
+ marginLeft: -22,
230
+ marginTop: -22,
231
+ borderRadius: "50%",
232
+ background: "var(--ds-nav2d-knob, rgba(94,198,232,0.9))",
233
+ boxShadow: "0 4px 16px rgba(0,0,0,0.35)",
234
+ pointerEvents: "none"
235
+ }
236
+ }
237
+ )
238
+ ] }) }) : null;
239
+ }
240
+ function fe(e, o) {
241
+ const a = {
242
+ borderRadius: o,
243
+ transition: "box-shadow 140ms ease"
244
+ };
245
+ return e === "selected" ? {
246
+ ...a,
247
+ boxShadow: "0 0 0 2px var(--ds-nav2d-selected, #5ec6e8), 0 0 0 6px var(--ds-nav2d-selected-glow, rgba(94,198,232,0.22))"
248
+ } : e === "preview" ? {
249
+ ...a,
250
+ boxShadow: "0 0 0 2px var(--ds-nav2d-preview, #f5a623)",
251
+ animation: "ds-nav2d-pulse 900ms ease-in-out infinite"
252
+ } : a;
253
+ }
254
+ function xe({ children: e, onActivate: o, id: a, radius: w = 12, className: f, style: d }) {
255
+ const u = Z(), l = a ?? u, h = P(null), p = re();
256
+ $(() => {
257
+ const s = h.current;
258
+ if (s)
259
+ return p.register(l, s, o);
260
+ }, [l]), J(() => {
261
+ p.setActivate(l, o);
262
+ }, [p, l, o]);
263
+ const g = p.selectedId === l ? "selected" : p.previewId === l ? "preview" : "idle";
264
+ return /* @__PURE__ */ c(
265
+ "div",
266
+ {
267
+ ref: h,
268
+ "data-nav2d-item": l,
269
+ "data-nav2d-state": g,
270
+ className: f,
271
+ style: { ...fe(g, w), ...d },
272
+ children: e
273
+ }
274
+ );
275
+ }
276
+ let H = !1;
277
+ function pe() {
278
+ return J(() => {
279
+ if (H || typeof document > "u") return;
280
+ H = !0;
281
+ const e = document.createElement("style");
282
+ e.dataset.dsNav2d = "", e.textContent = "@keyframes ds-nav2d-pulse{0%,100%{box-shadow:0 0 0 2px var(--ds-nav2d-preview,#f5a623)}50%{box-shadow:0 0 0 2px var(--ds-nav2d-preview,#f5a623),0 0 0 7px var(--ds-nav2d-preview-glow,rgba(245,166,35,0.28))}}", document.head.appendChild(e);
283
+ }, []), null;
284
+ }
285
+ export {
286
+ xe as Nav2DItem,
287
+ he as Nav2DProvider,
288
+ re as useNav2D
289
+ };
290
+ //# sourceMappingURL=nav-2d.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nav-2d.js","sources":["../../../src/components/nav-2d/nav-2d.tsx"],"sourcesContent":["import {\n createContext,\n useCallback,\n useContext,\n useEffect,\n useId,\n useLayoutEffect,\n useMemo,\n useRef,\n useState,\n type CSSProperties,\n type PointerEvent as ReactPointerEvent,\n type ReactNode,\n} from 'react';\nimport { createPortal } from 'react-dom';\n\n/**\n * `Nav2D` — a spatial, joystick-driven way to navigate an interface with one\n * thumb, built for touch.\n *\n * Wrap a tree in {@link Nav2DProvider} and mark the reachable targets with\n * {@link Nav2DItem}. The provider drops a full-page invisible **blocker** that\n * captures every touch and turns it into one of three gestures:\n *\n * • **hold + drag** — the press point becomes the base of an invisible\n * joystick; dragging shows its direction. A 2-D ray is cast from the centre\n * of the currently selected item along that direction and the first target\n * it reaches lights up as the *preview*. Releasing commits the preview as\n * the new selection.\n * • **single tap** — selects the item under the finger, if any.\n * • **double tap** — \"clicks\" (activates) the currently selected item.\n *\n * Each {@link Nav2DItem} shows one of three states as a ring around it:\n * *selected* (solid), *preview* (dashed, pulsing) or nothing. The whole thing\n * is dependency-free inline styles + a couple of injected keyframes, themeable\n * through the `--ds-nav2d-*` custom properties.\n */\n\n/* ─── Context ────────────────────────────────────────────────────────────── */\n\ntype ItemState = 'selected' | 'preview' | 'idle';\n\ninterface RegisteredItem {\n id: string;\n el: HTMLElement;\n onActivate?: () => void;\n}\n\nexport interface Nav2DContextValue {\n /** The id of the item currently selected (the ray's origin). */\n selectedId: string | null;\n /** The id currently previewed mid-drag (committed on release), or null. */\n previewId: string | null;\n /** Whether the capture blocker is live. */\n enabled: boolean;\n /** Turn the navigation blocker on/off (e.g. from a toolbar toggle). */\n setEnabled: (v: boolean) => void;\n /** Programmatically select an item (or clear with null). */\n select: (id: string | null) => void;\n /** Fire an item's `onActivate` — defaults to the current selection. */\n activate: (id?: string | null) => void;\n /** @internal registration used by {@link Nav2DItem}. */\n register: (id: string, el: HTMLElement, onActivate?: () => void) => () => void;\n /** @internal keep an item's activate handler fresh across renders. */\n setActivate: (id: string, onActivate?: () => void) => void;\n}\n\nconst Ctx = createContext<Nav2DContextValue | null>(null);\n\n/** Access the ambient {@link Nav2DProvider}. Throws if used outside one. */\nexport function useNav2D(): Nav2DContextValue {\n const v = useContext(Ctx);\n if (!v) throw new Error('useNav2D must be used within <Nav2DProvider>');\n return v;\n}\n\n/* ─── Tunables ───────────────────────────────────────────────────────────── */\n\n/** Finger travel (px) before a press turns into a joystick drag. */\nconst DRAG_THRESHOLD = 12;\n/** Visual joystick radius (px) the knob is clamped inside. */\nconst JOYSTICK_RADIUS = 56;\n/** Half-angle (deg) of the cone a target must fall inside to be a candidate. */\nconst CONE_DEG = 55;\n/** How strongly to punish a target that sits off the ray line. */\nconst PERP_WEIGHT = 1.6;\n/** Max ms / px between two taps for them to count as a double tap. */\nconst DOUBLE_TAP_MS = 320;\nconst DOUBLE_TAP_PX = 34;\n\nconst cos = (deg: number) => Math.cos((deg * Math.PI) / 180);\n\n/**\n * Pick the best target reached by a ray from `origin` in `dir`.\n *\n * Classic D-pad-style spatial scoring rather than a brittle exact ray/rect hit:\n * a target counts if it is in front of the ray and within a cone, and among\n * those we prefer the one that is both near along the ray and close to the ray\n * line. Returns its id, or null if the ray hits nothing.\n */\nfunction pickInDirection(\n origin: { x: number; y: number },\n dir: { x: number; y: number },\n items: RegisteredItem[],\n excludeId: string | null,\n): { id: string; cx: number; cy: number } | null {\n const len = Math.hypot(dir.x, dir.y);\n if (len < 1e-3) return null;\n const dx = dir.x / len;\n const dy = dir.y / len;\n const minCos = cos(CONE_DEG);\n\n let best: { id: string; cx: number; cy: number } | null = null;\n let bestScore = Infinity;\n for (const it of items) {\n if (it.id === excludeId) continue;\n const r = it.el.getBoundingClientRect();\n if (r.width === 0 && r.height === 0) continue;\n const cx = r.left + r.width / 2;\n const cy = r.top + r.height / 2;\n const vx = cx - origin.x;\n const vy = cy - origin.y;\n const dist = Math.hypot(vx, vy);\n if (dist < 1) continue;\n const proj = vx * dx + vy * dy; // distance along the ray\n if (proj <= 0) continue; // behind the origin\n if (proj / dist < minCos) continue; // outside the cone\n const perp = Math.abs(vx * dy - vy * dx); // offset from the ray line\n const score = proj + perp * PERP_WEIGHT;\n if (score < bestScore) {\n bestScore = score;\n best = { id: it.id, cx, cy };\n }\n }\n return best;\n}\n\n/** The item whose box contains the point, if any (topmost wins). */\nfunction itemAtPoint(x: number, y: number, items: RegisteredItem[]): string | null {\n let hit: string | null = null;\n for (const it of items) {\n const r = it.el.getBoundingClientRect();\n if (x >= r.left && x <= r.right && y >= r.top && y <= r.bottom) hit = it.id;\n }\n return hit;\n}\n\nconst center = (el: HTMLElement) => {\n const r = el.getBoundingClientRect();\n return { x: r.left + r.width / 2, y: r.top + r.height / 2 };\n};\n\n/* ─── Provider ───────────────────────────────────────────────────────────── */\n\nexport interface Nav2DProviderProps {\n children: ReactNode;\n /** Start with this item selected (else the first to register wins). */\n defaultSelectedId?: string | null;\n /** Start with the capture blocker off. */\n defaultEnabled?: boolean;\n /**\n * Where the capture blocker lives. `'viewport'` (default) covers the whole\n * page — the intended full-screen navigation mode. `'container'` scopes the\n * blocker to a positioned wrapper around `children`, so navigation only takes\n * over a panel and the rest of the page stays interactive (used by the docs\n * demo, and handy for scoping nav to one region).\n */\n bounds?: 'viewport' | 'container';\n /** Called whenever the selection changes (via joystick, tap or code). */\n onSelect?: (id: string | null) => void;\n /** Called when an item is activated (double tap / `activate()`). */\n onActivate?: (id: string) => void;\n}\n\ninterface DragViz {\n baseX: number;\n baseY: number;\n knobX: number;\n knobY: number;\n originX: number;\n originY: number;\n targetX: number | null;\n targetY: number | null;\n active: boolean;\n}\n\nexport function Nav2DProvider({\n children,\n defaultSelectedId = null,\n defaultEnabled = true,\n bounds = 'viewport',\n onSelect,\n onActivate,\n}: Nav2DProviderProps) {\n const items = useRef(new Map<string, RegisteredItem>());\n const [selectedId, setSelectedId] = useState<string | null>(defaultSelectedId);\n const [previewId, setPreviewId] = useState<string | null>(null);\n const [enabled, setEnabled] = useState(defaultEnabled);\n const [drag, setDrag] = useState<DragViz | null>(null);\n\n // Latest values for use inside pointer handlers without re-binding them.\n const selectedRef = useRef(selectedId);\n selectedRef.current = selectedId;\n const onSelectRef = useRef(onSelect);\n onSelectRef.current = onSelect;\n const onActivateRef = useRef(onActivate);\n onActivateRef.current = onActivate;\n\n const select = useCallback((id: string | null) => {\n setSelectedId((prev) => {\n if (prev !== id) onSelectRef.current?.(id);\n return id;\n });\n }, []);\n\n const activate = useCallback((id?: string | null) => {\n const target = id ?? selectedRef.current;\n if (!target) return;\n const it = items.current.get(target);\n it?.onActivate?.();\n onActivateRef.current?.(target);\n }, []);\n\n const register = useCallback((id: string, el: HTMLElement, onAct?: () => void) => {\n items.current.set(id, { id, el, onActivate: onAct });\n // First target to register becomes the origin unless one was preset.\n setSelectedId((prev) => prev ?? id);\n return () => {\n items.current.delete(id);\n setSelectedId((prev) => (prev === id ? null : prev));\n setPreviewId((prev) => (prev === id ? null : prev));\n };\n }, []);\n\n const setActivate = useCallback((id: string, onAct?: () => void) => {\n const it = items.current.get(id);\n if (it) it.onActivate = onAct;\n }, []);\n\n // Gesture bookkeeping kept in refs — no re-render on every move.\n const gesture = useRef<{\n baseX: number;\n baseY: number;\n origin: { x: number; y: number };\n dragging: boolean;\n preview: string | null;\n } | null>(null);\n const lastTap = useRef<{ t: number; x: number; y: number } | null>(null);\n\n const onPointerDown = useCallback((e: ReactPointerEvent) => {\n e.preventDefault();\n (e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);\n const sel = selectedRef.current ? items.current.get(selectedRef.current) : null;\n const origin = sel ? center(sel.el) : { x: e.clientX, y: e.clientY };\n gesture.current = {\n baseX: e.clientX,\n baseY: e.clientY,\n origin,\n dragging: false,\n preview: null,\n };\n setDrag({\n baseX: e.clientX,\n baseY: e.clientY,\n knobX: e.clientX,\n knobY: e.clientY,\n originX: origin.x,\n originY: origin.y,\n targetX: null,\n targetY: null,\n active: false,\n });\n }, []);\n\n const onPointerMove = useCallback((e: ReactPointerEvent) => {\n const g = gesture.current;\n if (!g) return;\n const dxTotal = e.clientX - g.baseX;\n const dyTotal = e.clientY - g.baseY;\n if (!g.dragging && Math.hypot(dxTotal, dyTotal) < DRAG_THRESHOLD) return;\n g.dragging = true;\n\n // The origin tracks the *live* selected element (it may have scrolled).\n const sel = selectedRef.current ? items.current.get(selectedRef.current) : null;\n const origin = sel ? center(sel.el) : { x: g.baseX, y: g.baseY };\n g.origin = origin;\n\n const hit = pickInDirection(origin, { x: dxTotal, y: dyTotal }, [...items.current.values()], selectedRef.current);\n g.preview = hit?.id ?? null;\n setPreviewId(hit?.id ?? null);\n\n // Clamp the joystick knob to its radius for the visual.\n const dist = Math.hypot(dxTotal, dyTotal);\n const k = dist > JOYSTICK_RADIUS ? JOYSTICK_RADIUS / dist : 1;\n setDrag({\n baseX: g.baseX,\n baseY: g.baseY,\n knobX: g.baseX + dxTotal * k,\n knobY: g.baseY + dyTotal * k,\n originX: origin.x,\n originY: origin.y,\n targetX: hit?.cx ?? origin.x + (dxTotal / dist || 0) * 360,\n targetY: hit?.cy ?? origin.y + (dyTotal / dist || 0) * 360,\n active: true,\n });\n }, []);\n\n const onPointerUp = useCallback((e: ReactPointerEvent) => {\n const g = gesture.current;\n gesture.current = null;\n setDrag(null);\n setPreviewId(null);\n if (!g) return;\n\n if (g.dragging) {\n if (g.preview) select(g.preview); // commit the previewed selection\n return;\n }\n\n // A stationary press: single vs. double tap.\n const t = performance.now();\n const prev = lastTap.current;\n const isDouble =\n prev &&\n t - prev.t < DOUBLE_TAP_MS &&\n Math.hypot(e.clientX - prev.x, e.clientY - prev.y) < DOUBLE_TAP_PX;\n if (isDouble) {\n activate();\n lastTap.current = null;\n } else {\n const hit = itemAtPoint(e.clientX, e.clientY, [...items.current.values()]);\n if (hit) select(hit);\n lastTap.current = { t, x: e.clientX, y: e.clientY };\n }\n }, [select, activate]);\n\n const value = useMemo<Nav2DContextValue>(\n () => ({ selectedId, previewId, enabled, setEnabled, select, activate, register, setActivate }),\n [selectedId, previewId, enabled, select, activate, register, setActivate],\n );\n\n const handlers = {\n onPointerDown,\n onPointerMove,\n onPointerUp,\n onPointerCancel: onPointerUp,\n };\n const canPortal = typeof document !== 'undefined';\n\n return (\n <Ctx.Provider value={value}>\n <StyleOnce />\n {bounds === 'container' ? (\n <div style={{ position: 'relative' }}>\n {children}\n {enabled && <CaptureRegion mode=\"absolute\" active={!!drag?.active} handlers={handlers} />}\n </div>\n ) : (\n <>\n {children}\n {enabled &&\n canPortal &&\n createPortal(<CaptureRegion mode=\"fixed\" active={!!drag?.active} handlers={handlers} />, document.body)}\n </>\n )}\n {enabled && canPortal && createPortal(<VizOverlay drag={drag} />, document.body)}\n </Ctx.Provider>\n );\n}\n\n/* ─── The capture blocker ────────────────────────────────────────────────── */\n\n/**\n * The transparent layer that swallows pointer input and turns it into\n * navigation gestures. `fixed` for the whole viewport, or `absolute` to fill a\n * `container`-bounded provider wrapper.\n */\nfunction CaptureRegion({\n mode,\n active,\n handlers,\n}: {\n mode: 'fixed' | 'absolute';\n active: boolean;\n handlers: {\n onPointerDown: (e: ReactPointerEvent) => void;\n onPointerMove: (e: ReactPointerEvent) => void;\n onPointerUp: (e: ReactPointerEvent) => void;\n onPointerCancel: (e: ReactPointerEvent) => void;\n };\n}) {\n return (\n <div\n aria-hidden\n {...handlers}\n style={{\n position: mode,\n inset: 0,\n zIndex: 2147483000,\n touchAction: 'none',\n cursor: active ? 'grabbing' : 'default',\n background: 'transparent',\n userSelect: 'none',\n WebkitUserSelect: 'none',\n }}\n />\n );\n}\n\n/* ─── Joystick + ray visuals ─────────────────────────────────────────────── */\n\n/** Full-viewport, pointer-transparent overlay drawing the ray and joystick. */\nfunction VizOverlay({ drag }: { drag: DragViz | null }) {\n if (!drag?.active) return null;\n return (\n <div style={{ position: 'fixed', inset: 0, zIndex: 2147483001, pointerEvents: 'none' }}>\n <>\n {/* The 2-D ray, from the selected element toward the preview. */}\n <svg\n width=\"100%\"\n height=\"100%\"\n style={{ position: 'absolute', inset: 0, pointerEvents: 'none', overflow: 'visible' }}\n >\n <defs>\n <linearGradient id=\"ds-nav2d-ray\" gradientUnits=\"userSpaceOnUse\" x1={drag.originX} y1={drag.originY} x2={drag.targetX ?? drag.originX} y2={drag.targetY ?? drag.originY}>\n <stop offset=\"0%\" stopColor=\"var(--ds-nav2d-ray-from, rgba(94,198,232,0.15))\" />\n <stop offset=\"100%\" stopColor=\"var(--ds-nav2d-ray-to, rgba(245,166,35,0.9))\" />\n </linearGradient>\n </defs>\n <line\n x1={drag.originX}\n y1={drag.originY}\n x2={drag.targetX ?? drag.originX}\n y2={drag.targetY ?? drag.originY}\n stroke=\"url(#ds-nav2d-ray)\"\n strokeWidth={3}\n strokeLinecap=\"round\"\n strokeDasharray=\"2 8\"\n />\n <circle cx={drag.originX} cy={drag.originY} r={5} fill=\"var(--ds-nav2d-selected, #5ec6e8)\" />\n {drag.targetX != null && drag.targetY != null && (\n <circle cx={drag.targetX} cy={drag.targetY} r={7} fill=\"none\" stroke=\"var(--ds-nav2d-preview, #f5a623)\" strokeWidth={2} />\n )}\n </svg>\n\n {/* The invisible-until-touched joystick. */}\n <div\n style={{\n position: 'absolute',\n left: drag.baseX,\n top: drag.baseY,\n width: JOYSTICK_RADIUS * 2,\n height: JOYSTICK_RADIUS * 2,\n marginLeft: -JOYSTICK_RADIUS,\n marginTop: -JOYSTICK_RADIUS,\n borderRadius: '50%',\n border: '1.5px solid var(--ds-nav2d-joystick, rgba(94,198,232,0.4))',\n background: 'radial-gradient(circle, rgba(94,198,232,0.08), transparent 70%)',\n pointerEvents: 'none',\n }}\n />\n <div\n style={{\n position: 'absolute',\n left: drag.knobX,\n top: drag.knobY,\n width: 44,\n height: 44,\n marginLeft: -22,\n marginTop: -22,\n borderRadius: '50%',\n background: 'var(--ds-nav2d-knob, rgba(94,198,232,0.9))',\n boxShadow: '0 4px 16px rgba(0,0,0,0.35)',\n pointerEvents: 'none',\n }}\n />\n </>\n </div>\n );\n}\n\n/* ─── Item wrapper ───────────────────────────────────────────────────────── */\n\nexport interface Nav2DItemProps {\n children: ReactNode;\n /** Fired when the item is activated (double tap while selected). */\n onActivate?: () => void;\n /** Stable id — auto-generated if omitted. */\n id?: string;\n /** Ring corner radius (px) — match the wrapped element for a snug ring. */\n radius?: number;\n className?: string;\n style?: CSSProperties;\n}\n\nfunction ringStyle(state: ItemState, radius: number): CSSProperties {\n const base: CSSProperties = {\n borderRadius: radius,\n transition: 'box-shadow 140ms ease',\n };\n if (state === 'selected')\n return {\n ...base,\n boxShadow:\n '0 0 0 2px var(--ds-nav2d-selected, #5ec6e8), 0 0 0 6px var(--ds-nav2d-selected-glow, rgba(94,198,232,0.22))',\n };\n if (state === 'preview')\n return {\n ...base,\n boxShadow: '0 0 0 2px var(--ds-nav2d-preview, #f5a623)',\n animation: 'ds-nav2d-pulse 900ms ease-in-out infinite',\n };\n return base;\n}\n\n/**\n * Marks a subtree as a reachable navigation target. Shows a ring reflecting its\n * state (selected / preview / idle) without shifting layout, and registers with\n * the nearest {@link Nav2DProvider}.\n */\nexport function Nav2DItem({ children, onActivate, id: idProp, radius = 12, className, style }: Nav2DItemProps) {\n const autoId = useId();\n const id = idProp ?? autoId;\n const ref = useRef<HTMLDivElement>(null);\n const ctx = useNav2D();\n\n useLayoutEffect(() => {\n const el = ref.current;\n if (!el) return;\n return ctx.register(id, el, onActivate);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [id]);\n\n useEffect(() => {\n ctx.setActivate(id, onActivate);\n }, [ctx, id, onActivate]);\n\n const state: ItemState =\n ctx.selectedId === id ? 'selected' : ctx.previewId === id ? 'preview' : 'idle';\n\n return (\n <div\n ref={ref}\n data-nav2d-item={id}\n data-nav2d-state={state}\n className={className}\n style={{ ...ringStyle(state, radius), ...style }}\n >\n {children}\n </div>\n );\n}\n\n/* ─── One-shot keyframes injection ───────────────────────────────────────── */\n\nlet injected = false;\nfunction StyleOnce() {\n useEffect(() => {\n if (injected || typeof document === 'undefined') return;\n injected = true;\n const el = document.createElement('style');\n el.dataset.dsNav2d = '';\n el.textContent =\n '@keyframes ds-nav2d-pulse{0%,100%{box-shadow:0 0 0 2px var(--ds-nav2d-preview,#f5a623)}50%{box-shadow:0 0 0 2px var(--ds-nav2d-preview,#f5a623),0 0 0 7px var(--ds-nav2d-preview-glow,rgba(245,166,35,0.28))}}';\n document.head.appendChild(el);\n }, []);\n return null;\n}\n"],"names":["Ctx","createContext","useNav2D","v","useContext","DRAG_THRESHOLD","JOYSTICK_RADIUS","CONE_DEG","PERP_WEIGHT","DOUBLE_TAP_MS","DOUBLE_TAP_PX","cos","deg","pickInDirection","origin","dir","items","excludeId","len","dx","dy","minCos","best","bestScore","it","r","cx","cy","vx","vy","dist","proj","perp","score","itemAtPoint","x","y","hit","center","el","Nav2DProvider","children","defaultSelectedId","defaultEnabled","bounds","onSelect","onActivate","useRef","selectedId","setSelectedId","useState","previewId","setPreviewId","enabled","setEnabled","drag","setDrag","selectedRef","onSelectRef","onActivateRef","select","useCallback","id","prev","_a","activate","target","_b","register","onAct","setActivate","gesture","lastTap","onPointerDown","e","sel","onPointerMove","g","dxTotal","dyTotal","k","onPointerUp","t","value","useMemo","handlers","canPortal","jsxs","jsx","StyleOnce","CaptureRegion","Fragment","createPortal","VizOverlay","mode","active","ringStyle","state","radius","base","Nav2DItem","idProp","className","style","autoId","useId","ref","ctx","useLayoutEffect","useEffect","injected"],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { PhonePreview, IOSStatusBar } from './phone-preview';
2
+ export type { PhonePreviewProps } from './phone-preview';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/phone-preview/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAC7D,YAAY,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,45 @@
1
+ import { CSSProperties, ReactNode } from 'react';
2
+ /**
3
+ * Faux iOS status bar for the top of a {@link PhonePreview} screen: time on the
4
+ * left, signal / Wi-Fi / battery on the right, the centre left clear for the
5
+ * dynamic island. Decorative only. Reads `--foreground` / `--background` so it
6
+ * inherits the screen's theme, with light-mode fallbacks.
7
+ */
8
+ export declare function IOSStatusBar({ time, className }: {
9
+ time?: string;
10
+ className?: string;
11
+ }): import("react").JSX.Element;
12
+ export interface PhonePreviewProps {
13
+ /** Screen content. Ignored when `src` is set. */
14
+ children?: ReactNode;
15
+ /**
16
+ * Render a live app inside the screen. The iframe is laid out at
17
+ * `deviceWidth` (a real phone's logical width) then scaled down to the frame,
18
+ * so the embedded app lays out exactly as it does on a device instead of
19
+ * reflowing to the narrow mockup width.
20
+ */
21
+ src?: string;
22
+ title?: string;
23
+ /** Rendered width of the screen, in px (the frame sizes off this). */
24
+ screenWidth?: number;
25
+ /** Logical device width the `src` iframe is laid out at before scaling. */
26
+ deviceWidth?: number;
27
+ /** Logical device height, for the screen aspect ratio. */
28
+ deviceHeight?: number;
29
+ /** Frame / bezel colour. */
30
+ frameColor?: string;
31
+ /** Show a dynamic-island pill at the top of the screen. */
32
+ island?: boolean;
33
+ /** Prepend an {@link IOSStatusBar} (only meaningful with `children`). */
34
+ statusBar?: boolean;
35
+ className?: string;
36
+ style?: CSSProperties;
37
+ }
38
+ /**
39
+ * A dependency-free iPhone mockup. Drop any React tree in as `children` to frame
40
+ * a screen, or pass `src` to embed a live app as a scaled iframe (the technique
41
+ * the note-vite and insta-pics landing pages use). Pure inline styles — no
42
+ * Tailwind required.
43
+ */
44
+ export declare function PhonePreview({ children, src, title, screenWidth, deviceWidth, deviceHeight, frameColor, island, statusBar, className, style, }: PhonePreviewProps): import("react").JSX.Element;
45
+ //# sourceMappingURL=phone-preview.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phone-preview.d.ts","sourceRoot":"","sources":["../../../src/components/phone-preview/phone-preview.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAGtD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAAE,IAAa,EAAE,SAAS,EAAE,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,+BA2B/F;AAED,MAAM,WAAW,iBAAiB;IAChC,iDAAiD;IACjD,QAAQ,CAAC,EAAE,SAAS,CAAC;IACrB;;;;;OAKG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,2EAA2E;IAC3E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,0DAA0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4BAA4B;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,yEAAyE;IACzE,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,aAAa,CAAC;CACvB;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAC3B,QAAQ,EACR,GAAG,EACH,KAAuB,EACvB,WAAiB,EACjB,WAAiB,EACjB,YAAkB,EAClB,UAAsB,EACtB,MAAa,EACb,SAAiB,EACjB,SAAS,EACT,KAAK,GACN,EAAE,iBAAiB,+BAyEnB"}
@@ -0,0 +1,117 @@
1
+ import { jsxs as r, jsx as t } from "react/jsx-runtime";
2
+ import { Signal as m, Wifi as w, BatteryFull as k } from "lucide-react";
3
+ function M({ time: a = "9:41", className: n }) {
4
+ return /* @__PURE__ */ r(
5
+ "div",
6
+ {
7
+ "aria-hidden": !0,
8
+ className: n,
9
+ style: {
10
+ position: "sticky",
11
+ top: 0,
12
+ zIndex: 30,
13
+ display: "flex",
14
+ height: 34,
15
+ alignItems: "center",
16
+ justifyContent: "space-between",
17
+ padding: "0 22px",
18
+ userSelect: "none",
19
+ color: "var(--foreground, #0c0a09)",
20
+ background: "var(--background, #fff)"
21
+ },
22
+ children: [
23
+ /* @__PURE__ */ t("span", { style: { fontSize: 13, fontWeight: 600, fontVariantNumeric: "tabular-nums" }, children: a }),
24
+ /* @__PURE__ */ r("div", { style: { display: "flex", alignItems: "center", gap: 5 }, children: [
25
+ /* @__PURE__ */ t(m, { size: 15 }),
26
+ /* @__PURE__ */ t(w, { size: 15 }),
27
+ /* @__PURE__ */ t(k, { size: 22 })
28
+ ] })
29
+ ]
30
+ }
31
+ );
32
+ }
33
+ function I({
34
+ children: a,
35
+ src: n,
36
+ title: l = "Phone preview",
37
+ screenWidth: e = 300,
38
+ deviceWidth: i = 390,
39
+ deviceHeight: u = 844,
40
+ frameColor: f = "#1f2933",
41
+ island: h = !0,
42
+ statusBar: c = !1,
43
+ className: g,
44
+ style: p
45
+ }) {
46
+ const b = Math.round(e * u / i), o = e / 300, d = Math.round(12 * o), y = Math.round(54 * o), v = Math.round(e * 0.14), s = e / i, x = h && /* @__PURE__ */ t(
47
+ "div",
48
+ {
49
+ "aria-hidden": !0,
50
+ style: {
51
+ position: "absolute",
52
+ top: Math.round(9 * o),
53
+ left: "50%",
54
+ transform: "translateX(-50%)",
55
+ width: Math.round(e * 0.34),
56
+ height: Math.round(28 * o),
57
+ borderRadius: 999,
58
+ background: "#05070a",
59
+ zIndex: 40
60
+ }
61
+ }
62
+ );
63
+ return /* @__PURE__ */ t("div", { className: g, style: { width: e + d * 2, ...p }, children: /* @__PURE__ */ t(
64
+ "div",
65
+ {
66
+ style: {
67
+ padding: d,
68
+ background: f,
69
+ borderRadius: y,
70
+ boxShadow: `0 0 0 ${Math.max(1, Math.round(o))}px rgba(255,255,255,0.06), 0 24px 60px -20px rgba(0,0,0,0.7)`
71
+ },
72
+ children: /* @__PURE__ */ r(
73
+ "div",
74
+ {
75
+ style: {
76
+ position: "relative",
77
+ width: e,
78
+ height: b,
79
+ overflow: "hidden",
80
+ borderRadius: v,
81
+ background: "var(--background, #fff)"
82
+ },
83
+ children: [
84
+ x,
85
+ n ? /* @__PURE__ */ t(
86
+ "iframe",
87
+ {
88
+ src: n,
89
+ title: l,
90
+ loading: "lazy",
91
+ style: {
92
+ position: "absolute",
93
+ left: 0,
94
+ top: 0,
95
+ border: 0,
96
+ width: i,
97
+ height: `${100 / s}%`,
98
+ transform: `scale(${s})`,
99
+ transformOrigin: "top left",
100
+ background: "var(--background, #fff)"
101
+ }
102
+ }
103
+ ) : /* @__PURE__ */ r("div", { style: { position: "absolute", inset: 0, overflow: "auto" }, children: [
104
+ c && /* @__PURE__ */ t(M, {}),
105
+ a
106
+ ] })
107
+ ]
108
+ }
109
+ )
110
+ }
111
+ ) });
112
+ }
113
+ export {
114
+ M as IOSStatusBar,
115
+ I as PhonePreview
116
+ };
117
+ //# sourceMappingURL=phone-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"phone-preview.js","sources":["../../../src/components/phone-preview/phone-preview.tsx"],"sourcesContent":["import type { CSSProperties, ReactNode } from 'react';\nimport { BatteryFull, Signal, Wifi } from 'lucide-react';\n\n/**\n * Faux iOS status bar for the top of a {@link PhonePreview} screen: time on the\n * left, signal / Wi-Fi / battery on the right, the centre left clear for the\n * dynamic island. Decorative only. Reads `--foreground` / `--background` so it\n * inherits the screen's theme, with light-mode fallbacks.\n */\nexport function IOSStatusBar({ time = '9:41', className }: { time?: string; className?: string }) {\n return (\n <div\n aria-hidden\n className={className}\n style={{\n position: 'sticky',\n top: 0,\n zIndex: 30,\n display: 'flex',\n height: 34,\n alignItems: 'center',\n justifyContent: 'space-between',\n padding: '0 22px',\n userSelect: 'none',\n color: 'var(--foreground, #0c0a09)',\n background: 'var(--background, #fff)',\n }}\n >\n <span style={{ fontSize: 13, fontWeight: 600, fontVariantNumeric: 'tabular-nums' }}>{time}</span>\n <div style={{ display: 'flex', alignItems: 'center', gap: 5 }}>\n <Signal size={15} />\n <Wifi size={15} />\n <BatteryFull size={22} />\n </div>\n </div>\n );\n}\n\nexport interface PhonePreviewProps {\n /** Screen content. Ignored when `src` is set. */\n children?: ReactNode;\n /**\n * Render a live app inside the screen. The iframe is laid out at\n * `deviceWidth` (a real phone's logical width) then scaled down to the frame,\n * so the embedded app lays out exactly as it does on a device instead of\n * reflowing to the narrow mockup width.\n */\n src?: string;\n title?: string;\n /** Rendered width of the screen, in px (the frame sizes off this). */\n screenWidth?: number;\n /** Logical device width the `src` iframe is laid out at before scaling. */\n deviceWidth?: number;\n /** Logical device height, for the screen aspect ratio. */\n deviceHeight?: number;\n /** Frame / bezel colour. */\n frameColor?: string;\n /** Show a dynamic-island pill at the top of the screen. */\n island?: boolean;\n /** Prepend an {@link IOSStatusBar} (only meaningful with `children`). */\n statusBar?: boolean;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * A dependency-free iPhone mockup. Drop any React tree in as `children` to frame\n * a screen, or pass `src` to embed a live app as a scaled iframe (the technique\n * the note-vite and insta-pics landing pages use). Pure inline styles — no\n * Tailwind required.\n */\nexport function PhonePreview({\n children,\n src,\n title = 'Phone preview',\n screenWidth = 300,\n deviceWidth = 390,\n deviceHeight = 844,\n frameColor = '#1f2933',\n island = true,\n statusBar = false,\n className,\n style,\n}: PhonePreviewProps) {\n const screenHeight = Math.round((screenWidth * deviceHeight) / deviceWidth);\n const unit = screenWidth / 300; // scale every fixed dimension off a 300px baseline\n const bezel = Math.round(12 * unit);\n const outerRadius = Math.round(54 * unit);\n const screenRadius = Math.round(screenWidth * 0.14);\n const scale = screenWidth / deviceWidth;\n\n const islandEl = island && (\n <div\n aria-hidden\n style={{\n position: 'absolute',\n top: Math.round(9 * unit),\n left: '50%',\n transform: 'translateX(-50%)',\n width: Math.round(screenWidth * 0.34),\n height: Math.round(28 * unit),\n borderRadius: 999,\n background: '#05070a',\n zIndex: 40,\n }}\n />\n );\n\n return (\n <div className={className} style={{ width: screenWidth + bezel * 2, ...style }}>\n <div\n style={{\n padding: bezel,\n background: frameColor,\n borderRadius: outerRadius,\n boxShadow: `0 0 0 ${Math.max(1, Math.round(unit))}px rgba(255,255,255,0.06), 0 24px 60px -20px rgba(0,0,0,0.7)`,\n }}\n >\n <div\n style={{\n position: 'relative',\n width: screenWidth,\n height: screenHeight,\n overflow: 'hidden',\n borderRadius: screenRadius,\n background: 'var(--background, #fff)',\n }}\n >\n {islandEl}\n {src ? (\n <iframe\n src={src}\n title={title}\n loading=\"lazy\"\n style={{\n position: 'absolute',\n left: 0,\n top: 0,\n border: 0,\n width: deviceWidth,\n height: `${100 / scale}%`,\n transform: `scale(${scale})`,\n transformOrigin: 'top left',\n background: 'var(--background, #fff)',\n }}\n />\n ) : (\n <div style={{ position: 'absolute', inset: 0, overflow: 'auto' }}>\n {statusBar && <IOSStatusBar />}\n {children}\n </div>\n )}\n </div>\n </div>\n </div>\n );\n}\n"],"names":["IOSStatusBar","time","className","jsxs","jsx","Signal","Wifi","BatteryFull","PhonePreview","children","src","title","screenWidth","deviceWidth","deviceHeight","frameColor","island","statusBar","style","screenHeight","unit","bezel","outerRadius","screenRadius","scale","islandEl"],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ export { ProgressiveBash } from './progressive-bash';
2
+ export type { ProgressiveBashProps, ProgressiveBashHandle } from './progressive-bash';
3
+ export type { BashEntry, PlaybackTuning } from './playback';
4
+ export { computeGapMs, DEFAULT_TUNING } from './playback';
5
+ export { tokenizeCommand, splitOutput, classifyLine, parseEchoMarkers, parseMarkerText, splitBySubparts } from './parse';
6
+ export type { CmdToken, CmdKind, OutputLine, OutputSpan, LineKind, SubMarker, SubCommand } from './parse';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/progressive-bash/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,YAAY,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,oBAAoB,CAAC;AACtF,YAAY,EAAE,SAAS,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AACzH,YAAY,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC"}