@miethe/ui 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (251) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/README.md +1536 -0
  3. package/dist/bulk-actions/Button.d.ts +28 -0
  4. package/dist/bulk-actions/Button.d.ts.map +1 -0
  5. package/dist/bulk-actions/Button.js +45 -0
  6. package/dist/bulk-actions/Button.js.map +1 -0
  7. package/dist/bulk-actions/bulk-action-bar.d.ts +91 -0
  8. package/dist/bulk-actions/bulk-action-bar.d.ts.map +1 -0
  9. package/dist/bulk-actions/bulk-action-bar.js +94 -0
  10. package/dist/bulk-actions/bulk-action-bar.js.map +1 -0
  11. package/dist/bulk-actions/index.d.ts +5 -0
  12. package/dist/bulk-actions/index.d.ts.map +1 -0
  13. package/dist/bulk-actions/index.js +7 -0
  14. package/dist/bulk-actions/index.js.map +1 -0
  15. package/dist/bulk-actions/utils.d.ts +6 -0
  16. package/dist/bulk-actions/utils.d.ts.map +1 -0
  17. package/dist/bulk-actions/utils.js +9 -0
  18. package/dist/bulk-actions/utils.js.map +1 -0
  19. package/dist/components/ui/alert.d.ts +9 -0
  20. package/dist/components/ui/alert.d.ts.map +1 -0
  21. package/dist/components/ui/alert.js +23 -0
  22. package/dist/components/ui/alert.js.map +1 -0
  23. package/dist/components/ui/button.d.ts +12 -0
  24. package/dist/components/ui/button.d.ts.map +1 -0
  25. package/dist/components/ui/button.js +34 -0
  26. package/dist/components/ui/button.js.map +1 -0
  27. package/dist/components/ui/collapsible.d.ts +6 -0
  28. package/dist/components/ui/collapsible.d.ts.map +1 -0
  29. package/dist/components/ui/collapsible.js +7 -0
  30. package/dist/components/ui/collapsible.js.map +1 -0
  31. package/dist/components/ui/skeleton.d.ts +4 -0
  32. package/dist/components/ui/skeleton.d.ts.map +1 -0
  33. package/dist/components/ui/skeleton.js +7 -0
  34. package/dist/components/ui/skeleton.js.map +1 -0
  35. package/dist/content-viewer/ContentPane.d.ts +107 -0
  36. package/dist/content-viewer/ContentPane.d.ts.map +1 -0
  37. package/dist/content-viewer/ContentPane.js +247 -0
  38. package/dist/content-viewer/ContentPane.js.map +1 -0
  39. package/dist/content-viewer/ContentViewerProvider.d.ts +83 -0
  40. package/dist/content-viewer/ContentViewerProvider.d.ts.map +1 -0
  41. package/dist/content-viewer/ContentViewerProvider.js +92 -0
  42. package/dist/content-viewer/ContentViewerProvider.js.map +1 -0
  43. package/dist/content-viewer/FileTree.d.ts +71 -0
  44. package/dist/content-viewer/FileTree.d.ts.map +1 -0
  45. package/dist/content-viewer/FileTree.js +294 -0
  46. package/dist/content-viewer/FileTree.js.map +1 -0
  47. package/dist/content-viewer/adapters.d.ts +101 -0
  48. package/dist/content-viewer/adapters.d.ts.map +1 -0
  49. package/dist/content-viewer/adapters.js +32 -0
  50. package/dist/content-viewer/adapters.js.map +1 -0
  51. package/dist/content-viewer/index.d.ts +8 -0
  52. package/dist/content-viewer/index.d.ts.map +1 -0
  53. package/dist/content-viewer/index.js +5 -0
  54. package/dist/content-viewer/index.js.map +1 -0
  55. package/dist/diff/DiffViewer.d.ts +112 -0
  56. package/dist/diff/DiffViewer.d.ts.map +1 -0
  57. package/dist/diff/DiffViewer.js +414 -0
  58. package/dist/diff/DiffViewer.js.map +1 -0
  59. package/dist/diff/diff.d.ts +32 -0
  60. package/dist/diff/diff.d.ts.map +1 -0
  61. package/dist/diff/diff.js +8 -0
  62. package/dist/diff/diff.js.map +1 -0
  63. package/dist/diff/index.d.ts +4 -0
  64. package/dist/diff/index.d.ts.map +1 -0
  65. package/dist/diff/index.js +3 -0
  66. package/dist/diff/index.js.map +1 -0
  67. package/dist/display/FilePreviewPane.d.ts +31 -0
  68. package/dist/display/FilePreviewPane.d.ts.map +1 -0
  69. package/dist/display/FilePreviewPane.js +144 -0
  70. package/dist/display/FilePreviewPane.js.map +1 -0
  71. package/dist/display/FrontmatterDisplay.d.ts +33 -0
  72. package/dist/display/FrontmatterDisplay.d.ts.map +1 -0
  73. package/dist/display/FrontmatterDisplay.js +79 -0
  74. package/dist/display/FrontmatterDisplay.js.map +1 -0
  75. package/dist/display/index.d.ts +5 -0
  76. package/dist/display/index.d.ts.map +1 -0
  77. package/dist/display/index.js +4 -0
  78. package/dist/display/index.js.map +1 -0
  79. package/dist/editor/MarkdownEditor.d.ts +28 -0
  80. package/dist/editor/MarkdownEditor.d.ts.map +1 -0
  81. package/dist/editor/MarkdownEditor.js +160 -0
  82. package/dist/editor/MarkdownEditor.js.map +1 -0
  83. package/dist/editor/SplitPreview.d.ts +28 -0
  84. package/dist/editor/SplitPreview.d.ts.map +1 -0
  85. package/dist/editor/SplitPreview.js +34 -0
  86. package/dist/editor/SplitPreview.js.map +1 -0
  87. package/dist/editor/index.d.ts +5 -0
  88. package/dist/editor/index.d.ts.map +1 -0
  89. package/dist/editor/index.js +4 -0
  90. package/dist/editor/index.js.map +1 -0
  91. package/dist/filters/filters-dropdown.d.ts +24 -0
  92. package/dist/filters/filters-dropdown.d.ts.map +1 -0
  93. package/dist/filters/filters-dropdown.js +36 -0
  94. package/dist/filters/filters-dropdown.js.map +1 -0
  95. package/dist/filters/index.d.ts +9 -0
  96. package/dist/filters/index.d.ts.map +1 -0
  97. package/dist/filters/index.js +5 -0
  98. package/dist/filters/index.js.map +1 -0
  99. package/dist/filters/sort-dropdown.d.ts +13 -0
  100. package/dist/filters/sort-dropdown.d.ts.map +1 -0
  101. package/dist/filters/sort-dropdown.js +20 -0
  102. package/dist/filters/sort-dropdown.js.map +1 -0
  103. package/dist/filters/tag-filter-popover.d.ts +39 -0
  104. package/dist/filters/tag-filter-popover.d.ts.map +1 -0
  105. package/dist/filters/tag-filter-popover.js +72 -0
  106. package/dist/filters/tag-filter-popover.js.map +1 -0
  107. package/dist/filters/tool-filter-popover.d.ts +42 -0
  108. package/dist/filters/tool-filter-popover.d.ts.map +1 -0
  109. package/dist/filters/tool-filter-popover.js +67 -0
  110. package/dist/filters/tool-filter-popover.js.map +1 -0
  111. package/dist/hooks/use-debounce.d.ts +9 -0
  112. package/dist/hooks/use-debounce.d.ts.map +1 -0
  113. package/dist/hooks/use-debounce.js +21 -0
  114. package/dist/hooks/use-debounce.js.map +1 -0
  115. package/dist/hooks/use-intersection-observer.d.ts +11 -0
  116. package/dist/hooks/use-intersection-observer.d.ts.map +1 -0
  117. package/dist/hooks/use-intersection-observer.js +25 -0
  118. package/dist/hooks/use-intersection-observer.js.map +1 -0
  119. package/dist/index.d.ts +10 -0
  120. package/dist/index.d.ts.map +1 -0
  121. package/dist/index.js +10 -0
  122. package/dist/index.js.map +1 -0
  123. package/dist/pickers/EntityPickerDialog.d.ts +233 -0
  124. package/dist/pickers/EntityPickerDialog.d.ts.map +1 -0
  125. package/dist/pickers/EntityPickerDialog.js +355 -0
  126. package/dist/pickers/EntityPickerDialog.js.map +1 -0
  127. package/dist/pickers/EntityPickerViewToggle.d.ts +8 -0
  128. package/dist/pickers/EntityPickerViewToggle.d.ts.map +1 -0
  129. package/dist/pickers/EntityPickerViewToggle.js +17 -0
  130. package/dist/pickers/EntityPickerViewToggle.js.map +1 -0
  131. package/dist/pickers/index.d.ts +5 -0
  132. package/dist/pickers/index.d.ts.map +1 -0
  133. package/dist/pickers/index.js +3 -0
  134. package/dist/pickers/index.js.map +1 -0
  135. package/dist/primitives/Badge.d.ts +16 -0
  136. package/dist/primitives/Badge.d.ts.map +1 -0
  137. package/dist/primitives/Badge.js +43 -0
  138. package/dist/primitives/Badge.js.map +1 -0
  139. package/dist/primitives/BaseArtifactModal.d.ts +114 -0
  140. package/dist/primitives/BaseArtifactModal.d.ts.map +1 -0
  141. package/dist/primitives/BaseArtifactModal.js +76 -0
  142. package/dist/primitives/BaseArtifactModal.js.map +1 -0
  143. package/dist/primitives/Dialog.d.ts +20 -0
  144. package/dist/primitives/Dialog.d.ts.map +1 -0
  145. package/dist/primitives/Dialog.js +24 -0
  146. package/dist/primitives/Dialog.js.map +1 -0
  147. package/dist/primitives/DropdownMenu.d.ts +28 -0
  148. package/dist/primitives/DropdownMenu.d.ts.map +1 -0
  149. package/dist/primitives/DropdownMenu.js +34 -0
  150. package/dist/primitives/DropdownMenu.js.map +1 -0
  151. package/dist/primitives/EnterpriseOwnerBadge.d.ts +9 -0
  152. package/dist/primitives/EnterpriseOwnerBadge.d.ts.map +1 -0
  153. package/dist/primitives/EnterpriseOwnerBadge.js +12 -0
  154. package/dist/primitives/EnterpriseOwnerBadge.js.map +1 -0
  155. package/dist/primitives/GroupedSelect.d.ts +30 -0
  156. package/dist/primitives/GroupedSelect.d.ts.map +1 -0
  157. package/dist/primitives/GroupedSelect.js +47 -0
  158. package/dist/primitives/GroupedSelect.js.map +1 -0
  159. package/dist/primitives/Input.d.ts +6 -0
  160. package/dist/primitives/Input.d.ts.map +1 -0
  161. package/dist/primitives/Input.js +9 -0
  162. package/dist/primitives/Input.js.map +1 -0
  163. package/dist/primitives/LockIcon.d.ts +11 -0
  164. package/dist/primitives/LockIcon.d.ts.map +1 -0
  165. package/dist/primitives/LockIcon.js +15 -0
  166. package/dist/primitives/LockIcon.js.map +1 -0
  167. package/dist/primitives/MaskedSecretInput.d.ts +16 -0
  168. package/dist/primitives/MaskedSecretInput.d.ts.map +1 -0
  169. package/dist/primitives/MaskedSecretInput.js +42 -0
  170. package/dist/primitives/MaskedSecretInput.js.map +1 -0
  171. package/dist/primitives/ModalHeader.d.ts +66 -0
  172. package/dist/primitives/ModalHeader.d.ts.map +1 -0
  173. package/dist/primitives/ModalHeader.js +58 -0
  174. package/dist/primitives/ModalHeader.js.map +1 -0
  175. package/dist/primitives/Popover.d.ts +9 -0
  176. package/dist/primitives/Popover.d.ts.map +1 -0
  177. package/dist/primitives/Popover.js +13 -0
  178. package/dist/primitives/Popover.js.map +1 -0
  179. package/dist/primitives/ScrollArea.d.ts +6 -0
  180. package/dist/primitives/ScrollArea.d.ts.map +1 -0
  181. package/dist/primitives/ScrollArea.js +11 -0
  182. package/dist/primitives/ScrollArea.js.map +1 -0
  183. package/dist/primitives/SearchableCombobox.d.ts +30 -0
  184. package/dist/primitives/SearchableCombobox.d.ts.map +1 -0
  185. package/dist/primitives/SearchableCombobox.js +124 -0
  186. package/dist/primitives/SearchableCombobox.js.map +1 -0
  187. package/dist/primitives/SearchablePickerDialog.d.ts +20 -0
  188. package/dist/primitives/SearchablePickerDialog.d.ts.map +1 -0
  189. package/dist/primitives/SearchablePickerDialog.js +78 -0
  190. package/dist/primitives/SearchablePickerDialog.js.map +1 -0
  191. package/dist/primitives/StatusBadge.d.ts +21 -0
  192. package/dist/primitives/StatusBadge.d.ts.map +1 -0
  193. package/dist/primitives/StatusBadge.js +25 -0
  194. package/dist/primitives/StatusBadge.js.map +1 -0
  195. package/dist/primitives/TabNavigation.d.ts +68 -0
  196. package/dist/primitives/TabNavigation.d.ts.map +1 -0
  197. package/dist/primitives/TabNavigation.js +74 -0
  198. package/dist/primitives/TabNavigation.js.map +1 -0
  199. package/dist/primitives/Tabs.d.ts +8 -0
  200. package/dist/primitives/Tabs.d.ts.map +1 -0
  201. package/dist/primitives/Tabs.js +14 -0
  202. package/dist/primitives/Tabs.js.map +1 -0
  203. package/dist/primitives/Tooltip.d.ts +8 -0
  204. package/dist/primitives/Tooltip.d.ts.map +1 -0
  205. package/dist/primitives/Tooltip.js +12 -0
  206. package/dist/primitives/Tooltip.js.map +1 -0
  207. package/dist/primitives/VerticalTabNavigation.d.ts +75 -0
  208. package/dist/primitives/VerticalTabNavigation.d.ts.map +1 -0
  209. package/dist/primitives/VerticalTabNavigation.js +166 -0
  210. package/dist/primitives/VerticalTabNavigation.js.map +1 -0
  211. package/dist/primitives/ViewModeToggle.d.ts +12 -0
  212. package/dist/primitives/ViewModeToggle.d.ts.map +1 -0
  213. package/dist/primitives/ViewModeToggle.js +56 -0
  214. package/dist/primitives/ViewModeToggle.js.map +1 -0
  215. package/dist/primitives/WizardShell.d.ts +81 -0
  216. package/dist/primitives/WizardShell.d.ts.map +1 -0
  217. package/dist/primitives/WizardShell.js +73 -0
  218. package/dist/primitives/WizardShell.js.map +1 -0
  219. package/dist/primitives/index.d.ts +38 -0
  220. package/dist/primitives/index.d.ts.map +1 -0
  221. package/dist/primitives/index.js +24 -0
  222. package/dist/primitives/index.js.map +1 -0
  223. package/dist/primitives/utils.d.ts +6 -0
  224. package/dist/primitives/utils.d.ts.map +1 -0
  225. package/dist/primitives/utils.js +9 -0
  226. package/dist/primitives/utils.js.map +1 -0
  227. package/dist/types/index.d.ts +63 -0
  228. package/dist/types/index.d.ts.map +1 -0
  229. package/dist/types/index.js +9 -0
  230. package/dist/types/index.js.map +1 -0
  231. package/dist/utils/frontmatter.d.ts +63 -0
  232. package/dist/utils/frontmatter.d.ts.map +1 -0
  233. package/dist/utils/frontmatter.js +345 -0
  234. package/dist/utils/frontmatter.js.map +1 -0
  235. package/dist/utils/index.d.ts +6 -0
  236. package/dist/utils/index.d.ts.map +1 -0
  237. package/dist/utils/index.js +6 -0
  238. package/dist/utils/index.js.map +1 -0
  239. package/dist/utils/perf-marks.d.ts +28 -0
  240. package/dist/utils/perf-marks.d.ts.map +1 -0
  241. package/dist/utils/perf-marks.js +45 -0
  242. package/dist/utils/perf-marks.js.map +1 -0
  243. package/dist/utils/readme-utils.d.ts +67 -0
  244. package/dist/utils/readme-utils.d.ts.map +1 -0
  245. package/dist/utils/readme-utils.js +164 -0
  246. package/dist/utils/readme-utils.js.map +1 -0
  247. package/dist/utils/type-colors.d.ts +70 -0
  248. package/dist/utils/type-colors.d.ts.map +1 -0
  249. package/dist/utils/type-colors.js +118 -0
  250. package/dist/utils/type-colors.js.map +1 -0
  251. package/package.json +131 -0
