GitHub Action commited on
Commit
a4093da
·
1 Parent(s): 5ef2825

Sync from GitHub: 3f27e5802e9ea1f29a6e07e9d09b3bd2ef3e27ec

Browse files
Files changed (32) hide show
  1. .gitattributes +6 -0
  2. .gitignore.backup +1 -1
  3. frontend/src/lib/components/Navbar.svelte +34 -0
  4. frontend/src/routes/+layout.svelte +117 -57
  5. frontend/src/routes/+page.svelte +721 -253
  6. frontend/src/routes/code-recorder/+page.svelte +27 -46
  7. frontend/src/routes/voice-cloning/+page.svelte +526 -164
  8. hfstudio/database.py +14 -0
  9. hfstudio/server.py +396 -11
  10. hfstudio/static/_app/immutable/assets/0.3AZkBLcv.css +1 -0
  11. hfstudio/static/_app/immutable/assets/2.CdRym-eY.css +1 -0
  12. hfstudio/static/_app/immutable/chunks/4G_mFUFB.js +1 -0
  13. hfstudio/static/_app/immutable/chunks/B7RJWGyJ.js +3 -0
  14. hfstudio/static/_app/immutable/chunks/BV8rDFhh.js +1 -0
  15. hfstudio/static/_app/immutable/chunks/BaOlNwUz.js +1 -0
  16. hfstudio/static/_app/immutable/chunks/Bm0csYZC.js +1 -0
  17. hfstudio/static/_app/immutable/chunks/C7BncMoR.js +6 -0
  18. hfstudio/static/_app/immutable/chunks/CbFjO8O8.js +1 -0
  19. hfstudio/static/_app/immutable/chunks/Dj_MM6zE.js +9 -0
  20. hfstudio/static/_app/immutable/chunks/QsMRfqzH.js +1 -0
  21. hfstudio/static/_app/immutable/entry/app.BBX27H-0.js +2 -0
  22. hfstudio/static/_app/immutable/entry/start.C4SfOwCE.js +1 -0
  23. hfstudio/static/_app/immutable/nodes/0.Ch20oj6r.js +4 -0
  24. hfstudio/static/_app/immutable/nodes/1.C7ooe2uD.js +1 -0
  25. hfstudio/static/_app/immutable/nodes/2.DEDaBsJG.js +38 -0
  26. hfstudio/static/_app/immutable/nodes/3.CX0V79eQ.js +23 -0
  27. hfstudio/static/_app/immutable/nodes/4.Blz4Bme4.js +12 -0
  28. hfstudio/static/_app/version.json +1 -1
  29. hfstudio/static/index.html +7 -7
  30. pyproject.toml +3 -1
  31. requirements.txt +4 -1
  32. requirements_space.txt +4 -1
.gitattributes CHANGED
@@ -7,3 +7,9 @@
7
  *.mp4 filter=lfs diff=lfs merge=lfs -text
8
  *.webm filter=lfs diff=lfs merge=lfs -text
9
  *.pdf filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
7
  *.mp4 filter=lfs diff=lfs merge=lfs -text
8
  *.webm filter=lfs diff=lfs merge=lfs -text
9
  *.pdf filter=lfs diff=lfs merge=lfs -text
10
+ hfstudio/static/assets/hf-logo.png filter=lfs diff=lfs merge=lfs -text
11
+ hfstudio/static/assets/hf-studio-logo.png filter=lfs diff=lfs merge=lfs -text
12
+ frontend/static/assets/hf-logo.png filter=lfs diff=lfs merge=lfs -text
13
+ frontend/static/assets/hf-studio-logo.png filter=lfs diff=lfs merge=lfs -text
14
+ hfstudio/static/samples/harvard.wav filter=lfs diff=lfs merge=lfs -text
15
+ frontend/static/samples/harvard.wav filter=lfs diff=lfs merge=lfs -text
.gitignore.backup CHANGED
@@ -10,7 +10,7 @@ dist/
10
  downloads/
11
  eggs/
12
  .eggs/
13
- lib/
14
  lib64/
15
  parts/
16
  sdist/
 
10
  downloads/
11
  eggs/
12
  .eggs/
13
+ # lib/ - commented out to allow frontend/src/lib/
14
  lib64/
15
  parts/
16
  sdist/
frontend/src/lib/components/Navbar.svelte ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script>
2
+ export let isLoggedIn = false;
3
+ export let username = '';
4
+ export let handleAuthAction = () => {};
5
+ export let flashButton = false;
6
+ export let pageTitle = 'HFStudio';
7
+ </script>
8
+
9
+ <!-- Top navbar -->
10
+ <div class="flex items-center justify-between px-4 py-4 border-b border-gray-200 min-h-[73px]">
11
+ <!-- Logo/Title -->
12
+ <div class="flex items-center gap-2">
13
+ <span class="font-semibold text-gray-900">{pageTitle}</span>
14
+ </div>
15
+
16
+ <!-- Sign in button -->
17
+ <button
18
+ on:click={handleAuthAction}
19
+ disabled={false}
20
+ class="px-4 py-2 bg-black text-white rounded-lg font-medium hover:bg-gray-800 transition-colors shadow-sm flex items-center justify-center gap-2 text-sm disabled:opacity-50 disabled:cursor-not-allowed relative overflow-hidden"
21
+ >
22
+ {#if flashButton}
23
+ <div
24
+ class="absolute inset-0 -left-full animate-sweep bg-gradient-to-r from-transparent via-orange-400/40 to-transparent"
25
+ ></div>
26
+ {/if}
27
+ {#if isLoggedIn}
28
+ <span class="relative z-10">👋 Logout, {username}</span>
29
+ {:else}
30
+ <img src="/assets/hf-logo.png" alt="HF Logo" class="w-4 h-4 relative z-10" />
31
+ <span class="relative z-10">Sign In</span>
32
+ {/if}
33
+ </button>
34
+ </div>
frontend/src/routes/+layout.svelte CHANGED
@@ -3,6 +3,7 @@
3
  import { Home, Settings, Github, Menu, Mic, Layout, Code } from 'lucide-svelte';
4
  import { onMount } from 'svelte';
5
  import { page } from '$app/stores';
 
6
  let sidebarOpen = true;
7
 
8
  // Initialize from server-side injected data with safe fallback
@@ -161,6 +162,17 @@
161
 
162
  // Removed old localStorage-based functions
163
 
 
 
 
 
 
 
 
 
 
 
 
164
  async function handleAuthAction() {
165
  if (isLoggedIn) {
166
  // Call backend logout endpoint to clear session
@@ -177,6 +189,9 @@
177
  sessionStorage.removeItem('oauth_state');
178
  isLoggedIn = false;
179
  username = '';
 
 
 
180
  } else {
181
  // Always use OAuth flow for authentication
182
  try {
@@ -190,7 +205,10 @@
190
  redirectUri = 'http://localhost:7860/auth/callback';
191
  }
192
 
193
- const oauthUrl = `https://huggingface.co/oauth/authorize?client_id=${config.client_id}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${encodeURIComponent(scopes)}&response_type=code&state=${Date.now()}`;
 
 
 
194
  window.location.href = oauthUrl;
195
  } catch (error) {
196
  // Fallback to manual token input if OAuth config fails
@@ -298,7 +316,8 @@
298
  </div>
299
 
300
  <nav class="p-2 text-sm flex-1">
301
- <div class="mt-2 mb-1 px-2 text-xs font-medium text-gray-500 uppercase">Tasks</div>
 
302
 
303
  <a
304
  href="/"
@@ -318,7 +337,6 @@
318
  <span>Voice Cloning</span>
319
  </a>
320
 
321
- <div class="mt-3 mb-1 px-2 text-xs font-medium text-gray-500 uppercase">Coming Soon</div>
322
  <button
323
  class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
324
  disabled
@@ -350,70 +368,112 @@
350
  <span>🔊</span>
351
  <span>Audio Enhancement</span>
352
  </button>
353
- </nav>
354
 
355
- <!-- Sign in with Hugging Face at bottom -->
356
- <div class="absolute bottom-4 left-0 right-0 px-2">
357
- {#if !isLoggedIn && showLoginPrompt}
358
- <!-- Login prompt message -->
359
- <div
360
- class="mb-3 px-3 py-2 bg-gradient-to-r from-amber-50 to-orange-50 rounded-lg border border-amber-200 relative"
361
- >
362
- <!-- Close button -->
363
- <button
364
- on:click={() => (showLoginPrompt = false)}
365
- class="absolute top-2 right-2 text-gray-400 hover:text-gray-600 transition-colors"
366
- aria-label="Dismiss"
367
- >
368
- <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
369
- <path
370
- stroke-linecap="round"
371
- stroke-linejoin="round"
372
- stroke-width="2"
373
- d="M6 18L18 6M6 6l12 12"
374
- />
375
- </svg>
376
- </button>
377
 
378
- <p class="text-sm font-medium text-gray-700 mb-1 pr-4">
379
- Hugging Face <span
380
- class="bg-gradient-to-r from-purple-500 via-pink-500 via-green-500 to-blue-500 bg-clip-text text-transparent font-bold"
381
- >PRO</span
382
- >
383
- </p>
384
- <p class="text-sm text-gray-600 pr-4">
385
- Sign in to with your Hugging Face <a
386
- href="https://huggingface.co/pro"
387
- target="_blank"
388
- class="text-amber-600 hover:text-amber-700 underline font-medium">PRO account</a
389
- > to get started with $2 of free API credits per month. You can add a billing method for
390
- additional pay-as-you-go usage &#10549;
391
- </p>
392
- </div>
393
- {/if}
394
 
395
  <button
396
- on:click={handleAuthAction}
397
- disabled={false}
398
- class="w-full px-6 py-3 bg-black text-white rounded-lg font-medium hover:bg-gray-800 transition-colors shadow-sm flex items-center justify-center gap-2 text-sm disabled:opacity-50 disabled:cursor-not-allowed relative overflow-hidden"
399
  >
400
- {#if flashButton}
401
- <div
402
- class="absolute inset-0 -left-full animate-sweep bg-gradient-to-r from-transparent via-orange-400/40 to-transparent"
403
- ></div>
404
- {/if}
405
- {#if isLoggedIn}
406
- <span class="relative z-10">👋 Logout, {username}</span>
407
- {:else}
408
- <img src="/assets/hf-logo.png" alt="HF Logo" class="w-5 h-5 relative z-10" />
409
- <span class="relative z-10">Sign In</span>
410
- {/if}
411
  </button>
412
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
413
  </aside>
414
 
415
  <!-- Main content -->
416
  <main class="flex-1 overflow-auto">
 
 
 
 
 
 
 
417
  <slot />
418
  </main>
419
 
 
3
  import { Home, Settings, Github, Menu, Mic, Layout, Code } from 'lucide-svelte';
4
  import { onMount } from 'svelte';
5
  import { page } from '$app/stores';
6
+ import Navbar from '$lib/components/Navbar.svelte';
7
  let sidebarOpen = true;
8
 
9
  // Initialize from server-side injected data with safe fallback
 
162
 
163
  // Removed old localStorage-based functions
164
 
165
+ function getPageTitle(pathname) {
166
+ switch (pathname) {
167
+ case '/':
168
+ return 'Text to Speech';
169
+ case '/voice-cloning':
170
+ return 'Voice Cloning';
171
+ default:
172
+ return 'HFStudio';
173
+ }
174
+ }
175
+
176
  async function handleAuthAction() {
177
  if (isLoggedIn) {
178
  // Call backend logout endpoint to clear session
 
189
  sessionStorage.removeItem('oauth_state');
190
  isLoggedIn = false;
191
  username = '';
192
+
193
+ // Refresh the page to ensure clean state
194
+ window.location.reload();
195
  } else {
196
  // Always use OAuth flow for authentication
197
  try {
 
205
  redirectUri = 'http://localhost:7860/auth/callback';
206
  }
207
 
208
+ // Store current path to return to after auth
209
+ const returnPath = window.location.pathname;
210
+
211
+ const oauthUrl = `https://huggingface.co/oauth/authorize?client_id=${config.client_id}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${encodeURIComponent(scopes)}&response_type=code&state=${encodeURIComponent(returnPath)}`;
212
  window.location.href = oauthUrl;
213
  } catch (error) {
214
  // Fallback to manual token input if OAuth config fails
 
316
  </div>
317
 
318
  <nav class="p-2 text-sm flex-1">
319
+ <!-- Audio Section -->
320
+ <div class="mt-2 mb-1 px-2 text-xs font-medium text-gray-500 uppercase">Audio</div>
321
 
322
  <a
323
  href="/"
 
337
  <span>Voice Cloning</span>
338
  </a>
339
 
 
340
  <button
341
  class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
342
  disabled
 
368
  <span>🔊</span>
369
  <span>Audio Enhancement</span>
370
  </button>
 
371
 
372
+ <!-- Image Section -->
373
+ <div class="mt-4 mb-1 px-2 text-xs font-medium text-gray-500 uppercase">Image</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
374
 
375
+ <button
376
+ class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
377
+ disabled
378
+ >
379
+ <span>🎨</span>
380
+ <span>Text to Image</span>
381
+ </button>
 
 
 
 
 
 
 
 
 
382
 
383
  <button
384
+ class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
385
+ disabled
 
386
  >
387
+ <span>🖼️</span>
388
+ <span>Image to Image</span>
 
 
 
 
 
 
 
 
 
389
  </button>
390
+
391
+ <button
392
+ class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
393
+ disabled
394
+ >
395
+ <span>✂️</span>
396
+ <span>Remove Background</span>
397
+ </button>
398
+
399
+ <button
400
+ class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
401
+ disabled
402
+ >
403
+ <span>🔍</span>
404
+ <span>Upscale Image</span>
405
+ </button>
406
+
407
+ <button
408
+ class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
409
+ disabled
410
+ >
411
+ <span>🎭</span>
412
+ <span>Face Swap</span>
413
+ </button>
414
+
415
+ <button
416
+ class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
417
+ disabled
418
+ >
419
+ <span>📝</span>
420
+ <span>Image to Text</span>
421
+ </button>
422
+
423
+ <!-- Video Section -->
424
+ <div class="mt-4 mb-1 px-2 text-xs font-medium text-gray-500 uppercase">Video</div>
425
+
426
+ <button
427
+ class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
428
+ disabled
429
+ >
430
+ <span>🎬</span>
431
+ <span>Text to Video</span>
432
+ </button>
433
+
434
+ <button
435
+ class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
436
+ disabled
437
+ >
438
+ <span>🎞️</span>
439
+ <span>Image to Video</span>
440
+ </button>
441
+
442
+ <button
443
+ class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
444
+ disabled
445
+ >
446
+ <span>✨</span>
447
+ <span>Video Enhancement</span>
448
+ </button>
449
+
450
+ <button
451
+ class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
452
+ disabled
453
+ >
454
+ <span>🎤</span>
455
+ <span>Lip Sync</span>
456
+ </button>
457
+
458
+ <button
459
+ class="w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"
460
+ disabled
461
+ >
462
+ <span>🗣️</span>
463
+ <span>Video Dubbing</span>
464
+ </button>
465
+ </nav>
466
  </aside>
467
 
468
  <!-- Main content -->
469
  <main class="flex-1 overflow-auto">
470
+ <Navbar
471
+ {isLoggedIn}
472
+ {username}
473
+ {handleAuthAction}
474
+ {flashButton}
475
+ pageTitle={getPageTitle($page.url.pathname)}
476
+ />
477
  <slot />
478
  </main>
479
 
frontend/src/routes/+page.svelte CHANGED
@@ -15,13 +15,18 @@
15
  Layout,
16
  } from 'lucide-svelte';
17
  import { onMount } from 'svelte';
 
 
 
18
 
19
  let text = `In a hole in the ground, there lived a hobbit. Not a nasty, dirty, wet hole, filled with the ends of worms and an oozy smell, nor yet a dry, bare, sandy hole with nothing in it to sit down on or to eat: it was a hobbit-hole, and that means comfort.`;
20
  let selectedVoice = 'Andrew';
21
  let selectedModel = 'Chatterbox';
22
  let modelDropdownOpen = false;
 
23
  let isGenerating = false;
24
  let audioUrl = null;
 
25
  let exaggeration = 0.25;
26
  let temperature = 0.7;
27
  let isPlaying = false;
@@ -35,11 +40,22 @@
35
  let errorMessage = '';
36
  let errorDetails = '';
37
  let historyCount = 0;
 
 
 
 
 
 
 
 
 
 
38
 
39
  const famousBookOpeners = [
40
  'It was the best of times, it was the worst of times. It was the age of wisdom, it was the age of foolishness.',
41
  'It is a truth universally acknowledged, that a single man in possession of a good fortune, must be in want of a wife.',
42
  'All happy families are alike; each unhappy family is unhappy in its own way.',
 
43
  ];
44
  let currentBookIndex = 0;
45
 
@@ -52,15 +68,15 @@
52
  {
53
  id: 'andrew',
54
  name: 'Andrew',
55
- description: 'Older British man who speaks clearly and kindly',
56
  sample: '/voices/andrew.mp3',
57
  preview_url:
58
  'https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/andrew.mp3',
59
  },
60
  {
61
  id: 'lily',
62
- name: 'Jasmine',
63
- description: 'Warm, conversational tone of a woman in her 30s',
64
  sample: '/voices/lily.mp3',
65
  preview_url:
66
  'https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/lily.mp3',
@@ -88,7 +104,7 @@
88
 
89
  const response = await fetch('/api/auth/user', { credentials: 'include' });
90
  if (!response.ok) {
91
- window.dispatchEvent(new CustomEvent('show-login-prompt'));
92
  return;
93
  }
94
 
@@ -128,6 +144,7 @@
128
 
129
  if (result.success && result.audio_url) {
130
  audioUrl = result.audio_url;
 
131
 
132
  // Save to code recorder history
133
  await saveToHistory(requestBody, result);
@@ -239,12 +256,19 @@
239
  event.preventDefault();
240
  generateSpeech();
241
  }
 
 
 
 
242
  }
243
 
244
  function handleClickOutside(event) {
245
  if (!event.target.closest('.model-dropdown')) {
246
  modelDropdownOpen = false;
247
  }
 
 
 
248
  }
249
 
250
  function showError(message, details = '') {
@@ -266,13 +290,32 @@
266
 
267
  async function saveToHistory(requestBody, result) {
268
  try {
269
- const pythonCode = `# Generate speech
270
- client.text_to_speech(
271
- text="${requestBody.text.replace(/"/g, '\\"')}",
272
- voice_id="${requestBody.voice_id}",
273
- model_id="${requestBody.model_id}",
274
- exaggeration=${requestBody.parameters.exaggeration},
275
- temperature=${requestBody.parameters.temperature}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
276
  )`;
277
 
278
  await fetch('/api/history/save', {
@@ -285,10 +328,10 @@ client.text_to_speech(
285
  result_data: {
286
  url: result.audio_url,
287
  title: audioTitle,
288
- type: 'audio'
289
  },
290
- entry_type: 'generation'
291
- })
292
  });
293
 
294
  // Update history count
@@ -316,8 +359,171 @@ client.text_to_speech(
316
  }
317
  }
318
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
  onMount(async () => {
320
  await loadHistoryCount();
 
321
  });
322
  </script>
323
 
@@ -325,30 +531,20 @@ client.text_to_speech(
325
  <title>Text to Speech - HFStudio</title>
326
  </svelte:head>
327
 
328
- <div class="flex flex-col h-full" on:click={handleClickOutside}>
329
- <!-- Top navbar -->
330
- <div class="flex items-center justify-end px-4 py-4 border-b border-gray-200 min-h-[73px]">
331
- <a
332
- href="/code-recorder"
333
- class="px-3 py-1.5 text-sm font-medium rounded transition-colors text-gray-600 hover:bg-gray-50 flex items-center gap-1 bg-gray-100"
334
- >
335
- <Code size={14} />
336
- Code Recorder
337
- {#if historyCount > 0}
338
- <span class="ml-1 px-1.5 py-0.5 bg-gray-500 text-white text-xs rounded-full min-w-[18px] text-center">
339
- {historyCount}
340
- </span>
341
- {/if}
342
- </a>
343
- </div>
344
-
345
  <!-- Main content area -->
346
  <div class="flex-1 flex">
347
  <!-- Main content area -->
348
- <div class="flex-1 flex flex-col p-6 relative">
349
  <!-- Text input area -->
350
- <div class="flex-1 relative">
351
- <div class="absolute -top-2 right-0 flex items-center gap-2 z-10">
352
  <span class="text-sm text-gray-400">
353
  {text.length.toLocaleString()} / 1,000 characters
354
  </span>
@@ -363,267 +559,516 @@ client.text_to_speech(
363
  <textarea
364
  bind:value={text}
365
  maxlength="1000"
366
- class="w-full h-full p-6 bg-white resize-none border-0 focus:outline-none text-gray-900 text-base leading-relaxed"
367
  placeholder="Type the text you'd like to convert to spoken audio here..."
368
- autofocus
369
  on:keydown={handleKeyDown}
 
370
  />
371
  </div>
372
 
373
- <!-- Generate button at bottom -->
374
- <div class="absolute bottom-4 left-0 right-0 px-2">
375
- <button
376
- on:click={generateSpeech}
377
- disabled={isGenerating || !text.trim()}
378
- class="w-full px-6 py-3 bg-gradient-to-r from-amber-400 to-orange-500 text-white rounded-lg font-medium hover:from-amber-500 hover:to-orange-600 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2 shadow-sm"
379
- >
380
- {#if isGenerating}
381
- <Loader2 size={20} class="animate-spin" />
382
- Generating...
383
- {:else}
384
- <Play size={20} />
385
- Generate speech
386
- {/if}
387
- </button>
388
- </div>
 
 
 
 
 
 
 
 
 
 
 
389
 
390
- <!-- Generated audio section -->
391
- {#if audioUrl}
392
- <div class="p-4 border border-gray-200 rounded-lg bg-white mb-6">
393
- <!-- Audio title and voice info -->
394
- <div class="flex items-center gap-3 mb-4">
395
- <div class="w-2 h-2 bg-green-500 rounded-full"></div>
396
- <div class="flex-1">
397
- <h3 class="font-medium text-gray-900 text-sm">{audioTitle}</h3>
398
- <p class="text-xs text-gray-500">{selectedVoice} Created 1 second ago</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
399
  </div>
400
- <!-- Mini action buttons -->
401
- <div class="flex items-center gap-2">
 
 
 
 
 
402
  <button
403
- on:click={shareAudio}
404
- class="flex items-center gap-1.5 px-3 py-1.5 text-sm border border-gray-200 rounded-md hover:bg-gray-50 transition-colors"
 
 
 
405
  >
406
- <Share size={14} class="text-gray-600" />
407
- <span class="text-gray-700">Share</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
408
  </button>
 
 
409
  <button
410
- on:click={downloadAudio}
411
- class="flex items-center gap-1.5 px-3 py-1.5 text-sm border border-gray-200 rounded-md hover:bg-gray-50 transition-colors"
 
 
 
412
  >
413
- <span class="text-gray-700">Download</span>
414
- <Download size={14} class="text-gray-600" />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
415
  </button>
416
- </div>
417
- </div>
418
 
419
- <!-- Mini audio controls -->
420
- <div class="flex items-center gap-3 mb-4">
421
- <!-- Play/Pause button -->
422
- <button
423
- on:click={togglePlayPause}
424
- class="w-8 h-8 bg-black rounded-full flex items-center justify-center hover:bg-gray-800 transition-colors"
425
- >
426
- {#if isPlaying}
427
- <div class="pause-filled text-white"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
428
  {:else}
429
- <Play size={14} class="text-white ml-0.5" />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
430
  {/if}
431
- </button>
 
432
 
433
- <!-- Progress bar -->
434
- <div class="flex-1 flex items-center gap-2">
435
- <span class="text-xs text-gray-500 font-mono">{formatTime(currentTime)}</span>
436
- <div class="flex-1 h-1 bg-gray-200 rounded-full cursor-pointer">
437
- <div
438
- class="h-full bg-gradient-to-r from-amber-400 to-orange-500 rounded-full transition-all"
439
- style="width: {(currentTime / duration) * 100}%"
440
- ></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
441
  </div>
442
- <span class="text-xs text-gray-500 font-mono">{formatTime(duration)}</span>
443
  </div>
444
- </div>
445
 
446
- <!-- Hidden audio element -->
447
- {#if audioUrl}
448
- <audio
449
- bind:this={audioElement}
450
- src={audioUrl}
451
- on:loadedmetadata={handleAudioLoad}
452
- on:timeupdate={handleTimeUpdate}
453
- on:play={handlePlay}
454
- on:pause={handlePause}
455
- style="display: none;"
456
- />
457
- {/if}
 
 
 
 
 
 
 
 
 
 
 
458
  </div>
459
- {/if}
460
- </div>
461
 
462
- <!-- Right panel -->
463
- <div class="w-80 border-l border-gray-200 bg-white p-3 overflow-y-auto">
464
- <!-- Model selector -->
465
- <div class="mb-4 relative model-dropdown">
466
- <h3 class="text-sm font-medium text-gray-900 mb-2">Model</h3>
467
- <button
468
- on:click={() => (modelDropdownOpen = !modelDropdownOpen)}
469
- class="w-full p-2.5 border border-gray-200 rounded-lg bg-white text-xs focus:outline-none focus:ring-2 focus:ring-amber-400 focus:border-transparent appearance-none bg-no-repeat bg-right pr-10 shadow-sm text-left flex items-center justify-between"
470
- >
471
- <span>
472
- {#each models as model}
473
- {#if model.name === selectedModel}
474
- {model.name}{#if model.badge}&nbsp;<span class="text-xs text-gray-500"
475
- >({model.badge})</span
476
- >{/if}
477
- {/if}
478
- {/each}
479
- </span>
480
- <ChevronDown size={14} class="text-gray-500" />
481
- </button>
482
 
483
- {#if modelDropdownOpen}
 
 
 
 
484
  <div
485
- class="absolute top-full left-0 right-0 mt-1 bg-white border border-gray-200 rounded-lg shadow-lg z-10"
486
  >
487
- {#each models as model}
488
- <button
489
- class="w-full px-3 py-1.5 text-left transition-colors text-xs {model.disabled
490
- ? 'opacity-50 cursor-not-allowed'
491
- : 'hover:bg-gray-50'} {model.name === selectedModel ? 'bg-gray-100' : ''}"
492
- disabled={model.disabled}
493
- on:click={() => {
494
- if (!model.disabled) {
495
- selectedModel = model.name;
496
- modelDropdownOpen = false;
497
- }
498
- }}
 
 
 
 
 
 
 
 
499
  >
500
- {model.name}{#if model.badge}&nbsp;<span class="text-xs text-gray-500"
501
- >({model.badge})</span
502
- >{/if}
503
- </button>
504
- {/each}
 
 
 
 
505
  </div>
506
  {/if}
507
 
508
- <!-- Pricing info -->
509
- <div class="mt-1.5 text-xs text-gray-500">
510
- Estimated $0.025 per 1000 characters <a
511
- href="https://huggingface.co/settings/billing"
512
- target="_blank"
513
- class="text-amber-600 hover:text-amber-700 underline">Billing ⤴</a
514
- >
515
  </div>
516
- </div>
517
 
518
- <div class="mb-4">
519
- <div class="mb-2">
520
- <h3 class="text-sm font-medium text-gray-900">Voice</h3>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
521
  </div>
522
 
523
- <div class="space-y-1.5">
524
- {#each voices as voice}
525
- <button
526
- class="w-full flex items-center justify-between p-1.5 rounded-lg hover:bg-gray-50 transition-colors text-left group border border-transparent
527
- {voice.name === selectedVoice ? 'bg-gray-100 border-gray-200' : ''}"
528
- on:click={() => (selectedVoice = voice.name)}
529
  >
530
- <div class="flex items-center gap-2.5 flex-1 min-w-0">
531
- <div
532
- class="w-8 h-8 bg-gradient-to-br from-amber-400 to-orange-500 rounded-full flex items-center justify-center text-white text-xs font-semibold flex-shrink-0"
533
- >
534
- {voice.name[0]}
535
- </div>
536
- <div class="flex-1 min-w-0">
537
- <div class="text-xs font-medium text-gray-900">{voice.name}</div>
538
- <div class="text-xs text-gray-500 leading-relaxed">
539
- {voice.description}
540
- </div>
541
- </div>
542
  </div>
543
  <button
544
- on:click={(e) => playSampleVoice(voice, e)}
545
- class="p-1.5 rounded-full hover:bg-gray-200 transition-colors flex-shrink-0 ml-2 w-7 h-7 flex items-center justify-center"
546
- title="Play sample"
547
  >
548
- {#if playingSampleVoice === voice.name}
549
- <Pause size={14} class="text-gray-600" />
550
- {:else}
551
- <Play size={14} class="text-gray-600" />
552
- {/if}
553
  </button>
554
- </button>
555
- {/each}
556
- </div>
557
- </div>
558
-
559
- <div class="space-y-3 pt-3 border-t border-gray-200">
560
- <!-- Exaggeration control -->
561
- <div>
562
- <div class="flex justify-between mb-0.5">
563
- <label for="exaggeration-slider" class="text-xs font-medium text-gray-700"
564
- >Exaggeration</label
565
- >
566
- <span class="text-xs text-gray-500">{exaggeration.toFixed(2)}</span>
567
- </div>
568
- <input
569
- id="exaggeration-slider"
570
- type="range"
571
- bind:value={exaggeration}
572
- min="0"
573
- max="1"
574
- step="0.01"
575
- class="w-full h-1.5 bg-gray-200 rounded-lg appearance-none cursor-pointer slider-hf"
576
- />
577
- <div class="flex justify-between text-xs text-gray-400 mt-0.5">
578
- <span>None</span>
579
- <span>Exaggerated</span>
580
  </div>
581
- </div>
582
 
583
- <!-- Stability control -->
584
- <div>
585
- <div class="flex justify-between mb-0.5">
586
- <label for="temperature-slider" class="text-xs font-medium text-gray-700"
587
- >Stability</label
588
  >
589
- <span class="text-xs text-gray-500">{temperature.toFixed(2)}</span>
590
- </div>
591
- <input
592
- id="temperature-slider"
593
- type="range"
594
- bind:value={temperature}
595
- min="0"
596
- max="1"
597
- step="0.01"
598
- class="w-full h-1.5 bg-gray-200 rounded-lg appearance-none cursor-pointer slider-hf"
599
- />
600
- <div class="flex justify-between text-xs text-gray-400 mt-0.5">
601
- <span>More stable</span>
602
- <span>More variable</span>
 
 
 
 
 
603
  </div>
604
- </div>
605
- </div>
606
 
607
- <!-- GitHub link at bottom -->
608
- <div class="mt-auto pt-3 flex justify-end">
609
- <a
610
- href="https://github.com/gradio-app/hfstudio"
611
- target="_blank"
612
- class="p-2 text-gray-400 hover:text-gray-600 transition-colors"
613
- title="View on GitHub"
614
- >
615
- <svg
616
- xmlns="http://www.w3.org/2000/svg"
617
- width="20"
618
- height="20"
619
- viewBox="0 0 24 24"
620
- fill="currentColor"
621
- >
622
- <path
623
- d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"
624
- />
625
- </svg>
626
- </a>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
627
  </div>
628
  </div>
629
  </div>
@@ -686,7 +1131,30 @@ client.text_to_speech(
686
  </div>
687
  {/if}
688
 
 
 
 
 
 
 
 
 
 
689
  <style>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
690
  .pause-filled::after {
691
  content: '';
692
  width: 3px;
@@ -703,4 +1171,4 @@ client.text_to_speech(
703
  display: inline-block;
704
  margin-right: 2px;
705
  }
706
- </style>
 
15
  Layout,
16
  } from 'lucide-svelte';
17
  import { onMount } from 'svelte';
18
+ import Prism from 'prismjs';
19
+ import 'prismjs/components/prism-python';
20
+ import 'prismjs/components/prism-bash';
21
 
22
  let text = `In a hole in the ground, there lived a hobbit. Not a nasty, dirty, wet hole, filled with the ends of worms and an oozy smell, nor yet a dry, bare, sandy hole with nothing in it to sit down on or to eat: it was a hobbit-hole, and that means comfort.`;
23
  let selectedVoice = 'Andrew';
24
  let selectedModel = 'Chatterbox';
25
  let modelDropdownOpen = false;
26
+ let voiceDropdownOpen = false;
27
  let isGenerating = false;
28
  let audioUrl = null;
29
+ let generationTime = 0;
30
  let exaggeration = 0.25;
31
  let temperature = 0.7;
32
  let isPlaying = false;
 
40
  let errorMessage = '';
41
  let errorDetails = '';
42
  let historyCount = 0;
43
+ let userVoices = [];
44
+ let isLoadingVoices = false;
45
+ let showLoginPrompt = false;
46
+ let copyNotification = null;
47
+ let mode = 'api';
48
+
49
+ // Live code variables
50
+ let setupCode = '';
51
+ let pythonCode = '';
52
+ let codeUpdateCounter = 0;
53
 
54
  const famousBookOpeners = [
55
  'It was the best of times, it was the worst of times. It was the age of wisdom, it was the age of foolishness.',
56
  'It is a truth universally acknowledged, that a single man in possession of a good fortune, must be in want of a wife.',
57
  'All happy families are alike; each unhappy family is unhappy in its own way.',
58
+ 'In a hole in the ground, there lived a hobbit. Not a nasty, dirty, wet hole, filled with the ends of worms and an oozy smell, nor yet a dry, bare, sandy hole with nothing in it to sit down on or to eat: it was a hobbit-hole, and that means comfort.',
59
  ];
60
  let currentBookIndex = 0;
61
 
 
68
  {
69
  id: 'andrew',
70
  name: 'Andrew',
71
+ description: 'Older British man who speaks clearly and warmly.',
72
  sample: '/voices/andrew.mp3',
73
  preview_url:
74
  'https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/andrew.mp3',
75
  },
76
  {
77
  id: 'lily',
78
+ name: 'Lily',
79
+ description: 'Friendly, conversational tone of a woman in her 30s',
80
  sample: '/voices/lily.mp3',
81
  preview_url:
82
  'https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/lily.mp3',
 
104
 
105
  const response = await fetch('/api/auth/user', { credentials: 'include' });
106
  if (!response.ok) {
107
+ showLoginPrompt = true;
108
  return;
109
  }
110
 
 
144
 
145
  if (result.success && result.audio_url) {
146
  audioUrl = result.audio_url;
147
+ generationTime = result.generation_time || 0;
148
 
149
  // Save to code recorder history
150
  await saveToHistory(requestBody, result);
 
256
  event.preventDefault();
257
  generateSpeech();
258
  }
259
+ if (event.key === 'Escape') {
260
+ modelDropdownOpen = false;
261
+ voiceDropdownOpen = false;
262
+ }
263
  }
264
 
265
  function handleClickOutside(event) {
266
  if (!event.target.closest('.model-dropdown')) {
267
  modelDropdownOpen = false;
268
  }
269
+ if (!event.target.closest('.voice-dropdown')) {
270
+ voiceDropdownOpen = false;
271
+ }
272
  }
273
 
274
  function showError(message, details = '') {
 
290
 
291
  async function saveToHistory(requestBody, result) {
292
  try {
293
+ // Get the actual voice URL
294
+ let voiceUrl = null;
295
+
296
+ // Check if this is a user voice (cloned voice)
297
+ const userVoice = userVoices.find((v) => v.voice_name === selectedVoice);
298
+ if (userVoice && userVoice.sample_url) {
299
+ voiceUrl = userVoice.sample_url;
300
+ } else {
301
+ // Check built-in voices
302
+ const builtInVoice = voices.find((v) => v.name === selectedVoice);
303
+ if (builtInVoice && builtInVoice.preview_url) {
304
+ voiceUrl = builtInVoice.preview_url;
305
+ }
306
+ }
307
+
308
+ const pythonCode = `audio_bytes = client.text_to_speech(
309
+ "${requestBody.text.replace(/"/g, '\\"')}",
310
+ extra_body={
311
+ "exaggeration": ${requestBody.parameters.exaggeration},
312
+ "temperature": ${requestBody.parameters.temperature}${
313
+ voiceUrl
314
+ ? `,
315
+ "audio_url": "${voiceUrl}"`
316
+ : ''
317
+ }
318
+ }
319
  )`;
320
 
321
  await fetch('/api/history/save', {
 
328
  result_data: {
329
  url: result.audio_url,
330
  title: audioTitle,
331
+ type: 'audio',
332
  },
333
+ entry_type: 'generation',
334
+ }),
335
  });
336
 
337
  // Update history count
 
359
  }
360
  }
361
 
362
+ async function loadUserVoices() {
363
+ try {
364
+ isLoadingVoices = true;
365
+ const response = await fetch('/api/voice/user-voices', {
366
+ method: 'GET',
367
+ credentials: 'include',
368
+ });
369
+
370
+ if (response.ok) {
371
+ const data = await response.json();
372
+ userVoices = data.voices || [];
373
+ } else {
374
+ userVoices = [];
375
+ }
376
+ } catch (error) {
377
+ console.error('Error loading user voices:', error);
378
+ userVoices = [];
379
+ } finally {
380
+ isLoadingVoices = false;
381
+ }
382
+ }
383
+
384
+ function handleAuthAction() {
385
+ // Get OAuth config and redirect to HuggingFace OAuth
386
+ const clientId = '4831a493-1dbc-4dd4-9bb3-c3b41d2e96ba';
387
+ const scopes = 'inference-api manage-repos';
388
+
389
+ // Store current path to return to after auth
390
+ const returnPath = window.location.pathname;
391
+
392
+ // Determine the correct callback URL based on environment
393
+ let redirectUri;
394
+ if (window.location.hostname === 'localhost') {
395
+ // Development: use backend port for callback
396
+ redirectUri = 'http://localhost:7860/auth/callback';
397
+ } else {
398
+ // Production: use current origin
399
+ redirectUri = `${window.location.origin}/auth/callback`;
400
+ }
401
+
402
+ const authUrl = `https://huggingface.co/oauth/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${encodeURIComponent(scopes)}&response_type=code&state=${encodeURIComponent(returnPath)}`;
403
+
404
+ window.location.href = authUrl;
405
+ }
406
+
407
+ function generateSetupCode() {
408
+ if (mode === 'local') {
409
+ return `pip install huggingface-hub hfstudio uv
410
+ hfstudio start ${selectedModel.toLowerCase()} --port 7861`;
411
+ } else {
412
+ return `pip install huggingface-hub`;
413
+ }
414
+ }
415
+
416
+ function generateClientInitCode() {
417
+ if (mode === 'local') {
418
+ const port = 7861;
419
+ return `client = InferenceClient(base_url="http://localhost:${port}/api/v1")`;
420
+ } else {
421
+ const endpointModel =
422
+ selectedModel.toLowerCase() === 'chatterbox'
423
+ ? 'ResembleAI/chatterbox'
424
+ : selectedModel.toLowerCase();
425
+ return `client = InferenceClient(
426
+ api_key="YOUR_HF_TOKEN", # Get your token from https://huggingface.co/settings/tokens
427
+ model="${endpointModel}",
428
+ )`;
429
+ }
430
+ }
431
+
432
+ function generateImportCode() {
433
+ const clientCode = generateClientInitCode();
434
+
435
+ if (mode === 'local') {
436
+ return `from huggingface_hub import InferenceClient
437
+
438
+ ${clientCode}`;
439
+ } else {
440
+ return `from huggingface_hub import InferenceClient
441
+
442
+ ${clientCode}`;
443
+ }
444
+ }
445
+
446
+ function generatePythonCode() {
447
+ // Get the actual voice URL
448
+ let voiceUrl = null;
449
+
450
+ // Check if this is a user voice (cloned voice)
451
+ if (selectedVoice === 'Yours' && userVoices.length > 0) {
452
+ const userVoice = userVoices[0]; // Use the first (latest) user voice
453
+ if (userVoice && userVoice.sample_url) {
454
+ voiceUrl = userVoice.sample_url;
455
+ }
456
+ } else {
457
+ // Check built-in voices
458
+ const builtInVoice = voices.find((v) => v.name === selectedVoice);
459
+ if (builtInVoice && builtInVoice.preview_url) {
460
+ voiceUrl = builtInVoice.preview_url;
461
+ }
462
+ }
463
+
464
+ const currentText = text || 'Hello, this is a sample text.';
465
+
466
+ // Generate imports directly here to avoid function call issues
467
+ const clientCode = generateClientInitCode();
468
+ const imports = `from huggingface_hub import InferenceClient
469
+
470
+ ${clientCode}`;
471
+
472
+ return `${imports}
473
+
474
+ audio_bytes = client.text_to_speech(
475
+ "${currentText.replace(/"/g, '\\"')}",
476
+ extra_body={
477
+ "exaggeration": ${exaggeration},
478
+ "temperature": ${temperature}${
479
+ voiceUrl
480
+ ? `,
481
+ "audio_url": "${voiceUrl}"`
482
+ : ''
483
+ }
484
+ }
485
+ )`;
486
+ }
487
+
488
+ function copyToClipboard(textToCopy, message = 'Copied to clipboard!') {
489
+ navigator.clipboard.writeText(textToCopy).then(() => {
490
+ copyNotification = message;
491
+ setTimeout(() => {
492
+ copyNotification = null;
493
+ }, 2000);
494
+ });
495
+ }
496
+
497
+ function copyAllCode() {
498
+ const parts = [];
499
+
500
+ if (setupCode) {
501
+ const isTerminalCommand =
502
+ setupCode.includes('pip install') || setupCode.includes('hfstudio start');
503
+ const language = isTerminalCommand ? 'bash' : '';
504
+ parts.push(`## Setup (Run in Terminal)\n\n\`\`\`${language}\n${setupCode}\n\`\`\``);
505
+ }
506
+
507
+ if (pythonCode) {
508
+ parts.push(`## Python Code\n\n\`\`\`python\n${pythonCode}\n\`\`\``);
509
+ }
510
+
511
+ const markdownContent = parts.join('\n\n');
512
+ copyToClipboard(markdownContent, 'All code copied as Markdown!');
513
+ }
514
+
515
+ // Reactive statements for live code updates
516
+ $: {
517
+ // This block will re-run whenever any of these variables change
518
+ (text, selectedVoice, selectedModel, exaggeration, temperature, userVoices, mode);
519
+ setupCode = generateSetupCode();
520
+ pythonCode = generatePythonCode();
521
+ codeUpdateCounter++;
522
+ }
523
+
524
  onMount(async () => {
525
  await loadHistoryCount();
526
+ await loadUserVoices();
527
  });
528
  </script>
529
 
 
531
  <title>Text to Speech - HFStudio</title>
532
  </svelte:head>
533
 
534
+ <div
535
+ class="flex flex-col h-full"
536
+ on:click={handleClickOutside}
537
+ on:keydown={handleKeyDown}
538
+ role="main"
539
+ tabindex="-1"
540
+ >
 
 
 
 
 
 
 
 
 
 
541
  <!-- Main content area -->
542
  <div class="flex-1 flex">
543
  <!-- Main content area -->
544
+ <div class="flex-1 flex flex-col p-6">
545
  <!-- Text input area -->
546
+ <div class="relative mb-4">
547
+ <div class="absolute top-3 right-3 flex items-center gap-2 z-10">
548
  <span class="text-sm text-gray-400">
549
  {text.length.toLocaleString()} / 1,000 characters
550
  </span>
 
559
  <textarea
560
  bind:value={text}
561
  maxlength="1000"
562
+ class="w-full h-80 pt-10 px-6 pb-6 bg-white resize-none border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-400 focus:border-transparent text-gray-900 text-lg leading-relaxed"
563
  placeholder="Type the text you'd like to convert to spoken audio here..."
 
564
  on:keydown={handleKeyDown}
565
+ autofocus
566
  />
567
  </div>
568
 
569
+ <!-- Settings panel above generate button -->
570
+ <div class="p-4 border border-gray-200 rounded-lg bg-white mb-6">
571
+ <div class="grid grid-cols-1 lg:grid-cols-[1fr_1.4fr_1fr] gap-6">
572
+ <!-- Model selector -->
573
+ <div class="model-dropdown">
574
+ <h3 class="text-sm font-medium text-gray-900 mb-2">Model</h3>
575
+ <div class="relative">
576
+ <button
577
+ on:click={() => (modelDropdownOpen = !modelDropdownOpen)}
578
+ class="w-full p-3 border border-gray-200 bg-white text-sm focus:outline-none focus:ring-2 focus:ring-amber-400 focus:border-transparent shadow-sm text-left flex items-center justify-between {modelDropdownOpen
579
+ ? 'rounded-b-lg border-t-0'
580
+ : 'rounded-lg'}"
581
+ >
582
+ <span>
583
+ {#each models as model}
584
+ {#if model.name === selectedModel}
585
+ {model.name}{#if model.badge}&nbsp;<span class="text-sm text-gray-500"
586
+ >({model.badge})</span
587
+ >{/if}
588
+ {/if}
589
+ {/each}
590
+ </span>
591
+ <ChevronDown
592
+ size={14}
593
+ class="text-gray-500 transition-transform {modelDropdownOpen ? 'rotate-180' : ''}"
594
+ />
595
+ </button>
596
 
597
+ {#if modelDropdownOpen}
598
+ <div
599
+ class="absolute bottom-full left-0 right-0 border border-gray-200 border-b-0 bg-white shadow-lg rounded-t-lg overflow-hidden z-20"
600
+ >
601
+ {#each models as model}
602
+ <button
603
+ class="w-full px-3 py-2.5 text-left transition-colors text-sm {model.disabled
604
+ ? 'opacity-50 cursor-not-allowed'
605
+ : 'hover:bg-gray-50'} {model.name === selectedModel ? 'bg-gray-100' : ''}"
606
+ disabled={model.disabled}
607
+ on:click={() => {
608
+ if (!model.disabled) {
609
+ selectedModel = model.name;
610
+ modelDropdownOpen = false;
611
+ }
612
+ }}
613
+ >
614
+ {model.name}{#if model.badge}&nbsp;<span class="text-sm text-gray-500"
615
+ >({model.badge})</span
616
+ >{/if}
617
+ </button>
618
+ {/each}
619
+ </div>
620
+ {/if}
621
+ </div>
622
+
623
+ <!-- Pricing info -->
624
+ <div class="mt-1.5 text-xs text-gray-500 text-right">
625
+ $0.025 per 1000 chars • <a
626
+ href="https://huggingface.co/settings/billing"
627
+ target="_blank"
628
+ class="text-amber-600 hover:text-amber-700 underline">Billing ⤴</a
629
+ >
630
  </div>
631
+ </div>
632
+
633
+ <!-- Voice selector -->
634
+ <div>
635
+ <h3 class="text-sm font-medium text-gray-900 mb-2">Voice</h3>
636
+ <div class="grid grid-cols-2 gap-2">
637
+ <!-- Andrew -->
638
  <button
639
+ class="p-3 border rounded-lg transition-colors text-left hover:bg-gray-50 {selectedVoice ===
640
+ 'Andrew'
641
+ ? 'border-amber-400 bg-amber-50'
642
+ : 'border-gray-200'}"
643
+ on:click={() => (selectedVoice = 'Andrew')}
644
  >
645
+ <div class="flex items-center justify-between mb-1">
646
+ <div class="flex items-center gap-2">
647
+ <div
648
+ class="w-6 h-6 bg-gradient-to-br from-amber-400 to-orange-500 rounded-full flex items-center justify-center text-white text-xs font-semibold"
649
+ >
650
+ A
651
+ </div>
652
+ <span class="text-sm font-medium">Andrew</span>
653
+ </div>
654
+ <button
655
+ on:click={(e) =>
656
+ playSampleVoice({ name: 'Andrew', sample: '/voices/andrew.mp3' }, e)}
657
+ class="p-1 rounded-full hover:bg-gray-200 transition-colors w-5 h-5 flex items-center justify-center"
658
+ title="Play sample"
659
+ >
660
+ {#if playingSampleVoice === 'Andrew'}
661
+ <Pause size={10} class="text-gray-600" />
662
+ {:else}
663
+ <Play size={10} class="text-gray-600" />
664
+ {/if}
665
+ </button>
666
+ </div>
667
  </button>
668
+
669
+ <!-- Lily -->
670
  <button
671
+ class="p-3 border rounded-lg transition-colors text-left hover:bg-gray-50 {selectedVoice ===
672
+ 'Lily'
673
+ ? 'border-amber-400 bg-amber-50'
674
+ : 'border-gray-200'}"
675
+ on:click={() => (selectedVoice = 'Lily')}
676
  >
677
+ <div class="flex items-center justify-between mb-1">
678
+ <div class="flex items-center gap-2">
679
+ <div
680
+ class="w-6 h-6 bg-gradient-to-br from-amber-400 to-orange-500 rounded-full flex items-center justify-center text-white text-xs font-semibold"
681
+ >
682
+ L
683
+ </div>
684
+ <span class="text-sm font-medium">Lily</span>
685
+ </div>
686
+ <button
687
+ on:click={(e) =>
688
+ playSampleVoice({ name: 'Lily', sample: '/voices/lily.mp3' }, e)}
689
+ class="p-1 rounded-full hover:bg-gray-200 transition-colors w-5 h-5 flex items-center justify-center"
690
+ title="Play sample"
691
+ >
692
+ {#if playingSampleVoice === 'Lily'}
693
+ <Pause size={10} class="text-gray-600" />
694
+ {:else}
695
+ <Play size={10} class="text-gray-600" />
696
+ {/if}
697
+ </button>
698
+ </div>
699
  </button>
 
 
700
 
701
+ <!-- Pirate -->
702
+ <button
703
+ class="p-3 border rounded-lg transition-colors text-left hover:bg-gray-50 {selectedVoice ===
704
+ 'Pirate'
705
+ ? 'border-amber-400 bg-amber-50'
706
+ : 'border-gray-200'}"
707
+ on:click={() => (selectedVoice = 'Pirate')}
708
+ >
709
+ <div class="flex items-center justify-between mb-1">
710
+ <div class="flex items-center gap-2">
711
+ <div
712
+ class="w-6 h-6 bg-gradient-to-br from-amber-400 to-orange-500 rounded-full flex items-center justify-center text-white text-xs font-semibold"
713
+ >
714
+ P
715
+ </div>
716
+ <span class="text-sm font-medium">Pirate</span>
717
+ </div>
718
+ <button
719
+ on:click={(e) =>
720
+ playSampleVoice({ name: 'Pirate', sample: '/voices/pirate.mp3' }, e)}
721
+ class="p-1 rounded-full hover:bg-gray-200 transition-colors w-5 h-5 flex items-center justify-center"
722
+ title="Play sample"
723
+ >
724
+ {#if playingSampleVoice === 'Pirate'}
725
+ <Pause size={10} class="text-gray-600" />
726
+ {:else}
727
+ <Play size={10} class="text-gray-600" />
728
+ {/if}
729
+ </button>
730
+ </div>
731
+ </button>
732
+
733
+ <!-- User Voice or Clone CTA -->
734
+ {#if userVoices.length > 0}
735
+ <button
736
+ class="p-3 border rounded-lg transition-colors text-left hover:bg-gray-50 {selectedVoice ===
737
+ 'Yours'
738
+ ? 'border-purple-400 bg-purple-50'
739
+ : 'border-gray-200'}"
740
+ on:click={() => (selectedVoice = 'Yours')}
741
+ >
742
+ <div class="flex items-center justify-between mb-1">
743
+ <div class="flex items-center gap-2">
744
+ <div
745
+ class="w-6 h-6 bg-gradient-to-br from-purple-400 to-pink-500 rounded-full flex items-center justify-center text-white text-xs"
746
+ >
747
+ 🎤
748
+ </div>
749
+ <span class="text-sm font-medium">Yours</span>
750
+ </div>
751
+ <button
752
+ on:click={(e) =>
753
+ playSampleVoice({ name: 'Yours', sample: userVoices[0].sample_url }, e)}
754
+ class="p-1 rounded-full hover:bg-gray-200 transition-colors w-5 h-5 flex items-center justify-center"
755
+ title="Play sample"
756
+ >
757
+ {#if playingSampleVoice === 'Yours'}
758
+ <Pause size={10} class="text-gray-600" />
759
+ {:else}
760
+ <Play size={10} class="text-gray-600" />
761
+ {/if}
762
+ </button>
763
+ </div>
764
+ </button>
765
  {:else}
766
+ <!-- Clone CTA -->
767
+ <a
768
+ href="/voice-cloning"
769
+ class="p-3 border border-purple-200 rounded-lg transition-colors text-left hover:bg-purple-50 bg-purple-25"
770
+ >
771
+ <div class="flex items-center justify-between mb-1">
772
+ <div class="flex items-center gap-2">
773
+ <div
774
+ class="w-6 h-6 bg-gradient-to-br from-purple-400 to-pink-500 rounded-full flex items-center justify-center text-white text-xs font-semibold"
775
+ >
776
+ 🎤
777
+ </div>
778
+ <span class="text-sm font-medium text-purple-900">Clone</span>
779
+ </div>
780
+ <div class="w-5 h-5 flex items-center justify-center">
781
+ <svg
782
+ class="w-3 h-3 text-purple-600"
783
+ fill="none"
784
+ viewBox="0 0 24 24"
785
+ stroke="currentColor"
786
+ >
787
+ <path
788
+ stroke-linecap="round"
789
+ stroke-linejoin="round"
790
+ stroke-width="2"
791
+ d="M9 5l7 7-7 7"
792
+ />
793
+ </svg>
794
+ </div>
795
+ </div>
796
+ </a>
797
  {/if}
798
+ </div>
799
+ </div>
800
 
801
+ <!-- Settings controls -->
802
+ <div class="space-y-6">
803
+ <!-- Exaggeration control -->
804
+ <div>
805
+ <div class="flex justify-between mb-3">
806
+ <label for="exaggeration-slider" class="text-sm font-medium text-gray-900"
807
+ >Exaggeration</label
808
+ >
809
+ <span class="text-sm text-gray-500">{exaggeration.toFixed(2)}</span>
810
+ </div>
811
+ <input
812
+ id="exaggeration-slider"
813
+ type="range"
814
+ bind:value={exaggeration}
815
+ min="0"
816
+ max="1"
817
+ step="0.01"
818
+ class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer slider-hf"
819
+ />
820
+ <div class="flex justify-between text-xs text-gray-400 mt-2">
821
+ <span>None</span>
822
+ <span>More</span>
823
  </div>
 
824
  </div>
 
825
 
826
+ <!-- Stability control -->
827
+ <div>
828
+ <div class="flex justify-between mb-3">
829
+ <label for="temperature-slider" class="text-sm font-medium text-gray-900"
830
+ >Stability</label
831
+ >
832
+ <span class="text-sm text-gray-500">{temperature.toFixed(2)}</span>
833
+ </div>
834
+ <input
835
+ id="temperature-slider"
836
+ type="range"
837
+ bind:value={temperature}
838
+ min="0"
839
+ max="1"
840
+ step="0.01"
841
+ class="w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer slider-hf"
842
+ />
843
+ <div class="flex justify-between text-xs text-gray-400 mt-2">
844
+ <span>More stable</span>
845
+ <span>More variable</span>
846
+ </div>
847
+ </div>
848
+ </div>
849
  </div>
850
+ </div>
 
851
 
852
+ <!-- Generate button -->
853
+ <button
854
+ on:click={generateSpeech}
855
+ disabled={isGenerating || !text.trim()}
856
+ class="w-full px-4 py-3 bg-gradient-to-r from-amber-400 to-orange-500 text-white rounded-lg font-medium hover:from-amber-500 hover:to-orange-600 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2 shadow-sm"
857
+ >
858
+ {#if isGenerating}
859
+ <Loader2 size={20} class="animate-spin" />
860
+ Generating...
861
+ {:else}
862
+ <Play size={20} />
863
+ Generate speech
864
+ {/if}
865
+ </button>
866
+ </div>
 
 
 
 
 
867
 
868
+ <!-- Right sidebar - Live Code Display -->
869
+ <div class="w-96 border-l border-gray-200 bg-white overflow-y-auto">
870
+ <div class="p-4">
871
+ <!-- Login prompt if not authenticated -->
872
+ {#if showLoginPrompt}
873
  <div
874
+ class="mb-4 px-3 py-2 bg-gradient-to-r from-amber-50 to-orange-50 rounded-lg border border-amber-200 relative"
875
  >
876
+ <!-- Close button -->
877
+ <button
878
+ on:click={() => (showLoginPrompt = false)}
879
+ class="absolute top-2 right-2 text-gray-400 hover:text-gray-600 transition-colors"
880
+ aria-label="Dismiss"
881
+ >
882
+ <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
883
+ <path
884
+ stroke-linecap="round"
885
+ stroke-linejoin="round"
886
+ stroke-width="2"
887
+ d="M6 18L18 6M6 6l12 12"
888
+ />
889
+ </svg>
890
+ </button>
891
+
892
+ <p class="text-sm font-medium text-gray-700 mb-1 pr-4">
893
+ Hugging Face <span
894
+ class="bg-gradient-to-r from-purple-500 via-pink-500 via-green-500 to-blue-500 bg-clip-text text-transparent font-bold"
895
+ >PRO</span
896
  >
897
+ </p>
898
+ <p class="text-sm text-gray-600 pr-4">
899
+ Sign in to with your Hugging Face <a
900
+ href="https://huggingface.co/pro"
901
+ target="_blank"
902
+ class="text-amber-600 hover:text-amber-700 underline font-medium">PRO account</a
903
+ > to get started with $2 of free API credits per month. You can add a billing method for
904
+ additional pay-as-you-go usage ⤴
905
+ </p>
906
  </div>
907
  {/if}
908
 
909
+ <!-- Header -->
910
+ <div class="mb-4">
911
+ <h3 class="text-lg font-semibold text-gray-900 mb-1">Live Documentation ✨</h3>
 
 
 
 
912
  </div>
 
913
 
914
+ <!-- Toggle and Copy All button row -->
915
+ <div class="flex items-center justify-between mb-4">
916
+ <!-- API/Local Mode Toggle -->
917
+ <div class="flex items-center bg-gray-100 rounded-md p-0.5">
918
+ <button
919
+ class="px-2 py-1 text-xs font-medium rounded transition-colors {mode === 'api'
920
+ ? 'bg-white shadow-sm'
921
+ : 'text-gray-600'}"
922
+ on:click={() => (mode = 'api')}
923
+ >
924
+ API
925
+ </button>
926
+ <button
927
+ class="px-2 py-1 text-xs font-medium rounded transition-colors {mode === 'local'
928
+ ? 'bg-white shadow-sm'
929
+ : 'text-gray-600'}"
930
+ on:click={() => (mode = 'local')}
931
+ >
932
+ Local
933
+ </button>
934
+ </div>
935
+
936
+ <button
937
+ on:click={copyAllCode}
938
+ class="flex items-center bg-gray-100 hover:bg-gray-200 rounded-md px-2 py-1 transition-colors"
939
+ >
940
+ <Copy size={12} class="text-gray-600" />
941
+ <span class="ml-1 text-xs font-medium text-gray-600">Copy all as Markdown</span>
942
+ </button>
943
  </div>
944
 
945
+ <!-- Code sections -->
946
+ <div class="space-y-4">
947
+ <!-- Setup Section -->
948
+ <div class="bg-white rounded-lg border border-gray-200 overflow-hidden">
949
+ <div
950
+ class="flex items-center justify-between px-3 py-2 bg-blue-50 border-b border-blue-200"
951
  >
952
+ <div class="flex items-center gap-2">
953
+ <span class="text-xs font-medium text-blue-900">Install in Terminal</span>
 
 
 
 
 
 
 
 
 
 
954
  </div>
955
  <button
956
+ on:click={() => copyToClipboard(setupCode)}
957
+ class="p-1 hover:bg-blue-100 rounded transition-colors"
958
+ title="Copy setup code"
959
  >
960
+ <Copy size={12} class="text-blue-600" />
 
 
 
 
961
  </button>
962
+ </div>
963
+ <div class="relative">
964
+ {#key codeUpdateCounter}
965
+ <pre class="p-3 overflow-x-auto bg-gray-50 text-xs"><code class="language-bash"
966
+ >{@html Prism.highlight(setupCode, Prism.languages.bash, 'bash')}</code
967
+ ></pre>
968
+ {/key}
969
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
970
  </div>
 
971
 
972
+ <!-- Python Code Section (Imports + Generation) -->
973
+ <div class="bg-white rounded-lg border border-gray-200 overflow-hidden">
974
+ <div
975
+ class="flex items-center justify-between px-3 py-2 bg-amber-50 border-b border-amber-200"
 
976
  >
977
+ <div class="flex items-center gap-2">
978
+ <span class="text-xs font-medium text-amber-900">Python Code</span>
979
+ <span class="text-xs bg-amber-100 text-amber-700 px-1.5 py-0.5 rounded">Live</span>
980
+ </div>
981
+ <button
982
+ on:click={() => copyToClipboard(pythonCode)}
983
+ class="p-1 hover:bg-amber-100 rounded transition-colors"
984
+ title="Copy Python code"
985
+ >
986
+ <Copy size={12} class="text-amber-600" />
987
+ </button>
988
+ </div>
989
+ <div class="relative">
990
+ {#key codeUpdateCounter}
991
+ <pre class="p-3 overflow-x-auto bg-gray-50 text-xs"><code class="language-python"
992
+ >{@html Prism.highlight(pythonCode, Prism.languages.python, 'python')}</code
993
+ ></pre>
994
+ {/key}
995
+ </div>
996
  </div>
 
 
997
 
998
+ <!-- Generated Audio Section -->
999
+ {#if audioUrl}
1000
+ <div class="bg-white rounded-lg border border-gray-200 overflow-hidden mt-4">
1001
+ <div
1002
+ class="flex items-center justify-between px-3 py-2 bg-green-50 border-b border-green-200"
1003
+ >
1004
+ <div class="flex items-center gap-2">
1005
+ <div class="w-1.5 h-1.5 bg-green-500 rounded-full"></div>
1006
+ <span class="text-xs font-medium text-green-900">Generated Audio</span>
1007
+ {#if generationTime > 0 && mode !== 'local'}
1008
+ <span class="text-xs text-green-700">(took {generationTime.toFixed(1)}s)</span>
1009
+ {/if}
1010
+ </div>
1011
+ <div class="flex items-center gap-1">
1012
+ <button
1013
+ on:click={downloadAudio}
1014
+ class="flex items-center gap-1 px-2 py-1 hover:bg-green-100 rounded transition-colors"
1015
+ title="Download audio"
1016
+ >
1017
+ <span class="text-xs text-green-700">Download</span>
1018
+ <Download size={12} class="text-green-600" />
1019
+ </button>
1020
+ </div>
1021
+ </div>
1022
+ <div class="p-3">
1023
+ <!-- Audio info -->
1024
+ <div class="mb-3">
1025
+ <h4 class="font-medium text-gray-900 text-xs">{audioTitle}</h4>
1026
+ <p class="text-xs text-gray-500">{selectedVoice} • {formatTime(duration)}</p>
1027
+ </div>
1028
+
1029
+ <!-- Audio controls -->
1030
+ <div class="flex items-center gap-2">
1031
+ <!-- Play/Pause button -->
1032
+ <button
1033
+ on:click={togglePlayPause}
1034
+ class="w-6 h-6 bg-black rounded-full flex items-center justify-center hover:bg-gray-800 transition-colors flex-shrink-0"
1035
+ >
1036
+ {#if isPlaying}
1037
+ <div class="pause-filled text-white text-xs"></div>
1038
+ {:else}
1039
+ <Play size={10} class="text-white ml-0.5" />
1040
+ {/if}
1041
+ </button>
1042
+
1043
+ <!-- Progress bar -->
1044
+ <div class="flex-1 flex items-center gap-1">
1045
+ <span class="text-xs text-gray-500 font-mono">{formatTime(currentTime)}</span>
1046
+ <div class="flex-1 h-1 bg-gray-200 rounded-full cursor-pointer">
1047
+ <div
1048
+ class="h-full bg-gradient-to-r from-amber-400 to-orange-500 rounded-full transition-all"
1049
+ style="width: {(currentTime / duration) * 100}%"
1050
+ ></div>
1051
+ </div>
1052
+ <span class="text-xs text-gray-500 font-mono">{formatTime(duration)}</span>
1053
+ </div>
1054
+ </div>
1055
+
1056
+ <!-- Hidden audio element -->
1057
+ {#if audioUrl}
1058
+ <audio
1059
+ bind:this={audioElement}
1060
+ src={audioUrl}
1061
+ on:loadedmetadata={handleAudioLoad}
1062
+ on:timeupdate={handleTimeUpdate}
1063
+ on:play={handlePlay}
1064
+ on:pause={handlePause}
1065
+ style="display: none;"
1066
+ />
1067
+ {/if}
1068
+ </div>
1069
+ </div>
1070
+ {/if}
1071
+ </div>
1072
  </div>
1073
  </div>
1074
  </div>
 
1131
  </div>
1132
  {/if}
1133
 
1134
+ <!-- Copy notification toast -->
1135
+ {#if copyNotification}
1136
+ <div
1137
+ class="fixed bottom-4 right-4 px-4 py-2 bg-gray-900 text-white rounded-lg shadow-lg z-50 animate-fade-in"
1138
+ >
1139
+ {copyNotification}
1140
+ </div>
1141
+ {/if}
1142
+
1143
  <style>
1144
+ @keyframes fade-in {
1145
+ from {
1146
+ opacity: 0;
1147
+ transform: translateY(10px);
1148
+ }
1149
+ to {
1150
+ opacity: 1;
1151
+ transform: translateY(0);
1152
+ }
1153
+ }
1154
+
1155
+ .animate-fade-in {
1156
+ animation: fade-in 0.3s ease-out;
1157
+ }
1158
  .pause-filled::after {
1159
  content: '';
1160
  width: 3px;
 
1171
  display: inline-block;
1172
  margin-right: 2px;
1173
  }
1174
+ </style>
frontend/src/routes/code-recorder/+page.svelte CHANGED
@@ -1,24 +1,16 @@
1
  <script>
2
- import {
3
- Copy,
4
- RotateCcw,
5
- Play,
6
- Download,
7
- Share,
8
- Pause,
9
- Layout,
10
- Code,
11
- } from 'lucide-svelte';
12
  import { onMount } from 'svelte';
13
  import Prism from 'prismjs';
14
  import 'prismjs/components/prism-python';
15
  import 'prismjs/components/prism-bash';
 
16
 
17
  let selectedModel = 'Chatterbox';
18
  let mode = 'api';
19
  let codeHistory = [];
20
  let setupCode = generateSetupCode();
21
- let importCode = null;
22
  let copyNotification = null;
23
  let historyCount = 0;
24
 
@@ -33,28 +25,32 @@
33
  name: 'Andrew',
34
  description: 'Older British man who speaks clearly and kindly',
35
  sample: '/voices/andrew.mp3',
36
- preview_url: 'https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/andrew.mp3',
 
37
  },
38
  {
39
  id: 'lily',
40
  name: 'Jasmine',
41
  description: 'Warm, conversational tone of a woman in her 30s',
42
  sample: '/voices/lily.mp3',
43
- preview_url: 'https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/lily.mp3',
 
44
  },
45
  {
46
  id: 'pirate',
47
  name: 'Pirate',
48
  description: 'Young male pirate-y voice that speaks gruffly and with excitement',
49
  sample: '/voices/pirate.mp3',
50
- preview_url: 'https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/pirate.mp3',
 
51
  },
52
  {
53
  id: 'fairy',
54
  name: 'Fairy',
55
  description: 'High and airy female voice that bursts with excitement',
56
  sample: '/voices/fairy.mp3',
57
- preview_url: 'https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/fairy.mp3',
 
58
  },
59
  ];
60
 
@@ -73,21 +69,24 @@
73
  const generationEntries = data.entries.filter((e) => e.entry_type === 'generation');
74
 
75
  setupCode = generateSetupCode();
76
- importCode = importEntries.length > 0 ? importEntries[importEntries.length - 1].code : null;
 
 
 
77
 
78
  codeHistory = generationEntries.map((entry) => ({
79
  id: entry.id,
80
  code: entry.code,
81
  result: entry.result_data,
82
  }));
83
-
84
  historyCount = generationEntries.length;
85
  }
86
  } catch (error) {
87
  console.error('Error loading history from database:', error);
88
  codeHistory = [];
89
  setupCode = generateSetupCode();
90
- importCode = null;
91
  }
92
  }
93
 
@@ -100,12 +99,14 @@
100
 
101
  codeHistory = [];
102
  setupCode = generateSetupCode();
103
- importCode = null;
 
104
  } catch (error) {
105
  console.error('Error clearing history:', error);
106
  codeHistory = [];
107
  setupCode = generateSetupCode();
108
- importCode = null;
 
109
  }
110
  }
111
 
@@ -222,9 +223,7 @@ ${clientCode}`;
222
 
223
  $: if (mode) {
224
  setupCode = generateSetupCode();
225
- if (importCode) {
226
- importCode = generateImportCode();
227
- }
228
  }
229
 
230
  onMount(async () => {
@@ -237,21 +236,7 @@ ${clientCode}`;
237
  </svelte:head>
238
 
239
  <div class="flex-1 bg-gray-50 overflow-y-auto">
240
- <!-- Top navbar -->
241
- <div class="flex items-center justify-end px-4 py-4 border-b border-gray-200 bg-white min-h-[73px]">
242
- <a
243
- href="/"
244
- class="px-3 py-1.5 text-sm font-medium rounded transition-colors text-gray-600 hover:bg-gray-50 flex items-center gap-1 bg-gray-100"
245
- >
246
- <Layout size={14} />
247
- UI
248
- {#if historyCount > 0}
249
- <span class="ml-1 px-1.5 py-0.5 bg-gray-500 text-white text-xs rounded-full min-w-[18px] text-center">
250
- {historyCount}
251
- </span>
252
- {/if}
253
- </a>
254
- </div>
255
 
256
  <div class="max-w-4xl mx-auto p-8">
257
  <!-- Header -->
@@ -321,9 +306,7 @@ ${clientCode}`;
321
  >
322
  <div class="flex items-center gap-2">
323
  <span class="text-sm font-medium text-amber-900">Setup (Run in Terminal)</span>
324
- <span class="text-xs bg-amber-100 text-amber-700 px-2 py-0.5 rounded"
325
- >Run once</span
326
- >
327
  </div>
328
  <button
329
  on:click={() => copyToClipboard(setupCode)}
@@ -355,8 +338,7 @@ ${clientCode}`;
355
  >
356
  <div class="flex items-center gap-2">
357
  <span class="text-sm font-medium text-blue-900">Imports (Python)</span>
358
- <span class="text-xs bg-blue-100 text-blue-700 px-2 py-0.5 rounded">Run once</span
359
- >
360
  </div>
361
  <button
362
  on:click={() => copyToClipboard(importCode)}
@@ -432,8 +414,7 @@ ${clientCode}`;
432
  </div>
433
  <div class="flex items-center gap-1">
434
  <button
435
- on:click={() =>
436
- downloadHistoryAudio(entry.result.url, entry.result.title)}
437
  class="p-2 hover:bg-gray-100 rounded-lg transition-colors"
438
  title="Download"
439
  >
@@ -486,4 +467,4 @@ ${clientCode}`;
486
  .animate-fade-in {
487
  animation: fade-in 0.3s ease-out;
488
  }
489
- </style>
 
1
  <script>
2
+ import { Copy, RotateCcw, Play, Download, Share, Pause, Layout, Code } from 'lucide-svelte';
 
 
 
 
 
 
 
 
 
3
  import { onMount } from 'svelte';
4
  import Prism from 'prismjs';
5
  import 'prismjs/components/prism-python';
6
  import 'prismjs/components/prism-bash';
7
+ import Navbar from '$lib/components/Navbar.svelte';
8
 
9
  let selectedModel = 'Chatterbox';
10
  let mode = 'api';
11
  let codeHistory = [];
12
  let setupCode = generateSetupCode();
13
+ let importCode = generateImportCode();
14
  let copyNotification = null;
15
  let historyCount = 0;
16
 
 
25
  name: 'Andrew',
26
  description: 'Older British man who speaks clearly and kindly',
27
  sample: '/voices/andrew.mp3',
28
+ preview_url:
29
+ 'https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/andrew.mp3',
30
  },
31
  {
32
  id: 'lily',
33
  name: 'Jasmine',
34
  description: 'Warm, conversational tone of a woman in her 30s',
35
  sample: '/voices/lily.mp3',
36
+ preview_url:
37
+ 'https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/lily.mp3',
38
  },
39
  {
40
  id: 'pirate',
41
  name: 'Pirate',
42
  description: 'Young male pirate-y voice that speaks gruffly and with excitement',
43
  sample: '/voices/pirate.mp3',
44
+ preview_url:
45
+ 'https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/pirate.mp3',
46
  },
47
  {
48
  id: 'fairy',
49
  name: 'Fairy',
50
  description: 'High and airy female voice that bursts with excitement',
51
  sample: '/voices/fairy.mp3',
52
+ preview_url:
53
+ 'https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/fairy.mp3',
54
  },
55
  ];
56
 
 
69
  const generationEntries = data.entries.filter((e) => e.entry_type === 'generation');
70
 
71
  setupCode = generateSetupCode();
72
+ importCode =
73
+ importEntries.length > 0
74
+ ? importEntries[importEntries.length - 1].code
75
+ : generateImportCode();
76
 
77
  codeHistory = generationEntries.map((entry) => ({
78
  id: entry.id,
79
  code: entry.code,
80
  result: entry.result_data,
81
  }));
82
+
83
  historyCount = generationEntries.length;
84
  }
85
  } catch (error) {
86
  console.error('Error loading history from database:', error);
87
  codeHistory = [];
88
  setupCode = generateSetupCode();
89
+ importCode = generateImportCode();
90
  }
91
  }
92
 
 
99
 
100
  codeHistory = [];
101
  setupCode = generateSetupCode();
102
+ importCode = generateImportCode();
103
+ historyCount = 0;
104
  } catch (error) {
105
  console.error('Error clearing history:', error);
106
  codeHistory = [];
107
  setupCode = generateSetupCode();
108
+ importCode = generateImportCode();
109
+ historyCount = 0;
110
  }
111
  }
112
 
 
223
 
224
  $: if (mode) {
225
  setupCode = generateSetupCode();
226
+ importCode = generateImportCode();
 
 
227
  }
228
 
229
  onMount(async () => {
 
236
  </svelte:head>
237
 
238
  <div class="flex-1 bg-gray-50 overflow-y-auto">
239
+ <Navbar {historyCount} />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
 
241
  <div class="max-w-4xl mx-auto p-8">
242
  <!-- Header -->
 
306
  >
307
  <div class="flex items-center gap-2">
308
  <span class="text-sm font-medium text-amber-900">Setup (Run in Terminal)</span>
309
+ <span class="text-xs bg-amber-100 text-amber-700 px-2 py-0.5 rounded">Run once</span>
 
 
310
  </div>
311
  <button
312
  on:click={() => copyToClipboard(setupCode)}
 
338
  >
339
  <div class="flex items-center gap-2">
340
  <span class="text-sm font-medium text-blue-900">Imports (Python)</span>
341
+ <span class="text-xs bg-blue-100 text-blue-700 px-2 py-0.5 rounded">Run once</span>
 
342
  </div>
343
  <button
344
  on:click={() => copyToClipboard(importCode)}
 
414
  </div>
415
  <div class="flex items-center gap-1">
416
  <button
417
+ on:click={() => downloadHistoryAudio(entry.result.url, entry.result.title)}
 
418
  class="p-2 hover:bg-gray-100 rounded-lg transition-colors"
419
  title="Download"
420
  >
 
467
  .animate-fade-in {
468
  animation: fade-in 0.3s ease-out;
469
  }
470
+ </style>
frontend/src/routes/voice-cloning/+page.svelte CHANGED
@@ -14,6 +14,7 @@
14
  RotateCcw,
15
  Mic,
16
  Square,
 
17
  } from 'lucide-svelte';
18
  import { onMount } from 'svelte';
19
 
@@ -21,7 +22,6 @@
21
  let isRecording = false;
22
  let sessionRecordings = [];
23
  let selectedRecording = null;
24
- let cloneName = '';
25
  let recordingWaveform = [];
26
  let mediaRecorder = null;
27
  let audioChunks = [];
@@ -36,17 +36,36 @@
36
  let analyser = null;
37
  let playingRecording = null;
38
  let currentAudio = null;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  // Validation helper functions
41
  function isRecordingLongEnough(recording) {
42
- return recording && recording.duration >= 15;
43
  }
44
-
45
  function hasConsent(recording) {
46
- // Since we can't analyze actual audio content, we'll assume consent is included
47
- // based on the script requirement. In a real implementation, this would use
48
- // speech-to-text to verify the "I consent" phrase is present.
49
- return recording !== null;
50
  }
51
 
52
  function showError(message, details = '') {
@@ -61,11 +80,78 @@
61
  errorDetails = '';
62
  }
63
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
64
  // Voice cloning functions
65
  async function startRecording() {
 
 
 
 
 
 
66
  try {
67
  const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
68
- mediaRecorder = new MediaRecorder(stream);
 
 
 
 
 
 
 
 
 
69
  audioChunks = [];
70
  recordingWaveform = [];
71
  recordingProgress = 0;
@@ -76,7 +162,7 @@
76
  analyser = audioContext.createAnalyser();
77
  const source = audioContext.createMediaStreamSource(stream);
78
  source.connect(analyser);
79
-
80
  analyser.fftSize = 256;
81
  const bufferLength = analyser.frequencyBinCount;
82
  const dataArray = new Uint8Array(bufferLength);
@@ -93,10 +179,10 @@
93
  url: audioUrl,
94
  blob: audioBlob,
95
  timestamp: new Date(),
96
- duration: recordingProgress / 100 * 15
97
  };
98
  sessionRecordings = [...sessionRecordings, recording];
99
- stream.getTracks().forEach(track => track.stop());
100
  if (audioContext) {
101
  audioContext.close();
102
  audioContext = null;
@@ -111,14 +197,14 @@
111
  // Function to update amplitude
112
  function updateAmplitude() {
113
  if (!isRecording || !analyser) return;
114
-
115
  analyser.getByteFrequencyData(dataArray);
116
  let sum = 0;
117
  for (let i = 0; i < bufferLength; i++) {
118
  sum += dataArray[i];
119
  }
120
- audioAmplitude = (sum / bufferLength) / 255; // Normalize to 0-1
121
-
122
  requestAnimationFrame(updateAmplitude);
123
  }
124
  updateAmplitude();
@@ -129,14 +215,13 @@
129
  clearInterval(recordingTimer);
130
  return;
131
  }
132
- recordingProgress += (100 / 15) / 10; // 100% over 15 seconds, updated every 100ms
133
  if (recordingProgress >= 100) {
134
  recordingProgress = 100;
135
  // Auto-stop after 15 seconds if desired
136
  // stopRecording();
137
  }
138
  }, 100);
139
-
140
  } catch (error) {
141
  console.error('Error accessing microphone:', error);
142
  showError('Microphone Error', 'Could not access microphone. Please check permissions.');
@@ -174,38 +259,131 @@
174
  playingRecording = null;
175
  return;
176
  }
177
-
178
  // Stop any currently playing audio
179
  if (currentAudio) {
180
  currentAudio.pause();
181
  currentAudio = null;
182
  }
183
-
184
  // Start playing the new recording
185
  currentAudio = new Audio(recording.url);
186
  playingRecording = recording;
187
-
188
  currentAudio.addEventListener('ended', () => {
189
  playingRecording = null;
190
  currentAudio = null;
191
  });
192
-
193
  currentAudio.addEventListener('pause', () => {
194
  if (currentAudio && currentAudio.ended) {
195
  playingRecording = null;
196
  currentAudio = null;
197
  }
198
  });
199
-
200
  currentAudio.play();
201
  }
202
 
203
- function cloneVoice() {
204
- if (!selectedRecording || !cloneName.trim()) {
205
- showError('Clone Error', 'Please select a recording and enter a name.');
206
  return;
207
  }
208
- showError('Clone Voice', 'Voice cloning functionality will be implemented soon.');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
209
  }
210
 
211
  async function loadHistoryCount() {
@@ -226,8 +404,56 @@
226
  }
227
  }
228
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
229
  onMount(async () => {
 
230
  await loadHistoryCount();
 
231
  });
232
  </script>
233
 
@@ -236,176 +462,309 @@
236
  </svelte:head>
237
 
238
  <div class="flex flex-col h-full">
239
- <!-- Top navbar -->
240
- <div class="flex items-center justify-end px-4 py-4 border-b border-gray-200 min-h-[73px]">
241
- <a
242
- href="/code-recorder"
243
- class="px-3 py-1.5 text-sm font-medium rounded transition-colors text-gray-600 hover:bg-gray-50 flex items-center gap-1 bg-gray-100"
244
- >
245
- <Code size={14} />
246
- Code Recorder
247
- {#if historyCount > 0}
248
- <span class="ml-1 px-1.5 py-0.5 bg-gray-500 text-white text-xs rounded-full min-w-[18px] text-center">
249
- {historyCount}
250
- </span>
251
- {/if}
252
- </a>
253
- </div>
254
-
255
  <div class="flex-1 flex">
256
  <!-- Main content area -->
257
  <div class="flex-1 flex flex-col p-6">
258
- <!-- Script reading area -->
259
- <div class="flex-1 pb-24 relative flex flex-col">
260
- <div class="mb-6">
261
- <p><em>Record your voice for at least 15 seconds to create a voice clone. To prevent unauthorized voice cloning, you must start by clearly saying "I consent to cloning my voice" — the rest of the text is arbitrary.</em></p>
262
- </div>
263
-
264
- <!-- Script text -->
265
- <div class="flex-1 p-8 mb-6">
266
- <div class="text-gray-900 leading-relaxed font-serif text-lg relative p-4">
267
- <div class="absolute top-0 left-0 w-8 h-8 border-l-2 border-t-2 border-amber-400 rounded-tl-lg"></div>
268
- <div class="absolute bottom-0 right-0 w-8 h-8 border-r-2 border-b-2 border-amber-400 rounded-br-lg"></div>
269
- <p class="mb-4"><span class="bg-yellow-50">I consent to cloning my voice.</span> There's a quiet kind of magic in the early hours of the morning, when the world is still half-asleep and the air feels crisp with possibility. The hum of the refrigerator becomes a rhythm, the ticking of the clock a heartbeat, and for a brief moment, everything feels perfectly in sync.</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
270
  </div>
271
- </div>
272
 
273
- <!-- Record button -->
274
- <div class="flex justify-center items-center flex-1 relative">
275
- <!-- Concentric circles for amplitude visualization -->
276
- {#if isRecording}
277
- <div class="absolute inset-0 flex items-center justify-center">
278
- <div
279
- class="absolute rounded-full border-2 border-orange-300 transition-all duration-75"
280
- style="width: {120 + audioAmplitude * 120}px; height: {120 + audioAmplitude * 120}px; opacity: {0.4 + audioAmplitude * 0.6}"
281
- ></div>
282
- <div
283
- class="absolute rounded-full border-2 border-orange-200 transition-all duration-100"
284
- style="width: {150 + audioAmplitude * 150}px; height: {150 + audioAmplitude * 150}px; opacity: {0.3 + audioAmplitude * 0.5}"
285
- ></div>
286
- <div
287
- class="absolute rounded-full border-1 border-orange-100 transition-all duration-125"
288
- style="width: {180 + audioAmplitude * 180}px; height: {180 + audioAmplitude * 180}px; opacity: {0.2 + audioAmplitude * 0.4}"
289
- ></div>
290
- </div>
291
- {/if}
292
-
293
- <button
294
- on:click={toggleRecording}
295
- class="w-24 h-24 rounded-full flex items-center justify-center transition-all duration-200 shadow-lg relative overflow-hidden z-20 {isRecording ? 'border-4 border-orange-500 bg-transparent' : 'bg-orange-500 hover:bg-orange-600'}"
296
- >
297
  {#if isRecording}
298
- <!-- Filling effect -->
299
- <div
300
- class="absolute bottom-0 left-0 right-0 bg-orange-500 transition-all duration-100 ease-linear rounded-full"
301
- style="height: {recordingProgress}%"
302
- ></div>
303
- <Square size={36} class="{recordingProgress >= 100 ? 'text-white' : 'text-orange-700'} relative z-10" />
304
- {:else}
305
- <Mic size={36} class="text-white" />
 
 
 
 
 
 
 
 
 
306
  {/if}
307
- </button>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
308
  </div>
309
  </div>
310
- </div>
311
 
312
- <!-- Right panel for voice cloning -->
313
- <div class="w-80 border-l border-gray-200 bg-white p-3 overflow-y-auto">
314
- <div class="mb-4">
315
-
316
- {#if sessionRecordings.length === 0}
317
- <div class="text-center py-8 text-gray-500">
318
- <Mic size={32} class="mx-auto mb-2 opacity-30" />
319
- <p class="text-sm">No recordings yet</p>
320
- <p class="text-xs text-gray-400">Start recording to see them here</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  </div>
322
- {:else}
323
- <div class="space-y-2">
324
- {#each sessionRecordings as recording, i}
325
- <div class="border rounded-lg p-3 {selectedRecording?.id === recording.id ? 'border-amber-300 bg-amber-50' : 'border-gray-200 hover:border-gray-300'} transition-colors">
326
- <div class="flex items-center justify-between mb-2">
327
- <span class="text-sm font-medium text-gray-900">Recording {i + 1}</span>
328
- <button
329
- on:click={() => togglePlayRecording(recording)}
330
- class="p-1 hover:bg-gray-100 rounded transition-colors"
331
- >
332
- {#if playingRecording?.id === recording.id && currentAudio && !currentAudio.paused}
333
- <Pause size={14} class="text-gray-600" />
334
- {:else}
335
- <Play size={14} class="text-gray-600" />
336
- {/if}
337
- </button>
338
- </div>
339
- <div class="text-xs text-gray-500 mb-2">
340
- {recording.timestamp.toLocaleTimeString()}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
341
  </div>
342
- <button
343
- on:click={() => selectRecording(recording)}
344
- class="w-full text-xs px-2 py-1 rounded {selectedRecording?.id === recording.id ? 'bg-amber-200 text-amber-800' : 'bg-gray-100 text-gray-700 hover:bg-gray-200'} transition-colors"
345
- >
346
- {selectedRecording?.id === recording.id ? 'Selected' : 'Select for cloning'}
347
- </button>
348
- </div>
349
- {/each}
350
  </div>
351
  {/if}
352
- </div>
353
 
354
- <!-- Clone section -->
355
- <div class="mt-6 pt-4 border-t border-gray-200">
356
- <div class="mb-3">
357
- <label for="clone-name" class="block text-sm font-medium text-gray-700 mb-1">
358
- Give name to recording
359
- </label>
360
- <input
361
- id="clone-name"
362
- type="text"
363
- bind:value={cloneName}
364
- placeholder="e.g., My Voice"
365
- class="w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-amber-400 focus:border-transparent"
366
- />
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
367
  </div>
368
- <button
369
- on:click={cloneVoice}
370
- disabled={!selectedRecording || !cloneName.trim()}
371
- class="w-full px-4 py-2 bg-gradient-to-r from-amber-400 to-orange-500 text-white rounded-lg font-medium hover:from-amber-500 hover:to-orange-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors"
372
- >
373
- Clone
374
- </button>
375
-
376
- <!-- Validation status -->
377
- {#if selectedRecording}
378
- <div class="mt-3 text-sm text-green-600 flex items-center gap-4">
379
- <span class="flex items-center gap-1">
380
- {#if isRecordingLongEnough(selectedRecording)}
381
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
382
  {:else}
383
 
384
  {/if}
385
- at least 15 seconds
386
  </span>
387
- <span class="flex items-center gap-1">
388
- {#if hasConsent(selectedRecording)}
389
-
 
 
 
 
 
 
 
 
 
 
 
 
390
  {:else}
391
-
392
  {/if}
393
  includes consent
394
  </span>
395
  </div>
396
- {/if}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
397
  </div>
398
  </div>
399
  </div>
400
- </div>
401
 
402
  <!-- Error Modal -->
403
  {#if showErrorModal}
404
  <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
405
  <div class="bg-white rounded-xl shadow-2xl max-w-2xl w-full max-h-[80vh] flex flex-col">
406
- <div class="flex items-center justify-between p-6 border-b border-gray-200 bg-red-50 flex-shrink-0">
 
 
407
  <div class="flex items-center gap-3 min-w-0">
408
- <div class="w-10 h-10 bg-red-100 rounded-full flex items-center justify-center flex-shrink-0">
 
 
409
  <AlertCircle size={20} class="text-red-600" />
410
  </div>
411
  <div class="min-w-0">
@@ -425,11 +784,14 @@
425
  {#if errorDetails}
426
  <div class="bg-gray-50 rounded-lg p-4 border">
427
  <h4 class="text-sm font-medium text-gray-900 mb-2">Error Details:</h4>
428
- <pre class="text-xs text-gray-700 whitespace-pre-wrap font-mono leading-relaxed break-words">{errorDetails}</pre>
 
429
  </div>
430
  {/if}
431
  </div>
432
- <div class="flex items-center justify-end gap-3 p-6 border-t border-gray-200 bg-gray-50 flex-shrink-0">
 
 
433
  <button
434
  on:click={closeErrorModal}
435
  class="px-6 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors"
@@ -439,4 +801,4 @@
439
  </div>
440
  </div>
441
  </div>
442
- {/if}
 
14
  RotateCcw,
15
  Mic,
16
  Square,
17
+ Shuffle,
18
  } from 'lucide-svelte';
19
  import { onMount } from 'svelte';
20
 
 
22
  let isRecording = false;
23
  let sessionRecordings = [];
24
  let selectedRecording = null;
 
25
  let recordingWaveform = [];
26
  let mediaRecorder = null;
27
  let audioChunks = [];
 
36
  let analyser = null;
37
  let playingRecording = null;
38
  let currentAudio = null;
39
+ let transcriptionStatus = {}; // Store transcription results for each recording
40
+ let isTranscribing = false;
41
+ let isUploading = false;
42
+ let cloneName = '';
43
+ let uploadResults = {}; // Store upload results for each recording
44
+ let successMessage = '';
45
+ let userVoices = []; // Store user's existing voices
46
+ let isDeletingVoice = false;
47
+
48
+ // Sample text rotation state
49
+ const sampleTexts = [
50
+ "There's a quiet kind of magic in the early hours of the morning, when the world is still half-asleep and the air feels crisp with possibility. The hum of the refrigerator becomes a rhythm, the ticking of the clock a heartbeat, and for a brief moment, everything feels perfectly in sync.",
51
+ 'The aroma of fresh coffee dances through the kitchen as sunlight streams through translucent curtains, casting golden patterns on weathered wooden floors. Steam rises from the ceramic mug like incense, creating a small sanctuary of warmth and comfort in the midst of a busy day.',
52
+ 'Ocean waves crash against weathered cliffs with relentless determination, their white foam reaching toward the endless sky. Seabirds call out across the salt-scented breeze, their cries echoing off ancient stone formations that have stood witness to countless storms and seasons.',
53
+ ];
54
+ let currentSampleIndex = 0;
55
+
56
+ // Authentication state
57
+ let isLoggedIn = false;
58
+ let showLoginPrompt = false;
59
 
60
  // Validation helper functions
61
  function isRecordingLongEnough(recording) {
62
+ return recording && recording.duration >= 3;
63
  }
64
+
65
  function hasConsent(recording) {
66
+ if (!recording) return false;
67
+ const transcription = transcriptionStatus[recording.id];
68
+ return transcription && transcription.consent_detected;
 
69
  }
70
 
71
  function showError(message, details = '') {
 
80
  errorDetails = '';
81
  }
82
 
83
+ function shuffleSampleText() {
84
+ currentSampleIndex = (currentSampleIndex + 1) % sampleTexts.length;
85
+ }
86
+
87
+ function handleAuthAction() {
88
+ // Get OAuth config and redirect to HuggingFace OAuth
89
+ const clientId = '4831a493-1dbc-4dd4-9bb3-c3b41d2e96ba';
90
+ const scopes = 'inference-api manage-repos';
91
+
92
+ // Store current path to return to after auth
93
+ const returnPath = window.location.pathname;
94
+
95
+ // Determine the correct callback URL based on environment
96
+ let redirectUri;
97
+ if (window.location.hostname === 'localhost') {
98
+ // Development: use backend port for callback
99
+ redirectUri = 'http://localhost:7860/auth/callback';
100
+ } else {
101
+ // Production: use current origin
102
+ redirectUri = `${window.location.origin}/auth/callback`;
103
+ }
104
+
105
+ const authUrl = `https://huggingface.co/oauth/authorize?client_id=${clientId}&redirect_uri=${encodeURIComponent(redirectUri)}&scope=${encodeURIComponent(scopes)}&response_type=code&state=${encodeURIComponent(returnPath)}`;
106
+
107
+ window.location.href = authUrl;
108
+ }
109
+
110
+ async function checkAuthStatus() {
111
+ try {
112
+ const response = await fetch('/api/auth/user', { credentials: 'include' });
113
+ if (response.ok) {
114
+ const data = await response.json();
115
+ const wasLoggedIn = isLoggedIn;
116
+ isLoggedIn = data.authenticated;
117
+
118
+ // If login status changed to logged in, load voices
119
+ if (isLoggedIn && !wasLoggedIn) {
120
+ await loadUserVoices();
121
+ } else if (!isLoggedIn && wasLoggedIn) {
122
+ // Clear voices when logged out
123
+ userVoices = [];
124
+ }
125
+ } else {
126
+ isLoggedIn = false;
127
+ userVoices = [];
128
+ }
129
+ } catch (error) {
130
+ isLoggedIn = false;
131
+ userVoices = [];
132
+ }
133
+ }
134
+
135
  // Voice cloning functions
136
  async function startRecording() {
137
+ // Check authentication before recording
138
+ if (!isLoggedIn) {
139
+ showLoginPrompt = true;
140
+ return;
141
+ }
142
+
143
  try {
144
  const stream = await navigator.mediaDevices.getUserMedia({ audio: true });
145
+
146
+ // Try to use WAV format if supported, otherwise use default
147
+ let options = {};
148
+ if (MediaRecorder.isTypeSupported('audio/wav')) {
149
+ options.mimeType = 'audio/wav';
150
+ } else if (MediaRecorder.isTypeSupported('audio/webm')) {
151
+ options.mimeType = 'audio/webm';
152
+ }
153
+
154
+ mediaRecorder = new MediaRecorder(stream, options);
155
  audioChunks = [];
156
  recordingWaveform = [];
157
  recordingProgress = 0;
 
162
  analyser = audioContext.createAnalyser();
163
  const source = audioContext.createMediaStreamSource(stream);
164
  source.connect(analyser);
165
+
166
  analyser.fftSize = 256;
167
  const bufferLength = analyser.frequencyBinCount;
168
  const dataArray = new Uint8Array(bufferLength);
 
179
  url: audioUrl,
180
  blob: audioBlob,
181
  timestamp: new Date(),
182
+ duration: (recordingProgress / 100) * 15,
183
  };
184
  sessionRecordings = [...sessionRecordings, recording];
185
+ stream.getTracks().forEach((track) => track.stop());
186
  if (audioContext) {
187
  audioContext.close();
188
  audioContext = null;
 
197
  // Function to update amplitude
198
  function updateAmplitude() {
199
  if (!isRecording || !analyser) return;
200
+
201
  analyser.getByteFrequencyData(dataArray);
202
  let sum = 0;
203
  for (let i = 0; i < bufferLength; i++) {
204
  sum += dataArray[i];
205
  }
206
+ audioAmplitude = sum / bufferLength / 255; // Normalize to 0-1
207
+
208
  requestAnimationFrame(updateAmplitude);
209
  }
210
  updateAmplitude();
 
215
  clearInterval(recordingTimer);
216
  return;
217
  }
218
+ recordingProgress += 100 / 15 / 10; // 100% over 15 seconds, updated every 100ms
219
  if (recordingProgress >= 100) {
220
  recordingProgress = 100;
221
  // Auto-stop after 15 seconds if desired
222
  // stopRecording();
223
  }
224
  }, 100);
 
225
  } catch (error) {
226
  console.error('Error accessing microphone:', error);
227
  showError('Microphone Error', 'Could not access microphone. Please check permissions.');
 
259
  playingRecording = null;
260
  return;
261
  }
262
+
263
  // Stop any currently playing audio
264
  if (currentAudio) {
265
  currentAudio.pause();
266
  currentAudio = null;
267
  }
268
+
269
  // Start playing the new recording
270
  currentAudio = new Audio(recording.url);
271
  playingRecording = recording;
272
+
273
  currentAudio.addEventListener('ended', () => {
274
  playingRecording = null;
275
  currentAudio = null;
276
  });
277
+
278
  currentAudio.addEventListener('pause', () => {
279
  if (currentAudio && currentAudio.ended) {
280
  playingRecording = null;
281
  currentAudio = null;
282
  }
283
  });
284
+
285
  currentAudio.play();
286
  }
287
 
288
+ async function cloneVoice() {
289
+ if (!selectedRecording) {
290
+ showError('Clone Error', 'Please select a recording.');
291
  return;
292
  }
293
+
294
+ isTranscribing = true;
295
+ successMessage = '';
296
+
297
+ try {
298
+ // Create FormData to send the audio file
299
+ const formData = new FormData();
300
+ formData.append('audio_file', selectedRecording.blob, 'recording.wav');
301
+
302
+ const response = await fetch('/api/voice/transcribe', {
303
+ method: 'POST',
304
+ credentials: 'include',
305
+ body: formData,
306
+ });
307
+
308
+ if (!response.ok) {
309
+ const errorText = await response.text();
310
+ throw new Error(`HTTP error! status: ${response.status}, response: ${errorText}`);
311
+ }
312
+
313
+ const result = await response.json();
314
+
315
+ if (result.success) {
316
+ // Store transcription results
317
+ transcriptionStatus[selectedRecording.id] = {
318
+ transcript: result.transcript,
319
+ first_words: result.first_words,
320
+ consent_detected: result.consent_detected,
321
+ };
322
+
323
+ // Force reactivity update
324
+ transcriptionStatus = { ...transcriptionStatus };
325
+
326
+ // Check if the recording meets criteria for upload
327
+ const meetsLengthCriteria = isRecordingLongEnough(selectedRecording);
328
+ const meetsConsentCriteria = result.consent_detected;
329
+
330
+ if (meetsLengthCriteria && meetsConsentCriteria) {
331
+ // Upload to HuggingFace dataset
332
+ isTranscribing = false;
333
+ isUploading = true;
334
+
335
+ try {
336
+ const uploadFormData = new FormData();
337
+ uploadFormData.append('audio_file', selectedRecording.blob, 'recording.wav');
338
+
339
+ const voiceName = `Voice_${Date.now()}`;
340
+ const transcript = encodeURIComponent(result.transcript);
341
+ const duration = Math.floor(selectedRecording.duration);
342
+
343
+ const uploadResponse = await fetch(
344
+ `/api/voice/upload?voice_name=${voiceName}&transcript=${transcript}&duration=${duration}`,
345
+ {
346
+ method: 'POST',
347
+ credentials: 'include',
348
+ body: uploadFormData,
349
+ }
350
+ );
351
+
352
+ if (!uploadResponse.ok) {
353
+ const errorText = await uploadResponse.text();
354
+ throw new Error(`Upload failed: ${errorText}`);
355
+ }
356
+
357
+ const uploadResult = await uploadResponse.json();
358
+
359
+ if (uploadResult.success) {
360
+ // Store upload results
361
+ uploadResults[selectedRecording.id] = uploadResult;
362
+ uploadResults = { ...uploadResults };
363
+
364
+ successMessage = `Your voice has been saved and can be used for text-to-speech generation.`;
365
+
366
+ // Reload user voices to show the new voice
367
+ await loadUserVoices();
368
+ } else {
369
+ showError('Upload Error', uploadResult.error || 'Failed to upload voice');
370
+ }
371
+ } catch (uploadError) {
372
+ showError('Upload Error', `Failed to upload voice: ${uploadError.message}`);
373
+ } finally {
374
+ isUploading = false;
375
+ }
376
+ }
377
+ } else {
378
+ showError('Transcription Error', result.error || 'Failed to transcribe audio');
379
+ }
380
+ } catch (error) {
381
+ showError('Network Error', `Failed to process recording: ${error.message}`);
382
+ } finally {
383
+ if (!isUploading) {
384
+ isTranscribing = false;
385
+ }
386
+ }
387
  }
388
 
389
  async function loadHistoryCount() {
 
404
  }
405
  }
406
 
407
+ async function loadUserVoices() {
408
+ if (!isLoggedIn) return;
409
+
410
+ try {
411
+ const response = await fetch('/api/voice/user-voices', {
412
+ method: 'GET',
413
+ credentials: 'include',
414
+ });
415
+
416
+ if (response.ok) {
417
+ const data = await response.json();
418
+ userVoices = data.voices;
419
+ }
420
+ } catch (error) {
421
+ console.error('Error loading user voices:', error);
422
+ userVoices = [];
423
+ }
424
+ }
425
+
426
+ async function deleteVoice(voiceId) {
427
+ isDeletingVoice = true;
428
+
429
+ try {
430
+ const response = await fetch(`/api/voice/${voiceId}`, {
431
+ method: 'DELETE',
432
+ credentials: 'include',
433
+ });
434
+
435
+ if (response.ok) {
436
+ // Remove the voice from the list
437
+ userVoices = userVoices.filter((voice) => voice.id !== voiceId);
438
+ successMessage = 'Voice deleted successfully';
439
+ setTimeout(() => {
440
+ successMessage = '';
441
+ }, 3000);
442
+ } else {
443
+ const errorData = await response.json();
444
+ showError('Delete Error', errorData.detail || 'Failed to delete voice');
445
+ }
446
+ } catch (error) {
447
+ showError('Delete Error', `Failed to delete voice: ${error.message}`);
448
+ } finally {
449
+ isDeletingVoice = false;
450
+ }
451
+ }
452
+
453
  onMount(async () => {
454
+ await checkAuthStatus();
455
  await loadHistoryCount();
456
+ await loadUserVoices();
457
  });
458
  </script>
459
 
 
462
  </svelte:head>
463
 
464
  <div class="flex flex-col h-full">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
465
  <div class="flex-1 flex">
466
  <!-- Main content area -->
467
  <div class="flex-1 flex flex-col p-6">
468
+ <!-- Script reading area -->
469
+ <div class="flex-1 pb-24 relative flex flex-col">
470
+ <!-- Script text -->
471
+ <div class="relative mb-4">
472
+ <div class="absolute top-3 left-3 flex items-center gap-2 z-10">
473
+ <span class="text-sm text-gray-400">Sample script</span>
474
+ </div>
475
+ <div class="absolute top-3 right-3 flex items-center gap-2 z-10">
476
+ <button
477
+ on:click={shuffleSampleText}
478
+ class="p-1 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-lg transition-colors"
479
+ title="Try a different sample text"
480
+ >
481
+ <Shuffle size={16} />
482
+ </button>
483
+ </div>
484
+ <div
485
+ class="w-full h-80 pt-10 px-6 pb-6 bg-white border border-amber-400 rounded-lg text-gray-900 text-lg leading-relaxed overflow-y-auto"
486
+ >
487
+ <p>
488
+ <span class="bg-yellow-50 px-2 py-1 rounded border border-amber-200"
489
+ >I consent to cloning my voice.</span
490
+ >
491
+ {sampleTexts[currentSampleIndex]}
492
+ </p>
493
+ </div>
494
  </div>
 
495
 
496
+ <!-- Record button -->
497
+ <div class="flex justify-center items-center flex-1 relative">
498
+ <!-- Concentric circles for amplitude visualization -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
499
  {#if isRecording}
500
+ <div class="absolute inset-0 flex items-center justify-center">
501
+ <div
502
+ class="absolute rounded-full border-2 border-orange-300 transition-all duration-75"
503
+ style="width: {120 + audioAmplitude * 120}px; height: {120 +
504
+ audioAmplitude * 120}px; opacity: {0.4 + audioAmplitude * 0.6}"
505
+ ></div>
506
+ <div
507
+ class="absolute rounded-full border-2 border-orange-200 transition-all duration-100"
508
+ style="width: {150 + audioAmplitude * 150}px; height: {150 +
509
+ audioAmplitude * 150}px; opacity: {0.3 + audioAmplitude * 0.5}"
510
+ ></div>
511
+ <div
512
+ class="absolute rounded-full border-1 border-orange-100 transition-all duration-125"
513
+ style="width: {180 + audioAmplitude * 180}px; height: {180 +
514
+ audioAmplitude * 180}px; opacity: {0.2 + audioAmplitude * 0.4}"
515
+ ></div>
516
+ </div>
517
  {/if}
518
+
519
+ <button
520
+ on:click={toggleRecording}
521
+ class="w-24 h-24 rounded-full flex items-center justify-center transition-all duration-200 shadow-lg relative overflow-hidden z-20 cursor-pointer {isRecording
522
+ ? 'border-4 border-orange-500 bg-transparent'
523
+ : 'bg-orange-500 hover:bg-orange-600'}"
524
+ >
525
+ {#if isRecording}
526
+ <!-- Filling effect -->
527
+ <div
528
+ class="absolute bottom-0 left-0 right-0 bg-orange-500 transition-all duration-100 ease-linear rounded-full"
529
+ style="height: {recordingProgress}%"
530
+ ></div>
531
+ <Square
532
+ size={36}
533
+ class="{recordingProgress >= 100 ? 'text-white' : 'text-orange-700'} relative z-10"
534
+ />
535
+ {:else}
536
+ <Mic size={36} class="text-white" />
537
+ {/if}
538
+ </button>
539
+ </div>
540
+ <div class="mb-6">
541
+ <p class="text-center">
542
+ <em
543
+ >Record your voice for at least 3 seconds to create a voice clone. To prevent
544
+ unauthorized voice cloning, you must start by clearly saying "I consent to cloning my
545
+ voice" — the rest of the text is arbitrary. Try reading the sample above.</em
546
+ >
547
+ </p>
548
+ </div>
549
  </div>
550
  </div>
 
551
 
552
+ <!-- Right panel for voice cloning -->
553
+ <div class="w-80 border-l border-gray-200 bg-white p-3 overflow-y-auto">
554
+ {#if !isLoggedIn && showLoginPrompt}
555
+ <!-- Login prompt message -->
556
+ <div
557
+ class="mb-3 px-3 py-2 bg-gradient-to-r from-amber-50 to-orange-50 rounded-lg border border-amber-200 relative"
558
+ >
559
+ <!-- Close button -->
560
+ <button
561
+ on:click={() => (showLoginPrompt = false)}
562
+ class="absolute top-2 right-2 text-gray-400 hover:text-gray-600 transition-colors"
563
+ aria-label="Dismiss"
564
+ >
565
+ <svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
566
+ <path
567
+ stroke-linecap="round"
568
+ stroke-linejoin="round"
569
+ stroke-width="2"
570
+ d="M6 18L18 6M6 6l12 12"
571
+ />
572
+ </svg>
573
+ </button>
574
+
575
+ <p class="text-sm font-medium text-gray-700 mb-1 pr-4">
576
+ Hugging Face <span
577
+ class="bg-gradient-to-r from-purple-500 via-pink-500 via-green-500 to-blue-500 bg-clip-text text-transparent font-bold"
578
+ >PRO</span
579
+ >
580
+ </p>
581
+ <p class="text-sm text-gray-600 pr-4">
582
+ Sign in to with your Hugging Face <a
583
+ href="https://huggingface.co/pro"
584
+ target="_blank"
585
+ class="text-amber-600 hover:text-amber-700 underline font-medium">PRO account</a
586
+ > to get started with $2 of free API credits per month. You can add a billing method for
587
+ additional pay-as-you-go usage ⤴
588
+ </p>
589
  </div>
590
+ {/if}
591
+
592
+ <!-- Existing voices section -->
593
+ {#if isLoggedIn && userVoices.length > 0}
594
+ <div class="mb-6">
595
+ <h3 class="text-sm font-medium text-gray-700 mb-3">Your Voices</h3>
596
+ <div class="space-y-2">
597
+ {#each userVoices as voice}
598
+ <div class="border rounded-lg p-3 bg-blue-50 border-blue-200">
599
+ <div class="flex items-center justify-between mb-2">
600
+ <span class="text-sm font-medium text-blue-900">{voice.voice_name}</span>
601
+ <div class="flex items-center gap-2">
602
+ <audio controls class="h-8" style="max-width: 120px;">
603
+ <source src={voice.voice_url} type="audio/wav" />
604
+ </audio>
605
+ <button
606
+ on:click={() => deleteVoice(voice.id)}
607
+ disabled={isDeletingVoice}
608
+ class="p-1 text-red-600 hover:text-red-800 hover:bg-red-100 rounded transition-colors disabled:opacity-50"
609
+ title="Delete voice"
610
+ >
611
+ {#if isDeletingVoice}
612
+ <Loader2 size={14} class="animate-spin" />
613
+ {:else}
614
+ <X size={14} />
615
+ {/if}
616
+ </button>
617
+ </div>
618
+ </div>
619
+ <div class="text-xs text-blue-600">
620
+ Expires: {new Date(voice.expires_at).toLocaleDateString()} at {new Date(
621
+ voice.expires_at
622
+ ).toLocaleTimeString()}
623
+ </div>
624
  </div>
625
+ {/each}
626
+ </div>
 
 
 
 
 
 
627
  </div>
628
  {/if}
 
629
 
630
+ <div class="mb-4">
631
+ {#if sessionRecordings.length === 0}
632
+ <div class="text-center py-8 text-gray-500">
633
+ <Mic size={32} class="mx-auto mb-2 opacity-30" />
634
+ <p class="text-sm">Pick a recording to clone</p>
635
+ <p class="text-xs text-gray-400">No recordings yet</p>
636
+ </div>
637
+ {:else}
638
+ <div class="space-y-2">
639
+ {#each sessionRecordings as recording, i}
640
+ <div
641
+ class="border rounded-lg p-3 {selectedRecording?.id === recording.id
642
+ ? 'border-amber-300 bg-amber-50'
643
+ : 'border-gray-200 hover:border-gray-300'} transition-colors"
644
+ >
645
+ <div class="flex items-center justify-between mb-2">
646
+ <span class="text-sm font-medium text-gray-900">Recording {i + 1}</span>
647
+ <button
648
+ on:click={() => togglePlayRecording(recording)}
649
+ class="p-1 hover:bg-gray-100 rounded transition-colors"
650
+ >
651
+ {#if playingRecording?.id === recording.id && currentAudio && !currentAudio.paused}
652
+ <Pause size={14} class="text-gray-600" />
653
+ {:else}
654
+ <Play size={14} class="text-gray-600" />
655
+ {/if}
656
+ </button>
657
+ </div>
658
+ <div class="text-xs text-gray-500 mb-2">
659
+ {recording.timestamp.toLocaleTimeString()}
660
+ </div>
661
+ <button
662
+ on:click={() => selectRecording(recording)}
663
+ class="w-full text-xs px-2 py-1 rounded {selectedRecording?.id === recording.id
664
+ ? 'bg-amber-200 text-amber-800'
665
+ : 'bg-gray-100 text-gray-700 hover:bg-gray-200'} transition-colors"
666
+ >
667
+ {selectedRecording?.id === recording.id ? 'Selected' : 'Select for cloning'}
668
+ </button>
669
+ </div>
670
+ {/each}
671
+ </div>
672
+ {/if}
673
  </div>
674
+
675
+ <!-- Clone section -->
676
+ <div class="mt-6 pt-4 border-t border-gray-200">
677
+ <button
678
+ on:click={cloneVoice}
679
+ disabled={!selectedRecording || isTranscribing || isUploading}
680
+ class="w-full px-4 py-2 bg-gradient-to-r from-amber-400 to-orange-500 text-white rounded-lg font-medium hover:from-amber-500 hover:to-orange-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center justify-center gap-2"
681
+ >
682
+ {#if isTranscribing}
683
+ <Loader2 size={16} class="animate-spin" />
684
+ Transcribing...
685
+ {:else if isUploading}
686
+ <Loader2 size={16} class="animate-spin" />
687
+ Uploading...
688
+ {:else}
689
+ Clone
690
+ {/if}
691
+ </button>
692
+
693
+ <!-- Validation status -->
694
+ <div class="mt-3 text-sm flex items-center gap-4">
695
+ <span
696
+ class="flex items-center gap-1 {selectedRecording
697
+ ? isRecordingLongEnough(selectedRecording)
698
+ ? 'text-green-600'
699
+ : 'text-red-600'
700
+ : 'text-gray-400'}"
701
+ >
702
+ {#if selectedRecording}
703
+ {#if isRecordingLongEnough(selectedRecording)}
704
+
705
+ {:else}
706
+
707
+ {/if}
708
  {:else}
709
 
710
  {/if}
711
+ at least 3 seconds
712
  </span>
713
+ <span
714
+ class="flex items-center gap-1 {selectedRecording
715
+ ? hasConsent(selectedRecording)
716
+ ? 'text-green-600'
717
+ : transcriptionStatus[selectedRecording.id]
718
+ ? 'text-red-600'
719
+ : 'text-gray-400'
720
+ : 'text-gray-400'}"
721
+ >
722
+ {#if selectedRecording && transcriptionStatus[selectedRecording.id]}
723
+ {#if hasConsent(selectedRecording)}
724
+
725
+ {:else}
726
+
727
+ {/if}
728
  {:else}
729
+
730
  {/if}
731
  includes consent
732
  </span>
733
  </div>
734
+
735
+ <!-- Transcript preview -->
736
+ {#if selectedRecording && transcriptionStatus[selectedRecording.id]}
737
+ <div class="mt-3 p-3 bg-gray-50 rounded-lg border">
738
+ <p class="text-sm text-gray-600 italic">
739
+ "{transcriptionStatus[selectedRecording.id].first_words}..."
740
+ </p>
741
+ </div>
742
+ {/if}
743
+
744
+ <!-- Success message -->
745
+ {#if successMessage}
746
+ <div class="mt-3 p-3 bg-green-50 rounded-lg border border-green-200">
747
+ <p class="text-sm text-green-700">
748
+ {successMessage}
749
+ </p>
750
+ </div>
751
+ {/if}
752
+ </div>
753
  </div>
754
  </div>
755
  </div>
 
756
 
757
  <!-- Error Modal -->
758
  {#if showErrorModal}
759
  <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4">
760
  <div class="bg-white rounded-xl shadow-2xl max-w-2xl w-full max-h-[80vh] flex flex-col">
761
+ <div
762
+ class="flex items-center justify-between p-6 border-b border-gray-200 bg-red-50 flex-shrink-0"
763
+ >
764
  <div class="flex items-center gap-3 min-w-0">
765
+ <div
766
+ class="w-10 h-10 bg-red-100 rounded-full flex items-center justify-center flex-shrink-0"
767
+ >
768
  <AlertCircle size={20} class="text-red-600" />
769
  </div>
770
  <div class="min-w-0">
 
784
  {#if errorDetails}
785
  <div class="bg-gray-50 rounded-lg p-4 border">
786
  <h4 class="text-sm font-medium text-gray-900 mb-2">Error Details:</h4>
787
+ <pre
788
+ class="text-xs text-gray-700 whitespace-pre-wrap font-mono leading-relaxed break-words">{errorDetails}</pre>
789
  </div>
790
  {/if}
791
  </div>
792
+ <div
793
+ class="flex items-center justify-end gap-3 p-6 border-t border-gray-200 bg-gray-50 flex-shrink-0"
794
+ >
795
  <button
796
  on:click={closeErrorModal}
797
  class="px-6 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors"
 
801
  </div>
802
  </div>
803
  </div>
804
+ {/if}
hfstudio/database.py CHANGED
@@ -20,6 +20,20 @@ class CodeHistory(Base):
20
  created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
21
 
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  def get_database_url():
24
  """Get database URL, using persistent storage on Spaces or local directory."""
25
  if os.getenv("SPACE_ID"):
 
20
  created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
21
 
22
 
23
+ class Voice(Base):
24
+ __tablename__ = "voices"
25
+
26
+ id = Column(Integer, primary_key=True, autoincrement=True)
27
+ username = Column(String(255), nullable=False, index=True)
28
+ voice_name = Column(String(255), nullable=False)
29
+ file_path = Column(String(500), nullable=False) # local file path on server
30
+ public_url = Column(String(500), nullable=False) # obfuscated public URL
31
+ transcript = Column(Text, nullable=True)
32
+ duration = Column(Integer, nullable=True) # duration in seconds
33
+ expires_at = Column(DateTime, nullable=False) # expiration timestamp
34
+ created_at = Column(DateTime, default=datetime.utcnow, nullable=False)
35
+
36
+
37
  def get_database_url():
38
  """Get database URL, using persistent storage on Spaces or local directory."""
39
  if os.getenv("SPACE_ID"):
hfstudio/server.py CHANGED
@@ -1,4 +1,13 @@
1
- from fastapi import FastAPI, HTTPException, Request, Depends, Response, Cookie
 
 
 
 
 
 
 
 
 
2
  from fastapi.middleware.cors import CORSMiddleware
3
  from fastapi.responses import FileResponse, HTMLResponse
4
  from fastapi.staticfiles import StaticFiles
@@ -10,12 +19,27 @@ import os
10
  import json
11
  import secrets
12
  import time
 
 
 
 
 
 
13
  from pathlib import Path
14
- from huggingface_hub import InferenceClient, get_token, whoami
 
 
 
 
 
 
 
15
  from huggingface_hub.utils import build_hf_headers
16
  from hfstudio import __version__
17
- from hfstudio.database import create_tables, get_db, CodeHistory
18
  from sqlalchemy.orm import Session
 
 
19
 
20
 
21
  class TTSRequest(BaseModel):
@@ -34,6 +58,7 @@ class TTSResponse(BaseModel):
34
  format: str = "wav"
35
  error: Optional[str] = None
36
  success: bool = True
 
37
 
38
 
39
  app = FastAPI(title="HFStudio API", version="0.1.0")
@@ -96,6 +121,40 @@ def require_auth(
96
 
97
  static_dir = Path(__file__).parent / "static"
98
  models_dir = Path(__file__).parent.parent / "models"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
99
 
100
 
101
  def is_running_on_spaces() -> bool:
@@ -132,17 +191,25 @@ def generate_tts_with_client(
132
  if request.voice_id.lower() in voice_urls:
133
  extra_body["audio_url"] = voice_urls[request.voice_id.lower()]
134
 
 
 
135
  audio_bytes = client.text_to_speech(
136
  request.text,
137
  extra_body=extra_body if extra_body else None,
138
  )
 
139
 
140
  audio_base64 = base64.b64encode(audio_bytes).decode("utf-8")
141
  audio_url = f"data:audio/wav;base64,{audio_base64}"
142
 
143
  duration = len(request.text) * 0.05
144
 
145
- return TTSResponse(audio_url=audio_url, duration=duration, format="wav")
 
 
 
 
 
146
  except Exception as e:
147
  error_str = str(e)
148
 
@@ -181,7 +248,7 @@ app.add_middleware(
181
  )
182
 
183
 
184
- class Voice(BaseModel):
185
  id: str
186
  name: str
187
  preview_url: Optional[str] = None
@@ -229,6 +296,39 @@ class HistoryResponse(BaseModel):
229
  entries: list[HistoryEntryResponse]
230
 
231
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
232
  @app.get("/")
233
  async def root():
234
  index_path = static_dir / "index.html"
@@ -250,7 +350,7 @@ async def get_status():
250
 
251
  @app.get("/api/auth/oauth-config")
252
  async def get_oauth_config():
253
- scopes = os.getenv("OAUTH_SCOPES", "inference-api")
254
 
255
  return {
256
  "client_id": os.getenv(
@@ -317,7 +417,7 @@ async def get_voices():
317
  model_spec = load_model_spec(model_dir.name)
318
  if model_spec and "voices" in model_spec:
319
  for voice_spec in model_spec["voices"]:
320
- voice = Voice(
321
  id=voice_spec["id"],
322
  name=voice_spec["name"],
323
  preview_url=model_spec.get("api", {})
@@ -715,17 +815,21 @@ async def oauth_callback(
715
  # Create session and set HTTP-only cookie
716
  session_id = create_session(access_token, user_info)
717
 
718
- # Determine redirect URL based on environment
 
719
  if (
720
  not is_running_on_spaces()
721
  and referer
722
  and "localhost:11111" in referer
723
  ):
724
  # Local development - redirect to frontend port
725
- redirect_url = "http://localhost:11111/"
 
 
 
 
726
  else:
727
- # Production or same-origin - redirect to root
728
- redirect_url = "/"
729
 
730
  html_response = HTMLResponse(f"""
731
  <html>
@@ -788,6 +892,274 @@ async def oauth_callback(
788
  )
789
 
790
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
791
  @app.get("/{path:path}")
792
  async def serve_spa(path: str):
793
  if (
@@ -813,6 +1185,19 @@ async def serve_spa(path: str):
813
  """)
814
 
815
 
 
 
 
 
 
 
 
 
 
 
 
 
 
816
  if __name__ == "__main__":
817
  import uvicorn
818
 
 
1
+ from fastapi import (
2
+ FastAPI,
3
+ HTTPException,
4
+ Request,
5
+ Depends,
6
+ Response,
7
+ Cookie,
8
+ UploadFile,
9
+ File,
10
+ )
11
  from fastapi.middleware.cors import CORSMiddleware
12
  from fastapi.responses import FileResponse, HTMLResponse
13
  from fastapi.staticfiles import StaticFiles
 
19
  import json
20
  import secrets
21
  import time
22
+ import tempfile
23
+ import io
24
+ import random
25
+ import string
26
+ import uuid
27
+ from datetime import datetime, timedelta
28
  from pathlib import Path
29
+ from huggingface_hub import (
30
+ InferenceClient,
31
+ get_token,
32
+ whoami,
33
+ HfApi,
34
+ create_repo,
35
+ RepoUrl,
36
+ )
37
  from huggingface_hub.utils import build_hf_headers
38
  from hfstudio import __version__
39
+ from hfstudio.database import create_tables, get_db, CodeHistory, Voice
40
  from sqlalchemy.orm import Session
41
+ from transformers import pipeline
42
+ import soundfile as sf
43
 
44
 
45
  class TTSRequest(BaseModel):
 
58
  format: str = "wav"
59
  error: Optional[str] = None
60
  success: bool = True
61
+ generation_time: Optional[float] = None
62
 
63
 
64
  app = FastAPI(title="HFStudio API", version="0.1.0")
 
121
 
122
  static_dir = Path(__file__).parent / "static"
123
  models_dir = Path(__file__).parent.parent / "models"
124
+ voices_dir = Path(__file__).parent / "voices"
125
+
126
+ # Create voices directory if it doesn't exist
127
+ voices_dir.mkdir(exist_ok=True)
128
+
129
+
130
+ def generate_voice_url_id() -> str:
131
+ """Generate a long, obfuscated URL ID for voice files."""
132
+ return str(uuid.uuid4()) + "-" + secrets.token_urlsafe(32)
133
+
134
+
135
+ def get_voice_file_path(url_id: str) -> Path:
136
+ """Get the local file path for a voice file."""
137
+ return voices_dir / f"{url_id}.wav"
138
+
139
+
140
+ def cleanup_expired_voices(db: Session):
141
+ """Clean up expired voice files and database records."""
142
+ expired_voices = db.query(Voice).filter(Voice.expires_at < datetime.utcnow()).all()
143
+
144
+ for voice in expired_voices:
145
+ # Delete the file if it exists
146
+ file_path = Path(voice.file_path)
147
+ if file_path.exists():
148
+ try:
149
+ file_path.unlink()
150
+ except Exception as e:
151
+ print(f"Error deleting voice file {file_path}: {e}")
152
+
153
+ # Delete the database record
154
+ db.delete(voice)
155
+
156
+ db.commit()
157
+ return len(expired_voices)
158
 
159
 
160
  def is_running_on_spaces() -> bool:
 
191
  if request.voice_id.lower() in voice_urls:
192
  extra_body["audio_url"] = voice_urls[request.voice_id.lower()]
193
 
194
+ # Time the API call
195
+ start_time = time.time()
196
  audio_bytes = client.text_to_speech(
197
  request.text,
198
  extra_body=extra_body if extra_body else None,
199
  )
200
+ generation_time = time.time() - start_time
201
 
202
  audio_base64 = base64.b64encode(audio_bytes).decode("utf-8")
203
  audio_url = f"data:audio/wav;base64,{audio_base64}"
204
 
205
  duration = len(request.text) * 0.05
206
 
207
+ return TTSResponse(
208
+ audio_url=audio_url,
209
+ duration=duration,
210
+ format="wav",
211
+ generation_time=generation_time,
212
+ )
213
  except Exception as e:
214
  error_str = str(e)
215
 
 
248
  )
249
 
250
 
251
+ class VoiceModel(BaseModel):
252
  id: str
253
  name: str
254
  preview_url: Optional[str] = None
 
296
  entries: list[HistoryEntryResponse]
297
 
298
 
299
+ class VoiceTranscriptionResponse(BaseModel):
300
+ success: bool
301
+ transcript: Optional[str] = None
302
+ first_words: Optional[str] = None
303
+ consent_detected: bool = False
304
+ error: Optional[str] = None
305
+
306
+
307
+ class VoiceUploadRequest(BaseModel):
308
+ voice_name: str
309
+ audio_file_name: str # This will be sent separately as FormData
310
+
311
+
312
+ class VoiceUploadResponse(BaseModel):
313
+ success: bool
314
+ voice_url: Optional[str] = None
315
+ voice_id: Optional[int] = None
316
+ expires_at: Optional[str] = None
317
+ error: Optional[str] = None
318
+
319
+
320
+ class UserVoiceResponse(BaseModel):
321
+ id: int
322
+ voice_name: str
323
+ voice_url: str
324
+ expires_at: str
325
+ created_at: str
326
+
327
+
328
+ class UserVoicesResponse(BaseModel):
329
+ voices: list[UserVoiceResponse]
330
+
331
+
332
  @app.get("/")
333
  async def root():
334
  index_path = static_dir / "index.html"
 
350
 
351
  @app.get("/api/auth/oauth-config")
352
  async def get_oauth_config():
353
+ scopes = os.getenv("OAUTH_SCOPES", "inference-api manage-repos")
354
 
355
  return {
356
  "client_id": os.getenv(
 
417
  model_spec = load_model_spec(model_dir.name)
418
  if model_spec and "voices" in model_spec:
419
  for voice_spec in model_spec["voices"]:
420
+ voice = VoiceModel(
421
  id=voice_spec["id"],
422
  name=voice_spec["name"],
423
  preview_url=model_spec.get("api", {})
 
815
  # Create session and set HTTP-only cookie
816
  session_id = create_session(access_token, user_info)
817
 
818
+ # Determine redirect URL based on environment and state parameter
819
+ base_url = "/"
820
  if (
821
  not is_running_on_spaces()
822
  and referer
823
  and "localhost:11111" in referer
824
  ):
825
  # Local development - redirect to frontend port
826
+ base_url = "http://localhost:11111"
827
+
828
+ # Use state parameter to redirect to original page
829
+ if state and state.startswith("/"):
830
+ redirect_url = f"{base_url}{state}"
831
  else:
832
+ redirect_url = f"{base_url}/"
 
833
 
834
  html_response = HTMLResponse(f"""
835
  <html>
 
892
  )
893
 
894
 
895
+ # Initialize whisper pipeline globally for better performance
896
+ whisper_pipeline = None
897
+
898
+
899
+ def get_whisper_pipeline():
900
+ global whisper_pipeline
901
+ if whisper_pipeline is None:
902
+ whisper_pipeline = pipeline(
903
+ "automatic-speech-recognition", model="openai/whisper-tiny"
904
+ )
905
+ return whisper_pipeline
906
+
907
+
908
+ @app.post("/api/voice/transcribe")
909
+ async def transcribe_voice(
910
+ audio_file: UploadFile = File(...), session: Dict[str, Any] = Depends(require_auth)
911
+ ):
912
+ """Transcribe audio file using whisper-tiny and check for consent."""
913
+ try:
914
+ # Read the uploaded audio file
915
+ audio_content = await audio_file.read()
916
+
917
+ # Create temporary file to save audio
918
+ with tempfile.NamedTemporaryFile(suffix=".wav", delete=False) as temp_file:
919
+ temp_file.write(audio_content)
920
+ temp_file_path = temp_file.name
921
+
922
+ try:
923
+ # Get whisper pipeline
924
+ transcriber = get_whisper_pipeline()
925
+
926
+ # Try to transcribe directly - Whisper can handle many formats
927
+ result = transcriber(temp_file_path)
928
+ transcript = result["text"].strip()
929
+
930
+ # Get first ~8 words for feedback
931
+ words = transcript.split()
932
+ first_words = " ".join(words[:8])
933
+
934
+ # Check for consent (case insensitive)
935
+ consent_phrases = [
936
+ "i consent to cloning my voice",
937
+ "i consent to clone my voice",
938
+ "i consent to voice cloning",
939
+ ]
940
+
941
+ transcript_lower = transcript.lower()
942
+ consent_detected = any(
943
+ phrase in transcript_lower[:50] # Check first 50 characters
944
+ for phrase in consent_phrases
945
+ )
946
+
947
+ return VoiceTranscriptionResponse(
948
+ success=True,
949
+ transcript=transcript,
950
+ first_words=first_words,
951
+ consent_detected=consent_detected,
952
+ )
953
+
954
+ finally:
955
+ # Clean up temporary file
956
+ if os.path.exists(temp_file_path):
957
+ os.unlink(temp_file_path)
958
+
959
+ except Exception as e:
960
+ return VoiceTranscriptionResponse(
961
+ success=False, error=f"Transcription error: {str(e)}"
962
+ )
963
+
964
+
965
+ @app.post("/api/voice/upload")
966
+ async def upload_voice_to_server(
967
+ voice_name: str,
968
+ transcript: str,
969
+ duration: int,
970
+ audio_file: UploadFile = File(...),
971
+ session: Dict[str, Any] = Depends(require_auth),
972
+ db: Session = Depends(get_db),
973
+ ):
974
+ """Upload voice recording to server storage and save to database."""
975
+ try:
976
+ username = session["user_info"].get("name") or session["user_info"].get("login")
977
+ if not username:
978
+ raise HTTPException(status_code=400, detail="Username not found in session")
979
+
980
+ # Clean up any expired voices first
981
+ cleanup_expired_voices(db)
982
+
983
+ # Generate obfuscated URL ID
984
+ url_id = generate_voice_url_id()
985
+ file_path = get_voice_file_path(url_id)
986
+
987
+ # Read and save audio content
988
+ audio_content = await audio_file.read()
989
+
990
+ try:
991
+ with open(file_path, "wb") as f:
992
+ f.write(audio_content)
993
+
994
+ # Set expiration to 24 hours from now
995
+ expires_at = datetime.utcnow() + timedelta(hours=24)
996
+
997
+ # Create public URL (will be served by the voices endpoint)
998
+ public_url = f"/api/voices/{url_id}"
999
+
1000
+ # Save voice info to database
1001
+ voice_record = Voice(
1002
+ username=username,
1003
+ voice_name=voice_name,
1004
+ file_path=str(file_path),
1005
+ public_url=public_url,
1006
+ transcript=transcript,
1007
+ duration=duration,
1008
+ expires_at=expires_at,
1009
+ )
1010
+
1011
+ db.add(voice_record)
1012
+ db.commit()
1013
+ db.refresh(voice_record)
1014
+
1015
+ return VoiceUploadResponse(
1016
+ success=True,
1017
+ voice_url=public_url,
1018
+ voice_id=voice_record.id,
1019
+ expires_at=expires_at.isoformat(),
1020
+ )
1021
+
1022
+ except Exception as file_error:
1023
+ # Clean up file if database save fails
1024
+ if file_path.exists():
1025
+ file_path.unlink()
1026
+ raise file_error
1027
+
1028
+ except Exception as e:
1029
+ db.rollback()
1030
+ return VoiceUploadResponse(success=False, error=f"Upload error: {str(e)}")
1031
+
1032
+
1033
+ @app.get("/api/voice/user-voices")
1034
+ async def get_user_voices(
1035
+ session: Dict[str, Any] = Depends(require_auth), db: Session = Depends(get_db)
1036
+ ) -> UserVoicesResponse:
1037
+ """Get all voice recordings for the authenticated user."""
1038
+ try:
1039
+ username = session["user_info"].get("name") or session["user_info"].get("login")
1040
+ if not username:
1041
+ raise HTTPException(status_code=400, detail="Username not found in session")
1042
+
1043
+ # Clean up expired voices first
1044
+ cleanup_expired_voices(db)
1045
+
1046
+ # Query user's valid (non-expired) voices from database
1047
+ valid_voices = (
1048
+ db.query(Voice)
1049
+ .filter(Voice.username == username)
1050
+ .filter(Voice.expires_at > datetime.utcnow())
1051
+ .order_by(Voice.created_at.desc())
1052
+ .all()
1053
+ )
1054
+
1055
+ # Convert to response format
1056
+ user_voices = []
1057
+ for voice in valid_voices:
1058
+ user_voices.append(
1059
+ UserVoiceResponse(
1060
+ id=voice.id,
1061
+ voice_name=voice.voice_name,
1062
+ voice_url=voice.public_url,
1063
+ expires_at=voice.expires_at.isoformat(),
1064
+ created_at=voice.created_at.isoformat(),
1065
+ )
1066
+ )
1067
+
1068
+ return UserVoicesResponse(voices=user_voices)
1069
+
1070
+ except Exception as e:
1071
+ raise HTTPException(status_code=500, detail=f"Error fetching voices: {str(e)}")
1072
+
1073
+
1074
+ @app.get("/api/voices/{voice_id}")
1075
+ async def serve_voice_file(voice_id: str, db: Session = Depends(get_db)):
1076
+ """Serve voice file by obfuscated ID."""
1077
+ try:
1078
+ # Clean up expired voices first
1079
+ cleanup_expired_voices(db)
1080
+
1081
+ # Find the voice record by public URL
1082
+ voice = (
1083
+ db.query(Voice)
1084
+ .filter(Voice.public_url == f"/api/voices/{voice_id}")
1085
+ .first()
1086
+ )
1087
+
1088
+ if not voice:
1089
+ raise HTTPException(status_code=404, detail="Voice file not found")
1090
+
1091
+ # Check if voice has expired
1092
+ if voice.expires_at < datetime.utcnow():
1093
+ # Clean up expired voice
1094
+ file_path = Path(voice.file_path)
1095
+ if file_path.exists():
1096
+ file_path.unlink()
1097
+ db.delete(voice)
1098
+ db.commit()
1099
+ raise HTTPException(status_code=404, detail="Voice file has expired")
1100
+
1101
+ # Check if file exists
1102
+ file_path = Path(voice.file_path)
1103
+ if not file_path.exists():
1104
+ raise HTTPException(status_code=404, detail="Voice file not found on disk")
1105
+
1106
+ return FileResponse(
1107
+ path=str(file_path),
1108
+ media_type="audio/wav",
1109
+ filename=f"{voice.voice_name}.wav",
1110
+ )
1111
+
1112
+ except HTTPException:
1113
+ raise
1114
+ except Exception as e:
1115
+ raise HTTPException(
1116
+ status_code=500, detail=f"Error serving voice file: {str(e)}"
1117
+ )
1118
+
1119
+
1120
+ @app.delete("/api/voice/{voice_id}")
1121
+ async def delete_voice(
1122
+ voice_id: int,
1123
+ session: Dict[str, Any] = Depends(require_auth),
1124
+ db: Session = Depends(get_db),
1125
+ ):
1126
+ """Delete a voice recording."""
1127
+ try:
1128
+ username = session["user_info"].get("name") or session["user_info"].get("login")
1129
+ if not username:
1130
+ raise HTTPException(status_code=400, detail="Username not found in session")
1131
+
1132
+ # Find the voice record
1133
+ voice = (
1134
+ db.query(Voice)
1135
+ .filter(Voice.id == voice_id, Voice.username == username)
1136
+ .first()
1137
+ )
1138
+
1139
+ if not voice:
1140
+ raise HTTPException(status_code=404, detail="Voice not found")
1141
+
1142
+ # Delete the file if it exists
1143
+ file_path = Path(voice.file_path)
1144
+ if file_path.exists():
1145
+ try:
1146
+ file_path.unlink()
1147
+ except Exception as e:
1148
+ print(f"Error deleting voice file {file_path}: {e}")
1149
+
1150
+ # Delete the database record
1151
+ db.delete(voice)
1152
+ db.commit()
1153
+
1154
+ return {"success": True, "message": "Voice deleted successfully"}
1155
+
1156
+ except HTTPException:
1157
+ raise
1158
+ except Exception as e:
1159
+ db.rollback()
1160
+ raise HTTPException(status_code=500, detail=f"Error deleting voice: {str(e)}")
1161
+
1162
+
1163
  @app.get("/{path:path}")
1164
  async def serve_spa(path: str):
1165
  if (
 
1185
  """)
1186
 
1187
 
1188
+ # Background cleanup job for expired voices
1189
+ @app.on_event("startup")
1190
+ async def startup_event():
1191
+ """Run cleanup on startup."""
1192
+ db = SessionLocal()
1193
+ try:
1194
+ cleaned_count = cleanup_expired_voices(db)
1195
+ if cleaned_count > 0:
1196
+ print(f"Cleaned up {cleaned_count} expired voice files on startup")
1197
+ finally:
1198
+ db.close()
1199
+
1200
+
1201
  if __name__ == "__main__":
1202
  import uvicorn
1203
 
hfstudio/static/_app/immutable/assets/0.3AZkBLcv.css ADDED
@@ -0,0 +1 @@
 
 
1
+ *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.inset-0{top:0;right:0;bottom:0;left:0}.-left-full{left:-100%}.bottom-0{bottom:0}.bottom-4{bottom:1rem}.bottom-full{bottom:100%}.left-0{left:0}.left-3{left:.75rem}.right-0{right:0}.right-2{right:.5rem}.right-3{right:.75rem}.right-4{right:1rem}.top-2{top:.5rem}.top-3{top:.75rem}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.ml-0\.5{margin-left:.125rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.block{display:block}.flex{display:flex}.grid{display:grid}.contents{display:contents}.hidden{display:none}.h-1{height:.25rem}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-2{height:.5rem}.h-24{height:6rem}.h-3{height:.75rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-8{height:2rem}.h-80{height:20rem}.h-full{height:100%}.h-screen{height:100vh}.max-h-\[80vh\]{max-height:80vh}.min-h-0{min-height:0px}.min-h-\[73px\]{min-height:73px}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-24{width:6rem}.w-3{width:.75rem}.w-4{width:1rem}.w-5{width:1.25rem}.w-56{width:14rem}.w-6{width:1.5rem}.w-8{width:2rem}.w-80{width:20rem}.w-96{width:24rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.flex-shrink-0{flex-shrink:0}.rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.items-center{align-items:center}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.rounded-b-lg{border-bottom-right-radius:.5rem;border-bottom-left-radius:.5rem}.rounded-t-lg{border-top-left-radius:.5rem;border-top-right-radius:.5rem}.border{border-width:1px}.border-2{border-width:2px}.border-4{border-width:4px}.border-b{border-bottom-width:1px}.border-b-0{border-bottom-width:0px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-t-0{border-top-width:0px}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-amber-300{--tw-border-opacity: 1;border-color:rgb(252 211 77 / var(--tw-border-opacity, 1))}.border-amber-400{--tw-border-opacity: 1;border-color:rgb(251 191 36 / var(--tw-border-opacity, 1))}.border-blue-200{--tw-border-opacity: 1;border-color:rgb(191 219 254 / var(--tw-border-opacity, 1))}.border-gray-100{--tw-border-opacity: 1;border-color:rgb(243 244 246 / var(--tw-border-opacity, 1))}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-gray-300{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.border-green-200{--tw-border-opacity: 1;border-color:rgb(187 247 208 / var(--tw-border-opacity, 1))}.border-orange-100{--tw-border-opacity: 1;border-color:rgb(255 237 213 / var(--tw-border-opacity, 1))}.border-orange-200{--tw-border-opacity: 1;border-color:rgb(254 215 170 / var(--tw-border-opacity, 1))}.border-orange-300{--tw-border-opacity: 1;border-color:rgb(253 186 116 / var(--tw-border-opacity, 1))}.border-orange-500{--tw-border-opacity: 1;border-color:rgb(249 115 22 / var(--tw-border-opacity, 1))}.border-purple-200{--tw-border-opacity: 1;border-color:rgb(233 213 255 / var(--tw-border-opacity, 1))}.border-purple-400{--tw-border-opacity: 1;border-color:rgb(192 132 252 / var(--tw-border-opacity, 1))}.bg-amber-100{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-amber-200{--tw-bg-opacity: 1;background-color:rgb(253 230 138 / var(--tw-bg-opacity, 1))}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-200{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-gray-900{--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.bg-green-50{--tw-bg-opacity: 1;background-color:rgb(240 253 244 / var(--tw-bg-opacity, 1))}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-orange-500{--tw-bg-opacity: 1;background-color:rgb(249 115 22 / var(--tw-bg-opacity, 1))}.bg-purple-50{--tw-bg-opacity: 1;background-color:rgb(250 245 255 / var(--tw-bg-opacity, 1))}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-red-600{--tw-bg-opacity: 1;background-color:rgb(220 38 38 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-yellow-50{--tw-bg-opacity: 1;background-color:rgb(254 252 232 / var(--tw-bg-opacity, 1))}.bg-opacity-50{--tw-bg-opacity: .5}.bg-gradient-to-b{background-image:linear-gradient(to bottom,var(--tw-gradient-stops))}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.from-amber-400{--tw-gradient-from: #fbbf24 var(--tw-gradient-from-position);--tw-gradient-to: rgb(251 191 36 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-amber-50{--tw-gradient-from: #fffbeb var(--tw-gradient-from-position);--tw-gradient-to: rgb(255 251 235 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-amber-500{--tw-gradient-from: #f59e0b var(--tw-gradient-from-position);--tw-gradient-to: rgb(245 158 11 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-gray-50{--tw-gradient-from: #f9fafb var(--tw-gradient-from-position);--tw-gradient-to: rgb(249 250 251 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-purple-400{--tw-gradient-from: #c084fc var(--tw-gradient-from-position);--tw-gradient-to: rgb(192 132 252 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-purple-500{--tw-gradient-from: #a855f7 var(--tw-gradient-from-position);--tw-gradient-to: rgb(168 85 247 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-transparent{--tw-gradient-from: transparent var(--tw-gradient-from-position);--tw-gradient-to: rgb(0 0 0 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.via-green-500{--tw-gradient-to: rgb(34 197 94 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #22c55e var(--tw-gradient-via-position), var(--tw-gradient-to)}.via-orange-400\/40{--tw-gradient-to: rgb(251 146 60 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), rgb(251 146 60 / .4) var(--tw-gradient-via-position), var(--tw-gradient-to)}.via-pink-500{--tw-gradient-to: rgb(236 72 153 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #ec4899 var(--tw-gradient-via-position), var(--tw-gradient-to)}.to-blue-500{--tw-gradient-to: #3b82f6 var(--tw-gradient-to-position)}.to-orange-50{--tw-gradient-to: #fff7ed var(--tw-gradient-to-position)}.to-orange-500{--tw-gradient-to: #f97316 var(--tw-gradient-to-position)}.to-pink-500{--tw-gradient-to: #ec4899 var(--tw-gradient-to-position)}.to-transparent{--tw-gradient-to: transparent var(--tw-gradient-to-position)}.to-white{--tw-gradient-to: #fff var(--tw-gradient-to-position)}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-24{padding-bottom:6rem}.pb-6{padding-bottom:1.5rem}.pr-4{padding-right:1rem}.pt-10{padding-top:2.5rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.italic{font-style:italic}.leading-relaxed{line-height:1.625}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-amber-800{--tw-text-opacity: 1;color:rgb(146 64 14 / var(--tw-text-opacity, 1))}.text-amber-900{--tw-text-opacity: 1;color:rgb(120 53 15 / var(--tw-text-opacity, 1))}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / var(--tw-text-opacity, 1))}.text-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-blue-800{--tw-text-opacity: 1;color:rgb(30 64 175 / var(--tw-text-opacity, 1))}.text-blue-900{--tw-text-opacity: 1;color:rgb(30 58 138 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-green-700{--tw-text-opacity: 1;color:rgb(21 128 61 / var(--tw-text-opacity, 1))}.text-green-900{--tw-text-opacity: 1;color:rgb(20 83 45 / var(--tw-text-opacity, 1))}.text-orange-700{--tw-text-opacity: 1;color:rgb(194 65 12 / var(--tw-text-opacity, 1))}.text-purple-600{--tw-text-opacity: 1;color:rgb(147 51 234 / var(--tw-text-opacity, 1))}.text-purple-900{--tw-text-opacity: 1;color:rgb(88 28 135 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-transparent{color:transparent}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.opacity-30{opacity:.3}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-md{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-100{transition-duration:.1s}.duration-200{transition-duration:.2s}.duration-75{transition-duration:75ms}.ease-linear{transition-timing-function:linear}code[class*=language-],pre[class*=language-]{color:#393a34;font-family:Consolas,Bitstream Vera Sans Mono,Courier New,Courier,monospace;direction:ltr;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;font-size:.875rem;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;hyphens:none}pre[class*=language-]{padding:1rem;margin:0;overflow:auto;background:#f8f9fa}.token.comment,.token.prolog,.token.doctype,.token.cdata{color:green;font-style:italic}.token.punctuation{color:#393a34}.token.property,.token.tag,.token.boolean,.token.number,.token.constant,.token.symbol,.token.deleted{color:#e91e63}.token.selector,.token.attr-name,.token.string,.token.char,.token.builtin,.token.inserted{color:#067d17}.token.operator,.token.entity,.token.url,.language-css .token.string,.style .token.string{color:#795da3}.token.atrule,.token.attr-value,.token.keyword{color:#00f}.token.function,.token.class-name{color:#795da3}.token.regex,.token.important,.token.variable{color:#e90}.language-bash .token.function{color:#067d17}.slider-hf::-webkit-slider-thumb{height:1rem;width:1rem;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:9999px;background:linear-gradient(45deg,#ffd21e,#ff9d00);box-shadow:0 1px 3px #0000001a}.slider-hf::-moz-range-thumb{height:1rem;width:1rem;cursor:pointer;border-radius:9999px;border-width:0px;background:linear-gradient(45deg,#ffd21e,#ff9d00);box-shadow:0 1px 3px #0000001a}.pause-filled{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px}.pause-filled:before,.pause-filled:after{content:"";width:2px;height:10px;background-color:currentColor;border-radius:1px}.pause-filled:before{margin-right:2px}.pause-filled:after{margin-left:2px}.hover\:border-gray-300:hover{--tw-border-opacity: 1;border-color:rgb(209 213 219 / var(--tw-border-opacity, 1))}.hover\:bg-amber-100:hover{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-100:hover{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-100:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-200:hover{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-50:hover{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-800:hover{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.hover\:bg-green-100:hover{--tw-bg-opacity: 1;background-color:rgb(220 252 231 / var(--tw-bg-opacity, 1))}.hover\:bg-orange-600:hover{--tw-bg-opacity: 1;background-color:rgb(234 88 12 / var(--tw-bg-opacity, 1))}.hover\:bg-purple-50:hover{--tw-bg-opacity: 1;background-color:rgb(250 245 255 / var(--tw-bg-opacity, 1))}.hover\:bg-red-100:hover{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.hover\:bg-red-700:hover{--tw-bg-opacity: 1;background-color:rgb(185 28 28 / var(--tw-bg-opacity, 1))}.hover\:from-amber-500:hover{--tw-gradient-from: #f59e0b var(--tw-gradient-from-position);--tw-gradient-to: rgb(245 158 11 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.hover\:from-amber-600:hover{--tw-gradient-from: #d97706 var(--tw-gradient-from-position);--tw-gradient-to: rgb(217 119 6 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.hover\:to-orange-600:hover{--tw-gradient-to: #ea580c var(--tw-gradient-to-position)}.hover\:text-amber-700:hover{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.hover\:text-gray-600:hover{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.hover\:text-gray-800:hover{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.hover\:text-red-800:hover{--tw-text-opacity: 1;color:rgb(153 27 27 / var(--tw-text-opacity, 1))}.focus\:border-transparent:focus{border-color:transparent}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-amber-400:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(251 191 36 / var(--tw-ring-opacity, 1))}.focus\:ring-orange-500:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(249 115 22 / var(--tw-ring-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media (min-width: 1024px){.lg\:grid-cols-\[1fr_1\.4fr_1fr\]{grid-template-columns:1fr 1.4fr 1fr}}@keyframes svelte-1s3xy1i-sweep{0%{transform:translate(-100%)}to{transform:translate(300%)}}
hfstudio/static/_app/immutable/assets/2.CdRym-eY.css ADDED
@@ -0,0 +1 @@
 
 
1
+ @keyframes svelte-13ak1iw-fade-in{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.animate-fade-in.svelte-13ak1iw{animation:svelte-13ak1iw-fade-in .3s ease-out}.pause-filled.svelte-13ak1iw:after{content:"";width:3px;height:12px;background:currentColor;display:inline-block;margin-right:2px}.pause-filled.svelte-13ak1iw:before{content:"";width:3px;height:12px;background:currentColor;display:inline-block;margin-right:2px}
hfstudio/static/_app/immutable/chunks/4G_mFUFB.js ADDED
@@ -0,0 +1 @@
 
 
1
+ import{S as f,i as m,s as p,u as c,v as d,w as u,x as _,y as g,z as $,A as h,B as r,C as v,D as M,E as N,F as b}from"./BaOlNwUz.js";import{I as C,g as I,a as S}from"./C7BncMoR.js";import"./IHki7fMi.js";function j(l){let e;const a=l[2].default,s=v(a,l,l[3],null);return{c(){s&&s.c()},l(n){s&&s.l(n)},m(n,t){s&&s.m(n,t),e=!0},p(n,t){s&&s.p&&(!e||t&8)&&M(s,a,n,n[3],e?b(a,n[3],t,null):N(n[3]),null)},i(n){e||(_(s,n),e=!0)},o(n){u(s,n),e=!1},d(n){s&&s.d(n)}}}function q(l){let e,a;const s=[{name:"mic"},l[1],{iconNode:l[0]}];let n={$$slots:{default:[j]},$$scope:{ctx:l}};for(let t=0;t<s.length;t+=1)n=c(n,s[t]);return e=new C({props:n}),{c(){h(e.$$.fragment)},l(t){$(e.$$.fragment,t)},m(t,o){g(e,t,o),a=!0},p(t,[o]){const i=o&3?I(s,[s[0],o&2&&S(t[1]),o&1&&{iconNode:t[0]}]):{};o&8&&(i.$$scope={dirty:o,ctx:t}),e.$set(i)},i(t){a||(_(e.$$.fragment,t),a=!0)},o(t){u(e.$$.fragment,t),a=!1},d(t){d(e,t)}}}function z(l,e,a){let{$$slots:s={},$$scope:n}=e;const t=[["path",{d:"M12 2a3 3 0 0 0-3 3v7a3 3 0 0 0 6 0V5a3 3 0 0 0-3-3Z"}],["path",{d:"M19 10v2a7 7 0 0 1-14 0v-2"}],["line",{x1:"12",x2:"12",y1:"19",y2:"22"}]];return l.$$set=o=>{a(1,e=c(c({},e),r(o))),"$$scope"in o&&a(3,n=o.$$scope)},e=r(e),[t,e,s,n]}class E extends f{constructor(e){super(),m(this,e,z,q,p,{})}}export{E as M};
hfstudio/static/_app/immutable/chunks/B7RJWGyJ.js ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ var kt=Object.defineProperty;var St=(e,t,n)=>t in e?kt(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var R=(e,t,n)=>St(e,typeof t!="symbol"?t+"":t,n);import{S as Et,U as At,$ as Rt,a0 as Tt,a1 as It,a2 as Ut,a3 as Lt,a4 as $t,K as ve,a5 as xt,V as be,n as ge,s as Ct}from"./BaOlNwUz.js";class Ze extends Et{constructor(n){if(!n||!n.target&&!n.$$inline)throw new Error("'target' is a required option");super();R(this,"$$prop_def");R(this,"$$events_def");R(this,"$$slot_def")}$destroy(){super.$destroy(),this.$destroy=()=>{console.warn("Component was already destroyed")}}$capture_state(){}$inject_state(){}}class Pt extends Ze{}const Ot=Object.freeze(Object.defineProperty({__proto__:null,SvelteComponent:Ze,SvelteComponentTyped:Pt,afterUpdate:At,beforeUpdate:Rt,createEventDispatcher:Tt,getAllContexts:It,getContext:Ut,hasContext:Lt,onDestroy:$t,onMount:ve,setContext:xt,tick:be},Symbol.toStringTag,{value:"Module"}));class ie{constructor(t,n){this.status=t,typeof n=="string"?this.body={message:n}:n?this.body=n:this.body={message:`Error: ${t}`}}toString(){return JSON.stringify(this.body)}}class Re{constructor(t,n){this.status=t,this.location=n}}class Te extends Error{constructor(t,n,r){super(r),this.status=t,this.text=n}}new URL("sveltekit-internal://");function Nt(e,t){return e==="/"||t==="ignore"?e:t==="never"?e.endsWith("/")?e.slice(0,-1):e:t==="always"&&!e.endsWith("/")?e+"/":e}function jt(e){return e.split("%25").map(decodeURI).join("%25")}function Dt(e){for(const t in e)e[t]=decodeURIComponent(e[t]);return e}function me({href:e}){return e.split("#")[0]}function Bt(e,t,n,r=!1){const a=new URL(e);Object.defineProperty(a,"searchParams",{value:new Proxy(a.searchParams,{get(i,o){if(o==="get"||o==="getAll"||o==="has")return l=>(n(l),i[o](l));t();const c=Reflect.get(i,o);return typeof c=="function"?c.bind(i):c}}),enumerable:!0,configurable:!0});const s=["href","pathname","search","toString","toJSON"];r&&s.push("hash");for(const i of s)Object.defineProperty(a,i,{get(){return t(),e[i]},enumerable:!0,configurable:!0});return a}function Ft(...e){let t=5381;for(const n of e)if(typeof n=="string"){let r=n.length;for(;r;)t=t*33^n.charCodeAt(--r)}else if(ArrayBuffer.isView(n)){const r=new Uint8Array(n.buffer,n.byteOffset,n.byteLength);let a=r.length;for(;a;)t=t*33^r[--a]}else throw new TypeError("value must be a string or TypedArray");return(t>>>0).toString(36)}new TextEncoder;const Vt=new TextDecoder;function Mt(e){const t=atob(e),n=new Uint8Array(t.length);for(let r=0;r<t.length;r++)n[r]=t.charCodeAt(r);return n}const qt=window.fetch;window.fetch=(e,t)=>((e instanceof Request?e.method:(t==null?void 0:t.method)||"GET")!=="GET"&&K.delete(Ie(e)),qt(e,t));const K=new Map;function Gt(e,t){const n=Ie(e,t),r=document.querySelector(n);if(r!=null&&r.textContent){r.remove();let{body:a,...s}=JSON.parse(r.textContent);const i=r.getAttribute("data-ttl");return i&&K.set(n,{body:a,init:s,ttl:1e3*Number(i)}),r.getAttribute("data-b64")!==null&&(a=Mt(a)),Promise.resolve(new Response(a,s))}return window.fetch(e,t)}function Kt(e,t,n){if(K.size>0){const r=Ie(e,n),a=K.get(r);if(a){if(performance.now()<a.ttl&&["default","force-cache","only-if-cached",void 0].includes(n==null?void 0:n.cache))return new Response(a.body,a.init);K.delete(r)}}return window.fetch(t,n)}function Ie(e,t){let r=`script[data-sveltekit-fetched][data-url=${JSON.stringify(e instanceof Request?e.url:e)}]`;if(t!=null&&t.headers||t!=null&&t.body){const a=[];t.headers&&a.push([...new Headers(t.headers)].join(",")),t.body&&(typeof t.body=="string"||ArrayBuffer.isView(t.body))&&a.push(t.body),r+=`[data-hash="${Ft(...a)}"]`}return r}const Yt=/^(\[)?(\.\.\.)?(\w+)(?:=(\w+))?(\])?$/;function Ht(e){const t=[];return{pattern:e==="/"?/^\/$/:new RegExp(`^${Wt(e).map(r=>{const a=/^\[\.\.\.(\w+)(?:=(\w+))?\]$/.exec(r);if(a)return t.push({name:a[1],matcher:a[2],optional:!1,rest:!0,chained:!0}),"(?:/([^]*))?";const s=/^\[\[(\w+)(?:=(\w+))?\]\]$/.exec(r);if(s)return t.push({name:s[1],matcher:s[2],optional:!0,rest:!1,chained:!0}),"(?:/([^/]+))?";if(!r)return;const i=r.split(/\[(.+?)\](?!\])/);return"/"+i.map((c,l)=>{if(l%2){if(c.startsWith("x+"))return _e(String.fromCharCode(parseInt(c.slice(2),16)));if(c.startsWith("u+"))return _e(String.fromCharCode(...c.slice(2).split("-").map(u=>parseInt(u,16))));const d=Yt.exec(c),[,h,y,f,p]=d;return t.push({name:f,matcher:p,optional:!!h,rest:!!y,chained:y?l===1&&i[0]==="":!1}),y?"([^]*?)":h?"([^/]*)?":"([^/]+?)"}return _e(c)}).join("")}).join("")}/?$`),params:t}}function zt(e){return e!==""&&!/^\([^)]+\)$/.test(e)}function Wt(e){return e.slice(1).split("/").filter(zt)}function Jt(e,t,n){const r={},a=e.slice(1),s=a.filter(o=>o!==void 0);let i=0;for(let o=0;o<t.length;o+=1){const c=t[o];let l=a[o-i];if(c.chained&&c.rest&&i&&(l=a.slice(o-i,o+1).filter(d=>d).join("/"),i=0),l===void 0){c.rest&&(r[c.name]="");continue}if(!c.matcher||n[c.matcher](l)){r[c.name]=l;const d=t[o+1],h=a[o+1];d&&!d.rest&&d.optional&&h&&c.chained&&(i=0),!d&&!h&&Object.keys(r).length===s.length&&(i=0);continue}if(c.optional&&c.chained){i++;continue}return}if(!i)return r}function _e(e){return e.normalize().replace(/[[\]]/g,"\\$&").replace(/%/g,"%25").replace(/\//g,"%2[Ff]").replace(/\?/g,"%3[Ff]").replace(/#/g,"%23").replace(/[.*+?^${}()|\\]/g,"\\$&")}function Xt({nodes:e,server_loads:t,dictionary:n,matchers:r}){const a=new Set(t);return Object.entries(n).map(([o,[c,l,d]])=>{const{pattern:h,params:y}=Ht(o),f={id:o,exec:p=>{const u=h.exec(p);if(u)return Jt(u,y,r)},errors:[1,...d||[]].map(p=>e[p]),layouts:[0,...l||[]].map(i),leaf:s(c)};return f.errors.length=f.layouts.length=Math.max(f.errors.length,f.layouts.length),f});function s(o){const c=o<0;return c&&(o=~o),[c,e[o]]}function i(o){return o===void 0?o:[a.has(o),e[o]]}}function Qe(e,t=JSON.parse){try{return t(sessionStorage[e])}catch{}}function Fe(e,t,n=JSON.stringify){const r=n(t);try{sessionStorage[e]=r}catch{}}const D=[];function Ue(e,t=ge){let n;const r=new Set;function a(o){if(Ct(e,o)&&(e=o,n)){const c=!D.length;for(const l of r)l[1](),D.push(l,e);if(c){for(let l=0;l<D.length;l+=2)D[l][0](D[l+1]);D.length=0}}}function s(o){a(o(e))}function i(o,c=ge){const l=[o,c];return r.add(l),r.size===1&&(n=t(a,s)||ge),o(e),()=>{r.delete(l),r.size===0&&n&&(n(),n=null)}}return{set:a,update:s,subscribe:i}}var Je;const $=((Je=globalThis.__sveltekit_1wyakc0)==null?void 0:Je.base)??"";var Xe;const Zt=((Xe=globalThis.__sveltekit_1wyakc0)==null?void 0:Xe.assets)??$??"",Qt="1761278727586",et="sveltekit:snapshot",tt="sveltekit:scroll",nt="sveltekit:states",en="sveltekit:pageurl",F="sveltekit:history",z="sveltekit:navigation",O={tap:1,hover:2,viewport:3,eager:4,off:-1,false:-1},ce=location.origin;function at(e){if(e instanceof URL)return e;let t=document.baseURI;if(!t){const n=document.getElementsByTagName("base");t=n.length?n[0].href:document.URL}return new URL(e,t)}function le(){return{x:pageXOffset,y:pageYOffset}}function B(e,t){return e.getAttribute(`data-sveltekit-${t}`)}const Ve={...O,"":O.hover};function rt(e){let t=e.assignedSlot??e.parentNode;return(t==null?void 0:t.nodeType)===11&&(t=t.host),t}function ot(e,t){for(;e&&e!==t;){if(e.nodeName.toUpperCase()==="A"&&e.hasAttribute("href"))return e;e=rt(e)}}function ke(e,t,n){let r;try{if(r=new URL(e instanceof SVGAElement?e.href.baseVal:e.href,document.baseURI),n&&r.hash.match(/^#[^/]/)){const o=location.hash.split("#")[1]||"/";r.hash=`#${o}${r.hash}`}}catch{}const a=e instanceof SVGAElement?e.target.baseVal:e.target,s=!r||!!a||fe(r,t,n)||(e.getAttribute("rel")||"").split(/\s+/).includes("external"),i=(r==null?void 0:r.origin)===ce&&e.hasAttribute("download");return{url:r,external:s,target:a,download:i}}function Q(e){let t=null,n=null,r=null,a=null,s=null,i=null,o=e;for(;o&&o!==document.documentElement;)r===null&&(r=B(o,"preload-code")),a===null&&(a=B(o,"preload-data")),t===null&&(t=B(o,"keepfocus")),n===null&&(n=B(o,"noscroll")),s===null&&(s=B(o,"reload")),i===null&&(i=B(o,"replacestate")),o=rt(o);function c(l){switch(l){case"":case"true":return!0;case"off":case"false":return!1;default:return}}return{preload_code:Ve[r??"off"],preload_data:Ve[a??"off"],keepfocus:c(t),noscroll:c(n),reload:c(s),replace_state:c(i)}}function Me(e){const t=Ue(e);let n=!0;function r(){n=!0,t.update(i=>i)}function a(i){n=!1,t.set(i)}function s(i){let o;return t.subscribe(c=>{(o===void 0||n&&c!==o)&&i(o=c)})}return{notify:r,set:a,subscribe:s}}const st={v:()=>{}};function tn(){const{set:e,subscribe:t}=Ue(!1);let n;async function r(){clearTimeout(n);try{const a=await fetch(`${Zt}/_app/version.json`,{headers:{pragma:"no-cache","cache-control":"no-cache"}});if(!a.ok)return!1;const i=(await a.json()).version!==Qt;return i&&(e(!0),st.v(),clearTimeout(n)),i}catch{return!1}}return{subscribe:t,check:r}}function fe(e,t,n){return e.origin!==ce||!e.pathname.startsWith(t)?!0:n?!(e.pathname===t+"/"||e.pathname===t+"/index.html"||e.protocol==="file:"&&e.pathname.replace(/\/[^/]+\.html?$/,"")===t):!1}function qn(e){}function nn(e){const t=rn(e),n=new ArrayBuffer(t.length),r=new DataView(n);for(let a=0;a<n.byteLength;a++)r.setUint8(a,t.charCodeAt(a));return n}const an="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function rn(e){e.length%4===0&&(e=e.replace(/==?$/,""));let t="",n=0,r=0;for(let a=0;a<e.length;a++)n<<=6,n|=an.indexOf(e[a]),r+=6,r===24&&(t+=String.fromCharCode((n&16711680)>>16),t+=String.fromCharCode((n&65280)>>8),t+=String.fromCharCode(n&255),n=r=0);return r===12?(n>>=4,t+=String.fromCharCode(n)):r===18&&(n>>=2,t+=String.fromCharCode((n&65280)>>8),t+=String.fromCharCode(n&255)),t}const on=-1,sn=-2,cn=-3,ln=-4,fn=-5,un=-6;function dn(e,t){if(typeof e=="number")return a(e,!0);if(!Array.isArray(e)||e.length===0)throw new Error("Invalid input");const n=e,r=Array(n.length);function a(s,i=!1){if(s===on)return;if(s===cn)return NaN;if(s===ln)return 1/0;if(s===fn)return-1/0;if(s===un)return-0;if(i||typeof s!="number")throw new Error("Invalid input");if(s in r)return r[s];const o=n[s];if(!o||typeof o!="object")r[s]=o;else if(Array.isArray(o))if(typeof o[0]=="string"){const c=o[0],l=t==null?void 0:t[c];if(l)return r[s]=l(a(o[1]));switch(c){case"Date":r[s]=new Date(o[1]);break;case"Set":const d=new Set;r[s]=d;for(let f=1;f<o.length;f+=1)d.add(a(o[f]));break;case"Map":const h=new Map;r[s]=h;for(let f=1;f<o.length;f+=2)h.set(a(o[f]),a(o[f+1]));break;case"RegExp":r[s]=new RegExp(o[1],o[2]);break;case"Object":r[s]=Object(o[1]);break;case"BigInt":r[s]=BigInt(o[1]);break;case"null":const y=Object.create(null);r[s]=y;for(let f=1;f<o.length;f+=2)y[o[f]]=a(o[f+1]);break;case"Int8Array":case"Uint8Array":case"Uint8ClampedArray":case"Int16Array":case"Uint16Array":case"Int32Array":case"Uint32Array":case"Float32Array":case"Float64Array":case"BigInt64Array":case"BigUint64Array":{const f=globalThis[c],p=new f(a(o[1]));r[s]=o[2]!==void 0?p.subarray(o[2],o[3]):p;break}case"ArrayBuffer":{const f=o[1],p=nn(f);r[s]=p;break}case"Temporal.Duration":case"Temporal.Instant":case"Temporal.PlainDate":case"Temporal.PlainTime":case"Temporal.PlainDateTime":case"Temporal.PlainMonthDay":case"Temporal.PlainYearMonth":case"Temporal.ZonedDateTime":{const f=c.slice(9);r[s]=Temporal[f].from(o[1]);break}case"URL":{const f=new URL(o[1]);r[s]=f;break}case"URLSearchParams":{const f=new URLSearchParams(o[1]);r[s]=f;break}default:throw new Error(`Unknown type ${c}`)}}else{const c=new Array(o.length);r[s]=c;for(let l=0;l<o.length;l+=1){const d=o[l];d!==sn&&(c[l]=a(d))}}else{const c={};r[s]=c;for(const l in o){if(l==="__proto__")throw new Error("Cannot parse an object with a `__proto__` property");const d=o[l];c[l]=a(d)}}return r[s]}return a(0)}const it=new Set(["load","prerender","csr","ssr","trailingSlash","config"]);[...it];const hn=new Set([...it]);[...hn];function pn(e){return e.filter(t=>t!=null)}const gn="x-sveltekit-invalidated",mn="x-sveltekit-trailing-slash";function ee(e){return e instanceof ie||e instanceof Te?e.status:500}function _n(e){return e instanceof Te?e.text:"Internal Error"}let T,W,we;const wn=ve.toString().includes("$$")||/function \w+\(\) \{\}/.test(ve.toString());wn?(T={data:{},form:null,error:null,params:{},route:{id:null},state:{},status:-1,url:new URL("https://example.com")},W={current:null},we={current:!1}):(T=new class{constructor(){R(this,"data",$state.raw({}));R(this,"form",$state.raw(null));R(this,"error",$state.raw(null));R(this,"params",$state.raw({}));R(this,"route",$state.raw({id:null}));R(this,"state",$state.raw({}));R(this,"status",$state.raw(-1));R(this,"url",$state.raw(new URL("https://example.com")))}},W=new class{constructor(){R(this,"current",$state.raw(null))}},we=new class{constructor(){R(this,"current",$state.raw(!1))}},st.v=()=>we.current=!0);function yn(e){Object.assign(T,e)}const vn="/__data.json",bn=".html__data.json";function kn(e){return e.endsWith(".html")?e.replace(/\.html$/,bn):e.replace(/\/$/,"")+vn}const qe={spanContext(){return Sn},setAttribute(){return this},setAttributes(){return this},addEvent(){return this},setStatus(){return this},updateName(){return this},end(){return this},isRecording(){return!1},recordException(){return this},addLink(){return this},addLinks(){return this}},Sn={traceId:"",spanId:"",traceFlags:0},{tick:En}=Ot,An=new Set(["icon","shortcut icon","apple-touch-icon"]),j=Qe(tt)??{},J=Qe(et)??{},C={url:Me({}),page:Me({}),navigating:Ue(null),updated:tn()};function Le(e){j[e]=le()}function Rn(e,t){let n=e+1;for(;j[n];)delete j[n],n+=1;for(n=t+1;J[n];)delete J[n],n+=1}function q(e,t=!1){return t?location.replace(e.href):location.href=e.href,new Promise(()=>{})}async function ct(){if("serviceWorker"in navigator){const e=await navigator.serviceWorker.getRegistration($||"/");e&&await e.update()}}function Ge(){}let $e,Se,te,x,Ee,S;const ne=[],ae=[];let U=null;const Z=new Map,lt=new Set,Tn=new Set,Y=new Set;let b={branch:[],error:null,url:null},xe=!1,re=!1,Ke=!0,X=!1,G=!1,ft=!1,Ce=!1,ut,A,L,N;const H=new Set,Ye=new Map;async function Hn(e,t,n){var s,i,o,c,l;(s=globalThis.__sveltekit_1wyakc0)!=null&&s.data&&globalThis.__sveltekit_1wyakc0.data,document.URL!==location.href&&(location.href=location.href),S=e,await((o=(i=e.hooks).init)==null?void 0:o.call(i)),$e=Xt(e),x=document.documentElement,Ee=t,Se=e.nodes[0],te=e.nodes[1],Se(),te(),A=(c=history.state)==null?void 0:c[F],L=(l=history.state)==null?void 0:l[z],A||(A=L=Date.now(),history.replaceState({...history.state,[F]:A,[z]:L},""));const r=j[A];function a(){r&&(history.scrollRestoration="manual",scrollTo(r.x,r.y))}n?(a(),await Dn(Ee,n)):(await V({type:"enter",url:at(S.hash?Fn(new URL(location.href)):location.href),replace_state:!0}),a()),jn()}function In(){ne.length=0,Ce=!1}function dt(e){ae.some(t=>t==null?void 0:t.snapshot)&&(J[e]=ae.map(t=>{var n;return(n=t==null?void 0:t.snapshot)==null?void 0:n.capture()}))}function ht(e){var t;(t=J[e])==null||t.forEach((n,r)=>{var a,s;(s=(a=ae[r])==null?void 0:a.snapshot)==null||s.restore(n)})}function He(){Le(A),Fe(tt,j),dt(L),Fe(et,J)}async function Un(e,t,n,r){let a;t.invalidateAll&&(U=null),await V({type:"goto",url:at(e),keepfocus:t.keepFocus,noscroll:t.noScroll,replace_state:t.replaceState,state:t.state,redirect_count:n,nav_token:r,accept:()=>{t.invalidateAll&&(Ce=!0,a=[...Ye.keys()]),t.invalidate&&t.invalidate.forEach(Nn)}}),t.invalidateAll&&be().then(be).then(()=>{Ye.forEach(({resource:s},i)=>{var o;a!=null&&a.includes(i)&&((o=s.refresh)==null||o.call(s))})})}async function Ln(e){if(e.id!==(U==null?void 0:U.id)){const t={};H.add(t),U={id:e.id,token:t,promise:mt({...e,preload:t}).then(n=>(H.delete(t),n.type==="loaded"&&n.state.error&&(U=null),n))}}return U.promise}async function ye(e){var n;const t=(n=await de(e,!1))==null?void 0:n.route;t&&await Promise.all([...t.layouts,t.leaf].map(r=>r==null?void 0:r[1]()))}function pt(e,t,n){var a;b=e.state;const r=document.querySelector("style[data-sveltekit]");if(r&&r.remove(),Object.assign(T,e.props.page),ut=new S.root({target:t,props:{...e.props,stores:C,components:ae},hydrate:n,sync:!1}),ht(L),n){const s={from:null,to:{params:b.params,route:{id:((a=b.route)==null?void 0:a.id)??null},url:new URL(location.href)},willUnload:!1,type:"enter",complete:Promise.resolve()};Y.forEach(i=>i(s))}re=!0}function oe({url:e,params:t,branch:n,status:r,error:a,route:s,form:i}){let o="never";if($&&(e.pathname===$||e.pathname===$+"/"))o="always";else for(const f of n)(f==null?void 0:f.slash)!==void 0&&(o=f.slash);e.pathname=Nt(e.pathname,o),e.search=e.search;const c={type:"loaded",state:{url:e,params:t,branch:n,error:a,route:s},props:{constructors:pn(n).map(f=>f.node.component),page:je(T)}};i!==void 0&&(c.props.form=i);let l={},d=!T,h=0;for(let f=0;f<Math.max(n.length,b.branch.length);f+=1){const p=n[f],u=b.branch[f];(p==null?void 0:p.data)!==(u==null?void 0:u.data)&&(d=!0),p&&(l={...l,...p.data},d&&(c.props[`data_${h}`]=l),h+=1)}return(!b.url||e.href!==b.url.href||b.error!==a||i!==void 0&&i!==T.form||d)&&(c.props.page={error:a,params:t,route:{id:(s==null?void 0:s.id)??null},state:{},status:r,url:new URL(e),form:i??null,data:d?l:T.data}),c}async function Pe({loader:e,parent:t,url:n,params:r,route:a,server_data_node:s}){var d,h,y;let i=null,o=!0;const c={dependencies:new Set,params:new Set,parent:!1,route:!1,url:!1,search_params:new Set},l=await e();if((d=l.universal)!=null&&d.load){let f=function(...u){for(const g of u){const{href:_}=new URL(g,n);c.dependencies.add(_)}};const p={tracing:{enabled:!1,root:qe,current:qe},route:new Proxy(a,{get:(u,g)=>(o&&(c.route=!0),u[g])}),params:new Proxy(r,{get:(u,g)=>(o&&c.params.add(g),u[g])}),data:(s==null?void 0:s.data)??null,url:Bt(n,()=>{o&&(c.url=!0)},u=>{o&&c.search_params.add(u)},S.hash),async fetch(u,g){u instanceof Request&&(g={body:u.method==="GET"||u.method==="HEAD"?void 0:await u.blob(),cache:u.cache,credentials:u.credentials,headers:[...u.headers].length>0?u==null?void 0:u.headers:void 0,integrity:u.integrity,keepalive:u.keepalive,method:u.method,mode:u.mode,redirect:u.redirect,referrer:u.referrer,referrerPolicy:u.referrerPolicy,signal:u.signal,...g});const{resolved:_,promise:I}=gt(u,g,n);return o&&f(_.href),I},setHeaders:()=>{},depends:f,parent(){return o&&(c.parent=!0),t()},untrack(u){o=!1;try{return u()}finally{o=!0}}};i=await l.universal.load.call(null,p)??null}return{node:l,loader:e,server:s,universal:(h=l.universal)!=null&&h.load?{type:"data",data:i,uses:c}:null,data:i??(s==null?void 0:s.data)??null,slash:((y=l.universal)==null?void 0:y.trailingSlash)??(s==null?void 0:s.slash)}}function gt(e,t,n){let r=e instanceof Request?e.url:e;const a=new URL(r,n);a.origin===n.origin&&(r=a.href.slice(n.origin.length));const s=re?Kt(r,a.href,t):Gt(r,t);return{resolved:a,promise:s}}function ze(e,t,n,r,a,s){if(Ce)return!0;if(!a)return!1;if(a.parent&&e||a.route&&t||a.url&&n)return!0;for(const i of a.search_params)if(r.has(i))return!0;for(const i of a.params)if(s[i]!==b.params[i])return!0;for(const i of a.dependencies)if(ne.some(o=>o(new URL(i))))return!0;return!1}function Oe(e,t){return(e==null?void 0:e.type)==="data"?e:(e==null?void 0:e.type)==="skip"?t??null:null}function $n(e,t){if(!e)return new Set(t.searchParams.keys());const n=new Set([...e.searchParams.keys(),...t.searchParams.keys()]);for(const r of n){const a=e.searchParams.getAll(r),s=t.searchParams.getAll(r);a.every(i=>s.includes(i))&&s.every(i=>a.includes(i))&&n.delete(r)}return n}function We({error:e,url:t,route:n,params:r}){return{type:"loaded",state:{error:e,url:t,route:n,params:r,branch:[]},props:{page:je(T),constructors:[]}}}async function mt({id:e,invalidating:t,url:n,params:r,route:a,preload:s}){if((U==null?void 0:U.id)===e)return H.delete(U.token),U.promise;const{errors:i,layouts:o,leaf:c}=a,l=[...o,c];i.forEach(w=>w==null?void 0:w().catch(()=>{})),l.forEach(w=>w==null?void 0:w[1]().catch(()=>{}));let d=null;const h=b.url?e!==se(b.url):!1,y=b.route?a.id!==b.route.id:!1,f=$n(b.url,n);let p=!1;const u=l.map((w,m)=>{var P;const v=b.branch[m],k=!!(w!=null&&w[0])&&((v==null?void 0:v.loader)!==w[1]||ze(p,y,h,f,(P=v.server)==null?void 0:P.uses,r));return k&&(p=!0),k});if(u.some(Boolean)){try{d=await yt(n,u)}catch(w){const m=await M(w,{url:n,params:r,route:{id:e}});return H.has(s)?We({error:m,url:n,params:r,route:a}):ue({status:ee(w),error:m,url:n,route:a})}if(d.type==="redirect")return d}const g=d==null?void 0:d.nodes;let _=!1;const I=l.map(async(w,m)=>{var he;if(!w)return;const v=b.branch[m],k=g==null?void 0:g[m];if((!k||k.type==="skip")&&w[1]===(v==null?void 0:v.loader)&&!ze(_,y,h,f,(he=v.universal)==null?void 0:he.uses,r))return v;if(_=!0,(k==null?void 0:k.type)==="error")throw k;return Pe({loader:w[1],url:n,params:r,route:a,parent:async()=>{var Be;const De={};for(let pe=0;pe<m;pe+=1)Object.assign(De,(Be=await I[pe])==null?void 0:Be.data);return De},server_data_node:Oe(k===void 0&&w[0]?{type:"skip"}:k??null,w[0]?v==null?void 0:v.server:void 0)})});for(const w of I)w.catch(()=>{});const E=[];for(let w=0;w<l.length;w+=1)if(l[w])try{E.push(await I[w])}catch(m){if(m instanceof Re)return{type:"redirect",location:m.location};if(H.has(s))return We({error:await M(m,{params:r,url:n,route:{id:a.id}}),url:n,params:r,route:a});let v=ee(m),k;if(g!=null&&g.includes(m))v=m.status??v,k=m.error;else if(m instanceof ie)k=m.body;else{if(await C.updated.check())return await ct(),await q(n);k=await M(m,{params:r,url:n,route:{id:a.id}})}const P=await xn(w,E,i);return P?oe({url:n,params:r,branch:E.slice(0,P.idx).concat(P.node),status:v,error:k,route:a}):await wt(n,{id:a.id},k,v)}else E.push(void 0);return oe({url:n,params:r,branch:E,status:200,error:null,route:a,form:t?void 0:null})}async function xn(e,t,n){for(;e--;)if(n[e]){let r=e;for(;!t[r];)r-=1;try{return{idx:r+1,node:{node:await n[e](),loader:n[e],data:{},server:null,universal:null}}}catch{continue}}}async function ue({status:e,error:t,url:n,route:r}){const a={};let s=null;if(S.server_loads[0]===0)try{const o=await yt(n,[!0]);if(o.type!=="data"||o.nodes[0]&&o.nodes[0].type!=="data")throw 0;s=o.nodes[0]??null}catch{(n.origin!==ce||n.pathname!==location.pathname||xe)&&await q(n)}try{const o=await Pe({loader:Se,url:n,params:a,route:r,parent:()=>Promise.resolve({}),server_data_node:Oe(s)}),c={node:await te(),loader:te,universal:null,server:null,data:null};return oe({url:n,params:a,branch:[o,c],status:e,error:t,route:null})}catch(o){if(o instanceof Re)return Un(new URL(o.location,location.href),{},0);throw o}}async function Cn(e){const t=e.href;if(Z.has(t))return Z.get(t);let n;try{const r=(async()=>{let a=await S.hooks.reroute({url:new URL(e),fetch:async(s,i)=>gt(s,i,e).promise})??e;if(typeof a=="string"){const s=new URL(e);S.hash?s.hash=a:s.pathname=a,a=s}return a})();Z.set(t,r),n=await r}catch{Z.delete(t);return}return n}async function de(e,t){if(e&&!fe(e,$,S.hash)){const n=await Cn(e);if(!n)return;const r=Pn(n);for(const a of $e){const s=a.exec(r);if(s)return{id:se(e),invalidating:t,route:a,params:Dt(s),url:e}}}}function Pn(e){return jt(S.hash?e.hash.replace(/^#/,"").replace(/[?#].+/,""):e.pathname.slice($.length))||"/"}function se(e){return(S.hash?e.hash.replace(/^#/,""):e.pathname)+e.search}function _t({url:e,type:t,intent:n,delta:r,event:a}){let s=!1;const i=Ne(b,n,e,t);r!==void 0&&(i.navigation.delta=r),a!==void 0&&(i.navigation.event=a);const o={...i.navigation,cancel:()=>{s=!0,i.reject(new Error("navigation cancelled"))}};return X||lt.forEach(c=>c(o)),s?null:i}async function V({type:e,url:t,popped:n,keepfocus:r,noscroll:a,replace_state:s,state:i={},redirect_count:o=0,nav_token:c={},accept:l=Ge,block:d=Ge,event:h}){const y=N;N=c;const f=await de(t,!1),p=e==="enter"?Ne(b,f,t,e):_t({url:t,type:e,delta:n==null?void 0:n.delta,intent:f,event:h});if(!p){d(),N===c&&(N=y);return}const u=A,g=L;l(),X=!0,re&&p.navigation.type!=="enter"&&C.navigating.set(W.current=p.navigation);let _=f&&await mt(f);if(!_){if(fe(t,$,S.hash))return await q(t,s);_=await wt(t,{id:null},await M(new Te(404,"Not Found",`Not found: ${t.pathname}`),{url:t,params:{},route:{id:null}}),404,s)}if(t=(f==null?void 0:f.url)||t,N!==c)return p.reject(new Error("navigation aborted")),!1;if(_.type==="redirect"){if(o<20){await V({type:e,url:new URL(_.location,t),popped:n,keepfocus:r,noscroll:a,replace_state:s,state:i,redirect_count:o+1,nav_token:c}),p.fulfil(void 0);return}_=await ue({status:500,error:await M(new Error("Redirect loop"),{url:t,params:{},route:{id:null}}),url:t,route:{id:null}})}else _.props.page.status>=400&&await C.updated.check()&&(await ct(),await q(t,s));if(In(),Le(u),dt(g),_.props.page.url.pathname!==t.pathname&&(t.pathname=_.props.page.url.pathname),i=n?n.state:i,!n){const m=s?0:1,v={[F]:A+=m,[z]:L+=m,[nt]:i};(s?history.replaceState:history.pushState).call(history,v,"",t),s||Rn(A,L)}if(U=null,_.props.page.state=i,re){const m=(await Promise.all(Array.from(Tn,v=>v(p.navigation)))).filter(v=>typeof v=="function");if(m.length>0){let v=function(){m.forEach(k=>{Y.delete(k)})};m.push(v),m.forEach(k=>{Y.add(k)})}b=_.state,_.props.page&&(_.props.page.url=t),ut.$set(_.props),yn(_.props.page),ft=!0}else pt(_,Ee,!1);const{activeElement:I}=document;await En();let E=n?n.scroll:a?le():null;if(Ke){const m=t.hash&&document.getElementById(bt(t));if(E)scrollTo(E.x,E.y);else if(m){m.scrollIntoView();const{top:v,left:k}=m.getBoundingClientRect();E={x:pageXOffset+k,y:pageYOffset+v}}else scrollTo(0,0)}const w=document.activeElement!==I&&document.activeElement!==document.body;!r&&!w&&Bn(t,E),Ke=!0,_.props.page&&Object.assign(T,_.props.page),X=!1,e==="popstate"&&ht(L),p.fulfil(void 0),Y.forEach(m=>m(p.navigation)),C.navigating.set(W.current=null)}async function wt(e,t,n,r,a){return e.origin===ce&&e.pathname===location.pathname&&!xe?await ue({status:r,error:n,url:e,route:t}):await q(e,a)}function On(){let e,t,n;x.addEventListener("mousemove",o=>{const c=o.target;clearTimeout(e),e=setTimeout(()=>{s(c,O.hover)},20)});function r(o){o.defaultPrevented||s(o.composedPath()[0],O.tap)}x.addEventListener("mousedown",r),x.addEventListener("touchstart",r,{passive:!0});const a=new IntersectionObserver(o=>{for(const c of o)c.isIntersecting&&(ye(new URL(c.target.href)),a.unobserve(c.target))},{threshold:0});async function s(o,c){const l=ot(o,x),d=l===t&&c>=n;if(!l||d)return;const{url:h,external:y,download:f}=ke(l,$,S.hash);if(y||f)return;const p=Q(l),u=h&&se(b.url)===se(h);if(!(p.reload||u))if(c<=p.preload_data){t=l,n=O.tap;const g=await de(h,!1);if(!g)return;Ln(g)}else c<=p.preload_code&&(t=l,n=c,ye(h))}function i(){a.disconnect();for(const o of x.querySelectorAll("a")){const{url:c,external:l,download:d}=ke(o,$,S.hash);if(l||d)continue;const h=Q(o);h.reload||(h.preload_code===O.viewport&&a.observe(o),h.preload_code===O.eager&&ye(c))}}Y.add(i),i()}function M(e,t){if(e instanceof ie)return e.body;const n=ee(e),r=_n(e);return S.hooks.handleError({error:e,event:t,status:n,message:r})??{message:r}}function Nn(e){if(typeof e=="function")ne.push(e);else{const{href:t}=new URL(e,location.href);ne.push(n=>n.href===t)}}function jn(){var t;history.scrollRestoration="manual",addEventListener("beforeunload",n=>{let r=!1;if(He(),!X){const a=Ne(b,void 0,null,"leave"),s={...a.navigation,cancel:()=>{r=!0,a.reject(new Error("navigation cancelled"))}};lt.forEach(i=>i(s))}r?(n.preventDefault(),n.returnValue=""):history.scrollRestoration="auto"}),addEventListener("visibilitychange",()=>{document.visibilityState==="hidden"&&He()}),(t=navigator.connection)!=null&&t.saveData||On(),x.addEventListener("click",async n=>{if(n.button||n.which!==1||n.metaKey||n.ctrlKey||n.shiftKey||n.altKey||n.defaultPrevented)return;const r=ot(n.composedPath()[0],x);if(!r)return;const{url:a,external:s,target:i,download:o}=ke(r,$,S.hash);if(!a)return;if(i==="_parent"||i==="_top"){if(window.parent!==window)return}else if(i&&i!=="_self")return;const c=Q(r);if(!(r instanceof SVGAElement)&&a.protocol!==location.protocol&&!(a.protocol==="https:"||a.protocol==="http:")||o)return;const[d,h]=(S.hash?a.hash.replace(/^#/,""):a.href).split("#"),y=d===me(location);if(s||c.reload&&(!y||!h)){_t({url:a,type:"link",event:n})?X=!0:n.preventDefault();return}if(h!==void 0&&y){const[,f]=b.url.href.split("#");if(f===h){if(n.preventDefault(),h===""||h==="top"&&r.ownerDocument.getElementById("top")===null)scrollTo({top:0});else{const p=r.ownerDocument.getElementById(decodeURIComponent(h));p&&(p.scrollIntoView(),p.focus())}return}if(G=!0,Le(A),e(a),!c.replace_state)return;G=!1}n.preventDefault(),await new Promise(f=>{requestAnimationFrame(()=>{setTimeout(f,0)}),setTimeout(f,100)}),await V({type:"link",url:a,keepfocus:c.keepfocus,noscroll:c.noscroll,replace_state:c.replace_state??a.href===location.href,event:n})}),x.addEventListener("submit",n=>{if(n.defaultPrevented)return;const r=HTMLFormElement.prototype.cloneNode.call(n.target),a=n.submitter;if(((a==null?void 0:a.formTarget)||r.target)==="_blank"||((a==null?void 0:a.formMethod)||r.method)!=="get")return;const o=new URL((a==null?void 0:a.hasAttribute("formaction"))&&(a==null?void 0:a.formAction)||r.action);if(fe(o,$,!1))return;const c=n.target,l=Q(c);if(l.reload)return;n.preventDefault(),n.stopPropagation();const d=new FormData(c,a);o.search=new URLSearchParams(d).toString(),V({type:"form",url:o,keepfocus:l.keepfocus,noscroll:l.noscroll,replace_state:l.replace_state??o.href===location.href,event:n})}),addEventListener("popstate",async n=>{var r;if(!Ae){if((r=n.state)!=null&&r[F]){const a=n.state[F];if(N={},a===A)return;const s=j[a],i=n.state[nt]??{},o=new URL(n.state[en]??location.href),c=n.state[z],l=b.url?me(location)===me(b.url):!1;if(c===L&&(ft||l)){i!==T.state&&(T.state=i),e(o),j[A]=le(),s&&scrollTo(s.x,s.y),A=a;return}const h=a-A;await V({type:"popstate",url:o,popped:{state:i,scroll:s,delta:h},accept:()=>{A=a,L=c},block:()=>{history.go(-h)},nav_token:N,event:n})}else if(!G){const a=new URL(location.href);e(a),S.hash&&location.reload()}}}),addEventListener("hashchange",()=>{G&&(G=!1,history.replaceState({...history.state,[F]:++A,[z]:L},"",location.href))});for(const n of document.querySelectorAll("link"))An.has(n.rel)&&(n.href=n.href);addEventListener("pageshow",n=>{n.persisted&&C.navigating.set(W.current=null)});function e(n){b.url=T.url=n,C.page.set(je(T)),C.page.notify()}}async function Dn(e,{status:t=200,error:n,node_ids:r,params:a,route:s,server_route:i,data:o,form:c}){xe=!0;const l=new URL(location.href);let d;({params:a={},route:s={id:null}}=await de(l,!1)||{}),d=$e.find(({id:f})=>f===s.id);let h,y=!0;try{const f=r.map(async(u,g)=>{const _=o[g];return _!=null&&_.uses&&(_.uses=vt(_.uses)),Pe({loader:S.nodes[u],url:l,params:a,route:s,parent:async()=>{const I={};for(let E=0;E<g;E+=1)Object.assign(I,(await f[E]).data);return I},server_data_node:Oe(_)})}),p=await Promise.all(f);if(d){const u=d.layouts;for(let g=0;g<u.length;g++)u[g]||p.splice(g,0,void 0)}h=oe({url:l,params:a,branch:p,status:t,error:n,form:c,route:d??null})}catch(f){if(f instanceof Re){await q(new URL(f.location,location.href));return}h=await ue({status:ee(f),error:await M(f,{url:l,params:a,route:s}),url:l,route:s}),e.textContent="",y=!1}h.props.page&&(h.props.page.state={}),pt(h,e,y)}async function yt(e,t){var s;const n=new URL(e);n.pathname=kn(e.pathname),e.pathname.endsWith("/")&&n.searchParams.append(mn,"1"),n.searchParams.append(gn,t.map(i=>i?"1":"0").join(""));const r=window.fetch,a=await r(n.href,{});if(!a.ok){let i;throw(s=a.headers.get("content-type"))!=null&&s.includes("application/json")?i=await a.json():a.status===404?i="Not Found":a.status===500&&(i="Internal Error"),new ie(a.status,i)}return new Promise(async i=>{var h;const o=new Map,c=a.body.getReader();function l(y){return dn(y,{...S.decoders,Promise:f=>new Promise((p,u)=>{o.set(f,{fulfil:p,reject:u})})})}let d="";for(;;){const{done:y,value:f}=await c.read();if(y&&!d)break;for(d+=!f&&d?`
2
+ `:Vt.decode(f,{stream:!0});;){const p=d.indexOf(`
3
+ `);if(p===-1)break;const u=JSON.parse(d.slice(0,p));if(d=d.slice(p+1),u.type==="redirect")return i(u);if(u.type==="data")(h=u.nodes)==null||h.forEach(g=>{(g==null?void 0:g.type)==="data"&&(g.uses=vt(g.uses),g.data=l(g.data))}),i(u);else if(u.type==="chunk"){const{id:g,data:_,error:I}=u,E=o.get(g);o.delete(g),I?E.reject(l(I)):E.fulfil(l(_))}}}})}function vt(e){return{dependencies:new Set((e==null?void 0:e.dependencies)??[]),params:new Set((e==null?void 0:e.params)??[]),parent:!!(e!=null&&e.parent),route:!!(e!=null&&e.route),url:!!(e!=null&&e.url),search_params:new Set((e==null?void 0:e.search_params)??[])}}let Ae=!1;function Bn(e,t=null){const n=document.querySelector("[autofocus]");if(n)n.focus();else{const r=bt(e);if(r&&document.getElementById(r)){const{x:s,y:i}=t??le();setTimeout(()=>{const o=history.state;Ae=!0,location.replace(`#${r}`),S.hash&&location.replace(e.hash),history.replaceState(o,"",e.hash),scrollTo(s,i),Ae=!1})}else{const s=document.body,i=s.getAttribute("tabindex");s.tabIndex=-1,s.focus({preventScroll:!0,focusVisible:!1}),i!==null?s.setAttribute("tabindex",i):s.removeAttribute("tabindex")}const a=getSelection();if(a&&a.type!=="None"){const s=[];for(let i=0;i<a.rangeCount;i+=1)s.push(a.getRangeAt(i));setTimeout(()=>{if(a.rangeCount===s.length){for(let i=0;i<a.rangeCount;i+=1){const o=s[i],c=a.getRangeAt(i);if(o.commonAncestorContainer!==c.commonAncestorContainer||o.startContainer!==c.startContainer||o.endContainer!==c.endContainer||o.startOffset!==c.startOffset||o.endOffset!==c.endOffset)return}a.removeAllRanges()}})}}}function Ne(e,t,n,r){var c,l;let a,s;const i=new Promise((d,h)=>{a=d,s=h});return i.catch(()=>{}),{navigation:{from:{params:e.params,route:{id:((c=e.route)==null?void 0:c.id)??null},url:e.url},to:n&&{params:(t==null?void 0:t.params)??null,route:{id:((l=t==null?void 0:t.route)==null?void 0:l.id)??null},url:n},willUnload:!t,type:r,complete:i},fulfil:a,reject:s}}function je(e){return{data:e.data,error:e.error,form:e.form,params:e.params,route:e.route,state:e.state,status:e.status,url:e.url}}function Fn(e){const t=new URL(e);return t.hash=decodeURIComponent(e.hash),t}function bt(e){let t;if(S.hash){const[,,n]=e.hash.split("#",3);t=n??""}else t=e.hash.slice(1);return decodeURIComponent(t)}export{Hn as a,qn as l,C as s};
hfstudio/static/_app/immutable/chunks/BV8rDFhh.js ADDED
@@ -0,0 +1 @@
 
 
1
+ import{S as _,i as m,s as d,u as c,v as $,w as u,x as i,y as g,z as p,A as h,B as r,C as N,D as M,E as S,F as A}from"./BaOlNwUz.js";import{I as b,g as v,a as C}from"./C7BncMoR.js";import"./IHki7fMi.js";function I(a){let e;const s=a[2].default,l=N(s,a,a[3],null);return{c(){l&&l.c()},l(n){l&&l.l(n)},m(n,t){l&&l.m(n,t),e=!0},p(n,t){l&&l.p&&(!e||t&8)&&M(l,s,n,n[3],e?A(s,n[3],t,null):S(n[3]),null)},i(n){e||(i(l,n),e=!0)},o(n){u(l,n),e=!1},d(n){l&&l.d(n)}}}function L(a){let e,s;const l=[{name:"alert-circle"},a[1],{iconNode:a[0]}];let n={$$slots:{default:[I]},$$scope:{ctx:a}};for(let t=0;t<l.length;t+=1)n=c(n,l[t]);return e=new b({props:n}),{c(){h(e.$$.fragment)},l(t){p(e.$$.fragment,t)},m(t,o){g(e,t,o),s=!0},p(t,[o]){const f=o&3?v(l,[l[0],o&2&&C(t[1]),o&1&&{iconNode:t[0]}]):{};o&8&&(f.$$scope={dirty:o,ctx:t}),e.$set(f)},i(t){s||(i(e.$$.fragment,t),s=!0)},o(t){u(e.$$.fragment,t),s=!1},d(t){$(e,t)}}}function j(a,e,s){let{$$slots:l={},$$scope:n}=e;const t=[["circle",{cx:"12",cy:"12",r:"10"}],["line",{x1:"12",x2:"12",y1:"8",y2:"12"}],["line",{x1:"12",x2:"12.01",y1:"16",y2:"16"}]];return a.$$set=o=>{s(1,e=c(c({},e),r(o))),"$$scope"in o&&s(3,n=o.$$scope)},e=r(e),[t,e,l,n]}class O extends _{constructor(e){super(),m(this,e,j,L,d,{})}}function q(a){let e;const s=a[2].default,l=N(s,a,a[3],null);return{c(){l&&l.c()},l(n){l&&l.l(n)},m(n,t){l&&l.m(n,t),e=!0},p(n,t){l&&l.p&&(!e||t&8)&&M(l,s,n,n[3],e?A(s,n[3],t,null):S(n[3]),null)},i(n){e||(i(l,n),e=!0)},o(n){u(l,n),e=!1},d(n){l&&l.d(n)}}}function z(a){let e,s;const l=[{name:"loader-2"},a[1],{iconNode:a[0]}];let n={$$slots:{default:[q]},$$scope:{ctx:a}};for(let t=0;t<l.length;t+=1)n=c(n,l[t]);return e=new b({props:n}),{c(){h(e.$$.fragment)},l(t){p(e.$$.fragment,t)},m(t,o){g(e,t,o),s=!0},p(t,[o]){const f=o&3?v(l,[l[0],o&2&&C(t[1]),o&1&&{iconNode:t[0]}]):{};o&8&&(f.$$scope={dirty:o,ctx:t}),e.$set(f)},i(t){s||(i(e.$$.fragment,t),s=!0)},o(t){u(e.$$.fragment,t),s=!1},d(t){$(e,t)}}}function B(a,e,s){let{$$slots:l={},$$scope:n}=e;const t=[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56"}]];return a.$$set=o=>{s(1,e=c(c({},e),r(o))),"$$scope"in o&&s(3,n=o.$$scope)},e=r(e),[t,e,l,n]}class P extends _{constructor(e){super(),m(this,e,B,z,d,{})}}function D(a){let e;const s=a[2].default,l=N(s,a,a[3],null);return{c(){l&&l.c()},l(n){l&&l.l(n)},m(n,t){l&&l.m(n,t),e=!0},p(n,t){l&&l.p&&(!e||t&8)&&M(l,s,n,n[3],e?A(s,n[3],t,null):S(n[3]),null)},i(n){e||(i(l,n),e=!0)},o(n){u(l,n),e=!1},d(n){l&&l.d(n)}}}function E(a){let e,s;const l=[{name:"shuffle"},a[1],{iconNode:a[0]}];let n={$$slots:{default:[D]},$$scope:{ctx:a}};for(let t=0;t<l.length;t+=1)n=c(n,l[t]);return e=new b({props:n}),{c(){h(e.$$.fragment)},l(t){p(e.$$.fragment,t)},m(t,o){g(e,t,o),s=!0},p(t,[o]){const f=o&3?v(l,[l[0],o&2&&C(t[1]),o&1&&{iconNode:t[0]}]):{};o&8&&(f.$$scope={dirty:o,ctx:t}),e.$set(f)},i(t){s||(i(e.$$.fragment,t),s=!0)},o(t){u(e.$$.fragment,t),s=!1},d(t){$(e,t)}}}function F(a,e,s){let{$$slots:l={},$$scope:n}=e;const t=[["path",{d:"M2 18h1.4c1.3 0 2.5-.6 3.3-1.7l6.1-8.6c.7-1.1 2-1.7 3.3-1.7H22"}],["path",{d:"m18 2 4 4-4 4"}],["path",{d:"M2 6h1.9c1.5 0 2.9.9 3.6 2.2"}],["path",{d:"M22 18h-5.9c-1.3 0-2.6-.7-3.3-1.8l-.5-.8"}],["path",{d:"m18 14 4 4-4 4"}]];return a.$$set=o=>{s(1,e=c(c({},e),r(o))),"$$scope"in o&&s(3,n=o.$$scope)},e=r(e),[t,e,l,n]}class Q extends _{constructor(e){super(),m(this,e,F,E,d,{})}}function H(a){let e;const s=a[2].default,l=N(s,a,a[3],null);return{c(){l&&l.c()},l(n){l&&l.l(n)},m(n,t){l&&l.m(n,t),e=!0},p(n,t){l&&l.p&&(!e||t&8)&&M(l,s,n,n[3],e?A(s,n[3],t,null):S(n[3]),null)},i(n){e||(i(l,n),e=!0)},o(n){u(l,n),e=!1},d(n){l&&l.d(n)}}}function X(a){let e,s;const l=[{name:"x"},a[1],{iconNode:a[0]}];let n={$$slots:{default:[H]},$$scope:{ctx:a}};for(let t=0;t<l.length;t+=1)n=c(n,l[t]);return e=new b({props:n}),{c(){h(e.$$.fragment)},l(t){p(e.$$.fragment,t)},m(t,o){g(e,t,o),s=!0},p(t,[o]){const f=o&3?v(l,[l[0],o&2&&C(t[1]),o&1&&{iconNode:t[0]}]):{};o&8&&(f.$$scope={dirty:o,ctx:t}),e.$set(f)},i(t){s||(i(e.$$.fragment,t),s=!0)},o(t){u(e.$$.fragment,t),s=!1},d(t){$(e,t)}}}function k(a,e,s){let{$$slots:l={},$$scope:n}=e;const t=[["path",{d:"M18 6 6 18"}],["path",{d:"m6 6 12 12"}]];return a.$$set=o=>{s(1,e=c(c({},e),r(o))),"$$scope"in o&&s(3,n=o.$$scope)},e=r(e),[t,e,l,n]}class R extends _{constructor(e){super(),m(this,e,k,X,d,{})}}export{O as A,P as L,Q as S,R as X};
hfstudio/static/_app/immutable/chunks/BaOlNwUz.js ADDED
@@ -0,0 +1 @@
 
 
1
+ var Q=Object.defineProperty;var V=(t,n,e)=>n in t?Q(t,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[n]=e;var d=(t,n,e)=>V(t,typeof n!="symbol"?n+"":n,e);function w(){}function X(t,n){for(const e in n)t[e]=n[e];return t}function O(t){return t()}function k(){return Object.create(null)}function $(t){t.forEach(O)}function q(t){return typeof t=="function"}function xt(t,n){return t!=t?n==n:t!==n||t&&typeof t=="object"||typeof t=="function"}let E;function $t(t,n){return t===n?!0:(E||(E=document.createElement("a")),E.href=n,t===E.href)}function Y(t){return Object.keys(t).length===0}function Z(t,...n){if(t==null){for(const i of n)i(void 0);return w}const e=t.subscribe(...n);return e.unsubscribe?()=>e.unsubscribe():e}function bt(t,n,e){t.$$.on_destroy.push(Z(n,e))}function Et(t,n,e,i){if(t){const r=G(t,n,e,i);return t[0](r)}}function G(t,n,e,i){return t[1]&&i?X(e.ctx.slice(),t[1](i(n))):e.ctx}function vt(t,n,e,i){if(t[2]&&i){const r=t[2](i(e));if(n.dirty===void 0)return r;if(typeof r=="object"){const o=[],s=Math.max(n.dirty.length,r.length);for(let u=0;u<s;u+=1)o[u]=n.dirty[u]|r[u];return o}return n.dirty|r}return n.dirty}function wt(t,n,e,i,r,o){if(r){const s=G(n,e,i,o);t.p(s,r)}}function Tt(t){if(t.ctx.length>32){const n=[],e=t.ctx.length/32;for(let i=0;i<e;i++)n[i]=-1;return n}return-1}function Nt(t){const n={};for(const e in t)e[0]!=="$"&&(n[e]=t[e]);return n}function At(t,n){const e={};n=new Set(n);for(const i in t)!n.has(i)&&i[0]!=="$"&&(e[i]=t[i]);return e}let N=!1;function tt(){N=!0}function nt(){N=!1}function et(t,n,e,i){for(;t<n;){const r=t+(n-t>>1);e(r)<=i?t=r+1:n=r}return t}function it(t){if(t.hydrate_init)return;t.hydrate_init=!0;let n=t.childNodes;if(t.nodeName==="HEAD"){const c=[];for(let l=0;l<n.length;l++){const f=n[l];f.claim_order!==void 0&&c.push(f)}n=c}const e=new Int32Array(n.length+1),i=new Int32Array(n.length);e[0]=-1;let r=0;for(let c=0;c<n.length;c++){const l=n[c].claim_order,f=(r>0&&n[e[r]].claim_order<=l?r+1:et(1,r,b=>n[e[b]].claim_order,l))-1;i[c]=e[f]+1;const a=f+1;e[a]=c,r=Math.max(a,r)}const o=[],s=[];let u=n.length-1;for(let c=e[r]+1;c!=0;c=i[c-1]){for(o.push(n[c-1]);u>=c;u--)s.push(n[u]);u--}for(;u>=0;u--)s.push(n[u]);o.reverse(),s.sort((c,l)=>c.claim_order-l.claim_order);for(let c=0,l=0;c<s.length;c++){for(;l<o.length&&s[c].claim_order>=o[l].claim_order;)l++;const f=l<o.length?o[l]:null;t.insertBefore(s[c],f)}}function rt(t,n){if(N){for(it(t),(t.actual_end_child===void 0||t.actual_end_child!==null&&t.actual_end_child.parentNode!==t)&&(t.actual_end_child=t.firstChild);t.actual_end_child!==null&&t.actual_end_child.claim_order===void 0;)t.actual_end_child=t.actual_end_child.nextSibling;n!==t.actual_end_child?(n.claim_order!==void 0||n.parentNode!==t)&&t.insertBefore(n,t.actual_end_child):t.actual_end_child=n.nextSibling}else(n.parentNode!==t||n.nextSibling!==null)&&t.appendChild(n)}function st(t,n,e){t.insertBefore(n,e||null)}function ct(t,n,e){N&&!e?rt(t,n):(n.parentNode!==t||n.nextSibling!=e)&&t.insertBefore(n,e||null)}function T(t){t.parentNode&&t.parentNode.removeChild(t)}function Ct(t,n){for(let e=0;e<t.length;e+=1)t[e]&&t[e].d(n)}function R(t){return document.createElement(t)}function U(t){return document.createElementNS("http://www.w3.org/2000/svg",t)}function M(t){return document.createTextNode(t)}function St(){return M(" ")}function Ht(){return M("")}function Mt(t,n,e,i){return t.addEventListener(n,e,i),()=>t.removeEventListener(n,e,i)}function ot(t,n,e){e==null?t.removeAttribute(n):t.getAttribute(n)!==e&&t.setAttribute(n,e)}function Lt(t,n){for(const e in n)ot(t,e,n[e])}function jt(t){return t.dataset.svelteH}function kt(t){return t===""?null:+t}function lt(t){return Array.from(t.childNodes)}function z(t){t.claim_info===void 0&&(t.claim_info={last_index:0,total_claimed:0})}function F(t,n,e,i,r=!1){z(t);const o=(()=>{for(let s=t.claim_info.last_index;s<t.length;s++){const u=t[s];if(n(u)){const c=e(u);return c===void 0?t.splice(s,1):t[s]=c,r||(t.claim_info.last_index=s),u}}for(let s=t.claim_info.last_index-1;s>=0;s--){const u=t[s];if(n(u)){const c=e(u);return c===void 0?t.splice(s,1):t[s]=c,r?c===void 0&&t.claim_info.last_index--:t.claim_info.last_index=s,u}}return i()})();return o.claim_order=t.claim_info.total_claimed,t.claim_info.total_claimed+=1,o}function I(t,n,e,i){return F(t,r=>r.nodeName===n,r=>{const o=[];for(let s=0;s<r.attributes.length;s++){const u=r.attributes[s];e[u.name]||o.push(u.name)}o.forEach(s=>r.removeAttribute(s))},()=>i(n))}function Dt(t,n,e){return I(t,n,e,R)}function Pt(t,n,e){return I(t,n,e,U)}function ut(t,n){return F(t,e=>e.nodeType===3,e=>{const i=""+n;if(e.data.startsWith(i)){if(e.data.length!==i.length)return e.splitText(i.length)}else e.data=i},()=>M(n),!0)}function Bt(t){return ut(t," ")}function D(t,n,e){for(let i=e;i<t.length;i+=1){const r=t[i];if(r.nodeType===8&&r.textContent.trim()===n)return i}return-1}function Ot(t,n){const e=D(t,"HTML_TAG_START",0),i=D(t,"HTML_TAG_END",e+1);if(e===-1||i===-1)return new A(n);z(t);const r=t.splice(e,i-e+1);T(r[0]),T(r[r.length-1]);const o=r.slice(1,r.length-1);if(o.length===0)return new A(n);for(const s of o)s.claim_order=t.claim_info.total_claimed,t.claim_info.total_claimed+=1;return new A(n,o)}function qt(t,n){n=""+n,t.data!==n&&(t.data=n)}function Gt(t,n){t.value=n??""}function Rt(t,n,e,i){e==null?t.style.removeProperty(n):t.style.setProperty(n,e,"")}function at(t,n,{bubbles:e=!1,cancelable:i=!1}={}){return new CustomEvent(t,{detail:n,bubbles:e,cancelable:i})}function Ut(t,n){const e=[];let i=0;for(const r of n.childNodes)if(r.nodeType===8){const o=r.textContent.trim();o===`HEAD_${t}_END`?(i-=1,e.push(r)):o===`HEAD_${t}_START`&&(i+=1,e.push(r))}else i>0&&e.push(r);return e}class ft{constructor(n=!1){d(this,"is_svg",!1);d(this,"e");d(this,"n");d(this,"t");d(this,"a");this.is_svg=n,this.e=this.n=null}c(n){this.h(n)}m(n,e,i=null){this.e||(this.is_svg?this.e=U(e.nodeName):this.e=R(e.nodeType===11?"TEMPLATE":e.nodeName),this.t=e.tagName!=="TEMPLATE"?e:e.content,this.c(n)),this.i(i)}h(n){this.e.innerHTML=n,this.n=Array.from(this.e.nodeName==="TEMPLATE"?this.e.content.childNodes:this.e.childNodes)}i(n){for(let e=0;e<this.n.length;e+=1)st(this.t,this.n[e],n)}p(n){this.d(),this.h(n),this.i(this.a)}d(){this.n.forEach(T)}}class A extends ft{constructor(e=!1,i){super(e);d(this,"l");this.e=this.n=null,this.l=i}c(e){this.l?this.n=this.l:super.c(e)}i(e){for(let i=0;i<this.n.length;i+=1)ct(this.t,this.n[i],e)}}function zt(t,n){return new t(n)}let x;function y(t){x=t}function _(){if(!x)throw new Error("Function called outside component initialization");return x}function Ft(t){_().$$.before_update.push(t)}function It(t){_().$$.on_mount.push(t)}function Wt(t){_().$$.after_update.push(t)}function Jt(t){_().$$.on_destroy.push(t)}function Kt(){const t=_();return(n,e,{cancelable:i=!1}={})=>{const r=t.$$.callbacks[n];if(r){const o=at(n,e,{cancelable:i});return r.slice().forEach(s=>{s.call(t,o)}),!o.defaultPrevented}return!0}}function Qt(t,n){return _().$$.context.set(t,n),n}function Vt(t){return _().$$.context.get(t)}function Xt(){return _().$$.context}function Yt(t){return _().$$.context.has(t)}const p=[],P=[];let g=[];const B=[],W=Promise.resolve();let S=!1;function J(){S||(S=!0,W.then(K))}function Zt(){return J(),W}function H(t){g.push(t)}const C=new Set;let m=0;function K(){if(m!==0)return;const t=x;do{try{for(;m<p.length;){const n=p[m];m++,y(n),dt(n.$$)}}catch(n){throw p.length=0,m=0,n}for(y(null),p.length=0,m=0;P.length;)P.pop()();for(let n=0;n<g.length;n+=1){const e=g[n];C.has(e)||(C.add(e),e())}g.length=0}while(p.length);for(;B.length;)B.pop()();S=!1,C.clear(),y(t)}function dt(t){if(t.fragment!==null){t.update(),$(t.before_update);const n=t.dirty;t.dirty=[-1],t.fragment&&t.fragment.p(t.ctx,n),t.after_update.forEach(H)}}function _t(t){const n=[],e=[];g.forEach(i=>t.indexOf(i)===-1?n.push(i):e.push(i)),e.forEach(i=>i()),g=n}const v=new Set;let h;function tn(){h={r:0,c:[],p:h}}function nn(){h.r||$(h.c),h=h.p}function ht(t,n){t&&t.i&&(v.delete(t),t.i(n))}function en(t,n,e,i){if(t&&t.o){if(v.has(t))return;v.add(t),h.c.push(()=>{v.delete(t),i&&(e&&t.d(1),i())}),t.o(n)}else i&&i()}function rn(t){t&&t.c()}function sn(t,n){t&&t.l(n)}function mt(t,n,e){const{fragment:i,after_update:r}=t.$$;i&&i.m(n,e),H(()=>{const o=t.$$.on_mount.map(O).filter(q);t.$$.on_destroy?t.$$.on_destroy.push(...o):$(o),t.$$.on_mount=[]}),r.forEach(H)}function pt(t,n){const e=t.$$;e.fragment!==null&&(_t(e.after_update),$(e.on_destroy),e.fragment&&e.fragment.d(n),e.on_destroy=e.fragment=null,e.ctx=[])}function gt(t,n){t.$$.dirty[0]===-1&&(p.push(t),J(),t.$$.dirty.fill(0)),t.$$.dirty[n/31|0]|=1<<n%31}function cn(t,n,e,i,r,o,s=null,u=[-1]){const c=x;y(t);const l=t.$$={fragment:null,ctx:[],props:o,update:w,not_equal:r,bound:k(),on_mount:[],on_destroy:[],on_disconnect:[],before_update:[],after_update:[],context:new Map(n.context||(c?c.$$.context:[])),callbacks:k(),dirty:u,skip_bound:!1,root:n.target||c.$$.root};s&&s(l.root);let f=!1;if(l.ctx=e?e(t,n.props||{},(a,b,...L)=>{const j=L.length?L[0]:b;return l.ctx&&r(l.ctx[a],l.ctx[a]=j)&&(!l.skip_bound&&l.bound[a]&&l.bound[a](j),f&&gt(t,a)),b}):[],l.update(),f=!0,$(l.before_update),l.fragment=i?i(l.ctx):!1,n.target){if(n.hydrate){tt();const a=lt(n.target);l.fragment&&l.fragment.l(a),a.forEach(T)}else l.fragment&&l.fragment.c();n.intro&&ht(t.$$.fragment),mt(t,n.target,n.anchor),nt(),K()}y(c)}class on{constructor(){d(this,"$$");d(this,"$$set")}$destroy(){pt(this,1),this.$destroy=w}$on(n,e){if(!q(e))return w;const i=this.$$.callbacks[n]||(this.$$.callbacks[n]=[]);return i.push(e),()=>{const r=i.indexOf(e);r!==-1&&i.splice(r,1)}}$set(n){this.$$set&&!Y(n)&&(this.$$.skip_bound=!0,this.$$set(n),this.$$.skip_bound=!1)}}export{Ft as $,rn as A,Nt as B,Et as C,wt as D,Tt as E,vt as F,$ as G,nn as H,Ut as I,Ht as J,It as K,Rt as L,Ct as M,tn as N,Gt as O,Ot as P,A as Q,kt as R,on as S,P as T,Wt as U,Zt as V,zt as W,Lt as X,Pt as Y,U as Z,At as _,qt as a,Kt as a0,Xt as a1,Vt as a2,Yt as a3,Jt as a4,Qt as a5,ct as b,rt as c,T as d,Dt as e,lt as f,ut as g,Bt as h,cn as i,R as j,St as k,bt as l,Mt as m,w as n,q as o,ot as p,$t as q,jt as r,xt as s,M as t,X as u,pt as v,en as w,ht as x,mt as y,sn as z};
hfstudio/static/_app/immutable/chunks/Bm0csYZC.js ADDED
@@ -0,0 +1 @@
 
 
1
+ import{S as _,i as m,s as g,u as c,v as d,w as u,x as f,y as p,z as $,A as h,B as i,C as N,D as P,E as b,F as v}from"./BaOlNwUz.js";import{I as C,g as I,a as S}from"./C7BncMoR.js";import"./IHki7fMi.js";function j(l){let e;const o=l[2].default,s=N(o,l,l[3],null);return{c(){s&&s.c()},l(n){s&&s.l(n)},m(n,t){s&&s.m(n,t),e=!0},p(n,t){s&&s.p&&(!e||t&8)&&P(s,o,n,n[3],e?v(o,n[3],t,null):b(n[3]),null)},i(n){e||(f(s,n),e=!0)},o(n){u(s,n),e=!1},d(n){s&&s.d(n)}}}function q(l){let e,o;const s=[{name:"pause"},l[1],{iconNode:l[0]}];let n={$$slots:{default:[j]},$$scope:{ctx:l}};for(let t=0;t<s.length;t+=1)n=c(n,s[t]);return e=new C({props:n}),{c(){h(e.$$.fragment)},l(t){$(e.$$.fragment,t)},m(t,a){p(e,t,a),o=!0},p(t,[a]){const r=a&3?I(s,[s[0],a&2&&S(t[1]),a&1&&{iconNode:t[0]}]):{};a&8&&(r.$$scope={dirty:a,ctx:t}),e.$set(r)},i(t){o||(f(e.$$.fragment,t),o=!0)},o(t){u(e.$$.fragment,t),o=!1},d(t){d(e,t)}}}function w(l,e,o){let{$$slots:s={},$$scope:n}=e;const t=[["rect",{width:"4",height:"16",x:"6",y:"4"}],["rect",{width:"4",height:"16",x:"14",y:"4"}]];return l.$$set=a=>{o(1,e=c(c({},e),i(a))),"$$scope"in a&&o(3,n=a.$$scope)},e=i(e),[t,e,s,n]}class k extends _{constructor(e){super(),m(this,e,w,q,g,{})}}function z(l){let e;const o=l[2].default,s=N(o,l,l[3],null);return{c(){s&&s.c()},l(n){s&&s.l(n)},m(n,t){s&&s.m(n,t),e=!0},p(n,t){s&&s.p&&(!e||t&8)&&P(s,o,n,n[3],e?v(o,n[3],t,null):b(n[3]),null)},i(n){e||(f(s,n),e=!0)},o(n){u(s,n),e=!1},d(n){s&&s.d(n)}}}function A(l){let e,o;const s=[{name:"play"},l[1],{iconNode:l[0]}];let n={$$slots:{default:[z]},$$scope:{ctx:l}};for(let t=0;t<s.length;t+=1)n=c(n,s[t]);return e=new C({props:n}),{c(){h(e.$$.fragment)},l(t){$(e.$$.fragment,t)},m(t,a){p(e,t,a),o=!0},p(t,[a]){const r=a&3?I(s,[s[0],a&2&&S(t[1]),a&1&&{iconNode:t[0]}]):{};a&8&&(r.$$scope={dirty:a,ctx:t}),e.$set(r)},i(t){o||(f(e.$$.fragment,t),o=!0)},o(t){u(e.$$.fragment,t),o=!1},d(t){d(e,t)}}}function B(l,e,o){let{$$slots:s={},$$scope:n}=e;const t=[["polygon",{points:"5 3 19 12 5 21 5 3"}]];return l.$$set=a=>{o(1,e=c(c({},e),i(a))),"$$scope"in a&&o(3,n=a.$$scope)},e=i(e),[t,e,s,n]}class G extends _{constructor(e){super(),m(this,e,B,A,g,{})}}export{k as P,G as a};
hfstudio/static/_app/immutable/chunks/C7BncMoR.js ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import{G as Q,x as X,w as Y,S as R,i as T,s as Z,C as U,u as W,d as b,M as V,D as p,E as x,F as $,X as y,b as E,c as ee,Y as H,f as K,J as S,Z as L,_ as q,B as D}from"./BaOlNwUz.js";import"./IHki7fMi.js";function F(s){return(s==null?void 0:s.length)!==void 0?s:Array.from(s)}function ie(s,t){Y(s,1,1,()=>{t.delete(s.key)})}function oe(s,t,o,i,n,a,h,u,c,d,_,k){let e=s.length,l=a.length,f=e;const v={};for(;f--;)v[s[f].key]=f;const w=[],z=new Map,C=new Map,A=[];for(f=l;f--;){const r=k(n,a,f),m=o(r);let g=h.get(m);g?A.push(()=>g.p(r,t)):(g=d(m,r),g.c()),z.set(m,w[f]=g),m in v&&C.set(m,Math.abs(f-v[m]))}const B=new Set,I=new Set;function M(r){X(r,1),r.m(u,_),h.set(r.key,r),_=r.first,l--}for(;e&&l;){const r=w[l-1],m=s[e-1],g=r.key,N=m.key;r===m?(_=r.first,e--,l--):z.has(N)?!h.has(g)||B.has(g)?M(r):I.has(N)?e--:C.get(g)>C.get(N)?(I.add(g),M(r)):(B.add(N),e--):(c(m,h),e--)}for(;e--;){const r=s[e];z.has(r.key)||c(r,h)}for(;l;)M(w[l-1]);return Q(A),w}function O(s,t){const o={},i={},n={$$scope:1};let a=s.length;for(;a--;){const h=s[a],u=t[a];if(u){for(const c in h)c in u||(i[c]=1);for(const c in u)n[c]||(o[c]=u[c],n[c]=1);s[a]=u}else for(const c in h)n[c]=1}for(const h in i)h in o||(o[h]=void 0);return o}function ae(s){return typeof s=="object"&&s!==null?s:{}}/**
2
+ * @license lucide-svelte v0.303.0 - ISC
3
+
4
+ This source code is licensed under the ISC license.
5
+ See the LICENSE file in the root directory of this source tree.
6
+ */const G={xmlns:"http://www.w3.org/2000/svg",width:24,height:24,viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":2,"stroke-linecap":"round","stroke-linejoin":"round"};function J(s,t,o){const i=s.slice();return i[10]=t[o][0],i[11]=t[o][1],i}function j(s){let t,o=[s[11]],i={};for(let n=0;n<o.length;n+=1)i=W(i,o[n]);return{c(){t=L(s[10]),this.h()},l(n){t=H(n,s[10],{}),K(t).forEach(b),this.h()},h(){y(t,i)},m(n,a){E(n,t,a)},p(n,a){y(t,i=O(o,[a&32&&n[11]]))},d(n){n&&b(t)}}}function P(s){let t=s[10],o,i=s[10]&&j(s);return{c(){i&&i.c(),o=S()},l(n){i&&i.l(n),o=S()},m(n,a){i&&i.m(n,a),E(n,o,a)},p(n,a){n[10]?t?Z(t,n[10])?(i.d(1),i=j(n),t=n[10],i.c(),i.m(o.parentNode,o)):i.p(n,a):(i=j(n),t=n[10],i.c(),i.m(o.parentNode,o)):t&&(i.d(1),i=null,t=n[10])},d(n){n&&b(o),i&&i.d(n)}}}function te(s){let t,o,i,n,a,h=F(s[5]),u=[];for(let e=0;e<h.length;e+=1)u[e]=P(J(s,h,e));const c=s[9].default,d=U(c,s,s[8],null);let _=[G,s[6],{width:s[2]},{height:s[2]},{stroke:s[1]},{"stroke-width":i=s[4]?Number(s[3])*24/Number(s[2]):s[3]},{class:n=`lucide-icon lucide lucide-${s[0]} ${s[7].class??""}`}],k={};for(let e=0;e<_.length;e+=1)k=W(k,_[e]);return{c(){t=L("svg");for(let e=0;e<u.length;e+=1)u[e].c();o=S(),d&&d.c(),this.h()},l(e){t=H(e,"svg",{width:!0,height:!0,stroke:!0,"stroke-width":!0,class:!0});var l=K(t);for(let f=0;f<u.length;f+=1)u[f].l(l);o=S(),d&&d.l(l),l.forEach(b),this.h()},h(){y(t,k)},m(e,l){E(e,t,l);for(let f=0;f<u.length;f+=1)u[f]&&u[f].m(t,null);ee(t,o),d&&d.m(t,null),a=!0},p(e,[l]){if(l&32){h=F(e[5]);let f;for(f=0;f<h.length;f+=1){const v=J(e,h,f);u[f]?u[f].p(v,l):(u[f]=P(v),u[f].c(),u[f].m(t,o))}for(;f<u.length;f+=1)u[f].d(1);u.length=h.length}d&&d.p&&(!a||l&256)&&p(d,c,e,e[8],a?$(c,e[8],l,null):x(e[8]),null),y(t,k=O(_,[G,l&64&&e[6],(!a||l&4)&&{width:e[2]},(!a||l&4)&&{height:e[2]},(!a||l&2)&&{stroke:e[1]},(!a||l&28&&i!==(i=e[4]?Number(e[3])*24/Number(e[2]):e[3]))&&{"stroke-width":i},(!a||l&129&&n!==(n=`lucide-icon lucide lucide-${e[0]} ${e[7].class??""}`))&&{class:n}]))},i(e){a||(X(d,e),a=!0)},o(e){Y(d,e),a=!1},d(e){e&&b(t),V(u,e),d&&d.d(e)}}}function se(s,t,o){const i=["name","color","size","strokeWidth","absoluteStrokeWidth","iconNode"];let n=q(t,i),{$$slots:a={},$$scope:h}=t,{name:u}=t,{color:c="currentColor"}=t,{size:d=24}=t,{strokeWidth:_=2}=t,{absoluteStrokeWidth:k=!1}=t,{iconNode:e}=t;return s.$$set=l=>{o(7,t=W(W({},t),D(l))),o(6,n=q(t,i)),"name"in l&&o(0,u=l.name),"color"in l&&o(1,c=l.color),"size"in l&&o(2,d=l.size),"strokeWidth"in l&&o(3,_=l.strokeWidth),"absoluteStrokeWidth"in l&&o(4,k=l.absoluteStrokeWidth),"iconNode"in l&&o(5,e=l.iconNode),"$$scope"in l&&o(8,h=l.$$scope)},t=D(t),[u,c,d,_,k,e,n,t,h,a]}class fe extends R{constructor(t){super(),T(this,t,se,te,Z,{name:0,color:1,size:2,strokeWidth:3,absoluteStrokeWidth:4,iconNode:5})}}export{fe as I,ae as a,F as e,O as g,ie as o,oe as u};
hfstudio/static/_app/immutable/chunks/CbFjO8O8.js ADDED
@@ -0,0 +1 @@
 
 
1
+ import{S as j,i as q,s as z,n as A,d as c,a as C,b as p,c as g,m as D,o as P,p as h,e as _,f as v,g as I,h as w,j as b,t as L,k as S,q as V,r as F}from"./BaOlNwUz.js";import"./IHki7fMi.js";function B(l){let e;return{c(){e=b("div"),this.h()},l(t){e=_(t,"DIV",{class:!0}),v(e).forEach(c),this.h()},h(){h(e,"class","absolute inset-0 -left-full animate-sweep bg-gradient-to-r from-transparent via-orange-400/40 to-transparent")},m(t,n){p(t,e,n)},d(t){t&&c(e)}}}function H(l){let e,t,n,a,i="Sign In";return{c(){e=b("img"),n=S(),a=b("span"),a.textContent=i,this.h()},l(s){e=_(s,"IMG",{src:!0,alt:!0,class:!0}),n=w(s),a=_(s,"SPAN",{class:!0,"data-svelte-h":!0}),F(a)!=="svelte-b2ltkx"&&(a.textContent=i),this.h()},h(){V(e.src,t="/assets/hf-logo.png")||h(e,"src",t),h(e,"alt","HF Logo"),h(e,"class","w-4 h-4 relative z-10"),h(a,"class","relative z-10")},m(s,f){p(s,e,f),p(s,n,f),p(s,a,f)},p:A,d(s){s&&(c(e),c(n),c(a))}}}function G(l){let e,t,n;return{c(){e=b("span"),t=L("👋 Logout, "),n=L(l[1]),this.h()},l(a){e=_(a,"SPAN",{class:!0});var i=v(e);t=I(i,"👋 Logout, "),n=I(i,l[1]),i.forEach(c),this.h()},h(){h(e,"class","relative z-10")},m(a,i){p(a,e,i),g(e,t),g(e,n)},p(a,i){i&2&&C(n,a[1])},d(a){a&&c(e)}}}function M(l){let e,t,n,a,i,s,f,o,x,r=l[3]&&B();function E(m,d){return m[0]?G:H}let y=E(l),u=y(l);return{c(){e=b("div"),t=b("div"),n=b("span"),a=L(l[4]),i=S(),s=b("button"),r&&r.c(),f=S(),u.c(),this.h()},l(m){e=_(m,"DIV",{class:!0});var d=v(e);t=_(d,"DIV",{class:!0});var N=v(t);n=_(N,"SPAN",{class:!0});var T=v(n);a=I(T,l[4]),T.forEach(c),N.forEach(c),i=w(d),s=_(d,"BUTTON",{class:!0});var k=v(s);r&&r.l(k),f=w(k),u.l(k),k.forEach(c),d.forEach(c),this.h()},h(){h(n,"class","font-semibold text-gray-900"),h(t,"class","flex items-center gap-2"),s.disabled=!1,h(s,"class","px-4 py-2 bg-black text-white rounded-lg font-medium hover:bg-gray-800 transition-colors shadow-sm flex items-center justify-center gap-2 text-sm disabled:opacity-50 disabled:cursor-not-allowed relative overflow-hidden"),h(e,"class","flex items-center justify-between px-4 py-4 border-b border-gray-200 min-h-[73px]")},m(m,d){p(m,e,d),g(e,t),g(t,n),g(n,a),g(e,i),g(e,s),r&&r.m(s,null),g(s,f),u.m(s,null),o||(x=D(s,"click",function(){P(l[2])&&l[2].apply(this,arguments)}),o=!0)},p(m,[d]){l=m,d&16&&C(a,l[4]),l[3]?r||(r=B(),r.c(),r.m(s,f)):r&&(r.d(1),r=null),y===(y=E(l))&&u?u.p(l,d):(u.d(1),u=y(l),u&&(u.c(),u.m(s,null)))},i:A,o:A,d(m){m&&c(e),r&&r.d(),u.d(),o=!1,x()}}}function O(l,e,t){let{isLoggedIn:n=!1}=e,{username:a=""}=e,{handleAuthAction:i=()=>{}}=e,{flashButton:s=!1}=e,{pageTitle:f="HFStudio"}=e;return l.$$set=o=>{"isLoggedIn"in o&&t(0,n=o.isLoggedIn),"username"in o&&t(1,a=o.username),"handleAuthAction"in o&&t(2,i=o.handleAuthAction),"flashButton"in o&&t(3,s=o.flashButton),"pageTitle"in o&&t(4,f=o.pageTitle)},[n,a,i,s,f]}class K extends j{constructor(e){super(),q(this,e,O,M,z,{isLoggedIn:0,username:1,handleAuthAction:2,flashButton:3,pageTitle:4})}}export{K as N};
hfstudio/static/_app/immutable/chunks/Dj_MM6zE.js ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import{S as V,i as J,s as Q,u as $,v as ee,w as G,x as U,y as te,z as ae,A as ne,B as H,C as re,D as ie,E as se,F as oe}from"./BaOlNwUz.js";import{I as le,g as ue,a as ce}from"./C7BncMoR.js";import"./IHki7fMi.js";const xe=typeof window<"u"?window:typeof globalThis<"u"?globalThis:global;function me(f){let c;const a=f[2].default,i=re(a,f,f[3],null);return{c(){i&&i.c()},l(o){i&&i.l(o)},m(o,l){i&&i.m(o,l),c=!0},p(o,l){i&&i.p&&(!c||l&8)&&ie(i,a,o,o[3],c?oe(a,o[3],l,null):se(o[3]),null)},i(o){c||(U(i,o),c=!0)},o(o){G(i,o),c=!1},d(o){i&&i.d(o)}}}function be(f){let c,a;const i=[{name:"copy"},f[1],{iconNode:f[0]}];let o={$$slots:{default:[me]},$$scope:{ctx:f}};for(let l=0;l<i.length;l+=1)o=$(o,i[l]);return c=new le({props:o}),{c(){ne(c.$$.fragment)},l(l){ae(c.$$.fragment,l)},m(l,p){te(c,l,p),a=!0},p(l,[p]){const u=p&3?ue(i,[i[0],p&2&&ce(l[1]),p&1&&{iconNode:l[0]}]):{};p&8&&(u.$$scope={dirty:p,ctx:l}),c.$set(u)},i(l){a||(U(c.$$.fragment,l),a=!0)},o(l){G(c.$$.fragment,l),a=!1},d(l){ee(c,l)}}}function ve(f,c,a){let{$$slots:i={},$$scope:o}=c;const l=[["rect",{width:"14",height:"14",x:"8",y:"8",rx:"2",ry:"2"}],["path",{d:"M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"}]];return f.$$set=p=>{a(1,c=$($({},c),H(p))),"$$scope"in p&&a(3,o=p.$$scope)},c=H(c),[l,c,i,o]}class Te extends V{constructor(c){super(),J(this,c,ve,be,Q,{})}}function Se(f){let c;const a=f[2].default,i=re(a,f,f[3],null);return{c(){i&&i.c()},l(o){i&&i.l(o)},m(o,l){i&&i.m(o,l),c=!0},p(o,l){i&&i.p&&(!c||l&8)&&ie(i,a,o,o[3],c?oe(a,o[3],l,null):se(o[3]),null)},i(o){c||(U(i,o),c=!0)},o(o){G(i,o),c=!1},d(o){i&&i.d(o)}}}function ye(f){let c,a;const i=[{name:"download"},f[1],{iconNode:f[0]}];let o={$$slots:{default:[Se]},$$scope:{ctx:f}};for(let l=0;l<i.length;l+=1)o=$(o,i[l]);return c=new le({props:o}),{c(){ne(c.$$.fragment)},l(l){ae(c.$$.fragment,l)},m(l,p){te(c,l,p),a=!0},p(l,[p]){const u=p&3?ue(i,[i[0],p&2&&ce(l[1]),p&1&&{iconNode:l[0]}]):{};p&8&&(u.$$scope={dirty:p,ctx:l}),c.$set(u)},i(l){a||(U(c.$$.fragment,l),a=!0)},o(l){G(c.$$.fragment,l),a=!1},d(l){ee(c,l)}}}function Ae(f,c,a){let{$$slots:i={},$$scope:o}=c;const l=[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"}],["polyline",{points:"7 10 12 15 17 10"}],["line",{x1:"12",x2:"12",y1:"15",y2:"3"}]];return f.$$set=p=>{a(1,c=$($({},c),H(p))),"$$scope"in p&&a(3,o=p.$$scope)},c=H(c),[l,c,i,o]}class $e extends V{constructor(c){super(),J(this,c,Ae,ye,Q,{})}}var K=typeof globalThis<"u"?globalThis:typeof window<"u"?window:typeof global<"u"?global:typeof self<"u"?self:{};function _e(f){return f&&f.__esModule&&Object.prototype.hasOwnProperty.call(f,"default")?f.default:f}var de={exports:{}};(function(f){var c=typeof window<"u"?window:typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope?self:{};/**
2
+ * Prism: Lightweight, robust, elegant syntax highlighting
3
+ *
4
+ * @license MIT <https://opensource.org/licenses/MIT>
5
+ * @author Lea Verou <https://lea.verou.me>
6
+ * @namespace
7
+ * @public
8
+ */var a=function(i){var o=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,l=0,p={},u={manual:i.Prism&&i.Prism.manual,disableWorkerMessageHandler:i.Prism&&i.Prism.disableWorkerMessageHandler,util:{encode:function t(e){return e instanceof _?new _(e.type,t(e.content),e.alias):Array.isArray(e)?e.map(t):e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/\u00a0/g," ")},type:function(t){return Object.prototype.toString.call(t).slice(8,-1)},objId:function(t){return t.__id||Object.defineProperty(t,"__id",{value:++l}),t.__id},clone:function t(e,n){n=n||{};var r,s;switch(u.util.type(e)){case"Object":if(s=u.util.objId(e),n[s])return n[s];r={},n[s]=r;for(var g in e)e.hasOwnProperty(g)&&(r[g]=t(e[g],n));return r;case"Array":return s=u.util.objId(e),n[s]?n[s]:(r=[],n[s]=r,e.forEach(function(h,d){r[d]=t(h,n)}),r);default:return e}},getLanguage:function(t){for(;t;){var e=o.exec(t.className);if(e)return e[1].toLowerCase();t=t.parentElement}return"none"},setLanguage:function(t,e){t.className=t.className.replace(RegExp(o,"gi"),""),t.classList.add("language-"+e)},currentScript:function(){if(typeof document>"u")return null;if(document.currentScript&&document.currentScript.tagName==="SCRIPT")return document.currentScript;try{throw new Error}catch(r){var t=(/at [^(\r\n]*\((.*):[^:]+:[^:]+\)$/i.exec(r.stack)||[])[1];if(t){var e=document.getElementsByTagName("script");for(var n in e)if(e[n].src==t)return e[n]}return null}},isActive:function(t,e,n){for(var r="no-"+e;t;){var s=t.classList;if(s.contains(e))return!0;if(s.contains(r))return!1;t=t.parentElement}return!!n}},languages:{plain:p,plaintext:p,text:p,txt:p,extend:function(t,e){var n=u.util.clone(u.languages[t]);for(var r in e)n[r]=e[r];return n},insertBefore:function(t,e,n,r){r=r||u.languages;var s=r[t],g={};for(var h in s)if(s.hasOwnProperty(h)){if(h==e)for(var d in n)n.hasOwnProperty(d)&&(g[d]=n[d]);n.hasOwnProperty(h)||(g[h]=s[h])}var b=r[t];return r[t]=g,u.languages.DFS(u.languages,function(y,k){k===b&&y!=t&&(this[y]=g)}),g},DFS:function t(e,n,r,s){s=s||{};var g=u.util.objId;for(var h in e)if(e.hasOwnProperty(h)){n.call(e,h,e[h],r||h);var d=e[h],b=u.util.type(d);b==="Object"&&!s[g(d)]?(s[g(d)]=!0,t(d,n,null,s)):b==="Array"&&!s[g(d)]&&(s[g(d)]=!0,t(d,n,h,s))}}},plugins:{},highlightAll:function(t,e){u.highlightAllUnder(document,t,e)},highlightAllUnder:function(t,e,n){var r={callback:n,container:t,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};u.hooks.run("before-highlightall",r),r.elements=Array.prototype.slice.apply(r.container.querySelectorAll(r.selector)),u.hooks.run("before-all-elements-highlight",r);for(var s=0,g;g=r.elements[s++];)u.highlightElement(g,e===!0,r.callback)},highlightElement:function(t,e,n){var r=u.util.getLanguage(t),s=u.languages[r];u.util.setLanguage(t,r);var g=t.parentElement;g&&g.nodeName.toLowerCase()==="pre"&&u.util.setLanguage(g,r);var h=t.textContent,d={element:t,language:r,grammar:s,code:h};function b(k){d.highlightedCode=k,u.hooks.run("before-insert",d),d.element.innerHTML=d.highlightedCode,u.hooks.run("after-highlight",d),u.hooks.run("complete",d),n&&n.call(d.element)}if(u.hooks.run("before-sanity-check",d),g=d.element.parentElement,g&&g.nodeName.toLowerCase()==="pre"&&!g.hasAttribute("tabindex")&&g.setAttribute("tabindex","0"),!d.code){u.hooks.run("complete",d),n&&n.call(d.element);return}if(u.hooks.run("before-highlight",d),!d.grammar){b(u.util.encode(d.code));return}if(e&&i.Worker){var y=new Worker(u.filename);y.onmessage=function(k){b(k.data)},y.postMessage(JSON.stringify({language:d.language,code:d.code,immediateClose:!0}))}else b(u.highlight(d.code,d.grammar,d.language))},highlight:function(t,e,n){var r={code:t,grammar:e,language:n};if(u.hooks.run("before-tokenize",r),!r.grammar)throw new Error('The language "'+r.language+'" has no grammar.');return r.tokens=u.tokenize(r.code,r.grammar),u.hooks.run("after-tokenize",r),_.stringify(u.util.encode(r.tokens),r.language)},tokenize:function(t,e){var n=e.rest;if(n){for(var r in n)e[r]=n[r];delete e.rest}var s=new O;return x(s,s.head,t),R(t,s,e,s.head,0),P(s)},hooks:{all:{},add:function(t,e){var n=u.hooks.all;n[t]=n[t]||[],n[t].push(e)},run:function(t,e){var n=u.hooks.all[t];if(!(!n||!n.length))for(var r=0,s;s=n[r++];)s(e)}},Token:_};i.Prism=u;function _(t,e,n,r){this.type=t,this.content=e,this.alias=n,this.length=(r||"").length|0}_.stringify=function t(e,n){if(typeof e=="string")return e;if(Array.isArray(e)){var r="";return e.forEach(function(b){r+=t(b,n)}),r}var s={type:e.type,content:t(e.content,n),tag:"span",classes:["token",e.type],attributes:{},language:n},g=e.alias;g&&(Array.isArray(g)?Array.prototype.push.apply(s.classes,g):s.classes.push(g)),u.hooks.run("wrap",s);var h="";for(var d in s.attributes)h+=" "+d+'="'+(s.attributes[d]||"").replace(/"/g,"&quot;")+'"';return"<"+s.tag+' class="'+s.classes.join(" ")+'"'+h+">"+s.content+"</"+s.tag+">"};function I(t,e,n,r){t.lastIndex=e;var s=t.exec(n);if(s&&r&&s[1]){var g=s[1].length;s.index+=g,s[0]=s[0].slice(g)}return s}function R(t,e,n,r,s,g){for(var h in n)if(!(!n.hasOwnProperty(h)||!n[h])){var d=n[h];d=Array.isArray(d)?d:[d];for(var b=0;b<d.length;++b){if(g&&g.cause==h+","+b)return;var y=d[b],k=y.inside,q=!!y.lookbehind,Y=!!y.greedy,ge=y.alias;if(Y&&!y.pattern.global){var pe=y.pattern.toString().match(/[imsuy]*$/)[0];y.pattern=RegExp(y.pattern.source,pe+"g")}for(var Z=y.pattern||y,A=r.next,w=s;A!==e.tail&&!(g&&w>=g.reach);w+=A.value.length,A=A.next){var T=A.value;if(e.length>t.length)return;if(!(T instanceof _)){var C=1,E;if(Y){if(E=I(Z,w,t,q),!E||E.index>=t.length)break;var N=E.index,fe=E.index+E[0].length,F=w;for(F+=A.value.length;N>=F;)A=A.next,F+=A.value.length;if(F-=A.value.length,w=F,A.value instanceof _)continue;for(var D=A;D!==e.tail&&(F<fe||typeof D.value=="string");D=D.next)C++,F+=D.value.length;C--,T=t.slice(w,F),E.index-=w}else if(E=I(Z,0,T,q),!E)continue;var N=E.index,L=E[0],z=T.slice(0,N),W=T.slice(N+L.length),j=w+T.length;g&&j>g.reach&&(g.reach=j);var M=A.prev;z&&(M=x(e,M,z),w+=z.length),B(e,M,C);var he=new _(h,k?u.tokenize(L,k):L,ge,L);if(A=x(e,M,he),W&&x(e,A,W),C>1){var X={cause:h+","+b,reach:j};R(t,e,n,A.prev,w,X),g&&X.reach>g.reach&&(g.reach=X.reach)}}}}}}function O(){var t={value:null,prev:null,next:null},e={value:null,prev:t,next:null};t.next=e,this.head=t,this.tail=e,this.length=0}function x(t,e,n){var r=e.next,s={value:n,prev:e,next:r};return e.next=s,r.prev=s,t.length++,s}function B(t,e,n){for(var r=e.next,s=0;s<n&&r!==t.tail;s++)r=r.next;e.next=r,r.prev=e,t.length-=s}function P(t){for(var e=[],n=t.head.next;n!==t.tail;)e.push(n.value),n=n.next;return e}if(!i.document)return i.addEventListener&&(u.disableWorkerMessageHandler||i.addEventListener("message",function(t){var e=JSON.parse(t.data),n=e.language,r=e.code,s=e.immediateClose;i.postMessage(u.highlight(r,u.languages[n],n)),s&&i.close()},!1)),u;var v=u.util.currentScript();v&&(u.filename=v.src,v.hasAttribute("data-manual")&&(u.manual=!0));function m(){u.manual||u.highlightAll()}if(!u.manual){var S=document.readyState;S==="loading"||S==="interactive"&&v&&v.defer?document.addEventListener("DOMContentLoaded",m):window.requestAnimationFrame?window.requestAnimationFrame(m):window.setTimeout(m,16)}return u}(c);f.exports&&(f.exports=a),typeof K<"u"&&(K.Prism=a),a.languages.markup={comment:{pattern:/<!--(?:(?!<!--)[\s\S])*?-->/,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},{pattern:/^(\s*)["']|["']$/,lookbehind:!0}]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",function(i){i.type==="entity"&&(i.attributes.title=i.content.replace(/&amp;/,"&"))}),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(o,l){var p={};p["language-"+l]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:a.languages[l]},p.cdata=/^<!\[CDATA\[|\]\]>$/i;var u={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:p}};u["language-"+l]={pattern:/[\s\S]+/,inside:a.languages[l]};var _={};_[o]={pattern:RegExp(/(<__[^>]*>)(?:<!\[CDATA\[(?:[^\]]|\](?!\]>))*\]\]>|(?!<!\[CDATA\[)[\s\S])*?(?=<\/__>)/.source.replace(/__/g,function(){return o}),"i"),lookbehind:!0,greedy:!0,inside:u},a.languages.insertBefore("markup","cdata",_)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(i,o){a.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+i+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[o,"language-"+o],inside:a.languages[o]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,function(i){var o=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;i.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:RegExp("@[\\w-](?:"+/[^;{\s"']|\s+(?!\s)/.source+"|"+o.source+")*?"+/(?:;|(?=\s*\{))/.source),inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+o.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+o.source+"$"),alias:"url"}}},selector:{pattern:RegExp(`(^|[{}\\s])[^{}\\s](?:[^{};"'\\s]|\\s+(?![\\s{])|`+o.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:o,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},i.languages.css.atrule.inside.rest=i.languages.css;var l=i.languages.markup;l&&(l.tag.addInlined("style","css"),l.tag.addAttribute("style","css"))}(a),a.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|trait)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:break|catch|continue|do|else|finally|for|function|if|in|instanceof|new|null|return|throw|try|while)\b/,boolean:/\b(?:false|true)\b/,function:/\b\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.javascript=a.languages.extend("clike",{"class-name":[a.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+(/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source)+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:RegExp(/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)/.source+/\//.source+"(?:"+/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}/.source+"|"+/(?:\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.|\[(?:[^[\]\\\r\n]|\\.)*\])*\])*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}v[dgimyus]{0,7}/.source+")"+/(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/.source),lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:a.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),a.languages.js=a.languages.javascript,function(){if(typeof a>"u"||typeof document>"u")return;Element.prototype.matches||(Element.prototype.matches=Element.prototype.msMatchesSelector||Element.prototype.webkitMatchesSelector);var i="Loading…",o=function(v,m){return"✖ Error "+v+" while fetching file: "+m},l="✖ Error: File does not exist or is empty",p={js:"javascript",py:"python",rb:"ruby",ps1:"powershell",psm1:"powershell",sh:"bash",bat:"batch",h:"c",tex:"latex"},u="data-src-status",_="loading",I="loaded",R="failed",O="pre[data-src]:not(["+u+'="'+I+'"]):not(['+u+'="'+_+'"])';function x(v,m,S){var t=new XMLHttpRequest;t.open("GET",v,!0),t.onreadystatechange=function(){t.readyState==4&&(t.status<400&&t.responseText?m(t.responseText):t.status>=400?S(o(t.status,t.statusText)):S(l))},t.send(null)}function B(v){var m=/^\s*(\d+)\s*(?:(,)\s*(?:(\d+)\s*)?)?$/.exec(v||"");if(m){var S=Number(m[1]),t=m[2],e=m[3];return t?e?[S,Number(e)]:[S,void 0]:[S,S]}}a.hooks.add("before-highlightall",function(v){v.selector+=", "+O}),a.hooks.add("before-sanity-check",function(v){var m=v.element;if(m.matches(O)){v.code="",m.setAttribute(u,_);var S=m.appendChild(document.createElement("CODE"));S.textContent=i;var t=m.getAttribute("data-src"),e=v.language;if(e==="none"){var n=(/\.(\w+)$/.exec(t)||[,"none"])[1];e=p[n]||n}a.util.setLanguage(S,e),a.util.setLanguage(m,e);var r=a.plugins.autoloader;r&&r.loadLanguages(e),x(t,function(s){m.setAttribute(u,I);var g=B(m.getAttribute("data-range"));if(g){var h=s.split(/\r\n?|\n/g),d=g[0],b=g[1]==null?h.length:g[1];d<0&&(d+=h.length),d=Math.max(0,Math.min(d-1,h.length)),b<0&&(b+=h.length),b=Math.max(0,Math.min(b,h.length)),s=h.slice(d,b).join(`
9
+ `),m.hasAttribute("data-start")||m.setAttribute("data-start",String(d+1))}S.textContent=s,a.highlightElement(S)},function(s){m.setAttribute(u,R),S.textContent=s})}}),a.plugins.fileHighlight={highlight:function(m){for(var S=(m||document).querySelectorAll(O),t=0,e;e=S[t++];)a.highlightElement(e)}};var P=!1;a.fileHighlight=function(){P||(console.warn("Prism.fileHighlight is deprecated. Use `Prism.plugins.fileHighlight.highlight` instead."),P=!0),a.plugins.fileHighlight.highlight.apply(this,arguments)}}()})(de);var Ee=de.exports;const Ie=_e(Ee);Prism.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/};Prism.languages.python["string-interpolation"].inside.interpolation.inside.rest=Prism.languages.python;Prism.languages.py=Prism.languages.python;(function(f){var c="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",a={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},i={bash:a,environment:{pattern:RegExp("\\$"+c),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+c),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};f.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?:\.\w+)*(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+c),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},parameter:{pattern:/(^|\s)-{1,2}(?:\w+:[+-]?)?\w+(?:\.\w+)*(?=[=\s]|$)/,alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:i},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:a}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:i},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:i.entity}}],environment:{pattern:RegExp("\\$?"+c),alias:"constant"},variable:i.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cargo|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|java|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|sysctl|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},a.inside=f.languages.bash;for(var o=["comment","function-name","for-or-select","assign-left","parameter","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],l=i.variable[1].inside,p=0;p<o.length;p++)l[o[p]]=f.languages.bash[o[p]];f.languages.sh=f.languages.bash,f.languages.shell=f.languages.bash})(Prism);export{Te as C,$e as D,Ie as P,xe as g};
hfstudio/static/_app/immutable/chunks/QsMRfqzH.js ADDED
@@ -0,0 +1 @@
 
 
1
+ import{s as e}from"./B7RJWGyJ.js";const r=()=>{const s=e;return{page:{subscribe:s.page.subscribe},navigating:{subscribe:s.navigating.subscribe},updated:s.updated}},b={subscribe(s){return r().page.subscribe(s)}};export{b as p};
hfstudio/static/_app/immutable/entry/app.BBX27H-0.js ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["../nodes/0.Ch20oj6r.js","../chunks/BaOlNwUz.js","../chunks/IHki7fMi.js","../chunks/QsMRfqzH.js","../chunks/B7RJWGyJ.js","../chunks/CbFjO8O8.js","../chunks/4G_mFUFB.js","../chunks/C7BncMoR.js","../assets/0.3AZkBLcv.css","../nodes/1.C7ooe2uD.js","../nodes/2.DEDaBsJG.js","../chunks/Dj_MM6zE.js","../chunks/BV8rDFhh.js","../chunks/Bm0csYZC.js","../assets/2.CdRym-eY.css","../nodes/3.CX0V79eQ.js","../assets/3.BNkL3CE9.css","../nodes/4.Blz4Bme4.js"])))=>i.map(i=>d[i]);
2
+ import{S as C,i as U,s as q,d,w as h,x as g,N as O,H as S,b as v,h as B,J as w,k as W,U as z,K as H,V as J,W as y,v as P,A as R,y as L,z as D,p as T,L as p,e as K,f as F,j as G,T as V,a as Q,g as X,t as Y}from"../chunks/BaOlNwUz.js";import"../chunks/IHki7fMi.js";const Z="modulepreload",M=function(o,e){return new URL(o,e).href},I={},A=function(e,n,i){let r=Promise.resolve();if(n&&n.length>0){const t=document.getElementsByTagName("link"),s=document.querySelector("meta[property=csp-nonce]"),a=(s==null?void 0:s.nonce)||(s==null?void 0:s.getAttribute("nonce"));r=Promise.allSettled(n.map(f=>{if(f=M(f,i),f in I)return;I[f]=!0;const l=f.endsWith(".css"),_=l?'[rel="stylesheet"]':"";if(!!i)for(let k=t.length-1;k>=0;k--){const E=t[k];if(E.href===f&&(!l||E.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${f}"]${_}`))return;const m=document.createElement("link");if(m.rel=l?"stylesheet":Z,l||(m.as="script"),m.crossOrigin="",m.href=f,a&&m.setAttribute("nonce",a),document.head.appendChild(m),l)return new Promise((k,E)=>{m.addEventListener("load",k),m.addEventListener("error",()=>E(new Error(`Unable to preload CSS for ${f}`)))})}))}function u(t){const s=new Event("vite:preloadError",{cancelable:!0});if(s.payload=t,window.dispatchEvent(s),!s.defaultPrevented)throw t}return r.then(t=>{for(const s of t||[])s.status==="rejected"&&u(s.reason);return e().catch(u)})},ae={};function $(o){let e,n,i;var r=o[2][0];function u(t,s){return{props:{data:t[4],form:t[3],params:t[1].params}}}return r&&(e=y(r,u(o)),o[12](e)),{c(){e&&R(e.$$.fragment),n=w()},l(t){e&&D(e.$$.fragment,t),n=w()},m(t,s){e&&L(e,t,s),v(t,n,s),i=!0},p(t,s){if(s&4&&r!==(r=t[2][0])){if(e){O();const a=e;h(a.$$.fragment,1,0,()=>{P(a,1)}),S()}r?(e=y(r,u(t)),t[12](e),R(e.$$.fragment),g(e.$$.fragment,1),L(e,n.parentNode,n)):e=null}else if(r){const a={};s&16&&(a.data=t[4]),s&8&&(a.form=t[3]),s&2&&(a.params=t[1].params),e.$set(a)}},i(t){i||(e&&g(e.$$.fragment,t),i=!0)},o(t){e&&h(e.$$.fragment,t),i=!1},d(t){t&&d(n),o[12](null),e&&P(e,t)}}}function x(o){let e,n,i;var r=o[2][0];function u(t,s){return{props:{data:t[4],params:t[1].params,$$slots:{default:[ee]},$$scope:{ctx:t}}}}return r&&(e=y(r,u(o)),o[11](e)),{c(){e&&R(e.$$.fragment),n=w()},l(t){e&&D(e.$$.fragment,t),n=w()},m(t,s){e&&L(e,t,s),v(t,n,s),i=!0},p(t,s){if(s&4&&r!==(r=t[2][0])){if(e){O();const a=e;h(a.$$.fragment,1,0,()=>{P(a,1)}),S()}r?(e=y(r,u(t)),t[11](e),R(e.$$.fragment),g(e.$$.fragment,1),L(e,n.parentNode,n)):e=null}else if(r){const a={};s&16&&(a.data=t[4]),s&2&&(a.params=t[1].params),s&8239&&(a.$$scope={dirty:s,ctx:t}),e.$set(a)}},i(t){i||(e&&g(e.$$.fragment,t),i=!0)},o(t){e&&h(e.$$.fragment,t),i=!1},d(t){t&&d(n),o[11](null),e&&P(e,t)}}}function ee(o){let e,n,i;var r=o[2][1];function u(t,s){return{props:{data:t[5],form:t[3],params:t[1].params}}}return r&&(e=y(r,u(o)),o[10](e)),{c(){e&&R(e.$$.fragment),n=w()},l(t){e&&D(e.$$.fragment,t),n=w()},m(t,s){e&&L(e,t,s),v(t,n,s),i=!0},p(t,s){if(s&4&&r!==(r=t[2][1])){if(e){O();const a=e;h(a.$$.fragment,1,0,()=>{P(a,1)}),S()}r?(e=y(r,u(t)),t[10](e),R(e.$$.fragment),g(e.$$.fragment,1),L(e,n.parentNode,n)):e=null}else if(r){const a={};s&32&&(a.data=t[5]),s&8&&(a.form=t[3]),s&2&&(a.params=t[1].params),e.$set(a)}},i(t){i||(e&&g(e.$$.fragment,t),i=!0)},o(t){e&&h(e.$$.fragment,t),i=!1},d(t){t&&d(n),o[10](null),e&&P(e,t)}}}function N(o){let e,n=o[7]&&j(o);return{c(){e=G("div"),n&&n.c(),this.h()},l(i){e=K(i,"DIV",{id:!0,"aria-live":!0,"aria-atomic":!0,style:!0});var r=F(e);n&&n.l(r),r.forEach(d),this.h()},h(){T(e,"id","svelte-announcer"),T(e,"aria-live","assertive"),T(e,"aria-atomic","true"),p(e,"position","absolute"),p(e,"left","0"),p(e,"top","0"),p(e,"clip","rect(0 0 0 0)"),p(e,"clip-path","inset(50%)"),p(e,"overflow","hidden"),p(e,"white-space","nowrap"),p(e,"width","1px"),p(e,"height","1px")},m(i,r){v(i,e,r),n&&n.m(e,null)},p(i,r){i[7]?n?n.p(i,r):(n=j(i),n.c(),n.m(e,null)):n&&(n.d(1),n=null)},d(i){i&&d(e),n&&n.d()}}}function j(o){let e;return{c(){e=Y(o[8])},l(n){e=X(n,o[8])},m(n,i){v(n,e,i)},p(n,i){i&256&&Q(e,n[8])},d(n){n&&d(e)}}}function te(o){let e,n,i,r,u;const t=[x,$],s=[];function a(l,_){return l[2][1]?0:1}e=a(o),n=s[e]=t[e](o);let f=o[6]&&N(o);return{c(){n.c(),i=W(),f&&f.c(),r=w()},l(l){n.l(l),i=B(l),f&&f.l(l),r=w()},m(l,_){s[e].m(l,_),v(l,i,_),f&&f.m(l,_),v(l,r,_),u=!0},p(l,[_]){let b=e;e=a(l),e===b?s[e].p(l,_):(O(),h(s[b],1,1,()=>{s[b]=null}),S(),n=s[e],n?n.p(l,_):(n=s[e]=t[e](l),n.c()),g(n,1),n.m(i.parentNode,i)),l[6]?f?f.p(l,_):(f=N(l),f.c(),f.m(r.parentNode,r)):f&&(f.d(1),f=null)},i(l){u||(g(n),u=!0)},o(l){h(n),u=!1},d(l){l&&(d(i),d(r)),s[e].d(l),f&&f.d(l)}}}function ne(o,e,n){let{stores:i}=e,{page:r}=e,{constructors:u}=e,{components:t=[]}=e,{form:s}=e,{data_0:a=null}=e,{data_1:f=null}=e;z(i.page.notify);let l=!1,_=!1,b=null;H(()=>{const c=i.page.subscribe(()=>{l&&(n(7,_=!0),J().then(()=>{n(8,b=document.title||"untitled page")}))});return n(6,l=!0),c});function m(c){V[c?"unshift":"push"](()=>{t[1]=c,n(0,t)})}function k(c){V[c?"unshift":"push"](()=>{t[0]=c,n(0,t)})}function E(c){V[c?"unshift":"push"](()=>{t[0]=c,n(0,t)})}return o.$$set=c=>{"stores"in c&&n(9,i=c.stores),"page"in c&&n(1,r=c.page),"constructors"in c&&n(2,u=c.constructors),"components"in c&&n(0,t=c.components),"form"in c&&n(3,s=c.form),"data_0"in c&&n(4,a=c.data_0),"data_1"in c&&n(5,f=c.data_1)},o.$$.update=()=>{o.$$.dirty&514&&i.page.set(r)},[t,r,u,s,a,f,l,_,b,i,m,k,E]}class le extends C{constructor(e){super(),U(this,e,ne,te,q,{stores:9,page:1,constructors:2,components:0,form:3,data_0:4,data_1:5})}}const fe=[()=>A(()=>import("../nodes/0.Ch20oj6r.js"),__vite__mapDeps([0,1,2,3,4,5,6,7,8]),import.meta.url),()=>A(()=>import("../nodes/1.C7ooe2uD.js"),__vite__mapDeps([9,1,2,3,4]),import.meta.url),()=>A(()=>import("../nodes/2.DEDaBsJG.js"),__vite__mapDeps([10,1,11,7,2,12,13,14]),import.meta.url),()=>A(()=>import("../nodes/3.CX0V79eQ.js"),__vite__mapDeps([15,1,11,7,2,5,13,16]),import.meta.url),()=>A(()=>import("../nodes/4.Blz4Bme4.js"),__vite__mapDeps([17,1,7,2,12,6,13]),import.meta.url)],ce=[],ue={"/":[2],"/code-recorder":[3],"/voice-cloning":[4]},se={handleError:({error:o})=>{console.error(o)},reroute:()=>{},transport:{}},ie=Object.fromEntries(Object.entries(se.transport).map(([o,e])=>[o,e.decode])),_e=!1,me=(o,e)=>ie[o](e);export{me as decode,ie as decoders,ue as dictionary,_e as hash,se as hooks,ae as matchers,fe as nodes,le as root,ce as server_loads};
hfstudio/static/_app/immutable/entry/start.C4SfOwCE.js ADDED
@@ -0,0 +1 @@
 
 
1
+ import{l as o,a as r}from"../chunks/B7RJWGyJ.js";export{o as load_css,r as start};
hfstudio/static/_app/immutable/nodes/0.Ch20oj6r.js ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ import{S as lt,i as ot,s as rt,C as it,d as I,v as Qe,w as Oe,x as Ue,p as s,D as ut,E as ct,F as pt,b as be,c as t,y as Xe,e as a,f as j,r as d,h as u,z as Ze,j as l,k as c,A as $e,l as ft,K as dt,G as ht,O as et,m as xe,a as mt,g as gt,t as xt}from"../chunks/BaOlNwUz.js";import"../chunks/IHki7fMi.js";import{p as bt}from"../chunks/QsMRfqzH.js";import{N as _t}from"../chunks/CbFjO8O8.js";import{M as vt}from"../chunks/4G_mFUFB.js";function tt(f){let o,n,p,L="Sign In with HuggingFace Token",R,e,x,A="<strong>Manual Token Entry:</strong> Please enter your HuggingFace token.",D,h,T=`1. Go to <a href="https://huggingface.co/settings/tokens" target="_blank" class="underline text-blue-600">HuggingFace Settings</a><br/>
2
+ 2. Create a new token with &quot;Inference API&quot; permissions<br/>
3
+ 3. Copy and paste it below`,Q,F,_,O,q="HuggingFace Token",K,b,S,W,k,i,N="Cancel",H,g,z="Sign In",B,U,y=f[5]&&nt(),w=f[4]&&st(f);return{c(){o=l("div"),n=l("div"),p=l("h2"),p.textContent=L,R=c(),e=l("div"),x=l("p"),x.innerHTML=A,D=c(),h=l("p"),h.innerHTML=T,Q=c(),y&&y.c(),F=c(),_=l("div"),O=l("label"),O.textContent=q,K=c(),b=l("input"),S=c(),w&&w.c(),W=c(),k=l("div"),i=l("button"),i.textContent=N,H=c(),g=l("button"),g.textContent=z,this.h()},l(v){o=a(v,"DIV",{class:!0});var G=j(o);n=a(G,"DIV",{class:!0});var V=j(n);p=a(V,"H2",{class:!0,"data-svelte-h":!0}),d(p)!=="svelte-1t0ehet"&&(p.textContent=L),R=u(V),e=a(V,"DIV",{class:!0});var E=j(e);x=a(E,"P",{class:!0,"data-svelte-h":!0}),d(x)!=="svelte-344vn4"&&(x.innerHTML=A),D=u(E),h=a(E,"P",{class:!0,"data-svelte-h":!0}),d(h)!=="svelte-orsfwv"&&(h.innerHTML=T),Q=u(E),y&&y.l(E),E.forEach(I),F=u(V),_=a(V,"DIV",{class:!0});var Y=j(_);O=a(Y,"LABEL",{for:!0,class:!0,"data-svelte-h":!0}),d(O)!=="svelte-vtbmxo"&&(O.textContent=q),K=u(Y),b=a(Y,"INPUT",{id:!0,type:!0,placeholder:!0,class:!0}),S=u(Y),w&&w.l(Y),Y.forEach(I),W=u(V),k=a(V,"DIV",{class:!0});var X=j(k);i=a(X,"BUTTON",{class:!0,"data-svelte-h":!0}),d(i)!=="svelte-csk0rj"&&(i.textContent=N),H=u(X),g=a(X,"BUTTON",{class:!0,"data-svelte-h":!0}),d(g)!=="svelte-1nxas5u"&&(g.textContent=z),X.forEach(I),V.forEach(I),G.forEach(I),this.h()},h(){s(p,"class","text-xl font-semibold mb-4"),s(x,"class","text-blue-800 mb-2"),s(h,"class","text-blue-700"),s(e,"class","mb-4 p-3 bg-blue-50 rounded-md text-sm"),s(O,"for","token"),s(O,"class","block text-sm font-medium text-gray-700 mb-2"),s(b,"id","token"),s(b,"type","password"),s(b,"placeholder","hf_..."),s(b,"class","w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-orange-500 focus:border-transparent"),s(_,"class","mb-4"),s(i,"class","px-4 py-2 text-gray-600 hover:text-gray-800 transition-colors"),s(g,"class","px-4 py-2 bg-orange-500 text-white rounded-md hover:bg-orange-600 transition-colors"),s(k,"class","flex justify-end gap-3"),s(n,"class","bg-white rounded-lg p-6 max-w-md w-full mx-4 shadow-xl"),s(o,"class","fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50")},m(v,G){be(v,o,G),t(o,n),t(n,p),t(n,R),t(n,e),t(e,x),t(e,D),t(e,h),t(e,Q),y&&y.m(e,null),t(n,F),t(n,_),t(_,O),t(_,K),t(_,b),et(b,f[3]),t(_,S),w&&w.m(_,null),t(n,W),t(n,k),t(k,i),t(k,H),t(k,g),B||(U=[xe(b,"input",f[13]),xe(b,"keydown",f[14]),xe(i,"click",f[9]),xe(g,"click",f[10])],B=!0)},p(v,G){v[5]?y||(y=nt(),y.c(),y.m(e,null)):y&&(y.d(1),y=null),G&8&&b.value!==v[3]&&et(b,v[3]),v[4]?w?w.p(v,G):(w=st(v),w.c(),w.m(_,null)):w&&(w.d(1),w=null)},d(v){v&&I(o),y&&y.d(),w&&w.d(),B=!1,ht(U)}}}function nt(f){let o,n=`<strong>Tip:</strong> You can also run <code>huggingface-cli login</code> in your terminal
4
+ to automatically use your local token.`;return{c(){o=l("p"),o.innerHTML=n,this.h()},l(p){o=a(p,"P",{class:!0,"data-svelte-h":!0}),d(o)!=="svelte-xrut8w"&&(o.innerHTML=n),this.h()},h(){s(o,"class","text-blue-600 mt-2")},m(p,L){be(p,o,L)},d(p){p&&I(o)}}}function st(f){let o,n;return{c(){o=l("p"),n=xt(f[4]),this.h()},l(p){o=a(p,"P",{class:!0});var L=j(o);n=gt(L,f[4]),L.forEach(I),this.h()},h(){s(o,"class","text-red-600 text-sm mt-1")},m(p,L){be(p,o,L),t(o,n)},p(p,L){L&16&&mt(n,p[4])},d(p){p&&I(o)}}}function wt(f){let o,n,p,L='<div class="flex items-center gap-3"><img src="/assets/hf-studio-logo.png" alt="HF Logo" class="w-8 h-8"/> <h1 class="text-xl font-semibold">HFStudio<sup class="text-xs text-gray-500 ml-1">BETA</sup></h1></div>',R,e,x,A="Audio",D,h,T,Q="🎙️",F,_,O="Text to Speech",q,K,b,S,W,k,i="Voice Cloning",N,H,g,z="<span>🎧</span> <span>Speech to Text</span>",B,U,y="<span>🎼</span> <span>Sound Effects</span>",w,v,G="<span>🎸</span> <span>Music Generation</span>",V,E,Y="<span>🔊</span> <span>Audio Enhancement</span>",X,fe,Pe="Image",_e,Z,Ve="<span>🎨</span> <span>Text to Image</span>",ve,$,je="<span>🖼️</span> <span>Image to Image</span>",we,ee,De="<span>✂️</span> <span>Remove Background</span>",Te,te,Fe="<span>🔍</span> <span>Upscale Image</span>",ye,ne,ze="<span>🎭</span> <span>Face Swap</span>",Ce,se,Re="<span>📝</span> <span>Image to Text</span>",ke,de,qe="Video",Le,ae,Ge="<span>🎬</span> <span>Text to Video</span>",He,le,Je="<span>🎞️</span> <span>Image to Video</span>",Me,oe,Ke="<span>✨</span> <span>Video Enhancement</span>",Ie,re,We="<span>🎤</span> <span>Lip Sync</span>",Ne,ie,Ye="<span>🗣️</span> <span>Video Dubbing</span>",Ee,ue,ce,Se,Be,pe;S=new vt({props:{size:16}}),ce=new _t({props:{isLoggedIn:f[0],username:f[1],handleAuthAction:f[8],flashButton:f[6],pageTitle:at(f[7].url.pathname)}});const Ae=f[12].default,P=it(Ae,f,f[11],null);let M=f[2]&&tt(f);return{c(){o=l("div"),n=l("aside"),p=l("div"),p.innerHTML=L,R=c(),e=l("nav"),x=l("div"),x.textContent=A,D=c(),h=l("a"),T=l("span"),T.textContent=Q,F=c(),_=l("span"),_.textContent=O,K=c(),b=l("a"),$e(S.$$.fragment),W=c(),k=l("span"),k.textContent=i,H=c(),g=l("button"),g.innerHTML=z,B=c(),U=l("button"),U.innerHTML=y,w=c(),v=l("button"),v.innerHTML=G,V=c(),E=l("button"),E.innerHTML=Y,X=c(),fe=l("div"),fe.textContent=Pe,_e=c(),Z=l("button"),Z.innerHTML=Ve,ve=c(),$=l("button"),$.innerHTML=je,we=c(),ee=l("button"),ee.innerHTML=De,Te=c(),te=l("button"),te.innerHTML=Fe,ye=c(),ne=l("button"),ne.innerHTML=ze,Ce=c(),se=l("button"),se.innerHTML=Re,ke=c(),de=l("div"),de.textContent=qe,Le=c(),ae=l("button"),ae.innerHTML=Ge,He=c(),le=l("button"),le.innerHTML=Je,Me=c(),oe=l("button"),oe.innerHTML=Ke,Ie=c(),re=l("button"),re.innerHTML=We,Ne=c(),ie=l("button"),ie.innerHTML=Ye,Ee=c(),ue=l("main"),$e(ce.$$.fragment),Se=c(),P&&P.c(),Be=c(),M&&M.c(),this.h()},l(m){o=a(m,"DIV",{class:!0});var C=j(o);n=a(C,"ASIDE",{class:!0});var J=j(n);p=a(J,"DIV",{class:!0,"data-svelte-h":!0}),d(p)!=="svelte-xzbt87"&&(p.innerHTML=L),R=u(J),e=a(J,"NAV",{class:!0});var r=j(e);x=a(r,"DIV",{class:!0,"data-svelte-h":!0}),d(x)!=="svelte-52jqai"&&(x.textContent=A),D=u(r),h=a(r,"A",{href:!0,class:!0});var he=j(h);T=a(he,"SPAN",{"data-svelte-h":!0}),d(T)!=="svelte-1yx42xi"&&(T.textContent=Q),F=u(he),_=a(he,"SPAN",{"data-svelte-h":!0}),d(_)!=="svelte-2j89jk"&&(_.textContent=O),he.forEach(I),K=u(r),b=a(r,"A",{href:!0,class:!0});var me=j(b);Ze(S.$$.fragment,me),W=u(me),k=a(me,"SPAN",{"data-svelte-h":!0}),d(k)!=="svelte-10pmll2"&&(k.textContent=i),me.forEach(I),H=u(r),g=a(r,"BUTTON",{class:!0,"data-svelte-h":!0}),d(g)!=="svelte-wf0x5d"&&(g.innerHTML=z),B=u(r),U=a(r,"BUTTON",{class:!0,"data-svelte-h":!0}),d(U)!=="svelte-x7bha3"&&(U.innerHTML=y),w=u(r),v=a(r,"BUTTON",{class:!0,"data-svelte-h":!0}),d(v)!=="svelte-1tyblmt"&&(v.innerHTML=G),V=u(r),E=a(r,"BUTTON",{class:!0,"data-svelte-h":!0}),d(E)!=="svelte-1emrjb3"&&(E.innerHTML=Y),X=u(r),fe=a(r,"DIV",{class:!0,"data-svelte-h":!0}),d(fe)!=="svelte-1pmjg3x"&&(fe.textContent=Pe),_e=u(r),Z=a(r,"BUTTON",{class:!0,"data-svelte-h":!0}),d(Z)!=="svelte-11wbuiv"&&(Z.innerHTML=Ve),ve=u(r),$=a(r,"BUTTON",{class:!0,"data-svelte-h":!0}),d($)!=="svelte-ol2yvl"&&($.innerHTML=je),we=u(r),ee=a(r,"BUTTON",{class:!0,"data-svelte-h":!0}),d(ee)!=="svelte-ttigif"&&(ee.innerHTML=De),Te=u(r),te=a(r,"BUTTON",{class:!0,"data-svelte-h":!0}),d(te)!=="svelte-ixgtu4"&&(te.innerHTML=Fe),ye=u(r),ne=a(r,"BUTTON",{class:!0,"data-svelte-h":!0}),d(ne)!=="svelte-r2ax5z"&&(ne.innerHTML=ze),Ce=u(r),se=a(r,"BUTTON",{class:!0,"data-svelte-h":!0}),d(se)!=="svelte-n9rt3x"&&(se.innerHTML=Re),ke=u(r),de=a(r,"DIV",{class:!0,"data-svelte-h":!0}),d(de)!=="svelte-1gfxetb"&&(de.textContent=qe),Le=u(r),ae=a(r,"BUTTON",{class:!0,"data-svelte-h":!0}),d(ae)!=="svelte-gox1rd"&&(ae.innerHTML=Ge),He=u(r),le=a(r,"BUTTON",{class:!0,"data-svelte-h":!0}),d(le)!=="svelte-13pimzy"&&(le.innerHTML=Je),Me=u(r),oe=a(r,"BUTTON",{class:!0,"data-svelte-h":!0}),d(oe)!=="svelte-c86wph"&&(oe.innerHTML=Ke),Ie=u(r),re=a(r,"BUTTON",{class:!0,"data-svelte-h":!0}),d(re)!=="svelte-wkify0"&&(re.innerHTML=We),Ne=u(r),ie=a(r,"BUTTON",{class:!0,"data-svelte-h":!0}),d(ie)!=="svelte-10ou061"&&(ie.innerHTML=Ye),r.forEach(I),J.forEach(I),Ee=u(C),ue=a(C,"MAIN",{class:!0});var ge=j(ue);Ze(ce.$$.fragment,ge),Se=u(ge),P&&P.l(ge),ge.forEach(I),Be=u(C),M&&M.l(C),C.forEach(I),this.h()},h(){s(p,"class","px-4 py-4 border-b border-gray-200 min-h-[73px] flex items-center"),s(x,"class","mt-2 mb-1 px-2 text-xs font-medium text-gray-500 uppercase"),s(h,"href","/"),s(h,"class",q="w-full flex items-center gap-2 px-2 py-1.5 rounded-md hover:bg-gray-100 transition-colors text-left "+(f[7].url.pathname==="/"?"bg-gray-100":"")),s(b,"href","/voice-cloning"),s(b,"class",N="w-full flex items-center gap-2 px-2 py-1.5 rounded-md hover:bg-gray-100 transition-colors text-left "+(f[7].url.pathname==="/voice-cloning"?"bg-gray-100":"")),s(g,"class","w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"),g.disabled=!0,s(U,"class","w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"),U.disabled=!0,s(v,"class","w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"),v.disabled=!0,s(E,"class","w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"),E.disabled=!0,s(fe,"class","mt-4 mb-1 px-2 text-xs font-medium text-gray-500 uppercase"),s(Z,"class","w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"),Z.disabled=!0,s($,"class","w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"),$.disabled=!0,s(ee,"class","w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"),ee.disabled=!0,s(te,"class","w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"),te.disabled=!0,s(ne,"class","w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"),ne.disabled=!0,s(se,"class","w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"),se.disabled=!0,s(de,"class","mt-4 mb-1 px-2 text-xs font-medium text-gray-500 uppercase"),s(ae,"class","w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"),ae.disabled=!0,s(le,"class","w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"),le.disabled=!0,s(oe,"class","w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"),oe.disabled=!0,s(re,"class","w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"),re.disabled=!0,s(ie,"class","w-full flex items-center gap-2 px-2 py-1.5 rounded-md text-left opacity-40 cursor-not-allowed"),ie.disabled=!0,s(e,"class","p-2 text-sm flex-1"),s(n,"class","w-56 border-r border-gray-200 bg-white flex-shrink-0 flex flex-col h-full relative "),s(ue,"class","flex-1 overflow-auto"),s(o,"class","flex h-screen bg-white")},m(m,C){be(m,o,C),t(o,n),t(n,p),t(n,R),t(n,e),t(e,x),t(e,D),t(e,h),t(h,T),t(h,F),t(h,_),t(e,K),t(e,b),Xe(S,b,null),t(b,W),t(b,k),t(e,H),t(e,g),t(e,B),t(e,U),t(e,w),t(e,v),t(e,V),t(e,E),t(e,X),t(e,fe),t(e,_e),t(e,Z),t(e,ve),t(e,$),t(e,we),t(e,ee),t(e,Te),t(e,te),t(e,ye),t(e,ne),t(e,Ce),t(e,se),t(e,ke),t(e,de),t(e,Le),t(e,ae),t(e,He),t(e,le),t(e,Me),t(e,oe),t(e,Ie),t(e,re),t(e,Ne),t(e,ie),t(o,Ee),t(o,ue),Xe(ce,ue,null),t(ue,Se),P&&P.m(ue,null),t(o,Be),M&&M.m(o,null),pe=!0},p(m,[C]){(!pe||C&128&&q!==(q="w-full flex items-center gap-2 px-2 py-1.5 rounded-md hover:bg-gray-100 transition-colors text-left "+(m[7].url.pathname==="/"?"bg-gray-100":"")))&&s(h,"class",q),(!pe||C&128&&N!==(N="w-full flex items-center gap-2 px-2 py-1.5 rounded-md hover:bg-gray-100 transition-colors text-left "+(m[7].url.pathname==="/voice-cloning"?"bg-gray-100":"")))&&s(b,"class",N);const J={};C&1&&(J.isLoggedIn=m[0]),C&2&&(J.username=m[1]),C&64&&(J.flashButton=m[6]),C&128&&(J.pageTitle=at(m[7].url.pathname)),ce.$set(J),P&&P.p&&(!pe||C&2048)&&ut(P,Ae,m,m[11],pe?pt(Ae,m[11],C,null):ct(m[11]),null),m[2]?M?M.p(m,C):(M=tt(m),M.c(),M.m(o,null)):M&&(M.d(1),M=null)},i(m){pe||(Ue(S.$$.fragment,m),Ue(ce.$$.fragment,m),Ue(P,m),pe=!0)},o(m){Oe(S.$$.fragment,m),Oe(ce.$$.fragment,m),Oe(P,m),pe=!1},d(m){m&&I(o),Qe(S),Qe(ce),P&&P.d(m),M&&M.d()}}}function at(f){switch(f){case"/":return"Text to Speech";case"/voice-cloning":return"Voice Cloning";default:return"HFStudio"}}function Tt(f,o,n){let p;ft(f,bt,i=>n(7,p=i));let{$$slots:L={},$$scope:R}=o,e=typeof window<"u"&&window.__INITIAL_USER__?window.__INITIAL_USER__:{authenticated:!1},x=(e==null?void 0:e.authenticated)||!1,A=e!=null&&e.authenticated&&(e!=null&&e.user_info)?(e.user_info.name||e.user_info.fullname||e.user_info.login||e.user_info.username||"User").split(" ")[0]:"",D=!1,h="",T="",Q=!1,F=!1,_=!1;dt(()=>(window.addEventListener("show-login-prompt",()=>{x||(n(6,F=!0),setTimeout(()=>{n(6,F=!1)},1600))}),O().then(()=>{e!=null&&e.authenticated||q()}),document.addEventListener("visibilitychange",()=>{document.hidden||q()}),()=>{}));async function O(){try{_=(await(await fetch("/api/status")).json()).is_spaces||!1}catch(i){console.error("Error checking Spaces status:",i),_=!1}}async function q(){if(!(e!=null&&e.authenticated&&x))try{const i=await fetch("/api/auth/user",{credentials:"include"});if(i.ok){const N=await i.json();if(N.authenticated){n(0,x=!0);const H=N.user_info,g=H.name||H.fullname||H.login||H.username||"User";n(1,A=g.split(" ")[0])}else n(0,x=!1),n(1,A="")}else n(0,x=!1),n(1,A="")}catch{n(0,x=!1),n(1,A="")}}async function K(){if(x){try{await fetch("/api/auth/logout",{method:"POST",credentials:"include"})}catch(i){console.error("Logout error:",i)}sessionStorage.removeItem("oauth_state"),n(0,x=!1),n(1,A=""),window.location.reload()}else try{const N=await(await fetch("/api/auth/oauth-config")).json(),H=N.scopes||"inference-api";let g=window.location.origin+"/auth/callback";window.location.hostname==="localhost"&&window.location.port==="11111"&&(g="http://localhost:7860/auth/callback");const z=window.location.pathname,B=`https://huggingface.co/oauth/authorize?client_id=${N.client_id}&redirect_uri=${encodeURIComponent(g)}&scope=${encodeURIComponent(H)}&response_type=code&state=${encodeURIComponent(z)}`;window.location.href=B}catch{n(2,D=!0),n(3,h=""),n(4,T="")}}function b(){n(2,D=!1),n(3,h=""),n(4,T="")}async function S(){if(!h.trim()){n(4,T="Please enter a token");return}if(!h.startsWith("hf_")){n(4,T='Token should start with "hf_"');return}try{const i=await fetch("https://huggingface.co/api/whoami-v2",{headers:{Authorization:`Bearer ${h.trim()}`}});if(i.ok){const N=await i.json(),H=h.trim();try{const g=await fetch("/api/auth/manual-token",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({token:H})});if(g.ok){const z=await g.json();n(0,x=!0);const B=z.user_info,U=B.name||B.fullname||B.login||B.username||"User";n(1,A=U.split(" ")[0]),b()}else{const z=await g.json();n(4,T=z.detail||"Token validation failed")}}catch{n(4,T="Failed to validate token. Please try again.")}}else n(4,T=`Invalid token (${i.status}). Please check your token and try again.`)}catch{n(4,T="Error validating token. Please try again.")}}function W(){h=this.value,n(3,h)}const k=i=>i.key==="Enter"&&S();return f.$$set=i=>{"$$scope"in i&&n(11,R=i.$$scope)},[x,A,D,h,T,Q,F,p,K,b,S,R,L,W,k]}class Mt extends lt{constructor(o){super(),ot(this,o,Tt,wt,rt,{})}}export{Mt as component};
hfstudio/static/_app/immutable/nodes/1.C7ooe2uD.js ADDED
@@ -0,0 +1 @@
 
 
1
+ import{S as x,i as S,s as j,n as u,d as c,a as h,b as _,c as d,e as v,f as g,g as b,h as k,j as E,t as $,k as q,l as y}from"../chunks/BaOlNwUz.js";import"../chunks/IHki7fMi.js";import{p as C}from"../chunks/QsMRfqzH.js";function H(p){var f;let a,s=p[0].status+"",r,n,o,i=((f=p[0].error)==null?void 0:f.message)+"",m;return{c(){a=E("h1"),r=$(s),n=q(),o=E("p"),m=$(i)},l(e){a=v(e,"H1",{});var t=g(a);r=b(t,s),t.forEach(c),n=k(e),o=v(e,"P",{});var l=g(o);m=b(l,i),l.forEach(c)},m(e,t){_(e,a,t),d(a,r),_(e,n,t),_(e,o,t),d(o,m)},p(e,[t]){var l;t&1&&s!==(s=e[0].status+"")&&h(r,s),t&1&&i!==(i=((l=e[0].error)==null?void 0:l.message)+"")&&h(m,i)},i:u,o:u,d(e){e&&(c(a),c(n),c(o))}}}function P(p,a,s){let r;return y(p,C,n=>s(0,r=n)),[r]}class B extends x{constructor(a){super(),S(this,a,P,H,j,{})}}export{B as component};
hfstudio/static/_app/immutable/nodes/2.DEDaBsJG.js ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import{S as bs,i as vs,s as zl,u as dr,v as ce,w as I,x as C,y as ue,z as fe,A as de,B as Zr,C as ws,D as ks,E as xs,F as Es,d as c,M as ys,G as _l,a as Ye,O as ul,p as a,H as ht,b as j,c as n,m as L,I as Ts,h as _,e as u,f as p,g as M,r as q,J as At,k as b,j as f,t as H,K as Cs,N as mt,n as jt,P as hr,Q as mr,L as pr,R as es,T as $s,q as ts}from"../chunks/BaOlNwUz.js";import{C as fr,g as Is,P as Ht,D as Ds}from"../chunks/Dj_MM6zE.js";import{I as Vs,g as Ps,a as Ls,e as Ul}from"../chunks/C7BncMoR.js";import"../chunks/IHki7fMi.js";import{S as Ns,L as Ms,A as Hs,X as js}from"../chunks/BV8rDFhh.js";import{P as Bl,a as dl}from"../chunks/Bm0csYZC.js";function As(s){let e;const t=s[2].default,l=ws(t,s,s[3],null);return{c(){l&&l.c()},l(r){l&&l.l(r)},m(r,o){l&&l.m(r,o),e=!0},p(r,o){l&&l.p&&(!e||o&8)&&ks(l,t,r,r[3],e?Es(t,r[3],o,null):xs(r[3]),null)},i(r){e||(C(l,r),e=!0)},o(r){I(l,r),e=!1},d(r){l&&l.d(r)}}}function Os(s){let e,t;const l=[{name:"chevron-down"},s[1],{iconNode:s[0]}];let r={$$slots:{default:[As]},$$scope:{ctx:s}};for(let o=0;o<l.length;o+=1)r=dr(r,l[o]);return e=new Vs({props:r}),{c(){de(e.$$.fragment)},l(o){fe(e.$$.fragment,o)},m(o,i){ue(e,o,i),t=!0},p(o,[i]){const h=i&3?Ps(l,[l[0],i&2&&Ls(o[1]),i&1&&{iconNode:o[0]}]):{};i&8&&(h.$$scope={dirty:i,ctx:o}),e.$set(h)},i(o){t||(C(e.$$.fragment,o),t=!0)},o(o){I(e.$$.fragment,o),t=!1},d(o){ce(e,o)}}}function Ss(s,e,t){let{$$slots:l={},$$scope:r}=e;const o=[["path",{d:"m6 9 6 6 6-6"}]];return s.$$set=i=>{t(1,e=dr(dr({},e),Zr(i))),"$$scope"in i&&t(3,r=i.$$scope)},e=Zr(e),[o,e,l,r]}class zs extends bs{constructor(e){super(),vs(this,e,Ss,Os,zl,{})}}const{document:ls}=Is;function rs(s,e,t){const l=s.slice();return l[74]=e[t],l}function ss(s,e,t){const l=s.slice();return l[74]=e[t],l}function ns(s){let e=s[74].name+"",t,l,r=s[74].badge&&Us(s);return{c(){t=H(e),r&&r.c(),l=At()},l(o){t=M(o,e),r&&r.l(o),l=At()},m(o,i){j(o,t,i),r&&r.m(o,i),j(o,l,i)},p(o,i){o[74].badge&&r.p(o,i)},d(o){o&&(c(t),c(l)),r&&r.d(o)}}}function Us(s){let e,t,l,r=s[74].badge+"",o,i;return{c(){e=H(" "),t=f("span"),l=H("("),o=H(r),i=H(")"),this.h()},l(h){e=M(h," "),t=u(h,"SPAN",{class:!0});var m=p(t);l=M(m,"("),o=M(m,r),i=M(m,")"),m.forEach(c),this.h()},h(){a(t,"class","text-sm text-gray-500")},m(h,m){j(h,e,m),j(h,t,m),n(t,l),n(t,o),n(t,i)},p:jt,d(h){h&&(c(e),c(t))}}}function as(s){let e,t=s[74].name===s[2]&&ns(s);return{c(){t&&t.c(),e=At()},l(l){t&&t.l(l),e=At()},m(l,r){t&&t.m(l,r),j(l,e,r)},p(l,r){l[74].name===l[2]?t?t.p(l,r):(t=ns(l),t.c(),t.m(e.parentNode,e)):t&&(t.d(1),t=null)},d(l){l&&c(e),t&&t.d(l)}}}function os(s){let e,t=Ul(s[25]),l=[];for(let r=0;r<t.length;r+=1)l[r]=is(rs(s,t,r));return{c(){e=f("div");for(let r=0;r<l.length;r+=1)l[r].c();this.h()},l(r){e=u(r,"DIV",{class:!0});var o=p(e);for(let i=0;i<l.length;i+=1)l[i].l(o);o.forEach(c),this.h()},h(){a(e,"class","absolute bottom-full left-0 right-0 border border-gray-200 border-b-0 bg-white shadow-lg rounded-t-lg overflow-hidden z-20")},m(r,o){j(r,e,o);for(let i=0;i<l.length;i+=1)l[i]&&l[i].m(e,null)},p(r,o){if(o[0]&33554692){t=Ul(r[25]);let i;for(i=0;i<t.length;i+=1){const h=rs(r,t,i);l[i]?l[i].p(h,o):(l[i]=is(h),l[i].c(),l[i].m(e,null))}for(;i<l.length;i+=1)l[i].d(1);l.length=t.length}},d(r){r&&c(e),ys(l,r)}}}function Bs(s){let e,t,l,r=s[74].badge+"",o,i;return{c(){e=H(" "),t=f("span"),l=H("("),o=H(r),i=H(")"),this.h()},l(h){e=M(h," "),t=u(h,"SPAN",{class:!0});var m=p(t);l=M(m,"("),o=M(m,r),i=M(m,")"),m.forEach(c),this.h()},h(){a(t,"class","text-sm text-gray-500")},m(h,m){j(h,e,m),j(h,t,m),n(t,l),n(t,o),n(t,i)},p:jt,d(h){h&&(c(e),c(t))}}}function is(s){let e,t=s[74].name+"",l,r,o,i,h,m=s[74].badge&&Bs(s);function $(){return s[42](s[74])}return{c(){e=f("button"),l=H(t),m&&m.c(),r=b(),this.h()},l(y){e=u(y,"BUTTON",{class:!0});var v=p(e);l=M(v,t),m&&m.l(v),r=_(v),v.forEach(c),this.h()},h(){a(e,"class",o="w-full px-3 py-2.5 text-left transition-colors text-sm "+(s[74].disabled?"opacity-50 cursor-not-allowed":"hover:bg-gray-50")+" "+(s[74].name===s[2]?"bg-gray-100":"")),e.disabled=s[74].disabled},m(y,v){j(y,e,v),n(e,l),m&&m.m(e,null),n(e,r),i||(h=L(e,"click",$),i=!0)},p(y,v){s=y,s[74].badge&&m.p(s,v),v[0]&4&&o!==(o="w-full px-3 py-2.5 text-left transition-colors text-sm "+(s[74].disabled?"opacity-50 cursor-not-allowed":"hover:bg-gray-50")+" "+(s[74].name===s[2]?"bg-gray-100":""))&&a(e,"class",o)},d(y){y&&c(e),m&&m.d(),i=!1,h()}}}function Fs(s){let e,t;return e=new dl({props:{size:10,class:"text-gray-600"}}),{c(){de(e.$$.fragment)},l(l){fe(e.$$.fragment,l)},m(l,r){ue(e,l,r),t=!0},i(l){t||(C(e.$$.fragment,l),t=!0)},o(l){I(e.$$.fragment,l),t=!1},d(l){ce(e,l)}}}function Rs(s){let e,t;return e=new Bl({props:{size:10,class:"text-gray-600"}}),{c(){de(e.$$.fragment)},l(l){fe(e.$$.fragment,l)},m(l,r){ue(e,l,r),t=!0},i(l){t||(C(e.$$.fragment,l),t=!0)},o(l){I(e.$$.fragment,l),t=!1},d(l){ce(e,l)}}}function Gs(s){let e,t;return e=new dl({props:{size:10,class:"text-gray-600"}}),{c(){de(e.$$.fragment)},l(l){fe(e.$$.fragment,l)},m(l,r){ue(e,l,r),t=!0},i(l){t||(C(e.$$.fragment,l),t=!0)},o(l){I(e.$$.fragment,l),t=!1},d(l){ce(e,l)}}}function qs(s){let e,t;return e=new Bl({props:{size:10,class:"text-gray-600"}}),{c(){de(e.$$.fragment)},l(l){fe(e.$$.fragment,l)},m(l,r){ue(e,l,r),t=!0},i(l){t||(C(e.$$.fragment,l),t=!0)},o(l){I(e.$$.fragment,l),t=!1},d(l){ce(e,l)}}}function Ys(s){let e,t;return e=new dl({props:{size:10,class:"text-gray-600"}}),{c(){de(e.$$.fragment)},l(l){fe(e.$$.fragment,l)},m(l,r){ue(e,l,r),t=!0},i(l){t||(C(e.$$.fragment,l),t=!0)},o(l){I(e.$$.fragment,l),t=!1},d(l){ce(e,l)}}}function Ks(s){let e,t;return e=new Bl({props:{size:10,class:"text-gray-600"}}),{c(){de(e.$$.fragment)},l(l){fe(e.$$.fragment,l)},m(l,r){ue(e,l,r),t=!0},i(l){t||(C(e.$$.fragment,l),t=!0)},o(l){I(e.$$.fragment,l),t=!1},d(l){ce(e,l)}}}function Js(s){let e,t='<div class="flex items-center justify-between mb-1"><div class="flex items-center gap-2"><div class="w-6 h-6 bg-gradient-to-br from-purple-400 to-pink-500 rounded-full flex items-center justify-center text-white text-xs font-semibold">🎤</div> <span class="text-sm font-medium text-purple-900">Clone</span></div> <div class="w-5 h-5 flex items-center justify-center"><svg class="w-3 h-3 text-purple-600" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg></div></div>';return{c(){e=f("a"),e.innerHTML=t,this.h()},l(l){e=u(l,"A",{href:!0,class:!0,"data-svelte-h":!0}),q(e)!=="svelte-mxzea4"&&(e.innerHTML=t),this.h()},h(){a(e,"href","/voice-cloning"),a(e,"class","p-3 border border-purple-200 rounded-lg transition-colors text-left hover:bg-purple-50 bg-purple-25")},m(l,r){j(l,e,r)},p:jt,i:jt,o:jt,d(l){l&&c(e)}}}function Xs(s){let e,t,l,r='<div class="w-6 h-6 bg-gradient-to-br from-purple-400 to-pink-500 rounded-full flex items-center justify-center text-white text-xs">🎤</div> <span class="text-sm font-medium">Yours</span>',o,i,h,m,$,y,v,x;const A=[Ws,Qs],J=[];function D(E,T){return E[17]==="Yours"?0:1}return h=D(s),m=J[h]=A[h](s),{c(){e=f("button"),t=f("div"),l=f("div"),l.innerHTML=r,o=b(),i=f("button"),m.c(),this.h()},l(E){e=u(E,"BUTTON",{class:!0});var T=p(e);t=u(T,"DIV",{class:!0});var w=p(t);l=u(w,"DIV",{class:!0,"data-svelte-h":!0}),q(l)!=="svelte-uwm948"&&(l.innerHTML=r),o=_(w),i=u(w,"BUTTON",{class:!0,title:!0});var U=p(i);m.l(U),U.forEach(c),w.forEach(c),T.forEach(c),this.h()},h(){a(l,"class","flex items-center gap-2"),a(i,"class","p-1 rounded-full hover:bg-gray-200 transition-colors w-5 h-5 flex items-center justify-center"),a(i,"title","Play sample"),a(t,"class","flex items-center justify-between mb-1"),a(e,"class",$="p-3 border rounded-lg transition-colors text-left hover:bg-gray-50 "+(s[1]==="Yours"?"border-purple-400 bg-purple-50":"border-gray-200"))},m(E,T){j(E,e,T),n(e,t),n(t,l),n(t,o),n(t,i),J[h].m(i,null),y=!0,v||(x=[L(i,"click",s[49]),L(e,"click",s[50])],v=!0)},p(E,T){let w=h;h=D(E),h!==w&&(mt(),I(J[w],1,1,()=>{J[w]=null}),ht(),m=J[h],m||(m=J[h]=A[h](E),m.c()),C(m,1),m.m(i,null)),(!y||T[0]&2&&$!==($="p-3 border rounded-lg transition-colors text-left hover:bg-gray-50 "+(E[1]==="Yours"?"border-purple-400 bg-purple-50":"border-gray-200")))&&a(e,"class",$)},i(E){y||(C(m),y=!0)},o(E){I(m),y=!1},d(E){E&&c(e),J[h].d(),v=!1,_l(x)}}}function Qs(s){let e,t;return e=new dl({props:{size:10,class:"text-gray-600"}}),{c(){de(e.$$.fragment)},l(l){fe(e.$$.fragment,l)},m(l,r){ue(e,l,r),t=!0},i(l){t||(C(e.$$.fragment,l),t=!0)},o(l){I(e.$$.fragment,l),t=!1},d(l){ce(e,l)}}}function Ws(s){let e,t;return e=new Bl({props:{size:10,class:"text-gray-600"}}),{c(){de(e.$$.fragment)},l(l){fe(e.$$.fragment,l)},m(l,r){ue(e,l,r),t=!0},i(l){t||(C(e.$$.fragment,l),t=!0)},o(l){I(e.$$.fragment,l),t=!1},d(l){ce(e,l)}}}function Zs(s){let e,t,l;return e=new dl({props:{size:20}}),{c(){de(e.$$.fragment),t=H(`
2
+ Generate speech`)},l(r){fe(e.$$.fragment,r),t=M(r,`
3
+ Generate speech`)},m(r,o){ue(e,r,o),j(r,t,o),l=!0},i(r){l||(C(e.$$.fragment,r),l=!0)},o(r){I(e.$$.fragment,r),l=!1},d(r){r&&c(t),ce(e,r)}}}function en(s){let e,t,l;return e=new Ms({props:{size:20,class:"animate-spin"}}),{c(){de(e.$$.fragment),t=H(`
4
+ Generating...`)},l(r){fe(e.$$.fragment,r),t=M(r,`
5
+ Generating...`)},m(r,o){ue(e,r,o),j(r,t,o),l=!0},i(r){l||(C(e.$$.fragment,r),l=!0)},o(r){I(e.$$.fragment,r),l=!1},d(r){r&&c(t),ce(e,r)}}}function cs(s){let e,t,l='<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>',r,o,i='Hugging Face <span class="bg-gradient-to-r from-purple-500 via-pink-500 via-green-500 to-blue-500 bg-clip-text text-transparent font-bold">PRO</span>',h,m,$=`Sign in to with your Hugging Face <a href="https://huggingface.co/pro" target="_blank" class="text-amber-600 hover:text-amber-700 underline font-medium">PRO account</a> to get started with $2 of free API credits per month. You can add a billing method for
6
+ additional pay-as-you-go usage ⤴`,y,v;return{c(){e=f("div"),t=f("button"),t.innerHTML=l,r=b(),o=f("p"),o.innerHTML=i,h=b(),m=f("p"),m.innerHTML=$,this.h()},l(x){e=u(x,"DIV",{class:!0});var A=p(e);t=u(A,"BUTTON",{class:!0,"aria-label":!0,"data-svelte-h":!0}),q(t)!=="svelte-9gdgq5"&&(t.innerHTML=l),r=_(A),o=u(A,"P",{class:!0,"data-svelte-h":!0}),q(o)!=="svelte-1q58z3k"&&(o.innerHTML=i),h=_(A),m=u(A,"P",{class:!0,"data-svelte-h":!0}),q(m)!=="svelte-dysk74"&&(m.innerHTML=$),A.forEach(c),this.h()},h(){a(t,"class","absolute top-2 right-2 text-gray-400 hover:text-gray-600 transition-colors"),a(t,"aria-label","Dismiss"),a(o,"class","text-sm font-medium text-gray-700 mb-1 pr-4"),a(m,"class","text-sm text-gray-600 pr-4"),a(e,"class","mb-4 px-3 py-2 bg-gradient-to-r from-amber-50 to-orange-50 rounded-lg border border-amber-200 relative")},m(x,A){j(x,e,A),n(e,t),n(e,r),n(e,o),n(e,h),n(e,m),y||(v=L(t,"click",s[53]),y=!0)},p:jt,d(x){x&&c(e),y=!1,v()}}}function us(s){let e,t,l,r=Ht.highlight(s[23],Ht.languages.bash,"bash")+"";return{c(){e=f("pre"),t=f("code"),l=new mr(!1),this.h()},l(o){e=u(o,"PRE",{class:!0});var i=p(e);t=u(i,"CODE",{class:!0});var h=p(t);l=hr(h,!1),h.forEach(c),i.forEach(c),this.h()},h(){l.a=null,a(t,"class","language-bash"),a(e,"class","p-3 overflow-x-auto bg-gray-50 text-xs")},m(o,i){j(o,e,i),n(e,t),l.m(r,t)},p(o,i){i[0]&8388608&&r!==(r=Ht.highlight(o[23],Ht.languages.bash,"bash")+"")&&l.p(r)},d(o){o&&c(e)}}}function fs(s){let e,t,l,r=Ht.highlight(s[24],Ht.languages.python,"python")+"";return{c(){e=f("pre"),t=f("code"),l=new mr(!1),this.h()},l(o){e=u(o,"PRE",{class:!0});var i=p(e);t=u(i,"CODE",{class:!0});var h=p(t);l=hr(h,!1),h.forEach(c),i.forEach(c),this.h()},h(){l.a=null,a(t,"class","language-python"),a(e,"class","p-3 overflow-x-auto bg-gray-50 text-xs")},m(o,i){j(o,e,i),n(e,t),l.m(r,t)},p(o,i){i[0]&16777216&&r!==(r=Ht.highlight(o[24],Ht.languages.python,"python")+"")&&l.p(r)},d(o){o&&c(e)}}}function ds(s){let e,t,l,r,o,i,h="Generated Audio",m,$,y,v,x,A="Download",J,D,E,T,w,U,Y,pe,_e,O,Z,he=fl(s[14])+"",S,V,z,F,G,B,Oe,ee,se,me=fl(s[13])+"",Be,Fe,X,be,Pe,xe,Le=fl(s[14])+"",We,Ie,R,ye,at,Q=s[11]>0&&s[6]!=="local"&&ps(s);D=new Ds({props:{size:12,class:"text-green-600"}});const Ne=[ln,tn],ve=[];function Re(P,N){return P[12]?0:1}G=Re(s),B=ve[G]=Ne[G](s);let te=s[10]&&hs(s);return{c(){e=f("div"),t=f("div"),l=f("div"),r=f("div"),o=b(),i=f("span"),i.textContent=h,m=b(),Q&&Q.c(),$=b(),y=f("div"),v=f("button"),x=f("span"),x.textContent=A,J=b(),de(D.$$.fragment),E=b(),T=f("div"),w=f("div"),U=f("h4"),Y=H(s[15]),pe=b(),_e=f("p"),O=H(s[1]),Z=H(" • "),S=H(he),V=b(),z=f("div"),F=f("button"),B.c(),Oe=b(),ee=f("div"),se=f("span"),Be=H(me),Fe=b(),X=f("div"),be=f("div"),Pe=b(),xe=f("span"),We=H(Le),Ie=b(),te&&te.c(),this.h()},l(P){e=u(P,"DIV",{class:!0});var N=p(e);t=u(N,"DIV",{class:!0});var W=p(t);l=u(W,"DIV",{class:!0});var ne=p(l);r=u(ne,"DIV",{class:!0}),p(r).forEach(c),o=_(ne),i=u(ne,"SPAN",{class:!0,"data-svelte-h":!0}),q(i)!=="svelte-1hz7jl7"&&(i.textContent=h),m=_(ne),Q&&Q.l(ne),ne.forEach(c),$=_(W),y=u(W,"DIV",{class:!0});var ot=p(y);v=u(ot,"BUTTON",{class:!0,title:!0});var Ze=p(v);x=u(Ze,"SPAN",{class:!0,"data-svelte-h":!0}),q(x)!=="svelte-kkuif9"&&(x.textContent=A),J=_(Ze),fe(D.$$.fragment,Ze),Ze.forEach(c),ot.forEach(c),W.forEach(c),E=_(N),T=u(N,"DIV",{class:!0});var we=p(T);w=u(we,"DIV",{class:!0});var De=p(w);U=u(De,"H4",{class:!0});var Ge=p(U);Y=M(Ge,s[15]),Ge.forEach(c),pe=_(De),_e=u(De,"P",{class:!0});var it=p(_e);O=M(it,s[1]),Z=M(it," • "),S=M(it,he),it.forEach(c),De.forEach(c),V=_(we),z=u(we,"DIV",{class:!0});var et=p(z);F=u(et,"BUTTON",{class:!0});var Me=p(F);B.l(Me),Me.forEach(c),Oe=_(et),ee=u(et,"DIV",{class:!0});var ae=p(ee);se=u(ae,"SPAN",{class:!0});var Ee=p(se);Be=M(Ee,me),Ee.forEach(c),Fe=_(ae),X=u(ae,"DIV",{class:!0});var ct=p(X);be=u(ct,"DIV",{class:!0,style:!0}),p(be).forEach(c),ct.forEach(c),Pe=_(ae),xe=u(ae,"SPAN",{class:!0});var gt=p(xe);We=M(gt,Le),gt.forEach(c),ae.forEach(c),et.forEach(c),Ie=_(we),te&&te.l(we),we.forEach(c),N.forEach(c),this.h()},h(){a(r,"class","w-1.5 h-1.5 bg-green-500 rounded-full"),a(i,"class","text-xs font-medium text-green-900"),a(l,"class","flex items-center gap-2"),a(x,"class","text-xs text-green-700"),a(v,"class","flex items-center gap-1 px-2 py-1 hover:bg-green-100 rounded transition-colors"),a(v,"title","Download audio"),a(y,"class","flex items-center gap-1"),a(t,"class","flex items-center justify-between px-3 py-2 bg-green-50 border-b border-green-200"),a(U,"class","font-medium text-gray-900 text-xs"),a(_e,"class","text-xs text-gray-500"),a(w,"class","mb-3"),a(F,"class","w-6 h-6 bg-black rounded-full flex items-center justify-center hover:bg-gray-800 transition-colors flex-shrink-0"),a(se,"class","text-xs text-gray-500 font-mono"),a(be,"class","h-full bg-gradient-to-r from-amber-400 to-orange-500 rounded-full transition-all"),pr(be,"width",s[13]/s[14]*100+"%"),a(X,"class","flex-1 h-1 bg-gray-200 rounded-full cursor-pointer"),a(xe,"class","text-xs text-gray-500 font-mono"),a(ee,"class","flex-1 flex items-center gap-1"),a(z,"class","flex items-center gap-2"),a(T,"class","p-3"),a(e,"class","bg-white rounded-lg border border-gray-200 overflow-hidden mt-4")},m(P,N){j(P,e,N),n(e,t),n(t,l),n(l,r),n(l,o),n(l,i),n(l,m),Q&&Q.m(l,null),n(t,$),n(t,y),n(y,v),n(v,x),n(v,J),ue(D,v,null),n(e,E),n(e,T),n(T,w),n(w,U),n(U,Y),n(w,pe),n(w,_e),n(_e,O),n(_e,Z),n(_e,S),n(T,V),n(T,z),n(z,F),ve[G].m(F,null),n(z,Oe),n(z,ee),n(ee,se),n(se,Be),n(ee,Fe),n(ee,X),n(X,be),n(ee,Pe),n(ee,xe),n(xe,We),n(T,Ie),te&&te.m(T,null),R=!0,ye||(at=[L(v,"click",s[32]),L(F,"click",s[27])],ye=!0)},p(P,N){P[11]>0&&P[6]!=="local"?Q?Q.p(P,N):(Q=ps(P),Q.c(),Q.m(l,null)):Q&&(Q.d(1),Q=null),(!R||N[0]&32768)&&Ye(Y,P[15]),(!R||N[0]&2)&&Ye(O,P[1]),(!R||N[0]&16384)&&he!==(he=fl(P[14])+"")&&Ye(S,he);let W=G;G=Re(P),G!==W&&(mt(),I(ve[W],1,1,()=>{ve[W]=null}),ht(),B=ve[G],B||(B=ve[G]=Ne[G](P),B.c()),C(B,1),B.m(F,null)),(!R||N[0]&8192)&&me!==(me=fl(P[13])+"")&&Ye(Be,me),(!R||N[0]&24576)&&pr(be,"width",P[13]/P[14]*100+"%"),(!R||N[0]&16384)&&Le!==(Le=fl(P[14])+"")&&Ye(We,Le),P[10]?te?te.p(P,N):(te=hs(P),te.c(),te.m(T,null)):te&&(te.d(1),te=null)},i(P){R||(C(D.$$.fragment,P),C(B),R=!0)},o(P){I(D.$$.fragment,P),I(B),R=!1},d(P){P&&c(e),Q&&Q.d(),ce(D),ve[G].d(),te&&te.d(),ye=!1,_l(at)}}}function ps(s){let e,t,l=s[11].toFixed(1)+"",r,o;return{c(){e=f("span"),t=H("(took "),r=H(l),o=H("s)"),this.h()},l(i){e=u(i,"SPAN",{class:!0});var h=p(e);t=M(h,"(took "),r=M(h,l),o=M(h,"s)"),h.forEach(c),this.h()},h(){a(e,"class","text-xs text-green-700")},m(i,h){j(i,e,h),n(e,t),n(e,r),n(e,o)},p(i,h){h[0]&2048&&l!==(l=i[11].toFixed(1)+"")&&Ye(r,l)},d(i){i&&c(e)}}}function tn(s){let e,t;return e=new dl({props:{size:10,class:"text-white ml-0.5"}}),{c(){de(e.$$.fragment)},l(l){fe(e.$$.fragment,l)},m(l,r){ue(e,l,r),t=!0},i(l){t||(C(e.$$.fragment,l),t=!0)},o(l){I(e.$$.fragment,l),t=!1},d(l){ce(e,l)}}}function ln(s){let e;return{c(){e=f("div"),this.h()},l(t){e=u(t,"DIV",{class:!0}),p(e).forEach(c),this.h()},h(){a(e,"class","pause-filled text-white text-xs svelte-13ak1iw")},m(t,l){j(t,e,l)},i:jt,o:jt,d(t){t&&c(e)}}}function hs(s){let e,t,l,r;return{c(){e=f("audio"),this.h()},l(o){e=u(o,"AUDIO",{src:!0,style:!0}),p(e).forEach(c),this.h()},h(){ts(e.src,t=s[10])||a(e,"src",t),pr(e,"display","none")},m(o,i){j(o,e,i),s[58](e),l||(r=[L(e,"loadedmetadata",s[28]),L(e,"timeupdate",s[29]),L(e,"play",s[30]),L(e,"pause",s[31])],l=!0)},p(o,i){i[0]&1024&&!ts(e.src,t=o[10])&&a(e,"src",t)},d(o){o&&c(e),s[58](null),l=!1,_l(r)}}}function ms(s){let e,t,l,r,o,i,h,m,$,y,v,x,A="An error occurred while processing your request",J,D,E,T,w,U,Y,pe,_e="Close",O,Z,he;i=new Hs({props:{size:20,class:"text-red-600"}}),E=new js({props:{size:20,class:"text-gray-500"}});let S=s[20]&&gs(s);return{c(){e=f("div"),t=f("div"),l=f("div"),r=f("div"),o=f("div"),de(i.$$.fragment),h=b(),m=f("div"),$=f("h3"),y=H(s[19]),v=b(),x=f("p"),x.textContent=A,J=b(),D=f("button"),de(E.$$.fragment),T=b(),w=f("div"),S&&S.c(),U=b(),Y=f("div"),pe=f("button"),pe.textContent=_e,this.h()},l(V){e=u(V,"DIV",{class:!0});var z=p(e);t=u(z,"DIV",{class:!0});var F=p(t);l=u(F,"DIV",{class:!0});var G=p(l);r=u(G,"DIV",{class:!0});var B=p(r);o=u(B,"DIV",{class:!0});var Oe=p(o);fe(i.$$.fragment,Oe),Oe.forEach(c),h=_(B),m=u(B,"DIV",{class:!0});var ee=p(m);$=u(ee,"H3",{class:!0});var se=p($);y=M(se,s[19]),se.forEach(c),v=_(ee),x=u(ee,"P",{class:!0,"data-svelte-h":!0}),q(x)!=="svelte-1l3zl3"&&(x.textContent=A),ee.forEach(c),B.forEach(c),J=_(G),D=u(G,"BUTTON",{class:!0,title:!0});var me=p(D);fe(E.$$.fragment,me),me.forEach(c),G.forEach(c),T=_(F),w=u(F,"DIV",{class:!0});var Be=p(w);S&&S.l(Be),Be.forEach(c),U=_(F),Y=u(F,"DIV",{class:!0});var Fe=p(Y);pe=u(Fe,"BUTTON",{class:!0,"data-svelte-h":!0}),q(pe)!=="svelte-4sxk6g"&&(pe.textContent=_e),Fe.forEach(c),F.forEach(c),z.forEach(c),this.h()},h(){a(o,"class","w-10 h-10 bg-red-100 rounded-full flex items-center justify-center flex-shrink-0"),a($,"class","text-lg font-semibold text-gray-900 truncate"),a(x,"class","text-sm text-gray-600"),a(m,"class","min-w-0"),a(r,"class","flex items-center gap-3 min-w-0"),a(D,"class","p-2 hover:bg-red-100 rounded-full transition-colors flex-shrink-0"),a(D,"title","Close"),a(l,"class","flex items-center justify-between p-6 border-b border-gray-200 bg-red-50 flex-shrink-0"),a(w,"class","p-6 overflow-y-auto flex-1 min-h-0"),a(pe,"class","px-6 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors"),a(Y,"class","flex items-center justify-end gap-3 p-6 border-t border-gray-200 bg-gray-50 flex-shrink-0"),a(t,"class","bg-white rounded-xl shadow-2xl max-w-2xl w-full max-h-[80vh] flex flex-col"),a(e,"class","fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4")},m(V,z){j(V,e,z),n(e,t),n(t,l),n(l,r),n(r,o),ue(i,o,null),n(r,h),n(r,m),n(m,$),n($,y),n(m,v),n(m,x),n(l,J),n(l,D),ue(E,D,null),n(t,T),n(t,w),S&&S.m(w,null),n(t,U),n(t,Y),n(Y,pe),O=!0,Z||(he=[L(D,"click",s[36]),L(pe,"click",s[36])],Z=!0)},p(V,z){(!O||z[0]&524288)&&Ye(y,V[19]),V[20]?S?S.p(V,z):(S=gs(V),S.c(),S.m(w,null)):S&&(S.d(1),S=null)},i(V){O||(C(i.$$.fragment,V),C(E.$$.fragment,V),O=!0)},o(V){I(i.$$.fragment,V),I(E.$$.fragment,V),O=!1},d(V){V&&c(e),ce(i),ce(E),S&&S.d(),Z=!1,_l(he)}}}function gs(s){let e,t,l="Error Details:",r,o,i;function h(y,v){return v[0]&1048576&&(i=null),i==null&&(i=!!y[20].includes("exceeded your monthly included credits")),i?sn:rn}let m=h(s,[-1,-1,-1]),$=m(s);return{c(){e=f("div"),t=f("h4"),t.textContent=l,r=b(),o=f("pre"),$.c(),this.h()},l(y){e=u(y,"DIV",{class:!0});var v=p(e);t=u(v,"H4",{class:!0,"data-svelte-h":!0}),q(t)!=="svelte-3lmggt"&&(t.textContent=l),r=_(v),o=u(v,"PRE",{class:!0});var x=p(o);$.l(x),x.forEach(c),v.forEach(c),this.h()},h(){a(t,"class","text-sm font-medium text-gray-900 mb-2"),a(o,"class","text-xs text-gray-700 whitespace-pre-wrap font-mono leading-relaxed break-words"),a(e,"class","bg-gray-50 rounded-lg p-4 border")},m(y,v){j(y,e,v),n(e,t),n(e,r),n(e,o),$.m(o,null)},p(y,v){m===(m=h(y,v))&&$?$.p(y,v):($.d(1),$=m(y),$&&($.c(),$.m(o,null)))},d(y){y&&c(e),$.d()}}}function rn(s){let e;return{c(){e=H(s[20])},l(t){e=M(t,s[20])},m(t,l){j(t,e,l)},p(t,l){l[0]&1048576&&Ye(e,t[20])},d(t){t&&c(e)}}}function sn(s){let e,t=s[20].replace("Subscribe to PRO",'<a href="https://huggingface.co/settings/billing" target="_blank" class="text-amber-600 hover:text-amber-700 underline font-medium">Subscribe to PRO</a>')+"",l;return{c(){e=new mr(!1),l=At(),this.h()},l(r){e=hr(r,!1),l=At(),this.h()},h(){e.a=l},m(r,o){e.m(t,r,o),j(r,l,o)},p(r,o){o[0]&1048576&&t!==(t=r[20].replace("Subscribe to PRO",'<a href="https://huggingface.co/settings/billing" target="_blank" class="text-amber-600 hover:text-amber-700 underline font-medium">Subscribe to PRO</a>')+"")&&e.p(t)},d(r){r&&(c(l),e.d())}}}function _s(s){let e,t;return{c(){e=f("div"),t=H(s[22]),this.h()},l(l){e=u(l,"DIV",{class:!0});var r=p(e);t=M(r,s[22]),r.forEach(c),this.h()},h(){a(e,"class","fixed bottom-4 right-4 px-4 py-2 bg-gray-900 text-white rounded-lg shadow-lg z-50 animate-fade-in svelte-13ak1iw")},m(l,r){j(l,e,r),n(e,t)},p(l,r){r[0]&4194304&&Ye(t,l[22])},d(l){l&&c(e)}}}function nn(s){let e,t,l,r,o,i,h,m=s[0].length.toLocaleString()+"",$,y,v,x,A,J,D,E,T,w,U,Y,pe="Model",_e,O,Z,he,S,V,z,F,G,B,Oe='$0.025 per 1000 chars • <a href="https://huggingface.co/settings/billing" target="_blank" class="text-amber-600 hover:text-amber-700 underline">Billing ⤴</a>',ee,se,me,Be="Voice",Fe,X,be,Pe,xe,Le='<div class="w-6 h-6 bg-gradient-to-br from-amber-400 to-orange-500 rounded-full flex items-center justify-center text-white text-xs font-semibold">A</div> <span class="text-sm font-medium">Andrew</span>',We,Ie,R,ye,at,Q,Ne,ve,Re,te='<div class="w-6 h-6 bg-gradient-to-br from-amber-400 to-orange-500 rounded-full flex items-center justify-center text-white text-xs font-semibold">L</div> <span class="text-sm font-medium">Lily</span>',P,N,W,ne,ot,Ze,we,De,Ge,it='<div class="w-6 h-6 bg-gradient-to-br from-amber-400 to-orange-500 rounded-full flex items-center justify-center text-white text-xs font-semibold">P</div> <span class="text-sm font-medium">Pirate</span>',et,Me,ae,Ee,ct,gt,He,je,pl,tt,Ke,lt,g,le="Exaggeration",re,K,ge=s[3].toFixed(2)+"",qe,hl,Se,Fl,Ot,gr="<span>None</span> <span>More</span>",Rl,ut,_t,bt,_r="Stability",Gl,el,ml=s[4].toFixed(2)+"",bl,ql,ze,Yl,St,br="<span>More stable</span> <span>More variable</span>",Kl,rt,Je,Xe,vl,Jl,tl,Ue,yl,zt,vr='<h3 class="text-lg font-semibold text-gray-900 mb-1">Live Documentation ✨</h3>',Xl,vt,yt,wt,Ql,wl,Wl,kt,Zl,kl,er,ft,Ut,tr,Bt,yr="Copy all as Markdown",lr,Qe,xt,Et,Ft,wr='<span class="text-xs font-medium text-blue-900">Install in Terminal</span>',rr,Tt,Rt,sr,Gt,kr=s[7],nr,Ct,$t,qt,xr='<span class="text-xs font-medium text-amber-900">Python Code</span> <span class="text-xs bg-amber-100 text-amber-700 px-1.5 py-0.5 rounded">Live</span>',ar,It,Yt,or,Kt,Er=s[7],ir,xl,ll,rl,Ae,cr,Tr;A=new Ns({props:{size:16}});let sl=Ul(s[25]),ke=[];for(let d=0;d<sl.length;d+=1)ke[d]=as(ss(s,sl,d));V=new zs({props:{size:14,class:"text-gray-500 transition-transform "+(s[8]?"rotate-180":"")}});let Te=s[8]&&os(s);const Cr=[Rs,Fs],Jt=[];function $r(d,k){return d[17]==="Andrew"?0:1}R=$r(s),ye=Jt[R]=Cr[R](s);const Ir=[qs,Gs],Xt=[];function Dr(d,k){return d[17]==="Lily"?0:1}W=Dr(s),ne=Xt[W]=Ir[W](s);const Vr=[Ks,Ys],Qt=[];function Pr(d,k){return d[17]==="Pirate"?0:1}ae=Pr(s),Ee=Qt[ae]=Vr[ae](s);const Lr=[Xs,Js],Dt=[];function Nr(d,k){return d[5].length>0?0:1}He=Nr(s),je=Dt[He]=Lr[He](s);const Mr=[en,Zs],Wt=[];function Hr(d,k){return d[9]?0:1}Je=Hr(s),Xe=Wt[Je]=Mr[Je](s);let Ce=s[21]&&cs(s);Ut=new fr({props:{size:12,class:"text-gray-600"}}),Rt=new fr({props:{size:12,class:"text-blue-600"}});let dt=us(s);Yt=new fr({props:{size:12,class:"text-amber-600"}});let pt=fs(s),oe=s[10]&&ds(s),ie=s[18]&&ms(s),$e=s[22]&&_s(s);return{c(){e=b(),t=f("div"),l=f("div"),r=f("div"),o=f("div"),i=f("div"),h=f("span"),$=H(m),y=H(" / 1,000 characters"),v=b(),x=f("button"),de(A.$$.fragment),J=b(),D=f("textarea"),E=b(),T=f("div"),w=f("div"),U=f("div"),Y=f("h3"),Y.textContent=pe,_e=b(),O=f("div"),Z=f("button"),he=f("span");for(let d=0;d<ke.length;d+=1)ke[d].c();S=b(),de(V.$$.fragment),F=b(),Te&&Te.c(),G=b(),B=f("div"),B.innerHTML=Oe,ee=b(),se=f("div"),me=f("h3"),me.textContent=Be,Fe=b(),X=f("div"),be=f("button"),Pe=f("div"),xe=f("div"),xe.innerHTML=Le,We=b(),Ie=f("button"),ye.c(),Q=b(),Ne=f("button"),ve=f("div"),Re=f("div"),Re.innerHTML=te,P=b(),N=f("button"),ne.c(),Ze=b(),we=f("button"),De=f("div"),Ge=f("div"),Ge.innerHTML=it,et=b(),Me=f("button"),Ee.c(),gt=b(),je.c(),pl=b(),tt=f("div"),Ke=f("div"),lt=f("div"),g=f("label"),g.textContent=le,re=b(),K=f("span"),qe=H(ge),hl=b(),Se=f("input"),Fl=b(),Ot=f("div"),Ot.innerHTML=gr,Rl=b(),ut=f("div"),_t=f("div"),bt=f("label"),bt.textContent=_r,Gl=b(),el=f("span"),bl=H(ml),ql=b(),ze=f("input"),Yl=b(),St=f("div"),St.innerHTML=br,Kl=b(),rt=f("button"),Xe.c(),Jl=b(),tl=f("div"),Ue=f("div"),Ce&&Ce.c(),yl=b(),zt=f("div"),zt.innerHTML=vr,Xl=b(),vt=f("div"),yt=f("div"),wt=f("button"),Ql=H("API"),Wl=b(),kt=f("button"),Zl=H("Local"),er=b(),ft=f("button"),de(Ut.$$.fragment),tr=b(),Bt=f("span"),Bt.textContent=yr,lr=b(),Qe=f("div"),xt=f("div"),Et=f("div"),Ft=f("div"),Ft.innerHTML=wr,rr=b(),Tt=f("button"),de(Rt.$$.fragment),sr=b(),Gt=f("div"),dt.c(),nr=b(),Ct=f("div"),$t=f("div"),qt=f("div"),qt.innerHTML=xr,ar=b(),It=f("button"),de(Yt.$$.fragment),or=b(),Kt=f("div"),pt.c(),ir=b(),oe&&oe.c(),xl=b(),ie&&ie.c(),ll=b(),$e&&$e.c(),rl=At(),this.h()},l(d){Ts("svelte-y100ki",ls.head).forEach(c),e=_(d),t=u(d,"DIV",{class:!0,role:!0,tabindex:!0});var st=p(t);l=u(st,"DIV",{class:!0});var Vt=p(l);r=u(Vt,"DIV",{class:!0});var nt=p(r);o=u(nt,"DIV",{class:!0});var Pt=p(o);i=u(Pt,"DIV",{class:!0});var Lt=p(i);h=u(Lt,"SPAN",{class:!0});var Zt=p(h);$=M(Zt,m),y=M(Zt," / 1,000 characters"),Zt.forEach(c),v=_(Lt),x=u(Lt,"BUTTON",{class:!0,title:!0});var Ve=p(x);fe(A.$$.fragment,Ve),Ve.forEach(c),Lt.forEach(c),J=_(Pt),D=u(Pt,"TEXTAREA",{maxlength:!0,class:!0,placeholder:!0}),p(D).forEach(c),Pt.forEach(c),E=_(nt),T=u(nt,"DIV",{class:!0});var gl=p(T);w=u(gl,"DIV",{class:!0});var nl=p(w);U=u(nl,"DIV",{class:!0});var al=p(U);Y=u(al,"H3",{class:!0,"data-svelte-h":!0}),q(Y)!=="svelte-x9l5tw"&&(Y.textContent=pe),_e=_(al),O=u(al,"DIV",{class:!0});var El=p(O);Z=u(El,"BUTTON",{class:!0});var Tl=p(Z);he=u(Tl,"SPAN",{});var jr=p(he);for(let ur=0;ur<ke.length;ur+=1)ke[ur].l(jr);jr.forEach(c),S=_(Tl),fe(V.$$.fragment,Tl),Tl.forEach(c),F=_(El),Te&&Te.l(El),El.forEach(c),G=_(al),B=u(al,"DIV",{class:!0,"data-svelte-h":!0}),q(B)!=="svelte-162fgbh"&&(B.innerHTML=Oe),al.forEach(c),ee=_(nl),se=u(nl,"DIV",{});var Cl=p(se);me=u(Cl,"H3",{class:!0,"data-svelte-h":!0}),q(me)!=="svelte-1pzzi7j"&&(me.textContent=Be),Fe=_(Cl),X=u(Cl,"DIV",{class:!0});var Nt=p(X);be=u(Nt,"BUTTON",{class:!0});var Ar=p(be);Pe=u(Ar,"DIV",{class:!0});var $l=p(Pe);xe=u($l,"DIV",{class:!0,"data-svelte-h":!0}),q(xe)!=="svelte-qsi6ww"&&(xe.innerHTML=Le),We=_($l),Ie=u($l,"BUTTON",{class:!0,title:!0});var Or=p(Ie);ye.l(Or),Or.forEach(c),$l.forEach(c),Ar.forEach(c),Q=_(Nt),Ne=u(Nt,"BUTTON",{class:!0});var Sr=p(Ne);ve=u(Sr,"DIV",{class:!0});var Il=p(ve);Re=u(Il,"DIV",{class:!0,"data-svelte-h":!0}),q(Re)!=="svelte-1c7qu8y"&&(Re.innerHTML=te),P=_(Il),N=u(Il,"BUTTON",{class:!0,title:!0});var zr=p(N);ne.l(zr),zr.forEach(c),Il.forEach(c),Sr.forEach(c),Ze=_(Nt),we=u(Nt,"BUTTON",{class:!0});var Ur=p(we);De=u(Ur,"DIV",{class:!0});var Dl=p(De);Ge=u(Dl,"DIV",{class:!0,"data-svelte-h":!0}),q(Ge)!=="svelte-1o6w87n"&&(Ge.innerHTML=it),et=_(Dl),Me=u(Dl,"BUTTON",{class:!0,title:!0});var Br=p(Me);Ee.l(Br),Br.forEach(c),Dl.forEach(c),Ur.forEach(c),gt=_(Nt),je.l(Nt),Nt.forEach(c),Cl.forEach(c),pl=_(nl),tt=u(nl,"DIV",{class:!0});var Vl=p(tt);Ke=u(Vl,"DIV",{});var ol=p(Ke);lt=u(ol,"DIV",{class:!0});var Pl=p(lt);g=u(Pl,"LABEL",{for:!0,class:!0,"data-svelte-h":!0}),q(g)!=="svelte-ywi5v5"&&(g.textContent=le),re=_(Pl),K=u(Pl,"SPAN",{class:!0});var Fr=p(K);qe=M(Fr,ge),Fr.forEach(c),Pl.forEach(c),hl=_(ol),Se=u(ol,"INPUT",{id:!0,type:!0,min:!0,max:!0,step:!0,class:!0}),Fl=_(ol),Ot=u(ol,"DIV",{class:!0,"data-svelte-h":!0}),q(Ot)!=="svelte-y2ce61"&&(Ot.innerHTML=gr),ol.forEach(c),Rl=_(Vl),ut=u(Vl,"DIV",{});var il=p(ut);_t=u(il,"DIV",{class:!0});var Ll=p(_t);bt=u(Ll,"LABEL",{for:!0,class:!0,"data-svelte-h":!0}),q(bt)!=="svelte-1y95y02"&&(bt.textContent=_r),Gl=_(Ll),el=u(Ll,"SPAN",{class:!0});var Rr=p(el);bl=M(Rr,ml),Rr.forEach(c),Ll.forEach(c),ql=_(il),ze=u(il,"INPUT",{id:!0,type:!0,min:!0,max:!0,step:!0,class:!0}),Yl=_(il),St=u(il,"DIV",{class:!0,"data-svelte-h":!0}),q(St)!=="svelte-1sqzqqv"&&(St.innerHTML=br),il.forEach(c),Vl.forEach(c),nl.forEach(c),gl.forEach(c),Kl=_(nt),rt=u(nt,"BUTTON",{class:!0});var Gr=p(rt);Xe.l(Gr),Gr.forEach(c),nt.forEach(c),Jl=_(Vt),tl=u(Vt,"DIV",{class:!0});var qr=p(tl);Ue=u(qr,"DIV",{class:!0});var Mt=p(Ue);Ce&&Ce.l(Mt),yl=_(Mt),zt=u(Mt,"DIV",{class:!0,"data-svelte-h":!0}),q(zt)!=="svelte-kwvs7"&&(zt.innerHTML=vr),Xl=_(Mt),vt=u(Mt,"DIV",{class:!0});var Nl=p(vt);yt=u(Nl,"DIV",{class:!0});var Ml=p(yt);wt=u(Ml,"BUTTON",{class:!0});var Yr=p(wt);Ql=M(Yr,"API"),Yr.forEach(c),Wl=_(Ml),kt=u(Ml,"BUTTON",{class:!0});var Kr=p(kt);Zl=M(Kr,"Local"),Kr.forEach(c),Ml.forEach(c),er=_(Nl),ft=u(Nl,"BUTTON",{class:!0});var Hl=p(ft);fe(Ut.$$.fragment,Hl),tr=_(Hl),Bt=u(Hl,"SPAN",{class:!0,"data-svelte-h":!0}),q(Bt)!=="svelte-o5pdun"&&(Bt.textContent=yr),Hl.forEach(c),Nl.forEach(c),lr=_(Mt),Qe=u(Mt,"DIV",{class:!0});var cl=p(Qe);xt=u(cl,"DIV",{class:!0});var jl=p(xt);Et=u(jl,"DIV",{class:!0});var Al=p(Et);Ft=u(Al,"DIV",{class:!0,"data-svelte-h":!0}),q(Ft)!=="svelte-1eboucz"&&(Ft.innerHTML=wr),rr=_(Al),Tt=u(Al,"BUTTON",{class:!0,title:!0});var Jr=p(Tt);fe(Rt.$$.fragment,Jr),Jr.forEach(c),Al.forEach(c),sr=_(jl),Gt=u(jl,"DIV",{class:!0});var Xr=p(Gt);dt.l(Xr),Xr.forEach(c),jl.forEach(c),nr=_(cl),Ct=u(cl,"DIV",{class:!0});var Ol=p(Ct);$t=u(Ol,"DIV",{class:!0});var Sl=p($t);qt=u(Sl,"DIV",{class:!0,"data-svelte-h":!0}),q(qt)!=="svelte-w4xfzx"&&(qt.innerHTML=xr),ar=_(Sl),It=u(Sl,"BUTTON",{class:!0,title:!0});var Qr=p(It);fe(Yt.$$.fragment,Qr),Qr.forEach(c),Sl.forEach(c),or=_(Ol),Kt=u(Ol,"DIV",{class:!0});var Wr=p(Kt);pt.l(Wr),Wr.forEach(c),Ol.forEach(c),ir=_(cl),oe&&oe.l(cl),cl.forEach(c),Mt.forEach(c),qr.forEach(c),Vt.forEach(c),st.forEach(c),xl=_(d),ie&&ie.l(d),ll=_(d),$e&&$e.l(d),rl=At(),this.h()},h(){ls.title="Text to Speech - HFStudio",a(h,"class","text-sm text-gray-400"),a(x,"class","p-1 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-lg transition-colors"),a(x,"title","Refresh with famous book opening"),a(i,"class","absolute top-3 right-3 flex items-center gap-2 z-10"),a(D,"maxlength","1000"),a(D,"class","w-full h-80 pt-10 px-6 pb-6 bg-white resize-none border border-gray-200 rounded-lg focus:outline-none focus:ring-2 focus:ring-amber-400 focus:border-transparent text-gray-900 text-lg leading-relaxed"),a(D,"placeholder","Type the text you'd like to convert to spoken audio here..."),D.autofocus=!0,a(o,"class","relative mb-4"),a(Y,"class","text-sm font-medium text-gray-900 mb-2"),a(Z,"class",z="w-full p-3 border border-gray-200 bg-white text-sm focus:outline-none focus:ring-2 focus:ring-amber-400 focus:border-transparent shadow-sm text-left flex items-center justify-between "+(s[8]?"rounded-b-lg border-t-0":"rounded-lg")),a(O,"class","relative"),a(B,"class","mt-1.5 text-xs text-gray-500 text-right"),a(U,"class","model-dropdown"),a(me,"class","text-sm font-medium text-gray-900 mb-2"),a(xe,"class","flex items-center gap-2"),a(Ie,"class","p-1 rounded-full hover:bg-gray-200 transition-colors w-5 h-5 flex items-center justify-center"),a(Ie,"title","Play sample"),a(Pe,"class","flex items-center justify-between mb-1"),a(be,"class",at="p-3 border rounded-lg transition-colors text-left hover:bg-gray-50 "+(s[1]==="Andrew"?"border-amber-400 bg-amber-50":"border-gray-200")),a(Re,"class","flex items-center gap-2"),a(N,"class","p-1 rounded-full hover:bg-gray-200 transition-colors w-5 h-5 flex items-center justify-center"),a(N,"title","Play sample"),a(ve,"class","flex items-center justify-between mb-1"),a(Ne,"class",ot="p-3 border rounded-lg transition-colors text-left hover:bg-gray-50 "+(s[1]==="Lily"?"border-amber-400 bg-amber-50":"border-gray-200")),a(Ge,"class","flex items-center gap-2"),a(Me,"class","p-1 rounded-full hover:bg-gray-200 transition-colors w-5 h-5 flex items-center justify-center"),a(Me,"title","Play sample"),a(De,"class","flex items-center justify-between mb-1"),a(we,"class",ct="p-3 border rounded-lg transition-colors text-left hover:bg-gray-50 "+(s[1]==="Pirate"?"border-amber-400 bg-amber-50":"border-gray-200")),a(X,"class","grid grid-cols-2 gap-2"),a(g,"for","exaggeration-slider"),a(g,"class","text-sm font-medium text-gray-900"),a(K,"class","text-sm text-gray-500"),a(lt,"class","flex justify-between mb-3"),a(Se,"id","exaggeration-slider"),a(Se,"type","range"),a(Se,"min","0"),a(Se,"max","1"),a(Se,"step","0.01"),a(Se,"class","w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer slider-hf"),a(Ot,"class","flex justify-between text-xs text-gray-400 mt-2"),a(bt,"for","temperature-slider"),a(bt,"class","text-sm font-medium text-gray-900"),a(el,"class","text-sm text-gray-500"),a(_t,"class","flex justify-between mb-3"),a(ze,"id","temperature-slider"),a(ze,"type","range"),a(ze,"min","0"),a(ze,"max","1"),a(ze,"step","0.01"),a(ze,"class","w-full h-2 bg-gray-200 rounded-lg appearance-none cursor-pointer slider-hf"),a(St,"class","flex justify-between text-xs text-gray-400 mt-2"),a(tt,"class","space-y-6"),a(w,"class","grid grid-cols-1 lg:grid-cols-[1fr_1.4fr_1fr] gap-6"),a(T,"class","p-4 border border-gray-200 rounded-lg bg-white mb-6"),rt.disabled=vl=s[9]||!s[0].trim(),a(rt,"class","w-full px-4 py-3 bg-gradient-to-r from-amber-400 to-orange-500 text-white rounded-lg font-medium hover:from-amber-500 hover:to-orange-600 disabled:opacity-50 disabled:cursor-not-allowed flex items-center justify-center gap-2 shadow-sm"),a(r,"class","flex-1 flex flex-col p-6"),a(zt,"class","mb-4"),a(wt,"class",wl="px-2 py-1 text-xs font-medium rounded transition-colors "+(s[6]==="api"?"bg-white shadow-sm":"text-gray-600")),a(kt,"class",kl="px-2 py-1 text-xs font-medium rounded transition-colors "+(s[6]==="local"?"bg-white shadow-sm":"text-gray-600")),a(yt,"class","flex items-center bg-gray-100 rounded-md p-0.5"),a(Bt,"class","ml-1 text-xs font-medium text-gray-600"),a(ft,"class","flex items-center bg-gray-100 hover:bg-gray-200 rounded-md px-2 py-1 transition-colors"),a(vt,"class","flex items-center justify-between mb-4"),a(Ft,"class","flex items-center gap-2"),a(Tt,"class","p-1 hover:bg-blue-100 rounded transition-colors"),a(Tt,"title","Copy setup code"),a(Et,"class","flex items-center justify-between px-3 py-2 bg-blue-50 border-b border-blue-200"),a(Gt,"class","relative"),a(xt,"class","bg-white rounded-lg border border-gray-200 overflow-hidden"),a(qt,"class","flex items-center gap-2"),a(It,"class","p-1 hover:bg-amber-100 rounded transition-colors"),a(It,"title","Copy Python code"),a($t,"class","flex items-center justify-between px-3 py-2 bg-amber-50 border-b border-amber-200"),a(Kt,"class","relative"),a(Ct,"class","bg-white rounded-lg border border-gray-200 overflow-hidden"),a(Qe,"class","space-y-4"),a(Ue,"class","p-4"),a(tl,"class","w-96 border-l border-gray-200 bg-white overflow-y-auto"),a(l,"class","flex-1 flex"),a(t,"class","flex flex-col h-full"),a(t,"role","main"),a(t,"tabindex","-1")},m(d,k){j(d,e,k),j(d,t,k),n(t,l),n(l,r),n(r,o),n(o,i),n(i,h),n(h,$),n(h,y),n(i,v),n(i,x),ue(A,x,null),n(o,J),n(o,D),ul(D,s[0]),n(r,E),n(r,T),n(T,w),n(w,U),n(U,Y),n(U,_e),n(U,O),n(O,Z),n(Z,he);for(let st=0;st<ke.length;st+=1)ke[st]&&ke[st].m(he,null);n(Z,S),ue(V,Z,null),n(O,F),Te&&Te.m(O,null),n(U,G),n(U,B),n(w,ee),n(w,se),n(se,me),n(se,Fe),n(se,X),n(X,be),n(be,Pe),n(Pe,xe),n(Pe,We),n(Pe,Ie),Jt[R].m(Ie,null),n(X,Q),n(X,Ne),n(Ne,ve),n(ve,Re),n(ve,P),n(ve,N),Xt[W].m(N,null),n(X,Ze),n(X,we),n(we,De),n(De,Ge),n(De,et),n(De,Me),Qt[ae].m(Me,null),n(X,gt),Dt[He].m(X,null),n(w,pl),n(w,tt),n(tt,Ke),n(Ke,lt),n(lt,g),n(lt,re),n(lt,K),n(K,qe),n(Ke,hl),n(Ke,Se),ul(Se,s[3]),n(Ke,Fl),n(Ke,Ot),n(tt,Rl),n(tt,ut),n(ut,_t),n(_t,bt),n(_t,Gl),n(_t,el),n(el,bl),n(ut,ql),n(ut,ze),ul(ze,s[4]),n(ut,Yl),n(ut,St),n(r,Kl),n(r,rt),Wt[Je].m(rt,null),n(l,Jl),n(l,tl),n(tl,Ue),Ce&&Ce.m(Ue,null),n(Ue,yl),n(Ue,zt),n(Ue,Xl),n(Ue,vt),n(vt,yt),n(yt,wt),n(wt,Ql),n(yt,Wl),n(yt,kt),n(kt,Zl),n(vt,er),n(vt,ft),ue(Ut,ft,null),n(ft,tr),n(ft,Bt),n(Ue,lr),n(Ue,Qe),n(Qe,xt),n(xt,Et),n(Et,Ft),n(Et,rr),n(Et,Tt),ue(Rt,Tt,null),n(xt,sr),n(xt,Gt),dt.m(Gt,null),n(Qe,nr),n(Qe,Ct),n(Ct,$t),n($t,qt),n($t,ar),n($t,It),ue(Yt,It,null),n(Ct,or),n(Ct,Kt),pt.m(Kt,null),n(Qe,ir),oe&&oe.m(Qe,null),j(d,xl,k),ie&&ie.m(d,k),j(d,ll,k),$e&&$e.m(d,k),j(d,rl,k),Ae=!0,D.focus(),cr||(Tr=[L(x,"click",s[37]),L(D,"input",s[40]),L(D,"keydown",s[34]),L(Z,"click",s[41]),L(Ie,"click",s[43]),L(be,"click",s[44]),L(N,"click",s[45]),L(Ne,"click",s[46]),L(Me,"click",s[47]),L(we,"click",s[48]),L(Se,"change",s[51]),L(Se,"input",s[51]),L(ze,"change",s[52]),L(ze,"input",s[52]),L(rt,"click",s[26]),L(wt,"click",s[54]),L(kt,"click",s[55]),L(ft,"click",s[39]),L(Tt,"click",s[56]),L(It,"click",s[57]),L(t,"click",s[35]),L(t,"keydown",s[34])],cr=!0)},p(d,k){if((!Ae||k[0]&1)&&m!==(m=d[0].length.toLocaleString()+"")&&Ye($,m),k[0]&1&&ul(D,d[0]),k[0]&33554436){sl=Ul(d[25]);let Ve;for(Ve=0;Ve<sl.length;Ve+=1){const gl=ss(d,sl,Ve);ke[Ve]?ke[Ve].p(gl,k):(ke[Ve]=as(gl),ke[Ve].c(),ke[Ve].m(he,null))}for(;Ve<ke.length;Ve+=1)ke[Ve].d(1);ke.length=sl.length}const st={};k[0]&256&&(st.class="text-gray-500 transition-transform "+(d[8]?"rotate-180":"")),V.$set(st),(!Ae||k[0]&256&&z!==(z="w-full p-3 border border-gray-200 bg-white text-sm focus:outline-none focus:ring-2 focus:ring-amber-400 focus:border-transparent shadow-sm text-left flex items-center justify-between "+(d[8]?"rounded-b-lg border-t-0":"rounded-lg")))&&a(Z,"class",z),d[8]?Te?Te.p(d,k):(Te=os(d),Te.c(),Te.m(O,null)):Te&&(Te.d(1),Te=null);let Vt=R;R=$r(d),R!==Vt&&(mt(),I(Jt[Vt],1,1,()=>{Jt[Vt]=null}),ht(),ye=Jt[R],ye||(ye=Jt[R]=Cr[R](d),ye.c()),C(ye,1),ye.m(Ie,null)),(!Ae||k[0]&2&&at!==(at="p-3 border rounded-lg transition-colors text-left hover:bg-gray-50 "+(d[1]==="Andrew"?"border-amber-400 bg-amber-50":"border-gray-200")))&&a(be,"class",at);let nt=W;W=Dr(d),W!==nt&&(mt(),I(Xt[nt],1,1,()=>{Xt[nt]=null}),ht(),ne=Xt[W],ne||(ne=Xt[W]=Ir[W](d),ne.c()),C(ne,1),ne.m(N,null)),(!Ae||k[0]&2&&ot!==(ot="p-3 border rounded-lg transition-colors text-left hover:bg-gray-50 "+(d[1]==="Lily"?"border-amber-400 bg-amber-50":"border-gray-200")))&&a(Ne,"class",ot);let Pt=ae;ae=Pr(d),ae!==Pt&&(mt(),I(Qt[Pt],1,1,()=>{Qt[Pt]=null}),ht(),Ee=Qt[ae],Ee||(Ee=Qt[ae]=Vr[ae](d),Ee.c()),C(Ee,1),Ee.m(Me,null)),(!Ae||k[0]&2&&ct!==(ct="p-3 border rounded-lg transition-colors text-left hover:bg-gray-50 "+(d[1]==="Pirate"?"border-amber-400 bg-amber-50":"border-gray-200")))&&a(we,"class",ct);let Lt=He;He=Nr(d),He===Lt?Dt[He].p(d,k):(mt(),I(Dt[Lt],1,1,()=>{Dt[Lt]=null}),ht(),je=Dt[He],je?je.p(d,k):(je=Dt[He]=Lr[He](d),je.c()),C(je,1),je.m(X,null)),(!Ae||k[0]&8)&&ge!==(ge=d[3].toFixed(2)+"")&&Ye(qe,ge),k[0]&8&&ul(Se,d[3]),(!Ae||k[0]&16)&&ml!==(ml=d[4].toFixed(2)+"")&&Ye(bl,ml),k[0]&16&&ul(ze,d[4]);let Zt=Je;Je=Hr(d),Je!==Zt&&(mt(),I(Wt[Zt],1,1,()=>{Wt[Zt]=null}),ht(),Xe=Wt[Je],Xe||(Xe=Wt[Je]=Mr[Je](d),Xe.c()),C(Xe,1),Xe.m(rt,null)),(!Ae||k[0]&513&&vl!==(vl=d[9]||!d[0].trim()))&&(rt.disabled=vl),d[21]?Ce?Ce.p(d,k):(Ce=cs(d),Ce.c(),Ce.m(Ue,yl)):Ce&&(Ce.d(1),Ce=null),(!Ae||k[0]&64&&wl!==(wl="px-2 py-1 text-xs font-medium rounded transition-colors "+(d[6]==="api"?"bg-white shadow-sm":"text-gray-600")))&&a(wt,"class",wl),(!Ae||k[0]&64&&kl!==(kl="px-2 py-1 text-xs font-medium rounded transition-colors "+(d[6]==="local"?"bg-white shadow-sm":"text-gray-600")))&&a(kt,"class",kl),k[0]&128&&zl(kr,kr=d[7])?(dt.d(1),dt=us(d),dt.c(),dt.m(Gt,null)):dt.p(d,k),k[0]&128&&zl(Er,Er=d[7])?(pt.d(1),pt=fs(d),pt.c(),pt.m(Kt,null)):pt.p(d,k),d[10]?oe?(oe.p(d,k),k[0]&1024&&C(oe,1)):(oe=ds(d),oe.c(),C(oe,1),oe.m(Qe,null)):oe&&(mt(),I(oe,1,1,()=>{oe=null}),ht()),d[18]?ie?(ie.p(d,k),k[0]&262144&&C(ie,1)):(ie=ms(d),ie.c(),C(ie,1),ie.m(ll.parentNode,ll)):ie&&(mt(),I(ie,1,1,()=>{ie=null}),ht()),d[22]?$e?$e.p(d,k):($e=_s(d),$e.c(),$e.m(rl.parentNode,rl)):$e&&($e.d(1),$e=null)},i(d){Ae||(C(A.$$.fragment,d),C(V.$$.fragment,d),C(ye),C(ne),C(Ee),C(je),C(Xe),C(Ut.$$.fragment,d),C(Rt.$$.fragment,d),C(Yt.$$.fragment,d),C(oe),C(ie),Ae=!0)},o(d){I(A.$$.fragment,d),I(V.$$.fragment,d),I(ye),I(ne),I(Ee),I(je),I(Xe),I(Ut.$$.fragment,d),I(Rt.$$.fragment,d),I(Yt.$$.fragment,d),I(oe),I(ie),Ae=!1},d(d){d&&(c(e),c(t),c(xl),c(ll),c(rl)),ce(A),ys(ke,d),ce(V),Te&&Te.d(),Jt[R].d(),Xt[W].d(),Qt[ae].d(),Dt[He].d(),Wt[Je].d(),Ce&&Ce.d(),ce(Ut),ce(Rt),dt.d(d),ce(Yt),pt.d(d),oe&&oe.d(),ie&&ie.d(d),$e&&$e.d(d),cr=!1,_l(Tr)}}}function fl(s){const e=Math.floor(s/60),t=Math.floor(s%60);return`${e}:${t.toString().padStart(2,"0")}`}function an(s,e,t){let l="In a hole in the ground, there lived a hobbit. Not a nasty, dirty, wet hole, filled with the ends of worms and an oozy smell, nor yet a dry, bare, sandy hole with nothing in it to sit down on or to eat: it was a hobbit-hole, and that means comfort.",r="Andrew",o="Chatterbox",i=!1,h=!1,m=null,$=0,y=.25,v=.7,x=!1,A=0,J=0,D="",E=null,T=null,w=null,U=!1,Y="",pe="",_e=0,O=[],Z=!1,he=!1,S=null,V="api",z="",F="",G=0;const B=["It was the best of times, it was the worst of times. It was the age of wisdom, it was the age of foolishness.","It is a truth universally acknowledged, that a single man in possession of a good fortune, must be in want of a wife.","All happy families are alike; each unhappy family is unhappy in its own way.","In a hole in the ground, there lived a hobbit. Not a nasty, dirty, wet hole, filled with the ends of worms and an oozy smell, nor yet a dry, bare, sandy hole with nothing in it to sit down on or to eat: it was a hobbit-hole, and that means comfort."];let Oe=0;const ee=[{id:"chatterbox",name:"Chatterbox",badge:"recommended"},{id:"kokoro",name:"Kokoro",badge:"coming soon",disabled:!0}],se=[{id:"andrew",name:"Andrew",description:"Older British man who speaks clearly and warmly.",sample:"/voices/andrew.mp3",preview_url:"https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/andrew.mp3"},{id:"lily",name:"Lily",description:"Friendly, conversational tone of a woman in her 30s",sample:"/voices/lily.mp3",preview_url:"https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/lily.mp3"},{id:"pirate",name:"Pirate",description:"Young male pirate-y voice that speaks gruffly and with excitement",sample:"/voices/pirate.mp3",preview_url:"https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/pirate.mp3"},{id:"fairy",name:"Fairy",description:"High and airy female voice that bursts with excitement",sample:"/voices/fairy.mp3",preview_url:"https://huggingface.co/spaces/abidlabs/hfstudio/resolve/main/frontend/static/voices/fairy.mp3"}];async function me(){if(!l.trim())return;if(!(await fetch("/api/auth/user",{credentials:"include"})).ok){t(21,he=!0);return}t(9,h=!0),t(10,m=null),t(13,A=0),t(12,x=!1),t(15,D=l.length>30?l.substring(0,30)+"...":l);try{const le={text:l,voice_id:r.toLowerCase(),model_id:o.toLowerCase(),mode:"api",parameters:{exaggeration:y,temperature:v}},re=await fetch("/api/tts/generate",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify(le)});if(!re.ok){const ge=await re.text();throw new Error(`HTTP error! status: ${re.status}, body: ${ge}`)}const K=await re.json();if(K.success&&K.audio_url)t(10,m=K.audio_url),t(11,$=K.generation_time||0),await Q(le,K),setTimeout(()=>{E&&E.play().catch(()=>{})},100);else{const ge=K.error||"Unknown error occurred";R("Generation Failed",ge),t(10,m=null)}}catch{R("Network Error","Failed to connect to the server. Please check your connection and try again."),t(10,m=null)}finally{t(9,h=!1)}}function Be(){E&&(x?E.pause():E.play())}function Fe(){E&&t(14,J=E.duration)}function X(){E&&t(13,A=E.currentTime)}function be(){t(12,x=!0)}function Pe(){t(12,x=!1)}function xe(){if(m){const g=document.createElement("a");g.href=m,g.download="speech.wav",g.click()}}function Le(g,le){if(le.stopPropagation(),w===g.name)T&&(T.pause(),T.currentTime=0),t(17,w=null);else{T&&T.pause(),t(17,w=g.name);const re=g.sample||"/samples/harvard.wav";T?T.src=re:(T=new Audio(re),T.addEventListener("ended",()=>{t(17,w=null)})),T.play().catch(K=>{t(17,w=null)})}}function We(g){g.key==="Enter"&&!g.shiftKey&&(g.preventDefault(),me()),g.key==="Escape"&&t(8,i=!1)}function Ie(g){g.target.closest(".model-dropdown")||t(8,i=!1),g.target.closest(".voice-dropdown")}function R(g,le=""){t(19,Y=g),t(20,pe=le),t(18,U=!0)}function ye(){t(18,U=!1),t(19,Y=""),t(20,pe="")}function at(){Oe=(Oe+1)%B.length,t(0,l=B[Oe])}async function Q(g,le){try{let re=null;const K=O.find(qe=>qe.voice_name===r);if(K&&K.sample_url)re=K.sample_url;else{const qe=se.find(hl=>hl.name===r);qe&&qe.preview_url&&(re=qe.preview_url)}const ge=`audio_bytes = client.text_to_speech(
7
+ "${g.text.replace(/"/g,'\\"')}",
8
+ extra_body={
9
+ "exaggeration": ${g.parameters.exaggeration},
10
+ "temperature": ${g.parameters.temperature}${re?`,
11
+ "audio_url": "${re}"`:""}
12
+ }
13
+ )`;await fetch("/api/history/save",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({code:ge,result_type:"audio",result_data:{url:le.audio_url,title:D,type:"audio"},entry_type:"generation"})}),await Ne()}catch(re){console.error("Error saving to history:",re)}}async function Ne(){try{const g=await fetch("/api/history/load",{method:"GET",credentials:"include"});g.ok&&(_e=(await g.json()).entries.filter(K=>K.entry_type==="generation").length)}catch(g){console.error("Error loading history count:",g),_e=0}}async function ve(){try{Z=!0;const g=await fetch("/api/voice/user-voices",{method:"GET",credentials:"include"});if(g.ok){const le=await g.json();t(5,O=le.voices||[])}else t(5,O=[])}catch(g){console.error("Error loading user voices:",g),t(5,O=[])}finally{Z=!1}}function Re(){return V==="local"?`pip install huggingface-hub hfstudio uv
14
+ hfstudio start ${o.toLowerCase()} --port 7861`:"pip install huggingface-hub"}function te(){return V==="local"?'client = InferenceClient(base_url="http://localhost:7861/api/v1")':`client = InferenceClient(
15
+ api_key="YOUR_HF_TOKEN", # Get your token from https://huggingface.co/settings/tokens
16
+ model="${o.toLowerCase()==="chatterbox"?"ResembleAI/chatterbox":o.toLowerCase()}",
17
+ )`}function P(){let g=null;if(r==="Yours"&&O.length>0){const ge=O[0];ge&&ge.sample_url&&(g=ge.sample_url)}else{const ge=se.find(qe=>qe.name===r);ge&&ge.preview_url&&(g=ge.preview_url)}const le=l||"Hello, this is a sample text.";return`${`from huggingface_hub import InferenceClient
18
+
19
+ ${te()}`}
20
+
21
+ audio_bytes = client.text_to_speech(
22
+ "${le.replace(/"/g,'\\"')}",
23
+ extra_body={
24
+ "exaggeration": ${y},
25
+ "temperature": ${v}${g?`,
26
+ "audio_url": "${g}"`:""}
27
+ }
28
+ )`}function N(g,le="Copied to clipboard!"){navigator.clipboard.writeText(g).then(()=>{t(22,S=le),setTimeout(()=>{t(22,S=null)},2e3)})}function W(){const g=[];if(z){const K=z.includes("pip install")||z.includes("hfstudio start")?"bash":"";g.push(`## Setup (Run in Terminal)
29
+
30
+ \`\`\`${K}
31
+ ${z}
32
+ \`\`\``)}F&&g.push(`## Python Code
33
+
34
+ \`\`\`python
35
+ ${F}
36
+ \`\`\``);const le=g.join(`
37
+
38
+ `);N(le,"All code copied as Markdown!")}Cs(async()=>{await Ne(),await ve()});function ne(){l=this.value,t(0,l)}const ot=()=>t(8,i=!i),Ze=g=>{g.disabled||(t(2,o=g.name),t(8,i=!1))},we=g=>Le({name:"Andrew",sample:"/voices/andrew.mp3"},g),De=()=>t(1,r="Andrew"),Ge=g=>Le({name:"Lily",sample:"/voices/lily.mp3"},g),it=()=>t(1,r="Lily"),et=g=>Le({name:"Pirate",sample:"/voices/pirate.mp3"},g),Me=()=>t(1,r="Pirate"),ae=g=>Le({name:"Yours",sample:O[0].sample_url},g),Ee=()=>t(1,r="Yours");function ct(){y=es(this.value),t(3,y)}function gt(){v=es(this.value),t(4,v)}const He=()=>t(21,he=!1),je=()=>t(6,V="api"),pl=()=>t(6,V="local"),tt=()=>N(z),Ke=()=>N(F);function lt(g){$s[g?"unshift":"push"](()=>{E=g,t(16,E)})}return s.$$.update=()=>{s.$$.dirty[0]&255&&(t(23,z=Re()),t(24,F=P()),t(7,G++,G))},[l,r,o,y,v,O,V,G,i,h,m,$,x,A,J,D,E,w,U,Y,pe,he,S,z,F,ee,me,Be,Fe,X,be,Pe,xe,Le,We,Ie,ye,at,N,W,ne,ot,Ze,we,De,Ge,it,et,Me,ae,Ee,ct,gt,He,je,pl,tt,Ke,lt]}class hn extends bs{constructor(e){super(),vs(this,e,an,nn,zl,{},null,[-1,-1,-1])}}export{hn as component};
hfstudio/static/_app/immutable/nodes/3.CX0V79eQ.js ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import{S as Pe,i as Ve,s as Ne,u as ve,v as ee,w as S,x,y as te,z as le,A as se,B as Ce,C as Ye,D as We,E as Xe,F as Ze,d as c,G as xe,p as u,H as _e,b as W,c as a,m as ce,I as st,h as M,e as h,f as g,r as ye,g as ne,J as Se,k as A,j as m,t as ae,K as rt,n as ot,P as He,Q as Me,a as we,N as be,T as nt,q as Le}from"../chunks/BaOlNwUz.js";import{g as at,C as Ie,P as Z,D as it}from"../chunks/Dj_MM6zE.js";import{I as et,g as tt,a as lt,e as Re,u as ct,o as ut}from"../chunks/C7BncMoR.js";import"../chunks/IHki7fMi.js";import{N as dt}from"../chunks/CbFjO8O8.js";import{P as ft,a as ht}from"../chunks/Bm0csYZC.js";function mt(o){let e;const t=o[2].default,l=Ye(t,o,o[3],null);return{c(){l&&l.c()},l(r){l&&l.l(r)},m(r,s){l&&l.m(r,s),e=!0},p(r,s){l&&l.p&&(!e||s&8)&&We(l,t,r,r[3],e?Ze(t,r[3],s,null):Xe(r[3]),null)},i(r){e||(x(l,r),e=!0)},o(r){S(l,r),e=!1},d(r){l&&l.d(r)}}}function pt(o){let e,t;const l=[{name:"rotate-ccw"},o[1],{iconNode:o[0]}];let r={$$slots:{default:[mt]},$$scope:{ctx:o}};for(let s=0;s<l.length;s+=1)r=ve(r,l[s]);return e=new et({props:r}),{c(){se(e.$$.fragment)},l(s){le(e.$$.fragment,s)},m(s,n){te(e,s,n),t=!0},p(s,[n]){const f=n&3?tt(l,[l[0],n&2&&lt(s[1]),n&1&&{iconNode:s[0]}]):{};n&8&&(f.$$scope={dirty:n,ctx:s}),e.$set(f)},i(s){t||(x(e.$$.fragment,s),t=!0)},o(s){S(e.$$.fragment,s),t=!1},d(s){ee(e,s)}}}function gt(o,e,t){let{$$slots:l={},$$scope:r}=e;const s=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8"}],["path",{d:"M3 3v5h5"}]];return o.$$set=n=>{t(1,e=ve(ve({},e),Ce(n))),"$$scope"in n&&t(3,r=n.$$scope)},e=Ce(e),[s,e,l,r]}class _t extends Pe{constructor(e){super(),Ve(this,e,gt,pt,Ne,{})}}function bt(o){let e;const t=o[2].default,l=Ye(t,o,o[3],null);return{c(){l&&l.c()},l(r){l&&l.l(r)},m(r,s){l&&l.m(r,s),e=!0},p(r,s){l&&l.p&&(!e||s&8)&&We(l,t,r,r[3],e?Ze(t,r[3],s,null):Xe(r[3]),null)},i(r){e||(x(l,r),e=!0)},o(r){S(l,r),e=!1},d(r){l&&l.d(r)}}}function vt(o){let e,t;const l=[{name:"share"},o[1],{iconNode:o[0]}];let r={$$slots:{default:[bt]},$$scope:{ctx:o}};for(let s=0;s<l.length;s+=1)r=ve(r,l[s]);return e=new et({props:r}),{c(){se(e.$$.fragment)},l(s){le(e.$$.fragment,s)},m(s,n){te(e,s,n),t=!0},p(s,[n]){const f=n&3?tt(l,[l[0],n&2&&lt(s[1]),n&1&&{iconNode:s[0]}]):{};n&8&&(f.$$scope={dirty:n,ctx:s}),e.$set(f)},i(s){t||(x(e.$$.fragment,s),t=!0)},o(s){S(e.$$.fragment,s),t=!1},d(s){ee(e,s)}}}function yt(o,e,t){let{$$slots:l={},$$scope:r}=e;const s=[["path",{d:"M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8"}],["polyline",{points:"16 6 12 2 8 6"}],["line",{x1:"12",x2:"12",y1:"2",y2:"15"}]];return o.$$set=n=>{t(1,e=ve(ve({},e),Ce(n))),"$$scope"in n&&t(3,r=n.$$scope)},e=Ce(e),[s,e,l,r]}class Et extends Pe{constructor(e){super(),Ve(this,e,yt,vt,Ne,{})}}const{document:ze}=at;function Ue(o,e,t){const l=o.slice();return l[25]=e[t],l[26]=e,l[27]=t,l}function kt(o){let e;return{c(){e=ae("Python code to reproduce your actions via the API")},l(t){e=ne(t,"Python code to reproduce your actions via the API")},m(t,l){W(t,e,l)},d(t){t&&c(e)}}}function wt(o){let e;return{c(){e=ae("Python code to reproduce your actions using a local HFStudio server")},l(t){e=ne(t,"Python code to reproduce your actions using a local HFStudio server")},m(t,l){W(t,e,l)},d(t){t&&c(e)}}}function je(o){let e,t,l,r,s,n="Reset history",f,$,E,I,_,O="Copy all as Markdown",k,y,w;return l=new _t({props:{size:16,class:"text-red-600"}}),E=new Ie({props:{size:16,class:"text-gray-600"}}),{c(){e=m("div"),t=m("button"),se(l.$$.fragment),r=A(),s=m("span"),s.textContent=n,f=A(),$=m("button"),se(E.$$.fragment),I=A(),_=m("span"),_.textContent=O,this.h()},l(p){e=h(p,"DIV",{class:!0});var v=g(e);t=h(v,"BUTTON",{class:!0,title:!0});var P=g(t);le(l.$$.fragment,P),r=M(P),s=h(P,"SPAN",{class:!0,"data-svelte-h":!0}),ye(s)!=="svelte-1x639i7"&&(s.textContent=n),P.forEach(c),f=M(v),$=h(v,"BUTTON",{class:!0});var D=g($);le(E.$$.fragment,D),I=M(D),_=h(D,"SPAN",{class:!0,"data-svelte-h":!0}),ye(_)!=="svelte-kfbkuj"&&(_.textContent=O),D.forEach(c),v.forEach(c),this.h()},h(){u(s,"class","ml-2 text-sm font-medium text-red-600"),u(t,"class","flex items-center bg-red-50 hover:bg-red-100 rounded-md px-3 py-1.5 transition-colors"),u(t,"title","Clear history"),u(_,"class","ml-2 text-sm font-medium text-gray-600"),u($,"class","flex items-center bg-gray-100 hover:bg-gray-200 rounded-md px-3 py-1.5 transition-colors"),u(e,"class","flex items-center gap-2")},m(p,v){W(p,e,v),a(e,t),te(l,t,null),a(t,r),a(t,s),a(e,f),a(e,$),te(E,$,null),a($,I),a($,_),k=!0,y||(w=[ce(t,"click",o[6]),ce($,"click",o[8])],y=!0)},p:ot,i(p){k||(x(l.$$.fragment,p),x(E.$$.fragment,p),k=!0)},o(p){S(l.$$.fragment,p),S(E.$$.fragment,p),k=!1},d(p){p&&c(e),ee(l),ee(E),y=!1,xe(w)}}}function Be(o){let e,t,l,r='<span class="text-sm font-medium text-amber-900">Setup (Run in Terminal)</span> <span class="text-xs bg-amber-100 text-amber-700 px-2 py-0.5 rounded">Run once</span>',s,n,f,$,E,I,_,O;f=new Ie({props:{size:14,class:"text-amber-600"}});function k(p,v){return p[2]==="pip install huggingface-hub"?Ct:$t}let y=k(o),w=y(o);return{c(){e=m("div"),t=m("div"),l=m("div"),l.innerHTML=r,s=A(),n=m("button"),se(f.$$.fragment),$=A(),E=m("div"),w.c(),this.h()},l(p){e=h(p,"DIV",{class:!0});var v=g(e);t=h(v,"DIV",{class:!0});var P=g(t);l=h(P,"DIV",{class:!0,"data-svelte-h":!0}),ye(l)!=="svelte-akzwnd"&&(l.innerHTML=r),s=M(P),n=h(P,"BUTTON",{class:!0,title:!0});var D=g(n);le(f.$$.fragment,D),D.forEach(c),P.forEach(c),$=M(v),E=h(v,"DIV",{class:!0});var H=g(E);w.l(H),H.forEach(c),v.forEach(c),this.h()},h(){u(l,"class","flex items-center gap-2"),u(n,"class","p-1.5 hover:bg-amber-100 rounded transition-colors"),u(n,"title","Copy setup code"),u(t,"class","flex items-center justify-between px-4 py-2 bg-amber-50 border-b border-amber-200"),u(E,"class","relative"),u(e,"class","bg-white rounded-lg border border-gray-200 overflow-hidden")},m(p,v){W(p,e,v),a(e,t),a(t,l),a(t,s),a(t,n),te(f,n,null),a(e,$),a(e,E),w.m(E,null),I=!0,_||(O=ce(n,"click",o[12]),_=!0)},p(p,v){y===(y=k(p))&&w?w.p(p,v):(w.d(1),w=y(p),w&&(w.c(),w.m(E,null)))},i(p){I||(x(f.$$.fragment,p),I=!0)},o(p){S(f.$$.fragment,p),I=!1},d(p){p&&c(e),ee(f),w.d(),_=!1,O()}}}function $t(o){let e,t,l,r=Z.highlight(o[2],Z.languages.bash,"bash")+"";return{c(){e=m("pre"),t=m("code"),l=new Me(!1),this.h()},l(s){e=h(s,"PRE",{class:!0});var n=g(e);t=h(n,"CODE",{class:!0});var f=g(t);l=He(f,!1),f.forEach(c),n.forEach(c),this.h()},h(){l.a=null,u(t,"class","language-bash text-sm"),u(e,"class","p-4 overflow-x-auto bg-gray-50")},m(s,n){W(s,e,n),a(e,t),l.m(r,t)},p(s,n){n&4&&r!==(r=Z.highlight(s[2],Z.languages.bash,"bash")+"")&&l.p(r)},d(s){s&&c(e)}}}function Ct(o){let e,t,l;return{c(){e=m("pre"),t=m("code"),l=ae(o[2]),this.h()},l(r){e=h(r,"PRE",{class:!0});var s=g(e);t=h(s,"CODE",{class:!0});var n=g(t);l=ne(n,o[2]),n.forEach(c),s.forEach(c),this.h()},h(){u(t,"class","language-bash text-sm text-black"),u(e,"class","p-4 overflow-x-auto bg-gray-50")},m(r,s){W(r,e,s),a(e,t),a(t,l)},p(r,s){s&4&&we(l,r[2])},d(r){r&&c(e)}}}function Fe(o){let e,t,l,r='<span class="text-sm font-medium text-blue-900">Imports (Python)</span> <span class="text-xs bg-blue-100 text-blue-700 px-2 py-0.5 rounded">Run once</span>',s,n,f,$,E,I,_,O,k=Z.highlight(o[3],Z.languages.python,"python")+"",y,w,p;return f=new Ie({props:{size:14,class:"text-blue-600"}}),{c(){e=m("div"),t=m("div"),l=m("div"),l.innerHTML=r,s=A(),n=m("button"),se(f.$$.fragment),$=A(),E=m("div"),I=m("pre"),_=m("code"),O=new Me(!1),this.h()},l(v){e=h(v,"DIV",{class:!0});var P=g(e);t=h(P,"DIV",{class:!0});var D=g(t);l=h(D,"DIV",{class:!0,"data-svelte-h":!0}),ye(l)!=="svelte-sun3yz"&&(l.innerHTML=r),s=M(D),n=h(D,"BUTTON",{class:!0,title:!0});var H=g(n);le(f.$$.fragment,H),H.forEach(c),D.forEach(c),$=M(P),E=h(P,"DIV",{class:!0});var B=g(E);I=h(B,"PRE",{class:!0});var Q=g(I);_=h(Q,"CODE",{class:!0});var K=g(_);O=He(K,!1),K.forEach(c),Q.forEach(c),B.forEach(c),P.forEach(c),this.h()},h(){u(l,"class","flex items-center gap-2"),u(n,"class","p-1.5 hover:bg-blue-100 rounded transition-colors"),u(n,"title","Copy import code"),u(t,"class","flex items-center justify-between px-4 py-2 bg-blue-50 border-b border-blue-200"),O.a=null,u(_,"class","language-python text-sm"),u(I,"class","p-4 overflow-x-auto bg-gray-50"),u(E,"class","relative"),u(e,"class","bg-white rounded-lg border border-gray-200 overflow-hidden")},m(v,P){W(v,e,P),a(e,t),a(t,l),a(t,s),a(t,n),te(f,n,null),a(e,$),a(e,E),a(E,I),a(I,_),O.m(k,_),y=!0,w||(p=ce(n,"click",o[13]),w=!0)},p(v,P){(!y||P&8)&&k!==(k=Z.highlight(v[3],Z.languages.python,"python")+"")&&O.p(k)},i(v){y||(x(f.$$.fragment,v),y=!0)},o(v){S(f.$$.fragment,v),y=!1},d(v){v&&c(e),ee(f),w=!1,p()}}}function Ge(o){let e,t='<p class="text-gray-500">Start using the UI to see generated code here</p>';return{c(){e=m("div"),e.innerHTML=t,this.h()},l(l){e=h(l,"DIV",{class:!0,"data-svelte-h":!0}),ye(e)!=="svelte-1v3062w"&&(e.innerHTML=t),this.h()},h(){u(e,"class","bg-white rounded-lg border border-gray-200 p-8 text-center")},m(l,r){W(l,e,r)},d(l){l&&c(e)}}}function qe(o){let e,t,l,r,s,n,f,$,E,I,_=(o[25].result.title||"Generated Audio")+"",O,k,y,w,p=Qe(o[25].result.duration||0)+"",v,P,D,H,B,Q,K,b,U,i,V,T=o[26],q=o[27],J,L,X;const ue=[Dt,It],ie=[];function Ee(N,Y){return N[25].isPlaying?0:1}n=Ee(o),f=ie[n]=ue[n](o);function ge(){return o[15](o[25])}B=new it({props:{size:16,class:"text-gray-600"}});function re(){return o[16](o[25])}b=new Et({props:{size:16,class:"text-gray-600"}});const R=()=>o[17](i,T,q),z=()=>o[17](null,T,q);function j(){return o[18](o[25],o[26],o[27])}return{c(){e=m("div"),t=m("div"),l=m("div"),r=m("div"),s=m("button"),f.c(),$=A(),E=m("div"),I=m("div"),O=ae(_),k=A(),y=m("div"),w=ae("Duration: "),v=ae(p),P=A(),D=m("div"),H=m("button"),se(B.$$.fragment),Q=A(),K=m("button"),se(b.$$.fragment),U=A(),i=m("audio"),this.h()},l(N){e=h(N,"DIV",{class:!0});var Y=g(e);t=h(Y,"DIV",{class:!0});var oe=g(t);l=h(oe,"DIV",{class:!0});var F=g(l);r=h(F,"DIV",{class:!0});var d=g(r);s=h(d,"BUTTON",{class:!0});var C=g(s);f.l(C),C.forEach(c),$=M(d),E=h(d,"DIV",{class:!0});var G=g(E);I=h(G,"DIV",{class:!0});var me=g(I);O=ne(me,_),me.forEach(c),k=M(G),y=h(G,"DIV",{class:!0});var fe=g(y);w=ne(fe,"Duration: "),v=ne(fe,p),fe.forEach(c),G.forEach(c),d.forEach(c),P=M(F),D=h(F,"DIV",{class:!0});var de=g(D);H=h(de,"BUTTON",{class:!0,title:!0});var ke=g(H);le(B.$$.fragment,ke),ke.forEach(c),Q=M(de),K=h(de,"BUTTON",{class:!0,title:!0});var pe=g(K);le(b.$$.fragment,pe),pe.forEach(c),de.forEach(c),F.forEach(c),U=M(oe),i=h(oe,"AUDIO",{src:!0,class:!0}),g(i).forEach(c),oe.forEach(c),Y.forEach(c),this.h()},h(){u(s,"class","w-10 h-10 bg-gradient-to-r from-amber-500 to-orange-500 rounded-full flex items-center justify-center text-white hover:from-amber-600 hover:to-orange-600 transition-colors shadow-md"),u(I,"class","text-sm font-medium text-gray-900 truncate"),u(y,"class","text-xs text-gray-500"),u(E,"class","flex-1"),u(r,"class","flex items-center gap-3 flex-1"),u(H,"class","p-2 hover:bg-gray-100 rounded-lg transition-colors"),u(H,"title","Download"),u(K,"class","p-2 hover:bg-gray-100 rounded-lg transition-colors"),u(K,"title","Share"),u(D,"class","flex items-center gap-1"),u(l,"class","flex items-center justify-between"),Le(i.src,V=o[25].result.url)||u(i,"src",V),u(i,"class","hidden"),u(t,"class","bg-white rounded-lg border border-gray-200 p-4 shadow-sm"),u(e,"class","bg-gradient-to-b from-gray-50 to-white p-4")},m(N,Y){W(N,e,Y),a(e,t),a(t,l),a(l,r),a(r,s),ie[n].m(s,null),a(r,$),a(r,E),a(E,I),a(I,O),a(E,k),a(E,y),a(y,w),a(y,v),a(l,P),a(l,D),a(D,H),te(B,H,null),a(D,Q),a(D,K),te(b,K,null),a(t,U),a(t,i),R(),J=!0,L||(X=[ce(s,"click",ge),ce(H,"click",re),ce(i,"ended",j)],L=!0)},p(N,Y){o=N;let oe=n;n=Ee(o),n!==oe&&(be(),S(ie[oe],1,1,()=>{ie[oe]=null}),_e(),f=ie[n],f||(f=ie[n]=ue[n](o),f.c()),x(f,1),f.m(s,null)),(!J||Y&2)&&_!==(_=(o[25].result.title||"Generated Audio")+"")&&we(O,_),(!J||Y&2)&&p!==(p=Qe(o[25].result.duration||0)+"")&&we(v,p),(!J||Y&2&&!Le(i.src,V=o[25].result.url))&&u(i,"src",V),(T!==o[26]||q!==o[27])&&(z(),T=o[26],q=o[27],R())},i(N){J||(x(f),x(B.$$.fragment,N),x(b.$$.fragment,N),J=!0)},o(N){S(f),S(B.$$.fragment,N),S(b.$$.fragment,N),J=!1},d(N){N&&c(e),ie[n].d(),ee(B),ee(b),z(),L=!1,xe(X)}}}function It(o){let e,t;return e=new ht({props:{size:18,class:"ml-0.5"}}),{c(){se(e.$$.fragment)},l(l){le(e.$$.fragment,l)},m(l,r){te(e,l,r),t=!0},i(l){t||(x(e.$$.fragment,l),t=!0)},o(l){S(e.$$.fragment,l),t=!1},d(l){ee(e,l)}}}function Dt(o){let e,t;return e=new ft({props:{size:18}}),{c(){se(e.$$.fragment)},l(l){le(e.$$.fragment,l)},m(l,r){te(e,l,r),t=!0},i(l){t||(x(e.$$.fragment,l),t=!0)},o(l){S(e.$$.fragment,l),t=!1},d(l){ee(e,l)}}}function Ke(o,e){let t,l,r,s,n,f=e[27]+1+"",$,E,I,_,O,k,y,w,p,v=Z.highlight(e[25].code,Z.languages.python,"python")+"",P,D,H,B,Q;_=new Ie({props:{size:14,class:"text-gray-600"}});function K(){return e[14](e[25])}let b=e[25].result&&e[25].result.type==="audio"&&qe(e);return{key:o,first:null,c(){t=m("div"),l=m("div"),r=m("div"),s=m("span"),n=ae("Cell "),$=ae(f),E=A(),I=m("button"),se(_.$$.fragment),O=A(),k=m("div"),y=m("pre"),w=m("code"),p=new Me(!1),P=A(),b&&b.c(),D=A(),this.h()},l(U){t=h(U,"DIV",{class:!0});var i=g(t);l=h(i,"DIV",{class:!0});var V=g(l);r=h(V,"DIV",{class:!0});var T=g(r);s=h(T,"SPAN",{class:!0});var q=g(s);n=ne(q,"Cell "),$=ne(q,f),q.forEach(c),E=M(T),I=h(T,"BUTTON",{class:!0,title:!0});var J=g(I);le(_.$$.fragment,J),J.forEach(c),T.forEach(c),O=M(V),k=h(V,"DIV",{class:!0});var L=g(k);y=h(L,"PRE",{class:!0});var X=g(y);w=h(X,"CODE",{class:!0});var ue=g(w);p=He(ue,!1),ue.forEach(c),X.forEach(c),L.forEach(c),V.forEach(c),P=M(i),b&&b.l(i),D=M(i),i.forEach(c),this.h()},h(){u(s,"class","text-sm font-medium text-gray-700"),u(I,"class","p-1.5 hover:bg-gray-200 rounded transition-colors"),u(I,"title","Copy code"),u(r,"class","flex items-center justify-between px-4 py-2 bg-gray-50 border-b border-gray-100"),p.a=null,u(w,"class","language-python text-sm"),u(y,"class","p-4 overflow-x-auto bg-gray-50"),u(k,"class","relative"),u(l,"class","border-b border-gray-200"),u(t,"class","bg-white rounded-lg border border-gray-200 overflow-hidden shadow-sm"),this.first=t},m(U,i){W(U,t,i),a(t,l),a(l,r),a(r,s),a(s,n),a(s,$),a(r,E),a(r,I),te(_,I,null),a(l,O),a(l,k),a(k,y),a(y,w),p.m(v,w),a(t,P),b&&b.m(t,null),a(t,D),H=!0,B||(Q=ce(I,"click",K),B=!0)},p(U,i){e=U,(!H||i&2)&&f!==(f=e[27]+1+"")&&we($,f),(!H||i&2)&&v!==(v=Z.highlight(e[25].code,Z.languages.python,"python")+"")&&p.p(v),e[25].result&&e[25].result.type==="audio"?b?(b.p(e,i),i&2&&x(b,1)):(b=qe(e),b.c(),x(b,1),b.m(t,D)):b&&(be(),S(b,1,1,()=>{b=null}),_e())},i(U){H||(x(_.$$.fragment,U),x(b),H=!0)},o(U){S(_.$$.fragment,U),S(b),H=!1},d(U){U&&c(t),ee(_),b&&b.d(),B=!1,Q()}}}function Je(o){let e,t;return{c(){e=m("div"),t=ae(o[4]),this.h()},l(l){e=h(l,"DIV",{class:!0});var r=g(e);t=ne(r,o[4]),r.forEach(c),this.h()},h(){u(e,"class","fixed bottom-4 right-4 px-4 py-2 bg-gray-900 text-white rounded-lg shadow-lg z-50 animate-fade-in svelte-1vrx3m3")},m(l,r){W(l,e,r),a(e,t)},p(l,r){r&16&&we(t,l[4])},d(l){l&&c(e)}}}function Tt(o){let e,t,l,r,s,n,f,$,E="Code Recorder",I,_,O,k,y,w,p,v,P,D,H,B,Q,K,b,U,i,V,T=[],q=new Map,J,L,X,ue,ie;l=new dt({props:{historyCount:o[5]}});function Ee(d,C){return d[0]==="local"?wt:kt}let ge=Ee(o),re=ge(o),R=(o[1].length>0||o[2]||o[3])&&je(o),z=o[2]&&Be(o),j=o[3]&&Fe(o),N=!o[3]&&o[1].length===0&&Ge(),Y=Re(o[1]);const oe=d=>d[25].id;for(let d=0;d<Y.length;d+=1){let C=Ue(o,Y,d),G=oe(C);q.set(G,T[d]=Ke(G,C))}let F=o[4]&&Je(o);return{c(){e=A(),t=m("div"),se(l.$$.fragment),r=A(),s=m("div"),n=m("div"),f=m("div"),$=m("h2"),$.textContent=E,I=A(),_=m("p"),re.c(),O=A(),k=m("div"),y=m("div"),w=m("button"),p=ae("API"),P=A(),D=m("button"),H=ae("Local"),Q=A(),R&&R.c(),K=A(),b=m("div"),z&&z.c(),U=A(),j&&j.c(),i=A(),N&&N.c(),V=A();for(let d=0;d<T.length;d+=1)T[d].c();J=A(),F&&F.c(),L=Se(),this.h()},l(d){st("svelte-1s75m5n",ze.head).forEach(c),e=M(d),t=h(d,"DIV",{class:!0});var G=g(t);le(l.$$.fragment,G),r=M(G),s=h(G,"DIV",{class:!0});var me=g(s);n=h(me,"DIV",{class:!0});var fe=g(n);f=h(fe,"DIV",{});var de=g(f);$=h(de,"H2",{class:!0,"data-svelte-h":!0}),ye($)!=="svelte-8fx49i"&&($.textContent=E),I=M(de),_=h(de,"P",{class:!0});var ke=g(_);re.l(ke),ke.forEach(c),de.forEach(c),O=M(fe),k=h(fe,"DIV",{class:!0});var pe=g(k);y=h(pe,"DIV",{class:!0});var $e=g(y);w=h($e,"BUTTON",{class:!0});var Ae=g(w);p=ne(Ae,"API"),Ae.forEach(c),P=M($e),D=h($e,"BUTTON",{class:!0});var Oe=g(D);H=ne(Oe,"Local"),Oe.forEach(c),$e.forEach(c),Q=M(pe),R&&R.l(pe),pe.forEach(c),fe.forEach(c),K=M(me),b=h(me,"DIV",{class:!0});var he=g(b);z&&z.l(he),U=M(he),j&&j.l(he),i=M(he),N&&N.l(he),V=M(he);for(let De=0;De<T.length;De+=1)T[De].l(he);he.forEach(c),me.forEach(c),G.forEach(c),J=M(d),F&&F.l(d),L=Se(),this.h()},h(){ze.title="Code Recorder - HFStudio",u($,"class","text-2xl font-semibold text-gray-900"),u(_,"class","text-sm text-gray-600 mt-1"),u(w,"class",v="px-3 py-1 text-sm font-medium rounded transition-colors "+(o[0]==="api"?"bg-white shadow-sm":"text-gray-600")),u(D,"class",B="px-3 py-1 text-sm font-medium rounded transition-colors "+(o[0]==="local"?"bg-white shadow-sm":"text-gray-600")),u(y,"class","flex items-center bg-gray-100 rounded-md p-0.5"),u(k,"class","flex items-center justify-between mt-4"),u(n,"class","mb-6"),u(b,"class","space-y-6"),u(s,"class","max-w-4xl mx-auto p-8"),u(t,"class","flex-1 bg-gray-50 overflow-y-auto")},m(d,C){W(d,e,C),W(d,t,C),te(l,t,null),a(t,r),a(t,s),a(s,n),a(n,f),a(f,$),a(f,I),a(f,_),re.m(_,null),a(n,O),a(n,k),a(k,y),a(y,w),a(w,p),a(y,P),a(y,D),a(D,H),a(k,Q),R&&R.m(k,null),a(s,K),a(s,b),z&&z.m(b,null),a(b,U),j&&j.m(b,null),a(b,i),N&&N.m(b,null),a(b,V);for(let G=0;G<T.length;G+=1)T[G]&&T[G].m(b,null);W(d,J,C),F&&F.m(d,C),W(d,L,C),X=!0,ue||(ie=[ce(w,"click",o[10]),ce(D,"click",o[11])],ue=!0)},p(d,[C]){const G={};C&32&&(G.historyCount=d[5]),l.$set(G),ge!==(ge=Ee(d))&&(re.d(1),re=ge(d),re&&(re.c(),re.m(_,null))),(!X||C&1&&v!==(v="px-3 py-1 text-sm font-medium rounded transition-colors "+(d[0]==="api"?"bg-white shadow-sm":"text-gray-600")))&&u(w,"class",v),(!X||C&1&&B!==(B="px-3 py-1 text-sm font-medium rounded transition-colors "+(d[0]==="local"?"bg-white shadow-sm":"text-gray-600")))&&u(D,"class",B),d[1].length>0||d[2]||d[3]?R?(R.p(d,C),C&14&&x(R,1)):(R=je(d),R.c(),x(R,1),R.m(k,null)):R&&(be(),S(R,1,1,()=>{R=null}),_e()),d[2]?z?(z.p(d,C),C&4&&x(z,1)):(z=Be(d),z.c(),x(z,1),z.m(b,U)):z&&(be(),S(z,1,1,()=>{z=null}),_e()),d[3]?j?(j.p(d,C),C&8&&x(j,1)):(j=Fe(d),j.c(),x(j,1),j.m(b,i)):j&&(be(),S(j,1,1,()=>{j=null}),_e()),!d[3]&&d[1].length===0?N||(N=Ge(),N.c(),N.m(b,V)):N&&(N.d(1),N=null),C&642&&(Y=Re(d[1]),be(),T=ct(T,C,oe,1,d,Y,q,b,ut,Ke,null,Ue),_e()),d[4]?F?F.p(d,C):(F=Je(d),F.c(),F.m(L.parentNode,L)):F&&(F.d(1),F=null)},i(d){if(!X){x(l.$$.fragment,d),x(R),x(z),x(j);for(let C=0;C<Y.length;C+=1)x(T[C]);X=!0}},o(d){S(l.$$.fragment,d),S(R),S(z),S(j);for(let C=0;C<T.length;C+=1)S(T[C]);X=!1},d(d){d&&(c(e),c(t),c(J),c(L)),ee(l),re.d(),R&&R.d(),z&&z.d(),j&&j.d(),N&&N.d();for(let C=0;C<T.length;C+=1)T[C].d();F&&F.d(d),ue=!1,xe(ie)}}}let Te="Chatterbox";function Pt(o,e){const t=document.createElement("a");t.href=o,t.download=`${e||"audio"}.wav`,document.body.appendChild(t),t.click(),document.body.removeChild(t)}function Qe(o){if(!o)return"0:00";const e=Math.floor(o/60),t=Math.floor(o%60);return`${e}:${t.toString().padStart(2,"0")}`}function Vt(o,e,t){let l="api",r=[],s=_(),n=k(),f=null,$=0;async function E(){try{const i=await fetch("/api/history/load",{method:"GET",credentials:"include"});if(i.ok){const V=await i.json(),T=V.entries.filter(L=>L.entry_type==="setup"),q=V.entries.filter(L=>L.entry_type==="import"),J=V.entries.filter(L=>L.entry_type==="generation");t(2,s=_()),t(3,n=q.length>0?q[q.length-1].code:k()),t(1,r=J.map(L=>({id:L.id,code:L.code,result:L.result_data}))),t(5,$=J.length)}}catch(i){console.error("Error loading history from database:",i),t(1,r=[]),t(2,s=_()),t(3,n=k())}}async function I(){try{await fetch("/api/history/clear",{method:"DELETE",credentials:"include"}),t(1,r=[]),t(2,s=_()),t(3,n=k()),t(5,$=0)}catch(i){console.error("Error clearing history:",i),t(1,r=[]),t(2,s=_()),t(3,n=k()),t(5,$=0)}}function _(){return l==="local"?`pip install huggingface-hub hfstudio uv
2
+ hfstudio start ${Te.toLowerCase()} --port 7861`:"pip install huggingface-hub"}function O(){return l==="local"?'client = InferenceClient(base_url="http://localhost:7861/api/v1")':`client = InferenceClient(
3
+ api_key="YOUR_HF_TOKEN", # Get your token from https://huggingface.co/settings/tokens
4
+ model="${Te.toLowerCase()==="chatterbox"?"ResembleAI/chatterbox":Te.toLowerCase()}",
5
+ )`}function k(){const i=O();return l==="local"?`from huggingface_hub import InferenceClient
6
+
7
+ ${i}`:`from huggingface_hub import InferenceClient
8
+
9
+ ${i}`}function y(i,V="Copied to clipboard!"){navigator.clipboard.writeText(i).then(()=>{t(4,f=V),setTimeout(()=>{t(4,f=null)},2e3)})}function w(){const i=[];if(s){const q=s.includes("pip install")||s.includes("hfstudio start")?"bash":"";i.push(`## Setup (Run in Terminal)
10
+
11
+ \`\`\`${q}
12
+ ${s}
13
+ \`\`\``)}n&&i.push(`## Imports (Python)
14
+
15
+ \`\`\`python
16
+ ${n}
17
+ \`\`\``),r.forEach((T,q)=>{i.push(`## Cell ${q+1}
18
+
19
+ \`\`\`python
20
+ ${T.code}
21
+ \`\`\``)});const V=i.join(`
22
+
23
+ `);y(V,"All code copied as Markdown!")}function p(i){i.audioElement||(i.audioElement=new Audio(i.result.url),i.audioElement.addEventListener("ended",()=>{i.isPlaying=!1,t(1,r=[...r])})),i.isPlaying?(i.audioElement.pause(),i.isPlaying=!1):(r.forEach(V=>{V!==i&&V.isPlaying&&V.audioElement&&(V.audioElement.pause(),V.isPlaying=!1)}),i.audioElement.play(),i.isPlaying=!0),t(1,r=[...r])}rt(async()=>{await E()});const v=()=>t(0,l="api"),P=()=>t(0,l="local"),D=()=>y(s),H=()=>y(n),B=i=>y(i.code),Q=i=>p(i),K=i=>Pt(i.result.url,i.result.title);function b(i,V,T){nt[i?"unshift":"push"](()=>{V[T].audioElement=i,t(1,r)})}const U=(i,V,T)=>t(1,V[T].isPlaying=!1,r);return o.$$.update=()=>{o.$$.dirty&1&&l&&(t(2,s=_()),t(3,n=k()))},[l,r,s,n,f,$,I,y,w,p,v,P,D,H,B,Q,K,b,U]}class St extends Pe{constructor(e){super(),Ve(this,e,Vt,Tt,Ne,{})}}export{St as component};
hfstudio/static/_app/immutable/nodes/4.Blz4Bme4.js ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import{S as Rt,i as Nt,s as Ut,u as nt,v as ge,w as z,x as V,y as be,z as ve,A as ye,B as Et,C as Bt,D as Ot,E as qt,F as Ft,d as u,G as at,a as Ie,H as Se,p as d,b as O,c,m as Pe,I as Gt,h as T,e as h,f as b,r as we,g as q,J as Je,k as I,j as p,t as F,K as Yt,L as ee,n as He,M as At,N as Le,q as Dt}from"../chunks/BaOlNwUz.js";import{I as Jt,g as Kt,a as Wt,e as rt}from"../chunks/C7BncMoR.js";import"../chunks/IHki7fMi.js";import{S as Xt,L as it,A as Qt,X as jt}from"../chunks/BV8rDFhh.js";import{M as Ht}from"../chunks/4G_mFUFB.js";import{P as Zt,a as er}from"../chunks/Bm0csYZC.js";function tr(s){let t;const e=s[2].default,r=Bt(e,s,s[3],null);return{c(){r&&r.c()},l(l){r&&r.l(l)},m(l,o){r&&r.m(l,o),t=!0},p(l,o){r&&r.p&&(!t||o&8)&&Ot(r,e,l,l[3],t?Ft(e,l[3],o,null):qt(l[3]),null)},i(l){t||(V(r,l),t=!0)},o(l){z(r,l),t=!1},d(l){r&&r.d(l)}}}function rr(s){let t,e;const r=[{name:"square"},s[1],{iconNode:s[0]}];let l={$$slots:{default:[tr]},$$scope:{ctx:s}};for(let o=0;o<r.length;o+=1)l=nt(l,r[o]);return t=new Jt({props:l}),{c(){ye(t.$$.fragment)},l(o){ve(t.$$.fragment,o)},m(o,n){be(t,o,n),e=!0},p(o,[n]){const i=n&3?Kt(r,[r[0],n&2&&Wt(o[1]),n&1&&{iconNode:o[0]}]):{};n&8&&(i.$$scope={dirty:n,ctx:o}),t.$set(i)},i(o){e||(V(t.$$.fragment,o),e=!0)},o(o){z(t.$$.fragment,o),e=!1},d(o){ge(t,o)}}}function lr(s,t,e){let{$$slots:r={},$$scope:l}=t;const o=[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2"}]];return s.$$set=n=>{e(1,t=nt(nt({},t),Et(n))),"$$scope"in n&&e(3,l=n.$$scope)},t=Et(t),[o,t,r,l]}class sr extends Rt{constructor(t){super(),Nt(this,t,lr,rr,Ut,{})}}function xt(s,t,e){const r=s.slice();return r[46]=t[e],r[48]=e,r}function Tt(s,t,e){const r=s.slice();return r[49]=t[e],r}function It(s){let t,e,r,l,o,n;return{c(){t=p("div"),e=p("div"),r=I(),l=p("div"),o=I(),n=p("div"),this.h()},l(i){t=h(i,"DIV",{class:!0});var a=b(t);e=h(a,"DIV",{class:!0,style:!0}),b(e).forEach(u),r=T(a),l=h(a,"DIV",{class:!0,style:!0}),b(l).forEach(u),o=T(a),n=h(a,"DIV",{class:!0,style:!0}),b(n).forEach(u),a.forEach(u),this.h()},h(){d(e,"class","absolute rounded-full border-2 border-orange-300 transition-all duration-75"),ee(e,"width",120+s[7]*120+"px"),ee(e,"height",120+s[7]*120+"px"),ee(e,"opacity",.4+s[7]*.6),d(l,"class","absolute rounded-full border-2 border-orange-200 transition-all duration-100"),ee(l,"width",150+s[7]*150+"px"),ee(l,"height",150+s[7]*150+"px"),ee(l,"opacity",.3+s[7]*.5),d(n,"class","absolute rounded-full border-1 border-orange-100 transition-all duration-125"),ee(n,"width",180+s[7]*180+"px"),ee(n,"height",180+s[7]*180+"px"),ee(n,"opacity",.2+s[7]*.4),d(t,"class","absolute inset-0 flex items-center justify-center")},m(i,a){O(i,t,a),c(t,e),c(t,r),c(t,l),c(t,o),c(t,n)},p(i,a){a[0]&128&&ee(e,"width",120+i[7]*120+"px"),a[0]&128&&ee(e,"height",120+i[7]*120+"px"),a[0]&128&&ee(e,"opacity",.4+i[7]*.6),a[0]&128&&ee(l,"width",150+i[7]*150+"px"),a[0]&128&&ee(l,"height",150+i[7]*150+"px"),a[0]&128&&ee(l,"opacity",.3+i[7]*.5),a[0]&128&&ee(n,"width",180+i[7]*180+"px"),a[0]&128&&ee(n,"height",180+i[7]*180+"px"),a[0]&128&&ee(n,"opacity",.2+i[7]*.4)},d(i){i&&u(t)}}}function or(s){let t,e;return t=new Ht({props:{size:36,class:"text-white"}}),{c(){ye(t.$$.fragment)},l(r){ve(t.$$.fragment,r)},m(r,l){be(t,r,l),e=!0},p:He,i(r){e||(V(t.$$.fragment,r),e=!0)},o(r){z(t.$$.fragment,r),e=!1},d(r){ge(t,r)}}}function nr(s){let t,e,r,l;return r=new sr({props:{size:36,class:(s[6]>=100?"text-white":"text-orange-700")+" relative z-10"}}),{c(){t=p("div"),e=I(),ye(r.$$.fragment),this.h()},l(o){t=h(o,"DIV",{class:!0,style:!0}),b(t).forEach(u),e=T(o),ve(r.$$.fragment,o),this.h()},h(){d(t,"class","absolute bottom-0 left-0 right-0 bg-orange-500 transition-all duration-100 ease-linear rounded-full"),ee(t,"height",s[6]+"%")},m(o,n){O(o,t,n),O(o,e,n),be(r,o,n),l=!0},p(o,n){(!l||n[0]&64)&&ee(t,"height",o[6]+"%");const i={};n[0]&64&&(i.class=(o[6]>=100?"text-white":"text-orange-700")+" relative z-10"),r.$set(i)},i(o){l||(V(r.$$.fragment,o),l=!0)},o(o){z(r.$$.fragment,o),l=!1},d(o){o&&(u(t),u(e)),ge(r,o)}}}function Vt(s){let t,e,r='<svg class="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path></svg>',l,o,n='Hugging Face <span class="bg-gradient-to-r from-purple-500 via-pink-500 via-green-500 to-blue-500 bg-clip-text text-transparent font-bold">PRO</span>',i,a,v=`Sign in to with your Hugging Face <a href="https://huggingface.co/pro" target="_blank" class="text-amber-600 hover:text-amber-700 underline font-medium">PRO account</a> to get started with $2 of free API credits per month. You can add a billing method for
2
+ additional pay-as-you-go usage ⤴`,_,y;return{c(){t=p("div"),e=p("button"),e.innerHTML=r,l=I(),o=p("p"),o.innerHTML=n,i=I(),a=p("p"),a.innerHTML=v,this.h()},l(m){t=h(m,"DIV",{class:!0});var k=b(t);e=h(k,"BUTTON",{class:!0,"aria-label":!0,"data-svelte-h":!0}),we(e)!=="svelte-1ywh7al"&&(e.innerHTML=r),l=T(k),o=h(k,"P",{class:!0,"data-svelte-h":!0}),we(o)!=="svelte-1k9uu9c"&&(o.innerHTML=n),i=T(k),a=h(k,"P",{class:!0,"data-svelte-h":!0}),we(a)!=="svelte-tylx6o"&&(a.innerHTML=v),k.forEach(u),this.h()},h(){d(e,"class","absolute top-2 right-2 text-gray-400 hover:text-gray-600 transition-colors"),d(e,"aria-label","Dismiss"),d(o,"class","text-sm font-medium text-gray-700 mb-1 pr-4"),d(a,"class","text-sm text-gray-600 pr-4"),d(t,"class","mb-3 px-3 py-2 bg-gradient-to-r from-amber-50 to-orange-50 rounded-lg border border-amber-200 relative")},m(m,k){O(m,t,k),c(t,e),c(t,l),c(t,o),c(t,i),c(t,a),_||(y=Pe(e,"click",s[28]),_=!0)},p:He,d(m){m&&u(t),_=!1,y()}}}function Ct(s){let t,e,r="Your Voices",l,o,n,i=rt(s[14]),a=[];for(let _=0;_<i.length;_+=1)a[_]=St(Tt(s,i,_));const v=_=>z(a[_],1,1,()=>{a[_]=null});return{c(){t=p("div"),e=p("h3"),e.textContent=r,l=I(),o=p("div");for(let _=0;_<a.length;_+=1)a[_].c();this.h()},l(_){t=h(_,"DIV",{class:!0});var y=b(t);e=h(y,"H3",{class:!0,"data-svelte-h":!0}),we(e)!=="svelte-is6ybk"&&(e.textContent=r),l=T(y),o=h(y,"DIV",{class:!0});var m=b(o);for(let k=0;k<a.length;k+=1)a[k].l(m);m.forEach(u),y.forEach(u),this.h()},h(){d(e,"class","text-sm font-medium text-gray-700 mb-3"),d(o,"class","space-y-2"),d(t,"class","mb-6")},m(_,y){O(_,t,y),c(t,e),c(t,l),c(t,o);for(let m=0;m<a.length;m+=1)a[m]&&a[m].m(o,null);n=!0},p(_,y){if(y[0]&134266880){i=rt(_[14]);let m;for(m=0;m<i.length;m+=1){const k=Tt(_,i,m);a[m]?(a[m].p(k,y),V(a[m],1)):(a[m]=St(k),a[m].c(),V(a[m],1),a[m].m(o,null))}for(Le(),m=i.length;m<a.length;m+=1)v(m);Se()}},i(_){if(!n){for(let y=0;y<i.length;y+=1)V(a[y]);n=!0}},o(_){a=a.filter(Boolean);for(let y=0;y<a.length;y+=1)z(a[y]);n=!1},d(_){_&&u(t),At(a,_)}}}function ar(s){let t,e;return t=new jt({props:{size:14}}),{c(){ye(t.$$.fragment)},l(r){ve(t.$$.fragment,r)},m(r,l){be(t,r,l),e=!0},i(r){e||(V(t.$$.fragment,r),e=!0)},o(r){z(t.$$.fragment,r),e=!1},d(r){ge(t,r)}}}function ir(s){let t,e;return t=new it({props:{size:14,class:"animate-spin"}}),{c(){ye(t.$$.fragment)},l(r){ve(t.$$.fragment,r)},m(r,l){be(t,r,l),e=!0},i(r){e||(V(t.$$.fragment,r),e=!0)},o(r){z(t.$$.fragment,r),e=!1},d(r){ge(t,r)}}}function St(s){let t,e,r,l=s[49].voice_name+"",o,n,i,a,v,_,y,m,k,S,j,D,K,$=new Date(s[49].expires_at).toLocaleDateString()+"",C,G,B=new Date(s[49].expires_at).toLocaleTimeString()+"",R,Q,P,N,E;const A=[ir,ar],J=[];function H(x,g){return x[15]?0:1}k=H(s),S=J[k]=A[k](s);function ne(){return s[29](s[49])}return{c(){t=p("div"),e=p("div"),r=p("span"),o=F(l),n=I(),i=p("div"),a=p("audio"),v=p("source"),y=I(),m=p("button"),S.c(),j=I(),D=p("div"),K=F("Expires: "),C=F($),G=F(" at "),R=F(B),Q=I(),this.h()},l(x){t=h(x,"DIV",{class:!0});var g=b(t);e=h(g,"DIV",{class:!0});var M=b(e);r=h(M,"SPAN",{class:!0});var le=b(r);o=q(le,l),le.forEach(u),n=T(M),i=h(M,"DIV",{class:!0});var W=b(i);a=h(W,"AUDIO",{class:!0,style:!0});var Y=b(a);v=h(Y,"SOURCE",{src:!0,type:!0}),Y.forEach(u),y=T(W),m=h(W,"BUTTON",{class:!0,title:!0});var X=b(m);S.l(X),X.forEach(u),W.forEach(u),M.forEach(u),j=T(g),D=h(g,"DIV",{class:!0});var Ee=b(D);K=q(Ee,"Expires: "),C=q(Ee,$),G=q(Ee," at "),R=q(Ee,B),Ee.forEach(u),Q=T(g),g.forEach(u),this.h()},h(){d(r,"class","text-sm font-medium text-blue-900"),Dt(v.src,_=s[49].voice_url)||d(v,"src",_),d(v,"type","audio/wav"),a.controls=!0,d(a,"class","h-8"),ee(a,"max-width","120px"),m.disabled=s[15],d(m,"class","p-1 text-red-600 hover:text-red-800 hover:bg-red-100 rounded transition-colors disabled:opacity-50"),d(m,"title","Delete voice"),d(i,"class","flex items-center gap-2"),d(e,"class","flex items-center justify-between mb-2"),d(D,"class","text-xs text-blue-600"),d(t,"class","border rounded-lg p-3 bg-blue-50 border-blue-200")},m(x,g){O(x,t,g),c(t,e),c(e,r),c(r,o),c(e,n),c(e,i),c(i,a),c(a,v),c(i,y),c(i,m),J[k].m(m,null),c(t,j),c(t,D),c(D,K),c(D,C),c(D,G),c(D,R),c(t,Q),P=!0,N||(E=Pe(m,"click",ne),N=!0)},p(x,g){s=x,(!P||g[0]&16384)&&l!==(l=s[49].voice_name+"")&&Ie(o,l),(!P||g[0]&16384&&!Dt(v.src,_=s[49].voice_url))&&d(v,"src",_);let M=k;k=H(s),k!==M&&(Le(),z(J[M],1,1,()=>{J[M]=null}),Se(),S=J[k],S||(S=J[k]=A[k](s),S.c()),V(S,1),S.m(m,null)),(!P||g[0]&32768)&&(m.disabled=s[15]),(!P||g[0]&16384)&&$!==($=new Date(s[49].expires_at).toLocaleDateString()+"")&&Ie(C,$),(!P||g[0]&16384)&&B!==(B=new Date(s[49].expires_at).toLocaleTimeString()+"")&&Ie(R,B)},i(x){P||(V(S),P=!0)},o(x){z(S),P=!1},d(x){x&&u(t),J[k].d(),N=!1,E()}}}function cr(s){let t,e,r=rt(s[1]),l=[];for(let n=0;n<r.length;n+=1)l[n]=Lt(xt(s,r,n));const o=n=>z(l[n],1,1,()=>{l[n]=null});return{c(){t=p("div");for(let n=0;n<l.length;n+=1)l[n].c();this.h()},l(n){t=h(n,"DIV",{class:!0});var i=b(t);for(let a=0;a<l.length;a+=1)l[a].l(i);i.forEach(u),this.h()},h(){d(t,"class","space-y-2")},m(n,i){O(n,t,i);for(let a=0;a<l.length;a+=1)l[a]&&l[a].m(t,null);e=!0},p(n,i){if(i[0]&50332422){r=rt(n[1]);let a;for(a=0;a<r.length;a+=1){const v=xt(n,r,a);l[a]?(l[a].p(v,i),V(l[a],1)):(l[a]=Lt(v),l[a].c(),V(l[a],1),l[a].m(t,null))}for(Le(),a=r.length;a<l.length;a+=1)o(a);Se()}},i(n){if(!e){for(let i=0;i<r.length;i+=1)V(l[i]);e=!0}},o(n){l=l.filter(Boolean);for(let i=0;i<l.length;i+=1)z(l[i]);e=!1},d(n){n&&u(t),At(l,n)}}}function ur(s){let t,e,r,l,o="Pick a recording to clone",n,i,a="No recordings yet",v;return e=new Ht({props:{size:32,class:"mx-auto mb-2 opacity-30"}}),{c(){t=p("div"),ye(e.$$.fragment),r=I(),l=p("p"),l.textContent=o,n=I(),i=p("p"),i.textContent=a,this.h()},l(_){t=h(_,"DIV",{class:!0});var y=b(t);ve(e.$$.fragment,y),r=T(y),l=h(y,"P",{class:!0,"data-svelte-h":!0}),we(l)!=="svelte-faot34"&&(l.textContent=o),n=T(y),i=h(y,"P",{class:!0,"data-svelte-h":!0}),we(i)!=="svelte-kwlxsz"&&(i.textContent=a),y.forEach(u),this.h()},h(){d(l,"class","text-sm"),d(i,"class","text-xs text-gray-400"),d(t,"class","text-center py-8 text-gray-500")},m(_,y){O(_,t,y),be(e,t,null),c(t,r),c(t,l),c(t,n),c(t,i),v=!0},p:He,i(_){v||(V(e.$$.fragment,_),v=!0)},o(_){z(e.$$.fragment,_),v=!1},d(_){_&&u(t),ge(e)}}}function fr(s){let t,e;return t=new er({props:{size:14,class:"text-gray-600"}}),{c(){ye(t.$$.fragment)},l(r){ve(t.$$.fragment,r)},m(r,l){be(t,r,l),e=!0},i(r){e||(V(t.$$.fragment,r),e=!0)},o(r){z(t.$$.fragment,r),e=!1},d(r){ge(t,r)}}}function dr(s){let t,e;return t=new Zt({props:{size:14,class:"text-gray-600"}}),{c(){ye(t.$$.fragment)},l(r){ve(t.$$.fragment,r)},m(r,l){be(t,r,l),e=!0},i(r){e||(V(t.$$.fragment,r),e=!0)},o(r){z(t.$$.fragment,r),e=!1},d(r){ge(t,r)}}}function Lt(s){var ne;let t,e,r,l,o=s[48]+1+"",n,i,a,v,_,y,m,k=s[46].timestamp.toLocaleTimeString()+"",S,j,D,K=((ne=s[2])==null?void 0:ne.id)===s[46].id?"Selected":"Select for cloning",$,C,G,B,R,Q,P;const N=[dr,fr],E=[];function A(x,g){var M;return((M=x[8])==null?void 0:M.id)===x[46].id&&x[9]&&!x[9].paused?0:1}v=A(s),_=E[v]=N[v](s);function J(){return s[30](s[46])}function H(){return s[31](s[46])}return{c(){t=p("div"),e=p("div"),r=p("span"),l=F("Recording "),n=F(o),i=I(),a=p("button"),_.c(),y=I(),m=p("div"),S=F(k),j=I(),D=p("button"),$=F(K),G=I(),this.h()},l(x){t=h(x,"DIV",{class:!0});var g=b(t);e=h(g,"DIV",{class:!0});var M=b(e);r=h(M,"SPAN",{class:!0});var le=b(r);l=q(le,"Recording "),n=q(le,o),le.forEach(u),i=T(M),a=h(M,"BUTTON",{class:!0});var W=b(a);_.l(W),W.forEach(u),M.forEach(u),y=T(g),m=h(g,"DIV",{class:!0});var Y=b(m);S=q(Y,k),Y.forEach(u),j=T(g),D=h(g,"BUTTON",{class:!0});var X=b(D);$=q(X,K),X.forEach(u),G=T(g),g.forEach(u),this.h()},h(){var x,g;d(r,"class","text-sm font-medium text-gray-900"),d(a,"class","p-1 hover:bg-gray-100 rounded transition-colors"),d(e,"class","flex items-center justify-between mb-2"),d(m,"class","text-xs text-gray-500 mb-2"),d(D,"class",C="w-full text-xs px-2 py-1 rounded "+(((x=s[2])==null?void 0:x.id)===s[46].id?"bg-amber-200 text-amber-800":"bg-gray-100 text-gray-700 hover:bg-gray-200")+" transition-colors"),d(t,"class",B="border rounded-lg p-3 "+(((g=s[2])==null?void 0:g.id)===s[46].id?"border-amber-300 bg-amber-50":"border-gray-200 hover:border-gray-300")+" transition-colors")},m(x,g){O(x,t,g),c(t,e),c(e,r),c(r,l),c(r,n),c(e,i),c(e,a),E[v].m(a,null),c(t,y),c(t,m),c(m,S),c(t,j),c(t,D),c(D,$),c(t,G),R=!0,Q||(P=[Pe(a,"click",J),Pe(D,"click",H)],Q=!0)},p(x,g){var le,W,Y;s=x;let M=v;v=A(s),v!==M&&(Le(),z(E[M],1,1,()=>{E[M]=null}),Se(),_=E[v],_||(_=E[v]=N[v](s),_.c()),V(_,1),_.m(a,null)),(!R||g[0]&2)&&k!==(k=s[46].timestamp.toLocaleTimeString()+"")&&Ie(S,k),(!R||g[0]&6)&&K!==(K=((le=s[2])==null?void 0:le.id)===s[46].id?"Selected":"Select for cloning")&&Ie($,K),(!R||g[0]&6&&C!==(C="w-full text-xs px-2 py-1 rounded "+(((W=s[2])==null?void 0:W.id)===s[46].id?"bg-amber-200 text-amber-800":"bg-gray-100 text-gray-700 hover:bg-gray-200")+" transition-colors"))&&d(D,"class",C),(!R||g[0]&6&&B!==(B="border rounded-lg p-3 "+(((Y=s[2])==null?void 0:Y.id)===s[46].id?"border-amber-300 bg-amber-50":"border-gray-200 hover:border-gray-300")+" transition-colors"))&&d(t,"class",B)},i(x){R||(V(_),R=!0)},o(x){z(_),R=!1},d(x){x&&u(t),E[v].d(),Q=!1,at(P)}}}function _r(s){let t;return{c(){t=F("Clone")},l(e){t=q(e,"Clone")},m(e,r){O(e,t,r)},i:He,o:He,d(e){e&&u(t)}}}function hr(s){let t,e,r;return t=new it({props:{size:16,class:"animate-spin"}}),{c(){ye(t.$$.fragment),e=F(`
3
+ Uploading...`)},l(l){ve(t.$$.fragment,l),e=q(l,`
4
+ Uploading...`)},m(l,o){be(t,l,o),O(l,e,o),r=!0},i(l){r||(V(t.$$.fragment,l),r=!0)},o(l){z(t.$$.fragment,l),r=!1},d(l){l&&u(e),ge(t,l)}}}function pr(s){let t,e,r;return t=new it({props:{size:16,class:"animate-spin"}}),{c(){ye(t.$$.fragment),e=F(`
5
+ Transcribing...`)},l(l){ve(t.$$.fragment,l),e=q(l,`
6
+ Transcribing...`)},m(l,o){be(t,l,o),O(l,e,o),r=!0},i(l){r||(V(t.$$.fragment,l),r=!0)},o(l){z(t.$$.fragment,l),r=!1},d(l){l&&u(e),ge(t,l)}}}function mr(s){let t;return{c(){t=F("✓")},l(e){t=q(e,"✓")},m(e,r){O(e,t,r)},p:He,d(e){e&&u(t)}}}function gr(s){let t,e;function r(n,i){return i[0]&4&&(t=null),t==null&&(t=!!lt(n[2])),t?vr:br}let l=r(s,[-1,-1]),o=l(s);return{c(){o.c(),e=Je()},l(n){o.l(n),e=Je()},m(n,i){o.m(n,i),O(n,e,i)},p(n,i){l!==(l=r(n,i))&&(o.d(1),o=l(n),o&&(o.c(),o.m(e.parentNode,e)))},d(n){n&&u(e),o.d(n)}}}function br(s){let t;return{c(){t=F("✗")},l(e){t=q(e,"✗")},m(e,r){O(e,t,r)},d(e){e&&u(t)}}}function vr(s){let t;return{c(){t=F("✓")},l(e){t=q(e,"✓")},m(e,r){O(e,t,r)},d(e){e&&u(t)}}}function yr(s){let t;return{c(){t=F("✓")},l(e){t=q(e,"✓")},m(e,r){O(e,t,r)},p:He,d(e){e&&u(t)}}}function kr(s){let t,e;function r(n,i){return i[0]&4&&(t=null),t==null&&(t=!!n[20](n[2])),t?Er:wr}let l=r(s,[-1,-1]),o=l(s);return{c(){o.c(),e=Je()},l(n){o.l(n),e=Je()},m(n,i){o.m(n,i),O(n,e,i)},p(n,i){l!==(l=r(n,i))&&(o.d(1),o=l(n),o&&(o.c(),o.m(e.parentNode,e)))},d(n){n&&u(e),o.d(n)}}}function wr(s){let t;return{c(){t=F("✗")},l(e){t=q(e,"✗")},m(e,r){O(e,t,r)},d(e){e&&u(t)}}}function Er(s){let t;return{c(){t=F("✓")},l(e){t=q(e,"✓")},m(e,r){O(e,t,r)},d(e){e&&u(t)}}}function Pt(s){let t,e,r,l=s[10][s[2].id].first_words+"",o,n;return{c(){t=p("div"),e=p("p"),r=F('"'),o=F(l),n=F('..."'),this.h()},l(i){t=h(i,"DIV",{class:!0});var a=b(t);e=h(a,"P",{class:!0});var v=b(e);r=q(v,'"'),o=q(v,l),n=q(v,'..."'),v.forEach(u),a.forEach(u),this.h()},h(){d(e,"class","text-sm text-gray-600 italic"),d(t,"class","mt-3 p-3 bg-gray-50 rounded-lg border")},m(i,a){O(i,t,a),c(t,e),c(e,r),c(e,o),c(e,n)},p(i,a){a[0]&1028&&l!==(l=i[10][i[2].id].first_words+"")&&Ie(o,l)},d(i){i&&u(t)}}}function Mt(s){let t,e,r;return{c(){t=p("div"),e=p("p"),r=F(s[13]),this.h()},l(l){t=h(l,"DIV",{class:!0});var o=b(t);e=h(o,"P",{class:!0});var n=b(e);r=q(n,s[13]),n.forEach(u),o.forEach(u),this.h()},h(){d(e,"class","text-sm text-green-700"),d(t,"class","mt-3 p-3 bg-green-50 rounded-lg border border-green-200")},m(l,o){O(l,t,o),c(t,e),c(e,r)},p(l,o){o[0]&8192&&Ie(r,l[13])},d(l){l&&u(t)}}}function zt(s){let t,e,r,l,o,n,i,a,v,_,y,m,k="An error occurred while processing your request",S,j,D,K,$,C,G,B,R="Close",Q,P,N;n=new Qt({props:{size:20,class:"text-red-600"}}),D=new jt({props:{size:20,class:"text-gray-500"}});let E=s[5]&&$t(s);return{c(){t=p("div"),e=p("div"),r=p("div"),l=p("div"),o=p("div"),ye(n.$$.fragment),i=I(),a=p("div"),v=p("h3"),_=F(s[4]),y=I(),m=p("p"),m.textContent=k,S=I(),j=p("button"),ye(D.$$.fragment),K=I(),$=p("div"),E&&E.c(),C=I(),G=p("div"),B=p("button"),B.textContent=R,this.h()},l(A){t=h(A,"DIV",{class:!0});var J=b(t);e=h(J,"DIV",{class:!0});var H=b(e);r=h(H,"DIV",{class:!0});var ne=b(r);l=h(ne,"DIV",{class:!0});var x=b(l);o=h(x,"DIV",{class:!0});var g=b(o);ve(n.$$.fragment,g),g.forEach(u),i=T(x),a=h(x,"DIV",{class:!0});var M=b(a);v=h(M,"H3",{class:!0});var le=b(v);_=q(le,s[4]),le.forEach(u),y=T(M),m=h(M,"P",{class:!0,"data-svelte-h":!0}),we(m)!=="svelte-1l3zl3"&&(m.textContent=k),M.forEach(u),x.forEach(u),S=T(ne),j=h(ne,"BUTTON",{class:!0,title:!0});var W=b(j);ve(D.$$.fragment,W),W.forEach(u),ne.forEach(u),K=T(H),$=h(H,"DIV",{class:!0});var Y=b($);E&&E.l(Y),Y.forEach(u),C=T(H),G=h(H,"DIV",{class:!0});var X=b(G);B=h(X,"BUTTON",{class:!0,"data-svelte-h":!0}),we(B)!=="svelte-4sxk6g"&&(B.textContent=R),X.forEach(u),H.forEach(u),J.forEach(u),this.h()},h(){d(o,"class","w-10 h-10 bg-red-100 rounded-full flex items-center justify-center flex-shrink-0"),d(v,"class","text-lg font-semibold text-gray-900 truncate"),d(m,"class","text-sm text-gray-600"),d(a,"class","min-w-0"),d(l,"class","flex items-center gap-3 min-w-0"),d(j,"class","p-2 hover:bg-red-100 rounded-full transition-colors flex-shrink-0"),d(j,"title","Close"),d(r,"class","flex items-center justify-between p-6 border-b border-gray-200 bg-red-50 flex-shrink-0"),d($,"class","p-6 overflow-y-auto flex-1 min-h-0"),d(B,"class","px-6 py-2 bg-red-600 text-white rounded-lg hover:bg-red-700 transition-colors"),d(G,"class","flex items-center justify-end gap-3 p-6 border-t border-gray-200 bg-gray-50 flex-shrink-0"),d(e,"class","bg-white rounded-xl shadow-2xl max-w-2xl w-full max-h-[80vh] flex flex-col"),d(t,"class","fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 p-4")},m(A,J){O(A,t,J),c(t,e),c(e,r),c(r,l),c(l,o),be(n,o,null),c(l,i),c(l,a),c(a,v),c(v,_),c(a,y),c(a,m),c(r,S),c(r,j),be(D,j,null),c(e,K),c(e,$),E&&E.m($,null),c(e,C),c(e,G),c(G,B),Q=!0,P||(N=[Pe(j,"click",s[21]),Pe(B,"click",s[21])],P=!0)},p(A,J){(!Q||J[0]&16)&&Ie(_,A[4]),A[5]?E?E.p(A,J):(E=$t(A),E.c(),E.m($,null)):E&&(E.d(1),E=null)},i(A){Q||(V(n.$$.fragment,A),V(D.$$.fragment,A),Q=!0)},o(A){z(n.$$.fragment,A),z(D.$$.fragment,A),Q=!1},d(A){A&&u(t),ge(n),ge(D),E&&E.d(),P=!1,at(N)}}}function $t(s){let t,e,r="Error Details:",l,o,n;return{c(){t=p("div"),e=p("h4"),e.textContent=r,l=I(),o=p("pre"),n=F(s[5]),this.h()},l(i){t=h(i,"DIV",{class:!0});var a=b(t);e=h(a,"H4",{class:!0,"data-svelte-h":!0}),we(e)!=="svelte-3lmggt"&&(e.textContent=r),l=T(a),o=h(a,"PRE",{class:!0});var v=b(o);n=q(v,s[5]),v.forEach(u),a.forEach(u),this.h()},h(){d(e,"class","text-sm font-medium text-gray-900 mb-2"),d(o,"class","text-xs text-gray-700 whitespace-pre-wrap font-mono leading-relaxed break-words"),d(t,"class","bg-gray-50 rounded-lg p-4 border")},m(i,a){O(i,t,a),c(t,e),c(t,l),c(t,o),c(o,n)},p(i,a){a[0]&32&&Ie(n,i[5])},d(i){i&&u(t)}}}function Dr(s){let t,e,r,l,o,n,i,a='<span class="text-sm text-gray-400">Sample script</span>',v,_,y,m,k,S,j,D,K="I consent to cloning my voice.",$,C=s[19][s[16]]+"",G,B,R,Q,P,N,E,A,J,H,ne=`<p class="text-center"><em>Record your voice for at least 3 seconds to create a voice clone. To prevent
7
+ unauthorized voice cloning, you must start by clearly saying &quot;I consent to cloning my
8
+ voice&quot; — the rest of the text is arbitrary. Try reading the sample above.</em></p>`,x,g,M,le,W,Y,X,Ee,oe,_e,he,pe,Me,Be,Ve,Te,Ke,We,w,L,Z,ue,ze,ke,fe,de,me,Ce,Oe;m=new Xt({props:{size:16}});let se=s[0]&&It(s);const ct=[nr,or],$e=[];function ut(f,U){return f[0]?0:1}N=ut(s),E=$e[N]=ct[N](s);let ae=!s[17]&&s[18]&&Vt(s),te=s[17]&&s[14].length>0&&Ct(s);const ft=[ur,cr],Re=[];function dt(f,U){return f[1].length===0?0:1}Y=dt(s),X=Re[Y]=ft[Y](s);const _t=[pr,hr,_r],je=[];function ht(f,U){return f[11]?0:f[12]?1:2}he=ht(s),pe=je[he]=_t[he](s);function pt(f,U){return f[2]?gr:mr}let Xe=pt(s),De=Xe(s);function mt(f,U){return f[2]&&f[10][f[2].id]?kr:yr}let Qe=mt(s),xe=Qe(s),ie=s[2]&&s[10][s[2].id]&&Pt(s),ce=s[13]&&Mt(s),re=s[3]&&zt(s);return{c(){t=I(),e=p("div"),r=p("div"),l=p("div"),o=p("div"),n=p("div"),i=p("div"),i.innerHTML=a,v=I(),_=p("div"),y=p("button"),ye(m.$$.fragment),k=I(),S=p("div"),j=p("p"),D=p("span"),D.textContent=K,$=I(),G=F(C),B=I(),R=p("div"),se&&se.c(),Q=I(),P=p("button"),E.c(),J=I(),H=p("div"),H.innerHTML=ne,x=I(),g=p("div"),ae&&ae.c(),M=I(),te&&te.c(),le=I(),W=p("div"),X.c(),Ee=I(),oe=p("div"),_e=p("button"),pe.c(),Be=I(),Ve=p("div"),Te=p("span"),De.c(),Ke=F(`
9
+ at least 3 seconds`),w=I(),L=p("span"),xe.c(),Z=F(`
10
+ includes consent`),ze=I(),ie&&ie.c(),ke=I(),ce&&ce.c(),fe=I(),re&&re.c(),de=Je(),this.h()},l(f){Gt("svelte-ymar42",document.head).forEach(u),t=T(f),e=h(f,"DIV",{class:!0});var qe=b(e);r=h(qe,"DIV",{class:!0});var Ne=b(r);l=h(Ne,"DIV",{class:!0});var Fe=b(l);o=h(Fe,"DIV",{class:!0});var Ge=b(o);n=h(Ge,"DIV",{class:!0});var Ye=b(n);i=h(Ye,"DIV",{class:!0,"data-svelte-h":!0}),we(i)!=="svelte-hnzyx9"&&(i.innerHTML=a),v=T(Ye),_=h(Ye,"DIV",{class:!0});var gt=b(_);y=h(gt,"BUTTON",{class:!0,title:!0});var bt=b(y);ve(m.$$.fragment,bt),bt.forEach(u),gt.forEach(u),k=T(Ye),S=h(Ye,"DIV",{class:!0});var vt=b(S);j=h(vt,"P",{});var Ze=b(j);D=h(Ze,"SPAN",{class:!0,"data-svelte-h":!0}),we(D)!=="svelte-teyhel"&&(D.textContent=K),$=T(Ze),G=q(Ze,C),Ze.forEach(u),vt.forEach(u),Ye.forEach(u),B=T(Ge),R=h(Ge,"DIV",{class:!0});var et=b(R);se&&se.l(et),Q=T(et),P=h(et,"BUTTON",{class:!0});var yt=b(P);E.l(yt),yt.forEach(u),et.forEach(u),J=T(Ge),H=h(Ge,"DIV",{class:!0,"data-svelte-h":!0}),we(H)!=="svelte-fbcwq9"&&(H.innerHTML=ne),Ge.forEach(u),Fe.forEach(u),x=T(Ne),g=h(Ne,"DIV",{class:!0});var Ue=b(g);ae&&ae.l(Ue),M=T(Ue),te&&te.l(Ue),le=T(Ue),W=h(Ue,"DIV",{class:!0});var kt=b(W);X.l(kt),kt.forEach(u),Ee=T(Ue),oe=h(Ue,"DIV",{class:!0});var Ae=b(oe);_e=h(Ae,"BUTTON",{class:!0});var wt=b(_e);pe.l(wt),wt.forEach(u),Be=T(Ae),Ve=h(Ae,"DIV",{class:!0});var tt=b(Ve);Te=h(tt,"SPAN",{class:!0});var st=b(Te);De.l(st),Ke=q(st,`
11
+ at least 3 seconds`),st.forEach(u),w=T(tt),L=h(tt,"SPAN",{class:!0});var ot=b(L);xe.l(ot),Z=q(ot,`
12
+ includes consent`),ot.forEach(u),tt.forEach(u),ze=T(Ae),ie&&ie.l(Ae),ke=T(Ae),ce&&ce.l(Ae),Ae.forEach(u),Ue.forEach(u),Ne.forEach(u),qe.forEach(u),fe=T(f),re&&re.l(f),de=Je(),this.h()},h(){document.title="Voice Cloning - HFStudio",d(i,"class","absolute top-3 left-3 flex items-center gap-2 z-10"),d(y,"class","p-1 text-gray-400 hover:text-gray-600 hover:bg-gray-100 rounded-lg transition-colors"),d(y,"title","Try a different sample text"),d(_,"class","absolute top-3 right-3 flex items-center gap-2 z-10"),d(D,"class","bg-yellow-50 px-2 py-1 rounded border border-amber-200"),d(S,"class","w-full h-80 pt-10 px-6 pb-6 bg-white border border-amber-400 rounded-lg text-gray-900 text-lg leading-relaxed overflow-y-auto"),d(n,"class","relative mb-4"),d(P,"class",A="w-24 h-24 rounded-full flex items-center justify-center transition-all duration-200 shadow-lg relative overflow-hidden z-20 cursor-pointer "+(s[0]?"border-4 border-orange-500 bg-transparent":"bg-orange-500 hover:bg-orange-600")),d(R,"class","flex justify-center items-center flex-1 relative"),d(H,"class","mb-6"),d(o,"class","flex-1 pb-24 relative flex flex-col"),d(l,"class","flex-1 flex flex-col p-6"),d(W,"class","mb-4"),_e.disabled=Me=!s[2]||s[11]||s[12],d(_e,"class","w-full px-4 py-2 bg-gradient-to-r from-amber-400 to-orange-500 text-white rounded-lg font-medium hover:from-amber-500 hover:to-orange-600 disabled:opacity-50 disabled:cursor-not-allowed transition-colors flex items-center justify-center gap-2"),d(Te,"class",We="flex items-center gap-1 "+(s[2]?lt(s[2])?"text-green-600":"text-red-600":"text-gray-400")),d(L,"class",ue="flex items-center gap-1 "+(s[2]?s[20](s[2])?"text-green-600":s[10][s[2].id]?"text-red-600":"text-gray-400":"text-gray-400")),d(Ve,"class","mt-3 text-sm flex items-center gap-4"),d(oe,"class","mt-6 pt-4 border-t border-gray-200"),d(g,"class","w-80 border-l border-gray-200 bg-white p-3 overflow-y-auto"),d(r,"class","flex-1 flex"),d(e,"class","flex flex-col h-full")},m(f,U){O(f,t,U),O(f,e,U),c(e,r),c(r,l),c(l,o),c(o,n),c(n,i),c(n,v),c(n,_),c(_,y),be(m,y,null),c(n,k),c(n,S),c(S,j),c(j,D),c(j,$),c(j,G),c(o,B),c(o,R),se&&se.m(R,null),c(R,Q),c(R,P),$e[N].m(P,null),c(o,J),c(o,H),c(r,x),c(r,g),ae&&ae.m(g,null),c(g,M),te&&te.m(g,null),c(g,le),c(g,W),Re[Y].m(W,null),c(g,Ee),c(g,oe),c(oe,_e),je[he].m(_e,null),c(oe,Be),c(oe,Ve),c(Ve,Te),De.m(Te,null),c(Te,Ke),c(Ve,w),c(Ve,L),xe.m(L,null),c(L,Z),c(oe,ze),ie&&ie.m(oe,null),c(oe,ke),ce&&ce.m(oe,null),O(f,fe,U),re&&re.m(f,U),O(f,de,U),me=!0,Ce||(Oe=[Pe(y,"click",s[22]),Pe(P,"click",s[23]),Pe(_e,"click",s[26])],Ce=!0)},p(f,U){(!me||U[0]&65536)&&C!==(C=f[19][f[16]]+"")&&Ie(G,C),f[0]?se?se.p(f,U):(se=It(f),se.c(),se.m(R,Q)):se&&(se.d(1),se=null);let qe=N;N=ut(f),N===qe?$e[N].p(f,U):(Le(),z($e[qe],1,1,()=>{$e[qe]=null}),Se(),E=$e[N],E?E.p(f,U):(E=$e[N]=ct[N](f),E.c()),V(E,1),E.m(P,null)),(!me||U[0]&1&&A!==(A="w-24 h-24 rounded-full flex items-center justify-center transition-all duration-200 shadow-lg relative overflow-hidden z-20 cursor-pointer "+(f[0]?"border-4 border-orange-500 bg-transparent":"bg-orange-500 hover:bg-orange-600")))&&d(P,"class",A),!f[17]&&f[18]?ae?ae.p(f,U):(ae=Vt(f),ae.c(),ae.m(g,M)):ae&&(ae.d(1),ae=null),f[17]&&f[14].length>0?te?(te.p(f,U),U[0]&147456&&V(te,1)):(te=Ct(f),te.c(),V(te,1),te.m(g,le)):te&&(Le(),z(te,1,1,()=>{te=null}),Se());let Ne=Y;Y=dt(f),Y===Ne?Re[Y].p(f,U):(Le(),z(Re[Ne],1,1,()=>{Re[Ne]=null}),Se(),X=Re[Y],X?X.p(f,U):(X=Re[Y]=ft[Y](f),X.c()),V(X,1),X.m(W,null));let Fe=he;he=ht(f),he!==Fe&&(Le(),z(je[Fe],1,1,()=>{je[Fe]=null}),Se(),pe=je[he],pe||(pe=je[he]=_t[he](f),pe.c()),V(pe,1),pe.m(_e,null)),(!me||U[0]&6148&&Me!==(Me=!f[2]||f[11]||f[12]))&&(_e.disabled=Me),Xe===(Xe=pt(f))&&De?De.p(f,U):(De.d(1),De=Xe(f),De&&(De.c(),De.m(Te,Ke))),(!me||U[0]&4&&We!==(We="flex items-center gap-1 "+(f[2]?lt(f[2])?"text-green-600":"text-red-600":"text-gray-400")))&&d(Te,"class",We),Qe===(Qe=mt(f))&&xe?xe.p(f,U):(xe.d(1),xe=Qe(f),xe&&(xe.c(),xe.m(L,Z))),(!me||U[0]&1028&&ue!==(ue="flex items-center gap-1 "+(f[2]?f[20](f[2])?"text-green-600":f[10][f[2].id]?"text-red-600":"text-gray-400":"text-gray-400")))&&d(L,"class",ue),f[2]&&f[10][f[2].id]?ie?ie.p(f,U):(ie=Pt(f),ie.c(),ie.m(oe,ke)):ie&&(ie.d(1),ie=null),f[13]?ce?ce.p(f,U):(ce=Mt(f),ce.c(),ce.m(oe,null)):ce&&(ce.d(1),ce=null),f[3]?re?(re.p(f,U),U[0]&8&&V(re,1)):(re=zt(f),re.c(),V(re,1),re.m(de.parentNode,de)):re&&(Le(),z(re,1,1,()=>{re=null}),Se())},i(f){me||(V(m.$$.fragment,f),V(E),V(te),V(X),V(pe),V(re),me=!0)},o(f){z(m.$$.fragment,f),z(E),z(te),z(X),z(pe),z(re),me=!1},d(f){f&&(u(t),u(e),u(fe),u(de)),ge(m),se&&se.d(),$e[N].d(),ae&&ae.d(),te&&te.d(),Re[Y].d(),je[he].d(),De.d(),xe.d(),ie&&ie.d(),ce&&ce.d(),re&&re.d(f),Ce=!1,at(Oe)}}}function lt(s){return s&&s.duration>=3}function xr(s,t,e){let r=!1,l=[],o=null,n=[],i=null,a=[],v=!1,_="",y="",m=0,k=0,S=null,j=0,D=null,K=null,$=null,C=null,G={},B=!1,R=!1,Q={},P="",N=[],E=!1;const A=["There's a quiet kind of magic in the early hours of the morning, when the world is still half-asleep and the air feels crisp with possibility. The hum of the refrigerator becomes a rhythm, the ticking of the clock a heartbeat, and for a brief moment, everything feels perfectly in sync.","The aroma of fresh coffee dances through the kitchen as sunlight streams through translucent curtains, casting golden patterns on weathered wooden floors. Steam rises from the ceramic mug like incense, creating a small sanctuary of warmth and comfort in the midst of a busy day.","Ocean waves crash against weathered cliffs with relentless determination, their white foam reaching toward the endless sky. Seabirds call out across the salt-scented breeze, their cries echoing off ancient stone formations that have stood witness to countless storms and seasons."];let J=0,H=!1,ne=!1;function x(w){if(!w)return!1;const L=G[w.id];return L&&L.consent_detected}function g(w,L=""){e(4,_=w),e(5,y=L),e(3,v=!0)}function M(){e(3,v=!1),e(4,_=""),e(5,y="")}function le(){e(16,J=(J+1)%A.length)}async function W(){try{const w=await fetch("/api/auth/user",{credentials:"include"});if(w.ok){const L=await w.json(),Z=H;e(17,H=L.authenticated),H&&!Z?await Me():!H&&Z&&e(14,N=[])}else e(17,H=!1),e(14,N=[])}catch{e(17,H=!1),e(14,N=[])}}async function Y(){if(!H){e(18,ne=!0);return}try{let ke=function(){if(!r||!K)return;K.getByteFrequencyData(ze);let fe=0;for(let de=0;de<ue;de++)fe+=ze[de];e(7,j=fe/ue/255),requestAnimationFrame(ke)};const w=await navigator.mediaDevices.getUserMedia({audio:!0});let L={};MediaRecorder.isTypeSupported("audio/wav")?L.mimeType="audio/wav":MediaRecorder.isTypeSupported("audio/webm")&&(L.mimeType="audio/webm"),i=new MediaRecorder(w,L),a=[],n=[],e(6,k=0),e(7,j=0),D=new(window.AudioContext||window.webkitAudioContext),K=D.createAnalyser(),D.createMediaStreamSource(w).connect(K),K.fftSize=256;const ue=K.frequencyBinCount,ze=new Uint8Array(ue);i.ondataavailable=fe=>{a.push(fe.data)},i.onstop=()=>{const fe=new Blob(a,{type:"audio/wav"}),de=URL.createObjectURL(fe),me={id:Date.now(),url:de,blob:fe,timestamp:new Date,duration:k/100*15};e(1,l=[...l,me]),w.getTracks().forEach(Ce=>Ce.stop()),D&&(D.close(),D=null),e(6,k=0),e(7,j=0)},i.start(),e(0,r=!0),ke(),S=setInterval(()=>{if(!r){clearInterval(S);return}e(6,k+=100/15/10),k>=100&&e(6,k=100)},100)}catch(w){console.error("Error accessing microphone:",w),g("Microphone Error","Could not access microphone. Please check permissions.")}}function X(){i&&i.state==="recording"&&(i.stop(),e(0,r=!1),n=[],S&&(clearInterval(S),S=null))}function Ee(){r?X():Y()}function oe(w){e(2,o=w)}function _e(w){if(($==null?void 0:$.id)===w.id&&C&&!C.paused){C.pause(),e(8,$=null);return}C&&(C.pause(),e(9,C=null)),e(9,C=new Audio(w.url)),e(8,$=w),C.addEventListener("ended",()=>{e(8,$=null),e(9,C=null)}),C.addEventListener("pause",()=>{C&&C.ended&&(e(8,$=null),e(9,C=null))}),C.play()}async function he(){if(!o){g("Clone Error","Please select a recording.");return}e(11,B=!0),e(13,P="");try{const w=new FormData;w.append("audio_file",o.blob,"recording.wav");const L=await fetch("/api/voice/transcribe",{method:"POST",credentials:"include",body:w});if(!L.ok){const ue=await L.text();throw new Error(`HTTP error! status: ${L.status}, response: ${ue}`)}const Z=await L.json();if(Z.success){e(10,G[o.id]={transcript:Z.transcript,first_words:Z.first_words,consent_detected:Z.consent_detected},G),e(10,G={...G});const ue=lt(o),ze=Z.consent_detected;if(ue&&ze){e(11,B=!1),e(12,R=!0);try{const ke=new FormData;ke.append("audio_file",o.blob,"recording.wav");const fe=`Voice_${Date.now()}`,de=encodeURIComponent(Z.transcript),me=Math.floor(o.duration),Ce=await fetch(`/api/voice/upload?voice_name=${fe}&transcript=${de}&duration=${me}`,{method:"POST",credentials:"include",body:ke});if(!Ce.ok){const se=await Ce.text();throw new Error(`Upload failed: ${se}`)}const Oe=await Ce.json();Oe.success?(Q[o.id]=Oe,Q={...Q},e(13,P="Your voice has been saved and can be used for text-to-speech generation."),await Me()):g("Upload Error",Oe.error||"Failed to upload voice")}catch(ke){g("Upload Error",`Failed to upload voice: ${ke.message}`)}finally{e(12,R=!1)}}}else g("Transcription Error",Z.error||"Failed to transcribe audio")}catch(w){g("Network Error",`Failed to process recording: ${w.message}`)}finally{R||e(11,B=!1)}}async function pe(){try{const w=await fetch("/api/history/load",{method:"GET",credentials:"include"});w.ok&&(m=(await w.json()).entries.filter(ue=>ue.entry_type==="generation").length)}catch(w){console.error("Error loading history count:",w),m=0}}async function Me(){if(H)try{const w=await fetch("/api/voice/user-voices",{method:"GET",credentials:"include"});if(w.ok){const L=await w.json();e(14,N=L.voices)}}catch(w){console.error("Error loading user voices:",w),e(14,N=[])}}async function Be(w){e(15,E=!0);try{const L=await fetch(`/api/voice/${w}`,{method:"DELETE",credentials:"include"});if(L.ok)e(14,N=N.filter(Z=>Z.id!==w)),e(13,P="Voice deleted successfully"),setTimeout(()=>{e(13,P="")},3e3);else{const Z=await L.json();g("Delete Error",Z.detail||"Failed to delete voice")}}catch(L){g("Delete Error",`Failed to delete voice: ${L.message}`)}finally{e(15,E=!1)}}return Yt(async()=>{await W(),await pe(),await Me()}),[r,l,o,v,_,y,k,j,$,C,G,B,R,P,N,E,J,H,ne,A,x,M,le,Ee,oe,_e,he,Be,()=>e(18,ne=!1),w=>Be(w.id),w=>_e(w),w=>oe(w)]}class Pr extends Rt{constructor(t){super(),Nt(this,t,xr,Dr,Ut,{},null,[-1,-1])}}export{Pr as component};
hfstudio/static/_app/version.json CHANGED
@@ -1 +1 @@
1
- {"version":"1761244884160"}
 
1
+ {"version":"1761278727586"}
hfstudio/static/index.html CHANGED
@@ -6,25 +6,25 @@
6
  <meta name="viewport" content="width=device-width, initial-scale=1" />
7
  <title>HFStudio - Text to Speech</title>
8
 
9
- <link rel="modulepreload" href="/_app/immutable/entry/start.DiWn1IXe.js">
10
- <link rel="modulepreload" href="/_app/immutable/chunks/e2OxhbUw.js">
11
- <link rel="modulepreload" href="/_app/immutable/chunks/BjzGjDWb.js">
12
- <link rel="modulepreload" href="/_app/immutable/entry/app.Bclt6vmz.js">
13
  <link rel="modulepreload" href="/_app/immutable/chunks/IHki7fMi.js">
14
  </head>
15
  <body data-sveltekit-preload-data="hover">
16
  <div style="display: contents">
17
  <script>
18
  {
19
- __sveltekit_j7e979 = {
20
  base: ""
21
  };
22
 
23
  const element = document.currentScript.parentElement;
24
 
25
  Promise.all([
26
- import("/_app/immutable/entry/start.DiWn1IXe.js"),
27
- import("/_app/immutable/entry/app.Bclt6vmz.js")
28
  ]).then(([kit, app]) => {
29
  kit.start(app, element);
30
  });
 
6
  <meta name="viewport" content="width=device-width, initial-scale=1" />
7
  <title>HFStudio - Text to Speech</title>
8
 
9
+ <link rel="modulepreload" href="/_app/immutable/entry/start.C4SfOwCE.js">
10
+ <link rel="modulepreload" href="/_app/immutable/chunks/B7RJWGyJ.js">
11
+ <link rel="modulepreload" href="/_app/immutable/chunks/BaOlNwUz.js">
12
+ <link rel="modulepreload" href="/_app/immutable/entry/app.BBX27H-0.js">
13
  <link rel="modulepreload" href="/_app/immutable/chunks/IHki7fMi.js">
14
  </head>
15
  <body data-sveltekit-preload-data="hover">
16
  <div style="display: contents">
17
  <script>
18
  {
19
+ __sveltekit_1wyakc0 = {
20
  base: ""
21
  };
22
 
23
  const element = document.currentScript.parentElement;
24
 
25
  Promise.all([
26
+ import("/_app/immutable/entry/start.C4SfOwCE.js"),
27
+ import("/_app/immutable/entry/app.BBX27H-0.js")
28
  ]).then(([kit, app]) => {
29
  kit.start(app, element);
30
  });
pyproject.toml CHANGED
@@ -30,9 +30,11 @@ dependencies = [
30
  "pydantic>=2.0.0",
31
  "huggingface-hub>=0.20.0",
32
  "httpx>=0.25.0",
33
- "numpy>=1.21.0",
34
  "soundfile>=0.12.0",
35
  "sqlalchemy>=2.0.0",
 
 
36
  ]
37
 
38
  [project.optional-dependencies]
 
30
  "pydantic>=2.0.0",
31
  "huggingface-hub>=0.20.0",
32
  "httpx>=0.25.0",
33
+ "numpy>=1.21.0,<2.0",
34
  "soundfile>=0.12.0",
35
  "sqlalchemy>=2.0.0",
36
+ "transformers>=4.21.0",
37
+ "torch>=1.12.0",
38
  ]
39
 
40
  [project.optional-dependencies]
requirements.txt CHANGED
@@ -6,4 +6,7 @@ numpy>=1.24.0
6
  soundfile>=0.12.0
7
  typer>=0.9.0
8
  rich>=13.0.0
9
- sqlalchemy>=2.0.0
 
 
 
 
6
  soundfile>=0.12.0
7
  typer>=0.9.0
8
  rich>=13.0.0
9
+ sqlalchemy>=2.0.0
10
+ torch>=2.2.0
11
+ torchvision>=0.17.0
12
+ transformers>=4.30.0
requirements_space.txt CHANGED
@@ -6,4 +6,7 @@ numpy>=1.24.0
6
  soundfile>=0.12.0
7
  typer>=0.9.0
8
  rich>=13.0.0
9
- sqlalchemy>=2.0.0
 
 
 
 
6
  soundfile>=0.12.0
7
  typer>=0.9.0
8
  rich>=13.0.0
9
+ sqlalchemy>=2.0.0
10
+ torch>=2.2.0
11
+ torchvision>=0.17.0
12
+ transformers>=4.30.0