@moldable-ai/ui 0.2.17 → 0.2.19

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 (232) hide show
  1. package/dist/components/chat/chat-panel.d.ts +18 -12
  2. package/dist/components/chat/chat-panel.d.ts.map +1 -1
  3. package/dist/components/chat/chat-panel.js +73 -19
  4. package/dist/components/chat/index.d.ts +2 -1
  5. package/dist/components/chat/index.d.ts.map +1 -1
  6. package/dist/components/chat/index.js +2 -1
  7. package/dist/components/chat/model-effort-power-effects.d.ts +7 -0
  8. package/dist/components/chat/model-effort-power-effects.d.ts.map +1 -0
  9. package/dist/components/chat/model-effort-power-effects.js +54 -0
  10. package/dist/components/chat/model-effort-selector.d.ts +26 -0
  11. package/dist/components/chat/model-effort-selector.d.ts.map +1 -0
  12. package/dist/components/chat/model-effort-selector.js +179 -0
  13. package/dist/components/chat/model-effort-ultra-effects.d.ts +5 -0
  14. package/dist/components/chat/model-effort-ultra-effects.d.ts.map +1 -0
  15. package/dist/components/chat/model-effort-ultra-effects.js +56 -0
  16. package/dist/components/chat/tool-handlers.d.ts.map +1 -1
  17. package/dist/components/hardware/bluetooth-panel-helpers.d.ts +9 -0
  18. package/dist/components/hardware/bluetooth-panel-helpers.d.ts.map +1 -0
  19. package/dist/components/hardware/bluetooth-panel-helpers.js +37 -0
  20. package/dist/components/hardware/bluetooth-panel.d.ts +56 -0
  21. package/dist/components/hardware/bluetooth-panel.d.ts.map +1 -0
  22. package/dist/components/hardware/bluetooth-panel.js +470 -0
  23. package/dist/components/hardware/camera-preview.d.ts +39 -0
  24. package/dist/components/hardware/camera-preview.d.ts.map +1 -0
  25. package/dist/components/hardware/camera-preview.js +228 -0
  26. package/dist/components/hardware/capability-badge.d.ts +23 -0
  27. package/dist/components/hardware/capability-badge.d.ts.map +1 -0
  28. package/dist/components/hardware/capability-badge.js +39 -0
  29. package/dist/components/hardware/capability-matrix.d.ts +14 -0
  30. package/dist/components/hardware/capability-matrix.d.ts.map +1 -0
  31. package/dist/components/hardware/capability-matrix.js +97 -0
  32. package/dist/components/hardware/clipboard-button.d.ts +26 -0
  33. package/dist/components/hardware/clipboard-button.d.ts.map +1 -0
  34. package/dist/components/hardware/clipboard-button.js +114 -0
  35. package/dist/components/hardware/device-io-controls.d.ts +4 -0
  36. package/dist/components/hardware/device-io-controls.d.ts.map +1 -0
  37. package/dist/components/hardware/device-io-controls.js +28 -0
  38. package/dist/components/hardware/device-list.d.ts +20 -0
  39. package/dist/components/hardware/device-list.d.ts.map +1 -0
  40. package/dist/components/hardware/device-list.js +14 -0
  41. package/dist/components/hardware/display-map.d.ts +23 -0
  42. package/dist/components/hardware/display-map.d.ts.map +1 -0
  43. package/dist/components/hardware/display-map.js +114 -0
  44. package/dist/components/hardware/haptic-button.d.ts +26 -0
  45. package/dist/components/hardware/haptic-button.d.ts.map +1 -0
  46. package/dist/components/hardware/haptic-button.js +94 -0
  47. package/dist/components/hardware/hardware-panel.d.ts +11 -0
  48. package/dist/components/hardware/hardware-panel.d.ts.map +1 -0
  49. package/dist/components/hardware/hardware-panel.js +28 -0
  50. package/dist/components/hardware/hid-panel.d.ts +40 -0
  51. package/dist/components/hardware/hid-panel.d.ts.map +1 -0
  52. package/dist/components/hardware/hid-panel.js +373 -0
  53. package/dist/components/hardware/index.d.ts +27 -0
  54. package/dist/components/hardware/index.d.ts.map +1 -0
  55. package/dist/components/hardware/index.js +26 -0
  56. package/dist/components/hardware/live-indicator.d.ts +15 -0
  57. package/dist/components/hardware/live-indicator.d.ts.map +1 -0
  58. package/dist/components/hardware/live-indicator.js +26 -0
  59. package/dist/components/hardware/local-auth-button.d.ts +33 -0
  60. package/dist/components/hardware/local-auth-button.d.ts.map +1 -0
  61. package/dist/components/hardware/local-auth-button.js +115 -0
  62. package/dist/components/hardware/location-panel.d.ts +29 -0
  63. package/dist/components/hardware/location-panel.d.ts.map +1 -0
  64. package/dist/components/hardware/location-panel.js +154 -0
  65. package/dist/components/hardware/microphone-meter.d.ts +35 -0
  66. package/dist/components/hardware/microphone-meter.d.ts.map +1 -0
  67. package/dist/components/hardware/microphone-meter.js +244 -0
  68. package/dist/components/hardware/midi-monitor.d.ts +54 -0
  69. package/dist/components/hardware/midi-monitor.d.ts.map +1 -0
  70. package/dist/components/hardware/midi-monitor.js +534 -0
  71. package/dist/components/hardware/notification-panel.d.ts +24 -0
  72. package/dist/components/hardware/notification-panel.d.ts.map +1 -0
  73. package/dist/components/hardware/notification-panel.js +124 -0
  74. package/dist/components/hardware/power-blocker-controller.d.ts +19 -0
  75. package/dist/components/hardware/power-blocker-controller.d.ts.map +1 -0
  76. package/dist/components/hardware/power-blocker-controller.js +83 -0
  77. package/dist/components/hardware/power-panel.d.ts +67 -0
  78. package/dist/components/hardware/power-panel.d.ts.map +1 -0
  79. package/dist/components/hardware/power-panel.js +309 -0
  80. package/dist/components/hardware/readout.d.ts +10 -0
  81. package/dist/components/hardware/readout.d.ts.map +1 -0
  82. package/dist/components/hardware/readout.js +11 -0
  83. package/dist/components/hardware/screen-share-preview.d.ts +36 -0
  84. package/dist/components/hardware/screen-share-preview.d.ts.map +1 -0
  85. package/dist/components/hardware/screen-share-preview.js +191 -0
  86. package/dist/components/hardware/secure-storage-panel.d.ts +36 -0
  87. package/dist/components/hardware/secure-storage-panel.d.ts.map +1 -0
  88. package/dist/components/hardware/secure-storage-panel.js +193 -0
  89. package/dist/components/hardware/serial-console.d.ts +64 -0
  90. package/dist/components/hardware/serial-console.d.ts.map +1 -0
  91. package/dist/components/hardware/serial-console.js +399 -0
  92. package/dist/components/hardware/shortcut-recorder.d.ts +35 -0
  93. package/dist/components/hardware/shortcut-recorder.d.ts.map +1 -0
  94. package/dist/components/hardware/shortcut-recorder.js +217 -0
  95. package/dist/components/hardware/stream-log.d.ts +35 -0
  96. package/dist/components/hardware/stream-log.d.ts.map +1 -0
  97. package/dist/components/hardware/stream-log.js +65 -0
  98. package/dist/components/hardware/system-audio-monitor.d.ts +34 -0
  99. package/dist/components/hardware/system-audio-monitor.d.ts.map +1 -0
  100. package/dist/components/hardware/system-audio-monitor.js +275 -0
  101. package/dist/components/hardware/usb-panel.d.ts +54 -0
  102. package/dist/components/hardware/usb-panel.d.ts.map +1 -0
  103. package/dist/components/hardware/usb-panel.js +363 -0
  104. package/dist/components/hardware/use-capability.d.ts +20 -0
  105. package/dist/components/hardware/use-capability.d.ts.map +1 -0
  106. package/dist/components/hardware/use-capability.js +61 -0
  107. package/dist/components/ui/input-group.d.ts +1 -1
  108. package/dist/components/ui/slider.d.ts +4 -1
  109. package/dist/components/ui/slider.d.ts.map +1 -1
  110. package/dist/components/ui/slider.js +2 -2
  111. package/dist/index.d.ts +3 -1
  112. package/dist/index.d.ts.map +1 -1
  113. package/dist/index.js +5 -1
  114. package/dist/lib/commands.d.ts +59 -0
  115. package/dist/lib/commands.d.ts.map +1 -1
  116. package/dist/lib/commands.js +97 -0
  117. package/dist/lib/native-hardware/bluetooth-access.d.ts +14 -0
  118. package/dist/lib/native-hardware/bluetooth-access.d.ts.map +1 -0
  119. package/dist/lib/native-hardware/bluetooth-access.js +40 -0
  120. package/dist/lib/native-hardware/bluetooth-connection.d.ts +19 -0
  121. package/dist/lib/native-hardware/bluetooth-connection.d.ts.map +1 -0
  122. package/dist/lib/native-hardware/bluetooth-connection.js +88 -0
  123. package/dist/lib/native-hardware/bluetooth-gatt.d.ts +7 -0
  124. package/dist/lib/native-hardware/bluetooth-gatt.d.ts.map +1 -0
  125. package/dist/lib/native-hardware/bluetooth-gatt.js +77 -0
  126. package/dist/lib/native-hardware/bluetooth-internal.d.ts +10 -0
  127. package/dist/lib/native-hardware/bluetooth-internal.d.ts.map +1 -0
  128. package/dist/lib/native-hardware/bluetooth-internal.js +105 -0
  129. package/dist/lib/native-hardware/bluetooth-native-fallback.d.ts +33 -0
  130. package/dist/lib/native-hardware/bluetooth-native-fallback.d.ts.map +1 -0
  131. package/dist/lib/native-hardware/bluetooth-native-fallback.js +214 -0
  132. package/dist/lib/native-hardware/bluetooth-types.d.ts +85 -0
  133. package/dist/lib/native-hardware/bluetooth-types.d.ts.map +1 -0
  134. package/dist/lib/native-hardware/bluetooth-types.js +2 -0
  135. package/dist/lib/native-hardware/bluetooth.d.ts +7 -0
  136. package/dist/lib/native-hardware/bluetooth.d.ts.map +1 -0
  137. package/dist/lib/native-hardware/bluetooth.js +4 -0
  138. package/dist/lib/native-hardware/bridge.d.ts +23 -0
  139. package/dist/lib/native-hardware/bridge.d.ts.map +1 -0
  140. package/dist/lib/native-hardware/bridge.js +266 -0
  141. package/dist/lib/native-hardware/capabilities.d.ts +7 -0
  142. package/dist/lib/native-hardware/capabilities.d.ts.map +1 -0
  143. package/dist/lib/native-hardware/capabilities.js +95 -0
  144. package/dist/lib/native-hardware/clipboard.d.ts +11 -0
  145. package/dist/lib/native-hardware/clipboard.d.ts.map +1 -0
  146. package/dist/lib/native-hardware/clipboard.js +55 -0
  147. package/dist/lib/native-hardware/device-io-errors.d.ts +11 -0
  148. package/dist/lib/native-hardware/device-io-errors.d.ts.map +1 -0
  149. package/dist/lib/native-hardware/device-io-errors.js +82 -0
  150. package/dist/lib/native-hardware/displays.d.ts +38 -0
  151. package/dist/lib/native-hardware/displays.d.ts.map +1 -0
  152. package/dist/lib/native-hardware/displays.js +12 -0
  153. package/dist/lib/native-hardware/global-shortcuts.d.ts +86 -0
  154. package/dist/lib/native-hardware/global-shortcuts.d.ts.map +1 -0
  155. package/dist/lib/native-hardware/global-shortcuts.js +351 -0
  156. package/dist/lib/native-hardware/haptics.d.ts +25 -0
  157. package/dist/lib/native-hardware/haptics.d.ts.map +1 -0
  158. package/dist/lib/native-hardware/haptics.js +18 -0
  159. package/dist/lib/native-hardware/hid-native.d.ts +26 -0
  160. package/dist/lib/native-hardware/hid-native.d.ts.map +1 -0
  161. package/dist/lib/native-hardware/hid-native.js +229 -0
  162. package/dist/lib/native-hardware/hid.d.ts +52 -0
  163. package/dist/lib/native-hardware/hid.d.ts.map +1 -0
  164. package/dist/lib/native-hardware/hid.js +160 -0
  165. package/dist/lib/native-hardware/index.d.ts +38 -0
  166. package/dist/lib/native-hardware/index.d.ts.map +1 -0
  167. package/dist/lib/native-hardware/index.js +20 -0
  168. package/dist/lib/native-hardware/local-authentication.d.ts +32 -0
  169. package/dist/lib/native-hardware/local-authentication.d.ts.map +1 -0
  170. package/dist/lib/native-hardware/local-authentication.js +46 -0
  171. package/dist/lib/native-hardware/location.d.ts +49 -0
  172. package/dist/lib/native-hardware/location.d.ts.map +1 -0
  173. package/dist/lib/native-hardware/location.js +114 -0
  174. package/dist/lib/native-hardware/media-permissions.d.ts +28 -0
  175. package/dist/lib/native-hardware/media-permissions.d.ts.map +1 -0
  176. package/dist/lib/native-hardware/media-permissions.js +37 -0
  177. package/dist/lib/native-hardware/media.d.ts +17 -0
  178. package/dist/lib/native-hardware/media.d.ts.map +1 -0
  179. package/dist/lib/native-hardware/media.js +99 -0
  180. package/dist/lib/native-hardware/midi-access.d.ts +13 -0
  181. package/dist/lib/native-hardware/midi-access.d.ts.map +1 -0
  182. package/dist/lib/native-hardware/midi-access.js +66 -0
  183. package/dist/lib/native-hardware/midi-internal.d.ts +12 -0
  184. package/dist/lib/native-hardware/midi-internal.d.ts.map +1 -0
  185. package/dist/lib/native-hardware/midi-internal.js +88 -0
  186. package/dist/lib/native-hardware/midi-native-fallback.d.ts +27 -0
  187. package/dist/lib/native-hardware/midi-native-fallback.d.ts.map +1 -0
  188. package/dist/lib/native-hardware/midi-native-fallback.js +127 -0
  189. package/dist/lib/native-hardware/midi-ports.d.ts +6 -0
  190. package/dist/lib/native-hardware/midi-ports.d.ts.map +1 -0
  191. package/dist/lib/native-hardware/midi-ports.js +115 -0
  192. package/dist/lib/native-hardware/midi-types.d.ts +25 -0
  193. package/dist/lib/native-hardware/midi-types.d.ts.map +1 -0
  194. package/dist/lib/native-hardware/midi-types.js +1 -0
  195. package/dist/lib/native-hardware/midi.d.ts +6 -0
  196. package/dist/lib/native-hardware/midi.d.ts.map +1 -0
  197. package/dist/lib/native-hardware/midi.js +3 -0
  198. package/dist/lib/native-hardware/native-device-io.d.ts +28 -0
  199. package/dist/lib/native-hardware/native-device-io.d.ts.map +1 -0
  200. package/dist/lib/native-hardware/native-device-io.js +91 -0
  201. package/dist/lib/native-hardware/native-device-lifecycle.d.ts +13 -0
  202. package/dist/lib/native-hardware/native-device-lifecycle.d.ts.map +1 -0
  203. package/dist/lib/native-hardware/native-device-lifecycle.js +40 -0
  204. package/dist/lib/native-hardware/notifications.d.ts +38 -0
  205. package/dist/lib/native-hardware/notifications.d.ts.map +1 -0
  206. package/dist/lib/native-hardware/notifications.js +50 -0
  207. package/dist/lib/native-hardware/power-session.d.ts +113 -0
  208. package/dist/lib/native-hardware/power-session.d.ts.map +1 -0
  209. package/dist/lib/native-hardware/power-session.js +264 -0
  210. package/dist/lib/native-hardware/secure-storage.d.ts +36 -0
  211. package/dist/lib/native-hardware/secure-storage.d.ts.map +1 -0
  212. package/dist/lib/native-hardware/secure-storage.js +64 -0
  213. package/dist/lib/native-hardware/serial-native.d.ts +23 -0
  214. package/dist/lib/native-hardware/serial-native.d.ts.map +1 -0
  215. package/dist/lib/native-hardware/serial-native.js +181 -0
  216. package/dist/lib/native-hardware/serial.d.ts +76 -0
  217. package/dist/lib/native-hardware/serial.d.ts.map +1 -0
  218. package/dist/lib/native-hardware/serial.js +212 -0
  219. package/dist/lib/native-hardware/system-audio.d.ts +127 -0
  220. package/dist/lib/native-hardware/system-audio.d.ts.map +1 -0
  221. package/dist/lib/native-hardware/system-audio.js +330 -0
  222. package/dist/lib/native-hardware/types.d.ts +62 -0
  223. package/dist/lib/native-hardware/types.d.ts.map +1 -0
  224. package/dist/lib/native-hardware/types.js +27 -0
  225. package/dist/lib/native-hardware/usb-native.d.ts +39 -0
  226. package/dist/lib/native-hardware/usb-native.d.ts.map +1 -0
  227. package/dist/lib/native-hardware/usb-native.js +217 -0
  228. package/dist/lib/native-hardware/usb.d.ts +85 -0
  229. package/dist/lib/native-hardware/usb.d.ts.map +1 -0
  230. package/dist/lib/native-hardware/usb.js +222 -0
  231. package/package.json +1 -1
  232. package/src/styles/index.css +377 -0
