@useupup/svelte 3.3.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 (222) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +60 -0
  3. package/dist/UpupUploader.svelte +96 -0
  4. package/dist/UpupUploader.svelte.d.ts +5 -0
  5. package/dist/UpupUploader.svelte.d.ts.map +1 -0
  6. package/dist/assets/logos.d.ts +5 -0
  7. package/dist/assets/logos.d.ts.map +1 -0
  8. package/dist/assets/logos.js +4 -0
  9. package/dist/components/AudioUploader.svelte +220 -0
  10. package/dist/components/AudioUploader.svelte.d.ts +4 -0
  11. package/dist/components/AudioUploader.svelte.d.ts.map +1 -0
  12. package/dist/components/AudioWaveform.svelte +72 -0
  13. package/dist/components/AudioWaveform.svelte.d.ts +7 -0
  14. package/dist/components/AudioWaveform.svelte.d.ts.map +1 -0
  15. package/dist/components/BoxUploader.svelte +17 -0
  16. package/dist/components/BoxUploader.svelte.d.ts +19 -0
  17. package/dist/components/BoxUploader.svelte.d.ts.map +1 -0
  18. package/dist/components/CameraUploader.svelte +140 -0
  19. package/dist/components/CameraUploader.svelte.d.ts +4 -0
  20. package/dist/components/CameraUploader.svelte.d.ts.map +1 -0
  21. package/dist/components/ClientBoxUploader.svelte +60 -0
  22. package/dist/components/ClientBoxUploader.svelte.d.ts +19 -0
  23. package/dist/components/ClientBoxUploader.svelte.d.ts.map +1 -0
  24. package/dist/components/ClientDropboxUploader.svelte +60 -0
  25. package/dist/components/ClientDropboxUploader.svelte.d.ts +19 -0
  26. package/dist/components/ClientDropboxUploader.svelte.d.ts.map +1 -0
  27. package/dist/components/ClientGoogleDriveUploader.svelte +57 -0
  28. package/dist/components/ClientGoogleDriveUploader.svelte.d.ts +19 -0
  29. package/dist/components/ClientGoogleDriveUploader.svelte.d.ts.map +1 -0
  30. package/dist/components/ClientOneDriveUploader.svelte +60 -0
  31. package/dist/components/ClientOneDriveUploader.svelte.d.ts +19 -0
  32. package/dist/components/ClientOneDriveUploader.svelte.d.ts.map +1 -0
  33. package/dist/components/DefaultAddMoreIcon.svelte +11 -0
  34. package/dist/components/DefaultAddMoreIcon.svelte.d.ts +8 -0
  35. package/dist/components/DefaultAddMoreIcon.svelte.d.ts.map +1 -0
  36. package/dist/components/DefaultLoaderIcon.svelte +5 -0
  37. package/dist/components/DefaultLoaderIcon.svelte.d.ts +19 -0
  38. package/dist/components/DefaultLoaderIcon.svelte.d.ts.map +1 -0
  39. package/dist/components/DropboxUploader.svelte +17 -0
  40. package/dist/components/DropboxUploader.svelte.d.ts +19 -0
  41. package/dist/components/DropboxUploader.svelte.d.ts.map +1 -0
  42. package/dist/components/EmptyIcon.svelte +3 -0
  43. package/dist/components/EmptyIcon.svelte.d.ts +19 -0
  44. package/dist/components/EmptyIcon.svelte.d.ts.map +1 -0
  45. package/dist/components/FileHero.svelte +152 -0
  46. package/dist/components/FileHero.svelte.d.ts +8 -0
  47. package/dist/components/FileHero.svelte.d.ts.map +1 -0
  48. package/dist/components/FileIcon.svelte +23 -0
  49. package/dist/components/FileIcon.svelte.d.ts +8 -0
  50. package/dist/components/FileIcon.svelte.d.ts.map +1 -0
  51. package/dist/components/FileItem.svelte +95 -0
  52. package/dist/components/FileItem.svelte.d.ts +12 -0
  53. package/dist/components/FileItem.svelte.d.ts.map +1 -0
  54. package/dist/components/FileList.svelte +442 -0
  55. package/dist/components/FileList.svelte.d.ts +4 -0
  56. package/dist/components/FileList.svelte.d.ts.map +1 -0
  57. package/dist/components/FilePreview.svelte +218 -0
  58. package/dist/components/FilePreview.svelte.d.ts +17 -0
  59. package/dist/components/FilePreview.svelte.d.ts.map +1 -0
  60. package/dist/components/FilePreviewPortal.svelte +189 -0
  61. package/dist/components/FilePreviewPortal.svelte.d.ts +12 -0
  62. package/dist/components/FilePreviewPortal.svelte.d.ts.map +1 -0
  63. package/dist/components/FilePreviewThumbnail.svelte +87 -0
  64. package/dist/components/FilePreviewThumbnail.svelte.d.ts +17 -0
  65. package/dist/components/FilePreviewThumbnail.svelte.d.ts.map +1 -0
  66. package/dist/components/FileRow.svelte +192 -0
  67. package/dist/components/FileRow.svelte.d.ts +10 -0
  68. package/dist/components/FileRow.svelte.d.ts.map +1 -0
  69. package/dist/components/GoogleDriveUploader.svelte +17 -0
  70. package/dist/components/GoogleDriveUploader.svelte.d.ts +19 -0
  71. package/dist/components/GoogleDriveUploader.svelte.d.ts.map +1 -0
  72. package/dist/components/Icon.svelte +24 -0
  73. package/dist/components/Icon.svelte.d.ts +10 -0
  74. package/dist/components/Icon.svelte.d.ts.map +1 -0
  75. package/dist/components/Icons.d.ts +10 -0
  76. package/dist/components/Icons.d.ts.map +1 -0
  77. package/dist/components/Icons.js +9 -0
  78. package/dist/components/ImageEditorStub.svelte +3 -0
  79. package/dist/components/ImageEditorStub.svelte.d.ts +19 -0
  80. package/dist/components/ImageEditorStub.svelte.d.ts.map +1 -0
  81. package/dist/components/OneDriveUploader.svelte +17 -0
  82. package/dist/components/OneDriveUploader.svelte.d.ts +19 -0
  83. package/dist/components/OneDriveUploader.svelte.d.ts.map +1 -0
  84. package/dist/components/ScreenCaptureUploader.svelte +254 -0
  85. package/dist/components/ScreenCaptureUploader.svelte.d.ts +4 -0
  86. package/dist/components/ScreenCaptureUploader.svelte.d.ts.map +1 -0
  87. package/dist/components/ServerModeDriveUploader.svelte +250 -0
  88. package/dist/components/ServerModeDriveUploader.svelte.d.ts +10 -0
  89. package/dist/components/ServerModeDriveUploader.svelte.d.ts.map +1 -0
  90. package/dist/components/SourceSelector.svelte +292 -0
  91. package/dist/components/SourceSelector.svelte.d.ts +19 -0
  92. package/dist/components/SourceSelector.svelte.d.ts.map +1 -0
  93. package/dist/components/SourceView.svelte +100 -0
  94. package/dist/components/SourceView.svelte.d.ts +4 -0
  95. package/dist/components/SourceView.svelte.d.ts.map +1 -0
  96. package/dist/components/TrashIcon.svelte +11 -0
  97. package/dist/components/TrashIcon.svelte.d.ts +8 -0
  98. package/dist/components/TrashIcon.svelte.d.ts.map +1 -0
  99. package/dist/components/UploaderPanel.svelte +363 -0
  100. package/dist/components/UploaderPanel.svelte.d.ts +4 -0
  101. package/dist/components/UploaderPanel.svelte.d.ts.map +1 -0
  102. package/dist/components/UrlUploader.svelte +71 -0
  103. package/dist/components/UrlUploader.svelte.d.ts +4 -0
  104. package/dist/components/UrlUploader.svelte.d.ts.map +1 -0
  105. package/dist/components/icons/AudioIcon.svelte +5 -0
  106. package/dist/components/icons/AudioIcon.svelte.d.ts +7 -0
  107. package/dist/components/icons/AudioIcon.svelte.d.ts.map +1 -0
  108. package/dist/components/icons/BoxIcon.svelte +5 -0
  109. package/dist/components/icons/BoxIcon.svelte.d.ts +7 -0
  110. package/dist/components/icons/BoxIcon.svelte.d.ts.map +1 -0
  111. package/dist/components/icons/CameraIcon.svelte +5 -0
  112. package/dist/components/icons/CameraIcon.svelte.d.ts +7 -0
  113. package/dist/components/icons/CameraIcon.svelte.d.ts.map +1 -0
  114. package/dist/components/icons/DropboxIcon.svelte +5 -0
  115. package/dist/components/icons/DropboxIcon.svelte.d.ts +7 -0
  116. package/dist/components/icons/DropboxIcon.svelte.d.ts.map +1 -0
  117. package/dist/components/icons/GoogleDriveIcon.svelte +5 -0
  118. package/dist/components/icons/GoogleDriveIcon.svelte.d.ts +7 -0
  119. package/dist/components/icons/GoogleDriveIcon.svelte.d.ts.map +1 -0
  120. package/dist/components/icons/LinkIcon.svelte +5 -0
  121. package/dist/components/icons/LinkIcon.svelte.d.ts +7 -0
  122. package/dist/components/icons/LinkIcon.svelte.d.ts.map +1 -0
  123. package/dist/components/icons/MyDeviceIcon.svelte +5 -0
  124. package/dist/components/icons/MyDeviceIcon.svelte.d.ts +7 -0
  125. package/dist/components/icons/MyDeviceIcon.svelte.d.ts.map +1 -0
  126. package/dist/components/icons/OneDriveIcon.svelte +5 -0
  127. package/dist/components/icons/OneDriveIcon.svelte.d.ts +7 -0
  128. package/dist/components/icons/OneDriveIcon.svelte.d.ts.map +1 -0
  129. package/dist/components/icons/ScreenCaptureIcon.svelte +5 -0
  130. package/dist/components/icons/ScreenCaptureIcon.svelte.d.ts +7 -0
  131. package/dist/components/icons/ScreenCaptureIcon.svelte.d.ts.map +1 -0
  132. package/dist/components/shared/DriveAuthFallback.svelte +60 -0
  133. package/dist/components/shared/DriveAuthFallback.svelte.d.ts +12 -0
  134. package/dist/components/shared/DriveAuthFallback.svelte.d.ts.map +1 -0
  135. package/dist/components/shared/DriveBrowser.svelte +209 -0
  136. package/dist/components/shared/DriveBrowser.svelte.d.ts +25 -0
  137. package/dist/components/shared/DriveBrowser.svelte.d.ts.map +1 -0
  138. package/dist/components/shared/DriveBrowserHeader.svelte +191 -0
  139. package/dist/components/shared/DriveBrowserHeader.svelte.d.ts +14 -0
  140. package/dist/components/shared/DriveBrowserHeader.svelte.d.ts.map +1 -0
  141. package/dist/components/shared/DriveBrowserIcon.svelte +39 -0
  142. package/dist/components/shared/DriveBrowserIcon.svelte.d.ts +8 -0
  143. package/dist/components/shared/DriveBrowserIcon.svelte.d.ts.map +1 -0
  144. package/dist/components/shared/DriveBrowserItem.svelte +63 -0
  145. package/dist/components/shared/DriveBrowserItem.svelte.d.ts +10 -0
  146. package/dist/components/shared/DriveBrowserItem.svelte.d.ts.map +1 -0
  147. package/dist/components/shared/FileSuccessCheck.svelte +47 -0
  148. package/dist/components/shared/FileSuccessCheck.svelte.d.ts +10 -0
  149. package/dist/components/shared/FileSuccessCheck.svelte.d.ts.map +1 -0
  150. package/dist/components/shared/ProgressBar.svelte +81 -0
  151. package/dist/components/shared/ProgressBar.svelte.d.ts +10 -0
  152. package/dist/components/shared/ProgressBar.svelte.d.ts.map +1 -0
  153. package/dist/components/shared/SourceViewContainer.svelte +27 -0
  154. package/dist/components/shared/SourceViewContainer.svelte.d.ts +10 -0
  155. package/dist/components/shared/SourceViewContainer.svelte.d.ts.map +1 -0
  156. package/dist/components/shared/UploaderHeader.svelte +156 -0
  157. package/dist/components/shared/UploaderHeader.svelte.d.ts +13 -0
  158. package/dist/components/shared/UploaderHeader.svelte.d.ts.map +1 -0
  159. package/dist/composables/use-tiles-per-row.d.ts +19 -0
  160. package/dist/composables/use-tiles-per-row.d.ts.map +1 -0
  161. package/dist/composables/use-tiles-per-row.js +30 -0
  162. package/dist/composables/useBox.d.ts +28 -0
  163. package/dist/composables/useBox.d.ts.map +1 -0
  164. package/dist/composables/useBox.js +61 -0
  165. package/dist/composables/useCameraUploader.d.ts +23 -0
  166. package/dist/composables/useCameraUploader.d.ts.map +1 -0
  167. package/dist/composables/useCameraUploader.js +114 -0
  168. package/dist/composables/useDropbox.d.ts +28 -0
  169. package/dist/composables/useDropbox.d.ts.map +1 -0
  170. package/dist/composables/useDropbox.js +61 -0
  171. package/dist/composables/useFetchFileByUrl.d.ts +9 -0
  172. package/dist/composables/useFetchFileByUrl.d.ts.map +1 -0
  173. package/dist/composables/useFetchFileByUrl.js +33 -0
  174. package/dist/composables/useGoogleDrive.d.ts +28 -0
  175. package/dist/composables/useGoogleDrive.d.ts.map +1 -0
  176. package/dist/composables/useGoogleDrive.js +65 -0
  177. package/dist/composables/useOneDrive.d.ts +29 -0
  178. package/dist/composables/useOneDrive.d.ts.map +1 -0
  179. package/dist/composables/useOneDrive.js +64 -0
  180. package/dist/composables/useSSEProcessing.d.ts +20 -0
  181. package/dist/composables/useSSEProcessing.d.ts.map +1 -0
  182. package/dist/composables/useSSEProcessing.js +17 -0
  183. package/dist/composables/useServerModeDrive.d.ts +17 -0
  184. package/dist/composables/useServerModeDrive.d.ts.map +1 -0
  185. package/dist/composables/useServerModeDrive.js +33 -0
  186. package/dist/composables/useSourceSelector.d.ts +13 -0
  187. package/dist/composables/useSourceSelector.d.ts.map +1 -0
  188. package/dist/composables/useSourceSelector.js +36 -0
  189. package/dist/composables/useUploaderPanel.d.ts +12 -0
  190. package/dist/composables/useUploaderPanel.d.ts.map +1 -0
  191. package/dist/composables/useUploaderPanel.js +43 -0
  192. package/dist/context/create-uploader-context.d.ts +4 -0
  193. package/dist/context/create-uploader-context.d.ts.map +1 -0
  194. package/dist/context/create-uploader-context.js +324 -0
  195. package/dist/context/source-view-header-extra.d.ts +14 -0
  196. package/dist/context/source-view-header-extra.d.ts.map +1 -0
  197. package/dist/context/source-view-header-extra.js +41 -0
  198. package/dist/context/uploader-context.d.ts +109 -0
  199. package/dist/context/uploader-context.d.ts.map +1 -0
  200. package/dist/context/uploader-context.js +96 -0
  201. package/dist/index.d.ts +10 -0
  202. package/dist/index.d.ts.map +1 -0
  203. package/dist/index.js +5 -0
  204. package/dist/lib/constants.d.ts +13 -0
  205. package/dist/lib/constants.d.ts.map +1 -0
  206. package/dist/lib/constants.js +67 -0
  207. package/dist/lib/to-readable.d.ts +14 -0
  208. package/dist/lib/to-readable.d.ts.map +1 -0
  209. package/dist/lib/to-readable.js +15 -0
  210. package/dist/lib/view-mode.d.ts +24 -0
  211. package/dist/lib/view-mode.d.ts.map +1 -0
  212. package/dist/lib/view-mode.js +31 -0
  213. package/dist/shared/types.d.ts +15 -0
  214. package/dist/shared/types.d.ts.map +1 -0
  215. package/dist/shared/types.js +1 -0
  216. package/dist/styles.d.ts +4 -0
  217. package/dist/tailwind-prefixed.css +2479 -0
  218. package/dist/tailwind.css +74 -0
  219. package/dist/use-upup-upload.d.ts +38 -0
  220. package/dist/use-upup-upload.d.ts.map +1 -0
  221. package/dist/use-upup-upload.js +81 -0
  222. package/package.json +101 -0