@@ -0,0 +1,294 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useState, useCallback, useRef, useEffect } from 'react';
4
+ import { ChevronRight, ChevronDown, Folder, FolderOpen, FileText, FileCode, File, Braces, Trash2, Plus, } from 'lucide-react';
5
+ import { cn } from '../primitives/utils';
6
+ import { Button } from '../components/ui/button';
7
+ import { Skeleton } from '../components/ui/skeleton';
8
+ // ============================================================================
9
+ // Helper Functions
10
+ // ============================================================================
11
+ /**
12
+ * Get the appropriate icon for a file based on its extension
13
+ */
14
+ function getFileIcon(fileName) {
15
+ const extension = fileName.split('.').pop()?.toLowerCase();
16
+ switch (extension) {
17
+ case 'md':
18
+ case 'txt':
19
+ return FileText;
20
+ case 'ts':
21
+ case 'tsx':
22
+ case 'js':
23
+ case 'jsx':
24
+ case 'py':
25
+ case 'java':
26
+ case 'cpp':
27
+ case 'c':
28
+ case 'go':
29
+ case 'rs':
30
+ return FileCode;
31
+ case 'json':
32
+ return Braces;
33
+ default:
34
+ return File;
35
+ }
36
+ }
37
+ // ============================================================================
38
+ // Helper: Flatten tree to ordered list for keyboard navigation
39
+ // ============================================================================
40
+ /**
41
+ * Flatten tree nodes into a linear list for keyboard navigation.
42
+ * Only includes visible nodes (respects expanded state).
43
+ */
44
+ function flattenVisibleNodes(nodes, expandedPaths) {
45
+ const result = [];
46
+ function traverse(nodeList) {
47
+ for (const node of nodeList) {
48
+ result.push(node);
49
+ if (node.type === 'directory' && expandedPaths.has(node.path) && node.children) {
50
+ traverse(node.children);
51
+ }
52
+ }
53
+ }
54
+ traverse(nodes);
55
+ return result;
56
+ }
57
+ function TreeNode({ node, level, selectedPath, focusedPath, expandedPaths, onSelect, onToggle, onDelete, onFocus, onKeyNavigation, treeSize, positionInSet, }) {
58
+ const nodeRef = useRef(null);
59
+ const isExpanded = expandedPaths.has(node.path);
60
+ const isSelected = selectedPath === node.path;
61
+ const isFocused = focusedPath === node.path;
62
+ const isDirectory = node.type === 'directory';
63
+ // Focus the element when it becomes the focused item (roving tabindex)
64
+ useEffect(() => {
65
+ if (isFocused && nodeRef.current) {
66
+ nodeRef.current.focus();
67
+ }
68
+ }, [isFocused]);
69
+ const handleClick = useCallback(() => {
70
+ onFocus(node.path);
71
+ if (isDirectory) {
72
+ onToggle(node.path);
73
+ }
74
+ else {
75
+ onSelect(node.path);
76
+ }
77
+ }, [isDirectory, node.path, onSelect, onToggle, onFocus]);
78
+ const handleKeyDown = useCallback((e) => {
79
+ // Handle Enter and Space for activation
80
+ if (e.key === 'Enter' || e.key === ' ') {
81
+ e.preventDefault();
82
+ if (isDirectory) {
83
+ onToggle(node.path);
84
+ }
85
+ else {
86
+ onSelect(node.path);
87
+ }
88
+ return;
89
+ }
90
+ // Handle ArrowRight to expand directory
91
+ if (e.key === 'ArrowRight' && isDirectory) {
92
+ e.preventDefault();
93
+ if (!isExpanded) {
94
+ onToggle(node.path);
95
+ }
96
+ return;
97
+ }
98
+ // Handle ArrowLeft to collapse directory
99
+ if (e.key === 'ArrowLeft' && isDirectory && isExpanded) {
100
+ e.preventDefault();
101
+ onToggle(node.path);
102
+ return;
103
+ }
104
+ // Delegate Up/Down/Home/End navigation to parent
105
+ onKeyNavigation(e, node);
106
+ }, [isDirectory, isExpanded, node, onSelect, onToggle, onKeyNavigation]);
107
+ const handleDelete = useCallback((e) => {
108
+ e.stopPropagation();
109
+ if (onDelete) {
110
+ onDelete(node.path);
111
+ }
112
+ }, [node.path, onDelete]);
113
+ const IconComponent = isDirectory ? (isExpanded ? FolderOpen : Folder) : getFileIcon(node.name);
114
+ return (_jsxs("div", { role: "none", children: [_jsxs("div", { ref: nodeRef, role: "treeitem", tabIndex: isFocused ? 0 : -1, "aria-selected": isSelected, "aria-expanded": isDirectory ? isExpanded : undefined, "aria-level": level + 1, "aria-setsize": treeSize, "aria-posinset": positionInSet, "data-testid": `tree-item-${node.path}`, className: cn('group flex cursor-pointer items-center gap-1 rounded px-2 py-1 transition-colors hover:bg-accent', isSelected && 'bg-accent text-accent-foreground', 'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1'), style: { paddingLeft: `${level * 12 + 8}px` }, onClick: handleClick, onKeyDown: handleKeyDown, onFocus: () => onFocus(node.path), children: [isDirectory ? (_jsx("span", { className: "flex-shrink-0", "aria-hidden": "true", children: isExpanded ? (_jsx(ChevronDown, { className: "h-4 w-4 text-muted-foreground" })) : (_jsx(ChevronRight, { className: "h-4 w-4 text-muted-foreground" })) })) : (_jsx("span", { className: "w-4 flex-shrink-0", "aria-hidden": "true" })), _jsx(IconComponent, { className: cn('h-4 w-4 flex-shrink-0', isDirectory ? 'text-blue-500' : 'text-muted-foreground'), "aria-hidden": "true" }), _jsx("span", { className: "min-w-0 flex-1 truncate text-sm", children: node.name }), onDelete && !isDirectory && (_jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6 opacity-0 transition-opacity focus:opacity-100 group-hover:opacity-100", onClick: handleDelete, "aria-label": `Delete ${node.name}`, tabIndex: -1, children: _jsx(Trash2, { className: "h-3 w-3", "aria-hidden": "true" }) }))] }), isDirectory && isExpanded && node.children && (_jsx("div", { role: "group", "aria-label": `Contents of ${node.name}`, children: node.children.map((child, index) => {
115
+ // Calculate position in the flattened visible list
116
+ // This is a simplified version - the parent handles the full calculation
117
+ return (_jsx(TreeNode, { node: child, level: level + 1, selectedPath: selectedPath, focusedPath: focusedPath, expandedPaths: expandedPaths, onSelect: onSelect, onToggle: onToggle, onDelete: onDelete, onFocus: onFocus, onKeyNavigation: onKeyNavigation, treeSize: treeSize, positionInSet: index + 1 }, child.path));
118
+ }) }))] }));
119
+ }
120
+ // ============================================================================
121
+ // Loading Skeleton
122
+ // ============================================================================
123
+ function FileTreeSkeleton() {
124
+ return (_jsx("div", { className: "space-y-2 p-2", children: [...Array(8)].map((_, i) => (_jsxs("div", { className: "flex items-center gap-2", style: { paddingLeft: `${(i % 3) * 12 + 8}px` }, children: [_jsx(Skeleton, { className: "h-4 w-4" }), _jsx(Skeleton, { className: "h-4 flex-1" })] }, i))) }));
125
+ }
126
+ // ============================================================================
127
+ // Main Component
128
+ // ============================================================================
129
+ /**
130
+ * FileTree - Recursive file browser component
131
+ *
132
+ * Displays a hierarchical tree of files and directories with expand/collapse functionality.
133
+ * Supports keyboard navigation, file selection, and optional delete actions.
134
+ *
135
+ * Features:
136
+ * - Recursive rendering of nested directories
137
+ * - Expandable/collapsible folders with chevron icons
138
+ * - File type icons (markdown, code, JSON, etc.)
139
+ * - Selected file highlighting
140
+ * - Full keyboard navigation (Arrow keys, Enter, Space, Home, End)
141
+ * - ARIA tree pattern for screen reader accessibility
142
+ * - Roving tabindex for efficient keyboard focus management
143
+ * - Optional context actions (delete)
144
+ * - Loading skeleton state
145
+ * - Read-only mode (hides create/delete buttons)
146
+ *
147
+ * Keyboard Controls:
148
+ * - ArrowUp/ArrowDown: Move focus between visible items
149
+ * - ArrowRight: Expand folder (if collapsed) or move to first child
150
+ * - ArrowLeft: Collapse folder (if expanded) or move to parent
151
+ * - Enter/Space: Select file or toggle folder
152
+ * - Home: Move to first item
153
+ * - End: Move to last visible item
154
+ *
155
+ * @example
156
+ * ```tsx
157
+ * // Editable mode (default)
158
+ * <FileTree
159
+ * entityId="skill-123"
160
+ * files={fileStructure}
161
+ * selectedPath={selectedPath}
162
+ * onSelect={(path) => setSelectedPath(path)}
163
+ * onDeleteFile={(path) => handleDelete(path)}
164
+ * />
165
+ *
166
+ * // Read-only mode (no create/delete buttons)
167
+ * <FileTree
168
+ * entityId="skill-123"
169
+ * files={fileStructure}
170
+ * selectedPath={selectedPath}
171
+ * onSelect={(path) => setSelectedPath(path)}
172
+ * readOnly
173
+ * ariaLabel="Artifact file browser"
174
+ * />
175
+ * ```
176
+ */
177
+ export function FileTree({ entityId: _entityId, files, selectedPath, onSelect, onAddFile, onDeleteFile, isLoading = false, readOnly = false, ariaLabel = 'File browser', }) {
178
+ const [expandedPaths, setExpandedPaths] = useState(new Set());
179
+ const [focusedPath, setFocusedPath] = useState(null);
180
+ const treeRef = useRef(null);
181
+ // Get flat list of all visible nodes for keyboard navigation
182
+ const visibleNodes = flattenVisibleNodes(files, expandedPaths);
183
+ // Initialize focus to first item or selected item
184
+ useEffect(() => {
185
+ if (focusedPath === null && visibleNodes.length > 0) {
186
+ // If there's a selected path, focus it; otherwise focus first item
187
+ const firstNode = visibleNodes[0];
188
+ if (selectedPath && visibleNodes.some((n) => n.path === selectedPath)) {
189
+ setFocusedPath(selectedPath);
190
+ }
191
+ else if (firstNode) {
192
+ setFocusedPath(firstNode.path);
193
+ }
194
+ }
195
+ }, [focusedPath, visibleNodes, selectedPath]);
196
+ const handleToggle = useCallback((path) => {
197
+ setExpandedPaths((prev) => {
198
+ const next = new Set(prev);
199
+ if (next.has(path)) {
200
+ next.delete(path);
201
+ }
202
+ else {
203
+ next.add(path);
204
+ }
205
+ return next;
206
+ });
207
+ }, []);
208
+ const handleFocus = useCallback((path) => {
209
+ setFocusedPath(path);
210
+ }, []);
211
+ // Handle keyboard navigation for the tree
212
+ const handleKeyNavigation = useCallback((e, currentNode) => {
213
+ const currentIndex = visibleNodes.findIndex((n) => n.path === currentNode.path);
214
+ if (currentIndex === -1)
215
+ return;
216
+ switch (e.key) {
217
+ case 'ArrowDown': {
218
+ e.preventDefault();
219
+ const nextNode = visibleNodes[currentIndex + 1];
220
+ if (nextNode) {
221
+ setFocusedPath(nextNode.path);
222
+ }
223
+ break;
224
+ }
225
+ case 'ArrowUp': {
226
+ e.preventDefault();
227
+ const prevNode = visibleNodes[currentIndex - 1];
228
+ if (prevNode) {
229
+ setFocusedPath(prevNode.path);
230
+ }
231
+ break;
232
+ }
233
+ case 'Home': {
234
+ e.preventDefault();
235
+ const firstNode = visibleNodes[0];
236
+ if (firstNode) {
237
+ setFocusedPath(firstNode.path);
238
+ }
239
+ break;
240
+ }
241
+ case 'End': {
242
+ e.preventDefault();
243
+ const lastNode = visibleNodes[visibleNodes.length - 1];
244
+ if (lastNode) {
245
+ setFocusedPath(lastNode.path);
246
+ }
247
+ break;
248
+ }
249
+ case 'ArrowLeft': {
250
+ // If not a directory or not expanded, try to move to parent
251
+ e.preventDefault();
252
+ const isDirectory = currentNode.type === 'directory';
253
+ const isExpanded = expandedPaths.has(currentNode.path);
254
+ if (isDirectory && isExpanded) {
255
+ // Let TreeNode handle collapsing
256
+ return;
257
+ }
258
+ // Find parent directory
259
+ const pathParts = currentNode.path.split('/');
260
+ if (pathParts.length > 1) {
261
+ pathParts.pop();
262
+ const parentPath = pathParts.join('/');
263
+ const parentNode = visibleNodes.find((n) => n.path === parentPath);
264
+ if (parentNode) {
265
+ setFocusedPath(parentPath);
266
+ }
267
+ }
268
+ break;
269
+ }
270
+ case 'ArrowRight': {
271
+ // If directory is expanded, move to first child
272
+ const isDirectory = currentNode.type === 'directory';
273
+ const isExpanded = expandedPaths.has(currentNode.path);
274
+ if (isDirectory && isExpanded && currentNode.children?.length) {
275
+ e.preventDefault();
276
+ const firstChild = currentNode.children[0];
277
+ if (firstChild) {
278
+ setFocusedPath(firstChild.path);
279
+ }
280
+ }
281
+ // If not expanded, TreeNode will handle expanding
282
+ break;
283
+ }
284
+ }
285
+ }, [visibleNodes, expandedPaths]);
286
+ if (isLoading) {
287
+ return _jsx(FileTreeSkeleton, {});
288
+ }
289
+ if (files.length === 0) {
290
+ return (_jsxs("div", { className: "flex h-full flex-col items-center justify-center py-12 text-center", children: [_jsx(Folder, { className: "mb-4 h-12 w-12 text-muted-foreground opacity-50", "aria-hidden": "true" }), _jsx("h3", { className: "mb-1 text-sm font-medium text-muted-foreground", children: "No files found" }), _jsx("p", { className: "text-xs text-muted-foreground", children: "This entity does not contain any files yet." })] }));
291
+ }
292
+ return (_jsxs("div", { className: "flex h-full flex-col", children: [onAddFile && !readOnly && (_jsxs("div", { className: "flex items-center justify-between border-b p-2", children: [_jsx("span", { className: "whitespace-nowrap text-xs font-medium text-muted-foreground", children: "FILES" }), _jsx(Button, { variant: "ghost", size: "icon", className: "h-6 w-6 flex-shrink-0", onClick: onAddFile, "aria-label": "Add new file", children: _jsx(Plus, { className: "h-3 w-3", "aria-hidden": "true" }) })] })), _jsx("div", { ref: treeRef, role: "tree", "aria-label": ariaLabel, className: "flex-1 overflow-auto p-2", "data-testid": "file-tree", children: files.map((node, index) => (_jsx(TreeNode, { node: node, level: 0, selectedPath: selectedPath, focusedPath: focusedPath, expandedPaths: expandedPaths, onSelect: onSelect, onToggle: handleToggle, onDelete: readOnly ? undefined : onDeleteFile, onFocus: handleFocus, onKeyNavigation: handleKeyNavigation, treeSize: visibleNodes.length, positionInSet: index + 1 }, node.path))) })] }));
293
+ }
294
+ //# sourceMappingURL=FileTree.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FileTree.js","sourceRoot":"","sources":["../../src/content-viewer/FileTree.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * @skillmeat/content-viewer — Adapter Interface Definitions
3
+ *
4
+ * Adapter abstractions allow consumers to inject their own data-fetching
5
+ * hooks without coupling content-viewer components to any specific API layer
6
+ * (SkillMeat backend, REST, GraphQL, static JSON, etc.).
7
+ *
8
+ * Consumers implement these interfaces and pass them to ContentViewerProvider.
9
+ * Components then call useContentViewerAdapter() to access the injected hooks.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * // In your app, create an adapter that wraps your fetching hooks:
14
+ * const myAdapter: ContentViewerAdapter = {
15
+ * useFileTree: (artifactId, options) => {
16
+ * const result = useCatalogFileTree(sourceId, artifactId, options);
17
+ * return { data: result.data, isLoading: result.isLoading, error: result.error };
18
+ * },
19
+ * useFileContent: (artifactId, filePath, options) => {
20
+ * const result = useCatalogFileContent(sourceId, artifactId, filePath, options);
21
+ * return { data: result.data, isLoading: result.isLoading, error: result.error };
22
+ * },
23
+ * };
24
+ *
25
+ * // Wrap your component tree:
26
+ * <ContentViewerProvider adapter={myAdapter}>
27
+ * <FileTree artifactId={id} />
28
+ * </ContentViewerProvider>
29
+ * ```
30
+ */
31
+ import type { FileTreeResponse, FileContentResponse } from '../types';
32
+ /**
33
+ * Common options accepted by all adapter hooks.
34
+ */
35
+ export interface AdapterHookOptions {
36
+ /**
37
+ * When false, the hook skips fetching entirely.
38
+ * Useful for conditional/deferred data loading.
39
+ * @default true
40
+ */
41
+ enabled?: boolean;
42
+ }
43
+ /**
44
+ * Normalized return shape for any data-fetching adapter hook.
45
+ * Mirrors the TanStack Query subset that content-viewer components need.
46
+ */
47
+ export interface AdapterQueryResult<TData> {
48
+ /** The fetched data, or undefined while loading or on error. */
49
+ data: TData | undefined;
50
+ /** True while the initial fetch is in flight. */
51
+ isLoading: boolean;
52
+ /** Non-null when the most recent fetch failed. */
53
+ error: Error | null;
54
+ }
55
+ /**
56
+ * Adapter interface for fetching the directory/file tree of an artifact.
57
+ *
58
+ * Implementors must provide a `useFileTree` hook that accepts an artifact
59
+ * identifier and returns loading/error/data state conforming to
60
+ * AdapterQueryResult<FileTreeResponse>.
61
+ */
62
+ export interface FileTreeAdapter {
63
+ /**
64
+ * React hook that fetches the file tree for the given artifact.
65
+ *
66
+ * @param artifactId - Opaque identifier for the artifact. The consumer
67
+ * decides how to map this to their API (e.g. sourceId + path tuple,
68
+ * UUID, slug, etc.).
69
+ * @param options - Optional control flags (enabled).
70
+ */
71
+ useFileTree: (artifactId: string, options?: AdapterHookOptions) => AdapterQueryResult<FileTreeResponse>;
72
+ }
73
+ /**
74
+ * Adapter interface for fetching the content of a single file within
75
+ * an artifact.
76
+ *
77
+ * Implementors must provide a `useFileContent` hook that accepts an
78
+ * artifact identifier plus a file path and returns normalized query state.
79
+ */
80
+ export interface FileContentAdapter {
81
+ /**
82
+ * React hook that fetches the content of a specific file.
83
+ *
84
+ * @param artifactId - Opaque identifier for the artifact (same semantics
85
+ * as FileTreeAdapter.useFileTree).
86
+ * @param filePath - Path of the file relative to the artifact root
87
+ * (e.g. "src/index.md").
88
+ * @param options - Optional control flags (enabled).
89
+ */
90
+ useFileContent: (artifactId: string, filePath: string, options?: AdapterHookOptions) => AdapterQueryResult<FileContentResponse>;
91
+ }
92
+ /**
93
+ * Full content-viewer adapter — combines file tree and file content fetching.
94
+ *
95
+ * Pass an object implementing this interface to ContentViewerProvider.
96
+ * All content-viewer components that need data fetching will access it
97
+ * through useContentViewerAdapter().
98
+ */
99
+ export interface ContentViewerAdapter extends FileTreeAdapter, FileContentAdapter {
100
+ }
101
+ //# sourceMappingURL=adapters.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapters.d.ts","sourceRoot":"","sources":["../../src/content-viewer/adapters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAMtE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAMD;;;GAGG;AACH,MAAM,WAAW,kBAAkB,CAAC,KAAK;IACvC,gEAAgE;IAChE,IAAI,EAAE,KAAK,GAAG,SAAS,CAAC;IACxB,iDAAiD;IACjD,SAAS,EAAE,OAAO,CAAC;IACnB,kDAAkD;IAClD,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;;;OAOG;IACH,WAAW,EAAE,CACX,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,kBAAkB,KACzB,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;CAC3C;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,kBAAkB;IACjC;;;;;;;;OAQG;IACH,cAAc,EAAE,CACd,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,MAAM,EAChB,OAAO,CAAC,EAAE,kBAAkB,KACzB,kBAAkB,CAAC,mBAAmB,CAAC,CAAC;CAC9C;AAMD;;;;;;GAMG;AACH,MAAM,WAAW,oBAAqB,SAAQ,eAAe,EAAE,kBAAkB;CAAG"}
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @skillmeat/content-viewer — Adapter Interface Definitions
3
+ *
4
+ * Adapter abstractions allow consumers to inject their own data-fetching
5
+ * hooks without coupling content-viewer components to any specific API layer
6
+ * (SkillMeat backend, REST, GraphQL, static JSON, etc.).
7
+ *
8
+ * Consumers implement these interfaces and pass them to ContentViewerProvider.
9
+ * Components then call useContentViewerAdapter() to access the injected hooks.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * // In your app, create an adapter that wraps your fetching hooks:
14
+ * const myAdapter: ContentViewerAdapter = {
15
+ * useFileTree: (artifactId, options) => {
16
+ * const result = useCatalogFileTree(sourceId, artifactId, options);
17
+ * return { data: result.data, isLoading: result.isLoading, error: result.error };
18
+ * },
19
+ * useFileContent: (artifactId, filePath, options) => {
20
+ * const result = useCatalogFileContent(sourceId, artifactId, filePath, options);
21
+ * return { data: result.data, isLoading: result.isLoading, error: result.error };
22
+ * },
23
+ * };
24
+ *
25
+ * // Wrap your component tree:
26
+ * <ContentViewerProvider adapter={myAdapter}>
27
+ * <FileTree artifactId={id} />
28
+ * </ContentViewerProvider>
29
+ * ```
30
+ */
31
+ export {};
32
+ //# sourceMappingURL=adapters.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapters.js","sourceRoot":"","sources":["../../src/content-viewer/adapters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG"}
@@ -0,0 +1,8 @@
1
+ export { FileTree } from './FileTree';
2
+ export type { FileTreeProps } from './FileTree';
3
+ export { ContentPane } from './ContentPane';
4
+ export type { ContentPaneProps, TruncationInfo } from './ContentPane';
5
+ export { ContentViewerProvider, useContentViewerAdapter, } from './ContentViewerProvider';
6
+ export type { ContentViewerProviderProps } from './ContentViewerProvider';
7
+ export type { AdapterHookOptions, AdapterQueryResult, FileTreeAdapter, FileContentAdapter, ContentViewerAdapter, } from './adapters';
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/content-viewer/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,YAAY,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC;AACjC,YAAY,EAAE,0BAA0B,EAAE,MAAM,yBAAyB,CAAC;AAC1E,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,5 @@
1
+ // @miethe/ui — content-viewer submodule
2
+ export { FileTree } from './FileTree';
3
+ export { ContentPane } from './ContentPane';
4
+ export { ContentViewerProvider, useContentViewerAdapter, } from './ContentViewerProvider';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/content-viewer/index.ts"],"names":[],"mappings":"AAAA,wCAAwC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAEtC,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EACL,qBAAqB,EACrB,uBAAuB,GACxB,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,112 @@
1
+ import { FileDiff } from './diff';
2
+ /**
3
+ * Resolution type for sync conflict resolution
4
+ */
5
+ export type ResolutionType = 'keep_local' | 'keep_remote' | 'merge';
6
+ /**
7
+ * Tier context for enterprise tier comparison diffs.
8
+ *
9
+ * When provided, the diff panel headers display tier badges (e.g. "Tier 1 · Team")
10
+ * instead of the plain leftLabel/rightLabel text. The ownerType string is used to
11
+ * derive a human-readable tier name alongside the numeric tier level.
12
+ */
13
+ export interface TierContext {
14
+ /** Owner type for the left (before) panel — e.g. "user", "team", "enterprise" */
15
+ leftOwnerType: string;
16
+ /** Owner type for the right (after) panel */
17
+ rightOwnerType: string;
18
+ /** Numeric tier level for the left panel (0 = Developer, 1 = Team, 2 = Enterprise, …) */
19
+ leftTier: number;
20
+ /** Numeric tier level for the right panel */
21
+ rightTier: number;
22
+ }
23
+ /**
24
+ * Props for DiffViewer component
25
+ *
26
+ * Configuration for displaying unified diffs with side-by-side view.
27
+ */
28
+ export interface DiffViewerProps {
29
+ /** Array of file diffs to display */
30
+ files: FileDiff[];
31
+ /** Label for left (before) panel */
32
+ leftLabel?: string;
33
+ /** Label for right (after) panel */
34
+ rightLabel?: string;
35
+ /** Callback when user closes the diff viewer */
36
+ onClose?: () => void;
37
+ /** Show resolution action buttons (for sync conflict resolution) */
38
+ showResolutionActions?: boolean;
39
+ /** Callback when user selects a resolution */
40
+ onResolve?: (resolution: ResolutionType) => void;
41
+ /** Custom label for local version button (default: "Local (Project)") */
42
+ localLabel?: string;
43
+ /** Custom label for remote version button (default: "Remote (Collection)") */
44
+ remoteLabel?: string;
45
+ /** Show preview mode UI before applying resolution */
46
+ previewMode?: boolean;
47
+ /** Show loading state during resolution */
48
+ isResolving?: boolean;
49
+ /** Show skeleton loading state while data is being fetched */
50
+ isLoading?: boolean;
51
+ /**
52
+ * Optional tier context for enterprise tier comparison diffs.
53
+ *
54
+ * When provided, the diff panel headers render tier badges instead of the
55
+ * default plain-text leftLabel/rightLabel. Existing label props still apply
56
+ * to other parts of the UI (e.g. "file added in {rightLabel}" messages);
57
+ * only the side-by-side panel column headers change.
58
+ */
59
+ tierContext?: TierContext;
60
+ }
61
+ /**
62
+ * DiffViewerSkeleton - Loading skeleton matching the DiffViewer layout
63
+ *
64
+ * Mimics the side-by-side diff viewer structure:
65
+ * - Summary header bar with skeleton badges
66
+ * - File list sidebar with skeleton entries
67
+ * - Main diff area with side-by-side skeleton code lines
68
+ */
69
+ export declare function DiffViewerSkeleton(): import("react/jsx-runtime").JSX.Element;
70
+ /**
71
+ * DiffViewer - Side-by-side diff viewer with file browser
72
+ *
73
+ * Displays unified diffs in a professional side-by-side format. Features include:
74
+ * - File list sidebar with expandable items showing change statistics
75
+ * - Side-by-side diff panels with independent scrollbars
76
+ * - Color-coded additions (green), deletions (red), and context lines
77
+ * - File status badges (added, modified, deleted, unchanged)
78
+ * - Change summary (total files added, modified, deleted)
79
+ * - Optional sync conflict resolution actions (keep local/remote/merge)
80
+ *
81
+ * @example
82
+ * Basic diff viewer:
83
+ * ```tsx
84
+ * <DiffViewer
85
+ * files={diffData.files}
86
+ * leftLabel="Collection"
87
+ * rightLabel="Project"
88
+ * onClose={() => closeDiff()}
89
+ * />
90
+ * ```
91
+ *
92
+ * @example
93
+ * With sync resolution actions:
94
+ * ```tsx
95
+ * <DiffViewer
96
+ * files={diffData.files}
97
+ * leftLabel="Collection"
98
+ * rightLabel="Project"
99
+ * showResolutionActions={true}
100
+ * onResolve={(resolution) => handleResolve(resolution)}
101
+ * localLabel="Project"
102
+ * remoteLabel="Collection"
103
+ * isResolving={isResolving}
104
+ * previewMode={true}
105
+ * />
106
+ * ```
107
+ *
108
+ * @param props - DiffViewerProps configuration
109
+ * @returns Full-height diff viewer component
110
+ */
111
+ export declare function DiffViewer({ files, leftLabel, rightLabel, onClose, showResolutionActions, onResolve, localLabel, remoteLabel, previewMode, isResolving, isLoading, tierContext, }: DiffViewerProps): import("react/jsx-runtime").JSX.Element;
112
+ //# sourceMappingURL=DiffViewer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DiffViewer.d.ts","sourceRoot":"","sources":["../../src/diff/DiffViewer.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAOlC;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,YAAY,GAAG,aAAa,GAAG,OAAO,CAAC;AAEpE;;;;;;GAMG;AACH,MAAM,WAAW,WAAW;IAC1B,iFAAiF;IACjF,aAAa,EAAE,MAAM,CAAC;IACtB,6CAA6C;IAC7C,cAAc,EAAE,MAAM,CAAC;IACvB,yFAAyF;IACzF,QAAQ,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,SAAS,EAAE,MAAM,CAAC;CACnB;AAqCD;;;;GAIG;AACH,MAAM,WAAW,eAAe;IAC9B,qCAAqC;IACrC,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,oCAAoC;IACpC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,oEAAoE;IACpE,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,8CAA8C;IAC9C,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,cAAc,KAAK,IAAI,CAAC;IACjD,yEAAyE;IACzE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,sDAAsD;IACtD,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,2CAA2C;IAC3C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8DAA8D;IAC9D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAiDD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,4CAyFjC;AAyID;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,SAAoB,EACpB,UAAoB,EACpB,OAAO,EACP,qBAA6B,EAC7B,SAAS,EACT,UAAU,EACV,WAAW,EACX,WAAmB,EACnB,WAAmB,EACnB,SAAiB,EACjB,WAAW,GACZ,EAAE,eAAe,2CAgdjB"}