Opera8 commited on
Commit
fd5019d
·
verified ·
1 Parent(s): b23be79

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +220 -585
index.html CHANGED
@@ -1,12 +1,10 @@
1
- <!DOCTYPE html> " content="width=device-width, initial-scale=1.0, maximum-scale=1.0
2
  <html lang="fa" dir="rtl">
3
  <head>
4
  <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=, user-scalable=no">
6
  <title>استودیو موزیک آلفا</title>
7
- <link href="https://fonts.googleapis.com/css2?family=Vazirmatn1.0">
8
- <title>استودیو آلفا</title>
9
- <link:wght@300;400;500;700;800&display href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;500;600;700;800&display=swap" rel="stylesheet">
10
  <style>
11
  :root {
12
  --app-font: 'Vazirmatn', sans-serif;
@@ -14,706 +12,343 @@
14
  --panel-bg: #FFFFFF;
15
  --panel-border: #EAEFF7;
16
  --input-bg: #F6F8FB;
17
- --input-border: #=swap" rel="stylesheet">
18
- <style>
19
- :root {
20
- --appE1E7EF;
21
  --text-primary: #1A202C;
22
  --text-secondary: #626F86;
23
  --accent-primary: #4A6CFA;
24
- --accent-glow: rgba(74, 108, 250, 0.25);
25
- --accent-secondary: #0FD4A8;
26
  --radius-card: 24px;
27
- --radius-btn: 14px;
28
- --radius-input: 12px;
29
- --transition-smooth: all 0.35s cubic-bezier(0.4, 0, 0.2, 1);
30
- }
31
-
32
- @keyframes fadeIn { from { opacity: 0; transform: translateY(15px); } to { opacity: 1; transform: translateY(0); } }
33
- @keyframes fill-progress { from { width: 0%; } to { width: 100%; } }
34
- @keyframes pulse-loader { 0% { box-shadow: 0 0 40px rgba(56, 189, 248, 0.3); } 50%-font: 'Vazirmatn', sans-serif;
35
- --bg-color: #F3F4F6;
36
- --card-bg: #FFFFFF;
37
- --primary: #3B82F6;
38
- --primary-dark: #2563EB;
39
- --accent: #8B5CF6;
40
- --text-dark: #1F2937;
41
- --text-gray: #6B7280;
42
- --border: #E5E7EB;
43
- --radius: 16px;
44
- }
45
-
46
- * { box-sizing: border-box; -webkit-tap-highlight-color: transparent; outline: none; } { box-shadow: 0 0 60px rgba(56, 189,
47
-
48
- body {
49
- font-family: var(--app-font);
50
- background-color: var(--bg-color);
51
- color: var(--text-dark);
52
- margin: 0;
53
- padding: 20px;
54
- min-height: 100vh;
55
- display: flex;
56
- justify-content: center;
57
- align-items: flex-start;
58
  }
59
 
 
60
  .container { max-width: 600px; width: 100%; position: relative; z-index: 2; }
61
-
62
- /* Header */
63
- header { text-align: center; margin-bottom: 2rem; }
64
- .logo {
65
- font-size: 2.5rem; font-weight: 900;
66
- background: linear-gradient(135deg, var(--primary), var(--accent));
67
- -webkit-background-clip: text; -webkit-text-fill-color: transparent;
68
- letter-spacing: -1px; margin-bottom: 5px; display248, 0.7); } 100% { box-shadow: 0 0: inline-block;
69
- }
70
- .tagline { color: var(--text-gray); font- 40px rgba(56, 189, 248, 0.3);size: 0.9rem; font-weight: 500; }
71
-
72
- /* Main Card */ } }
73
 
74
- body { font-family: var(--app-font); background-color: var
75
- .card {
76
- background: var(--card-bg);
77
- border-radius: var(--app-bg); color: var(--text-primary); margin: 0; padding: 2.5(--radius);
78
- box-shadow: 0 10px 25px -5px rgbarem 1rem; display: flex; justify-content: center; align-items: flex-start; min(0, 0, 0, 0.05);
79
- border: 1px solid-height: 100vh; }
80
- .container { max-width: 820 var(--border);
81
- padding: 25px;
82
- transition: all 0.3s ease;px; width: 100%; }
83
- header { position: relative; text-align: center
84
  }
85
-
86
- .input-area { position: relative; margin-bottom: 15px; }
87
-
88
- ; margin-bottom: 2.5rem; padding: 2rem 0; animation: fadeIn 0 textarea {
89
- width: 100%; background: #F9FAFB;
90
- border: 2px solid var(--border);
91
- border-radius: 12px; padding: 15px;
92
- font-family: inherit; font-size: 1rem; color: var(--.8s 0.1s ease-out backwards; overflow: hidden; }
93
- #neural-canvas { position: absolute; top: 0; left: 0; width: 100%; height:text-dark);
94
- min-height: 120px; resize: none; transition: 0.3s 100%; z-index: 1; opacity: 0.6; }
95
- .header-content { position: relative; z-index: 2; }
96
-
97
- .logo-container;
98
- }
99
- textarea:focus { border-color: var(--primary); background: #fff; box { width: 80px; height: 80px; margin: 0 auto 1.5-shadow: 0 0 0 4px rgba(59, 130, 246,rem; display: flex; align-items: center; justify-content: center; background: radial-gradient(circle, rgba 0.1); }
100
-
101
- /* Settings Accordion */
102
- details {
103
- background: #F8(255, 255, 255, 0.8), rgba(255, 255, 255, 0)); border-radius: 50%; boxFAFC; border: 1px solid var(--border);
104
- border-radius: 12px;-shadow: 0 0 30px var(--accent-primary-glow); }
105
- .logo margin-top: -10px; margin-bottom: 20px;
106
- overflow: hidden;-icon { width: 40px; height: 40px; color: var(--accent-primary); }
107
- transition: 0.3s;
108
- }
109
- summary {
110
- padding: 12px
111
- h1 { font-size: 2.8rem; font-weight: 80015px; cursor: pointer; font-size: 0.9rem;
112
- font-weight: ; margin: 0; background: linear-gradient(90deg, var(--accent-primary), var(--600; color: var(--text-gray); list-style: none;
113
- display: flex;accent-secondary)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; align-items: center; justify-content: space-between;
114
  }
115
- summary::after { content: '+'; letter-spacing: -1px; }
116
- .subtitle { font-size: 1.1rem font-size: 1.2em; font-weight: bold; }
117
- details[open] summary::; color: var(--text-secondary); margin-top: 0.5rem; }
118
 
119
- mainafter { content: '-'; }
120
- details[open] { border-color: var(--primary); }
121
-
122
- { padding: 3rem; background-color: var(--panel-bg); border-radius: var(--radius.settings-grid {
123
- padding: 15px; border-top: 1px solid var(---card); box-shadow: 0 20px 25px -5px rgba(26border);
124
- display: grid; grid-template-columns: 1fr 1fr; gap: , 32, 44, 0.07); border: 1px solid var(--panel15px;
125
- }
126
- .setting-item label { display: block; font-size: -border); animation: fadeIn 0.8s 0.3s ease-out backwards; }
127
- 0.8rem; color: var(--text-gray); margin-bottom: 5px; }
128
-
129
- .form-group { margin-bottom: 1.5rem; }
130
- .form-label { display: flex; align-items: center; gap: 0.75rem; font-.setting-item input, .setting-item select {
131
- width: 100%; padding: 8px; border: 1px solid var(--border);
132
- border-radius: 8px; background:weight: 700; color: var(--text-primary); font-size: 1.2em #fff; font-family: inherit;
133
  }
134
 
135
- /* Generate Button */
136
- .btn-alpha; margin-bottom: 1rem; }
137
-
138
  textarea {
139
- width: 100 {
140
- width: 100%; padding: 18px;
141
- background: linear%; background-color: var(--input-bg); border: 2px solid var(--input-border);
142
- border-gradient(90deg, var(--primary), var(--accent));
143
- color: #fff; border-radius: var(--radius-input); padding: 1.5rem;
144
- font-family:: none; border-radius: 14px;
145
- font-size: 1.1rem var(--app-font); font-size: 1.1rem; color: var(--text-primary);; font-weight: 800; cursor: pointer;
146
- box-shadow: 0 4
147
- outline: none; resize: vertical; min-height: 150px; transition: var(--transitionpx 15px rgba(59, 130, 246, 0.3-smooth);
148
  }
149
- textarea:focus { border-color: var(--accent-primary); background-);
150
- display: flex; justify-content: center; align-items: center; gap: 10color: #fff; box-shadow: 0 0 15px var(--accent-primary-glowpx;
151
- transition: transform 0.2s, box-shadow 0.2s;
152
- }
153
- ); }
154
 
