diff --git a/.gitignore b/.gitignore index efd2b6c5..6486d03e 100644 --- a/.gitignore +++ b/.gitignore @@ -105,4 +105,5 @@ LibTorrent/ iTorrent/ simkl-docss downloader.md -server \ No newline at end of file +server +Deliverables 2 \ No newline at end of file diff --git a/App.tsx b/App.tsx index 87b97907..40642842 100644 --- a/App.tsx +++ b/App.tsx @@ -50,6 +50,7 @@ import { mmkvStorage } from './src/services/mmkvStorage'; import { CampaignManager } from './src/components/promotions/CampaignManager'; import { isErrorReportingEnabledSync } from './src/services/telemetryService'; import { networkPrivacyService } from './src/services/networkPrivacyService'; +import { supabaseSyncService } from './src/services/supabaseSyncService'; // Initialize Sentry with privacy-first defaults // Settings are loaded from telemetryService and can be controlled by user @@ -183,6 +184,15 @@ const ThemedApp = () => { const onboardingCompleted = await mmkvStorage.getItem('hasCompletedOnboarding'); setHasCompletedOnboarding(onboardingCompleted === 'true'); + // Initialize Supabase auth/session and start background sync. + // This is intentionally non-blocking for app startup UX. + supabaseSyncService + .initialize() + .then(() => supabaseSyncService.startupSync()) + .catch((error) => { + console.warn('[App] Supabase sync bootstrap failed:', error); + }); + // Initialize update service await UpdateService.initialize(); diff --git a/README.md b/README.md index 671cef36..dca575ef 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@
- Nuvio + Nuvio

diff --git a/android/.kotlin/sessions/kotlin-compiler-17947464936783636493.salive b/android/.kotlin/sessions/kotlin-compiler-17947464936783636493.salive new file mode 100644 index 00000000..e69de29b diff --git a/android/app/build.gradle b/android/app/build.gradle index 86a13334..13cefd46 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -95,8 +95,8 @@ android { applicationId 'com.nuvio.app' minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 35 - versionName "1.3.7" + versionCode 36 + versionName "1.4.0" buildConfigField "String", "REACT_NATIVE_RELEASE_LEVEL", "\"${findProperty('reactNativeReleaseLevel') ?: 'stable'}\"" } @@ -118,7 +118,7 @@ android { def abiVersionCodes = ['armeabi-v7a': 1, 'arm64-v8a': 2, 'x86': 3, 'x86_64': 4] applicationVariants.all { variant -> variant.outputs.each { output -> - def baseVersionCode = 35 // Current versionCode 35 from defaultConfig + def baseVersionCode = 36 // Current versionCode 36 from defaultConfig def abiName = output.getFilter(com.android.build.OutputFile.ABI) def versionCode = baseVersionCode * 100 // Base multiplier diff --git a/android/app/src/main/res/drawable-hdpi/splashscreen_logo.png b/android/app/src/main/res/drawable-hdpi/splashscreen_logo.png index 15b512eb..84066f8c 100644 Binary files a/android/app/src/main/res/drawable-hdpi/splashscreen_logo.png and b/android/app/src/main/res/drawable-hdpi/splashscreen_logo.png differ diff --git a/android/app/src/main/res/drawable-mdpi/splashscreen_logo.png b/android/app/src/main/res/drawable-mdpi/splashscreen_logo.png index 8b78e2f9..a1907f1b 100644 Binary files a/android/app/src/main/res/drawable-mdpi/splashscreen_logo.png and b/android/app/src/main/res/drawable-mdpi/splashscreen_logo.png differ diff --git a/android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png b/android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png index 528962ab..5e73c55f 100644 Binary files a/android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png and b/android/app/src/main/res/drawable-xhdpi/splashscreen_logo.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png b/android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png index 0969e6a3..81d907ff 100644 Binary files a/android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png and b/android/app/src/main/res/drawable-xxhdpi/splashscreen_logo.png differ diff --git a/android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png b/android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png index 7de47821..bb8a75f5 100644 Binary files a/android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png and b/android/app/src/main/res/drawable-xxxhdpi/splashscreen_logo.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp index 70320a98..409cd825 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.webp differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp index 46b9e444..fa1a496b 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.webp differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp index 63e85ffe..9ea4744d 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp index a5a1dfa9..0d22646c 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.webp differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp index 133272a5..7acd5195 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.webp differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp index a1156c2f..e152d6b3 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp index 705ab974..fa2054ea 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.webp differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp index 401543d6..f1994a0d 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.webp differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp index 111ae461..8d958805 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp index 76fb597c..72ed3e7e 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp index 5e694a8a..e0989481 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.webp differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp index a06585cb..6f370d8c 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp index 57b30c91..7ec5130e 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp index ab60c474..9ac056b7 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.webp differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp index acdda655..6fe44f1f 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp differ diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 9b0596a4..0c2f2351 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -3,5 +3,5 @@ contain false dark - 1.3.7 + 1.4.0 \ No newline at end of file diff --git a/app.json b/app.json index d5510500..4fd63fba 100644 --- a/app.json +++ b/app.json @@ -2,7 +2,7 @@ "expo": { "name": "Nuvio", "slug": "nuvio", - "version": "1.3.7", + "version": "1.4.0", "orientation": "default", "backgroundColor": "#020404", "icon": "./assets/ios/AppIcon.appiconset/Icon-App-60x60@3x.png", @@ -17,7 +17,7 @@ "ios": { "supportsTablet": true, "icon": "./assets/ios/AppIcon.appiconset/Icon-App-60x60@3x.png", - "buildNumber": "35", + "buildNumber": "36", "infoPlist": { "NSAppTransportSecurity": { "NSAllowsArbitraryLoads": true @@ -35,7 +35,7 @@ "LSSupportsOpeningDocumentsInPlace": true, "UIFileSharingEnabled": true }, - "bundleIdentifier": "com.nuvio.app", + "bundleIdentifier": "com.nuvio.hub", "associatedDomains": [], "jsEngine": "hermes", "appleTeamId": "8QBDZ766S3" @@ -52,7 +52,7 @@ "android.permission.WRITE_SETTINGS" ], "package": "com.nuvio.app", - "versionCode": 35, + "versionCode": 36, "architectures": [ "arm64-v8a", "armeabi-v7a", @@ -105,6 +105,6 @@ "fallbackToCacheTimeout": 30000, "url": "https://ota.nuvioapp.space/api/manifest" }, - "runtimeVersion": "1.3.7" + "runtimeVersion": "1.4.0" } } diff --git a/assets/AppIcons/android/mipmap-hdpi/ic_launcher.png b/assets/AppIcons/android/mipmap-hdpi/ic_launcher.png index fc396770..589a0139 100644 Binary files a/assets/AppIcons/android/mipmap-hdpi/ic_launcher.png and b/assets/AppIcons/android/mipmap-hdpi/ic_launcher.png differ diff --git a/assets/AppIcons/android/mipmap-mdpi/ic_launcher.png b/assets/AppIcons/android/mipmap-mdpi/ic_launcher.png index 02d4de67..3a9261d7 100644 Binary files a/assets/AppIcons/android/mipmap-mdpi/ic_launcher.png and b/assets/AppIcons/android/mipmap-mdpi/ic_launcher.png differ diff --git a/assets/AppIcons/android/mipmap-xhdpi/ic_launcher.png b/assets/AppIcons/android/mipmap-xhdpi/ic_launcher.png index 41b56cf1..3c101f3f 100644 Binary files a/assets/AppIcons/android/mipmap-xhdpi/ic_launcher.png and b/assets/AppIcons/android/mipmap-xhdpi/ic_launcher.png differ diff --git a/assets/AppIcons/android/mipmap-xxhdpi/ic_launcher.png b/assets/AppIcons/android/mipmap-xxhdpi/ic_launcher.png index 570413cc..4a50f3a8 100644 Binary files a/assets/AppIcons/android/mipmap-xxhdpi/ic_launcher.png and b/assets/AppIcons/android/mipmap-xxhdpi/ic_launcher.png differ diff --git a/assets/AppIcons/android/mipmap-xxxhdpi/ic_launcher.png b/assets/AppIcons/android/mipmap-xxxhdpi/ic_launcher.png index a101d4a9..c72a7215 100644 Binary files a/assets/AppIcons/android/mipmap-xxxhdpi/ic_launcher.png and b/assets/AppIcons/android/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/assets/android/ic_launcher-web.png b/assets/android/ic_launcher-web.png index 493e3b98..b2f544c0 100644 Binary files a/assets/android/ic_launcher-web.png and b/assets/android/ic_launcher-web.png differ diff --git a/assets/android/mipmap-hdpi/ic_launcher.png b/assets/android/mipmap-hdpi/ic_launcher.png index 558dfbae..d044d633 100644 Binary files a/assets/android/mipmap-hdpi/ic_launcher.png and b/assets/android/mipmap-hdpi/ic_launcher.png differ diff --git a/assets/android/mipmap-hdpi/ic_launcher_foreground.png b/assets/android/mipmap-hdpi/ic_launcher_foreground.png index 2f49c5f1..0d8e9ca8 100644 Binary files a/assets/android/mipmap-hdpi/ic_launcher_foreground.png and b/assets/android/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/assets/android/mipmap-hdpi/ic_launcher_round.png b/assets/android/mipmap-hdpi/ic_launcher_round.png index 1b48a3ef..589a0139 100644 Binary files a/assets/android/mipmap-hdpi/ic_launcher_round.png and b/assets/android/mipmap-hdpi/ic_launcher_round.png differ diff --git a/assets/android/mipmap-ldpi/ic_launcher.png b/assets/android/mipmap-ldpi/ic_launcher.png index 3524b2fc..7912de17 100644 Binary files a/assets/android/mipmap-ldpi/ic_launcher.png and b/assets/android/mipmap-ldpi/ic_launcher.png differ diff --git a/assets/android/mipmap-ldpi/ic_launcher_foreground.png b/assets/android/mipmap-ldpi/ic_launcher_foreground.png new file mode 100644 index 00000000..efd269fb Binary files /dev/null and b/assets/android/mipmap-ldpi/ic_launcher_foreground.png differ diff --git a/assets/android/mipmap-ldpi/ic_launcher_round.png b/assets/android/mipmap-ldpi/ic_launcher_round.png index 02020f6f..1a964dbd 100644 Binary files a/assets/android/mipmap-ldpi/ic_launcher_round.png and b/assets/android/mipmap-ldpi/ic_launcher_round.png differ diff --git a/assets/android/mipmap-mdpi/ic_launcher.png b/assets/android/mipmap-mdpi/ic_launcher.png index 6c259c80..526eaffd 100644 Binary files a/assets/android/mipmap-mdpi/ic_launcher.png and b/assets/android/mipmap-mdpi/ic_launcher.png differ diff --git a/assets/android/mipmap-mdpi/ic_launcher_foreground.png b/assets/android/mipmap-mdpi/ic_launcher_foreground.png index 64546171..335c655b 100644 Binary files a/assets/android/mipmap-mdpi/ic_launcher_foreground.png and b/assets/android/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/assets/android/mipmap-mdpi/ic_launcher_round.png b/assets/android/mipmap-mdpi/ic_launcher_round.png index f637369f..3a9261d7 100644 Binary files a/assets/android/mipmap-mdpi/ic_launcher_round.png and b/assets/android/mipmap-mdpi/ic_launcher_round.png differ diff --git a/assets/android/mipmap-xhdpi/ic_launcher.png b/assets/android/mipmap-xhdpi/ic_launcher.png index 9fb69a54..3c101f3f 100644 Binary files a/assets/android/mipmap-xhdpi/ic_launcher.png and b/assets/android/mipmap-xhdpi/ic_launcher.png differ diff --git a/assets/android/mipmap-xhdpi/ic_launcher_foreground.png b/assets/android/mipmap-xhdpi/ic_launcher_foreground.png index f03be67e..f964ed8d 100644 Binary files a/assets/android/mipmap-xhdpi/ic_launcher_foreground.png and b/assets/android/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/assets/android/mipmap-xhdpi/ic_launcher_round.png b/assets/android/mipmap-xhdpi/ic_launcher_round.png index c34a4836..3c101f3f 100644 Binary files a/assets/android/mipmap-xhdpi/ic_launcher_round.png and b/assets/android/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/assets/android/mipmap-xxhdpi/ic_launcher.png b/assets/android/mipmap-xxhdpi/ic_launcher.png index d16402dd..4a50f3a8 100644 Binary files a/assets/android/mipmap-xxhdpi/ic_launcher.png and b/assets/android/mipmap-xxhdpi/ic_launcher.png differ diff --git a/assets/android/mipmap-xxhdpi/ic_launcher_foreground.png b/assets/android/mipmap-xxhdpi/ic_launcher_foreground.png index 8605f5e6..0e2377c7 100644 Binary files a/assets/android/mipmap-xxhdpi/ic_launcher_foreground.png and b/assets/android/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/assets/android/mipmap-xxhdpi/ic_launcher_round.png b/assets/android/mipmap-xxhdpi/ic_launcher_round.png index 749d0724..4a50f3a8 100644 Binary files a/assets/android/mipmap-xxhdpi/ic_launcher_round.png and b/assets/android/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/assets/android/mipmap-xxxhdpi/ic_launcher.png b/assets/android/mipmap-xxxhdpi/ic_launcher.png index 2e35f619..c72a7215 100644 Binary files a/assets/android/mipmap-xxxhdpi/ic_launcher.png and b/assets/android/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/assets/android/mipmap-xxxhdpi/ic_launcher_foreground.png b/assets/android/mipmap-xxxhdpi/ic_launcher_foreground.png index 6cc901eb..dd2e6bee 100644 Binary files a/assets/android/mipmap-xxxhdpi/ic_launcher_foreground.png and b/assets/android/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/assets/android/mipmap-xxxhdpi/ic_launcher_round.png b/assets/android/mipmap-xxxhdpi/ic_launcher_round.png index 06cdb2f5..c72a7215 100644 Binary files a/assets/android/mipmap-xxxhdpi/ic_launcher_round.png and b/assets/android/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/assets/android/playstore-icon.png b/assets/android/playstore-icon.png index e5dd4a6b..b2f544c0 100644 Binary files a/assets/android/playstore-icon.png and b/assets/android/playstore-icon.png differ diff --git a/assets/ios/AppIcon.appiconset/Icon-App-20x20@1x.png b/assets/ios/AppIcon.appiconset/Icon-App-20x20@1x.png index 18d719cf..1fdc796e 100644 Binary files a/assets/ios/AppIcon.appiconset/Icon-App-20x20@1x.png and b/assets/ios/AppIcon.appiconset/Icon-App-20x20@1x.png differ diff --git a/assets/ios/AppIcon.appiconset/Icon-App-20x20@2x.png b/assets/ios/AppIcon.appiconset/Icon-App-20x20@2x.png index 5bd9ac8e..35572c94 100644 Binary files a/assets/ios/AppIcon.appiconset/Icon-App-20x20@2x.png and b/assets/ios/AppIcon.appiconset/Icon-App-20x20@2x.png differ diff --git a/assets/ios/AppIcon.appiconset/Icon-App-20x20@3x.png b/assets/ios/AppIcon.appiconset/Icon-App-20x20@3x.png index a526217a..92d5c55a 100644 Binary files a/assets/ios/AppIcon.appiconset/Icon-App-20x20@3x.png and b/assets/ios/AppIcon.appiconset/Icon-App-20x20@3x.png differ diff --git a/assets/ios/AppIcon.appiconset/Icon-App-29x29@1x.png b/assets/ios/AppIcon.appiconset/Icon-App-29x29@1x.png index e2841b48..8954f0f4 100644 Binary files a/assets/ios/AppIcon.appiconset/Icon-App-29x29@1x.png and b/assets/ios/AppIcon.appiconset/Icon-App-29x29@1x.png differ diff --git a/assets/ios/AppIcon.appiconset/Icon-App-29x29@2x.png b/assets/ios/AppIcon.appiconset/Icon-App-29x29@2x.png index 34e2d79c..37175fd9 100644 Binary files a/assets/ios/AppIcon.appiconset/Icon-App-29x29@2x.png and b/assets/ios/AppIcon.appiconset/Icon-App-29x29@2x.png differ diff --git a/assets/ios/AppIcon.appiconset/Icon-App-29x29@3x.png b/assets/ios/AppIcon.appiconset/Icon-App-29x29@3x.png index 11953d6c..77d6dc8d 100644 Binary files a/assets/ios/AppIcon.appiconset/Icon-App-29x29@3x.png and b/assets/ios/AppIcon.appiconset/Icon-App-29x29@3x.png differ diff --git a/assets/ios/AppIcon.appiconset/Icon-App-40x40@1x.png b/assets/ios/AppIcon.appiconset/Icon-App-40x40@1x.png index 5bd9ac8e..330fb482 100644 Binary files a/assets/ios/AppIcon.appiconset/Icon-App-40x40@1x.png and b/assets/ios/AppIcon.appiconset/Icon-App-40x40@1x.png differ diff --git a/assets/ios/AppIcon.appiconset/Icon-App-40x40@2x.png b/assets/ios/AppIcon.appiconset/Icon-App-40x40@2x.png index 56a3b787..2cda25b7 100644 Binary files a/assets/ios/AppIcon.appiconset/Icon-App-40x40@2x.png and b/assets/ios/AppIcon.appiconset/Icon-App-40x40@2x.png differ diff --git a/assets/ios/AppIcon.appiconset/Icon-App-40x40@3x.png b/assets/ios/AppIcon.appiconset/Icon-App-40x40@3x.png index c36efb6e..3678d9c9 100644 Binary files a/assets/ios/AppIcon.appiconset/Icon-App-40x40@3x.png and b/assets/ios/AppIcon.appiconset/Icon-App-40x40@3x.png differ diff --git a/assets/ios/AppIcon.appiconset/Icon-App-60x60@2x.png b/assets/ios/AppIcon.appiconset/Icon-App-60x60@2x.png index c36efb6e..3678d9c9 100644 Binary files a/assets/ios/AppIcon.appiconset/Icon-App-60x60@2x.png and b/assets/ios/AppIcon.appiconset/Icon-App-60x60@2x.png differ diff --git a/assets/ios/AppIcon.appiconset/Icon-App-60x60@3x.png b/assets/ios/AppIcon.appiconset/Icon-App-60x60@3x.png index d84612d1..7e8b1ce9 100644 Binary files a/assets/ios/AppIcon.appiconset/Icon-App-60x60@3x.png and b/assets/ios/AppIcon.appiconset/Icon-App-60x60@3x.png differ diff --git a/assets/ios/AppIcon.appiconset/Icon-App-76x76@1x.png b/assets/ios/AppIcon.appiconset/Icon-App-76x76@1x.png index 53317602..52b302e8 100644 Binary files a/assets/ios/AppIcon.appiconset/Icon-App-76x76@1x.png and b/assets/ios/AppIcon.appiconset/Icon-App-76x76@1x.png differ diff --git a/assets/ios/AppIcon.appiconset/Icon-App-76x76@2x.png b/assets/ios/AppIcon.appiconset/Icon-App-76x76@2x.png index 082be8c5..7e342789 100644 Binary files a/assets/ios/AppIcon.appiconset/Icon-App-76x76@2x.png and b/assets/ios/AppIcon.appiconset/Icon-App-76x76@2x.png differ diff --git a/assets/ios/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png b/assets/ios/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png index 2218f825..48877c47 100644 Binary files a/assets/ios/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png and b/assets/ios/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png differ diff --git a/assets/ios/AppIcon.appiconset/ItunesArtwork@2x.png b/assets/ios/AppIcon.appiconset/ItunesArtwork@2x.png index 8ac40dd4..8c09f13f 100644 Binary files a/assets/ios/AppIcon.appiconset/ItunesArtwork@2x.png and b/assets/ios/AppIcon.appiconset/ItunesArtwork@2x.png differ diff --git a/assets/ios/iTunesArtwork@1x.png b/assets/ios/iTunesArtwork@1x.png index 637db4d5..95e87d0b 100644 Binary files a/assets/ios/iTunesArtwork@1x.png and b/assets/ios/iTunesArtwork@1x.png differ diff --git a/assets/ios/iTunesArtwork@2x.png b/assets/ios/iTunesArtwork@2x.png index 8ac40dd4..8c09f13f 100644 Binary files a/assets/ios/iTunesArtwork@2x.png and b/assets/ios/iTunesArtwork@2x.png differ diff --git a/assets/ios/iTunesArtwork@3x.png b/assets/ios/iTunesArtwork@3x.png index 18b16be3..ce974813 100644 Binary files a/assets/ios/iTunesArtwork@3x.png and b/assets/ios/iTunesArtwork@3x.png differ diff --git a/assets/nuvio-sync-icon-og.png b/assets/nuvio-sync-icon-og.png new file mode 100644 index 00000000..28bf19e5 Binary files /dev/null and b/assets/nuvio-sync-icon-og.png differ diff --git a/assets/player-icons/ic_player_aspect_ratio.svg b/assets/player-icons/ic_player_aspect_ratio.svg new file mode 100644 index 00000000..12b2f7b6 --- /dev/null +++ b/assets/player-icons/ic_player_aspect_ratio.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/player-icons/ic_player_audio_filled.svg b/assets/player-icons/ic_player_audio_filled.svg new file mode 100644 index 00000000..2961dd6a --- /dev/null +++ b/assets/player-icons/ic_player_audio_filled.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/player-icons/ic_player_audio_outline.svg b/assets/player-icons/ic_player_audio_outline.svg new file mode 100644 index 00000000..87c64646 --- /dev/null +++ b/assets/player-icons/ic_player_audio_outline.svg @@ -0,0 +1,6 @@ + + + + + + diff --git a/assets/player-icons/ic_player_episodes.svg b/assets/player-icons/ic_player_episodes.svg new file mode 100644 index 00000000..c09c7205 --- /dev/null +++ b/assets/player-icons/ic_player_episodes.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/player-icons/ic_player_pause.svg b/assets/player-icons/ic_player_pause.svg new file mode 100644 index 00000000..69f83449 --- /dev/null +++ b/assets/player-icons/ic_player_pause.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/assets/player-icons/ic_player_play.svg b/assets/player-icons/ic_player_play.svg new file mode 100644 index 00000000..d375a176 --- /dev/null +++ b/assets/player-icons/ic_player_play.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/player-icons/ic_player_source.svg b/assets/player-icons/ic_player_source.svg new file mode 100644 index 00000000..1e79c2a3 --- /dev/null +++ b/assets/player-icons/ic_player_source.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/player-icons/ic_player_subtitles.svg b/assets/player-icons/ic_player_subtitles.svg new file mode 100644 index 00000000..bf8041e3 --- /dev/null +++ b/assets/player-icons/ic_player_subtitles.svg @@ -0,0 +1,4 @@ + + + + diff --git a/assets/text_only_og.png b/assets/text_only_og.png new file mode 100644 index 00000000..35eca9a4 Binary files /dev/null and b/assets/text_only_og.png differ diff --git a/docs/SUPABASE_SYNC.md b/docs/SUPABASE_SYNC.md new file mode 100644 index 00000000..494c2ddc --- /dev/null +++ b/docs/SUPABASE_SYNC.md @@ -0,0 +1,1254 @@ +# NuvioTV Supabase Sync Documentation + +This document describes the complete Supabase backend used by NuvioTV for cross-device data synchronization. It covers database schema, RPC functions, authentication, device linking, and integration patterns. + +--- + +## Table of Contents + +1. [Overview](#overview) +2. [Prerequisites](#prerequisites) +3. [Database Schema](#database-schema) +4. [RPC Functions](#rpc-functions) +5. [Integration Guide](#integration-guide) +6. [Data Models](#data-models) +7. [Sync Behavior & Restrictions](#sync-behavior--restrictions) +8. [Error Handling](#error-handling) + +--- + +## Overview + +NuvioTV syncs the following data to Supabase so linked devices share the same state: + +| Data | Description | Trakt Override | +|------|-------------|----------------| +| **Plugins** | JavaScript plugin repository URLs | No (always syncs) | +| **Addons** | Stremio-compatible addon manifest URLs | No (always syncs) | +| **Watch Progress** | Per-movie/episode playback position | Yes (skipped when Trakt connected) | +| **Library** | Saved movies & TV shows | Yes (skipped when Trakt connected) | +| **Watched Items** | Permanent watched history (movies & episodes) | Yes (skipped when Trakt connected) | + +### Authentication Model + +- **Anonymous**: Auto-created account, can generate/claim sync codes +- **Email/Password**: Full account with permanent data storage +- **Linked Device**: A device linked to another account via sync code; reads/writes the owner's data + +### Security Model + +All data operations use **SECURITY DEFINER** RPC functions that call `get_sync_owner()` to resolve the effective user ID. This allows linked devices to transparently access the owner's data without needing direct RLS access. + +--- + +## Prerequisites + +- Supabase project with: + - **Auth** enabled (anonymous sign-in + email/password) + - **pgcrypto** extension enabled (for `crypt()`, `gen_salt()`) +- Environment variables: + - `SUPABASE_URL` — Your Supabase project URL + - `SUPABASE_ANON_KEY` — Your Supabase anonymous/public key + +--- + +## Database Schema + +### Tables + +#### `sync_codes` + +Temporary codes for device linking, protected by a bcrypt-hashed PIN. + +```sql +CREATE TABLE sync_codes ( + id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY, + owner_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, + code TEXT NOT NULL, + pin_hash TEXT NOT NULL, + is_active BOOLEAN NOT NULL DEFAULT true, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now(), + expires_at TIMESTAMPTZ DEFAULT 'infinity'::TIMESTAMPTZ +); + +ALTER TABLE sync_codes ENABLE ROW LEVEL SECURITY; + +CREATE POLICY "Users can manage own sync codes" + ON sync_codes FOR ALL + USING (auth.uid() = owner_id) + WITH CHECK (auth.uid() = owner_id); +``` + +#### `linked_devices` + +Maps a child device's user ID to a parent (owner) user ID. + +```sql +CREATE TABLE linked_devices ( + id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY, + owner_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, + device_user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, + device_name TEXT, + linked_at TIMESTAMPTZ NOT NULL DEFAULT now(), + UNIQUE(owner_id, device_user_id) +); + +ALTER TABLE linked_devices ENABLE ROW LEVEL SECURITY; + +CREATE POLICY "Owners can read their linked devices" + ON linked_devices FOR SELECT + USING (auth.uid() = owner_id); + +CREATE POLICY "Devices can read their own link" + ON linked_devices FOR SELECT + USING (auth.uid() = device_user_id); +``` + +#### `plugins` + +Plugin repository URLs synced across devices. + +```sql +CREATE TABLE plugins ( + id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY, + user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, + url TEXT NOT NULL, + name TEXT, + enabled BOOLEAN NOT NULL DEFAULT true, + sort_order INTEGER NOT NULL DEFAULT 0, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +CREATE INDEX idx_plugins_user_id ON plugins(user_id); +ALTER TABLE plugins ENABLE ROW LEVEL SECURITY; + +CREATE POLICY "Users can manage own plugins" + ON plugins FOR ALL + USING (auth.uid() = user_id) + WITH CHECK (auth.uid() = user_id); +``` + +#### `addons` + +Addon manifest URLs synced across devices. + +```sql +CREATE TABLE addons ( + id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY, + user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, + url TEXT NOT NULL, + name TEXT, + enabled BOOLEAN NOT NULL DEFAULT true, + sort_order INTEGER NOT NULL DEFAULT 0, + created_at TIMESTAMPTZ NOT NULL DEFAULT now(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT now() +); + +CREATE INDEX idx_addons_user_id ON addons(user_id); +ALTER TABLE addons ENABLE ROW LEVEL SECURITY; + +CREATE POLICY "Users can manage own addons" + ON addons FOR ALL + USING (auth.uid() = user_id) + WITH CHECK (auth.uid() = user_id); +``` + +#### `watch_progress` + +Per-movie or per-episode playback progress. + +```sql +CREATE TABLE watch_progress ( + id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY, + user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, + content_id TEXT NOT NULL, + content_type TEXT NOT NULL, + video_id TEXT NOT NULL, + season INTEGER, + episode INTEGER, + position BIGINT NOT NULL DEFAULT 0, + duration BIGINT NOT NULL DEFAULT 0, + last_watched BIGINT NOT NULL DEFAULT 0, + progress_key TEXT NOT NULL +); + +CREATE INDEX idx_watch_progress_user_id ON watch_progress(user_id); +ALTER TABLE watch_progress ENABLE ROW LEVEL SECURITY; + +CREATE POLICY "Users can manage own watch progress" + ON watch_progress FOR ALL + USING (auth.uid() = user_id) + WITH CHECK (auth.uid() = user_id); +``` + +#### `library_items` + +Saved movies and TV shows (bookmarks/favorites). + +```sql +CREATE TABLE library_items ( + id UUID NOT NULL DEFAULT gen_random_uuid() PRIMARY KEY, + user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, + content_id TEXT NOT NULL, + content_type TEXT NOT NULL, + name TEXT NOT NULL DEFAULT '', + poster TEXT, + poster_shape TEXT NOT NULL DEFAULT 'POSTER', + background TEXT, + description TEXT, + release_info TEXT, + imdb_rating REAL, + genres TEXT[] DEFAULT '{}', + addon_base_url TEXT, + added_at BIGINT NOT NULL DEFAULT 0, + created_at TIMESTAMPTZ DEFAULT now(), + updated_at TIMESTAMPTZ DEFAULT now(), + UNIQUE(user_id, content_id, content_type) +); + +CREATE INDEX idx_library_items_user_id ON library_items(user_id); +ALTER TABLE library_items ENABLE ROW LEVEL SECURITY; + +CREATE POLICY "Users can manage own library items" + ON library_items FOR ALL + USING (auth.uid() = user_id) + WITH CHECK (auth.uid() = user_id); +``` + +#### `watched_items` + +Permanent watched history. Unlike `watch_progress` (which is capped and stores playback position), this table is a permanent record of everything the user has watched or marked as watched. Used to determine if a movie or episode should show a "watched" checkmark. + +```sql +CREATE TABLE watched_items ( + id UUID DEFAULT gen_random_uuid() PRIMARY KEY, + user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE, + content_id TEXT NOT NULL, + content_type TEXT NOT NULL, + title TEXT NOT NULL DEFAULT '', + season INTEGER, + episode INTEGER, + watched_at BIGINT NOT NULL, + created_at TIMESTAMPTZ DEFAULT now() +); + +CREATE UNIQUE INDEX idx_watched_items_unique + ON watched_items (user_id, content_id, COALESCE(season, -1), COALESCE(episode, -1)); + +CREATE INDEX idx_watched_items_user_id ON watched_items(user_id); + +ALTER TABLE watched_items ENABLE ROW LEVEL SECURITY; + +CREATE POLICY "Users can manage own watched items" + ON watched_items FOR ALL + USING (auth.uid() = user_id) + WITH CHECK (auth.uid() = user_id); +``` + +> **Note:** The unique index uses `COALESCE(season, -1)` and `COALESCE(episode, -1)` because PostgreSQL treats NULLs as distinct in unique constraints. Movies have `NULL` season/episode, so without COALESCE, multiple entries for the same movie would be allowed. + +### Triggers + +```sql +-- Auto-update updated_at timestamp +CREATE OR REPLACE FUNCTION set_updated_at() +RETURNS TRIGGER +LANGUAGE plpgsql +AS $$ +BEGIN + NEW.updated_at = now(); + RETURN NEW; +END; +$$; + +-- Apply to tables with updated_at +CREATE TRIGGER set_updated_at BEFORE UPDATE ON plugins FOR EACH ROW EXECUTE FUNCTION set_updated_at(); +CREATE TRIGGER set_updated_at BEFORE UPDATE ON addons FOR EACH ROW EXECUTE FUNCTION set_updated_at(); +CREATE TRIGGER set_updated_at BEFORE UPDATE ON sync_codes FOR EACH ROW EXECUTE FUNCTION set_updated_at(); +``` + +--- + +## RPC Functions + +### Core: `get_sync_owner()` + +Resolves the effective user ID. If the current user is a linked device, returns the owner's ID. Otherwise returns the caller's own ID. This is the foundation of the linked-device sync model. + +```sql +CREATE OR REPLACE FUNCTION get_sync_owner() +RETURNS UUID +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +DECLARE + v_owner_id uuid; +BEGIN + SELECT owner_id INTO v_owner_id + FROM linked_devices + WHERE device_user_id = auth.uid() + LIMIT 1; + + RETURN COALESCE(v_owner_id, auth.uid()); +END; +$$; + +GRANT EXECUTE ON FUNCTION get_sync_owner() TO authenticated; +``` + +### Core: `can_access_user_data(p_user_id UUID)` + +Helper to check if the current user can access another user's data (either they are that user, or they are a linked device). + +```sql +CREATE OR REPLACE FUNCTION can_access_user_data(p_user_id UUID) +RETURNS BOOLEAN +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +BEGIN + IF auth.uid() = p_user_id THEN + RETURN true; + END IF; + + IF EXISTS ( + SELECT 1 FROM public.linked_devices + WHERE owner_id = p_user_id + AND device_user_id = auth.uid() + ) THEN + RETURN true; + END IF; + + RETURN false; +END; +$$; + +GRANT EXECUTE ON FUNCTION can_access_user_data(UUID) TO authenticated; +``` + +### Device Linking: `generate_sync_code(p_pin TEXT)` + +Generates a sync code for the current user. If a code already exists, updates the PIN. The code format is `XXXX-XXXX-XXXX-XXXX-XXXX` (uppercase hex). PIN is bcrypt-hashed. + +```sql +CREATE OR REPLACE FUNCTION generate_sync_code(p_pin TEXT) +RETURNS TABLE(code TEXT) +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +DECLARE + v_user_id uuid; + v_existing_code text; + v_new_code text; + v_pin_hash text; +BEGIN + v_user_id := auth.uid(); + + IF v_user_id IS NULL THEN + RAISE EXCEPTION 'Not authenticated'; + END IF; + + SELECT sc.code INTO v_existing_code + FROM sync_codes sc + WHERE sc.owner_id = v_user_id + ORDER BY sc.created_at DESC + LIMIT 1; + + IF v_existing_code IS NOT NULL THEN + v_pin_hash := crypt(p_pin, gen_salt('bf')); + UPDATE sync_codes + SET pin_hash = v_pin_hash + WHERE sync_codes.owner_id = v_user_id + AND sync_codes.code = v_existing_code; + RETURN QUERY SELECT v_existing_code; + RETURN; + END IF; + + v_new_code := upper( + substr(md5(random()::text || clock_timestamp()::text), 1, 4) || '-' || + substr(md5(random()::text || clock_timestamp()::text), 5, 4) || '-' || + substr(md5(random()::text || clock_timestamp()::text), 9, 4) || '-' || + substr(md5(random()::text || clock_timestamp()::text), 13, 4) || '-' || + substr(md5(random()::text || clock_timestamp()::text), 17, 4) + ); + + v_pin_hash := crypt(p_pin, gen_salt('bf')); + + INSERT INTO sync_codes (owner_id, code, pin_hash) + VALUES (v_user_id, v_new_code, v_pin_hash); + + RETURN QUERY SELECT v_new_code; +END; +$$; + +GRANT EXECUTE ON FUNCTION generate_sync_code(TEXT) TO authenticated; +``` + +### Device Linking: `get_sync_code(p_pin TEXT)` + +Retrieves the existing sync code for the current user, validated by PIN. + +```sql +CREATE OR REPLACE FUNCTION get_sync_code(p_pin TEXT) +RETURNS TABLE(code TEXT) +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +DECLARE + v_user_id uuid; + v_existing_code text; + v_existing_pin_hash text; +BEGIN + v_user_id := auth.uid(); + + IF v_user_id IS NULL THEN + RAISE EXCEPTION 'Not authenticated'; + END IF; + + SELECT sc.code, sc.pin_hash + INTO v_existing_code, v_existing_pin_hash + FROM sync_codes sc + WHERE sc.owner_id = v_user_id + ORDER BY sc.created_at DESC + LIMIT 1; + + IF v_existing_code IS NULL THEN + RAISE EXCEPTION 'No sync code found. Generate one first.'; + END IF; + + IF v_existing_pin_hash != crypt(p_pin, v_existing_pin_hash) THEN + RAISE EXCEPTION 'Incorrect PIN'; + END IF; + + RETURN QUERY SELECT v_existing_code; +END; +$$; + +GRANT EXECUTE ON FUNCTION get_sync_code(TEXT) TO authenticated; +``` + +### Device Linking: `claim_sync_code(p_code TEXT, p_pin TEXT, p_device_name TEXT)` + +Links the current device to the owner of the sync code. Validates the PIN, then creates a `linked_devices` row. + +```sql +CREATE OR REPLACE FUNCTION claim_sync_code(p_code TEXT, p_pin TEXT, p_device_name TEXT DEFAULT NULL) +RETURNS TABLE(result_owner_id UUID, success BOOLEAN, message TEXT) +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +DECLARE + v_owner_id uuid; + v_pin_hash text; +BEGIN + SELECT sc.owner_id, sc.pin_hash + INTO v_owner_id, v_pin_hash + FROM sync_codes sc + WHERE sc.code = p_code; + + IF v_owner_id IS NULL THEN + RETURN QUERY SELECT NULL::uuid, false, 'Sync code not found'::text; + RETURN; + END IF; + + IF crypt(p_pin, v_pin_hash) != v_pin_hash THEN + RETURN QUERY SELECT NULL::uuid, false, 'Incorrect PIN'::text; + RETURN; + END IF; + + INSERT INTO linked_devices (owner_id, device_user_id, device_name) + VALUES (v_owner_id, auth.uid(), p_device_name) + ON CONFLICT (owner_id, device_user_id) DO UPDATE + SET device_name = EXCLUDED.device_name; + + RETURN QUERY SELECT v_owner_id, true, 'Device linked successfully'::text; +END; +$$; + +GRANT EXECUTE ON FUNCTION claim_sync_code(TEXT, TEXT, TEXT) TO authenticated; +``` + +### Device Linking: `unlink_device(p_device_user_id UUID)` + +Removes a linked device. Only the owner can unlink their devices. + +```sql +CREATE OR REPLACE FUNCTION unlink_device(p_device_user_id UUID) +RETURNS VOID +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +BEGIN + DELETE FROM linked_devices + WHERE (owner_id = auth.uid() AND device_user_id = p_device_user_id) + OR (device_user_id = auth.uid() AND device_user_id = p_device_user_id); +END; +$$; + +GRANT EXECUTE ON FUNCTION unlink_device(UUID) TO authenticated; +``` + +### Sync: `sync_push_plugins(p_plugins JSONB)` + +Full-replace push of plugin repository URLs. + +```sql +CREATE OR REPLACE FUNCTION sync_push_plugins(p_plugins JSONB) +RETURNS VOID +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +DECLARE + v_effective_user_id uuid; + v_plugin jsonb; +BEGIN + SELECT get_sync_owner() INTO v_effective_user_id; + + DELETE FROM plugins WHERE user_id = v_effective_user_id; + + FOR v_plugin IN SELECT * FROM jsonb_array_elements(p_plugins) + LOOP + INSERT INTO plugins (user_id, url, name, enabled, sort_order) + VALUES ( + v_effective_user_id, + v_plugin->>'url', + v_plugin->>'name', + COALESCE((v_plugin->>'enabled')::boolean, true), + (v_plugin->>'sort_order')::int + ); + END LOOP; +END; +$$; + +GRANT EXECUTE ON FUNCTION sync_push_plugins(JSONB) TO authenticated; +``` + +### Sync: `sync_push_addons(p_addons JSONB)` + +Full-replace push of addon manifest URLs. + +```sql +CREATE OR REPLACE FUNCTION sync_push_addons(p_addons JSONB) +RETURNS VOID +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +DECLARE + v_effective_user_id uuid; + v_addon jsonb; +BEGIN + SELECT get_sync_owner() INTO v_effective_user_id; + + DELETE FROM addons WHERE user_id = v_effective_user_id; + + FOR v_addon IN SELECT * FROM jsonb_array_elements(p_addons) + LOOP + INSERT INTO addons (user_id, url, sort_order) + VALUES ( + v_effective_user_id, + v_addon->>'url', + (v_addon->>'sort_order')::int + ); + END LOOP; +END; +$$; + +GRANT EXECUTE ON FUNCTION sync_push_addons(JSONB) TO authenticated; +``` + +### Sync: `sync_push_watch_progress(p_entries JSONB)` + +Full-replace push of watch progress entries. + +```sql +CREATE OR REPLACE FUNCTION sync_push_watch_progress(p_entries JSONB) +RETURNS VOID +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +DECLARE + v_effective_user_id UUID; +BEGIN + v_effective_user_id := get_sync_owner(); + + DELETE FROM watch_progress WHERE user_id = v_effective_user_id; + + INSERT INTO watch_progress ( + user_id, content_id, content_type, video_id, + season, episode, position, duration, last_watched, progress_key + ) + SELECT + v_effective_user_id, + (entry->>'content_id'), + (entry->>'content_type'), + (entry->>'video_id'), + (entry->>'season')::INTEGER, + (entry->>'episode')::INTEGER, + (entry->>'position')::BIGINT, + (entry->>'duration')::BIGINT, + (entry->>'last_watched')::BIGINT, + (entry->>'progress_key') + FROM jsonb_array_elements(p_entries) AS entry; +END; +$$; + +GRANT EXECUTE ON FUNCTION sync_push_watch_progress(JSONB) TO authenticated; +``` + +### Sync: `sync_pull_watch_progress()` + +Returns all watch progress for the effective user (owner or linked device's owner). + +```sql +CREATE OR REPLACE FUNCTION sync_pull_watch_progress() +RETURNS SETOF watch_progress +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +DECLARE + v_effective_user_id UUID; +BEGIN + v_effective_user_id := get_sync_owner(); + RETURN QUERY SELECT * FROM watch_progress WHERE user_id = v_effective_user_id; +END; +$$; + +GRANT EXECUTE ON FUNCTION sync_pull_watch_progress() TO authenticated; +``` + +### Sync: `sync_push_library(p_items JSONB)` + +Full-replace push of library items. + +```sql +CREATE OR REPLACE FUNCTION sync_push_library(p_items JSONB) +RETURNS VOID +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +DECLARE + v_effective_user_id UUID; +BEGIN + v_effective_user_id := get_sync_owner(); + + DELETE FROM library_items WHERE user_id = v_effective_user_id; + + INSERT INTO library_items ( + user_id, content_id, content_type, name, poster, poster_shape, + background, description, release_info, imdb_rating, genres, + addon_base_url, added_at + ) + SELECT + v_effective_user_id, + (item->>'content_id'), + (item->>'content_type'), + COALESCE(item->>'name', ''), + (item->>'poster'), + COALESCE(item->>'poster_shape', 'POSTER'), + (item->>'background'), + (item->>'description'), + (item->>'release_info'), + (item->>'imdb_rating')::REAL, + COALESCE( + (SELECT array_agg(g::TEXT) FROM jsonb_array_elements_text(item->'genres') AS g), + '{}' + ), + (item->>'addon_base_url'), + COALESCE((item->>'added_at')::BIGINT, EXTRACT(EPOCH FROM now())::BIGINT * 1000) + FROM jsonb_array_elements(p_items) AS item; +END; +$$; + +GRANT EXECUTE ON FUNCTION sync_push_library(JSONB) TO authenticated; +``` + +### Sync: `sync_pull_library()` + +Returns all library items for the effective user. + +```sql +CREATE OR REPLACE FUNCTION sync_pull_library() +RETURNS SETOF library_items +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +DECLARE + v_effective_user_id UUID; +BEGIN + v_effective_user_id := get_sync_owner(); + RETURN QUERY SELECT * FROM library_items WHERE user_id = v_effective_user_id; +END; +$$; + +GRANT EXECUTE ON FUNCTION sync_pull_library() TO authenticated; +``` + +### Sync: `sync_push_watched_items(p_items JSONB)` + +Full-replace push of watched items (permanent watched history). + +```sql +CREATE OR REPLACE FUNCTION sync_push_watched_items(p_items JSONB) +RETURNS VOID +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +DECLARE + v_effective_user_id UUID; +BEGIN + v_effective_user_id := get_sync_owner(); + DELETE FROM watched_items WHERE user_id = v_effective_user_id; + INSERT INTO watched_items (user_id, content_id, content_type, title, season, episode, watched_at) + SELECT + v_effective_user_id, + (item->>'content_id'), + (item->>'content_type'), + COALESCE(item->>'title', ''), + (item->>'season')::INTEGER, + (item->>'episode')::INTEGER, + (item->>'watched_at')::BIGINT + FROM jsonb_array_elements(p_items) AS item; +END; +$$; + +GRANT EXECUTE ON FUNCTION sync_push_watched_items(JSONB) TO authenticated; +``` + +### Sync: `sync_pull_watched_items()` + +Returns all watched items for the effective user. + +```sql +CREATE OR REPLACE FUNCTION sync_pull_watched_items() +RETURNS SETOF watched_items +LANGUAGE plpgsql +SECURITY DEFINER +AS $$ +DECLARE + v_effective_user_id UUID; +BEGIN + v_effective_user_id := get_sync_owner(); + RETURN QUERY SELECT * FROM watched_items WHERE user_id = v_effective_user_id; +END; +$$; + +GRANT EXECUTE ON FUNCTION sync_pull_watched_items() TO authenticated; +``` + +--- + +## Integration Guide + +### 1. Authentication + +All API calls require a Supabase auth session. Initialize the Supabase client and authenticate: + +``` +POST {SUPABASE_URL}/auth/v1/signup +Headers: apikey: {SUPABASE_ANON_KEY} +Body: { "email": "user@example.com", "password": "..." } +``` + +Or for anonymous sign-in: + +``` +POST {SUPABASE_URL}/auth/v1/signup +Headers: apikey: {SUPABASE_ANON_KEY} +Body: {} +``` + +All subsequent requests include: +``` +Headers: + apikey: {SUPABASE_ANON_KEY} + Authorization: Bearer {ACCESS_TOKEN} +``` + +### 2. Calling RPC Functions + +All RPCs are called via the Supabase PostgREST endpoint: + +``` +POST {SUPABASE_URL}/rest/v1/rpc/{function_name} +Headers: + apikey: {SUPABASE_ANON_KEY} + Authorization: Bearer {ACCESS_TOKEN} + Content-Type: application/json +Body: { ...parameters... } +``` + +### 3. Device Linking Flow + +**Device A (Parent) — Generate Sync Code:** + +```json +// POST /rest/v1/rpc/generate_sync_code +{ "p_pin": "1234" } + +// Response: +[{ "code": "A1B2-C3D4-E5F6-G7H8-I9J0" }] +``` + +**Device B (Child) — Claim Sync Code:** + +```json +// POST /rest/v1/rpc/claim_sync_code +{ + "p_code": "A1B2-C3D4-E5F6-G7H8-I9J0", + "p_pin": "1234", + "p_device_name": "Living Room TV" +} + +// Response: +[{ + "result_owner_id": "uuid-of-device-a-user", + "success": true, + "message": "Device linked successfully" +}] +``` + +After claiming, Device B's `get_sync_owner()` will return Device A's user ID, so all push/pull operations operate on the shared data. + +**Retrieve Existing Code (with PIN):** + +```json +// POST /rest/v1/rpc/get_sync_code +{ "p_pin": "1234" } + +// Response: +[{ "code": "A1B2-C3D4-E5F6-G7H8-I9J0" }] +``` + +**Get Linked Devices:** + +``` +GET {SUPABASE_URL}/rest/v1/linked_devices?select=*&owner_id=eq.{your_user_id} +``` + +**Unlink a Device:** + +```json +// POST /rest/v1/rpc/unlink_device +{ "p_device_user_id": "uuid-of-device-to-unlink" } +``` + +### 4. Pushing Data + +All push RPCs use a **full-replace** strategy: existing data for the effective user is deleted, then the new data is inserted. This means you must always push the **complete** local dataset, not just changes. + +#### Push Plugins + +```json +// POST /rest/v1/rpc/sync_push_plugins +{ + "p_plugins": [ + { + "url": "https://example.com/plugin-repo", + "name": "My Plugin Repo", + "enabled": true, + "sort_order": 0 + } + ] +} +``` + +#### Push Addons + +```json +// POST /rest/v1/rpc/sync_push_addons +{ + "p_addons": [ + { + "url": "https://example.com/addon/manifest.json", + "sort_order": 0 + } + ] +} +``` + +#### Push Watch Progress + +```json +// POST /rest/v1/rpc/sync_push_watch_progress +{ + "p_entries": [ + { + "content_id": "tt1234567", + "content_type": "movie", + "video_id": "tt1234567", + "season": null, + "episode": null, + "position": 3600000, + "duration": 7200000, + "last_watched": 1700000000000, + "progress_key": "tt1234567" + }, + { + "content_id": "tt7654321", + "content_type": "series", + "video_id": "tt7654321:2:5", + "season": 2, + "episode": 5, + "position": 1800000, + "duration": 3600000, + "last_watched": 1700000000000, + "progress_key": "tt7654321_s2e5" + } + ] +} +``` + +| Field | Type | Description | +|-------|------|-------------| +| `content_id` | string | IMDB ID or content identifier | +| `content_type` | string | `"movie"` or `"series"` | +| `video_id` | string | Video stream identifier | +| `season` | int/null | Season number (null for movies) | +| `episode` | int/null | Episode number (null for movies) | +| `position` | long | Playback position in milliseconds | +| `duration` | long | Total duration in milliseconds | +| `last_watched` | long | Unix timestamp in milliseconds | +| `progress_key` | string | Unique key: `contentId` for movies, `contentId_s{S}e{E}` for episodes | + +#### Push Library Items + +```json +// POST /rest/v1/rpc/sync_push_library +{ + "p_items": [ + { + "content_id": "tt1234567", + "content_type": "movie", + "name": "Example Movie", + "poster": "https://image.tmdb.org/t/p/w500/poster.jpg", + "poster_shape": "POSTER", + "background": "https://image.tmdb.org/t/p/original/backdrop.jpg", + "description": "A great movie about...", + "release_info": "2024", + "imdb_rating": 8.5, + "genres": ["Action", "Thriller"], + "addon_base_url": "https://example.com/addon" + } + ] +} +``` + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `content_id` | string | Yes | IMDB ID or content identifier | +| `content_type` | string | Yes | `"movie"` or `"series"` | +| `name` | string | No | Display name (defaults to `""`) | +| `poster` | string | No | Poster image URL | +| `poster_shape` | string | No | `"POSTER"`, `"LANDSCAPE"`, or `"SQUARE"` (defaults to `"POSTER"`) | +| `background` | string | No | Background/backdrop image URL | +| `description` | string | No | Content description | +| `release_info` | string | No | Release year or date string | +| `imdb_rating` | float | No | IMDB rating (0.0-10.0) | +| `genres` | string[] | No | Genre list (defaults to `[]`) | +| `addon_base_url` | string | No | Source addon base URL | +| `added_at` | long | No | Timestamp in ms (defaults to current time) | + +#### Push Watched Items + +```json +// POST /rest/v1/rpc/sync_push_watched_items +{ + "p_items": [ + { + "content_id": "tt1234567", + "content_type": "movie", + "title": "Example Movie", + "season": null, + "episode": null, + "watched_at": 1700000000000 + }, + { + "content_id": "tt7654321", + "content_type": "series", + "title": "Example Series", + "season": 2, + "episode": 5, + "watched_at": 1700000000000 + } + ] +} +``` + +| Field | Type | Required | Description | +|-------|------|----------|-------------| +| `content_id` | string | Yes | IMDB ID or content identifier | +| `content_type` | string | Yes | `"movie"` or `"series"` | +| `title` | string | No | Display name (defaults to `""`) | +| `season` | int/null | No | Season number (null for movies) | +| `episode` | int/null | No | Episode number (null for movies) | +| `watched_at` | long | Yes | Unix timestamp in milliseconds | + +### 5. Pulling Data + +#### Pull Watch Progress + +```json +// POST /rest/v1/rpc/sync_pull_watch_progress +{} + +// Response: array of watch_progress rows +[ + { + "id": "uuid", + "user_id": "uuid", + "content_id": "tt1234567", + "content_type": "movie", + "video_id": "tt1234567", + "season": null, + "episode": null, + "position": 3600000, + "duration": 7200000, + "last_watched": 1700000000000, + "progress_key": "tt1234567" + } +] +``` + +#### Pull Library Items + +```json +// POST /rest/v1/rpc/sync_pull_library +{} + +// Response: array of library_items rows +[ + { + "id": "uuid", + "user_id": "uuid", + "content_id": "tt1234567", + "content_type": "movie", + "name": "Example Movie", + "poster": "https://...", + "poster_shape": "POSTER", + "background": "https://...", + "description": "...", + "release_info": "2024", + "imdb_rating": 8.5, + "genres": ["Action", "Thriller"], + "addon_base_url": "https://...", + "added_at": 1700000000000, + "created_at": "2024-01-01T00:00:00Z", + "updated_at": "2024-01-01T00:00:00Z" + } +] +``` + +#### Pull Watched Items + +```json +// POST /rest/v1/rpc/sync_pull_watched_items +{} + +// Response: array of watched_items rows +[ + { + "id": "uuid", + "user_id": "uuid", + "content_id": "tt1234567", + "content_type": "movie", + "title": "Example Movie", + "season": null, + "episode": null, + "watched_at": 1700000000000, + "created_at": "2024-01-01T00:00:00Z" + } +] +``` + +#### Pull Plugins/Addons (Direct Table Query) + +Plugins and addons are pulled via direct table queries using the effective user ID: + +``` +// First, get the effective user ID +POST /rest/v1/rpc/get_sync_owner +{} +// Response: "uuid-of-effective-owner" + +// Then query tables +GET /rest/v1/addons?select=*&user_id=eq.{effective_user_id}&order=sort_order +GET /rest/v1/plugins?select=*&user_id=eq.{effective_user_id}&order=sort_order +``` + +--- + +## Data Models + +### Plugin + +```json +{ + "url": "string (required)", + "name": "string (optional)", + "enabled": "boolean (default: true)", + "sort_order": "integer (default: 0)" +} +``` + +### Addon + +```json +{ + "url": "string (required)", + "sort_order": "integer (default: 0)" +} +``` + +### Watch Progress Entry + +```json +{ + "content_id": "string (required)", + "content_type": "string (required) - 'movie' | 'series'", + "video_id": "string (required)", + "season": "integer (optional, null for movies)", + "episode": "integer (optional, null for movies)", + "position": "long (required) - playback position in ms", + "duration": "long (required) - total duration in ms", + "last_watched": "long (required) - unix timestamp in ms", + "progress_key": "string (required) - unique key per entry" +} +``` + +### Library Item + +```json +{ + "content_id": "string (required)", + "content_type": "string (required) - 'movie' | 'series'", + "name": "string (default: '')", + "poster": "string (optional) - poster image URL", + "poster_shape": "string (default: 'POSTER') - 'POSTER' | 'LANDSCAPE' | 'SQUARE'", + "background": "string (optional) - backdrop image URL", + "description": "string (optional)", + "release_info": "string (optional) - release year/date", + "imdb_rating": "float (optional) - 0.0 to 10.0", + "genres": "string[] (default: []) - list of genre names", + "addon_base_url": "string (optional) - source addon URL", + "added_at": "long (default: current time) - unix timestamp in ms" +} +``` + +### Watched Item + +```json +{ + "content_id": "string (required)", + "content_type": "string (required) - 'movie' | 'series'", + "title": "string (default: '') - display name", + "season": "integer (optional, null for movies)", + "episode": "integer (optional, null for movies)", + "watched_at": "long (required) - unix timestamp in ms" +} +``` + +### Linked Device + +```json +{ + "owner_id": "uuid (required) - parent account user ID", + "device_user_id": "uuid (required) - this device's user ID", + "device_name": "string (optional) - human-readable device name", + "linked_at": "timestamptz (auto-set)" +} +``` + +### Sync Code + +```json +{ + "owner_id": "uuid - user who generated the code", + "code": "string - format: XXXX-XXXX-XXXX-XXXX-XXXX", + "pin_hash": "string - bcrypt hash of the PIN", + "is_active": "boolean (default: true)", + "expires_at": "timestamptz (default: infinity)" +} +``` + +--- + +## Sync Behavior & Restrictions + +### Startup Sync Flow + +When the app starts and the user is authenticated (anonymous or full account): + +1. **Pull plugins** from remote → install any new ones locally +2. **Pull addons** from remote → install any new ones locally +3. If Trakt is **NOT** connected: + - **Pull watch progress** → merge into local (additive) + - **Push watch progress** → so linked devices can pull + - **Pull library items** → merge into local (additive) + - **Push library items** → so linked devices can pull + - **Pull watched items** → merge into local (additive) + - **Push watched items** → so linked devices can pull + +### On-Demand Sync + +- **Plugins/Addons**: Pushed to remote immediately when added or removed +- **Watch Progress**: Pushed with a 2-second debounce after any playback position update +- **Library Items**: Pushed with a 2-second debounce after add or remove +- **Watched Items**: Pushed with a 2-second debounce after mark/unmark as watched + +### Merge Strategy + +- **Push**: Full-replace. The entire local dataset replaces the remote dataset. +- **Pull (merge)**: Additive. Remote items not already present locally are added. Existing local items are preserved. Match keys vary by data type: `content_id` + `content_type` for library, `content_id` + `season` + `episode` for watched items. + +### Trakt Override + +When Trakt is connected: +- **Watch progress**, **library**, and **watched items** sync via Supabase is **completely skipped** +- Trakt becomes the source of truth for these data types +- **Plugins** and **addons** always sync regardless of Trakt status + +### Push on Account Events + +| Event | Action | +|-------|--------| +| Sign up (email) | Push all local data to remote | +| Sign in (email) | Pull all remote data to local | +| Generate sync code | Push all local data to remote, then generate code | +| Claim sync code | Pull all remote data from owner to local | + +--- + +## Error Handling + +### Sync Code Errors + +| Error Message | Cause | +|---------------|-------| +| `Not authenticated` | No auth session | +| `No sync code found. Generate one first.` | Calling `get_sync_code` before generating | +| `Incorrect PIN` | Wrong PIN for `get_sync_code` or `claim_sync_code` | +| `Sync code not found` | Invalid or non-existent code in `claim_sync_code` | +| `Device linked successfully` | Success response from `claim_sync_code` | + +### Auth Errors + +| Error Message | Cause | +|---------------|-------| +| `Invalid login credentials` | Wrong email or password | +| `Email not confirmed` | Email verification pending | +| `User already registered` | Duplicate email signup | +| `Password is too short/weak` | Password policy violation | +| `Signup is disabled` | Admin disabled signups | +| `Rate limit` / `Too many requests` | Too many auth attempts | + +### Network Errors + +| Error Message | Cause | +|---------------|-------| +| `Unable to resolve host` | No internet | +| `Timeout` / `Timed out` | Connection timeout | +| `Connection refused` | Server unreachable | +| `404` | RPC function not found (missing migration) | +| `400` / `Bad request` | Invalid parameters | diff --git a/eas.json b/eas.json index b208a76d..d68dbe69 100644 --- a/eas.json +++ b/eas.json @@ -5,13 +5,22 @@ }, "build": { "development": { + "env": { + "SENTRY_DISABLE_AUTO_UPLOAD": "true" + }, "developmentClient": true, "distribution": "internal" }, "preview": { + "env": { + "SENTRY_DISABLE_AUTO_UPLOAD": "true" + }, "distribution": "internal" }, "production": { + "env": { + "SENTRY_DISABLE_AUTO_UPLOAD": "true" + }, "autoIncrement": true, "extends": "apk", "android": { @@ -21,12 +30,18 @@ } }, "release": { + "env": { + "SENTRY_DISABLE_AUTO_UPLOAD": "true" + }, "distribution": "store", "android": { "buildType": "app-bundle" } }, "apk": { + "env": { + "SENTRY_DISABLE_AUTO_UPLOAD": "true" + }, "android": { "buildType": "apk", "gradleCommand": ":app:assembleRelease" diff --git a/index.html b/index.html index 749e2f0a..fe298212 100644 --- a/index.html +++ b/index.html @@ -779,9 +779,9 @@
01
-

Stremio Addon Support

-

Full compatibility with Stremio addons. Access your favorite content - providers seamlessly.

+

Stremio Addon Integration

+

Supports user-installed Stremio addons for metadata and source + integration.

@@ -984,9 +984,9 @@

Copyright & DMCA

-

We respect the intellectual property rights of others. Since Nuvio does not host any content, we - cannot remove content from the internet. However, if you believe that the application interface - itself infringes on your rights, please contact us.

+

We respect the intellectual property rights of others. Nuvio does not host media content. + If you believe this project's code, assets, or interface infringes your rights, please submit + a notice through the official project contact channels listed on this site and repository.

@@ -1157,4 +1157,4 @@ - \ No newline at end of file + diff --git a/ios/Nuvio.xcodeproj/project.pbxproj b/ios/Nuvio.xcodeproj/project.pbxproj index 08e51391..63bd1ba6 100644 --- a/ios/Nuvio.xcodeproj/project.pbxproj +++ b/ios/Nuvio.xcodeproj/project.pbxproj @@ -689,7 +689,7 @@ "-lc++", ); OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG"; - PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.app; + PRODUCT_BUNDLE_IDENTIFIER = com.nuvio.hub; PRODUCT_NAME = Nuvio; SUPPORTS_MACCATALYST = YES; SWIFT_OBJC_BRIDGING_HEADER = "Nuvio/Nuvio-Bridging-Header.h"; diff --git a/ios/Nuvio/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png b/ios/Nuvio/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png index 929e1472..9adedac5 100644 Binary files a/ios/Nuvio/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png and b/ios/Nuvio/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png differ diff --git a/ios/Nuvio/Images.xcassets/SplashScreenLegacy.imageset/image.png b/ios/Nuvio/Images.xcassets/SplashScreenLegacy.imageset/image.png index 8649d708..ef3b0dbb 100644 Binary files a/ios/Nuvio/Images.xcassets/SplashScreenLegacy.imageset/image.png and b/ios/Nuvio/Images.xcassets/SplashScreenLegacy.imageset/image.png differ diff --git a/ios/Nuvio/Images.xcassets/SplashScreenLegacy.imageset/image@2x.png b/ios/Nuvio/Images.xcassets/SplashScreenLegacy.imageset/image@2x.png index 8649d708..ef3b0dbb 100644 Binary files a/ios/Nuvio/Images.xcassets/SplashScreenLegacy.imageset/image@2x.png and b/ios/Nuvio/Images.xcassets/SplashScreenLegacy.imageset/image@2x.png differ diff --git a/ios/Nuvio/Images.xcassets/SplashScreenLegacy.imageset/image@3x.png b/ios/Nuvio/Images.xcassets/SplashScreenLegacy.imageset/image@3x.png index 8649d708..ef3b0dbb 100644 Binary files a/ios/Nuvio/Images.xcassets/SplashScreenLegacy.imageset/image@3x.png and b/ios/Nuvio/Images.xcassets/SplashScreenLegacy.imageset/image@3x.png differ diff --git a/ios/Nuvio/Info.plist b/ios/Nuvio/Info.plist index 6b345fac..ba093107 100644 --- a/ios/Nuvio/Info.plist +++ b/ios/Nuvio/Info.plist @@ -39,7 +39,7 @@ CFBundleVersion - 35 + 36 LSMinimumSystemVersion 12.0 LSRequiresIPhoneOS diff --git a/nuvio-source.json b/nuvio-source.json index c8919604..e2d48d42 100644 --- a/nuvio-source.json +++ b/nuvio-source.json @@ -13,8 +13,8 @@ "name": "Nuvio", "bundleIdentifier": "com.nuvio.app", "developerName": "Tapframe", - "subtitle": "Streaming app for movies and TV shows", - "localizedDescription": "Nuvio is a comprehensive streaming application that provides access to a vast library of movies and TV shows.", + "subtitle": "Media player and discovery app", + "localizedDescription": "Nuvio is a media player and metadata discovery application for user-provided and user-installed sources.", "iconURL": "https://github.com/tapframe/NuvioStreaming/blob/main/assets/android/playstore-icon.png?raw=true", "tintColor": "#04dcfc", "category": "entertainment", @@ -264,4 +264,4 @@ } ], "news": [] -} \ No newline at end of file +} diff --git a/package-lock.json b/package-lock.json index bb70659e..e7c7a877 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1540,7 +1540,6 @@ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.28.4.tgz", "integrity": "sha512-Q/N6JNWvIvPnLDvjlE1OUBLPQHH6l3CltCEsHIujp45zQUSSh8K+gHnaEX45yAT1nyngnINhvWtzN+Nb9D8RAQ==", "license": "MIT", - "peer": true, "engines": { "node": ">=6.9.0" } @@ -2098,7 +2097,6 @@ "resolved": "https://registry.npmjs.org/@expo/metro-runtime/-/metro-runtime-6.1.2.tgz", "integrity": "sha512-nvM+Qv45QH7pmYvP8JB1G8JpScrWND3KrMA6ZKe62cwwNiX/BjHU28Ear0v/4bQWXlOY0mv6B8CDIm8JxXde9g==", "license": "MIT", - "peer": true, "dependencies": { "anser": "^1.4.9", "pretty-format": "^29.7.0", @@ -2587,7 +2585,6 @@ "resolved": "https://registry.npmjs.org/@jimp/custom/-/custom-0.22.12.tgz", "integrity": "sha512-xcmww1O/JFP2MrlGUMd3Q78S3Qu6W3mYTXYuIqFq33EorgYHV/HqymHfXy9GjiCJ7OI+7lWx6nYFOzU7M4rd1Q==", "license": "MIT", - "peer": true, "dependencies": { "@jimp/core": "^0.22.12" } @@ -2773,7 +2770,6 @@ "resolved": "https://registry.npmjs.org/@lottiefiles/dotlottie-react/-/dotlottie-react-0.13.5.tgz", "integrity": "sha512-4U5okwjRqDPkjB572hfZtLXJ/LGfCo6vDwUB2KIPEUoSgqbIlw+UrbnaqVp3GS+dRvhMD27F2JObpHpYRlpF0Q==", "license": "MIT", - "peer": true, "dependencies": { "@lottiefiles/dotlottie-web": "0.44.0" }, @@ -3129,7 +3125,7 @@ "version": "0.72.8", "resolved": "https://registry.npmjs.org/@react-native/virtualized-lists/-/virtualized-lists-0.72.8.tgz", "integrity": "sha512-J3Q4Bkuo99k7mu+jPS9gSUSgq+lLRSI/+ahXNwV92XgJ/8UgOTxu2LPwhJnBk/sQKxq7E8WkZBnBiozukQMqrw==", - "devOptional": true, + "dev": true, "license": "MIT", "dependencies": { "invariant": "^2.2.4", @@ -3250,7 +3246,6 @@ "resolved": "https://registry.npmjs.org/@react-navigation/native/-/native-7.1.25.tgz", "integrity": "sha512-zQeWK9txDePWbYfqTs0C6jeRdJTm/7VhQtW/1IbJNDi9/rFIRzZule8bdQPAnf8QWUsNujRmi1J9OG/hhfbalg==", "license": "MIT", - "peer": true, "dependencies": { "@react-navigation/core": "^7.13.6", "escape-string-regexp": "^4.0.0", @@ -3892,7 +3887,6 @@ "integrity": "sha512-8QqtOQT5ACVlmsvKOJNEaWmRPmcojMOzCz4Hs2BGG/toAp/K38LcsMRyLp349glq5AzJbCEeimEoxaX6v/fLrA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@babel/core": "^7.21.3", "@svgr/babel-preset": "8.1.0", @@ -4113,7 +4107,6 @@ "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.27.tgz", "integrity": "sha512-cisd7gxkzjBKU2GgdYrTdtQx1SORymWyaAFhaxQPK9bYO9ot3Y5OikQRvY0VYQtvwjeQnizCINJAenh/V7MK2w==", "license": "MIT", - "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.2.2" @@ -4123,9 +4116,8 @@ "version": "0.72.8", "resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.72.8.tgz", "integrity": "sha512-St6xA7+EoHN5mEYfdWnfYt0e8u6k2FR0P9s2arYgakQGFgU1f9FlPrIEcj0X24pLCF5c5i3WVuLCUdiCYHmOoA==", - "devOptional": true, + "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@react-native/virtualized-lists": "^0.72.4", "@types/react": "*" @@ -4661,7 +4653,6 @@ "resolved": "https://registry.npmjs.org/axios/-/axios-1.13.2.tgz", "integrity": "sha512-VPk9ebNqPcy5lRGuSlKx752IlDatOjT9paPlm8A7yOuW2Fbvp4X3JznJtT4f0GzGLLiWE9W8onz51SqLYwzGaA==", "license": "MIT", - "peer": true, "dependencies": { "follow-redirects": "^1.15.6", "form-data": "^4.0.4", @@ -5065,7 +5056,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "baseline-browser-mapping": "^2.9.0", "caniuse-lite": "^1.0.30001759", @@ -6295,7 +6285,6 @@ "resolved": "https://registry.npmjs.org/expo/-/expo-54.0.29.tgz", "integrity": "sha512-9C90gyOzV83y2S3XzCbRDCuKYNaiyCzuP9ketv46acHCEZn+QTamPK/DobdghoSiofCmlfoaiD6/SzfxDiHMnw==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.20.0", "@expo/cli": "54.0.19", @@ -6499,7 +6488,6 @@ "resolved": "https://registry.npmjs.org/expo-device/-/expo-device-8.0.10.tgz", "integrity": "sha512-jd5BxjaF7382JkDMaC+P04aXXknB2UhWaVx5WiQKA05ugm/8GH5uaz9P9ckWdMKZGQVVEOC8MHaUADoT26KmFA==", "license": "MIT", - "peer": true, "dependencies": { "ua-parser-js": "^0.7.33" }, @@ -6527,7 +6515,6 @@ "resolved": "https://registry.npmjs.org/expo-file-system/-/expo-file-system-19.0.21.tgz", "integrity": "sha512-s3DlrDdiscBHtab/6W1osrjGL+C2bvoInPJD7sOwmxfJ5Woynv2oc+Fz1/xVXaE/V7HE/+xrHC/H45tu6lZzzg==", "license": "MIT", - "peer": true, "peerDependencies": { "expo": "*", "react-native": "*" @@ -6538,7 +6525,6 @@ "resolved": "https://registry.npmjs.org/expo-font/-/expo-font-14.0.10.tgz", "integrity": "sha512-UqyNaaLKRpj4pKAP4HZSLnuDQqueaO5tB1c/NWu5vh1/LF9ulItyyg2kF/IpeOp0DeOLk0GY0HrIXaKUMrwB+Q==", "license": "MIT", - "peer": true, "dependencies": { "fontfaceobserver": "^2.1.0" }, @@ -6634,7 +6620,6 @@ "resolved": "https://registry.npmjs.org/expo-localization/-/expo-localization-17.0.8.tgz", "integrity": "sha512-UrdwklZBDJ+t+ZszMMiE0SXZ2eJxcquCuQcl6EvGHM9K+e6YqKVRQ+w8qE+iIB3H75v2RJy6MHAaLK+Mqeo04g==", "license": "MIT", - "peer": true, "dependencies": { "rtl-detect": "^1.0.2" }, @@ -7694,7 +7679,6 @@ } ], "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.28.4" }, @@ -10601,7 +10585,6 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz", "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -10642,7 +10625,6 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz", "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==", "license": "MIT", - "peer": true, "dependencies": { "scheduler": "^0.26.0" }, @@ -10700,7 +10682,6 @@ "resolved": "https://registry.npmjs.org/react-native/-/react-native-0.81.4.tgz", "integrity": "sha512-bt5bz3A/+Cv46KcjV0VQa+fo7MKxs17RCcpzjftINlen4ZDUl0I6Ut+brQ2FToa5oD0IB0xvQHfmsg2EDqsZdQ==", "license": "MIT", - "peer": true, "dependencies": { "@jest/create-cache-key-function": "^29.7.0", "@react-native/assets-registry": "0.81.4", @@ -10789,7 +10770,6 @@ "resolved": "https://registry.npmjs.org/react-native-bottom-tabs/-/react-native-bottom-tabs-1.1.0.tgz", "integrity": "sha512-Uu1gvM3i1Hb4DjVvR/38J1QVQEs0RkPc7K6yon99HgvRWWOyLs7kjPDhUswtb8ije4pKW712skIXWJ0lgKzbyQ==", "license": "MIT", - "peer": true, "dependencies": { "react-freeze": "^1.0.0", "sf-symbols-typescript": "^2.0.0", @@ -10820,7 +10800,6 @@ "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.29.1.tgz", "integrity": "sha512-du3qmv0e3Sm7qsd9SfmHps+AggLiylcBBQ8ztz7WUtd8ZjKs5V3kekAbi9R2W9bRLSg47Ntp4GGMYZOhikQdZA==", "license": "MIT", - "peer": true, "dependencies": { "@egjs/hammerjs": "^2.0.17", "hoist-non-react-statics": "^3.3.0", @@ -10919,7 +10898,6 @@ "integrity": "sha512-hcvjTu9YJE9fMmnAUvhG8CxvYLpOuMQ/2eyi/S6GyrecezF6Rmk/uRQEL6v09BRFWA/xRVZNQVulQPS+2HS3mQ==", "hasInstallScript": true, "license": "MIT", - "peer": true, "peerDependencies": { "react": "*", "react-native": "*" @@ -10985,7 +10963,6 @@ "resolved": "https://registry.npmjs.org/react-native-reanimated/-/react-native-reanimated-4.2.0.tgz", "integrity": "sha512-frhu5b8/m/VvaMWz48V8RxcsXnE3hrlErQ5chr21MzAeDCpY4X14sQjvm+jvu3aOI+7Cz2atdRpyhhIuqxVaXg==", "license": "MIT", - "peer": true, "dependencies": { "react-native-is-edge-to-edge": "1.2.1", "semver": "7.7.3" @@ -11025,7 +11002,6 @@ "resolved": "https://registry.npmjs.org/react-native-safe-area-context/-/react-native-safe-area-context-5.6.2.tgz", "integrity": "sha512-4XGqMNj5qjUTYywJqpdWZ9IG8jgkS3h06sfVjfw5yZQZfWnRFXczi0GnYyFyCc2EBps/qFmoCH8fez//WumdVg==", "license": "MIT", - "peer": true, "peerDependencies": { "react": "*", "react-native": "*" @@ -11036,7 +11012,6 @@ "resolved": "https://registry.npmjs.org/react-native-screens/-/react-native-screens-4.18.0.tgz", "integrity": "sha512-mRTLWL7Uc1p/RFNveEIIrhP22oxHduC2ZnLr/2iHwBeYpGXR0rJZ7Bgc0ktxQSHRjWTPT70qc/7yd4r9960PBQ==", "license": "MIT", - "peer": true, "dependencies": { "react-freeze": "^1.0.0", "warn-once": "^0.1.0" @@ -11051,7 +11026,6 @@ "resolved": "https://registry.npmjs.org/react-native-svg/-/react-native-svg-15.15.1.tgz", "integrity": "sha512-ZUD1xwc3Hwo4cOmOLumjJVoc7lEf9oQFlHnLmgccLC19fNm6LVEdtB+Cnip6gEi0PG3wfvVzskViEtrySQP8Fw==", "license": "MIT", - "peer": true, "dependencies": { "css-select": "^5.1.0", "css-tree": "^1.1.3", @@ -11280,7 +11254,6 @@ "resolved": "https://registry.npmjs.org/react-native-web/-/react-native-web-0.21.2.tgz", "integrity": "sha512-SO2t9/17zM4iEnFvlu2DA9jqNbzNhoUP+AItkoCOyFmDMOhUnBBznBDCYN92fGdfAkfQlWzPoez6+zLxFNsZEg==", "license": "MIT", - "peer": true, "dependencies": { "@babel/runtime": "^7.18.6", "@react-native/normalize-colors": "^0.74.1", @@ -11537,7 +11510,6 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz", "integrity": "sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==", "license": "MIT", - "peer": true, "engines": { "node": ">=0.10.0" } @@ -13004,24 +12976,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/tldts": { - "version": "7.0.19", - "resolved": "https://registry.npmjs.org/tldts/-/tldts-7.0.19.tgz", - "integrity": "sha512-8PWx8tvC4jDB39BQw1m4x8y5MH1BcQ5xHeL2n7UVFulMPH/3Q0uiamahFJ3lXA0zO2SUyRXuVVbWSDmstlt9YA==", - "license": "MIT", - "dependencies": { - "tldts-core": "^7.0.19" - }, - "bin": { - "tldts": "bin/cli.js" - } - }, - "node_modules/tldts-core": { - "version": "7.0.19", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-7.0.19.tgz", - "integrity": "sha512-lJX2dEWx0SGH4O6p+7FPwYmJ/bu1JbcGJ8RLaG9b7liIgZ85itUVEPbMtWRVrde/0fnDPEPHW10ZsKW3kVsE9A==", - "license": "MIT" - }, "node_modules/tmp": { "version": "0.2.5", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.5.tgz", @@ -13076,19 +13030,6 @@ "url": "https://github.com/sponsors/Borewit" } }, - "node_modules/tough-cookie": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-6.0.0.tgz", - "integrity": "sha512-kXuRi1mtaKMrsLUxz3sQYvVl37B0Ns6MzfrtV5DvJceE9bPyspOqk9xxv7XbZWcfLWbFmm997vl83qUWVJA64w==", - "license": "BSD-3-Clause", - "peer": true, - "dependencies": { - "tldts": "^7.0.5" - }, - "engines": { - "node": ">=16" - } - }, "node_modules/tr46": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", @@ -13163,9 +13104,8 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "devOptional": true, + "dev": true, "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index e5f102df..8bff9af6 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "start": "expo start", "android": "expo run:android", "ios": "expo run:ios", - "build": "export NODE_ENV=production && cd android && ./gradlew assembleRelease", + "build": "export NODE_ENV=production && export SENTRY_DISABLE_AUTO_UPLOAD=true && cd android && ./gradlew assembleRelease", "postinstall": "patch-package" }, "dependencies": { diff --git a/src/assets/splash-icon-new.png b/src/assets/splash-icon-new.png index 07445d3e..d0bbb55f 100644 Binary files a/src/assets/splash-icon-new.png and b/src/assets/splash-icon-new.png differ diff --git a/src/components/home/AppleTVHero.tsx b/src/components/home/AppleTVHero.tsx index 1f257307..7de8e8b0 100644 --- a/src/components/home/AppleTVHero.tsx +++ b/src/components/home/AppleTVHero.tsx @@ -30,6 +30,7 @@ import Animated, { Extrapolation, useAnimatedScrollHandler, SharedValue, + useAnimatedReaction, } from 'react-native-reanimated'; import { Gesture, GestureDetector } from 'react-native-gesture-handler'; import { StreamingContent } from '../../services/catalogService'; @@ -163,10 +164,25 @@ const AppleTVHero: React.FC = ({ const [shouldResume, setShouldResume] = useState(false); const [type, setType] = useState<'movie' | 'series'>('movie'); - // Create internal scrollY if not provided externally + // Shared value for scroll position (for parallax effects) const internalScrollY = useSharedValue(0); const scrollY = externalScrollY || internalScrollY; + const [isOutOfView, setIsOutOfView] = useState(false); + + // Track if hero is in view + useAnimatedReaction( + () => scrollY.value, + (currentScrollY) => { + // If hero is more than 80% scrolled out of view, consider it out of view + const outOfView = currentScrollY > HERO_HEIGHT * 0.8; + if (outOfView !== isOutOfView) { + runOnJS(setIsOutOfView)(outOfView); + } + }, + [isOutOfView] + ); + // Determine items to display const items = useMemo(() => { if (allFeaturedContent && allFeaturedContent.length > 0) { @@ -354,9 +370,9 @@ const AppleTVHero: React.FC = ({ } }, [currentItem, loading, heroOpacity]); - // Stop trailer when screen loses focus + // Stop trailer when screen loses focus or scrolled out of view useEffect(() => { - if (!isFocused) { + if (!isFocused || isOutOfView) { // Pause this screen's trailer setTrailerShouldBePaused(true); setTrailerPlaying(false); @@ -365,20 +381,24 @@ const AppleTVHero: React.FC = ({ trailerOpacity.value = withTiming(0, { duration: 300 }); thumbnailOpacity.value = withTiming(1, { duration: 300 }); - logger.info('[AppleTVHero] Screen lost focus - pausing trailer'); + if (!isFocused) { + logger.info('[AppleTVHero] Screen lost focus - pausing trailer'); + } else { + logger.info('[AppleTVHero] Scrolled out of view - pausing trailer'); + } } else { - // Screen gained focus - allow trailer to resume if it was ready + // Screen gained focus and is in view - allow trailer to resume if it was ready setTrailerShouldBePaused(false); // If trailer was ready and loaded, restore the video opacity if (trailerReady && trailerUrl) { - logger.info('[AppleTVHero] Screen gained focus - restoring trailer'); + logger.info('[AppleTVHero] Screen in focus and in view - restoring trailer'); thumbnailOpacity.value = withTiming(0, { duration: 800 }); trailerOpacity.value = withTiming(1, { duration: 800 }); setTrailerPlaying(true); } } - }, [isFocused, setTrailerPlaying, trailerOpacity, thumbnailOpacity, trailerReady, trailerUrl]); + }, [isFocused, isOutOfView, setTrailerPlaying, trailerOpacity, thumbnailOpacity, trailerReady, trailerUrl]); // Listen to navigation events to stop trailer when navigating to other screens useEffect(() => { @@ -714,7 +734,7 @@ const AppleTVHero: React.FC = ({ updateSetting('trailerMuted', !trailerMuted); }, [trailerMuted, updateSetting]); - // Auto-advance timer - PAUSE when trailer is playing + // Auto-advance timer - PAUSE when trailer is playing or out of view const startAutoPlay = useCallback(() => { if (autoPlayTimerRef.current) { clearTimeout(autoPlayTimerRef.current); @@ -722,16 +742,20 @@ const AppleTVHero: React.FC = ({ if (items.length <= 1) return; - // Don't auto-advance if trailer is playing - if (globalTrailerPlaying && trailerReady) { - logger.info('[AppleTVHero] Auto-rotation paused - trailer is playing'); + // Don't auto-advance if trailer is playing or out of view + if ((globalTrailerPlaying && trailerReady) || isOutOfView) { + if (isOutOfView) { + logger.info('[AppleTVHero] Auto-rotation paused - out of view'); + } else { + logger.info('[AppleTVHero] Auto-rotation paused - trailer is playing'); + } return; } autoPlayTimerRef.current = setTimeout(() => { const timeSinceInteraction = Date.now() - lastInteractionRef.current; // Only auto-advance if user hasn't interacted recently (5 seconds) and no trailer playing - if (timeSinceInteraction >= 5000 && (!globalTrailerPlaying || !trailerReady)) { + if (timeSinceInteraction >= 5000 && (!globalTrailerPlaying || !trailerReady) && !isOutOfView) { // Set next index preview for crossfade const nextIdx = (currentIndex + 1) % items.length; setNextIndex(nextIdx); @@ -757,7 +781,7 @@ const AppleTVHero: React.FC = ({ startAutoPlay(); } }, 25000); // Auto-advance every 25 seconds - }, [items.length, globalTrailerPlaying, trailerReady, currentIndex, dragDirection, dragProgress]); + }, [items.length, globalTrailerPlaying, trailerReady, currentIndex, dragDirection, dragProgress, isOutOfView]); useEffect(() => { startAutoPlay(); diff --git a/src/components/home/ContinueWatchingSection.tsx b/src/components/home/ContinueWatchingSection.tsx index 104f4d9f..62bdd020 100644 --- a/src/components/home/ContinueWatchingSection.tsx +++ b/src/components/home/ContinueWatchingSection.tsx @@ -119,6 +119,7 @@ const ContinueWatchingSection = React.forwardRef((props, re const [loading, setLoading] = useState(true); const appState = useRef(AppState.currentState); const refreshTimerRef = useRef(null); + const pendingRefreshRef = useRef(false); const [deletingItemId, setDeletingItemId] = useState(null); const longPressTimeoutRef = useRef(null); @@ -326,6 +327,7 @@ const ContinueWatchingSection = React.forwardRef((props, re // Modified loadContinueWatching to render incrementally const loadContinueWatching = useCallback(async (isBackgroundRefresh = false) => { if (isRefreshingRef.current) { + pendingRefreshRef.current = true; return; } @@ -368,6 +370,20 @@ const ContinueWatchingSection = React.forwardRef((props, re return candidateProgress > existingProgress; }; + const compareCwItems = (a: ContinueWatchingItem, b: ContinueWatchingItem): number => { + const aProgress = a.progress ?? 0; + const bProgress = b.progress ?? 0; + const aIsUpNext = a.type === 'series' && aProgress <= 0; + const bIsUpNext = b.type === 'series' && bProgress <= 0; + + // Keep active in-progress items ahead of "Up Next" placeholders. + if (aIsUpNext !== bIsUpNext) { + return aIsUpNext ? 1 : -1; + } + + return (b.lastUpdated ?? 0) - (a.lastUpdated ?? 0); + }; + type LocalProgressEntry = { episodeId?: string; season?: number; @@ -466,7 +482,7 @@ const ContinueWatchingSection = React.forwardRef((props, re } const merged = Array.from(map.values()); - merged.sort((a, b) => (b.lastUpdated ?? 0) - (a.lastUpdated ?? 0)); + merged.sort(compareCwItems); return merged; }); @@ -1272,7 +1288,7 @@ const ContinueWatchingSection = React.forwardRef((props, re }); // Sort by lastUpdated descending and set directly - adjustedItems.sort((a, b) => (b.lastUpdated ?? 0) - (a.lastUpdated ?? 0)); + adjustedItems.sort(compareCwItems); // Debug final order (only if changed) try { @@ -1515,7 +1531,7 @@ const ContinueWatchingSection = React.forwardRef((props, re return it; }); - adjustedItems.sort((a, b) => (b.lastUpdated ?? 0) - (a.lastUpdated ?? 0)); + adjustedItems.sort(compareCwItems); setContinueWatchingItems(adjustedItems); } catch (err) { logger.error('[SimklSync] Error in Simkl merge:', err); @@ -1529,6 +1545,12 @@ const ContinueWatchingSection = React.forwardRef((props, re } finally { setLoading(false); isRefreshingRef.current = false; + if (pendingRefreshRef.current) { + pendingRefreshRef.current = false; + setTimeout(() => { + loadContinueWatching(true); + }, 0); + } } }, [getCachedMetadata]); @@ -1602,6 +1624,13 @@ const ContinueWatchingSection = React.forwardRef((props, re // Initial load useEffect(() => { loadContinueWatching(); + const trailingRefreshId = setTimeout(() => { + loadContinueWatching(true); + }, 4000); + + return () => { + clearTimeout(trailingRefreshId); + }; }, [loadContinueWatching]); // Refresh on screen focus (lightweight, no polling) @@ -1879,7 +1908,8 @@ const ContinueWatchingSection = React.forwardRef((props, re }, [computedPosterWidth]); // Memoized render function for poster-style continue watching items - const renderPosterStyleItem = useCallback(({ item }: { item: ContinueWatchingItem }) => ( + const renderPosterStyleItem = useCallback(({ item }: { item: ContinueWatchingItem }) => { + return ( ((props, re )} - ), [currentTheme.colors, handleContentPress, handleLongPress, deletingItemId, computedPosterWidth, computedPosterHeight, isTV, isLargeTablet, settings.posterBorderRadius]); + ); + }, [currentTheme.colors, handleContentPress, handleLongPress, deletingItemId, computedPosterWidth, computedPosterHeight, isTV, isLargeTablet, settings.posterBorderRadius]); // Memoized render function for wide-style continue watching items - const renderWideStyleItem = useCallback(({ item }: { item: ContinueWatchingItem }) => ( + const renderWideStyleItem = useCallback(({ item }: { item: ContinueWatchingItem }) => { + return ( ((props, re )} - ), [currentTheme.colors, handleContentPress, handleLongPress, deletingItemId, computedItemWidth, computedItemHeight, isTV, isLargeTablet, isTablet, settings.posterBorderRadius]); + ); + }, [currentTheme.colors, handleContentPress, handleLongPress, deletingItemId, computedItemWidth, computedItemHeight, isTV, isLargeTablet, isTablet, settings.posterBorderRadius, t]); // Choose the appropriate render function based on settings const renderContinueWatchingItem = useCallback(({ item }: { item: ContinueWatchingItem }) => { @@ -2190,7 +2223,14 @@ const ContinueWatchingSection = React.forwardRef((props, re (b.lastUpdated ?? 0) - (a.lastUpdated ?? 0))} + data={[...continueWatchingItems].sort((a, b) => { + const aProgress = a.progress ?? 0; + const bProgress = b.progress ?? 0; + const aIsUpNext = a.type === 'series' && aProgress <= 0; + const bIsUpNext = b.type === 'series' && bProgress <= 0; + if (aIsUpNext !== bIsUpNext) return aIsUpNext ? 1 : -1; + return (b.lastUpdated ?? 0) - (a.lastUpdated ?? 0); + })} renderItem={renderContinueWatchingItem} keyExtractor={keyExtractor} horizontal diff --git a/src/components/metadata/.HeroSection.tsx.swp b/src/components/metadata/.HeroSection.tsx.swp deleted file mode 100644 index 6a8c4627..00000000 Binary files a/src/components/metadata/.HeroSection.tsx.swp and /dev/null differ diff --git a/src/components/player/AndroidVideoPlayer.tsx b/src/components/player/AndroidVideoPlayer.tsx index 12a843e3..331937f3 100644 --- a/src/components/player/AndroidVideoPlayer.tsx +++ b/src/components/player/AndroidVideoPlayer.tsx @@ -11,7 +11,8 @@ import { usePlayerModals, useSpeedControl, useOpeningAnimation, - useWatchProgress + useWatchProgress, + useSkipSegments } from './hooks'; // Android-specific hooks @@ -222,6 +223,16 @@ const AndroidVideoPlayer: React.FC = () => { const nextEpisodeHook = useNextEpisode(type, season, episode, groupedEpisodes, (metadataResult as any)?.groupedEpisodes, episodeId); + const { segments: skipIntervals, outroSegment } = useSkipSegments({ + imdbId: imdbId || (id?.startsWith('tt') ? id : undefined), + type, + season, + episode, + malId: (metadata as any)?.mal_id || (metadata as any)?.external_ids?.mal_id, + kitsuId: id?.startsWith('kitsu:') ? id.split(':')[1] : undefined, + enabled: settings.skipIntroEnabled + }); + const fadeAnim = useRef(new Animated.Value(1)).current; useEffect(() => { @@ -975,6 +986,7 @@ const AndroidVideoPlayer: React.FC = () => { episode={episode} malId={(metadata as any)?.mal_id || (metadata as any)?.external_ids?.mal_id} kitsuId={id?.startsWith('kitsu:') ? id.split(':')[1] : undefined} + skipIntervals={skipIntervals} currentTime={playerState.currentTime} onSkip={(endTime) => controlsHook.seekToTime(endTime)} controlsVisible={playerState.showControls} @@ -1002,6 +1014,7 @@ const AndroidVideoPlayer: React.FC = () => { metadata={metadataResult?.metadata ? { poster: metadataResult.metadata.poster, id: metadataResult.metadata.id } : undefined} controlsVisible={playerState.showControls} controlsFixedOffset={100} + outroSegment={outroSegment} /> diff --git a/src/components/player/KSPlayerCore.tsx b/src/components/player/KSPlayerCore.tsx index b6ca3d47..231d71d8 100644 --- a/src/components/player/KSPlayerCore.tsx +++ b/src/components/player/KSPlayerCore.tsx @@ -36,7 +36,8 @@ import { usePlayerControls, usePlayerSetup, useWatchProgress, - useNextEpisode + useNextEpisode, + useSkipSegments } from './hooks'; // Platform-specific hooks @@ -209,6 +210,16 @@ const KSPlayerCore: React.FC = () => { episodeId }); + const { segments: skipIntervals, outroSegment } = useSkipSegments({ + imdbId: imdbId || (id?.startsWith('tt') ? id : undefined), + type, + season, + episode, + malId: (metadata as any)?.mal_id || (metadata as any)?.external_ids?.mal_id, + kitsuId: id?.startsWith('kitsu:') ? id.split(':')[1] : undefined, + enabled: settings.skipIntroEnabled + }); + const controls = usePlayerControls({ playerRef: ksPlayerRef, paused, @@ -945,6 +956,7 @@ const KSPlayerCore: React.FC = () => { episode={episode} malId={(metadata as any)?.mal_id || (metadata as any)?.external_ids?.mal_id} kitsuId={id?.startsWith('kitsu:') ? id.split(':')[1] : undefined} + skipIntervals={skipIntervals} currentTime={currentTime} onSkip={(endTime) => controls.seekToTime(endTime)} controlsVisible={showControls} @@ -972,6 +984,7 @@ const KSPlayerCore: React.FC = () => { metadata={metadata ? { poster: metadata.poster, id: metadata.id } : undefined} controlsVisible={showControls} controlsFixedOffset={126} + outroSegment={outroSegment} /> {/* Modals */} @@ -1102,4 +1115,4 @@ const KSPlayerCore: React.FC = () => { ); }; -export default KSPlayerCore; \ No newline at end of file +export default KSPlayerCore; diff --git a/src/components/player/common/UpNextButton.tsx b/src/components/player/common/UpNextButton.tsx index 9958e0c6..77f44416 100644 --- a/src/components/player/common/UpNextButton.tsx +++ b/src/components/player/common/UpNextButton.tsx @@ -4,6 +4,7 @@ import { Animated } from 'react-native'; import { MaterialIcons } from '@expo/vector-icons'; import { logger } from '../../../utils/logger'; import { LinearGradient } from 'expo-linear-gradient'; +import { SkipInterval } from '../../../services/introService'; export interface Insets { top: number; @@ -33,6 +34,7 @@ interface UpNextButtonProps { metadata?: { poster?: string; id?: string }; // Added metadata prop controlsVisible?: boolean; controlsFixedOffset?: number; + outroSegment?: SkipInterval | null; } const UpNextButton: React.FC = ({ @@ -49,6 +51,7 @@ const UpNextButton: React.FC = ({ metadata, controlsVisible = false, controlsFixedOffset = 100, + outroSegment, }) => { const [visible, setVisible] = useState(false); const opacity = useRef(new Animated.Value(0)).current; @@ -76,10 +79,20 @@ const UpNextButton: React.FC = ({ const shouldShow = useMemo(() => { if (!nextEpisode || duration <= 0) return false; + + // 1. Determine if we have a valid ending outro (within last 5 mins) + const hasValidEndingOutro = outroSegment && (duration - outroSegment.endTime < 300); + + if (hasValidEndingOutro) { + // If we have a valid outro, ONLY show after it finishes + // This prevents the 60s fallback from "jumping the gun" + return currentTime >= outroSegment.endTime; + } + + // 2. Standard Fallback (only if no valid ending outro was found) const timeRemaining = duration - currentTime; - // Be tolerant to timer jitter: show when under ~1 minute and above 10s - return timeRemaining < 61 && timeRemaining > 10; - }, [nextEpisode, duration, currentTime]); + return timeRemaining < 61 && timeRemaining > 0; + }, [nextEpisode, duration, currentTime, outroSegment]); // Debug logging removed to reduce console noise // The state is computed in shouldShow useMemo above diff --git a/src/components/player/controls/PlayerControls.tsx b/src/components/player/controls/PlayerControls.tsx index 29861710..18084de0 100644 --- a/src/components/player/controls/PlayerControls.tsx +++ b/src/components/player/controls/PlayerControls.tsx @@ -12,6 +12,14 @@ import { useSettings } from '../../../hooks/useSettings'; import { introService } from '../../../services/introService'; import { toastService } from '../../../services/toastService'; +import PlayerAspectRatioIcon from '../../../../assets/player-icons/ic_player_aspect_ratio.svg'; +import PlayerAudioFilledIcon from '../../../../assets/player-icons/ic_player_audio_filled.svg'; +import PlayerAudioOutlineIcon from '../../../../assets/player-icons/ic_player_audio_outline.svg'; +import PlayerEpisodesIcon from '../../../../assets/player-icons/ic_player_episodes.svg'; +import PlayerPauseIcon from '../../../../assets/player-icons/ic_player_pause.svg'; +import PlayerPlayIcon from '../../../../assets/player-icons/ic_player_play.svg'; +import PlayerSourceIcon from '../../../../assets/player-icons/ic_player_source.svg'; +import PlayerSubtitlesIcon from '../../../../assets/player-icons/ic_player_subtitles.svg'; interface PlayerControlsProps { showControls: boolean; @@ -498,11 +506,11 @@ export const PlayerControls: React.FC = ({ {isBuffering ? ( ) : ( - + paused ? ( + + ) : ( + + ) )} @@ -594,7 +602,7 @@ export const PlayerControls: React.FC = ({ {/* Left Side: Aspect Ratio Button */} - + {/* Subtitle Button */} @@ -602,7 +610,7 @@ export const PlayerControls: React.FC = ({ style={styles.iconButton} onPress={() => setShowSubtitleModal(!isSubtitleModalOpen)} > - + {/* Change Source Button */} @@ -611,7 +619,7 @@ export const PlayerControls: React.FC = ({ style={styles.iconButton} onPress={() => setShowSourcesModal(true)} > - + )} @@ -626,11 +634,11 @@ export const PlayerControls: React.FC = ({ onPress={() => setShowAudioModal(true)} disabled={ksAudioTracks.length <= 1} > - + {ksAudioTracks.length <= 1 ? ( + + ) : ( + + )} {/* Submit Intro Button */} @@ -653,7 +661,7 @@ export const PlayerControls: React.FC = ({ style={styles.iconButton} onPress={() => setShowEpisodesModal(true)} > - + )} diff --git a/src/components/player/hooks/index.ts b/src/components/player/hooks/index.ts index 570d3de1..8041cb78 100644 --- a/src/components/player/hooks/index.ts +++ b/src/components/player/hooks/index.ts @@ -20,3 +20,4 @@ export { usePlayerSetup } from './usePlayerSetup'; // Content export { useNextEpisode } from './useNextEpisode'; export { useWatchProgress } from './useWatchProgress'; +export { useSkipSegments } from './useSkipSegments'; diff --git a/src/components/player/hooks/useSkipSegments.ts b/src/components/player/hooks/useSkipSegments.ts new file mode 100644 index 00000000..3a81e86d --- /dev/null +++ b/src/components/player/hooks/useSkipSegments.ts @@ -0,0 +1,100 @@ +import { useState, useEffect, useRef } from 'react'; +import { introService, SkipInterval } from '../../../services/introService'; +import { logger } from '../../../utils/logger'; + +interface UseSkipSegmentsProps { + imdbId?: string; + type?: string; + season?: number; + episode?: number; + malId?: string; + kitsuId?: string; + enabled: boolean; +} + +export const useSkipSegments = ({ + imdbId, + type, + season, + episode, + malId, + kitsuId, + enabled +}: UseSkipSegmentsProps) => { + const [segments, setSegments] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const fetchedRef = useRef(false); + const lastKeyRef = useRef(''); + + useEffect(() => { + const key = `${imdbId}-${season}-${episode}-${malId}-${kitsuId}`; + + if (!enabled || type !== 'series' || (!imdbId && !malId && !kitsuId) || !season || !episode) { + setSegments([]); + setIsLoading(false); + fetchedRef.current = false; + lastKeyRef.current = ''; + return; + } + + if (lastKeyRef.current === key && fetchedRef.current) { + return; + } + + // Clear stale intervals while resolving a new episode/key. + if (lastKeyRef.current !== key) { + setSegments([]); + fetchedRef.current = false; + } + + lastKeyRef.current = key; + setIsLoading(true); + let cancelled = false; + + const fetchSegments = async () => { + try { + const intervals = await introService.getSkipTimes(imdbId, season, episode, malId, kitsuId); + + // Ignore stale responses from old requests. + if (cancelled || lastKeyRef.current !== key) return; + setSegments(intervals); + fetchedRef.current = true; + } catch (error) { + if (cancelled || lastKeyRef.current !== key) return; + logger.error('[useSkipSegments] Error fetching skip data:', error); + setSegments([]); + // Keep this key retryable on transient failures. + fetchedRef.current = false; + } finally { + if (cancelled || lastKeyRef.current !== key) return; + setIsLoading(false); + } + }; + + fetchSegments(); + + return () => { + cancelled = true; + }; + }, [imdbId, type, season, episode, malId, kitsuId, enabled]); + + const getActiveSegment = (currentTime: number) => { + return segments.find( + s => currentTime >= s.startTime && currentTime < (s.endTime - 0.5) + ); + }; + + const outroSegment = segments + .filter(s => ['ed', 'outro', 'mixed-ed'].includes(s.type)) + .reduce((latest, interval) => { + if (!latest || interval.endTime > latest.endTime) return interval; + return latest; + }, null); + + return { + segments, + getActiveSegment, + outroSegment, + isLoading + }; +}; diff --git a/src/components/player/modals/SubmitIntroModal.tsx b/src/components/player/modals/SubmitIntroModal.tsx index 42873ba0..11afaa7c 100644 --- a/src/components/player/modals/SubmitIntroModal.tsx +++ b/src/components/player/modals/SubmitIntroModal.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from 'react'; -import { View, Text, TouchableOpacity, useWindowDimensions, StyleSheet, TextInput, ActivityIndicator } from 'react-native'; +import { View, Text, TouchableOpacity, useWindowDimensions, StyleSheet, TextInput, ActivityIndicator, ScrollView } from 'react-native'; import { Ionicons, MaterialIcons } from '@expo/vector-icons'; import { useTranslation } from 'react-i18next'; import Animated, { @@ -9,7 +9,7 @@ import Animated, { SlideOutDown, } from 'react-native-reanimated'; import { useSettings } from '../../../hooks/useSettings'; -import { introService } from '../../../services/introService'; +import { introService, SkipType } from '../../../services/introService'; import { toastService } from '../../../services/toastService'; interface SubmitIntroModalProps { @@ -67,6 +67,7 @@ export const SubmitIntroModal: React.FC = ({ const [startTimeStr, setStartTimeStr] = useState('00:00'); const [endTimeStr, setEndTimeStr] = useState(formatSecondsToMMSS(currentTime)); + const [segmentType, setSegmentType] = useState('intro'); const [isSubmitting, setIsSubmitting] = useState(false); useEffect(() => { @@ -107,14 +108,15 @@ export const SubmitIntroModal: React.FC = ({ season, episode, startSec, - endSec + endSec, + segmentType ); if (success) { - toastService.success(t('player_ui.intro_submitted', { defaultValue: 'Intro submitted successfully' })); + toastService.success(t('player_ui.intro_submitted', { defaultValue: 'Segment submitted successfully' })); onClose(); } else { - toastService.error(t('player_ui.intro_submit_failed', { defaultValue: 'Failed to submit intro' })); + toastService.error(t('player_ui.intro_submit_failed', { defaultValue: 'Failed to submit segment' })); } } catch (error) { toastService.error('Error', 'An unexpected error occurred'); @@ -123,9 +125,11 @@ export const SubmitIntroModal: React.FC = ({ } }; - const startVal = parseTimeToSeconds(startTimeStr); - const endVal = parseTimeToSeconds(endTimeStr); - const durationSec = (startVal !== null && endVal !== null) ? endVal - startVal : 0; + const segmentTypes: { label: string; value: SkipType; icon: any }[] = [ + { label: 'Intro', value: 'intro', icon: 'play-circle-outline' }, + { label: 'Recap', value: 'recap', icon: 'replay' }, + { label: 'Outro', value: 'outro', icon: 'stop-circle' }, + ]; return ( @@ -144,13 +148,42 @@ export const SubmitIntroModal: React.FC = ({ style={[localStyles.modalContainer, { width: Math.min(width * 0.85, 380) }]} > - Submit Intro Timestamp + Submit Timestamps - + + {/* Segment Type Selector */} + + Segment Type + + {segmentTypes.map((type) => ( + setSegmentType(type.value)} + style={[ + localStyles.typeButton, + segmentType === type.value && localStyles.typeButtonActive + ]} + > + + + {type.label} + + + ))} + + + {/* Start Time Input */} @@ -214,7 +247,7 @@ export const SubmitIntroModal: React.FC = ({ )} - + @@ -239,6 +272,7 @@ const localStyles = StyleSheet.create({ shadowOpacity: 0.5, shadowRadius: 15, elevation: 20, + maxHeight: '80%', }, header: { flexDirection: 'row', @@ -257,6 +291,34 @@ const localStyles = StyleSheet.create({ content: { gap: 20, }, + typeRow: { + flexDirection: 'row', + gap: 8, + }, + typeButton: { + flex: 1, + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'center', + gap: 6, + backgroundColor: 'rgba(255,255,255,0.05)', + borderRadius: 12, + paddingVertical: 10, + borderWidth: 1, + borderColor: 'rgba(255,255,255,0.1)', + }, + typeButtonActive: { + backgroundColor: 'white', + borderColor: 'white', + }, + typeButtonText: { + color: 'rgba(255,255,255,0.6)', + fontSize: 13, + fontWeight: '600', + }, + typeButtonTextActive: { + color: 'black', + }, inputRow: { flexDirection: 'row', alignItems: 'flex-end', @@ -295,22 +357,6 @@ const localStyles = StyleSheet.create({ fontSize: 13, fontWeight: '600', }, - summaryBox: { - backgroundColor: 'rgba(255,255,255,0.03)', - borderRadius: 16, - padding: 16, - marginTop: 8, - }, - summaryText: { - color: 'rgba(255,255,255,0.5)', - fontSize: 14, - marginBottom: 4, - }, - hintText: { - color: 'rgba(255,255,255,0.3)', - fontSize: 12, - fontStyle: 'italic', - }, buttonRow: { flexDirection: 'row', gap: 12, @@ -345,3 +391,4 @@ const localStyles = StyleSheet.create({ fontWeight: '700', }, }); + diff --git a/src/components/player/overlays/SkipIntroButton.tsx b/src/components/player/overlays/SkipIntroButton.tsx index b5329c6a..67f72173 100644 --- a/src/components/player/overlays/SkipIntroButton.tsx +++ b/src/components/player/overlays/SkipIntroButton.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect, useRef, useCallback } from 'react'; -import { Text, TouchableOpacity, StyleSheet, Platform } from 'react-native'; +import { Text, TouchableOpacity, StyleSheet, Platform, View } from 'react-native'; import Animated, { useSharedValue, useAnimatedStyle, @@ -10,10 +10,11 @@ import Animated, { import { useSafeAreaInsets } from 'react-native-safe-area-context'; import { MaterialIcons } from '@expo/vector-icons'; import { BlurView } from 'expo-blur'; -import { introService, SkipInterval, SkipType } from '../../../services/introService'; +import { SkipInterval } from '../../../services/introService'; import { useTheme } from '../../../contexts/ThemeContext'; import { logger } from '../../../utils/logger'; import { useSettings } from '../../../hooks/useSettings'; +import { useSkipSegments } from '../hooks/useSkipSegments'; interface SkipIntroButtonProps { imdbId: string | undefined; @@ -22,6 +23,7 @@ interface SkipIntroButtonProps { episode?: number; malId?: string; kitsuId?: string; + skipIntervals?: SkipInterval[] | null; currentTime: number; onSkip: (endTime: number) => void; controlsVisible?: boolean; @@ -35,6 +37,7 @@ export const SkipIntroButton: React.FC = ({ episode, malId, kitsuId, + skipIntervals: externalSkipIntervals, currentTime, onSkip, controlsVisible = false, @@ -46,16 +49,25 @@ export const SkipIntroButton: React.FC = ({ const skipIntroEnabled = settings.skipIntroEnabled; + const { segments: fetchedSkipIntervals } = useSkipSegments({ + imdbId, + type, + season, + episode, + malId, + kitsuId, + // Allow parent components to provide pre-fetched intervals to avoid duplicate requests. + enabled: skipIntroEnabled && !externalSkipIntervals + }); + const skipIntervals = externalSkipIntervals ?? fetchedSkipIntervals; + // State - const [skipIntervals, setSkipIntervals] = useState([]); const [currentInterval, setCurrentInterval] = useState(null); const [isVisible, setIsVisible] = useState(false); const [hasSkippedCurrent, setHasSkippedCurrent] = useState(false); const [autoHidden, setAutoHidden] = useState(false); // Refs - const fetchedRef = useRef(false); - const lastEpisodeRef = useRef(''); const autoHideTimerRef = useRef(null); // Animation values @@ -63,55 +75,11 @@ export const SkipIntroButton: React.FC = ({ const scale = useSharedValue(0.8); const translateY = useSharedValue(0); - // Fetch skip data when episode changes + // Reset skipped state when episode changes useEffect(() => { - const episodeKey = `${imdbId}-${season}-${episode}-${malId}-${kitsuId}`; - - if (!skipIntroEnabled) { - setSkipIntervals([]); - setCurrentInterval(null); - setIsVisible(false); - fetchedRef.current = false; - return; - } - - // Skip if not a series or missing required data (though MAL/Kitsu ID might be enough for some cases, usually need season/ep) - if (type !== 'series' || (!imdbId && !malId && !kitsuId) || !season || !episode) { - setSkipIntervals([]); - fetchedRef.current = false; - return; - } - - // Skip if already fetched for this episode - if (lastEpisodeRef.current === episodeKey && fetchedRef.current) { - return; - } - - lastEpisodeRef.current = episodeKey; - fetchedRef.current = true; setHasSkippedCurrent(false); setAutoHidden(false); - setSkipIntervals([]); - - const fetchSkipData = async () => { - logger.log(`[SkipIntroButton] Fetching skip data for S${season}E${episode} (IMDB: ${imdbId}, MAL: ${malId}, Kitsu: ${kitsuId})...`); - try { - const intervals = await introService.getSkipTimes(imdbId, season, episode, malId, kitsuId); - setSkipIntervals(intervals); - - if (intervals.length > 0) { - logger.log(`[SkipIntroButton] ✓ Found ${intervals.length} skip intervals:`, intervals); - } else { - logger.log(`[SkipIntroButton] ✗ No skip data available for this episode`); - } - } catch (error) { - logger.error('[SkipIntroButton] Error fetching skip data:', error); - setSkipIntervals([]); - } - }; - - fetchSkipData(); - }, [imdbId, type, season, episode, malId, kitsuId, skipIntroEnabled]); + }, [imdbId, season, episode, malId, kitsuId]); // Determine active interval based on current playback position useEffect(() => { @@ -278,7 +246,7 @@ export const SkipIntroButton: React.FC = ({ style={styles.icon} /> {getButtonText()} - = ({ child user, loading, signIn: async (email: string, password: string) => { - const { error } = await accountService.signInWithEmail(email, password); + const { user: signedInUser, error } = await accountService.signInWithEmail(email, password); + if (!error && signedInUser) { + setUser(signedInUser); + } return error || null; }, signUp: async (email: string, password: string) => { - const { error } = await accountService.signUpWithEmail(email, password); + const { user: signedUpUser, error } = await accountService.signUpWithEmail(email, password); + if (!error && signedUpUser) { + setUser(signedUpUser); + } return error || null; }, signOut: async () => { @@ -107,4 +113,3 @@ export const useAccount = (): AccountContextValue => { }; export default AccountContext; - diff --git a/src/hooks/useMetadata.ts b/src/hooks/useMetadata.ts index b0d1b5c6..48cbdd72 100644 --- a/src/hooks/useMetadata.ts +++ b/src/hooks/useMetadata.ts @@ -1486,10 +1486,10 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat setActiveFetchingScrapers([]); setAddonResponseOrder([]); // Reset response order - // Get TMDB ID for external sources and determine the correct ID for Stremio addons if (__DEV__) console.log('🔍 [loadStreams] Getting TMDB ID for:', id); let tmdbId; - let stremioId = id; // Default to original ID + let stremioId = id; + let effectiveStreamType: string = type; if (id.startsWith('tmdb:')) { tmdbId = id.split(':')[1]; @@ -1544,56 +1544,66 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat const allStremioAddons = await stremioService.getInstalledAddons(); const localScrapers = await localScraperService.getInstalledScrapers(); - // Map app-level "tv" type to Stremio "series" for addon capability checks - const stremioType = type === 'tv' ? 'series' : type; + const requestedStreamType = type; - // Filter Stremio addons to only include those that provide streams for this content type - const streamAddons = allStremioAddons.filter(addon => { - if (!addon.resources || !Array.isArray(addon.resources)) { - return false; - } + const pickEligibleStreamAddons = (requestType: string) => + allStremioAddons.filter(addon => { + if (!addon.resources || !Array.isArray(addon.resources)) { + return false; + } - let hasStreamResource = false; - let supportsIdPrefix = false; + let hasStreamResource = false; + let supportsIdPrefix = false; - for (const resource of addon.resources) { - // Check if the current element is a ResourceObject - if (typeof resource === 'object' && resource !== null && 'name' in resource) { - const typedResource = resource as any; - if (typedResource.name === 'stream' && - Array.isArray(typedResource.types) && - typedResource.types.includes(stremioType)) { - hasStreamResource = true; + for (const resource of addon.resources) { + if (typeof resource === 'object' && resource !== null && 'name' in resource) { + const typedResource = resource as any; + if (typedResource.name === 'stream' && + Array.isArray(typedResource.types) && + typedResource.types.includes(requestType)) { + hasStreamResource = true; - // Check if this addon supports the ID prefix generically: any prefix must match start of id - if (Array.isArray(typedResource.idPrefixes) && typedResource.idPrefixes.length > 0) { - supportsIdPrefix = typedResource.idPrefixes.some((p: string) => id.startsWith(p)); - } else { - // If no idPrefixes specified, assume it supports all prefixes - supportsIdPrefix = true; + if (Array.isArray(typedResource.idPrefixes) && typedResource.idPrefixes.length > 0) { + supportsIdPrefix = typedResource.idPrefixes.some((p: string) => stremioId.startsWith(p)); + } else { + supportsIdPrefix = true; + } + break; + } + } else if (typeof resource === 'string' && resource === 'stream' && addon.types) { + if (Array.isArray(addon.types) && addon.types.includes(requestType)) { + hasStreamResource = true; + if (addon.idPrefixes && Array.isArray(addon.idPrefixes) && addon.idPrefixes.length > 0) { + supportsIdPrefix = addon.idPrefixes.some((p: string) => stremioId.startsWith(p)); + } else { + supportsIdPrefix = true; + } + break; } - break; } } - // Check if the element is the simple string "stream" AND the addon has a top-level types array - else if (typeof resource === 'string' && resource === 'stream' && addon.types) { - if (Array.isArray(addon.types) && addon.types.includes(stremioType)) { - hasStreamResource = true; - // For simple string resources, check addon-level idPrefixes generically - if (addon.idPrefixes && Array.isArray(addon.idPrefixes) && addon.idPrefixes.length > 0) { - supportsIdPrefix = addon.idPrefixes.some((p: string) => id.startsWith(p)); - } else { - // If no idPrefixes specified, assume it supports all prefixes - supportsIdPrefix = true; - } - break; - } + + return hasStreamResource && supportsIdPrefix; + }); + + effectiveStreamType = requestedStreamType; + let eligibleStreamAddons = pickEligibleStreamAddons(requestedStreamType); + + if (eligibleStreamAddons.length === 0) { + const fallbackTypes = ['series', 'movie'].filter(t => t !== requestedStreamType); + for (const fallbackType of fallbackTypes) { + const fallback = pickEligibleStreamAddons(fallbackType); + if (fallback.length > 0) { + effectiveStreamType = fallbackType; + eligibleStreamAddons = fallback; + if (__DEV__) console.log(`[useMetadata.loadStreams] No addons for '${requestedStreamType}', falling back to '${fallbackType}'`); + break; } } + } - return hasStreamResource && supportsIdPrefix; - }); - if (__DEV__) console.log('[useMetadata.loadStreams] Eligible stream addons:', streamAddons.map(a => a.id)); + const streamAddons = eligibleStreamAddons; + if (__DEV__) console.log('[useMetadata.loadStreams] Eligible stream addons:', streamAddons.map(a => a.id), { requestedStreamType, effectiveStreamType }); // Initialize scraper statuses for tracking const initialStatuses: ScraperStatus[] = []; @@ -1645,9 +1655,9 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat // Start Stremio request using the converted ID format if (__DEV__) console.log('🎬 [loadStreams] Using ID for Stremio addons:', stremioId); - // Map app-level "tv" type to Stremio "series" when requesting streams - const stremioContentType = type === 'tv' ? 'series' : type; - processStremioSource(stremioContentType, stremioId, false); + // Use the effective type we selected when building the eligible addon list. + // This stays aligned with Stremio manifest filtering rules and avoids hard-mapping non-standard types. + processStremioSource(effectiveStreamType, stremioId, false); // Also extract any embedded streams from metadata (PPV-style addons) extractEmbeddedStreams(); @@ -1707,36 +1717,41 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat const allStremioAddons = await stremioService.getInstalledAddons(); const localScrapers = await localScraperService.getInstalledScrapers(); - // Filter Stremio addons to only include those that provide streams for series content - const streamAddons = allStremioAddons.filter(addon => { - if (!addon.resources || !Array.isArray(addon.resources)) { + // We don't yet know the final episode ID format here (it can be normalized later), + // but we can still pre-filter by stream capability for the most likely types. + const pickStreamCapableAddons = (requestType: string) => + allStremioAddons.filter(addon => { + if (!addon.resources || !Array.isArray(addon.resources)) return false; + + for (const resource of addon.resources) { + if (typeof resource === 'object' && resource !== null && 'name' in resource) { + const typedResource = resource as any; + if (typedResource.name === 'stream' && Array.isArray(typedResource.types) && typedResource.types.includes(requestType)) { + return true; + } + } else if (typeof resource === 'string' && resource === 'stream' && addon.types) { + if (Array.isArray(addon.types) && addon.types.includes(requestType)) { + return true; + } + } + } return false; - } + }); - let hasStreamResource = false; - - for (const resource of addon.resources) { - // Check if the current element is a ResourceObject - if (typeof resource === 'object' && resource !== null && 'name' in resource) { - const typedResource = resource as any; - if (typedResource.name === 'stream' && - Array.isArray(typedResource.types) && - typedResource.types.includes('series')) { - hasStreamResource = true; - break; - } - } - // Check if the element is the simple string "stream" AND the addon has a top-level types array - else if (typeof resource === 'string' && resource === 'stream' && addon.types) { - if (Array.isArray(addon.types) && addon.types.includes('series')) { - hasStreamResource = true; - break; - } + const requestedEpisodeType = type; + let streamAddons = pickStreamCapableAddons(requestedEpisodeType); + + if (streamAddons.length === 0) { + const fallbackTypes = ['series', 'movie'].filter(t => t !== requestedEpisodeType); + for (const fallbackType of fallbackTypes) { + const fallback = pickStreamCapableAddons(fallbackType); + if (fallback.length > 0) { + streamAddons = fallback; + if (__DEV__) console.log(`[useMetadata.loadEpisodeStreams] No addons for '${requestedEpisodeType}', falling back to '${fallbackType}'`); + break; } } - - return hasStreamResource; - }); + } // Initialize scraper statuses for tracking const initialStatuses: ScraperStatus[] = []; @@ -1923,10 +1938,8 @@ export const useMetadata = ({ id, type, addonId }: UseMetadataProps): UseMetadat // Start Stremio request using the converted episode ID format if (__DEV__) console.log('🎬 [loadEpisodeStreams] Using episode ID for Stremio addons:', stremioEpisodeId); - // For collections, treat episodes as individual movies, not series - // For other types (e.g. StreamsPPV), preserve the original type unless it's explicitly 'series' logic we want - // Map app-level "tv" type to Stremio "series" for addon stream endpoint - const contentType = isCollection ? 'movie' : (type === 'tv' ? 'series' : type); + const requestedContentType = isCollection ? 'movie' : type; + const contentType = requestedContentType; if (__DEV__) console.log(`🎬 [loadEpisodeStreams] Using content type: ${contentType} for ${isCollection ? 'collection' : type}`); processStremioSource(contentType, stremioEpisodeId, true); diff --git a/src/i18n/locales/ar.json b/src/i18n/locales/ar.json index 47a0ad2f..cc29d446 100644 --- a/src/i18n/locales/ar.json +++ b/src/i18n/locales/ar.json @@ -636,6 +636,18 @@ "chinese": "الصينية (المبسطة)", "hindi": "الهندية", "serbian": "الصربية", + "hebrew": "العبرية", + "bulgarian": "بلغاري", + "polish": "بولندي", + "czech": "التشيكية", + "turkish": "التركية", + "slovenian": "السلوفينية", + "macedonian": "مقدوني", + "russian": "الروسية", + "filipino": "الفلبينية", + "dutch_nl": "الهولندية (هولندا)", + "romanian": "روماني", + "albanian": "ألباني", "account": "الحساب", "content_discovery": "المحتوى والاكتشاف", "appearance": "المظهر", @@ -896,8 +908,8 @@ }, "debrid": { "title": "تكامل Debrid", - "description_torbox": "افتح بثوث 4K عالية الجودة وسرعات البرق من خلال دمج Torbox. أدخل مفتاح API الخاص بك أدناه لتطوير تجربة البث فوراً.", - "description_torrentio": "قم بتهيئة Torrentio للحصول على بثوث تورنت للأفلام والبرامج التلفزيونية. مطلوب خدمة debrid لبث المحتوى.", + "description_torbox": "Connect Torbox to use your account-based source preferences. Enter your API key below to configure the integration.", + "description_torrentio": "Configure Torrentio as an external source integration. A compatible debrid account may be required depending on your setup.", "tab_torbox": "TorBox", "tab_torrentio": "Torrentio", "status_connected": "متصل", @@ -924,15 +936,15 @@ "enter_api_key": "أدخل مفتاح API الخاص بك", "connect_button": "اتصال وتثبيت", "connecting": "جاري الاتصال...", - "unlock_speeds_title": "افتح سرعات مميزة", - "unlock_speeds_desc": "احصل على اشتراك Torbox للوصول إلى بثوث عالية الجودة مخزنة مؤقتاً بدون تقطيع.", + "unlock_speeds_title": "Optional Torbox Subscription", + "unlock_speeds_desc": "Torbox offers account tiers with enhanced performance and availability features.", "get_subscription": "احصل على اشتراك", "powered_by": "مدعوم بواسطة", "disclaimer_torbox": "Nuvio ليس منتسباً لـ Torbox بأي شكل من الأشكال.", "disclaimer_torrentio": "Nuvio ليس منتسباً لـ Torrentio بأي شكل من الأشكال.", "installed_badge": "✓ تم التثبيت", "promo_title": "⚡ هل تحتاج إلى خدمة Debrid؟", - "promo_desc": "احصل على TorBox للبث السريع بدقة 4K بدون تقطيع. تورنت مميز مخزن مؤقتاً وتنزيلات فورية.", + "promo_desc": "Use TorBox if you want account-managed performance features for supported integrations.", "promo_button": "احصل على اشتراك TorBox", "service_label": "خدمة Debrid *", "api_key_label": "مفتاح API *", @@ -1324,7 +1336,7 @@ "user_resp_title": "مسؤولية المستخدم", "user_resp_text": "المستخدمون مسؤولون وحدهم عن الامتدادات التي يقومون بتثبيتها والمحتوى الذي يصلون إليه. باستخدام هذا التطبيق، فإنك توافق على ضمان أن لديك الحق القانوني في الوصول إلى أي محتوى تشاهده باستخدام Nuvio. لا يؤيد مطورو Nuvio أو يشجعون انتهاك حقوق الطبع والنشر.", "dmca_title": "حقوق الطبع والنشر و DMCA", - "dmca_text": "نحن نحترم حقوق الملكية الفكرية للآخرين. نظرًا لأن Nuvio لا يستضيف أي محتوى، فلا يمكننا إزالة المحتوى من الإنترنت. ومع ذلك، إذا كنت تعتقد أن واجهة التطبيق نفسها تنتهك حقوقك، فيرجى الاتصال بنا.", + "dmca_text": "We respect the intellectual property rights of others. Nuvio does not host media content. If you believe this project's code, assets, or interface infringes your rights, submit a notice through the official project contact channels listed on the website and repository.", "warranty_title": "لا يوجد ضمان", "warranty_text": "يتم توفير هذا البرنامج \"كما هو\"، دون أي ضمان من أي نوع، صريحًا أو ضمنيًا. لا يتحمل المؤلفون أو أصحاب حقوق الطبع والنشر بأي حال من الأحوال المسؤولية عن أي مطالبة أو أضرار أو مسؤولية أخرى تنشأ عن استخدام هذا البرنامج." }, diff --git a/src/i18n/locales/bg.json b/src/i18n/locales/bg.json new file mode 100644 index 00000000..23394570 --- /dev/null +++ b/src/i18n/locales/bg.json @@ -0,0 +1,1430 @@ +{ + "common": { + "loading": "Зареждане...", + "cancel": "Отказ", + "save": "Запазване", + "delete": "Изтриване", + "edit": "Редактиране", + "search": "Търсене", + "error": "Грешка", + "success": "Успех", + "ok": "ОК", + "unknown": "Неизвестно", + "retry": "Повторен опит", + "try_again": "Опитайте отново", + "go_back": "Назад", + "settings": "Настройки", + "close": "Затваряне", + "enable": "Активиране", + "disable": "Деактивиране", + "show_more": "Покажи повече", + "show_less": "Покажи по-малко", + "load_more": "Зареди още", + "unknown_date": "Неизвестна дата", + "anonymous_user": "Анонимен потребител", + "time": { + "now": "Току-що", + "minutes_ago": "преди {{count}}м", + "hours_ago": "преди {{count}}ч", + "days_ago": "преди {{count}}д" + }, + "days_short": { + "sun": "Нд", + "mon": "Пн", + "tue": "Вт", + "wed": "Ср", + "thu": "Чт", + "fri": "Пт", + "sat": "Сб" + }, + "email": "Имейл", + "status": "Статус" + }, + "home": { + "categories": { + "movies": "Филми", + "series": "Сериали", + "channels": "Канали" + }, + "movies": "Филми", + "tv_shows": "ТВ предавания", + "load_more_catalogs": "Зареди още каталози", + "no_content": "Няма налично съдържание", + "add_catalogs": "Добавяне на каталози", + "sign_in_available": "Налично вписване", + "sign_in_desc": "Можете да се впишете по всяко време от Настройки → Профил", + "view_all": "Виж всички", + "this_week": "Тази седмица", + "upcoming": "Предстоящи", + "recently_released": "Наскоро пуснати", + "no_scheduled_episodes": "Сериали без планирани епизоди", + "check_back_later": "Проверете отново по-късно", + "continue_watching": "Продължи гледането", + "up_next": "Следващо", + "up_next_caps": "СЛЕДВАЩО", + "released": "Издаден", + "new": "Ново", + "tba": "Ще бъде обявено", + "new_episodes": "{{count}} нови епизода", + "season_short": "С{{season}}", + "episode_short": "Е{{episode}}", + "season": "Сезон {{season}}", + "episode": "Епизод {{episode}}", + "movie": "Филм", + "series": "Сериал", + "tv_show": "ТВ предаване", + "percent_watched": "{{percent}}% изгледано", + "view_details": "Виж детайли", + "remove": "Премахни", + "play": "Пусни", + "play_now": "Пусни сега", + "resume": "Продължи", + "info": "Инфо", + "more_info": "Още инфо", + "my_list": "Моят списък", + "save": "Запази", + "saved": "Запазено", + "retry": "Повтори", + "install_addons": "Инсталирай добавки", + "settings": "Настройки", + "no_featured_content": "Няма акцентирано съдържание", + "couldnt_load_featured": "Неуспешно зареждане на акценти", + "no_featured_desc": "Инсталирайте добавки с каталози или променете източника в настройките.", + "load_error_desc": "Проблем при извличане на съдържанието. Проверете връзката си и опитайте отново.", + "no_featured_available": "Няма налични акценти", + "no_description": "Няма налично описание" + }, + "navigation": { + "home": "Начало", + "library": "Библиотека", + "search": "Търсене", + "downloads": "Изтегляния", + "settings": "Настройки" + }, + "search": { + "title": "Търсене", + "recent_searches": "Скорошни търсения", + "discover": "Открий", + "movies": "Филми", + "tv_shows": "ТВ предавания", + "select_catalog": "Избери каталог", + "all_genres": "Всички жанрове", + "discovering": "Откриване на съдържание...", + "show_more": "Покажи още ({{count}})", + "no_content_found": "Няма намерено съдържание", + "try_different": "Опитайте различен жанр или каталог", + "select_catalog_desc": "Изберете каталог за откриване", + "tap_catalog_desc": "Докоснете каталога по-горе, за да започнете", + "placeholder": "Търсене на филми, сериали...", + "keep_typing": "Продължете да пишете...", + "type_characters": "Въведете поне 2 знака за търсене", + "no_results": "Няма намерени резултати", + "try_keywords": "Опитайте с други ключови думи или проверете правописа", + "select_type": "Избери тип", + "browse_movies": "Разгледай филмови каталози", + "browse_tv": "Разгледай каталози за сериали", + "select_genre": "Избери жанр", + "show_all_content": "Покажи цялото съдържание", + "genres_count": "{{count}} жанра" + }, + "library": { + "title": "Библиотека", + "watched": "Гледани", + "continue": "Продължи", + "watchlist": "Списък за гледане", + "collection": "Колекция", + "rated": "Оценени", + "items": "елемента", + "trakt_collections": "Trakt колекции", + "trakt_collection": "Trakt колекция", + "no_trakt": "Няма Trakt колекции", + "no_trakt_desc": "Вашите Trakt колекции ще се появят тук, след като започнете да използвате Trakt", + "load_collections": "Зареди колекции", + "empty_folder": "Няма съдържание в {{folder}}", + "empty_folder_desc": "Тази колекция е празна", + "refresh": "Обнови", + "no_movies": "Все още няма филми", + "no_series": "Все още няма ТВ сериали", + "no_content": "Все още няма съдържание", + "add_content_desc": "Добавете съдържание към библиотеката си, за да го видите тук", + "find_something": "Намери нещо за гледане", + "removed_from_library": "Премахнато от библиотеката", + "item_removed": "Елементът е премахнат от вашата библиотека", + "failed_update_library": "Неуспешно обновяване на библиотеката", + "unable_remove": "Неуспешно премахване от библиотеката", + "marked_watched": "Маркирано като изгледано", + "marked_unwatched": "Маркирано като неизгледано", + "item_marked_watched": "Елементът е маркиран като изгледан", + "item_marked_unwatched": "Елементът е маркиран като неизгледан", + "failed_update_watched": "Неуспешно обновяване на статуса", + "unable_update_watched": "Неуспешно обновяване на статуса на гледане", + "added_to_library": "Добавено в библиотеката", + "item_added": "Добавено в локалната ви библиотека", + "add_to_library": "Добави в библиотека", + "remove_from_library": "Премахни от библиотека", + "mark_watched": "Маркирай като гледано", + "mark_unwatched": "Маркирай като негледано", + "share": "Сподели", + "add_to_watchlist": "Добави в Trakt Watchlist", + "remove_from_watchlist": "Премахни от Trakt Watchlist", + "added_to_watchlist": "Добавено в списъка", + "added_to_watchlist_desc": "Добавено във вашия Trakt watchlist", + "removed_from_watchlist": "Премахнато от списъка", + "removed_from_watchlist_desc": "Премахнато от вашия Trakt watchlist", + "add_to_collection": "Добави в Trakt колекция", + "remove_from_collection": "Премахни от Trakt колекция", + "added_to_collection": "Добавено в колекция", + "added_to_collection_desc": "Добавено във вашата Trakt колекция", + "removed_from_collection": "Премахнато от колекция", + "removed_from_collection_desc": "Премахнато от вашата Trakt колекция" + }, + "metadata": { + "unable_to_load": "Неуспешно зареждане на съдържание", + "error_code": "Код на грешка: {{code}}", + "content_not_found": "Съдържанието не е намерено", + "content_not_found_desc": "Това съдържание не съществува или е премахнато.", + "server_error": "Сървърна грешка", + "server_error_desc": "Сървърът е временно недостъпен. Моля, опитайте по-късно.", + "bad_gateway": "Грешен шлюз (Bad gateway)", + "bad_gateway_desc": "Сървърът има проблеми. Моля, опитайте по-късно.", + "service_unavailable": "Услугата е недостъпна", + "service_unavailable_desc": "Услугата е в процес на профилактика. Опитайте по-късно.", + "too_many_requests": "Твърде много заявки", + "too_many_requests_desc": "Правите твърде много заявки. Моля, изчакайте и опитайте пак.", + "request_timeout": "Изтекло време за заявка", + "request_timeout_desc": "Заявката отне твърде дълго време. Опитайте отново.", + "network_error": "Мрежова грешка", + "network_error_desc": "Моля, проверете интернет връзката си.", + "auth_error": "Грешка при удостоверяване", + "auth_error_desc": "Проверете настройките на профила си и опитайте пак.", + "access_denied": "Достъпът е отказан", + "access_denied_desc": "Нямате разрешение за достъп до това съдържание.", + "connection_error": "Грешка при свързване", + "streams_unavailable": "Стриймовете са недостъпни", + "streams_unavailable_desc": "Източниците за стрийминг в момента са недостъпни. Опитайте по-късно.", + "unknown_error": "Неизвестна грешка", + "something_went_wrong": "Нещо се обърка. Моля, опитайте отново.", + "cast": "Актьорски състав", + "more_like_this": "Още подобни", + "collection": "Колекция", + "episodes": "Епизоди", + "seasons": "Сезони", + "posters": "Постери", + "banners": "Банери", + "specials": "Специални", + "season_number": "Сезон {{number}}", + "episode_count": "{{count}} Епизод", + "episode_count_plural": "{{count}} Епизода", + "no_episodes": "Няма налични епизоди", + "no_episodes_for_season": "Няма налични епизоди за Сезон {{season}}", + "episodes_not_released": "Епизодите може още да не са издадени", + "no_description": "Няма налично описание", + "episode_label": "ЕПИЗОД {{number}}", + "watch_again": "Гледай отново", + "completed": "Завършено", + "play_episode": "Пусни С{{season}}Е{{episode}}", + "play": "Пусни", + "watched": "Гледано", + "watched_on_trakt": "Гледано в Trakt", + "synced_with_trakt": "Синхронизирано с Trakt", + "saved": "Запазено", + "director": "Режисьор", + "directors": "Режисьори", + "creator": "Създател", + "creators": "Създатели", + "production": "Продукция", + "network": "Мрежа", + "mark_watched": "Маркирай като гледано", + "mark_unwatched": "Маркирай като негледано", + "marking": "Маркиране...", + "removing": "Премахване...", + "unmark_season": "Отмаркирай Сезон {{season}}", + "mark_season": "Маркирай Сезон {{season}}", + "resume": "Продължи", + "spoiler_warning": "Предупреждение за спойлер", + "spoiler_warning_desc": "Този коментар съдържа спойлери. Сигурни ли сте, че искате да го видите?", + "cancel": "Отказ", + "reveal_spoilers": "Покажи спойлерите", + "movie_details": "Детайли за филма", + "show_details": "Детайли за сериала", + "tagline": "Слоган", + "status": "Статус", + "release_date": "Дата на излизане", + "runtime": "Времетраене", + "budget": "Бюджет", + "revenue": "Приходи", + "origin_country": "Държава на произход", + "original_language": "Оригинален език", + "first_air_date": "Първо излъчване", + "last_air_date": "Последно излъчване", + "total_episodes": "Общо епизоди", + "episode_runtime": "Продължителност на епизод", + "created_by": "Създадено от", + "backdrop_gallery": "Галерия фонове", + "loading_episodes": "Зареждане на епизоди...", + "no_episodes_available": "Няма налични епизоди", + "play_next": "Следващ С{{season}}Е{{episode}}", + "play_next_episode": "Пусни следващ епизод", + "save": "Запази", + "percent_watched": "{{percent}}% изгледано", + "percent_watched_trakt": "{{percent}}% изгледано ({{traktPercent}}% в Trakt)", + "synced_with_trakt_progress": "Синхронизирано с Trakt", + "using_trakt_progress": "Използва се прогрес от Trakt", + "added_to_collection_hero": "Добавено в колекция", + "added_to_collection_desc_hero": "Добавено във вашата Trakt колекция", + "removed_from_collection_hero": "Премахнато от колекция", + "removed_from_collection_desc_hero": "Премахнато от вашата Trakt колекция", + "mark_as_watched": "Маркирай като гледано", + "mark_as_unwatched": "Маркирай като негледано" + }, + "cast": { + "biography": "Биография", + "known_for": "Известен с", + "personal_info": "Лична информация", + "born_in": "Роден в {{place}}", + "filmography": "Филмография", + "also_known_as": "Известен още като", + "no_info_available": "Няма налична допълнителна информация", + "as_character": "като {{character}}", + "loading_details": "Зареждане на детайли...", + "years_old": "на {{age}} години", + "view_filmography": "Виж филмографията", + "filter": "Филтър", + "sort_by": "Сортирай по", + "sort_popular": "Популярни", + "sort_latest": "Най-нови", + "sort_upcoming": "Предстоящи", + "upcoming_badge": "ПРЕДСТОЯЩО", + "coming_soon": "Очаквайте скоро", + "filmography_count": "Филмография • {{count}} заглавия", + "loading_filmography": "Зареждане на филмография...", + "load_more_remaining": "Зареди още ({{count}} оставащи)", + "alert_error_title": "Грешка", + "alert_error_message": "Неуспешно зареждане на \"{{title}}\". Моля, опитайте по-късно.", + "alert_ok": "ОК", + "no_upcoming": "Няма предстоящи заглавия за този актьор", + "no_content": "Няма налично съдържание за този актьор", + "no_movies": "Няма налични филми за този актьор", + "no_tv": "Няма налични ТВ сериали за този актьор" + }, + "comments": { + "title": "Trakt коментари", + "spoiler_warning": "⚠️ Този коментар съдържа спойлери. Докоснете за преглед.", + "spoiler": "Спойлер", + "contains_spoilers": "Съдържа спойлери", + "reveal": "Покажи", + "vip": "VIP", + "unavailable": "Коментарите са недостъпни", + "no_comments": "Все още няма коментари в Trakt", + "not_in_database": "Това съдържание може още да не е в базата на Trakt", + "check_trakt": "Провери в Trakt" + }, + "trailers": { + "title": "Трейлъри", + "official_trailers": "Официални трейлъри", + "official_trailer": "Официален трейлър", + "teasers": "Тийзъри", + "teaser": "Тийзър", + "clips_scenes": "Клипове и сцени", + "clip": "Клип", + "featurettes": "Кратки филми (Featurettes)", + "featurette": "Featurette", + "behind_the_scenes": "Зад кулисите", + "no_trailers": "Няма налични трейлъри", + "unavailable": "Трейлърът е недостъпен", + "unavailable_desc": "Този трейлър не може да бъде зареден в момента. Моля, опитайте по-късно.", + "unable_to_play": "Неуспешно пускане на трейлъра. Моля, опитайте пак.", + "watch_on_youtube": "Гледай в YouTube" + }, + "catalog": { + "no_content_found": "Няма намерено съдържание", + "no_content_filters": "Няма намерено съдържание за избраните филтри", + "loading_content": "Зареждане на съдържание...", + "back": "Назад", + "in_theaters": "В кината", + "all": "Всички", + "failed_tmdb": "Неуспешно зареждане на съдържание от TMDB", + "movies": "Филми", + "tv_shows": "ТВ сериали", + "channels": "Канали" + }, + "streams": { + "back_to_episodes": "Назад към епизодите", + "back_to_info": "Назад към информацията", + "fetching_from": "Извличане от:", + "no_sources_available": "Няма налични източници за стрийминг", + "add_sources_desc": "Моля, добавете източници в настройките", + "add_sources": "Добави източници", + "finding_streams": "Търсене на налични стриймове...", + "finding_best_stream": "Търсене на най-добрия стрийм за автоматично пускане...", + "still_fetching": "Все още се извличат стриймове...", + "no_streams_available": "Няма налични стриймове", + "starting_best_stream": "Стартиране на най-добрия стрийм...", + "loading_more_sources": "Зареждане на още източници..." + }, + "player_ui": { + "via": "чрез {{name}}", + "audio_tracks": "Аудио писти", + "no_audio_tracks": "Няма налични аудио писти", + "playback_speed": "Скорост на възпроизвеждане", + "on_hold": "На изчакване", + "playback_error": "Грешка при възпроизвеждане", + "unknown_error": "Възникна неизвестна грешка по време на възпроизвеждане.", + "copy_error": "Копирай детайлите за грешката", + "copied_to_clipboard": "Копирано в клипборда", + "dismiss": "Отхвърли", + "continue_watching": "Продължи гледането", + "start_over": "Започни отначало", + "resume": "Продължи", + "change_source": "Промени източника", + "switching_source": "Превключване на източника...", + "no_sources_found": "Няма намерени източници", + "sources": "Източници", + "finding_sources": "Търсене на източници...", + "unknown_source": "Неизвестен източник", + "sources_limited": "Източниците може да са ограничени поради грешки при доставчика.", + "episodes": "Епизоди", + "specials": "Специални", + "season": "Сезон {{season}}", + "stream": "Стрийм {{number}}", + "subtitles": "Субтитри", + "built_in": "Вградени", + "addons": "Добавки", + "style": "Стил", + "none": "Няма", + "search_online_subtitles": "Търси субтитри онлайн", + "preview": "Преглед", + "quick_presets": "Бързи настройки", + "default": "По подразбиране", + "yellow": "Жълто", + "high_contrast": "Висок контраст", + "large": "Големи", + "core": "Основни", + "font_size": "Размер на шрифта", + "show_background": "Покажи фон", + "advanced": "Разширени", + "position": "Позиция", + "text_color": "Цвят на текста", + "align": "Подравняване", + "bottom_offset": "Отместване отдолу", + "background_opacity": "Прозрачност на фона", + "text_shadow": "Сянка на текста", + "on": "Вкл.", + "off": "Изкл.", + "outline_color": "Цвят на контура", + "outline": "Контур", + "outline_width": "Ширина на контура", + "letter_spacing": "Разстояние между буквите", + "line_height": "Височина на реда", + "timing_offset": "Изместване на времето (s)", + "visual_sync": "Визуална синхронизация", + "timing_hint": "Преместете субтитрите по-рано (-) или по-късно (+), за да ги синхронизирате.", + "reset_defaults": "Възстанови настройките", + "mark_intro_start": "Маркирай начало на интро", + "mark_intro_end": "Маркирай край на интро", + "intro_start_marked": "Началото на интрото е маркирано", + "intro_submitted": "Интрото е изпратено успешно", + "intro_submit_failed": "Неуспешно изпращане на интро" + }, + "downloads": { + "title": "Изтегляния", + "no_downloads": "Все още няма изтегляния", + "no_downloads_desc": "Изтегленото съдържание ще се появи тук за гледане офлайн", + "explore": "Разгледай съдържание", + "path_copied": "Пътят е копиран", + "path_copied_desc": "Локалният път до файла е копиран в клипборда", + "copied": "Копирано", + "incomplete": "Незавършено изтегляне", + "incomplete_desc": "Изтеглянето все още не е завършено", + "not_available": "Не е достъпно", + "not_available_desc": "Локалният път до файла е достъпен само след приключване на изтеглянето.", + "status_downloading": "Изтегляне", + "status_completed": "Завършено", + "status_paused": "На пауза", + "status_error": "Грешка", + "status_queued": "На опашка", + "status_unknown": "Неизвестно", + "provider": "Доставчик", + "streaming_playlist_warning": "Може да не се възпроизведе - стрийминг плейлист", + "remaining": "остават", + "not_ready": "Изтеглянето не е готово", + "not_ready_desc": "Моля, изчакайте до завършване на изтеглянето.", + "filter_all": "Всички", + "filter_active": "Активни", + "filter_done": "Готови", + "filter_paused": "На пауза", + "no_filter_results": "Няма {{filter}} изтегляния", + "try_different_filter": "Опитайте да изберете друг филтър", + "limitations_title": "Ограничения при изтегляне", + "limitations_msg": "• Файлове под 1MB обикновено са M3U8 стрийминг плейлисти и не могат да бъдат изтеглени за гледане офлайн. Те работят само със стрийминг онлайн и съдържат връзки към видео сегменти, а не самото видео съдържание.", + "remove_title": "Премахни изтеглянето", + "remove_confirm": "Премахване на \"{{title}}\"{{season_episode}}?", + "cancel": "Отказ", + "remove": "Премахни" + }, + "addons": { + "title": "Добавки", + "reorder_mode": "Режим за пренареждане", + "reorder_info": "Добавките най-отгоре имат по-висок приоритет при зареждане на съдържание", + "add_addon_placeholder": "URL на добавка", + "add_button": "Добави добавка", + "my_addons": "Моите добавки", + "community_addons": "Добавки от общността", + "no_addons": "Няма инсталирани добавки", + "uninstall_title": "Деинсталирай добавка", + "uninstall_message": "Сигурни ли сте, че искате да деинсталирате {{name}}?", + "uninstall_button": "Деинсталирай", + "install_success": "Добавката е инсталирана успешно", + "install_error": "Неуспешно инсталиране на добавка", + "load_error": "Неуспешно зареждане на добавки", + "fetch_error": "Неуспешно извличане на детайли за добавката", + "invalid_url": "Моля, въведете URL на добавка", + "configure": "Конфигурирай", + "version": "Версия: {{version}}", + "installed_addons": "ИНСТАЛИРАНИ ДОБАВКИ", + "reorder_drag_title": "ПЛЪЗНЕТЕ ДОБАВКИТЕ ЗА ПРЕНАРЕЖДАНЕ", + "install": "Инсталирай", + "config_unavailable_title": "Конфигурацията е недостъпна", + "config_unavailable_msg": "Неуспешно определяне на URL адреса за конфигурация на тази добавка.", + "cannot_open_config_title": "Не може да се отвори конфигурацията", + "cannot_open_config_msg": "URL адресът за конфигурация ({{url}}) не може да бъде отворен. Добавката може да няма страница за конфигурация.", + "description": "Описание", + "supported_types": "Поддържани типове", + "catalogs": "Каталози", + "no_description": "Няма налично описание", + "overview": "ОБЗОР", + "no_categories": "Няма категории", + "pre_installed": "ПРЕДВАРИТЕЛНО ИНСТАЛИРАНИ" + }, + "trakt": { + "title": "Trakt настройки", + "settings_title": "Trakt настройки", + "connect_title": "Свързване с Trakt", + "connect_desc": "Синхронизирайте историята, списъка за гледане и колекцията си с Trakt.tv", + "sign_in": "Вписване с Trakt", + "sign_out": "Излизане", + "sign_out_confirm": "Сигурни ли сте, че искате да излезете от вашия Trakt профил?", + "joined": "Присъединил се на {{date}}", + "sync_settings_title": "Настройки за синхронизация", + "sync_info": "Когато сте свързани с Trakt, цялата история се синхронизира директно от API и не се записва в локалното хранилище. Вашият списък \"Продължи гледането\" отразява глобалния ви прогрес в Trakt.", + "auto_sync_label": "Автоматична синхронизация на прогреса", + "auto_sync_desc": "Автоматично синхронизиране на прогреса на гледане с Trakt", + "import_history_label": "Импортиране на историята на гледане", + "import_history_desc": "Използвайте \"Синхронизирай сега\", за да импортирате историята и прогреса си от Trakt", + "sync_now_button": "Синхронизирай сега", + "display_settings_title": "Настройки на дисплея", + "show_comments_label": "Покажи Trakt коментари", + "show_comments_desc": "Показване на Trakt коментари в екраните с метаданни, когато са налични", + "maintenance_title": "В процес на профилактика", + "maintenance_unavailable": "Trakt е недостъпен", + "maintenance_desc": "Интеграцията с Trakt временно е преустановена за профилактика. Цялата синхронизация и удостоверяване са деактивирани до приключване на профилактиката.", + "maintenance_button": "Услугата е в профилактика", + "auth_success_title": "Успешно свързване", + "auth_success_msg": "Вашият Trakt профил беше свързан успешно.", + "auth_error_title": "Грешка при удостоверяване", + "auth_error_msg": "Неуспешно завършване на удостоверяването с Trakt.", + "auth_error_generic": "Възникна грешка по време на удостоверяването.", + "sign_out_error": "Неуспешно излизане от Trakt.", + "sync_complete_title": "Синхронизацията завърши", + "sync_success_msg": "Успешно синхронизиран прогрес с Trakt.", + "sync_error_msg": "Синхронизацията не успя. Моля, опитайте отново." + }, + "simkl": { + "title": "Simkl настройки", + "settings_title": "Simkl настройки", + "connect_title": "Свързване със Simkl", + "connect_desc": "Синхронизирайте историята си и следете какво гледате", + "sign_in": "Вписване със Simkl", + "sign_out": "Прекъсване на връзката", + "sign_out_confirm": "Сигурни ли сте, че искате да прекъснете връзката със Simkl?", + "syncing_desc": "Вашите изгледани елементи се синхронизират със Simkl.", + "auth_success_title": "Успешно свързване", + "auth_success_msg": "Вашият Simkl профил беше свързан успешно.", + "auth_error_title": "Грешка при удостоверяване", + "auth_error_msg": "Неуспешно завършване на удостоверяването със Simkl.", + "auth_error_generic": "Възникна грешка по време на удостоверяването.", + "sign_out_error": "Неуспешно прекъсване на връзката със Simkl.", + "config_error_title": "Грешка в конфигурацията", + "config_error_msg": "Липсва Simkl Client ID в променливите на средата.", + "conflict_title": "Конфликт", + "conflict_msg": "Не можете да се свържете със Simkl, докато Trakt е свързан. Моля, първо прекъснете връзката с Trakt.", + "disclaimer": "Nuvio не е свързан със Simkl." + }, + "tmdb_settings": { + "title": "TMDb настройки", + "metadata_enrichment": "Обогатяване на метаданни", + "metadata_enrichment_desc": "Подобрете метаданните на съдържанието с данни от TMDb за по-добри детайли и информация.", + "enable_enrichment": "Активирай обогатяването", + "enable_enrichment_desc": "Допълва метаданните от добавките с данни от TMDb за актьорски състав, сертификация, лога/постери и продукция.", + "localized_text": "Локализиран текст", + "localized_text_desc": "Извличане на заглавия и описания на предпочитания от вас език от TMDb.", + "language": "Език", + "change": "Промени", + "logo_preview": "Преглед на лого", + "logo_preview_desc": "Прегледът показва как ще изглеждат локализираните лога на избрания език.", + "example": "Пример:", + "no_logo": "Няма налично лого", + "enrichment_options": "Опции за обогатяване", + "enrichment_options_desc": "Контролирайте какви данни да се извличат от TMDb. Деактивираните опции ще използват данни от добавката, ако са налични.", + "cast_crew": "Актьори и екип", + "cast_crew_desc": "Актьори, режисьори, сценаристи със снимки на профила", + "title_description": "Заглавие и описание", + "title_description_desc": "Използвай локализирано заглавие и обзорен текст от TMDb", + "title_logos": "Лога на заглавия", + "title_logos_desc": "Висококачествени изображения на лога на заглавия", + "banners_backdrops": "Банери и фонове", + "banners_backdrops_desc": "Изображения на фонове с висока резолюция", + "certification": "Сертификация на съдържанието", + "certification_desc": "Възрастови рейтинги (PG-13, R, TV-MA и др.)", + "recommendations": "Препоръки", + "recommendations_desc": "Предложения за подобно съдържание", + "episode_data": "Данни за епизоди", + "episode_data_desc": "Миниатюри на епизоди, инфо и резервни варианти за ТВ сериали", + "season_posters": "Постери на сезони", + "season_posters_desc": "Специфични за сезона изображения на постери", + "production_info": "Информация за продукцията", + "production_info_desc": "Мрежи и продуцентски компании с лога", + "movie_details": "Детайли за филма", + "movie_details_desc": "Бюджет, приходи, времетраене, слоган", + "tv_details": "Детайли за ТВ сериала", + "tv_details_desc": "Статус, брой сезони, мрежи, създатели", + "movie_collections": "Филмови колекции", + "movie_collections_desc": "Филми от франчайзи (Marvel, Star Wars и др.)", + "api_configuration": "API конфигурация", + "api_configuration_desc": "Конфигурирайте вашия TMDb API достъп за разширена функционалност.", + "custom_api_key": "Персонализиран API ключ", + "custom_api_key_desc": "Използвайте собствен TMDb API ключ за по-добра производителност и специални лимити.", + "custom_key_active": "Персонализираният API ключ е активен", + "api_key_required": "Изисква се API ключ", + "api_key_placeholder": "Поставете вашия TMDb API ключ (v3)", + "how_to_get_key": "Как да получа TMDb API ключ?", + "built_in_key_msg": "В момента се използва вграденият API ключ. Помислете за използване на собствен ключ за по-добра производителност.", + "cache_size": "Размер на кеша", + "clear_cache": "Изчисти кеша", + "cache_days": "Отговорите от TMDB се кешират за 7 дни за подобряване на производителността", + "choose_language": "Избери език", + "choose_language_desc": "Изберете предпочитания език за съдържанието от TMDb", + "popular": "Популярни", + "all_languages": "Всички езици", + "search_results": "Резултати от търсенето", + "no_languages_found": "Няма намерени езици за \"{{query}}\"", + "clear_search": "Изчисти търсенето", + "clear_cache_title": "Изчисти TMDB кеша", + "clear_cache_msg": "Това ще изчисти всички кеширани данни на TMDB ({{size}}). Това може временно да забави зареждането до възстановяване на кеша.", + "clear_cache_success": "Кешът на TMDB е изчистен успешно.", + "clear_cache_error": "Неуспешно изчистване на кеша.", + "clear_api_key_title": "Изчисти API ключа", + "clear_api_key_msg": "Сигурни ли сте, че искате да премахнете персонализирания си API ключ и да се върнете към оригиналния?", + "clear_api_key_success": "API ключът е изчистен успешно", + "clear_api_key_error": "Неуспешно изчистване на API ключа", + "empty_api_key": "API ключът не може да бъде празен.", + "invalid_api_key": "Невалиден API ключ. Моля, проверете и опитайте отново.", + "save_error": "Възникна грешка при запазването. Моля, опитайте отново.", + "using_builtin_key": "Сега се използва вграденият TMDb API ключ.", + "using_custom_key": "Сега се използва вашият персонализиран TMDb API ключ.", + "enter_custom_key": "Моля, въведете и запазете вашия персонализиран TMDb API ключ.", + "key_verified": "API ключът е потвърден и запазен успешно." + }, + "settings": { + "language": "Език", + "select_language": "Избери език", + "english": "Английски", + "portuguese": "Португалски", + "portuguese_br": "Португалски (Бразилия)", + "portuguese_pt": "Португалски (Португалия)", + "german": "Немски", + "arabic": "Арабски", + "spanish": "Испански", + "french": "Френски", + "italian": "Италиански", + "croatian": "Хърватски", + "chinese": "Китайски (Опростен)", + "hindi": "Хинди", + "serbian": "Сръбски", + "hebrew": "Иврит", + "bulgarian": "български", + "polish": "Полски", + "czech": "Чешки", + "turkish": "Турски", + "slovenian": "Словенски", + "macedonian": "Македонски", + "russian": "Руски", + "filipino": "Филипински", + "dutch_nl": "Нидерландски (Нидерландия)", + "romanian": "Румънски", + "albanian": "Албански", + "account": "Профил", + "content_discovery": "Съдържание и откриване", + "appearance": "Външен вид", + "integrations": "Интеграции", + "playback": "Възпроизвеждане", + "backup_restore": "Архивиране и възстановяване", + "updates": "Обновявания", + "about": "Относно", + "developer": "Разработчик", + "cache": "Кеш", + "title": "Настройки", + "settings_title": "Настройки", + "sign_in_sync": "Влез за синхронизиране", + "add_catalogs_sources": "Добавки, каталози и източници", + "player_trailers_downloads": "Плейър, трейлъри, изтегляния", + "mdblist_tmdb_ai": "MDBList, TMDB, AI", + "check_updates": "Провери за обновления", + "clear_mdblist_cache": "Изчисти MDBList кеша", + "cache_management": "УПРАВЛЕНИЕ НА КЕША", + "downloads_counter": "изтегляния и броене", + "made_with_love": "Направено с ❤️ от Tapframe и приятели", + "sections": { + "information": "ИНФОРМАЦИЯ", + "account": "ПРОФИЛ", + "theme": "ТЕМА", + "layout": "ОФОРМЛЕНИЕ", + "sources": "ИЗТОЧНИЦИ", + "catalogs": "КАТАЛОЗИ", + "discovery": "ОТКРИВАНЕ", + "metadata": "МЕТАДАННИ", + "ai_assistant": "AI АСИСТЕНТ", + "video_player": "ВИДЕО ПЛЕЙЪР", + "audio_subtitles": "АУДИО И СУБТИТРИ", + "media": "МЕДИЯ", + "notifications": "ИЗВЕСТИЯ", + "testing": "ТЕСТВАНЕ", + "danger_zone": "ОПАСНА ЗОНА" + }, + "items": { + "legal": "Правна информация", + "privacy_policy": "Политика за поверителност", + "report_issue": "Докладвай проблем", + "version": "Версия", + "contributors": "Сътрудници", + "view_contributors": "Виж всички сътрудници", + "theme": "Тема", + "episode_layout": "Оформление на епизодите", + "streams_backdrop": "Фон на стриймовете", + "streams_backdrop_desc": "Покажи замъглен фон при стриймове на мобилни устройства", + "addons": "Добавки", + "installed": "инсталирани", + "debrid_integration": "Debrid интеграция", + "debrid_desc": "Свържи Torbox", + "plugins": "Плъгини", + "plugins_desc": "Управление на плъгини и хранилища", + "catalogs": "Каталози", + "active": "активни", + "home_screen": "Начален екран", + "home_screen_desc": "Оформление и съдържание", + "continue_watching": "Продължи гледането", + "continue_watching_desc": "Поведение на кеша и възпроизвеждането", + "show_discover": "Покажи секция Откриване", + "show_discover_desc": "Показване на съдържание за откриване в Търсене", + "mdblist": "MDBList", + "mdblist_connected": "Свързан", + "mdblist_desc": "Активирайте за добавяне на рейтинги и ревюта", + "simkl": "Simkl", + "simkl_connected": "Свързан", + "simkl_desc": "Следете какво гледате", + "tmdb": "TMDB", + "tmdb_desc": "Доставчик на метаданни и лога", + "openrouter": "OpenRouter API", + "openrouter_connected": "Свързан", + "openrouter_desc": "Добавете API ключ за активиране на AI чат", + "video_player": "Видео плейър", + "built_in": "Вграден", + "external": "Външен", + "preferred_audio": "Предпочитан език на аудиото", + "preferred_subtitle": "Предпочитан език на субтитрите", + "subtitle_source": "Приоритет на източника на субтитри", + "auto_select_subs": "Автоматичен избор на субтитри", + "auto_select_subs_desc": "Автоматично избиране на субтитри според предпочитанията", + "show_trailers": "Покажи трейлъри", + "show_trailers_desc": "Показване на трейлъри в основната секция", + "enable_downloads": "Активирай изтеглянията", + "enable_downloads_desc": "Покажи раздел Изтегляния и разреши запазване на стриймове", + "notifications": "Известия", + "notifications_desc": "Напомняния за епизоди", + "developer_tools": "Инструменти за разработчици", + "developer_tools_desc": "Опции за тестване и дебъгване", + "test_onboarding": "Тествай запознаването", + "reset_onboarding": "Нулирай запознаването", + "test_announcement": "Тествай анонса", + "test_announcement_desc": "Покажи наслагването за новости", + "reset_campaigns": "Нулирай кампаниите", + "reset_campaigns_desc": "Изчисти импресиите от кампании", + "clear_all_data": "Изчисти всички данни", + "clear_all_data_desc": "Нулирай всички настройки и кеширани данни" + }, + "options": { + "horizontal": "Хоризонтално", + "vertical": "Вертикално", + "internal_first": "Първо вътрешни", + "internal_first_desc": "Предпочитане на вградени субтитри, след това външни", + "external_first": "Първо външни", + "external_first_desc": "Предпочитане на субтитри от добавки, след това вградени", + "any_available": "Всички налични", + "any_available_desc": "Използвай първата налична пътека за субтитри" + }, + "clear_data_desc": "Това ще нулира всички настройки и ще изчисти всички кеширани данни. Сигурни ли сте?", + "app_updates": "Обновявания на приложението", + "about_nuvio": "Относно Nuvio" + }, + "privacy": { + "title": "Поверителност и данни", + "settings_desc": "Контрол на телеметрията и събирането на данни", + "info_title": "Вашата поверителност е важна", + "info_description": "Контролирайте какви данни се събират и споделят. Анализите са изключени по подразбиране, а докладите за грешки са анонимни по подразбиране.", + "analytics_enabled_title": "Анализите са активирани", + "analytics_enabled_message": "Данните за употреба ще бъдат събирани, за да помогнат за подобряване на приложението. Можете да деактивирате това по всяко време.", + "disable_error_reporting_title": "Деактивиране на докладите за грешки?", + "disable_error_reporting_message": "Деактивирането на докладите за грешки означава, че няма да бъдем уведомявани за сривове или проблеми, които срещате. Това може да повлияе на способността ни да отстраняваме грешки.", + "enable_session_replay_title": "Активиране на запис на сесията?", + "enable_session_replay_message": "Записът на сесията записва вашия екран, когато възникнат грешки, за да ни помогне да разберем какво се е случило. Това може да улови видимо съдържание на вашия екран.", + "enable_pii_title": "Активиране на събирането на PII данни?", + "enable_pii_message": "Това позволява събирането на лично идентифицираща информация като IP адрес и детайли за устройството. Тези данни помагат за диагностициране на проблеми, но увеличават излагането на поверителността.", + "disable_all_title": "Деактивиране на цялата телеметрия?", + "disable_all_message": "Това ще деактивира всички анализи, доклади за грешки и записи на сесии. Няма да получаваме никакви данни за употребата на приложението или сривове.", + "disable_all_button": "Деактивирай всичко", + "all_disabled_title": "Цялата телеметрия е деактивирана", + "all_disabled_message": "Цялото събиране на данни е деактивирано. Промените влизат в сила при следващото стартиране на приложението.", + "reset_title": "Нулиране до препоръчителните", + "reset_message": "Настройките за поверителност бяха нулирани до препоръчителните по подразбиране (доклади за грешки активирани, анализи деактивирани).", + "section_analytics": "АНАЛИЗИ", + "analytics_title": "Анализи на употребата", + "analytics_description": "Събиране на анонимни модели на употреба и прегледи на екрани", + "section_error_reporting": "ДОКЛАДИ ЗА ГРЕШКИ", + "error_reporting_title": "Доклади за сривове", + "error_reporting_description": "Изпращане на анонимни доклади за сривове за подобряване на стабилността", + "session_replay_title": "Запис на сесия", + "session_replay_description": "Записване на екрана при възникване на грешки", + "pii_title": "Включи информация за устройството", + "pii_description": "Изпращане на IP адрес и детайли за устройството с докладите", + "section_quick_actions": "БЪРЗИ ДЕЙСТВИЯ", + "disable_all": "Деактивирай цялата телеметрия", + "disable_all_desc": "Изключи цялото събиране на данни", + "reset_recommended": "Нулиране до препоръчителните", + "reset_recommended_desc": "Настройки по подразбиране с фокус върху поверителността и доклади за грешки", + "section_learn_more": "НАУЧЕТЕ ПОВЕЧЕ", + "privacy_policy": "Политика за поверителност", + "current_settings": "Обобщение на текущите настройки", + "summary_analytics": "Анализи", + "summary_errors": "Доклади за грешки", + "summary_replay": "Запис на сесия", + "summary_pii": "Инфо за устройството", + "restart_note_detailed": "* Промените в анализите и докладите за грешки влизат в сила веднага. Настройките за запис на сесия и PII изискват рестартиране на приложението." + }, + "ai_settings": { + "title": "AI Асистент", + "info_title": "Чат, захранван от AI", + "info_desc": "Задавайте въпроси за всеки филм или епизод на сериал, използвайки напреднал AI. Получете информация за сюжета, героите, темите, любопитни факти и още - всичко това е захранвано от изчерпателни данни от TMDB.", + "feature_1": "Контекст и анализ за конкретен епизод", + "feature_2": "Обяснения на сюжета и прозрения за героите", + "feature_3": "Закулисни любопитни факти и факти", + "feature_4": "Ваш собствен безплатен OpenRouter API ключ", + "api_key_section": "OPENROUTER API КЛЮЧ", + "api_key_label": "API ключ", + "api_key_desc": "Въведете вашия OpenRouter API ключ, за да активирате функциите за AI чат", + "save_api_key": "Запази API ключа", + "saving": "Запазване...", + "update": "Обнови", + "remove": "Премахни", + "get_free_key": "Вземете безплатен API ключ от OpenRouter", + "enable_chat": "Активирай AI чат", + "enable_chat_desc": "Когато е активирано, бутонът „Питай AI“ ще се появи на страниците със съдържание.", + "chat_enabled": "AI чатът е активиран", + "chat_enabled_desc": "Вече можете да задавате въпроси за филми и сериали. Потърсете бутона „Питай AI“ на страниците със съдържание!", + "how_it_works": "Как работи", + "how_it_works_desc": "• OpenRouter осигурява достъп до множество AI модели\n• Вашият API ключ остава поверителен и защитен\n• Безплатният план включва щедри лимити за употреба\n• Чат с контекст за конкретни епизоди/филми\n• Получаване на детайлен анализ и обяснения", + "error_invalid_key": "Моля, въведете валиден API ключ", + "error_key_format": "API ключовете на OpenRouter трябва да започват с \"sk-or-\"", + "success_saved": "OpenRouter API ключът е запазен успешно!", + "error_save": "Неуспешно запазване на API ключа", + "confirm_remove_title": "Премахване на API ключ", + "confirm_remove_msg": "Сигурни ли сте, че искате да премахнете вашия OpenRouter API ключ? Това ще деактивира функциите за AI чат.", + "success_removed": "API ключът е премахнат успешно", + "error_remove": "Неуспешно премахване на API ключа" + }, + "catalog_settings": { + "title": "Каталози", + "layout_phone": "ОФОРМЛЕНИЕ НА КАТАЛОГА (ТЕЛЕФОН)", + "posters_per_row": "Постери на ред", + "auto": "Автоматично", + "show_titles": "Покажи заглавия на постери", + "show_titles_desc": "Показване на заглавието под всеки постер", + "phone_only_hint": "Прилага се само за телефони. Таблетите запазват адаптивно оформление.", + "catalogs_group": "Каталози", + "enabled_count": "{{enabled}} от {{total}} активирани", + "rename_hint": "Задръжте продължително върху каталог, за да го преименувате", + "rename_modal_title": "Преименуване на каталог", + "rename_placeholder": "Въведете ново име на каталога", + "error_save_name": "Името не можа да бъде запазено." + }, + "continue_watching_settings": { + "title": "Продължи гледането", + "playback_behavior": "ПОВЕДЕНИЕ ПРИ ВЪЗПРОИЗВЕЖДАНЕ", + "use_cached": "Използвай кеширани стриймове", + "use_cached_desc": "Когато е активирано, щракването върху елементи от „Продължи гледането“ ще отвори плейъра директно чрез предишно използвани стриймове. Когато е деактивирано, се отваря екран със съдържание.", + "open_metadata": "Отвори екран с метаданни", + "open_metadata_desc": "Когато кешираните стриймове са деактивирани, отвори екрана с метаданни вместо екрана със стриймове. Това показва детайли за съдържанието и позволява ръчен избор на стрийм.", + "card_appearance": "ВЪНШЕН ВИД НА КАРТАТА", + "card_style": "Стил на картата", + "card_style_desc": "Изберете как елементите от „Продължи гледането“ да се появяват на началния екран", + "wide": "Широка", + "poster": "Постер", + "cache_settings": "НАСТРОЙКИ НА КЕША", + "cache_duration": "Продължителност на кеша на стрийма", + "cache_duration_desc": "Колко дълго да се пазят кешираните връзки към стриймове преди да изтекат", + "important_note": "Важна бележка", + "important_note_text": "Не всички връзки към стриймове може да останат активни за пълната продължителност на кеша. По-дългото време може да доведе до изтекли връзки. Ако кеширана връзка не работи, приложението ще премине към извличане на нови стриймове.", + "how_it_works": "Как работи", + "how_it_works_cached": "• Стриймовете се кешират за избраната от вас продължителност след възпроизвеждане\n• Кешираните стриймове се проверяват преди употреба\n• Ако кешът е невалиден или изтекъл, се връща към екрана със съдържание\n• „Използвай кеширани стриймове“ контролира директния плейър срещу навигацията в екрана\n• „Отвори екран с метаданни“ се появява само когато кешираните стриймове са деактивирани", + "how_it_works_uncached": "• Когато кешираните стриймове са деактивирани, кликването върху елементи от „Продължи гледането“ отваря екрани със съдържание\n• Опцията „Отвори екран с метаданни“ контролира кой екран да се отвори\n• Екранът с метаданни показва детайли и позволява ръчен избор на стрийм\n• Екранът със стриймове показва наличните стриймове за незабавно възпроизвеждане", + "changes_saved": "Промените са запазени", + "min": "мин", + "hour": "час", + "hours": "часа" + }, + "contributors": { + "title": "Сътрудници", + "special_mentions": "Специални благодарности", + "tab_contributors": "Сътрудници", + "tab_special": "Специални", + "tab_donors": "Дарители", + "manager_role": "Мениджър на общността", + "manager_desc": "Управлява Discord и Reddit общностите за Nuvio", + "sponsor_role": "Спонсор на сървъра", + "sponsor_desc": "Спонсорира инфраструктурата на сървъра за Nuvio", + "mod_role": "Discord модератор", + "mod_desc": "Помага за модерирането на Nuvio Discord общността", + "loading": "Зареждане...", + "discord_user": "Discord потребител", + "contributions": "приноса", + "gratitude_title": "Благодарни сме за всеки принос", + "gratitude_desc": "Всеки ред код, доклад за грешка и предложение помага Nuvio да стане по-добър за всички", + "special_thanks_title": "Специални благодарности", + "special_thanks_desc": "Тези невероятни хора помагат на общността на Nuvio да работи и на сървърите да бъдат онлайн", + "donors_desc": "Благодарим ви, че вярвате в това, което градим. Вашата подкрепа поддържа Nuvio безплатен и постоянно подобряващ се.", + "latest_donations": "Последни", + "leaderboard": "Класация", + "loading_donors": "Зареждане на дарители...", + "no_donors": "Все още няма дарители", + "error_rate_limit": "Лимитът на GitHub API е превишен. Моля, опитайте по-късно.", + "error_failed": "Неуспешно зареждане на сътрудниците. Моля, проверете интернет връзката си.", + "retry": "Опитай отново", + "no_contributors": "Няма намерени сътрудници", + "loading_contributors": "Зареждане на сътрудници..." + }, + "debrid": { + "title": "Debrid Интеграция", + "description_torbox": "Отключете 4K висококачествени стриймове и светкавична скорост чрез интегриране на Torbox. Въведете вашия API ключ по-долу за незабавно подобрение.", + "description_torrentio": "Конфигурирайте Torrentio, за да получите торент стриймове за филми и сериали. Изисква се debrid услуга за стрийминг.", + "tab_torbox": "TorBox", + "tab_torrentio": "Torrentio", + "status_connected": "Свързан", + "status_disconnected": "Прекъснат", + "enable_addon": "Активирай добавката", + "disconnect_button": "Прекъсни връзката и премахни", + "disconnect_loading": "Прекъсване на връзката...", + "account_info": "Информация за профила", + "plan": "План", + "plan_free": "Безплатен", + "plan_essential": "Essential ($3/мес)", + "plan_pro": "Pro ($10/мес)", + "plan_standard": "Standard ($5/мес)", + "plan_unknown": "Неизвестен", + "expires": "Изтича на", + "downloaded": "Изтеглено", + "status_active": "Активен", + "connected_title": "✓ Свързан с TorBox", + "connected_desc": "Вашата добавка TorBox е активна и предоставя премиум стриймове.", + "configure_title": "Конфигурирай добавката", + "configure_desc": "Персонализирайте вашето изживяване. Сортиране по качество, филтриране по размер и други настройки.", + "open_settings": "Отвори настройките", + "what_is_debrid": "Какво е Debrid услуга?", + "enter_api_key": "Въведете вашия API ключ", + "connect_button": "Свържи и инсталирай", + "connecting": "Свързване...", + "unlock_speeds_title": "Отключете премиум скорости", + "unlock_speeds_desc": "Вземете абонамент за Torbox за достъп до кеширани стриймове с високо качество без буфериране.", + "get_subscription": "Вземи абонамент", + "powered_by": "Задвижвано от", + "disclaimer_torbox": "Nuvio не е свързан с Torbox по никакъв начин.", + "disclaimer_torrentio": "Nuvio не е свързан с Torrentio по никакъв начин.", + "installed_badge": "✓ ИНСТАЛИРАНО", + "promo_title": "⚡ Нуждаете се от Debrid услуга?", + "promo_desc": "Вземете TorBox за светкавичен 4K стрийминг без буфериране. Премиум кеширани торенти и незабавни изтегляния.", + "promo_button": "Вземи абонамент за TorBox", + "service_label": "Debrid услуга *", + "api_key_label": "API ключ *", + "sorting_label": "Сортиране", + "exclude_qualities": "Изключи качества", + "priority_languages": "Приоритетни езици", + "max_results": "Макс. резултати", + "additional_options": "Допълнителни опции", + "no_download_links": "Не показвай връзки за изтегляне", + "no_debrid_catalog": "Не показвай debrid каталог", + "install_button": "Инсталирай Torrentio", + "installing": "Инсталиране...", + "update_button": "Обнови конфигурацията", + "updating": "Обновяване...", + "remove_button": "Премахни Torrentio", + "error_api_required": "Изисква се API ключ", + "error_api_required_desc": "Моля, въведете вашия API ключ за debrid услугата, за да инсталирате Torrentio.", + "success_installed": "Добавката Torrentio е инсталирана успешно!", + "success_removed": "Добавката Torrentio е премахната успешно", + "alert_disconnect_title": "Прекъсване на Torbox", + "alert_disconnect_msg": "Сигурни ли сте, че искате да прекъснете връзката с Torbox? Това ще премахне добавката и изчисти API ключа." + }, + "home_screen": { + "title": "Настройки на началния екран", + "changes_applied": "Промените са приложени", + "display_options": "ОПЦИИ ЗА ДИСПЛЕЯ", + "show_hero": "Покажи секция „Hero“", + "show_hero_desc": "Предпочитано съдържание най-отгоре", + "show_this_week": "Покажи секция „Тази седмица“", + "show_this_week_desc": "Нови епизоди от текущата седмица", + "select_catalogs": "Избери каталози", + "all_catalogs": "Всички каталози", + "selected": "избрани", + "hero_layout": "Hero оформление", + "layout_legacy": "Класическо", + "layout_carousel": "Въртележка (Carousel)", + "layout_appletv": "Apple TV", + "layout_desc": "Банер на цял екран, плъзгащи се карти или стил Apple TV", + "featured_source": "Източник на акцентите", + "using_catalogs": "Използване на каталози", + "manage_selected_catalogs": "Управление на избраните каталози", + "dynamic_bg": "Динамичен Hero фон", + "dynamic_bg_desc": "Замъглен банер зад въртележката", + "performance_note": "Може да повлияе на производителността на по-слаби устройства.", + "posters": "Постери", + "show_titles": "Покажи заглавия", + "poster_size": "Размер на постера", + "poster_corners": "Ъгли на постера", + "size_small": "Малък", + "size_medium": "Среден", + "size_large": "Голям", + "corners_square": "Квадратни", + "corners_rounded": "Заоблени", + "corners_pill": "Тип хапче", + "about_these_settings": "ОТНОСНО ТЕЗИ НАСТРОЙКИ", + "about_desc": "Тези настройки контролират как се показва съдържанието на вашия начален екран. Промените се прилагат веднага.", + "hero_catalogs": { + "title": "Каталози за Hero секция", + "select_all": "Избери всички", + "clear_all": "Изчисти всички", + "info": "Изберете кои каталози да се показват в секцията hero. Ако нищо не е избрано, ще се използват всички. Не забравяйте да натиснете Запази.", + "settings_saved": "Настройките са запазени", + "error_load": "Неуспешно зареждане на каталозите", + "movies": "Филми", + "tv_shows": "ТВ сериали" + } + }, + "calendar": { + "title": "Календар", + "loading": "Зареждане на календара...", + "no_scheduled_episodes": "Няма насрочени епизоди", + "check_back_later": "Проверете отново по-късно", + "showing_episodes_for": "Показване на епизоди за {{date}}", + "show_all_episodes": "Покажи всички епизоди", + "no_episodes_for": "Няма епизоди за {{date}}", + "no_upcoming_found": "Няма намерени предстоящи епизоди", + "add_series_desc": "Добавете сериали в библиотеката си, за да виждате техните предстоящи епизоди тук" + }, + "mdblist": { + "title": "Източници на рейтинги", + "status_disabled": "MDBList е деактивиран", + "status_active": "API ключът е активен", + "status_required": "Изисква се API ключ", + "status_disabled_desc": "Функционалността на MDBList в момента е изключена.", + "status_active_desc": "Рейтингите от MDBList са активирани.", + "status_required_desc": "Добавете вашия ключ по-долу, за да активирате рейтингите.", + "enable_toggle": "Активирай MDBList", + "enable_toggle_desc": "Включи/изключи цялата функционалност на MDBList", + "api_section": "API ключ", + "placeholder": "Поставете вашия MDBList API ключ", + "save": "Запази", + "clear": "Изчисти ключа", + "rating_providers": "Доставчици на рейтинги", + "rating_providers_desc": "Изберете кои рейтинги да се показват в приложението", + "how_to": "Как да получа API ключ", + "step_1": "Влезте в", + "step_1_link": "уебсайта на MDBList", + "step_2": "Отидете в секция", + "step_2_settings": "Настройки", + "step_2_api": "API", + "step_2_end": ".", + "step_3": "Генерирайте нов ключ и го копирайте.", + "go_to_website": "Отиди в MDBList", + "alert_clear_title": "Изчистване на API ключ", + "alert_clear_msg": "Сигурни ли сте, че искате да премахнете запазения API ключ?", + "success_saved": "API ключът е запазен успешно.", + "error_empty": "API ключът не може да бъде празен.", + "error_save": "Възникна грешка при запазването. Моля, опитайте отново.", + "api_key_empty_error": "API ключът не може да бъде празен.", + "success_cleared": "API ключът е изчистен успешно", + "error_clear": "Неуспешно изчистване на API ключа" + }, + "notification": { + "title": "Настройки на известията", + "section_general": "Общи", + "enable_notifications": "Активирай известията", + "section_types": "Типове известия", + "new_episodes": "Нови епизоди", + "upcoming_shows": "Предстоящи сериали", + "reminders": "Напомняния", + "section_timing": "Време на известяване", + "timing_desc": "Кога да бъдете уведомени преди излъчването на епизод?", + "hours_1": "1 час", + "hours_suffix": "часа", + "section_status": "Статус на известията", + "stats_upcoming": "Предстоящи", + "stats_this_week": "Тази седмица", + "stats_total": "Общо", + "sync_button": "Синхронизирай Библиотека и Trakt", + "syncing": "Синхронизиране...", + "sync_desc": "Автоматично синхронизира известията за всички сериали във вашата библиотека и списъка за гледане на Trakt.", + "section_advanced": "Разширени", + "reset_button": "Нулирай всички известия", + "test_button": "Тестово известие (5 сек)", + "test_notification_in": "Известие след {{seconds}}с...", + "test_notification_text": "Известието ще се появи след {{seconds}} секунди", + "alert_reset_title": "Нулиране на известията", + "alert_reset_msg": "Това ще анулира всички насрочени известия, но няма да премахне нищо от библиотеката ви. Сигурни ли сте?", + "alert_reset_success": "Всички известия бяха нулирани", + "alert_sync_complete": "Синхронизацията приключи", + "alert_sync_msg": "Успешно синхронизирани известия за вашата библиотека и Trakt.\n\nНасрочени: {{upcoming}} предстоящи епизода\nТази седмица: {{thisWeek}} епизода", + "alert_test_scheduled": "Тестовото известие е насрочено да се появи веднага" + }, + "backup": { + "title": "Архивиране и възстановяване", + "options_title": "Опции за архивиране", + "options_desc": "Изберете какво да включите във вашите архиви", + "section_core": "Основни данни", + "section_addons": "Добавки и интеграции", + "section_settings": "Настройки и предпочитания", + "library_label": "Библиотека", + "library_desc": "Вашите запазени филми и сериали", + "watch_progress_label": "Прогрес на гледане", + "watch_progress_desc": "Позиции на продължаване на гледането", + "addons_label": "Добавки", + "addons_desc": "Инсталирани Stremio добавки", + "plugins_label": "Плъгини", + "plugins_desc": "Персонализирани конфигурации на търсачки", + "trakt_label": "Trakt интеграция", + "trakt_desc": "Синхронизиране на данни и токени за автентификация", + "app_settings_label": "Настройки на приложението", + "app_settings_desc": "Тема, предпочитания и конфигурации", + "user_prefs_label": "Потребителски предпочитания", + "user_prefs_desc": "Подредба на добавките и настройки на интерфейса", + "catalog_settings_label": "Настройки на каталога", + "catalog_settings_desc": "Филтри на каталога и предпочитания", + "api_keys_label": "API ключове", + "api_keys_desc": "Ключове за MDBList и OpenRouter", + "action_create": "Създай архив", + "action_restore": "Възстанови от архив", + "section_info": "Относно архивите", + "info_text": "• Персонализирайте какво да се архивира чрез превключвателите по-горе\n• Архивните файлове се съхраняват локално на вашето устройство\n• Споделете архива си, за да прехвърлите данни между устройства\n• Възстановяването ще презапише текущите ви данни", + "alert_create_title": "Създаване на архив", + "alert_no_content": "Няма избрано съдържание за архивиране.\n\nМоля, активирайте поне една опция в секцията за архивиране по-горе.", + "alert_backup_created_title": "Архивът е създаден", + "alert_backup_created_msg": "Вашият архив е създаден и е готов за споделяне.", + "alert_backup_failed_title": "Архивирането е неуспешно", + "alert_restore_confirm_title": "Потвърдете възстановяването", + "alert_restore_confirm_msg": "Това ще възстанови вашите данни от архив, създаден на {{date}}.\n\nТова действие ще презапише текущите ви данни. Сигурни ли сте, че искате да продължите?", + "alert_restore_complete_title": "Възстановяването приключи", + "alert_restore_complete_msg": "Вашите данни бяха успешно възстановени. Моля, рестартирайте приложението, за да видите промените.", + "alert_restore_failed_title": "Възстановяването е неуспешно", + "restart_app": "Рестартирай приложението", + "alert_restart_failed_title": "Рестартирането е неуспешно", + "alert_restart_failed_msg": "Неуспешно рестартиране на приложението. Моля, затворете и отворете приложението ръчно." + }, + "updates": { + "title": "Обновявания", + "status_checking": "Проверка за обновявания...", + "status_available": "Налично е обновяване!", + "status_downloading": "Изтегляне на обновяването...", + "status_installing": "Инсталиране на обновяването...", + "status_success": "Обновяването е инсталирано успешно!", + "status_error": "Обновяването е неуспешно", + "status_ready": "Готовност за проверка за обновявания", + "action_check": "Провери за обновявания", + "action_install": "Инсталирай обновяването", + "release_notes": "Бележки към версията:", + "version": "Версия:", + "last_checked": "Последна проверка:", + "current_version": "Текуща версия:", + "current_release_notes": "Текущи бележки към версията:", + "github_release": "GITHUB ВЕРСИЯ", + "current": "Текуща:", + "latest": "Най-нова:", + "notes": "Бележки:", + "view_release": "Виж версията", + "notification_settings": "НАСТРОЙКИ ЗА ИЗВЕСТИЯ", + "ota_alerts_label": "Известия за OTA обновявания", + "ota_alerts_desc": "Показвай известия за обновявания по въздуха", + "major_alerts_label": "Известия за големи обновявания", + "major_alerts_desc": "Показвай известия за нови версии на приложението в GitHub", + "alert_disable_ota_title": "Деактивиране на OTA известията?", + "alert_disable_ota_msg": "Вече няма да получавате автоматични известия за OTA обновявания.\n\n⚠️ Предупреждение: Поддържането на последната версия е важно за:\n• Поправки на грешки и стабилност\n• Нови функции и подобрения\n• Предоставяне на точни доклади за сривове", + "alert_disable_major_title": "Деактивиране на големите известия?", + "alert_disable_major_msg": "Вече няма да получавате известия за големи обновявания, които изискват преинсталация.\n\n⚠️ Предупреждение: Големите обновявания често включват:\n• Критични корекции по сигурността\n• Промени, изискващи преинсталиране\n• Важни корекции за съвместимост", + "warning_note": "Активираните известия гарантират, че получавате поправки и стабилност.", + "disable": "Деактивирай", + "alert_no_update_to_install": "Няма налично обновяване за инсталиране", + "alert_install_failed": "Неуспешно инсталиране на обновяването", + "alert_no_update_title": "Няма обновяване", + "alert_update_applied_msg": "Обновяването ще бъде приложено при следващото стартиране" + }, + "player": { + "title": "Видео плейър", + "section_selection": "ИЗБОР НА ПЛЕЙЪР", + "internal_title": "Вграден плейър", + "internal_desc": "Използвай плейъра по подразбиране на приложението", + "vlc_title": "VLC", + "vlc_desc": "Отвори стриймовете във VLC media player", + "infuse_title": "Infuse", + "infuse_desc": "Отвори стриймовете в Infuse плейър", + "outplayer_title": "OutPlayer", + "outplayer_desc": "Отвори стриймовете в OutPlayer", + "vidhub_title": "VidHub", + "vidhub_desc": "Отвори стриймовете в VidHub плейър", + "infuse_live_title": "Infuse Livecontainer", + "infuse_live_desc": "Отвори стриймовете в Infuse LiveContainer", + "external_title": "Външен плейър", + "external_desc": "Отвори стриймовете в предпочитания от вас плейър", + "section_playback": "ОПЦИИ ЗА ВЪЗПРОИЗВЕЖДАНЕ", + "skip_intro_settings_title": "Пропусни интро", + "powered_by_introdb": "Задвижвано от IntroDB", + "autoplay_title": "Автоматично пускане", + "autoplay_desc": "Автоматично стартиране на първия стрийм от списъка.", + "resume_title": "Винаги продължавай", + "resume_desc": "Пропусни запитването и автоматично продължи от там, където сте спрели (ако е изгледано под 85%).", + "engine_title": "Двигател на видео плейъра", + "engine_desc": "Auto използва ExoPlayer с MPV като резервен вариант. За най-добра съвместимост се препоръчва Auto.", + "decoder_title": "Режим на декодиране", + "decoder_desc": "Как се декодира видеото. Auto се препоръчва за най-добър баланс.", + "gpu_title": "GPU рендиране", + "gpu_desc": "GPU-Next предлага по-добро управление на HDR и цветовете.", + "external_downloads_title": "Външен плейър за изтегляния", + "external_downloads_desc": "Възпроизвеждай изтегленото съдържание във външен плейър.", + "restart_required": "Изисква се рестартиране", + "restart_msg_decoder": "Моля, рестартирайте за промяна на декодера.", + "restart_msg_gpu": "Моля, рестартирайте за промяна на GPU режима.", + "option_auto": "Автоматично", + "option_auto_desc_engine": "ExoPlayer + MPV резерва", + "option_mpv": "MPV", + "option_mpv_desc": "Само MPV", + "option_auto_desc_decoder": "Най-добър баланс", + "option_sw": "SW", + "option_sw_desc": "Софтуерно", + "option_hw": "HW", + "option_hw_desc": "Хардуерно", + "option_hw_plus": "HW+", + "option_hw_plus_desc": "Пълен HW", + "option_gpu_desc": "Стандартно", + "option_gpu_next_desc": "Разширено" + }, + "plugins": { + "title": "Плъгини", + "enable_title": "Активирай плъгините", + "enable_desc": "Активирай системата за плъгини за външни медийни източници", + "repo_config_title": "Конфигурация на хранилища", + "repo_config_desc": "Управлявайте външни хранилища за плъгини.", + "your_repos": "Хранилища", + "your_repos_desc": "Конфигурирайте външни източници.", + "add_repo_button": "Добави хранилище", + "refresh": "Обнови", + "remove": "Премахни", + "enabled": "Активирано", + "disabled": "Деактивирано", + "updating": "Обновяване...", + "success": "Успех", + "error": "Грешка", + "alert_repo_added": "Хранилището е добавено успешно", + "alert_repo_saved": "URL адресът на хранилището е запазен", + "alert_repo_refreshed": "Хранилището е обновено успешно", + "alert_invalid_url": "Невалиден формат на URL", + "alert_plugins_cleared": "Всички плъгини са премахнати", + "alert_cache_cleared": "Кешът на хранилището е изчистен", + "unknown": "Неизвестно", + "active": "Активен", + "available": "Наличен", + "platform_disabled": "Платформата е изключена", + "limited": "Ограничен", + "clear_all": "Изчисти всички плъгини", + "clear_all_desc": "Сигурни ли сте? Това действие е необратимо.", + "clear_cache": "Изчисти кеша на хранилищата", + "clear_cache_desc": "Това ще премахне запазените URL адреси и кеширани данни.", + "add_new_repo": "Добави ново хранилище", + "available_plugins": "Налични плъгини ({{count}})", + "placeholder": "Търсене на плъгини...", + "all": "Всички", + "filter_all": "Всички типове", + "filter_movies": "Филми", + "filter_tv": "Сериали", + "enable_all": "Активирай всички", + "disable_all": "Деактивирай всички", + "no_plugins_found": "Няма намерени плъгини", + "no_plugins_available": "Няма налични плъгини", + "no_match_desc": "Няма съвпадения за \"{{query}}\".", + "configure_repo_desc": "Конфигурирайте хранилище по-горе.", + "clear_search": "Изчисти търсенето", + "no_external_player": "Без външен плейър", + "showbox_token": "ShowBox UI Токен", + "showbox_placeholder": "Поставете вашия ShowBox UI токен", + "save": "Запази", + "clear": "Изчисти", + "additional_settings": "Допълнителни настройки", + "enable_url_validation": "Активирай валидация на URL", + "url_validation_desc": "Проверявай URL адресите за надеждност (може да забави резултатите)", + "group_streams": "Групирай източниците", + "group_streams_desc": "Източниците се групират по хранилище.", + "sort_quality": "Сортирай първо по качество", + "sort_quality_desc": "Само при активирано групиране.", + "show_logos": "Покажи лога на плъгините", + "show_logos_desc": "Показвай лога до медийните връзки.", + "quality_filtering": "Филтриране по качество", + "quality_filtering_desc": "Изключете конкретни резолюции от резултатите.", + "excluded_qualities": "Изключени качества:", + "language_filtering": "Филтриране по език", + "language_filtering_desc": "Изключете конкретни езици от резултатите.", + "note": "Забележка:", + "language_filtering_note": "Прилага се само за доставчици с езикова информация.", + "excluded_languages": "Изключени езици:", + "about_title": "Относно плъгините", + "about_desc_1": "Плъгините са модулни компоненти, които адаптират съдържание от външни протоколи.", + "about_desc_2": "Плъгините с етикет „Ограничен“ може да изискват външна конфигурация.", + "help_title": "Настройка на плъгини", + "help_step_1": "1. **Активиране** - Включете основния ключ", + "help_step_2": "2. **Добавяне** - Добавете валиден URL на хранилище", + "help_step_3": "3. **Обновяване** - Изтеглете наличните плъгини", + "help_step_4": "4. **Активиране** - Включете плъгините, които искате", + "got_it": "Разбрах!", + "repo_format_hint": "Формат: https://raw.githubusercontent.com/username/repo", + "cancel": "Отказ", + "add": "Добави" + }, + "theme": { + "title": "Теми", + "select_theme": "ИЗБЕРИ ТЕМА", + "create_custom": "Създай персонализирана тема", + "options": "ОПЦИИ", + "use_dominant_color": "Използвай доминиращ цвят от постера", + "categories": { + "all": "Всички теми", + "dark": "Тъмни теми", + "colorful": "Цветни", + "custom": "Моите теми" + }, + "editor": { + "theme_name_placeholder": "Име на темата", + "save": "Запази", + "primary": "Основен", + "secondary": "Вторичен", + "background": "Фон", + "invalid_name_title": "Невалидно име", + "invalid_name_msg": "Моля, въведете валидно име" + }, + "alerts": { + "delete_title": "Изтриване на тема", + "delete_msg": "Сигурни ли сте, че искате да изтриете \"{{name}}\"?", + "ok": "ОК", + "delete": "Изтрий", + "cancel": "Отказ", + "back": "Настройки" + } + }, + "legal": { + "title": "Правна информация", + "intro_title": "Естество на приложението", + "intro_text": "Nuvio е медиен плейър и приложение за управление на метаданни. То действа единствено като интерфейс за разглеждане на публично достъпни метаданни. Nuvio не хоства, не съхранява и не разпространява медийно съдържание.", + "extensions_title": "Плъгини от трети страни", + "extensions_text": "Тези плъгини се разработват от независими разработчици. Ние нямаме контрол върху тяхната законност или функционалност.", + "user_resp_title": "Отговорност на потребителя", + "user_resp_text": "Потребителите носят пълна отговорност за инсталираните плъгини и достъпваното съдържание.", + "dmca_title": "Авторски права и DMCA", + "dmca_text": "Ние уважаваме интелектуалната собственост. Тъй като Nuvio не хоства съдържание, не можем да премахваме такова от интернет.", + "warranty_title": "Без гаранция", + "warranty_text": "Софтуерът се предоставя „във вида, в който е“, без никакви гаранции." + }, + "plugin_tester": { + "title": "Тестер на плъгини", + "subtitle": "Стартирайте търсачки и следете лог файловете", + "tabs": { + "individual": "Индивидуален", + "repo": "Репо тестер", + "code": "Код", + "logs": "Логове", + "results": "Резултати" + }, + "common": { + "error": "Грешка", + "success": "Успех", + "movie": "Филм", + "tv": "Сериал", + "tmdb_id": "TMDB ID", + "season": "Сезон", + "episode": "Епизод", + "running": "Работи…", + "run_test": "Пусни тест", + "play": "Пусни", + "done": "Готово", + "test": "Тест", + "testing": "Тестване…" + }, + "individual": { + "load_from_url": "Зареди от URL", + "load_from_url_desc": "Поставете GitHub URL или локален IP.", + "enter_url_error": "Моля, въведете URL", + "code_loaded": "Кодът е зареден", + "fetch_error": "Грешка при извличане: {{message}}", + "no_code_error": "Няма код за изпълнение", + "plugin_code": "Код на плъгина", + "focus_editor": "Фокусирай редактора", + "code_placeholder": "// Поставете кода тук...", + "test_parameters": "Тестови параметри", + "no_logs": "Все още няма логове.", + "no_streams": "Няма намерени стриймове.", + "streams_found": "{{count}} намерен стрийм", + "streams_found_plural": "{{count}} намерени стрийма", + "tap_play_hint": "Натиснете Пусни за тест.", + "unnamed_stream": "Неименуван стрийм", + "quality": "Качество: {{quality}}", + "size": "Размер: {{size}}", + "url_label": "URL: {{url}}", + "headers_info": "Хедъри: {{count}} броя", + "find_placeholder": "Търси в кода…", + "edit_code_title": "Редактирай кода", + "no_url_stream_error": "Няма намерен URL за този стрийm" + }, + "repo": { + "title": "Репо тестер", + "description": "Тествайте всеки доставчик от хранилище.", + "enter_repo_url_error": "Моля, въведете URL на хранилище", + "invalid_url_title": "Невалиден URL", + "invalid_url_msg": "Използвайте GitHub raw URL или локален http(s).", + "manifest_build_error": "Неуспешно изграждане на манифест URL", + "manifest_fetch_error": "Неуспешно извличане на манифест", + "repo_manifest_fetch_error": "Грешка при извличане на манифест на хранилището", + "missing_filename": "Липсва име на файл в манифеста", + "scraper_build_error": "Неуспешно изграждане на URL на търсачка", + "download_scraper_error": "Неуспешно изтегляне на търсачка", + "test_failed": "Тестът е неуспешен", + "test_parameters": "Параметри за репо тест", + "test_parameters_desc": "Използват се само за Репо тестера.", + "using_info": "Използва се: {{mediaType}} • TMDB {{tmdbId}}", + "using_info_tv": "Използва се: {{mediaType}} • TMDB {{tmdbId}} • S{{season}}E{{episode}}", + "providers_title": "Доставчици", + "repository_default": "Хранилище", + "providers_count": "{{count}} доставчика", + "fetch_hint": "Извлечете репо за списък.", + "test_all": "Тествай всички", + "status_running": "РАБОТИ", + "status_ok": "ОК ({{count}})", + "status_ok_empty": "ОК (0)", + "status_failed": "ГРЕШКА", + "status_idle": "В ПОКОЙ", + "tried_url": "Опитано: {{url}}", + "provider_logs": "Логове на доставчика", + "no_logs_captured": "Няма уловени логове." + } + } +} \ No newline at end of file diff --git a/src/i18n/locales/cs.json b/src/i18n/locales/cs.json new file mode 100644 index 00000000..3b5675ef --- /dev/null +++ b/src/i18n/locales/cs.json @@ -0,0 +1,1420 @@ +{ + "common": { + "loading": "Načítání...", + "cancel": "Zrušit", + "save": "Uložit", + "delete": "Smazat", + "edit": "Upravit", + "search": "Hledat", + "error": "Chyba", + "success": "Úspěch", + "ok": "OK", + "unknown": "Neznámý", + "retry": "Zkusit znovu", + "try_again": "Zkusit znovu", + "go_back": "Zpět", + "settings": "Nastavení", + "close": "Zavřít", + "enable": "Povolit", + "disable": "Zakázat", + "show_more": "Zobrazit více", + "show_less": "Zobrazit méně", + "load_more": "Načíst další", + "unknown_date": "Neznámé datum", + "anonymous_user": "Anonymní uživatel", + "time": { + "now": "Právě teď", + "minutes_ago": "před {{count}} min", + "hours_ago": "před {{count}} h", + "days_ago": "před {{count}} d" + }, + "days_short": { + "sun": "Ne", + "mon": "Po", + "tue": "Út", + "wed": "St", + "thu": "Čt", + "fri": "Pá", + "sat": "So" + }, + "email": "E-mail", + "status": "Stav" + }, + "home": { + "categories": { + "movies": "Filmy", + "series": "Seriály", + "channels": "Kanály" + }, + "movies": "Filmy", + "tv_shows": "TV pořady", + "load_more_catalogs": "Načíst další katalogy", + "no_content": "Žádný obsah není k dispozici", + "add_catalogs": "Přidat katalogy", + "sign_in_available": "Možnost přihlášení", + "sign_in_desc": "Přihlásit se můžete kdykoli v Nastavení → Účet", + "view_all": "Zobrazit vše", + "this_week": "Tento týden", + "upcoming": "Nadcházející", + "recently_released": "Nedávno vydáno", + "no_scheduled_episodes": "Seriály bez naplánovaných epizod", + "check_back_later": "Zkuste to později", + "continue_watching": "Pokračovat ve sledování", + "up_next": "Další na řadě", + "up_next_caps": "DALŠÍ NA ŘADĚ", + "released": "Vydáno", + "new": "Nové", + "tba": "Bude oznámeno", + "new_episodes": "{{count}} nové epizody", + "season_short": "S{{season}}", + "episode_short": "E{{episode}}", + "season": "Série {{season}}", + "episode": "Epizoda {{episode}}", + "movie": "Film", + "series": "Seriál", + "tv_show": "TV pořad", + "percent_watched": "{{percent}} % zhlédnuto", + "view_details": "Zobrazit podrobnosti", + "remove": "Odebrat", + "play": "Přehrát", + "play_now": "Přehrát nyní", + "resume": "Pokračovat", + "info": "Info", + "more_info": "Více informací", + "my_list": "Můj seznam", + "save": "Uložit", + "saved": "Uloženo", + "retry": "Zkusit znovu", + "install_addons": "Instalovat doplňky", + "settings": "Nastavení", + "no_featured_content": "Žádný doporučený obsah", + "couldnt_load_featured": "Nepodařilo se načíst doporučený obsah", + "no_featured_desc": "Nainstalujte doplňky s katalogy nebo změňte zdroj obsahu v nastavení.", + "load_error_desc": "Při načítání doporučeného obsahu došlo k chybě. Zkontrolujte připojení a zkuste to znovu.", + "no_featured_available": "Žádný doporučený obsah není k dispozici", + "no_description": "Popis není k dispozici" + }, + "navigation": { + "home": "Domů", + "library": "Knihovna", + "search": "Hledat", + "downloads": "Stažené", + "settings": "Nastavení" + }, + "search": { + "title": "Hledat", + "recent_searches": "Nedávná hledání", + "discover": "Objevovat", + "movies": "Filmy", + "tv_shows": "TV pořady", + "select_catalog": "Vybrat katalog", + "all_genres": "Všechny žánry", + "discovering": "Vyhledávání obsahu...", + "show_more": "Zobrazit více ({{count}})", + "no_content_found": "Nebyl nalezen žádný obsah", + "try_different": "Zkuste jiný žánr nebo katalog", + "select_catalog_desc": "Vyberte katalog k objevování", + "tap_catalog_desc": "Začněte klepnutím na kartu katalogu výše", + "placeholder": "Hledat filmy, seriály...", + "keep_typing": "Pište dál...", + "type_characters": "Pro hledání zadejte alespoň 2 znaky", + "no_results": "Nebyly nalezeny žádné výsledky", + "try_keywords": "Zkuste jiná klíčová slova nebo zkontrolujte pravopis", + "select_type": "Vybrat typ", + "browse_movies": "Procházet katalogy filmů", + "browse_tv": "Procházet katalogy seriálů", + "select_genre": "Vybrat žánr", + "show_all_content": "Zobrazit veškerý obsah", + "genres_count": "{{count}} žánrů" + }, + "library": { + "title": "Knihovna", + "watched": "Zhlédnuto", + "continue": "Pokračovat", + "watchlist": "Seznam ke zhlédnutí", + "collection": "Sbírka", + "rated": "Hodnoceno", + "items": "položky", + "trakt_collections": "Trakt sbírky", + "trakt_collection": "Trakt sbírka", + "no_trakt": "Žádné sbírky na Trakt", + "no_trakt_desc": "Vaše Trakt sbírky se zde zobrazí, jakmile začnete Trakt používat", + "load_collections": "Načíst sbírky", + "empty_folder": "Žádný obsah v {{folder}}", + "empty_folder_desc": "Tato sbírka je prázdná", + "refresh": "Obnovit", + "no_movies": "Zatím žádné filmy", + "no_series": "Zatím žádné TV pořady", + "no_content": "Zatím žádný obsah", + "add_content_desc": "Přidejte obsah do své knihovny, abyste jej zde viděli", + "find_something": "Najděte si něco ke zhlédnutí", + "removed_from_library": "Odebráno z knihovny", + "item_removed": "Položka byla odebrána z vaší knihovny", + "failed_update_library": "Nepodařilo se aktualizovat knihovnu", + "unable_remove": "Nepodařilo se odebrat položku z knihovny", + "marked_watched": "Označeno jako zhlédnuté", + "marked_unwatched": "Označeno jako nezhlédnuté", + "item_marked_watched": "Položka označena jako zhlédnutá", + "item_marked_unwatched": "Položka označena jako nezhlédnutá", + "failed_update_watched": "Nepodařilo se aktualizovat stav zhlédnutí", + "unable_update_watched": "Nelze aktualizovat stav zhlédnutí", + "added_to_library": "Přidáno do knihovny", + "item_added": "Přidáno do vaší místní knihovny", + "add_to_library": "Přidat do knihovny", + "remove_from_library": "Odebrat z knihovny", + "mark_watched": "Označit jako zhlédnuté", + "mark_unwatched": "Označit jako nezhlédnuté", + "share": "Sdílet", + "add_to_watchlist": "Přidat do Trakt seznamu", + "remove_from_watchlist": "Odebrat z Trakt seznamu", + "added_to_watchlist": "Přidáno do seznamu ke zhlédnutí", + "added_to_watchlist_desc": "Přidáno do vašeho Trakt seznamu", + "removed_from_watchlist": "Odebráno ze seznamu ke zhlédnutí", + "removed_from_watchlist_desc": "Odebráno z vašeho Trakt seznamu", + "add_to_collection": "Přidat do Trakt sbírky", + "remove_from_collection": "Odebrat z Trakt sbírky", + "added_to_collection": "Přidáno do sbírky", + "added_to_collection_desc": "Přidáno do vaší Trakt sbírky", + "removed_from_collection": "Odebráno ze sbírky", + "removed_from_collection_desc": "Odebráno z vaší Trakt sbírky" + }, + "metadata": { + "unable_to_load": "Nelze načíst obsah", + "error_code": "Kód chyby: {{code}}", + "content_not_found": "Obsah nebyl nalezen", + "content_not_found_desc": "Tento obsah neexistuje nebo mohl být odebrán.", + "server_error": "Chyba serveru", + "server_error_desc": "Server je dočasně nedostupný. Zkuste to prosím později.", + "bad_gateway": "Chybná brána", + "bad_gateway_desc": "Server má potíže. Zkuste to prosím později.", + "service_unavailable": "Služba nedostupná", + "service_unavailable_desc": "Služba je momentálně mimo provoz kvůli údržbě.", + "too_many_requests": "Příliš mnoho požadavků", + "too_many_requests_desc": "Provádíte příliš mnoho požadavků. Počkejte chvíli a zkuste to znovu.", + "request_timeout": "Časový limit vypršel", + "request_timeout_desc": "Požadavek trval příliš dlouho. Zkuste to znovu.", + "network_error": "Chyba sítě", + "network_error_desc": "Zkontrolujte připojení k internetu a zkuste to znovu.", + "auth_error": "Chyba autentizace", + "auth_error_desc": "Zkontrolujte nastavení účtu a zkuste to znovu.", + "access_denied": "Přístup odepřen", + "access_denied_desc": "Nemáte oprávnění k přístupu k tomuto obsahu.", + "connection_error": "Chyba připojení", + "streams_unavailable": "Streamy nedostupné", + "streams_unavailable_desc": "Zdroje streamování jsou momentálně nedostupné.", + "unknown_error": "Neznámá chyba", + "something_went_wrong": "Něco se pokazilo. Zkuste to znovu.", + "cast": "Obsazení", + "more_like_this": "Podobné", + "episodes": "Epizody", + "seasons": "Série", + "posters": "Plakáty", + "banners": "Bannery", + "specials": "Speciály", + "season_number": "Série {{number}}", + "episode_count": "{{count}} Epizoda", + "episode_count_plural": "{{count}} Epizody", + "no_episodes": "Žádné epizody nejsou k dispozici", + "no_episodes_for_season": "Pro sérii {{season}} nejsou k dispozici žádné epizody", + "episodes_not_released": "Epizody možná ještě nebyly vydány", + "episode_label": "EPIZODA {{number}}", + "watch_again": "Zhlédnout znovu", + "completed": "Dokončeno", + "play_episode": "Přehrát S{{season}}E{{episode}}", + "play": "Přehrát", + "watched": "Zhlédnuto", + "watched_on_trakt": "Zhlédnuto na Trakt", + "synced_with_trakt": "Synchronizováno s Trakt", + "director": "Režisér", + "directors": "Režiséři", + "creator": "Tvůrce", + "creators": "Tvůrci", + "production": "Produkce", + "network": "Stanice", + "marking": "Označování...", + "removing": "Odstraňování...", + "unmark_season": "Zrušit označení série {{season}}", + "mark_season": "Označit sérii {{season}}", + "resume": "Pokračovat", + "spoiler_warning": "Varování: Spoiler", + "spoiler_warning_desc": "Tento komentář obsahuje spoilery. Opravdu jej chcete odkrýt?", + "reveal_spoilers": "Odkrýt spoilery", + "movie_details": "Detaily filmu", + "show_details": "Detaily pořadu", + "tagline": "Slogan", + "release_date": "Datum vydání", + "runtime": "Délka", + "budget": "Rozpočet", + "revenue": "Tržby", + "origin_country": "Země původu", + "original_language": "Původní jazyk", + "first_air_date": "První vysílání", + "last_air_date": "Poslední vysílání", + "total_episodes": "Celkem epizod", + "episode_runtime": "Délka epizody", + "created_by": "Vytvořil", + "backdrop_gallery": "Galerie pozadí", + "loading_episodes": "Načítání epizod...", + "play_next": "Hrát S{{season}}E{{episode}}", + "play_next_episode": "Hrát další epizodu", + "percent_watched_trakt": "{{percent}} % zhlédnuto ({{traktPercent}} % na Trakt)", + "synced_with_trakt_progress": "Synchronizováno s Trakt", + "using_trakt_progress": "Používá se postup z Trakt", + "added_to_collection_hero": "Přidáno do sbírky", + "added_to_collection_desc_hero": "Přidáno do vaší Trakt sbírky", + "removed_from_collection_hero": "Odebráno ze sbírky", + "removed_from_collection_desc_hero": "Odebráno z vaší Trakt sbírky", + "mark_as_watched": "Označit jako zhlédnuté", + "mark_as_unwatched": "Označit jako nezhlédnuté" + }, + "cast": { + "biography": "Biografie", + "known_for": "Známý z", + "personal_info": "Osobní informace", + "born_in": "Narozen v {{place}}", + "filmography": "Filmografie", + "also_known_as": "Také známý jako", + "no_info_available": "Nejsou k dispozici žádné další informace", + "as_character": "jako {{character}}", + "loading_details": "Načítání detailů...", + "years_old": "{{age}} let", + "view_filmography": "Zobrazit filmografii", + "filter": "Filtr", + "sort_by": "Seřadit podle", + "sort_popular": "Populární", + "sort_latest": "Nejnovější", + "sort_upcoming": "Chystané", + "upcoming_badge": "CHYSTANÉ", + "coming_soon": "Již brzy", + "filmography_count": "Filmografie • {{count}} titulů", + "loading_filmography": "Načítání filmografie...", + "load_more_remaining": "Načíst další (zbývá {{count}})", + "alert_error_title": "Chyba", + "alert_error_message": "Nelze načíst \"{{title}}\". Zkuste to prosím později.", + "alert_ok": "OK", + "no_upcoming": "Pro tohoto herce nejsou k dispozici žádné chystané tituly", + "no_content": "Pro tohoto herce není k dispozici žádný obsah", + "no_movies": "Pro tohoto herce nejsou k dispozici žádné filmy", + "no_tv": "Pro tohoto herce nejsou k dispozici žádné TV pořady" + }, + "comments": { + "title": "Komentáře Trakt", + "spoiler_warning": "⚠️ Tento komentář obsahuje spoilery. Klepnutím odhalíte.", + "spoiler": "Spoiler", + "contains_spoilers": "Obsahuje spoilery", + "reveal": "Odhalit", + "vip": "VIP", + "unavailable": "Komentáře nejsou k dispozici", + "no_comments": "Na Trakt zatím nejsou žádné komentáře", + "not_in_database": "Tento obsah možná ještě není v databázi Trakt", + "check_trakt": "Zkontrolovat Trakt" + }, + "trailers": { + "title": "Trailery", + "official_trailers": "Oficiální trailery", + "official_trailer": "Oficiální trailer", + "teasers": "Teasery", + "teaser": "Teaser", + "clips_scenes": "Klipy a scény", + "clip": "Klip", + "featurettes": "Featuretty", + "featurette": "Featuretta", + "behind_the_scenes": "Ze zákulisí", + "no_trailers": "Nejsou k dispozici žádné trailery", + "unavailable": "Trailer nedostupný", + "unavailable_desc": "Tento trailer se nepodařilo načíst. Zkuste to prosím později.", + "unable_to_play": "Trailer nelze přehrát. Zkuste to znovu.", + "watch_on_youtube": "Sledovat na YouTube" + }, + "catalog": { + "no_content_found": "Nebyl nalezen žádný obsah", + "no_content_filters": "Pro vybrané filtry nebyl nalezen žádný obsah", + "loading_content": "Načítání obsahu...", + "back": "Zpět", + "in_theaters": "V kinech", + "all": "Vše", + "failed_tmdb": "Nepodařilo se načíst obsah z TMDB", + "movies": "Filmy", + "tv_shows": "TV pořady", + "channels": "Kanály" + }, + "streams": { + "back_to_episodes": "Zpět k epizodám", + "back_to_info": "Zpět na info", + "fetching_from": "Získávání z:", + "no_sources_available": "Nejsou k dispozici žádné zdroje streamování", + "add_sources_desc": "Přidejte zdroje streamování v nastavení", + "add_sources": "Přidat zdroje", + "finding_streams": "Hledání dostupných streamů...", + "finding_best_stream": "Hledání nejlepšího streamu pro automatické přehrávání...", + "still_fetching": "Stále vyhledávám streamy...", + "no_streams_available": "Žádné streamy nejsou k dispozici", + "starting_best_stream": "Spouštění nejlepšího streamu...", + "loading_more_sources": "Načítání dalších zdrojů..." + }, + "player_ui": { + "via": "přes {{name}}", + "audio_tracks": "Zvukové stopy", + "no_audio_tracks": "Nejsou k dispozici žádné zvukové stopy", + "playback_speed": "Rychlost přehrávání", + "on_hold": "Pozastaveno", + "playback_error": "Chyba přehrávání", + "unknown_error": "Během přehrávání došlo k neznámé chybě.", + "copy_error": "Kopírovat detaily chyby", + "copied_to_clipboard": "Zkopírováno do schránky", + "dismiss": "Zavřít", + "continue_watching": "Pokračovat ve sledování", + "start_over": "Přehrát od začátku", + "resume": "Pokračovat", + "change_source": "Změnit zdroj", + "switching_source": "Přepínání zdroje...", + "no_sources_found": "Nebyly nalezeny žádné zdroje", + "sources": "Zdroje", + "finding_sources": "Hledání zdrojů...", + "unknown_source": "Neznámý zdroj", + "sources_limited": "Zdroje mohou být omezeny kvůli chybám poskytovatele.", + "episodes": "Epizody", + "specials": "Speciály", + "season": "Série {{season}}", + "stream": "Stream {{number}}", + "subtitles": "Titulky", + "built_in": "Vestavěné", + "addons": "Doplňky", + "style": "Styl", + "none": "Žádné", + "search_online_subtitles": "Hledat titulky online", + "preview": "Náhled", + "quick_presets": "Rychlé předvolby", + "default": "Výchozí", + "yellow": "Žlutá", + "high_contrast": "Vysoký kontrast", + "large": "Velké", + "core": "Základní", + "font_size": "Velikost písma", + "show_background": "Zobrazit pozadí", + "advanced": "Pokročilé", + "position": "Pozice", + "text_color": "Barva textu", + "align": "Zarovnání", + "bottom_offset": "Odsazení zdola", + "background_opacity": "Průhlednost pozadí", + "text_shadow": "Stín textu", + "on": "Zapnuto", + "off": "Vypnuto", + "outline_color": "Barva obrysu", + "outline": "Obrys", + "outline_width": "Šířka obrysu", + "letter_spacing": "Prokládání písma", + "line_height": "Výška řádku", + "timing_offset": "Časový posun (s)", + "visual_sync": "Vizuální synchronizace", + "timing_hint": "Pokud je potřeba, posuňte titulky dříve (-) nebo později (+) pro synchronizaci.", + "reset_defaults": "Obnovit výchozí", + "mark_intro_start": "Označit začátek znělky", + "mark_intro_end": "Označit konec znělky", + "intro_start_marked": "Začátek znělky označen", + "intro_submitted": "Znělka úspěšně odeslána", + "intro_submit_failed": "Odeslání znělky se nezdařilo" + }, + "downloads": { + "title": "Stažené", + "no_downloads": "Zatím žádné stažené soubory", + "no_downloads_desc": "Stažený obsah se zde zobrazí pro offline sledování", + "explore": "Prozkoumat obsah", + "path_copied": "Cesta zkopírována", + "path_copied_desc": "Cesta k místnímu souboru byla zkopírována", + "copied": "Zkopírováno", + "incomplete": "Stahování nedokončeno", + "incomplete_desc": "Stahování ještě není dokončeno", + "not_available": "Není k dispozici", + "not_available_desc": "Cesta k místnímu souboru je k dispozici až po dokončení stahování.", + "status_downloading": "Stahování", + "status_completed": "Dokončeno", + "status_paused": "Pozastaveno", + "status_error": "Chyba", + "status_queued": "Ve frontě", + "status_unknown": "Neznámý", + "provider": "Poskytovatel", + "streaming_playlist_warning": "Nemusí jít přehrát - streamovací playlist", + "remaining": "zbývá", + "not_ready": "Stahování není připraveno", + "not_ready_desc": "Počkejte prosím na dokončení stahování.", + "filter_all": "Vše", + "filter_active": "Aktivní", + "filter_done": "Hotovo", + "filter_paused": "Pozastaveno", + "no_filter_results": "Žádná stahování typu {{filter}}", + "try_different_filter": "Zkuste vybrat jiný filtr", + "limitations_title": "Omezení stahování", + "limitations_msg": "• Soubory menší než 1 MB jsou obvykle streamovací playlisty M3U8 a nelze je stáhnout pro offline sledování. Ty fungují pouze s online streamováním a obsahují odkazy na video segmenty, nikoli skutečný video obsah.", + "remove_title": "Odstranit stažený soubor", + "remove_confirm": "Odstranit \"{{title}}\"{{season_episode}}?", + "cancel": "Zrušit", + "remove": "Odstranit" + }, + "addons": { + "title": "Doplňky", + "reorder_mode": "Režim řazení", + "reorder_info": "Doplňky nahoře mají vyšší prioritu při načítání obsahu", + "add_addon_placeholder": "URL doplňku", + "add_button": "Přidat doplněk", + "my_addons": "Moje doplňky", + "community_addons": "Komunitní doplňky", + "no_addons": "Nejsou nainstalovány žádné doplňky", + "uninstall_title": "Odinstalovat doplněk", + "uninstall_message": "Opravdu chcete odinstalovat {{name}}?", + "uninstall_button": "Odinstalovat", + "install_success": "Doplněk byl úspěšně nainstalován", + "install_error": "Instalace doplňku se nezdařila", + "load_error": "Nepodařilo se načíst doplňky", + "fetch_error": "Nepodařilo se načíst podrobnosti o doplňku", + "invalid_url": "Zadejte prosím URL doplňku", + "configure": "Konfigurovat", + "version": "Verze: {{version}}", + "installed_addons": "NAINSTALOVANÉ DOPLŇKY", + "reorder_drag_title": "TAŽENÍM ZMĚŇTE POŘADÍ", + "install": "Instalovat", + "config_unavailable_title": "Konfigurace nedostupná", + "config_unavailable_msg": "Nepodařilo se určit konfigurační URL pro tento doplněk.", + "cannot_open_config_title": "Nelze otevřít konfiguraci", + "cannot_open_config_msg": "Konfigurační URL ({{url}}) nelze otevřít. Doplněk nemusí mít konfigurační stránku.", + "description": "Popis", + "supported_types": "Podporované typy", + "catalogs": "Katalogy", + "no_description": "Popis není k dispozici", + "overview": "PŘEHLED", + "no_categories": "Žádné kategorie", + "pre_installed": "PŘEDINSTALOVÁNO" + }, + "trakt": { + "title": "Nastavení Trakt", + "settings_title": "Nastavení Trakt", + "connect_title": "Propojit s Trakt", + "connect_desc": "Synchronizujte historii sledování, seznam ke zhlédnutí a sbírku s Trakt.tv", + "sign_in": "Přihlásit se k Trakt", + "sign_out": "Odhlásit se", + "sign_out_confirm": "Opravdu se chcete odhlásit ze svého Trakt účtu?", + "joined": "Připojen(a) {{date}}", + "sync_settings_title": "Nastavení synchronizace", + "sync_info": "Při propojení s Trakt se celá historie synchronizuje přímo z API a neukládá se do místního úložiště. Váš seznam 'Pokračovat ve sledování' odráží váš globální postup na Trakt.", + "auto_sync_label": "Automatická synchronizace postupu", + "auto_sync_desc": "Automaticky synchronizovat postup sledování na Trakt", + "import_history_label": "Importovat historii sledování", + "import_history_desc": "Použijte 'Synchronizovat nyní' pro import historie a postupu z Trakt", + "sync_now_button": "Synchronizovat nyní", + "display_settings_title": "Nastavení zobrazení", + "show_comments_label": "Zobrazit komentáře Trakt", + "show_comments_desc": "Zobrazit komentáře z Trakt v detailech obsahu, pokud jsou k dispozici", + "maintenance_title": "Probíhá údržba", + "maintenance_unavailable": "Trakt je nedostupný", + "maintenance_desc": "Integrace Trakt je dočasně pozastavena kvůli údržbě. Veškerá synchronizace a autentizace je vypnuta.", + "maintenance_button": "Služba v údržbě", + "auth_success_title": "Úspěšně připojeno", + "auth_success_msg": "Váš Trakt účet byl úspěšně připojen.", + "auth_error_title": "Chyba autentizace", + "auth_error_msg": "Nepodařilo se dokončit autentizaci s Trakt.", + "auth_error_generic": "Během autentizace došlo k chybě.", + "sign_out_error": "Nepodařilo se odhlásit z Trakt.", + "sync_complete_title": "Synchronizace dokončena", + "sync_success_msg": "Váš postup sledování byl úspěšně synchronizován s Trakt.", + "sync_error_msg": "Synchronizace se nezdařila. Zkuste to prosím znovu." + }, + "simkl": { + "title": "Nastavení Simkl", + "settings_title": "Nastavení Simkl", + "connect_title": "Propojit s Simkl", + "connect_desc": "Synchronizujte historii sledování a sledujte, co právě sledujete", + "sign_in": "Přihlásit se k Simkl", + "sign_out": "Odpojit", + "sign_out_confirm": "Opravdu se chcete odpojit od Simkl?", + "syncing_desc": "Vaše zhlédnuté položky se synchronizují s Simkl.", + "auth_success_title": "Úspěšně připojeno", + "auth_success_msg": "Váš Simkl účet byl úspěšně připojen.", + "auth_error_title": "Chyba autentizace", + "auth_error_msg": "Nepodařilo se dokončit autentizaci s Simkl.", + "auth_error_generic": "Během autentizace došlo k chybě.", + "sign_out_error": "Nepodařilo se odpojit od Simkl.", + "config_error_title": "Chyba konfigurace", + "config_error_msg": "Simkl Client ID chybí v proměnných prostředí.", + "conflict_title": "Konflikt", + "conflict_msg": "Nemůžete se připojit k Simkl, dokud je připojen Trakt. Nejprve odpojte Trakt.", + "disclaimer": "Nuvio není přidruženo k Simkl." + }, + "tmdb_settings": { + "title": "Nastavení TMDb", + "metadata_enrichment": "Obohacení metapodat", + "metadata_enrichment_desc": "Vylepšete metapodaty o data z TMDb pro lepší detaily a informace.", + "enable_enrichment": "Povolit obohacení", + "enable_enrichment_desc": "Doplňuje metapodaty z doplňků o TMDb data pro obsazení, certifikaci, loga a produkční info.", + "localized_text": "Lokalizovaný text", + "localized_text_desc": "Načítat názvy a popisy v preferovaném jazyce z TMDb.", + "language": "Jazyk", + "change": "Změnit", + "logo_preview": "Náhled loga", + "logo_preview_desc": "Náhled ukazuje, jak se budou lokalizovaná loga zobrazovat ve vybraném jazyce.", + "example": "Příklad:", + "no_logo": "Logo není k dispozici", + "enrichment_options": "Možnosti obohacení", + "enrichment_options_desc": "Nastavte, která data se mají z TMDb načítat. Vypnuté možnosti použijí data z doplňku.", + "cast_crew": "Obsazení a štáb", + "cast_crew_desc": "Herci, režiséři, scénáristé s profilovými fotkami", + "title_description": "Název a popis", + "title_description_desc": "Použít lokalizovaný název a přehled z TMDb", + "title_logos": "Loga titulů", + "title_logos_desc": "Vysoce kvalitní obrázky s názvy titulů", + "banners_backdrops": "Bannery a pozadí", + "banners_backdrops_desc": "Obrázky pozadí ve vysokém rozlišení", + "certification": "Certifikace obsahu", + "certification_desc": "Věkové hodnocení (PG-13, R, TV-MA atd.)", + "recommendations": "Doporučení", + "recommendations_desc": "Návrhy podobného obsahu", + "episode_data": "Data epizod", + "episode_data_desc": "Náhledy epizod, info a záložní data pro seriály", + "season_posters": "Plakáty sérií", + "season_posters_desc": "Plakáty specifické pro jednotlivé série", + "production_info": "Produkční info", + "production_info_desc": "Stanice a produkční společnosti s logy", + "movie_details": "Detaily filmu", + "movie_details_desc": "Rozpočet, tržby, délka, slogan", + "tv_details": "Detaily seriálu", + "tv_details_desc": "Stav, počet sérií, stanice, tvůrci", + "movie_collections": "Filmové sbírky", + "movie_collections_desc": "Filmové franšízy (Marvel, Star Wars atd.)", + "api_configuration": "Konfigurace API", + "api_configuration_desc": "Nakonfigurujte svůj přístup k TMDb API pro vylepšené funkce.", + "custom_api_key": "Vlastní API klíč", + "custom_api_key_desc": "Použijte vlastní TMDb API klíč pro lepší výkon a vyhrazené limity.", + "custom_key_active": "Vlastní API klíč je aktivní", + "api_key_required": "API klíč je vyžadován", + "api_key_placeholder": "Vložte svůj TMDb API klíč (v3)", + "how_to_get_key": "Jak získat TMDb API klíč?", + "built_in_key_msg": "Aktuálně používáte vestavěný API klíč. Zvažte použití vlastního klíče pro lepší výkon.", + "cache_size": "Velikost mezipaměti", + "clear_cache": "Vymazat mezipaměť", + "cache_days": "Odezvy TMDB jsou uloženy v mezipaměti po dobu 7 dní pro zvýšení výkonu", + "choose_language": "Vybrat jazyk", + "choose_language_desc": "Vyberte preferovaný jazyk pro obsah z TMDb", + "popular": "Populární", + "all_languages": "Všechny jazyky", + "search_results": "Výsledky hledání", + "no_languages_found": "Pro dotaz \"{{query}}\" nebyly nalezeny žádné jazyky", + "clear_search": "Vymazat hledání", + "clear_cache_title": "Vymazat TMDB mezipaměť", + "clear_cache_msg": "Tímto vymažete všechna uložená data TMDB ({{size}}). To může dočasně zpomalit načítání, dokud se mezipaměť neobnoví.", + "clear_cache_success": "Mezipaměť TMDB byla úspěšně vymazána.", + "clear_cache_error": "Nepodařilo se vymazat mezipaměť.", + "clear_api_key_title": "Vymazat API klíč", + "clear_api_key_msg": "Opravdu chcete odebrat svůj vlastní API klíč a vrátit se k výchozímu?", + "clear_api_key_success": "API klíč byl úspěšně vymazán", + "clear_api_key_error": "Nepodařilo se vymazat API klíč", + "empty_api_key": "API klíč nemůže být prázdný.", + "invalid_api_key": "Neplatný API klíč. Zkontrolujte jej a zkuste to znovu.", + "save_error": "Při ukládání došlo k chybě. Zkuste to znovu.", + "using_builtin_key": "Nyní používáte vestavěný TMDb API klíč.", + "using_custom_key": "Nyní používáte svůj vlastní TMDb API klíč.", + "enter_custom_key": "Zadejte a uložte svůj vlastní TMDb API klíč.", + "key_verified": "API klíč byl úspěšně ověřen a uložen." + }, + "settings": { + "language": "Jazyk", + "select_language": "Vybrat jazyk", + "english": "Angličtina", + "portuguese": "Portugalština", + "portuguese_br": "Portugalština (Brazílie)", + "portuguese_pt": "Portugalština (Portugalsko)", + "german": "Němčina", + "arabic": "Arabština", + "spanish": "Španělština", + "french": "Francouzština", + "italian": "Italština", + "croatian": "Chorvatština", + "chinese": "Čínština (Zjednodušená)", + "hindi": "Hindština", + "serbian": "Srbština", + "hebrew": "Hebrejština", + "bulgarian": "Bulharština", + "polish": "Polština", + "czech": "Čeština", + "turkish": "Turečtina", + "slovenian": "Slovinština", + "macedonian": "Makedonský", + "russian": "Ruština", + "filipino": "Filipínština", + "dutch_nl": "Nizozemština (Nizozemsko)", + "romanian": "Rumanština", + "albanian": "Albánština", + "account": "Účet", + "content_discovery": "Obsah a objevování", + "appearance": "Vzhled", + "integrations": "Integrace", + "playback": "Přehrávání", + "backup_restore": "Záloha a obnovení", + "updates": "Aktualizace", + "about": "O aplikaci", + "developer": "Vývojář", + "cache": "Mezipaměť", + "title": "Nastavení", + "settings_title": "Nastavení", + "sign_in_sync": "Přihlaste se pro synchronizaci", + "add_catalogs_sources": "Doplňky, katalogy a zdroje", + "player_trailers_downloads": "Přehrávač, trailery, stahování", + "mdblist_tmdb_ai": "MDBList, TMDB, AI", + "check_updates": "Zkontrolovat aktualizace", + "clear_mdblist_cache": "Vymazat mezipaměť MDBList", + "cache_management": "SPRÁVA MEZIPAMĚTI", + "downloads_counter": "stažení a přibývají", + "made_with_love": "Vytvořeno s ❤️ týmem Tapframe a přáteli", + "sections": { + "information": "INFORMACE", + "account": "ÚČET", + "theme": "MOTIV", + "layout": "ROZVRŽENÍ", + "sources": "ZDROJE", + "catalogs": "KATALOGY", + "discovery": "OBJEVOVÁNÍ", + "metadata": "METADATA", + "ai_assistant": "AI ASISTENT", + "video_player": "VIDEO PŘEHRÁVAČ", + "audio_subtitles": "AUDIO A TITULKY", + "media": "MÉDIA", + "notifications": "NOTIFIKACE", + "testing": "TESTOVÁNÍ", + "danger_zone": "NEBEZPEČNÁ ZÓNA" + }, + "items": { + "legal": "Právní informace", + "privacy_policy": "Zásady ochrany osobních údajů", + "report_issue": "Nahlásit problém", + "version": "Verze", + "contributors": "Přispěvatelé", + "view_contributors": "Zobrazit všechny přispěvatele", + "theme": "Motiv", + "episode_layout": "Rozvržení epizod", + "streams_backdrop": "Pozadí streamů", + "streams_backdrop_desc": "Zobrazit rozmazané pozadí u mobilních streamů", + "addons": "Doplňky", + "installed": "nainstalováno", + "debrid_integration": "Integrace Debrid", + "debrid_desc": "Připojit Torbox", + "plugins": "Pluginy", + "plugins_desc": "Spravovat pluginy a repozitáře", + "catalogs": "Katalogy", + "active": "aktivní", + "home_screen": "Domovská obrazovka", + "home_screen_desc": "Rozvržení a obsah", + "continue_watching": "Pokračovat ve sledování", + "continue_watching_desc": "Mezipaměť a chování při přehrávání", + "show_discover": "Zobrazit sekci Objevovat", + "show_discover_desc": "Zobrazit obsah k objevování v Hledání", + "mdblist": "MDBList", + "mdblist_connected": "Připojeno", + "mdblist_desc": "Povolit pro přidání hodnocení a recenzí", + "simkl": "Simkl", + "simkl_connected": "Připojeno", + "simkl_desc": "Sledujte, co sledujete", + "tmdb": "TMDB", + "tmdb_desc": "Zdroj metapodat a log", + "openrouter": "OpenRouter API", + "openrouter_connected": "Připojeno", + "openrouter_desc": "Přidejte svůj API klíč pro povolení AI chatu", + "video_player": "Video přehrávač", + "built_in": "Vestavěný", + "external": "Externí", + "preferred_audio": "Preferovaný jazyk zvuku", + "preferred_subtitle": "Preferovaný jazyk titulků", + "subtitle_source": "Priorita zdroje titulků", + "auto_select_subs": "Automaticky vybrat titulky", + "auto_select_subs_desc": "Automaticky vybrat titulky odpovídající vašim preferencím", + "show_trailers": "Zobrazit trailery", + "show_trailers_desc": "Zobrazit trailery v hlavní sekci", + "enable_downloads": "Povolit stahování", + "enable_downloads_desc": "Zobrazit kartu Stahování i možnost ukládání streamů", + "notifications": "Notifikace", + "notifications_desc": "Připomenutí epizod", + "developer_tools": "Vývojářské nástroje", + "developer_tools_desc": "Možnosti testování a ladění", + "test_onboarding": "Testovat uvítání", + "reset_onboarding": "Resetovat uvítání", + "test_announcement": "Testovat oznámení", + "test_announcement_desc": "Zobrazit překryvnou vrstvu 'Co je nového'", + "reset_campaigns": "Resetovat kampaně", + "reset_campaigns_desc": "Vymazat imprese kampaní", + "clear_all_data": "Vymazat všechna data", + "clear_all_data_desc": "Resetovat všechna nastavení a smazat data v mezipaměti" + }, + "options": { + "horizontal": "Horizontální", + "vertical": "Vertikální", + "internal_first": "Nejdříve interní", + "internal_first_desc": "Preferovat vestavěné titulky, poté externí", + "external_first": "Nejdříve externí", + "external_first_desc": "Preferovat titulky z doplňků, poté vestavěné", + "any_available": "Jakékoli dostupné", + "any_available_desc": "Použít první dostupnou stopu titulků" + }, + "clear_data_desc": "Tímto dojde k resetování všech nastavení a vymazání všech dat v mezipaměti. Jste si jisti?", + "app_updates": "Aktualizace aplikace", + "about_nuvio": "O aplikaci Nuvio" + }, + "privacy": { + "title": "Soukromí a data", + "settings_desc": "Ovládání telemetrie a sběru dat", + "info_title": "Na vašem soukromí záleží", + "info_description": "Mějte pod kontrolou, jaká data jsou sbírána a sdílena. Analytika je ve výchozím nastavení vypnutá a hlášení o chybách jsou anonymní.", + "analytics_enabled_title": "Analytika povolena", + "analytics_enabled_message": "Data o používání budou sbírána pro zlepšení aplikace. Toto můžete kdykoli vypnout.", + "disable_error_reporting_title": "Vypnout hlášení chyb?", + "disable_error_reporting_message": "Vypnutím hlášení o chybách nebudeme upozorněni na pády nebo problémy, které zaznamenáte. To může ovlivnit naši schopnost opravovat chyby.", + "enable_session_replay_title": "Povolit záznam relace?", + "enable_session_replay_message": "Záznam relace nahrává obrazovku při výskytu chyby, abychom pochopili, co se stalo. Může zachytit viditelný obsah na vaší obrazovce.", + "enable_pii_title": "Povolit sběr PII?", + "enable_pii_message": "Toto umožňuje sběr osobně identifikovatelných informací, jako je IP adresa a detaily o zařízení. Tato data pomáhají diagnostikovat problémy, ale zvyšují expozici soukromí.", + "disable_all_title": "Vypnout veškerou telemetrii?", + "disable_all_message": "Tímto vypnete veškerou analytiku, hlášení chyb i záznamy relací. Nebudeme dostávat žádná data o používání nebo pádech aplikace.", + "disable_all_button": "Vypnout vše", + "all_disabled_title": "Veškerá telemetrie vypnuta", + "all_disabled_message": "Veškerý sběr dat byl vypnut. Změny se projeví při příštím restartu aplikace.", + "reset_title": "Resetovat na doporučené", + "reset_message": "Nastavení soukromí byla resetována na doporučené výchozí hodnoty (hlášení chyb povoleno, analytika vypnuta).", + "section_analytics": "ANALYTIKA", + "analytics_title": "Analytika používání", + "analytics_description": "Sbírat anonymní vzorce používání a zobrazení obrazovek", + "section_error_reporting": "HLÁŠENÍ CHYB", + "error_reporting_title": "Hlášení o pádech", + "error_reporting_description": "Odesílat anonymní hlášení o pádech pro zlepšení stability", + "session_replay_title": "Záznam relace", + "session_replay_description": "Nahrávat obrazovku při výskytu chyb", + "pii_title": "Zahrnout info o zařízení", + "pii_description": "Odesílat IP adresu a detaily o zařízení spolu s hlášeními", + "section_quick_actions": "RYCHLÉ AKCE", + "disable_all": "Vypnout veškerou telemetrii", + "disable_all_desc": "Vypnout veškerý sběr dat", + "reset_recommended": "Resetovat na doporučené", + "reset_recommended_desc": "Soukromí na prvním místě s hlášením chyb", + "section_learn_more": "ZJISTIT VÍCE", + "privacy_policy": "Zásady ochrany osobních údajů", + "current_settings": "Shrnutí aktuálního nastavení", + "summary_analytics": "Analytika", + "summary_errors": "Hlášení chyb", + "summary_replay": "Záznam relace", + "summary_pii": "Info o zařízení", + "restart_note_detailed": "* Změny analytiky a hlášení chyb se projeví okamžitě. Nastavení záznamu relace a PII vyžaduje restart aplikace." + }, + "ai_settings": { + "title": "AI Asistent", + "info_title": "Chat s podporou AI", + "info_desc": "Ptejte se na cokoli ohledně jakéhokoli filmu nebo epizody seriálu pomocí pokročilé AI. Získejte vhled do děje, postav, témat, zajímavostí a dalšího - vše poháněno komplexními daty z TMDB.", + "feature_1": "Kontext a analýza specifická pro danou epizodu", + "feature_2": "Vysvětlení děje a vhled do postav", + "feature_3": "Zajímavosti ze zákulisí a fakta", + "feature_4": "Váš vlastní bezplatný API klíč OpenRouter", + "api_key_section": "OPENROUTER API KLÍČ", + "api_key_label": "API klíč", + "api_key_desc": "Zadejte svůj OpenRouter API klíč pro povolení funkcí AI chatu", + "save_api_key": "Uložit API klíč", + "saving": "Ukládání...", + "update": "Aktualizovat", + "remove": "Odebrat", + "get_free_key": "Získat zdarma API klíč od OpenRouter", + "enable_chat": "Povolit AI chat", + "enable_chat_desc": "Po zapnutí se na stránkách s obsahem zobrazí tlačítko 'Poptat se AI'.", + "chat_enabled": "AI chat povolen", + "chat_enabled_desc": "Nyní se můžete ptát na filmy a seriály. Hledejte tlačítko 'Poptat se AI' na stránkách s obsahem!", + "how_it_works": "Jak to funguje", + "how_it_works_desc": "• OpenRouter poskytuje přístup k mnoha modelům AI\n• Váš API klíč zůstává soukromý a v bezpečí\n• Bezplatná úroveň zahrnuje štědré limity používání\n• Chatujte s kontextem o konkrétních epizodách/filmech\n• Získejte detailní analýzu a vysvětlení", + "error_invalid_key": "Zadejte prosím platný API klíč", + "error_key_format": "OpenRouter API klíče by měly začínat na 'sk-or-'", + "success_saved": "API klíč OpenRouter byl úspěšně uložen!", + "error_save": "Nepodařilo se uložit API klíč", + "confirm_remove_title": "Odebrat API klíč", + "confirm_remove_msg": "Opravdu chcete odebrat svůj OpenRouter API klíč? Tím se vypnou funkce AI chatu.", + "success_removed": "API klíč byl úspěšně odebrán", + "error_remove": "Nepodařilo se odebrat API klíč" + }, + "catalog_settings": { + "title": "Katalogy", + "layout_phone": "ROZVRŽENÍ KATALOGU (TELEFON)", + "posters_per_row": "Plakátů na řádek", + "auto": "Auto", + "show_titles": "Zobrazit názvy u plakátů", + "show_titles_desc": "Zobrazit text názvu pod každým plakátem", + "phone_only_hint": "Platí pouze pro telefony. Tablety si ponechávají adaptivní rozvržení.", + "catalogs_group": "Katalogy", + "enabled_count": "{{enabled}} z {{total}} povoleno", + "rename_hint": "Dlouhým stisknutím katalog přejmenujete", + "rename_modal_title": "Přejmenovat katalog", + "rename_placeholder": "Zadejte nový název katalogu", + "error_save_name": "Nepodařilo se uložit vlastní název." + }, + "continue_watching_settings": { + "title": "Pokračovat ve sledování", + "playback_behavior": "CHOVÁNÍ PŘI PŘEHRÁVÁNÍ", + "use_cached": "Používat streamy z mezipaměti", + "use_cached_desc": "Pokud je povoleno, kliknutím na položky v 'Pokračovat ve sledování' se přímo otevře přehrávač s použitím dříve přehrávaných streamů. Pokud je vypnuto, otevře se obrazovka s obsahem.", + "open_metadata": "Otevřít obrazovku metapodat", + "open_metadata_desc": "Pokud jsou streamy z mezipaměti vypnuty, otevře se obrazovka Metadat namísto obrazovky Streamů. To zobrazí detaily obsahu a umožní manuální výběr streamu.", + "card_appearance": "VZHLED KARTY", + "card_style": "Styl karty", + "card_style_desc": "Vyberte, jak se mají položky v 'Pokračovat ve sledování' zobrazovat na domovské obrazovce", + "wide": "Široká", + "poster": "Plakát", + "cache_settings": "NASTAVENÍ MEZIPAMĚTI", + "cache_duration": "Doba uložení streamu v mezipaměti", + "cache_duration_desc": "Jak dlouho uchovávat odkazy na streamy v mezipaměti, než vyprší", + "important_note": "Důležitá poznámka", + "important_note_text": "Ne všechny odkazy na streamy musí zůstat aktivní po celou dobu uložení v mezipaměti. Delší doba může vést k nefunkčním odkazům. Pokud odkaz z mezipaměti selže, aplikace se vrátí k načítání čerstvých streamů.", + "how_it_works": "Jak to funguje", + "how_it_works_cached": "• Streamy jsou po přehrání uloženy do mezipaměti na vámi zvolenou dobu\n• Streamy v mezipaměti jsou před použitím ověřeny\n• Pokud je mezipaměť neplatná nebo vypršela, aplikace se vrátí na obrazovku obsahu\n• 'Používat streamy z mezipaměti' ovládá navigaci (přímo přehrávač vs. obrazovka)\n• 'Otevřít obrazovku metapodat' se zobrazí pouze při vypnutí streamů z mezipaměti", + "how_it_works_uncached": "• Když jsou streamy z mezipaměti vypnuty, kliknutí na 'Pokračovat ve sledování' otevře obrazovku obsahu\n• Možnost 'Otevřít obrazovku metapodat' určuje, která obrazovka se otevře\n• Obrazovka metapodat ukazuje detaily a dovoluje ruční výběr\n• Obrazovka streamů ukazuje dostupné zdroje pro okamžité přehrání", + "changes_saved": "Změny uloženy", + "min": "min", + "hour": "hodina", + "hours": "hodin" + }, + "contributors": { + "title": "Přispěvatelé", + "special_mentions": "Zvláštní uznání", + "tab_contributors": "Přispěvatelé", + "tab_special": "Zvláštní uznání", + "tab_donors": "Dárci", + "manager_role": "Komunitní manažer", + "manager_desc": "Spravuje komunity Discord a Reddit pro Nuvio", + "sponsor_role": "Sponzor serveru", + "sponsor_desc": "Sponzoroval serverovou infrastrukturu pro Nuvio", + "mod_role": "Discord moderátor", + "mod_desc": "Pomáhá moderovat komunitu Nuvio na Discordu", + "loading": "Načítání...", + "discord_user": "Uživatel Discordu", + "contributions": "příspěvků", + "gratitude_title": "Jsme vděční za každý příspěvek", + "gratitude_desc": "Každý řádek kódu, nahlášení chyby a návrh pomáhá dělat Nuvio lepším pro všechny", + "special_thanks_title": "Zvláštní poděkování", + "special_thanks_desc": "Tito úžasní lidé pomáhají udržovat komunitu Nuvio v chodu a servery online", + "donors_desc": "Děkujeme, že věříte v to, co stavíme. Vaše podpora udržuje Nuvio zdarma a umožňuje nám se neustále zlepšovat.", + "latest_donations": "Nejnovější", + "leaderboard": "Žebříček", + "loading_donors": "Načítání dárců...", + "no_donors": "Zatím žádní dárci", + "error_rate_limit": "Limit požadavků GitHub API byl překročen. Zkuste to prosím později nebo obnovte stažením dolů.", + "error_failed": "Nepodařilo se načíst přispěvatele. Zkontrolujte prosím připojení k internetu.", + "retry": "Zkusit znovu", + "no_contributors": "Nebyli nalezeni žádní přispěvatelé", + "loading_contributors": "Načítání přispěvatelů..." + }, + "debrid": { + "title": "Integrace Debrid", + "description_torbox": "Odemkněte 4K streamy ve vysoké kvalitě a bleskovou rychlost integrací Torboxu. Zadejte svůj API klíč níže a okamžitě vylepšete svůj zážitek ze sledování.", + "description_torrentio": "Nakonfigurujte Torrentio pro získávání torrentových streamů pro filmy a seriály. Pro streamování obsahu je vyžadována služba debrid.", + "tab_torbox": "TorBox", + "tab_torrentio": "Torrentio", + "status_connected": "Připojeno", + "status_disconnected": "Odpojeno", + "enable_addon": "Povolit doplněk", + "disconnect_button": "Odpojit a odebrat", + "disconnect_loading": "Odpojování...", + "account_info": "Informace o účtu", + "plan": "Tarif", + "plan_free": "Zdarma", + "plan_essential": "Essential ($3/měsíc)", + "plan_pro": "Pro ($10/měsíc)", + "plan_standard": "Standard ($5/měsíc)", + "plan_unknown": "Neznámý", + "expires": "Vyprší", + "downloaded": "Staženo", + "status_active": "Aktivní", + "connected_title": "✓ Připojeno k TorBoxu", + "connected_desc": "Váš doplněk TorBox je aktivní a poskytuje prémiové streamy.", + "configure_title": "Konfigurovat doplněk", + "configure_desc": "Přizpůsobte si zážitek ze sledování. Řaďte podle kvality, filtrujte velikosti souborů a spravujte další nastavení integrace.", + "open_settings": "Otevřít nastavení", + "what_is_debrid": "Co je to služba Debrid?", + "enter_api_key": "Zadejte svůj API klíč", + "connect_button": "Připojit a instalovat", + "connecting": "Připojování...", + "unlock_speeds_title": "Odemkněte prémiové rychlosti", + "unlock_speeds_desc": "Získejte předplatné Torbox pro přístup k cachovaným streamům ve vysoké kvalitě bez načítání.", + "get_subscription": "Získat předplatné", + "powered_by": "Poháněno", + "disclaimer_torbox": "Nuvio není žádným způsobem spojeno s Torboxem.", + "disclaimer_torrentio": "Nuvio není žádným způsobem spojeno s Torrentio.", + "installed_badge": "✓ NAINSTALOVÁNO", + "promo_title": "⚡ Potřebujete službu Debrid?", + "promo_desc": "Získejte TorBox pro bleskové 4K streamování bez sekání. Prémiové cachované torrenty a okamžité stahování.", + "promo_button": "Získat předplatné TorBox", + "service_label": "Debrid služba *", + "api_key_label": "API klíč *", + "sorting_label": "Řazení", + "exclude_qualities": "Vyloučit kvality", + "priority_languages": "Prioritní jazyky", + "max_results": "Max. výsledků", + "additional_options": "Další možnosti", + "no_download_links": "Nezobrazovat odkazy ke stažení", + "no_debrid_catalog": "Nezobrazovat debrid katalog", + "install_button": "Instalovat Torrentio", + "installing": "Instalace...", + "update_button": "Aktualizovat konfiguraci", + "updating": "Aktualizace...", + "remove_button": "Odebrat Torrentio", + "error_api_required": "API klíč je vyžadován", + "error_api_required_desc": "Pro instalaci Torrentio zadejte prosím API klíč své debrid služby.", + "success_installed": "Doplněk Torrentio byl úspěšně nainstalován!", + "success_removed": "Doplněk Torrentio byl úspěšně odebrán", + "alert_disconnect_title": "Odpojit Torbox", + "alert_disconnect_msg": "Opravdu chcete odpojit Torbox? Tímto dojde k odebrání doplňku a vymazání vašeho uloženého API klíče." + }, + "home_screen": { + "title": "Nastavení domovské obrazovky", + "changes_applied": "Změny byly aplikovány", + "display_options": "MOŽNOSTI ZOBRAZENÍ", + "show_hero": "Zobrazit hlavní sekci (Hero)", + "show_hero_desc": "Doporučený obsah v horní části", + "show_this_week": "Zobrazit sekci 'Tento týden'", + "show_this_week_desc": "Nové epizody z aktuálního týdne", + "select_catalogs": "Vybrat katalogy", + "all_catalogs": "Všechny katalogy", + "selected": "vybráno", + "hero_layout": "Rozvržení hlavní sekce", + "layout_legacy": "Původní (Legacy)", + "layout_carousel": "Karousel", + "layout_appletv": "Apple TV", + "layout_desc": "Banner na celou šířku, posuvné karty nebo styl Apple TV", + "featured_source": "Zdroj doporučeného obsahu", + "using_catalogs": "Používání katalogů", + "manage_selected_catalogs": "Spravovat vybrané katalogy", + "dynamic_bg": "Dynamické pozadí hlavní sekce", + "dynamic_bg_desc": "Rozmazaný banner za karouselem", + "performance_note": "Může ovlivnit výkon na slabších zařízeních.", + "posters": "Plakáty", + "show_titles": "Zobrazit názvy", + "poster_size": "Velikost plakátu", + "poster_corners": "Rohy plakátu", + "size_small": "Malé", + "size_medium": "Střední", + "size_large": "Velké", + "corners_square": "Ostré", + "corners_rounded": "Zaoblené", + "corners_pill": "Výrazně zaoblené", + "about_these_settings": "O TOMTO NASTAVENÍ", + "about_desc": "Tato nastavení určují, jak se obsah zobrazuje na vaší domovské obrazovce. Změny se projeví okamžitě bez nutnosti restartu aplikace.", + "hero_catalogs": { + "title": "Katalogy hlavní sekce", + "select_all": "Vybrat vše", + "clear_all": "Zrušit výběr", + "info": "Vyberte, které katalogy se mají zobrazovat v hlavní sekci (Hero). Pokud není vybrán žádný, použijí se všechny katalogy. Po dokončení nezapomeňte stisknout Uložit.", + "settings_saved": "Nastavení uloženo", + "error_load": "Nepodařilo se načíst katalogy", + "movies": "Filmy", + "tv_shows": "TV pořady" + } + }, + "calendar": { + "title": "Kalendář", + "loading": "Načítání kalendáře...", + "no_scheduled_episodes": "Žádné naplánované epizody", + "check_back_later": "Zkuste to prosím později", + "showing_episodes_for": "Zobrazení epizod pro {{date}}", + "show_all_episodes": "Zobrazit všechny epizody", + "no_episodes_for": "Žádné epizody pro {{date}}", + "no_upcoming_found": "Nebyly nalezeny žádné nadcházející epizody", + "add_series_desc": "Přidejte seriály do své knihovny, abyste zde viděli jejich nadcházející epizody" + }, + "mdblist": { + "title": "Zdroje hodnocení", + "status_disabled": "MDBList zakázán", + "status_active": "API klíč je aktivní", + "status_required": "Vyžadován API klíč", + "status_disabled_desc": "Funkcionalita MDBList je aktuálně vypnutá.", + "status_active_desc": "Hodnocení z MDBList jsou povolena.", + "status_required_desc": "Pro povolení hodnocení přidejte svůj klíč níže.", + "enable_toggle": "Povolit MDBList", + "enable_toggle_desc": "Zapnout/vypnout veškerou funkcionalitu MDBList", + "api_section": "API klíč", + "placeholder": "Vložte svůj MDBList API klíč", + "save": "Uložit", + "clear": "Smazat klíč", + "rating_providers": "Poskytovatelé hodnocení", + "rating_providers_desc": "Vyberte, která hodnocení se mají v aplikaci zobrazovat", + "how_to": "Jak získat API klíč", + "step_1": "Přihlaste se na", + "step_1_link": "webové stránce MDBList", + "step_2": "Přejděte do sekce", + "step_2_settings": "Settings", + "step_2_api": "API", + "step_2_end": ".", + "step_3": "Vygenerujte nový klíč a zkopírujte jej.", + "go_to_website": "Přejít na MDBList", + "alert_clear_title": "Smazat API klíč", + "alert_clear_msg": "Opravdu chcete odebrat uložený API klíč?", + "success_saved": "API klíč byl úspěšně uložen.", + "error_empty": "API klíč nemůže být prázdný.", + "error_save": "Při ukládání došlo k chybě. Zkuste to prosím znovu.", + "api_key_empty_error": "API klíč nemůže být prázdný.", + "success_cleared": "API klíč byl úspěšně smazán", + "error_clear": "Nepodařilo se smazat API klíč" + }, + "notification": { + "title": "Nastavení oznámení", + "section_general": "Obecné", + "enable_notifications": "Povolit oznámení", + "section_types": "Typy oznámení", + "new_episodes": "Nové epizody", + "upcoming_shows": "Nadcházející pořady", + "reminders": "Připomínky", + "section_timing": "Načasování oznámení", + "timing_desc": "Kdy chcete být upozorněni před vysíláním epizody?", + "hours_1": "1 hodina", + "hours_suffix": "hodin", + "section_status": "Stav oznámení", + "stats_upcoming": "Nadcházející", + "stats_this_week": "Tento týden", + "stats_total": "Celkem", + "sync_button": "Synchronizovat knihovnu a Trakt", + "syncing": "Synchronizace...", + "sync_desc": "Automaticky synchronizuje oznámení pro všechny pořady ve vaší knihovně a seznamu sledování/kolekci Trakt.", + "section_advanced": "Pokročilé", + "reset_button": "Resetovat všechna oznámení", + "test_button": "Testovací oznámení (5 s)", + "test_notification_in": "Oznámení za {{seconds}} s...", + "test_notification_text": "Oznámení se zobrazí za {{seconds}} sekund", + "alert_reset_title": "Resetovat oznámení", + "alert_reset_msg": "Tímto zrušíte všechna naplánovaná oznámení, ale nic neodstraníte z vaší knihovny. Jste si jisti?", + "alert_reset_success": "Všechna oznámení byla resetována", + "alert_sync_complete": "Synchronizace dokončena", + "alert_sync_msg": "Oznámení pro položky z vaší knihovny a Traktu byla úspěšně synchronizována.\n\nNaplánováno: {{upcoming}} nadcházejících epizod\nTento týden: {{thisWeek}} epizod", + "alert_test_scheduled": "Testovací oznámení naplánováno k okamžitému spuštění" + }, + "backup": { + "title": "Zálohování a obnovení", + "options_title": "Možnosti zálohování", + "options_desc": "Vyberte, co chcete zahrnout do svých záloh", + "section_core": "Základní data", + "section_addons": "Doplňky a integrace", + "section_settings": "Nastavení a předvolby", + "library_label": "Knihovna", + "library_desc": "Vaše uložené filmy a seriály", + "watch_progress_label": "Průběh sledování", + "watch_progress_desc": "Pozice rozkoukaných pořadů", + "addons_label": "Doplňky", + "addons_desc": "Nainstalované doplňky Stremio", + "plugins_label": "Pluginy", + "plugins_desc": "Vlastní konfigurace scraperů", + "trakt_label": "Integrace Trakt", + "trakt_desc": "Synchronizační data a autentizační tokeny", + "app_settings_label": "Nastavení aplikace", + "app_settings_desc": "Motiv, předvolby a konfigurace", + "user_prefs_label": "Uživatelské předvolby", + "user_prefs_desc": "Pořadí doplňků a nastavení UI", + "catalog_settings_label": "Nastavení katalogu", + "catalog_settings_desc": "Filtry katalogu a preference", + "api_keys_label": "API klíče", + "api_keys_desc": "Klíče pro MDBList a OpenRouter", + "action_create": "Vytvořit zálohu", + "action_restore": "Obnovit ze zálohy", + "section_info": "O zálohování", + "info_text": "• Pomocí přepínačů výše přizpůsobte obsah zálohy\n• Soubory zálohy jsou uloženy lokálně ve vašem zařízení\n• Sdílejte zálohu pro přenos dat mezi zařízeními\n• Obnovení přepíše vaše aktuální data", + "alert_create_title": "Vytvořit zálohu", + "alert_no_content": "K zálohování nebyl vybrán žádný obsah.\n\nPovolte prosím alespoň jednu možnost v sekci Možnosti zálohování výše.", + "alert_backup_created_title": "Záloha vytvořena", + "alert_backup_created_msg": "Vaše záloha byla vytvořena a je připravena ke sdílení.", + "alert_backup_failed_title": "Zálohování selhalo", + "alert_restore_confirm_title": "Potvrdit obnovení", + "alert_restore_confirm_msg": "Tímto obnovíte svá data ze zálohy vytvořené dne {{date}}.\n\nTato akce přepíše vaše aktuální data. Opravdu chcete pokračovat?", + "alert_restore_complete_title": "Obnovení dokončeno", + "alert_restore_complete_msg": "Vaše data byla úspěšně obnovena. Restartujte prosím aplikaci, aby se projevily všechny změny.", + "alert_restore_failed_title": "Obnovení selhalo", + "restart_app": "Restartovat aplikaci", + "alert_restart_failed_title": "Restart selhal", + "alert_restart_failed_msg": "Nepodařilo se restartovat aplikaci. Zavřete a znovu otevřete aplikaci ručně, abyste viděli obnovená data." + }, + "updates": { + "title": "Aktualizace aplikace", + "status_checking": "Kontrola aktualizací...", + "status_available": "Aktualizace je k dispozici!", + "status_downloading": "Stahování aktualizace...", + "status_installing": "Instalace aktualizace...", + "status_success": "Aktualizace byla úspěšně nainstalována!", + "status_error": "Aktualizace selhala", + "status_ready": "Připraveno ke kontrole aktualizací", + "action_check": "Zkontrolovat aktualizace", + "action_install": "Instalovat aktualizaci", + "release_notes": "Poznámky k vydání:", + "version": "Verze:", + "last_checked": "Poslední kontrola:", + "current_version": "Aktuální verze:", + "current_release_notes": "Poznámky k aktuální verzi:", + "github_release": "GITHUB RELEASE", + "current": "Aktuální:", + "latest": "Nejnovější:", + "notes": "Poznámky:", + "view_release": "Zobrazit vydání", + "notification_settings": "NASTAVENÍ OZNÁMENÍ", + "ota_alerts_label": "Upozornění na OTA aktualizace", + "ota_alerts_desc": "Zobrazovat oznámení pro bezdrátové (over-the-air) aktualizace", + "major_alerts_label": "Upozornění na hlavní aktualizace", + "major_alerts_desc": "Zobrazovat oznámení pro nové verze aplikace na GitHubu", + "alert_disable_ota_title": "Zakázat upozornění na OTA aktualizace?", + "alert_disable_ota_msg": "Již nebudete dostávat automatická oznámení o OTA aktualizacích.\n\n⚠️ Varování: Používání nejnovější verze je důležité pro:\n• Opravy chyb a stabilitu\n• Nové funkce a vylepšení\n• Poskytování přesné zpětné vazby a hlášení o pádech\n\nAktualizace můžete stále kontrolovat ručně na této obrazovce.", + "alert_disable_major_title": "Zakázat upozornění na hlavní aktualizace?", + "alert_disable_major_msg": "Již nebudete dostávat oznámení o hlavních aktualizacích aplikace, které vyžadují přeinstalaci.\n\n⚠️ Varování: Hlavní aktualizace často obsahují:\n• Kritické bezpečnostní záplaty\n• Zásadní změny vyžadující přeinstalaci\n• Důležité opravy kompatibility\n\nAktualizace můžete stále kontrolovat ručně.", + "warning_note": "Ponechání upozornění zapnutých zajišťuje, že obdržíte opravy chyb a budete moci poskytovat přesná hlášení o pádech.", + "disable": "Zakázat", + "alert_no_update_to_install": "Není k dispozici žádná aktualizace k instalaci", + "alert_install_failed": "Instalace aktualizace selhala", + "alert_no_update_title": "Žádná aktualizace", + "alert_update_applied_msg": "Aktualizace bude aplikována při příštím spuštění aplikace" + }, + "player": { + "title": "Video přehrávač", + "section_selection": "VÝBĚR PŘEHRÁVAČE", + "internal_title": "Vestavěný přehrávač", + "internal_desc": "Použít výchozí video přehrávač aplikace", + "vlc_title": "VLC", + "vlc_desc": "Otevírat streamy v přehrávači VLC", + "infuse_title": "Infuse", + "infuse_desc": "Otevírat streamy v přehrávači Infuse", + "outplayer_title": "OutPlayer", + "outplayer_desc": "Otevírat streamy v přehrávači OutPlayer", + "vidhub_title": "VidHub", + "vidhub_desc": "Otevírat streamy v přehrávači VidHub", + "infuse_live_title": "Infuse LiveContainer", + "infuse_live_desc": "Otevírat streamy v přehrávači Infuse přes LiveContainer", + "external_title": "Externí přehrávač", + "external_desc": "Otevírat streamy ve vašem preferovaném přehrávači", + "section_playback": "MOŽNOSTI PŘEHRÁVÁNÍ", + "skip_intro_settings_title": "Přeskočit úvod", + "powered_by_introdb": "Poháněno IntroDB", + "autoplay_title": "Automaticky přehrát první stream", + "autoplay_desc": "Automaticky spustit první stream zobrazený v seznamu.", + "resume_title": "Vždy navázat", + "resume_desc": "Přeskočit dotaz na pokračování a automaticky navázat tam, kde jste skončili (pokud zbývá více než 15 %).", + "engine_title": "Jádro video přehrávače", + "engine_desc": "Auto používá ExoPlayer s MPV jako zálohou. Některé formáty jako Dolby Vision a HDR nemusí být v MPV podporovány, proto je doporučeno nastavení Auto.", + "decoder_title": "Režim dekodéru", + "decoder_desc": "Způsob dekódování videa. Auto je doporučeno pro nejlepší rovnováhu.", + "gpu_title": "GPU vykreslování", + "gpu_desc": "GPU-Next nabízí lepší správu HDR a barev.", + "external_downloads_title": "Externí přehrávač pro stažené", + "external_downloads_desc": "Přehrávat stažený obsah ve vašem preferovaném externím přehrávači.", + "restart_required": "Vyžadován restart", + "restart_msg_decoder": "Restartujte prosím aplikaci, aby se změna dekodéru projevila.", + "restart_msg_gpu": "Restartujte prosím aplikaci, aby se změna režimu GPU projevila.", + "option_auto": "Auto", + "option_auto_desc_engine": "ExoPlayer + MPV záloha", + "option_mpv": "MPV", + "option_mpv_desc": "Pouze MPV", + "option_auto_desc_decoder": "Nejlepší rovnováha", + "option_sw": "SW", + "option_sw_desc": "Softwarové", + "option_hw": "HW", + "option_hw_desc": "Hardwarové", + "option_hw_plus": "HW+", + "option_hw_plus_desc": "Plné HW", + "option_gpu_desc": "Standardní", + "option_gpu_next_desc": "Pokročilé" + }, + "plugins": { + "title": "Pluginy", + "enable_title": "Povolit pluginy", + "enable_desc": "Povolit jádro pluginů pro vyhledávání externích zdrojů médií", + "repo_config_title": "Konfigurace repozitáře", + "repo_config_desc": "Spravujte externí repozitáře pluginů. Jednotlivé repozitáře můžete zapnout nebo vypnout níže.", + "your_repos": "Repozitáře", + "your_repos_desc": "Konfigurace externích zdrojů pro pluginy.", + "add_repo_button": "Přidat repozitář", + "refresh": "Obnovit", + "remove": "Odebrat", + "enabled": "Povoleno", + "disabled": "Zakázáno", + "updating": "Aktualizace...", + "success": "Úspěch", + "error": "Chyba", + "alert_repo_added": "Repozitář byl přidán a pluginy úspěšně načteny", + "alert_repo_saved": "URL repozitáře byla úspěšně uložena", + "alert_repo_refreshed": "Repozitář byl úspěšně obnoven", + "alert_invalid_url": "Neplatný formát URL", + "alert_plugins_cleared": "Všechny pluginy byly odebrány", + "alert_cache_cleared": "Mezipaměť repozitáře byla úspěšně vymazána", + "unknown": "Neznámý", + "active": "Aktivní", + "available": "Dostupný", + "platform_disabled": "Platforma zakázána", + "limited": "Omezený", + "clear_all": "Smazat všechny pluginy", + "clear_all_desc": "Opravdu chcete odebrat všechny nainstalované pluginy? Tuto akci nelze vrátit zpět.", + "clear_cache": "Vymazat mezipaměť repozitáře", + "clear_cache_desc": "Tímto odstraníte uloženou URL repozitáře a vymažete všechna data pluginů v mezipaměti. Budete muset znovu zadat URL repozitáře.", + "add_new_repo": "Přidat nový repozitář", + "available_plugins": "Dostupné pluginy ({{count}})", + "placeholder": "Hledat pluginy...", + "all": "Vše", + "filter_all": "Všechny typy", + "filter_movies": "Filmy", + "filter_tv": "TV pořady", + "enable_all": "Povolit vše", + "disable_all": "Zakázat vše", + "no_plugins_found": "Nebyly nalezeny žádné pluginy", + "no_plugins_available": "Nejsou k dispozici žádné pluginy", + "no_match_desc": "Žádné pluginy neodpovídají dotazu \"{{query}}\". Zkuste jiný termín.", + "configure_repo_desc": "Pro zobrazení dostupných pluginů nejprve nakonfigurujte repozitář výše.", + "clear_search": "Vymazat hledání", + "no_external_player": "Žádný externí přehrávač", + "showbox_token": "ShowBox UI Token", + "showbox_placeholder": "Vložte svůj ShowBox UI token", + "save": "Uložit", + "clear": "Smazat", + "additional_settings": "Další nastavení", + "enable_url_validation": "Povolit validaci URL", + "url_validation_desc": "Ověřit URL médií před jejich vrácením (může zpomalit výsledky, ale zvyšuje spolehlivost)", + "group_streams": "Seskupovat zdroje pluginů", + "group_streams_desc": "Pokud je povoleno, zdroje jsou seskupeny podle repozitáře. Pokud je zakázáno, každý plugin se zobrazuje jako samostatný poskytovatel.", + "sort_quality": "Řadit primárně podle kvality", + "sort_quality_desc": "Pokud je povoleno, zdroje jsou nejdříve řazeny podle kvality. Dostupné pouze při zapnutém seskupování.", + "show_logos": "Zobrazovat loga pluginů", + "show_logos_desc": "Zobrazit loga pluginů vedle odkazů na média na obrazovce zdrojů.", + "quality_filtering": "Filtrování kvality", + "quality_filtering_desc": "Vyloučit konkrétní rozlišení videa z výsledků hledání. Klepnutím na kvalitu ji vyloučíte.", + "excluded_qualities": "Vyloučené kvality:", + "language_filtering": "Filtrování jazyků", + "language_filtering_desc": "Vyloučit konkrétní jazyky z výsledků hledání. Klepnutím na jazyk jej vyloučíte.", + "note": "Poznámka:", + "language_filtering_note": "Tento filtr se vztahuje pouze na poskytovatele, kteří uvádějí informace o jazyce.", + "excluded_languages": "Vyloučené jazyky:", + "about_title": "O pluginech", + "about_desc_1": "Pluginy jsou modulární komponenty, které adaptují obsah z různých externích protokolů. Běží lokálně na vašem zařízení.", + "about_desc_2": "Pluginy označené jako „Omezené“ mohou vyžadovat specifické externí konfigurace.", + "help_title": "Nastavení pluginů", + "help_step_1": "1. **Povolit pluginy** - Zapněte hlavní vypínač", + "help_step_2": "2. **Přidat repozitář** - Zadejte platnou URL repozitáře", + "help_step_3": "3. **Obnovit repozitář** - Načtěte dostupné pluginy", + "help_step_4": "4. **Aktivovat** - Povolte pluginy, které chcete používat", + "got_it": "Rozumím!", + "repo_format_hint": "Formát: https://raw.githubusercontent.com/uzivatel/repo/refs/heads/hlavni", + "cancel": "Zrušit", + "add": "Přidat" + }, + "theme": { + "title": "Motivy aplikace", + "select_theme": "VYBRAT MOTIV", + "create_custom": "Vytvořit vlastní motiv", + "options": "MOŽNOSTI", + "use_dominant_color": "Použít dominantní barvu z plakátu", + "categories": { + "all": "Všechny motivy", + "dark": "Tmavé motivy", + "colorful": "Barevné", + "custom": "Moje motivy" + }, + "editor": { + "theme_name_placeholder": "Název motivu", + "save": "Uložit", + "primary": "Primární", + "secondary": "Sekundární", + "background": "Pozadí", + "invalid_name_title": "Neplatný název", + "invalid_name_msg": "Zadejte prosím platný název motivu" + }, + "alerts": { + "delete_title": "Smazat motiv", + "delete_msg": "Opravdu chcete smazat motiv „{{name}}“?", + "ok": "OK", + "delete": "Smazat", + "cancel": "Zrušit", + "back": "Nastavení" + } + }, + "legal": { + "title": "Právní informace", + "intro_title": "Povaha aplikace", + "intro_text": "Nuvio je přehrávač médií a nástroj pro správu metadat. Funguje výhradně jako klientské rozhraní pro prohlížení veřejně dostupných metadat (filmy, seriály atd.) a přehrávání souborů poskytnutých uživatelem nebo doplňky třetích stran. Nuvio samo o sobě nehostuje, neukládá, nedistribuuje ani neindexuje žádný mediální obsah.", + "extensions_title": "Pluginy třetích stran", + "extensions_text": "Nuvio využívá rozšiřitelnou architekturu, která uživatelům umožňuje instalovat pluginy třetích stran. Tyto pluginy jsou vyvíjeny nezávislými vývojáři. Nemáme žádnou kontrolu nad obsahem, legalitou nebo funkcionalitou jakéhokoli pluginu třetí strany.", + "user_resp_title": "Odpovědnost uživatele", + "user_resp_text": "Uživatelé jsou výhradně odpovědní za pluginy, které instalují, a obsah, ke kterému přistupují. Používáním této aplikace souhlasíte s tím, že zajistíte, abyste měli zákonné právo na přístup k obsahu. Vývojáři aplikace Nuvio neschvalují ani nepodporují porušování autorských práv.", + "dmca_title": "Autorská práva a DMCA", + "dmca_text": "Respektujeme práva duševního vlastnictví ostatních. Protože Nuvio nehostuje žádný obsah, nemůžeme jej z internetu odstranit. Pokud se však domníváte, že samotné rozhraní aplikace porušuje vaše práva, kontaktujte nás.", + "warranty_title": "Bez záruky", + "warranty_text": "Tento software je poskytován „tak, jak je“, bez jakékoli záruky. Autoři ani držitelé autorských práv v žádném případě nenesou odpovědnost za jakékoli nároky, škody nebo jiné závazky vyplývající z používání tohoto softwaru." + }, + "plugin_tester": { + "title": "Tester pluginů", + "subtitle": "Spouštějte scrapery a sledujte logy v reálném čase", + "tabs": { + "individual": "Individuální", + "repo": "Tester repozitáře", + "code": "Kód", + "logs": "Logy", + "results": "Výsledky" + }, + "common": { + "error": "Chyba", + "success": "Úspěch", + "movie": "Film", + "tv": "TV", + "tmdb_id": "TMDB ID", + "season": "Série", + "episode": "Epizoda", + "running": "Běží…", + "run_test": "Spustit test", + "play": "Přehrát", + "done": "Hotovo", + "test": "Test", + "testing": "Testování…" + }, + "individual": { + "load_from_url": "Načíst z URL", + "load_from_url_desc": "Vložte přímou URL z GitHubu nebo lokální IP a klepněte na stáhnout.", + "enter_url_error": "Zadejte prosím URL", + "code_loaded": "Kód načten z URL", + "fetch_error": "Chyba načítání: {{message}}", + "no_code_error": "Žádný kód ke spuštění", + "plugin_code": "Kód pluginu", + "focus_editor": "Aktivovat editor kódu", + "code_placeholder": "// Zde vložte kód pluginu...", + "test_parameters": "Parametry testu", + "no_logs": "Zatím žádné logy. Spusťte test pro zobrazení výstupu.", + "no_streams": "Zatím nebyly nalezeny žádné streamy.", + "streams_found": "Nalezen {{count}} stream", + "streams_found_plural": "Nalezeno {{count}} streamů", + "tap_play_hint": "Klepnutím na Přehrát otestujete stream v nativním přehrávači.", + "unnamed_stream": "Nepojmenovaný stream", + "quality": "Kvalita: {{quality}}", + "size": "Velikost: {{size}}", + "url_label": "URL: {{url}}", + "headers_info": "Hlavičky: {{count}} vlastní hlavička/y", + "find_placeholder": "Hledat v kódu…", + "edit_code_title": "Upravit kód", + "no_url_stream_error": "Pro tento stream nebyla nalezena žádná URL" + }, + "repo": { + "title": "Tester repozitáře", + "description": "Načtěte repozitář (lokální URL nebo GitHub raw) a otestujte každého poskytovatele.", + "enter_repo_url_error": "Zadejte prosím URL repozitáře", + "invalid_url_title": "Neplatná URL", + "invalid_url_msg": "Použijte přímou GitHub raw URL nebo lokální http(s) URL.\n\nPříklad:\nhttps://raw.githubusercontent.com/uzivatel/nuvio-providers/refs/heads/main", + "manifest_build_error": "Nepodařilo se sestavit URL manifestu ze vstupu", + "manifest_fetch_error": "Nepodařilo se načíst manifest", + "repo_manifest_fetch_error": "Nepodařilo se načíst manifest repozitáře", + "missing_filename": "V manifestu chybí název souboru", + "scraper_build_error": "Nepodařilo se sestavit URL scraperu", + "download_scraper_error": "Nepodařilo se stáhnout scraper", + "test_failed": "Test selhal", + "test_parameters": "Parametry testu repozitáře", + "test_parameters_desc": "Tyto parametry se používají pouze pro Tester repozitáře.", + "using_info": "Použito: {{mediaType}} • TMDB {{tmdbId}}", + "using_info_tv": "Použito: {{mediaType}} • TMDB {{tmdbId}} • S{{season}}E{{episode}}", + "providers_title": "Poskytovatelé", + "repository_default": "Repozitář", + "providers_count": "{{count}} poskytovatelů", + "fetch_hint": "Načtěte repozitář pro zobrazení seznamu poskytovatelů.", + "test_all": "Otestovat vše", + "status_running": "BĚŽÍ", + "status_ok": "OK ({{count}})", + "status_ok_empty": "OK (0)", + "status_failed": "CHYBA", + "status_idle": "NEČINNÝ", + "tried_url": "Zkoušeno: {{url}}", + "provider_logs": "Logy poskytovatele", + "no_logs_captured": "Nebyly zachyceny žádné logy." + } + } +} \ No newline at end of file diff --git a/src/i18n/locales/de.json b/src/i18n/locales/de.json index fdf27e82..c9f70d81 100644 --- a/src/i18n/locales/de.json +++ b/src/i18n/locales/de.json @@ -636,6 +636,18 @@ "chinese": "Chinesisch (Vereinfacht)", "hindi": "Hindi", "serbian": "Serbisch", + "hebrew": "Hebräisch", + "bulgarian": "Bulgarisch", + "polish": "Polnisch", + "czech": "Tschechisch", + "turkish": "Türkisch", + "slovenian": "Slowenisch", + "macedonian": "Makedonisch", + "russian": "Russisch", + "filipino": "Philippinisch", + "dutch_nl": "Niederländisch (Niederlande)", + "romanian": "Rumänisch", + "albanian": "Albanisch", "account": "Konto", "content_discovery": "Inhalt & Entdeckung", "appearance": "Aussehen", @@ -896,8 +908,8 @@ }, "debrid": { "title": "Debrid Integration", - "description_torbox": "Entsperren Sie 4K-Streams durch Integration von Torbox.", - "description_torrentio": "Konfigurieren Sie Torrentio um Torrent-Streams zu erhalten.", + "description_torbox": "Connect Torbox to use your account-based source preferences. Enter your API key below to configure the integration.", + "description_torrentio": "Configure Torrentio as an external source integration. A compatible debrid account may be required depending on your setup.", "tab_torbox": "TorBox", "tab_torrentio": "Torrentio", "status_connected": "Verbunden", @@ -924,15 +936,15 @@ "enter_api_key": "Geben Sie Ihren API-Schlüssel ein", "connect_button": "Verbinden & Installieren", "connecting": "Verbinde...", - "unlock_speeds_title": "Premium-Geschwindigkeiten entsperren", - "unlock_speeds_desc": "Holen Sie sich ein Torbox-Abonnement.", + "unlock_speeds_title": "Optional Torbox Subscription", + "unlock_speeds_desc": "Torbox offers account tiers with enhanced performance and availability features.", "get_subscription": "Abonnement holen", "powered_by": "Bereitgestellt von", "disclaimer_torbox": "Nuvio ist nicht mit Torbox verbunden.", "disclaimer_torrentio": "Nuvio ist nicht mit Torrentio verbunden.", "installed_badge": "✓ INSTALLIERT", "promo_title": "⚡ Brauchen Sie einen Debrid-Dienst?", - "promo_desc": "Holen Sie sich TorBox für blitzschnelles 4K-Streaming.", + "promo_desc": "Use TorBox if you want account-managed performance features for supported integrations.", "promo_button": "TorBox-Abonnement holen", "service_label": "Debrid-Dienst *", "api_key_label": "API-Schlüssel *", @@ -1324,7 +1336,7 @@ "user_resp_title": "Verantwortung des Benutzers", "user_resp_text": "Benutzer sind allein verantwortlich für die installierten Erweiterungen.", "dmca_title": "Urheberrecht & DMCA", - "dmca_text": "Wir respektieren die geistigen Eigentumsrechte anderer.", + "dmca_text": "We respect the intellectual property rights of others. Nuvio does not host media content. If you believe this project's code, assets, or interface infringes your rights, submit a notice through the official project contact channels listed on the website and repository.", "warranty_title": "Keine Garantie", "warranty_text": "Diese Software wird ohne Mängelgewähr bereitgestellt." }, diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index bb7c8cb3..dd85edf5 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -641,6 +641,18 @@ "chinese": "Chinese (Simplified)", "hindi": "Hindi", "serbian": "Serbian", + "hebrew": "Hebrew", + "bulgarian": "Bulgarian", + "polish": "Polish", + "czech": "Czech", + "turkish": "Turkish", + "slovenian": "Slovenian", + "macedonian": "Macedonian", + "russian": "Russian", + "filipino": "Filipino", + "dutch_nl": "Dutch (Netherlands)", + "romanian": "Romanian", + "albanian": "Albanian", "account": "Account", "content_discovery": "Content & Discovery", "appearance": "Appearance", @@ -786,13 +798,13 @@ "analytics_enabled_title": "Analytics Enabled", "analytics_enabled_message": "Usage data will be collected to help improve the app. You can disable this at any time.", "disable_error_reporting_title": "Disable Error Reporting?", - "disable_error_reporting_message": "Disabling error reporting means we won\u2019t be notified of crashes or issues you experience. This may affect our ability to fix bugs.", + "disable_error_reporting_message": "Disabling error reporting means we won’t be notified of crashes or issues you experience. This may affect our ability to fix bugs.", "enable_session_replay_title": "Enable Session Replay?", "enable_session_replay_message": "Session replay records your screen when errors occur to help us understand what happened. This may capture visible content on your screen.", "enable_pii_title": "Enable PII Collection?", "enable_pii_message": "This allows collection of personally identifiable information like IP address and device details. This data helps diagnose issues but increases privacy exposure.", "disable_all_title": "Disable All Telemetry?", - "disable_all_message": "This will disable all analytics, error reporting, and session replay. We won\u2019t receive any data about app usage or crashes.", + "disable_all_message": "This will disable all analytics, error reporting, and session replay. We won’t receive any data about app usage or crashes.", "disable_all_button": "Disable All", "all_disabled_title": "All Telemetry Disabled", "all_disabled_message": "All data collection has been disabled. Changes take effect on next app restart.", @@ -925,8 +937,8 @@ }, "debrid": { "title": "Debrid Integration", - "description_torbox": "Unlock 4K high-quality streams and lightning-fast speeds by integrating Torbox. Enter your API Key below to instantly upgrade your streaming experience.", - "description_torrentio": "Configure Torrentio to get torrent streams for movies and TV shows. A debrid service is required to stream content.", + "description_torbox": "Connect Torbox to use your account-based source preferences. Enter your API key below to configure the integration.", + "description_torrentio": "Configure Torrentio as an external source integration. A compatible debrid account may be required depending on your setup.", "tab_torbox": "TorBox", "tab_torrentio": "Torrentio", "status_connected": "Connected", @@ -953,15 +965,15 @@ "enter_api_key": "Enter your API Key", "connect_button": "Connect & Install", "connecting": "Connecting...", - "unlock_speeds_title": "Unlock Premium Speeds", - "unlock_speeds_desc": "Get a Torbox subscription to access cached high-quality streams with zero buffering.", + "unlock_speeds_title": "Optional Torbox Subscription", + "unlock_speeds_desc": "Torbox offers account tiers with enhanced performance and availability features.", "get_subscription": "Get Subscription", "powered_by": "Powered by", "disclaimer_torbox": "Nuvio is not affiliated with Torbox in any way.", "disclaimer_torrentio": "Nuvio is not affiliated with Torrentio in any way.", "installed_badge": "✓ INSTALLED", "promo_title": "⚡ Need a Debrid Service?", - "promo_desc": "Get TorBox for lightning-fast 4K streaming with zero buffering. Premium cached torrents and instant downloads.", + "promo_desc": "Use TorBox if you want account-managed performance features for supported integrations.", "promo_button": "Get TorBox Subscription", "service_label": "Debrid Service *", "api_key_label": "API Key *", @@ -1353,7 +1365,7 @@ "user_resp_title": "User Responsibility", "user_resp_text": "Users are solely responsible for the plugins they install and the content they access. By using this application, you agree to ensure that you have the legal right to access any content you view using Nuvio. The developers of Nuvio do not endorse or encourage copyright infringement.", "dmca_title": "Copyright & DMCA", - "dmca_text": "We respect the intellectual property rights of others. Since Nuvio does not host any content, we cannot remove content from the internet. However, if you believe that the application interface itself infringes on your rights, please contact us.", + "dmca_text": "We respect the intellectual property rights of others. Nuvio does not host media content. If you believe this project's code, assets, or interface infringes your rights, submit a notice through the official project contact channels listed on the website and repository.", "warranty_title": "No Warranty", "warranty_text": "This software is provided \"as is\", without warranty of any kind, express or implied. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability arising from the use of this software." }, diff --git a/src/i18n/locales/es.json b/src/i18n/locales/es.json index b0ae867f..21077949 100644 --- a/src/i18n/locales/es.json +++ b/src/i18n/locales/es.json @@ -636,6 +636,18 @@ "chinese": "Chino (Simplificado)", "hindi": "Hindi", "serbian": "Serbio", + "hebrew": "Hebreo", + "bulgarian": "Búlgaro", + "polish": "Polaco", + "czech": "Checo", + "turkish": "Turco", + "slovenian": "Esloveno", + "macedonian": "Macedonio", + "russian": "Ruso", + "filipino": "Filipino", + "dutch_nl": "Holandés (Países Bajos)", + "romanian": "Rumano", + "albanian": "Albanés", "account": "Cuenta", "content_discovery": "Contenido y descubrimiento", "appearance": "Apariencia", @@ -896,8 +908,8 @@ }, "debrid": { "title": "Integración de Debrid", - "description_torbox": "Desbloquea fuentes 4K de alta calidad y velocidades ultrarrápidas integrando Torbox. Introduce tu clave de API abajo para mejorar instantáneamente tu experiencia de streaming.", - "description_torrentio": "Configura Torrentio para obtener fuentes de torrents para películas y series. Se requiere un servicio de debrid para reproducir el contenido.", + "description_torbox": "Connect Torbox to use your account-based source preferences. Enter your API key below to configure the integration.", + "description_torrentio": "Configure Torrentio as an external source integration. A compatible debrid account may be required depending on your setup.", "tab_torbox": "TorBox", "tab_torrentio": "Torrentio", "status_connected": "Conectado", @@ -924,15 +936,15 @@ "enter_api_key": "Introduce tu clave de API", "connect_button": "Conectar e instalar", "connecting": "Conectando...", - "unlock_speeds_title": "Desbloquea velocidades premium", - "unlock_speeds_desc": "Consigue una suscripción a Torbox para acceder a fuentes de alta calidad en caché sin buffering.", + "unlock_speeds_title": "Optional Torbox Subscription", + "unlock_speeds_desc": "Torbox offers account tiers with enhanced performance and availability features.", "get_subscription": "Conseguir suscripción", "powered_by": "Impulsado por", "disclaimer_torbox": "Nuvio no tiene ninguna afiliación con Torbox.", "disclaimer_torrentio": "Nuvio no tiene ninguna afiliación con Torrentio.", "installed_badge": "✓ INSTALADO", "promo_title": "⚡ ¿Necesitas un servicio de Debrid?", - "promo_desc": "Consigue TorBox para streaming 4K ultrarrápido sin buffering. Torrents en caché premium y descargas instantáneas.", + "promo_desc": "Use TorBox if you want account-managed performance features for supported integrations.", "promo_button": "Conseguir suscripción a TorBox", "service_label": "Servicio de Debrid *", "api_key_label": "Clave de API *", @@ -1324,7 +1336,7 @@ "user_resp_title": "Responsabilidad del usuario", "user_resp_text": "Los usuarios son los únicos responsables de las extensiones que instalan y del contenido al que acceden. Al utilizar esta aplicación, aceptas asegurarte de que tienes el derecho legal de acceder a cualquier contenido que veas utilizando Nuvio. Los desarrolladores de Nuvio no respaldan ni fomentan la infracción de derechos de autor.", "dmca_title": "Derechos de autor y DMCA", - "dmca_text": "Respetamos los derechos de propiedad intelectual de otros. Dado que Nuvio no aloja ningún contenido, no podemos eliminar contenido de Internet. Sin embargo, si crees que la interfaz de la aplicación en sí infringe tus derechos, por favor contáctanos.", + "dmca_text": "We respect the intellectual property rights of others. Nuvio does not host media content. If you believe this project's code, assets, or interface infringes your rights, submit a notice through the official project contact channels listed on the website and repository.", "warranty_title": "Sin garantía", "warranty_text": "Este software se proporciona \"tal cual\", sin garantía de ningún tipo, expresa o implícita. En ningún caso los autores o titulares de los derechos de autor serán responsables de ninguna reclamación, daños u otra responsabilidad que surja del uso de este software." }, diff --git a/src/i18n/locales/fil.json b/src/i18n/locales/fil.json new file mode 100644 index 00000000..ff2092b6 --- /dev/null +++ b/src/i18n/locales/fil.json @@ -0,0 +1,1430 @@ +{ + "common": { + "loading": "Naglo-loading...", + "cancel": "Kanselahin", + "save": "I-save", + "delete": "Burahin", + "edit": "I-edit", + "search": "Maghanap", + "error": "Error", + "success": "Tagumpay", + "ok": "OK", + "unknown": "Hindi Alam", + "retry": "Subukan muli", + "try_again": "Subukan muli", + "go_back": "Bumalik", + "settings": "Mga Setting", + "close": "Isara", + "enable": "I-enable", + "disable": "I-disable", + "show_more": "Ipakita ang higit pa", + "show_less": "Ipakita ang mas kaunti", + "load_more": "Mag-load ng higit pa", + "unknown_date": "Hindi alam na petsa", + "anonymous_user": "Anonymous na User", + "time": { + "now": "Ngayon lang", + "minutes_ago": "{{count}}m ang nakalipas", + "hours_ago": "{{count}}h ang nakalipas", + "days_ago": "{{count}}d ang nakalipas" + }, + "days_short": { + "sun": "Lin", + "mon": "Lun", + "tue": "Mar", + "wed": "Miy", + "thu": "Huw", + "fri": "Biy", + "sat": "Sab" + }, + "email": "Email", + "status": "Status" + }, + "home": { + "categories": { + "movies": "Mga Pelikula", + "series": "Mga Serye", + "channels": "Mga Channel" + }, + "movies": "Mga Pelikula", + "tv_shows": "Mga TV Show", + "load_more_catalogs": "Mag-load ng iba pang Catalog", + "no_content": "Walang available na nilalaman", + "add_catalogs": "Magdagdag ng mga Catalog", + "sign_in_available": "Puwede nang Mag-sign In", + "sign_in_desc": "Maaari kang mag-sign in anumang oras mula sa Settings → Account", + "view_all": "Tingnan Lahat", + "this_week": "Ngayong Linggo", + "upcoming": "Malapit Na", + "recently_released": "Kakalabas Lang", + "no_scheduled_episodes": "Serye na Walang Naka-iskedyul na Episode", + "check_back_later": "Bumalik na lang mamaya", + "continue_watching": "Ituloy ang Panonood", + "up_next": "Susunod", + "up_next_caps": "SUSUNOD", + "released": "Ipinalabas", + "new": "Bago", + "tba": "Iaanunsyo pa", + "new_episodes": "{{count}} Bagong Episode", + "season_short": "S{{season}}", + "episode_short": "E{{episode}}", + "season": "Season {{season}}", + "episode": "Episode {{episode}}", + "movie": "Pelikula", + "series": "Serye", + "tv_show": "TV Show", + "percent_watched": "{{percent}}% napanood na", + "view_details": "Tingnan ang Detalye", + "remove": "Alisin", + "play": "I-play", + "play_now": "I-play Na", + "resume": "Ituloy", + "info": "Info", + "more_info": "Higit pang Info", + "my_list": "Aking Listahan", + "save": "I-save", + "saved": "Na-save na", + "retry": "Subukan muli", + "install_addons": "Mag-install ng mga Addon", + "settings": "Mga Setting", + "no_featured_content": "Walang Itinatampok na Nilalaman", + "couldnt_load_featured": "Hindi ma-load ang itinatampok na nilalaman", + "no_featured_desc": "Mag-install ng mga addon na may mga catalog o baguhin ang source sa iyong settings.", + "load_error_desc": "Nagkaroon ng problema sa pagkuha ng content. Pakisuri ang iyong koneksyon at subukan muli.", + "no_featured_available": "Walang available na itinatampok na nilalaman", + "no_description": "Walang available na deskripsyon" + }, + "navigation": { + "home": "Home", + "library": "Library", + "search": "Maghanap", + "downloads": "Downloads", + "settings": "Mga Setting" + }, + "search": { + "title": "Maghanap", + "recent_searches": "Mga Nakaraang Hinanap", + "discover": "Tumuklas", + "movies": "Mga Pelikula", + "tv_shows": "Mga TV Show", + "select_catalog": "Pumili ng Catalog", + "all_genres": "Lahat ng Genre", + "discovering": "Naghahanap ng nilalaman...", + "show_more": "Ipakita ang higit pa ({{count}})", + "no_content_found": "Walang nahanap na nilalaman", + "try_different": "Subukan ang ibang genre o catalog", + "select_catalog_desc": "Pumili ng catalog para tumuklas", + "tap_catalog_desc": "I-tap ang catalog sa itaas para magsimula", + "placeholder": "Maghanap ng pelikula, show...", + "keep_typing": "Ipagpatuloy ang pag-type...", + "type_characters": "Mag-type ng hindi bababa sa 2 character", + "no_results": "Walang nahanap na resulta", + "try_keywords": "Subukan ang ibang keywords o suriin ang spelling", + "select_type": "Pumili ng Uri", + "browse_movies": "Mag-browse ng mga pelikula", + "browse_tv": "Mag-browse ng mga TV series", + "select_genre": "Pumili ng Genre", + "show_all_content": "Ipakita ang lahat ng nilalaman", + "genres_count": "{{count}} na genre" + }, + "library": { + "title": "Library", + "watched": "Napanood na", + "continue": "Ituloy", + "watchlist": "Watchlist", + "collection": "Koleksyon", + "rated": "Na-rate na", + "items": "items", + "trakt_collections": "Mga koleksyon sa Trakt", + "trakt_collection": "Koleksyon sa Trakt", + "no_trakt": "Walang mga koleksyon sa Trakt", + "no_trakt_desc": "Lilitaw dito ang iyong mga Trakt collection kapag ginamit mo na ang Trakt", + "load_collections": "Mag-load ng Koleksyon", + "empty_folder": "Walang laman ang {{folder}}", + "empty_folder_desc": "Walang laman ang koleksyong ito", + "refresh": "I-refresh", + "no_movies": "Wala pang mga pelikula", + "no_series": "Wala pang mga TV show", + "no_content": "Wala pang nilalaman", + "add_content_desc": "Magdagdag ng content sa iyong library para makita ito rito", + "find_something": "Maghanap ng mapapanood", + "removed_from_library": "Inalis sa Library", + "item_removed": "Ang item ay inalis na sa iyong library", + "failed_update_library": "Bigo sa pag-update ng Library", + "unable_remove": "Hindi maalis ang item sa library", + "marked_watched": "Minarkahan bilang Napanood na", + "marked_unwatched": "Minarkahan bilang Hindi pa Napanood", + "item_marked_watched": "Minarkahan ang item bilang napanood na", + "item_marked_unwatched": "Minarkahan ang item bilang hindi pa napanood", + "failed_update_watched": "Bigo sa pag-update ng watched status", + "unable_update_watched": "Hindi ma-update ang watched status", + "added_to_library": "Idinagdag sa Library", + "item_added": "Idinagdag sa iyong local library", + "add_to_library": "Idagdag sa Library", + "remove_from_library": "Alisin sa Library", + "mark_watched": "Markahan bilang Napanood", + "mark_unwatched": "Markahan bilang Hindi pa Napanood", + "share": "Ibahagi", + "add_to_watchlist": "Idagdag sa Trakt Watchlist", + "remove_from_watchlist": "Alisin sa Trakt Watchlist", + "added_to_watchlist": "Idinagdag sa Watchlist", + "added_to_watchlist_desc": "Idinagdag sa iyong Trakt watchlist", + "removed_from_watchlist": "Inalis sa Watchlist", + "removed_from_watchlist_desc": "Inalis sa iyong Trakt watchlist", + "add_to_collection": "Idagdag sa Trakt Collection", + "remove_from_collection": "Alisin sa Trakt Collection", + "added_to_collection": "Idinagdag sa Koleksyon", + "added_to_collection_desc": "Idinagdag sa iyong Trakt collection", + "removed_from_collection": "Inalis sa Koleksyon", + "removed_from_collection_desc": "Inalis sa iyong Trakt collection" + }, + "metadata": { + "unable_to_load": "Hindi ma-load ang nilalaman", + "error_code": "Error Code: {{code}}", + "content_not_found": "Hindi nahanap ang nilalaman", + "content_not_found_desc": "Ang nilalamang ito ay hindi umiiral o maaaring inalis na.", + "server_error": "Error sa server", + "server_error_desc": "Ang server ay pansamantalang hindi available. Pakisubukan muli mamaya.", + "bad_gateway": "Bad gateway", + "bad_gateway_desc": "Nagkakaproblema ang server. Pakisubukan muli mamaya.", + "service_unavailable": "Hindi available ang serbisyo", + "service_unavailable_desc": "Kasalukuyang inaayos ang serbisyo. Pakisubukan muli mamaya.", + "too_many_requests": "Masyadong maraming request", + "too_many_requests_desc": "Masyadong madalas ang iyong pag-request. Pakihintay muna at subukan muli.", + "request_timeout": "Nag-timeout ang request", + "request_timeout_desc": "Masyadong matagal ang request. Pakisubukan muli.", + "network_error": "Error sa network", + "network_error_desc": "Pakisuri ang iyong koneksyon sa internet at subukan muli.", + "auth_error": "Error sa authentication", + "auth_error_desc": "Pakisuri ang iyong account settings at subukan muli.", + "access_denied": "Denied ang access", + "access_denied_desc": "Wala kang permiso na i-access ang nilalamang ito.", + "connection_error": "Error sa koneksyon", + "streams_unavailable": "Hindi available ang mga stream", + "streams_unavailable_desc": "Ang mga streaming source ay kasalukuyang hindi available. Pakisubukan muli mamaya.", + "unknown_error": "Hindi alam na error", + "something_went_wrong": "May nagkamali. Pakisubukan muli.", + "cast": "Mga Artista", + "more_like_this": "Mga Katulad Nito", + "collection": "Koleksyon", + "episodes": "Mga Episode", + "seasons": "Mga Season", + "posters": "Mga Poster", + "banners": "Mga Banner", + "specials": "Mga Special", + "season_number": "Season {{number}}", + "episode_count": "{{count}} Episode", + "episode_count_plural": "{{count}} na mga Episode", + "no_episodes": "Walang available na mga episode", + "no_episodes_for_season": "Walang available na mga episode para sa Season {{season}}", + "episodes_not_released": "Maaaring hindi pa ipinapalabas ang mga episode", + "no_description": "Walang available na deskripsyon", + "episode_label": "EPISODE {{number}}", + "watch_again": "Panoorin muli", + "completed": "Tapos na", + "play_episode": "I-play ang S{{season}}E{{episode}}", + "play": "I-play", + "watched": "Napanood na", + "watched_on_trakt": "Napanood na sa Trakt", + "synced_with_trakt": "Naka-sync sa Trakt", + "saved": "Na-save na", + "director": "Direktor", + "directors": "Mga Direktor", + "creator": "Tagalikha", + "creators": "Mga Tagalikha", + "production": "Produksyon", + "network": "Network", + "mark_watched": "Markahan bilang Napanood", + "mark_unwatched": "Markahan bilang Hindi pa Napanood", + "marking": "Minamarkahan...", + "removing": "Inaalis...", + "unmark_season": "I-unmark ang Season {{season}}", + "mark_season": "Markahan ang Season {{season}}", + "resume": "Ituloy", + "spoiler_warning": "Spoiler Warning", + "spoiler_warning_desc": "Ang komento na ito ay may mga spoiler. Sigurado ka bang gusto mo itong makita?", + "cancel": "Kanselahin", + "reveal_spoilers": "Ipakita ang mga Spoiler", + "movie_details": "Mga Detalye ng Pelikula", + "show_details": "Mga Detalye ng Show", + "tagline": "Tagline", + "status": "Status", + "release_date": "Petsa ng Paglabas", + "runtime": "Runtime", + "budget": "Budget", + "revenue": "Kita", + "origin_country": "Bansang Pinagmulan", + "original_language": "Orihinal na Wika", + "first_air_date": "Unang Petsa ng Pag-ere", + "last_air_date": "Huling Petsa ng Pag-ere", + "total_episodes": "Kabuuang Episode", + "episode_runtime": "Runtime ng Episode", + "created_by": "Nilikha ni", + "backdrop_gallery": "Backdrop Gallery", + "loading_episodes": "Naglo-load ng mga episode...", + "no_episodes_available": "Walang available na mga episode", + "play_next": "I-play ang S{{season}}E{{episode}}", + "play_next_episode": "I-play ang Susunod na Episode", + "save": "I-save", + "percent_watched": "{{percent}}% napanood na", + "percent_watched_trakt": "{{percent}}% napanood na ({{traktPercent}}% sa Trakt)", + "synced_with_trakt_progress": "Naka-sync sa Trakt", + "using_trakt_progress": "Gamit ang Trakt progress", + "added_to_collection_hero": "Idinagdag sa Koleksyon", + "added_to_collection_desc_hero": "Idinagdag sa iyong Trakt collection", + "removed_from_collection_hero": "Inalis sa Koleksyon", + "removed_from_collection_desc_hero": "Inalis sa iyong Trakt collection", + "mark_as_watched": "Markahan bilang Napanood", + "mark_as_unwatched": "Markahan bilang Hindi pa Napanood" + }, + "cast": { + "biography": "Talambuhay", + "known_for": "Kilala sa", + "personal_info": "Personal na Impormasyon", + "born_in": "Ipinanganak sa {{place}}", + "filmography": "Pelikulang Kinabilangan", + "also_known_as": "Kilala rin bilang", + "no_info_available": "Walang karagdagang impormasyon", + "as_character": "bilang {{character}}", + "loading_details": "Naglo-load ng mga detalye...", + "years_old": "{{age}} taong gulang", + "view_filmography": "Tingnan ang Filmography", + "filter": "I-filter", + "sort_by": "I-sort ayon sa", + "sort_popular": "Sikat", + "sort_latest": "Pinakabago", + "sort_upcoming": "Paparating", + "upcoming_badge": "PAPARATING", + "coming_soon": "Malapit na", + "filmography_count": "Filmography • {{count}} na titulo", + "loading_filmography": "Naglo-load ng filmography...", + "load_more_remaining": "Mag-load pa ({{count}} ang natitira)", + "alert_error_title": "Error", + "alert_error_message": "Hindi ma-load ang \"{{title}}\". Pakisubukan muli mamaya.", + "alert_ok": "OK", + "no_upcoming": "Walang paparating na release para sa artist na ito", + "no_content": "Walang available na content para sa artist na ito", + "no_movies": "Walang mga pelikula para sa artist na ito", + "no_tv": "Walang mga TV show para sa artist na ito" + }, + "comments": { + "title": "Mga Komento sa Trakt", + "spoiler_warning": "⚠️ Ang komento na ito ay may spoiler. I-tap para makita.", + "spoiler": "Spoiler", + "contains_spoilers": "May mga spoiler", + "reveal": "Ipakita", + "vip": "VIP", + "unavailable": "Hindi available ang mga komento", + "no_comments": "Wala pang mga komento sa Trakt", + "not_in_database": "Maaaring wala pa ito sa database ng Trakt", + "check_trakt": "Suriin ang Trakt" + }, + "trailers": { + "title": "Mga Trailer", + "official_trailers": "Mga Opisyal na Trailer", + "official_trailer": "Opisyal na Trailer", + "teasers": "Mga Teaser", + "teaser": "Teaser", + "clips_scenes": "Mga Clip at Eksena", + "clip": "Clip", + "featurettes": "Mga Featurette", + "featurette": "Featurette", + "behind_the_scenes": "Behind the Scenes", + "no_trailers": "Walang available na mga trailer", + "unavailable": "Hindi Available ang Trailer", + "unavailable_desc": "Hindi ma-load ang trailer na ito ngayon. Pakisubukan muli mamaya.", + "unable_to_play": "Hindi ma-play ang trailer. Pakisubukan muli.", + "watch_on_youtube": "Panoorin sa YouTube" + }, + "catalog": { + "no_content_found": "Walang nahanap na nilalaman", + "no_content_filters": "Walang nahanap na nilalaman para sa napiling filters", + "loading_content": "Naglo-load ng nilalaman...", + "back": "Bumalik", + "in_theaters": "Nasa mga Sinehan", + "all": "Lahat", + "failed_tmdb": "Bigo sa pag-load ng content mula sa TMDB", + "movies": "Mga Pelikula", + "tv_shows": "Mga TV Show", + "channels": "Mga Channel" + }, + "streams": { + "back_to_episodes": "Bumalik sa mga Episode", + "back_to_info": "Bumalik sa Info", + "fetching_from": "Kinukuha mula sa:", + "no_sources_available": "Walang available na streaming sources", + "add_sources_desc": "Mangyaring magdagdag ng streaming sources sa settings", + "add_sources": "Magdagdag ng Source", + "finding_streams": "Naghahanap ng mga stream...", + "finding_best_stream": "Hinahanap ang pinakamagandang stream...", + "still_fetching": "Kumukuha pa ng mga stream...", + "no_streams_available": "Walang available na stream", + "starting_best_stream": "Sinisimulan ang pinakamagandang stream...", + "loading_more_sources": "Naglo-load ng higit pang source..." + }, + "player_ui": { + "via": "gamit ang {{name}}", + "audio_tracks": "Mga Audio Track", + "no_audio_tracks": "Walang available na audio track", + "playback_speed": "Bilis ng Playback", + "on_hold": "Naka-hold", + "playback_error": "Error sa Playback", + "unknown_error": "Nagkaroon ng hindi malamang error habang nagpe-play.", + "copy_error": "Kopyahin ang detalye ng error", + "copied_to_clipboard": "Nagawa nang kopyahin", + "dismiss": "I-dismiss", + "continue_watching": "Ituloy ang Panonood", + "start_over": "Ulitin sa Simula", + "resume": "Ituloy", + "change_source": "Palitan ang Source", + "switching_source": "Lumilipat ng source...", + "no_sources_found": "Walang nahanap na source", + "sources": "Mga Source", + "finding_sources": "Naghahanap ng mga source...", + "unknown_source": "Hindi Alam na Source", + "sources_limited": "Maaaring limitado ang mga source dahil sa error ng provider.", + "episodes": "Mga Episode", + "specials": "Mga Special", + "season": "Season {{season}}", + "stream": "Stream {{number}}", + "subtitles": "Mga Subtitle", + "built_in": "Built-in", + "addons": "Mga Addon", + "style": "Istilo", + "none": "Wala", + "search_online_subtitles": "Maghanap ng Online Subtitles", + "preview": "Preview", + "quick_presets": "Quick Presets", + "default": "Default", + "yellow": "Dilaw", + "high_contrast": "High Contrast", + "large": "Malaki", + "core": "Core", + "font_size": "Laki ng Font", + "show_background": "Ipakita ang Background", + "advanced": "Advanced", + "position": "Posisyon", + "text_color": "Kulay ng Text", + "align": "Alignment", + "bottom_offset": "Bottom Offset", + "background_opacity": "Background Opacity", + "text_shadow": "Text Shadow", + "on": "On", + "off": "Off", + "outline_color": "Kulay ng Outline", + "outline": "Outline", + "outline_width": "Lapad ng Outline", + "letter_spacing": "Letter Spacing", + "line_height": "Line Height", + "timing_offset": "Timing Offset (s)", + "visual_sync": "Visual Sync", + "timing_hint": "I-nudge ang subtitle nang mas maaga (-) o mamaya (+) para mag-sync.", + "reset_defaults": "I-reset sa default", + "mark_intro_start": "Markahan ang Simula ng Intro", + "mark_intro_end": "Markahan ang Tapos ng Intro", + "intro_start_marked": "Ang simula ng intro ay namarkahan na", + "intro_submitted": "Matagumpay na naisumite ang intro", + "intro_submit_failed": "Bigo sa pagsumite ng intro" + }, + "downloads": { + "title": "Mga Download", + "no_downloads": "Wala pang Downloads", + "no_downloads_desc": "Lilitaw dito ang mga dinownload na content para sa offline viewing", + "explore": "Mag-explore ng Content", + "path_copied": "Nakopya na ang Path", + "path_copied_desc": "Nakopya na sa clipboard ang local file path", + "copied": "Nakopya na", + "incomplete": "Hindi Tapos ang Download", + "incomplete_desc": "Hindi pa tapos ang pag-download", + "not_available": "Hindi Available", + "not_available_desc": "Magiging available lang ang file path kapag tapos na ang download.", + "status_downloading": "Nagda-download", + "status_completed": "Tapos na", + "status_paused": "Naka-pause", + "status_error": "Error", + "status_queued": "Naka-queue", + "status_unknown": "Hindi Alam", + "provider": "Provider", + "streaming_playlist_warning": "Maaaring hindi mag-play - streaming playlist", + "remaining": "natitira", + "not_ready": "Download ay hindi pa handa", + "not_ready_desc": "Mangyaring maghintay hanggang matapos ang pag-download.", + "filter_all": "Lahat", + "filter_active": "Aktibo", + "filter_done": "Tapos na", + "filter_paused": "Naka-pause", + "no_filter_results": "Walang {{filter}} na downloads", + "try_different_filter": "Subukan ang ibang filter", + "limitations_title": "Limitasyon sa Download", + "limitations_msg": "• Ang mga file na mas maliit sa 1MB ay karaniwang M3U8 streaming playlists at hindi maaaring i-download para sa offline viewing.", + "remove_title": "Alisin ang Download", + "remove_confirm": "Alisin ang \"{{title}}\"{{season_episode}}?", + "cancel": "Kanselahin", + "remove": "Alisin" + }, + "addons": { + "title": "Mga Addon", + "reorder_mode": "Reorder Mode", + "reorder_info": "Ang mga addon sa itaas ang may mas mataas na priyoridad", + "add_addon_placeholder": "Addon URL", + "add_button": "Magdagdag ng Addon", + "my_addons": "Aking mga Addon", + "community_addons": "Community Addons", + "no_addons": "Walang nakatalagang addon", + "uninstall_title": "I-uninstall ang Addon", + "uninstall_message": "Sigurado ka bang gusto mong i-uninstall ang {{name}}?", + "uninstall_button": "I-uninstall", + "install_success": "Matagumpay na na-install ang addon", + "install_error": "Bigo sa pag-install ng addon", + "load_error": "Bigo sa pag-load ng mga addon", + "fetch_error": "Bigo sa pagkuha ng detalye ng addon", + "invalid_url": "Mangyaring maglagay ng tamang addon URL", + "configure": "I-configure", + "version": "Bersyon: {{version}}", + "installed_addons": "MGA NAKA-INSTALL NA ADDON", + "reorder_drag_title": "I-DRAG ANG MGA ADDON PARA MAG-REORDER", + "install": "I-install", + "config_unavailable_title": "Hindi Available ang Configuration", + "config_unavailable_msg": "Hindi mahanap ang configuration URL para sa addon na ito.", + "cannot_open_config_title": "Hindi Mabuksan ang Configuration", + "cannot_open_config_msg": "Hindi mabuksan ang configuration URL ({{url}}).", + "description": "Deskripsyon", + "supported_types": "Mga Suportadong Uri", + "catalogs": "Mga Catalog", + "no_description": "Walang available na deskripsyon", + "overview": "OVERVIEW", + "no_categories": "Walang kategorya", + "pre_installed": "PRE-INSTALLED" + }, + "trakt": { + "title": "Mga Setting ng Trakt", + "settings_title": "Mga Setting ng Trakt", + "connect_title": "Kumonekta sa Trakt", + "connect_desc": "I-sync ang iyong history, watchlist, at koleksyon sa Trakt.tv", + "sign_in": "Mag-sign In gamit ang Trakt", + "sign_out": "Mag-sign Out", + "sign_out_confirm": "Sigurado ka bang gusto mong mag-sign out sa iyong Trakt account?", + "joined": "Sumali noong {{date}}", + "sync_settings_title": "Mga Setting ng Sync", + "sync_info": "Kapag nakakonekta sa Trakt, ang buong history ay direktang naka-sync mula sa API at hindi isinusulat sa local storage. Ang iyong Continue Watching list ay nagpapakita ng iyong global Trakt progress.", + "auto_sync_label": "Auto-sync ng playback progress", + "auto_sync_desc": "Awtomatikong i-sync ang watch progress sa Trakt", + "import_history_label": "I-import ang watched history", + "import_history_desc": "Gamitin ang \"Sync Now\" para i-import ang iyong watch history at progress mula sa Trakt", + "sync_now_button": "I-sync Na", + "display_settings_title": "Mga Setting ng Display", + "show_comments_label": "Ipakita ang mga Komento sa Trakt", + "show_comments_desc": "Ipakita ang mga komento sa Trakt sa metadata screen kapag available", + "maintenance_title": "Kasalukuyang Inaayos", + "maintenance_unavailable": "Hindi Available ang Trakt", + "maintenance_desc": "Pansamantalang itinigil ang Trakt integration para sa maintenance. Lahat ng syncing at authentication ay disabled muna.", + "maintenance_button": "Serbisyo ay nasa Maintenance", + "auth_success_title": "Matagumpay na Nakakonekta", + "auth_success_msg": "Matagumpay na naikonekta ang iyong Trakt account.", + "auth_error_title": "Error sa Authentication", + "auth_error_msg": "Bigo sa pag-authenticate sa Trakt.", + "auth_error_generic": "Nagkaroon ng error habang nag-a-authenticate.", + "sign_out_error": "Bigo sa pag-sign out sa Trakt.", + "sync_complete_title": "Tapos na ang Sync", + "sync_success_msg": "Matagumpay na na-sync ang iyong watch progress sa Trakt.", + "sync_error_msg": "Bigo ang pag-sync. Pakisubukan muli." + }, + "simkl": { + "title": "Mga Setting ng Simkl", + "settings_title": "Mga Setting ng Simkl", + "connect_title": "Kumonekta sa Simkl", + "connect_desc": "I-sync ang iyong watch history at i-track ang iyong mga pinapanood", + "sign_in": "Mag-sign In gamit ang Simkl", + "sign_out": "Idiskonekta", + "sign_out_confirm": "Sigurado ka bang gusto mong idiskonekta ang Simkl?", + "syncing_desc": "Ang iyong mga napanood ay nina-sync na sa Simkl.", + "auth_success_title": "Matagumpay na Nakakonekta", + "auth_success_msg": "Matagumpay na naikonekta ang iyong Simkl account.", + "auth_error_title": "Error sa Authentication", + "auth_error_msg": "Bigo sa pag-authenticate sa Simkl.", + "auth_error_generic": "Nagkaroon ng error habang nag-a-authenticate.", + "sign_out_error": "Bigo sa pagdisidkonekta sa Simkl.", + "config_error_title": "Error sa Configuration", + "config_error_msg": "Ang Simkl Client ID ay wala sa environment variables.", + "conflict_title": "Conflict", + "conflict_msg": "Hindi ka maaaring kumonekta sa Simkl habang nakakonekta ang Trakt. Pakidiskonekta muna ang Trakt.", + "disclaimer": "Ang Nuvio ay hindi kaanib ng Simkl." + }, + "tmdb_settings": { + "title": "Mga Setting ng TMDb", + "metadata_enrichment": "Metadata Enrichment", + "metadata_enrichment_desc": "Pagandahin ang metadata ng iyong content gamit ang TMDb data.", + "enable_enrichment": "I-enable ang Enrichment", + "enable_enrichment_desc": "Dinaragdagan ang addon metadata gamit ang TMDb para sa cast, certification, logos, at production info.", + "localized_text": "Localized na Text", + "localized_text_desc": "Kunin ang mga titulo at deskripsyon sa iyong gustong wika mula sa TMDb.", + "language": "Wika", + "change": "Baguhin", + "logo_preview": "Preview ng Logo", + "logo_preview_desc": "Ipinapakita nito kung paano lilitaw ang mga localized na logo sa napiling wika.", + "example": "Halimbawa:", + "no_logo": "Walang available na logo", + "enrichment_options": "Mga Option sa Enrichment", + "enrichment_options_desc": "Kontrolin kung anong data ang kukunin mula sa TMDb.", + "cast_crew": "Cast at Crew", + "cast_crew_desc": "Mga artista, direktor, at manunulat na may profile photos", + "title_description": "Titulo at Deskripsyon", + "title_description_desc": "Gamitin ang localized na titulo at overview mula sa TMDb", + "title_logos": "Mga Logo ng Titulo", + "title_logos_desc": "Mataas na kalidad na mga image ng titulo", + "banners_backdrops": "Mga Banner at Backdrop", + "banners_backdrops_desc": "Mataas na resolution na mga backdrop image", + "certification": "Certification ng Content", + "certification_desc": "Mga age rating (PG-13, R, TV-MA, atbp.)", + "recommendations": "Mga Rekomendasyon", + "recommendations_desc": "Mga mungkahi para sa katulad na content", + "episode_data": "Data ng Episode", + "episode_data_desc": "Mga thumbnail at impormasyon ng episode", + "season_posters": "Mga Poster ng Season", + "season_posters_desc": "Mga poster image na para sa bawat season", + "production_info": "Impormasyon ng Produksyon", + "production_info_desc": "Mga network at production company na may logo", + "movie_details": "Mga Detalye ng Pelikula", + "movie_details_desc": "Budget, kita, runtime, at tagline", + "tv_details": "Mga Detalye ng TV Show", + "tv_details_desc": "Status, bilang ng season, mga network, at tagalikha", + "movie_collections": "Koleksyon ng Pelikula", + "movie_collections_desc": "Mga franchise na pelikula (Marvel, Star Wars, atbp.)", + "api_configuration": "Configuration ng API", + "api_configuration_desc": "I-configure ang iyong TMDb API access.", + "custom_api_key": "Custom API Key", + "custom_api_key_desc": "Gamitin ang sarili mong TMDb API key para sa mas magandang performance.", + "custom_key_active": "Aktibo ang Custom API key", + "api_key_required": "Kailangan ng API key", + "api_key_placeholder": "I-paste ang iyong TMDb API key (v3)", + "how_to_get_key": "Paano kumuha ng TMDb API key?", + "built_in_key_msg": "Kasalukuyang gamit ang built-in API key.", + "cache_size": "Laki ng Cache", + "clear_cache": "I-clear ang Cache", + "cache_days": "Ang mga TMDb response ay naka-cache ng 7 araw.", + "choose_language": "Pumili ng Wika", + "choose_language_desc": "Pumili ng iyong gustong wika para sa TMDb content", + "popular": "Sikat", + "all_languages": "Lahat ng Wika", + "search_results": "Mga Resulta ng Paghahanap", + "no_languages_found": "Walang wikang nahanap para sa \"{{query}}\"", + "clear_search": "I-clear ang Paghahanap", + "clear_cache_title": "I-clear ang TMDB Cache", + "clear_cache_msg": "Buburahin nito ang lahat ng cached TMDB data ({{size}}). Maaaring bumagal ang pag-load pansamantala.", + "clear_cache_success": "Matagumpay na na-clear ang TMDB cache.", + "clear_cache_error": "Bigo sa pag-clear ng cache.", + "clear_api_key_title": "I-clear ang API Key", + "clear_api_key_msg": "Sigurado ka bang gusto mong alisin ang iyong custom API key?", + "clear_api_key_success": "Matagumpay na na-clear ang API key", + "clear_api_key_error": "Bigo sa pag-clear ng API key", + "empty_api_key": "Hindi maaaring walang laman ang API Key.", + "invalid_api_key": "Maling API key. Pakisuri at subukan muli.", + "save_error": "Nagkaroon ng error habang nag-i-save. Pakisubukan muli.", + "using_builtin_key": "Gamit na ngayon ang built-in TMDb API key.", + "using_custom_key": "Gamit na ngayon ang iyong custom TMDb API key.", + "enter_custom_key": "Mangyaring ilagay at i-save ang iyong custom TMDb API key.", + "key_verified": "API key ay na-verify at matagumpay na na-save." + }, + "settings": { + "language": "Wika", + "select_language": "Pumili ng Wika", + "english": "Ingles", + "portuguese": "Portuguese", + "portuguese_br": "Portuguese (Brazil)", + "portuguese_pt": "Portuguese (Portugal)", + "german": "German", + "arabic": "Arabic", + "spanish": "Spanish", + "french": "French", + "italian": "Italian", + "croatian": "Croatian", + "chinese": "Chinese (Simplified)", + "hindi": "Hindi", + "serbian": "Serbian", + "hebrew": "Hebreo", + "bulgarian": "Bulgaro", + "polish": "Polako", + "czech": "Tsek", + "turkish": "Turko", + "slovenian": "Eslobeno", + "macedonian": "Macedonio", + "russian": "Ruso", + "filipino": "Filipino", + "dutch_nl": "Dutch (Netherlands)", + "romanian": "Romanyano", + "albanian": "Albano", + "account": "Account", + "content_discovery": "Content at Discovery", + "appearance": "Appearance", + "integrations": "Integrations", + "playback": "Playback", + "backup_restore": "Backup at Restore", + "updates": "Mga Update", + "about": "Tungkol sa App", + "developer": "Developer", + "cache": "Cache", + "title": "Mga Setting", + "settings_title": "Mga Setting", + "sign_in_sync": "Mag-sign in para mag-sync", + "add_catalogs_sources": "Addons, catalog, at sources", + "player_trailers_downloads": "Player, trailer, downloads", + "mdblist_tmdb_ai": "MDBList, TMDB, AI", + "check_updates": "Mag-check ng mga update", + "clear_mdblist_cache": "I-clear ang MDBList Cache", + "cache_management": "PAMAMAHALA NG CACHE", + "downloads_counter": "downloads at nadaragdagan pa", + "made_with_love": "Gawa nang may ❤️ nina Tapframe at mga kaibigan", + "sections": { + "information": "IMPORMASYON", + "account": "ACCOUNT", + "theme": "TEMA", + "layout": "LAYOUT", + "sources": "SOURCES", + "catalogs": "MGA CATALOG", + "discovery": "DISCOVERY", + "metadata": "METADATA", + "ai_assistant": "AI ASSISTANT", + "video_player": "VIDEO PLAYER", + "audio_subtitles": "AUDIO AT MGA SUBTITLE", + "media": "MEDIA", + "notifications": "MGA NOTIFICATION", + "testing": "TESTING", + "danger_zone": "DANGER ZONE" + }, + "items": { + "legal": "Legal at Disclaimer", + "privacy_policy": "Privacy Policy", + "report_issue": "Mag-report ng Isyu", + "version": "Bersyon", + "contributors": "Mga Contributor", + "view_contributors": "Tingnan ang lahat ng contributor", + "theme": "Tema", + "episode_layout": "Layout ng Episode", + "streams_backdrop": "Backdrop ng mga Stream", + "streams_backdrop_desc": "Ipakita ang blurred backdrop sa mobile streams", + "addons": "Mga Addon", + "installed": "naka-install", + "debrid_integration": "Debrid Integration", + "debrid_desc": "Ikonekta ang Torbox", + "plugins": "Mga Plugin", + "plugins_desc": "Pamahalaan ang mga plugin at repository", + "catalogs": "Mga Catalog", + "active": "aktibo", + "home_screen": "Home Screen", + "home_screen_desc": "Layout at nilalaman", + "continue_watching": "Ituloy ang Panonood", + "continue_watching_desc": "Cache at gawi ng playback", + "show_discover": "Ipakita ang Discover Section", + "show_discover_desc": "Ipakita ang discover content sa Search", + "mdblist": "MDBList", + "mdblist_connected": "Nakakonekta", + "mdblist_desc": "I-enable para sa mga rating at review", + "simkl": "Simkl", + "simkl_connected": "Nakakonekta", + "simkl_desc": "I-track ang iyong mga pinapanood", + "tmdb": "TMDB", + "tmdb_desc": "Source provider ng metadata at logo", + "openrouter": "OpenRouter API", + "openrouter_connected": "Nakakonekta", + "openrouter_desc": "Ilagay ang API key para sa AI chat", + "video_player": "Video Player", + "built_in": "Built-in", + "external": "External", + "preferred_audio": "Gustong Wika ng Audio", + "preferred_subtitle": "Gustong Wika ng Subtitle", + "subtitle_source": "Priority ng Subtitle Source", + "auto_select_subs": "Auto-Select ng mga Subtitle", + "auto_select_subs_desc": "Awtomatikong pumili ng subtitle ayon sa preference", + "show_trailers": "Ipakita ang mga Trailer", + "show_trailers_desc": "Ipakita ang mga trailer sa hero section", + "enable_downloads": "I-enable ang mga Download", + "enable_downloads_desc": "Ipakita ang tab ng Downloads at i-save ang mga stream", + "notifications": "Mga Notification", + "notifications_desc": "Mga paalala para sa episode", + "developer_tools": "Developer Tools", + "developer_tools_desc": "Mga option para sa testing at debug", + "test_onboarding": "I-test ang Onboarding", + "reset_onboarding": "I-reset ang Onboarding", + "test_announcement": "I-test ang Announcement", + "test_announcement_desc": "Ipakita ang what's new overlay", + "reset_campaigns": "I-reset ang mga Campaign", + "reset_campaigns_desc": "I-clear ang mga campaign impression", + "clear_all_data": "I-clear ang Lahat ng Data", + "clear_all_data_desc": "I-reset ang lahat ng settings at cached data" + }, + "options": { + "horizontal": "Horizontal", + "vertical": "Vertical", + "internal_first": "Internal Muna", + "internal_first_desc": "Unahin ang embedded subtitles", + "external_first": "External Muna", + "external_first_desc": "Unahin ang addon subtitles", + "any_available": "Kahit Ano", + "any_available_desc": "Gamitin ang unang available na track" + }, + "clear_data_desc": "I-re-reset nito ang lahat ng settings at buburahin ang lahat ng cached data. Sigurado ka ba?", + "app_updates": "Mga Update ng App", + "about_nuvio": "Tungkol sa Nuvio" + }, + "privacy": { + "title": "Privacy at Data", + "settings_desc": "Kontrolin ang telemetry at pagkuha ng data", + "info_title": "Mahalaga ang Iyong Privacy", + "info_description": "Kontrolin kung anong data ang kinukuha at ibinabahagi.", + "analytics_enabled_title": "Naka-enable ang Analytics", + "analytics_enabled_message": "Kukuha ng usage data para mapaganda ang app.", + "disable_error_reporting_title": "I-disable ang Error Reporting?", + "disable_error_reporting_message": "Hindi kami manonotify sa mga crash o isyu na mararanasan mo.", + "enable_session_replay_title": "I-enable ang Session Replay?", + "enable_session_replay_message": "I-re-record ang iyong screen kapag may error para malaman ang nangyari.", + "enable_pii_title": "I-enable ang PII Collection?", + "enable_pii_message": "Pinapayagan nito ang pagkuha ng impormasyon gaya ng IP address para sa diagnosis.", + "disable_all_title": "I-disable ang Lahat ng Telemetry?", + "disable_all_message": "I-di-disable nito ang lahat ng analytics at error reporting.", + "disable_all_button": "I-disable Lahat", + "all_disabled_title": "Lahat ng Telemetry ay Disabled", + "all_disabled_message": "Lahat ng pagkuha ng data ay itinigil na.", + "reset_title": "I-reset sa Recommended", + "reset_message": "Na-reset na ang privacy settings sa recommended defaults.", + "section_analytics": "ANALYTICS", + "analytics_title": "Analytics ng Paggamit", + "analytics_description": "Kumuha ng anonymous na pattern ng paggamit", + "section_error_reporting": "REPORTING NG ERROR", + "error_reporting_title": "Mga Crash Report", + "error_reporting_description": "Magpadala ng anonymous crash reports", + "session_replay_title": "Session Replay", + "session_replay_description": "I-record ang screen kapag may error", + "pii_title": "Isama ang Device Info", + "pii_description": "Ipadala ang IP address at detalye ng device sa mga report", + "section_quick_actions": "MABILIS NA AKSYON", + "disable_all": "I-disable ang Lahat ng Telemetry", + "disable_all_desc": "I-off ang lahat ng pagkuha ng data", + "reset_recommended": "I-reset sa Recommended", + "reset_recommended_desc": "Privacy-first defaults na may error reporting", + "section_learn_more": "ALAMIN PA", + "privacy_policy": "Privacy Policy", + "current_settings": "Buod ng Kasalukuyang Settings", + "summary_analytics": "Analytics", + "summary_errors": "Mga Error Report", + "summary_replay": "Session Replay", + "summary_pii": "Impormasyon ng Device", + "restart_note_detailed": "* Ang mga pagbabago sa analytics at error reporting ay epektibo agad. Ang session replay at PII ay nangangailangan ng app restart." + }, + "ai_settings": { + "title": "AI Assistant", + "info_title": "Chat na Gamit ang AI", + "info_desc": "Magtanong tungkol sa kahit anong pelikula o TV show gamit ang advanced AI.", + "feature_1": "Konteksto at pagsusuri na para sa episode", + "feature_2": "Paliwanag sa plot at character insights", + "feature_3": "Trivia at mga katotohanan", + "feature_4": "Sarili mong libreng OpenRouter API key", + "api_key_section": "OPENROUTER API KEY", + "api_key_label": "API Key", + "api_key_desc": "Ilagay ang iyong OpenRouter API key para ma-enable ang AI chat", + "save_api_key": "I-save ang API Key", + "saving": "Inia-save...", + "update": "I-update", + "remove": "Alisin", + "get_free_key": "Kumuha ng Libreng API Key mula sa OpenRouter", + "enable_chat": "I-enable ang AI Chat", + "enable_chat_desc": "Lilitaw ang Ask AI button sa mga pahina ng content.", + "chat_enabled": "Naka-enable ang AI Chat", + "chat_enabled_desc": "Maaari ka nang magtanong tungkol sa mga pelikula at shows!", + "how_it_works": "Paano ito gumagana", + "how_it_works_desc": "• Ang OpenRouter ay nagbibigay ng access sa maraming AI models\n• Mananatiling private ang iyong API key\n• Ang libreng tier ay may sapat na limit sa paggamit", + "error_invalid_key": "Mangyaring maglagay ng tamang API key", + "error_key_format": "Ang OpenRouter API keys ay dapat magsimula sa \"sk-or-\"", + "success_saved": "Matagumpay na na-save ang OpenRouter API key!", + "error_save": "Bigo sa pag-save ng API key", + "confirm_remove_title": "Alisin ang API Key", + "confirm_remove_msg": "Sigurado ka bang gusto mong alisin ang iyong API key?", + "success_removed": "Matagumpay na naalis ang API key", + "error_remove": "Bigo sa pag-alis ng API key" + }, + "catalog_settings": { + "title": "Mga Catalog", + "layout_phone": "LAYOUT NG CATALOG SCREEN (PHONE)", + "posters_per_row": "Poster sa bawat row", + "auto": "Auto", + "show_titles": "Ipakita ang Titulo ng Poster", + "show_titles_desc": "Ipakita ang pangalan sa ibaba ng bawat poster", + "phone_only_hint": "Para sa mga phone lang ito.", + "catalogs_group": "Mga Catalog", + "enabled_count": "{{enabled}} sa {{total}} ay naka-enable", + "rename_hint": "I-long-press ang catalog para mapalitan ang pangalan", + "rename_modal_title": "Palitan ang Pangalan ng Catalog", + "rename_placeholder": "Ilagay ang bagong pangalan", + "error_save_name": "Hindi ma-save ang custom na pangalan." + }, + "continue_watching_settings": { + "title": "Ituloy ang Panonood", + "playback_behavior": "GAWI NG PLAYBACK", + "use_cached": "Gamitin ang Cached Streams", + "use_cached_desc": "Direktang bubuksan ang player gamit ang mga naunang stream.", + "open_metadata": "Buksan ang Metadata Screen", + "open_metadata_desc": "Buksan ang Metadata screen sa halip na Streams screen.", + "card_appearance": "ITSURA NG CARD", + "card_style": "Istilo ng Card", + "card_style_desc": "Pumili kung paano lilitaw ang mga item sa home screen", + "wide": "Malapad", + "poster": "Poster", + "cache_settings": "MGA SETTING NG CACHE", + "cache_duration": "Tagal ng Stream Cache", + "cache_duration_desc": "Gaano katagal itatago ang cached stream links bago mag-expire", + "important_note": "Mahalagang Paalala", + "important_note_text": "Maaaring mag-expire ang ilang links kahit hindi pa tapos ang cache duration.", + "how_it_works": "Paano ito gumagana", + "how_it_works_cached": "• Ang mga stream ay naka-cache sa napiling tagal pagkatapos i-play\n• Bine-verify ang mga stream bago gamitin\n• Kapag expired ang cache, babalik ito sa content screen", + "how_it_works_uncached": "• Kapag disabled ang cached streams, content screens ang bubuksan\n• Maaari mong piliin ang Metadata o Streams screen\n• Ang Metadata screen ay may kumpletong detalye", + "changes_saved": "Na-save na ang mga pagbabago", + "min": "min", + "hour": "oras", + "hours": "oras" + }, + "contributors": { + "title": "Mga Contributor", + "special_mentions": "Espesyal na Pagbanggit", + "tab_contributors": "Mga Contributor", + "tab_special": "Espesyal", + "tab_donors": "Mga Donor", + "manager_role": "Community Manager", + "manager_desc": "Nagpapatakbo ng Discord at Reddit communities para sa Nuvio", + "sponsor_role": "Sponsor ng Server", + "sponsor_desc": "Nag-sponsor ng server infrastructure para sa Nuvio", + "mod_role": "Discord Mod", + "mod_desc": "Tumutulong sa pag-moderate ng Nuvio Discord community", + "loading": "Naglo-load...", + "discord_user": "User sa Discord", + "contributions": "mga kontribusyon", + "gratitude_title": "Nagpapasalamat kami sa bawat kontribusyon", + "gratitude_desc": "Ang bawat linya ng code, bug report, at suhestyon ay nakakatulong para mas mapaganda ang Nuvio para sa lahat", + "special_thanks_title": "Espesyal na Pasasalamat", + "special_thanks_desc": "Ang mga kahanga-hangang taong ito ay tumutulong upang mapanatiling maayos ang Nuvio community at online ang mga server", + "donors_desc": "Salamat sa paniniwala sa aming ginagawa. Ang inyong suporta ang nagpapanatiling libre sa Nuvio at patuloy na nag-i-improve.", + "latest_donations": "Pinakabago", + "leaderboard": "Leaderboard", + "loading_donors": "Naglo-load ng mga donor...", + "no_donors": "Wala pang mga donor", + "error_rate_limit": "Lumampas na sa GitHub API rate limit. Pakisubukan muli mamaya.", + "error_failed": "Bigo sa pag-load ng mga contributor. Pakisuri ang iyong internet connection.", + "retry": "Subukan Uli", + "no_contributors": "Walang nahanap na contributor", + "loading_contributors": "Naglo-load ng mga contributor..." + }, + "debrid": { + "title": "Debrid Integration", + "description_torbox": "I-unlock ang 4K high-quality streams at mabilis na speed sa pamamagitan ng pag-integrate ng Torbox. Ilagay ang iyong API Key sa ibaba para sa instant upgrade.", + "description_torrentio": "I-configure ang Torrentio para makakuha ng torrent streams para sa mga pelikula at TV shows. Kailangan ng debrid service para makapag-stream.", + "tab_torbox": "TorBox", + "tab_torrentio": "Torrentio", + "status_connected": "Nakakonekta", + "status_disconnected": "Nadiskonekta", + "enable_addon": "I-enable ang Addon", + "disconnect_button": "Idiskonekta at Alisin", + "disconnect_loading": "Idididiskonekta...", + "account_info": "Impormasyon ng Account", + "plan": "Plan", + "plan_free": "Libre", + "plan_essential": "Essential ($3/mo)", + "plan_pro": "Pro ($10/mo)", + "plan_standard": "Standard ($5/mo)", + "plan_unknown": "Hindi Alam", + "expires": "Mapapaso sa", + "downloaded": "Na-download na", + "status_active": "Aktibo", + "connected_title": "✓ Nakakonekta sa TorBox", + "connected_desc": "Aktibo ang iyong TorBox addon at nagbibigay ng premium streams.", + "configure_title": "I-configure ang Addon", + "configure_desc": "I-customize ang iyong streaming. I-sort ayon sa quality, i-filter ang laki ng file, at iba pa.", + "open_settings": "Buksan ang Settings", + "what_is_debrid": "Ano ang Debrid Service?", + "enter_api_key": "Ilagay ang iyong API Key", + "connect_button": "Iikonekta at I-install", + "connecting": "Kumokonekta...", + "unlock_speeds_title": "I-unlock ang Premium Speeds", + "unlock_speeds_desc": "Kumuha ng Torbox subscription para sa high-quality streams na walang buffering.", + "get_subscription": "Kumuha ng Subscription", + "powered_by": "Powered by", + "disclaimer_torbox": "Ang Nuvio ay hindi kaanib ng Torbox sa anumang paraan.", + "disclaimer_torrentio": "Ang Nuvio ay hindi kaanib ng Torrentio sa anumang paraan.", + "installed_badge": "✓ NAKA-INSTALL", + "promo_title": "⚡ Kailangan ng Debrid Service?", + "promo_desc": "Kumuha ng TorBox para sa mabilis na 4K streaming na walang buffering.", + "promo_button": "Kumuha ng TorBox Subscription", + "service_label": "Debrid Service *", + "api_key_label": "API Key *", + "sorting_label": "Pag-sort", + "exclude_qualities": "I-exclude ang mga Quality", + "priority_languages": "Mga Priority na Wika", + "max_results": "Max Results", + "additional_options": "Iba pang Option", + "no_download_links": "Huwag ipakita ang download links", + "no_debrid_catalog": "Huwag ipakita ang debrid catalog", + "install_button": "I-install ang Torrentio", + "installing": "Inia-install...", + "update_button": "I-update ang Configuration", + "updating": "Inia-update...", + "remove_button": "Alisin ang Torrentio", + "error_api_required": "Kailangan ng API Key", + "error_api_required_desc": "Mangyaring ilagay ang iyong debrid API key para ma-install ang Torrentio.", + "success_installed": "Matagumpay na na-install ang Torrentio addon!", + "success_removed": "Matagumpay na naalis ang Torrentio addon", + "alert_disconnect_title": "Idiskonekta ang Torbox", + "alert_disconnect_msg": "Sigurado ka bang gusto mong idiskonekta ang Torbox? Maalis ang addon at ang iyong API key." + }, + "home_screen": { + "title": "Mga Setting ng Home Screen", + "changes_applied": "Nailapat na ang mga Pagbabago", + "display_options": "MGA OPTION SA DISPLAY", + "show_hero": "Ipakita ang Hero Section", + "show_hero_desc": "Tinatampok na content sa itaas", + "show_this_week": "Ipakita ang 'Ngayong Linggo'", + "show_this_week_desc": "Mga bagong episode ngayong linggo", + "select_catalogs": "Pumili ng mga Catalog", + "all_catalogs": "Lahat ng catalog", + "selected": "napili", + "hero_layout": "Hero Layout", + "layout_legacy": "Legacy", + "layout_carousel": "Carousel", + "layout_appletv": "Apple TV", + "layout_desc": "Full-width banner, swipeable cards, o Apple TV style", + "featured_source": "Featured Source", + "using_catalogs": "Gumagamit ng mga Catalog", + "manage_selected_catalogs": "Pamahalaan ang mga napiling catalog", + "dynamic_bg": "Dynamic Hero Background", + "dynamic_bg_desc": "Blurred na banner sa likod ng carousel", + "performance_note": "Maaaring makaapekto sa performance ng mga low-end na device.", + "posters": "Mga Poster", + "show_titles": "Ipakita ang mga Titulo", + "poster_size": "Laki ng Poster", + "poster_corners": "Kanto ng Poster", + "size_small": "Maliit", + "size_medium": "Katamtaman", + "size_large": "Malaki", + "corners_square": "Kanto (Square)", + "corners_rounded": "Rounded", + "corners_pill": "Pill", + "about_these_settings": "TUNGKOL SA MGA SETTING NA ITO", + "about_desc": "Kinokontrol nito kung paano ipinapakita ang content sa iyong Home screen. Mailalapat agad ang mga pagbabago.", + "hero_catalogs": { + "title": "Mga Catalog sa Hero Section", + "select_all": "Piliin Lahat", + "clear_all": "I-clear Lahat", + "info": "Pumili ng mga catalog na ipapakita sa hero section. Kung walang pipiliin, lahat ay gagamitin. Huwag kalimutang i-Save.", + "settings_saved": "Na-save na ang Settings", + "error_load": "Bigo sa pag-load ng mga catalog", + "movies": "Mga Pelikula", + "tv_shows": "Mga TV Show" + } + }, + "calendar": { + "title": "Kalendaryo", + "loading": "Naglo-load ng kalendaryo...", + "no_scheduled_episodes": "Walang nakatakdang episode", + "check_back_later": "Bumalik na lang mamaya", + "showing_episodes_for": "Ipinapakita ang mga episode para sa {{date}}", + "show_all_episodes": "Ipakita Lahat ng Episode", + "no_episodes_for": "Walang episode para sa {{date}}", + "no_upcoming_found": "Walang nahanap na paparating na episode", + "add_series_desc": "Magdagdag ng series sa iyong library para makita ang mga paparating na episode dito" + }, + "mdblist": { + "title": "Mga Source ng Rating", + "status_disabled": "MDBList ay Disabled", + "status_active": "Aktibo ang API Key", + "status_required": "Kailangan ng API Key", + "status_disabled_desc": "Ang MDBList functionality ay kasalukuyang disabled.", + "status_active_desc": "Naka-enable ang mga rating mula sa MDBList.", + "status_required_desc": "Ilagay ang iyong key sa ibaba para ma-enable ang mga rating.", + "enable_toggle": "I-enable ang MDBList", + "enable_toggle_desc": "I-on/off ang lahat ng MDBList functionality", + "api_section": "API Key", + "placeholder": "I-paste ang iyong MDBList API key", + "save": "I-save", + "clear": "I-clear ang Key", + "rating_providers": "Mga Provider ng Rating", + "rating_providers_desc": "Pumili kung aling mga rating ang ipapakita sa app", + "how_to": "Paano kumuha ng API key", + "step_1": "Mag-log in sa", + "step_1_link": "MDBList website", + "step_2": "Pumunta sa", + "step_2_settings": "Settings", + "step_2_api": "API", + "step_2_end": "section.", + "step_3": "Gumawa ng bagong key at i-copy ito.", + "go_to_website": "Pumunta sa MDBList", + "alert_clear_title": "I-clear ang API Key", + "alert_clear_msg": "Sigurado ka bang gusto mong alisin ang naka-save na API key?", + "success_saved": "Matagumpay na na-save ang API key.", + "error_empty": "Hindi maaaring walang laman ang API Key.", + "error_save": "Nagkaroon ng error habang nag-i-save. Pakisubukan muli.", + "api_key_empty_error": "Hindi maaaring walang laman ang API Key.", + "success_cleared": "Matagumpay na na-clear ang API key", + "error_clear": "Bigo sa pag-clear ng API key" + }, + "notification": { + "title": "Mga Setting ng Notification", + "section_general": "Pangkalahatan", + "enable_notifications": "I-enable ang mga Notification", + "section_types": "Mga Uri ng Notification", + "new_episodes": "Mga Bagong Episode", + "upcoming_shows": "Mga Paparating na Show", + "reminders": "Mga Paalala", + "section_timing": "Timing ng Notification", + "timing_desc": "Kailan ka dapat i-notify bago ipalabas ang isang episode?", + "hours_1": "1 oras", + "hours_suffix": "oras", + "section_status": "Status ng Notification", + "stats_upcoming": "Paparating", + "stats_this_week": "Ngayong Linggo", + "stats_total": "Kabuuan", + "sync_button": "I-sync ang Library at Trakt", + "syncing": "Sini-sync...", + "sync_desc": "Awtomatikong sini-sync ang notifications para sa lahat ng show sa iyong library at Trakt watchlist.", + "section_advanced": "Advanced", + "reset_button": "I-reset Lahat ng Notification", + "test_button": "I-test ang Notification (5 sec)", + "test_notification_in": "Notification sa loob ng {{seconds}}s...", + "test_notification_text": "Lilitaw ang notification sa loob ng {{seconds}} segundo", + "alert_reset_title": "I-reset ang mga Notification", + "alert_reset_msg": "Ika-cancel nito ang lahat ng nakatakdang notification. Sigurado ka ba?", + "alert_reset_success": "Lahat ng notification ay na-reset na", + "alert_sync_complete": "Tapos na ang Sync", + "alert_sync_msg": "Matagumpay na na-sync ang notifications.\n\nNakatakda: {{upcoming}} paparating na episode\nNgayong linggo: {{thisWeek}} episode", + "alert_test_scheduled": "Nakatakda na ang test notification" + }, + "backup": { + "title": "Backup at Restore", + "options_title": "Mga Option sa Backup", + "options_desc": "Pumili ng isasama sa iyong backup", + "section_core": "Core Data", + "section_addons": "Mga Addon at Integration", + "section_settings": "Settings at Preferences", + "library_label": "Library", + "library_desc": "Iyong mga na-save na pelikula at TV shows", + "watch_progress_label": "Watch Progress", + "watch_progress_desc": "Mga posisyon sa 'Ituloy ang Panonood'", + "addons_label": "Mga Addon", + "addons_desc": "Mga naka-install na Stremio addon", + "plugins_label": "Mga Plugin", + "plugins_desc": "Mga custom scraper configuration", + "trakt_label": "Trakt Integration", + "trakt_desc": "I-sync ang data at authentication tokens", + "app_settings_label": "App Settings", + "app_settings_desc": "Tema, preferences, at mga configuration", + "user_prefs_label": "User Preferences", + "user_prefs_desc": "Pagkakasunod-sunod ng addon at UI settings", + "catalog_settings_label": "Catalog Settings", + "catalog_settings_desc": "Mga filter at preference sa catalog", + "api_keys_label": "Mga API Key", + "api_keys_desc": "MDBList at OpenRouter keys", + "action_create": "Gumawa ng Backup", + "action_restore": "Mag-restore mula sa Backup", + "section_info": "Tungkol sa mga Backup", + "info_text": "• Ang backup files ay nakatago sa iyong device\n• I-share ang backup para maglipat ng data sa ibang device\n• Ang pag-restore ay magbubura sa iyong kasalukuyang data", + "alert_create_title": "Gumawa ng Backup", + "alert_no_content": "Walang napiling content para sa backup.", + "alert_backup_created_title": "Nagawa na ang Backup", + "alert_backup_created_msg": "Ang iyong backup ay handa na para i-share.", + "alert_backup_failed_title": "Bigo ang Backup", + "alert_restore_confirm_title": "Kumpirmahin ang Pag-restore", + "alert_restore_confirm_msg": "I-re-restore nito ang iyong data mula sa backup noong {{date}}. Mabubura ang iyong kasalukuyang data. Ituloy?", + "alert_restore_complete_title": "Tapos na ang Pag-restore", + "alert_restore_complete_msg": "Matagumpay na na-restore ang data. Mangyaring i-restart ang app.", + "alert_restore_failed_title": "Bigo ang Pag-restore", + "restart_app": "I-restart ang App", + "alert_restart_failed_title": "Bigo ang Pag-restart", + "alert_restart_failed_msg": "Bigo sa pag-restart ng app. Pakisara at buksan ang app nang manual." + }, + "updates": { + "title": "Mga Update ng App", + "status_checking": "Nag-che-check ng mga update...", + "status_available": "May available na update!", + "status_downloading": "Dina-download ang update...", + "status_installing": "Inia-install ang update...", + "status_success": "Matagumpay na na-install ang update!", + "status_error": "Bigo ang update", + "status_ready": "Handa nang mag-check ng update", + "action_check": "Mag-check ng Update", + "action_install": "I-install ang Update", + "release_notes": "Release notes:", + "version": "Bersyon:", + "last_checked": "Huling check:", + "current_version": "Kasalukuyang bersyon:", + "current_release_notes": "Kasalukuyang release notes:", + "github_release": "GITHUB RELEASE", + "current": "Kasalukuyan:", + "latest": "Pinakabago:", + "notes": "Mga Tala:", + "view_release": "Tingnan ang Release", + "notification_settings": "MGA SETTING NG NOTIFICATION", + "ota_alerts_label": "OTA Update Alerts", + "ota_alerts_desc": "Magpakita ng notifications para sa over-the-air updates", + "major_alerts_label": "Major Update Alerts", + "major_alerts_desc": "Magpakita ng notifications para sa bagong bersyon sa GitHub", + "alert_disable_ota_title": "I-disable ang OTA Update Alerts?", + "alert_disable_ota_msg": "Hindi ka na makakatanggap ng awtomatikong notification para sa OTA updates.", + "alert_disable_major_title": "I-disable ang Major Update Alerts?", + "alert_disable_major_msg": "Hindi ka na makakatanggap ng notification para sa mga major app update.", + "warning_note": "Ang pag-iiwan sa alerts na naka-enable ay naniniguradong makakatanggap ka ng mga bug fix.", + "disable": "I-disable", + "alert_no_update_to_install": "Walang update na available para i-install", + "alert_install_failed": "Bigo sa pag-install ng update", + "alert_no_update_title": "Walang Update", + "alert_update_applied_msg": "Ilalapat ang update sa susunod na pag-restart ng app" + }, + "player": { + "title": "Video Player", + "section_selection": "PAGPILI NG PLAYER", + "internal_title": "Built-in Player", + "internal_desc": "Gamitin ang default player ng app", + "vlc_title": "VLC", + "vlc_desc": "Buksan ang streams sa VLC media player", + "infuse_title": "Infuse", + "infuse_desc": "Buksan ang streams sa Infuse player", + "outplayer_title": "OutPlayer", + "outplayer_desc": "Buksan ang streams sa OutPlayer", + "vidhub_title": "VidHub", + "vidhub_desc": "Buksan ang streams sa VidHub player", + "infuse_live_title": "Infuse Livecontainer", + "infuse_live_desc": "Buksan ang streams sa Infuse player LiveContainer", + "external_title": "External Player", + "external_desc": "Buksan ang streams sa iyong napiling video player", + "section_playback": "MGA OPTION SA PLAYBACK", + "skip_intro_settings_title": "Laktawan ang Intro", + "powered_by_introdb": "Powered by IntroDB", + "autoplay_title": "Auto-play ng Unang Stream", + "autoplay_desc": "Awtomatikong simulan ang unang stream sa listahan.", + "resume_title": "Laging I-resume", + "resume_desc": "Laktawan ang resume prompt at ituloy kung saan huminto.", + "engine_title": "Video Player Engine", + "engine_desc": "Ang 'Auto' ay gumagamit ng ExoPlayer na may MPV fallback.", + "decoder_title": "Decoder Mode", + "decoder_desc": "Paano idine-decode ang video. Inirerekomenda ang 'Auto'.", + "gpu_title": "GPU Rendering", + "gpu_desc": "Ang GPU-Next ay may mas magandang HDR at color management.", + "external_downloads_title": "External Player para sa Downloads", + "external_downloads_desc": "I-play ang downloaded content sa external player.", + "restart_required": "Kailangan ng Restart", + "restart_msg_decoder": "I-restart ang app para sa decoder change.", + "restart_msg_gpu": "I-restart ang app para sa GPU mode change.", + "option_auto": "Auto", + "option_auto_desc_engine": "ExoPlayer + MPV fallback", + "option_mpv": "MPV", + "option_mpv_desc": "MPV lang", + "option_auto_desc_decoder": "Pinaka-balanse", + "option_sw": "SW", + "option_sw_desc": "Software", + "option_hw": "HW", + "option_hw_desc": "Hardware", + "option_hw_plus": "HW+", + "option_hw_plus_desc": "Full HW", + "option_gpu_desc": "Standard", + "option_gpu_next_desc": "Advanced" + }, + "plugins": { + "title": "Mga Plugin", + "enable_title": "I-enable ang mga Plugin", + "enable_desc": "I-enable ang plugin engine para sa external media sources", + "repo_config_title": "Configuration ng Repository", + "repo_config_desc": "Pamahalaan ang mga external plugin repository.", + "your_repos": "Mga Repository", + "your_repos_desc": "I-configure ang external sources para sa mga plugin.", + "add_repo_button": "Magdagdag ng Repository", + "refresh": "I-refresh", + "remove": "Alisin", + "enabled": "Naka-enable", + "disabled": "Disabled", + "updating": "Inia-update...", + "success": "Tagumpay", + "error": "Error", + "alert_repo_added": "Matagumpay na naidagdag ang repository", + "alert_repo_saved": "Matagumpay na na-save ang Repository URL", + "alert_repo_refreshed": "Matagumpay na na-refresh ang repository", + "alert_invalid_url": "Maling Format ng URL", + "alert_plugins_cleared": "Lahat ng plugin ay naalis na", + "alert_cache_cleared": "Matagumpay na na-clear ang repository cache", + "unknown": "Hindi Alam", + "active": "Aktibo", + "available": "Available", + "platform_disabled": "Platform Disabled", + "limited": "Limitado", + "clear_all": "I-clear Lahat ng Plugin", + "clear_all_desc": "Sigurado ka bang gusto mong alisin lahat ng naka-install na plugin?", + "clear_cache": "I-clear ang Repository Cache", + "clear_cache_desc": "Mabubura ang URL at lahat ng cached plugin data.", + "add_new_repo": "Magdagdag ng Bagong Repository", + "available_plugins": "Available na Plugin ({{count}})", + "placeholder": "Maghanap ng mga plugin...", + "all": "Lahat", + "filter_all": "Lahat ng Uri", + "filter_movies": "Mga Pelikula", + "filter_tv": "Mga TV Show", + "enable_all": "I-enable Lahat", + "disable_all": "I-disable Lahat", + "no_plugins_found": "Walang Nahanap na Plugin", + "no_plugins_available": "Walang Available na Plugin", + "no_match_desc": "Walang tumutugmang plugin para sa \"{{query}}\".", + "configure_repo_desc": "Mag-configure ng repository sa itaas.", + "clear_search": "I-clear ang Search", + "no_external_player": "Walang external player", + "showbox_token": "ShowBox UI Token", + "showbox_placeholder": "I-paste ang iyong ShowBox UI token", + "save": "I-save", + "clear": "I-clear", + "additional_settings": "Karagdagang Settings", + "enable_url_validation": "I-enable ang URL Validation", + "url_validation_desc": "I-validate ang media URLs bago ipakita", + "group_streams": "I-grupo ang Plugin Sources", + "group_streams_desc": "Kapag enabled, naka-grupo ang sources ayon sa repository.", + "sort_quality": "I-sort ayon sa Quality Una", + "sort_quality_desc": "I-sort ang sources base sa kalidad ng video.", + "show_logos": "Ipakita ang mga Plugin Logo", + "show_logos_desc": "Ipakita ang logos ng plugin sa tabi ng media links.", + "quality_filtering": "Filtering ng Quality", + "quality_filtering_desc": "I-exclude ang mga partikular na resolution.", + "excluded_qualities": "Mga excluded na quality:", + "language_filtering": "Filtering ng Wika", + "language_filtering_desc": "I-exclude ang mga partikular na wika.", + "note": "Tandaan:", + "language_filtering_note": "Ang filter na ito ay para lang sa providers na may impormasyon ng wika.", + "excluded_languages": "Mga excluded na wika:", + "about_title": "Tungkol sa mga Plugin", + "about_desc_1": "Ang mga plugin ay modular components na kumukuha ng content mula sa iba't ibang protocol.", + "about_desc_2": "Ang mga plugin na \"Limited\" ay maaaring mangailangan ng external configurations.", + "help_title": "Setup ng Plugin", + "help_step_1": "1. **I-enable ang Plugins** - I-on ang main switch", + "help_step_2": "2. **Magdagdag ng Repository** - Maglagay ng valid na repo URL", + "help_step_3": "3. **I-refresh ang Repository** - Kunin ang available na plugins", + "help_step_4": "4. **I-activate** - I-enable ang mga gusto mong gamitin", + "got_it": "Nakuha ko na!", + "repo_format_hint": "Format: https://raw.githubusercontent.com/username/repo/refs/heads/branch", + "cancel": "Kanselahin", + "add": "Idagdag" + }, + "theme": { + "title": "Mga Tema ng App", + "select_theme": "PUMILI NG TEMA", + "create_custom": "Gumawa ng Custom na Tema", + "options": "MGA OPTION", + "use_dominant_color": "Gamitin ang Dominant Color mula sa Artwork", + "categories": { + "all": "Lahat ng Tema", + "dark": "Dark Themes", + "colorful": "Makulay", + "custom": "Aking mga Tema" + }, + "editor": { + "theme_name_placeholder": "Pangalan ng tema", + "save": "I-save", + "primary": "Primary", + "secondary": "Secondary", + "background": "Background", + "invalid_name_title": "Maling Pangalan", + "invalid_name_msg": "Mangyaring maglagay ng valid na pangalan ng tema" + }, + "alerts": { + "delete_title": "Burahin ang Tema", + "delete_msg": "Sigurado ka bang gusto mong burahin ang \"{{name}}\"?", + "ok": "OK", + "delete": "Burahin", + "cancel": "Kanselahin", + "back": "Mga Setting" + } + }, + "legal": { + "title": "Legal at Disclaimer", + "intro_title": "Kalikasan ng Application", + "intro_text": "Ang Nuvio ay isang media player at metadata management application. Ito ay nagsisilbi lamang bilang interface para sa pag-browse ng metadata at pag-play ng media files mula sa user o third-party extensions.", + "extensions_title": "Third-Party Plugins", + "extensions_text": "Pinapayagan ng Nuvio ang pag-install ng third-party plugins. Ang mga ito ay binuo ng mga independent developers at walang kinalaman sa Nuvio.", + "user_resp_title": "Responsibilidad ng User", + "user_resp_text": "Ang mga user ay tanging responsable para sa plugins na kanilang inilalagay. Sa paggamit nito, sumasang-ayon ka na may legal na karapatan ka sa content na pinapanood mo.", + "dmca_title": "Copyright at DMCA", + "dmca_text": "Iginagalang namin ang intellectual property rights. Dahil ang Nuvio ay hindi nag-ho-host ng content, hindi kami makakapagtanggal ng content sa internet.", + "warranty_title": "Walang Warranty", + "warranty_text": "Ang software na ito ay ibinibigay nang \"as is\", nang walang anumang warranty." + }, + "plugin_tester": { + "title": "Plugin Tester", + "subtitle": "Patakbuhin ang mga scraper i-inspect ang logs", + "tabs": { + "individual": "Individual", + "repo": "Repo Tester", + "code": "Code", + "logs": "Logs", + "results": "Mga Resulta" + }, + "common": { + "error": "Error", + "success": "Tagumpay", + "movie": "Pelikula", + "tv": "TV", + "tmdb_id": "TMDB ID", + "season": "Season", + "episode": "Episode", + "running": "Tumatakbo...", + "run_test": "Patakbuhin ang Test", + "play": "I-play", + "done": "Tapos na", + "test": "Test", + "testing": "Sini-suri..." + }, + "individual": { + "load_from_url": "I-load mula sa URL", + "load_from_url_desc": "I-paste ang raw GitHub URL.", + "enter_url_error": "Mangyaring maglagay ng URL", + "code_loaded": "Code ay na-load mula sa URL", + "fetch_error": "Bigo sa pag-fetch: {{message}}", + "no_code_error": "Walang code na tatakbo", + "plugin_code": "Code ng Plugin", + "focus_editor": "Focus sa code editor", + "code_placeholder": "// I-paste ang code ng plugin dito...", + "test_parameters": "Mga Parameter ng Test", + "no_logs": "Wala pang logs. Patakbuhin ang test.", + "no_streams": "Walang nahanap na streams.", + "streams_found": "{{count}} Stream ang Nahanap", + "streams_found_plural": "{{count}} na Stream ang Nahanap", + "tap_play_hint": "I-tap ang Play para i-test ang stream.", + "unnamed_stream": "Walang Pangalang Stream", + "quality": "Quality: {{quality}}", + "size": "Laki: {{size}}", + "url_label": "URL: {{url}}", + "headers_info": "Headers: {{count}} custom header(s)", + "find_placeholder": "Hanapin sa code...", + "edit_code_title": "I-edit ang Code", + "no_url_stream_error": "Walang URL para sa stream na ito" + }, + "repo": { + "title": "Repo Tester", + "description": "Mag-fetch ng repository at i-test ang bawat provider.", + "enter_repo_url_error": "Maglagay ng repository URL", + "invalid_url_title": "Maling URL", + "invalid_url_msg": "Gumamit ng GitHub raw URL.", + "manifest_build_error": "Hindi makabuo ng manifest URL", + "manifest_fetch_error": "Bigo sa pag-fetch ng manifest", + "repo_manifest_fetch_error": "Bigo sa pag-fetch ng repository manifest", + "missing_filename": "Nawawalang filename sa manifest", + "scraper_build_error": "Hindi makabuo ng scraper URL", + "download_scraper_error": "Bigo sa pag-download ng scraper", + "test_failed": "Bigo ang test", + "test_parameters": "Repo Test Parameters", + "test_parameters_desc": "Gagamitin lang para sa Repo Tester.", + "using_info": "Gamit: {{mediaType}} • TMDB {{tmdbId}}", + "using_info_tv": "Gamit: {{mediaType}} • TMDB {{tmdbId}} • S{{season}}E{{episode}}", + "providers_title": "Mga Provider", + "repository_default": "Repository", + "providers_count": "{{count}} providers", + "fetch_hint": "Mag-fetch ng repo para makita ang providers.", + "test_all": "I-test Lahat", + "status_running": "TUMATAKBO", + "status_ok": "OK ({{count}})", + "status_ok_empty": "OK (0)", + "status_failed": "BIGO", + "status_idle": "IDLE", + "tried_url": "Sinubukan: {{url}}", + "provider_logs": "Logs ng Provider", + "no_logs_captured": "Walang logs na nakuha." + } + } +} \ No newline at end of file diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json index 19ba0e6d..f013901a 100644 --- a/src/i18n/locales/fr.json +++ b/src/i18n/locales/fr.json @@ -636,6 +636,18 @@ "chinese": "Chinois (Simplifié)", "hindi": "Hindi", "serbian": "Serbe", + "hebrew": "Hébreu", + "bulgarian": "Bulgare", + "polish": "Polonais", + "czech": "Tchèque", + "turkish": "Turc", + "slovenian": "Slovène", + "macedonian": "Macédonien", + "russian": "Russe", + "filipino": "Philippin", + "dutch_nl": "Néerlandais (Pays-Bas)", + "romanian": "Roumain", + "albanian": "Albanais", "account": "Compte", "content_discovery": "Contenu et découverte", "appearance": "Apparence", @@ -896,8 +908,8 @@ }, "debrid": { "title": "Intégration Debrid", - "description_torbox": "Débloquez des flux 4K de haute qualité et des vitesses fulgurantes en intégrant Torbox. Entrez votre clé API ci-dessous pour améliorer instantanément votre expérience de streaming.", - "description_torrentio": "Configurez Torrentio pour obtenir des flux torrent pour les films et les séries TV. Un service debrid est requis pour streamer le contenu.", + "description_torbox": "Connect Torbox to use your account-based source preferences. Enter your API key below to configure the integration.", + "description_torrentio": "Configure Torrentio as an external source integration. A compatible debrid account may be required depending on your setup.", "tab_torbox": "TorBox", "tab_torrentio": "Torrentio", "status_connected": "Connecté", @@ -924,15 +936,15 @@ "enter_api_key": "Entrez votre clé API", "connect_button": "Connecter et installer", "connecting": "Connexion...", - "unlock_speeds_title": "Débloquez les vitesses premium", - "unlock_speeds_desc": "Obtenez un abonnement Torbox pour accéder à des flux en cache de haute qualité sans aucun buffering.", + "unlock_speeds_title": "Optional Torbox Subscription", + "unlock_speeds_desc": "Torbox offers account tiers with enhanced performance and availability features.", "get_subscription": "S'abonner", "powered_by": "Propulsé par", "disclaimer_torbox": "Nuvio n'est affilié à Torbox d'aucune façon.", "disclaimer_torrentio": "Nuvio n'est affilié à Torrentio d'aucune façon.", "installed_badge": "✓ INSTALLÉ", "promo_title": "⚡ Besoin d'un service Debrid ?", - "promo_desc": "Obtenez TorBox pour un streaming 4K ultra-rapide sans buffering. Torrents en cache premium et téléchargements instantanés.", + "promo_desc": "Use TorBox if you want account-managed performance features for supported integrations.", "promo_button": "Obtenir un abonnement TorBox", "service_label": "Service Debrid *", "api_key_label": "Clé API *", @@ -1324,7 +1336,7 @@ "user_resp_title": "Responsabilité de l'Utilisateur", "user_resp_text": "Les utilisateurs sont seuls responsables des extensions qu'ils installent et du contenu auquel ils accèdent. En utilisant cette application, vous acceptez de vous assurer que vous disposez du droit légal d'accéder à tout contenu que vous visualisez en utilisant Nuvio. Les développeurs de Nuvio ne cautionnent ni n'encouragent la violation du droit d'auteur.", "dmca_title": "Droits d'Auteur et DMCA", - "dmca_text": "Nous respectons les droits de propriété intellectuelle d'autrui. Étant donné que Nuvio n'héberge aucun contenu, nous ne pouvons pas supprimer de contenu d'Internet. Toutefois, si vous pensez que l'interface de l'application elle-même enfreint vos droits, veuillez nous contacter.", + "dmca_text": "We respect the intellectual property rights of others. Nuvio does not host media content. If you believe this project's code, assets, or interface infringes your rights, submit a notice through the official project contact channels listed on the website and repository.", "warranty_title": "Aucune Garantie", "warranty_text": "Ce logiciel est fourni \"tel quel\", sans garantie d'aucune sorte, expresse ou implicite. En aucun cas, les auteurs ou titulaires de droits d'auteur ne pourront être tenus responsables de toute réclamation, dommage ou autre responsabilité découlant de l'utilisation de ce logiciel." }, diff --git a/src/i18n/locales/he.json b/src/i18n/locales/he.json new file mode 100644 index 00000000..153ecc86 --- /dev/null +++ b/src/i18n/locales/he.json @@ -0,0 +1,1430 @@ +{ + "common": { + "loading": "טוען...", + "cancel": "ביטול", + "save": "שמירה", + "delete": "מחיקה", + "edit": "עריכה", + "search": "חיפוש", + "error": "שגיאה", + "success": "הצלחה", + "ok": "אישור", + "unknown": "לא ידוע", + "retry": "ניסיון חוזר", + "try_again": "נסה שנית", + "go_back": "חזור", + "settings": "הגדרות", + "close": "סגירה", + "enable": "הפעלה", + "disable": "השבתה", + "show_more": "הצג עוד", + "show_less": "הצג פחות", + "load_more": "טען עוד", + "unknown_date": "תאריך לא ידוע", + "anonymous_user": "משתמש אנונימי", + "time": { + "now": "ממש עכשיו", + "minutes_ago": "לפני {{count}} דק'", + "hours_ago": "לפני {{count}} שע'", + "days_ago": "לפני {{count}} ימים" + }, + "days_short": { + "sun": "א'", + "mon": "ב'", + "tue": "ג'", + "wed": "ד'", + "thu": "ה'", + "fri": "ו'", + "sat": "ש'" + }, + "email": "אימייל", + "status": "סטטוס" + }, + "home": { + "categories": { + "movies": "סרטים", + "series": "סדרות", + "channels": "ערוצים" + }, + "movies": "סרטים", + "tv_shows": "תוכניות טלוויזיה", + "load_more_catalogs": "טען קטלוגים נוספים", + "no_content": "אין תוכן זמין", + "add_catalogs": "הוספת קטלוגים", + "sign_in_available": "ניתן להתחבר", + "sign_in_desc": "ניתן להתחבר בכל עת דרך הגדרות ← חשבון", + "view_all": "צפייה בהכל", + "this_week": "השבוע", + "upcoming": "בקרוב", + "recently_released": "שוחררו לאחרונה", + "no_scheduled_episodes": "סדרות ללא פרקים מתוזמנים", + "check_back_later": "בדקו שוב מאוחר יותר", + "continue_watching": "המשך צפייה", + "up_next": "הבא בתור", + "up_next_caps": "הבא בתור", + "released": "שוחרר", + "new": "חדש", + "tba": "טרם פורסם", + "new_episodes": "{{count}} פרקים חדשים", + "season_short": "עונה {{season}}", + "episode_short": "פרק {{episode}}", + "season": "עונה {{season}}", + "episode": "פרק {{episode}}", + "movie": "סרט", + "series": "סדרה", + "tv_show": "תוכנית טלוויזיה", + "percent_watched": "{{percent}}% נצפו", + "view_details": "לפרטים נוספים", + "remove": "הסרה", + "play": "נגן", + "play_now": "נגן עכשיו", + "resume": "המשך", + "info": "מידע", + "more_info": "מידע נוסף", + "my_list": "הרשימה שלי", + "save": "שמירה", + "saved": "נשמר", + "retry": "ניסיון חוזר", + "install_addons": "התקנת תוספים", + "settings": "הגדרות", + "no_featured_content": "אין תוכן מומלץ", + "couldnt_load_featured": "לא ניתן לטעון תוכן מומלץ", + "no_featured_desc": "התקינו תוספים עם קטלוגים או שנו את מקור התוכן בהגדרות.", + "load_error_desc": "אירעה שגיאה בטעינת התוכן המומלץ. בדקו את החיבור ונסו שוב.", + "no_featured_available": "אין תוכן מומלץ זמין", + "no_description": "אין תיאור זמין" + }, + "navigation": { + "home": "בית", + "library": "ספרייה", + "search": "חיפוש", + "downloads": "הורדות", + "settings": "הגדרות" + }, + "search": { + "title": "חיפוש", + "recent_searches": "חיפושים אחרונים", + "discover": "גילוי", + "movies": "סרטים", + "tv_shows": "תוכניות טלוויזיה", + "select_catalog": "בחירת קטלוג", + "all_genres": "כל הז'אנרים", + "discovering": "מגלה תוכן...", + "show_more": "הצג עוד ({{count}})", + "no_content_found": "לא נמצא תוכן", + "try_different": "נסו ז'אנר או קטלוג אחר", + "select_catalog_desc": "בחרו קטלוג כדי להתחיל לגלות", + "tap_catalog_desc": "לחצו על שבב הקטלוג שלמעלה כדי להתחיל", + "placeholder": "חיפוש סרטים, סדרות...", + "keep_typing": "המשיכו להקליד...", + "type_characters": "הקלידו לפחות 2 תווים לחיפוש", + "no_results": "לא נמצאו תוצאות", + "try_keywords": "נסו מילות מפתח אחרות או בדקו את האיות", + "select_type": "בחירת סוג", + "browse_movies": "דפדוף בקטלוג סרטים", + "browse_tv": "דפדוף בקטלוג סדרות טלוויזיה", + "select_genre": "בחירת ז'אנר", + "show_all_content": "הצגת כל התוכן", + "genres_count": "{{count}} ז'אנרים" + }, + "library": { + "title": "ספרייה", + "watched": "נצפה", + "continue": "המשך", + "watchlist": "רשימת צפייה", + "collection": "אוסף", + "rated": "דורג", + "items": "פריטים", + "trakt_collections": "אוספי Trakt", + "trakt_collection": "אוסף Trakt", + "no_trakt": "אין אוספי Trakt", + "no_trakt_desc": "אוספי ה-Trakt שלך יופיעו כאן ברגע שתתחיל להשתמש ב-Trakt", + "load_collections": "טעינת אוספים", + "empty_folder": "אין תוכן ב{{folder}}", + "empty_folder_desc": "אוסף זה ריק", + "refresh": "רענון", + "no_movies": "אין עדיין סרטים", + "no_series": "אין עדיין סדרות", + "no_content": "אין עדיין תוכן", + "add_content_desc": "הוסיפו תוכן לספרייה כדי לראות אותו כאן", + "find_something": "מצאו משהו לצפות בו", + "removed_from_library": "הוסר מהספרייה", + "item_removed": "הפריט הוסר מהספרייה שלך", + "failed_update_library": "עדכון הספרייה נכשל", + "unable_remove": "לא ניתן להסיר את הפריט מהספרייה", + "marked_watched": "סומן כנצפה", + "marked_unwatched": "סומן כלא נצפה", + "item_marked_watched": "הפריט סומן כנצפה", + "item_marked_unwatched": "הפריט סומן כלא נצפה", + "failed_update_watched": "עדכון סטטוס צפייה נכשל", + "unable_update_watched": "לא ניתן לעדכן את סטטוס הצפייה", + "added_to_library": "נוסף לספרייה", + "item_added": "נוסף לספרייה המקומית שלך", + "add_to_library": "הוספה לספרייה", + "remove_from_library": "הסרה מהספרייה", + "mark_watched": "סימון כנצפה", + "mark_unwatched": "סימון כלא נצפה", + "share": "שיתוף", + "add_to_watchlist": "הוספה לרשימת הצפייה ב-Trakt", + "remove_from_watchlist": "הסרה מרשימת הצפייה ב-Trakt", + "added_to_watchlist": "נוסף לרשימת הצפייה", + "added_to_watchlist_desc": "נוסף לרשימת הצפייה שלך ב-Trakt", + "removed_from_watchlist": "הוסר מרשימת הצפייה", + "removed_from_watchlist_desc": "הוסר מרשימת הצפייה שלך ב-Trakt", + "add_to_collection": "הוספה לאוסף Trakt", + "remove_from_collection": "הסרה מאוסף Trakt", + "added_to_collection": "נוסף לאוסף", + "added_to_collection_desc": "נוסף לאוסף שלך ב-Trakt", + "removed_from_collection": "הוסר מהאוסף", + "removed_from_collection_desc": "הוסר מהאוסף שלך ב-Trakt" + }, + "metadata": { + "unable_to_load": "לא ניתן לטעון תוכן", + "error_code": "קוד שגיאה: {{code}}", + "content_not_found": "תוכן לא נמצא", + "content_not_found_desc": "תוכן זה אינו קיים או שהוסר.", + "server_error": "שגיאת שרת", + "server_error_desc": "השרת אינו זמין באופן זמני. נסו שוב מאוחר יותר.", + "bad_gateway": "שגיאת שער (Bad gateway)", + "bad_gateway_desc": "השרת חווה בעיות. נסו שוב מאוחר יותר.", + "service_unavailable": "שירות לא זמין", + "service_unavailable_desc": "השירות מושבת כעת לצורכי תחזוקה. נסו שוב מאוחר יותר.", + "too_many_requests": "יותר מדי בקשות", + "too_many_requests_desc": "שלחתם יותר מדי בקשות. המתינו רגע ונסו שוב.", + "request_timeout": "פסק זמן לבקשה", + "request_timeout_desc": "הבקשה ארכה זמן רב מדי. נסו שוב.", + "network_error": "שגיאת רשת", + "network_error_desc": "בדקו את חיבור האינטרנט ונסו שוב.", + "auth_error": "שגיאת אימות", + "auth_error_desc": "בדקו את הגדרות החשבון ונסו שוב.", + "access_denied": "גישה נדחתה", + "access_denied_desc": "אין לכם הרשאה לגשת לתוכן זה.", + "connection_error": "שגיאת חיבור", + "streams_unavailable": "מקורות סטרימינג לא זמינים", + "streams_unavailable_desc": "מקורות סטרימינג אינם זמינים כעת. נסו שוב מאוחר יותר.", + "unknown_error": "שגיאה לא ידועה", + "something_went_wrong": "משהו השתבש. נסו שוב.", + "cast": "צוות שחקנים", + "more_like_this": "עוד תכנים דומים", + "collection": "אוסף", + "episodes": "פרקים", + "seasons": "עונות", + "posters": "פוסטרים", + "banners": "באנרים", + "specials": "פרקים מיוחדים", + "season_number": "עונה {{number}}", + "episode_count": "פרק {{count}}", + "episode_count_plural": "{{count}} פרקים", + "no_episodes": "אין פרקים זמינים", + "no_episodes_for_season": "אין פרקים זמינים לעונה {{season}}", + "episodes_not_released": "ייתכן שהפרקים טרם שוחררו", + "no_description": "אין תיאור זמין", + "episode_label": "פרק {{number}}", + "watch_again": "צפייה חוזרת", + "completed": "הושלם", + "play_episode": "נגן ע'{{season}} פ'{{episode}}", + "play": "נגן", + "watched": "נצפה", + "watched_on_trakt": "נצפה ב-Trakt", + "synced_with_trakt": "סונכרן עם Trakt", + "saved": "נשמר", + "director": "במאי", + "directors": "במאים", + "creator": "יוצר", + "creators": "יוצרים", + "production": "הפקה", + "network": "רשת שידור", + "mark_watched": "סימון כנצפה", + "mark_unwatched": "סימון כלא נצפה", + "marking": "מסמן...", + "removing": "מסיר...", + "unmark_season": "ביטול סימון עונה {{season}}", + "mark_season": "סימון עונה {{season}} כנצפתה", + "resume": "המשך", + "spoiler_warning": "אזהרת ספוילר", + "spoiler_warning_desc": "תגובה זו מכילה ספוילרים. האם אתם בטוחים שברצונכם לחשוף אותה?", + "cancel": "ביטול", + "reveal_spoilers": "חשיפת ספוילרים", + "movie_details": "פרטי הסרט", + "show_details": "פרטי הסדרה", + "tagline": "שורת מחץ", + "status": "סטטוס", + "release_date": "תאריך יציאה", + "runtime": "זמן הרצה", + "budget": "תקציב", + "revenue": "הכנסות", + "origin_country": "ארץ מקור", + "original_language": "שפת מקור", + "first_air_date": "תאריך שידור ראשון", + "last_air_date": "תאריך שידור אחרון", + "total_episodes": "סה\"כ פרקים", + "episode_runtime": "אורך פרק", + "created_by": "נוצר על ידי", + "backdrop_gallery": "גלריית תמונות רקע", + "loading_episodes": "טוען פרקים...", + "no_episodes_available": "אין פרקים זמינים", + "play_next": "נגן ע'{{season}} פ'{{episode}}", + "play_next_episode": "נגן את הפרק הבא", + "save": "שמירה", + "percent_watched": "{{percent}}% נצפו", + "percent_watched_trakt": "{{percent}}% נצפו ({{traktPercent}}% ב-Trakt)", + "synced_with_trakt_progress": "סונכרן עם Trakt", + "using_trakt_progress": "משתמש בהתקדמות מ-Trakt", + "added_to_collection_hero": "נוסף לאוסף", + "added_to_collection_desc_hero": "נוסף לאוסף שלך ב-Trakt", + "removed_from_collection_hero": "הוסר מהאוסף", + "removed_from_collection_desc_hero": "הוסר מהאוסף שלך ב-Trakt", + "mark_as_watched": "סימון כנצפה", + "mark_as_unwatched": "סימון כלא נצפה" + }, + "cast": { + "biography": "ביוגרפיה", + "known_for": "מוכר בזכות", + "personal_info": "מידע אישי", + "born_in": "נולד ב{{place}}", + "filmography": "פילמוגרפיה", + "also_known_as": "ידוע גם כ-", + "no_info_available": "אין מידע נוסף זמין", + "as_character": "בתור {{character}}", + "loading_details": "טוען פרטים...", + "years_old": "בן {{age}}", + "view_filmography": "צפייה בפילמוגרפיה", + "filter": "סינון", + "sort_by": "מיון לפי", + "sort_popular": "פופולרי", + "sort_latest": "הכי חדש", + "sort_upcoming": "בקרוב", + "upcoming_badge": "בקרוב", + "coming_soon": "בקרוב", + "filmography_count": "פילמוגרפיה • {{count}} כותרים", + "loading_filmography": "טוען פילמוגרפיה...", + "load_more_remaining": "טען עוד ({{count}} נותרו)", + "alert_error_title": "שגיאה", + "alert_error_message": "לא ניתן לטעון את \"{{title}}\". נסו שוב מאוחר יותר.", + "alert_ok": "אישור", + "no_upcoming": "אין כותרים עתידיים זמינים עבור שחקן זה", + "no_content": "אין תוכן זמין עבור שחקן זה", + "no_movies": "אין סרטים זמינים עבור שחקן זה", + "no_tv": "אין תוכניות טלוויזיה זמינות עבור שחקן זה" + }, + "comments": { + "title": "תגובות Trakt", + "spoiler_warning": "⚠️ תגובה זו מכילה ספוילרים. לחצו כדי לחשוף.", + "spoiler": "ספוילר", + "contains_spoilers": "מכיל ספוילרים", + "reveal": "חשיפה", + "vip": "VIP", + "unavailable": "תגובות לא זמינות", + "no_comments": "אין עדיין תגובות ב-Trakt", + "not_in_database": "ייתכן שתוכן זה עדיין אינו מופיע במאגר של Trakt", + "check_trakt": "בדקו ב-Trakt" + }, + "trailers": { + "title": "טריילרים", + "official_trailers": "טריילרים רשמיים", + "official_trailer": "טריילר רשמי", + "teasers": "טיזרים", + "teaser": "טיזר", + "clips_scenes": "קליפים וסצנות", + "clip": "קליפ", + "featurettes": "מאחורי הקלעים", + "featurette": "סרטון קצר", + "behind_the_scenes": "מאחורי הקלעים", + "no_trailers": "אין טריילרים זמינים", + "unavailable": "טריילר לא זמין", + "unavailable_desc": "לא ניתן לטעון טריילר זה כרגע. נסו שוב מאוחר יותר.", + "unable_to_play": "לא ניתן לנגן את הטריילר. נסו שוב.", + "watch_on_youtube": "צפייה ב-YouTube" + }, + "catalog": { + "no_content_found": "לא נמצא תוכן", + "no_content_filters": "לא נמצא תוכן עבור המסננים שנבחרו", + "loading_content": "טוען תוכן...", + "back": "חזור", + "in_theaters": "בקולנוע", + "all": "הכל", + "failed_tmdb": "טעינת תוכן מ-TMDB נכשלה", + "movies": "סרטים", + "tv_shows": "תוכניות טלוויזיה", + "channels": "ערוצים" + }, + "streams": { + "back_to_episodes": "חזרה לפרקים", + "back_to_info": "חזרה למידע", + "fetching_from": "מביא נתונים מ-:", + "no_sources_available": "אין מקורות סטרימינג זמינים", + "add_sources_desc": "אנא הוסיפו מקורות סטרימינג בהגדרות", + "add_sources": "הוספת מקורות", + "finding_streams": "מחפש סטרימים זמינים...", + "finding_best_stream": "מחפש את הסטרים הטוב ביותר לניגון אוטומטי...", + "still_fetching": "עדיין מחפש סטרימים...", + "no_streams_available": "אין סטרימים זמינים", + "starting_best_stream": "מתחיל את הסטרים הטוב ביותר...", + "loading_more_sources": "טוען מקורות נוספים..." + }, + "player_ui": { + "via": "דרך {{name}}", + "audio_tracks": "רצועות שמע", + "no_audio_tracks": "אין רצועות שמע זמינות", + "playback_speed": "מהירות ניגון", + "on_hold": "בהמתנה", + "playback_error": "שגיאת ניגון", + "unknown_error": "אירעה שגיאה לא ידועה במהלך הניגון.", + "copy_error": "העתקת פרטי שגיאה", + "copied_to_clipboard": "הועתק ללוח", + "dismiss": "סגירה", + "continue_watching": "המשך צפייה", + "start_over": "התחל מהתחלה", + "resume": "המשך", + "change_source": "החלפת מקור", + "switching_source": "מחליף מקור...", + "no_sources_found": "לא נמצאו מקורות", + "sources": "מקורות", + "finding_sources": "מחפש מקורות...", + "unknown_source": "מקור לא ידוע", + "sources_limited": "המקורות עשויים להיות מוגבלים עקב שגיאות ספק.", + "episodes": "פרקים", + "specials": "פרקים מיוחדים", + "season": "עונה {{season}}", + "stream": "סטרים {{number}}", + "subtitles": "כתוביות", + "built_in": "מובנה", + "addons": "תוספים", + "style": "סגנון", + "none": "ללא", + "search_online_subtitles": "חיפוש כתוביות באינטרנט", + "preview": "תצוגה מקדימה", + "quick_presets": "הגדרות מהירות", + "default": "ברירת מחדל", + "yellow": "צהוב", + "high_contrast": "ניגודיות גבוהה", + "large": "גדול", + "core": "ליבה", + "font_size": "גודל גופן", + "show_background": "הצגת רקע", + "advanced": "מתקדם", + "position": "מיקום", + "text_color": "צבע טקסט", + "align": "יישור", + "bottom_offset": "מרחק מהתחתית", + "background_opacity": "אטימות רקע", + "text_shadow": "צל טקסט", + "on": "פעיל", + "off": "כבוי", + "outline_color": "צבע קווי מתאר", + "outline": "קווי מתאר", + "outline_width": "עובי קווי מתאר", + "letter_spacing": "מרווח בין אותיות", + "line_height": "גובה שורה", + "timing_offset": "היסט תזמון (שניות)", + "visual_sync": "סנכרון ויזואלי", + "timing_hint": "הזיזו את הכתוביות מוקדם יותר (-) או מאוחר יותר (+) כדי לסנכרן במידת הצורך.", + "reset_defaults": "איפוס לברירת מחדל", + "mark_intro_start": "סימון תחילת פתיח", + "mark_intro_end": "סימון סוף פתיח", + "intro_start_marked": "תחילת הפתיח סומנה", + "intro_submitted": "הפתיח נשלח בהצלחה", + "intro_submit_failed": "שליחת הפתיח נכשלה" + }, + "downloads": { + "title": "הורדות", + "no_downloads": "אין עדיין הורדות", + "no_downloads_desc": "תוכן שהורד יופיע כאן לצפייה במצב לא מקוון", + "explore": "גילוי תוכן", + "path_copied": "הנתיב הועתק", + "path_copied_desc": "נתיב הקובץ המקומי הועתק ללוח", + "copied": "הועתק", + "incomplete": "הורדה לא הושלמה", + "incomplete_desc": "ההורדה עדיין לא הסתיימה", + "not_available": "לא זמין", + "not_available_desc": "נתיב הקובץ המקומי זמין רק לאחר סיום ההורדה.", + "status_downloading": "מוריד", + "status_completed": "הושלם", + "status_paused": "מושהה", + "status_error": "שגיאה", + "status_queued": "בתור", + "status_unknown": "לא ידוע", + "provider": "ספק", + "streaming_playlist_warning": "ייתכן שלא יתנגן - פלייליסט סטרימינג", + "remaining": "נותרו", + "not_ready": "הורדה לא מוכנה", + "not_ready_desc": "אנא המתינו לסיום ההורדה.", + "filter_all": "הכל", + "filter_active": "פעיל", + "filter_done": "הושלם", + "filter_paused": "מושהה", + "no_filter_results": "אין הורדות מסוג {{filter}}", + "try_different_filter": "נסו לבחור מסנן אחר", + "limitations_title": "מגבלות הורדה", + "limitations_msg": "• קבצים קטנים מ-1MB הם בדרך כלל פלייליסטים של סטרימינג (M3U8) ולא ניתן להוריד אותם לצפייה לא מקוונת. אלו עובדים רק בסטרימינג חי ומכילים קישורים למקטעי וידאו, ולא את תוכן הווידאו עצמו.", + "remove_title": "הסרת הורדה", + "remove_confirm": "להסיר את \"{{title}}\" {{season_episode}}?", + "cancel": "ביטול", + "remove": "הסרה" + }, + "addons": { + "title": "תוספים", + "reorder_mode": "מצב סידור מחדש", + "reorder_info": "לתוספים בראש הרשימה יש עדיפות גבוהה יותר בטעינת תוכן", + "add_addon_placeholder": "כתובת URL של התוסף", + "add_button": "הוספת תוסף", + "my_addons": "התוספים שלי", + "community_addons": "תוספי קהילה", + "no_addons": "אין תוספים מותקנים", + "uninstall_title": "הסרת תוסף", + "uninstall_message": "האם אתם בטוחים שברצונכם להסיר את {{name}}?", + "uninstall_button": "הסרה", + "install_success": "התוסף הותקן בהצלחה", + "install_error": "התקנת התוסף נכשלה", + "load_error": "טעינת התוספים נכשלה", + "fetch_error": "קבלת פרטי התוסף נכשלה", + "invalid_url": "אנא הכניסו כתובת URL חוקית", + "configure": "הגדרה", + "version": "גרסה: {{version}}", + "installed_addons": "תוספים מותקנים", + "reorder_drag_title": "גררו תוספים לשינוי הסדר", + "install": "התקנה", + "config_unavailable_title": "הגדרה לא זמינה", + "config_unavailable_msg": "לא ניתן היה לקבוע את כתובת ה-URL להגדרה עבור תוסף זה.", + "cannot_open_config_title": "לא ניתן לפתוח הגדרות", + "cannot_open_config_msg": "לא ניתן לפתוח את כתובת ההגדרות ({{url}}). ייתכן שלתוסף אין דף הגדרות.", + "description": "תיאור", + "supported_types": "סוגים נתמכים", + "catalogs": "קטלוגים", + "no_description": "אין תיאור זמין", + "overview": "סקירה כללית", + "no_categories": "אין קטגוריות", + "pre_installed": "מותקן מראש" + }, + "trakt": { + "title": "הגדרות Trakt", + "settings_title": "הגדרות Trakt", + "connect_title": "התחברות ל-Trakt", + "connect_desc": "סנכרנו את היסטוריית הצפייה, רשימת המעקב והאוסף שלכם עם Trakt.tv", + "sign_in": "התחברות ל-Trakt", + "sign_out": "התנתקות", + "sign_out_confirm": "האם אתם בטוחים שברצונכם להתנתק מחשבון ה-Trakt שלכם?", + "joined": "הצטרף ב-{{date}}", + "sync_settings_title": "הגדרות סנכרון", + "sync_info": "כאשר מחוברים ל-Trakt, כל ההיסטוריה מסונכרנת ישירות מה-API ואינה נכתבת לאחסון המקומי. רשימת ה-'המשך צפייה' משקפת את ההתקדמות הגלובלית שלכם ב-Trakt.", + "auto_sync_label": "סנכרון אוטומטי של התקדמות הניגון", + "auto_sync_desc": "סנכרון אוטומטי של התקדמות הצפייה ל-Trakt", + "import_history_label": "ייבוא היסטוריית צפייה", + "import_history_desc": "השתמשו ב-'סנכרן עכשיו' כדי לייבא את היסטוריית הצפייה וההתקדמות מ-Trakt", + "sync_now_button": "סנכרן עכשיו", + "display_settings_title": "הגדרות תצוגה", + "show_comments_label": "הצגת תגובות Trakt", + "show_comments_desc": "הצגת תגובות מ-Trakt במסכי המידע במידה וקיימות", + "maintenance_title": "בתחזוקה", + "maintenance_unavailable": "Trakt לא זמין", + "maintenance_desc": "האינטגרציה עם Trakt מושהית זמנית לצורכי תחזוקה. כל אפשרויות הסנכרון והאימות מושבתות עד לסיום התחזוקה.", + "maintenance_button": "השירות בתחזוקה", + "auth_success_title": "התחברת בהצלחה", + "auth_success_msg": "חשבון ה-Trakt שלך חובדר בהצלחה.", + "auth_error_title": "שגיאת אימות", + "auth_error_msg": "ההתחברות ל-Trakt נכשלה.", + "auth_error_generic": "אירעה שגיאה במהלך האימות.", + "sign_out_error": "ההתנתקות מ-Trakt נכשלה.", + "sync_complete_title": "הסנכרון הושלם", + "sync_success_msg": "התקדמות הצפייה סונכרנה בהצלחה עם Trakt.", + "sync_error_msg": "הסנכרון נכשל. אנא נסו שוב." + }, + "simkl": { + "title": "הגדרות Simkl", + "settings_title": "הגדרות Simkl", + "connect_title": "התחברות ל-Simkl", + "connect_desc": "סנכרנו את היסטוריית הצפייה ועקבו אחרי מה שאתם רואים", + "sign_in": "התחברות ל-Simkl", + "sign_out": "ניתוק", + "sign_out_confirm": "האם אתם בטוחים שברצונכם להתנתק מ-Simkl?", + "syncing_desc": "הפריטים שצפיתם בהם מסתנכרנים עם Simkl.", + "auth_success_title": "התחברת בהצלחה", + "auth_success_msg": "חשבון ה-Simkl שלך חובדר בהצלחה.", + "auth_error_title": "שגיאת אימות", + "auth_error_msg": "ההתחברות ל-Simkl נכשלה.", + "auth_error_generic": "אירעה שגיאה במהלך האימות.", + "sign_out_error": "הניתוק מ-Simkl נכשל.", + "config_error_title": "שגיאת הגדרה", + "config_error_msg": "חסר Simkl Client ID במשתני הסביבה.", + "conflict_title": "קונפליקט", + "conflict_msg": "לא ניתן להתחבר ל-Simkl בזמן ש-Trakt מחובר. אנא נתקו את Trakt תחילה.", + "disclaimer": "Nuvio אינה קשורה ל-Simkl." + }, + "tmdb_settings": { + "title": "הגדרות TMDb", + "metadata_enrichment": "העשרת מידע (Metadata)", + "metadata_enrichment_desc": "שפרו את המידע על התכנים בעזרת נתוני TMDb לקבלת פרטים עשירים יותר.", + "enable_enrichment": "הפעלת העשרה", + "enable_enrichment_desc": "משלים מידע מ-TMDb עבור צוות שחקנים, סיווג גיל, לוגואים/פוסטרים ופרטי הפקה.", + "localized_text": "טקסט מקומי", + "localized_text_desc": "קבלת שמות ותיאורים בשפה המועדפת עליכם מ-TMDb.", + "language": "שפה", + "change": "שינוי", + "logo_preview": "תצוגה מקדימה של לוגו", + "logo_preview_desc": "התצוגה מראה כיצד יופיעו לוגואים מקומיים בשפה שנבחרה.", + "example": "דוגמה:", + "no_logo": "אין לוגו זמין", + "enrichment_options": "אפשרויות העשרה", + "enrichment_options_desc": "שלטו באילו נתונים יימשכו מ-TMDb. אפשרויות כבויות ישתמשו בנתוני התוסף המקוריים.", + "cast_crew": "צוות שחקנים והפקה", + "cast_crew_desc": "שחקנים, במאים, כותבים כולל תמונות פרופיל", + "title_description": "שם ותיאור", + "title_description_desc": "שימוש בשם ובתיאור המקומיים של TMDb", + "title_logos": "לוגואים של כותרים", + "title_logos_desc": "עיצובי לוגו באיכות גבוהה", + "banners_backdrops": "באנרים ותמונות רקע", + "banners_backdrops_desc": "תמונות רקע ברזולוציה גבוהה", + "certification": "סיווג תוכן", + "certification_desc": "דירוגי גיל (PG-13, R, TV-MA וכדומה)", + "recommendations": "המלצות", + "recommendations_desc": "הצעות לתוכן דומה", + "episode_data": "נתוני פרקים", + "episode_data_desc": "תמונות ממוזערות של פרקים, מידע וגיבוי לסדרות טלוויזיה", + "season_posters": "פוסטרים של עונות", + "season_posters_desc": "תמונות פוסטר ספציפיות לכל עונה", + "production_info": "פרטי הפקה", + "production_info_desc": "רשתות שידור וחברות הפקה כולל לוגואים", + "movie_details": "פרטי סרט", + "movie_details_desc": "תקציב, הכנסות, זמן הרצה, שורת מחץ", + "tv_details": "פרטי סדרת טלוויזיה", + "tv_details_desc": "סטטוס, מספר עונות, רשתות, יוצרים", + "movie_collections": "אוספי סרטים", + "movie_collections_desc": "פרנצ'ייזים (מארוול, מלחמת הכוכבים וכדומה)", + "api_configuration": "הגדרות API", + "api_configuration_desc": "הגדירו את הגישה שלכם ל-API של TMDb עבור יכולות משופרות.", + "custom_api_key": "מפתח API אישי", + "custom_api_key_desc": "השתמשו במפתח API משלכם לביצועים טובים יותר ומגבלות קצב ייעודיות.", + "custom_key_active": "מפתח API אישי פעיל", + "api_key_required": "נדרש מפתח API", + "api_key_placeholder": "הדביקו את מפתח ה-API שלכם (v3)", + "how_to_get_key": "איך משיגים מפתח API של TMDb?", + "built_in_key_msg": "כרגע בשימוש במפתח המובנה. מומלץ להשתמש במפתח אישי לביצועים טובים יותר.", + "cache_size": "גודל מטמון (Cache)", + "clear_cache": "ניקוי מטמון", + "cache_days": "תשובות TMDb נשמרות במטמון ל-7 ימים לשיפור ביצועים", + "choose_language": "בחירת שפה", + "choose_language_desc": "בחרו את השפה המועדפת לתוכן מ-TMDb", + "popular": "פופולרי", + "all_languages": "כל השפות", + "search_results": "תוצאות חיפוש", + "no_languages_found": "לא נמצאו שפות עבור \"{{query}}\"", + "clear_search": "ניקוי חיפוש", + "clear_cache_title": "ניקוי מטמון TMDB", + "clear_cache_msg": "פעולה זו תמחק את כל המידע השמור של TMDB ({{size}}). זה עלול להאט זמנית את הטעינה עד לבנייה מחדש של המטמון.", + "clear_cache_success": "מטמון TMDB נוקה בהצלחה.", + "clear_cache_error": "ניקוי המטמון נכשל.", + "clear_api_key_title": "הסרת מפתח API", + "clear_api_key_msg": "האם אתם בטוחים שברצונכם להסיר את מפתח ה-API האישי ולחזור לברירת המחדל?", + "clear_api_key_success": "מפתח ה-API הוסר בהצלחה", + "clear_api_key_error": "הסרת מפתח ה-API נכשלה", + "empty_api_key": "מפתח API לא יכול להיות ריק.", + "invalid_api_key": "מפתח API לא תקין. אנא בדקו ונסו שוב.", + "save_error": "אירעה שגיאה בזמן השמירה. אנא נסו שוב.", + "using_builtin_key": "כעת בשימוש במפתח המובנה של TMDb.", + "using_custom_key": "כעת בשימוש במפתח האישי שלכם.", + "enter_custom_key": "אנא הזינו ושמרו את מפתח ה-API האישי שלכם.", + "key_verified": "מפתח ה-API אומת ונשמר בהצלחה." + }, + "settings": { + "language": "שפה", + "select_language": "בחר שפה", + "english": "אנגלית", + "portuguese": "פורטוגזית", + "portuguese_br": "פורטוגזית (ברזיל)", + "portuguese_pt": "פורטוגזית (פורטוגל)", + "german": "גרמנית", + "arabic": "ערבית", + "spanish": "ספרדית", + "french": "צרפתית", + "italian": "איטלקית", + "croatian": "קרואטית", + "chinese": "סינית (מפושטת)", + "hindi": "הינדי", + "serbian": "סרבית", + "hebrew": "עברית", + "bulgarian": "בולגרית", + "polish": "פולנית", + "czech": "צ'כית", + "turkish": "טורקית", + "slovenian": "סلوفينية", + "macedonian": "מקדונית", + "russian": "רוסית", + "filipino": "פיליפינית", + "dutch_nl": "הולנדית (הולנד)", + "romanian": "רומנית", + "albanian": "אלבנית", + "account": "חשבון", + "content_discovery": "תוכן וגילוי", + "appearance": "מראה", + "integrations": "אינטגרציות", + "playback": "ניגון", + "backup_restore": "גיבוי ושחזור", + "updates": "עדכונים", + "about": "אודות", + "developer": "מפתח", + "cache": "מטמון", + "title": "הגדרות", + "settings_title": "הגדרות", + "sign_in_sync": "התחברו כדי לסנכרן", + "add_catalogs_sources": "תוספים, קטלוגים ומקורות", + "player_trailers_downloads": "נגן, טריילרים, הורדות", + "mdblist_tmdb_ai": "MDBList, TMDB, בינה מלאכותית", + "check_updates": "בדוק עדכונים", + "clear_mdblist_cache": "ניקוי מטמון MDBList", + "cache_management": "ניהול מטמון", + "downloads_counter": "הורדות וסופר...", + "made_with_love": "נוצר עם ❤️ על ידי Tapframe וחברים", + "sections": { + "information": "מידע", + "account": "חשבון", + "theme": "עיצוב", + "layout": "פריסה", + "sources": "מקורות", + "catalogs": "קטלוגים", + "discovery": "גילוי", + "metadata": "מידע (Metadata)", + "ai_assistant": "עוזר AI", + "video_player": "נגן וידאו", + "audio_subtitles": "שמע וכתוביות", + "media": "מדיה", + "notifications": "התראות", + "testing": "בדיקות", + "danger_zone": "אזור מסוכן" + }, + "items": { + "legal": "משפטי והצהרת ויתור", + "privacy_policy": "מדיניות פרטיות", + "report_issue": "דיווח על תקלה", + "version": "גרסה", + "contributors": "תורמים", + "view_contributors": "צפייה בכל התורמים", + "theme": "ערכת נושא", + "episode_layout": "פריסת פרקים", + "streams_backdrop": "רקע סטרימינג", + "streams_backdrop_desc": "הצגת רקע מטושטש בסטרימינג בנייד", + "addons": "תוספים", + "installed": "מותקנים", + "debrid_integration": "אינטגרציית Debrid", + "debrid_desc": "חיבור Torbox", + "plugins": "פלאגינים", + "plugins_desc": "ניהול פלאגינים ומאגרים", + "catalogs": "קטלוגים", + "active": "פעילים", + "home_screen": "מסך הבית", + "home_screen_desc": "פריסה ותוכן", + "continue_watching": "המשך צפייה", + "continue_watching_desc": "התנהגות מטמון וניגון", + "show_discover": "הצגת אזור הגילוי", + "show_discover_desc": "הצגת תוכן גילוי בחיפוש", + "mdblist": "MDBList", + "mdblist_connected": "מחובר", + "mdblist_desc": "הפעל כדי להוסיף דירוגים וביקורות", + "simkl": "Simkl", + "simkl_connected": "מחובר", + "simkl_desc": "מעקב אחר צפיות", + "tmdb": "TMDB", + "tmdb_desc": "מקור מידע ולוגואים", + "openrouter": "OpenRouter API", + "openrouter_connected": "מחובר", + "openrouter_desc": "הוסיפו מפתח API כדי להפעיל צ'אט AI", + "video_player": "נגן וידאו", + "built_in": "מובנה", + "external": "חיצוני", + "preferred_audio": "שפת שמע מועדפת", + "preferred_subtitle": "שפת כתוביות מועדפת", + "subtitle_source": "עדיפות מקור כתוביות", + "auto_select_subs": "בחירה אוטומטית של כתוביות", + "auto_select_subs_desc": "בחירה אוטומטית של כתוביות התואמות להעדפותיכם", + "show_trailers": "הצגת טריילרים", + "show_trailers_desc": "הצגת טריילרים באזור הראשי", + "enable_downloads": "אפשר הורדות", + "enable_downloads_desc": "הצגת לשונית הורדות ואפשרות שמירת סטרימים", + "notifications": "התראות", + "notifications_desc": "תזכורות לפרקים", + "developer_tools": "כלי מפתח", + "developer_tools_desc": "אפשרויות בדיקה ודיבאג", + "test_onboarding": "בדיקת תהליך פתיחה", + "reset_onboarding": "איפוס תהליך פתיחה", + "test_announcement": "בדיקת הכרזות", + "test_announcement_desc": "הצגת חלון 'מה חדש'", + "reset_campaigns": "איפוס קמפיינים", + "reset_campaigns_desc": "ניקוי נתוני חשיפה לקמפיינים", + "clear_all_data": "מחיקת כל הנתונים", + "clear_all_data_desc": "איפוס כל ההגדרות והמידע השמור" + }, + "options": { + "horizontal": "אופקי", + "vertical": "אנכי", + "internal_first": "פנימי תחילה", + "internal_first_desc": "עדיפות לכתוביות מובנות, ואז חיצוניות", + "external_first": "חיצוני תחילה", + "external_first_desc": "עדיפות לכתוביות מהתוסף, ואז מובנות", + "any_available": "כל מה שזמין", + "any_available_desc": "שימוש ברצועת הכתוביות הראשונה שנמצאה" + }, + "clear_data_desc": "פעולה זו תאפס את כל ההגדרות ותנקה את כל המידע השמור. האם אתם בטוחים?", + "app_updates": "עדכוני אפליקציה", + "about_nuvio": "אודות Nuvio" + }, + "privacy": { + "title": "פרטיות ומידע", + "settings_desc": "ניהול טלמטריה ואיסוף נתונים", + "info_title": "הפרטיות שלכם חשובה לנו", + "info_description": "שלטו במידע שנאסף ומשותף. ניתוח נתונים (Analytics) כבוי כברירת מחדל ודיווחי קריסה הם אנונימיים.", + "analytics_enabled_title": "ניתוח נתונים פעיל", + "analytics_enabled_message": "נתוני שימוש ייאספו כדי לעזור לנו לשפר את האפליקציה. ניתן לבטל זאת בכל עת.", + "disable_error_reporting_title": "לבטל דיווחי שגיאות?", + "disable_error_reporting_message": "ביטול דיווחי שגיאות אומר שלא נקבל התראות על קריסות או בעיות שאתם חווים. זה עלול להשפיע על היכולת שלנו לתקן באגים.", + "enable_session_replay_title": "להפעיל הקלטת סשן?", + "enable_session_replay_message": "הקלטת סשן מתעדת את המסך שלכם בזמן שגיאות כדי לעזור לנו להבין מה קרה. זה עלול ללכוד תוכן שמוצג על המסך.", + "enable_pii_title": "להפעיל איסוף מידע אישי (PII)?", + "enable_pii_message": "זה מאפשר איסוף מידע המזהה את המשתמש כמו כתובת IP ופרטי מכשיר. מידע זה עוזר לאבחן בעיות אך מגדיל את החשיפה של פרטיותכם.", + "disable_all_title": "לבטל את כל הטלמטריה?", + "disable_all_message": "זה יבטל את כל ניתוחי הנתונים, דיווחי השגיאות והקלטות הסשן. לא נקבל שום מידע על השימוש באפליקציה או על קריסות.", + "disable_all_button": "ביטול הכל", + "all_disabled_title": "כל הטלמטריה בוטלה", + "all_disabled_message": "כל איסוף הנתונים הופסק. השינויים ייכנסו לתוקף בהפעלה מחדש של האפליקציה.", + "reset_title": "חזרה להגדרות המומלצות", + "reset_message": "הגדרות הפרטיות שוחזרו לברירת המחדל המומלצת (דיווחי שגיאות פעילים, ניתוח נתונים כבוי).", + "section_analytics": "ניתוח נתונים (Analytics)", + "analytics_title": "ניתוח נתוני שימוש", + "analytics_description": "איסוף דפוסי שימוש אנונימיים וצפיות במסכים", + "section_error_reporting": "דיווחי שגיאות", + "error_reporting_title": "דיווחי קריסה", + "error_reporting_description": "שליחת דיווחי קריסה אנונימיים לשיפור היציבות", + "session_replay_title": "הקלטת סשן (Session Replay)", + "session_replay_description": "הקלטת המסך בזמן התרחשות שגיאות", + "pii_title": "כלול פרטי מכשיר", + "pii_description": "שליחת כתובת IP ופרטי מכשיר יחד עם הדיווחים", + "section_quick_actions": "פעולות מהירות", + "disable_all": "ביטול כל הטלמטריה", + "disable_all_desc": "כיבוי כל איסוף הנתונים", + "reset_recommended": "איפוס להגדרות מומלצות", + "reset_recommended_desc": "ברירות מחדל מוטות פרטיות עם דיווחי שגיאות", + "section_learn_more": "למידע נוסף", + "privacy_policy": "מדיניות פרטיות", + "current_settings": "סיכום הגדרות נוכחיות", + "summary_analytics": "ניתוח נתונים", + "summary_errors": "דיווחי שגיאות", + "summary_replay": "הקלטת סשן", + "summary_pii": "פרטי מכשיר", + "restart_note_detailed": "* שינויים בניתוח נתונים ודיווחי שגיאות נכנסים לתוקף מיידית. הגדרות הקלטת סשן ופרטי מכשיר דורשות הפעלה מחדש." + }, + "ai_settings": { + "title": "עוזר AI", + "info_title": "צ'אט מבוסס בינה מלאכותית", + "info_desc": "שאלו שאלות על כל סרט או פרק בסדרה בעזרת AI מתקדם. קבלו תובנות על העלילה, דמויות, נושאים, טריוויה ועוד - הכל מבוסס על נתוני TMDB מקיפים.", + "feature_1": "ניתוח והקשר ספציפי לפרקים", + "feature_2": "הסברי עלילה ותובנות על דמויות", + "feature_3": "עובדות וטריוויה מאחורי הקלעים", + "feature_4": "שימוש במפתח OpenRouter API משלכם", + "api_key_section": "מפתח OPENROUTER API", + "api_key_label": "מפתח API", + "api_key_desc": "הזינו את מפתח ה-API של OpenRouter כדי להפעיל את יכולות הצ'אט", + "save_api_key": "שמירת מפתח API", + "saving": "שומר...", + "update": "עדכון", + "remove": "הסרה", + "get_free_key": "קבלת מפתח API בחינם מ-OpenRouter", + "enable_chat": "הפעלת צ'אט AI", + "enable_chat_desc": "כאשר פעיל, כפתור \"שאל את ה-AI\" יופיע בדפי התוכן.", + "chat_enabled": "צ'אט AI פעיל", + "chat_enabled_desc": "כעת ניתן לשאול שאלות על סרטים וסדרות. חפשו את כפתור \"שאל את ה-AI\" בדפי התוכן!", + "how_it_works": "איך זה עובד", + "how_it_works_desc": "• OpenRouter מספק גישה למגוון מודלי AI\n• מפתח ה-API שלכם נשאר פרטי ומאובטח\n• המסלול החינמי כולל מגבלות שימוש נדיבות\n• צ'אט עם הקשר על פרקים/סרטים ספציפיים\n• קבלת ניתוחים והסברים מפורטים", + "error_invalid_key": "אנא הזינו מפתח API תקין", + "error_key_format": "מפתחות API של OpenRouter צריכים להתחיל ב-\"sk-or-\"", + "success_saved": "מפתח ה-API של OpenRouter נשמר בהצלחה!", + "error_save": "שמירת מפתח ה-API נכשלה", + "confirm_remove_title": "הסרת מפתח API", + "confirm_remove_msg": "האם אתם בטוחים שברצונכם להסיר את מפתח ה-API? פעולה זו תבטל את יכולות הצ'אט.", + "success_removed": "מפתח ה-API הוסר בהצלחה", + "error_remove": "הסרת מפתח ה-API נכשלה" + }, + "catalog_settings": { + "title": "קטלוגים", + "layout_phone": "פריסת מסך קטלוג (טלפון)", + "posters_per_row": "פוסטרים בשורה", + "auto": "אוטומטי", + "show_titles": "הצגת שמות על פוסטרים", + "show_titles_desc": "הצגת שם התוכן מתחת לכל פוסטר", + "phone_only_hint": "תקף לטלפונים בלבד. טאבלטים שומרים על פריסה אדפטיבית.", + "catalogs_group": "קטלוגים", + "enabled_count": "{{enabled}} מתוך {{total}} פעילים", + "rename_hint": "לחיצה ארוכה על קטלוג כדי לשנות את שמו", + "rename_modal_title": "שינוי שם קטלוג", + "rename_placeholder": "הזינו שם קטלוג חדש", + "error_save_name": "לא ניתן היה לשמור את השם המותאם." + }, + "continue_watching_settings": { + "title": "המשך צפייה", + "playback_behavior": "התנהגות ניגון", + "use_cached": "שימוש בקישורים שמורים (Cache)", + "use_cached_desc": "כאשר פעיל, לחיצה על פריטי 'המשך צפייה' תפתח את הנגן ישירות עם הקישורים הקודמים. כאשר כבוי, ייפתח מסך התוכן במקום זאת.", + "open_metadata": "פתיחת מסך מידע", + "open_metadata_desc": "כאשר קישורים שמורים כבויים, פתח את מסך המידע במקום מסך הסטרימים. זה מציג פרטי תוכן ומאפשר בחירה ידנית של מקור.", + "card_appearance": "מראה כרטיסייה", + "card_style": "סגנון כרטיסייה", + "card_style_desc": "בחרו כיצד יופיעו פריטי 'המשך צפייה' במסך הבית", + "wide": "רחב", + "poster": "פוסטר", + "cache_settings": "הגדרות מטמון (Cache)", + "cache_duration": "משך שמירת קישור", + "cache_duration_desc": "כמה זמן לשמור קישורי סטרימינג לפני שתוקפם יפוג", + "important_note": "הערה חשובה", + "important_note_text": "לא כל קישורי הסטרימינג נשארים פעילים לכל משך זמן המטמון. זמני שמירה ארוכים עלולים להוביל לקישורים שפג תוקפם. אם קישור שמור נכשל, האפליקציה תחזור לחיפוש מקורות טריים.", + "how_it_works": "איך זה עובד", + "how_it_works_cached": "• קישורים נשמרים למשך הזמן שבחרתם לאחר הניגון\n• הקישורים השמורים מאומתים לפני השימוש\n• אם המטמון לא תקין או פג תוקפו, המערכת חוזרת למסך התוכן\n• 'שימוש בקישורים שמורים' שולט במעבר ישיר לנגן לעומת ניווט למסך\n• 'פתיחת מסך מידע' מופיע רק כשקישורים שמורים כבויים", + "how_it_works_uncached": "• כשקישורים שמורים כבויים, לחיצה על המשך צפייה פותחת מסכי תוכן\n• האופציה 'פתיחת מסך מידע' שולטת איזה מסך ייפתח\n• מסך מידע מציג פרטי תוכן ומאפשר בחירה ידנית\n• מסך סטרימים מציג מקורות זמינים לניגון מיידי", + "changes_saved": "השינויים נשמרו", + "min": "דקות", + "hour": "שעה", + "hours": "שעות" + }, + "contributors": { + "title": "תורמים", + "special_mentions": "אזכורים מיוחדים", + "tab_contributors": "תורמים", + "tab_special": "אזכורים מיוחדים", + "tab_donors": "תורמים (Donors)", + "manager_role": "מנהל קהילה", + "manager_desc": "מנהל את קהילות הדיסקורד והרדיט של Nuvio", + "sponsor_role": "ספונסר שרת", + "sponsor_desc": "מימן את תשתית השרתים של Nuvio", + "mod_role": "מודרטור דיסקורד", + "mod_desc": "עוזר בניהול קהילת הדיסקורד של Nuvio", + "loading": "טוען...", + "discord_user": "משתמש דיסקורד", + "contributions": "תרומות", + "gratitude_title": "אנחנו מודים על כל תרומה", + "gratitude_desc": "כל שורת קוד, דיווח באג או הצעה עוזרים להפוך את Nuvio לטובה יותר עבור כולם", + "special_thanks_title": "תודה מיוחדת", + "special_thanks_desc": "האנשים המדהימים האלה עוזרים לשמור על קהילת Nuvio פעילה ועל השרתים מחוברים", + "donors_desc": "תודה שאתם מאמינים במה שאנחנו בונים. התמיכה שלכם שומרת על Nuvio חינמית ומשתפרת כל הזמן.", + "latest_donations": "אחרונים", + "leaderboard": "לוח מובילים", + "loading_donors": "טוען תורמים...", + "no_donors": "אין עדיין תורמים", + "error_rate_limit": "חרגתם ממגבלת ה-API של GitHub. אנא נסו שוב מאוחר יותר.", + "error_failed": "טעינת התורמים נכשלה. אנא בדקו את חיבור האינטרנט.", + "retry": "נסה שוב", + "no_contributors": "לא נמצאו תורמים", + "loading_contributors": "טוען תורמים..." + }, + "debrid": { + "title": "אינטגרציית Debrid", + "description_torbox": "פתחו סטרימינג באיכות 4K ומהירויות גבוהות על ידי חיבור Torbox. הזינו את מפתח ה-API שלכם למטה לשדרוג חווית הצפייה.", + "description_torrentio": "הגדר את Torrentio כדי לקבל מקורות טורנט לסרטים וסדרות. שירות debrid נדרש כדי להזרים את התוכן.", + "tab_torbox": "TorBox", + "tab_torrentio": "Torrentio", + "status_connected": "מחובר", + "status_disconnected": "מנותק", + "enable_addon": "הפעלת תוסף", + "disconnect_button": "ניתוק והסרה", + "disconnect_loading": "מתנתק...", + "account_info": "פרטי חשבון", + "plan": "תוכנית", + "plan_free": "חינם", + "plan_essential": "Essential ($3/mo)", + "plan_pro": "Pro ($10/mo)", + "plan_standard": "Standard ($5/mo)", + "plan_unknown": "לא ידוע", + "expires": "פג תוקף", + "downloaded": "הורדו", + "status_active": "פעיל", + "connected_title": "✓ מחובר ל-TorBox", + "connected_desc": "תוסף ה-TorBox שלך פעיל ומספק מקורות פרימיום.", + "configure_title": "הגדרת תוסף", + "configure_desc": "התאימו את חווית הצפייה. מיון לפי איכות, סינון גודל קבצים וניהול הגדרות נוספות.", + "open_settings": "פתח הגדרות", + "what_is_debrid": "מה זה שירות Debrid?", + "enter_api_key": "הזינו מפתח API", + "connect_button": "התחברות והתקנה", + "connecting": "מתחבר...", + "unlock_speeds_title": "פתיחת מהירויות פרימיום", + "unlock_speeds_desc": "רכשו מנוי Torbox לגישה למקורות באיכות גבוהה ללא טעינה (Buffering).", + "get_subscription": "רכישת מנוי", + "powered_by": "מופעל על ידי", + "disclaimer_torbox": "Nuvio אינה קשורה ל-Torbox בשום צורה.", + "disclaimer_torrentio": "Nuvio אינה קשורה ל-Torrentio בשום צורה.", + "installed_badge": "✓ מותקן", + "promo_title": "⚡ צריכים שירות Debrid?", + "promo_desc": "קבלו את TorBox לסטרימינג 4K מהיר במיוחד ללא Buffering. טורנטים שמורים והורדות מיידיות.", + "promo_button": "קבלת מנוי TorBox", + "service_label": "שירות Debrid *", + "api_key_label": "מפתח API *", + "sorting_label": "מיון", + "exclude_qualities": "החרגת איכויות", + "priority_languages": "שפות בעדיפות", + "max_results": "מקסימום תוצאות", + "additional_options": "אפשרויות נוספות", + "no_download_links": "אל תציג קישורי הורדה", + "no_debrid_catalog": "אל תציג קטלוג Debrid", + "install_button": "התקנת Torrentio", + "installing": "מתקין...", + "update_button": "עדכון הגדרות", + "updating": "מעדכן...", + "remove_button": "הסרת Torrentio", + "error_api_required": "נדרש מפתח API", + "error_api_required_desc": "אנא הזינו את מפתח ה-API של שירות ה-debrid שלכם כדי להתקין את Torrentio.", + "success_installed": "תוסף Torrentio הותקן בהצלחה!", + "success_removed": "תוסף Torrentio הוסר בהצלחה", + "alert_disconnect_title": "ניתוק Torbox", + "alert_disconnect_msg": "האם אתם בטוחים שברצונכם לנתק את Torbox? זה יסיר את התוסף וימחוק את מפתח ה-API השמור." + }, + "home_screen": { + "title": "הגדרות מסך הבית", + "changes_applied": "השינויים הוחלו", + "display_options": "אפשרויות תצוגה", + "show_hero": "הצגת קרוסלת תוכן (Hero)", + "show_hero_desc": "תוכן מומלץ בראש המסך", + "show_this_week": "הצגת 'השבוע'", + "show_this_week_desc": "פרקים חדשים מהשבוע הנוכחי", + "select_catalogs": "בחירת קטלוגים", + "all_catalogs": "כל הקטלוגים", + "selected": "נבחרו", + "hero_layout": "פריסת קרוסלה (Hero)", + "layout_legacy": "קלאסי", + "layout_carousel": "קרוסלה", + "layout_appletv": "Apple TV", + "layout_desc": "באנר ברוחב מלא, כרטיסיות להחלקה, או סגנון Apple TV", + "featured_source": "מקור תוכן מומלץ", + "using_catalogs": "משתמש בקטלוגים", + "manage_selected_catalogs": "ניהול קטלוגים שנבחרו", + "dynamic_bg": "רקע דינמי לקרוסלה", + "dynamic_bg_desc": "באנר מטושטש מאחורי הקרוסלה", + "performance_note": "עשוי להשפיע על הביצועים במכשירים חלשים.", + "posters": "פוסטרים", + "show_titles": "הצגת שמות", + "poster_size": "גודל פוסטר", + "poster_corners": "פינות הפוסטר", + "size_small": "קטן", + "size_medium": "בינוני", + "size_large": "גדול", + "corners_square": "ישרות", + "corners_rounded": "מעוגלות", + "corners_pill": "מעוגלות מאוד (Pill)", + "about_these_settings": "אודות ההגדרות הללו", + "about_desc": "הגדרות אלו קובעות כיצד יוצג התוכן במסך הבית שלכם. השינויים מוחלים מיידית ללא צורך בהפעלה מחדש.", + "hero_catalogs": { + "title": "קטלוגים לקרוסלה הראשי", + "select_all": "בחירת הכל", + "clear_all": "ניקוי הכל", + "info": "בחרו אילו קטלוגים יוצגו בקרוסלה הראשית. אם לא ייבחר דבר, ייעשה שימוש בכל הקטלוגים. אל תשכחו ללחוץ על שמירה בסיום.", + "settings_saved": "ההגדרות נשמרו", + "error_load": "טעינת הקטלוגים נכשלה", + "movies": "סרטים", + "tv_shows": "סדרות טלוויזיה" + } + }, + "calendar": { + "title": "לוח שידורים", + "loading": "טוען לוח שידורים...", + "no_scheduled_episodes": "אין פרקים מתוכננים", + "check_back_later": "בדקו שוב מאוחר יותר", + "showing_episodes_for": "מציג פרקים עבור {{date}}", + "show_all_episodes": "הצגת כל הפרקים", + "no_episodes_for": "אין פרקים עבור {{date}}", + "no_upcoming_found": "לא נמצאו פרקים קרובים", + "add_series_desc": "הוסיפו סדרות לספרייה שלכם כדי לראות את הפרקים הבאים שלהן כאן" + }, + "mdblist": { + "title": "מקורות דירוג", + "status_disabled": "MDBList כבוי", + "status_active": "מפתח API פעיל", + "status_required": "נדרש מפתח API", + "status_disabled_desc": "פונקציונליות MDBList מושבתת כרגע.", + "status_active_desc": "דירוגים מ-MDBList פעילים.", + "status_required_desc": "הוסיפו את המפתח שלכם למטה כדי להפעיל דירוגים.", + "enable_toggle": "הפעלת MDBList", + "enable_toggle_desc": "הפעלה/כיבוי של כל יכולות MDBList", + "api_section": "מפתח API", + "placeholder": "הדביקו את מפתח ה-API של MDBList", + "save": "שמירה", + "clear": "מחיקת מפתח", + "rating_providers": "ספקי דירוג", + "rating_providers_desc": "בחרו אילו דירוגים להציג באפליקציה", + "how_to": "איך משיגים מפתח API?", + "step_1": "התחברו לאתר", + "step_1_link": "MDBList", + "step_2": "עברו ללשונית", + "step_2_settings": "הגדרות (Settings)", + "step_2_api": "API", + "step_2_end": ".", + "step_3": "צרו מפתח חדש והעתיקו אותו.", + "go_to_website": "מעבר לאתר MDBList", + "alert_clear_title": "מחיקת מפתח API", + "alert_clear_msg": "האם אתם בטוחים שברצונכם להסיר את מפתח ה-API השמור?", + "success_saved": "מפתח ה-API נשמר בהצלחה.", + "error_empty": "מפתח ה-API אינו יכול להיות ריק.", + "error_save": "אירעה שגיאה במהלך השמירה. אנא נסו שוב.", + "api_key_empty_error": "מפתח ה-API אינו יכול להיות ריק.", + "success_cleared": "מפתח ה-API נמחק בהצלחה", + "error_clear": "מחיקת מפתח ה-API נכשלה" + }, + "notification": { + "title": "הגדרות התראות", + "section_general": "כללי", + "enable_notifications": "הפעלת התראות", + "section_types": "סוגי התראות", + "new_episodes": "פרקים חדשים", + "upcoming_shows": "סדרות קרובות", + "reminders": "תזכורות", + "section_timing": "תזמון התראות", + "timing_desc": "מתי תרצו לקבל התראה לפני שידור פרק?", + "hours_1": "שעה אחת", + "hours_suffix": "שעות", + "section_status": "סטטוס התראות", + "stats_upcoming": "קרובים", + "stats_this_week": "השבוע", + "stats_total": "סה\"כ", + "sync_button": "סנכרון ספרייה ו-Trakt", + "syncing": "מסנכרן...", + "sync_desc": "מסנכרן אוטומטית התראות עבור כל הסדרות בספרייה שלכם וברשימות ה-Trakt.", + "section_advanced": "מתקדם", + "reset_button": "איפוס כל ההתראות", + "test_button": "התראת בדיקה (5 שניות)", + "test_notification_in": "התראה בעוד {{seconds}} שניות...", + "test_notification_text": "התראה תופיע בעוד {{seconds}} שניות", + "alert_reset_title": "איפוס התראות", + "alert_reset_msg": "פעולה זו תבטל את כל ההתראות המתוזמנות, אך לא תסיר דבר מהספרייה השמורה. האם אתם בטוחים?", + "alert_reset_success": "כל ההתראות אופסו", + "alert_sync_complete": "הסנכרון הושלם", + "alert_sync_msg": "התראות עבור הספרייה ונתוני Trakt סונכרנו בהצלחה.\n\nתוזמנו: {{upcoming}} פרקים קרובים\nהשבוע: {{thisWeek}} פרקים", + "alert_test_scheduled": "התראת בדיקה תוזמנה להופעה מיידית" + }, + "backup": { + "title": "גיבוי ושחזור", + "options_title": "אפשרויות גיבוי", + "options_desc": "בחרו מה לכלול בגיבוי שלכם", + "section_core": "נתוני ליבה", + "section_addons": "תוספים ואינטגרציות", + "section_settings": "הגדרות והעדפות", + "library_label": "ספרייה", + "library_desc": "הסרטים וסדרות הטלוויזיה השמורים שלכם", + "watch_progress_label": "התקדמות צפייה", + "watch_progress_desc": "נקודות הזמן שבהן הפסקתם לצפות", + "addons_label": "תוספים", + "addons_desc": "תוספי Stremio מותקנים", + "plugins_label": "פלאגינים", + "plugins_desc": "הגדרות סורקים (Scrapers) מותאמות", + "trakt_label": "אינטגרציית Trakt", + "trakt_desc": "סנכרון נתונים ואסימוני אימות", + "app_settings_label": "הגדרות אפליקציה", + "app_settings_desc": "עיצוב, העדפות והגדרות מערכת", + "user_prefs_label": "העדפות משתמש", + "user_prefs_desc": "סדר תוספים והגדרות ממשק משתמש", + "catalog_settings_label": "הגדרות קטלוג", + "catalog_settings_desc": "מסנני קטלוג והעדפות", + "api_keys_label": "מפתחות API", + "api_keys_desc": "מפתחות MDBList ו-OpenRouter", + "action_create": "יצירת גיבוי", + "action_restore": "שחזור מגיבוי", + "section_info": "אודות גיבויים", + "info_text": "• ניתן להתאים מה יגובה באמצעות המתגים למעלה\n• קבצי הגיבוי נשמרים מקומית על המכשיר שלכם\n• שתפו את קובץ הגיבוי כדי להעביר נתונים בין מכשירים\n• שחזור יחליף את הנתונים הנוכחיים שלכם", + "alert_create_title": "יצירת גיבוי", + "alert_no_content": "לא נבחר תוכן לגיבוי.\n\nאנא הפעילו לפחות אפשרות אחת בסעיף אפשרויות הגיבוי.", + "alert_backup_created_title": "הגיבוי נוצר", + "alert_backup_created_msg": "הגיבוי שלכם נוצר ומוכן לשיתוף.", + "alert_backup_failed_title": "הגיבוי נכשל", + "alert_restore_confirm_title": "אישור שחזור", + "alert_restore_confirm_msg": "פעולה זו תשחזר נתונים מגיבוי שנוצר בתאריך {{date}}.\n\nפעולה זו תדרוס את הנתונים הנוכחיים שלכם. האם אתם בטוחים שברצונכם להמשיך?", + "alert_restore_complete_title": "השחזור הושלם", + "alert_restore_complete_msg": "הנתונים שוחזרו בהצלחה. אנא הפעילו מחדש את האפליקציה כדי לראות את השינויים.", + "alert_restore_failed_title": "השחזור נכשל", + "restart_app": "הפעלה מחדש", + "alert_restart_failed_title": "הפעלה מחדש נכשלה", + "alert_restart_failed_msg": "הפעלת האפליקציה מחדש נכשלה. אנא סגרו ופתחו את האפליקציה ידנית." + }, + "updates": { + "title": "עדכוני אפליקציה", + "status_checking": "בודק עדכונים...", + "status_available": "יש עדכון זמין!", + "status_downloading": "מוריד עדכון...", + "status_installing": "מתקין עדכון...", + "status_success": "העדכון הותקן בהצלחה!", + "status_error": "העדכון נכשל", + "status_ready": "מוכן לבדיקת עדכונים", + "action_check": "בדוק עדכונים", + "action_install": "התקן עדכון", + "release_notes": "הערות גרסה:", + "version": "גרסה:", + "last_checked": "בדיקה אחרונה:", + "current_version": "גרסה נוכחית:", + "current_release_notes": "הערות לגרסה הנוכחית:", + "github_release": "גרסת GITHUB", + "current": "נוכחית:", + "latest": "חדשה ביותר:", + "notes": "הערות:", + "view_release": "צפייה בגרסה", + "notification_settings": "הגדרות התראות", + "ota_alerts_label": "התראות עדכוני OTA", + "ota_alerts_desc": "הצגת התראות עבור עדכונים מהירים (Over-the-air)", + "major_alerts_label": "התראות על גרסאות ראשיות", + "major_alerts_desc": "הצגת התראות עבור גרסאות אפליקציה חדשות ב-GitHub", + "alert_disable_ota_title": "לבטל התראות עדכוני OTA?", + "alert_disable_ota_msg": "לא תקבלו יותר התראות אוטומטיות על עדכוני OTA.\n\n⚠️ אזהרה: שמירה על הגרסה העדכנית חשובה עבור:\n• תיקוני באגים ושיפורי יציבות\n• תכונות חדשות ושיפורים\n• מתן משוב ודיווחי קריסה מדויקים\n\nעדיין תוכלו לבדוק עדכונים ידנית במסך זה.", + "alert_disable_major_title": "לבטל התראות על גרסאות ראשיות?", + "alert_disable_major_msg": "לא תקבלו יותר התראות על עדכוני אפליקציה גדולים הדורשים התקנה מחדש.\n\n⚠️ אזהרה: עדכונים ראשיים כוללים לרוב:\n• תיקוני אבטחה קריטיים\n• שינויים משמעותיים הדורשים התקנה מחדש\n• תיקוני תאימות חשובים\n\nעדיין תוכלו לבדוק עדכונים ידנית.", + "warning_note": "השארת ההתראות פעילות מבטיחה שתקבלו תיקוני באגים ותוכלו לספק דיווחי קריסה מדויקים.", + "disable": "ביטול", + "alert_no_update_to_install": "אין עדכון זמין להתקנה", + "alert_install_failed": "התקנת העדכון נכשלה", + "alert_no_update_title": "אין עדכון", + "alert_update_applied_msg": "העדכון יוחל בהפעלה מחדש הבאה של האפליקציה" + }, + "player": { + "title": "נגן וידאו", + "section_selection": "בחירת נגן", + "internal_title": "נגן מובנה", + "internal_desc": "שימוש בנגן ברירת המחדל של האפליקציה", + "vlc_title": "VLC", + "vlc_desc": "פתיחת סטרימים בנגן VLC", + "infuse_title": "Infuse", + "infuse_desc": "פתיחת סטרימים בנגן Infuse", + "outplayer_title": "OutPlayer", + "outplayer_desc": "פתיחת סטרימים בנגן OutPlayer", + "vidhub_title": "VidHub", + "vidhub_desc": "פתיחת סטרימים בנגן VidHub", + "infuse_live_title": "Infuse Livecontainer", + "infuse_live_desc": "פתיחת סטרימים ב-Infuse דרך LiveContainer", + "external_title": "נגן חיצוני", + "external_desc": "פתיחת סטרימים בנגן הוידאו המועדף עליכם", + "section_playback": "אפשרויות ניגון", + "skip_intro_settings_title": "דילוג על פתיח", + "powered_by_introdb": "מופעל על ידי IntroDB", + "autoplay_title": "ניגון אוטומטי של המקור הראשון", + "autoplay_desc": "התחלת הסטרים הראשון המופיע ברשימה באופן אוטומטי.", + "resume_title": "המשך צפייה תמידי", + "resume_desc": "דילוג על שאלת ה-'המשך צפייה' והמשך אוטומטי מהנקודה האחרונה (אם נצפה פחות מ-85%).", + "engine_title": "מנוע נגן וידאו", + "engine_desc": "במצב אוטומטי נעשה שימוש ב-ExoPlayer עם גיבוי של MPV. פורמטים מסוימים כמו Dolby Vision ו-HDR עשויים לא להיתמך ב-MPV, לכן מומלץ להישאר על אוטומטי.", + "decoder_title": "מצב מפענח (Decoder)", + "decoder_desc": "כיצד הוידאו מפוענח. מומלץ לבחור באוטומטי לאיזון מיטבי.", + "gpu_title": "רינדור GPU", + "gpu_desc": "GPU-Next מציע ניהול צבעים ו-HDR טובים יותר.", + "external_downloads_title": "נגן חיצוני עבור הורדות", + "external_downloads_desc": "ניגון תוכן שהורד בנגן חיצוני מועדף.", + "restart_required": "נדרשת הפעלה מחדש", + "restart_msg_decoder": "אנא הפעילו מחדש את האפליקציה כדי ששינוי המפענח ייכנס לתוקף.", + "restart_msg_gpu": "אנא הפעילו מחדש את האפליקציה כדי ששינוי מצב ה-GPU ייכנס לתוקף.", + "option_auto": "אוטומטי", + "option_auto_desc_engine": "ExoPlayer + גיבוי MPV", + "option_mpv": "MPV", + "option_mpv_desc": "MPV בלבד", + "option_auto_desc_decoder": "איזון מיטבי", + "option_sw": "SW", + "option_sw_desc": "תוכנה (Software)", + "option_hw": "HW", + "option_hw_desc": "חומרה (Hardware)", + "option_hw_plus": "HW+", + "option_hw_plus_desc": "חומרה מלאה", + "option_gpu_desc": "סטנדרטי", + "option_gpu_next_desc": "מתקדם" + }, + "plugins": { + "title": "תוספים (Plugins)", + "enable_title": "הפעלת תוספים", + "enable_desc": "הפעלת מנוע התוספים כדי לאתר מקורות מדיה חיצוניים", + "repo_config_title": "הגדרות מאגר (Repository)", + "repo_config_desc": "ניהול מאגרי תוספים חיצוניים. ניתן להפעיל או לכבות כל מאגר להלן.", + "your_repos": "מאגרים", + "your_repos_desc": "הגדרת מקורות חיצוניים עבור תוספים.", + "add_repo_button": "הוספת מאגר", + "refresh": "רענון", + "remove": "הסרה", + "enabled": "פעיל", + "disabled": "כבוי", + "updating": "מעדכן...", + "success": "הצלחנו", + "error": "שגיאה", + "alert_repo_added": "המאגר נוסף והתוספים נטענו בהצלחח", + "alert_repo_saved": "כתובת המאגר נשמרה בהצלחה", + "alert_repo_refreshed": "המאגר רוענן בהצלחה", + "alert_invalid_url": "פורמט כתובת (URL) לא תקין", + "alert_plugins_cleared": "כל התוספים הוסרו", + "alert_cache_cleared": "מטמון המאגרים נוקה בהצלחה", + "unknown": "לא ידוע", + "active": "פעיל", + "available": "זמין", + "platform_disabled": "פלטפורמה כבויה", + "limited": "מוגבל", + "clear_all": "הסרת כל התוספים", + "clear_all_desc": "האם אתם בטוחים שברצונכם להסיר את כל התוספים המותקנים? לא ניתן לבטל פעולה זו.", + "clear_cache": "ניקוי מטמון מאגרים", + "clear_cache_desc": "פעולה זו תחמוק את כתובת המאגר ותנקה את כל נתוני התוספים השמורים. תצטרכו להזין מחדש את כתובת המאגר.", + "add_new_repo": "הוספת מאגר חדש", + "available_plugins": "תוספים זמינים ({{count}})", + "placeholder": "חיפוש תוספים...", + "all": "הכל", + "filter_all": "כל הסוגים", + "filter_movies": "סרטים", + "filter_tv": "סדרות טלוויזיה", + "enable_all": "הפעלת הכל", + "disable_all": "ביטול הכל", + "no_plugins_found": "לא נמצאו תוספים", + "no_plugins_available": "אין תוספים זמינים", + "no_match_desc": "לא נמצאו תוספים התואמים ל-\"{{query}}\". נסו מונח חיפוש אחר.", + "configure_repo_desc": "הגדירו מאגר למעלה כדי לצפות בתוספים זמינים.", + "clear_search": "ניקוי חיפוש", + "no_external_player": "אין נגן חיצוני", + "showbox_token": "ShowBox UI Token", + "showbox_placeholder": "הדביקו את ה-token של ShowBox כאן", + "save": "שמירה", + "clear": "ניקוי", + "additional_settings": "הגדרות נוספות", + "enable_url_validation": "הפעלת אימות כתובת (URL)", + "url_validation_desc": "אימות כתובות מדיה לפני הצגתן (עשוי להאט את התוצאות אך משפר אמינות)", + "group_streams": "קיבוץ מקורות תוספים", + "group_streams_desc": "כאשר פעיל, המקורות מקובצים לפי מאגר. כשר כבוי, כל תוסף מופיע כספק נפרד.", + "sort_quality": "מיון לפי איכות תחילה", + "sort_quality_desc": "כאשר פעיל, המקורות ממוינים לפי איכות. זמין רק כאשר קיבוץ המקורות מופעל.", + "show_logos": "הצגת לוגו התוסף", + "show_logos_desc": "הצגת לוגו התוסף לצד קישורי המדיה במסך המקורות.", + "quality_filtering": "סינון איכות", + "quality_filtering_desc": "החרגת רזולוציות וידאו ספציפיות מתוצאות החיפוש. לחצו על איכות כדי להחריג אותה.", + "excluded_qualities": "איכויות שהוחרגו:", + "language_filtering": "סינון שפה", + "language_filtering_desc": "החרגת שפות ספציפיות מתוצאות החיפוש. לחצו על שפה כדי להחריג אותה.", + "note": "הערה:", + "language_filtering_note": "מסנן זה חל רק על ספקים הכוללים מידע על שפה. הוא אינו משפיע על ספקים אחרים.", + "excluded_languages": "שפות שהוחרגו:", + "about_title": "אודות תוספים", + "about_desc_1": "תוספים הם רכיבים מודולריים שמתאימים תוכן מפרוטוקולים חיצוניים שונים. הם רצים מקומית על המכשיר שלכם וניתנים להתקנה ממאגרים מהימנים.", + "about_desc_2": "תוספים המסומנים כ-\"מוגבלים\" עשויים לדרוש הגדרות חיצוניות ספציפיות.", + "help_title": "הגדרת תוספים", + "help_step_1": "1. **הפעלת תוספים** - הפעילו את המתג הראשי", + "help_step_2": "2. **הוספת מאגר** - הוסיפו כתובת מאגר (URL) תקינה", + "help_step_3": "3. **רענון מאגר** - טעינת התוספים הזמינים", + "help_step_4": "4. **הפעלה** - הפעילו את התוספים שבהם תרצו להשתמש", + "got_it": "הבנתי!", + "repo_format_hint": "פורמט: https://raw.githubusercontent.com/username/repo/refs/heads/branch", + "cancel": "ביטול", + "add": "הוספה" + }, + "theme": { + "title": "ערכות נושא (Themes)", + "select_theme": "בחירת ערכת נושא", + "create_custom": "יצירת ערכה מותאמת אישית", + "options": "אפשרויות", + "use_dominant_color": "שימוש בצבע הדומיננטי מהפוסטר", + "categories": { + "all": "כל הערכות", + "dark": "ערכות כהות", + "colorful": "צבעוני", + "custom": "הערכות שלי" + }, + "editor": { + "theme_name_placeholder": "שם ערכת הנושא", + "save": "שמירה", + "primary": "ראשי", + "secondary": "משני", + "background": "רקע", + "invalid_name_title": "שם לא תקין", + "invalid_name_msg": "אנא הזינו שם תקין לערכת הנושא" + }, + "alerts": { + "delete_title": "מחיקת ערכת נושא", + "delete_msg": "האם אתם בטוחים שברצונכם למחוק את \"{{name}}\"?", + "ok": "אישור", + "delete": "מחיקה", + "cancel": "ביטול", + "back": "הגדרות" + } + }, + "legal": { + "title": "משפטי והצהרת אחריות", + "intro_title": "מהות האפליקציה", + "intro_text": "Nuvio היא נגן מדיה ואפליקציה לניהול מטא-דאטה. היא משמשת אך ורק כממשק צד-לקוח לדפדוף במידע זמין לציבור (סרטים, סדרות וכו') ולניגון קבצי מדיה המסופקים על ידי המשתמש או תוספי צד-שלישי. Nuvio עצמה אינה מארחת, מאחסנת, מפיצה או מקטלגת תוכן מדיה כלשהו.", + "extensions_title": "תוספי צד-שלישי", + "extensions_text": "Nuvio משתמשת בארכיטקטורה הניתנת להרחבה המאפשרת למשתמשים להתקין תוספי צד-שלישי. תוספים אלו מפותחים ומתוחזקים על ידי מפתחים עצמאיים שאינם קשורים ל-Nuvio. אין לנו שליטה על התוכן, החוקיות או הפונקציונליות של תוספי צד-שלישי כלשהם, ואנו לא נושאים באחריות לגביהם.", + "user_resp_title": "אחריות המשתמש", + "user_resp_text": "המשתמשים אחראים בלעדית לתוספים שהם מתקינים ולתוכן שאליו הם ניגשים. בשימוש באפליקציה זו, אתם מסכימים לוודא שיש לכם את הזכות החוקית לגשת לכל תוכן שבו אתם צופים באמצעות Nuvio. מפתחי Nuvio אינם תומכים או מעודדים הפרת זכויות יוצרים.", + "dmca_title": "זכויות יוצרים ו-DMCA", + "dmca_text": "אנו מכבדים את זכויות הקניין הרוחני של אחרים. כיוון ש-Nuvio אינה מארחת תוכן, אין ביכולתנו להסיר תוכן מהאינטרנט. עם זאת, אם אתם סבורים שממשק האפליקציה עצמו מפר את זכויותיכם, אנא צרו עמנו קשר.", + "warranty_title": "העדר אחריות", + "warranty_text": "תוכנה זו מסופקת \"כפי שהיא\" (As-Is), ללא אחריות מכל סוג שהוא. בשום מקרה המפתחים או בעלי זכויות היוצרים לא יהיו אחראים לכל תביעה, נזק או חבות אחרת הנובעת מהשימוש בתוכנה זו." + }, + "plugin_tester": { + "title": "בודק תוספים (Plugin Tester)", + "subtitle": "הרצת סורקים ובדיקת לוגים בזמן אמת", + "tabs": { + "individual": "אישי", + "repo": "בודק מאגר", + "code": "קוד", + "logs": "לוגים", + "results": "תוצאות" + }, + "common": { + "error": "שגיאה", + "success": "הצלחה", + "movie": "סרט", + "tv": "סדרה", + "tmdb_id": "TMDB ID", + "season": "עונה", + "episode": "פרק", + "running": "מריץ...", + "run_test": "הפעלת בדיקה", + "play": "נגן", + "done": "בוצע", + "test": "בדיקה", + "testing": "בודק..." + }, + "individual": { + "load_from_url": "טעינה מכתובת (URL)", + "load_from_url_desc": "הדביקו כתובת גולמית מ-GitHub או IP מקומי ולחצו על הורדה.", + "enter_url_error": "אנא הזינו כתובת URL", + "code_loaded": "הקוד נטען בהצלחה מהכתובת", + "fetch_error": "הטעינה נכשלה: {{message}}", + "no_code_error": "אין קוד להרצה", + "plugin_code": "קוד התוסף", + "focus_editor": "מיקוד בעורך הקוד", + "code_placeholder": "// הדביקו את קוד התוסף כאן...", + "test_parameters": "פרמטרים לבדיקה", + "no_logs": "אין עדיין לוגים. הריצו בדיקה כדי לראות פלט.", + "no_streams": "לא נמצאו מקורות (Streams) עדיין.", + "streams_found": "נמצא מקור {{count}}", + "streams_found_plural": "נמצאו {{count}} מקורות", + "tap_play_hint": "לחצו על 'נגן' כדי לבדוק את המקור בנגן המובנה.", + "unnamed_stream": "מקור ללא שם", + "quality": "איכות: {{quality}}", + "size": "גודל: {{size}}", + "url_label": "כתובת: {{url}}", + "headers_info": "Headers: {{count}} כותרות מותאמות", + "find_placeholder": "חיפוש בקוד...", + "edit_code_title": "עריכת קוד", + "no_url_stream_error": "לא נמצאה כתובת למקור זה" + }, + "repo": { + "title": "בודק מאגרים", + "description": "טעינת מאגר (כתובת מקומית או GitHub raw) ובדיקת כל ספק.", + "enter_repo_url_error": "אנא הזינו כתובת מאגר (URL)", + "invalid_url_title": "כתובת לא תקינה", + "invalid_url_msg": "השתמשו בכתובת raw של GitHub או כתובת http(s) מקומית.\n\nדוגמה:\nhttps://raw.githubusercontent.com/tapframe/nuvio-providers/refs/heads/main", + "manifest_build_error": "לא ניתן היה ליצור כתובת מניפסט מהקלט", + "manifest_fetch_error": "טעינת המניפסט נכשלה", + "repo_manifest_fetch_error": "טעינת מניפסט המאגר נכשלה", + "missing_filename": "שם קובץ חסר במניפסט", + "scraper_build_error": "לא ניתן היה ליצור כתובת לסורק (Scraper)", + "download_scraper_error": "הורדת הסורק נכשלה", + "test_failed": "הבדיקה נכשלה", + "test_parameters": "פרמטרים לבדיקת מאגר", + "test_parameters_desc": "פרמטרים אלו משמשים רק עבור בודק המאגרים.", + "using_info": "משתמש ב: {{mediaType}} • TMDB {{tmdbId}}", + "using_info_tv": "משתמש ב: {{mediaType}} • TMDB {{tmdbId}} • עונה {{season}} פרק {{episode}}", + "providers_title": "ספקים (Providers)", + "repository_default": "מאגר", + "providers_count": "{{count}} ספקים", + "fetch_hint": "טענו מאגר כדי להציג את רשימת הספקים.", + "test_all": "בדיקת הכל", + "status_running": "רץ", + "status_ok": "תקין ({{count}})", + "status_ok_empty": "תקין (0)", + "status_failed": "נכשל", + "status_idle": "ממתין", + "tried_url": "נוסה: {{url}}", + "provider_logs": "לוגים של הספק", + "no_logs_captured": "לא נלכדו לוגים." + } + } +} \ No newline at end of file diff --git a/src/i18n/locales/hi.json b/src/i18n/locales/hi.json index df34dc67..15fa5631 100644 --- a/src/i18n/locales/hi.json +++ b/src/i18n/locales/hi.json @@ -636,6 +636,18 @@ "chinese": "चीनी (सरलीकृत)", "hindi": "हिन्दी", "serbian": "सर्बियाई", + "hebrew": "इब्रानी", + "bulgarian": "बुल्गारियाई", + "polish": "पोलिश", + "czech": "चेक", + "turkish": "तुर्की", + "slovenian": "स्लोवेनियाई", + "macedonian": "मकदूनियाई", + "russian": "रूसी", + "filipino": "फ़िलिपिनो", + "dutch_nl": "डच (नीदरलैंड)", + "romanian": "रोमानियाई", + "albanian": "अल्बानियाई", "account": "खाता", "content_discovery": "सामग्री और खोज", "appearance": "दिखावट", @@ -896,8 +908,8 @@ }, "debrid": { "title": "Debrid एकीकरण", - "description_torbox": "Torbox को एकीकृत करके 4K उच्च-गुणवत्ता वाले स्ट्रीम और बिजली की तेज़ गति अनलॉक करें। अपने स्ट्रीमिंग अनुभव को तुरंत अपग्रेड करने के लिए नीचे अपनी API कुंजी दर्ज करें।", - "description_torrentio": "फिल्मों और टीवी शो के लिए टोरेंट स्ट्रीम प्राप्त करने के लिए Torrentio कॉन्फ़िगर करें। सामग्री स्ट्रीम करने के लिए एक डेब्रिड सेवा आवश्यक है।", + "description_torbox": "Connect Torbox to use your account-based source preferences. Enter your API key below to configure the integration.", + "description_torrentio": "Configure Torrentio as an external source integration. A compatible debrid account may be required depending on your setup.", "tab_torbox": "TorBox", "tab_torrentio": "Torrentio", "status_connected": "जुड़ा हुआ", @@ -924,15 +936,15 @@ "enter_api_key": "अपनी API कुंजी दर्ज करें", "connect_button": "कनेक्ट करें और इंस्टॉल करें", "connecting": "कनेक्ट किया जा रहा है...", - "unlock_speeds_title": "प्रीमियम गति अनलॉक करें", - "unlock_speeds_desc": "शून्य बफरिंग के साथ कैश किए गए उच्च-गुणवत्ता वाले स्ट्रीम तक पहुंचने के लिए Torbox सदस्यता प्राप्त करें।", + "unlock_speeds_title": "Optional Torbox Subscription", + "unlock_speeds_desc": "Torbox offers account tiers with enhanced performance and availability features.", "get_subscription": "सदस्यता प्राप्त करें", "powered_by": "द्वारा संचालित", "disclaimer_torbox": "Nuvio किसी भी तरह से Torbox से संबद्ध नहीं है।", "disclaimer_torrentio": "Nuvio किसी भी तरह से Torrentio से संबद्ध नहीं है।", "installed_badge": "✓ स्थापित", "promo_title": "⚡ एक Debrid सेवा की आवश्यकता है?", - "promo_desc": "शून्य बफरिंग के साथ बिजली की तेज़ 4K स्ट्रीमिंग के लिए TorBox प्राप्त करें। प्रीमियम कैश किए गए टोरेंट और तत्काल डाउनलोड।", + "promo_desc": "Use TorBox if you want account-managed performance features for supported integrations.", "promo_button": "TorBox सदस्यता प्राप्त करें", "service_label": "Debrid सेवा *", "api_key_label": "API कुंजी *", @@ -1324,7 +1336,7 @@ "user_resp_title": "उपयोगकर्ता जिम्मेदारी", "user_resp_text": "उपयोगकर्ता पूरी तरह से उन प्लगइन्स के लिए जिम्मेदार हैं जिन्हें वे स्थापित करते हैं और जिस सामग्री तक वे पहुंचते हैं। इस एप्लिकेशन का उपयोग करके, आप यह सुनिश्चित करने के लिए सहमत हैं कि आपके पास Nuvio का उपयोग करके किसी भी सामग्री को देखने का कानूनी अधिकार है। Nuvio के डेवलपर्स कॉपीराइट उल्लंघन का समर्थन या प्रोत्साहन नहीं करते हैं।", "dmca_title": "कॉपीराइट और DMCA", - "dmca_text": "हम दूसरों के बौद्धिक संपदा अधिकारों का सम्मान करते हैं। चूंकि Nuvio किसी भी सामग्री को होस्ट नहीं करता है, इसलिए हम इंटरनेट से सामग्री नहीं हटा सकते हैं। हालाँकि, यदि आपको लगता है कि एप्लिकेशन इंटरफ़ेस स्वयं आपके अधिकारों का उल्लंघन करता है, तो कृपया हमसे संपर्क करें।", + "dmca_text": "We respect the intellectual property rights of others. Nuvio does not host media content. If you believe this project's code, assets, or interface infringes your rights, submit a notice through the official project contact channels listed on the website and repository.", "warranty_title": "कोई वारंटी नहीं", "warranty_text": "यह सॉफ़्टवेयर \"जैसा है\" प्रदान किया जाता है, बिना किसी प्रकार की वारंटी, व्यक्त या निहित। किसी भी स्थिति में लेखक या कॉपीराइट धारक इस सॉफ़्टवेयर के उपयोग से उत्पन्न किसी भी दावे, क्षति या अन्य दायित्व के लिए उत्तरदायी नहीं होंगे।" }, diff --git a/src/i18n/locales/hr.json b/src/i18n/locales/hr.json index 09bdfa73..e974081c 100644 --- a/src/i18n/locales/hr.json +++ b/src/i18n/locales/hr.json @@ -1,1414 +1,1413 @@ -{ - "common": { - "loading": "Učitavanje...", - "cancel": "Odustani", - "save": "Spremi", - "delete": "Obriši", - "edit": "Uredi", - "search": "Pretraži", - "error": "Pogreška", - "success": "Uspjeh", - "ok": "U redu", - "unknown": "Nepoznato", - "retry": "Pokušaj ponovno", - "try_again": "Pokušajte ponovno", - "go_back": "Idi natrag", - "settings": "Postavke", - "close": "Zatvori", - "enable": "Omogući", - "disable": "Onemogući", - "show_more": "Prikaži više", - "show_less": "Prikaži manje", - "load_more": "Učitaj više", - "unknown_date": "Nepoznat datum", - "anonymous_user": "Anonimni korisnik", - "time": { - "now": "Upravo sada", - "minutes_ago": "prije {{count}} min", - "hours_ago": "prije {{count}} h", - "days_ago": "prije {{count}} d" - }, - "days_short": { - "sun": "Ned", - "mon": "Pon", - "tue": "Uto", - "wed": "Sri", - "thu": "Čet", - "fri": "Pet", - "sat": "Sub" - }, - "email": "E-pošta", - "status": "Status" - }, - "home": { - "categories": { - "movies": "Filmovi", - "series": "Serije", - "channels": "Kanali" - }, - "movies": "Filmovi", - "tv_shows": "Serije", - "load_more_catalogs": "Učitaj više kataloga", - "no_content": "Sadržaj nije dostupan", - "add_catalogs": "Dodaj kataloge", - "sign_in_available": "Prijava je dostupna", - "sign_in_desc": "Možete se prijaviti bilo kada u Postavke → Račun", - "view_all": "Vidi sve", - "this_week": "Ovaj tjedan", - "upcoming": "Dolazeće", - "recently_released": "Nedavno objavljeno", - "no_scheduled_episodes": "Serije bez zakazanih epizoda", - "check_back_later": "Provjerite kasnije", - "continue_watching": "Nastavi gledati", - "up_next": "Sljedeće", - "up_next_caps": "SLJEDEĆE", - "released": "Objavljeno", - "new": "Novo", - "tba": "Bit će objavljeno", - "new_episodes": "{{count}} nove epizode", - "season_short": "S{{season}}", - "episode_short": "E{{episode}}", - "season": "Sezona {{season}}", - "episode": "Epizoda {{episode}}", - "movie": "Film", - "series": "Serija", - "tv_show": "Serija", - "percent_watched": "{{percent}}% pogledano", - "view_details": "Vidi detalje", - "remove": "Ukloni", - "play": "Reproduciraj", - "play_now": "Pokreni odmah", - "resume": "Nastavi", - "info": "Informacije", - "more_info": "Više informacija", - "my_list": "Moj popis", - "save": "Spremi", - "saved": "Spremljeno", - "retry": "Pokušaj ponovno", - "install_addons": "Instaliraj dodatke", - "settings": "Postavke", - "no_featured_content": "Nema istaknutog sadržaja", - "couldnt_load_featured": "Nije moguće učitati istaknuti sadržaj", - "no_featured_desc": "Instalirajte dodatke s katalozima ili promijenite izvor sadržaja u postavkama.", - "load_error_desc": "Došlo je do problema prilikom dohvaćanja istaknutog sadržaja. Provjerite vezu i pokušajte ponovno.", - "no_featured_available": "Nema dostupnog istaknutog sadržaja", - "no_description": "Opis nije dostupan" - }, - "navigation": { - "home": "Početna", - "library": "Knjižnica", - "search": "Pretraživanje", - "downloads": "Preuzimanja", - "settings": "Postavke" - }, - "search": { - "title": "Pretraživanje", - "recent_searches": "Nedavna pretraživanja", - "discover": "Otkrij", - "movies": "Filmovi", - "tv_shows": "Serije", - "select_catalog": "Odaberi katalog", - "all_genres": "Svi žanrovi", - "discovering": "Otkrivanje sadržaja...", - "show_more": "Prikaži više ({{count}})", - "no_content_found": "Sadržaj nije pronađen", - "try_different": "Pokušajte s drugim žanrom ili katalogom", - "select_catalog_desc": "Odaberite katalog za istraživanje", - "tap_catalog_desc": "Dodirnite karticu kataloga iznad za početak", - "placeholder": "Pretraži filmove, serije...", - "keep_typing": "Nastavite tipkati...", - "type_characters": "Upišite barem 2 znaka za pretraživanje", - "no_results": "Nema rezultata", - "try_keywords": "Pokušajte s drugim ključnim riječima ili provjerite pravopis", - "select_type": "Odaberi vrstu", - "browse_movies": "Pregledaj kataloge filmova", - "browse_tv": "Pregledaj kataloge serija", - "select_genre": "Odaberi žanr", - "show_all_content": "Prikaži sav sadržaj", - "genres_count": "{{count}} žanrova" - }, - "library": { - "title": "Knjižnica", - "watched": "Pogledano", - "continue": "Nastavi", - "watchlist": "Popis za gledanje", - "collection": "Kolekcija", - "rated": "Ocijenjeno", - "items": "stavki", - "trakt_collections": "Trakt kolekcije", - "trakt_collection": "Trakt kolekcija", - "no_trakt": "Nema Trakt kolekcija", - "no_trakt_desc": "Vaše Trakt kolekcije pojavit će se ovdje kada počnete koristiti Trakt", - "load_collections": "Učitaj kolekcije", - "empty_folder": "Nema sadržaja u {{folder}}", - "empty_folder_desc": "Ova kolekcija je prazna", - "refresh": "Osvježi", - "no_movies": "Još nema filmova", - "no_series": "Još nema serija", - "no_content": "Još nema sadržaja", - "add_content_desc": "Dodajte sadržaj u svoju knjižnicu kako biste ga vidjeli ovdje", - "find_something": "Pronađi nešto za gledanje", - "removed_from_library": "Uklonjeno iz knjižnice", - "item_removed": "Stavka je uklonjena iz vaše knjižnice", - "failed_update_library": "Ažuriranje knjižnice nije uspjelo", - "unable_remove": "Nije moguće ukloniti stavku iz knjižnice", - "marked_watched": "Označeno kao pogledano", - "marked_unwatched": "Označeno kao nepogledano", - "item_marked_watched": "Stavka je označena kao pogledana", - "item_marked_unwatched": "Stavka je označena kao nepogledana", - "failed_update_watched": "Ažuriranje statusa gledanja nije uspjelo", - "unable_update_watched": "Nije moguće ažurirati status gledanja", - "added_to_library": "Dodano u knjižnicu", - "item_added": "Dodano u vašu lokalnu knjižnicu", - "add_to_library": "Dodaj u knjižnicu", - "remove_from_library": "Ukloni iz knjižnice", - "mark_watched": "Označi kao pogledano", - "mark_unwatched": "Označi kao nepogledano", - "share": "Podijeli", - "add_to_watchlist": "Dodaj na Trakt popis za gledanje", - "remove_from_watchlist": "Ukloni s Trakt popisa za gledanje", - "added_to_watchlist": "Dodano na popis za gledanje", - "added_to_watchlist_desc": "Dodano na vaš Trakt popis za gledanje", - "removed_from_watchlist": "Uklonjeno s popisa za gledanje", - "removed_from_watchlist_desc": "Uklonjeno s vašeg Trakt popisa za gledanje", - "add_to_collection": "Dodaj u Trakt kolekciju", - "remove_from_collection": "Ukloni iz Trakt kolekcije", - "added_to_collection": "Dodano u kolekciju", - "added_to_collection_desc": "Dodano u vašu Trakt kolekciju", - "removed_from_collection": "Uklonjeno iz kolekcije", - "removed_from_collection_desc": "Uklonjeno iz vaše Trakt kolekcije" - }, - "metadata": { - "unable_to_load": "Nije moguće učitati sadržaj", - "error_code": "Šifra pogreške: {{code}}", - "content_not_found": "Sadržaj nije pronađen", - "content_not_found_desc": "Ovaj sadržaj ne postoji ili je možda uklonjen.", - "server_error": "Pogreška poslužitelja", - "server_error_desc": "Poslužitelj je privremeno nedostupan. Pokušajte ponovno kasnije.", - "bad_gateway": "Loš gateway", - "bad_gateway_desc": "Poslužitelj ima poteškoća. Pokušajte ponovno kasnije.", - "service_unavailable": "Usluga nedostupna", - "service_unavailable_desc": "Usluga je trenutno na održavanju. Pokušajte ponovno kasnije.", - "too_many_requests": "Previše zahtjeva", - "too_many_requests_desc": "Šaljete previše zahtjeva. Pričekajte trenutak i pokušajte ponovno.", - "request_timeout": "Istek vremena zahtjeva", - "request_timeout_desc": "Zahtjev je trajao predugo. Pokušajte ponovno.", - "network_error": "Pogreška mreže", - "network_error_desc": "Provjerite internetsku vezu i pokušajte ponovno.", - "auth_error": "Pogreška autentifikacije", - "auth_error_desc": "Provjerite postavke računa i pokušajte ponovno.", - "access_denied": "Pristup odbijen", - "access_denied_desc": "Nemate dopuštenje za pristup ovom sadržaju.", - "connection_error": "Pogreška veze", - "streams_unavailable": "Streaming izvori nedostupni", - "streams_unavailable_desc": "Izvori za streaming trenutno su nedostupni. Pokušajte ponovno kasnije.", - "unknown_error": "Nepoznata pogreška", - "something_went_wrong": "Nešto je pošlo po zlu. Pokušajte ponovno.", - "cast": "Glumačka postava", - "more_like_this": "Slično ovome", - "collection": "Kolekcija", - "episodes": "Epizode", - "seasons": "Sezone", - "posters": "Posteri", - "banners": "Banneri", - "specials": "Specijali", - "season_number": "Sezona {{number}}", - "episode_count": "{{count}} epizoda", - "episode_count_plural": "{{count}} epizoda", - "no_episodes": "Nema dostupnih epizoda", - "no_episodes_for_season": "Nema dostupnih epizoda za Sezonu {{season}}", - "episodes_not_released": "Epizode možda još nisu objavljene", - "no_description": "Opis nije dostupan", - "episode_label": "EPIZODA {{number}}", - "watch_again": "Gledaj ponovno", - "completed": "Završeno", - "play_episode": "Reproduciraj S{{season}}E{{episode}}", - "play": "Reproduciraj", - "watched": "Pogledano", - "watched_on_trakt": "Pogledano na Traktu", - "synced_with_trakt": "Sinkronizirano s Traktom", - "saved": "Spremljeno", - "director": "Redatelj", - "directors": "Redatelji", - "creator": "Autor", - "creators": "Autori", - "production": "Produkcija", - "network": "Mreža", - "mark_watched": "Označi kao pogledano", - "mark_unwatched": "Označi kao nepogledano", - "marking": "Označavanje...", - "removing": "Uklanjanje...", - "unmark_season": "Odznači Sezonu {{season}}", - "mark_season": "Označi Sezonu {{season}}", - "resume": "Nastavi", - "spoiler_warning": "Upozorenje o spoilerima", - "spoiler_warning_desc": "Ovaj komentar sadrži spoilere. Jeste li sigurni da ga želite otkriti?", - "cancel": "Odustani", - "reveal_spoilers": "Otkrij spoilere", - "movie_details": "Detalji o filmu", - "show_details": "Detalji o seriji", - "tagline": "Slogan", - "status": "Status", - "release_date": "Datum izlaska", - "runtime": "Trajanje", - "budget": "Budžet", - "revenue": "Prihod", - "origin_country": "Zemlja podrijetla", - "original_language": "Izvorni jezik", - "first_air_date": "Datum prve emisije", - "last_air_date": "Datum zadnje emisije", - "total_episodes": "Ukupno epizoda", - "episode_runtime": "Trajanje epizode", - "created_by": "Autor", - "backdrop_gallery": "Galerija pozadina", - "loading_episodes": "Učitavanje epizoda...", - "no_episodes_available": "Nema dostupnih epizoda", - "play_next": "Reproduciraj S{{season}}E{{episode}}", - "play_next_episode": "Reproduciraj sljedeću epizodu", - "save": "Spremi", - "percent_watched": "{{percent}}% pogledano", - "percent_watched_trakt": "{{percent}}% pogledano ({{traktPercent}}% na Traktu)", - "synced_with_trakt_progress": "Sinkronizirano s Traktom", - "using_trakt_progress": "Koristi se Trakt napredak", - "added_to_collection_hero": "Dodano u kolekciju", - "added_to_collection_desc_hero": "Dodano u vašu Trakt kolekciju", - "removed_from_collection_hero": "Uklonjeno iz kolekcije", - "removed_from_collection_desc_hero": "Uklonjeno iz vaše Trakt kolekcije", - "mark_as_watched": "Označi kao pogledano", - "mark_as_unwatched": "Označi kao nepogledano" - }, - "cast": { - "biography": "Biografija", - "known_for": "Poznat po", - "personal_info": "Osobni podaci", - "born_in": "Rođen u {{place}}", - "filmography": "Filmografija", - "also_known_as": "Poznat i kao", - "no_info_available": "Dodatne informacije nisu dostupne", - "as_character": "kao {{character}}", - "loading_details": "Učitavanje detalja...", - "years_old": "{{age}} godina", - "view_filmography": "Vidi filmografiju", - "filter": "Filter", - "sort_by": "Sortiraj po", - "sort_popular": "Popularno", - "sort_latest": "Najnovije", - "sort_upcoming": "Dolazeće", - "upcoming_badge": "DOLAZI", - "coming_soon": "Dolazi uskoro", - "filmography_count": "Filmografija • {{count}} naslova", - "loading_filmography": "Učitavanje filmografije...", - "load_more_remaining": "Učitaj više (preostalo {{count}})", - "alert_error_title": "Pogreška", - "alert_error_message": "Nije moguće učitati \"{{title}}\". Pokušajte ponovno kasnije.", - "alert_ok": "U redu", - "no_upcoming": "Nema dolazećih izdanja za ovog glumca", - "no_content": "Sadržaj nije dostupan za ovog glumca", - "no_movies": "Nema dostupnih filmova za ovog glumca", - "no_tv": "Nema dostupnih serija za ovog glumca" - }, - "comments": { - "title": "Trakt komentari", - "spoiler_warning": "⚠️ Ovaj komentar sadrži spoilere. Dodirni za prikaz.", - "spoiler": "Spoiler", - "contains_spoilers": "Sadrži spoilere", - "reveal": "Otkrij", - "vip": "VIP", - "unavailable": "Komentari nedostupni", - "no_comments": "Još nema komentara na Traktu", - "not_in_database": "Ovaj sadržaj možda još nije u Trakt bazi podataka", - "check_trakt": "Provjeri Trakt" - }, - "trailers": { - "title": "Traileri", - "official_trailers": "Službeni traileri", - "official_trailer": "Službeni trailer", - "teasers": "Teaseri", - "teaser": "Teaser", - "clips_scenes": "Isječci i scene", - "clip": "Isječak", - "featurettes": "Featurettes", - "featurette": "Featurette", - "behind_the_scenes": "Iza kulisa", - "no_trailers": "Nema dostupnih trailera", - "unavailable": "Trailer nedostupan", - "unavailable_desc": "Ovaj trailer trenutno se ne može učitati. Pokušajte ponovno kasnije.", - "unable_to_play": "Nije moguće reproducirati trailer. Pokušajte ponovno.", - "watch_on_youtube": "Gledaj na YouTubeu" - }, - "catalog": { - "no_content_found": "Sadržaj nije pronađen", - "no_content_filters": "Nije pronađen sadržaj za odabrane filtere", - "loading_content": "Učitavanje sadržaja...", - "back": "Natrag", - "in_theaters": "U kinima", - "all": "Sve", - "failed_tmdb": "Učitavanje sadržaja s TMDB-a nije uspjelo", - "movies": "Filmovi", - "tv_shows": "Serije", - "channels": "Kanali" - }, - "streams": { - "back_to_episodes": "Natrag na epizode", - "back_to_info": "Natrag na informacije", - "fetching_from": "Dohvaćanje iz:", - "no_sources_available": "Nema dostupnih izvora za streaming", - "add_sources_desc": "Molimo dodajte izvore za streaming u postavkama", - "add_sources": "Dodaj izvore", - "finding_streams": "Pronalaženje dostupnih streamova...", - "finding_best_stream": "Pronalaženje najboljeg streama za automatsku reprodukciju...", - "still_fetching": "Dohvaćanje streamova i dalje u tijeku...", - "no_streams_available": "Nema dostupnih streamova", - "starting_best_stream": "Pokretanje najboljeg streama...", - "loading_more_sources": "Učitavanje dodatnih izvora..." - }, - "player_ui": { - "via": "putem {{name}}", - "audio_tracks": "Zvučni zapisi", - "no_audio_tracks": "Nema dostupnih zvučnih zapisa", - "playback_speed": "Brzina reprodukcije", - "on_hold": "Na čekanju", - "playback_error": "Pogreška pri reprodukciji", - "unknown_error": "Došlo je do nepoznate pogreške tijekom reprodukcije.", - "copy_error": "Kopiraj detalje pogreške", - "copied_to_clipboard": "Kopirano u međuspremnik", - "dismiss": "Zatvori", - "continue_watching": "Nastavi gledati", - "start_over": "Kreni ispočetka", - "resume": "Nastavi", - "change_source": "Promijeni izvor", - "switching_source": "Promjena izvora...", - "no_sources_found": "Nema pronađenih izvora", - "sources": "Izvori", - "finding_sources": "Pronalaženje izvora...", - "unknown_source": "Nepoznat izvor", - "sources_limited": "Izvori mogu biti ograničeni zbog pogrešaka pružatelja usluga.", - "episodes": "Epizode", - "specials": "Specijali", - "season": "Sezona {{season}}", - "stream": "Stream {{number}}", - "subtitles": "Titlovi", - "built_in": "Ugrađeno", - "addons": "Dodaci", - "style": "Stil", - "none": "Nijedan", - "search_online_subtitles": "Pretraži titlove na mreži", - "preview": "Pretpregled", - "quick_presets": "Brze postavke", - "default": "Zadano", - "yellow": "Žuta", - "high_contrast": "Visoki kontrast", - "large": "Veliko", - "core": "Osnovno", - "font_size": "Veličina fonta", - "show_background": "Prikaži pozadinu", - "advanced": "Napredno", - "position": "Položaj", - "text_color": "Boja teksta", - "align": "Poravnanje", - "bottom_offset": "Pomak od dna", - "background_opacity": "Prozirnost pozadine", - "text_shadow": "Sjena teksta", - "on": "Uključeno", - "off": "Isključeno", - "outline_color": "Boja obruba", - "outline": "Obrub", - "outline_width": "Širina obruba", - "letter_spacing": "Razmak slova", - "line_height": "Visina retka", - "timing_offset": "Pomak vremena (s)", - "visual_sync": "Vizualna sinkronizacija", - "timing_hint": "Pomaknite titlove ranije (-) ili kasnije (+) za sinkronizaciju ako je potrebno.", - "reset_defaults": "Vrati na zadano" - }, - "downloads": { - "title": "Preuzimanja", - "no_downloads": "Još nema preuzimanja", - "no_downloads_desc": "Preuzeti sadržaj pojavit će se ovdje za gledanje izvan mreže", - "explore": "Istraži sadržaj", - "path_copied": "Putanja kopirana", - "path_copied_desc": "Lokalna putanja datoteke kopirana u međuspremnik", - "copied": "Kopirano", - "incomplete": "Preuzimanje nepotpuno", - "incomplete_desc": "Preuzimanje još nije završeno", - "not_available": "Nije dostupno", - "not_available_desc": "Lokalna putanja datoteke dostupna je tek nakon završetka preuzimanja.", - "status_downloading": "Preuzimanje", - "status_completed": "Dovršeno", - "status_paused": "Pauzirano", - "status_error": "Pogreška", - "status_queued": "U redu čekanja", - "status_unknown": "Nepoznato", - "provider": "Pružatelj usluge", - "streaming_playlist_warning": "Možda se neće reproducirati - streaming playlista", - "remaining": "preostalo", - "not_ready": "Preuzimanje nije spremno", - "not_ready_desc": "Molimo pričekajte dok preuzimanje ne završi.", - "filter_all": "Sve", - "filter_active": "Aktivno", - "filter_done": "Gotovo", - "filter_paused": "Pauzirano", - "no_filter_results": "Nema {{filter}} preuzimanja", - "try_different_filter": "Pokušajte odabrati drugi filter", - "limitations_title": "Ograničenja preuzimanja", - "limitations_msg": "• Datoteke manje od 1MB obično su M3U8 streaming liste i ne mogu se preuzeti za gledanje izvan mreže. One rade samo s online streamingom i sadrže poveznice na segmente videa, a ne stvarni video sadržaj.", - "remove_title": "Ukloni preuzimanje", - "remove_confirm": "Ukloniti \"{{title}}\"{{season_episode}}?", - "cancel": "Odustani", - "remove": "Ukloni" - }, - "addons": { - "title": "Dodaci", - "reorder_mode": "Način preslagivanja", - "reorder_info": "Dodaci na vrhu imaju veći prioritet prilikom učitavanja sadržaja", - "add_addon_placeholder": "URL dodatka", - "add_button": "Dodaj dodatak", - "my_addons": "Moji dodaci", - "community_addons": "Dodaci zajednice", - "no_addons": "Nema instaliranih dodataka", - "uninstall_title": "Deinstaliraj dodatak", - "uninstall_message": "Jeste li sigurni da želite deinstalirati {{name}}?", - "uninstall_button": "Deinstaliraj", - "install_success": "Dodatak je uspješno instaliran", - "install_error": "Instalacija dodatka nije uspjela", - "load_error": "Učitavanje dodataka nije uspjelo", - "fetch_error": "Dohvaćanje detalja dodatka nije uspjelo", - "invalid_url": "Molimo unesite URL dodatka", - "configure": "Konfiguriraj", - "version": "Verzija: {{version}}", - "installed_addons": "INSTALIRANI DODACI", - "reorder_drag_title": "POVUCITE DODATKE ZA PRESLAGIVANJE", - "install": "Instaliraj", - "config_unavailable_title": "Konfiguracija nedostupna", - "config_unavailable_msg": "Nije moguće odrediti URL konfiguracije za ovaj dodatak.", - "cannot_open_config_title": "Nije moguće otvoriti konfiguraciju", - "cannot_open_config_msg": "Konfiguracijski URL ({{url}}) ne može se otvoriti. Dodatak možda nema stranicu za konfiguraciju.", - "description": "Opis", - "supported_types": "Podržane vrste", - "catalogs": "Katalozi", - "no_description": "Opis nije dostupan", - "overview": "PREGLED", - "no_categories": "Nema kategorija", - "pre_installed": "PREDINSTRUALIRANO" - }, - "trakt": { - "title": "Trakt postavke", - "settings_title": "Trakt postavke", - "connect_title": "Poveži se s Traktom", - "connect_desc": "Sinkronizirajte povijest gledanja, popis za gledanje i kolekciju s Trakt.tv", - "sign_in": "Prijavi se na Trakt", - "sign_out": "Odjava", - "sign_out_confirm": "Jeste li sigurni da se želite odjaviti s vašeg Trakt računa?", - "joined": "Pridružen {{date}}", - "sync_settings_title": "Postavke sinkronizacije", - "sync_info": "Kada ste povezani s Traktom, cijela povijest se sinkronizira izravno putem API-ja i ne zapisuje se u lokalnu pohranu. Vaš popis 'Nastavi gledati' odražava vaš ukupni Trakt napredak.", - "auto_sync_label": "Automatska sinkronizacija napretka", - "auto_sync_desc": "Automatski sinkroniziraj napredak gledanja na Trakt", - "import_history_label": "Uvezi povijest gledanja", - "import_history_desc": "Koristite 'Sinkroniziraj sada' za uvoz povijesti gledanja i napretka s Trakta", - "sync_now_button": "Sinkroniziraj sada", - "display_settings_title": "Postavke prikaza", - "show_comments_label": "Prikaži Trakt komentare", - "show_comments_desc": "Prikaži Trakt komentare u detaljima sadržaja kada su dostupni", - "maintenance_title": "Održavanje u tijeku", - "maintenance_unavailable": "Trakt nedostupan", - "maintenance_desc": "Integracija s Traktom privremeno je zaustavljena zbog održavanja. Sinkronizacija i autentifikacija su onemogućeni dok se održavanje ne završi.", - "maintenance_button": "Usluga se održava", - "auth_success_title": "Uspješno povezano", - "auth_success_msg": "Vaš Trakt račun je uspješno povezan.", - "auth_error_title": "Pogreška autentifikacije", - "auth_error_msg": "Autentifikacija s Traktom nije uspjela.", - "auth_error_generic": "Došlo je do pogreške tijekom autentifikacije.", - "sign_out_error": "Odjava s Trakta nije uspjela.", - "sync_complete_title": "Sinkronizacija završena", - "sync_success_msg": "Vaš napredak gledanja uspješno je sinkroniziran s Traktom.", - "sync_error_msg": "Sinkronizacija nije uspjela. Molimo pokušajte ponovno." - }, - "simkl": { - "title": "Simkl postavke", - "settings_title": "Simkl postavke", - "connect_title": "Poveži se sa Simklom", - "connect_desc": "Sinkronizirajte povijest gledanja i pratite što gledate", - "sign_in": "Prijavi se na Simkl", - "sign_out": "Odspoji se", - "sign_out_confirm": "Jeste li sigurni da se želite odspojiti sa Simkla?", - "syncing_desc": "Vaše pogledane stavke sinkroniziraju se sa Simklom.", - "auth_success_title": "Uspješno povezano", - "auth_success_msg": "Vaš Simkl račun je uspješno povezan.", - "auth_error_title": "Pogreška autentifikacije", - "auth_error_msg": "Autentifikacija sa Simklom nije uspjela.", - "auth_error_generic": "Došlo je do pogreške tijekom autentifikacije.", - "sign_out_error": "Odspajanje sa Simkla nije uspjelo.", - "config_error_title": "Pogreška konfiguracije", - "config_error_msg": "Simkl Client ID nedostaje u varijablama okruženja.", - "conflict_title": "Sukob", - "conflict_msg": "Ne možete se povezati sa Simklom dok je Trakt povezan. Molimo prvo odspojite Trakt.", - "disclaimer": "Nuvio nije povezan sa Simklom." - }, - "tmdb_settings": { - "title": "TMDb postavke", - "metadata_enrichment": "Obogaćivanje metapodataka", - "metadata_enrichment_desc": "Poboljšajte metapodatke sadržaja s TMDb podacima za bolje detalje i informacije.", - "enable_enrichment": "Omogući obogaćivanje", - "enable_enrichment_desc": "Proširuje metapodatke dodataka s TMDb-a za glumačku postavu, dobne ocjene, logotipe/postere i informacije o produkciji.", - "localized_text": "Lokalizirani tekst", - "localized_text_desc": "Dohvati naslove i opise na vašem željenom jeziku s TMDb-a.", - "language": "Jezik", - "change": "Promijeni", - "logo_preview": "Pretpregled logotipa", - "logo_preview_desc": "Pretpregled pokazuje kako će se lokalizirani logotipi pojaviti na odabranom jeziku.", - "example": "Primjer:", - "no_logo": "Logotip nije dostupan", - "enrichment_options": "Opcije obogaćivanja", - "enrichment_options_desc": "Kontrolirajte koji se podaci dohvaćaju s TMDb-a. Onemogućene opcije koristit će podatke iz dodatka ako su dostupni.", - "cast_crew": "Glumci i ekipa", - "cast_crew_desc": "Glumci, redatelji, scenaristi s profilnim fotografijama", - "title_description": "Naslov i opis", - "title_description_desc": "Koristi TMDb lokalizirani naslov i opis", - "title_logos": "Logotipi naslova", - "title_logos_desc": "Visokokvalitetne slike naslova", - "banners_backdrops": "Banneri i pozadine", - "banners_backdrops_desc": "Slike pozadina visoke rezolucije", - "certification": "Dobna ocjena sadržaja", - "certification_desc": "Dobne preporuke (PG-13, R, TV-MA, itd.)", - "recommendations": "Preporuke", - "recommendations_desc": "Prijedlozi sličnog sadržaja", - "episode_data": "Podaci o epizodama", - "episode_data_desc": "Sličice epizoda, informacije i zamjenski podaci za serije", - "season_posters": "Posteri sezona", - "season_posters_desc": "Slike postera specifične za sezonu", - "production_info": "Informacije o produkciji", - "production_info_desc": "Mreže i produkcijske kuće s logotipima", - "movie_details": "Detalji o filmu", - "movie_details_desc": "Budžet, prihod, trajanje, slogan", - "tv_details": "Detalji o seriji", - "tv_details_desc": "Status, broj sezona, mreže, autori", - "movie_collections": "Kolekcije filmova", - "movie_collections_desc": "Filmske franšize (Marvel, Star Wars, itd.)", - "api_configuration": "API konfiguracija", - "api_configuration_desc": "Konfigurirajte svoj TMDb API pristup za poboljšanu funkcionalnost.", - "custom_api_key": "Prilagođeni API ključ", - "custom_api_key_desc": "Koristite vlastiti TMDb API ključ za bolje performanse i namjenska ograničenja.", - "custom_key_active": "Prilagođeni API ključ je aktivan", - "api_key_required": "Potreban je API ključ", - "api_key_placeholder": "Zalijepite svoj TMDb API ključ (v3)", - "how_to_get_key": "Kako dobiti TMDb API ključ?", - "built_in_key_msg": "Trenutno se koristi ugrađeni API ključ. Razmislite o korištenju vlastitog ključa za bolje performanse.", - "cache_size": "Veličina predmemorije", - "clear_cache": "Očisti predmemoriju", - "cache_days": "TMDb odgovori se spremaju 7 dana radi boljih performansi", - "choose_language": "Odaberi jezik", - "choose_language_desc": "Odaberite željeni jezik za TMDb sadržaj", - "popular": "Popularno", - "all_languages": "Svi jezici", - "search_results": "Rezultati pretraživanja", - "no_languages_found": "Nema pronađenih jezika za \"{{query}}\"", - "clear_search": "Očisti pretragu", - "clear_cache_title": "Očisti TMDb predmemoriju", - "clear_cache_msg": "Ovo će obrisati sve spremljene TMDb podatke ({{size}}). To može privremeno usporiti učitavanje dok se predmemorija ponovno ne izgradi.", - "clear_cache_success": "TMDb predmemorija je uspješno očišćena.", - "clear_cache_error": "Čišćenje predmemorije nije uspjelo.", - "clear_api_key_title": "Ukloni API ključ", - "clear_api_key_msg": "Jeste li sigurni da želite ukloniti svoj prilagođeni API ključ i vratiti se na zadani?", - "clear_api_key_success": "API ključ je uspješno uklonjen", - "clear_api_key_error": "Uklanjanje API ključa nije uspjelo", - "empty_api_key": "API ključ ne može biti prazan.", - "invalid_api_key": "Nevažeći API ključ. Provjerite i pokušajte ponovno.", - "save_error": "Došlo je do pogreške pri spremanju. Pokušajte ponovno.", - "using_builtin_key": "Sada koristite ugrađeni TMDb API ključ.", - "using_custom_key": "Sada koristite svoj prilagođeni TMDb API ključ.", - "enter_custom_key": "Molimo unesite i spremite svoj prilagođeni TMDb API ključ.", - "key_verified": "API ključ je verificiran i uspješno spremljen." - }, - "settings": { - "language": "Jezik", - "select_language": "Odaberi jezik", - "english": "Engleski", - "portuguese": "Portugalski", - "portuguese_br": "Portugalski (Brazil)", - "portuguese_pt": "Portugalski (Portugal)", - "german": "Njemački", - "arabic": "Arapski", - "spanish": "Španjolski", - "french": "Francuski", - "italian": "Talijanski", - "croatian": "Hrvatski", - "chinese": "Kineski (pojednostavljeni)", - "hindi": "Hindski", - "serbian": "Srpski", - "account": "Račun", - "content_discovery": "Sadržaj i otkrivanje", - "appearance": "Izgled", - "integrations": "Integracije", - "playback": "Reprodukcija", - "backup_restore": "Sigurnosna kopija i vraćanje", - "updates": "Ažuriranja", - "about": "O aplikaciji", - "developer": "Razvojni programer", - "cache": "Predmemorija", - "title": "Postavke", - "settings_title": "Postavke", - "sign_in_sync": "Prijavite se za sinkronizaciju", - "add_catalogs_sources": "Dodaci, katalozi i izvori", - "player_trailers_downloads": "Player, traileri, preuzimanja", - "mdblist_tmdb_ai": "MDBList, TMDB, AI", - "check_updates": "Provjeri ažuriranja", - "clear_mdblist_cache": "Očisti MDBList predmemoriju", - "cache_management": "UPRAVLJANJE PREDMEMORIJOM", - "downloads_counter": "preuzimanja i raste", - "made_with_love": "Napravljeno s ❤️ - Tapframe i prijatelji", - "sections": { - "information": "INFORMACIJE", - "account": "RAČUN", - "theme": "TEMA", - "layout": "RASPORED", - "sources": "IZVORI", - "catalogs": "KATALOZI", - "discovery": "OTKRIVANJE", - "metadata": "METAPODACI", - "ai_assistant": "AI ASISTENT", - "video_player": "VIDEO PLAYER", - "audio_subtitles": "AUDIO I TITLOVI", - "media": "MEDIJI", - "notifications": "OBAVIJESTI", - "testing": "TESTIRANJE", - "danger_zone": "ZONA OPASNOSTI" - }, - "items": { - "legal": "Pravne napomene i odricanje odgovornosti", - "privacy_policy": "Pravila privatnosti", - "report_issue": "Prijavi problem", - "version": "Verzija", - "contributors": "Suradnici", - "view_contributors": "Prikaži sve suradnike", - "theme": "Tema", - "episode_layout": "Raspored epizoda", - "streams_backdrop": "Pozadina streamova", - "streams_backdrop_desc": "Prikaži zamućenu pozadinu na streamovima na mobitelu", - "addons": "Dodaci", - "installed": "instalirano", - "debrid_integration": "Debrid integracija", - "debrid_desc": "Poveži Torbox", - "plugins": "Priključci", - "plugins_desc": "Upravljaj priključcima i repozitorijima", - "catalogs": "Katalozi", - "active": "aktivno", - "home_screen": "Početni zaslon", - "home_screen_desc": "Raspored i sadržaj", - "continue_watching": "Nastavi gledati", - "continue_watching_desc": "Predmemorija i ponašanje reprodukcije", - "show_discover": "Prikaži odjeljak 'Otkrij'", - "show_discover_desc": "Prikaži sadržaj za otkrivanje u pretrazi", - "mdblist": "MDBList", - "mdblist_connected": "Povezano", - "mdblist_desc": "Omogući za prikaz ocjena i recenzija", - "simkl": "Simkl", - "simkl_connected": "Povezano", - "simkl_desc": "Prati što gledaš", - "tmdb": "TMDB", - "tmdb_desc": "Pružatelj metapodataka i logotipa", - "openrouter": "OpenRouter API", - "openrouter_connected": "Povezano", - "openrouter_desc": "Dodaj API ključ za AI chat", - "video_player": "Video player", - "built_in": "Ugrađeni", - "external": "Vanjski", - "preferred_audio": "Željeni jezik zvuka", - "preferred_subtitle": "Željeni jezik titlova", - "subtitle_source": "Prioritet izvora titlova", - "auto_select_subs": "Automatski odabir titlova", - "auto_select_subs_desc": "Automatski odaberi titlove koji odgovaraju vašim postavkama", - "show_trailers": "Prikaži najave", - "show_trailers_desc": "Prikaži najave u glavnom odjeljku", - "enable_downloads": "Omogući preuzimanja", - "enable_downloads_desc": "Prikaži karticu Preuzimanja i omogući spremanje streamova", - "notifications": "Obavijesti", - "notifications_desc": "Podsjetnici za epizode", - "developer_tools": "Razvojni alati", - "developer_tools_desc": "Opcije za testiranje i uklanjanje pogrešaka", - "test_onboarding": "Testiraj uvodni ekran", - "reset_onboarding": "Resetiraj uvodni ekran", - "test_announcement": "Testiraj objavu", - "test_announcement_desc": "Prikaži prozor s novostima", - "reset_campaigns": "Resetiraj kampanje", - "reset_campaigns_desc": "Očisti zapise o prikazanim kampanjama", - "clear_all_data": "Očisti sve podatke", - "clear_all_data_desc": "Resetiraj sve postavke i predmemorirane podatke" - }, - "options": { - "horizontal": "Vodoravno", - "vertical": "Okomito", - "internal_first": "Prvo unutarnji", - "internal_first_desc": "Prednost imaju ugrađeni titlovi, zatim vanjski", - "external_first": "Prvo vanjski", - "external_first_desc": "Prednost imaju titlovi iz dodataka, zatim ugrađeni", - "any_available": "Bilo koji dostupni", - "any_available_desc": "Koristi prvi dostupni zapis titlova" - }, - "clear_data_desc": "Ovo će resetirati sve postavke i obrisati sve privremene podatke. Jeste li sigurni?", - "app_updates": "Ažuriranja aplikacije", - "about_nuvio": "O Nuviju" - }, - "privacy": { - "title": "Privatnost i Podaci", - "settings_desc": "Kontrolirajte telemetriju i prikupljanje podataka", - "info_title": "Vaša Privatnost nam je Važna", - "info_description": "Kontrolirajte koje podatke se prikupljaju i dijele. Analitika je podrazumevano onemogućena, a izveštaji o greškama su anonimni po zadanom.", - "analytics_enabled_title": "Analitika Omogućena", - "analytics_enabled_message": "Podaci o korišćenju će se prikupljati kako bi se poboljšala aplikacija. Možete to onemogućiti u bilo kojem trenutku.", - "disable_error_reporting_title": "Onemogućiti Izveštavanje o Greškama?", - "disable_error_reporting_message": "Onemogućavanje izveštavanja o greškama znači da nećemo biti obavesteni o padu ili problemima koje doživljate. Ovo može uticati na našu sposobnost da ispravimo greške.", - "enable_session_replay_title": "Omogućiti Reprodukciju Sesije?", - "enable_session_replay_message": "Reprodukcija sesije snima vaš ekran kada se greške dogode kako bi nam pomogla da razumemo šta se desilo. Ovo može da hvata vidljiv sadržaj na vašoj ekranu.", - "enable_pii_title": "Omogućiti Prikupljanje PII?", - "enable_pii_message": "Ovo omogućava prikupljanje lično identifikabilnih podataka kao što su IP adresa i detalji uređaja. Ovi podaci pomažu u dijagnostici problema, ali povećavaju izloženost privatnosti.", - "disable_all_title": "Onemogućiti Svu Telemetriju?", - "disable_all_message": "Ovo će onemogućiti svu analitiku, izveštavanje o greškama i reprodukciju sesije. Nećemo primati nikakve podatke o korišćenju aplikacije ili padevima.", - "disable_all_button": "Onemogući Sve", - "all_disabled_title": "Sva Telemetrija Onemogućena", - "all_disabled_message": "Svo prikupljanje podataka je onemogućeno. Promene će stupiti na snagu pri sledećem pokretanju aplikacije.", - "reset_title": "Resetuj na Preporučene", - "reset_message": "Postavke privatnosti su resetovane na preporučene zadane vrednosti (izveštavanje o greškama omogućeno, analitika onemogućena).", - "section_analytics": "ANALITIKA", - "analytics_title": "Analitika Korišćenja", - "analytics_description": "Prikupljaj anonimne obrasce korišćenja i prikaze ekrana", - "section_error_reporting": "IZVEŠTAVANJE O GREŠKAMA", - "error_reporting_title": "Izveštaji o Greškama", - "error_reporting_description": "Pošalji anonimne izveštaje o greškama kako bi se poboljšala stabilnost", - "session_replay_title": "Reprodukcija Sesije", - "session_replay_description": "Snimaj ekran kada se greške dogode", - "pii_title": "Uključi Informacije o Uređaju", - "pii_description": "Pošalji IP adresu i detalje uređaja sa izveštajima", - "section_quick_actions": "BRZE AKCIJE", - "disable_all": "Onemogući Svu Telemetriju", - "disable_all_desc": "Isključi svo prikupljanje podataka", - "reset_recommended": "Resetuj na Preporučene", - "reset_recommended_desc": "Zadane vrednosti usmeren na privatnost sa izveštavanjem o greškama", - "section_learn_more": "SAZNAJ VIŠE", - "privacy_policy": "Politika Privatnosti", - "current_settings": "Sažetak Trenutnih Postavki", - "summary_analytics": "Analitika", - "summary_errors": "Izveštaji o Greškama", - "summary_replay": "Reprodukcija Sesije", - "summary_pii": "Informacije o Uređaju", - "restart_note_detailed": "* Promene u analitici i izveštavanju o greškama stupaju na snagu odmah. Reprodukcija sesije i PII postavke zahtevaju ponovni pokretanje aplikacije." - }, - "ai_settings": { - "title": "AI asistent", - "info_title": "Chat pokretan umjetnom inteligencijom", - "info_desc": "Postavljajte pitanja o bilo kojem filmu ili epizodi serije koristeći napredni AI. Saznajte više o radnji, likovima, temama i zanimljivostima - sve temeljeno na TMDB podacima.", - "feature_1": "Kontekst i analiza specifična za epizodu", - "feature_2": "Objašnjenja radnje i uvid u likove", - "feature_3": "Zanimljivosti i činjenice iza kulisa", - "feature_4": "Vlastiti besplatni OpenRouter API ključ", - "api_key_section": "OPENROUTER API KLJUČ", - "api_key_label": "API ključ", - "api_key_desc": "Unesite svoj OpenRouter API ključ kako biste omogućili AI chat", - "save_api_key": "Spremi API ključ", - "saving": "Spremanje...", - "update": "Ažuriraj", - "remove": "Ukloni", - "get_free_key": "Nabavi besplatni API ključ od OpenRoutera", - "enable_chat": "Omogući AI Chat", - "enable_chat_desc": "Kada je omogućeno, gumb 'Pitaj AI' pojavit će se na stranicama sadržaja.", - "chat_enabled": "AI Chat omogućen", - "chat_enabled_desc": "Sada možete postavljati pitanja o filmovima i serijama. Potražite gumb \"Pitaj AI\"!", - "how_it_works": "Kako radi", - "how_it_works_desc": "• OpenRouter omogućuje pristup brojnim AI modelima\n• Vaš API ključ ostaje privatan i siguran\n• Besplatni paket uključuje izdašna ograničenja upotrebe\n• Razgovarajte o specifičnim epizodama ili filmovima\n• Dobijte detaljne analize i objašnjenja", - "error_invalid_key": "Molimo unesite važeći API ključ", - "error_key_format": "OpenRouter API ključevi trebaju počinjati s \"sk-or-\"", - "success_saved": "OpenRouter API ključ je uspješno spremljen!", - "error_save": "Spremanje API ključa nije uspjelo", - "confirm_remove_title": "Ukloni API ključ", - "confirm_remove_msg": "Jeste li sigurni da želite ukloniti svoj OpenRouter API ključ? To će onemogućiti AI chat.", - "success_removed": "API ključ uspješno uklonjen", - "error_remove": "Uklanjanje API ključa nije uspjelo" - }, - "catalog_settings": { - "title": "Katalozi", - "layout_phone": "RASPORED ZASLONA KATALOGA (MOBITEL)", - "posters_per_row": "Postera po retku", - "auto": "Automatski", - "show_titles": "Prikaži naslove postera", - "show_titles_desc": "Prikaži tekst naslova ispod svakog postera", - "phone_only_hint": "Vrijedi samo za mobitele. Tableti zadržavaju prilagodljivi raspored.", - "catalogs_group": "Katalozi", - "enabled_count": "Omogućeno {{enabled}} od {{total}}", - "rename_hint": "Dugo pritisnite katalog za preimenovanje", - "rename_modal_title": "Preimenuj katalog", - "rename_placeholder": "Unesite novi naziv kataloga", - "error_save_name": "Spremanje prilagođenog naziva nije uspjelo." - }, - "continue_watching_settings": { - "title": "Nastavi gledati", - "playback_behavior": "PONAŠANJE REPRODUKCIJE", - "use_cached": "Koristi predmemorirane streamove", - "use_cached_desc": "Kada je omogućeno, klikom na stavke 'Nastavi gledati' player se otvara izravno koristeći prethodne streamove. Kada je isključeno, otvara se zaslon sa sadržajem.", - "open_metadata": "Otvori zaslon s detaljima", - "open_metadata_desc": "Kada su predmemorirani streamovi isključeni, otvara se zaslon s detaljima umjesto popisa streamova. Ovo omogućuje ručni odabir streama.", - "card_appearance": "IZGLED KARTICE", - "card_style": "Stil kartice", - "card_style_desc": "Odaberite kako će se stavke 'Nastavi gledati' pojavljivati na početnom zaslonu", - "wide": "Široko", - "poster": "Poster", - "cache_settings": "POSTAVKE PREDMEMORIJE", - "cache_duration": "Trajanje predmemorije streama", - "cache_duration_desc": "Koliko dugo čuvati poveznice streamova prije nego što isteknu", - "important_note": "Važna napomena", - "important_note_text": "Sve poveznice streamova možda neće ostati aktivne cijelo vrijeme. Duže vrijeme predmemorije može rezultirati neispravnim poveznicama. U tom slučaju, aplikacija će ponovno dohvatiti svježe streamove.", - "how_it_works": "Kako radi", - "how_it_works_cached": "• Streamovi se spremaju na odabrano trajanje nakon gledanja\n• Predmemorirani streamovi se provjeravaju prije upotrebe\n• Ako je zapis nevažeći ili istekao, otvara se zaslon sadržaja\n• Opcija 'Koristi predmemorirane streamove' kontrolira izravni ulaz u player\n• 'Otvori zaslon s detaljima' pojavljuje se samo kad su predmemorirani streamovi isključeni", - "how_it_works_uncached": "• Kada su predmemorirani streamovi isključeni, klik otvara zaslone sadržaja\n• Opcija 'Otvori zaslon s detaljima' određuje koji će se zaslon otvoriti\n• Zaslon s metapodacima prikazuje detalje i ručni odabir\n• Zaslon sa streamovima prikazuje dostupne izvore za trenutnu reprodukciju", - "changes_saved": "Promjene spremljene", - "min": "min", - "hour": "sat", - "hours": "sati" - }, - "contributors": { - "title": "Suradnici", - "special_mentions": "Posebna priznanja", - "tab_contributors": "Suradnici", - "tab_special": "Posebna priznanja", - "tab_donors": "Donatori", - "manager_role": "Voditelj zajednice", - "manager_desc": "Upravlja Discord i Reddit zajednicama za Nuvio", - "sponsor_role": "Sponzor poslužitelja", - "sponsor_desc": "Sponzorirao infrastrukturu poslužitelja za Nuvio", - "mod_role": "Discord moderator", - "mod_desc": "Pomaže u moderiranju Nuvio Discord zajednice", - "loading": "Učitavanje...", - "discord_user": "Discord korisnik", - "contributions": "doprinosa", - "gratitude_title": "Zahvalni smo na svakom doprinosu", - "gratitude_desc": "Svaka linija koda, prijava pogreške i prijedlog pomažu da Nuvio postane bolji za sve", - "special_thanks_title": "Posebna hvala", - "special_thanks_desc": "Ovi nevjerojatni ljudi pomažu u održavanju Nuvio zajednice i poslužitelja", - "donors_desc": "Hvala vam što vjerujete u ono što gradimo. Vaša podrška drži Nuvio besplatnim i stalno ga poboljšava.", - "latest_donations": "Najnovije", - "leaderboard": "Poredak", - "loading_donors": "Učitavanje donatora...", - "no_donors": "Još nema donatora", - "error_rate_limit": "Prekoračeno ograničenje GitHub API-ja. Pokušajte kasnije.", - "error_failed": "Učitavanje suradnika nije uspjelo. Provjerite internetsku vezu.", - "retry": "Pokušaj ponovno", - "no_contributors": "Nisu pronađeni suradnici", - "loading_contributors": "Učitavanje suradnika..." - }, - "debrid": { - "title": "Debrid integracija", - "description_torbox": "Otključajte 4K streamove visoke kvalitete i munjevite brzine integracijom Torboxa. Unesite API ključ ispod za trenutnu nadogradnju iskustva gledanja.", - "description_torrentio": "Konfigurirajte Torrentio za torrent streamove filmova i serija. Debrid usluga je potrebna za gledanje sadržaja.", - "tab_torbox": "TorBox", - "tab_torrentio": "Torrentio", - "status_connected": "Povezano", - "status_disconnected": "Odspojeno", - "enable_addon": "Omogući dodatak", - "disconnect_button": "Odspoji i ukloni", - "disconnect_loading": "Odspajanje...", - "account_info": "Informacije o računu", - "plan": "Paket", - "plan_free": "Besplatno", - "plan_essential": "Essential (3 $/mj)", - "plan_pro": "Pro (10 $/mj)", - "plan_standard": "Standard (5 $/mj)", - "plan_unknown": "Nepoznato", - "expires": "Istječe", - "downloaded": "Preuzeto", - "status_active": "Aktivno", - "connected_title": "✓ Povezano s TorBoxom", - "connected_desc": "Vaš TorBox dodatak je aktivan i pruža premium streamove.", - "configure_title": "Konfiguriraj dodatak", - "configure_desc": "Prilagodite svoje iskustvo. Razvrstajte po kvaliteti, filtrirajte veličine datoteka i upravljajte postavkama.", - "open_settings": "Otvori postavke", - "what_is_debrid": "Što je Debrid usluga?", - "enter_api_key": "Unesite API ključ", - "connect_button": "Poveži i instaliraj", - "connecting": "Povezivanje...", - "unlock_speeds_title": "Otključaj premium brzine", - "unlock_speeds_desc": "Pretplatite se na Torbox za pristup predmemoriranim 4K streamovima bez učitavanja.", - "get_subscription": "Pretplati se", - "powered_by": "Pokreće", - "disclaimer_torbox": "Nuvio nije povezan s Torboxom ni na koji način.", - "disclaimer_torrentio": "Nuvio nije povezan s Torrentio dodatakom ni na koji način.", - "installed_badge": "✓ INSTALIRANO", - "promo_title": "⚡ Trebate Debrid uslugu?", - "promo_desc": "Nabavite TorBox za munjeviti 4K streaming bez trzanja. Premium torrenti i trenutna preuzimanja.", - "promo_button": "Nabavi TorBox pretplatu", - "service_label": "Debrid usluga *", - "api_key_label": "API ključ *", - "sorting_label": "Razvrstavanje", - "exclude_qualities": "Isključi kvalitete", - "priority_languages": "Prioritetni jezici", - "max_results": "Maksimalno rezultata", - "additional_options": "Dodatne opcije", - "no_download_links": "Ne prikazuj poveznice za preuzimanje", - "no_debrid_catalog": "Ne prikazuj debrid katalog", - "install_button": "Instaliraj Torrentio", - "installing": "Instalacija...", - "update_button": "Ažuriraj konfiguraciju", - "updating": "Ažuriranje...", - "remove_button": "Ukloni Torrentio", - "error_api_required": "Potreban API ključ", - "error_api_required_desc": "Unesite API ključ debrid usluge za instalaciju Torrentia.", - "success_installed": "Torrentio dodatak je uspješno instaliran!", - "success_removed": "Torrentio dodatak je uspješno uklonjen", - "alert_disconnect_title": "Odspoji Torbox", - "alert_disconnect_msg": "Jeste li sigurni da želite odspojiti Torbox? Ovo će ukloniti dodatak i obrisati API ključ." - }, - "home_screen": { - "title": "Postavke početnog zaslona", - "changes_applied": "Promjene primijenjene", - "display_options": "OPCIJE PRIKAZA", - "show_hero": "Prikaži istaknuti sadržaj", - "show_hero_desc": "Istaknuti sadržaj na vrhu", - "show_this_week": "Prikaži 'Ovaj tjedan'", - "show_this_week_desc": "Nove epizode iz tekućeg tjedna", - "select_catalogs": "Odaberi kataloge", - "all_catalogs": "Svi katalozi", - "selected": "odabrano", - "hero_layout": "Izgled istaknutog sadržaja", - "layout_legacy": "Klasično", - "layout_carousel": "Vrtuljak", - "layout_appletv": "Apple TV", - "layout_desc": "Banner pune širine, kartice koje se listaju ili Apple TV stil", - "featured_source": "Izvor istaknutog sadržaja", - "using_catalogs": "Koriste se katalozi", - "manage_selected_catalogs": "Upravljaj odabranim katalozima", - "dynamic_bg": "Dinamična pozadina", - "dynamic_bg_desc": "Zamućeni banner iza vrtuljka", - "performance_note": "Može utjecati na performanse na slabijim uređajima.", - "posters": "Posteri", - "show_titles": "Prikaži naslove", - "poster_size": "Veličina postera", - "poster_corners": "Kutovi postera", - "size_small": "Mali", - "size_medium": "Srednji", - "size_large": "Veliki", - "corners_square": "Oštri", - "corners_rounded": "Zaobljeni", - "corners_pill": "Ovalni", - "about_these_settings": "O OVIM POSTAVKAMA", - "about_desc": "Ove postavke kontroliraju kako se sadržaj prikazuje na vašem početnom zaslonu. Promjene se primjenjuju odmah bez potrebe za ponovnim pokretanjem aplikacije.", - "hero_catalogs": { - "title": "Katalozi istaknutog sadržaja", - "select_all": "Odaberi sve", - "clear_all": "Očisti sve", - "info": "Odaberite koji će se katalozi prikazivati u odjeljku s istaknutim sadržajem. Ako ništa nije odabrano, koristit će se svi katalozi. Ne zaboravite pritisnuti 'Spremi' kada završite.", - "settings_saved": "Postavke spremljene", - "error_load": "Učitavanje kataloga nije uspjelo", - "movies": "Filmovi", - "tv_shows": "Serije" - } - }, - "calendar": { - "title": "Kalendar", - "loading": "Učitavanje kalendara...", - "no_scheduled_episodes": "Nema zakazanih epizoda", - "check_back_later": "Provjerite ponovno kasnije", - "showing_episodes_for": "Prikaz epizoda za {{date}}", - "show_all_episodes": "Prikaži sve epizode", - "no_episodes_for": "Nema epizoda za {{date}}", - "no_upcoming_found": "Nisu pronađene nadolazeće epizode", - "add_series_desc": "Dodajte serije u svoju knjižnicu kako biste ovdje vidjeli njihove nadolazeće epizode" - }, - "mdblist": { - "title": "Izvori ocjena", - "status_disabled": "MDBList onemogućen", - "status_active": "API ključ aktivan", - "status_required": "Potreban API ključ", - "status_disabled_desc": "MDBList funkcionalnost je trenutno isključena.", - "status_active_desc": "Ocjene s MDBList-a su omogućene.", - "status_required_desc": "Dodajte svoj ključ ispod kako biste omogućili ocjene.", - "enable_toggle": "Omogući MDBList", - "enable_toggle_desc": "Uključi/isključi sve MDBList funkcionalnosti", - "api_section": "API ključ", - "placeholder": "Zalijepite svoj MDBList API ključ", - "save": "Spremi", - "clear": "Obriši ključ", - "rating_providers": "Pružatelji ocjena", - "rating_providers_desc": "Odaberite čije će se ocjene prikazivati u aplikaciji", - "how_to": "Kako dobiti API ključ", - "step_1": "Prijavite se na", - "step_1_link": "MDBList web stranici", - "step_2": "Idite na odjeljak", - "step_2_settings": "Postavke", - "step_2_api": "API", - "step_2_end": ".", - "step_3": "Generirajte novi ključ i kopirajte ga.", - "go_to_website": "Posjeti MDBList", - "alert_clear_title": "Brisanje API ključa", - "alert_clear_msg": "Jeste li sigurni da želite ukloniti spremljeni API ključ?", - "success_saved": "API ključ uspješno spremljen.", - "error_empty": "API ključ ne može biti prazan.", - "error_save": "Došlo je do pogreške pri spremanju. Pokušajte ponovno.", - "api_key_empty_error": "API ključ ne može biti prazan.", - "success_cleared": "API ključ uspješno obrisan", - "error_clear": "Brisanje API ključa nije uspjelo" - }, - "notification": { - "title": "Postavke obavijesti", - "section_general": "Općenito", - "enable_notifications": "Omogući obavijesti", - "section_types": "Vrste obavijesti", - "new_episodes": "Nove epizode", - "upcoming_shows": "Nadolazeće serije", - "reminders": "Podsjetnici", - "section_timing": "Vrijeme obavijesti", - "timing_desc": "Kada želite primiti obavijest prije emitiranja epizode?", - "hours_1": "1 sat", - "hours_suffix": "sati", - "section_status": "Status obavijesti", - "stats_upcoming": "Nadolazeće", - "stats_this_week": "Ovaj tjedan", - "stats_total": "Ukupno", - "sync_button": "Sinkroniziraj knjižnicu i Trakt", - "syncing": "Sinkronizacija...", - "sync_desc": "Automatski sinkronizira obavijesti za sve serije u vašoj knjižnici i Trakt listama.", - "section_advanced": "Napredno", - "reset_button": "Resetiraj sve obavijesti", - "test_button": "Testiraj obavijest (5 sek)", - "test_notification_in": "Obavijest za {{seconds}}s...", - "test_notification_text": "Obavijest će se pojaviti za {{seconds}} sekundi", - "alert_reset_title": "Resetiraj obavijesti", - "alert_reset_msg": "Ovo će otkazati sve zakazane obavijesti, ali neće ukloniti ništa iz vaše knjižnice. Jeste li sigurni?", - "alert_reset_success": "Sve obavijesti su resetirane", - "alert_sync_complete": "Sinkronizacija dovršena", - "alert_sync_msg": "Uspješno sinkronizirane obavijesti za vašu knjižnicu i Trakt stavke.\n\nZakazano: {{upcoming}} nadolazećih epizoda\nOvaj tjedan: {{thisWeek}} epizoda", - "alert_test_scheduled": "Testna obavijest zakazana za trenutno prikazivanje" - }, - "backup": { - "title": "Sigurnosna kopija i oporavak", - "options_title": "Opcije sigurnosne kopije", - "options_desc": "Odaberite što želite uključiti u sigurnosnu kopiju", - "section_core": "Osnovni podaci", - "section_addons": "Dodaci i integracije", - "section_settings": "Postavke i preferencije", - "library_label": "Knjižnica", - "library_desc": "Vaši spremljeni filmovi i serije", - "watch_progress_label": "Napredak gledanja", - "watch_progress_desc": "Pozicije 'Nastavi gledati'", - "addons_label": "Dodaci", - "addons_desc": "Instalirani Stremio dodaci", - "plugins_label": "Priključci", - "plugins_desc": "Prilagođene konfiguracije strugača", - "trakt_label": "Trakt integracija", - "trakt_desc": "Sinkronizacija podataka i tokeni za prijavu", - "app_settings_label": "Postavke aplikacije", - "app_settings_desc": "Tema, preferencije i konfiguracije", - "user_prefs_label": "Korisničke preferencije", - "user_prefs_desc": "Redoslijed dodataka i postavke sučelja", - "catalog_settings_label": "Postavke kataloga", - "catalog_settings_desc": "Filteri kataloga i preferencije", - "api_keys_label": "API ključevi", - "api_keys_desc": "MDBList i OpenRouter ključevi", - "action_create": "Stvori sigurnosnu kopiju", - "action_restore": "Vrati iz sigurnosne kopije", - "section_info": "O sigurnosnim kopijama", - "info_text": "• Prilagodite što se sprema pomoću prekidača iznad\n• Datoteke se pohranjuju lokalno na vašem uređaju\n• Podijelite sigurnosnu kopiju za prijenos podataka na drugi uređaj\n• Oporavak će prepisati vaše trenutne podatke", - "alert_create_title": "Stvori sigurnosnu kopiju", - "alert_no_content": "Nije odabran sadržaj za kopiju.\n\nMolimo omogućite barem jednu opciju iznad.", - "alert_backup_created_title": "Kopija stvorena", - "alert_backup_created_msg": "Vaša sigurnosna kopija je spremna i možete je podijeliti.", - "alert_backup_failed_title": "Stvaranje kopije nije uspjelo", - "alert_restore_confirm_title": "Potvrdi oporavak", - "alert_restore_confirm_msg": "Ovo će vratiti vaše podatke iz kopije stvorene {{date}}.\n\nOva radnja će prepisati trenutne podatke. Želite li nastaviti?", - "alert_restore_complete_title": "Oporavak dovršen", - "alert_restore_complete_msg": "Vaši podaci su uspješno vraćeni. Ponovno pokrenite aplikaciju za primjenu promjena.", - "alert_restore_failed_title": "Oporavak nije uspio", - "restart_app": "Ponovno pokreni aplikaciju", - "alert_restart_failed_title": "Ponovno pokretanje nije uspjelo", - "alert_restart_failed_msg": "Neuspjelo ponovno pokretanje. Ručno zatvorite i otvorite aplikaciju." - }, - "updates": { - "title": "Ažuriranja aplikacije", - "status_checking": "Provjera ažuriranja...", - "status_available": "Ažuriranje dostupno!", - "status_downloading": "Preuzimanje ažuriranja...", - "status_installing": "Instalacija ažuriranja...", - "status_success": "Ažuriranje uspješno instalirano!", - "status_error": "Ažuriranje nije uspjelo", - "status_ready": "Spremno za provjeru", - "action_check": "Provjeri ažuriranja", - "action_install": "Instaliraj ažuriranje", - "release_notes": "Napomene o izdanju:", - "version": "Verzija:", - "last_checked": "Zadnja provjera:", - "current_version": "Trenutna verzija:", - "current_release_notes": "Trenutne napomene o izdanju:", - "github_release": "GITHUB IZDANJE", - "current": "Trenutna:", - "latest": "Najnovija:", - "notes": "Bilješke:", - "view_release": "Pogledaj izdanje", - "notification_settings": "POSTAVKE OBAVIJESTI", - "ota_alerts_label": "OTA upozorenja o ažuriranju", - "ota_alerts_desc": "Prikaži obavijesti za bežična (OTA) ažuriranja", - "major_alerts_label": "Glavna upozorenja o ažuriranju", - "major_alerts_desc": "Prikaži obavijesti za nove verzije na GitHubu", - "alert_disable_ota_title": "Onemogućiti OTA upozorenja?", - "alert_disable_ota_msg": "Više nećete primati obavijesti o OTA ažuriranjima.\n\n⚠️ Upozorenje: Najnovija verzija je važna za:\n• Ispravke bugova i stabilnost\n• Nove značajke\n• Točne izvještaje o padu aplikacije\n\nI dalje možete ručno provjeriti ažuriranja.", - "alert_disable_major_title": "Onemogućiti glavna upozorenja?", - "alert_disable_major_msg": "Više nećete primati obavijesti o verzijama koje zahtijevaju ponovnu instalaciju.\n\n⚠️ Upozorenje: Glavna ažuriranja sadrže:\n• Kritične sigurnosne zakrpe\n• Velike promjene sustava\n• Važne ispravke kompatibilnosti", - "warning_note": "Omogućena upozorenja osiguravaju da dobijete ispravke i nove mogućnosti.", - "disable": "Onemogući", - "alert_no_update_to_install": "Nema dostupnog ažuriranja za instalaciju", - "alert_install_failed": "Instalacija ažuriranja nije uspjela", - "alert_no_update_title": "Nema ažuriranja", - "alert_update_applied_msg": "Ažuriranje će se primijeniti kod sljedećeg pokretanja" - }, - "player": { - "title": "Video player", - "section_selection": "ODABIR PLAYERA", - "internal_title": "Ugrađeni player", - "internal_desc": "Koristi zadani player aplikacije", - "vlc_title": "VLC", - "vlc_desc": "Otvori streamove u VLC-u", - "infuse_title": "Infuse", - "infuse_desc": "Otvori streamove u Infuse-u", - "outplayer_title": "OutPlayer", - "outplayer_desc": "Otvori streamove u OutPlayeru", - "vidhub_title": "VidHub", - "vidhub_desc": "Otvori streamove u VidHubu", - "infuse_live_title": "Infuse LiveContainer", - "infuse_live_desc": "Otvori streamove u Infuse-u putem LiveContainera", - "external_title": "Vanjski player", - "external_desc": "Otvori streamove u svom željenom playeru", - "section_playback": "OPCIJE REPRODUKCIJE", - "skip_intro_settings_title": "Preskoči uvod", - "powered_by_introdb": "Pokreće IntroDB", - "autoplay_title": "Automatska reprodukcija prvog streama", - "autoplay_desc": "Automatski pokreni prvi stream s popisa.", - "resume_title": "Uvijek nastavi", - "resume_desc": "Preskoči upit i nastavi tamo gdje ste stali (ako je odgledano manje od 85%).", - "engine_title": "Engine video playera", - "engine_desc": "Auto koristi ExoPlayer uz MPV kao rezervu. Neki formati poput Dolby Vision možda nisu podržani na MPV-u.", - "decoder_title": "Način dekodiranja", - "decoder_desc": "Kako se video dekodira. 'Auto' se preporučuje.", - "gpu_title": "GPU renderiranje", - "gpu_desc": "GPU-Next nudi bolje HDR upravljanje bojama.", - "external_downloads_title": "Vanjski player za preuzimanja", - "external_downloads_desc": "Reproduciraj preuzeti sadržaj u vanjskom playeru.", - "restart_required": "Potrebno ponovno pokretanje", - "restart_msg_decoder": "Ponovno pokrenite aplikaciju za primjenu promjena dekodera.", - "restart_msg_gpu": "Ponovno pokrenite aplikaciju za primjenu GPU načina.", - "option_auto": "Auto", - "option_auto_desc_engine": "ExoPlayer + MPV rezerva", - "option_mpv": "MPV", - "option_mpv_desc": "Samo MPV", - "option_auto_desc_decoder": "Najbolji balans", - "option_sw": "SW", - "option_sw_desc": "Softversko", - "option_hw": "HW", - "option_hw_desc": "Hardversko", - "option_hw_plus": "HW+", - "option_hw_plus_desc": "Puni HW", - "option_gpu_desc": "Standardno", - "option_gpu_next_desc": "Napredno" - }, - "plugins": { - "title": "Priključci", - "enable_title": "Omogući priključke", - "enable_desc": "Omogući sustav priključaka za pronalaženje vanjskih izvora medija", - "repo_config_title": "Konfiguracija repozitorija", - "repo_config_desc": "Upravljajte vanjskim repozitorijima priključaka.", - "your_repos": "Repozitoriji", - "your_repos_desc": "Konfigurirajte vanjske izvore za priključke.", - "add_repo_button": "Dodaj repozitorij", - "refresh": "Osvježi", - "remove": "Ukloni", - "enabled": "Omogućeno", - "disabled": "Onemogućeno", - "updating": "Ažuriranje...", - "success": "Uspjeh", - "error": "Pogreška", - "alert_repo_added": "Repozitorij dodan i priključci uspješno učitani", - "alert_repo_saved": "URL repozitorija uspješno spremljen", - "alert_repo_refreshed": "Repozitorij uspješno osvježen", - "alert_invalid_url": "Nevažeći URL format", - "alert_plugins_cleared": "Svi priključci su uklonjeni", - "alert_cache_cleared": "Predmemorija repozitorija uspješno očišćena", - "unknown": "Nepoznato", - "active": "Aktivno", - "available": "Dostupno", - "platform_disabled": "Platforma onemogućena", - "limited": "Ograničeno", - "clear_all": "Ukloni sve priključke", - "clear_all_desc": "Jeste li sigurni da želite ukloniti sve instalirane priključke? To se ne može poništiti.", - "clear_cache": "Očisti predmemoriju repozitorija", - "clear_cache_desc": "Ovo će ukloniti URL i podatke repozitorija. Morat ćete ga ponovno unijeti.", - "add_new_repo": "Dodaj novi repozitorij", - "available_plugins": "Dostupni priključci ({{count}})", - "placeholder": "Pretraži priključke...", - "all": "Svi", - "filter_all": "Sve vrste", - "filter_movies": "Filmovi", - "filter_tv": "Serije", - "enable_all": "Omogući sve", - "disable_all": "Onemogući sve", - "no_plugins_found": "Priključci nisu pronađeni", - "no_plugins_available": "Nema dostupnih priključaka", - "no_match_desc": "Nema rezultata za \"{{query}}\". Pokušajte s drugim pojmom.", - "configure_repo_desc": "Konfigurirajte repozitorij iznad za prikaz priključaka.", - "clear_search": "Očisti pretragu", - "no_external_player": "Nema vanjskog playera", - "showbox_token": "ShowBox UI Token", - "showbox_placeholder": "Zalijepite svoj ShowBox UI token", - "save": "Spremi", - "clear": "Očisti", - "additional_settings": "Dodatne postavke", - "enable_url_validation": "Omogući provjeru URL-a", - "url_validation_desc": "Provjeri ispravnost poveznica (može usporiti rezultate, ali povećava pouzdanost)", - "group_streams": "Grupiraj izvore priključaka", - "group_streams_desc": "Izvori će biti grupirani prema repozitoriju.", - "sort_quality": "Poredaj prvo po kvaliteti", - "sort_quality_desc": "Izvori se prvo razvrstavaju po kvaliteti (samo uz grupiranje).", - "show_logos": "Prikaži logotipe priključaka", - "show_logos_desc": "Prikaži logotipe pored izvora na zaslonu odabira.", - "quality_filtering": "Filtriranje kvalitete", - "quality_filtering_desc": "Isključi određene rezolucije iz rezultata.", - "excluded_qualities": "Isključene kvalitete:", - "language_filtering": "Filtriranje jezika", - "language_filtering_desc": "Isključi određene jezike iz rezultata.", - "note": "Napomena:", - "language_filtering_note": "Ovo se primjenjuje samo na pružatelje koji šalju informaciju o jeziku.", - "excluded_languages": "Isključeni jezici:", - "about_title": "O priključcima", - "about_desc_1": "Priključci su modularne komponente koje prilagođavaju sadržaj s vanjskih protokola. Rade lokalno na vašem uređaju.", - "about_desc_2": "Priključci označeni kao \"Ograničeno\" mogu zahtijevati dodatne konfiguracije.", - "help_title": "Postavljanje priključaka", - "help_step_1": "1. **Omogući priključke** - Uključite glavni prekidač", - "help_step_2": "2. **Dodaj repozitorij** - Unesite ispravan URL", - "help_step_3": "3. **Osvježi** - Povucite popis dostupnih priključaka", - "help_step_4": "4. **Aktiviraj** - Omogućite željene priključke", - "got_it": "Razumijem!", - "repo_format_hint": "Format: https://raw.githubusercontent.com/korisnik/repo/refs/heads/branch", - "cancel": "Odustani", - "add": "Dodaj" - }, - "theme": { - "title": "Teme aplikacije", - "select_theme": "ODABERI TEMU", - "create_custom": "Stvori vlastitu temu", - "options": "OPCIJE", - "use_dominant_color": "Koristi dominantnu boju s postera", - "categories": { - "all": "Sve teme", - "dark": "Tamne teme", - "colorful": "Šarene", - "custom": "Moje teme" - }, - "editor": { - "theme_name_placeholder": "Naziv teme", - "save": "Spremi", - "primary": "Primarna", - "secondary": "Sekundarna", - "background": "Pozadina", - "invalid_name_title": "Nevažeći naziv", - "invalid_name_msg": "Molimo unesite ispravan naziv teme" - }, - "alerts": { - "delete_title": "Obriši temu", - "delete_msg": "Jeste li sigurni da želite obrisati temu \"{{name}}\"?", - "ok": "U redu", - "delete": "Obriši", - "cancel": "Odustani", - "back": "Postavke" - } - }, - "legal": { - "title": "Pravne napomene i odricanje odgovornosti", - "intro_title": "Priroda aplikacije", - "intro_text": "Nuvio je media player i aplikacija za upravljanje metapodacima. Djeluje isključivo kao klijentsko sučelje za pregledavanje javno dostupnih informacija (filmovi, serije) i reprodukciju datoteka koje osigura korisnik ili dodaci trećih strana. Nuvio ne ugošćuje, ne distribuira niti indeksira nikakav medijski sadržaj.", - "extensions_title": "Priključci trećih strana", - "extensions_text": "Nuvio omogućuje instalaciju priključaka koje razvijaju neovisni programeri. Nemamo kontrolu niti odgovornost za sadržaj, zakonitost ili funkcionalnost tih priključaka.", - "user_resp_title": "Odgovornost korisnika", - "user_resp_text": "Korisnici su isključivo odgovorni za priključke koje instaliraju. Korištenjem aplikacije pristajete osigurati da imate zakonsko pravo na pristup sadržaju koji gledate. Autori Nuvia ne potiču kršenje autorskih prava.", - "dmca_title": "Autorska prava i DMCA", - "dmca_text": "Nuvio ne ugošćuje sadržaj pa ga ne može ukloniti s interneta. Ako smatrate da samo sučelje krši vaša prava, kontaktirajte nas.", - "warranty_title": "Bez jamstva", - "warranty_text": "Softver se isporučuje \"kakav jest\", bez ikakvih jamstava. Autori nisu odgovorni za bilo kakvu štetu nastalu korištenjem ovog softvera." - }, - "plugin_tester": { - "title": "Plugin Tester", - "subtitle": "Pokrenite strugače i pratite zapise u stvarnom vremenu", - "tabs": { - "individual": "Pojedinačno", - "repo": "Repo Tester", - "code": "Kod", - "logs": "Zapisi", - "results": "Rezultati" - }, - "common": { - "error": "Pogreška", - "success": "Uspjeh", - "movie": "Film", - "tv": "Serija", - "tmdb_id": "TMDB ID", - "season": "Sezona", - "episode": "Epizoda", - "running": "Pokretanje…", - "run_test": "Pokreni test", - "play": "Reproduciraj", - "done": "Gotovo", - "test": "Test", - "testing": "Testiranje…" - }, - "individual": { - "load_from_url": "Učitaj s URL-a", - "load_from_url_desc": "Zalijepite GitHub URL ili lokalni IP i preuzmite.", - "enter_url_error": "Molimo unesite URL", - "code_loaded": "Kod učitan s URL-a", - "fetch_error": "Dohvaćanje nije uspjelo: {{message}}", - "no_code_error": "Nema koda za pokretanje", - "plugin_code": "Kod priključka", - "focus_editor": "Fokusiraj uređivač koda", - "code_placeholder": "// Zalijepite kod priključka ovdje...", - "test_parameters": "Testni parametri", - "no_logs": "Još nema zapisa. Pokrenite test.", - "no_streams": "Nisu pronađeni streamovi.", - "streams_found": "Pronađen {{count}} stream", - "streams_found_plural": "Pronađeno {{count}} streama", - "tap_play_hint": "Dodirnite 'Reproduciraj' za testiranje streama.", - "unnamed_stream": "Neimenovani stream", - "quality": "Kvaliteta: {{quality}}", - "size": "Veličina: {{size}}", - "url_label": "URL: {{url}}", - "headers_info": "Zaglavlja: {{count}} prilagođenih", - "find_placeholder": "Pronađi u kodu…", - "edit_code_title": "Uredi kod", - "no_url_stream_error": "Nije pronađen URL za ovaj stream" - }, - "repo": { - "title": "Repo Tester", - "description": "Dohvatite repozitorij i testirajte svakog pružatelja.", - "enter_repo_url_error": "Unesite URL repozitorija", - "invalid_url_title": "Nevažeći URL", - "invalid_url_msg": "Koristite GitHub raw URL ili lokalni http(s) URL.", - "manifest_build_error": "Neuspjelo stvaranje URL-a manifesta", - "manifest_fetch_error": "Neuspjelo dohvaćanje manifesta", - "repo_manifest_fetch_error": "Neuspjelo dohvaćanje manifesta repozitorija", - "missing_filename": "Nedostaje naziv datoteke u manifestu", - "scraper_build_error": "Neuspjelo stvaranje URL-a strugača", - "download_scraper_error": "Neuspjelo preuzimanje strugača", - "test_failed": "Test nije uspio", - "test_parameters": "Parametri Repo testa", - "test_parameters_desc": "Ovi se parametri koriste samo za Repo Tester.", - "using_info": "Koristi se: {{mediaType}} • TMDB {{tmdbId}}", - "using_info_tv": "Koristi se: {{mediaType}} • TMDB {{tmdbId}} • S{{season}}E{{episode}}", - "providers_title": "Pružatelji", - "repository_default": "Repozitorij", - "providers_count": "{{count}} pružatelja", - "fetch_hint": "Dohvatite repo za popis pružatelja.", - "test_all": "Testiraj sve", - "status_running": "U TIJEKU", - "status_ok": "OK ({{count}})", - "status_ok_empty": "OK (0)", - "status_failed": "NEUSPJEH", - "status_idle": "ČEKANJE", - "tried_url": "Pokušano: {{url}}", - "provider_logs": "Zapisi pružatelja", - "no_logs_captured": "Nema zapisa." - } - } - -} +{ + "common": { + "loading": "Učitavanje...", + "cancel": "Odustani", + "save": "Spremi", + "delete": "Obriši", + "edit": "Uredi", + "search": "Pretraži", + "error": "Pogreška", + "success": "Uspjeh", + "ok": "U redu", + "unknown": "Nepoznato", + "retry": "Pokušaj ponovno", + "try_again": "Pokušajte ponovno", + "go_back": "Idi natrag", + "settings": "Postavke", + "close": "Zatvori", + "enable": "Omogući", + "disable": "Onemogući", + "show_more": "Prikaži više", + "show_less": "Prikaži manje", + "load_more": "Učitaj više", + "unknown_date": "Nepoznat datum", + "anonymous_user": "Anonimni korisnik", + "time": { + "now": "Upravo sada", + "minutes_ago": "prije {{count}} min", + "hours_ago": "prije {{count}} h", + "days_ago": "prije {{count}} d" + }, + "days_short": { + "sun": "Ned", + "mon": "Pon", + "tue": "Uto", + "wed": "Sri", + "thu": "Čet", + "fri": "Pet", + "sat": "Sub" + }, + "email": "E-pošta", + "status": "Status" + }, + "home": { + "categories": { + "movies": "Filmovi", + "series": "Serije", + "channels": "Kanali" + }, + "movies": "Filmovi", + "tv_shows": "Serije", + "load_more_catalogs": "Učitaj više kataloga", + "no_content": "Sadržaj nije dostupan", + "add_catalogs": "Dodaj kataloge", + "sign_in_available": "Prijava je dostupna", + "sign_in_desc": "Možete se prijaviti bilo kada u Postavke → Račun", + "view_all": "Vidi sve", + "this_week": "Ovaj tjedan", + "upcoming": "Dolazeće", + "recently_released": "Nedavno objavljeno", + "no_scheduled_episodes": "Serije bez zakazanih epizoda", + "check_back_later": "Provjerite kasnije", + "continue_watching": "Nastavi gledati", + "up_next": "Sljedeće", + "up_next_caps": "SLJEDEĆE", + "released": "Objavljeno", + "new": "Novo", + "tba": "Bit će objavljeno", + "new_episodes": "{{count}} nove epizode", + "season_short": "S{{season}}", + "episode_short": "E{{episode}}", + "season": "Sezona {{season}}", + "episode": "Epizoda {{episode}}", + "movie": "Film", + "series": "Serija", + "tv_show": "Serija", + "percent_watched": "{{percent}}% pogledano", + "view_details": "Vidi detalje", + "remove": "Ukloni", + "play": "Reproduciraj", + "play_now": "Pokreni odmah", + "resume": "Nastavi", + "info": "Informacije", + "more_info": "Više informacija", + "my_list": "Moj popis", + "save": "Spremi", + "saved": "Spremljeno", + "retry": "Pokušaj ponovno", + "install_addons": "Instaliraj dodatke", + "settings": "Postavke", + "no_featured_content": "Nema istaknutog sadržaja", + "couldnt_load_featured": "Nije moguće učitati istaknuti sadržaj", + "no_featured_desc": "Instalirajte dodatke s katalozima ili promijenite izvor sadržaja u postavkama.", + "load_error_desc": "Došlo je do problema prilikom dohvaćanja istaknutog sadržaja. Provjerite vezu i pokušajte ponovno.", + "no_featured_available": "Nema dostupnog istaknutog sadržaja", + "no_description": "Opis nije dostupan" + }, + "navigation": { + "home": "Početna", + "library": "Knjižnica", + "search": "Pretraživanje", + "downloads": "Preuzimanja", + "settings": "Postavke" + }, + "search": { + "title": "Pretraživanje", + "recent_searches": "Nedavna pretraživanja", + "discover": "Otkrij", + "movies": "Filmovi", + "tv_shows": "Serije", + "select_catalog": "Odaberi katalog", + "all_genres": "Svi žanrovi", + "discovering": "Otkrivanje sadržaja...", + "show_more": "Prikaži više ({{count}})", + "no_content_found": "Sadržaj nije pronađen", + "try_different": "Pokušajte s drugim žanrom ili katalogom", + "select_catalog_desc": "Odaberite katalog za istraživanje", + "tap_catalog_desc": "Dodirnite karticu kataloga iznad za početak", + "placeholder": "Pretraži filmove, serije...", + "keep_typing": "Nastavite tipkati...", + "type_characters": "Upišite barem 2 znaka za pretraživanje", + "no_results": "Nema rezultata", + "try_keywords": "Pokušajte s drugim ključnim riječima ili provjerite pravopis", + "select_type": "Odaberi vrstu", + "browse_movies": "Pregledaj kataloge filmova", + "browse_tv": "Pregledaj kataloge serija", + "select_genre": "Odaberi žanr", + "show_all_content": "Prikaži sav sadržaj", + "genres_count": "{{count}} žanrova" + }, + "library": { + "title": "Knjižnica", + "watched": "Pogledano", + "continue": "Nastavi", + "watchlist": "Popis za gledanje", + "collection": "Kolekcija", + "rated": "Ocijenjeno", + "items": "stavki", + "trakt_collections": "Trakt kolekcije", + "trakt_collection": "Trakt kolekcija", + "no_trakt": "Nema Trakt kolekcija", + "no_trakt_desc": "Vaše Trakt kolekcije pojavit će se ovdje kada počnete koristiti Trakt", + "load_collections": "Učitaj kolekcije", + "empty_folder": "Nema sadržaja u {{folder}}", + "empty_folder_desc": "Ova kolekcija je prazna", + "refresh": "Osvježi", + "no_movies": "Još nema filmova", + "no_series": "Još nema serija", + "no_content": "Još nema sadržaja", + "add_content_desc": "Dodajte sadržaj u svoju knjižnicu kako biste ga vidjeli ovdje", + "find_something": "Pronađi nešto za gledanje", + "removed_from_library": "Uklonjeno iz knjižnice", + "item_removed": "Stavka je uklonjena iz vaše knjižnice", + "failed_update_library": "Ažuriranje knjižnice nije uspjelo", + "unable_remove": "Nije moguće ukloniti stavku iz knjižnice", + "marked_watched": "Označeno kao pogledano", + "marked_unwatched": "Označeno kao nepogledano", + "item_marked_watched": "Stavka je označena kao pogledana", + "item_marked_unwatched": "Stavka je označena kao nepogledana", + "failed_update_watched": "Ažuriranje statusa gledanja nije uspjelo", + "unable_update_watched": "Nije moguće ažurirati status gledanja", + "added_to_library": "Dodano u knjižnicu", + "item_added": "Dodano u vašu lokalnu knjižnicu", + "add_to_library": "Dodaj u knjižnicu", + "remove_from_library": "Ukloni iz knjižnice", + "mark_watched": "Označi kao pogledano", + "mark_unwatched": "Označi kao nepogledano", + "share": "Podijeli", + "add_to_watchlist": "Dodaj na Trakt popis za gledanje", + "remove_from_watchlist": "Ukloni s Trakt popisa za gledanje", + "added_to_watchlist": "Dodano na popis za gledanje", + "added_to_watchlist_desc": "Dodano na vaš Trakt popis za gledanje", + "removed_from_watchlist": "Uklonjeno s popisa za gledanje", + "removed_from_watchlist_desc": "Uklonjeno s vašeg Trakt popisa za gledanje", + "add_to_collection": "Dodaj u Trakt kolekciju", + "remove_from_collection": "Ukloni iz Trakt kolekcije", + "added_to_collection": "Dodano u kolekciju", + "added_to_collection_desc": "Dodano u vašu Trakt kolekciju", + "removed_from_collection": "Uklonjeno iz kolekcije", + "removed_from_collection_desc": "Uklonjeno iz vaše Trakt kolekcije" + }, + "metadata": { + "unable_to_load": "Nije moguće učitati sadržaj", + "error_code": "Šifra pogreške: {{code}}", + "content_not_found": "Sadržaj nije pronađen", + "content_not_found_desc": "Ovaj sadržaj ne postoji ili je možda uklonjen.", + "server_error": "Pogreška poslužitelja", + "server_error_desc": "Poslužitelj je privremeno nedostupan. Pokušajte ponovno kasnije.", + "bad_gateway": "Loš gateway", + "bad_gateway_desc": "Poslužitelj ima poteškoća. Pokušajte ponovno kasnije.", + "service_unavailable": "Usluga nedostupna", + "service_unavailable_desc": "Usluga je trenutno na održavanju. Pokušajte ponovno kasnije.", + "too_many_requests": "Previše zahtjeva", + "too_many_requests_desc": "Šaljete previše zahtjeva. Pričekajte trenutak i pokušajte ponovno.", + "request_timeout": "Istek vremena zahtjeva", + "request_timeout_desc": "Zahtjev je trajao predugo. Pokušajte ponovno.", + "network_error": "Pogreška mreže", + "network_error_desc": "Provjerite internetsku vezu i pokušajte ponovno.", + "auth_error": "Pogreška autentifikacije", + "auth_error_desc": "Provjerite postavke računa i pokušajte ponovno.", + "access_denied": "Pristup odbijen", + "access_denied_desc": "Nemate dopuštenje za pristup ovom sadržaju.", + "connection_error": "Pogreška veze", + "streams_unavailable": "Streaming izvori nedostupni", + "streams_unavailable_desc": "Izvori za streaming trenutno su nedostupni. Pokušajte ponovno kasnije.", + "unknown_error": "Nepoznata pogreška", + "something_went_wrong": "Nešto je pošlo po zlu. Pokušajte ponovno.", + "cast": "Glumačka postava", + "more_like_this": "Slično ovome", + "collection": "Kolekcija", + "episodes": "Epizode", + "seasons": "Sezone", + "posters": "Posteri", + "banners": "Banneri", + "specials": "Specijali", + "season_number": "Sezona {{number}}", + "episode_count": "{{count}} epizoda", + "episode_count_plural": "{{count}} epizoda", + "no_episodes": "Nema dostupnih epizoda", + "no_episodes_for_season": "Nema dostupnih epizoda za Sezonu {{season}}", + "episodes_not_released": "Epizode možda još nisu objavljene", + "no_description": "Opis nije dostupan", + "episode_label": "EPIZODA {{number}}", + "watch_again": "Gledaj ponovno", + "completed": "Završeno", + "play_episode": "Reproduciraj S{{season}}E{{episode}}", + "play": "Reproduciraj", + "watched": "Pogledano", + "watched_on_trakt": "Pogledano na Traktu", + "synced_with_trakt": "Sinkronizirano s Traktom", + "saved": "Spremljeno", + "director": "Redatelj", + "directors": "Redatelji", + "creator": "Autor", + "creators": "Autori", + "production": "Produkcija", + "network": "Mreža", + "mark_watched": "Označi kao pogledano", + "mark_unwatched": "Označi kao nepogledano", + "marking": "Označavanje...", + "removing": "Uklanjanje...", + "unmark_season": "Odznači Sezonu {{season}}", + "mark_season": "Označi Sezonu {{season}}", + "resume": "Nastavi", + "spoiler_warning": "Upozorenje o spoilerima", + "spoiler_warning_desc": "Ovaj komentar sadrži spoilere. Jeste li sigurni da ga želite otkriti?", + "cancel": "Odustani", + "reveal_spoilers": "Otkrij spoilere", + "movie_details": "Detalji o filmu", + "show_details": "Detalji o seriji", + "tagline": "Slogan", + "status": "Status", + "release_date": "Datum izlaska", + "runtime": "Trajanje", + "budget": "Budžet", + "revenue": "Prihod", + "origin_country": "Zemlja podrijetla", + "original_language": "Izvorni jezik", + "first_air_date": "Datum prve emisije", + "last_air_date": "Datum zadnje emisije", + "total_episodes": "Ukupno epizoda", + "episode_runtime": "Trajanje epizode", + "created_by": "Autor", + "backdrop_gallery": "Galerija pozadina", + "loading_episodes": "Učitavanje epizoda...", + "no_episodes_available": "Nema dostupnih epizoda", + "play_next": "Reproduciraj S{{season}}E{{episode}}", + "play_next_episode": "Reproduciraj sljedeću epizodu", + "save": "Spremi", + "percent_watched": "{{percent}}% pogledano", + "percent_watched_trakt": "{{percent}}% pogledano ({{traktPercent}}% na Traktu)", + "synced_with_trakt_progress": "Sinkronizirano s Traktom", + "using_trakt_progress": "Koristi se Trakt napredak", + "added_to_collection_hero": "Dodano u kolekciju", + "added_to_collection_desc_hero": "Dodano u vašu Trakt kolekciju", + "removed_from_collection_hero": "Uklonjeno iz kolekcije", + "removed_from_collection_desc_hero": "Uklonjeno iz vaše Trakt kolekcije", + "mark_as_watched": "Označi kao pogledano", + "mark_as_unwatched": "Označi kao nepogledano" + }, + "cast": { + "biography": "Biografija", + "known_for": "Poznat po", + "personal_info": "Osobni podaci", + "born_in": "Rođen u {{place}}", + "filmography": "Filmografija", + "also_known_as": "Poznat i kao", + "no_info_available": "Dodatne informacije nisu dostupne", + "as_character": "kao {{character}}", + "loading_details": "Učitavanje detalja...", + "years_old": "{{age}} godina", + "view_filmography": "Vidi filmografiju", + "filter": "Filter", + "sort_by": "Sortiraj po", + "sort_popular": "Popularno", + "sort_latest": "Najnovije", + "sort_upcoming": "Dolazeće", + "upcoming_badge": "DOLAZI", + "coming_soon": "Dolazi uskoro", + "filmography_count": "Filmografija • {{count}} naslova", + "loading_filmography": "Učitavanje filmografije...", + "load_more_remaining": "Učitaj više (preostalo {{count}})", + "alert_error_title": "Pogreška", + "alert_error_message": "Nije moguće učitati \"{{title}}\". Pokušajte ponovno kasnije.", + "alert_ok": "U redu", + "no_upcoming": "Nema dolazećih izdanja za ovog glumca", + "no_content": "Sadržaj nije dostupan za ovog glumca", + "no_movies": "Nema dostupnih filmova za ovog glumca", + "no_tv": "Nema dostupnih serija za ovog glumca" + }, + "comments": { + "title": "Trakt komentari", + "spoiler_warning": "⚠️ Ovaj komentar sadrži spoilere. Dodirni za prikaz.", + "spoiler": "Spoiler", + "contains_spoilers": "Sadrži spoilere", + "reveal": "Otkrij", + "vip": "VIP", + "unavailable": "Komentari nedostupni", + "no_comments": "Još nema komentara na Traktu", + "not_in_database": "Ovaj sadržaj možda još nije u Trakt bazi podataka", + "check_trakt": "Provjeri Trakt" + }, + "trailers": { + "title": "Traileri", + "official_trailers": "Službeni traileri", + "official_trailer": "Službeni trailer", + "teasers": "Teaseri", + "teaser": "Teaser", + "clips_scenes": "Isječci i scene", + "clip": "Isječak", + "featurettes": "Featurettes", + "featurette": "Featurette", + "behind_the_scenes": "Iza kulisa", + "no_trailers": "Nema dostupnih trailera", + "unavailable": "Trailer nedostupan", + "unavailable_desc": "Ovaj trailer trenutno se ne može učitati. Pokušajte ponovno kasnije.", + "unable_to_play": "Nije moguće reproducirati trailer. Pokušajte ponovno.", + "watch_on_youtube": "Gledaj na YouTubeu" + }, + "catalog": { + "no_content_found": "Sadržaj nije pronađen", + "no_content_filters": "Nije pronađen sadržaj za odabrane filtere", + "loading_content": "Učitavanje sadržaja...", + "back": "Natrag", + "in_theaters": "U kinima", + "all": "Sve", + "failed_tmdb": "Učitavanje sadržaja s TMDB-a nije uspjelo", + "movies": "Filmovi", + "tv_shows": "Serije", + "channels": "Kanali" + }, + "streams": { + "back_to_episodes": "Natrag na epizode", + "back_to_info": "Natrag na informacije", + "fetching_from": "Dohvaćanje iz:", + "no_sources_available": "Nema dostupnih izvora za streaming", + "add_sources_desc": "Molimo dodajte izvore za streaming u postavkama", + "add_sources": "Dodaj izvore", + "finding_streams": "Pronalaženje dostupnih streamova...", + "finding_best_stream": "Pronalaženje najboljeg streama za automatsku reprodukciju...", + "still_fetching": "Dohvaćanje streamova i dalje u tijeku...", + "no_streams_available": "Nema dostupnih streamova", + "starting_best_stream": "Pokretanje najboljeg streama...", + "loading_more_sources": "Učitavanje dodatnih izvora..." + }, + "player_ui": { + "via": "putem {{name}}", + "audio_tracks": "Zvučni zapisi", + "no_audio_tracks": "Nema dostupnih zvučnih zapisa", + "playback_speed": "Brzina reprodukcije", + "on_hold": "Na čekanju", + "playback_error": "Pogreška pri reprodukciji", + "unknown_error": "Došlo je do nepoznate pogreške tijekom reprodukcije.", + "copy_error": "Kopiraj detalje pogreške", + "copied_to_clipboard": "Kopirano u međuspremnik", + "dismiss": "Zatvori", + "continue_watching": "Nastavi gledati", + "start_over": "Kreni ispočetka", + "resume": "Nastavi", + "change_source": "Promijeni izvor", + "switching_source": "Promjena izvora...", + "no_sources_found": "Nema pronađenih izvora", + "sources": "Izvori", + "finding_sources": "Pronalaženje izvora...", + "unknown_source": "Nepoznat izvor", + "sources_limited": "Izvori mogu biti ograničeni zbog pogrešaka pružatelja usluga.", + "episodes": "Epizode", + "specials": "Specijali", + "season": "Sezona {{season}}", + "stream": "Stream {{number}}", + "subtitles": "Titlovi", + "built_in": "Ugrađeno", + "addons": "Dodaci", + "style": "Stil", + "none": "Nijedan", + "search_online_subtitles": "Pretraži titlove na mreži", + "preview": "Pretpregled", + "quick_presets": "Brze postavke", + "default": "Zadano", + "yellow": "Žuta", + "high_contrast": "Visoki kontrast", + "large": "Veliko", + "core": "Osnovno", + "font_size": "Veličina fonta", + "show_background": "Prikaži pozadinu", + "advanced": "Napredno", + "position": "Položaj", + "text_color": "Boja teksta", + "align": "Poravnanje", + "bottom_offset": "Pomak od dna", + "background_opacity": "Prozirnost pozadine", + "text_shadow": "Sjena teksta", + "on": "Uključeno", + "off": "Isključeno", + "outline_color": "Boja obruba", + "outline": "Obrub", + "outline_width": "Širina obruba", + "letter_spacing": "Razmak slova", + "line_height": "Visina retka", + "timing_offset": "Pomak vremena (s)", + "visual_sync": "Vizualna sinkronizacija", + "timing_hint": "Pomaknite titlove ranije (-) ili kasnije (+) za sinkronizaciju ako je potrebno.", + "reset_defaults": "Vrati na zadano" + }, + "downloads": { + "title": "Preuzimanja", + "no_downloads": "Još nema preuzimanja", + "no_downloads_desc": "Preuzeti sadržaj pojavit će se ovdje za gledanje izvan mreže", + "explore": "Istraži sadržaj", + "path_copied": "Putanja kopirana", + "path_copied_desc": "Lokalna putanja datoteke kopirana u međuspremnik", + "copied": "Kopirano", + "incomplete": "Preuzimanje nepotpuno", + "incomplete_desc": "Preuzimanje još nije završeno", + "not_available": "Nije dostupno", + "not_available_desc": "Lokalna putanja datoteke dostupna je tek nakon završetka preuzimanja.", + "status_downloading": "Preuzimanje", + "status_completed": "Dovršeno", + "status_paused": "Pauzirano", + "status_error": "Pogreška", + "status_queued": "U redu čekanja", + "status_unknown": "Nepoznato", + "provider": "Pružatelj usluge", + "streaming_playlist_warning": "Možda se neće reproducirati - streaming playlista", + "remaining": "preostalo", + "not_ready": "Preuzimanje nije spremno", + "not_ready_desc": "Molimo pričekajte dok preuzimanje ne završi.", + "filter_all": "Sve", + "filter_active": "Aktivno", + "filter_done": "Gotovo", + "filter_paused": "Pauzirano", + "no_filter_results": "Nema {{filter}} preuzimanja", + "try_different_filter": "Pokušajte odabrati drugi filter", + "limitations_title": "Ograničenja preuzimanja", + "limitations_msg": "• Datoteke manje od 1MB obično su M3U8 streaming liste i ne mogu se preuzeti za gledanje izvan mreže. One rade samo s online streamingom i sadrže poveznice na segmente videa, a ne stvarni video sadržaj.", + "remove_title": "Ukloni preuzimanje", + "remove_confirm": "Ukloniti \"{{title}}\"{{season_episode}}?", + "cancel": "Odustani", + "remove": "Ukloni" + }, + "addons": { + "title": "Dodaci", + "reorder_mode": "Način preslagivanja", + "reorder_info": "Dodaci na vrhu imaju veći prioritet prilikom učitavanja sadržaja", + "add_addon_placeholder": "URL dodatka", + "add_button": "Dodaj dodatak", + "my_addons": "Moji dodaci", + "community_addons": "Dodaci zajednice", + "no_addons": "Nema instaliranih dodataka", + "uninstall_title": "Deinstaliraj dodatak", + "uninstall_message": "Jeste li sigurni da želite deinstalirati {{name}}?", + "uninstall_button": "Deinstaliraj", + "install_success": "Dodatak je uspješno instaliran", + "install_error": "Instalacija dodatka nije uspjela", + "load_error": "Učitavanje dodataka nije uspjelo", + "fetch_error": "Dohvaćanje detalja dodatka nije uspjelo", + "invalid_url": "Molimo unesite URL dodatka", + "configure": "Konfiguriraj", + "version": "Verzija: {{version}}", + "installed_addons": "INSTALIRANI DODACI", + "reorder_drag_title": "POVUCITE DODATKE ZA PRESLAGIVANJE", + "install": "Instaliraj", + "config_unavailable_title": "Konfiguracija nedostupna", + "config_unavailable_msg": "Nije moguće odrediti URL konfiguracije za ovaj dodatak.", + "cannot_open_config_title": "Nije moguće otvoriti konfiguraciju", + "cannot_open_config_msg": "Konfiguracijski URL ({{url}}) ne može se otvoriti. Dodatak možda nema stranicu za konfiguraciju.", + "description": "Opis", + "supported_types": "Podržane vrste", + "catalogs": "Katalozi", + "no_description": "Opis nije dostupan", + "overview": "PREGLED", + "no_categories": "Nema kategorija", + "pre_installed": "PREDINSTRUALIRANO" + }, + "trakt": { + "title": "Trakt postavke", + "settings_title": "Trakt postavke", + "connect_title": "Poveži se s Traktom", + "connect_desc": "Sinkronizirajte povijest gledanja, popis za gledanje i kolekciju s Trakt.tv", + "sign_in": "Prijavi se na Trakt", + "sign_out": "Odjava", + "sign_out_confirm": "Jeste li sigurni da se želite odjaviti s vašeg Trakt računa?", + "joined": "Pridružen {{date}}", + "sync_settings_title": "Postavke sinkronizacije", + "sync_info": "Kada ste povezani s Traktom, cijela povijest se sinkronizira izravno putem API-ja i ne zapisuje se u lokalnu pohranu. Vaš popis 'Nastavi gledati' odražava vaš ukupni Trakt napredak.", + "auto_sync_label": "Automatska sinkronizacija napretka", + "auto_sync_desc": "Automatski sinkroniziraj napredak gledanja na Trakt", + "import_history_label": "Uvezi povijest gledanja", + "import_history_desc": "Koristite 'Sinkroniziraj sada' za uvoz povijesti gledanja i napretka s Trakta", + "sync_now_button": "Sinkroniziraj sada", + "display_settings_title": "Postavke prikaza", + "show_comments_label": "Prikaži Trakt komentare", + "show_comments_desc": "Prikaži Trakt komentare u detaljima sadržaja kada su dostupni", + "maintenance_title": "Održavanje u tijeku", + "maintenance_unavailable": "Trakt nedostupan", + "maintenance_desc": "Integracija s Traktom privremeno je zaustavljena zbog održavanja. Sinkronizacija i autentifikacija su onemogućeni dok se održavanje ne završi.", + "maintenance_button": "Usluga se održava", + "auth_success_title": "Uspješno povezano", + "auth_success_msg": "Vaš Trakt račun je uspješno povezan.", + "auth_error_title": "Pogreška autentifikacije", + "auth_error_msg": "Autentifikacija s Traktom nije uspjela.", + "auth_error_generic": "Došlo je do pogreške tijekom autentifikacije.", + "sign_out_error": "Odjava s Trakta nije uspjela.", + "sync_complete_title": "Sinkronizacija završena", + "sync_success_msg": "Vaš napredak gledanja uspješno je sinkroniziran s Traktom.", + "sync_error_msg": "Sinkronizacija nije uspjela. Molimo pokušajte ponovno." + }, + "simkl": { + "title": "Simkl postavke", + "settings_title": "Simkl postavke", + "connect_title": "Poveži se sa Simklom", + "connect_desc": "Sinkronizirajte povijest gledanja i pratite što gledate", + "sign_in": "Prijavi se na Simkl", + "sign_out": "Odspoji se", + "sign_out_confirm": "Jeste li sigurni da se želite odspojiti sa Simkla?", + "syncing_desc": "Vaše pogledane stavke sinkroniziraju se sa Simklom.", + "auth_success_title": "Uspješno povezano", + "auth_success_msg": "Vaš Simkl račun je uspješno povezan.", + "auth_error_title": "Pogreška autentifikacije", + "auth_error_msg": "Autentifikacija sa Simklom nije uspjela.", + "auth_error_generic": "Došlo je do pogreške tijekom autentifikacije.", + "sign_out_error": "Odspajanje sa Simkla nije uspjelo.", + "config_error_title": "Pogreška konfiguracije", + "config_error_msg": "Simkl Client ID nedostaje u varijablama okruženja.", + "conflict_title": "Sukob", + "conflict_msg": "Ne možete se povezati sa Simklom dok je Trakt povezan. Molimo prvo odspojite Trakt.", + "disclaimer": "Nuvio nije povezan sa Simklom." + }, + "tmdb_settings": { + "title": "TMDb postavke", + "metadata_enrichment": "Obogaćivanje metapodataka", + "metadata_enrichment_desc": "Poboljšajte metapodatke sadržaja s TMDb podacima za bolje detalje i informacije.", + "enable_enrichment": "Omogući obogaćivanje", + "enable_enrichment_desc": "Proširuje metapodatke dodataka s TMDb-a za glumačku postavu, dobne ocjene, logotipe/postere i informacije o produkciji.", + "localized_text": "Lokalizirani tekst", + "localized_text_desc": "Dohvati naslove i opise na vašem željenom jeziku s TMDb-a.", + "language": "Jezik", + "change": "Promijeni", + "logo_preview": "Pretpregled logotipa", + "logo_preview_desc": "Pretpregled pokazuje kako će se lokalizirani logotipi pojaviti na odabranom jeziku.", + "example": "Primjer:", + "no_logo": "Logotip nije dostupan", + "enrichment_options": "Opcije obogaćivanja", + "enrichment_options_desc": "Kontrolirajte koji se podaci dohvaćaju s TMDb-a. Onemogućene opcije koristit će podatke iz dodatka ako su dostupni.", + "cast_crew": "Glumci i ekipa", + "cast_crew_desc": "Glumci, redatelji, scenaristi s profilnim fotografijama", + "title_description": "Naslov i opis", + "title_description_desc": "Koristi TMDb lokalizirani naslov i opis", + "title_logos": "Logotipi naslova", + "title_logos_desc": "Visokokvalitetne slike naslova", + "banners_backdrops": "Banneri i pozadine", + "banners_backdrops_desc": "Slike pozadina visoke rezolucije", + "certification": "Dobna ocjena sadržaja", + "certification_desc": "Dobne preporuke (PG-13, R, TV-MA, itd.)", + "recommendations": "Preporuke", + "recommendations_desc": "Prijedlozi sličnog sadržaja", + "episode_data": "Podaci o epizodama", + "episode_data_desc": "Sličice epizoda, informacije i zamjenski podaci za serije", + "season_posters": "Posteri sezona", + "season_posters_desc": "Slike postera specifične za sezonu", + "production_info": "Informacije o produkciji", + "production_info_desc": "Mreže i produkcijske kuće s logotipima", + "movie_details": "Detalji o filmu", + "movie_details_desc": "Budžet, prihod, trajanje, slogan", + "tv_details": "Detalji o seriji", + "tv_details_desc": "Status, broj sezona, mreže, autori", + "movie_collections": "Kolekcije filmova", + "movie_collections_desc": "Filmske franšize (Marvel, Star Wars, itd.)", + "api_configuration": "API konfiguracija", + "api_configuration_desc": "Konfigurirajte svoj TMDb API pristup za poboljšanu funkcionalnost.", + "custom_api_key": "Prilagođeni API ključ", + "custom_api_key_desc": "Koristite vlastiti TMDb API ključ za bolje performanse i namjenska ograničenja.", + "custom_key_active": "Prilagođeni API ključ je aktivan", + "api_key_required": "Potreban je API ključ", + "api_key_placeholder": "Zalijepite svoj TMDb API ključ (v3)", + "how_to_get_key": "Kako dobiti TMDb API ključ?", + "built_in_key_msg": "Trenutno se koristi ugrađeni API ključ. Razmislite o korištenju vlastitog ključa za bolje performanse.", + "cache_size": "Veličina predmemorije", + "clear_cache": "Očisti predmemoriju", + "cache_days": "TMDb odgovori se spremaju 7 dana radi boljih performansi", + "choose_language": "Odaberi jezik", + "choose_language_desc": "Odaberite željeni jezik za TMDb sadržaj", + "popular": "Popularno", + "all_languages": "Svi jezici", + "search_results": "Rezultati pretraživanja", + "no_languages_found": "Nema pronađenih jezika za \"{{query}}\"", + "clear_search": "Očisti pretragu", + "clear_cache_title": "Očisti TMDb predmemoriju", + "clear_cache_msg": "Ovo će obrisati sve spremljene TMDb podatke ({{size}}). To može privremeno usporiti učitavanje dok se predmemorija ponovno ne izgradi.", + "clear_cache_success": "TMDb predmemorija je uspješno očišćena.", + "clear_cache_error": "Čišćenje predmemorije nije uspjelo.", + "clear_api_key_title": "Ukloni API ključ", + "clear_api_key_msg": "Jeste li sigurni da želite ukloniti svoj prilagođeni API ključ i vratiti se na zadani?", + "clear_api_key_success": "API ključ je uspješno uklonjen", + "clear_api_key_error": "Uklanjanje API ključa nije uspjelo", + "empty_api_key": "API ključ ne može biti prazan.", + "invalid_api_key": "Nevažeći API ključ. Provjerite i pokušajte ponovno.", + "save_error": "Došlo je do pogreške pri spremanju. Pokušajte ponovno.", + "using_builtin_key": "Sada koristite ugrađeni TMDb API ključ.", + "using_custom_key": "Sada koristite svoj prilagođeni TMDb API ključ.", + "enter_custom_key": "Molimo unesite i spremite svoj prilagođeni TMDb API ključ.", + "key_verified": "API ključ je verificiran i uspješno spremljen." + }, + "settings": { + "language": "Jezik", + "select_language": "Odaberi jezik", + "english": "Engleski", + "portuguese": "Portugalski", + "portuguese_br": "Portugalski (Brazil)", + "portuguese_pt": "Portugalski (Portugal)", + "german": "Njemački", + "arabic": "Arapski", + "spanish": "Španjolski", + "french": "Francuski", + "italian": "Talijanski", + "croatian": "Hrvatski", + "chinese": "Kineski (pojednostavljeni)", + "hindi": "Hindski", + "serbian": "Srpski", + "account": "Račun", + "content_discovery": "Sadržaj i otkrivanje", + "appearance": "Izgled", + "integrations": "Integracije", + "playback": "Reprodukcija", + "backup_restore": "Sigurnosna kopija i vraćanje", + "updates": "Ažuriranja", + "about": "O aplikaciji", + "developer": "Razvojni programer", + "cache": "Predmemorija", + "title": "Postavke", + "settings_title": "Postavke", + "sign_in_sync": "Prijavite se za sinkronizaciju", + "add_catalogs_sources": "Dodaci, katalozi i izvori", + "player_trailers_downloads": "Player, traileri, preuzimanja", + "mdblist_tmdb_ai": "MDBList, TMDB, AI", + "check_updates": "Provjeri ažuriranja", + "clear_mdblist_cache": "Očisti MDBList predmemoriju", + "cache_management": "UPRAVLJANJE PREDMEMORIJOM", + "downloads_counter": "preuzimanja i raste", + "made_with_love": "Napravljeno s ❤️ - Tapframe i prijatelji", + "sections": { + "information": "INFORMACIJE", + "account": "RAČUN", + "theme": "TEMA", + "layout": "RASPORED", + "sources": "IZVORI", + "catalogs": "KATALOZI", + "discovery": "OTKRIVANJE", + "metadata": "METAPODACI", + "ai_assistant": "AI ASISTENT", + "video_player": "VIDEO PLAYER", + "audio_subtitles": "AUDIO I TITLOVI", + "media": "MEDIJI", + "notifications": "OBAVIJESTI", + "testing": "TESTIRANJE", + "danger_zone": "ZONA OPASNOSTI" + }, + "items": { + "legal": "Pravne napomene i odricanje odgovornosti", + "privacy_policy": "Pravila privatnosti", + "report_issue": "Prijavi problem", + "version": "Verzija", + "contributors": "Suradnici", + "view_contributors": "Prikaži sve suradnike", + "theme": "Tema", + "episode_layout": "Raspored epizoda", + "streams_backdrop": "Pozadina streamova", + "streams_backdrop_desc": "Prikaži zamućenu pozadinu na streamovima na mobitelu", + "addons": "Dodaci", + "installed": "instalirano", + "debrid_integration": "Debrid integracija", + "debrid_desc": "Poveži Torbox", + "plugins": "Priključci", + "plugins_desc": "Upravljaj priključcima i repozitorijima", + "catalogs": "Katalozi", + "active": "aktivno", + "home_screen": "Početni zaslon", + "home_screen_desc": "Raspored i sadržaj", + "continue_watching": "Nastavi gledati", + "continue_watching_desc": "Predmemorija i ponašanje reprodukcije", + "show_discover": "Prikaži odjeljak 'Otkrij'", + "show_discover_desc": "Prikaži sadržaj za otkrivanje u pretrazi", + "mdblist": "MDBList", + "mdblist_connected": "Povezano", + "mdblist_desc": "Omogući za prikaz ocjena i recenzija", + "simkl": "Simkl", + "simkl_connected": "Povezano", + "simkl_desc": "Prati što gledaš", + "tmdb": "TMDB", + "tmdb_desc": "Pružatelj metapodataka i logotipa", + "openrouter": "OpenRouter API", + "openrouter_connected": "Povezano", + "openrouter_desc": "Dodaj API ključ za AI chat", + "video_player": "Video player", + "built_in": "Ugrađeni", + "external": "Vanjski", + "preferred_audio": "Željeni jezik zvuka", + "preferred_subtitle": "Željeni jezik titlova", + "subtitle_source": "Prioritet izvora titlova", + "auto_select_subs": "Automatski odabir titlova", + "auto_select_subs_desc": "Automatski odaberi titlove koji odgovaraju vašim postavkama", + "show_trailers": "Prikaži najave", + "show_trailers_desc": "Prikaži najave u glavnom odjeljku", + "enable_downloads": "Omogući preuzimanja", + "enable_downloads_desc": "Prikaži karticu Preuzimanja i omogući spremanje streamova", + "notifications": "Obavijesti", + "notifications_desc": "Podsjetnici za epizode", + "developer_tools": "Razvojni alati", + "developer_tools_desc": "Opcije za testiranje i uklanjanje pogrešaka", + "test_onboarding": "Testiraj uvodni ekran", + "reset_onboarding": "Resetiraj uvodni ekran", + "test_announcement": "Testiraj objavu", + "test_announcement_desc": "Prikaži prozor s novostima", + "reset_campaigns": "Resetiraj kampanje", + "reset_campaigns_desc": "Očisti zapise o prikazanim kampanjama", + "clear_all_data": "Očisti sve podatke", + "clear_all_data_desc": "Resetiraj sve postavke i predmemorirane podatke" + }, + "options": { + "horizontal": "Vodoravno", + "vertical": "Okomito", + "internal_first": "Prvo unutarnji", + "internal_first_desc": "Prednost imaju ugrađeni titlovi, zatim vanjski", + "external_first": "Prvo vanjski", + "external_first_desc": "Prednost imaju titlovi iz dodataka, zatim ugrađeni", + "any_available": "Bilo koji dostupni", + "any_available_desc": "Koristi prvi dostupni zapis titlova" + }, + "clear_data_desc": "Ovo će resetirati sve postavke i obrisati sve privremene podatke. Jeste li sigurni?", + "app_updates": "Ažuriranja aplikacije", + "about_nuvio": "O Nuviju" + }, + "privacy": { + "title": "Privatnost i Podaci", + "settings_desc": "Kontrolirajte telemetriju i prikupljanje podataka", + "info_title": "Vaša Privatnost nam je Važna", + "info_description": "Kontrolirajte koje podatke se prikupljaju i dijele. Analitika je podrazumevano onemogućena, a izveštaji o greškama su anonimni po zadanom.", + "analytics_enabled_title": "Analitika Omogućena", + "analytics_enabled_message": "Podaci o korišćenju će se prikupljati kako bi se poboljšala aplikacija. Možete to onemogućiti u bilo kojem trenutku.", + "disable_error_reporting_title": "Onemogućiti Izveštavanje o Greškama?", + "disable_error_reporting_message": "Onemogućavanje izveštavanja o greškama znači da nećemo biti obavesteni o padu ili problemima koje doživljate. Ovo može uticati na našu sposobnost da ispravimo greške.", + "enable_session_replay_title": "Omogućiti Reprodukciju Sesije?", + "enable_session_replay_message": "Reprodukcija sesije snima vaš ekran kada se greške dogode kako bi nam pomogla da razumemo šta se desilo. Ovo može da hvata vidljiv sadržaj na vašoj ekranu.", + "enable_pii_title": "Omogućiti Prikupljanje PII?", + "enable_pii_message": "Ovo omogućava prikupljanje lično identifikabilnih podataka kao što su IP adresa i detalji uređaja. Ovi podaci pomažu u dijagnostici problema, ali povećavaju izloženost privatnosti.", + "disable_all_title": "Onemogućiti Svu Telemetriju?", + "disable_all_message": "Ovo će onemogućiti svu analitiku, izveštavanje o greškama i reprodukciju sesije. Nećemo primati nikakve podatke o korišćenju aplikacije ili padevima.", + "disable_all_button": "Onemogući Sve", + "all_disabled_title": "Sva Telemetrija Onemogućena", + "all_disabled_message": "Svo prikupljanje podataka je onemogućeno. Promene će stupiti na snagu pri sledećem pokretanju aplikacije.", + "reset_title": "Resetuj na Preporučene", + "reset_message": "Postavke privatnosti su resetovane na preporučene zadane vrednosti (izveštavanje o greškama omogućeno, analitika onemogućena).", + "section_analytics": "ANALITIKA", + "analytics_title": "Analitika Korišćenja", + "analytics_description": "Prikupljaj anonimne obrasce korišćenja i prikaze ekrana", + "section_error_reporting": "IZVEŠTAVANJE O GREŠKAMA", + "error_reporting_title": "Izveštaji o Greškama", + "error_reporting_description": "Pošalji anonimne izveštaje o greškama kako bi se poboljšala stabilnost", + "session_replay_title": "Reprodukcija Sesije", + "session_replay_description": "Snimaj ekran kada se greške dogode", + "pii_title": "Uključi Informacije o Uređaju", + "pii_description": "Pošalji IP adresu i detalje uređaja sa izveštajima", + "section_quick_actions": "BRZE AKCIJE", + "disable_all": "Onemogući Svu Telemetriju", + "disable_all_desc": "Isključi svo prikupljanje podataka", + "reset_recommended": "Resetuj na Preporučene", + "reset_recommended_desc": "Zadane vrednosti usmeren na privatnost sa izveštavanjem o greškama", + "section_learn_more": "SAZNAJ VIŠE", + "privacy_policy": "Politika Privatnosti", + "current_settings": "Sažetak Trenutnih Postavki", + "summary_analytics": "Analitika", + "summary_errors": "Izveštaji o Greškama", + "summary_replay": "Reprodukcija Sesije", + "summary_pii": "Informacije o Uređaju", + "restart_note_detailed": "* Promene u analitici i izveštavanju o greškama stupaju na snagu odmah. Reprodukcija sesije i PII postavke zahtevaju ponovni pokretanje aplikacije." + }, + "ai_settings": { + "title": "AI asistent", + "info_title": "Chat pokretan umjetnom inteligencijom", + "info_desc": "Postavljajte pitanja o bilo kojem filmu ili epizodi serije koristeći napredni AI. Saznajte više o radnji, likovima, temama i zanimljivostima - sve temeljeno na TMDB podacima.", + "feature_1": "Kontekst i analiza specifična za epizodu", + "feature_2": "Objašnjenja radnje i uvid u likove", + "feature_3": "Zanimljivosti i činjenice iza kulisa", + "feature_4": "Vlastiti besplatni OpenRouter API ključ", + "api_key_section": "OPENROUTER API KLJUČ", + "api_key_label": "API ključ", + "api_key_desc": "Unesite svoj OpenRouter API ključ kako biste omogućili AI chat", + "save_api_key": "Spremi API ključ", + "saving": "Spremanje...", + "update": "Ažuriraj", + "remove": "Ukloni", + "get_free_key": "Nabavi besplatni API ključ od OpenRoutera", + "enable_chat": "Omogući AI Chat", + "enable_chat_desc": "Kada je omogućeno, gumb 'Pitaj AI' pojavit će se na stranicama sadržaja.", + "chat_enabled": "AI Chat omogućen", + "chat_enabled_desc": "Sada možete postavljati pitanja o filmovima i serijama. Potražite gumb \"Pitaj AI\"!", + "how_it_works": "Kako radi", + "how_it_works_desc": "• OpenRouter omogućuje pristup brojnim AI modelima\n• Vaš API ključ ostaje privatan i siguran\n• Besplatni paket uključuje izdašna ograničenja upotrebe\n• Razgovarajte o specifičnim epizodama ili filmovima\n• Dobijte detaljne analize i objašnjenja", + "error_invalid_key": "Molimo unesite važeći API ključ", + "error_key_format": "OpenRouter API ključevi trebaju počinjati s \"sk-or-\"", + "success_saved": "OpenRouter API ključ je uspješno spremljen!", + "error_save": "Spremanje API ključa nije uspjelo", + "confirm_remove_title": "Ukloni API ključ", + "confirm_remove_msg": "Jeste li sigurni da želite ukloniti svoj OpenRouter API ključ? To će onemogućiti AI chat.", + "success_removed": "API ključ uspješno uklonjen", + "error_remove": "Uklanjanje API ključa nije uspjelo" + }, + "catalog_settings": { + "title": "Katalozi", + "layout_phone": "RASPORED ZASLONA KATALOGA (MOBITEL)", + "posters_per_row": "Postera po retku", + "auto": "Automatski", + "show_titles": "Prikaži naslove postera", + "show_titles_desc": "Prikaži tekst naslova ispod svakog postera", + "phone_only_hint": "Vrijedi samo za mobitele. Tableti zadržavaju prilagodljivi raspored.", + "catalogs_group": "Katalozi", + "enabled_count": "Omogućeno {{enabled}} od {{total}}", + "rename_hint": "Dugo pritisnite katalog za preimenovanje", + "rename_modal_title": "Preimenuj katalog", + "rename_placeholder": "Unesite novi naziv kataloga", + "error_save_name": "Spremanje prilagođenog naziva nije uspjelo." + }, + "continue_watching_settings": { + "title": "Nastavi gledati", + "playback_behavior": "PONAŠANJE REPRODUKCIJE", + "use_cached": "Koristi predmemorirane streamove", + "use_cached_desc": "Kada je omogućeno, klikom na stavke 'Nastavi gledati' player se otvara izravno koristeći prethodne streamove. Kada je isključeno, otvara se zaslon sa sadržajem.", + "open_metadata": "Otvori zaslon s detaljima", + "open_metadata_desc": "Kada su predmemorirani streamovi isključeni, otvara se zaslon s detaljima umjesto popisa streamova. Ovo omogućuje ručni odabir streama.", + "card_appearance": "IZGLED KARTICE", + "card_style": "Stil kartice", + "card_style_desc": "Odaberite kako će se stavke 'Nastavi gledati' pojavljivati na početnom zaslonu", + "wide": "Široko", + "poster": "Poster", + "cache_settings": "POSTAVKE PREDMEMORIJE", + "cache_duration": "Trajanje predmemorije streama", + "cache_duration_desc": "Koliko dugo čuvati poveznice streamova prije nego što isteknu", + "important_note": "Važna napomena", + "important_note_text": "Sve poveznice streamova možda neće ostati aktivne cijelo vrijeme. Duže vrijeme predmemorije može rezultirati neispravnim poveznicama. U tom slučaju, aplikacija će ponovno dohvatiti svježe streamove.", + "how_it_works": "Kako radi", + "how_it_works_cached": "• Streamovi se spremaju na odabrano trajanje nakon gledanja\n• Predmemorirani streamovi se provjeravaju prije upotrebe\n• Ako je zapis nevažeći ili istekao, otvara se zaslon sadržaja\n• Opcija 'Koristi predmemorirane streamove' kontrolira izravni ulaz u player\n• 'Otvori zaslon s detaljima' pojavljuje se samo kad su predmemorirani streamovi isključeni", + "how_it_works_uncached": "• Kada su predmemorirani streamovi isključeni, klik otvara zaslone sadržaja\n• Opcija 'Otvori zaslon s detaljima' određuje koji će se zaslon otvoriti\n• Zaslon s metapodacima prikazuje detalje i ručni odabir\n• Zaslon sa streamovima prikazuje dostupne izvore za trenutnu reprodukciju", + "changes_saved": "Promjene spremljene", + "min": "min", + "hour": "sat", + "hours": "sati" + }, + "contributors": { + "title": "Suradnici", + "special_mentions": "Posebna priznanja", + "tab_contributors": "Suradnici", + "tab_special": "Posebna priznanja", + "tab_donors": "Donatori", + "manager_role": "Voditelj zajednice", + "manager_desc": "Upravlja Discord i Reddit zajednicama za Nuvio", + "sponsor_role": "Sponzor poslužitelja", + "sponsor_desc": "Sponzorirao infrastrukturu poslužitelja za Nuvio", + "mod_role": "Discord moderator", + "mod_desc": "Pomaže u moderiranju Nuvio Discord zajednice", + "loading": "Učitavanje...", + "discord_user": "Discord korisnik", + "contributions": "doprinosa", + "gratitude_title": "Zahvalni smo na svakom doprinosu", + "gratitude_desc": "Svaka linija koda, prijava pogreške i prijedlog pomažu da Nuvio postane bolji za sve", + "special_thanks_title": "Posebna hvala", + "special_thanks_desc": "Ovi nevjerojatni ljudi pomažu u održavanju Nuvio zajednice i poslužitelja", + "donors_desc": "Hvala vam što vjerujete u ono što gradimo. Vaša podrška drži Nuvio besplatnim i stalno ga poboljšava.", + "latest_donations": "Najnovije", + "leaderboard": "Poredak", + "loading_donors": "Učitavanje donatora...", + "no_donors": "Još nema donatora", + "error_rate_limit": "Prekoračeno ograničenje GitHub API-ja. Pokušajte kasnije.", + "error_failed": "Učitavanje suradnika nije uspjelo. Provjerite internetsku vezu.", + "retry": "Pokušaj ponovno", + "no_contributors": "Nisu pronađeni suradnici", + "loading_contributors": "Učitavanje suradnika..." + }, + "debrid": { + "title": "Debrid integracija", + "description_torbox": "Connect Torbox to use your account-based source preferences. Enter your API key below to configure the integration.", + "description_torrentio": "Configure Torrentio as an external source integration. A compatible debrid account may be required depending on your setup.", + "tab_torbox": "TorBox", + "tab_torrentio": "Torrentio", + "status_connected": "Povezano", + "status_disconnected": "Odspojeno", + "enable_addon": "Omogući dodatak", + "disconnect_button": "Odspoji i ukloni", + "disconnect_loading": "Odspajanje...", + "account_info": "Informacije o računu", + "plan": "Paket", + "plan_free": "Besplatno", + "plan_essential": "Essential (3 $/mj)", + "plan_pro": "Pro (10 $/mj)", + "plan_standard": "Standard (5 $/mj)", + "plan_unknown": "Nepoznato", + "expires": "Istječe", + "downloaded": "Preuzeto", + "status_active": "Aktivno", + "connected_title": "✓ Povezano s TorBoxom", + "connected_desc": "Vaš TorBox dodatak je aktivan i pruža premium streamove.", + "configure_title": "Konfiguriraj dodatak", + "configure_desc": "Prilagodite svoje iskustvo. Razvrstajte po kvaliteti, filtrirajte veličine datoteka i upravljajte postavkama.", + "open_settings": "Otvori postavke", + "what_is_debrid": "Što je Debrid usluga?", + "enter_api_key": "Unesite API ključ", + "connect_button": "Poveži i instaliraj", + "connecting": "Povezivanje...", + "unlock_speeds_title": "Optional Torbox Subscription", + "unlock_speeds_desc": "Torbox offers account tiers with enhanced performance and availability features.", + "get_subscription": "Pretplati se", + "powered_by": "Pokreće", + "disclaimer_torbox": "Nuvio nije povezan s Torboxom ni na koji način.", + "disclaimer_torrentio": "Nuvio nije povezan s Torrentio dodatakom ni na koji način.", + "installed_badge": "✓ INSTALIRANO", + "promo_title": "⚡ Trebate Debrid uslugu?", + "promo_desc": "Use TorBox if you want account-managed performance features for supported integrations.", + "promo_button": "Nabavi TorBox pretplatu", + "service_label": "Debrid usluga *", + "api_key_label": "API ključ *", + "sorting_label": "Razvrstavanje", + "exclude_qualities": "Isključi kvalitete", + "priority_languages": "Prioritetni jezici", + "max_results": "Maksimalno rezultata", + "additional_options": "Dodatne opcije", + "no_download_links": "Ne prikazuj poveznice za preuzimanje", + "no_debrid_catalog": "Ne prikazuj debrid katalog", + "install_button": "Instaliraj Torrentio", + "installing": "Instalacija...", + "update_button": "Ažuriraj konfiguraciju", + "updating": "Ažuriranje...", + "remove_button": "Ukloni Torrentio", + "error_api_required": "Potreban API ključ", + "error_api_required_desc": "Unesite API ključ debrid usluge za instalaciju Torrentia.", + "success_installed": "Torrentio dodatak je uspješno instaliran!", + "success_removed": "Torrentio dodatak je uspješno uklonjen", + "alert_disconnect_title": "Odspoji Torbox", + "alert_disconnect_msg": "Jeste li sigurni da želite odspojiti Torbox? Ovo će ukloniti dodatak i obrisati API ključ." + }, + "home_screen": { + "title": "Postavke početnog zaslona", + "changes_applied": "Promjene primijenjene", + "display_options": "OPCIJE PRIKAZA", + "show_hero": "Prikaži istaknuti sadržaj", + "show_hero_desc": "Istaknuti sadržaj na vrhu", + "show_this_week": "Prikaži 'Ovaj tjedan'", + "show_this_week_desc": "Nove epizode iz tekućeg tjedna", + "select_catalogs": "Odaberi kataloge", + "all_catalogs": "Svi katalozi", + "selected": "odabrano", + "hero_layout": "Izgled istaknutog sadržaja", + "layout_legacy": "Klasično", + "layout_carousel": "Vrtuljak", + "layout_appletv": "Apple TV", + "layout_desc": "Banner pune širine, kartice koje se listaju ili Apple TV stil", + "featured_source": "Izvor istaknutog sadržaja", + "using_catalogs": "Koriste se katalozi", + "manage_selected_catalogs": "Upravljaj odabranim katalozima", + "dynamic_bg": "Dinamična pozadina", + "dynamic_bg_desc": "Zamućeni banner iza vrtuljka", + "performance_note": "Može utjecati na performanse na slabijim uređajima.", + "posters": "Posteri", + "show_titles": "Prikaži naslove", + "poster_size": "Veličina postera", + "poster_corners": "Kutovi postera", + "size_small": "Mali", + "size_medium": "Srednji", + "size_large": "Veliki", + "corners_square": "Oštri", + "corners_rounded": "Zaobljeni", + "corners_pill": "Ovalni", + "about_these_settings": "O OVIM POSTAVKAMA", + "about_desc": "Ove postavke kontroliraju kako se sadržaj prikazuje na vašem početnom zaslonu. Promjene se primjenjuju odmah bez potrebe za ponovnim pokretanjem aplikacije.", + "hero_catalogs": { + "title": "Katalozi istaknutog sadržaja", + "select_all": "Odaberi sve", + "clear_all": "Očisti sve", + "info": "Odaberite koji će se katalozi prikazivati u odjeljku s istaknutim sadržajem. Ako ništa nije odabrano, koristit će se svi katalozi. Ne zaboravite pritisnuti 'Spremi' kada završite.", + "settings_saved": "Postavke spremljene", + "error_load": "Učitavanje kataloga nije uspjelo", + "movies": "Filmovi", + "tv_shows": "Serije" + } + }, + "calendar": { + "title": "Kalendar", + "loading": "Učitavanje kalendara...", + "no_scheduled_episodes": "Nema zakazanih epizoda", + "check_back_later": "Provjerite ponovno kasnije", + "showing_episodes_for": "Prikaz epizoda za {{date}}", + "show_all_episodes": "Prikaži sve epizode", + "no_episodes_for": "Nema epizoda za {{date}}", + "no_upcoming_found": "Nisu pronađene nadolazeće epizode", + "add_series_desc": "Dodajte serije u svoju knjižnicu kako biste ovdje vidjeli njihove nadolazeće epizode" + }, + "mdblist": { + "title": "Izvori ocjena", + "status_disabled": "MDBList onemogućen", + "status_active": "API ključ aktivan", + "status_required": "Potreban API ključ", + "status_disabled_desc": "MDBList funkcionalnost je trenutno isključena.", + "status_active_desc": "Ocjene s MDBList-a su omogućene.", + "status_required_desc": "Dodajte svoj ključ ispod kako biste omogućili ocjene.", + "enable_toggle": "Omogući MDBList", + "enable_toggle_desc": "Uključi/isključi sve MDBList funkcionalnosti", + "api_section": "API ključ", + "placeholder": "Zalijepite svoj MDBList API ključ", + "save": "Spremi", + "clear": "Obriši ključ", + "rating_providers": "Pružatelji ocjena", + "rating_providers_desc": "Odaberite čije će se ocjene prikazivati u aplikaciji", + "how_to": "Kako dobiti API ključ", + "step_1": "Prijavite se na", + "step_1_link": "MDBList web stranici", + "step_2": "Idite na odjeljak", + "step_2_settings": "Postavke", + "step_2_api": "API", + "step_2_end": ".", + "step_3": "Generirajte novi ključ i kopirajte ga.", + "go_to_website": "Posjeti MDBList", + "alert_clear_title": "Brisanje API ključa", + "alert_clear_msg": "Jeste li sigurni da želite ukloniti spremljeni API ključ?", + "success_saved": "API ključ uspješno spremljen.", + "error_empty": "API ključ ne može biti prazan.", + "error_save": "Došlo je do pogreške pri spremanju. Pokušajte ponovno.", + "api_key_empty_error": "API ključ ne može biti prazan.", + "success_cleared": "API ključ uspješno obrisan", + "error_clear": "Brisanje API ključa nije uspjelo" + }, + "notification": { + "title": "Postavke obavijesti", + "section_general": "Općenito", + "enable_notifications": "Omogući obavijesti", + "section_types": "Vrste obavijesti", + "new_episodes": "Nove epizode", + "upcoming_shows": "Nadolazeće serije", + "reminders": "Podsjetnici", + "section_timing": "Vrijeme obavijesti", + "timing_desc": "Kada želite primiti obavijest prije emitiranja epizode?", + "hours_1": "1 sat", + "hours_suffix": "sati", + "section_status": "Status obavijesti", + "stats_upcoming": "Nadolazeće", + "stats_this_week": "Ovaj tjedan", + "stats_total": "Ukupno", + "sync_button": "Sinkroniziraj knjižnicu i Trakt", + "syncing": "Sinkronizacija...", + "sync_desc": "Automatski sinkronizira obavijesti za sve serije u vašoj knjižnici i Trakt listama.", + "section_advanced": "Napredno", + "reset_button": "Resetiraj sve obavijesti", + "test_button": "Testiraj obavijest (5 sek)", + "test_notification_in": "Obavijest za {{seconds}}s...", + "test_notification_text": "Obavijest će se pojaviti za {{seconds}} sekundi", + "alert_reset_title": "Resetiraj obavijesti", + "alert_reset_msg": "Ovo će otkazati sve zakazane obavijesti, ali neće ukloniti ništa iz vaše knjižnice. Jeste li sigurni?", + "alert_reset_success": "Sve obavijesti su resetirane", + "alert_sync_complete": "Sinkronizacija dovršena", + "alert_sync_msg": "Uspješno sinkronizirane obavijesti za vašu knjižnicu i Trakt stavke.\n\nZakazano: {{upcoming}} nadolazećih epizoda\nOvaj tjedan: {{thisWeek}} epizoda", + "alert_test_scheduled": "Testna obavijest zakazana za trenutno prikazivanje" + }, + "backup": { + "title": "Sigurnosna kopija i oporavak", + "options_title": "Opcije sigurnosne kopije", + "options_desc": "Odaberite što želite uključiti u sigurnosnu kopiju", + "section_core": "Osnovni podaci", + "section_addons": "Dodaci i integracije", + "section_settings": "Postavke i preferencije", + "library_label": "Knjižnica", + "library_desc": "Vaši spremljeni filmovi i serije", + "watch_progress_label": "Napredak gledanja", + "watch_progress_desc": "Pozicije 'Nastavi gledati'", + "addons_label": "Dodaci", + "addons_desc": "Instalirani Stremio dodaci", + "plugins_label": "Priključci", + "plugins_desc": "Prilagođene konfiguracije strugača", + "trakt_label": "Trakt integracija", + "trakt_desc": "Sinkronizacija podataka i tokeni za prijavu", + "app_settings_label": "Postavke aplikacije", + "app_settings_desc": "Tema, preferencije i konfiguracije", + "user_prefs_label": "Korisničke preferencije", + "user_prefs_desc": "Redoslijed dodataka i postavke sučelja", + "catalog_settings_label": "Postavke kataloga", + "catalog_settings_desc": "Filteri kataloga i preferencije", + "api_keys_label": "API ključevi", + "api_keys_desc": "MDBList i OpenRouter ključevi", + "action_create": "Stvori sigurnosnu kopiju", + "action_restore": "Vrati iz sigurnosne kopije", + "section_info": "O sigurnosnim kopijama", + "info_text": "• Prilagodite što se sprema pomoću prekidača iznad\n• Datoteke se pohranjuju lokalno na vašem uređaju\n• Podijelite sigurnosnu kopiju za prijenos podataka na drugi uređaj\n• Oporavak će prepisati vaše trenutne podatke", + "alert_create_title": "Stvori sigurnosnu kopiju", + "alert_no_content": "Nije odabran sadržaj za kopiju.\n\nMolimo omogućite barem jednu opciju iznad.", + "alert_backup_created_title": "Kopija stvorena", + "alert_backup_created_msg": "Vaša sigurnosna kopija je spremna i možete je podijeliti.", + "alert_backup_failed_title": "Stvaranje kopije nije uspjelo", + "alert_restore_confirm_title": "Potvrdi oporavak", + "alert_restore_confirm_msg": "Ovo će vratiti vaše podatke iz kopije stvorene {{date}}.\n\nOva radnja će prepisati trenutne podatke. Želite li nastaviti?", + "alert_restore_complete_title": "Oporavak dovršen", + "alert_restore_complete_msg": "Vaši podaci su uspješno vraćeni. Ponovno pokrenite aplikaciju za primjenu promjena.", + "alert_restore_failed_title": "Oporavak nije uspio", + "restart_app": "Ponovno pokreni aplikaciju", + "alert_restart_failed_title": "Ponovno pokretanje nije uspjelo", + "alert_restart_failed_msg": "Neuspjelo ponovno pokretanje. Ručno zatvorite i otvorite aplikaciju." + }, + "updates": { + "title": "Ažuriranja aplikacije", + "status_checking": "Provjera ažuriranja...", + "status_available": "Ažuriranje dostupno!", + "status_downloading": "Preuzimanje ažuriranja...", + "status_installing": "Instalacija ažuriranja...", + "status_success": "Ažuriranje uspješno instalirano!", + "status_error": "Ažuriranje nije uspjelo", + "status_ready": "Spremno za provjeru", + "action_check": "Provjeri ažuriranja", + "action_install": "Instaliraj ažuriranje", + "release_notes": "Napomene o izdanju:", + "version": "Verzija:", + "last_checked": "Zadnja provjera:", + "current_version": "Trenutna verzija:", + "current_release_notes": "Trenutne napomene o izdanju:", + "github_release": "GITHUB IZDANJE", + "current": "Trenutna:", + "latest": "Najnovija:", + "notes": "Bilješke:", + "view_release": "Pogledaj izdanje", + "notification_settings": "POSTAVKE OBAVIJESTI", + "ota_alerts_label": "OTA upozorenja o ažuriranju", + "ota_alerts_desc": "Prikaži obavijesti za bežična (OTA) ažuriranja", + "major_alerts_label": "Glavna upozorenja o ažuriranju", + "major_alerts_desc": "Prikaži obavijesti za nove verzije na GitHubu", + "alert_disable_ota_title": "Onemogućiti OTA upozorenja?", + "alert_disable_ota_msg": "Više nećete primati obavijesti o OTA ažuriranjima.\n\n⚠️ Upozorenje: Najnovija verzija je važna za:\n• Ispravke bugova i stabilnost\n• Nove značajke\n• Točne izvještaje o padu aplikacije\n\nI dalje možete ručno provjeriti ažuriranja.", + "alert_disable_major_title": "Onemogućiti glavna upozorenja?", + "alert_disable_major_msg": "Više nećete primati obavijesti o verzijama koje zahtijevaju ponovnu instalaciju.\n\n⚠️ Upozorenje: Glavna ažuriranja sadrže:\n• Kritične sigurnosne zakrpe\n• Velike promjene sustava\n• Važne ispravke kompatibilnosti", + "warning_note": "Omogućena upozorenja osiguravaju da dobijete ispravke i nove mogućnosti.", + "disable": "Onemogući", + "alert_no_update_to_install": "Nema dostupnog ažuriranja za instalaciju", + "alert_install_failed": "Instalacija ažuriranja nije uspjela", + "alert_no_update_title": "Nema ažuriranja", + "alert_update_applied_msg": "Ažuriranje će se primijeniti kod sljedećeg pokretanja" + }, + "player": { + "title": "Video player", + "section_selection": "ODABIR PLAYERA", + "internal_title": "Ugrađeni player", + "internal_desc": "Koristi zadani player aplikacije", + "vlc_title": "VLC", + "vlc_desc": "Otvori streamove u VLC-u", + "infuse_title": "Infuse", + "infuse_desc": "Otvori streamove u Infuse-u", + "outplayer_title": "OutPlayer", + "outplayer_desc": "Otvori streamove u OutPlayeru", + "vidhub_title": "VidHub", + "vidhub_desc": "Otvori streamove u VidHubu", + "infuse_live_title": "Infuse LiveContainer", + "infuse_live_desc": "Otvori streamove u Infuse-u putem LiveContainera", + "external_title": "Vanjski player", + "external_desc": "Otvori streamove u svom željenom playeru", + "section_playback": "OPCIJE REPRODUKCIJE", + "skip_intro_settings_title": "Preskoči uvod", + "powered_by_introdb": "Pokreće IntroDB", + "autoplay_title": "Automatska reprodukcija prvog streama", + "autoplay_desc": "Automatski pokreni prvi stream s popisa.", + "resume_title": "Uvijek nastavi", + "resume_desc": "Preskoči upit i nastavi tamo gdje ste stali (ako je odgledano manje od 85%).", + "engine_title": "Engine video playera", + "engine_desc": "Auto koristi ExoPlayer uz MPV kao rezervu. Neki formati poput Dolby Vision možda nisu podržani na MPV-u.", + "decoder_title": "Način dekodiranja", + "decoder_desc": "Kako se video dekodira. 'Auto' se preporučuje.", + "gpu_title": "GPU renderiranje", + "gpu_desc": "GPU-Next nudi bolje HDR upravljanje bojama.", + "external_downloads_title": "Vanjski player za preuzimanja", + "external_downloads_desc": "Reproduciraj preuzeti sadržaj u vanjskom playeru.", + "restart_required": "Potrebno ponovno pokretanje", + "restart_msg_decoder": "Ponovno pokrenite aplikaciju za primjenu promjena dekodera.", + "restart_msg_gpu": "Ponovno pokrenite aplikaciju za primjenu GPU načina.", + "option_auto": "Auto", + "option_auto_desc_engine": "ExoPlayer + MPV rezerva", + "option_mpv": "MPV", + "option_mpv_desc": "Samo MPV", + "option_auto_desc_decoder": "Najbolji balans", + "option_sw": "SW", + "option_sw_desc": "Softversko", + "option_hw": "HW", + "option_hw_desc": "Hardversko", + "option_hw_plus": "HW+", + "option_hw_plus_desc": "Puni HW", + "option_gpu_desc": "Standardno", + "option_gpu_next_desc": "Napredno" + }, + "plugins": { + "title": "Priključci", + "enable_title": "Omogući priključke", + "enable_desc": "Omogući sustav priključaka za pronalaženje vanjskih izvora medija", + "repo_config_title": "Konfiguracija repozitorija", + "repo_config_desc": "Upravljajte vanjskim repozitorijima priključaka.", + "your_repos": "Repozitoriji", + "your_repos_desc": "Konfigurirajte vanjske izvore za priključke.", + "add_repo_button": "Dodaj repozitorij", + "refresh": "Osvježi", + "remove": "Ukloni", + "enabled": "Omogućeno", + "disabled": "Onemogućeno", + "updating": "Ažuriranje...", + "success": "Uspjeh", + "error": "Pogreška", + "alert_repo_added": "Repozitorij dodan i priključci uspješno učitani", + "alert_repo_saved": "URL repozitorija uspješno spremljen", + "alert_repo_refreshed": "Repozitorij uspješno osvježen", + "alert_invalid_url": "Nevažeći URL format", + "alert_plugins_cleared": "Svi priključci su uklonjeni", + "alert_cache_cleared": "Predmemorija repozitorija uspješno očišćena", + "unknown": "Nepoznato", + "active": "Aktivno", + "available": "Dostupno", + "platform_disabled": "Platforma onemogućena", + "limited": "Ograničeno", + "clear_all": "Ukloni sve priključke", + "clear_all_desc": "Jeste li sigurni da želite ukloniti sve instalirane priključke? To se ne može poništiti.", + "clear_cache": "Očisti predmemoriju repozitorija", + "clear_cache_desc": "Ovo će ukloniti URL i podatke repozitorija. Morat ćete ga ponovno unijeti.", + "add_new_repo": "Dodaj novi repozitorij", + "available_plugins": "Dostupni priključci ({{count}})", + "placeholder": "Pretraži priključke...", + "all": "Svi", + "filter_all": "Sve vrste", + "filter_movies": "Filmovi", + "filter_tv": "Serije", + "enable_all": "Omogući sve", + "disable_all": "Onemogući sve", + "no_plugins_found": "Priključci nisu pronađeni", + "no_plugins_available": "Nema dostupnih priključaka", + "no_match_desc": "Nema rezultata za \"{{query}}\". Pokušajte s drugim pojmom.", + "configure_repo_desc": "Konfigurirajte repozitorij iznad za prikaz priključaka.", + "clear_search": "Očisti pretragu", + "no_external_player": "Nema vanjskog playera", + "showbox_token": "ShowBox UI Token", + "showbox_placeholder": "Zalijepite svoj ShowBox UI token", + "save": "Spremi", + "clear": "Očisti", + "additional_settings": "Dodatne postavke", + "enable_url_validation": "Omogući provjeru URL-a", + "url_validation_desc": "Provjeri ispravnost poveznica (može usporiti rezultate, ali povećava pouzdanost)", + "group_streams": "Grupiraj izvore priključaka", + "group_streams_desc": "Izvori će biti grupirani prema repozitoriju.", + "sort_quality": "Poredaj prvo po kvaliteti", + "sort_quality_desc": "Izvori se prvo razvrstavaju po kvaliteti (samo uz grupiranje).", + "show_logos": "Prikaži logotipe priključaka", + "show_logos_desc": "Prikaži logotipe pored izvora na zaslonu odabira.", + "quality_filtering": "Filtriranje kvalitete", + "quality_filtering_desc": "Isključi određene rezolucije iz rezultata.", + "excluded_qualities": "Isključene kvalitete:", + "language_filtering": "Filtriranje jezika", + "language_filtering_desc": "Isključi određene jezike iz rezultata.", + "note": "Napomena:", + "language_filtering_note": "Ovo se primjenjuje samo na pružatelje koji šalju informaciju o jeziku.", + "excluded_languages": "Isključeni jezici:", + "about_title": "O priključcima", + "about_desc_1": "Priključci su modularne komponente koje prilagođavaju sadržaj s vanjskih protokola. Rade lokalno na vašem uređaju.", + "about_desc_2": "Priključci označeni kao \"Ograničeno\" mogu zahtijevati dodatne konfiguracije.", + "help_title": "Postavljanje priključaka", + "help_step_1": "1. **Omogući priključke** - Uključite glavni prekidač", + "help_step_2": "2. **Dodaj repozitorij** - Unesite ispravan URL", + "help_step_3": "3. **Osvježi** - Povucite popis dostupnih priključaka", + "help_step_4": "4. **Aktiviraj** - Omogućite željene priključke", + "got_it": "Razumijem!", + "repo_format_hint": "Format: https://raw.githubusercontent.com/korisnik/repo/refs/heads/branch", + "cancel": "Odustani", + "add": "Dodaj" + }, + "theme": { + "title": "Teme aplikacije", + "select_theme": "ODABERI TEMU", + "create_custom": "Stvori vlastitu temu", + "options": "OPCIJE", + "use_dominant_color": "Koristi dominantnu boju s postera", + "categories": { + "all": "Sve teme", + "dark": "Tamne teme", + "colorful": "Šarene", + "custom": "Moje teme" + }, + "editor": { + "theme_name_placeholder": "Naziv teme", + "save": "Spremi", + "primary": "Primarna", + "secondary": "Sekundarna", + "background": "Pozadina", + "invalid_name_title": "Nevažeći naziv", + "invalid_name_msg": "Molimo unesite ispravan naziv teme" + }, + "alerts": { + "delete_title": "Obriši temu", + "delete_msg": "Jeste li sigurni da želite obrisati temu \"{{name}}\"?", + "ok": "U redu", + "delete": "Obriši", + "cancel": "Odustani", + "back": "Postavke" + } + }, + "legal": { + "title": "Pravne napomene i odricanje odgovornosti", + "intro_title": "Priroda aplikacije", + "intro_text": "Nuvio je media player i aplikacija za upravljanje metapodacima. Djeluje isključivo kao klijentsko sučelje za pregledavanje javno dostupnih informacija (filmovi, serije) i reprodukciju datoteka koje osigura korisnik ili dodaci trećih strana. Nuvio ne ugošćuje, ne distribuira niti indeksira nikakav medijski sadržaj.", + "extensions_title": "Priključci trećih strana", + "extensions_text": "Nuvio omogućuje instalaciju priključaka koje razvijaju neovisni programeri. Nemamo kontrolu niti odgovornost za sadržaj, zakonitost ili funkcionalnost tih priključaka.", + "user_resp_title": "Odgovornost korisnika", + "user_resp_text": "Korisnici su isključivo odgovorni za priključke koje instaliraju. Korištenjem aplikacije pristajete osigurati da imate zakonsko pravo na pristup sadržaju koji gledate. Autori Nuvia ne potiču kršenje autorskih prava.", + "dmca_title": "Autorska prava i DMCA", + "dmca_text": "We respect the intellectual property rights of others. Nuvio does not host media content. If you believe this project's code, assets, or interface infringes your rights, submit a notice through the official project contact channels listed on the website and repository.", + "warranty_title": "Bez jamstva", + "warranty_text": "Softver se isporučuje \"kakav jest\", bez ikakvih jamstava. Autori nisu odgovorni za bilo kakvu štetu nastalu korištenjem ovog softvera." + }, + "plugin_tester": { + "title": "Plugin Tester", + "subtitle": "Pokrenite strugače i pratite zapise u stvarnom vremenu", + "tabs": { + "individual": "Pojedinačno", + "repo": "Repo Tester", + "code": "Kod", + "logs": "Zapisi", + "results": "Rezultati" + }, + "common": { + "error": "Pogreška", + "success": "Uspjeh", + "movie": "Film", + "tv": "Serija", + "tmdb_id": "TMDB ID", + "season": "Sezona", + "episode": "Epizoda", + "running": "Pokretanje…", + "run_test": "Pokreni test", + "play": "Reproduciraj", + "done": "Gotovo", + "test": "Test", + "testing": "Testiranje…" + }, + "individual": { + "load_from_url": "Učitaj s URL-a", + "load_from_url_desc": "Zalijepite GitHub URL ili lokalni IP i preuzmite.", + "enter_url_error": "Molimo unesite URL", + "code_loaded": "Kod učitan s URL-a", + "fetch_error": "Dohvaćanje nije uspjelo: {{message}}", + "no_code_error": "Nema koda za pokretanje", + "plugin_code": "Kod priključka", + "focus_editor": "Fokusiraj uređivač koda", + "code_placeholder": "// Zalijepite kod priključka ovdje...", + "test_parameters": "Testni parametri", + "no_logs": "Još nema zapisa. Pokrenite test.", + "no_streams": "Nisu pronađeni streamovi.", + "streams_found": "Pronađen {{count}} stream", + "streams_found_plural": "Pronađeno {{count}} streama", + "tap_play_hint": "Dodirnite 'Reproduciraj' za testiranje streama.", + "unnamed_stream": "Neimenovani stream", + "quality": "Kvaliteta: {{quality}}", + "size": "Veličina: {{size}}", + "url_label": "URL: {{url}}", + "headers_info": "Zaglavlja: {{count}} prilagođenih", + "find_placeholder": "Pronađi u kodu…", + "edit_code_title": "Uredi kod", + "no_url_stream_error": "Nije pronađen URL za ovaj stream" + }, + "repo": { + "title": "Repo Tester", + "description": "Dohvatite repozitorij i testirajte svakog pružatelja.", + "enter_repo_url_error": "Unesite URL repozitorija", + "invalid_url_title": "Nevažeći URL", + "invalid_url_msg": "Koristite GitHub raw URL ili lokalni http(s) URL.", + "manifest_build_error": "Neuspjelo stvaranje URL-a manifesta", + "manifest_fetch_error": "Neuspjelo dohvaćanje manifesta", + "repo_manifest_fetch_error": "Neuspjelo dohvaćanje manifesta repozitorija", + "missing_filename": "Nedostaje naziv datoteke u manifestu", + "scraper_build_error": "Neuspjelo stvaranje URL-a strugača", + "download_scraper_error": "Neuspjelo preuzimanje strugača", + "test_failed": "Test nije uspio", + "test_parameters": "Parametri Repo testa", + "test_parameters_desc": "Ovi se parametri koriste samo za Repo Tester.", + "using_info": "Koristi se: {{mediaType}} • TMDB {{tmdbId}}", + "using_info_tv": "Koristi se: {{mediaType}} • TMDB {{tmdbId}} • S{{season}}E{{episode}}", + "providers_title": "Pružatelji", + "repository_default": "Repozitorij", + "providers_count": "{{count}} pružatelja", + "fetch_hint": "Dohvatite repo za popis pružatelja.", + "test_all": "Testiraj sve", + "status_running": "U TIJEKU", + "status_ok": "OK ({{count}})", + "status_ok_empty": "OK (0)", + "status_failed": "NEUSPJEH", + "status_idle": "ČEKANJE", + "tried_url": "Pokušano: {{url}}", + "provider_logs": "Zapisi pružatelja", + "no_logs_captured": "Nema zapisa." + } + } +} diff --git a/src/i18n/locales/it.json b/src/i18n/locales/it.json index 5e34bf56..3d8cf357 100644 --- a/src/i18n/locales/it.json +++ b/src/i18n/locales/it.json @@ -636,6 +636,18 @@ "chinese": "Cinese (Semplificato)", "hindi": "Hindi", "serbian": "Serbo", + "hebrew": "Ebraico", + "bulgarian": "Bulgaro", + "polish": "Polacco", + "czech": "Ceco", + "turkish": "Turco", + "slovenian": "Sloveno", + "macedonian": "Macedone", + "russian": "Russo", + "filipino": "Filippino", + "dutch_nl": "Olandese (Paesi Bassi)", + "romanian": "Rumeno", + "albanian": "Albanese", "account": "Account", "content_discovery": "Contenuti e Scoperta", "appearance": "Aspetto", diff --git a/src/i18n/locales/mk.json b/src/i18n/locales/mk.json new file mode 100644 index 00000000..22b8287d --- /dev/null +++ b/src/i18n/locales/mk.json @@ -0,0 +1,1428 @@ +{ + "common": { + "loading": "Се вчитува...", + "cancel": "Откажи", + "save": "Зачувај", + "delete": "Избриши", + "edit": "Уреди", + "search": "Пребарај", + "error": "Грешка", + "success": "Успешно", + "ok": "Во ред", + "unknown": "Непознато", + "retry": "Обиди се повторно", + "try_again": "Обиди се пак", + "go_back": "Оди назад", + "settings": "Поставки", + "close": "Затвори", + "enable": "Овозможи", + "disable": "Оневозможи", + "show_more": "Прикажи повеќе", + "show_less": "Прикажи помалку", + "load_more": "Вчитај повеќе", + "unknown_date": "Непознат датум", + "anonymous_user": "Анонимен корисник", + "time": { + "now": "Штотуку", + "minutes_ago": "Пред {{count}}м", + "hours_ago": "Пред {{count}}ч", + "days_ago": "Пред {{count}}д" + }, + "days_short": { + "sun": "Нед", + "mon": "Пон", + "tue": "Вто", + "wed": "Сре", + "thu": "Чет", + "fri": "Пет", + "sat": "Саб" + }, + "email": "Е-пошта", + "status": "Статус" + }, + "home": { + "categories": { + "movies": "Филмови", + "series": "Серии", + "channels": "Канали" + }, + "movies": "Филмови", + "tv_shows": "ТВ Емисии", + "load_more_catalogs": "Вчитај повеќе каталози", + "no_content": "Нема достапна содржина", + "add_catalogs": "Додај каталози", + "sign_in_available": "Достапна е најава", + "sign_in_desc": "Можете да се најавите во секое време преку Поставки → Сметка", + "view_all": "Види ги сите", + "this_week": "Оваа недела", + "upcoming": "Наскоро", + "recently_released": "Неодамна објавено", + "no_scheduled_episodes": "Серии без закажани епизоди", + "check_back_later": "Проверете подоцна", + "continue_watching": "Продолжи со гледање", + "up_next": "Следно за гледање", + "up_next_caps": "СЛЕДНО", + "released": "Објавено", + "new": "Ново", + "tba": "Наскоро", + "new_episodes": "{{count}} нови епизоди", + "season_short": "С{{season}}", + "episode_short": "Е{{episode}}", + "season": "Сезона {{season}}", + "episode": "Епизода {{episode}}", + "movie": "Филм", + "series": "Серија", + "tv_show": "ТВ Емисија", + "percent_watched": "{{percent}}% изгледано", + "view_details": "Види детали", + "remove": "Отстрани", + "play": "Пушти", + "play_now": "Пушти сега", + "resume": "Продолжи", + "info": "Инфо", + "more_info": "Повеќе инфо", + "my_list": "Моја листа", + "save": "Зачувај", + "saved": "Зачувано", + "retry": "Обиди се повторно", + "install_addons": "Инсталирај додатоци", + "settings": "Поставки", + "no_featured_content": "Нема истакната содржина", + "couldnt_load_featured": "Не можеше да се вчита истакнатата содржина", + "no_featured_desc": "Инсталирајте додатоци со каталози или променете го изворот на содржина во поставките.", + "load_error_desc": "Настана проблем при преземање на истакнатата содржина. Проверете ја врската и обидете се повторно.", + "no_featured_available": "Нема достапна истакната содржина", + "no_description": "Нема достапен опис" + }, + "navigation": { + "home": "Почетна", + "library": "Библиотека", + "search": "Пребарај", + "downloads": "Преземања", + "settings": "Поставки" + }, + "search": { + "title": "Пребарај", + "recent_searches": "Неодамнешни пребарувања", + "discover": "Откриј", + "movies": "Филмови", + "tv_shows": "ТВ Емисии", + "select_catalog": "Избери каталог", + "all_genres": "Сите жанрови", + "discovering": "Откривање содржина...", + "show_more": "Прикажи повеќе ({{count}})", + "no_content_found": "Не е пронајдена содржина", + "try_different": "Обидете се со друг жанр или каталог", + "select_catalog_desc": "Изберете каталог за истражување", + "tap_catalog_desc": "Допрете на копчето за каталог погоре за да започнете", + "placeholder": "Пребарај филмови, серии...", + "keep_typing": "Продолжете со пишување...", + "type_characters": "Впишете барем 2 карактери за пребарување", + "no_results": "Нема резултати", + "try_keywords": "Обидете се со други клучни зборови или проверете го правописот", + "select_type": "Избери тип", + "browse_movies": "Прелистувај каталози со филмови", + "browse_tv": "Прелистувај каталози со ТВ серии", + "select_genre": "Избери жанр", + "show_all_content": "Прикажи ја целата содржина", + "genres_count": "{{count}} жанрови" + }, + "library": { + "title": "Библиотека", + "watched": "Гледано", + "continue": "Продолжи", + "watchlist": "Листа за гледање", + "collection": "Колекција", + "rated": "Оценето", + "items": "ставки", + "trakt_collections": "Trakt колекции", + "trakt_collection": "Trakt колекција", + "no_trakt": "Нема Trakt колекции", + "no_trakt_desc": "Вашите Trakt колекции ќе се појават тука откако ќе почнете да користите Trakt", + "load_collections": "Вчитај колекции", + "empty_folder": "Нема содржина во {{folder}}", + "empty_folder_desc": "Оваа колекција е празна", + "refresh": "Освежи", + "no_movies": "Сè уште нема филмови", + "no_series": "Сè уште нема ТВ серии", + "no_content": "Сè уште нема содржина", + "add_content_desc": "Додајте содржина во вашата библиотека за да ја видите тука", + "find_something": "Најди нешто за гледање", + "removed_from_library": "Отстрането од библиотека", + "item_removed": "Ставката е отстранета од вашата библиотека", + "failed_update_library": "Неуспешно ажурирање на библиотеката", + "unable_remove": "Не може да се отстрани ставката од библиотеката", + "marked_watched": "Означено како гледано", + "marked_unwatched": "Означено како негледано", + "item_marked_watched": "Ставката е означена како гледана", + "item_marked_unwatched": "Ставката е означена како негледана", + "failed_update_watched": "Неуспешно ажурирање на статусот на гледање", + "unable_update_watched": "Не може да се ажурира статусот на гледање", + "added_to_library": "Додадено во библиотека", + "item_added": "Додадено во вашата локална библиотека", + "add_to_library": "Додај во библиотека", + "remove_from_library": "Отстрани од библиотека", + "mark_watched": "Означи како гледано", + "mark_unwatched": "Означи како негледано", + "share": "Сподели", + "add_to_watchlist": "Додај во Trakt листа за гледање", + "remove_from_watchlist": "Отстрани од Trakt листа за гледање", + "added_to_watchlist": "Додадено во листа за гледање", + "added_to_watchlist_desc": "Додадено во вашата Trakt листа за гледање", + "removed_from_watchlist": "Отстрането од листа за гледање", + "removed_from_watchlist_desc": "Отстрането од вашата Trakt листа за гледање", + "add_to_collection": "Додај во Trakt колекција", + "remove_from_collection": "Отстрани од Trakt колекција", + "added_to_collection": "Додадено во колекција", + "added_to_collection_desc": "Додадено во вашата Trakt колекција", + "removed_from_collection": "Отстрането од колекција", + "removed_from_collection_desc": "Отстрането од вашата Trakt колекција" + }, + "metadata": { + "unable_to_load": "Не може да се вчита содржината", + "error_code": "Код на грешка: {{code}}", + "content_not_found": "Содржината не е пронајдена", + "content_not_found_desc": "Оваа содржина не постои или е можеби отстранета.", + "server_error": "Грешка на серверот", + "server_error_desc": "Серверот е привремено недостапен. Ве молиме обидете се подоцна.", + "bad_gateway": "Лош влез (Bad gateway)", + "bad_gateway_desc": "Серверот се соочува со проблеми. Ве молиме обидете се подоцна.", + "service_unavailable": "Услугата е недостапна", + "service_unavailable_desc": "Услугата е моментално во прекин поради одржување. Ве молиме обидете се подоцна.", + "too_many_requests": "Премногу барања", + "too_many_requests_desc": "Правите премногу барања. Почекајте малку и обидете се повторно.", + "request_timeout": "Барањето истече", + "request_timeout_desc": "Барањето траеше предолго. Ве молиме обидете се повторно.", + "network_error": "Мрежна грешка", + "network_error_desc": "Проверете ја интернет врската и обидете се повторно.", + "auth_error": "Грешка при автентикација", + "auth_error_desc": "Проверете ги поставките на вашата сметка и обидете се повторно.", + "access_denied": "Пристапот е одбиен", + "access_denied_desc": "Немате дозвола за пристап до оваа содржина.", + "connection_error": "Грешка во врската", + "streams_unavailable": "Стримовите се недостапни", + "streams_unavailable_desc": "Изворите за стриминг се моментално недостапни. Обидете се подоцна.", + "unknown_error": "Непозната грешка", + "something_went_wrong": "Нешто тргна наопаку. Ве молиме обидете се повторно.", + "cast": "Актерска екипа", + "more_like_this": "Слично на ова", + "collection": "Колекција", + "episodes": "Епизоди", + "seasons": "Сезони", + "posters": "Постери", + "banners": "Банери", + "specials": "Специјали", + "season_number": "Сезона {{number}}", + "episode_count": "{{count}} епизода", + "episode_count_plural": "{{count}} епизоди", + "no_episodes": "Нема достапни епизоди", + "no_episodes_for_season": "Нема достапни епизоди за Сезона {{season}}", + "episodes_not_released": "Епизодите можеби сè уште не се објавени", + "no_description": "Нема достапен опис", + "episode_label": "ЕПИЗОДА {{number}}", + "watch_again": "Гледај повторно", + "completed": "Завршено", + "play_episode": "Пушти С{{season}}Е{{episode}}", + "play": "Пушти", + "watched": "Гледано", + "watched_on_trakt": "Гледано на Trakt", + "synced_with_trakt": "Синхронизирано со Trakt", + "saved": "Зачувано", + "director": "Режисер", + "directors": "Режисери", + "creator": "Креатор", + "creators": "Креатори", + "production": "Продукција", + "network": "Мрежа", + "mark_watched": "Означи како гледано", + "mark_unwatched": "Означи како негледано", + "marking": "Означување...", + "removing": "Отстранување...", + "unmark_season": "Одозначи ја Сезона {{season}}", + "mark_season": "Означи ја Сезона {{season}}", + "resume": "Продолжи", + "spoiler_warning": "Предупредување за спојлери", + "spoiler_warning_desc": "Овој коментар содржи спојлери. Дали сте сигурни дека сакате да го откриете?", + "cancel": "Откажи", + "reveal_spoilers": "Откриј спојлери", + "movie_details": "Детали за филмот", + "show_details": "Детали за емисијата", + "tagline": "Слоган", + "status": "Статус", + "release_date": "Датум на објавување", + "runtime": "Времетраење", + "budget": "Буџет", + "revenue": "Заработка", + "origin_country": "Земја на потекло", + "original_language": "Оригинален јазик", + "first_air_date": "Прво емитување", + "last_air_date": "Последно емитување", + "total_episodes": "Вкупно епизоди", + "episode_runtime": "Времетраење на епизода", + "created_by": "Креирано од", + "backdrop_gallery": "Галерија на позадини", + "loading_episodes": "Се вчитуваат епизоди...", + "no_episodes_available": "Нема достапни епизоди", + "play_next": "Пушти С{{season}}Е{{episode}}", + "play_next_episode": "Пушти следна епизода", + "save": "Зачувај", + "percent_watched": "{{percent}}% изгледано", + "percent_watched_trakt": "{{percent}}% изгледано ({{traktPercent}}% на Trakt)", + "synced_with_trakt_progress": "Синхронизирано со Trakt", + "using_trakt_progress": "Се користи напредокот од Trakt", + "added_to_collection_hero": "Додадено во колекција", + "added_to_collection_desc_hero": "Додадено во вашата Trakt колекција", + "removed_from_collection_hero": "Отстрането од колекција", + "removed_from_collection_desc_hero": "Отстрането од вашата Trakt колекција", + "mark_as_watched": "Означи како гледано", + "mark_as_unwatched": "Означи како негледано" + }, + "cast": { + "biography": "Биографија", + "known_for": "Познат по", + "personal_info": "Лични информации", + "born_in": "Роден во {{place}}", + "filmography": "Филмографија", + "also_known_as": "Познат и како", + "no_info_available": "Нема достапни дополнителни информации", + "as_character": "како {{character}}", + "loading_details": "Се вчитуваат детали...", + "years_old": "{{age}} години", + "view_filmography": "Види филмографија", + "filter": "Филтер", + "sort_by": "Сортирај по", + "sort_popular": "Популарност", + "sort_latest": "Најново", + "sort_upcoming": "Идно", + "upcoming_badge": "ВО ПОДГОТОВКА", + "coming_soon": "Наскоро", + "filmography_count": "Филмографија • {{count}} наслови", + "loading_filmography": "Се вчитува филмографијата...", + "load_more_remaining": "Вчитај повеќе (преостанати {{count}})", + "alert_error_title": "Грешка", + "alert_error_message": "Не може да се вчита „{{title}}“. Обидете се подоцна.", + "alert_ok": "Во ред", + "no_upcoming": "Нема идно објавени дела за овој актер", + "no_content": "Нема достапна содржина за овој актер", + "no_movies": "Нема достапни филмови за овој актер", + "no_tv": "Нема достапни ТВ серии за овој актер" + }, + "comments": { + "title": "Trakt коментари", + "spoiler_warning": "⚠️ Овој коментар содржи спојлери. Допрете за откривање.", + "spoiler": "Спојлер", + "contains_spoilers": "Содржи спојлери", + "reveal": "Откриј", + "vip": "VIP", + "unavailable": "Коментарите се недостапни", + "no_comments": "Сè уште нема коментари на Trakt", + "not_in_database": "Оваа содржина можеби сè уште не е во базата на Trakt", + "check_trakt": "Провери на Trakt" + }, + "trailers": { + "title": "Трејлери", + "official_trailers": "Официјални трејлери", + "official_trailer": "Официјален трејлер", + "teasers": "Тизери", + "teaser": "Тизер", + "clips_scenes": "Клипови и сцени", + "clip": "Клип", + "featurettes": "Кратки документарци", + "featurette": "Краток документарец", + "behind_the_scenes": "Зад сцената", + "no_trailers": "Нема достапни трејлери", + "unavailable": "Трејлерот е недостапен", + "unavailable_desc": "Овој трејлер не може да се вчита моментално. Ве молиме обидете се подоцна.", + "unable_to_play": "Не може да се пушти трејлерот. Обидете се повторно.", + "watch_on_youtube": "Гледај на YouTube" + }, + "catalog": { + "no_content_found": "Не е пронајдена содржина", + "no_content_filters": "Нема содржина за избраните филтри", + "loading_content": "Се вчитува содржина...", + "back": "Назад", + "in_theaters": "Во кината", + "all": "Сите", + "failed_tmdb": "Неуспешно вчитување на содржина од TMDB", + "movies": "Филмови", + "tv_shows": "ТВ Емисии", + "channels": "Канали" + }, + "streams": { + "back_to_episodes": "Назад кон епизоди", + "back_to_info": "Назад кон инфо", + "fetching_from": "Преземање од:", + "no_sources_available": "Нема достапни извори за стриминг", + "add_sources_desc": "Додајте извори за стриминг во поставките", + "add_sources": "Додај извори", + "finding_streams": "Пронаоѓање достапни стримови...", + "finding_best_stream": "Пронаоѓање на најдобар стрим за автоматско пуштање...", + "still_fetching": "Сè уште се преземаат стримови...", + "no_streams_available": "Нема достапни стримови", + "starting_best_stream": "Стартување на најдобриот стрим...", + "loading_more_sources": "Се вчитуваат повеќе извори..." + }, + "player_ui": { + "via": "преку {{name}}", + "audio_tracks": "Аудио записи", + "no_audio_tracks": "Нема достапни аудио записи", + "playback_speed": "Брзина на репродукција", + "on_hold": "На чекање", + "playback_error": "Грешка при репродукција", + "unknown_error": "Настана непозната грешка при репродукцијата.", + "copy_error": "Копирај детали за грешката", + "copied_to_clipboard": "Копирано во меморија", + "dismiss": "Отфрли", + "continue_watching": "Продолжи со гледање", + "start_over": "Почни од почеток", + "resume": "Продолжи", + "change_source": "Промени извор", + "switching_source": "Префрлање на извор...", + "no_sources_found": "Не се пронајдени извори", + "sources": "Извори", + "finding_sources": "Пронаоѓање извори...", + "unknown_source": "Непознат извор", + "sources_limited": "Изворите може да бидат ограничени поради грешки кај провајдерот.", + "episodes": "Епизоди", + "specials": "Специјали", + "season": "Сезона {{season}}", + "stream": "Стрим {{number}}", + "subtitles": "Превод", + "built_in": "Вградено", + "addons": "Додатоци", + "style": "Стил", + "none": "Ништо", + "search_online_subtitles": "Пребарај преводи онлајн", + "preview": "Преглед", + "quick_presets": "Брзи поставки", + "default": "Стандардно", + "yellow": "Жолто", + "high_contrast": "Висок контраст", + "large": "Големо", + "core": "Основно", + "font_size": "Големина на фонт", + "show_background": "Прикажи позадина", + "advanced": "Напредно", + "position": "Позиција", + "text_color": "Боја на текст", + "align": "Порамнување", + "bottom_offset": "Оддалеченост од дното", + "background_opacity": "Проѕирност на позадина", + "text_shadow": "Сенка на текст", + "on": "Вклучено", + "off": "Исклучено", + "outline_color": "Боја на контура", + "outline": "Контура", + "outline_width": "Ширина на контура", + "letter_spacing": "Проред помеѓу букви", + "line_height": "Висина на ред", + "timing_offset": "Временско отстапување (с)", + "visual_sync": "Визуелна синхронизација", + "timing_hint": "Поместете го преводот порано (-) или подоцна (+) за синхронизација.", + "reset_defaults": "Врати на стандардно", + "mark_intro_start": "Означи почеток на увод", + "mark_intro_end": "Означи крај на увод", + "intro_start_marked": "Почетокот на уводот е означен", + "intro_submitted": "Уводот е успешно испратен", + "intro_submit_failed": "Неуспешно испраќање на увод" + }, + "downloads": { + "title": "Преземања", + "no_downloads": "Сè уште нема преземања", + "no_downloads_desc": "Преземената содржина ќе се појави тука за гледање офлајн", + "explore": "Истражи содржина", + "path_copied": "Патеката е копирана", + "path_copied_desc": "Локалната патека до датотеката е копирана", + "copied": "Копирано", + "incomplete": "Преземањето е нецелосно", + "incomplete_desc": "Преземањето сè уште не е завршено", + "not_available": "Не е достапно", + "not_available_desc": "Локалната патека е достапна само откако преземањето ќе заврши.", + "status_downloading": "Се презема", + "status_completed": "Завршено", + "status_paused": "Паузирано", + "status_error": "Грешка", + "status_queued": "Во ред за чекање", + "status_unknown": "Непознато", + "provider": "Провајдер", + "streaming_playlist_warning": "Може да не се репродуцира - стриминг листа", + "remaining": "преостануваат", + "not_ready": "Преземањето не е подготвено", + "not_ready_desc": "Ве молиме почекајте додека преземањето не заврши.", + "filter_all": "Сите", + "filter_active": "Активни", + "filter_done": "Завршени", + "filter_paused": "Паузирани", + "no_filter_results": "Нема {{filter}} преземања", + "try_different_filter": "Обидете се со друг филтер", + "limitations_title": "Ограничувања при преземање", + "limitations_msg": "• Датотеките помали од 1MB се обично M3U8 листи и не можат да се преземат за гледање офлајн. Тие работат само онлајн.", + "remove_title": "Отстрани преземање", + "remove_confirm": "Да се отстрани „{{title}}“{{season_episode}}?", + "cancel": "Откажи", + "remove": "Отстрани" + }, + "addons": { + "title": "Додатоци", + "reorder_mode": "Режим за преуредување", + "reorder_info": "Додатоците на врвот имаат приоритет при вчитување содржина", + "add_addon_placeholder": "URL на додаток", + "add_button": "Додај додаток", + "my_addons": "Мои додатоци", + "community_addons": "Додатоци од заедницата", + "no_addons": "Нема инсталирани додатоци", + "uninstall_title": "Деинсталирај додаток", + "uninstall_message": "Дали сте сигурни дека сакате да го деинсталирате {{name}}?", + "uninstall_button": "Деинсталирај", + "install_success": "Додатокот е успешно инсталиран", + "install_error": "Неуспешна инсталација на додаток", + "load_error": "Неуспешно вчитување на додатоци", + "fetch_error": "Неуспешно преземање детали за додатокот", + "invalid_url": "Внесете важечки URL на додатокот", + "configure": "Конфигурирај", + "version": "Верзија: {{version}}", + "installed_addons": "ИНСТАЛИРАНИ ДОДАТОЦИ", + "reorder_drag_title": "ВЛЕЧЕТЕ ЗА ПРЕУРЕДУВАЊЕ", + "install": "Инсталирај", + "config_unavailable_title": "Конфигурацијата е недостапна", + "config_unavailable_msg": "Не може да се одреди URL-то за конфигурација на овој додаток.", + "cannot_open_config_title": "Не може да се отвори конфигурацијата", + "cannot_open_config_msg": "URL-то за конфигурација ({{url}}) не може да се отвори.", + "description": "Опис", + "supported_types": "Поддржани типови", + "catalogs": "Каталози", + "no_description": "Нема достапен опис", + "overview": "ПРЕГЛЕД", + "no_categories": "Нема категории", + "pre_installed": "ПРЕТХОДНО ИНСТАЛИРАНО" + }, + "trakt": { + "title": "Trakt поставки", + "settings_title": "Trakt поставки", + "connect_title": "Поврзи се со Trakt", + "connect_desc": "Синхронизирајте ја историјата на гледање, листата и колекцијата со Trakt.tv", + "sign_in": "Најави се со Trakt", + "sign_out": "Одјави се", + "sign_out_confirm": "Дали сте сигурни дека сакате да се одјавите од Trakt?", + "joined": "Се придружи на {{date}}", + "sync_settings_title": "Поставки за синхронизација", + "sync_info": "Кога сте поврзани со Trakt, целата историја се синхронизира директно од API-то.", + "auto_sync_label": "Автоматска синхронизација", + "auto_sync_desc": "Автоматски синхронизирај го напредокот со Trakt", + "import_history_label": "Увези историја на гледање", + "import_history_desc": "Користи „Синхронизирај сега“ за увоз на историјата од Trakt", + "sync_now_button": "Синхронизирај сега", + "display_settings_title": "Поставки за приказ", + "show_comments_label": "Прикажи Trakt коментари", + "show_comments_desc": "Прикажувај коментари во екранот со детали кога се достапни", + "maintenance_title": "Во фаза на одржување", + "maintenance_unavailable": "Trakt е недостапен", + "maintenance_desc": "Интеграцијата со Trakt е привремено во прекин поради одржување.", + "maintenance_button": "Сервисот е под одржување", + "auth_success_title": "Успешно поврзување", + "auth_success_msg": "Вашата Trakt сметка е успешно поврзана.", + "auth_error_title": "Грешка при автентикација", + "auth_error_msg": "Неуспешна автентикација со Trakt.", + "auth_error_generic": "Настана грешка при автентикацијата.", + "sign_out_error": "Неуспешна одјава од Trakt.", + "sync_complete_title": "Синхронизацијата е завршена", + "sync_success_msg": "Успешно синхронизиран напредок со Trakt.", + "sync_error_msg": "Синхронизацијата не успеа. Обидете се повторно." + }, + "simkl": { + "title": "Simkl поставки", + "settings_title": "Simkl поставки", + "connect_title": "Поврзи се со Simkl", + "connect_desc": "Синхронизирајте ја историјата и следете што гледате", + "sign_in": "Најави се со Simkl", + "sign_out": "Исклучи се", + "sign_out_confirm": "Дали сте сигурни дека сакате да се исклучите од Simkl?", + "syncing_desc": "Вашите изгледани ставки се синхронизираат со Simkl.", + "auth_success_title": "Успешно поврзување", + "auth_success_msg": "Вашата Simkl сметка е успешно поврзана.", + "auth_error_title": "Грешка при автентикација", + "auth_error_msg": "Неуспешна автентикација со Simkl.", + "auth_error_generic": "Настана грешка при автентикацијата.", + "sign_out_error": "Неуспешно исклучување од Simkl.", + "config_error_title": "Грешка во конфигурација", + "config_error_msg": "Simkl Client ID недостига во системските променливи.", + "conflict_title": "Конфликт", + "conflict_msg": "Не можете да се поврзете со Simkl додека Trakt е поврзан.", + "disclaimer": "Nuvio не е поврзан со Simkl." + }, + "tmdb_settings": { + "title": "TMDb поставки", + "metadata_enrichment": "Збогатување на метаподатоци", + "metadata_enrichment_desc": "Подобрете ги метаподатоците со податоци од TMDb за повеќе детали.", + "enable_enrichment": "Овозможи збогатување", + "enable_enrichment_desc": "Ги надополнува метаподатоците со актери, сертификати, лога и постери.", + "localized_text": "Локализиран текст", + "localized_text_desc": "Преземај наслови и описи на вашиот претпочитан јазик од TMDb.", + "language": "Јазик", + "change": "Промени", + "logo_preview": "Преглед на лого", + "logo_preview_desc": "Преглед како ќе изгледаат локализираните лога.", + "example": "Пример:", + "no_logo": "Нема достапно лого", + "enrichment_options": "Опции за збогатување", + "enrichment_options_desc": "Контролирајте кои податоци се преземаат од TMDb.", + "cast_crew": "Актери и екипа", + "cast_crew_desc": "Актери, режисери, сценаристи со фотографии", + "title_description": "Наслов и опис", + "title_description_desc": "Користи локализиран наслов и опис од TMDb", + "title_logos": "Лога на наслови", + "title_logos_desc": "Висококвалитетни слики за насловите", + "banners_backdrops": "Банери и позадини", + "banners_backdrops_desc": "Слики со висока резолуција за позадина", + "certification": "Сертификација на содржина", + "certification_desc": "Рјтинзи за возраст (PG-13, R, итн.)", + "recommendations": "Препораки", + "recommendations_desc": "Предлози за слична содржина", + "episode_data": "Податоци за епизоди", + "episode_data_desc": "Слики, информации и резервни податоци за епизоди", + "season_posters": "Постери за сезони", + "season_posters_desc": "Специфични постери за секоја сезона", + "production_info": "Информации за продукција", + "production_info_desc": "Мрежи и продукции со нивни лога", + "movie_details": "Детали за филм", + "movie_details_desc": "Буџет, заработка, времетраење", + "tv_details": "Детали за ТВ емисија", + "tv_details_desc": "Статус, број на сезони, креатори", + "movie_collections": "Филмски колекции", + "movie_collections_desc": "Филмски франшизи (Marvel, Star Wars, итн.)", + "api_configuration": "API конфигурација", + "api_configuration_desc": "Конфигурирајте го вашиот TMDb API пристап.", + "custom_api_key": "Сопствен API клуч", + "custom_api_key_desc": "Користете сопствен клуч за подобри перформанси.", + "custom_key_active": "Сопствениот API клуч е активен", + "api_key_required": "Потребен е API клуч", + "api_key_placeholder": "Залепете го вашиот TMDb API клуч (v3)", + "how_to_get_key": "Како да добијам TMDb API клуч?", + "built_in_key_msg": "Моментално се користи вградениот API клуч.", + "cache_size": "Големина на кеш", + "clear_cache": "Исчисти кеш", + "cache_days": "Одговорите од TMDB се чуваат 7 дена", + "choose_language": "Избери јазик", + "choose_language_desc": "Изберете јазик за TMDb содржината", + "popular": "Популарно", + "all_languages": "Сите јазици", + "search_results": "Резултати од пребарување", + "no_languages_found": "Не се пронајдени јазици за „{{query}}“", + "clear_search": "Исчисти пребарување", + "clear_cache_title": "Исчисти TMDB кеш", + "clear_cache_msg": "Ова ќе ги избрише сите зачувани податоци од TMDB ({{size}}).", + "clear_cache_success": "TMDB кешот е успешно исчистен.", + "clear_cache_error": "Неуспешно чистење на кешот.", + "clear_api_key_title": "Избриши API клуч", + "clear_api_key_msg": "Дали сте сигурни дека сакате да го отстраните сопствениот API клуч?", + "clear_api_key_success": "API клучот е успешно избришан", + "clear_api_key_error": "Неуспешно бришење на API клучот", + "empty_api_key": "API клучот не може да биде празен.", + "invalid_api_key": "Неважечки API клуч. Проверете и обидете се повторно.", + "save_error": "Настана грешка при зачувување.", + "using_builtin_key": "Сега се користи вградениот TMDb API клуч.", + "using_custom_key": "Сега се користи вашиот сопствен TMDb API клуч.", + "enter_custom_key": "Внесете и зачувајте сопствен TMDb API клуч.", + "key_verified": "API клучот е верификуван и успешно зачуван." + }, + "settings": { + "language": "Јазик", + "select_language": "Избери јазик", + "english": "Англиски", + "portuguese": "Португалски", + "portuguese_br": "Португалски (Бразил)", + "portuguese_pt": "Португалски (Португалија)", + "german": "Германски", + "arabic": "Арапски", + "spanish": "Шпански", + "french": "Француски", + "italian": "Италијански", + "croatian": "Хрватски", + "chinese": "Кинески (поедноставен)", + "hindi": "Хинди", + "serbian": "Српски", + "hebrew": "Хебрејски", + "bulgarian": "Бугарски", + "polish": "Полски", + "czech": "Чешки", + "turkish": "Турски", + "slovenian": "Словенечки", + "macedonian": "Македонски", + "russian": "Руски", + "filipino": "Филипински", + "dutch_nl": "Холандски (Холандија)", + "romanian": "Романски", + "albanian": "Албански", + "account": "Сметка", + "content_discovery": "Содржина и откривање", + "appearance": "Изглед", + "integrations": "Интеграции", + "playback": "Репродукција", + "backup_restore": "Резервна копија и враќање", + "updates": "Ажурирања", + "about": "За апликацијата", + "developer": "Програмер", + "cache": "Кеш", + "title": "Поставки", + "settings_title": "Поставки", + "sign_in_sync": "Најави се за синхронизација", + "add_catalogs_sources": "Додатоци, каталози и извори", + "player_trailers_downloads": "Плеер, трејлери, преземања", + "mdblist_tmdb_ai": "MDBList, TMDB, AI", + "check_updates": "Провери за ажурирања", + "clear_mdblist_cache": "Исчисти MDBList кеш", + "cache_management": "УПРАВУВАЊЕ СО КЕШ", + "downloads_counter": "преземања и продолжува", + "made_with_love": "Направено со ❤️ од Tapframe и пријателите", + "sections": { + "information": "ИНФОРМАЦИИ", + "account": "СМЕТКА", + "theme": "ТЕМА", + "layout": "РАСПОРЕД", + "sources": "ИЗВОРИ", + "catalogs": "КАТАЛОЗИ", + "discovery": "ОТКРИВАЊЕ", + "metadata": "МЕТАПОДАТОЦИ", + "ai_assistant": "AI АСИСТЕНТ", + "video_player": "ВИДЕО ПЛЕЕР", + "audio_subtitles": "АУДИО И ПРЕВОД", + "media": "МЕДИУМИ", + "notifications": "ИЗВЕСТУВАЊА", + "testing": "ТЕСТИРАЊЕ", + "danger_zone": "ОПАСНА ЗОНА" + }, + "items": { + "legal": "Правни информации и одрекување", + "privacy_policy": "Политика за приватност", + "report_issue": "Пријави проблем", + "version": "Верзија", + "contributors": "Соработници", + "view_contributors": "Види ги сите соработници", + "theme": "Тема", + "episode_layout": "Распоред на епизоди", + "streams_backdrop": "Позадина за стримови", + "streams_backdrop_desc": "Прикажи заматена позадина кај стримовите на мобилен", + "addons": "Додатоци", + "installed": "инсталирано", + "debrid_integration": "Debrid интеграција", + "debrid_desc": "Поврзи Torbox", + "plugins": "Приклучоци", + "plugins_desc": "Управувај со приклучоци и складишта", + "catalogs": "Каталози", + "active": "активно", + "home_screen": "Почетен екран", + "home_screen_desc": "Распоред и содржина", + "continue_watching": "Продолжи со гледање", + "continue_watching_desc": "Кеш и однесување при репродукција", + "show_discover": "Прикажи секција „Откриј“", + "show_discover_desc": "Прикажи содржини за откривање во Пребарување", + "mdblist": "MDBList", + "mdblist_connected": "Поврзано", + "mdblist_desc": "Овозможи за додавање рејтинзи и рецензии", + "simkl": "Simkl", + "simkl_connected": "Поврзано", + "simkl_desc": "Следете го она што го гледате", + "tmdb": "TMDB", + "tmdb_desc": "Извор на метаподатоци и лога", + "openrouter": "OpenRouter API", + "openrouter_connected": "Поврзано", + "openrouter_desc": "Додајте API клуч за AI разговор", + "video_player": "Видео плеер", + "built_in": "Вграден", + "external": "Надворешен", + "preferred_audio": "Претпочитан јазик на аудио", + "preferred_subtitle": "Претпочитан јазик на превод", + "subtitle_source": "Приоритет на извор за превод", + "auto_select_subs": "Автоматски избор на превод", + "auto_select_subs_desc": "Автоматски избери превод според вашите претпочитања", + "show_trailers": "Прикажи трејлери", + "show_trailers_desc": "Прикажувај трејлери во истакнатата секција", + "enable_downloads": "Овозможи преземања", + "enable_downloads_desc": "Прикажи го табот за преземања и овозможи снимање стримови", + "notifications": "Известувања", + "notifications_desc": "Потсетници за епизоди", + "developer_tools": "Алатки за програмери", + "developer_tools_desc": "Опции за тестирање и дебагирање", + "test_onboarding": "Тестирај воведно упатство", + "reset_onboarding": "Ресетирај воведно упатство", + "test_announcement": "Тестирај соопштение", + "test_announcement_desc": "Прикажи го преклопот за новини", + "reset_campaigns": "Ресетирај кампањи", + "reset_campaigns_desc": "Исчисти ги импресиите од кампањите", + "clear_all_data": "Избриши ги сите податоци", + "clear_all_data_desc": "Ресетирај ги сите поставки и кеширани податоци" + }, + "options": { + "horizontal": "Хоризонтално", + "vertical": "Вертикално", + "internal_first": "Прво внатрешни", + "internal_first_desc": "Претпочитај вградени преводи, па надворешни", + "external_first": "Прво надворешни", + "external_first_desc": "Претпочитај преводи од додатоци, па вградени", + "any_available": "Било кој достапен", + "any_available_desc": "Користи го првиот достапен превод" + }, + "clear_data_desc": "Ова ќе ги ресетира сите поставки и ќе ги избрише сите кеширани податоци. Дали сте сигурни?", + "app_updates": "Ажурирања на апликацијата", + "about_nuvio": "За Nuvio", + "privacy": { + "title": "Приватност и податоци", + "settings_desc": "Контролирајте ја телеметријата и прибирањето податоци", + "info_title": "Вашата приватност е важна", + "info_description": "Контролирајте кои податоци се собираат и споделуваат. Аналитиката е стандардно исклучена, а извештаите за падови се анонимни.", + "analytics_enabled_title": "Аналитиката е овозможена", + "analytics_enabled_message": "Податоците за користење ќе бидат собирани за подобрување на апликацијата. Можете да го исклучите ова во секое време.", + "disable_error_reporting_title": "Исклучи известување за грешки?", + "disable_error_reporting_message": "Со исклучување на оваа опција, нема да бидеме известени за падови или проблеми со кои се соочувате. Ова може да ја ограничи нашата способност да ги поправиме баговите.", + "enable_session_replay_title": "Овозможи снимање сесија?", + "enable_session_replay_message": "Снимањето сесија го снима вашиот екран кога ќе се појават грешки за да ни помогне да разбереме што се случило. Ова може да ја сними видливата содржина на вашиот екран.", + "enable_pii_title": "Овозможи собирање лични податоци (PII)?", + "enable_pii_message": "Ова овозможува собирање на информации како IP адреса и детали за уредот. Овие податоци помагаат во дијагностицирање на проблеми, но ја зголемуваат изложеноста на приватноста.", + "disable_all_title": "Исклучи ја целата телеметрија?", + "disable_all_message": "Ова ќе ги оневозможи сите аналитики, известувања за грешки и снимање сесии. Нема да добиваме никакви податоци за користењето на апликацијата.", + "disable_all_button": "Исклучи сè", + "all_disabled_title": "Целата телеметрија е исклучена", + "all_disabled_message": "Прибирањето податоци е исклучено. Промените ќе стапат на сила при следното стартување на апликацијата.", + "reset_title": "Врати на препорачано", + "reset_message": "Поставките за приватност се вратени на препорачаните вредности (известување за грешки вклучено, аналитика исклучена).", + "section_analytics": "АНАЛИТИКА", + "analytics_title": "Аналитика на користење", + "analytics_description": "Собирај анонимни шеми на користење и прегледи на екрани", + "section_error_reporting": "ИЗВЕСТУВАЊЕ ЗА ГРЕШКИ", + "error_reporting_title": "Извештаи за падови", + "error_reporting_description": "Испраќај анонимни извештаи за падови за подобра стабилност", + "session_replay_title": "Снимање сесија", + "session_replay_description": "Сними го екранот кога ќе се појават грешки", + "pii_title": "Вклучи информации за уредот", + "pii_description": "Испраќај IP адреса и детали за уредот со извештаите", + "section_quick_actions": "БРЗИ АКЦИИ", + "disable_all": "Исклучи ја целата телеметрија", + "disable_all_desc": "Исклучи го целото прибирање податоци", + "reset_recommended": "Врати на препорачано", + "reset_recommended_desc": "Поставки со фокус на приватност и известување за грешки", + "section_learn_more": "ДОЗНАЈ ПОВЕЌЕ", + "current_settings": "Преглед на моменталните поставки", + "summary_analytics": "Аналитика", + "summary_errors": "Извештаи за грешки", + "summary_replay": "Снимање сесија", + "summary_pii": "Инфо за уред", + "restart_note_detailed": "* Промените за аналитика и грешки стапуваат на сила веднаш. Снимањето сесија и PII бараат рестартирање на апликацијата." + }, + "ai_settings": { + "title": "AI Асистент", + "info_title": "AI Разговор", + "info_desc": "Поставувајте прашања за било кој филм или епизода користејќи напредна вештачка интелигенција. Добијте информации за дејството, ликовите, темите и интересни факти - сè базирано на TMDB податоци.", + "feature_1": "Контекст и анализа специфични за епизодата", + "feature_2": "Објаснувања на дејството и увид во ликовите", + "feature_3": "Интересни факти зад сцената", + "feature_4": "Ваш сопствен бесплатен OpenRouter API клуч", + "api_key_section": "OPENROUTER API КЛУЧ", + "api_key_label": "API Клуч", + "api_key_desc": "Внесете го вашиот OpenRouter API клуч за овозможување на AI опциите", + "save_api_key": "Зачувај API клуч", + "saving": "Се зачувува...", + "update": "Ажурирај", + "remove": "Отстрани", + "get_free_key": "Земи бесплатен API клуч од OpenRouter", + "enable_chat": "Овозможи AI разговор", + "enable_chat_desc": "Кога е овозможено, копчето „Прашај AI“ ќе се појави на страниците со содржина.", + "chat_enabled": "AI разговорот е овозможен", + "chat_enabled_desc": "Сега можете да поставувате прашања. Побарајте го копчето „Прашај AI“!", + "how_it_works": "Како функционира", + "how_it_works_desc": "• OpenRouter нуди пристап до повеќе AI модели\n• Вашиот API клуч останува приватен и безбеден\n• Бесплатниот план вклучува дарежливи лимити за користење\n• Разговарајте со контекст за конкретни епизоди/филмови\n• Добијте детални анализи и објаснувања", + "error_invalid_key": "Ве молиме внесете важечки API клуч", + "error_key_format": "OpenRouter API клучевите треба да започнуваат со „sk-or-“", + "success_saved": "API клучот е успешно зачуван!", + "error_save": "Неуспешно зачувување на API клучот", + "confirm_remove_title": "Отстрани API клуч", + "confirm_remove_msg": "Дали сте сигурни дека сакате да го отстраните клучот? Ова ќе го оневозможи AI асистентот.", + "success_removed": "API клучот е успешно отстранет", + "error_remove": "Неуспешно отстранување на API клучот" + }, + "catalog_settings": { + "title": "Каталози", + "layout_phone": "РАСПОРЕД НА КАТАЛОГ (ТЕЛЕФОН)", + "posters_per_row": "Постери во ред", + "auto": "Автоматски", + "show_titles": "Прикажи наслови на постери", + "show_titles_desc": "Прикажи го насловот под секој постер", + "phone_only_hint": "Важи само за телефони. Таблетите го задржуваат адаптивниот распоред.", + "catalogs_group": "Каталози", + "enabled_count": "{{enabled}} од {{total}} овозможени", + "rename_hint": "Држете долго на каталог за да го преименувате", + "rename_modal_title": "Преименувај каталог", + "rename_placeholder": "Внесете ново име на каталогот", + "error_save_name": "Името не можеше да се зачува." + }, + "continue_watching_settings": { + "title": "Продолжи со гледање", + "playback_behavior": "ОДНЕСУВАЊЕ ПРИ РЕПРОДУКЦИЈА", + "use_cached": "Користи кеширани стримови", + "use_cached_desc": "Кога е овозможено, кликнувањето на ставките ќе го отвори плеерот директно со претходните стримови. Кога е исклучено, отвора екран со содржина.", + "open_metadata": "Отвори екран со детали", + "open_metadata_desc": "Кога кешираните стримови се исклучени, отвори го екранот со детали наместо екранот со стримови.", + "card_appearance": "ИЗГЛЕД НА КАРТИЧКА", + "card_style": "Стил на картичка", + "card_style_desc": "Изберете како ќе изгледаат ставките на почетниот екран", + "wide": "Широко", + "poster": "Постер", + "cache_settings": "ПОСТАВКИ ЗА КЕШ", + "cache_duration": "Времетраење на кешот за стримови", + "cache_duration_desc": "Колку долго да се чуваат линковите пред да истечат", + "important_note": "Важна напомена", + "important_note_text": "Не сите стримови остануваат активни до крајот на кешот. Подолго време може да доведе до нефункционални линкови.", + "how_it_works_cached": "• Стримовите се кешираат по гледањето\n• Кешот се проверува пред употреба\n• Ако кешот е неважечки, се отвора екранот со содржина\n• „Користи кеширани стримови“ контролира директна навигација", + "how_it_works_uncached": "• Кога кешот е исклучен, се отвораат екрани со содржина\n• Опцијата за детали контролира кој екран ќе се отвори\n• Екранот со детали овозможува рачен избор на стрим", + "changes_saved": "Промените се зачувани", + "min": "мин", + "hour": "час", + "hours": "часови" + }, + "contributors": { + "title": "Соработници", + "special_mentions": "Посебни признанија", + "tab_contributors": "Соработници", + "tab_special": "Специјално", + "tab_donors": "Донатори", + "manager_role": "Менаџер на заедница", + "manager_desc": "Управува со Discord и Reddit заедниците за Nuvio", + "sponsor_role": "Спонзор на сервер", + "sponsor_desc": "Ја спонзорираше серверската инфраструктура за Nuvio", + "mod_role": "Discord Модератор", + "mod_desc": "Помага во модерирање на Nuvio Discord заедницата", + "loading": "Се вчитува...", + "discord_user": "Discord Корисник", + "contributions": "придонеси", + "gratitude_title": "Благодарни сме за секој придонес", + "gratitude_desc": "Секоја линија код и предлог помага Nuvio да биде подобар за сите", + "special_thanks_title": "Посебна благодарност", + "special_thanks_desc": "Овие луѓе помагаат заедницата да опстои и серверите да бидат онлајн", + "donors_desc": "Ви благодариме што верувате во нас. Вашата поддршка го одржува Nuvio бесплатен.", + "latest_donations": "Најнови", + "leaderboard": "Ранг листа", + "loading_donors": "Се вчитуваат донатори...", + "no_donors": "Сè уште нема донатори", + "error_rate_limit": "Лимитот на GitHub API е надминат. Обидете се подоцна.", + "error_failed": "Неуспешно вчитување на соработници. Проверете ја врската.", + "retry": "Обиди се повторно", + "no_contributors": "Не се пронајдени соработници", + "loading_contributors": "Се вчитуваат соработници..." + }, + "debrid": { + "title": "Debrid интеграција", + "description_torbox": "Отклучете 4K квалитет и големи брзини со Torbox. Внесете го вашиот API клуч за премиум искуство.", + "description_torrentio": "Конфигурирајте Torrentio за торент стримови. Потребен е debrid сервис за гледање.", + "tab_torbox": "TorBox", + "tab_torrentio": "Torrentio", + "status_connected": "Поврзано", + "status_disconnected": "Исклучено", + "enable_addon": "Овозможи додаток", + "disconnect_button": "Исклучи и отстрани", + "disconnect_loading": "Се исклучува...", + "account_info": "Информации за сметка", + "plan": "План", + "plan_free": "Бесплатен", + "plan_essential": "Essential ($3/мес)", + "plan_pro": "Pro ($10/мес)", + "plan_standard": "Standard ($5/мес)", + "plan_unknown": "Непознато", + "expires": "Истекува", + "downloaded": "Преземено", + "status_active": "Активно", + "connected_title": "✓ Поврзано со TorBox", + "connected_desc": "Вашиот TorBox додаток е активен.", + "configure_title": "Конфигурирај додаток", + "configure_desc": "Прилагодете го стримингот: сортирајте по квалитет, филтрирајте големини на фајлови.", + "open_settings": "Отвори поставки", + "what_is_debrid": "Што е Debrid сервис?", + "enter_api_key": "Внесете го вашиот API клуч", + "connect_button": "Поврзи и инсталирај", + "connecting": "Се поврзува...", + "unlock_speeds_title": "Отклучете премиум брзини", + "unlock_speeds_desc": "Земете Torbox претплата за пристап до кеширани стримови без баферирање.", + "get_subscription": "Земи претплата", + "powered_by": "Овозможено од", + "disclaimer_torbox": "Nuvio не е поврзан со Torbox на никаков начин.", + "disclaimer_torrentio": "Nuvio не е поврзан со Torrentio на никаков начин.", + "installed_badge": "✓ ИНСТАЛИРАНО", + "promo_title": "⚡ Ви треба Debrid сервис?", + "promo_desc": "Земете TorBox за молскавично брз 4K стриминг.", + "promo_button": "Земи TorBox претплата", + "service_label": "Debrid сервис *", + "api_key_label": "API Клуч *", + "sorting_label": "Сортирање", + "exclude_qualities": "Исклучи квалитети", + "priority_languages": "Приоритетни јазици", + "max_results": "Макс. резултати", + "additional_options": "Дополнителни опции", + "no_download_links": "Не прикажувај линкови за преземање", + "no_debrid_catalog": "Не прикажувај debrid каталог", + "install_button": "Инсталирај Torrentio", + "installing": "Се инсталира...", + "update_button": "Ажурирај конфигурација", + "updating": "Се ажурира...", + "remove_button": "Отстрани Torrentio", + "error_api_required": "Потребен е API клуч", + "error_api_required_desc": "Внесете го клучот за да инсталирате Torrentio.", + "success_installed": "Torrentio е успешно инсталиран!", + "success_removed": "Torrentio е успешно отстранет", + "alert_disconnect_title": "Исклучи Torbox", + "alert_disconnect_msg": "Дали сте сигурни? Ова ќе го избрише клучот и додатокот." + }, + "home_screen": { + "title": "Поставки за почетен екран", + "changes_applied": "Промените се применети", + "display_options": "ОПЦИИ ЗА ПРИКАЗ", + "show_hero": "Прикажи истакната секција", + "show_hero_desc": "Најпопуларна содржина најгоре", + "show_this_week": "Прикажи „Оваа недела“", + "show_this_week_desc": "Нови епизоди од тековната недела", + "select_catalogs": "Избери каталози", + "all_catalogs": "Сите каталози", + "selected": "избрано", + "hero_layout": "Распоред на истакнато", + "layout_legacy": "Класично", + "layout_carousel": "Вртелешка", + "layout_appletv": "Apple TV", + "layout_desc": "Банер во полна ширина, картички за лизгање или Apple TV стил", + "featured_source": "Извор на истакнато", + "using_catalogs": "Се користат каталози", + "manage_selected_catalogs": "Управувај со избрани каталози", + "dynamic_bg": "Динамична позадина", + "dynamic_bg_desc": "Заматен банер зад вртелешката", + "performance_note": "Може да влијае на перформансите кај послаби уреди.", + "posters": "Постери", + "show_titles": "Прикажи наслови", + "poster_size": "Големина на постер", + "poster_corners": "Агли на постерот", + "size_small": "Мал", + "size_medium": "Среден", + "size_large": "Голем", + "corners_square": "Квадратни", + "corners_rounded": "Заоблени", + "corners_pill": "Елипсовидни", + "about_these_settings": "ЗА ОВИЕ ПОСТАВКИ", + "about_desc": "Контролирајте го приказот на Почетната страна. Промените се применуваат веднаш.", + "hero_catalogs": { + "title": "Каталози за истакната секција", + "select_all": "Избери сите", + "clear_all": "Исчисти сите", + "info": "Изберете кои каталози да се појавуваат најгоре. Ако не изберете ништо, ќе се користат сите.", + "settings_saved": "Поставките се зачувани", + "error_load": "Грешка при вчитување", + "movies": "Филмови", + "tv_shows": "ТВ Емисии" + } + }, + "calendar": { + "title": "Календар", + "loading": "Се вчитува календар...", + "no_scheduled_episodes": "Нема закажани епизоди", + "check_back_later": "Проверете подоцна", + "showing_episodes_for": "Епизоди за {{date}}", + "show_all_episodes": "Прикажи ги сите епизоди", + "no_episodes_for": "Нема епизоди за {{date}}", + "no_upcoming_found": "Нема нови епизоди во најава", + "add_series_desc": "Додајте серии во библиотеката за да ги видите нивните нови епизоди тука" + }, + "mdblist": { + "title": "Извори на рејтинзи", + "status_disabled": "MDBList е исклучен", + "status_active": "API клучот е активен", + "status_required": "Потребен е API клуч", + "status_disabled_desc": "Функционалноста на MDBList моментално е оневозможена.", + "status_active_desc": "Рејтинзите од MDBList се овозможени.", + "status_required_desc": "Додајте го вашиот клуч подолу за да овозможите рејтинзи.", + "enable_toggle": "Овозможи MDBList", + "enable_toggle_desc": "Вклучи/исклучи ја целата MDBList функционалност", + "api_section": "API Клуч", + "placeholder": "Залепете го вашиот MDBList API клуч", + "save": "Зачувај", + "clear": "Избриши клуч", + "rating_providers": "Провајдери на рејтинзи", + "rating_providers_desc": "Изберете кои рејтинзи да се прикажуваат во апликацијата", + "how_to": "Како да добиете API клуч", + "step_1": "Најавете се на", + "step_1_link": "веб-страницата на MDBList", + "step_2": "Одете во секцијата", + "step_2_settings": "Settings", + "step_2_api": "API", + "step_2_end": ".", + "step_3": "Генерирајте нов клуч и копирајте го.", + "go_to_website": "Оди на MDBList", + "alert_clear_title": "Избриши API клуч", + "alert_clear_msg": "Дали сте сигурни дека сакате да го отстраните зачуваниот API клуч?", + "success_saved": "API клучот е успешно зачуван.", + "error_empty": "API клучот не може да биде празен.", + "error_save": "Се појави грешка при зачувувањето. Обидете се повторно.", + "api_key_empty_error": "API клучот не може да биде празен.", + "success_cleared": "API клучот е успешно избришан", + "error_clear": "Неуспешно бришење на API клучот" + }, + "notification": { + "title": "Поставки за известувања", + "section_general": "Општо", + "enable_notifications": "Овозможи известувања", + "section_types": "Типови на известувања", + "new_episodes": "Нови епизоди", + "upcoming_shows": "Претстојни серии", + "reminders": "Потсетници", + "section_timing": "Време на известување", + "timing_desc": "Кога сакате да бидете известени пред емитување на епизода?", + "hours_1": "1 час", + "hours_suffix": "часови", + "section_status": "Статус на известувања", + "stats_upcoming": "Претстојни", + "stats_this_week": "Оваа недела", + "stats_total": "Вкупно", + "sync_button": "Синхронизирај Библиотека и Trakt", + "syncing": "Се синхронизира...", + "sync_desc": "Автоматски ги синхронизира известувањата за сите серии во вашата библиотека и Trakt листа за гледање.", + "section_advanced": "Напредно", + "reset_button": "Ресетирај ги сите известувања", + "test_button": "Тестирај известување (5 сек)", + "test_notification_in": "Известување за {{seconds}}с...", + "test_notification_text": "Известувањето ќе се појави по {{seconds}} секунди", + "alert_reset_title": "Ресетирај известувања", + "alert_reset_msg": "Ова ќе ги откаже сите закажани известувања, но нема да избрише ништо од вашата библиотека. Дали сте сигурни?", + "alert_reset_success": "Сите известувања се ресетирани", + "alert_sync_complete": "Синхронизацијата е завршена", + "alert_sync_msg": "Успешно синхронизирани известувања за вашата библиотека и Trakt ставки.\n\nЗакажани: {{upcoming}} претстојни епизоди\nОваа недела: {{thisWeek}} епизоди", + "alert_test_scheduled": "Тест известувањето е закажано" + }, + "backup": { + "title": "Резервна копија и враќање", + "options_title": "Опции за резервна копија", + "options_desc": "Изберете што да вклучите во вашата резервна копија", + "section_core": "Основни податоци", + "section_addons": "Додатоци и интеграции", + "section_settings": "Поставки и преференции", + "library_label": "Библиотека", + "library_desc": "Вашите зачувани филмови и серии", + "watch_progress_label": "Напредок во гледање", + "watch_progress_desc": "Позиции на продолжување со гледање", + "addons_label": "Додатоци", + "addons_desc": "Инсталирани Stremio додатоци", + "plugins_label": "Приклучоци", + "plugins_desc": "Конфигурации на сопствени скрипти", + "trakt_label": "Trakt интеграција", + "trakt_desc": "Синхронизација на податоци и автентикација", + "app_settings_label": "Поставки на апликацијата", + "app_settings_desc": "Тема, преференции и конфигурации", + "user_prefs_label": "Кориснички преференции", + "user_prefs_desc": "Редослед на додатоци и UI поставки", + "catalog_settings_label": "Поставки на каталогот", + "catalog_settings_desc": "Филтри и преференции за каталози", + "api_keys_label": "API Клучеви", + "api_keys_desc": "MDBList и OpenRouter клучеви", + "action_create": "Создади резервна копија", + "action_restore": "Врати од резервна копија", + "section_info": "За резервните копии", + "info_text": "• Прилагодете ја содржината со прекинувачите погоре\n• Фајловите се чуваат локално на вашиот уред\n• Споделете го фајлот за пренос помеѓу уреди\n• Враќањето ќе ги пребрише вашите моментални податоци", + "alert_create_title": "Создади резервна копија", + "alert_no_content": "Нема избрано содржина.\n\nВе молиме овозможете барем една опција погоре.", + "alert_backup_created_title": "Копијата е создадена", + "alert_backup_created_msg": "Вашата резервна копија е подготвена за споделување.", + "alert_backup_failed_title": "Неуспешна резервна копија", + "alert_restore_confirm_title": "Потврди враќање", + "alert_restore_confirm_msg": "Ова ќе ги врати податоците од копијата создадена на {{date}}.\n\nОваа акција ќе ги пребрише тековните податоци. Дали продолжувате?", + "alert_restore_complete_title": "Враќањето е завршено", + "alert_restore_complete_msg": "Податоците се успешно вратени. Ве молиме рестартирајте ја апликацијата.", + "alert_restore_failed_title": "Враќањето не успеа", + "restart_app": "Рестартирај ја апликацијата", + "alert_restart_failed_title": "Неуспешно рестартирање", + "alert_restart_failed_msg": "Неуспешно рестартирање. Ве молиме рачно затворете ја и отворете ја апликацијата." + }, + "updates": { + "title": "Ажурирања", + "status_checking": "Проверка за ажурирања...", + "status_available": "Достапно е ажурирање!", + "status_downloading": "Преземање на ажурирањето...", + "status_installing": "Инсталирање на ажурирањето...", + "status_success": "Ажурирањето е успешно инсталирано!", + "status_error": "Неуспешно ажурирање", + "status_ready": "Подготвено за проверка", + "action_check": "Провери за ажурирања", + "action_install": "Инсталирај ажурирање", + "release_notes": "Белешки за верзијата:", + "version": "Верзија:", + "last_checked": "Последна проверка:", + "current_version": "Моментална верзија:", + "current_release_notes": "Белешки за тековната верзија:", + "github_release": "GITHUB ИЗДАНИЕ", + "current": "Тековна:", + "latest": "Најнова:", + "notes": "Белешки:", + "view_release": "Види издание", + "notification_settings": "ПОСТАВКИ ЗА ИЗВЕСТУВАЊА", + "ota_alerts_label": "OTA известувања", + "ota_alerts_desc": "Прикажи известувања за преку-воздух (OTA) ажурирања", + "major_alerts_label": "Главни ажурирања", + "major_alerts_desc": "Прикажи известувања за нови верзии на GitHub", + "alert_disable_ota_title": "Исклучи OTA известувања?", + "alert_disable_ota_msg": "Повеќе нема да добивате автоматски известувања.\n\n⚠️ Предупредување: Најновата верзија е важна за:\n• Поправка на грешки и стабилност\n• Нови функции\n• Точни извештаи за падови", + "alert_disable_major_title": "Исклучи известувања за главни верзии?", + "alert_disable_major_msg": "Повеќе нема да добивате инфо за верзии кои бараат реинсталација.\n\n⚠️ Предупредување: Овие ажурирања често содржат критични безбедносни поправки.", + "warning_note": "Останувањето на најнова верзија ви гарантира стабилна работа.", + "disable": "Исклучи", + "alert_no_update_to_install": "Нема достапно ажурирање за инсталација", + "alert_install_failed": "Неуспешна инсталација на ажурирањето", + "alert_no_update_title": "Нема ажурирање", + "alert_update_applied_msg": "Ажурирањето ќе биде применето при следното стартување" + }, + "player": { + "title": "Видео плеер", + "section_selection": "ИЗБОР НА ПЛЕЕР", + "internal_title": "Вграден плеер", + "internal_desc": "Користи го стандардниот плеер на апликацијата", + "vlc_title": "VLC", + "vlc_desc": "Отвори го стримот во VLC", + "infuse_title": "Infuse", + "infuse_desc": "Отвори го стримот во Infuse", + "outplayer_title": "OutPlayer", + "outplayer_desc": "Отвори го стримот во OutPlayer", + "vidhub_title": "VidHub", + "vidhub_desc": "Отвори го стримот во VidHub", + "infuse_live_title": "Infuse Livecontainer", + "infuse_live_desc": "Отвори го стримот во Infuse LiveContainer", + "external_title": "Надворешен плеер", + "external_desc": "Отвори во вашиот претпочитан надворешен плеер", + "section_playback": "ОПЦИИ ЗА РЕПРОДУКЦИЈА", + "skip_intro_settings_title": "Прескокни вовед", + "powered_by_introdb": "Овозможено од IntroDB", + "autoplay_title": "Автоматски пушти прв стрим", + "autoplay_desc": "Автоматски стартувај го првиот стрим од листата.", + "resume_title": "Секогаш продолжи", + "resume_desc": "Прескокни го прашањето и продолжи каде што застанавте (ако е изгледано помалку од 85%).", + "engine_title": "Енџин на плеер", + "engine_desc": "Auto користи ExoPlayer со MPV резерва. Auto се препорачува за најдобра компатибилност со HDR и Dolby Vision.", + "decoder_title": "Режим на декодер", + "decoder_desc": "Како се декодира видеото. Auto се препорачува за најдобар баланс.", + "gpu_title": "GPU Рендерирање", + "gpu_desc": "GPU-Next нуди подобро управување со HDR и бои.", + "external_downloads_title": "Надворешен плеер за преземања", + "external_downloads_desc": "Пуштајте ја преземената содржина во надворешен плеер.", + "restart_required": "Потребно е рестартирање", + "restart_msg_decoder": "Рестартирајте ја апликацијата за промената на декодерот да стапи на сила.", + "restart_msg_gpu": "Рестартирајте ја апликацијата за промената на GPU режимот да стапи на сила.", + "option_auto": "Auto", + "option_auto_desc_engine": "ExoPlayer + MPV резерва", + "option_mpv": "MPV", + "option_mpv_desc": "Само MPV", + "option_auto_desc_decoder": "Најдобар баланс", + "option_sw": "SW", + "option_sw_desc": "Софтверски", + "option_hw": "HW", + "option_hw_desc": "Хардверски", + "option_hw_plus": "HW+", + "option_hw_plus_desc": "Целосен HW", + "option_gpu_desc": "Стандардно", + "option_gpu_next_desc": "Напредно" + }, + "plugins": { + "title": "Приклучоци", + "enable_title": "Овозможи приклучоци", + "enable_desc": "Овозможи го енџинот за надворешни извори на медиуми", + "repo_config_title": "Конфигурација на складишта", + "repo_config_desc": "Управувајте со надворешни складишта (Repositories).", + "your_repos": "Складишта", + "your_repos_desc": "Конфигурирајте надворешни извори.", + "add_repo_button": "Додај складиште", + "refresh": "Освежи", + "remove": "Отстрани", + "enabled": "Овозможено", + "disabled": "Оневозможено", + "updating": "Се ажурира...", + "success": "Успех", + "error": "Грешка", + "alert_repo_added": "Складиштето е додадено и приклучоците се вчитани", + "alert_repo_saved": "URL адресата е успешно зачувана", + "alert_repo_refreshed": "Складиштето е освежено", + "alert_invalid_url": "Невалиден формат на URL", + "alert_plugins_cleared": "Сите приклучоци се отстранети", + "alert_cache_cleared": "Кеш меморијата е исчистена", + "unknown": "Непознато", + "active": "Активно", + "available": "Достапно", + "platform_disabled": "Платформата е исклучена", + "limited": "Ограничено", + "clear_all": "Избриши ги сите приклучоци", + "clear_all_desc": "Дали сте сигурни дека сакате да ги избришете сите приклучоци?", + "clear_cache": "Исчисти кеш на складишта", + "clear_cache_desc": "Ова ќе ги избрише зачуваните URL адреси и податоци.", + "add_new_repo": "Додај ново складиште", + "available_plugins": "Достапни приклучоци ({{count}})", + "placeholder": "Пребарај приклучоци...", + "all": "Сите", + "filter_all": "Сите типови", + "filter_movies": "Филмови", + "filter_tv": "ТВ Серии", + "enable_all": "Овозможи ги сите", + "disable_all": "Оневозможи ги сите", + "no_plugins_found": "Не се пронајдени приклучоци", + "no_plugins_available": "Нема достапни приклучоци", + "no_match_desc": "Ништо не одговара на „{{query}}“.", + "configure_repo_desc": "Конфигурирајте складиште погоре за да видите приклучоци.", + "clear_search": "Исчисти пребарување", + "no_external_player": "Нема надворешен плеер", + "showbox_token": "ShowBox UI Токен", + "showbox_placeholder": "Залепете го вашиот ShowBox UI токен", + "save": "Зачувај", + "clear": "Исчисти", + "additional_settings": "Дополнителни поставки", + "enable_url_validation": "Овозможи валидација на URL", + "url_validation_desc": "Провери ги линковите пред прикажување (подобрува сигурност, но може да биде побавно)", + "group_streams": "Групирај извори од приклучоци", + "group_streams_desc": "Групирај ги изворите според складиштето.", + "sort_quality": "Сортирај прво по квалитет", + "sort_quality_desc": "Достапно само кога групирањето е вклучено.", + "show_logos": "Прикажи логоа на приклучоци", + "show_logos_desc": "Прикажи лого покрај линковите за стриминг.", + "quality_filtering": "Филтрирање по квалитет", + "quality_filtering_desc": "Исклучете одредени резолуции од резултатите.", + "excluded_qualities": "Исклучени квалитети:", + "language_filtering": "Филтрирање по јазик", + "language_filtering_desc": "Исклучете одредени јазици од резултатите.", + "note": "Забелешка:", + "language_filtering_note": "Овој филтер важи само за провајдери кои нудат информации за јазик.", + "excluded_languages": "Исклучени јазици:", + "about_title": "За приклучоците", + "about_desc_1": "Приклучоците се модуларни компоненти кои повлекуваат содржина од надворешни протоколи. Тие работат локално на вашиот уред.", + "about_desc_2": "Приклучоците означени како „Ограничени“ може да бараат дополнителна конфигурација.", + "help_title": "Поставување приклучоци", + "help_step_1": "1. **Овозможи приклучоци** - Вклучи го главниот прекинувач", + "help_step_2": "2. **Додај складиште** - Внеси валидна URL адреса", + "help_step_3": "3. **Освежи** - Повлечи ги достапните приклучоци", + "help_step_4": "4. **Активирај** - Овозможи ги приклучоците што сакаш да ги користиш", + "got_it": "Разбрав!", + "repo_format_hint": "Формат: https://raw.githubusercontent.com/корисник/складиште/гранка", + "cancel": "Откажи", + "add": "Додај" + }, + "theme": { + "title": "Теми", + "select_theme": "ИЗБЕРИ ТЕМА", + "create_custom": "Создади сопствена тема", + "options": "ОПЦИИ", + "use_dominant_color": "Користи доминантна боја од постерот", + "categories": { + "all": "Сите теми", + "dark": "Темни теми", + "colorful": "Во боја", + "custom": "Мои теми" + }, + "editor": { + "theme_name_placeholder": "Име на тема", + "save": "Зачувај", + "primary": "Примарна", + "secondary": "Секундарна", + "background": "Позадина", + "invalid_name_title": "Невалидно име", + "invalid_name_msg": "Ве молиме внесете валидно име за темата" + }, + "alerts": { + "delete_title": "Избриши тема", + "delete_msg": "Дали сте сигурни дека сакате да ја избришете „{{name}}“?", + "ok": "Во ред", + "delete": "Избриши", + "cancel": "Откажи", + "back": "Поставки" + } + }, + "legal": { + "title": "Правни информации", + "intro_title": "Природа на апликацијата", + "intro_text": "Nuvio е медиумски плеер и апликација за управување со метаподатоци. Делува исклучиво како интерфејс за прелистување на јавно достапни информации и пуштање на фајлови обезбедени од корисникот. Nuvio не хостира ниту дистрибуира никаква содржина.", + "extensions_title": "Приклучоци од трети страни", + "extensions_text": "Приклучоците се развиени од независни програмери. Ние немаме контрола врз легалноста или функционалноста на тие приклучоци.", + "user_resp_title": "Одговорност на корисникот", + "user_resp_text": "Корисниците се одговорни за приклучоците што ги инсталираат. Програмерите на Nuvio не поддржуваат кршење на авторски права.", + "dmca_title": "Авторски права и DMCA", + "dmca_text": "Бидејќи не хостираме содржина, не можеме да ја отстраниме од интернет. Доколку верувате дека интерфејсот ги крши вашите права, контактирајте нè.", + "warranty_title": "Без гаранција", + "warranty_text": "Софтверот се нуди „како што е“, без никаква гаранција." + }, + "plugin_tester": { + "title": "Тестер на приклучоци", + "subtitle": "Стартувајте скрипти и следете ги логовите во реално време", + "tabs": { + "individual": "Индивидуално", + "repo": "Тестер на складиште", + "code": "Код", + "logs": "Логови", + "results": "Резултати" + }, + "common": { + "error": "Грешка", + "success": "Успех", + "movie": "Филм", + "tv": "ТВ", + "tmdb_id": "TMDB ID", + "season": "Сезона", + "episode": "Епизода", + "running": "Се извршува...", + "run_test": "Пушти тест", + "play": "Пушти", + "done": "Завршено", + "test": "Тест", + "testing": "Се тестира..." + }, + "individual": { + "load_from_url": "Вчитај од URL", + "load_from_url_desc": "Залепете GitHub URL или локална IP адреса.", + "enter_url_error": "Внесете URL адреса", + "code_loaded": "Кодот е вчитан", + "fetch_error": "Неуспешно вчитување: {{message}}", + "no_code_error": "Нема код за извршување", + "plugin_code": "Код на приклучокот", + "focus_editor": "Фокусирај го уредникот", + "code_placeholder": "// Залепете го кодот тука...", + "test_parameters": "Параметри за тест", + "no_logs": "Нема логови. Пуштете тест.", + "no_streams": "Не се пронајдени стримови.", + "streams_found": "Пронајден {{count}} стрим", + "streams_found_plural": "Пронајдени {{count}} стримови", + "tap_play_hint": "Притиснете Пушти за тест во плеер.", + "unnamed_stream": "Неименуван стрим", + "quality": "Квалитет: {{quality}}", + "size": "Големина: {{size}}", + "url_label": "URL: {{url}}", + "headers_info": "Headers: {{count}}", + "find_placeholder": "Најди во кодот...", + "edit_code_title": "Уреди код", + "no_url_stream_error": "Не е пронајдена URL за овој стрим" + }, + "repo": { + "title": "Тестер на складиште", + "description": "Тестирајте ги сите провајдери од едно складиште.", + "enter_repo_url_error": "Внесете URL на складиште", + "invalid_url_title": "Невалидна URL", + "invalid_url_msg": "Користете GitHub raw линк или локален http(s) линк.", + "manifest_build_error": "Не може да се креира manifest URL", + "manifest_fetch_error": "Неуспешно вчитување на manifest", + "repo_manifest_fetch_error": "Неуспешно вчитување на manifest на складиштето", + "missing_filename": "Недостасува име на фајл", + "scraper_build_error": "Не може да се креира линк за скриптата", + "download_scraper_error": "Неуспешно преземање на скриптата", + "test_failed": "Тестот не успеа", + "test_parameters": "Параметри", + "test_parameters_desc": "Овие параметри важат само за тестерот.", + "using_info": "Користи: {{mediaType}} • TMDB {{tmdbId}}", + "using_info_tv": "Користи: {{mediaType}} • TMDB {{tmdbId}} • S{{season}}E{{episode}}", + "providers_title": "Провајдери", + "repository_default": "Складиште", + "providers_count": "{{count}} провајдери", + "fetch_hint": "Вчитајте складиште за листа.", + "test_all": "Тестирај ги сите", + "status_running": "СЕ ИЗВРШУВА", + "status_ok": "ВО РЕД ({{count}})", + "status_ok_empty": "ВО РЕД (0)", + "status_failed": "НЕ УСПЕА", + "status_idle": "ВО МИРУВАЊЕ", + "tried_url": "Обид со: {{url}}", + "provider_logs": "Логови на провајдерот", + "no_logs_captured": "Нема снимено логови." + } + } +} +} diff --git a/src/i18n/locales/nl-NL.json b/src/i18n/locales/nl-NL.json new file mode 100644 index 00000000..467a6a01 --- /dev/null +++ b/src/i18n/locales/nl-NL.json @@ -0,0 +1,1430 @@ +{ + "common": { + "loading": "Laden...", + "cancel": "Annuleren", + "save": "Opslaan", + "delete": "Verwijderen", + "edit": "Bewerken", + "search": "Zoeken", + "error": "Fout", + "success": "Succes", + "ok": "OK", + "unknown": "Onbekend", + "retry": "Opnieuw proberen", + "try_again": "Probeer het opnieuw", + "go_back": "Ga terug", + "settings": "Instellingen", + "close": "Sluiten", + "enable": "Inschakelen", + "disable": "Uitschakelen", + "show_more": "Meer tonen", + "show_less": "Minder tonen", + "load_more": "Meer laden", + "unknown_date": "Onbekende datum", + "anonymous_user": "Anonieme gebruiker", + "time": { + "now": "Zojuist", + "minutes_ago": "{{count}}m geleden", + "hours_ago": "{{count}}u geleden", + "days_ago": "{{count}}d geleden" + }, + "days_short": { + "sun": "Zo", + "mon": "Ma", + "tue": "Di", + "wed": "Wo", + "thu": "Do", + "fri": "Vr", + "sat": "Za" + }, + "email": "E-mail", + "status": "Status" + }, + "home": { + "categories": { + "movies": "Films", + "series": "Series", + "channels": "Zenders" + }, + "movies": "Films", + "tv_shows": "TV-programma's", + "load_more_catalogs": "Meer catalogi laden", + "no_content": "Geen inhoud beschikbaar", + "add_catalogs": "Catalogi toevoegen", + "sign_in_available": "Inloggen beschikbaar", + "sign_in_desc": "Je kunt op elk moment inloggen via Instellingen → Account", + "view_all": "Alles bekijken", + "this_week": "Deze week", + "upcoming": "Binnenkort", + "recently_released": "Onlangs uitgebracht", + "no_scheduled_episodes": "Series zonder geplande afleveringen", + "check_back_later": "Kom later terug", + "continue_watching": "Verderkijken", + "up_next": "Volgende", + "up_next_caps": "VOLGENDE", + "released": "Uitgebracht", + "new": "Nieuw", + "tba": "Nader te bepalen", + "new_episodes": "{{count}} nieuwe afleveringen", + "season_short": "S{{season}}", + "episode_short": "A{{episode}}", + "season": "Seizoen {{season}}", + "episode": "Aflevering {{episode}}", + "movie": "Film", + "series": "Serie", + "tv_show": "TV-show", + "percent_watched": "{{percent}}% bekeken", + "view_details": "Details bekijken", + "remove": "Verwijderen", + "play": "Afspelen", + "play_now": "Nu afspelen", + "resume": "Hervatten", + "info": "Info", + "more_info": "Meer info", + "my_list": "Mijn lijst", + "save": "Opslaan", + "saved": "Opgeslagen", + "retry": "Opnieuw proberen", + "install_addons": "Add-ons installeren", + "settings": "Instellingen", + "no_featured_content": "Geen uitgelichte inhoud", + "couldnt_load_featured": "Kon uitgelichte inhoud niet laden", + "no_featured_desc": "Installeer add-ons met catalogi of wijzig de bron in de instellingen.", + "load_error_desc": "Er is een probleem opgetreden bij het ophalen van de uitgelichte inhoud. Controleer je verbinding.", + "no_featured_available": "Geen uitgelichte inhoud beschikbaar", + "no_description": "Geen beschrijving beschikbaar" + }, + "navigation": { + "home": "Home", + "library": "Bibliotheek", + "search": "Zoeken", + "downloads": "Downloads", + "settings": "Instellingen" + }, + "search": { + "title": "Zoeken", + "recent_searches": "Recente zoekopdrachten", + "discover": "Ontdekken", + "movies": "Films", + "tv_shows": "TV-programma's", + "select_catalog": "Selecteer catalogus", + "all_genres": "Alle genres", + "discovering": "Inhoud ontdekken...", + "show_more": "Toon meer ({{count}})", + "no_content_found": "Geen inhoud gevonden", + "try_different": "Probeer een ander genre of catalogus", + "select_catalog_desc": "Selecteer een catalogus om te ontdekken", + "tap_catalog_desc": "Tik op een catalogus hierboven om te beginnen", + "placeholder": "Zoek films, series...", + "keep_typing": "Blijf typen...", + "type_characters": "Typ ten minste 2 tekens om te zoeken", + "no_results": "Geen resultaten gevonden", + "try_keywords": "Probeer andere trefwoorden of controleer de spelling", + "select_type": "Selecteer type", + "browse_movies": "Blader door filmcatalogi", + "browse_tv": "Blader door seriecatalogi", + "select_genre": "Selecteer genre", + "show_all_content": "Toon alle inhoud", + "genres_count": "{{count}} genres" + }, + "library": { + "title": "Bibliotheek", + "watched": "Bekeken", + "continue": "Verdergaan", + "watchlist": "Watchlist", + "collection": "Collectie", + "rated": "Beoordeeld", + "items": "items", + "trakt_collections": "Trakt collecties", + "trakt_collection": "Trakt collectie", + "no_trakt": "Geen Trakt collecties", + "no_trakt_desc": "Je Trakt collecties verschijnen hier zodra je Trakt gebruikt", + "load_collections": "Collecties laden", + "empty_folder": "Geen inhoud in {{folder}}", + "empty_folder_desc": "Deze collectie is leeg", + "refresh": "Vernieuwen", + "no_movies": "Nog geen films", + "no_series": "Nog geen TV-series", + "no_content": "Nog geen inhoud", + "add_content_desc": "Voeg inhoud toe aan je bibliotheek om deze hier te zien", + "find_something": "Zoek iets om te kijken", + "removed_from_library": "Verwijderd uit bibliotheek", + "item_removed": "Item verwijderd uit je bibliotheek", + "failed_update_library": "Bijwerken bibliotheek mislukt", + "unable_remove": "Kan item niet verwijderen uit bibliotheek", + "marked_watched": "Gemarkeerd als bekeken", + "marked_unwatched": "Gemarkeerd als niet bekeken", + "item_marked_watched": "Item gemarkeerd als bekeken", + "item_marked_unwatched": "Item gemarkeerd als niet bekeken", + "failed_update_watched": "Status bekeken bijwerken mislukt", + "unable_update_watched": "Kan status bekeken niet bijwerken", + "added_to_library": "Toegevoegd aan bibliotheek", + "item_added": "Toegevoegd aan je lokale bibliotheek", + "add_to_library": "Toevoegen aan bibliotheek", + "remove_from_library": "Verwijderen uit bibliotheek", + "mark_watched": "Markeren als bekeken", + "mark_unwatched": "Markeren als niet bekeken", + "share": "Delen", + "add_to_watchlist": "Toevoegen aan Trakt Watchlist", + "remove_from_watchlist": "Verwijderen uit Trakt Watchlist", + "added_to_watchlist": "Toegevoegd aan Watchlist", + "added_to_watchlist_desc": "Toegevoegd aan je Trakt watchlist", + "removed_from_watchlist": "Verwijderd uit Watchlist", + "removed_from_watchlist_desc": "Verwijderd uit je Trakt watchlist", + "add_to_collection": "Toevoegen aan Trakt Collectie", + "remove_from_collection": "Verwijderen uit Trakt Collectie", + "added_to_collection": "Toegevoegd aan collectie", + "added_to_collection_desc": "Toegevoegd aan je Trakt collectie", + "removed_from_collection": "Verwijderd uit collectie", + "removed_from_collection_desc": "Verwijderd uit je Trakt collectie" + }, + "metadata": { + "unable_to_load": "Kan inhoud niet laden", + "error_code": "Foutcode: {{code}}", + "content_not_found": "Inhoud niet gevonden", + "content_not_found_desc": "Deze inhoud bestaat niet of is mogelijk verwijderd.", + "server_error": "Serverfout", + "server_error_desc": "De server is tijdelijk onbereikbaar. Probeer het later opnieuw.", + "bad_gateway": "Bad Gateway", + "bad_gateway_desc": "De server ervaart problemen. Probeer het later opnieuw.", + "service_unavailable": "Dienst niet beschikbaar", + "service_unavailable_desc": "De dienst is momenteel offline voor onderhoud.", + "too_many_requests": "Te veel verzoeken", + "too_many_requests_desc": "Je doet te veel verzoeken. Wacht even en probeer het opnieuw.", + "request_timeout": "Time-out van verzoek", + "request_timeout_desc": "Het verzoek duurde te lang. Probeer het opnieuw.", + "network_error": "Netwerkfout", + "network_error_desc": "Controleer je internetverbinding en probeer het opnieuw.", + "auth_error": "Authenticatiefout", + "auth_error_desc": "Controleer je accountinstellingen en probeer het opnieuw.", + "access_denied": "Toegang geweigerd", + "access_denied_desc": "Je hebt geen toestemming om deze inhoud te bekijken.", + "connection_error": "Verbindingsfout", + "streams_unavailable": "Streams niet beschikbaar", + "streams_unavailable_desc": "Streamingbronnen zijn momenteel niet beschikbaar.", + "unknown_error": "Onbekende fout", + "something_went_wrong": "Er is iets misgegaan. Probeer het opnieuw.", + "cast": "Cast", + "more_like_this": "Vergelijkbaar met dit", + "collection": "Collectie", + "episodes": "Afleveringen", + "seasons": "Seizoenen", + "posters": "Posters", + "banners": "Banners", + "specials": "Specials", + "season_number": "Seizoen {{number}}", + "episode_count": "{{count}} aflevering", + "episode_count_plural": "{{count}} afleveringen", + "no_episodes": "Geen afleveringen beschikbaar", + "no_episodes_for_season": "Geen afleveringen beschikbaar voor Seizoen {{season}}", + "episodes_not_released": "Afleveringen zijn mogelijk nog niet uitgebracht", + "no_description": "Geen beschrijving beschikbaar", + "episode_label": "AFLEVERING {{number}}", + "watch_again": "Opnieuw kijken", + "completed": "Voltooid", + "play_episode": "S{{season}}E{{episode}} afspelen", + "play": "Afspelen", + "watched": "Bekeken", + "watched_on_trakt": "Bekeken op Trakt", + "synced_with_trakt": "Gesynchroniseerd met Trakt", + "saved": "Opgeslagen", + "director": "Regisseur", + "directors": "Regisseurs", + "creator": "Maker", + "creators": "Makers", + "production": "Productie", + "network": "Netwerk", + "mark_watched": "Markeren als bekeken", + "mark_unwatched": "Markeren als niet bekeken", + "marking": "Markeren...", + "removing": "Verwijderen...", + "unmark_season": "Seizoen {{season}} als niet bekeken markeren", + "mark_season": "Seizoen {{season}} als bekeken markeren", + "resume": "Hervatten", + "spoiler_warning": "Spoiler waarschuwing", + "spoiler_warning_desc": "Deze reactie bevat spoilers. Weet je zeker dat je deze wilt zien?", + "cancel": "Annuleren", + "reveal_spoilers": "Spoilers tonen", + "movie_details": "Filmdetails", + "show_details": "Serie-details", + "tagline": "Tagline", + "status": "Status", + "release_date": "Releasedatum", + "runtime": "Speelduur", + "budget": "Budget", + "revenue": "Opbrengst", + "origin_country": "Land van herkomst", + "original_language": "Originele taal", + "first_air_date": "Eerste uitzenddatum", + "last_air_date": "Laatste uitzenddatum", + "total_episodes": "Totaal aantal afleveringen", + "episode_runtime": "Duur per aflevering", + "created_by": "Gemaakt door", + "backdrop_gallery": "Achtergrondgalerij", + "loading_episodes": "Afleveringen laden...", + "no_episodes_available": "Geen afleveringen beschikbaar", + "play_next": "S{{season}}E{{episode}} afspelen", + "play_next_episode": "Volgende aflevering afspelen", + "save": "Opslaan", + "percent_watched": "{{percent}}% bekeken", + "percent_watched_trakt": "{{percent}}% bekeken ({{traktPercent}}% op Trakt)", + "synced_with_trakt_progress": "Gesynchroniseerd met Trakt", + "using_trakt_progress": "Trakt voortgang gebruiken", + "added_to_collection_hero": "Toegevoegd aan collectie", + "added_to_collection_desc_hero": "Toegevoegd aan je Trakt collectie", + "removed_from_collection_hero": "Verwijderd uit collectie", + "removed_from_collection_desc_hero": "Verwijderd uit je Trakt collectie", + "mark_as_watched": "Markeren als bekeken", + "mark_as_unwatched": "Markeren als niet bekeken" + }, + "cast": { + "biography": "Biografie", + "known_for": "Bekend van", + "personal_info": "Persoonlijke info", + "born_in": "Geboren in {{place}}", + "filmography": "Filmografie", + "also_known_as": "Ook bekend als", + "no_info_available": "Geen aanvullende informatie beschikbaar", + "as_character": "als {{character}}", + "loading_details": "Details laden...", + "years_old": "{{age}} jaar oud", + "view_filmography": "Filmografie bekijken", + "filter": "Filter", + "sort_by": "Sorteren op", + "sort_popular": "Populair", + "sort_latest": "Nieuwste", + "sort_upcoming": "Binnenkort", + "upcoming_badge": "BINNENKORT", + "coming_soon": "Binnenkort verwacht", + "filmography_count": "Filmografie • {{count}} titels", + "loading_filmography": "Filmografie laden...", + "load_more_remaining": "Meer laden ({{count}} resterend)", + "alert_error_title": "Fout", + "alert_error_message": "Kan \"{{title}}\" niet laden. Probeer het later opnieuw.", + "alert_ok": "OK", + "no_upcoming": "Geen aankomende releases voor deze acteur", + "no_content": "Geen inhoud beschikbaar voor deze acteur", + "no_movies": "Geen films beschikbaar voor deze acteur", + "no_tv": "Geen TV-programma's beschikbaar voor deze acteur" + }, + "comments": { + "title": "Trakt Reacties", + "spoiler_warning": "⚠️ Deze reactie bevat spoilers. Tik om te tonen.", + "spoiler": "Spoiler", + "contains_spoilers": "Bevat spoilers", + "reveal": "Tonen", + "vip": "VIP", + "unavailable": "Reacties niet beschikbaar", + "no_comments": "Nog geen reacties op Trakt", + "not_in_database": "Deze inhoud staat mogelijk nog niet in de Trakt-database", + "check_trakt": "Check Trakt" + }, + "trailers": { + "title": "Trailers", + "official_trailers": "Officiële trailers", + "official_trailer": "Officiële trailer", + "teasers": "Teasers", + "teaser": "Teaser", + "clips_scenes": "Clips & Scènes", + "clip": "Clip", + "featurettes": "Featurettes", + "featurette": "Featurette", + "behind_the_scenes": "Achter de schermen", + "no_trailers": "Geen trailers beschikbaar", + "unavailable": "Trailer niet beschikbaar", + "unavailable_desc": "Deze trailer kon niet worden geladen. Probeer het later opnieuw.", + "unable_to_play": "Kan trailer niet afspelen. Probeer het opnieuw.", + "watch_on_youtube": "Bekijken op YouTube" + }, + "catalog": { + "no_content_found": "Geen inhoud gevonden", + "no_content_filters": "Geen inhoud gevonden voor de geselecteerde filters", + "loading_content": "Inhoud laden...", + "back": "Terug", + "in_theaters": "In de bioscoop", + "all": "Alle", + "failed_tmdb": "Laden van inhoud van TMDB mislukt", + "movies": "Films", + "tv_shows": "TV-programma's", + "channels": "Zenders" + }, + "streams": { + "back_to_episodes": "Terug naar afleveringen", + "back_to_info": "Terug naar info", + "fetching_from": "Ophalen van:", + "no_sources_available": "Geen streamingbronnen beschikbaar", + "add_sources_desc": "Voeg streamingbronnen toe in de instellingen", + "add_sources": "Bronnen toevoegen", + "finding_streams": "Beschikbare streams zoeken...", + "finding_best_stream": "Beste stream zoeken voor automatisch afspelen...", + "still_fetching": "Nog steeds streams aan het ophalen...", + "no_streams_available": "Geen streams beschikbaar", + "starting_best_stream": "Beste stream starten...", + "loading_more_sources": "Meer bronnen laden..." + }, + "player_ui": { + "via": "via {{name}}", + "audio_tracks": "Audiotracks", + "no_audio_tracks": "Geen audiotracks beschikbaar", + "playback_speed": "Afspeelsnelheid", + "on_hold": "Gepauzeerd", + "playback_error": "Afspeelfout", + "unknown_error": "Er is een onbekende fout opgetreden tijdens het afspelen.", + "copy_error": "Foutdetails kopiëren", + "copied_to_clipboard": "Gekopieerd naar klembord", + "dismiss": "Sluiten", + "continue_watching": "Verderkijken", + "start_over": "Opnieuw beginnen", + "resume": "Hervatten", + "change_source": "Bron wijzigen", + "switching_source": "Van bron wisselen...", + "no_sources_found": "Geen bronnen gevonden", + "sources": "Bronnen", + "finding_sources": "Bronnen zoeken...", + "unknown_source": "Onbekende bron", + "sources_limited": "Bronnen kunnen beperkt zijn door providerfouten.", + "episodes": "Afleveringen", + "specials": "Specials", + "season": "Seizoen {{season}}", + "stream": "Stream {{number}}", + "subtitles": "Ondertiteling", + "built_in": "Ingebouwd", + "addons": "Add-ons", + "style": "Stijl", + "none": "Geen", + "search_online_subtitles": "Online ondertiteling zoeken", + "preview": "Voorvertoning", + "quick_presets": "Snelinstellingen", + "default": "Standaard", + "yellow": "Geel", + "high_contrast": "Hoog contrast", + "large": "Groot", + "core": "Basis", + "font_size": "Lettergrootte", + "show_background": "Achtergrond tonen", + "advanced": "Geavanceerd", + "position": "Positie", + "text_color": "Tekstkleur", + "align": "Uitlijning", + "bottom_offset": "Afstand van onderkant", + "background_opacity": "Achtergrond transparantie", + "text_shadow": "Tekstschaduw", + "on": "Aan", + "off": "Uit", + "outline_color": "Contourkleur", + "outline": "Contour", + "outline_width": "Contourbreedte", + "letter_spacing": "Letterafstand", + "line_height": "Regelhoogte", + "timing_offset": "Tijdsverschil (s)", + "visual_sync": "Visuele synchronisatie", + "timing_hint": "Verschuif ondertiteling eerder (-) of later (+) om te synchroniseren.", + "reset_defaults": "Standaardinstellingen herstellen", + "mark_intro_start": "Begin intro markeren", + "mark_intro_end": "Einde intro markeren", + "intro_start_marked": "Begin intro gemarkeerd", + "intro_submitted": "Intro succesvol ingediend", + "intro_submit_failed": "Indienen van intro mislukt" + }, + "downloads": { + "title": "Downloads", + "no_downloads": "Nog geen downloads", + "no_downloads_desc": "Gedownloade inhoud verschijnt hier voor offline gebruik", + "explore": "Inhoud ontdekken", + "path_copied": "Pad gekopieerd", + "path_copied_desc": "Lokaal bestandspad gekopieerd naar klembord", + "copied": "Gekopieerd", + "incomplete": "Download onvoltooid", + "incomplete_desc": "Download is nog niet klaar", + "not_available": "Niet beschikbaar", + "not_available_desc": "Lokaal bestandspad is pas beschikbaar na voltooien download.", + "status_downloading": "Downloaden", + "status_completed": "Voltooid", + "status_paused": "Gepauzeerd", + "status_error": "Fout", + "status_queued": "In wachtrij", + "status_unknown": "Onbekend", + "provider": "Provider", + "streaming_playlist_warning": "Kan mogelijk niet afspelen - streaming playlist", + "remaining": "resterend", + "not_ready": "Download niet gereed", + "not_ready_desc": "Wacht tot de download is voltooid.", + "filter_all": "Alle", + "filter_active": "Actief", + "filter_done": "Klaar", + "filter_paused": "Gepauzeerd", + "no_filter_results": "Geen {{filter}} downloads", + "try_different_filter": "Probeer een ander filter", + "limitations_title": "Downloadbeperkingen", + "limitations_msg": "• Bestanden kleiner dan 1MB zijn meestal M3U8-streamingplaylists en kunnen niet worden gedownload voor offline gebruik. Deze werken alleen online.", + "remove_title": "Download verwijderen", + "remove_confirm": "Verwijder \"{{title}}\"{{season_episode}}?", + "cancel": "Annuleren", + "remove": "Verwijderen" + }, + "addons": { + "title": "Add-ons", + "reorder_mode": "Sorteermodus", + "reorder_info": "Add-ons bovenaan hebben prioriteit bij het laden", + "add_addon_placeholder": "Add-on URL", + "add_button": "Add-on toevoegen", + "my_addons": "Mijn add-ons", + "community_addons": "Community add-ons", + "no_addons": "Geen add-ons geïnstalleerd", + "uninstall_title": "Add-on verwijderen", + "uninstall_message": "Weet je zeker dat je {{name}} wilt verwijderen?", + "uninstall_button": "Verwijderen", + "install_success": "Add-on succesvol geïnstalleerd", + "install_error": "Installeren van add-on mislukt", + "load_error": "Laden van add-ons mislukt", + "fetch_error": "Ophalen van add-on details mislukt", + "invalid_url": "Voer een geldige add-on URL in", + "configure": "Configureren", + "version": "Versie: {{version}}", + "installed_addons": "GEÏNSTALLEERDE ADD-ONS", + "reorder_drag_title": "SLEEP ADD-ONS OM TE SORTEREN", + "install": "Installeren", + "config_unavailable_title": "Configuratie niet beschikbaar", + "config_unavailable_msg": "Kon configuratie-URL voor deze add-on niet vinden.", + "cannot_open_config_title": "Kan configuratie niet openen", + "cannot_open_config_msg": "De configuratie-URL ({{url}}) kan niet worden geopend.", + "description": "Beschrijving", + "supported_types": "Ondersteunde types", + "catalogs": "Catalogi", + "no_description": "Geen beschrijving beschikbaar", + "overview": "OVERZICHT", + "no_categories": "Geen categorieën", + "pre_installed": "VOORAF GEÏNSTALLEERD" + }, + "trakt": { + "title": "Trakt Instellingen", + "settings_title": "Trakt Instellingen", + "connect_title": "Verbinden met Trakt", + "connect_desc": "Synchroniseer je kijkgeschiedenis, watchlist en collectie met Trakt.tv", + "sign_in": "Inloggen bij Trakt", + "sign_out": "Uitloggen", + "sign_out_confirm": "Weet je zeker dat je wilt uitloggen bij Trakt?", + "joined": "Lid sinds {{date}}", + "sync_settings_title": "Sync Instellingen", + "sync_info": "Wanneer verbonden met Trakt, wordt de volledige geschiedenis direct via de API gesynchroniseerd.", + "auto_sync_label": "Kijkvoortgang automatisch syncen", + "auto_sync_desc": "Voortgang automatisch naar Trakt sturen", + "import_history_label": "Kijkgeschiedenis importeren", + "import_history_desc": "Gebruik \"Nu syncen\" om je geschiedenis van Trakt te halen", + "sync_now_button": "Nu syncen", + "display_settings_title": "Weergave Instellingen", + "show_comments_label": "Trakt Reacties tonen", + "show_comments_desc": "Toon Trakt reacties in de metadata-schermen", + "maintenance_title": "In Onderhoud", + "maintenance_unavailable": "Trakt niet beschikbaar", + "maintenance_desc": "De Trakt-integratie is tijdelijk onderbroken voor onderhoud.", + "maintenance_button": "Dienst in onderhoud", + "auth_success_title": "Succesvol verbonden", + "auth_success_msg": "Je Trakt-account is succesvol verbonden.", + "auth_error_title": "Authenticatiefout", + "auth_error_msg": "Koppelen met Trakt mislukt.", + "auth_error_generic": "Er is een fout opgetreden tijdens de authenticatie.", + "sign_out_error": "Uitloggen bij Trakt mislukt.", + "sync_complete_title": "Sync Voltooid", + "sync_success_msg": "Kijkvoortgang succesvol gesynchroniseerd met Trakt.", + "sync_error_msg": "Sync mislukt. Probeer het opnieuw." + }, + "simkl": { + "title": "Simkl Instellingen", + "settings_title": "Simkl Instellingen", + "connect_title": "Verbinden met Simkl", + "connect_desc": "Synchroniseer je kijkgeschiedenis en houd bij wat je kijkt", + "sign_in": "Inloggen bij Simkl", + "sign_out": "Verbinding verbreken", + "sign_out_confirm": "Weet je zeker dat je de verbinding met Simkl wilt verbreken?", + "syncing_desc": "Je bekeken items worden gesynchroniseerd met Simkl.", + "auth_success_title": "Succesvol verbonden", + "auth_success_msg": "Je Simkl-account is succesvol verbonden.", + "auth_error_title": "Authenticatiefout", + "auth_error_msg": "Koppelen met Simkl mislukt.", + "auth_error_generic": "Er is een fout opgetreden tijdens de authenticatie.", + "sign_out_error": "Verbinding met Simkl verbreken mislukt.", + "config_error_title": "Configuratiefout", + "config_error_msg": "Simkl Client ID ontbreekt.", + "conflict_title": "Conflict", + "conflict_msg": "Je kunt Simkl niet verbinden terwijl Trakt verbonden is. Ontkoppel eerst Trakt.", + "disclaimer": "Nuvio is niet gelieerd aan Simkl." + }, + "tmdb_settings": { + "title": "TMDb Instellingen", + "metadata_enrichment": "Metadata Verrijking", + "metadata_enrichment_desc": "Verbeter je inhoudsmetadata met TMDb-gegevens voor meer details.", + "enable_enrichment": "Verrijking inschakelen", + "enable_enrichment_desc": "Voegt TMDb-gegevens toe voor cast, certificering, logo's en productie-info.", + "localized_text": "Gelokaliseerde tekst", + "localized_text_desc": "Haal titels en beschrijvingen op in je voorkeurstaal van TMDb.", + "language": "Taal", + "change": "Wijzigen", + "logo_preview": "Logo Voorbeeld", + "logo_preview_desc": "Voorbeeld van hoe gelokaliseerde logo's eruit zien.", + "example": "Voorbeeld:", + "no_logo": "Geen logo beschikbaar", + "enrichment_options": "Verrijkingsopties", + "enrichment_options_desc": "Bepaal welke gegevens van TMDb worden opgehaald.", + "cast_crew": "Cast & Crew", + "cast_crew_desc": "Acteurs, regisseurs, schrijvers met profielfoto's", + "title_description": "Titel & Beschrijving", + "title_description_desc": "Gebruik gelokaliseerde TMDb-titels en samenvattingen", + "title_logos": "Titellogo's", + "title_logos_desc": "Hoogwaardige afbeeldingen van de titel", + "banners_backdrops": "Banners & Achtergronden", + "banners_backdrops_desc": "Hoge resolutie achtergrondafbeeldingen", + "certification": "Leeftijdsclassificatie", + "certification_desc": "Leeftijdskeuringen (PG-13, R, etc.)", + "recommendations": "Aanbevelingen", + "recommendations_desc": "Suggesties voor vergelijkbare inhoud", + "episode_data": "Afleveringsgegevens", + "episode_data_desc": "Miniaturen en info voor TV-afleveringen", + "season_posters": "Seizoensposters", + "season_posters_desc": "Posters specifiek per seizoen", + "production_info": "Productie-informatie", + "production_info_desc": "Netwerken en productiebedrijven met logo's", + "movie_details": "Filmdetails", + "movie_details_desc": "Budget, opbrengst, speelduur, tagline", + "tv_details": "TV Show details", + "tv_details_desc": "Status, aantal seizoenen, netwerken, makers", + "movie_collections": "Filmcollecties", + "movie_collections_desc": "Franchises (Marvel, Star Wars, etc.)", + "api_configuration": "API Configuratie", + "api_configuration_desc": "Configureer je TMDb API-toegang.", + "custom_api_key": "Eigen API Key", + "custom_api_key_desc": "Gebruik je eigen TMDb API key voor betere prestaties.", + "custom_key_active": "Eigen API key actief", + "api_key_required": "API key vereist", + "api_key_placeholder": "Plak je TMDb API key (v3)", + "how_to_get_key": "Hoe kom ik aan een TMDb API key?", + "built_in_key_msg": "Momenteel wordt de ingebouwde API key gebruikt.", + "cache_size": "Cache Grootte", + "clear_cache": "Cache Wissen", + "cache_days": "TMDb-gegevens worden 7 dagen bewaard voor snelheid", + "choose_language": "Taal Kiezen", + "choose_language_desc": "Selecteer je voorkeurstaal voor TMDb-inhoud", + "popular": "Populair", + "all_languages": "Alle talen", + "search_results": "Zoekresultaten", + "no_languages_found": "Geen talen gevonden voor \"{{query}}\"", + "clear_search": "Zoekopdracht wissen", + "clear_cache_title": "TMDb Cache Wissen", + "clear_cache_msg": "Dit wist alle gecachte TMDb-gegevens ({{size}}).", + "clear_cache_success": "TMDb cache succesvol gewist.", + "clear_cache_error": "Wissen van cache mislukt.", + "clear_api_key_title": "API Key Wissen", + "clear_api_key_msg": "Weet je zeker dat je je eigen API key wilt verwijderen?", + "clear_api_key_success": "API key succesvol gewist", + "clear_api_key_error": "Wissen van API key mislukt", + "empty_api_key": "API Key mag niet leeg zijn.", + "invalid_api_key": "Ongeldige API key. Controleer en probeer opnieuw.", + "save_error": "Er is een fout opgetreden bij het opslaan.", + "using_builtin_key": "Ingebouwde TMDb API key wordt nu gebruikt.", + "using_custom_key": "Eigen TMDb API key wordt nu gebruikt.", + "enter_custom_key": "Voer je eigen TMDb API key in en sla op.", + "key_verified": "API key geverifieerd en succesvol opgeslagen." + }, + "settings": { + "language": "Taal", + "select_language": "Selecteer taal", + "english": "Engels", + "portuguese": "Portugees", + "portuguese_br": "Portugees (Brazilië)", + "portuguese_pt": "Portugees (Portugal)", + "german": "Duits", + "arabic": "Arabisch", + "spanish": "Spaans", + "french": "Frans", + "italian": "Italiaans", + "croatian": "Kroatisch", + "chinese": "Chinees (Vereenvoudigd)", + "hindi": "Hindi", + "serbian": "Servisch", + "hebrew": "Hebreeuws", + "bulgarian": "Bulgaars", + "polish": "Pools", + "czech": "Tsjechisch", + "turkish": "Turks", + "slovenian": "Sloveens", + "macedonian": "Macedonisch", + "russian": "Russisch", + "filipino": "Filipijns", + "dutch_nl": "Nederlands (Nederland)", + "romanian": "Roemeens", + "albanian": "Albanees", + "account": "Account", + "content_discovery": "Inhoud & Ontdekken", + "appearance": "Uiterlijk", + "integrations": "Integraties", + "playback": "Afspelen", + "backup_restore": "Backup & Herstel", + "updates": "Updates", + "about": "Over", + "developer": "Ontwikkelaar", + "cache": "Cache", + "title": "Instellingen", + "settings_title": "Instellingen", + "sign_in_sync": "Inloggen om te synchroniseren", + "add_catalogs_sources": "Add-ons, catalogi en bronnen", + "player_trailers_downloads": "Speler, trailers, downloads", + "mdblist_tmdb_ai": "MDBList, TMDB, AI", + "check_updates": "Controleren op updates", + "clear_mdblist_cache": "MDBList-cache wissen", + "cache_management": "CACHEBEHEER", + "downloads_counter": "downloads en tellende", + "made_with_love": "Gemaakt met ❤️ door Tapframe en vrienden", + "sections": { + "information": "INFORMATIE", + "account": "ACCOUNT", + "theme": "THEMA", + "layout": "LAYOUT", + "sources": "BRONNEN", + "catalogs": "CATALOGI", + "discovery": "ONTDEKKEN", + "metadata": "METADATA", + "ai_assistant": "AI-ASSISTENT", + "video_player": "VIDEOSPELER", + "audio_subtitles": "AUDIO & ONDERTITELING", + "media": "MEDIA", + "notifications": "MELDINGEN", + "testing": "TESTEN", + "danger_zone": "GEVARENZONE" + }, + "items": { + "legal": "Juridisch & Disclaimer", + "privacy_policy": "Privacybeleid", + "report_issue": "Probleem melden", + "version": "Versie", + "contributors": "Bijdragers", + "view_contributors": "Bekijk alle bijdragers", + "theme": "Thema", + "episode_layout": "Aflevering layout", + "streams_backdrop": "Stream-achtergrond", + "streams_backdrop_desc": "Toon vervaagde achtergrond bij mobiele streams", + "addons": "Add-ons", + "installed": "geïnstalleerd", + "debrid_integration": "Debrid Integratie", + "debrid_desc": "Verbind Torbox", + "plugins": "Plugins", + "plugins_desc": "Beheer plugins en repositories", + "catalogs": "Catalogi", + "active": "actief", + "home_screen": "Home-scherm", + "home_screen_desc": "Layout en inhoud", + "continue_watching": "Verderkijken", + "continue_watching_desc": "Cache en afspeelgedrag", + "show_discover": "Toon Ontdek-sectie", + "show_discover_desc": "Toon ontdek-inhoud in Zoeken", + "mdblist": "MDBList", + "mdblist_connected": "Verbonden", + "mdblist_desc": "Inschakelen om beoordelingen & recensies toe te voegen", + "simkl": "Simkl", + "simkl_connected": "Verbonden", + "simkl_desc": "Houd bij wat je kijkt", + "tmdb": "TMDB", + "tmdb_desc": "Bron voor metadata & logo's", + "openrouter": "OpenRouter API", + "openrouter_connected": "Verbonden", + "openrouter_desc": "Voeg je API-key toe voor AI-chat", + "video_player": "Videospeler", + "built_in": "Ingebouwd", + "external": "Extern", + "preferred_audio": "Voorkeurstaal audio", + "preferred_subtitle": "Voorkeurstaal ondertiteling", + "subtitle_source": "Prioriteit ondertitelbron", + "auto_select_subs": "Automatisch ondertitels selecteren", + "auto_select_subs_desc": "Selecteer automatisch ondertitels op basis van je voorkeuren", + "show_trailers": "Trailers tonen", + "show_trailers_desc": "Toon trailers in de uitgelichte sectie", + "enable_downloads": "Downloads inschakelen", + "enable_downloads_desc": "Toon tabblad Downloads en sta opslaan van streams toe", + "notifications": "Meldingen", + "notifications_desc": "Herinneringen voor afleveringen", + "developer_tools": "Ontwikkelaarstools", + "developer_tools_desc": "Opties voor testen en debuggen", + "test_onboarding": "Test Onboarding", + "reset_onboarding": "Onboarding resetten", + "test_announcement": "Test Aankondiging", + "test_announcement_desc": "Toon 'Wat is er nieuw' overlay", + "reset_campaigns": "Campagnes resetten", + "reset_campaigns_desc": "Wis campagne-impressies", + "clear_all_data": "Alle gegevens wissen", + "clear_all_data_desc": "Reset alle instellingen en gecachte gegevens" + }, + "options": { + "horizontal": "Horizontaal", + "vertical": "Verticaal", + "internal_first": "Intern eerst", + "internal_first_desc": "Voorkeur voor ingebouwde ondertitels, daarna extern", + "external_first": "Extern eerst", + "external_first_desc": "Voorkeur voor add-on ondertitels, daarna ingebouwd", + "any_available": "Elke beschikbare", + "any_available_desc": "Gebruik het eerste beschikbare ondertitelspoor" + }, + "clear_data_desc": "Dit zal alle instellingen resetten en alle gecachte gegevens wissen. Weet je het zeker?", + "app_updates": "App Updates", + "about_nuvio": "Over Nuvio" + }, + "privacy": { + "title": "Privacy & Gegevens", + "settings_desc": "Beheer telemetrie en gegevensverzameling", + "info_title": "Je privacy is belangrijk", + "info_description": "Beheer welke gegevens worden verzameld. Analyse staat standaard uit en crashrapporten zijn anoniem.", + "analytics_enabled_title": "Analyse ingeschakeld", + "analytics_enabled_message": "Gebruiksgegevens worden verzameld om de app te verbeteren. Je kunt dit op elk moment uitschakelen.", + "disable_error_reporting_title": "Foutrapportage uitschakelen?", + "disable_error_reporting_message": "Als je dit uitschakelt, worden we niet op de hoogte gesteld van crashes. Dit kan ons vermogen om bugs op te lossen beïnvloeden.", + "enable_session_replay_title": "Sessieherhaling inschakelen?", + "enable_session_replay_message": "Dit neemt je scherm op bij fouten om ons te helpen begrijpen wat er gebeurde. Dit kan zichtbare inhoud op je scherm vastleggen.", + "enable_pii_title": "PII-verzameling inschakelen?", + "enable_pii_message": "Hiermee kunnen persoonlijk identificeerbare gegevens zoals IP-adres en apparaatdetails worden verzameld.", + "disable_all_title": "Alle telemetrie uitschakelen?", + "disable_all_message": "Dit schakelt alle analyses, foutrapportages en sessieherhalingen uit.", + "disable_all_button": "Alles uitschakelen", + "all_disabled_title": "Alle telemetrie uitgeschakeld", + "all_disabled_message": "Alle gegevensverzameling is uitgeschakeld. Wijzigingen worden van kracht na herstart.", + "reset_title": "Herstellen naar aanbevolen", + "reset_message": "Privacy-instellingen zijn hersteld naar aanbevolen waarden.", + "section_analytics": "ANALYSE", + "analytics_title": "Gebruiksanalyse", + "analytics_description": "Verzamel anonieme gebruikspatronen en schermweergaven", + "section_error_reporting": "FOUTRAPPORTAGE", + "error_reporting_title": "Crashrapporten", + "error_reporting_description": "Verstuur anonieme crashrapporten om stabiliteit te verbeteren", + "session_replay_title": "Sessieherhaling", + "session_replay_description": "Neem scherm op wanneer er fouten optreden", + "pii_title": "Inclusief apparaatinfo", + "pii_description": "Stuur IP-adres en apparaatdetails mee met rapporten", + "section_quick_actions": "SNELLE ACTIES", + "disable_all": "Alle telemetrie uitschakelen", + "disable_all_desc": "Zet alle gegevensverzameling uit", + "reset_recommended": "Herstellen naar aanbevolen", + "reset_recommended_desc": "Privacy-first instellingen met foutrapportage", + "section_learn_more": "LEER MEER", + "privacy_policy": "Privacybeleid", + "current_settings": "Overzicht huidige instellingen", + "summary_analytics": "Analyse", + "summary_errors": "Foutrapporten", + "summary_replay": "Sessieherhaling", + "summary_pii": "Apparaatinfo", + "restart_note_detailed": "* Wijzigingen in analyse en foutrapportage zijn direct van kracht. Sessieherhaling en PII vereisen een herstart." + }, + "ai_settings": { + "title": "AI-assistent", + "info_title": "AI-gestuurde Chat", + "info_desc": "Stel vragen over elke film of aflevering met geavanceerde AI. Krijg inzicht in het verhaal, personages, thema's en meer.", + "feature_1": "Context en analyse specifiek per aflevering", + "feature_2": "Uitleg van het verhaal en personage-inzichten", + "feature_3": "Trivia en feiten van achter de schermen", + "feature_4": "Je eigen gratis OpenRouter API-key", + "api_key_section": "OPENROUTER API-KEY", + "api_key_label": "API-key", + "api_key_desc": "Voer je OpenRouter API-key in om AI-chatfuncties te activeren", + "save_api_key": "API-key opslaan", + "saving": "Opslaan...", + "update": "Bijwerken", + "remove": "Verwijderen", + "get_free_key": "Krijg een gratis API-key van OpenRouter", + "enable_chat": "AI-chat inschakelen", + "enable_chat_desc": "Indien ingeschakeld, verschijnt de 'Vraag AI'-knop bij de inhoud.", + "chat_enabled": "AI-chat ingeschakeld", + "chat_enabled_desc": "Je kunt nu vragen stellen over films en series!", + "how_it_works": "Hoe het werkt", + "how_it_works_desc": "• OpenRouter geeft toegang tot meerdere AI-modellen\n• Je API-key blijft privé en veilig\n• Chat met context over specifieke afleveringen/films", + "error_invalid_key": "Voer een geldige API-key in", + "error_key_format": "OpenRouter API-keys moeten beginnen met 'sk-or-'", + "success_saved": "OpenRouter API-key succesvol opgeslagen!", + "error_save": "Opslaan van API-key mislukt", + "confirm_remove_title": "API-key verwijderen", + "confirm_remove_msg": "Weet je zeker dat je de API-key wilt verwijderen? Hiermee schakel je de AI-chat uit.", + "success_removed": "API-key succesvol verwijderd", + "error_remove": "Verwijderen van API-key mislukt" + }, + "catalog_settings": { + "title": "Catalogi", + "layout_phone": "LAYOUT CATALOGUSSCHERM (TELEFOON)", + "posters_per_row": "Posters per rij", + "auto": "Auto", + "show_titles": "Toon titels op posters", + "show_titles_desc": "Toon de titel onder elke poster", + "phone_only_hint": "Alleen van toepassing op telefoons. Tablets behouden adaptive layout.", + "catalogs_group": "Catalogi", + "enabled_count": "{{enabled}} van {{total}} ingeschakeld", + "rename_hint": "Houd een catalogus lang ingedrukt om deze te hernoemen", + "rename_modal_title": "Catalogus hernoemen", + "rename_placeholder": "Voer nieuwe naam in", + "error_save_name": "Kon de aangepaste naam niet opslaan." + }, + "continue_watching_settings": { + "title": "Verderkijken", + "playback_behavior": "AFSPEELGEDRAG", + "use_cached": "Gebruik gecachte streams", + "use_cached_desc": "Indien ingeschakeld, opent Verderkijken direct de speler met de laatst gebruikte stream.", + "open_metadata": "Open metadatascherm", + "open_metadata_desc": "Open het infoscherm in plaats van de streams wanneer cache uit staat.", + "card_appearance": "UITERLIJK KAART", + "card_style": "Kaartstijl", + "card_style_desc": "Kies hoe items in Verderkijken op het home-scherm verschijnen", + "wide": "Breed", + "poster": "Poster", + "cache_settings": "CACHE-INSTELLINGEN", + "cache_duration": "Duur stream-cache", + "cache_duration_desc": "Hoe lang gecachte streams bewaard blijven", + "important_note": "Belangrijke opmerking", + "important_note_text": "Niet alle streams blijven de hele duur actief. Langere cachetijden kunnen leiden tot verlopen links.", + "how_it_works": "Hoe het werkt", + "how_it_works_cached": "• Streams worden gecacht na het afspelen\n• Gecachte streams worden gecontroleerd voor gebruik\n• Indien verlopen, wordt het gewone scherm geopend", + "how_it_works_uncached": "• Zonder cache opent Verderkijken de inhoudspagina's\n• Je kunt kiezen tussen het Metadata- of Streams-scherm", + "changes_saved": "Wijzigingen opgeslagen", + "min": "min", + "hour": "uur", + "hours": "uur" + }, + "contributors": { + "title": "Bijdragers", + "special_mentions": "Speciale vermeldingen", + "tab_contributors": "Bijdragers", + "tab_special": "Speciale vermeldingen", + "tab_donors": "Donateurs", + "manager_role": "Community Manager", + "manager_desc": "Beheert de Discord & Reddit communities voor Nuvio", + "sponsor_role": "Server Sponsor", + "sponsor_desc": "Sponsorde de serverinfrastructuur voor Nuvio", + "mod_role": "Discord Mod", + "mod_desc": "Helpt bij het modereren van de Discord", + "loading": "Laden...", + "discord_user": "Discord Gebruiker", + "contributions": "bijdragen", + "gratitude_title": "Dankbaar voor elke bijdrage", + "gratitude_desc": "Elke regel code en elk bugrapport helpt Nuvio beter te maken", + "special_thanks_title": "Speciale dank", + "special_thanks_desc": "Deze mensen houden de community en servers draaiende", + "donors_desc": "Bedankt voor je steun. Jullie hulp houdt Nuvio gratis.", + "latest_donations": "Nieuwste", + "leaderboard": "Ranglijst", + "loading_donors": "Donateurs laden...", + "no_donors": "Nog geen donateurs", + "error_rate_limit": "GitHub API limiet bereikt. Probeer het later opnieuw.", + "error_failed": "Laden bijdragers mislukt. Controleer je verbinding.", + "retry": "Opnieuw proberen", + "no_contributors": "Geen bijdragers gevonden", + "loading_contributors": "Bijdragers laden..." + }, + "debrid": { + "title": "Debrid Integratie", + "description_torbox": "Ontgrendel 4K-kwaliteit en hoge snelheden door Torbox te integreren. Voer je API-key in voor een premium ervaring.", + "description_torrentio": "Configureer Torrentio voor torrent-streams. Een debrid-service is vereist.", + "tab_torbox": "TorBox", + "tab_torrentio": "Torrentio", + "status_connected": "Verbonden", + "status_disconnected": "Niet verbonden", + "enable_addon": "Add-on inschakelen", + "disconnect_button": "Ontkoppelen & Verwijderen", + "disconnect_loading": "Ontkoppelen...", + "account_info": "Accountinformatie", + "plan": "Abonnement", + "plan_free": "Gratis", + "plan_essential": "Essential ($3/p.m.)", + "plan_pro": "Pro ($10/p.m.)", + "plan_standard": "Standard ($5/p.m.)", + "plan_unknown": "Onbekend", + "expires": "Verloopt op", + "downloaded": "Gedownload", + "status_active": "Actief", + "connected_title": "✓ Verbonden met TorBox", + "connected_desc": "Je TorBox add-on is actief en biedt premium streams.", + "configure_title": "Add-on configureren", + "configure_desc": "Sorteer op kwaliteit, filter bestandsgroottes en beheer instellingen.", + "open_settings": "Instellingen openen", + "what_is_debrid": "Wat is een Debrid-service?", + "enter_api_key": "Voer je API-key in", + "connect_button": "Verbinden & Installeren", + "connecting": "Verbinden...", + "unlock_speeds_title": "Ontgrendel premium snelheden", + "unlock_speeds_desc": "Neem een Torbox-abonnement voor 4K-streams zonder bufferen.", + "get_subscription": "Abonnement afsluiten", + "powered_by": "Mogelijk gemaakt door", + "disclaimer_torbox": "Nuvio is niet gelieerd aan Torbox.", + "disclaimer_torrentio": "Nuvio is niet gelieerd aan Torrentio.", + "installed_badge": "✓ GEÏNSTALLEERD", + "promo_title": "⚡ Debrid-service nodig?", + "promo_desc": "Krijg TorBox voor razendsnelle 4K-streaming zonder bufferen.", + "promo_button": "TorBox abonnement afsluiten", + "service_label": "Debrid-service *", + "api_key_label": "API-key *", + "sorting_label": "Sorteren", + "exclude_qualities": "Kwaliteiten uitsluiten", + "priority_languages": "Prioriteitstalen", + "max_results": "Max resultaten", + "additional_options": "Aanvullende opties", + "no_download_links": "Geen downloadlinks tonen", + "no_debrid_catalog": "Geen debrid-catalogus tonen", + "install_button": "Installeer Torrentio", + "installing": "Installeren...", + "update_button": "Configuratie bijwerken", + "updating": "Bijwerken...", + "remove_button": "Torrentio verwijderen", + "error_api_required": "API-key vereist", + "error_api_required_desc": "Voer je API-key in om Torrentio te installeren.", + "success_installed": "Torrentio add-on succesvol geïnstalleerd!", + "success_removed": "Torrentio add-on succesvol verwijderd", + "alert_disconnect_title": "Torbox ontkoppelen", + "alert_disconnect_msg": "Weet je zeker dat je Torbox wilt ontkoppelen?" + }, + "home_screen": { + "title": "Home-scherm instellingen", + "changes_applied": "Wijzigingen toegepast", + "display_options": "WEERGAVE-OPTIES", + "show_hero": "Toon uitgelichte sectie", + "show_hero_desc": "Belangrijke inhoud bovenaan", + "show_this_week": "Toon 'Deze Week' sectie", + "show_this_week_desc": "Nieuwe afleveringen van deze week", + "select_catalogs": "Selecteer catalogi", + "all_catalogs": "Alle catalogi", + "selected": "geselecteerd", + "hero_layout": "Layout uitgelicht", + "layout_legacy": "Klassiek", + "layout_carousel": "Carrousel", + "layout_appletv": "Apple TV", + "layout_desc": "Banner, kaarten of Apple TV-stijl", + "featured_source": "Bron voor uitgelicht", + "using_catalogs": "Gebruikt catalogi", + "manage_selected_catalogs": "Beheer geselecteerde catalogi", + "dynamic_bg": "Dynamische achtergrond", + "dynamic_bg_desc": "Vervaagde banner achter carrousel", + "performance_note": "Kan prestaties beïnvloeden op tragere apparaten.", + "posters": "Posters", + "show_titles": "Toon titels", + "poster_size": "Postergrootte", + "poster_corners": "Posterhoeken", + "size_small": "Klein", + "size_medium": "Gemiddeld", + "size_large": "Groot", + "corners_square": "Vierkant", + "corners_rounded": "Afgerond", + "corners_pill": "Pilaar", + "about_these_settings": "OVER DEZE INSTELLINGEN", + "about_desc": "Beheer hoe inhoud verschijnt op je home-scherm.", + "hero_catalogs": { + "title": "Catalogi uitgelichte sectie", + "select_all": "Alles selecteren", + "clear_all": "Alles wissen", + "info": "Kies welke catalogi in de uitgelichte sectie verschijnen. Indien geen, worden ze allemaal gebruikt.", + "settings_saved": "Instellingen opgeslagen", + "error_load": "Laden catalogi mislukt", + "movies": "Films", + "tv_shows": "TV-series" + } + }, + "calendar": { + "title": "Kalender", + "loading": "Kalender laden...", + "no_scheduled_episodes": "Geen geplande afleveringen", + "check_back_later": "Kom later terug", + "showing_episodes_for": "Afleveringen voor {{date}}", + "show_all_episodes": "Toon alle afleveringen", + "no_episodes_for": "Geen afleveringen voor {{date}}", + "no_upcoming_found": "Geen aankomende afleveringen gevonden", + "add_series_desc": "Voeg series toe aan je bibliotheek om ze hier te zien" + }, + "mdblist": { + "title": "Beoordelingsbronnen", + "status_disabled": "MDBList uitgeschakeld", + "status_active": "API-key actief", + "status_required": "API-key vereist", + "status_disabled_desc": "MDBList-functionaliteit is momenteel uitgeschakeld.", + "status_active_desc": "Beoordelingen van MDBList zijn ingeschakeld.", + "status_required_desc": "Voeg hieronder je key toe om beoordelingen te activeren.", + "enable_toggle": "MDBList inschakelen", + "enable_toggle_desc": "Zet alle MDBList-functionaliteit aan/uit", + "api_section": "API-key", + "placeholder": "Plak je MDBList API-key", + "save": "Opslaan", + "clear": "Key wissen", + "rating_providers": "Beoordelingsproviders", + "rating_providers_desc": "Kies welke beoordelingen in de app worden getoond", + "how_to": "Hoe krijg ik een API-key?", + "step_1": "Log in op de", + "step_1_link": "MDBList website", + "step_2": "Ga naar de", + "step_2_settings": "Instellingen", + "step_2_api": "API", + "step_2_end": "sectie.", + "step_3": "Genereer een nieuwe key en kopieer deze.", + "go_to_website": "Ga naar MDBList", + "alert_clear_title": "API-key wissen", + "alert_clear_msg": "Weet je zeker dat je de opgeslagen API-key wilt verwijderen?", + "success_saved": "API-key succesvol opgeslagen.", + "error_empty": "API-key mag niet leeg zijn.", + "error_save": "Er is een fout opgetreden bij het opslaan. Probeer het opnieuw.", + "api_key_empty_error": "API-key mag niet leeg zijn.", + "success_cleared": "API-key succesvol gewist", + "error_clear": "Wissen van API-key mislukt" + }, + "notification": { + "title": "Notificatie-instellingen", + "section_general": "Algemeen", + "enable_notifications": "Notificaties inschakelen", + "section_types": "Type notificaties", + "new_episodes": "Nieuwe afleveringen", + "upcoming_shows": "Aankomende series", + "reminders": "Herinneringen", + "section_timing": "Timing van notificaties", + "timing_desc": "Wanneer wil je een melding ontvangen voordat een aflevering begint?", + "hours_1": "1 uur", + "hours_suffix": "uur", + "section_status": "Status notificaties", + "stats_upcoming": "Aankomend", + "stats_this_week": "Deze week", + "stats_total": "Totaal", + "sync_button": "Synchroniseer Bibliotheek & Trakt", + "syncing": "Synchroniseren...", + "sync_desc": "Synchroniseert automatisch meldingen voor alle series in je bibliotheek en Trakt watchlist.", + "section_advanced": "Geavanceerd", + "reset_button": "Alle notificaties resetten", + "test_button": "Testnotificatie (5 sec)", + "test_notification_in": "Notificatie over {{seconds}}s...", + "test_notification_text": "Notificatie verschijnt over {{seconds}} seconden", + "alert_reset_title": "Notificaties resetten", + "alert_reset_msg": "Dit annuleert alle geplande notificaties, maar verwijdert niets uit je bibliotheek. Weet je het zeker?", + "alert_reset_success": "Alle notificaties zijn gereset", + "alert_sync_complete": "Synchronisatie voltooid", + "alert_sync_msg": "Notificaties succesvol gesynchroniseerd.\n\nGepland: {{upcoming}} afleveringen\nDeze week: {{thisWeek}} afleveringen", + "alert_test_scheduled": "Testnotificatie ingepland" + }, + "backup": { + "title": "Backup & Herstel", + "options_title": "Backup-opties", + "options_desc": "Kies wat je wilt opnemen in je backup", + "section_core": "Kerndata", + "section_addons": "Add-ons & Integraties", + "section_settings": "Instellingen & Voorkeuren", + "library_label": "Bibliotheek", + "library_desc": "Je opgeslagen films en series", + "watch_progress_label": "Kijkvoortgang", + "watch_progress_desc": "Posities van verderkijken", + "addons_label": "Add-ons", + "addons_desc": "Geïnstalleerde Stremio add-ons", + "plugins_label": "Plugins", + "plugins_desc": "Aangepaste scraper-configuraties", + "trakt_label": "Trakt-integratie", + "trakt_desc": "Synchronisatiegegevens en tokens", + "app_settings_label": "App-instellingen", + "app_settings_desc": "Thema, voorkeuren en configuraties", + "user_prefs_label": "Gebruikersvoorkeuren", + "user_prefs_desc": "Add-on volgorde en UI-instellingen", + "catalog_settings_label": "Catalogus-instellingen", + "catalog_settings_desc": "Catalogusfilters en voorkeuren", + "api_keys_label": "API-keys", + "api_keys_desc": "MDBList en OpenRouter keys", + "action_create": "Backup maken", + "action_restore": "Herstellen van backup", + "section_info": "Over backups", + "info_text": "• Pas je backup aan met de schakelaars hierboven\n• Backup-bestanden worden lokaal opgeslagen\n• Deel je backup om gegevens over te zetten naar andere apparaten\n• Herstellen zal je huidige gegevens overschrijven", + "alert_create_title": "Backup maken", + "alert_no_content": "Geen inhoud geselecteerd voor backup.\n\nSchakel minimaal één optie in.", + "alert_backup_created_title": "Backup voltooid", + "alert_backup_created_msg": "Je backup is gemaakt en klaar om te worden gedeeld.", + "alert_backup_failed_title": "Backup mislukt", + "alert_restore_confirm_title": "Herstel bevestigen", + "alert_restore_confirm_msg": "Dit herstelt je gegevens van een backup gemaakt op {{date}}.\n\nDit overschrijft je huidige gegevens. Weet je het zeker?", + "alert_restore_complete_title": "Herstel voltooid", + "alert_restore_complete_msg": "Je gegevens zijn succesvol hersteld. Start de app opnieuw op om de wijzigingen te zien.", + "alert_restore_failed_title": "Herstel mislukt", + "restart_app": "App herstarten", + "alert_restart_failed_title": "Herstart mislukt", + "alert_restart_failed_msg": "Kon de app niet automatisch herstarten. Sluit de app handmatig af en open deze opnieuw." + }, + "updates": { + "title": "App Updates", + "status_checking": "Controleren op updates...", + "status_available": "Update beschikbaar!", + "status_downloading": "Update downloaden...", + "status_installing": "Update installeren...", + "status_success": "Update succesvol geïnstalleerd!", + "status_error": "Update mislukt", + "status_ready": "Klaar om op updates te controleren", + "action_check": "Controleren op updates", + "action_install": "Update installeren", + "release_notes": "Release-notities:", + "version": "Versie:", + "last_checked": "Laatst gecontroleerd:", + "current_version": "Huidige versie:", + "current_release_notes": "Huidige release-notities:", + "github_release": "GITHUB RELEASE", + "current": "Huidig:", + "latest": "Nieuwste:", + "notes": "Notities:", + "view_release": "Bekijk release", + "notification_settings": "NOTIFICATIE-INSTELLINGEN", + "ota_alerts_label": "OTA Update-meldingen", + "ota_alerts_desc": "Toon meldingen voor over-the-air updates", + "major_alerts_label": "Grote update-meldingen", + "major_alerts_desc": "Toon meldingen voor nieuwe app-versies op GitHub", + "alert_disable_ota_title": "OTA-meldingen uitschakelen?", + "alert_disable_ota_msg": "Je ontvangt geen automatische meldingen meer voor OTA-updates.\n\n⚠️ Waarschuwing: Up-to-date blijven is belangrijk voor bugfixes en stabiliteit.", + "alert_disable_major_title": "Grote update-meldingen uitschakelen?", + "alert_disable_major_msg": "Je ontvangt geen meldingen meer voor grote updates die herinstallatie vereisen.", + "warning_note": "Het ingeschakeld laten van meldingen zorgt ervoor dat je belangrijke bugfixes ontvangt.", + "disable": "Uitschakelen", + "alert_no_update_to_install": "Geen update beschikbaar om te installeren", + "alert_install_failed": "Installatie van update mislukt", + "alert_no_update_title": "Geen update", + "alert_update_applied_msg": "Update wordt toegepast bij de volgende herstart" + }, + "player": { + "title": "Videospeler", + "section_selection": "SPELER SELECTIE", + "internal_title": "Ingebouwde speler", + "internal_desc": "Gebruik de standaard videospeler van de app", + "vlc_title": "VLC", + "vlc_desc": "Open streams in VLC media player", + "infuse_title": "Infuse", + "infuse_desc": "Open streams in Infuse speler", + "outplayer_title": "OutPlayer", + "outplayer_desc": "Open streams in OutPlayer", + "vidhub_title": "VidHub", + "vidhub_desc": "Open streams in VidHub speler", + "infuse_live_title": "Infuse Livecontainer", + "infuse_live_desc": "Open streams in Infuse speler LiveContainer", + "external_title": "Externe speler", + "external_desc": "Open streams in je eigen voorkeursspeler", + "section_playback": "AFSPEELOPTIES", + "skip_intro_settings_title": "Intro overslaan", + "powered_by_introdb": "Mogelijk gemaakt door IntroDB", + "autoplay_title": "Eerste stream automatisch afspelen", + "autoplay_desc": "Start automatisch de eerste stream in de lijst.", + "resume_title": "Altijd hervatten", + "resume_desc": "Sla de vraag om te hervatten over en ga direct verder waar je gebleven was.", + "engine_title": "Videospeler Engine", + "engine_desc": "Auto gebruikt ExoPlayer met MPV als reserve. 'Auto' wordt aanbevolen voor de beste compatibiliteit.", + "decoder_title": "Decoder-modus", + "decoder_desc": "Hoe video wordt gedecodeerd. 'Auto' wordt aanbevolen.", + "gpu_title": "GPU Rendering", + "gpu_desc": "GPU-Next biedt beter HDR- en kleurbeheer.", + "external_downloads_title": "Externe speler voor downloads", + "external_downloads_desc": "Speel gedownloade inhoud af in je favoriete externe speler.", + "restart_required": "Herstart vereist", + "restart_msg_decoder": "Start de app opnieuw op om de decoder-wijziging toe te passen.", + "restart_msg_gpu": "Start de app opnieuw op om de GPU-modus te wijzigen.", + "option_auto": "Auto", + "option_auto_desc_engine": "ExoPlayer + MPV reserve", + "option_mpv": "MPV", + "option_mpv_desc": "Alleen MPV", + "option_auto_desc_decoder": "Beste balans", + "option_sw": "SW", + "option_sw_desc": "Software", + "option_hw": "HW", + "option_hw_desc": "Hardware", + "option_hw_plus": "HW+", + "option_hw_plus_desc": "Volledige hardware", + "option_gpu_desc": "Standaard", + "option_gpu_next_desc": "Geavanceerd" + }, + "plugins": { + "title": "Plugins", + "enable_title": "Plugins inschakelen", + "enable_desc": "Schakel de plugin-engine in om externe mediabronnen te vinden", + "repo_config_title": "Repository-configuratie", + "repo_config_desc": "Beheer externe plugin-repositories.", + "your_repos": "Repositories", + "your_repos_desc": "Configureer externe bronnen voor plugins.", + "add_repo_button": "Repository toevoegen", + "refresh": "Vernieuwen", + "remove": "Verwijderen", + "enabled": "Ingeschakeld", + "disabled": "Uitgeschakeld", + "updating": "Bijwerken...", + "success": "Succes", + "error": "Fout", + "alert_repo_added": "Repository toegevoegd en plugins geladen", + "alert_repo_saved": "Repository-URL succesvol opgeslagen", + "alert_repo_refreshed": "Repository succesvol vernieuwd", + "alert_invalid_url": "Ongeldig URL-formaat", + "alert_plugins_cleared": "Alle plugins zijn verwijderd", + "alert_cache_cleared": "Repository-cache succesvol gewist", + "unknown": "Onbekend", + "active": "Actief", + "available": "Beschikbaar", + "platform_disabled": "Platform uitgeschakeld", + "limited": "Beperkt", + "clear_all": "Wis alle plugins", + "clear_all_desc": "Weet je zeker dat je alle plugins wilt verwijderen? Dit kan niet ongedaan worden gemaakt.", + "clear_cache": "Wis repository-cache", + "clear_cache_desc": "Dit verwijdert de opgeslagen URL en gecachte gegevens.", + "add_new_repo": "Nieuwe repository toevoegen", + "available_plugins": "Beschikbare plugins ({{count}})", + "placeholder": "Zoek plugins...", + "all": "Alle", + "filter_all": "Alle types", + "filter_movies": "Films", + "filter_tv": "TV-series", + "enable_all": "Alles inschakelen", + "disable_all": "Alles uitschakelen", + "no_plugins_found": "Geen plugins gevonden", + "no_plugins_available": "Geen plugins beschikbaar", + "no_match_desc": "Geen plugins gevonden voor \"{{query}}\".", + "configure_repo_desc": "Configureer hierboven een repository om beschikbare plugins te zien.", + "clear_search": "Zoekopdracht wissen", + "no_external_player": "Geen externe speler", + "showbox_token": "ShowBox UI Token", + "showbox_placeholder": "Plak je ShowBox UI token", + "save": "Opslaan", + "clear": "Wissen", + "additional_settings": "Aanvullende instellingen", + "enable_url_validation": "URL-validatie inschakelen", + "url_validation_desc": "Valideer links voor weergave (verbetert betrouwbaarheid, kan resultaten vertragen)", + "group_streams": "Groepeer plugin-bronnen", + "group_streams_desc": "Groepeer bronnen per repository.", + "sort_quality": "Sorteer eerst op kwaliteit", + "sort_quality_desc": "Sorteer resultaten eerst op resolutie (alleen bij groepering).", + "show_logos": "Toon plugin-logo's", + "show_logos_desc": "Toon logo's naast de medialinks.", + "quality_filtering": "Kwaliteitsfilter", + "quality_filtering_desc": "Sluit specifieke resoluties uit van zoekresultaten.", + "excluded_qualities": "Uitgesloten kwaliteiten:", + "language_filtering": "Taalfilter", + "language_filtering_desc": "Sluit specifieke talen uit van zoekresultaten.", + "note": "Let op:", + "language_filtering_note": "Dit filter werkt alleen bij providers die taalinformatie meesturen.", + "excluded_languages": "Uitgesloten talen:", + "about_title": "Over plugins", + "about_desc_1": "Plugins zijn modulaire componenten die inhoud van externe protocollen ophalen. Ze draaien lokaal op je apparaat.", + "about_desc_2": "Plugins gemarkeerd als 'Beperkt' vereisen mogelijk extra configuratie.", + "help_title": "Plugin Setup", + "help_step_1": "1. **Activeer Plugins** - Zet de hoofdschakelaar aan", + "help_step_2": "2. **Voeg Repository toe** - Voer een geldige URL in", + "help_step_3": "3. **Vernieuw** - Haal de lijst met plugins op", + "help_step_4": "4. **Activeer** - Schakel de gewenste plugins in", + "got_it": "Begrepen!", + "repo_format_hint": "Formaat: https://raw.githubusercontent.com/gebruiker/repo/branch", + "cancel": "Annuleren", + "add": "Toevoegen" + }, + "theme": { + "title": "App thema's", + "select_theme": "SELECTEER THEMA", + "create_custom": "Aangepast thema maken", + "options": "OPTIES", + "use_dominant_color": "Gebruik dominante kleur van artwork", + "categories": { + "all": "Alle thema's", + "dark": "Donkere thema's", + "colorful": "Kleurrijk", + "custom": "Mijn thema's" + }, + "editor": { + "theme_name_placeholder": "Naam thema", + "save": "Opslaan", + "primary": "Primair", + "secondary": "Secundair", + "background": "Achtergrond", + "invalid_name_title": "Ongeldige naam", + "invalid_name_msg": "Voer een geldige naam in" + }, + "alerts": { + "delete_title": "Thema verwijderen", + "delete_msg": "Weet je zeker dat je \"{{name}}\" wilt verwijderen?", + "ok": "OK", + "delete": "Verwijderen", + "cancel": "Annuleren", + "back": "Instellingen" + } + }, + "legal": { + "title": "Juridisch & Disclaimer", + "intro_title": "Aard van de applicatie", + "intro_text": "Nuvio is een mediaspeler en metadata-beheertoepassing. Het fungeert uitsluitend als interface voor het browsen van openbaar beschikbare metadata en het afspelen van mediabestanden verstrekt door de gebruiker of externe plugins. Nuvio host zelf geen media.", + "extensions_title": "Plugins van derden", + "extensions_text": "Nuvio staat toe dat gebruikers plugins van derden installeren. Wij zijn niet verantwoordelijk voor de inhoud, legaliteit of functionaliteit van deze plugins.", + "user_resp_title": "Verantwoordelijkheid van de gebruiker", + "user_resp_text": "Gebruikers zijn zelf verantwoordelijk voor de geïnstalleerde plugins en de inhoud die zij bekijken. Door deze app te gebruiken, stem je ermee in dat je het wettelijk recht hebt op de toegang tot de betreffende content.", + "dmca_title": "Auteursrecht & DMCA", + "dmca_text": "Wij respecteren intellectueel eigendom. Omdat Nuvio geen content host, kunnen we geen content van het internet verwijderen.", + "warranty_title": "Geen garantie", + "warranty_text": "Deze software wordt geleverd 'as is', zonder enige vorm van garantie." + }, + "plugin_tester": { + "title": "Plugin Tester", + "subtitle": "Voer scrapers uit en bekijk logs in real-time", + "tabs": { + "individual": "Individueel", + "repo": "Repo Tester", + "code": "Code", + "logs": "Logs", + "results": "Resultaten" + }, + "common": { + "error": "Fout", + "success": "Succes", + "movie": "Film", + "tv": "TV", + "tmdb_id": "TMDB ID", + "season": "Seizoen", + "episode": "Aflevering", + "running": "Bezig…", + "run_test": "Test uitvoeren", + "play": "Afspelen", + "done": "Klaar", + "test": "Test", + "testing": "Testen…" + }, + "individual": { + "load_from_url": "Laden van URL", + "load_from_url_desc": "Plak een raw GitHub URL of lokaal IP en tik op download.", + "enter_url_error": "Voer een URL in", + "code_loaded": "Code geladen van URL", + "fetch_error": "Ophalen mislukt: {{message}}", + "no_code_error": "Geen code om uit te voeren", + "plugin_code": "Plugin Code", + "focus_editor": "Focus editor", + "code_placeholder": "// Plak plugin code hier...", + "test_parameters": "Testparameters", + "no_logs": "Nog geen logs. Voer een test uit.", + "no_streams": "Nog geen streams gevonden.", + "streams_found": "{{count}} stream gevonden", + "streams_found_plural": "{{count}} streams gevonden", + "tap_play_hint": "Tik op afspelen om een stream te testen.", + "unnamed_stream": "Naamloze stream", + "quality": "Kwaliteit: {{quality}}", + "size": "Grootte: {{size}}", + "url_label": "URL: {{url}}", + "headers_info": "Headers: {{count}} aangepaste header(s)", + "find_placeholder": "Zoek in code…", + "edit_code_title": "Code bewerken", + "no_url_stream_error": "Geen URL gevonden voor deze stream" + }, + "repo": { + "title": "Repo Tester", + "description": "Haal een repository op en test elke provider.", + "enter_repo_url_error": "Voer een repository-URL in", + "invalid_url_title": "Ongeldige URL", + "invalid_url_msg": "Gebruik een GitHub raw URL of een lokale URL.", + "manifest_build_error": "Kon geen manifest-URL bouwen", + "manifest_fetch_error": "Kon manifest niet ophalen", + "repo_manifest_fetch_error": "Kon repository-manifest niet ophalen", + "missing_filename": "Bestandsnaam ontbreekt in manifest", + "scraper_build_error": "Kon scraper-URL niet bouwen", + "download_scraper_error": "Downloaden scraper mislukt", + "test_failed": "Test mislukt", + "test_parameters": "Repo Testparameters", + "test_parameters_desc": "Deze parameters worden alleen gebruikt voor de Repo Tester.", + "using_info": "Gebruikt: {{mediaType}} • TMDB {{tmdbId}}", + "using_info_tv": "Gebruikt: {{mediaType}} • TMDB {{tmdbId}} • S{{season}}E{{episode}}", + "providers_title": "Providers", + "repository_default": "Repository", + "providers_count": "{{count}} providers", + "fetch_hint": "Haal een repo op om providers te tonen.", + "test_all": "Alles testen", + "status_running": "BEZIG", + "status_ok": "OK ({{count}})", + "status_ok_empty": "OK (0)", + "status_failed": "MISLUKT", + "status_idle": "WACHTEN", + "tried_url": "Geprobeerd: {{url}}", + "provider_logs": "Provider logs", + "no_logs_captured": "Geen logs vastgelegd." + } + } +} diff --git a/src/i18n/locales/pl.json b/src/i18n/locales/pl.json new file mode 100644 index 00000000..184316c0 --- /dev/null +++ b/src/i18n/locales/pl.json @@ -0,0 +1,1430 @@ +{ + "common": { + "loading": "Ładowanie...", + "cancel": "Anuluj", + "save": "Zapisz", + "delete": "Usuń", + "edit": "Edytuj", + "search": "Szukaj", + "error": "Błąd", + "success": "Sukces", + "ok": "OK", + "unknown": "Nieznane", + "retry": "Ponów", + "try_again": "Spróbuj ponownie", + "go_back": "Wróć", + "settings": "Ustawienia", + "close": "Zamknij", + "enable": "Włącz", + "disable": "Wyłącz", + "show_more": "Pokaż więcej", + "show_less": "Pokaż mniej", + "load_more": "Załaduj więcej", + "unknown_date": "Nieznana data", + "anonymous_user": "Anonimowy użytkownik", + "time": { + "now": "Przed chwilą", + "minutes_ago": "{{count}} min temu", + "hours_ago": "{{count}} godz. temu", + "days_ago": "{{count}} dni temu" + }, + "days_short": { + "sun": "Ndz", + "mon": "Pon", + "tue": "Wt", + "wed": "Śr", + "thu": "Czw", + "fri": "Pt", + "sat": "Sob" + }, + "email": "Email", + "status": "Status" + }, + "home": { + "categories": { + "movies": "Filmy", + "series": "Seriale", + "channels": "Kanały" + }, + "movies": "Filmy", + "tv_shows": "Programy TV", + "load_more_catalogs": "Załaduj więcej katalogów", + "no_content": "Brak dostępnej zawartości", + "add_catalogs": "Dodaj katalogi", + "sign_in_available": "Logowanie dostępne", + "sign_in_desc": "Możesz zalogować się w dowolnym momencie w Ustawienia → Konto", + "view_all": "Zobacz wszystko", + "this_week": "W tym tygodniu", + "upcoming": "Nadchodzące", + "recently_released": "Ostatnio wydane", + "no_scheduled_episodes": "Seriale bez zaplanowanych odcinków", + "check_back_later": "Sprawdź ponownie później", + "continue_watching": "Kontynuuj oglądanie", + "up_next": "Następne", + "up_next_caps": "NASTĘPNE", + "released": "Wydano", + "new": "Nowe", + "tba": "TBA", + "new_episodes": "{{count}} nowych odcinków", + "season_short": "S{{season}}", + "episode_short": "O{{episode}}", + "season": "Sezon {{season}}", + "episode": "Odcinek {{episode}}", + "movie": "Film", + "series": "Serial", + "tv_show": "Program TV", + "percent_watched": "Obejrzano {{percent}}%", + "view_details": "Pokaż szczegóły", + "remove": "Usuń", + "play": "Odtwórz", + "play_now": "Odtwórz teraz", + "resume": "Wznów", + "info": "Info", + "more_info": "Więcej informacji", + "my_list": "Moja lista", + "save": "Zapisz", + "saved": "Zapisano", + "retry": "Ponów", + "install_addons": "Zainstaluj dodatki", + "settings": "Ustawienia", + "no_featured_content": "Brak wyróżnionej zawartości", + "couldnt_load_featured": "Nie udało się załadować wyróżnionych treści", + "no_featured_desc": "Zainstaluj dodatki z katalogami lub zmień źródło treści w ustawieniach.", + "load_error_desc": "Wystąpił problem z pobieraniem wyróżnionych treści. Sprawdź połączenie i spróbuj ponownie.", + "no_featured_available": "Brak dostępnych wyróżnionych treści", + "no_description": "Brak opisu" + }, + "navigation": { + "home": "Start", + "library": "Biblioteka", + "search": "Szukaj", + "downloads": "Pobrane", + "settings": "Ustawienia" + }, + "search": { + "title": "Szukaj", + "recent_searches": "Ostatnie wyszukiwania", + "discover": "Odkrywaj", + "movies": "Filmy", + "tv_shows": "Programy TV", + "select_catalog": "Wybierz katalog", + "all_genres": "Wszystkie gatunki", + "discovering": "Odkrywanie treści...", + "show_more": "Pokaż więcej ({{count}})", + "no_content_found": "Nie znaleziono treści", + "try_different": "Spróbuj innego gatunku lub katalogu", + "select_catalog_desc": "Wybierz katalog, aby zacząć odkrywać", + "tap_catalog_desc": "Stuknij w powyższy katalog, aby zacząć", + "placeholder": "Szukaj filmów, seriali...", + "keep_typing": "Pisz dalej...", + "type_characters": "Wpisz co najmniej 2 znaki, aby szukać", + "no_results": "Brak wyników", + "try_keywords": "Spróbuj innych słów kluczowych lub sprawdź pisownię", + "select_type": "Wybierz typ", + "browse_movies": "Przeglądaj katalogi filmów", + "browse_tv": "Przeglądaj katalogi seriali", + "select_genre": "Wybierz gatunek", + "show_all_content": "Pokaż całą zawartość", + "genres_count": "{{count}} gatunków" + }, + "library": { + "title": "Biblioteka", + "watched": "Obejrzane", + "continue": "Kontynuuj", + "watchlist": "Do obejrzenia", + "collection": "Kolekcja", + "rated": "Ocenione", + "items": "elementy", + "trakt_collections": "Kolekcje Trakt", + "trakt_collection": "Kolekcja Trakt", + "no_trakt": "Brak kolekcji Trakt", + "no_trakt_desc": "Twoje kolekcje Trakt pojawią się tutaj po zalogowaniu do Trakt", + "load_collections": "Załaduj kolekcje", + "empty_folder": "Brak treści w {{folder}}", + "empty_folder_desc": "Ta kolekcja jest pusta", + "refresh": "Odśwież", + "no_movies": "Brak filmów", + "no_series": "Brak seriali", + "no_content": "Brak treści", + "add_content_desc": "Dodaj treści do biblioteki, aby zobaczyć je tutaj", + "find_something": "Znajdź coś do obejrzenia", + "removed_from_library": "Usunięto z biblioteki", + "item_removed": "Element usunięty z Twojej biblioteki", + "failed_update_library": "Nie udało się zaktualizować biblioteki", + "unable_remove": "Nie można usunąć elementu z biblioteki", + "marked_watched": "Oznaczono jako obejrzane", + "marked_unwatched": "Oznaczono jako nieobejrzane", + "item_marked_watched": "Element oznaczony jako obejrzany", + "item_marked_unwatched": "Element oznaczony jako nieobejrzany", + "failed_update_watched": "Nie udało się zaktualizować statusu oglądania", + "unable_update_watched": "Nie można zaktualizować statusu oglądania", + "added_to_library": "Dodano do biblioteki", + "item_added": "Dodano do lokalnej biblioteki", + "add_to_library": "Dodaj do biblioteki", + "remove_from_library": "Usuń z biblioteki", + "mark_watched": "Oznacz jako obejrzane", + "mark_unwatched": "Oznacz jako nieobejrzane", + "share": "Udostępnij", + "add_to_watchlist": "Dodaj do listy Trakt", + "remove_from_watchlist": "Usuń z listy Trakt", + "added_to_watchlist": "Dodano do listy", + "added_to_watchlist_desc": "Dodano do Twojej listy do obejrzenia na Trakt", + "removed_from_watchlist": "Usunięto z listy", + "removed_from_watchlist_desc": "Usunięto z Twojej listy do obejrzenia na Trakt", + "add_to_collection": "Dodaj do kolekcji Trakt", + "remove_from_collection": "Usuń z kolekcji Trakt", + "added_to_collection": "Dodano do kolekcji", + "added_to_collection_desc": "Dodano do Twojej kolekcji Trakt", + "removed_from_collection": "Usunięto z kolekcji", + "removed_from_collection_desc": "Usunięto z Twojej kolekcji Trakt" + }, + "metadata": { + "unable_to_load": "Nie można załadować treści", + "error_code": "Kod błędu: {{code}}", + "content_not_found": "Nie znaleziono treści", + "content_not_found_desc": "Ta treść nie istnieje lub mogła zostać usunięta.", + "server_error": "Błąd serwera", + "server_error_desc": "Serwer jest chwilowo niedostępny. Spróbuj ponownie później.", + "bad_gateway": "Błąd bramy", + "bad_gateway_desc": "Serwer napotkał problemy. Spróbuj ponownie później.", + "service_unavailable": "Usługa niedostępna", + "service_unavailable_desc": "Usługa jest obecnie w trakcie konserwacji. Spróbuj ponownie później.", + "too_many_requests": "Zbyt wiele zapytań", + "too_many_requests_desc": "Wysyłasz zbyt wiele zapytań. Odczekaj chwilę i spróbuj ponownie.", + "request_timeout": "Przekroczono czas oczekiwania", + "request_timeout_desc": "Zapytanie trwało zbyt długo. Spróbuj ponownie.", + "network_error": "Błąd sieci", + "network_error_desc": "Sprawdź połączenie internetowe i spróbuj ponownie.", + "auth_error": "Błąd uwierzytelniania", + "auth_error_desc": "Sprawdź ustawienia konta i spróbuj ponownie.", + "access_denied": "Odmowa dostępu", + "access_denied_desc": "Nie masz uprawnień do dostępu do tej treści.", + "connection_error": "Błąd połączenia", + "streams_unavailable": "Strumienie niedostępne", + "streams_unavailable_desc": "Źródła strumieniowania są obecnie niedostępne. Spróbuj ponownie później.", + "unknown_error": "Nieznany błąd", + "something_went_wrong": "Coś poszło nie tak. Spróbuj ponownie.", + "cast": "Obsada", + "more_like_this": "Więcej w tym stylu", + "collection": "Kolekcja", + "episodes": "Odcinki", + "seasons": "Sezony", + "posters": "Plakaty", + "banners": "Bannery", + "specials": "Odcinki specjalne", + "season_number": "Sezon {{number}}", + "episode_count": "{{count}} odcinek", + "episode_count_plural": "{{count}} odcinki", + "no_episodes": "Brak dostępnych odcinków", + "no_episodes_for_season": "Brak dostępnych odcinków dla sezonu {{season}}", + "episodes_not_released": "Odcinki mogły jeszcze nie zostać wydane", + "no_description": "Brak opisu", + "episode_label": "ODCINEK {{number}}", + "watch_again": "Obejrzyj ponownie", + "completed": "Ukończono", + "play_episode": "Odtwórz S{{season}}O{{episode}}", + "play": "Odtwórz", + "watched": "Obejrzane", + "watched_on_trakt": "Obejrzane na Trakt", + "synced_with_trakt": "Zsynchronizowano z Trakt", + "saved": "Zapisano", + "director": "Reżyser", + "directors": "Reżyserzy", + "creator": "Twórca", + "creators": "Twórcy", + "production": "Produkcja", + "network": "Sieć", + "mark_watched": "Oznacz jako obejrzane", + "mark_unwatched": "Oznacz jako nieobejrzane", + "marking": "Oznaczanie...", + "removing": "Usuwanie...", + "unmark_season": "Odznacz sezon {{season}}", + "mark_season": "Oznacz sezon {{season}}", + "resume": "Wznów", + "spoiler_warning": "Ostrzeżenie o spojlerach", + "spoiler_warning_desc": "Ten komentarz zawiera spoilery. Czy na pewno chcesz go wyświetlić?", + "cancel": "Anuluj", + "reveal_spoilers": "Pokaż spoilery", + "movie_details": "Szczegóły filmu", + "show_details": "Pokaż szczegóły", + "tagline": "Hasło", + "status": "Status", + "release_date": "Data premiery", + "runtime": "Czas trwania", + "budget": "Budżet", + "revenue": "Przychód", + "origin_country": "Kraj pochodzenia", + "original_language": "Język oryginalny", + "first_air_date": "Data pierwszej emisji", + "last_air_date": "Data ostatniej emisji", + "total_episodes": "Liczba odcinków", + "episode_runtime": "Czas trwania odcinka", + "created_by": "Utworzone przez", + "backdrop_gallery": "Galeria tła", + "loading_episodes": "Ładowanie odcinków...", + "no_episodes_available": "Brak dostępnych odcinków", + "play_next": "Odtwórz S{{season}}O{{episode}}", + "play_next_episode": "Odtwórz następny odcinek", + "save": "Zapisz", + "percent_watched": "Obejrzano {{percent}}%", + "percent_watched_trakt": "Obejrzano {{percent}}% ({{traktPercent}}% na Trakt)", + "synced_with_trakt_progress": "Zsynchronizowano postęp z Trakt", + "using_trakt_progress": "Używanie postępu z Trakt", + "added_to_collection_hero": "Dodano do kolekcji", + "added_to_collection_desc_hero": "Dodano do Twojej kolekcji Trakt", + "removed_from_collection_hero": "Usunięto z kolekcji", + "removed_from_collection_desc_hero": "Usunięto z Twojej kolekcji Trakt", + "mark_as_watched": "Oznacz jako obejrzane", + "mark_as_unwatched": "Oznacz jako nieobejrzane" + }, + "cast": { + "biography": "Biografia", + "known_for": "Znany(a) z", + "personal_info": "Informacje osobiste", + "born_in": "Urodzony(a) w {{place}}", + "filmography": "Filmografia", + "also_known_as": "Znany(a) również jako", + "no_info_available": "Brak dodatkowych informacji", + "as_character": "jako {{character}}", + "loading_details": "Ładowanie szczegółów...", + "years_old": "{{age}} lat", + "view_filmography": "Zobacz filmografię", + "filter": "Filtruj", + "sort_by": "Sortuj według", + "sort_popular": "Popularność", + "sort_latest": "Najnowsze", + "sort_upcoming": "Nadchodzące", + "upcoming_badge": "NADCHODZĄCE", + "coming_soon": "Wkrótce", + "filmography_count": "Filmografia • {{count}} pozycji", + "loading_filmography": "Ładowanie filmografii...", + "load_more_remaining": "Załaduj więcej (zostało {{count}})", + "alert_error_title": "Błąd", + "alert_error_message": "Nie można załadować „{{title}}”. Spróbuj ponownie później.", + "alert_ok": "OK", + "no_upcoming": "Brak nadchodzących wydań dla tego aktora/aktorki", + "no_content": "Brak treści dla tego aktora/aktorki", + "no_movies": "Brak filmów dla tego aktora/aktorki", + "no_tv": "Brak seriali dla tego aktora/aktorki" + }, + "comments": { + "title": "Komentarze Trakt", + "spoiler_warning": "⚠️ Ten komentarz zawiera spoilery. Stuknij, aby odkryć.", + "spoiler": "Spojler", + "contains_spoilers": "Zawiera spojlery", + "reveal": "Odkryj", + "vip": "VIP", + "unavailable": "Komentarze niedostępne", + "no_comments": "Brak komentarzy na Trakt", + "not_in_database": "Tej treści może nie być jeszcze w bazie Trakt", + "check_trakt": "Sprawdź Trakt" + }, + "trailers": { + "title": "Zwiastuny", + "official_trailers": "Oficjalne zwiastuny", + "official_trailer": "Oficjalny zwiastun", + "teasers": "Teasery", + "teaser": "Teaser", + "clips_scenes": "Klipy i sceny", + "clip": "Klip", + "featurettes": "Materiały dodatkowe", + "featurette": "Materiał dodatkowy", + "behind_the_scenes": "Za kulisami", + "no_trailers": "Brak dostępnych zwiastunów", + "unavailable": "Zwiastun niedostępny", + "unavailable_desc": "Nie udało się załadować zwiastuna. Spróbuj ponownie później.", + "unable_to_play": "Nie można odtworzyć zwiastuna. Spróbuj ponownie.", + "watch_on_youtube": "Obejrzyj na YouTube" + }, + "catalog": { + "no_content_found": "Nie znaleziono treści", + "no_content_filters": "Nie znaleziono treści dla wybranych filtrów", + "loading_content": "Ładowanie treści...", + "back": "Wstecz", + "in_theaters": "W kinach", + "all": "Wszystkie", + "failed_tmdb": "Nie udało się załadować treści z TMDB", + "movies": "Filmy", + "tv_shows": "Programy TV", + "channels": "Kanały" + }, + "streams": { + "back_to_episodes": "Wróć do odcinków", + "back_to_info": "Wróć do informacji", + "fetching_from": "Pobieranie z:", + "no_sources_available": "Brak dostępnych źródeł strumieniowania", + "add_sources_desc": "Dodaj źródła strumieniowania w ustawieniach", + "add_sources": "Dodaj źródła", + "finding_streams": "Szukanie dostępnych strumieni...", + "finding_best_stream": "Szukanie najlepszego strumienia do autoodtwarzania...", + "still_fetching": "Wciąż pobieram strumienie...", + "no_streams_available": "Brak dostępnych strumieni", + "starting_best_stream": "Uruchamianie najlepszego strumienia...", + "loading_more_sources": "Ładowanie większej liczby źródeł..." + }, + "player_ui": { + "via": "przez {{name}}", + "audio_tracks": "Ścieżki dźwiękowe", + "no_audio_tracks": "Brak dostępnych ścieżek dźwiękowych", + "playback_speed": "Prędkość odtwarzania", + "on_hold": "Wstrzymano", + "playback_error": "Błąd odtwarzania", + "unknown_error": "Wystąpił nieznany błąd podczas odtwarzania.", + "copy_error": "Kopiuj szczegóły błędu", + "copied_to_clipboard": "Skopiowano do schowka", + "dismiss": "Odrzuć", + "continue_watching": "Kontynuuj oglądanie", + "start_over": "Zacznij od nowa", + "resume": "Wznów", + "change_source": "Zmień źródło", + "switching_source": "Przełączanie źródła...", + "no_sources_found": "Nie znaleziono źródeł", + "sources": "Źródła", + "finding_sources": "Szukanie źródeł...", + "unknown_source": "Nieznane źródło", + "sources_limited": "Liczba źródeł może być ograniczona z powodu błędów dostawcy.", + "episodes": "Odcinki", + "specials": "Odcinki specjalne", + "season": "Sezon {{season}}", + "stream": "Strumień {{number}}", + "subtitles": "Napisy", + "built_in": "Wbudowane", + "addons": "Dodatki", + "style": "Styl", + "none": "Brak", + "search_online_subtitles": "Szukaj napisów online", + "preview": "Podgląd", + "quick_presets": "Szybkie ustawienia", + "default": "Domyślne", + "yellow": "Żółte", + "high_contrast": "Wysoki kontrast", + "large": "Duże", + "core": "Podstawowe", + "font_size": "Wielkość czcionki", + "show_background": "Pokaż tło", + "advanced": "Zaawansowane", + "position": "Pozycja", + "text_color": "Kolor tekstu", + "align": "Wyrównanie", + "bottom_offset": "Margines dolny", + "background_opacity": "Przezroczystość tła", + "text_shadow": "Cień tekstu", + "on": "Wł.", + "off": "Wył.", + "outline_color": "Kolor obrysu", + "outline": "Obrys", + "outline_width": "Szerokość obrysu", + "letter_spacing": "Odstępy między literami", + "line_height": "Wysokość linii", + "timing_offset": "Przesunięcie czasu (s)", + "visual_sync": "Synchronizacja wizualna", + "timing_hint": "Przesuń napisy wcześniej (-) lub później (+), aby zsynchronizować.", + "reset_defaults": "Przywróć domyślne", + "mark_intro_start": "Oznacz początek intro", + "mark_intro_end": "Oznacz koniec intro", + "intro_start_marked": "Oznaczono początek intro", + "intro_submitted": "Pomyślnie przesłano intro", + "intro_submit_failed": "Nie udało się przesłać intro" + }, + "downloads": { + "title": "Pobrane", + "no_downloads": "Brak pobranych plików", + "no_downloads_desc": "Pobrane treści pojawią się tutaj, aby umożliwić oglądanie offline", + "explore": "Przeglądaj treści", + "path_copied": "Skopiowano ścieżkę", + "path_copied_desc": "Ścieżka do pliku lokalnego została skopiowana do schowka", + "copied": "Skopiowano", + "incomplete": "Pobieranie nieukończone", + "incomplete_desc": "Pobieranie jeszcze się nie zakończyło", + "not_available": "Niedostępne", + "not_available_desc": "Ścieżka do pliku lokalnego jest dostępna dopiero po zakończeniu pobierania.", + "status_downloading": "Pobieranie", + "status_completed": "Zakończono", + "status_paused": "Wstrzymano", + "status_error": "Błąd", + "status_queued": "W kolejce", + "status_unknown": "Nieznany", + "provider": "Dostawca", + "streaming_playlist_warning": "Może nie działać – lista odtwarzania strumieniowego", + "remaining": "Pozostało", + "not_ready": "Pobieranie nie jest jeszcze gotowe", + "not_ready_desc": "Proszę czekać na zakończenie pobierania.", + "filter_all": "Wszystkie", + "filter_active": "Aktywne", + "filter_done": "Gotowe", + "filter_paused": "Wstrzymane", + "no_filter_results": "Brak pobrań dla filtra: {{filter}}", + "try_different_filter": "Spróbuj wybrać inny filtr", + "limitations_title": "Ograniczenia pobierania", + "limitations_msg": "• Pliki mniejsze niż 1MB to zazwyczaj listy odtwarzania M3U8 i nie można ich pobrać do oglądania offline. Działają one tylko ze strumieniowaniem online i zawierają linki do segmentów wideo, a nie samą treść wideo.", + "remove_title": "Usuń pobrane", + "remove_confirm": "Usunąć „{{title}}”{{season_episode}}?", + "cancel": "Anuluj", + "remove": "Usuń" + }, + "addons": { + "title": "Dodatki", + "reorder_mode": "Tryb zmiany kolejności", + "reorder_info": "Dodatki na górze mają wyższy priorytet podczas ładowania treści", + "add_addon_placeholder": "URL dodatku", + "add_button": "Dodaj dodatek", + "my_addons": "Moje dodatki", + "community_addons": "Dodatki społeczności", + "no_addons": "Brak zainstalowanych dodatków", + "uninstall_title": "Odinstaluj dodatek", + "uninstall_message": "Czy na pewno chcesz odinstalować {{name}}?", + "uninstall_button": "Odinstaluj", + "install_success": "Dodatek zainstalowany pomyślnie", + "install_error": "Nie udało się zainstalować dodatku", + "load_error": "Nie udało się załadować dodatków", + "fetch_error": "Nie udało się pobrać szczegółów dodatku", + "invalid_url": "Proszę podać prawidłowy URL dodatku", + "configure": "Konfiguruj", + "version": "Wersja: {{version}}", + "installed_addons": "ZAINSTALOWANE DODATKI", + "reorder_drag_title": "PRZECIĄGNIJ DODATKI, ABY ZMIENIĆ KOLEJNOŚĆ", + "install": "Instaluj", + "config_unavailable_title": "Konfiguracja niedostępna", + "config_unavailable_msg": "Nie można określić adresu URL konfiguracji dla tego dodatku.", + "cannot_open_config_title": "Nie można otworzyć konfiguracji", + "cannot_open_config_msg": "Nie można otworzyć adresu URL konfiguracji ({{url}}). Dodatek może nie posiadać strony konfiguracji.", + "description": "Opis", + "supported_types": "Obsługiwane typy", + "catalogs": "Katalogi", + "no_description": "Brak dostępnego opisu", + "overview": "PRZEGLĄD", + "no_categories": "Brak kategorii", + "pre_installed": "PREINSTALOWANE" + }, + "trakt": { + "title": "Ustawienia Trakt", + "settings_title": "Ustawienia Trakt", + "connect_title": "Połącz z Trakt", + "connect_desc": "Synchronizuj historię oglądania, listę do obejrzenia i kolekcję z Trakt.tv", + "sign_in": "Zaloguj się przez Trakt", + "sign_out": "Wyloguj się", + "sign_out_confirm": "Czy na pewno chcesz wylogować się z konta Trakt?", + "joined": "Dołączono {{date}}", + "sync_settings_title": "Ustawienia synchronizacji", + "sync_info": "Po połączeniu z Trakt pełna historia jest synchronizowana bezpośrednio z API i nie jest zapisywana lokalnie. Twoja lista „Kontynuuj oglądanie” odzwierciedla ogólny postęp na Trakt.", + "auto_sync_label": "Automatyczna synchronizacja postępu", + "auto_sync_desc": "Automatycznie przesyłaj postęp oglądania do Trakt", + "import_history_label": "Importuj historię oglądania", + "import_history_desc": "Użyj „Synchronizuj teraz”, aby zaimportować historię i postępy z Trakt", + "sync_now_button": "Synchronizuj teraz", + "display_settings_title": "Ustawienia wyświetlania", + "show_comments_label": "Pokaż komentarze Trakt", + "show_comments_desc": "Wyświetlaj komentarze Trakt w szczegółach treści, jeśli są dostępne", + "maintenance_title": "Przerwa techniczna", + "maintenance_unavailable": "Trakt niedostępny", + "maintenance_desc": "Integracja z Trakt jest tymczasowo wstrzymana z powodu prac konserwacyjnych. Synchronizacja i autoryzacja są wyłączone do czasu zakończenia prac.", + "maintenance_button": "Usługa w trakcie konserwacji", + "auth_success_title": "Połączono pomyślnie", + "auth_success_msg": "Twoje konto Trakt zostało pomyślnie połączone.", + "auth_error_title": "Błąd autoryzacji", + "auth_error_msg": "Nie udało się ukończyć autoryzacji w serwisie Trakt.", + "auth_error_generic": "Wystąpił błąd podczas autoryzacji.", + "sign_out_error": "Nie udało się wylogować z Trakt.", + "sync_complete_title": "Synchronizacja zakończona", + "sync_success_msg": "Pomyślnie zsynchronizowano postęp oglądania z Trakt.", + "sync_error_msg": "Synchronizacja nie powiodła się. Spróbuj ponownie." + }, + "simkl": { + "title": "Ustawienia Simkl", + "settings_title": "Ustawienia Simkl", + "connect_title": "Połącz z Simkl", + "connect_desc": "Synchronizuj historię i śledź to, co oglądasz", + "sign_in": "Zaloguj się przez Simkl", + "sign_out": "Odłącz", + "sign_out_confirm": "Czy na pewno chcesz odłączyć konto Simkl?", + "syncing_desc": "Twoje obejrzane pozycje są synchronizowane z Simkl.", + "auth_success_title": "Połączono pomyślnie", + "auth_success_msg": "Twoje konto Simkl zostało pomyślnie połączone.", + "auth_error_title": "Błąd autoryzacji", + "auth_error_msg": "Nie udało się ukończyć autoryzacji w serwisie Simkl.", + "auth_error_generic": "Wystąpił błąd podczas autoryzacji.", + "sign_out_error": "Nie udało się odłączyć od Simkl.", + "config_error_title": "Błąd konfiguracji", + "config_error_msg": "Brak Simkl Client ID w zmiennych środowiskowych.", + "conflict_title": "Konflikt", + "conflict_msg": "Nie możesz połączyć się z Simkl, gdy połączony jest Trakt. Proszę najpierw odłączyć Trakt.", + "disclaimer": "Nuvio nie jest powiązane z serwisem Simkl." + }, + "tmdb_settings": { + "title": "Ustawienia TMDb", + "metadata_enrichment": "Wzbogacanie metadanych", + "metadata_enrichment_desc": "Ulepsz metadane treści o dane z TMDb, aby uzyskać lepsze szczegóły i informacje.", + "enable_enrichment": "Włącz wzbogacanie", + "enable_enrichment_desc": "Uzupełnia metadane dodatków o dane z TMDb dotyczące obsady, klasyfikacji wiekowej, logo/plakatów i produkcji.", + "localized_text": "Zlokalizowany tekst", + "localized_text_desc": "Pobieraj tytuły i opisy w preferowanym języku z bazy TMDb.", + "language": "Język", + "change": "Zmień", + "logo_preview": "Podgląd logo", + "logo_preview_desc": "Podgląd pokazuje, jak zlokalizowane logo będzie wyglądać w wybranym języku.", + "example": "Przykład:", + "no_logo": "Brak dostępnego logo", + "enrichment_options": "Opcje wzbogacania", + "enrichment_options_desc": "Wybierz, jakie dane mają być pobierane z TMDb. Wyłączone opcje będą korzystać z danych dodatku.", + "cast_crew": "Obsada i ekipa", + "cast_crew_desc": "Aktorzy, reżyserzy, scenarzyści wraz ze zdjęciami profilowymi", + "title_description": "Tytuł i opis", + "title_description_desc": "Używaj zlokalizowanego tytułu i opisu z TMDb", + "title_logos": "Logo tytułowe", + "title_logos_desc": "Wysokiej jakości grafiki z tytułami", + "banners_backdrops": "Bannery i tła", + "banners_backdrops_desc": "Obrazy tła w wysokiej rozdzielczości", + "certification": "Klasyfikacja treści", + "certification_desc": "Ograniczenia wiekowe (PG-13, R, TV-MA itp.)", + "recommendations": "Rekomendacje", + "recommendations_desc": "Sugestie podobnych treści", + "episode_data": "Dane odcinków", + "episode_data_desc": "Miniatury odcinków, informacje i dane zapasowe dla seriali", + "season_posters": "Plakaty sezonów", + "season_posters_desc": "Grafiki plakatów przypisane do konkretnych sezonów", + "production_info": "Informacje o produkcji", + "production_info_desc": "Stacje telewizyjne i firmy produkcyjne wraz z logo", + "movie_details": "Szczegóły filmu", + "movie_details_desc": "Budżet, przychody, czas trwania, hasło reklamowe", + "tv_details": "Szczegóły serialu", + "tv_details_desc": "Status, liczba sezonów, sieci, twórcy", + "movie_collections": "Kolekcje filmowe", + "movie_collections_desc": "Serie filmowe (Marvel, Gwiezdne Wojny itp.)", + "api_configuration": "Konfiguracja API", + "api_configuration_desc": "Skonfiguruj dostęp do API TMDb dla rozszerzonej funkcjonalności.", + "custom_api_key": "Własny klucz API", + "custom_api_key_desc": "Użyj własnego klucza API TMDb dla lepszej wydajności i dedykowanych limitów.", + "custom_key_active": "Własny klucz API aktywny", + "api_key_required": "Klucz API wymagany", + "api_key_placeholder": "Wklej swój klucz API TMDb (v3)", + "how_to_get_key": "Jak uzyskać klucz API TMDb?", + "built_in_key_msg": "Obecnie używasz wbudowanego klucza API. Rozważ użycie własnego klucza dla lepszej wydajności.", + "cache_size": "Rozmiar pamięci podręcznej", + "clear_cache": "Wyczyść pamięć podręczną", + "cache_days": "Dane z TMDb są przechowywane przez 7 dni w celu poprawy wydajności", + "choose_language": "Wybierz język", + "choose_language_desc": "Wybierz preferowany język dla treści z TMDb", + "popular": "Popularne", + "all_languages": "Wszystkie języki", + "search_results": "Wyniki wyszukiwania", + "no_languages_found": "Nie znaleziono języków dla „{{query}}”", + "clear_search": "Wyczyść wyszukiwanie", + "clear_cache_title": "Wyczyść pamięć podręczną TMDB", + "clear_cache_msg": "To spowoduje usunięcie wszystkich zapisanych danych TMDB ({{size}}). Może to tymczasowo spowolnić ładowanie do czasu odbudowania pamięci.", + "clear_cache_success": "Pamięć podręczna TMDB została wyczyszczona.", + "clear_cache_error": "Nie udało się wyczyścić pamięci podręcznej.", + "clear_api_key_title": "Usuń klucz API", + "clear_api_key_msg": "Czy na pewno chcesz usunąć własny klucz API i wrócić do domyślnego?", + "clear_api_key_success": "Klucz API został usunięty", + "clear_api_key_error": "Nie udało się usunąć klucza API", + "empty_api_key": "Klucz API nie może być pusty.", + "invalid_api_key": "Nieprawidłowy klucz API. Sprawdź i spróbuj ponownie.", + "save_error": "Wystąpił błąd podczas zapisywania. Spróbuj ponownie.", + "using_builtin_key": "Używasz teraz wbudowanego klucza API TMDb.", + "using_custom_key": "Używasz teraz własnego klucza API TMDb.", + "enter_custom_key": "Proszę wprowadzić i zapisać własny klucz API TMDb.", + "key_verified": "Klucz API został zweryfikowany i zapisany pomyślnie." + }, + "settings": { + "language": "Język", + "select_language": "Wybierz język", + "english": "Angielski", + "portuguese": "Portugalski", + "portuguese_br": "Portugalski (Brazylia)", + "portuguese_pt": "Portugalski (Portugalia)", + "german": "Niemiecki", + "arabic": "Arabski", + "spanish": "Hiszpański", + "french": "Francuski", + "italian": "Włoski", + "croatian": "Chorwacki", + "chinese": "Chiński (Uproszczony)", + "hindi": "Hindi", + "serbian": "Serbski", + "hebrew": "Hebrajski", + "bulgarian": "Bułgarski", + "polish": "Polski", + "czech": "Czeski", + "turkish": "Turecki", + "slovenian": "Słoweński", + "macedonian": "Macedoński", + "russian": "Rosyjski", + "filipino": "Filipiński", + "dutch_nl": "Holenderski (Niderlandy)", + "romanian": "Rumuński", + "albanian": "Albański", + "account": "Konto", + "content_discovery": "Treści i odkrywanie", + "appearance": "Wygląd", + "integrations": "Integracje", + "playback": "Odtwarzanie", + "backup_restore": "Kopia zapasowa i przywracanie", + "updates": "Aktualizacje", + "about": "O aplikacji", + "developer": "Deweloper", + "cache": "Pamięć podręczna", + "title": "Ustawienia", + "settings_title": "Ustawienia", + "sign_in_sync": "Zaloguj się, aby synchronizować", + "add_catalogs_sources": "Dodatki, katalogi i źródła", + "player_trailers_downloads": "Odtwarzacz, zwiastuny, pobieranie", + "mdblist_tmdb_ai": "MDBList, TMDB, AI", + "check_updates": "Sprawdź aktualizacje", + "clear_mdblist_cache": "Wyczyść pamięć MDBList", + "cache_management": "ZARZĄDZANIE PAMIĘCIĄ PODRĘCZNĄ", + "downloads_counter": "pobrań i wciąż rośnie", + "made_with_love": "Stworzone z ❤️ przez Tapframe i przyjaciół", + "sections": { + "information": "INFORMACJE", + "account": "KONTO", + "theme": "MOTYW", + "layout": "UKŁAD", + "sources": "ŹRÓDŁA", + "catalogs": "KATALOGI", + "discovery": "ODKRYWANIE", + "metadata": "METADANE", + "ai_assistant": "ASYSTENT AI", + "video_player": "ODTWARZACZ WIDEO", + "audio_subtitles": "AUDIO I NAPISY", + "media": "MEDIA", + "notifications": "POWIADOMIENIA", + "testing": "TESTOWANIE", + "danger_zone": "STREFA NIEBEZPIECZEŃSTWA" + }, + "items": { + "legal": "Informacje prawne i zastrzeżenia", + "privacy_policy": "Polityka prywatności", + "report_issue": "Zgłoś problem", + "version": "Wersja", + "contributors": "Współtwórcy", + "view_contributors": "Zobacz wszystkich współtwórców", + "theme": "Motyw", + "episode_layout": "Układ odcinków", + "streams_backdrop": "Tło strumieni", + "streams_backdrop_desc": "Pokaż rozmyte tło podczas strumieniowania na urządzeniach mobilnych", + "addons": "Dodatki", + "installed": "zainstalowane", + "debrid_integration": "Integracja Debrid", + "debrid_desc": "Połącz Torbox", + "plugins": "Wtyczki", + "plugins_desc": "Zarządzaj wtyczkami i repozytoriami", + "catalogs": "Katalogi", + "active": "aktywne", + "home_screen": "Ekran główny", + "home_screen_desc": "Układ i zawartość", + "continue_watching": "Kontynuuj oglądanie", + "continue_watching_desc": "Zachowanie pamięci podręcznej i odtwarzania", + "show_discover": "Pokaż sekcję odkrywania", + "show_discover_desc": "Wyświetlaj odkryte treści w wyszukiwarce", + "mdblist": "MDBList", + "mdblist_connected": "Połączono", + "mdblist_desc": "Włącz, aby dodać oceny i recenzje", + "simkl": "Simkl", + "simkl_connected": "Połączono", + "simkl_desc": "Śledź to, co oglądasz", + "tmdb": "TMDB", + "tmdb_desc": "Dostawca metadanych i logo", + "openrouter": "OpenRouter API", + "openrouter_connected": "Połączono", + "openrouter_desc": "Dodaj klucz API, aby włączyć czat AI", + "video_player": "Odtwarzacz wideo", + "built_in": "Wbudowany", + "external": "Zewnętrzny", + "preferred_audio": "Preferowany język audio", + "preferred_subtitle": "Preferowany język napisów", + "subtitle_source": "Priorytet źródła napisów", + "auto_select_subs": "Automatyczny wybór napisów", + "auto_select_subs_desc": "Automatycznie wybieraj napisy pasujące do Twoich preferencji", + "show_trailers": "Pokaż zwiastuny", + "show_trailers_desc": "Wyświetlaj zwiastuny w sekcji głównej", + "enable_downloads": "Włącz pobieranie", + "enable_downloads_desc": "Pokaż kartę Pobrane i włącz zapisywanie strumieni", + "notifications": "Powiadomienia", + "notifications_desc": "Przypomnienia o odcinkach", + "developer_tools": "Narzędzia deweloperskie", + "developer_tools_desc": "Opcje testowania i debugowania", + "test_onboarding": "Testuj powitanie (Onboarding)", + "reset_onboarding": "Resetuj powitanie", + "test_announcement": "Testuj ogłoszenie", + "test_announcement_desc": "Pokaż nakładkę „Co nowego”", + "reset_campaigns": "Resetuj kampanie", + "reset_campaigns_desc": "Wyczyść wyświetlenia kampanii", + "clear_all_data": "Wyczyść wszystkie dane", + "clear_all_data_desc": "Zresetuj wszystkie ustawienia i dane w pamięci podręcznej" + }, + "options": { + "horizontal": "Poziomy", + "vertical": "Pionowy", + "internal_first": "Najpierw wewnętrzne", + "internal_first_desc": "Preferuj napisy wbudowane, następnie zewnętrzne", + "external_first": "Najpierw zewnętrzne", + "external_first_desc": "Preferuj napisy z dodatków, następnie wbudowane", + "any_available": "Dowolne dostępne", + "any_available_desc": "Użyj pierwszej dostępnej ścieżki napisów" + }, + "clear_data_desc": "To zresetuje wszystkie ustawienia i wyczyści pamięć podręczną. Czy na pewno?", + "app_updates": "Aktualizacje aplikacji", + "about_nuvio": "O Nuvio" + }, + "privacy": { + "title": "Prywatność i Dane", + "settings_desc": "Kontrola telemetrii i zbierania danych", + "info_title": "Twoja prywatność jest ważna", + "info_description": "Kontroluj, jakie dane są zbierane i udostępniane. Analityka jest domyślnie wyłączona, a raporty o błędach są domyślnie anonimowe.", + "analytics_enabled_title": "Analityka włączona", + "analytics_enabled_message": "Dane o użytkowaniu będą zbierane w celu ulepszania aplikacji. Możesz to wyłączyć w dowolnym momencie.", + "disable_error_reporting_title": "Wyłączyć raportowanie błędów?", + "disable_error_reporting_message": "Wyłączenie raportowania błędów oznacza, że nie będziemy powiadamiani o awariach lub problemach, których doświadczasz. Może to wpłynąć na naszą zdolność do naprawiania błędów.", + "enable_session_replay_title": "Włączyć powtórkę sesji?", + "enable_session_replay_message": "Powtórka sesji rejestruje ekran w momencie wystąpienia błędu, aby pomóc nam zrozumieć, co się stało. Może to zarejestrować treści widoczne na ekranie.", + "enable_pii_title": "Włączyć zbieranie danych PII?", + "enable_pii_message": "Pozwala to na zbieranie danych osobowych, takich jak adres IP i szczegóły urządzenia. Dane te pomagają diagnozować problemy, ale zwiększają ryzyko naruszenia prywatności.", + "disable_all_title": "Wyłączyć całą telemetrię?", + "disable_all_message": "Spowoduje to wyłączenie analityki, raportowania błędów i powtórek sesji. Nie będziemy otrzymywać żadnych danych o użytkowaniu ani awariach aplikacji.", + "disable_all_button": "Wyłącz wszystko", + "all_disabled_title": "Telemetria wyłączona", + "all_disabled_message": "Wszelkie zbieranie danych zostało wyłączone. Zmiany wejdą w życie po ponownym uruchomieniu aplikacji.", + "reset_title": "Przywróć zalecane", + "reset_message": "Ustawienia prywatności zostały zresetowane do zalecanych wartości domyślnych (raportowanie błędów włączone, analityka wyłączona).", + "section_analytics": "ANALITYKA", + "analytics_title": "Statystyki użytkowania", + "analytics_description": "Zbieraj anonimowe wzorce użytkowania i widoki ekranu", + "section_error_reporting": "RAPORTOWANIE BŁĘDÓW", + "error_reporting_title": "Raporty o awariach", + "error_reporting_description": "Wysyłaj anonimowe raporty o awariach, aby poprawić stabilność", + "session_replay_title": "Powtórka sesji", + "session_replay_description": "Rejestruj ekran w momencie wystąpienia błędu", + "pii_title": "Dołącz info o urządzeniu", + "pii_description": "Wysyłaj adres IP i szczegóły urządzenia wraz z raportami", + "section_quick_actions": "SZYBKIE AKCJE", + "disable_all": "Wyłącz całą telemetrię", + "disable_all_desc": "Wyłącz całkowicie zbieranie danych", + "reset_recommended": "Przywróć zalecane", + "reset_recommended_desc": "Ustawienia prywatności z raportowaniem błędów", + "section_learn_more": "DOWIEDZ SIĘ WIĘCEJ", + "privacy_policy": "Polityka prywatności", + "current_settings": "Podsumowanie obecnych ustawień", + "summary_analytics": "Analityka", + "summary_errors": "Raporty o błędach", + "summary_replay": "Powtórka sesji", + "summary_pii": "Info o urządzeniu", + "restart_note_detailed": "* Zmiany w analityce i raportowaniu błędów wchodzą w życie natychmiast. Powtórka sesji i ustawienia PII wymagają restartu aplikacji." + }, + "ai_settings": { + "title": "Asystent AI", + "info_title": "Czat oparty na AI", + "info_desc": "Zadawaj pytania dotyczące dowolnego filmu lub odcinka serialu, korzystając z zaawansowanej sztucznej inteligencji. Uzyskaj wgląd w fabułę, postacie, motywy, ciekawostki i wiele więcej – wszystko w oparciu o kompleksowe dane TMDB.", + "feature_1": "Analiza i kontekst specyficzny dla odcinka", + "feature_2": "Wyjaśnienia fabuły i wgląd w postacie", + "feature_3": "Ciekawostki i fakty zza kulis", + "feature_4": "Twój własny, darmowy klucz API OpenRouter", + "api_key_section": "KLUCZ API OPENROUTER", + "api_key_label": "Klucz API", + "api_key_desc": "Wprowadź swój klucz API OpenRouter, aby włączyć funkcje czatu AI", + "save_api_key": "Zapisz klucz API", + "saving": "Zapisywanie...", + "update": "Aktualizuj", + "remove": "Usuń", + "get_free_key": "Pobierz darmowy klucz API z OpenRouter", + "enable_chat": "Włącz czat AI", + "enable_chat_desc": "Gdy ta opcja jest włączona, na stronach treści pojawi się przycisk „Zapytaj AI”.", + "chat_enabled": "Czat AI włączony", + "chat_enabled_desc": "Możesz teraz zadawać pytania dotyczące filmów i seriali. Szukaj przycisku „Zapytaj AI” na stronach treści!", + "how_it_works": "Jak to działa", + "how_it_works_desc": "• OpenRouter zapewnia dostęp do wielu modeli AI\n• Twój klucz API pozostaje prywatny i bezpieczny\n• Darmowy poziom zawiera hojne limity użytkowania\n• Czatuj z uwzględnieniem kontekstu konkretnych odcinków/filmów\n• Otrzymuj szczegółowe analizy i wyjaśnienia", + "error_invalid_key": "Proszę wprowadzić poprawny klucz API", + "error_key_format": "Klucze API OpenRouter powinny zaczynać się od „sk-or-”", + "success_saved": "Klucz API OpenRouter zapisany pomyślnie!", + "error_save": "Nie udało się zapisać klucza API", + "confirm_remove_title": "Usuń klucz API", + "confirm_remove_msg": "Czy na pewno chcesz usunąć swój klucz API OpenRouter? Spowoduje to wyłączenie funkcji czatu AI.", + "success_removed": "Klucz API został usunięty", + "error_remove": "Nie udało się usunąć klucza API" + }, + "catalog_settings": { + "title": "Katalogi", + "layout_phone": "UKŁAD EKRANU KATALOGU (TELEFON)", + "posters_per_row": "Plakaty w rzędzie", + "auto": "Auto", + "show_titles": "Pokaż tytuły na plakatach", + "show_titles_desc": "Wyświetlaj tekst tytułu pod każdym plakatem", + "phone_only_hint": "Dotyczy tylko telefonów. Tablety zachowują układ adaptacyjny.", + "catalogs_group": "Katalogi", + "enabled_count": "{{enabled}} z {{total}} włączonych", + "rename_hint": "Przytrzymaj dłużej katalog, aby zmienić jego nazwę", + "rename_modal_title": "Zmień nazwę katalogu", + "rename_placeholder": "Wprowadź nową nazwę katalogu", + "error_save_name": "Nie udało się zapisać własnej nazwy." + }, + "continue_watching_settings": { + "title": "Kontynuuj oglądanie", + "playback_behavior": "ZACHOWANIE ODTWARZANIA", + "use_cached": "Używaj zapisanych strumieni", + "use_cached_desc": "Gdy ta opcja jest włączona, kliknięcie pozycji w „Kontynuuj oglądanie” otworzy odtwarzacz bezpośrednio przy użyciu wcześniej odtworzonych strumieni. Gdy wyłączona, otwiera ekran treści.", + "open_metadata": "Otwórz ekran szczegółów", + "open_metadata_desc": "Gdy zapisane strumienie są wyłączone, otwórz ekran metadanych zamiast ekranu wyboru strumieni. Pozwala to zobaczyć szczegóły i ręcznie wybrać źródło.", + "card_appearance": "WYGLĄD KARTY", + "card_style": "Styl karty", + "card_style_desc": "Wybierz, jak pozycje „Kontynuuj oglądanie” mają wyglądać na ekranie głównym", + "wide": "Szeroka", + "poster": "Plakat", + "cache_settings": "USTAWIENIA PAMIĘCI PODRĘCZNEJ", + "cache_duration": "Czas przechowywania strumienia", + "cache_duration_desc": "Jak długo przechowywać linki do strumieni, zanim wygasną", + "important_note": "Ważna uwaga", + "important_note_text": "Nie wszystkie linki do strumieni pozostają aktywne przez cały czas przechowywania w pamięci. Dłuższy czas może skutkować wygaśnięciem linków. Jeśli zapisany link zawiedzie, aplikacja pobierze nowe źródła.", + "how_it_works": "Jak to działa", + "how_it_works_cached": "• Strumienie są zapisywane na wybrany czas po odtworzeniu\n• Zapisane strumienie są weryfikowane przed użyciem\n• Jeśli pamięć wygasła, następuje powrót do ekranu treści\n• „Używaj zapisanych strumieni” kontroluje nawigację bezpośrednio do odtwarzacza\n• „Otwórz ekran szczegółów” pojawia się tylko, gdy zapisane strumienie są wyłączone", + "how_it_works_uncached": "• Gdy zapisane strumienie są wyłączone, kliknięcie pozycji otwiera ekrany treści\n• Opcja „Otwórz ekran szczegółów” kontroluje, który ekran otworzyć\n• Ekran metadanych pokazuje szczegóły i pozwala na ręczny wybór\n• Ekran strumieni pokazuje dostępne źródła do natychmiastowego odtworzenia", + "changes_saved": "Zmiany zapisane", + "min": "min", + "hour": "godz.", + "hours": "godz." + }, + "contributors": { + "title": "Współtwórcy", + "special_mentions": "Specjalne wyróżnienia", + "tab_contributors": "Współtwórcy", + "tab_special": "Specjalne", + "tab_donors": "Darczyńcy", + "manager_role": "Community Manager", + "manager_desc": "Zarządza społecznościami Discord i Reddit dla Nuvio", + "sponsor_role": "Sponsor serwera", + "sponsor_desc": "Sponsoruje infrastrukturę serwerową dla Nuvio", + "mod_role": "Moderator Discord", + "mod_desc": "Pomaga moderować społeczność Nuvio na Discordzie", + "loading": "Ładowanie...", + "discord_user": "Użytkownik Discord", + "contributions": "wkład", + "gratitude_title": "Jesteśmy wdzięczni za każdy wkład", + "gratitude_desc": "Każda linijka kodu, zgłoszenie błędu i sugestia pomaga ulepszać Nuvio dla wszystkich", + "special_thanks_title": "Specjalne podziękowania", + "special_thanks_desc": "Te niesamowite osoby pomagają utrzymać społeczność Nuvio i serwery online", + "donors_desc": "Dziękujemy za wiarę w to, co budujemy. Wasze wsparcie sprawia, że Nuvio pozostaje darmowe i stale się rozwija.", + "latest_donations": "Najnowsze", + "leaderboard": "Ranking", + "loading_donors": "Ładowanie darczyńców...", + "no_donors": "Brak darczyńców", + "error_rate_limit": "Przekroczono limit API GitHub. Spróbuj ponownie później lub odśwież.", + "error_failed": "Nie udało się załadować współtwórców. Sprawdź połączenie internetowe.", + "retry": "Spróbuj ponownie", + "no_contributors": "Nie znaleziono współtwórców", + "loading_contributors": "Ładowanie współtwórców..." + }, + "debrid": { + "title": "Integracja Debrid", + "description_torbox": "Odblokuj strumienie w jakości 4K i błyskawiczne prędkości dzięki integracji z Torbox. Wprowadź swój klucz API poniżej, aby natychmiast ulepszyć swoje wrażenia.", + "description_torrentio": "Skonfiguruj Torrentio, aby otrzymywać strumienie torrent dla filmów i seriali. Usługa debrid jest wymagana do odtwarzania treści.", + "tab_torbox": "TorBox", + "tab_torrentio": "Torrentio", + "status_connected": "Połączono", + "status_disconnected": "Rozłączono", + "enable_addon": "Włącz dodatek", + "disconnect_button": "Rozłącz i usuń", + "disconnect_loading": "Rozłączanie...", + "account_info": "Informacje o koncie", + "plan": "Plan", + "plan_free": "Darmowy", + "plan_essential": "Essential ($3/mc)", + "plan_pro": "Pro ($10/mc)", + "plan_standard": "Standard ($5/mc)", + "plan_unknown": "Nieznany", + "expires": "Wygasa", + "downloaded": "Pobrano", + "status_active": "Aktywny", + "connected_title": "✓ Połączono z TorBox", + "connected_desc": "Twój dodatek TorBox jest aktywny i dostarcza strumienie premium.", + "configure_title": "Konfiguruj dodatek", + "configure_desc": "Spersonalizuj swoje wrażenia. Sortuj według jakości, filtruj rozmiary plików i zarządzaj innymi ustawieniami.", + "open_settings": "Otwórz ustawienia", + "what_is_debrid": "Czym jest usługa Debrid?", + "enter_api_key": "Wprowadź swój klucz API", + "connect_button": "Połącz i zainstaluj", + "connecting": "Łączenie...", + "unlock_speeds_title": "Odblokuj prędkość Premium", + "unlock_speeds_desc": "Wykup subskrypcję Torbox, aby uzyskać dostęp do zapisanych strumieni wysokiej jakości bez buforowania.", + "get_subscription": "Kup subskrypcję", + "powered_by": "Obsługiwane przez", + "disclaimer_torbox": "Nuvio nie jest w żaden sposób powiązane z Torbox.", + "disclaimer_torrentio": "Nuvio nie jest w żaden sposób powiązane z Torrentio.", + "installed_badge": "✓ ZAINSTALOWANO", + "promo_title": "⚡ Potrzebujesz usługi Debrid?", + "promo_desc": "Wybierz TorBox dla błyskawicznego strumieniowania 4K bez buforowania. Torrenty premium i natychmiastowe pobieranie.", + "promo_button": "Kup subskrypcję TorBox", + "service_label": "Usługa Debrid *", + "api_key_label": "Klucz API *", + "sorting_label": "Sortowanie", + "exclude_qualities": "Wyklucz jakości", + "priority_languages": "Języki priorytetowe", + "max_results": "Maks. wyników", + "additional_options": "Opcje dodatkowe", + "no_download_links": "Nie pokazuj linków do pobierania", + "no_debrid_catalog": "Nie pokazuj katalogu debrid", + "install_button": "Instaluj Torrentio", + "installing": "Instalowanie...", + "update_button": "Aktualizuj konfigurację", + "updating": "Aktualizacja...", + "remove_button": "Usuń Torrentio", + "error_api_required": "Klucz API wymagany", + "error_api_required_desc": "Proszę wprowadzić klucz API usługi debrid, aby zainstalować Torrentio.", + "success_installed": "Dodatek Torrentio zainstalowany pomyślnie!", + "success_removed": "Dodatek Torrentio został usunięty", + "alert_disconnect_title": "Rozłącz Torbox", + "alert_disconnect_msg": "Czy na pewno chcesz rozłączyć Torbox? Spowoduje to usunięcie dodatku i wyczyszczenie klucza API." + }, + "home_screen": { + "title": "Ustawienia ekranu głównego", + "changes_applied": "Zmiany zastosowane", + "display_options": "OPCJE WYŚWIETLANIA", + "show_hero": "Pokaż sekcję Hero", + "show_hero_desc": "Wyróżnione treści na górze", + "show_this_week": "Pokaż sekcję „W tym tygodniu”", + "show_this_week_desc": "Nowe odcinki z obecnego tygodnia", + "select_catalogs": "Wybierz katalogi", + "all_catalogs": "Wszystkie katalogi", + "selected": "wybrane", + "hero_layout": "Układ sekcji Hero", + "layout_legacy": "Klasyczny", + "layout_carousel": "Karuzela", + "layout_appletv": "Apple TV", + "layout_desc": "Banner na całą szerokość, przesuwane karty lub styl Apple TV", + "featured_source": "Źródło wyróżnionych", + "using_catalogs": "Używanie katalogów", + "manage_selected_catalogs": "Zarządzaj wybranymi katalogami", + "dynamic_bg": "Dynamiczne tło Hero", + "dynamic_bg_desc": "Rozmyty banner za karuzelą", + "performance_note": "Może wpływać na wydajność na słabszych urządzeniach.", + "posters": "Plakaty", + "show_titles": "Pokaż tytuły", + "poster_size": "Rozmiar plakatów", + "poster_corners": "Narożniki plakatów", + "size_small": "Małe", + "size_medium": "Średnie", + "size_large": "Duże", + "corners_square": "Kwadratowe", + "corners_rounded": "Zaokrąglone", + "corners_pill": "Pastylka", + "about_these_settings": "O TYCH USTAWIENIACH", + "about_desc": "Te ustawienia kontrolują sposób wyświetlania treści na ekranie głównym. Zmiany są stosowane natychmiast.", + "hero_catalogs": { + "title": "Katalogi sekcji Hero", + "select_all": "Zaznacz wszystko", + "clear_all": "Wyczyść wszystko", + "info": "Wybierz, które katalogi mają być wyświetlane w sekcji Hero. Jeśli żadne nie zostaną wybrane, użyte zostaną wszystkie. Pamiętaj o zapisaniu zmian.", + "settings_saved": "Ustawienia zapisane", + "error_load": "Nie udało się załadować katalogów", + "movies": "Filmy", + "tv_shows": "Seriale" + } + }, + "calendar": { + "title": "Kalendarz", + "loading": "Ładowanie kalendarza...", + "no_scheduled_episodes": "Brak zaplanowanych odcinków", + "check_back_later": "Sprawdź ponownie później", + "showing_episodes_for": "Odcinki na dzień: {{date}}", + "show_all_episodes": "Pokaż wszystkie odcinki", + "no_episodes_for": "Brak odcinków na dzień {{date}}", + "no_upcoming_found": "Nie znaleziono nadchodzących odcinków", + "add_series_desc": "Dodaj seriale do biblioteki, aby zobaczyć ich nadchodzące odcinki tutaj" + }, + "mdblist": { + "title": "Źródła ocen", + "status_disabled": "MDBList wyłączony", + "status_active": "Klucz API aktywny", + "status_required": "Klucz API wymagany", + "status_disabled_desc": "Funkcjonalność MDBList jest obecnie wyłączona.", + "status_active_desc": "Oceny z MDBList są włączone.", + "status_required_desc": "Dodaj swój klucz poniżej, aby włączyć oceny.", + "enable_toggle": "Włącz MDBList", + "enable_toggle_desc": "Włącz/wyłącz wszystkie funkcje MDBList", + "api_section": "Klucz API", + "placeholder": "Wklej swój klucz API MDBList", + "save": "Zapisz", + "clear": "Wyczyść klucz", + "rating_providers": "Dostawcy ocen", + "rating_providers_desc": "Wybierz, które oceny mają być wyświetlane w aplikacji", + "how_to": "Jak uzyskać klucz API", + "step_1": "Zaloguj się na", + "step_1_link": "stronie MDBList", + "step_2": "Przejdź do sekcji", + "step_2_settings": "Ustawienia", + "step_2_api": "API", + "step_2_end": ".", + "step_3": "Wygeneruj nowy klucz i skopiuj go.", + "go_to_website": "Przejdź do MDBList", + "alert_clear_title": "Usuń klucz API", + "alert_clear_msg": "Czy na pewno chcesz usunąć zapisany klucz API?", + "success_saved": "Klucz API zapisany pomyślnie.", + "error_empty": "Klucz API nie może być pusty.", + "error_save": "Wystąpił błąd podczas zapisywania. Spróbuj ponownie.", + "api_key_empty_error": "Klucz API nie może być pusty.", + "success_cleared": "Klucz API został usunięty", + "error_clear": "Nie udało się usunąć klucza API" + }, + "notification": { + "title": "Ustawienia powiadomień", + "section_general": "Ogólne", + "enable_notifications": "Włącz powiadomienia", + "section_types": "Typy powiadomień", + "new_episodes": "Nowe odcinki", + "upcoming_shows": "Nadchodzące programy", + "reminders": "Przypomnienia", + "section_timing": "Czas powiadomienia", + "timing_desc": "Kiedy powiadomić Cię przed emisją odcinka?", + "hours_1": "1 godzina", + "hours_suffix": "godz.", + "section_status": "Status powiadomień", + "stats_upcoming": "Nadchodzące", + "stats_this_week": "W tym tygodniu", + "stats_total": "Łącznie", + "sync_button": "Synchronizuj Bibliotekę i Trakt", + "syncing": "Synchronizacja...", + "sync_desc": "Automatycznie synchronizuje powiadomienia dla wszystkich seriali w bibliotece oraz na liście do obejrzenia/kolekcji Trakt.", + "section_advanced": "Zaawansowane", + "reset_button": "Zresetuj wszystkie powiadomienia", + "test_button": "Testuj powiadomienie (5 sek)", + "test_notification_in": "Powiadomienie za {{seconds}}s...", + "test_notification_text": "Powiadomienie pojawi się za {{seconds}} sekund", + "alert_reset_title": "Resetuj powiadomienia", + "alert_reset_msg": "To anuluje wszystkie zaplanowane powiadomienia, ale nie usunie niczego z biblioteki. Kontynuować?", + "alert_reset_success": "Wszystkie powiadomienia zostały zresetowane", + "alert_sync_complete": "Synchronizacja zakończona", + "alert_sync_msg": "Pomyślnie zsynchronizowano powiadomienia dla pozycji z biblioteki i Trakt.\n\nZaplanowano: {{upcoming}} nadchodzących odcinków\nW tym tygodniu: {{thisWeek}} odcinków", + "alert_test_scheduled": "Testowe powiadomienie zaplanowane" + }, + "backup": { + "title": "Kopia zapasowa i przywracanie", + "options_title": "Opcje kopii zapasowej", + "options_desc": "Wybierz, co ma zostać uwzględnione w kopii", + "section_core": "Dane podstawowe", + "section_addons": "Dodatki i integracje", + "section_settings": "Ustawienia i preferencje", + "library_label": "Biblioteka", + "library_desc": "Twoje zapisane filmy i seriale", + "watch_progress_label": "Postęp oglądania", + "watch_progress_desc": "Pozycje kontynuowania oglądania", + "addons_label": "Dodatki", + "addons_desc": "Zainstalowane dodatki Stremio", + "plugins_label": "Wtyczki", + "plugins_desc": "Własne konfiguracje scraperów", + "trakt_label": "Integracja Trakt", + "trakt_desc": "Dane synchronizacji i tokeny autoryzacji", + "app_settings_label": "Ustawienia aplikacji", + "app_settings_desc": "Motyw, preferencje i konfiguracje", + "user_prefs_label": "Preferencje użytkownika", + "user_prefs_desc": "Kolejność dodatków i ustawienia UI", + "catalog_settings_label": "Ustawienia katalogu", + "catalog_settings_desc": "Filtry katalogów i preferencje", + "api_keys_label": "Klucze API", + "api_keys_desc": "Klucze MDBList i OpenRouter", + "action_create": "Utwórz kopię zapasową", + "action_restore": "Przywróć z kopii", + "section_info": "O kopiach zapasowych", + "info_text": "• Dostosuj zakres kopii za pomocą przełączników powyżej\n• Pliki kopii są przechowywane lokalnie na Twoim urządzeniu\n• Udostępnij kopię, aby przenieść dane między urządzeniami\n• Przywracanie nadpisze Twoje obecne dane", + "alert_create_title": "Utwórz kopię zapasową", + "alert_no_content": "Nie wybrano żadnej treści do kopii zapasowej.\n\nProszę włączyć co najmniej jedną opcję powyżej.", + "alert_backup_created_title": "Kopia utworzona", + "alert_backup_created_msg": "Twoja kopia zapasowa została utworzona i jest gotowa do udostępnienia.", + "alert_backup_failed_title": "Kopia nieudana", + "alert_restore_confirm_title": "Potwierdź przywracanie", + "alert_restore_confirm_msg": "To przywróci dane z kopii utworzonej w dniu {{date}}.\n\nTa akcja nadpisze obecne dane. Czy na pewno chcesz kontynuować?", + "alert_restore_complete_title": "Przywracanie zakończone", + "alert_restore_complete_msg": "Dane zostały pomyślnie przywrócone. Uruchom ponownie aplikację, aby zobaczyć zmiany.", + "alert_restore_failed_title": "Przywracanie nieudane", + "restart_app": "Restartuj aplikację", + "alert_restart_failed_title": "Restart nieudany", + "alert_restart_failed_msg": "Nie udało się zrestartować aplikacji. Proszę zamknąć ją ręcznie i otworzyć ponownie." + }, + "updates": { + "title": "Aktualizacje aplikacji", + "status_checking": "Sprawdzanie aktualizacji...", + "status_available": "Dostępna aktualizacja!", + "status_downloading": "Pobieranie aktualizacji...", + "status_installing": "Instalowanie aktualizacji...", + "status_success": "Aktualizacja zainstalowana pomyślnie!", + "status_error": "Aktualizacja nie powiodła się", + "status_ready": "Gotowy do sprawdzenia aktualizacji", + "action_check": "Sprawdź aktualizacje", + "action_install": "Zainstaluj aktualizację", + "release_notes": "Lista zmian:", + "version": "Wersja:", + "last_checked": "Ostatnio sprawdzono:", + "current_version": "Aktualna wersja:", + "current_release_notes": "Aktualna lista zmian:", + "github_release": "WYDANIE GITHUB", + "current": "Obecna:", + "latest": "Najnowsza:", + "notes": "Notatki:", + "view_release": "Zobacz wydanie", + "notification_settings": "USTAWIENIA POWIADOMIEŃ", + "ota_alerts_label": "Alerty aktualizacji OTA", + "ota_alerts_desc": "Pokaż powiadomienia dla aktualizacji bezprzewodowych (over-the-air)", + "major_alerts_label": "Alerty głównych aktualizacji", + "major_alerts_desc": "Pokaż powiadomienia o nowych wersjach aplikacji na GitHub", + "alert_disable_ota_title": "Wyłączyć alerty aktualizacji OTA?", + "alert_disable_ota_msg": "Nie będziesz już otrzymywać automatycznych powiadomień o aktualizacjach OTA.\n\n⚠️ Ostrzeżenie: Korzystanie z najnowszej wersji jest ważne dla:\n• Poprawek błędów i stabilności\n• Nowych funkcji i ulepszeń\n• Dostarczania dokładnych raportów o błędach\n\nNadal możesz ręcznie sprawdzać aktualizacje na tym ekranie.", + "alert_disable_major_title": "Wyłączyć alerty głównych aktualizacji?", + "alert_disable_major_msg": "Nie będziesz już otrzymywać powiadomień o głównych aktualizacjach wymagających ponownej instalacji.\n\n⚠️ Ostrzeżenie: Główne aktualizacje często zawierają:\n• Krytyczne poprawki bezpieczeństwa\n• Zmiany wymagające reinstalacji aplikacji\n• Ważne poprawki kompatybilności\n\nNadal możesz sprawdzać aktualizacje ręcznie.", + "warning_note": "Włączone alerty zapewniają otrzymywanie poprawek błędów i możliwość przesyłania raportów o awariach.", + "disable": "Wyłącz", + "alert_no_update_to_install": "Brak dostępnych aktualizacji do zainstalowania", + "alert_install_failed": "Błąd instalacji aktualizacji", + "alert_no_update_title": "Brak aktualizacji", + "alert_update_applied_msg": "Aktualizacja zostanie zastosowana przy następnym uruchomieniu aplikacji" + }, + "player": { + "title": "Odtwarzacz wideo", + "section_selection": "WYBÓR ODTWARZACZA", + "internal_title": "Wbudowany odtwarzacz", + "internal_desc": "Używaj domyślnego odtwarzacza aplikacji", + "vlc_title": "VLC", + "vlc_desc": "Otwieraj strumienie w odtwarzaczu VLC", + "infuse_title": "Infuse", + "infuse_desc": "Otwieraj strumienie w odtwarzaczu Infuse", + "outplayer_title": "OutPlayer", + "outplayer_desc": "Otwieraj strumienie w OutPlayer", + "vidhub_title": "VidHub", + "vidhub_desc": "Otwieraj strumienie w odtwarzaczu VidHub", + "infuse_live_title": "Infuse LiveContainer", + "infuse_live_desc": "Otwieraj strumienie w Infuse LiveContainer", + "external_title": "Zewnętrzny odtwarzacz", + "external_desc": "Otwieraj strumienie w preferowanym odtwarzaczu wideo", + "section_playback": "OPCJE ODTWARZANIA", + "skip_intro_settings_title": "Pomiń wstęp", + "powered_by_introdb": "Wspierane przez IntroDB", + "autoplay_title": "Autoodtwarzanie pierwszego strumienia", + "autoplay_desc": "Automatycznie uruchamiaj pierwszy strumień widoczny na liście.", + "resume_title": "Zawsze wznawiaj", + "resume_desc": "Pomiń zapytanie o wznowienie i kontynuuj od momentu przerwania (jeśli obejrzano mniej niż 85%).", + "engine_title": "Silnik odtwarzacza", + "engine_desc": "Tryb Auto używa ExoPlayer z opcją awaryjną MPV. Niektóre formaty, jak Dolby Vision i HDR, mogą nie być wspierane przez MPV, więc zalecany jest tryb Auto.", + "decoder_title": "Tryb dekodera", + "decoder_desc": "Sposób dekodowania wideo. Tryb Auto jest zalecany dla najlepszej równowagi.", + "gpu_title": "Renderowanie GPU", + "gpu_desc": "GPU-Next oferuje lepsze zarządzanie HDR i kolorami.", + "external_downloads_title": "Zewnętrzny odtwarzacz dla pobranych", + "external_downloads_desc": "Odtwarzaj pobrane treści w preferowanym zewnętrznym odtwarzaczu.", + "restart_required": "Wymagany restart", + "restart_msg_decoder": "Uruchom ponownie aplikację, aby zmiana dekodera weszła w życie.", + "restart_msg_gpu": "Uruchom ponownie aplikację, aby zmiana trybu GPU weszła w życie.", + "option_auto": "Auto", + "option_auto_desc_engine": "ExoPlayer + MPV fallback", + "option_mpv": "MPV", + "option_mpv_desc": "Tylko MPV", + "option_auto_desc_decoder": "Najlepsza równowaga", + "option_sw": "SW", + "option_sw_desc": "Programowe", + "option_hw": "HW", + "option_hw_desc": "Sprzętowe", + "option_hw_plus": "HW+", + "option_hw_plus_desc": "Pełne sprzętowe", + "option_gpu_desc": "Standardowe", + "option_gpu_next_desc": "Zaawansowane" + }, + "plugins": { + "title": "Wtyczki", + "enable_title": "Włącz wtyczki", + "enable_desc": "Włącz silnik wtyczek, aby pobierać zewnętrzne źródła mediów", + "repo_config_title": "Konfiguracja repozytorium", + "repo_config_desc": "Zarządzaj zewnętrznymi repozytoriami wtyczek. Przełączaj poniższe repozytoria.", + "your_repos": "Repozytoria", + "your_repos_desc": "Skonfiguruj zewnętrzne źródła wtyczek.", + "add_repo_button": "Dodaj repozytorium", + "refresh": "Odśwież", + "remove": "Usuń", + "enabled": "Włączone", + "disabled": "Wyłączone", + "updating": "Aktualizowanie...", + "success": "Sukces", + "error": "Błąd", + "alert_repo_added": "Repozytorium dodane, a wtyczki załadowane pomyślnie", + "alert_repo_saved": "Adres URL repozytorium zapisany pomyślnie", + "alert_repo_refreshed": "Repozytorium odświeżone pomyślnie", + "alert_invalid_url": "Nieprawidłowy format adresu URL", + "alert_plugins_cleared": "Wszystkie wtyczki zostały usunięte", + "alert_cache_cleared": "Pamięć podręczna repozytorium wyczyszczona", + "unknown": "Nieznany", + "active": "Aktywne", + "available": "Dostępne", + "platform_disabled": "Platforma wyłączona", + "limited": "Ograniczone", + "clear_all": "Usuń wszystkie wtyczki", + "clear_all_desc": "Czy na pewno chcesz usunąć wszystkie zainstalowane wtyczki? Tej akcji nie można cofnąć.", + "clear_cache": "Wyczyść cache repozytorium", + "clear_cache_desc": "To spowoduje usunięcie adresu URL repozytorium i wyczyszczenie danych cache. Będziesz musiał ponownie wprowadzić URL.", + "add_new_repo": "Dodaj nowe repozytorium", + "available_plugins": "Dostępne wtyczki ({{count}})", + "placeholder": "Szukaj wtyczek...", + "all": "Wszystkie", + "filter_all": "Wszystkie typy", + "filter_movies": "Filmy", + "filter_tv": "Seriale", + "enable_all": "Włącz wszystkie", + "disable_all": "Wyłącz wszystkie", + "no_plugins_found": "Nie znaleziono wtyczek", + "no_plugins_available": "Brak dostępnych wtyczek", + "no_match_desc": "Brak wtyczek pasujących do „{{query}}”. Spróbuj innego hasła.", + "configure_repo_desc": "Skonfiguruj repozytorium powyżej, aby zobaczyć dostępne wtyczki.", + "clear_search": "Wyczyść wyszukiwanie", + "no_external_player": "Brak zewnętrznego odtwarzacza", + "showbox_token": "Token ShowBox UI", + "showbox_placeholder": "Wklej swój token ShowBox UI", + "save": "Zapisz", + "clear": "Wyczyść", + "additional_settings": "Ustawienia dodatkowe", + "enable_url_validation": "Włącz walidację URL", + "url_validation_desc": "Waliduj adresy URL mediów przed ich zwróceniem (może spowolnić wyniki, ale poprawia niezawodność)", + "group_streams": "Grupuj źródła wtyczek", + "group_streams_desc": "Gdy włączone, źródła są grupowane według repozytoriów. Gdy wyłączone, każda wtyczka widnieje jako osobny dostawca.", + "sort_quality": "Sortuj najpierw według jakości", + "sort_quality_desc": "Gdy włączone, źródła są sortowane według jakości. Działa tylko przy włączonym grupowaniu.", + "show_logos": "Pokaż logo wtyczek", + "show_logos_desc": "Wyświetlaj logo wtyczek obok linków do mediów na ekranie źródeł.", + "quality_filtering": "Filtrowanie jakości", + "quality_filtering_desc": "Wyklucz określone rozdzielczości z wyników wyszukiwania. Dotknij jakości, aby ją wykluczyć.", + "excluded_qualities": "Wykluczone jakości:", + "language_filtering": "Filtrowanie języka", + "language_filtering_desc": "Wyklucz określone języki z wyników wyszukiwania. Dotknij języka, aby go wykluczyć.", + "note": "Uwaga:", + "language_filtering_note": "Ten filtr dotyczy tylko dostawców udostępniających informacje o języku.", + "excluded_languages": "Wykluczone języki:", + "about_title": "O wtyczkach", + "about_desc_1": "Wtyczki to modułowe komponenty, które adaptują treści z różnych protokołów. Działają lokalnie na Twoim urządzeniu.", + "about_desc_2": "Wtyczki oznaczone jako „Ograniczone” mogą wymagać specyficznej konfiguracji zewnętrznej.", + "help_title": "Konfiguracja wtyczek", + "help_step_1": "1. **Włącz wtyczki** – Uruchom główny przełącznik", + "help_step_2": "2. **Dodaj repozytorium** – Wprowadź poprawny URL repozytorium", + "help_step_3": "3. **Odśwież repozytorium** – Pobierz dostępne wtyczki", + "help_step_4": "4. **Aktywuj** – Włącz wtyczki, których chcesz używać", + "got_it": "Rozumiem!", + "repo_format_hint": "Format: https://raw.githubusercontent.com/użytkownik/repo/gałąź", + "cancel": "Anuluj", + "add": "Dodaj" + }, + "theme": { + "title": "Motywy aplikacji", + "select_theme": "WYBIERZ MOTYW", + "create_custom": "Utwórz własny motyw", + "options": "OPCJE", + "use_dominant_color": "Użyj koloru dominującego z okładki", + "categories": { + "all": "Wszystkie motywy", + "dark": "Ciemne motywy", + "colorful": "Kolorowe", + "custom": "Moje motywy" + }, + "editor": { + "theme_name_placeholder": "Nazwa motywu", + "save": "Zapisz", + "primary": "Podstawowy", + "secondary": "Drugorzędny", + "background": "Tło", + "invalid_name_title": "Nieprawidłowa nazwa", + "invalid_name_msg": "Proszę podać poprawną nazwę motywu" + }, + "alerts": { + "delete_title": "Usuń motyw", + "delete_msg": "Czy na pewno chcesz usunąć „{{name}}”?", + "ok": "OK", + "delete": "Usuń", + "cancel": "Anuluj", + "back": "Ustawienia" + } + }, + "legal": { + "title": "Informacje prawne", + "intro_title": "Charakter aplikacji", + "intro_text": "Nuvio to odtwarzacz multimedialny i aplikacja do zarządzania metadanymi. Działa wyłącznie jako interfejs po stronie klienta do przeglądania publicznie dostępnych metadanych (filmy, seriale itp.) i odtwarzania plików dostarczonych przez użytkownika lub rozszerzenia stron trzecich. Nuvio nie hostuje, nie przechowuje, nie dystrybuuje ani nie indeksuje żadnych treści medialnych.", + "extensions_title": "Wtyczki stron trzecich", + "extensions_text": "Nuvio korzysta z rozszerzalnej architektury, która pozwala użytkownikom instalować wtyczki stron trzecich. Są one tworzone przez niezależnych programistów niezwiązanych z Nuvio. Nie mamy kontroli i nie ponosimy odpowiedzialności za treść, legalność ani funkcjonalność jakiejkolwiek wtyczki zewnętrznej.", + "user_resp_title": "Odpowiedzialność użytkownika", + "user_resp_text": "Użytkownicy ponoszą wyłączną odpowiedzialność za instalowane wtyczki i treści, do których uzyskują dostęp. Korzystając z aplikacji, zgadzasz się upewnić, że masz prawo do przeglądania danych treści. Twórcy Nuvio nie zachęcają do naruszania praw autorskich.", + "dmca_title": "Prawa autorskie i DMCA", + "dmca_text": "Szanujemy prawa własności intelektualnej innych osób. Ponieważ Nuvio nie hostuje żadnych treści, nie możemy ich usunąć z Internetu. Jeśli jednak uważasz, że sam interfejs aplikacji narusza Twoje prawa, skontaktuj się z nami.", + "warranty_title": "Brak gwarancji", + "warranty_text": "Oprogramowanie jest dostarczane w stanie „takim, jakie jest”, bez jakiejkolwiek gwarancji. W żadnym wypadku autorzy nie ponoszą odpowiedzialności za jakiekolwiek roszczenia czy szkody wynikające z użytkowania tego oprogramowania." + }, + "plugin_tester": { + "title": "Tester wtyczek", + "subtitle": "Uruchamiaj skrapery i sprawdzaj logi w czasie rzeczywistym", + "tabs": { + "individual": "Indywidualny", + "repo": "Tester repo", + "code": "Kod", + "logs": "Logi", + "results": "Wyniki" + }, + "common": { + "error": "Błąd", + "success": "Sukces", + "movie": "Film", + "tv": "Serial", + "tmdb_id": "ID TMDB", + "season": "Sezon", + "episode": "Odcinek", + "running": "Uruchamianie...", + "run_test": "Uruchom test", + "play": "Odtwórz", + "done": "Gotowe", + "test": "Test", + "testing": "Testowanie..." + }, + "individual": { + "load_from_url": "Wczytaj z adresu URL", + "load_from_url_desc": "Wklej surowy URL z GitHub lub lokalne IP i dotknij pobierz.", + "enter_url_error": "Proszę podać adres URL", + "code_loaded": "Kod wczytany z adresu URL", + "fetch_error": "Błąd pobierania: {{message}}", + "no_code_error": "Brak kodu do uruchomienia", + "plugin_code": "Kod wtyczki", + "focus_editor": "Aktywuj edytor kodu", + "code_placeholder": "// Wklej kod wtyczki tutaj...", + "test_parameters": "Parametry testowe", + "no_logs": "Brak logów. Uruchom test, aby zobaczyć dane wyjściowe.", + "no_streams": "Nie znaleziono jeszcze żadnych strumieni.", + "streams_found": "Znaleziono {{count}} strumień", + "streams_found_plural": "Znaleziono {{count}} strumienie/strumieni", + "tap_play_hint": "Dotknij Odtwórz, aby przetestować strumień w natywnym odtwarzaczu.", + "unnamed_stream": "Strumień bez nazwy", + "quality": "Jakość: {{quality}}", + "size": "Rozmiar: {{size}}", + "url_label": "URL: {{url}}", + "headers_info": "Nagłówki: {{count}} niestandardowych", + "find_placeholder": "Znajdź w kodzie...", + "edit_code_title": "Edytuj kod", + "no_url_stream_error": "Nie znaleziono adresu URL dla tego strumienia" + }, + "repo": { + "title": "Tester repozytorium", + "description": "Pobierz repozytorium (URL lokalny lub GitHub raw) i przetestuj każdego dostawcę.", + "enter_repo_url_error": "Proszę podać URL repozytorium", + "invalid_url_title": "Nieprawidłowy URL", + "invalid_url_msg": "Użyj surowego adresu URL GitHub lub lokalnego adresu http(s).\n\nPrzykład:\nhttps://raw.githubusercontent.com/użytkownik/repo/main", + "manifest_build_error": "Nie można utworzyć adresu URL manifestu", + "manifest_fetch_error": "Błąd pobierania manifestu", + "repo_manifest_fetch_error": "Błąd pobierania manifestu repozytorium", + "missing_filename": "Brak nazwy pliku w manifeście", + "scraper_build_error": "Nie można utworzyć adresu URL skrapera", + "download_scraper_error": "Błąd pobierania skrapera", + "test_failed": "Test nie powiódł się", + "test_parameters": "Parametry testu repozytorium", + "test_parameters_desc": "Te parametry są używane tylko dla Testera repozytorium.", + "using_info": "Użycie: {{mediaType}} • TMDB {{tmdbId}}", + "using_info_tv": "Użycie: {{mediaType}} • TMDB {{tmdbId}} • S{{season}}E{{episode}}", + "providers_title": "Dostawcy", + "repository_default": "Repozytorium", + "providers_count": "{{count}} dostawców", + "fetch_hint": "Pobierz repozytorium, aby wyświetlić dostawców.", + "test_all": "Testuj wszystko", + "status_running": "W TOKU", + "status_ok": "OK ({{count}})", + "status_ok_empty": "OK (0)", + "status_failed": "BŁĄD", + "status_idle": "OCZEKIWANIE", + "tried_url": "Próbowano: {{url}}", + "provider_logs": "Logi dostawcy", + "no_logs_captured": "Nie przechwycono żadnych logów." + } + } +} diff --git a/src/i18n/locales/pt-BR.json b/src/i18n/locales/pt-BR.json index b482e3ea..8ac6a0bb 100644 --- a/src/i18n/locales/pt-BR.json +++ b/src/i18n/locales/pt-BR.json @@ -650,6 +650,18 @@ "chinese": "Chinês (Simplificado)", "hindi": "Hindi", "serbian": "Sérvio", + "hebrew": "Hebraico", + "bulgarian": "Búlgaro", + "polish": "Polonês", + "czech": "Theco", + "turkish": "Turco", + "slovenian": "Esloveno", + "macedonian": "Macedônio", + "russian": "Russo", + "filipino": "Filipino", + "dutch_nl": "Holandês (Países Baixos)", + "romanian": "Romeno", + "albanian": "Albanês", "account": "Conta", "content_discovery": "Conteúdo e Descoberta", "appearance": "Aparência", @@ -910,8 +922,8 @@ }, "debrid": { "title": "Integração Debrid", - "description_torbox": "Desbloqueie streams 4K de alta qualidade e velocidades ultra-rápidas integrando o Torbox. Insira sua chave API abaixo para atualizar instantaneamente sua experiência de streaming.", - "description_torrentio": "Configure o Torrentio para obter streams de torrent para filmes e séries. Um serviço debrid é necessário para transmitir conteúdo.", + "description_torbox": "Connect Torbox to use your account-based source preferences. Enter your API key below to configure the integration.", + "description_torrentio": "Configure Torrentio as an external source integration. A compatible debrid account may be required depending on your setup.", "tab_torbox": "TorBox", "tab_torrentio": "Torrentio", "status_connected": "Conectado", @@ -938,15 +950,15 @@ "enter_api_key": "Insira sua Chave API", "connect_button": "Conectar e Instalar", "connecting": "Conectando...", - "unlock_speeds_title": "Velocidades Premium", - "unlock_speeds_desc": "Assine o Torbox para acessar streams em cache de alta qualidade com zero buffering.", + "unlock_speeds_title": "Optional Torbox Subscription", + "unlock_speeds_desc": "Torbox offers account tiers with enhanced performance and availability features.", "get_subscription": "Obter Assinatura", "powered_by": "Desenvolvido por", "disclaimer_torbox": "O Nuvio não é afiliado ao Torbox de nenhuma forma.", "disclaimer_torrentio": "O Nuvio não é afiliado ao Torrentio de nenhuma forma.", "installed_badge": "✓ INSTALADO", "promo_title": "⚡ Precisa de um Serviço Debrid?", - "promo_desc": "Obtenha o TorBox para streaming 4K ultra-rápido com zero buffering. Torrents em cache premium e downloads instantâneos.", + "promo_desc": "Use TorBox if you want account-managed performance features for supported integrations.", "promo_button": "Assinar TorBox", "service_label": "Serviço Debrid *", "api_key_label": "Chave API *", @@ -1338,7 +1350,7 @@ "user_resp_title": "Responsabilidade do Usuário", "user_resp_text": "Os usuários são os únicos responsáveis pelas extensões que instalam e pelo conteúdo que acessam. Ao usar este aplicativo, você concorda em garantir que tem o direito legal de acessar qualquer conteúdo que visualizar usando o Nuvio. Os desenvolvedores do Nuvio não endossam ou incentivam a violação de direitos autorais.", "dmca_title": "Direitos Autorais e DMCA", - "dmca_text": "Respeitamos os direitos de propriedade intelectual de terceiros. Como o Nuvio não hospeda nenhum conteúdo, não podemos remover conteúdo da internet. No entanto, se você acredita que a interface do aplicativo em si infringe seus direitos, entre em contato conosco.", + "dmca_text": "We respect the intellectual property rights of others. Nuvio does not host media content. If you believe this project's code, assets, or interface infringes your rights, submit a notice through the official project contact channels listed on the website and repository.", "warranty_title": "Sem Garantia", "warranty_text": "Este software é fornecido \"como está\", sem garantia de qualquer tipo, expressa ou implícita. Em nenhum caso os autores ou detentores de direitos autorais serão responsáveis por qualquer reclamação, danos ou outra responsabilidade decorrente do uso deste software." }, diff --git a/src/i18n/locales/pt-PT.json b/src/i18n/locales/pt-PT.json index 18a32583..0bdb7ce3 100644 --- a/src/i18n/locales/pt-PT.json +++ b/src/i18n/locales/pt-PT.json @@ -648,6 +648,18 @@ "chinese": "Chinês (Simplificado)", "hindi": "Hindi", "serbian": "Sérvio", + "hebrew": "Hebraico", + "bulgarian": "Búlgaro", + "polish": "Polonês", + "czech": "Theco", + "turkish": "Turco", + "slovenian": "Esloveno", + "macedonian": "Macedônio", + "russian": "Russo", + "filipino": "Filipino", + "dutch_nl": "Holandês (Países Baixos)", + "Romanian": "Romeno", + "albanian": "Albanês", "account": "Conta", "content_discovery": "Conteúdo e Descoberta", "appearance": "Aparência", @@ -908,8 +920,8 @@ }, "debrid": { "title": "Integração Debrid", - "description_torbox": "Desbloqueia streams 4K de alta qualidade e velocidades ultra-rápidas integrando o Torbox. Insere a tua chave API abaixo para atualizar instantaneamente a tua experiência de streaming.", - "description_torrentio": "Configura o Torrentio para obter streams de torrent para filmes e séries. Um serviço debrid é necessário para transmitir conteúdo.", + "description_torbox": "Connect Torbox to use your account-based source preferences. Enter your API key below to configure the integration.", + "description_torrentio": "Configure Torrentio as an external source integration. A compatible debrid account may be required depending on your setup.", "tab_torbox": "TorBox", "tab_torrentio": "Torrentio", "status_connected": "Conectado", @@ -936,15 +948,15 @@ "enter_api_key": "Insere a tua Chave API", "connect_button": "Conectar e Instalar", "connecting": "A conectar...", - "unlock_speeds_title": "Velocidades Premium", - "unlock_speeds_desc": "Subscreve o Torbox para acessar streams em cache de alta qualidade com zero buffering.", + "unlock_speeds_title": "Optional Torbox Subscription", + "unlock_speeds_desc": "Torbox offers account tiers with enhanced performance and availability features.", "get_subscription": "Obter Subscrição", "powered_by": "Desenvolvido por", "disclaimer_torbox": "O Nuvio não é afiliado ao Torbox de nenhuma forma.", "disclaimer_torrentio": "O Nuvio não é afiliado ao Torrentio de nenhuma forma.", "installed_badge": "✓ INSTALADO", "promo_title": "⚡ Precisas de um Serviço Debrid?", - "promo_desc": "Obtém o TorBox para streaming 4K ultra-rápido com zero buffering. Torrents em cache premium e downloads instantâneos.", + "promo_desc": "Use TorBox if you want account-managed performance features for supported integrations.", "promo_button": "Subscrever TorBox", "service_label": "Serviço Debrid *", "api_key_label": "Chave API *", @@ -1336,7 +1348,7 @@ "user_resp_title": "Responsabilidade do Usuário", "user_resp_text": "Os usuários são os únicos responsáveis pelas extensões que instalam e pelo conteúdo que acessam. Ao usar este aplicativo, você concorda em garantir que tem o direito legal de acessar qualquer conteúdo que visualizar usando o Nuvio. Os desenvolvedores do Nuvio não endossam ou incentivam a violação de direitos autorais.", "dmca_title": "Direitos Autorais e DMCA", - "dmca_text": "Respeitamos os direitos de propriedade intelectual de terceiros. Como o Nuvio não hospeda nenhum conteúdo, não podemos remover conteúdo da internet. No entanto, se você acredita que a interface do aplicativo em si infringe seus direitos, entre em contato conosco.", + "dmca_text": "We respect the intellectual property rights of others. Nuvio does not host media content. If you believe this project's code, assets, or interface infringes your rights, submit a notice through the official project contact channels listed on the website and repository.", "warranty_title": "Sem Garantia", "warranty_text": "Este software é fornecido \"como está\", sem garantia de qualquer tipo, expressa ou implícita. Em nenhum caso os autores ou detentores de direitos autorais serão responsáveis por qualquer reclamação, danos ou outra responsabilidade decorrente do uso deste software." }, diff --git a/src/i18n/locales/ro.json b/src/i18n/locales/ro.json new file mode 100644 index 00000000..34aad5df --- /dev/null +++ b/src/i18n/locales/ro.json @@ -0,0 +1,1430 @@ +{ + "common": { + "loading": "Se încarcă...", + "cancel": "Anulează", + "save": "Salvează", + "delete": "Șterge", + "edit": "Editează", + "search": "Caută", + "error": "Eroare", + "success": "Succes", + "ok": "OK", + "unknown": "Necunoscut", + "retry": "Reîncearcă", + "try_again": "Încearcă din nou", + "go_back": "Înapoi", + "settings": "Setări", + "close": "Închide", + "enable": "Activează", + "disable": "Dezactivează", + "show_more": "Afișează mai mult", + "show_less": "Afișează mai puțin", + "load_more": "Încarcă mai mult", + "unknown_date": "Dată necunoscută", + "anonymous_user": "Utilizator anonim", + "time": { + "now": "Chiar acum", + "minutes_ago": "Acum {{count}}m", + "hours_ago": "Acum {{count}}h", + "days_ago": "Acum {{count}}z" + }, + "days_short": { + "sun": "Dum", + "mon": "Lun", + "tue": "Mar", + "wed": "Mie", + "thu": "Joi", + "fri": "Vin", + "sat": "Sâm" + }, + "email": "Email", + "status": "Stare" + }, + "home": { + "categories": { + "movies": "Filme", + "series": "Seriale", + "channels": "Canale" + }, + "movies": "Filme", + "tv_shows": "Seriale TV", + "load_more_catalogs": "Încarcă mai multe cataloage", + "no_content": "Niciun conținut disponibil", + "add_catalogs": "Adaugă cataloage", + "sign_in_available": "Autentificare disponibilă", + "sign_in_desc": "Te poți autentifica oricând din Setări → Cont", + "view_all": "Vezi tot", + "this_week": "Săptămâna aceasta", + "upcoming": "Viitoare", + "recently_released": "Lansate recent", + "no_scheduled_episodes": "Seriale fără episoade programate", + "check_back_later": "Revino mai târziu", + "continue_watching": "Continuă vizionarea", + "up_next": "Urmează", + "up_next_caps": "URMEAZĂ", + "released": "Lansat", + "new": "Nou", + "tba": "Va fi anunțat", + "new_episodes": "{{count}} episoade noi", + "season_short": "S{{season}}", + "episode_short": "E{{episode}}", + "season": "Sezonul {{season}}", + "episode": "Episodul {{episode}}", + "movie": "Film", + "series": "Serial", + "tv_show": "Serial TV", + "percent_watched": "{{percent}}% vizionat", + "view_details": "Vezi detalii", + "remove": "Elimină", + "play": "Redă", + "play_now": "Redă acum", + "resume": "Reia", + "info": "Info", + "more_info": "Mai multe info", + "my_list": "Lista mea", + "save": "Salvează", + "saved": "Salvat", + "retry": "Reîncearcă", + "install_addons": "Instalează extensii", + "settings": "Setări", + "no_featured_content": "Niciun conținut recomandat", + "couldnt_load_featured": "Nu s-a putut încărca conținutul recomandat", + "no_featured_desc": "Instalează extensii cu cataloage sau schimbă sursa de conținut din setări.", + "load_error_desc": "A apărut o problemă la preluarea conținutului. Te rugăm să verifici conexiunea și să încerci din nou.", + "no_featured_available": "Niciun conținut recomandat disponibil", + "no_description": "Nicio descriere disponibilă" + }, + "navigation": { + "home": "Acasă", + "library": "Bibliotecă", + "search": "Căutare", + "downloads": "Descărcări", + "settings": "Setări" + }, + "search": { + "title": "Căutare", + "recent_searches": "Căutări recente", + "discover": "Descoperă", + "movies": "Filme", + "tv_shows": "Seriale TV", + "select_catalog": "Selectează catalogul", + "all_genres": "Toate genurile", + "discovering": "Se descoperă conținut...", + "show_more": "Arată mai mult ({{count}})", + "no_content_found": "Niciun conținut găsit", + "try_different": "Încearcă un alt gen sau catalog", + "select_catalog_desc": "Selectează un catalog pentru a descoperi", + "tap_catalog_desc": "Apasă pe cipul catalogului de mai sus pentru a începe", + "placeholder": "Caută filme, seriale...", + "keep_typing": "Continuă să scrii...", + "type_characters": "Scrie cel puțin 2 caractere pentru a căuta", + "no_results": "Niciun rezultat găsit", + "try_keywords": "Încearcă alte cuvinte cheie sau verifică ortografia", + "select_type": "Selectează tipul", + "browse_movies": "Răsfoiește cataloage de filme", + "browse_tv": "Răsfoiește cataloage de seriale TV", + "select_genre": "Selectează genul", + "show_all_content": "Arată tot conținutul", + "genres_count": "{{count}} genuri" + }, + "library": { + "title": "Bibliotecă", + "watched": "Vizonate", + "continue": "Continuă", + "watchlist": "Listă de vizionare", + "collection": "Colecție", + "rated": "Apreciate", + "items": "elemente", + "trakt_collections": "Colecții Trakt", + "trakt_collection": "Colecție Trakt", + "no_trakt": "Nicio colecție Trakt", + "no_trakt_desc": "Colecțiile tale Trakt vor apărea aici după ce începi să folosești Trakt", + "load_collections": "Încarcă colecțiile", + "empty_folder": "Niciun conținut în {{folder}}", + "empty_folder_desc": "Această colecție este goală", + "refresh": "Reîmprospătează", + "no_movies": "Încă nu sunt filme", + "no_series": "Încă nu sunt seriale", + "no_content": "Încă nu există conținut", + "add_content_desc": "Adaugă conținut în bibliotecă pentru a-l vedea aici", + "find_something": "Găsește ceva de vizionat", + "removed_from_library": "Eliminat din bibliotecă", + "item_removed": "Element eliminat din bibliotecă", + "failed_update_library": "Eșec la actualizarea bibliotecii", + "unable_remove": "Nu s-a putut elimina elementul din bibliotecă", + "marked_watched": "Marcat ca vizionat", + "marked_unwatched": "Marcat ca nevizionat", + "item_marked_watched": "Element marcat ca vizionat", + "item_marked_unwatched": "Element marcat ca nevizionat", + "failed_update_watched": "Eșec la actualizarea stării de vizionare", + "unable_update_watched": "Nu s-a putut actualiza starea de vizionare", + "added_to_library": "Adăugat în bibliotecă", + "item_added": "Adăugat în biblioteca locală", + "add_to_library": "Adaugă în bibliotecă", + "remove_from_library": "Elimină din bibliotecă", + "mark_watched": "Marchează ca vizionat", + "mark_unwatched": "Marchează ca nevizionat", + "share": "Partajează", + "add_to_watchlist": "Adaugă în Watchlist Trakt", + "remove_from_watchlist": "Elimină din Watchlist Trakt", + "added_to_watchlist": "Adăugat în Watchlist", + "added_to_watchlist_desc": "Adăugat în lista de vizionare Trakt", + "removed_from_watchlist": "Eliminat din Watchlist", + "removed_from_watchlist_desc": "Eliminat din lista de vizionare Trakt", + "add_to_collection": "Adaugă în Colecția Trakt", + "remove_from_collection": "Elimină din Colecția Trakt", + "added_to_collection": "Adăugat în Colecție", + "added_to_collection_desc": "Adăugat în colecția ta Trakt", + "removed_from_collection": "Eliminat din Colecție", + "removed_from_collection_desc": "Eliminat din colecția ta Trakt" + }, + "metadata": { + "unable_to_load": "Nu s-a putut încărca conținutul", + "error_code": "Cod eroare: {{code}}", + "content_not_found": "Conținut negăsit", + "content_not_found_desc": "Acest conținut nu există sau a fost eliminat.", + "server_error": "Eroare de server", + "server_error_desc": "Serverul este temporar indisponibil. Te rugăm să încerci mai târziu.", + "bad_gateway": "Bad gateway", + "bad_gateway_desc": "Serverul întâmpină probleme. Te rugăm să încerci mai târziu.", + "service_unavailable": "Serviciu indisponibil", + "service_unavailable_desc": "Serviciul este în mentenanță. Te rugăm să încerci mai târziu.", + "too_many_requests": "Prea multe cereri", + "too_many_requests_desc": "Efectuezi prea multe cereri. Te rugăm să aștepți un moment.", + "request_timeout": "Cerere expirată", + "request_timeout_desc": "Cererea a durat prea mult. Te rugăm să încerci din nou.", + "network_error": "Eroare de rețea", + "network_error_desc": "Te rugăm să verifici conexiunea la internet.", + "auth_error": "Eroare de autentificare", + "auth_error_desc": "Te rugăm să verifici setările contului.", + "access_denied": "Acces respins", + "access_denied_desc": "Nu ai permisiunea de a accesa acest conținut.", + "connection_error": "Eroare de conexiune", + "streams_unavailable": "Surse indisponibile", + "streams_unavailable_desc": "Sursele de streaming sunt momentan indisponibile.", + "unknown_error": "Eroare necunoscută", + "something_went_wrong": "Ceva nu a mers bine. Încearcă din nou.", + "cast": "Distribuție", + "more_like_this": "Recomandări similare", + "collection": "Colecție", + "episodes": "Episoade", + "seasons": "Sezoane", + "posters": "Postere", + "banners": "Bannere", + "specials": "Speciale", + "season_number": "Sezonul {{number}}", + "episode_count": "{{count}} Episod", + "episode_count_plural": "{{count}} Episoade", + "no_episodes": "Niciun episod disponibil", + "no_episodes_for_season": "Niciun episod disponibil pentru Sezonul {{season}}", + "episodes_not_released": "Episoadele s-ar putea să nu fie lansate încă", + "no_description": "Nicio descriere disponibilă", + "episode_label": "EPISODUL {{number}}", + "watch_again": "Vizionează din nou", + "completed": "Finalizat", + "play_episode": "Redă S{{season}}E{{episode}}", + "play": "Redă", + "watched": "Vizionat", + "watched_on_trakt": "Vizionat pe Trakt", + "synced_with_trakt": "Sincronizat cu Trakt", + "saved": "Salvat", + "director": "Regizor", + "directors": "Regizori", + "creator": "Creator", + "creators": "Creatori", + "production": "Producție", + "network": "Rețea", + "mark_watched": "Marchează ca vizionat", + "mark_unwatched": "Marchează ca nevizionat", + "marking": "Se marchează...", + "removing": "Se elimină...", + "unmark_season": "Anulează marcarea Sezonului {{season}}", + "mark_season": "Marchează Sezonul {{season}}", + "resume": "Reia", + "spoiler_warning": "Avertisment Spoiler", + "spoiler_warning_desc": "Acest comentariu conține spoilere. Ești sigur că vrei să-l vezi?", + "cancel": "Anulează", + "reveal_spoilers": "Dezvăluie spoilere", + "movie_details": "Detalii Film", + "show_details": "Detalii Serial", + "tagline": "Slogan", + "status": "Stare", + "release_date": "Data lansării", + "runtime": "Durată", + "budget": "Buget", + "revenue": "Încasări", + "origin_country": "Țara de origine", + "original_language": "Limba originală", + "first_air_date": "Prima difuzare", + "last_air_date": "Ultima difuzare", + "total_episodes": "Total episoade", + "episode_runtime": "Durată episod", + "created_by": "Creat de", + "backdrop_gallery": "Galerie fundaluri", + "loading_episodes": "Se încarcă episoadele...", + "no_episodes_available": "Niciun episod disponibil", + "play_next": "Redă S{{season}}E{{episode}}", + "play_next_episode": "Redă următorul episod", + "save": "Salvează", + "percent_watched": "{{percent}}% vizionat", + "percent_watched_trakt": "{{percent}}% vizionat ({{traktPercent}}% pe Trakt)", + "synced_with_trakt_progress": "Sincronizat cu Trakt", + "using_trakt_progress": "Se folosește progresul Trakt", + "added_to_collection_hero": "Adăugat în Colecție", + "added_to_collection_desc_hero": "Adăugat în colecția ta Trakt", + "removed_from_collection_hero": "Eliminat din Colecție", + "removed_from_collection_desc_hero": "Eliminat din colecția ta Trakt", + "mark_as_watched": "Marchează ca vizionat", + "mark_as_unwatched": "Marchează ca nevizionat" + }, + "cast": { + "biography": "Biografie", + "known_for": "Cunoscut pentru", + "personal_info": "Informații personale", + "born_in": "Născut în {{place}}", + "filmography": "Filmografie", + "also_known_as": "Cunoscut și ca", + "no_info_available": "Nicio informație suplimentară disponibilă", + "as_character": "ca {{character}}", + "loading_details": "Se încarcă detaliile...", + "years_old": "{{age}} ani", + "view_filmography": "Vezi filmografia", + "filter": "Filtru", + "sort_by": "Sortează după", + "sort_popular": "Populare", + "sort_latest": "Ultimele", + "sort_upcoming": "Viitoare", + "upcoming_badge": "VIITOARE", + "coming_soon": "În curând", + "filmography_count": "Filmografie • {{count}} titluri", + "loading_filmography": "Se încarcă filmografia...", + "load_more_remaining": "Încarcă mai mult ({{count}} rămase)", + "alert_error_title": "Eroare", + "alert_error_message": "Nu s-a putut încărca \"{{title}}\". Încearcă mai târziu.", + "alert_ok": "OK", + "no_upcoming": "Nicio lansare viitoare disponibilă pentru acest actor", + "no_content": "Niciun conținut disponibil pentru acest actor", + "no_movies": "Niciun film disponibil pentru acest actor", + "no_tv": "Niciun serial disponibil pentru acest actor" + }, + "comments": { + "title": "Comentarii Trakt", + "spoiler_warning": "⚠️ Acest comentariu conține spoilere. Apasă pentru a vedea.", + "spoiler": "Spoiler", + "contains_spoilers": "Conține spoilere", + "reveal": "Dezvăluie", + "vip": "VIP", + "unavailable": "Comentarii indisponibile", + "no_comments": "Încă nu sunt comentarii pe Trakt", + "not_in_database": "Acest conținut s-ar putea să nu fie încă în baza de date Trakt", + "check_trakt": "Verifică Trakt" + }, + "trailers": { + "title": "Trailere", + "official_trailers": "Trailere Oficiale", + "official_trailer": "Trailer Oficial", + "teasers": "Teasere", + "teaser": "Teaser", + "clips_scenes": "Clipuri și Scene", + "clip": "Clip", + "featurettes": "Featurettes", + "featurette": "Featurette", + "behind_the_scenes": "În spatele scenelor", + "no_trailers": "Niciun trailer disponibil", + "unavailable": "Trailer Indisponibil", + "unavailable_desc": "Acest trailer nu a putut fi încărcat. Te rugăm să încerci mai târziu.", + "unable_to_play": "Nu s-a putut reda trailerul. Încearcă din nou.", + "watch_on_youtube": "Vizionează pe YouTube" + }, + "catalog": { + "no_content_found": "Niciun conținut găsit", + "no_content_filters": "Niciun conținut găsit pentru filtrele selectate", + "loading_content": "Se încarcă conținutul...", + "back": "Înapoi", + "in_theaters": "În cinematografe", + "all": "Toate", + "failed_tmdb": "Eșec la încărcarea conținutului de pe TMDB", + "movies": "Filme", + "tv_shows": "Seriale TV", + "channels": "Canale" + }, + "streams": { + "back_to_episodes": "Înapoi la Episoade", + "back_to_info": "Înapoi la Info", + "fetching_from": "Se preia de la:", + "no_sources_available": "Nicio sursă de streaming disponibilă", + "add_sources_desc": "Te rugăm să adaugi surse de streaming în setări", + "add_sources": "Adaugă surse", + "finding_streams": "Se caută fluxuri disponibile...", + "finding_best_stream": "Se caută cel mai bun flux pentru redare automată...", + "still_fetching": "Încă se preiau fluxurile…", + "no_streams_available": "Niciun flux disponibil", + "starting_best_stream": "Se pornește cel mai bun flux...", + "loading_more_sources": "Se încarcă mai multe surse..." + }, + "player_ui": { + "via": "prin {{name}}", + "audio_tracks": "Piste Audio", + "no_audio_tracks": "Nicio pistă audio disponibilă", + "playback_speed": "Viteză de redare", + "on_hold": "În așteptare", + "playback_error": "Eroare de redare", + "unknown_error": "A apărut o eroare necunoscută în timpul redării.", + "copy_error": "Copiază detaliile erorii", + "copied_to_clipboard": "Copiat în clipboard", + "dismiss": "Închide", + "continue_watching": "Continuă vizionarea", + "start_over": "O ia de la început", + "resume": "Reia", + "change_source": "Schimbă sursa", + "switching_source": "Se schimbă sursa...", + "no_sources_found": "Nicio sursă găsită", + "sources": "Surse", + "finding_sources": "Se caută surse...", + "unknown_source": "Sursă necunoscută", + "sources_limited": "Sursele pot fi limitate din cauza erorilor de furnizor.", + "episodes": "Episoade", + "specials": "Speciale", + "season": "Sezonul {{season}}", + "stream": "Flux {{number}}", + "subtitles": "Subtitrări", + "built_in": "Integrate", + "addons": "Extensii", + "style": "Stil", + "none": "Niciuna", + "search_online_subtitles": "Caută subtitrări online", + "preview": "Previzualizare", + "quick_presets": "Presetări rapide", + "default": "Implicit", + "yellow": "Galben", + "high_contrast": "Contrast ridicat", + "large": "Mare", + "core": "Core", + "font_size": "Dimensiune font", + "show_background": "Arată fundalul", + "advanced": "Avansat", + "position": "Poziție", + "text_color": "Culoare text", + "align": "Aliniere", + "bottom_offset": "Compensare jos", + "background_opacity": "Opacitate fundal", + "text_shadow": "Umbră text", + "on": "Pornit", + "off": "Oprit", + "outline_color": "Culoare contur", + "outline": "Contur", + "outline_width": "Grosime contur", + "letter_spacing": "Spațiere litere", + "line_height": "Înălțime rând", + "timing_offset": "Decalaj timp (s)", + "visual_sync": "Sincronizare vizuală", + "timing_hint": "Ajustează subtitrarea mai devreme (-) sau mai târziu (+) pentru sincronizare.", + "reset_defaults": "Resetează la implicite", + "mark_intro_start": "Marchează început intro", + "mark_intro_end": "Marchează sfârșit intro", + "intro_start_marked": "Început intro marcat", + "intro_submitted": "Intro trimis cu succes", + "intro_submit_failed": "Eșec la trimiterea intro-ului" + }, + "downloads": { + "title": "Descărcări", + "no_downloads": "Nicio descărcare încă", + "no_downloads_desc": "Conținutul descărcat va apărea aici pentru vizionare offline", + "explore": "Explorează conținut", + "path_copied": "Calea a fost copiată", + "path_copied_desc": "Calea fișierului local a fost copiată în clipboard", + "copied": "Copiat", + "incomplete": "Descărcare incompletă", + "incomplete_desc": "Descărcarea nu este încă finalizată", + "not_available": "Nu este disponibil", + "not_available_desc": "Calea fișierului local este disponibilă doar după finalizarea descărcării.", + "status_downloading": "Se descarcă", + "status_completed": "Finalizat", + "status_paused": "Pauzat", + "status_error": "Eroare", + "status_queued": "În coadă", + "status_unknown": "Necunoscut", + "provider": "Furnizor", + "streaming_playlist_warning": "S-ar putea să nu ruleze - playlist de streaming", + "remaining": "rămas", + "not_ready": "Descărcarea nu este gata", + "not_ready_desc": "Te rugăm să aștepți până când descărcarea se termină.", + "filter_all": "Toate", + "filter_active": "Active", + "filter_done": "Gata", + "filter_paused": "Pauzate", + "no_filter_results": "Nicio descărcare {{filter}}", + "try_different_filter": "Încearcă să selectezi un alt filtru", + "limitations_title": "Limitări descărcare", + "limitations_msg": "• Fișierele mai mici de 1MB sunt de obicei playlist-uri M3U8 și nu pot fi descărcate pentru vizionare offline. Acestea funcționează doar online.", + "remove_title": "Elimină descărcarea", + "remove_confirm": "Elimini \"{{title}}\"{{season_episode}}?", + "cancel": "Anulează", + "remove": "Elimină" + }, + "addons": { + "title": "Extensii", + "reorder_mode": "Mod Reordonare", + "reorder_info": "Extensiile de sus au prioritate mai mare la încărcarea conținutului", + "add_addon_placeholder": "URL Extensie", + "add_button": "Adaugă Extensie", + "my_addons": "Extensiile mele", + "community_addons": "Extensii comunitate", + "no_addons": "Nicio extensie instalată", + "uninstall_title": "Dezinstalează Extensia", + "uninstall_message": "Ești sigur că vrei să dezinstalezi {{name}}?", + "uninstall_button": "Dezinstalează", + "install_success": "Extensie instalată cu succes", + "install_error": "Eșec la instalarea extensiei", + "load_error": "Eșec la încărcarea extensiilor", + "fetch_error": "Eșec la preluarea detaliilor extensiei", + "invalid_url": "Te rugăm să introduci un URL de extensie valid", + "configure": "Configurează", + "version": "Versiune: {{version}}", + "installed_addons": "EXTENSII INSTALATE", + "reorder_drag_title": "TRAGE EXTENSIILE PENTRU REORDONARE", + "install": "Instalează", + "config_unavailable_title": "Configurare indisponibilă", + "config_unavailable_msg": "Nu s-a putut determina URL-ul de configurare pentru această extensie.", + "cannot_open_config_title": "Nu se poate deschide configurarea", + "cannot_open_config_msg": "URL-ul de configurare ({{url}}) nu poate fi deschis.", + "description": "Descriere", + "supported_types": "Tipuri suportate", + "catalogs": "Cataloage", + "no_description": "Nicio descriere disponibilă", + "overview": "PREZENTARE GENERALĂ", + "no_categories": "Nicio categorie", + "pre_installed": "PREINSTALAT" + }, + "trakt": { + "title": "Setări Trakt", + "settings_title": "Setări Trakt", + "connect_title": "Conectează-te cu Trakt", + "connect_desc": "Sincronizează istoricul, lista de vizionare și colecția cu Trakt.tv", + "sign_in": "Autentificare cu Trakt", + "sign_out": "Deconectare", + "sign_out_confirm": "Ești sigur că vrei să te deconectezi de la contul Trakt?", + "joined": "Membru din {{date}}", + "sync_settings_title": "Setări Sincronizare", + "sync_info": "Când ești conectat la Trakt, istoricul complet este sincronizat direct din API. Lista 'Continuă vizionarea' reflectă progresul tău global Trakt.", + "auto_sync_label": "Sincronizare automată progres", + "auto_sync_desc": "Sincronizează automat progresul vizionării cu Trakt", + "import_history_label": "Importă istoricul vizionărilor", + "import_history_desc": "Folosește \"Sincronizează acum\" pentru a importa istoricul de pe Trakt", + "sync_now_button": "Sincronizează acum", + "display_settings_title": "Setări Afișare", + "show_comments_label": "Arată comentariile Trakt", + "show_comments_desc": "Afișează comentariile Trakt în ecranele de detalii", + "maintenance_title": "În mentenanță", + "maintenance_unavailable": "Trakt Indisponibil", + "maintenance_desc": "Integrarea Trakt este temporar suspendată pentru mentenanță.", + "maintenance_button": "Serviciu în mentenanță", + "auth_success_title": "Conectat cu succes", + "auth_success_msg": "Contul tău Trakt a fost conectat cu succes.", + "auth_error_title": "Eroare de autentificare", + "auth_error_msg": "Eșec la finalizarea autentificării cu Trakt.", + "auth_error_generic": "A apărut o eroare în timpul autentificării.", + "sign_out_error": "Eșec la deconectarea de la Trakt.", + "sync_complete_title": "Sincronizare completă", + "sync_success_msg": "Sincronizarea progresului cu Trakt a fost realizată cu succes.", + "sync_error_msg": "Sincronizare eșuată. Te rugăm să încerci din nou." + }, + "simkl": { + "title": "Setări Simkl", + "settings_title": "Setări Simkl", + "connect_title": "Conectează-te cu Simkl", + "connect_desc": "Sincronizează istoricul de vizionare și urmărește ce vizionezi", + "sign_in": "Autentificare cu Simkl", + "sign_out": "Deconectare", + "sign_out_confirm": "Ești sigur că vrei să te deconectezi de la Simkl?", + "syncing_desc": "Elementele vizionate se sincronizează cu Simkl.", + "auth_success_title": "Conectat cu succes", + "auth_success_msg": "Contul tău Simkl a fost conectat cu succes.", + "auth_error_title": "Eroare de autentificare", + "auth_error_msg": "Eșec la finalizarea autentificării cu Simkl.", + "auth_error_generic": "A apărut o eroare în timpul autentificării.", + "sign_out_error": "Eșec la deconectarea de la Simkl.", + "config_error_title": "Eroare de configurare", + "config_error_msg": "Simkl Client ID lipsește din variabilele de mediu.", + "conflict_title": "Conflict", + "conflict_msg": "Nu te poți conecta la Simkl în timp ce Trakt este conectat. Te rugăm să deconectezi Trakt mai întâi.", + "disclaimer": "Nuvio nu este afiliat cu Simkl." + }, + "tmdb_settings": { + "title": "Setări TMDb", + "metadata_enrichment": "Îmbogățire Metadate", + "metadata_enrichment_desc": "Îmbunătățește metadatele conținutului cu date de la TMDb pentru detalii mai bune.", + "enable_enrichment": "Activează îmbogățirea", + "enable_enrichment_desc": "Completează metadatele extensiilor cu info despre distribuție, rating-uri, logo-uri și postere de la TMDb.", + "localized_text": "Text localizat", + "localized_text_desc": "Preia titlurile și descrierile în limba preferată de pe TMDb.", + "language": "Limbă", + "change": "Schimbă", + "logo_preview": "Previzualizare Logo", + "logo_preview_desc": "Previzualizarea arată cum vor apărea logo-urile localizate în limba selectată.", + "example": "Exemplu:", + "no_logo": "Niciun logo disponibil", + "enrichment_options": "Opțiuni de îmbogățire", + "enrichment_options_desc": "Controlează ce date sunt preluate de pe TMDb.", + "cast_crew": "Distribuție și Echipă", + "cast_crew_desc": "Actori, regizori, scriitori cu fotografii de profil", + "title_description": "Titlu și Descriere", + "title_description_desc": "Folosește titlul și descrierea localizată TMDb", + "title_logos": "Logo-uri titlu", + "title_logos_desc": "Imagini de înaltă calitate pentru titluri", + "banners_backdrops": "Bannere și Fundaluri", + "banners_backdrops_desc": "Imagini de fundal la rezoluție mare", + "certification": "Certificare conținut", + "certification_desc": "Clasificări de vârstă (PG-13, R, etc.)", + "recommendations": "Recomandări", + "recommendations_desc": "Sugestii de conținut similar", + "episode_data": "Date episoade", + "episode_data_desc": "Miniaturi episoade, info și variante de rezervă", + "season_posters": "Postere sezoane", + "season_posters_desc": "Imagini specifice pentru posterele de sezon", + "production_info": "Info Producție", + "production_info_desc": "Rețele și companii de producție cu logo-uri", + "movie_details": "Detalii Film", + "movie_details_desc": "Buget, încasări, durată, slogan", + "tv_details": "Detalii Serial TV", + "tv_details_desc": "Stare, număr sezoane, rețele, creatori", + "movie_collections": "Colecții de Filme", + "movie_collections_desc": "Filme din francize (Marvel, Star Wars, etc.)", + "api_configuration": "Configurare API", + "api_configuration_desc": "Configurează accesul API TMDb pentru funcționalitate sporită.", + "custom_api_key": "Cheie API personalizată", + "custom_api_key_desc": "Folosește propria cheie API TMDb pentru performanță mai bună.", + "custom_key_active": "Cheie API personalizată activă", + "api_key_required": "Cheie API obligatorie", + "api_key_placeholder": "Lipește cheia API TMDb (v3)", + "how_to_get_key": "Cum obțin o cheie API TMDb?", + "built_in_key_msg": "Se folosește cheia API integrată. Recomandăm folosirea propriei chei.", + "cache_size": "Dimensiune Cache", + "clear_cache": "Șterge Cache", + "cache_days": "Răspunsurile TMDb sunt stocate 7 zile pentru a îmbunătăți performanța", + "choose_language": "Alege Limba", + "choose_language_desc": "Selectează limba preferată pentru conținutul TMDb", + "popular": "Populare", + "all_languages": "Toate limbile", + "search_results": "Rezultate căutare", + "no_languages_found": "Nicio limbă găsită pentru \"{{query}}\"", + "clear_search": "Șterge căutarea", + "clear_cache_title": "Șterge Cache TMDB", + "clear_cache_msg": "Această acțiune va șterge toate datele TMDB stocate ({{size}}).", + "clear_cache_success": "Cache-ul TMDB a fost șters cu succes.", + "clear_cache_error": "Eșec la ștergerea cache-ului.", + "clear_api_key_title": "Șterge cheia API", + "clear_api_key_msg": "Ești sigur că vrei să elimini cheia personalizată și să revii la cea implicită?", + "clear_api_key_success": "Cheia API a fost ștearsă cu succes", + "clear_api_key_error": "Eșec la ștergerea cheii API", + "empty_api_key": "Cheia API nu poate fi goală.", + "invalid_api_key": "Cheie API invalidă. Te rugăm să verifici.", + "save_error": "A apărut o eroare la salvare. Încearcă din nou.", + "using_builtin_key": "Se folosește cheia API TMDb integrată.", + "using_custom_key": "Se folosește cheia ta personalizată TMDb.", + "enter_custom_key": "Te rugăm să introduci și să salvezi cheia personalizată.", + "key_verified": "Cheia API a fost verificată și salvată cu succes." + }, + "settings": { + "language": "Limbă", + "select_language": "Selectează limba", + "english": "Engleză", + "portuguese": "Portugheză", + "portuguese_br": "Portugheză (Brazilia)", + "portuguese_pt": "Portugheză (Portugalia)", + "german": "Germană", + "arabic": "Arabă", + "spanish": "Spaniolă", + "french": "Franceză", + "italian": "Italiană", + "croatian": "Croată", + "chinese": "Chineză (Simplificată)", + "hindi": "Hindi", + "serbian": "Sârbă", + "hebrew": "Ebraică", + "bulgarian": "Bulgară", + "polish": "Poloneză", + "czech": "Cehă", + "turkish": "Turcă", + "slovenian": "Slovenă", + "macedonian": "Macedoneană", + "russian": "Rusă", + "filipino": "Filipineză", + "dutch_nl": "Olandeză (Olanda)", + "romanian": "Română", + "albanian": "Albaneză", + "account": "Cont", + "content_discovery": "Conținut și Descoperire", + "appearance": "Aspect", + "integrations": "Integrări", + "playback": "Redare", + "backup_restore": "Backup și Restaurare", + "updates": "Actualizări", + "about": "Despre", + "developer": "Dezvoltator", + "cache": "Cache", + "title": "Setări", + "settings_title": "Setări", + "sign_in_sync": "Autentifică-te pentru sincronizare", + "add_catalogs_sources": "Extensii, cataloage și surse", + "player_trailers_downloads": "Player, trailere, descărcări", + "mdblist_tmdb_ai": "MDBList, TMDB, AI", + "check_updates": "Verifică actualizări", + "clear_mdblist_cache": "Șterge Cache MDBList", + "cache_management": "GESTIONARE CACHE", + "downloads_counter": "descărcări și numărătoarea continuă", + "made_with_love": "Creat cu ❤️ de Tapframe și prietenii", + "sections": { + "information": "INFORMAȚII", + "account": "CONT", + "theme": "TEMĂ", + "layout": "DIAGRAMĂ", + "sources": "SURSE", + "catalogs": "CATALOAGE", + "discovery": "DESCOPERIRE", + "metadata": "METADATE", + "ai_assistant": "ASISTENT AI", + "video_player": "VIDEO PLAYER", + "audio_subtitles": "AUDIO ȘI SUBTITRĂRI", + "media": "MEDIA", + "notifications": "NOTIFICĂRI", + "testing": "TESTARE", + "danger_zone": "ZONĂ PERICULOASĂ" + }, + "items": { + "legal": "Juridic și Declinarea responsabilității", + "privacy_policy": "Politica de confidențialitate", + "report_issue": "Raportează o problemă", + "version": "Versiune", + "contributors": "Contribuitori", + "view_contributors": "Vezi toți contribuitorii", + "theme": "Temă", + "episode_layout": "Layout episoade", + "streams_backdrop": "Fundal fluxuri", + "streams_backdrop_desc": "Arată fundal încețoșat pe fluxurile mobile", + "addons": "Extensii", + "installed": "instalate", + "debrid_integration": "Integrare Debrid", + "debrid_desc": "Conectează Torbox", + "plugins": "Module", + "plugins_desc": "Gestionare module și depozite", + "catalogs": "Cataloage", + "active": "active", + "home_screen": "Ecran principal", + "home_screen_desc": "Layout și conținut", + "continue_watching": "Continuă vizionarea", + "continue_watching_desc": "Comportament cache și redare", + "show_discover": "Arată secțiunea Descoperă", + "show_discover_desc": "Afișează conținut de descoperit în Căutare", + "mdblist": "MDBList", + "mdblist_connected": "Conectat", + "mdblist_desc": "Activează pentru a adăuga evaluări și recenzii", + "simkl": "Simkl", + "simkl_connected": "Conectat", + "simkl_desc": "Urmărește ce vizionezi", + "tmdb": "TMDB", + "tmdb_desc": "Furnizor de metadate și logo-uri", + "openrouter": "OpenRouter API", + "openrouter_connected": "Conectat", + "openrouter_desc": "Adaugă cheia API pentru a activa chat-ul AI", + "video_player": "Video Player", + "built_in": "Integrat", + "external": "Extern", + "preferred_audio": "Limba audio preferată", + "preferred_subtitle": "Limba subtitrare preferată", + "subtitle_source": "Prioritate sursă subtitrare", + "auto_select_subs": "Selectare automată subtitrări", + "auto_select_subs_desc": "Selectează automat subtitrările care se potrivesc preferințelor tale", + "show_trailers": "Arată trailere", + "show_trailers_desc": "Afișează trailere în secțiunea hero", + "enable_downloads": "Activează descărcările", + "enable_downloads_desc": "Arată fila Descărcări și activează salvarea fluxurilor", + "notifications": "Notificări", + "notifications_desc": "Mementouri episoade", + "developer_tools": "Instrumente dezvoltator", + "developer_tools_desc": "Opțiuni de testare și depanare", + "test_onboarding": "Testează Onboarding", + "reset_onboarding": "Resetează Onboarding", + "test_announcement": "Testează Anunț", + "test_announcement_desc": "Arată suprapunerea cu noutăți", + "reset_campaigns": "Resetează Campanii", + "reset_campaigns_desc": "Șterge impresiile campaniilor", + "clear_all_data": "Șterge toate datele", + "clear_all_data_desc": "Resetează toate setările și datele cache" + }, + "options": { + "horizontal": "Orizontal", + "vertical": "Vertical", + "internal_first": "Mai întâi interne", + "internal_first_desc": "Preferă subtitrările încorporate, apoi cele externe", + "external_first": "Mai întâi externe", + "external_first_desc": "Preferă subtitrările din extensii, apoi cele încorporate", + "any_available": "Oricare disponibilă", + "any_available_desc": "Folosește prima pistă de subtitrare găsită" + }, + "clear_data_desc": "Această acțiune va reseta toate setările și va șterge toate datele cache. Ești sigur?", + "app_updates": "Actualizări aplicație", + "about_nuvio": "Despre Nuvio" + }, + "privacy": { + "title": "Confidențialitate și Date", + "settings_desc": "Control telemetrie și colectare date", + "info_title": "Confidențialitatea ta contează", + "info_description": "Controlează ce date sunt colectate și partajate. Analizele sunt dezactivate implicit, iar rapoartele de eroare sunt anonime.", + "analytics_enabled_title": "Analize activate", + "analytics_enabled_message": "Datele de utilizare vor fi colectate pentru a ajuta la îmbunătățirea aplicației. Poți dezactiva asta oricând.", + "disable_error_reporting_title": "Dezactivezi raportarea erorilor?", + "disable_error_reporting_message": "Dezactivarea raportării înseamnă că nu vom fi notificați de erorile sau problemele întâmpinate. Acest lucru poate afecta capacitatea noastră de a repara bug-urile.", + "enable_session_replay_title": "Activezi Reluarea Sesiunii?", + "enable_session_replay_message": "Reluarea sesiunii înregistrează ecranul când apar erori pentru a ne ajuta să înțelegem ce s-a întâmplat. Acest lucru poate capta conținut vizibil pe ecran.", + "enable_pii_title": "Activezi colectarea PII?", + "enable_pii_message": "Acest lucru permite colectarea informațiilor de identificare personală, cum ar fi adresa IP și detaliile dispozitivului. Aceste date ajută la diagnosticarea problemelor, dar cresc expunerea confidențialității.", + "disable_all_title": "Dezactivezi toată telemetria?", + "disable_all_message": "Acest lucru va dezactiva toate analizele, raportarea erorilor și reluarea sesiunii. Nu vom primi nicio dată despre utilizarea aplicației sau erori.", + "disable_all_button": "Dezactivează Tot", + "all_disabled_title": "Toată telemetria a fost dezactivată", + "all_disabled_message": "Colectarea datelor a fost oprită. Modificările intră în vigoare la următoarea repornire a aplicației.", + "reset_title": "Resetează la Recomandat", + "reset_message": "Setările de confidențialitate au fost resetate la valorile implicite (raportare erori activată, analize dezactivate).", + "section_analytics": "ANALIZE", + "analytics_title": "Analize de utilizare", + "analytics_description": "Colectează tipare de utilizare anonime și vizualizări de ecran", + "section_error_reporting": "RAPORTARE ERORI", + "error_reporting_title": "Rapoarte de eroare", + "error_reporting_description": "Trimite rapoarte de eroare anonime pentru a îmbunătăți stabilitatea", + "session_replay_title": "Reluare Sesiune", + "session_replay_description": "Înregistrează ecranul când apar erori", + "pii_title": "Include info dispozitiv", + "pii_description": "Trimite adresa IP și detaliile dispozitivului împreună cu rapoartele", + "section_quick_actions": "ACȚIUNI RAPIDE", + "disable_all": "Dezactivează toată telemetria", + "disable_all_desc": "Oprește orice colectare de date", + "reset_recommended": "Resetează la recomandat", + "reset_recommended_desc": "Valori implicite axate pe confidențialitate", + "section_learn_more": "AFLĂ MAI MULTE", + "privacy_policy": "Politica de confidențialitate", + "current_settings": "Rezumat setări actuale", + "summary_analytics": "Analize", + "summary_errors": "Rapoarte erori", + "summary_replay": "Reluare Sesiune", + "summary_pii": "Info Dispozitiv", + "restart_note_detailed": "* Modificările pentru analize și rapoarte de eroare intră în vigoare imediat. Setările pentru reluarea sesiunii și PII necesită repornirea aplicației." + }, + "ai_settings": { + "title": "Asistent AI", + "info_title": "Chat asistat de AI", + "info_desc": "Pune întrebări despre orice film sau episod de serial folosind AI avansat. Obține detalii despre intrigă, personaje, teme, curiozități și multe altele - totul bazat pe datele TMDB.", + "feature_1": "Context și analiză specifică episodului", + "feature_2": "Explicații despre intrigă și detalii personaje", + "feature_3": "Curiozități și fapte din spatele scenelor", + "feature_4": "Propria ta cheie API OpenRouter gratuită", + "api_key_section": "CHEIE API OPENROUTER", + "api_key_label": "Cheie API", + "api_key_desc": "Introdu cheia API OpenRouter pentru a activa funcțiile de chat AI", + "save_api_key": "Salvează Cheia API", + "saving": "Se salvează...", + "update": "Actualizează", + "remove": "Elimină", + "get_free_key": "Obține o cheie API gratuită de la OpenRouter", + "enable_chat": "Activează Chat AI", + "enable_chat_desc": "Când este activat, butonul „Întreabă AI” va apărea pe paginile de conținut.", + "chat_enabled": "Chat AI activat", + "chat_enabled_desc": "Acum poți pune întrebări despre filme și seriale. Caută butonul „Întreabă AI” pe paginile de conținut!", + "how_it_works": "Cum funcționează", + "how_it_works_desc": "• OpenRouter oferă acces la mai multe modele AI\n• Cheia ta API rămâne privată și sigură\n• Nivelul gratuit include limite de utilizare generoase\n• Conversați cu context despre episoade/filme specifice\n• Obțineți analize și explicații detaliate", + "error_invalid_key": "Te rugăm să introduci o cheie API validă", + "error_key_format": "Cheile API OpenRouter trebuie să înceapă cu „sk-or-”", + "success_saved": "Cheia API OpenRouter a fost salvată cu succes!", + "error_save": "Eșec la salvarea cheii API", + "confirm_remove_title": "Elimină Cheia API", + "confirm_remove_msg": "Ești sigur că vrei să elimini cheia API OpenRouter? Acest lucru va dezactiva funcțiile de chat AI.", + "success_removed": "Cheia API a fost eliminată cu succes", + "error_remove": "Eșec la eliminarea cheii API" + }, + "catalog_settings": { + "title": "Cataloage", + "layout_phone": "LAYOUT ECRAN CATALOG (TELEFON)", + "posters_per_row": "Postere pe rând", + "auto": "Auto", + "show_titles": "Arată titlurile posterelor", + "show_titles_desc": "Afișează textul titlului sub fiecare poster", + "phone_only_hint": "Se aplică doar telefoanelor. Tabletele păstrează layout-ul adaptiv.", + "catalogs_group": "Cataloage", + "enabled_count": "{{enabled}} din {{total}} activate", + "rename_hint": "Apasă lung pe un catalog pentru a-l redenumi", + "rename_modal_title": "Redenumește Catalogul", + "rename_placeholder": "Introdu noul nume al catalogului", + "error_save_name": "Nu s-a putut salva numele personalizat." + }, + "continue_watching_settings": { + "title": "Continuă vizionarea", + "playback_behavior": "COMPORTAMENT REDARE", + "use_cached": "Folosește fluxuri stocate (Cache)", + "use_cached_desc": "Când este activat, apăsarea pe elementele din „Continuă vizionarea” va deschide player-ul direct folosind fluxurile redate anterior. Când este dezactivat, deschide ecranul de conținut.", + "open_metadata": "Deschide ecranul de metadate", + "open_metadata_desc": "Când fluxurile cache sunt dezactivate, deschide ecranul de metadate în locul celui de fluxuri. Acesta arată detalii și permite selecția manuală.", + "card_appearance": "ASPECT CARD", + "card_style": "Stil card", + "card_style_desc": "Alege cum apar elementele „Continuă vizionarea” pe ecranul principal", + "wide": "Lat", + "poster": "Poster", + "cache_settings": "SETĂRI CACHE", + "cache_duration": "Durată Cache Flux", + "cache_duration_desc": "Cât timp să fie păstrate link-urile de flux înainte de a expira", + "important_note": "Notă importantă", + "important_note_text": "Nu toate link-urile de flux rămân active pe toată durata cache-ului. Timpii mai lungi pot duce la link-uri expirate. Dacă un link eșuează, aplicația va prelua fluxuri noi.", + "how_it_works": "Cum funcționează", + "how_it_works_cached": "• Fluxurile sunt stocate pentru durata selectată după redare\n• Fluxurile cache sunt validate înainte de utilizare\n• Dacă cache-ul este invalid sau expirat, revine la ecranul de conținut\n• „Folosește fluxuri stocate” controlează navigarea directă în player\n• „Deschide ecranul de metadate” apare doar când cache-ul este dezactivat", + "how_it_works_uncached": "• Când cache-ul este dezactivat, apăsarea pe elemente deschide ecranele de conținut\n• Opțiunea „Deschide ecranul de metadate” controlează ce ecran se deschide\n• Ecranul de metadate arată detalii și permite selecția manuală\n• Ecranul de fluxuri arată sursele disponibile pentru redare imediată", + "changes_saved": "Modificări salvate", + "min": "min", + "hour": "oră", + "hours": "ore" + }, + "contributors": { + "title": "Contribuitori", + "special_mentions": "Mențiuni Speciale", + "tab_contributors": "Contribuitori", + "tab_special": "Mențiuni Speciale", + "tab_donors": "Donatori", + "manager_role": "Community Manager", + "manager_desc": "Gestionează comunitățile Discord și Reddit pentru Nuvio", + "sponsor_role": "Sponsor Server", + "sponsor_desc": "A sponsorizat infrastructura de servere pentru Nuvio", + "mod_role": "Mod Discord", + "mod_desc": "Ajută la moderarea comunității Nuvio pe Discord", + "loading": "Se încarcă...", + "discord_user": "Utilizator Discord", + "contributions": "contribuții", + "gratitude_title": "Suntem recunoscători pentru fiecare contribuție", + "gratitude_desc": "Fiecare linie de cod, raport de eroare și sugestie ajută la îmbunătățirea Nuvio pentru toți", + "special_thanks_title": "Mulțumiri Speciale", + "special_thanks_desc": "Acești oameni minunați ajută la menținerea comunității Nuvio și a serverelor online", + "donors_desc": "Vă mulțumim pentru că credeți în ceea ce construim. Sprijinul vostru menține Nuvio gratuit și în continuă îmbunătățire.", + "latest_donations": "Ultimele", + "leaderboard": "Clasament", + "loading_donors": "Se încarcă donatorii…", + "no_donors": "Încă nu sunt donatori", + "error_rate_limit": "Limita API GitHub a fost depășită. Reîncearcă mai târziu.", + "error_failed": "Eșec la încărcarea contribuitorilor. Verifică conexiunea la internet.", + "retry": "Încearcă din nou", + "no_contributors": "Niciun contribuitor găsit", + "loading_contributors": "Se încarcă contribuitorii..." + }, + "debrid": { + "title": "Integrare Debrid", + "description_torbox": "Deblochează fluxuri 4K de înaltă calitate și viteze fulgerătoare prin integrarea Torbox. Introdu cheia API mai jos pentru a-ți îmbunătăți experiența de streaming.", + "description_torrentio": "Configurează Torrentio pentru a obține fluxuri torrent pentru filme și seriale. Un serviciu debrid este necesar pentru redarea conținutului.", + "tab_torbox": "TorBox", + "tab_torrentio": "Torrentio", + "status_connected": "Conectat", + "status_disconnected": "Deconectat", + "enable_addon": "Activează Extensia", + "disconnect_button": "Deconectează și Elimină", + "disconnect_loading": "Se deconectează...", + "account_info": "Informații Cont", + "plan": "Plan", + "plan_free": "Gratuit", + "plan_essential": "Essential ($3/lună)", + "plan_pro": "Pro ($10/lună)", + "plan_standard": "Standard ($5/lună)", + "plan_unknown": "Necunoscut", + "expires": "Expiră", + "downloaded": "Descărcat", + "status_active": "Activ", + "connected_title": "✓ Conectat la TorBox", + "connected_desc": "Extensia ta TorBox este activă și oferă fluxuri premium.", + "configure_title": "Configurează Extensia", + "configure_desc": "Personalizează experiența de streaming. Sortează după calitate, filtrează dimensiunile fișierelor și gestionează alte setări.", + "open_settings": "Deschide Setările", + "what_is_debrid": "Ce este un serviciu Debrid?", + "enter_api_key": "Introdu cheia API", + "connect_button": "Conectează și Instalează", + "connecting": "Se conectează...", + "unlock_speeds_title": "Deblochează viteze premium", + "unlock_speeds_desc": "Obține un abonament Torbox pentru a accesa fluxuri cache de înaltă calitate fără buffering.", + "get_subscription": "Obține abonament", + "powered_by": "Powered by", + "disclaimer_torbox": "Nuvio nu este afiliat cu Torbox în niciun fel.", + "disclaimer_torrentio": "Nuvio nu este afiliat cu Torrentio în niciun fel.", + "installed_badge": "✓ INSTALAT", + "promo_title": "⚡ Ai nevoie de un serviciu Debrid?", + "promo_desc": "Obține TorBox pentru streaming 4K rapid. Torrente cache premium și descărcări instantanee.", + "promo_button": "Obține abonament TorBox", + "service_label": "Serviciu Debrid *", + "api_key_label": "Cheie API *", + "sorting_label": "Sortare", + "exclude_qualities": "Exclude Calități", + "priority_languages": "Limbi Prioritare", + "max_results": "Rezultate Maxime", + "additional_options": "Opțiuni adiționale", + "no_download_links": "Nu afișa link-uri de descărcare", + "no_debrid_catalog": "Nu afișa catalogul debrid", + "install_button": "Instalează Torrentio", + "installing": "Se instalează...", + "update_button": "Actualizează Configurația", + "updating": "Se actualizează...", + "remove_button": "Elimină Torrentio", + "error_api_required": "Cheie API obligatorie", + "error_api_required_desc": "Te rugăm să introduci cheia API debrid pentru a instala Torrentio.", + "success_installed": "Extensia Torrentio a fost instalată cu succes!", + "success_removed": "Extensia Torrentio a fost eliminată cu succes", + "alert_disconnect_title": "Deconectează Torbox", + "alert_disconnect_msg": "Ești sigur că vrei să deconectezi Torbox? Această acțiune va elimina extensia și cheia API salvată." + }, + "home_screen": { + "title": "Setări Ecran Principal", + "changes_applied": "Modificări aplicate", + "display_options": "OPȚIUNI AFIȘARE", + "show_hero": "Arată secțiunea Hero", + "show_hero_desc": "Conținut recomandat în partea de sus", + "show_this_week": "Arată secțiunea Săptămâna aceasta", + "show_this_week_desc": "Episoade noi din săptămâna curentă", + "select_catalogs": "Selectează Cataloage", + "all_catalogs": "Toate cataloagele", + "selected": "selectate", + "hero_layout": "Layout Hero", + "layout_legacy": "Clasic", + "layout_carousel": "Carusel", + "layout_appletv": "Apple TV", + "layout_desc": "Banner pe toată lățimea, carduri glisante sau stil Apple TV", + "featured_source": "Sursă recomandate", + "using_catalogs": "Se folosesc cataloage", + "manage_selected_catalogs": "Gestionează cataloagele selectate", + "dynamic_bg": "Fundal Hero Dinamic", + "dynamic_bg_desc": "Banner încețoșat în spatele caruselului", + "performance_note": "Poate afecta performanța pe dispozitivele mai slabe.", + "posters": "Postere", + "show_titles": "Arată Titlurile", + "poster_size": "Dimensiune Poster", + "poster_corners": "Colțuri Poster", + "size_small": "Mic", + "size_medium": "Mediu", + "size_large": "Mare", + "corners_square": "Pătrat", + "corners_rounded": "Rotunjit", + "corners_pill": "Pastilă", + "about_these_settings": "DESPRE ACESTE SETĂRI", + "about_desc": "Aceste setări controlează modul în care conținutul este afișat pe ecranul principal. Modificările se aplică imediat.", + "hero_catalogs": { + "title": "Cataloage Secțiune Hero", + "select_all": "Selectează Tot", + "clear_all": "Șterge Tot", + "info": "Selectează ce cataloage să apară în secțiunea hero. Dacă nu selectezi niciunul, vor fi folosite toate. Nu uita să apeși Salvează.", + "settings_saved": "Setări Salvate", + "error_load": "Eșec la încărcarea cataloagelor", + "movies": "Filme", + "tv_shows": "Seriale TV" + } + }, + "calendar": { + "title": "Calendar", + "loading": "Se încarcă calendarul...", + "no_scheduled_episodes": "Niciun episod programat", + "check_back_later": "Revino mai târziu", + "showing_episodes_for": "Se afișează episoadele pentru {{date}}", + "show_all_episodes": "Arată toate episoadele", + "no_episodes_for": "Niciun episod pentru {{date}}", + "no_upcoming_found": "Niciun episod viitor găsit", + "add_series_desc": "Adaugă seriale în bibliotecă pentru a vedea episoadele lor viitoare aici" + }, + "mdblist": { + "title": "Surse de evaluare", + "status_disabled": "MDBList dezactivat", + "status_active": "Cheie API activă", + "status_required": "Cheie API obligatorie", + "status_disabled_desc": "Funcționalitatea MDBList este momentan dezactivată.", + "status_active_desc": "Evaluările de la MDBList sunt activate.", + "status_required_desc": "Adaugă cheia mai jos pentru a activa evaluările.", + "enable_toggle": "Activează MDBList", + "enable_toggle_desc": "Pornește/oprește toate funcțiile MDBList", + "api_section": "Cheie API", + "placeholder": "Lipește cheia API MDBList", + "save": "Salvează", + "clear": "Șterge cheia", + "rating_providers": "Furnizori de evaluări", + "rating_providers_desc": "Alege ce evaluări să fie afișate în aplicație", + "how_to": "Cum obții o cheie API", + "step_1": "Autentifică-te pe", + "step_1_link": "site-ul MDBList", + "step_2": "Mergi la secțiunea", + "step_2_settings": "Settings", + "step_2_api": "API", + "step_2_end": ".", + "step_3": "Generează o cheie nouă și copiază-o.", + "go_to_website": "Mergi la MDBList", + "alert_clear_title": "Șterge Cheia API", + "alert_clear_msg": "Ești sigur că vrei să elimini cheia API salvată?", + "success_saved": "Cheia API a fost salvată cu succes.", + "error_empty": "Cheia API nu poate fi goală.", + "error_save": "A apărut o eroare la salvare. Te rugăm să încerci din nou.", + "api_key_empty_error": "Cheia API nu poate fi goală.", + "success_cleared": "Cheia API a fost ștearsă cu succes", + "error_clear": "Eșec la ștergerea cheii API" + }, + "notification": { + "title": "Setări notificări", + "section_general": "General", + "enable_notifications": "Activează notificările", + "section_types": "Tipuri de notificări", + "new_episodes": "Episoade noi", + "upcoming_shows": "Seriale viitoare", + "reminders": "Mementouri", + "section_timing": "Sincronizare notificări", + "timing_desc": "Cu cât timp înainte de difuzare să fii notificat?", + "hours_1": "1 oră", + "hours_suffix": "ore", + "section_status": "Status notificări", + "stats_upcoming": "Viitoare", + "stats_this_week": "Săptămâna aceasta", + "stats_total": "Total", + "sync_button": "Sincronizează Biblioteca și Trakt", + "syncing": "Se sincronizează...", + "sync_desc": "Sincronizează automat notificările pentru serialele din bibliotecă și watchlist-ul Trakt.", + "section_advanced": "Avansat", + "reset_button": "Resetează toate notificările", + "test_button": "Testează notificarea (5 sec)", + "test_notification_in": "Notificare în {{seconds}}s...", + "test_notification_text": "Notificarea va apărea în {{seconds}} secunde", + "alert_reset_title": "Resetează notificările", + "alert_reset_msg": "Această acțiune va anula toate notificările programate, dar nu va șterge nimic din bibliotecă. Ești sigur?", + "alert_reset_success": "Toate notificările au fost resetate", + "alert_sync_complete": "Sincronizare finalizată", + "alert_sync_msg": "S-au sincronizat notificările pentru bibliotecă și Trakt.\n\nProgramate: {{upcoming}} episoade viitoare\nSăptămâna aceasta: {{thisWeek}} episoade", + "alert_test_scheduled": "Notificarea de test a fost programată" + }, + "backup": { + "title": "Backup și Restaurare", + "options_title": "Opțiuni Backup", + "options_desc": "Alege ce dorești să incluzi în backup", + "section_core": "Date de bază", + "section_addons": "Extensii și Integrări", + "section_settings": "Setări și Preferințe", + "library_label": "Bibliotecă", + "library_desc": "Filmele și serialele tale salvate", + "watch_progress_label": "Progres vizionare", + "watch_progress_desc": "Pozițiile de unde ai rămas", + "addons_label": "Extensii", + "addons_desc": "Extensiile Stremio instalate", + "plugins_label": "Module", + "plugins_desc": "Configurații personalizate de scannere", + "trakt_label": "Integrare Trakt", + "trakt_desc": "Sincronizare date și token-uri de autentificare", + "app_settings_label": "Setări Aplicație", + "app_settings_desc": "Temă, preferințe și configurații", + "user_prefs_label": "Preferințe Utilizator", + "user_prefs_desc": "Ordinea extensiilor și setări UI", + "catalog_settings_label": "Setări Catalog", + "catalog_settings_desc": "Filtre de catalog și preferințe", + "api_keys_label": "Chei API", + "api_keys_desc": "Cheile MDBList și OpenRouter", + "action_create": "Creează Backup", + "action_restore": "Restaurează din Backup", + "section_info": "Despre Backup-uri", + "info_text": "• Personalizează backup-ul folosind comutatoarele de mai sus\n• Fișierele de backup sunt stocate local pe dispozitiv\n• Trimite fișierul de backup pentru a transfera datele pe alt dispozitiv\n• Restaurarea va suprascrie datele tale actuale", + "alert_create_title": "Creează Backup", + "alert_no_content": "Niciun conținut selectat pentru backup.\n\nTe rugăm să activezi cel puțin o opțiune de mai sus.", + "alert_backup_created_title": "Backup Creat", + "alert_backup_created_msg": "Backup-ul a fost creat și este gata de a fi trimis.", + "alert_backup_failed_title": "Eșec Backup", + "alert_restore_confirm_title": "Confirmă Restaurarea", + "alert_restore_confirm_msg": "Această acțiune va restaura datele dintr-un backup creat pe {{date}}.\n\nDatele actuale vor fi suprascrise. Ești sigur că vrei să continui?", + "alert_restore_complete_title": "Restaurare Completă", + "alert_restore_complete_msg": "Datele au fost restaurate cu succes. Te rugăm să repornești aplicația.", + "alert_restore_failed_title": "Eșec Restaurare", + "restart_app": "Repornește Aplicația", + "alert_restart_failed_title": "Repornire eșuată", + "alert_restart_failed_msg": "Aplicația nu a putut fi repornită automat. Te rugăm să o închizi și să o redeschizi manual." + }, + "updates": { + "title": "Actualizări Aplicație", + "status_checking": "Se caută actualizări...", + "status_available": "Actualizare disponibilă!", + "status_downloading": "Se descarcă actualizarea...", + "status_installing": "Se instalează actualizarea...", + "status_success": "Actualizare instalată cu succes!", + "status_error": "Actualizarea a eșuat", + "status_ready": "Gata pentru verificare", + "action_check": "Verifică Actualizări", + "action_install": "Instalează Actualizarea", + "release_notes": "Notele ediției:", + "version": "Versiune:", + "last_checked": "Ultima verificare:", + "current_version": "Versiunea curentă:", + "current_release_notes": "Notele versiunii actuale:", + "github_release": "VERSIUNE GITHUB", + "current": "Curentă:", + "latest": "Ultima:", + "notes": "Note:", + "view_release": "Vezi detalii", + "notification_settings": "SETĂRI NOTIFICĂRI", + "ota_alerts_label": "Alerte actualizări OTA", + "ota_alerts_desc": "Arată notificări pentru actualizările over-the-air", + "major_alerts_label": "Alerte actualizări majore", + "major_alerts_desc": "Arată notificări pentru versiuni noi de aplicație pe GitHub", + "alert_disable_ota_title": "Dezactivezi alertele OTA?", + "alert_disable_ota_msg": "Nu vei mai primi notificări automate pentru actualizările OTA.\n\n⚠️ Atenție: Este important să fii pe ultima versiune pentru:\n• Corecții și stabilitate\n• Funcții noi\n• Raportare corectă a erorilor", + "alert_disable_major_title": "Dezactivezi alertele majore?", + "alert_disable_major_msg": "Nu vei mai primi notificări pentru actualizările care necesită reinstalare.\n\n⚠️ Atenție: Actualizările majore includ adesea:\n• Patch-uri critice de securitate\n• Modificări structurale\n• Fix-uri de compatibilitate", + "warning_note": "Păstrarea alertelor activate te asigură că primești rapid corecțiile de bug-uri.", + "disable": "Dezactivează", + "alert_no_update_to_install": "Nicio actualizare disponibilă pentru instalare", + "alert_install_failed": "Eșec la instalarea actualizării", + "alert_no_update_title": "Fără actualizări", + "alert_update_applied_msg": "Actualizarea va fi aplicată la următoarea repornire" + }, + "player": { + "title": "Video Player", + "section_selection": "SELECȚIE PLAYER", + "internal_title": "Player integrat", + "internal_desc": "Folosește player-ul implicit al aplicației", + "vlc_title": "VLC", + "vlc_desc": "Deschide fluxurile în VLC media player", + "infuse_title": "Infuse", + "infuse_desc": "Deschide fluxurile în player-ul Infuse", + "outplayer_title": "OutPlayer", + "outplayer_desc": "Deschide fluxurile în OutPlayer", + "vidhub_title": "VidHub", + "vidhub_desc": "Deschide fluxurile în player-ul VidHub", + "infuse_live_title": "Infuse Livecontainer", + "infuse_live_desc": "Deschide fluxurile în Infuse LiveContainer", + "external_title": "Player extern", + "external_desc": "Deschide fluxurile în player-ul tău preferat", + "section_playback": "OPȚIUNI REDARE", + "skip_intro_settings_title": "Sari peste Intro", + "powered_by_introdb": "Pus la dispoziție de IntroDB", + "autoplay_title": "Redare automată primului flux", + "autoplay_desc": "Începe automat primul flux din listă.", + "resume_title": "Reluare automată", + "resume_desc": "Sari peste confirmarea de reluare și continuă automat unde ai rămas (dacă ai vizionat sub 85%).", + "engine_title": "Motor Video Player", + "engine_desc": "Auto folosește ExoPlayer cu rezervă MPV. Unele formate ca Dolby Vision pot necesita modul Auto pentru compatibilitate maximă.", + "decoder_title": "Mod Decodor", + "decoder_desc": "Modul în care este decodat video. Auto este recomandat.", + "gpu_title": "Randare GPU", + "gpu_desc": "GPU-Next oferă un management mai bun al culorilor și HDR.", + "external_downloads_title": "Player extern pentru descărcări", + "external_downloads_desc": "Redă conținutul descărcat într-un player extern.", + "restart_required": "Repornire obligatorie", + "restart_msg_decoder": "Te rugăm să repornești aplicația pentru ca schimbarea decodorului să fie aplicată.", + "restart_msg_gpu": "Te rugăm să repornești aplicația pentru ca schimbarea modului GPU să fie aplicată.", + "option_auto": "Auto", + "option_auto_desc_engine": "ExoPlayer + rezervă MPV", + "option_mpv": "MPV", + "option_mpv_desc": "Doar MPV", + "option_auto_desc_decoder": "Cel mai bun echilibru", + "option_sw": "SW", + "option_sw_desc": "Software", + "option_hw": "HW", + "option_hw_desc": "Hardware", + "option_hw_plus": "HW+", + "option_hw_plus_desc": "Hardware Complet", + "option_gpu_desc": "Standard", + "option_gpu_next_desc": "Avansat" + }, + "plugins": { + "title": "Module", + "enable_title": "Activează Modulele", + "enable_desc": "Activează motorul de module pentru a prelua surse media externe", + "repo_config_title": "Configurare depozite", + "repo_config_desc": "Gestionează depozitele externe. Comută fiecare depozit pornit sau oprit.", + "your_repos": "Depozite", + "your_repos_desc": "Configurează sursele externe pentru module.", + "add_repo_button": "Adaugă Depozit", + "refresh": "Împrospătează", + "remove": "Elimină", + "enabled": "Activat", + "disabled": "Dezactivat", + "updating": "Se actualizează...", + "success": "Succes", + "error": "Eroare", + "alert_repo_added": "Depozitul a fost adăugat și modulele au fost încărcate", + "alert_repo_saved": "URL-ul depozitului a fost salvat", + "alert_repo_refreshed": "Depozit împrospătat cu succes", + "alert_invalid_url": "Format URL invalid", + "alert_plugins_cleared": "Toate modulele au fost eliminate", + "alert_cache_cleared": "Cache depozit șters cu succes", + "unknown": "Necunoscut", + "active": "Activ", + "available": "Disponibil", + "platform_disabled": "Platformă dezactivată", + "limited": "Limitat", + "clear_all": "Șterge toate modulele", + "clear_all_desc": "Ești sigur că vrei să elimini toate modulele instalate? Această acțiune este ireversibilă.", + "clear_cache": "Șterge Cache Depozit", + "clear_cache_desc": "Această acțiune va șterge URL-ul salvat și toate datele cache. Va trebui să introduci din nou URL-ul depozitului.", + "add_new_repo": "Adaugă depozit nou", + "available_plugins": "Module disponibile ({{count}})", + "placeholder": "Caută module...", + "all": "Toate", + "filter_all": "Toate tipurile", + "filter_movies": "Filme", + "filter_tv": "Seriale TV", + "enable_all": "Activează tot", + "disable_all": "Dezactivează tot", + "no_plugins_found": "Niciun modul găsit", + "no_plugins_available": "Niciun modul disponibil", + "no_match_desc": "Niciun modul nu se potrivește cu „{{query}}”.", + "configure_repo_desc": "Configurează un depozit mai sus pentru a vedea modulele disponibile.", + "clear_search": "Șterge căutarea", + "no_external_player": "Fără player extern", + "showbox_token": "Token UI ShowBox", + "showbox_placeholder": "Lipește token-ul UI ShowBox", + "save": "Salvează", + "clear": "Șterge", + "additional_settings": "Setări adiționale", + "enable_url_validation": "Activează validarea URL", + "url_validation_desc": "Validează link-urile media înainte de a le returna (poate încetini rezultatele, dar crește fiabilitatea)", + "group_streams": "Grupează sursele modulelor", + "group_streams_desc": "Sursele sunt grupate după depozit.", + "sort_quality": "Sortează după calitate mai întâi", + "sort_quality_desc": "Valabil doar când gruparea este activată.", + "show_logos": "Arată logo-urile modulelor", + "show_logos_desc": "Afișează pictograma modulului lângă link-urile media.", + "quality_filtering": "Filtrare calitate", + "quality_filtering_desc": "Exclude rezoluții specifice din rezultate. Apasă pe o calitate pentru a o exclude.", + "excluded_qualities": "Calități excluse:", + "language_filtering": "Filtrare limbă", + "language_filtering_desc": "Exclude limbi specifice din rezultate.", + "note": "Notă:", + "language_filtering_note": "Acest filtru se aplică doar furnizorilor care oferă informații despre limbă.", + "excluded_languages": "Limbi excluse:", + "about_title": "Despre Module", + "about_desc_1": "Modulele sunt componente care adaptează conținutul din diverse protocoale externe. Rulează local și pot fi instalate din depozite de încredere.", + "about_desc_2": "Modulele marcate ca „Limitat” pot necesita configurații externe specifice.", + "help_title": "Configurare Module", + "help_step_1": "1. **Activează Modulele** - Pornește comutatorul principal", + "help_step_2": "2. **Adaugă Depozit** - Introdu un URL de depozit valid", + "help_step_3": "3. **Împrospătează** - Descarcă lista de module", + "help_step_4": "4. **Activează** - Pornește modulele dorite", + "got_it": "Am înțeles!", + "repo_format_hint": "Format: https://raw.githubusercontent.com/user/repo/branch", + "cancel": "Anulează", + "add": "Adaugă" + }, + "theme": { + "title": "Teme Aplicație", + "select_theme": "SELECTEAZĂ TEMA", + "create_custom": "Creează Temă Personalizată", + "options": "OPȚIUNI", + "use_dominant_color": "Folosește culoarea dominantă din artwork", + "categories": { + "all": "Toate temele", + "dark": "Teme întunecate", + "colorful": "Colorate", + "custom": "Temele mele" + }, + "editor": { + "theme_name_placeholder": "Nume temă", + "save": "Salvează", + "primary": "Primară", + "secondary": "Secundară", + "background": "Fundal", + "invalid_name_title": "Nume invalid", + "invalid_name_msg": "Te rugăm să introduci un nume valid" + }, + "alerts": { + "delete_title": "Șterge Tema", + "delete_msg": "Ești sigur că vrei să ștergi „{{name}}”?", + "ok": "OK", + "delete": "Șterge", + "cancel": "Anulează", + "back": "Setări" + } + }, + "legal": { + "title": "Juridic și Declinarea responsabilității", + "intro_title": "Natura Aplicației", + "intro_text": "Nuvio este un player media și o aplicație de gestionare a metadatelor. Acționează exclusiv ca o interfață pentru navigarea metadatelor publice și redarea fișierelor oferite de utilizator sau extensii terțe. Nuvio nu găzduiește, stochează sau distribuie conținut media.", + "extensions_title": "Module Terțe", + "extensions_text": "Nuvio permite instalarea modulelor dezvoltate de terți. Acestea nu sunt afiliate cu Nuvio. Nu ne asumăm responsabilitatea pentru conținutul sau legalitatea acestora.", + "user_resp_title": "Responsabilitatea Utilizatorului", + "user_resp_text": "Utilizatorii sunt singurii responsabili pentru modulele instalate. Prin utilizarea aplicației, confirmi că ai dreptul legal de a accesa conținutul vizionat.", + "dmca_title": "Drepturi de autor și DMCA", + "dmca_text": "Respectăm proprietatea intelectuală. Deoarece Nuvio nu găzduiește conținut, nu îl putem elimina de pe internet. Dacă interfața aplicației îți încalcă drepturile, te rugăm să ne contactezi.", + "warranty_title": "Fără Garanție", + "warranty_text": "Software-ul este oferit „ca atare”, fără nicio garanție expresă sau implicită." + }, + "plugin_tester": { + "title": "Tester Module", + "subtitle": "Rulează scannere și verifică log-urile în timp real", + "tabs": { + "individual": "Individual", + "repo": "Tester Depozit", + "code": "Cod", + "logs": "Log-uri", + "results": "Rezultate" + }, + "common": { + "error": "Eroare", + "success": "Succes", + "movie": "Film", + "tv": "Serial", + "tmdb_id": "TMDB ID", + "season": "Sezon", + "episode": "Episod", + "running": "Se execută...", + "run_test": "Rulează Test", + "play": "Redă", + "done": "Gata", + "test": "Test", + "testing": "Se testează..." + }, + "individual": { + "load_from_url": "Încarcă din URL", + "load_from_url_desc": "Lipește un URL brut de GitHub sau IP local.", + "enter_url_error": "Te rugăm să introduci un URL", + "code_loaded": "Cod încărcat din URL", + "fetch_error": "Eșec la preluare: {{message}}", + "no_code_error": "Niciun cod de rulat", + "plugin_code": "Cod Modul", + "focus_editor": "Focalizează editorul", + "code_placeholder": "// Lipește codul modului aici...", + "test_parameters": "Parametri Test", + "no_logs": "Niciun log momentan. Rulează un test.", + "no_streams": "Niciun flux găsit.", + "streams_found": "{{count}} flux găsit", + "streams_found_plural": "{{count}} fluxuri găsite", + "tap_play_hint": "Apasă Redă pentru a testa fluxul.", + "unnamed_stream": "Flux fără nume", + "quality": "Calitate: {{quality}}", + "size": "Dimensiune: {{size}}", + "url_label": "URL: {{url}}", + "headers_info": "Header-e: {{count}} personalizate", + "find_placeholder": "Caută în cod...", + "edit_code_title": "Editează Codul", + "no_url_stream_error": "Nu s-a găsit URL pentru acest flux" + }, + "repo": { + "title": "Tester Depozit", + "description": "Preia un depozit și testează fiecare furnizor.", + "enter_repo_url_error": "Introdu un URL de depozit", + "invalid_url_title": "URL Invalid", + "invalid_url_msg": "Folosește un URL brut GitHub sau local.", + "manifest_build_error": "Nu s-a putut construi URL-ul manifestului", + "manifest_fetch_error": "Eșec la preluarea manifestului", + "repo_manifest_fetch_error": "Eșec la preluarea manifestului depozitului", + "missing_filename": "Nume fișier lipsă în manifest", + "scraper_build_error": "Nu s-a putut construi URL-ul scannerului", + "download_scraper_error": "Eșec la descărcarea scannerului", + "test_failed": "Test eșuat", + "test_parameters": "Parametri Test Depozit", + "test_parameters_desc": "Acești parametri sunt folosiți doar în Testerul de Depozit.", + "using_info": "Folosind: {{mediaType}} • TMDB {{tmdbId}}", + "using_info_tv": "Folosind: {{mediaType}} • TMDB {{tmdbId}} • S{{season}}E{{episode}}", + "providers_title": "Furnizori", + "repository_default": "Depozit", + "providers_count": "{{count}} furnizori", + "fetch_hint": "Preia un depozit pentru a vedea furnizorii.", + "test_all": "Testează tot", + "status_running": "RULEAZĂ", + "status_ok": "OK ({{count}})", + "status_ok_empty": "OK (0)", + "status_failed": "EȘUAT", + "status_idle": "INACTIV", + "tried_url": "S-a încercat: {{url}}", + "provider_logs": "Log-uri furnizor", + "no_logs_captured": "Niciun log capturat." + } + } +} diff --git a/src/i18n/locales/ru.json b/src/i18n/locales/ru.json new file mode 100644 index 00000000..ceca3c79 --- /dev/null +++ b/src/i18n/locales/ru.json @@ -0,0 +1,1430 @@ +{ + "common": { + "loading": "Загрузка...", + "cancel": "Отмена", + "save": "Сохранить", + "delete": "Удалить", + "edit": "Изменить", + "search": "Поиск", + "error": "Ошибка", + "success": "Успешно", + "ok": "ОК", + "unknown": "Неизвестно", + "retry": "Повторить", + "try_again": "Попробовать еще раз", + "go_back": "Назад", + "settings": "Настройки", + "close": "Закрыть", + "enable": "Включить", + "disable": "Выключить", + "show_more": "Показать больше", + "show_less": "Показать меньше", + "load_more": "Загрузить еще", + "unknown_date": "Дата неизвестна", + "anonymous_user": "Анонимный пользователь", + "time": { + "now": "Только что", + "minutes_ago": "{{count}} мин. назад", + "hours_ago": "{{count}} ч. назад", + "days_ago": "{{count}} дн. назад" + }, + "days_short": { + "sun": "Вс", + "mon": "Пн", + "tue": "Вт", + "wed": "Ср", + "thu": "Чт", + "fri": "Пт", + "sat": "Сб" + }, + "email": "Email", + "status": "Статус" + }, + "home": { + "categories": { + "movies": "Фильмы", + "series": "Сериалы", + "channels": "Каналы" + }, + "movies": "Фильмы", + "tv_shows": "ТВ-Шоу", + "load_more_catalogs": "Загрузить другие каталоги", + "no_content": "Контент недоступен", + "add_catalogs": "Добавить каталоги", + "sign_in_available": "Доступен вход", + "sign_in_desc": "Вы можете войти в любое время в меню Настройки → Аккаунт", + "view_all": "Смотреть все", + "this_week": "На этой неделе", + "upcoming": "Ожидаемые", + "recently_released": "Недавние релизы", + "no_scheduled_episodes": "Сериалы без расписания серий", + "check_back_later": "Зайдите позже", + "continue_watching": "Продолжить просмотр", + "up_next": "Далее", + "up_next_caps": "ДАЛЕЕ", + "released": "Выпущено", + "new": "Новое", + "tba": "Будет объявлено", + "new_episodes": "{{count}} новых серий", + "season_short": "С{{season}}", + "episode_short": "Э{{episode}}", + "season": "Сезон {{season}}", + "episode": "Серия {{episode}}", + "movie": "Фильм", + "series": "Сериал", + "tv_show": "ТВ-Шоу", + "percent_watched": "{{percent}}% просмотрено", + "view_details": "Подробнее", + "remove": "Удалить", + "play": "Смотреть", + "play_now": "Смотреть сейчас", + "resume": "Продолжить", + "info": "Инфо", + "more_info": "Больше информации", + "my_list": "Мой список", + "save": "Сохранить", + "saved": "Сохранено", + "retry": "Повторить", + "install_addons": "Установить дополнения", + "settings": "Настройки", + "no_featured_content": "Нет рекомендуемого контента", + "couldnt_load_featured": "Не удалось загрузить рекомендации", + "no_featured_desc": "Установите дополнения с каталогами или измените источник контента в настройках.", + "load_error_desc": "Произошла ошибка при загрузке рекомендаций. Проверьте соединение и попробуйте снова.", + "no_featured_available": "Рекомендации отсутствуют", + "no_description": "Описание отсутствует" + }, + "navigation": { + "home": "Главная", + "library": "Библиотека", + "search": "Поиск", + "downloads": "Загрузки", + "settings": "Настройки" + }, + "search": { + "title": "Поиск", + "recent_searches": "История поиска", + "discover": "Обзор", + "movies": "Фильмы", + "tv_shows": "ТВ-Шоу", + "select_catalog": "Выберите каталог", + "all_genres": "Все жанры", + "discovering": "Поиск контента...", + "show_more": "Показать больше ({{count}})", + "no_content_found": "Контент не найден", + "try_different": "Попробуйте другой жанр или каталог", + "select_catalog_desc": "Выберите каталог для поиска", + "tap_catalog_desc": "Нажмите на кнопку каталога выше, чтобы начать", + "placeholder": "Фильмы, сериалы...", + "keep_typing": "Продолжайте ввод...", + "type_characters": "Введите минимум 2 символа для поиска", + "no_results": "Результатов не найдено", + "try_keywords": "Попробуйте другие ключевые слова или проверьте опечатки", + "select_type": "Выберите тип", + "browse_movies": "Просмотр каталогов фильмов", + "browse_tv": "Просмотр каталогов сериалов", + "select_genre": "Выберите жанр", + "show_all_content": "Показать весь контент", + "genres_count": "Жанров: {{count}}" + }, + "library": { + "title": "Библиотека", + "watched": "Просмотрено", + "continue": "Продолжить", + "watchlist": "Список желаемого", + "collection": "Коллекция", + "rated": "С оценкой", + "items": "объектов", + "trakt_collections": "Коллекции Trakt", + "trakt_collection": "Коллекция Trakt", + "no_trakt": "Нет коллекций Trakt", + "no_trakt_desc": "Ваши коллекции Trakt появятся здесь после авторизации", + "load_collections": "Загрузить коллекции", + "empty_folder": "Нет контента в {{folder}}", + "empty_folder_desc": "Эта коллекция пуста", + "refresh": "Обновить", + "no_movies": "Фильмов пока нет", + "no_series": "Сериалов пока нет", + "no_content": "Контента пока нет", + "add_content_desc": "Добавьте контент в библиотеку, чтобы увидеть его здесь", + "find_something": "Найти что-нибудь интересное", + "removed_from_library": "Удалено из библиотеки", + "item_removed": "Объект удален из вашей библиотеки", + "failed_update_library": "Не удалось обновить библиотеку", + "unable_remove": "Не удалось удалить объект из библиотеки", + "marked_watched": "Отмечено как просмотренное", + "marked_unwatched": "Отмечено как непросмотренное", + "item_marked_watched": "Объект отмечен как просмотренный", + "item_marked_unwatched": "Объект отмечен как непросмотренный", + "failed_update_watched": "Не удалось обновить статус просмотра", + "unable_update_watched": "Не удалось обновить статус просмотра", + "added_to_library": "Добавлено в библиотеку", + "item_added": "Добавлено в локальную библиотеку", + "add_to_library": "Добавить в библиотеку", + "remove_from_library": "Удалить из библиотеки", + "mark_watched": "Отметить как просмотренное", + "mark_unwatched": "Отметить как непросмотренное", + "share": "Поделиться", + "add_to_watchlist": "Добавить в список желаемого Trakt", + "remove_from_watchlist": "Удалить из списка желаемого Trakt", + "added_to_watchlist": "Добавлено в список желаемого", + "added_to_watchlist_desc": "Объект добавлен в ваш список желаемого Trakt", + "removed_from_watchlist": "Удалено из списка желаемого", + "removed_from_watchlist_desc": "Объект удален из вашего списка желаемого Trakt", + "add_to_collection": "Добавить в коллекцию Trakt", + "remove_from_collection": "Удалить из коллекции Trakt", + "added_to_collection": "Добавлено в коллекцию", + "added_to_collection_desc": "Объект добавлен в вашу коллекцию Trakt", + "removed_from_collection": "Удалено из коллекции", + "removed_from_collection_desc": "Объект удален из вашей коллекции Trakt" + }, + "metadata": { + "unable_to_load": "Не удалось загрузить контент", + "error_code": "Код ошибки: {{code}}", + "content_not_found": "Контент не найден", + "content_not_found_desc": "Этот контент не существует или был удален.", + "server_error": "Ошибка сервера", + "server_error_desc": "Сервер временно недоступен. Попробуйте позже.", + "bad_gateway": "Плохой шлюз", + "bad_gateway_desc": "На сервере возникли проблемы. Попробуйте позже.", + "service_unavailable": "Сервис недоступен", + "service_unavailable_desc": "Сервис на техническом обслуживании. Попробуйте позже.", + "too_many_requests": "Слишком много запросов", + "too_many_requests_desc": "Вы делаете слишком много запросов. Пожалуйста, подождите.", + "request_timeout": "Время ожидания истекло", + "request_timeout_desc": "Запрос занял слишком много времени. Попробуйте снова.", + "network_error": "Ошибка сети", + "network_error_desc": "Проверьте интернет-соединение и попробуйте снова.", + "auth_error": "Ошибка аутентификации", + "auth_error_desc": "Проверьте настройки аккаунта и попробуйте снова.", + "access_denied": "Доступ запрещен", + "access_denied_desc": "У вас нет прав для доступа к этому контенту.", + "connection_error": "Ошибка подключения", + "streams_unavailable": "Потоки недоступны", + "streams_unavailable_desc": "Источники трансляции сейчас недоступны. Попробуйте позже.", + "unknown_error": "Неизвестная ошибка", + "something_went_wrong": "Что-то пошло не так. Попробуйте снова.", + "cast": "Актеры", + "more_like_this": "Похожее", + "collection": "Коллекция", + "episodes": "Серии", + "seasons": "Сезоны", + "posters": "Постеры", + "banners": "Баннеры", + "specials": "Спецвыпуски", + "season_number": "Сезон {{number}}", + "episode_count": "{{count}} серия", + "episode_count_plural": "{{count}} серий", + "no_episodes": "Серии недоступны", + "no_episodes_for_season": "Для сезона {{season}} нет доступных серий", + "episodes_not_released": "Серии еще не вышли", + "no_description": "Описание отсутствует", + "episode_label": "СЕРИЯ {{number}}", + "watch_again": "Смотреть снова", + "completed": "Завершено", + "play_episode": "Смотреть С{{season}}Э{{episode}}", + "play": "Смотреть", + "watched": "Просмотрено", + "watched_on_trakt": "Просмотрено на Trakt", + "synced_with_trakt": "Синхронизировано с Trakt", + "saved": "Сохранено", + "director": "Режиссер", + "directors": "Режиссеры", + "creator": "Создатель", + "creators": "Создатели", + "production": "Производство", + "network": "Сеть", + "mark_watched": "Отметить как просмотренное", + "mark_unwatched": "Отметить как непросмотренное", + "marking": "Отметка...", + "removing": "Удаление...", + "unmark_season": "Снять отметку с сезона {{season}}", + "mark_season": "Отметить сезон {{season}}", + "resume": "Продолжить", + "spoiler_warning": "Предупреждение о спойлерах", + "spoiler_warning_desc": "Этот комментарий содержит спойлеры. Вы уверены, что хотите его прочитать?", + "cancel": "Отмена", + "reveal_spoilers": "Показать спойлеры", + "movie_details": "Детали фильма", + "show_details": "Детали шоу", + "tagline": "Слоган", + "status": "Статус", + "release_date": "Дата выхода", + "runtime": "Длительность", + "budget": "Бюджет", + "revenue": "Сборы", + "origin_country": "Страна", + "original_language": "Оригинальный язык", + "first_air_date": "Первый выход", + "last_air_date": "Последний выход", + "total_episodes": "Всего серий", + "episode_runtime": "Длительность серии", + "created_by": "Авторы", + "backdrop_gallery": "Галерея фонов", + "loading_episodes": "Загрузка серий...", + "no_episodes_available": "Нет доступных серий", + "play_next": "Смотреть С{{season}}Э{{episode}}", + "play_next_episode": "Следующая серия", + "save": "Сохранить", + "percent_watched": "{{percent}}% просмотрено", + "percent_watched_trakt": "{{percent}}% просмотрено ({{traktPercent}}% на Trakt)", + "synced_with_trakt_progress": "Прогресс синхронизирован с Trakt", + "using_trakt_progress": "Используется прогресс Trakt", + "added_to_collection_hero": "В коллекции", + "added_to_collection_desc_hero": "Добавлено в вашу коллекцию Trakt", + "removed_from_collection_hero": "Удалено из коллекции", + "removed_from_collection_desc_hero": "Удалено из вашей коллекции Trakt", + "mark_as_watched": "Отметить как просмотренное", + "mark_as_unwatched": "Отметить как непросмотренное" + }, + "cast": { + "biography": "Биография", + "known_for": "Известность за", + "personal_info": "Личная информация", + "born_in": "Место рождения: {{place}}", + "filmography": "Фильмография", + "also_known_as": "Также известен как", + "no_info_available": "Дополнительная информация отсутствует", + "as_character": "в роли {{character}}", + "loading_details": "Загрузка деталей...", + "years_old": "{{age}} лет", + "view_filmography": "Смотреть фильмографию", + "filter": "Фильтр", + "sort_by": "Сортировать по", + "sort_popular": "Популярности", + "sort_latest": "Новизне", + "sort_upcoming": "Ожидаемым", + "upcoming_badge": "ОЖИДАЕТСЯ", + "coming_soon": "Скоро", + "filmography_count": "Фильмография • {{count}} работ", + "loading_filmography": "Загрузка фильмографии...", + "load_more_remaining": "Загрузить еще (осталось {{count}})", + "alert_error_title": "Ошибка", + "alert_error_message": "Не удалось загрузить \"{{title}}\". Попробуйте позже.", + "alert_ok": "ОК", + "no_upcoming": "У этого актера нет предстоящих релизов", + "no_content": "Контент с этим актером отсутствует", + "no_movies": "Фильмы с этим актером отсутствуют", + "no_tv": "ТВ-шоу с этим актером отсутствуют" + }, + "comments": { + "title": "Комментарии Trakt", + "spoiler_warning": "⚠️ Комментарий содержит спойлеры. Нажмите, чтобы открыть.", + "spoiler": "Спойлер", + "contains_spoilers": "Содержит спойлеры", + "reveal": "Открыть", + "vip": "VIP", + "unavailable": "Комментарии недоступны", + "no_comments": "Комментариев на Trakt пока нет", + "not_in_database": "Этого контента еще может не быть в базе Trakt", + "check_trakt": "Проверить на Trakt" + }, + "trailers": { + "title": "Трейлеры", + "official_trailers": "Официальные трейлеры", + "official_trailer": "Официальный трейлер", + "teasers": "Тизеры", + "teaser": "Тизер", + "clips_scenes": "Клипы и сцены", + "clip": "Клип", + "featurettes": "О создании", + "featurette": "Ролик", + "behind_the_scenes": "За кулисами", + "no_trailers": "Трейлеры недоступны", + "unavailable": "Трейлер недоступен", + "unavailable_desc": "Не удалось загрузить трейлер. Попробуйте позже.", + "unable_to_play": "Не удалось воспроизвести трейлер. Попробуйте еще раз.", + "watch_on_youtube": "Смотреть на YouTube" + }, + "catalog": { + "no_content_found": "Контент не найден", + "no_content_filters": "По выбранным фильтрам ничего не найдено", + "loading_content": "Загрузка контента...", + "back": "Назад", + "in_theaters": "В кинотеатрах", + "all": "Все", + "failed_tmdb": "Не удалось загрузить данные из TMDB", + "movies": "Фильмы", + "tv_shows": "ТВ-Шоу", + "channels": "Каналы" + }, + "streams": { + "back_to_episodes": "Назад к сериям", + "back_to_info": "Назад к инфо", + "fetching_from": "Загрузка из:", + "no_sources_available": "Источники трансляции не найдены", + "add_sources_desc": "Пожалуйста, добавьте источники в настройках", + "add_sources": "Добавить источники", + "finding_streams": "Поиск доступных потоков...", + "finding_best_stream": "Поиск лучшего потока для автовоспроизведения...", + "still_fetching": "Все еще ищем потоки…", + "no_streams_available": "Потоки не найдены", + "starting_best_stream": "Запуск лучшего потока...", + "loading_more_sources": "Загрузка дополнительных источников..." + }, + "player_ui": { + "via": "через {{name}}", + "audio_tracks": "Аудиодорожки", + "no_audio_tracks": "Аудиодорожки недоступны", + "playback_speed": "Скорость воспроизведения", + "on_hold": "Удержание", + "playback_error": "Ошибка воспроизведения", + "unknown_error": "Произошла неизвестная ошибка при воспроизведении.", + "copy_error": "Копировать детали ошибки", + "copied_to_clipboard": "Скопировано в буфер обмена", + "dismiss": "Закрыть", + "continue_watching": "Продолжить просмотр", + "start_over": "Начать заново", + "resume": "Продолжить", + "change_source": "Сменить источник", + "switching_source": "Переключение источника...", + "no_sources_found": "Источники не найдены", + "sources": "Источники", + "finding_sources": "Поиск источников...", + "unknown_source": "Неизвестный источник", + "sources_limited": "Список источников может быть неполным из-за ошибок провайдера.", + "episodes": "Серии", + "specials": "Спецвыпуски", + "season": "Сезон {{season}}", + "stream": "Поток {{number}}", + "subtitles": "Субтитры", + "built_in": "Встроенные", + "addons": "Дополнения", + "style": "Стиль", + "none": "Нет", + "search_online_subtitles": "Поиск субтитров онлайн", + "preview": "Предпросмотр", + "quick_presets": "Быстрые пресеты", + "default": "По умолчанию", + "yellow": "Желтый", + "high_contrast": "Высокий контраст", + "large": "Крупный", + "core": "Основные", + "font_size": "Размер шрифта", + "show_background": "Показывать фон", + "advanced": "Дополнительно", + "position": "Позиция", + "text_color": "Цвет текста", + "align": "Выравнивание", + "bottom_offset": "Отступ снизу", + "background_opacity": "Прозрачность фона", + "text_shadow": "Тень текста", + "on": "Вкл", + "off": "Выкл", + "outline_color": "Цвет контура", + "outline": "Контур", + "outline_width": "Ширина контура", + "letter_spacing": "Межсимвольный интервал", + "line_height": "Высота строки", + "timing_offset": "Смещение времени (с)", + "visual_sync": "Визуальная синхронизация", + "timing_hint": "Используйте (-), чтобы субтитры появились раньше, или (+), чтобы позже.", + "reset_defaults": "Сбросить настройки", + "mark_intro_start": "Отметить начало интро", + "mark_intro_end": "Отметить конец интро", + "intro_start_marked": "Начало интро отмечено", + "intro_submitted": "Данные об интро отправлены", + "intro_submit_failed": "Не удалось отправить данные об интро" + }, + "downloads": { + "title": "Загрузки", + "no_downloads": "Загрузок пока нет", + "no_downloads_desc": "Загруженный контент появится здесь для офлайн-просмотра", + "explore": "Обзор контента", + "path_copied": "Путь скопирован", + "path_copied_desc": "Путь к локальному файлу скопирован", + "copied": "Скопировано", + "incomplete": "Загрузка не завершена", + "incomplete_desc": "Файл еще загружается", + "not_available": "Недоступно", + "not_available_desc": "Путь к файлу доступен только после завершения загрузки.", + "status_downloading": "Загрузка", + "status_completed": "Завершено", + "status_paused": "На паузе", + "status_error": "Ошибка", + "status_queued": "В очереди", + "status_unknown": "Неизвестно", + "provider": "Провайдер", + "streaming_playlist_warning": "Может не воспроизводиться (стриминг-плейлист)", + "remaining": "осталось", + "not_ready": "Загрузка не готова", + "not_ready_desc": "Пожалуйста, дождитесь завершения загрузки.", + "filter_all": "Все", + "filter_active": "Активные", + "filter_done": "Готовые", + "filter_paused": "На паузе", + "no_filter_results": "Нет {{filter}} загрузок", + "try_different_filter": "Попробуйте другой фильтр", + "limitations_title": "Ограничения загрузки", + "limitations_msg": "• Файлы меньше 1 МБ обычно являются плейлистами M3U8 и не могут быть загружены для офлайн-просмотра. Они работают только онлайн.", + "remove_title": "Удалить загрузку", + "remove_confirm": "Удалить \"{{title}}\"{{season_episode}}?", + "cancel": "Отмена", + "remove": "Удалить" + }, + "addons": { + "title": "Дополнения", + "reorder_mode": "Режим сортировки", + "reorder_info": "Дополнения сверху имеют приоритет при загрузке контента", + "add_addon_placeholder": "URL дополнения", + "add_button": "Добавить дополнение", + "my_addons": "Мои дополнения", + "community_addons": "Дополнения сообщества", + "no_addons": "Нет установленных дополнений", + "uninstall_title": "Удалить дополнение", + "uninstall_message": "Вы уверены, что хотите удалить {{name}}?", + "uninstall_button": "Удалить", + "install_success": "Дополнение успешно установлено", + "install_error": "Ошибка установки дополнения", + "load_error": "Ошибка загрузки дополнений", + "fetch_error": "Ошибка получения данных о дополнении", + "invalid_url": "Пожалуйста, введите корректный URL", + "configure": "Настроить", + "version": "Версия: {{version}}", + "installed_addons": "УСТАНОВЛЕННЫЕ ДОПОЛНЕНИЯ", + "reorder_drag_title": "ПЕРЕТАЩИТЕ ДЛЯ СОРТИРОВКИ", + "install": "Установить", + "config_unavailable_title": "Настройка недоступна", + "config_unavailable_msg": "Не удалось определить URL конфигурации для этого дополнения.", + "cannot_open_config_title": "Не удалось открыть настройки", + "cannot_open_config_msg": "URL ({{url}}) не открывается. Возможно, у дополнения нет страницы настроек.", + "description": "Описание", + "supported_types": "Поддерживаемые типы", + "catalogs": "Каталоги", + "no_description": "Описание отсутствует", + "overview": "ОБЗОР", + "no_categories": "Нет категорий", + "pre_installed": "ПРЕДУСТАНОВЛЕНО" + }, + "trakt": { + "title": "Настройки Trakt", + "settings_title": "Настройки Trakt", + "connect_title": "Подключить Trakt", + "connect_desc": "Синхронизируйте историю, список желаемого и коллекцию с Trakt.tv", + "sign_in": "Войти в Trakt", + "sign_out": "Выйти", + "sign_out_confirm": "Вы уверены, что хотите выйти из аккаунта Trakt?", + "joined": "Вместе с нами с {{date}}", + "sync_settings_title": "Настройки синхронизации", + "sync_info": "При подключении к Trakt история синхронизируется напрямую через API и не хранится локально. Список «Продолжить просмотр» отражает ваш глобальный прогресс Trakt.", + "auto_sync_label": "Автосинхронизация прогресса", + "auto_sync_desc": "Автоматически сохранять прогресс просмотра на Trakt", + "import_history_label": "Импорт истории просмотров", + "import_history_desc": "Используйте «Синхронизировать сейчас», чтобы загрузить историю с Trakt", + "sync_now_button": "Синхронизировать сейчас", + "display_settings_title": "Настройки отображения", + "show_comments_label": "Показывать комментарии Trakt", + "show_comments_desc": "Отображать отзывы пользователей на экранах описания контента", + "maintenance_title": "Техническое обслуживание", + "maintenance_unavailable": "Trakt недоступен", + "maintenance_desc": "Интеграция с Trakt временно приостановлена для обслуживания. Синхронизация и вход отключены.", + "maintenance_button": "Сервис на обслуживании", + "auth_success_title": "Подключено успешно", + "auth_success_msg": "Ваш аккаунт Trakt успешно подключен.", + "auth_error_title": "Ошибка авторизации", + "auth_error_msg": "Не удалось выполнить авторизацию в Trakt.", + "auth_error_generic": "Произошла ошибка во время авторизации.", + "sign_out_error": "Не удалось выйти из Trakt.", + "sync_complete_title": "Синхронизация завершена", + "sync_success_msg": "Прогресс просмотра успешно синхронизирован с Trakt.", + "sync_error_msg": "Ошибка синхронизации. Попробуйте снова." + }, + "simkl": { + "title": "Настройки Simkl", + "settings_title": "Настройки Simkl", + "connect_title": "Подключить Simkl", + "connect_desc": "Синхронизируйте историю и отслеживайте свои просмотры", + "sign_in": "Войти в Simkl", + "sign_out": "Отключить", + "sign_out_confirm": "Вы уверены, что хотите отключиться от Simkl?", + "syncing_desc": "Ваши просмотры синхронизируются с Simkl.", + "auth_success_title": "Подключено успешно", + "auth_success_msg": "Ваш аккаунт Simkl успешно подключен.", + "auth_error_title": "Ошибка авторизации", + "auth_error_msg": "Не удалось выполнить авторизацию в Simkl.", + "auth_error_generic": "Произошла ошибка во время авторизации.", + "sign_out_error": "Не удалось отключиться от Simkl.", + "config_error_title": "Ошибка конфигурации", + "config_error_msg": "Simkl Client ID отсутствует в переменных окружения.", + "conflict_title": "Конфликт", + "conflict_msg": "Вы не можете подключить Simkl, пока подключен Trakt. Сначала отключите Trakt.", + "disclaimer": "Nuvio не является аффилированным лицом Simkl." + }, + "tmdb_settings": { + "title": "Настройки TMDb", + "metadata_enrichment": "Обогащение метаданных", + "metadata_enrichment_desc": "Улучшите описание контента данными из TMDb для получения подробной информации.", + "enable_enrichment": "Включить обогащение", + "enable_enrichment_desc": "Дополняет метаданные данными об актерах, рейтингах, логотипах и студиях.", + "localized_text": "Локализованный текст", + "localized_text_desc": "Загружать названия и описания на вашем языке из TMDb.", + "language": "Язык", + "change": "Изменить", + "logo_preview": "Предпросмотр логотипа", + "logo_preview_desc": "Показывает, как будут выглядеть локализованные логотипы.", + "example": "Пример:", + "no_logo": "Логотип отсутствует", + "enrichment_options": "Опции обогащения", + "enrichment_options_desc": "Выберите, какие данные запрашивать. Отключенные опции будут использовать данные дополнений.", + "cast_crew": "Актеры и команда", + "cast_crew_desc": "Актеры, режиссеры, сценаристы с фото", + "title_description": "Заголовки и описания", + "title_description_desc": "Использовать локализованные тексты из TMDb", + "title_logos": "Логотипы названий", + "title_logos_desc": "Качественные изображения названий", + "banners_backdrops": "Баннеры и фоны", + "banners_backdrops_desc": "Изображения фона в высоком разрешении", + "certification": "Возрастные рейтинги", + "certification_desc": "Рейтинги (PG-13, R, и др.)", + "recommendations": "Рекомендации", + "recommendations_desc": "Предложения похожего контента", + "episode_data": "Данные о сериях", + "episode_data_desc": "Превью серий, информация и заглушки", + "season_posters": "Постеры сезонов", + "season_posters_desc": "Изображения для конкретных сезонов", + "production_info": "Информация о производстве", + "production_info_desc": "Сети и студии с логотипами", + "movie_details": "Детали фильма", + "movie_details_desc": "Бюджет, сборы, длительность, слоган", + "tv_details": "Детали сериала", + "tv_details_desc": "Статус, количество сезонов, авторы", + "movie_collections": "Кинофраншизы", + "movie_collections_desc": "Списки связанных фильмов (Marvel, Звездные войны и т.д.)", + "api_configuration": "Настройка API", + "api_configuration_desc": "Настройте доступ к TMDb API для повышения производительности.", + "custom_api_key": "Персональный API ключ", + "custom_api_key_desc": "Используйте собственный ключ для стабильной работы и личных лимитов.", + "custom_key_active": "Персональный ключ активен", + "api_key_required": "Требуется API ключ", + "api_key_placeholder": "Вставьте ваш TMDb API ключ (v3)", + "how_to_get_key": "Как получить API ключ TMDb?", + "built_in_key_msg": "Используется встроенный ключ. Рекомендуем использовать свой.", + "cache_size": "Размер кэша", + "clear_cache": "Очистить кэш", + "cache_days": "Данные TMDB кэшируются на 7 дней для быстрой работы", + "choose_language": "Выберите язык", + "choose_language_desc": "Выберите предпочтительный язык для контента TMDb", + "popular": "Популярные", + "all_languages": "Все языки", + "search_results": "Результаты поиска", + "no_languages_found": "Языки для «{{query}}» не найдены", + "clear_search": "Очистить поиск", + "clear_cache_title": "Очистить кэш TMDB", + "clear_cache_msg": "Это удалит все кэшированные данные ({{size}}). Загрузка может временно замедлиться.", + "clear_cache_success": "Кэш TMDB успешно очищен.", + "clear_cache_error": "Ошибка при очистке кэша.", + "clear_api_key_title": "Удалить API ключ", + "clear_api_key_msg": "Вы уверены, что хотите удалить свой ключ и вернуться к стандартному?", + "clear_api_key_success": "API ключ удален", + "clear_api_key_error": "Ошибка при удалении ключа", + "empty_api_key": "Ключ не может быть пустым.", + "invalid_api_key": "Некорректный ключ. Проверьте данные.", + "save_error": "Ошибка при сохранении. Попробуйте еще раз.", + "using_builtin_key": "Используется встроенный ключ TMDb.", + "using_custom_key": "Используется ваш персональный ключ TMDb.", + "enter_custom_key": "Пожалуйста, введите и сохраните ваш ключ TMDb.", + "key_verified": "API ключ проверен и сохранен." + }, + "settings": { + "language": "Язык", + "select_language": "Выберите язык", + "english": "Английский", + "portuguese": "Португальский", + "portuguese_br": "Португальский (Бразилия)", + "portuguese_pt": "Португальский (Португалия)", + "german": "Немецкий", + "arabic": "Арабский", + "spanish": "Испанский", + "french": "Французский", + "italian": "Итальянский", + "croatian": "Хорватский", + "chinese": "Китайский (упрощенный)", + "hindi": "Хинди", + "serbian": "Сербский", + "hebrew": "Иврит", + "bulgarian": "Болгарский", + "polish": "Польский", + "czech": "Чешский", + "turkish": "Турецкий", + "slovenian": "Словенский", + "macedonian": "Македонский", + "russian": "Русский", + "filipino": "Филиппинский", + "dutch_nl": "Нидерландский (Нидерланды)", + "romanian": "Румынский", + "albanian": "Албанский", + "account": "Аккаунт", + "content_discovery": "Контент и поиск", + "appearance": "Внешний вид", + "integrations": "Интеграции", + "playback": "Воспроизведение", + "backup_restore": "Резервное копирование", + "updates": "Обновления", + "about": "О приложении", + "developer": "Разработчик", + "cache": "Кэш", + "title": "Настройки", + "settings_title": "Настройки", + "sign_in_sync": "Войдите для синхронизации", + "add_catalogs_sources": "Дополнения, каталоги и источники", + "player_trailers_downloads": "Плеер, трейлеры, загрузки", + "mdblist_tmdb_ai": "MDBList, TMDB, ИИ", + "check_updates": "Проверить обновления", + "clear_mdblist_cache": "Очистить кэш MDBList", + "cache_management": "УПРАВЛЕНИЕ КЭШЕМ", + "downloads_counter": "загрузок и считаем дальше", + "made_with_love": "Сделано с ❤️ Tapframe и друзьями", + "sections": { + "information": "ИНФОРМАЦИЯ", + "account": "АККАУНТ", + "theme": "ТЕМА", + "layout": "РАЗМЕТКА", + "sources": "ИСТОЧНИКИ", + "catalogs": "КАТАЛОГИ", + "discovery": "ОБЗОР", + "metadata": "МЕТАДАННЫЕ", + "ai_assistant": "ИИ-ПОМОЩНИК", + "video_player": "ВИДЕОПЛЕЕР", + "audio_subtitles": "АУДИО И СУБТИТРЫ", + "media": "МЕДИА", + "notifications": "УВЕДОМЛЕНИЯ", + "testing": "ТЕСТИРОВАНИЕ", + "danger_zone": "ОПАСНАЯ ЗОНА" + }, + "items": { + "legal": "Юридическая информация", + "privacy_policy": "Политика конфиденциальности", + "report_issue": "Сообщить о проблеме", + "version": "Версия", + "contributors": "Участники проекта", + "view_contributors": "Посмотреть всех участников", + "theme": "Тема", + "episode_layout": "Вид списка серий", + "streams_backdrop": "Фон потоков", + "streams_backdrop_desc": "Размытый фон при просмотре потоков на мобильных", + "addons": "Дополнения", + "installed": "установлено", + "debrid_integration": "Интеграция Debrid", + "debrid_desc": "Подключить Torbox", + "plugins": "Плагины", + "plugins_desc": "Управление плагинами и репозиториями", + "catalogs": "Каталоги", + "active": "активно", + "home_screen": "Главный экран", + "home_screen_desc": "Разметка и контент", + "continue_watching": "Продолжить просмотр", + "continue_watching_desc": "Кэш и поведение плеера", + "show_discover": "Раздел «Обзор»", + "show_discover_desc": "Показывать рекомендации в Поиске", + "mdblist": "MDBList", + "mdblist_connected": "Подключено", + "mdblist_desc": "Включите для рейтингов и отзывов", + "simkl": "Simkl", + "simkl_connected": "Подключено", + "simkl_desc": "Отслеживайте ваши просмотры", + "tmdb": "TMDB", + "tmdb_desc": "Источник метаданных и логотипов", + "openrouter": "OpenRouter API", + "openrouter_connected": "Подключено", + "openrouter_desc": "Добавьте API ключ для ИИ-чата", + "video_player": "Видеоплеер", + "built_in": "Встроенный", + "external": "Внешний", + "preferred_audio": "Предпочитаемый язык аудио", + "preferred_subtitle": "Предпочитаемый язык субтитров", + "subtitle_source": "Приоритет источников субтитров", + "auto_select_subs": "Автовыбор субтитров", + "auto_select_subs_desc": "Автоматически выбирать субтитры по вашим предпочтениям", + "show_trailers": "Показывать трейлеры", + "show_trailers_desc": "Отображать трейлеры в главном блоке", + "enable_downloads": "Включить загрузки", + "enable_downloads_desc": "Показывать вкладку загрузок и сохранять потоки", + "notifications": "Уведомления", + "notifications_desc": "Напоминания о новых сериях", + "developer_tools": "Инструменты разработчика", + "developer_tools_desc": "Опции для тестирования и отладки", + "test_onboarding": "Тест приветствия", + "reset_onboarding": "Сбросить приветствие", + "test_announcement": "Тест объявлений", + "test_announcement_desc": "Показать окно «Что нового»", + "reset_campaigns": "Сбросить кампании", + "reset_campaigns_desc": "Очистить показы кампаний", + "clear_all_data": "Удалить все данные", + "clear_all_data_desc": "Сбросить все настройки и кэш" + }, + "options": { + "horizontal": "Горизонтально", + "vertical": "Вертикально", + "internal_first": "Сначала встроенные", + "internal_first_desc": "Приоритет встроенных субтитров, затем внешних", + "external_first": "Сначала внешние", + "external_first_desc": "Приоритет субтитров из дополнений, затем встроенных", + "any_available": "Любые доступные", + "any_available_desc": "Использовать первую найденную дорожку" + }, + "clear_data_desc": "Это сбросит все настройки и очистит кэш. Вы уверены?", + "app_updates": "Обновления приложения", + "about_nuvio": "О Nuvio" + }, + "privacy": { + "title": "Конфиденциальность", + "settings_desc": "Управление телеметрией и сбором данных", + "info_title": "Ваша приватность важна", + "info_description": "Контролируйте, какие данные собираются. Аналитика отключена по умолчанию, а отчеты об ошибках анонимны.", + "analytics_enabled_title": "Аналитика включена", + "analytics_enabled_message": "Данные об использовании будут собираться для улучшения приложения. Вы можете отключить это в любое время.", + "disable_error_reporting_title": "Отключить отчеты об ошибках?", + "disable_error_reporting_message": "Мы не сможем узнать о сбоях, с которыми вы столкнулись. Это затруднит исправление ошибок.", + "enable_session_replay_title": "Включить запись сессии?", + "enable_session_replay_message": "Записывает экран в момент ошибки, чтобы мы поняли, что пошло не так. Может захватить видимый контент.", + "enable_pii_title": "Включить сбор личных данных?", + "enable_pii_message": "Разрешает сбор IP-адреса и данных устройства. Помогает в диагностике, но снижает приватность.", + "disable_all_title": "Отключить всю телеметрию?", + "disable_all_message": "Это отключит аналитику, отчеты об ошибках и запись сессий. Мы не получим никаких данных об использовании.", + "disable_all_button": "Отключить всё", + "all_disabled_title": "Вся телеметрия отключена", + "all_disabled_message": "Сбор данных отключен. Изменения вступят в силу после перезапуска приложения.", + "reset_title": "Сброс к рекомендуемым", + "reset_message": "Настройки сброшены к значениям по умолчанию (отчеты включены, аналитика выключена).", + "section_analytics": "АНАЛИТИКА", + "analytics_title": "Аналитика использования", + "analytics_description": "Анонимный сбор паттернов использования и просмотров экранов", + "section_error_reporting": "ОТЧЕТЫ ОБ ОШИБКАХ", + "error_reporting_title": "Отчеты о сбоях", + "error_reporting_description": "Отправка анонимных отчетов для улучшения стабильности", + "session_replay_title": "Запись сессии", + "session_replay_description": "Запись экрана при возникновении ошибок", + "pii_title": "Инфо об устройстве", + "pii_description": "Отправлять IP и данные устройства вместе с отчетами", + "section_quick_actions": "БЫСТРЫЕ ДЕЙСТВИЯ", + "disable_all": "Отключить всю телеметрию", + "disable_all_desc": "Выключить любой сбор данных", + "reset_recommended": "Сбросить к рекомендуемым", + "reset_recommended_desc": "Приватность прежде всего с отчетами об ошибках", + "section_learn_more": "УЗНАТЬ БОЛЬШЕ", + "privacy_policy": "Политика конфиденциальности", + "current_settings": "Текущие настройки", + "summary_analytics": "Аналитика", + "summary_errors": "Отчеты об ошибках", + "summary_replay": "Запись сессии", + "summary_pii": "Инфо об устройстве", + "restart_note_detailed": "* Изменения аналитики и ошибок применяются сразу. Запись сессий и инфо об устройстве требуют перезапуска." + }, + "ai_settings": { + "title": "ИИ-помощник", + "info_title": "Чат на базе ИИ", + "info_desc": "Задавайте вопросы о фильмах и сериях продвинутому ИИ. Сюжет, персонажи, факты — всё на основе данных TMDB.", + "feature_1": "Контекст и анализ конкретных серий", + "feature_2": "Объяснение сюжета и разбор персонажей", + "feature_3": "Закулисные факты и мелочи", + "feature_4": "Ваш собственный бесплатный ключ OpenRouter API", + "api_key_section": "API КЛЮЧ OPENROUTER", + "api_key_label": "API Ключ", + "api_key_desc": "Введите ваш ключ OpenRouter для активации ИИ-чата", + "save_api_key": "Сохранить API Ключ", + "saving": "Сохранение...", + "update": "Обновить", + "remove": "Удалить", + "get_free_key": "Получить бесплатный ключ на OpenRouter", + "enable_chat": "Включить ИИ-чат", + "enable_chat_desc": "Если включено, кнопка «Спросить ИИ» появится на страницах контента.", + "chat_enabled": "ИИ-чат включен", + "chat_enabled_desc": "Теперь вы можете задавать вопросы! Ищите кнопку «Спросить ИИ» на страницах фильмов и шоу.", + "how_it_works": "Как это работает", + "how_it_works_desc": "• OpenRouter дает доступ к разным моделям ИИ\n• Ваш ключ остается приватным и защищенным\n• Бесплатный тариф имеет щедрые лимиты\n• Чат понимает контекст фильма или серии\n• Получайте детальный анализ и объяснения", + "error_invalid_key": "Введите корректный API ключ", + "error_key_format": "Ключи OpenRouter должны начинаться с «sk-or-»", + "success_saved": "API ключ OpenRouter успешно сохранен!", + "error_save": "Не удалось сохранить API ключ", + "confirm_remove_title": "Удалить API Ключ", + "confirm_remove_msg": "Вы уверены? Это отключит все функции ИИ-чата.", + "success_removed": "API ключ успешно удален", + "error_remove": "Не удалось удалить API ключ" + }, + "catalog_settings": { + "title": "Каталоги", + "layout_phone": "РАЗМЕТКА КАТАЛОГА (ТЕЛЕФОН)", + "posters_per_row": "Постеров в ряду", + "auto": "Авто", + "show_titles": "Показывать названия", + "show_titles_desc": "Отображать текст названия под каждым постером", + "phone_only_hint": "Применяется только к телефонам. На планшетах — адаптивная разметка.", + "catalogs_group": "Каталоги", + "enabled_count": "{{enabled}} из {{total}} включено", + "rename_hint": "Удерживайте каталог, чтобы переименовать его", + "rename_modal_title": "Переименовать каталог", + "rename_placeholder": "Введите новое название", + "error_save_name": "Не удалось сохранить название." + }, + "continue_watching_settings": { + "title": "Продолжить просмотр", + "playback_behavior": "ПОВЕДЕНИЕ ПРИ ВОСПРОИЗВЕДЕНИИ", + "use_cached": "Использовать кэшированные потоки", + "use_cached_desc": "При нажатии на «Продолжить просмотр» плеер откроется сразу с ранее выбранным потоком. Если выключено — откроется страница контента.", + "open_metadata": "Открыть страницу описания", + "open_metadata_desc": "Если кэш потоков выключен, открывать детали контента вместо списка потоков.", + "card_appearance": "ВНЕШНИЙ ВИД КАРТОЧКИ", + "card_style": "Стиль карточки", + "card_style_desc": "Как объекты будут выглядеть на главном экране", + "wide": "Широкая", + "poster": "Постер", + "cache_settings": "НАСТРОЙКИ КЭША", + "cache_duration": "Срок хранения кэша потоков", + "cache_duration_desc": "Как долго хранить ссылки на потоки до их обновления", + "important_note": "Важное замечание", + "important_note_text": "Не все ссылки остаются активными долго. При долгом хранении ссылка может протухнуть. Если кэш не сработает, приложение найдет новые потоки.", + "how_it_works": "Как это работает", + "how_it_works_cached": "• Потоки кэшируются после просмотра на выбранный срок\n• Кэш проверяется перед использованием\n• Если кэш невалиден, открывается страница контента\n• Настройка управляет переходом в плеер или на экран\n• Выбор экрана доступен только при выключенном кэше", + "how_it_works_uncached": "• Если кэш выключен, нажатие открывает страницы контента\n• Вы можете выбрать, какой экран открывать (инфо или потоки)\n• Экран инфо показывает детали и ручной выбор\n• Экран потоков сразу ищет источники для запуска", + "changes_saved": "Изменения сохранены", + "min": "мин", + "hour": "час", + "hours": "ч." + }, + "contributors": { + "title": "Участники", + "special_mentions": "Особые благодарности", + "tab_contributors": "Участники", + "tab_special": "Особые", + "tab_donors": "Доны", + "manager_role": "Комьюнити-менеджер", + "manager_desc": "Управляет сообществами Discord и Reddit", + "sponsor_role": "Спонсор сервера", + "sponsor_desc": "Оплачивает серверную инфраструктуру Nuvio", + "mod_role": "Модератор Discord", + "mod_desc": "Помогает модерировать сообщество Nuvio", + "loading": "Загрузка...", + "discord_user": "Пользователь Discord", + "contributions": "вкладов", + "gratitude_title": "Мы благодарны за любой вклад", + "gratitude_desc": "Каждая строка кода, отчет об ошибке или предложение делают Nuvio лучше", + "special_thanks_title": "Особая благодарность", + "special_thanks_desc": "Эти люди помогают поддерживать работу сообщества и серверов", + "donors_desc": "Спасибо за веру в проект. Ваша поддержка позволяет Nuvio оставаться бесплатным.", + "latest_donations": "Последние", + "leaderboard": "Таблица лидеров", + "loading_donors": "Загрузка донов...", + "no_donors": "Донов пока нет", + "error_rate_limit": "Лимит GitHub API исчерпан. Попробуйте позже.", + "error_failed": "Ошибка загрузки. Проверьте соединение.", + "retry": "Повторить", + "no_contributors": "Участники не найдены", + "loading_contributors": "Загрузка участников..." + }, + "debrid": { + "title": "Интеграция Debrid", + "description_torbox": "Разблокируйте 4K потоки и высокую скорость через Torbox. Введите API ключ для мгновенного апгрейда.", + "description_torrentio": "Настройте Torrentio для получения торрент-потоков. Для работы требуется Debrid-сервис.", + "tab_torbox": "TorBox", + "tab_torrentio": "Torrentio", + "status_connected": "Подключено", + "status_disconnected": "Отключено", + "enable_addon": "Включить дополнение", + "disconnect_button": "Отключить и удалить", + "disconnect_loading": "Отключение...", + "account_info": "Информация об аккаунте", + "plan": "Тариф", + "plan_free": "Бесплатный", + "plan_essential": "Essential ($3/мес)", + "plan_pro": "Pro ($10/мес)", + "plan_standard": "Standard ($5/мес)", + "plan_unknown": "Неизвестно", + "expires": "Истекает", + "downloaded": "Загружено", + "status_active": "Активен", + "connected_title": "✓ Подключено к TorBox", + "connected_desc": "Ваше дополнение TorBox активно и предоставляет премиум-потоки.", + "configure_title": "Настроить дополнение", + "configure_desc": "Настройте сортировку по качеству, фильтрацию размеров и другие параметры.", + "open_settings": "Открыть настройки", + "what_is_debrid": "Что такое Debrid-сервис?", + "enter_api_key": "Введите ваш API ключ", + "connect_button": "Подключить и установить", + "connecting": "Подключение...", + "unlock_speeds_title": "Премиум скорость", + "unlock_speeds_desc": "Подпишитесь на Torbox для доступа к 4K потокам без буферизации.", + "get_subscription": "Получить подписку", + "powered_by": "Работает на", + "disclaimer_torbox": "Nuvio никак не связан с Torbox.", + "disclaimer_torrentio": "Nuvio никак не связан с Torrentio.", + "installed_badge": "✓ УСТАНОВЛЕНО", + "promo_title": "⚡ Нужен Debrid?", + "promo_desc": "TorBox обеспечит 4K стриминг без тормозов. Моментальные загрузки и кэшированные торренты.", + "promo_button": "Подписаться на TorBox", + "service_label": "Сервис Debrid *", + "api_key_label": "API Ключ *", + "sorting_label": "Сортировка", + "exclude_qualities": "Исключить качество", + "priority_languages": "Приоритетные языки", + "max_results": "Макс. результатов", + "additional_options": "Доп. опции", + "no_download_links": "Не показывать ссылки на загрузку", + "no_debrid_catalog": "Не показывать каталог Debrid", + "install_button": "Установить Torrentio", + "installing": "Установка...", + "update_button": "Обновить конфигурацию", + "updating": "Обновление...", + "remove_button": "Удалить Torrentio", + "error_api_required": "Требуется API Ключ", + "error_api_required_desc": "Введите API ключ вашего debrid-сервиса для установки Torrentio.", + "success_installed": "Torrentio успешно установлен!", + "success_removed": "Torrentio успешно удален", + "alert_disconnect_title": "Отключить Torbox", + "alert_disconnect_msg": "Вы уверены? Это удалит дополнение и ваш API ключ." + }, + "home_screen": { + "title": "Настройки главного экрана", + "changes_applied": "Изменения применены", + "display_options": "ОПЦИИ ОТОБРАЖЕНИЯ", + "show_hero": "Показывать главный блок", + "show_hero_desc": "Рекомендуемый контент сверху", + "show_this_week": "Раздел «На этой неделе»", + "show_this_week_desc": "Новые серии текущей недели", + "select_catalogs": "Выбрать каталоги", + "all_catalogs": "Все каталоги", + "selected": "выбрано", + "hero_layout": "Вид главного блока", + "layout_legacy": "Классический", + "layout_carousel": "Карусель", + "layout_appletv": "Apple TV", + "layout_desc": "Баннер на всю ширину, карточки или стиль Apple TV", + "featured_source": "Источник рекомендаций", + "using_catalogs": "Используются каталоги", + "manage_selected_catalogs": "Управление выбранными каталогами", + "dynamic_bg": "Динамический фон", + "dynamic_bg_desc": "Размытый баннер за каруселью", + "performance_note": "Может снизить скорость на слабых устройствах.", + "posters": "Постеры", + "show_titles": "Показывать названия", + "poster_size": "Размер постера", + "poster_corners": "Углы постера", + "size_small": "Маленький", + "size_medium": "Средний", + "size_large": "Большой", + "corners_square": "Квадратные", + "corners_rounded": "Закругленные", + "corners_pill": "Скругленные (Pill)", + "about_these_settings": "ОБ ЭТИХ НАСТРОЙКАХ", + "about_desc": "Настройки управляют контентом на главной. Изменения применяются мгновенно.", + "hero_catalogs": { + "title": "Каталоги главного блока", + "select_all": "Выбрать все", + "clear_all": "Сбросить все", + "info": "Выберите каталоги для показа в главном блоке. Если ничего не выбрано, будут показаны все. Не забудьте нажать «Сохранить».", + "settings_saved": "Настройки сохранены", + "error_load": "Не удалось загрузить каталоги", + "movies": "Фильмы", + "tv_shows": "ТВ-Шоу" + } + }, + "calendar": { + "title": "Календарь", + "loading": "Загрузка календаря...", + "no_scheduled_episodes": "Нет запланированных серий", + "check_back_later": "Зайдите позже", + "showing_episodes_for": "Серии на {{date}}", + "show_all_episodes": "Показать все серии", + "no_episodes_for": "Нет серий на {{date}}", + "no_upcoming_found": "Предстоящих серий не найдено", + "add_series_desc": "Добавьте сериалы в библиотеку, чтобы видеть их расписание здесь" + }, + "mdblist": { + "title": "Источники рейтингов", + "status_disabled": "MDBList отключен", + "status_active": "API-ключ активен", + "status_required": "Требуется API-ключ", + "status_disabled_desc": "Функционал MDBList в данный момент отключен.", + "status_active_desc": "Рейтинги MDBList включены.", + "status_required_desc": "Добавьте ключ ниже, чтобы включить отображение рейтингов.", + "enable_toggle": "Включить MDBList", + "enable_toggle_desc": "Включить/выключить все функции MDBList", + "api_section": "API-ключ", + "placeholder": "Вставьте ваш API-ключ MDBList", + "save": "Сохранить", + "clear": "Удалить ключ", + "rating_providers": "Провайдеры рейтингов", + "rating_providers_desc": "Выберите, какие рейтинги отображать в приложении", + "how_to": "Как получить API-ключ", + "step_1": "Войдите на", + "step_1_link": "сайт MDBList", + "step_2": "Перейдите в раздел", + "step_2_settings": "Settings", + "step_2_api": "API", + "step_2_end": ".", + "step_3": "Создайте новый ключ и скопируйте его.", + "go_to_website": "Перейти на MDBList", + "alert_clear_title": "Удалить API-ключ", + "alert_clear_msg": "Вы уверены, что хотите удалить сохраненный API-ключ?", + "success_saved": "API-ключ успешно сохранен.", + "error_empty": "API-ключ не может быть пустым.", + "error_save": "Произошла ошибка при сохранении. Попробуйте еще раз.", + "api_key_empty_error": "API-ключ не может быть пустым.", + "success_cleared": "API-ключ успешно удален", + "error_clear": "Не удалось удалить API-ключ" + }, + "notification": { + "title": "Настройки уведомлений", + "section_general": "Общие", + "enable_notifications": "Включить уведомления", + "section_types": "Типы уведомлений", + "new_episodes": "Новые серии", + "upcoming_shows": "Предстоящие шоу", + "reminders": "Напоминания", + "section_timing": "Время уведомления", + "timing_desc": "За сколько до выхода серии присылать уведомление?", + "hours_1": "1 час", + "hours_suffix": "час(ов)", + "section_status": "Статус уведомлений", + "stats_upcoming": "Ожидаются", + "stats_this_week": "На этой неделе", + "stats_total": "Всего", + "sync_button": "Синхронизировать библиотеку и Trakt", + "syncing": "Синхронизация...", + "sync_desc": "Автоматически настраивает уведомления для всех шоу в вашей библиотеке и списках Trakt.", + "section_advanced": "Дополнительно", + "reset_button": "Сбросить все уведомления", + "test_button": "Тест уведомления (5 сек)", + "test_notification_in": "Уведомление через {{seconds}}с...", + "test_notification_text": "Уведомление появится через {{seconds}} секунд", + "alert_reset_title": "Сброс уведомлений", + "alert_reset_msg": "Это отменит все запланированные уведомления, но не удалит данные из вашей библиотеки. Продолжить?", + "alert_reset_success": "Все уведомления были сброшены", + "alert_sync_complete": "Синхронизация завершена", + "alert_sync_msg": "Уведомления для библиотеки и Trakt синхронизированы.\n\nЗапланировано: {{upcoming}} серий\nНа этой неделе: {{thisWeek}} серий", + "alert_test_scheduled": "Тестовое уведомление запланировано" + }, + "backup": { + "title": "Резервное копирование", + "options_title": "Опции копирования", + "options_desc": "Выберите, что включить в бэкап", + "section_core": "Основные данные", + "section_addons": "Дополнения и интеграции", + "section_settings": "Настройки и предпочтения", + "library_label": "Библиотека", + "library_desc": "Ваши сохраненные фильмы и сериалы", + "watch_progress_label": "Прогресс просмотра", + "watch_progress_desc": "Позиции воспроизведения", + "addons_label": "Дополнения", + "addons_desc": "Установленные дополнения Stremio", + "plugins_label": "Плагины", + "plugins_desc": "Конфигурации пользовательских скреперов", + "trakt_label": "Интеграция Trakt", + "trakt_desc": "Данные синхронизации и токены авторизации", + "app_settings_label": "Настройки приложения", + "app_settings_desc": "Тема, предпочтения и конфигурации", + "user_prefs_label": "Пользовательские предпочтения", + "user_prefs_desc": "Порядок дополнений и настройки интерфейса", + "catalog_settings_label": "Настройки каталога", + "catalog_settings_desc": "Фильтры и предпочтения каталогов", + "api_keys_label": "API-ключи", + "api_keys_desc": "Ключи MDBList и OpenRouter", + "action_create": "Создать бэкап", + "action_restore": "Восстановить из бэкапа", + "section_info": "О резервных копиях", + "info_text": "• Выберите нужные пункты с помощью переключателей выше\n• Файлы бэкапа сохраняются локально на устройстве\n• Вы можете передать файл на другое устройство для переноса данных\n• Восстановление перезапишет текущие данные", + "alert_create_title": "Создание бэкапа", + "alert_no_content": "Не выбрано данных для копирования.\n\nПожалуйста, включите хотя бы одну опцию выше.", + "alert_backup_created_title": "Бэкап создан", + "alert_backup_created_msg": "Резервная копия создана и готова к отправке.", + "alert_backup_failed_title": "Ошибка бэкапа", + "alert_restore_confirm_title": "Подтвердите восстановление", + "alert_restore_confirm_msg": "Данные будут восстановлены из копии от {{date}}.\n\nЭто действие полностью заменит ваши текущие данные. Вы уверены?", + "alert_restore_complete_title": "Восстановление завершено", + "alert_restore_complete_msg": "Данные успешно восстановлены. Пожалуйста, перезапустите приложение.", + "alert_restore_failed_title": "Ошибка восстановления", + "restart_app": "Перезапустить", + "alert_restart_failed_title": "Ошибка перезапуска", + "alert_restart_failed_msg": "Не удалось перезапустить приложение автоматически. Пожалуйста, закройте и откройте его вручную." + }, + "updates": { + "title": "Обновления", + "status_checking": "Поиск обновлений...", + "status_available": "Доступно обновление!", + "status_downloading": "Загрузка обновления...", + "status_installing": "Установка обновления...", + "status_success": "Обновление успешно установлено!", + "status_error": "Ошибка обновления", + "status_ready": "Готов к проверке", + "action_check": "Проверить наличие обновлений", + "action_install": "Установить обновление", + "release_notes": "Список изменений:", + "version": "Версия:", + "last_checked": "Последняя проверка:", + "current_version": "Текущая версия:", + "current_release_notes": "Текущий список изменений:", + "github_release": "РЕЛИЗ НА GITHUB", + "current": "Текущая:", + "latest": "Последняя:", + "notes": "Заметки:", + "view_release": "Просмотреть релиз", + "notification_settings": "НАСТРОЙКИ УВЕДОМЛЕНИЙ", + "ota_alerts_label": "Оповещения OTA-обновлений", + "ota_alerts_desc": "Уведомления о быстрых исправлениях (по воздуху)", + "major_alerts_label": "Оповещения о мажорных обновлениях", + "major_alerts_desc": "Уведомления о новых версиях приложения на GitHub", + "alert_disable_ota_title": "Отключить OTA-оповещения?", + "alert_disable_ota_msg": "Вы больше не будете получать автоматические уведомления об исправлениях.\n\n⚠️ Внимание: Последние версии важны для:\n• Стабильности и исправления багов\n• Новых функций\n• Корректной отправки отчетов о сбоях\n\nВы сможете проверять обновления вручную на этом экране.", + "alert_disable_major_title": "Отключить оповещения о новых версиях?", + "alert_disable_major_msg": "Вы перестанете получать уведомления о крупных обновлениях, требующих переустановки.\n\n⚠️ Важно: Мажорные обновления включают:\n• Критические патчи безопасности\n• Важные изменения в работе приложения\n• Исправления совместимости", + "warning_note": "Включенные оповещения гарантируют получение исправлений и актуальную поддержку.", + "disable": "Отключить", + "alert_no_update_to_install": "Нет доступных обновлений для установки", + "alert_install_failed": "Не удалось установить обновление", + "alert_no_update_title": "Нет обновлений", + "alert_update_applied_msg": "Обновление будет применено при следующем запуске" + }, + "player": { + "title": "Видеоплеер", + "section_selection": "ВЫБОР ПЛЕЕРА", + "internal_title": "Встроенный плеер", + "internal_desc": "Использовать стандартный плеер приложения", + "vlc_title": "VLC", + "vlc_desc": "Открыть поток в VLC media player", + "infuse_title": "Infuse", + "infuse_desc": "Открыть поток в плеере Infuse", + "outplayer_title": "OutPlayer", + "outplayer_desc": "Открыть поток в OutPlayer", + "vidhub_title": "VidHub", + "vidhub_desc": "Открыть поток в VidHub", + "infuse_live_title": "Infuse Livecontainer", + "infuse_live_desc": "Открыть поток в Infuse (LiveContainer)", + "external_title": "Внешний плеер", + "external_desc": "Открыть поток в любом другом установленном плеере", + "section_playback": "ОПЦИИ ВОСПРОИЗВЕДЕНИЯ", + "skip_intro_settings_title": "Пропуск вступления", + "powered_by_introdb": "На базе IntroDB", + "autoplay_title": "Автозапуск первого потока", + "autoplay_desc": "Автоматически начинать воспроизведение первого найденного источника.", + "resume_title": "Всегда продолжать", + "resume_desc": "Пропускать вопрос о возобновлении и сразу включать с места остановки (если просмотрено менее 85%).", + "engine_title": "Движок видеоплеера", + "engine_desc": "«Авто» использует ExoPlayer с переключением на MPV при необходимости. Рекомендуется для лучшей поддержки форматов вроде Dolby Vision.", + "decoder_title": "Режим декодера", + "decoder_desc": "Способ декодирования видео. «Авто» — лучший баланс.", + "gpu_title": "GPU-рендеринг", + "gpu_desc": "GPU-Next обеспечивает лучшую работу с HDR и цветом.", + "external_downloads_title": "Внешний плеер для загрузок", + "external_downloads_desc": "Воспроизводить загруженный контент во внешнем плеере.", + "restart_required": "Требуется перезапуск", + "restart_msg_decoder": "Пожалуйста, перезапустите приложение для смены режима декодера.", + "restart_msg_gpu": "Пожалуйста, перезапустите приложение для смены режима GPU.", + "option_auto": "Авто", + "option_auto_desc_engine": "ExoPlayer + MPV", + "option_mpv": "MPV", + "option_mpv_desc": "Только MPV", + "option_auto_desc_decoder": "Оптимально", + "option_sw": "Программный (SW)", + "option_sw_desc": "Software", + "option_hw": "Аппаратный (HW)", + "option_hw_desc": "Hardware", + "option_hw_plus": "HW+", + "option_hw_plus_desc": "Full Hardware", + "option_gpu_desc": "Стандартный", + "option_gpu_next_desc": "Продвинутый" + }, + "plugins": { + "title": "Плагины", + "enable_title": "Включить плагины", + "enable_desc": "Включить движок плагинов для поиска внешних источников", + "repo_config_title": "Конфигурация репозитория", + "repo_config_desc": "Управление внешними репозиториями плагинов.", + "your_repos": "Репозитории", + "your_repos_desc": "Настройте внешние источники для плагинов.", + "add_repo_button": "Добавить репозиторий", + "refresh": "Обновить", + "remove": "Удалить", + "enabled": "Включено", + "disabled": "Выключено", + "updating": "Обновление...", + "success": "Успешно", + "error": "Ошибка", + "alert_repo_added": "Репозиторий добавлен, плагины загружены", + "alert_repo_saved": "URL репозитория сохранен", + "alert_repo_refreshed": "Репозиторий успешно обновлен", + "alert_invalid_url": "Неверный формат URL", + "alert_plugins_cleared": "Все плагины удалены", + "alert_cache_cleared": "Кэш репозитория очищен", + "unknown": "Неизвестно", + "active": "Активен", + "available": "Доступен", + "platform_disabled": "Платформа отключена", + "limited": "Ограничен", + "clear_all": "Удалить все плагины", + "clear_all_desc": "Вы уверены, что хотите удалить все установленные плагины? Это действие нельзя отменить.", + "clear_cache": "Очистить кэш репозитория", + "clear_cache_desc": "Это удалит URL репозитория и все кэшированные данные. Вам нужно будет ввести URL заново.", + "add_new_repo": "Добавить новый репозиторий", + "available_plugins": "Доступно плагинов ({{count}})", + "placeholder": "Поиск плагинов...", + "all": "Все", + "filter_all": "Все типы", + "filter_movies": "Фильмы", + "filter_tv": "Сериалы", + "enable_all": "Включить все", + "disable_all": "Выключить все", + "no_plugins_found": "Плагины не найдены", + "no_plugins_available": "Нет доступных плагинов", + "no_match_desc": "Ни один плагин не соответствует запросу \"{{query}}\".", + "configure_repo_desc": "Настройте репозиторий выше, чтобы увидеть список плагинов.", + "clear_search": "Очистить поиск", + "no_external_player": "Нет внешнего плеера", + "showbox_token": "Токен ShowBox UI", + "showbox_placeholder": "Вставьте ваш токен ShowBox UI", + "save": "Сохранить", + "clear": "Очистить", + "additional_settings": "Дополнительные настройки", + "enable_url_validation": "Валидация URL", + "url_validation_desc": "Проверять ссылки перед показом (может замедлить поиск, но повышает надежность)", + "group_streams": "Группировать источники", + "group_streams_desc": "Источники будут сгруппированы по репозиториям.", + "sort_quality": "Сначала по качеству", + "sort_quality_desc": "Сортировать результаты в первую очередь по качеству (только при включенной группировке).", + "show_logos": "Показывать логотипы", + "show_logos_desc": "Отображать логотипы плагинов рядом со ссылками на источники.", + "quality_filtering": "Фильтр качества", + "quality_filtering_desc": "Исключить определенные разрешения. Нажмите, чтобы скрыть из результатов.", + "excluded_qualities": "Исключенное качество:", + "language_filtering": "Фильтр языков", + "language_filtering_desc": "Исключить определенные языки из результатов поиска.", + "note": "Примечание:", + "language_filtering_note": "Этот фильтр работает только для провайдеров, которые передают информацию о языке.", + "excluded_languages": "Исключенные языки:", + "about_title": "О плагинах", + "about_desc_1": "Плагины — это модули для адаптации контента из внешних протоколов. Они работают локально и могут быть установлены из доверенных репозиториев.", + "about_desc_2": "Плагины с меткой «Ограничен» могут требовать дополнительной внешней настройки.", + "help_title": "Настройка плагинов", + "help_step_1": "1. **Включите плагины** — используйте главный переключатель", + "help_step_2": "2. **Добавьте репозиторий** — введите рабочий URL", + "help_step_3": "3. **Обновите** — получите список доступных плагинов", + "help_step_4": "4. **Активируйте** — включите нужные плагины", + "got_it": "Понятно!", + "repo_format_hint": "Формат: https://raw.githubusercontent.com/username/repo/branch", + "cancel": "Отмена", + "add": "Добавить" + }, + "theme": { + "title": "Темы оформления", + "select_theme": "ВЫБЕРИТЕ ТЕМУ", + "create_custom": "Создать свою тему", + "options": "ОПЦИИ", + "use_dominant_color": "Цвет на основе обложки", + "categories": { + "all": "Все темы", + "dark": "Темные", + "colorful": "Цветные", + "custom": "Мои темы" + }, + "editor": { + "theme_name_placeholder": "Название темы", + "save": "Сохранить", + "primary": "Основной", + "secondary": "Вторичный", + "background": "Фон", + "invalid_name_title": "Неверное имя", + "invalid_name_msg": "Пожалуйста, введите корректное название темы" + }, + "alerts": { + "delete_title": "Удалить тему", + "delete_msg": "Вы уверены, что хотите удалить тему «{{name}}»?", + "ok": "ОК", + "delete": "Удалить", + "cancel": "Отмена", + "back": "Настройки" + } + }, + "legal": { + "title": "Юридическая информация", + "intro_title": "Природа приложения", + "intro_text": "Nuvio — это медиаплеер и менеджер метаданных. Он выступает исключительно как клиентский интерфейс для просмотра общедоступных данных и воспроизведения файлов, предоставленных пользователем или сторонними расширениями. Nuvio не хостит, не хранит и не распространяет медиаконтент.", + "extensions_title": "Сторонние плагины", + "extensions_text": "Nuvio позволяет устанавливать сторонние плагины, которые создаются независимыми разработчиками. Мы не несем ответственности за их содержание, легальность или работоспособность.", + "user_resp_title": "Ответственность пользователя", + "user_resp_text": "Пользователи несут полную ответственность за устанавливаемые плагины. Используя приложение, вы подтверждаете, что имеете законное право на просмотр контента. Разработчики Nuvio не поощряют нарушение авторских прав.", + "dmca_title": "Авторское право (DMCA)", + "dmca_text": "Мы уважаем интеллектуальную собственность. Так как Nuvio не хранит контент, мы не можем удалить его из сети. Если вы считаете, что интерфейс приложения нарушает ваши права, свяжитесь с нами.", + "warranty_title": "Отказ от гарантий", + "warranty_text": "ПО предоставляется «как есть» без каких-либо гарантий. Авторы не несут ответственности за любые претензии или ущерб, возникшие в результате использования данного ПО." + }, + "plugin_tester": { + "title": "Тестер плагинов", + "subtitle": "Запуск скреперов и просмотр логов в реальном времени", + "tabs": { + "individual": "Индивидуальный", + "repo": "Тестер репозитория", + "code": "Код", + "logs": "Логи", + "results": "Результаты" + }, + "common": { + "error": "Ошибка", + "success": "Успех", + "movie": "Фильм", + "tv": "ТВ", + "tmdb_id": "TMDB ID", + "season": "Сезон", + "episode": "Серия", + "running": "Запуск...", + "run_test": "Начать тест", + "play": "Играть", + "done": "Готово", + "test": "Тест", + "testing": "Тестирование..." + }, + "individual": { + "load_from_url": "Загрузить по URL", + "load_from_url_desc": "Вставьте прямую ссылку (raw GitHub) или локальный IP.", + "enter_url_error": "Пожалуйста, введите URL", + "code_loaded": "Код загружен из URL", + "fetch_error": "Ошибка загрузки: {{message}}", + "no_code_error": "Нет кода для запуска", + "plugin_code": "Код плагина", + "focus_editor": "Фокус на редакторе", + "code_placeholder": "// Вставьте код плагина здесь...", + "test_parameters": "Параметры теста", + "no_logs": "Логи отсутствуют. Запустите тест.", + "no_streams": "Потоки не найдены.", + "streams_found": "Найден {{count}} поток", + "streams_found_plural": "Найдено потоков: {{count}}", + "tap_play_hint": "Нажмите «Играть», чтобы проверить поток в плеере.", + "unnamed_stream": "Безымянный поток", + "quality": "Качество: {{quality}}", + "size": "Размер: {{size}}", + "url_label": "URL: {{url}}", + "headers_info": "Заголовки: {{count}} шт.", + "find_placeholder": "Найти в коде...", + "edit_code_title": "Редактировать код", + "no_url_stream_error": "URL для этого потока не найден" + }, + "repo": { + "title": "Тестер репозитория", + "description": "Загрузите репозиторий и проверьте каждого провайдера.", + "enter_repo_url_error": "Введите URL репозитория", + "invalid_url_title": "Неверный URL", + "invalid_url_msg": "Используйте прямую ссылку GitHub (raw) или локальный http(s).", + "manifest_build_error": "Не удалось создать URL манифеста", + "manifest_fetch_error": "Ошибка загрузки манифеста", + "repo_manifest_fetch_error": "Ошибка загрузки манифеста репозитория", + "missing_filename": "В манифесте отсутствует имя файла", + "scraper_build_error": "Не удалось создать URL скрепера", + "download_scraper_error": "Ошибка загрузки скрепера", + "test_failed": "Тест провален", + "test_parameters": "Параметры теста репозитория", + "test_parameters_desc": "Эти параметры используются только для тестера репозитория.", + "using_info": "Используем: {{mediaType}} • TMDB {{tmdbId}}", + "using_info_tv": "Используем: {{mediaType}} • TMDB {{tmdbId}} • S{{season}}E{{episode}}", + "providers_title": "Провайдеры", + "repository_default": "Репозиторий", + "providers_count": "Провайдеров: {{count}}", + "fetch_hint": "Загрузите репо, чтобы увидеть список.", + "test_all": "Тестировать все", + "status_running": "В ПРОЦЕССЕ", + "status_ok": "OK ({{count}})", + "status_ok_empty": "OK (0)", + "status_failed": "ОШИБКА", + "status_idle": "ОЖИДАНИЕ", + "tried_url": "Попытка URL: {{url}}", + "provider_logs": "Логи провайдера", + "no_logs_captured": "Логи не перехвачены." + } + } +} diff --git a/src/i18n/locales/sl.json b/src/i18n/locales/sl.json new file mode 100644 index 00000000..c3c49bcf --- /dev/null +++ b/src/i18n/locales/sl.json @@ -0,0 +1,1430 @@ +{ + "common": { + "loading": "Nalaganje...", + "cancel": "Prekliči", + "save": "Shrani", + "delete": "Izbriši", + "edit": "Uredi", + "search": "Išči", + "error": "Napaka", + "success": "Uspešno", + "ok": "V redu", + "unknown": "Neznano", + "retry": "Poskusi znova", + "try_again": "Poskusi ponovno", + "go_back": "Nazaj", + "settings": "Nastavitve", + "close": "Zapri", + "enable": "Omogoči", + "disable": "Onemogoči", + "show_more": "Pokaži več", + "show_less": "Pokaži manj", + "load_more": "Naloži več", + "unknown_date": "Neznan datum", + "anonymous_user": "Anonimen uporabnik", + "time": { + "now": "Ravno zdaj", + "minutes_ago": "pred {{count}} min", + "hours_ago": "pred {{count}} h", + "days_ago": "pred {{count}} d" + }, + "days_short": { + "sun": "Ned", + "mon": "Pon", + "tue": "Tor", + "wed": "Sre", + "thu": "Čet", + "fri": "Pet", + "sat": "Sob" + }, + "email": "E-pošta", + "status": "Stanje" + }, + "home": { + "categories": { + "movies": "Filmi", + "series": "Serije", + "channels": "Kanali" + }, + "movies": "Filmi", + "tv_shows": "TV oddaje", + "load_more_catalogs": "Naloži več katalogov", + "no_content": "Vsebina ni na voljo", + "add_catalogs": "Dodaj kataloge", + "sign_in_available": "Prijava je na voljo", + "sign_in_desc": "Prijavite se lahko kadarkoli v Nastavitve → Račun", + "view_all": "Prikaži vse", + "this_week": "Ta teden", + "upcoming": "Prihajajoče", + "recently_released": "Nedavno izšlo", + "no_scheduled_episodes": "Serije brez načrtovanih epizod", + "check_back_later": "Preverite pozneje", + "continue_watching": "Nadaljuj z gledanjem", + "up_next": "Naslednje", + "up_next_caps": "NASLEDNJE", + "released": "Izšlo", + "new": "Novo", + "tba": "Še ni določeno", + "new_episodes": "{{count}} novih epizod", + "season_short": "S{{season}}", + "episode_short": "E{{episode}}", + "season": "Sezona {{season}}", + "episode": "Epizoda {{episode}}", + "movie": "Film", + "series": "Serija", + "tv_show": "TV oddaja", + "percent_watched": "{{percent}} % ogledano", + "view_details": "Prikaži podrobnosti", + "remove": "Odstrani", + "play": "Predvajaj", + "play_now": "Predvajaj zdaj", + "resume": "Nadaljuj", + "info": "Informacije", + "more_info": "Več informacij", + "my_list": "Moj seznam", + "save": "Shrani", + "saved": "Shranjeno", + "retry": "Poskusi znova", + "install_addons": "Namesti dodatke", + "settings": "Nastavitve", + "no_featured_content": "Ni izpostavljene vsebine", + "couldnt_load_featured": "Izpostavljene vsebine ni bilo mogoče naložiti", + "no_featured_desc": "Namestite dodatke s katalogi ali spremenite vir vsebine v nastavitvah.", + "load_error_desc": "Prišlo je do težave pri pridobivanju izpostavljene vsebine. Preverite povezavo in poskusite znova.", + "no_featured_available": "Izpostavljena vsebina ni na voljo", + "no_description": "Opis ni na voljo" + }, + "navigation": { + "home": "Domov", + "library": "Knjižnica", + "search": "Iskanje", + "downloads": "Prenosi", + "settings": "Nastavitve" + }, + "search": { + "title": "Iskanje", + "recent_searches": "Nedavna iskanja", + "discover": "Odkrivaj", + "movies": "Filmi", + "tv_shows": "TV oddaje", + "select_catalog": "Izberi katalog", + "all_genres": "Vsi žanri", + "discovering": "Odkrivanje vsebine...", + "show_more": "Pokaži več ({{count}})", + "no_content_found": "Vsebine ni bilo mogoče najti", + "try_different": "Poskusite drug žanr ali katalog", + "select_catalog_desc": "Izberite katalog za raziskovanje", + "tap_catalog_desc": "Za začetek tapnite zavihek kataloga zgoraj", + "placeholder": "Išči filme, oddaje...", + "keep_typing": "Nadaljujte s tipkanjem...", + "type_characters": "Vnesite vsaj 2 znaka za iskanje", + "no_results": "Ni rezultatov", + "try_keywords": "Poskusite z drugimi ključnimi besedami ali preverite črkovanje", + "select_type": "Izberi vrsto", + "browse_movies": "Prebrskaj kataloge filmov", + "browse_tv": "Prebrskaj kataloge TV serij", + "select_genre": "Izberi žanr", + "show_all_content": "Prikaži vso vsebino", + "genres_count": "{{count}} žanrov" + }, + "library": { + "title": "Knjižnica", + "watched": "Ogledano", + "continue": "Nadaljuj", + "watchlist": "Seznam ogledov", + "collection": "Zbirka", + "rated": "Ocenjeno", + "items": "elementov", + "trakt_collections": "Trakt zbirke", + "trakt_collection": "Trakt zbirka", + "no_trakt": "Ni Trakt zbirk", + "no_trakt_desc": "Vaše Trakt zbirke se bodo pojavile tukaj, ko začnete uporabljati Trakt", + "load_collections": "Naloži zbirke", + "empty_folder": "Ni vsebine v {{folder}}", + "empty_folder_desc": "Ta zbirka je prazna", + "refresh": "Osveži", + "no_movies": "Ni še filmov", + "no_series": "Ni še TV oddaj", + "no_content": "Ni še vsebine", + "add_content_desc": "Dodajte vsebino v knjižnico, da jo vidite tukaj", + "find_something": "Najdi nekaj za gledanje", + "removed_from_library": "Odstranjeno iz knjižnice", + "item_removed": "Element odstranjen iz knjižnice", + "failed_update_library": "Posodobitev knjižnice ni uspela", + "unable_remove": "Elementa ni mogoče odstraniti iz knjižnice", + "marked_watched": "Označeno kot ogledano", + "marked_unwatched": "Označeno kot neogledano", + "item_marked_watched": "Element je označen kot ogledan", + "item_marked_unwatched": "Element je označen kot neogledan", + "failed_update_watched": "Posodobitev stanja ogleda ni uspela", + "unable_update_watched": "Stanja ogleda ni mogoče posodobiti", + "added_to_library": "Dodano v knjižnico", + "item_added": "Dodano v vašo lokalno knjižnico", + "add_to_library": "Dodaj v knjižnico", + "remove_from_library": "Odstrani iz knjižnice", + "mark_watched": "Označi kot ogledano", + "mark_unwatched": "Označi kot neogledano", + "share": "Deli", + "add_to_watchlist": "Dodaj na Trakt seznam ogledov", + "remove_from_watchlist": "Odstrani s Trakt seznama ogledov", + "added_to_watchlist": "Dodano na seznam ogledov", + "added_to_watchlist_desc": "Dodano na vaš Trakt seznam ogledov", + "removed_from_watchlist": "Odstranjeno s seznama ogledov", + "removed_from_watchlist_desc": "Odstranjeno z vašega Trakt seznama ogledov", + "add_to_collection": "Dodaj v Trakt zbirko", + "remove_from_collection": "Odstrani iz Trakt zbirke", + "added_to_collection": "Dodano v zbirko", + "added_to_collection_desc": "Dodano v vašo Trakt zbirko", + "removed_from_collection": "Odstranjeno iz zbirke", + "removed_from_collection_desc": "Odstranjeno iz vaše Trakt zbirke" + }, + "metadata": { + "unable_to_load": "Vsebine ni mogoče naložiti", + "error_code": "Koda napake: {{code}}", + "content_not_found": "Vsebine ni mogoče najti", + "content_not_found_desc": "Ta vsebina ne obstaja ali pa je bila odstranjena.", + "server_error": "Napaka strežnika", + "server_error_desc": "Strežnik trenutno ni na voljo. Poskusite pozneje.", + "bad_gateway": "Slab prehod", + "bad_gateway_desc": "Strežnik ima težave. Poskusite pozneje.", + "service_unavailable": "Storitev ni na voljo", + "service_unavailable_desc": "Storitev je trenutno onemogočena zaradi vzdrževanja. Poskusite pozneje.", + "too_many_requests": "Preveč zahtev", + "too_many_requests_desc": "Pošiljate preveč zahtev. Počakajte trenutek in poskusite znova.", + "request_timeout": "Časovna omejitev zahteve", + "request_timeout_desc": "Zahteva je trajala predolgo. Poskusite znova.", + "network_error": "Napaka omrežja", + "network_error_desc": "Preverite internetno povezavo in poskusite znova.", + "auth_error": "Napaka pri preverjanju pristnosti", + "auth_error_desc": "Preverite nastavitve računa in poskusite znova.", + "access_denied": "Dostop zavrnjen", + "access_denied_desc": "Nimate dovoljenja za dostop do te vsebine.", + "connection_error": "Napaka povezave", + "streams_unavailable": "Viri niso na voljo", + "streams_unavailable_desc": "Viri pretakanja trenutno niso na voljo. Poskusite pozneje.", + "unknown_error": "Neznana napaka", + "something_went_wrong": "Nekaj je šlo narobe. Poskusite znova.", + "cast": "Igralska zasedba", + "more_like_this": "Več podobnih vsebin", + "collection": "Zbirka", + "episodes": "Epizode", + "seasons": "Sezone", + "posters": "Plakati", + "banners": "Pasice", + "specials": "Posebne epizode", + "season_number": "Sezona {{number}}", + "episode_count": "{{count}} epizoda", + "episode_count_plural": "{{count}} epizod", + "no_episodes": "Epizode niso na voljo", + "no_episodes_for_season": "Ni epizod za sezono {{season}}", + "episodes_not_released": "Epizode morda še niso izšle", + "no_description": "Opis ni na voljo", + "episode_label": "EPIZODA {{number}}", + "watch_again": "Glej ponovno", + "completed": "Dokončano", + "play_episode": "Predvajaj S{{season}}E{{episode}}", + "play": "Predvajaj", + "watched": "Ogledano", + "watched_on_trakt": "Ogledano na Traktu", + "synced_with_trakt": "Sinhronizirano s Traktom", + "saved": "Shranjeno", + "director": "Režiser", + "directors": "Režiserji", + "creator": "Ustvarjalec", + "creators": "Ustvarjalci", + "production": "Produkcija", + "network": "Mreža", + "mark_watched": "Označi kot ogledano", + "mark_unwatched": "Označi kot neogledano", + "marking": "Označevanje...", + "removing": "Odstranjevanje...", + "unmark_season": "Odznači sezono {{season}}", + "mark_season": "Označi sezono {{season}}", + "resume": "Nadaljuj", + "spoiler_warning": "Opozorilo o razkritju", + "spoiler_warning_desc": "Ta komentar vsebuje razkritja zgodbe. Ali ga želite vseeno prikazati?", + "cancel": "Prekliči", + "reveal_spoilers": "Razkrij vsebino", + "movie_details": "Podrobnosti o filmu", + "show_details": "Podrobnosti o oddaji", + "tagline": "Slogan", + "status": "Stanje", + "release_date": "Datum izida", + "runtime": "Trajanje", + "budget": "Proračun", + "revenue": "Prihodek", + "origin_country": "Država izvora", + "original_language": "Izvirni jezik", + "first_air_date": "Prvič predvajano", + "last_air_date": "Zadnjič predvajano", + "total_episodes": "Skupaj epizod", + "episode_runtime": "Trajanje epizode", + "created_by": "Ustvaril", + "backdrop_gallery": "Galerija ozadij", + "loading_episodes": "Nalaganje epizod...", + "no_episodes_available": "Epizode niso na voljo", + "play_next": "Predvajaj S{{season}}E{{episode}}", + "play_next_episode": "Predvajaj naslednjo epizodo", + "save": "Shrani", + "percent_watched": "{{percent}} % ogledano", + "percent_watched_trakt": "{{percent}} % ogledano ({{traktPercent}} % na Traktu)", + "synced_with_trakt_progress": "Sinhronizirano s Traktom", + "using_trakt_progress": "Uporaba Trakt napredka", + "added_to_collection_hero": "Dodano v zbirko", + "added_to_collection_desc_hero": "Dodano v vašo Trakt zbirko", + "removed_from_collection_hero": "Odstranjeno iz zbirke", + "removed_from_collection_desc_hero": "Odstranjeno iz vaše Trakt zbirke", + "mark_as_watched": "Označi kot ogledano", + "mark_as_unwatched": "Označi kot neogledano" + }, + "cast": { + "biography": "Biografija", + "known_for": "Znan po", + "personal_info": "Osebni podatki", + "born_in": "Rojen v: {{place}}", + "filmography": "Filmografija", + "also_known_as": "Znan tudi kot", + "no_info_available": "Dodatne informacije niso na voljo", + "as_character": "kot {{character}}", + "loading_details": "Nalaganje podrobnosti...", + "years_old": "{{age}} let", + "view_filmography": "Prikaži filmografijo", + "filter": "Filter", + "sort_by": "Razvrsti po", + "sort_popular": "Priljubljeno", + "sort_latest": "Najnovejše", + "sort_upcoming": "Prihajajoče", + "upcoming_badge": "PRIHAJAJOČE", + "coming_soon": "Kmalu", + "filmography_count": "Filmografija • {{count}} naslovov", + "loading_filmography": "Nalaganje filmografije...", + "load_more_remaining": "Naloži več (še {{count}})", + "alert_error_title": "Napaka", + "alert_error_message": "Naslova \"{{title}}\" ni bilo mogoče naložiti. Poskusite pozneje.", + "alert_ok": "V redu", + "no_upcoming": "Za tega igralca ni prihajajočih izidov", + "no_content": "Za tega igralca ni na voljo nobene vsebine", + "no_movies": "Za tega igralca ni na voljo nobenih filmov", + "no_tv": "Za tega igralca ni na voljo nobenih TV oddaj" + }, + "comments": { + "title": "Trakt komentarji", + "spoiler_warning": "⚠️ Ta komentar vsebuje razkritja. Tapnite za prikaz.", + "spoiler": "Razkritje", + "contains_spoilers": "Vsebuje razkritja", + "reveal": "Razkrij", + "vip": "VIP", + "unavailable": "Komentarji niso na voljo", + "no_comments": "Na Traktu še ni komentarjev", + "not_in_database": "Te vsebine morda še ni v Trakt bazi podatkov", + "check_trakt": "Preveri Trakt" + }, + "trailers": { + "title": "Napovedniki", + "official_trailers": "Uradni napovedniki", + "official_trailer": "Uradni napovednik", + "teasers": "Napovedniki (teasers)", + "teaser": "Napovednik (teaser)", + "clips_scenes": "Izseki in prizori", + "clip": "Izsek", + "featurettes": "Prispevki (featurettes)", + "featurette": "Prispevek (featurette)", + "behind_the_scenes": "Zakulisje", + "no_trailers": "Napovedniki niso na voljo", + "unavailable": "Napovednik ni na voljo", + "unavailable_desc": "Napovednika trenutno ni mogoče naložiti. Poskusite pozneje.", + "unable_to_play": "Napovednika ni mogoče predvajati. Poskusite znova.", + "watch_on_youtube": "Glej na YouTubu" + }, + "catalog": { + "no_content_found": "Vsebine ni bilo mogoče najti", + "no_content_filters": "Za izbrane filtre ni bilo najdene vsebine", + "loading_content": "Nalaganje vsebine...", + "back": "Nazaj", + "in_theaters": "V kinih", + "all": "Vse", + "failed_tmdb": "Nalaganje vsebine s TMDB ni uspelo", + "movies": "Filmi", + "tv_shows": "TV oddaje", + "channels": "Kanali" + }, + "streams": { + "back_to_episodes": "Nazaj na epizode", + "back_to_info": "Nazaj na informacije", + "fetching_from": "Pridobivanje iz:", + "no_sources_available": "Viri pretakanja niso na voljo", + "add_sources_desc": "V nastavitvah dodajte vire pretakanja", + "add_sources": "Dodaj vire", + "finding_streams": "Iskanje razpoložljivih virov...", + "finding_best_stream": "Iskanje najboljšega vira za samodejno predvajanje...", + "still_fetching": "Še vedno pridobivam vire...", + "no_streams_available": "Ni razpoložljivih virov", + "starting_best_stream": "Zagon najboljšega vira...", + "loading_more_sources": "Nalaganje dodatnih virov..." + }, + "player_ui": { + "via": "preko {{name}}", + "audio_tracks": "Zvočni zapisi", + "no_audio_tracks": "Zvočni zapisi niso na voljo", + "playback_speed": "Hitrost predvajanja", + "on_hold": "Na čakanju", + "playback_error": "Napaka pri predvajanju", + "unknown_error": "Med predvajanjem je prišlo do neznane napake.", + "copy_error": "Kopiraj podrobnosti napake", + "copied_to_clipboard": "Kopirano v odložišče", + "dismiss": "Opusti", + "continue_watching": "Nadaljuj z gledanjem", + "start_over": "Začni znova", + "resume": "Nadaljuj", + "change_source": "Spremeni vir", + "switching_source": "Preklapljanje vira...", + "no_sources_found": "Ni najdenih virov", + "sources": "Viri", + "finding_sources": "Iskanje virov...", + "unknown_source": "Neznan vir", + "sources_limited": "Viri so morda omejeni zaradi napak ponudnika.", + "episodes": "Epizode", + "specials": "Posebne epizode", + "season": "Sezona {{season}}", + "stream": "Vir {{number}}", + "subtitles": "Podnapisi", + "built_in": "Vgrajeni", + "addons": "Dodatki", + "style": "Slog", + "none": "Brez", + "search_online_subtitles": "Išči podnapise na spletu", + "preview": "Predogled", + "quick_presets": "Hitre prednastavitve", + "default": "Privzeto", + "yellow": "Rumeno", + "high_contrast": "Visok kontrast", + "large": "Veliko", + "core": "Jedro", + "font_size": "Velikost pisave", + "show_background": "Pokaži ozadje", + "advanced": "Napredno", + "position": "Položaj", + "text_color": "Barva besedila", + "align": "Poravnava", + "bottom_offset": "Odmik od spodaj", + "background_opacity": "Prosojnost ozadja", + "text_shadow": "Senca besedila", + "on": "Vklopljeno", + "off": "Izklopljeno", + "outline_color": "Barva obrobe", + "outline": "Obroba", + "outline_width": "Širina obrobe", + "letter_spacing": "Razmik med črkami", + "line_height": "Višina vrstice", + "timing_offset": "Časovni zamik (s)", + "visual_sync": "Vizualna sinhronizacija", + "timing_hint": "Pomaknite podnapise prej (-) ali pozneje (+), če je potrebna sinhronizacija.", + "reset_defaults": "Ponastavi na privzeto", + "mark_intro_start": "Označi začetek uvoda", + "mark_intro_end": "Označi konec uvoda", + "intro_start_marked": "Začetek uvoda označen", + "intro_submitted": "Uvod uspešno poslan", + "intro_submit_failed": "Pošiljanje uvoda ni uspelo" + }, + "downloads": { + "title": "Prenosi", + "no_downloads": "Ni še prenosov", + "no_downloads_desc": "Prenesena vsebina se bo prikazala tukaj za ogled brez povezave", + "explore": "Razišči vsebino", + "path_copied": "Pot kopirana", + "path_copied_desc": "Pot do lokalne datoteke je kopirana v odložišče", + "copied": "Kopirano", + "incomplete": "Prenos ni dokončan", + "incomplete_desc": "Prenos še ni končan", + "not_available": "Ni na voljo", + "not_available_desc": "Lokalna pot je na voljo šele, ko je prenos končan.", + "status_downloading": "Prenašanje", + "status_completed": "Končano", + "status_paused": "V premoru", + "status_error": "Napaka", + "status_queued": "V čakalni vrsti", + "status_unknown": "Neznano", + "provider": "Ponudnik", + "streaming_playlist_warning": "Morda se ne bo predvajalo - pretočni seznam (playlist)", + "remaining": "preostalo", + "not_ready": "Prenos ni pripravljen", + "not_ready_desc": "Počakajte, da se prenos konča.", + "filter_all": "Vse", + "filter_active": "Aktivno", + "filter_done": "Končano", + "filter_paused": "V premoru", + "no_filter_results": "Ni prenosov za filter {{filter}}", + "try_different_filter": "Poskusite izbrati drug filter", + "limitations_title": "Omejitve prenosov", + "limitations_msg": "• Datoteke, manjše od 1 MB, so običajno M3U8 pretočni seznami in jih ni mogoče prenesti za ogled brez povezave. Te delujejo le s spletnim pretakanjem.", + "remove_title": "Odstrani prenos", + "remove_confirm": "Odstrani \"{{title}}\"{{season_episode}}?", + "cancel": "Prekliči", + "remove": "Odstrani" + }, + "addons": { + "title": "Dodatki", + "reorder_mode": "Način razvrščanja", + "reorder_info": "Dodatki na vrhu imajo prednost pri nalaganju vsebine", + "add_addon_placeholder": "URL dodatka", + "add_button": "Dodaj dodatek", + "my_addons": "Moji dodatki", + "community_addons": "Skupnostni dodatki", + "no_addons": "Ni nameščenih dodatkov", + "uninstall_title": "Odstrani dodatek", + "uninstall_message": "Ali ste prepričani, da želite odstraniti {{name}}?", + "uninstall_button": "Odstrani", + "install_success": "Dodatek uspešno nameščen", + "install_error": "Namestitev dodatka ni uspela", + "load_error": "Nalaganje dodatkov ni uspelo", + "fetch_error": "Pridobivanje podrobnosti o dodatku ni uspelo", + "invalid_url": "Vnesite URL dodatka", + "configure": "Nastavi", + "version": "Različica: {{version}}", + "installed_addons": "NAMEŠČENI DODATKI", + "reorder_drag_title": "POVLECITE DODATKE ZA RAZVRŠČANJE", + "install": "Namesti", + "config_unavailable_title": "Nastavitve niso na voljo", + "config_unavailable_msg": "Ni mogoče določiti URL-ja za nastavitev tega dodatka.", + "cannot_open_config_title": "Nastavitev ni mogoče odpreti", + "cannot_open_config_msg": "URL-ja za nastavitev ({{url}}) ni mogoče odpreti. Dodatek morda nima strani za nastavitve.", + "description": "Opis", + "supported_types": "Podprte vrste", + "catalogs": "Katalogi", + "no_description": "Opis ni na voljo", + "overview": "PREGLED", + "no_categories": "Brez kategorij", + "pre_installed": "PREDNAMEŠČENO" + }, + "trakt": { + "title": "Trakt nastavitve", + "settings_title": "Trakt nastavitve", + "connect_title": "Poveži se s Traktom", + "connect_desc": "Sinhronizirajte zgodovino ogledov, seznam ogledov in zbirko s Trakt.tv", + "sign_in": "Prijava v Trakt", + "sign_out": "Odjava", + "sign_out_confirm": "Ali ste prepričani, da se želite odjaviti iz svojega Trakt računa?", + "joined": "Pridružen {{date}}", + "sync_settings_title": "Nastavitve sinhronizacije", + "sync_info": "Ko ste povezani s Traktom, se celotna zgodovina sinhronizira neposredno prek API-ja in se ne zapisuje v lokalno shrambo. Vaš seznam 'Nadaljuj z gledanjem' odraža vaš globalni Trakt napredek.", + "auto_sync_label": "Samodejna sinhronizacija napredka", + "auto_sync_desc": "Samodejno sinhroniziraj napredek gledanja s Traktom", + "import_history_label": "Uvozi zgodovino ogledov", + "import_history_desc": "Uporabite 'Sinhroniziraj zdaj' za uvoz zgodovine ogledov in napredka s Trakta", + "sync_now_button": "Sinhroniziraj zdaj", + "display_settings_title": "Nastavitve zaslona", + "show_comments_label": "Prikaži Trakt komentarje", + "show_comments_desc": "Prikaži Trakt komentarje na zaslonih z metapodatki, ko so na voljo", + "maintenance_title": "Vzdrževanje", + "maintenance_unavailable": "Trakt ni na voljo", + "maintenance_desc": "Integracija s Traktom je začasno onemogočena zaradi vzdrževanja. Vsa sinhronizacija in avtentikacija sta onemogočeni, dokler vzdrževanje ni končano.", + "maintenance_button": "Storitev se vzdržuje", + "auth_success_title": "Uspešno povezano", + "auth_success_msg": "Vaš Trakt račun je bil uspešno povezan.", + "auth_error_title": "Napaka pri avtentikaciji", + "auth_error_msg": "Preverjanje pristnosti s Traktom ni uspelo.", + "auth_error_generic": "Med preverjanjem pristnosti je prišlo do napake.", + "sign_out_error": "Odjava iz Trakta ni uspela.", + "sync_complete_title": "Sinhronizacija končana", + "sync_success_msg": "Napredek gledanja je bil uspešno sinhroniziran s Traktom.", + "sync_error_msg": "Sinhronizacija ni uspela. Poskusite znova." + }, + "simkl": { + "title": "Simkl nastavitve", + "settings_title": "Simkl nastavitve", + "connect_title": "Poveži se s Simklom", + "connect_desc": "Sinhronizirajte zgodovino ogledov in spremljajte, kaj gledate", + "sign_in": "Prijava v Simkl", + "sign_out": "Prekini povezavo", + "sign_out_confirm": "Ali ste prepričani, da želite prekiniti povezavo s Simklom?", + "syncing_desc": "Vaši ogledani elementi se sinhronizirajo s Simklom.", + "auth_success_title": "Uspešno povezano", + "auth_success_msg": "Vaš Simkl račun je bil uspešno povezan.", + "auth_error_title": "Napaka pri avtentikaciji", + "auth_error_msg": "Preverjanje pristnosti s Simklom ni uspelo.", + "auth_error_generic": "Med preverjanjem pristnosti je prišlo do napake.", + "sign_out_error": "Prekinitev povezave s Simklom ni uspela.", + "config_error_title": "Napaka v konfiguraciji", + "config_error_msg": "Simkl Client ID manjka v okoljskih spremenljivkah.", + "conflict_title": "Spor", + "conflict_msg": "S Simklom se ne morete povezati, dokler je povezan Trakt. Najprej prekinite povezavo s Traktom.", + "disclaimer": "Nuvio ni povezan s Simklom." + }, + "tmdb_settings": { + "title": "TMDb nastavitve", + "metadata_enrichment": "Obogatitev metapodatkov", + "metadata_enrichment_desc": "Izboljšajte metapodatke vsebine s podatki TMDb za boljše podrobnosti in informacije.", + "enable_enrichment": "Omogoči obogatitev", + "enable_enrichment_desc": "Dopolni metapodatke dodatkov s TMDb podatki za igralce, certifikate, logotipe/plakate in produkcijske informacije.", + "localized_text": "Lokalizirano besedilo", + "localized_text_desc": "Pridobi naslove in opise v vašem prednostnem jeziku iz TMDb.", + "language": "Jezik", + "change": "Spremeni", + "logo_preview": "Predogled logotipa", + "logo_preview_desc": "Predogled prikazuje, kako se bodo lokalizirani logotipi pojavili v izbranem jeziku.", + "example": "Primer:", + "no_logo": "Logotip ni na voljo", + "enrichment_options": "Možnosti obogatitve", + "enrichment_options_desc": "Nadzirajte, kateri podatki se pridobivajo iz TMDb. Onemogočene možnosti bodo uporabile podatke dodatkov, če so na voljo.", + "cast_crew": "Igralska zasedba in ekipa", + "cast_crew_desc": "Igralci, režiserji, scenaristi s profilnimi fotografijami", + "title_description": "Naslov in opis", + "title_description_desc": "Uporabi lokaliziran naslov in opis iz TMDb", + "title_logos": "Logotipi naslovov", + "title_logos_desc": "Visokokakovostne slike naslovov", + "banners_backdrops": "Pasice in ozadja", + "banners_backdrops_desc": "Slike ozadja visoke ločljivosti", + "certification": "Certifikacija vsebine", + "certification_desc": "Starostne omejitve (PG-13, R, TV-MA, itd.)", + "recommendations": "Priporočila", + "recommendations_desc": "Predlogi za podobno vsebino", + "episode_data": "Podatki o epizodah", + "episode_data_desc": "Sličice epizod, informacije in nadomestni podatki za TV oddaje", + "season_posters": "Plakati sezon", + "season_posters_desc": "Slike plakatov za specifične sezone", + "production_info": "Informacije o produkciji", + "production_info_desc": "Mreže in produkcijske hiše z logotipi", + "movie_details": "Podrobnosti o filmu", + "movie_details_desc": "Proračun, prihodki, trajanje, slogan", + "tv_details": "Podrobnosti o TV oddaji", + "tv_details_desc": "Stanje, število sezon, mreže, ustvarjalci", + "movie_collections": "Filmske zbirke", + "movie_collections_desc": "Filmske franšize (Marvel, Star Wars, itd.)", + "api_configuration": "Konfiguracija API-ja", + "api_configuration_desc": "Konfigurirajte svoj dostop do TMDb API-ja za izboljšano funkcionalnost.", + "custom_api_key": "API ključ po meri", + "custom_api_key_desc": "Uporabite lasten TMDb API ključ za boljšo učinkovitost in namenske omejitve.", + "custom_key_active": "API ključ po meri je aktiven", + "api_key_required": "API ključ je obvezen", + "api_key_placeholder": "Prilepite svoj TMDb API ključ (v3)", + "how_to_get_key": "Kako pridobiti TMDb API ključ?", + "built_in_key_msg": "Trenutno uporabljate vgrajeni API ključ. Razmislite o uporabi lastnega ključa za boljšo učinkovitost.", + "cache_size": "Velikost predpomnilnika", + "clear_cache": "Počisti predpomnilnik", + "cache_days": "TMDb odzivi so shranjeni 7 dni za izboljšanje učinkovitosti", + "choose_language": "Izberi jezik", + "choose_language_desc": "Izberite prednostni jezik za TMDb vsebino", + "popular": "Priljubljeno", + "all_languages": "Vsi jeziki", + "search_results": "Rezultati iskanja", + "no_languages_found": "Ni najdenih jezikov za \"{{query}}\"", + "clear_search": "Počisti iskanje", + "clear_cache_title": "Počisti TMDb predpomnilnik", + "clear_cache_msg": "To bo izbrisalo vse shranjene TMDb podatke ({{size}}). To lahko začasno upočasni nalaganje.", + "clear_cache_success": "TMDb predpomnilnik uspešno počiščen.", + "clear_cache_error": "Predpomnilnika ni bilo mogoče počistiti.", + "clear_api_key_title": "Izbriši API ključ", + "clear_api_key_msg": "Ali ste prepričani, da želite odstraniti svoj API ključ in se vrniti na privzetega?", + "clear_api_key_success": "API ključ uspešno izbrisan", + "clear_api_key_error": "API ključa ni bilo mogoče izbrisati", + "empty_api_key": "API ključ ne more biti prazen.", + "invalid_api_key": "Neveljaven API ključ. Preverite in poskusite znova.", + "save_error": "Med shranjevanjem je prišlo do napake. Poskusite znova.", + "using_builtin_key": "Zdaj uporabljate vgrajeni TMDb API ključ.", + "using_custom_key": "Zdaj uporabljate svoj TMDb API ključ po meri.", + "enter_custom_key": "Vnesite in shranite svoj TMDb API ključ po meri.", + "key_verified": "API ključ je bil preverjen in uspešno shranjen." + }, + "settings": { + "language": "Jezik", + "select_language": "Izberite jezik", + "english": "Angleščina", + "portuguese": "Portugalščina", + "portuguese_br": "Portugalščina (Brazilija)", + "portuguese_pt": "Portugalščina (Portugalska)", + "german": "Nemščina", + "arabic": "Arabščina", + "spanish": "Španščina", + "french": "Francoščina", + "italian": "Italijanščina", + "croatian": "Hrvaščina", + "chinese": "Kitajščina (poenostavljena)", + "hindi": "Hindi", + "serbian": "Srbeščina", + "hebrew": "Hebrejščina", + "bulgarian": "Bulgarščina", + "polish": "Poljščina", + "czech": "Češčina", + "turkish": "Turščina", + "slovenian": "Slovenščina", + "macedonian": "Makedonski", + "russian": "Ruščina", + "filipino": "Filipinščina", + "dutch_nl": "Nizozemščina (Nizozemska)", + "romanian": "Romunščina", + "albanian": "Albanski", + "account": "Račun", + "content_discovery": "Vsebina in odkrivanje", + "appearance": "Videz", + "integrations": "Integracije", + "playback": "Predvajanje", + "backup_restore": "Varnostna kopija in obnovitev", + "updates": "Posodobitve", + "about": "O aplikaciji", + "developer": "Razvijalec", + "cache": "Predpomnilnik", + "title": "Nastavitve", + "settings_title": "Nastavitve", + "sign_in_sync": "Prijavite se za sinhronizacijo", + "add_catalogs_sources": "Dodatki, katalogi in viri", + "player_trailers_downloads": "Predvajalnik, napovedniki, prenosi", + "mdblist_tmdb_ai": "MDBList, TMDb, AI", + "check_updates": "Preveri posodobitve", + "clear_mdblist_cache": "Počisti MDBList predpomnilnik", + "cache_management": "UPRAVLJANJE PREDPOMNILNIKA", + "downloads_counter": "prenosov in narašča", + "made_with_love": "Izdelano z ❤️ - Tapframe in prijatelji", + "sections": { + "information": "INFORMACIJE", + "account": "RAČUN", + "theme": "TEMA", + "layout": "POSTAVITEV", + "sources": "VIRI", + "catalogs": "KATALOGI", + "discovery": "ODKRIVANJE", + "metadata": "METAPODATKI", + "ai_assistant": "AI ASISTENT", + "video_player": "VIDEO PREDVAJALNIK", + "audio_subtitles": "AVDIO IN PODNAPISI", + "media": "MEDIJI", + "notifications": "OBVESTILA", + "testing": "TESTIRANJE", + "danger_zone": "NEVARNO OBMOČJE" + }, + "items": { + "legal": "Pravne informacije", + "privacy_policy": "Pravilnik o zasebnosti", + "report_issue": "Prijavi težavo", + "version": "Različica", + "contributors": "Sodelavci", + "view_contributors": "Prikaži vse sodelavce", + "theme": "Tema", + "episode_layout": "Postavitev epizod", + "streams_backdrop": "Ozadje virov", + "streams_backdrop_desc": "Prikaži zamegljeno ozadje pri virih na mobilnih napravah", + "addons": "Dodatki", + "installed": "nameščeno", + "debrid_integration": "Debrid integracija", + "debrid_desc": "Poveži Torbox", + "plugins": "Vtičniki", + "plugins_desc": "Upravljaj vtičnike in repozitorije", + "catalogs": "Katalogi", + "active": "aktivno", + "home_screen": "Začetni zaslon", + "home_screen_desc": "Postavitev in vsebina", + "continue_watching": "Nadaljuj z gledanjem", + "continue_watching_desc": "Predpomnjenje in obnašanje predvajanja", + "show_discover": "Pokaži razdelek 'Odkrivaj'", + "show_discover_desc": "Prikaži vsebino za odkrivanje v iskanju", + "mdblist": "MDBList", + "mdblist_connected": "Povezano", + "mdblist_desc": "Omogoči za ocene in ocene uporabnikov", + "simkl": "Simkl", + "simkl_connected": "Povezano", + "simkl_desc": "Spremljajte, kaj gledate", + "tmdb": "TMDb", + "tmdb_desc": "Vir metapodatkov in logotipov", + "openrouter": "OpenRouter API", + "openrouter_connected": "Povezano", + "openrouter_desc": "Dodajte API ključ za AI klepet", + "video_player": "Video predvajalnik", + "built_in": "Vgrajen", + "external": "Zunanji", + "preferred_audio": "Prednostni jezik zvoka", + "preferred_subtitle": "Prednostni jezik podnapisov", + "subtitle_source": "Prioriteta vira podnapisov", + "auto_select_subs": "Samodejna izbira podnapisov", + "auto_select_subs_desc": "Samodejno izberi podnapise po vaših željah", + "show_trailers": "Pokaži napovednike", + "show_trailers_desc": "Prikaži napovednike v glavnem razdelku", + "enable_downloads": "Omogoči prenose", + "enable_downloads_desc": "Prikaži zavihek Prenosi i omogoči shranjevanje", + "notifications": "Obvestila", + "notifications_desc": "Opomniki za epizode", + "developer_tools": "Orodja za razvijalce", + "developer_tools_desc": "Možnosti testiranja in razhroščevanja", + "test_onboarding": "Testiraj uvajanje", + "reset_onboarding": "Ponastavi uvajanje", + "test_announcement": "Testiraj obvestilo", + "test_announcement_desc": "Prikaži prekrivni zaslon 'Kaj je novega'", + "reset_campaigns": "Ponastavi kampanje", + "reset_campaigns_desc": "Počisti vtise kampanj", + "clear_all_data": "Počisti vse podatke", + "clear_all_data_desc": "Ponastavi vse nastavitve in predpomnjene podatke" + }, + "options": { + "horizontal": "Vodoravno", + "vertical": "Navpično", + "internal_first": "Najprej notranji", + "internal_first_desc": "Prednost imajo vgrajeni podnapisi", + "external_first": "Najprej zunanji", + "external_first_desc": "Prednost imajo zunanji podnapisi", + "any_available": "Katerikoli na voljo", + "any_available_desc": "Uporabi prvi razpoložljiv podnapis" + }, + "clear_data_desc": "To bo ponastavilo vse nastavitve in počistilo predpomnilnik. Ste prepričani?", + "app_updates": "Posodobitve aplikacije", + "about_nuvio": "O Nuvio" + }, + "privacy": { + "title": "Zasebnost in podatki", + "settings_desc": "Nadzor telemetrije in zbiranja podatkov", + "info_title": "Vaša zasebnost je pomembna", + "info_description": "Nadzirajte, kateri podatki se zbirajo. Analitika je privzeto izklopljena, poročila o napakah pa anonimna.", + "analytics_enabled_title": "Analitika omogočena", + "analytics_enabled_message": "Podatki o uporabi se bodo zbirali za izboljšanje aplikacije. To lahko kadarkoli onemogočite.", + "disable_error_reporting_title": "Onemogočim poročanje o napakah?", + "disable_error_reporting_message": "Če onemogočite poročanje, ne bomo obveščeni o sesutjih, kar oteži odpravljanje napak.", + "enable_session_replay_title": "Omogočim ponovni prikaz seje?", + "enable_session_replay_message": "To posname zaslon ob napaki za lažje razumevanje težave. Lahko zajame vidno vsebino zaslona.", + "enable_pii_title": "Omogočim zbiranje osebnih podatkov (PII)?", + "enable_pii_message": "Dovoli zbiranje IP naslova in podrobnosti o napravi za boljšo diagnostiko.", + "disable_all_title": "Onemogočim vso telemetrijo?", + "disable_all_message": "To bo onemogočilo vso analitiko in poročanje o napakah.", + "disable_all_button": "Onemogoči vse", + "all_disabled_title": "Vsa telemetrija onemogočena", + "all_disabled_message": "Zbiranje podatkov je onemogočeno. Spremembe stopijo v veljavo ob naslednjem zagonu.", + "reset_title": "Ponastavi na priporočeno", + "reset_message": "Nastavitve zasebnosti so bile ponastavljene na priporočene vrednosti.", + "section_analytics": "ANALITIKA", + "analytics_title": "Analitika uporabe", + "analytics_description": "Zbiranje anonimnih vzorcev uporabe", + "section_error_reporting": "POROČANJE O NAPAKAH", + "error_reporting_title": "Poročila o sesutjih", + "error_reporting_description": "Pošiljaj anonimna poročila za boljšo stabilnost", + "session_replay_title": "Ponovni prikaz seje", + "session_replay_description": "Posnemi zaslon, ko pride do napake", + "pii_title": "Vključi info o napravi", + "pii_description": "Pošlji IP naslov in podatke o napravi s poročili", + "section_quick_actions": "HITRE AKCIJE", + "disable_all": "Onemogoči vso telemetrijo", + "disable_all_desc": "Izklopi vso zbiranje podatkov", + "reset_recommended": "Ponastavi na priporočeno", + "reset_recommended_desc": "Zasebnost na prvem mestu s poročanjem o napakah", + "section_learn_more": "VEČ O TEM", + "privacy_policy": "Pravilnik o zasebnosti", + "current_settings": "Povzetek trenutnih nastavitev", + "summary_analytics": "Analitika", + "summary_errors": "Poročila o napakah", + "summary_replay": "Ponovni prikaz seje", + "summary_pii": "Info o napravi", + "restart_note_detailed": "* Spremembe analitike stopijo v veljavo takoj. Nastavitve seje in PII zahtevajo ponovni zagon." + }, + "ai_settings": { + "title": "AI asistent", + "info_title": "Klepet z umetno inteligenco", + "info_desc": "Z napredno umetno inteligenco zastavljajte vprašanja o katerem koli filmu ali epizodi TV oddaje. Pridobite vpoglede v zgodbo, like, teme in zanimivosti.", + "feature_1": "Kontekst in analiza posameznih epizod", + "feature_2": "Razlage zgodbe in vpogledi v like", + "feature_3": "Zanimivosti iz ozadja in dejstva", + "feature_4": "Uporaba lastnega brezplačnega OpenRouter API ključa", + "api_key_section": "OPENROUTER API KLJUČ", + "api_key_label": "API ključ", + "api_key_desc": "Vnesite svoj OpenRouter API ključ za AI klepet", + "save_api_key": "Shrani API ključ", + "saving": "Shranjevanje...", + "update": "Posodobi", + "remove": "Odstrani", + "get_free_key": "Pridobi brezplačen API ključ na OpenRouter", + "enable_chat": "Omogoči AI klepet", + "enable_chat_desc": "Ko je omogočeno, se na straneh z vsebino pojavi gumb 'Vprašaj AI'.", + "chat_enabled": "AI klepet omogočen", + "chat_enabled_desc": "Zdaj lahko sprašujete o filmih in oddajah. Poiščite gumb 'Vprašaj AI'!", + "how_it_works": "Kako deluje", + "how_it_works_desc": "• OpenRouter omogoča dostop do več AI modelov\n• Vaš API ključ ostane zaseben in varen\n• Brezplačni paket vključuje radodarne omejitve\n• Klepetajte s kontekstom o specifičnih epizodah\n• Pridobite podrobne analize in razlage", + "error_invalid_key": "Vnesite veljaven API ključ", + "error_key_format": "OpenRouter API ključi se morajo začeti s 'sk-or-'", + "success_saved": "OpenRouter API ključ uspešno shranjen!", + "error_save": "Shranjevanje API ključa ni uspelo", + "confirm_remove_title": "Odstrani API ključ", + "confirm_remove_msg": "Ali ste prepričani? To bo onemogočilo AI funkcije.", + "success_removed": "API ključ uspešno odstranjen", + "error_remove": "Odstranjevanje API ključa ni uspelo" + }, + "catalog_settings": { + "title": "Katalogi", + "layout_phone": "POSTAVITEV ZASLONA KATALOGOV (TELEFON)", + "posters_per_row": "Plakatov v vrstici", + "auto": "Samodejno", + "show_titles": "Pokaži naslove plakatov", + "show_titles_desc": "Prikaži naslov pod vsakim plakatom", + "phone_only_hint": "Velja samo za telefone. Tablice ohranijo prilagodljivo postavitev.", + "catalogs_group": "Katalogi", + "enabled_count": "Omogočeno {{enabled}} od {{total}}", + "rename_hint": "Dolgo pritisnite na katalog za preimenovanje", + "rename_modal_title": "Preimenuj katalog", + "rename_placeholder": "Vnesite novo ime kataloga", + "error_save_name": "Imena po meri ni bilo mogoče shraniti." + }, + "continue_watching_settings": { + "title": "Nadaljuj z gledanjem", + "playback_behavior": "OBNAŠANJE PREDVAJANJA", + "use_cached": "Uporabi predpomnjene vire", + "use_cached_desc": "Klik na elemente 'Nadaljuj z gledanjem' bo takoj odprl predvajalnik s prejšnjimi viri. Če je onemogočeno, odpre zaslon z vsebino.", + "open_metadata": "Odpri zaslon z metapodatki", + "open_metadata_desc": "Odpre podrobnosti o vsebini namesto seznama virov.", + "card_appearance": "VIDEZ KARTICE", + "card_style": "Slog kartice", + "card_style_desc": "Izberite videz elementov na začetnem zaslonu", + "wide": "Široko", + "poster": "Plakat", + "cache_settings": "NASTAVITVE PREDPOMNILNIKA", + "cache_duration": "Trajanje predpomnilnika virov", + "cache_duration_desc": "Kako dolgo naj se hranijo povezave do virov", + "important_note": "Pomembno obvestilo", + "important_note_text": "Vse povezave morda ne bodo delovale ves čas. Če predpomnjena povezava ne uspe, bo aplikacija poiskala nove vire.", + "how_it_works": "Kako deluje", + "how_it_works_cached": "• Viri se shranijo za izbrano obdobje\n• Pred uporabo se preveri njihova veljavnost\n• Če so potekli, se vrne na zaslon z vsebino", + "how_it_works_uncached": "• Ko je onemogočeno, klik odpre podrobnosti vsebine\n• Metapodatkovni zaslon omogoča ročno izbiro virov", + "changes_saved": "Spremembe shranjene", + "min": "min", + "hour": "ura", + "hours": "ure" + }, + "contributors": { + "title": "Sodelavci", + "special_mentions": "Posebne omembe", + "tab_contributors": "Sodelavci", + "tab_special": "Posebne omembe", + "tab_donors": "Donatorji", + "manager_role": "Upravitelj skupnosti", + "manager_desc": "Upravlja Discord in Reddit skupnosti za Nuvio", + "sponsor_role": "Sponzor strežnika", + "sponsor_desc": "Sponzorira strežniško infrastrukturo za Nuvio", + "mod_role": "Discord moderator", + "mod_desc": "Pomaga pri moderiranju Nuvio Discord skupnosti", + "loading": "Nalaganje...", + "discord_user": "Uporabnik Discorda", + "contributions": "prispevkov", + "gratitude_title": "Hvaležni smo za vsak prispevek", + "gratitude_desc": "Vsaka vrstica kode i predlog pomagata izboljšati Nuvio", + "special_thanks_title": "Posebna hvala", + "special_thanks_desc": "Ti ljudje pomagajo ohranjati skupnost i strežnike na spletu", + "donors_desc": "Hvala za vašo podporo, ki ohranja Nuvio brezplačen.", + "latest_donations": "Zadnje", + "leaderboard": "Lestvica", + "loading_donors": "Nalaganje donatorjev...", + "no_donors": "Ni še donatorjev", + "error_rate_limit": "Omejitev GitHub API presežena. Poskusite pozneje.", + "error_failed": "Nalaganje sodelavcev ni uspelo. Preverite povezavo.", + "retry": "Poskusi znova", + "no_contributors": "Ni najdenih sodelavcev", + "loading_contributors": "Nalaganje sodelavcev..." + }, + "debrid": { + "title": "Debrid integracija", + "description_torbox": "Odklenite 4K visokokakovostne tokove in bliskovite hitrosti z integracijo Torbox. Spodaj vnesite svoj API ključ za takojšnjo nadgradnjo izkušnje pretakanja.", + "description_torrentio": "Konfigurirajte Torrentio za pridobivanje hudourniških (torrent) tokov za filme in TV oddaje. Za pretakanje vsebine je potrebna debrid storitev.", + "tab_torbox": "TorBox", + "tab_torrentio": "Torrentio", + "status_connected": "Povezano", + "status_disconnected": "Prekinjeno", + "enable_addon": "Omogoči dodatek", + "disconnect_button": "Prekini in odstrani", + "disconnect_loading": "Prekinjanje povezave...", + "account_info": "Informacije o računu", + "plan": "Paket", + "plan_free": "Brezplačno", + "plan_essential": "Essential ($3/mesec)", + "plan_pro": "Pro ($10/mesec)", + "plan_standard": "Standard ($5/mesec)", + "plan_unknown": "Neznano", + "expires": "Potreče", + "downloaded": "Prenešeno", + "status_active": "Aktivno", + "connected_title": "✓ Povezano s TorBox", + "connected_desc": "Vaš TorBox dodatek je aktiven in zagotavlja premium tokove.", + "configure_title": "Konfiguriraj dodatek", + "configure_desc": "Prilagodite svojo izkušnjo pretakanja. Razvrstite po kakovosti, filtrirajte velikosti datotek in upravljajte druge nastavitve.", + "open_settings": "Odpri nastavitve", + "what_is_debrid": "Kaj je Debrid storitev?", + "enter_api_key": "Vnesite svoj API ključ", + "connect_button": "Poveži in namesti", + "connecting": "Povezovanje...", + "unlock_speeds_title": "Odklenite premium hitrosti", + "unlock_speeds_desc": "Pridobite Torbox naročnino za dostop do predpomnjenih visokokakovostnih tokov brez zatikanja.", + "get_subscription": "Pridobite naročnino", + "powered_by": "Poganja", + "disclaimer_torbox": "Nuvio ni na noben način povezan s Torboxom.", + "disclaimer_torrentio": "Nuvio ni na noben način povezan s Torrentio.", + "installed_badge": "✓ NAMEŠČENO", + "promo_title": "⚡ Potrebujete Debrid storitev?", + "promo_desc": "Pridobite TorBox za bliskovito 4K pretakanje brez čakanja na nalaganje. Premium predpomnjeni torrenti in takojšnji prenosi.", + "promo_button": "Pridobite TorBox naročnino", + "service_label": "Debrid storitev *", + "api_key_label": "API ključ *", + "sorting_label": "Razvrščanje", + "exclude_qualities": "Izključi kakovosti", + "priority_languages": "Prednostni jeziki", + "max_results": "Največ rezultatov", + "additional_options": "Dodatne možnosti", + "no_download_links": "Ne prikaži povezav za prenos", + "no_debrid_catalog": "Ne prikaži debrid kataloga", + "install_button": "Namesti Torrentio", + "installing": "Nameščanje...", + "update_button": "Posodobi konfiguracijo", + "updating": "Posodabljanje...", + "remove_button": "Odstrani Torrentio", + "error_api_required": "API ključ je obvezen", + "error_api_required_desc": "Za namestitev Torrentio vnesite API ključ svoje debrid storitve.", + "success_installed": "Dodatek Torrentio je bil uspešno nameščen!", + "success_removed": "Dodatek Torrentio je bil uspešno odstranjen", + "alert_disconnect_title": "Prekini povezavo s Torbox", + "alert_disconnect_msg": "Ali ste prepričani, da želite prekiniti povezavo s Torboxom? To bo odstranilo dodatek in izbrisalo shranjen API ključ." + }, + "home_screen": { + "title": "Nastavitve začetnega zaslona", + "changes_applied": "Spremembe uveljavljene", + "display_options": "MOŽNOSTI PRIKAZA", + "show_hero": "Prikaži glavni razdelek (Hero)", + "show_hero_desc": "Izpostavljena vsebina na vrhu", + "show_this_week": "Prikaži razdelek 'Ta teden'", + "show_this_week_desc": "Nove epizode iz trenutnega tedna", + "select_catalogs": "Izberite kataloge", + "all_catalogs": "Vsi katalogi", + "selected": "izbrano", + "hero_layout": "Postavitev glavnega razdelka", + "layout_legacy": "Klasično", + "layout_carousel": "Vrtiljak", + "layout_appletv": "Apple TV", + "layout_desc": "Pasica čez celotno širino, drsne kartice ali Apple TV slog", + "featured_source": "Vir izpostavljene vsebine", + "using_catalogs": "Uporaba katalogov", + "manage_selected_catalogs": "Upravljaj izbrane kataloge", + "dynamic_bg": "Dinamično ozadje glavnega razdelka", + "dynamic_bg_desc": "Zamegljena pasica za vrtiljakom", + "performance_note": "Lahko vpliva na delovanje na manj zmogljivih napravah.", + "posters": "Plakati", + "show_titles": "Prikaži naslove", + "poster_size": "Velikost plakata", + "poster_corners": "Robovi plakata", + "size_small": "Majhno", + "size_medium": "Srednje", + "size_large": "Veliko", + "corners_square": "Ostro", + "corners_rounded": "Zaobljeno", + "corners_pill": "Kapsula", + "about_these_settings": "O TEH NASTAVITVAH", + "about_desc": "Te nastavitve nadzorujejo prikaz vsebine na vašem začetnem zaslonu. Spremembe so uveljavljene takoj.", + "hero_catalogs": { + "title": "Katalogi glavnega razdelka", + "select_all": "Izberi vse", + "clear_all": "Počisti vse", + "info": "Izberite kataloge za prikaz v glavnem razdelku. Če ni izbran noben, bodo uporabljeni vsi. Ne pozabite shraniti.", + "settings_saved": "Nastavitve shranjene", + "error_load": "Nalaganje katalogov ni uspelo", + "movies": "Filmi", + "tv_shows": "TV oddaje" + } + }, + "calendar": { + "title": "Koledar", + "loading": "Nalaganje koledarja...", + "no_scheduled_episodes": "Ni načrtovanih epizod", + "check_back_later": "Preverite pozneje", + "showing_episodes_for": "Prikaz epizod za {{date}}", + "show_all_episodes": "Prikaži vse epizode", + "no_episodes_for": "Ni epizod za {{date}}", + "no_upcoming_found": "Ni najdenih prihajajočih epizod", + "add_series_desc": "Dodajte serije v svojo knjižnico, da tukaj vidite njihove prihajajoče epizode" + }, + "mdblist": { + "title": "Viri ocen", + "status_disabled": "MDBList onemogočen", + "status_active": "API ključ aktiven", + "status_required": "API ključ obvezen", + "status_disabled_desc": "Funkcionalnost MDBList je trenutno onemogočena.", + "status_active_desc": "Ocene iz MDBList so omogočene.", + "status_required_desc": "Spodaj dodajte svoj ključ za omogočanje ocen.", + "enable_toggle": "Omogoči MDBList", + "enable_toggle_desc": "Vklopi/izklopi vse MDBList funkcije", + "api_section": "API ključ", + "placeholder": "Prilepite svoj MDBList API ključ", + "save": "Shrani", + "clear": "Izbriši ključ", + "rating_providers": "Ponudniki ocen", + "rating_providers_desc": "Izberite, katere ocene želite videti v aplikaciji", + "how_to": "Kako pridobiti API ključ", + "step_1": "Prijavite se na", + "step_1_link": "spletni strani MDBList", + "step_2": "Pojdite v razdelek", + "step_2_settings": "Settings", + "step_2_api": "API", + "step_2_end": ".", + "step_3": "Ustvarite nov ključ in ga kopirajte.", + "go_to_website": "Pojdi na MDBList", + "alert_clear_title": "Izbriši API ključ", + "alert_clear_msg": "Ali ste prepričani, da želite odstraniti shranjeni API ključ?", + "success_saved": "API ključ je bil uspešno shranjen.", + "error_empty": "API ključ ne more biti prazen.", + "error_save": "Med shranjevanjem je prišlo do napake. Poskusite znova.", + "api_key_empty_error": "API ključ ne more biti prazen.", + "success_cleared": "API ključ uspešno izbrisan", + "error_clear": "API ključa ni bilo mogoče izbrisati" + }, + "notification": { + "title": "Nastavitve obvestil", + "section_general": "Splošno", + "enable_notifications": "Omogoči obvestila", + "section_types": "Vrste obvestil", + "new_episodes": "Nove epizode", + "upcoming_shows": "Prihajajoče oddaje", + "reminders": "Opomniki", + "section_timing": "Čas obvestil", + "timing_desc": "Kdaj želite biti obveščeni pred predvajanjem epizode?", + "hours_1": "1 ura", + "hours_suffix": "ure/ur", + "section_status": "Stanje obvestil", + "stats_upcoming": "Prihajajoče", + "stats_this_week": "Ta teden", + "stats_total": "Skupaj", + "sync_button": "Sinhroniziraj knjižnico in Trakt", + "syncing": "Sinhronizacija...", + "sync_desc": "Samodejno sinhronizira obvestila za vse oddaje v vaši knjižnici in na Trakt seznamih.", + "section_advanced": "Napredno", + "reset_button": "Ponastavi vsa obvestila", + "test_button": "Testno obvestilo (5 s)", + "test_notification_in": "Obvestilo čez {{seconds}} s...", + "test_notification_text": "Obvestilo se bo pojavilo čez {{seconds}} sekund", + "alert_reset_title": "Ponastavi obvestila", + "alert_reset_msg": "To bo preklicalo vsa načrtovana obvestila. Ste prepričani?", + "alert_reset_success": "Vsa obvestila so bila ponastavljena", + "alert_sync_complete": "Sinhronizacija končana", + "alert_sync_msg": "Uspešno sinhronizirana obvestila.\n\nNačrtovano: {{upcoming}} epizod\nTa teden: {{thisWeek}} epizod", + "alert_test_scheduled": "Testno obvestilo je načrtovano" + }, + "backup": { + "title": "Varnostna kopija in obnovitev", + "options_title": "Možnosti varnostne kopije", + "options_desc": "Izberite, kaj želite vključiti v varnostno kopijo", + "section_core": "Jedrni podatki", + "section_addons": "Dodatki in integracije", + "section_settings": "Nastavitve in preference", + "library_label": "Knjižnica", + "library_desc": "Vaši shranjeni filmi in TV oddaje", + "watch_progress_label": "Napredek gledanja", + "watch_progress_desc": "Mesta, kjer ste končali gledanje", + "addons_label": "Dodatki", + "addons_desc": "Nameščeni Stremio dodatki", + "plugins_label": "Vtičniki", + "plugins_desc": "Konfiguracije scraperjev po meri", + "trakt_label": "Trakt integracija", + "trakt_desc": "Podatki o sinhronizaciji in žetoni za avtentikaciju", + "app_settings_label": "Nastavitve aplikacije", + "app_settings_desc": "Tema, preference in konfiguracije", + "user_prefs_label": "Uporabniške preference", + "user_prefs_desc": "Vrstni red dodatkov in nastavitve vmesnika", + "catalog_settings_label": "Nastavitve katalogov", + "catalog_settings_desc": "Filtri katalogov in preference", + "api_keys_label": "API ključi", + "api_keys_desc": "MDBList in OpenRouter ključi", + "action_create": "Ustvari varnostno kopijo", + "action_restore": "Obnovi iz varnostne kopije", + "section_info": "O varnostnih kopijah", + "info_text": "• Prilagodite vsebino kopije s stikali zgoraj\n• Datoteke se shranijo lokalno na vašo napravo\n• Delite datoteko za prenos podatkov med napravami\n• Obnovitev bo prepisala trenutne podatke", + "alert_create_title": "Ustvari varnostno kopijo", + "alert_no_content": "Nobena vsebina ni izbrana. Omogočite vsaj eno možnost.", + "alert_backup_created_title": "Varnostna kopija ustvarjena", + "alert_backup_created_msg": "Vaša varnostna kopija je pripravljena na deljenje.", + "alert_backup_failed_title": "Napaka pri ustvarjanju kopije", + "alert_restore_confirm_title": "Potrdi obnovitev", + "alert_restore_confirm_msg": "To bo obnovilo podatke iz kopije, ustvarjene dne {{date}}.\n\nTo bo prepisalo trenutne podatke. Želite nadaljevati?", + "alert_restore_complete_title": "Obnovitev končana", + "alert_restore_complete_msg": "Podatki so bili uspešno obnovljeni. Ponovno zaženite aplikacijo.", + "alert_restore_failed_title": "Obnovitev ni uspela", + "restart_app": "Ponovni zagon", + "alert_restart_failed_title": "Napaka pri zagonu", + "alert_restart_failed_msg": "Aplikacije ni bilo mogoče samodejno zagnati. Ročno jo zaprite in odprite." + }, + "updates": { + "title": "Posodobitve aplikacije", + "status_checking": "Preverjanje posodobitev...", + "status_available": "Posodobitev je na voljo!", + "status_downloading": "Prenos posodobitve...", + "status_installing": "Nameščanje posodobitve...", + "status_success": "Posodobitev uspešno nameščena!", + "status_error": "Posodobitev ni uspela", + "status_ready": "Pripravljeno na preverjanje", + "action_check": "Preveri posodobitve", + "action_install": "Namesti posodobitev", + "release_notes": "Zapisi o izdaji:", + "version": "Različica:", + "last_checked": "Zadnjič preverjeno:", + "current_version": "Trenutna različica:", + "current_release_notes": "Trenutni zapisi o izdaji:", + "github_release": "GITHUB IZDAJA", + "current": "Trenutna:", + "latest": "Najnovejša:", + "notes": "Opombe:", + "view_release": "Prikaži izdajo", + "notification_settings": "NASTAVITVE OBVESTIL", + "ota_alerts_label": "OTA opozorila o posodobitvah", + "ota_alerts_desc": "Prikaži obvestila za posodobitve prek spleta", + "major_alerts_label": "Opozorila o večjih posodobitvah", + "major_alerts_desc": "Prikaži obvestila za nove različice na GitHubu", + "alert_disable_ota_title": "Onemogočim OTA opozorila?", + "alert_disable_ota_msg": "Ne boste več prejemali samodejnih obvestil za OTA posodobitve. To je pomembno za popravke napak in stabilnost.", + "alert_disable_major_title": "Onemogočim opozorila o večjih posodobitvah?", + "alert_disable_major_msg": "Ne boste več obveščeni o večjih različicah, ki zahtevajo ponovno namestitev.", + "warning_note": "Omogočena opozorila zagotavljajo, da pravočasno prejmete popravke napak.", + "disable": "Onemogoči", + "alert_no_update_to_install": "Ni posodobitev za namestitev", + "alert_install_failed": "Namestitev posodobitve ni uspela", + "alert_no_update_title": "Ni posodobitev", + "alert_update_applied_msg": "Posodobitev bo uveljavljena ob naslednjem zagonu" + }, + "player": { + "title": "Video predvajalnik", + "section_selection": "IZBIRA PREDVAJALNIKA", + "internal_title": "Vgrajen predvajalnik", + "internal_desc": "Uporabi privzeti predvajalnik aplikacije", + "vlc_title": "VLC", + "vlc_desc": "Odpri v VLC medijskem predvajalniku", + "infuse_title": "Infuse", + "infuse_desc": "Odpri v Infuse predvajalniku", + "outplayer_title": "OutPlayer", + "outplayer_desc": "Odpri v OutPlayerju", + "vidhub_title": "VidHub", + "vidhub_desc": "Odpri v VidHub predvajalniku", + "infuse_live_title": "Infuse Livecontainer", + "infuse_live_desc": "Odpri v Infuse LiveContainerju", + "external_title": "Zunanji predvajalnik", + "external_desc": "Odpri v svojem najljubšem zunanjem predvajalniku", + "section_playback": "MOŽNOSTI PREDVAJANJA", + "skip_intro_settings_title": "Preskoči uvod", + "powered_by_introdb": "Poganja IntroDB", + "autoplay_title": "Samodejno predvajaj prvi vir", + "autoplay_desc": "Samodejno zaženi prvi vir s seznama.", + "resume_title": "Vedno nadaljuj", + "resume_desc": "Preskoči vprašanje o nadaljevanju in samodejno nadaljuj (če je ogledano manj kot 85 %).", + "engine_title": "Motor video predvajalnika", + "engine_desc": "Auto uporablja ExoPlayer z MPV rezervo. Nekateri formati, kot sta Dolby Vision in HDR, morda niso podprti v MPV.", + "decoder_title": "Način dekodiranja", + "decoder_desc": "Kako se video dekodira. Priporočeno: Auto.", + "gpu_title": "GPU upodabljanje", + "gpu_desc": "GPU-Next ponuja boljši HDR in upravljanje barv.", + "external_downloads_title": "Zunanji predvajalnik za prenose", + "external_downloads_desc": "Predvajaj preneseno vsebino v izbranem zunanjem predvajalniku.", + "restart_required": "Potreben ponovni zagon", + "restart_msg_decoder": "Ponovno zaženite aplikacijo, da sprememba dekodiranja stopi v veljavo.", + "restart_msg_gpu": "Ponovno zaženite aplikacijo, da sprememba GPU načina stopi v veljavo.", + "option_auto": "Samodejno", + "option_auto_desc_engine": "ExoPlayer + MPV rezerva", + "option_mpv": "MPV", + "option_mpv_desc": "Samo MPV", + "option_auto_desc_decoder": "Najboljše ravnovesje", + "option_sw": "SW", + "option_sw_desc": "Programsko (Software)", + "option_hw": "HW", + "option_hw_desc": "Strojno (Hardware)", + "option_hw_plus": "HW+", + "option_hw_plus_desc": "Polno strojno", + "option_gpu_desc": "Standardno", + "option_gpu_next_desc": "Napredno" + }, + "plugins": { + "title": "Vtičniki", + "enable_title": "Omogoči vtičnike", + "enable_desc": "Omogoči motor vtičnikov za razreševanje zunanjih medijskih virov", + "repo_config_title": "Konfiguracija repozitorija", + "repo_config_desc": "Upravljajte zunanje repozitorije vtičnikov.", + "your_repos": "Repozitoriji", + "your_repos_desc": "Konfigurirajte zunanje vire za vtičnike.", + "add_repo_button": "Dodaj repozitorij", + "refresh": "Osveži", + "remove": "Odstrani", + "enabled": "Omogočeno", + "disabled": "Onemogočeno", + "updating": "Posodabljanje...", + "success": "Uspešno", + "error": "Napaka", + "alert_repo_added": "Repozitorij dodan in vtičniki uspešno naloženi", + "alert_repo_saved": "URL repozitorija uspešno shranjen", + "alert_repo_refreshed": "Repozitorij uspešno osvežen", + "alert_invalid_url": "Neveljaven format URL-ja", + "alert_plugins_cleared": "Vsi vtičniki so bili odstranjeni", + "alert_cache_cleared": "Predpomnilnik repozitorija uspešno počiščen", + "unknown": "Neznano", + "active": "Aktivno", + "available": "Na voljo", + "platform_disabled": "Platforma onemogočena", + "limited": "Omejeno", + "clear_all": "Odstrani vse vtičnike", + "clear_all_desc": "Ali ste prepričani, da želite odstraniti vse nameščene vtičnike? Tega dejanja ni mogoče razveljaviti.", + "clear_cache": "Počisti predpomnilnik repozitorija", + "clear_cache_desc": "To bo odstranilo URL repozitorija in vse podatke. Ponovno boste morali vnesti URL.", + "add_new_repo": "Dodaj nov repozitorij", + "available_plugins": "Vtičniki na voljo ({{count}})", + "placeholder": "Išči vtičnike...", + "all": "Vsi", + "filter_all": "Vse vrste", + "filter_movies": "Filmi", + "filter_tv": "TV oddaje", + "enable_all": "Omogoči vse", + "disable_all": "Onemogoči vse", + "no_plugins_found": "Ni najdenih vtičnikov", + "no_plugins_available": "Ni razpoložljivih vtičnikov", + "no_match_desc": "Noben vtičnik ne ustreza iskanju \"{{query}}\".", + "configure_repo_desc": "Konfigurirajte repozitorij zgoraj za ogled vtičnikov.", + "clear_search": "Počisti iskanje", + "no_external_player": "Brez zunanjega predvajalnika", + "showbox_token": "ShowBox UI žeton", + "showbox_placeholder": "Prilepite svoj ShowBox UI žeton", + "save": "Shrani", + "clear": "Počisti", + "additional_settings": "Dodatne nastavitve", + "enable_url_validation": "Omogoči preverjanje URL-jev", + "url_validation_desc": "Preveri medijske URL-je pred prikazom (izboljša zanesljivost, a upočasni rezultate)", + "group_streams": "Združi vire vtičnikov", + "group_streams_desc": "Viri bodo združeni po repozitorijih.", + "sort_quality": "Najprej razvrsti po kakovosti", + "sort_quality_desc": "Viri bodo najprej razvrščeni po kakovosti (samo ob vklopljenem združevanju).", + "show_logos": "Prikaži logotipe vtičnikov", + "show_logos_desc": "Prikaži logotipe vtičnikov poleg povezav na zaslonu z viri.", + "quality_filtering": "Filtriranje kakovosti", + "quality_filtering_desc": "Tapnite na kakovost, da jo izključite iz rezultatov iskanja.", + "excluded_qualities": "Izključene kakovosti:", + "language_filtering": "Filtriranje jezikov", + "language_filtering_desc": "Izključite določene jezike iz rezultatov.", + "note": "Opomba:", + "language_filtering_note": "Ta filter velja le za ponudnike, ki posredujejo podatke o jeziku.", + "excluded_languages": "Izključeni jeziki:", + "about_title": "O vtičnikih", + "about_desc_1": "Vtičniki so modularne komponente, ki prilagajajo vsebino iz zunanjih protokolov. Tečejo lokalno na vaši napravi.", + "about_desc_2": "Vtičniki z oznako \"Omejeno\" lahko zahtevajo specifične zunanje konfiguracije.", + "help_title": "Nastavitev vtičnikov", + "help_step_1": "1. **Omogoči vtičnike** - Vklopite glavno stikalo", + "help_step_2": "2. **Dodaj repozitorij** - Dodajte veljaven URL repozitorija", + "help_step_3": "3. **Osveži repozitorij** - Pridobite seznam vtičnikov", + "help_step_4": "4. **Aktiviraj** - Omogočite želene vtičnike", + "got_it": "Razumem!", + "repo_format_hint": "Format: https://raw.githubusercontent.com/username/repo/refs/heads/branch", + "cancel": "Prekliči", + "add": "Dodaj" + }, + "theme": { + "title": "Teme aplikacije", + "select_theme": "IZBERI TEMO", + "create_custom": "Ustvari temo po meri", + "options": "MOŽNOSTI", + "use_dominant_color": "Uporabi prevladujočo barvo iz slike", + "categories": { + "all": "Vse teme", + "dark": "Temne teme", + "colorful": "Barvite", + "custom": "Moje teme" + }, + "editor": { + "theme_name_placeholder": "Ime teme", + "save": "Shrani", + "primary": "Primarna", + "secondary": "Sekundarna", + "background": "Ozadje", + "invalid_name_title": "Neveljavno ime", + "invalid_name_msg": "Vnesite veljavno ime teme" + }, + "alerts": { + "delete_title": "Izbriši temo", + "delete_msg": "Ali ste prepričani, da želite izbrisati temo \"{{name}}\"?", + "ok": "V redu", + "delete": "Izbriši", + "cancel": "Prekliči", + "back": "Nastavitve" + } + }, + "legal": { + "title": "Pravne informacije", + "intro_title": "Narava aplikacije", + "intro_text": "Nuvio je predvajalnik medijev in upravitelj metapodatkov. Deluje izključno kot vmesnik na strani odjemalca za brskanje po javno dostopnih podatkih. Nuvio sam ne gosti, ne shranjuje in ne distribuira nobene vsebine.", + "extensions_title": "Vtičniki tretjih oseb", + "extensions_text": "Nuvio omogoča namestitev vtičnikov tretjih oseb, ki jih vzdržujejo neodvisni razvijalci. Nimamo nadzora nad njihovo zakonitostjo ali vsebino.", + "user_resp_title": "Odgovornost uporabnika", + "user_resp_text": "Uporabniki so sami odgovorni za vtičnike, ki jih namestijo. Z uporabo se strinjate, da imate pravico do dostopa do vsebine, ki jo gledate.", + "dmca_title": "Avtorske pravice in DMCA", + "dmca_text": "Spoštujemo intelektualno lastnino. Ker Nuvio ne gosti vsebine, je ne moremo odstraniti z interneta. Če menite, da vmesnik sam krši vaše pravice, nas kontaktirajte.", + "warranty_title": "Brez garancije", + "warranty_text": "Programska oprema je na voljo \"takšna, kot je\", brez kakršne koli garancije." + }, + "plugin_tester": { + "title": "Tester vtičnikov", + "subtitle": "Zaženite scraperje in spremljajte dnevnike v realnem času", + "tabs": { + "individual": "Posamično", + "repo": "Tester repozitorija", + "code": "Koda", + "logs": "Dnevniki", + "results": "Rezultati" + }, + "common": { + "error": "Napaka", + "success": "Uspešno", + "movie": "Film", + "tv": "TV", + "tmdb_id": "TMDB ID", + "season": "Sezona", + "episode": "Epizoda", + "running": "Teče...", + "run_test": "Zaženi test", + "play": "Predvajaj", + "done": "Končano", + "test": "Test", + "testing": "Testiranje..." + }, + "individual": { + "load_from_url": "Naloži iz URL-ja", + "load_from_url_desc": "Prilepite GitHub URL ali lokalni IP.", + "enter_url_error": "Vnesite URL", + "code_loaded": "Koda naložena iz URL-ja", + "fetch_error": "Napaka pri pridobivanju: {{message}}", + "no_code_error": "Ni kode za zagon", + "plugin_code": "Koda vtičnika", + "focus_editor": "Fokus na urejevalnik", + "code_placeholder": "// Tukaj prilepite kodo vtičnika...", + "test_parameters": "Testni parametri", + "no_logs": "Ni dnevnikov. Zaženite test za izpis.", + "no_streams": "Ni najdenih tokov.", + "streams_found": "Najden {{count}} tok", + "streams_found_plural": "Najdenih {{count}} tokov", + "tap_play_hint": "Tapnite Predvajaj za testiranje toka v predvajalniku.", + "unnamed_stream": "Neimenovan tok", + "quality": "Kakovost: {{quality}}", + "size": "Velikost: {{size}}", + "url_label": "URL: {{url}}", + "headers_info": "Glave: {{count}} po meri", + "find_placeholder": "Najdi v kodi...", + "edit_code_title": "Uredi kodo", + "no_url_stream_error": "Za ta tok ni bil najden noben URL" + }, + "repo": { + "title": "Tester repozitorija", + "description": "Pridobite repozitorij in testirajte vsakega ponudnika.", + "enter_repo_url_error": "Vnesite URL repozitorija", + "invalid_url_title": "Neveljaven URL", + "invalid_url_msg": "Uporabite GitHub raw URL ali lokalni http(s) URL.", + "manifest_build_error": "Ni bilo mogoče zgraditi URL-ja manifesta.", + "manifest_fetch_error": "Napaka pri pridobivanju manifesta.", + "repo_manifest_fetch_error": "Napaka pri pridobivanju manifesta repozitorija.", + "missing_filename": "V manifestu manjka ime datoteke.", + "scraper_build_error": "Ni bilo mogoče zgraditi URL-ja scraperja.", + "download_scraper_error": "Napaka pri prenosu scraperja.", + "test_failed": "Test ni uspel", + "test_parameters": "Parametri testa repozitorija", + "test_parameters_desc": "Uporabljeno samo za Tester repozitorija.", + "using_info": "Uporaba: {{mediaType}} • TMDB {{tmdbId}}", + "using_info_tv": "Uporaba: {{mediaType}} • TMDB {{tmdbId}} • S{{season}}E{{episode}}", + "providers_title": "Ponudniki", + "repository_default": "Repozitorij", + "providers_count": "{{count}} ponudnikov", + "fetch_hint": "Pridobite repozitorij za seznam ponudnikov.", + "test_all": "Testiraj vse", + "status_running": "TEČE", + "status_ok": "V REDU ({{count}})", + "status_ok_empty": "V REDU (0)", + "status_failed": "NAPAKA", + "status_idle": "MIROVANJE", + "tried_url": "Poskus: {{url}}", + "provider_logs": "Dnevniki ponudnika", + "no_logs_captured": "Ni zajetih dnevnikov." + } + } +} \ No newline at end of file diff --git a/src/i18n/locales/sq.json b/src/i18n/locales/sq.json new file mode 100644 index 00000000..8606830e --- /dev/null +++ b/src/i18n/locales/sq.json @@ -0,0 +1,1430 @@ +{ + "common": { + "loading": "Duke u ngarkuar...", + "cancel": "Anulo", + "save": "Ruaj", + "delete": "Fshi", + "edit": "Redakto", + "search": "Kërko", + "error": "Gabim", + "success": "Sukses", + "ok": "OK", + "unknown": "I panjohur", + "retry": "Riprovo", + "try_again": "Provo përsëri", + "go_back": "Kthehu pas", + "settings": "Cilësimet", + "close": "Mbyll", + "enable": "Aktivizo", + "disable": "Çaktivizo", + "show_more": "Shfaq më shumë", + "show_less": "Shfaq më pak", + "load_more": "Ngarko më shumë", + "unknown_date": "Datë e panjohur", + "anonymous_user": "Përdorues Anonim", + "time": { + "now": "Tani", + "minutes_ago": "{{count}}m më parë", + "hours_ago": "{{count}}h më parë", + "days_ago": "{{count}}d më parë" + }, + "days_short": { + "sun": "Die", + "mon": "Hën", + "tue": "Mar", + "wed": "Mër", + "thu": "Enj", + "fri": "Pre", + "sat": "Sht" + }, + "email": "Email", + "status": "Statusi" + }, + "home": { + "categories": { + "movies": "Filma", + "series": "Seriale", + "channels": "Kanale" + }, + "movies": "Filma", + "tv_shows": "Emisione TV", + "load_more_catalogs": "Ngarko më shumë katalogë", + "no_content": "Asnjë përmbajtje e disponueshme", + "add_catalogs": "Shto Katalogë", + "sign_in_available": "Hyrja e disponueshme", + "sign_in_desc": "Mund të hyni në çdo kohë nga Cilësimet → Llogaria", + "view_all": "Shiko të gjitha", + "this_week": "Këtë javë", + "upcoming": "Së shpejti", + "recently_released": "Publikuar së fundmi", + "no_scheduled_episodes": "Seriale pa episode të planifikuara", + "check_back_later": "Kontrollo përsëri më vonë", + "continue_watching": "Vazhdo shikimin", + "up_next": "Radha e", + "up_next_caps": "RADHA E", + "released": "Publikuar", + "new": "I ri", + "tba": "Do të njoftohet", + "new_episodes": "{{count}} Episode të reja", + "season_short": "S{{season}}", + "episode_short": "E{{episode}}", + "season": "Sezoni {{season}}", + "episode": "Episodi {{episode}}", + "movie": "Film", + "series": "Serial", + "tv_show": "Emision TV", + "percent_watched": "{{percent}}% e shikuar", + "view_details": "Shiko detajet", + "remove": "Hiq", + "play": "Luaj", + "play_now": "Luaj tani", + "resume": "Vazhdo", + "info": "Informacion", + "more_info": "Më shumë info", + "my_list": "Lista ime", + "save": "Ruaj", + "saved": "Ruajtur", + "retry": "Riprovo", + "install_addons": "Instalo Shtojcat", + "settings": "Cilësimet", + "no_featured_content": "Asnjë përmbajtje e veçuar", + "couldnt_load_featured": "Nuk u mundësua ngarkimi i përmbajtjes së veçuar", + "no_featured_desc": "Instaloni shtojca me katalogë ose ndryshoni burimin e përmbajtjes në cilësimet tuaja.", + "load_error_desc": "Pati një problem gjatë marrjes së përmbajtjes. Ju lutem kontrolloni lidhjen tuaj dhe provoni përsëri.", + "no_featured_available": "Asnjë përmbajtje e veçuar e disponueshme", + "no_description": "Asnjë përshkrim i disponueshëm" + }, + "navigation": { + "home": "Kreu", + "library": "Biblioteka", + "search": "Kërko", + "downloads": "Shkarkimet", + "settings": "Cilësimet" + }, + "search": { + "title": "Kërko", + "recent_searches": "Kërkimet e fundit", + "discover": "Zbulo", + "movies": "Filma", + "tv_shows": "Emisione TV", + "select_catalog": "Zgjidh Katalogun", + "all_genres": "Të gjitha Zhanret", + "discovering": "Duke zbuluar përmbajtje...", + "show_more": "Shfaq më shumë ({{count}})", + "no_content_found": "Nuk u gjet asnjë përmbajtje", + "try_different": "Provoni një zhanër ose katalog tjetër", + "select_catalog_desc": "Zgjidhni një katalog për të zbuluar", + "tap_catalog_desc": "Prekni skedën e katalogut më lart për të filluar", + "placeholder": "Kërko filma, emisione...", + "keep_typing": "Vazhdo të shkruash...", + "type_characters": "Shkruani të paktën 2 karaktere për të kërkuar", + "no_results": "Asnjë rezultat nuk u gjet", + "try_keywords": "Provoni fjalë kyçe të tjera ose kontrolloni drejtshkrimin", + "select_type": "Zgjidh Llojin", + "browse_movies": "Shfleto katalogët e filmave", + "browse_tv": "Shfleto katalogët e serialeve TV", + "select_genre": "Zgjidh Zhanrin", + "show_all_content": "Shfaq të gjithë përmbajtjen", + "genres_count": "{{count}} zhanre" + }, + "library": { + "title": "Biblioteka", + "watched": "Të shikuara", + "continue": "Vazhdo", + "watchlist": "Lista e shikimit", + "collection": "Koleksioni", + "rated": "Të vlerësuara", + "items": "artikuj", + "trakt_collections": "Koleksionet Trakt", + "trakt_collection": "Koleksion Trakt", + "no_trakt": "Asnjë koleksion Trakt", + "no_trakt_desc": "Koleksionet tuaja Trakt do të shfaqen këtu pasi të filloni të përdorni Trakt", + "load_collections": "Ngarko Koleksionet", + "empty_folder": "Asnjë përmbajtje në {{folder}}", + "empty_folder_desc": "Ky koleksion është i zbrazët", + "refresh": "Rifresko", + "no_movies": "Ende asnjë film", + "no_series": "Ende asnjë emision TV", + "no_content": "Ende asnjë përmbajtje", + "add_content_desc": "Shto përmbajtje në bibliotekën tënde për ta parë këtu", + "find_something": "Gjej diçka për të parë", + "removed_from_library": "U hoq nga Biblioteka", + "item_removed": "Artikulli u hoq nga biblioteka juaj", + "failed_update_library": "Përditësimi i Bibliotekës dështoi", + "unable_remove": "Nuk mund të hiqet artikulli nga biblioteka", + "marked_watched": "U shënua si i shikuar", + "marked_unwatched": "U shënua si i pashikuar", + "item_marked_watched": "Artikulli u shënua si i shikuar", + "item_marked_unwatched": "Artikulli u shënua si i pashikuar", + "failed_update_watched": "Dështoi përditësimi i statusit të shikimit", + "unable_update_watched": "Nuk mund të përditësohet statusi i shikimit", + "added_to_library": "U shtua në Bibliotekë", + "item_added": "U shtua në bibliotekën tuaj lokale", + "add_to_library": "Shto në Bibliotekë", + "remove_from_library": "Hiq nga Biblioteka", + "mark_watched": "Shëno si i shikuar", + "mark_unwatched": "Shëno si i pashikuar", + "share": "Shpërndaj", + "add_to_watchlist": "Shto në Trakt Watchlist", + "remove_from_watchlist": "Hiq nga Trakt Watchlist", + "added_to_watchlist": "U shtua në Listën e Shikimit", + "added_to_watchlist_desc": "U shtua në listën tuaj të shikimit në Trakt", + "removed_from_watchlist": "U hoq nga Lista e Shikimit", + "removed_from_watchlist_desc": "U hoq nga lista juaj e shikimit në Trakt", + "add_to_collection": "Shto në Koleksionin Trakt", + "remove_from_collection": "Hiq nga Koleksioni Trakt", + "added_to_collection": "U shtua në Koleksion", + "added_to_collection_desc": "U shtua në koleksionin tuaj në Trakt", + "removed_from_collection": "U hoq nga Koleksioni", + "removed_from_collection_desc": "U hoq nga koleksioni tuaj në Trakt" + }, + "metadata": { + "unable_to_load": "Nuk mund të ngarkohet përmbajtja", + "error_code": "Kodi i gabimit: {{code}}", + "content_not_found": "Përmbajtja nuk u gjet", + "content_not_found_desc": "Kjo përmbajtje nuk ekziston ose mund të jetë hequr.", + "server_error": "Gabim serveri", + "server_error_desc": "Serveri është përkohësisht i padisponueshëm. Ju lutem provoni përsëri më vonë.", + "bad_gateway": "Portë e gabuar", + "bad_gateway_desc": "Serveri po përjeton probleme. Ju lutem provoni përsëri më vonë.", + "service_unavailable": "Shërbimi i padisponueshëm", + "service_unavailable_desc": "Shërbimi është aktualisht jashtë funksionit për mirëmbajtje.", + "too_many_requests": "Shumë kërkesa", + "too_many_requests_desc": "Po bëni shumë kërkesa. Ju lutem prisni një moment dhe provoni përsëri.", + "request_timeout": "Kërkesës i kaloi koha", + "request_timeout_desc": "Kërkesa zgjati shumë. Ju lutem provoni përsëri.", + "network_error": "Gabim rrjeti", + "network_error_desc": "Ju lutem kontrolloni lidhjen tuaj të internetit dhe provoni përsëri.", + "auth_error": "Gabim autentikimi", + "auth_error_desc": "Ju lutem kontrolloni cilësimet e llogarisë suaj.", + "access_denied": "Akses i mohuar", + "access_denied_desc": "Nuk keni leje për të aksesuar këtë përmbajtje.", + "connection_error": "Gabim lidhjeje", + "streams_unavailable": "Burimet nuk gjenden", + "streams_unavailable_desc": "Burimet e transmetimit janë aktualisht të padisponueshme.", + "unknown_error": "Gabim i panjohur", + "something_went_wrong": "Diçka shkoi keq. Ju lutem provoni përsëri.", + "cast": "Aktorët", + "more_like_this": "Më shumë si kjo", + "collection": "Koleksioni", + "episodes": "Episode", + "seasons": "Sezone", + "posters": "Postera", + "banners": "Bannera", + "specials": "Speciale", + "season_number": "Sezoni {{number}}", + "episode_count": "{{count}} Episod", + "episode_count_plural": "{{count}} Episode", + "no_episodes": "Asnjë episod i disponueshëm", + "no_episodes_for_season": "Asnjë episod i disponueshëm për Sezonin {{season}}", + "episodes_not_released": "Episodet mund të mos jenë publikuar ende", + "no_description": "Asnjë përshkrim i disponueshëm", + "episode_label": "EPISODI {{number}}", + "watch_again": "Shiko përsëri", + "completed": "Përfunduar", + "play_episode": "Luaj S{{season}}E{{episode}}", + "play": "Luaj", + "watched": "E shikuar", + "watched_on_trakt": "E shikuar në Trakt", + "synced_with_trakt": "Sinkronizuar me Trakt", + "saved": "Ruajtur", + "director": "Regjisori", + "directors": "Regjisorët", + "creator": "Krijuesi", + "creators": "Krijuesit", + "production": "Produksioni", + "network": "Rrjeti", + "mark_watched": "Shëno si i shikuar", + "mark_unwatched": "Shëno si i pashikuar", + "marking": "Duke shënuar...", + "removing": "Duke hequr...", + "unmark_season": "Hiq shënimin për Sezonin {{season}}", + "mark_season": "Shëno Sezonin {{season}}", + "resume": "Vazhdo", + "spoiler_warning": "Paralajmërim Spoiler", + "spoiler_warning_desc": "Ky koment përmban spoiler. Jeni të sigurt që dëshironi ta shfaqni?", + "cancel": "Anulo", + "reveal_spoilers": "Shfaq Spoiler-at", + "movie_details": "Detajet e Filmit", + "show_details": "Detajet e Serialit", + "tagline": "Slogani", + "status": "Statusi", + "release_date": "Data e Publikimit", + "runtime": "Kohëzgjatja", + "budget": "Buxheti", + "revenue": "Të ardhurat", + "origin_country": "Vendi i origjinës", + "original_language": "Gjuha origjinale", + "first_air_date": "Data e parë e transmetimit", + "last_air_date": "Data e fundit e transmetimit", + "total_episodes": "Gjithsej Episode", + "episode_runtime": "Kohëzgjatja e episodit", + "created_by": "Krijuar nga", + "backdrop_gallery": "Galeria e sfondeve", + "loading_episodes": "Duke ngarkuar episodet...", + "no_episodes_available": "Asnjë episod i disponueshëm", + "play_next": "Luaj S{{season}}E{{episode}}", + "play_next_episode": "Luaj Episodin e Radhës", + "save": "Ruaj", + "percent_watched": "{{percent}}% e shikuar", + "percent_watched_trakt": "{{percent}}% e shikuar ({{traktPercent}}% në Trakt)", + "synced_with_trakt_progress": "Sinkronizuar me Trakt", + "using_trakt_progress": "Duke përdorur progresin e Trakt", + "added_to_collection_hero": "Shtuar në Koleksion", + "added_to_collection_desc_hero": "Shtuar në koleksionin tuaj në Trakt", + "removed_from_collection_hero": "Hequr nga Koleksioni", + "removed_from_collection_desc_hero": "Hequr nga koleksioni tuaj në Trakt", + "mark_as_watched": "Shëno si i shikuar", + "mark_as_unwatched": "Shëno si i pashikuar" + }, + "cast": { + "biography": "Biografia", + "known_for": "I njohur për", + "personal_info": "Info Personale", + "born_in": "Lindur në {{place}}", + "filmography": "Filmografia", + "also_known_as": "I njohur edhe si", + "no_info_available": "Asnjë informacion shtesë i disponueshëm", + "as_character": "si {{character}}", + "loading_details": "Duke ngarkuar detajet...", + "years_old": "{{age}} vjeç", + "view_filmography": "Shiko Filmografinë", + "filter": "Filtro", + "sort_by": "Rendit sipas", + "sort_popular": "Popullore", + "sort_latest": "Të fundit", + "sort_upcoming": "Së shpejti", + "upcoming_badge": "SË SHPEJTI", + "coming_soon": "Vjen së shpejti", + "filmography_count": "Filmografia • {{count}} tituj", + "loading_filmography": "Duke ngarkuar filmografinë...", + "load_more_remaining": "Ngarko më shumë (edhe {{count}})", + "alert_error_title": "Gabim", + "alert_error_message": "Nuk mund të ngarkohej \"{{title}}\". Ju lutem provoni përsëri më vonë.", + "alert_ok": "OK", + "no_upcoming": "Asnjë publikim i ardhshëm për këtë aktor", + "no_content": "Asnjë përmbajtje e disponueshme për këtë aktor", + "no_movies": "Asnjë film i disponueshëm për këtë aktor", + "no_tv": "Asnjë emision TV për këtë aktor" + }, + "comments": { + "title": "Komentet në Trakt", + "spoiler_warning": "⚠️ Ky koment përmban spoiler. Prekni për ta shfaqur.", + "spoiler": "Spoiler", + "contains_spoilers": "Përmban spoiler", + "reveal": "Shfaq", + "vip": "VIP", + "unavailable": "Komentet nuk disponohen", + "no_comments": "Ende asnjë koment në Trakt", + "not_in_database": "Kjo përmbajtje mund të mos jetë ende në bazën e të dhënave të Trakt", + "check_trakt": "Kontrollo në Trakt" + }, + "trailers": { + "title": "Trailer-at", + "official_trailers": "Trailer-at Zyrtarë", + "official_trailer": "Trailer-i Zyrtar", + "teasers": "Teaser-at", + "teaser": "Teaser", + "clips_scenes": "Klip-e & Skena", + "clip": "Klip", + "featurettes": "Featurettes", + "featurette": "Featurette", + "behind_the_scenes": "Prapaskenat", + "no_trailers": "Asnjë trailer i disponueshëm", + "unavailable": "Trailer-i i padisponueshëm", + "unavailable_desc": "Ky trailer nuk mund të ngarkohej tani. Ju lutem provoni përsëri më vonë.", + "unable_to_play": "Nuk mund të luhet trailer-i. Ju lutem provoni përsëri.", + "watch_on_youtube": "Shiko në YouTube" + }, + "catalog": { + "no_content_found": "Nuk u gjet asnjë përmbajtje", + "no_content_filters": "Nuk u gjet asnjë përmbajtje për filtrat e zgjedhur", + "loading_content": "Duke ngarkuar përmbajtjen...", + "back": "Pas", + "in_theaters": "Në Kinema", + "all": "Të gjitha", + "failed_tmdb": "Dështoi ngarkimi i përmbajtjes nga TMDB", + "movies": "Filma", + "tv_shows": "Emisione TV", + "channels": "Kanale" + }, + "streams": { + "back_to_episodes": "Kthehu tek Episodet", + "back_to_info": "Kthehu tek Info", + "fetching_from": "Duke marrë nga:", + "no_sources_available": "Asnjë burim transmetimi i disponueshëm", + "add_sources_desc": "Ju lutem shtoni burime transmetimi në cilësime", + "add_sources": "Shto Burime", + "finding_streams": "Duke kërkuar burime...", + "finding_best_stream": "Duke kërkuar burimin më të mirë...", + "still_fetching": "Ende duke kërkuar burime…", + "no_streams_available": "Asnjë burim i disponueshëm", + "starting_best_stream": "Duke nisur burimin më të mirë...", + "loading_more_sources": "Duke ngarkuar më shumë burime..." + }, + "player_ui": { + "via": "përmes {{name}}", + "audio_tracks": "Gjurmët Audio", + "no_audio_tracks": "Asnjë gjurmë audio e disponueshme", + "playback_speed": "Shpejtësia e Riprodhimit", + "on_hold": "Në pritje", + "playback_error": "Gabim gjatë riprodhimit", + "unknown_error": "Ndodhi një gabim i panjohur gjatë riprodhimit.", + "copy_error": "Kopjo detajet e gabimit", + "copied_to_clipboard": "U kopjua në clipboard", + "dismiss": "Largo", + "continue_watching": "Vazhdo shikimin", + "start_over": "Fillo nga fillimi", + "resume": "Vazhdo", + "change_source": "Ndrysho Burimin", + "switching_source": "Duke ndërruar burimin...", + "no_sources_found": "Nuk u gjet asnjë burim", + "sources": "Burimet", + "finding_sources": "Duke kërkuar burime...", + "unknown_source": "Burim i panjohur", + "sources_limited": "Burimet mund të jenë të kufizuara për shkak të gabimeve të ofruesit.", + "episodes": "Episode", + "specials": "Speciale", + "season": "Sezoni {{season}}", + "stream": "Burimi {{number}}", + "subtitles": "Titrat", + "built_in": "Të integruara", + "addons": "Shtojcat", + "style": "Stili", + "none": "Asnjë", + "search_online_subtitles": "Kërko Titra Online", + "preview": "Parashikim", + "quick_presets": "Paracaktimet e Shpejta", + "default": "Paracaktuar", + "yellow": "E verdhë", + "high_contrast": "Kontrast i lartë", + "large": "Të mëdha", + "core": "Bazë", + "font_size": "Madhësia e shkrimit", + "show_background": "Shfaq sfondin", + "advanced": "Të avancuara", + "position": "Pozicioni", + "text_color": "Ngjyra e tekstit", + "align": "Rreshtimi", + "bottom_offset": "Largësia nga fundi", + "background_opacity": "Opaciteti i sfondit", + "text_shadow": "Hija e tekstit", + "on": "Aktiv", + "off": "Joaktiv", + "outline_color": "Ngjyra e konturit", + "outline": "Konturi", + "outline_width": "Trashësia e konturit", + "letter_spacing": "Hapësira midis shkronjave", + "line_height": "Lartësia e rreshtit", + "timing_offset": "Vonesa e kohës (s)", + "visual_sync": "Sinkronizim vizual", + "timing_hint": "Lëvizni titrat më herët (-) ose më vonë (+) për sinkronizim.", + "reset_defaults": "Rikthe vlerat fillestare", + "mark_intro_start": "Shëno fillimin e hyrjes", + "mark_intro_end": "Shëno fundin e hyrjes", + "intro_start_marked": "Fillimi i hyrjes u shënua", + "intro_submitted": "Hyrja u dërgua me sukses", + "intro_submit_failed": "Dështoi dërgimi i hyrjes" + }, + "downloads": { + "title": "Shkarkimet", + "no_downloads": "Ende asnjë shkarkim", + "no_downloads_desc": "Përmbajtja e shkarkuar do të shfaqet këtu për shikim offline", + "explore": "Eksploro Përmbajtjen", + "path_copied": "Shtegu u kopjua", + "path_copied_desc": "Shtegu i skedarit lokal u kopjua", + "copied": "U kopjua", + "incomplete": "Shkarkim i papërfunduar", + "incomplete_desc": "Shkarkimi nuk ka përfunduar ende", + "not_available": "Nuk disponohet", + "not_available_desc": "Shtegu lokal është i disponueshëm vetëm pas përfundimit të shkarkimit.", + "status_downloading": "Duke u shkarkuar", + "status_completed": "Përfunduar", + "status_paused": "Në pauzë", + "status_error": "Gabim", + "status_queued": "Në pritje", + "status_unknown": "I panjohur", + "provider": "Ofruesi", + "streaming_playlist_warning": "Mund të mos luhet - listë transmetimi", + "remaining": "mbetur", + "not_ready": "Shkarkimi nuk është gati", + "not_ready_desc": "Ju lutem prisni deri sa të përfundojë shkarkimi.", + "filter_all": "Të gjitha", + "filter_active": "Aktive", + "filter_done": "Të kryera", + "filter_paused": "Në pauzë", + "no_filter_results": "Asnjë shkarkim {{filter}}", + "try_different_filter": "Provoni të zgjidhni një filtër tjetër", + "limitations_title": "Kufizimet e shkarkimit", + "limitations_msg": "• Skedarët më të vegjël se 1MB janë zakonisht lista transmetimi M3U8 dhe nuk mund të shkarkohen për shikim offline.", + "remove_title": "Hiq Shkarkimin", + "remove_confirm": "Dëshironi të hiqni \"{{title}}\"{{season_episode}}?", + "cancel": "Anulo", + "remove": "Hiq" + }, + "addons": { + "title": "Shtojcat", + "reorder_mode": "Mënyra e rirenditjes", + "reorder_info": "Shtojcat në krye kanë prioritet më të lartë gjatë ngarkimit", + "add_addon_placeholder": "URL e shtojcës", + "add_button": "Shto Shtojcë", + "my_addons": "Shtojcat e Mia", + "community_addons": "Shtojcat e Komunitetit", + "no_addons": "Asnjë shtojcë e instaluar", + "uninstall_title": "Çinstalo Shtojcën", + "uninstall_message": "Jeni të sigurt që dëshironi të çinstaloni {{name}}?", + "uninstall_button": "Çinstalo", + "install_success": "Shtojca u instalua me sukses", + "install_error": "Dështoi instalimi i shtojcës", + "load_error": "Dështoi ngarkimi i shtojcave", + "fetch_error": "Dështoi marrja e detajeve të shtojcës", + "invalid_url": "Ju lutem jepni një URL të vlefshme", + "configure": "Konfiguro", + "version": "Versioni: {{version}}", + "installed_addons": "SHTOJCAT E INSTALUARA", + "reorder_drag_title": "TËRHIQ SHTOJCAT PËR RIRENDITJE", + "install": "Instalo", + "config_unavailable_title": "Konfigurimi nuk disponohet", + "config_unavailable_msg": "Nuk u gjet URL-ja e konfigurimit për këtë shtojcë.", + "cannot_open_config_title": "Nuk mund të hapet konfigurimi", + "cannot_open_config_msg": "URL-ja e konfigurimit ({{url}}) nuk mund të hapet.", + "description": "Përshkrimi", + "supported_types": "Llojet e mbështetura", + "catalogs": "Katalogët", + "no_description": "Asnjë përshkrim i disponueshëm", + "overview": "PËRMBLEDHJE", + "no_categories": "Asnjë kategori", + "pre_installed": "TË PARA-INSTALUARA" + }, + "trakt": { + "title": "Cilësimet e Trakt", + "settings_title": "Cilësimet e Trakt", + "connect_title": "Lidhu me Trakt", + "connect_desc": "Sinkronizo historinë, listën e shikimit dhe koleksionin me Trakt.tv", + "sign_in": "Hyr me Trakt", + "sign_out": "Dil", + "sign_out_confirm": "Jeni të sigurt që dëshironi të dilni nga llogaria Trakt?", + "joined": "Anëtarësuar më {{date}}", + "sync_settings_title": "Cilësimet e Sinkronizimit", + "sync_info": "Kur lidheni me Trakt, historia sinkronizohet direkt nga API.", + "auto_sync_label": "Sinkronizim automatik i progresit", + "auto_sync_desc": "Sinkronizo progresin automatikisht në Trakt", + "import_history_label": "Importo historinë", + "import_history_desc": "Përdorni \"Sinkronizo Tani\" për të importuar historinë nga Trakt", + "sync_now_button": "Sinkronizo Tani", + "display_settings_title": "Cilësimet e Shfaqjes", + "show_comments_label": "Shfaq Komentet e Trakt", + "show_comments_desc": "Shfaq komentet në ekranet e informacionit", + "maintenance_title": "Në Mirëmbajtje", + "maintenance_unavailable": "Trakt i padisponueshëm", + "maintenance_desc": "Integrimi me Trakt është ndalur përkohësisht për mirëmbajtje.", + "maintenance_button": "Shërbimi në Mirëmbajtje", + "auth_success_title": "U lidh me sukses", + "auth_success_msg": "Llogaria juaj Trakt u lidh me sukses.", + "auth_error_title": "Gabim Autentikimi", + "auth_error_msg": "Dështoi autentikimi me Trakt.", + "auth_error_generic": "Ndodhi një gabim gjatë autentikimit.", + "sign_out_error": "Dështoi dalja nga Trakt.", + "sync_complete_title": "Sinkronizimi u krye", + "sync_success_msg": "Progresi u sinkronizua me sukses me Trakt.", + "sync_error_msg": "Sinkronizimi dështoi. Ju lutem provoni përsëri." + }, + "simkl": { + "title": "Cilësimet e Simkl", + "settings_title": "Cilësimet e Simkl", + "connect_title": "Lidhu me Simkl", + "connect_desc": "Sinkronizo historinë dhe ndiq atë që po shikon", + "sign_in": "Hyr me Simkl", + "sign_out": "Shkëputu", + "sign_out_confirm": "Jeni të sigurt që dëshironi të shkëputeni nga Simkl?", + "syncing_desc": "Artikujt tuaj po sinkronizohen me Simkl.", + "auth_success_title": "U lidh me sukses", + "auth_success_msg": "Llogaria juaj Simkl u lidh me sukses.", + "auth_error_title": "Gabim Autentikimi", + "auth_error_msg": "Dështoi autentikimi me Simkl.", + "auth_error_generic": "Ndodhi një gabim gjatë autentikimit.", + "sign_out_error": "Dështoi shkëputja nga Simkl.", + "config_error_title": "Gabim Konfigurimi", + "config_error_msg": "Client ID i Simkl mungon.", + "conflict_title": "Konflikt", + "conflict_msg": "Nuk mund të lidheni me Simkl ndërkohë që Trakt është i lidhur. Ju lutem shkëputni Trakt më parë.", + "disclaimer": "Nuvio nuk është i lidhur me Simkl." + }, + "tmdb_settings": { + "title": "Cilësimet e TMDb", + "metadata_enrichment": "Pasurimi i Metadhenave", + "metadata_enrichment_desc": "Përmirësoni detajet e përmbajtjes me të dhëna nga TMDb.", + "enable_enrichment": "Aktivizo Pasurimin", + "enable_enrichment_desc": "Shton aktorët, certifikimet dhe logot nga TMDb.", + "localized_text": "Tekst i Lokalizuar", + "localized_text_desc": "Merr titujt dhe përshkrimet në gjuhën tënde të preferuar.", + "language": "Gjuha", + "change": "Ndrysho", + "logo_preview": "Parashikimi i Logos", + "logo_preview_desc": "Tregon se si do të duken logot në gjuhën e zgjedhur.", + "example": "Shembull:", + "no_logo": "Asnjë logo e disponueshme", + "enrichment_options": "Opsionet e Pasurimit", + "enrichment_options_desc": "Kontrollo cilat të dhëna merren nga TMDb.", + "cast_crew": "Aktorët & Ekipi", + "cast_crew_desc": "Aktorët, regjisorët, skenaristët me foto", + "title_description": "Titulli & Përshkrimi", + "title_description_desc": "Përdor titullin dhe përshkrimin e lokalizuar të TMDb", + "title_logos": "Logot e Titullit", + "title_logos_desc": "Imazhe të cilësisë së lartë për titujt", + "banners_backdrops": "Bannera & Sfonde", + "banners_backdrops_desc": "Imazhe sfondi me rezolucion të lartë", + "certification": "Certifikimi i Përmbajtjes", + "certification_desc": "Vlerësimet e moshës (PG-13, R, etj.)", + "recommendations": "Rekomandime", + "recommendations_desc": "Sugjerime për përmbajtje të ngjashme", + "episode_data": "Të dhënat e Episodit", + "episode_data_desc": "Imazhet dhe info e episodeve për serialet", + "season_posters": "Posterat e Sezonit", + "season_posters_desc": "Imazhe posterash për çdo sezon", + "production_info": "Info e Produksionit", + "production_info_desc": "Rrjetet dhe kompanitë e produksionit", + "movie_details": "Detajet e Filmit", + "movie_details_desc": "Buxheti, të ardhurat, kohëzgjatja", + "tv_details": "Detajet e Serialit", + "tv_details_desc": "Statusi, numri i sezoneve, krijuesit", + "movie_collections": "Koleksionet e Filmave", + "movie_collections_desc": "Filmat e sagave (Marvel, Star Wars, etj.)", + "api_configuration": "Konfigurimi i API", + "api_configuration_desc": "Konfiguro aksesin tuaj në TMDb API.", + "custom_api_key": "Çelës API Personal", + "custom_api_key_desc": "Përdor çelësin tënd për performancë më të mirë.", + "custom_key_active": "Çelësi API personal është aktiv", + "api_key_required": "Kërkohet çelësi API", + "api_key_placeholder": "Ngjit çelësin tënd TMDb API (v3)", + "how_to_get_key": "Si të marr një çelës TMDb API?", + "built_in_key_msg": "Aktualisht po përdoret çelësi i integruar.", + "cache_size": "Madhësia e Cache", + "clear_cache": "Pastro Cache", + "cache_days": "Përgjigjet e TMDB ruhen për 7 ditë.", + "choose_language": "Zgjidh Gjuhën", + "choose_language_desc": "Zgjidh gjuhën tënde për përmbajtjen e TMDb", + "popular": "Popullore", + "all_languages": "Të gjitha gjuhët", + "search_results": "Rezultatet e kërkimit", + "no_languages_found": "Nuk u gjet asnjë gjuhë për \"{{query}}\"", + "clear_search": "Pastro kërkimin", + "clear_cache_title": "Pastro Cache-in e TMDB", + "clear_cache_msg": "Kjo do të fshijë të gjitha të dhënat e ruajtura ({{size}}).", + "clear_cache_success": "Cache-i i TMDB u pastrua me sukses.", + "clear_cache_error": "Dështoi pastrimi i cache-it.", + "clear_api_key_title": "Fshi Çelësin API", + "clear_api_key_msg": "Jeni të sigurt që dëshironi të hiqni çelësin tuaj personal?", + "clear_api_key_success": "Çelësi API u fshi me sukses", + "clear_api_key_error": "Dështoi fshirja e çelësit API", + "empty_api_key": "Çelësi API nuk mund të jetë i zbrazët.", + "invalid_api_key": "Çelës API i pavlefshëm.", + "save_error": "Ndodhi një gabim gjatë ruajtjes.", + "using_builtin_key": "Tani po përdorni çelësin e integruar të TMDb.", + "using_custom_key": "Tani po përdorni çelësin tuaj personal TMDb.", + "enter_custom_key": "Ju lutem jepni dhe ruani çelësin tuaj personal.", + "key_verified": "Çelësi API u verifikua dhe u ruajt me sukses." + }, + "settings": { + "language": "Gjuha", + "select_language": "Zgjidh Gjuhën", + "english": "Anglisht", + "portuguese": "Portugalisht", + "portuguese_br": "Portugalisht (Brazil)", + "portuguese_pt": "Portugalisht (Portugali)", + "german": "Gjermanisht", + "arabic": "Arabisht", + "spanish": "Spanjisht", + "french": "Frëngjisht", + "italian": "Italisht", + "croatian": "Kroatisht", + "chinese": "Kinezisht (E thjeshtuar)", + "hindi": "Hindisht", + "serbian": "Serbisht", + "hebrew": "Hebraike", + "bulgarian": "Bullgare", + "polish": "Polake", + "czech": "Çeke", + "turkish": "Turke", + "slovenian": "Sllovene", + "macedonian": "Maqedonase", + "russian": "Ruse", + "filipino": "Filipine", + "dutch_nl": "Holandeze", + "romanian": "Rumune", + "albanian": "Shqipe", + "account": "Llogaria", + "content_discovery": "Përmbajtja & Zbulimi", + "appearance": "Pamja", + "integrations": "Integrimet", + "playback": "Riprodhimi", + "backup_restore": "Rezervimi & Rikthimi", + "updates": "Përditësimet", + "about": "Rreth nesh", + "developer": "Zhvilluesi", + "cache": "Cache", + "title": "Cilësimet", + "settings_title": "Cilësimet", + "sign_in_sync": "Hyni për sinkronizim", + "add_catalogs_sources": "Shtojcat, katalogët dhe burimet", + "player_trailers_downloads": "Player-i, trailer-at, shkarkimet", + "mdblist_tmdb_ai": "MDBList, TMDB, AI", + "check_updates": "Kontrollo për përditësime", + "clear_mdblist_cache": "Pastro Cache-in e MDBList", + "cache_management": "MENAXHIMI I CACHE", + "downloads_counter": "shkarkime dhe po vazhdojnë", + "made_with_love": "Punuar me ❤️ nga Tapframe dhe miqtë", + "sections": { + "information": "INFORMACION", + "account": "LLOGARIA", + "theme": "TEMA", + "layout": "PAMJA (LAYOUT)", + "sources": "BURIMET", + "catalogs": "KATALOGËT", + "discovery": "ZBULIMI", + "metadata": "METADHENAT", + "ai_assistant": "ASISTENTI AI", + "video_player": "VIDEO PLAYER", + "audio_subtitles": "AUDIO & TITRAT", + "media": "MEDIA", + "notifications": "NJOFTIMET", + "testing": "TESTIMI", + "danger_zone": "ZONA E RREZIKUT" + }, + "items": { + "legal": "Ligjore & Mohimi i përgjegjësisë", + "privacy_policy": "Politika e Privatësisë", + "report_issue": "Raporto një problem", + "version": "Versioni", + "contributors": "Kontribuesit", + "view_contributors": "Shiko të gjithë kontribuesit", + "theme": "Tema", + "episode_layout": "Pamja e Episodit", + "streams_backdrop": "Sfondi i burimeve", + "streams_backdrop_desc": "Shfaq sfond të turbullt në burimet mobile", + "addons": "Shtojcat", + "installed": "të instaluara", + "debrid_integration": "Integrimi Debrid", + "debrid_desc": "Lidhu me Torbox", + "plugins": "Shtojcat (Plugins)", + "plugins_desc": "Menaxho shtojcat dhe depot (repositories)", + "catalogs": "Katalogët", + "active": "aktiv", + "home_screen": "Ekrani Kryesor", + "home_screen_desc": "Pamja dhe përmbajtja", + "continue_watching": "Vazhdo Shikimin", + "continue_watching_desc": "Sjellja e cache dhe riprodhimit", + "show_discover": "Shfaq Seksionin e Zbulimit", + "show_discover_desc": "Shfaq përmbajtjen e zbulimit në Kërkim", + "mdblist": "MDBList", + "mdblist_connected": "I lidhur", + "mdblist_desc": "Aktivizo për të shtuar vlerësime & komente", + "simkl": "Simkl", + "simkl_connected": "I lidhur", + "simkl_desc": "Ndiq atë që po shikon", + "tmdb": "TMDB", + "tmdb_desc": "Ofruesi i metadhenave dhe logove", + "openrouter": "OpenRouter API", + "openrouter_connected": "I lidhur", + "openrouter_desc": "Shto çelësin API për bisedën me AI", + "video_player": "Video Player", + "built_in": "I integruar", + "external": "I jashtëm", + "preferred_audio": "Gjuha e preferuar e Audios", + "preferred_subtitle": "Gjuha e preferuar e Titrave", + "subtitle_source": "Prioriteti i Burimit të Titrave", + "auto_select_subs": "Zgjidh Titrat Automatikisht", + "auto_select_subs_desc": "Zgjidh automatikisht titrat që përputhen me preferencat tuaja", + "show_trailers": "Shfaq Trailer-at", + "show_trailers_desc": "Shfaq trailer-at në seksionin kryesor", + "enable_downloads": "Aktivizo Shkarkimet", + "enable_downloads_desc": "Shfaq skedën e shkarkimeve dhe aktivizo ruajtjen e burimeve", + "notifications": "Njoftimet", + "notifications_desc": "Kujtesat për episode", + "developer_tools": "Mjetet e Zhvilluesit", + "developer_tools_desc": "Opsionet e testimit dhe korrigjimit", + "test_onboarding": "Testo Mirëseardhjen", + "reset_onboarding": "Rifillo Mirëseardhjen", + "test_announcement": "Testo Njoftimin", + "test_announcement_desc": "Shfaq njoftimin për risitë", + "reset_campaigns": "Rifillo Fushatat", + "reset_campaigns_desc": "Pastro përshtypjet e fushatave", + "clear_all_data": "Pastro të gjitha të dhënat", + "clear_all_data_desc": "Rifillo të gjitha cilësimet dhe të dhënat e cache" + }, + "options": { + "horizontal": "Horizontal", + "vertical": "Vertikal", + "internal_first": "Të brendshmet paratë", + "internal_first_desc": "Prefero titrat e integruar, pastaj ato të jashtëm", + "external_first": "Të jashtmet paratë", + "external_first_desc": "Prefero titrat nga shtojcat, pastaj ato të integruar", + "any_available": "Çdo gjë e disponueshme", + "any_available_desc": "Përdor gjurmën e parë të disponueshme të titrave" + }, + "clear_data_desc": "Kjo do të rikthejë të gjitha cilësimet dhe do të fshijë të gjithë cache-in. Jeni të sigurt?", + "app_updates": "Përditësimet e Aplikacionit", + "about_nuvio": "Rreth Nuvio" + }, + "privacy": { + "title": "Privatësia & Të dhënat", + "settings_desc": "Kontrollo telemetrinë dhe mbledhjen e të dhënave", + "info_title": "Privatësia Juaj ka Rëndësi", + "info_description": "Kontrolloni cilat të dhëna mblidhen dhe shpërndahen. Analitika është e çaktivizuar si parazgjedhje dhe raportet e gabimeve janë anonime.", + "analytics_enabled_title": "Analitika u Aktivizua", + "analytics_enabled_message": "Të dhënat e përdorimit do të mblidhen për të përmirësuar aplikacionin. Mund ta çaktivizoni këtë në çdo kohë.", + "disable_error_reporting_title": "Çaktivizo Raportimin e Gabimeve?", + "disable_error_reporting_message": "Nëse e çaktivizoni, ne nuk do të njoftohemi për mbylljet e papritura apo problemet. Kjo mund të ndikojë në aftësinë tonë për të rregulluar gabimet.", + "enable_session_replay_title": "Aktivizo Rishikimin e Sesionit?", + "enable_session_replay_message": "Rishikimi i sesionit regjistron ekranin tuaj kur ndodhin gabime. Kjo mund të kapë përmbajtje të dukshme në ekranin tuaj.", + "enable_pii_title": "Aktivizo Mbledhjen e PII?", + "enable_pii_message": "Kjo lejon mbledhjen e të dhënave identifikuese si adresa IP dhe detajet e pajisjes për të diagnostikuar problemet.", + "disable_all_title": "Çaktivizo të gjithë Telemetrinë?", + "disable_all_message": "Kjo do të çaktivizojë analitikën, raportimin e gabimeve dhe rishikimin e sesionit.", + "disable_all_button": "Çaktivizo të Gjitha", + "all_disabled_title": "Telemetria u Çaktivizua", + "all_disabled_message": "Mbledhja e të dhënave është çaktivizuar. Ndryshimet do të hyjnë në fuqi pas rinisjes së aplikacionit.", + "reset_title": "Rikthe te të Rekomanduarat", + "reset_message": "Cilësimet e privatësisë janë rikthyer në vlerat e rekomanduara (raportimi i gabimeve aktiv, analitika joaktive).", + "section_analytics": "ANALITIKA", + "analytics_title": "Analitika e Përdorimit", + "analytics_description": "Mblidh modele anonime të përdorimit", + "section_error_reporting": "RAPORTIMI I GABIMEVE", + "error_reporting_title": "Raportet e Gabimeve", + "error_reporting_description": "Dërgo raporte anonime për të përmirësuar stabilitetin", + "session_replay_title": "Rishikimi i Sesionit", + "session_replay_description": "Regjistro ekranin kur ndodhin gabime", + "pii_title": "Përfshi Info e Pajisjes", + "pii_description": "Dërgo adresën IP dhe detajet e pajisjes me raporte", + "section_quick_actions": "VEPRIME TË SHPEJTA", + "disable_all": "Çaktivizo të gjithë Telemetrinë", + "disable_all_desc": "Fikni çdo mbledhje të dhënash", + "reset_recommended": "Rikthe te të Rekomanduarat", + "reset_recommended_desc": "Parazgjedhje për privatësi me raportim gabimesh", + "section_learn_more": "MËSO MË SHUMË", + "privacy_policy": "Politika e Privatësisë", + "current_settings": "Përmbledhja e Cilësimeve Aktuale", + "summary_analytics": "Analitika", + "summary_errors": "Raportet e Gabimeve", + "summary_replay": "Rishikimi i Sesionit", + "summary_pii": "Info e Pajisjes", + "restart_note_detailed": "* Analitika dhe raportimi i gabimeve hyjnë në fuqi menjëherë. Rishikimi i sesionit dhe PII kërkojnë rinisje të aplikacionit." + }, + "ai_settings": { + "title": "Asistenti AI", + "info_title": "Bisedë e Fuqizuar nga AI", + "info_desc": "Bëni pyetje për çdo film apo episod duke përdorur AI të avancuar. Merrni informacione për subjektin, personazhet, temat dhe më shumë.", + "feature_1": "Kontekst dhe analizë specifike për episodin", + "feature_2": "Shpjegime të subjektit dhe njohuri për personazhet", + "feature_3": "Kuriozitete dhe fakte nga prapaskenat", + "feature_4": "Çelësi juaj falas OpenRouter API", + "api_key_section": "ÇELËSI OPENROUTER API", + "api_key_label": "Çelësi API", + "api_key_desc": "Jepni çelësin tuaj OpenRouter API për të aktivizuar AI", + "save_api_key": "Ruaj Çelësin API", + "saving": "Duke u ruajtur...", + "update": "Përditëso", + "remove": "Hiq", + "get_free_key": "Merr Çelës API Falas nga OpenRouter", + "enable_chat": "Aktivizo AI Chat", + "enable_chat_desc": "Kur aktivizohet, butoni \"Pyet AI\" do të shfaqet në faqet e përmbajtjes.", + "chat_enabled": "AI Chat u Aktivizua", + "chat_enabled_desc": "Tani mund të bëni pyetje. Kërkoni butonin \"Pyet AI\"!", + "how_it_works": "Si funksionon", + "how_it_works_desc": "• OpenRouter ofron akses në modele të shumta AI\n• Çelësi juaj mbetet privat dhe i sigurt\n• Paketa falas përfshin limite bujare përdorimi\n• Bisedoni me kontekst për episode/filma specifikë", + "error_invalid_key": "Ju lutem jepni një çelës API të vlefshëm", + "error_key_format": "Çelësat OpenRouter duhet të fillojnë me \"sk-or-\"", + "success_saved": "Çelësi OpenRouter u ruajt me sukses!", + "error_save": "Dështoi ruajtja e çelësit API", + "confirm_remove_title": "Hiq Çelësin API", + "confirm_remove_msg": "Jeni të sigurt? Kjo do të çaktivizojë veçoritë e AI.", + "success_removed": "Çelësi API u hoq me sukses", + "error_remove": "Dështoi heqja e çelësit API" + }, + "catalog_settings": { + "title": "Katalogët", + "layout_phone": "PAMJA E EKRANIT TË KATALOGUT (TELEFON)", + "posters_per_row": "Postera për rresht", + "auto": "Auto", + "show_titles": "Shfaq Titujt e Posterave", + "show_titles_desc": "Shfaq tekstin e titullit poshtë çdo posteri", + "phone_only_hint": "Vlen vetëm për telefonat. Tabletat mbajnë pamjen adaptive.", + "catalogs_group": "Katalogët", + "enabled_count": "{{enabled}} nga {{total}} të aktivizuar", + "rename_hint": "Shtypni gjatë një katalog për ta riemërtuar", + "rename_modal_title": "Riemërto Katalogun", + "rename_placeholder": "Jepni emrin e ri të katalogut", + "error_save_name": "Nuk u mundësua ruajtja e emrit të personalizuar." + }, + "continue_watching_settings": { + "title": "Vazhdo Shikimin", + "playback_behavior": "SJELLJA E RIPRODHIMIT", + "use_cached": "Përdor Burimet e Ruajtura (Cache)", + "use_cached_desc": "Kur aktivizohet, klikimi te \"Vazhdo Shikimin\" hap direkt player-in me burimin e fundit. Kur çaktivizohet, hap ekranin e përmbajtjes.", + "open_metadata": "Hap Ekranin e Metadhenave", + "open_metadata_desc": "Hap detajet e përmbajtjes në vend të listës së burimeve.", + "card_appearance": "PAMJA E KARTËS", + "card_style": "Stili i Kartës", + "card_style_desc": "Zgjidhni si do të shfaqen artikujt në ekranin kryesor", + "wide": "E gjerë", + "poster": "Poster", + "cache_settings": "CILËSIMET E CACHE", + "cache_duration": "Kohëzgjatja e Cache të Burimit", + "cache_duration_desc": "Sa gjatë do të ruhen linqet e burimeve para se të skadojnë", + "important_note": "Shënim i Rëndësishëm", + "important_note_text": "Linqet mund të skadojnë më shpejt se kohëzgjatja e cache. Nëse një link dështon, aplikacioni do të kërkojë burime të reja.", + "how_it_works": "Si funksionon", + "how_it_works_cached": "• Burimet ruhen në cache për kohën e zgjedhur\n• Burimet validohen para përdorimit\n• Nëse cache skadon, kthehet te ekrani i përmbajtjes", + "how_it_works_uncached": "• Kur cache është i fikur, hapet ekrani i informacionit\n• Ju lejon të zgjidhni burimin manualisht", + "changes_saved": "Ndryshimet u ruajtën", + "min": "min", + "hour": "orë", + "hours": "orë" + }, + "contributors": { + "title": "Kontribuesit", + "special_mentions": "Përmendje Speciale", + "tab_contributors": "Kontribuesit", + "tab_special": "Speciale", + "tab_donors": "Dhuruesit", + "manager_role": "Menaxher i Komunitetit", + "manager_desc": "Menaxhon komunitetet në Discord & Reddit", + "sponsor_role": "Sponsor i Serverit", + "sponsor_desc": "Sponsorizoi infrastrukturën e serverit", + "mod_role": "Moderator Discord", + "mod_desc": "Ndihmon në moderimin e komunitetit", + "loading": "Duke u ngarkuar...", + "discord_user": "Përdorues Discord", + "contributions": "kontribute", + "gratitude_title": "Jemi mirënjohës për çdo kontribut", + "gratitude_desc": "Çdo rresht kodi dhe sugjerim ndihmon Nuvio-n të rritet", + "special_thanks_title": "Falënderime të Veçanta", + "special_thanks_desc": "Këta njerëz mahnitës mbajnë gjallë komunitetin dhe serverat tanë", + "donors_desc": "Faleminderit që besoni në projektin tonë. Mbështetja juaj e mban Nuvio-n falas.", + "latest_donations": "Të fundit", + "leaderboard": "Tabela e Nderit", + "loading_donors": "Duke ngarkuar dhuruesit...", + "no_donors": "Ende asnjë dhurues", + "error_rate_limit": "U kalua limiti i API të GitHub. Provoni më vonë.", + "error_failed": "Dështoi ngarkimi i kontribuesve.", + "retry": "Riprovo", + "no_contributors": "Nuk u gjet asnjë kontribues", + "loading_contributors": "Duke ngarkuar kontribuesit..." + }, + "debrid": { + "title": "Integrimi Debrid", + "description_torbox": "Zhbllokoni burimet 4K dhe shpejtësitë maksimale duke integruar Torbox.", + "description_torrentio": "Konfiguro Torrentio për të marrë burime torrent. Kërkohet një shërbim debrid.", + "tab_torbox": "TorBox", + "tab_torrentio": "Torrentio", + "status_connected": "I lidhur", + "status_disconnected": "I shkëputur", + "enable_addon": "Aktivizo Shtojcën", + "disconnect_button": "Shkëputu & Hiq", + "disconnect_loading": "Duke u shkëputur...", + "account_info": "Informacioni i Llogarisë", + "plan": "Plani", + "plan_free": "Falas", + "plan_essential": "Essential ($3/muaj)", + "plan_pro": "Pro ($10/muaj)", + "plan_standard": "Standard ($5/muaj)", + "plan_unknown": "I panjohur", + "expires": "Skadon", + "downloaded": "Shkarkuar", + "status_active": "Aktiv", + "connected_title": "✓ Lidhur me TorBox", + "connected_desc": "Shtojca TorBox është aktive dhe ofron burime premium.", + "configure_title": "Konfiguro Shtojcën", + "configure_desc": "Personalizoni përvojën tuaj të transmetimit.", + "open_settings": "Hap Cilësimet", + "what_is_debrid": "Çfarë është një Shërbim Debrid?", + "enter_api_key": "Jepni çelësin API", + "connect_button": "Lidhu & Instalo", + "connecting": "Duke u lidhur...", + "unlock_speeds_title": "Zhblloko Shpejtësitë Premium", + "unlock_speeds_desc": "Merrni një pajtim në Torbox për transmetim pa buffering.", + "get_subscription": "Merr Pajtimin", + "powered_by": "Fuqizuar nga", + "disclaimer_torbox": "Nuvio nuk është i lidhur me Torbox.", + "disclaimer_torrentio": "Nuvio nuk është i lidhur me Torrentio.", + "installed_badge": "✓ I INSTALUAR", + "promo_title": "⚡ Keni nevojë për Shërbim Debrid?", + "promo_desc": "Merrni TorBox për transmetim 4K jashtëzakonisht të shpejtë.", + "promo_button": "Merr Pajtimin në TorBox", + "service_label": "Shërbimi Debrid *", + "api_key_label": "Çelësi API *", + "sorting_label": "Renditja", + "exclude_qualities": "Përjashto Cilësitë", + "priority_languages": "Gjuhët Prioritare", + "max_results": "Maksimumi i Rezultateve", + "additional_options": "Opsione Shtesë", + "no_download_links": "Mos shfaq linqet e shkarkimit", + "no_debrid_catalog": "Mos shfaq katalogun debrid", + "install_button": "Instalo Torrentio", + "installing": "Duke u instaluar...", + "update_button": "Përditëso Konfigurimin", + "updating": "Duke u përditësuar...", + "remove_button": "Hiq Torrentio", + "error_api_required": "Kërkohet Çelësi API", + "error_api_required_desc": "Ju lutem jepni çelësin API për të instaluar Torrentio.", + "success_installed": "Shtojca Torrentio u instaluar me sukses!", + "success_removed": "Shtojca Torrentio u hoq me sukses", + "alert_disconnect_title": "Shkëput Torbox", + "alert_disconnect_msg": "Jeni të sigurt? Kjo do të fshijë çelësin API të ruajtur." + }, + "home_screen": { + "title": "Cilësimet e Ekranit Kryesor", + "changes_applied": "Ndryshimet u aplikuan", + "display_options": "OPSIONET E SHFAQJES", + "show_hero": "Shfaq Seksionin Hero", + "show_hero_desc": "Përmbajtja e sugjeruar në krye", + "show_this_week": "Shfaq Seksionin 'Këtë Javë'", + "show_this_week_desc": "Episodet e reja nga java aktuale", + "select_catalogs": "Zgjidh Katalogët", + "all_catalogs": "Të gjithë katalogët", + "selected": "të zgjedhur", + "hero_layout": "Pamja e Seksionit Hero", + "layout_legacy": "Klasike", + "layout_carousel": "Karuzel", + "layout_appletv": "Apple TV", + "layout_desc": "Banner me gjerësi të plotë, karta rrëshqitëse ose stili Apple TV", + "featured_source": "Burimi i Sugjeruar", + "using_catalogs": "Duke përdorur Katalogët", + "manage_selected_catalogs": "Menaxho katalogët e zgjedhur", + "dynamic_bg": "Sfond Dinamik për Hero", + "dynamic_bg_desc": "Banner i turbullt pas karuzelit", + "performance_note": "Mund të ndikojë në performancë në pajisjet e vjetra.", + "posters": "Posterat", + "show_titles": "Shfaq Titujt", + "poster_size": "Madhësia e Posterit", + "poster_corners": "Këndet e Posterit", + "size_small": "Vogël", + "size_medium": "Mesme", + "size_large": "Madhe", + "corners_square": "Katror", + "corners_rounded": "Rrumbullakosur", + "corners_pill": "Kapsulë (Pill)", + "about_these_settings": "RRETH KËTYRE CILËSIMEVE", + "about_desc": "Këto cilësime kontrollojnë shfaqjen e përmbajtjes në ekranin kryesor. Ndryshimet aplikohen menjëherë.", + "hero_catalogs": { + "title": "Katalogët e Seksionit Hero", + "select_all": "Zgjidh të Gjitha", + "clear_all": "Pastro të Gjitha", + "info": "Zgjidh cilët katalogë do të shfaqen në seksionin hero. Nëse nuk zgjidhet asnjë, do të përdoren të gjithë. Mos harroni të shtypni Ruaj.", + "settings_saved": "Cilësimet u ruajtën", + "error_load": "Dështoi ngarkimi i katalogëve", + "movies": "Filma", + "tv_shows": "Serialet" + } + }, + "calendar": { + "title": "Kalendari", + "loading": "Duke ngarkuar kalendarin...", + "no_scheduled_episodes": "Nuk ka episode të planifikuara", + "check_back_later": "Kontrolloni përsëri më vonë", + "showing_episodes_for": "Duke shfaqur episodet për {{date}}", + "show_all_episodes": "Shfaq të Gjithë Episodet", + "no_episodes_for": "Nuk ka episode për {{date}}", + "no_upcoming_found": "Nuk u gjet asnjë episod i ardhshëm", + "add_series_desc": "Shtoni seriale në bibliotekë për të parë episodet e tyre të ardhshme këtu" + }, + "mdblist": { + "title": "Burimet e Vlerësimit", + "status_disabled": "MDBList u çaktivizua", + "status_active": "Çelësi API Aktiv", + "status_required": "Kërkohet Çelësi API", + "status_disabled_desc": "Funksionaliteti i MDBList është aktualisht i fikur.", + "status_active_desc": "Vlerësimet nga MDBList janë aktive.", + "status_required_desc": "Shtoni çelësin tuaj më poshtë për të aktivizuar vlerësimet.", + "enable_toggle": "Aktivizo MDBList", + "enable_toggle_desc": "Ndez/Fik të gjithë funksionalitetin e MDBList", + "api_section": "Çelësi API", + "placeholder": "Ngjisni çelësin tuaj API të MDBList", + "save": "Ruaj", + "clear": "Fshi Çelësin", + "rating_providers": "Ofruesit e Vlerësimeve", + "rating_providers_desc": "Zgjidhni cilat vlerësime të shfaqen në aplikacion", + "how_to": "Si të merrni një çelës API", + "step_1": "Hyni në faqen e", + "step_1_link": "MDBList", + "step_2": "Shkoni te seksioni", + "step_2_settings": "Cilësimet (Settings)", + "step_2_api": "API", + "step_2_end": ".", + "step_3": "Gjeneroni një çelës të ri dhe kopjojeni atë.", + "go_to_website": "Shko te MDBList", + "alert_clear_title": "Fshi Çelësin API", + "alert_clear_msg": "Jeni të sigurt që dëshironi të hiqni çelësin API të ruajtur?", + "success_saved": "Çelësi API u ruajt me sukses.", + "error_empty": "Çelësi API nuk mund të jetë bosh.", + "error_save": "Ndodhi një gabim gjatë ruajtjes. Provoni përsëri.", + "api_key_empty_error": "Çelësi API nuk mund të jetë bosh.", + "success_cleared": "Çelësi API u fshi me sukses", + "error_clear": "Dështoi fshirja e çelësit API" + }, + "notification": { + "title": "Cilësimet e Njoftimeve", + "section_general": "Të përgjithshme", + "enable_notifications": "Aktivizo Njoftimet", + "section_types": "Llojet e Njoftimeve", + "new_episodes": "Episode të Reja", + "upcoming_shows": "Serialet e Ardhshme", + "reminders": "Kujtesat", + "section_timing": "Koha e Njoftimit", + "timing_desc": "Kur dëshironi të njoftoheni para transmetimit të episodit?", + "hours_1": "1 orë", + "hours_suffix": "orë", + "section_status": "Statusi i Njoftimeve", + "stats_upcoming": "Të ardhshme", + "stats_this_week": "Këtë javë", + "stats_total": "Totali", + "sync_button": "Sinkronizo Bibliotekën & Trakt", + "syncing": "Duke u sinkronizuar...", + "sync_desc": "Sinkronizon automatikisht njoftimet për bibliotekën tuaj dhe listat e Trakt.", + "section_advanced": "Të avancuara", + "reset_button": "Rifillo të gjitha njoftimet", + "test_button": "Testo Njoftimin (5 sek)", + "test_notification_in": "Njoftimi pas {{seconds}}s...", + "test_notification_text": "Njoftimi do të shfaqet pas {{seconds}} sekondash", + "alert_reset_title": "Rifillo Njoftimet", + "alert_reset_msg": "Kjo do të anulojë të gjitha njoftimet e planifikuara. Jeni të sigurt?", + "alert_reset_success": "Të gjitha njoftimet janë rifilluar", + "alert_sync_complete": "Sinkronizimi u krye", + "alert_sync_msg": "Njoftimet u sinkronizuan me sukses.\n\nPlanifikuar: {{upcoming}} episode\nKëtë javë: {{thisWeek}} episode", + "alert_test_scheduled": "Njoftimi i testimit u planifikua" + }, + "backup": { + "title": "Rezervimi & Rikthimi", + "options_title": "Opsionet e Rezervimit", + "options_desc": "Zgjidhni çfarë të përfshini në rezervimin tuaj", + "section_core": "Të dhënat kryesore", + "section_addons": "Shtojcat & Integrimet", + "section_settings": "Cilësimet & Preferencat", + "library_label": "Biblioteka", + "library_desc": "Filmat dhe serialet tuaja të ruajtura", + "watch_progress_label": "Progresi i Shikimit", + "watch_progress_desc": "Pozicionet e fundit të shikimit", + "addons_label": "Shtojcat (Addons)", + "addons_desc": "Shtojcat e instaluara të Stremio", + "plugins_label": "Plugins", + "plugins_desc": "Konfigurimet e personalizuara të skraperëve", + "trakt_label": "Integrimi Trakt", + "trakt_desc": "Të dhënat e sinkronizimit dhe token-at", + "app_settings_label": "Cilësimet e Aplikacionit", + "app_settings_desc": "Tema, preferencat dhe konfigurimet", + "user_prefs_label": "Preferencat e Përdoruesit", + "user_prefs_desc": "Renditja e shtojcave dhe cilësimet e UI", + "catalog_settings_label": "Cilësimet e Katalogut", + "catalog_settings_desc": "Filtrat dhe preferencat e katalogut", + "api_keys_label": "Çelësat API", + "api_keys_desc": "Çelësat e MDBList dhe OpenRouter", + "action_create": "Krijo Rezervim (Backup)", + "action_restore": "Rikthe nga Rezervimi", + "section_info": "Rreth Rezervimeve", + "info_text": "• Skedarët e rezervimit ruhen lokalisht në pajisje\n• Mund ta ndani rezervimin për të transferuar të dhënat\n• Rikthimi do të fshijë të dhënat tuaja aktuale", + "alert_create_title": "Krijo Rezervim", + "alert_no_content": "Asnjë opsion nuk është zgjedhur për rezervim.", + "alert_backup_created_title": "Rezervimi u krijua", + "alert_backup_created_msg": "Rezervimi juaj është gati për t'u ndarë.", + "alert_backup_failed_title": "Rezervimi dështoi", + "alert_restore_confirm_title": "Konfirmo Rikthimin", + "alert_restore_confirm_msg": "Kjo do të rikthejë të dhënat nga rezervimi i datës {{date}}. Kjo do të mbishkruajë të dhënat aktuale. Vazhdoni?", + "alert_restore_complete_title": "Rikthimi u krye", + "alert_restore_complete_msg": "Të dhënat u rikthyen me sukses. Ju lutem rinisni aplikacionin.", + "alert_restore_failed_title": "Rikthimi dështoi", + "restart_app": "Rinis Aplikacionin", + "alert_restart_failed_title": "Rinisja dështoi", + "alert_restart_failed_msg": "Mbylleni dhe hapeni aplikacionin manualisht për të parë ndryshimet." + }, + "updates": { + "title": "Përditësimet", + "status_checking": "Duke kërkuar për përditësime...", + "status_available": "Përditësim i ri i disponueshëm!", + "status_downloading": "Duke shkarkuar përditësimin...", + "status_installing": "Duke instaluar përditësimin...", + "status_success": "Përditësimi u instalua me sukses!", + "status_error": "Përditësimi dështoi", + "status_ready": "Gati për të kërkuar përditësime", + "action_check": "Kontrollo për Përditësime", + "action_install": "Instalo Përditësimin", + "release_notes": "Shënimet e versionit:", + "version": "Versioni:", + "last_checked": "Kontrolli i fundit:", + "current_version": "Versioni aktual:", + "current_release_notes": "Shënimet e versionit aktual:", + "github_release": "VERSIONI NË GITHUB", + "current": "Aktual:", + "latest": "I fundit:", + "notes": "Shënime:", + "view_release": "Shiko Versionin", + "notification_settings": "CILËSIMET E NJOFTIMEVE", + "ota_alerts_label": "Njoftimet OTA", + "ota_alerts_desc": "Shfaq njoftime për përditësimet 'over-the-air'", + "major_alerts_label": "Njoftime për Versionet Kryesore", + "major_alerts_desc": "Shfaq njoftime për versione të reja në GitHub", + "alert_disable_ota_title": "Çaktivizo njoftimet OTA?", + "alert_disable_ota_msg": "Nuk do të merrni më njoftime automatike. Përditësimet janë të rëndësishme për rregullimin e gabimeve dhe stabilitetin.", + "alert_disable_major_title": "Çaktivizo njoftimet kryesore?", + "alert_disable_major_msg": "Versionet kryesore shpesh përfshijnë arnime sigurie dhe veçori të reja.", + "warning_note": "Mbajtja e njoftimeve aktive ju siguron që të keni gjithmonë versionin më të sigurt.", + "disable": "Çaktivizo", + "alert_no_update_to_install": "Nuk ka asnjë përditësim për të instaluar", + "alert_install_failed": "Dështoi instalimi i përditësimit", + "alert_no_update_title": "Asnjë përditësim", + "alert_update_applied_msg": "Përditësimi do të aplikohet në rinisjen e radhës" + }, + "player": { + "title": "Video Player", + "section_selection": "ZGJEDHJA E PLAYER-IT", + "internal_title": "Player i Integruar", + "internal_desc": "Përdor player-in e paracaktuar të aplikacionit", + "vlc_title": "VLC", + "vlc_desc": "Hap burimet në VLC media player", + "infuse_title": "Infuse", + "infuse_desc": "Hap burimet në Infuse player", + "outplayer_title": "OutPlayer", + "outplayer_desc": "Hap burimet në OutPlayer", + "vidhub_title": "VidHub", + "vidhub_desc": "Hap burimet në VidHub player", + "infuse_live_title": "Infuse Livecontainer", + "infuse_live_desc": "Hap burimet në Infuse player LiveContainer", + "external_title": "Player i Jashtëm", + "external_desc": "Hap burimet në player-in tuaj të preferuar", + "section_playback": "OPSIONET E RIPRODHIMIT", + "skip_intro_settings_title": "Anashkalo Intron", + "powered_by_introdb": "Mundësuar nga IntroDB", + "autoplay_title": "Luaj Automatikisht Burimin e Parë", + "autoplay_desc": "Fillo automatikisht burimin e parë në listë.", + "resume_title": "Vazhdo Gjithmonë", + "resume_desc": "Vazhdo automatikisht aty ku e keni lënë pa pyetur.", + "engine_title": "Motori i Video Player-it", + "engine_desc": "Auto përdor ExoPlayer me rikthim në MPV. Rekomandohet për pajtueshmëri më të mirë.", + "decoder_title": "Mënyra e Dekoderit", + "decoder_desc": "Si dekodohet videoja. Auto rekomandohet.", + "gpu_title": "Renderimi me GPU", + "gpu_desc": "GPU-Next ofron menaxhim më të mirë të HDR dhe ngjyrave.", + "external_downloads_title": "Player i Jashtëm për Shkarkimet", + "external_downloads_desc": "Luaj përmbajtjen e shkarkuar në një player të jashtëm.", + "restart_required": "Kërkohet Rinisja", + "restart_msg_decoder": "Rinisni aplikacionin që ndryshimi i dekoderit të hyjë në fuqi.", + "restart_msg_gpu": "Rinisni aplikacionin që ndryshimi i GPU-së të hyjë në fuqi.", + "option_auto": "Auto", + "option_auto_desc_engine": "ExoPlayer + rikthim në MPV", + "option_mpv": "MPV", + "option_mpv_desc": "Vetëm MPV", + "option_auto_desc_decoder": "Ekuilibri më i mirë", + "option_sw": "SW", + "option_sw_desc": "Software", + "option_hw": "HW", + "option_hw_desc": "Hardware", + "option_hw_plus": "HW+", + "option_hw_plus_desc": "Hardware i Plotë", + "option_gpu_desc": "Standarde", + "option_gpu_next_desc": "Avancuar" + }, + "plugins": { + "title": "Plugins", + "enable_title": "Aktivizo Plugins", + "enable_desc": "Aktivizo motorin e plugin-eve për të gjetur burime mediash", + "repo_config_title": "Konfigurimi i Repositorit", + "repo_config_desc": "Menaxho repositoret e jashtme të plugin-eve.", + "your_repos": "Repositoret", + "your_repos_desc": "Konfiguro burimet e jashtme për plugin-et.", + "add_repo_button": "Shto Repositor", + "refresh": "Rinfresko", + "remove": "Hiq", + "enabled": "Aktivizuar", + "disabled": "Çaktivizuar", + "updating": "Duke u përditësuar...", + "success": "Sukses", + "error": "Gabim", + "alert_repo_added": "Repositori u shtua dhe plugin-et u ngarkuan", + "alert_repo_saved": "URL e repositorit u ruajt me sukses", + "alert_repo_refreshed": "Repositori u rinfreskua me sukses", + "alert_invalid_url": "Format i pavlefshëm i URL-së", + "alert_plugins_cleared": "Të gjithë plugin-et janë hequr", + "alert_cache_cleared": "Cache i repositorit u pastrua", + "unknown": "I panjohur", + "active": "Aktiv", + "available": "I disponueshëm", + "platform_disabled": "Platformë e Çaktivizuar", + "limited": "I kufizuar", + "clear_all": "Fshi të Gjithë Plugin-et", + "clear_all_desc": "Jeni të sigurt? Ky veprim nuk mund të kthehet mbrapa.", + "clear_cache": "Pastro Cache-in e Repositorit", + "clear_cache_desc": "Kjo do të fshijë URL-në dhe të dhënat e ruajtura.", + "add_new_repo": "Shto Repositor të Ri", + "available_plugins": "Plugin-e të disponueshëm ({{count}})", + "placeholder": "Kërko plugin-e...", + "all": "Të gjithë", + "filter_all": "Të gjitha llojet", + "filter_movies": "Filma", + "filter_tv": "Seriale", + "enable_all": "Aktivizo të Gjitha", + "disable_all": "Çaktivizo të Gjitha", + "no_plugins_found": "Nuk u gjet asnjë plugin", + "no_plugins_available": "Nuk ka plugin-e të disponueshëm", + "no_match_desc": "Asnjë plugin nuk përputhet me \"{{query}}\".", + "configure_repo_desc": "Konfiguroni një repositor për të parë plugin-et.", + "clear_search": "Pastro Kërkimin", + "no_external_player": "Asnjë player i jashtëm", + "showbox_token": "Token-i i UI të ShowBox", + "showbox_placeholder": "Ngjisni token-in tuaj këtu", + "save": "Ruaj", + "clear": "Pastro", + "additional_settings": "Cilësime Shtesë", + "enable_url_validation": "Aktivizo Validimin e URL-së", + "url_validation_desc": "Validon linqet para shfaqjes (mund të jetë më i ngadaltë).", + "group_streams": "Grupo Burimet e Plugin-eve", + "group_streams_desc": "Burimet grupohen sipas repositorit.", + "sort_quality": "Rendit sipas Cilësisë", + "sort_quality_desc": "Burimet renditen së pari sipas rezolucionit.", + "show_logos": "Shfaq Logot e Plugin-eve", + "show_logos_desc": "Shfaq ikonat e plugin-eve pranë linqeve.", + "quality_filtering": "Filtrimi i Cilësisë", + "quality_filtering_desc": "Përjashto rezolucione specifike nga rezultatet.", + "excluded_qualities": "Cilësitë e përjashtuara:", + "language_filtering": "Filtrimi i Gjuhës", + "language_filtering_desc": "Përjashto gjuhë specifike nga kërkimi.", + "note": "Shënim:", + "language_filtering_note": "Ky filtër vlen vetëm për ofruesit që japin info për gjuhën.", + "excluded_languages": "Gjuhët e përjashtuara:", + "about_title": "Rreth Plugin-eve", + "about_desc_1": "Plugin-et janë komponentë që përshtatin përmbajtjen nga burime të jashtme. Ato funksionojnë lokalisht.", + "about_desc_2": "Plugin-et e shënuar si \"Limited\" mund të kërkojnë konfigurim shtesë.", + "help_title": "Konfigurimi i Plugin-eve", + "help_step_1": "1. **Aktivizo Plugin-et** - Ndizni çelësin kryesor", + "help_step_2": "2. **Shto Repositor** - Shtoni një URL të vlefshme", + "help_step_3": "3. **Rinfresko** - Ngarkoni plugin-et e disponueshëm", + "help_step_4": "4. **Aktivizo** - Ndizni plugin-et që dëshironi", + "got_it": "U kuptua!", + "repo_format_hint": "Formati: https://raw.githubusercontent.com/përdoruesi/repo/branch", + "cancel": "Anulo", + "add": "Shto" + }, + "theme": { + "title": "Temat e Aplikacionit", + "select_theme": "ZGJIDH TEMËN", + "create_custom": "Krijo Temë të Personalizuar", + "options": "OPSIONET", + "use_dominant_color": "Përdor Ngjyrën Dominante nga Arti", + "categories": { + "all": "Të gjitha temat", + "dark": "Tema të Erreta", + "colorful": "Me Ngjyra", + "custom": "Temat e Mia" + }, + "editor": { + "theme_name_placeholder": "Emri i temës", + "save": "Ruaj", + "primary": "Primare", + "secondary": "Sekondare", + "background": "Sfondi", + "invalid_name_title": "Emër i Pavlefshëm", + "invalid_name_msg": "Ju lutem jepni një emër të vlefshëm" + }, + "alerts": { + "delete_title": "Fshi Temën", + "delete_msg": "Jeni të sigurt që dëshironi të fshini \"{{name}}\"?", + "ok": "OK", + "delete": "Fshi", + "cancel": "Anulo", + "back": "Cilësimet" + } + }, + "legal": { + "title": "Ligjore & Mohimi i Përgjegjësisë", + "intro_title": "Natyra e Aplikacionit", + "intro_text": "Nuvio është një player mediash dhe mjet menaxhimi metadhenash. Ai shërben vetëm si ndërfaqe për shfletimin e metadhenave publike. Nuvio nuk mban, nuk shpërndan dhe nuk indekson asnjë përmbajtje mediatike.", + "extensions_title": "Plugins nga Palët e Treta", + "extensions_text": "Nuvio lejon instalimin e plugin-eve nga zhvillues të pavarur. Ne nuk kemi kontroll dhe nuk mbajmë përgjegjësi për ligjshmërinë apo funksionalitetin e tyre.", + "user_resp_title": "Përgjegjësia e Përdoruesit", + "user_resp_text": "Përdoruesit janë përgjegjësit e vetëm për plugin-et që instalojnë. Duke përdorur aplikacionin, ju pranoni që keni të drejtën ligjore për të hyrë në përmbajtjen që shikoni.", + "dmca_title": "E Drejta e Autorit & DMCA", + "dmca_text": "Ne respektojmë pronësinë intelektuale. Meqenëse Nuvio nuk mban përmbajtje, ne nuk mund të fshijmë materiale nga interneti.", + "warranty_title": "Asnjë Garanci", + "warranty_text": "Ky softuer ofrohet \"siç është\", pa asnjë lloj garancie, të shprehur apo të nënkuptuar." + }, + "plugin_tester": { + "title": "Testuesi i Plugin-eve", + "subtitle": "Ekzekutoni skraperët dhe kontrolloni loget", + "tabs": { + "individual": "Individual", + "repo": "Testuesi i Repos", + "code": "Kodi", + "logs": "Loget", + "results": "Rezultatet" + }, + "common": { + "error": "Gabim", + "success": "Sukses", + "movie": "Film", + "tv": "TV", + "tmdb_id": "ID e TMDB", + "season": "Sezoni", + "episode": "Episodi", + "running": "Duke u ekzekutuar...", + "run_test": "Nis Testin", + "play": "Luaj", + "done": "U krye", + "test": "Test", + "testing": "Duke testuar..." + }, + "individual": { + "load_from_url": "Ngarko nga URL", + "load_from_url_desc": "Ngjisni një URL të GitHub ose IP lokale.", + "enter_url_error": "Ju lutem jepni një URL", + "code_loaded": "Kodi u ngarkua nga URL", + "fetch_error": "Dështoi marrja: {{message}}", + "no_code_error": "Nuk ka kod për të ekzekutuar", + "plugin_code": "Kodi i Plugin-it", + "focus_editor": "Fokuso te kodi", + "code_placeholder": "// Ngjisni kodin e plugin-it këtu...", + "test_parameters": "Parametrat e Testit", + "no_logs": "Nuk ka loge ende.", + "no_streams": "Nuk u gjet asnjë burim.", + "streams_found": "{{count}} Burim u gjet", + "streams_found_plural": "{{count}} Burime u gjetën", + "tap_play_hint": "Shtypni Luaj për të testuar burimin në player.", + "unnamed_stream": "Burim pa emër", + "quality": "Cilësia: {{quality}}", + "size": "Madhësia: {{size}}", + "url_label": "URL: {{url}}", + "headers_info": "Headers: {{count}} të personalizuar", + "find_placeholder": "Gjej në kod...", + "edit_code_title": "Edito Kodin", + "no_url_stream_error": "Nuk u gjet asnjë URL për këtë burim" + }, + "repo": { + "title": "Testuesi i Repos", + "description": "Testoni çdo ofrues nga një repositor.", + "enter_repo_url_error": "Ju lutem jepni një URL repositori", + "invalid_url_title": "URL e Pavlefshme", + "invalid_url_msg": "Përdorni një URL 'raw' të GitHub.", + "manifest_build_error": "Nuk u mundësua ndërtimi i manifestit", + "manifest_fetch_error": "Dështoi marrja e manifestit", + "repo_manifest_fetch_error": "Dështoi marrja e manifestit të repositorit", + "missing_filename": "Mungon emri i skedarit në manifest", + "scraper_build_error": "Nuk u mundësua ndërtimi i skraperit", + "download_scraper_error": "Dështoi shkarkimi i skraperit", + "test_failed": "Testi dështoi", + "test_parameters": "Parametrat e Testit të Repos", + "test_parameters_desc": "Këto vlejnë vetëm për Testuesin e Repos.", + "using_info": "Duke përdorur: {{mediaType}} • TMDB {{tmdbId}}", + "using_info_tv": "Duke përdorur: {{mediaType}} • TMDB {{tmdbId}} • S{{season}}E{{episode}}", + "providers_title": "Ofruesit", + "repository_default": "Repositori", + "providers_count": "{{count}} ofrues", + "fetch_hint": "Ngarkoni një repo për të listuar ofruesit.", + "test_all": "Testo të Gjitha", + "status_running": "DUKE U EKZEKUTUAR", + "status_ok": "OK ({{count}})", + "status_ok_empty": "OK (0)", + "status_failed": "DËSHTOI", + "status_idle": "GATI", + "tried_url": "Provuar: {{url}}", + "provider_logs": "Loget e Ofruesit", + "no_logs_captured": "Nuk u kap asnjë log." + } + } +} diff --git a/src/i18n/locales/sr.json b/src/i18n/locales/sr.json index 4ca910dc..3398bcee 100644 --- a/src/i18n/locales/sr.json +++ b/src/i18n/locales/sr.json @@ -47,7 +47,7 @@ "channels": "Канали" }, "movies": "Филмови", - "tv_shows": "ТВ серије", + "tv_shows": "Cерије", "load_more_catalogs": "Учитај више каталога", "no_content": "Садржај није доступан", "add_catalogs": "Додај каталоге", @@ -72,7 +72,7 @@ "episode": "Епизода {{episode}}", "movie": "Филм", "series": "Серија", - "tv_show": "ТВ серија", + "tv_show": "Cерија", "percent_watched": "{{percent}}% одгледано", "view_details": "Види детаље", "remove": "Уклони", @@ -97,16 +97,16 @@ "navigation": { "home": "Почетна", "library": "Библиотека", - "search": "Претражи", + "search": "Претрага", "downloads": "Преузимања", "settings": "Подешавања" }, "search": { - "title": "Претражи", + "title": "Претрага", "recent_searches": "Недавне претраге", "discover": "Откриј", "movies": "Филмови", - "tv_shows": "ТВ серије", + "tv_shows": "Cерије", "select_catalog": "Изабери каталог", "all_genres": "Сви жанрови", "discovering": "Откривање садржаја...", @@ -122,7 +122,7 @@ "try_keywords": "Покушајте са другим кључним речима", "select_type": "Изабери тип", "browse_movies": "Прегледај каталоге филмова", - "browse_tv": "Прегледај каталоге ТВ серија", + "browse_tv": "Прегледај каталоге cерија", "select_genre": "Изабери жанр", "show_all_content": "Прикажи сав садржај", "genres_count": "{{count}} жанрова" @@ -144,7 +144,7 @@ "empty_folder_desc": "Ова колекција је празна", "refresh": "Освежи", "no_movies": "Још нема филмова", - "no_series": "Још нема ТВ серија", + "no_series": "Још нема cерија", "no_content": "Још нема садржаја", "add_content_desc": "Додајте садржај у своју библиотеку да бисте га видели овде", "find_something": "Пронађи нешто за гледање", @@ -304,7 +304,7 @@ "no_upcoming": "Нема надолазећих објава за овог глумца", "no_content": "Нема доступног садржаја за овог глумца", "no_movies": "Нема доступних филмова за овог глумца", - "no_tv": "Нема доступних ТВ серија за овог глумца" + "no_tv": "Нема доступних серија за овог глумца" }, "comments": { "title": "Trakt коментари", @@ -344,7 +344,7 @@ "all": "Све", "failed_tmdb": "Неуспело учитавање садржаја са TMDB", "movies": "Филмови", - "tv_shows": "ТВ серије", + "tv_shows": "Cерије", "channels": "Канали" }, "streams": { @@ -580,7 +580,7 @@ "production_info_desc": "Мреже и продукцијске куће са логотипима", "movie_details": "Детаљи о филму", "movie_details_desc": "Буџет, приход, трајање, слоган", - "tv_details": "Детаљи о ТВ серији", + "tv_details": "Детаљи о cерији", "tv_details_desc": "Статус, број сезона, мреже, креатори", "movie_collections": "Филмске колекције", "movie_collections_desc": "Филмске франшизе (Marvel, Star Wars, итд.)", @@ -634,6 +634,19 @@ "croatian": "Хрватски", "chinese": "Кинески (поједностављени)", "hindi": "Хинди", + "serbian": "Српски", + "hebrew": "Хебрејски", + "bulgarian": "бугарски", + "polish": "Пољски", + "czech": "Чешки", + "turkish": "Турски", + "slovenian": "Словеначки", + "macedonian": "Македонски", + "russian": "Руски", + "filipino": "Филипински", + "dutch_nl": "Холандски (Холандија)", + "romanian": "Румунски", + "albanian": "Албански", "account": "Налог", "content_discovery": "Садржај и откривање", "appearance": "Изглед", @@ -1408,4 +1421,4 @@ "no_logs_captured": "Нема забележених логова." } } -} +} \ No newline at end of file diff --git a/src/i18n/locales/tr.json b/src/i18n/locales/tr.json new file mode 100644 index 00000000..eda338ee --- /dev/null +++ b/src/i18n/locales/tr.json @@ -0,0 +1,1430 @@ +{ + "common": { + "loading": "Yükleniyor...", + "cancel": "İptal", + "save": "Kaydet", + "delete": "Sil", + "edit": "Düzenle", + "search": "Ara", + "error": "Hata", + "success": "Başarılı", + "ok": "Tamam", + "unknown": "Bilinmiyor", + "retry": "Yeniden Dene", + "try_again": "Tekrar Dene", + "go_back": "Geri Git", + "settings": "Ayarlar", + "close": "Kapat", + "enable": "Etkinleştir", + "disable": "Devre Dışı Bırak", + "show_more": "Daha Fazla Göster", + "show_less": "Daha Az Göster", + "load_more": "Daha Fazla Yükle", + "unknown_date": "Bilinmeyen tarih", + "anonymous_user": "Anonim Kullanıcı", + "time": { + "now": "Az önce", + "minutes_ago": "{{count}}dk önce", + "hours_ago": "{{count}}sa önce", + "days_ago": "{{count}}g önce" + }, + "days_short": { + "sun": "Paz", + "mon": "Pzt", + "tue": "Sal", + "wed": "Çar", + "thu": "Per", + "fri": "Cum", + "sat": "Cmt" + }, + "email": "E-posta", + "status": "Durum" + }, + "home": { + "categories": { + "movies": "Filmler", + "series": "Diziler", + "channels": "Kanallar" + }, + "movies": "Filmler", + "tv_shows": "TV Programları", + "load_more_catalogs": "Daha Fazla Katalog Yükle", + "no_content": "İçerik mevcut değil", + "add_catalogs": "Katalog Ekle", + "sign_in_available": "Giriş Yapılabilir", + "sign_in_desc": "Ayarlar → Hesap kısmından dilediğiniz zaman giriş yapabilirsiniz", + "view_all": "Tümünü Gör", + "this_week": "Bu Hafta", + "upcoming": "Yakında", + "recently_released": "Yeni Çıkanlar", + "no_scheduled_episodes": "Planlanmış Bölümü Olmayan Diziler", + "check_back_later": "Sonra tekrar kontrol edin", + "continue_watching": "İzlemeye Devam Et", + "up_next": "Sıradaki", + "up_next_caps": "SIRADAKİ", + "released": "Yayınlandı", + "new": "Yeni", + "tba": "Açıklanacak", + "new_episodes": "{{count}} Yeni Bölüm", + "season_short": "S{{season}}", + "episode_short": "B{{episode}}", + "season": "Sezon {{season}}", + "episode": "Bölüm {{episode}}", + "movie": "Film", + "series": "Dizi", + "tv_show": "TV Programı", + "percent_watched": "%{{percent}} izlendi", + "view_details": "Detayları Gör", + "remove": "Kaldır", + "play": "Oynat", + "play_now": "Şimdi Oynat", + "resume": "Devam Et", + "info": "Bilgi", + "more_info": "Daha Fazla Bilgi", + "my_list": "Listem", + "save": "Kaydet", + "saved": "Kaydedildi", + "retry": "Yeniden Dene", + "install_addons": "Eklentileri Yükle", + "settings": "Ayarlar", + "no_featured_content": "Öne Çıkan İçerik Yok", + "couldnt_load_featured": "Öne çıkan içerik yüklenemedi", + "no_featured_desc": "Katalog içeren eklentiler yükleyin veya ayarlardan içerik kaynağını değiştirin.", + "load_error_desc": "Öne çıkan içerik getirilirken bir sorun oluştu. Lütfen bağlantınızı kontrol edip tekrar deneyin.", + "no_featured_available": "Kullanılabilir öne çıkan içerik yok", + "no_description": "Açıklama mevcut değil" + }, + "navigation": { + "home": "Ana Sayfa", + "library": "Kütüphane", + "search": "Ara", + "downloads": "İndirmeler", + "settings": "Ayarlar" + }, + "search": { + "title": "Ara", + "recent_searches": "Son Aramalar", + "discover": "Keşfet", + "movies": "Filmler", + "tv_shows": "TV Programları", + "select_catalog": "Katalog Seç", + "all_genres": "Tüm Türler", + "discovering": "İçerik keşfediliyor...", + "show_more": "Daha Fazla Göster ({{count}})", + "no_content_found": "İçerik bulunamadı", + "try_different": "Farklı bir tür veya katalog deneyin", + "select_catalog_desc": "Keşfetmek için bir katalog seçin", + "tap_catalog_desc": "Başlamak için yukarıdaki katalog çipine dokunun", + "placeholder": "Film, dizi ara...", + "keep_typing": "Yazmaya devam edin...", + "type_characters": "Aramak için en az 2 karakter yazın", + "no_results": "Sonuç bulunamadı", + "try_keywords": "Farklı anahtar kelimeler deneyin veya yazımınızı kontrol edin", + "select_type": "Tür Seç", + "browse_movies": "Film kataloglarına göz at", + "browse_tv": "TV dizisi kataloglarına göz at", + "select_genre": "Tür Seç", + "show_all_content": "Tüm içeriği göster", + "genres_count": "{{count}} tür" + }, + "library": { + "title": "Kütüphane", + "watched": "İzlendi", + "continue": "Devam Et", + "watchlist": "İzleme Listesi", + "collection": "Koleksiyon", + "rated": "Puanlananlar", + "items": "öğe", + "trakt_collections": "Trakt koleksiyonları", + "trakt_collection": "Trakt Koleksiyonu", + "no_trakt": "Trakt koleksiyonu yok", + "no_trakt_desc": "Trakt kullanmaya başladığınızda koleksiyonlarınız burada görünecektir", + "load_collections": "Koleksiyonları Yükle", + "empty_folder": "{{folder}} klasöründe içerik yok", + "empty_folder_desc": "Bu koleksiyon boş", + "refresh": "Yenile", + "no_movies": "Henüz film yok", + "no_series": "Henüz TV dizisi yok", + "no_content": "Henüz içerik yok", + "add_content_desc": "Burada görmek için kütüphanenize içerik ekleyin", + "find_something": "İzleyecek bir şeyler bul", + "removed_from_library": "Kütüphaneden Kaldırıldı", + "item_removed": "Öğe kütüphanenizden kaldırıldı", + "failed_update_library": "Kütüphane güncellenemedi", + "unable_remove": "Öğe kütüphaneden kaldırılamıyor", + "marked_watched": "İzlendi Olarak İşaretlendi", + "marked_unwatched": "İzlenmedi Olarak İşaretlendi", + "item_marked_watched": "Öğe izlendi olarak işaretlendi", + "item_marked_unwatched": "Öğe izlenmedi olarak işaretlendi", + "failed_update_watched": "İzlendi durumu güncellenemedi", + "unable_update_watched": "İzlendi durumu güncellenemiyor", + "added_to_library": "Kütüphaneye Eklendi", + "item_added": "Yerel kütüphanenize eklendi", + "add_to_library": "Kütüphaneye Ekle", + "remove_from_library": "Kütüphaneden Kaldır", + "mark_watched": "İzlendi Olarak İşaretle", + "mark_unwatched": "İzlenmedi Olarak İşaretle", + "share": "Paylaş", + "add_to_watchlist": "Trakt İzleme Listesine Ekle", + "remove_from_watchlist": "Trakt İzleme Listesinden Kaldır", + "added_to_watchlist": "İzleme Listesine Eklendi", + "added_to_watchlist_desc": "Trakt izleme listenize eklendi", + "removed_from_watchlist": "İzleme Listesinden Kaldırıldı", + "removed_from_watchlist_desc": "Trakt izleme listenizden kaldırıldı", + "add_to_collection": "Trakt Koleksiyonuna Ekle", + "remove_from_collection": "Trakt Koleksiyonundan Kaldır", + "added_to_collection": "Koleksiyona Eklendi", + "added_to_collection_desc": "Trakt koleksiyonunuza eklendi", + "removed_from_collection": "Koleksiyondan Kaldırıldı", + "removed_from_collection_desc": "Trakt koleksiyonunuzdan kaldırıldı" + }, + "metadata": { + "unable_to_load": "İçerik Yüklenemedi", + "error_code": "Hata Kodu: {{code}}", + "content_not_found": "İçerik bulunamadı", + "content_not_found_desc": "Bu içerik mevcut değil veya kaldırılmış olabilir.", + "server_error": "Sunucu hatası", + "server_error_desc": "Sunucu geçici olarak kullanılamıyor. Lütfen daha sonra tekrar deneyin.", + "bad_gateway": "Hatalı ağ geçidi", + "bad_gateway_desc": "Sunucu sorun yaşıyor. Lütfen daha sonra tekrar deneyin.", + "service_unavailable": "Hizmet kullanılamıyor", + "service_unavailable_desc": "Hizmet şu anda bakım nedeniyle kapalı. Lütfen daha sonra tekrar deneyin.", + "too_many_requests": "Çok fazla istek", + "too_many_requests_desc": "Çok fazla istek yapıyorsunuz. Lütfen biraz bekleyip tekrar deneyin.", + "request_timeout": "İstek zaman aşımı", + "request_timeout_desc": "İstek çok uzun sürdü. Lütfen tekrar deneyin.", + "network_error": "Ağ hatası", + "network_error_desc": "Lütfen internet bağlantınızı kontrol edip tekrar deneyin.", + "auth_error": "Kimlik doğrulama hatası", + "auth_error_desc": "Lütfen hesap ayarlarınızı kontrol edip tekrar deneyin.", + "access_denied": "Erişim reddedildi", + "access_denied_desc": "Bu içeriğe erişim izniniz yok.", + "connection_error": "Bağlantı hatası", + "streams_unavailable": "Yayınlar kullanılamıyor", + "streams_unavailable_desc": "Yayın kaynakları şu anda kullanılamıyor. Lütfen daha sonra tekrar deneyin.", + "unknown_error": "Bilinmeyen hata", + "something_went_wrong": "Bir şeyler yanlış gitti. Lütfen tekrar deneyin.", + "cast": "Oyuncular", + "more_like_this": "Benzer İçerikler", + "collection": "Koleksiyon", + "episodes": "Bölümler", + "seasons": "Sezonlar", + "posters": "Afişler", + "banners": "Bannerlar", + "specials": "Özeller", + "season_number": "Sezon {{number}}", + "episode_count": "{{count}} Bölüm", + "episode_count_plural": "{{count}} Bölüm", + "no_episodes": "Bölüm mevcut değil", + "no_episodes_for_season": "Sezon {{season}} için bölüm mevcut değil", + "episodes_not_released": "Bölümler henüz yayınlanmamış olabilir", + "no_description": "Açıklama mevcut değil", + "episode_label": "BÖLÜM {{number}}", + "watch_again": "Tekrar İzle", + "completed": "Tamamlandı", + "play_episode": "Oynat S{{season}}E{{episode}}", + "play": "Oynat", + "watched": "İzlendi", + "watched_on_trakt": "Trakt'ta izlendi", + "synced_with_trakt": "Trakt ile senkronize edildi", + "saved": "Kaydedildi", + "director": "Yönetmen", + "directors": "Yönetmenler", + "creator": "Oluşturan", + "creators": "Oluşturanlar", + "production": "Yapım", + "network": "Kanal", + "mark_watched": "İzlendi Olarak İşaretle", + "mark_unwatched": "İzlenmedi Olarak İşaretle", + "marking": "İşaretleniyor...", + "removing": "Kaldırılıyor...", + "unmark_season": "Sezonu İzlenmedi Yap {{season}}", + "mark_season": "Sezonu İzlendi Yap {{season}}", + "resume": "Devam Et", + "spoiler_warning": "Spoiler Uyarısı", + "spoiler_warning_desc": "Bu yorum spoiler içeriyor. Görmek istediğinize emin misiniz?", + "cancel": "İptal", + "reveal_spoilers": "Spoiler'ı Göster", + "movie_details": "Film Detayları", + "show_details": "Program Detayları", + "tagline": "Slogan", + "status": "Durum", + "release_date": "Yayın Tarihi", + "runtime": "Süre", + "budget": "Bütçe", + "revenue": "Hasılat", + "origin_country": "Menşei Ülke", + "original_language": "Orijinal Dil", + "first_air_date": "İlk Yayın Tarihi", + "last_air_date": "Son Yayın Tarihi", + "total_episodes": "Toplam Bölüm", + "episode_runtime": "Bölüm Süresi", + "created_by": "Oluşturan", + "backdrop_gallery": "Arka Plan Galerisi", + "loading_episodes": "Bölümler yükleniyor...", + "no_episodes_available": "Bölüm mevcut değil", + "play_next": "Sıradakini Oynat S{{season}}E{{episode}}", + "play_next_episode": "Sıradaki Bölümü Oynat", + "save": "Kaydet", + "percent_watched": "%{{percent}} izlendi", + "percent_watched_trakt": "%{{percent}} izlendi (Trakt'ta %{{traktPercent}})", + "synced_with_trakt_progress": "Trakt ile senkronize edildi", + "using_trakt_progress": "Trakt ilerlemesi kullanılıyor", + "added_to_collection_hero": "Koleksiyona Eklendi", + "added_to_collection_desc_hero": "Trakt koleksiyonunuza eklendi", + "removed_from_collection_hero": "Koleksiyondan Kaldırıldı", + "removed_from_collection_desc_hero": "Trakt koleksiyonunuzdan kaldırıldı", + "mark_as_watched": "İzlendi Olarak İşaretle", + "mark_as_unwatched": "İzlenmedi Olarak İşaretle" + }, + "cast": { + "biography": "Biyografi", + "known_for": "Bilindiği Yapımlar", + "personal_info": "Kişisel Bilgiler", + "born_in": "{{place}} doğumlu", + "filmography": "Filmografi", + "also_known_as": "Ayrıca Şöyle Bilinir", + "no_info_available": "Ek bilgi mevcut değil", + "as_character": "{{character}} rolünde", + "loading_details": "Detaylar yükleniyor...", + "years_old": "{{age}} yaşında", + "view_filmography": "Filmografiyi Görüntüle", + "filter": "Filtrele", + "sort_by": "Sırala", + "sort_popular": "Popüler", + "sort_latest": "En Yeni", + "sort_upcoming": "Gelecek", + "upcoming_badge": "GELECEK", + "coming_soon": "Yakında", + "filmography_count": "Filmografi • {{count}} yapım", + "loading_filmography": "Filmografi yükleniyor...", + "load_more_remaining": "Daha Fazla Yükle ({{count}} kalan)", + "alert_error_title": "Hata", + "alert_error_message": "\"{{title}}\" yüklenemedi. Lütfen daha sonra tekrar deneyin.", + "alert_ok": "Tamam", + "no_upcoming": "Bu oyuncu için gelecek bir yapım yok", + "no_content": "Bu oyuncu için içerik yok", + "no_movies": "Bu oyuncu için film yok", + "no_tv": "Bu oyuncu için TV programı yok" + }, + "comments": { + "title": "Trakt Yorumları", + "spoiler_warning": "⚠️ Bu yorum spoiler içerir. Görmek için dokunun.", + "spoiler": "Spoiler", + "contains_spoilers": "Spoiler içerir", + "reveal": "Göster", + "vip": "VIP", + "unavailable": "Yorumlar kullanılamıyor", + "no_comments": "Henüz Trakt yorumu yok", + "not_in_database": "Bu içerik henüz Trakt veritabanında olmayabilir", + "check_trakt": "Trakt'ı Kontrol Et" + }, + "trailers": { + "title": "Fragmanlar", + "official_trailers": "Resmi Fragmanlar", + "official_trailer": "Resmi Fragman", + "teasers": "Tanıtımlar", + "teaser": "Tanıtım", + "clips_scenes": "Klipler ve Sahneler", + "clip": "Klip", + "featurettes": "Özel Videolar", + "featurette": "Özel Video", + "behind_the_scenes": "Kamera Arkası", + "no_trailers": "Fragman mevcut değil", + "unavailable": "Fragman Kullanılamıyor", + "unavailable_desc": "Bu fragman şu an yüklenemedi. Lütfen daha sonra tekrar deneyin.", + "unable_to_play": "Fragman oynatılamıyor. Lütfen tekrar deneyin.", + "watch_on_youtube": "YouTube'da İzle" + }, + "catalog": { + "no_content_found": "İçerik bulunamadı", + "no_content_filters": "Seçili filtreler için içerik bulunamadı", + "loading_content": "İçerik yükleniyor...", + "back": "Geri", + "in_theaters": "Vizyondakiler", + "all": "Hepsi", + "failed_tmdb": "TMDB'den içerik yüklenemedi", + "movies": "Filmler", + "tv_shows": "TV Programları", + "channels": "Kanallar" + }, + "streams": { + "back_to_episodes": "Bölümlere Dön", + "back_to_info": "Bilgiye Dön", + "fetching_from": "Şuradan getiriliyor:", + "no_sources_available": "Yayın kaynağı mevcut değil", + "add_sources_desc": "Lütfen ayarlardan yayın kaynakları ekleyin", + "add_sources": "Kaynak Ekle", + "finding_streams": "Uygun yayınlar aranıyor...", + "finding_best_stream": "Otomatik oynatma için en iyi yayın aranıyor...", + "still_fetching": "Hala yayınlar aranıyor...", + "no_streams_available": "Yayın mevcut değil", + "starting_best_stream": "En iyi yayın başlatılıyor...", + "loading_more_sources": "Daha fazla kaynak yükleniyor..." + }, + "player_ui": { + "via": "{{name}} aracılığıyla", + "audio_tracks": "Ses Kanalları", + "no_audio_tracks": "Ses kanalı mevcut değil", + "playback_speed": "Oynatma Hızı", + "on_hold": "Beklemede", + "playback_error": "Oynatma Hatası", + "unknown_error": "Oynatma sırasında bilinmeyen bir hata oluştu.", + "copy_error": "Hata detaylarını kopyala", + "copied_to_clipboard": "Panoya kopyalandı", + "dismiss": "Kapat", + "continue_watching": "İzlemeye Devam Et", + "start_over": "Baştan Başlat", + "resume": "Devam Et", + "change_source": "Kaynağı Değiştir", + "switching_source": "Kaynak değiştiriliyor...", + "no_sources_found": "Kaynak bulunamadı", + "sources": "Kaynaklar", + "finding_sources": "Kaynaklar aranıyor...", + "unknown_source": "Bilinmeyen Kaynak", + "sources_limited": "Sağlayıcı hataları nedeniyle kaynaklar sınırlı olabilir.", + "episodes": "Bölümler", + "specials": "Özeller", + "season": "Sezon {{season}}", + "stream": "Yayın {{number}}", + "subtitles": "Altyazılar", + "built_in": "Yerleşik", + "addons": "Eklentiler", + "style": "Stil", + "none": "Yok", + "search_online_subtitles": "Çevrimiçi Altyazı Ara", + "preview": "Önizleme", + "quick_presets": "Hızlı Şablonlar", + "default": "Varsayılan", + "yellow": "Sarı", + "high_contrast": "Yüksek Kontrast", + "large": "Büyük", + "core": "Temel", + "font_size": "Yazı Tipi Boyutu", + "show_background": "Arka Planı Göster", + "advanced": "Gelişmiş", + "position": "Konum", + "text_color": "Metin Rengi", + "align": "Hizala", + "bottom_offset": "Alt Kenar Boşluğu", + "background_opacity": "Arka Plan Saydamlığı", + "text_shadow": "Metin Gölgesi", + "on": "Açık", + "off": "Kapalı", + "outline_color": "Kenarlık Rengi", + "outline": "Kenarlık", + "outline_width": "Kenarlık Genişliği", + "letter_spacing": "Harf Boşluğu", + "line_height": "Satır Yüksekliği", + "timing_offset": "Zamanlama Kaydırma (s)", + "visual_sync": "Görsel Senkronizasyon", + "timing_hint": "Gerekirse senkronizasyon için altyazıları öne (-) veya arkaya (+) alın.", + "reset_defaults": "Varsayılana sıfırla", + "mark_intro_start": "Giriş Başlangıcını İşaretle", + "mark_intro_end": "Giriş Bitişini İşaretle", + "intro_start_marked": "Giriş başlangıcı işaretlendi", + "intro_submitted": "Giriş başarıyla gönderildi", + "intro_submit_failed": "Giriş gönderilemedi" + }, + "downloads": { + "title": "İndirmeler", + "no_downloads": "Henüz İndirme Yok", + "no_downloads_desc": "İndirilen içerikler çevrimdışı izlemek için burada görünecek", + "explore": "İçerikleri Keşfet", + "path_copied": "Yol Kopyalandı", + "path_copied_desc": "Yerel dosya yolu panoya kopyalandı", + "copied": "Kopyalandı", + "incomplete": "İndirme Tamamlanmadı", + "incomplete_desc": "İndirme henüz bitmedi", + "not_available": "Kullanılamaz", + "not_available_desc": "Yerel dosya yolu sadece indirme bittikten sonra kullanılabilir.", + "status_downloading": "İndiriliyor", + "status_completed": "Tamamlandı", + "status_paused": "Duraklatıldı", + "status_error": "Hata", + "status_queued": "Sırada", + "status_unknown": "Bilinmiyor", + "provider": "Sağlayıcı", + "streaming_playlist_warning": "Oynatılamayabilir - akış listesi", + "remaining": "kaldı", + "not_ready": "İndirme hazır değil", + "not_ready_desc": "Lütfen indirme bitene kadar bekleyin.", + "filter_all": "Hepsi", + "filter_active": "Aktif", + "filter_done": "Bitenler", + "filter_paused": "Duraklatılanlar", + "no_filter_results": "{{filter}} indirme yok", + "try_different_filter": "Farklı bir filtre seçmeyi deneyin", + "limitations_title": "İndirme Kısıtlamaları", + "limitations_msg": "• 1MB'dan küçük dosyalar genellikle M3U8 akış listeleridir ve çevrimdışı izlemek için indirilemezler. Bunlar sadece çevrimiçi akışla çalışır ve gerçek video içeriğini değil, video parçalarının bağlantılarını içerir.", + "remove_title": "İndirmeyi Kaldır", + "remove_confirm": "\"{{title}}\"{{season_episode}} kaldırılsın mı?", + "cancel": "İptal", + "remove": "Kaldır" + }, + "addons": { + "title": "Eklentiler", + "reorder_mode": "Yeniden Sıralama Modu", + "reorder_info": "Üstteki eklentiler içerik yüklenirken daha yüksek önceliğe sahiptir", + "add_addon_placeholder": "Eklenti URL'si", + "add_button": "Eklenti Ekle", + "my_addons": "Eklentilerim", + "community_addons": "Topluluk Eklentileri", + "no_addons": "Yüklü eklenti yok", + "uninstall_title": "Eklentiyi Kaldır", + "uninstall_message": "{{name}} eklentisini kaldırmak istediğinize emin misiniz?", + "uninstall_button": "Kaldır", + "install_success": "Eklenti başarıyla yüklendi", + "install_error": "Eklenti yüklenemedi", + "load_error": "Eklentiler yüklenemedi", + "fetch_error": "Eklenti detayları alınamadı", + "invalid_url": "Lütfen geçerli bir eklenti URL'si girin", + "configure": "Yapılandır", + "version": "Sürüm: {{version}}", + "installed_addons": "YÜKLÜ EKLENTİLER", + "reorder_drag_title": "SIRALAMAK İÇİN EKLENTİLERİ SÜRÜKLEYİN", + "install": "Yükle", + "config_unavailable_title": "Yapılandırma Kullanılamıyor", + "config_unavailable_msg": "Bu eklenti için yapılandırma URL'si belirlenemedi.", + "cannot_open_config_title": "Yapılandırma Açılamıyor", + "cannot_open_config_msg": "Yapılandırma URL'si ({{url}}) açılamıyor. Eklentinin bir yapılandırma sayfası olmayabilir.", + "description": "Açıklama", + "supported_types": "Desteklenen Türler", + "catalogs": "Kataloglar", + "no_description": "Açıklama mevcut değil", + "overview": "GENEL BAKIŞ", + "no_categories": "Kategori yok", + "pre_installed": "ÖNCEDEN YÜKLENMİŞ" + }, + "trakt": { + "title": "Trakt Ayarları", + "settings_title": "Trakt Ayarları", + "connect_title": "Trakt ile Bağlan", + "connect_desc": "İzleme geçmişinizi, izleme listenizi ve koleksiyonunuzu Trakt.tv ile senkronize edin", + "sign_in": "Trakt ile Giriş Yap", + "sign_out": "Oturumu Kapat", + "sign_out_confirm": "Trakt hesabınızdan çıkış yapmak istediğinize emin misiniz?", + "joined": "{{date}} tarihinde katıldı", + "sync_settings_title": "Senkronizasyon Ayarları", + "sync_info": "Trakt'a bağlandığında, tam geçmiş doğrudan API üzerinden senkronize edilir ve yerel depolamaya yazılmaz. İzlemeye Devam Et listeniz küresel Trakt ilerlemenizi yansıtır.", + "auto_sync_label": "Oynatma ilerlemesini otomatik senkronize et", + "auto_sync_desc": "İzleme ilerlemesini otomatik olarak Trakt'a senkronize et", + "import_history_label": "İzleme geçmişini içe aktar", + "import_history_desc": "İzleme geçmişinizi ve ilerlemenizi Trakt'tan içe aktarmak için \"Şimdi Senkronize Et\" butonunu kullanın", + "sync_now_button": "Şimdi Senkronize Et", + "display_settings_title": "Görüntüleme Ayarları", + "show_comments_label": "Trakt Yorumlarını Göster", + "show_comments_desc": "Mevcut olduğunda meta veri ekranlarında Trakt yorumlarını görüntüle", + "maintenance_title": "Bakım Yapılıyor", + "maintenance_unavailable": "Trakt Kullanılamıyor", + "maintenance_desc": "Trakt entegrasyonu bakım nedeniyle geçici olarak durduruldu. Bakım tamamlanana kadar tüm senkronizasyon ve kimlik doğrulama işlemleri devre dışıdır.", + "maintenance_button": "Hizmet Bakımda", + "auth_success_title": "Başarıyla Bağlanıldı", + "auth_success_msg": "Trakt hesabınız başarıyla bağlandı.", + "auth_error_title": "Kimlik Doğrulama Hatası", + "auth_error_msg": "Trakt ile kimlik doğrulama tamamlanamadı.", + "auth_error_generic": "Kimlik doğrulama sırasında bir hata oluştu.", + "sign_out_error": "Trakt oturumu kapatılamadı.", + "sync_complete_title": "Senkronizasyon Tamamlandı", + "sync_success_msg": "İzleme ilerlemeniz Trakt ile başarıyla senkronize edildi.", + "sync_error_msg": "Senkronizasyon başarısız oldu. Lütfen tekrar deneyin." + }, + "simkl": { + "title": "Simkl Ayarları", + "settings_title": "Simkl Ayarları", + "connect_title": "Simkl ile Bağlan", + "connect_desc": "İzleme geçmişinizi senkronize edin ve ne izlediğinizi takip edin", + "sign_in": "Simkl ile Giriş Yap", + "sign_out": "Bağlantıyı Kes", + "sign_out_confirm": "Simkl bağlantısını kesmek istediğinize emin misiniz?", + "syncing_desc": "İzlediğiniz öğeler Simkl ile senkronize ediliyor.", + "auth_success_title": "Başarıyla Bağlanıldı", + "auth_success_msg": "Simkl hesabınız başarıyla bağlandı.", + "auth_error_title": "Kimlik Doğrulama Hatası", + "auth_error_msg": "Simkl ile kimlik doğrulama tamamlanamadı.", + "auth_error_generic": "Kimlik doğrulama sırasında bir hata oluştu.", + "sign_out_error": "Simkl bağlantısı kesilemedi.", + "config_error_title": "Yapılandırma Hatası", + "config_error_msg": "Ortam değişkenlerinde Simkl Client ID eksik.", + "conflict_title": "Çakışma", + "conflict_msg": "Trakt bağlıyken Simkl'e bağlanamazsınız. Lütfen önce Trakt bağlantısını kesin.", + "disclaimer": "Nuvio'nun Simkl ile bir bağlantısı yoktur." + }, + "tmdb_settings": { + "title": "TMDb Ayarları", + "metadata_enrichment": "Meta Veri Zenginleştirme", + "metadata_enrichment_desc": "Daha iyi detaylar ve bilgiler için içerik meta verilerinizi TMDb verileriyle geliştirin.", + "enable_enrichment": "Zenginleştirmeyi Etkinleştir", + "enable_enrichment_desc": "Oyuncular, sertifikalar, logolar/afişler ve yapım bilgileri için eklenti meta verilerini TMDb ile güçlendirir.", + "localized_text": "Yerelleştirilmiş Metin", + "localized_text_desc": "Başlıkları ve açıklamaları TMDb'den tercih ettiğiniz dilde getirin.", + "language": "Dil", + "change": "Değiştir", + "logo_preview": "Logo Önizleme", + "logo_preview_desc": "Önizleme, yerelleştirilmiş logoların seçilen dilde nasıl görüneceğini gösterir.", + "example": "Örnek:", + "no_logo": "Logo mevcut değil", + "enrichment_options": "Zenginleştirme Seçenekleri", + "enrichment_options_desc": "Hangi verilerin TMDb'den getirileceğini kontrol edin. Devre dışı bırakılan seçenekler varsa eklenti verilerini kullanacaktır.", + "cast_crew": "Oyuncular ve Ekip", + "cast_crew_desc": "Profil fotoğraflarıyla birlikte oyuncular, yönetmenler, yazarlar", + "title_description": "Başlık ve Açıklama", + "title_description_desc": "TMDb yerelleştirilmiş başlığını ve genel bakış metnini kullan", + "title_logos": "Başlık Logoları", + "title_logos_desc": "Yüksek kaliteli başlık tasarım görselleri", + "banners_backdrops": "Bannerlar ve Arka Planlar", + "banners_backdrops_desc": "Yüksek çözünürlüklü arka plan görselleri", + "certification": "İçerik Sertifikasyonu", + "certification_desc": "Yaş derecelendirmeleri (PG-13, R, TV-MA, vb.)", + "recommendations": "Öneriler", + "recommendations_desc": "Benzer içerik önerileri", + "episode_data": "Bölüm Verileri", + "episode_data_desc": "TV şovları için bölüm küçük resimleri, bilgiler ve yedek veriler", + "season_posters": "Sezon Afişleri", + "season_posters_desc": "Sezona özel afiş görselleri", + "production_info": "Yapım Bilgisi", + "production_info_desc": "Logolarıyla birlikte kanallar ve yapım şirketleri", + "movie_details": "Film Detayları", + "movie_details_desc": "Bütçe, hasılat, süre, slogan", + "tv_details": "TV Programı Detayları", + "tv_details_desc": "Durum, sezon sayısı, kanallar, yaratıcılar", + "movie_collections": "Film Koleksiyonları", + "movie_collections_desc": "Seri filmler (Marvel, Star Wars, vb.)", + "api_configuration": "API Yapılandırması", + "api_configuration_desc": "Gelişmiş işlevsellik için TMDb API erişiminizi yapılandırın.", + "custom_api_key": "Özel API Anahtarı", + "custom_api_key_desc": "Daha iyi performans ve özel limitler için kendi TMDb API anahtarınızı kullanın.", + "custom_key_active": "Özel API anahtarı aktif", + "api_key_required": "API anahtarı gerekli", + "api_key_placeholder": "TMDb API anahtarınızı yapıştırın (v3)", + "how_to_get_key": "TMDb API anahtarı nasıl alınır?", + "built_in_key_msg": "Şu anda yerleşik API anahtarı kullanılıyor. Daha iyi performans için kendi anahtarınızı kullanmayı düşünebilirsiniz.", + "cache_size": "Önbellek Boyutu", + "clear_cache": "Önbelleği Temizle", + "cache_days": "Performansı artırmak için TMDB yanıtları 7 gün boyunca önbelleğe alınır", + "choose_language": "Dil Seçin", + "choose_language_desc": "TMDb içeriği için tercih ettiğiniz dili seçin", + "popular": "Popüler", + "all_languages": "Tüm Diller", + "search_results": "Arama Sonuçları", + "no_languages_found": "\"{{query}}\" için dil bulunamadı", + "clear_search": "Aramayı Temizle", + "clear_cache_title": "TMDB Önbelleğini Temizle", + "clear_cache_msg": "Bu işlem tüm önbelleğe alınmış TMDB verilerini ({{size}}) temizleyecektir. Önbellek yeniden oluşturulana kadar yükleme geçici olarak yavaşlayabilir.", + "clear_cache_success": "TMDB önbelleği başarıyla temizlendi.", + "clear_cache_error": "Önbellek temizlenemedi.", + "clear_api_key_title": "API Anahtarını Temizle", + "clear_api_key_msg": "Özel API anahtarınızı kaldırıp varsayılana dönmek istediğinize emin misiniz?", + "clear_api_key_success": "API anahtarı başarıyla temizlendi", + "clear_api_key_error": "API anahtarı temizlenemedi", + "empty_api_key": "API Anahtarı boş olamaz.", + "invalid_api_key": "Geçersiz API anahtarı. Lütfen kontrol edip tekrar deneyin.", + "save_error": "Kaydetme sırasında bir hata oluştu. Lütfen tekrar deneyin.", + "using_builtin_key": "Şimdi yerleşik TMDb API anahtarı kullanılıyor.", + "using_custom_key": "Şimdi özel TMDb API anahtarınız kullanılıyor.", + "enter_custom_key": "Lütfen özel TMDb API anahtarınızı girin ve kaydedin.", + "key_verified": "API anahtarı doğrulandı ve başarıyla kaydedildi." + }, + "settings": { + "language": "Dil", + "select_language": "Dil Seçin", + "english": "İngilizce", + "portuguese": "Portekizce", + "portuguese_br": "Portekizce (Brezilya)", + "portuguese_pt": "Portekizce (Portekiz)", + "german": "Almanca", + "arabic": "Arapça", + "spanish": "İspanyolca", + "french": "Fransızca", + "italian": "İtalyanca", + "croatian": "Hırvatça", + "chinese": "Çince (Basitleştirilmiş)", + "hindi": "Hintçe", + "serbian": "Sırpça", + "hebrew": "İbranice", + "bulgarian": "Bulgarca", + "polish": "Polonyaca", + "czech": "Çekçe", + "turkish": "Türkçe", + "slovenian": "Slovence", + "macedonian": "Makedonca", + "russian": "Rusça", + "filipino": "Filipince", + "dutch_nl": "Felemenkçe (Hollanda)", + "romanian": "Rumence", + "albanian": "Arnavutça", + "account": "Hesap", + "content_discovery": "İçerik ve Keşif", + "appearance": "Görünüm", + "integrations": "Entegrasyonlar", + "playback": "Oynatma", + "backup_restore": "Yedekle ve Geri Yükle", + "updates": "Güncellemeler", + "about": "Hakkında", + "developer": "Geliştirici", + "cache": "Önbellek", + "title": "Ayarlar", + "settings_title": "Ayarlar", + "sign_in_sync": "Senkronizasyon için giriş yapın", + "add_catalogs_sources": "Eklentiler, kataloglar ve kaynaklar", + "player_trailers_downloads": "Oynatıcı, fragmanlar, indirmeler", + "mdblist_tmdb_ai": "MDBList, TMDB, AI", + "check_updates": "Güncellemeleri kontrol et", + "clear_mdblist_cache": "MDBList Önbelleğini Temizle", + "cache_management": "ÖNBELLEK YÖNETİMİ", + "downloads_counter": "indirme ve artıyor", + "made_with_love": "Tapframe ve arkadaşları tarafından ❤️ ile yapıldı", + "sections": { + "information": "BİLGİ", + "account": "HESAP", + "theme": "TEMA", + "layout": "DÜZEN", + "sources": "KAYNAKLAR", + "catalogs": "KATALOGLAR", + "discovery": "KEŞİF", + "metadata": "META VERİ", + "ai_assistant": "AI ASİSTANI", + "video_player": "VİDEO OYNATICI", + "audio_subtitles": "SES VE ALTYAZI", + "media": "MEDYA", + "notifications": "BİLDİRİMLER", + "testing": "TEST", + "danger_zone": "TEHLİKELİ BÖLGE" + }, + "items": { + "legal": "Yasal ve Sorumluluk Reddi", + "privacy_policy": "Gizlilik Politikası", + "report_issue": "Sorun Bildir", + "version": "Sürüm", + "contributors": "Katkıda Bulunanlar", + "view_contributors": "Tüm katkıda bulunanları gör", + "theme": "Tema", + "episode_layout": "Bölüm Düzeni", + "streams_backdrop": "Yayın Arka Planı", + "streams_backdrop_desc": "Mobil yayınlarda bulanık arka plan göster", + "addons": "Eklentiler", + "installed": "yüklü", + "debrid_integration": "Debrid Entegrasyonu", + "debrid_desc": "Torbox'ı bağla", + "plugins": "Eklentiler", + "plugins_desc": "Eklentileri ve depoları yönet", + "catalogs": "Kataloglar", + "active": "aktif", + "home_screen": "Ana Ekran", + "home_screen_desc": "Düzen ve içerik", + "continue_watching": "İzlemeye Devam Et", + "continue_watching_desc": "Önbellek ve oynatma davranışı", + "show_discover": "Keşfet Bölümünü Göster", + "show_discover_desc": "Aramada keşif içeriğini görüntüle", + "mdblist": "MDBList", + "mdblist_connected": "Bağlı", + "mdblist_desc": "Puanlar ve incelemeler eklemek için etkinleştir", + "simkl": "Simkl", + "simkl_connected": "Bağlı", + "simkl_desc": "İzlediklerini takip et", + "tmdb": "TMDB", + "tmdb_desc": "Meta veri ve logo kaynağı sağlayıcısı", + "openrouter": "OpenRouter API", + "openrouter_connected": "Bağlı", + "openrouter_desc": "AI sohbetini etkinleştirmek için API anahtarınızı ekleyin", + "video_player": "Video Oynatıcı", + "built_in": "Yerleşik", + "external": "Harici", + "preferred_audio": "Tercih Edilen Ses Dili", + "preferred_subtitle": "Tercih Edilen Altyazı Dili", + "subtitle_source": "Altyazı Kaynak Önceliği", + "auto_select_subs": "Altyazıları Otomatik Seç", + "auto_select_subs_desc": "Tercihlerinize uygun altyazıları otomatik olarak seç", + "show_trailers": "Fragmanları Göster", + "show_trailers_desc": "Hero bölümünde fragmanları görüntüle", + "enable_downloads": "İndirmeleri Etkinleştir", + "enable_downloads_desc": "İndirmeler sekmesini göster ve yayınları kaydetmeyi etkinleştir", + "notifications": "Bildirimler", + "notifications_desc": "Bölüm hatırlatıcıları", + "developer_tools": "Geliştirici Araçları", + "developer_tools_desc": "Test ve hata ayıklama seçenekleri", + "test_onboarding": "Başlangıç Rehberini Test Et", + "reset_onboarding": "Başlangıç Rehberini Sıfırla", + "test_announcement": "Duyuruyu Test Et", + "test_announcement_desc": "Yenilikler katmanını göster", + "reset_campaigns": "Kampanyaları Sıfırla", + "reset_campaigns_desc": "Kampanya gösterimlerini temizle", + "clear_all_data": "Tüm Verileri Temizle", + "clear_all_data_desc": "Tüm ayarları ve önbelleğe alınmış verileri sıfırla" + }, + "options": { + "horizontal": "Yatay", + "vertical": "Dikey", + "internal_first": "Önce Dahili", + "internal_first_desc": "Önce gömülü altyazıları, sonra haricileri tercih et", + "external_first": "Önce Harici", + "external_first_desc": "Önce eklenti altyazılarını, sonra gömülüleri tercih et", + "any_available": "Herhangi Biri", + "any_available_desc": "Mevcut olan ilk altyazı kanalını kullan" + }, + "clear_data_desc": "Bu işlem tüm ayarları sıfırlayacak ve tüm önbelleği temizleyecektir. Emin misiniz?", + "app_updates": "Uygulama Güncellemeleri", + "about_nuvio": "Nuvio Hakkında" + }, + "privacy": { + "title": "Gizlilik ve Veri", + "settings_desc": "Telemetri ve veri toplama ayarlarını kontrol edin", + "info_title": "Gizliliğiniz Önemlidir", + "info_description": "Hangi verilerin toplanıp paylaşılacağını kontrol edin. Analitikler varsayılan olarak kapalıdır ve hata raporları varsayılan olarak anonimdir.", + "analytics_enabled_title": "Analitik Etkinleştirildi", + "analytics_enabled_message": "Uygulamayı geliştirmeye yardımcı olmak için kullanım verileri toplanacaktır. Bunu istediğiniz zaman devre dışı bırakabilirsiniz.", + "disable_error_reporting_title": "Hata Bildirimi Devre Dışı Bırakılsın mı?", + "disable_error_reporting_message": "Hata bildirimini devre dışı bırakmak, yaşadığınız çökmelerden veya sorunlardan haberdar olamayacağımız anlamına gelir. Bu, hataları düzeltme yeteneğimizi etkileyebilir.", + "enable_session_replay_title": "Oturum Tekrarı Etkinleştirilsin mi?", + "enable_session_replay_message": "Oturum tekrarı, ne olduğunu anlamamıza yardımcı olmak için hatalar oluştuğunda ekranınızı kaydeder. Bu, ekranınızdaki görünür içeriği yakalayabilir.", + "enable_pii_title": "PII Koleksiyonu Etkinleştirilsin mi?", + "enable_pii_message": "Bu, IP adresi ve cihaz detayları gibi kişisel olarak tanımlanabilir bilgilerin toplanmasına izin verir. Bu veriler sorunları teşhis etmeye yardımcı olur ancak gizlilik maruziyetini artırır.", + "disable_all_title": "Tüm Telemetri Devre Dışı Bırakılsın mı?", + "disable_all_message": "Bu, tüm analitikleri, hata bildirimlerini ve oturum tekrarlarını devre dışı bırakacaktır. Uygulama kullanımı veya çökmeler hakkında herhangi bir veri almayacağız.", + "disable_all_button": "Hepsini Devre Dışı Bırak", + "all_disabled_title": "Tüm Telemetri Devre Dışı Bırakıldı", + "all_disabled_message": "Tüm veri toplama işlemleri devre dışı bırakıldı. Değişiklikler uygulama bir sonraki başlatıldığında geçerli olacaktır.", + "reset_title": "Önerilen Ayarlara Sıfırla", + "reset_message": "Gizlilik ayarları önerilen varsayılanlara sıfırlandı (hata bildirimi etkin, analitik devre dışı).", + "section_analytics": "ANALİTİK", + "analytics_title": "Kullanım Analitiği", + "analytics_description": "Anonim kullanım kalıplarını ve ekran görüntülerini topla", + "section_error_reporting": "HATA BİLDİRİMİ", + "error_reporting_title": "Çökme Raporları", + "error_reporting_description": "Kararlılığı artırmak için anonim çökme raporları gönder", + "session_replay_title": "Oturum Tekrarı", + "session_replay_description": "Hatalar oluştuğunda ekranı kaydet", + "pii_title": "Cihaz Bilgisini Dahil Et", + "pii_description": "Raporlarla birlikte IP adresi ve cihaz detaylarını gönder", + "section_quick_actions": "HIZLI EYLEMLER", + "disable_all": "Tüm Telemetriyi Kapat", + "disable_all_desc": "Tüm veri toplamayı kapat", + "reset_recommended": "Önerilene Sıfırla", + "reset_recommended_desc": "Hata bildirimi içeren gizlilik odaklı varsayılanlar", + "section_learn_more": "DAHA FAZLA BİLGİ", + "privacy_policy": "Gizlilik Politikası", + "current_settings": "Mevcut Ayarlar Özeti", + "summary_analytics": "Analitik", + "summary_errors": "Hata Raporları", + "summary_replay": "Oturum Tekrarı", + "summary_pii": "Cihaz Bilgisi", + "restart_note_detailed": "* Analitik ve hata bildirimi değişiklikleri anında geçerli olur. Oturum tekrarı ve PII ayarları uygulama yeniden başlatılmasını gerektirir." + }, + "ai_settings": { + "title": "AI Asistanı", + "info_title": "AI Destekli Sohbet", + "info_desc": "Gelişmiş yapay zeka kullanarak herhangi bir film veya TV dizisi bölümü hakkında sorular sorun. Konu, karakterler, temalar, trivia ve daha fazlası hakkında -tamamı kapsamlı TMDB verileriyle desteklenen- bilgiler edinin.", + "feature_1": "Bölüme özel bağlam ve analiz", + "feature_2": "Konu açıklamaları ve karakter içgörüleri", + "feature_3": "Kamera arkası trivia ve gerçekler", + "feature_4": "Kendi ücretsiz OpenRouter API anahtarınız", + "api_key_section": "OPENROUTER API ANAHTARI", + "api_key_label": "API Anahtarı", + "api_key_desc": "AI sohbet özelliklerini etkinleştirmek için OpenRouter API anahtarınızı girin", + "save_api_key": "API Anahtarını Kaydet", + "saving": "Kaydediliyor...", + "update": "Güncelle", + "remove": "Kaldır", + "get_free_key": "OpenRouter'dan Ücretsiz API Anahtarı Al", + "enable_chat": "AI Sohbeti Etkinleştir", + "enable_chat_desc": "Etkinleştirildiğinde, içerik sayfalarında AI'ya Sor butonu görünecektir.", + "chat_enabled": "AI Sohbet Etkin", + "chat_enabled_desc": "Artık filmler ve TV şovları hakkında sorular sorabilirsiniz. İçerik sayfalarındaki \"AI'ya Sor\" butonuna bakın!", + "how_it_works": "Nasıl çalışır?", + "how_it_works_desc": "• OpenRouter birden fazla AI modeline erişim sağlar\n• API anahtarınız gizli ve güvenli kalır\n• Ücretsiz katman cömert kullanım limitleri içerir\n• Belirli bölümler/filmler hakkında bağlamla sohbet edin\n• Detaylı analiz ve açıklamalar alın", + "error_invalid_key": "Lütfen geçerli bir API anahtarı girin", + "error_key_format": "OpenRouter API anahtarları \"sk-or-\" ile başlamalıdır", + "success_saved": "OpenRouter API anahtarı başarıyla kaydedildi!", + "error_save": "API anahtarı kaydedilemedi", + "confirm_remove_title": "API Anahtarını Kaldır", + "confirm_remove_msg": "OpenRouter API anahtarınızı kaldırmak istediğinize emin misiniz? Bu, AI sohbet özelliklerini devre dışı bırakacaktır.", + "success_removed": "API anahtarı başarıyla kaldırıldı", + "error_remove": "API anahtarı kaldırılamadı" + }, + "catalog_settings": { + "title": "Kataloglar", + "layout_phone": "KATALOG EKRANI DÜZENİ (TELEFON)", + "posters_per_row": "Satır başına afiş", + "auto": "Otomatik", + "show_titles": "Afiş Başlıklarını Göster", + "show_titles_desc": "Her afişin altında başlık metnini görüntüle", + "phone_only_hint": "Yalnızca telefonlar için geçerlidir. Tabletler uyarlanabilir düzeni korur.", + "catalogs_group": "Kataloglar", + "enabled_count": "{{total}} katalogdan {{enabled}} tanesi etkin", + "rename_hint": "Yeniden adlandırmak için bir kataloğa uzun basın", + "rename_modal_title": "Kataloğu Yeniden Adlandır", + "rename_placeholder": "Yeni katalog adını girin", + "error_save_name": "Özel ad kaydedilemedi." + }, + "continue_watching_settings": { + "title": "İzlemeye Devam Et", + "playback_behavior": "OYNATMA DAVRANIŞI", + "use_cached": "Önbelleğe Alınmış Yayınları Kullan", + "use_cached_desc": "Etkinleştirildiğinde, İzlemeye Devam Et öğelerine tıklamak, önceden oynatılan yayınları kullanarak oynatıcıyı doğrudan açar. Devre dışı bırakıldığında ise içerik ekranını açar.", + "open_metadata": "Meta Veri Ekranını Aç", + "open_metadata_desc": "Önbelleğe alınmış yayınlar devre dışı bırakıldığında, Yayınlar ekranı yerine Meta Veri ekranını açar. Bu, içerik detaylarını gösterir ve manuel yayın seçimine izin verir.", + "card_appearance": "KART GÖRÜNÜMÜ", + "card_style": "Kart Stili", + "card_style_desc": "İzlemeye Devam Et öğelerinin ana ekranda nasıl görüneceğini seçin", + "wide": "Geniş", + "poster": "Afiş", + "cache_settings": "ÖNBELLEK AYARLARI", + "cache_duration": "Yayın Önbellek Süresi", + "cache_duration_desc": "Önbelleğe alınmış yayın bağlantılarının süresi dolmadan ne kadar süre saklanacağı", + "important_note": "Önemli Not", + "important_note_text": "Tüm yayın bağlantıları tam önbellek süresi boyunca aktif kalmayabilir. Daha uzun önbellek süreleri süresi dolmuş bağlantılara neden olabilir. Önbelleğe alınmış bir bağlantı başarısız olursa, uygulama yeni yayınları getirmeye geri dönecektir.", + "how_it_works": "Nasıl çalışır?", + "how_it_works_cached": "• Yayınlar oynatıldıktan sonra seçtiğiniz süre boyunca önbelleğe alınır\n• Önbelleğe alınan yayınlar kullanılmadan önce doğrulanır\n• Önbellek geçersizse veya süresi dolmuşsa içerik ekranına döner\n• \"Önbelleğe Alınmış Yayınları Kullan\" doğrudan oynatıcı vs ekran navigasyonunu kontrol eder\n• \"Meta Veri Ekranını Aç\" seçeneği yalnızca önbelleğe alınmış yayınlar devre dışı bırakıldığında görünür", + "how_it_works_uncached": "• Önbelleğe alınmış yayınlar devre dışı bırakıldığında, İzlemeye Devam Et öğelerine tıklamak içerik ekranlarını açar\n• \"Meta Veri Ekranını Aç\" seçeneği hangi ekranın açılacağını kontrol eder\n• Meta Veri ekranı içerik detaylarını gösterir ve manuel yayın seçimine izin verir\n• Yayınlar ekranı hemen oynatma için mevcut yayınları gösterir", + "changes_saved": "Değişiklikler kaydedildi", + "min": "dk", + "hour": "saat", + "hours": "saat" + }, + "contributors": { + "title": "Katkıda Bulunanlar", + "special_mentions": "Özel Mansiyonlar", + "tab_contributors": "Katkıda Bulunanlar", + "tab_special": "Özel Mansiyonlar", + "tab_donors": "Bağışçılar", + "manager_role": "Topluluk Yöneticisi", + "manager_desc": "Nuvio için Discord ve Reddit topluluklarını yönetir", + "sponsor_role": "Sunucu Sponsoru", + "sponsor_desc": "Nuvio için sunucu altyapısına sponsor oldu", + "mod_role": "Discord Moderatörü", + "mod_desc": "Nuvio Discord topluluğunun yönetilmesine yardımcı olur", + "loading": "Yükleniyor...", + "discord_user": "Discord Kullanıcısı", + "contributions": "katkı", + "gratitude_title": "Her katkı için minnettarız", + "gratitude_desc": "Her kod satırı, hata raporu ve öneri Nuvio'yu herkes için daha iyi hale getirmeye yardımcı olur", + "special_thanks_title": "Özel Teşekkürler", + "special_thanks_desc": "Bu harika insanlar Nuvio topluluğunun devam etmesine ve sunucuların çevrimiçi kalmasına yardımcı oluyor", + "donors_desc": "İnşa ettiğimiz şeye inandığınız için teşekkür ederiz. Desteğiniz Nuvio'nun ücretsiz kalmasını ve sürekli gelişmesini sağlıyor.", + "latest_donations": "En Son", + "leaderboard": "Liderlik Tablosu", + "loading_donors": "Bağışçılar yükleniyor…", + "no_donors": "Henüz bağışçı yok", + "error_rate_limit": "GitHub API hız sınırı aşıldı. Lütfen daha sonra tekrar deneyin veya yenilemek için aşağı çekin.", + "error_failed": "Katkıda bulunanlar yüklenemedi. Lütfen internet bağlantınızı kontrol edin.", + "retry": "Tekrar Dene", + "no_contributors": "Katkıda bulunan bulunamadı", + "loading_contributors": "Katkıda bulunanlar yükleniyor..." + }, + "debrid": { + "title": "Debrid Entegrasyonu", + "description_torbox": "Torbox'ı entegre ederek 4K yüksek kaliteli yayınların ve yıldırım hızındaki hızların kilidini açın. Yayın deneyiminizi anında yükseltmek için aşağıya API Anahtarınızı girin.", + "description_torrentio": "Filmler ve TV şovları için torrent yayınları almak üzere Torrentio'yu yapılandırın. İçeriği yayınlamak için bir debrid hizmeti gereklidir.", + "tab_torbox": "TorBox", + "tab_torrentio": "Torrentio", + "status_connected": "Bağlı", + "status_disconnected": "Bağlantı Kesildi", + "enable_addon": "Eklentiyi Etkinleştir", + "disconnect_button": "Bağlantıyı Kes ve Kaldır", + "disconnect_loading": "Bağlantı kesiliyor...", + "account_info": "Hesap Bilgileri", + "plan": "Plan", + "plan_free": "Ücretsiz", + "plan_essential": "Essential ($3/ay)", + "plan_pro": "Pro ($10/ay)", + "plan_standard": "Standard ($5/ay)", + "plan_unknown": "Bilinmiyor", + "expires": "Sona Erme", + "downloaded": "İndirilen", + "status_active": "Aktif", + "connected_title": "✓ TorBox'a Bağlanıldı", + "connected_desc": "TorBox eklentiniz aktif ve premium yayınlar sağlıyor.", + "configure_title": "Eklentiyi Yapılandır", + "configure_desc": "Yayın deneyiminizi özelleştirin. Kaliteye göre sıralayın, dosya boyutlarını filtreleyin ve diğer entegrasyon ayarlarını yönetin.", + "open_settings": "Ayarları Aç", + "what_is_debrid": "Debrid Hizmeti Nedir?", + "enter_api_key": "API Anahtarınızı Girin", + "connect_button": "Bağlan ve Yükle", + "connecting": "Bağlanıyor...", + "unlock_speeds_title": "Premium Hızların Kilidini Açın", + "unlock_speeds_desc": "Sıfır ara belleğe alma ile önbelleğe alınmış yüksek kaliteli yayınlara erişmek için bir Torbox aboneliği edinin.", + "get_subscription": "Abonelik Al", + "powered_by": "Destekleyen", + "disclaimer_torbox": "Nuvio'nun hiçbir şekilde Torbox ile bağlantısı yoktur.", + "disclaimer_torrentio": "Nuvio'nun hiçbir şekilde Torrentio ile bağlantısı yoktur.", + "installed_badge": "✓ YÜKLENDİ", + "promo_title": "⚡ Bir Debrid Hizmetine mi İhtiyacınız Var?", + "promo_desc": "Sıfır ara belleğe alma ile yıldırım hızında 4K yayın için TorBox edinin. Premium önbelleğe alınmış torrentler ve anında indirmeler.", + "promo_button": "TorBox Aboneliği Al", + "service_label": "Debrid Hizmeti *", + "api_key_label": "API Anahtarı *", + "sorting_label": "Sıralama", + "exclude_qualities": "Kaliteleri Hariç Tut", + "priority_languages": "Öncelikli Diller", + "max_results": "Maksimum Sonuç", + "additional_options": "Ek Seçenekler", + "no_download_links": "İndirme bağlantılarını gösterme", + "no_debrid_catalog": "Debrid kataloğunu gösterme", + "install_button": "Torrentio Yükle", + "installing": "Yükleniyor...", + "update_button": "Yapılandırmayı Güncelle", + "updating": "Güncelleniyor...", + "remove_button": "Torrentio'yu Kaldır", + "error_api_required": "API Anahtarı Gerekli", + "error_api_required_desc": "Torrentio'yu yüklemek için lütfen debrid hizmeti API anahtarınızı girin.", + "success_installed": "Torrentio eklentisi başarıyla yüklendi!", + "success_removed": "Torrentio eklentisi başarıyla kaldırıldı", + "alert_disconnect_title": "Torbox Bağlantısını Kes", + "alert_disconnect_msg": "Torbox bağlantısını kesmek istediğinize emin misiniz? Bu işlem eklentiyi kaldıracak ve kaydedilmiş API anahtarınızı silecektir." + }, + "home_screen": { + "title": "Home Screen Settings", + "changes_applied": "Changes Applied", + "display_options": "DISPLAY OPTIONS", + "show_hero": "Show Hero Section", + "show_hero_desc": "Featured content at the top", + "show_this_week": "Show This Week Section", + "show_this_week_desc": "New episodes from current week", + "select_catalogs": "Select Catalogs", + "all_catalogs": "All catalogs", + "selected": "selected", + "hero_layout": "Hero Layout", + "layout_legacy": "Legacy", + "layout_carousel": "Carousel", + "layout_appletv": "Apple TV", + "layout_desc": "Full-width banner, swipeable cards, or Apple TV style", + "featured_source": "Featured Source", + "using_catalogs": "Using Catalogs", + "manage_selected_catalogs": "Manage selected catalogs", + "dynamic_bg": "Dynamic Hero Background", + "dynamic_bg_desc": "Blurred banner behind carousel", + "performance_note": "May impact performance on low-end devices.", + "posters": "Posters", + "show_titles": "Show Titles", + "poster_size": "Poster Size", + "poster_corners": "Poster Corners", + "size_small": "Small", + "size_medium": "Medium", + "size_large": "Large", + "corners_square": "Square", + "corners_rounded": "Rounded", + "corners_pill": "Pill", + "about_these_settings": "ABOUT THESE SETTINGS", + "about_desc": "These settings control how content is displayed on your Home screen. Changes are applied immediately without requiring an app restart.", + "hero_catalogs": { + "title": "Hero Section Catalogs", + "select_all": "Select All", + "clear_all": "Clear All", + "info": "Select which catalogs to display in the hero section. If none are selected, all catalogs will be used. Don't forget to press Save when you're done.", + "settings_saved": "Settings Saved", + "error_load": "Failed to load catalogs", + "movies": "Movies", + "tv_shows": "TV Shows" + } + }, + "calendar": { + "title": "Calendar", + "loading": "Loading calendar...", + "no_scheduled_episodes": "No scheduled episodes", + "check_back_later": "Check back later", + "showing_episodes_for": "Showing episodes for {{date}}", + "show_all_episodes": "Show All Episodes", + "no_episodes_for": "No episodes for {{date}}", + "no_upcoming_found": "No upcoming episodes found", + "add_series_desc": "Add series to your library to see their upcoming episodes here" + }, + "mdblist": { + "title": "Rating Sources", + "status_disabled": "MDBList Disabled", + "status_active": "API Key Active", + "status_required": "API Key Required", + "status_disabled_desc": "MDBList functionality is currently disabled.", + "status_active_desc": "Ratings from MDBList are enabled.", + "status_required_desc": "Add your key below to enable ratings.", + "enable_toggle": "Enable MDBList", + "enable_toggle_desc": "Turn on/off all MDBList functionality", + "api_section": "API Key", + "placeholder": "Paste your MDBList API key", + "save": "Save", + "clear": "Clear Key", + "rating_providers": "Rating Providers", + "rating_providers_desc": "Choose which ratings to display in the app", + "how_to": "How to get an API key", + "step_1": "Log in on the", + "step_1_link": "MDBList website", + "step_2": "Go to", + "step_2_settings": "Settings", + "step_2_api": "API", + "step_2_end": "section.", + "step_3": "Generate a new key and copy it.", + "go_to_website": "Go to MDBList", + "alert_clear_title": "Clear API Key", + "alert_clear_msg": "Are you sure you want to remove the saved API key?", + "success_saved": "API key saved successfully.", + "error_empty": "API Key cannot be empty.", + "error_save": "An error occurred while saving. Please try again.", + "api_key_empty_error": "API Key cannot be empty.", + "success_cleared": "API key cleared successfully", + "error_clear": "Failed to clear API key" + }, + "notification": { + "title": "Notification Settings", + "section_general": "General", + "enable_notifications": "Enable Notifications", + "section_types": "Notification Types", + "new_episodes": "New Episodes", + "upcoming_shows": "Upcoming Shows", + "reminders": "Reminders", + "section_timing": "Notification Timing", + "timing_desc": "When should you be notified before an episode airs?", + "hours_1": "1 hour", + "hours_suffix": "hours", + "section_status": "Notification Status", + "stats_upcoming": "Upcoming", + "stats_this_week": "This Week", + "stats_total": "Total", + "sync_button": "Sync Library & Trakt", + "syncing": "Syncing...", + "sync_desc": "Automatically syncs notifications for all shows in your library and Trakt watchlist/collection.", + "section_advanced": "Advanced", + "reset_button": "Reset All Notifications", + "test_button": "Test Notification (5 sec)", + "test_notification_in": "Notification in {{seconds}}s...", + "test_notification_text": "Notification will appear in {{seconds}} seconds", + "alert_reset_title": "Reset Notifications", + "alert_reset_msg": "This will cancel all scheduled notifications, but will not remove anything from your saved library. Are you sure?", + "alert_reset_success": "All notifications have been reset", + "alert_sync_complete": "Sync Complete", + "alert_sync_msg": "Successfully synced notifications for your library and Trakt items.\n\nScheduled: {{upcoming}} upcoming episodes\nThis week: {{thisWeek}} episodes", + "alert_test_scheduled": "Test notification scheduled to fire instantly" + }, + "backup": { + "title": "Backup & Restore", + "options_title": "Backup Options", + "options_desc": "Choose what to include in your backups", + "section_core": "Core Data", + "section_addons": "Addons & Integrations", + "section_settings": "Settings & Preferences", + "library_label": "Library", + "library_desc": "Your saved movies and TV shows", + "watch_progress_label": "Watch Progress", + "watch_progress_desc": "Continue watching positions", + "addons_label": "Addons", + "addons_desc": "Installed Stremio addons", + "plugins_label": "Plugins", + "plugins_desc": "Custom scraper configurations", + "trakt_label": "Trakt Integration", + "trakt_desc": "Sync data and authentication tokens", + "app_settings_label": "App Settings", + "app_settings_desc": "Theme, preferences, and configurations", + "user_prefs_label": "User Preferences", + "user_prefs_desc": "Addon order and UI settings", + "catalog_settings_label": "Catalog Settings", + "catalog_settings_desc": "Catalog filters and preferences", + "api_keys_label": "API Keys", + "api_keys_desc": "MDBList and OpenRouter keys", + "action_create": "Create Backup", + "action_restore": "Restore from Backup", + "section_info": "About Backups", + "info_text": "• Customize what gets backed up using the toggles above\n• Backup files are stored locally on your device\n• Share your backup to transfer data between devices\n• Restoring will overwrite your current data", + "alert_create_title": "Create Backup", + "alert_no_content": "No content selected for backup.\n\nPlease enable at least one option in the Backup Options section above.", + "alert_backup_created_title": "Backup Created", + "alert_backup_created_msg": "Your backup has been created and is ready to share.", + "alert_backup_failed_title": "Backup Failed", + "alert_restore_confirm_title": "Confirm Restore", + "alert_restore_confirm_msg": "This will restore your data from a backup created on {{date}}.\n\nThis action will overwrite your current data. Are you sure you want to continue?", + "alert_restore_complete_title": "Restore Complete", + "alert_restore_complete_msg": "Your data has been successfully restored. Please restart the app to see all changes.", + "alert_restore_failed_title": "Restore Failed", + "restart_app": "Restart App", + "alert_restart_failed_title": "Restart Failed", + "alert_restart_failed_msg": "Failed to restart the app. Please manually close and reopen the app to see your restored data." + }, + "updates": { + "title": "App Updates", + "status_checking": "Checking for updates...", + "status_available": "Update available!", + "status_downloading": "Downloading update...", + "status_installing": "Installing update...", + "status_success": "Update installed successfully!", + "status_error": "Update failed", + "status_ready": "Ready to check for updates", + "action_check": "Check for Updates", + "action_install": "Install Update", + "release_notes": "Release notes:", + "version": "Version:", + "last_checked": "Last checked:", + "current_version": "Current version:", + "current_release_notes": "Current release notes:", + "github_release": "GITHUB RELEASE", + "current": "Current:", + "latest": "Latest:", + "notes": "Notes:", + "view_release": "View Release", + "notification_settings": "NOTIFICATION SETTINGS", + "ota_alerts_label": "OTA Update Alerts", + "ota_alerts_desc": "Show notifications for over-the-air updates", + "major_alerts_label": "Major Update Alerts", + "major_alerts_desc": "Show notifications for new app versions on GitHub", + "alert_disable_ota_title": "Disable OTA Update Alerts?", + "alert_disable_ota_msg": "You will no longer receive automatic notifications for OTA updates.\n\n⚠️ Warning: Staying on the latest version is important for:\n• Bug fixes and stability improvements\n• New features and enhancements\n• Providing accurate feedback and crash reports\n\nYou can still manually check for updates in this screen.", + "alert_disable_major_title": "Disable Major Update Alerts?", + "alert_disable_major_msg": "You will no longer receive notifications for major app updates that require reinstallation.\n\n⚠️ Warning: Major updates often include:\n• Critical security patches\n• Breaking changes that require app reinstall\n• Important compatibility fixes\n\nYou can still check for updates manually.", + "warning_note": "Keeping alerts enabled ensures you receive bug fixes and can provide accurate crash reports.", + "disable": "Disable", + "alert_no_update_to_install": "No update available to install", + "alert_install_failed": "Failed to install update", + "alert_no_update_title": "No Update", + "alert_update_applied_msg": "Update will be applied on next app restart" + }, + "player": { + "title": "Video Player", + "section_selection": "PLAYER SELECTION", + "internal_title": "Built-in Player", + "internal_desc": "Use the app's default video player", + "vlc_title": "VLC", + "vlc_desc": "Open streams in VLC media player", + "infuse_title": "Infuse", + "infuse_desc": "Open streams in Infuse player", + "outplayer_title": "OutPlayer", + "outplayer_desc": "Open streams in OutPlayer", + "vidhub_title": "VidHub", + "vidhub_desc": "Open streams in VidHub player", + "infuse_live_title": "Infuse Livecontainer", + "infuse_live_desc": "Open streams in Infuse player LiveContainer", + "external_title": "External Player", + "external_desc": "Open streams in your preferred video player", + "section_playback": "PLAYBACK OPTIONS", + "skip_intro_settings_title": "Skip Intro", + "powered_by_introdb": "Powered by IntroDB", + "autoplay_title": "Auto-play First Stream", + "autoplay_desc": "Automatically start the first stream shown in the list.", + "resume_title": "Always Resume", + "resume_desc": "Skip the resume prompt and automatically continue where you left off (if less than 85% watched).", + "engine_title": "Video Player Engine", + "engine_desc": "Auto uses ExoPlayer with MPV fallback. Some formats like Dolby Vision and HDR may not be supported by MPV, so Auto is recommended for best compatibility.", + "decoder_title": "Decoder Mode", + "decoder_desc": "How video is decoded. Auto is recommended for best balance.", + "gpu_title": "GPU Rendering", + "gpu_desc": "GPU-Next offers better HDR and color management.", + "external_downloads_title": "External Player for Downloads", + "external_downloads_desc": "Play downloaded content in your preferred external player.", + "restart_required": "Restart Required", + "restart_msg_decoder": "Please restart the app for the decoder change to take effect.", + "restart_msg_gpu": "Please restart the app for the GPU mode change to take effect.", + "option_auto": "Auto", + "option_auto_desc_engine": "ExoPlayer + MPV fallback", + "option_mpv": "MPV", + "option_mpv_desc": "MPV only", + "option_auto_desc_decoder": "Best balance", + "option_sw": "SW", + "option_sw_desc": "Software", + "option_hw": "HW", + "option_hw_desc": "Hardware", + "option_hw_plus": "HW+", + "option_hw_plus_desc": "Full HW", + "option_gpu_desc": "Standard", + "option_gpu_next_desc": "Advanced" + }, + "plugins": { + "title": "Plugins", + "enable_title": "Enable Plugins", + "enable_desc": "Enable the plugin engine to resolve external media sources", + "repo_config_title": "Repository Configuration", + "repo_config_desc": "Manage external plugin repositories. Toggle each repository on or off below.", + "your_repos": "Repositories", + "your_repos_desc": "Configure external sources for plugins.", + "add_repo_button": "Add Repository", + "refresh": "Refresh", + "remove": "Remove", + "enabled": "Enabled", + "disabled": "Disabled", + "updating": "Updating...", + "success": "Success", + "error": "Error", + "alert_repo_added": "Repository added and plugins loaded successfully", + "alert_repo_saved": "Repository URL saved successfully", + "alert_repo_refreshed": "Repository refreshed successfully", + "alert_invalid_url": "Invalid URL Format", + "alert_plugins_cleared": "All plugins have been removed", + "alert_cache_cleared": "Repository cache cleared successfully", + "unknown": "Unknown", + "active": "Active", + "available": "Available", + "platform_disabled": "Platform Disabled", + "limited": "Limited", + "clear_all": "Clear All Plugins", + "clear_all_desc": "Are you sure you want to remove all installed plugins? This action cannot be undone.", + "clear_cache": "Clear Repository Cache", + "clear_cache_desc": "This will remove the saved repository URL and clear all cached plugin data. You will need to re-enter your repository URL.", + "add_new_repo": "Add New Repository", + "available_plugins": "Available Plugins ({{count}})", + "placeholder": "Search plugins...", + "all": "All", + "filter_all": "All Types", + "filter_movies": "Movies", + "filter_tv": "TV Shows", + "enable_all": "Enable All", + "disable_all": "Disable All", + "no_plugins_found": "No Plugins Found", + "no_plugins_available": "No Plugins Available", + "no_match_desc": "No plugins match \"{{query}}\". Try a different search term.", + "configure_repo_desc": "Configure a repository above to view available plugins.", + "clear_search": "Clear Search", + "no_external_player": "No external player", + "showbox_token": "ShowBox UI Token", + "showbox_placeholder": "Paste your ShowBox UI token", + "save": "Save", + "clear": "Clear", + "additional_settings": "Additional Settings", + "enable_url_validation": "Enable URL Validation", + "url_validation_desc": "Validate media URLs before returning them (may slow down results but improves reliability)", + "group_streams": "Group Plugin Sources", + "group_streams_desc": "When enabled, sources are grouped by repository. When disabled, each plugin shows as a separate provider.", + "sort_quality": "Sort by Quality First", + "sort_quality_desc": "When enabled, sources are sorted by quality first. Only available when grouping is enabled.", + "show_logos": "Show Plugin Logos", + "show_logos_desc": "Display plugin logos next to media links on the sources screen.", + "quality_filtering": "Quality Filtering", + "quality_filtering_desc": "Exclude specific video resolutions from search results. Tap on a quality to exclude it from plugin results.", + "excluded_qualities": "Excluded qualities:", + "language_filtering": "Language Filtering", + "language_filtering_desc": "Exclude specific languages from search results. Tap on a language to exclude it from plugin results.", + "note": "Note:", + "language_filtering_note": "This filter only applies to providers that include language information. It does not affect other providers.", + "excluded_languages": "Excluded languages:", + "about_title": "About Plugins", + "about_desc_1": "Plugins are modular components that adapt content from various external protocols. They run locally on your device and can be installed from trusted repositories.", + "about_desc_2": "Plugins marked as \"Limited\" may require specific external configurations.", + "help_title": "Plugin Setup", + "help_step_1": "1. **Enable Plugins** - Turn on the main switch", + "help_step_2": "2. **Add Repository** - Add a valid repository URL", + "help_step_3": "3. **Refresh Repository** - Fetch available plugins", + "help_step_4": "4. **Activate** - Enable the plugins you wish to use", + "got_it": "Got it!", + "repo_format_hint": "Format: https://raw.githubusercontent.com/username/repo/refs/heads/branch", + "cancel": "Cancel", + "add": "Add" + }, + "theme": { + "title": "App Themes", + "select_theme": "SELECT THEME", + "create_custom": "Create Custom Theme", + "options": "OPTIONS", + "use_dominant_color": "Use Dominant Color from Artwork", + "categories": { + "all": "All Themes", + "dark": "Dark Themes", + "colorful": "Colorful", + "custom": "My Themes" + }, + "editor": { + "theme_name_placeholder": "Theme name", + "save": "Save", + "primary": "Primary", + "secondary": "Secondary", + "background": "Background", + "invalid_name_title": "Invalid Name", + "invalid_name_msg": "Please enter a valid theme name" + }, + "alerts": { + "delete_title": "Delete Theme", + "delete_msg": "Are you sure you want to delete \"{{name}}\"?", + "ok": "OK", + "delete": "Delete", + "cancel": "Cancel", + "back": "Settings" + } + }, + "legal": { + "title": "Legal & Disclaimer", + "intro_title": "Nature of the Application", + "intro_text": "Nuvio is a media player and metadata management application. It acts solely as a client-side interface for browsing publicly available metadata (movies, TV shows, etc.) and playing media files provided by the user or third-party extensions. Nuvio itself does not host, store, distribute, or index any media content.", + "extensions_title": "Third-Party Plugins", + "extensions_text": "Nuvio uses an extensible architecture that allows users to install third-party plugins. These plugins are developed and maintained by independent developers not affiliated with Nuvio. We have no control over, and assume no responsibility for, the content, legality, or functionality of any third-party plugin.", + "user_resp_title": "User Responsibility", + "user_resp_text": "Users are solely responsible for the plugins they install and the content they access. By using this application, you agree to ensure that you have the legal right to access any content you view using Nuvio. The developers of Nuvio do not endorse or encourage copyright infringement.", + "dmca_title": "Copyright & DMCA", + "dmca_text": "We respect the intellectual property rights of others. Since Nuvio does not host any content, we cannot remove content from the internet. However, if you believe that the application interface itself infringes on your rights, please contact us.", + "warranty_title": "No Warranty", + "warranty_text": "This software is provided \"as is\", without warranty of any kind, express or implied. In no event shall the authors or copyright holders be liable for any claim, damages, or other liability arising from the use of this software." + }, + "plugin_tester": { + "title": "Plugin Tester", + "subtitle": "Run scrapers and inspect logs in real-time", + "tabs": { + "individual": "Individual", + "repo": "Repo Tester", + "code": "Code", + "logs": "Logs", + "results": "Results" + }, + "common": { + "error": "Error", + "success": "Success", + "movie": "Movie", + "tv": "TV", + "tmdb_id": "TMDB ID", + "season": "Season", + "episode": "Episode", + "running": "Running…", + "run_test": "Run Test", + "play": "Play", + "done": "Done", + "test": "Test", + "testing": "Testing…" + }, + "individual": { + "load_from_url": "Load from URL", + "load_from_url_desc": "Paste a raw GitHub URL or local IP and tap download.", + "enter_url_error": "Please enter a URL", + "code_loaded": "Code loaded from URL", + "fetch_error": "Failed to fetch: {{message}}", + "no_code_error": "No code to run", + "plugin_code": "Plugin Code", + "focus_editor": "Focus code editor", + "code_placeholder": "// Paste plugin code here...", + "test_parameters": "Test Parameters", + "no_logs": "No logs yet. Run a test to see output.", + "no_streams": "No streams found yet.", + "streams_found": "{{count}} Stream Found", + "streams_found_plural": "{{count}} Streams Found", + "tap_play_hint": "Tap Play to test a stream in the native player.", + "unnamed_stream": "Unnamed Stream", + "quality": "Quality: {{quality}}", + "size": "Size: {{size}}", + "url_label": "URL: {{url}}", + "headers_info": "Headers: {{count}} custom header(s)", + "find_placeholder": "Find in code…", + "edit_code_title": "Edit Code", + "no_url_stream_error": "No URL found for this stream" + }, + "repo": { + "title": "Repo Tester", + "description": "Fetch a repository (local URL or GitHub raw) and test each provider.", + "enter_repo_url_error": "Please enter a repository URL", + "invalid_url_title": "Invalid URL", + "invalid_url_msg": "Use a GitHub raw URL or a local http(s) URL.\n\nExample:\nhttps://raw.githubusercontent.com/tapframe/nuvio-providers/refs/heads/main", + "manifest_build_error": "Could not build a manifest URL from the input", + "manifest_fetch_error": "Failed to fetch manifest", + "repo_manifest_fetch_error": "Failed to fetch repository manifest", + "missing_filename": "Missing filename in manifest", + "scraper_build_error": "Could not build a scraper URL", + "download_scraper_error": "Failed to download scraper", + "test_failed": "Test failed", + "test_parameters": "Repo Test Parameters", + "test_parameters_desc": "These parameters are used only for Repo Tester.", + "using_info": "Using: {{mediaType}} • TMDB {{tmdbId}}", + "using_info_tv": "Using: {{mediaType}} • TMDB {{tmdbId}} • S{{season}}E{{episode}}", + "providers_title": "Providers", + "repository_default": "Repository", + "providers_count": "{{count}} providers", + "fetch_hint": "Fetch a repo to list providers.", + "test_all": "Test All", + "status_running": "RUNNING", + "status_ok": "OK ({{count}})", + "status_ok_empty": "OK (0)", + "status_failed": "FAILED", + "status_idle": "IDLE", + "tried_url": "Tried: {{url}}", + "provider_logs": "Provider Logs", + "no_logs_captured": "No logs captured." + } + } +} \ No newline at end of file diff --git a/src/i18n/locales/zh-CN.json b/src/i18n/locales/zh-CN.json index 9bb550f5..01420a2d 100644 --- a/src/i18n/locales/zh-CN.json +++ b/src/i18n/locales/zh-CN.json @@ -636,6 +636,18 @@ "chinese": "简体中文", "hindi": "印地语", "serbian": "塞尔维亚语", + "hebrew": "希伯来语", + "bulgarian": "保加利亚语", + "polish": "波兰语", + "czech": "捷克语", + "turkish": "土耳其语", + "slovenian": "斯洛文尼亚语", + "macedonian": "马其顿语", + "russian": "俄语", + "filipino": "菲律宾语", + "dutch_nl": "荷兰语 (荷兰)", + "romanian": "罗马尼亚语", + "albanian": "阿尔巴尼亚语", "account": "账户", "content_discovery": "内容与发现", "appearance": "外观", @@ -896,8 +908,8 @@ }, "debrid": { "title": "Debrid 集成", - "description_torbox": "通过集成 Torbox 解锁 4K 高质量流媒体和闪电般的速度。在下方输入您的 API 密钥以立即升级您的流媒体体验。", - "description_torrentio": "配置 Torrentio 以获取电影和电视节目的 Torrent 流。需要 Debrid 服务才能流式传输内容。", + "description_torbox": "Connect Torbox to use your account-based source preferences. Enter your API key below to configure the integration.", + "description_torrentio": "Configure Torrentio as an external source integration. A compatible debrid account may be required depending on your setup.", "tab_torbox": "TorBox", "tab_torrentio": "Torrentio", "status_connected": "已连接", @@ -924,15 +936,15 @@ "enter_api_key": "输入您的 API 密钥", "connect_button": "连接并安装", "connecting": "正在连接...", - "unlock_speeds_title": "解锁高级速度", - "unlock_speeds_desc": "获取 Torbox 订阅以访问零缓冲的缓存高质量流媒体。", + "unlock_speeds_title": "Optional Torbox Subscription", + "unlock_speeds_desc": "Torbox offers account tiers with enhanced performance and availability features.", "get_subscription": "获取订阅", "powered_by": "技术支持", "disclaimer_torbox": "Nuvio 与 Torbox 没有任何关联。", "disclaimer_torrentio": "Nuvio 与 Torrentio 没有任何关联。", "installed_badge": "✓ 已安装", "promo_title": "⚡ 需要 Debrid 服务?", - "promo_desc": "获取 TorBox 以获得零缓冲的闪电般 4K 流媒体。高级缓存 Torrent 和即时下载。", + "promo_desc": "Use TorBox if you want account-managed performance features for supported integrations.", "promo_button": "获取 TorBox 订阅", "service_label": "Debrid 服务 *", "api_key_label": "API 密钥 *", @@ -1324,7 +1336,7 @@ "user_resp_title": "用户责任", "user_resp_text": "用户对其安装的插件和访问的内容负全责。使用本应用程序即表示您同意确保您拥有使用 Nuvio 访问任何内容的合法权利。Nuvio 的开发者不认可或鼓励侵犯版权。", "dmca_title": "版权与 DMCA", - "dmca_text": "我们尊重他人的知识产权。由于 Nuvio 不托管任何内容,我们无法从互联网上移除内容。但是,如果您认为应用程序界面本身侵犯了您的权利,请联系我们。", + "dmca_text": "We respect the intellectual property rights of others. Nuvio does not host media content. If you believe this project's code, assets, or interface infringes your rights, submit a notice through the official project contact channels listed on the website and repository.", "warranty_title": "无担保", "warranty_text": "本软件“按原样”提供,不提供任何明示或暗示的担保。在任何情况下,作者或版权持有人均不对因使用本软件而引起的任何索赔、损害或其他责任负责。" }, diff --git a/src/i18n/resources.ts b/src/i18n/resources.ts index 106b445a..3be6d915 100644 --- a/src/i18n/resources.ts +++ b/src/i18n/resources.ts @@ -11,6 +11,18 @@ import hr from './locales/hr.json'; import hi from './locales/hi.json'; import zhCN from './locales/zh-CN.json'; import sr from './locales/sr.json'; +import he from './locales/he.json'; +import bg from './locales/bg.json'; +import pl from './locales/pl.json'; +import cs from './locales/cs.json'; +import tr from './locales/tr.json'; +import sl from './locales/sl.json'; +import mk from './locales/mk.json'; +import ru from './locales/ru.json'; +import fil from './locales/fil.json'; +import nlNL from './locales/nl-NL.json'; +import ro from './locales/ro.json'; +import sq from './locales/sq.json'; export const resources = { en: { translation: en }, @@ -25,4 +37,16 @@ export const resources = { 'zh-CN': { translation: zhCN }, hi: { translation: hi }, sr: { translation: sr }, + he: { translation: he }, + bg: { translation: bg }, + pl: { translation: pl }, + cs: { translation: cs }, + tr: { translation: tr }, + sl: { translation: sl }, + mk: { translation: mk }, + ru: { translation: ru }, + fil: { translation: fil }, + 'nl-NL': { translation: nlNL }, + ro: { translation: ro }, + sq: { translation: sq }, }; diff --git a/src/navigation/AppNavigator.tsx b/src/navigation/AppNavigator.tsx index ec219b70..a818fcf2 100644 --- a/src/navigation/AppNavigator.tsx +++ b/src/navigation/AppNavigator.tsx @@ -39,6 +39,7 @@ if (Platform.OS === 'ios') { import HomeScreen from '../screens/HomeScreen'; import LibraryScreen from '../screens/LibraryScreen'; import SettingsScreen from '../screens/SettingsScreen'; +import SyncSettingsScreen from '../screens/SyncSettingsScreen'; import DownloadsScreen from '../screens/DownloadsScreen'; import MetadataScreen from '../screens/MetadataScreen'; import KSPlayerCore from '../components/player/KSPlayerCore'; @@ -105,6 +106,7 @@ export type RootStackParamList = { Home: undefined; Library: undefined; Settings: undefined; + SyncSettings: undefined; Update: undefined; Search: undefined; Calendar: undefined; @@ -1854,7 +1856,12 @@ const InnerNavigator = ({ initialRouteName }: { initialRouteName?: keyof RootSta }, }} /> - + + @@ -1924,7 +1931,6 @@ const ConditionalPostHogProvider: React.FC<{ children: React.ReactNode }> = ({ c apiKey="phc_sk6THCtV3thEAn6cTaA9kL2cHuKDBnlYiSL40ywdS6C" options={{ host: "https://us.i.posthog.com", - autocapture: analyticsEnabled, // Start opted out if analytics is disabled defaultOptIn: analyticsEnabled, }} diff --git a/src/screens/AuthScreen.tsx b/src/screens/AuthScreen.tsx index c890208f..9bd9ef84 100644 --- a/src/screens/AuthScreen.tsx +++ b/src/screens/AuthScreen.tsx @@ -1,5 +1,5 @@ import React, { useEffect, useMemo, useRef, useState } from 'react'; -import { View, TextInput, Text, TouchableOpacity, StyleSheet, ActivityIndicator, SafeAreaView, KeyboardAvoidingView, Platform, Dimensions, Animated, Easing, Keyboard } from 'react-native'; +import { View, TextInput, Text, TouchableOpacity, StyleSheet, ActivityIndicator, SafeAreaView, KeyboardAvoidingView, Platform, Animated, Easing, Keyboard, StatusBar, useWindowDimensions } from 'react-native'; import { mmkvStorage } from '../services/mmkvStorage'; import { LinearGradient } from 'expo-linear-gradient'; import { MaterialIcons } from '@expo/vector-icons'; @@ -10,15 +10,46 @@ import * as Haptics from 'expo-haptics'; import { useToast } from '../contexts/ToastContext'; import { useSafeAreaInsets } from 'react-native-safe-area-context'; -const { width, height } = Dimensions.get('window'); +const EMAIL_CONFIRMATION_REQUIRED_PREFIX = '__EMAIL_CONFIRMATION__'; +const AUTH_BG_GRADIENT = ['#07090F', '#0D1020', '#140B24'] as const; + +const normalizeAuthErrorMessage = (input: string): string => { + const raw = (input || '').trim(); + if (!raw) return 'Authentication failed'; + + let parsed: any = null; + if (raw.startsWith('{') && raw.endsWith('}')) { + try { + parsed = JSON.parse(raw); + } catch { + parsed = null; + } + } + + const code = (parsed?.error_code || parsed?.code || '').toString().toLowerCase(); + const message = (parsed?.msg || parsed?.message || raw).toString(); + + if (code === 'invalid_credentials' || /invalid login credentials/i.test(message)) { + return 'Invalid email or password'; + } + if (code === 'email_not_confirmed' || /email not confirmed/i.test(message)) { + return 'Email not confirmed. Check your inbox or Spam/Junk folder, verify your account, then sign in.'; + } + + return message; +}; const AuthScreen: React.FC = () => { + const { width, height } = useWindowDimensions(); + const isTablet = width >= 768; const { currentTheme } = useTheme(); const { signIn, signUp } = useAccount(); const navigation = useNavigation(); const route = useRoute(); const fromOnboarding = !!route?.params?.fromOnboarding; const insets = useSafeAreaInsets(); + const safeTopInset = Math.max(insets.top, Platform.OS === 'android' ? (StatusBar.currentHeight || 0) : 0); + const backButtonTop = safeTopInset + 8; const { showError, showSuccess } = useToast(); const [email, setEmail] = useState(''); @@ -27,11 +58,8 @@ const AuthScreen: React.FC = () => { const [showPassword, setShowPassword] = useState(false); const [showConfirm, setShowConfirm] = useState(false); const [mode, setMode] = useState<'signin' | 'signup'>('signin'); - const signupDisabled = true; // Signup disabled due to upcoming system replacement const [error, setError] = useState(null); const [loading, setLoading] = useState(false); - const [showWarningDetails, setShowWarningDetails] = useState(false); - const authCardOpacity = useRef(new Animated.Value(1)).current; // Subtle, performant animations const introOpacity = useRef(new Animated.Value(0)).current; @@ -46,8 +74,6 @@ const AuthScreen: React.FC = () => { const modeAnim = useRef(new Animated.Value(0)).current; // 0 = signin, 1 = signup const [switchWidth, setSwitchWidth] = useState(0); // Legacy local toast state removed in favor of global toast - const [headerHeight, setHeaderHeight] = useState(0); - const headerHideAnim = useRef(new Animated.Value(0)).current; // 0 visible, 1 hidden const [keyboardHeight, setKeyboardHeight] = useState(0); useEffect(() => { @@ -113,21 +139,9 @@ const AuthScreen: React.FC = () => { const onShow = (e: any) => { const kh = e?.endCoordinates?.height ?? 0; setKeyboardHeight(kh); - Animated.timing(headerHideAnim, { - toValue: 1, - duration: 180, - easing: Easing.out(Easing.cubic), - useNativeDriver: true, - }).start(); }; const onHide = () => { setKeyboardHeight(0); - Animated.timing(headerHideAnim, { - toValue: 0, - duration: 180, - easing: Easing.out(Easing.cubic), - useNativeDriver: true, - }).start(); }; const subShow = Keyboard.addListener(showEvt, onShow as any); const subHide = Keyboard.addListener(hideEvt, onHide as any); @@ -135,7 +149,7 @@ const AuthScreen: React.FC = () => { subShow.remove(); subHide.remove(); }; - }, [headerHideAnim]); + }, []); const isEmailValid = useMemo(() => /\S+@\S+\.\S+/.test(email.trim()), [email]); const isPasswordValid = useMemo(() => password.length >= 6, [password]); @@ -145,16 +159,7 @@ const AuthScreen: React.FC = () => { const handleSubmit = async () => { if (loading) return; - - // Prevent signup if disabled - if (mode === 'signup' && signupDisabled) { - const msg = 'Sign up is currently disabled due to upcoming system changes'; - setError(msg); - showError('Sign Up Disabled', 'Sign up is currently disabled due to upcoming system changes'); - Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error).catch(() => {}); - return; - } - + if (!isEmailValid) { const msg = 'Enter a valid email address'; setError(msg); @@ -180,8 +185,19 @@ const AuthScreen: React.FC = () => { setError(null); const err = mode === 'signin' ? await signIn(email.trim(), password) : await signUp(email.trim(), password); if (err) { - setError(err); - showError('Authentication Failed', err); + if (mode === 'signup' && err.startsWith(EMAIL_CONFIRMATION_REQUIRED_PREFIX)) { + setError(null); + setMode('signin'); + setPassword(''); + setConfirmPassword(''); + Haptics.notificationAsync(Haptics.NotificationFeedbackType.Success).catch(() => {}); + setLoading(false); + return; + } + + const cleanError = normalizeAuthErrorMessage(err); + setError(cleanError); + showError('Authentication Failed', cleanError); Haptics.notificationAsync(Haptics.NotificationFeedbackType.Error).catch(() => {}); } else { const msg = mode === 'signin' ? 'Logged in successfully' : 'Sign up successful'; @@ -201,39 +217,14 @@ const AuthScreen: React.FC = () => { navigation.reset({ index: 0, routes: [{ name: 'MainTabs' as never }] } as any); }; - const toggleWarningDetails = () => { - if (showWarningDetails) { - // Fade in auth card - Animated.timing(authCardOpacity, { - toValue: 1, - duration: 300, - easing: Easing.out(Easing.cubic), - useNativeDriver: true, - }).start(); - } else { - // Fade out auth card - Animated.timing(authCardOpacity, { - toValue: 0, - duration: 300, - easing: Easing.out(Easing.cubic), - useNativeDriver: true, - }).start(); - } - setShowWarningDetails(!showWarningDetails); - }; - // showToast helper replaced with direct calls to toast.* API return ( - {Platform.OS !== 'android' ? ( - - ) : ( - - )} + {/* Background Pattern (iOS only) */} {Platform.OS !== 'android' && ( @@ -255,107 +246,55 @@ const AuthScreen: React.FC = () => { )} - {/* Header outside KeyboardAvoidingView to avoid being overlapped */} - setHeaderHeight(e.nativeEvent.layout.height)} - style={[ - styles.header, - { - opacity: Animated.multiply( - introOpacity, - headerHideAnim.interpolate({ inputRange: [0, 1], outputRange: [1, 0] }) - ), - transform: [ - { - translateY: Animated.add( - introTranslateY, - headerHideAnim.interpolate({ inputRange: [0, 1], outputRange: [0, -12] }) - ), - }, - ], - }, - ]} - > - {navigation.canGoBack() && ( - navigation.goBack()} style={[styles.backButton, Platform.OS === 'android' ? { top: Math.max(insets.top + 6, 18) } : null]} hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }}> - - - )} - - {mode === 'signin' ? 'Welcome back' : 'Create your account'} - - - Sync your addons, progress and settings across devices - - - - {/* Important Warning Message */} - + {navigation.canGoBack() && ( navigation.goBack()} + style={[styles.backButton, { top: backButtonTop }]} + hitSlop={{ top: 8, bottom: 8, left: 8, right: 8 }} > - - - - Important Notice - - - This authentication system will be completely replaced by local backup/restore functionality by October 8th. Please create backup files as your cloud data will be permanently destroyed. - - - Read more {showWarningDetails ? '▼' : '▶'} - - + - - {/* Expanded Details */} - {showWarningDetails && ( - - - - Why is this system being discontinued? - - - • Lack of real-time support for addon synchronization{'\n'} - • Database synchronization issues with addons and settings{'\n'} - • Unreliable cloud data management{'\n'} - • Performance problems with remote data access - - - - Benefits of Local Backup System: - - - • Instant addon synchronization across devices{'\n'} - • Reliable offline access to all your data{'\n'} - • Complete control over your backup files{'\n'} - • Faster performance with local data storage{'\n'} - • No dependency on external servers{'\n'} - • Easy migration between devices - - - - )} - + )} - {/* Main Card - Hide when warning details are expanded */} - - 0 + ? { + justifyContent: 'flex-start', + paddingTop: Platform.OS === 'ios' ? 12 : safeTopInset + 8, + } + : null, + ]} + > + 0 ? styles.centerHeaderCompact : null, + { + opacity: introOpacity, + transform: [{ translateY: introTranslateY }], + }, + ]} + > + + {mode === 'signin' ? 'Welcome back' : 'Create your account'} + + {keyboardHeight === 0 && ( + + Sync your addons, progress and settings across devices + + )} + + + 0 ? styles.cardCompact : null, { backgroundColor: Platform.OS === 'android' ? '#121212' : 'rgba(255,255,255,0.02)', borderColor: Platform.OS === 'android' ? '#1f1f1f' : 'rgba(255,255,255,0.06)', ...(Platform.OS !== 'android' ? { @@ -404,21 +343,17 @@ const AuthScreen: React.FC = () => { !signupDisabled && setMode('signup')} - activeOpacity={signupDisabled ? 1 : 0.8} - disabled={signupDisabled} + style={styles.switchButton} + onPress={() => setMode('signup')} + activeOpacity={0.8} > - Sign Up {signupDisabled && '(Disabled)'} + Sign Up @@ -583,29 +518,18 @@ const AuthScreen: React.FC = () => { {/* Switch Mode */} - {!signupDisabled && ( - setMode(mode === 'signin' ? 'signup' : 'signin')} - activeOpacity={0.7} - style={{ marginTop: 16 }} - > - - {mode === 'signin' ? "Don't have an account? " : 'Already have an account? '} - - {mode === 'signin' ? 'Sign up' : 'Sign in'} - + setMode(mode === 'signin' ? 'signup' : 'signin')} + activeOpacity={0.7} + style={{ marginTop: 16 }} + > + + {mode === 'signin' ? "Don't have an account? " : 'Already have an account? '} + + {mode === 'signin' ? 'Sign up' : 'Sign in'} - - )} - - {/* Signup disabled message */} - {signupDisabled && mode === 'signin' && ( - - - New account creation is temporarily disabled - - - )} + + {/* Skip sign in - more prominent when coming from onboarding */} { if (!url.startsWith('https://raw.githubusercontent.com/') && !url.startsWith('http://')) { openAlert( t('plugins.alert_invalid_url'), - 'Please use a valid GitHub raw URL format:\n\nhttps://raw.githubusercontent.com/username/repo/refs/heads/branch\n\nor include manifest.json:\nhttps://raw.githubusercontent.com/username/repo/refs/heads/branch/manifest.json\n\nExample:\nhttps://raw.githubusercontent.com/tapframe/nuvio-providers/refs/heads/master' + 'Please use a valid GitHub raw URL format:\n\nhttps://raw.githubusercontent.com/username/repo/refs/heads/branch\n\nor include manifest.json:\nhttps://raw.githubusercontent.com/username/repo/refs/heads/branch/manifest.json\n\nExample:\nhttps://raw.githubusercontent.com/your-username/your-repo/refs/heads/main' ); return; } @@ -1291,7 +1291,7 @@ const PluginsScreen: React.FC = () => { if (!url.startsWith('https://raw.githubusercontent.com/') && !url.startsWith('http://')) { openAlert( 'Invalid URL Format', - 'Please use a valid GitHub raw URL format:\n\nhttps://raw.githubusercontent.com/username/repo/refs/heads/branch\n\nExample:\nhttps://raw.githubusercontent.com/tapframe/nuvio-providers/refs/heads/master' + 'Please use a valid GitHub raw URL format:\n\nhttps://raw.githubusercontent.com/username/repo/refs/heads/branch\n\nExample:\nhttps://raw.githubusercontent.com/your-username/your-repo/refs/heads/main' ); return; } @@ -1413,11 +1413,6 @@ const PluginsScreen: React.FC = () => { ); }; - const handleUseDefaultRepo = () => { - const defaultUrl = 'https://raw.githubusercontent.com/tapframe/nuvio-providers/refs/heads/main'; - setRepositoryUrl(defaultUrl); - }; - const handleToggleLocalScrapers = async (enabled: boolean) => { await updateSetting('enableLocalScrapers', enabled); @@ -2250,4 +2245,4 @@ const PluginsScreen: React.FC = () => { ); }; -export default PluginsScreen; \ No newline at end of file +export default PluginsScreen; diff --git a/src/screens/SettingsScreen.tsx b/src/screens/SettingsScreen.tsx index 3b217ce9..cd545c8f 100644 --- a/src/screens/SettingsScreen.tsx +++ b/src/screens/SettingsScreen.tsx @@ -361,6 +361,9 @@ const SettingsScreen: React.FC = () => { if (item && item.visible === false) return false; return true; }; + const showTraktItem = isItemVisible('trakt'); + const showSimklItem = isItemVisible('simkl'); + const showCloudSyncItem = isItemVisible('cloud_sync'); // Filter categories based on conditions const visibleCategories = SETTINGS_CATEGORIES.filter(category => { @@ -376,22 +379,39 @@ const SettingsScreen: React.FC = () => { case 'account': return ( - {isItemVisible('trakt') && ( - } + {showCloudSyncItem && ( + + } renderControl={() => } - onPress={() => navigation.navigate('TraktSettings')} - isLast={!isItemVisible('simkl')} + onPress={() => (navigation as any).navigate('SyncSettings')} + isLast={!showTraktItem && !showSimklItem} isTablet={isTablet} /> )} - {isItemVisible('simkl') && ( - } + {showTraktItem && ( + } + renderControl={() => } + onPress={() => navigation.navigate('TraktSettings')} + isLast={!showSimklItem} + isTablet={isTablet} + /> + )} + {showSimklItem && ( + } renderControl={() => } onPress={() => navigation.navigate('SimklSettings')} isLast={true} @@ -682,19 +702,35 @@ const SettingsScreen: React.FC = () => { contentContainerStyle={styles.scrollContent} > {/* Account */} - {(settingsConfig?.categories?.['account']?.visible !== false) && (isItemVisible('trakt') || isItemVisible('simkl')) && ( + {(settingsConfig?.categories?.['account']?.visible !== false) && (showTraktItem || showSimklItem || showCloudSyncItem) && ( - {isItemVisible('trakt') && ( + {showCloudSyncItem && ( + + } + renderControl={() => } + onPress={() => (navigation as any).navigate('SyncSettings')} + isLast={!showTraktItem && !showSimklItem} + /> + )} + {showTraktItem && ( } renderControl={() => } onPress={() => navigation.navigate('TraktSettings')} - isLast={!isItemVisible('simkl')} + isLast={!showSimklItem} /> )} - {isItemVisible('simkl') && ( + {showSimklItem && ( { @@ -1198,6 +1234,14 @@ const styles = StyleSheet.create({ width: 180, height: 180, }, + syncLogoIcon: { + width: 20, + height: 20, + }, + syncLogoIconTablet: { + width: 24, + height: 24, + }, brandLogoContainer: { alignItems: 'center', justifyContent: 'center', @@ -1211,4 +1255,4 @@ const styles = StyleSheet.create({ }, }); -export default SettingsScreen; \ No newline at end of file +export default SettingsScreen; diff --git a/src/screens/SyncSettingsScreen.tsx b/src/screens/SyncSettingsScreen.tsx new file mode 100644 index 00000000..6be0070f --- /dev/null +++ b/src/screens/SyncSettingsScreen.tsx @@ -0,0 +1,493 @@ +import React, { useCallback, useMemo, useState } from 'react'; +import { + ActivityIndicator, + SafeAreaView, + ScrollView, + StatusBar, + StyleSheet, + Text, + TouchableOpacity, + useWindowDimensions, + View, +} from 'react-native'; +import { NavigationProp, useFocusEffect, useNavigation } from '@react-navigation/native'; +import { useSafeAreaInsets } from 'react-native-safe-area-context'; +import { MaterialIcons } from '@expo/vector-icons'; +import { RootStackParamList } from '../navigation/AppNavigator'; +import { useTheme } from '../contexts/ThemeContext'; +import CustomAlert from '../components/CustomAlert'; +import { supabaseSyncService, SupabaseUser, RemoteSyncStats } from '../services/supabaseSyncService'; +import { useAccount } from '../contexts/AccountContext'; +import { useTraktContext } from '../contexts/TraktContext'; +import { useSimklContext } from '../contexts/SimklContext'; +import { useTranslation } from 'react-i18next'; + +const SyncSettingsScreen: React.FC = () => { + const { currentTheme } = useTheme(); + const { t } = useTranslation(); + const { width } = useWindowDimensions(); + const isTablet = width >= 768; + const navigation = useNavigation>(); + const insets = useSafeAreaInsets(); + const { user, signOut } = useAccount(); + const { isAuthenticated: traktAuthenticated } = useTraktContext(); + const { isAuthenticated: simklAuthenticated } = useSimklContext(); + + const [loading, setLoading] = useState(false); + const [syncCodeLoading, setSyncCodeLoading] = useState(false); + const [sessionUser, setSessionUser] = useState(null); + const [ownerId, setOwnerId] = useState(null); + const [remoteStats, setRemoteStats] = useState(null); + + const [alertVisible, setAlertVisible] = useState(false); + const [alertTitle, setAlertTitle] = useState(''); + const [alertMessage, setAlertMessage] = useState(''); + const [alertActions, setAlertActions] = useState void; style?: object }>>([]); + + const openAlert = useCallback( + (title: string, message: string, actions?: Array<{ label: string; onPress: () => void; style?: object }>) => { + setAlertTitle(title); + setAlertMessage(message); + setAlertActions(actions && actions.length > 0 ? actions : [{ label: 'OK', onPress: () => {} }]); + setAlertVisible(true); + }, + [] + ); + + const loadSyncState = useCallback(async () => { + setLoading(true); + try { + await supabaseSyncService.initialize(); + setSessionUser(supabaseSyncService.getCurrentSessionUser()); + const owner = await supabaseSyncService.getEffectiveOwnerId(); + setOwnerId(owner); + const stats = await supabaseSyncService.getRemoteStats(); + setRemoteStats(stats); + } catch (error: any) { + openAlert('Sync Error', error?.message || 'Failed to load sync state'); + } finally { + setLoading(false); + } + }, [openAlert]); + + useFocusEffect( + useCallback(() => { + loadSyncState(); + }, [loadSyncState]) + ); + + const authLabel = useMemo(() => { + if (!supabaseSyncService.isConfigured()) return 'Supabase not configured'; + if (!sessionUser) return 'Not authenticated'; + return `Email session${sessionUser.email ? ` (${sessionUser.email})` : ''}`; + }, [sessionUser]); + + const statItems = useMemo(() => { + if (!remoteStats) return []; + return [ + { label: 'Plugins', value: remoteStats.plugins }, + { label: 'Addons', value: remoteStats.addons }, + { label: 'Watch Progress', value: remoteStats.watchProgress }, + { label: 'Library Items', value: remoteStats.libraryItems }, + { label: 'Watched Items', value: remoteStats.watchedItems }, + ]; + }, [remoteStats]); + const isSignedIn = Boolean(user); + const externalSyncServices = useMemo( + () => [ + traktAuthenticated ? 'Trakt' : null, + simklAuthenticated ? 'Simkl' : null, + ].filter(Boolean) as string[], + [traktAuthenticated, simklAuthenticated] + ); + const externalSyncActive = externalSyncServices.length > 0; + + const handleManualSync = async () => { + setSyncCodeLoading(true); + try { + await supabaseSyncService.pullAllToLocal(); + openAlert('Cloud Data Pulled', 'Latest cloud data was pulled to this device.'); + await loadSyncState(); + } catch (error: any) { + openAlert('Pull Failed', error?.message || 'Failed to pull cloud data'); + } finally { + setSyncCodeLoading(false); + } + }; + + const handleUploadLocalData = async () => { + setSyncCodeLoading(true); + try { + await supabaseSyncService.pushAllLocalData(); + openAlert('Upload Complete', 'This device data has been uploaded to cloud.'); + await loadSyncState(); + } catch (error: any) { + openAlert('Upload Failed', error?.message || 'Failed to upload local data'); + } finally { + setSyncCodeLoading(false); + } + }; + + const handleSignOut = async () => { + setSyncCodeLoading(true); + try { + await signOut(); + await loadSyncState(); + } catch (error: any) { + openAlert('Sign Out Failed', error?.message || 'Failed to sign out'); + } finally { + setSyncCodeLoading(false); + } + }; + + return ( + + + + navigation.goBack()} style={styles.backButton}> + + {t('settings.title')} + + + + Nuvio Sync + + {loading ? ( + + + + ) : ( + <> + + + + + + Cloud Sync + + Keep your addons, progress and library aligned across devices. + + + + + + + + + External Sync Priority + + + {externalSyncActive + ? `${externalSyncServices.join(' + ')} is active. Watch progress and library updates are managed by these services instead of Nuvio cloud database.` + : 'If Trakt or Simkl sync is enabled, watch progress and library updates will use those services instead of Nuvio cloud database.'} + + + + + + + Account + + + {user?.email ? `Signed in as ${user.email}` : 'Not signed in'} + + + {!isSignedIn ? ( + navigation.navigate('Account')} + > + Sign In / Sign Up + + ) : ( + <> + navigation.navigate('AccountManage')} + > + Manage Account + + + Sign Out + + + )} + + + + {!isSignedIn ? ( + + + + Before You Sync + + + Sign in to start cloud sync and keep your data consistent across devices. + + + • Addons and plugin settings + • Watch progress and library + + {!supabaseSyncService.isConfigured() && ( + + Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync. + + )} + + ) : ( + <> + + + + Connection + + {authLabel} + + Effective owner: {ownerId || 'Unavailable'} + + {!supabaseSyncService.isConfigured() && ( + + Set EXPO_PUBLIC_SUPABASE_URL and EXPO_PUBLIC_SUPABASE_ANON_KEY to enable sync. + + )} + + + + + + Database Stats + + {!remoteStats ? ( + + Sign in to load remote data counts. + + ) : ( + + {statItems.map((item) => ( + + {item.value} + {item.label} + + ))} + + )} + + + + + + Actions + + + Pull to refresh this device from cloud, or upload this device as the latest source. + + + + {syncCodeLoading ? ( + + ) : ( + Pull From Cloud + )} + + + Upload This Device + + + + + )} + + + )} + + setAlertVisible(false)} + /> + + ); +}; + +const styles = StyleSheet.create({ + container: { + flex: 1, + }, + loadingContainer: { + flex: 1, + alignItems: 'center', + justifyContent: 'center', + }, + header: { + flexDirection: 'row', + alignItems: 'center', + justifyContent: 'space-between', + paddingHorizontal: 16, + paddingTop: 8, + }, + backButton: { + flexDirection: 'row', + alignItems: 'center', + paddingVertical: 8, + }, + backText: { + marginLeft: 8, + fontSize: 16, + fontWeight: '600', + }, + headerActions: { + minWidth: 32, + }, + screenTitle: { + fontSize: 32, + fontWeight: '800', + paddingHorizontal: 16, + marginTop: 4, + marginBottom: 10, + }, + content: { + padding: 16, + gap: 14, + }, + contentTablet: { + alignSelf: 'center', + width: '100%', + maxWidth: 980, + }, + heroCard: { + borderWidth: 1, + borderRadius: 16, + padding: 16, + }, + heroTopRow: { + flexDirection: 'row', + justifyContent: 'space-between', + gap: 12, + }, + heroTitleWrap: { + flex: 1, + }, + heroTitle: { + fontSize: 20, + fontWeight: '800', + marginBottom: 4, + }, + heroSubtitle: { + fontSize: 13, + lineHeight: 18, + }, + card: { + borderWidth: 1, + borderRadius: 14, + padding: 14, + gap: 10, + }, + noteCard: { + borderWidth: 1, + borderRadius: 14, + padding: 14, + gap: 8, + }, + preAuthCard: { + gap: 12, + }, + preAuthList: { + gap: 6, + marginTop: 2, + }, + preAuthItem: { + fontSize: 13, + lineHeight: 18, + }, + sectionHeader: { + flexDirection: 'row', + alignItems: 'center', + gap: 8, + }, + cardTitle: { + fontSize: 15, + fontWeight: '700', + }, + cardText: { + fontSize: 13, + lineHeight: 18, + }, + warning: { + fontSize: 12, + marginTop: 4, + }, + statsGrid: { + marginTop: 2, + flexDirection: 'row', + flexWrap: 'wrap', + gap: 8, + }, + statTile: { + width: '48%', + borderWidth: 1, + borderRadius: 10, + paddingHorizontal: 10, + paddingVertical: 8, + }, + statValue: { + fontSize: 18, + fontWeight: '800', + marginBottom: 2, + }, + statLabel: { + fontSize: 11, + fontWeight: '600', + }, + buttonRow: { + flexDirection: 'row', + gap: 10, + }, + button: { + flex: 1, + borderRadius: 10, + minHeight: 42, + justifyContent: 'center', + alignItems: 'center', + paddingHorizontal: 12, + }, + primaryButton: { + borderWidth: 0, + }, + secondaryButton: { + borderWidth: 1, + }, + buttonDisabled: { + opacity: 0.55, + }, + buttonText: { + color: '#fff', + fontWeight: '700', + fontSize: 13, + }, +}); + +export default SyncSettingsScreen; diff --git a/src/screens/TMDBSettingsScreen.tsx b/src/screens/TMDBSettingsScreen.tsx index 029ae8af..57f0dd4a 100644 --- a/src/screens/TMDBSettingsScreen.tsx +++ b/src/screens/TMDBSettingsScreen.tsx @@ -1175,8 +1175,13 @@ const TMDBSettingsScreen = () => { { code: 'uk', label: 'Українська', native: 'Ukrainian' }, { code: 'vi', label: 'Tiếng Việt', native: 'Vietnamese' }, { code: 'th', label: 'ไทย', native: 'Thai' }, - { code: 'hr', -label: 'Hrvatski', native: 'Croatian' }, + { code: 'hr', label: 'Hrvatski', native: 'Croatian' }, + { code: 'sr', label: 'Српски', native: 'Serbian' }, + { code: 'bg', label: 'български', native: 'Bulgarian' }, + { code: 'sl', label: 'Slovenščina', native: 'Slovenian' }, + { code: 'mk', label: 'Македонски', native: 'Macedonian' }, + { code: 'fil', label: 'Filipino', native: 'Filipino' }, + { code: 'sq', label: 'Shqipe', native: 'Albanian' }, ]; const filteredLanguages = languages.filter(({ label, code, native }) => diff --git a/src/screens/settings/AboutSettingsScreen.tsx b/src/screens/settings/AboutSettingsScreen.tsx index 04e3d3d4..18f39bb1 100644 --- a/src/screens/settings/AboutSettingsScreen.tsx +++ b/src/screens/settings/AboutSettingsScreen.tsx @@ -391,7 +391,7 @@ export const AboutFooter: React.FC<{ displayDownloads: number | null }> = ({ dis diff --git a/src/screens/settings/PlaybackSettingsScreen.tsx b/src/screens/settings/PlaybackSettingsScreen.tsx index 98ce9a72..bbbc5328 100644 --- a/src/screens/settings/PlaybackSettingsScreen.tsx +++ b/src/screens/settings/PlaybackSettingsScreen.tsx @@ -55,6 +55,14 @@ const AVAILABLE_LANGUAGES = [ { code: 'uk', name: 'Ukrainian' }, { code: 'he', name: 'Hebrew' }, { code: 'fa', name: 'Persian' }, + { code: 'hr', name: 'Croatian' }, + { code: 'sr', name: 'Serbian' }, + { code: 'bg', name: 'Bulgarian' }, + { code: 'sl', name: 'Slovenian' }, + { code: 'mk', name: 'Macedonian' }, + { code: 'fil', name: 'Filipino' }, + { code: 'ro', name: 'Romanian' }, + { code: 'sq', name: 'Albanian' }, ]; const SUBTITLE_SOURCE_OPTIONS = [ diff --git a/src/services/AccountService.ts b/src/services/AccountService.ts index 32dc943f..3d3d4440 100644 --- a/src/services/AccountService.ts +++ b/src/services/AccountService.ts @@ -1,4 +1,6 @@ import { mmkvStorage } from './mmkvStorage'; +import { supabaseSyncService, SupabaseUser } from './supabaseSyncService'; +import { logger } from '../utils/logger'; export type AuthUser = { id: string; @@ -9,6 +11,7 @@ export type AuthUser = { const USER_DATA_KEY = '@user:data'; const USER_SCOPE_KEY = '@user:current'; +const EMAIL_CONFIRMATION_REQUIRED_PREFIX = '__EMAIL_CONFIRMATION__'; class AccountService { private static instance: AccountService; @@ -19,23 +22,79 @@ class AccountService { return AccountService.instance; } + private mapSupabaseUser(user: SupabaseUser): AuthUser { + return { + id: user.id, + email: user.email, + displayName: user.user_metadata?.display_name as string | undefined, + avatarUrl: user.user_metadata?.avatar_url as string | undefined, + }; + } + + private async persistUser(user: AuthUser): Promise { + await mmkvStorage.setItem(USER_DATA_KEY, JSON.stringify(user)); + await mmkvStorage.setItem(USER_SCOPE_KEY, 'local'); + } + async signUpWithEmail(email: string, password: string): Promise<{ user?: AuthUser; error?: string }> { - // Since signup is disabled, always return error - return { error: 'Sign up is currently disabled due to upcoming system changes' }; + const result = await supabaseSyncService.signUpWithEmail(email, password); + if (result.error) { + return { error: result.error }; + } + + const sessionUser = supabaseSyncService.getCurrentSessionUser(); + if (!sessionUser) { + return { + error: `${EMAIL_CONFIRMATION_REQUIRED_PREFIX}Account created. Check your email to verify, then sign in.`, + }; + } + + const mapped = this.mapSupabaseUser(sessionUser); + await this.persistUser(mapped); + + try { + await supabaseSyncService.onSignUpPushAll(); + } catch (error) { + logger.error('[AccountService] Sign-up push-all failed:', error); + } + + return { user: mapped }; } async signInWithEmail(email: string, password: string): Promise<{ user?: AuthUser; error?: string }> { - // Since signin is disabled, always return error - return { error: 'Authentication is currently disabled' }; + const result = await supabaseSyncService.signInWithEmail(email, password); + if (result.error || !result.user) { + return { error: result.error || 'Sign in failed' }; + } + + const mapped = this.mapSupabaseUser(result.user); + await this.persistUser(mapped); + + try { + await supabaseSyncService.onSignInPullAll(); + } catch (error) { + logger.error('[AccountService] Sign-in pull-all failed:', error); + } + + return { user: mapped }; } async signOut(): Promise { + await supabaseSyncService.signOut(); await mmkvStorage.removeItem(USER_DATA_KEY); await mmkvStorage.setItem(USER_SCOPE_KEY, 'local'); } async getCurrentUser(): Promise { try { + await supabaseSyncService.initialize(); + const sessionUser = supabaseSyncService.getCurrentSessionUser(); + if (sessionUser) { + const mapped = this.mapSupabaseUser(sessionUser); + await this.persistUser(mapped); + return mapped; + } + const userData = await mmkvStorage.getItem(USER_DATA_KEY); if (!userData) return null; return JSON.parse(userData); @@ -69,4 +128,3 @@ class AccountService { export const accountService = AccountService.getInstance(); export default accountService; - diff --git a/src/services/introService.ts b/src/services/introService.ts index de9a1c78..9d96b43c 100644 --- a/src/services/introService.ts +++ b/src/services/introService.ts @@ -26,11 +26,21 @@ export interface IntroTimestamps { imdb_id: string; season: number; episode: number; - start_sec: number; - end_sec: number; - start_ms: number; - end_ms: number; - confidence: number; + intro?: { + start_sec: number; + end_sec: number; + confidence: number; + }; + recap?: { + start_sec: number; + end_sec: number; + confidence: number; + }; + outro?: { + start_sec: number; + end_sec: number; + confidence: number; + }; } async function getMalIdFromArm(imdbId: string): Promise { @@ -154,7 +164,7 @@ async function fetchFromAniSkip(malId: string, episode: number): Promise { try { - const response = await axios.get(`${INTRODB_API_URL}/intro`, { + const response = await axios.get(`${INTRODB_API_URL}/segments`, { params: { imdb_id: imdbId, season, @@ -163,26 +173,48 @@ async function fetchFromIntroDb(imdbId: string, season: number, episode: number) timeout: 5000, }); - logger.log(`[IntroService] Found intro for ${imdbId} S${season}E${episode}:`, { - start: response.data.start_sec, - end: response.data.end_sec, - confidence: response.data.confidence, - }); + const intervals: SkipInterval[] = []; - return [{ - startTime: response.data.start_sec, - endTime: response.data.end_sec, - type: 'intro', - provider: 'introdb' - }]; + if (response.data.intro) { + intervals.push({ + startTime: response.data.intro.start_sec, + endTime: response.data.intro.end_sec, + type: 'intro', + provider: 'introdb' + }); + } + + if (response.data.recap) { + intervals.push({ + startTime: response.data.recap.start_sec, + endTime: response.data.recap.end_sec, + type: 'recap', + provider: 'introdb' + }); + } + + if (response.data.outro) { + intervals.push({ + startTime: response.data.outro.start_sec, + endTime: response.data.outro.end_sec, + type: 'outro', + provider: 'introdb' + }); + } + + if (intervals.length > 0) { + logger.log(`[IntroService] Found ${intervals.length} segments for ${imdbId} S${season}E${episode}`); + } + + return intervals; } catch (error: any) { if (axios.isAxiosError(error) && error.response?.status === 404) { // No intro data available for this episode - this is expected - logger.log(`[IntroService] No intro data for ${imdbId} S${season}E${episode}`); + logger.log(`[IntroService] No segment data for ${imdbId} S${season}E${episode}`); return []; } - logger.error('[IntroService] Error fetching intro timestamps:', error?.message || error); + logger.error('[IntroService] Error fetching segments from IntroDB:', error?.message || error); return []; } } @@ -230,7 +262,8 @@ export async function submitIntro( season: number, episode: number, startTime: number, // in seconds - endTime: number // in seconds + endTime: number, // in seconds + segmentType: SkipType = 'intro' ): Promise { try { if (!apiKey) { @@ -240,8 +273,12 @@ export async function submitIntro( const response = await axios.post(`${INTRODB_API_URL}/submit`, { imdb_id: imdbId, + segment_type: segmentType === 'op' ? 'intro' : (segmentType === 'ed' ? 'outro' : segmentType), season, episode, + start_sec: startTime, + end_sec: endTime, + // Keep start_ms/end_ms for backward compatibility if the server still expects it start_ms: Math.round(startTime * 1000), end_ms: Math.round(endTime * 1000), }, { @@ -319,18 +356,24 @@ export async function getIntroTimestamps( imdbId: string, season: number, episode: number -): Promise { +): Promise { const intervals = await fetchFromIntroDb(imdbId, season, episode); - if (intervals.length > 0) { + const intro = intervals.find(i => i.type === 'intro'); + if (intro) { return { imdb_id: imdbId, season, episode, - start_sec: intervals[0].startTime, - end_sec: intervals[0].endTime, - start_ms: intervals[0].startTime * 1000, - end_ms: intervals[0].endTime * 1000, - confidence: 1.0 + start_sec: intro.startTime, + end_sec: intro.endTime, + start_ms: intro.startTime * 1000, + end_ms: intro.endTime * 1000, + confidence: 1.0, + intro: { + start_sec: intro.startTime, + end_sec: intro.endTime, + confidence: 1.0 + } }; } return null; diff --git a/src/services/pluginService.ts b/src/services/pluginService.ts index 8c7e2b25..a84437f4 100644 --- a/src/services/pluginService.ts +++ b/src/services/pluginService.ts @@ -6,6 +6,7 @@ import { Stream } from '../types/streams'; import { cacheService } from './cacheService'; import CryptoJS from 'crypto-js'; import { safeAxiosConfig, createSafeAxiosConfig } from '../utils/axiosConfig'; +import EventEmitter from 'eventemitter3'; const MAX_CONCURRENT_SCRAPERS = 5; const MAX_INFLIGHT_KEYS = 30; @@ -24,6 +25,12 @@ const VIDEO_CONTENT_TYPES = [ const MAX_PREFLIGHT_SIZE = 50 * 1024 * 1024; +export const PLUGIN_SYNC_EVENTS = { + CHANGED: 'changed', +} as const; + +const pluginSyncEmitter = new EventEmitter(); + // Types for local scrapers export interface ScraperManifest { name: string; @@ -176,6 +183,10 @@ class LocalScraperService { return LocalScraperService.instance; } + public getPluginSyncEventEmitter(): EventEmitter { + return pluginSyncEmitter; + } + private async initialize(): Promise { if (this.initialized) return; @@ -367,6 +378,7 @@ class LocalScraperService { }; this.repositories.set(id, newRepo); await this.saveRepositories(); + pluginSyncEmitter.emit(PLUGIN_SYNC_EVENTS.CHANGED, { action: 'add_repository', id: newRepo.id }); logger.log('[LocalScraperService] Added repository:', newRepo.name); return id; } @@ -386,6 +398,7 @@ class LocalScraperService { this.repositoryUrl = updatedRepo.url; this.repositoryName = updatedRepo.name; } + pluginSyncEmitter.emit(PLUGIN_SYNC_EVENTS.CHANGED, { action: 'update_repository', id }); logger.log('[LocalScraperService] Updated repository:', updatedRepo.name); } @@ -424,6 +437,7 @@ class LocalScraperService { this.repositories.delete(id); await this.saveRepositories(); await this.saveInstalledScrapers(); + pluginSyncEmitter.emit(PLUGIN_SYNC_EVENTS.CHANGED, { action: 'remove_repository', id }); logger.log('[LocalScraperService] Removed repository:', id); } @@ -450,6 +464,7 @@ class LocalScraperService { } logger.log('[LocalScraperService] Switched to repository:', repo.name); + pluginSyncEmitter.emit(PLUGIN_SYNC_EVENTS.CHANGED, { action: 'set_current_repository', id }); } getCurrentRepositoryId(): string { @@ -553,6 +568,7 @@ class LocalScraperService { this.repositories.set(id, repo); await this.saveRepositories(); + pluginSyncEmitter.emit(PLUGIN_SYNC_EVENTS.CHANGED, { action: 'toggle_repository_enabled', id, enabled }); logger.log('[LocalScraperService] Toggled repository', repo.name, 'to', enabled ? 'enabled' : 'disabled'); } @@ -1777,4 +1793,4 @@ class LocalScraperService { export const localScraperService = LocalScraperService.getInstance(); export const pluginService = localScraperService; // Alias for UI consistency -export default localScraperService; \ No newline at end of file +export default localScraperService; diff --git a/src/services/stremioService.ts b/src/services/stremioService.ts index e155ad26..ec886e95 100644 --- a/src/services/stremioService.ts +++ b/src/services/stremioService.ts @@ -1250,6 +1250,49 @@ class StremioService { const addons = this.getInstalledAddons(); + // Some addons use non-standard meta types (e.g. "anime") but expect streams under the "series" endpoint. + // We'll try the requested type first, then (if no addons match) fall back to "series". + const pickStreamAddons = (requestType: string) => + addons.filter(addon => { + if (!addon.resources || !Array.isArray(addon.resources)) { + logger.log(`⚠️ [getStreams] Addon ${addon.id} has no valid resources array`); + return false; + } + + let hasStreamResource = false; + let supportsIdPrefix = false; + + for (const resource of addon.resources) { + if (typeof resource === 'object' && resource !== null && 'name' in resource) { + const typedResource = resource as ResourceObject; + if (typedResource.name === 'stream' && + Array.isArray(typedResource.types) && + typedResource.types.includes(requestType)) { + hasStreamResource = true; + + if (Array.isArray(typedResource.idPrefixes) && typedResource.idPrefixes.length > 0) { + supportsIdPrefix = typedResource.idPrefixes.some(p => id.startsWith(p)); + } else { + supportsIdPrefix = true; + } + break; + } + } else if (typeof resource === 'string' && resource === 'stream' && addon.types) { + if (Array.isArray(addon.types) && addon.types.includes(requestType)) { + hasStreamResource = true; + if (addon.idPrefixes && Array.isArray(addon.idPrefixes) && addon.idPrefixes.length > 0) { + supportsIdPrefix = addon.idPrefixes.some(p => id.startsWith(p)); + } else { + supportsIdPrefix = true; + } + break; + } + } + } + + return hasStreamResource && supportsIdPrefix; + }); + // Check if local scrapers are enabled and execute them first try { // Load settings from AsyncStorage directly (scoped with fallback) @@ -1396,64 +1439,109 @@ class StremioService { // TMDB Embed addon not found } - // Find addons that provide streams and sort them by installation order - const streamAddons = addons - .filter(addon => { - if (!addon.resources || !Array.isArray(addon.resources)) { - logger.log(`⚠️ [getStreams] Addon ${addon.id} has no valid resources array`); - return false; + let effectiveType = type; + let streamAddons = pickStreamAddons(type); + + logger.log(`🧭 [getStreams] Resolving stream addons for type='${type}' id='${id}' (matched=${streamAddons.length})`); + + if (streamAddons.length === 0) { + const fallbackTypes = ['series', 'movie', 'tv', 'channel'].filter(t => t !== type); + for (const fallbackType of fallbackTypes) { + const fallbackAddons = pickStreamAddons(fallbackType); + if (fallbackAddons.length > 0) { + effectiveType = fallbackType; + streamAddons = fallbackAddons; + logger.log(`🔁 [getStreams] No stream addons for type '${type}', falling back to '${effectiveType}' for id '${id}'`); + break; } + } + } - let hasStreamResource = false; - let supportsIdPrefix = false; - - // Iterate through the resources array, checking each element - for (const resource of addon.resources) { - // Check if the current element is a ResourceObject - if (typeof resource === 'object' && resource !== null && 'name' in resource) { - const typedResource = resource as ResourceObject; - if (typedResource.name === 'stream' && - Array.isArray(typedResource.types) && - typedResource.types.includes(type)) { - hasStreamResource = true; - - // Check if this addon supports the ID prefix (generic: any prefix that matches start of id) - if (Array.isArray(typedResource.idPrefixes) && typedResource.idPrefixes.length > 0) { - supportsIdPrefix = typedResource.idPrefixes.some(p => id.startsWith(p)); - } else { - // If no idPrefixes specified, assume it supports all prefixes - supportsIdPrefix = true; - } - break; // Found the stream resource object, no need to check further - } - } - // Check if the element is the simple string "stream" AND the addon has a top-level types array - else if (typeof resource === 'string' && resource === 'stream' && addon.types) { - if (Array.isArray(addon.types) && addon.types.includes(type)) { - hasStreamResource = true; - // For simple string resources, check addon-level idPrefixes (generic) - if (addon.idPrefixes && Array.isArray(addon.idPrefixes) && addon.idPrefixes.length > 0) { - supportsIdPrefix = addon.idPrefixes.some(p => id.startsWith(p)); - } else { - // If no idPrefixes specified, assume it supports all prefixes - supportsIdPrefix = true; - } - break; // Found the simple stream resource string and type support - } - } - } - - const canHandleRequest = hasStreamResource && supportsIdPrefix; - - return canHandleRequest; - }); - - + if (effectiveType !== type) { + logger.log(`🧭 [getStreams] Using effectiveType='${effectiveType}' (requested='${type}') for id='${id}'`); + } if (streamAddons.length === 0) { logger.warn('⚠️ [getStreams] No addons found that can provide streams'); - // Optionally call callback with an empty result or specific status? - // For now, just return if no addons. + + // Log what the URL would have been for debugging + const encodedId = encodeURIComponent(id); + const exampleUrl = `/stream/${effectiveType}/${encodedId}.json`; + logger.log(`🚫 [getStreams] No stream addons matched. Would have requested: ${exampleUrl}`); + logger.log(`🚫 [getStreams] Details: requestedType='${type}' effectiveType='${effectiveType}' id='${id}'`); + + // Show which addons have stream capability but didn't match + const streamCapableAddons = addons.filter(addon => { + if (!addon.resources || !Array.isArray(addon.resources)) return false; + return addon.resources.some(resource => { + if (typeof resource === 'object' && resource !== null && 'name' in resource) { + return (resource as ResourceObject).name === 'stream'; + } + return typeof resource === 'string' && resource === 'stream'; + }); + }); + + if (streamCapableAddons.length > 0) { + logger.log(`🚫 [getStreams] Found ${streamCapableAddons.length} stream-capable addon(s) that didn't match:`); + + for (const addon of streamCapableAddons) { + const streamResources = addon.resources!.filter(resource => { + if (typeof resource === 'object' && resource !== null && 'name' in resource) { + return (resource as ResourceObject).name === 'stream'; + } + return typeof resource === 'string' && resource === 'stream'; + }); + + for (const resource of streamResources) { + if (typeof resource === 'object' && resource !== null) { + const typedResource = resource as ResourceObject; + const types = typedResource.types || []; + const prefixes = typedResource.idPrefixes || []; + const typeMatch = types.includes(effectiveType); + const prefixMatch = prefixes.length === 0 || prefixes.some(p => id.startsWith(p)); + + if (addon.url) { + const { baseUrl, queryParams } = this.getAddonBaseURL(addon.url); + const wouldBeUrl = queryParams + ? `${baseUrl}/stream/${effectiveType}/${encodedId}.json?${queryParams}` + : `${baseUrl}/stream/${effectiveType}/${encodedId}.json`; + + console.log( + ` ❌ ${addon.name} (${addon.id}):\n` + + ` types=[${types.join(',')}] typeMatch=${typeMatch}\n` + + ` prefixes=[${prefixes.join(',')}] prefixMatch=${prefixMatch}\n` + + ` url=${wouldBeUrl}` + ); + } else { + console.log(` ❌ ${addon.name} (${addon.id}): no URL configured`); + } + } else if (typeof resource === 'string' && resource === 'stream') { + // String resource - check addon-level types and prefixes + const addonTypes = addon.types || []; + const addonPrefixes = addon.idPrefixes || []; + const typeMatch = addonTypes.includes(effectiveType); + const prefixMatch = addonPrefixes.length === 0 || addonPrefixes.some(p => id.startsWith(p)); + + if (addon.url) { + const { baseUrl, queryParams } = this.getAddonBaseURL(addon.url); + const wouldBeUrl = queryParams + ? `${baseUrl}/stream/${effectiveType}/${encodedId}.json?${queryParams}` + : `${baseUrl}/stream/${effectiveType}/${encodedId}.json`; + + console.log( + ` ❌ ${addon.name} (${addon.id}) [addon-level]:\n` + + ` types=[${addonTypes.join(',')}] typeMatch=${typeMatch}\n` + + ` prefixes=[${addonPrefixes.join(',')}] prefixMatch=${prefixMatch}\n` + + ` url=${wouldBeUrl}` + ); + } + } + } + } + } else { + logger.log(`🚫 [getStreams] No stream-capable addons installed`); + } + return; } @@ -1470,9 +1558,11 @@ class StremioService { const { baseUrl, queryParams } = this.getAddonBaseURL(addon.url); const encodedId = encodeURIComponent(id); - const url = queryParams ? `${baseUrl}/stream/${type}/${encodedId}.json?${queryParams}` : `${baseUrl}/stream/${type}/${encodedId}.json`; + const url = queryParams ? `${baseUrl}/stream/${effectiveType}/${encodedId}.json?${queryParams}` : `${baseUrl}/stream/${effectiveType}/${encodedId}.json`; - logger.log(`🔗 [getStreams] Requesting streams from ${addon.name} (${addon.id}) [${addon.installationId}]: ${url}`); + logger.log( + `🔗 [getStreams] GET ${url} (addon='${addon.name}' id='${addon.id}' install='${addon.installationId}' requestedType='${type}' effectiveType='${effectiveType}' rawId='${id}')` + ); const response = await this.retryRequest(async () => { return await axios.get(url, safeAxiosConfig); @@ -1517,14 +1607,16 @@ class StremioService { const streamPath = `/stream/${type}/${encodedId}.json`; const url = queryParams ? `${baseUrl}${streamPath}?${queryParams}` : `${baseUrl}${streamPath}`; - logger.log(`Fetching streams from URL: ${url}`); + logger.log( + `🔗 [fetchStreamsFromAddon] GET ${url} (addon='${addon.name}' id='${addon.id}' install='${addon.installationId}' type='${type}' rawId='${id}')` + ); try { // Increase timeout for debrid services const timeout = addon.id.toLowerCase().includes('torrentio') ? 60000 : 10000; const response = await this.retryRequest(async () => { - logger.log(`Making request to ${url} with timeout ${timeout}ms`); + logger.log(`🌐 [fetchStreamsFromAddon] Requesting ${url} (timeout=${timeout}ms)`); return await axios.get(url, createSafeAxiosConfig(timeout, { headers: { 'Accept': 'application/json', @@ -1895,6 +1987,65 @@ class StremioService { return false; } + // Reconcile local addon order to match a remote ordered list of addon manifest URLs. + // Any local addons not present in the remote list are appended in their current order. + async applyAddonOrderFromManifestUrls(manifestUrls: string[]): Promise { + await this.ensureInitialized(); + if (!Array.isArray(manifestUrls) || manifestUrls.length === 0) return false; + + const normalizeManifestUrl = (raw: string): string => { + const value = (raw || '').trim(); + if (!value) return ''; + const withManifest = value.includes('manifest.json') + ? value + : `${value.replace(/\/$/, '')}/manifest.json`; + return withManifest.toLowerCase(); + }; + + const localByNormalizedUrl = new Map(); + for (const installationId of this.addonOrder) { + const addon = this.installedAddons.get(installationId); + if (!addon) continue; + const normalized = normalizeManifestUrl(addon.originalUrl || addon.url || ''); + if (!normalized) continue; + const list = localByNormalizedUrl.get(normalized) || []; + list.push(installationId); + localByNormalizedUrl.set(normalized, list); + } + + const nextOrder: string[] = []; + const seenInstallations = new Set(); + + for (const remoteUrl of manifestUrls) { + const normalizedRemote = normalizeManifestUrl(remoteUrl); + if (!normalizedRemote) continue; + const candidates = localByNormalizedUrl.get(normalizedRemote); + if (!candidates || candidates.length === 0) continue; + const installationId = candidates.shift(); + if (!installationId || seenInstallations.has(installationId)) continue; + nextOrder.push(installationId); + seenInstallations.add(installationId); + } + + for (const installationId of this.addonOrder) { + if (!this.installedAddons.has(installationId)) continue; + if (seenInstallations.has(installationId)) continue; + nextOrder.push(installationId); + seenInstallations.add(installationId); + } + + const changed = + nextOrder.length !== this.addonOrder.length || + nextOrder.some((id, index) => id !== this.addonOrder[index]); + + if (!changed) return false; + + this.addonOrder = nextOrder; + await this.saveAddonOrder(); + addonEmitter.emit(ADDON_EVENTS.ORDER_CHANGED); + return true; + } + // Check if any installed addons can provide streams (including embedded streams in metadata) async hasStreamProviders(type?: string): Promise { await this.ensureInitialized(); @@ -1997,4 +2148,4 @@ export interface AddonCatalogItem { } export const stremioService = StremioService.getInstance(); -export default stremioService; \ No newline at end of file +export default stremioService; diff --git a/src/services/supabaseSyncService.ts b/src/services/supabaseSyncService.ts new file mode 100644 index 00000000..2134edbc --- /dev/null +++ b/src/services/supabaseSyncService.ts @@ -0,0 +1,1299 @@ +import { AppState, Platform } from 'react-native'; +import { mmkvStorage } from './mmkvStorage'; +import { logger } from '../utils/logger'; +import { localScraperService, PLUGIN_SYNC_EVENTS } from './pluginService'; +import { stremioService, addonEmitter, ADDON_EVENTS, Manifest } from './stremioService'; +import { catalogService, StreamingContent } from './catalogService'; +import { storageService } from './storageService'; +import { watchedService, LocalWatchedItem } from './watchedService'; +import { TraktService } from './traktService'; + +const SUPABASE_SESSION_KEY = '@supabase:session'; +const DEFAULT_SYNC_DEBOUNCE_MS = 2000; + +type Nullable = T | null; + +export type SupabaseUser = { + id: string; + email?: string; + user_metadata?: { + display_name?: string; + avatar_url?: string; + [key: string]: unknown; + }; + app_metadata?: { + provider?: string; + [key: string]: unknown; + }; +}; + +type SupabaseSession = { + access_token: string; + refresh_token: string; + expires_at?: number; + expires_in?: number; + token_type?: string; + user: SupabaseUser; +}; + +type PluginRow = { + url: string; + name?: string; + enabled?: boolean; + sort_order?: number; +}; + +type AddonRow = { + url: string; + sort_order: number; +}; + +type WatchProgressRow = { + content_id: string; + content_type: 'movie' | 'series'; + video_id: string; + season: Nullable; + episode: Nullable; + position: number; + duration: number; + last_watched: number; + progress_key: string; +}; + +type LibraryRow = { + content_id: string; + content_type: string; + name?: string; + poster?: string; + poster_shape?: string; + background?: string; + description?: string; + release_info?: string; + imdb_rating?: number; + genres?: string[]; + addon_base_url?: string; + added_at?: number; +}; + +type WatchedRow = { + content_id: string; + content_type: string; + title?: string; + season: Nullable; + episode: Nullable; + watched_at: number; +}; + +type RpcClaimSyncCodeRow = { + result_owner_id: Nullable; + success: boolean; + message: string; +}; + +export type LinkedDevice = { + owner_id: string; + device_user_id: string; + device_name?: string; + linked_at: string; +}; + +export type RemoteSyncStats = { + plugins: number; + addons: number; + watchProgress: number; + libraryItems: number; + watchedItems: number; + linkedDevices: number; +}; + +type PushTarget = 'plugins' | 'addons' | 'watch_progress' | 'library' | 'watched_items'; + +class SupabaseSyncService { + private static instance: SupabaseSyncService; + + private readonly supabaseUrl: string; + private readonly anonKey: string; + private session: SupabaseSession | null = null; + private initializePromise: Promise | null = null; + private startupSyncPromise: Promise | null = null; + private listenersRegistered = false; + private suppressPushes = false; + private appStateSub: { remove: () => void } | null = null; + private lastForegroundPullAt = 0; + private readonly foregroundPullCooldownMs = 30000; + + private pendingPushTimers: Record | null> = { + plugins: null, + addons: null, + watch_progress: null, + library: null, + watched_items: null, + }; + + private constructor() { + this.supabaseUrl = (process.env.EXPO_PUBLIC_SUPABASE_URL || '').replace(/\/$/, ''); + this.anonKey = process.env.EXPO_PUBLIC_SUPABASE_ANON_KEY || ''; + } + + static getInstance(): SupabaseSyncService { + if (!SupabaseSyncService.instance) { + SupabaseSyncService.instance = new SupabaseSyncService(); + } + return SupabaseSyncService.instance; + } + + public isConfigured(): boolean { + return Boolean(this.supabaseUrl && this.anonKey); + } + + public getCurrentSessionUser(): SupabaseUser | null { + return this.session?.user || null; + } + + public isAnonymousSession(): boolean { + return this.session?.user?.app_metadata?.provider === 'anonymous'; + } + + public async initialize(): Promise { + if (!this.isConfigured()) { + logger.warn('[SupabaseSyncService] Missing Supabase env vars; sync disabled.'); + return; + } + + if (this.initializePromise) { + await this.initializePromise; + return; + } + + this.initializePromise = (async () => { + await this.loadStoredSession(); + await this.ensureValidSession(); + this.registerSyncListeners(); + })(); + + try { + await this.initializePromise; + } finally { + this.initializePromise = null; + } + } + + public async signUpWithEmail(email: string, password: string): Promise<{ user?: SupabaseUser; error?: string }> { + if (!this.isConfigured()) { + return { error: 'Supabase is not configured' }; + } + + try { + const response = await this.requestAuth<{ user?: SupabaseUser; session?: SupabaseSession }>('/auth/v1/signup', { + method: 'POST', + body: { email, password }, + }); + + if (response.session) { + await this.setSession(response.session); + } + + // In email-confirmation mode, Supabase may not establish a session immediately. + // Treat this as a successful signup attempt and let caller handle next UX step. + return { user: response.user }; + } catch (error: any) { + return { error: this.extractErrorMessage(error, 'Signup failed') }; + } + } + + public async signInWithEmail(email: string, password: string): Promise<{ user?: SupabaseUser; error?: string }> { + if (!this.isConfigured()) { + return { error: 'Supabase is not configured' }; + } + + try { + const response = await this.requestAuth('/auth/v1/token?grant_type=password', { + method: 'POST', + body: { email, password }, + }); + await this.setSession(response); + return { user: response.user }; + } catch (error: any) { + return { error: this.extractErrorMessage(error, 'Sign in failed') }; + } + } + + public async signOut(): Promise { + if (!this.isConfigured()) return; + const token = await this.getValidAccessToken(); + + if (token) { + try { + await this.request('/auth/v1/logout', { + method: 'POST', + authToken: token, + }); + } catch (error) { + logger.warn('[SupabaseSyncService] Supabase logout request failed, clearing local session:', error); + } + } + + this.session = null; + await mmkvStorage.removeItem(SUPABASE_SESSION_KEY); + } + + public async startupSync(): Promise { + if (!this.isConfigured()) return; + await this.initialize(); + logger.log('[SupabaseSyncService] startupSync: begin'); + + if (this.startupSyncPromise) { + await this.startupSyncPromise; + return; + } + + this.startupSyncPromise = this.runStartupSync(); + try { + await this.startupSyncPromise; + logger.log('[SupabaseSyncService] startupSync: complete'); + } finally { + this.startupSyncPromise = null; + } + } + + public async onSignUpPushAll(): Promise { + await this.pushAllLocalData(); + } + + public async onSignInPullAll(): Promise { + await this.pullAllToLocal(); + } + + public async syncNow(): Promise { + await this.startupSync(); + } + + public async pushAllLocalData(): Promise { + await this.initialize(); + logger.log('[SupabaseSyncService] pushAllLocalData: begin'); + + await this.pushPluginsFromLocal(); + await this.pushAddonsFromLocal(); + + const traktConnected = await this.isTraktConnected(); + if (traktConnected) { + return; + } + + await this.pushWatchProgressFromLocal(); + await this.pushLibraryFromLocal(); + await this.pushWatchedItemsFromLocal(); + logger.log('[SupabaseSyncService] pushAllLocalData: complete'); + } + + public async pullAllToLocal(): Promise { + await this.initialize(); + logger.log('[SupabaseSyncService] pullAllToLocal: begin'); + + await this.withSuppressedPushes(async () => { + await this.pullPluginsToLocal(); + await this.pullAddonsToLocal(); + + const traktConnected = await this.isTraktConnected(); + if (traktConnected) { + return; + } + + await this.pullWatchProgressToLocal(); + await this.pullLibraryToLocal(); + await this.pullWatchedItemsToLocal(); + }); + logger.log('[SupabaseSyncService] pullAllToLocal: complete'); + } + + public async generateSyncCode(pin: string): Promise<{ code?: string; error?: string }> { + try { + await this.pushAllLocalData(); + const response = await this.callRpc>('generate_sync_code', { p_pin: pin }); + const code = response?.[0]?.code; + if (!code) return { error: 'Failed to generate sync code' }; + return { code }; + } catch (error: any) { + return { error: this.extractErrorMessage(error, 'Failed to generate sync code') }; + } + } + + public async getSyncCode(pin: string): Promise<{ code?: string; error?: string }> { + try { + const response = await this.callRpc>('get_sync_code', { p_pin: pin }); + const code = response?.[0]?.code; + if (!code) return { error: 'No sync code found' }; + return { code }; + } catch (error: any) { + return { error: this.extractErrorMessage(error, 'Failed to fetch sync code') }; + } + } + + public async claimSyncCode(code: string, pin: string, deviceName?: string): Promise<{ success: boolean; message: string }> { + try { + const response = await this.callRpc('claim_sync_code', { + p_code: code, + p_pin: pin, + p_device_name: deviceName || `Nuvio ${Platform.OS}`, + }); + const result = response?.[0]; + if (!result || !result.success) { + return { + success: false, + message: result?.message || 'Failed to claim sync code', + }; + } + + await this.pullAllToLocal(); + + return { + success: true, + message: result.message || 'Device linked successfully', + }; + } catch (error: any) { + return { + success: false, + message: this.extractErrorMessage(error, 'Failed to claim sync code'), + }; + } + } + + public async getLinkedDevices(): Promise { + try { + const token = await this.getValidAccessToken(); + if (!token) return []; + + const ownerId = await this.getEffectiveOwnerId(); + if (!ownerId) return []; + + return await this.request( + `/rest/v1/linked_devices?select=owner_id,device_user_id,device_name,linked_at&owner_id=eq.${encodeURIComponent(ownerId)}&order=linked_at.desc`, + { + method: 'GET', + authToken: token, + } + ); + } catch (error) { + logger.error('[SupabaseSyncService] Failed to fetch linked devices:', error); + return []; + } + } + + public async getRemoteStats(): Promise { + try { + const token = await this.getValidAccessToken(); + if (!token) return null; + + const ownerId = await this.getEffectiveOwnerId(); + if (!ownerId) return null; + + const ownerFilter = encodeURIComponent(ownerId); + const [ + pluginRows, + addonRows, + watchRows, + libraryRows, + watchedRows, + deviceRows, + ] = await Promise.all([ + this.request>(`/rest/v1/plugins?select=id&user_id=eq.${ownerFilter}`, { + method: 'GET', + authToken: token, + }), + this.request>(`/rest/v1/addons?select=id&user_id=eq.${ownerFilter}`, { + method: 'GET', + authToken: token, + }), + this.request>(`/rest/v1/watch_progress?select=id&user_id=eq.${ownerFilter}`, { + method: 'GET', + authToken: token, + }), + this.request>(`/rest/v1/library_items?select=id&user_id=eq.${ownerFilter}`, { + method: 'GET', + authToken: token, + }), + this.request>(`/rest/v1/watched_items?select=id&user_id=eq.${ownerFilter}`, { + method: 'GET', + authToken: token, + }), + this.request>(`/rest/v1/linked_devices?select=device_user_id&owner_id=eq.${ownerFilter}`, { + method: 'GET', + authToken: token, + }), + ]); + + return { + plugins: pluginRows?.length || 0, + addons: addonRows?.length || 0, + watchProgress: watchRows?.length || 0, + libraryItems: libraryRows?.length || 0, + watchedItems: watchedRows?.length || 0, + linkedDevices: deviceRows?.length || 0, + }; + } catch (error) { + logger.warn('[SupabaseSyncService] Failed to fetch remote stats:', error); + return null; + } + } + + public async unlinkDevice(deviceUserId: string): Promise<{ success: boolean; error?: string }> { + try { + await this.callRpc('unlink_device', { p_device_user_id: deviceUserId }); + return { success: true }; + } catch (error: any) { + return { + success: false, + error: this.extractErrorMessage(error, 'Failed to unlink device'), + }; + } + } + + public async getEffectiveOwnerId(): Promise { + try { + const response = await this.callRpc('get_sync_owner', {}); + if (typeof response === 'string') return response; + if (Array.isArray(response)) { + const first = response[0]; + if (typeof first === 'string') return first; + if (first && typeof first === 'object') { + const candidate = (first as any).get_sync_owner || (first as any).id; + return typeof candidate === 'string' ? candidate : null; + } + } + if (response && typeof response === 'object') { + const candidate = (response as any).get_sync_owner || (response as any).id; + return typeof candidate === 'string' ? candidate : null; + } + return null; + } catch (error) { + logger.error('[SupabaseSyncService] Failed to resolve effective owner id:', error); + return null; + } + } + + private async runStartupSync(): Promise { + logger.log('[SupabaseSyncService] runStartupSync: step=pull_plugins:start'); + const pluginPullOk = await this.safeRun('pull_plugins', async () => { + await this.withSuppressedPushes(async () => { + await this.pullPluginsToLocal(); + }); + }); + logger.log(`[SupabaseSyncService] runStartupSync: step=pull_plugins:done ok=${pluginPullOk}`); + + logger.log('[SupabaseSyncService] runStartupSync: step=pull_addons:start'); + const addonPullOk = await this.safeRun('pull_addons', async () => { + await this.withSuppressedPushes(async () => { + await this.pullAddonsToLocal(); + }); + }); + logger.log(`[SupabaseSyncService] runStartupSync: step=pull_addons:done ok=${addonPullOk}`); + if (!pluginPullOk || !addonPullOk) { + logger.warn('[SupabaseSyncService] runStartupSync: one or more pull steps failed; skipped startup push-by-design'); + } + + const traktConnected = await this.isTraktConnected(); + if (traktConnected) { + logger.log('[SupabaseSyncService] Trakt is connected; skipping progress/library/watched Supabase sync.'); + return; + } + + const watchPullOk = await this.safeRun('pull_watch_progress', async () => { + await this.withSuppressedPushes(async () => { + await this.pullWatchProgressToLocal(); + }); + }); + + const libraryPullOk = await this.safeRun('pull_library', async () => { + await this.withSuppressedPushes(async () => { + await this.pullLibraryToLocal(); + }); + }); + + const watchedPullOk = await this.safeRun('pull_watched_items', async () => { + await this.withSuppressedPushes(async () => { + await this.pullWatchedItemsToLocal(); + }); + }); + + if (!watchPullOk || !libraryPullOk || !watchedPullOk) { + logger.warn('[SupabaseSyncService] runStartupSync: one or more content pulls failed; skipped startup push-by-design'); + } + } + + private async safeRun(step: string, task: () => Promise): Promise { + try { + await task(); + return true; + } catch (error) { + logger.error(`[SupabaseSyncService] Sync step failed (${step}):`, error); + return false; + } + } + + private registerSyncListeners(): void { + if (this.listenersRegistered) return; + this.listenersRegistered = true; + + addonEmitter.on(ADDON_EVENTS.ADDON_ADDED, () => this.schedulePush('addons')); + addonEmitter.on(ADDON_EVENTS.ADDON_REMOVED, () => this.schedulePush('addons')); + addonEmitter.on(ADDON_EVENTS.ORDER_CHANGED, () => this.schedulePush('addons')); + + localScraperService.getPluginSyncEventEmitter().on(PLUGIN_SYNC_EVENTS.CHANGED, () => this.schedulePush('plugins')); + + catalogService.onLibraryAdd(() => this.schedulePush('library')); + catalogService.onLibraryRemove(() => this.schedulePush('library')); + + storageService.subscribeToWatchProgressUpdates(() => this.schedulePush('watch_progress')); + storageService.onWatchProgressRemoved(() => this.schedulePush('watch_progress')); + + watchedService.subscribeToWatchedUpdates(() => this.schedulePush('watched_items')); + + if (!this.appStateSub) { + this.appStateSub = AppState.addEventListener('change', (state) => { + if (state === 'active') { + this.onAppForeground().catch((error) => { + logger.warn('[SupabaseSyncService] Foreground pull failed:', error); + }); + } + }); + } + } + + private async onAppForeground(): Promise { + if (!this.isConfigured()) return; + if (this.suppressPushes) return; + + const now = Date.now(); + if (now - this.lastForegroundPullAt < this.foregroundPullCooldownMs) return; + this.lastForegroundPullAt = now; + logger.log('[SupabaseSyncService] App foreground: triggering pullAllToLocal'); + + await this.initialize(); + if (!this.session) return; + + await this.safeRun('foreground_pull_all', async () => { + await this.pullAllToLocal(); + }); + } + + private schedulePush(target: PushTarget): void { + if (!this.isConfigured() || this.suppressPushes) { + return; + } + + const existing = this.pendingPushTimers[target]; + if (existing) clearTimeout(existing); + logger.log(`[SupabaseSyncService] schedulePush: target=${target} delayMs=${DEFAULT_SYNC_DEBOUNCE_MS}`); + + this.pendingPushTimers[target] = setTimeout(() => { + this.pendingPushTimers[target] = null; + this.executeScheduledPush(target).catch((error) => { + logger.error(`[SupabaseSyncService] Scheduled push failed (${target}):`, error); + }); + }, DEFAULT_SYNC_DEBOUNCE_MS); + } + + private async executeScheduledPush(target: PushTarget): Promise { + await this.initialize(); + if (!this.session) return; + logger.log(`[SupabaseSyncService] executeScheduledPush: target=${target}:start`); + + if (target === 'plugins') { + await this.pushPluginsFromLocal(); + logger.log(`[SupabaseSyncService] executeScheduledPush: target=${target}:done`); + return; + } + + if (target === 'addons') { + await this.pushAddonsFromLocal(); + logger.log(`[SupabaseSyncService] executeScheduledPush: target=${target}:done`); + return; + } + + const traktConnected = await this.isTraktConnected(); + if (traktConnected) { + return; + } + + if (target === 'watch_progress') { + await this.pushWatchProgressFromLocal(); + logger.log(`[SupabaseSyncService] executeScheduledPush: target=${target}:done`); + return; + } + if (target === 'library') { + await this.pushLibraryFromLocal(); + logger.log(`[SupabaseSyncService] executeScheduledPush: target=${target}:done`); + return; + } + + await this.pushWatchedItemsFromLocal(); + logger.log(`[SupabaseSyncService] executeScheduledPush: target=${target}:done`); + } + + private async withSuppressedPushes(task: () => Promise): Promise { + this.suppressPushes = true; + try { + await task(); + } finally { + this.suppressPushes = false; + } + } + + private async loadStoredSession(): Promise { + try { + const raw = await mmkvStorage.getItem(SUPABASE_SESSION_KEY); + if (!raw) { + this.session = null; + return; + } + this.session = JSON.parse(raw) as SupabaseSession; + } catch (error) { + logger.error('[SupabaseSyncService] Failed to load stored session:', error); + this.session = null; + await mmkvStorage.removeItem(SUPABASE_SESSION_KEY); + } + } + + private async setSession(session: SupabaseSession): Promise { + this.session = session; + await mmkvStorage.setItem(SUPABASE_SESSION_KEY, JSON.stringify(session)); + } + + private isSessionExpired(session: SupabaseSession): boolean { + if (!session.expires_at) return false; + const now = Math.floor(Date.now() / 1000); + return now >= (session.expires_at - 30); + } + + private async refreshSession(refreshToken: string): Promise { + return await this.requestAuth('/auth/v1/token?grant_type=refresh_token', { + method: 'POST', + body: { refresh_token: refreshToken }, + }); + } + + private async ensureValidSession(): Promise { + if (!this.session) return false; + if (!this.session.access_token || !this.session.refresh_token) return false; + + if (!this.isSessionExpired(this.session)) return true; + + try { + const refreshed = await this.refreshSession(this.session.refresh_token); + await this.setSession(refreshed); + return true; + } catch (error) { + logger.error('[SupabaseSyncService] Failed to refresh session:', error); + this.session = null; + await mmkvStorage.removeItem(SUPABASE_SESSION_KEY); + return false; + } + } + + private async getValidAccessToken(): Promise { + await this.initialize(); + if (!this.session) return null; + + if (this.isSessionExpired(this.session)) { + try { + const refreshed = await this.refreshSession(this.session.refresh_token); + await this.setSession(refreshed); + } catch (error) { + logger.error('[SupabaseSyncService] Token refresh failed:', error); + this.session = null; + await mmkvStorage.removeItem(SUPABASE_SESSION_KEY); + return null; + } + } + + return this.session?.access_token || null; + } + + private async requestAuth(path: string, options: { method: string; body?: unknown }): Promise { + return await this.request(path, { + method: options.method, + body: options.body, + authToken: null, + }); + } + + private async request( + path: string, + options: { + method: string; + body?: unknown; + authToken: string | null; + } + ): Promise { + if (!this.isConfigured()) { + throw new Error('Supabase is not configured'); + } + + const headers: Record = { + apikey: this.anonKey, + }; + if (options.authToken) { + headers.Authorization = `Bearer ${options.authToken}`; + } + if (options.body !== undefined) { + headers['Content-Type'] = 'application/json'; + } + + const response = await fetch(`${this.supabaseUrl}${path}`, { + method: options.method, + headers, + body: options.body === undefined ? undefined : JSON.stringify(options.body), + }); + + const raw = await response.text(); + const parsed = this.parsePayload(raw); + + if (!response.ok) { + throw this.buildRequestError(response.status, parsed, raw); + } + + return parsed as T; + } + + private parsePayload(raw: string): unknown { + if (!raw) return null; + try { + return JSON.parse(raw); + } catch { + return raw; + } + } + + private buildRequestError(status: number, parsed: unknown, raw: string): Error { + if (parsed && typeof parsed === 'object') { + const message = + (parsed as any).message || + (parsed as any).msg || + (parsed as any).error_description || + (parsed as any).error; + if (typeof message === 'string' && message.trim().length > 0) { + return new Error(message); + } + } + if (raw && raw.trim().length > 0) { + return new Error(raw); + } + return new Error(`Supabase request failed with status ${status}`); + } + + private extractErrorMessage(error: unknown, fallback: string): string { + if (error instanceof Error && error.message) { + const raw = error.message.trim(); + + let parsed: any = null; + if (raw.startsWith('{') && raw.endsWith('}')) { + try { + parsed = JSON.parse(raw); + } catch { + parsed = null; + } + } + + const errorCode = (parsed?.error_code || parsed?.code || '').toString().toLowerCase(); + const message = (parsed?.msg || parsed?.message || raw).toString().trim(); + + if (errorCode === 'invalid_credentials') { + return 'Invalid email or password'; + } + if (errorCode === 'email_not_confirmed') { + return 'Email not confirmed. Check your inbox or Spam/Junk folder, verify your account, then sign in.'; + } + + if (message.length > 0) { + return message; + } + } + return fallback; + } + + private async callRpc(functionName: string, payload?: Record): Promise { + const token = await this.getValidAccessToken(); + if (!token) { + throw new Error('Not authenticated'); + } + + return await this.request(`/rest/v1/rpc/${functionName}`, { + method: 'POST', + body: payload || {}, + authToken: token, + }); + } + + private normalizeUrl(url: string): string { + return url.trim().toLowerCase(); + } + + private toBigIntNumber(value: unknown): number { + const n = Number(value); + if (!Number.isFinite(n) || n <= 0) return 0; + return Math.trunc(n); + } + + private secondsToMsLong(value: unknown): number { + const n = Number(value); + if (!Number.isFinite(n) || n <= 0) return 0; + return Math.trunc(n * 1000); + } + + private normalizeEpochMs(value: unknown): number { + const n = Number(value); + if (!Number.isFinite(n) || n <= 0) return 0; + // If value looks like seconds, convert to milliseconds. + if (n < 1_000_000_000_000) { + return Math.trunc(n * 1000); + } + return Math.trunc(n); + } + + private msToSeconds(value: unknown): number { + const n = Number(value); + if (!Number.isFinite(n) || n <= 0) return 0; + return n / 1000; + } + + private addonManifestUrl(addon: Manifest): string | null { + const raw = (addon.originalUrl || addon.url || '').trim(); + if (!raw) return null; + if (raw.includes('manifest.json')) return raw; + return `${raw.replace(/\/$/, '')}/manifest.json`; + } + + private parseWatchProgressKey(key: string): { + contentType: 'movie' | 'series'; + contentId: string; + season: number | null; + episode: number | null; + videoId: string; + progressKey: string; + } | null { + const parts = key.split(':'); + if (parts.length < 2) return null; + + const contentType: 'movie' | 'series' = parts[0] === 'movie' ? 'movie' : 'series'; + const contentId = parts[1]; + const episodeId = parts.length > 2 ? parts.slice(2).join(':') : ''; + let season: number | null = null; + let episode: number | null = null; + + if (episodeId) { + const match = episodeId.match(/:(\d+):(\d+)$/); + if (match) { + season = Number(match[1]); + episode = Number(match[2]); + } + } + + const videoId = episodeId || contentId; + const progressKey = contentType === 'movie' + ? contentId + : (season != null && episode != null ? `${contentId}_s${season}e${episode}` : `${contentId}_${videoId}`); + + return { + contentType, + contentId, + season, + episode, + videoId, + progressKey, + }; + } + + private toStreamingContent(item: LibraryRow): StreamingContent { + const type = item.content_type === 'movie' ? 'movie' : 'series'; + const posterShape = (item.poster_shape || 'POSTER').toLowerCase() as 'poster' | 'square' | 'landscape'; + + return { + id: item.content_id, + type, + name: item.name || '', + poster: item.poster || '', + posterShape, + banner: item.background, + description: item.description, + releaseInfo: item.release_info, + imdbRating: item.imdb_rating != null ? String(item.imdb_rating) : undefined, + genres: item.genres || [], + addonId: item.addon_base_url, + addedToLibraryAt: item.added_at, + inLibrary: true, + }; + } + + private toWatchedItem(row: WatchedRow): LocalWatchedItem { + return { + content_id: row.content_id, + content_type: row.content_type === 'movie' ? 'movie' : 'series', + title: row.title || '', + season: row.season == null ? null : Number(row.season), + episode: row.episode == null ? null : Number(row.episode), + watched_at: Number(row.watched_at || Date.now()), + }; + } + + private async isTraktConnected(): Promise { + try { + return await TraktService.getInstance().isAuthenticated(); + } catch { + return false; + } + } + + private async pullPluginsToLocal(): Promise { + const token = await this.getValidAccessToken(); + if (!token) return; + const ownerId = await this.getEffectiveOwnerId(); + if (!ownerId) return; + + const rows = await this.request( + `/rest/v1/plugins?select=url,name,enabled,sort_order&user_id=eq.${encodeURIComponent(ownerId)}&order=sort_order.asc`, + { + method: 'GET', + authToken: token, + } + ); + logger.log(`[SupabaseSyncService] pullPluginsToLocal: remoteCount=${rows?.length || 0}`); + + const localRepos = await localScraperService.getRepositories(); + const byUrl = new Map(localRepos.map((repo) => [this.normalizeUrl(repo.url), repo])); + const remoteSet = new Set( + (rows || []) + .map((row) => (row?.url ? this.normalizeUrl(row.url) : null)) + .filter((url): url is string => Boolean(url)) + ); + + for (const row of rows || []) { + if (!row.url) continue; + const normalized = this.normalizeUrl(row.url); + const existing = byUrl.get(normalized); + + if (!existing) { + await localScraperService.addRepository({ + name: row.name || localScraperService.extractRepositoryName(row.url), + url: row.url, + enabled: row.enabled !== false, + description: 'Synced from cloud', + }); + continue; + } + + const shouldUpdate = + (row.name && row.name !== existing.name) || + (typeof row.enabled === 'boolean' && row.enabled !== existing.enabled); + + if (shouldUpdate) { + await localScraperService.updateRepository(existing.id, { + name: row.name || existing.name, + enabled: typeof row.enabled === 'boolean' ? row.enabled : existing.enabled, + }); + } + } + + // Reconcile removals only when remote has at least one entry to avoid wiping local + // data if backend temporarily returns an empty set. + if (remoteSet.size > 0) { + let removedCount = 0; + for (const repo of localRepos) { + const normalized = this.normalizeUrl(repo.url); + if (remoteSet.has(normalized)) continue; + try { + await localScraperService.removeRepository(repo.id); + removedCount += 1; + } catch (error) { + logger.warn('[SupabaseSyncService] Failed to remove local plugin repository missing in remote set:', repo.name, error); + } + } + logger.log(`[SupabaseSyncService] pullPluginsToLocal: removedLocalExtras=${removedCount}`); + } else { + logger.log('[SupabaseSyncService] pullPluginsToLocal: remote set empty, skipped local prune'); + } + } + + private async pushPluginsFromLocal(): Promise { + const repos = await localScraperService.getRepositories(); + logger.log(`[SupabaseSyncService] pushPluginsFromLocal: localCount=${repos.length}`); + const payload: PluginRow[] = repos.map((repo, index) => ({ + url: repo.url, + name: repo.name, + enabled: repo.enabled !== false, + sort_order: index, + })); + await this.callRpc('sync_push_plugins', { p_plugins: payload }); + } + + private async pullAddonsToLocal(): Promise { + const token = await this.getValidAccessToken(); + if (!token) return; + const ownerId = await this.getEffectiveOwnerId(); + if (!ownerId) return; + + const rows = await this.request( + `/rest/v1/addons?select=url,sort_order&user_id=eq.${encodeURIComponent(ownerId)}&order=sort_order.asc`, + { + method: 'GET', + authToken: token, + } + ); + logger.log(`[SupabaseSyncService] pullAddonsToLocal: remoteCount=${rows?.length || 0}`); + const orderedRemoteUrls: string[] = []; + const seenRemoteUrls = new Set(); + for (const row of rows || []) { + if (!row?.url) continue; + const normalized = this.normalizeUrl(row.url); + if (seenRemoteUrls.has(normalized)) continue; + seenRemoteUrls.add(normalized); + orderedRemoteUrls.push(row.url); + } + + const installed = await stremioService.getInstalledAddonsAsync(); + logger.log(`[SupabaseSyncService] pullAddonsToLocal: localInstalledBefore=${installed.length}`); + const remoteSet = new Set( + (rows || []) + .map((row) => (row?.url ? this.normalizeUrl(row.url) : null)) + .filter((url): url is string => Boolean(url)) + ); + const installedUrls = new Set( + installed + .map((addon) => this.addonManifestUrl(addon)) + .filter((url): url is string => Boolean(url)) + .map((url) => this.normalizeUrl(url)) + ); + + for (const row of rows || []) { + if (!row.url) continue; + const normalized = this.normalizeUrl(row.url); + if (installedUrls.has(normalized)) continue; + + try { + await stremioService.installAddon(row.url); + installedUrls.add(normalized); + } catch (error) { + logger.warn('[SupabaseSyncService] Failed to install synced addon:', row.url, error); + } + } + + // Reconcile removals only when remote has at least one entry to avoid wiping local + // data if backend temporarily returns an empty set. + if (remoteSet.size > 0) { + let removedCount = 0; + for (const addon of installed) { + const url = this.addonManifestUrl(addon); + const normalized = url ? this.normalizeUrl(url) : null; + if (!normalized || remoteSet.has(normalized)) continue; + if (!addon.installationId) continue; + try { + await stremioService.removeAddon(addon.installationId); + removedCount += 1; + } catch (error) { + logger.warn('[SupabaseSyncService] Failed to remove local addon missing in remote set:', addon.name, error); + } + } + logger.log(`[SupabaseSyncService] pullAddonsToLocal: removedLocalExtras=${removedCount}`); + } else { + logger.log('[SupabaseSyncService] pullAddonsToLocal: remote set empty, skipped local prune'); + } + + if (orderedRemoteUrls.length > 0) { + try { + const changed = await stremioService.applyAddonOrderFromManifestUrls(orderedRemoteUrls); + logger.log(`[SupabaseSyncService] pullAddonsToLocal: orderReconciled changed=${changed}`); + } catch (error) { + logger.warn('[SupabaseSyncService] pullAddonsToLocal: failed to reconcile addon order:', error); + } + } + } + + private async pushAddonsFromLocal(): Promise { + const addons = await stremioService.getInstalledAddonsAsync(); + logger.log(`[SupabaseSyncService] pushAddonsFromLocal: localInstalledRaw=${addons.length}`); + const seen = new Set(); + const payload: AddonRow[] = addons.reduce((acc, addon) => { + const url = this.addonManifestUrl(addon); + if (!url) return acc; + const normalized = this.normalizeUrl(url); + if (seen.has(normalized)) return acc; + seen.add(normalized); + acc.push({ + url, + sort_order: acc.length, + }); + return acc; + }, []); + logger.log(`[SupabaseSyncService] pushAddonsFromLocal: payloadDeduped=${payload.length}`); + + await this.callRpc('sync_push_addons', { p_addons: payload }); + } + + private async pullWatchProgressToLocal(): Promise { + const rows = await this.callRpc('sync_pull_watch_progress', {}); + const remoteSet = new Set(); + + for (const row of rows || []) { + if (!row.content_id) continue; + const type = row.content_type === 'movie' ? 'movie' : 'series'; + const season = row.season == null ? null : Number(row.season); + const episode = row.episode == null ? null : Number(row.episode); + remoteSet.add(`${type}:${row.content_id}:${season ?? ''}:${episode ?? ''}`); + + const episodeId = type === 'series' && season != null && episode != null + ? `${row.content_id}:${season}:${episode}` + : undefined; + + const local = await storageService.getWatchProgress(row.content_id, type, episodeId); + const remoteLastWatched = this.normalizeEpochMs(row.last_watched); + if (local && Number(local.lastUpdated || 0) >= remoteLastWatched) { + continue; + } + + await storageService.setWatchProgress( + row.content_id, + type, + { + ...(local || {}), + currentTime: this.msToSeconds(row.position), + duration: this.msToSeconds(row.duration), + lastUpdated: remoteLastWatched || Date.now(), + }, + episodeId, + { + preserveTimestamp: true, + forceWrite: true, + forceNotify: true, + } + ); + } + + // Reconcile removals only when remote has at least one entry to avoid wiping local + // data if backend temporarily returns an empty set. + if (remoteSet.size > 0) { + const allLocal = await storageService.getAllWatchProgress(); + let removedCount = 0; + + for (const [key] of Object.entries(allLocal)) { + const parsed = this.parseWatchProgressKey(key); + if (!parsed) continue; + const localSig = `${parsed.contentType}:${parsed.contentId}:${parsed.season ?? ''}:${parsed.episode ?? ''}`; + if (remoteSet.has(localSig)) continue; + + const episodeId = parsed.contentType === 'series' && parsed.season != null && parsed.episode != null + ? `${parsed.contentId}:${parsed.season}:${parsed.episode}` + : undefined; + + await storageService.removeWatchProgress(parsed.contentId, parsed.contentType, episodeId); + removedCount += 1; + } + logger.log(`[SupabaseSyncService] pullWatchProgressToLocal: removedLocalExtras=${removedCount}`); + } else { + logger.log('[SupabaseSyncService] pullWatchProgressToLocal: remote set empty, skipped local prune'); + } + } + + private async pushWatchProgressFromLocal(): Promise { + const all = await storageService.getAllWatchProgress(); + const entries: WatchProgressRow[] = Object.entries(all).reduce((acc, [key, value]) => { + const parsed = this.parseWatchProgressKey(key); + if (!parsed) return acc; + acc.push({ + content_id: parsed.contentId, + content_type: parsed.contentType, + video_id: parsed.videoId, + season: parsed.season, + episode: parsed.episode, + position: this.secondsToMsLong(value.currentTime), + duration: this.secondsToMsLong(value.duration), + last_watched: this.normalizeEpochMs(value.lastUpdated || Date.now()), + progress_key: parsed.progressKey, + }); + return acc; + }, []); + + await this.callRpc('sync_push_watch_progress', { p_entries: entries }); + } + + private async pullLibraryToLocal(): Promise { + const rows = await this.callRpc('sync_pull_library', {}); + const localItems = await catalogService.getLibraryItems(); + const existing = new Set(localItems.map((item) => `${item.type}:${item.id}`)); + const remoteSet = new Set(); + + for (const row of rows || []) { + if (!row.content_id || !row.content_type) continue; + const type = row.content_type === 'movie' ? 'movie' : 'series'; + const key = `${type}:${row.content_id}`; + remoteSet.add(key); + if (existing.has(key)) continue; + + try { + await catalogService.addToLibrary(this.toStreamingContent(row)); + existing.add(key); + } catch (error) { + logger.warn('[SupabaseSyncService] Failed to merge library item from sync:', key, error); + } + } + + // Reconcile removals only when remote has at least one entry to avoid wiping local + // data if backend temporarily returns an empty set. + if (remoteSet.size > 0) { + let removedCount = 0; + for (const item of localItems) { + const key = `${item.type}:${item.id}`; + if (remoteSet.has(key)) continue; + try { + await catalogService.removeFromLibrary(item.type, item.id); + removedCount += 1; + } catch (error) { + logger.warn('[SupabaseSyncService] Failed to remove local library item missing in remote set:', key, error); + } + } + logger.log(`[SupabaseSyncService] pullLibraryToLocal: removedLocalExtras=${removedCount}`); + } else { + logger.log('[SupabaseSyncService] pullLibraryToLocal: remote set empty, skipped local prune'); + } + } + + private async pushLibraryFromLocal(): Promise { + const items = await catalogService.getLibraryItems(); + const payload: LibraryRow[] = items.map((item) => ({ + content_id: item.id, + content_type: item.type === 'movie' ? 'movie' : 'series', + name: item.name, + poster: item.poster, + poster_shape: (item.posterShape || 'poster').toUpperCase(), + background: item.banner || (item as any).background, + description: item.description, + release_info: item.releaseInfo, + imdb_rating: item.imdbRating != null ? Number(item.imdbRating) : undefined, + genres: item.genres || [], + addon_base_url: item.addonId, + added_at: item.addedToLibraryAt, + })); + + await this.callRpc('sync_push_library', { p_items: payload }); + } + + private async pullWatchedItemsToLocal(): Promise { + const rows = await this.callRpc('sync_pull_watched_items', {}); + const mapped = (rows || []).map((row) => this.toWatchedItem(row)); + await watchedService.reconcileRemoteWatchedItems(mapped); + } + + private async pushWatchedItemsFromLocal(): Promise { + const items = await watchedService.getAllWatchedItems(); + const payload: WatchedRow[] = items.map((item) => ({ + content_id: item.content_id, + content_type: item.content_type, + title: item.title, + season: item.season, + episode: item.episode, + watched_at: item.watched_at, + })); + await this.callRpc('sync_push_watched_items', { p_items: payload }); + } +} + +export const supabaseSyncService = SupabaseSyncService.getInstance(); +export default supabaseSyncService; diff --git a/src/services/watchedService.ts b/src/services/watchedService.ts index 50218aeb..5b609ff2 100644 --- a/src/services/watchedService.ts +++ b/src/services/watchedService.ts @@ -4,10 +4,19 @@ import { storageService } from './storageService'; import { mmkvStorage } from './mmkvStorage'; import { logger } from '../utils/logger'; +export interface LocalWatchedItem { + content_id: string; + content_type: 'movie' | 'series'; + title: string; + season: number | null; + episode: number | null; + watched_at: number; +} + /** * WatchedService - Manages "watched" status for movies, episodes, and seasons. * Handles both local storage and Trakt sync transparently. - * + * * When Trakt is authenticated, it syncs to Trakt. * When not authenticated, it stores locally. */ @@ -15,6 +24,8 @@ class WatchedService { private static instance: WatchedService; private traktService: TraktService; private simklService: SimklService; + private readonly WATCHED_ITEMS_KEY = '@user:local:watched_items'; + private watchedSubscribers: Array<() => void> = []; private constructor() { this.traktService = TraktService.getInstance(); @@ -28,6 +39,158 @@ class WatchedService { return WatchedService.instance; } + private watchedKey(item: Pick): string { + return `${item.content_id}::${item.season ?? -1}::${item.episode ?? -1}`; + } + + private normalizeWatchedItem(item: LocalWatchedItem): LocalWatchedItem { + return { + content_id: String(item.content_id || ''), + content_type: item.content_type === 'movie' ? 'movie' : 'series', + title: item.title || '', + season: item.season == null ? null : Number(item.season), + episode: item.episode == null ? null : Number(item.episode), + watched_at: Number(item.watched_at || Date.now()), + }; + } + + private notifyWatchedSubscribers(): void { + if (this.watchedSubscribers.length === 0) return; + this.watchedSubscribers.forEach((cb) => cb()); + } + + public subscribeToWatchedUpdates(callback: () => void): () => void { + this.watchedSubscribers.push(callback); + return () => { + const index = this.watchedSubscribers.indexOf(callback); + if (index > -1) { + this.watchedSubscribers.splice(index, 1); + } + }; + } + + private async loadWatchedItems(): Promise { + try { + const json = await mmkvStorage.getItem(this.WATCHED_ITEMS_KEY); + if (!json) return []; + const parsed = JSON.parse(json); + if (!Array.isArray(parsed)) return []; + + const deduped = new Map(); + parsed.forEach((raw) => { + if (!raw || typeof raw !== 'object') return; + const normalized = this.normalizeWatchedItem(raw as LocalWatchedItem); + if (!normalized.content_id) return; + const key = this.watchedKey(normalized); + const existing = deduped.get(key); + if (!existing || normalized.watched_at > existing.watched_at) { + deduped.set(key, normalized); + } + }); + + return Array.from(deduped.values()); + } catch (error) { + logger.error('[WatchedService] Failed to load local watched items:', error); + return []; + } + } + + private async saveWatchedItems(items: LocalWatchedItem[]): Promise { + try { + await mmkvStorage.setItem(this.WATCHED_ITEMS_KEY, JSON.stringify(items)); + } catch (error) { + logger.error('[WatchedService] Failed to save local watched items:', error); + } + } + + public async getAllWatchedItems(): Promise { + return await this.loadWatchedItems(); + } + + private async upsertLocalWatchedItems(items: LocalWatchedItem[]): Promise { + if (items.length === 0) return; + + const current = await this.loadWatchedItems(); + const byKey = new Map( + current.map((item) => [this.watchedKey(item), item]) + ); + + let changed = false; + for (const raw of items) { + const normalized = this.normalizeWatchedItem(raw); + if (!normalized.content_id) continue; + + const key = this.watchedKey(normalized); + const existing = byKey.get(key); + if (!existing || normalized.watched_at > existing.watched_at || (normalized.title && normalized.title !== existing.title)) { + byKey.set(key, normalized); + changed = true; + } + } + + if (changed) { + await this.saveWatchedItems(Array.from(byKey.values())); + this.notifyWatchedSubscribers(); + } + } + + private async removeLocalWatchedItems(items: Array>): Promise { + if (items.length === 0) return; + + const current = await this.loadWatchedItems(); + const toRemove = new Set(items.map((item) => this.watchedKey({ content_id: item.content_id, season: item.season ?? null, episode: item.episode ?? null }))); + const filtered = current.filter((item) => !toRemove.has(this.watchedKey(item))); + + if (filtered.length !== current.length) { + await this.saveWatchedItems(filtered); + this.notifyWatchedSubscribers(); + } + } + + public async mergeRemoteWatchedItems(items: LocalWatchedItem[]): Promise { + const normalized = items + .map((item) => this.normalizeWatchedItem(item)) + .filter((item) => Boolean(item.content_id)); + + await this.upsertLocalWatchedItems(normalized); + + for (const item of normalized) { + if (item.content_type === 'movie') { + await this.setLocalWatchedStatus(item.content_id, 'movie', true, undefined, new Date(item.watched_at)); + continue; + } + + if (item.season == null || item.episode == null) continue; + const episodeId = `${item.content_id}:${item.season}:${item.episode}`; + await this.setLocalWatchedStatus(item.content_id, 'series', true, episodeId, new Date(item.watched_at)); + } + } + + public async reconcileRemoteWatchedItems(items: LocalWatchedItem[]): Promise { + const normalizedRemote = items + .map((item) => this.normalizeWatchedItem(item)) + .filter((item) => Boolean(item.content_id)); + + // Guard: do not wipe local watched data if backend temporarily returns empty. + if (normalizedRemote.length === 0) { + return; + } + + await this.saveWatchedItems(normalizedRemote); + this.notifyWatchedSubscribers(); + + for (const item of normalizedRemote) { + if (item.content_type === 'movie') { + await this.setLocalWatchedStatus(item.content_id, 'movie', true, undefined, new Date(item.watched_at)); + continue; + } + + if (item.season == null || item.episode == null) continue; + const episodeId = `${item.content_id}:${item.season}:${item.episode}`; + await this.setLocalWatchedStatus(item.content_id, 'series', true, episodeId, new Date(item.watched_at)); + } + } + /** * Mark a movie as watched * @param imdbId - The IMDb ID of the movie @@ -59,6 +222,16 @@ class WatchedService { // Also store locally as "completed" (100% progress) await this.setLocalWatchedStatus(imdbId, 'movie', true, undefined, watchedAt); + await this.upsertLocalWatchedItems([ + { + content_id: imdbId, + content_type: 'movie', + title: imdbId, + season: null, + episode: null, + watched_at: watchedAt.getTime(), + }, + ]); return { success: true, syncedToTrakt }; } catch (error) { @@ -119,6 +292,16 @@ class WatchedService { // Store locally as "completed" const episodeId = `${showId}:${season}:${episode}`; await this.setLocalWatchedStatus(showId, 'series', true, episodeId, watchedAt); + await this.upsertLocalWatchedItems([ + { + content_id: showImdbId, + content_type: 'series', + title: showImdbId, + season, + episode, + watched_at: watchedAt.getTime(), + }, + ]); return { success: true, syncedToTrakt }; } catch (error) { @@ -188,6 +371,17 @@ class WatchedService { await this.setLocalWatchedStatus(showId, 'series', true, episodeId, watchedAt); } + await this.upsertLocalWatchedItems( + episodes.map((ep) => ({ + content_id: showImdbId, + content_type: 'series' as const, + title: showImdbId, + season: ep.season, + episode: ep.episode, + watched_at: watchedAt.getTime(), + })) + ); + return { success: true, syncedToTrakt, count: episodes.length }; } catch (error) { logger.error('[WatchedService] Failed to mark episodes as watched:', error); @@ -231,7 +425,6 @@ class WatchedService { const isSimklAuth = await this.simklService.isAuthenticated(); if (isSimklAuth) { // Simkl doesn't have a direct "mark season" generic endpoint in the same way, but we can construct it - // We know the episodeNumbers from the arguments! const episodes = episodeNumbers.map(num => ({ number: num, watched_at: watchedAt.toISOString() })); await this.simklService.addToHistory({ shows: [{ @@ -251,6 +444,17 @@ class WatchedService { await this.setLocalWatchedStatus(showId, 'series', true, episodeId, watchedAt); } + await this.upsertLocalWatchedItems( + episodeNumbers.map((episode) => ({ + content_id: showImdbId, + content_type: 'series' as const, + title: showImdbId, + season, + episode, + watched_at: watchedAt.getTime(), + })) + ); + return { success: true, syncedToTrakt, count: episodeNumbers.length }; } catch (error) { logger.error('[WatchedService] Failed to mark season as watched:', error); @@ -285,6 +489,9 @@ class WatchedService { // Remove local progress await storageService.removeWatchProgress(imdbId, 'movie'); await mmkvStorage.removeItem(`watched:movie:${imdbId}`); + await this.removeLocalWatchedItems([ + { content_id: imdbId, season: null, episode: null }, + ]); return { success: true, syncedToTrakt }; } catch (error) { @@ -335,6 +542,9 @@ class WatchedService { // Remove local progress const episodeId = `${showId}:${season}:${episode}`; await storageService.removeWatchProgress(showId, 'series', episodeId); + await this.removeLocalWatchedItems([ + { content_id: showImdbId, season, episode }, + ]); return { success: true, syncedToTrakt }; } catch (error) { @@ -368,10 +578,6 @@ class WatchedService { showImdbId, season ); - syncedToTrakt = await this.traktService.removeSeasonFromHistory( - showImdbId, - season - ); logger.log(`[WatchedService] Trakt season removal result: ${syncedToTrakt}`); } @@ -397,6 +603,14 @@ class WatchedService { await storageService.removeWatchProgress(showId, 'series', episodeId); } + await this.removeLocalWatchedItems( + episodeNumbers.map((episode) => ({ + content_id: showImdbId, + season, + episode, + })) + ); + return { success: true, syncedToTrakt, count: episodeNumbers.length }; } catch (error) { logger.error('[WatchedService] Failed to unmark season as watched:', error); diff --git a/src/utils/version.ts b/src/utils/version.ts index 06f1acea..ce2f67b5 100644 --- a/src/utils/version.ts +++ b/src/utils/version.ts @@ -1,7 +1,7 @@ // Single source of truth for the app version displayed in Settings // Update this when bumping app version -export const APP_VERSION = '1.3.7'; +export const APP_VERSION = '1.4.0'; export function getDisplayedAppVersion(): string { return APP_VERSION;