@@ -0,0 +1,220 @@
1
+ <script lang="ts">
2
+ import { onDestroy } from 'svelte'
3
+ import {
4
+ useUploaderFiles,
5
+ useUploaderSource,
6
+ useUploaderTheme,
7
+ } from '../context/uploader-context'
8
+ import { cn } from '@useupup/core/internal'
9
+ import SourceViewContainer from './shared/SourceViewContainer.svelte'
10
+ import AudioWaveform from './AudioWaveform.svelte'
11
+
12
+ type RecordingState = 'idle' | 'recording' | 'recorded'
13
+
14
+ const { setFiles } = useUploaderFiles()
15
+ const { setActiveSource } = useUploaderSource()
16
+ const { isDark: dark } = useUploaderTheme()
17
+
18
+ let recordingState: RecordingState = $state('idle')
19
+ let duration = $state(0)
20
+ let audioUrl: string | null = $state(null)
21
+ let error: string | null = $state(null)
22
+
23
+ let mediaRecorder: MediaRecorder | null = null
24
+ const chunks: Blob[] = []
25
+ let timerHandle: ReturnType<typeof setInterval> | null = null
26
+ let streamRef: MediaStream | null = $state(null)
27
+
28
+ onDestroy(() => {
29
+ if (timerHandle) clearInterval(timerHandle)
30
+ if (audioUrl) URL.revokeObjectURL(audioUrl)
31
+ streamRef?.getTracks().forEach((t) => t.stop())
32
+ })
33
+
34
+ async function startRecording() {
35
+ try {
36
+ const stream = await navigator.mediaDevices.getUserMedia({ audio: true })
37
+ streamRef = stream
38
+ chunks.length = 0
39
+ const recorder = new MediaRecorder(stream)
40
+ mediaRecorder = recorder
41
+
42
+ recorder.ondataavailable = (e) => {
43
+ if (e.data.size > 0) chunks.push(e.data)
44
+ }
45
+
46
+ recorder.onstop = () => {
47
+ const blob = new Blob(chunks, { type: recorder.mimeType || 'audio/webm' })
48
+ audioUrl = URL.createObjectURL(blob)
49
+ stream.getTracks().forEach((t) => t.stop())
50
+ }
51
+
52
+ recorder.start()
53
+ recordingState = 'recording'
54
+ duration = 0
55
+ timerHandle = setInterval(() => { duration++ }, 1000)
56
+ } catch {
57
+ error = 'Microphone access denied. Please allow microphone access and try again.'
58
+ }
59
+ }
60
+
61
+ function stopRecording() {
62
+ mediaRecorder?.stop()
63
+ if (timerHandle) clearInterval(timerHandle)
64
+ recordingState = 'recorded'
65
+ }
66
+
67
+ function discardRecording() {
68
+ if (audioUrl) URL.revokeObjectURL(audioUrl)
69
+ audioUrl = null
70
+ duration = 0
71
+ recordingState = 'idle'
72
+ }
73
+
74
+ function addRecording() {
75
+ if (!audioUrl) return
76
+ const ext = mediaRecorder?.mimeType?.includes('webm') ? 'webm' : 'ogg'
77
+ fetch(audioUrl)
78
+ .then((r) => r.blob())
79
+ .then((blob) => {
80
+ const file = new File([blob], `recording-${Date.now()}.${ext}`, { type: blob.type })
81
+ setFiles([file])
82
+ setActiveSource(undefined)
83
+ })
84
+ .catch(() => {
85
+ // upup-catch: replaying an in-memory object URL cannot fail in practice; ignore
86
+ })
87
+ }
88
+
89
+ function formatTime(s: number) {
90
+ const m = Math.floor(s / 60)
91
+ const sec = s % 60
92
+ return `${m}:${sec.toString().padStart(2, '0')}`
93
+ }
94
+ </script>
95
+
96
+ {#if error}
97
+ <!-- Error state -->
98
+ <SourceViewContainer data-upup-slot="audio-uploader">
99
+ <div class="upup-flex upup-flex-col upup-items-center upup-gap-3 upup-p-6 upup-text-center">
100
+ <p
101
+ class={cn('upup-text-sm upup-text-red-500', {
102
+ 'upup-text-red-400': $dark,
103
+ })}
104
+ >
105
+ {error}
106
+ </p>
107
+ </div>
108
+ </SourceViewContainer>
109
+ {:else}
110
+ <!-- Normal state -->
111
+ <SourceViewContainer data-upup-slot="audio-uploader">
112
+ <div class="upup-flex upup-h-full upup-w-full upup-flex-col upup-items-center upup-justify-center upup-gap-6 upup-p-6">
113
+ <div
114
+ class={cn(
115
+ 'upup-flex upup-h-24 upup-w-24 upup-items-center upup-justify-center upup-rounded-full',
116
+ {
117
+ 'upup-bg-red-500/20': recordingState === 'recording',
118
+ 'upup-bg-[#0ea5e9]/20': recordingState === 'idle' || recordingState === 'recorded',
119
+ },
120
+ )}
121
+ >
122
+ <div
123
+ class={cn(
124
+ 'upup-flex upup-h-16 upup-w-16 upup-items-center upup-justify-center upup-rounded-full upup-transition-all',
125
+ {
126
+ 'upup-animate-pulse upup-bg-red-500': recordingState === 'recording',
127
+ 'upup-bg-[#0ea5e9]': recordingState === 'idle' || recordingState === 'recorded',
128
+ },
129
+ )}
130
+ >
131
+ <svg
132
+ xmlns="http://www.w3.org/2000/svg"
133
+ width="28"
134
+ height="28"
135
+ viewBox="0 0 24 24"
136
+ fill="none"
137
+ stroke="white"
138
+ stroke-width="2"
139
+ stroke-linecap="round"
140
+ stroke-linejoin="round"
141
+ >
142
+ <path d="M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z" />
143
+ <path d="M19 10v2a7 7 0 0 1-14 0v-2" />
144
+ <line x1="12" x2="12" y1="19" y2="22" />
145
+ </svg>
146
+ </div>
147
+ </div>
148
+
149
+ {#if recordingState === 'recording' && streamRef}
150
+ <AudioWaveform stream={streamRef!} />
151
+ {/if}
152
+
153
+ <span
154
+ class={cn(
155
+ 'upup-text-2xl upup-font-mono upup-tabular-nums',
156
+ {
157
+ 'upup-text-[#1b1b1b]': !$dark,
158
+ 'upup-text-white': $dark,
159
+ },
160
+ )}
161
+ >
162
+ {formatTime(duration)}
163
+ </span>
164
+
165
+ {#if recordingState === 'recorded' && audioUrl}
166
+ <!-- svelte-ignore a11y_media_has_caption -->
167
+ <audio controls src={audioUrl} class="upup-w-full upup-max-w-xs"></audio>
168
+ {/if}
169
+
170
+ <div class="upup-flex upup-gap-3">
171
+ {#if recordingState === 'idle'}
172
+ <button
173
+ type="button"
174
+ class={cn(
175
+ 'upup-rounded-lg upup-bg-[#0ea5e9] upup-px-6 upup-py-2.5 upup-text-sm upup-font-medium upup-text-white upup-transition-colors hover:upup-bg-[#0284c7]',
176
+ {
177
+ 'upup-bg-[#38bdf8] hover:upup-bg-[#0ea5e9] dark:upup-bg-[#38bdf8]': $dark,
178
+ },
179
+ )}
180
+ onclick={startRecording}
181
+ >
182
+ Start Recording
183
+ </button>
184
+ {/if}
185
+
186
+ {#if recordingState === 'recording'}
187
+ <button
188
+ type="button"
189
+ class="upup-rounded-lg upup-bg-red-500 upup-px-6 upup-py-2.5 upup-text-sm upup-font-medium upup-text-white upup-transition-colors hover:upup-bg-red-600"
190
+ onclick={stopRecording}
191
+ >
192
+ Stop Recording
193
+ </button>
194
+ {/if}
195
+
196
+ {#if recordingState === 'recorded'}
197
+ <button
198
+ type="button"
199
+ class="upup-rounded-lg upup-bg-gray-500 upup-px-4 upup-py-2.5 upup-text-sm upup-font-medium upup-text-white upup-transition-colors hover:upup-bg-gray-600"
200
+ onclick={discardRecording}
201
+ >
202
+ Discard
203
+ </button>
204
+ <button
205
+ type="button"
206
+ class={cn(
207
+ 'upup-rounded-lg upup-bg-[#0ea5e9] upup-px-4 upup-py-2.5 upup-text-sm upup-font-medium upup-text-white upup-transition-colors hover:upup-bg-[#0284c7]',
208
+ {
209
+ 'upup-bg-[#38bdf8] hover:upup-bg-[#0ea5e9] dark:upup-bg-[#38bdf8]': $dark,
210
+ },
211
+ )}
212
+ onclick={addRecording}
213
+ >
214
+ Add Recording
215
+ </button>
216
+ {/if}
217
+ </div>
218
+ </div>
219
+ </SourceViewContainer>
220
+ {/if}
@@ -0,0 +1,4 @@
1
+ declare const AudioUploader: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type AudioUploader = ReturnType<typeof AudioUploader>;
3
+ export default AudioUploader;
4
+ //# sourceMappingURL=AudioUploader.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AudioUploader.svelte.d.ts","sourceRoot":"","sources":["../../src/components/AudioUploader.svelte.ts"],"names":[],"mappings":"AAsMA,QAAA,MAAM,aAAa,2DAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
@@ -0,0 +1,72 @@
1
+ <script lang="ts">
2
+ import { onMount, onDestroy } from 'svelte'
3
+
4
+ const BAR_COUNT = 28
5
+
6
+ /**
7
+ * Live recording waveform (states-tour-3 state D): sky bars whose heights track
8
+ * the microphone's live frequency data via a Web Audio AnalyserNode.
9
+ *
10
+ * This is the ONE place JS-driven visuals are sanctioned — the bars render REAL
11
+ * audio data, not fx decoration, so (a) they are NOT classed `upup-fx-*` (the
12
+ * motion gate must not freeze live data) and (b) the rAF read loop is
13
+ * legitimate. Heights are written straight to the DOM (no per-frame render).
14
+ * The AnalyserNode + AudioContext are torn down on unmount/stop.
15
+ */
16
+ let { stream }: { stream: MediaStream } = $props()
17
+
18
+ const barEls: Array<HTMLSpanElement | null> = Array.from(
19
+ { length: BAR_COUNT },
20
+ () => null,
21
+ )
22
+ let raf = 0
23
+ let audioCtx: AudioContext | null = null
24
+ let sourceNode: MediaStreamAudioSourceNode | null = null
25
+
26
+ onMount(() => {
27
+ const AudioCtor =
28
+ window.AudioContext ??
29
+ (window as unknown as { webkitAudioContext?: typeof AudioContext })
30
+ .webkitAudioContext
31
+ if (!AudioCtor) return
32
+ audioCtx = new AudioCtor()
33
+ // Autoplay policy may create the context suspended; without resuming,
34
+ // getByteFrequencyData returns all-zeros and the bars silently flatline.
35
+ void audioCtx.resume()
36
+ sourceNode = audioCtx.createMediaStreamSource(stream)
37
+ const analyser = audioCtx.createAnalyser()
38
+ analyser.fftSize = 64
39
+ sourceNode.connect(analyser)
40
+ const data = new Uint8Array(analyser.frequencyBinCount)
41
+ const tick = () => {
42
+ analyser.getByteFrequencyData(data)
43
+ for (let i = 0; i < barEls.length; i++) {
44
+ const v = data[i % data.length] ?? 0
45
+ const el = barEls[i]
46
+ if (el) el.style.height = `${6 + (v / 255) * 34}px`
47
+ }
48
+ raf = requestAnimationFrame(tick)
49
+ }
50
+ raf = requestAnimationFrame(tick)
51
+ })
52
+
53
+ onDestroy(() => {
54
+ cancelAnimationFrame(raf)
55
+ sourceNode?.disconnect()
56
+ void audioCtx?.close()
57
+ })
58
+ </script>
59
+
60
+ <div
61
+ data-upup-slot="audio-waveform"
62
+ aria-hidden="true"
63
+ class="upup-flex upup-h-11 upup-items-center upup-justify-center upup-gap-[3px]"
64
+ >
65
+ {#each Array.from({ length: BAR_COUNT }) as _, i}
66
+ <span
67
+ bind:this={barEls[i]}
68
+ class="upup-w-[3px] upup-flex-none upup-rounded-full upup-bg-[#38bdf8]"
69
+ style="height: 6px"
70
+ ></span>
71
+ {/each}
72
+ </div>
@@ -0,0 +1,7 @@
1
+ type $$ComponentProps = {
2
+ stream: MediaStream;
3
+ };
4
+ declare const AudioWaveform: import("svelte").Component<$$ComponentProps, {}, "">;
5
+ type AudioWaveform = ReturnType<typeof AudioWaveform>;
6
+ export default AudioWaveform;
7
+ //# sourceMappingURL=AudioWaveform.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AudioWaveform.svelte.d.ts","sourceRoot":"","sources":["../../src/components/AudioWaveform.svelte.ts"],"names":[],"mappings":"AAKC,KAAK,gBAAgB,GAAI;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,CAAC;AAoElD,QAAA,MAAM,aAAa,sDAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
@@ -0,0 +1,17 @@
1
+ <script lang="ts">
2
+ import { useUploaderRuntime, useUploaderSource } from '../context/uploader-context'
3
+ import ClientBoxUploader from './ClientBoxUploader.svelte'
4
+ import ServerModeDriveUploader from './ServerModeDriveUploader.svelte'
5
+
6
+ const { mode } = useUploaderRuntime()
7
+ const { setActiveSource } = useUploaderSource()
8
+ </script>
9
+
10
+ {#if mode === 'server'}
11
+ <ServerModeDriveUploader
12
+ provider="box"
13
+ onBack={() => setActiveSource(undefined)}
14
+ />
15
+ {:else}
16
+ <ClientBoxUploader />
17
+ {/if}
@@ -0,0 +1,19 @@
1
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
+ $$bindings?: Bindings;
4
+ } & Exports;
5
+ (internal: unknown, props: {
6
+ $$events?: Events;
7
+ $$slots?: Slots;
8
+ }): Exports & {
9
+ $set?: any;
10
+ $on?: any;
11
+ };
12
+ z_$$bindings?: Bindings;
13
+ }
14
+ declare const BoxUploader: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type BoxUploader = InstanceType<typeof BoxUploader>;
18
+ export default BoxUploader;
19
+ //# sourceMappingURL=BoxUploader.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BoxUploader.svelte.d.ts","sourceRoot":"","sources":["../../src/components/BoxUploader.svelte.ts"],"names":[],"mappings":"AAwBA,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,WAAW;;kBAA+E,CAAC;AAC/E,KAAK,WAAW,GAAG,YAAY,CAAC,OAAO,WAAW,CAAC,CAAC;AACtD,eAAe,WAAW,CAAC"}
@@ -0,0 +1,140 @@
1
+ <script lang="ts">
2
+ import { onMount, onDestroy } from 'svelte'
3
+ import { formatUiMessage as t } from '@useupup/core'
4
+ import { cn } from '@useupup/core/internal'
5
+ import useCameraUploader from '../composables/useCameraUploader'
6
+ import SourceViewContainer from './shared/SourceViewContainer.svelte'
7
+
8
+ const {
9
+ setVideoEl,
10
+ capturedUrl,
11
+ facingMode,
12
+ newCameraSide,
13
+ startCamera,
14
+ capture,
15
+ clearUrl,
16
+ handleFetchImage,
17
+ handleCameraSwitch,
18
+ translations: tr,
19
+ props,
20
+ theme,
21
+ } = useCameraUploader()
22
+
23
+ const { icons: { CameraCaptureIcon, CameraDeleteIcon, CameraRotateIcon } } = props
24
+ const { isDark: dark, slotOverrides: slotClasses } = theme
25
+
26
+ // video element bound via bind:this — set into composable
27
+ let videoEl: HTMLVideoElement | null = $state(null)
28
+
29
+ // Keep composable in sync with the bound element
30
+ $effect(() => {
31
+ setVideoEl(videoEl)
32
+ })
33
+
34
+ onMount(() => {
35
+ // Start camera initially
36
+ startCamera()
37
+
38
+ // Restart camera when facingMode changes, but only when no capture is shown
39
+ let isFirst = true
40
+ const unsub = facingMode.subscribe(() => {
41
+ if (isFirst) { isFirst = false; return }
42
+ let currentCapturedUrl = ''
43
+ const u = capturedUrl.subscribe((v) => { currentCapturedUrl = v })
44
+ u()
45
+ if (!currentCapturedUrl) startCamera()
46
+ })
47
+
48
+ return () => unsub()
49
+ })
50
+ </script>
51
+
52
+ <SourceViewContainer data-upup-slot="camera-uploader">
53
+ <div
54
+ data-testid="upup-camera-uploader"
55
+ class="upup-flex upup-h-full upup-w-full upup-flex-col upup-justify-center upup-overflow-hidden upup-px-3 upup-py-2"
56
+ >
57
+ <div class="upup-flex upup-min-h-0 upup-flex-1 upup-items-center upup-justify-center upup-pt-2">
58
+ {#if $capturedUrl}
59
+ <div
60
+ class={cn(
61
+ 'upup-relative upup-aspect-video upup-max-h-full upup-max-w-full upup-bg-black/[0.025] upup-bg-contain upup-bg-center upup-bg-no-repeat upup-shadow-xl',
62
+ {
63
+ 'upup-bg-white/5 dark:upup-bg-white/5': $dark,
64
+ },
65
+ $slotClasses.cameraPreviewContainer,
66
+ )}
67
+ style="background-image: url({$capturedUrl})"
68
+ >
69
+ <button
70
+ onclick={clearUrl}
71
+ class={cn(
72
+ 'upup-absolute upup--right-2 upup--top-2 upup-z-10 upup-rounded-full upup-bg-[#272727] upup-p-1 upup-text-xl upup-text-[#f5f5f5]',
73
+ $slotClasses.cameraDeleteButton,
74
+ )}
75
+ type="button"
76
+ >
77
+ <CameraDeleteIcon />
78
+ </button>
79
+ </div>
80
+ {:else}
81
+ <!-- svelte-ignore a11y_media_has_caption -->
82
+ <video
83
+ bind:this={videoEl}
84
+ autoplay
85
+ muted
86
+ playsinline
87
+ class="upup-aspect-video upup-max-h-full upup-max-w-full upup-rounded-xl upup-object-contain"
88
+ ></video>
89
+ {/if}
90
+ </div>
91
+
92
+ <div class="upup-flex upup-shrink-0 upup-gap-4">
93
+ {#if !$capturedUrl}
94
+ <button
95
+ class={cn(
96
+ 'upup-mt-2 upup-flex upup-w-1/3 upup-flex-col upup-items-center upup-justify-center upup-rounded-md upup-bg-[#0ea5e9] upup-p-2 upup-text-white upup-transition-all upup-duration-300',
97
+ {
98
+ 'upup-bg-[#38bdf8] dark:upup-bg-[#38bdf8]': $dark,
99
+ },
100
+ $slotClasses.cameraCaptureButton,
101
+ )}
102
+ onclick={capture}
103
+ type="button"
104
+ >
105
+ <span><CameraCaptureIcon /></span>
106
+ <span>{tr.capture}</span>
107
+ </button>
108
+ <button
109
+ class={cn(
110
+ 'upup-mt-2 upup-flex upup-w-1/3 upup-flex-col upup-items-center upup-rounded-md upup-bg-gray-500 upup-p-2 upup-text-white upup-transition-all upup-duration-300 hover:upup-bg-gray-600',
111
+ $slotClasses.cameraRotateButton,
112
+ )}
113
+ onclick={handleCameraSwitch}
114
+ type="button"
115
+ >
116
+ <span><CameraRotateIcon /></span>
117
+ <span>
118
+ {t(tr.switchToCamera, {
119
+ side: $newCameraSide === 'front' ? tr.front : tr.back,
120
+ })}
121
+ </span>
122
+ </button>
123
+ {:else}
124
+ <button
125
+ class={cn(
126
+ 'upup-mt-2 upup-w-full upup-rounded-md upup-bg-[#0ea5e9] upup-p-2 upup-text-white upup-transition-all upup-duration-300',
127
+ {
128
+ 'upup-bg-[#38bdf8] dark:upup-bg-[#38bdf8]': $dark,
129
+ },
130
+ $slotClasses.cameraAddButton,
131
+ )}
132
+ onclick={handleFetchImage}
133
+ type="button"
134
+ >
135
+ {tr.addImage}
136
+ </button>
137
+ {/if}
138
+ </div>
139
+ </div>
140
+ </SourceViewContainer>
@@ -0,0 +1,4 @@
1
+ declare const CameraUploader: import("svelte").Component<Record<string, never>, {}, "">;
2
+ type CameraUploader = ReturnType<typeof CameraUploader>;
3
+ export default CameraUploader;
4
+ //# sourceMappingURL=CameraUploader.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CameraUploader.svelte.d.ts","sourceRoot":"","sources":["../../src/components/CameraUploader.svelte.ts"],"names":[],"mappings":"AA4HA,QAAA,MAAM,cAAc,2DAAwC,CAAC;AAC7D,KAAK,cAAc,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AACxD,eAAe,cAAc,CAAC"}
@@ -0,0 +1,60 @@
1
+ <script lang="ts">
2
+ import { useBox } from '../composables/useBox'
3
+ import DriveAuthFallback from './shared/DriveAuthFallback.svelte'
4
+ import DriveBrowser from './shared/DriveBrowser.svelte'
5
+
6
+ const {
7
+ user,
8
+ boxFiles: driveFiles,
9
+ logout,
10
+ token,
11
+ isAuthenticated,
12
+ authenticate,
13
+ isLoading,
14
+ path,
15
+ setPath,
16
+ isClickLoading,
17
+ handleClick,
18
+ selectedFiles,
19
+ showLoader,
20
+ handleSubmit,
21
+ handleCancelDownload,
22
+ onSelectCurrentFolder,
23
+ error,
24
+ hasMore,
25
+ isLoadingMore,
26
+ loadMore,
27
+ } = useBox()
28
+
29
+ async function handleSignOut() {
30
+ logout()
31
+ }
32
+ </script>
33
+
34
+ {#if !$isAuthenticated && !$token && !$isLoading}
35
+ <DriveAuthFallback
36
+ providerName="Box"
37
+ onRetry={authenticate}
38
+ dataUpupSlot="box-uploader"
39
+ />
40
+ {:else}
41
+ <DriveBrowser
42
+ {driveFiles}
43
+ {user}
44
+ {handleSignOut}
45
+ dataUpupSlot="box-uploader"
46
+ {path}
47
+ {setPath}
48
+ {isClickLoading}
49
+ {handleClick}
50
+ {selectedFiles}
51
+ {showLoader}
52
+ {handleSubmit}
53
+ {handleCancelDownload}
54
+ {onSelectCurrentFolder}
55
+ {error}
56
+ {hasMore}
57
+ {isLoadingMore}
58
+ {loadMore}
59
+ />
60
+ {/if}
@@ -0,0 +1,19 @@
1
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
+ $$bindings?: Bindings;
4
+ } & Exports;
5
+ (internal: unknown, props: {
6
+ $$events?: Events;
7
+ $$slots?: Slots;
8
+ }): Exports & {
9
+ $set?: any;
10
+ $on?: any;
11
+ };
12
+ z_$$bindings?: Bindings;
13
+ }
14
+ declare const ClientBoxUploader: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type ClientBoxUploader = InstanceType<typeof ClientBoxUploader>;
18
+ export default ClientBoxUploader;
19
+ //# sourceMappingURL=ClientBoxUploader.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientBoxUploader.svelte.d.ts","sourceRoot":"","sources":["../../src/components/ClientBoxUploader.svelte.ts"],"names":[],"mappings":"AAgDA,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,iBAAiB;;kBAA+E,CAAC;AACrF,KAAK,iBAAiB,GAAG,YAAY,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAClE,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,60 @@
1
+ <script lang="ts">
2
+ import { useDropbox } from '../composables/useDropbox'
3
+ import DriveAuthFallback from './shared/DriveAuthFallback.svelte'
4
+ import DriveBrowser from './shared/DriveBrowser.svelte'
5
+
6
+ const {
7
+ user,
8
+ dropboxFiles: driveFiles,
9
+ logout,
10
+ token,
11
+ isAuthenticated,
12
+ authenticate,
13
+ isLoading,
14
+ path,
15
+ setPath,
16
+ isClickLoading,
17
+ handleClick,
18
+ selectedFiles,
19
+ showLoader,
20
+ handleSubmit,
21
+ handleCancelDownload,
22
+ onSelectCurrentFolder,
23
+ error,
24
+ hasMore,
25
+ isLoadingMore,
26
+ loadMore,
27
+ } = useDropbox()
28
+
29
+ async function handleSignOut() {
30
+ logout()
31
+ }
32
+ </script>
33
+
34
+ {#if !$isAuthenticated && !$token && !$isLoading}
35
+ <DriveAuthFallback
36
+ providerName="Dropbox"
37
+ onRetry={authenticate}
38
+ dataUpupSlot="dropbox-uploader"
39
+ />
40
+ {:else}
41
+ <DriveBrowser
42
+ {driveFiles}
43
+ {user}
44
+ {handleSignOut}
45
+ dataUpupSlot="dropbox-uploader"
46
+ {path}
47
+ {setPath}
48
+ {isClickLoading}
49
+ {handleClick}
50
+ {selectedFiles}
51
+ {showLoader}
52
+ {handleSubmit}
53
+ {handleCancelDownload}
54
+ {onSelectCurrentFolder}
55
+ {error}
56
+ {hasMore}
57
+ {isLoadingMore}
58
+ {loadMore}
59
+ />
60
+ {/if}
@@ -0,0 +1,19 @@
1
+ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
3
+ $$bindings?: Bindings;
4
+ } & Exports;
5
+ (internal: unknown, props: {
6
+ $$events?: Events;
7
+ $$slots?: Slots;
8
+ }): Exports & {
9
+ $set?: any;
10
+ $on?: any;
11
+ };
12
+ z_$$bindings?: Bindings;
13
+ }
14
+ declare const ClientDropboxUploader: $$__sveltets_2_IsomorphicComponent<Record<string, never>, {
15
+ [evt: string]: CustomEvent<any>;
16
+ }, {}, {}, string>;
17
+ type ClientDropboxUploader = InstanceType<typeof ClientDropboxUploader>;
18
+ export default ClientDropboxUploader;
19
+ //# sourceMappingURL=ClientDropboxUploader.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ClientDropboxUploader.svelte.d.ts","sourceRoot":"","sources":["../../src/components/ClientDropboxUploader.svelte.ts"],"names":[],"mappings":"AAgDA,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IACtG,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,qBAAqB;;kBAA+E,CAAC;AACzF,KAAK,qBAAqB,GAAG,YAAY,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAC1E,eAAe,qBAAqB,CAAC"}