155
- /* Settings Accordion */
156
  .settings-toggle {
157
- cursor: pointer; display: flex.btn-alpha:active { transform: scale(0.98); }
158
- .btn-alpha:; align-items: center; justify-content: space-between;
159
- padding: 1rem; backgrounddisabled { opacity: 0.7; filter: grayscale(1); cursor: not-allowed; }
160
-
161
- : var(--input-bg); border-radius: var(--radius-input);
162
- font-weight: 600; color: var(--text-secondary); border: 1px solid var(--input-border);/* --- COOL LOADER ANIMATION --- */
163
- #loader-container {
164
- display: none; flex-direction: column
165
- transition: var(--transition-smooth);
166
  }
167
- .settings-toggle:hover { background:; align-items: center; justify-content: center;
168
- padding: 40px 20px; text #fff; border-color: var(--accent-primary); }
169
- .settings-content {
170
- max-align: center;
 
 
 
171
  }
 
172
 
173
- .neural-loader {
174
- position: relative; width: 8-height: 0; overflow: hidden; transition: max-height 0.5s ease-out;
175
- padding0px; height: 80px; margin-bottom: 20px;
 
 
176
  }
177
- : 0 1rem; background: #fff;
 
 
 
 
 
 
 
 
 
178
  }
179
- .settings-content.open { max.neural-circle {
180
- position: absolute; width: 100%; height: 100-height: 500px; padding: 1rem; border: 1px solid var(--input-%; border-radius: 50%;
181
- border: 3px solid transparent; border-top-color: var(--border); border-top: none; border-radius: 0 0 var(--radius-input) var(--primary);
182
- animation: spin 1.5s linear infinite;
 
 
 
 
 
183
  }
184
- .neural-circle::before {
185
- content: ""; position: absolute; top: 5px; left: 5px;radius-input); margin-top: -5px; }
186
 
187
- .grid-3 { display: grid; right: 5px; bottom: 5px;
188
- border-radius: 50%; border: grid-template-columns: 1fr 1fr 1fr; gap: 1rem; margin-top: 3px solid transparent; border-top-color: var(--accent);
189
- animation: spin 3s linear infinite;10px; }
190
- .input-mini { width: 100%; padding: 10px
191
  }
192
- .neural-circle::after {
193
- content: ""; position: absolute; top: ; border-radius: 8px; border: 1px solid var(--input-border); background: var(--input15px; left: 15px; right: 15px; bottom: 15px-bg); font-family: inherit; }
194
- .label-mini { font-size: 0.;
195
- border-radius: 50%; border: 3px solid transparent; border-top-color85rem; color: var(--text-secondary); margin-bottom: 5px; display: block;: #10B981;
196
- animation: spin 1.5s linear infinite reverse;
197
  }
198
- }
199
-
200
- /* Main Button */
201
- #generateButton {
202
- display: flex; align-items: center .neural-core {
203
- position: absolute; top: 50%; left: 50%; transform: translate; justify-content: center; gap: 0.75rem;
204
- width: 100(-50%, -50%);
205
- width: 20px; height: 20px;%; padding: 1.2rem; font-size: 1.2rem; font-weight: background: var(--primary); border-radius: 50%;
206
- box-shadow: 0 0700;
207
- background: linear-gradient(95deg, var(--accent-secondary) 20px var(--primary); animation: pulse 1s infinite alternate;
208
- }
209
-
210
- @keyframes0%, var(--accent-primary) 100%);
211
- color: #fff; border: none spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(; border-radius: var(--radius-btn); cursor: pointer;
212
- transition: all 0.360deg); } }
213
- @keyframes pulse { 0% { transform: translate(-50%, -53s ease; box-shadow: 0 6px 20px -5px var(--accent-primary-glow0%) scale(0.8); opacity: 0.6; } 100% { transform: translate(-50%, -50%) scale(1.2); opacity: 1; } }
214
-
215
- .status); margin-top: 2rem;
216
- }
217
- #generateButton:hover { transform: translateY(--text {
218
- font-weight: 600; background: linear-gradient(90deg, var3px) scale(1.01); box-shadow: 0 10px 25px -5px var(--accent-primary-glow); }
219
- #generateButton:disabled { opacity: 0.5(--primary), var(--accent));
220
- -webkit-background-clip: text; -webkit-text-fill; cursor: not-allowed; transform: none; }
221
-
222
- /* --- COOL LOADER --- */
223
- #-color: transparent;
224
- font-size: 1.1rem;
225
- }
226
-
227
- /* --- RESULT SECTIONaiLoader { display: none; margin-top: 3rem; flex-direction: column; align-items: center --- */
228
- #result-section { display: none; animation: slideUp 0.6s cubic-bezier(0; }
229
- .generator-container {
230
- position: relative; width: 100%; height: 2.2, 1, 0.3, 1); }
231
 
232
- .result-card {
233
- background00px; background: #0f172a; border-radius: 20px;
234
- : #fff; border-radius: 20px; overflow: hidden;
235
- box-shadow: 0 overflow: hidden; border: 1px solid #334155; box-shadow: 20px 40px -10px rgba(0,0,0,0.1); border: 0 0 50px rgba(74, 108, 250, 0.21px solid var(--border);
236
  }
237
-
238
- .player-top {
239
- background: linear-gradient);
240
- display: flex; flex-direction: column; align-items: center; justify-content: center;
241
- (135deg, #F8FAFC, #EFF6FF);
242
- padding: 20px; }
243
- .scan-line {
244
- position: absolute; top: 0; left: 0; width border-bottom: 1px solid var(--border);
245
- text-align: center;
246
  }
247
 
248
- : 100%; height: 4px;
249
- background: var(--accent-secondary);
250
- box-shadow audio { width: 100%; height: 45px; border-radius: 25px;: 0 0 15px var(--accent-secondary);
251
- animation: scan 2s linear margin-top: 10px; }
252
 
