horeg-audio 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/horeg-audio.cjs +503 -92
- package/dist/horeg-audio.cjs.map +1 -1
- package/dist/horeg-audio.global.js +499 -88
- package/dist/horeg-audio.global.js.map +1 -1
- package/dist/horeg-audio.js +989 -436
- package/dist/horeg-audio.js.map +1 -1
- package/dist/index.d.ts +17 -1
- package/package.json +1 -1
package/dist/horeg-audio.cjs
CHANGED
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
"use strict";var
|
|
1
|
+
"use strict";var U=Object.defineProperty;var q=(d,e,r)=>e in d?U(d,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):d[e]=r;var i=(d,e,r)=>q(d,typeof e!="symbol"?e+"":e,r);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});function B(d){const e=d.replace("#","");if(e.length===3){const r=parseInt(e[0]+e[0],16),t=parseInt(e[1]+e[1],16),o=parseInt(e[2]+e[2],16);return`${r}, ${t}, ${o}`}if(e.length===6){const r=parseInt(e.substring(0,2),16),t=parseInt(e.substring(2,4),16),o=parseInt(e.substring(4,6),16);return`${r}, ${t}, ${o}`}return"245, 158, 11"}function V(d){if(!d)return!1;const e=d.replace("#","");let r=0,t=0,o=0;if(e.length===3)r=parseInt(e[0]+e[0],16),t=parseInt(e[1]+e[1],16),o=parseInt(e[2]+e[2],16);else if(e.length===6)r=parseInt(e.substring(0,2),16),t=parseInt(e.substring(2,4),16),o=parseInt(e.substring(4,6),16);else return!1;return(r*299+t*587+o*114)/1e3>155}const E={"horeg-classic":{variant:"horeg-classic",primaryGlowColor:"#f59e0b",accentColor:"#ef4444",cardBackground:"#121214",textColor:"#f4f4f5",sliderProgressColor:"#f59e0b",borderRadius:"14px",isLight:!1},"horeg-nightclub":{variant:"horeg-nightclub",primaryGlowColor:"#06b6d4",accentColor:"#ec4899",cardBackground:"#0b0c10",textColor:"#f8fafc",sliderProgressColor:"#06b6d4",borderRadius:"14px",isLight:!1},"horeg-stealth":{variant:"horeg-stealth",primaryGlowColor:"#94a3b8",accentColor:"#e2e8f0",cardBackground:"#0f1115",textColor:"#e2e8f0",sliderProgressColor:"#94a3b8",borderRadius:"8px",isLight:!1},"horeg-light":{variant:"horeg-light",primaryGlowColor:"#d97706",accentColor:"#dc2626",cardBackground:"#ffffff",textColor:"#0f172a",sliderProgressColor:"#d97706",borderRadius:"14px",surfaceColor:"#f8fafc",surfaceHoverColor:"#f1f5f9",borderColor:"#e2e8f0",mutedTextColor:"#64748b",isLight:!0},"horeg-light-clean":{variant:"horeg-light-clean",primaryGlowColor:"#0284c7",accentColor:"#db2777",cardBackground:"#ffffff",textColor:"#0f172a",sliderProgressColor:"#0284c7",borderRadius:"14px",surfaceColor:"#f8fafc",surfaceHoverColor:"#f1f5f9",borderColor:"#e2e8f0",mutedTextColor:"#64748b",isLight:!0},"horeg-light-minimal":{variant:"horeg-light-minimal",primaryGlowColor:"#475569",accentColor:"#2563eb",cardBackground:"#f8fafc",textColor:"#1e293b",sliderProgressColor:"#2563eb",borderRadius:"8px",surfaceColor:"#f1f5f9",surfaceHoverColor:"#e2e8f0",borderColor:"#e2e8f0",mutedTextColor:"#64748b",isLight:!0}};function L(d={}){const e=d.variant||"horeg-classic",r=E[e]||E["horeg-classic"],t=d.isLight??r.isLight??(e.includes("light")||V(d.cardBackground||r.cardBackground)),o=d.primaryGlowColor||r.primaryGlowColor||(t?"#d97706":"#f59e0b"),n=d.accentColor||r.accentColor||(t?"#dc2626":"#ef4444"),a=d.cardBackground||r.cardBackground||(t?"#ffffff":"#121214"),l=d.textColor||r.textColor||(t?"#0f172a":"#f4f4f5"),h=d.sliderProgressColor||r.sliderProgressColor||o,g=d.borderRadius||r.borderRadius||"14px",p=d.surfaceColor||r.surfaceColor||(t?"#f8fafc":"#18181b"),b=d.surfaceHoverColor||r.surfaceHoverColor||(t?"#f1f5f9":"#222226"),u=d.borderColor||r.borderColor||(t?"#e2e8f0":"#27272a"),v=d.mutedTextColor||r.mutedTextColor||(t?"#64748b":"#a1a1aa"),x=t?p:"#141416",k=t?"#e2e8f0":"#27272a",y=t?"#cbd5e1":"#3f3f46",w=t?"#ffffff":"#1f1f23",f=t?"#ffffff":"#09090b",M=t?"#94a3b8":"#3f3f46",P=t?"#cbd5e1":"#18181b",S=t?"#cbd5e1":"#2c2d33",A=t?"0.35":"0.3",I=t?"#f8fafc":"#141416",z=t?"#ffffff":"#121214",N=t?"#f1f5f9":"#202024",H=t?"#ffffff":"#27272a",D=t?`linear-gradient(90deg, rgba(${B(o)}, 0.12) 0%, rgba(${B(o)}, 0.02) 100%)`:"linear-gradient(90deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.02) 100%)",$=t?"rgba(0, 0, 0, 0.06)":"rgba(255, 255, 255, 0.06)",F=t?"0 14px 36px -8px rgba(15, 23, 42, 0.12), 0 2px 10px -2px rgba(15, 23, 42, 0.06), 0 0 16px -4px var(--horeg-glow)":"0 16px 40px -10px rgba(0, 0, 0, 0.9), 0 0 20px -5px var(--horeg-glow)",R=t?"0 18px 44px -8px rgba(15, 23, 42, 0.18), 0 0 24px -2px var(--horeg-glow)":"0 20px 48px -10px rgba(0, 0, 0, 0.95), 0 0 30px -2px var(--horeg-glow), 0 0 10px var(--horeg-glow)";return`
|
|
2
2
|
:host {
|
|
3
3
|
--horeg-bg: ${a};
|
|
4
|
-
--horeg-surface: ${
|
|
5
|
-
--horeg-surface-hover: ${
|
|
6
|
-
--horeg-border: ${
|
|
7
|
-
--horeg-glow: ${
|
|
8
|
-
--horeg-glow-rgb: ${B(
|
|
4
|
+
--horeg-surface: ${p};
|
|
5
|
+
--horeg-surface-hover: ${b};
|
|
6
|
+
--horeg-border: ${u};
|
|
7
|
+
--horeg-glow: ${o};
|
|
8
|
+
--horeg-glow-rgb: ${B(o)};
|
|
9
9
|
--horeg-accent: ${n};
|
|
10
|
-
--horeg-progress: ${
|
|
10
|
+
--horeg-progress: ${h};
|
|
11
11
|
--horeg-text-main: ${l};
|
|
12
|
-
--horeg-text-muted: ${
|
|
13
|
-
--horeg-radius: ${
|
|
14
|
-
--horeg-drawer-bg: ${
|
|
15
|
-
--horeg-slider-bg: ${
|
|
16
|
-
--horeg-slider-buffer: ${
|
|
17
|
-
--horeg-btn-play-bg: ${
|
|
18
|
-
--horeg-btn-play-text: ${
|
|
19
|
-
--horeg-bolt-bg: ${
|
|
20
|
-
--horeg-bolt-border: ${
|
|
21
|
-
--horeg-grill-color: ${
|
|
22
|
-
--horeg-grill-opacity: ${
|
|
23
|
-
--horeg-dropzone-bg: ${
|
|
24
|
-
--horeg-input-bg: ${
|
|
25
|
-
--horeg-tab-bg: ${
|
|
26
|
-
--horeg-tab-active-bg: ${
|
|
27
|
-
--horeg-item-active-bg: ${
|
|
28
|
-
--horeg-btn-active-bg: ${
|
|
12
|
+
--horeg-text-muted: ${v};
|
|
13
|
+
--horeg-radius: ${g};
|
|
14
|
+
--horeg-drawer-bg: ${x};
|
|
15
|
+
--horeg-slider-bg: ${k};
|
|
16
|
+
--horeg-slider-buffer: ${y};
|
|
17
|
+
--horeg-btn-play-bg: ${w};
|
|
18
|
+
--horeg-btn-play-text: ${f};
|
|
19
|
+
--horeg-bolt-bg: ${M};
|
|
20
|
+
--horeg-bolt-border: ${P};
|
|
21
|
+
--horeg-grill-color: ${S};
|
|
22
|
+
--horeg-grill-opacity: ${A};
|
|
23
|
+
--horeg-dropzone-bg: ${I};
|
|
24
|
+
--horeg-input-bg: ${z};
|
|
25
|
+
--horeg-tab-bg: ${N};
|
|
26
|
+
--horeg-tab-active-bg: ${H};
|
|
27
|
+
--horeg-item-active-bg: ${D};
|
|
28
|
+
--horeg-btn-active-bg: ${$};
|
|
29
29
|
--horeg-box-shadow: ${F};
|
|
30
|
-
--horeg-focus-shadow: ${
|
|
30
|
+
--horeg-focus-shadow: ${R};
|
|
31
31
|
display: block;
|
|
32
32
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
33
33
|
box-sizing: border-box;
|
|
@@ -151,54 +151,429 @@
|
|
|
151
151
|
}
|
|
152
152
|
|
|
153
153
|
/* Track Display & Visualizer Section */
|
|
154
|
-
|
|
154
|
+
/* 3-Soundbox Stage Visualizer */
|
|
155
|
+
.horeg-soundbox-stage {
|
|
156
|
+
position: relative;
|
|
157
|
+
width: 100%;
|
|
158
|
+
box-sizing: border-box;
|
|
155
159
|
display: flex;
|
|
156
160
|
align-items: center;
|
|
157
|
-
|
|
161
|
+
justify-content: center;
|
|
162
|
+
gap: 12px;
|
|
163
|
+
padding: 14px 24px;
|
|
164
|
+
background: ${t?"rgba(0, 0, 0, 0.04)":"rgba(0, 0, 0, 0.45)"};
|
|
165
|
+
border: 1px solid var(--horeg-border);
|
|
166
|
+
border-radius: 12px;
|
|
167
|
+
box-shadow: inset 0 2px 10px rgba(0, 0, 0, 0.35);
|
|
168
|
+
overflow: visible;
|
|
158
169
|
}
|
|
159
170
|
|
|
160
|
-
|
|
171
|
+
/* Base Soundbox Cabinet */
|
|
172
|
+
.horeg-soundbox {
|
|
161
173
|
position: relative;
|
|
162
|
-
width: 64px;
|
|
163
|
-
height: 64px;
|
|
164
|
-
min-width: 64px;
|
|
165
|
-
border-radius: 8px;
|
|
166
|
-
overflow: hidden;
|
|
167
174
|
background: var(--horeg-surface);
|
|
168
175
|
border: 1px solid var(--horeg-border);
|
|
176
|
+
box-sizing: border-box;
|
|
177
|
+
flex-shrink: 0;
|
|
178
|
+
user-select: none;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/* Miniature Box Bolts */
|
|
182
|
+
.horeg-box-bolt {
|
|
183
|
+
position: absolute;
|
|
184
|
+
width: 5px;
|
|
185
|
+
height: 5px;
|
|
186
|
+
background: ${M};
|
|
187
|
+
border: 1px solid ${P};
|
|
188
|
+
border-radius: 50%;
|
|
189
|
+
z-index: 5;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
.horeg-box-bolt.top-left { top: 4px; left: 4px; }
|
|
193
|
+
.horeg-box-bolt.top-right { top: 4px; right: 4px; }
|
|
194
|
+
.horeg-box-bolt.bottom-left { bottom: 4px; left: 4px; }
|
|
195
|
+
.horeg-box-bolt.bottom-right { bottom: 4px; right: 4px; }
|
|
196
|
+
|
|
197
|
+
/* Left & Right Satellite Speakers */
|
|
198
|
+
.horeg-soundbox.is-satellite {
|
|
199
|
+
width: 58px;
|
|
200
|
+
height: 106px;
|
|
201
|
+
border-radius: 6px;
|
|
202
|
+
padding: 6px 4px;
|
|
203
|
+
display: flex;
|
|
204
|
+
flex-direction: column;
|
|
205
|
+
justify-content: space-between;
|
|
206
|
+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(255, 255, 255, 0.06);
|
|
207
|
+
z-index: 2;
|
|
208
|
+
position: relative;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
.horeg-soundbox.is-satellite.is-left {
|
|
212
|
+
margin-right: -6px;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
.horeg-soundbox.is-satellite.is-right {
|
|
216
|
+
margin-left: -6px;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
.horeg-box-header, .horeg-box-footer {
|
|
220
|
+
position: relative;
|
|
221
|
+
display: flex;
|
|
222
|
+
align-items: center;
|
|
223
|
+
justify-content: center;
|
|
224
|
+
height: 10px;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.horeg-tweeter-slot {
|
|
228
|
+
width: 14px;
|
|
229
|
+
height: 3px;
|
|
230
|
+
background: var(--horeg-glow);
|
|
231
|
+
border-radius: 2px;
|
|
232
|
+
opacity: 0.75;
|
|
233
|
+
box-shadow: 0 0 4px var(--horeg-glow);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
.horeg-port-slot {
|
|
237
|
+
width: 16px;
|
|
238
|
+
height: 3px;
|
|
239
|
+
background: #090a0d;
|
|
240
|
+
border: 1px solid var(--horeg-border);
|
|
241
|
+
border-radius: 2px;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
.horeg-satellite-baffle {
|
|
245
|
+
display: flex;
|
|
246
|
+
flex-direction: column;
|
|
247
|
+
align-items: center;
|
|
248
|
+
justify-content: center;
|
|
249
|
+
gap: 6px;
|
|
250
|
+
flex: 1;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
.horeg-satellite-driver {
|
|
254
|
+
position: relative;
|
|
255
|
+
display: flex;
|
|
256
|
+
align-items: center;
|
|
257
|
+
justify-content: center;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
/* Water-like Ripple Rings around the 4 Satellite Circles */
|
|
261
|
+
.horeg-driver-ripple {
|
|
262
|
+
position: absolute;
|
|
263
|
+
top: 50%;
|
|
264
|
+
left: 50%;
|
|
265
|
+
width: 38px;
|
|
266
|
+
height: 38px;
|
|
267
|
+
margin-top: -19px;
|
|
268
|
+
margin-left: -19px;
|
|
269
|
+
border-radius: 50%;
|
|
270
|
+
border: 1.5px solid rgba(var(--horeg-glow-rgb), 0.5);
|
|
271
|
+
box-shadow: 0 0 12px rgba(var(--horeg-glow-rgb), 0.25), inset 0 0 8px rgba(var(--horeg-glow-rgb), 0.125);
|
|
272
|
+
opacity: 0;
|
|
273
|
+
pointer-events: none;
|
|
274
|
+
transform-origin: center center;
|
|
275
|
+
transition: transform 0.06s ease-out, opacity 0.06s ease-out;
|
|
276
|
+
z-index: 1;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.horeg-driver-ripple.ripple-2 {
|
|
280
|
+
border-width: 1px;
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
.horeg-driver-surround {
|
|
284
|
+
position: relative;
|
|
285
|
+
z-index: 2;
|
|
286
|
+
width: 38px;
|
|
287
|
+
height: 38px;
|
|
288
|
+
border-radius: 50%;
|
|
289
|
+
background: #0c0d12;
|
|
290
|
+
border: 1px solid var(--horeg-border);
|
|
291
|
+
display: flex;
|
|
292
|
+
align-items: center;
|
|
293
|
+
justify-content: center;
|
|
294
|
+
box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.8);
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
.horeg-driver-cone {
|
|
298
|
+
width: 30px;
|
|
299
|
+
height: 30px;
|
|
300
|
+
border-radius: 50%;
|
|
301
|
+
background: radial-gradient(circle, #2a2b33 0%, #15161c 65%, #09090b 100%);
|
|
302
|
+
border: 1px solid rgba(255, 255, 255, 0.08);
|
|
169
303
|
display: flex;
|
|
170
304
|
align-items: center;
|
|
171
305
|
justify-content: center;
|
|
172
|
-
|
|
306
|
+
transform-origin: center center;
|
|
307
|
+
transition: transform 0.05s ease-out;
|
|
308
|
+
box-shadow: 0 0 4px rgba(0, 0, 0, 0.5);
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
.horeg-driver-cap {
|
|
312
|
+
width: 10px;
|
|
313
|
+
height: 10px;
|
|
314
|
+
border-radius: 50%;
|
|
315
|
+
background: radial-gradient(circle, var(--horeg-glow) 0%, #181920 80%);
|
|
316
|
+
opacity: 0.85;
|
|
317
|
+
box-shadow: 0 0 4px var(--horeg-glow);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/* Center Monster Subwoofer - Higher z-index in front of left and right */
|
|
321
|
+
.horeg-soundbox.is-subwoofer {
|
|
322
|
+
width: 126px;
|
|
323
|
+
height: 126px;
|
|
324
|
+
border-radius: 12px;
|
|
325
|
+
border: 1.5px solid var(--horeg-border);
|
|
326
|
+
display: flex;
|
|
327
|
+
align-items: center;
|
|
328
|
+
justify-content: center;
|
|
329
|
+
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.6), inset 0 1px 0 rgba(255, 255, 255, 0.08);
|
|
330
|
+
z-index: 10 !important;
|
|
331
|
+
position: relative;
|
|
332
|
+
transition: transform 0.04s ease-out, box-shadow 0.08s ease-out;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
/* Concentric Bass Shockwaves */
|
|
336
|
+
.horeg-shockwaves-wrap {
|
|
337
|
+
position: absolute;
|
|
338
|
+
top: 50%;
|
|
339
|
+
left: 50%;
|
|
340
|
+
width: 0;
|
|
341
|
+
height: 0;
|
|
342
|
+
pointer-events: none;
|
|
343
|
+
z-index: 6;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
.horeg-shockwave {
|
|
347
|
+
position: absolute;
|
|
348
|
+
top: -50px;
|
|
349
|
+
left: -50px;
|
|
350
|
+
width: 100px;
|
|
351
|
+
height: 100px;
|
|
352
|
+
border-radius: 50%;
|
|
353
|
+
border: 2px solid var(--horeg-glow);
|
|
354
|
+
box-shadow: 0 0 16px var(--horeg-glow), inset 0 0 8px var(--horeg-glow);
|
|
355
|
+
opacity: 0;
|
|
356
|
+
transform-origin: center center;
|
|
357
|
+
pointer-events: none;
|
|
358
|
+
transition: transform 0.05s ease-out, opacity 0.08s ease-out;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
.horeg-shockwave.wave-1 {
|
|
362
|
+
border-width: 2.5px;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
.horeg-shockwave.wave-2 {
|
|
366
|
+
border-width: 1.5px;
|
|
367
|
+
border-style: dashed;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/* Subwoofer Frame Details */
|
|
371
|
+
.horeg-sub-frame {
|
|
372
|
+
position: absolute;
|
|
373
|
+
inset: 0;
|
|
374
|
+
pointer-events: none;
|
|
375
|
+
z-index: 3;
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
.horeg-sub-badge {
|
|
379
|
+
position: absolute;
|
|
380
|
+
top: 2px;
|
|
381
|
+
left: 50%;
|
|
382
|
+
transform: translateX(-50%);
|
|
383
|
+
font-size: 8px;
|
|
384
|
+
font-weight: 800;
|
|
385
|
+
letter-spacing: 1.2px;
|
|
386
|
+
color: var(--horeg-glow);
|
|
387
|
+
background: rgba(0, 0, 0, 0.2);
|
|
388
|
+
padding: 1px 6px;
|
|
389
|
+
border-radius: 3px;
|
|
390
|
+
border: 1px solid rgba(255, 255, 255, 0.05);
|
|
391
|
+
text-shadow: 0 0 6px var(--horeg-glow);
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
.horeg-sub-ports {
|
|
395
|
+
position: absolute;
|
|
396
|
+
bottom: 6px;
|
|
397
|
+
left: 0;
|
|
398
|
+
right: 0;
|
|
399
|
+
display: flex;
|
|
400
|
+
justify-content: space-between;
|
|
401
|
+
padding: 0 12px;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
.horeg-sub-port {
|
|
405
|
+
width: 10px;
|
|
406
|
+
height: 10px;
|
|
407
|
+
background: #08080a;
|
|
408
|
+
border-radius: 50%;
|
|
409
|
+
border: 1px solid var(--horeg-border);
|
|
410
|
+
box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.9);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/* Subwoofer Baffle, Surround & Cone */
|
|
414
|
+
.horeg-sub-baffle {
|
|
415
|
+
position: relative;
|
|
416
|
+
z-index: 2;
|
|
417
|
+
width: 96px;
|
|
418
|
+
height: 96px;
|
|
419
|
+
border-radius: 50%;
|
|
420
|
+
background: #0a0b0e;
|
|
421
|
+
display: flex;
|
|
422
|
+
align-items: center;
|
|
423
|
+
justify-content: center;
|
|
424
|
+
border: 1.5px solid var(--horeg-border);
|
|
425
|
+
box-shadow: inset 0 0 12px rgba(0, 0, 0, 0.9);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
.horeg-sub-surround {
|
|
429
|
+
width: 86px;
|
|
430
|
+
height: 86px;
|
|
431
|
+
border-radius: 50%;
|
|
432
|
+
background: radial-gradient(circle, #1a1b22 60%, #0d0e13 100%);
|
|
433
|
+
border: 2px solid rgba(0, 0, 0, 0.6);
|
|
434
|
+
display: flex;
|
|
435
|
+
align-items: center;
|
|
436
|
+
justify-content: center;
|
|
437
|
+
box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.7);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
.horeg-sub-cone {
|
|
441
|
+
width: 72px;
|
|
442
|
+
height: 72px;
|
|
443
|
+
border-radius: 50%;
|
|
444
|
+
background: radial-gradient(circle, #2a2b34 0%, #15161d 65%, #0a0a0d 100%);
|
|
445
|
+
display: flex;
|
|
446
|
+
align-items: center;
|
|
447
|
+
justify-content: center;
|
|
448
|
+
transform-origin: center center;
|
|
449
|
+
transition: transform 0.05s ease-out;
|
|
450
|
+
box-shadow: 0 0 10px rgba(0, 0, 0, 0.6);
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
/* Circular Cover Art inside Subwoofer */
|
|
454
|
+
.horeg-sub-cover-wrap {
|
|
455
|
+
position: relative;
|
|
456
|
+
width: 54px;
|
|
457
|
+
height: 54px;
|
|
458
|
+
min-width: 54px;
|
|
459
|
+
border-radius: 50%;
|
|
460
|
+
overflow: hidden;
|
|
461
|
+
background: #0f1015;
|
|
462
|
+
border: 2px solid var(--horeg-glow);
|
|
463
|
+
display: flex;
|
|
464
|
+
align-items: center;
|
|
465
|
+
justify-content: center;
|
|
466
|
+
box-shadow: 0 0 12px var(--horeg-glow), inset 0 0 8px rgba(0, 0, 0, 0.6);
|
|
173
467
|
}
|
|
174
468
|
|
|
175
469
|
.horeg-cover-img {
|
|
176
470
|
width: 100%;
|
|
177
471
|
height: 100%;
|
|
178
472
|
object-fit: cover;
|
|
473
|
+
display: block;
|
|
179
474
|
}
|
|
180
475
|
|
|
181
476
|
.horeg-cover-fallback {
|
|
182
477
|
color: var(--horeg-glow);
|
|
183
|
-
opacity: 0.
|
|
478
|
+
opacity: 0.8;
|
|
479
|
+
display: flex;
|
|
480
|
+
align-items: center;
|
|
481
|
+
justify-content: center;
|
|
184
482
|
}
|
|
185
483
|
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
min-width: 0;
|
|
484
|
+
/* Centered Metadata & Title Marquee Section */
|
|
485
|
+
.horeg-track-meta {
|
|
189
486
|
display: flex;
|
|
190
487
|
flex-direction: column;
|
|
191
|
-
|
|
488
|
+
align-items: center;
|
|
489
|
+
justify-content: center;
|
|
490
|
+
gap: 3px;
|
|
491
|
+
margin: 4px 0 2px 0;
|
|
492
|
+
text-align: center;
|
|
493
|
+
width: 100%;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
.horeg-title-wrap {
|
|
497
|
+
width: 100%;
|
|
498
|
+
max-width: 380px;
|
|
499
|
+
overflow: hidden;
|
|
500
|
+
position: relative;
|
|
501
|
+
margin: 0 auto;
|
|
502
|
+
text-align: center;
|
|
503
|
+
display: flex;
|
|
504
|
+
align-items: center;
|
|
505
|
+
justify-content: center;
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
.horeg-title-wrap.is-overflowing {
|
|
509
|
+
justify-content: flex-start;
|
|
510
|
+
-webkit-mask-image: linear-gradient(to right, #000 0%, #000 calc(100% - 24px), transparent 100%);
|
|
511
|
+
mask-image: linear-gradient(to right, #000 0%, #000 calc(100% - 24px), transparent 100%);
|
|
512
|
+
animation: horegTitleMask var(--marquee-duration, 8s) ease-in-out infinite;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
/* Mask Fading:
|
|
516
|
+
- 0% - 18%: Teks di ujung kiri (awal) -> fade kiri hilang (teks jelas), fade kanan aktif
|
|
517
|
+
- 26% - 70%: Teks berjalan -> fade kiri & kanan sama-sama aktif
|
|
518
|
+
- 78% - 86%: Teks di ujung kanan (akhir) -> fade kanan hilang (teks jelas), fade kiri aktif
|
|
519
|
+
- 92% - 100%: Teks reset ke awal -> fade kiri hilang kembali, fade kanan aktif
|
|
520
|
+
*/
|
|
521
|
+
@keyframes horegTitleMask {
|
|
522
|
+
0%, 18% {
|
|
523
|
+
-webkit-mask-image: linear-gradient(to right, #000 0%, #000 calc(100% - 24px), transparent 100%);
|
|
524
|
+
mask-image: linear-gradient(to right, #000 0%, #000 calc(100% - 24px), transparent 100%);
|
|
525
|
+
}
|
|
526
|
+
26%, 70% {
|
|
527
|
+
-webkit-mask-image: linear-gradient(to right, transparent 0%, #000 24px, #000 calc(100% - 24px), transparent 100%);
|
|
528
|
+
mask-image: linear-gradient(to right, transparent 0%, #000 24px, #000 calc(100% - 24px), transparent 100%);
|
|
529
|
+
}
|
|
530
|
+
78%, 86% {
|
|
531
|
+
-webkit-mask-image: linear-gradient(to right, transparent 0%, #000 24px, #000 100%);
|
|
532
|
+
mask-image: linear-gradient(to right, transparent 0%, #000 24px, #000 100%);
|
|
533
|
+
}
|
|
534
|
+
92%, 100% {
|
|
535
|
+
-webkit-mask-image: linear-gradient(to right, #000 0%, #000 calc(100% - 24px), transparent 100%);
|
|
536
|
+
mask-image: linear-gradient(to right, #000 0%, #000 calc(100% - 24px), transparent 100%);
|
|
537
|
+
}
|
|
192
538
|
}
|
|
193
539
|
|
|
194
540
|
.horeg-track-title {
|
|
195
541
|
font-size: 15px;
|
|
196
542
|
font-weight: 700;
|
|
197
543
|
white-space: nowrap;
|
|
198
|
-
|
|
199
|
-
text-overflow: ellipsis;
|
|
544
|
+
display: inline-block;
|
|
200
545
|
color: var(--horeg-text-main);
|
|
201
546
|
letter-spacing: 0.2px;
|
|
547
|
+
text-align: center;
|
|
548
|
+
will-change: transform, opacity;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/* Marquee: Reset ke posisi awal (BUKAN rewind bolak-balik) */
|
|
552
|
+
.horeg-track-title.is-marquee {
|
|
553
|
+
animation: horegMarquee var(--marquee-duration, 8s) ease-in-out infinite;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
@keyframes horegMarquee {
|
|
557
|
+
0%, 18% {
|
|
558
|
+
transform: translateX(0);
|
|
559
|
+
opacity: 1;
|
|
560
|
+
}
|
|
561
|
+
76%, 86% {
|
|
562
|
+
transform: translateX(var(--marquee-dist, -40px));
|
|
563
|
+
opacity: 1;
|
|
564
|
+
}
|
|
565
|
+
90% {
|
|
566
|
+
transform: translateX(var(--marquee-dist, -40px));
|
|
567
|
+
opacity: 0;
|
|
568
|
+
}
|
|
569
|
+
93% {
|
|
570
|
+
transform: translateX(0);
|
|
571
|
+
opacity: 0;
|
|
572
|
+
}
|
|
573
|
+
100% {
|
|
574
|
+
transform: translateX(0);
|
|
575
|
+
opacity: 1;
|
|
576
|
+
}
|
|
202
577
|
}
|
|
203
578
|
|
|
204
579
|
.horeg-track-artist {
|
|
@@ -208,33 +583,19 @@
|
|
|
208
583
|
white-space: nowrap;
|
|
209
584
|
overflow: hidden;
|
|
210
585
|
text-overflow: ellipsis;
|
|
586
|
+
max-width: 360px;
|
|
587
|
+
text-align: center;
|
|
211
588
|
}
|
|
212
589
|
|
|
213
590
|
.horeg-track-album {
|
|
214
591
|
font-size: 10px;
|
|
215
592
|
color: var(--horeg-text-muted);
|
|
216
|
-
opacity: 0.
|
|
593
|
+
opacity: 0.8;
|
|
217
594
|
white-space: nowrap;
|
|
218
595
|
overflow: hidden;
|
|
219
596
|
text-overflow: ellipsis;
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
/* Mini EQ Visualizer */
|
|
223
|
-
.horeg-eq-wrapper {
|
|
224
|
-
display: flex;
|
|
225
|
-
align-items: flex-end;
|
|
226
|
-
gap: 2px;
|
|
227
|
-
height: 24px;
|
|
228
|
-
padding: 0 4px;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
.horeg-eq-bar {
|
|
232
|
-
width: 3px;
|
|
233
|
-
height: 4px;
|
|
234
|
-
background: var(--horeg-glow);
|
|
235
|
-
border-radius: 1px;
|
|
236
|
-
transition: height 0.1s ease;
|
|
237
|
-
box-shadow: 0 0 4px var(--horeg-glow);
|
|
597
|
+
max-width: 360px;
|
|
598
|
+
text-align: center;
|
|
238
599
|
}
|
|
239
600
|
|
|
240
601
|
/* Scrubbing / Fader Progress Bar */
|
|
@@ -258,26 +619,12 @@
|
|
|
258
619
|
height: 7px;
|
|
259
620
|
background: var(--horeg-slider-bg);
|
|
260
621
|
border-radius: 4px;
|
|
261
|
-
cursor:
|
|
622
|
+
cursor: pointer;
|
|
262
623
|
overflow: hidden;
|
|
263
624
|
box-shadow: inset 0 1px 3px rgba(0,0,0,0.2);
|
|
264
625
|
touch-action: none;
|
|
265
626
|
}
|
|
266
627
|
|
|
267
|
-
.horeg-slider-track:hover {
|
|
268
|
-
cursor: grab;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
.horeg-slider-track:active,
|
|
272
|
-
.horeg-slider-track.scrubbing {
|
|
273
|
-
cursor: grabbing;
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
.horeg-player-box.scrubbing,
|
|
277
|
-
.horeg-player-box.scrubbing * {
|
|
278
|
-
cursor: grabbing !important;
|
|
279
|
-
}
|
|
280
|
-
|
|
281
628
|
.horeg-buffer-bar {
|
|
282
629
|
position: absolute;
|
|
283
630
|
top: 0;
|
|
@@ -416,11 +763,7 @@
|
|
|
416
763
|
background: var(--horeg-slider-bg);
|
|
417
764
|
border-radius: 3px;
|
|
418
765
|
outline: none;
|
|
419
|
-
cursor:
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
.horeg-volume-slider:active {
|
|
423
|
-
cursor: grabbing;
|
|
766
|
+
cursor: pointer;
|
|
424
767
|
}
|
|
425
768
|
|
|
426
769
|
.horeg-volume-slider::-webkit-slider-thumb {
|
|
@@ -432,7 +775,7 @@
|
|
|
432
775
|
background: var(--horeg-glow);
|
|
433
776
|
border: 1px solid var(--horeg-border);
|
|
434
777
|
box-shadow: 0 0 6px var(--horeg-glow);
|
|
435
|
-
cursor:
|
|
778
|
+
cursor: pointer;
|
|
436
779
|
transition: transform 0.1s ease;
|
|
437
780
|
}
|
|
438
781
|
|
|
@@ -440,10 +783,6 @@
|
|
|
440
783
|
transform: scale(1.2);
|
|
441
784
|
}
|
|
442
785
|
|
|
443
|
-
.horeg-volume-slider:active::-webkit-slider-thumb {
|
|
444
|
-
cursor: grabbing;
|
|
445
|
-
}
|
|
446
|
-
|
|
447
786
|
.horeg-volume-slider::-moz-range-thumb {
|
|
448
787
|
width: 12px;
|
|
449
788
|
height: 12px;
|
|
@@ -451,11 +790,7 @@
|
|
|
451
790
|
background: var(--horeg-glow);
|
|
452
791
|
border: 1px solid var(--horeg-border);
|
|
453
792
|
box-shadow: 0 0 6px var(--horeg-glow);
|
|
454
|
-
cursor:
|
|
455
|
-
}
|
|
456
|
-
|
|
457
|
-
.horeg-volume-slider:active::-moz-range-thumb {
|
|
458
|
-
cursor: grabbing;
|
|
793
|
+
cursor: pointer;
|
|
459
794
|
}
|
|
460
795
|
|
|
461
796
|
/* Drag Over Highlight on main player */
|
|
@@ -870,9 +1205,85 @@
|
|
|
870
1205
|
font-size: 12px;
|
|
871
1206
|
font-style: italic;
|
|
872
1207
|
}
|
|
873
|
-
`}function T(h){if(isNaN(h)||!isFinite(h)||h<0)return"00:00";const e=Math.floor(h),t=Math.floor(e/3600),r=Math.floor(e%3600/60),i=e%60,n=a=>a.toString().padStart(2,"0");return t>0?`${t}:${n(r)}:${n(i)}`:`${n(r)}:${n(i)}`}function u(h,e,t){return Math.min(Math.max(h,e),t)}class j{constructor(e,t={}){o(this,"audio");o(this,"playlist",[]);o(this,"currentIndex",0);o(this,"loopMode","all");o(this,"shuffleMode",!1);o(this,"volumeLevel",.8);o(this,"previousVolume",.8);o(this,"callbacks",{});o(this,"handlePlay",()=>{const e=this.getCurrentTrack();e&&this.callbacks.onPlay&&this.callbacks.onPlay(e)});o(this,"handlePause",()=>{this.callbacks.onPause&&this.callbacks.onPause()});o(this,"handleTimeUpdate",()=>{if(this.audio.seeking)return;const e=this.audio.currentTime||0,t=this.getDuration();this.callbacks.onTimeUpdate&&this.callbacks.onTimeUpdate(e,t)});o(this,"handleSeeked",()=>{const e=this.audio.currentTime||0,t=this.getDuration();this.callbacks.onTimeUpdate&&this.callbacks.onTimeUpdate(e,t)});o(this,"handleProgress",()=>{if(this.audio.buffered.length>0&&this.audio.duration>0){const e=this.audio.buffered.end(this.audio.buffered.length-1),t=u(e/this.audio.duration*100,0,100);this.callbacks.onBufferUpdate&&this.callbacks.onBufferUpdate(t)}});o(this,"handleLoadedMetadata",()=>{const e=this.audio.currentTime||0,t=this.getDuration();this.callbacks.onTimeUpdate&&this.callbacks.onTimeUpdate(e,t),this.handleProgress()});o(this,"handleWaiting",()=>{this.callbacks.onLoadingChange&&this.callbacks.onLoadingChange(!0)});o(this,"handlePlaying",()=>{this.callbacks.onLoadingChange&&this.callbacks.onLoadingChange(!1)});o(this,"handleEnded",()=>{const e=this.getCurrentTrack();e&&this.callbacks.onEnded&&this.callbacks.onEnded(e),this.loopMode==="one"?(this.audio.currentTime=0,this.play()):this.next(!0)});o(this,"handleError",()=>{const e=this.audio.error||new Error("Unknown audio playback error");this.callbacks.onError&&this.callbacks.onError(e)});this.audio=new Audio,this.playlist=[...e.playlist||[]],this.currentIndex=e.initialIndex!==void 0?u(e.initialIndex,0,Math.max(0,this.playlist.length-1)):0,this.loopMode=e.loop||"all",this.shuffleMode=!!e.shuffle,this.volumeLevel=e.volume!==void 0?u(e.volume,0,1):.8,this.callbacks=t||{onPlay:e.onPlay,onPause:e.onPause,onTrackChange:e.onTrackChange,onPlaylistChange:e.onPlaylistChange,onTimeUpdate:e.onTimeUpdate,onEnded:e.onEnded,onError:e.onError},this.audio.volume=this.volumeLevel,this.attachEvents(),this.playlist.length>0&&this.loadTrack(this.currentIndex,!!e.autoplay)}attachEvents(){this.audio.addEventListener("play",this.handlePlay),this.audio.addEventListener("pause",this.handlePause),this.audio.addEventListener("timeupdate",this.handleTimeUpdate),this.audio.addEventListener("progress",this.handleProgress),this.audio.addEventListener("ended",this.handleEnded),this.audio.addEventListener("error",this.handleError),this.audio.addEventListener("waiting",this.handleWaiting),this.audio.addEventListener("playing",this.handlePlaying),this.audio.addEventListener("loadedmetadata",this.handleLoadedMetadata),this.audio.addEventListener("seeked",this.handleSeeked)}detachEvents(){this.audio.removeEventListener("play",this.handlePlay),this.audio.removeEventListener("pause",this.handlePause),this.audio.removeEventListener("timeupdate",this.handleTimeUpdate),this.audio.removeEventListener("progress",this.handleProgress),this.audio.removeEventListener("ended",this.handleEnded),this.audio.removeEventListener("error",this.handleError),this.audio.removeEventListener("waiting",this.handleWaiting),this.audio.removeEventListener("playing",this.handlePlaying),this.audio.removeEventListener("loadedmetadata",this.handleLoadedMetadata),this.audio.removeEventListener("seeked",this.handleSeeked)}getCurrentTrack(){return this.playlist[this.currentIndex]}getCurrentIndex(){return this.currentIndex}getPlaylist(){return this.playlist}setPlaylist(e,t=0){this.playlist=[...e],this.currentIndex=u(t,0,Math.max(0,this.playlist.length-1)),this.loadTrack(this.currentIndex,!1),this.callbacks.onPlaylistChange&&this.callbacks.onPlaylistChange([...this.playlist],this.currentIndex),this.playlist.length>0?this.loadTrack(this.currentIndex,!1):(this.audio.pause(),this.audio.src="",this.callbacks.onTrackChange&&this.callbacks.onTrackChange({title:"No Track Loaded",src:""},0))}addTrack(e,t=!1){const r=this.playlist.length===0;this.playlist.push(e);const i=this.playlist.length-1;return this.callbacks.onPlaylistChange&&this.callbacks.onPlaylistChange([...this.playlist],this.currentIndex),r?this.loadTrack(0,t):t&&this.loadTrack(i,!0),i}addTracks(e,t=!1){if(!e||e.length===0)return;const r=this.playlist.length===0,i=this.playlist.length;this.playlist.push(...e),this.callbacks.onPlaylistChange&&this.callbacks.onPlaylistChange([...this.playlist],this.currentIndex),r?this.loadTrack(0,t):t&&this.loadTrack(i,!0)}removeTrack(e){if(e<0||e>=this.playlist.length)return;const t=e===this.currentIndex;if(this.playlist.splice(e,1),this.playlist.length===0)this.currentIndex=0,this.audio.pause(),this.audio.src="",this.callbacks.onTrackChange&&this.callbacks.onTrackChange({title:"No Track Loaded",src:""},0);else if(t){const r=u(e,0,this.playlist.length-1);this.loadTrack(r,!1)}else e<this.currentIndex&&this.currentIndex--;this.callbacks.onPlaylistChange&&this.callbacks.onPlaylistChange([...this.playlist],this.currentIndex)}getDuration(){const e=this.audio.duration;if(e&&!isNaN(e)&&isFinite(e))return e;const t=this.getCurrentTrack();return(t==null?void 0:t.duration)||0}getCurrentTime(){return this.audio.currentTime||0}isPlaying(){return!this.audio.paused&&!this.audio.ended}isMuted(){return this.audio.muted||this.audio.volume===0}getVolume(){return this.audio.volume}getLoop(){return this.loopMode}isShuffle(){return this.shuffleMode}loadTrack(e,t=!1){let r;typeof e=="number"?r=u(e,0,Math.max(0,this.playlist.length-1)):(r=this.playlist.findIndex(n=>n.src===e.src),r===-1&&(this.playlist.push(e),r=this.playlist.length-1)),this.currentIndex=r;const i=this.playlist[this.currentIndex];i&&(this.audio.src=i.src,this.callbacks.onTrackChange&&this.callbacks.onTrackChange(i,this.currentIndex),t&&this.play())}async play(){try{await this.audio.play()}catch(e){console.warn("[HoregAudio] Autoplay / Audio play was prevented by browser policy:",e)}}pause(){this.audio.pause()}toggle(){this.audio.paused?this.play():this.pause()}seek(e){const t=this.getDuration(),r=u(e,0,t>0?t:1/0);this.audio.currentTime=r}setVolume(e){const t=u(e,0,1);this.volumeLevel=t,this.audio.volume=t,t>0&&(this.audio.muted=!1,this.previousVolume=t)}toggleMute(){return this.isMuted()?(this.audio.muted=!1,this.setVolume(this.previousVolume>0?this.previousVolume:.5),!1):(this.previousVolume=this.audio.volume,this.audio.muted=!0,!0)}next(e=!1){if(this.playlist.length===0)return;if(this.shuffleMode&&this.playlist.length>1){let r;do r=Math.floor(Math.random()*this.playlist.length);while(r===this.currentIndex);this.loadTrack(r,!0);return}const t=this.currentIndex+1;t<this.playlist.length?this.loadTrack(t,!0):this.loopMode==="all"?this.loadTrack(0,!0):e?this.pause():this.loadTrack(0,!0)}prev(){if(this.playlist.length===0)return;if(this.audio.currentTime>2){this.seek(0);return}if(this.shuffleMode&&this.playlist.length>1){let t;do t=Math.floor(Math.random()*this.playlist.length);while(t===this.currentIndex);this.loadTrack(t,!0);return}const e=this.currentIndex-1;e>=0?this.loadTrack(e,!0):this.loopMode==="all"?this.loadTrack(this.playlist.length-1,!0):this.seek(0)}setLoop(e){this.loopMode=e}setShuffle(e){this.shuffleMode=e}setCallbacks(e){this.callbacks={...this.callbacks,...e}}destroy(){this.detachEvents(),this.audio.pause(),this.audio.src="",this.audio.load()}}const c={play:'<svg viewBox="0 0 24 24" fill="currentColor" width="20" height="20"><path d="M8 5v14l11-7z"/></svg>',pause:'<svg viewBox="0 0 24 24" fill="currentColor" width="20" height="20"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>',prev:'<svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18"><path d="M6 6h2v12H6zm3.5 6l8.5 6V6z"/></svg>',next:'<svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18"><path d="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z"/></svg>',volumeHigh:'<svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></svg>',volumeMute:'<svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18"><path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27l4.73 4.73H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/></svg>',shuffle:'<svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16"><path d="M10.59 9.17L5.41 4 4 5.41l5.17 5.17 1.42-1.41zM14.5 4l2.04 2.04L4 18.59 5.41 20 17.96 7.46 20 9.5V4h-5.5zm.33 9.41l-1.41 1.41 3.13 3.13L14.5 20H20v-5.5l-2.04 2.04-3.13-3.13z"/></svg>',repeat:'<svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16"><path d="M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4z"/></svg>',repeatOne:'<svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16"><path d="M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4zm-4-2V9h-1l-2 1v1h1.5v4H13z"/></svg>',playlist:'<svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18"><path d="M3 10h11v2H3zm0-4h11v2H3zm0 8h7v2H3zm13-1v8l6-4-6-4z"/></svg>',speaker:'<svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M17 2H7c-1.1 0-2 .9-2 2v16c0 1.1.9 1.99 2 1.99L17 22c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-5 2c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm0 16c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></svg>',plus:'<svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>',trash:'<svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg>',upload:'<svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M9 16h6v-6h4l-7-7-7 7h4zm-4 2h14v2H5z"/></svg>',link:'<svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></svg>'};function s(h,e){const t=document.createElement(h);if(e!=null&&e.className&&(t.className=e.className),e!=null&&e.attributes)for(const[r,i]of Object.entries(e.attributes))t.setAttribute(r,i);return e!=null&&e.innerHTML?t.innerHTML=e.innerHTML:e!=null&&e.textContent&&(t.textContent=e.textContent),t}class q{constructor(e){o(this,"root");o(this,"eqContainer");o(this,"playBtn");o(this,"prevBtn");o(this,"nextBtn");o(this,"shuffleBtn");o(this,"loopBtn");o(this,"muteBtn");o(this,"drawerBtn");o(this,"titleEl");o(this,"artistEl");o(this,"albumEl");o(this,"coverImgEl",null);o(this,"coverContainer");o(this,"currentTimeEl");o(this,"durationEl");o(this,"sliderTrack");o(this,"fillBar");o(this,"bufferBar");o(this,"volumeSlider");o(this,"drawerEl");o(this,"drawerCountEl");o(this,"addTrackBtn");o(this,"addPanelEl");o(this,"fileInputEl");o(this,"tabBtnFile");o(this,"tabBtnUrl");o(this,"tabPaneFile");o(this,"tabPaneUrl");o(this,"urlInput");o(this,"titleInput");o(this,"artistInput");o(this,"submitUrlBtn");o(this,"cancelAddBtn");o(this,"dropzoneEl");o(this,"drawerInner");o(this,"isScrubbing",!1);o(this,"currentDuration",0);o(this,"events");o(this,"startScrubbing",e=>{e.preventDefault(),this.isScrubbing=!0,document.body.style.userSelect="none",this.handleScrubbingMove(e);const t=i=>{this.isScrubbing&&this.handleScrubbingMove(i)},r=i=>{this.isScrubbing&&(this.finishScrubbing(i),window.removeEventListener("mousemove",t),window.removeEventListener("mouseup",r),window.removeEventListener("touchmove",t),window.removeEventListener("touchend",r))};window.addEventListener("mousemove",t),window.addEventListener("mouseup",r),window.addEventListener("touchmove",t,{passive:!1}),window.addEventListener("touchend",r)});this.events=e,this.root=s("div",{className:"horeg-player-box"});const t=s("div",{className:"horeg-speaker-grill"});this.root.appendChild(t),["top-left","top-right","bottom-left","bottom-right"].forEach(P=>{this.root.appendChild(s("div",{className:`horeg-bolt ${P}`}))});const r=s("div",{className:"horeg-content-wrap"});this.root.appendChild(r);const i=s("div",{className:"horeg-header"}),n=s("div",{className:"horeg-rig-badge",innerHTML:'<span class="horeg-badge-led"></span> HOREG RIG • HIGH VOLTAGE'});i.appendChild(n),r.appendChild(i);const a=s("div",{className:"horeg-track-row"});this.coverContainer=s("div",{className:"horeg-cover-container"}),this.coverContainer.innerHTML=`<span class="horeg-cover-fallback">${c.speaker}</span>`,a.appendChild(this.coverContainer);const l=s("div",{className:"horeg-track-info"});this.titleEl=s("div",{className:"horeg-track-title",textContent:"No Track Loaded"}),this.artistEl=s("div",{className:"horeg-track-artist",textContent:"Unknown Artist"}),this.albumEl=s("div",{className:"horeg-track-album",textContent:""}),l.appendChild(this.titleEl),l.appendChild(this.artistEl),l.appendChild(this.albumEl),a.appendChild(l),this.eqContainer=s("div",{className:"horeg-eq-wrapper"}),a.appendChild(this.eqContainer),r.appendChild(a);const d=s("div",{className:"horeg-progress-container"}),p=s("div",{className:"horeg-time-row"});this.currentTimeEl=s("span",{textContent:"00:00"}),this.durationEl=s("span",{textContent:"00:00"}),p.appendChild(this.currentTimeEl),p.appendChild(this.durationEl),d.appendChild(p),this.sliderTrack=s("div",{className:"horeg-slider-track",attributes:{role:"slider","aria-label":"Seek progress","aria-valuemin":"0","aria-valuemax":"100","aria-valuenow":"0",tabindex:"0"}}),this.bufferBar=s("div",{className:"horeg-buffer-bar"}),this.fillBar=s("div",{className:"horeg-fill-bar"}),this.sliderTrack.appendChild(this.bufferBar),this.sliderTrack.appendChild(this.fillBar),d.appendChild(this.sliderTrack),r.appendChild(d);const g=s("div",{className:"horeg-controls-row"}),f=s("div",{className:"horeg-side-controls"});this.shuffleBtn=s("button",{className:"horeg-btn",attributes:{"aria-label":"Toggle shuffle",type:"button"},innerHTML:c.shuffle}),this.loopBtn=s("button",{className:"horeg-btn active",attributes:{"aria-label":"Toggle loop mode",type:"button"},innerHTML:c.repeat}),f.appendChild(this.shuffleBtn),f.appendChild(this.loopBtn),g.appendChild(f);const b=s("div",{className:"horeg-center-controls"});this.prevBtn=s("button",{className:"horeg-btn",attributes:{"aria-label":"Previous track",type:"button"},innerHTML:c.prev}),this.playBtn=s("button",{className:"horeg-btn horeg-btn-play",attributes:{"aria-label":"Play track",type:"button"},innerHTML:c.play}),this.nextBtn=s("button",{className:"horeg-btn",attributes:{"aria-label":"Next track",type:"button"},innerHTML:c.next}),b.appendChild(this.prevBtn),b.appendChild(this.playBtn),b.appendChild(this.nextBtn),g.appendChild(b);const x=s("div",{className:"horeg-side-controls"}),w=s("div",{className:"horeg-volume-wrap"});this.muteBtn=s("button",{className:"horeg-btn",attributes:{"aria-label":"Toggle mute",type:"button"},innerHTML:c.volumeHigh}),this.volumeSlider=s("input",{className:"horeg-volume-slider",attributes:{type:"range",min:"0",max:"1",step:"0.01",value:"0.8","aria-label":"Volume control"}}),w.appendChild(this.muteBtn),w.appendChild(this.volumeSlider),x.appendChild(w),this.drawerBtn=s("button",{className:"horeg-btn",attributes:{"aria-label":"Toggle playlist drawer",type:"button"},innerHTML:c.playlist}),x.appendChild(this.drawerBtn),g.appendChild(x),r.appendChild(g),this.drawerEl=s("div",{className:"horeg-drawer"});const y=s("div",{className:"horeg-drawer-header"}),k=s("div",{className:"horeg-drawer-heading"});k.innerHTML="<span>PLAYLIST</span>",this.drawerCountEl=s("span",{className:"horeg-drawer-count",textContent:"0"}),k.appendChild(this.drawerCountEl),y.appendChild(k),this.addTrackBtn=s("button",{className:"horeg-btn-add-track",attributes:{type:"button","aria-label":"Add track to playlist"},innerHTML:`${c.plus} <span>Add Track</span>`}),y.appendChild(this.addTrackBtn),this.drawerEl.appendChild(y),this.addPanelEl=s("div",{className:"horeg-add-panel"});const E=s("div",{className:"horeg-add-tabs"});this.tabBtnFile=s("button",{className:"horeg-tab-btn active",attributes:{type:"button"},innerHTML:`${c.upload} <span>File Lokal</span>`}),this.tabBtnUrl=s("button",{className:"horeg-tab-btn",attributes:{type:"button"},innerHTML:`${c.link} <span>Audio URL</span>`}),E.appendChild(this.tabBtnFile),E.appendChild(this.tabBtnUrl),this.addPanelEl.appendChild(E),this.tabPaneFile=s("div",{className:"horeg-tab-pane active"}),this.fileInputEl=s("input",{attributes:{type:"file",accept:"audio/*",multiple:"true",style:"display: none;"}}),this.dropzoneEl=s("div",{className:"horeg-dropzone"}),this.dropzoneEl.innerHTML=`
|
|
1208
|
+
`}function T(d){if(isNaN(d)||!isFinite(d)||d<0)return"00:00";const e=Math.floor(d),r=Math.floor(e/3600),t=Math.floor(e%3600/60),o=e%60,n=a=>a.toString().padStart(2,"0");return r>0?`${r}:${n(t)}:${n(o)}`:`${n(t)}:${n(o)}`}function m(d,e,r){return Math.min(Math.max(d,e),r)}class j{constructor(e,r={}){i(this,"audio");i(this,"playlist",[]);i(this,"currentIndex",0);i(this,"loopMode","all");i(this,"shuffleMode",!1);i(this,"volumeLevel",.8);i(this,"previousVolume",.8);i(this,"callbacks",{});i(this,"audioContext",null);i(this,"analyser",null);i(this,"sourceNode",null);i(this,"freqData",null);i(this,"webAudioInitialized",!1);i(this,"bassRollingAvg",.2);i(this,"bassPulseEnvelope",0);i(this,"handlePlay",()=>{const e=this.getCurrentTrack();e&&this.callbacks.onPlay&&this.callbacks.onPlay(e)});i(this,"handlePause",()=>{this.callbacks.onPause&&this.callbacks.onPause()});i(this,"handleTimeUpdate",()=>{if(this.audio.seeking)return;const e=this.audio.currentTime||0,r=this.getDuration();this.callbacks.onTimeUpdate&&this.callbacks.onTimeUpdate(e,r)});i(this,"handleSeeked",()=>{const e=this.audio.currentTime||0,r=this.getDuration();this.callbacks.onTimeUpdate&&this.callbacks.onTimeUpdate(e,r)});i(this,"handleProgress",()=>{if(this.audio.buffered.length>0&&this.audio.duration>0){const e=this.audio.buffered.end(this.audio.buffered.length-1),r=this.audio.duration,t=m(e/r*100,0,100);this.callbacks.onBufferUpdate&&this.callbacks.onBufferUpdate(t)}});i(this,"handleWaiting",()=>{this.callbacks.onLoadingChange&&this.callbacks.onLoadingChange(!0)});i(this,"handlePlaying",()=>{this.callbacks.onLoadingChange&&this.callbacks.onLoadingChange(!1)});i(this,"handleLoadedMetadata",()=>{const e=this.getDuration();this.callbacks.onTimeUpdate&&this.callbacks.onTimeUpdate(this.audio.currentTime||0,e)});i(this,"handleEnded",()=>{const e=this.getCurrentTrack();e&&this.callbacks.onEnded&&this.callbacks.onEnded(e),this.loopMode==="one"?(this.audio.currentTime=0,this.play()):this.next(!0)});i(this,"handleError",()=>{const e=this.audio.error||new Error("Unknown audio playback error");this.callbacks.onError&&this.callbacks.onError(e)});this.audio=new Audio,this.audio.crossOrigin="anonymous",this.playlist=[...e.playlist||[]],this.currentIndex=e.initialIndex!==void 0?m(e.initialIndex,0,Math.max(0,this.playlist.length-1)):0,this.loopMode=e.loop||"all",this.shuffleMode=!!e.shuffle,this.volumeLevel=e.volume!==void 0?m(e.volume,0,1):.8,this.callbacks=r||{onPlay:e.onPlay,onPause:e.onPause,onTrackChange:e.onTrackChange,onPlaylistChange:e.onPlaylistChange,onTimeUpdate:e.onTimeUpdate,onEnded:e.onEnded,onError:e.onError},this.audio.volume=this.volumeLevel,this.attachEvents(),this.playlist.length>0&&this.loadTrack(this.currentIndex,!!e.autoplay)}attachEvents(){this.audio.addEventListener("play",this.handlePlay),this.audio.addEventListener("pause",this.handlePause),this.audio.addEventListener("timeupdate",this.handleTimeUpdate),this.audio.addEventListener("progress",this.handleProgress),this.audio.addEventListener("ended",this.handleEnded),this.audio.addEventListener("error",this.handleError),this.audio.addEventListener("waiting",this.handleWaiting),this.audio.addEventListener("playing",this.handlePlaying),this.audio.addEventListener("loadedmetadata",this.handleLoadedMetadata),this.audio.addEventListener("seeked",this.handleSeeked)}detachEvents(){this.audio.removeEventListener("play",this.handlePlay),this.audio.removeEventListener("pause",this.handlePause),this.audio.removeEventListener("timeupdate",this.handleTimeUpdate),this.audio.removeEventListener("progress",this.handleProgress),this.audio.removeEventListener("ended",this.handleEnded),this.audio.removeEventListener("error",this.handleError),this.audio.removeEventListener("waiting",this.handleWaiting),this.audio.removeEventListener("playing",this.handlePlaying),this.audio.removeEventListener("loadedmetadata",this.handleLoadedMetadata),this.audio.removeEventListener("seeked",this.handleSeeked)}getCurrentTrack(){return this.playlist[this.currentIndex]}getCurrentIndex(){return this.currentIndex}getPlaylist(){return this.playlist}setPlaylist(e,r=0){this.playlist=[...e],this.currentIndex=m(r,0,Math.max(0,this.playlist.length-1)),this.loadTrack(this.currentIndex,!1),this.callbacks.onPlaylistChange&&this.callbacks.onPlaylistChange([...this.playlist],this.currentIndex),this.playlist.length>0?this.loadTrack(this.currentIndex,!1):(this.audio.pause(),this.audio.src="",this.callbacks.onTrackChange&&this.callbacks.onTrackChange({title:"No Track Loaded",src:""},0))}addTrack(e,r=!1){const t=this.playlist.length===0;this.playlist.push(e);const o=this.playlist.length-1;return this.callbacks.onPlaylistChange&&this.callbacks.onPlaylistChange([...this.playlist],this.currentIndex),t?this.loadTrack(0,r):r&&this.loadTrack(o,!0),o}addTracks(e,r=!1){if(!e||e.length===0)return;const t=this.playlist.length===0,o=this.playlist.length;this.playlist.push(...e),this.callbacks.onPlaylistChange&&this.callbacks.onPlaylistChange([...this.playlist],this.currentIndex),t?this.loadTrack(0,r):r&&this.loadTrack(o,!0)}removeTrack(e){if(e<0||e>=this.playlist.length)return;const r=e===this.currentIndex;if(this.playlist.splice(e,1),this.playlist.length===0)this.currentIndex=0,this.audio.pause(),this.audio.src="",this.callbacks.onTrackChange&&this.callbacks.onTrackChange({title:"No Track Loaded",src:""},0);else if(r){const t=m(e,0,this.playlist.length-1);this.loadTrack(t,!1)}else e<this.currentIndex&&this.currentIndex--;this.callbacks.onPlaylistChange&&this.callbacks.onPlaylistChange([...this.playlist],this.currentIndex)}getDuration(){const e=this.audio.duration;if(e&&!isNaN(e)&&isFinite(e))return e;const r=this.getCurrentTrack();return(r==null?void 0:r.duration)||0}getCurrentTime(){return this.audio.currentTime||0}isPlaying(){return!this.audio.paused&&!this.audio.ended}isMuted(){return this.audio.muted||this.audio.volume===0}getVolume(){return this.audio.volume}getLoop(){return this.loopMode}isShuffle(){return this.shuffleMode}loadTrack(e,r=!1){let t;typeof e=="number"?t=m(e,0,Math.max(0,this.playlist.length-1)):(t=this.playlist.findIndex(n=>n.src===e.src),t===-1&&(this.playlist.push(e),t=this.playlist.length-1)),this.currentIndex=t;const o=this.playlist[this.currentIndex];o&&(this.audio.src=o.src,this.callbacks.onTrackChange&&this.callbacks.onTrackChange(o,this.currentIndex),r&&this.play())}async play(){this.initWebAudio();try{await this.audio.play()}catch(e){console.warn("[HoregAudio] Autoplay / Audio play was prevented by browser policy:",e)}}initWebAudio(){if(this.webAudioInitialized){this.audioContext&&this.audioContext.state==="suspended"&&this.audioContext.resume().catch(()=>{});return}try{const e=window.AudioContext||window.webkitAudioContext;if(!e)return;this.audioContext=new e,this.analyser=this.audioContext.createAnalyser(),this.analyser.fftSize=128,this.analyser.smoothingTimeConstant=.65,this.sourceNode=this.audioContext.createMediaElementSource(this.audio),this.sourceNode.connect(this.analyser),this.analyser.connect(this.audioContext.destination),this.freqData=new Uint8Array(this.analyser.frequencyBinCount),this.webAudioInitialized=!0}catch{this.webAudioInitialized=!0}}getAudioEnergy(){if(!this.isPlaying())return{bass:0,midHigh:0,left:0,right:0};const e=this.isMuted()?0:Math.max(.35,Math.sqrt(this.volumeLevel));if(this.analyser&&this.freqData&&this.audioContext&&this.audioContext.state==="running")try{this.analyser.getByteFrequencyData(this.freqData);let r=0;const t=Math.min(4,this.freqData.length);for(let f=0;f<t;f++)r+=this.freqData[f];let o=0;const n=Math.min(16,this.freqData.length);for(let f=t;f<n;f++)o+=this.freqData[f];const a=r/(t*255),l=o/((n-t)*255);if(a<.025&&l<.025)return this.bassPulseEnvelope*=.5,this.bassPulseEnvelope<.01&&(this.bassPulseEnvelope=0),{bass:0,midHigh:0,left:0,right:0};const h=Math.max(a,l*.7),g=a*.75;this.bassRollingAvg=this.bassRollingAvg*.92+a*.08;const p=Math.max(0,a-this.bassRollingAvg),b=p>.006?Math.min(1,p*4.5+.3+a*.35):0,u=this.audio.currentTime>0?this.audio.currentTime:Date.now()/1e3,v=(Math.sin(u*13)*.5+.5)*.08*Math.min(1,h*2.5),x=.09*Math.min(1,h*3)+v,k=Math.max(b,g,x);this.bassPulseEnvelope=Math.max(k,this.bassPulseEnvelope*.82);const y=Math.min(1,this.bassPulseEnvelope)*e,w=Math.min(1,l*1.3)*e;return{bass:y,midHigh:w,left:w*.9,right:w*.95}}catch{}if(!this.analyser||!this.audioContext||this.audioContext.state!=="running"){const r=this.audio.currentTime>0?this.audio.currentTime:Date.now()/1e3,o=60/130,n=r%o/o,a=Math.pow(Math.max(0,1-n*2.2),3.2),l=m(Math.max(.12,a),0,1)*e,h=m(Math.sin(r*8)*.25+.35+a*.25,0,1)*e;return{bass:l,midHigh:h,left:h*.85,right:h*.9}}return{bass:0,midHigh:0,left:0,right:0}}pause(){this.audio.pause()}toggle(){this.audio.paused?this.play():this.pause()}seek(e){const r=this.getDuration();this.audio.currentTime=m(e,0,r||0)}setVolume(e){this.volumeLevel=m(e,0,1),this.audio.volume=this.volumeLevel,this.volumeLevel>0&&(this.audio.muted=!1)}toggleMute(){return this.isMuted()?(this.audio.muted=!1,this.audio.volume=this.previousVolume||.8,this.volumeLevel=this.previousVolume||.8,!1):(this.previousVolume=this.volumeLevel,this.audio.muted=!0,!0)}next(e=!1){if(this.playlist.length===0)return;if(this.loopMode==="one"){this.seek(0),this.play();return}if(this.shuffleMode&&this.playlist.length>1){let t;do t=Math.floor(Math.random()*this.playlist.length);while(t===this.currentIndex);this.loadTrack(t,!0);return}const r=this.currentIndex+1;r<this.playlist.length?this.loadTrack(r,!0):this.loopMode==="all"?this.loadTrack(0,!0):e?this.pause():this.loadTrack(0,!0)}prev(){if(this.playlist.length===0)return;if(this.audio.currentTime>3){this.seek(0);return}if(this.loopMode==="one"){this.seek(0),this.play();return}if(this.shuffleMode&&this.playlist.length>1){let r;do r=Math.floor(Math.random()*this.playlist.length);while(r===this.currentIndex);this.loadTrack(r,!0);return}const e=this.currentIndex-1;e>=0?this.loadTrack(e,!0):this.loopMode==="all"?this.loadTrack(this.playlist.length-1,!0):this.seek(0)}setLoop(e){this.loopMode=e}setShuffle(e){this.shuffleMode=e}setCallbacks(e){this.callbacks={...this.callbacks,...e}}destroy(){this.detachEvents(),this.audio.pause(),this.audio.src="",this.audio.load(),this.audioContext&&this.audioContext.state!=="closed"&&this.audioContext.close().catch(()=>{})}}const c={play:'<svg viewBox="0 0 24 24" fill="currentColor" width="20" height="20"><path d="M8 5v14l11-7z"/></svg>',pause:'<svg viewBox="0 0 24 24" fill="currentColor" width="20" height="20"><path d="M6 19h4V5H6v14zm8-14v14h4V5h-4z"/></svg>',prev:'<svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18"><path d="M6 6h2v12H6zm3.5 6l8.5 6V6z"/></svg>',next:'<svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18"><path d="M6 18l8.5-6L6 6v12zM16 6v12h2V6h-2z"/></svg>',volumeHigh:'<svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18"><path d="M3 9v6h4l5 5V4L7 9H3zm13.5 3c0-1.77-1.02-3.29-2.5-4.03v8.05c1.48-.73 2.5-2.25 2.5-4.02zM14 3.23v2.06c2.89.86 5 3.54 5 6.71s-2.11 5.85-5 6.71v2.06c4.01-.91 7-4.49 7-8.77s-2.99-7.86-7-8.77z"/></svg>',volumeMute:'<svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18"><path d="M16.5 12c0-1.77-1.02-3.29-2.5-4.03v2.21l2.45 2.45c.03-.2.05-.41.05-.63zm2.5 0c0 .94-.2 1.82-.54 2.64l1.51 1.51C20.63 14.91 21 13.5 21 12c0-4.28-2.99-7.86-7-8.77v2.06c2.89.86 5 3.54 5 6.71zM4.27 3L3 4.27l4.73 4.73H3v6h4l5 5v-6.73l4.25 4.25c-.67.52-1.42.93-2.25 1.18v2.06c1.38-.31 2.63-.95 3.69-1.81L19.73 21 21 19.73l-9-9L4.27 3zM12 4L9.91 6.09 12 8.18V4z"/></svg>',shuffle:'<svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16"><path d="M10.59 9.17L5.41 4 4 5.41l5.17 5.17 1.42-1.41zM14.5 4l2.04 2.04L4 18.59 5.41 20 17.96 7.46 20 9.5V4h-5.5zm.33 9.41l-1.41 1.41 3.13 3.13L14.5 20H20v-5.5l-2.04 2.04-3.13-3.13z"/></svg>',repeat:'<svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16"><path d="M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4z"/></svg>',repeatOne:'<svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16"><path d="M7 7h10v3l4-4-4-4v3H5v6h2V7zm10 10H7v-3l-4 4 4 4v-3h12v-6h-2v4zm-4-2V9h-1l-2 1v1h1.5v4H13z"/></svg>',playlist:'<svg viewBox="0 0 24 24" fill="currentColor" width="18" height="18"><path d="M3 10h11v2H3zm0-4h11v2H3zm0 8h7v2H3zm13-1v8l6-4-6-4z"/></svg>',speaker:'<svg viewBox="0 0 24 24" fill="currentColor" width="32" height="32"><path d="M17 2H7c-1.1 0-2 .9-2 2v16c0 1.1.9 1.99 2 1.99L17 22c1.1 0 2-.9 2-2V4c0-1.1-.9-2-2-2zm-5 2c1.1 0 2 .9 2 2s-.9 2-2 2-2-.9-2-2 .9-2 2-2zm0 16c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5zm0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3z"/></svg>',plus:'<svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/></svg>',trash:'<svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg>',upload:'<svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M9 16h6v-6h4l-7-7-7 7h4zm-4 2h14v2H5z"/></svg>',link:'<svg viewBox="0 0 24 24" fill="currentColor" width="14" height="14"><path d="M3.9 12c0-1.71 1.39-3.1 3.1-3.1h4V7H7c-2.76 0-5 2.24-5 5s2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1zM8 13h8v-2H8v2zm9-6h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1s-1.39 3.1-3.1 3.1h-4V17h4c2.76 0 5-2.24 5-5s-2.24-5-5-5z"/></svg>'};function s(d,e){const r=document.createElement(d);if(e!=null&&e.className&&(r.className=e.className),e!=null&&e.attributes)for(const[t,o]of Object.entries(e.attributes))r.setAttribute(t,o);return e!=null&&e.innerHTML?r.innerHTML=e.innerHTML:e!=null&&e.textContent&&(r.textContent=e.textContent),r}class W{constructor(e){i(this,"root");i(this,"stageContainer");i(this,"eqContainer");i(this,"coverContainer");i(this,"titleWrap");i(this,"playBtn");i(this,"prevBtn");i(this,"nextBtn");i(this,"shuffleBtn");i(this,"loopBtn");i(this,"muteBtn");i(this,"drawerBtn");i(this,"titleEl");i(this,"artistEl");i(this,"albumEl");i(this,"coverImgEl",null);i(this,"currentTimeEl");i(this,"durationEl");i(this,"sliderTrack");i(this,"fillBar");i(this,"bufferBar");i(this,"volumeSlider");i(this,"drawerEl");i(this,"drawerCountEl");i(this,"addTrackBtn");i(this,"addPanelEl");i(this,"fileInputEl");i(this,"tabBtnFile");i(this,"tabBtnUrl");i(this,"tabPaneFile");i(this,"tabPaneUrl");i(this,"urlInput");i(this,"titleInput");i(this,"artistInput");i(this,"submitUrlBtn");i(this,"cancelAddBtn");i(this,"dropzoneEl");i(this,"drawerInner");i(this,"isScrubbing",!1);i(this,"currentDuration",0);i(this,"events");i(this,"startScrubbing",e=>{e.preventDefault(),this.isScrubbing=!0,document.body.style.userSelect="none",this.handleScrubbingMove(e);const r=o=>{this.isScrubbing&&this.handleScrubbingMove(o)},t=o=>{this.isScrubbing&&(this.finishScrubbing(o),window.removeEventListener("mousemove",r),window.removeEventListener("mouseup",t),window.removeEventListener("touchmove",r),window.removeEventListener("touchend",t))};window.addEventListener("mousemove",r),window.addEventListener("mouseup",t),window.addEventListener("touchmove",r,{passive:!1}),window.addEventListener("touchend",t)});this.events=e,this.root=s("div",{className:"horeg-player-box"});const r=s("div",{className:"horeg-speaker-grill"});this.root.appendChild(r),["top-left","top-right","bottom-left","bottom-right"].forEach(f=>{this.root.appendChild(s("div",{className:`horeg-bolt ${f}`}))});const t=s("div",{className:"horeg-content-wrap"});this.root.appendChild(t);const o=s("div",{className:"horeg-header"}),n=s("div",{className:"horeg-rig-badge",innerHTML:'<span class="horeg-badge-led"></span> SOUND HOREG • HIGH VOLTAGE'});o.appendChild(n),t.appendChild(o),this.stageContainer=s("div",{className:"horeg-soundbox-stage"}),this.eqContainer=this.stageContainer,this.coverContainer=s("div",{className:"horeg-sub-cover-wrap"}),this.coverContainer.innerHTML=`<span class="horeg-cover-fallback">${c.speaker}</span>`;const a=s("div",{className:"horeg-track-meta"});this.titleWrap=s("div",{className:"horeg-title-wrap"}),this.titleEl=s("div",{className:"horeg-track-title",textContent:"No Track Loaded"}),this.titleWrap.appendChild(this.titleEl),this.artistEl=s("div",{className:"horeg-track-artist",textContent:"Unknown Artist"}),this.albumEl=s("div",{className:"horeg-track-album",textContent:""}),a.appendChild(this.titleWrap),a.appendChild(this.artistEl),a.appendChild(this.albumEl),t.appendChild(this.stageContainer),t.appendChild(a);const l=s("div",{className:"horeg-progress-container"}),h=s("div",{className:"horeg-time-row"});this.currentTimeEl=s("span",{textContent:"00:00"}),this.durationEl=s("span",{textContent:"00:00"}),h.appendChild(this.currentTimeEl),h.appendChild(this.durationEl),l.appendChild(h),this.sliderTrack=s("div",{className:"horeg-slider-track",attributes:{role:"slider","aria-label":"Seek progress","aria-valuemin":"0","aria-valuemax":"100","aria-valuenow":"0",tabindex:"0"}}),this.bufferBar=s("div",{className:"horeg-buffer-bar"}),this.fillBar=s("div",{className:"horeg-fill-bar"}),this.sliderTrack.appendChild(this.bufferBar),this.sliderTrack.appendChild(this.fillBar),l.appendChild(this.sliderTrack),t.appendChild(l);const g=s("div",{className:"horeg-controls-row"}),p=s("div",{className:"horeg-side-controls"});this.shuffleBtn=s("button",{className:"horeg-btn",attributes:{"aria-label":"Toggle shuffle",type:"button"},innerHTML:c.shuffle}),this.loopBtn=s("button",{className:"horeg-btn active",attributes:{"aria-label":"Toggle loop mode",type:"button"},innerHTML:c.repeat}),p.appendChild(this.shuffleBtn),p.appendChild(this.loopBtn),g.appendChild(p);const b=s("div",{className:"horeg-center-controls"});this.prevBtn=s("button",{className:"horeg-btn",attributes:{"aria-label":"Previous track",type:"button"},innerHTML:c.prev}),this.playBtn=s("button",{className:"horeg-btn horeg-btn-play",attributes:{"aria-label":"Play track",type:"button"},innerHTML:c.play}),this.nextBtn=s("button",{className:"horeg-btn",attributes:{"aria-label":"Next track",type:"button"},innerHTML:c.next}),b.appendChild(this.prevBtn),b.appendChild(this.playBtn),b.appendChild(this.nextBtn),g.appendChild(b);const u=s("div",{className:"horeg-side-controls"}),v=s("div",{className:"horeg-volume-wrap"});this.muteBtn=s("button",{className:"horeg-btn",attributes:{"aria-label":"Toggle mute",type:"button"},innerHTML:c.volumeHigh}),this.volumeSlider=s("input",{className:"horeg-volume-slider",attributes:{type:"range",min:"0",max:"1",step:"0.01",value:"0.8","aria-label":"Volume control"}}),v.appendChild(this.muteBtn),v.appendChild(this.volumeSlider),u.appendChild(v),this.drawerBtn=s("button",{className:"horeg-btn",attributes:{"aria-label":"Toggle playlist drawer",type:"button"},innerHTML:c.playlist}),u.appendChild(this.drawerBtn),g.appendChild(u),t.appendChild(g),this.drawerEl=s("div",{className:"horeg-drawer"});const x=s("div",{className:"horeg-drawer-header"}),k=s("div",{className:"horeg-drawer-heading"});k.innerHTML="<span>PLAYLIST</span>",this.drawerCountEl=s("span",{className:"horeg-drawer-count",textContent:"0"}),k.appendChild(this.drawerCountEl),x.appendChild(k),this.addTrackBtn=s("button",{className:"horeg-btn-add-track",attributes:{type:"button","aria-label":"Add track to playlist"},innerHTML:`${c.plus} <span>Add Track</span>`}),x.appendChild(this.addTrackBtn),this.drawerEl.appendChild(x),this.addPanelEl=s("div",{className:"horeg-add-panel"});const y=s("div",{className:"horeg-add-tabs"});this.tabBtnFile=s("button",{className:"horeg-tab-btn active",attributes:{type:"button"},innerHTML:`${c.upload} <span>File Lokal</span>`}),this.tabBtnUrl=s("button",{className:"horeg-tab-btn",attributes:{type:"button"},innerHTML:`${c.link} <span>Audio URL</span>`}),y.appendChild(this.tabBtnFile),y.appendChild(this.tabBtnUrl),this.addPanelEl.appendChild(y),this.tabPaneFile=s("div",{className:"horeg-tab-pane active"}),this.fileInputEl=s("input",{attributes:{type:"file",accept:"audio/*",multiple:"true",style:"display: none;"}}),this.dropzoneEl=s("div",{className:"horeg-dropzone"}),this.dropzoneEl.innerHTML=`
|
|
874
1209
|
<div class="horeg-dropzone-icon">${c.upload}</div>
|
|
875
1210
|
<div class="horeg-dropzone-text">Pilih File Audio Komputer</div>
|
|
876
1211
|
<div class="horeg-dropzone-hint">Klik di sini atau drag & drop file (.mp3, .wav, .flac, .ogg, .m4a)</div>
|
|
877
|
-
`,this.tabPaneFile.appendChild(this.fileInputEl),this.tabPaneFile.appendChild(this.dropzoneEl),this.addPanelEl.appendChild(this.tabPaneFile),this.tabPaneUrl=s("div",{className:"horeg-tab-pane"}),this.urlInput=s("input",{className:"horeg-input-field",attributes:{type:"url",placeholder:"Audio URL (https://...mp3/wav)",required:"true"}}),this.titleInput=s("input",{className:"horeg-input-field",attributes:{type:"text",placeholder:"Judul Lagu (Opsional)"}}),this.artistInput=s("input",{className:"horeg-input-field",attributes:{type:"text",placeholder:"Nama Artis (Opsional)"}});const C=s("div",{className:"horeg-form-actions"});this.cancelAddBtn=s("button",{className:"horeg-btn-cancel",attributes:{type:"button"},textContent:"Batal"}),this.submitUrlBtn=s("button",{className:"horeg-btn-submit",attributes:{type:"button"},innerHTML:`${c.plus} Tambah`}),C.appendChild(this.cancelAddBtn),C.appendChild(this.submitUrlBtn),this.tabPaneUrl.appendChild(this.urlInput),this.tabPaneUrl.appendChild(this.titleInput),this.tabPaneUrl.appendChild(this.artistInput),this.tabPaneUrl.appendChild(C),this.addPanelEl.appendChild(this.tabPaneUrl),this.drawerEl.appendChild(this.addPanelEl),this.drawerInner=s("div",{className:"horeg-drawer-inner"}),this.drawerEl.appendChild(this.drawerInner),this.root.appendChild(this.drawerEl),this.bindDOMEvents()}bindDOMEvents(){this.playBtn.addEventListener("click",()=>this.events.onPlayPauseClick()),this.prevBtn.addEventListener("click",()=>this.events.onPrevClick()),this.nextBtn.addEventListener("click",()=>this.events.onNextClick()),this.shuffleBtn.addEventListener("click",()=>this.events.onShuffleToggle()),this.loopBtn.addEventListener("click",()=>this.events.onLoopToggle()),this.muteBtn.addEventListener("click",()=>this.events.onMuteToggle()),this.volumeSlider.addEventListener("input",()=>{this.events.onVolumeChange(parseFloat(this.volumeSlider.value))}),this.drawerBtn.addEventListener("click",()=>{this.toggleDrawer()}),this.addTrackBtn.addEventListener("click",()=>{const r=this.addPanelEl.classList.toggle("open");this.addTrackBtn.classList.toggle("active",r),r&&this.toggleDrawer(!0)}),this.tabBtnFile.addEventListener("click",()=>{this.tabBtnFile.classList.add("active"),this.tabBtnUrl.classList.remove("active"),this.tabPaneFile.classList.add("active"),this.tabPaneUrl.classList.remove("active")}),this.tabBtnUrl.addEventListener("click",()=>{this.tabBtnUrl.classList.add("active"),this.tabBtnFile.classList.remove("active"),this.tabPaneUrl.classList.add("active"),this.tabPaneFile.classList.remove("active"),this.urlInput.focus()}),this.dropzoneEl.addEventListener("click",()=>{this.fileInputEl.click()}),this.fileInputEl.addEventListener("change",()=>{if(this.fileInputEl.files&&this.fileInputEl.files.length>0){const r=Array.from(this.fileInputEl.files);this.events.onAddTrackFiles&&this.events.onAddTrackFiles(r),this.fileInputEl.value="",this.closeAddPanel()}}),this.dropzoneEl.addEventListener("dragover",r=>{r.preventDefault(),this.dropzoneEl.classList.add("drag-active")}),this.dropzoneEl.addEventListener("dragleave",()=>{this.dropzoneEl.classList.remove("drag-active")}),this.dropzoneEl.addEventListener("drop",r=>{var i;if(r.preventDefault(),this.dropzoneEl.classList.remove("drag-active"),(i=r.dataTransfer)!=null&&i.files&&r.dataTransfer.files.length>0){const n=Array.from(r.dataTransfer.files).filter(a=>a.type.startsWith("audio/")||/\.(mp3|wav|ogg|flac|m4a|aac)$/i.test(a.name));n.length>0&&this.events.onAddTrackFiles&&(this.events.onAddTrackFiles(n),this.closeAddPanel())}}),this.root.addEventListener("dragover",r=>{r.preventDefault(),this.root.classList.add("drag-over")}),this.root.addEventListener("dragleave",r=>{this.root.contains(r.relatedTarget)||this.root.classList.remove("drag-over")}),this.root.addEventListener("drop",r=>{var i;if(r.preventDefault(),this.root.classList.remove("drag-over"),(i=r.dataTransfer)!=null&&i.files&&r.dataTransfer.files.length>0){const n=Array.from(r.dataTransfer.files).filter(a=>a.type.startsWith("audio/")||/\.(mp3|wav|ogg|flac|m4a|aac)$/i.test(a.name));n.length>0&&this.events.onAddTrackFiles&&(this.events.onAddTrackFiles(n),this.closeAddPanel())}});const e=()=>{const r=this.urlInput.value.trim();if(!r){this.urlInput.focus();return}const i=this.titleInput.value.trim(),n=this.artistInput.value.trim();this.events.onAddTrackUrl&&this.events.onAddTrackUrl(r,i||void 0,n||void 0),this.urlInput.value="",this.titleInput.value="",this.artistInput.value="",this.closeAddPanel()};this.submitUrlBtn.addEventListener("click",e);const t=r=>{r.stopPropagation(),r.key==="Enter"&&(r.preventDefault(),e())};this.urlInput.addEventListener("keydown",t),this.titleInput.addEventListener("keydown",t),this.artistInput.addEventListener("keydown",t),this.cancelAddBtn.addEventListener("click",()=>{this.closeAddPanel()}),this.sliderTrack.addEventListener("mousedown",this.startScrubbing),this.sliderTrack.addEventListener("touchstart",this.startScrubbing,{passive:!1}),this.sliderTrack.addEventListener("keydown",r=>{if(this.currentDuration){if(r.key==="ArrowRight"||r.key==="ArrowUp"){r.preventDefault();const i=parseFloat(this.fillBar.style.width)/100*this.currentDuration;this.events.onSeek(Math.min(i+5,this.currentDuration))}else if(r.key==="ArrowLeft"||r.key==="ArrowDown"){r.preventDefault();const i=parseFloat(this.fillBar.style.width)/100*this.currentDuration;this.events.onSeek(Math.max(i-5,0))}}})}calculateProgressPercent(e){var n,a,l,d;const t=this.sliderTrack.getBoundingClientRect(),r="touches"in e?((a=(n=e.touches)==null?void 0:n[0])==null?void 0:a.clientX)??((d=(l=e.changedTouches)==null?void 0:l[0])==null?void 0:d.clientX)??0:e.clientX,i=u(r-t.left,0,t.width);return t.width>0?i/t.width*100:0}handleScrubbingMove(e){const t=this.calculateProgressPercent(e);if(this.fillBar.style.width=`${t}%`,this.sliderTrack.setAttribute("aria-valuenow",Math.round(t).toString()),this.currentDuration>0){const r=t/100*this.currentDuration;this.currentTimeEl.textContent=T(r)}}finishScrubbing(e){const t=this.calculateProgressPercent(e);if(this.fillBar.style.width=`${t}%`,this.sliderTrack.setAttribute("aria-valuenow",Math.round(t).toString()),this.currentDuration>0){const r=t/100*this.currentDuration;this.currentTimeEl.textContent=T(r),this.events.onSeek(r)}this.isScrubbing=!1,document.body.style.userSelect=""}updateTrackInfo(e){this.titleEl.textContent=e.title||"Untitled Track",this.artistEl.textContent=e.artist||"Unknown Artist",this.albumEl.textContent=e.album||"",e.coverArt?(this.coverContainer.innerHTML="",this.coverImgEl=s("img",{className:"horeg-cover-img",attributes:{src:e.coverArt,alt:`${e.title} cover`}}),this.coverImgEl.onerror=()=>{this.coverContainer.innerHTML=`<span class="horeg-cover-fallback">${c.speaker}</span>`},this.coverContainer.appendChild(this.coverImgEl)):this.coverContainer.innerHTML=`<span class="horeg-cover-fallback">${c.speaker}</span>`}updatePlayState(e){e?(this.playBtn.classList.add("playing"),this.playBtn.innerHTML=c.pause,this.playBtn.setAttribute("aria-label","Pause track")):(this.playBtn.classList.remove("playing"),this.playBtn.innerHTML=c.play,this.playBtn.setAttribute("aria-label","Play track"))}updateProgress(e,t){if(this.currentDuration=t,this.durationEl.textContent=T(t),!this.isScrubbing){this.currentTimeEl.textContent=T(e);const r=t>0?e/t*100:0;this.fillBar.style.width=`${u(r,0,100)}%`,this.sliderTrack.setAttribute("aria-valuenow",Math.round(r).toString())}}updateBuffer(e){this.bufferBar.style.width=`${u(e,0,100)}%`}updateVolume(e,t){this.volumeSlider.value=e.toString(),t||e===0?(this.muteBtn.innerHTML=c.volumeMute,this.muteBtn.setAttribute("aria-label","Unmute")):(this.muteBtn.innerHTML=c.volumeHigh,this.muteBtn.setAttribute("aria-label","Mute"))}updateLoopState(e){e==="none"?(this.loopBtn.classList.remove("active"),this.loopBtn.innerHTML=c.repeat):e==="all"?(this.loopBtn.classList.add("active"),this.loopBtn.innerHTML=c.repeat):e==="one"&&(this.loopBtn.classList.add("active"),this.loopBtn.innerHTML=c.repeatOne),this.loopBtn.setAttribute("aria-label",`Repeat mode: ${e}`)}updateShuffleState(e){e?this.shuffleBtn.classList.add("active"):this.shuffleBtn.classList.remove("active")}toggleDrawer(e){(e!==void 0?e:!this.drawerEl.classList.contains("open"))?(this.drawerEl.classList.add("open"),this.drawerBtn.classList.add("active")):(this.drawerEl.classList.remove("open"),this.drawerBtn.classList.remove("active"),this.closeAddPanel())}closeAddPanel(){this.addPanelEl.classList.remove("open"),this.addTrackBtn.classList.remove("active")}renderPlaylist(e,t){if(this.drawerCountEl.textContent=e.length.toString(),this.drawerInner.innerHTML="",e.length===0){const r=s("div",{className:"horeg-empty-playlist",textContent:'Playlist masih kosong. Klik "Add Track" untuk menambahkan lagu.'});this.drawerInner.appendChild(r);return}e.forEach((r,i)=>{const n=s("div",{className:`horeg-track-item ${i===t?"active":""}`}),a=s("div",{className:"horeg-track-num",textContent:(i+1).toString().padStart(2,"0")});n.appendChild(a);const l=s("div",{className:"horeg-track-details"}),d=s("div",{className:"horeg-item-title",textContent:r.title}),p=s("div",{className:"horeg-item-artist",textContent:r.artist||"Unknown Artist"});if(l.appendChild(d),l.appendChild(p),n.appendChild(l),r.duration){const b=s("div",{className:"horeg-item-duration",textContent:T(r.duration)});n.appendChild(b)}const g=s("div",{className:"horeg-track-actions"}),f=s("button",{className:"horeg-btn-remove",attributes:{type:"button","aria-label":"Hapus lagu dari playlist"},innerHTML:c.trash});f.addEventListener("click",b=>{b.stopPropagation(),this.events.onRemoveTrack&&this.events.onRemoveTrack(i)}),g.appendChild(f),n.appendChild(g),n.addEventListener("click",()=>{this.events.onTrackSelect(i)}),this.drawerInner.appendChild(n)})}destroy(){this.root.remove()}}class G{constructor(e){o(this,"container");o(this,"bars",[]);o(this,"isRunning",!1);o(this,"animFrameId",null);o(this,"isEnabled",!0);o(this,"baseHeights",[]);o(this,"loop",()=>{if(!this.isRunning)return;const e=Date.now()/150;for(let t=0;t<this.bars.length;t++){const r=Math.sin(e*1.8+t*1.2),i=Math.cos(e*2.5+t*.8),n=Math.abs(r*.6+i*.4),a=Math.floor(4+n*18);this.bars[t].style.height=`${a}px`}this.animFrameId=requestAnimationFrame(this.loop)});this.container=e.container,this.isEnabled=e.enableAnimation!==!1;const t=e.barCount||5;this.initBars(t)}initBars(e){this.container.innerHTML="",this.bars=[],this.baseHeights=[];for(let t=0;t<e;t++){const r=document.createElement("span");r.className="horeg-eq-bar",this.container.appendChild(r),this.bars.push(r),this.baseHeights.push(3+t%2*2),r.style.height=`${this.baseHeights[t]}px`}}setEnabled(e){this.isEnabled=e,e||this.stop()}start(){this.isRunning||!this.isEnabled||(this.isRunning=!0,this.loop())}stop(){this.isRunning=!1,this.animFrameId!==null&&(cancelAnimationFrame(this.animFrameId),this.animFrameId=null);for(let e=0;e<this.bars.length;e++)this.bars[e].style.height=`${this.baseHeights[e]||3}px`}destroy(){this.stop(),this.bars=[],this.container.innerHTML=""}}class m{constructor(e){o(this,"container");o(this,"shadow");o(this,"styleEl");o(this,"audioEngine");o(this,"ui");o(this,"visualizer");o(this,"theme");o(this,"boundKeyHandler");var n;if(typeof e.container=="string"){const a=document.querySelector(e.container);if(!a)throw new Error(`[HoregAudio] Container "${e.container}" not found in DOM.`);this.container=a}else if(e.container instanceof HTMLElement)this.container=e.container;else throw new Error("[HoregAudio] Invalid container option provided.");const t=((n=e.theme)==null?void 0:n.variant)||"horeg-classic",r=v[t]||v["horeg-classic"];this.theme={...r,...e.theme||{}},this.shadow=this.container.attachShadow({mode:"open"}),this.styleEl=document.createElement("style"),this.styleEl.textContent=L(this.theme),this.shadow.appendChild(this.styleEl),this.ui=new q({onPlayPauseClick:()=>this.toggle(),onPrevClick:()=>this.prev(),onNextClick:()=>this.next(),onSeek:a=>this.seek(a),onVolumeChange:a=>this.setVolume(a),onMuteToggle:()=>{const a=this.audioEngine.toggleMute();this.ui.updateVolume(this.audioEngine.getVolume(),a)},onShuffleToggle:()=>{const a=!this.audioEngine.isShuffle();this.audioEngine.setShuffle(a),this.ui.updateShuffleState(a)},onLoopToggle:()=>{const a=this.audioEngine.getLoop(),l=a==="all"?"one":a==="one"?"none":"all";this.audioEngine.setLoop(l),this.ui.updateLoopState(l)},onTrackSelect:a=>{this.loadTrack(a,!0)},onAddTrackFiles:a=>{this.addTrackFromFiles(a,!1)},onAddTrackUrl:(a,l,d)=>{this.addTrackFromUrl(a,{title:l,artist:d},!1)},onRemoveTrack:a=>{this.removeTrack(a)}}),this.shadow.appendChild(this.ui.root),this.visualizer=new G({container:this.ui.eqContainer,enableAnimation:this.theme.enableEqAnimation!==!1}),this.audioEngine=new j(e,{onPlay:a=>{this.ui.updatePlayState(!0),this.visualizer.start(),e.onPlay&&e.onPlay(a)},onPause:()=>{this.ui.updatePlayState(!1),this.visualizer.stop(),e.onPause&&e.onPause()},onTrackChange:(a,l)=>{this.ui.updateTrackInfo(a);const d=this.audioEngine?this.audioEngine.getPlaylist():e.playlist||[];this.ui.renderPlaylist(d,l),this.ui.updateProgress(0,a.duration||0),e.onTrackChange&&e.onTrackChange(a,l)},onPlaylistChange:(a,l)=>{this.ui.renderPlaylist(a,l),e.onPlaylistChange&&e.onPlaylistChange(a,l)},onTimeUpdate:(a,l)=>{this.ui.updateProgress(a,l),e.onTimeUpdate&&e.onTimeUpdate(a,l)},onBufferUpdate:a=>{this.ui.updateBuffer(a)},onEnded:a=>{this.visualizer.stop(),e.onEnded&&e.onEnded(a)},onError:a=>{this.ui.updatePlayState(!1),this.visualizer.stop(),e.onError&&e.onError(a)}}),this.ui.updateVolume(this.audioEngine.getVolume(),this.audioEngine.isMuted()),this.ui.updateLoopState(this.audioEngine.getLoop()),this.ui.updateShuffleState(this.audioEngine.isShuffle()),this.ui.renderPlaylist(this.audioEngine.getPlaylist(),this.audioEngine.getCurrentIndex());const i=this.audioEngine.getCurrentTrack();i&&(this.ui.updateTrackInfo(i),this.ui.renderPlaylist(this.audioEngine.getPlaylist(),this.audioEngine.getCurrentIndex())),this.boundKeyHandler=this.handleKeyDown.bind(this),this.container.tabIndex=this.container.tabIndex>=0?this.container.tabIndex:0,this.container.addEventListener("keydown",this.boundKeyHandler)}handleKeyDown(e){var a;const t=e.composedPath?e.composedPath():[],r=t.length>0?t[0]:e.target,i=((a=this.shadow)==null?void 0:a.activeElement)||document.activeElement,n=l=>{if(!l)return!1;const d=l.tagName;return d==="INPUT"||d==="TEXTAREA"||d==="SELECT"||l.isContentEditable};if(!(n(r)||n(i)))if(e.code==="Space"){if((r==null?void 0:r.tagName)==="BUTTON"||(i==null?void 0:i.tagName)==="BUTTON")return;e.preventDefault(),this.toggle()}else e.key==="ArrowRight"&&!e.shiftKey?(e.preventDefault(),this.seek(this.audioEngine.getCurrentTime()+5)):e.key==="ArrowLeft"&&!e.shiftKey?(e.preventDefault(),this.seek(this.audioEngine.getCurrentTime()-5)):e.key==="ArrowUp"?(e.preventDefault(),this.setVolume(this.audioEngine.getVolume()+.05)):e.key==="ArrowDown"&&(e.preventDefault(),this.setVolume(this.audioEngine.getVolume()-.05))}async play(){await this.audioEngine.play()}pause(){this.audioEngine.pause()}toggle(){this.audioEngine.toggle()}next(){this.audioEngine.next()}prev(){this.audioEngine.prev()}seek(e){this.audioEngine.seek(e)}setVolume(e){this.audioEngine.setVolume(e),this.ui.updateVolume(this.audioEngine.getVolume(),this.audioEngine.isMuted())}loadTrack(e,t=!1){this.audioEngine.loadTrack(e,t)}addTrack(e,t=!1){const r=this.audioEngine.addTrack(e,t);return this.ui.renderPlaylist(this.audioEngine.getPlaylist(),this.audioEngine.getCurrentIndex()),r}addTracks(e,t=!1){this.audioEngine.addTracks(e,t),this.ui.renderPlaylist(this.audioEngine.getPlaylist(),this.audioEngine.getCurrentIndex())}async addTrackFromFile(e,t=!1){const r=URL.createObjectURL(e),i=e.name.replace(/\.[^/.]+$/,""),n={id:`local-${Date.now()}-${Math.random().toString(36).substring(2,7)}`,title:i,artist:"File Audio Lokal",src:r};try{const a=await this.probeAudioDuration(r);a>0&&(n.duration=a)}catch{}return this.addTrack(n,t),n}async addTrackFromFiles(e,t=!1){const r=Array.from(e),i=[];for(let n=0;n<r.length;n++){const a=r[n],l=t&&n===0,d=await this.addTrackFromFile(a,l);i.push(d)}return i}async addTrackFromUrl(e,t={},r=!1){var a,l;let i="Online Track";try{const p=new URL(e).pathname,g=p.substring(p.lastIndexOf("/")+1);g&&(i=decodeURIComponent(g).replace(/\.[^/.]+$/,""))}catch{}const n={id:t.id||`url-${Date.now()}-${Math.random().toString(36).substring(2,7)}`,title:((a=t.title)==null?void 0:a.trim())||i,artist:((l=t.artist)==null?void 0:l.trim())||"Audio Stream",album:t.album,coverArt:t.coverArt,src:e,duration:t.duration};if(!n.duration)try{const d=await this.probeAudioDuration(e);d>0&&(n.duration=d)}catch{}return this.addTrack(n,r),n}removeTrack(e){this.audioEngine.removeTrack(e),this.ui.renderPlaylist(this.audioEngine.getPlaylist(),this.audioEngine.getCurrentIndex());const t=this.audioEngine.getCurrentTrack();t?this.ui.updateTrackInfo(t):this.ui.updateTrackInfo({title:"No Track Loaded",src:""})}getPlaylist(){return this.audioEngine.getPlaylist()}probeAudioDuration(e){return new Promise(t=>{const r=new Audio;let i=!1;const n=d=>{i||(i=!0,r.removeEventListener("loadedmetadata",a),r.removeEventListener("error",l),r.src="",t(d))},a=()=>{const d=r.duration;n(d&&!isNaN(d)&&isFinite(d)?d:0)},l=()=>n(0);r.addEventListener("loadedmetadata",a),r.addEventListener("error",l),r.src=e,setTimeout(()=>n(0),3e3)})}setTheme(e){if(e.variant){const t=v[e.variant]||v["horeg-classic"];this.theme={...t,...e}}else this.theme={...this.theme,...e};this.styleEl.textContent=L(this.theme),this.theme.enableEqAnimation!==void 0&&this.visualizer.setEnabled(this.theme.enableEqAnimation)}getTheme(){return{...this.theme}}getAudioEngine(){return this.audioEngine}destroy(){this.container.removeEventListener("keydown",this.boundKeyHandler),this.audioEngine.destroy(),this.visualizer.destroy(),this.ui.destroy(),this.shadow.innerHTML=""}}m.HoregAudio=m;m.default=m;m.THEME_PRESETS=v;m.generateStyles=L;exports.HoregAudio=m;exports.THEME_PRESETS=v;exports.default=m;exports.generateStyles=L;module.exports=Object.assign(exports.default||exports.HoregAudio,exports);
|
|
1212
|
+
`,this.tabPaneFile.appendChild(this.fileInputEl),this.tabPaneFile.appendChild(this.dropzoneEl),this.addPanelEl.appendChild(this.tabPaneFile),this.tabPaneUrl=s("div",{className:"horeg-tab-pane"}),this.urlInput=s("input",{className:"horeg-input-field",attributes:{type:"url",placeholder:"Audio URL (https://...mp3/wav)",required:"true"}}),this.titleInput=s("input",{className:"horeg-input-field",attributes:{type:"text",placeholder:"Judul Lagu (Opsional)"}}),this.artistInput=s("input",{className:"horeg-input-field",attributes:{type:"text",placeholder:"Nama Artis (Opsional)"}});const w=s("div",{className:"horeg-form-actions"});this.cancelAddBtn=s("button",{className:"horeg-btn-cancel",attributes:{type:"button"},textContent:"Batal"}),this.submitUrlBtn=s("button",{className:"horeg-btn-submit",attributes:{type:"button"},innerHTML:`${c.plus} Tambah`}),w.appendChild(this.cancelAddBtn),w.appendChild(this.submitUrlBtn),this.tabPaneUrl.appendChild(this.urlInput),this.tabPaneUrl.appendChild(this.titleInput),this.tabPaneUrl.appendChild(this.artistInput),this.tabPaneUrl.appendChild(w),this.addPanelEl.appendChild(this.tabPaneUrl),this.drawerEl.appendChild(this.addPanelEl),this.drawerInner=s("div",{className:"horeg-drawer-inner"}),this.drawerEl.appendChild(this.drawerInner),this.root.appendChild(this.drawerEl),this.bindDOMEvents()}bindDOMEvents(){this.playBtn.addEventListener("click",()=>this.events.onPlayPauseClick()),this.prevBtn.addEventListener("click",()=>this.events.onPrevClick()),this.nextBtn.addEventListener("click",()=>this.events.onNextClick()),this.shuffleBtn.addEventListener("click",()=>this.events.onShuffleToggle()),this.loopBtn.addEventListener("click",()=>this.events.onLoopToggle()),this.muteBtn.addEventListener("click",()=>this.events.onMuteToggle()),this.volumeSlider.addEventListener("input",()=>{this.events.onVolumeChange(parseFloat(this.volumeSlider.value))}),this.drawerBtn.addEventListener("click",()=>{this.toggleDrawer()}),this.addTrackBtn.addEventListener("click",()=>{const t=this.addPanelEl.classList.toggle("open");this.addTrackBtn.classList.toggle("active",t),t&&this.toggleDrawer(!0)}),this.tabBtnFile.addEventListener("click",()=>{this.tabBtnFile.classList.add("active"),this.tabBtnUrl.classList.remove("active"),this.tabPaneFile.classList.add("active"),this.tabPaneUrl.classList.remove("active")}),this.tabBtnUrl.addEventListener("click",()=>{this.tabBtnUrl.classList.add("active"),this.tabBtnFile.classList.remove("active"),this.tabPaneUrl.classList.add("active"),this.tabPaneFile.classList.remove("active"),this.urlInput.focus()}),this.dropzoneEl.addEventListener("click",()=>{this.fileInputEl.click()}),this.fileInputEl.addEventListener("change",()=>{if(this.fileInputEl.files&&this.fileInputEl.files.length>0){const t=Array.from(this.fileInputEl.files);this.events.onAddTrackFiles&&this.events.onAddTrackFiles(t),this.fileInputEl.value="",this.closeAddPanel()}}),this.dropzoneEl.addEventListener("dragover",t=>{t.preventDefault(),this.dropzoneEl.classList.add("drag-active")}),this.dropzoneEl.addEventListener("dragleave",()=>{this.dropzoneEl.classList.remove("drag-active")}),this.dropzoneEl.addEventListener("drop",t=>{var o;if(t.preventDefault(),this.dropzoneEl.classList.remove("drag-active"),(o=t.dataTransfer)!=null&&o.files&&t.dataTransfer.files.length>0){const n=Array.from(t.dataTransfer.files).filter(a=>a.type.startsWith("audio/")||/\.(mp3|wav|ogg|flac|m4a|aac)$/i.test(a.name));n.length>0&&this.events.onAddTrackFiles&&(this.events.onAddTrackFiles(n),this.closeAddPanel())}}),this.root.addEventListener("dragover",t=>{t.preventDefault(),this.root.classList.add("drag-over")}),this.root.addEventListener("dragleave",t=>{this.root.contains(t.relatedTarget)||this.root.classList.remove("drag-over")}),this.root.addEventListener("drop",t=>{var o;if(t.preventDefault(),this.root.classList.remove("drag-over"),(o=t.dataTransfer)!=null&&o.files&&t.dataTransfer.files.length>0){const n=Array.from(t.dataTransfer.files).filter(a=>a.type.startsWith("audio/")||/\.(mp3|wav|ogg|flac|m4a|aac)$/i.test(a.name));n.length>0&&this.events.onAddTrackFiles&&(this.events.onAddTrackFiles(n),this.closeAddPanel())}});const e=()=>{const t=this.urlInput.value.trim();if(!t){this.urlInput.focus();return}const o=this.titleInput.value.trim(),n=this.artistInput.value.trim();this.events.onAddTrackUrl&&this.events.onAddTrackUrl(t,o||void 0,n||void 0),this.urlInput.value="",this.titleInput.value="",this.artistInput.value="",this.closeAddPanel()};this.submitUrlBtn.addEventListener("click",e);const r=t=>{t.stopPropagation(),t.key==="Enter"&&(t.preventDefault(),e())};this.urlInput.addEventListener("keydown",r),this.titleInput.addEventListener("keydown",r),this.artistInput.addEventListener("keydown",r),this.cancelAddBtn.addEventListener("click",()=>{this.closeAddPanel()}),this.sliderTrack.addEventListener("mousedown",this.startScrubbing),this.sliderTrack.addEventListener("touchstart",this.startScrubbing,{passive:!1}),this.sliderTrack.addEventListener("keydown",t=>{if(this.currentDuration){if(t.key==="ArrowRight"||t.key==="ArrowUp"){t.preventDefault();const o=parseFloat(this.fillBar.style.width)/100*this.currentDuration;this.events.onSeek(Math.min(o+5,this.currentDuration))}else if(t.key==="ArrowLeft"||t.key==="ArrowDown"){t.preventDefault();const o=parseFloat(this.fillBar.style.width)/100*this.currentDuration;this.events.onSeek(Math.max(o-5,0))}}})}calculateProgressPercent(e){var n,a,l,h;const r=this.sliderTrack.getBoundingClientRect(),t="touches"in e?((a=(n=e.touches)==null?void 0:n[0])==null?void 0:a.clientX)??((h=(l=e.changedTouches)==null?void 0:l[0])==null?void 0:h.clientX)??0:e.clientX,o=m(t-r.left,0,r.width);return r.width>0?o/r.width*100:0}handleScrubbingMove(e){const r=this.calculateProgressPercent(e);if(this.fillBar.style.width=`${r}%`,this.sliderTrack.setAttribute("aria-valuenow",Math.round(r).toString()),this.currentDuration>0){const t=r/100*this.currentDuration;this.currentTimeEl.textContent=T(t)}}finishScrubbing(e){const r=this.calculateProgressPercent(e);if(this.fillBar.style.width=`${r}%`,this.sliderTrack.setAttribute("aria-valuenow",Math.round(r).toString()),this.currentDuration>0){const t=r/100*this.currentDuration;this.currentTimeEl.textContent=T(t),this.events.onSeek(t)}this.isScrubbing=!1,document.body.style.userSelect=""}updateTrackInfo(e){this.titleEl.textContent=e.title||"Untitled Track",this.artistEl.textContent=e.artist||"Unknown Artist",this.albumEl.textContent=e.album||"",e.coverArt?(this.coverContainer.innerHTML="",this.coverImgEl=s("img",{className:"horeg-cover-img",attributes:{src:e.coverArt,alt:`${e.title} cover`}}),this.coverImgEl.onerror=()=>{this.coverContainer.innerHTML=`<span class="horeg-cover-fallback">${c.speaker}</span>`},this.coverContainer.appendChild(this.coverImgEl)):this.coverContainer.innerHTML=`<span class="horeg-cover-fallback">${c.speaker}</span>`,this.checkTitleMarquee()}checkTitleMarquee(){!this.titleEl||!this.titleWrap||(this.titleEl.classList.remove("is-marquee"),this.titleWrap.classList.remove("is-overflowing"),this.titleWrap.style.removeProperty("--marquee-dist"),this.titleWrap.style.removeProperty("--marquee-duration"),this.titleEl.style.removeProperty("--marquee-dist"),this.titleEl.style.removeProperty("--marquee-duration"),requestAnimationFrame(()=>{const e=this.titleEl.scrollWidth,r=this.titleWrap.clientWidth;if(e>r&&r>0){const t=e-r+20,o=Math.max(6,Math.round(t/18)+3),n=`-${t}px`,a=`${o}s`;this.titleWrap.style.setProperty("--marquee-dist",n),this.titleWrap.style.setProperty("--marquee-duration",a),this.titleEl.style.setProperty("--marquee-dist",n),this.titleEl.style.setProperty("--marquee-duration",a),this.titleWrap.classList.add("is-overflowing"),this.titleEl.classList.add("is-marquee")}}))}updatePlayState(e){e?(this.playBtn.classList.add("playing"),this.playBtn.innerHTML=c.pause,this.playBtn.setAttribute("aria-label","Pause track")):(this.playBtn.classList.remove("playing"),this.playBtn.innerHTML=c.play,this.playBtn.setAttribute("aria-label","Play track"))}updateProgress(e,r){if(this.currentDuration=r,this.durationEl.textContent=T(r),!this.isScrubbing){this.currentTimeEl.textContent=T(e);const t=r>0?e/r*100:0;this.fillBar.style.width=`${m(t,0,100)}%`,this.sliderTrack.setAttribute("aria-valuenow",Math.round(t).toString())}}updateBuffer(e){this.bufferBar.style.width=`${m(e,0,100)}%`}updateVolume(e,r){this.volumeSlider.value=e.toString(),r||e===0?(this.muteBtn.innerHTML=c.volumeMute,this.muteBtn.setAttribute("aria-label","Unmute")):(this.muteBtn.innerHTML=c.volumeHigh,this.muteBtn.setAttribute("aria-label","Mute"))}updateLoopState(e){e==="none"?(this.loopBtn.classList.remove("active"),this.loopBtn.innerHTML=c.repeat):e==="all"?(this.loopBtn.classList.add("active"),this.loopBtn.innerHTML=c.repeat):e==="one"&&(this.loopBtn.classList.add("active"),this.loopBtn.innerHTML=c.repeatOne),this.loopBtn.setAttribute("aria-label",`Repeat mode: ${e}`)}updateShuffleState(e){e?this.shuffleBtn.classList.add("active"):this.shuffleBtn.classList.remove("active")}toggleDrawer(e){(e!==void 0?e:!this.drawerEl.classList.contains("open"))?(this.drawerEl.classList.add("open"),this.drawerBtn.classList.add("active")):(this.drawerEl.classList.remove("open"),this.drawerBtn.classList.remove("active"),this.closeAddPanel())}closeAddPanel(){this.addPanelEl.classList.remove("open"),this.addTrackBtn.classList.remove("active")}renderPlaylist(e,r){if(this.drawerCountEl.textContent=e.length.toString(),this.drawerInner.innerHTML="",e.length===0){const t=s("div",{className:"horeg-empty-playlist",textContent:'Playlist masih kosong. Klik "Add Track" untuk menambahkan lagu.'});this.drawerInner.appendChild(t);return}e.forEach((t,o)=>{const n=s("div",{className:`horeg-track-item ${o===r?"active":""}`}),a=s("div",{className:"horeg-track-num",textContent:(o+1).toString().padStart(2,"0")});n.appendChild(a);const l=s("div",{className:"horeg-track-details"}),h=s("div",{className:"horeg-item-title",textContent:t.title}),g=s("div",{className:"horeg-item-artist",textContent:t.artist||"Unknown Artist"});if(l.appendChild(h),l.appendChild(g),n.appendChild(l),t.duration){const u=s("div",{className:"horeg-item-duration",textContent:T(t.duration)});n.appendChild(u)}const p=s("div",{className:"horeg-track-actions"}),b=s("button",{className:"horeg-btn-remove",attributes:{type:"button","aria-label":"Hapus lagu dari playlist"},innerHTML:c.trash});b.addEventListener("click",u=>{u.stopPropagation(),this.events.onRemoveTrack&&this.events.onRemoveTrack(o)}),p.appendChild(b),n.appendChild(p),n.addEventListener("click",()=>{this.events.onTrackSelect(o)}),this.drawerInner.appendChild(n)})}destroy(){this.root.remove()}}class O{constructor(e){i(this,"stageContainer");i(this,"coverContainer",null);i(this,"isEnabled",!0);i(this,"isRunning",!1);i(this,"animFrameId",null);i(this,"getAudioEnergy");i(this,"leftBoxEl");i(this,"leftTopDriverEl");i(this,"leftBottomDriverEl");i(this,"leftRipples",[]);i(this,"subBoxEl");i(this,"subConeEl");i(this,"shockwave1El");i(this,"shockwave2El");i(this,"rightBoxEl");i(this,"rightTopDriverEl");i(this,"rightBottomDriverEl");i(this,"rightRipples",[]);i(this,"smoothBass",0);i(this,"smoothLeft",0);i(this,"smoothRight",0);i(this,"loop",()=>{if(!this.isRunning)return;const e=this.getAudioEnergy?this.getAudioEnergy():{bass:0,left:0,right:0},r=e.bass<.01?0:e.bass,t=e.left<.01?0:e.left,o=e.right<.01?0:e.right;r>this.smoothBass?this.smoothBass+=(r-this.smoothBass)*.7:this.smoothBass+=(r-this.smoothBass)*.25,this.smoothBass<.01&&(this.smoothBass=0),this.smoothLeft+=(t-this.smoothLeft)*.4,this.smoothLeft<.01&&(this.smoothLeft=0),this.smoothRight+=(o-this.smoothRight)*.4,this.smoothRight<.01&&(this.smoothRight=0),this.applyExcursion(this.smoothBass,this.smoothLeft,this.smoothRight),this.animFrameId=requestAnimationFrame(this.loop)});this.stageContainer=e.stageContainer,this.coverContainer=e.coverContainer||null,this.isEnabled=e.enableAnimation!==!1,this.getAudioEnergy=e.getAudioEnergy,this.buildStage()}setAudioEnergyGetter(e){this.getAudioEnergy=e}buildStage(){this.stageContainer.innerHTML="",this.leftBoxEl=document.createElement("div"),this.leftBoxEl.className="horeg-soundbox is-satellite is-left",this.leftBoxEl.innerHTML=`
|
|
1213
|
+
<div class="horeg-box-header">
|
|
1214
|
+
<span class="horeg-box-bolt top-left"></span>
|
|
1215
|
+
<span class="horeg-tweeter-slot"></span>
|
|
1216
|
+
<span class="horeg-box-bolt top-right"></span>
|
|
1217
|
+
</div>
|
|
1218
|
+
<div class="horeg-satellite-baffle">
|
|
1219
|
+
<!-- Lingkaran 1 Kiri: Top Driver -->
|
|
1220
|
+
<div class="horeg-satellite-driver top">
|
|
1221
|
+
<span class="horeg-driver-ripple ripple-1"></span>
|
|
1222
|
+
<span class="horeg-driver-ripple ripple-2"></span>
|
|
1223
|
+
<div class="horeg-driver-surround">
|
|
1224
|
+
<div class="horeg-driver-cone">
|
|
1225
|
+
<div class="horeg-driver-cap"></div>
|
|
1226
|
+
</div>
|
|
1227
|
+
</div>
|
|
1228
|
+
</div>
|
|
1229
|
+
<!-- Lingkaran 2 Kiri: Bottom Driver -->
|
|
1230
|
+
<div class="horeg-satellite-driver bottom">
|
|
1231
|
+
<span class="horeg-driver-ripple ripple-1"></span>
|
|
1232
|
+
<span class="horeg-driver-ripple ripple-2"></span>
|
|
1233
|
+
<div class="horeg-driver-surround">
|
|
1234
|
+
<div class="horeg-driver-cone">
|
|
1235
|
+
<div class="horeg-driver-cap"></div>
|
|
1236
|
+
</div>
|
|
1237
|
+
</div>
|
|
1238
|
+
</div>
|
|
1239
|
+
</div>
|
|
1240
|
+
<div class="horeg-box-footer">
|
|
1241
|
+
<span class="horeg-box-bolt bottom-left"></span>
|
|
1242
|
+
<span class="horeg-port-slot"></span>
|
|
1243
|
+
<span class="horeg-box-bolt bottom-right"></span>
|
|
1244
|
+
</div>
|
|
1245
|
+
`,this.leftTopDriverEl=this.leftBoxEl.querySelector(".top .horeg-driver-cone"),this.leftBottomDriverEl=this.leftBoxEl.querySelector(".bottom .horeg-driver-cone"),this.leftRipples=Array.from(this.leftBoxEl.querySelectorAll(".horeg-driver-ripple")),this.stageContainer.appendChild(this.leftBoxEl),this.subBoxEl=document.createElement("div"),this.subBoxEl.className="horeg-soundbox is-subwoofer";const e=document.createElement("div");e.className="horeg-shockwaves-wrap",this.shockwave1El=document.createElement("div"),this.shockwave1El.className="horeg-shockwave wave-1",this.shockwave2El=document.createElement("div"),this.shockwave2El.className="horeg-shockwave wave-2",e.appendChild(this.shockwave1El),e.appendChild(this.shockwave2El),this.subBoxEl.appendChild(e);const r=document.createElement("div");r.className="horeg-sub-frame",r.innerHTML=`
|
|
1246
|
+
<span class="horeg-box-bolt top-left"></span>
|
|
1247
|
+
<span class="horeg-box-bolt top-right"></span>
|
|
1248
|
+
<span class="horeg-sub-badge">SUB 18"</span>
|
|
1249
|
+
<span class="horeg-box-bolt bottom-left"></span>
|
|
1250
|
+
<span class="horeg-box-bolt bottom-right"></span>
|
|
1251
|
+
<div class="horeg-sub-ports">
|
|
1252
|
+
<span class="horeg-sub-port left"></span>
|
|
1253
|
+
<span class="horeg-sub-port right"></span>
|
|
1254
|
+
</div>
|
|
1255
|
+
`;const t=document.createElement("div");t.className="horeg-sub-baffle";const o=document.createElement("div");o.className="horeg-sub-surround",this.subConeEl=document.createElement("div"),this.subConeEl.className="horeg-sub-cone",this.coverContainer&&this.subConeEl.appendChild(this.coverContainer),o.appendChild(this.subConeEl),t.appendChild(o),this.subBoxEl.appendChild(r),this.subBoxEl.appendChild(t),this.stageContainer.appendChild(this.subBoxEl),this.rightBoxEl=document.createElement("div"),this.rightBoxEl.className="horeg-soundbox is-satellite is-right",this.rightBoxEl.innerHTML=`
|
|
1256
|
+
<div class="horeg-box-header">
|
|
1257
|
+
<span class="horeg-box-bolt top-left"></span>
|
|
1258
|
+
<span class="horeg-tweeter-slot"></span>
|
|
1259
|
+
<span class="horeg-box-bolt top-right"></span>
|
|
1260
|
+
</div>
|
|
1261
|
+
<div class="horeg-satellite-baffle">
|
|
1262
|
+
<!-- Lingkaran 1 Kanan: Top Driver -->
|
|
1263
|
+
<div class="horeg-satellite-driver top">
|
|
1264
|
+
<span class="horeg-driver-ripple ripple-1"></span>
|
|
1265
|
+
<span class="horeg-driver-ripple ripple-2"></span>
|
|
1266
|
+
<div class="horeg-driver-surround">
|
|
1267
|
+
<div class="horeg-driver-cone">
|
|
1268
|
+
<div class="horeg-driver-cap"></div>
|
|
1269
|
+
</div>
|
|
1270
|
+
</div>
|
|
1271
|
+
</div>
|
|
1272
|
+
<!-- Lingkaran 2 Kanan: Bottom Driver -->
|
|
1273
|
+
<div class="horeg-satellite-driver bottom">
|
|
1274
|
+
<span class="horeg-driver-ripple ripple-1"></span>
|
|
1275
|
+
<span class="horeg-driver-ripple ripple-2"></span>
|
|
1276
|
+
<div class="horeg-driver-surround">
|
|
1277
|
+
<div class="horeg-driver-cone">
|
|
1278
|
+
<div class="horeg-driver-cap"></div>
|
|
1279
|
+
</div>
|
|
1280
|
+
</div>
|
|
1281
|
+
</div>
|
|
1282
|
+
</div>
|
|
1283
|
+
<div class="horeg-box-footer">
|
|
1284
|
+
<span class="horeg-box-bolt bottom-left"></span>
|
|
1285
|
+
<span class="horeg-port-slot"></span>
|
|
1286
|
+
<span class="horeg-box-bolt bottom-right"></span>
|
|
1287
|
+
</div>
|
|
1288
|
+
`,this.rightTopDriverEl=this.rightBoxEl.querySelector(".top .horeg-driver-cone"),this.rightBottomDriverEl=this.rightBoxEl.querySelector(".bottom .horeg-driver-cone"),this.rightRipples=Array.from(this.rightBoxEl.querySelectorAll(".horeg-driver-ripple")),this.stageContainer.appendChild(this.rightBoxEl)}setCoverContainer(e){this.coverContainer=e,this.subConeEl&&!this.subConeEl.contains(e)&&(this.subConeEl.innerHTML="",this.subConeEl.appendChild(e))}setEnabled(e){this.isEnabled=e,e||this.stop()}start(){this.isRunning||!this.isEnabled||(this.isRunning=!0,this.loop())}stop(){this.isRunning=!1,this.decayToIdle()}decayToIdle(){this.animFrameId!==null&&(cancelAnimationFrame(this.animFrameId),this.animFrameId=null);const e=()=>{this.smoothBass*=.8,this.smoothLeft*=.8,this.smoothRight*=.8,this.applyExcursion(this.smoothBass,this.smoothLeft,this.smoothRight),this.smoothBass>.005||this.smoothLeft>.005||this.smoothRight>.005?this.animFrameId=requestAnimationFrame(e):(this.smoothBass=0,this.smoothLeft=0,this.smoothRight=0,this.applyExcursion(0,0,0),this.animFrameId=null)};this.animFrameId=requestAnimationFrame(e)}applyExcursion(e,r,t){const o=1+e*.34;this.subConeEl.style.transform=`scale(${o.toFixed(3)})`;const n=1+e*.04;if(this.subBoxEl.style.transform=`scale(${n.toFixed(3)})`,e>.18){const g=(e-.18)/.82,p=1+g*.7,b=Math.min(.95,g*1.3);this.shockwave1El.style.transform=`scale(${p.toFixed(3)})`,this.shockwave1El.style.opacity=b.toFixed(2);const u=1+g*1.1,v=Math.max(0,(g-.2)*1.2);this.shockwave2El.style.transform=`scale(${u.toFixed(3)})`,this.shockwave2El.style.opacity=v.toFixed(2)}else this.shockwave1El.style.transform="scale(1)",this.shockwave1El.style.opacity="0",this.shockwave2El.style.transform="scale(1)",this.shockwave2El.style.opacity="0";const a=1+r*.1;this.leftTopDriverEl&&(this.leftTopDriverEl.style.transform=`scale(${a.toFixed(3)})`),this.leftBottomDriverEl&&(this.leftBottomDriverEl.style.transform=`scale(${a.toFixed(3)})`);const l=1+t*.1;this.rightTopDriverEl&&(this.rightTopDriverEl.style.transform=`scale(${l.toFixed(3)})`),this.rightBottomDriverEl&&(this.rightBottomDriverEl.style.transform=`scale(${l.toFixed(3)})`);const h=(g,p)=>{const b=p>.06;for(let u=0;u<g.length;u++){const v=g[u],x=v.classList.contains("ripple-2");if(!b){v.style.transform="scale(1)",v.style.opacity="0";continue}const y=1+p*(x?.42:.28),f=Math.max(0,Math.min(1,p*(x?.65:.85)-(x?.15:.05)));v.style.transform=`scale(${y.toFixed(3)})`,v.style.opacity=f.toFixed(2)}};h(this.leftRipples,r),h(this.rightRipples,t)}destroy(){this.stop(),this.stageContainer.innerHTML=""}}class C{constructor(e){i(this,"container");i(this,"shadow");i(this,"styleEl");i(this,"audioEngine");i(this,"ui");i(this,"visualizer");i(this,"theme");i(this,"boundKeyHandler");var n;if(typeof e.container=="string"){const a=document.querySelector(e.container);if(!a)throw new Error(`[HoregAudio] Container "${e.container}" not found in DOM.`);this.container=a}else if(e.container instanceof HTMLElement)this.container=e.container;else throw new Error("[HoregAudio] Invalid container option provided.");const r=((n=e.theme)==null?void 0:n.variant)||"horeg-classic",t=E[r]||E["horeg-classic"];this.theme={...t,...e.theme||{}},this.shadow=this.container.attachShadow({mode:"open"}),this.styleEl=document.createElement("style"),this.styleEl.textContent=L(this.theme),this.shadow.appendChild(this.styleEl),this.ui=new W({onPlayPauseClick:()=>this.toggle(),onPrevClick:()=>this.prev(),onNextClick:()=>this.next(),onSeek:a=>this.seek(a),onVolumeChange:a=>this.setVolume(a),onMuteToggle:()=>{const a=this.audioEngine.toggleMute();this.ui.updateVolume(this.audioEngine.getVolume(),a)},onShuffleToggle:()=>{const a=!this.audioEngine.isShuffle();this.audioEngine.setShuffle(a),this.ui.updateShuffleState(a)},onLoopToggle:()=>{const a=this.audioEngine.getLoop(),l=a==="all"?"one":a==="one"?"none":"all";this.audioEngine.setLoop(l),this.ui.updateLoopState(l)},onTrackSelect:a=>{this.loadTrack(a,!0)},onAddTrackFiles:a=>{this.addTrackFromFiles(a,!1)},onAddTrackUrl:(a,l,h)=>{this.addTrackFromUrl(a,{title:l,artist:h},!1)},onRemoveTrack:a=>{this.removeTrack(a)}}),this.shadow.appendChild(this.ui.root),this.visualizer=new O({stageContainer:this.ui.stageContainer,coverContainer:this.ui.coverContainer,enableAnimation:this.theme.enableEqAnimation!==!1}),this.audioEngine=new j(e,{onPlay:a=>{this.ui.updatePlayState(!0),this.visualizer.start(),e.onPlay&&e.onPlay(a)},onPause:()=>{this.ui.updatePlayState(!1),this.visualizer.stop(),e.onPause&&e.onPause()},onTrackChange:(a,l)=>{this.ui.updateTrackInfo(a);const h=this.audioEngine?this.audioEngine.getPlaylist():e.playlist||[];this.ui.renderPlaylist(h,l),this.ui.updateProgress(0,a.duration||0),e.onTrackChange&&e.onTrackChange(a,l)},onPlaylistChange:(a,l)=>{this.ui.renderPlaylist(a,l),e.onPlaylistChange&&e.onPlaylistChange(a,l)},onTimeUpdate:(a,l)=>{this.ui.updateProgress(a,l),e.onTimeUpdate&&e.onTimeUpdate(a,l)},onBufferUpdate:a=>{this.ui.updateBuffer(a)},onEnded:a=>{this.visualizer.stop(),e.onEnded&&e.onEnded(a)},onError:a=>{this.ui.updatePlayState(!1),this.visualizer.stop(),e.onError&&e.onError(a)}}),this.visualizer.setAudioEnergyGetter(()=>this.audioEngine.getAudioEnergy()),this.ui.updateVolume(this.audioEngine.getVolume(),this.audioEngine.isMuted()),this.ui.updateLoopState(this.audioEngine.getLoop()),this.ui.updateShuffleState(this.audioEngine.isShuffle()),this.ui.renderPlaylist(this.audioEngine.getPlaylist(),this.audioEngine.getCurrentIndex());const o=this.audioEngine.getCurrentTrack();o&&(this.ui.updateTrackInfo(o),this.ui.renderPlaylist(this.audioEngine.getPlaylist(),this.audioEngine.getCurrentIndex())),this.boundKeyHandler=this.handleKeyDown.bind(this),this.container.tabIndex=this.container.tabIndex>=0?this.container.tabIndex:0,this.container.addEventListener("keydown",this.boundKeyHandler)}handleKeyDown(e){var a;const r=e.composedPath?e.composedPath():[],t=r.length>0?r[0]:e.target,o=((a=this.shadow)==null?void 0:a.activeElement)||document.activeElement,n=l=>{if(!l)return!1;const h=l.tagName;return h==="INPUT"||h==="TEXTAREA"||h==="SELECT"||l.isContentEditable};if(!(n(t)||n(o)))if(e.code==="Space"){if((t==null?void 0:t.tagName)==="BUTTON"||(o==null?void 0:o.tagName)==="BUTTON")return;e.preventDefault(),this.toggle()}else e.key==="ArrowRight"&&!e.shiftKey?(e.preventDefault(),this.seek(this.audioEngine.getCurrentTime()+5)):e.key==="ArrowLeft"&&!e.shiftKey?(e.preventDefault(),this.seek(this.audioEngine.getCurrentTime()-5)):e.key==="ArrowUp"?(e.preventDefault(),this.setVolume(this.audioEngine.getVolume()+.05)):e.key==="ArrowDown"&&(e.preventDefault(),this.setVolume(this.audioEngine.getVolume()-.05))}async play(){await this.audioEngine.play()}pause(){this.audioEngine.pause()}toggle(){this.audioEngine.toggle()}next(){this.audioEngine.next()}prev(){this.audioEngine.prev()}seek(e){this.audioEngine.seek(e)}setVolume(e){this.audioEngine.setVolume(e),this.ui.updateVolume(this.audioEngine.getVolume(),this.audioEngine.isMuted())}loadTrack(e,r=!1){this.audioEngine.loadTrack(e,r)}addTrack(e,r=!1){const t=this.audioEngine.addTrack(e,r);return this.ui.renderPlaylist(this.audioEngine.getPlaylist(),this.audioEngine.getCurrentIndex()),t}addTracks(e,r=!1){this.audioEngine.addTracks(e,r),this.ui.renderPlaylist(this.audioEngine.getPlaylist(),this.audioEngine.getCurrentIndex())}async addTrackFromFile(e,r=!1){const t=URL.createObjectURL(e),o=e.name.replace(/\.[^/.]+$/,""),n={id:`local-${Date.now()}-${Math.random().toString(36).substring(2,7)}`,title:o,artist:"File Audio Lokal",src:t};try{const a=await this.probeAudioDuration(t);a>0&&(n.duration=a)}catch{}return this.addTrack(n,r),n}async addTrackFromFiles(e,r=!1){const t=Array.from(e),o=[];for(let n=0;n<t.length;n++){const a=t[n],l=r&&n===0,h=await this.addTrackFromFile(a,l);o.push(h)}return o}async addTrackFromUrl(e,r={},t=!1){var a,l;let o="Online Track";try{const g=new URL(e).pathname,p=g.substring(g.lastIndexOf("/")+1);p&&(o=decodeURIComponent(p).replace(/\.[^/.]+$/,""))}catch{}const n={id:r.id||`url-${Date.now()}-${Math.random().toString(36).substring(2,7)}`,title:((a=r.title)==null?void 0:a.trim())||o,artist:((l=r.artist)==null?void 0:l.trim())||"Audio Stream",album:r.album,coverArt:r.coverArt,src:e,duration:r.duration};if(!n.duration)try{const h=await this.probeAudioDuration(e);h>0&&(n.duration=h)}catch{}return this.addTrack(n,t),n}removeTrack(e){this.audioEngine.removeTrack(e),this.ui.renderPlaylist(this.audioEngine.getPlaylist(),this.audioEngine.getCurrentIndex());const r=this.audioEngine.getCurrentTrack();r?this.ui.updateTrackInfo(r):this.ui.updateTrackInfo({title:"No Track Loaded",src:""})}getPlaylist(){return this.audioEngine.getPlaylist()}probeAudioDuration(e){return new Promise(r=>{const t=new Audio;let o=!1;const n=h=>{o||(o=!0,t.removeEventListener("loadedmetadata",a),t.removeEventListener("error",l),t.src="",r(h))},a=()=>{const h=t.duration;n(h&&!isNaN(h)&&isFinite(h)?h:0)},l=()=>n(0);t.addEventListener("loadedmetadata",a),t.addEventListener("error",l),t.src=e,setTimeout(()=>n(0),3e3)})}setTheme(e){if(e.variant){const r=E[e.variant]||E["horeg-classic"];this.theme={...r,...e}}else this.theme={...this.theme,...e};this.styleEl.textContent=L(this.theme),this.theme.enableEqAnimation!==void 0&&this.visualizer.setEnabled(this.theme.enableEqAnimation)}getTheme(){return{...this.theme}}getAudioEngine(){return this.audioEngine}destroy(){this.container.removeEventListener("keydown",this.boundKeyHandler),this.audioEngine.destroy(),this.visualizer.destroy(),this.ui.destroy(),this.shadow.innerHTML=""}}C.HoregAudio=C;C.default=C;C.THEME_PRESETS=E;C.generateStyles=L;exports.HoregAudio=C;exports.THEME_PRESETS=E;exports.default=C;exports.generateStyles=L;module.exports=Object.assign(exports.default||exports.HoregAudio,exports);
|
|
878
1289
|
//# sourceMappingURL=horeg-audio.cjs.map
|