@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,72 @@
1
+ import { jsxs as C, jsx as A } from "react/jsx-runtime";
2
+ import * as m from "react";
3
+ import { cn as T } from "../../lib/utils.js";
4
+ const S = 'script, iframe, object, embed, link[rel="import"]';
5
+ function k(e, r) {
6
+ const o = [e, ...Array.from(e.querySelectorAll("input, textarea, select"))], u = [r, ...Array.from(r.querySelectorAll("input, textarea, select"))];
7
+ o.forEach((s, d) => {
8
+ const t = u[d];
9
+ t && (s instanceof HTMLInputElement && t instanceof HTMLInputElement ? (t.setAttribute("value", s.value), s.checked ? t.setAttribute("checked", "") : t.removeAttribute("checked")) : s instanceof HTMLTextAreaElement && t instanceof HTMLTextAreaElement ? t.textContent = s.value : s instanceof HTMLSelectElement && t instanceof HTMLSelectElement && Array.from(t.options).forEach((f, h) => {
10
+ var c;
11
+ (c = s.options[h]) != null && c.selected ? f.setAttribute("selected", "") : f.removeAttribute("selected");
12
+ }));
13
+ });
14
+ }
15
+ function R(e) {
16
+ for (let r = e; r; r = r.parentElement) {
17
+ const o = getComputedStyle(r).backgroundColor;
18
+ if (o && o !== "transparent" && !/rgba\(0, 0, 0, 0\)/.test(o)) return o;
19
+ }
20
+ }
21
+ function L({
22
+ element: e,
23
+ height: r = 120,
24
+ shrinkOnly: o = !0,
25
+ minScale: u = 0,
26
+ className: s
27
+ }) {
28
+ const d = m.useRef(null), t = m.useRef(null), [f, h] = m.useState(!0);
29
+ return m.useEffect(() => {
30
+ const c = d.current, a = t.current;
31
+ if (!c || !a) return;
32
+ if (a.replaceChildren(), !(e != null && e.isConnected)) {
33
+ h(!0);
34
+ return;
35
+ }
36
+ h(!1);
37
+ const n = e.getBoundingClientRect(), i = e.cloneNode(!0);
38
+ i.querySelectorAll(S).forEach((l) => l.remove()), k(e, i), i.style.width = `${n.width}px`, i.style.height = `${n.height}px`, i.style.margin = "0", i.style.flex = "0 0 auto", i.inert = !0, a.style.width = `${n.width}px`, a.style.height = `${n.height}px`, a.appendChild(i);
39
+ const g = R(e);
40
+ g && (c.style.backgroundColor = g);
41
+ const x = () => {
42
+ const l = c.getBoundingClientRect();
43
+ if (!n.width || !n.height) return;
44
+ const y = Math.min(l.width / n.width, l.height / n.height), v = o ? Math.min(y, 1) : y, p = Math.max(v, u), w = p > v, E = w ? 0 : Math.max((l.width - n.width * p) / 2, 0), M = w ? 0 : Math.max((l.height - n.height * p) / 2, 0);
45
+ a.style.transform = `translate(${E}px, ${M}px) scale(${p})`;
46
+ };
47
+ x();
48
+ const b = new ResizeObserver(x);
49
+ return b.observe(c), () => {
50
+ b.disconnect(), a.replaceChildren();
51
+ };
52
+ }, [e, o, u, r]), /* @__PURE__ */ C(
53
+ "div",
54
+ {
55
+ ref: d,
56
+ style: { height: r },
57
+ "aria-hidden": !0,
58
+ className: T(
59
+ "pointer-events-none relative overflow-hidden rounded-lg border border-border bg-muted/30",
60
+ s
61
+ ),
62
+ children: [
63
+ /* @__PURE__ */ A("div", { ref: t, className: "absolute top-0 left-0 origin-top-left" }),
64
+ f && /* @__PURE__ */ A("span", { className: "absolute inset-0 flex items-center justify-center text-xs text-muted-foreground", children: "No preview" })
65
+ ]
66
+ }
67
+ );
68
+ }
69
+ export {
70
+ L as ElementPreview
71
+ };
72
+ //# sourceMappingURL=element-preview.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"element-preview.js","sources":["../../../src/components/element-picker/element-preview.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { cn } from '../../lib/utils';\n\n/** Nothing that could run, load or navigate survives the clone. */\nconst STRIP = 'script, iframe, object, embed, link[rel=\"import\"]';\n\n/**\n * `cloneNode` copies the *attributes*, not the live state — a typed-in input\n * comes back empty, a checked box unchecked. Walk the pairs and put it back.\n */\nfunction copyFieldState(from: HTMLElement, to: HTMLElement) {\n const originals = [from, ...Array.from(from.querySelectorAll<HTMLElement>('input, textarea, select'))];\n const clones = [to, ...Array.from(to.querySelectorAll<HTMLElement>('input, textarea, select'))];\n\n originals.forEach((el, i) => {\n const clone = clones[i];\n if (!clone) return;\n\n if (el instanceof HTMLInputElement && clone instanceof HTMLInputElement) {\n clone.setAttribute('value', el.value);\n if (el.checked) clone.setAttribute('checked', '');\n else clone.removeAttribute('checked');\n } else if (el instanceof HTMLTextAreaElement && clone instanceof HTMLTextAreaElement) {\n clone.textContent = el.value;\n } else if (el instanceof HTMLSelectElement && clone instanceof HTMLSelectElement) {\n Array.from(clone.options).forEach((o, oi) => {\n if (el.options[oi]?.selected) o.setAttribute('selected', '');\n else o.removeAttribute('selected');\n });\n }\n });\n}\n\n/** The colour actually painted behind the element, so light text stays legible. */\nfunction backdropOf(el: HTMLElement): string | undefined {\n for (let node: HTMLElement | null = el; node; node = node.parentElement) {\n const bg = getComputedStyle(node).backgroundColor;\n if (bg && bg !== 'transparent' && !/rgba\\(0, 0, 0, 0\\)/.test(bg)) return bg;\n }\n return undefined;\n}\n\nexport interface ElementPreviewProps {\n /** The element to mirror. A detached or null node renders the fallback. */\n element: HTMLElement | null;\n /** Height of the preview box, in px. Default 120. */\n height?: number;\n /** Never enlarge past 1:1, only shrink to fit. Default true. */\n shrinkOnly?: boolean;\n /**\n * Floor on the scale. Below it the preview crops from the top-left instead of\n * shrinking further — a 900px-wide heading fitted into a thumbnail is two\n * pixels of grey, where its first few words are recognisable. Default 0.\n */\n minScale?: number;\n className?: string;\n}\n\n/**\n * A live, inert clone of an element, scaled to fit its box. Because the copy\n * sits in the same document it inherits the same stylesheets, so it looks\n * exactly like the thing it came from — the page's CSS does the work.\n */\nexport function ElementPreview({\n element,\n height = 120,\n shrinkOnly = true,\n minScale = 0,\n className,\n}: ElementPreviewProps) {\n const host = React.useRef<HTMLDivElement>(null);\n const stage = React.useRef<HTMLDivElement>(null);\n const [empty, setEmpty] = React.useState(true);\n\n React.useEffect(() => {\n const frame = host.current;\n const surface = stage.current;\n if (!frame || !surface) return;\n\n surface.replaceChildren();\n if (!element?.isConnected) {\n setEmpty(true);\n return;\n }\n setEmpty(false);\n\n const rect = element.getBoundingClientRect();\n const clone = element.cloneNode(true) as HTMLElement;\n clone.querySelectorAll(STRIP).forEach((n) => n.remove());\n copyFieldState(element, clone);\n\n // Freeze it at the size it really is — a clone out of its flex/grid parent\n // would otherwise collapse or stretch to the preview box instead.\n clone.style.width = `${rect.width}px`;\n clone.style.height = `${rect.height}px`;\n clone.style.margin = '0';\n clone.style.flex = '0 0 auto';\n clone.inert = true;\n\n surface.style.width = `${rect.width}px`;\n surface.style.height = `${rect.height}px`;\n surface.appendChild(clone);\n\n const backdrop = backdropOf(element);\n if (backdrop) frame.style.backgroundColor = backdrop;\n\n const fit = () => {\n const box = frame.getBoundingClientRect();\n if (!rect.width || !rect.height) return;\n\n const raw = Math.min(box.width / rect.width, box.height / rect.height);\n const fitted = shrinkOnly ? Math.min(raw, 1) : raw;\n const scale = Math.max(fitted, minScale);\n\n // Centre what fits; anchor what doesn't, so a crop starts at the corner\n // you'd actually read from.\n const cropped = scale > fitted;\n const tx = cropped ? 0 : Math.max((box.width - rect.width * scale) / 2, 0);\n const ty = cropped ? 0 : Math.max((box.height - rect.height * scale) / 2, 0);\n surface.style.transform = `translate(${tx}px, ${ty}px) scale(${scale})`;\n };\n\n fit();\n const ro = new ResizeObserver(fit);\n ro.observe(frame);\n return () => {\n ro.disconnect();\n surface.replaceChildren();\n };\n }, [element, shrinkOnly, minScale, height]);\n\n return (\n <div\n ref={host}\n style={{ height }}\n aria-hidden\n className={cn(\n 'pointer-events-none relative overflow-hidden rounded-lg border border-border bg-muted/30',\n className,\n )}\n >\n <div ref={stage} className=\"absolute top-0 left-0 origin-top-left\" />\n {empty && (\n <span className=\"absolute inset-0 flex items-center justify-center text-xs text-muted-foreground\">\n No preview\n </span>\n )}\n </div>\n );\n}\n"],"names":["STRIP","copyFieldState","from","to","originals","clones","el","i","clone","o","oi","_a","backdropOf","node","bg","ElementPreview","element","height","shrinkOnly","minScale","className","host","React","stage","empty","setEmpty","frame","surface","rect","n","backdrop","fit","box","raw","fitted","scale","cropped","tx","ty","ro","jsxs","cn","jsx"],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export { ElementPicker, ElementPickerOverlay } from './element-picker';
2
+ export type { ElementPickerProps, ElementPickerOverlayProps } from './element-picker';
3
+ export { ElementPickerField } from './element-picker-field';
4
+ export type { ElementPickerFieldProps } from './element-picker-field';
5
+ export { ElementPreview } from './element-preview';
6
+ export type { ElementPreviewProps } from './element-preview';
7
+ export { useElementPicker } from './use-element-picker';
8
+ export type { UseElementPickerOptions, UseElementPickerResult } from './use-element-picker';
9
+ export { classify, formatHtml, hierarchy, parseElement, uniqueSelector, STYLE_GROUPS, STYLE_PROPS } from './parse';
10
+ export type { ParseOptions } from './parse';
11
+ export type { ElementField, ElementInfo, ElementKind, ElementPathStep, PickedElement } from './types';
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/element-picker/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACvE,YAAY,EAAE,kBAAkB,EAAE,yBAAyB,EAAE,MAAM,kBAAkB,CAAC;AACtF,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAC5D,YAAY,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,YAAY,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,YAAY,EAAE,uBAAuB,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC5F,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACnH,YAAY,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5C,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC"}
@@ -0,0 +1,32 @@
1
+ import { ElementInfo, ElementKind, ElementPathStep } from './types';
2
+ /**
3
+ * The computed properties we read off a picked element, grouped the way the
4
+ * inspector shows them. Anything the browser reports as its initial value is
5
+ * dropped later, so a plain `<div>` doesn't come back with forty entries.
6
+ */
7
+ export declare const STYLE_GROUPS: Record<string, string[]>;
8
+ export declare const STYLE_PROPS: string[];
9
+ /**
10
+ * The shortest selector that still lands on exactly this element. Tries an
11
+ * `#id` first, then a class-qualified path, and falls back to `:nth-of-type`
12
+ * when a step is still ambiguous — the same ladder devtools climbs.
13
+ */
14
+ export declare function uniqueSelector(el: HTMLElement, root?: HTMLElement): string;
15
+ /** The ancestor chain from the picker root down to the element itself. */
16
+ export declare function hierarchy(el: HTMLElement, root: HTMLElement): ElementPathStep[];
17
+ /** What the element *is*, as a human would name it. */
18
+ export declare function classify(el: HTMLElement): ElementKind;
19
+ export interface ParseOptions {
20
+ /** The subtree the selector and hierarchy are expressed relative to. */
21
+ root?: HTMLElement;
22
+ /** Override which computed properties are captured. */
23
+ styleProps?: string[];
24
+ }
25
+ /** Read an element down to plain, serializable data. */
26
+ export declare function parseElement(el: HTMLElement, options?: ParseOptions): ElementInfo;
27
+ /**
28
+ * Re-indent a serialized HTML string. `outerHTML` comes back as one line for
29
+ * anything the browser normalized, which is unreadable past a few nodes.
30
+ */
31
+ export declare function formatHtml(html: string, indent?: string): string;
32
+ //# sourceMappingURL=parse.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../src/components/element-picker/parse.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAgB,WAAW,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAEvF;;;;GAIG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAiDjD,CAAC;AAEF,eAAO,MAAM,WAAW,EAAE,MAAM,EAAuC,CAAC;AAmCxE;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,GAAE,WAA2B,GAAG,MAAM,CAyCzF;AAED,0EAA0E;AAC1E,wBAAgB,SAAS,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,WAAW,GAAG,eAAe,EAAE,CAY/E;AAiBD,uDAAuD;AACvD,wBAAgB,QAAQ,CAAC,EAAE,EAAE,WAAW,GAAG,WAAW,CAmBrD;AAwED,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;CACvB;AAED,wDAAwD;AACxD,wBAAgB,YAAY,CAAC,EAAE,EAAE,WAAW,EAAE,OAAO,GAAE,YAAiB,GAAG,WAAW,CAgCrF;AAID;;;GAGG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,SAAO,GAAG,MAAM,CAsB9D"}
@@ -0,0 +1,230 @@
1
+ const h = {
2
+ Layout: [
3
+ "display",
4
+ "position",
5
+ "top",
6
+ "right",
7
+ "bottom",
8
+ "left",
9
+ "zIndex",
10
+ "flexDirection",
11
+ "flexWrap",
12
+ "alignItems",
13
+ "justifyContent",
14
+ "gap",
15
+ "gridTemplateColumns",
16
+ "gridTemplateRows",
17
+ "overflow"
18
+ ],
19
+ Box: [
20
+ "width",
21
+ "height",
22
+ "boxSizing",
23
+ "padding",
24
+ "margin",
25
+ "border",
26
+ "borderRadius"
27
+ ],
28
+ Typography: [
29
+ "fontFamily",
30
+ "fontSize",
31
+ "fontWeight",
32
+ "fontStyle",
33
+ "lineHeight",
34
+ "letterSpacing",
35
+ "textAlign",
36
+ "textTransform",
37
+ "textDecorationLine",
38
+ "whiteSpace"
39
+ ],
40
+ Visual: [
41
+ "color",
42
+ "backgroundColor",
43
+ "backgroundImage",
44
+ "opacity",
45
+ "boxShadow",
46
+ "transform",
47
+ "transition",
48
+ "cursor"
49
+ ]
50
+ }, g = Object.values(h).flat(), b = /* @__PURE__ */ new Set([
51
+ "",
52
+ "none",
53
+ "auto",
54
+ "normal",
55
+ "static",
56
+ "0px",
57
+ "visible",
58
+ "rgba(0, 0, 0, 0)",
59
+ "start",
60
+ "nowrap",
61
+ "row",
62
+ "stretch",
63
+ "flex-start",
64
+ "content-box",
65
+ "transparent"
66
+ ]), c = (t) => t.replace(/\s+/g, " ").trim(), y = (t) => Array.from(t.classList).filter((n) => /^[a-zA-Z_][\w-]*$/.test(n));
67
+ function m(t) {
68
+ let n = 1;
69
+ for (let e = t.previousElementSibling; e; e = e.previousElementSibling)
70
+ e.tagName === t.tagName && n++;
71
+ return n;
72
+ }
73
+ function v(t, n = document.body) {
74
+ const e = t.ownerDocument, r = (i) => {
75
+ try {
76
+ return e.querySelectorAll(i).length;
77
+ } catch {
78
+ return 0;
79
+ }
80
+ };
81
+ if (t.id && /^[a-zA-Z_][\w-]*$/.test(t.id) && r(`#${t.id}`) === 1) return `#${t.id}`;
82
+ const o = [];
83
+ for (let i = t; i && i !== n.parentElement; i = i.parentElement) {
84
+ const s = i.tagName.toLowerCase();
85
+ if (i.id && /^[a-zA-Z_][\w-]*$/.test(i.id) && r(`#${i.id}`) === 1) {
86
+ o.unshift(`#${i.id}`);
87
+ break;
88
+ }
89
+ const a = i.parentElement, l = (u) => !!a && Array.from(a.children).filter((p) => p.matches(u)).length > 1;
90
+ let d = s;
91
+ if (l(d)) {
92
+ const u = y(i).slice(0, 2), p = u.length ? `${s}.${u.join(".")}` : s;
93
+ d = l(p) ? `${p}:nth-of-type(${m(i)})` : p;
94
+ }
95
+ o.unshift(d);
96
+ const f = o.join(" > ");
97
+ if (r(f) === 1) return f;
98
+ }
99
+ return o.join(" > ");
100
+ }
101
+ function x(t, n) {
102
+ const e = [];
103
+ for (let r = t; r && r !== n.parentElement && (e.unshift({
104
+ tag: r.tagName.toLowerCase(),
105
+ id: r.id || void 0,
106
+ classes: Array.from(r.classList),
107
+ nth: m(r)
108
+ }), r !== n); r = r.parentElement)
109
+ ;
110
+ return e;
111
+ }
112
+ const w = (t) => t.map((n) => {
113
+ let e = n.tag;
114
+ return n.id ? e += `#${n.id}` : n.classes.length && (e += `.${n.classes[0]}`), n.nth > 1 && (e += `:nth-of-type(${n.nth})`), e;
115
+ }).join(" > "), S = /* @__PURE__ */ new Set(["nav", "header", "footer", "main", "aside", "section", "article", "dialog"]), A = /* @__PURE__ */ new Set(["p", "span", "strong", "em", "b", "i", "small", "label", "li", "dt", "dd", "blockquote", "code", "pre", "time", "figcaption"]), C = /* @__PURE__ */ new Set(["img", "svg", "video", "audio", "canvas", "picture", "iframe"]);
116
+ function L(t) {
117
+ const n = t.tagName.toLowerCase(), e = t.getAttribute("role");
118
+ return n === "input" && /^(button|submit|reset|image)$/.test(t.type) ? "button" : n === "input" || n === "textarea" || n === "select" ? "input" : n === "button" || e === "button" ? "button" : n === "a" ? t.href ? "link" : "text" : C.has(n) ? "media" : /^h[1-6]$/.test(n) ? "heading" : n === "form" ? "form" : n === "table" ? "table" : n === "ul" || n === "ol" || n === "dl" || e === "list" ? "list" : S.has(n) ? "landmark" : A.has(n) || !t.children.length && c(t.textContent ?? "") ? "text" : "container";
119
+ }
120
+ function $(t) {
121
+ const n = t.tagName.toLowerCase();
122
+ if (n === "input") {
123
+ const e = t;
124
+ return {
125
+ type: e.type,
126
+ name: e.name || void 0,
127
+ value: e.value,
128
+ placeholder: e.placeholder || void 0,
129
+ checked: e.type === "checkbox" || e.type === "radio" ? e.checked : void 0,
130
+ required: e.required || void 0,
131
+ disabled: e.disabled || void 0
132
+ };
133
+ }
134
+ if (n === "textarea") {
135
+ const e = t;
136
+ return {
137
+ type: "textarea",
138
+ name: e.name || void 0,
139
+ value: e.value,
140
+ placeholder: e.placeholder || void 0,
141
+ required: e.required || void 0,
142
+ disabled: e.disabled || void 0
143
+ };
144
+ }
145
+ if (n === "select") {
146
+ const e = t;
147
+ return {
148
+ type: e.multiple ? "select-multiple" : "select",
149
+ name: e.name || void 0,
150
+ value: e.value,
151
+ required: e.required || void 0,
152
+ disabled: e.disabled || void 0,
153
+ options: Array.from(e.options).map((r) => [r.value, c(r.text)])
154
+ };
155
+ }
156
+ }
157
+ function k(t) {
158
+ const n = t.getAttribute("aria-label");
159
+ if (n) return c(n);
160
+ const e = t.getAttribute("aria-labelledby");
161
+ if (e) {
162
+ const o = t.ownerDocument.getElementById(e);
163
+ if (o) return c(o.textContent ?? "");
164
+ }
165
+ if (t.id) {
166
+ const o = t.ownerDocument.querySelector(`label[for="${CSS.escape(t.id)}"]`);
167
+ if (o) return c(o.textContent ?? "");
168
+ }
169
+ const r = t.getAttribute("alt") ?? t.getAttribute("title");
170
+ return r ? c(r) : void 0;
171
+ }
172
+ function T(t, n) {
173
+ const e = getComputedStyle(t), r = {};
174
+ for (const o of n) {
175
+ const i = e.getPropertyValue(
176
+ o.replace(/[A-Z]/g, (s) => `-${s.toLowerCase()}`)
177
+ );
178
+ b.has(i.trim()) || (r[o] = i.trim());
179
+ }
180
+ return r;
181
+ }
182
+ function q(t, n = {}) {
183
+ const e = n.root ?? t.ownerDocument.body, r = x(t, e), o = t.getBoundingClientRect(), i = t.parentElement, s = {};
184
+ for (const a of Array.from(t.attributes)) s[a.name] = a.value;
185
+ return {
186
+ selector: v(t, e),
187
+ path: w(r),
188
+ tag: t.tagName.toLowerCase(),
189
+ kind: L(t),
190
+ id: t.id || void 0,
191
+ classes: Array.from(t.classList),
192
+ role: t.getAttribute("role") ?? void 0,
193
+ label: k(t),
194
+ text: c(t.textContent ?? ""),
195
+ outerHTML: t.outerHTML,
196
+ innerHTML: t.innerHTML,
197
+ attributes: s,
198
+ dataset: { ...t.dataset },
199
+ hierarchy: r,
200
+ depth: Math.max(r.length - 1, 0),
201
+ index: i ? Array.from(i.children).indexOf(t) + 1 : 1,
202
+ siblings: i ? i.children.length : 1,
203
+ children: t.children.length,
204
+ rect: { x: o.x, y: o.y, width: o.width, height: o.height },
205
+ styles: T(t, n.styleProps ?? g),
206
+ field: $(t)
207
+ };
208
+ }
209
+ const E = /* @__PURE__ */ new Set(["area", "base", "br", "col", "embed", "hr", "img", "input", "link", "meta", "param", "source", "track", "wbr"]);
210
+ function D(t, n = " ") {
211
+ var i, s;
212
+ const e = t.replace(/>\s+</g, "><").split(/(<[^>]+>)/).map((a) => a.trim()).filter(Boolean), r = [];
213
+ let o = 0;
214
+ for (const a of e) {
215
+ const l = a.startsWith("<"), d = a.startsWith("</"), f = l ? (s = (i = /^<\/?([a-zA-Z0-9-]+)/.exec(a)) == null ? void 0 : i[1]) == null ? void 0 : s.toLowerCase() : void 0, u = l && (a.endsWith("/>") || (f ? E.has(f) : !1));
216
+ d && (o = Math.max(o - 1, 0)), r.push(n.repeat(o) + a), l && !d && !u && !a.startsWith("<!") && o++;
217
+ }
218
+ return r.join(`
219
+ `);
220
+ }
221
+ export {
222
+ h as STYLE_GROUPS,
223
+ g as STYLE_PROPS,
224
+ L as classify,
225
+ D as formatHtml,
226
+ x as hierarchy,
227
+ q as parseElement,
228
+ v as uniqueSelector
229
+ };
230
+ //# sourceMappingURL=parse.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parse.js","sources":["../../../src/components/element-picker/parse.ts"],"sourcesContent":["import type { ElementField, ElementInfo, ElementKind, ElementPathStep } from './types';\n\n/**\n * The computed properties we read off a picked element, grouped the way the\n * inspector shows them. Anything the browser reports as its initial value is\n * dropped later, so a plain `<div>` doesn't come back with forty entries.\n */\nexport const STYLE_GROUPS: Record<string, string[]> = {\n Layout: [\n 'display',\n 'position',\n 'top',\n 'right',\n 'bottom',\n 'left',\n 'zIndex',\n 'flexDirection',\n 'flexWrap',\n 'alignItems',\n 'justifyContent',\n 'gap',\n 'gridTemplateColumns',\n 'gridTemplateRows',\n 'overflow',\n ],\n Box: [\n 'width',\n 'height',\n 'boxSizing',\n 'padding',\n 'margin',\n 'border',\n 'borderRadius',\n ],\n Typography: [\n 'fontFamily',\n 'fontSize',\n 'fontWeight',\n 'fontStyle',\n 'lineHeight',\n 'letterSpacing',\n 'textAlign',\n 'textTransform',\n 'textDecorationLine',\n 'whiteSpace',\n ],\n Visual: [\n 'color',\n 'backgroundColor',\n 'backgroundImage',\n 'opacity',\n 'boxShadow',\n 'transform',\n 'transition',\n 'cursor',\n ],\n};\n\nexport const STYLE_PROPS: string[] = Object.values(STYLE_GROUPS).flat();\n\n/** Values the browser reports when nothing was actually set. */\nconst BORING = new Set([\n '',\n 'none',\n 'auto',\n 'normal',\n 'static',\n '0px',\n 'visible',\n 'rgba(0, 0, 0, 0)',\n 'start',\n 'nowrap',\n 'row',\n 'stretch',\n 'flex-start',\n 'content-box',\n 'transparent',\n]);\n\nconst collapse = (s: string) => s.replace(/\\s+/g, ' ').trim();\n\n/** Class names that are safe (and useful) to put in a selector. */\nconst usableClasses = (el: Element) =>\n Array.from(el.classList).filter((c) => /^[a-zA-Z_][\\w-]*$/.test(c));\n\nfunction nthOfType(el: Element): number {\n let n = 1;\n for (let sib = el.previousElementSibling; sib; sib = sib.previousElementSibling) {\n if (sib.tagName === el.tagName) n++;\n }\n return n;\n}\n\n/**\n * The shortest selector that still lands on exactly this element. Tries an\n * `#id` first, then a class-qualified path, and falls back to `:nth-of-type`\n * when a step is still ambiguous — the same ladder devtools climbs.\n */\nexport function uniqueSelector(el: HTMLElement, root: HTMLElement = document.body): string {\n const doc = el.ownerDocument;\n const hits = (sel: string) => {\n try {\n return doc.querySelectorAll(sel).length;\n } catch {\n return 0;\n }\n };\n\n if (el.id && /^[a-zA-Z_][\\w-]*$/.test(el.id) && hits(`#${el.id}`) === 1) return `#${el.id}`;\n\n const steps: string[] = [];\n for (let node: HTMLElement | null = el; node && node !== root.parentElement; node = node.parentElement) {\n const tag = node.tagName.toLowerCase();\n if (node.id && /^[a-zA-Z_][\\w-]*$/.test(node.id) && hits(`#${node.id}`) === 1) {\n steps.unshift(`#${node.id}`);\n break;\n }\n\n // Take the shortest step that still singles the node out among its\n // siblings: the bare tag, then a class or two, then the positional index.\n // Without that ladder a utility-class page yields selectors that are all\n // noise — `div.flex.min-w-0 > p.mt-0.5.truncate.text-xs` and so on.\n const parent: HTMLElement | null = node.parentElement;\n const ambiguous = (sel: string) =>\n !!parent && Array.from(parent.children).filter((c) => c.matches(sel)).length > 1;\n\n let step = tag;\n if (ambiguous(step)) {\n const classes = usableClasses(node).slice(0, 2);\n const qualified = classes.length ? `${tag}.${classes.join('.')}` : tag;\n step = ambiguous(qualified) ? `${qualified}:nth-of-type(${nthOfType(node)})` : qualified;\n }\n steps.unshift(step);\n\n const candidate = steps.join(' > ');\n if (hits(candidate) === 1) return candidate;\n }\n\n return steps.join(' > ');\n}\n\n/** The ancestor chain from the picker root down to the element itself. */\nexport function hierarchy(el: HTMLElement, root: HTMLElement): ElementPathStep[] {\n const chain: ElementPathStep[] = [];\n for (let node: HTMLElement | null = el; node && node !== root.parentElement; node = node.parentElement) {\n chain.unshift({\n tag: node.tagName.toLowerCase(),\n id: node.id || undefined,\n classes: Array.from(node.classList),\n nth: nthOfType(node),\n });\n if (node === root) break;\n }\n return chain;\n}\n\nconst pathString = (chain: ElementPathStep[]) =>\n chain\n .map((s) => {\n let step = s.tag;\n if (s.id) step += `#${s.id}`;\n else if (s.classes.length) step += `.${s.classes[0]}`;\n if (s.nth > 1) step += `:nth-of-type(${s.nth})`;\n return step;\n })\n .join(' > ');\n\nconst LANDMARKS = new Set(['nav', 'header', 'footer', 'main', 'aside', 'section', 'article', 'dialog']);\nconst TEXTUAL = new Set(['p', 'span', 'strong', 'em', 'b', 'i', 'small', 'label', 'li', 'dt', 'dd', 'blockquote', 'code', 'pre', 'time', 'figcaption']);\nconst MEDIA = new Set(['img', 'svg', 'video', 'audio', 'canvas', 'picture', 'iframe']);\n\n/** What the element *is*, as a human would name it. */\nexport function classify(el: HTMLElement): ElementKind {\n const tag = el.tagName.toLowerCase();\n const role = el.getAttribute('role');\n\n // A submit/reset/button input is a button first and a field second.\n if (tag === 'input' && /^(button|submit|reset|image)$/.test((el as HTMLInputElement).type)) return 'button';\n if (tag === 'input' || tag === 'textarea' || tag === 'select') return 'input';\n if (tag === 'button' || role === 'button') return 'button';\n if (tag === 'a') return (el as HTMLAnchorElement).href ? 'link' : 'text';\n if (MEDIA.has(tag)) return 'media';\n if (/^h[1-6]$/.test(tag)) return 'heading';\n if (tag === 'form') return 'form';\n if (tag === 'table') return 'table';\n if (tag === 'ul' || tag === 'ol' || tag === 'dl' || role === 'list') return 'list';\n if (LANDMARKS.has(tag)) return 'landmark';\n if (TEXTUAL.has(tag)) return 'text';\n // A div holding nothing but words is text; a div holding boxes is a container.\n if (!el.children.length && collapse(el.textContent ?? '')) return 'text';\n return 'container';\n}\n\nfunction readField(el: HTMLElement): ElementField | undefined {\n const tag = el.tagName.toLowerCase();\n\n if (tag === 'input') {\n const input = el as HTMLInputElement;\n return {\n type: input.type,\n name: input.name || undefined,\n value: input.value,\n placeholder: input.placeholder || undefined,\n checked: input.type === 'checkbox' || input.type === 'radio' ? input.checked : undefined,\n required: input.required || undefined,\n disabled: input.disabled || undefined,\n };\n }\n if (tag === 'textarea') {\n const area = el as HTMLTextAreaElement;\n return {\n type: 'textarea',\n name: area.name || undefined,\n value: area.value,\n placeholder: area.placeholder || undefined,\n required: area.required || undefined,\n disabled: area.disabled || undefined,\n };\n }\n if (tag === 'select') {\n const select = el as HTMLSelectElement;\n return {\n type: select.multiple ? 'select-multiple' : 'select',\n name: select.name || undefined,\n value: select.value,\n required: select.required || undefined,\n disabled: select.disabled || undefined,\n options: Array.from(select.options).map((o) => [o.value, collapse(o.text)]),\n };\n }\n return undefined;\n}\n\n/** The element's accessible-ish name: aria-label, then its `<label>`, then alt/title. */\nfunction labelOf(el: HTMLElement): string | undefined {\n const aria = el.getAttribute('aria-label');\n if (aria) return collapse(aria);\n\n const labelledBy = el.getAttribute('aria-labelledby');\n if (labelledBy) {\n const target = el.ownerDocument.getElementById(labelledBy);\n if (target) return collapse(target.textContent ?? '');\n }\n if (el.id) {\n const label = el.ownerDocument.querySelector(`label[for=\"${CSS.escape(el.id)}\"]`);\n if (label) return collapse(label.textContent ?? '');\n }\n const alt = el.getAttribute('alt') ?? el.getAttribute('title');\n return alt ? collapse(alt) : undefined;\n}\n\nfunction readStyles(el: HTMLElement, props: string[]): Record<string, string> {\n const computed = getComputedStyle(el);\n const out: Record<string, string> = {};\n for (const prop of props) {\n const value = computed.getPropertyValue(\n prop.replace(/[A-Z]/g, (c) => `-${c.toLowerCase()}`),\n );\n if (!BORING.has(value.trim())) out[prop] = value.trim();\n }\n return out;\n}\n\nexport interface ParseOptions {\n /** The subtree the selector and hierarchy are expressed relative to. */\n root?: HTMLElement;\n /** Override which computed properties are captured. */\n styleProps?: string[];\n}\n\n/** Read an element down to plain, serializable data. */\nexport function parseElement(el: HTMLElement, options: ParseOptions = {}): ElementInfo {\n const root = options.root ?? el.ownerDocument.body;\n const chain = hierarchy(el, root);\n const rect = el.getBoundingClientRect();\n const parent = el.parentElement;\n\n const attributes: Record<string, string> = {};\n for (const attr of Array.from(el.attributes)) attributes[attr.name] = attr.value;\n\n return {\n selector: uniqueSelector(el, root),\n path: pathString(chain),\n tag: el.tagName.toLowerCase(),\n kind: classify(el),\n id: el.id || undefined,\n classes: Array.from(el.classList),\n role: el.getAttribute('role') ?? undefined,\n label: labelOf(el),\n text: collapse(el.textContent ?? ''),\n outerHTML: el.outerHTML,\n innerHTML: el.innerHTML,\n attributes,\n dataset: { ...el.dataset } as Record<string, string>,\n hierarchy: chain,\n depth: Math.max(chain.length - 1, 0),\n index: parent ? Array.from(parent.children).indexOf(el) + 1 : 1,\n siblings: parent ? parent.children.length : 1,\n children: el.children.length,\n rect: { x: rect.x, y: rect.y, width: rect.width, height: rect.height },\n styles: readStyles(el, options.styleProps ?? STYLE_PROPS),\n field: readField(el),\n };\n}\n\nconst VOID_TAGS = new Set(['area', 'base', 'br', 'col', 'embed', 'hr', 'img', 'input', 'link', 'meta', 'param', 'source', 'track', 'wbr']);\n\n/**\n * Re-indent a serialized HTML string. `outerHTML` comes back as one line for\n * anything the browser normalized, which is unreadable past a few nodes.\n */\nexport function formatHtml(html: string, indent = ' '): string {\n const tokens = html\n .replace(/>\\s+</g, '><')\n .split(/(<[^>]+>)/)\n .map((t) => t.trim())\n .filter(Boolean);\n\n const lines: string[] = [];\n let depth = 0;\n\n for (const token of tokens) {\n const isTag = token.startsWith('<');\n const isClose = token.startsWith('</');\n const tag = isTag ? /^<\\/?([a-zA-Z0-9-]+)/.exec(token)?.[1]?.toLowerCase() : undefined;\n const selfClosing = isTag && (token.endsWith('/>') || (tag ? VOID_TAGS.has(tag) : false));\n\n if (isClose) depth = Math.max(depth - 1, 0);\n lines.push(indent.repeat(depth) + token);\n if (isTag && !isClose && !selfClosing && !token.startsWith('<!')) depth++;\n }\n\n return lines.join('\\n');\n}\n"],"names":["STYLE_GROUPS","STYLE_PROPS","BORING","collapse","s","usableClasses","el","c","nthOfType","sib","uniqueSelector","root","doc","hits","sel","steps","node","tag","parent","ambiguous","step","classes","qualified","candidate","hierarchy","chain","pathString","LANDMARKS","TEXTUAL","MEDIA","classify","role","readField","input","area","select","o","labelOf","aria","labelledBy","target","label","alt","readStyles","props","computed","out","prop","value","parseElement","options","rect","attributes","attr","VOID_TAGS","formatHtml","html","indent","_a","_b","tokens","t","lines","depth","token","isTag","isClose","selfClosing"],"mappings":"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"}
@@ -0,0 +1,72 @@
1
+ /** What kind of thing the element is, judged from its tag, role and content. */
2
+ export type ElementKind = 'input' | 'button' | 'link' | 'media' | 'heading' | 'text' | 'list' | 'table' | 'form' | 'landmark' | 'container';
3
+ /** One rung of the ancestor chain, root-first. */
4
+ export interface ElementPathStep {
5
+ tag: string;
6
+ id?: string;
7
+ classes: string[];
8
+ /** 1-based position among siblings of the same tag. */
9
+ nth: number;
10
+ }
11
+ /** The form state of an `<input>`/`<textarea>`/`<select>`, when there is one. */
12
+ export interface ElementField {
13
+ /** `type` for an input, otherwise the tag: `textarea`, `select`. */
14
+ type: string;
15
+ name?: string;
16
+ value?: string;
17
+ placeholder?: string;
18
+ checked?: boolean;
19
+ required?: boolean;
20
+ disabled?: boolean;
21
+ /** `<select>` options, as `[value, label]`. */
22
+ options?: [string, string][];
23
+ }
24
+ /**
25
+ * Everything we learn about a picked element — plain data, safe to
26
+ * `JSON.stringify`, post to an API or diff. The live node is kept beside it on
27
+ * {@link PickedElement}, never in here.
28
+ */
29
+ export interface ElementInfo {
30
+ /** A CSS selector that resolves to this element, and only this element. */
31
+ selector: string;
32
+ /** The same thing spelled out: `main > section.cards > div.card:nth-of-type(2)`. */
33
+ path: string;
34
+ tag: string;
35
+ kind: ElementKind;
36
+ id?: string;
37
+ classes: string[];
38
+ role?: string;
39
+ label?: string;
40
+ /** Visible text, whitespace-collapsed. */
41
+ text: string;
42
+ outerHTML: string;
43
+ innerHTML: string;
44
+ attributes: Record<string, string>;
45
+ /** `data-*` attributes, camelCased, as the DOM exposes them. */
46
+ dataset: Record<string, string>;
47
+ /** Ancestors from the picker root down to (and including) the element. */
48
+ hierarchy: ElementPathStep[];
49
+ /** How deep below the picker root it sits — the root's children are 1. */
50
+ depth: number;
51
+ /** 1-based position among *all* siblings. */
52
+ index: number;
53
+ siblings: number;
54
+ children: number;
55
+ rect: {
56
+ x: number;
57
+ y: number;
58
+ width: number;
59
+ height: number;
60
+ };
61
+ /** Computed styles worth reading — see `STYLE_PROPS`. */
62
+ styles: Record<string, string>;
63
+ field?: ElementField;
64
+ }
65
+ /** A selected element: the live node, plus what we parsed out of it. */
66
+ export interface PickedElement {
67
+ /** Stable across re-picks of the same node. */
68
+ id: string;
69
+ element: HTMLElement;
70
+ info: ElementInfo;
71
+ }
72
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/components/element-picker/types.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,QAAQ,GACR,MAAM,GACN,OAAO,GACP,SAAS,GACT,MAAM,GACN,MAAM,GACN,OAAO,GACP,MAAM,GACN,UAAU,GACV,WAAW,CAAC;AAEhB,kDAAkD;AAClD,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,uDAAuD;IACvD,GAAG,EAAE,MAAM,CAAC;CACb;AAED,iFAAiF;AACjF,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,+CAA+C;IAC/C,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,CAAC;CAC9B;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,oFAAoF;IACpF,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,WAAW,CAAC;IAClB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0CAA0C;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,gEAAgE;IAChE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,0EAA0E;IAC1E,SAAS,EAAE,eAAe,EAAE,CAAC;IAC7B,0EAA0E;IAC1E,KAAK,EAAE,MAAM,CAAC;IACd,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9D,yDAAyD;IACzD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC/B,KAAK,CAAC,EAAE,YAAY,CAAC;CACtB;AAED,wEAAwE;AACxE,MAAM,WAAW,aAAa;IAC5B,+CAA+C;IAC/C,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,WAAW,CAAC;IACrB,IAAI,EAAE,WAAW,CAAC;CACnB"}
@@ -0,0 +1,56 @@
1
+ import { PickedElement } from './types';
2
+ export interface UseElementPickerOptions {
3
+ /** The subtree you can pick from. Defaults to `document.body`. */
4
+ root?: HTMLElement | null;
5
+ /** Keep picking after the first hit. Default true. */
6
+ multiple?: boolean;
7
+ /** Controlled selection. */
8
+ value?: PickedElement[];
9
+ defaultValue?: PickedElement[];
10
+ onChange?: (picked: PickedElement[]) => void;
11
+ onPick?: (picked: PickedElement) => void;
12
+ /** Controlled picking mode. */
13
+ active?: boolean;
14
+ onActiveChange?: (active: boolean) => void;
15
+ /**
16
+ * Which elements may be picked. When an element fails, the picker walks up to
17
+ * the nearest ancestor that passes — so `(el) => el.matches('.card')` turns it
18
+ * into a card picker, however deep the pointer actually lands.
19
+ */
20
+ filter?: (el: HTMLElement) => boolean;
21
+ /** Subtrees the picker won't look at — your own toolbar, typically. */
22
+ ignoreSelector?: string;
23
+ /** Override which computed properties get captured. */
24
+ styleProps?: string[];
25
+ /** Touch: how long to hold before hover mode engages, in ms. Default 350. */
26
+ holdDelay?: number;
27
+ /** Touch: movement (px) that reads as a scroll and cancels the hold. Default 12. */
28
+ moveTolerance?: number;
29
+ /** Cap the selection. Picking past it drops the oldest. */
30
+ max?: number;
31
+ }
32
+ export interface UseElementPickerResult {
33
+ active: boolean;
34
+ start: () => void;
35
+ stop: () => void;
36
+ toggle: () => void;
37
+ /** What the pointer is over right now — the live preview target. */
38
+ hovered: HTMLElement | null;
39
+ /** True while a touch hold has engaged hover mode. */
40
+ holding: boolean;
41
+ picked: PickedElement[];
42
+ pick: (el: HTMLElement) => void;
43
+ remove: (id: string) => void;
44
+ clear: () => void;
45
+ isPicked: (el: HTMLElement) => boolean;
46
+ root: HTMLElement | null;
47
+ /** Put this on any UI of your own that must stay clickable while picking. */
48
+ ignoreProps: Record<string, string>;
49
+ }
50
+ /**
51
+ * The machinery behind {@link ElementPicker}: hover tracking, click-to-select,
52
+ * and the press-and-hold gesture that turns a touchscreen — which has no hover
53
+ * — into one. Use it directly when you want the behaviour without the overlay.
54
+ */
55
+ export declare function useElementPicker(options?: UseElementPickerOptions): UseElementPickerResult;
56
+ //# sourceMappingURL=use-element-picker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"use-element-picker.d.ts","sourceRoot":"","sources":["../../../src/components/element-picker/use-element-picker.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAc7C,MAAM,WAAW,uBAAuB;IACtC,kEAAkE;IAClE,IAAI,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC1B,sDAAsD;IACtD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,aAAa,EAAE,CAAC;IACxB,YAAY,CAAC,EAAE,aAAa,EAAE,CAAC;IAC/B,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,IAAI,CAAC;IAC7C,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,IAAI,CAAC;IACzC,+BAA+B;IAC/B,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C;;;;OAIG;IACH,MAAM,CAAC,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC;IACtC,uEAAuE;IACvE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,6EAA6E;IAC7E,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oFAAoF;IACpF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,2DAA2D;IAC3D,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,OAAO,CAAC;IAChB,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,MAAM,EAAE,MAAM,IAAI,CAAC;IACnB,oEAAoE;IACpE,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAC5B,sDAAsD;IACtD,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,IAAI,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,IAAI,CAAC;IAChC,MAAM,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,QAAQ,EAAE,CAAC,EAAE,EAAE,WAAW,KAAK,OAAO,CAAC;IACvC,IAAI,EAAE,WAAW,GAAG,IAAI,CAAC;IACzB,6EAA6E;IAC7E,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACrC;AAOD;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,GAAE,uBAA4B,GAAG,sBAAsB,CAiW9F"}