253
- .lyrics-box {
254
- padding: 25 infinite; z-index: 5;
255
- }
256
- .data-stream {
257
- position: absolute; widthpx; max-height: 400px; overflow-y: auto;
258
- text-align:: 100%; height: 100%; top:0; left:0;
259
- background center; line-height: 2.4; font-size: 1.05rem;
260
- color:: repeating-linear-gradient(0deg, transparent 0, transparent 20px, rgba(74, #374151; white-space: pre-wrap; background: #fff;
261
- }
262
- 108, 250, 0.1) 21px);
263
- opacity:
264
- .lyrics-tag {
265
- color: var(--primary); font-weight: 800; display0.3;
266
- }
267
- .loader-text {
268
- font-size: 1.2rem;: block; margin-top: 15px;
269
- font-size: 0.85em font-weight: 700; color: #fff; z-index: 10; margin-; letter-spacing: 1px; text-transform: uppercase;
270
  }
 
271
 
272
- .btn-downloadbottom: 10px; text-shadow: 0 0 10px rgba(255,2 {
273
- display: inline-flex; align-items: center; gap: 5px;
274
- color55,255,0.5);
275
- }
276
- .progress-bar-container {: var(--primary); text-decoration: none; font-weight: 700; font-size: width: 80%; height: 6px; background: #334155; border-0.9rem;
277
  }
 
278
 
279
- @keyframes slideUp { from { opacity: 0; transform: translateYradius: 3px; z-index: 10; overflow: hidden; }
280
- .progress-bar { width(40px); } to { opacity: 1; transform: translateY(0); } }
281
-
282
- /*: 0%; height: 100%; background: linear-gradient(90deg, var(--accent Hide Scrollbar */
283
- .lyrics-box::-webkit-scrollbar { width: 6px; }
284
- .lyrics--secondary), var(--accent-primary)); transition: width 0.3s; animation: fill-progress 20box::-webkit-scrollbar-thumb { background: #E5E7EB; border-radius: 3px;s linear forwards; }
285
-
286
- @keyframes scan { 0% { top: 0%; opacity: 0; }
287
  </style>
288
  </head>
289
  <body>
 
290
  <div class="container">
291
-
292
- <!-- } 10% { opacity: 1; } 90% { opacity: 1; } 10 HEADER -->
293
- <header id="mainHeader">
294
- <div class="logo">Alpha Music</div>
295
- 0% { top: 100%; opacity: 0; } }
296
-
297
- /* Result */
298
- #result-container { display: none; margin-top: 2rem; animation: fadeIn 0.8s; <div class="tagline">استودیو هوشمند ساخت موسیقی آلفا</div>
299
- </header> }
300
- .audio-player-wrapper {
301
- background: #fff; border: 2px solid var(--input
302
-
303
- <!-- INPUT SECTION -->
304
- <div id="inputSection" class="card">
305
- <div class="input-area">
306
- <textarea id="ideaInput" placeholder="توضیحات آهنگ خود را-border); border-radius: var(--radius-card); padding: 1.5rem;
307
- box-shadow: 0 10px 30px rgba(0,0,0,0.05); اینجا بنویسید...&#10;مثال: آهنگ پاپ عاشقانه درباره باران، صدای زن، احساس text-align: center;
308
- }
309
- audio { width: 100%; border-radius:ی..."></textarea>
310
- </div>
311
 
312
- <details>
313
- <summary>
314
- <span>تنظیمات پیش 30px; margin-top: 10px; }
315
- .lyrics-box {
316
- رفته (اختیاری)</span>
317
- </summary>
 
 
318
  <div class="settings-grid">
319
- margin-top: 1.5rem; padding: 1.5rem; background: var(--input-bg); border<div class="setting-item">
320
  <label>مدل هوش مصنوعی</label>
321
- <-radius: var(--radius-input);
322
- max-height: 400px; overflow-yselect id="modelSelect">
323
- <option value="acestep-v15-turbo">Alpha Turbo (: auto; white-space: pre-wrap; line-height: 1.8; text-align:سریع)</option>
324
- <option value="acestep-v15-turbo-shift3">Alpha Pro center;
325
- color: var(--text-primary); border: 1px dashed var(--input-border);
326
- (دقیق)</option>
327
  </select>
328
  </div>
329
  <div class="setting-item">
330
- }
331
-
332
- @media (max-width: 768px) { .grid-3 { grid-<label>تعداد گام (Steps)</label>
333
- <input type="number" id="steps"template-columns: 1fr; } }
334
- </style>
335
- </head>
336
- <body>
337
- value="8" min="4" max="20">
338
  </div>
339
  <div class="setting-item">
340
- <div class="container">
341
- <header>
342
- <canvas id="neural-canvas"></ <label>شانس (Seed)</label>
343
- <input type="text" id="seed" value="-canvas>
344
- <div class="header-content">
345
- <div class="logo-container">
346
- <svg class="logo-icon" viewBox="0 0 24 24" fill="1" placeholder="-1 برای تصادفی">
347
  </div>
348
  <div class="setting-item">
349
- <labelnone" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon>تعداد خروجی</label>
350
- <input type="number" value="1" disabled style="background: points="12 2 2 7 12 12 22 7 12 2"></ #f3f4f6; color: #9ca3af;">
351
  </div>
352
  </div>
353
- </details>polygon><polyline points="2 17 12 22 22 17"></polyline><
354
 
355
  <button id="generateBtn" class="btn-alpha">
356
- <span>ساخت آهنگ جادویی</span>
357
- polyline points="2 12 12 17 22 12"></polyline></svg>
358
- <svg width="24" height="24" viewBox="0 0 24 24" fill="</div>
359
- <h1>استودیو آلفا</h1>
360
- <p class="subtitle">هوش مصنوعی،none" xmlns="http://www.w3.org/2000/svg"><path d="M12 آهنگساز شخصی شما</p>
361
- </div>
362
- </header>
363
- <main>
364
- <!--22C17.5228 22 22 17.5228 22 Main Input -->
365
- <div class="form-group">
366
- <div class="form-label"> 12C22 6.47715 17.5228 2
367
- <svg width="24" height="24" viewBox="0 0 24 24 12 2C6.47715 2 2 6.4771" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 1a5 2 12C2 17.5228 6.477153 3 0 0 0-3 3v8a3 3 0 0 22 12 22Z" stroke="currentColor" stroke-width="2" stroke-linecap0 6 0V4a3 3 0 0 0-3-3z"></path="round" stroke-linejoin="round"/><path d="M2 12H22" stroke="currentColor"><path d="M19 10v2a7 7 0 0 1-1 stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/><path d="M124 0v-2"></path></svg>
368
- توصیف آهنگ (موضوع، سبک، خوان 2C14.5013 4.73835 15.92نده)
369
- </div>
370
- <textarea id="ideaInput" placeholder="مثال: یه آهنگ پاپ عاشق28 8.29203 16 12C15.9228 15انه غمگین، صدای زن، در مورد جاده شمال و بارون..."></textarea>
371
- </div>
372
-
373
- .708 14.5013 19.2616 12 <!-- Advanced Settings (Collapsible) -->
374
- <div class="form-group">
375
- <div class="22C9.49872 19.2616 8.077settings-toggle" onclick="toggleSettings()">
376
- <span>تنظیمات پیشرفته (اختیاری)</span>
377
- 25 15.708 8 12C8.07725 8.2 <svg width="20" height="20" viewBox="0 0 24 249203 9.49872 4.73835 12 " fill="none" stroke="currentColor" stroke-width="2"><polyline points="6 9 122Z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round 15 18 9"></polyline></svg>
378
- </div>
379
- <div class="settings-"/></svg>
380
  </button>
