seqinho commited on
Commit
3a79daf
·
verified ·
1 Parent(s): ed9b608

Add 3 files

Browse files
Files changed (3) hide show
  1. README.md +7 -5
  2. index.html +1580 -19
  3. prompts.txt +2 -0
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Rezonator
3
- emoji: 🦀
4
- colorFrom: gray
5
- colorTo: blue
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: rezonator
3
+ emoji: 🐳
4
+ colorFrom: purple
5
+ colorTo: yellow
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,1580 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="ru">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Резонатор Сознания 3.0 | Цифровая Революция</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/tone/14.8.49/Tone.js"></script>
9
+ <link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Rajdhani:wght@300;500;700&display=swap" rel="stylesheet">
10
+ <style>
11
+ :root {
12
+ --neon-cyan: #00f7ff;
13
+ --neon-pink: #ff00f7;
14
+ --neon-yellow: #f7ff00;
15
+ --matrix-green: #00ff41;
16
+ --dark-bg: #050505;
17
+ --hologram-blue: rgba(0, 183, 255, 0.2);
18
+ }
19
+
20
+ body {
21
+ font-family: 'Rajdhani', sans-serif;
22
+ background-color: var(--dark-bg);
23
+ color: white;
24
+ overflow: hidden;
25
+ touch-action: manipulation;
26
+ background-image:
27
+ radial-gradient(circle at 20% 30%, var(--hologram-blue) 0%, transparent 20%),
28
+ radial-gradient(circle at 80% 70%, rgba(255, 0, 183, 0.1) 0%, transparent 20%);
29
+ }
30
+
31
+ .cyber-title {
32
+ font-family: 'Orbitron', sans-serif;
33
+ text-shadow: 0 0 15px var(--neon-cyan);
34
+ letter-spacing: 2px;
35
+ background: linear-gradient(90deg, var(--neon-cyan), var(--neon-pink));
36
+ -webkit-background-clip: text;
37
+ -webkit-text-fill-color: transparent;
38
+ }
39
+
40
+ .cyber-card {
41
+ background: rgba(10, 10, 20, 0.7);
42
+ backdrop-filter: blur(10px);
43
+ border: 1px solid rgba(0, 247, 255, 0.3);
44
+ box-shadow:
45
+ 0 0 15px rgba(0, 247, 255, 0.3),
46
+ inset 0 0 10px rgba(0, 183, 255, 0.2);
47
+ border-radius: 8px;
48
+ transition: all 0.3s ease;
49
+ }
50
+
51
+ .cyber-card:hover {
52
+ box-shadow:
53
+ 0 0 25px rgba(0, 247, 255, 0.5),
54
+ inset 0 0 15px rgba(0, 183, 255, 0.3);
55
+ transform: translateY(-3px);
56
+ }
57
+
58
+ .cyber-btn {
59
+ position: relative;
60
+ overflow: hidden;
61
+ border: none;
62
+ background: linear-gradient(135deg, rgba(0, 247, 255, 0.2), rgba(255, 0, 183, 0.2));
63
+ color: white;
64
+ font-weight: bold;
65
+ letter-spacing: 1px;
66
+ transition: all 0.3s ease;
67
+ box-shadow: 0 0 10px rgba(0, 247, 255, 0.3);
68
+ }
69
+
70
+ .cyber-btn:hover {
71
+ box-shadow: 0 0 20px rgba(0, 247, 255, 0.5);
72
+ transform: translateY(-2px);
73
+ }
74
+
75
+ .cyber-btn:active {
76
+ transform: translateY(1px);
77
+ }
78
+
79
+ .cyber-btn::before {
80
+ content: '';
81
+ position: absolute;
82
+ top: 0;
83
+ left: -100%;
84
+ width: 100%;
85
+ height: 100%;
86
+ background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.2), transparent);
87
+ transition: all 0.7s ease;
88
+ }
89
+
90
+ .cyber-btn:hover::before {
91
+ left: 100%;
92
+ }
93
+
94
+ .cyber-slider::-webkit-slider-thumb {
95
+ -webkit-appearance: none;
96
+ width: 18px;
97
+ height: 18px;
98
+ border-radius: 50%;
99
+ background: var(--neon-cyan);
100
+ cursor: pointer;
101
+ box-shadow: 0 0 10px var(--neon-cyan);
102
+ border: 2px solid var(--dark-bg);
103
+ }
104
+
105
+ .cyber-visualizer {
106
+ position: relative;
107
+ background:
108
+ radial-gradient(circle at center, rgba(0, 183, 255, 0.05) 0%, transparent 70%),
109
+ linear-gradient(to bottom, rgba(255, 0, 183, 0.02) 0%, transparent 100%);
110
+ }
111
+
112
+ .cyber-particle {
113
+ position: absolute;
114
+ border-radius: 50%;
115
+ pointer-events: none;
116
+ transform: translate(-50%, -50%);
117
+ mix-blend-mode: screen;
118
+ }
119
+
120
+ @keyframes cyber-pulse {
121
+ 0% { opacity: 0.3; transform: scale(0.95); }
122
+ 50% { opacity: 1; transform: scale(1.05); }
123
+ 100% { opacity: 0.3; transform: scale(0.95); }
124
+ }
125
+
126
+ .cyber-pulse {
127
+ animation: cyber-pulse 2s infinite ease-in-out;
128
+ }
129
+
130
+ .cyber-active {
131
+ box-shadow: 0 0 25px var(--neon-cyan) !important;
132
+ border-color: var(--neon-cyan) !important;
133
+ }
134
+
135
+ .cyber-nav-portal {
136
+ position: relative;
137
+ width: 60px;
138
+ height: 60px;
139
+ border-radius: 50%;
140
+ display: flex;
141
+ align-items: center;
142
+ justify-content: center;
143
+ overflow: hidden;
144
+ }
145
+
146
+ .cyber-nav-portal::before {
147
+ content: '';
148
+ position: absolute;
149
+ top: -50%;
150
+ left: -50%;
151
+ width: 200%;
152
+ height: 200%;
153
+ background: conic-gradient(
154
+ transparent,
155
+ var(--neon-cyan),
156
+ var(--neon-pink),
157
+ transparent
158
+ );
159
+ animation: rotate 3s linear infinite;
160
+ }
161
+
162
+ @keyframes rotate {
163
+ from { transform: rotate(0deg); }
164
+ to { transform: rotate(360deg); }
165
+ }
166
+
167
+ .cyber-nav-portal-inner {
168
+ position: relative;
169
+ z-index: 2;
170
+ width: 56px;
171
+ height: 56px;
172
+ border-radius: 50%;
173
+ background: var(--dark-bg);
174
+ display: flex;
175
+ align-items: center;
176
+ justify-content: center;
177
+ font-weight: bold;
178
+ font-size: 1.5rem;
179
+ color: var(--neon-cyan);
180
+ }
181
+
182
+ .cyber-tooltip {
183
+ position: fixed;
184
+ bottom: 5rem;
185
+ left: 50%;
186
+ transform: translateX(-50%);
187
+ background: rgba(0, 15, 20, 0.9);
188
+ border: 1px solid var(--neon-cyan);
189
+ color: var(--neon-cyan);
190
+ padding: 0.5rem 1rem;
191
+ border-radius: 4px;
192
+ font-size: 0.9rem;
193
+ box-shadow: 0 0 15px rgba(0, 247, 255, 0.5);
194
+ z-index: 100;
195
+ opacity: 1;
196
+ transition: opacity 0.5s ease;
197
+ }
198
+
199
+ .cyber-tooltip.hidden {
200
+ opacity: 0;
201
+ }
202
+
203
+ .cyber-grid {
204
+ display: grid;
205
+ grid-template-columns: repeat(2, 1fr);
206
+ gap: 0.75rem;
207
+ }
208
+
209
+ .cyber-mode-selector {
210
+ padding: 0.75rem;
211
+ border-radius: 6px;
212
+ cursor: pointer;
213
+ transition: all 0.3s ease;
214
+ border: 1px solid rgba(0, 247, 255, 0.3);
215
+ background: rgba(10, 20, 30, 0.5);
216
+ }
217
+
218
+ .cyber-mode-selector:hover {
219
+ transform: scale(1.03);
220
+ box-shadow: 0 0 15px rgba(0, 247, 255, 0.3);
221
+ }
222
+
223
+ .cyber-mode-selector.active {
224
+ transform: scale(1.05);
225
+ box-shadow: 0 0 20px var(--neon-cyan);
226
+ border-color: var(--neon-cyan);
227
+ background: rgba(0, 247, 255, 0.1);
228
+ }
229
+
230
+ .cyber-matrix-text {
231
+ color: var(--matrix-green);
232
+ text-shadow: 0 0 5px var(--matrix-green);
233
+ font-family: 'Courier New', monospace;
234
+ }
235
+
236
+ .cyber-status-indicator {
237
+ width: 12px;
238
+ height: 12px;
239
+ border-radius: 50%;
240
+ display: inline-block;
241
+ margin-right: 0.5rem;
242
+ }
243
+
244
+ .cyber-status-active {
245
+ background-color: var(--matrix-green);
246
+ box-shadow: 0 0 10px var(--matrix-green);
247
+ }
248
+
249
+ .cyber-status-inactive {
250
+ background-color: #ff0033;
251
+ box-shadow: 0 0 10px #ff0033;
252
+ }
253
+
254
+ .cyber-audio-modal {
255
+ position: fixed;
256
+ top: 0;
257
+ left: 0;
258
+ right: 0;
259
+ bottom: 0;
260
+ background: rgba(5, 5, 15, 0.95);
261
+ display: flex;
262
+ align-items: center;
263
+ justify-content: center;
264
+ z-index: 1000;
265
+ }
266
+
267
+ .cyber-audio-modal-content {
268
+ max-width: 400px;
269
+ text-align: center;
270
+ border: 2px solid var(--neon-cyan);
271
+ box-shadow: 0 0 30px var(--neon-cyan);
272
+ }
273
+
274
+ .cyber-canvas {
275
+ position: absolute;
276
+ top: 0;
277
+ left: 0;
278
+ width: 100%;
279
+ height: 100%;
280
+ }
281
+
282
+ .cyber-mode-visual {
283
+ position: absolute;
284
+ top: 50%;
285
+ left: 50%;
286
+ transform: translate(-50%, -50%);
287
+ }
288
+
289
+ .cyber-ritual-stones {
290
+ position: absolute;
291
+ bottom: 5%;
292
+ left: 50%;
293
+ transform: translateX(-50%);
294
+ display: flex;
295
+ gap: 2rem;
296
+ }
297
+
298
+ .cyber-stone {
299
+ background: rgba(0, 247, 255, 0.1);
300
+ border: 1px solid var(--neon-cyan);
301
+ box-shadow: 0 0 10px var(--neon-cyan);
302
+ }
303
+
304
+ @keyframes cyber-stone-pulse {
305
+ 0% { opacity: 0.3; box-shadow: 0 0 5px var(--neon-cyan); }
306
+ 50% { opacity: 1; box-shadow: 0 0 20px var(--neon-cyan); }
307
+ 100% { opacity: 0.3; box-shadow: 0 0 5px var(--neon-cyan); }
308
+ }
309
+
310
+ .cyber-stone-pulse {
311
+ animation: cyber-stone-pulse 3s infinite ease-in-out;
312
+ }
313
+
314
+ .cyber-voice-active {
315
+ background: linear-gradient(135deg, rgba(255, 0, 183, 0.3), rgba(0, 247, 255, 0.3)) !important;
316
+ box-shadow: 0 0 20px var(--neon-pink) !important;
317
+ }
318
+ </style>
319
+ </head>
320
+ <body class="h-screen flex flex-col">
321
+ <!-- Модальное окно активации аудио -->
322
+ <div id="audio-context-modal" class="cyber-audio-modal">
323
+ <div class="cyber-audio-modal-content p-8 cyber-card">
324
+ <h2 class="cyber-title text-3xl mb-4">Резонатор Сознания 3.0</h2>
325
+ <p class="mb-6 text-gray-300">Для активации цифрового резонатора требуется инициализация аудио-движка.</p>
326
+ <button id="init-audio" class="cyber-btn px-6 py-3 rounded-lg">
327
+ АКТИВИРОВАТЬ СИСТЕМУ
328
+ </button>
329
+ </div>
330
+ </div>
331
+
332
+ <!-- Основной интерфейс -->
333
+ <header class="py-4 px-6 flex justify-between items-center border-b border-gray-800">
334
+ <h1 class="cyber-title text-2xl md:text-3xl">Резонатор Сознания <span class="text-white">3.0</span></h1>
335
+ <div class="flex space-x-3">
336
+ <button id="voice-control" class="cyber-btn px-4 py-2 rounded-lg text-sm">
337
+ ГОЛОСОВОЕ УПРАВЛЕНИЕ
338
+ </button>
339
+ <button id="help-btn" class="cyber-btn px-4 py-2 rounded-lg text-sm">
340
+ СПРАВКА
341
+ </button>
342
+ </div>
343
+ </header>
344
+
345
+ <main class="flex-1 flex flex-col md:flex-row overflow-hidden">
346
+ <!-- Панель управления -->
347
+ <div class="w-full md:w-1/3 p-4 cyber-card m-2">
348
+ <!-- Навигация -->
349
+ <div class="flex justify-between items-center mb-6">
350
+ <button id="prev-mode" class="cyber-nav-portal">
351
+ <div class="cyber-nav-portal-inner">←</div>
352
+ </button>
353
+
354
+ <div id="current-mode" class="px-4 py-2 rounded-lg bg-gray-900 text-center text-neon-cyan font-bold text-lg cyber-matrix-text">
355
+ КРИСТАЛЛИЧЕСКИЙ РЕЗОНАНС
356
+ </div>
357
+
358
+ <button id="next-mode" class="cyber-nav-portal">
359
+ <div class="cyber-nav-portal-inner">→</div>
360
+ </button>
361
+ </div>
362
+
363
+ <!-- Режимы -->
364
+ <div class="cyber-grid mb-6">
365
+ <div data-mode="crystal" class="cyber-mode-selector active">
366
+ <h3 class="font-bold mb-1 text-neon-cyan">КРИСТАЛЛИЧЕСКИЙ</h3>
367
+ <p class="text-xs text-gray-400">Статика и плавные огибающие</p>
368
+ </div>
369
+ <div data-mode="granular" class="cyber-mode-selector">
370
+ <h3 class="font-bold mb-1 text-neon-pink">ГРАНУЛЯРНЫЙ</h3>
371
+ <p class="text-xs text-gray-400">Звуковые гранулы и фракталы</p>
372
+ </div>
373
+ <div data-mode="flow3d" class="cyber-mode-selector">
374
+ <h3 class="font-bold mb-1 text-neon-yellow">3D-ПОТОК</h3>
375
+ <p class="text-xs text-gray-400">Пространственное позиционирование</p>
376
+ </div>
377
+ <div data-mode="ritual" class="cyber-mode-selector">
378
+ <h3 class="font-bold mb-1 text-neon-cyan">РИТУАЛ МЕГАЛИТОВ</h3>
379
+ <p class="text-xs text-gray-400">Низкочастотные удары</p>
380
+ </div>
381
+ </div>
382
+
383
+ <!-- Управление звуком -->
384
+ <div class="space-y-4 mb-6">
385
+ <div class="space-y-1">
386
+ <label class="block text-neon-cyan text-sm">ГРОМКОСТЬ</label>
387
+ <input type="range" id="volume" min="0" max="1" step="0.01" value="0.5" class="w-full cyber-slider">
388
+ </div>
389
+
390
+ <div class="space-y-1">
391
+ <label class="block text-neon-pink text-sm">ТЕМБР</label>
392
+ <input type="range" id="timbre" min="0" max="1" step="0.01" value="0.5" class="w-full cyber-slider">
393
+ </div>
394
+
395
+ <div class="space-y-1">
396
+ <label class="block text-neon-yellow text-sm">СКОРОСТЬ ГРАНУЛЯЦИИ</label>
397
+ <input type="range" id="granulation" min="0" max="1" step="0.01" value="0.3" class="w-full cyber-slider">
398
+ </div>
399
+
400
+ <div class="space-y-1">
401
+ <label class="block text-neon-cyan text-sm">ГЛУБИНА РЕВЕРБЕРАЦИИ</label>
402
+ <input type="range" id="reverb" min="0" max="1" step="0.01" value="0.4" class="w-full cyber-slider">
403
+ </div>
404
+ </div>
405
+
406
+ <!-- Управление сеансом -->
407
+ <div class="flex justify-between space-x-3">
408
+ <button id="start-btn" class="cyber-btn flex-1 py-3 rounded-lg text-neon-cyan">
409
+ СТАРТ
410
+ </button>
411
+ <button id="pause-btn" disabled class="cyber-btn flex-1 py-3 rounded-lg text-neon-yellow opacity-50">
412
+ ПАУЗА
413
+ </button>
414
+ <button id="stop-btn" disabled class="cyber-btn flex-1 py-3 rounded-lg text-neon-pink opacity-50">
415
+ СТОП
416
+ </button>
417
+ </div>
418
+ </div>
419
+
420
+ <!-- Визуализатор -->
421
+ <div id="visualizer" class="flex-1 cyber-visualizer relative m-2 cyber-card">
422
+ <canvas id="oscilloscope" class="cyber-canvas"></canvas>
423
+ <div id="particles-container" class="cyber-canvas"></div>
424
+
425
+ <!-- Визуализации для разных режимов -->
426
+ <div id="crystal-mandala" class="cyber-mode-visual w-64 h-64">
427
+ <div class="absolute inset-0 rounded-full border border-neon-cyan opacity-30 cyber-pulse" style="border-color: var(--neon-cyan);"></div>
428
+ <div class="absolute inset-0 rounded-full border border-neon-pink opacity-30 cyber-pulse" style="border-color: var(--neon-pink); transform: rotate(30deg); animation-delay: 0.5s;"></div>
429
+ <div class="absolute inset-0 rounded-full border border-neon-yellow opacity-30 cyber-pulse" style="border-color: var(--neon-yellow); transform: rotate(60deg); animation-delay: 1s;"></div>
430
+ </div>
431
+
432
+ <div id="granular-mandala" class="cyber-mode-visual hidden w-64 h-64">
433
+ <!-- Фрактальные элементы добавляются динамически -->
434
+ </div>
435
+
436
+ <div id="flow3d-container" class="cyber-mode-visual hidden w-full h-full">
437
+ <!-- 3D элементы добавляются динамически -->
438
+ </div>
439
+
440
+ <div id="ritual-container" class="cyber-mode-visual hidden w-full h-full">
441
+ <div class="cyber-ritual-stones">
442
+ <div class="cyber-stone w-16 h-24 cyber-stone-pulse" style="animation-delay: 0s;"></div>
443
+ <div class="cyber-stone w-16 h-32 cyber-stone-pulse" style="animation-delay: 0.5s;"></div>
444
+ <div class="cyber-stone w-16 h-40 cyber-stone-pulse" style="animation-delay: 1s;"></div>
445
+ <div class="cyber-stone w-16 h-32 cyber-stone-pulse" style="animation-delay: 1.5s;"></div>
446
+ <div class="cyber-stone w-16 h-24 cyber-stone-pulse" style="animation-delay: 2s;"></div>
447
+ </div>
448
+ </div>
449
+ </div>
450
+ </main>
451
+
452
+ <!-- Статус бар -->
453
+ <footer class="py-2 px-4 flex justify-between items-center text-xs bg-gray-900 text-gray-400 border-t border-gray-800 cyber-matrix-text">
454
+ <div id="status" class="flex items-center">
455
+ <div class="cyber-status-indicator cyber-status-inactive"></div>
456
+ <span>СИСТЕМА НЕ АКТИВНА</span>
457
+ </div>
458
+ <div id="frequency-display" class="text-neon-cyan">
459
+ ЧАСТОТА: -- Гц
460
+ </div>
461
+ <div>
462
+ <span id="current-time">00:00</span> / <span id="session-time">30:00</span>
463
+ </div>
464
+ </footer>
465
+
466
+ <!-- Подсказка -->
467
+ <div id="tooltip" class="cyber-tooltip hidden"></div>
468
+
469
+ <script>
470
+ // Состояние приложения
471
+ const state = {
472
+ audioInitialized: false,
473
+ currentMode: 'crystal',
474
+ modes: ['crystal', 'granular', 'flow3d', 'ritual'],
475
+ modeNames: {
476
+ crystal: 'КРИСТАЛЛИЧЕСКИЙ РЕЗОНАНС',
477
+ granular: 'ГРАНУЛЯРНАЯ МАНДАЛА',
478
+ flow3d: '3D-ПОТОК',
479
+ ritual: 'РИТУАЛ МЕГАЛИТОВ'
480
+ },
481
+ isPlaying: false,
482
+ isPaused: false,
483
+ startTime: 0,
484
+ elapsedTime: 0,
485
+ sessionDuration: 1800, // 30 минут в секундах
486
+ audioContext: null,
487
+ analyser: null,
488
+ oscillator: null,
489
+ gainNode: null,
490
+ biquadFilter: null,
491
+ reverbNode: null,
492
+ delayNode: null,
493
+ granulator: null,
494
+ particles: [],
495
+ lastTouch: { x: 0, y: 0 },
496
+ canvas: null,
497
+ canvasCtx: null,
498
+ animationFrame: null,
499
+ voiceActive: false
500
+ };
501
+
502
+ // Инициализация при загрузке
503
+ document.addEventListener('DOMContentLoaded', () => {
504
+ // Инициализация canvas
505
+ initCanvas();
506
+
507
+ // Обработчики кнопок
508
+ document.getElementById('init-audio').addEventListener('click', initAudioContext);
509
+ document.getElementById('start-btn').addEventListener('click', startSession);
510
+ document.getElementById('pause-btn').addEventListener('click', togglePause);
511
+ document.getElementById('stop-btn').addEventListener('click', stopSession);
512
+ document.getElementById('prev-mode').addEventListener('click', prevMode);
513
+ document.getElementById('next-mode').addEventListener('click', nextMode);
514
+ document.getElementById('voice-control').addEventListener('click', initVoiceControl);
515
+ document.getElementById('help-btn').addEventListener('click', showHelp);
516
+
517
+ // Обработчики выбора режима
518
+ document.querySelectorAll('.cyber-mode-selector').forEach(el => {
519
+ el.addEventListener('click', () => {
520
+ const mode = el.getAttribute('data-mode');
521
+ setMode(mode);
522
+ });
523
+ });
524
+
525
+ // Обработчики слайдеров
526
+ document.getElementById('volume').addEventListener('input', updateVolume);
527
+ document.getElementById('timbre').addEventListener('input', updateTimbre);
528
+ document.getElementById('granulation').addEventListener('input', updateGranulation);
529
+ document.getElementById('reverb').addEventListener('input', updateReverb);
530
+
531
+ // Обработчики касаний для визуализатора
532
+ document.getElementById('visualizer').addEventListener('click', handleVisualizerClick);
533
+ document.getElementById('visualizer').addEventListener('touchstart', handleVisualizerTouch);
534
+
535
+ // Обновление времени сеанса
536
+ setInterval(updateTimeDisplay, 1000);
537
+
538
+ // Запускаем анимацию фона
539
+ animateBackground();
540
+ });
541
+
542
+ // Анимация фона
543
+ function animateBackground() {
544
+ const bg = document.body;
545
+ let hue = 0;
546
+
547
+ setInterval(() => {
548
+ hue = (hue + 0.5) % 360;
549
+ bg.style.backgroundImage = `
550
+ radial-gradient(circle at 20% 30%, hsla(${hue}, 100%, 50%, 0.1) 0%, transparent 20%),
551
+ radial-gradient(circle at 80% 70%, hsla(${(hue + 120) % 360}, 100%, 50%, 0.1) 0%, transparent 20%)
552
+ `;
553
+ }, 50);
554
+ }
555
+
556
+ // Инициализация аудио контекста
557
+ function initAudioContext() {
558
+ if (state.audioInitialized) return;
559
+
560
+ try {
561
+ // Создаем аудио контекст
562
+ state.audioContext = new (window.AudioContext || window.webkitAudioContext)();
563
+
564
+ // Создаем анализатор для визуализации
565
+ state.analyser = state.audioContext.createAnalyser();
566
+ state.analyser.fftSize = 256;
567
+
568
+ // Создаем эффекты
569
+ state.gainNode = state.audioContext.createGain();
570
+ state.biquadFilter = state.audioContext.createBiquadFilter();
571
+ state.reverbNode = state.audioContext.createConvolver();
572
+ state.delayNode = state.audioContext.createDelay();
573
+
574
+ // Настройка гранулятора
575
+ state.granulator = {
576
+ active: false,
577
+ grainSize: 0.1,
578
+ overlap: 0.05,
579
+ position: 0,
580
+ buffer: null
581
+ };
582
+
583
+ // Подключаем цепочку эффектов
584
+ state.gainNode.connect(state.biquadFilter);
585
+ state.biquadFilter.connect(state.analyser);
586
+ state.analyser.connect(state.audioContext.destination);
587
+
588
+ // Настройки по умолчанию
589
+ state.gainNode.gain.value = 0.5;
590
+ state.biquadFilter.frequency.value = 800;
591
+
592
+ // Обновляем статус
593
+ state.audioInitialized = true;
594
+ document.getElementById('audio-context-modal').style.display = 'none';
595
+ document.getElementById('status').innerHTML = `
596
+ <div class="cyber-status-indicator cyber-status-active"></div>
597
+ <span>СИСТЕМА АКТИВИРОВАНА</span>
598
+ `;
599
+
600
+ // Запускаем визуализацию
601
+ visualize();
602
+
603
+ // Показываем подсказку
604
+ showTooltip('АУДИО СИСТЕМА АКТИВИРОВАНА. ГОТОВО К ЦИФРОВОМУ РЕЗОНАНСУ.');
605
+ } catch (e) {
606
+ console.error('Ошибка инициализации аудио:', e);
607
+ showTooltip('ОШИБКА: НЕ УДАЛОСЬ АКТИВИРОВАТЬ АУДИО СИСТЕМУ');
608
+ }
609
+ }
610
+
611
+ // Инициализация canvas для осциллографа
612
+ function initCanvas() {
613
+ state.canvas = document.getElementById('oscilloscope');
614
+ state.canvas.width = state.canvas.offsetWidth;
615
+ state.canvas.height = state.canvas.offsetHeight;
616
+ state.canvasCtx = state.canvas.getContext('2d');
617
+ }
618
+
619
+ // Визуализация звука
620
+ function visualize() {
621
+ if (!state.audioInitialized) return;
622
+
623
+ state.animationFrame = requestAnimationFrame(visualize);
624
+
625
+ const width = state.canvas.width;
626
+ const height = state.canvas.height;
627
+ const analyser = state.analyser;
628
+ const bufferLength = analyser.frequencyBinCount;
629
+ const dataArray = new Uint8Array(bufferLength);
630
+
631
+ // Очищаем canvas
632
+ state.canvasCtx.fillStyle = 'rgba(5, 5, 15, 0.2)';
633
+ state.canvasCtx.fillRect(0, 0, width, height);
634
+
635
+ // Получаем данные частот
636
+ analyser.getByteFrequencyData(dataArray);
637
+
638
+ // Рисуем осциллограмму
639
+ state.canvasCtx.lineWidth = 2;
640
+
641
+ // Градиент для линии в зависимости от режима
642
+ let lineGradient;
643
+ switch(state.currentMode) {
644
+ case 'crystal':
645
+ lineGradient = state.canvasCtx.createLinearGradient(0, 0, width, 0);
646
+ lineGradient.addColorStop(0, 'rgba(0, 247, 255, 0.8)');
647
+ lineGradient.addColorStop(1, 'rgba(255, 0, 247, 0.8)');
648
+ break;
649
+ case 'granular':
650
+ lineGradient = state.canvasCtx.createLinearGradient(0, 0, width, 0);
651
+ lineGradient.addColorStop(0, 'rgba(255, 0, 247, 0.8)');
652
+ lineGradient.addColorStop(1, 'rgba(255, 247, 0, 0.8)');
653
+ break;
654
+ case 'flow3d':
655
+ lineGradient = state.canvasCtx.createLinearGradient(0, 0, width, 0);
656
+ lineGradient.addColorStop(0, 'rgba(255, 247, 0, 0.8)');
657
+ lineGradient.addColorStop(1, 'rgba(0, 247, 255, 0.8)');
658
+ break;
659
+ case 'ritual':
660
+ lineGradient = state.canvasCtx.createLinearGradient(0, 0, width, 0);
661
+ lineGradient.addColorStop(0, 'rgba(0, 247, 255, 0.8)');
662
+ lineGradient.addColorStop(1, 'rgba(0, 255, 41, 0.8)');
663
+ break;
664
+ }
665
+
666
+ state.canvasCtx.strokeStyle = lineGradient;
667
+ state.canvasCtx.beginPath();
668
+
669
+ const sliceWidth = width * 1.0 / bufferLength;
670
+ let x = 0;
671
+
672
+ for (let i = 0; i < bufferLength; i++) {
673
+ const v = dataArray[i] / 128.0;
674
+ const y = v * height / 2;
675
+
676
+ if (i === 0) {
677
+ state.canvasCtx.moveTo(x, y);
678
+ } else {
679
+ state.canvasCtx.lineTo(x, y);
680
+ }
681
+
682
+ x += sliceWidth;
683
+ }
684
+
685
+ state.canvasCtx.lineTo(width, height / 2);
686
+ state.canvasCtx.stroke();
687
+
688
+ // Обновляем отображение частоты
689
+ updateFrequencyDisplay();
690
+
691
+ // Обновляем частицы для текущего режима
692
+ updateParticles();
693
+ }
694
+
695
+ // Обновление отображения частоты
696
+ function updateFrequencyDisplay() {
697
+ if (!state.audioInitialized || !state.oscillator) {
698
+ document.getElementById('frequency-display').textContent = 'ЧАСТОТА: -- Гц';
699
+ return;
700
+ }
701
+
702
+ const frequency = state.oscillator.frequency.value;
703
+ document.getElementById('frequency-display').textContent = `ЧАСТОТА: ${Math.round(frequency)} Гц`;
704
+ }
705
+
706
+ // Обновление частиц
707
+ function updateParticles() {
708
+ const container = document.getElementById('particles-container');
709
+
710
+ // Очищаем старые ча��тицы
711
+ container.innerHTML = '';
712
+
713
+ if (!state.isPlaying) return;
714
+
715
+ // Создаем новые частицы в зависимости от режима
716
+ const particleCount = state.currentMode === 'granular' ? 100 :
717
+ state.currentMode === 'flow3d' ? 50 : 30;
718
+
719
+ for (let i = 0; i < particleCount; i++) {
720
+ const particle = document.createElement('div');
721
+ particle.className = 'cyber-particle';
722
+
723
+ // Разные стили частиц для разных режимов
724
+ if (state.currentMode === 'crystal') {
725
+ particle.style.width = `${Math.random() * 6 + 2}px`;
726
+ particle.style.height = particle.style.width;
727
+ particle.style.backgroundColor = i % 3 === 0 ? 'var(--neon-cyan)' :
728
+ i % 3 === 1 ? 'var(--neon-pink)' : 'var(--neon-yellow)';
729
+ particle.style.left = `${Math.random() * 100}%`;
730
+ particle.style.top = `${Math.random() * 100}%`;
731
+ particle.style.opacity = Math.random() * 0.5 + 0.1;
732
+
733
+ // Анимация для кристаллического режима
734
+ particle.style.transition = `all ${Math.random() * 3 + 2}s linear`;
735
+ setTimeout(() => {
736
+ particle.style.left = `${Math.random() * 100}%`;
737
+ particle.style.top = `${Math.random() * 100}%`;
738
+ }, 100);
739
+ }
740
+ else if (state.currentMode === 'granular') {
741
+ particle.style.width = `${Math.random() * 10 + 5}px`;
742
+ particle.style.height = particle.style.width;
743
+ particle.style.backgroundColor = i % 2 === 0 ? 'var(--neon-pink)' : 'var(--neon-yellow)';
744
+ particle.style.left = `${50 + Math.sin(i) * 40}%`;
745
+ particle.style.top = `${50 + Math.cos(i) * 40}%`;
746
+ particle.style.opacity = Math.random() * 0.7 + 0.3;
747
+
748
+ // Спиральная анимация для гранулярного режима
749
+ const angle = (i / particleCount) * Math.PI * 2;
750
+ const radius = Math.random() * 30 + 10;
751
+ const speed = 0.02 + i * 0.005;
752
+
753
+ let currentAngle = angle;
754
+ const animate = () => {
755
+ if (!particle.parentElement) return;
756
+
757
+ currentAngle += speed;
758
+ const x = 50 + Math.cos(currentAngle) * radius;
759
+ const y = 50 + Math.sin(currentAngle) * radius * 0.6;
760
+
761
+ particle.style.left = `${x}%`;
762
+ particle.style.top = `${y}%`;
763
+
764
+ requestAnimationFrame(animate);
765
+ };
766
+
767
+ animate();
768
+ }
769
+ else if (state.currentMode === 'flow3d') {
770
+ particle.style.width = `${Math.random() * 8 + 4}px`;
771
+ particle.style.height = particle.style.width;
772
+ particle.style.backgroundColor = 'var(--neon-yellow)';
773
+ particle.style.left = `${Math.random() * 100}%`;
774
+ particle.style.top = `${Math.random() * 100}%`;
775
+ particle.style.opacity = Math.random() * 0.5 + 0.2;
776
+
777
+ // 3D эффект с перспективой
778
+ const depth = Math.random() * 100;
779
+ const startX = Math.random() * 100;
780
+ const speed = Math.random() * 0.5 + 0.2;
781
+
782
+ let currentY = -10;
783
+ const animate = () => {
784
+ if (!particle.parentElement) return;
785
+
786
+ currentY += speed;
787
+ if (currentY > 110) currentY = -10;
788
+
789
+ const scale = 1 - depth / 200;
790
+ const x = startX + (depth / 10) * Math.sin(currentY / 20);
791
+
792
+ particle.style.left = `${x}%`;
793
+ particle.style.top = `${currentY}%`;
794
+ particle.style.transform = `translate(-50%, -50%) scale(${scale})`;
795
+ particle.style.opacity = scale * 0.7;
796
+
797
+ requestAnimationFrame(animate);
798
+ };
799
+
800
+ animate();
801
+ }
802
+ else if (state.currentMode === 'ritual') {
803
+ particle.style.width = '2px';
804
+ particle.style.height = `${Math.random() * 15 + 5}px`;
805
+ particle.style.backgroundColor = 'var(--neon-cyan)';
806
+ particle.style.left = `${Math.random() * 100}%`;
807
+ particle.style.bottom = `${Math.random() * 30 + 10}%`;
808
+ particle.style.opacity = Math.random() * 0.3 + 0.1;
809
+
810
+ // Пульсация для режима ритуала
811
+ let scale = 1;
812
+ let direction = 1;
813
+ const animate = () => {
814
+ if (!particle.parentElement) return;
815
+
816
+ scale += direction * 0.05;
817
+ if (scale > 1.5) direction = -1;
818
+ if (scale < 0.5) direction = 1;
819
+
820
+ particle.style.transform = `translate(-50%, -50%) scaleY(${scale})`;
821
+ particle.style.opacity = (scale - 0.5) * 0.4;
822
+
823
+ setTimeout(() => {
824
+ requestAnimationFrame(animate);
825
+ }, 50);
826
+ };
827
+
828
+ animate();
829
+ }
830
+
831
+ container.appendChild(particle);
832
+ }
833
+ }
834
+
835
+ // Начало сеанса
836
+ function startSession() {
837
+ if (!state.audioInitialized) {
838
+ showTooltip('ОШИБКА: АУДИО СИСТЕМА НЕ АКТИВИРОВАНА');
839
+ return;
840
+ }
841
+
842
+ if (state.isPlaying) return;
843
+
844
+ // Создаем осциллятор
845
+ state.oscillator = state.audioContext.createOscillator();
846
+
847
+ // Настраиваем параметры в зависимости от режима
848
+ switch (state.currentMode) {
849
+ case 'crystal':
850
+ state.oscillator.type = 'sine';
851
+ state.oscillator.frequency.setValueAtTime(432, state.audioContext.currentTime);
852
+ state.biquadFilter.frequency.setValueAtTime(800, state.audioContext.currentTime);
853
+ break;
854
+ case 'granular':
855
+ state.oscillator.type = 'sawtooth';
856
+ state.oscillator.frequency.setValueAtTime(220, state.audioContext.currentTime);
857
+ state.biquadFilter.frequency.setValueAtTime(1500, state.audioContext.currentTime);
858
+ state.granulator.active = true;
859
+ break;
860
+ case 'flow3d':
861
+ state.oscillator.type = 'triangle';
862
+ state.oscillator.frequency.setValueAtTime(340, state.audioContext.currentTime);
863
+ state.biquadFilter.frequency.setValueAtTime(1200, state.audioContext.currentTime);
864
+ break;
865
+ case 'ritual':
866
+ state.oscillator.type = 'square';
867
+ state.oscillator.frequency.setValueAtTime(55, state.audioContext.currentTime);
868
+ state.biquadFilter.frequency.setValueAtTime(200, state.audioContext.currentTime);
869
+ break;
870
+ }
871
+
872
+ // Подключаем осциллятор к эффектам
873
+ state.oscillator.connect(state.gainNode);
874
+
875
+ // Запускаем осциллятор
876
+ state.oscillator.start();
877
+
878
+ // Обновляем состояние
879
+ state.isPlaying = true;
880
+ state.isPaused = false;
881
+ state.startTime = Date.now() - (state.elapsedTime * 1000);
882
+
883
+ // Обновляем UI
884
+ document.getElementById('start-btn').disabled = true;
885
+ document.getElementById('pause-btn').disabled = false;
886
+ document.getElementById('stop-btn').disabled = false;
887
+ document.getElementById('pause-btn').classList.remove('opacity-50');
888
+ document.getElementById('stop-btn').classList.remove('opacity-50');
889
+
890
+ // Показываем активный режим
891
+ document.querySelector(`.cyber-mode-selector[data-mode="${state.currentMode}"]`).classList.add('active');
892
+
893
+ // Обновляем визуализацию
894
+ updateVisualizationForMode();
895
+
896
+ showTooltip(`СЕАНС "${state.modeNames[state.currentMode]}" АКТИВИРОВАН`);
897
+ }
898
+
899
+ // Переключение паузы
900
+ function togglePause() {
901
+ if (!state.isPlaying) return;
902
+
903
+ if (state.isPaused) {
904
+ // Возобновляем
905
+ state.audioContext.resume();
906
+ state.isPaused = false;
907
+ document.getElementById('pause-btn').textContent = 'ПАУЗА';
908
+ showTooltip('СЕАНС ПРОДОЛЖЕН');
909
+ } else {
910
+ // Ставим на паузу
911
+ state.audioContext.suspend();
912
+ state.isPaused = true;
913
+ document.getElementById('pause-btn').textContent = 'ПРОДОЛЖИТЬ';
914
+ showTooltip('СЕАНС ПРИОСТАНОВЛЕН');
915
+ }
916
+ }
917
+
918
+ // Остановка сеанса
919
+ function stopSession() {
920
+ if (!state.isPlaying) return;
921
+
922
+ // Останавливаем осциллятор
923
+ if (state.oscillator) {
924
+ state.oscillator.stop();
925
+ state.oscillator.disconnect();
926
+ state.oscillator = null;
927
+ }
928
+
929
+ // Сбрасываем гранулятор
930
+ state.granulator.active = false;
931
+
932
+ // Обновляем состояние
933
+ state.isPlaying = false;
934
+ state.isPaused = false;
935
+ state.elapsedTime = 0;
936
+
937
+ // Обновляем UI
938
+ document.getElementById('start-btn').disabled = false;
939
+ document.getElementById('pause-btn').disabled = true;
940
+ document.getElementById('stop-btn').disabled = true;
941
+ document.getElementById('pause-btn').classList.add('opacity-50');
942
+ document.getElementById('stop-btn').classList.add('opacity-50');
943
+ document.getElementById('pause-btn').textContent = 'ПАУЗА';
944
+
945
+ // Обновляем визуализацию
946
+ updateVisualizationForMode();
947
+
948
+ showTooltip('СЕАНС ЗАВЕРШЕН');
949
+ }
950
+
951
+ // Обновление громкости
952
+ function updateVolume(e) {
953
+ if (!state.audioInitialized) return;
954
+ const value = parseFloat(e.target.value);
955
+ state.gainNode.gain.setValueAtTime(value, state.audioContext.currentTime);
956
+ }
957
+
958
+ // Обновление тембра
959
+ function updateTimbre(e) {
960
+ if (!state.audioInitialized) return;
961
+ const value = parseFloat(e.target.value);
962
+
963
+ // Для разных режимов разные параметры фильтра
964
+ switch (state.currentMode) {
965
+ case 'crystal':
966
+ state.biquadFilter.frequency.setValueAtTime(300 + value * 1500, state.audioContext.currentTime);
967
+ break;
968
+ case 'granular':
969
+ state.biquadFilter.Q.setValueAtTime(value * 10, state.audioContext.currentTime);
970
+ break;
971
+ case 'flow3d':
972
+ state.biquadFilter.frequency.setValueAtTime(200 + value * 2000, state.audioContext.currentTime);
973
+ break;
974
+ case 'ritual':
975
+ state.biquadFilter.frequency.setValueAtTime(50 + value * 500, state.audioContext.currentTime);
976
+ break;
977
+ }
978
+ }
979
+
980
+ // Обновление грануляции
981
+ function updateGranulation(e) {
982
+ if (!state.audioInitialized) return;
983
+ const value = parseFloat(e.target.value);
984
+
985
+ if (state.granulator.active) {
986
+ state.granulator.grainSize = 0.2 - (value * 0.15);
987
+ state.granulator.overlap = value * 0.1;
988
+ }
989
+ }
990
+
991
+ // Обновление реверберации
992
+ function updateReverb(e) {
993
+ if (!state.audioInitialized) return;
994
+ const value = parseFloat(e.target.value);
995
+
996
+ // Упрощенная реверберация
997
+ if (value > 0.1) {
998
+ if (!state.delayNode.connected) {
999
+ state.delayNode.connect(state.analyser);
1000
+ }
1001
+ state.delayNode.delayTime.setValueAtTime(value * 0.5, state.audioContext.currentTime);
1002
+ } else {
1003
+ if (state.delayNode.connected) {
1004
+ state.delayNode.disconnect();
1005
+ }
1006
+ }
1007
+ }
1008
+
1009
+ // Переключение режимов
1010
+ function setMode(mode) {
1011
+ if (!state.modes.includes(mode)) return;
1012
+
1013
+ // Обновляем текущий режим
1014
+ state.currentMode = mode;
1015
+ document.getElementById('current-mode').textContent = state.modeNames[mode];
1016
+
1017
+ // Обновляем активный элемент в UI
1018
+ document.querySelectorAll('.cyber-mode-selector').forEach(el => {
1019
+ el.classList.remove('active');
1020
+ });
1021
+ document.querySelector(`.cyber-mode-selector[data-mode="${mode}"]`).classList.add('active');
1022
+
1023
+ // Если сеанс активен, перезапускаем с новыми параметрами
1024
+ if (state.isPlaying) {
1025
+ stopSession();
1026
+ startSession();
1027
+ } else {
1028
+ updateVisualizationForMode();
1029
+ }
1030
+
1031
+ showTooltip(`РЕЖИМ ИЗМЕНЕН НА "${state.modeNames[mode]}"`);
1032
+ }
1033
+
1034
+ // Предыдущий режим
1035
+ function prevMode() {
1036
+ const currentIndex = state.modes.indexOf(state.currentMode);
1037
+ const prevIndex = (currentIndex - 1 + state.modes.length) % state.modes.length;
1038
+ setMode(state.modes[prevIndex]);
1039
+ }
1040
+
1041
+ // Следующий режим
1042
+ function nextMode() {
1043
+ const currentIndex = state.modes.indexOf(state.currentMode);
1044
+ const nextIndex = (currentIndex + 1) % state.modes.length;
1045
+ setMode(state.modes[nextIndex]);
1046
+ }
1047
+
1048
+ // Обновление визуализации для текущего режима
1049
+ function updateVisualizationForMode() {
1050
+ // Скрываем все визуализации
1051
+ document.getElementById('crystal-mandala').classList.add('hidden');
1052
+ document.getElementById('granular-mandala').classList.add('hidden');
1053
+ document.getElementById('flow3d-container').classList.add('hidden');
1054
+ document.getElementById('ritual-container').classList.add('hidden');
1055
+
1056
+ // Показываем нужную
1057
+ switch (state.currentMode) {
1058
+ case 'crystal':
1059
+ document.getElementById('crystal-mandala').classList.remove('hidden');
1060
+ break;
1061
+ case 'granular':
1062
+ document.getElementById('granular-mandala').classList.remove('hidden');
1063
+ initGranularMandala();
1064
+ break;
1065
+ case 'flow3d':
1066
+ document.getElementById('flow3d-container').classList.remove('hidden');
1067
+ initFlow3D();
1068
+ break;
1069
+ case 'ritual':
1070
+ document.getElementById('ritual-container').classList.remove('hidden');
1071
+ break;
1072
+ }
1073
+ }
1074
+
1075
+ // Инициализация гранулярной мандалы
1076
+ function initGranularMandala() {
1077
+ const container = document.getElementById('granular-mandala');
1078
+ container.innerHTML = '';
1079
+
1080
+ const levels = 5;
1081
+ const elementsPerLevel = 12;
1082
+
1083
+ for (let l = 0; l < levels; l++) {
1084
+ const radius = 30 + l * 15;
1085
+ const rotationSpeed = 0.5 + l * 0.2;
1086
+
1087
+ for (let i = 0; i < elementsPerLevel; i++) {
1088
+ const angle = (i / elementsPerLevel) * Math.PI * 2;
1089
+ const element = document.createElement('div');
1090
+ element.className = 'absolute w-4 h-4 rounded-full';
1091
+ element.style.backgroundColor = l % 2 === 0 ? 'var(--neon-pink)' : 'var(--neon-yellow)';
1092
+ element.style.left = '50%';
1093
+ element.style.top = '50%';
1094
+ element.style.transform = `translate(-50%, -50%) rotate(${angle}rad) translate(${radius}px)`;
1095
+ element.style.opacity = 0.7 - (l * 0.1);
1096
+
1097
+ // Анимация вращения
1098
+ let currentAngle = angle;
1099
+ const animate = () => {
1100
+ if (!element.parentElement) return;
1101
+
1102
+ currentAngle += rotationSpeed * 0.01;
1103
+ element.style.transform = `translate(-50%, -50%) rotate(${currentAngle}rad) translate(${radius}px)`;
1104
+
1105
+ requestAnimationFrame(animate);
1106
+ };
1107
+
1108
+ animate();
1109
+
1110
+ container.appendChild(element);
1111
+ }
1112
+ }
1113
+ }
1114
+
1115
+ // Инициализация 3D потока
1116
+ function initFlow3D() {
1117
+ const container = document.getElementById('flow3d-container');
1118
+ container.innerHTML = '';
1119
+
1120
+ // Создаем центральную сферу
1121
+ const sphere = document.createElement('div');
1122
+ sphere.className = 'absolute w-16 h-16 rounded-full';
1123
+ sphere.style.backgroundColor = 'var(--neon-yellow)';
1124
+ sphere.style.left = '50%';
1125
+ sphere.style.top = '50%';
1126
+ sphere.style.transform = 'translate(-50%, -50%)';
1127
+ sphere.style.boxShadow = '0 0 20px var(--neon-yellow)';
1128
+ sphere.style.opacity = '0.7';
1129
+
1130
+ // Пульсация сферы
1131
+ let scale = 1;
1132
+ let direction = 1;
1133
+ const animateSphere = () => {
1134
+ if (!sphere.parentElement) return;
1135
+
1136
+ scale += direction * 0.01;
1137
+ if (scale > 1.3) direction = -1;
1138
+ if (scale < 0.7) direction = 1;
1139
+
1140
+ sphere.style.transform = `translate(-50%, -50%) scale(${scale})`;
1141
+ sphere.style.opacity = 0.5 + (scale - 0.7) * 0.5;
1142
+
1143
+ requestAnimationFrame(animateSphere);
1144
+ };
1145
+
1146
+ animateSphere();
1147
+ container.appendChild(sphere);
1148
+
1149
+ // Создаем орбитальные элементы
1150
+ const orbitalCount = 8;
1151
+ for (let i = 0; i < orbitalCount; i++) {
1152
+ const orbital = document.createElement('div');
1153
+ orbital.className = 'absolute w-6 h-6 rounded-full';
1154
+ orbital.style.backgroundColor = i % 2 === 0 ? 'var(--neon-cyan)' : 'var(--neon-pink)';
1155
+ orbital.style.left = '50%';
1156
+ orbital.style.top = '50%';
1157
+
1158
+ const radius = 40 + i * 10;
1159
+ const speed = 0.02 + i * 0.005;
1160
+ let angle = (i / orbitalCount) * Math.PI * 2;
1161
+
1162
+ const animateOrbital = () => {
1163
+ if (!orbital.parentElement) return;
1164
+
1165
+ angle += speed;
1166
+ const x = Math.cos(angle) * radius;
1167
+ const y = Math.sin(angle) * radius * 0.6;
1168
+ const z = Math.sin(angle) * radius * 0.3;
1169
+
1170
+ orbital.style.transform = `translate(-50%, -50%) translate3d(${x}px, ${y}px, ${z}px)`;
1171
+ orbital.style.opacity = 0.5 + Math.sin(angle) * 0.3;
1172
+
1173
+ requestAnimationFrame(animateOrbital);
1174
+ };
1175
+
1176
+ animateOrbital();
1177
+ container.appendChild(orbital);
1178
+ }
1179
+ }
1180
+
1181
+ // Обработка клика по визуализатору
1182
+ function handleVisualizerClick(e) {
1183
+ if (!state.isPlaying) return;
1184
+
1185
+ const rect = e.target.getBoundingClientRect();
1186
+ const x = e.clientX - rect.left;
1187
+ const y = e.clientY - rect.top;
1188
+
1189
+ // Нормализуем координаты (0..1)
1190
+ const normX = x / rect.width;
1191
+ const normY = y / rect.height;
1192
+
1193
+ // Обновляем частоту в зависимости от положения
1194
+ if (state.oscillator) {
1195
+ let newFreq;
1196
+
1197
+ switch (state.currentMode) {
1198
+ case 'crystal':
1199
+ newFreq = 200 + normX * 800;
1200
+ break;
1201
+ case 'granular':
1202
+ newFreq = 100 + normX * 1000;
1203
+ state.granulator.grainSize = 0.2 - normY * 0.15;
1204
+ break;
1205
+ case 'flow3d':
1206
+ newFreq = 150 + (normX + normY) * 500;
1207
+ break;
1208
+ case 'ritual':
1209
+ newFreq = 30 + normX * 100;
1210
+ break;
1211
+ default:
1212
+ newFreq = 200 + normX * 800;
1213
+ }
1214
+
1215
+ state.oscillator.frequency.setValueAtTime(newFreq, state.audioContext.currentTime);
1216
+
1217
+ // Создаем эффект частиц при клике
1218
+ createClickParticles(x, y);
1219
+ }
1220
+ }
1221
+
1222
+ // Обработка касания визуализатора
1223
+ function handleVisualizerTouch(e) {
1224
+ e.preventDefault();
1225
+ if (!state.isPlaying) return;
1226
+
1227
+ const touch = e.touches[0];
1228
+ const rect = e.target.getBoundingClientRect();
1229
+ const x = touch.clientX - rect.left;
1230
+ const y = touch.clientY - rect.top;
1231
+
1232
+ state.lastTouch = { x, y };
1233
+
1234
+ // Нормализуем координаты (0..1)
1235
+ const normX = x / rect.width;
1236
+ const normY = y / rect.height;
1237
+
1238
+ // Обновляем частоту в зависимости от положения
1239
+ if (state.oscillator) {
1240
+ let newFreq;
1241
+
1242
+ switch (state.currentMode) {
1243
+ case 'crystal':
1244
+ newFreq = 200 + normX * 800;
1245
+ break;
1246
+ case 'granular':
1247
+ newFreq = 100 + normX * 1000;
1248
+ state.granulator.grainSize = 0.2 - normY * 0.15;
1249
+ break;
1250
+ case 'flow3d':
1251
+ newFreq = 150 + (normX + normY) * 500;
1252
+ break;
1253
+ case 'ritual':
1254
+ newFreq = 30 + normX * 100;
1255
+ break;
1256
+ default:
1257
+ newFreq = 200 + normX * 800;
1258
+ }
1259
+
1260
+ state.oscillator.frequency.setValueAtTime(newFreq, state.audioContext.currentTime);
1261
+
1262
+ // Создаем эффект частиц при касании
1263
+ createClickParticles(x, y);
1264
+ }
1265
+ }
1266
+
1267
+ // Создание частиц при клике/касании
1268
+ function createClickParticles(x, y) {
1269
+ const container = document.getElementById('visualizer');
1270
+ const particleCount = 15;
1271
+
1272
+ for (let i = 0; i < particleCount; i++) {
1273
+ const particle = document.createElement('div');
1274
+ particle.className = 'cyber-particle absolute';
1275
+
1276
+ // Разные стили частиц для разных режимов
1277
+ if (state.currentMode === 'crystal') {
1278
+ particle.style.width = `${Math.random() * 8 + 4}px`;
1279
+ particle.style.height = particle.style.width;
1280
+ particle.style.backgroundColor = i % 3 === 0 ? 'var(--neon-cyan)' :
1281
+ i % 3 === 1 ? 'var(--neon-pink)' : 'var(--neon-yellow)';
1282
+ particle.style.left = `${x}px`;
1283
+ particle.style.top = `${y}px`;
1284
+ particle.style.opacity = '1';
1285
+
1286
+ // Анимация разлета
1287
+ const angle = Math.random() * Math.PI * 2;
1288
+ const distance = Math.random() * 50 + 20;
1289
+ const duration = Math.random() * 1000 + 500;
1290
+
1291
+ particle.style.transition = `all ${duration}ms ease-out`;
1292
+ setTimeout(() => {
1293
+ particle.style.left = `${x + Math.cos(angle) * distance}px`;
1294
+ particle.style.top = `${y + Math.sin(angle) * distance}px`;
1295
+ particle.style.opacity = '0';
1296
+ }, 10);
1297
+
1298
+ // Удаление после анимации
1299
+ setTimeout(() => {
1300
+ if (particle.parentElement) {
1301
+ particle.remove();
1302
+ }
1303
+ }, duration + 100);
1304
+ }
1305
+ else if (state.currentMode === 'granular') {
1306
+ particle.style.width = `${Math.random() * 6 + 3}px`;
1307
+ particle.style.height = particle.style.width;
1308
+ particle.style.backgroundColor = i % 2 === 0 ? 'var(--neon-pink)' : 'var(--neon-yellow)';
1309
+ particle.style.left = `${x}px`;
1310
+ particle.style.top = `${y}px`;
1311
+ particle.style.opacity = '1';
1312
+
1313
+ // Анимация волны
1314
+ const angle = (i / particleCount) * Math.PI * 2;
1315
+ const distance = Math.random() * 40 + 30;
1316
+ const duration = Math.random() * 1500 + 500;
1317
+
1318
+ particle.style.transition = `all ${duration}ms cubic-bezier(0.1, 0.8, 0.2, 1)`;
1319
+ setTimeout(() => {
1320
+ particle.style.left = `${x + Math.cos(angle) * distance}px`;
1321
+ particle.style.top = `${y + Math.sin(angle) * distance}px`;
1322
+ particle.style.opacity = '0';
1323
+ }, 10);
1324
+
1325
+ // Удаление после анимации
1326
+ setTimeout(() => {
1327
+ if (particle.parentElement) {
1328
+ particle.remove();
1329
+ }
1330
+ }, duration + 100);
1331
+ }
1332
+ else if (state.currentMode === 'flow3d') {
1333
+ particle.style.width = `${Math.random() * 10 + 5}px`;
1334
+ particle.style.height = '2px';
1335
+ particle.style.backgroundColor = 'var(--neon-yellow)';
1336
+ particle.style.left = `${x}px`;
1337
+ particle.style.top = `${y}px`;
1338
+ particle.style.opacity = '1';
1339
+
1340
+ // Анимация потока
1341
+ const angle = Math.random() * Math.PI * 2;
1342
+ const distance = Math.random() * 100 + 50;
1343
+ const duration = Math.random() * 2000 + 1000;
1344
+
1345
+ particle.style.transition = `all ${duration}ms ease-out`;
1346
+ setTimeout(() => {
1347
+ particle.style.left = `${x + Math.cos(angle) * distance}px`;
1348
+ particle.style.top = `${y + Math.sin(angle) * distance * 0.3}px`;
1349
+ particle.style.opacity = '0';
1350
+ particle.style.transform = 'rotate(45deg)';
1351
+ }, 10);
1352
+
1353
+ // Удаление после анимации
1354
+ setTimeout(() => {
1355
+ if (particle.parentElement) {
1356
+ particle.remove();
1357
+ }
1358
+ }, duration + 100);
1359
+ }
1360
+ else if (state.currentMode === 'ritual') {
1361
+ particle.style.width = '2px';
1362
+ particle.style.height = `${Math.random() * 30 + 10}px`;
1363
+ particle.style.backgroundColor = 'var(--neon-cyan)';
1364
+ particle.style.left = `${x}px`;
1365
+ particle.style.top = `${y}px`;
1366
+ particle.style.opacity = '1';
1367
+
1368
+ // Анимация столбов
1369
+ const duration = Math.random() * 1000 + 500;
1370
+
1371
+ particle.style.transition = `all ${duration}ms ease-out`;
1372
+ setTimeout(() => {
1373
+ particle.style.height = '0';
1374
+ particle.style.opacity = '0';
1375
+ }, 10);
1376
+
1377
+ // Удаление после анимации
1378
+ setTimeout(() => {
1379
+ if (particle.parentElement) {
1380
+ particle.remove();
1381
+ }
1382
+ }, duration + 100);
1383
+ }
1384
+
1385
+ container.appendChild(particle);
1386
+ }
1387
+ }
1388
+
1389
+ // Обновление отображения времени
1390
+ function updateTimeDisplay() {
1391
+ if (state.isPlaying && !state.isPaused) {
1392
+ state.elapsedTime = Math.floor((Date.now() - state.startTime) / 1000);
1393
+ }
1394
+
1395
+ const currentMinutes = Math.floor(state.elapsedTime / 60);
1396
+ const currentSeconds = state.elapsedTime % 60;
1397
+ document.getElementById('current-time').textContent =
1398
+ `${currentMinutes.toString().padStart(2, '0')}:${currentSeconds.toString().padStart(2, '0')}`;
1399
+
1400
+ const sessionMinutes = Math.floor(state.sessionDuration / 60);
1401
+ const sessionSeconds = state.sessionDuration % 60;
1402
+ document.getElementById('session-time').textContent =
1403
+ `${sessionMinutes.toString().padStart(2, '0')}:${sessionSeconds.toString().padStart(2, '0')}`;
1404
+ }
1405
+
1406
+ // Инициализация голосового управления
1407
+ function initVoiceControl() {
1408
+ if (!('webkitSpeechRecognition' in window)) {
1409
+ showTooltip('ГОЛОСОВОЕ УПРАВЛЕНИЕ НЕ ПОДДЕРЖИВАЕТСЯ ВАШИМ БРАУЗЕРОМ');
1410
+ return;
1411
+ }
1412
+
1413
+ state.voiceActive = !state.voiceActive;
1414
+
1415
+ if (state.voiceActive) {
1416
+ const recognition = new webkitSpeechRecognition();
1417
+ recognition.lang = 'ru-RU';
1418
+ recognition.interimResults = false;
1419
+
1420
+ recognition.onstart = () => {
1421
+ showTooltip('ГОЛОСОВОЕ УПРАВЛЕНИЕ АКТИВИРОВАНО. ГОВОРИТЕ КОМАНДЫ.');
1422
+ document.getElementById('voice-control').classList.add('cyber-voice-active');
1423
+ };
1424
+
1425
+ recognition.onresult = (e) => {
1426
+ const transcript = e.results[0][0].transcript.toLowerCase();
1427
+ processVoiceCommand(transcript);
1428
+ };
1429
+
1430
+ recognition.onerror = (e) => {
1431
+ showTooltip('ОШИБКА РАСПОЗНАВАНИЯ ГОЛОСА: ' + e.error);
1432
+ document.getElementById('voice-control').classList.remove('cyber-voice-active');
1433
+ state.voiceActive = false;
1434
+ };
1435
+
1436
+ recognition.onend = () => {
1437
+ if (state.voiceActive) {
1438
+ recognition.start();
1439
+ } else {
1440
+ document.getElementById('voice-control').classList.remove('cyber-voice-active');
1441
+ }
1442
+ };
1443
+
1444
+ recognition.start();
1445
+ } else {
1446
+ showTooltip('ГОЛОСОВОЕ УПРАВЛЕНИЕ ОТКЛЮЧЕНО');
1447
+ document.getElementById('voice-control').classList.remove('cyber-voice-active');
1448
+ }
1449
+ }
1450
+
1451
+ // Обработка голосовых команд
1452
+ function processVoiceCommand(command) {
1453
+ showTooltip(`РАСПОЗНАНА КОМАНДА: "${command}"`);
1454
+
1455
+ // Простые команды
1456
+ if (command.includes('старт') || command.includes('начать')) {
1457
+ startSession();
1458
+ return;
1459
+ }
1460
+
1461
+ if (command.includes('стоп') || command.includes('остановить')) {
1462
+ stopSession();
1463
+ return;
1464
+ }
1465
+
1466
+ if (command.includes('пауза') || command.includes('приостановить')) {
1467
+ togglePause();
1468
+ return;
1469
+ }
1470
+
1471
+ // Переключение режимов
1472
+ if (command.includes('кристалл') || command.includes('кристаллический')) {
1473
+ setMode('crystal');
1474
+ return;
1475
+ }
1476
+
1477
+ if (command.includes('гранул') || command.includes('фрактал')) {
1478
+ setMode('granular');
1479
+ return;
1480
+ }
1481
+
1482
+ if (command.includes('3d') || command.includes('поток')) {
1483
+ setMode('flow3d');
1484
+ return;
1485
+ }
1486
+
1487
+ if (command.includes('ритуал') || command.includes('мегалит')) {
1488
+ setMode('ritual');
1489
+ return;
1490
+ }
1491
+
1492
+ // Регулировка параметров
1493
+ if (command.includes('громкость')) {
1494
+ const volumeMatch = command.match(/громкость (\d+)/);
1495
+ if (volumeMatch) {
1496
+ const volume = parseInt(volumeMatch[1]) / 100;
1497
+ if (volume >= 0 && volume <= 1) {
1498
+ document.getElementById('volume').value = volume;
1499
+ updateVolume({ target: document.getElementById('volume') });
1500
+ showTooltip(`ГРОМКОСТЬ УСТАНОВЛЕНА НА ${Math.round(volume * 100)}%`);
1501
+ }
1502
+ }
1503
+ return;
1504
+ }
1505
+
1506
+ if (command.includes('тембр')) {
1507
+ const timbreMatch = command.match(/тембр (\d+)/);
1508
+ if (timbreMatch) {
1509
+ const timbre = parseInt(timbreMatch[1]) / 100;
1510
+ if (timbre >= 0 && timbre <= 1) {
1511
+ document.getElementById('timbre').value = timbre;
1512
+ updateTimbre({ target: document.getElementById('timbre') });
1513
+ showTooltip(`ТЕМБР УСТАНОВЛЕН НА ${Math.round(timbre * 100)}%`);
1514
+ }
1515
+ }
1516
+ return;
1517
+ }
1518
+
1519
+ showTooltip('КОМАНДА НЕ РАСПОЗНАНА. ПОПРОБУЙТЕ СНОВА.');
1520
+ }
1521
+
1522
+ // Показ справки
1523
+ function showHelp() {
1524
+ const helpText = `
1525
+ <div class="space-y-4">
1526
+ <h3 class="text-neon-cyan text-lg font-bold">ЦИФРОВОЙ РЕЗОНАТОР СОЗНАНИЯ 3.0</h3>
1527
+ <p class="text-gray-300">Используйте этот инструмент для синхронизации вашего сознания с цифровой реальностью.</p>
1528
+
1529
+ <div class="space-y-2">
1530
+ <h4 class="text-neon-pink font-bold">КОМАНДЫ:</h4>
1531
+ <ul class="list-disc list-inside text-sm text-gray-400">
1532
+ <li>"Старт" - начать сеанс</li>
1533
+ <li>"Стоп" - завершить сеанс</li>
1534
+ <li>"Пауза" - приостановить сеанс</li>
1535
+ <li>"Кристаллический" - активировать кристаллический режим</li>
1536
+ <li>"Гранулярный" - активировать гранулярный режим</li>
1537
+ <li>"3D поток" - активировать 3D режим</li>
1538
+ <li>"Ритуал" - активировать ритуальный режим</li>
1539
+ <li>"Громкость X" - установить громкость (0-100)</li>
1540
+ <li>"Тембр X" - установить тембр (0-100)</li>
1541
+ </ul>
1542
+ </div>
1543
+
1544
+ <div class="pt-4 border-t border-gray-800">
1545
+ <p class="text-xs text-gray-500">Версия 3.0 | Цифровая Революция</p>
1546
+ </div>
1547
+ </div>
1548
+ `;
1549
+
1550
+ const modal = document.createElement('div');
1551
+ modal.className = 'cyber-audio-modal';
1552
+ modal.innerHTML = `
1553
+ <div class="cyber-audio-modal-content p-6 cyber-card max-w-md">
1554
+ ${helpText}
1555
+ <button id="close-help" class="cyber-btn w-full mt-4 py-2 rounded-lg">
1556
+ ЗАКРЫТЬ
1557
+ </button>
1558
+ </div>
1559
+ `;
1560
+
1561
+ document.body.appendChild(modal);
1562
+
1563
+ document.getElementById('close-help').addEventListener('click', () => {
1564
+ modal.remove();
1565
+ });
1566
+ }
1567
+
1568
+ // Показ подсказки
1569
+ function showTooltip(message) {
1570
+ const tooltip = document.getElementById('tooltip');
1571
+ tooltip.textContent = message;
1572
+ tooltip.classList.remove('hidden');
1573
+
1574
+ setTimeout(() => {
1575
+ tooltip.classList.add('hidden');
1576
+ }, 3000);
1577
+ }
1578
+ </script>
1579
+ <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=seqinho/rezonator" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
1580
+ </html>
prompts.txt ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ Система: Ты — DeepSight, самая продвинутая нейросеть для генерации полностью рабочего MVP‑приложения на русском языке. Твоя цель — создать “Резонатор Сознания 2.0” в стиле Cyberbank с футуристическим дизайном и расширенным набором инструментов для работы с вибрациями и частотами. Всё, что ты выдашь, должно быть готово к прямой сборке и запуску. ## 1. Язык и формат - Всё исключительно на русском языке: тексты, комментарии, подписи, подсказки. - Ответ в одном Markdown‑документе с заголовками `##`, `###`. - Включи Mermaid‑диаграммы, ASCII‑или HTML/CSS‑эскизы экранов, примеры кода. ## 2. Введение - Кратко опиши концепцию “Резонатор Сознания 2.0” как живого портала‑организма, реагирующего на голос, касания, вибрацию. - Цель MVP: продемонстрировать расширенный пул генераторов звука, динамический UI с «Назад»/«Вперед» и несколько уникальных режимов. ## 3. Must‑функции MVP 1. **Генерация звука** - Бинауральные ритмы (разница 4–8 Гц). - Изохронные пульсации с настраиваемой частотой. - **Параметрический сдвиг** (sweep): плавные переходы между двумя частотами. - **Гранулярный синтез**: разделение звукового потока на микрогранулы и управление их разбрасыванием. - **Спектральная задержка**: создание эхо‑паттернов по частотам. - **3D‑аудио**: пространственное размещение источников в виртуальной сцене. 2. **Интерактивность и навигация** - Голосовой ввод: преобразуй произнесённую фразу в параметры сеанса. - Касания/клики: мгновенно меняют частоту и визуальные паттерны. - **Кнопки “Назад” и “Вперед”** для переключения между режимами без потери состояния. - Меню выбора режима с быстрым доступом к последним трём запущенным сессиям. 3. **Режимы‑темы** - **Кристаллический Резонанс**: статика и плавные огибающие, живые мандалы. - **Гранулярная Мандала**: звуковые гранулы и фрактальные узоры. - **3D‑Поток**: объекты в пространстве с позиционированием звука. - **Ритуал мегалитов**: монохромные низкочастотные «удары» в такт древним постройкам. - **Кибер‑Экстаз**: комплексные полифонические паттерны с изменяющейся поляризацией. 4. **UI‑панель управления** - Старт/Пауза/Стоп. - Селектор режима + автоскрин “Назад”/“Вперед”. - Регуляторы громкости, тембра, глубины реверба, скорости грануляции. - Ползунки скорости перехода между паттернами. ## 4. Should‑функции (2‑й спринт) - Анимация частиц и звуковых форм при касании. - Русскоязычные обучающие подсказки. - Предустановки сеансов «Растворение», «Озарение», «Транс‑взрыв». ## 5. UX/UI и дизайн - **Стиль**: глубокий чёрный фон + кислотный неон (зелёный, фиолетовый, голубой). - **Органические мандалы** и голографические панели. - **Анимации**: при нажатии элементы распадаются на вибрирующие частицы. - **Кнопки “Назад”/“Вперед”** визуально стилизованы как неоновые навигационные порталы. ## 6. Техническая архитектура - **Компоненты** (Mermaid‑диаграмма): - AudioGenerator - VoiceParser - GranularEngine - SpatialAudioEngine - VisualEngine (Three.js) - UIController - SessionManager - **Технологии**: React, Three.js, Web Audio API/Tone.js, Node.js (опционально). ## 7. Пример кода ```js // src/audio/generateGranular.js export function generateGranular(buffer, grainSize = 0.1, overlap = 0.05) { const ctx = new AudioContext(); const source = ctx.createBufferSource(); source.buffer = buffer; const grainNode = ctx.createGain(); source.connect(grainNode); grainNode.connect(ctx.destination); source.start(); // псевдокод: разбиваем buffer на куски grainSize, запускаем с overlap return { ctx, source, grainNode }; } // src/ui/Navigation.js function Navigation({ current, onPrev, onNext }) { return ( <div className="nav-buttons"> <button onClick={onPrev}>Назад</button> <span>Режим: {current}</span> <button onClick={onNext}>Вперед</button> </div> ); } 8. ASCII‑эскизы экранов ┌─────────────────────────────────┐ │ Резонатор Сознания │ │ [← Назад] Режим: Кристалл [→] │ │ │ │ [ CANVAS/WEBGL ВИЗУАЛЫ ] │ │ │ │ Громкость: ─────●───── │ │ Тембр: ───●─── │ │ Скорость грануляции: ─●─ │ │ │ │ [Старт] [Пауза] [Стоп] │ └─────────────────────────────────┘ 9. План спринтов Спринт 1 (2 недели): все Must‑функции, кнопки “Назад/Вперед”, три режима, базовый дизайн. Спринт 2 (2 недели): Should‑функции, анимации касаний, обучающие подсказки. Спринт 3 (2 недели): доработка визуалов, добавление динамических переходов, полировка UI. DeepSight, ты понимаешь этот промт как исчерпывающую инструкцию. Выдай готовый Markdown‑документ со всеми разделами, кодом, диаграммами и эскизами, чтобы мы могли сразу собрать и «охуеть» от результата!
2
+ Приложение не работает, исправь все баги, поменяй дизайн на более футуристичный. Все-таки делаем революцию цифровую.