@@ -0,0 +1,35 @@
1
+ import * as React from 'react';
2
+ export type StreamLogDirection = 'in' | 'out' | 'info' | 'error';
3
+ export interface StreamLogEntry {
4
+ id: string | number;
5
+ /** Epoch millis. Defaults to now when appended via `useStreamLog`. */
6
+ timestamp?: number;
7
+ direction?: StreamLogDirection;
8
+ /** Chip text override (defaults per direction: RX / TX / · / ERR). */
9
+ label?: string;
10
+ data: React.ReactNode;
11
+ }
12
+ /** Rolling entry buffer for `StreamLog`, capped at `maxEntries`. */
13
+ export declare function useStreamLog(maxEntries?: number): {
14
+ entries: StreamLogEntry[];
15
+ append: (entry: Omit<StreamLogEntry, "id"> & {
16
+ id?: string | number;
17
+ }) => void;
18
+ clear: () => void;
19
+ };
20
+ declare function formatStreamLogTime(timestamp: number): string;
21
+ export interface StreamLogProps extends React.ComponentProps<'div'> {
22
+ entries: StreamLogEntry[];
23
+ /** Pixel height of the scroll well. Defaults to 240. */
24
+ maxHeight?: number;
25
+ emptyLabel?: React.ReactNode;
26
+ /** Hide the per-row timestamp column. */
27
+ hideTimestamps?: boolean;
28
+ }
29
+ /**
30
+ * Auto-following mono event log for streams (serial, HID, MIDI, BLE, power
31
+ * events). Stays pinned to the newest entry unless the user scrolls up.
32
+ */
33
+ declare function StreamLog({ entries, maxHeight, emptyLabel, hideTimestamps, className, ...props }: StreamLogProps): import("react/jsx-runtime").JSX.Element;
34
+ export { StreamLog, formatStreamLogTime };
35
+ //# sourceMappingURL=stream-log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-log.d.ts","sourceRoot":"","sources":["../../../src/components/hardware/stream-log.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAI9B,MAAM,MAAM,kBAAkB,GAAG,IAAI,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAA;AAEhE,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,GAAG,MAAM,CAAA;IACnB,sEAAsE;IACtE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,kBAAkB,CAAA;IAC9B,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,KAAK,CAAC,SAAS,CAAA;CACtB;AAED,oEAAoE;AACpE,wBAAgB,YAAY,CAAC,UAAU,SAAM;;oBAKjC,IAAI,CAAC,cAAc,EAAE,IAAI,CAAC,GAAG;QAAE,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE;;EAqBhE;AAgBD,iBAAS,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAKtD;AAED,MAAM,WAAW,cAAe,SAAQ,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;IACjE,OAAO,EAAE,cAAc,EAAE,CAAA;IACzB,wDAAwD;IACxD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC5B,yCAAyC;IACzC,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED;;;GAGG;AACH,iBAAS,SAAS,CAAC,EACjB,OAAO,EACP,SAAe,EACf,UAA+B,EAC/B,cAAsB,EACtB,SAAS,EACT,GAAG,KAAK,EACT,EAAE,cAAc,2CA6DhB;AAED,OAAO,EAAE,SAAS,EAAE,mBAAmB,EAAE,CAAA"}
@@ -0,0 +1,65 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useCallback, useEffect, useRef, useState } from 'react';
4
+ import { cn } from '../../lib/utils';
5
+ /** Rolling entry buffer for `StreamLog`, capped at `maxEntries`. */
6
+ export function useStreamLog(maxEntries = 500) {
7
+ const [entries, setEntries] = useState([]);
8
+ const counter = useRef(0);
9
+ const append = useCallback((entry) => {
10
+ setEntries((previous) => {
11
+ const next = [
12
+ ...previous,
13
+ {
14
+ ...entry,
15
+ id: entry.id ?? ++counter.current,
16
+ timestamp: entry.timestamp ?? Date.now(),
17
+ },
18
+ ];
19
+ return next.length > maxEntries
20
+ ? next.slice(next.length - maxEntries)
21
+ : next;
22
+ });
23
+ }, [maxEntries]);
24
+ const clear = useCallback(() => setEntries([]), []);
25
+ return { entries, append, clear };
26
+ }
27
+ const DIRECTION_LABEL = {
28
+ in: 'RX',
29
+ out: 'TX',
30
+ info: '·',
31
+ error: 'ERR',
32
+ };
33
+ const DIRECTION_CLASS = {
34
+ in: 'text-success border-success/40',
35
+ out: 'text-foreground border-border',
36
+ info: 'text-muted-foreground border-transparent',
37
+ error: 'text-status-error border-status-error/40',
38
+ };
39
+ function formatStreamLogTime(timestamp) {
40
+ const date = new Date(timestamp);
41
+ const pad = (value, length = 2) => value.toString().padStart(length, '0');
42
+ return `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}.${pad(date.getMilliseconds(), 3)}`;
43
+ }
44
+ /**
45
+ * Auto-following mono event log for streams (serial, HID, MIDI, BLE, power
46
+ * events). Stays pinned to the newest entry unless the user scrolls up.
47
+ */
48
+ function StreamLog({ entries, maxHeight = 240, emptyLabel = 'Waiting for data', hideTimestamps = false, className, ...props }) {
49
+ const scrollRef = useRef(null);
50
+ const pinnedRef = useRef(true);
51
+ useEffect(() => {
52
+ const element = scrollRef.current;
53
+ if (element && pinnedRef.current)
54
+ element.scrollTop = element.scrollHeight;
55
+ }, [entries]);
56
+ return (_jsx("div", { "data-slot": "stream-log", ref: scrollRef, onScroll: (event) => {
57
+ const element = event.currentTarget;
58
+ pinnedRef.current =
59
+ element.scrollHeight - element.scrollTop - element.clientHeight < 32;
60
+ }, className: cn('bg-muted/30 overflow-y-auto rounded-lg border font-mono text-xs', className), style: { maxHeight, ...props.style }, ...props, children: entries.length === 0 ? (_jsx("div", { className: "text-muted-foreground/70 flex items-center justify-center px-4 py-10", children: emptyLabel })) : (entries.map((entry) => {
61
+ const direction = entry.direction ?? 'info';
62
+ return (_jsxs("div", { "data-slot": "stream-log-entry", "data-direction": direction, className: "animate-in fade-in border-border/40 flex items-baseline gap-2 border-b px-3 py-1.5 duration-200 last:border-0 motion-reduce:animate-none", children: [!hideTimestamps && entry.timestamp !== undefined ? (_jsx("span", { className: "text-muted-foreground/70 shrink-0 text-[10px] tabular-nums", children: formatStreamLogTime(entry.timestamp) })) : null, _jsx("span", { className: cn('w-8 shrink-0 rounded border text-center text-[9px] font-semibold uppercase leading-4 tracking-wide', DIRECTION_CLASS[direction]), children: entry.label ?? DIRECTION_LABEL[direction] }), _jsx("span", { className: "min-w-0 flex-1 whitespace-pre-wrap break-all", children: entry.data })] }, entry.id));
63
+ })) }));
64
+ }
65
+ export { StreamLog, formatStreamLogTime };
@@ -0,0 +1,34 @@
1
+ import * as React from 'react';
2
+ import { type MoldableSystemAudioCaptureMode, type MoldableSystemAudioEvent } from '../../lib/native-hardware';
3
+ export type MoldableSystemAudioMonitorStatus = 'idle' | 'starting' | 'stopping' | 'capturing' | 'error';
4
+ export interface UseMoldableSystemAudioOptions {
5
+ /** Observe raw capture events (lifecycle plus PCM data frames). */
6
+ onEvent?: (event: MoldableSystemAudioEvent) => void;
7
+ }
8
+ /**
9
+ * System-audio capture state machine behind `SystemAudioMonitor`. macOS PCM
10
+ * capture (Int16 LE frames over the native bridge), not a `MediaStream` — the
11
+ * level is a running RMS computed from incoming frames.
12
+ */
13
+ export declare function useMoldableSystemAudio(options?: UseMoldableSystemAudioOptions): {
14
+ status: MoldableSystemAudioMonitorStatus;
15
+ level: number;
16
+ mode: MoldableSystemAudioCaptureMode | null;
17
+ framesReceived: number;
18
+ error: Error | null;
19
+ active: boolean;
20
+ start: (nextMode: MoldableSystemAudioCaptureMode) => Promise<void>;
21
+ stop: () => Promise<void>;
22
+ };
23
+ export interface SystemAudioMonitorProps extends React.ComponentProps<'div'> {
24
+ /** Capture mode preselected in the header. */
25
+ defaultMode?: MoldableSystemAudioCaptureMode;
26
+ }
27
+ /**
28
+ * System-audio panel: capture-mode picker, RMS level meter with peak hold,
29
+ * and a lifecycle event log. macOS-only; other platforms get the standard
30
+ * unsupported state.
31
+ */
32
+ declare function SystemAudioMonitor({ className, defaultMode, ...props }: SystemAudioMonitorProps): import("react/jsx-runtime").JSX.Element;
33
+ export { SystemAudioMonitor };
34
+ //# sourceMappingURL=system-audio-monitor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"system-audio-monitor.d.ts","sourceRoot":"","sources":["../../../src/components/hardware/system-audio-monitor.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EACL,KAAK,8BAA8B,EACnC,KAAK,wBAAwB,EAI9B,MAAM,2BAA2B,CAAA;AAwBlC,MAAM,MAAM,gCAAgC,GACxC,MAAM,GACN,UAAU,GACV,UAAU,GACV,WAAW,GACX,OAAO,CAAA;AAKX,MAAM,WAAW,6BAA6B;IAC5C,mEAAmE;IACnE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,IAAI,CAAA;CACpD;AAcD;;;;GAIG;AACH,wBAAgB,sBAAsB,CACpC,OAAO,GAAE,6BAAkC;;;;;;;sBA2DxB,8BAA8B;;EA2GlD;AAOD,MAAM,WAAW,uBAAwB,SAAQ,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;IAC1E,8CAA8C;IAC9C,WAAW,CAAC,EAAE,8BAA8B,CAAA;CAC7C;AAED;;;;GAIG;AACH,iBAAS,kBAAkB,CAAC,EAC1B,SAAS,EACT,WAA2B,EAC3B,GAAG,KAAK,EACT,EAAE,uBAAuB,2CAgMzB;AAED,OAAO,EAAE,kBAAkB,EAAE,CAAA"}
@@ -0,0 +1,275 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { Play, Square, Volume2, VolumeX } from 'lucide-react';
4
+ import { useCallback, useEffect, useRef, useState } from 'react';
5
+ import { startMoldableSystemAudioCapture, stopMoldableSystemAudioCapture, subscribeMoldableSystemAudioEvents, } from '../../lib/native-hardware';
6
+ import { Button } from '../ui/button';
7
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '../ui/select';
8
+ import { Spinner } from '../ui/spinner';
9
+ import { CapabilityBadge } from './capability-badge';
10
+ import { HardwarePanel, HardwarePanelAction, HardwarePanelContent, HardwarePanelFooter, HardwarePanelHeader, HardwarePanelIcon, HardwarePanelTitle, } from './hardware-panel';
11
+ import { LiveIndicator } from './live-indicator';
12
+ import { StreamLog, useStreamLog } from './stream-log';
13
+ import { useMoldableCapability } from './use-capability';
14
+ const SYSTEM_AUDIO_SAMPLE_RATE = 48_000;
15
+ const FRAME_LOG_INTERVAL = 50;
16
+ function computeRmsLevel(buffer) {
17
+ const sampleCount = Math.floor(buffer.byteLength / 2);
18
+ if (sampleCount === 0)
19
+ return 0;
20
+ const samples = new Int16Array(buffer, 0, sampleCount);
21
+ let sum = 0;
22
+ for (let index = 0; index < samples.length; index++) {
23
+ const sample = samples[index] ?? 0;
24
+ sum += sample * sample;
25
+ }
26
+ return Math.min(1, Math.sqrt(sum / sampleCount) / 32_768);
27
+ }
28
+ /**
29
+ * System-audio capture state machine behind `SystemAudioMonitor`. macOS PCM
30
+ * capture (Int16 LE frames over the native bridge), not a `MediaStream` — the
31
+ * level is a running RMS computed from incoming frames.
32
+ */
33
+ export function useMoldableSystemAudio(options = {}) {
34
+ const [status, setStatus] = useState('idle');
35
+ const [level, setLevel] = useState(0);
36
+ const [mode, setMode] = useState(null);
37
+ const [framesReceived, setFramesReceived] = useState(0);
38
+ const [error, setError] = useState(null);
39
+ const [active, setActive] = useState(false);
40
+ const tokenRef = useRef(0);
41
+ const controllerRef = useRef(null);
42
+ const sessionActiveRef = useRef(false);
43
+ const levelRef = useRef(0);
44
+ const framesRef = useRef(0);
45
+ const onEventRef = useRef(options.onEvent);
46
+ useEffect(() => {
47
+ onEventRef.current = options.onEvent;
48
+ }, [options.onEvent]);
49
+ const releaseSession = useCallback((controller) => {
50
+ if (controller && controllerRef.current !== controller)
51
+ return;
52
+ controllerRef.current?.abort();
53
+ controllerRef.current = null;
54
+ sessionActiveRef.current = false;
55
+ setActive(false);
56
+ levelRef.current = 0;
57
+ setLevel(0);
58
+ }, []);
59
+ const closeActiveSession = useCallback(async () => {
60
+ if (!sessionActiveRef.current) {
61
+ releaseSession();
62
+ return;
63
+ }
64
+ const stopped = await stopMoldableSystemAudioCapture();
65
+ if (!stopped && sessionActiveRef.current) {
66
+ throw new Error('System audio capture did not stop.');
67
+ }
68
+ releaseSession();
69
+ }, [releaseSession]);
70
+ const stop = useCallback(async () => {
71
+ const token = ++tokenRef.current;
72
+ setStatus('stopping');
73
+ setError(null);
74
+ try {
75
+ await closeActiveSession();
76
+ if (tokenRef.current !== token)
77
+ return;
78
+ setStatus('idle');
79
+ }
80
+ catch (cause) {
81
+ if (tokenRef.current !== token)
82
+ return;
83
+ setError(cause instanceof Error ? cause : new Error(String(cause)));
84
+ // Keep the session and subscription intact so Stop can be retried.
85
+ setStatus('error');
86
+ }
87
+ }, [closeActiveSession]);
88
+ const start = useCallback(async (nextMode) => {
89
+ const token = ++tokenRef.current;
90
+ setError(null);
91
+ if (sessionActiveRef.current) {
92
+ setStatus('stopping');
93
+ try {
94
+ await closeActiveSession();
95
+ }
96
+ catch (cause) {
97
+ if (tokenRef.current !== token)
98
+ return;
99
+ setError(cause instanceof Error ? cause : new Error(String(cause)));
100
+ setStatus('error');
101
+ return;
102
+ }
103
+ }
104
+ if (tokenRef.current !== token)
105
+ return;
106
+ setStatus('starting');
107
+ setMode(nextMode);
108
+ setLevel(0);
109
+ setFramesReceived(0);
110
+ framesRef.current = 0;
111
+ const controller = new AbortController();
112
+ controllerRef.current = controller;
113
+ let endedBeforeStartSettled = false;
114
+ const drop = () => {
115
+ endedBeforeStartSettled = true;
116
+ releaseSession(controller);
117
+ };
118
+ try {
119
+ // Subscribe before starting so the first lifecycle event is
120
+ // observable, per the native-hardware contract.
121
+ subscribeMoldableSystemAudioEvents((event) => {
122
+ if (controllerRef.current !== controller)
123
+ return;
124
+ onEventRef.current?.(event);
125
+ if (event.kind === 'data') {
126
+ framesRef.current++;
127
+ setFramesReceived(framesRef.current);
128
+ const rms = computeRmsLevel(event.data);
129
+ const smoothed = rms >= levelRef.current
130
+ ? rms
131
+ : levelRef.current * 0.7 + rms * 0.3;
132
+ levelRef.current = smoothed;
133
+ setLevel(smoothed);
134
+ }
135
+ else if (event.kind === 'started') {
136
+ sessionActiveRef.current = true;
137
+ setActive(true);
138
+ setStatus('capturing');
139
+ }
140
+ else if (event.kind === 'stopped') {
141
+ drop();
142
+ setStatus('idle');
143
+ }
144
+ else {
145
+ setError(new Error(event.message ?? 'System audio capture failed.'));
146
+ if (!event.recoverable) {
147
+ setStatus('error');
148
+ }
149
+ }
150
+ }, { signal: controller.signal });
151
+ await startMoldableSystemAudioCapture({
152
+ captureMode: nextMode,
153
+ sampleRate: SYSTEM_AUDIO_SAMPLE_RATE,
154
+ channels: 1,
155
+ signal: controller.signal,
156
+ });
157
+ if (tokenRef.current !== token) {
158
+ if (!endedBeforeStartSettled) {
159
+ void stopMoldableSystemAudioCapture().catch(() => {
160
+ // A superseded pending start can only be closed best-effort.
161
+ });
162
+ }
163
+ return;
164
+ }
165
+ if (endedBeforeStartSettled)
166
+ return;
167
+ sessionActiveRef.current = true;
168
+ setActive(true);
169
+ setStatus('capturing');
170
+ }
171
+ catch (cause) {
172
+ releaseSession(controller);
173
+ if (tokenRef.current !== token)
174
+ return;
175
+ setError(cause instanceof Error ? cause : new Error(String(cause)));
176
+ setStatus('error');
177
+ }
178
+ }, [closeActiveSession, releaseSession]);
179
+ useEffect(() => () => {
180
+ tokenRef.current++;
181
+ const wasActive = sessionActiveRef.current;
182
+ controllerRef.current?.abort();
183
+ controllerRef.current = null;
184
+ sessionActiveRef.current = false;
185
+ if (wasActive) {
186
+ void stopMoldableSystemAudioCapture().catch(() => {
187
+ // Unmount has no remaining UI in which to retry a failed stop.
188
+ });
189
+ }
190
+ }, []);
191
+ return { status, level, mode, framesReceived, error, active, start, stop };
192
+ }
193
+ const MODE_LABEL = {
194
+ systemAudio: 'System audio',
195
+ systemMicrophone: 'System + mic',
196
+ };
197
+ /**
198
+ * System-audio panel: capture-mode picker, RMS level meter with peak hold,
199
+ * and a lifecycle event log. macOS-only; other platforms get the standard
200
+ * unsupported state.
201
+ */
202
+ function SystemAudioMonitor({ className, defaultMode = 'systemAudio', ...props }) {
203
+ const log = useStreamLog(200);
204
+ const { append } = log;
205
+ const frameLogRef = useRef(0);
206
+ const handleEvent = useCallback((event) => {
207
+ if (event.kind === 'started') {
208
+ append({
209
+ direction: 'info',
210
+ data: event.sessionId
211
+ ? `Capture started · session ${event.sessionId}`
212
+ : 'Capture started',
213
+ });
214
+ }
215
+ else if (event.kind === 'stopped') {
216
+ append({
217
+ direction: 'info',
218
+ data: event.reason
219
+ ? `Capture stopped · ${event.reason}`
220
+ : 'Capture stopped',
221
+ });
222
+ }
223
+ else if (event.kind === 'data') {
224
+ // Frames arrive continuously; log a summary line instead of each one.
225
+ frameLogRef.current++;
226
+ if (frameLogRef.current % FRAME_LOG_INTERVAL === 0) {
227
+ append({
228
+ direction: 'in',
229
+ data: `${frameLogRef.current.toLocaleString()} frames · ${(event.sampleRate ?? SYSTEM_AUDIO_SAMPLE_RATE).toLocaleString()} Hz · ${event.channels ?? 1} ch`,
230
+ });
231
+ }
232
+ }
233
+ }, [append]);
234
+ const audio = useMoldableSystemAudio({ onEvent: handleEvent });
235
+ const capability = useMoldableCapability('system-audio');
236
+ const [selectedMode, setSelectedMode] = useState(defaultMode);
237
+ const [peak, setPeak] = useState(0);
238
+ const { error } = audio;
239
+ useEffect(() => {
240
+ if (error)
241
+ append({ direction: 'error', data: error.message });
242
+ }, [error, append]);
243
+ const capturing = audio.active;
244
+ const starting = audio.status === 'starting';
245
+ const stopping = audio.status === 'stopping';
246
+ const { level } = audio;
247
+ useEffect(() => {
248
+ if (!capturing) {
249
+ setPeak(0);
250
+ return;
251
+ }
252
+ setPeak((previous) => level >= previous ? level : Math.max(level, previous - 0.008));
253
+ }, [capturing, level]);
254
+ const unsupported = capability.status === 'unsupported' || capability.status === 'unavailable';
255
+ return (_jsxs(HardwarePanel, { "data-slot": "system-audio-monitor", "data-status": audio.status, className: className, ...props, children: [_jsxs(HardwarePanelHeader, { children: [_jsx(HardwarePanelIcon, { children: _jsx(Volume2, {}) }), _jsx(HardwarePanelTitle, { children: "System Audio" }), _jsx(CapabilityBadge, { capability: "system-audio" }), !unsupported ? (_jsxs(HardwarePanelAction, { children: [_jsxs(Select, { value: selectedMode, onValueChange: (value) => setSelectedMode(value === 'systemMicrophone'
256
+ ? 'systemMicrophone'
257
+ : 'systemAudio'), disabled: starting || stopping || capturing, children: [_jsx(SelectTrigger, { size: "sm", className: "text-xs", children: _jsx(SelectValue, {}) }), _jsxs(SelectContent, { children: [_jsx(SelectItem, { value: "systemAudio", children: MODE_LABEL.systemAudio }), _jsx(SelectItem, { value: "systemMicrophone", children: MODE_LABEL.systemMicrophone })] })] }), _jsxs(Button, { size: "sm", variant: capturing ? 'outline' : 'default', disabled: starting || stopping, onClick: () => {
258
+ if (capturing) {
259
+ void audio.stop();
260
+ }
261
+ else {
262
+ frameLogRef.current = 0;
263
+ void audio.start(selectedMode);
264
+ }
265
+ }, children: [starting || stopping ? (_jsx(Spinner, {})) : capturing ? (_jsx(Square, { className: "fill-current" })) : (_jsx(Play, { className: "fill-current" })), starting
266
+ ? 'Starting…'
267
+ : stopping
268
+ ? 'Stopping…'
269
+ : capturing
270
+ ? 'Stop'
271
+ : 'Start'] })] })) : null] }), _jsx(HardwarePanelContent, { className: "space-y-3", children: unsupported ? (_jsxs("div", { className: "animate-in fade-in flex flex-col items-center gap-3 py-6 text-center duration-300 motion-reduce:animate-none", children: [_jsx("div", { className: "text-muted-foreground bg-background shadow-xs flex size-10 items-center justify-center rounded-lg border [&_svg]:size-5", children: _jsx(VolumeX, {}) }), _jsx("p", { className: "text-sm font-medium", children: "System audio unavailable" }), _jsx("p", { className: "text-muted-foreground max-w-64 text-xs", children: capability.status === 'unavailable'
272
+ ? 'System audio capture is only available inside Moldable.'
273
+ : 'System audio capture requires Moldable on macOS.' })] })) : (_jsxs(_Fragment, { children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsxs("div", { className: "bg-muted relative h-2 flex-1 overflow-hidden rounded-full", children: [_jsx("div", { className: "bg-primary absolute inset-y-0 left-0 rounded-full transition-[width] duration-100 ease-out motion-reduce:transition-none", style: { width: `${Math.min(1, level) * 100}%` } }), peak > 0 ? (_jsx("div", { className: "bg-primary/70 absolute inset-y-0 w-0.5 rounded-full transition-[left] duration-150 ease-out motion-reduce:transition-none", style: { left: `calc(${Math.min(1, peak) * 100}% - 2px)` } })) : null] }), capturing ? _jsx(LiveIndicator, { label: "Capturing" }) : null] }), audio.status === 'error' ? (_jsx("p", { className: "text-status-error text-xs", children: audio.error?.message ?? 'System audio capture failed.' })) : null, _jsx(StreamLog, { entries: log.entries, maxHeight: 180, emptyLabel: "No capture events yet" })] })) }), _jsxs(HardwarePanelFooter, { children: [_jsx("span", { className: "truncate", children: audio.mode ? MODE_LABEL[audio.mode] : 'No capture yet' }), _jsxs("span", { className: "ml-auto shrink-0 font-mono tabular-nums", children: [SYSTEM_AUDIO_SAMPLE_RATE.toLocaleString(), " Hz"] }), _jsxs("span", { className: "shrink-0 font-mono tabular-nums", children: [audio.framesReceived.toLocaleString(), " frames"] })] })] }));
274
+ }
275
+ export { SystemAudioMonitor };
@@ -0,0 +1,54 @@
1
+ import * as React from 'react';
2
+ import { type MoldableUsbControlTransferParameters, type MoldableUsbDevice, type MoldableUsbDeviceFilter, type MoldableUsbOpenOptions, type MoldableUsbRequestOptions } from '../../lib/native-hardware';
3
+ export type MoldableUsbStatus = 'idle' | 'loading' | 'requesting' | 'error';
4
+ export interface UseMoldableUsbOptions {
5
+ /** Device filters used when `request` does not override them. */
6
+ filters?: readonly MoldableUsbDeviceFilter[];
7
+ /** Overrides the built-in explicit picker for multiple native matches. */
8
+ selectNativeDevice?: MoldableUsbRequestOptions['selectNativeDevice'];
9
+ /** Configuration and interfaces to claim when opening a device. */
10
+ openOptions?: MoldableUsbOpenOptions;
11
+ onDeviceOpen?: (device: MoldableUsbDevice) => void;
12
+ }
13
+ /**
14
+ * USB state machine behind `UsbDevicePanel`: granted-device enumeration,
15
+ * chooser requests, minimal-claim open/close tracking. Use directly to build
16
+ * custom USB UI on the same best-effort error handling.
17
+ */
18
+ export declare function useMoldableUsb(options?: UseMoldableUsbOptions): {
19
+ devices: MoldableUsbDevice[];
20
+ status: MoldableUsbStatus;
21
+ error: Error | null;
22
+ openDeviceIds: string[];
23
+ nativeDeviceChoices: readonly MoldableUsbDevice[];
24
+ deviceId: (device: MoldableUsbDevice) => string;
25
+ refresh: () => Promise<void>;
26
+ request: (filters?: readonly MoldableUsbDeviceFilter[]) => Promise<MoldableUsbDevice | undefined>;
27
+ selectNativeDevice: (device: MoldableUsbDevice) => void;
28
+ cancelNativeSelection: () => void;
29
+ open: (device: MoldableUsbDevice) => Promise<void>;
30
+ close: (device: MoldableUsbDevice) => Promise<boolean>;
31
+ forget: (device: MoldableUsbDevice) => Promise<boolean>;
32
+ readEndpoint: (device: MoldableUsbDevice, endpoint: number, length: number) => Promise<import("../..").MoldableUsbInTransferResult>;
33
+ writeEndpoint: (device: MoldableUsbDevice, endpoint: number, data: BufferSource) => Promise<import("../..").MoldableUsbOutTransferResult>;
34
+ readControl: (device: MoldableUsbDevice, setup: MoldableUsbControlTransferParameters, length: number) => Promise<import("../..").MoldableUsbInTransferResult>;
35
+ writeControl: (device: MoldableUsbDevice, setup: MoldableUsbControlTransferParameters, data?: BufferSource) => Promise<import("../..").MoldableUsbOutTransferResult>;
36
+ clearHalt: (device: MoldableUsbDevice, direction: "in" | "out", endpoint: number) => Promise<void>;
37
+ reset: (device: MoldableUsbDevice) => Promise<void>;
38
+ };
39
+ export interface UsbDevicePanelProps extends React.ComponentProps<'div'> {
40
+ /** Device filters for the chooser (WebUSB requires at least one to narrow). */
41
+ filters?: readonly MoldableUsbDeviceFilter[];
42
+ /** Overrides the built-in explicit picker for multiple native matches. */
43
+ selectNativeDevice?: MoldableUsbRequestOptions['selectNativeDevice'];
44
+ /** Configuration and interfaces to claim when opening a device. */
45
+ openOptions?: MoldableUsbOpenOptions;
46
+ onDeviceOpen?: (device: MoldableUsbDevice) => void;
47
+ }
48
+ /**
49
+ * USB device panel: request access, list granted devices, open/close each
50
+ * with minimal claims, and read out live device details while open.
51
+ */
52
+ declare function UsbDevicePanel({ className, filters, selectNativeDevice, openOptions, onDeviceOpen, ...props }: UsbDevicePanelProps): import("react/jsx-runtime").JSX.Element;
53
+ export { UsbDevicePanel };
54
+ //# sourceMappingURL=usb-panel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usb-panel.d.ts","sourceRoot":"","sources":["../../../src/components/hardware/usb-panel.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EACL,KAAK,oCAAoC,EACzC,KAAK,iBAAiB,EACtB,KAAK,uBAAuB,EAC5B,KAAK,sBAAsB,EAC3B,KAAK,yBAAyB,EAa/B,MAAM,2BAA2B,CAAA;AA6BlC,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,SAAS,GAAG,YAAY,GAAG,OAAO,CAAA;AAmB3E,MAAM,WAAW,qBAAqB;IACpC,iEAAiE;IACjE,OAAO,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAA;IAC5C,0EAA0E;IAC1E,kBAAkB,CAAC,EAAE,yBAAyB,CAAC,oBAAoB,CAAC,CAAA;IACpE,mEAAmE;IACnE,WAAW,CAAC,EAAE,sBAAsB,CAAA;IACpC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAA;CACnD;AAcD;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,GAAE,qBAA0B;;;;;;uBAkB1B,iBAAiB,KAAG,MAAM;;wBA4F7C,SAAS,uBAAuB,EAAE;iCAvBL,iBAAiB;;mBAyDhD,iBAAiB;oBAoCjB,iBAAiB;qBA6CjB,iBAAiB;2BA+DtB,iBAAiB,YACf,MAAM,UACR,MAAM;4BAGN,iBAAiB,YACf,MAAM,QACV,YAAY;0BAGV,iBAAiB,SAClB,oCAAoC,UACnC,MAAM;2BAIN,iBAAiB,SAClB,oCAAoC,SACpC,YAAY;wBAIX,iBAAiB,aACd,IAAI,GAAG,KAAK,YACb,MAAM;oBAEF,iBAAiB;EAGpC;AAED,MAAM,WAAW,mBAAoB,SAAQ,KAAK,CAAC,cAAc,CAAC,KAAK,CAAC;IACtE,+EAA+E;IAC/E,OAAO,CAAC,EAAE,SAAS,uBAAuB,EAAE,CAAA;IAC5C,0EAA0E;IAC1E,kBAAkB,CAAC,EAAE,yBAAyB,CAAC,oBAAoB,CAAC,CAAA;IACpE,mEAAmE;IACnE,WAAW,CAAC,EAAE,sBAAsB,CAAA;IACpC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,iBAAiB,KAAK,IAAI,CAAA;CACnD;AAqPD;;;GAGG;AACH,iBAAS,cAAc,CAAC,EACtB,SAAS,EACT,OAAO,EACP,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,GAAG,KAAK,EACT,EAAE,mBAAmB,2CAmLrB;AAED,OAAO,EAAE,cAAc,EAAE,CAAA"}