381
  </div>
382
 
383
- <!-- COOL LOADER -->
384
- <div id="content" id="settingsContent">
385
- <div class="grid-3">
386
- <div>
387
- <labelloader-container">
388
- <div class="neural-loader">
389
- <div class="neural-circle"></div>
390
- <div class="neural-core"></div>
391
  </div>
392
- <div class="status-text class="label-mini">مدل هوش مصنوعی</label>
393
- <select id="modelSelect" class="input" id="loaderText">در حال پردازش...</div>
394
- <p style="color: #9CA3AF;-mini">
395
- <option value="acestep-v15-turbo">Alpha Turbo (سریع)</option> font-size: 0.85rem; margin-top: 10px;">لطفاً صفحه را نب
396
- <option value="acestep-v15-turbo-shift3">Alpha Pro (دقیق)</option>
397
- </select>
398
- </div>
399
- <div>
400
- <label class="label-mini">تعداد مراحلندید، این فرآیند حدود ۱ دقیقه طول می‌کشد.</p>
401
- </div>
402
 
403
- <!-- RESULT SECTION -->
404
- <div id="result-section">
405
- <div class="result-card">
406
- <div (Steps)</label>
407
- <select id="stepsSelect" class="input-mini">
408
- <option value class="player-top">
409
- <div style="display: flex; justify-content: space-between;="8">۸ مرحله (نرمال)</option>
410
- <option value="12">۱۲ مرحله (کی align-items: center; margin-bottom: 10px;">
411
- <span style="font-weight: 7فیت بالا)</option>
412
- <option value="4">۴ مرحله (خیلی سریع)</option>
413
- 00; color: var(--text-dark);">خروجی نهایی آلفا</span>
414
- <a id="download </select>
415
- </div>
416
- <div>
417
- <label class="label-mini">تنوع (Seed)</labelLink" href="#" class="btn-download" download>
418
- <svg width="18" height="1>
419
- <input type="text" id="seedInput" class="input-mini" value="-1" placeholder="-8" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-1 تصادفی">
420
- </div>
421
- </div>
422
  </div>
423
- </div>
424
-
425
- <button id="generateButton">width="2"><path d="M21 15v4a2 2 0 0
426
- <svg width="24" height="24" viewBox="0 0 24 1-2 2H5a2 2 0 0 1-2-2v-424" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke"/><polyline points="7 10 12 15 17 10"/><line x1="-linejoin="round"><polygon points="5 3 19 12 5 21 5 312" y1="15" x2="12" y2="3"/></svg>
427
- "></polygon></svg>
428
- <span>ساخت آهنگ با هوش مصنوعی</span>
429
- </button>
430
 
431
- دانلود
432
- </a>
433
- </div>
434
- <div id="player-wrapper"></div>
435
- </div>
436
-
437
- < <!-- Cool Loader -->
438
- <div id="aiLoader">
439
- <div class="generator-container">
440
- div class="lyrics-box" id="lyrics-content">
441
- <!-- متن آهنگ اینجا قرار میگیرد -->
442
- </div><div class="scan-line"></div>
443
- <div class="data-stream"></div>
444
- <div
445
- </div>
446
 
447
- <button onclick="location.reload()" class="btn-alpha" style="margin class="loader-text" id="loaderText">در حال پردازش هسته آلفا...</div>
448
- -top: 20px; background: #fff; color: var(--text-dark); border: 2px<div class="progress-bar-container">
449
- <div class="progress-bar"></div>
450
- </div> solid var(--border); box-shadow: none;">
451
- ساخت یک آهنگ دیگر
452
- </button>
453
  </div>
454
- <div style="margin-top: 10px; color: #94a3b8; font-
455
 
456
  </div>
457
 
 
 
 
 
 
 
 
 
458
  <script>
459
- // Configuration
460
- const ACE_SPACE_URL = "https://size: 0.8rem;">لطفاً صفحه را نبندید</div>
461
- </div>
462
- </div> ace-step-ace-step-v1-5.hf.space/";
463
 
464
- // DOM Elements
465
-
466
- <!-- Final Result -->
467
- <div id="result-container">
468
- <div class="audio-
469
  const generateBtn = document.getElementById('generateBtn');
470
- const ideaInput = document.getElementById('ideaplayer-wrapper">
471
- <h3 style="margin: 0 0 10px 0; color:Input');
472
  const inputSection = document.getElementById('inputSection');
473
- const loaderContainer = document.getElementById var(--success-color);">✨ آهنگ شما آماده شد</h3>
474
- <div id="audioWrapper"></div>
475
- ('loader-container');
476
- const loaderText = document.getElementById('loaderText');
477
- const resultSection =<a id="downloadBtn" href="#" style="display: inline-block; margin-top: 15px; document.getElementById('result-section');
478
- const lyricsContent = document.getElementById('lyrics-content');
479
- const playerWrapper = document.getElementById('player-wrapper');
480
- const downloadLink = document.getElementById('downloadLink color: var(--accent-primary); text-decoration: none; font-weight: bold;">دانلود فایل MP3</a>
481
- ');
482
- const mainHeader = document.getElementById('mainHeader');
483
-
484
- // Inputs
485
- const modelSelect =</div>
486
- <div class="lyrics-box" id="lyricsOutput"></div>
487
- </div>
488
- </main>
489
- document.getElementById('modelSelect');
490
- const stepsInput = document.getElementById('steps');
491
- const seedInput </div>
492
-
493
- <script>
494
- const ACE_SPACE_URL = "https://ace-step = document.getElementById('seed');
495
-
496
- generateBtn.addEventListener('click', async () => {
497
- const idea = idea-ace-step-v1-5.hf.space/";
498
-
499
- // UI Elements
500
- constInput.value.trim();
501
- if (!idea) {
502
- ideaInput.focus();
503
- alert("لطف ideaInput = document.getElementById('ideaInput');
504
- const generateButton = document.getElementById('generateButton');
505
- const loaderاً توضیحات آهنگ را وارد کنید.");
506
- return;
507
- }
508
-
509
- // 1. Switch UI to Loader
510
- = document.getElementById('aiLoader');
511
- const loaderText = document.getElementById('loaderText');
512
- const inputSection.style.display = 'none';
513
- mainHeader.style.display = 'none'; // Hide header resultContainer = document.getElementById('result-container');
514
- const lyricsOutput = document.getElementById('lyricsOutput');
515
- const audioWrapper = document.getElementById('audioWrapper');
516
- const downloadBtn = document.getElementById('downloadBtn');
517
-
518
- for cleaner look during load
519
- loaderContainer.style.display = 'flex';
520
- loaderText.textContent = "آلف // Settings Logic
521
  function toggleSettings() {
522
- const content = document.getElementById('settingsContent');
523
- ا در حال نوشتن ترانه و ملودی...";
524
-
525
- try {
526
- // 2. Call Gemini ( content.classList.toggle('open');
527
  }
528
 
529
- // Main Logic
530
- generateButton.addEventListener('click', asyncLyrics & Prompt)
531
- const geminiResp = await fetch('/api/refine', {
532
- method: () => {
533
- const idea = ideaInput.value.trim();
534
- if (!idea) { alert('لط 'POST',
535
- headers: {'Content-Type': 'application/json'},
536
- body: JSON.stringifyفا ایده آهنگ را بنویسید.'); return; }
537
-
538
- // 1. UI Transition
539
- generateButton({ idea: idea })
540
- });
541
-
542
- const geminiData = await geminiResp.json();
543
- if (gem.style.display = 'none';
544
- resultContainer.style.display = 'none';
545
- loader.style.displayiniData.error) throw new Error("Gemini Error: " + geminiData.error);
546
 
547
- // 3 = 'flex';
548
- loaderText.innerText = "هوش مصنوعی آلفا در حال نوشتن شعر...";
549
- . Update Loader & Call ACE-Step
550
- loaderText.textContent = "آلفا در حال تنظیم و ساخت
551
- // Scroll to loader
552
- loader.scrollIntoView({ behavior: 'smooth' });
553
 
554
  try {
555
- آهنگ...";
556
-
557
- const payload = [
558
- modelSelect.value, // Model
559
- "custom",// 2. Call Gemini for Text & Prompt
560
  const refineResponse = await fetch('/api/refine', {
561
- null, "unknown",
562
- geminiData.music_prompt, // Prompt from Gemini
563
- geminiData.lyrics method: 'POST',
564
  headers: {'Content-Type': 'application/json'},
565
- body:, // Lyrics from Gemini
566
- 0, "", "", "unknown",
567
- parseInt(stepsInput.value) JSON.stringify({ idea: idea })
568
  });
569
-
570
- const refinedData = await refineResponse.json(); || 8, // Steps
571
- 7, true,
572
- parseInt(seedInput.value) || -
573
- if (refinedData.error) throw new Error(refinedData.error);
574
-
575
- const lyrics = refinedData1, // Seed
576
- null, -1, 1, null, null, 0, -1,
577
- "Fill the audio semantic mask based on the given conditions:",
578
- 1, "text2music", false, 0, 1, 3, "ode", "", "mp3", 0.85,
579
- true, 2, 0, 0.9, "NO USER INPUT", true,.lyrics;
580
- const prompt = refinedData.music_prompt;
581
-
582
- // Update Loader
583
- loaderText.innerText = "استودیو آلفا در حال ضبط آهنگ...";
584
 
585
- // 3. Call ACE-Step for true, true, null, false, true, false, false, 0.5, 8, null, [], false, null, null, null, null
586
- ];
587
 
588
- const session_hash = Math.random().toString(36).substring(2);
 
589
 
590
- const aceResp = await fetch(`${ACE_SPACE_URL}grad Audio
591
- const model = document.getElementById('modelSelect').value;
592
- const steps = Number(document.getElementById('stepsSelect').value);
593
- const seed = document.getElementById('seedInput').value;
594
 
595
- const payloadio_api/queue/join`, {
596
- method: 'POST',
597
- headers: { 'Content-Type': 'application/json' },
598
- body: JSON.stringify({ data: payload, fn_index: 77, session_hash })
599
- });
600
 
601
- if (!aceResp.ok) throw new Error(' = [
602
  model, "custom", null, "unknown",
603
  prompt, lyrics,
604
- 0, "", "", "unknown", steps, 7, true, seed, null, -1, 1, null, null, 0, -1,
 
605
  "Fill the audio semantic mask based on the given conditions:",
606
  1, "text2music", false, 0, 1, 3, "ode", "", "mp3", 0.85,
607
- true, 2, 0, 0.9, "NO USERخطا در اتصال به سرور موزیک');
608
-
609
- // 4. Handle SSE
610
- const eventSource = new EventSource INPUT", true, true, true, null, false, true, false, false, 0.5, 8, null, [], false, null, null, null, null
611
  ];
612
 
613
- const session_hash =(`${ACE_SPACE_URL}gradio_api/queue/data?session_hash=${session_hash}`);
614
-
615
- eventSource.onmessage = (event) => {
616
- const msg = JSON.parse(event. Math.random().toString(36).substring(2);
617
 
618
- const joinResp = await fetch(`${ACE_data);
619
-
620
- if (msg.msg === 'process_starts') {
621
- loaderText.textContentSPACE_URL}gradio_api/queue/join`, {
622
  method: 'POST',
623
- headers = "آهنگ در حال ضبط استودیویی...";
624
- }
625
- else if (msg.msg: { 'Content-Type': 'application/json' },
626
  body: JSON.stringify({ data: payload, fn_index: 77, session_hash })
627
  });
628
 
629
- if (!joinResp.ok === 'process_completed') {
630
- eventSource.close();
631
- showResult(msg.output, geminiData.lyrics);
632
- }
633
- };
634
-
635
- eventSource.onerror = () => {
636
- ) throw new Error('خطا در اتصال به سرور موزیک');
637
-
638
- const eventSource = new EventSource(`${ACE_ throw new Error('ارتباط با سرور قطع شد.');
639
- };
640
 
641
- } catch (error) {
642
- SPACE_URL}gradio_api/queue/data?session_hash=${session_hash}`);
643
 
644
- eventalert("خطا: " + error.message);
645
- location.reload(); // Reset on error
646
- }Source.onmessage = (event) => {
647
  const msg = JSON.parse(event.data);
648
 
649
  if (msg.msg === 'process_starts') {
650
- loaderText.innerText = "در
651
- });
652
-
653
- function showResult(outputData, lyricsText) {
654
- loaderContainer.style.display = 'none حال رندر نهایی صدا...";
655
  } else if (msg.msg === 'process_completed') {
656
- event';
657
- mainHeader.style.display = 'block';
658
- resultSection.style.display = 'blockSource.close();
659
  showResult(msg.output, lyrics);
660
  }
661
  };
662
 
663
- eventSource.onerror';
664
-
665
- // Find Audio URL
666
- let audioUrl = null;
667
- function findAudio(obj) {
668
- if (typeof obj === 'string' && obj.includes('/file=') && obj.endsWith('.mp3')) { = () => { throw new Error('ارتباط با سرور قطع شد.'); };
669
 
670
- } catch (e)
671
- audioUrl = obj;
672
- } else if (obj && typeof obj === 'object') {
673
- {
674
  alert("خطا: " + e.message);
675
- loader.style.display = 'noneif (obj.url && obj.url.endsWith('.mp3')) audioUrl = obj.url;
676
- ';
677
- generateButton.style.display = 'flex';
678
  }
679
  });
680
 
681
- function showResultObject.values(obj).forEach(findAudio);
682
- }
683
- }
684
- findAudio(outputData(data, lyrics) {
685
  let audioUrl = null;
686
  function traverse(obj) {
687
- if);
688
-
689
- if (audioUrl) {
690
- const fullUrl = audioUrl.startsWith('http') ? audio (typeof obj === 'string' && obj.includes('/file=') && obj.endsWith('.mp3')) {Url : ACE_SPACE_URL.replace(/\/$/, '') + audioUrl;
691
-
692
- // Create Player
693
  audioUrl = obj;
694
  } else if (obj && typeof obj === 'object') {
695
-
696
- playerWrapper.innerHTML = `<audio controls autoplay src="${fullUrl}"></audio>`;
697
- downloadLink.href = fullif (obj.url && obj.url.endsWith('.mp3')) audioUrl = obj.url;
698
  Object.values(obj).forEach(traverse);
699
  }
700
  }
701
- traverse(data);
702
 
703
- Url;
704
-
705
- // Format Lyrics
706
- const formattedLyrics = lyricsText.replace(/\[(.*?)\]/g, '<span class="lyrics-tag">[$1]</span>');
707
- lyricsContent.innerHTML = formattedLyrics;if (audioUrl) {
708
  const fullUrl = audioUrl.startsWith('http') ? audioUrl : ACE_SPACE_URL.replace(/\/$/, '') + audioUrl;
709
 
710
- audioWrapper.innerHTML = `<
 
 
 
 
 
 
 
711
  } else {
712
- alert("فایل صوتی یافت نشد!");
713
- location.reload();
714
- audio controls autoplay src="${fullUrl}"></audio>`;
715
- downloadBtn.href = fullUrl;
716
- lyrics}
717
  }
718
  </script>
719
  </body>
 
1
+ <!DOCTYPE html>
2
  <html lang="fa" dir="rtl">
3
  <head>
4
  <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>استودیو موزیک آلفا</title>
7
+ <link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;500;600;700;800&display=swap" rel="stylesheet">
 
 
8
  <style>
9
  :root {
10
  --app-font: 'Vazirmatn', sans-serif;
 
12
  --panel-bg: #FFFFFF;
13
  --panel-border: #EAEFF7;
14
  --input-bg: #F6F8FB;
15
+ --input-border: #E1E7EF;
 
 
 
16
  --text-primary: #1A202C;
17
  --text-secondary: #626F86;
18
  --accent-primary: #4A6CFA;
19
+ --accent-glow: rgba(74, 108, 250, 0.3);
20
+ --shadow-card: 0 10px 30px -5px rgba(0, 0, 0, 0.05);
21
  --radius-card: 24px;
22
+ --radius-input: 16px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  }
24
 
25
+ body { font-family: var(--app-font); background-color: var(--app-bg); color: var(--text-primary); margin: 0; padding: 2rem 1rem; display: flex; justify-content: center; min-height: 100vh; }
26
  .container { max-width: 600px; width: 100%; position: relative; z-index: 2; }
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
+ /* هدر */
29
+ header { text-align: center; margin-bottom: 2.5rem; }
30
+ h1 {
31
+ font-size: 2.2rem; font-weight: 900; margin: 0;
32
+ background: linear-gradient(135deg, #1A202C 0%, #4A6CFA 100%);
33
+ -webkit-background-clip: text; -webkit-text-fill-color: transparent;
34
+ letter-spacing: -1px;
 
 
 
35
  }
36
+ .alpha-badge {
37
+ background: rgba(74, 108, 250, 0.1); color: var(--accent-primary);
38
+ padding: 4px 12px; border-radius: 20px; font-size: 0.8rem; font-weight: 700;
39
+ display: inline-block; margin-bottom: 10px;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  }
 
 
 
41
 
42
+ /* کارت اصلی */
43
+ .main-card {
44
+ background: var(--panel-bg); border-radius: var(--radius-card);
45
+ box-shadow: var(--shadow-card); border: 1px solid var(--panel-border);
46
+ padding: 2rem; position: relative; overflow: hidden;
47
+ transition: transform 0.3s ease;
 
 
 
 
 
 
 
 
48
  }
49
 
 
 
 
50
  textarea {
51
+ width: 100%; background: var(--input-bg); border: 2px solid var(--input-border);
52
+ border-radius: var(--radius-input); padding: 1.2rem;
53
+ font-family: inherit; font-size: 1rem; color: var(--text-primary);
54
+ min-height: 140px; resize: none; outline: none; transition: all 0.3s;
 
 
 
 
 
55
  }
56
+ textarea:focus { border-color: var(--accent-primary); background: #fff; box-shadow: 0 0 0 4px var(--accent-glow); }
 
 
 
 
57
 
58
+ /* تنظیمات پیشر��ته (کشویی) */
59
  .settings-toggle {
60
+ display: flex; align-items: center; gap: 8px; cursor: pointer;
61
+ color: var(--text-secondary); font-size: 0.9rem; font-weight: 600;
62
+ margin-top: 1rem; padding: 10px; border-radius: 10px;
63
+ transition: background 0.2s; user-select: none;
 
 
 
 
 
64
  }
65
+ .settings-toggle:hover { background: var(--input-bg); color: var(--accent-primary); }
66
+ .settings-toggle svg { transition: transform 0.3s; }
67
+ .settings-toggle.open svg { transform: rotate(180deg); }
68
+
69
+ .settings-panel {
70
+ max-height: 0; overflow: hidden; transition: max-height 0.4s cubic-bezier(0, 1, 0, 1);
71
+ background: var(--input-bg); border-radius: var(--radius-input); margin-top: 5px;
72
  }
73
+ .settings-panel.open { max-height: 300px; border: 1px solid var(--input-border); }
74
 
75
+ .settings-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 15px; padding: 20px; }
76
+ .setting-item label { display: block; font-size: 0.8rem; color: var(--text-secondary); margin-bottom: 5px; }
77
+ .setting-item input, .setting-item select {
78
+ width: 100%; padding: 10px; border-radius: 10px; border: 1px solid var(--input-border);
79
+ background: #fff; font-family: inherit; font-size: 0.9rem; outline: none;
80
  }
81
+
82
+ /* دکمه اصلی */
83
+ .btn-alpha {
84
+ width: 100%; padding: 18px; margin-top: 2rem;
85
+ background: linear-gradient(135deg, var(--accent-primary), #2563EB);
86
+ color: #fff; border: none; border-radius: var(--radius-input);
87
+ font-size: 1.1rem; font-weight: 700; cursor: pointer;
88
+ display: flex; justify-content: center; align-items: center; gap: 10px;
89
+ box-shadow: 0 10px 25px -5px var(--accent-glow);
90
+ transition: all 0.3s; position: relative; overflow: hidden;
91
  }
92
+ .btn-alpha:hover { transform: translateY(-3px); box-shadow: 0 15px 30px -5px var(--accent-glow); }
93
+ .btn-alpha:active { transform: scale(0.98); }
94
+
95
+ /* لودر خفن (Cyberpunk Style) */
96
+ #loaderOverlay {
97
+ display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%;
98
+ background: rgba(255, 255, 255, 0.95); z-index: 100;
99
+ flex-direction: column; justify-content: center; align-items: center;
100
+ backdrop-filter: blur(10px);
101
  }
 
 
102
 
103
+ .scanner {
104
+ position: relative; width: 200px; height: 200px;
105
+ background: radial-gradient(circle, rgba(74, 108, 250, 0.1) 0%, transparent 70%);
106
+ border-radius: 50%; display: flex; justify-content: center; align-items: center;
107
  }
108
+ .scanner::before, .scanner::after {
109
+ content: ''; position: absolute; border-radius: 50%;
110
+ border: 2px solid transparent; border-top-color: var(--accent-primary); border-bottom-color: var(--accent-primary);
111
+ animation: spin 3s linear infinite;
 
112
  }
113
+ .scanner::before { width: 100%; height: 100%; opacity: 0.7; }
114
+ .scanner::after { width: 70%; height: 70%; animation-direction: reverse; animation-duration: 2s; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
 
116
+ .core-pulse {
117
+ width: 40px; height: 40px; background: var(--accent-primary); border-radius: 50%;
118
+ box-shadow: 0 0 30px var(--accent-primary);
119
+ animation: pulse 1.5s ease-in-out infinite alternate;
120
  }
121
+
122
+ .loading-text {
123
+ margin-top: 30px; font-size: 1.2rem; font-weight: 700; color: var(--text-primary);
124
+ animation: fadeText 2s infinite;
 
 
 
 
 
125
  }
126
 
127
+ @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
128
+ @keyframes pulse { 0% { transform: scale(0.8); opacity: 0.8; } 100% { transform: scale(1.2); opacity: 1; } }
129
+ @keyframes fadeText { 0%, 100% { opacity: 0.6; } 50% { opacity: 1; } }
 
130
 
131
+ /* نتیجه نهایی */
132
+ #resultCard { display: none; animation: slideUp 0.8s cubic-bezier(0.2, 1, 0.2, 1); }
133
+
134
+ .result-header { text-align: center; margin-bottom: 20px; }
135
+ .result-title { font-size: 1.5rem; font-weight: 800; color: var(--text-primary); }
136
+
137
+ .player-container {
138
+ background: #F1F5F9; padding: 20px; border-radius: 20px; margin-bottom: 20px;
139
+ display: flex; align-items: center; justify-content: center;
 
 
 
 
 
 
 
 
140
  }
141
+ audio { width: 100%; height: 45px; border-radius: 30px; }
142
 
143
+ .lyrics-box {
144
+ background: #fff; border: 1px solid var(--panel-border); border-radius: 16px;
145
+ padding: 25px; max-height: 400px; overflow-y: auto;
146
+ text-align: center; line-height: 2.4; font-size: 1.05rem; color: #4a5568;
147
+ white-space: pre-wrap;
148
  }
149
+ .tag { color: var(--accent-primary); font-weight: 900; display: block; margin-top: 15px; font-size: 0.85em; letter-spacing: 1px; }
150
 
151
+ @keyframes slideUp { from { opacity: 0; transform: translateY(40px); } to { opacity: 1; transform: translateY(0); } }
 
 
 
 
 
 
 
152
  </style>
153
  </head>
154
  <body>
155
+
156
  <div class="container">
157
+ <header>
158
+ <span class="alpha-badge">نسخه هوشمند</span>
159
+ <h1>استودیو موزیک آلفا</h1>
160
+ </header>
161
+
162
+ <!-- بخش ورودی و تنظیمات -->
163
+ <div id="inputSection" class="main-card">
164
+ <textarea id="ideaInput" placeholder="توضیحات آهنگ رو اینجا بنویس... (مثال: یه آهنگ رپ گنگ در مورد موفقیت با بیت سنگین)"></textarea>
 
 
 
 
 
 
 
 
 
 
 
 
165
 
166
+ <!-- دکمه تنظیمات -->
167
+ <div class="settings-toggle" onclick="toggleSettings()">
168
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="3"></circle><path d="M19.4 15a1.65 1.65 0 0 0 .33 1.82l.06.06a2 2 0 0 1 0 2.83 2 2 0 0 1-2.83 0l-.06-.06a1.65 1.65 0 0 0-1.82-.33 1.65 1.65 0 0 0-1 1.51V21a2 2 0 0 1-2 2 2 2 0 0 1-2-2v-.09A1.65 1.65 0 0 0 9 19.4a1.65 1.65 0 0 0-1.82.33l-.06.06a2 2 0 0 1-2.83 0 2 2 0 0 1 0-2.83l.06-.06a1.65 1.65 0 0 0 .33-1.82 1.65 1.65 0 0 0-1.51-1H3a2 2 0 0 1-2-2 2 2 0 0 1 2-2h.09A1.65 1.65 0 0 0 4.6 9a1.65 1.65 0 0 0-.33-1.82l-.06-.06a2 2 0 0 1 0-2.83 2 2 0 0 1 2.83 0l.06.06a1.65 1.65 0 0 0 1.82.33H9a1.65 1.65 0 0 0 1-1.51V3a2 2 0 0 1 2-2 2 2 0 0 1 2 2v.09a1.65 1.65 0 0 0 1 1.51 1.65 1.65 0 0 0 1.82-.33l.06-.06a2 2 0 0 1 2.83 0 2 2 0 0 1 0 2.83l-.06.06a1.65 1.65 0 0 0-.33 1.82V9a1.65 1.65 0 0 0 1.51 1H21a2 2 0 0 1 2 2 2 2 0 0 1-2 2h-.09a1.65 1.65 0 0 0-1.51 1z"></path></svg>
169
+ تنظیمات پیشرفته
170
+ </div>
171
+
172
+ <!-- پنل تنظیمات مخفی -->
173
+ <div class="settings-panel" id="settingsPanel">
174
  <div class="settings-grid">
175
+ <div class="setting-item">
176
  <label>مدل هوش مصنوعی</label>
177
+ <select id="modelSelector">
178
+ <option value="acestep-v15-turbo">Alpha Turbo (سریع)</option>
179
+ <option value="acestep-v15-turbo-shift3">Alpha Pro (دقیق)</option>
 
 
 
180
  </select>
181
  </div>
182
  <div class="setting-item">
183
+ <label>کیفیت (Steps)</label>
184
+ <input type="number" id="steps" value="8" min="4" max="20">
 
 
 
 
 
 
185
  </div>
186
  <div class="setting-item">
187
+ <label>مدت زمان (ثانیه)</label>
188
+ <input type="number" id="duration" value="60" disabled style="opacity: 0.6; cursor: not-allowed;" title="توسط هوش مصنوعی تعیین می‌شود">
 
 
 
 
 
189
  </div>
190
  <div class="setting-item">
191
+ <labelنوع (Seed)</label>
192
+ <input type="text" id="seed" value="-1" placeholder="-1 تصادفی">
193
  </div>
194
  </div>
195
+ </div>
196
 
197
  <button id="generateBtn" class="btn-alpha">
198
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="11 5 6 9 2 9 2 15 6 15 11 19 11 5"></polygon><path d="M19.07 4.93a10 10 0 0 1 0 14.14M15.54 8.46a5 5 0 0 1 0 7.07"></path></svg>
199
+ ساخت آهنگ هوشمند
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
200
  </button>
201
  </div>
202
 
203
+ <!-- نتیجه نهایی -->
204
+ <div id="resultCard" class="main-card" style="display:none; margin-top: 20px;">
205
+ <div class="result-header">
206
+ <div class="result-title">آهنگ شما آماده است 🎵</div>
207
+ <a id="downloadLink" href="#" style="color: var(--accent-primary); font-weight: 700; text-decoration: none; display: block; margin-top: 5px;">دانلود فایل با کیفیت بالا</a>
 
 
 
208
  </div>
 
 
 
 
 
 
 
 
 
 
209
 
210
+ <div class="player-container" id="playerWrapper">
211
+ <!-- پلیر اینجا قرار می‌گیرد -->
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  </div>
 
 
 
 
 
 
 
213
 
214
+ <div style="text-align: center; margin-bottom: 10px; color: var(--text-secondary); font-size: 0.9rem;">متن آهنگ</div>
215
+ <div class="lyrics-box" id="finalLyrics"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
216
 
217
+ <button onclick="location.reload()" class="btn-alpha" style="background: var(--input-bg); color: var(--text-primary); margin-top: 15px;">ساخت یک آهنگ دیگر</button>
 
 
 
 
 
218
  </div>
 
219
 
220
  </div>
221
 
222
+ <!-- انیمیشن لودینگ خفن -->
223
+ <div id="loaderOverlay">
224
+ <div class="scanner">
225
+ <div class="core-pulse"></div>
226
+ </div>
227
+ <div class="loading-text" id="loadingStatus">در حال آنالیز ایده...</div>
228
+ </div>
229
+
230
  <script>
231
+ const ACE_SPACE_URL = "https://ace-step-ace-step-v1-5.hf.space/";
 
 
 
232
 
233
+ // المان‌ها
234
+ const ideaInput = document.getElementById('ideaInput');
 
 
 
235
  const generateBtn = document.getElementById('generateBtn');
 
 
236
  const inputSection = document.getElementById('inputSection');
237
+ const loader = document.getElementById('loaderOverlay');
238
+ const loadingStatus = document.getElementById('loadingStatus');
239
+ const resultCard = document.getElementById('resultCard');
240
+ const playerWrapper = document.getElementById('playerWrapper');
241
+ const finalLyrics = document.getElementById('finalLyrics');
242
+ const downloadLink = document.getElementById('downloadLink');
243
+
244
+ // باز و بسته کردن تنظیمات
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
245
  function toggleSettings() {
246
+ document.querySelector('.settings-toggle').classList.toggle('open');
247
+ document.getElementById('settingsPanel').classList.toggle('open');
 
 
 
248
  }
249
 
250
+ generateBtn.addEventListener('click', async () => {
251
+ if (!ideaInput.value.trim()) return alert("لطفا ایده آهنگ را بنویسید");
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
 
253
+ // شروع فرآیند
254
+ inputSection.style.display = 'none';
255
+ loader.style.display = 'flex';
256
+ loadingStatus.innerText = "هوش مصنوعی آلفا در حال نوشتن شعر...";
 
 
257
 
258
  try {
259
+ // 1. دریافت متن و پرامپت از جمینای
 
 
 
 
260
  const refineResponse = await fetch('/api/refine', {
261
+ method: 'POST',
 
 
262
  headers: {'Content-Type': 'application/json'},
263
+ body: JSON.stringify({ idea: ideaInput.value })
 
 
264
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
265
 
266
+ const data = await refineResponse.json();
267
+ if (data.error) throw new Error(data.error);
268
 
269
+ const lyrics = data.lyrics;
270
+ const prompt = data.music_prompt;
271
 
272
+ // 2. شروع ساخت آهنگ بلافاصله
273
+ loadingStatus.innerText = "در حال ضبط در استودیو آلفا (زمان تقریبی: 1 دقیقه)...";
 
 
274
 
275
+ // تنظیمات
276
+ const model = document.getElementById('modelSelector').value;
277
+ const steps = parseInt(document.getElementById('steps').value);
278
+ const seed = document.getElementById('seed').value;
 
279
 
280
+ const payload = [
281
  model, "custom", null, "unknown",
282
  prompt, lyrics,
283
+ 0, "", "", "unknown",
284
+ steps, 7, true, seed, null, -1, 1, null, null, 0, -1,
285
  "Fill the audio semantic mask based on the given conditions:",
286
  1, "text2music", false, 0, 1, 3, "ode", "", "mp3", 0.85,
287
+ true, 2, 0, 0.9, "NO USER INPUT", true, true, true, null, false, true, false, false, 0.5, 8, null, [], false, null, null, null, null
 
 
 
288
  ];
289
 
290
+ const session_hash = Math.random().toString(36).substring(2);
 
 
 
291
 
292
+ const joinResp = await fetch(`${ACE_SPACE_URL}gradio_api/queue/join`, {
 
 
 
293
  method: 'POST',
294
+ headers: { 'Content-Type': 'application/json' },
 
 
295
  body: JSON.stringify({ data: payload, fn_index: 77, session_hash })
296
  });
297
 
298
+ if (!joinResp.ok) throw new Error('خطا در اتصال به سرور');
 
 
 
 
 
 
 
 
 
 
299
 
300
+ const eventSource = new EventSource(`${ACE_SPACE_URL}gradio_api/queue/data?session_hash=${session_hash}`);
 
301
 
302
+ eventSource.onmessage = (event) => {
 
 
303
  const msg = JSON.parse(event.data);
304
 
305
  if (msg.msg === 'process_starts') {
306
+ loadingStatus.innerText = "آلفا در حال تنظیم ملودی...";
 
 
 
 
307
  } else if (msg.msg === 'process_completed') {
308
+ eventSource.close();
309
+ loader.style.display = 'none';
 
310
  showResult(msg.output, lyrics);
311
  }
312
  };
313
 
314
+ eventSource.onerror = () => {
315
+ throw new Error('قطع ارتباط.');
316
+ };
 
 
 
317
 
318
+ } catch (e) {
 
 
 
319
  alert("خطا: " + e.message);
320
+ loader.style.display = 'none';
321
+ inputSection.style.display = 'block';
 
322
  }
323
  });
324
 
325
+ function showResult(outputData, lyricsText) {
 
 
 
326
  let audioUrl = null;
327
  function traverse(obj) {
328
+ if (typeof obj === 'string' && obj.includes('/file=') && obj.endsWith('.mp3')) {
 
 
 
 
 
329
  audioUrl = obj;
330
  } else if (obj && typeof obj === 'object') {
331
+ if (obj.url && obj.url.endsWith('.mp3')) audioUrl = obj.url;
 
 
332
  Object.values(obj).forEach(traverse);
333
  }
334
  }
335
+ traverse(outputData);
336
 
337
+ if (audioUrl) {
 
 
 
 
338
  const fullUrl = audioUrl.startsWith('http') ? audioUrl : ACE_SPACE_URL.replace(/\/$/, '') + audioUrl;
339
 
340
+ playerWrapper.innerHTML = `<audio controls autoplay src="${fullUrl}"></audio>`;
341
+ downloadLink.href = fullUrl;
342
+
343
+ // فرمت کردن متن شعر (رنگ کردن تگ‌ها)
344
+ const formattedLyrics = lyricsText.replace(/\[(.*?)\]/g, '<span class="tag">[$1]</span>');
345
+ finalLyrics.innerHTML = formattedLyrics;
346
+
347
+ resultCard.style.display = 'block';
348
  } else {
349
+ alert("مشکلی در تولید فایل صوتی پیش آمد.");
350
+ inputSection.style.display = 'block';
351
+ }
 
 
352
  }
353
  </script>
354
  </body>