PageSourceSearch

https://onlyhit.us/en/listen/

html onlyhit.us collected 2026-09-24 10:56:15 UTC 114,937 bytes, 2,194 lines download raw bytes

1<!DOCTYPE html>
2<html lang="en">
3<head>
4<meta charset="UTF-8">
5<meta name="viewport" content="width=device-width, initial-scale=1.0">
6<title>How to Listen to Only Hits — App, Web & More | Only Hits</title>
7<meta name="title" content="How to Listen to Only Hits — App, Web & More | Only Hits">
8<meta name="description" content="Download the Only Hits app on the App Store and Google Play, or listen to Only Hits on the web, TuneIn, Apple Music, smart speakers, and more.">
9<meta name="keywords" content="only hits app, onlyhits app, listen only hits, app store, google play, ios, android, tunein, apple music, web player, radio app">
10<meta name="robots" content="index, follow">
11<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
12<meta property="og:title" content="How to Listen to Only Hits — App, Web & More | Only Hits">
13<meta property="og:description" content="Download the Only Hits app on the App Store and Google Play, or listen to Only Hits on the web, TuneIn, Apple Music, smart speakers, and more.">
14<meta property="og:url" content="https://onlyhit.us/en/listen/">
15<meta property="og:site_name" content="Only Hits">
16<meta property="og:locale" content="en">
17<meta property="og:image" content="https://onlyhit.us/cdn/onlyhits_square.png?width=1200">
18
19<meta name="twitter:card" content="summary_large_image">
20<meta name="twitter:site" content="@onlyhitus">
21<meta name="twitter:title" content="How to Listen to Only Hits — App, Web & More | Only Hits">
22<meta name="twitter:description" content="Download the Only Hits app on the App Store and Google Play, or listen to Only Hits on the web, TuneIn, Apple Music, smart speakers, and more.">
23<meta name="twitter:image" content="https://onlyhit.us/cdn/onlyhits_square.png?width=1200">
24
25<meta name="apple-itunes-app" content="app-id=6773056315">
26<meta property="al:ios:app_store_id" content="6773056315">
27<meta property="al:ios:app_name" content="Only Hits">
28<meta property="al:android:package" content="com.onlyhits.onlyhits">
29<meta property="al:android:app_name" content="Only Hits">
30
31<link rel="icon" href="/favicon.ico" type="image/x-icon">
32<link rel="canonical" href="https://onlyhit.us/listen">
33<link rel="alternate" type="application/rss+xml" title="Only Hits - RSS Feed" href="https://onlyhit.us/en/feed/">
34<link rel="alternate" hreflang="x-default" href="https://onlyhit.us/en/listen">
35
36<link rel="alternate" hreflang="ar" href="https://onlyhit.us/ar/listen"><link rel="alternate" hreflang="bg" href="https://onlyhit.us/bg/listen"><link rel="alternate" hreflang="bn" href="https://onlyhit.us/bn/listen"><link rel="alternate" hreflang="bs" href="https://onlyhit.us/bs/listen"><link rel="alternate" hreflang="ca" href="https://onlyhit.us/ca/listen"><link rel="alternate" hreflang="cs" href="https://onlyhit.us/cs/listen"><link rel="alternate" hreflang="cy" href="https://onlyhit.us/cy/listen"><link rel="alternate" hreflang="da" href="https://onlyhit.us/da/listen"><link rel="alternate" hreflang="de" href="https://onlyhit.us/de/listen"><link rel="alternate" hreflang="el" href="https://onlyhit.us/el/listen"><link rel="alternate" hreflang="en" href="https://onlyhit.us/en/listen"><link rel="alternate" hreflang="es" href="https://onlyhit.us/es/listen"><link rel="alternate" hreflang="eu" href="https://onlyhit.us/eu/listen"><link rel="alternate" hreflang="fa" href="https://onlyhit.us/fa/listen"><link rel="alternate" hreflang="fi" href="https://onlyhit.us/fi/listen"><link rel="alternate" hreflang="fr" href="https://onlyhit.us/fr/listen"><link rel="alternate" hreflang="fy" href="https://onlyhit.us/fy/listen"><link rel="alternate" hreflang="gl" href="https://onlyhit.us/gl/listen"><link rel="alternate" hreflang="gu" href="https://onlyhit.us/gu/listen"><link rel="alternate" hreflang="he" href="https://onlyhit.us/he/listen"><link rel="alternate" hreflang="hi" href="https://onlyhit.us/hi/listen"><link rel="alternate" hreflang="hr" href="https://onlyhit.us/hr/listen"><link rel="alternate" hreflang="ht" href="https://onlyhit.us/ht/listen"><link rel="alternate" hreflang="hu" href="https://onlyhit.us/hu/listen"><link rel="alternate" hreflang="id" href="https://onlyhit.us/id/listen"><link rel="alternate" hreflang="is" href="https://onlyhit.us/is/listen"><link rel="alternate" hreflang="it" href="https://onlyhit.us/it/listen"><link rel="alternate" hreflang="ja" href="https://onlyhit.us/ja/listen"><link rel="alternate" hreflang="kn" href="https://onlyhit.us/kn/listen"><link rel="alternate" hreflang="ko" href="https://onlyhit.us/ko/listen"><link rel="alternate" hreflang="ky" href="https://onlyhit.us/ky/listen"><link rel="alternate" hreflang="lt" href="https://onlyhit.us/lt/listen"><link rel="alternate" hreflang="lv" href="https://onlyhit.us/lv/listen"><link rel="alternate" hreflang="mk" href="https://onlyhit.us/mk/listen"><link rel="alternate" hreflang="mr" href="https://onlyhit.us/mr/listen"><link rel="alternate" hreflang="ms" href="https://onlyhit.us/ms/listen"><link rel="alternate" hreflang="mt" href="https://onlyhit.us/mt/listen"><link rel="alternate" hreflang="nb" href="https://onlyhit.us/nb/listen"><link rel="alternate" hreflang="nl" href="https://onlyhit.us/nl/listen"><link rel="alternate" hreflang="no" href="https://onlyhit.us/no/listen"><link rel="alternate" hreflang="pl" href="https://onlyhit.us/pl/listen"><link rel="alternate" hreflang="pt" href="https://onlyhit.us/pt/listen"><link rel="alternate" hreflang="ro" href="https://onlyhit.us/ro/listen"><link rel="alternate" hreflang="ru" href="https://onlyhit.us/ru/listen"><link rel="alternate" hreflang="sk" href="https://onlyhit.us/sk/listen"><link rel="alternate" hreflang="sl" href="https://onlyhit.us/sl/listen"><link rel="alternate" hreflang="sq" href="https://onlyhit.us/sq/listen"><link rel="alternate" hreflang="sr" href="https://onlyhit.us/sr/listen"><link rel="alternate" hreflang="sv" href="https://onlyhit.us/sv/listen"><link rel="alternate" hreflang="th" href="https://onlyhit.us/th/listen"><link rel="alternate" hreflang="tk" href="https://onlyhit.us/tk/listen"><link rel="alternate" hreflang="tl" href="https://onlyhit.us/tl/listen"><link rel="alternate" hreflang="tr" href="https://onlyhit.us/tr/listen"><link rel="alternate" hreflang="uk" href="https://onlyhit.us/uk/listen"><link rel="alternate" hreflang="vi" href="https://onlyhit.us/vi/listen"><link rel="alternate" hreflang="wa" href="https://onlyhit.us/wa/listen"><link rel="alternate" hreflang="zh" href="https://onlyhit.us/zh/listen"><meta property="og:type" content="website">
37<script type="application/ld+json">{
38    "@context": "https://schema.org",
39    "@graph": [
40        {
41            "@type": "MobileApplication",
42            "name": "Only Hits",
43            "operatingSystem": "iOS",
44            "applicationCategory": "MusicApplication",
45            "description": "Listen to Only Hits live wherever you go: pop, gold, J-Pop, K-Pop, and Top Hits stations, plus now playing, track history, and charts. Free on iOS and Android.",
46            "url": "https://apps.apple.com/app/only-hits/id6773056315",
47            "installUrl": "https://apps.apple.com/app/only-hits/id6773056315",
48            "downloadUrl": "https://apps.apple.com/app/only-hits/id6773056315",
49            "image": "https://onlyhit.us/cdn/onlyhits_square.png",
50            "offers": {
51                "@type": "Offer",
52                "price": "0",
53                "priceCurrency": "USD"
54            },
55            "publisher": {
56                "@type": "Organization",
57                "name": "Only Hits",
58                "url": "https://onlyhit.us"
59            }
60        },
61        {
62            "@type": "MobileApplication",
63            "name": "Only Hits",
64            "operatingSystem": "ANDROID",
65            "applicationCategory": "MusicApplication",
66            "description": "Listen to Only Hits live wherever you go: pop, gold, J-Pop, K-Pop, and Top Hits stations, plus now playing, track history, and charts. Free on iOS and Android.",
67            "url": "https://play.google.com/store/apps/details?id=com.onlyhits.onlyhits",
68            "installUrl": "https://play.google.com/store/apps/details?id=com.onlyhits.onlyhits",
69            "downloadUrl": "https://play.google.com/store/apps/details?id=com.onlyhits.onlyhits",
70            "image": "https://onlyhit.us/cdn/onlyhits_square.png",
71            "offers": {
72                "@type": "Offer",
73                "price": "0",
74                "priceCurrency": "USD"
75            },
76            "publisher": {
77                "@type": "Organization",
78                "name": "Only Hits",
79                "url": "https://onlyhit.us"
80            }
81        }
82    ]
83}</script>
83
84    <meta name="theme-color" content="#c1272d">
85    <link rel="preload" href="/cdn/fonts/dm-sans/dm-sans-400.woff2" as="font" type="font/woff2" crossorigin>
86    <link rel="preload" href="/cdn/fonts/dm-sans/dm-sans-700.woff2" as="font" type="font/woff2" crossorigin>
87    <link rel="stylesheet" href="/cdn/fonts/dm-sans/dm-sans.css?1784222347">
88    <style>
89        :root {
90            --website-primary-color: #c1272d;
91            --player-primary-color: #c1272d;
92            --website-primary-color-rgb: 193, 39, 45;
93            --primary: #c1272d;
94            --primary-dark: color-mix(in srgb, #c1272d 82%, #000);
95            --primary-glow: rgba(193, 39, 45, 0.22);
96            --primary-soft: rgba(193, 39, 45, 0.14);
97
98            --font-sans: 'DM Sans', 'Segoe UI', Tahoma, sans-serif;
99            --font-display: 'DM Sans', 'Segoe UI', Tahoma, sans-serif;
100
101            --bg: #0f0f0f;
102            --bg-soft: #141416;
103            --background-dark: #0f0f0f;
104            --surface: #1a1a1a;
105            --surface-dark: #1a1a1a;
106            --surface-raised: #222226;
107            --charcoal: #2a2a30;
108            --bg-muted: #222226;
109
110            --text: #ffffff;
111            --text-primary: #ffffff;
112            --text-secondary: rgba(255, 255, 255, 0.65);
113            --text-muted: rgba(255, 255, 255, 0.45);
114
115            --border: rgba(255, 255, 255, 0.1);
116            --border-color: rgba(255, 255, 255, 0.1);
117            --border-light: rgba(255, 255, 255, 0.06);
118
119            --shadow-sm: 0 1px 3px rgba(0, 0, 0, 0.35);
120            --shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
121            --shadow-lg: 0 16px 40px rgba(0, 0, 0, 0.45);
122
123            --radius: 10px;
124            --radius-sm: 6px;
125            --radius-full: 9999px;
126
127            --nav-h: 64px;
128            --player-h: 72px;
129            --max: 1140px;
130        }
131    </style>
132    <link rel="stylesheet" href="/cdn/style.css?1786648139">
133    <!-- Meta Pixel Code -->
134<script async type="text/plain" data-cookie-consent="targeting">
vendor: 399 bytes, lines 134-143
134
135!function(f,b,e,v,n,t,s)
136{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
137n.callMethod.apply(n,arguments):n.queue.push(arguments)};
138if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
139n.queue=[];t=b.createElement(e);t.async=!0;
140t.src=v;s=b.getElementsByTagName(e)[0];
141s.parentNode.insertBefore(t,s)}(window, document,'script',
142'https://connect.facebook.net/en_US/fbevents.js');
143fbq('init', '
1432251220131831317
vendor: 30 bytes, lines 143-144
143');
144fbq('track', 'PageView');
145</script>
145
146<noscript><img height="1" width="1" style="display:none"
147src="https://www.facebook.com/tr?id=2251220131831317&ev=PageView&noscript=1"
148/></noscript>
149<!-- End Meta Pixel Code -->
150</head>
151<body>
152    <nav class="nav-container">
153        <div class="main-nav">
154            <div class="station-selector">
155                <a href="https://onlyhit.us/en/radio/onlyhit" class="current-station">
156                    <img src="/cdn/onlyhits_4x1.png?width=250" 
157                         alt="Only Hits" />
158                </a>
159                <button class="station-selector-toggle" aria-label="Switch station">▼</button>
160                <div class="station-dropdown">
161                                            <div class="station-option" 
162                             data-color="#c1272d" 
163                             data-id="onlyhit">
164                            <img src="/cdn/onlyhits_4x1.png?width=250" 
165                                 alt="Only Hits" />
166                        </div>
167                                            <div class="station-option" 
168                             data-color="#c17927" 
169                             data-id="gold">
170                            <img src="/cdn/gold_4x1.png?width=250" 
171                                 alt="Only Hits Gold" />
172                        </div>
173                                            <div class="station-option" 
174                             data-color="#278bc1" 
175                             data-id="japan">
176                            <img src="/cdn/japan_4x1.png?width=250" 
177                                 alt="Only Hits Japan" />
178                        </div>
179                                            <div class="station-option" 
180                             data-color="#c12789" 
181                             data-id="kpop">
182                            <img src="/cdn/kpop_4x1.png?width=250" 
183                                 alt="Only Hits K-Pop" />
184                        </div>
185                                            <div class="station-option" 
186                             data-color="#c1272d" 
187                             data-id="tophits">
188                            <img src="/cdn/tophits_4x1.png?width=250" 
189                                 alt="Top Hits" />
190                        </div>
191                                    </div>
192            </div>
193            <button class="menu-toggle" aria-label="Menu">☰</button>
194            <ul class="nav-items">
195                <li class="nav-item">
196                    <a href="#">Radio</a>
197                    <ul class="submenu" id="radio-submenu">
198                        <li><a href="https://onlyhit.us/en/listen/" class="station-dependent-link" data-path="/listen">
199                            Listen                        </a></li>
200                        <li><a href="https://onlyhit.us/en/listen/">
201                            Get the App                        </a></li>
202                        <li><a href="https://onlyhit.us/en/radio/onlyhit/schedule/" class="station-dependent-link" data-path="/schedule">
203                            Schedule                        </a></li>
204                        <li><a href="https://onlyhit.us/en/radio/onlyhit/team/" class="station-dependent-link" data-path="/team">
205                            Team                        </a></li>
206                        <li><a href="https://onlyhit.us/en/partners/" class="station-dependent-link" data-path="/partners">
207                            Partners                        </a></li>
208                        <li><a href="https://onlyhit.us/en/radio/onlyhit/history/" class="station-dependent-link" data-path="/history">
209                            What was played?                        </a></li>
210                    </ul>
211                </li>
212                <li class="nav-item">
213                    <a href="#">Music</a>
214                    <ul class="submenu">
215                        <li><a href="https://onlyhit.us/en/music/onlyhit/new-releases/" class="station-dependent-link" data-path="/new-releases">
216                            New releases                        </a></li>
217                        <li><a href="https://onlyhit.us/en/music/onlyhit/browse/" class="station-dependent-link" data-path="/browse">
218                            Browse                        </a></li>
219                        <li><a href="https://onlyhit.us/en/charts/">
220                            Charts                        </a></li>
221                    </ul>
222                </li>
223                <li class="nav-item">
224                    <a href="https://onlyhit.us/en/charts/">
225                        Charts                    </a>
226                    <ul class="submenu">
227                        <li><a href="https://onlyhit.us/en/charts/pop-thisweek/">
228                            Pop Charts
229                        </a></li>
230                        <li><a href="https://onlyhit.us/en/charts/japan-thisweek/">
231                            Japan Charts
232                        </a></li>
233                        <li><a href="https://onlyhit.us/en/charts/kpop-thisweek/">
234                            K-POP Charts
235                        </a></li>
236                    </ul>
237                </li>
238                <li class="nav-item">
239                    <a href="https://onlyhit.us/en/news/">
240                        News                    </a>
241                </li>
242                <li class="nav-item">
243                    <a href="https://onlyhit.us/en/contact/">Contact</a>
244                </li>
245                <li class="nav-item nav-item-cta">
246                    <button type="button" class="nav-listen-cta" id="nav-listen-cta" aria-label="Play">
247                        <span class="live-dot" aria-hidden="true"></span>
248                        <span class="nav-listen-cta-label">Listen</span>
249                    </button>
250                </li>
251            </ul>
252        </div>
253    </nav>
254<script type="module" src="https://static.cloudflareinsights.com/beacon.min.js/v31edd6df95cf4e85bb4c19e7a9bdbcba1788362987495" integrity="sha512-iIg7k2xntmwu6/uSb5tpc/hySgZc4eoL31yB29W6tJFo2akwjPWcEqnCEdJvGexCL0KEQwVYv5BlowfhVz26hg==" data-cf-beacon='{"version":"2024.11.0","token":"491cc5a392164229b9c14423b8be523c","r":1,"spa":2}' crossorigin="anonymous"></script>
254
255</body>
256</html>
257<!-- Main Content Area -->
258<main>
259    
260<div class="main-content">
261    <div class="main-header-3">
262        <img src="/cdn/https://cdn.onlyhitsradio.net/logo/onlyhits.png?width=60" 
263             alt="Only Hits" 
264             class="main-header-3-logo">
265        <div>
266            <h1>How to Listen</h1>
267            <p>Available on the Only Hits app, the web, and all your favorite devices</p>
268        </div>
269    </div>
270
271    <div id="get-the-app" class="section margin-bottom-3 listen-app-promo">
272        <h2>Get the Only Hits App</h2>
273        <p>Listen live on iPhone and Android — pop, gold, J-Pop, K-Pop, and Top Hits, plus now playing, track history, and charts. Free on the App Store and Google Play.</p>
274            <div class="store-badges store-badges--listen">
275        <a class="store-badge store-badge-apple"
276           href="https://apps.apple.com/app/only-hits/id6773056315"
277           target="_blank"
278           rel="noopener noreferrer"
279           aria-label="Download Only Hits on the App Store">
280            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc. --><path d="M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184.8 4 273.5q0 39.3 14.4 81.2c12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z"/></svg>            <span>
281                <small>Download on the</small>
282                App Store
283            </span>
284        </a>
285        <a class="store-badge store-badge-google"
286           href="https://play.google.com/store/apps/details?id=com.onlyhits.onlyhits"
287           target="_blank"
288           rel="noopener noreferrer"
289           aria-label="Get Only Hits on Google Play">
290            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc. --><path d="M325.3 234.3L104.6 13l280.8 161.2-60.1 60.1zM47 0C34 6.8 25.3 19.2 25.3 35.3v441.3c0 16.1 8.7 28.5 21.7 35.3l256.6-256L47 0zm425.2 225.6l-58.9-34.1-65.7 64.5 65.7 64.5 60.1-34.1c18-14.3 18-46.5-1.2-60.8zM104.6 499l280.8-161.2-60.1-60.1L104.6 499z"/></svg>            <span>
291                <small>Get it on</small>
292                Google Play
293            </span>
294        </a>
295    </div>
296        </div>
297
298    <div class="section margin-bottom-3">
299        <h2>Main Platforms</h2>
300        <div class="listen-platforms-grid">
301            <div class="listen-platform-card">
302                <div class="listen-platform-icon">
303                    <svg viewBox="0 0 24 24" width="48" height="48">
304                        <path fill="currentColor" d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 14.5c-2.49 0-4.5-2.01-4.5-4.5S9.51 7.5 12 7.5s4.5 2.01 4.5 4.5-2.01 4.5-4.5 4.5zm0-5.5c-.55 0-1 .45-1 1s.45 1 1 1 1-.45 1-1-.45-1-1-1z"/>
305                    </svg>
306                </div>
307                <h3>Web Player</h3>
308                <p>Listen directly from our website using the player at the bottom of the page.</p>
309            </div>
310
311            <div class="listen-platform-card">
312                <div class="listen-platform-icon">
313                    <svg viewBox="0 0 24 24" width="48" height="48">
314                        <path fill="currentColor" d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515a.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0a12.64 12.64 0 0 0-.617-1.25a.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057a19.9 19.9 0 0 0 5.993 3.03a.078.078 0 0 0 .084-.028a14.09 14.09 0 0 0 1.226-1.994a.076.076 0 0 0-.041-.106a13.107 13.107 0 0 1-1.872-.892a.077.077 0 0 1-.008-.128a10.2 10.2 0 0 0 .372-.292a.074.074 0 0 1 .077-.01c3.928 1.793 8.18 
3141.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127a12.299 12.299 0 0 1-1.873.892a.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028a19.839 19.839 0 0 0 6.002-3.03a.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.956-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419c0-1.333.955-2.419 2.157-2.419c1.21 0 2.176 1.096 2.157 2.42c0 1.333-.946 2.418-2.157 2.418z"/>
315                    </svg>
316                </div>
317                <h3>Discord Bot</h3>
318                <p>Listen to Only Hits directly in your Discord server.</p>
319                <a href="#discord-section" class="button-link">
320                    Learn More                </a>
321            </div>
322
323            <div class="listen-platform-card">
324                <div class="listen-platform-icon">
325                    <img src="/cdn/logos/tunein.png?width=48" alt="TuneIn" class="listen-platform-icon-image">
326                </div>
327                <h3>TuneIn</h3>
328                <p>Listen on smart speakers and devices through TuneIn. Just say "Play Only Hits on TuneIn".</p>
329                <a href="https://tunein.com/search/?query=Only Hits" class="button-link" target="_blank">
330                    Open TuneIn                </a>
331            </div>
332        </div>
333    </div>
334
335    <div class="section margin-bottom-3">
336        <h2>Other Platforms</h2>
337        <div class="listen-platforms-grid">
338            <div class="listen-platform-card">
339                <h3>TuneIn</h3>
340                <div class="platform-links">
341                    <a href="https://tunein.com/radio/Only-Hits-s259926/" class="button-link" target="_blank">Only Hits</a>
342                    <a href="https://tunein.com/radio/Only-Hits-Gold-s267300/" class="button-link" target="_blank">Only Hits Gold</a>
343                    <a href="https://tunein.com/radio/Only-Hits-Japan-s251172/" class="button-link" target="_blank">Only Hits Japan</a>
344                    <a href="https://tunein.com/radio/Only-Hits-K-Pop-s260557/" class="button-link" target="_blank">Only Hits K-Pop</a>
345                    <a href="https://tunein.com/radio/Top-Hits-s221182/" class="button-link" target="_blank">Top Hits</a>
346                </div>
347            </div>
348            <div class="listen-platform-card">
349                <h3>Apple Music</h3>
350                <div class="platform-links">
351                    <a href="https://music.apple.com/fr/station/only-hits-us/ra.1477719630" class="button-link" target="_blank">Only Hits</a>
352                    <a href="https://music.apple.com/fr/station/only-hits-gold/ra.1461169308" class="button-link" target="_blank">Only Hits Gold</a>
353                    <a href="https://music.apple.com/fr/station/only-hits-japan/ra.1486823407" class="button-link" target="_blank">Only Hits Japan</a>
354                    <a href="https://music.apple.com/fr/station/only-hits-k-pop/ra.1461110334" class="button-link" target="_blank">Only Hits K-Pop</a>
355                    <a href="https://music.apple.com/fr/station/top-hits/ra.1461094087" class="button-link" target="_blank">Top Hits</a>
356                </div>
357            </div>
358            <div class="listen-platform-card">
359                <h3>Getme.radio</h3>
360                <div class="platform-links">
361                    <a href="https://getme.radio/onlyhitus" class="button-link" target="_blank">Only Hits</a>
362                    <a href="https://getme.radio/onlyhitgold" class="button-link" target="_blank">Only Hits Gold</a>
363                    <a href="https://getme.radio/onlyhitjapan" class="button-link" target="_blank">Only Hits Japan</a>
364                    <a href="https://getme.radio/onlyhitk-pop" class="button-link" target="_blank">Only Hits K-Pop</a>
365                </div>
366            </div>
367
368            <div class="listen-platform-card">
369                <h3>Online Radio Box</h3>
370                <div class="platform-links">
371                    <a href="https://onlineradiobox.com/us/onlyhit/" class="button-link" target="_blank">Only Hits</a>
372                    <a href="https://onlineradiobox.com/us/onlyhitgold/" class="button-link" target="_blank">Only Hits Gold</a>
373                    <a href="https://onlineradiobox.com/us/onlyhitjapan/" class="button-link" target="_blank">
373Only Hits Japan</a>
374                    <a href="https://onlineradiobox.com/us/onlyhitkpop/" class="button-link" target="_blank">Only Hits K-Pop</a>
375                    <a href="https://onlineradiobox.com/us/onlyhittophits/" class="button-link" target="_blank">Top Hits</a>
376                </div>
377            </div>
378            <div class="listen-platform-card">
379                <h3>Apple Shortcuts</h3>
380                <div class="platform-links">
381                    <a href="https://www.icloud.com/shortcuts/0d8ccb04509d41fa813caec6f4020ff1" class="button-link" target="_blank">Only Hits</a>
382                    <a href="https://www.icloud.com/shortcuts/64b1329913b74b37af6902a22dbfb310" class="button-link" target="_blank">Only Hits Gold</a>
383                    <a href="https://www.icloud.com/shortcuts/04981301ff9448e79f98cdc1397f5f27" class="button-link" target="_blank">Only Hits Japan</a>
384                    <a href="https://www.icloud.com/shortcuts/37667fb077b440d09af6a9efe360a768" class="button-link" target="_blank">Only Hits K-Pop</a>
385                    <a href="https://www.icloud.com/shortcuts/dccbe9467e774b2bb7231c472b45ef54" class="button-link" target="_blank">Top Hits</a>
386                </div>
387                <p class="listen-apps-description">Set Only Hits as a home shortcut, or an alarm with these shortcuts.</p>
388            </div>
389            <div class="listen-platform-card">
390                <h3>Radio.net</h3>
391                <div class="platform-links">
392                    <a href="https://radio.net/s/onlyhit" class="button-link" target="_blank">Only Hits</a>
393                    <a href="https://radio.net/s/onlyhitgold" class="button-link" target="_blank">Only Hits Gold</a>
394                    <a href="https://radio.net/s/onlyhitj" class="button-link" target="_blank">Only Hits Japan</a>
395                    <a href="https://radio.net/s/onlyhitkpop" class="button-link" target="_blank">Only Hits K-Pop</a>
396                </div>
397            </div>
398            <div class="listen-platform-card">
399                <h3>Internet-Radio.com</h3>
400                <div class="platform-links">
401                    <a href="https://www.internet-radio.com/station/onlyhits/" class="button-link" target="_blank">Only Hits</a>
402                    <a href="https://www.internet-radio.com/station/onlyhitsgold/" class="button-link" target="_blank">Only Hits Gold</a>
403                    <a href="https://www.internet-radio.com/station/onlyhitsjapan/" class="button-link" target="_blank">Only Hits Japan</a>
404                    <a href="https://www.internet-radio.com/station/onlyhitskpop/" class="button-link" target="_blank">Only Hits K-Pop</a>
405                    <a href="https://www.internet-radio.com/station/tophits/" class="button-link" target="_blank">Top Hits</a>
406                </div>
407            </div>
408        </div>
409    </div>
410
411    <ins class="adsbygoogle margin-bottom-3" style="display:none" data-ad-client="ca-pub-7468708296619588" data-ad-slot="9151610796" data-ad-format="auto" data-full-width-responsive="true"></ins>
412
413    <div class="section margin-bottom-3">
414        <h2>Direct Links</h2>
415        <div class="listen-links-grid">
416                        <div class="listen-link-card">
417                <img src="/cdn/https://cdn.onlyhitsradio.net/logo/onlyhits.png?width=64" 
418                     alt="Only Hits">
419                <div>
420                    <h3>Only Hits</h3>
421                    <div class="listen-link-formats">
422                                                    <a href="https://cdn.onlyhitsradio.net/onlyhits" target="_blank" class="button-link">MP3</a>
423                                                                            <a href="https://cdn.onlyhitsradio.net/onlyhits_64" target="_blank" class="button-link">AAC</a>
424                                                                            <a href="https://cdn.onlyhitsradio.net/onlyhits.m3u8" target="_blank" class="button-link">HLS</a>
425                                            </div>
426                </div>
427            </div>
428                        <div class="listen-link-card">
429                <img src="/cdn/https://cdn.onlyhitsradio.net/logo/gold.png?width=64" 
430                     alt="Only Hits Gold">
431                <div>
432                    <h3>Only Hits Gold</h3>
433                    <div class="listen-link-formats">
434                                                    <a href="https://cdn.onlyhitsradio.net/gold" target="_blank" class="button-link">MP3</a>
435                                                                            <a href="https://cdn.onlyhitsradio.net/gold_64" target="_blank" class="button-link">AAC</a>
436                                                                            <a href="https://cdn.onlyhitsradio.net/gold.m3u8" target="_blank" class="button-link">HLS</a>
437                                            </div>
438                </div>
439            </div>
440                        <div class="listen-link-card">
441                <img src="/cdn/https://cdn.onlyhitsradio.net/logo/japan.png?width=64" 
442                     alt="Only Hits Japan">
443                <div>
444                    <h3>Only Hits Japan</h3>
445                    <div class="listen-link-formats">
446                                                    <a href="https://cdn.onlyhitsradio.net/japan" target="_blank" class="button-link">MP3</a>
447                                                                            <a href="https://cdn.onlyhitsradio.net/japan_64" target="_blank" class="button-link">AAC</a>
448                                                                            <a href="https://cdn.onlyhitsradio.net/japan.m3u8" target="_blank" class="button-link">HLS</a>
449                                            </div>
450                </div>
451            </div>
452                        <div class="listen-link-card">
453                <img src="/cdn/https://cdn.onlyhitsradio.net/logo/kpop.png?width=64" 
454                     alt="Only Hits K-Pop">
455                <div>
456                    <h3>Only Hits K-Pop</h3>
457                    <div class="listen-link-formats">
458                                                    <a href="https://cdn.onlyhitsradio.net/kpop" target="_blank" class="button-link">MP3</a>
459                                                                            <a href="https://cdn.onlyhitsradio.net/kpop_64" target="_blank" class="button-link">AAC</a>
460                                                                            <a href="https://cdn.onlyhitsradio.net/kpop.m3u8" target="_blank" class="button-link">HLS</a>
461                                            </div>
462                </div>
463            </div>
464                        <div class="listen-link-card">
465                <img src="/cdn/https://cdn.onlyhitsradio.net/logo/tophits.png?width=64" 
466                     alt="Top Hits">
467                <div>
468                    <h3>Top Hits</h3>
469                    <div class="listen-link-formats">
470                                                    <a href="https://cdn.onlyhitsradio.net/tophits" target="_blank" class="button-link">MP3</a>
471                                                                            <a href="https://cdn.onlyhitsradio.net/tophits_64" target="_blank" class="button-link">AAC</a>
472                                                                            <a href="https://cdn.onlyhitsradio.net/tophits.m3u8" target="_blank" class="button-link">HLS</a>
473                                            </div>
474                </div>
475            </div>
476                    </div>
477    </div>
478
479    <div id="discord-section" class="section margin-bottom-3">
480        <h2>Discord Bot</h2>
481        <p>Listen to Only Hits directly in your Discord server with our dedicated bots for each station.</p>
482        
483        <div class="listen-discord-grid">
484                                    <div class="listen-platform-card">
485                <h3>OnlyHit</h3>
486                <p>Our main station playing the latest hits</p>
487                <a href="https://discordapp.com/oauth2/authorize?client_id=666412985513672715&amp;scope=bot&amp;permissions=34606080" class="button-link" target="_blank">
488                    Add to Discord                </a>
489            </div>
490                        <div class="listen-platform-card">
491                <h3>Only Hits Gold</h3>
492                <p>For those who appreciate the golden hits</p>
493                <a href="https://discordapp.com/oauth2/authorize?client_id=775034887702970408&amp;scope=bot&amp;permissions=34606080" class="button-link" target="_blank">
494                    Add to Discord                </a>
495            </div>
496                        <div class="listen-platform-card">
497                <h3>
497Only Hits Japan</h3>
498                <p>Get the best of Japanese music</p>
499                <a href="https://discordapp.com/oauth2/authorize?client_id=775034918031458314&amp;scope=bot&amp;permissions=34606080" class="button-link" target="_blank">
500                    Add to Discord                </a>
501            </div>
502                        <div class="listen-platform-card">
503                <h3>Only Hits K-Pop</h3>
504                <p>The world of Korean pop</p>
505                <a href="https://discordapp.com/oauth2/authorize?client_id=775034945366130708&amp;scope=bot&amp;permissions=34606080" class="button-link" target="_blank">
506                    Add to Discord                </a>
507            </div>
508                    </div>
509
510        <div class="discord-commands">
511            <h3>Bot Commands</h3>
512            <div class="commands-grid">
513                <div class="command-item">
514                    <code>/join</code>
515                    <p>Join your voice channel and play Only Hits LIVE!</p>
516                </div>
517                <div class="command-item">
518                    <code>/setup &lt;channel&gt;</code>
519                    <p>Designate a specific channel for the bot (Admin only)</p>
520                </div>
521                <div class="command-item">
522                    <code>/stick</code>
523                    <p>Keep the bot in your current voice channel (Admin only)</p>
524                </div>
525                <div class="command-item">
526                    <code>/unstick</code>
527                    <p>Free the bot from your current voice channel (Admin only)</p>
528                </div>
529                <div class="command-item">
530                    <code>/help</code>
531                    <p>Display a list of all available commands</p>
532                </div>
533                <div class="command-item">
534                    <code>/info</code>
535                    <p>Get information about the radio website</p>
536                </div>
537            </div>
538        </div>
539    </div>
540
541    <div class="section margin-bottom-3">
542        <h2>Developer Tools</h2>
543        <p>Access our API for integration with your applications.</p>
544        <a href="https://api.onlyhit.us" class="button-link" target="_blank">
545            View API Documentation        </a>
546    </div>
547</div>
548
549</main>
550<footer>
551        <div class="footer-content">
552            <div class="footer-section">
553                <h3>Links</h3>
554                <div class="footer-links">
555                <p><a class="footer-link" href="/en/contact/">Contact Us</a></p>
556                <p><a class="footer-link" href="/en/privacy/">Privacy Policy</a></p>
557                <p><a class="footer-link" href="#" id="open_preferences_center">Manage Cookies</a></p>
558                <p><a class="footer-link" href="/en/page/advertise/">Advertise with us</a></p>
559                <p><a class="footer-link" href="http://onlyhit.merchforall.com/" target="_blank">Merch</a></p>
560                <p><a class="footer-link" href="https://api.onlyhit.us/" target="_blank">API</a></p>
561                </div>
562                <p class="footer-app-label">Get the App</p>
563                    <div class="store-badges store-badges--footer">
564        <a class="store-badge store-badge-apple"
565           href="https://apps.apple.com/app/only-hits/id6773056315"
566           target="_blank"
567           rel="noopener noreferrer"
568           aria-label="Download Only Hits on the App Store">
569            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc. --><path d="M318.7 268.7c-.2-36.7 16.4-64.4 50-84.8-18.8-26.9-47.2-41.7-84.7-44.6-35.5-2.8-74.3 20.7-88.5 20.7-15 0-49.4-19.7-76.4-19.7C63.3 141.2 4 184.8 4 273.5q0 39.3 14.4 81.2c12.8 36.7 59 126.7 107.2 125.2 25.2-.6 43-17.9 75.8-17.9 31.8 0 48.3 17.9 76.4 17.9 48.6-.7 90.4-82.5 102.6-119.3-65.2-30.7-61.7-90-61.7-91.9zm-56.6-164.2c27.3-32.4 24.8-61.9 24-72.5-24.1 1.4-52 16.4-67.9 34.9-17.5 19.8-27.8 44.3-25.6 71.9 26.1 2 49.9-11.4 69.5-34.3z"/></svg>
569            <span>
570                <small>Download on the</small>
571                App Store
572            </span>
573        </a>
574        <a class="store-badge store-badge-google"
575           href="https://play.google.com/store/apps/details?id=com.onlyhits.onlyhits"
576           target="_blank"
577           rel="noopener noreferrer"
578           aria-label="Get Only Hits on Google Play">
579            <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc. --><path d="M325.3 234.3L104.6 13l280.8 161.2-60.1 60.1zM47 0C34 6.8 25.3 19.2 25.3 35.3v441.3c0 16.1 8.7 28.5 21.7 35.3l256.6-256L47 0zm425.2 225.6l-58.9-34.1-65.7 64.5 65.7 64.5 60.1-34.1c18-14.3 18-46.5-1.2-60.8zM104.6 499l280.8-161.2-60.1-60.1L104.6 499z"/></svg>            <span>
580                <small>Get it on</small>
581                Google Play
582            </span>
583        </a>
584    </div>
585                </div>
586            <div class="footer-section">
587                <h3>Follow Us</h3>
588                <div class="social-links">
589                    <a href="https://www.facebook.com/OnlyHitUS" target="_blank" aria-label="Follow us on Facebook">
590                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc. --><path d="M512 256C512 114.6 397.4 0 256 0S0 114.6 0 256C0 376 82.7 476.8 194.2 504.5V334.2H141.4V256h52.8V222.3c0-87.1 39.4-127.5 125-127.5c16.2 0 44.2 3.2 55.7 6.4V172c-6-.6-16.5-1-29.6-1c-42 0-58.2 15.9-58.2 57.2V256h83.6l-14.4 78.2H287V510.1C413.8 494.8 512 386.9 512 256h0z"/></svg>                    </a>
591                    <a href="https://www.instagram.com/OnlyHitUS" target="_blank" aria-label="Follow us on Instagram">
592                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc. --><path d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"/></svg>                    </a>
593                    <a href="https://x.com/OnlyHitUS" target="_blank" aria-label="Follow us on X (Twitter)">
594                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc. --><path d="M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z"/></svg>                    </a>
595                    <a href="https://discord.gg/F9xhW8tjV2" target="_blank" aria-label="Join our Discord server">
596                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc. --><path d="M524.531,69.836a1.5,1.5,0,0,0-.764-.7A485.065,485.065,0,0,0,404.081,32.03a1.816,1.816,0,0,0-1.923.91,337.461,337.461,0,0,0-14.9,30.6,447.848,447.848,0,0,0-134.426,0,309.541,309.541,0,0,0-15.135-30.6,1.89,1.89,0,0,0-1.924-.91A483.689,483.689,0,0,0,116.085,69.137a1.712,1.712,0,0,0-.788.676C39.068,183.651,18.186,294.69,28.43,404.354a2.016,2.016,0,0,0,.765,1.375A487.666,487.666,0,0,0,176.02,479.918a1.9,1.9,0,0,0,2.063-.676A348.2,348.2,0,0,0,208.12,430.4a1.86,1.86,0,0,0-1.019-2.588,321.173,321.173,0,0,1-45.868-21.853,1.885,1.885,0,0,1-.185-3.126c3.082-2.309,6.166-4.711,9.109
596-7.137a1.819,1.819,0,0,1,1.9-.256c96.229,43.917,200.41,43.917,295.5,0a1.812,1.812,0,0,1,1.924.233c2.944,2.426,6.027,4.851,9.132,7.16a1.884,1.884,0,0,1-.162,3.126,301.407,301.407,0,0,1-45.89,21.83,1.875,1.875,0,0,0-1,2.611,391.055,391.055,0,0,0,30.014,48.815,1.864,1.864,0,0,0,2.063.7A486.048,486.048,0,0,0,610.7,405.729a1.882,1.882,0,0,0,.765-1.352C623.729,277.594,590.933,167.465,524.531,69.836ZM222.491,337.58c-28.972,0-52.844-26.587-52.844-59.239S193.056,219.1,222.491,219.1c29.665,0,53.306,26.82,52.843,59.239C275.334,310.993,251.924,337.58,222.491,337.58Zm195.38,0c-28.971,0-52.843-26.587-52.843-59.239S388.437,219.1,417.871,219.1c29.667,0,53.307,26.82,52.844,59.239C470.715,310.993,447.538,337.58,417.871,337.58Z"/></svg>                    </a>
597                    <a href="https://tunein.com/search/?query=OnlyHit" target="_blank" aria-label="Listen on TuneIn">
598                        <?xml version="1.0" encoding="UTF-8" standalone="no"?>
599<!-- Created with Inkscape (http://www.inkscape.org/) -->
600
601<svg
602   version="1.1"
603   id="svg2"
604   width="416"
605   height="266.66666"
606   viewBox="0 0 416 266.66666"
607   sodipodi:docname="TuneIn_Logo_Black.eps"
608   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
609   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
610   xmlns="http://www.w3.org/2000/svg"
611   xmlns:svg="http://www.w3.org/2000/svg">
612  <defs
613     id="defs6" />
614  <sodipodi:namedview
615     id="namedview4"
616     pagecolor="#ffffff"
617     bordercolor="#000000"
618     borderopacity="0.25"
619     inkscape:showpageshadow="2"
620     inkscape:pageopacity="0.0"
621     inkscape:pagecheckerboard="0"
622     inkscape:deskcolor="#d1d1d1" />
623  <g
624     id="g8"
625     inkscape:groupmode="layer"
626     inkscape:label="ink_ext_XXXXXX"
627     transform="matrix(1.3333333,0,0,-1.3333333,0,266.66667)">
628    <g
629       id="g10"
630       transform="scale(0.1)">
631      <path
632         d="m 2362.36,1232 c 0,4.41 -3.6,8 -7.99,8 h -40 c -4.4,0 -8,-3.59 -8,-8 v -150.37 c 0,-2.4 -2.8,-3.2 -3.6,-0.8 l -54.79,151.97 c -1.2,3.61 -4,7.2 -10,7.2 h -47.59 c -4.39,0 -8,-3.59 -8,-8 V 968.051 c 0,-4.403 3.61,-8 8,-8 h 39.99 c 4.41,0 8,3.597 8,8 v 138.379 c 0,2.4 2.8,3.19 3.6,0.8 l 54.4,-140.378 c 1.19,-3.204 3.99,-6.801 10.79,-6.801 h 47.2 c 4.39,0 7.99,3.597 7.99,8 z m -224.39,-225.95 c 0,4.39 -3.59,7.99 -8,7.99 h -33.99 c -2.4,0 -4,1.6 -4,4 v 163.97 c 0,2.4 1.6,4.01 4,4.01 h 30 c 4.39,0 7.99,3.59 7.99,8 V 1232 c 0,4.41 -3.6,8 -7.99,8 H 2002 c -4.4,0 -8.01,-3.59 -8.01,-8 v -37.98 c 0,-4.41 3.61,-8 8.01,-8 h 29.99 c 2.4,0 4,-1.61 4,-4.01 v -163.97 c 0,-2.4 -1.6,-4 -4,-4 H 1998 c -4.4,0 -8,-3.6 -8,-7.99 v -37.999 c 0,-4.403 3.6,-8 8,-8 h 131.97 c 4.41,0 8,3.597 8,8 z M 1780,1180 H 625 c -2.766,0 -5,-2.25 -5,-5 V 625 c 0,-2.762 2.234,-5 5,-5 h 1150 c 2.76,0 5,2.238 5,5 z m 780,230 V 790 c 0,-16.57 -13.44,-30 -30,-30 H 1840 V 590 c 0,-16.57 -13.43,-30 -30,-30 H 590 c -16.57,0 -30,13.43 -30,30 v 620 c 0,16.56 13.43,30 30,30 h 1190 v 170 c 0,16.57 13.44,30 30,30 h 720 c 16.56,0 30,-13.43 30,-30 z M 1602.75,816.039 h -94.78 c -2.4,0 -4.01,1.602 -4.01,4 v 47.992 c 0,2.399 1.61,4 4.01,4 h 89.98 c 4.4,0 8,3.59 8,8 v 39.989 c 0,4.402 -3.6,8 -8,8 h -89.98 c -2.4,0 -4.01,1.601 -4.01,4 v 47.992 c 0,2.398 1.61,4 4.01,4 h 93.18 c 4.4,0 8,3.597 8,8 V 1032 c 0,4.41 -3.6,8 -8,8 h -145.17 c -4.4,0 -8,-3.59 -8,-8 V 768.051 c 0,-4.403 3.6,-8 8,-8 h 146.77 c 4.4,0 8,3.597 8,8 v 39.988 c 0,4.402 -3.6,8 -8,8 z M 1395.56,1040 h -40 c -4.4,0 -8,-3.59 -8,-8 V 881.629 c 0,-2.399 -2.79,-3.199 -3.6,-0.801 l -54.79,151.972 c -1.2,3.61 -3.99,7.2 -10,7.2 h -47.59 c -4.39,0 -8,-3.59 -8,-8 V 768.051 c 0,-4.403 3.61,-8 8,-8 h 39.99 c 4.41,0 8,3.597 8,8 V 906.43 c 0,2.402 2.8,3.191 3.6,0.8 l 54.4,-140.378 c 1.19,-3.204 3.99,-6.801 10.79,-6.801 h 47.2 c 4.39,0 7.99,3.597 7.99,8 V 1032 c 0,4.41 -3.6,8 -7.99,8 z m -225.6,0 h -40.39 c -4.4,0 -8,-3.59 -8,-8 V 844.031 c 0,-17.59 -14.39,-31.992 -38.8,-31.992 -23.59,0 -37.98,14.402 -37.98,31.992 V 1032 c 0,4.41 -3.61,8 -8,8 h -40.395 c -4.403,0 -8.004,-3.59 -8.004,-8 V 844.031 c 0,-48.39 39.999,-88.383 94.379,-88.383 55.2,0 95.19,39.993 95.19,88.383 V 1032 c 0,4.41 -3.59,8 -8,8 z m -219.987,-8 v -39.988 c 0,-4.403 -3.606,-8 -8,-8 H 891.98 c -2.402,0 -4,-1.602 -4,-4 V 768.051 c 0,-4.403 -3.605,-8 -8,-8 h -39.992 c -4.402,0 -7.996,3.597 -7.996,8 v 211.961 c 0,2.398 -1.601,4 -4.004,4 h -49.992 c -4.402,0 -7.996,3.597 -7.996,8 V 1032 c 0,4.41 3.594,8 7.996,8 h 163.977 c 4.394,0 8,-3.59 8,-8"
633         style="fill-opacity:1;fill-rule:nonzero;stroke:none"
634         id="path12" />
635    </g>
636  </g>
637</svg>
638                    </a>
639                    <a href="https://open.spotify.com/user/31jjh5xk2gvwqh54jqqpe3ika3ki" target="_blank" aria-label="Follow us on Spotify">
640                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc. --><path d="M248 8C111.1 8 0 119.1 0 256s111.1 248 248 248 248-111.1 248-248S384.9 8 248 8zm100.7 364.9c-4.2 0-6.8-1.3-10.7-3.6-62.4-37.6-135-39.2-206.7-24.5-3.9 1-9 2.6-11.9 2.6-9.7 0-15.8-7.7-15.8-15.8 0-10.3 6.1-15.2 13.6-16.8 81.9-18.1 165.6-16.5 237 26.2 6.1 3.9 9.7 7.4 9.7 16.5s-7.1 15.4-15.2 15.4zm26.9-65.6c-5.2 0-8.7-2.3-12.3-4.2-62.5-37-155.7-51.9-238.6-29.4-4.8 1.3-7.4 2.6-11.9 2.6-10.7 0-19.4-8.7-19.4-19.4s5.2-17.8 15.5-20.7c27.8-7.8 56.2-13.6 97.8-13.6 64.9 0 127.6 16.1 177 45.5 8.1 4.8 11.3 11 11.3 19.7-.1 10.8-8.5 19.5-19.4 19.5zm31-76.2c-5.2 0-8.4-1.3-12.9-3.9-71.2-42.5-198.5-52.7-280.9-29.7-3.6 1-8.1 2.6-12.9 2.6-13.2 0-23.3-10.3-23.3-23.6 0-13.6 8.4-21.3 17.4-23.9 35.2-10.3 74.6-15.2 117.5-15.2 73 0 149.5 15.2 205.4 47.8 7.8 4.5 12.9 10.7 12.9 22.6 0 13.6-11 23.3-23.2 23.3z"/></svg>                    </a>
641                    <a href="https://www.youtube.com/@OnlyHitUS" target="_blank" aria-label="Follow us on YouTube">
642                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 6.7.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2024 Fonticons, Inc. --><path d="M549.655 124.083c-6.281-23.65-24.787-42.276-48.284-48.597C458.781 64 288 64 288 64S117.22 64 74.629 75.486c-23.497 6.322-42.003 24.947-48.284 48.597-11.412 42.867-11.412 132.305-11.412 132.305s0 89.438 11.412 132.305c6.281 23.65 24.787 41.5 48.284 47.821C117.22 448 288 448 288 448s170.78 0 213.371-11.486c23.497-6.321 42.003-24.171 48.284-47.821 11.412-42.867 11.412-132.305 11.412-132.305s0-89.438-11.412-132.305zm-317.51 213.508V175.185l142.739 81.205-142.739 81.201z"/></svg>                    </a>
643                </div>
644            </div>
645            <div class="footer-section">
646                <h3>Newsletter</h3>
647                <form class="newsletter-form" onsubmit="submitNewsletter(event)">
648                    <input type="email" name="email" placeholder="Enter your email address">
649                    <button type="submit">Subscribe</button>
650                </form>
651                <p class="newsletter-description">By subscribing here, you subscribe directly to our Pop Charts, Japan Charts, and K-POP Charts newsletters. You will need to confirm your subscription by clicking the link in the email you receive.</p>
652            </div>
653            <div class="footer-section">
654                <h3>
655                    Latest News                    <a href="https://onlyhit.us/en/feed" 
656                       target="_blank" 
657                       class="rss-feed-link" 
658                       title="RSS Feed"
659                       aria-label="RSS Feed">
660                        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
660<path fill="currentColor" d="M0 64C0 46.3 14.3 32 32 32c229.8 0 416 186.2 416 416c0 17.7-14.3 32-32 32s-32-14.3-32-32C384 253.6 226.4 96 32 96C14.3 96 0 81.7 0 64zM0 416a64 64 0 1 1 128 0A64 64 0 1 1 0 416zM32 160c159.1 0 288 128.9 288 288c0 17.7-14.3 32-32 32s-32-14.3-32-32c0-123.7-100.3-224-224-224c-17.7 0-32-14.3-32-32s14.3-32 32-32z"/></svg>
661                    </a>
662                </h3>
663                <div class="footer-news">
664                                            <a href="https://onlyhit.us/en/news/sky-hi-hosts-mazzels-naoya-and-ran-for-radio-show-public-recording" 
665                           class="footer-news-link">
666                                                            <img src="/cdn//uploads/prtimes/2026/09/6ab4e7d253581.jpg?width=50&height=50" 
667                                     alt="SKY-HI Hosts MAZZEL&#039;s NAOYA and RAN for Radio Show Public Recording"
668                                     class="footer-news-image">
669                                                        <div class="footer-news-info">
670                                <span class="news-title">SKY-HI Hosts MAZZEL&#039;s NAOYA and RAN for Radio Show Public Recording</span>
671                                <span class="news-date">24 September 2026</span>
672                            </div>
673                        </a>
674                                            <a href="https://onlyhit.us/en/news/ultra-japan-announces-2027-festival-dates-following-2026-event" 
675                           class="footer-news-link">
676                                                            <img src="/cdn//uploads/prtimes/2026/09/6ab4c465c0e87.jpg?width=50&height=50" 
677                                     alt="ULTRA JAPAN Announces 2027 Festival Dates Following 2026 Event"
678                                     class="footer-news-image">
679                                                        <div class="footer-news-info">
680                                <span class="news-title">ULTRA JAPAN Announces 2027 Festival Dates Following 2026 Event</span>
681                                <span class="news-date">24 September 2026</span>
682                            </div>
683                        </a>
684                                            <a href="https://onlyhit.us/en/news/silent-siren-announces-second-anime-tie-in-single-uma-for-october" 
685                           class="footer-news-link">
686                                                            <img src="/cdn//uploads/prtimes/2026/09/6ab48c3c66b1e.jpg?width=50&height=50" 
687                                     alt="SILENT SIREN Announces Second Anime Tie-In Single &#039;あっとUMA&#039; for October"
688                                     class="footer-news-image">
689                                                        <div class="footer-news-info">
690                                <span class="news-title">SILENT SIREN Announces Second Anime Tie-In Single &#039;あっとUMA&#039; for October</span>
691                                <span class="news-date">24 September 2026</span>
692                            </div>
693                        </a>
694                                    </div>
695            </div>
696        </div>
697        <p><br></p>
698        <div class="footer-content" style="font-size: 12px; color: gray;">
699            <p>&copy; 2026 OnlyHit. All rights reserved. - Metadata provided by <a style="color: var(--website-primary-color);" href="https://www.acrcloud.com" target="_blank">ACRCloud</a></p>
700        </div>
701    </footer>
702
703<style>
704    @keyframes spin {
705        from { transform: rotate(0deg); }
706        to { transform: rotate(360deg); }
707    }
708    .spin-animation {
709        animation: spin 1s linear infinite;
710    }
711</style>
712	
713<div id="audio-player">
714    <div id="station-logo">
715        <div id="station-logo-clickable" class="station-logo-clickable">
716            <img src="/cdn/https://cdn.onlyhitsradio.net/logo/onlyhits.png?width=60" alt="Cover of the playing song" />
717            <span id="station-toggle-arrow">&#9650;</span>
718        </div>
719        <div class="player-track-info">
720            <h4 id="player-track-title"></h4>
721            <p id="player-track-artist"></p>
722        </div>
723    </div>
724    
725    <div>
726        <button id="play-button" aria-label="Play">
727            <svg viewBox="0 0 24 24" width="30" height="30">
728                <path fill="currentColor" d="M8 5v14l11-7z"/>
729            </svg>
730        </button>
731    </div>
732    
733    <div>
734        <input id="volume-control" type="range" min="0" max="1" step="0.01" aria-label="Volume" />
735    </div>
736</div>
737
738<div id="player-station-list">
739    <h4>Select Station</h4>
740    <div>
741                    <div class="player-station-option" 
742                data-id="onlyhit"
743                data-url="https://cdn.onlyhitsradio.net/onlyhits"
744                data-color="#c1272d"
745                data-logo="https://cdn.onlyhitsradio.net/logo/onlyhits.png"
746                data-metadata="https://cdn.onlyhitsradio.net/currentsong/onlyhits">
747                <img loading="lazy" src="/cdn/https://cdn.onlyhitsradio.net/logo/onlyhits.png?width=48" alt="Only Hits" />
748                <div>
749                    <span>Only Hits</span>
750                    <p>Your Favorite Hit Music Station</p>
751                </div>
752            </div>
753                    <div class="player-station-option" 
754                data-id="gold"
755                data-url="https://cdn.onlyhitsradio.net/gold"
756                data-color="#c17927"
757                data-logo="https://cdn.onlyhitsradio.net/logo/gold.png"
758                data-metadata="https://cdn.onlyhitsradio.net/currentsong/gold">
759                <img loading="lazy" src="/cdn/https://cdn.onlyhitsradio.net/logo/gold.png?width=48" alt="Only Hits Gold" />
760                <div>
761                    <span>Only Hits Gold</span>
762                    <p>70s, 80s and Pop Rock Hits</p>
763                </div>
764            </div>
765                    <div class="player-station-option" 
766                data-id="japan"
767                data-url="https://cdn.onlyhitsradio.net/japan"
768                data-color="#278bc1"
769                data-logo="https://cdn.onlyhitsradio.net/logo/japan.png"
770                data-metadata="https://cdn.onlyhitsradio.net/currentsong/japan">
771                <img loading="lazy" src="/cdn/https://cdn.onlyhitsradio.net/logo/japan.png?width=48" alt="Only Hits Japan" />
772                <div>
773                    <span>Only Hits Japan</span>
774                    <p>The best Japanese Hits</p>
775                </div>
776            </div>
777                    <div class="player-station-option" 
778                data-id="kpop"
779                data-url="https://cdn.onlyhitsradio.net/kpop"
780                data-color="#c12789"
781                data-logo="https://cdn.onlyhitsradio.net/logo/kpop.png"
782                data-metadata="https://cdn.onlyhitsradio.net/currentsong/kpop">
783                <img loading="lazy" src="/cdn/https://cdn.onlyhitsradio.net/logo/kpop.png?width=48" alt="Only Hits K-Pop" />
784                <div>
785                    <span>Only Hits K-Pop</span>
786                    <p>The best K-POP Hits</p>
787                </div>
788            </div>
789                    <div class="player-station-option" 
790                data-id="tophits"
791                data-url="https://cdn.onlyhitsradio.net/tophits"
792                data-color="#c1272d"
793                data-logo="https://cdn.onlyhitsradio.net/logo/tophits.png"
794                data-metadata="https://cdn.onlyhitsradio.net/currentsong/tophits">
795                <img loading="lazy" src="/cdn/https://cdn.onlyhitsradio.net/logo/tophits.png?width=48" alt="Top Hits" />
796                <div>
797                    <span>Top Hits</span>
798                    <p>Number One On The Hits</p>
799                </div>
800            </div>
801            </div>
802</div>
803
804<script src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit" defer></script>
vendor: 1 bytes, line 804
804
805<script src="/cdn/cookie-consent.js" defer></script>
vendor: 1 bytes, line 805
805
806<script type="text/javascript" charset="UTF-8">
807document.addEventListener('DOMContentLoaded', function () {
808cookieconsent.run({"notice_banner_type":"interstitial","consent_type":"express","palette":"dark","language":"en","page_load_consent_levels":["strictly-necessary"],"notice_banner_reject_button_hide":false,"preferences_center_close_button_hide":false,"page_refresh_confirmation_buttons":false,"website_name":"OnlyHit","website_privacy_policy_url":"https://onlyhit.us/privacy/"});
809});
810</script>
810
811
812<script>
813    window.cookieConsent = 'false';
814
815    function acceptCookies() {
816        window.cookieConsent = true;
817    }
818
819    function isAppleDevice() {
820        const ua = navigator.userAgent || navigator.vendor || window.opera;
821        if (/iPhone|iPod|iPad/i.test(ua)) {
822            return true;
823        }
824        if (/Macintosh/i.test(ua) && 'ontouchend' in document) {
825            return true;
826        }
827        return false;
828    }
829
830    const isHDRDisplay = window.matchMedia('(dynamic-range: high)').matches;
831    
832    function hexToP3(hex, boost = 1.3) {
833        const r = parseInt(hex.slice(1, 3), 16) / 255;
834        const g = parseInt(hex.slice(3, 5), 16) / 255;
835        const b = parseInt(hex.slice(5, 7), 16) / 255;
836        const rP3 = Math.min(r * boost, 1.2);
837        const gP3 = Math.min(g * boost, 1.2);
838        const bP3 = Math.min(b * boost, 1.2);
839        return `color(display-p3 ${rP3.toFixed(3)} ${gP3.toFixed(3)} ${bP3.toFixed(3)})`;
840    }
841
842    function updateHDRColors(hexColor) {
843        if (!isHDRDisplay) return;
844        const hdrColor = hexToP3(hexColor, 1.3);
845        const hdrGlow = hexToP3(hexColor, 1.2).replace(')', ' / 0.6)');
846        document.documentElement.style.setProperty('--player-primary-color-hdr', hdrColor);
847        document.documentElement.style.setProperty('--player-primary-color-hdr-glow', hdrGlow);
848    }
849
850    function applyStationThemeColor(hexColor) {
851        if (!hexColor) return;
852        const root = document.documentElement;
853        root.style.setProperty('--website-primary-color', hexColor);
854        root.style.setProperty('--player-primary-color', hexColor);
855        root.style.setProperty('--primary', hexColor);
856        const match = /^#([a-fA-F0-9]{6})$/.exec(hexColor);
857        if (match) {
858            const r = parseInt(match[1].slice(0, 2), 16);
859            const g = parseInt(match[1].slice(2, 4), 16);
860            const b = parseInt(match[1].slice(4, 6), 16);
861            const rgb = `${r}, ${g}, ${b}`;
862            root.style.setProperty('--website-primary-color-rgb', rgb);
863            root.style.setProperty('--primary-glow', `rgba(${rgb}, 0.22)`);
864            root.style.setProperty('--primary-soft', `rgba(${rgb}, 0.14)`);
865        }
866        updateHDRColors(hexColor);
867    }
868
869    const appleMusicUrls = {
870        'onlyhit': 'https://music.apple.com/station/only-hits-us/ra.1477719630',
871        'gold': 'https://music.apple.com/station/only-hits-gold/ra.1461169308',
872        'japan': 'https://music.apple.com/station/only-hits-japan/ra.1486823407',
873        'kpop': 'https://music.apple.com/station/only-hits-k-pop/ra.1461110334',
874        'tophits': 'https://music.apple.com/station/top-hits/ra.1461094087'
875    };
876
877    const audio = new Audio();
878    window.audio = audio;
879    const playButton = document.getElementById('play-button');
880    const volumeControl = document.getElementById('volume-control');
881    const trackTitle = document.getElementById('player-track-title');
882    const trackArtist = document.getElementById('player-track-artist');
883    const stationLogo = document.getElementById('station-logo').querySelector('img');
884    const stationList = document.getElementById('player-station-list');
885    const toggleArrow = document.getElementById('station-toggle-arrow');
886    if (typeof base_url === 'undefined') {
887        var base_url = 'https://onlyhit.us';
888    }
889    if (typeof lang === 'undefined') {
890        var lang = "en";
891    }
892    
893    function encodeArtistSlug(artistName) {
894        return encodeURIComponent(artistName.replace(/\//g, '~'));
895    }
896    const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
897
898    let currentStationPlayer = {
899        id: "onlyhit",
900        url: "https://cdn.onlyhitsradio.net/onlyhits",
901        logo: "https://cdn.onlyhitsradio.net/logo/onlyhits.png",
902        color: "#c1272d",
903        metadataUrl: "https://cdn.onlyhitsradio.net/currentsong/onlyhits",
904        name: "Only Hits"
905    };
906
907    applyStationThemeColor(currentStationPlayer.color);
908
909    let selectedStationId = "onlyhit";
910    let isPlaying = false;
911
912    playButton.addEventListener('click', () => {
913        if (isAppleDevice() && appleMusicUrls[currentStationPlayer.id]) {
914            window.open(appleMusicUrls[currentStationPlayer.id], '_blank');
915            return;
916        }
917
918        if (!isPlaying) {
919            manuallyStopped = false;
920            cancelRetry();
921            audio.src = currentStationPlayer.url;
922            audio.play();
923            playButton.innerHTML = `
924                <svg viewBox="0 0 24 24" width="30" height="30">
925                    <path fill="currentColor" d="M6 6h12v12H6z"/>
926                </svg>`;
927        } else {
928            manuallyStopped = true;
929            cancelRetry();
930            audio.src = "";
931            audio.currentTime = 0;
932            playButton.innerHTML = `
933                <svg viewBox="0 0 24 24" width="30" height="30">
934                    <path fill="currentColor" d="M8 5v14l11-7z"/>
935                </svg>`;
936        }
937        isPlaying = !isPlaying;
938        if (window.data) window.data.isPlaying = isPlaying;
939        updateNavListenCta(isPlaying);
940    });
941
942    function updateNavListenCta(playing) {
943        const navCta = document.getElementById('nav-listen-cta');
944        if (!navCta) return;
945        const label = navCta.querySelector('.nav-listen-cta-label');
946        if (!label) return;
947        label.textContent = playing
948            ? "Stop"            : "Listen";
949        navCta.setAttribute('aria-label', label.textContent);
950    }
951
952    const navListenCta = document.getElementById('nav-listen-cta');
953    if (navListenCta) {
954        navListenCta.addEventListener('click', (e) => {
955            e.preventDefault();
956            e.stopPropagation();
957            // Prefer current page station when available (selectedStationId), else player station
958            const targetStationId = selectedStationId || currentStationPlayer.id;
959            if (targetStationId && targetStationId !== currentStationPlayer.id && typeof switchPlayerToStation === 'function') {
960                const wasPlaying = isPlaying;
961                switchPlayerToStation(targetStationId);
962                if (!wasPlaying) {
963                    playButton.click();
964                }
965                return;
966            }
967            playButton.click();
968        });
969    }
970
971    playButton.addEventListener('mouseenter', () => {
972        playButton.style.transform = 'scale(1.1)';
973        playButton.style.backgroundColor = 'var(--player-primary-color)';
974    });
975
976    playButton.addEventListener('mouseleave', () => {
977        playButton.style.transform = 'scale(1)';
978        playButton.style.backgroundColor = 'var(--player-primary-color)';
979    });
980
981    audio.addEventListener('playing', () => {
982        manuallyStopped = false;
983        isPlaying = true;
984        if (window.data) window.data.isPlaying = true;
985        playButton.innerHTML = `
986            <svg viewBox="0 0 24 24" width="30" height="30">
987                <path fill="currentColor" d="M6 6h12v12H6z"/>
988            </svg>`;
989        updateNavListenCta(true);
990    });
991
992    audio.addEventListener('ended', () => {
993        if (isPlaying) {
994            attemptReconnect();
995            return;
996        }
997        
998        isPlaying = false;
999        if (window.data) window.data.isPlaying = false;
1000        playButton.innerHTML = `
1001            <svg viewBox="0 0 24 24" width="30" height="30">
1002                <path fill="currentColor" d="M8 5v14l11-7z"/>
1003            </svg>`;
1004        updateNavListenCta(false);
1005        const originalTitle = document.querySelector('title').getAttribute('data-original');
1006        document.title = originalTitle || document.title;
1007    });
1008
1009    const retryDelay = 2000;
1010    let retryTimeout = null;
1011    let isRetrying = false;
1012    let lastErrorLogTime = 0;
1013    const errorLogInterval = 10000;
1014    let manuallyStopped = false;
1015
1016    function showRetryingState() {
1017        isRetrying = true;
1018        playButton.innerHTML = `
1019            <svg viewBox="0 0 24 24" width="30" height="30" class="spin-animation">
1020                <path fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" d="M12 2a10 10 0 0 1 10 10"/>
1021                <path fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" opacity="0.3" d="M12 2a10 10 0 1 0 10 10"/>
1022            </svg>`;
1023        playButton.style.opacity = '0.7';
1024    }
1025
1026    function hideRetryingState() {
1027        isRetrying = false;
1028        playButton.style.opacity = '1';
1029        if (isPlaying) {
1030            playButton.innerHTML = `
1031                <svg viewBox="0 0 24 24" width="30" height="30">
1032                    <path fill="currentColor" d="M6 6h12v12H6z"/>
1033                </svg>`;
1034        } else {
1035            playButton.innerHTML = `
1036                <svg viewBox="0 0 24 24" width="30" height="30">
1037                    <path fill="currentColor" d="M8 5v14l11-7z"/>
1038                </svg>`;
1039        }
1040    }
1041
1042    function attemptReconnect() {
1043        if (!isPlaying || isRetrying || retryTimeout) return;
1044        
1045        showRetryingState();
1046        
1047        retryTimeout = setTimeout(() => {
1048            retryTimeout = null;
1049            if (!isPlaying) {
1050                isRetrying = false;
1051                return;
1052            }
1053            
1054            const streamUrl = currentStationPlayer.url;
1055            const separator = streamUrl.includes('?') ? '&' : '?';
1056            audio.src = streamUrl + separator + '_t=' + Date.now();
1057            audio.play().then(() => {
1058                console.log('Reconnected successfully');
1059                hideRetryingState();
1060            }).catch(err => {
1061                const now = Date.now();
1062                if (now - lastErrorLogTime > errorLogInterval) {
1063                    console.error('Reconnect failed:', err);
1064                    lastErrorLogTime = now;
1065                }
1066                isRetrying = false;
1067                attemptReconnect();
1068            });
1069        }, retryDelay);
1070    }
1071
1072    function cancelRetry() {
1073        if (retryTimeout) {
1074            clearTimeout(retryTimeout);
1075            retryTimeout = null;
1076        }
1077        isRetrying = false;
1078    }
1079
1080    audio.addEventListener('error', (e) => {
1081        if (manuallyStopped) {
1082            manuallyStopped = false;
1083            return;
1084        }
1085        
1086        const now = Date.now();
1087        if (now - lastErrorLogTime > errorLogInterval) {
1088            console.error('Audio error:', e);
1089            lastErrorLogTime = now;
1090        }
1091        if (isPlaying && !isRetrying) {
1092            attemptReconnect();
1093        }
1094    });
1095
1096    audio.addEventListener('stalled', () => {
1097        console.warn('Stream stalled');
1098        if (isPlaying && !isRetrying && !retryTimeout) {
1099            setTimeout(() => {
1100                if (isPlaying && audio.readyState < 3 && !retryTimeout) {
1101                    attemptReconnect();
1102                }
1103            }, 5000);
1104        }
1105    });
1106
1107    audio.addEventListener('waiting', () => {
1108        if (isPlaying) {
1109            showRetryingState();
1110        }
1111    });
1112
1113    audio.addEventListener('canplay', () => {
1114        if (isRetrying) {
1115            hideRetryingState();
1116        }
1117    });
1118
1119    audio.addEventListener('pause', () => {
1120        if (isPlaying && !manuallyStopped && !isRetrying && !retryTimeout) {
1121            setTimeout(() => {
1122                if (isPlaying && audio.paused && !manuallyStopped && !retryTimeout) {
1123                    attemptReconnect();
1124                }
1125            }, 1000);
1126        }
1127    });
1128
1129    audio.addEventListener('playing', () => {
1130        manuallyStopped = false;
1131        hideRetryingState();
1132    });
1133
1134    volumeControl.addEventListener('input', (e) => {
1135        const value = e.target.value;
1136        const percentage = value * 100;
1137        e.target.style.background = `linear-gradient(to right, var(--player-primary-color) 0%, var(--player-primary-color) ${percentage}%, rgba(255, 255, 255, 0.1) ${percentage}%, rgba(255, 255, 255, 0.1) 100%)`;
1138        audio.volume = value;
1139        previewAudio.volume = value * 0.355;
1140        setCookie('playerVolume', value, 30);
1141    });
1142
1143    let previousSong = {
1144        artist: '',
1145        title: ''
1146    };
1147    
1148    window.data;
1149
1150    function updateMetadata() {
1151        fetch(`${base_url}/api/nowplaying/now?station=${currentStationPlayer.id}`)
1152            .then((response) => response.json())
1153            .then((data) => {
1154                window.data = data;
1155                window.data.isPlaying = isPlaying;
1156                window.data.station = currentStationPlayer;
1157                
1158                if (data.start_time) {
1159                    window.data.start_time = data.start_time;
1160                }
1161                if (data.duration) {
1162                    window.data.duration = data.duration;
1163                }
1164                
1165                const artistLinks = data.artist.split(',').map(artist => 
1166                    `<a href="${base_url}/${lang}
1166/music/artist/${encodeArtistSlug(artist.trim())}" 
1167                        class="player-track-artist-link">${artist.trim()}</a>`
1168                ).join(', ');
1169
1170                const titleLink = data.isrc ? 
1171                    `<a href="${base_url}/${lang}/music/track/${data.isrc}" 
1172                        class="player-track-title-link">${data.title}</a>` : 
1173                    `<span>${data.title}</span>`;
1174
1175                if (isPlaying) {
1176                    document.title = `🎧 ${data.artist} - ${data.title} | ${currentStationPlayer.name}`;
1177                } else {
1178                    const originalTitle = document.querySelector('title').getAttribute('data-original');
1179                    document.title = originalTitle || document.title;
1180                }
1181
1182                if (trackTitle.innerHTML !== titleLink) {
1183                    trackTitle.innerHTML = titleLink;
1184                    const titleElement = trackTitle;
1185                    if (titleElement && titleElement.scrollWidth > trackTitle.clientWidth) {
1186                        titleElement.style.animation = 'scroll 15s linear infinite';
1187                    } else if (titleElement) {
1188                        titleElement.style.animation = 'none';
1189                    }
1190                }
1191
1192                
1193                let stationAndShowText = currentStationPlayer.name;
1194                if (data.show) {
1195                    stationAndShowText += ` • <a href="${base_url}/${lang}/radio/${currentStationPlayer.id}/show/${data.show.permalink}" 
1196                        class="player-show-link"><span class="on-air-indicator"></span>${data.show.name}</a>`;
1197                }
1198                const artistText = `${artistLinks} • ${stationAndShowText}`;
1199                if (trackArtist.innerHTML !== artistText) {
1200                    trackArtist.innerHTML = artistText;
1201                    if (trackArtist.scrollWidth > trackArtist.clientWidth) {
1202                        trackArtist.style.animation = 'scroll 15s linear infinite';
1203                    } else {
1204                        trackArtist.style.animation = 'none';
1205                    }
1206                }
1207
1208                let currentCoverPath = data.cover ? `/cdn/${data.cover}?width=60` : `/cdn/${currentStationPlayer.logo}?width=60`;
1209                
1210                if (stationLogo.getAttribute('data-current-cover') !== currentCoverPath) {
1211                    stationLogo.src = currentCoverPath;
1212                    stationLogo.setAttribute('data-current-cover', currentCoverPath);
1213                } else if (!data.cover && stationLogo.getAttribute('data-current-cover') !== `/cdn/${currentStationPlayer.logo}?width=60`) {
1214                    stationLogo.src = `/cdn/${currentStationPlayer.logo}?width=60`;
1215                }
1216            });
1217    }
1218
1219    document.addEventListener('DOMContentLoaded', () => {
1220        const titleElement = document.querySelector('title');
1221        titleElement.setAttribute('data-original', titleElement.textContent);
1222        
1223        const stationLogo = document.getElementById('station-logo').querySelector('img');
1224        stationLogo.setAttribute('data-current-cover', stationLogo.src);
1225    });
1226
1227    setInterval(updateMetadata, 5000);
1228
1229    setInterval(() => {
1230        if (isPlaying && audio.paused && !manuallyStopped && !isRetrying && !retryTimeout) {
1231            attemptReconnect();
1232        }
1233    }, 3000);
1234
1235    document.getElementById('station-logo-clickable').addEventListener('click', () => {
1236        const stationList = document.getElementById('player-station-list');
1237        const toggleArrow = document.getElementById('station-toggle-arrow');
1238        const isOpen = stationList.style.display === 'block';
1239        
1240        if (!isOpen) {
1241            stationList.style.display = 'block';
1242            stationList.style.opacity = '0';
1243            stationList.style.transform = 'translate(-50%, 20px)';
1244            toggleArrow.style.transform = 'rotate(180deg)';
1245            
1246            requestAnimationFrame(() => {
1247                stationList.style.transition = 'opacity 0.3s, transform 0.3s';
1248                stationList.style.opacity = '1';
1249                stationList.style.transform = 'translate(-50%, 0)';
1250            });
1251        } else {
1252            stationList.style.opacity = '0';
1253            stationList.style.transform = 'translate(-50%, 20px)';
1254            toggleArrow.style.transform = 'rotate(0deg)';
1255            
1256            setTimeout(() => {
1257                stationList.style.display = 'none';
1258            }, 300);
1259        }
1260    });
1261
1262    document.querySelectorAll('.player-station-option').forEach(option => {
1263        option.addEventListener('mouseenter', () => {
1264            option.style.background = 'rgba(255, 255, 255, 0.1)';
1265            option.style.transform = 'translateX(5px)';
1266        });
1267        
1268        option.addEventListener('mouseleave', () => {
1269            option.style.background = 'transparent';
1270            option.style.transform = 'translateX(0)';
1271        });
1272        
1273        option.addEventListener('click', () => {
1274            currentStationPlayer = {
1275                id: option.dataset.id,
1276                url: option.dataset.url,
1277                logo: option.dataset.logo,
1278                color: option.dataset.color,
1279                metadataUrl: option.dataset.metadata,
1280                name: option.querySelector('span').textContent
1281            };
1282            
1283            stationLogo.src = currentStationPlayer.logo;
1284            applyStationThemeColor(currentStationPlayer.color);
1285            
1286            if (isAppleDevice() && appleMusicUrls[currentStationPlayer.id]) {
1287                window.open(appleMusicUrls[currentStationPlayer.id], '_blank');
1288                stationList.style.opacity = '0';
1289                stationList.style.transform = 'translate(-50%, 20px)';
1290                toggleArrow.style.transform = 'rotate(0deg)';
1291                setTimeout(() => {
1292                    stationList.style.display = 'none';
1293                }, 300);
1294                updateMetadata();
1295                return;
1296            }
1297
1298            manuallyStopped = false;
1299            audio.src = currentStationPlayer.url;
1300            audio.play();
1301            isPlaying = true;
1302            if (window.data) window.data.isPlaying = true;
1303            playButton.innerHTML = `
1304                <svg viewBox="0 0 24 24" width="30" height="30">
1305                    <path fill="currentColor" d="M6 6h12v12H6z"/>
1306                </svg>`;
1307            
1308            stationList.style.opacity = '0';
1309            stationList.style.transform = 'translate(-50%, 20px)';
1310            toggleArrow.style.transform = 'rotate(0deg)';
1311            setTimeout(() => {
1312                stationList.style.display = 'none';
1313            }, 300);
1314            
1315            updateMetadata();
1316        });
1317    });
1318
1319    document.addEventListener('click', (e) => {
1320        const stationList = document.getElementById('player-station-list');
1321        const stationLogo = document.getElementById('station-logo');
1322        const toggleArrow = document.getElementById('station-toggle-arrow');
1323        
1324        if (!stationList.contains(e.target) && !stationLogo.contains(e.target)) {
1325            stationList.style.display = 'none';
1326            toggleArrow.style.transform = 'rotate(0deg)';
1327        }
1328    });
1329
1330    function switchPlayerToStation(stationId) {
1331        if (currentStationPlayer.id === stationId) {
1332            return false;
1333        }
1334
1335        const correspondingPlayerStation = document.querySelector(`.player-station-option[data-id="${stationId}"]`);
1336        if (!correspondingPlayerStation) {
1337            return false;
1338        }
1339
1340        currentStationPlayer.id = correspondingPlayerStation.dataset.id;
1341        currentStationPlayer.url = correspondingPlayerStation.dataset.url;
1342        currentStationPlayer.logo = correspondingPlayerStation.dataset.logo;
1343        currentStationPlayer.color = correspondingPlayerStation.dataset.color;
1344        currentStationPlayer.metadataUrl = correspondingPlayerStation.dataset.metadata;
1345        currentStationPlayer.name = correspondingPlayerStation.querySelector('span').textContent;
1346
1347        stationLogo.src = currentStationPlayer.logo;
1348        applyStationThemeColor(currentStationPlayer.color);
1349
1350        if (isAppleDevice() && appleMusicUrls[currentStationPlayer.id]) {
1351            if (isPlaying) {
1352                window.open(appleMusicUrls[currentStationPlayer.id], '_blank');
1353            }
1354            updateMetadata();
1355            return true;
1356        }
1357
1358        if (isPlaying) {
1359            manuallyStopped = false;
1360            cancelRetry();
1361            audio.src = currentStationPlayer.url;
1362            audio.play();
1363            if (window.data) window.data.isPlaying = true;
1364            playButton.innerHTML = `
1365                <svg viewBox="0 0 24 24" width="30" height="30">
1366                    <path fill="currentColor" d="M6 6h12v12H6z"/>
1367                </svg>`;
1368        }
1369
1370        updateMetadata();
1371        return true;
1372    }
1373
1374    window.getPlayerStationId = function() {
1375        return currentStationPlayer.id;
1376    };
1377
1378    function updateSelectedStation(stationId) {
1379        if (stationId === selectedStationId) {
1380            return;
1381        }
1382        
1383        const option = document.querySelector(`.station-option[data-id="${stationId}"]`);
1384        
1385        if (!option) {
1386            return;
1387        }
1388
1389        const newStationImg = option.querySelector('img');
1390        const currentStationImg = document.querySelector('.current-station img');
1391        currentStationImg.src = newStationImg.src;
1392        currentStationImg.alt = newStationImg.alt;
1393
1394        const currentStationLink = document.querySelector('.current-station');
1395        currentStationLink.href = `${base_url}/${lang}/radio/${stationId}`;
1396
1397        const newColor = option.getAttribute('data-color');
1398        if (newColor) {
1399            applyStationThemeColor(newColor);
1400        }
1401
1402        document.querySelectorAll('.station-dependent-link').forEach(link => {
1403            const originalHref = link.href;
1404            const isRadioLink = originalHref.includes('/radio/');
1405            const isMusicLink = originalHref.includes('/music/');
1406            const section = isRadioLink ? 'radio' : (isMusicLink ? 'music' : null);
1407            
1408            if (section) {
1409                const basePath = `${base_url}/${lang}/${section}/${stationId}`;
1410                const subPath = link.getAttribute('data-path');
1411                link.href = basePath + subPath;
1412            }
1413        });
1414
1415        if (!isPlaying) {
1416            switchPlayerToStation(stationId);
1417        }
1418
1419        const stationSelector = document.querySelector('.station-selector');
1420        stationSelector.classList.remove('active');
1421        
1422        selectedStationId = stationId;
1423    }
1424
1425    const validStationIds = ["onlyhit","gold","japan","kpop","tophits"];
1426
1427    document.addEventListener('DOMContentLoaded', () => {
1428        const stationSelector = document.querySelector('.station-selector');
1429        const toggleButton = document.querySelector('.station-selector-toggle');
1430        const stationOptions = document.querySelectorAll('.station-option');
1431        const currentStation = document.querySelector('.current-station');
1432
1433        toggleButton.addEventListener('click', (e) => {
1434            e.stopPropagation();
1435            toggleButton.classList.toggle('active');
1436            const dropdown = stationSelector.querySelector('.station-dropdown');
1437            dropdown.style.display = toggleButton.classList.contains('active') ? 'block' : 'none';
1438        });
1439
1440        document.addEventListener('click', (e) => {
1441            if (!stationSelector.contains(e.target) || e.target.closest('.current-station')) {
1442                toggleButton.classList.remove('active');
1443                stationSelector.querySelector('.station-dropdown').style.display = 'none';
1444            }
1445        });
1446
1447        stationOptions.forEach(option => {
1448            option.addEventListener('click', () => {
1449                const stationId = option.getAttribute('data-id');
1450                updateSelectedStation(stationId);
1451
1452                const currentPath = window.location.pathname;
1453                const pathParts = currentPath.split('/');
1454                
1455                if (pathParts.filter(Boolean).length <= 1) {
1456                    const newUrl = `${base_url}/${lang}/radio/${stationId}`;
1457                    loadContent(newUrl, '', true);
1458                }
1459
1460                const sectionIndex = pathParts.indexOf('radio') !== -1 ? 
1461                    pathParts.indexOf('radio') : pathParts.indexOf('music');
1462                
1463                if (sectionIndex !== -1 && sectionIndex + 1 < pathParts.length) {
1464                    const currentStationOrSection = pathParts[sectionIndex + 1];
1465                    
1466                    if (validStationIds.includes(currentStationOrSection)) {
1467                        pathParts[sectionIndex + 1] = stationId;
1468                        const newUrl = pathParts.join('/');
1469                        loadContent(newUrl, '', true);
1470                    }
1471                }
1472
1473                toggleButton.classList.remove('active');
1474                stationSelector.querySelector('.station-dropdown').style.display = 'none';
1475            });
1476        });
1477    });
1478
1479    updateMetadata();
1480
1481    document.addEventListener('DOMContentLoaded', () => {
1482        if(document.querySelector('.captcha-container')){
1483            turnstile.render('.captcha-container', {
1484                sitekey: "0x4AAAAAAA2TThvP_ShS-Lu2",
1485            });
1486        };
1487    });
1488
1489
1490
1491        const menuToggle = document.querySelector('.menu-toggle');
1492        const navItems = document.querySelector('.nav-items');
1493        const navItemsWithSubmenu = document.querySelectorAll('.nav-item');
1494
1495        menuToggle.addEventListener('click', () => {
1496            navItems.classList.toggle('active');
1497        });
1498
1499        navItemsWithSubmenu.forEach(item => {
1500            item.addEventListener('click', (e) => {
1501                if (window.innerWidth <= 768) {
1502                    const clickedItem = e.currentTarget;
1503                    navItemsWithSubmenu.forEach(otherItem => {
1504                        if (otherItem !== clickedItem) {
1505                            otherItem.classList.remove('active');
1506                        }
1507                    });
1508                    clickedItem.classList.toggle('active');
1509                }
1510            });
1511        });
1512
1513        const stationSelector = document.querySelector('.station-selector');
1514        const currentStation = document.querySelector('.current-station');
1515        const stationOptions = document.querySelectorAll('.station-option');
1516
1517        currentStation.addEventListener('click', (e) => {
1518            stationSelector.classList.toggle('active');
1519        });
1520
1521        document.addEventListener('click', (e) => {
1522            if (!stationSelector.contains(e.target)) {
1523                stationSelector.classList.remove('active');
1524            }
1525        });
1526
1527    function setCookie(name, value, days) {
1528        if (!window.cookieConsent) return;
1529        const expires = new Date();
1530        expires.setTime(expires.getTime() + (days * 24 * 60 * 60 * 1000));
1531        document.cookie = `${name}=${value};expires=${expires.toUTCString()};path=/`;
1532    }
1533
1534    function getCookie(name) {
1535        const nameEQ = name + "=";
1536        const ca = document.cookie.split(';');
1537        for (let i = 0; i < ca.length; i++) {
1538            let c = ca[i];
1539            while (c.charAt(0) === ' ') c = c.substring(1, c.length);
1540            if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
1541        }
1542        return null;
1543    }
1544
1545    const savedVolume = getCookie('playerVolume');
1546    if (savedVolume !== null) {
1547        audio.volume = savedVolume;
1548        volumeControl.value = savedVolume;
1549        volumeControl.style.background = `linear-gradient(to right, var(--player-primary-color) 0%, var(--player-primary-color) ${savedVolume * 100}%, rgba(255, 255, 255, 0.1) ${savedVolume * 100}%, rgba(255, 255, 255, 0.1) 100%)`;
1550    }
1551
1552    function loadContent(url, content = '', pushState = true) {
1553        const urlParts = url.split('/');
1554        const sectionIndex = urlParts.indexOf('radio') !== -1 ? 
1555            urlParts.indexOf('radio') : urlParts.indexOf('music');
1556        const isStationSpecificPage = sectionIndex !== -1 && sectionIndex + 2 === urlParts.length;
1557
1558        if (isStationSpecificPage) {
1559            const headers = new Headers();
1560            headers.append('X-Custom-Header', 'loadContent');
1561        }
1562
1563        fetch(url, { 
1564            headers: new Headers({'X-Custom-Header': 'loadContent'})
1565        })
1566            .then(response => {
1567                return response.text().then(html => ({
1568                    ok: response.ok,
1569                    status: response.status,
1570                    html: html
1571                }));
1572            })
1573            .then(result => {
1574                const parser = new DOMParser();
1575                const doc = parser.parseFromString(result.html, 'text/html');
1576                
1577                const sections = ['main'];
1578                sections.forEach(section => {
1579                    const newContent = doc.querySelector(section);
1580                    const currentContent = document.querySelector(section);
1581                    if (newContent && currentContent) {
1582                        currentContent.innerHTML = newContent.innerHTML;
1583                    }
1584                });
1585                
1586                updatePageMetadata(doc);
1587                executeNewScripts(doc, sections);
1588
1589                if (pushState) {
1590                    history.pushState(
1591                        { url, content, scrollPosition: window.scrollY }, 
1592                        doc.title, 
1593                        url
1594                    );
1595                }
1596
1597                resetPageState();
1598                refreshAds();
1599                
1600                if (typeof fbq === 'function') {
1601                    fbq('track', 'PageView', {
1602                        page_path: url,
1603                        page_title: doc.title
1604                    });
1605                }
1606
1607                if (!result.ok) {
1608                    console.warn(`Page loaded with status: ${result.status}`);
1609                }
1610            })
1611            .catch(error => {
1612                console.error('Error loading content:', error);
1613            });
1614    }
1615
1616    function updatePageMetadata(doc) {
1617        const newTitle = doc.querySelector('title');
1618        if (newTitle) {
1619            document.title = newTitle.textContent;
1620        }
1621        
1622        const metaTags = doc.querySelectorAll('meta[name], meta[property]');
1623        metaTags.forEach(newMeta => {
1624            const selector = newMeta.getAttribute('name') ? 
1625                `meta[name="${newMeta.getAttribute('name')}"]` : 
1626                `meta[property="${newMeta.getAttribute('property')}"]`;
1627            const oldMeta = document.querySelector(selector);
1628            if (oldMeta) {
1629                oldMeta.setAttribute('content', newMeta.getAttribute('content'));
1630            }
1631        });
1632        const titleElement = document.querySelector('title');
1633        titleElement.setAttribute('data-original', titleElement.textContent);
1634    }
1635
1636    function executeNewScripts(doc, sections) {
1637        sections.forEach(section => {
1638            const newContent = doc.querySelector(section);
1639            if (newContent) {
1640                const scripts = newContent.getElementsByTagName('script');
1641                Array.from(scripts).forEach(script => {
1642                    if (script.src) {
1643                        const newScript = document.createElement('script');
1644                        newScript.src = script.src;
1645                        document.body.appendChild(newScript);
1646                    } else {
1647                        eval(script.textContent);
1648                    }
1649                });
1650                if(document.querySelector('.captcha-container')){
1651                turnstile.render('.captcha-container', {
1652                    sitekey: "0x4AAAAAAA2TThvP_ShS-Lu2",
1653                });
1654                }
1655            }
1656        });
1657    }
1658
1659    function resetPageState() {
1660        window.scrollTo(0, 0);
1661
1662        previewAudio.pause();
1663        previewAudio.currentTime = 0;
1664        previewAudio.src = "";
1665        audio.muted = false;
1666        
1667        if (activePreviewButton) {
1668            activePreviewButton.innerHTML = `
1669                <svg viewBox="0 0 24 24" width="24" height="24">
1670                    <path fill="currentColor" d="M8 5v14l11-7z"/>
1671                </svg>`;
1672            activePreviewButton = null;
1673        }
1674    }
1675
1676    window.onpopstate = function(event) {
1677        if (event.state) {
1678            const urlParts = window.location.pathname.split('/');
1679            const radioIndex = urlParts.indexOf('radio');
1680            if (radioIndex !== -1 && radioIndex + 1 < urlParts.length) {
1681                const stationId = urlParts[radioIndex + 1];
1682                updateSelectedStation(stationId);
1683            }
1684
1685            loadContent(event.state.url || window.location.pathname, '', false);
1686            if (event.state.scrollPosition) {
1687                window.scrollTo(0, event.state.scrollPosition);
1688            }
1689        } else {
1690            const urlParts = window.location.pathname.split('/');
1691            const radioIndex = urlParts.indexOf('radio');
1692            if (radioIndex !== -1 && radioIndex + 1 < urlParts.length) {
1693                const stationId = urlParts[radioIndex + 1];
1694                updateSelectedStation(stationId);
1695            }
1696            
1697            loadContent(window.location.pathname, '', false);
1698        }
1699    };
1700
1701    function isInternalUrl(url) {
1702        const baseDomain = 'onlyhit.us';
1703        try {
1704            if (url.startsWith('/') || url.startsWith('./') || url.startsWith('../')) {
1705                return true;
1706            }
1707            const urlObj = new URL(url);
1708            return urlObj.hostname === baseDomain;
1709        } catch {
1710            return false;
1711        }
1712    }
1713
1714
1715
1716    document.addEventListener('click', (e) => {
1717        const link = e.target.closest('a');
1718        if (!link) return;
1719
1720        const href = link.getAttribute('href');
1721        if (!href) return;
1722
1723        if (!href.startsWith('#')) {
1724            const navItems = document.querySelector('.nav-items');
1725            if (navItems) {
1726                navItems.classList.remove('active');
1727            }
1728        }
1729
1730        if (href.startsWith('#')) {
1731            e.preventDefault();
1732            const targetElement = document.querySelector(href);
1733            if (targetElement) {
1734                targetElement.scrollIntoView({ behavior: 'smooth' });
1735            }
1736            return;
1737        }
1738        
1739        if (link.getAttribute('target') === '_blank') {
1740            return;
1741        }
1742        
1743        if (isInternalUrl(link.href)) {
1744            e.preventDefault();
1745            const url = link.pathname + link.search + link.hash;
1746            loadContent(url, '', true);
1747        }
1748    });
1749
1750    let previewAudio = new Audio();
1751    let radioWasPlaying = false;
1752    let activePreviewButton = null;
1753
1754    document.addEventListener('click', (e) => {
1755        const previewButton = e.target.closest('.preview-button');
1756        if (!previewButton) return;
1757
1758        const previewUrl = previewButton.dataset.previewUrl;
1759        if (!previewUrl) return;
1760
1761        if (activePreviewButton === previewButton) {
1762            previewAudio.pause();
1763            previewAudio.currentTime = 0;
1764            activePreviewButton.innerHTML = `
1765                <svg viewBox="0 0 24 24" width="24" height="24">
1766                    <path fill="currentColor" d="M8 5v14l11-7z"/>
1767                </svg>`;
1768            activePreviewButton = null;
1769
1770                audio.muted = false;
1771        } else {
1772            if (activePreviewButton) {
1773                previewAudio.pause();
1774                previewAudio.currentTime = 0;
1775                activePreviewButton.innerHTML = `
1776                    <svg viewBox="0 0 24 24" width="24" height="24">
1777                        <path fill="currentColor" d="M8 5v14l11-7z"/>
1778                    </svg>`;
1779            }
1780
1781            activePreviewButton = previewButton;
1782            previewAudio.src = previewUrl;
1783            previewAudio.volume = volumeControl.value * 0.355;
1784            activePreviewButton.innerHTML = `
1785                <svg viewBox="0 0 24 24" width="24" height="24">
1786                    <path fill="currentColor" d="M6 6h12v12H6z"/>
1787                </svg>`;
1788
1789            radioWasPlaying = isPlaying;
1790            audio.muted = true;
1791
1792            previewAudio.play();
1793        }
1794    });
1795
1796    previewAudio.addEventListener('ended', () => {
1797        if (activePreviewButton) {
1798            activePreviewButton.innerHTML = `
1799                <svg viewBox="0 0 24 24" width="24" height="24">
1800                    <path fill="currentColor" d="M8 5v14l11-7z"/>
1801                </svg>`;
1802            activePreviewButton = null;
1803
1804                audio.muted = false;
1805        }
1806    });
1807
1808    document.addEventListener('DOMContentLoaded', () => {
1809        const userLanguage = navigator.language.split('-')[0];
1810        const currentLanguage = "en";
1811        const dismissedLanguageSuggestion = getCookie('dismissedLanguageSuggestion');
1812        const supportedLanguages = {"ar":"Arabic","bg":"Bulgarian","bn":"Bengali","bs":"Bosnian","ca":"Catalan","cs":"Czech","cy":"Welsh","da":"Danish","de":"German","el":"Greek, Modern","en":"English","es":"Spanish; Castilian","eu":"Basque","fa":"Persian","fi":"Finnish","fr":"French","fy":"Western Frisian","gl":"Galician","gu":"Gujarati","he":"Hebrew (modern)","hi":"Hindi","hr":"Croatian","ht":"Haitian; Haitian Creole","hu":"Hungarian","id":"Indonesian","is":"Icelandic","it":"Italian","ja":"Japanese","kn":"Kannada","ko":"Korean","ky":"Kirghiz, Kyrgyz","lt":"Lithuanian","lv":"Latvian","mk":"Macedonian","mr":"Marathi (Mar\u0101\u1e6dh\u012b)","ms":"Malay","mt":"Maltese","nb":"Norwegian Bokm\u00e5l","nl":"Dutch","no":"Norwegian","pl":"Polish","pt":"Portuguese","ro":"Romanian, Moldavian, Moldovan","ru":"Russian","sk":"Slovak","sl":"Slovene","sq":"Albanian","sr":"Serbian","sv":"Swedish","th":"Thai","tk":"Turkmen","tl":"Tagalog","tr":"Turkish","uk":"Ukrainian","vi":"Vietnamese","wa":"Walloon","zh":"Chinese"};
1813
1814        if (!dismissedLanguageSuggestion && 
1815            userLanguage !== currentLanguage && 
1816            supportedLanguages.hasOwnProperty(userLanguage)) {
1817
1818            const notification = document.createElement('div');
1819            notification.style.cssText = `
1820                position: fixed;
1821                bottom: 100px;
1822                right: 20px;
1823                background-color: var(--website-primary-color);
1824                color: white;
1825                padding: 15px 20px;
1826                border-radius: 8px;
1827                box-shadow: 0 2px 10px rgba(0,0,0,0.2);
1828                z-index: 1000;
1829                display: flex;
1830                align-items: center;
1831                gap: 15px;
1832                font-size: 14px;
1833                max-width: 400px;
1834                opacity: 0;
1835                transform: translateY(20px);
1836                transition: opacity 0.3s, transform 0.3s;
1837            `;
1838
1839                        notification.innerHTML = `
1840                <div>
1841                    Your browser is set to English. Would you like to view the site in English?                </div>
1842                <div style="display: flex; gap: 10px;">
1843                    <button onclick="switchLanguage('${userLanguage}')" style="
1844                        background: white;
1845                        color: var(--website-primary-color);
1846                        border: none;
1847                        padding: 5px 10px;
1848                        border-radius: 4px;
1849                        cursor: pointer;
1850                    ">Yes</button>
1851                    <button onclick="dismissLanguageSuggestion()" style="
1852                        background: transparent;
1853                        color: white;
1854                        border: 1px solid white;
1855                        padding: 5px 10px;
1856                        border-radius: 4px;
1857                        cursor: pointer;
1858                    ">Dismiss</button>
1859                </div>
1860            `;
1861
1862            document.body.appendChild(notification);
1863
1864            setTimeout(() => {
1865                notification.style.opacity = '1';
1866                notification.style.transform = 'translateY(0)';
1867            }, 100);
1868        }
1869    });
1870
1871    function switchLanguage(lang) {
1872        const currentPath = window.location.pathname;
1873        const newPath = currentPath.replace(/\/[a-z]{2}\//, `/${lang}/`);
1874        window.location.href = newPath;
1875    }
1876
1877    function dismissLanguageSuggestion() {
1878        setCookie('dismissedLanguageSuggestion', 'true', 30);
1879        
1880        const notification = document.querySelector('[style*="position: fixed"][style*="bottom: 100px"]');
1881        if (notification) {
1882            notification.style.opacity = '0';
1883            notification.style.transform = 'translateY(20px)';
1884            setTimeout(() => {
1885                notification.remove();
1886            }, 300);
1887        }
1888    }
1889
1890    function submitContactForm(e) {
1891        e.preventDefault();
1892        
1893        if (!turnstile.getResponse()) {
1894            alert('Please complete the CAPTCHA verification');
1895            return;
1896        }
1897
1898        const form = e.target;
1899        const subject = form.querySelector('#subject').value;
1900        const message = form.querySelector('#message').value;
1901        
1902        if (subject === 'general' && message.length < 40) {
1903            alert('For general inquiries, your message must be at least 40 characters.');
1904            return;
1905        }
1906        
1907        const formData = new FormData(form);
1908        
1909        fetch('/api/contact/submit', {
1910            method: 'POST',
1911            body: formData
1912        })
1913        .then(response => response.json())
1914        .then(data => {
1915            if (data.success) {
1916                form.innerHTML = `<div class="success-message">
1917                    Thank you for your message. We'll get back to you soon!                </div>`;
1918            } else {
1919                throw new Error(data.message || 'Submission failed');
1920            }
1921        })
1922        .catch(error => {
1923            console.error('Error:', error);
1924            const submitButton = form.querySelector('button[type="submit"]');
1925            submitButton.insertAdjacentHTML('afterend', `
1926                <p class="error-message">
1927                    Failed to send message. Please try again.                </p>
1928            `);
1929        });
1930    }
1931
1932    function toggleStationSelect() {
1933        const subjectSelect = document.getElementById('subject');
1934        const stationGroup = document.getElementById('stationSelectGroup');
1935        const stationSelect = document.getElementById('station');
1936        const songRequestMessage = document.getElementById('songRequestMessage');
1937        const generalSubjectMessage = document.getElementById('generalSubjectMessage');
1938        const messageTextarea = document.getElementById('message');
1939        const messageCharCount = document.getElementById('messageCharCount');
1940        
1941        messageTextarea.removeAttribute('minlength');
1942        messageCharCount.style.display = 'none';
1943        generalSubjectMessage.style.display = 'none';
1944        
1945        if (subjectSelect.value === 'song_request') {
1946            stationGroup.style.display = 'block';
1947            stationSelect.required = true;
1948            songRequestMessage.style.display = 'block';
1949        } else if (subjectSelect.value === 'general') {
1950            stationGroup.style.display = 'none';
1951            stationSelect.required = false;
1952            songRequestMessage.style.display = 'none';
1953            
1954            messageTextarea.setAttribute('minlength', '40');
1955            messageCharCount.style.display = 'block';
1956            
1957            const currentLength = messageTextarea.value.length;
1958            if (currentLength >= 1 && currentLength <= 40) {
1959                generalSubjectMessage.style.display = 'block';
1960            }
1961            
1962            updateCharCount();
1963        } else {
1964            stationGroup.style.display = 'none';
1965            stationSelect.required = false;
1966            songRequestMessage.style.display = 'none';
1967        }
1968    }
1969
1970    function updateCharCount() {
1971        const messageTextarea = document.getElementById('message');
1972        const messageCharCount = document.getElementById('messageCharCount');
1973        const generalSubjectMessage = document.getElementById('generalSubjectMessage');
1974        const subjectSelect = document.getElementById('subject');
1975        
1976        if (messageTextarea && messageCharCount) {
1977            const currentLength = messageTextarea.value.length;
1978            const minLength = messageTextarea.getAttribute('minlength');
1979            
1980            if (subjectSelect && subjectSelect.value === 'general') {
1981                if (currentLength >= 1 && currentLength <= 25) {
1982                    generalSubjectMessage.style.display = 'block';
1983                } else {
1984                    generalSubjectMessage.style.display = 'none';
1985                }
1986            }
1987            
1988            if (minLength && currentLength < parseInt(minLength)) {
1989                messageCharCount.textContent = `${currentLength}/${minLength} characters minimum`;
1990                messageCharCount.style.color = 'var(--website-primary-color, #007bff)';
1991            } else if (minLength) {
1992                messageCharCount.textContent = `${currentLength} characters`;
1993                messageCharCount.style.color = 'var(--text-secondary, rgba(255, 255, 255, 0.7))';
1994            } else {
1995                messageCharCount.textContent = '';
1996            }
1997        }
1998    }
1999
2000    document.addEventListener('DOMContentLoaded', function() {
2001        const messageTextarea = document.getElementById('message');
2002        
2003        if (messageTextarea) {
2004            messageTextarea.addEventListener('input', updateCharCount);
2005        }
2006        
2007        const subjectSelect = document.getElementById('subject');
2008        if (subjectSelect) {
2009            toggleStationSelect();
2010        }
2011    });
2012
2013    function submitNewsletter(e, type) {
2014        e.preventDefault();
2015        const email = e.target.querySelector('input[name="email"]').value;
2016        if(!type) {
2017            type = 'newsletter';
2018        }
2019        
2020        fetch('/api/newsletter/subscribe', {
2021            method: 'POST',
2022            headers: {
2023                'Content-Type': 'application/json',
2024            },
2025            body: JSON.stringify({
2026                email: email,
2027                type: type
2028            })
2029        })
2030        .then(response => response.json())
2031        .then(data => {
2032            if (data.success) {
2033                e.target.innerHTML = '<p class="success">Please confirm your subscription by clicking the link in the email we just sent you.</p>';
2034            } else {
2035                throw new Error(data.message || 'Subscription failed. Please try again.');
2036            }
2037        })
2038        .catch(error => {
2039            console.error('Error:', error);
2040            e.target.querySelector('button').insertAdjacentHTML('afterend', 
2041                        '<p class="error">Subscription failed. Please try again.</p>');
2042            });
2043    }
2044
2045    function refreshAds() {
2046        if (window.adsbygoogle && window.adsbygoogle.loaded) {
2047            var adElements = document.querySelectorAll('.adsbygoogle:not([data-adsbygoogle-status="done"])');
2048            if (adElements.length > 0) {
2049                for (var i = 0; i < adElements.length; i++) {
2050                    var adSlot = adElements[i].getAttribute('data-ad-slot');
2051                    var isAdSlotFilled = false;
2052
2053                    for (var j = 0; j < window.adsbygoogle.length; j++) {
2054                        try {
2055                            if (window.adsbygoogle[j].slot && window.adsbygoogle[j].slot.getSlotElementId() === adSlot) {
2056                                console.log("Ad slot found: ", adSlot);
2057                                isAdSlotFilled = true;
2058                                break;
2059                            }
2060                        } catch (error) {
2061                            console.error("Error checking ad slot: ", error);
2062                        }
2063                    }
2064
2065                if (!isAdSlotFilled) {
2066                    try {
2067                        console.log("Pushing ad slot: ", adSlot);
2068                        window.adsbygoogle = window.adsbygoogle || [];
2069                        adsbygoogle.push({});
2070                    } catch (pushError) {
2071                        console.error("Error pushing ad slot: ", pushError);
2072                    }
2073                }
2074                }
2075            } else {
2076                console.log("No ad elements found or all ad slots are filled.");
2077            }
2078        } else {
2079            setTimeout(refreshAds, 1000);
2080        }
2081    }
2082    refreshAds();
2083
2084    function createTrackElement(track) {
2085        const div = document.createElement('div');
2086        div.className = 'track-row';
2087        
2088        div.innerHTML = `
2089            <div class="track-row-cover">
2090                <img src="/cdn/${track.cover || 'fallback/cover_fallback.jpg'}?width=60" 
2091                     alt="${track.title}">
2092            </div>
2093            <div class="track-row-info">
2094                ${track.isrc ? 
2095                    `<a href="${base_url}/${lang}/music/track/${track.isrc}" 
2096                        class="track-row-title">${track.title}</a>` :
2097                    `<div class="track-row-title">${track.title}</div>`
2098                }
2099                <div class="track-row-artists">
2100                    ${track.artist.split(',').map(artist => 
2101                        `<a href="${base_url}/${lang}/music/artist/${encodeArtistSlug(artist.trim())}" 
2102                            class="track-row-artist-link">${artist.trim()}</a>`
2103                    ).join(', ')}
2104                </div>
2105            </div>
2106            ${track.preview ? `
2107                <div class="track-row-button-container">
2108                    <button class="preview-button" data-preview-url="${track.preview}" 
2109                            aria-label="Play preview">
2110                        <svg viewBox="0 0 24 24" width="24" height="24">
2111                            <path fill="currentColor" d="M8 5v14l11-7z"/>
2112                        </svg>
2113                    </button>
2114                </div>
2115            ` : ''}
2116        `;
2117        return div;
2118    }
2119
2120    let lastTrackId = null;
2121    let lastStationId = null;
2122
2123    function updateHistory() {
2124        const historyContainer = document.getElementById('dynamic-history');
2125        if(!historyContainer) return;
2126        const stationId = historyContainer.getAttribute('data-station');
2127        const limit = historyContainer.getAttribute('data-limit');
2128        if(lastStationId !== stationId) {
2129            lastStationId = stationId;
2130            lastTrackId = null;
2131        }
2132        fetch(`${base_url}/api/nowplaying/history?station=${stationId}&limit=${limit}`)
2133            .then(response => response.json())
2134            .then(tracks => {
2135                if (!tracks.length || tracks[0].id === lastTrackId) return;
2136                
2137                const historyContainer = document.getElementById('dynamic-history');
2138                
2139                if (!lastTrackId || historyContainer.children.length === 0) {
2140                    historyContainer.innerHTML = '';
2141                    
2142                    tracks.forEach(track => {
2143                        const trackElement = createTrackElement(track);
2144                        historyContainer.appendChild(trackElement);
2145                    });
2146                    lastTrackId = tracks[0].id;
2147                    return;
2148                }
2149                
2150                const newTrack = createTrackElement(tracks[0]);
2151                newTrack.style.transform = 'translateY(-100%)';
2152                newTrack.style.opacity = '0';
2153                historyContainer.insertBefore(newTrack, historyContainer.firstChild);
2154                
2155                Array.from(historyContainer.children).slice(1).forEac
2155h(track => {
2156                    track.style.transform = 'translateY(-100%)';
2157                    track.style.transition = 'none';
2158                });
2159                
2160                void historyContainer.offsetWidth;
2161                
2162                Array.from(historyContainer.children).forEach((track, index) => {
2163                    track.style.transition = 'transform 0.5s ease-out, opacity 0.5s ease-out';
2164                    if (index === 3) {
2165                        track.style.transform = 'translateY(100%)';
2166                        track.style.opacity = '0';
2167                        track.addEventListener('transitionend', () => {
2168                            if (track.parentNode === historyContainer) {
2169                                historyContainer.removeChild(track);
2170                            }
2171                        }, { once: true });
2172                    } else {
2173                        track.style.transform = 'translateY(0)';
2174                        track.style.opacity = '1';
2175                    }
2176                });
2177                
2178                lastTrackId = tracks[0].id;
2179            })
2180            .catch(error => console.error('Error updating history:', error));
2181    }
2182
2183    updateHistory();
2184
2185    setInterval(updateHistory, 5000);
2186</script>
2186
2187<!-- Adsense -->
2188<script type="text/plain" data-cookie-consent="targeting" async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-7468708296619588"
2189     crossorigin="anonymous"></script>
2189
2190<!-- end of Adsense-->
2191<script type="text/plain" data-cookie-consent="functionality">acceptCookies();</script>
2191
2192
2193</body>
2194</html>

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.