Download index.html from Guymy97/https-huggingface-co-spaces-guymy97: direct link, hf CLI and curl.
- Browser
- Download file 19 kB
-
https://huggingface.co/spaces/Guymy97/https-huggingface-co-spaces-guymy97/resolve/main/index.html
- Command line
-
hf download hf://spaces/Guymy97/https-huggingface-co-spaces-guymy97/index.html
-
curl -L -o index.html https://huggingface.co/spaces/Guymy97/https-huggingface-co-spaces-guymy97/resolve/main/index.html
19 kB
| === index.html === | |
| <html lang="fr"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover" /> | |
| <title>NeoIPTV - Connexion & Catalogue + Assistant IA</title> | |
| <meta name="color-scheme" content="dark light" /> | |
| <link rel="preconnect" href="https://fonts.googleapis.com" /> | |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> | |
| <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet" /> | |
| <link href="https://unpkg.com/boxicons@2.1.4/css/boxicons.min.css" rel="stylesheet"> | |
| <link rel="stylesheet" href="style.css" /> | |
| <script type="module"> | |
| import { pipeline } from 'https://cdn.jsdelivr.net/npm/@huggingface/transformers@3.7.3'; | |
| window.__TRANSFORMERS_PIPELINE__ = pipeline; | |
| </script> | |
| </head> | |
| <body> | |
| <header class="appbar"> | |
| <div class="appbar-inner"> | |
| <a class="brand" href="#" id="brandHome"> | |
| <div class="logo" aria-hidden="true"></div> | |
| <div> | |
| <h1>NeoIPTV</h1> | |
| <small>Connexion & Catalogue</small> | |
| </div> | |
| </a> | |
| <div class="top-actions"> | |
| <a href="#" id="scanBtn"><i class='bx bx-qr-scan'></i> Scanner QR</a> | |
| <a href="#" id="helpBtn"><i class='bx bx-help-circle'></i> Aide</a> | |
| </div> | |
| <div class="header-right"> | |
| <a class="anycoder" href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" rel="noopener">Built with anycoder</a> | |
| <div class="gpu-toggle"> | |
| <label class="switch"> | |
| <input type="checkbox" id="gpuToggle" aria-label="Activer l'exécution GPU (WebGPU)"> | |
| <span class="slider"></span> | |
| </label> | |
| <span id="gpuLabel" class="gpu-label" aria-live="polite">CPU</span> | |
| </div> | |
| <button class="theme-toggle" id="themeToggle" title="Basculer le thème" aria-label="Basculer le thème clair/sombre"><i class='bx bx-moon'></i></button> | |
| </div> | |
| </div> | |
| </header> | |
| <main> | |
| <section class="content"> | |
| <div class="hero"> | |
| <div class="hero-inner"> | |
| <h2>Vos chaînes, films et séries en un clic</h2> | |
| <p>Connectez-vous avec votre méthode préférée puis profitez du direct, de la VOD et des séries. Lecteur HLS intégré (m3u8).</p> | |
| </div> | |
| </div> | |
| <div class="tabs" role="tablist"> | |
| <button class="tab active" data-tab="connect" role="tab" aria-selected="true"><i class='bx bx-log-in-circle'></i> Connexion</button> | |
| <button class="tab" data-tab="live" role="tab" aria-selected="false"><i class='bx bx-play-circle'></i> Direct</button> | |
| <button class="tab" data-tab="vod" role="tab" aria-selected="false"><i class='bx bx-movie-play'></i> Films</button> | |
| <button class="tab" data-tab="series" role="tab" aria-selected="false"><i class='bx bx-collection'></i> Séries</button> | |
| <button class="tab" data-tab="favs" role="tab" aria-selected="false"><i class='bx bx-star'></i> Favoris</button> | |
| <button class="tab" data-tab="recent" role="tab" aria-selected="false"><i class='bx bx-time-five'></i> Récents</button> | |
| </div> | |
| <div class="toolbar" id="catalogToolbar"> | |
| <div class="searchbar"> | |
| <i class='bx bx-search' aria-hidden="true"></i> | |
| <input id="searchInput" type="search" placeholder="Rechercher dans tous les onglets…" aria-label="Rechercher"/> | |
| <button id="clearSearch" title="Effacer" class="btn ghost" aria-label="Effacer la recherche" style="border:none;background:transparent;color:var(--muted);padding:0;display:grid;place-items:center"><i class='bx bx-x'></i></button> | |
| </div> | |
| <div class="filters" role="group" aria-label="Filtres"> | |
| <button class="filter-chip active" data-filter="all" aria-pressed="true"><i class='bx bx-layer'></i> Tous</button> | |
| <button class="filter-chip" data-filter="hd" aria-pressed="false"><i class='bx bx-video'></i> HD/4K</button> | |
| <button class="filter-chip" data-filter="recent" aria-pressed="false"><i class='bx bx-bolt-circle'></i> Nouveautés</button> | |
| </div> | |
| </div> | |
| <section id="grid-connect" class="card page" aria-label="Connexion" style="padding: clamp(16px, 2.5vw, 22px);"> | |
| <div class="connect-wrap"> | |
| <div class="connect-panel"> | |
| <div class="connect-tabs" role="tablist" aria-label="Modes de connexion"> | |
| <button class="connect-tab active" data-mode="mac"><i class='bx bx-barcode'></i> Code MAC</button> | |
| <button class="connect-tab" data-mode="xtreme"><i class='bx bx-link'></i> Xtream Codes</button> | |
| <button class="connect-tab" data-mode="m3u"><i class='bx bx-file'></i> M3U/M3U8</button> | |
| <button class="connect-tab" data-mode="qr"><i class='bx bx-qr'></i> QR Code</button> | |
| </div> | |
| <form id="form-mac" class="form" autocomplete="on" novalidate> | |
| <div class="field"> | |
| <label for="macAddress">Adresse MAC</label> | |
| <div class="input"> | |
| <i class='bx bx-chip' aria-hidden="true"></i> | |
| <input id="macAddress" name="mac" inputmode="text" placeholder="AB:CD:EF:12:34:56" maxlength="17" aria-describedby="macHelp" /> | |
| </div> | |
| <div class="helper" id="macHelp">Format accepté: XX:XX:XX:XX:XX:XX (lettres et chiffres)</div> | |
| </div> | |
| <div class="field"> | |
| <label for="portalMac">Portail</label> | |
| <div class="input"> | |
| <i class='bx bx-globe' aria-hidden="true"></i> | |
| <input id="portalMac" name="portal" placeholder="https://mon-portail.example.com" /> | |
| </div> | |
| </div> | |
| <div class="cta"> | |
| <button type="button" class="btn" id="loginMac"><i class='bx bx-log-in'></i> Se connecter</button> | |
| <button type="button" class="btn secondary" id="genMac"><i class='bx bx-dice-6'></i> Générer MAC</button> | |
| </div> | |
| <div class="success" id="macSuccess" role="status"><i class='bx bx-check-shield'></i> Connecté (démo) — vos playlists seront chargées.</div> | |
| <div class="error" id="macError" role="alert"><i class='bx bx-error'></i> MAC invalide. Vérifiez le format.</div> | |
| </form> | |
| <form id="form-xtreme" class="form hidden" autocomplete="on" novalidate> | |
| <div class="row-2"> | |
| <div class="field"> | |
| <label for="xtHost">Hôte/URL</label> | |
| <div class="input"> | |
| <i class='bx bx-globe' aria-hidden="true"></i> | |
| <input id="xtHost" placeholder="ex: http://example.com:8080" /> | |
| </div> | |
| </div> | |
| <div class="field"> | |
| <label for="xtProtocol">Protocole</label> | |
| <div class="input"> | |
| <i class='bx bx-traffic-barrier' aria-hidden="true"></i> | |
| <select id="xtProtocol"> | |
| <option value="http">HTTP</option> | |
| <option value="https">HTTPS</option> | |
| </select> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="row-2"> | |
| <div class="field"> | |
| <label for="xtUser">Utilisateur</label> | |
| <div class="input"> | |
| <i class='bx bx-user' aria-hidden="true"></i> | |
| <input id="xtUser" placeholder="username" /> | |
| </div> | |
| </div> | |
| <div class="field"> | |
| <label for="xtPass">Mot de passe</label> | |
| <div class="input"> | |
| <i class='bx bx-lock-alt' aria-hidden="true"></i> | |
| <input id="xtPass" type="password" placeholder="password" /> | |
| </div> | |
| </div> | |
| </div> | |
| <div class="cta"> | |
| <button type="button" class="btn" id="loginXtream"><i class='bx bx-log-in'></i> Se connecter</button> | |
| <button type="button" class="btn secondary" id="testXtream"><i class='bx bx-plug'></i> Tester</button> | |
| </div> | |
| <div class="success" id="xtSuccess" role="status"><i class='bx bx-check-shield'></i> Authentification réussie (démo).</div> | |
| <div class="error" id="xtError" role="alert"><i class='bx bx-error'></i> Paramètres Xtream incomplets.</div> | |
| </form> | |
| <form id="form-m3u" class="form hidden" autocomplete="on" novalidate> | |
| <div class="field"> | |
| <label for="m3uUrl">URL de la playlist M3U/M3U8</label> | |
| <div class="input"> | |
| <i class='bx bx-link-external' aria-hidden="true"></i> | |
| <input id="m3uUrl" placeholder="https://.../playlist.m3u8" /> | |
| </div> | |
| </div> | |
| <div class="field"> | |
| <label for="m3uEpg">URL EPG (optionnel)</label> | |
| <div class="input"> | |
| <i class='bx bx-calendar-event' aria-hidden="true"></i> | |
| <input id="m3uEpg" placeholder="https://.../guide.xml" /> | |
| </div> | |
| </div> | |
| <div class="cta"> | |
| <button type="button" class="btn" id="loadM3u"><i class='bx bx-cloud-download'></i> Charger</button> | |
| <button type="button" class="btn secondary" id="demoM3u"><i class='bx bx-line-chart'></i> Utiliser démo</button> | |
| </div> | |
| <div class="success" id="m3uSuccess" role="status"><i class='bx bx-check-shield'></i> Playlist chargée (démo).</div> | |
| <div class="error" id="m3uError" role="alert"><i class='bx bx-error'></i> URL non valide.</div> | |
| </form> | |
| <div id="form-qr" class="form hidden"> | |
| <div class="field"> | |
| <label>Scanner un QR Code</label> | |
| <div class="qr-box" id="qrBox"> | |
| <i class='bx bx-qr' style="font-size: 56px; color: var(--muted)"></i> | |
| </div> | |
| <div class="helper">Autorisez l’accès à la caméra pour scanner (démo non connectée au flux caméra).</div> | |
| </div> | |
| <div class="cta"> | |
| <button type="button" class="btn" id="startQr"><i class='bx bx-camera'></i> Démarrer</button> | |
| <button type="button" class="btn secondary" id="pasteQr"><i class='bx bx-clipboard'></i> Coller un contenu</button> | |
| </div> | |
| <div class="success" id="qrSuccess" role="status"><i class='bx bx-check-shield'></i> QR lu (démo) — paramètres appliqués.</div> | |
| <div class="error" id="qrError" role="alert"><i class='bx bx-error'></i> Lecture QR impossible.</div> | |
| </div> | |
| </div> | |
| <div class="connect-panel"> | |
| <h3 style="margin:0 0 10px;font-size:16px">Aperçu de session</h3> | |
| <div class="empty" id="sessionEmpty"> | |
| <i class='bx bx-id-card' style="font-size: 28px;"></i> | |
| <div>Non connecté. Choisissez un mode de connexion à gauche.</div> | |
| </div> | |
| <div id="sessionInfo" class="hidden" aria-live="polite"> | |
| <div class="tag" id="sessionMode">Mode: -</div> | |
| <div style="height:8px"></div> | |
| <div class="grid" style="--card-w: 180px;" id="sessionPreview"></div> | |
| <div style="height:10px"></div> | |
| <div class="cta"> | |
| <button class="btn" id="goToLive"><i class='bx bx-television'></i> Aller au Direct</button> | |
| <button class="btn secondary" id="disconnect"><i class='bx bx-power-off'></i> Se déconnecter</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| </section> | |
| <section id="page-live" class="page hidden" aria-label="Direct"> | |
| <div class="card" style="padding:14px; margin-bottom:12px;"> | |
| <div style="display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap"> | |
| <div style="display:flex;align-items:center;gap:10px"> | |
| <i class='bx bx-broadcast' style="color:var(--accent)"></i> | |
| <strong>Direct — Chaînes TV</strong> | |
| </div> | |
| <div class="pager"> | |
| <button class="page-btn" id="livePrev" aria-label="Page précédente"><i class='bx bx-left-arrow'></i></button> | |
| <span class="pill" id="livePageInfo">Page 1</span> | |
| <button class="page-btn" id="liveNext" aria-label="Page suivante"><i class='bx bx-right-arrow'></i></button> | |
| </div> | |
| </div> | |
| </div> | |
| <div id="grid-live" class="grid" role="region" aria-label="Chaînes en direct"></div> | |
| </section> | |
| <section id="page-vod" class="page hidden" aria-label="Films"> | |
| <div class="card" style="padding:14px; margin-bottom:12px;"> | |
| <div style="display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap"> | |
| <div style="display:flex;align-items:center;gap:10px"> | |
| <i class='bx bx-film' style="color:var(--primary)"></i> | |
| <strong>Films — VOD</strong> | |
| </div> | |
| <div class="pager"> | |
| <button class="page-btn" id="vodPrev" aria-label="Page précédente"><i class='bx bx-left-arrow'></i></button> | |
| <span class="pill" id="vodPageInfo">Page 1</span> | |
| <button class="page-btn" id="vodNext" aria-label="Page suivante"><i class='bx bx-right-arrow'></i></button> | |
| </div> | |
| </div> | |
| </div> | |
| <div id="grid-vod" class="grid" role="region" aria-label="Films VOD"></div> | |
| </section> | |
| <section id="page-series" class="page hidden" aria-label="Séries"> | |
| <div class="card" style="padding:14px; margin-bottom:12px;"> | |
| <div style="display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap"> | |
| <div style="display:flex;align-items:center;gap:10px"> | |
| <i class='bx bx-collection' style="color:var(--warn)"></i> | |
| <strong>Séries TV</strong> | |
| </div> | |
| <div class="pager"> | |
| <button class="page-btn" id="seriesPrev" aria-label="Page précédente"><i class='bx bx-left-arrow'></i></button> | |
| <span class="pill" id="seriesPageInfo">Page 1</span> | |
| <button class="page-btn" id="seriesNext" aria-label="Page suivante"><i class='bx bx-right-arrow'></i></button> | |
| </div> | |
| </div> | |
| </div> | |
| <div id="grid-series" class="grid" role="region" aria-label="Séries"></div> | |
| </section> | |
| <section id="page-favs" class="page hidden" aria-label="Favoris"> | |
| <div class="empty"><i class='bx bx-star'></i> Aucun favori pour le moment.</div> | |
| </section> | |
| <section id="page-recent" class="page hidden" aria-label="Récents"> | |
| <div class="empty"><i class='bx bx-time-five'></i> Historique vide.</div> | |
| </section> | |
| </section> | |
| </main> | |
| <dialog class="player" id="playerDialog" aria-label="Lecteur vidéo"> | |
| <div class="player-card"> | |
| <div class="player-top"> | |
| <video id="video" playsinline controls></video> | |
| <div id="videoFallback" class="video-fallback" hidden> | |
| <i class='bx bx-error-circle'></i> | |
| <span>Votre navigateur ne supporte pas HLS natif. Utilisez un lien externe.</span> | |
| </div> | |
| </div> | |
| <div class="player-bottom"> | |
| <div class="player-actions"> | |
| <span class="chip" id="currentTitle">Titre</span> | |
| <span class="chip" id="currentQuality">HLS</span> | |
| <button class="close" id="closePlayer" aria-label="Fermer le lecteur"><i class='bx bx-x'></i> Fermer</button> | |
| </div> | |
| <div class="helper">Astuce: double-clic pour plein écran.</div> | |
| </div> | |
| </div> | |
| </dialog> | |
| <div class="overlay" id="sheetOverlay" aria-hidden="true"></div> | |
| <div class="fab" id="fabIa" aria-label="Assistant IA"> | |
| <i class='bx bx-bot'></i> | |
| </div> | |
| <section class="ia-panel hidden" id="iaPanel" aria-label="Assistant IA"> | |
| <div class="ia-header"> | |
| <i class='bx bx-bot' style="color:var(--primary)"></i> | |
| <div> | |
| <div class="title">Assistant IA</div> | |
| <div class="muted">Recherche sémantique pour vos contenus</div> | |
| </div> | |
| <div class="spacer" style="flex:1"></div> | |
| <span class="pill" id="modelBadge">Chargement…</span> | |
| </div> | |
| <div class="ia-prompt"> | |
| <input id="iaInput" type="text" placeholder="Demandez un film d'action récent, une chaîne sport, etc." aria-label="Entrer une requête" /> | |
| <button id="iaSearchBtn" class="btn" aria-label="Rechercher"><i class='bx bx-search-alt-2'></i> Rechercher</button> | |
| </div> | |
| <div class="ia-actions"> | |
| <button class="ia-chip" data-quick="match de foot en direct">Foot en direct</button> | |
| <button class="ia-chip" data-quick="comédie familiale">Comédie familiale</button> | |
| <button class="ia-chip" data-quick="série policière">Série policière</button> | |
| <button class="ia-chip" data-quick="film action 4K récent">Action 4K</button> | |
| </div> | |
| <div class="ia-results" id="iaResults" role="list"></div> | |
| <div class="ia-footer"> | |
| <div class="ia-status" id="iaStatus">Modèle non chargé</div> | |
| <div class="row"> | |
| <span class="kbd">GPU</span> | |
| <span class="kbd" id="gpuState">off</span> | |
| </div> | |
| </div> | |
| </section> | |
| <footer> | |
| <div class="credits"> | |
| <span class="tag">NeoIPTV démo</span> | |
| <span class="tag">HLS</span> | |
| <span class="tag" id="webgpuTag">WebGPU: test…</span> | |
| </div> | |
| <small class="muted">Ceci est une démo front-end. Aucun service externe n'est contacté sauf pour charger le modèle localement via transformers.js CDN.</small> | |
| </footer> | |
| <script src="index.js" type="module"></script> | |
| </body> | |
| </html> | |
| === index.js === | |
| /* NeoIPTV - Application front démo avec Assistant IA (transformers.js) | |
| - Grilles de contenus simulées | |
| - Lecteur HLS basique (m3u8), avec fallback message si non supporté | |
| - Assistant IA: text-classification pour requêtes et recommandation simple | |
| - WebGPU toggle si supporté | |
| */ | |
| const $ = (sel, root = document) => root.querySelector(sel); | |
| const $$ = (sel, root = document) => Array.from(root.querySelectorAll(sel)); | |
| /* THEME */ | |
| const themeToggle = $("#themeToggle"); | |
| const prefersDark = window.matchMedia && window.matchMedia("(prefers-color-scheme: dark)").matches; | |
| function applyTheme(theme) { | |
| document.documentElement.dataset.theme = theme; | |
| themeToggle.innerHTML = theme | |
| === style.css === | |
| :root { | |
| --bg: #0c0f14; | |
| --bg-soft: #121621; | |
| --surface: #141927; | |
| --elev: #192033; | |
| --txt: #e7ebf3; | |
| --muted: #9aa7c7; | |
| --primary: # |