v2.2.0: audio compressor, Ko-Fi support, 11 new locale translations, website locale test

This commit is contained in:
Timo
2026-06-08 20:36:49 +02:00
parent f5db39b77b
commit 9e2abadf5a
33 changed files with 307 additions and 228 deletions
+18 -1
View File
@@ -4,7 +4,24 @@ All notable changes to the KoalaSync browser extension and relay server.
--- ---
## [v2.1.3] — 2026-06-06 ## [v2.2.0] — 2026-06-08
### Added
- **Web Audio API Compressor**: Built-in audio dynamic range compression with four presets (Recommended, Dynamic Range, Vocal Enhancement, Smooth) and fully customizable sliders (threshold, ratio, knee, attack, release, makeup gain). Uses dry/wet crossfade (40ms linear ramp) to avoid clicks. Configured via the new Audio Options page accessible from the Settings tab.
- **Master Audio Toggle**: Global on/off switch for audio processing in both the extension popup and Audio Options page, synced via `chrome.storage.sync`.
- **Audio Options Page** (`audio-options.html`): Dedicated settings page with master toggle, compressor preset selector, real-time custom sliders, and equalizer placeholder. Dark theme matching the popup design.
- **Ko-Fi Support Links**: Static footer badges on the Settings and Status tabs linking to `https://support.koalastuff.net` (redirect owned by the developer). README now includes a Ko-Fi sponsor badge. Website footer updated with a styled Ko-Fi pill button (heart icon + "Ko-Fi").
- **Feature Hint System**: Generic `dismissedHints` array in sync storage for announcing new features. First hint highlights the Audio Options entry in Settings. Extensible for future features.
- **11 New Locale Translations**: 23 new i18n keys (audio processing, support links, etc.) fully translated into Spanish, French, Italian, Japanese, Korean, Dutch, Polish, European Portuguese, Brazilian Portuguese, Russian, and Turkish.
- **Website Locale Consistency Test** (`scripts/test-website-locales.mjs`): Validates all 12 non-English website locale files have exactly the same keys as `en.json`. Runs automatically as part of `npm run verify`.
### Fixed
- **Portuguese (PT) locale**: Removed Italian contamination — "sincronizzazione" → "sincronização", "tempo reale" → "tempo real", "Link di Invito" → "Link de Convite", "Sair della Sala" → "Sair da Sala".
- **Korean locale**: Fixed broken character in `HOWTO_STEP_2_TEXT` (`클rip보드``클립보드`).
- **Website COMP_FEAT_6_KOALA**: Normalized from inconsistent "6 Languages" to "13 Languages" across all locale files (en, de, es, fr, pt-BR, ru).
### Changed
- **ROADMAP.md**: Removed outdated cache LRU eviction item (already solved via time-based + insertion-order Map). Translated remaining German text to English.
### Fixed ### Fixed
- **Debug report showing wrong logs**: Fixed `logs.slice(-50)` and `history.slice(-20)` in the "Copy Debug Report" feature. Since `addLog()` and `addToHistory()` use `unshift` (inserting entries at index 0), the arrays are ordered newest-first. `slice(-N)` took the N **oldest** entries instead of the N **newest**. Changed to `slice(0, N).reverse()` to correctly include the most recent logs and display them chronologically. - **Debug report showing wrong logs**: Fixed `logs.slice(-50)` and `history.slice(-20)` in the "Copy Debug Report" feature. Since `addLog()` and `addToHistory()` use `unshift` (inserting entries at index 0), the arrays are ordered newest-first. `slice(-N)` took the N **oldest** entries instead of the N **newest**. Changed to `slice(0, N).reverse()` to correctly include the most recent logs and display them chronologically.
+19 -19
View File
@@ -180,27 +180,27 @@
"LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Tiempo de espera agotado: no todos los participantes cargaron el episodio", "LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Tiempo de espera agotado: no todos los participantes cargaron el episodio",
"LOBBY_CANCEL_USER": "Cancelado por el usuario", "LOBBY_CANCEL_USER": "Cancelado por el usuario",
"NOTIF_ERROR_TITLE": "Error de KoalaSync", "NOTIF_ERROR_TITLE": "Error de KoalaSync",
"FOOTER_SUPPORT": "♥ Support", "FOOTER_SUPPORT": "♥ Apoyar",
"FOOTER_REVIEW": "★ Rate us", "FOOTER_REVIEW": "★ Valorar",
"LABEL_AUDIO_PROCESSING": "Audio Processing", "LABEL_AUDIO_PROCESSING": "Procesamiento de audio",
"LABEL_AUDIO_PROCESSING_TOOLTIP": "Apply audio effects like compression to video playback", "LABEL_AUDIO_PROCESSING_TOOLTIP": "Aplica efectos de audio como compresión a la reproducción de video",
"AUDIO_OPEN_SETTINGS": "Open Audio Settings", "AUDIO_OPEN_SETTINGS": "Abrir configuración de audio",
"NEW_FEATURE_AUDIO": "New: Audio Processing — try the compressor!", "NEW_FEATURE_AUDIO": "Nuevo: Procesamiento de audio — ¡prueba el compresor!",
"AUDIO_PAGE_TITLE": "Audio Settings", "AUDIO_PAGE_TITLE": "Configuración de audio",
"AUDIO_MASTER_TOGGLE": "Audio Processing", "AUDIO_MASTER_TOGGLE": "Procesamiento de audio",
"AUDIO_COMPRESSOR": "Compressor", "AUDIO_COMPRESSOR": "Compresor",
"AUDIO_COMPRESSOR_ENABLE": "Enabled", "AUDIO_COMPRESSOR_ENABLE": "Activado",
"AUDIO_PRESET": "Preset", "AUDIO_PRESET": "Preajuste",
"AUDIO_PRESET_RECOMMENDED": "Recommended", "AUDIO_PRESET_RECOMMENDED": "Recomendado",
"AUDIO_PRESET_DYNAMIC_RANGE": "Dynamic Range", "AUDIO_PRESET_DYNAMIC_RANGE": "Rango dinámico",
"AUDIO_PRESET_VOCAL_ENHANCEMENT": "Vocal Enhancement", "AUDIO_PRESET_VOCAL_ENHANCEMENT": "Mejora de voz",
"AUDIO_PRESET_SMOOTH": "Smooth", "AUDIO_PRESET_SMOOTH": "Suave",
"AUDIO_PRESET_CUSTOM": "Custom", "AUDIO_PRESET_CUSTOM": "Personalizado",
"AUDIO_PARAM_THRESHOLD": "Threshold", "AUDIO_PARAM_THRESHOLD": "Umbral",
"AUDIO_PARAM_KNEE": "Knee", "AUDIO_PARAM_KNEE": "Knee",
"AUDIO_PARAM_RATIO": "Ratio", "AUDIO_PARAM_RATIO": "Ratio",
"AUDIO_PARAM_ATTACK": "Attack", "AUDIO_PARAM_ATTACK": "Attack",
"AUDIO_PARAM_RELEASE": "Release", "AUDIO_PARAM_RELEASE": "Release",
"AUDIO_EQUALIZER": "Equalizer", "AUDIO_EQUALIZER": "Ecualizador",
"AUDIO_COMING_SOON": "Coming soon" "AUDIO_COMING_SOON": "Próximamente"
} }
+19 -19
View File
@@ -180,27 +180,27 @@
"LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Délai dépassé — tous les membres n'ont pas chargé l'épisode", "LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Délai dépassé — tous les membres n'ont pas chargé l'épisode",
"LOBBY_CANCEL_USER": "Annulé par l'utilisateur", "LOBBY_CANCEL_USER": "Annulé par l'utilisateur",
"NOTIF_ERROR_TITLE": "Erreur KoalaSync", "NOTIF_ERROR_TITLE": "Erreur KoalaSync",
"FOOTER_SUPPORT": "♥ Support", "FOOTER_SUPPORT": "♥ Soutenir",
"FOOTER_REVIEW": "★ Rate us", "FOOTER_REVIEW": "★ Évaluer",
"LABEL_AUDIO_PROCESSING": "Audio Processing", "LABEL_AUDIO_PROCESSING": "Traitement audio",
"LABEL_AUDIO_PROCESSING_TOOLTIP": "Apply audio effects like compression to video playback", "LABEL_AUDIO_PROCESSING_TOOLTIP": "Applique des effets audio comme la compression à la lecture vidéo",
"AUDIO_OPEN_SETTINGS": "Open Audio Settings", "AUDIO_OPEN_SETTINGS": "Ouvrir les paramètres audio",
"NEW_FEATURE_AUDIO": "New: Audio Processing — try the compressor!", "NEW_FEATURE_AUDIO": "Nouveau : Traitement audio — essayez le compresseur !",
"AUDIO_PAGE_TITLE": "Audio Settings", "AUDIO_PAGE_TITLE": "Paramètres audio",
"AUDIO_MASTER_TOGGLE": "Audio Processing", "AUDIO_MASTER_TOGGLE": "Traitement audio",
"AUDIO_COMPRESSOR": "Compressor", "AUDIO_COMPRESSOR": "Compresseur",
"AUDIO_COMPRESSOR_ENABLE": "Enabled", "AUDIO_COMPRESSOR_ENABLE": "Activé",
"AUDIO_PRESET": "Preset", "AUDIO_PRESET": "Préréglage",
"AUDIO_PRESET_RECOMMENDED": "Recommended", "AUDIO_PRESET_RECOMMENDED": "Recommandé",
"AUDIO_PRESET_DYNAMIC_RANGE": "Dynamic Range", "AUDIO_PRESET_DYNAMIC_RANGE": "Plage dynamique",
"AUDIO_PRESET_VOCAL_ENHANCEMENT": "Vocal Enhancement", "AUDIO_PRESET_VOCAL_ENHANCEMENT": "Amélioration vocale",
"AUDIO_PRESET_SMOOTH": "Smooth", "AUDIO_PRESET_SMOOTH": "Douce",
"AUDIO_PRESET_CUSTOM": "Custom", "AUDIO_PRESET_CUSTOM": "Personnalisé",
"AUDIO_PARAM_THRESHOLD": "Threshold", "AUDIO_PARAM_THRESHOLD": "Seuil",
"AUDIO_PARAM_KNEE": "Knee", "AUDIO_PARAM_KNEE": "Knee",
"AUDIO_PARAM_RATIO": "Ratio", "AUDIO_PARAM_RATIO": "Ratio",
"AUDIO_PARAM_ATTACK": "Attack", "AUDIO_PARAM_ATTACK": "Attack",
"AUDIO_PARAM_RELEASE": "Release", "AUDIO_PARAM_RELEASE": "Release",
"AUDIO_EQUALIZER": "Equalizer", "AUDIO_EQUALIZER": "Égaliseur",
"AUDIO_COMING_SOON": "Coming soon" "AUDIO_COMING_SOON": "Bientôt disponible"
} }
+19 -19
View File
@@ -180,27 +180,27 @@
"LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Timeout — non tutti i partecipanti hanno caricato l'episodio", "LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Timeout — non tutti i partecipanti hanno caricato l'episodio",
"LOBBY_CANCEL_USER": "Annullato dall'utente", "LOBBY_CANCEL_USER": "Annullato dall'utente",
"NOTIF_ERROR_TITLE": "Errore KoalaSync", "NOTIF_ERROR_TITLE": "Errore KoalaSync",
"FOOTER_SUPPORT": "♥ Support", "FOOTER_SUPPORT": "♥ Supporta",
"FOOTER_REVIEW": "★ Rate us", "FOOTER_REVIEW": "★ Valuta",
"LABEL_AUDIO_PROCESSING": "Audio Processing", "LABEL_AUDIO_PROCESSING": "Elaborazione audio",
"LABEL_AUDIO_PROCESSING_TOOLTIP": "Apply audio effects like compression to video playback", "LABEL_AUDIO_PROCESSING_TOOLTIP": "Applica effetti audio come la compressione alla riproduzione video",
"AUDIO_OPEN_SETTINGS": "Open Audio Settings", "AUDIO_OPEN_SETTINGS": "Apri impostazioni audio",
"NEW_FEATURE_AUDIO": "New: Audio Processing — try the compressor!", "NEW_FEATURE_AUDIO": "Novità: Elaborazione audio — prova il compressore!",
"AUDIO_PAGE_TITLE": "Audio Settings", "AUDIO_PAGE_TITLE": "Impostazioni audio",
"AUDIO_MASTER_TOGGLE": "Audio Processing", "AUDIO_MASTER_TOGGLE": "Elaborazione audio",
"AUDIO_COMPRESSOR": "Compressor", "AUDIO_COMPRESSOR": "Compressore",
"AUDIO_COMPRESSOR_ENABLE": "Enabled", "AUDIO_COMPRESSOR_ENABLE": "Attivato",
"AUDIO_PRESET": "Preset", "AUDIO_PRESET": "Preimpostazione",
"AUDIO_PRESET_RECOMMENDED": "Recommended", "AUDIO_PRESET_RECOMMENDED": "Consigliato",
"AUDIO_PRESET_DYNAMIC_RANGE": "Dynamic Range", "AUDIO_PRESET_DYNAMIC_RANGE": "Gamma dinamica",
"AUDIO_PRESET_VOCAL_ENHANCEMENT": "Vocal Enhancement", "AUDIO_PRESET_VOCAL_ENHANCEMENT": "Miglioramento vocale",
"AUDIO_PRESET_SMOOTH": "Smooth", "AUDIO_PRESET_SMOOTH": "Morbido",
"AUDIO_PRESET_CUSTOM": "Custom", "AUDIO_PRESET_CUSTOM": "Personalizzato",
"AUDIO_PARAM_THRESHOLD": "Threshold", "AUDIO_PARAM_THRESHOLD": "Soglia",
"AUDIO_PARAM_KNEE": "Knee", "AUDIO_PARAM_KNEE": "Knee",
"AUDIO_PARAM_RATIO": "Ratio", "AUDIO_PARAM_RATIO": "Ratio",
"AUDIO_PARAM_ATTACK": "Attack", "AUDIO_PARAM_ATTACK": "Attack",
"AUDIO_PARAM_RELEASE": "Release", "AUDIO_PARAM_RELEASE": "Release",
"AUDIO_EQUALIZER": "Equalizer", "AUDIO_EQUALIZER": "Equalizzatore",
"AUDIO_COMING_SOON": "Coming soon" "AUDIO_COMING_SOON": "Prossimamente"
} }
+19 -19
View File
@@ -180,27 +180,27 @@
"LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "タイムアウト — 一部のメンバーがエピソードを読み込めませんでした", "LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "タイムアウト — 一部のメンバーがエピソードを読み込めませんでした",
"LOBBY_CANCEL_USER": "ユーザーによってキャンセルされました", "LOBBY_CANCEL_USER": "ユーザーによってキャンセルされました",
"NOTIF_ERROR_TITLE": "KoalaSyncエラー", "NOTIF_ERROR_TITLE": "KoalaSyncエラー",
"FOOTER_SUPPORT": "♥ Support", "FOOTER_SUPPORT": "♥ サポート",
"FOOTER_REVIEW": "★ Rate us", "FOOTER_REVIEW": "★ 評価する",
"LABEL_AUDIO_PROCESSING": "Audio Processing", "LABEL_AUDIO_PROCESSING": "オーディオ処理",
"LABEL_AUDIO_PROCESSING_TOOLTIP": "Apply audio effects like compression to video playback", "LABEL_AUDIO_PROCESSING_TOOLTIP": "動画再生に圧縮などのオーディオエフェクトを適用します",
"AUDIO_OPEN_SETTINGS": "Open Audio Settings", "AUDIO_OPEN_SETTINGS": "オーディオ設定を開く",
"NEW_FEATURE_AUDIO": "New: Audio Processing — try the compressor!", "NEW_FEATURE_AUDIO": "新機能: オーディオ処理 — コンプレッサーを試してみよう!",
"AUDIO_PAGE_TITLE": "Audio Settings", "AUDIO_PAGE_TITLE": "オーディオ設定",
"AUDIO_MASTER_TOGGLE": "Audio Processing", "AUDIO_MASTER_TOGGLE": "オーディオ処理",
"AUDIO_COMPRESSOR": "Compressor", "AUDIO_COMPRESSOR": "コンプレッサー",
"AUDIO_COMPRESSOR_ENABLE": "Enabled", "AUDIO_COMPRESSOR_ENABLE": "有効",
"AUDIO_PRESET": "Preset", "AUDIO_PRESET": "プリセット",
"AUDIO_PRESET_RECOMMENDED": "Recommended", "AUDIO_PRESET_RECOMMENDED": "推奨",
"AUDIO_PRESET_DYNAMIC_RANGE": "Dynamic Range", "AUDIO_PRESET_DYNAMIC_RANGE": "ダイナミックレンジ",
"AUDIO_PRESET_VOCAL_ENHANCEMENT": "Vocal Enhancement", "AUDIO_PRESET_VOCAL_ENHANCEMENT": "ボーカル強調",
"AUDIO_PRESET_SMOOTH": "Smooth", "AUDIO_PRESET_SMOOTH": "スムース",
"AUDIO_PRESET_CUSTOM": "Custom", "AUDIO_PRESET_CUSTOM": "カスタム",
"AUDIO_PARAM_THRESHOLD": "Threshold", "AUDIO_PARAM_THRESHOLD": "スレッショルド",
"AUDIO_PARAM_KNEE": "Knee", "AUDIO_PARAM_KNEE": "Knee",
"AUDIO_PARAM_RATIO": "Ratio", "AUDIO_PARAM_RATIO": "Ratio",
"AUDIO_PARAM_ATTACK": "Attack", "AUDIO_PARAM_ATTACK": "Attack",
"AUDIO_PARAM_RELEASE": "Release", "AUDIO_PARAM_RELEASE": "Release",
"AUDIO_EQUALIZER": "Equalizer", "AUDIO_EQUALIZER": "イコライザー",
"AUDIO_COMING_SOON": "Coming soon" "AUDIO_COMING_SOON": "近日公開"
} }
+19 -19
View File
@@ -180,27 +180,27 @@
"LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "시간 초과 — 모든 피어가 에피소드를 로드하지 못했습니다", "LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "시간 초과 — 모든 피어가 에피소드를 로드하지 못했습니다",
"LOBBY_CANCEL_USER": "사용자에 의해 취소됨", "LOBBY_CANCEL_USER": "사용자에 의해 취소됨",
"NOTIF_ERROR_TITLE": "KoalaSync 오류", "NOTIF_ERROR_TITLE": "KoalaSync 오류",
"FOOTER_SUPPORT": "♥ Support", "FOOTER_SUPPORT": "♥ 후원",
"FOOTER_REVIEW": "★ Rate us", "FOOTER_REVIEW": "★ 평가하기",
"LABEL_AUDIO_PROCESSING": "Audio Processing", "LABEL_AUDIO_PROCESSING": "오디오 처리",
"LABEL_AUDIO_PROCESSING_TOOLTIP": "Apply audio effects like compression to video playback", "LABEL_AUDIO_PROCESSING_TOOLTIP": "비디오 재생에 압축과 같은 오디오 효과를 적용합니다",
"AUDIO_OPEN_SETTINGS": "Open Audio Settings", "AUDIO_OPEN_SETTINGS": "오디오 설정 열기",
"NEW_FEATURE_AUDIO": "New: Audio Processing — try the compressor!", "NEW_FEATURE_AUDIO": "신규: 오디오 처리 — 컴프레서를 사용해보세요!",
"AUDIO_PAGE_TITLE": "Audio Settings", "AUDIO_PAGE_TITLE": "오디오 설정",
"AUDIO_MASTER_TOGGLE": "Audio Processing", "AUDIO_MASTER_TOGGLE": "오디오 처리",
"AUDIO_COMPRESSOR": "Compressor", "AUDIO_COMPRESSOR": "컴프레서",
"AUDIO_COMPRESSOR_ENABLE": "Enabled", "AUDIO_COMPRESSOR_ENABLE": "활성화",
"AUDIO_PRESET": "Preset", "AUDIO_PRESET": "프리셋",
"AUDIO_PRESET_RECOMMENDED": "Recommended", "AUDIO_PRESET_RECOMMENDED": "추천",
"AUDIO_PRESET_DYNAMIC_RANGE": "Dynamic Range", "AUDIO_PRESET_DYNAMIC_RANGE": "다이내믹 레인지",
"AUDIO_PRESET_VOCAL_ENHANCEMENT": "Vocal Enhancement", "AUDIO_PRESET_VOCAL_ENHANCEMENT": "음성 강화",
"AUDIO_PRESET_SMOOTH": "Smooth", "AUDIO_PRESET_SMOOTH": "부드럽게",
"AUDIO_PRESET_CUSTOM": "Custom", "AUDIO_PRESET_CUSTOM": "사용자 정의",
"AUDIO_PARAM_THRESHOLD": "Threshold", "AUDIO_PARAM_THRESHOLD": "임계값",
"AUDIO_PARAM_KNEE": "Knee", "AUDIO_PARAM_KNEE": "Knee",
"AUDIO_PARAM_RATIO": "Ratio", "AUDIO_PARAM_RATIO": "Ratio",
"AUDIO_PARAM_ATTACK": "Attack", "AUDIO_PARAM_ATTACK": "Attack",
"AUDIO_PARAM_RELEASE": "Release", "AUDIO_PARAM_RELEASE": "Release",
"AUDIO_EQUALIZER": "Equalizer", "AUDIO_EQUALIZER": "이퀄라이저",
"AUDIO_COMING_SOON": "Coming soon" "AUDIO_COMING_SOON": "출시 예정"
} }
+17 -17
View File
@@ -180,27 +180,27 @@
"LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Time-out — niet alle deelnemers hebben de aflevering geladen", "LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Time-out — niet alle deelnemers hebben de aflevering geladen",
"LOBBY_CANCEL_USER": "Geannuleerd door gebruiker", "LOBBY_CANCEL_USER": "Geannuleerd door gebruiker",
"NOTIF_ERROR_TITLE": "KoalaSync-fout", "NOTIF_ERROR_TITLE": "KoalaSync-fout",
"FOOTER_SUPPORT": "♥ Support", "FOOTER_SUPPORT": "♥ Steunen",
"FOOTER_REVIEW": "★ Rate us", "FOOTER_REVIEW": "★ Beoordelen",
"LABEL_AUDIO_PROCESSING": "Audio Processing", "LABEL_AUDIO_PROCESSING": "Audioverwerking",
"LABEL_AUDIO_PROCESSING_TOOLTIP": "Apply audio effects like compression to video playback", "LABEL_AUDIO_PROCESSING_TOOLTIP": "Past audio-effecten zoals compressie toe op video-afspelen",
"AUDIO_OPEN_SETTINGS": "Open Audio Settings", "AUDIO_OPEN_SETTINGS": "Audio-instellingen openen",
"NEW_FEATURE_AUDIO": "New: Audio Processing — try the compressor!", "NEW_FEATURE_AUDIO": "Nieuw: Audioverwerking — probeer de compressor!",
"AUDIO_PAGE_TITLE": "Audio Settings", "AUDIO_PAGE_TITLE": "Audio-instellingen",
"AUDIO_MASTER_TOGGLE": "Audio Processing", "AUDIO_MASTER_TOGGLE": "Audioverwerking",
"AUDIO_COMPRESSOR": "Compressor", "AUDIO_COMPRESSOR": "Compressor",
"AUDIO_COMPRESSOR_ENABLE": "Enabled", "AUDIO_COMPRESSOR_ENABLE": "Ingeschakeld",
"AUDIO_PRESET": "Preset", "AUDIO_PRESET": "Voorinstelling",
"AUDIO_PRESET_RECOMMENDED": "Recommended", "AUDIO_PRESET_RECOMMENDED": "Aanbevolen",
"AUDIO_PRESET_DYNAMIC_RANGE": "Dynamic Range", "AUDIO_PRESET_DYNAMIC_RANGE": "Dynamisch bereik",
"AUDIO_PRESET_VOCAL_ENHANCEMENT": "Vocal Enhancement", "AUDIO_PRESET_VOCAL_ENHANCEMENT": "Stemverbetering",
"AUDIO_PRESET_SMOOTH": "Smooth", "AUDIO_PRESET_SMOOTH": "Zacht",
"AUDIO_PRESET_CUSTOM": "Custom", "AUDIO_PRESET_CUSTOM": "Aangepast",
"AUDIO_PARAM_THRESHOLD": "Threshold", "AUDIO_PARAM_THRESHOLD": "Drempel",
"AUDIO_PARAM_KNEE": "Knee", "AUDIO_PARAM_KNEE": "Knee",
"AUDIO_PARAM_RATIO": "Ratio", "AUDIO_PARAM_RATIO": "Ratio",
"AUDIO_PARAM_ATTACK": "Attack", "AUDIO_PARAM_ATTACK": "Attack",
"AUDIO_PARAM_RELEASE": "Release", "AUDIO_PARAM_RELEASE": "Release",
"AUDIO_EQUALIZER": "Equalizer", "AUDIO_EQUALIZER": "Equalizer",
"AUDIO_COMING_SOON": "Coming soon" "AUDIO_COMING_SOON": "Binnenkort beschikbaar"
} }
+18 -18
View File
@@ -180,27 +180,27 @@
"LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Limit czasu — nie wszyscy uczestnicy załadowali odcinek", "LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Limit czasu — nie wszyscy uczestnicy załadowali odcinek",
"LOBBY_CANCEL_USER": "Anulowane przez użytkownika", "LOBBY_CANCEL_USER": "Anulowane przez użytkownika",
"NOTIF_ERROR_TITLE": "Błąd KoalaSync", "NOTIF_ERROR_TITLE": "Błąd KoalaSync",
"FOOTER_SUPPORT": "♥ Support", "FOOTER_SUPPORT": "♥ Wsparcie",
"FOOTER_REVIEW": "★ Rate us", "FOOTER_REVIEW": "★ Oceń",
"LABEL_AUDIO_PROCESSING": "Audio Processing", "LABEL_AUDIO_PROCESSING": "Przetwarzanie dźwięku",
"LABEL_AUDIO_PROCESSING_TOOLTIP": "Apply audio effects like compression to video playback", "LABEL_AUDIO_PROCESSING_TOOLTIP": "Stosuje efekty dźwiękowe, takie jak kompresja, do odtwarzania wideo",
"AUDIO_OPEN_SETTINGS": "Open Audio Settings", "AUDIO_OPEN_SETTINGS": "Otwórz ustawienia dźwięku",
"NEW_FEATURE_AUDIO": "New: Audio Processing — try the compressor!", "NEW_FEATURE_AUDIO": "Nowość: Przetwarzanie dźwięku — wypróbuj kompresor!",
"AUDIO_PAGE_TITLE": "Audio Settings", "AUDIO_PAGE_TITLE": "Ustawienia dźwięku",
"AUDIO_MASTER_TOGGLE": "Audio Processing", "AUDIO_MASTER_TOGGLE": "Przetwarzanie dźwięku",
"AUDIO_COMPRESSOR": "Compressor", "AUDIO_COMPRESSOR": "Kompresor",
"AUDIO_COMPRESSOR_ENABLE": "Enabled", "AUDIO_COMPRESSOR_ENABLE": "Włączony",
"AUDIO_PRESET": "Preset", "AUDIO_PRESET": "Preset",
"AUDIO_PRESET_RECOMMENDED": "Recommended", "AUDIO_PRESET_RECOMMENDED": "Zalecany",
"AUDIO_PRESET_DYNAMIC_RANGE": "Dynamic Range", "AUDIO_PRESET_DYNAMIC_RANGE": "Zakres dynamiki",
"AUDIO_PRESET_VOCAL_ENHANCEMENT": "Vocal Enhancement", "AUDIO_PRESET_VOCAL_ENHANCEMENT": "Wzmocnienie głosu",
"AUDIO_PRESET_SMOOTH": "Smooth", "AUDIO_PRESET_SMOOTH": "Płynny",
"AUDIO_PRESET_CUSTOM": "Custom", "AUDIO_PRESET_CUSTOM": "Niestandardowy",
"AUDIO_PARAM_THRESHOLD": "Threshold", "AUDIO_PARAM_THRESHOLD": "Próg",
"AUDIO_PARAM_KNEE": "Knee", "AUDIO_PARAM_KNEE": "Knee",
"AUDIO_PARAM_RATIO": "Ratio", "AUDIO_PARAM_RATIO": "Ratio",
"AUDIO_PARAM_ATTACK": "Attack", "AUDIO_PARAM_ATTACK": "Attack",
"AUDIO_PARAM_RELEASE": "Release", "AUDIO_PARAM_RELEASE": "Release",
"AUDIO_EQUALIZER": "Equalizer", "AUDIO_EQUALIZER": "Korektor",
"AUDIO_COMING_SOON": "Coming soon" "AUDIO_COMING_SOON": "Wkrótce"
} }
+18 -18
View File
@@ -180,27 +180,27 @@
"LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Tempo limite esgotado — nem todos os participantes carregaram o episódio", "LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Tempo limite esgotado — nem todos os participantes carregaram o episódio",
"LOBBY_CANCEL_USER": "Cancelado pelo usuário", "LOBBY_CANCEL_USER": "Cancelado pelo usuário",
"NOTIF_ERROR_TITLE": "Erro do KoalaSync", "NOTIF_ERROR_TITLE": "Erro do KoalaSync",
"FOOTER_SUPPORT": "♥ Support", "FOOTER_SUPPORT": "♥ Apoiar",
"FOOTER_REVIEW": "★ Rate us", "FOOTER_REVIEW": "★ Avaliar",
"LABEL_AUDIO_PROCESSING": "Audio Processing", "LABEL_AUDIO_PROCESSING": "Processamento de áudio",
"LABEL_AUDIO_PROCESSING_TOOLTIP": "Apply audio effects like compression to video playback", "LABEL_AUDIO_PROCESSING_TOOLTIP": "Aplica efeitos de áudio como compressão à reprodução de vídeo",
"AUDIO_OPEN_SETTINGS": "Open Audio Settings", "AUDIO_OPEN_SETTINGS": "Abrir configurações de áudio",
"NEW_FEATURE_AUDIO": "New: Audio Processing — try the compressor!", "NEW_FEATURE_AUDIO": "Novo: Processamento de áudio — experimente o compressor!",
"AUDIO_PAGE_TITLE": "Audio Settings", "AUDIO_PAGE_TITLE": "Configurações de áudio",
"AUDIO_MASTER_TOGGLE": "Audio Processing", "AUDIO_MASTER_TOGGLE": "Processamento de áudio",
"AUDIO_COMPRESSOR": "Compressor", "AUDIO_COMPRESSOR": "Compressor",
"AUDIO_COMPRESSOR_ENABLE": "Enabled", "AUDIO_COMPRESSOR_ENABLE": "Ativado",
"AUDIO_PRESET": "Preset", "AUDIO_PRESET": "Predefinição",
"AUDIO_PRESET_RECOMMENDED": "Recommended", "AUDIO_PRESET_RECOMMENDED": "Recomendado",
"AUDIO_PRESET_DYNAMIC_RANGE": "Dynamic Range", "AUDIO_PRESET_DYNAMIC_RANGE": "Faixa dinâmica",
"AUDIO_PRESET_VOCAL_ENHANCEMENT": "Vocal Enhancement", "AUDIO_PRESET_VOCAL_ENHANCEMENT": "Aprimoramento de voz",
"AUDIO_PRESET_SMOOTH": "Smooth", "AUDIO_PRESET_SMOOTH": "Suave",
"AUDIO_PRESET_CUSTOM": "Custom", "AUDIO_PRESET_CUSTOM": "Personalizado",
"AUDIO_PARAM_THRESHOLD": "Threshold", "AUDIO_PARAM_THRESHOLD": "Limiar",
"AUDIO_PARAM_KNEE": "Knee", "AUDIO_PARAM_KNEE": "Knee",
"AUDIO_PARAM_RATIO": "Ratio", "AUDIO_PARAM_RATIO": "Ratio",
"AUDIO_PARAM_ATTACK": "Attack", "AUDIO_PARAM_ATTACK": "Attack",
"AUDIO_PARAM_RELEASE": "Release", "AUDIO_PARAM_RELEASE": "Release",
"AUDIO_EQUALIZER": "Equalizer", "AUDIO_EQUALIZER": "Equalizador",
"AUDIO_COMING_SOON": "Coming soon" "AUDIO_COMING_SOON": "Em breve"
} }
+18 -18
View File
@@ -180,27 +180,27 @@
"LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Timeout — nem todos os participantes carregaram o episódio", "LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Timeout — nem todos os participantes carregaram o episódio",
"LOBBY_CANCEL_USER": "Cancelado pelo utilizador", "LOBBY_CANCEL_USER": "Cancelado pelo utilizador",
"NOTIF_ERROR_TITLE": "Erro do KoalaSync", "NOTIF_ERROR_TITLE": "Erro do KoalaSync",
"FOOTER_SUPPORT": "♥ Support", "FOOTER_SUPPORT": "♥ Apoiar",
"FOOTER_REVIEW": "★ Rate us", "FOOTER_REVIEW": "★ Avaliar",
"LABEL_AUDIO_PROCESSING": "Audio Processing", "LABEL_AUDIO_PROCESSING": "Processamento de áudio",
"LABEL_AUDIO_PROCESSING_TOOLTIP": "Apply audio effects like compression to video playback", "LABEL_AUDIO_PROCESSING_TOOLTIP": "Aplica efeitos de áudio como compressão à reprodução de vídeo",
"AUDIO_OPEN_SETTINGS": "Open Audio Settings", "AUDIO_OPEN_SETTINGS": "Abrir configurações de áudio",
"NEW_FEATURE_AUDIO": "New: Audio Processing — try the compressor!", "NEW_FEATURE_AUDIO": "Novo: Processamento de áudio — experimente o compressor!",
"AUDIO_PAGE_TITLE": "Audio Settings", "AUDIO_PAGE_TITLE": "Configurações de áudio",
"AUDIO_MASTER_TOGGLE": "Audio Processing", "AUDIO_MASTER_TOGGLE": "Processamento de áudio",
"AUDIO_COMPRESSOR": "Compressor", "AUDIO_COMPRESSOR": "Compressor",
"AUDIO_COMPRESSOR_ENABLE": "Enabled", "AUDIO_COMPRESSOR_ENABLE": "Ativado",
"AUDIO_PRESET": "Preset", "AUDIO_PRESET": "Predefinição",
"AUDIO_PRESET_RECOMMENDED": "Recommended", "AUDIO_PRESET_RECOMMENDED": "Recomendado",
"AUDIO_PRESET_DYNAMIC_RANGE": "Dynamic Range", "AUDIO_PRESET_DYNAMIC_RANGE": "Gama dinâmica",
"AUDIO_PRESET_VOCAL_ENHANCEMENT": "Vocal Enhancement", "AUDIO_PRESET_VOCAL_ENHANCEMENT": "Melhoria vocal",
"AUDIO_PRESET_SMOOTH": "Smooth", "AUDIO_PRESET_SMOOTH": "Suave",
"AUDIO_PRESET_CUSTOM": "Custom", "AUDIO_PRESET_CUSTOM": "Personalizado",
"AUDIO_PARAM_THRESHOLD": "Threshold", "AUDIO_PARAM_THRESHOLD": "Limiar",
"AUDIO_PARAM_KNEE": "Knee", "AUDIO_PARAM_KNEE": "Knee",
"AUDIO_PARAM_RATIO": "Ratio", "AUDIO_PARAM_RATIO": "Ratio",
"AUDIO_PARAM_ATTACK": "Attack", "AUDIO_PARAM_ATTACK": "Attack",
"AUDIO_PARAM_RELEASE": "Release", "AUDIO_PARAM_RELEASE": "Release",
"AUDIO_EQUALIZER": "Equalizer", "AUDIO_EQUALIZER": "Equalizador",
"AUDIO_COMING_SOON": "Coming soon" "AUDIO_COMING_SOON": "Em breve"
} }
+19 -19
View File
@@ -180,27 +180,27 @@
"LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Время ожидания истекло — не все участники загрузили серию", "LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Время ожидания истекло — не все участники загрузили серию",
"LOBBY_CANCEL_USER": "Отменено пользователем", "LOBBY_CANCEL_USER": "Отменено пользователем",
"NOTIF_ERROR_TITLE": "Ошибка KoalaSync", "NOTIF_ERROR_TITLE": "Ошибка KoalaSync",
"FOOTER_SUPPORT": "♥ Support", "FOOTER_SUPPORT": "♥ Поддержать",
"FOOTER_REVIEW": "★ Rate us", "FOOTER_REVIEW": "★ Оценить",
"LABEL_AUDIO_PROCESSING": "Audio Processing", "LABEL_AUDIO_PROCESSING": "Обработка звука",
"LABEL_AUDIO_PROCESSING_TOOLTIP": "Apply audio effects like compression to video playback", "LABEL_AUDIO_PROCESSING_TOOLTIP": "Применяет аудиоэффекты, такие как сжатие, к воспроизведению видео",
"AUDIO_OPEN_SETTINGS": "Open Audio Settings", "AUDIO_OPEN_SETTINGS": "Открыть настройки звука",
"NEW_FEATURE_AUDIO": "New: Audio Processing — try the compressor!", "NEW_FEATURE_AUDIO": "Новое: Обработка звука — попробуйте компрессор!",
"AUDIO_PAGE_TITLE": "Audio Settings", "AUDIO_PAGE_TITLE": "Настройки звука",
"AUDIO_MASTER_TOGGLE": "Audio Processing", "AUDIO_MASTER_TOGGLE": "Обработка звука",
"AUDIO_COMPRESSOR": "Compressor", "AUDIO_COMPRESSOR": "Компрессор",
"AUDIO_COMPRESSOR_ENABLE": "Enabled", "AUDIO_COMPRESSOR_ENABLE": "Включено",
"AUDIO_PRESET": "Preset", "AUDIO_PRESET": "Пресет",
"AUDIO_PRESET_RECOMMENDED": "Recommended", "AUDIO_PRESET_RECOMMENDED": "Рекомендуемый",
"AUDIO_PRESET_DYNAMIC_RANGE": "Dynamic Range", "AUDIO_PRESET_DYNAMIC_RANGE": "Динамический диапазон",
"AUDIO_PRESET_VOCAL_ENHANCEMENT": "Vocal Enhancement", "AUDIO_PRESET_VOCAL_ENHANCEMENT": "Улучшение голоса",
"AUDIO_PRESET_SMOOTH": "Smooth", "AUDIO_PRESET_SMOOTH": "Плавный",
"AUDIO_PRESET_CUSTOM": "Custom", "AUDIO_PRESET_CUSTOM": "Пользовательский",
"AUDIO_PARAM_THRESHOLD": "Threshold", "AUDIO_PARAM_THRESHOLD": "Порог",
"AUDIO_PARAM_KNEE": "Knee", "AUDIO_PARAM_KNEE": "Knee",
"AUDIO_PARAM_RATIO": "Ratio", "AUDIO_PARAM_RATIO": "Ratio",
"AUDIO_PARAM_ATTACK": "Attack", "AUDIO_PARAM_ATTACK": "Attack",
"AUDIO_PARAM_RELEASE": "Release", "AUDIO_PARAM_RELEASE": "Release",
"AUDIO_EQUALIZER": "Equalizer", "AUDIO_EQUALIZER": "Эквалайзер",
"AUDIO_COMING_SOON": "Coming soon" "AUDIO_COMING_SOON": "Скоро"
} }
+19 -19
View File
@@ -180,27 +180,27 @@
"LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Zaman aşımı — tüm bağlantılar bölümü yüklemedi", "LOBBY_CANCEL_TIMEOUT_PEERS_LOAD": "Zaman aşımı — tüm bağlantılar bölümü yüklemedi",
"LOBBY_CANCEL_USER": "Kullanıcı tarafından iptal edildi", "LOBBY_CANCEL_USER": "Kullanıcı tarafından iptal edildi",
"NOTIF_ERROR_TITLE": "KoalaSync Hatası", "NOTIF_ERROR_TITLE": "KoalaSync Hatası",
"FOOTER_SUPPORT": "♥ Support", "FOOTER_SUPPORT": "♥ Destekle",
"FOOTER_REVIEW": "★ Rate us", "FOOTER_REVIEW": "★ Değerlendir",
"LABEL_AUDIO_PROCESSING": "Audio Processing", "LABEL_AUDIO_PROCESSING": "Ses işleme",
"LABEL_AUDIO_PROCESSING_TOOLTIP": "Apply audio effects like compression to video playback", "LABEL_AUDIO_PROCESSING_TOOLTIP": "Video oynatımına sıkıştırma gibi ses efektleri uygular",
"AUDIO_OPEN_SETTINGS": "Open Audio Settings", "AUDIO_OPEN_SETTINGS": "Ses ayarlarını",
"NEW_FEATURE_AUDIO": "New: Audio Processing — try the compressor!", "NEW_FEATURE_AUDIO": "Yeni: Ses işleme — kompresörü deneyin!",
"AUDIO_PAGE_TITLE": "Audio Settings", "AUDIO_PAGE_TITLE": "Ses ayarları",
"AUDIO_MASTER_TOGGLE": "Audio Processing", "AUDIO_MASTER_TOGGLE": "Ses işleme",
"AUDIO_COMPRESSOR": "Compressor", "AUDIO_COMPRESSOR": "Kompresör",
"AUDIO_COMPRESSOR_ENABLE": "Enabled", "AUDIO_COMPRESSOR_ENABLE": "Etkin",
"AUDIO_PRESET": "Preset", "AUDIO_PRESET": "Ön ayar",
"AUDIO_PRESET_RECOMMENDED": "Recommended", "AUDIO_PRESET_RECOMMENDED": "Önerilen",
"AUDIO_PRESET_DYNAMIC_RANGE": "Dynamic Range", "AUDIO_PRESET_DYNAMIC_RANGE": "Dinamik aralık",
"AUDIO_PRESET_VOCAL_ENHANCEMENT": "Vocal Enhancement", "AUDIO_PRESET_VOCAL_ENHANCEMENT": "Ses iyileştirme",
"AUDIO_PRESET_SMOOTH": "Smooth", "AUDIO_PRESET_SMOOTH": "Yumuşak",
"AUDIO_PRESET_CUSTOM": "Custom", "AUDIO_PRESET_CUSTOM": "Özel",
"AUDIO_PARAM_THRESHOLD": "Threshold", "AUDIO_PARAM_THRESHOLD": "Eşik",
"AUDIO_PARAM_KNEE": "Knee", "AUDIO_PARAM_KNEE": "Knee",
"AUDIO_PARAM_RATIO": "Ratio", "AUDIO_PARAM_RATIO": "Ratio",
"AUDIO_PARAM_ATTACK": "Attack", "AUDIO_PARAM_ATTACK": "Attack",
"AUDIO_PARAM_RELEASE": "Release", "AUDIO_PARAM_RELEASE": "Release",
"AUDIO_EQUALIZER": "Equalizer", "AUDIO_EQUALIZER": "Ekolayzer",
"AUDIO_COMING_SOON": "Coming soon" "AUDIO_COMING_SOON": "Çok yakında"
} }
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env node
import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const localesDir = path.join(__dirname, '..', 'website', 'locales');
const enPath = path.join(localesDir, 'en.json');
if (!fs.existsSync(enPath)) {
console.error('CRITICAL: website/locales/en.json is missing!');
process.exit(1);
}
const enDict = JSON.parse(fs.readFileSync(enPath, 'utf8'));
const enKeys = Object.keys(enDict).sort();
const localeFiles = fs.readdirSync(localesDir)
.filter(file => file.endsWith('.json') && file !== 'en.json')
.sort();
let hasError = false;
console.log(`Auditing website i18n locales using ${enKeys.length} baseline keys from en.json...\n`);
for (const file of localeFiles) {
const filePath = path.join(localesDir, file);
try {
const dict = JSON.parse(fs.readFileSync(filePath, 'utf8'));
const keys = Object.keys(dict).sort();
const missingKeys = enKeys.filter(k => !keys.includes(k));
const extraKeys = keys.filter(k => !enKeys.includes(k));
if (missingKeys.length > 0 || extraKeys.length > 0) {
hasError = true;
console.error(`${file} has inconsistencies:`);
if (missingKeys.length > 0) {
console.error(` Missing keys (${missingKeys.length}):`, missingKeys);
}
if (extraKeys.length > 0) {
console.error(` Extra keys (${extraKeys.length}):`, extraKeys);
}
} else {
console.log(`${file} is fully consistent (matches all keys).`);
}
} catch (err) {
hasError = true;
console.error(`❌ Failed to parse ${file}:`, err.message);
}
}
console.log('');
if (hasError) {
console.error('❌ Website locale consistency check failed! Fix the errors above.');
process.exit(1);
} else {
console.log('🎉 All website locale files are perfectly synchronized and consistent!');
process.exit(0);
}
+1
View File
@@ -20,6 +20,7 @@ const checks = [
['popup syntax', 'node', ['-c', 'extension/popup.js']], ['popup syntax', 'node', ['-c', 'extension/popup.js']],
['background syntax', 'node', ['-c', 'extension/background.js']], ['background syntax', 'node', ['-c', 'extension/background.js']],
['locale coverage', 'node', ['scripts/test-locales.js']], ['locale coverage', 'node', ['scripts/test-locales.js']],
['website locale coverage', 'node', ['scripts/test-website-locales.mjs']],
['lint', 'npm', ['run', 'lint']], ['lint', 'npm', ['run', 'lint']],
['root production audit', 'npm', ['audit', '--omit=dev']], ['root production audit', 'npm', ['audit', '--omit=dev']],
['server production audit', 'npm', ['audit', '--omit=dev'], { cwd: path.join(repoRoot, 'server') }], ['server production audit', 'npm', ['audit', '--omit=dev'], { cwd: path.join(repoRoot, 'server') }],
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

+1 -1
View File
@@ -71,7 +71,7 @@
"COMP_FEAT_5_TELE": "Nur unterstützte Seiten", "COMP_FEAT_5_TELE": "Nur unterstützte Seiten",
"COMP_FEAT_6_NAME": "Lokalisierung / Übersetzung", "COMP_FEAT_6_NAME": "Lokalisierung / Übersetzung",
"COMP_FEAT_6_DESC": "Verfügbare Oberflächensprachen und Übersetzungsunterstützung.", "COMP_FEAT_6_DESC": "Verfügbare Oberflächensprachen und Übersetzungsunterstützung.",
"COMP_FEAT_6_KOALA": "6 Sprachen (wachsend)", "COMP_FEAT_6_KOALA": "13 Sprachen (wachsend)",
"COMP_FEAT_6_TELE": "Nur Englisch", "COMP_FEAT_6_TELE": "Nur Englisch",
"COMP_FOOTNOTE_1": "Stand des Vergleichs: Mai 2026.", "COMP_FOOTNOTE_1": "Stand des Vergleichs: Mai 2026.",
"COMP_FOOTNOTE_2": "Details zu Preisen und unterstützten Netzwerken von Teleparty Premium:", "COMP_FOOTNOTE_2": "Details zu Preisen und unterstützten Netzwerken von Teleparty Premium:",
+1 -1
View File
@@ -71,7 +71,7 @@
"COMP_FEAT_5_TELE": "Supported sites only", "COMP_FEAT_5_TELE": "Supported sites only",
"COMP_FEAT_6_NAME": "Localization / Translation", "COMP_FEAT_6_NAME": "Localization / Translation",
"COMP_FEAT_6_DESC": "Available interface languages and translation support.", "COMP_FEAT_6_DESC": "Available interface languages and translation support.",
"COMP_FEAT_6_KOALA": "6 Languages (and growing)", "COMP_FEAT_6_KOALA": "13 Languages (and growing)",
"COMP_FEAT_6_TELE": "English only", "COMP_FEAT_6_TELE": "English only",
"COMP_FOOTNOTE_1": "Comparison state: May 2026.", "COMP_FOOTNOTE_1": "Comparison state: May 2026.",
"COMP_FOOTNOTE_2": "Official Teleparty Premium pricing and supported networks details:", "COMP_FOOTNOTE_2": "Official Teleparty Premium pricing and supported networks details:",
+1 -1
View File
@@ -71,7 +71,7 @@
"COMP_FEAT_5_TELE": "Solo sitios compatibles", "COMP_FEAT_5_TELE": "Solo sitios compatibles",
"COMP_FEAT_6_NAME": "Localización / Traducción", "COMP_FEAT_6_NAME": "Localización / Traducción",
"COMP_FEAT_6_DESC": "Idiomas de interfaz disponibles y soporte de traducción.", "COMP_FEAT_6_DESC": "Idiomas de interfaz disponibles y soporte de traducción.",
"COMP_FEAT_6_KOALA": "6 idiomas (y creciendo)", "COMP_FEAT_6_KOALA": "13 idiomas (y creciendo)",
"COMP_FEAT_6_TELE": "Solo inglés", "COMP_FEAT_6_TELE": "Solo inglés",
"COMP_FOOTNOTE_1": "Estado de la comparación: mayo de 2026.", "COMP_FOOTNOTE_1": "Estado de la comparación: mayo de 2026.",
"COMP_FOOTNOTE_2": "Detalles oficiales de precios de Teleparty Premium y redes compatibles:", "COMP_FOOTNOTE_2": "Detalles oficiales de precios de Teleparty Premium y redes compatibles:",
+1 -1
View File
@@ -71,7 +71,7 @@
"COMP_FEAT_5_TELE": "Sites pris en charge uniquement", "COMP_FEAT_5_TELE": "Sites pris en charge uniquement",
"COMP_FEAT_6_NAME": "Localisation / Traduction", "COMP_FEAT_6_NAME": "Localisation / Traduction",
"COMP_FEAT_6_DESC": "Langues d'interface disponibles et support de traduction.", "COMP_FEAT_6_DESC": "Langues d'interface disponibles et support de traduction.",
"COMP_FEAT_6_KOALA": "6 langues (et plus à venir)", "COMP_FEAT_6_KOALA": "13 langues (et plus à venir)",
"COMP_FEAT_6_TELE": "Anglais uniquement", "COMP_FEAT_6_TELE": "Anglais uniquement",
"COMP_FOOTNOTE_1": "État de la comparaison : mai 2026.", "COMP_FOOTNOTE_1": "État de la comparaison : mai 2026.",
"COMP_FOOTNOTE_2": "Détails sur les tarifs officiels de Teleparty Premium et les réseaux pris en charge :", "COMP_FOOTNOTE_2": "Détails sur les tarifs officiels de Teleparty Premium et les réseaux pris en charge :",
+1 -1
View File
@@ -123,7 +123,7 @@
"HOWTO_STEP_1_NAME": "브라우저 확장 프로그램 설치", "HOWTO_STEP_1_NAME": "브라우저 확장 프로그램 설치",
"HOWTO_STEP_1_TEXT": "Chrome 웹 스토어 또는 Firefox 부가 기능에서 KoalaSync를 브라우저에 추가하세요. 비디오 요소가 있는 모든 웹사이트에서 작동합니다.", "HOWTO_STEP_1_TEXT": "Chrome 웹 스토어 또는 Firefox 부가 기능에서 KoalaSync를 브라우저에 추가하세요. 비디오 요소가 있는 모든 웹사이트에서 작동합니다.",
"HOWTO_STEP_2_NAME": "방 만들기", "HOWTO_STEP_2_NAME": "방 만들기",
"HOWTO_STEP_2_TEXT": "확장 프로그램 팝업을 열고 '새 방 만들기'를 클릭하세요. 초대 링크가 클rip보드에 자동으로 복사됩니다.", "HOWTO_STEP_2_TEXT": "확장 프로그램 팝업을 열고 '새 방 만들기'를 클릭하세요. 초대 링크가 클보드에 자동으로 복사됩니다.",
"HOWTO_STEP_3_NAME": "공유 및 동기화", "HOWTO_STEP_3_NAME": "공유 및 동기화",
"HOWTO_STEP_3_TEXT": "친구들에게 초대 링크를 보내세요. 비디오 탭을 선택하고 실시간으로 동기화된 재생을 즐기세요.", "HOWTO_STEP_3_TEXT": "친구들에게 초대 링크를 보내세요. 비디오 탭을 선택하고 실시간으로 동기화된 재생을 즐기세요.",
"FOOTER_MIT": "MIT 라이선스에 따른 오픈 소스.", "FOOTER_MIT": "MIT 라이선스에 따른 오픈 소스.",
+1 -1
View File
@@ -71,7 +71,7 @@
"COMP_FEAT_5_TELE": "Apenas sites suportados", "COMP_FEAT_5_TELE": "Apenas sites suportados",
"COMP_FEAT_6_NAME": "Localização / Tradução", "COMP_FEAT_6_NAME": "Localização / Tradução",
"COMP_FEAT_6_DESC": "Idiomas de interface disponíveis e suporte a tradução.", "COMP_FEAT_6_DESC": "Idiomas de interface disponíveis e suporte a tradução.",
"COMP_FEAT_6_KOALA": "6 idiomas (e crescendo)", "COMP_FEAT_6_KOALA": "13 idiomas (e crescendo)",
"COMP_FEAT_6_TELE": "Apenas inglês", "COMP_FEAT_6_TELE": "Apenas inglês",
"COMP_FOOTNOTE_1": "Estado da comparação: maio de 2026.", "COMP_FOOTNOTE_1": "Estado da comparação: maio de 2026.",
"COMP_FOOTNOTE_2": "Preços oficiais do Teleparty Premium e detalhes das redes suportadas:", "COMP_FOOTNOTE_2": "Preços oficiais do Teleparty Premium e detalhes das redes suportadas:",
+4 -4
View File
@@ -33,9 +33,9 @@
"USE_CASE_3_TITLE": "Relacionamentos à Distância", "USE_CASE_3_TITLE": "Relacionamentos à Distância",
"USE_CASE_3_DESC": "Ponte para a distância e aproveite as noites de encontros. Experimente cada reviravolta, ria das mesmas piadas e partilhe momentos emocionantes exatamente no mesmo milissegundo.", "USE_CASE_3_DESC": "Ponte para a distância e aproveite as noites de encontros. Experimente cada reviravolta, ria das mesmas piadas e partilhe momentos emocionantes exatamente no mesmo milissegundo.",
"WHY_TITLE": "Porquê KoalaSync?", "WHY_TITLE": "Porquê KoalaSync?",
"WHY_SUBTITLE": "Construído para uma sincronizzazione fiável, design focado na privacidade e configuração simples.", "WHY_SUBTITLE": "Construído para uma sincronização fiável, design focado na privacidade e configuração simples.",
"FEATURE_1_TITLE": "Controlo Total / Sincronização Instantânea", "FEATURE_1_TITLE": "Controlo Total / Sincronização Instantânea",
"FEATURE_1_DESC": "Um pausa, todos pausam. Um avança, todos seguem. O nosso protocolo di sincronizzazione a duas fases coordena a reprodução em tempo reale em todos os participantes.", "FEATURE_1_DESC": "Um pausa, todos pausam. Um avança, todos seguem. O nosso protocolo de sincronização a duas fases coordena a reprodução em tempo real em todos os participantes.",
"FEATURE_2_TITLE": "Binge-Watching Infinito", "FEATURE_2_TITLE": "Binge-Watching Infinito",
"FEATURE_2_DESC": "Reprodução automática em sincronia. O KoalaSync deteta automaticamente as transições de episódios e aguarda até que todos os peers tenham carregado o vídeo seguinte.", "FEATURE_2_DESC": "Reprodução automática em sincronia. O KoalaSync deteta automaticamente as transições de episódios e aguarda até que todos os peers tenham carregado o vídeo seguinte.",
"FEATURE_3_TITLE": "Zero Contas / Privacidade Pura", "FEATURE_3_TITLE": "Zero Contas / Privacidade Pura",
@@ -132,12 +132,12 @@
"FOOTER_PRIVACY": "Política de Privacidade", "FOOTER_PRIVACY": "Política de Privacidade",
"MOCK_01": "Sala Ativa", "MOCK_01": "Sala Ativa",
"MOCK_02": "Servidor Oficial", "MOCK_02": "Servidor Oficial",
"MOCK_03": "Link de Invito", "MOCK_03": "Link de Convite",
"MOCK_04": "Participantes na Sala", "MOCK_04": "Participantes na Sala",
"MOCK_05": "YOU", "MOCK_05": "YOU",
"MOCK_06": "Playing", "MOCK_06": "Playing",
"MOCK_07": "Peer", "MOCK_07": "Peer",
"MOCK_08": "Sair della Sala", "MOCK_08": "Sair da Sala",
"MOCK_09": "Selecionar Vídeo", "MOCK_09": "Selecionar Vídeo",
"MOCK_10": "Controlo Remoto", "MOCK_10": "Controlo Remoto",
"MOCK_11": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"14\" height=\"14\" aria-hidden=\"true\"><polygon points=\"5 3 19 12 5 21 5 3\"/></svg> Play", "MOCK_11": "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"currentColor\" width=\"14\" height=\"14\" aria-hidden=\"true\"><polygon points=\"5 3 19 12 5 21 5 3\"/></svg> Play",
+1 -1
View File
@@ -71,7 +71,7 @@
"COMP_FEAT_5_TELE": "Только поддерживаемые сайты", "COMP_FEAT_5_TELE": "Только поддерживаемые сайты",
"COMP_FEAT_6_NAME": "Локализация / Перевод", "COMP_FEAT_6_NAME": "Локализация / Перевод",
"COMP_FEAT_6_DESC": "Доступные языки интерфейса и поддержка перевода.", "COMP_FEAT_6_DESC": "Доступные языки интерфейса и поддержка перевода.",
"COMP_FEAT_6_KOALA": "6 языков (и расширяется)", "COMP_FEAT_6_KOALA": "13 языков (и расширяется)",
"COMP_FEAT_6_TELE": "Только английский", "COMP_FEAT_6_TELE": "Только английский",
"COMP_FOOTNOTE_1": "Состояние сравнения: май 2026.", "COMP_FOOTNOTE_1": "Состояние сравнения: май 2026.",
"COMP_FOOTNOTE_2": "Официальные цены Teleparty Premium и поддерживаемые сети:", "COMP_FOOTNOTE_2": "Официальные цены Teleparty Premium и поддерживаемые сети:",
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

+1 -1
View File
@@ -796,7 +796,7 @@
<strong><span>Lokalisierung / Übersetzung</span></strong> <strong><span>Lokalisierung / Übersetzung</span></strong>
<span class="feat-desc"><span>Verfügbare Oberflächensprachen und Übersetzungsunterstützung.</span></span> <span class="feat-desc"><span>Verfügbare Oberflächensprachen und Übersetzungsunterstützung.</span></span>
</td> </td>
<td class="check highlight"><span>6 Sprachen (wachsend)</span></td> <td class="check highlight"><span>13 Sprachen (wachsend)</span></td>
<td class="cross"> <td class="cross">
<span>Nur Englisch</span> <span>Nur Englisch</span>
</td> </td>
+1 -1
View File
@@ -796,7 +796,7 @@
<strong><span>Localización / Traducción</span></strong> <strong><span>Localización / Traducción</span></strong>
<span class="feat-desc"><span>Idiomas de interfaz disponibles y soporte de traducción.</span></span> <span class="feat-desc"><span>Idiomas de interfaz disponibles y soporte de traducción.</span></span>
</td> </td>
<td class="check highlight"><span>6 idiomas (y creciendo)</span></td> <td class="check highlight"><span>13 idiomas (y creciendo)</span></td>
<td class="cross"> <td class="cross">
<span>Solo inglés</span> <span>Solo inglés</span>
</td> </td>
+1 -1
View File
@@ -796,7 +796,7 @@
<strong><span>Localisation / Traduction</span></strong> <strong><span>Localisation / Traduction</span></strong>
<span class="feat-desc"><span>Langues d'interface disponibles et support de traduction.</span></span> <span class="feat-desc"><span>Langues d'interface disponibles et support de traduction.</span></span>
</td> </td>
<td class="check highlight"><span>6 langues (et plus à venir)</span></td> <td class="check highlight"><span>13 langues (et plus à venir)</span></td>
<td class="cross"> <td class="cross">
<span>Anglais uniquement</span> <span>Anglais uniquement</span>
</td> </td>
+1 -1
View File
@@ -796,7 +796,7 @@
<strong><span>Localization / Translation</span></strong> <strong><span>Localization / Translation</span></strong>
<span class="feat-desc"><span>Available interface languages and translation support.</span></span> <span class="feat-desc"><span>Available interface languages and translation support.</span></span>
</td> </td>
<td class="check highlight"><span>6 Languages (and growing)</span></td> <td class="check highlight"><span>13 Languages (and growing)</span></td>
<td class="cross"> <td class="cross">
<span>English only</span> <span>English only</span>
</td> </td>
+1 -1
View File
@@ -127,7 +127,7 @@
"@type": "HowToStep", "@type": "HowToStep",
"position": 2, "position": 2,
"name": "방 만들기", "name": "방 만들기",
"text": "확장 프로그램 팝업을 열고 '새 방 만들기'를 클릭하세요. 초대 링크가 클rip보드에 자동으로 복사됩니다.", "text": "확장 프로그램 팝업을 열고 '새 방 만들기'를 클릭하세요. 초대 링크가 클보드에 자동으로 복사됩니다.",
"url": "https://sync.koalastuff.net/#how-it-works" "url": "https://sync.koalastuff.net/#how-it-works"
}, },
{ {
+1 -1
View File
@@ -796,7 +796,7 @@
<strong><span>Localização / Tradução</span></strong> <strong><span>Localização / Tradução</span></strong>
<span class="feat-desc"><span>Idiomas de interface disponíveis e suporte a tradução.</span></span> <span class="feat-desc"><span>Idiomas de interface disponíveis e suporte a tradução.</span></span>
</td> </td>
<td class="check highlight"><span>6 idiomas (e crescendo)</span></td> <td class="check highlight"><span>13 idiomas (e crescendo)</span></td>
<td class="cross"> <td class="cross">
<span>Apenas inglês</span> <span>Apenas inglês</span>
</td> </td>
+5 -5
View File
@@ -303,7 +303,7 @@
<span class="mock-server-badge" style="font-size: 0.6rem; color: var(--text-muted);">Servidor Oficial</span> <span class="mock-server-badge" style="font-size: 0.6rem; color: var(--text-muted);">Servidor Oficial</span>
</div> </div>
<div class="mock-card"> <div class="mock-card">
<div class="mock-label" title="Share this link with friends so they can join">Link de Invito</div> <div class="mock-label" title="Share this link with friends so they can join">Link de Convite</div>
<div class="mock-invite-box"> <div class="mock-invite-box">
<input type="text" class="mock-input" value="https://sync.koalastuff.net/join#join:brave-eagle-80:pass" readonly style="flex: 1;" aria-label="Invite link"> <input type="text" class="mock-input" value="https://sync.koalastuff.net/join#join:brave-eagle-80:pass" readonly style="flex: 1;" aria-label="Invite link">
<button class="mock-btn" style="width: 40px; padding: 0.45rem 0; flex-shrink: 0; background: #334155;" title="Copy Invite Link"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" aria-hidden="true" viewBox="0 0 24 24"><rect width="13" height="13" x="9" y="9" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button> <button class="mock-btn" style="width: 40px; padding: 0.45rem 0; flex-shrink: 0; background: #334155;" title="Copy Invite Link"><svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" aria-hidden="true" viewBox="0 0 24 24"><rect width="13" height="13" x="9" y="9" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></button>
@@ -330,7 +330,7 @@
</div> </div>
</div> </div>
</div> </div>
<button class="mock-btn" style="background:#ef4444; width:100%; border: none; padding: 10px; border-radius: 8px; color: white; font-weight: 700; cursor: pointer; border: 1px solid #ef4444;">Sair della Sala</button> <button class="mock-btn" style="background:#ef4444; width:100%; border: none; padding: 10px; border-radius: 8px; color: white; font-weight: 700; cursor: pointer; border: 1px solid #ef4444;">Sair da Sala</button>
</div> </div>
<!-- SYNC TAB --> <!-- SYNC TAB -->
@@ -350,7 +350,7 @@
</label> </label>
<button class="mock-btn" style="background:transparent; border: 1px solid #334155; border-radius: 6px; padding: 2px 6px; font-size: 0.65rem; cursor:default; opacity:0.8; color: var(--text-muted); display: flex; align-items: center; gap: 4px; white-space: nowrap;" title="Copy Invite Link"> <button class="mock-btn" style="background:transparent; border: 1px solid #334155; border-radius: 6px; padding: 2px 6px; font-size: 0.65rem; cursor:default; opacity:0.8; color: var(--text-muted); display: flex; align-items: center; gap: 4px; white-space: nowrap;" title="Copy Invite Link">
<span><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" aria-hidden="true" viewBox="0 0 24 24"><rect width="13" height="13" x="9" y="9" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></span> <span><svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" aria-hidden="true" viewBox="0 0 24 24"><rect width="13" height="13" x="9" y="9" rx="2" ry="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg></span>
Link de Invito Link de Convite
</button> </button>
</div> </div>
<div style="display: flex; gap: 8px; margin-bottom: 12px;"> <div style="display: flex; gap: 8px; margin-bottom: 12px;">
@@ -638,7 +638,7 @@
<span>Porquê KoalaSync?</span> <span>Porquê KoalaSync?</span>
</h2> </h2>
<p style="text-align: center; color: var(--text-muted); margin-bottom: 4rem;"> <p style="text-align: center; color: var(--text-muted); margin-bottom: 4rem;">
<span>Construído para uma sincronizzazione fiável, design focado na privacidade e configuração simples.</span> <span>Construído para uma sincronização fiável, design focado na privacidade e configuração simples.</span>
</p> </p>
<div class="features-grid"> <div class="features-grid">
@@ -650,7 +650,7 @@
</span> </span>
<span>Controlo Total / Sincronização Instantânea</span> <span>Controlo Total / Sincronização Instantânea</span>
</h3> </h3>
<p>Um pausa, todos pausam. Um avança, todos seguem. O nosso protocolo di sincronizzazione a duas fases coordena a reprodução em tempo reale em todos os participantes.</p> <p>Um pausa, todos pausam. Um avança, todos seguem. O nosso protocolo de sincronização a duas fases coordena a reprodução em tempo real em todos os participantes.</p>
</div> </div>
<!-- Card 2: Endless Binge-Watching (Bento Standard) --> <!-- Card 2: Endless Binge-Watching (Bento Standard) -->
+1 -1
View File
@@ -796,7 +796,7 @@
<strong><span>Локализация / Перевод</span></strong> <strong><span>Локализация / Перевод</span></strong>
<span class="feat-desc"><span>Доступные языки интерфейса и поддержка перевода.</span></span> <span class="feat-desc"><span>Доступные языки интерфейса и поддержка перевода.</span></span>
</td> </td>
<td class="check highlight"><span>6 языков (и расширяется)</span></td> <td class="check highlight"><span>13 языков (и расширяется)</span></td>
<td class="cross"> <td class="cross">
<span>Только английский</span> <span>Только английский</span>
</td> </td>