iArt.ai
AI 모션 그래픽 소프트웨어, 누구나 사용할 수 있는 After Effects 대안, 텍스트 프롬프트로 몇 분 안에 애니메이션·설명 영상 제작
영화·시리즈·애니메이션을 한 곳에서, 진행 상황·새 에피소드·동기화 리스트 제공, 광고·추적 없이 무료
Suis tes films, séries et anime au même endroit : où tu en es, les nouveaux épisodes, ta liste synchronisée partout. Gratuit, sans pub, sans pistage, hébergé dans l'UE.
미디어JavaScript · HTMLGitHub @BixSopy온라인운영자 미확인
써 보셨어요? 한 번만 눌러 주세요. 로그인은 필요 없어요.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기README 전체를 불러오는 중입니다. 아래는 저장된 발췌입니다.
Suivi perso pour films, séries, anime avec aesthetic OLED dark inspiré de Plex. Service gratuit, sans publicité, ouvert à tous : https://cinepisode.com (l'ancienne adresse https://watchlist-omega-three.vercel.app continue de fonctionner). Le dépôt garde son nom watchlist ; le nom public, le domaine, les couleurs et le logo se règlent dans un seul fichier : brand.config.json (voir Marque).README 전문 보기 ↗
Suivi perso pour films, séries, anime avec aesthetic OLED dark inspiré de Plex. Service gratuit, sans publicité, ouvert à tous : https://cinepisode.com (l'ancienne adresse https://watchlist-omega-three.vercel.app continue de fonctionner).
Le dépôt garde son nom
watchlist; le nom public, le domaine, les couleurs et le logo se règlent dans un seul fichier :brand.config.json(voir Marque).
#0a0a0c)M, volume réglable) : fichiers courts dans sounds/ + synthèse Web AudioCrédits sons : sounds/open.mp3, close.mp3, add.mp3, done.mp3 — Kenney Interface Sounds
(maximize_008, minimize_008, confirmation_001, confirmation_004), licence CC0 ; sounds/del.mp3, err.mp3 —
Mixkit (n° 1120 « Modern click box check », n° 2569 « Negative tone interface tap »), licence
gratuite Mixkit (sans attribution obligatoire). Les autres sons (clic, survol, épisode suivant, alerte) sont synthétisés.
js/00-*.js … js/20-*.js/api, clés côté serveur)/api, région fra1) + Supabase Free (Francfort)supabase/templates/branding/legal/), attribution TMDB dans le pied de page.vendor/ (version
figée, SRI), les polices sont dans fonts/. Seule exception : le script Turnstile
(challenges.cloudflare.com), chargé uniquement à l'ouverture d'un formulaire de compte
et seulement si TURNSTILE_SITE_KEY est définie.vercel.json : CSP stricte (Turnstile seul autorisé en script-src /
frame-src), Referrer-Policy: strict-origin (Turnstile a besoin de l'origine),
Permissions-Policy, frame-ancestors 'none', HSTS.onclick=, onchange=…) : la CSP ne contient pas
script-src-attr 'unsafe-inline', donc un attribut injecté ne peut rien exécuter. Les boutons
portent data-click="action" (+ data-args en JSON) et js/00-actions.js appelle l'action
correspondante dans une liste fermée (tests/csp.test.js vérifie qu'il n'en reste aucun).brand.config.json › indexable: true) : l'accueil et les pages légales sont
indexables uniquement sur cinepisode.com (meta robots index, canonical,
robots.txt, sitemap.xml) ; X-Robots-Tag: noindex reste envoyé sur tout autre hôte
(previews, *.vercel.app) et sur /api/..vercelignore (liste blanche) : seuls index.html, les deux pages légales, robots.txt,
sitemap.xml, js/, api/,
vendor/, fonts/, icons/, sounds/, manifest.json, sw.js et vercel.json sont publiés./api : session Supabase obligatoire et email confirmé, liste blanche de chemins
et paramètres, quotas quotidiens par compte (consume_api_quota, voir la migration
), cache OMDb partagé pour tenir dans les 1 000 requêtes/jour de la clé.npx vercel dev # sert l'app et les fonctions /api (variables dans .env.local, non versionné)
node --test tests/ # tests unitaires : /api (fetch simulé), comptes, marque, migrations SQL*
cd e2e && npm install && npm test # parcours de compte dans un vrai Chrome (Supabase simulé, CSP de prod)
bash scripts/test-migrations.sh # migrations rejouées sur un Postgres local jetable
scripts/email-previews.sh # aperçus PNG des emails (Go + Chrome), dans ./email-previews/
* le test SQL est ignoré si Postgres n'est pas installé. e2e/ utilise le Chrome du système
(CHROME_PATH pour un autre navigateur ; SCREENSHOTS=dossier pour des captures).
Ajouter X sélectionné(s)Tout ce qui identifie l'app est dans brand.config.json : nom
(name, shortName, wordmark), slogan, domaine de production (baseUrl), adresses
(contactEmail, senderEmail, senderName), couleurs, chemins du logo et des icônes,
polices, indexation (indexable), redirections de domaine (domains).
Pour renommer l'app, changer de domaine, de couleurs ou de logo :
brand.config.json (et, pour un nouveau logo, remplacer branding/logo-mark.svg
et les PNG de icons/ aux chemins indiqués dans logo).node scripts/build-brand.mjs. Il régénère js/00-brand.js, manifest.json, les
blocs <!--brand:…--> / /*brand:css*/ d'index.html (titre, balises Open Graph, couleurs
CSS, logo, pied de page, balises de script des langues), confidentialite.html,
conditions.html, privacy.html, terms.html, vercel.json (X-Robots-Tag par hôte,
redirections, réécritures /fr et /en), robots.txt, sitemap.xml et les gabarits
d'emails supabase/templates/*.html +
subjects.json.scripts/email-previews.sh
pour vérifier le rendu.Les textes sources sont dans branding/ (emails : branding/emails/, pages légales :
branding/legal/) avec des marqueurs [[name]], [[contactEmail]]… ; ne jamais modifier les
fichiers générés à la main : node --test tests/ échoue s'ils ne sont plus à jour
(node scripts/build-brand.mjs --check). Aucun domaine n'est codé en dur dans le code de
l'app : elle fonctionne sur n'importe quel domaine (chemins relatifs, liens d'emails basés sur
l'adresse depuis laquelle la demande a été faite).
Tout existe en français et en anglais : interface, messages d'erreur (y compris ceux de Supabase), emails, pages légales, extension navigateur. L'app de bureau affiche le site, donc suit la même langue.
js/i18n/fr.js et js/i18n/en.js (mêmes clés, vérifiées par
tests/i18n.test.js), lus par js/00-i18n.js (t('clé', {var}), tn() pour les pluriels,
fmtDate / fmtNum via Intl). Textes d'index.html : attributs data-i18n et
data-i18n-attr. Choix de la langue : /fr, /en ou ?lang= dans l'adresse > choix
enregistré (localStorage wl_lang) > langue du navigateur (fr* → français, sinon
anglais). Sélecteur dans les réglages, la fenêtre de connexion et le pied de page.fr-FR (plateformes FR) ou en-US (plateformes US) ;
la langue fait partie de la clé de cache du proxy. Les titres déjà enregistrés dans une liste
ne sont jamais réécrits.{{ .Data.lang }} (= user_metadata.lang, enregistré à l'inscription et à chaque
changement de langue). Sans langue (comptes existants) : français. Les objets ne pouvant pas
être conditionnels dans l'interface Supabase, subjects.json donne un objet bilingue
(subject) ; subjectConditional est une variante qui choisit la langue, non testée chez
Supabase. Après toute modification, recoller les 8 modèles et objets (voir plus bas).branding/legal/fr/* → /confidentialite, /conditions ;
branding/legal/en/* → /privacy, /terms (en cas de divergence, la version française
prévaut).js/i18n/en.js en js/i18n/<code>.js, traduire, puis
node scripts/build-brand.mjs (balise de script, hreflang, sitemap, réécriture /<code>).
Facultatif : branding/emails/<code>/ et branding/legal/<code>/ (sinon emails dans la
langue par défaut, pages légales en anglais) ; la bascule des emails est générée pour chaque
langue disposant de modèles.Aucune clé TMDB ni OMDb n'est présente côté client. Les appels passent par des fonctions
serverless Vercel (api/tmdb.js, api/omdb.js, api/config.js) qui :
Authorization: Bearer <access_token>, vérifiée auprès
de /auth/v1/user) d'un compte à l'email confirmé ;api_quota_limits) ;/api lors d'un changement de domaine.Variables d'environnement Vercel (Production et Preview) :
| Variable | Obligatoire | Rôle |
|---|---|---|
TMDB_API_KEY | oui | Clé TMDB v3 (ou jeton de lecture v4) |
OMDB_API_KEY | oui | Clé OMDb (offre gratuite : 1 000 requêtes/jour) |
SUPABASE_ANON_KEY | oui | Clé publique (anon/publishable) du projet, pour vérifier les sessions et appeler consume_api_quota |
SUPABASE_URL | non | URL du projet Supabase (valeur par défaut : celle de l'app) |
SUPABASE_SECRET_KEY | recommandé | Clé secrète (sb_secret_…, ou ancienne service_role) : uniquement pour le cache OMDb partagé (api_cache). Sans elle, cache en mémoire par instance seulement |
TURNSTILE_SITE_KEY | recommandé | Clé de site Cloudflare Turnstile (publique). Vide = pas de CAPTCHA affiché |
SIGNUPS_OPEN | non | 0 masque l'onglet « Créer un compte » (les inscriptions se ferment vraiment dans Supabase) |
ALLOWED_EMAILS | non | À vider pour l'ouverture publique. Si renseignée, seuls ces emails accèdent au catalogue |
GITHUB_TOKEN | non | Pour api/releases.js (mises à jour de l'app de bureau) |
RESEND_API_KEY | pour les avis | Clé API Resend « Sending access » limitée au domaine cinepisode.com (à créer à part, ne pas réutiliser celle du SMTP Supabase) : email de notification de api/feedback.js. Sans elle, les avis sont seulement enregistrés en base |
FEEDBACK_TO | non | Destinataire des avis (défaut : [email protected], transféré vers Gmail par ImprovMX) |
FEEDBACK_FROM | non | Expéditeur des avis (défaut : Cinepisode <[email protected]>, domaine vérifié dans Resend) |
Avis (« Donner mon avis ») : POST /api/feedback (avec ou sans compte) valide le message, filtre les
robots (champ piège, délai minimum, même origine), enregistre l'avis par submit_feedback() avec
SUPABASE_SECRET_KEY (migration 20261008210000_feedback.sql : table feedback sans aucun accès client,
limites par profil, par empreinte d'IP du jour et globale, conservation 24 mois) puis envoie un email
texte [Cinepisode] Avis · <type> · <extrait> avec Reply-To = l'adresse donnée. SUPABASE_SECRET_KEY
et RESEND_API_KEY doivent être définies en Production (et en Preview pour tester un aperçu).
Projet Supabase batfulcvvquffgfeppcx, projet Vercel prj_FnDTFQQIs17MYUdwon10sPbndXQu.
0. Clés d'API à renouveler (audit du 08/10/2026) : la clé TMDB v3 et la clé OMDb ont été publiques (code client servi en ligne de juin au 25/09/2026, et toujours visibles dans l'historique git). Tant qu'elles ne sont pas renouvelées, n'importe qui peut les utiliser sans passer par le proxy ni par les quotas.
TMDB_API_KEY et OMDB_API_KEY en les
recréant avec le type Sensitive (valeur illisible après enregistrement), puis redéployer.1. Base de données (avant ou après le déploiement, l'ancienne version est compatible)
supabase/migrations/20261008100000_ouverture_publique.sql en une fois.supabase migration repair --status applied 20260925151457 (cette migration est
déjà appliquée en base mais absente de l'historique) puis ... applied 20261008100000.2. Cloudflare Turnstile (gratuit) : créer un widget « Managed », hostnames
cinepisode.com, www.cinepisode.com, watchlist-omega-three.vercel.app. Noter la clé de site
et la clé secrète.
3. Vercel › Settings › Environment Variables : vider/supprimer ALLOWED_EMAILS ; ajouter
TURNSTILE_SITE_KEY (clé de site) et SUPABASE_SECRET_KEY (Supabase › Settings › API Keys ›
Secret keys) ; garder les autres. Redéployer.
4. Supabase › Authentication (après le déploiement de cette version)
TURNSTILE_SITE_KEY déployée, sinon plus
personne ne peut se connecter.https://cinepisode.com ; Redirect URLs :
https://cinepisode.com/**, https://www.cinepisode.com/**,
https://watchlist-omega-three.vercel.app/** et, pour tester les previews,
https://*-pierre-unbekand-s-projects.vercel.app/**.vercel.app) : voir « Domaine cinepisode.com » plus bas.
Ensuite Rate Limits : « emails envoyés » à 30/h ou plus.supabase/templates/<fichier>.html
(versions française et anglaise dans le même fichier) et le sujet bilingue (subject) indiqué
dans supabase/templates/subjects.json :
Confirm sign up = confirmation, Invite user = invite, Magic link = magic_link,
Change email address = email_change, Reset password = recovery,
Reauthentication = reauthentication. Dans Security notifications (si disponible),
activer « Password changed » (password_changed_notification) et « Email address changed »
(email_changed_notification).5. Vérifier : créer un compte avec une adresse perso, recevoir l'email, cliquer, chercher un titre, supprimer le compte.
prj_FnDTFQQIs17MYUdwon10sPbndXQu › Domains :
cinepisode.com sert l'app, www.cinepisode.com redirige vers l'apex (307 ; « 308
permanent » est préférable pour le référencement, réglable dans Domains ›
www.cinepisode.com › Edit). Vérifier que le certificat HTTPS de www est bien émis.
watchlist-omega-three.vercel.app reste attaché (app de bureau, anciens favoris).https://cinepisode.com ;
Redirect URLs : ajouter https://cinepisode.com/** et https://www.cinepisode.com/**
(garder https://watchlist-omega-three.vercel.app/** et celle des previews).cinepisode.com ; recopier exactement les enregistrements affichés dans
Vercel › Domains › cinepisode.com › DNS Records (en général : MX + TXT SPF sur
send.cinepisode.com, TXT DKIM sur resend._domainkey.cinepisode.com ; parfois des
CNAME pour les domaines récents). Ajouter aussi un DMARC : TXT _dmarc =
v=DMARC1; p=none; rua=mailto:[email protected] (passer à p=quarantine après
quelques semaines sans souci). Cliquer « Verify ». Créer une clé API « Sending access »
limitée à ce domaine.[email protected], Sender name Cinepisode, Host smtp.resend.com, Port 465,
Username resend, Password = la clé API Resend. Enregistrer, puis Rate Limits ›
emails : 30/h (ou plus). Tester « Mot de passe oublié » sur son propre compte.cinepisode.com chez
ImprovMX avec l'alias contact → [email protected], puis dans Vercel DNS :
MX @ mx1.improvmx.com (priorité 10), MX @ mx2.improvmx.com (priorité 20), TXT @
v=spf1 include:spf.improvmx.com ~all. Ces MX sont sur la racine et ceux de Resend sur
send. : pas de conflit. Un seul enregistrement SPF par nom (fusionner si un autre
service en ajoute un sur @).20261008100000delete_my_account(), SECURITY DEFINER limitée à
auth.uid(), exige une connexion de moins de 15 min) : aucune clé secrète côté client.cinepisode.com et www.cinepisode.com figurent
dans les hostnames du widget./api : rien à faire (pas de liste d'origines ; la CSP utilise 'self').
Référencement (facultatif) : Google Search Console › ajouter cinepisode.com
(vérification par enregistrement TXT dans Vercel DNS) et soumettre
https://cinepisode.com/sitemap.xml.domains.redirects à true dans brand.config.json puis node scripts/build-brand.mjs
(ajoute dans vercel.json watchlist-omega-three.vercel.app → cinepisode.com, sauf
/api/ pour l'app de bureau ; www est déjà redirigé par Vercel). ⚠️ Les listes enregistrées seulement
sur l'appareil (sans compte) restent attachées à l'ancien domaine : prévenir les
utilisateurs de se connecter (synchro) ou d'exporter avant d'activer la redirection.
L'app de bureau (desktop/src-tauri/tauri.conf.json) pointe toujours sur l'ancienne
adresse ; la changer demande une nouvelle version de l'app de bureau.