diff --git a/docs/configure/ffmpeg/transcode_config.md b/docs/configure/ffmpeg/transcode_config.md index de33d47a1..dde14cd42 100644 --- a/docs/configure/ffmpeg/transcode_config.md +++ b/docs/configure/ffmpeg/transcode_config.md @@ -127,6 +127,8 @@ Controls the codec used to encode the output audio stream. - **AAC** — The default and most compatible format. Widely supported by all clients and streaming devices. Recommended for most setups. - **AC3 (Dolby Digital)** — Good choice for surround sound (5.1) content. Supported by most TVs and AV receivers, but not all streaming clients. +- **E-AC3 (Dolby Digital Plus)** — Supports higher bitrates and more channels than AC3 but is less supported. Use if you want to stream 7.1 (8 channel) surround sound and have compatible clients/hardware. +- **Opus (experimental)** — Highly efficient compression with inexpensive transcode perfomance and better multi-channel support than AAC or MP3. Would be ideal for surround sound content except that it isn't officially part of the the HLS spec as it is unsupported by most A/V hardware. Offered as an experimental option as it may still function due to nearly-universal software support. - **MP3** — Widely compatible but lower quality than AAC at equivalent bitrates. Only use if a specific client requires it. - **Copy** — Passes the audio stream through unchanged without re-encoding. When Copy is selected, all other audio settings (bitrate, sample rate, volume, channels) are **ignored**, since the stream is not being processed by FFmpeg. diff --git a/macos/FfmpegCapabilities/FfmpegCapabilities.xcodeproj/project.pbxproj b/macos/FfmpegCapabilities/FfmpegCapabilities.xcodeproj/project.pbxproj new file mode 100644 index 000000000..cca15dd74 --- /dev/null +++ b/macos/FfmpegCapabilities/FfmpegCapabilities.xcodeproj/project.pbxproj @@ -0,0 +1,298 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXCopyFilesBuildPhase section */ + 14F96BF72E3E85CE00B5BB70 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 14F96BF92E3E85CE00B5BB70 /* FfmpegCapabilities */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = FfmpegCapabilities; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 14F96BFB2E3E85CE00B5BB70 /* FfmpegCapabilities */ = { + isa = PBXFileSystemSynchronizedRootGroup; + path = FfmpegCapabilities; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 14F96BF62E3E85CE00B5BB70 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 14F96BF02E3E85CE00B5BB70 = { + isa = PBXGroup; + children = ( + 14F96BFB2E3E85CE00B5BB70 /* FfmpegCapabilities */, + 14F96BFA2E3E85CE00B5BB70 /* Products */, + ); + sourceTree = ""; + }; + 14F96BFA2E3E85CE00B5BB70 /* Products */ = { + isa = PBXGroup; + children = ( + 14F96BF92E3E85CE00B5BB70 /* FfmpegCapabilities */, + ); + name = Products; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 14F96BF82E3E85CE00B5BB70 /* FfmpegCapabilities */ = { + isa = PBXNativeTarget; + buildConfigurationList = 14F96C002E3E85CE00B5BB70 /* Build configuration list for PBXNativeTarget "FfmpegCapabilities" */; + buildPhases = ( + 14F96BF52E3E85CE00B5BB70 /* Sources */, + 14F96BF62E3E85CE00B5BB70 /* Frameworks */, + 14F96BF72E3E85CE00B5BB70 /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 14F96BFB2E3E85CE00B5BB70 /* FfmpegCapabilities */, + ); + name = FfmpegCapabilities; + packageProductDependencies = ( + ); + productName = FfmpegCapabilities; + productReference = 14F96BF92E3E85CE00B5BB70 /* FfmpegCapabilities */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 14F96BF12E3E85CE00B5BB70 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1640; + LastUpgradeCheck = 1640; + TargetAttributes = { + 14F96BF82E3E85CE00B5BB70 = { + CreatedOnToolsVersion = 16.4; + }; + }; + }; + buildConfigurationList = 14F96BF42E3E85CE00B5BB70 /* Build configuration list for PBXProject "FfmpegCapabilities" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 14F96BF02E3E85CE00B5BB70; + minimizedProjectReferenceProxies = 1; + preferredProjectObjectVersion = 77; + productRefGroup = 14F96BFA2E3E85CE00B5BB70 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 14F96BF82E3E85CE00B5BB70 /* FfmpegCapabilities */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 14F96BF52E3E85CE00B5BB70 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 14F96BFE2E3E85CE00B5BB70 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = XX35C4MZN8; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 15.5; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 14F96BFF2E3E85CE00B5BB70 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = XX35C4MZN8; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 15.5; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + }; + name = Release; + }; + 14F96C012E3E85CE00B5BB70 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = XX35C4MZN8; + ENABLE_HARDENED_RUNTIME = YES; + MACOSX_DEPLOYMENT_TARGET = 13.5; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 14F96C022E3E85CE00B5BB70 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = XX35C4MZN8; + ENABLE_HARDENED_RUNTIME = YES; + MACOSX_DEPLOYMENT_TARGET = 13.5; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 14F96BF42E3E85CE00B5BB70 /* Build configuration list for PBXProject "FfmpegCapabilities" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 14F96BFE2E3E85CE00B5BB70 /* Debug */, + 14F96BFF2E3E85CE00B5BB70 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 14F96C002E3E85CE00B5BB70 /* Build configuration list for PBXNativeTarget "FfmpegCapabilities" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 14F96C012E3E85CE00B5BB70 /* Debug */, + 14F96C022E3E85CE00B5BB70 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 14F96BF12E3E85CE00B5BB70 /* Project object */; +} diff --git a/macos/FfmpegCapabilities/FfmpegCapabilities.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/macos/FfmpegCapabilities/FfmpegCapabilities.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..919434a62 --- /dev/null +++ b/macos/FfmpegCapabilities/FfmpegCapabilities.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/macos/FfmpegCapabilities/FfmpegCapabilities.xcodeproj/project.xcworkspace/xcuserdata/christianbenincasa.xcuserdatad/UserInterfaceState.xcuserstate b/macos/FfmpegCapabilities/FfmpegCapabilities.xcodeproj/project.xcworkspace/xcuserdata/christianbenincasa.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 000000000..b8acd7409 Binary files /dev/null and b/macos/FfmpegCapabilities/FfmpegCapabilities.xcodeproj/project.xcworkspace/xcuserdata/christianbenincasa.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/macos/FfmpegCapabilities/FfmpegCapabilities.xcodeproj/xcuserdata/christianbenincasa.xcuserdatad/xcschemes/xcschememanagement.plist b/macos/FfmpegCapabilities/FfmpegCapabilities.xcodeproj/xcuserdata/christianbenincasa.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 000000000..9e54c67cd --- /dev/null +++ b/macos/FfmpegCapabilities/FfmpegCapabilities.xcodeproj/xcuserdata/christianbenincasa.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + FfmpegCapabilities.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/macos/FfmpegCapabilities/FfmpegCapabilities/main.swift b/macos/FfmpegCapabilities/FfmpegCapabilities/main.swift new file mode 100644 index 000000000..e09dc0b4c --- /dev/null +++ b/macos/FfmpegCapabilities/FfmpegCapabilities/main.swift @@ -0,0 +1,134 @@ +// +// main.swift +// FfmpegCapabilities +// +// Created by Christian Benincasa on 8/2/25. +// + +import CoreFoundation +import Foundation +import VideoToolbox + +extension FourCharCode { + var string: String? { + let cString: [CChar] = [ + CChar((self >> 24) & 0xFF), + CChar((self >> 16) & 0xFF), + CChar((self >> 8) & 0xFF), + CChar(self & 0xFF), + 0, + ] + + return String(cString: cString) + } +} + +func main() -> Int32 { + var encoders: CFArray? + let status = VTCopyVideoEncoderList(nil, &encoders) + + if status != noErr { + print("Failed to get encoder list: \(status)") + return 1 + } + + guard let encoderList = encoders as? [[String: Any]] else { + print("Encoder list is not in the expected format.") + return 1 + } + + var jsonEncoders: [[String: Any]] = [] + + for encoder in encoderList { + var jsonEncoder: [String: Any] = [:] + + let isHwAccel = + encoder[kVTVideoEncoderList_IsHardwareAccelerated as String] as? Bool ?? false + if !isHwAccel { + continue + } + + jsonEncoder["isHardwareAccelerated"] = true + + if let displayName = encoder[kVTVideoEncoderList_DisplayName as String] + as? String + { + jsonEncoder["displayName"] = displayName + } + + if let encoderName = encoder[kVTVideoEncoderList_EncoderName as String] + as? String + { + jsonEncoder["encoderName"] = encoderName + } + + if let encoderID = encoder[kVTVideoEncoderList_EncoderID as String] + as? String + { + jsonEncoder["encoderID"] = encoderID + } + + if let codecType = encoder[kVTVideoEncoderList_CodecType as String] + as? CMVideoCodecType + { + jsonEncoder["codecType"] = (codecType as FourCharCode).string! + } + + if let codecName = encoder[kVTVideoEncoderList_CodecName as String] + as? String + { + jsonEncoder["codecName"] = codecName + } + + if let supportedProps = encoder[kVTVideoEncoderList_SupportedSelectionProperties as String] + { + jsonEncoder["supportedProps"] = supportedProps + } + + jsonEncoders.append(jsonEncoder) + } + + let decoderSupport = [ + kCMVideoCodecType_H264, + kCMVideoCodecType_HEVC, + kCMVideoCodecType_AV1, + kCMVideoCodecType_MPEG2Video, + kCMVideoCodecType_MPEG4Video, + kCMVideoCodecType_VP9, + ] + .reduce( + into: [ + String: Bool + ]() + ) { + $0[$1.string!] = VTIsHardwareDecodeSupported($1) + } + + let jsonOutput: [String: Any] = [ + "encoders": jsonEncoders, + "decoders": decoderSupport, + ] + + // 4. Serialize the Swift dictionary into a JSON Data object. + do { + let jsonData = try JSONSerialization.data( + withJSONObject: jsonOutput, + options: [.prettyPrinted] + ) + + // 5. Convert the JSON Data to a String. + if let jsonString = String(data: jsonData, encoding: .utf8) { + print(jsonString) + } else { + print("Failed to convert JSON data to a string.") + return 1 + } + } catch { + print("Failed to serialize encoder list to JSON: \(error)") + return 1 + } + + return 0 +} + +exit(main()) diff --git a/server/src/Server.ts b/server/src/Server.ts index 089714a74..a687cabee 100644 --- a/server/src/Server.ts +++ b/server/src/Server.ts @@ -40,12 +40,13 @@ import { HdhrApiRouter } from './api/hdhrApi.js'; import { apiRouter } from './api/index.js'; import { streamApi } from './api/streamApi.js'; import { videoApiRouter } from './api/videoApi.js'; +import { createTunarrBasicAuthHook } from './util/basicAuth.js'; import { defaultHlsOptions } from './ffmpeg/builder/constants.ts'; import { type ServerOptions, serverOptions } from './globals.js'; import { IWorkerPool } from './interfaces/IWorkerPool.ts'; import { ServerContext, ServerRequestContext } from './ServerContext.js'; import { Result } from './types/result.ts'; -import { getBooleanEnvVar, TUNARR_ENV_VARS } from './util/env.ts'; +import { getBooleanEnvVar, getEnvVar, TUNARR_ENV_VARS } from './util/env.ts'; import { filename, isDev, run, timeoutPromise } from './util/index.js'; import { InjectLogger } from './util/inject.js'; import { type Logger } from './util/logging/LoggerFactory.js'; @@ -87,6 +88,21 @@ export class Server { .setSerializerCompiler(serializerCompiler) .withTypeProvider(); + const basicAuthUser = getEnvVar(TUNARR_ENV_VARS.BASIC_AUTH_USER_ENV_VAR); + const basicAuthPassword = getEnvVar( + TUNARR_ENV_VARS.BASIC_AUTH_PASSWORD_ENV_VAR, + ); + + if (basicAuthUser && basicAuthPassword) { + this.app.addHook( + 'onRequest', + createTunarrBasicAuthHook({ + username: basicAuthUser, + password: basicAuthPassword, + }), + ); + } + if (serverOptions().printRoutes) { await this.app.register( fp((f, opts, done) => @@ -287,6 +303,7 @@ export class Server { if (!route.config) { route.config = {}; } + route.config.authRequired = false; route.config.swaggerTransform = ({ schema, url }) => { const transformedSchema: FastifySchema = isUndefined(schema) ? {} @@ -341,6 +358,9 @@ export class Server { hide: true, params: z.object({ hash: z.string() }), }, + config: { + authRequired: false, + }, // Workaround for https://github.com/fastify/fastify/issues/4859 // eslint-disable-next-line @typescript-eslint/no-misused-promises onRequest: (req, res) => { diff --git a/server/src/api/creditsApi.ts b/server/src/api/creditsApi.ts index 811c5169c..68901624d 100644 --- a/server/src/api/creditsApi.ts +++ b/server/src/api/creditsApi.ts @@ -113,6 +113,9 @@ export class CreditsApiController { 404: z.void(), }, }, + config: { + authRequired: false, + }, }, async (req, res) => { const result = await this.artworkService.resolveArtwork( diff --git a/server/src/api/debug/debugJellyfinApi.ts b/server/src/api/debug/debugJellyfinApi.ts index f983a7429..2f43e5156 100644 --- a/server/src/api/debug/debugJellyfinApi.ts +++ b/server/src/api/debug/debugJellyfinApi.ts @@ -43,6 +43,7 @@ export const DebugJellyfinApiRouter: RouterPluginAsyncCallback = async ( mediaType: null, paths: [], replacePaths: [], + sendPlayStatusUpdates: false, }, }); @@ -84,6 +85,7 @@ export const DebugJellyfinApiRouter: RouterPluginAsyncCallback = async ( mediaType: null, paths: [], replacePaths: [], + sendPlayStatusUpdates: false, }, }); diff --git a/server/src/api/debug/debugPlexApi.ts b/server/src/api/debug/debugPlexApi.ts index 3503ced64..0bd69dd0a 100644 --- a/server/src/api/debug/debugPlexApi.ts +++ b/server/src/api/debug/debugPlexApi.ts @@ -1,6 +1,37 @@ import type { RouterPluginAsyncCallback } from '@/types/serverType.js'; +import { tag } from '@tunarr/types'; +import { z } from 'zod'; export const DebugPlexApiRouter: RouterPluginAsyncCallback = async ( - _fastify, + fastify, // eslint-disable-next-line @typescript-eslint/require-await -) => {}; +) => { + fastify.get( + '/plex/:mediaSourceId/:plexItemId', + { + schema: { + params: z.object({ + mediaSourceId: z.uuid(), + plexItemId: z.string(), + }), + }, + }, + async (req, res) => { + const mediaSource = await req.serverCtx.mediaSourceDB.getById( + tag(req.params.mediaSourceId), + ); + if (!mediaSource) { + return res.status(404).send('No media source found'); + } + + const client = + await req.serverCtx.mediaSourceApiFactory.getPlexApiClientForMediaSource( + mediaSource, + ); + + const result = await client.getItemMetadata(req.params.plexItemId); + + return res.send(result); + }, + ); +}; diff --git a/server/src/api/hdhrApi.ts b/server/src/api/hdhrApi.ts index a99597656..73a48430a 100644 --- a/server/src/api/hdhrApi.ts +++ b/server/src/api/hdhrApi.ts @@ -28,6 +28,7 @@ export class HdhrApiRouter { routeOpts.config = {}; } routeOpts.config.disableRequestLogging = true; + routeOpts.config.authRequired = false; if (!routeOpts.schema) { routeOpts.schema = {}; } diff --git a/server/src/api/index.ts b/server/src/api/index.ts index b8ea35772..3c4147742 100644 --- a/server/src/api/index.ts +++ b/server/src/api/index.ts @@ -236,6 +236,9 @@ export const apiRouter: RouterPluginAsyncCallback = async (fastify) => { schema: { tags: ['Streaming'], }, + config: { + authRequired: false, + }, handler: async (req, res) => { try { const host = `${req.protocol}://${req.host}`; @@ -273,6 +276,9 @@ export const apiRouter: RouterPluginAsyncCallback = async (fastify) => { }), tags: ['Streaming'], }, + config: { + authRequired: false, + }, method: ['HEAD', 'GET'], handler: async (req, res) => { try { diff --git a/server/src/api/mediaSourceApi.ts b/server/src/api/mediaSourceApi.ts index e55487686..a064657be 100644 --- a/server/src/api/mediaSourceApi.ts +++ b/server/src/api/mediaSourceApi.ts @@ -646,6 +646,7 @@ export const mediaSourceRouter: RouterPluginAsyncCallback = async ( paths: [], mediaType: null, replacePaths: [], + sendPlayStatusUpdates: false, }, }); @@ -666,6 +667,7 @@ export const mediaSourceRouter: RouterPluginAsyncCallback = async ( paths: [], mediaType: null, replacePaths: [], + sendPlayStatusUpdates: false, }, }); @@ -686,6 +688,7 @@ export const mediaSourceRouter: RouterPluginAsyncCallback = async ( paths: [], mediaType: null, replacePaths: [], + sendPlayStatusUpdates: false, }, }); @@ -936,6 +939,7 @@ export const mediaSourceRouter: RouterPluginAsyncCallback = async ( localPath: replace.localPath, serverPath: replace.serverPath, })), + sendPlayStatusUpdates: source.sendPlayStatusUpdates ?? false, }) satisfies StrictExtract< MediaSourceSettings, { type: 'plex' | 'jellyfin' | 'emby' } diff --git a/server/src/api/programmingApi.ts b/server/src/api/programmingApi.ts index 524338fa5..b7287eb1b 100644 --- a/server/src/api/programmingApi.ts +++ b/server/src/api/programmingApi.ts @@ -413,6 +413,9 @@ export const programmingApi: RouterPluginAsyncCallback = async (fastify) => { 404: z.void(), }, }, + config: { + authRequired: false, + }, }, async (req, res) => { let program: Maybe<{ diff --git a/server/src/api/streamApi.ts b/server/src/api/streamApi.ts index 5306904d9..3773feda3 100644 --- a/server/src/api/streamApi.ts +++ b/server/src/api/streamApi.ts @@ -42,6 +42,13 @@ export const streamApi: RouterPluginAsyncCallback = async (fastify) => { className: 'StreamApi', }); + fastify.addHook('onRoute', (routeOpts) => { + if (!routeOpts.config) { + routeOpts.config = {}; + } + routeOpts.config.authRequired = false; + }); + fastify.addHook('onError', (req, _, error, done) => { logger.error( error, diff --git a/server/src/api/videoApi.ts b/server/src/api/videoApi.ts index 2b535e6ce..063c09357 100644 --- a/server/src/api/videoApi.ts +++ b/server/src/api/videoApi.ts @@ -29,6 +29,13 @@ export const videoApiRouter: RouterPluginAsyncCallback = async (fastify) => { className: 'VideoApi', }); + fastify.addHook('onRoute', (routeOpts) => { + if (!routeOpts.config) { + routeOpts.config = {}; + } + routeOpts.config.authRequired = false; + }); + fastify.get( '/setup', { diff --git a/server/src/db/CustomShowDB.test.ts b/server/src/db/CustomShowDB.test.ts index a60ee5053..f351b0aea 100644 --- a/server/src/db/CustomShowDB.test.ts +++ b/server/src/db/CustomShowDB.test.ts @@ -3,14 +3,14 @@ import type { ContentProgram } from '@tunarr/types'; import { tag } from '@tunarr/types'; import dayjs from 'dayjs'; import tmp from 'tmp-promise'; -import { copyPreMigratedDb } from '../testing/testDbFactory.ts'; import { v4 } from 'uuid'; import { test as baseTest, describe, expect, vi } from 'vitest'; import { bootstrapTunarr } from '../bootstrap.ts'; import { setGlobalOptionsUnchecked } from '../globals.ts'; +import { copyPreMigratedDb } from '../testing/testDbFactory.ts'; import { CustomShowDB } from './CustomShowDB.ts'; -import { BasicProgramRepository } from './program/BasicProgramRepository.ts'; import { DBAccess } from './DBAccess.ts'; +import { BasicProgramRepository } from './program/BasicProgramRepository.ts'; import type { MediaSourceId, MediaSourceName } from './schema/base.ts'; import { CustomShow } from './schema/CustomShow.ts'; import type { NewCustomShowContent } from './schema/CustomShowContent.ts'; diff --git a/server/src/db/converters/ProgramMinter.ts b/server/src/db/converters/ProgramMinter.ts index 9b942963d..ec25d4299 100644 --- a/server/src/db/converters/ProgramMinter.ts +++ b/server/src/db/converters/ProgramMinter.ts @@ -545,6 +545,8 @@ export class ProgramDaoMinter { updatedAt: now, canonicalId: video.canonicalId, state: 'ok', + artistName: video.artistName ?? null, + albumName: video.albumName ?? null, } satisfies NewMusicVideoProgram; return { diff --git a/server/src/db/mediaSourceDB.ts b/server/src/db/mediaSourceDB.ts index ebbe04076..7d68a3a78 100644 --- a/server/src/db/mediaSourceDB.ts +++ b/server/src/db/mediaSourceDB.ts @@ -260,6 +260,10 @@ export class MediaSourceDB { uri: trimEnd(updateReq.uri, '/'), accessToken: updateReq.accessToken, sendGuideUpdates: booleanToNumber(sendGuideUpdates), + sendPlayStatusUpdates: + updateReq.type === 'plex' || updateReq.type === 'jellyfin' + ? booleanToNumber(updateReq.sendPlayStatusUpdates ?? false) + : 0, updatedAt: +dayjs(), // This allows clearing the values userId: updateReq.userId, diff --git a/server/src/db/program/BasicProgramRepository.ts b/server/src/db/program/BasicProgramRepository.ts index 2a6234d0e..612fe482a 100644 --- a/server/src/db/program/BasicProgramRepository.ts +++ b/server/src/db/program/BasicProgramRepository.ts @@ -106,10 +106,30 @@ export class BasicProgramRepository { with: { externalIds: true, artwork: true, + tags: { + with: { + tag: true, + }, + }, + genres: { + with: { + genre: true, + }, + }, }, }, externalIds: true, artwork: true, + credits: { + with: { + artwork: true, + }, + }, + genres: { + with: { + genre: true, + }, + }, tags: { with: { tag: true, diff --git a/server/src/db/schema/MediaSource.ts b/server/src/db/schema/MediaSource.ts index 271176e51..733b77ca3 100644 --- a/server/src/db/schema/MediaSource.ts +++ b/server/src/db/schema/MediaSource.ts @@ -31,7 +31,7 @@ export const MediaSource = sqliteTable( name: text().notNull().$type(), sendChannelUpdates: integer({ mode: 'boolean' }).default(false), sendGuideUpdates: integer({ mode: 'boolean' }).default(false), - // sendPlayStatusUpdates: integer({ mode: 'boolean' }).default(false), + sendPlayStatusUpdates: integer({ mode: 'boolean' }).default(false), type: text({ enum: MediaSourceTypes }).notNull(), uri: text().notNull(), username: text(), diff --git a/server/src/db/schema/TranscodeConfig.ts b/server/src/db/schema/TranscodeConfig.ts index 03c27b701..dfe596bd8 100644 --- a/server/src/db/schema/TranscodeConfig.ts +++ b/server/src/db/schema/TranscodeConfig.ts @@ -72,6 +72,8 @@ export const TranscodeAudioOutputFormats = [ 'ac3', 'copy', 'mp3', + 'libopus', + 'eac3', ] as const; export type TranscodeAudioOutputFormat = TupleToUnion< @@ -83,6 +85,8 @@ export const TranscodeAudioOutputFormat = { Ac3: 'ac3' as const, Copy: 'copy' as const, Mp3: 'mp3' as const, + Opus: 'libopus' as const, + Eac3: 'eac3' as const, } as const; export const ErrorScreenTypes = [ diff --git a/server/src/external/emby/EmbyApiClient.ts b/server/src/external/emby/EmbyApiClient.ts index b6735795d..1336d3acc 100644 --- a/server/src/external/emby/EmbyApiClient.ts +++ b/server/src/external/emby/EmbyApiClient.ts @@ -1784,6 +1784,8 @@ export class EmbyApiClient extends MediaSourceApiClient { video.TagItems?.map((item) => item.Name).filter(isNonEmptyString) ?? [], ), // summary: null, + artistName: video.Artists?.join(', ') ?? video.AlbumArtist ?? null, + albumName: video.Album ?? null, type: 'music_video', mediaItem, identifiers: collectEmbyItemIdentifiers( diff --git a/server/src/external/jellyfin/JellyfinApiClient.ts b/server/src/external/jellyfin/JellyfinApiClient.ts index 847c12314..d0db1314f 100644 --- a/server/src/external/jellyfin/JellyfinApiClient.ts +++ b/server/src/external/jellyfin/JellyfinApiClient.ts @@ -1744,6 +1744,8 @@ export class JellyfinApiClient extends MediaSourceApiClient { // tagline: find(video.Taglines, isNonEmptyString) ?? null, tags: video.Tags?.filter(isNonEmptyString) ?? [], // summary: null, + artistName: video.Artists?.join(', ') ?? video.AlbumArtist ?? null, + albumName: video.Album ?? null, type: 'music_video', mediaItem, identifiers: collectJellyfinItemIdentifiers( diff --git a/server/src/external/plex/PlexApiClient.ts b/server/src/external/plex/PlexApiClient.ts index e981d7b92..9795807be 100644 --- a/server/src/external/plex/PlexApiClient.ts +++ b/server/src/external/plex/PlexApiClient.ts @@ -734,10 +734,48 @@ export class PlexApiClient extends MediaSourceApiClient { ); } - async getItemMetadata(key: string): Promise> { + async getItemMetadataRaw(key: string): Promise> { return this.getItemMetadataInternal(key, PlexMediaContainerResponseSchema); } + async getItemMetadata(key: string): Promise> { + const rawResponse = await this.getItemMetadataRaw(key); + return rawResponse.flatMap((media) => { + return this.findLibraryFromPlexMedia(media).flatMap((library) => + match(media) + .returnType>() + .with({ type: 'movie' }, (movie) => + this.plexMovieInjection(movie, library), + ) + .with({ type: 'episode' }, (ep) => + this.plexEpisodeInjection(ep, library), + ) + .with({ type: 'show' }, (show) => + this.plexShowInjection(show, library), + ) + .with({ type: 'season' }, (season) => + this.plexSeasonInjection(season, library), + ) + .with({ type: 'album' }, (album) => + this.plexAlbumInjection(album, library), + ) + .with({ type: 'artist' }, (artist) => + this.plexMusicArtistInjection(artist, library), + ) + .with({ type: 'track' }, (track) => + this.plexTrackInjection(track, library), + ) + .with({ type: 'collection' }, () => { + throw new Error('Collections are not supported in this call'); + }) + .with({ type: 'playlist' }, () => { + throw new Error('Playlists are not supported in this call'); + }) + .exhaustive(), + ); + }); + } + async getMovie(key: string): Promise> { return this.getMediaOfType( key, diff --git a/server/src/ffmpeg/StreamSelectionEvaluator.ts b/server/src/ffmpeg/StreamSelectionEvaluator.ts index 1135498c6..a6ffa30f7 100644 --- a/server/src/ffmpeg/StreamSelectionEvaluator.ts +++ b/server/src/ffmpeg/StreamSelectionEvaluator.ts @@ -275,4 +275,3 @@ async function resolveSubtitleAction( } } } - diff --git a/server/src/ffmpeg/builder/constants.ts b/server/src/ffmpeg/builder/constants.ts index 7249854a3..ba6d90e16 100644 --- a/server/src/ffmpeg/builder/constants.ts +++ b/server/src/ffmpeg/builder/constants.ts @@ -71,6 +71,8 @@ export const AudioFormats = { Flac: 'flac', Dca: 'dca', TrueHd: 'truehd', + Opus: 'libopus', + Eac3: 'eac3', } as const; export type StdoutOutputLocation = { diff --git a/server/src/ffmpeg/builder/options/AudioOutputOptions.ts b/server/src/ffmpeg/builder/options/AudioOutputOptions.ts index 0be3c9123..ee365e4c2 100644 --- a/server/src/ffmpeg/builder/options/AudioOutputOptions.ts +++ b/server/src/ffmpeg/builder/options/AudioOutputOptions.ts @@ -12,7 +12,8 @@ export const AudioChannelsOutputOption = ( const opts: string[] = []; if ( sourceChannels !== desiredChannels || - (audioFormat === AudioFormats.Aac && desiredChannels > 2) + ((audioFormat === AudioFormats.Aac || audioFormat === AudioFormats.Opus) && + desiredChannels > 2) ) { opts.push('-ac', desiredChannels.toString()); } diff --git a/server/src/ffmpeg/builder/pipeline/BasePipelineBuilder.test.ts b/server/src/ffmpeg/builder/pipeline/BasePipelineBuilder.test.ts index 2d5f125b9..cc0ddabb8 100644 --- a/server/src/ffmpeg/builder/pipeline/BasePipelineBuilder.test.ts +++ b/server/src/ffmpeg/builder/pipeline/BasePipelineBuilder.test.ts @@ -387,4 +387,34 @@ describe('BasePipelineBuilder', () => { expect(loudnormFilter).toBeUndefined(); }); + + test('always add channel count for Opus', () => { + const audio = AudioInputSource.withStream( + new FileStreamSource('/path/to/movie.mkv'), + AudioStream.create({ + channels: 6, + codec: 'ac3', + index: 0, + }), + AudioState.create({ + audioEncoder: 'libopus', + audioChannels: 6, + }), + ); + + const pipeline = new NoopPipelineBuilder( + video, + audio, + null, + null, + null, + EmptyFfmpegCapabilities, + ); + + const result = pipeline.build(state, frameState, DefaultPipelineOptions); + const commandArgs = result.getCommandArgs(); + const channelIdx = commandArgs?.indexOf('-ac'); + expect(channelIdx).toBeDefined(); + expect(commandArgs?.at(channelIdx + 1)).toBe('6'); + }); }); diff --git a/server/src/migration/DirectMigrationProvider.ts b/server/src/migration/DirectMigrationProvider.ts index c93dfe109..482f56ec2 100644 --- a/server/src/migration/DirectMigrationProvider.ts +++ b/server/src/migration/DirectMigrationProvider.ts @@ -227,6 +227,12 @@ export class DirectMigrationProvider implements MigrationProvider { migration1777908252: makeMigrationFromSqlFile( './sql/0044_useful_groot.sql', ), + migration1779655043: makeMigrationFromSqlFile( + './sql/0045_lean_violations.sql', + ), + migration1782772646: makeMigrationFromSqlFile( + './sql/0046_melted_captain_flint.sql', + ), } satisfies Record, wrapWithTransaction, ); diff --git a/server/src/migration/db/sql/0045_lean_violations.sql b/server/src/migration/db/sql/0045_lean_violations.sql new file mode 100644 index 000000000..38e230fb0 --- /dev/null +++ b/server/src/migration/db/sql/0045_lean_violations.sql @@ -0,0 +1 @@ +ALTER TABLE `media_source` ADD `send_play_status_updates` integer DEFAULT false; \ No newline at end of file diff --git a/server/src/migration/db/sql/0046_melted_captain_flint.sql b/server/src/migration/db/sql/0046_melted_captain_flint.sql new file mode 100644 index 000000000..e84ad9782 --- /dev/null +++ b/server/src/migration/db/sql/0046_melted_captain_flint.sql @@ -0,0 +1,43 @@ +PRAGMA foreign_keys=OFF;--> statement-breakpoint +CREATE TABLE `__new_transcode_config` ( + `uuid` text PRIMARY KEY NOT NULL, + `name` text NOT NULL, + `thread_count` integer NOT NULL, + `hardware_acceleration_mode` text NOT NULL, + `vaapi_driver` text DEFAULT 'system' NOT NULL, + `vaapi_device` text, + `resolution` text NOT NULL, + `video_format` text NOT NULL, + `video_profile` text, + `video_preset` text, + `video_bit_depth` integer DEFAULT 8, + `video_bit_rate` integer NOT NULL, + `video_buffer_size` integer NOT NULL, + `audio_channels` integer NOT NULL, + `audio_format` text NOT NULL, + `audio_bit_rate` integer NOT NULL, + `audio_buffer_size` integer NOT NULL, + `audio_sample_rate` integer NOT NULL, + `audio_volume_percent` integer DEFAULT 100 NOT NULL, + `audio_loudnorm_config` text, + `normalize_frame_rate` integer DEFAULT false, + `deinterlace_video` integer DEFAULT true, + `disable_channel_overlay` integer DEFAULT false, + `error_screen` text DEFAULT 'pic' NOT NULL, + `error_screen_audio` text DEFAULT 'silent' NOT NULL, + `is_default` integer DEFAULT false NOT NULL, + `disable_hardware_decoder` integer DEFAULT false, + `disable_hardware_encoding` integer DEFAULT false, + `disable_hardware_filters` integer DEFAULT false, + CONSTRAINT "transcode_config_hardware_accel_check" CHECK("__new_transcode_config"."hardware_acceleration_mode" in ('none', 'cuda', 'vaapi', 'qsv', 'videotoolbox')), + CONSTRAINT "transcode_config_vaapi_driver_check" CHECK("__new_transcode_config"."vaapi_driver" in ('system', 'ihd', 'i965', 'radeonsi', 'nouveau')), + CONSTRAINT "transcode_config_video_format_check" CHECK("__new_transcode_config"."video_format" in ('h264', 'hevc', 'mpeg2video')), + CONSTRAINT "transcode_config_audio_format_check" CHECK("__new_transcode_config"."audio_format" in ('aac', 'ac3', 'copy', 'mp3', 'libopus')), + CONSTRAINT "transcode_config_error_screen_check" CHECK("__new_transcode_config"."error_screen" in ('static', 'pic', 'blank', 'testsrc', 'text', 'kill')), + CONSTRAINT "transcode_config_error_screen_audio_check" CHECK("__new_transcode_config"."error_screen_audio" in ('silent', 'sine', 'whitenoise')) +); +--> statement-breakpoint +INSERT INTO `__new_transcode_config`("uuid", "name", "thread_count", "hardware_acceleration_mode", "vaapi_driver", "vaapi_device", "resolution", "video_format", "video_profile", "video_preset", "video_bit_depth", "video_bit_rate", "video_buffer_size", "audio_channels", "audio_format", "audio_bit_rate", "audio_buffer_size", "audio_sample_rate", "audio_volume_percent", "audio_loudnorm_config", "normalize_frame_rate", "deinterlace_video", "disable_channel_overlay", "error_screen", "error_screen_audio", "is_default", "disable_hardware_decoder", "disable_hardware_encoding", "disable_hardware_filters") SELECT "uuid", "name", "thread_count", "hardware_acceleration_mode", "vaapi_driver", "vaapi_device", "resolution", "video_format", "video_profile", "video_preset", "video_bit_depth", "video_bit_rate", "video_buffer_size", "audio_channels", "audio_format", "audio_bit_rate", "audio_buffer_size", "audio_sample_rate", "audio_volume_percent", "audio_loudnorm_config", "normalize_frame_rate", "deinterlace_video", "disable_channel_overlay", "error_screen", "error_screen_audio", "is_default", "disable_hardware_decoder", "disable_hardware_encoding", "disable_hardware_filters" FROM `transcode_config`;--> statement-breakpoint +DROP TABLE `transcode_config`;--> statement-breakpoint +ALTER TABLE `__new_transcode_config` RENAME TO `transcode_config`;--> statement-breakpoint +PRAGMA foreign_keys=ON; \ No newline at end of file diff --git a/server/src/migration/db/sql/meta/0045_snapshot.json b/server/src/migration/db/sql/meta/0045_snapshot.json new file mode 100644 index 000000000..e33f3f1c1 --- /dev/null +++ b/server/src/migration/db/sql/meta/0045_snapshot.json @@ -0,0 +1,4175 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "882cf990-bbce-46d7-91ba-c2227a3f2098", + "prevId": "7fc76602-2332-46b5-aab6-c41eacbdad68", + "tables": { + "artwork": { + "name": "artwork", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "cache_path": { + "name": "cache_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "source_path": { + "name": "source_path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "artwork_type": { + "name": "artwork_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "blur_hash43": { + "name": "blur_hash43", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "blur_hash64": { + "name": "blur_hash64", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "program_id": { + "name": "program_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "grouping_id": { + "name": "grouping_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "credit_id": { + "name": "credit_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "artwork_program_idx": { + "name": "artwork_program_idx", + "columns": [ + "program_id" + ], + "isUnique": false + }, + "artwork_grouping_idx": { + "name": "artwork_grouping_idx", + "columns": [ + "grouping_id" + ], + "isUnique": false + }, + "artwork_credit_idx": { + "name": "artwork_credit_idx", + "columns": [ + "credit_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "artwork_program_id_program_uuid_fk": { + "name": "artwork_program_id_program_uuid_fk", + "tableFrom": "artwork", + "tableTo": "program", + "columnsFrom": [ + "program_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "artwork_grouping_id_program_grouping_uuid_fk": { + "name": "artwork_grouping_id_program_grouping_uuid_fk", + "tableFrom": "artwork", + "tableTo": "program_grouping", + "columnsFrom": [ + "grouping_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "artwork_credit_id_credit_uuid_fk": { + "name": "artwork_credit_id_credit_uuid_fk", + "tableFrom": "artwork", + "tableTo": "credit", + "columnsFrom": [ + "credit_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "cached_image": { + "name": "cached_image", + "columns": { + "hash": { + "name": "hash", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "mime_type": { + "name": "mime_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "channel": { + "name": "channel", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "disable_filler_overlay": { + "name": "disable_filler_overlay", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "duration": { + "name": "duration", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "filler_repeat_cooldown": { + "name": "filler_repeat_cooldown", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "group_title": { + "name": "group_title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "guide_flex_title": { + "name": "guide_flex_title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "guide_minimum_duration": { + "name": "guide_minimum_duration", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "number": { + "name": "number", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "offline": { + "name": "offline", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "start_time": { + "name": "start_time", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "stealth": { + "name": "stealth", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "stream_mode": { + "name": "stream_mode", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'hls'" + }, + "transcoding": { + "name": "transcoding", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "transcode_config_id": { + "name": "transcode_config_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "watermark": { + "name": "watermark", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "subtitles_enabled": { + "name": "subtitles_enabled", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "stream_selection_profile_id": { + "name": "stream_selection_profile_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "channel_number_unique": { + "name": "channel_number_unique", + "columns": [ + "number" + ], + "isUnique": true + } + }, + "foreignKeys": { + "channel_stream_selection_profile_id_stream_selection_profiles_uuid_fk": { + "name": "channel_stream_selection_profile_id_stream_selection_profiles_uuid_fk", + "tableFrom": "channel", + "tableTo": "stream_selection_profiles", + "columnsFrom": [ + "stream_selection_profile_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "channel_stream_mode_check": { + "name": "channel_stream_mode_check", + "value": "\"channel\".\"stream_mode\" in ('hls', 'hls_slower', 'mpegts', 'hls_direct', 'hls_direct_v2')" + } + } + }, + "channel_fallback": { + "name": "channel_fallback", + "columns": { + "channel_uuid": { + "name": "channel_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_uuid": { + "name": "program_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "channel_fallback_channel_uuid_channel_uuid_fk": { + "name": "channel_fallback_channel_uuid_channel_uuid_fk", + "tableFrom": "channel_fallback", + "tableTo": "channel", + "columnsFrom": [ + "channel_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "channel_fallback_program_uuid_program_uuid_fk": { + "name": "channel_fallback_program_uuid_program_uuid_fk", + "tableFrom": "channel_fallback", + "tableTo": "program", + "columnsFrom": [ + "program_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "channel_fallback_channel_uuid_program_uuid_pk": { + "columns": [ + "channel_uuid", + "program_uuid" + ], + "name": "channel_fallback_channel_uuid_program_uuid_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "channel_filler_show": { + "name": "channel_filler_show", + "columns": { + "channel_uuid": { + "name": "channel_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "filler_show_uuid": { + "name": "filler_show_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "cooldown": { + "name": "cooldown", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "weight": { + "name": "weight", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "channel_filler_show_channel_uuid_channel_uuid_fk": { + "name": "channel_filler_show_channel_uuid_channel_uuid_fk", + "tableFrom": "channel_filler_show", + "tableTo": "channel", + "columnsFrom": [ + "channel_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "channel_filler_show_filler_show_uuid_filler_show_uuid_fk": { + "name": "channel_filler_show_filler_show_uuid_filler_show_uuid_fk", + "tableFrom": "channel_filler_show", + "tableTo": "filler_show", + "columnsFrom": [ + "filler_show_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "channel_filler_show_channel_uuid_filler_show_uuid_pk": { + "columns": [ + "channel_uuid", + "filler_show_uuid" + ], + "name": "channel_filler_show_channel_uuid_filler_show_uuid_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "channel_programs": { + "name": "channel_programs", + "columns": { + "channel_uuid": { + "name": "channel_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_uuid": { + "name": "program_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "channel_programs_channel_uuid_channel_uuid_fk": { + "name": "channel_programs_channel_uuid_channel_uuid_fk", + "tableFrom": "channel_programs", + "tableTo": "channel", + "columnsFrom": [ + "channel_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "channel_programs_program_uuid_program_uuid_fk": { + "name": "channel_programs_program_uuid_program_uuid_fk", + "tableFrom": "channel_programs", + "tableTo": "program", + "columnsFrom": [ + "program_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "channel_programs_channel_uuid_program_uuid_pk": { + "columns": [ + "channel_uuid", + "program_uuid" + ], + "name": "channel_programs_channel_uuid_program_uuid_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "credit": { + "name": "credit", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "program_id": { + "name": "program_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "grouping_id": { + "name": "grouping_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "credit_program_id_idx": { + "name": "credit_program_id_idx", + "columns": [ + "program_id" + ], + "isUnique": false + }, + "credit_grouping_id_idx": { + "name": "credit_grouping_id_idx", + "columns": [ + "grouping_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "credit_program_id_program_uuid_fk": { + "name": "credit_program_id_program_uuid_fk", + "tableFrom": "credit", + "tableTo": "program", + "columnsFrom": [ + "program_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "credit_grouping_id_program_grouping_uuid_fk": { + "name": "credit_grouping_id_program_grouping_uuid_fk", + "tableFrom": "credit", + "tableTo": "program_grouping", + "columnsFrom": [ + "grouping_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "custom_show": { + "name": "custom_show", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "sync_media_source_id": { + "name": "sync_media_source_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sync_media_source_type": { + "name": "sync_media_source_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sync_external_playlist_id": { + "name": "sync_external_playlist_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_synced_at": { + "name": "last_synced_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "custom_show_sync_media_source_id_media_source_uuid_fk": { + "name": "custom_show_sync_media_source_id_media_source_uuid_fk", + "tableFrom": "custom_show", + "tableTo": "media_source", + "columnsFrom": [ + "sync_media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "custom_show_content": { + "name": "custom_show_content", + "columns": { + "content_uuid": { + "name": "content_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "custom_show_uuid": { + "name": "custom_show_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "custom_show_content_content_uuid_program_uuid_fk": { + "name": "custom_show_content_content_uuid_program_uuid_fk", + "tableFrom": "custom_show_content", + "tableTo": "program", + "columnsFrom": [ + "content_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "custom_show_content_custom_show_uuid_custom_show_uuid_fk": { + "name": "custom_show_content_custom_show_uuid_custom_show_uuid_fk", + "tableFrom": "custom_show_content", + "tableTo": "custom_show", + "columnsFrom": [ + "custom_show_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "custom_show_content_content_uuid_foreign": { + "name": "custom_show_content_content_uuid_foreign", + "tableFrom": "custom_show_content", + "tableTo": "program", + "columnsFrom": [ + "content_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "custom_show_content_custom_show_uuid_foreign": { + "name": "custom_show_content_custom_show_uuid_foreign", + "tableFrom": "custom_show_content", + "tableTo": "custom_show", + "columnsFrom": [ + "custom_show_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "custom_show_content_content_uuid_custom_show_uuid_index_pk": { + "columns": [ + "content_uuid", + "custom_show_uuid", + "index" + ], + "name": "custom_show_content_content_uuid_custom_show_uuid_index_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "external_collections": { + "name": "external_collections", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "media_source_id": { + "name": "media_source_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "library_id": { + "name": "library_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "external_key": { + "name": "external_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "source_type": { + "name": "source_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "external_collection_media_source_id_external_key_idx": { + "name": "external_collection_media_source_id_external_key_idx", + "columns": [ + "media_source_id", + "external_key" + ], + "isUnique": false + }, + "external_collection_library_id_external_key_idx": { + "name": "external_collection_library_id_external_key_idx", + "columns": [ + "library_id", + "external_key" + ], + "isUnique": false + }, + "external_collections_mediaSourceId_externalKey_unique": { + "name": "external_collections_mediaSourceId_externalKey_unique", + "columns": [ + "media_source_id", + "external_key" + ], + "isUnique": true + } + }, + "foreignKeys": { + "external_collections_media_source_id_media_source_uuid_fk": { + "name": "external_collections_media_source_id_media_source_uuid_fk", + "tableFrom": "external_collections", + "tableTo": "media_source", + "columnsFrom": [ + "media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "external_collections_library_id_media_source_library_uuid_fk": { + "name": "external_collections_library_id_media_source_library_uuid_fk", + "tableFrom": "external_collections", + "tableTo": "media_source_library", + "columnsFrom": [ + "library_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "external_collection_programs": { + "name": "external_collection_programs", + "columns": { + "collection_id": { + "name": "collection_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_id": { + "name": "program_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "grouping_id": { + "name": "grouping_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "external_collection_program_idx": { + "name": "external_collection_program_idx", + "columns": [ + "program_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "external_collection_programs_collection_id_external_collections_uuid_fk": { + "name": "external_collection_programs_collection_id_external_collections_uuid_fk", + "tableFrom": "external_collection_programs", + "tableTo": "external_collections", + "columnsFrom": [ + "collection_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "external_collection_programs_program_id_program_uuid_fk": { + "name": "external_collection_programs_program_id_program_uuid_fk", + "tableFrom": "external_collection_programs", + "tableTo": "program", + "columnsFrom": [ + "program_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "external_collection_programs_grouping_id_program_grouping_uuid_fk": { + "name": "external_collection_programs_grouping_id_program_grouping_uuid_fk", + "tableFrom": "external_collection_programs", + "tableTo": "program_grouping", + "columnsFrom": [ + "grouping_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "external_collection_programs_collection_id_program_id_pk": { + "columns": [ + "collection_id", + "program_id" + ], + "name": "external_collection_programs_collection_id_program_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "filler_show": { + "name": "filler_show", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "stream_selection_profile_id": { + "name": "stream_selection_profile_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "filler_show_stream_selection_profile_id_stream_selection_profiles_uuid_fk": { + "name": "filler_show_stream_selection_profile_id_stream_selection_profiles_uuid_fk", + "tableFrom": "filler_show", + "tableTo": "stream_selection_profiles", + "columnsFrom": [ + "stream_selection_profile_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "filler_show_content": { + "name": "filler_show_content", + "columns": { + "filler_show_uuid": { + "name": "filler_show_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_uuid": { + "name": "program_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "filler_show_content_filler_show_uuid_filler_show_uuid_fk": { + "name": "filler_show_content_filler_show_uuid_filler_show_uuid_fk", + "tableFrom": "filler_show_content", + "tableTo": "filler_show", + "columnsFrom": [ + "filler_show_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "filler_show_content_program_uuid_program_uuid_fk": { + "name": "filler_show_content_program_uuid_program_uuid_fk", + "tableFrom": "filler_show_content", + "tableTo": "program", + "columnsFrom": [ + "program_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "filler_show_content_filler_show_uuid_program_uuid_pk": { + "columns": [ + "filler_show_uuid", + "program_uuid" + ], + "name": "filler_show_content_filler_show_uuid_program_uuid_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "genre_entity": { + "name": "genre_entity", + "columns": { + "genre_id": { + "name": "genre_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_id": { + "name": "program_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "genre_entity_id_index": { + "name": "genre_entity_id_index", + "columns": [ + "genre_id" + ], + "isUnique": false + }, + "genre_entity_program_id_index": { + "name": "genre_entity_program_id_index", + "columns": [ + "program_id" + ], + "isUnique": false + }, + "genre_entity_group_id_index": { + "name": "genre_entity_group_id_index", + "columns": [ + "group_id" + ], + "isUnique": false + }, + "genre_program_unique_idx": { + "name": "genre_program_unique_idx", + "columns": [ + "genre_id", + "program_id" + ], + "isUnique": true + }, + "genre_grouping_unique_idx": { + "name": "genre_grouping_unique_idx", + "columns": [ + "genre_id", + "group_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "genre_entity_genre_id_genre_uuid_fk": { + "name": "genre_entity_genre_id_genre_uuid_fk", + "tableFrom": "genre_entity", + "tableTo": "genre", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "genre_entity_program_id_program_uuid_fk": { + "name": "genre_entity_program_id_program_uuid_fk", + "tableFrom": "genre_entity", + "tableTo": "program", + "columnsFrom": [ + "program_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "genre_entity_group_id_program_grouping_uuid_fk": { + "name": "genre_entity_group_id_program_grouping_uuid_fk", + "tableFrom": "genre_entity", + "tableTo": "program_grouping", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "genre": { + "name": "genre", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "genre_name_idx": { + "name": "genre_name_idx", + "columns": [ + "name" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "local_media_folder": { + "name": "local_media_folder", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "library_id": { + "name": "library_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "canonical_id": { + "name": "canonical_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "parent_id": { + "name": "parent_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "local_media_folder_library_id_path_idx": { + "name": "local_media_folder_library_id_path_idx", + "columns": [ + "library_id", + "path" + ], + "isUnique": false + }, + "local_media_folder_path_idx": { + "name": "local_media_folder_path_idx", + "columns": [ + "path" + ], + "isUnique": false + }, + "local_media_folder_canonical_id_id": { + "name": "local_media_folder_canonical_id_id", + "columns": [ + "canonical_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "local_media_folder_library_id_media_source_library_uuid_fk": { + "name": "local_media_folder_library_id_media_source_library_uuid_fk", + "tableFrom": "local_media_folder", + "tableTo": "media_source_library", + "columnsFrom": [ + "library_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "local_media_source_path": { + "name": "local_media_source_path", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "media_source_id": { + "name": "media_source_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_scanned_at": { + "name": "last_scanned_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "local_media_source_path_media_source_id_media_source_uuid_fk": { + "name": "local_media_source_path_media_source_id_media_source_uuid_fk", + "tableFrom": "local_media_source_path", + "tableTo": "media_source", + "columnsFrom": [ + "media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "media_source": { + "name": "media_source", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "client_identifier": { + "name": "client_identifier", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "send_channel_updates": { + "name": "send_channel_updates", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "send_guide_updates": { + "name": "send_guide_updates", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "send_play_status_updates": { + "name": "send_play_status_updates", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "uri": { + "name": "uri", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "media_type": { + "name": "media_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "media_source_type_check": { + "name": "media_source_type_check", + "value": "\"media_source\".\"type\" in ('plex', 'jellyfin', 'emby', 'local')" + } + } + }, + "media_source_library": { + "name": "media_source_library", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "media_type": { + "name": "media_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "media_source_id": { + "name": "media_source_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_scanned_at": { + "name": "last_scanned_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "external_key": { + "name": "external_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "media_source_library_media_source_id_media_source_uuid_fk": { + "name": "media_source_library_media_source_id_media_source_uuid_fk", + "tableFrom": "media_source_library", + "tableTo": "media_source", + "columnsFrom": [ + "media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "media_type_check": { + "name": "media_type_check", + "value": "\"media_source_library\".\"media_type\" in ('movies', 'shows', 'music_videos', 'other_videos', 'tracks')" + } + } + }, + "media_source_library_replace_path": { + "name": "media_source_library_replace_path", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "server_path": { + "name": "server_path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "local_path": { + "name": "local_path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "media_source_id": { + "name": "media_source_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "media_source_library_replace_path_media_source_id_media_source_uuid_fk": { + "name": "media_source_library_replace_path_media_source_id_media_source_uuid_fk", + "tableFrom": "media_source_library_replace_path", + "tableTo": "media_source", + "columnsFrom": [ + "media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "program": { + "name": "program", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "album_name": { + "name": "album_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "album_uuid": { + "name": "album_uuid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "artist_name": { + "name": "artist_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "artist_uuid": { + "name": "artist_uuid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "canonical_id": { + "name": "canonical_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "duration": { + "name": "duration", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "episode": { + "name": "episode", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "episode_icon": { + "name": "episode_icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "external_key": { + "name": "external_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "external_source_id": { + "name": "external_source_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "media_source_id": { + "name": "media_source_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "library_id": { + "name": "library_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "local_media_folder_id": { + "name": "local_media_folder_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "local_media_source_path_id": { + "name": "local_media_source_path_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "file_path": { + "name": "file_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "grandparent_external_key": { + "name": "grandparent_external_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "original_air_date": { + "name": "original_air_date", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "parent_external_key": { + "name": "parent_external_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "plex_file_path": { + "name": "plex_file_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "plex_rating_key": { + "name": "plex_rating_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rating": { + "name": "rating", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "season_icon": { + "name": "season_icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "season_number": { + "name": "season_number", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "season_uuid": { + "name": "season_uuid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "show_icon": { + "name": "show_icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "show_title": { + "name": "show_title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "source_type": { + "name": "source_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "plot": { + "name": "plot", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "tagline": { + "name": "tagline", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "tv_show_uuid": { + "name": "tv_show_uuid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "year": { + "name": "year", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "state": { + "name": "state", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'ok'" + }, + "stream_selection_profile_id": { + "name": "stream_selection_profile_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "program_season_uuid_index": { + "name": "program_season_uuid_index", + "columns": [ + "season_uuid" + ], + "isUnique": false + }, + "program_tv_show_uuid_index": { + "name": "program_tv_show_uuid_index", + "columns": [ + "tv_show_uuid" + ], + "isUnique": false + }, + "program_album_uuid_index": { + "name": "program_album_uuid_index", + "columns": [ + "album_uuid" + ], + "isUnique": false + }, + "program_artist_uuid_index": { + "name": "program_artist_uuid_index", + "columns": [ + "artist_uuid" + ], + "isUnique": false + }, + "program_media_source_id_index": { + "name": "program_media_source_id_index", + "columns": [ + "media_source_id" + ], + "isUnique": false + }, + "program_media_library_id_index": { + "name": "program_media_library_id_index", + "columns": [ + "library_id" + ], + "isUnique": false + }, + "program_source_type_external_source_id_external_key_unique": { + "name": "program_source_type_external_source_id_external_key_unique", + "columns": [ + "source_type", + "external_source_id", + "external_key" + ], + "isUnique": true + }, + "program_source_type_media_source_external_key_unique": { + "name": "program_source_type_media_source_external_key_unique", + "columns": [ + "source_type", + "media_source_id", + "external_key" + ], + "isUnique": true + }, + "program_canonical_id_index": { + "name": "program_canonical_id_index", + "columns": [ + "canonical_id" + ], + "isUnique": false + }, + "program_state_index": { + "name": "program_state_index", + "columns": [ + "state" + ], + "isUnique": false + } + }, + "foreignKeys": { + "program_album_uuid_program_grouping_uuid_fk": { + "name": "program_album_uuid_program_grouping_uuid_fk", + "tableFrom": "program", + "tableTo": "program_grouping", + "columnsFrom": [ + "album_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "program_artist_uuid_program_grouping_uuid_fk": { + "name": "program_artist_uuid_program_grouping_uuid_fk", + "tableFrom": "program", + "tableTo": "program_grouping", + "columnsFrom": [ + "artist_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "program_media_source_id_media_source_uuid_fk": { + "name": "program_media_source_id_media_source_uuid_fk", + "tableFrom": "program", + "tableTo": "media_source", + "columnsFrom": [ + "media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_library_id_media_source_library_uuid_fk": { + "name": "program_library_id_media_source_library_uuid_fk", + "tableFrom": "program", + "tableTo": "media_source_library", + "columnsFrom": [ + "library_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_local_media_folder_id_local_media_folder_uuid_fk": { + "name": "program_local_media_folder_id_local_media_folder_uuid_fk", + "tableFrom": "program", + "tableTo": "local_media_folder", + "columnsFrom": [ + "local_media_folder_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "program_local_media_source_path_id_local_media_source_path_uuid_fk": { + "name": "program_local_media_source_path_id_local_media_source_path_uuid_fk", + "tableFrom": "program", + "tableTo": "local_media_source_path", + "columnsFrom": [ + "local_media_source_path_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "program_season_uuid_program_grouping_uuid_fk": { + "name": "program_season_uuid_program_grouping_uuid_fk", + "tableFrom": "program", + "tableTo": "program_grouping", + "columnsFrom": [ + "season_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "program_tv_show_uuid_program_grouping_uuid_fk": { + "name": "program_tv_show_uuid_program_grouping_uuid_fk", + "tableFrom": "program", + "tableTo": "program_grouping", + "columnsFrom": [ + "tv_show_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "program_stream_selection_profile_id_stream_selection_profiles_uuid_fk": { + "name": "program_stream_selection_profile_id_stream_selection_profiles_uuid_fk", + "tableFrom": "program", + "tableTo": "stream_selection_profiles", + "columnsFrom": [ + "stream_selection_profile_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "program_type_check": { + "name": "program_type_check", + "value": "\"program\".\"type\" in ('movie', 'episode', 'track', 'music_video', 'other_video')" + }, + "program_source_type_check": { + "name": "program_source_type_check", + "value": "\"program\".\"source_type\" in ('plex', 'jellyfin', 'emby', 'local')" + } + } + }, + "program_chapter": { + "name": "program_chapter", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "start_time": { + "name": "start_time", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "end_time": { + "name": "end_time", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "chapter_type": { + "name": "chapter_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'chapter'" + }, + "program_version_id": { + "name": "program_version_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "program_chapter_program_version_id_program_version_uuid_fk": { + "name": "program_chapter_program_version_id_program_version_uuid_fk", + "tableFrom": "program_chapter", + "tableTo": "program_version", + "columnsFrom": [ + "program_version_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "program_external_id": { + "name": "program_external_id", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "direct_file_path": { + "name": "direct_file_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "external_file_path": { + "name": "external_file_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "external_key": { + "name": "external_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "external_source_id": { + "name": "external_source_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "media_source_id": { + "name": "media_source_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "program_uuid": { + "name": "program_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "source_type": { + "name": "source_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "program_external_id_program_uuid_index": { + "name": "program_external_id_program_uuid_index", + "columns": [ + "program_uuid" + ], + "isUnique": false + }, + "unique_program_multiple_external_id": { + "name": "unique_program_multiple_external_id", + "columns": [ + "program_uuid", + "source_type", + "external_source_id" + ], + "isUnique": true, + "where": "`external_source_id` is not null" + }, + "unique_program_single_external_id": { + "name": "unique_program_single_external_id", + "columns": [ + "program_uuid", + "source_type" + ], + "isUnique": true, + "where": "`external_source_id` is null" + }, + "unique_program_multiple_external_id_media_source": { + "name": "unique_program_multiple_external_id_media_source", + "columns": [ + "program_uuid", + "source_type", + "media_source_id" + ], + "isUnique": true, + "where": "`media_source_id` is not null" + }, + "unique_program_single_external_id_media_source": { + "name": "unique_program_single_external_id_media_source", + "columns": [ + "program_uuid", + "source_type" + ], + "isUnique": true, + "where": "`media_source_id` is null" + } + }, + "foreignKeys": { + "program_external_id_media_source_id_media_source_uuid_fk": { + "name": "program_external_id_media_source_id_media_source_uuid_fk", + "tableFrom": "program_external_id", + "tableTo": "media_source", + "columnsFrom": [ + "media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_external_id_program_uuid_program_uuid_fk": { + "name": "program_external_id_program_uuid_program_uuid_fk", + "tableFrom": "program_external_id", + "tableTo": "program", + "columnsFrom": [ + "program_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "source_type": { + "name": "source_type", + "value": "\"program_external_id\".\"source_type\" in ('plex', 'plex-guid', 'tmdb', 'imdb', 'tvdb', 'jellyfin', 'emby')" + } + } + }, + "program_grouping": { + "name": "program_grouping", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "canonical_id": { + "name": "canonical_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "plot": { + "name": "plot", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "tagline": { + "name": "tagline", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "year": { + "name": "year", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "release_date": { + "name": "release_date", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rating": { + "name": "rating", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "source_type": { + "name": "source_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "external_key": { + "name": "external_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "media_source_id": { + "name": "media_source_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "artist_uuid": { + "name": "artist_uuid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "show_uuid": { + "name": "show_uuid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "library_id": { + "name": "library_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "state": { + "name": "state", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'ok'" + } + }, + "indexes": { + "program_grouping_show_uuid_index": { + "name": "program_grouping_show_uuid_index", + "columns": [ + "show_uuid" + ], + "isUnique": false + }, + "program_grouping_artist_uuid_index": { + "name": "program_grouping_artist_uuid_index", + "columns": [ + "artist_uuid" + ], + "isUnique": false + } + }, + "foreignKeys": { + "program_grouping_media_source_id_media_source_uuid_fk": { + "name": "program_grouping_media_source_id_media_source_uuid_fk", + "tableFrom": "program_grouping", + "tableTo": "media_source", + "columnsFrom": [ + "media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_grouping_artist_uuid_program_grouping_uuid_fk": { + "name": "program_grouping_artist_uuid_program_grouping_uuid_fk", + "tableFrom": "program_grouping", + "tableTo": "program_grouping", + "columnsFrom": [ + "artist_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_grouping_show_uuid_program_grouping_uuid_fk": { + "name": "program_grouping_show_uuid_program_grouping_uuid_fk", + "tableFrom": "program_grouping", + "tableTo": "program_grouping", + "columnsFrom": [ + "show_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_grouping_library_id_media_source_library_uuid_fk": { + "name": "program_grouping_library_id_media_source_library_uuid_fk", + "tableFrom": "program_grouping", + "tableTo": "media_source_library", + "columnsFrom": [ + "library_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "type_check": { + "name": "type_check", + "value": "\"program_grouping\".\"type\" in ('show', 'season', 'artist', 'album')" + } + } + }, + "program_grouping_external_id": { + "name": "program_grouping_external_id", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "external_file_path": { + "name": "external_file_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "external_key": { + "name": "external_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "external_source_id": { + "name": "external_source_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "media_source_id": { + "name": "media_source_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "group_uuid": { + "name": "group_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "source_type": { + "name": "source_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "library_id": { + "name": "library_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "program_grouping_group_uuid_index": { + "name": "program_grouping_group_uuid_index", + "columns": [ + "group_uuid" + ], + "isUnique": false + }, + "unique_program_grouping_multiple_external_id_media_source": { + "name": "unique_program_grouping_multiple_external_id_media_source", + "columns": [ + "group_uuid", + "source_type", + "media_source_id" + ], + "isUnique": true, + "where": "`media_source_id is not null`" + }, + "unique_program_grouping_single_external_id_media_source": { + "name": "unique_program_grouping_single_external_id_media_source", + "columns": [ + "group_uuid", + "source_type", + "media_source_id" + ], + "isUnique": true, + "where": "`media_source_id is null`" + } + }, + "foreignKeys": { + "program_grouping_external_id_media_source_id_media_source_uuid_fk": { + "name": "program_grouping_external_id_media_source_id_media_source_uuid_fk", + "tableFrom": "program_grouping_external_id", + "tableTo": "media_source", + "columnsFrom": [ + "media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_grouping_external_id_group_uuid_program_grouping_uuid_fk": { + "name": "program_grouping_external_id_group_uuid_program_grouping_uuid_fk", + "tableFrom": "program_grouping_external_id", + "tableTo": "program_grouping", + "columnsFrom": [ + "group_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "program_grouping_external_id_library_id_media_source_library_uuid_fk": { + "name": "program_grouping_external_id_library_id_media_source_library_uuid_fk", + "tableFrom": "program_grouping_external_id", + "tableTo": "media_source_library", + "columnsFrom": [ + "library_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "source_type_check": { + "name": "source_type_check", + "value": "\"program_grouping_external_id\".\"source_type\" in ('plex', 'plex-guid', 'tmdb', 'imdb', 'tvdb', 'jellyfin', 'emby')" + } + } + }, + "program_media_file": { + "name": "program_media_file", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_version_id": { + "name": "program_version_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "local_media_folder_id": { + "name": "local_media_folder_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "program_media_file_program_version_idx": { + "name": "program_media_file_program_version_idx", + "columns": [ + "program_version_id" + ], + "isUnique": false + }, + "program_media_file_folder_idx": { + "name": "program_media_file_folder_idx", + "columns": [ + "local_media_folder_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "program_media_file_program_version_id_program_version_uuid_fk": { + "name": "program_media_file_program_version_id_program_version_uuid_fk", + "tableFrom": "program_media_file", + "tableTo": "program_version", + "columnsFrom": [ + "program_version_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_media_file_local_media_folder_id_local_media_folder_uuid_fk": { + "name": "program_media_file_local_media_folder_id_local_media_folder_uuid_fk", + "tableFrom": "program_media_file", + "tableTo": "local_media_folder", + "columnsFrom": [ + "local_media_folder_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "program_media_stream": { + "name": "program_media_stream", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "codec": { + "name": "codec", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "profile": { + "name": "profile", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "stream_kind": { + "name": "stream_kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "language": { + "name": "language", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "channels": { + "name": "channels", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "default": { + "name": "default", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "forced": { + "name": "forced", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "pixel_format": { + "name": "pixel_format", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "color_range": { + "name": "color_range", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "color_space": { + "name": "color_space", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "color_transfer": { + "name": "color_transfer", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "color_primaries": { + "name": "color_primaries", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "bits_per_sample": { + "name": "bits_per_sample", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "program_version_id": { + "name": "program_version_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "index_program_version_id": { + "name": "index_program_version_id", + "columns": [ + "program_version_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "program_media_stream_program_version_id_program_version_uuid_fk": { + "name": "program_media_stream_program_version_id_program_version_uuid_fk", + "tableFrom": "program_media_stream", + "tableTo": "program_version", + "columnsFrom": [ + "program_version_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "program_play_history": { + "name": "program_play_history", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "program_uuid": { + "name": "program_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "channel_uuid": { + "name": "channel_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "played_at": { + "name": "played_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "played_duration": { + "name": "played_duration", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "filler_list_id": { + "name": "filler_list_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "program_play_history_program_uuid_index": { + "name": "program_play_history_program_uuid_index", + "columns": [ + "program_uuid" + ], + "isUnique": false + }, + "program_play_history_channel_uuid_index": { + "name": "program_play_history_channel_uuid_index", + "columns": [ + "channel_uuid", + "program_uuid", + "filler_list_id" + ], + "isUnique": false + }, + "program_play_history_played_at_index": { + "name": "program_play_history_played_at_index", + "columns": [ + "played_at" + ], + "isUnique": false + }, + "program_play_history_channel_played_at_index": { + "name": "program_play_history_channel_played_at_index", + "columns": [ + "channel_uuid", + "played_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "program_play_history_program_uuid_program_uuid_fk": { + "name": "program_play_history_program_uuid_program_uuid_fk", + "tableFrom": "program_play_history", + "tableTo": "program", + "columnsFrom": [ + "program_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_play_history_channel_uuid_channel_uuid_fk": { + "name": "program_play_history_channel_uuid_channel_uuid_fk", + "tableFrom": "program_play_history", + "tableTo": "channel", + "columnsFrom": [ + "channel_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_play_history_filler_list_id_filler_show_uuid_fk": { + "name": "program_play_history_filler_list_id_filler_show_uuid_fk", + "tableFrom": "program_play_history", + "tableTo": "filler_show", + "columnsFrom": [ + "filler_list_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "program_subtitles": { + "name": "program_subtitles", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "subtitle_type": { + "name": "subtitle_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "stream_index": { + "name": "stream_index", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "codec": { + "name": "codec", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "default": { + "name": "default", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "forced": { + "name": "forced", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "sdh": { + "name": "sdh", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "language": { + "name": "language", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "program_id": { + "name": "program_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "is_extracted": { + "name": "is_extracted", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "program_subtitles_program_id_program_uuid_fk": { + "name": "program_subtitles_program_id_program_uuid_fk", + "tableFrom": "program_subtitles", + "tableTo": "program", + "columnsFrom": [ + "program_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "program_version": { + "name": "program_version", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "duration": { + "name": "duration", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "sample_aspect_ratio": { + "name": "sample_aspect_ratio", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "display_aspect_ratio": { + "name": "display_aspect_ratio", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "frame_rate": { + "name": "frame_rate", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "scan_kind": { + "name": "scan_kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_id": { + "name": "program_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "index_program_version_program_id": { + "name": "index_program_version_program_id", + "columns": [ + "program_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "program_version_program_id_program_uuid_fk": { + "name": "program_version_program_id_program_uuid_fk", + "tableFrom": "program_version", + "tableTo": "program", + "columnsFrom": [ + "program_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "smart_collection": { + "name": "smart_collection", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "query": { + "name": "query", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "keywords": { + "name": "keywords", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "stream_selection_profiles": { + "name": "stream_selection_profiles", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "rules": { + "name": "rules", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "studio": { + "name": "studio", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "studio_entity": { + "name": "studio_entity", + "columns": { + "studio_id": { + "name": "studio_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_id": { + "name": "program_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "studio_entity_id_index": { + "name": "studio_entity_id_index", + "columns": [ + "studio_id" + ], + "isUnique": false + }, + "studio_entity_program_id_index": { + "name": "studio_entity_program_id_index", + "columns": [ + "program_id" + ], + "isUnique": false + }, + "studio_entity_group_id_index": { + "name": "studio_entity_group_id_index", + "columns": [ + "group_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "studio_entity_studio_id_studio_uuid_fk": { + "name": "studio_entity_studio_id_studio_uuid_fk", + "tableFrom": "studio_entity", + "tableTo": "studio", + "columnsFrom": [ + "studio_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "studio_entity_program_id_program_uuid_fk": { + "name": "studio_entity_program_id_program_uuid_fk", + "tableFrom": "studio_entity", + "tableTo": "program", + "columnsFrom": [ + "program_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "studio_entity_group_id_program_grouping_uuid_fk": { + "name": "studio_entity_group_id_program_grouping_uuid_fk", + "tableFrom": "studio_entity", + "tableTo": "program_grouping", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "channel_subtitle_preferences": { + "name": "channel_subtitle_preferences", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "language_code": { + "name": "language_code", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "priority": { + "name": "priority", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "allow_image_based": { + "name": "allow_image_based", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "allow_external": { + "name": "allow_external", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "filter_type": { + "name": "filter_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'any'" + }, + "channel_id": { + "name": "channel_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "channel_priority_index": { + "name": "channel_priority_index", + "columns": [ + "channel_id", + "priority" + ], + "isUnique": false + } + }, + "foreignKeys": { + "channel_subtitle_preferences_channel_id_channel_uuid_fk": { + "name": "channel_subtitle_preferences_channel_id_channel_uuid_fk", + "tableFrom": "channel_subtitle_preferences", + "tableTo": "channel", + "columnsFrom": [ + "channel_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "custom_show_subtitle_preferences": { + "name": "custom_show_subtitle_preferences", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "language_code": { + "name": "language_code", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "priority": { + "name": "priority", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "allow_image_based": { + "name": "allow_image_based", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "allow_external": { + "name": "allow_external", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "filter_type": { + "name": "filter_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'any'" + }, + "custom_show_id": { + "name": "custom_show_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "custom_show_priority_index": { + "name": "custom_show_priority_index", + "columns": [ + "custom_show_id", + "priority" + ], + "isUnique": false + } + }, + "foreignKeys": { + "custom_show_subtitle_preferences_custom_show_id_custom_show_uuid_fk": { + "name": "custom_show_subtitle_preferences_custom_show_id_custom_show_uuid_fk", + "tableFrom": "custom_show_subtitle_preferences", + "tableTo": "custom_show", + "columnsFrom": [ + "custom_show_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "tags": { + "name": "tags", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "tag": { + "name": "tag", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "tags_unique_tag_idx": { + "name": "tags_unique_tag_idx", + "columns": [ + "tag" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "tag_relations": { + "name": "tag_relations", + "columns": { + "tag_id": { + "name": "tag_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_id": { + "name": "program_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "grouping_id": { + "name": "grouping_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'media'" + } + }, + "indexes": { + "tag_relations_program_id_idx": { + "name": "tag_relations_program_id_idx", + "columns": [ + "program_id" + ], + "isUnique": false + }, + "tag_relations_grouping_id_idx": { + "name": "tag_relations_grouping_id_idx", + "columns": [ + "grouping_id" + ], + "isUnique": false + }, + "tag_program_id_unique_idx": { + "name": "tag_program_id_unique_idx", + "columns": [ + "tag_id", + "program_id", + "source" + ], + "isUnique": true + }, + "tag_grouping_id_unique_idx": { + "name": "tag_grouping_id_unique_idx", + "columns": [ + "tag_id", + "grouping_id", + "source" + ], + "isUnique": true + } + }, + "foreignKeys": { + "tag_relations_tag_id_tags_uuid_fk": { + "name": "tag_relations_tag_id_tags_uuid_fk", + "tableFrom": "tag_relations", + "tableTo": "tags", + "columnsFrom": [ + "tag_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "tag_relations_program_id_program_uuid_fk": { + "name": "tag_relations_program_id_program_uuid_fk", + "tableFrom": "tag_relations", + "tableTo": "program", + "columnsFrom": [ + "program_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "tag_relations_grouping_id_program_grouping_uuid_fk": { + "name": "tag_relations_grouping_id_program_grouping_uuid_fk", + "tableFrom": "tag_relations", + "tableTo": "program_grouping", + "columnsFrom": [ + "grouping_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "transcode_config": { + "name": "transcode_config", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "thread_count": { + "name": "thread_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "hardware_acceleration_mode": { + "name": "hardware_acceleration_mode", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "vaapi_driver": { + "name": "vaapi_driver", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'system'" + }, + "vaapi_device": { + "name": "vaapi_device", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "resolution": { + "name": "resolution", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "video_format": { + "name": "video_format", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "video_profile": { + "name": "video_profile", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "video_preset": { + "name": "video_preset", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "video_bit_depth": { + "name": "video_bit_depth", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 8 + }, + "video_bit_rate": { + "name": "video_bit_rate", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "video_buffer_size": { + "name": "video_buffer_size", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "audio_channels": { + "name": "audio_channels", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "audio_format": { + "name": "audio_format", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "audio_bit_rate": { + "name": "audio_bit_rate", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "audio_buffer_size": { + "name": "audio_buffer_size", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "audio_sample_rate": { + "name": "audio_sample_rate", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "audio_volume_percent": { + "name": "audio_volume_percent", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 100 + }, + "audio_loudnorm_config": { + "name": "audio_loudnorm_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "normalize_frame_rate": { + "name": "normalize_frame_rate", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "deinterlace_video": { + "name": "deinterlace_video", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": true + }, + "disable_channel_overlay": { + "name": "disable_channel_overlay", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "error_screen": { + "name": "error_screen", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'pic'" + }, + "error_screen_audio": { + "name": "error_screen_audio", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'silent'" + }, + "is_default": { + "name": "is_default", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "disable_hardware_decoder": { + "name": "disable_hardware_decoder", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "disable_hardware_encoding": { + "name": "disable_hardware_encoding", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "disable_hardware_filters": { + "name": "disable_hardware_filters", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "transcode_config_hardware_accel_check": { + "name": "transcode_config_hardware_accel_check", + "value": "\"transcode_config\".\"hardware_acceleration_mode\" in ('none', 'cuda', 'vaapi', 'qsv', 'videotoolbox')" + }, + "transcode_config_vaapi_driver_check": { + "name": "transcode_config_vaapi_driver_check", + "value": "\"transcode_config\".\"vaapi_driver\" in ('system', 'ihd', 'i965', 'radeonsi', 'nouveau')" + }, + "transcode_config_video_format_check": { + "name": "transcode_config_video_format_check", + "value": "\"transcode_config\".\"video_format\" in ('h264', 'hevc', 'mpeg2video')" + }, + "transcode_config_audio_format_check": { + "name": "transcode_config_audio_format_check", + "value": "\"transcode_config\".\"audio_format\" in ('aac', 'ac3', 'copy', 'mp3')" + }, + "transcode_config_error_screen_check": { + "name": "transcode_config_error_screen_check", + "value": "\"transcode_config\".\"error_screen\" in ('static', 'pic', 'blank', 'testsrc', 'text', 'kill')" + }, + "transcode_config_error_screen_audio_check": { + "name": "transcode_config_error_screen_audio_check", + "value": "\"transcode_config\".\"error_screen_audio\" in ('silent', 'sine', 'whitenoise')" + } + } + } + }, + "views": {}, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": {} + } +} \ No newline at end of file diff --git a/server/src/migration/db/sql/meta/0046_snapshot.json b/server/src/migration/db/sql/meta/0046_snapshot.json new file mode 100644 index 000000000..0fd0de4a6 --- /dev/null +++ b/server/src/migration/db/sql/meta/0046_snapshot.json @@ -0,0 +1,4175 @@ +{ + "version": "6", + "dialect": "sqlite", + "id": "19a20928-115f-40b1-8eb6-ea572d5edba6", + "prevId": "882cf990-bbce-46d7-91ba-c2227a3f2098", + "tables": { + "artwork": { + "name": "artwork", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "cache_path": { + "name": "cache_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "source_path": { + "name": "source_path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "artwork_type": { + "name": "artwork_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "blur_hash43": { + "name": "blur_hash43", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "blur_hash64": { + "name": "blur_hash64", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "program_id": { + "name": "program_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "grouping_id": { + "name": "grouping_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "credit_id": { + "name": "credit_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "artwork_program_idx": { + "name": "artwork_program_idx", + "columns": [ + "program_id" + ], + "isUnique": false + }, + "artwork_grouping_idx": { + "name": "artwork_grouping_idx", + "columns": [ + "grouping_id" + ], + "isUnique": false + }, + "artwork_credit_idx": { + "name": "artwork_credit_idx", + "columns": [ + "credit_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "artwork_program_id_program_uuid_fk": { + "name": "artwork_program_id_program_uuid_fk", + "tableFrom": "artwork", + "tableTo": "program", + "columnsFrom": [ + "program_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "artwork_grouping_id_program_grouping_uuid_fk": { + "name": "artwork_grouping_id_program_grouping_uuid_fk", + "tableFrom": "artwork", + "tableTo": "program_grouping", + "columnsFrom": [ + "grouping_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "artwork_credit_id_credit_uuid_fk": { + "name": "artwork_credit_id_credit_uuid_fk", + "tableFrom": "artwork", + "tableTo": "credit", + "columnsFrom": [ + "credit_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "cached_image": { + "name": "cached_image", + "columns": { + "hash": { + "name": "hash", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "mime_type": { + "name": "mime_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "url": { + "name": "url", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "channel": { + "name": "channel", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "disable_filler_overlay": { + "name": "disable_filler_overlay", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "duration": { + "name": "duration", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "filler_repeat_cooldown": { + "name": "filler_repeat_cooldown", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "group_title": { + "name": "group_title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "guide_flex_title": { + "name": "guide_flex_title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "guide_minimum_duration": { + "name": "guide_minimum_duration", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "number": { + "name": "number", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "offline": { + "name": "offline", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "start_time": { + "name": "start_time", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "stealth": { + "name": "stealth", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "stream_mode": { + "name": "stream_mode", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'hls'" + }, + "transcoding": { + "name": "transcoding", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "transcode_config_id": { + "name": "transcode_config_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "watermark": { + "name": "watermark", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "subtitles_enabled": { + "name": "subtitles_enabled", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "stream_selection_profile_id": { + "name": "stream_selection_profile_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "channel_number_unique": { + "name": "channel_number_unique", + "columns": [ + "number" + ], + "isUnique": true + } + }, + "foreignKeys": { + "channel_stream_selection_profile_id_stream_selection_profiles_uuid_fk": { + "name": "channel_stream_selection_profile_id_stream_selection_profiles_uuid_fk", + "tableFrom": "channel", + "tableTo": "stream_selection_profiles", + "columnsFrom": [ + "stream_selection_profile_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "channel_stream_mode_check": { + "name": "channel_stream_mode_check", + "value": "\"channel\".\"stream_mode\" in ('hls', 'hls_slower', 'mpegts', 'hls_direct', 'hls_direct_v2')" + } + } + }, + "channel_fallback": { + "name": "channel_fallback", + "columns": { + "channel_uuid": { + "name": "channel_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_uuid": { + "name": "program_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "channel_fallback_channel_uuid_channel_uuid_fk": { + "name": "channel_fallback_channel_uuid_channel_uuid_fk", + "tableFrom": "channel_fallback", + "tableTo": "channel", + "columnsFrom": [ + "channel_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "channel_fallback_program_uuid_program_uuid_fk": { + "name": "channel_fallback_program_uuid_program_uuid_fk", + "tableFrom": "channel_fallback", + "tableTo": "program", + "columnsFrom": [ + "program_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "channel_fallback_channel_uuid_program_uuid_pk": { + "columns": [ + "channel_uuid", + "program_uuid" + ], + "name": "channel_fallback_channel_uuid_program_uuid_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "channel_filler_show": { + "name": "channel_filler_show", + "columns": { + "channel_uuid": { + "name": "channel_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "filler_show_uuid": { + "name": "filler_show_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "cooldown": { + "name": "cooldown", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "weight": { + "name": "weight", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "channel_filler_show_channel_uuid_channel_uuid_fk": { + "name": "channel_filler_show_channel_uuid_channel_uuid_fk", + "tableFrom": "channel_filler_show", + "tableTo": "channel", + "columnsFrom": [ + "channel_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "channel_filler_show_filler_show_uuid_filler_show_uuid_fk": { + "name": "channel_filler_show_filler_show_uuid_filler_show_uuid_fk", + "tableFrom": "channel_filler_show", + "tableTo": "filler_show", + "columnsFrom": [ + "filler_show_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "channel_filler_show_channel_uuid_filler_show_uuid_pk": { + "columns": [ + "channel_uuid", + "filler_show_uuid" + ], + "name": "channel_filler_show_channel_uuid_filler_show_uuid_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "channel_programs": { + "name": "channel_programs", + "columns": { + "channel_uuid": { + "name": "channel_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_uuid": { + "name": "program_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "channel_programs_channel_uuid_channel_uuid_fk": { + "name": "channel_programs_channel_uuid_channel_uuid_fk", + "tableFrom": "channel_programs", + "tableTo": "channel", + "columnsFrom": [ + "channel_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "channel_programs_program_uuid_program_uuid_fk": { + "name": "channel_programs_program_uuid_program_uuid_fk", + "tableFrom": "channel_programs", + "tableTo": "program", + "columnsFrom": [ + "program_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "channel_programs_channel_uuid_program_uuid_pk": { + "columns": [ + "channel_uuid", + "program_uuid" + ], + "name": "channel_programs_channel_uuid_program_uuid_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "credit": { + "name": "credit", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "role": { + "name": "role", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "program_id": { + "name": "program_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "grouping_id": { + "name": "grouping_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "credit_program_id_idx": { + "name": "credit_program_id_idx", + "columns": [ + "program_id" + ], + "isUnique": false + }, + "credit_grouping_id_idx": { + "name": "credit_grouping_id_idx", + "columns": [ + "grouping_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "credit_program_id_program_uuid_fk": { + "name": "credit_program_id_program_uuid_fk", + "tableFrom": "credit", + "tableTo": "program", + "columnsFrom": [ + "program_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "credit_grouping_id_program_grouping_uuid_fk": { + "name": "credit_grouping_id_program_grouping_uuid_fk", + "tableFrom": "credit", + "tableTo": "program_grouping", + "columnsFrom": [ + "grouping_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "custom_show": { + "name": "custom_show", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "sync_media_source_id": { + "name": "sync_media_source_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sync_media_source_type": { + "name": "sync_media_source_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "sync_external_playlist_id": { + "name": "sync_external_playlist_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "last_synced_at": { + "name": "last_synced_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "custom_show_sync_media_source_id_media_source_uuid_fk": { + "name": "custom_show_sync_media_source_id_media_source_uuid_fk", + "tableFrom": "custom_show", + "tableTo": "media_source", + "columnsFrom": [ + "sync_media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "custom_show_content": { + "name": "custom_show_content", + "columns": { + "content_uuid": { + "name": "content_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "custom_show_uuid": { + "name": "custom_show_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "custom_show_content_content_uuid_program_uuid_fk": { + "name": "custom_show_content_content_uuid_program_uuid_fk", + "tableFrom": "custom_show_content", + "tableTo": "program", + "columnsFrom": [ + "content_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "custom_show_content_custom_show_uuid_custom_show_uuid_fk": { + "name": "custom_show_content_custom_show_uuid_custom_show_uuid_fk", + "tableFrom": "custom_show_content", + "tableTo": "custom_show", + "columnsFrom": [ + "custom_show_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "custom_show_content_content_uuid_foreign": { + "name": "custom_show_content_content_uuid_foreign", + "tableFrom": "custom_show_content", + "tableTo": "program", + "columnsFrom": [ + "content_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "custom_show_content_custom_show_uuid_foreign": { + "name": "custom_show_content_custom_show_uuid_foreign", + "tableFrom": "custom_show_content", + "tableTo": "custom_show", + "columnsFrom": [ + "custom_show_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "custom_show_content_content_uuid_custom_show_uuid_index_pk": { + "columns": [ + "content_uuid", + "custom_show_uuid", + "index" + ], + "name": "custom_show_content_content_uuid_custom_show_uuid_index_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "external_collections": { + "name": "external_collections", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "media_source_id": { + "name": "media_source_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "library_id": { + "name": "library_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "external_key": { + "name": "external_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "source_type": { + "name": "source_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "external_collection_media_source_id_external_key_idx": { + "name": "external_collection_media_source_id_external_key_idx", + "columns": [ + "media_source_id", + "external_key" + ], + "isUnique": false + }, + "external_collection_library_id_external_key_idx": { + "name": "external_collection_library_id_external_key_idx", + "columns": [ + "library_id", + "external_key" + ], + "isUnique": false + }, + "external_collections_mediaSourceId_externalKey_unique": { + "name": "external_collections_mediaSourceId_externalKey_unique", + "columns": [ + "media_source_id", + "external_key" + ], + "isUnique": true + } + }, + "foreignKeys": { + "external_collections_media_source_id_media_source_uuid_fk": { + "name": "external_collections_media_source_id_media_source_uuid_fk", + "tableFrom": "external_collections", + "tableTo": "media_source", + "columnsFrom": [ + "media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "external_collections_library_id_media_source_library_uuid_fk": { + "name": "external_collections_library_id_media_source_library_uuid_fk", + "tableFrom": "external_collections", + "tableTo": "media_source_library", + "columnsFrom": [ + "library_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "external_collection_programs": { + "name": "external_collection_programs", + "columns": { + "collection_id": { + "name": "collection_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_id": { + "name": "program_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "grouping_id": { + "name": "grouping_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "external_collection_program_idx": { + "name": "external_collection_program_idx", + "columns": [ + "program_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "external_collection_programs_collection_id_external_collections_uuid_fk": { + "name": "external_collection_programs_collection_id_external_collections_uuid_fk", + "tableFrom": "external_collection_programs", + "tableTo": "external_collections", + "columnsFrom": [ + "collection_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "external_collection_programs_program_id_program_uuid_fk": { + "name": "external_collection_programs_program_id_program_uuid_fk", + "tableFrom": "external_collection_programs", + "tableTo": "program", + "columnsFrom": [ + "program_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "external_collection_programs_grouping_id_program_grouping_uuid_fk": { + "name": "external_collection_programs_grouping_id_program_grouping_uuid_fk", + "tableFrom": "external_collection_programs", + "tableTo": "program_grouping", + "columnsFrom": [ + "grouping_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "external_collection_programs_collection_id_program_id_pk": { + "columns": [ + "collection_id", + "program_id" + ], + "name": "external_collection_programs_collection_id_program_id_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "filler_show": { + "name": "filler_show", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "stream_selection_profile_id": { + "name": "stream_selection_profile_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "filler_show_stream_selection_profile_id_stream_selection_profiles_uuid_fk": { + "name": "filler_show_stream_selection_profile_id_stream_selection_profiles_uuid_fk", + "tableFrom": "filler_show", + "tableTo": "stream_selection_profiles", + "columnsFrom": [ + "stream_selection_profile_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "filler_show_content": { + "name": "filler_show_content", + "columns": { + "filler_show_uuid": { + "name": "filler_show_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_uuid": { + "name": "program_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "filler_show_content_filler_show_uuid_filler_show_uuid_fk": { + "name": "filler_show_content_filler_show_uuid_filler_show_uuid_fk", + "tableFrom": "filler_show_content", + "tableTo": "filler_show", + "columnsFrom": [ + "filler_show_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "filler_show_content_program_uuid_program_uuid_fk": { + "name": "filler_show_content_program_uuid_program_uuid_fk", + "tableFrom": "filler_show_content", + "tableTo": "program", + "columnsFrom": [ + "program_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": { + "filler_show_content_filler_show_uuid_program_uuid_pk": { + "columns": [ + "filler_show_uuid", + "program_uuid" + ], + "name": "filler_show_content_filler_show_uuid_program_uuid_pk" + } + }, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "genre_entity": { + "name": "genre_entity", + "columns": { + "genre_id": { + "name": "genre_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_id": { + "name": "program_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "genre_entity_id_index": { + "name": "genre_entity_id_index", + "columns": [ + "genre_id" + ], + "isUnique": false + }, + "genre_entity_program_id_index": { + "name": "genre_entity_program_id_index", + "columns": [ + "program_id" + ], + "isUnique": false + }, + "genre_entity_group_id_index": { + "name": "genre_entity_group_id_index", + "columns": [ + "group_id" + ], + "isUnique": false + }, + "genre_program_unique_idx": { + "name": "genre_program_unique_idx", + "columns": [ + "genre_id", + "program_id" + ], + "isUnique": true + }, + "genre_grouping_unique_idx": { + "name": "genre_grouping_unique_idx", + "columns": [ + "genre_id", + "group_id" + ], + "isUnique": true + } + }, + "foreignKeys": { + "genre_entity_genre_id_genre_uuid_fk": { + "name": "genre_entity_genre_id_genre_uuid_fk", + "tableFrom": "genre_entity", + "tableTo": "genre", + "columnsFrom": [ + "genre_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "genre_entity_program_id_program_uuid_fk": { + "name": "genre_entity_program_id_program_uuid_fk", + "tableFrom": "genre_entity", + "tableTo": "program", + "columnsFrom": [ + "program_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "genre_entity_group_id_program_grouping_uuid_fk": { + "name": "genre_entity_group_id_program_grouping_uuid_fk", + "tableFrom": "genre_entity", + "tableTo": "program_grouping", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "genre": { + "name": "genre", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "genre_name_idx": { + "name": "genre_name_idx", + "columns": [ + "name" + ], + "isUnique": false + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "local_media_folder": { + "name": "local_media_folder", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "library_id": { + "name": "library_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "canonical_id": { + "name": "canonical_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "parent_id": { + "name": "parent_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "local_media_folder_library_id_path_idx": { + "name": "local_media_folder_library_id_path_idx", + "columns": [ + "library_id", + "path" + ], + "isUnique": false + }, + "local_media_folder_path_idx": { + "name": "local_media_folder_path_idx", + "columns": [ + "path" + ], + "isUnique": false + }, + "local_media_folder_canonical_id_id": { + "name": "local_media_folder_canonical_id_id", + "columns": [ + "canonical_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "local_media_folder_library_id_media_source_library_uuid_fk": { + "name": "local_media_folder_library_id_media_source_library_uuid_fk", + "tableFrom": "local_media_folder", + "tableTo": "media_source_library", + "columnsFrom": [ + "library_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "local_media_source_path": { + "name": "local_media_source_path", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "media_source_id": { + "name": "media_source_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_scanned_at": { + "name": "last_scanned_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "local_media_source_path_media_source_id_media_source_uuid_fk": { + "name": "local_media_source_path_media_source_id_media_source_uuid_fk", + "tableFrom": "local_media_source_path", + "tableTo": "media_source", + "columnsFrom": [ + "media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "media_source": { + "name": "media_source", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "access_token": { + "name": "access_token", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "client_identifier": { + "name": "client_identifier", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "send_channel_updates": { + "name": "send_channel_updates", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "send_guide_updates": { + "name": "send_guide_updates", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "send_play_status_updates": { + "name": "send_play_status_updates", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "uri": { + "name": "uri", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "username": { + "name": "username", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "user_id": { + "name": "user_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "media_type": { + "name": "media_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "media_source_type_check": { + "name": "media_source_type_check", + "value": "\"media_source\".\"type\" in ('plex', 'jellyfin', 'emby', 'local')" + } + } + }, + "media_source_library": { + "name": "media_source_library", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "media_type": { + "name": "media_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "media_source_id": { + "name": "media_source_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "last_scanned_at": { + "name": "last_scanned_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "external_key": { + "name": "external_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "enabled": { + "name": "enabled", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "media_source_library_media_source_id_media_source_uuid_fk": { + "name": "media_source_library_media_source_id_media_source_uuid_fk", + "tableFrom": "media_source_library", + "tableTo": "media_source", + "columnsFrom": [ + "media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "media_type_check": { + "name": "media_type_check", + "value": "\"media_source_library\".\"media_type\" in ('movies', 'shows', 'music_videos', 'other_videos', 'tracks')" + } + } + }, + "media_source_library_replace_path": { + "name": "media_source_library_replace_path", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "server_path": { + "name": "server_path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "local_path": { + "name": "local_path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "media_source_id": { + "name": "media_source_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "media_source_library_replace_path_media_source_id_media_source_uuid_fk": { + "name": "media_source_library_replace_path_media_source_id_media_source_uuid_fk", + "tableFrom": "media_source_library_replace_path", + "tableTo": "media_source", + "columnsFrom": [ + "media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "program": { + "name": "program", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "album_name": { + "name": "album_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "album_uuid": { + "name": "album_uuid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "artist_name": { + "name": "artist_name", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "artist_uuid": { + "name": "artist_uuid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "canonical_id": { + "name": "canonical_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "duration": { + "name": "duration", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "episode": { + "name": "episode", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "episode_icon": { + "name": "episode_icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "external_key": { + "name": "external_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "external_source_id": { + "name": "external_source_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "media_source_id": { + "name": "media_source_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "library_id": { + "name": "library_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "local_media_folder_id": { + "name": "local_media_folder_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "local_media_source_path_id": { + "name": "local_media_source_path_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "file_path": { + "name": "file_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "grandparent_external_key": { + "name": "grandparent_external_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "original_air_date": { + "name": "original_air_date", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "parent_external_key": { + "name": "parent_external_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "plex_file_path": { + "name": "plex_file_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "plex_rating_key": { + "name": "plex_rating_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rating": { + "name": "rating", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "season_icon": { + "name": "season_icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "season_number": { + "name": "season_number", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "season_uuid": { + "name": "season_uuid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "show_icon": { + "name": "show_icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "show_title": { + "name": "show_title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "source_type": { + "name": "source_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "plot": { + "name": "plot", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "tagline": { + "name": "tagline", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "tv_show_uuid": { + "name": "tv_show_uuid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "year": { + "name": "year", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "state": { + "name": "state", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'ok'" + }, + "stream_selection_profile_id": { + "name": "stream_selection_profile_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "program_season_uuid_index": { + "name": "program_season_uuid_index", + "columns": [ + "season_uuid" + ], + "isUnique": false + }, + "program_tv_show_uuid_index": { + "name": "program_tv_show_uuid_index", + "columns": [ + "tv_show_uuid" + ], + "isUnique": false + }, + "program_album_uuid_index": { + "name": "program_album_uuid_index", + "columns": [ + "album_uuid" + ], + "isUnique": false + }, + "program_artist_uuid_index": { + "name": "program_artist_uuid_index", + "columns": [ + "artist_uuid" + ], + "isUnique": false + }, + "program_media_source_id_index": { + "name": "program_media_source_id_index", + "columns": [ + "media_source_id" + ], + "isUnique": false + }, + "program_media_library_id_index": { + "name": "program_media_library_id_index", + "columns": [ + "library_id" + ], + "isUnique": false + }, + "program_source_type_external_source_id_external_key_unique": { + "name": "program_source_type_external_source_id_external_key_unique", + "columns": [ + "source_type", + "external_source_id", + "external_key" + ], + "isUnique": true + }, + "program_source_type_media_source_external_key_unique": { + "name": "program_source_type_media_source_external_key_unique", + "columns": [ + "source_type", + "media_source_id", + "external_key" + ], + "isUnique": true + }, + "program_canonical_id_index": { + "name": "program_canonical_id_index", + "columns": [ + "canonical_id" + ], + "isUnique": false + }, + "program_state_index": { + "name": "program_state_index", + "columns": [ + "state" + ], + "isUnique": false + } + }, + "foreignKeys": { + "program_album_uuid_program_grouping_uuid_fk": { + "name": "program_album_uuid_program_grouping_uuid_fk", + "tableFrom": "program", + "tableTo": "program_grouping", + "columnsFrom": [ + "album_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "program_artist_uuid_program_grouping_uuid_fk": { + "name": "program_artist_uuid_program_grouping_uuid_fk", + "tableFrom": "program", + "tableTo": "program_grouping", + "columnsFrom": [ + "artist_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "program_media_source_id_media_source_uuid_fk": { + "name": "program_media_source_id_media_source_uuid_fk", + "tableFrom": "program", + "tableTo": "media_source", + "columnsFrom": [ + "media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_library_id_media_source_library_uuid_fk": { + "name": "program_library_id_media_source_library_uuid_fk", + "tableFrom": "program", + "tableTo": "media_source_library", + "columnsFrom": [ + "library_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_local_media_folder_id_local_media_folder_uuid_fk": { + "name": "program_local_media_folder_id_local_media_folder_uuid_fk", + "tableFrom": "program", + "tableTo": "local_media_folder", + "columnsFrom": [ + "local_media_folder_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "program_local_media_source_path_id_local_media_source_path_uuid_fk": { + "name": "program_local_media_source_path_id_local_media_source_path_uuid_fk", + "tableFrom": "program", + "tableTo": "local_media_source_path", + "columnsFrom": [ + "local_media_source_path_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "program_season_uuid_program_grouping_uuid_fk": { + "name": "program_season_uuid_program_grouping_uuid_fk", + "tableFrom": "program", + "tableTo": "program_grouping", + "columnsFrom": [ + "season_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "program_tv_show_uuid_program_grouping_uuid_fk": { + "name": "program_tv_show_uuid_program_grouping_uuid_fk", + "tableFrom": "program", + "tableTo": "program_grouping", + "columnsFrom": [ + "tv_show_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "no action", + "onUpdate": "no action" + }, + "program_stream_selection_profile_id_stream_selection_profiles_uuid_fk": { + "name": "program_stream_selection_profile_id_stream_selection_profiles_uuid_fk", + "tableFrom": "program", + "tableTo": "stream_selection_profiles", + "columnsFrom": [ + "stream_selection_profile_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "set null", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "program_type_check": { + "name": "program_type_check", + "value": "\"program\".\"type\" in ('movie', 'episode', 'track', 'music_video', 'other_video')" + }, + "program_source_type_check": { + "name": "program_source_type_check", + "value": "\"program\".\"source_type\" in ('plex', 'jellyfin', 'emby', 'local')" + } + } + }, + "program_chapter": { + "name": "program_chapter", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "start_time": { + "name": "start_time", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "end_time": { + "name": "end_time", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "chapter_type": { + "name": "chapter_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'chapter'" + }, + "program_version_id": { + "name": "program_version_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": { + "program_chapter_program_version_id_program_version_uuid_fk": { + "name": "program_chapter_program_version_id_program_version_uuid_fk", + "tableFrom": "program_chapter", + "tableTo": "program_version", + "columnsFrom": [ + "program_version_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "program_external_id": { + "name": "program_external_id", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "direct_file_path": { + "name": "direct_file_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "external_file_path": { + "name": "external_file_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "external_key": { + "name": "external_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "external_source_id": { + "name": "external_source_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "media_source_id": { + "name": "media_source_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "program_uuid": { + "name": "program_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "source_type": { + "name": "source_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "program_external_id_program_uuid_index": { + "name": "program_external_id_program_uuid_index", + "columns": [ + "program_uuid" + ], + "isUnique": false + }, + "unique_program_multiple_external_id": { + "name": "unique_program_multiple_external_id", + "columns": [ + "program_uuid", + "source_type", + "external_source_id" + ], + "isUnique": true, + "where": "`external_source_id` is not null" + }, + "unique_program_single_external_id": { + "name": "unique_program_single_external_id", + "columns": [ + "program_uuid", + "source_type" + ], + "isUnique": true, + "where": "`external_source_id` is null" + }, + "unique_program_multiple_external_id_media_source": { + "name": "unique_program_multiple_external_id_media_source", + "columns": [ + "program_uuid", + "source_type", + "media_source_id" + ], + "isUnique": true, + "where": "`media_source_id` is not null" + }, + "unique_program_single_external_id_media_source": { + "name": "unique_program_single_external_id_media_source", + "columns": [ + "program_uuid", + "source_type" + ], + "isUnique": true, + "where": "`media_source_id` is null" + } + }, + "foreignKeys": { + "program_external_id_media_source_id_media_source_uuid_fk": { + "name": "program_external_id_media_source_id_media_source_uuid_fk", + "tableFrom": "program_external_id", + "tableTo": "media_source", + "columnsFrom": [ + "media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_external_id_program_uuid_program_uuid_fk": { + "name": "program_external_id_program_uuid_program_uuid_fk", + "tableFrom": "program_external_id", + "tableTo": "program", + "columnsFrom": [ + "program_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "source_type": { + "name": "source_type", + "value": "\"program_external_id\".\"source_type\" in ('plex', 'plex-guid', 'tmdb', 'imdb', 'tvdb', 'jellyfin', 'emby')" + } + } + }, + "program_grouping": { + "name": "program_grouping", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "canonical_id": { + "name": "canonical_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "icon": { + "name": "icon", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "summary": { + "name": "summary", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "plot": { + "name": "plot", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "tagline": { + "name": "tagline", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "type": { + "name": "type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "year": { + "name": "year", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "release_date": { + "name": "release_date", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "rating": { + "name": "rating", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "source_type": { + "name": "source_type", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "external_key": { + "name": "external_key", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "media_source_id": { + "name": "media_source_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "artist_uuid": { + "name": "artist_uuid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "show_uuid": { + "name": "show_uuid", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "library_id": { + "name": "library_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "state": { + "name": "state", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'ok'" + } + }, + "indexes": { + "program_grouping_show_uuid_index": { + "name": "program_grouping_show_uuid_index", + "columns": [ + "show_uuid" + ], + "isUnique": false + }, + "program_grouping_artist_uuid_index": { + "name": "program_grouping_artist_uuid_index", + "columns": [ + "artist_uuid" + ], + "isUnique": false + } + }, + "foreignKeys": { + "program_grouping_media_source_id_media_source_uuid_fk": { + "name": "program_grouping_media_source_id_media_source_uuid_fk", + "tableFrom": "program_grouping", + "tableTo": "media_source", + "columnsFrom": [ + "media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_grouping_artist_uuid_program_grouping_uuid_fk": { + "name": "program_grouping_artist_uuid_program_grouping_uuid_fk", + "tableFrom": "program_grouping", + "tableTo": "program_grouping", + "columnsFrom": [ + "artist_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_grouping_show_uuid_program_grouping_uuid_fk": { + "name": "program_grouping_show_uuid_program_grouping_uuid_fk", + "tableFrom": "program_grouping", + "tableTo": "program_grouping", + "columnsFrom": [ + "show_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_grouping_library_id_media_source_library_uuid_fk": { + "name": "program_grouping_library_id_media_source_library_uuid_fk", + "tableFrom": "program_grouping", + "tableTo": "media_source_library", + "columnsFrom": [ + "library_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "type_check": { + "name": "type_check", + "value": "\"program_grouping\".\"type\" in ('show', 'season', 'artist', 'album')" + } + } + }, + "program_grouping_external_id": { + "name": "program_grouping_external_id", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "external_file_path": { + "name": "external_file_path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "external_key": { + "name": "external_key", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "external_source_id": { + "name": "external_source_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "media_source_id": { + "name": "media_source_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "group_uuid": { + "name": "group_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "source_type": { + "name": "source_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "library_id": { + "name": "library_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "program_grouping_group_uuid_index": { + "name": "program_grouping_group_uuid_index", + "columns": [ + "group_uuid" + ], + "isUnique": false + }, + "unique_program_grouping_multiple_external_id_media_source": { + "name": "unique_program_grouping_multiple_external_id_media_source", + "columns": [ + "group_uuid", + "source_type", + "media_source_id" + ], + "isUnique": true, + "where": "`media_source_id is not null`" + }, + "unique_program_grouping_single_external_id_media_source": { + "name": "unique_program_grouping_single_external_id_media_source", + "columns": [ + "group_uuid", + "source_type", + "media_source_id" + ], + "isUnique": true, + "where": "`media_source_id is null`" + } + }, + "foreignKeys": { + "program_grouping_external_id_media_source_id_media_source_uuid_fk": { + "name": "program_grouping_external_id_media_source_id_media_source_uuid_fk", + "tableFrom": "program_grouping_external_id", + "tableTo": "media_source", + "columnsFrom": [ + "media_source_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_grouping_external_id_group_uuid_program_grouping_uuid_fk": { + "name": "program_grouping_external_id_group_uuid_program_grouping_uuid_fk", + "tableFrom": "program_grouping_external_id", + "tableTo": "program_grouping", + "columnsFrom": [ + "group_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "cascade" + }, + "program_grouping_external_id_library_id_media_source_library_uuid_fk": { + "name": "program_grouping_external_id_library_id_media_source_library_uuid_fk", + "tableFrom": "program_grouping_external_id", + "tableTo": "media_source_library", + "columnsFrom": [ + "library_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "source_type_check": { + "name": "source_type_check", + "value": "\"program_grouping_external_id\".\"source_type\" in ('plex', 'plex-guid', 'tmdb', 'imdb', 'tvdb', 'jellyfin', 'emby')" + } + } + }, + "program_media_file": { + "name": "program_media_file", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_version_id": { + "name": "program_version_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "local_media_folder_id": { + "name": "local_media_folder_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "program_media_file_program_version_idx": { + "name": "program_media_file_program_version_idx", + "columns": [ + "program_version_id" + ], + "isUnique": false + }, + "program_media_file_folder_idx": { + "name": "program_media_file_folder_idx", + "columns": [ + "local_media_folder_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "program_media_file_program_version_id_program_version_uuid_fk": { + "name": "program_media_file_program_version_id_program_version_uuid_fk", + "tableFrom": "program_media_file", + "tableTo": "program_version", + "columnsFrom": [ + "program_version_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_media_file_local_media_folder_id_local_media_folder_uuid_fk": { + "name": "program_media_file_local_media_folder_id_local_media_folder_uuid_fk", + "tableFrom": "program_media_file", + "tableTo": "local_media_folder", + "columnsFrom": [ + "local_media_folder_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "program_media_stream": { + "name": "program_media_stream", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "index": { + "name": "index", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "codec": { + "name": "codec", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "profile": { + "name": "profile", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "stream_kind": { + "name": "stream_kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "title": { + "name": "title", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "language": { + "name": "language", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "channels": { + "name": "channels", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "default": { + "name": "default", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "forced": { + "name": "forced", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "pixel_format": { + "name": "pixel_format", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "color_range": { + "name": "color_range", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "color_space": { + "name": "color_space", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "color_transfer": { + "name": "color_transfer", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "color_primaries": { + "name": "color_primaries", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "bits_per_sample": { + "name": "bits_per_sample", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "program_version_id": { + "name": "program_version_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "index_program_version_id": { + "name": "index_program_version_id", + "columns": [ + "program_version_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "program_media_stream_program_version_id_program_version_uuid_fk": { + "name": "program_media_stream_program_version_id_program_version_uuid_fk", + "tableFrom": "program_media_stream", + "tableTo": "program_version", + "columnsFrom": [ + "program_version_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "program_play_history": { + "name": "program_play_history", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "program_uuid": { + "name": "program_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "channel_uuid": { + "name": "channel_uuid", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "played_at": { + "name": "played_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "played_duration": { + "name": "played_duration", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "filler_list_id": { + "name": "filler_list_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "program_play_history_program_uuid_index": { + "name": "program_play_history_program_uuid_index", + "columns": [ + "program_uuid" + ], + "isUnique": false + }, + "program_play_history_channel_uuid_index": { + "name": "program_play_history_channel_uuid_index", + "columns": [ + "channel_uuid", + "program_uuid", + "filler_list_id" + ], + "isUnique": false + }, + "program_play_history_played_at_index": { + "name": "program_play_history_played_at_index", + "columns": [ + "played_at" + ], + "isUnique": false + }, + "program_play_history_channel_played_at_index": { + "name": "program_play_history_channel_played_at_index", + "columns": [ + "channel_uuid", + "played_at" + ], + "isUnique": false + } + }, + "foreignKeys": { + "program_play_history_program_uuid_program_uuid_fk": { + "name": "program_play_history_program_uuid_program_uuid_fk", + "tableFrom": "program_play_history", + "tableTo": "program", + "columnsFrom": [ + "program_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_play_history_channel_uuid_channel_uuid_fk": { + "name": "program_play_history_channel_uuid_channel_uuid_fk", + "tableFrom": "program_play_history", + "tableTo": "channel", + "columnsFrom": [ + "channel_uuid" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "program_play_history_filler_list_id_filler_show_uuid_fk": { + "name": "program_play_history_filler_list_id_filler_show_uuid_fk", + "tableFrom": "program_play_history", + "tableTo": "filler_show", + "columnsFrom": [ + "filler_list_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "no action", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "program_subtitles": { + "name": "program_subtitles", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "subtitle_type": { + "name": "subtitle_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "stream_index": { + "name": "stream_index", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "codec": { + "name": "codec", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "default": { + "name": "default", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "forced": { + "name": "forced", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "sdh": { + "name": "sdh", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "language": { + "name": "language", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "path": { + "name": "path", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "program_id": { + "name": "program_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "is_extracted": { + "name": "is_extracted", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": { + "program_subtitles_program_id_program_uuid_fk": { + "name": "program_subtitles_program_id_program_uuid_fk", + "tableFrom": "program_subtitles", + "tableTo": "program", + "columnsFrom": [ + "program_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "program_version": { + "name": "program_version", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "duration": { + "name": "duration", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "sample_aspect_ratio": { + "name": "sample_aspect_ratio", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "display_aspect_ratio": { + "name": "display_aspect_ratio", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "frame_rate": { + "name": "frame_rate", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "scan_kind": { + "name": "scan_kind", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "width": { + "name": "width", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "height": { + "name": "height", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_id": { + "name": "program_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "index_program_version_program_id": { + "name": "index_program_version_program_id", + "columns": [ + "program_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "program_version_program_id_program_uuid_fk": { + "name": "program_version_program_id_program_uuid_fk", + "tableFrom": "program_version", + "tableTo": "program", + "columnsFrom": [ + "program_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "smart_collection": { + "name": "smart_collection", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "query": { + "name": "query", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "keywords": { + "name": "keywords", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "stream_selection_profiles": { + "name": "stream_selection_profiles", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "rules": { + "name": "rules", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "created_at": { + "name": "created_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "updated_at": { + "name": "updated_at", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "studio": { + "name": "studio", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "studio_entity": { + "name": "studio_entity", + "columns": { + "studio_id": { + "name": "studio_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_id": { + "name": "program_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "group_id": { + "name": "group_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + } + }, + "indexes": { + "studio_entity_id_index": { + "name": "studio_entity_id_index", + "columns": [ + "studio_id" + ], + "isUnique": false + }, + "studio_entity_program_id_index": { + "name": "studio_entity_program_id_index", + "columns": [ + "program_id" + ], + "isUnique": false + }, + "studio_entity_group_id_index": { + "name": "studio_entity_group_id_index", + "columns": [ + "group_id" + ], + "isUnique": false + } + }, + "foreignKeys": { + "studio_entity_studio_id_studio_uuid_fk": { + "name": "studio_entity_studio_id_studio_uuid_fk", + "tableFrom": "studio_entity", + "tableTo": "studio", + "columnsFrom": [ + "studio_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "studio_entity_program_id_program_uuid_fk": { + "name": "studio_entity_program_id_program_uuid_fk", + "tableFrom": "studio_entity", + "tableTo": "program", + "columnsFrom": [ + "program_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "studio_entity_group_id_program_grouping_uuid_fk": { + "name": "studio_entity_group_id_program_grouping_uuid_fk", + "tableFrom": "studio_entity", + "tableTo": "program_grouping", + "columnsFrom": [ + "group_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "channel_subtitle_preferences": { + "name": "channel_subtitle_preferences", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "language_code": { + "name": "language_code", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "priority": { + "name": "priority", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "allow_image_based": { + "name": "allow_image_based", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "allow_external": { + "name": "allow_external", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "filter_type": { + "name": "filter_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'any'" + }, + "channel_id": { + "name": "channel_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "channel_priority_index": { + "name": "channel_priority_index", + "columns": [ + "channel_id", + "priority" + ], + "isUnique": false + } + }, + "foreignKeys": { + "channel_subtitle_preferences_channel_id_channel_uuid_fk": { + "name": "channel_subtitle_preferences_channel_id_channel_uuid_fk", + "tableFrom": "channel_subtitle_preferences", + "tableTo": "channel", + "columnsFrom": [ + "channel_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "custom_show_subtitle_preferences": { + "name": "custom_show_subtitle_preferences", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "language_code": { + "name": "language_code", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "priority": { + "name": "priority", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "allow_image_based": { + "name": "allow_image_based", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "allow_external": { + "name": "allow_external", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": true + }, + "filter_type": { + "name": "filter_type", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'any'" + }, + "custom_show_id": { + "name": "custom_show_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "custom_show_priority_index": { + "name": "custom_show_priority_index", + "columns": [ + "custom_show_id", + "priority" + ], + "isUnique": false + } + }, + "foreignKeys": { + "custom_show_subtitle_preferences_custom_show_id_custom_show_uuid_fk": { + "name": "custom_show_subtitle_preferences_custom_show_id_custom_show_uuid_fk", + "tableFrom": "custom_show_subtitle_preferences", + "tableTo": "custom_show", + "columnsFrom": [ + "custom_show_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "tags": { + "name": "tags", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "tag": { + "name": "tag", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + } + }, + "indexes": { + "tags_unique_tag_idx": { + "name": "tags_unique_tag_idx", + "columns": [ + "tag" + ], + "isUnique": true + } + }, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "tag_relations": { + "name": "tag_relations", + "columns": { + "tag_id": { + "name": "tag_id", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "program_id": { + "name": "program_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "grouping_id": { + "name": "grouping_id", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "source": { + "name": "source", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'media'" + } + }, + "indexes": { + "tag_relations_program_id_idx": { + "name": "tag_relations_program_id_idx", + "columns": [ + "program_id" + ], + "isUnique": false + }, + "tag_relations_grouping_id_idx": { + "name": "tag_relations_grouping_id_idx", + "columns": [ + "grouping_id" + ], + "isUnique": false + }, + "tag_program_id_unique_idx": { + "name": "tag_program_id_unique_idx", + "columns": [ + "tag_id", + "program_id", + "source" + ], + "isUnique": true + }, + "tag_grouping_id_unique_idx": { + "name": "tag_grouping_id_unique_idx", + "columns": [ + "tag_id", + "grouping_id", + "source" + ], + "isUnique": true + } + }, + "foreignKeys": { + "tag_relations_tag_id_tags_uuid_fk": { + "name": "tag_relations_tag_id_tags_uuid_fk", + "tableFrom": "tag_relations", + "tableTo": "tags", + "columnsFrom": [ + "tag_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "tag_relations_program_id_program_uuid_fk": { + "name": "tag_relations_program_id_program_uuid_fk", + "tableFrom": "tag_relations", + "tableTo": "program", + "columnsFrom": [ + "program_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + }, + "tag_relations_grouping_id_program_grouping_uuid_fk": { + "name": "tag_relations_grouping_id_program_grouping_uuid_fk", + "tableFrom": "tag_relations", + "tableTo": "program_grouping", + "columnsFrom": [ + "grouping_id" + ], + "columnsTo": [ + "uuid" + ], + "onDelete": "cascade", + "onUpdate": "no action" + } + }, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": {} + }, + "transcode_config": { + "name": "transcode_config", + "columns": { + "uuid": { + "name": "uuid", + "type": "text", + "primaryKey": true, + "notNull": true, + "autoincrement": false + }, + "name": { + "name": "name", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "thread_count": { + "name": "thread_count", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "hardware_acceleration_mode": { + "name": "hardware_acceleration_mode", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "vaapi_driver": { + "name": "vaapi_driver", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'system'" + }, + "vaapi_device": { + "name": "vaapi_device", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "resolution": { + "name": "resolution", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "video_format": { + "name": "video_format", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "video_profile": { + "name": "video_profile", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "video_preset": { + "name": "video_preset", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "video_bit_depth": { + "name": "video_bit_depth", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": 8 + }, + "video_bit_rate": { + "name": "video_bit_rate", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "video_buffer_size": { + "name": "video_buffer_size", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "audio_channels": { + "name": "audio_channels", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "audio_format": { + "name": "audio_format", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "audio_bit_rate": { + "name": "audio_bit_rate", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "audio_buffer_size": { + "name": "audio_buffer_size", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "audio_sample_rate": { + "name": "audio_sample_rate", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false + }, + "audio_volume_percent": { + "name": "audio_volume_percent", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": 100 + }, + "audio_loudnorm_config": { + "name": "audio_loudnorm_config", + "type": "text", + "primaryKey": false, + "notNull": false, + "autoincrement": false + }, + "normalize_frame_rate": { + "name": "normalize_frame_rate", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "deinterlace_video": { + "name": "deinterlace_video", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": true + }, + "disable_channel_overlay": { + "name": "disable_channel_overlay", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "error_screen": { + "name": "error_screen", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'pic'" + }, + "error_screen_audio": { + "name": "error_screen_audio", + "type": "text", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": "'silent'" + }, + "is_default": { + "name": "is_default", + "type": "integer", + "primaryKey": false, + "notNull": true, + "autoincrement": false, + "default": false + }, + "disable_hardware_decoder": { + "name": "disable_hardware_decoder", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "disable_hardware_encoding": { + "name": "disable_hardware_encoding", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + }, + "disable_hardware_filters": { + "name": "disable_hardware_filters", + "type": "integer", + "primaryKey": false, + "notNull": false, + "autoincrement": false, + "default": false + } + }, + "indexes": {}, + "foreignKeys": {}, + "compositePrimaryKeys": {}, + "uniqueConstraints": {}, + "checkConstraints": { + "transcode_config_hardware_accel_check": { + "name": "transcode_config_hardware_accel_check", + "value": "\"transcode_config\".\"hardware_acceleration_mode\" in ('none', 'cuda', 'vaapi', 'qsv', 'videotoolbox')" + }, + "transcode_config_vaapi_driver_check": { + "name": "transcode_config_vaapi_driver_check", + "value": "\"transcode_config\".\"vaapi_driver\" in ('system', 'ihd', 'i965', 'radeonsi', 'nouveau')" + }, + "transcode_config_video_format_check": { + "name": "transcode_config_video_format_check", + "value": "\"transcode_config\".\"video_format\" in ('h264', 'hevc', 'mpeg2video')" + }, + "transcode_config_audio_format_check": { + "name": "transcode_config_audio_format_check", + "value": "\"transcode_config\".\"audio_format\" in ('aac', 'ac3', 'copy', 'mp3', 'libopus')" + }, + "transcode_config_error_screen_check": { + "name": "transcode_config_error_screen_check", + "value": "\"transcode_config\".\"error_screen\" in ('static', 'pic', 'blank', 'testsrc', 'text', 'kill')" + }, + "transcode_config_error_screen_audio_check": { + "name": "transcode_config_error_screen_audio_check", + "value": "\"transcode_config\".\"error_screen_audio\" in ('silent', 'sine', 'whitenoise')" + } + } + } + }, + "views": {}, + "enums": {}, + "_meta": { + "schemas": {}, + "tables": {}, + "columns": {} + }, + "internal": { + "indexes": {} + } +} \ No newline at end of file diff --git a/server/src/migration/db/sql/meta/_journal.json b/server/src/migration/db/sql/meta/_journal.json index f5a4539b1..989e99579 100644 --- a/server/src/migration/db/sql/meta/_journal.json +++ b/server/src/migration/db/sql/meta/_journal.json @@ -316,6 +316,20 @@ "when": 1777906281969, "tag": "0044_useful_groot", "breakpoints": true + }, + { + "idx": 45, + "version": "6", + "when": 1779654984240, + "tag": "0045_lean_violations", + "breakpoints": true + }, + { + "idx": 46, + "version": "6", + "when": 1782780220054, + "tag": "0046_melted_captain_flint", + "breakpoints": true } ] } \ No newline at end of file diff --git a/server/src/services/CustomShowSyncService.test.ts b/server/src/services/CustomShowSyncService.test.ts index 45fd9f852..c155dc64f 100644 --- a/server/src/services/CustomShowSyncService.test.ts +++ b/server/src/services/CustomShowSyncService.test.ts @@ -1,3 +1,10 @@ +import type { CustomShowDB } from '@/db/CustomShowDB.js'; +import type { IProgramDB } from '@/db/interfaces/IProgramDB.js'; +import type { MediaSourceDB } from '@/db/mediaSourceDB.js'; +import type { MediaSourceId, MediaSourceName } from '@/db/schema/base.js'; +import type { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.js'; +import { Result } from '@/types/result.js'; +import type { MutexMap } from '@/util/mutexMap.js'; import { faker } from '@faker-js/faker'; import type { CondensedContentProgram, @@ -6,15 +13,8 @@ import type { } from '@tunarr/types'; import { tag } from '@tunarr/types'; import { describe, expect, it, vi } from 'vitest'; -import type { CustomShowDB } from '@/db/CustomShowDB.js'; -import type { IProgramDB } from '@/db/interfaces/IProgramDB.js'; -import type { MediaSourceDB } from '@/db/mediaSourceDB.js'; -import type { MediaSourceId, MediaSourceName } from '@/db/schema/base.js'; -import type { MediaSourceApiFactory } from '@/external/MediaSourceApiFactory.js'; -import type { MutexMap } from '@/util/mutexMap.js'; -import { Result } from '@/types/result.js'; -import type { GenericMediaSourceScannerFactory } from './scanner/MediaSourceScanner.js'; import { CustomShowSyncService } from './CustomShowSyncService.js'; +import type { GenericMediaSourceScannerFactory } from './scanner/MediaSourceScanner.js'; const { fakeLogger } = vi.hoisted(() => { const fakeLogger = { @@ -220,6 +220,7 @@ describe('CustomShowSyncService', () => { { uuid: dbUuid1, sourceType: 'plex', + externalSourceId: mediaSourceId, mediaSourceId: mediaSourceId, externalKey: movie1.externalId, externalIds: [], @@ -227,6 +228,7 @@ describe('CustomShowSyncService', () => { { uuid: dbUuid2, sourceType: 'plex', + externalSourceId: mediaSourceId, mediaSourceId: mediaSourceId, externalKey: movie2.externalId, externalIds: [], @@ -357,6 +359,7 @@ describe('CustomShowSyncService', () => { [ep1, ep2, ep3].map((ep) => ({ uuid: ep.uuid, sourceType: 'plex', + externalSourceId: mediaSourceId, mediaSourceId: mediaSourceId, externalKey: ep.externalId, externalIds: [], @@ -470,6 +473,7 @@ describe('CustomShowSyncService', () => { { uuid: dbUuid2, sourceType: 'plex', + externalSourceId: mediaSourceId, mediaSourceId: mediaSourceId, externalKey: movie2.externalId, externalIds: [], diff --git a/server/src/services/XmlTvWriter.test.ts b/server/src/services/XmlTvWriter.test.ts index 6861d836b..1a608d55b 100644 --- a/server/src/services/XmlTvWriter.test.ts +++ b/server/src/services/XmlTvWriter.test.ts @@ -5,6 +5,7 @@ import type { ProgramWithRelationsOrm } from '../db/schema/derivedTypes.ts'; import { createChannel, createFakeProgram, + createFakeShow, } from '../testing/fakes/entityCreators.ts'; import { inMemorySettingsDB, @@ -88,7 +89,10 @@ describe('XmlTvWriter', () => { program: { ...createFakeProgram({ summary: `The family's trip to Itchy & Scratchy Land takes an unexpected turn when high-tech robots malfunction and become violent.`, + type: 'episode', }), + seasonNumber: 6, + episode: 4, genres: [ { genre: { uuid: v4(), name: 'Comedy' }, @@ -103,6 +107,61 @@ describe('XmlTvWriter', () => { programId: '', }, ], + tags: [ + { + tag: { uuid: v4(), tag: 'Theme Park' }, + tagId: v4(), + programId: null, + source: 'media', + groupingId: null, + }, + { + tag: { uuid: v4(), tag: 'Itchy & Scratchy' }, + tagId: v4(), + programId: null, + source: 'media', + groupingId: null, + }, + ], + show: { + ...createFakeShow({ + genres: [ + { + genre: { uuid: v4(), name: 'Comedy' }, + genreId: '', + groupId: '', + programId: '', + }, + { + genre: { uuid: v4(), name: 'Animated' }, + genreId: '', + groupId: '', + programId: '', + }, + { + genre: { uuid: v4(), name: 'Long-Running' }, + genreId: '', + groupId: '', + programId: '', + }, + { + genre: { uuid: v4(), name: '< 30 min' }, + genreId: '', + groupId: '', + programId: '', + }, + ], + tags: [ + { + tag: { uuid: v4(), tag: 'Dysfunctional Family' }, + tagId: v4(), + programId: null, + source: 'media', + groupingId: null, + }, + ], + }), + }, }, }, }, @@ -116,14 +175,104 @@ describe('XmlTvWriter', () => { expect(output.programmes[0]?.desc?.[0]?._value).includes('&'); }); - test('adds genres', () => { + test('adds and escapes genres as categories', () => { const writer = new XmlTvWriter(inMemorySettingsDB()); const output = writer.generateXmltv(channels); expect(output.programmes[0]?.category?.map((c) => c._value)).toEqual([ 'Comedy', 'Animated', + 'Long-Running', + '< 30 min', + ]); + }); + + test('adds and escapes tags as keywords', () => { + const writer = new XmlTvWriter(inMemorySettingsDB()); + const output = writer.generateXmltv(channels); + expect(output.programmes[0]?.keyword?.map((c) => c._value)).toEqual([ + 'Theme Park', + 'Itchy & Scratchy', + 'Dysfunctional Family', ]); }); + + test('zero-pads single digit onscreen season and episode numbers', () => { + const writer = new XmlTvWriter(inMemorySettingsDB()); + const output = writer.generateXmltv(channels); + const onscreenEpisodeNum = output.programmes[0]?.episodeNum?.find( + (e) => e.system === 'onscreen', + ); + expect(onscreenEpisodeNum?._value).toBe('S06E04'); + }); + + test('generates xmltv_ns format with 0-based indices', () => { + const writer = new XmlTvWriter(inMemorySettingsDB()); + const output = writer.generateXmltv(channels); + const xmltvNs = output.programmes[0]?.episodeNum?.find( + (e) => e.system === 'xmltv_ns', + ); + expect(xmltvNs?._value).toBe('5.3.'); + }); + + test('handles double digit season and episode numbers', () => { + const writer = new XmlTvWriter(inMemorySettingsDB()); + const channels: MaterializedChannelPrograms[] = [ + { + channel: createChannel(), + programs: [ + { + programming: { + type: 'program', + program: { + ...createFakeProgram({ + type: 'episode', + seasonNumber: 12, + episode: 25, + }), + }, + }, + title: 'Test Episode', + }, + ], + }, + ]; + + const output = writer.generateXmltv(channels); + const onscreenEpisodeNum = output.programmes[0]?.episodeNum?.find( + (e) => e.system === 'onscreen', + ); + expect(onscreenEpisodeNum?._value).toBe('S12E25'); + }); + + test('omits season number for season 0 (specials) in xmltv_ns', () => { + const writer = new XmlTvWriter(inMemorySettingsDB()); + const channels: MaterializedChannelPrograms[] = [ + { + channel: createChannel(), + programs: [ + { + programming: { + type: 'program', + program: { + ...createFakeProgram({ + type: 'episode', + seasonNumber: 0, + episode: 1, + }), + }, + }, + title: 'Test Special', + }, + ], + }, + ]; + + const output = writer.generateXmltv(channels); + const xmltvNs = output.programmes[0]?.episodeNum?.find( + (e) => e.system === 'xmltv_ns', + ); + expect(xmltvNs?._value).toBe('.0.'); + }); }); describe('resolveArtworkUrl', () => { @@ -450,4 +599,148 @@ describe('XmlTvWriter', () => { }); }); }); + + describe('credits', () => { + test('maps cast type to actor credits', () => { + const writer = new XmlTvWriter(inMemorySettingsDB()); + const channels: MaterializedChannelPrograms[] = [ + { + channel: createChannel(), + programs: [ + { + programming: { + type: 'program', + program: { + ...createFakeProgram({ + type: 'movie', + credits: [ + { + uuid: v4(), + name: 'Alan Smithee', + type: 'cast', + role: 'Himself', + artwork: [], + }, + ], + }), + }, + }, + start: Date.now(), + stop: Date.now() + 3600000, + title: 'See You Next Wednesday', + }, + ], + }, + ]; + + const output = writer.generateXmltv(channels); + const credits = output.programmes[0]?.credits; + expect(credits?.actor).toBeDefined(); + expect(credits?.actor?.[0]?._value).toBe('Alan Smithee'); + expect(credits?.actor?.[0]?.role).toBe('Himself'); + }); + + test('maps director, writer, and producer credits correctly', () => { + const writer = new XmlTvWriter(inMemorySettingsDB()); + const channels: MaterializedChannelPrograms[] = [ + { + channel: createChannel(), + programs: [ + { + programming: { + type: 'program', + program: { + ...createFakeProgram({ + type: 'movie', + credits: [ + { + uuid: v4(), + name: 'Alan Smithee', + type: 'director', + }, + { + uuid: v4(), + name: 'Cordwainer Bird', + type: 'writer', + }, + { + uuid: v4(), + name: 'John Doe', + type: 'producer', + }, + ], + }), + }, + }, + start: Date.now(), + stop: Date.now() + 3600000, + title: 'See You Next Wednesday', + }, + ], + }, + ]; + + const output = writer.generateXmltv(channels); + const credits = output.programmes[0]?.credits; + expect(credits?.director?.[0]?._value).toBe('Alan Smithee'); + expect(credits?.writer?.[0]?._value).toBe('Cordwainer Bird'); + expect(credits?.producer?.[0]?._value).toBe('John Doe'); + }); + }); + + describe('duration and metadata', () => { + test('omits length when duration is zero or negative', () => { + const writer = new XmlTvWriter(inMemorySettingsDB()); + const channels: MaterializedChannelPrograms[] = [ + { + channel: createChannel(), + programs: [ + { + programming: { + type: 'program', + program: { + ...createFakeProgram({ + duration: 0, + }), + }, + }, + start: Date.now(), + stop: Date.now() + 3600000, + title: 'Test', + }, + ], + }, + ]; + + const output = writer.generateXmltv(channels); + expect(output.programmes[0]?.length).toBeUndefined(); + }); + + test('adds video present: false for tracks', () => { + const writer = new XmlTvWriter(inMemorySettingsDB()); + const channels: MaterializedChannelPrograms[] = [ + { + channel: createChannel(), + programs: [ + { + programming: { + type: 'program', + program: { + ...createFakeProgram({ + type: 'track', + }), + }, + }, + start: Date.now(), + stop: Date.now() + 3600000, + title: 'Test Track', + }, + ], + }, + ]; + + const output = writer.generateXmltv(channels); + expect(output.programmes[0]?.video?.present).toBe(false); + }); + }); }); diff --git a/server/src/services/XmlTvWriter.ts b/server/src/services/XmlTvWriter.ts index e290074f3..7265df54b 100644 --- a/server/src/services/XmlTvWriter.ts +++ b/server/src/services/XmlTvWriter.ts @@ -2,13 +2,15 @@ import { SettingsDB } from '@/db/SettingsDB.js'; import { ChannelOrm } from '@/db/schema/Channel.js'; import { KEYS } from '@/types/inject.js'; import { getChannelId } from '@/util/channels.js'; -import { firstDefined, groupByFunc, isNonEmptyString } from '@/util/index.js'; import { resolveIconUrl } from '@/util/iconUtil.js'; +import { firstDefined, groupByFunc, isNonEmptyString } from '@/util/index.js'; import { LoggerFactory } from '@/util/logging/LoggerFactory.js'; import { writeXmltv, Xmltv, type XmltvChannel, + type XmltvCreditImage, + type XmltvPerson, type XmltvProgramme, } from '@iptv/xmltv'; import { Mutex } from 'async-mutex'; @@ -65,6 +67,10 @@ export class XmlTvWriter { ); return { generatorInfoName: 'tunarr', + generatorInfoUrl: 'https://tunarr.com', + sourceInfoName: 'tunarr', + sourceInfoUrl: `{{host}}/web`, + sourceDataUrl: `{{host}}/api/xmltv.xml`, date: new Date(), channels: map(channels, ({ channel }) => this.makeXmlTvChannel(channel, xmlChannelIdById[channel.uuid]!), @@ -151,6 +157,10 @@ export class XmlTvWriter { ({ program }) => `${program.album?.title ? `${program.album.title} - ` : ''}${program.title}`, ) + .with( + { type: 'program', program: { type: 'movie' } }, + ({ program }) => program.tagline, + ) // .with( // { type: 'custom', program: { subtype: P.union('track', 'episode') } }, // (p) => p.program?.title, @@ -161,7 +171,6 @@ export class XmlTvWriter { start: new Date(guideItem.start), stop: new Date(guideItem.stop), title: [{ _value: escape(title) }], - previouslyShown: {}, channel: xmlChannelId, }; @@ -191,12 +200,60 @@ export class XmlTvWriter { ]; } + const credits = program.credits?.length + ? program.credits + : program.show?.credits; + + for (const credit of credits ?? []) { + partial.credits ??= {}; + let xmlCreditList: XmltvPerson[] | undefined; + switch (credit.type) { + case 'cast': + xmlCreditList = partial.credits.actor ??= []; + break; + case 'director': + xmlCreditList = partial.credits.director ??= []; + break; + case 'writer': + xmlCreditList = partial.credits.writer ??= []; + break; + case 'producer': + xmlCreditList = partial.credits.producer ??= []; + break; + } + + xmlCreditList.push({ + _value: escape(credit.name), + ...(credit.role?.length && { role: credit.role }), + ...(this.settingsDB.featureFlags().xmltvCreditImagesEnabled && + credit.artwork?.length && { + image: credit.artwork.map( + (a) => + ({ + _value: `{{host}}/api/credits/${credit.uuid}/artwork/${a.artworkType}`, + type: 'person', + }) as XmltvCreditImage, + ), + }), + } as XmltvPerson); + } + + if (program.duration > 0) { + // length only supports seconds minutes or hours so convert duration from ms to seconds + partial.length = { _value: program.duration * 0.001, units: 'seconds' }; + } + const rating = firstDefined(program.rating, program.show?.rating); if (rating) { partial.rating ??= [ { - system: 'MPAA', - value: rating, + system: + program.type === 'movie' + ? 'MPAA' + : program.type === 'track' + ? 'RIAA' + : 'VCHIP', + value: escape(rating), }, ]; } @@ -212,13 +269,28 @@ export class XmlTvWriter { } } - partial.category = []; - for (const { genre } of program.genres ?? []) { - partial.category.push({ - _value: genre.name, - }); + const genres = [ + ...(program.genres ?? []), + ...(program.show?.genres ?? []), + ]; + const uniqueCategories: Set = new Set(); + for (const { genre } of genres ?? []) { + uniqueCategories.add(genre.name); } + partial.category = Array.from(uniqueCategories).map((c) => ({ + _value: escape(c), + })); + + const tags = [...(program.tags ?? []), ...(program.show?.tags ?? [])]; + const uniqueKeywords: Set = new Set(); + for (const { tag } of tags ?? []) { + uniqueKeywords.add(tag.tag); + } + partial.keyword = Array.from(uniqueKeywords).map((k) => ({ + _value: escape(k), + })); + const [seasonNumber, episodeNumber] = match(program) .with({ type: 'episode' }, (ep) => { return [ep.season?.index ?? ep.seasonNumber, ep.episode]; @@ -226,21 +298,32 @@ export class XmlTvWriter { .with({ type: 'track' }, (track) => [track.album?.index, track.episode]) .otherwise(() => [null, null]); - if (!isNil(seasonNumber) && !isNil(episodeNumber)) { + partial.episodeNum = []; + if (!isNil(episodeNumber)) { + const seasonString = isNil(seasonNumber) + ? '' + : `S${seasonNumber.toString().padStart(2, '0')}`; partial.episodeNum = [ { system: 'onscreen', - _value: `S${seasonNumber}E${episodeNumber}`, + _value: `${seasonString}E${episodeNumber.toString().padStart(2, '0')}`, }, ]; - // Simply drop the xmltv notation system for specials (seasonn == 0) - // or for any epipsode number that would lead to invalid syntax - if (seasonNumber > 0 && episodeNumber > 0) { - partial.episodeNum.push({ - system: 'xmltv_ns', - _value: `${seasonNumber - 1}.${episodeNumber - 1}.0/1`, - }); - } + } + + // xmltv_ns string is of the format SeasonIndex.EpisodeIndex.PartIndex/PartCount + // where indexes are 0-based and each portion is optional if unknown + // we don't have part information right now so we always omit it + // we also omit the season number for season 0 as that is used for specials which don't have a valid representation in this format + if (episodeNumber || seasonNumber) { + partial.episodeNum.push({ + system: 'xmltv_ns', + _value: `${seasonNumber ? seasonNumber - 1 : ''}.${episodeNumber ? episodeNumber - 1 : ''}.`, + }); + } + + if (program.type === 'track') { + partial.video = { present: false }; } const useShowPoster = @@ -250,7 +333,7 @@ export class XmlTvWriter { }); if (url) { - partial.image = [{ _value: url, size: 3 }]; + partial.image = [{ _value: url, size: 3, type: 'poster' }]; partial.icon = [{ src: url }]; } } diff --git a/server/src/services/scanner/FileSystemScanner.ts b/server/src/services/scanner/FileSystemScanner.ts index c3fdac1da..12df8b8a2 100644 --- a/server/src/services/scanner/FileSystemScanner.ts +++ b/server/src/services/scanner/FileSystemScanner.ts @@ -65,7 +65,7 @@ export abstract class FileSystemScanner { protected state: RunState = 'starting'; private mediaSourceId: Maybe; - @InjectLogger() protected declare readonly logger: Logger; + @InjectLogger() declare protected readonly logger: Logger; constructor( protected ffprobeStreamDetails: FfprobeStreamDetails, @@ -145,17 +145,23 @@ export abstract class FileSystemScanner { ); } - protected async getMediaItem(filePath: string): Promise> { + protected async getMediaItem( + filePath: string, + ): Promise< + Result<{ mediaItem: MediaItem; formatTags?: Record }> + > { try { - const streamDetails = await this.ffprobeStreamDetails.getStream({ + const streamDetailsResult = await this.ffprobeStreamDetails.getStream({ path: filePath, }); - if (streamDetails.isFailure()) { - return streamDetails.recast(); + if (streamDetailsResult.isFailure()) { + return streamDetailsResult.recast(); } - const videoStreams = streamDetails.get().streamDetails.videoDetails; + const streamDetails = streamDetailsResult.get(); + + const videoStreams = streamDetails.streamDetails.videoDetails; const streams: MediaStream[] = []; if (videoStreams) { for (const probeVideoStream of videoStreams) { @@ -179,8 +185,8 @@ export abstract class FileSystemScanner { } } - for (const audioStream of streamDetails.get().streamDetails - .audioDetails ?? []) { + for (const audioStream of streamDetails.streamDetails.audioDetails ?? + []) { const stream: MediaStream = { ...audioStream, // uuid: v4(), @@ -200,7 +206,7 @@ export abstract class FileSystemScanner { streams.push(stream); } - for (const subtitleStream of streamDetails.get().streamDetails + for (const subtitleStream of streamDetails.streamDetails .subtitleDetails ?? []) { const stream: MediaStream = { ...subtitleStream, @@ -227,13 +233,13 @@ export abstract class FileSystemScanner { const firstVideoStream = head( orderBy( - streamDetails.get().streamDetails.videoDetails, + streamDetails.streamDetails.videoDetails, (v, i) => (v.streamIndex ?? 0) + i, 'asc', ), ); - const chapters = streamDetails.get().streamDetails.chapters; + const chapters = streamDetails.streamDetails.chapters; const mediaItem: MediaItem = { // createdAt: statResult.ctime, @@ -241,7 +247,7 @@ export abstract class FileSystemScanner { chapters, displayAspectRatio: firstVideoStream?.displayAspectRatio, sampleAspectRatio: firstVideoStream?.sampleAspectRatio, - duration: +streamDetails.get().streamDetails.duration, + duration: +streamDetails.streamDetails.duration, frameRate: firstVideoStream?.framerate, resolution: isDefined(firstVideoStream?.height) && @@ -261,7 +267,10 @@ export abstract class FileSystemScanner { ], }; - return Result.success(mediaItem); + return Result.success({ + mediaItem, + formatTags: streamDetails.streamDetails.formatTags, + }); } catch (e) { return Result.forError(caughtErrorToError(e)); } diff --git a/server/src/services/scanner/LocalMovieScanner.ts b/server/src/services/scanner/LocalMovieScanner.ts index d6e19f6bf..410410dd6 100644 --- a/server/src/services/scanner/LocalMovieScanner.ts +++ b/server/src/services/scanner/LocalMovieScanner.ts @@ -307,6 +307,8 @@ export class LocalMovieScanner extends FileSystemScanner { return mediaItemResult.mapPure(() => void 0); } + const { mediaItem } = mediaItemResult.get(); + const metadataResult = await this.loadMovieMetadata(fullVideoFilePath); if (metadataResult.isFailure()) { return metadataResult.recast(); @@ -339,8 +341,8 @@ export class LocalMovieScanner extends FileSystemScanner { ...metadataResult.get(), mediaSourceId: context.mediaSource.uuid, libraryId: context.library.uuid, - duration: mediaItemResult.get().duration, - mediaItem: mediaItemResult.get(), + duration: mediaItem.duration, + mediaItem, externalId: fullVideoFilePath, canonicalId: '', externalSubtitles: subtitlesResult.getOrElse([]), diff --git a/server/src/services/scanner/LocalMusicScanner.ts b/server/src/services/scanner/LocalMusicScanner.ts index 31fe0b209..1e0b12bd9 100644 --- a/server/src/services/scanner/LocalMusicScanner.ts +++ b/server/src/services/scanner/LocalMusicScanner.ts @@ -528,7 +528,7 @@ export class LocalMusicScanner extends FileSystemScanner { trackDirent: Dirent, ): Promise> { const trackPath = path.join(trackDirent.parentPath, trackDirent.name); - const fileDetails = (await this.getMediaItem(trackPath)).getOrThrow(); + const { mediaItem: fileDetails } = (await this.getMediaItem(trackPath)).getOrThrow(); const parsedTrackMetadataResult = await Result.attemptAsync(() => parseFile(trackPath, { skipCovers: true, diff --git a/server/src/services/scanner/LocalMusicVideoScanner.ts b/server/src/services/scanner/LocalMusicVideoScanner.ts index bc0e1e0ea..fac09bbb8 100644 --- a/server/src/services/scanner/LocalMusicVideoScanner.ts +++ b/server/src/services/scanner/LocalMusicVideoScanner.ts @@ -318,13 +318,13 @@ export class LocalMusicVideoScanner extends FileSystemScanner { await wait(); - const mediaItem = (await this.getMediaItem(fullFilePath)).getOrThrow(); + const { mediaItem, formatTags } = (await this.getMediaItem(fullFilePath)).getOrThrow(); if (isNil(mediaItem.duration)) { throw new Error(`Could not derive duration for item: ${fullFilePath}`); } - const metadata = (await this.loadVideoMetadata(fullFilePath)).getOrThrow(); + const metadata = (await this.loadVideoMetadata(fullFilePath, formatTags)).getOrThrow(); metadata.tags.push(file.parentPath); @@ -380,16 +380,24 @@ export class LocalMusicVideoScanner extends FileSystemScanner { private async loadVideoMetadata( fullVideoFilePath: string, + formatTags?: Record, ): Promise> { + const probeMeta = this.extractMetadataFromFormatTags(formatTags); const nfoPath = await this.findNfoFile(fullVideoFilePath); + if (!isNonEmptyString(nfoPath)) { - return Result.attemptAsync(() => - Promise.resolve( - this.fallbackMetadataService.getMusicVideoFallbackMetadata( - fullVideoFilePath, - ), - ), - ); + const fallback = + this.fallbackMetadataService.getMusicVideoFallbackMetadata( + fullVideoFilePath, + ); + return Result.success({ + ...fallback, + title: probeMeta.title ?? fallback.title, + sortTitle: titleToSortTitle(probeMeta.title ?? fallback.title), + artistName: probeMeta.artistName ?? null, + albumName: probeMeta.albumName ?? null, + year: probeMeta.year ?? fallback.year, + }); } const parseResult = await this.nfoParser.parse( @@ -400,11 +408,59 @@ export class LocalMusicVideoScanner extends FileSystemScanner { return parseResult.recast(); } - const parsed = parseResult.get(); + const nfoMetadata = this.nfoToMusicVideo(parseResult.get().musicvideo); - return Result.attemptAsync(() => - Promise.resolve(this.nfoToMusicVideo(parsed.musicvideo)), - ); + return Result.success({ + ...nfoMetadata, + artistName: nfoMetadata.artistName ?? probeMeta.artistName ?? null, + albumName: nfoMetadata.albumName ?? probeMeta.albumName ?? null, + year: nfoMetadata.year ?? probeMeta.year ?? null, + }); + } + + private extractMetadataFromFormatTags( + formatTags?: Record, + ): { + title?: string; + artistName?: string; + albumName?: string; + year?: number; + } { + if (formatTags === undefined) { + return {}; + } + + const getTag = (...keys: string[]): string | undefined => { + for (const key of keys) { + const val = + formatTags[key] ?? + formatTags[key.toLowerCase()] ?? + formatTags[key.toUpperCase()]; + if (val !== undefined) return val; + } + return undefined; + }; + + let year: number | undefined; + const dateStr = getTag('date', 'DATE', 'year', 'YEAR'); + if (dateStr !== undefined) { + const parsed = parseInt(dateStr, 10); + if (!isNaN(parsed) && parsed > 0) { + year = parsed; + } + } + + return { + title: getTag('title', 'TITLE'), + artistName: getTag( + 'artist', + 'ARTIST', + 'album_artist', + 'ALBUM_ARTIST', + ), + albumName: getTag('album', 'ALBUM'), + year, + }; } private async findNfoFile(videoPath: string) { @@ -440,6 +496,8 @@ export class LocalMusicVideoScanner extends FileSystemScanner { year: releaseDate?.year() ?? null, actors: [], tags: nfo.tag ?? [], + artistName: nfo.artist?.join(', ') ?? null, + albumName: nfo.album ?? null, type: 'music_video', directors, studios: nfo.studio ? [{ name: nfo.studio }] : [], diff --git a/server/src/services/scanner/LocalOtherVideoScanner.ts b/server/src/services/scanner/LocalOtherVideoScanner.ts index 843d1c0e2..747e78312 100644 --- a/server/src/services/scanner/LocalOtherVideoScanner.ts +++ b/server/src/services/scanner/LocalOtherVideoScanner.ts @@ -323,7 +323,7 @@ export class LocalOtherVideoScanner extends FileSystemScanner { await wait(); - const mediaItem = (await this.getMediaItem(fullFilePath)).getOrThrow(); + const { mediaItem } = (await this.getMediaItem(fullFilePath)).getOrThrow(); if (isNil(mediaItem.duration)) { throw new Error(`Could not derive duration for item: ${fullFilePath}`); diff --git a/server/src/services/scanner/LocalTvShowScanner.ts b/server/src/services/scanner/LocalTvShowScanner.ts index 76e032ee4..187151259 100644 --- a/server/src/services/scanner/LocalTvShowScanner.ts +++ b/server/src/services/scanner/LocalTvShowScanner.ts @@ -615,7 +615,7 @@ export class LocalTvShowScanner extends FileSystemScanner { episodeDirent.name, ); - const mediaItem = (await this.getMediaItem(fullEpisodePath)).getOrThrow(); + const { mediaItem } = (await this.getMediaItem(fullEpisodePath)).getOrThrow(); if (isNil(mediaItem.duration)) { throw new Error(`Could not derive duration for item: ${fullEpisodePath}`); diff --git a/server/src/stream/FfprobeStreamDetails.ts b/server/src/stream/FfprobeStreamDetails.ts index a337419a8..cbad92dd5 100644 --- a/server/src/stream/FfprobeStreamDetails.ts +++ b/server/src/stream/FfprobeStreamDetails.ts @@ -155,6 +155,7 @@ export class FfprobeStreamDetails ? subtitleStreamDetails : undefined, duration: dayjs.duration({ seconds: probeDetails.format.duration }), + formatTags: probeDetails.format.tags, chapters: seq.collect( orderBy(probeDetails.chapters, (c) => c.start, 'asc'), (chapter, index) => { diff --git a/server/src/stream/ProgramStream.ts b/server/src/stream/ProgramStream.ts index 38469649b..90f9eabdd 100644 --- a/server/src/stream/ProgramStream.ts +++ b/server/src/stream/ProgramStream.ts @@ -23,7 +23,7 @@ import { MediaSourceDB } from '../db/mediaSourceDB.ts'; import type { FFmpegAssistedFactory } from '../ffmpeg/FFmpegModule.ts'; import type { StreamOptions } from '../ffmpeg/types.ts'; import { KEYS } from '../types/inject.ts'; -import { assisted, injected } from '../util/assistedInject.ts'; +import { assisted, injected, multiInjected } from '../util/assistedInject.ts'; import { attempt, isDefined, @@ -33,6 +33,7 @@ import { import { InjectLogger } from '../util/inject.ts'; import type { PlayerContext } from './PlayerStreamContext.ts'; import { ProgramStreamDetailsFetcher } from './ProgramStreamDetailsFetcher.ts'; +import { ProgramStreamPlugin } from './plugins/ProgramStreamPlugin.ts'; import type { StreamRenditions } from './types.ts'; type ProgramStreamEvents = { @@ -61,6 +62,8 @@ export class ProgramStream extends events.EventEmitter { @injected(MediaSourceDB) private mediaSourceDB: MediaSourceDB, @injected(ProgramStreamDetailsFetcher) private programStreamDetails: ProgramStreamDetailsFetcher, + @multiInjected(KEYS.ProgramStreamPlugin) + private streamPlugins: ProgramStreamPlugin[], @assisted public context: PlayerContext, @assisted protected outputFormat: OutputFormat, @assisted public opts?: Partial, @@ -134,21 +137,22 @@ export class ProgramStream extends events.EventEmitter { streamDetails.duration = dayjs.duration(lineupItem.streamDuration); const start = dayjs.duration(lineupItem.startOffset ?? 0); + const resolvedOptions = { + startTime: start, + duration: dayjs.duration(lineupItem.streamDuration), + watermark, + realtime: this.context.realtime, + outputFormat: this.outputFormat, + streamMode: this.context.streamMode, + encoding: this.context.encoding, + ...(this.opts ?? {}), + }; const sessionResult = await ffmpeg.createStreamSession({ stream: { source: streamSource, details: streamDetails, }, - options: { - startTime: start, - duration: dayjs.duration(lineupItem.streamDuration), - watermark, - realtime: this.context.realtime, - outputFormat: this.outputFormat, - streamMode: this.context.streamMode, - encoding: this.context.encoding, - ...(this.opts ?? {}), - }, + options: resolvedOptions, lineupItem, }); @@ -156,7 +160,22 @@ export class ProgramStream extends events.EventEmitter { return Result.forError(new Error('Unable to create ffmpeg process')); } - // TODO: Fire plugins. + for (const plugin of this.streamPlugins) { + try { + await plugin.run({ + opts: resolvedOptions, + outputFormat: this.outputFormat, + playerContext: this.context, + transcodeSession: sessionResult, + }); + } catch (e) { + this.logger.error( + e, + 'Error firing stream plugin %s', + plugin.constructor.name, + ); + } + } return Result.success(sessionResult); } diff --git a/server/src/stream/ProgramStreamDetailsFetcher.ts b/server/src/stream/ProgramStreamDetailsFetcher.ts index 5235a6164..7fdc1d9a5 100644 --- a/server/src/stream/ProgramStreamDetailsFetcher.ts +++ b/server/src/stream/ProgramStreamDetailsFetcher.ts @@ -131,8 +131,7 @@ export class ProgramStreamDetailsFetcher { const usableSubtitles = await Promise.all( (program.subtitles ?? []).map(async (subtitle) => { const pathOnDisk = - isNonEmptyString(subtitle.path) && - (await fileExists(subtitle.path)); + isNonEmptyString(subtitle.path) && (await fileExists(subtitle.path)); if (subtitle.subtitleType === 'sidecar') { return pathOnDisk ? subtitle : null; } @@ -159,8 +158,7 @@ export class ProgramStreamDetailsFetcher { return { ...subtitle, index: nullToUndefined(subtitle.streamIndex), - type: - subtitle.subtitleType === 'embedded' ? 'embedded' : 'external', + type: subtitle.subtitleType === 'embedded' ? 'embedded' : 'external', languageCodeISO6392: subtitle.language, sdh: subtitle.sdh, path: nullToUndefined(subtitle.path), diff --git a/server/src/stream/StreamModule.ts b/server/src/stream/StreamModule.ts index 1a955ea8d..fe2b405f4 100644 --- a/server/src/stream/StreamModule.ts +++ b/server/src/stream/StreamModule.ts @@ -22,6 +22,8 @@ import { bindAutoFactory } from '../util/inject.ts'; import { ProgramStream } from './ProgramStream.ts'; import { ProgramStreamDetailsFetcher } from './ProgramStreamDetailsFetcher.ts'; import type { ProgramStreamFactory } from './ProgramStreamFactory.ts'; +import { JellyfinPlayStatusUpdaterPlugin } from './plugins/JellyfinPlayStatusUpdaterPlugin.ts'; +import { PlexPlayStatusUpdaterPlugin } from './plugins/PlexPlayStatusUpdaterPlugin.ts'; const configure = ({ bind }: ContainerModuleLoadOptions) => { bind(SessionManager).toSelf().inSingletonScope(); @@ -85,6 +87,9 @@ const configure = ({ bind }: ContainerModuleLoadOptions) => { }); bind(KEYS.FillerPicker).to(FillerPickerV2).inSingletonScope(); + + bind(KEYS.ProgramStreamPlugin).to(PlexPlayStatusUpdaterPlugin); + bind(KEYS.ProgramStreamPlugin).to(JellyfinPlayStatusUpdaterPlugin); }; class StreamModule extends ContainerModule { diff --git a/server/src/stream/plugins/JellyfinPlayStatusUpdaterPlugin.ts b/server/src/stream/plugins/JellyfinPlayStatusUpdaterPlugin.ts new file mode 100644 index 000000000..bdc865325 --- /dev/null +++ b/server/src/stream/plugins/JellyfinPlayStatusUpdaterPlugin.ts @@ -0,0 +1,72 @@ +import { inject, injectable } from 'inversify'; +import { v4 } from 'uuid'; +import { isContentBackedLineupItem } from '../../db/derived_types/StreamLineup.ts'; +import { MediaSourceDB } from '../../db/mediaSourceDB.ts'; +import { + UpdateJellyfinPlayStatusScheduledTask, + UpdateJellyfinPlayStatusScheduledTaskFactory, +} from '../../tasks/jellyfin/UpdateJellyfinPlayStatusTask.ts'; +import { Result } from '../../types/result.ts'; +import { Maybe } from '../../types/util.ts'; +import { InjectLogger } from '../../util/inject.ts'; +import { Logger } from '../../util/logging/LoggerFactory.ts'; +import { PluginContext, ProgramStreamPlugin } from './ProgramStreamPlugin.ts'; + +@injectable() +export class JellyfinPlayStatusUpdaterPlugin implements ProgramStreamPlugin { + @InjectLogger() declare private readonly logger: Logger; + + private updateStatusTask: Maybe; + + constructor( + @inject(UpdateJellyfinPlayStatusScheduledTask.KEY) + private playStatusTaskFactory: UpdateJellyfinPlayStatusScheduledTaskFactory, + @inject(MediaSourceDB) private mediaSourceDB: MediaSourceDB, + ) {} + + async run(context: PluginContext): Promise> { + const lineupItem = context.playerContext.lineupItem; + if (!isContentBackedLineupItem(lineupItem)) { + return Result.void(); + } + + if (lineupItem.program.sourceType !== 'plex') { + return Result.void(); + } + + const server = await this.mediaSourceDB.getById( + lineupItem.program.mediaSourceId, + ); + + if (!server) { + return Result.forError( + new Error( + `Unable to find server "${lineupItem.program.mediaSourceId}" specified by program.`, + ), + ); + } + + if (!server.sendPlayStatusUpdates) { + return Result.void(); + } + + this.updateStatusTask = this.playStatusTaskFactory( + server, + { + channelNumber: context.playerContext.sourceChannel.number, + first: true, + itemDuration: lineupItem.duration, + itemId: lineupItem.program.externalKey, + itemStartPositionMs: lineupItem.startOffset ?? 0, + }, + v4(), + ); + + return Result.void(); + } + + shutdown(): Promise> { + this.updateStatusTask?.stop(); + return Promise.resolve(Result.void()); + } +} diff --git a/server/src/stream/plugins/PlexPlayStatusUpdaterPlugin.ts b/server/src/stream/plugins/PlexPlayStatusUpdaterPlugin.ts new file mode 100644 index 000000000..c8e52a3c3 --- /dev/null +++ b/server/src/stream/plugins/PlexPlayStatusUpdaterPlugin.ts @@ -0,0 +1,71 @@ +import { inject, injectable } from 'inversify'; +import { v4 } from 'uuid'; +import { isContentBackedLineupItem } from '../../db/derived_types/StreamLineup.ts'; +import { MediaSourceDB } from '../../db/mediaSourceDB.ts'; +import { + UpdatePlexPlayStatusScheduledTask, + UpdatePlexPlayStatusScheduledTaskFactory, +} from '../../tasks/plex/UpdatePlexPlayStatusTask.ts'; +import { Result } from '../../types/result.ts'; +import { Maybe } from '../../types/util.ts'; +import { InjectLogger } from '../../util/inject.ts'; +import { Logger } from '../../util/logging/LoggerFactory.ts'; +import { PluginContext, ProgramStreamPlugin } from './ProgramStreamPlugin.ts'; + +@injectable() +export class PlexPlayStatusUpdaterPlugin implements ProgramStreamPlugin { + @InjectLogger() declare private readonly logger: Logger; + + private updatePlexStatusTask: Maybe; + + constructor( + @inject(UpdatePlexPlayStatusScheduledTask.KEY) + private playStatusTaskFactory: UpdatePlexPlayStatusScheduledTaskFactory, + @inject(MediaSourceDB) private mediaSourceDB: MediaSourceDB, + ) {} + + async run(context: PluginContext): Promise> { + const lineupItem = context.playerContext.lineupItem; + if (!isContentBackedLineupItem(lineupItem)) { + return Result.void(); + } + + if (lineupItem.program.sourceType !== 'plex') { + return Result.void(); + } + + const server = await this.mediaSourceDB.getById( + lineupItem.program.mediaSourceId, + ); + + if (!server) { + return Result.forError( + new Error( + `Unable to find server "${lineupItem.program.mediaSourceId}" specified by program.`, + ), + ); + } + + if (!server.sendPlayStatusUpdates) { + return Result.void(); + } + + this.updatePlexStatusTask = this.playStatusTaskFactory( + server, + { + channelNumber: context.playerContext.sourceChannel.number, + duration: lineupItem.duration, + ratingKey: lineupItem.program.externalKey, + startTime: lineupItem.startOffset ?? 0, + }, + v4(), + ); + + return Result.void(); + } + + shutdown(): Promise> { + this.updatePlexStatusTask?.stop(); + return Promise.resolve(Result.void()); + } +} diff --git a/server/src/stream/plugins/ProgramStreamPlugin.ts b/server/src/stream/plugins/ProgramStreamPlugin.ts new file mode 100644 index 000000000..a5f9a97f2 --- /dev/null +++ b/server/src/stream/plugins/ProgramStreamPlugin.ts @@ -0,0 +1,20 @@ +import type { OutputFormat } from '../../ffmpeg/builder/constants.ts'; +import type { + StreamOptions, + TranscodeSessionResult, +} from '../../ffmpeg/types.ts'; +import type { Result } from '../../types/result.ts'; +import type { PlayerContext } from '../PlayerStreamContext.ts'; + +export type PluginContext = { + playerContext: PlayerContext; + outputFormat: OutputFormat; + opts?: Partial; + transcodeSession: TranscodeSessionResult; +}; + +export interface ProgramStreamPlugin { + run(context: PluginContext): Promise>; + + shutdown(): Promise>; +} diff --git a/server/src/stream/types.ts b/server/src/stream/types.ts index 2275ca9e7..75fc6bfa4 100644 --- a/server/src/stream/types.ts +++ b/server/src/stream/types.ts @@ -18,6 +18,7 @@ export type StreamDetails = { serverPath?: string; directFilePath?: string; chapters?: MediaChapter[]; + formatTags?: Record; }; export type VideoStreamDetails = { diff --git a/server/src/tasks/SubtitleExtractorTask.ts b/server/src/tasks/SubtitleExtractorTask.ts index 0a3645e77..3be806665 100644 --- a/server/src/tasks/SubtitleExtractorTask.ts +++ b/server/src/tasks/SubtitleExtractorTask.ts @@ -332,7 +332,10 @@ export class SubtitleExtractorTask extends Task2< createReadStream(tmpPath), new Transform({ transform(chunk: Buffer, _encoding, cb) { - cb(null, chunk.filter((byte) => byte !== 0x00)); + cb( + null, + chunk.filter((byte) => byte !== 0x00), + ); }, }), createWriteStream(outPath), diff --git a/server/src/tasks/TasksModule.ts b/server/src/tasks/TasksModule.ts index 4a893d9f1..bb2806444 100644 --- a/server/src/tasks/TasksModule.ts +++ b/server/src/tasks/TasksModule.ts @@ -21,6 +21,11 @@ import { bindAutoFactory, bindFactoryFunc } from '../util/inject.ts'; import { LoggerFactory } from '../util/logging/LoggerFactory.ts'; import { BackupTask } from './BackupTask.ts'; import { ClearM3uCacheTask } from './ClearM3uCacheTask.ts'; +import type { + UpdateJellyfinPlayStatusScheduledTaskFactory} from './jellyfin/UpdateJellyfinPlayStatusTask.ts'; +import { + UpdateJellyfinPlayStatusScheduledTask +} from './jellyfin/UpdateJellyfinPlayStatusTask.ts'; import { NoopTask } from './NoopTask.ts'; import type { UpdatePlexPlayStatusScheduledTaskFactory, @@ -121,6 +126,21 @@ const TasksModule = new ContainerModule(({ bind }) => { ), ); + bindFactoryFunc< + UpdateJellyfinPlayStatusScheduledTask, + Parameters + >( + bind, + UpdateJellyfinPlayStatusScheduledTask.KEY, + (ctx) => (server, request, sessionId) => + new UpdateJellyfinPlayStatusScheduledTask( + server, + request, + ctx.get(MediaSourceApiFactory), + sessionId, + ), + ); + bind(SubtitleExtractorTask).toSelf(); bindAutoFactory( bind, diff --git a/server/src/tasks/fixers/BackfillProgramExternalIds.ts b/server/src/tasks/fixers/BackfillProgramExternalIds.ts index dd8dfb0f9..2dfb5594a 100644 --- a/server/src/tasks/fixers/BackfillProgramExternalIds.ts +++ b/server/src/tasks/fixers/BackfillProgramExternalIds.ts @@ -42,7 +42,7 @@ import Fixer from './fixer.ts'; @injectable() export class BackfillProgramExternalIds extends Fixer { private timer: Timer; - @InjectLogger() protected declare readonly logger: Logger; + @InjectLogger() declare protected readonly logger: Logger; constructor( @inject(MediaSourceApiFactory) @@ -179,7 +179,7 @@ export class BackfillProgramExternalIds extends Fixer { throw new Error('Plex server is not a saved media source'); } - const metadataResult = await plex.getItemMetadata(program.externalKey); + const metadataResult = await plex.getItemMetadataRaw(program.externalKey); if (metadataResult.isFailure()) { throw new Error( diff --git a/server/src/tasks/jellyfin/UpdateJellyfinPlayStatusTask.ts b/server/src/tasks/jellyfin/UpdateJellyfinPlayStatusTask.ts index a8638db8f..4cc1ac105 100644 --- a/server/src/tasks/jellyfin/UpdateJellyfinPlayStatusTask.ts +++ b/server/src/tasks/jellyfin/UpdateJellyfinPlayStatusTask.ts @@ -46,11 +46,19 @@ type UpdateJellyfinPlayStatusTaskInvocation = z.infer< typeof UpdateJellyfinPlayStatusTaskInvocation >; +export type UpdateJellyfinPlayStatusScheduledTaskFactory = ( + server: MediaSourceWithRelations, + request: UpdateJellyfinPlayStatusScheduleRequest, + sessionId: string, +) => UpdateJellyfinPlayStatusScheduledTask; + @injectable() export class UpdateJellyfinPlayStatusScheduledTask extends ScheduledTask< typeof UpdateJellyfinPlayStatusTaskInvocation, boolean > { + static KEY = Symbol.for(UpdateJellyfinPlayStatusScheduledTask.name); + private playState: PlayState = 'playing'; private first: boolean = true; private start = dayjs(); diff --git a/server/src/testing/fakes/entityCreators.ts b/server/src/testing/fakes/entityCreators.ts index 2a2fa6a19..92a811c48 100644 --- a/server/src/testing/fakes/entityCreators.ts +++ b/server/src/testing/fakes/entityCreators.ts @@ -8,12 +8,14 @@ import type { MinimalProgramExternalId } from '../../db/schema/ProgramExternalId import type { MediaSourceName } from '../../db/schema/base.js'; import { type MediaSourceId } from '../../db/schema/base.js'; import type { + ProgramGroupingOrmWithRelations, ProgramWithExternalIds, ProgramWithRelationsOrm, } from '../../db/schema/derivedTypes.js'; export function createChannel(overrides?: Partial): Channel { return { + number: 1, uuid: faker.string.uuid(), duration: faker.number.int({ min: 0 }), startTime: faker.date.past().getTime(), @@ -89,3 +91,23 @@ export function createFakeProgramOrm( ...(overrides ?? {}), } satisfies ProgramWithRelationsOrm; } + +export function createFakeShow( + overrides?: Partial, +): ProgramGroupingOrmWithRelations { + const uuid = faker.string.uuid(); + return { + uuid: uuid, + type: 'show', + icon: faker.image.url(), + index: 0, + createdAt: faker.date.past().getMilliseconds(), + updatedAt: null, + canonicalId: null, + plot: faker.lorem.sentences(), + summary: faker.lorem.sentences(), + externalKey: faker.string.alphanumeric(), + mediaSourceId: tag(faker.string.uuid()), + ...(overrides ?? {}), + } satisfies ProgramGroupingOrmWithRelations; +} diff --git a/server/src/types/fastify.d.ts b/server/src/types/fastify.d.ts index 0de0c807f..16123e656 100644 --- a/server/src/types/fastify.d.ts +++ b/server/src/types/fastify.d.ts @@ -20,5 +20,6 @@ declare module 'fastify' { interface FastifyContextConfig { logAtLevel?: LogLevels; disableRequestLogging?: boolean | 'only-errors'; + authRequired?: boolean; } } diff --git a/server/src/types/inject.ts b/server/src/types/inject.ts index e88957a72..fe6721710 100644 --- a/server/src/types/inject.ts +++ b/server/src/types/inject.ts @@ -32,6 +32,7 @@ const KEYS = { ConcatSession: Symbol.for('ConcatSession'), HlsSessionProvder: Symbol.for('HlsSessionProvider'), ProgramStreamFactory: Symbol.for('Factory'), + ProgramStreamPlugin: Symbol.for('ProgramStreamPlugin'), JellyfinStreamDetails: Symbol.for('JellyfinStreamDetails'), JellyfinStreamDetailsFactory: Symbol.for('JellyfinStreamDetailsFactory'), PlexStreamDetails: Symbol.for('PlexStreamDetails'), diff --git a/server/src/util/assistedInject.ts b/server/src/util/assistedInject.ts index 1245eeed9..2b281b670 100644 --- a/server/src/util/assistedInject.ts +++ b/server/src/util/assistedInject.ts @@ -2,18 +2,18 @@ import type { Bind, BindWhenOnFluentSyntax, Factory, - ServiceIdentifier} from 'inversify'; -import { - inject + ServiceIdentifier, } from 'inversify'; +import { inject, multiInject } from 'inversify'; import 'reflect-metadata'; const INJECT_META = Symbol('assistedInject:inject'); const ASSISTED_META = Symbol('assistedInject:assisted'); -// Our own @inject — stores tokens in our own metadata, not inversify's internals -export function injected(serviceId: ServiceIdentifier) { - const injectFn = inject(serviceId); +function commonInjectedWrapper( + serviceId: ServiceIdentifier, + decorator: MethodDecorator & ParameterDecorator & PropertyDecorator, +): ParameterDecorator { return ( target: object, propertyKey: string | symbol | undefined, @@ -26,10 +26,24 @@ export function injected(serviceId: ServiceIdentifier) { ) ?? new Map(); map.set(index, serviceId); Reflect.defineMetadata(INJECT_META, map, target); - injectFn(target, propertyKey, index); + decorator(target, propertyKey, index); }; } +// Our own @inject — stores tokens in our own metadata, not inversify's internals +export function injected(serviceId: ServiceIdentifier) { + const injectFn = inject(serviceId); + return commonInjectedWrapper(serviceId, injectFn); +} + +// Our own @inject — stores tokens in our own metadata, not inversify's internals +export function multiInjected( + serviceId: ServiceIdentifier, +) { + const injectFn = multiInject(serviceId); + return commonInjectedWrapper(serviceId, injectFn); +} + export function assisted( target: object, _: string | symbol | undefined, diff --git a/server/src/util/basicAuth.test.ts b/server/src/util/basicAuth.test.ts new file mode 100644 index 000000000..fbaf8aa97 --- /dev/null +++ b/server/src/util/basicAuth.test.ts @@ -0,0 +1,147 @@ +import type { FastifyReply, FastifyRequest } from 'fastify'; +import { describe, expect, test, vi } from 'vitest'; +import { + createTunarrBasicAuthHook, + safeEqual, + validateBasicAuth, +} from './basicAuth.ts'; + +function basicAuthHeader(username: string, password: string) { + return `Basic ${Buffer.from(`${username}:${password}`).toString('base64')}`; +} + +function createRequest( + authorization?: string, + authRequired?: boolean, +): FastifyRequest { + return { + headers: { + authorization, + }, + routeOptions: { + config: authRequired === undefined ? {} : { authRequired }, + }, + } as unknown as FastifyRequest; +} + +type MockReply = FastifyReply & { + header: ReturnType; + status: ReturnType; + send: ReturnType; +}; + +function createReply(): MockReply { + const reply = {} as MockReply; + + reply.header = vi.fn(() => reply); + reply.status = vi.fn(() => reply); + reply.send = vi.fn(() => reply); + + return reply; +} + +describe('basicAuth', () => { + describe('safeEqual', () => { + test('returns true for matching strings', () => { + expect(safeEqual('tunarr', 'tunarr')).toBe(true); + }); + + test('returns false for non-matching strings with different lengths', () => { + expect(safeEqual('tunarr', 'tunarr-password')).toBe(false); + }); + }); + + describe('validateBasicAuth', () => { + test('returns false when the authorization header is missing', () => { + expect(validateBasicAuth(undefined, 'user', 'pass')).toBe(false); + }); + + test('returns false when the authorization header is not basic auth', () => { + expect(validateBasicAuth('Bearer token', 'user', 'pass')).toBe(false); + }); + + test('returns false when the credentials are malformed', () => { + expect(validateBasicAuth('Basic bm9jb2xvbg==', 'user', 'pass')).toBe( + false, + ); + }); + + test('returns false when the credentials do not match', () => { + expect( + validateBasicAuth(basicAuthHeader('wrong', 'creds'), 'user', 'pass'), + ).toBe(false); + }); + + test('returns true when the credentials match', () => { + expect( + validateBasicAuth(basicAuthHeader('user', 'pass'), 'user', 'pass'), + ).toBe(true); + }); + }); + + describe('createTunarrBasicAuthHook', () => { + test('skips auth when route config marks authRequired false', () => { + const hook = createTunarrBasicAuthHook({ + username: 'user', + password: 'pass', + }); + const reply = createReply(); + const done = vi.fn(); + + hook(createRequest(undefined, false), reply, done); + + expect(done).toHaveBeenCalledOnce(); + expect(reply.status).not.toHaveBeenCalled(); + expect(reply.send).not.toHaveBeenCalled(); + }); + + test('rejects protected routes when credentials are missing', () => { + const hook = createTunarrBasicAuthHook({ + username: 'user', + password: 'pass', + }); + const reply = createReply(); + const done = vi.fn(); + + hook(createRequest(), reply, done); + + expect(done).not.toHaveBeenCalled(); + expect(reply.header).toHaveBeenCalledWith( + 'WWW-Authenticate', + 'Basic realm="Tunarr"', + ); + expect(reply.status).toHaveBeenCalledWith(401); + expect(reply.send).toHaveBeenCalledWith('Authentication required'); + }); + + test('rejects protected routes when credentials are invalid', () => { + const hook = createTunarrBasicAuthHook({ + username: 'user', + password: 'pass', + }); + const reply = createReply(); + const done = vi.fn(); + + hook(createRequest(basicAuthHeader('user', 'wrong')), reply, done); + + expect(done).not.toHaveBeenCalled(); + expect(reply.status).toHaveBeenCalledWith(401); + expect(reply.send).toHaveBeenCalledWith('Authentication required'); + }); + + test('allows protected routes when credentials are valid', () => { + const hook = createTunarrBasicAuthHook({ + username: 'user', + password: 'pass', + }); + const reply = createReply(); + const done = vi.fn(); + + hook(createRequest(basicAuthHeader('user', 'pass')), reply, done); + + expect(done).toHaveBeenCalledOnce(); + expect(reply.status).not.toHaveBeenCalled(); + expect(reply.send).not.toHaveBeenCalled(); + }); + }); +}); diff --git a/server/src/util/basicAuth.ts b/server/src/util/basicAuth.ts new file mode 100644 index 000000000..90da3c113 --- /dev/null +++ b/server/src/util/basicAuth.ts @@ -0,0 +1,83 @@ +import crypto from 'node:crypto'; +import type { + FastifyReply, + FastifyRequest, + HookHandlerDoneFunction, + onRequestHookHandler, +} from 'fastify'; + +interface BasicAuthConfig { + username: string; + password: string; +} + +function unauthorized(reply: FastifyReply) { + reply.header('WWW-Authenticate', 'Basic realm="Tunarr"'); + return reply.status(401).send('Authentication required'); +} + +function hash(value: string) { + return crypto.createHash('sha256').update(value).digest(); +} + +export function safeEqual(a: string, b: string) { + return crypto.timingSafeEqual(hash(a), hash(b)); +} + +export function validateBasicAuth( + authHeader: string | undefined, + expectedUser: string, + expectedPass: string, +) { + if (!authHeader || !authHeader.startsWith('Basic ')) { + return false; + } + + try { + const encoded = authHeader.slice(6).trim(); + const decoded = Buffer.from(encoded, 'base64').toString('utf8'); + const idx = decoded.indexOf(':'); + + if (idx < 0) { + return false; + } + + const user = decoded.slice(0, idx); + const pass = decoded.slice(idx + 1); + + const userMatches = safeEqual(user, expectedUser); + const passMatches = safeEqual(pass, expectedPass); + + return userMatches && passMatches; + } catch { + return false; + } +} + +export function createTunarrBasicAuthHook( + config: BasicAuthConfig, +): onRequestHookHandler { + return ( + request: FastifyRequest, + reply: FastifyReply, + done: HookHandlerDoneFunction, + ) => { + if (request.routeOptions.config?.authRequired === false) { + done(); + return; + } + + const ok = validateBasicAuth( + request.headers.authorization, + config.username, + config.password, + ); + + if (!ok) { + void unauthorized(reply); + return; + } + + done(); + }; +} diff --git a/server/src/util/env.ts b/server/src/util/env.ts index 5365d8739..61a8efef5 100644 --- a/server/src/util/env.ts +++ b/server/src/util/env.ts @@ -13,6 +13,8 @@ const IS_EDGE_BUILD_ENV_VAR = 'TUNARR_EDGE_BUILD'; export const DATABASE_LOCATION_ENV_VAR = 'TUNARR_DATABASE_PATH'; const SERVER_PORT_ENV_VAR = 'TUNARR_SERVER_PORT'; const LOG_LEVEL_ENV_VAR = 'TUNARR_LOG_LEVEL'; +const BASIC_AUTH_USER_ENV_VAR = 'TUNARR_BASIC_AUTH_USER'; +const BASIC_AUTH_PASSWORD_ENV_VAR = 'TUNARR_BASIC_AUTH_PASSWORD'; // Advanced overrides const MEILISEARCH_PATH = 'TUNARR_MEILISEARCH_PATH'; @@ -33,6 +35,7 @@ const SESSION_STALENESS_MS = 'TUNARR_SESSION_STALENESS_MS'; const PROXY_ARTWORK_ENV_VAR = 'TUNARR_PROXY_ARTWORK'; export const TONEMAP_ENABLED = 'TUNARR_TONEMAP_ENABLED'; const WEBVTT_SIDECAR_ENABLED = 'TUNARR_WEBVTT_SIDECAR_ENABLED'; +const XMLTV_CREDIT_IMAGES_ENABLED = 'TUNARR_XMLTV_CREDIT_IMAGES_ENABLED'; // Escape hatches for new features const DISABLE_SEARCH_SNAPSHOT_IN_BACKUP = @@ -64,6 +67,8 @@ export const TUNARR_ENV_VARS = { SEARCH_MAX_INDEXING_THREADS, DEBUG__PROGRAM_GROUPING_UPDATE_CHUNK_SIZE, LOG_LEVEL_ENV_VAR, + BASIC_AUTH_USER_ENV_VAR, + BASIC_AUTH_PASSWORD_ENV_VAR, MEILISEARCH_PATH, DISABLE_SEARCH_SNAPSHOT_IN_BACKUP, SESSION_CLEANUP_DELAY_SECONDS, @@ -72,6 +77,7 @@ export const TUNARR_ENV_VARS = { DISABLE_VULKAN, DISABLE_VAAPI_PAD, MOUNT_DEBUG_ENDPOINTS, + XMLTV_CREDIT_IMAGES_ENABLED, SESSION_STALENESS_MS, } as const; diff --git a/types/src/FeatureFlags.ts b/types/src/FeatureFlags.ts index 1f7c8b9bb..541e95fcb 100644 --- a/types/src/FeatureFlags.ts +++ b/types/src/FeatureFlags.ts @@ -4,6 +4,7 @@ export const FeatureFlagsSchema = z.object({ proxyArtwork: z.boolean().default(false), tonemapEnabled: z.boolean().default(false), webvttSidecarEnabled: z.boolean().default(false), + xmltvCreditImagesEnabled: z.boolean().default(false), disableSearchSnapshotInBackup: z.boolean().default(false), disableVulkan: z.boolean().default(false), disableVaapiPad: z.boolean().default(false), @@ -45,6 +46,14 @@ export const FeatureFlagMetadata: FeatureFlagMeta[] = [ envVar: 'TUNARR_WEBVTT_SIDECAR_ENABLED', category: 'experimental', }, + { + key: 'xmltvCreditImagesEnabled', + displayName: 'XMLTV Credit Images', + description: + 'Enable embedding images of people in the xmltv credit elements. (must regenerate xmltv to take effect)', + envVar: 'TUNARR_XMLTV_CREDIT_IMAGES_ENABLED', + category: 'experimental', + }, { key: 'disableSearchSnapshotInBackup', displayName: 'Disable Search Snapshot in Backup', diff --git a/types/src/api/index.ts b/types/src/api/index.ts index 255cbbcf2..173c86882 100644 --- a/types/src/api/index.ts +++ b/types/src/api/index.ts @@ -174,18 +174,15 @@ export type UpdateChannelProgrammingRequest = z.infer< export const UpdateMediaSourceRequestSchema = z.discriminatedUnion('type', [ PlexServerSettingsSchema.partial({ sendGuideUpdates: true, + sendPlayStatusUpdates: true, clientIdentifier: true, - }) - .omit({ libraries: true }) - .required({ - accessToken: true, - }), - JellyfinServerSettingsSchema.omit({ libraries: true }).required({ - accessToken: true, - }), - EmbyServerSettingsSchema.omit({ libraries: true }).required({ - accessToken: true, + }).omit({ libraries: true }), + JellyfinServerSettingsSchema.partial({ + sendPlayStatusUpdates: true, + }).omit({ + libraries: true, }), + EmbyServerSettingsSchema.omit({ libraries: true }), LocalMediaSourceSchema.omit({ libraries: true }), ]); diff --git a/types/src/schemas/programmingSchema.ts b/types/src/schemas/programmingSchema.ts index 925fc8954..45f11673d 100644 --- a/types/src/schemas/programmingSchema.ts +++ b/types/src/schemas/programmingSchema.ts @@ -460,6 +460,8 @@ export const MusicTrackWithHierarchy = z.object({ export const MusicVideoMetadata = z.object({ ...BaseProgram.shape, type: z.literal('music_video'), + artistName: z.string().nullable().optional(), + albumName: z.string().nullable().optional(), }); export const MusicVideo = z.object({ diff --git a/types/src/schemas/settingsSchemas.ts b/types/src/schemas/settingsSchemas.ts index 63e5ade1d..29993fa24 100644 --- a/types/src/schemas/settingsSchemas.ts +++ b/types/src/schemas/settingsSchemas.ts @@ -150,38 +150,43 @@ export const MediaSourcePathReplacement = z.object({ const BaseMediaSourceSettingsSchema = z.object({ id: z.string(), name: z.string(), + libraries: z.array(BaseMediaSourceLibrarySchema), + pathReplacements: z.array(MediaSourcePathReplacement), +}); + +const RemoteMediaSourceSettingsSchema = z.object({ + ...BaseMediaSourceSettingsSchema.shape, uri: z.string(), accessToken: z.string().optional(), userId: z.string().nullable(), + sendPlayStatusUpdates: z.boolean().default(false), username: z.string().nullable(), - libraries: z.array(BaseMediaSourceLibrarySchema), - pathReplacements: z.array(MediaSourcePathReplacement), }); -export const PlexServerSettingsSchema = BaseMediaSourceSettingsSchema.extend({ +export const PlexServerSettingsSchema = z.object({ + ...RemoteMediaSourceSettingsSchema.shape, type: z.literal(MediaSourceType.enum.plex), sendGuideUpdates: z.boolean(), index: z.number(), clientIdentifier: z.string().optional(), }); -export const JellyfinServerSettingsSchema = - BaseMediaSourceSettingsSchema.extend({ - type: z.literal('jellyfin'), - }); +export const JellyfinServerSettingsSchema = z.object({ + ...RemoteMediaSourceSettingsSchema.shape, + type: z.literal('jellyfin'), +}); -export const EmbyServerSettingsSchema = BaseMediaSourceSettingsSchema.extend({ +export const EmbyServerSettingsSchema = z.object({ + ...RemoteMediaSourceSettingsSchema.shape, type: z.literal('emby'), }); -export const LocalMediaSourceSchema = z - .object({ - ...BaseMediaSourceSettingsSchema.shape, - type: z.literal('local'), - mediaType: MediaSourceContentType, - paths: z.array(z.string().min(1)).nonempty(), - }) - .omit({ accessToken: true, userId: true, username: true, uri: true }); +export const LocalMediaSourceSchema = z.object({ + ...BaseMediaSourceSettingsSchema.shape, + type: z.literal('local'), + mediaType: MediaSourceContentType, + paths: z.array(z.string().min(1)).nonempty(), +}); export const MediaSourceSettingsSchema = z.discriminatedUnion('type', [ PlexServerSettingsSchema, diff --git a/types/src/schemas/transcodeConfigSchemas.ts b/types/src/schemas/transcodeConfigSchemas.ts index ae573e707..8e629e409 100644 --- a/types/src/schemas/transcodeConfigSchemas.ts +++ b/types/src/schemas/transcodeConfigSchemas.ts @@ -31,6 +31,8 @@ export const SupportedTranscodeAudioOutputFormats = [ 'ac3', 'copy', 'mp3', + 'libopus', + 'eac3', ] as const; export type SupportedTranscodeAudioOutputFormats = TupleToUnion< diff --git a/web/src/components/form/BasicSelectInput.tsx b/web/src/components/form/BasicSelectInput.tsx index e722e52a4..f410942b6 100644 --- a/web/src/components/form/BasicSelectInput.tsx +++ b/web/src/components/form/BasicSelectInput.tsx @@ -67,7 +67,11 @@ export function SelectInput({ } > {options.map((opt) => ( - + {opt.description} ))} diff --git a/web/src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx b/web/src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx index 68c503e21..c92730103 100644 --- a/web/src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx +++ b/web/src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx @@ -16,8 +16,10 @@ import { LoudnormConfigSchema, type SupportedTranscodeAudioOutputFormats, } from '@tunarr/types/schemas'; +import { useQuery } from '@tanstack/react-query'; import { isNil } from 'lodash-es'; -import { useCallback, useState } from 'react'; +import { useCallback, useMemo, useState } from 'react'; +import { getApiFfmpegInfoOptions } from '../../../generated/@tanstack/react-query.gen.ts'; import type { DropdownOption } from '../../../helpers/DropdownOption.ts'; import type { BaseTranscodeConfigProps } from './BaseTranscodeConfigProps.ts'; import { useBaseTranscodeConfigFormOptions } from './useTranscodeConfigFormOptions.ts'; @@ -35,6 +37,14 @@ const AudioFormats: DropdownOption[] = [ description: 'MP3', value: 'mp3', }, + { + description: 'E-AC3', + value: 'eac3', + }, + { + description: 'Opus (experimental)', + value: 'libopus', + }, { description: 'Copy / Passthrough', value: 'copy', @@ -46,12 +56,39 @@ export const TranscodeConfigAudioSettingsForm = ({ showAdvancedSettings, }: BaseTranscodeConfigProps) => { const { t } = useLingui(); + const ffmpegInfo = useQuery({ + ...getApiFfmpegInfoOptions(), + }); const formOpts = useBaseTranscodeConfigFormOptions(initialConfig); const form = useTypedAppFormContext({ ...formOpts }); const [loudnormEnabled, setLoudnormEnabled] = useState( !isNil(form.getFieldValue('audioLoudnormConfig')), ); + const audioFormatOptions = useMemo(() => { + const availableEncoders = ffmpegInfo.data?.audioEncoders; + + return AudioFormats.map((option) => { + if (option.value === 'copy') { + return option; + } + + const isSupported = availableEncoders?.find((encoder) => { + return ( + encoder.ffmpegName === option.value || + // 'mp3' is an alias, the actual encoders in ffmpeg are called libmp3lame and libshine + (option.value === 'mp3' && + encoder.name.includes(`(codec ${option.value})`)) + ); + }); + + return { + ...option, + disabled: ffmpegInfo.isSuccess && !isSupported, + }; + }); + }, [ffmpegInfo.data?.audioEncoders, ffmpegInfo.isSuccess]); + const onLoudnormChange = useCallback( (enabled: boolean) => { setLoudnormEnabled(enabled); @@ -79,7 +116,7 @@ export const TranscodeConfigAudioSettingsForm = ({ selectProps={{ label: t`Audio Format`, }} - options={AudioFormats} + options={audioFormatOptions} helperText={ field.form.state.values.audioFormat === 'copy' ? t`Passthrough audio unchanged. Other settings will not apply.` diff --git a/web/src/components/settings/media_source/EmbyServerEditDialog.tsx b/web/src/components/settings/media_source/EmbyServerEditDialog.tsx index 0acaaca70..c8cf04712 100644 --- a/web/src/components/settings/media_source/EmbyServerEditDialog.tsx +++ b/web/src/components/settings/media_source/EmbyServerEditDialog.tsx @@ -67,6 +67,7 @@ const emptyDefaults: EmbyServerSettingsForm = { password: '', userId: '', pathReplacements: [], + sendPlayStatusUpdates: false, }; export function EmbyServerEditDialog({ open, onClose, server }: Props) { @@ -302,7 +303,9 @@ export function EmbyServerEditDialog({ open, onClose, server }: Props) { !serverStatus.healthy && isNonEmptyString(field.value) ? ( <> - Server is unreachable + + Server is unreachable +
) : null @@ -354,7 +357,9 @@ export function EmbyServerEditDialog({ open, onClose, server }: Props) { }} render={({ field, fieldState: { error } }) => ( - Username + + Username{' '} + ( - Password + + Password{' '} + - Enter your Emby password to generate a new access token. + + Enter your Emby password to generate a new access token. + - OR + + OR + - Access Token + + Access Token{' '} + )} - Manually add an access token from your Emby server + + Manually add an access token from your Emby server + diff --git a/web/src/components/settings/media_source/JelllyfinServerEditDialog.tsx b/web/src/components/settings/media_source/JelllyfinServerEditDialog.tsx index e25d84b28..c59e96899 100644 --- a/web/src/components/settings/media_source/JelllyfinServerEditDialog.tsx +++ b/web/src/components/settings/media_source/JelllyfinServerEditDialog.tsx @@ -2,9 +2,9 @@ import { isNonEmptyString, isValidUrlWithError, toggle } from '@/helpers/util'; import { RotatingLoopIcon } from '@/components/base/LoadingIcon.tsx'; import { jellyfinLogin } from '@/hooks/jellyfin/useJellyfinLogin.ts'; +import { useMediaSourceBackendStatus } from '@/hooks/media-sources/useMediaSourceBackendStatus'; import { t } from '@lingui/core/macro'; import { Trans } from '@lingui/react/macro'; -import { useMediaSourceBackendStatus } from '@/hooks/media-sources/useMediaSourceBackendStatus'; import { CloudDoneOutlined, CloudOff, @@ -14,12 +14,14 @@ import { import { Box, Button, + Checkbox, Dialog, DialogActions, DialogContent, DialogTitle, Divider, FormControl, + FormControlLabel, FormHelperText, IconButton, InputAdornment, @@ -30,10 +32,10 @@ import { Typography, } from '@mui/material'; import { type JellyfinServerSettings } from '@tunarr/types'; -import { isEmpty, isUndefined } from 'lodash-es'; +import { every, isEmpty, isUndefined } from 'lodash-es'; import { useSnackbar } from 'notistack'; import { useEffect, useState, type FormEvent } from 'react'; -import { Controller, FormProvider, useForm } from 'react-hook-form'; +import { Controller, FormProvider, useForm, useWatch } from 'react-hook-form'; import type { StrictOmit } from 'ts-essentials'; import { type MarkOptional } from 'ts-essentials'; import { useDebounceCallback, useDebounceValue } from 'usehooks-ts'; @@ -65,6 +67,7 @@ const emptyDefaults: JellyfinServerSettingsForm = { password: '', userId: '', pathReplacements: [], + sendPlayStatusUpdates: false, }; export function JellyfinServerEditDialog({ open, onClose, server }: Props) { @@ -87,12 +90,16 @@ export function JellyfinServerEditDialog({ open, onClose, server }: Props) { control, watch, reset, - formState: { isDirty, isValid, defaultValues, errors }, + formState: { isDirty, isValid, defaultValues, errors, dirtyFields }, handleSubmit, setError, clearErrors, getValues, } = form; + const [accessToken, username, password] = useWatch({ + control, + name: ['accessToken', 'username', 'password'], + }); useEffect(() => { if (open) { @@ -201,6 +208,25 @@ export function JellyfinServerEditDialog({ open, onClose, server }: Props) { } catch (e) { showErrorSnack(e); } + } else if (isNonEmptyString(server?.id)) { + await handleSubmit((data) => { + console.log(data); + updateMediaSourceMut.mutate({ + path: { + id: data.id!, + }, + body: { + ...data, + id: data.id!, + accessToken: undefined, + }, + }); + }, showErrorSnack)(e).catch((err) => { + console.error(err); + showErrorSnack(err); + }); + + handleClose(); } }; @@ -208,7 +234,16 @@ export function JellyfinServerEditDialog({ open, onClose, server }: Props) { const [serverStatusDetails, updateServerStatusDetails] = useDebounceValue( { - id: server?.id && !isDirty ? server.id : undefined, + id: + server?.id && + (!( + dirtyFields.accessToken || + dirtyFields.username || + dirtyFields.password + ) || + every([password, accessToken, username], isEmpty)) + ? server.id + : undefined, accessToken: defaultValues?.accessToken ?? '', uri: defaultValues?.uri ?? '', }, @@ -232,20 +267,30 @@ export function JellyfinServerEditDialog({ open, onClose, server }: Props) { // or URI changes, but the status query will only fire every 500ms useEffect(() => { const sub = watch((value, { name }) => { - if ( - isNonEmptyString(value.accessToken) || - (isNonEmptyString(value.username) && isNonEmptyString(value.password)) - ) { - debounceClearError('root.auth'); - } else { - debounceSetError('root.auth', { - message: 'Must provide either access token or username/password', - }); + if (isEmpty(server?.id)) { + if ( + isNonEmptyString(value.accessToken) || + (isNonEmptyString(value.username) && isNonEmptyString(value.password)) + ) { + debounceClearError('root.auth'); + } else { + debounceSetError('root.auth', { + message: 'Must provide either access token or username/password', + }); + } } if (name === 'uri' || name === 'accessToken') { updateServerStatusDetails({ - id: server?.id && !isDirty ? server.id : undefined, + id: + server?.id && + !( + dirtyFields.accessToken || + dirtyFields.username || + dirtyFields.password + ) + ? server.id + : undefined, accessToken: value.accessToken ?? '', uri: value.uri ?? '', }); @@ -261,6 +306,9 @@ export function JellyfinServerEditDialog({ open, onClose, server }: Props) { debounceClearError, debounceSetError, errors, + dirtyFields.accessToken, + dirtyFields.username, + dirtyFields.password, ]); const { data: serverStatus, isLoading: serverStatusLoading } = @@ -316,7 +364,9 @@ export function JellyfinServerEditDialog({ open, onClose, server }: Props) { !serverStatus.healthy && isNonEmptyString(field.value) ? ( <> - Server is unreachable + + Server is unreachable +
) : null @@ -436,16 +486,20 @@ export function JellyfinServerEditDialog({ open, onClose, server }: Props) { )} /> - Enter your Jellyfin password to generate a new access token. -
- NOTE: These are never saved to the Tunarr DB. - Instead they are sent to Jellyfin to exchange for a session - token.
+ + Enter your Jellyfin password to generate a new access token. +
+ NOTE: These are never saved to the Tunarr DB. + Instead they are sent to Jellyfin to exchange for a session + token. +
- OR + + OR + ( - Access Token + + Access Token{' '} + )} - Manually add an access token from your Jellyfin server + + Manually add an access token from your Jellyfin server + @@ -495,6 +553,28 @@ export function JellyfinServerEditDialog({ open, onClose, server }: Props) { + + + ( + + )} + /> + } + label={t`Update Play Status`} + /> + + + Tunarr will update Jellyfin's "now playing" state while + channels are active. + + + + diff --git a/web/src/components/settings/media_source/PlexServerEditDialog.tsx b/web/src/components/settings/media_source/PlexServerEditDialog.tsx index 99067b2e6..7cd13d98c 100644 --- a/web/src/components/settings/media_source/PlexServerEditDialog.tsx +++ b/web/src/components/settings/media_source/PlexServerEditDialog.tsx @@ -1,8 +1,8 @@ import { RotatingLoopIcon } from '@/components/base/LoadingIcon'; import { isNonEmptyString, isValidUrlWithError, toggle } from '@/helpers/util'; +import { useMediaSourceBackendStatus } from '@/hooks/media-sources/useMediaSourceBackendStatus'; import { t } from '@lingui/core/macro'; import { Trans } from '@lingui/react/macro'; -import { useMediaSourceBackendStatus } from '@/hooks/media-sources/useMediaSourceBackendStatus'; import { CloudDoneOutlined, CloudOff, @@ -61,6 +61,7 @@ const emptyDefaults: PlexServerSettingsForm = { name: '', accessToken: '', sendGuideUpdates: false, + sendPlayStatusUpdates: false, index: 0, type: 'plex', userId: '', @@ -90,7 +91,7 @@ export function PlexServerEditDialog({ open, onClose, server }: Props) { control, watch, reset, - formState: { isDirty, isValid, defaultValues }, + formState: { isDirty, isValid, defaultValues, dirtyFields }, handleSubmit, } = form; @@ -133,7 +134,7 @@ export function PlexServerEditDialog({ open, onClose, server }: Props) { const [serverStatusDetails, updateServerStatusDetails] = useDebounceValue( { - id: server?.id && !isDirty ? server.id : undefined, + id: server?.id && !dirtyFields.accessToken ? server.id : undefined, accessToken: defaultValues!.accessToken!, uri: defaultValues!.uri!, }, @@ -236,7 +237,9 @@ export function PlexServerEditDialog({ open, onClose, server }: Props) { !serverStatus.healthy && isNonEmptyString(field.value) ? ( <> - Server is unreachable + + Server is unreachable +
) : null @@ -262,7 +265,9 @@ export function PlexServerEditDialog({ open, onClose, server }: Props) { }} render={({ field, formState: { errors } }) => ( - Access Token + + Access Token{' '} + )} - For more details on manually retrieving a Plex token, see{' '} - - here - + + For more details on manually retrieving a Plex token, + see{' '} + + here + + @@ -329,7 +337,7 @@ export function PlexServerEditDialog({ open, onClose, server }: Props) { - + + + + Tunarr will attempt to get Plex to pull Tunarr's updated + XMLTV upon regeneration + + - + + ( + + )} + /> + } + label={t`Update Play Status`} + /> + + + Tunarr will update Plex's "now playing" state while channels + are active. + + + + diff --git a/web/src/generated/types.gen.ts b/web/src/generated/types.gen.ts index 68d0ec39b..87d476e00 100644 --- a/web/src/generated/types.gen.ts +++ b/web/src/generated/types.gen.ts @@ -370,6 +370,8 @@ export type TerminalProgramInput = { path?: string | null; }>; state: 'ok' | 'missing'; + artistName?: string | null; + albumName?: string | null; mediaSourceId: string; libraryId: string; canonicalId: string; @@ -1780,6 +1782,8 @@ export type TerminalProgram = { path?: string | null; }>; state: 'ok' | 'missing'; + artistName?: string | null; + albumName?: string | null; mediaSourceId: string; libraryId: string; canonicalId: string; @@ -5804,7 +5808,7 @@ export type GetApiChannelsByIdTranscodeConfigResponses = { videoBitRate: number; videoBufferSize: number; audioChannels: number; - audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3'; + audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3' | 'libopus' | 'eac3'; audioBitRate: number; audioBufferSize: number; audioSampleRate: number; @@ -8491,10 +8495,6 @@ export type GetApiMediaSourcesResponses = { 200: Array<{ id: string; name: string; - uri: string; - accessToken?: string; - userId: string | null; - username: string | null; libraries: Array<{ id: string; name: string; @@ -8509,6 +8509,11 @@ export type GetApiMediaSourcesResponses = { serverPath: string; localPath: string; }>; + uri: string; + accessToken?: string; + userId: string | null; + sendPlayStatusUpdates: boolean; + username: string | null; type: 'plex'; sendGuideUpdates: boolean; index: number; @@ -8516,10 +8521,6 @@ export type GetApiMediaSourcesResponses = { } | { id: string; name: string; - uri: string; - accessToken?: string; - userId: string | null; - username: string | null; libraries: Array<{ id: string; name: string; @@ -8534,14 +8535,15 @@ export type GetApiMediaSourcesResponses = { serverPath: string; localPath: string; }>; - type: 'jellyfin'; - } | { - id: string; - name: string; uri: string; accessToken?: string; userId: string | null; + sendPlayStatusUpdates: boolean; username: string | null; + type: 'jellyfin'; + } | { + id: string; + name: string; libraries: Array<{ id: string; name: string; @@ -8556,6 +8558,11 @@ export type GetApiMediaSourcesResponses = { serverPath: string; localPath: string; }>; + uri: string; + accessToken?: string; + userId: string | null; + sendPlayStatusUpdates: boolean; + username: string | null; type: 'emby'; } | { id: string; @@ -8585,39 +8592,42 @@ export type GetApiMediaSourcesResponse = GetApiMediaSourcesResponses[keyof GetAp export type PostApiMediaSourcesData = { body?: { name: string; - uri: string; - accessToken: string; - userId: string | null; - username: string | null; pathReplacements: Array<{ serverPath: string; localPath: string; }>; + uri: string; + accessToken: string; + userId: string | null; + sendPlayStatusUpdates?: boolean; + username: string | null; type: 'plex'; sendGuideUpdates?: boolean; index?: number; clientIdentifier?: string; } | { name: string; - uri: string; - accessToken: string; - userId: string | null; - username: string | null; pathReplacements: Array<{ serverPath: string; localPath: string; }>; - type: 'jellyfin'; - } | { - name: string; uri: string; accessToken: string; userId: string | null; + sendPlayStatusUpdates?: boolean; username: string | null; + type: 'jellyfin'; + } | { + name: string; pathReplacements: Array<{ serverPath: string; localPath: string; }>; + uri: string; + accessToken: string; + userId: string | null; + sendPlayStatusUpdates?: boolean; + username: string | null; type: 'emby'; } | { name: string; @@ -8687,10 +8697,6 @@ export type GetApiMediaSourcesByMediaSourceIdResponses = { 200: { id: string; name: string; - uri: string; - accessToken?: string; - userId: string | null; - username: string | null; libraries: Array<{ id: string; name: string; @@ -8705,6 +8711,11 @@ export type GetApiMediaSourcesByMediaSourceIdResponses = { serverPath: string; localPath: string; }>; + uri: string; + accessToken?: string; + userId: string | null; + sendPlayStatusUpdates: boolean; + username: string | null; type: 'plex'; sendGuideUpdates: boolean; index: number; @@ -8712,10 +8723,6 @@ export type GetApiMediaSourcesByMediaSourceIdResponses = { } | { id: string; name: string; - uri: string; - accessToken?: string; - userId: string | null; - username: string | null; libraries: Array<{ id: string; name: string; @@ -8730,14 +8737,15 @@ export type GetApiMediaSourcesByMediaSourceIdResponses = { serverPath: string; localPath: string; }>; - type: 'jellyfin'; - } | { - id: string; - name: string; uri: string; accessToken?: string; userId: string | null; + sendPlayStatusUpdates: boolean; username: string | null; + type: 'jellyfin'; + } | { + id: string; + name: string; libraries: Array<{ id: string; name: string; @@ -8752,6 +8760,11 @@ export type GetApiMediaSourcesByMediaSourceIdResponses = { serverPath: string; localPath: string; }>; + uri: string; + accessToken?: string; + userId: string | null; + sendPlayStatusUpdates: boolean; + username: string | null; type: 'emby'; } | { id: string; @@ -8820,14 +8833,15 @@ export type GetApiMediaSourcesByIdLibrariesResponses = { mediaSource?: { id: string; name: string; - uri: string; - accessToken?: string; - userId: string | null; - username: string | null; pathReplacements: Array<{ serverPath: string; localPath: string; }>; + uri: string; + accessToken?: string; + userId: string | null; + sendPlayStatusUpdates: boolean; + username: string | null; type: 'plex'; sendGuideUpdates: boolean; index: number; @@ -8835,26 +8849,28 @@ export type GetApiMediaSourcesByIdLibrariesResponses = { } | { id: string; name: string; - uri: string; - accessToken?: string; - userId: string | null; - username: string | null; pathReplacements: Array<{ serverPath: string; localPath: string; }>; - type: 'jellyfin'; - } | { - id: string; - name: string; uri: string; accessToken?: string; userId: string | null; + sendPlayStatusUpdates: boolean; username: string | null; + type: 'jellyfin'; + } | { + id: string; + name: string; pathReplacements: Array<{ serverPath: string; localPath: string; }>; + uri: string; + accessToken?: string; + userId: string | null; + sendPlayStatusUpdates: boolean; + username: string | null; type: 'emby'; } | { id: string; @@ -8916,14 +8932,15 @@ export type PutApiMediaSourcesByIdLibrariesByLibraryIdResponses = { mediaSource?: { id: string; name: string; - uri: string; - accessToken?: string; - userId: string | null; - username: string | null; pathReplacements: Array<{ serverPath: string; localPath: string; }>; + uri: string; + accessToken?: string; + userId: string | null; + sendPlayStatusUpdates: boolean; + username: string | null; type: 'plex'; sendGuideUpdates: boolean; index: number; @@ -8931,26 +8948,28 @@ export type PutApiMediaSourcesByIdLibrariesByLibraryIdResponses = { } | { id: string; name: string; - uri: string; - accessToken?: string; - userId: string | null; - username: string | null; pathReplacements: Array<{ serverPath: string; localPath: string; }>; - type: 'jellyfin'; - } | { - id: string; - name: string; uri: string; accessToken?: string; userId: string | null; + sendPlayStatusUpdates: boolean; username: string | null; + type: 'jellyfin'; + } | { + id: string; + name: string; pathReplacements: Array<{ serverPath: string; localPath: string; }>; + uri: string; + accessToken?: string; + userId: string | null; + sendPlayStatusUpdates: boolean; + username: string | null; type: 'emby'; } | { id: string; @@ -8999,10 +9018,6 @@ export type GetApiMediaLibrariesByLibraryIdResponses = { mediaSource: { id: string; name: string; - uri: string; - accessToken?: string; - userId: string | null; - username: string | null; libraries: Array<{ id: string; name: string; @@ -9017,6 +9032,11 @@ export type GetApiMediaLibrariesByLibraryIdResponses = { serverPath: string; localPath: string; }>; + uri: string; + accessToken?: string; + userId: string | null; + sendPlayStatusUpdates: boolean; + username: string | null; type: 'plex'; sendGuideUpdates: boolean; index: number; @@ -9024,10 +9044,6 @@ export type GetApiMediaLibrariesByLibraryIdResponses = { } | { id: string; name: string; - uri: string; - accessToken?: string; - userId: string | null; - username: string | null; libraries: Array<{ id: string; name: string; @@ -9042,14 +9058,15 @@ export type GetApiMediaLibrariesByLibraryIdResponses = { serverPath: string; localPath: string; }>; - type: 'jellyfin'; - } | { - id: string; - name: string; uri: string; accessToken?: string; userId: string | null; + sendPlayStatusUpdates: boolean; username: string | null; + type: 'jellyfin'; + } | { + id: string; + name: string; libraries: Array<{ id: string; name: string; @@ -9064,6 +9081,11 @@ export type GetApiMediaLibrariesByLibraryIdResponses = { serverPath: string; localPath: string; }>; + uri: string; + accessToken?: string; + userId: string | null; + sendPlayStatusUpdates: boolean; + username: string | null; type: 'emby'; } | { id: string; @@ -9343,14 +9365,15 @@ export type PutApiMediaSourcesByIdData = { body?: { id: string; name: string; - uri: string; - accessToken: string; - userId: string | null; - username: string | null; pathReplacements: Array<{ serverPath: string; localPath: string; }>; + uri: string; + accessToken?: string; + userId: string | null; + sendPlayStatusUpdates?: boolean; + username: string | null; type: 'plex'; sendGuideUpdates?: boolean; index: number; @@ -9358,26 +9381,28 @@ export type PutApiMediaSourcesByIdData = { } | { id: string; name: string; - uri: string; - accessToken: string; - userId: string | null; - username: string | null; pathReplacements: Array<{ serverPath: string; localPath: string; }>; + uri: string; + accessToken?: string; + userId: string | null; + sendPlayStatusUpdates?: boolean; + username: string | null; type: 'jellyfin'; } | { id: string; name: string; - uri: string; - accessToken: string; - userId: string | null; - username: string | null; pathReplacements: Array<{ serverPath: string; localPath: string; }>; + uri: string; + accessToken?: string; + userId: string | null; + sendPlayStatusUpdates?: boolean; + username: string | null; type: 'emby'; } | { id: string; @@ -9567,7 +9592,7 @@ export type GetApiTranscodeConfigsResponses = { videoBitRate: number; videoBufferSize: number; audioChannels: number; - audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3'; + audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3' | 'libopus' | 'eac3'; audioBitRate: number; audioBufferSize: number; audioSampleRate: number; @@ -9622,7 +9647,7 @@ export type PostApiTranscodeConfigsData = { videoBitRate: number; videoBufferSize: number; audioChannels: number; - audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3'; + audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3' | 'libopus' | 'eac3'; audioBitRate: number; audioBufferSize: number; audioSampleRate: number; @@ -9682,7 +9707,7 @@ export type PostApiTranscodeConfigsResponses = { videoBitRate: number; videoBufferSize: number; audioChannels: number; - audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3'; + audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3' | 'libopus' | 'eac3'; audioBitRate: number; audioBufferSize: number; audioSampleRate: number; @@ -9780,7 +9805,7 @@ export type GetApiTranscodeConfigsByIdResponses = { videoBitRate: number; videoBufferSize: number; audioChannels: number; - audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3'; + audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3' | 'libopus' | 'eac3'; audioBitRate: number; audioBufferSize: number; audioSampleRate: number; @@ -9836,7 +9861,7 @@ export type PutApiTranscodeConfigsByIdData = { videoBitRate: number; videoBufferSize: number; audioChannels: number; - audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3'; + audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3' | 'libopus' | 'eac3'; audioBitRate: number; audioBufferSize: number; audioSampleRate: number; @@ -9898,7 +9923,7 @@ export type PutApiTranscodeConfigsByIdResponses = { videoBitRate: number; videoBufferSize: number; audioChannels: number; - audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3'; + audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3' | 'libopus' | 'eac3'; audioBitRate: number; audioBufferSize: number; audioSampleRate: number; @@ -9977,7 +10002,7 @@ export type PostApiTranscodeConfigsByIdCopyResponses = { videoBitRate: number; videoBufferSize: number; audioChannels: number; - audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3'; + audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3' | 'libopus' | 'eac3'; audioBitRate: number; audioBufferSize: number; audioSampleRate: number; @@ -11219,6 +11244,8 @@ export type GetApiPlexByMediaSourceIdSearchResponses = { path?: string | null; }>; state: 'ok' | 'missing'; + artistName?: string | null; + albumName?: string | null; mediaSourceId: string; libraryId: string; canonicalId: string; @@ -12945,7 +12972,7 @@ export type PostApiTroubleshootResponses = { videoBitRate: number; videoBufferSize: number; audioChannels: number; - audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3'; + audioFormat: 'aac' | 'ac3' | 'copy' | 'mp3' | 'libopus' | 'eac3'; audioBitRate: number; audioBufferSize: number; audioSampleRate: number; diff --git a/web/src/helpers/DropdownOption.ts b/web/src/helpers/DropdownOption.ts index 90ae5561b..fa98632b6 100644 --- a/web/src/helpers/DropdownOption.ts +++ b/web/src/helpers/DropdownOption.ts @@ -2,4 +2,5 @@ export type DropdownOption = { value: T; description: string; helperText?: string; + disabled?: boolean; }; diff --git a/web/src/locales/en/messages.po b/web/src/locales/en/messages.po index 97ede1ed9..f54459067 100644 --- a/web/src/locales/en/messages.po +++ b/web/src/locales/en/messages.po @@ -298,16 +298,16 @@ msgstr "A-Z (desc)" msgid "about " msgstr "about " -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:362 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:398 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:439 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:455 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:382 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:424 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:456 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:472 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:265 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:281 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:367 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:405 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:451 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:468 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:432 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:474 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:511 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:528 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:269 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:286 msgid "Access Token" msgstr "Access Token" @@ -315,10 +315,10 @@ msgstr "Access Token" #: src/components/settings/AddPlexServer.tsx:14 #: src/components/settings/media_source/AddMediaSourceButton.tsx:83 #: src/components/settings/media_source/EditPathReplacementsForm.tsx:34 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:499 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:516 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:514 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:596 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:338 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:360 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:394 #: src/hooks/useRouteName.ts:83 msgid "Add" msgstr "Add" @@ -444,7 +444,7 @@ msgstr "Adds Flex breaks after each TV episode or movie to ensure that the progr msgid "Adds Flex breaks between programs, attempting to avoid groups of consecutive programs that exceed the specified number of minutes." msgstr "Adds Flex breaks between programs, attempting to avoid groups of consecutive programs that exceed the specified number of minutes." -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:196 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:233 msgid "Adjust the output volume (not recommended). Values higher than 100 will boost the audio." msgstr "Adjust the output volume (not recommended). Values higher than 100 will boost the audio." @@ -458,7 +458,7 @@ msgstr "Adjust Weights" #~ msgid "Advanced" #~ msgstr "Advanced" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:255 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:292 msgid "Advanced options relating to audio. In general, do not change these unless you know what you are doing!" msgstr "Advanced options relating to audio. In general, do not change these unless you know what you are doing!" @@ -466,7 +466,7 @@ msgstr "Advanced options relating to audio. In general, do not change these unle msgid "Advanced options relating to transcoding. In general, do not change these unless you know what you are doing! These settings exist in order to leave some parity with the old dizqueTV transcode pipeline as well as to provide mechanisms to aid in debugging streaming issues." msgstr "Advanced options relating to transcoding. In general, do not change these unless you know what you are doing! These settings exist in order to leave some parity with the old dizqueTV transcode pipeline as well as to provide mechanisms to aid in debugging streaming issues." -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:252 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:289 #: src/components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx:223 msgid "Advanced Video Options" msgstr "Advanced Video Options" @@ -596,19 +596,19 @@ msgstr "Audio & Subtitles" msgid "Audio Action" msgstr "Audio Action" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:102 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:139 msgid "Audio Bitrate" msgstr "Audio Bitrate" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:131 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:168 msgid "Audio Buffer Size" msgstr "Audio Buffer Size" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:185 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:222 msgid "Audio Channels" msgstr "Audio Channels" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:80 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:117 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:139 msgid "Audio Format" msgstr "Audio Format" @@ -617,8 +617,8 @@ msgstr "Audio Format" msgid "Audio Language Preferences" msgstr "Audio Language Preferences" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:211 -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:214 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:248 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:251 msgid "Audio Loudness Normalization" msgstr "Audio Loudness Normalization" @@ -626,7 +626,7 @@ msgstr "Audio Loudness Normalization" msgid "Audio Options" msgstr "Audio Options" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:161 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:198 msgid "Audio Sample Rate" msgstr "Audio Sample Rate" @@ -634,7 +634,7 @@ msgstr "Audio Sample Rate" msgid "Audio Streams" msgstr "Audio Streams" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:195 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:232 msgid "Audio Volume" msgstr "Audio Volume" @@ -650,7 +650,7 @@ msgstr "Auto Deinterlace Video" msgid "Auto uses the time convention for the selected language." msgstr "Auto uses the time convention for the selected language." -#: src/components/settings/media_source/PlexServerEditDialog.tsx:344 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:352 msgid "Auto-Update Guide" msgstr "Auto-Update Guide" @@ -703,7 +703,7 @@ msgstr "Basic button group" msgid "Bit Depth" msgstr "Bit Depth" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:113 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:150 msgid "Bitrate cannot be changed when copying input audio" msgstr "Bitrate cannot be changed when copying input audio" @@ -736,7 +736,7 @@ msgstr "Break Interval (minutes)" msgid "Break Positioning" msgstr "Break Positioning" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:142 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:179 msgid "Buffer size cannot be changed when copying input audio" msgstr "Buffer size cannot be changed when copying input audio" @@ -786,10 +786,10 @@ msgstr "Calculating Slots..." #: src/components/programming_controls/BalanceProgrammingModal.tsx:68 #: src/components/programming_controls/RemoveShowsModal.tsx:429 #: src/components/programming_controls/ShuffleProgrammingModal.tsx:76 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:486 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:503 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:501 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:583 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:330 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:353 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:387 #: src/components/settings/UnsavedNavigationAlert.tsx:67 #: src/components/slot_scheduler/EditRandomSlotDialogContent.tsx:576 #: src/components/slot_scheduler/EditTimeSlotDialogContent.tsx:408 @@ -804,9 +804,9 @@ msgstr "Calculating Slots..." msgid "Cancel" msgstr "Cancel" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:280 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:294 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:214 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:281 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:342 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:215 msgid "Cannot be empty" msgstr "Cannot be empty" @@ -1291,7 +1291,7 @@ msgstr "Description" msgid "Details" msgstr "Details" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:196 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:203 msgid "Did not receive an accessToken or userId from Jellyfin server." msgstr "Did not receive an accessToken or userId from Jellyfin server." @@ -1315,7 +1315,7 @@ msgstr "Disable Image Scaling" msgid "Disable Watermarks" msgstr "Disable Watermarks" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:219 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:256 #: src/pages/settings/FfmpegSettingsPage.tsx:224 #: src/pages/system/StatusPage.tsx:334 msgid "Disabled" @@ -1473,14 +1473,14 @@ msgstr "Edit Transcode Config: \"{0}\"" #. placeholder {0}: server.name #. placeholder {0}: source.name -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:78 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:75 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:79 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:78 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:214 msgid "Editing \"{0}\"" msgstr "Editing \"{0}\"" #. placeholder {0}: server.name -#: src/components/settings/media_source/PlexServerEditDialog.tsx:77 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:78 msgid "Editing Plex Server \"{0}\"" msgstr "Editing Plex Server \"{0}\"" @@ -1497,7 +1497,7 @@ msgstr "Emby" msgid "Empty Trash" msgstr "Empty Trash" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:226 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:263 msgid "Enable <0>EBU R 128 loudness normalization via the <1>loudnorm FFmpeg filter. May increase CPU usage during streaming." msgstr "Enable <0>EBU R 128 loudness normalization via the <1>loudnorm FFmpeg filter. May increase CPU usage during streaming." @@ -1554,7 +1554,7 @@ msgstr "Enable Watermark" msgid "Enabled" msgstr "Enabled" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:222 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:259 msgid "Enabled (loudnorm)" msgstr "Enabled (loudnorm)" @@ -1578,11 +1578,11 @@ msgstr "Ensures programs have a nice-looking start time, it will add Flex time t msgid "Ensures programs start only at a particular interval within the hour. This makes for nice looking schedules. Flex time is scheduled to facilitate." msgstr "Ensures programs start only at a particular interval within the hour. This makes for nice looking schedules. Flex time is scheduled to facilitate." -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:342 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:345 msgid "Enter a name for your Emby Server" msgstr "Enter a name for your Emby Server" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:356 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:406 msgid "Enter a name for your Jellyfin Server" msgstr "Enter a name for your Jellyfin Server" @@ -1590,11 +1590,11 @@ msgstr "Enter a name for your Jellyfin Server" msgid "Enter a name for your Local Media Source" msgstr "Enter a name for your Local Media Source" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:413 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:420 msgid "Enter your Emby password to generate a new access token." msgstr "Enter your Emby password to generate a new access token." -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:439 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:489 msgid "Enter your Jellyfin password to generate a new access token.<0/><1>NOTE: These are never saved to the Tunarr DB. Instead they are sent to Jellyfin to exchange for a session token." msgstr "Enter your Jellyfin password to generate a new access token.<0/><1>NOTE: These are never saved to the Tunarr DB. Instead they are sent to Jellyfin to exchange for a session token." @@ -1636,11 +1636,11 @@ msgstr "Error Options" msgid "Error querying Plex. Check console log and consider reporting a bug!" msgstr "Error querying Plex. Check console log and consider reporting a bug!" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:146 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:147 msgid "Error saving new Emby server. See browser console and server logs for details" msgstr "Error saving new Emby server. See browser console and server logs for details" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:115 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:122 msgid "Error saving new Jellyfin server. See browser console and server logs for details" msgstr "Error saving new Jellyfin server. See browser console and server logs for details" @@ -1950,7 +1950,7 @@ msgstr "Flex" msgid "Flex Style" msgstr "Flex Style" -#: src/components/settings/media_source/PlexServerEditDialog.tsx:292 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:297 msgid "For more details on manually retrieving a Plex token, see <0>here" msgstr "For more details on manually retrieving a Plex token, see <0>here" @@ -2368,15 +2368,15 @@ msgstr "Looks like something went wrong." msgid "Loop Short Programs" msgstr "Loop Short Programs" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:281 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:318 msgid "Loudness Range Target" msgstr "Loudness Range Target" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:271 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:308 msgid "Loudness Target" msgstr "Loudness Target" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:263 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:300 msgid "Loudnorm Options" msgstr "Loudnorm Options" @@ -2396,11 +2396,11 @@ msgstr "Manage Libraries" msgid "Manual" msgstr "Manual" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:467 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:480 msgid "Manually add an access token from your Emby server" msgstr "Manually add an access token from your Emby server" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:484 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:540 msgid "Manually add an access token from your Jellyfin server" msgstr "Manually add an access token from your Jellyfin server" @@ -2438,7 +2438,7 @@ msgstr "Max file size (bytes)" msgid "Max Lateness" msgstr "Max Lateness" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:291 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:328 msgid "Max True Peak" msgstr "Max True Peak" @@ -2573,10 +2573,10 @@ msgstr "Must use a valid URL, or empty." #: src/components/settings/ConnectMediaSources.tsx:44 #: src/components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx:95 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:93 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:335 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:349 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:338 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:399 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:238 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:317 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:325 #: src/components/smart_collections/CreateSmartCollectionDialog.tsx:162 #: src/components/smart_collections/EditSmartCollectionDialog.tsx:108 #: src/components/smart_collections/SmartCollectionsTable.tsx:59 @@ -2589,10 +2589,10 @@ msgstr "Must use a valid URL, or empty." msgid "Name" msgstr "Name" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:330 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:344 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:333 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:394 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:233 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:312 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:320 msgid "Name can only contain alphanumeric characters, dashes, and underscores" msgstr "Name can only contain alphanumeric characters, dashes, and underscores" @@ -2623,7 +2623,7 @@ msgstr "New Channel" msgid "New Custom Show" msgstr "New Custom Show" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:78 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:79 msgid "New Emby Media Source" msgstr "New Emby Media Source" @@ -2635,11 +2635,11 @@ msgstr "New Filler List" msgid "New Local Media Source" msgstr "New Local Media Source" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:75 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:78 msgid "New Media Source" msgstr "New Media Source" -#: src/components/settings/media_source/PlexServerEditDialog.tsx:78 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:79 msgid "New Plex Server" msgstr "New Plex Server" @@ -2711,9 +2711,9 @@ msgstr "Normalize Frame Rate" msgid "Not a valid number" msgstr "Not a valid number" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:282 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:296 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:216 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:283 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:344 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:217 msgid "Not a valid URL" msgstr "Not a valid URL" @@ -2781,8 +2781,8 @@ msgstr "Operator" msgid "Options" msgstr "Options" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:418 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:448 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:428 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:501 msgid "OR" msgstr "OR" @@ -2858,12 +2858,12 @@ msgstr "Pad Style" msgid "Pad Times" msgstr "Pad Times" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:85 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:122 msgid "Passthrough audio unchanged. Other settings will not apply." msgstr "Passthrough audio unchanged. Other settings will not apply." -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:382 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:407 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:388 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:457 msgid "Password" msgstr "Password" @@ -3032,9 +3032,9 @@ msgstr "Programs Too Long" msgid "Properties" msgstr "Properties" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:284 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:298 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:218 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:285 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:346 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:219 msgid "Protocol must be HTTP or HTTPS" msgstr "Protocol must be HTTP or HTTPS" @@ -3316,7 +3316,7 @@ msgstr "Run Troubleshooter" msgid "Running..." msgstr "Running..." -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:172 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:209 msgid "Sample rate cannot be changed when copying input audio" msgstr "Sample rate cannot be changed when copying input audio" @@ -3451,9 +3451,9 @@ msgstr "Selected Audio" msgid "Selected Subtitle" msgstr "Selected Subtitle" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:305 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:319 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:239 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:307 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:368 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:241 msgid "Server is unreachable" msgstr "Server is unreachable" @@ -4008,11 +4008,11 @@ msgstr "To use Tunarr, you need to first connect a media source. This will allow msgid "Today" msgstr "Today" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:390 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:447 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:416 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:464 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:273 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:397 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:460 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:466 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:520 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:278 msgid "toggle access token visibility" msgstr "toggle access token visibility" @@ -4087,6 +4087,18 @@ msgstr "Tunarr is currently configured to use the AC3 audio encoder. This audio msgid "Tunarr runs various tasks, sometimes on a schedule, for background operations." msgstr "Tunarr runs various tasks, sometimes on a schedule, for background operations." +#: src/components/settings/media_source/PlexServerEditDialog.tsx:355 +msgid "Tunarr will attempt to get Plex to pull Tunarr's updated XMLTV upon regeneration" +msgstr "Tunarr will attempt to get Plex to pull Tunarr's updated XMLTV upon regeneration" + +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:571 +msgid "Tunarr will update Jellyfin's \"now playing\" state while channels are active." +msgstr "Tunarr will update Jellyfin's \"now playing\" state while channels are active." + +#: src/components/settings/media_source/PlexServerEditDialog.tsx:375 +msgid "Tunarr will update Plex's \"now playing\" state while channels are active." +msgstr "Tunarr will update Plex's \"now playing\" state while channels are active." + #: src/pages/settings/HdhrSettingsPage.tsx:105 #: src/pages/settings/HdhrSettingsPage.tsx:108 msgid "Tuner Count" @@ -4124,16 +4136,21 @@ msgstr "Unlink" #~ msgid "Unlink from group" #~ msgstr "Unlink from group" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:499 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:516 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:514 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:596 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:338 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:360 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:394 msgid "Update" msgstr "Update" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:291 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:305 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:225 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:568 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:372 +msgid "Update Play Status" +msgstr "Update Play Status" + +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:292 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:353 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:226 #: src/pages/settings/MediaSourceSettingsPage.tsx:88 msgid "URL" msgstr "URL" @@ -4150,8 +4167,8 @@ msgstr "Use Show Poster" msgid "Use these settings to override global ffmpeg settings for this channel." msgstr "Use these settings to override global ffmpeg settings for this channel." -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:357 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:376 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:361 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:426 msgid "Username" msgstr "Username" diff --git a/web/src/locales/en/messages.ts b/web/src/locales/en/messages.ts index 731487c79..95077bf61 100644 --- a/web/src/locales/en/messages.ts +++ b/web/src/locales/en/messages.ts @@ -1 +1,4 @@ -/*eslint-disable*/import type{Messages}from"@lingui/core";export const messages=JSON.parse("{\"++nzCr\":[\"Bit Depth\"],\"+2JHIs\":[\"Link to existing slot\"],\"+406Vu\":[\"View Full Details\"],\"+4YwQF\":[\"# of Programs\"],\"+4mjS6\":[\"Remove icon\"],\"+9EErD\":[\"Music Videos\"],\"+DmLct\":[\"Programs\"],\"+SA5Ao\":[\"A root path to scan for media. Local sources can search many different paths.\"],\"+TZiPJ\":[\"Server is unreachable\"],\"+UPOiB\":[[\"count\",\"plural\",{\"one\":[\"min\"],\"other\":[\"mins\"]}]],\"+Xg5cX\":[\"Filler is picked fresh at stream time like Flex time. The guide shows \\\"Commercial Break\\\" placeholders.\"],\"+YdE7b\":[\"Enable rolling log files using time and/or size based criteria\"],\"+hl/7A\":[\"Channels configured to use the HLS Direct stream mode will output in the selected container format.\"],\"+k9lxR\":[\"Enter a name for your Local Media Source\"],\"+mdNfU\":[[\"count\",\"plural\",{\"one\":[\"#\",\" track\"],\"other\":[\"#\",\" tracks\"]}]],\"+suWTj\":[\"Adds Flex breaks between programs, attempting to avoid groups of consecutive programs that exceed the specified number of minutes.\"],\"+tlhMz\":[\"Plex (Manual)\"],\"+yEE7s\":[\"New Media Source\"],\"+yOcRn\":[\"HDHR\"],\"+ya1pX\":[\"Delete Slot\"],\"+zY9Xc\":[\"Configure Cyclic Shuffle\"],\"+zy2Nq\":[\"Type\"],\"/+ZaFm\":[\"Soundtrack\"],\"/4gGIX\":[\"Copy to clipboard\"],\"/6iIT9\":[\"Settings Saved!\"],\"/DTWjr\":[\"Congrats, you're ready to start building channels! Just click Finish below to start working on your first channel.\"],\"/QmYEW\":[\"Balance...\"],\"/TEOcd\":[\"Presets\"],\"/e88IO\":[\"Schedule programming in blocks that are either count or duration based. Can be used to generate random schedules.\"],\"/gavzH\":[\"Basic button group\"],\"/j3jjC\":[\"Error while saving settings. Please check console for details.\"],\"/n/HCO\":[\"Keywords\"],\"/rTz0M\":[\"Audio\"],\"/vJase\":[\"Streaming\"],\"09gg05\":[\"Programming\"],\"0IAEaX\":[\"Match\"],\"0MWZh1\":[\"Search is currently scoped to this Media Source Library.\"],\"0VHz2s\":[\"Filler Options\"],\"0cULRy\":[\"Experimental: Make perfect schedule loop\"],\"0dy9K6\":[\"Read Less\"],\"0mEBXY\":[\"Delete Transcoding Config \\\"\",[\"0\"],\"\\\"?\"],\"0wJVK+\":[\"Basic\"],\"0zpgxV\":[\"Options\"],\"1/dAym\":[\"Grouping works as follows:\"],\"14PdY0\":[\"Config\"],\"1AdBl9\":[\"Break Positioning\"],\"1BDPP1\":[\"Looks like something went wrong.\"],\"1BGQfg\":[\"Alphabetically\"],\"1CFAQ+\":[\"Set by environment variable\"],\"1DxLRi\":[\"No programming scheduled for this time period\"],\"1PQRWr\":[\"Start Time\"],\"1QfxQT\":[\"Dismiss\"],\"1TYXl0\":[\"Enter your Emby password to generate a new access token.\"],\"1V3Prt\":[\"Deleting a Filler will remove all programming from the channel. This action cannot be undone.\"],\"1Z90J4\":[\"Days to Precalculate\"],\"1hKEom\":[\"Priority\"],\"1jqDmP\":[\"Successfully scheduled \",[\"taskId\"],\" (running in background).\"],\"1njn7W\":[\"Light\"],\"2BBAbc\":[\"List\"],\"2BRPyl\":[\"System Info\"],\"2CVuYr\":[\"Smart Collection - \",[\"0\"]],\"2L7cj6\":[\"You haven't created any channels yet.\"],\"2QLniG\":[\"Existing query: \",[\"filterString\"]],\"2eFlmt\":[\"Tracks\"],\"2hOCU2\":[\"Smart Collections\"],\"2imNg3\":[\"Web version = \",[\"0\"],\", Server version = \",[\"1\"]],\"2mAJXf\":[\"Makes multiple copies of the schedule and plays them in sequence. Normally this isn't necessary, because Tunarr will always play the schedule back from the beginning when it finishes. But creating replicas is a useful intermediary step sometimes before applying other transformations. Note that because very large channels can be problematic, the number of replicas will be limited to avoid creating really large channels.\"],\"2oWehJ\":[\"Reset to current date/time\"],\"2vxecF\":[\"Show Stealth\"],\"2x4THe\":[\"\\\"\",[\"0\"],\"\\\" Sessions\"],\"312fSE\":[\"Select Shows to Remove\"],\"315BhT\":[\"Alphabetical\"],\"3JIYke\":[\"Healthy?\"],\"3JQkm5\":[\"Path Replacements\"],\"3JjdaA\":[\"Run\"],\"3LfNqe\":[\"Channel Number\"],\"3SH6Vv\":[\"Copied channel \\\"\",[\"channelName\"],\"\\\" m3u link to clipboard\"],\"3YNjnA\":[\"System Environment\"],\"3b1vGb\":[\"New Local Media Source\"],\"3mAQJI\":[\"How often the XMLTV file is regenerated\"],\"3nLdaX\":[\"Add \",[\"0\"]],\"3nwcC5\":[\"Filler - \",[\"0\"]],\"49dCCB\":[\"Use Show Poster\"],\"4Fpcxu\":[\"Initial Delay (minutes)\"],\"4NbDEd\":[\"Deleting a Custom Show will remove its programming from channels that use it. This action cannot be undone.\"],\"4Uc/2h\":[\"Server Listen Port\"],\"4VxpoP\":[\"Music tracks are grouped by artist\"],\"4XSc4l\":[\"Weekly\"],\"4XfYeY\":[\"Random (by show)\"],\"4fLgiT\":[\"Allow Image Based\"],\"4qmJK4\":[\"Tunarr Backend URL\"],\"4wkwyL\":[\"Disable Hardware Filters\"],\"4yQF++\":[\"Custom show programs are grouped by their parent show\"],\"50whWJ\":[\"XMLTV Link:\"],\"53/4tH\":[\"Audio Options\"],\"536Xwe\":[\"Error copying to clipboard!\"],\"53tfay\":[\"This allows to schedule specific shows to run at specific time slots of the day or a week. It's recommended you first populate the channel with the episodes from the shows you want to play and/or other content like movies and redirects.\"],\"5ABghp\":[\"FFmpeg Settings\"],\"5V93hk\":[\"Schedule programming using slots assigned a start time and duration.\"],\"5WeWGz\":[\"Selected Subtitle\"],\"5k0NLb\":[\"Review\"],\"5lSgNP\":[\"Enable SSDP server\"],\"5nsbxB\":[\"Alternates TV shows in blocks of episodes. You can pick the number of episodes per show in each block and if the order of shows in each block should be randomized. Movies are moved to the bottom.\"],\"5qV3NN\":[\"Flex Style\"],\"5yIPLp\":[\"Oops!\"],\"6/dCYd\":[\"Overview\"],\"63/DSM\":[\"Transcoding Configs\"],\"63driG\":[\"Stream JSON\"],\"67RoFa\":[\"Pipeline\"],\"6Y9c2m\":[\"This slot is linked with \",[\"0\"],\" other slot(s). Content fields are shared across the group.\"],\"6YtxFj\":[\"Name\"],\"6ZMWKw\":[\"XMLTV\"],\"6bbWRs\":[\"Add programming to custom show\"],\"6dvIbw\":[\"Unlink\"],\"6jAi8c\":[\"Range\"],\"6jfS51\":[\"Welcome\"],\"6ki7F2\":[[\"0\",\"plural\",{\"one\":[\"#\",\" item\"],\"other\":[\"#\",\" items\"]}]],\"6mJ9tF\":[\"FFMPEG is not detected.\"],\"6mpwdR\":[\"Match all of\"],\"6pL6be\":[\"Configure what appears on your channel when there is no suitable filler content available. Using channel fallbacks requires ffmpeg transcoding.\"],\"6w0yiE\":[\"FFMPEG Log Level\"],\"6zfUar\":[\"Stream Selection\"],\"71O7b0\":[\"Media Info\"],\"73XwX0\":[\"No programs selected\"],\"73flfT\":[\"QSV Device\"],\"7B3lfh\":[\"Items from any filler list will not be chosen more frequently than this cooldown setting.\"],\"7LWPgS\":[\"Enabled (loudnorm)\"],\"7ODkf5\":[\"Log level to pass to ffmpeg. Read more about ffmpeg's log levels <0>here\"],\"7Q5AKf\":[[\"count\",\"plural\",{\"one\":[\"track\"],\"other\":[\"tracks\"]}]],\"7b2stB\":[\"Media Type\"],\"7eMo+U\":[\"Go Home\"],\"7eZlTH\":[\"Sort TV Shows (asc)\"],\"7iJlKU\":[\"Please choose a value greater than 1\"],\"7pMNGK\":[\"Programs saved!\"],\"7sNhEz\":[\"Username\"],\"7tvV2B\":[\"Min Duration (minutes)\"],\"7uohY3\":[\"TV shows are grouped by show\"],\"80t7Ii\":[\"Increasing \\\"Max Lateness\\\" for the schedule.\"],\"87a/t/\":[\"Label\"],\"8E9KXK\":[\"Feature flags saved!\"],\"8MIU1T\":[\"Program\"],\"8TMaZI\":[\"Timestamp\"],\"8ZsakT\":[\"Password\"],\"8vETh9\":[\"Show\"],\"8wngZM\":[\"Fallback\"],\"8wu9lr\":[\"Queued\"],\"9+90+V\":[\"Enable Log File Rolling\"],\"94qSvE\":[\"Synced with external playlist\"],\"96zw7M\":[\"This show is marked as missing in the database.\"],\"983IRa\":[\"All linked slots show the same episode, advancing only after all have played.\"],\"9E+eyD\":[\"Output video at a constant frame rate.\"],\"9E9tRC\":[\"Fill with Flex\"],\"9Eq43e\":[\"If set, all watermark overlays will be disabled for channels assigned this transcode config.\"],\"9GPYnX\":[\"Do not group programs at all. Normal shuffle.\"],\"9WG5wy\":[\"Specials\"],\"9asVsi\":[\"How long each commercial break lasts\"],\"9qdNKR\":[\"Error Options\"],\"9sqrEU\":[\"Filler List\"],\"9td1Wl\":[\"Check\"],\"9vtG84\":[\" Scheduling Strategy\"],\"A+GCyx\":[\"Hide Advanced\"],\"A0+T6c\":[\"Reset Changes\"],\"A1taO8\":[\"Search\"],\"A7WmPm\":[\"New Plex Server\"],\"A9Rhec\":[\"Channel Name\"],\"ACKu03\":[\"Refresh Preview\"],\"AKjNTL\":[\"Add Padding\"],\"AM972O\":[\"Add Redirect\"],\"ANICN0\":[\"No media sources connected.\"],\"AO2Z5d\":[\"Movie, \",[\"0\"]],\"AOHgZp\":[\"Episodes\"],\"AVKoQM\":[\"Redirect to \\\"\",[\"0\"],\"\\\"\"],\"AXg7m0\":[\"Search is currently scoped to this Media Source.\"],\"AXjA78\":[\"Field\"],\"AdfhAd\":[\"If there are issues playing a video, Tunarr will try to use an error screen as a placeholder while retrying loading the video every 60 seconds.\"],\"AdogaJ\":[\"Pipeline Steps\"],\"AlfqgK\":[\"Watch\"],\"ApsQAb\":[\"HDHR: Loading...\"],\"AyInY5\":[\"Video Options\"],\"AzCYkg\":[\"Connect Media Sources\"],\"B+HsXP\":[\"FFMPEG: \",[\"0\"]],\"B1NOvD\":[\"Removes all programs from schedule\"],\"B1W8vw\":[\"Delete \\\"\",[\"0\"],\"\\\"\"],\"BGHH1t\":[\"Min. Visible in Guide Duration Program (seconds)\"],\"BJjJuo\":[\"EPG (Hours)\"],\"BMlGCC\":[\"Click to preview the items in this Custom Show. Note that only the whole show can be added at once.\"],\"BQsifH\":[\"Stream Info\"],\"BWTzAb\":[\"Manual\"],\"BXXjCD\":[\"FFmpeg not found. For all features to work, we recommend installing FFmpeg 7.1+ or update your FFmpeg executable path in settings.\"],\"BaUuhR\":[\"Codec\"],\"BlmmxH\":[\"FFmpeg Log\"],\"Bq0ryo\":[\"Reset Options\"],\"BtL93c\":[[\"0\",\"plural\",{\"one\":[\"#\",\" source connected.\"],\"other\":[\"#\",\" sources connected.\"]}]],\"C4KL42\":[\"Consolidates contiguous match flex and redirect blocks into singular spans\"],\"C6jEO3\":[\"Log Level\"],\"CAiikc\":[\"Enter your Jellyfin password to generate a new access token.<0/><1>NOTE: These are never saved to the Tunarr DB. Instead they are sent to Jellyfin to exchange for a session token.\"],\"CJkEfx\":[\"Block\"],\"CKQ3t3\":[\"Total Runtime\"],\"CMQ09J\":[\"Scanning\"],\"COv7As\":[\"Cooldown (seconds)\"],\"CRsuq4\":[\"Every\"],\"CVqySE\":[[\"len\",\"plural\",{\"one\":[\"There is \",\"#\",\" warning. Click for details.\"],\"other\":[\"There are \",\"#\",\" warnings. Click for details.\"]}]],\"CWRFGq\":[\"Modify Programming\"],\"CXDHcv\":[\"Grid\"],\"CcX8VV\":[\"Completely randomizes the order of programs.\"],\"CeyB7O\":[\"FFmpeg Executable Path\"],\"CfOWar\":[\"Logarithmic decay, lighter weighting.\"],\"CfUvtM\":[\"Error saving new Smart Collection. Check server logs and browser console for details.\"],\"CfxLtO\":[\"Program JSON\"],\"Cko536\":[\"Descending\"],\"Cp5Awv\":[\"Duration must be greater than 0.\"],\"CqSP2T\":[\"Edit Channel Redirect\"],\"CsrDsg\":[\"12-hour\"],\"Cxqf0C\":[\"Plex (Auto)\"],\"D+NlUC\":[\"System\"],\"D1Fhv3\":[[\"count\",\"plural\",{\"one\":[\"episode\"],\"other\":[\"episodes\"]}]],\"DPfwMq\":[\"Done\"],\"DRya1t\":[\"Audio Volume\"],\"DSwJ9W\":[\"Enable Animation\"],\"DUd3Ss\":[\"Sorts the list by TV Show and the episodes in each TV show by their season/episode number. Movies are moved to the bottom of the schedule.\"],\"DbouLP\":[\"Back to Programming\"],\"Dd9orS\":[\"Remove All \",[\"movieCount\"],\" \",[\"movieCount\",\"plural\",{\"one\":[\"Movie\"],\"other\":[\"Movies\"]}]],\"Dnn2XG\":[\"Automatic\"],\"DoJzLz\":[\"Collections\"],\"DxvGLB\":[\"Add Slot\"],\"E/QGRL\":[\"Disabled\"],\"E5ipHC\":[\"Balance By:\"],\"E8oclZ\":[\"Copied Channel ID!\"],\"EKlukx\":[\"Copy Full Report\"],\"EL4/HD\":[[\"0\",\"plural\",{\"one\":[\"program\"],\"other\":[\"programs\"]}]],\"EdQY6l\":[\"None\"],\"EkH9pt\":[\"Update\"],\"Etie0Q\":[\"All channels assigned to this config will be set to use the default configuration. If this is the last configuration, a new default configuration will be created.\"],\"Eu20Os\":[\"Time Slots\"],\"Ev2r9A\":[\"No results\"],\"F1l877\":[\"Subtitle Streams\"],\"F3bW6y\":[\"Platform\"],\"F3smBd\":[\"Maximum number of days to precalculate the schedule. Note that the length of the schedule is also bounded by the maximum number of programs allowed in a channel.<0/><1>Note: Previewing the schedule in the browser for long lengths of time can cause UI performance issues\"],\"FDEfoy\":[\"Deleting a media source will remove all of its associated programs from Tunarr.\"],\"FXCwT9\":[\"FFprobe Executable Path\"],\"FZg3wM\":[\"Operation\"],\"FmN5me\":[\"Resolution\"],\"FnChN1\":[\"Enable <0>EBU R 128 loudness normalization via the <1>loudnorm FFmpeg filter. May increase CPU usage during streaming.\"],\"Fp7p73\":[\"Time between subsequent breaks\"],\"FqCHF/\":[\"Threads\"],\"FrRP21\":[\"There was an error when submitting the form. Please see console logs for details.\"],\"FsF4bb\":[\"Audio Loudness Normalization\"],\"FssFce\":[\"Configure preferred audio languages globally.\"],\"Fzn/BQ\":[\"Release Date\"],\"G+8qH5\":[\"Channel name is required\"],\"GDKKxT\":[\"Access Token\"],\"GHOK4Z\":[\"Time Format\"],\"GJ1P5j\":[\"File a Bug Report\"],\"GKLqtE\":[\"Set the host of your Tunarr backend. When empty, the web UI will use the current host/port to communicate with the backend.\"],\"GLOZdc\":[\"Custom Shows\"],\"GP/CFo\":[\"HW Accel\"],\"GQ3O42\":[\"Trash\"],\"GRCrpV\":[\"Manage Libraries\"],\"GUtCZC\":[\"Version: \",[\"0\"]],\"GhZ4GX\":[\"Error while copying to clipboard. Check browser logs for details\"],\"GmP0oY\":[\"Slot Warnings\"],\"GmTnBN\":[\"Enable ffmpeg logging to different sinks. Outputting to a file will create a new log file for every spawned ffmpeg process in the Tunarr log directory. These files are automatically cleaned up by a background process.\"],\"Gr1Ik2\":[\"Nvidia Capabilities\"],\"GtycJ/\":[\"Tasks\"],\"GzzMwi\":[\"Roll on Schedule\"],\"H0QGc9\":[\"Filler List Cooldown (seconds)\"],\"H1OFlu\":[\"Inverse linear decay, heavier weighting.\"],\"H1V+2G\":[\"To use Tunarr, you must first connect at least one media source. Media sources provide all content used to create channels in Tunarr. Plex and Jellyfin are currently supported.\"],\"H3OF1s\":[\"Tuner Count\"],\"H7OUPr\":[\"Day\"],\"H8100o\":[\"Filler lists are collections of videos that you may want to play during 'flex' time segments. Flex is time within a channel that does not have a program scheduled (usually used for padding).\"],\"HDoQBx\":[\"Channel settings saved!\"],\"HEH0PR\":[\"Must define at least one language preference\"],\"HErtdg\":[\"Name can only contain alphanumeric characters, dashes, and underscores\"],\"HLlLPP\":[\"Channel Stream Mode\"],\"HMWEIt\":[\"Edit Flex Time\"],\"HOLbdk\":[\"Failed to load stream details! Check logs for details\"],\"HSfauP\":[\"This slot is linked with \",[\"0\"],\" other \",[\"1\",\"plural\",{\"one\":[\"slot\"],\"other\":[\"slots\"]}],\". Content fields are shared across the group.\"],\"HVpg3x\":[\"Failed to load Smart Collection\"],\"HXx+vU\":[\"Controls what happens when this slot runs out of replayed content from earlier continue slots.\"],\"HYCPKT\":[\"Add Selected Media\"],\"HajiZl\":[\"Month\"],\"HdE1If\":[\"Channel\"],\"Hjfx9G\":[\"Audio & Subtitles\"],\"HmHwcC\":[\"Fixed Interval\"],\"HptUxX\":[\"Number\"],\"HqUilK\":[\"Keywords perform full text search across all (or configured) fields\"],\"HzV8B2\":[\"Skip mid-roll for programs shorter than this\"],\"I+FvbD\":[\"Scan\"],\"I2Bar3\":[\"Shows\"],\"I5BU70\":[\"Smart Collection: \",[\"0\"]],\"I6gXOa\":[\"Path\"],\"IDlmXg\":[\"Tunarr Backend URL:\"],\"IFiQdD\":[\"Channels M3U Link:\"],\"IMxI++\":[\"Not a valid URL\"],\"INCbO6\":[\"On-Demand channels resume from where you left off. Programming is paused when the channel is not streaming.<0/><1>NOTE: While the channel is inactive, the TV Guide for the channel will be empty.\"],\"IagCbF\":[\"URL\"],\"IetKlB\":[\"New Custom Show\"],\"IgC1fP\":[\"Enable light Mode\"],\"IiBgkW\":[\"Failed to update Media Source settings. Please check server and browser logs for details.\"],\"IoSxk9\":[\"Protocol must be HTTP or HTTPS\"],\"IvkbIT\":[\"Read More\"],\"J/eF78\":[\"Removing overrun programs from the channel.\"],\"J0NKO1\":[\"Exclude Seasons\"],\"J2eKUI\":[\"File\"],\"J2lnQW\":[\"Pre\"],\"J41wt0\":[\"Slot Editor\"],\"J4Ngmi\":[\"Loop Short Programs\"],\"J50/e4\":[\"Filter Type\"],\"J8X80J\":[\"Stealth?\"],\"JCGCcQ\":[\"Sorts everything by its release date. This will only work correctly if the release dates in Plex are correct. In case any item does not have a release date specified, it will be moved to the bottom.\"],\"JCOZTc\":[\"Audio & Subtitle Options\"],\"JOFDLs\":[\"Program Playback Troubleshooter\"],\"JeAvlS\":[\"Pad Times\"],\"JeL1O4\":[\"Redirect duration\"],\"Jj3SJk\":[\"A-Z (asc)\"],\"JmZ/+d\":[\"Finish\"],\"Jpe9a8\":[\"Attempts to balance programming groups by either total lineup duration or number of unique programs. For instance, for a channel with many seasons of one show and few seasons of another, balancing will attempt to create an even mix of both shows by inserting repeats of the show with fewer episodes.\"],\"JryIGL\":[\"Adjust Weights\"],\"Jsel0T\":[\"This channel has an existing time slot schedule. A channel can only use one scheduling type at a time. Saving a schedule here will remove the existing time slot schedule.\"],\"Jtbzxr\":[\"Version: unknown\"],\"JxE+Bh\":[\"Allows you to pick specific programming to remove from the channel.\"],\"JyHA6G\":[\"Displays the last \",[\"0\"],\" system log events. Use the buttons below to export these logs or download the entire log file for debugging.\"],\"JzJk+4\":[\"Add Language Preference\"],\"K09nyY\":[\"Linked slots advance episode progression together sequentially.\"],\"K8+dbZ\":[[\"totalConnections\"],\" total\"],\"K9pQ8Q\":[\"Disable Watermarks\"],\"KRjDf4\":[\"Audio Streams\"],\"Khe/Vb\":[\"Watch Channel\"],\"KkOthv\":[\"Guide\"],\"Km5fSd\":[\"If you are confident FFMPEG is installed, you may just need to update the executable path in the settings. To do so, simply click Edit above to update the path.\"],\"L+8pV5\":[\"Sync with external playlist\"],\"L/KmPM\":[\"Usually slots need to add flex time to ensure that the next slot starts at the correct time. When there are multiple videos in the slot, you might prefer to distribute the flex time between the videos or to place most of the flex time at the end of the slot.\"],\"L6Mhe6\":[\"You have unsaved changes!\"],\"L8Hb+D\":[\"Sets the number of threads used to decode the input stream. Set to 0 to let ffmpeg automatically decide how many threads to use. Read more about this option <0>here. <1>Note: this option is overridden to 1 when using hardware accelearation for stability reasons.\"],\"LKPR6G\":[\"Playlist\"],\"LKSv28\":[\"Smart Collections are self-updating content lists. You set the query and the collection automatically adds any new content from your library that fits those rules. Any newly added content matching query will not modify existing channel programming at this time.\"],\"LMMGPr\":[\"Submitting...\"],\"LRvqnF\":[\"Error saving new Jellyfin server. See browser console and server logs for details\"],\"LTC198\":[\"Running...\"],\"LTYRAI\":[\"View Library\"],\"LiCr5o\":[\"Limit must be numeric\"],\"MHrjPM\":[\"Title\"],\"MKK96e\":[\"View Collection\"],\"MR6Nlf\":[\"Change the verbosity of specific categories of logs. Useful if debugging a specific feature.\"],\"MS1Dhi\":[\"Max file size (bytes)\"],\"MVBLYK\":[\"Remove...\"],\"MW42Hp\":[\"Customize how movie blocks are sorted\"],\"Md/eZS\":[[\"count\",\"plural\",{\"one\":[\"#\",\" item\"],\"other\":[\"#\",\" items\"]}]],\"MfkGXC\":[\"Shuffle Grouping\"],\"MkMcGz\":[\"Refresh Libraries\"],\"Ml7h3C\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Program\"],\"other\":[\"#\",\" Programs\"]}]],\"Mrdyk9\":[\"Genre\"],\"Mv+xQh\":[\"New Channel\"],\"N15e5e\":[\"Remove custom icon\"],\"NGOfis\":[\"Disable Image Scaling\"],\"NGSThJ\":[\"Smart Collection\"],\"NL/bON\":[\"FFmpeg Command\"],\"NQ7yht\":[\"Must use a valid URL, or empty.\"],\"NaDxQ2\":[\"Auto Deinterlace Video\"],\"Nb+B9K\":[\"Adjust the output volume (not recommended). Values higher than 100 will boost the audio.\"],\"NcV1df\":[\"Pad Start Times\"],\"NfTP7a\":[\"Advanced options relating to audio. In general, do not change these unless you know what you are doing!\"],\"NfZ8rc\":[\"24-hour\"],\"Nkn5MW\":[\"Removes all Flex periods from the schedule.\"],\"NnH3pK\":[\"Test\"],\"NnuRri\":[\"This allows you to pick the weights for each of the shows, so you can decide that some shows should be less frequent than other shows.\"],\"NtQvjo\":[\"Period\"],\"Nu4oKW\":[\"Description\"],\"Ny7dz3\":[\"Albums\"],\"NyfQ4q\":[\"Save as Smart Collection\"],\"O1xfOi\":[\"Random...\"],\"O5izWu\":[\"This custom show is synced with an external playlist. Content is updated automatically and cannot be edited manually.\"],\"O8g6Na\":[\"Last Scanned: \",[\"0\"]],\"OPw3KG\":[\"Connect Media Source\"],\"OVmXHk\":[\"Refresh Timer (Hours)\"],\"Ob+B6e\":[\"Buffer size cannot be changed when copying input audio\"],\"OfC/JK\":[\"Custom Show - \",[\"0\"]],\"OfYtUi\":[\"Filler Content\"],\"OfhWJH\":[\"Reset\"],\"OrDu0o\":[\"Video Buffer Size\"],\"Osn70z\":[\"Debug\"],\"P/TyYO\":[\"The type of media in the provided paths\"],\"P1BU0j\":[\"Frame Rate\"],\"P29ZKI\":[\"Enter a name for your Emby Server\"],\"P2DGHD\":[\"Programming starts at \",[\"startTime\"],\" and stops at \",[\"endTime\"]],\"P3i3NN\":[\"Edit Channel Settings\"],\"P6Io39\":[\"Max Lateness\"],\"P6c7YE\":[\"Remove Programming\"],\"PCBfmf\":[\"Renders a channel icon (also known as bug or Digital On-screen Graphic) on top of the channel's stream.\"],\"PJ/u9s\":[\"Copied \",[\"0\"],\" URL to clipboard\"],\"PT6k0T\":[\"Pixel Format\"],\"PX1WM1\":[\"Successfully emptied trash.\"],\"Pazp7r\":[\"There was an error generating time slots. Check the browser console log for more information\"],\"PeBTGz\":[\"Clear Schedule\"],\"PeBylA\":[\"You must create at least one <0>filler list before assigning filler to a lot.\"],\"Pfatg8\":[[\"minutes\",\"plural\",{\"one\":[\"#\",\" minute\"],\"other\":[\"#\",\" minutes\"]}]],\"PgdRhI\":[\"Weighting\"],\"Ph+yE0\":[\"0 mins\"],\"PhKcf0\":[\"Edit Transcode Config\"],\"PiY0nu\":[\"You have no Filler Lists. Create your first Filler List <0>here.\"],\"Pol2QS\":[\"Emby\"],\"PpZkda\":[\"Features\"],\"PwpUBp\":[\"This is the name of the fake program that will appear in the TV guide when there are no programs to display in that time slot guide, e.g when a large Flex block is scheduled.\"],\"Pwqkdw\":[\"Loading…\"],\"Q8L6q9\":[\"Video Streams\"],\"QAUrt0\":[\"Refresh Page\"],\"QEb4hu\":[\"Stealth Mode\"],\"QG2xdt\":[\"Create Rerun Block\"],\"QHRTYn\":[\"Slots Editor...\"],\"QKMxhc\":[\"Tunarr runs various tasks, sometimes on a schedule, for background operations.\"],\"QUxTIQ\":[\"Filler is resolved at schedule time. The guide shows specific filler titles.\"],\"Qll2Tb\":[\"Desc\"],\"QlrQ/Z\":[\"Next Scheduled Execution\"],\"Qm1NmK\":[\"OR\"],\"Qu844y\":[\"Time Slot Editor\"],\"QvKdb0\":[\"Placeholder Program Title\"],\"Qx971g\":[\"After Every\"],\"R/7J0Z\":[\"Artists\"],\"R/N+HY\":[\"No programming added yet\"],\"R/xSFi\":[\"Editing \\\"\",[\"0\"],\"\\\"\"],\"R0yni2\":[\"Attempt Auto-Fix\"],\"R40oLk\":[\"Will force use of a software encoder despite hardware acceleration settings.\"],\"R6kHq+\":[\"Link Mode\"],\"R9Khdg\":[\"Auto\"],\"RCeEAd\":[\"Global Options\"],\"RGf6l7\":[\"Select a slot to link to\"],\"RI4u49\":[\"<0>You can edit this location in your settings.json within your Tunarr data directory<1/><2>NOTE: When manually adding the XMLTV location to a client like Plex, do not use this file directly. Instead, use the generated XMLTV from the Tunarr API endpoint: \",[\"0\"],\"\"],\"RTxUjI\":[\"Copy to Clipboard\"],\"RUYsn0\":[\"Clear All\"],\"RVl9/c\":[\"Alternate programs in blocks. You can pick the number of programs per-type in each block and if the order of shows in each block should be randomized.\"],\"RYP47R\":[[\"0\",\"plural\",{\"one\":[\"Day\"],\"other\":[\"Days\"]}]],\"RYlQY0\":[\"Repeats\"],\"RaHlqV\":[[\"totalConnections\",\"plural\",{\"one\":[\"#\",\" connection\"],\"other\":[\"#\",\" connections\"]}]],\"RavMGr\":[[\"count\",\"plural\",{\"one\":[\"second\"],\"other\":[\"seconds\"]}]],\"RbgUS/\":[\"Copy Channel ID\"],\"RtPRIb\":[\"Maximum number of days to precalculate the schedule. Note that the length of the schedule is also bounded by the maximum number of programs allowed in a channel.\"],\"RxzN1M\":[\"Enabled\"],\"S/CawK\":[\"Movies are grouped altogether\"],\"S5v5/h\":[\"Enabling embedded subtitle extaction will periodically scan your upcoming programming for embedded text-based subtitle streams and extract them to a local cache. This is necessary in order to enable subtitle burning for text-based subtitles which are not external streams.\"],\"S60KP9\":[\"Server Settings\"],\"S8zZJK\":[\"Welcome to Tunarr!\"],\"SBtwzo\":[\"Version Mismatch!\"],\"SCZJhh\":[\"Audio Bitrate\"],\"SFjIKS\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Selected Item\"],\"other\":[\"#\",\" Selected Items\"]}]],\"SOXW6w\":[\"All Genres\"],\"SY1gRl\":[\"Media Source\"],\"SYGPcm\":[\"You have no smart collections. Smart collections can be created on the <0>search page.\"],\"SZcfpX\":[\"Pad Style\"],\"SZzr30\":[\"The selected languages will be considered in order they are selected.\"],\"Sbs5dW\":[\"Filler\"],\"Sg3laT\":[\"Min Duration\"],\"SoRsRS\":[\"Calculates a schedule where all programs end at the same time, creating a perfectly looping schedule.\"],\"SuubHr\":[\"Deleting a Plex server will remove all programming from your channels associated with this plex server. Missing programming will be replaced with Flex time. This action cannot be undone.\"],\"SywaS+\":[\"Data Directory:\"],\"T5wfux\":[\"Makes multiple copies of the schedule and plays them in sequence\"],\"T8drou\":[\"System Health\"],\"TEM0vH\":[\"Removes all programs from custom show\"],\"TMADKS\":[\"Divides the programming in blocks of 4, 6, 8 or 12 hours then repeats each of the blocks the specified number of times.\"],\"TMju4P\":[\"Delete Media Source \\\"\",[\"0\"],\"\\\"?\"],\"TS0lwx\":[\"Encountered an error when emptying trash. Check console logs for details.\"],\"TZKpsF\":[\"No Media Sources detected.\"],\"TpqW74\":[\"Fixed\"],\"Ts6Zfm\":[\"Error updating Smart Collection. Check logs for details.\"],\"Ts8Q+i\":[\"EPG\"],\"TvY/XA\":[\"Documentation\"],\"Tz0i8g\":[\"Settings\"],\"TzyoiK\":[\"When enabling, Tunarr will generate an initial backup immediately\"],\"U0sC6H\":[\"Daily\"],\"U3+jR/\":[\"Replicate Programs\"],\"UC1lMc\":[\"Failed to save feature flags.\"],\"UE2eVC\":[\"Sorts alphabetically by program title\"],\"UHu/Uf\":[\"Show only synced libraries\"],\"UOMT7z\":[\"This option is disabled because it would calculate a schedule that is too long.\"],\"URmyfc\":[\"Details\"],\"UXC1jS\":[\"NodeJS: \",[\"0\"]],\"UYUgdb\":[\"Order\"],\"UYW9jU\":[\"Successfully ran system fixer \",[\"fixerId\"]],\"Uf/h/w\":[\"Pick specific programming to remove from the channel.\"],\"UirGxE\":[\"Errors\"],\"UnI8zh\":[\"Channel #\",[\"0\"]],\"UweSf9\":[\"Add Channel Redirect\"],\"V8B1wG\":[\"Last synced \",[\"0\"]],\"V9UVpb\":[\"Total hits: \",[\"0\"]],\"VBsY8N\":[\"Set to 0 to never delete backups\"],\"VIHbrI\":[\"Advanced options relating to transcoding. In general, do not change these unless you know what you are doing! These settings exist in order to leave some parity with the old dizqueTV transcode pipeline as well as to provide mechanisms to aid in debugging streaming issues.\"],\"VP2oPP\":[\"Slots\"],\"VVAgOP\":[\"Rescan Interval (hours)\"],\"VXdzY3\":[\"Disable Hardware Encoding\"],\"Va3xJe\":[\"Add field\"],\"VfWz27\":[\"Weight %\"],\"VlEnCC\":[\"Archive Format\"],\"VlWKwW\":[\"Lazy\"],\"Vmvp5H\":[[\"count\",\"plural\",{\"one\":[\"day\"],\"other\":[\"days\"]}]],\"VrBtVn\":[\"Backups:\"],\"Vw5EeW\":[\"Enable Backups\"],\"VyUuZb\":[\"Image URL\"],\"WAakm9\":[\"Delete Channel\"],\"WDgJiV\":[\"Scanner\"],\"WGkxNZ\":[\"Error querying Plex. Check console log and consider reporting a bug!\"],\"WKHqM+\":[\"Weight\"],\"WMQchs\":[\"Audio Buffer Size\"],\"WT1Ibn\":[\"Last run\"],\"Wb3E4g\":[\"Run now\"],\"Weq9zb\":[\"General\"],\"WhJZoS\":[\"Choose the transcode configuration to use for this channel. Configure transcode configurations on the <0>FFmpeg settings page.\"],\"WjUHH8\":[\"Movie Sort\"],\"WnW1QF\":[[\"block\"],\" Hours\"],\"WzNAIP\":[[\"0\",\"plural\",{\"one\":[\"Hour\"],\"other\":[\"Hours\"]}]],\"X0mSqw\":[\"Will force use of a software filters (e.g. scale, pad, etc.) despite hardware acceleration settings.\"],\"X9EHMa\":[\"Editing Smart Collection \\\"\",[\"0\"],\"\\\"\"],\"XDT85c\":[\"Media Sources\"],\"XIgmo9\":[\"Did not receive an accessToken or userId from Jellyfin server.\"],\"XNtsE7\":[\"Calculating Slots...\"],\"XNw99A\":[\"Software (No GPU)\"],\"XOgcN3\":[\"Filler List: \",[\"0\"]],\"XOuE6F\":[\"This could cause the following slot's programs to go unscheduled. Possible solutions include:\"],\"XSkU3F\":[\"* Restart required\"],\"XWYqJx\":[\"Duplicate Channel\"],\"XXwX66\":[\"Set the log level for the Tunarr server.<0/>Selecting <1>\\\"Use environment settings\\\" will instruct the server to use the <2>LOG_LEVEL environment variable, if set, or system default \\\"info\\\".\"],\"XePUKr\":[\"Test Transcode\"],\"XhWvkJ\":[[\"0\"],\" of \",[\"1\"],\" \",[\"2\"],\" exceed the length of this slot (\",[\"3\"],\"). Average program length: \",[\"4\"]],\"Xkppm4\":[\"Enable Watermark\"],\"Xm/WEQ\":[\"Channel Group\"],\"XsR2HX\":[\"Test Duration (seconds)\"],\"Xuml3I\":[\"By default, time slots are time of the day-based, you can change it to time of the day + day of the week. That means scheduling 7x the number of time slots. If you change from daily to weekly, the current schedule will be repeated 7 times. If you change from weekly to daily, many of the slots will be deleted.\"],\"XwU6BE\":[\"You haven't created any filler lists yet! Go to the <0>Filler Lists page to create one.\"],\"Y2ngGV\":[\"Add a Filler List\"],\"Y5XZLy\":[\"<0>Pad Slot: Align slot start times to the specified pad time.<1/><2>Pad Episode: Align episode start times (within a slot) to the specified pad time. <3>NOTE: Depending on slot length and the chosen pad time, this could potentially create a lot of flex.\"],\"Y84UgQ\":[\"Loudness Target\"],\"YAKCkm\":[\"An error occurred: \",[\"0\"]],\"YDlcs3\":[\"Shuffle Programming\"],\"YLUnu0\":[\"Test Playback\"],\"YN7vx3\":[\"Custom Show\"],\"YRQaPv\":[\"Last Synced\"],\"YRT1+e\":[\"Creates a new collection\"],\"YSptU0\":[\"Replicate...\"],\"YT5/eK\":[\"Media Source: \\\"\",[\"0\"],\"\\\"\"],\"YXwR3a\":[\"Restore default logo\"],\"YY/JN7\":[\" the following day.\"],\"YYLNVW\":[\"Insert breaks at these percentages of the program duration\"],\"YdIZFA\":[\"This channel number has already been used\"],\"Yf/Mtb\":[\"You're All Set!\"],\"Z10t2U\":[\"Removes repeated programs.\"],\"Z3FXyt\":[\"Loading...\"],\"Z4IQ8m\":[\"Channel Transcode Config\"],\"Z5IrB3\":[\"Open in \",[\"0\"]],\"Z6dMWq\":[\"Error while running system fixer \",[\"fixerId\"],\". Check server logs for details.\"],\"ZND/fh\":[\"Cannot be empty\"],\"ZNZzTe\":[\"Cannot disable libraries when they are locked\"],\"ZShzvn\":[\"\\\"\",[\"0\"],\"\\\" Live\"],\"ZWRt1W\":[\"Output Path\"],\"ZkdKVr\":[\"Redirect to Channel \",[\"0\"]],\"Zky8hA\":[\"The image will be rendered at its actual size without any scaling applied.\"],\"Zs2GWW\":[\"New Emby Media Source\"],\"Zul8Ry\":[\"never\"],\"Zvipe1\":[\"Editing Plex Server \\\"\",[\"0\"],\"\\\"\"],\"ZxwuFV\":[\"Deleting a Channel will remove all programming from the channel. This action cannot be undone.\"],\"a+Pr3s\":[\"Apply to Program Types (empty = all)\"],\"a4N/Bg\":[\"Load More\"],\"aE3UMm\":[\"<0>None: slots are picked in the order they are specified in the table (i.e. not randomly)<1/><2>Uniform: all slots have an equal chance to be picked.<3/><4>Weighted: each slot is picked with a specified probability\"],\"aOaCIk\":[\"Allow External\"],\"aScBGS\":[\"Add a filter expression to fine-tune results of the search\"],\"aSwfbR\":[\"Unit\"],\"ak3N0i\":[\"Item was not present during the last scan\"],\"aoLy25\":[\"Opacity\"],\"b0Uv6P\":[[\"0\",\"plural\",{\"one\":[\"Path\"],\"other\":[\"Paths\"]}]],\"b6sx4K\":[\"No active sessions\"],\"bDY29m\":[\"Logarithmic\"],\"bGG6B1\":[\"Jellyfin\"],\"bHNlfr\":[\"Increasing the slot duration.\"],\"bNEQeI\":[\"Cooldown\"],\"bORfbY\":[\"Cannot use a channel number <= 0\"],\"bPJiZF\":[\"Show: \",[\"0\"]],\"bSIBDb\":[\"Release Date (asc)\"],\"bm8pgG\":[\"Add group\"],\"boItSp\":[\"Delete Media Source?\"],\"buS8nL\":[\"Enable Subtitles\"],\"bxyuno\":[\"Override global audio and subtitle settings for this channel.\"],\"bydide\":[\"FFMPEG Log Method\"],\"c6fsNw\":[\"When enabled, intermittent watermarks fade in immediately when a stream is initialized. When disabled, the first watermark fade-in occurs after a full period.\"],\"cF5KzV\":[\"Edit Filler List\"],\"cFTdM+\":[\"Console\"],\"cHYx4E\":[\"Empty Trash\"],\"cLgGtf\":[\"Reset programming to most recently saved state\"],\"cN5Dty\":[\"No Programming scheduled\"],\"cOvZFM\":[\"Dynamic\"],\"cXkSYc\":[\"There was an error submitting the request to update Media Source settings. Please check the form and try again\"],\"caSM6R\":[\"This is used by iptv clients to categorize the channels. You can leave it as 'tunarr' if you don't need this sort of classification.\"],\"cgo+Ch\":[[\"remainingTime\"],\" left\"],\"cheWPw\":[\"Duplicates\"],\"cjX7aq\":[\"Are you sure you want to delete Smart Collection \\\"\",[\"0\"],\"\\\"?\"],\"cmKYIw\":[\"Overflow Behavior\"],\"cmlWKg\":[\"<0>Error deleting custom show: \",[\"0\"],\"<1/>Please consider opening a bug with details!\"],\"cnCAaO\":[\"Percentage-Based\"],\"cnGeoo\":[\"Delete\"],\"cv/ykT\":[\"Search Server URL:\"],\"cxrM1O\":[\"Connect Sources\"],\"d5zxa4\":[\"Local\"],\"d72gcv\":[\"Loudnorm Options\"],\"d9HhJj\":[\"This media source has no enabled or scanned libraries. Enable libraries for this source on the <0>Media Sources page or manually trigger scans on the <1>Library page.\"],\"d9Tsiy\":[\"Error updating channel.<0/>Check browser console for details\"],\"d9XR+x\":[\"Transcode Config <0> <1/>\"],\"dBV/FP\":[\"Lock Weights\"],\"dDX6oS\":[\"Videos from the filler list will be randomly picked to play unless there are cooldown restrictions to place or if no videos are short enough for the remaining Flex time.<0/>Each filler can be assigned a cooldown, which restricts how frequently the list will be chosen during flex time.\"],\"dEgA5A\":[\"Cancel\"],\"dH8AwH\":[\"Add Breaks\"],\"dK3Z9j\":[\"Component\"],\"dQvGiF\":[[\"0\",\"plural\",{\"one\":[\"#\",\" session\"],\"other\":[\"#\",\" sessions\"]}]],\"dScixt\":[\"Enable dark Mode\"],\"dUyQn5\":[\"On-Demand\"],\"daSf8d\":[\"Group episode programs by their show.\"],\"djpQ8z\":[\"Reload Stream\"],\"dkURuB\":[\"Tail Buffer (minutes)\"],\"dnCwNB\":[\"Successfully copied to clipboard!\"],\"eARDm/\":[[\"0\",\"plural\",{\"one\":[\"#\",\" season\"],\"other\":[\"#\",\" seasons\"]}],\", \",[\"1\",\"plural\",{\"one\":[\"#\",\" total episode\"],\"other\":[\"#\",\" total episodes\"]}]],\"eEpDfJ\":[\"Will force use of a software decoder despite hardware acceleration settings.\"],\"eNorwJ\":[\"Programs Too Long\"],\"ePK91l\":[\"Edit\"],\"eSsduj\":[\"VA-API Device\"],\"eZTFiP\":[\"Review Selections\"],\"eZe0fr\":[\"Audio Channels\"],\"ecUA8p\":[\"Today\"],\"efuwN9\":[\"These settings are stored in your browser and are saved automatically when changed.\"],\"eg6m1K\":[\"Edit Transcode Config: \\\"\",[\"0\"],\"\\\"\"],\"ep+NHZ\":[\"If you proceed, all unsaved changes will be lost. Are you sure you want to proceed?\"],\"et+mIi\":[\"Troubleshoot\"],\"euChZN\":[\"Cyclic Shuffle\"],\"euc6Ns\":[\"Duplicate\"],\"exYcTF\":[\"Library\"],\"eyRsaH\":[\"Root\"],\"f0w0IC\":[\"Leave blank to use the channel's icon.\"],\"f6Hub0\":[\"Sort\"],\"f6pgxW\":[\"Temporarily caches responses from Plex based by request path. Could potentially speed up channel editing.\"],\"f7DWm5\":[\"Need at least one path\"],\"fD+lMD\":[\"Select the port the Tunarr server will listen on. This requires a server restart to take effect.\"],\"fI+mNw\":[\"Playlists\"],\"fJfo1A\":[\"Server Path\"],\"fN4bgn\":[\"Delete Filler List \\\"\",[\"0\"],\"\\\"?\"],\"fQ9phi\":[\"Remove All\"],\"fSRZCh\":[\"Restore Default Settings\"],\"fU1065\":[\"Mid-Roll\"],\"fWj7Tt\":[\"Shuffle programming in a channel, optionally grouping programs by certain criteria.\"],\"fcqkKg\":[\"Not found!\"],\"fsBGk0\":[\"Balance\"],\"ftF4U5\":[\"Show Advanced\"],\"fxTyFe\":[\"This slot is linked with \",[\"0\"],\" other \",[\"1\",\"plural\",{\"one\":[\"slot\"],\"other\":[\"slots\"]}],\"Content fields are shared across the group.\"],\"fyo+NB\":[\"The End.\"],\"fzWV5a\":[\"Sort TV Shows (desc)\"],\"g2Pro3\":[\"Reset changes made to the channel's lineup\"],\"g6LxbB\":[\"Break Interval (minutes)\"],\"g7LzUS\":[\"Install FFMPEG\"],\"gBx20d\":[\"Custom Program\"],\"gH5Gbn\":[\"Shuffle\"],\"gJrGqR\":[\"FFmpeg version 7.1+ recommended. Check your current version in the sidebar\"],\"gL9DoB\":[\"Programs shorter than this value will be treated the same as Flex time. Meaning that the TV Guide will try to meld them with the previous program or display the block of programs as the \\\"place holder program\\\" if they make a large continuous group. Use 0 to disable this feature or use a large value to make the channel report only the placeholder program and not the real programming.\\n\",[\"0\"]],\"gR/hgc\":[\"Error Audio\"],\"gcD6jw\":[\"Hide watermark during filler\"],\"gf/bM4\":[\"Continue with New Content\"],\"gg9/ya\":[\"Remove \",[\"count\"],\" \",[\"0\"]],\"ghGSuE\":[\"Ensures programs have a nice-looking start time, it will add Flex time to fill the gaps.\"],\"glVpbE\":[\"Eager\"],\"h/qU8b\":[\"Override the default \",[\"0\"],\" device path (defaults to <0>/dev/dri/renderD128 on Linux and blank otherwise)\"],\"h4yKYk\":[\"Next run\"],\"h8WhoR\":[\"Slot Scheduler\"],\"hBGuBW\":[\"Use channel default\"],\"hBzeL7\":[\"Time before first break\"],\"hG89Ed\":[\"Image\"],\"hISVAG\":[\"Media Sources are where Tunarr sources your content. Media can come from your filesystem or a remote server, like Plex or Jellyfin. At least one Media Source is necessary to create channels and play media in Tunarr.\"],\"hQRttt\":[\"Submit\"],\"hQSabA\":[\"TO\"],\"hXfj39\":[\"Audio Sample Rate\"],\"hXzOVo\":[\"Next\"],\"hYgDIe\":[\"Create\"],\"he3ygx\":[\"Copy\"],\"hehnjM\":[\"Amount\"],\"hhukVU\":[\"Trashed items are items that were previously scanned, but not found in a recent scan. This could be due to missing files or a media server no longer returning the item from its API. These items will be unplayable in channels in their current state. When the trash is emptied, their spots in channels will be replaced with flex.\"],\"hjerov\":[\"Guide Start Time\"],\"hlIKor\":[\"None:\"],\"hnFEC+\":[\"Initial Delay + Interval\"],\"hrdWlG\":[\"Add Show\"],\"hvo+jE\":[\"Add point (%)\"],\"i1+yww\":[\"FFprobe version 6.0+ recommended. Check your current version in the sidebar\"],\"i2QuB6\":[\"Error Screen\"],\"i9rcQ/\":[\"Movies\"],\"iH8pgl\":[\"Back\"],\"iQWhqk\":[\"FFMPEG is installed. Detected version \",[\"0\"]],\"iTjV+L\":[\"A-Z (desc)\"],\"iXJkMB\":[\"Cooldown (s)\"],\"ih+n6S\":[\"Linear\"],\"ihCTE6\":[\"Error occurred while loading channels, please try again soon.\"],\"ihn4zD\":[\"Search…\"],\"ilkCYA\":[[\"0\",\"plural\",{\"one\":[\"Selected Item\"],\"other\":[\"Selected Items\"]}]],\"imrPBy\":[\"Watermark Image URL\"],\"isC0OF\":[\"Use these settings to override global ffmpeg settings for this channel.\"],\"isRobC\":[\"New\"],\"isyw73\":[\"Auto uses the time convention for the selected language.\"],\"jETaUB\":[\"Buffer size effects how frequently ffmpeg reconsiders the output bitrate. <0>Read more\"],\"jHjfnS\":[\"Add filler\"],\"jZlrte\":[\"Color\"],\"jl3Q84\":[\"Create a Channel\"],\"jz1oG0\":[\"Selected Audio\"],\"k6TRai\":[\"FFMPEG transcoding is required for some features like channel overlay, subtitles, and measures to prevent issues when switching episodes.\"],\"kAidIP\":[\"Failed to load feature flags.\"],\"kBJRjR\":[\"Download all logs\"],\"kIYDzY\":[\"Successfully updated Media Source settings.\"],\"kKgsI0\":[\"<0>Configure the directory where Tunarr writes HLS segment files when transcoding. Tunarr will create the target directory (but not intermediate directories) if it doesn't exist.<1/>Changing this field will only affect new sessions. Existing sessions will continue writing to the previous setting, but will clean out segments when the segment ends.<2/>When unset, Tunarr will write segments to its current working directory.\"],\"kKk153\":[\"Load Stream\"],\"kO0aVB\":[\"Break Duration (minutes)\"],\"kThBL9\":[\"Sample rate cannot be changed when copying input audio\"],\"kdkZBD\":[\"Increment\"],\"kii1WH\":[\"Programming Preview\"],\"kolyzq\":[\"This \",[\"0\"],\" is marked as missing in the database.\"],\"kpfZ0g\":[\"Minimum Program Duration (minutes)\"],\"kq6sAD\":[\"Add TV Shows or Movies to filler\"],\"ksFZi3\":[\"<0>Experimental: Enable Plex Request Cache\"],\"kvMAno\":[\"Web Settings\"],\"l/UFPv\":[\"Properties\"],\"l0VyMh\":[\"Flex\"],\"l15zKW\":[\"All Set!\"],\"lBADOx\":[[\"count\",\"plural\",{\"one\":[\"#\",\" episode\"],\"other\":[\"#\",\" episodes\"]}]],\"lC2oeQ\":[\"Max Duration (minutes)\"],\"lCF0wC\":[\"Refresh\"],\"lIUgjN\":[\"Error copying channel m3u link to clipboard\"],\"lJSUC1\":[\"Watermark\"],\"lKCfnI\":[\"Audio Language Preferences\"],\"lS14fB\":[\"Theme Settings\"],\"lW3FB1\":[\"Download last \",[\"0\"],\" \",[\"1\",\"plural\",{\"one\":[\"#\",\" row\"],\"other\":[\"#\",\" rows\"]}]],\"lWmRHf\":[\"Time Slots...\"],\"lZMqZ5\":[\"If enabled, TV show episodes will use the poster of their show, instead of the individual episode poster.\"],\"laQT4o\":[\"Thumbnail URL\"],\"lfFsZ4\":[\"Channels\"],\"lkz6PL\":[\"Duration\"],\"llDXYJ\":[\"Backups\"],\"lnABVQ\":[\"Run Troubleshooter\"],\"m+8qnB\":[\"Library: \",[\"0\"]],\"m0Gp21\":[\"Select a program and channel to test playback. The troubleshooter will analyze stream selection, build the FFmpeg pipeline, and run a short test transcode.\"],\"m16xKo\":[\"Add\"],\"m48LOH\":[\"Hardware Acceleration\"],\"mCB6Je\":[\"Select All\"],\"mDcLzR\":[\"Caching\"],\"mF+u2B\":[\"Don't see the library you want here? Ensure it is enabled in the <0>Media Source Settings.\"],\"mGM6Aa\":[\"Custom Shows are sequences of videos that represent a episodes of a virtual TV show. When you add these shows to a channel, the schedule tools will treat the videos as if they belonged to a single TV show.\"],\"mHTMS1\":[\"Normalize Frame Rate\"],\"mQt7fl\":[[\"count\",\"plural\",{\"one\":[\"program\"],\"other\":[\"programs\"]}]],\"mRWiYM\":[\"Duration (seconds)\"],\"mWbpso\":[\"Max Backups\"],\"mYBORk\":[\"Movie\"],\"mYJG1x\":[\"Your list will be replicated \",[\"0\"],\" times\"],\"mZFYjJ\":[\"Error saving programs. \",[\"0\"]],\"mZFr14\":[\"HLS not supported in this browser!\"],\"md42bg\":[\"Transcode Config (optional override)\"],\"mgcp8D\":[\"How often to insert a break\"],\"migeCK\":[\"Filter which subtitle tracks are considered<0/><1>Any: All subtitle tracks are considered <2/><3>Forced: Only consider <4>\\\"forced\\\"subtitle tracks <5/><6>Default: Only consider default subtitle tracks <7/><8>None: Do not select any subtitles\"],\"mtQjGe\":[\"Configure subtitle preferences. Preferences are evaluated in order of priority. The first matching subtitle stream on a program will be used.\"],\"mvU6s8\":[\"Sort TV Shows\"],\"mwtge0\":[\"Started \",[\"startedAgo\"],\" - \",[\"remainingTime\"],\"remaining\"],\"n+7HJk\":[\"When file paths on the remote server differ from the paths Tunarr can see, use Path Replacements to instruct Tunarr how to stream media from disk.\"],\"n9nSNJ\":[\"Time format\"],\"nH6YaM\":[\"Other Videos\"],\"nSW2Lv\":[[\"days\",\"plural\",{\"one\":[\"#\",\" day\"],\"other\":[\"#\",\" days\"]}]],\"nV6twc\":[\"Organize\"],\"nYD/Cq\":[\"Ascending\"],\"nZXc7r\":[\"Unlink from group\"],\"nfAddt\":[\"FFmpeg Transcode Path\"],\"nfxRnc\":[\"Tunarr is currently configured to use the AC3 audio encoder. This audio format is not supported by browsers. The resultant stream will likely not have audio or will not play at all.\"],\"njIcYs\":[\"Save as new collection…\"],\"ntJ9rt\":[\"HLS Direct Output Format\"],\"nzDzPp\":[\"toggle access token visibility\"],\"o0+Ul2\":[\"Add Flex\"],\"o2Ucvk\":[\"Libraries\"],\"o6OQlp\":[\"Edit Channel\"],\"o7J4JM\":[\"Filter\"],\"o7Y4WO\":[\"Error saving new Emby server. See browser console and server logs for details\"],\"oADXRC\":[\"Calculated \",[\"humanizedDuration\"],\" (\",[\"numShows\"],\" programs) of programming in \",[\"duration\"],\"ms\"],\"oCHfGC\":[\"Level\"],\"oCpfQF\":[\"This feature is currently experimental. Proceed with caution and if you experience an issue, try disabling caching.\"],\"oEZmaP\":[[\"count\",\"plural\",{\"one\":[\"#\",\" season\"],\"other\":[\"#\",\" seasons\"]}]],\"oMA2jd\":[\"Removes any specials from the schedule. Specials are episodes with season '00'.\"],\"oPWgse\":[\"Maximum number of breaks per program (0 = unlimited)\"],\"ofUcbc\":[\"Random\"],\"oihuQr\":[\"Number of Replications\"],\"ousf2V\":[\"Random…\"],\"ovBPCi\":[\"Default\"],\"oxvBx3\":[\"If set, any programming group with fewer episodes will be looped in order to make perfectly even blocks.\"],\"p/78dY\":[\"Position\"],\"p/KgUp\":[\"The channel's regular programming between the specified hours. Flex time will fill up the remaining hours.\"],\"p04z/V\":[\"# Programs\"],\"p4XZFD\":[\"Local Path\"],\"pDwcFl\":[\"Save Smart Collection\"],\"pKYBXC\":[\"Last Scheduled Execution\"],\"paEQ75\":[\"\\\"Stealth\\\" channels are hidden from TV guides, spoofed HDHR, m3u playlist, etc. The channel can still be streamed directly or be used as a redirect target.\"],\"pcRxi1\":[\"How frequently libraries should be scanned (starting from midnight).\"],\"pdlmIS\":[\"<0>Error deleting filler list: \",[\"0\"],\"<1/>Please consider opening a bug with details!\"],\"pkERVr\":[\"Download JSON\"],\"pqarBu\":[\"Asc\"],\"pvnfJD\":[\"Dark\"],\"pwPreK\":[\"Restrict Hours\"],\"pxh+PI\":[\"Builder\"],\"q6GKgP\":[\"VAAPI Capabilities\"],\"q6nlo/\":[\"Subtitle Action\"],\"q9p3Xw\":[\"Bitrate cannot be changed when copying input audio\"],\"qAGp2O\":[\"Proceed\"],\"qG6T/X\":[\"Add Programming\"],\"qKNcv7\":[\"Generating Bug Report Link...\"],\"qV9xkb\":[\"Passthrough audio unchanged. Other settings will not apply.\"],\"qiXmlF\":[\"Add Media\"],\"qjW34v\":[\"This channel is set up to use <0>\",[\"0\"],\"Slots for programming. Any manual changes on this page will likely make this channel stop adhering to that schedule.\"],\"qlR1dD\":[\"Delete Channel \\\"\",[\"0\"],\"\\\"?\"],\"qs/mhD\":[\"Ensures programs start only at a particular interval within the hour. This makes for nice looking schedules. Flex time is scheduled to facilitate.\"],\"r3ptXC\":[\"Manually add an access token from your Jellyfin server\"],\"r9sc/0\":[\"Duration must be numeric\"],\"rAx5u1\":[\"End Time\"],\"rPEEWz\":[\"Successfully saved config!\"],\"rSZlvN\":[\"Programming Start\"],\"rhEkXj\":[\"Head\"],\"rl/8FN\":[\"Commit\"],\"rnbEQB\":[\"Copy M3U URL\"],\"roIf2/\":[\"On-Demand?\"],\"rtDDIV\":[\"Edit Slot\"],\"ru5qTc\":[\"Edit Media Source\"],\"rx5Ria\":[\"All lists are used\"],\"rxumR2\":[\"Match any of\"],\"s2OE0W\":[\"Enter a name for your Jellyfin Server\"],\"s4iETe\":[\"Transcode Config\"],\"s6lNC3\":[\"Fallback Mode\"],\"s8zbIS\":[\"Include Seasons\"],\"sA8Jt7\":[\"This slot replays content aired by continue slots earlier in the period.\"],\"sBJ5MF\":[\"Sources\"],\"sNnXh6\":[\"Order of programming within the slot\"],\"sUtIRs\":[\"about \"],\"sVVcvs\":[\"Experimental Features\"],\"sfbjgG\":[\"Audio Format\"],\"sxkWRg\":[\"Advanced\"],\"sxwNOp\":[\"Logs Directory:\"],\"sztQMJ\":[\"Programs a Flex time slot. Normally you'd use pad times, restrict times or add breaks to add a large quantity of Flex times at once, but this exists for more specific cases.\"],\"t/YqKh\":[\"Remove\"],\"t3hvHq\":[\"Sync Now\"],\"t5q6kk\":[\"For more details on manually retrieving a Plex token, see <0>here\"],\"t6+QCF\":[[\"count\"],\" \",[\"programLabel\"],\", \",[\"0\"]],\"t8Hzw3\":[\"Cyclic Shuffle randomly shuffles groups of programming.\"],\"tDuQbQ\":[\"Stream Mode\"],\"tEvsql\":[\"Subtitles\"],\"tH1aCG\":[\"Video Bitrate\"],\"tMxWK0\":[\"Adds Flex breaks after each TV episode or movie to ensure that the program starts at one of the allowed minute marks. For example, you can use this to ensure that all your programs start at either XX:00 times or XX:30 times. Removes any existing Flex periods before adding the new ones. This button might be disabled if the channel is already too large.\"],\"tPGTPB\":[\"Roll the log file on a fixed schedule, regardless of file size.\"],\"tRgOE5\":[\"Balance Programming\"],\"tXkhj/\":[\"Start\"],\"tXub8j\":[\"Display Watermark on Leading Edge\"],\"tYuxvA\":[\"FFMPEG\"],\"tfDRzk\":[\"Save\"],\"tgPwON\":[\"Operator\"],\"ti6ugP\":[\"Error while saving transcode config. See console log for details.\"],\"tkDYSE\":[[\"hours\",\"plural\",{\"one\":[\"#\",\" hour\"],\"other\":[\"#\",\" hours\"]}]],\"tlMRNb\":[\"The loaded version of the Tunarr UI does not match the server. Reload the browser to get the latest. If this message persists, clear your browser cache and reload.\"],\"tlNobE\":[\"Custom Show: \",[\"0\"]],\"tlmh8e\":[\"Add all selected programs to channel\"],\"tsqRRB\":[[\"0\"],\" Poster\"],\"ty8rVI\":[\"Now Playing:\"],\"tzwArf\":[\"View in \",[\"0\"]],\"u+VWhB\":[\"Copied to clipboard!\"],\"u+zFIr\":[\"Restrict search fields\"],\"uAQUqI\":[\"Status\"],\"uHTa9V\":[\"To use Tunarr, you need to first connect a media source. This will allow you to build custom channels with your content.\"],\"uLiDe/\":[\"Enable embedded subtitle extraction\"],\"uUTf8r\":[\"Delete Custom Show \\\"\",[\"0\"],\"\\\"?\"],\"uamufO\":[\"Add TV Shows or Movies to programming list.\"],\"ueG1bp\":[\"Program Count\"],\"ueLbrY\":[\"If true, adjusting the weight of one slot will scale the weights of other slots such that all weights total 100%. Otherwise, weights can be adjusted freely and the weight of each slot is only relative to the total weight.\"],\"uixVel\":[\"By default, saves backups in the server's run directory, or, if running in Docker, to /config/tunarr/backups\"],\"uyR9ei\":[\"Block Shuffle\"],\"v4nbQ4\":[\"If no more programs can fit into a duration-based slot, flex time is added to fill the gap. This setting determines how flex is added <0>within the slot to ensure all time is filled.<1/><2>Between: Flex time is added between videos within a slot, if there are multiple<3/><4>End: Flex time is added at the end of the slot\"],\"v5IstB\":[\"after every program\"],\"v5URfV\":[\"Like Random Shuffle, but tries to preserve the sequence of episodes for each TV show. If a TV show has multiple instances of its episodes, they are also cycled appropriately.\"],\"vAK/B1\":[\"Audio Action\"],\"vCBet9\":[\"Not a valid number\"],\"vERlcd\":[\"Profile\"],\"vGRvxs\":[\"Channel group is required\"],\"vLf7qg\":[\"Interval (minutes)\"],\"vSJd18\":[\"Video\"],\"vU/Hht\":[\"Distribution\"],\"vXIe7J\":[\"Language\"],\"vcvFVw\":[\"Escape Hatches\"],\"vkA4W/\":[\"Source Type\"],\"vn3SVH\":[\"Could not parse this filter expression. Check the <0>documentation for information about filter expressions.\"],\"vreTxe\":[[\"count\",\"plural\",{\"one\":[\"#\",\" program\"],\"other\":[\"#\",\" programs\"]}]],\"vwFKu0\":[\"Cast & Crew\"],\"vyL1gO\":[\"Release Date (desc)\"],\"w/bY7R\":[\"Logs\"],\"w2pCRr\":[\"Show:\"],\"w3KBq0\":[\"Allows programs to play a bit late if the previous program took longer than usual. If a program is too late, Flex is scheduled instead.\"],\"w3g+lo\":[\"Let's get started...\"],\"wBmIEf\":[\"Number of hours to include in the XMLTV file\"],\"wBo/7A\":[\"Error while scheduling \",[\"taskId\"],\". Check server logs for details\"],\"wKClDM\":[\"Adds a channel redirect. During this period of time, the channel will redirect to another channel.\"],\"wMHvYH\":[\"Value\"],\"wOUKOZ\":[\"Max True Peak\"],\"wZOYCY\":[\"Video Format\"],\"wdfBIP\":[\"Sort By...\"],\"wdxz7K\":[\"Source\"],\"wkQ2tb\":[\"Adds Flex breaks after each TV episode or movie to ensure that the program starts at one of the allowed minute marks.\"],\"wlYdUk\":[[\"count\",\"plural\",{\"one\":[\"hour\"],\"other\":[\"hours\"]}]],\"wpT1VN\":[\"Condition\"],\"wtuVU4\":[\"Frequency\"],\"wwu18a\":[\"Icon\"],\"x+AjXa\":[\"Channel Fallback\"],\"x/dwZe\":[\"Enable if the watermark is an animated GIF or PNG. The watermark will loop according to the image's configuration. If this option is enabled and the image is not animated, there will be playback errors.\"],\"x1tGMH\":[\"Override how programs within this slot are padded.\"],\"x6/Zc6\":[\"Tail\"],\"x63PSs\":[\"Search for shows\"],\"x7PDL5\":[\"Logging\"],\"xCJdfg\":[\"Clear\"],\"xDAtGP\":[\"Message\"],\"xDPFrK\":[\"Scan \",[\"0\"]],\"xGVfLh\":[\"Continue\"],\"xGYZfl\":[\"Edit Libraries\"],\"xIn7qU\":[\"Disable Hardware Decoding\"],\"xJIepX\":[\"Default Config\"],\"xOkMus\":[\"Hardware Accel.\"],\"xPmesF\":[\"Loudness Range Target\"],\"xQC5se\":[\"Advanced Video Options\"],\"xXrtPO\":[\"Failed to load item details! Check logs for details\"],\"xazqmy\":[\"Seasons\"],\"xbtgIC\":[\"HW Acceleration\"],\"xdA/+p\":[\"Tools\"],\"xmBknQ\":[\"Filler Lists\"],\"xptXTM\":[\"Select Artists to Remove\"],\"xqIrnW\":[\"Library Clip (not yet implemented)\"],\"xu3Kah\":[[\"0\",\"plural\",{\"one\":[\"#\",\" program\"],\"other\":[\"#\",\" programs\"]}]],\"y28hnO\":[\"Post\"],\"y4Jmre\":[\"Break Duration\"],\"y4iKY3\":[[\"count\",\"plural\",{\"one\":[\"#\",\" album\"],\"other\":[\"#\",\" albums\"]}]],\"y5x0aB\":[[\"0\"],\" Info\"],\"y7wpam\":[[\"value\",\"plural\",{\"one\":[\"#\",\" program\"],\"other\":[\"#\",\" programs\"]}]],\"yDUcwc\":[\"Manually add an access token from your Emby server\"],\"yPE51X\":[\"Configure transcoding settings for Tunarr's streams. Each channel is assigned one transcode configuration.\"],\"yPK7+5\":[\"Auto-Update Guide\"],\"yQE2r9\":[\"Loading\"],\"yRkqG9\":[\"Limit\"],\"yX8Rkw\":[\"Add All\"],\"yftDqj\":[\"New Filler List\"],\"yjzkvk\":[\"Stop Transcode Session\"],\"ysJk7v\":[\"Movie Sort Order\"],\"ysecYP\":[\"Search for a program\"],\"ytXxnP\":[\"Forced\"],\"yz/C2/\":[\"Rerun\"],\"yz7wBu\":[\"Close\"],\"z4K9d+\":[\"Roll based on size\"],\"z61uNR\":[\"Add Flex Time\"],\"zV6tsp\":[\"Consolidate\"],\"zV9awV\":[\"Force Scan\"],\"zpylsE\":[\"Transcoding Settings\"],\"zrmjn/\":[\"Max Duration\"],\"zthKEs\":[\"The streaming mode affects the type of underlying transcoding process used to create the channel's video stream.<0/>Learn more about Tunarr's stream modes <1>here!\"],\"zvjEp6\":[\"Filler cooldown must be a number\"],\"zx4BuL\":[\"Week\"],\"zyLvkd\":[\"Category Log Levels\"]}")as Messages; \ No newline at end of file + import type { Messages } from '@lingui/core'; +export const messages = JSON.parse( + '{"++nzCr":["Bit Depth"],"+2JHIs":["Link to existing slot"],"+406Vu":["View Full Details"],"+4YwQF":["# of Programs"],"+4mjS6":["Remove icon"],"+9EErD":["Music Videos"],"+DmLct":["Programs"],"+SA5Ao":["A root path to scan for media. Local sources can search many different paths."],"+TZiPJ":["Server is unreachable"],"+UPOiB":[["count","plural",{"one":["min"],"other":["mins"]}]],"+Xg5cX":["Filler is picked fresh at stream time like Flex time. The guide shows \\"Commercial Break\\" placeholders."],"+YdE7b":["Enable rolling log files using time and/or size based criteria"],"+hl/7A":["Channels configured to use the HLS Direct stream mode will output in the selected container format."],"+k9lxR":["Enter a name for your Local Media Source"],"+mdNfU":[["count","plural",{"one":["#"," track"],"other":["#"," tracks"]}]],"+suWTj":["Adds Flex breaks between programs, attempting to avoid groups of consecutive programs that exceed the specified number of minutes."],"+tlhMz":["Plex (Manual)"],"+yEE7s":["New Media Source"],"+yOcRn":["HDHR"],"+ya1pX":["Delete Slot"],"+zY9Xc":["Configure Cyclic Shuffle"],"+zy2Nq":["Type"],"/+ZaFm":["Soundtrack"],"/4gGIX":["Copy to clipboard"],"/6iIT9":["Settings Saved!"],"/DTWjr":["Congrats, you\'re ready to start building channels! Just click Finish below to start working on your first channel."],"/QmYEW":["Balance..."],"/TEOcd":["Presets"],"/e88IO":["Schedule programming in blocks that are either count or duration based. Can be used to generate random schedules."],"/gavzH":["Basic button group"],"/j3jjC":["Error while saving settings. Please check console for details."],"/n/HCO":["Keywords"],"/rTz0M":["Audio"],"/vJase":["Streaming"],"09gg05":["Programming"],"0IAEaX":["Match"],"0MWZh1":["Search is currently scoped to this Media Source Library."],"0VHz2s":["Filler Options"],"0cULRy":["Experimental: Make perfect schedule loop"],"0dy9K6":["Read Less"],"0mEBXY":["Delete Transcoding Config \\"",["0"],"\\"?"],"0wJVK+":["Basic"],"0zpgxV":["Options"],"1/dAym":["Grouping works as follows:"],"14PdY0":["Config"],"1AdBl9":["Break Positioning"],"1BDPP1":["Looks like something went wrong."],"1BGQfg":["Alphabetically"],"1CFAQ+":["Set by environment variable"],"1DxLRi":["No programming scheduled for this time period"],"1PQRWr":["Start Time"],"1QfxQT":["Dismiss"],"1TYXl0":["Enter your Emby password to generate a new access token."],"1V3Prt":["Deleting a Filler will remove all programming from the channel. This action cannot be undone."],"1Z90J4":["Days to Precalculate"],"1hKEom":["Priority"],"1jqDmP":["Successfully scheduled ",["taskId"]," (running in background)."],"1njn7W":["Light"],"2BBAbc":["List"],"2BRPyl":["System Info"],"2CVuYr":["Smart Collection - ",["0"]],"2L7cj6":["You haven\'t created any channels yet."],"2QLniG":["Existing query: ",["filterString"]],"2eFlmt":["Tracks"],"2hOCU2":["Smart Collections"],"2imNg3":["Web version = ",["0"],", Server version = ",["1"]],"2mAJXf":["Makes multiple copies of the schedule and plays them in sequence. Normally this isn\'t necessary, because Tunarr will always play the schedule back from the beginning when it finishes. But creating replicas is a useful intermediary step sometimes before applying other transformations. Note that because very large channels can be problematic, the number of replicas will be limited to avoid creating really large channels."],"2oWehJ":["Reset to current date/time"],"2vxecF":["Show Stealth"],"2x4THe":["\\"",["0"],"\\" Sessions"],"312fSE":["Select Shows to Remove"],"315BhT":["Alphabetical"],"3JIYke":["Healthy?"],"3JQkm5":["Path Replacements"],"3JjdaA":["Run"],"3LfNqe":["Channel Number"],"3SH6Vv":["Copied channel \\"",["channelName"],"\\" m3u link to clipboard"],"3YNjnA":["System Environment"],"3b1vGb":["New Local Media Source"],"3mAQJI":["How often the XMLTV file is regenerated"],"3nLdaX":["Add ",["0"]],"3nwcC5":["Filler - ",["0"]],"49dCCB":["Use Show Poster"],"4Fpcxu":["Initial Delay (minutes)"],"4NbDEd":["Deleting a Custom Show will remove its programming from channels that use it. This action cannot be undone."],"4Uc/2h":["Server Listen Port"],"4VxpoP":["Music tracks are grouped by artist"],"4XSc4l":["Weekly"],"4XfYeY":["Random (by show)"],"4fLgiT":["Allow Image Based"],"4qmJK4":["Tunarr Backend URL"],"4wkwyL":["Disable Hardware Filters"],"4yQF++":["Custom show programs are grouped by their parent show"],"50whWJ":["XMLTV Link:"],"53/4tH":["Audio Options"],"536Xwe":["Error copying to clipboard!"],"53tfay":["This allows to schedule specific shows to run at specific time slots of the day or a week. It\'s recommended you first populate the channel with the episodes from the shows you want to play and/or other content like movies and redirects."],"5ABghp":["FFmpeg Settings"],"5V93hk":["Schedule programming using slots assigned a start time and duration."],"5WeWGz":["Selected Subtitle"],"5jWg+L":["Tunarr will attempt to get Plex to pull Tunarr\'s updated XMLTV upon regeneration"],"5k0NLb":["Review"],"5lSgNP":["Enable SSDP server"],"5nsbxB":["Alternates TV shows in blocks of episodes. You can pick the number of episodes per show in each block and if the order of shows in each block should be randomized. Movies are moved to the bottom."],"5qV3NN":["Flex Style"],"5yIPLp":["Oops!"],"6/dCYd":["Overview"],"63/DSM":["Transcoding Configs"],"63driG":["Stream JSON"],"67RoFa":["Pipeline"],"6Y9c2m":["This slot is linked with ",["0"]," other slot(s). Content fields are shared across the group."],"6YtxFj":["Name"],"6ZMWKw":["XMLTV"],"6bbWRs":["Add programming to custom show"],"6dvIbw":["Unlink"],"6jAi8c":["Range"],"6jfS51":["Welcome"],"6ki7F2":[["0","plural",{"one":["#"," item"],"other":["#"," items"]}]],"6mJ9tF":["FFMPEG is not detected."],"6mpwdR":["Match all of"],"6pL6be":["Configure what appears on your channel when there is no suitable filler content available. Using channel fallbacks requires ffmpeg transcoding."],"6w0yiE":["FFMPEG Log Level"],"6zfUar":["Stream Selection"],"71O7b0":["Media Info"],"73XwX0":["No programs selected"],"73flfT":["QSV Device"],"7B3lfh":["Items from any filler list will not be chosen more frequently than this cooldown setting."],"7LWPgS":["Enabled (loudnorm)"],"7ODkf5":["Log level to pass to ffmpeg. Read more about ffmpeg\'s log levels <0>here"],"7Q5AKf":[["count","plural",{"one":["track"],"other":["tracks"]}]],"7b2stB":["Media Type"],"7eMo+U":["Go Home"],"7eZlTH":["Sort TV Shows (asc)"],"7iJlKU":["Please choose a value greater than 1"],"7pMNGK":["Programs saved!"],"7sNhEz":["Username"],"7tvV2B":["Min Duration (minutes)"],"7uohY3":["TV shows are grouped by show"],"80t7Ii":["Increasing \\"Max Lateness\\" for the schedule."],"87a/t/":["Label"],"8E9KXK":["Feature flags saved!"],"8MIU1T":["Program"],"8TMaZI":["Timestamp"],"8ZsakT":["Password"],"8vETh9":["Show"],"8wngZM":["Fallback"],"8wu9lr":["Queued"],"9+90+V":["Enable Log File Rolling"],"94qSvE":["Synced with external playlist"],"96zw7M":["This show is marked as missing in the database."],"983IRa":["All linked slots show the same episode, advancing only after all have played."],"9E+eyD":["Output video at a constant frame rate."],"9E9tRC":["Fill with Flex"],"9Eq43e":["If set, all watermark overlays will be disabled for channels assigned this transcode config."],"9GPYnX":["Do not group programs at all. Normal shuffle."],"9WG5wy":["Specials"],"9asVsi":["How long each commercial break lasts"],"9qdNKR":["Error Options"],"9sqrEU":["Filler List"],"9td1Wl":["Check"],"9vtG84":[" Scheduling Strategy"],"A+GCyx":["Hide Advanced"],"A0+T6c":["Reset Changes"],"A1taO8":["Search"],"A7WmPm":["New Plex Server"],"A9Rhec":["Channel Name"],"ACKu03":["Refresh Preview"],"AKjNTL":["Add Padding"],"AM972O":["Add Redirect"],"ANICN0":["No media sources connected."],"AO2Z5d":["Movie, ",["0"]],"AOHgZp":["Episodes"],"AVKoQM":["Redirect to \\"",["0"],"\\""],"AXg7m0":["Search is currently scoped to this Media Source."],"AXjA78":["Field"],"AdfhAd":["If there are issues playing a video, Tunarr will try to use an error screen as a placeholder while retrying loading the video every 60 seconds."],"AdogaJ":["Pipeline Steps"],"AlfqgK":["Watch"],"ApsQAb":["HDHR: Loading..."],"AyInY5":["Video Options"],"AzCYkg":["Connect Media Sources"],"B+HsXP":["FFMPEG: ",["0"]],"B1NOvD":["Removes all programs from schedule"],"B1W8vw":["Delete \\"",["0"],"\\""],"BGHH1t":["Min. Visible in Guide Duration Program (seconds)"],"BJjJuo":["EPG (Hours)"],"BMlGCC":["Click to preview the items in this Custom Show. Note that only the whole show can be added at once."],"BQsifH":["Stream Info"],"BWTzAb":["Manual"],"BXXjCD":["FFmpeg not found. For all features to work, we recommend installing FFmpeg 7.1+ or update your FFmpeg executable path in settings."],"BaUuhR":["Codec"],"BlmmxH":["FFmpeg Log"],"Bq0ryo":["Reset Options"],"BtL93c":[["0","plural",{"one":["#"," source connected."],"other":["#"," sources connected."]}]],"C4KL42":["Consolidates contiguous match flex and redirect blocks into singular spans"],"C6jEO3":["Log Level"],"CAiikc":["Enter your Jellyfin password to generate a new access token.<0/><1>NOTE: These are never saved to the Tunarr DB. Instead they are sent to Jellyfin to exchange for a session token."],"CJkEfx":["Block"],"CKQ3t3":["Total Runtime"],"CMQ09J":["Scanning"],"COv7As":["Cooldown (seconds)"],"CRsuq4":["Every"],"CVqySE":[["len","plural",{"one":["There is ","#"," warning. Click for details."],"other":["There are ","#"," warnings. Click for details."]}]],"CWRFGq":["Modify Programming"],"CXDHcv":["Grid"],"CcX8VV":["Completely randomizes the order of programs."],"CeyB7O":["FFmpeg Executable Path"],"CfOWar":["Logarithmic decay, lighter weighting."],"CfUvtM":["Error saving new Smart Collection. Check server logs and browser console for details."],"CfxLtO":["Program JSON"],"Cko536":["Descending"],"Cp5Awv":["Duration must be greater than 0."],"CqSP2T":["Edit Channel Redirect"],"CsrDsg":["12-hour"],"Cxqf0C":["Plex (Auto)"],"D+NlUC":["System"],"D1Fhv3":[["count","plural",{"one":["episode"],"other":["episodes"]}]],"DPfwMq":["Done"],"DRya1t":["Audio Volume"],"DSwJ9W":["Enable Animation"],"DUd3Ss":["Sorts the list by TV Show and the episodes in each TV show by their season/episode number. Movies are moved to the bottom of the schedule."],"DbouLP":["Back to Programming"],"Dd9orS":["Remove All ",["movieCount"]," ",["movieCount","plural",{"one":["Movie"],"other":["Movies"]}]],"Dnn2XG":["Automatic"],"DoJzLz":["Collections"],"DxvGLB":["Add Slot"],"E/QGRL":["Disabled"],"E5ipHC":["Balance By:"],"E8oclZ":["Copied Channel ID!"],"EKlukx":["Copy Full Report"],"EL4/HD":[["0","plural",{"one":["program"],"other":["programs"]}]],"EdQY6l":["None"],"EkH9pt":["Update"],"Etie0Q":["All channels assigned to this config will be set to use the default configuration. If this is the last configuration, a new default configuration will be created."],"Eu20Os":["Time Slots"],"Ev2r9A":["No results"],"F1l877":["Subtitle Streams"],"F3bW6y":["Platform"],"F3smBd":["Maximum number of days to precalculate the schedule. Note that the length of the schedule is also bounded by the maximum number of programs allowed in a channel.<0/><1>Note: Previewing the schedule in the browser for long lengths of time can cause UI performance issues"],"FDEfoy":["Deleting a media source will remove all of its associated programs from Tunarr."],"FXCwT9":["FFprobe Executable Path"],"FZg3wM":["Operation"],"FmN5me":["Resolution"],"FnChN1":["Enable <0>EBU R 128 loudness normalization via the <1>loudnorm FFmpeg filter. May increase CPU usage during streaming."],"Fp7p73":["Time between subsequent breaks"],"FqCHF/":["Threads"],"FrRP21":["There was an error when submitting the form. Please see console logs for details."],"FsF4bb":["Audio Loudness Normalization"],"FssFce":["Configure preferred audio languages globally."],"Fzn/BQ":["Release Date"],"G+8qH5":["Channel name is required"],"GDKKxT":["Access Token"],"GHOK4Z":["Time Format"],"GJ1P5j":["File a Bug Report"],"GKLqtE":["Set the host of your Tunarr backend. When empty, the web UI will use the current host/port to communicate with the backend."],"GLOZdc":["Custom Shows"],"GP/CFo":["HW Accel"],"GQ3O42":["Trash"],"GRCrpV":["Manage Libraries"],"GUtCZC":["Version: ",["0"]],"GhZ4GX":["Error while copying to clipboard. Check browser logs for details"],"GmP0oY":["Slot Warnings"],"GmTnBN":["Enable ffmpeg logging to different sinks. Outputting to a file will create a new log file for every spawned ffmpeg process in the Tunarr log directory. These files are automatically cleaned up by a background process."],"Gr1Ik2":["Nvidia Capabilities"],"GtycJ/":["Tasks"],"GzzMwi":["Roll on Schedule"],"H0QGc9":["Filler List Cooldown (seconds)"],"H1OFlu":["Inverse linear decay, heavier weighting."],"H1V+2G":["To use Tunarr, you must first connect at least one media source. Media sources provide all content used to create channels in Tunarr. Plex and Jellyfin are currently supported."],"H3OF1s":["Tuner Count"],"H7OUPr":["Day"],"H8100o":["Filler lists are collections of videos that you may want to play during \'flex\' time segments. Flex is time within a channel that does not have a program scheduled (usually used for padding)."],"HDoQBx":["Channel settings saved!"],"HEH0PR":["Must define at least one language preference"],"HErtdg":["Name can only contain alphanumeric characters, dashes, and underscores"],"HLlLPP":["Channel Stream Mode"],"HMWEIt":["Edit Flex Time"],"HOLbdk":["Failed to load stream details! Check logs for details"],"HSfauP":["This slot is linked with ",["0"]," other ",["1","plural",{"one":["slot"],"other":["slots"]}],". Content fields are shared across the group."],"HVpg3x":["Failed to load Smart Collection"],"HXx+vU":["Controls what happens when this slot runs out of replayed content from earlier continue slots."],"HYCPKT":["Add Selected Media"],"HajiZl":["Month"],"HdE1If":["Channel"],"Hjfx9G":["Audio & Subtitles"],"HmHwcC":["Fixed Interval"],"HptUxX":["Number"],"HqUilK":["Keywords perform full text search across all (or configured) fields"],"HzV8B2":["Skip mid-roll for programs shorter than this"],"I+FvbD":["Scan"],"I2Bar3":["Shows"],"I5BU70":["Smart Collection: ",["0"]],"I6gXOa":["Path"],"IDlmXg":["Tunarr Backend URL:"],"IE9OdF":["Update Play Status"],"IFiQdD":["Channels M3U Link:"],"IMxI++":["Not a valid URL"],"INCbO6":["On-Demand channels resume from where you left off. Programming is paused when the channel is not streaming.<0/><1>NOTE: While the channel is inactive, the TV Guide for the channel will be empty."],"IagCbF":["URL"],"IetKlB":["New Custom Show"],"IgC1fP":["Enable light Mode"],"IiBgkW":["Failed to update Media Source settings. Please check server and browser logs for details."],"IoSxk9":["Protocol must be HTTP or HTTPS"],"IvkbIT":["Read More"],"J/eF78":["Removing overrun programs from the channel."],"J0NKO1":["Exclude Seasons"],"J2eKUI":["File"],"J2lnQW":["Pre"],"J41wt0":["Slot Editor"],"J4Ngmi":["Loop Short Programs"],"J50/e4":["Filter Type"],"J8X80J":["Stealth?"],"JCGCcQ":["Sorts everything by its release date. This will only work correctly if the release dates in Plex are correct. In case any item does not have a release date specified, it will be moved to the bottom."],"JCOZTc":["Audio & Subtitle Options"],"JOFDLs":["Program Playback Troubleshooter"],"JeAvlS":["Pad Times"],"JeL1O4":["Redirect duration"],"Jj3SJk":["A-Z (asc)"],"JmZ/+d":["Finish"],"Jpe9a8":["Attempts to balance programming groups by either total lineup duration or number of unique programs. For instance, for a channel with many seasons of one show and few seasons of another, balancing will attempt to create an even mix of both shows by inserting repeats of the show with fewer episodes."],"JryIGL":["Adjust Weights"],"Jsel0T":["This channel has an existing time slot schedule. A channel can only use one scheduling type at a time. Saving a schedule here will remove the existing time slot schedule."],"Jtbzxr":["Version: unknown"],"JxE+Bh":["Allows you to pick specific programming to remove from the channel."],"JyHA6G":["Displays the last ",["0"]," system log events. Use the buttons below to export these logs or download the entire log file for debugging."],"JzJk+4":["Add Language Preference"],"K09nyY":["Linked slots advance episode progression together sequentially."],"K8+dbZ":[["totalConnections"]," total"],"K8ebg0":["Tunarr will update Jellyfin\'s \\"now playing\\" state while channels are active."],"K9pQ8Q":["Disable Watermarks"],"KRjDf4":["Audio Streams"],"Khe/Vb":["Watch Channel"],"KkOthv":["Guide"],"Km5fSd":["If you are confident FFMPEG is installed, you may just need to update the executable path in the settings. To do so, simply click Edit above to update the path."],"L+8pV5":["Sync with external playlist"],"L/KmPM":["Usually slots need to add flex time to ensure that the next slot starts at the correct time. When there are multiple videos in the slot, you might prefer to distribute the flex time between the videos or to place most of the flex time at the end of the slot."],"L6Mhe6":["You have unsaved changes!"],"L8Hb+D":["Sets the number of threads used to decode the input stream. Set to 0 to let ffmpeg automatically decide how many threads to use. Read more about this option <0>here. <1>Note: this option is overridden to 1 when using hardware accelearation for stability reasons."],"LKPR6G":["Playlist"],"LKSv28":["Smart Collections are self-updating content lists. You set the query and the collection automatically adds any new content from your library that fits those rules. Any newly added content matching query will not modify existing channel programming at this time."],"LMMGPr":["Submitting..."],"LRvqnF":["Error saving new Jellyfin server. See browser console and server logs for details"],"LTC198":["Running..."],"LTYRAI":["View Library"],"LiCr5o":["Limit must be numeric"],"MHrjPM":["Title"],"MKK96e":["View Collection"],"MR6Nlf":["Change the verbosity of specific categories of logs. Useful if debugging a specific feature."],"MS1Dhi":["Max file size (bytes)"],"MVBLYK":["Remove..."],"MW42Hp":["Customize how movie blocks are sorted"],"Md/eZS":[["count","plural",{"one":["#"," item"],"other":["#"," items"]}]],"MfkGXC":["Shuffle Grouping"],"MkMcGz":["Refresh Libraries"],"Ml7h3C":[["0","plural",{"one":["#"," Program"],"other":["#"," Programs"]}]],"Mrdyk9":["Genre"],"Mv+xQh":["New Channel"],"N15e5e":["Remove custom icon"],"NGOfis":["Disable Image Scaling"],"NGSThJ":["Smart Collection"],"NL/bON":["FFmpeg Command"],"NQ7yht":["Must use a valid URL, or empty."],"NaDxQ2":["Auto Deinterlace Video"],"Nb+B9K":["Adjust the output volume (not recommended). Values higher than 100 will boost the audio."],"NcV1df":["Pad Start Times"],"NfTP7a":["Advanced options relating to audio. In general, do not change these unless you know what you are doing!"],"NfZ8rc":["24-hour"],"Nkn5MW":["Removes all Flex periods from the schedule."],"NnH3pK":["Test"],"NnuRri":["This allows you to pick the weights for each of the shows, so you can decide that some shows should be less frequent than other shows."],"NtQvjo":["Period"],"Nu4oKW":["Description"],"Ny7dz3":["Albums"],"NyfQ4q":["Save as Smart Collection"],"O1xfOi":["Random..."],"O5izWu":["This custom show is synced with an external playlist. Content is updated automatically and cannot be edited manually."],"O8g6Na":["Last Scanned: ",["0"]],"OPw3KG":["Connect Media Source"],"OVmXHk":["Refresh Timer (Hours)"],"Ob+B6e":["Buffer size cannot be changed when copying input audio"],"OfC/JK":["Custom Show - ",["0"]],"OfYtUi":["Filler Content"],"OfhWJH":["Reset"],"OrDu0o":["Video Buffer Size"],"Osn70z":["Debug"],"P/TyYO":["The type of media in the provided paths"],"P1BU0j":["Frame Rate"],"P29ZKI":["Enter a name for your Emby Server"],"P2DGHD":["Programming starts at ",["startTime"]," and stops at ",["endTime"]],"P3i3NN":["Edit Channel Settings"],"P6Io39":["Max Lateness"],"P6c7YE":["Remove Programming"],"PCBfmf":["Renders a channel icon (also known as bug or Digital On-screen Graphic) on top of the channel\'s stream."],"PJ/u9s":["Copied ",["0"]," URL to clipboard"],"PT6k0T":["Pixel Format"],"PX1WM1":["Successfully emptied trash."],"Pazp7r":["There was an error generating time slots. Check the browser console log for more information"],"PeBTGz":["Clear Schedule"],"PeBylA":["You must create at least one <0>filler list before assigning filler to a lot."],"Pfatg8":[["minutes","plural",{"one":["#"," minute"],"other":["#"," minutes"]}]],"PgdRhI":["Weighting"],"Ph+yE0":["0 mins"],"PhKcf0":["Edit Transcode Config"],"PiY0nu":["You have no Filler Lists. Create your first Filler List <0>here."],"Pol2QS":["Emby"],"PpZkda":["Features"],"PwpUBp":["This is the name of the fake program that will appear in the TV guide when there are no programs to display in that time slot guide, e.g when a large Flex block is scheduled."],"Pwqkdw":["Loading…"],"Q8L6q9":["Video Streams"],"QAUrt0":["Refresh Page"],"QEb4hu":["Stealth Mode"],"QG2xdt":["Create Rerun Block"],"QHRTYn":["Slots Editor..."],"QKMxhc":["Tunarr runs various tasks, sometimes on a schedule, for background operations."],"QUxTIQ":["Filler is resolved at schedule time. The guide shows specific filler titles."],"Qll2Tb":["Desc"],"QlrQ/Z":["Next Scheduled Execution"],"Qm1NmK":["OR"],"Qu844y":["Time Slot Editor"],"QvKdb0":["Placeholder Program Title"],"Qx971g":["After Every"],"R/7J0Z":["Artists"],"R/N+HY":["No programming added yet"],"R/xSFi":["Editing \\"",["0"],"\\""],"R0yni2":["Attempt Auto-Fix"],"R40oLk":["Will force use of a software encoder despite hardware acceleration settings."],"R6kHq+":["Link Mode"],"R9Khdg":["Auto"],"RCeEAd":["Global Options"],"RGf6l7":["Select a slot to link to"],"RI4u49":["<0>You can edit this location in your settings.json within your Tunarr data directory<1/><2>NOTE: When manually adding the XMLTV location to a client like Plex, do not use this file directly. Instead, use the generated XMLTV from the Tunarr API endpoint: ",["0"],""],"RTxUjI":["Copy to Clipboard"],"RUYsn0":["Clear All"],"RVl9/c":["Alternate programs in blocks. You can pick the number of programs per-type in each block and if the order of shows in each block should be randomized."],"RYP47R":[["0","plural",{"one":["Day"],"other":["Days"]}]],"RYlQY0":["Repeats"],"RaHlqV":[["totalConnections","plural",{"one":["#"," connection"],"other":["#"," connections"]}]],"RavMGr":[["count","plural",{"one":["second"],"other":["seconds"]}]],"RbgUS/":["Copy Channel ID"],"RtPRIb":["Maximum number of days to precalculate the schedule. Note that the length of the schedule is also bounded by the maximum number of programs allowed in a channel."],"RxzN1M":["Enabled"],"S/CawK":["Movies are grouped altogether"],"S5v5/h":["Enabling embedded subtitle extaction will periodically scan your upcoming programming for embedded text-based subtitle streams and extract them to a local cache. This is necessary in order to enable subtitle burning for text-based subtitles which are not external streams."],"S60KP9":["Server Settings"],"S8zZJK":["Welcome to Tunarr!"],"SBtwzo":["Version Mismatch!"],"SCZJhh":["Audio Bitrate"],"SFjIKS":[["0","plural",{"one":["#"," Selected Item"],"other":["#"," Selected Items"]}]],"SOXW6w":["All Genres"],"SY1gRl":["Media Source"],"SYGPcm":["You have no smart collections. Smart collections can be created on the <0>search page."],"SZcfpX":["Pad Style"],"SZzr30":["The selected languages will be considered in order they are selected."],"Sbs5dW":["Filler"],"Sg3laT":["Min Duration"],"SoRsRS":["Calculates a schedule where all programs end at the same time, creating a perfectly looping schedule."],"SuubHr":["Deleting a Plex server will remove all programming from your channels associated with this plex server. Missing programming will be replaced with Flex time. This action cannot be undone."],"SywaS+":["Data Directory:"],"T5wfux":["Makes multiple copies of the schedule and plays them in sequence"],"T8drou":["System Health"],"TEM0vH":["Removes all programs from custom show"],"TMADKS":["Divides the programming in blocks of 4, 6, 8 or 12 hours then repeats each of the blocks the specified number of times."],"TMju4P":["Delete Media Source \\"",["0"],"\\"?"],"TS0lwx":["Encountered an error when emptying trash. Check console logs for details."],"TZKpsF":["No Media Sources detected."],"TpqW74":["Fixed"],"Ts6Zfm":["Error updating Smart Collection. Check logs for details."],"Ts8Q+i":["EPG"],"TvY/XA":["Documentation"],"Tz0i8g":["Settings"],"TzyoiK":["When enabling, Tunarr will generate an initial backup immediately"],"U0sC6H":["Daily"],"U3+jR/":["Replicate Programs"],"UC1lMc":["Failed to save feature flags."],"UE2eVC":["Sorts alphabetically by program title"],"UHu/Uf":["Show only synced libraries"],"UOMT7z":["This option is disabled because it would calculate a schedule that is too long."],"URmyfc":["Details"],"UXC1jS":["NodeJS: ",["0"]],"UYUgdb":["Order"],"UYW9jU":["Successfully ran system fixer ",["fixerId"]],"Uf/h/w":["Pick specific programming to remove from the channel."],"UirGxE":["Errors"],"UnI8zh":["Channel #",["0"]],"UweSf9":["Add Channel Redirect"],"V8B1wG":["Last synced ",["0"]],"V9UVpb":["Total hits: ",["0"]],"VBsY8N":["Set to 0 to never delete backups"],"VIHbrI":["Advanced options relating to transcoding. In general, do not change these unless you know what you are doing! These settings exist in order to leave some parity with the old dizqueTV transcode pipeline as well as to provide mechanisms to aid in debugging streaming issues."],"VP2oPP":["Slots"],"VVAgOP":["Rescan Interval (hours)"],"VXdzY3":["Disable Hardware Encoding"],"Va3xJe":["Add field"],"VfWz27":["Weight %"],"VlEnCC":["Archive Format"],"VlWKwW":["Lazy"],"Vmvp5H":[["count","plural",{"one":["day"],"other":["days"]}]],"VrBtVn":["Backups:"],"Vw5EeW":["Enable Backups"],"VyUuZb":["Image URL"],"WAakm9":["Delete Channel"],"WDgJiV":["Scanner"],"WGkxNZ":["Error querying Plex. Check console log and consider reporting a bug!"],"WKHqM+":["Weight"],"WMQchs":["Audio Buffer Size"],"WT1Ibn":["Last run"],"Wb3E4g":["Run now"],"Weq9zb":["General"],"WhJZoS":["Choose the transcode configuration to use for this channel. Configure transcode configurations on the <0>FFmpeg settings page."],"WjUHH8":["Movie Sort"],"WnW1QF":[["block"]," Hours"],"WzNAIP":[["0","plural",{"one":["Hour"],"other":["Hours"]}]],"X0mSqw":["Will force use of a software filters (e.g. scale, pad, etc.) despite hardware acceleration settings."],"X9EHMa":["Editing Smart Collection \\"",["0"],"\\""],"XDT85c":["Media Sources"],"XIgmo9":["Did not receive an accessToken or userId from Jellyfin server."],"XNtsE7":["Calculating Slots..."],"XNw99A":["Software (No GPU)"],"XOgcN3":["Filler List: ",["0"]],"XOuE6F":["This could cause the following slot\'s programs to go unscheduled. Possible solutions include:"],"XSkU3F":["* Restart required"],"XWYqJx":["Duplicate Channel"],"XXwX66":["Set the log level for the Tunarr server.<0/>Selecting <1>\\"Use environment settings\\" will instruct the server to use the <2>LOG_LEVEL environment variable, if set, or system default \\"info\\"."],"XePUKr":["Test Transcode"],"XhWvkJ":[["0"]," of ",["1"]," ",["2"]," exceed the length of this slot (",["3"],"). Average program length: ",["4"]],"Xkppm4":["Enable Watermark"],"Xm/WEQ":["Channel Group"],"XsR2HX":["Test Duration (seconds)"],"Xuml3I":["By default, time slots are time of the day-based, you can change it to time of the day + day of the week. That means scheduling 7x the number of time slots. If you change from daily to weekly, the current schedule will be repeated 7 times. If you change from weekly to daily, many of the slots will be deleted."],"XwU6BE":["You haven\'t created any filler lists yet! Go to the <0>Filler Lists page to create one."],"Y2ngGV":["Add a Filler List"],"Y5XZLy":["<0>Pad Slot: Align slot start times to the specified pad time.<1/><2>Pad Episode: Align episode start times (within a slot) to the specified pad time. <3>NOTE: Depending on slot length and the chosen pad time, this could potentially create a lot of flex."],"Y84UgQ":["Loudness Target"],"YAKCkm":["An error occurred: ",["0"]],"YDlcs3":["Shuffle Programming"],"YLUnu0":["Test Playback"],"YN7vx3":["Custom Show"],"YRQaPv":["Last Synced"],"YRT1+e":["Creates a new collection"],"YSptU0":["Replicate..."],"YT5/eK":["Media Source: \\"",["0"],"\\""],"YXwR3a":["Restore default logo"],"YY/JN7":[" the following day."],"YYLNVW":["Insert breaks at these percentages of the program duration"],"YdIZFA":["This channel number has already been used"],"Yf/Mtb":["You\'re All Set!"],"Z10t2U":["Removes repeated programs."],"Z3FXyt":["Loading..."],"Z4IQ8m":["Channel Transcode Config"],"Z5IrB3":["Open in ",["0"]],"Z6dMWq":["Error while running system fixer ",["fixerId"],". Check server logs for details."],"ZND/fh":["Cannot be empty"],"ZNZzTe":["Cannot disable libraries when they are locked"],"ZShzvn":["\\"",["0"],"\\" Live"],"ZWRt1W":["Output Path"],"ZkdKVr":["Redirect to Channel ",["0"]],"Zky8hA":["The image will be rendered at its actual size without any scaling applied."],"Zs2GWW":["New Emby Media Source"],"Zul8Ry":["never"],"Zvipe1":["Editing Plex Server \\"",["0"],"\\""],"ZxwuFV":["Deleting a Channel will remove all programming from the channel. This action cannot be undone."],"a+Pr3s":["Apply to Program Types (empty = all)"],"a4N/Bg":["Load More"],"aE3UMm":["<0>None: slots are picked in the order they are specified in the table (i.e. not randomly)<1/><2>Uniform: all slots have an equal chance to be picked.<3/><4>Weighted: each slot is picked with a specified probability"],"aOaCIk":["Allow External"],"aScBGS":["Add a filter expression to fine-tune results of the search"],"aSwfbR":["Unit"],"ak3N0i":["Item was not present during the last scan"],"aoLy25":["Opacity"],"b0Uv6P":[["0","plural",{"one":["Path"],"other":["Paths"]}]],"b6sx4K":["No active sessions"],"bDY29m":["Logarithmic"],"bGG6B1":["Jellyfin"],"bHNlfr":["Increasing the slot duration."],"bNEQeI":["Cooldown"],"bORfbY":["Cannot use a channel number <= 0"],"bPJiZF":["Show: ",["0"]],"bSIBDb":["Release Date (asc)"],"bm8pgG":["Add group"],"boItSp":["Delete Media Source?"],"buS8nL":["Enable Subtitles"],"bxyuno":["Override global audio and subtitle settings for this channel."],"bydide":["FFMPEG Log Method"],"c6fsNw":["When enabled, intermittent watermarks fade in immediately when a stream is initialized. When disabled, the first watermark fade-in occurs after a full period."],"cF5KzV":["Edit Filler List"],"cFTdM+":["Console"],"cHYx4E":["Empty Trash"],"cLgGtf":["Reset programming to most recently saved state"],"cN5Dty":["No Programming scheduled"],"cOvZFM":["Dynamic"],"cXkSYc":["There was an error submitting the request to update Media Source settings. Please check the form and try again"],"caSM6R":["This is used by iptv clients to categorize the channels. You can leave it as \'tunarr\' if you don\'t need this sort of classification."],"cgo+Ch":[["remainingTime"]," left"],"cheWPw":["Duplicates"],"cjX7aq":["Are you sure you want to delete Smart Collection \\"",["0"],"\\"?"],"cmKYIw":["Overflow Behavior"],"cmlWKg":["<0>Error deleting custom show: ",["0"],"<1/>Please consider opening a bug with details!"],"cnCAaO":["Percentage-Based"],"cnGeoo":["Delete"],"cv/ykT":["Search Server URL:"],"cxrM1O":["Connect Sources"],"d5zxa4":["Local"],"d72gcv":["Loudnorm Options"],"d9HhJj":["This media source has no enabled or scanned libraries. Enable libraries for this source on the <0>Media Sources page or manually trigger scans on the <1>Library page."],"d9Tsiy":["Error updating channel.<0/>Check browser console for details"],"d9XR+x":["Transcode Config <0> <1/>"],"dBV/FP":["Lock Weights"],"dDX6oS":["Videos from the filler list will be randomly picked to play unless there are cooldown restrictions to place or if no videos are short enough for the remaining Flex time.<0/>Each filler can be assigned a cooldown, which restricts how frequently the list will be chosen during flex time."],"dEgA5A":["Cancel"],"dH8AwH":["Add Breaks"],"dK3Z9j":["Component"],"dQvGiF":[["0","plural",{"one":["#"," session"],"other":["#"," sessions"]}]],"dScixt":["Enable dark Mode"],"dUyQn5":["On-Demand"],"daSf8d":["Group episode programs by their show."],"djpQ8z":["Reload Stream"],"dkURuB":["Tail Buffer (minutes)"],"dnCwNB":["Successfully copied to clipboard!"],"eARDm/":[["0","plural",{"one":["#"," season"],"other":["#"," seasons"]}],", ",["1","plural",{"one":["#"," total episode"],"other":["#"," total episodes"]}]],"eEpDfJ":["Will force use of a software decoder despite hardware acceleration settings."],"eNorwJ":["Programs Too Long"],"ePK91l":["Edit"],"eSsduj":["VA-API Device"],"eZTFiP":["Review Selections"],"eZe0fr":["Audio Channels"],"ecUA8p":["Today"],"efuwN9":["These settings are stored in your browser and are saved automatically when changed."],"eg6m1K":["Edit Transcode Config: \\"",["0"],"\\""],"ep+NHZ":["If you proceed, all unsaved changes will be lost. Are you sure you want to proceed?"],"et+mIi":["Troubleshoot"],"euChZN":["Cyclic Shuffle"],"euc6Ns":["Duplicate"],"exYcTF":["Library"],"eyRsaH":["Root"],"f0w0IC":["Leave blank to use the channel\'s icon."],"f6Hub0":["Sort"],"f6pgxW":["Temporarily caches responses from Plex based by request path. Could potentially speed up channel editing."],"f7DWm5":["Need at least one path"],"fD+lMD":["Select the port the Tunarr server will listen on. This requires a server restart to take effect."],"fI+mNw":["Playlists"],"fJfo1A":["Server Path"],"fN4bgn":["Delete Filler List \\"",["0"],"\\"?"],"fQ9phi":["Remove All"],"fSRZCh":["Restore Default Settings"],"fU1065":["Mid-Roll"],"fWj7Tt":["Shuffle programming in a channel, optionally grouping programs by certain criteria."],"fcqkKg":["Not found!"],"fsBGk0":["Balance"],"ftF4U5":["Show Advanced"],"fxTyFe":["This slot is linked with ",["0"]," other ",["1","plural",{"one":["slot"],"other":["slots"]}],"Content fields are shared across the group."],"fyo+NB":["The End."],"fzWV5a":["Sort TV Shows (desc)"],"g2Pro3":["Reset changes made to the channel\'s lineup"],"g6LxbB":["Break Interval (minutes)"],"g7LzUS":["Install FFMPEG"],"gBx20d":["Custom Program"],"gH5Gbn":["Shuffle"],"gJrGqR":["FFmpeg version 7.1+ recommended. Check your current version in the sidebar"],"gL9DoB":["Programs shorter than this value will be treated the same as Flex time. Meaning that the TV Guide will try to meld them with the previous program or display the block of programs as the \\"place holder program\\" if they make a large continuous group. Use 0 to disable this feature or use a large value to make the channel report only the placeholder program and not the real programming.\\n",["0"]],"gR/hgc":["Error Audio"],"gcD6jw":["Hide watermark during filler"],"gf/bM4":["Continue with New Content"],"gg9/ya":["Remove ",["count"]," ",["0"]],"ghGSuE":["Ensures programs have a nice-looking start time, it will add Flex time to fill the gaps."],"glVpbE":["Eager"],"h/qU8b":["Override the default ",["0"]," device path (defaults to <0>/dev/dri/renderD128 on Linux and blank otherwise)"],"h4yKYk":["Next run"],"h8WhoR":["Slot Scheduler"],"hBGuBW":["Use channel default"],"hBzeL7":["Time before first break"],"hG89Ed":["Image"],"hISVAG":["Media Sources are where Tunarr sources your content. Media can come from your filesystem or a remote server, like Plex or Jellyfin. At least one Media Source is necessary to create channels and play media in Tunarr."],"hQRttt":["Submit"],"hQSabA":["TO"],"hXfj39":["Audio Sample Rate"],"hXzOVo":["Next"],"hYgDIe":["Create"],"he3ygx":["Copy"],"hehnjM":["Amount"],"hhukVU":["Trashed items are items that were previously scanned, but not found in a recent scan. This could be due to missing files or a media server no longer returning the item from its API. These items will be unplayable in channels in their current state. When the trash is emptied, their spots in channels will be replaced with flex."],"hjerov":["Guide Start Time"],"hlIKor":["None:"],"hnFEC+":["Initial Delay + Interval"],"hrdWlG":["Add Show"],"hvo+jE":["Add point (%)"],"i1+yww":["FFprobe version 6.0+ recommended. Check your current version in the sidebar"],"i2QuB6":["Error Screen"],"i9rcQ/":["Movies"],"iH8pgl":["Back"],"iQWhqk":["FFMPEG is installed. Detected version ",["0"]],"iTjV+L":["A-Z (desc)"],"iXJkMB":["Cooldown (s)"],"ih+n6S":["Linear"],"ihCTE6":["Error occurred while loading channels, please try again soon."],"ihn4zD":["Search…"],"ilkCYA":[["0","plural",{"one":["Selected Item"],"other":["Selected Items"]}]],"imrPBy":["Watermark Image URL"],"isC0OF":["Use these settings to override global ffmpeg settings for this channel."],"isRobC":["New"],"isyw73":["Auto uses the time convention for the selected language."],"jETaUB":["Buffer size effects how frequently ffmpeg reconsiders the output bitrate. <0>Read more"],"jHjfnS":["Add filler"],"jZlrte":["Color"],"jl3Q84":["Create a Channel"],"jz1oG0":["Selected Audio"],"k6TRai":["FFMPEG transcoding is required for some features like channel overlay, subtitles, and measures to prevent issues when switching episodes."],"kAidIP":["Failed to load feature flags."],"kBJRjR":["Download all logs"],"kIYDzY":["Successfully updated Media Source settings."],"kKgsI0":["<0>Configure the directory where Tunarr writes HLS segment files when transcoding. Tunarr will create the target directory (but not intermediate directories) if it doesn\'t exist.<1/>Changing this field will only affect new sessions. Existing sessions will continue writing to the previous setting, but will clean out segments when the segment ends.<2/>When unset, Tunarr will write segments to its current working directory."],"kKk153":["Load Stream"],"kO0aVB":["Break Duration (minutes)"],"kThBL9":["Sample rate cannot be changed when copying input audio"],"kdkZBD":["Increment"],"kii1WH":["Programming Preview"],"kolyzq":["This ",["0"]," is marked as missing in the database."],"kpfZ0g":["Minimum Program Duration (minutes)"],"kq6sAD":["Add TV Shows or Movies to filler"],"ksFZi3":["<0>Experimental: Enable Plex Request Cache"],"kvMAno":["Web Settings"],"l/UFPv":["Properties"],"l0VyMh":["Flex"],"l15zKW":["All Set!"],"lBADOx":[["count","plural",{"one":["#"," episode"],"other":["#"," episodes"]}]],"lC2oeQ":["Max Duration (minutes)"],"lCF0wC":["Refresh"],"lIUgjN":["Error copying channel m3u link to clipboard"],"lJSUC1":["Watermark"],"lKCfnI":["Audio Language Preferences"],"lS14fB":["Theme Settings"],"lW3FB1":["Download last ",["0"]," ",["1","plural",{"one":["#"," row"],"other":["#"," rows"]}]],"lWmRHf":["Time Slots..."],"lZMqZ5":["If enabled, TV show episodes will use the poster of their show, instead of the individual episode poster."],"laQT4o":["Thumbnail URL"],"lfFsZ4":["Channels"],"lkz6PL":["Duration"],"llDXYJ":["Backups"],"lnABVQ":["Run Troubleshooter"],"m+8qnB":["Library: ",["0"]],"m0Gp21":["Select a program and channel to test playback. The troubleshooter will analyze stream selection, build the FFmpeg pipeline, and run a short test transcode."],"m16xKo":["Add"],"m48LOH":["Hardware Acceleration"],"mCB6Je":["Select All"],"mDcLzR":["Caching"],"mF+u2B":["Don\'t see the library you want here? Ensure it is enabled in the <0>Media Source Settings."],"mGM6Aa":["Custom Shows are sequences of videos that represent a episodes of a virtual TV show. When you add these shows to a channel, the schedule tools will treat the videos as if they belonged to a single TV show."],"mHTMS1":["Normalize Frame Rate"],"mQt7fl":[["count","plural",{"one":["program"],"other":["programs"]}]],"mRWiYM":["Duration (seconds)"],"mWbpso":["Max Backups"],"mYBORk":["Movie"],"mYJG1x":["Your list will be replicated ",["0"]," times"],"mZFYjJ":["Error saving programs. ",["0"]],"mZFr14":["HLS not supported in this browser!"],"md42bg":["Transcode Config (optional override)"],"mgcp8D":["How often to insert a break"],"migeCK":["Filter which subtitle tracks are considered<0/><1>Any: All subtitle tracks are considered <2/><3>Forced: Only consider <4>\\"forced\\"subtitle tracks <5/><6>Default: Only consider default subtitle tracks <7/><8>None: Do not select any subtitles"],"mtQjGe":["Configure subtitle preferences. Preferences are evaluated in order of priority. The first matching subtitle stream on a program will be used."],"mvU6s8":["Sort TV Shows"],"mwtge0":["Started ",["startedAgo"]," - ",["remainingTime"],"remaining"],"n+7HJk":["When file paths on the remote server differ from the paths Tunarr can see, use Path Replacements to instruct Tunarr how to stream media from disk."],"n9nSNJ":["Time format"],"nH6YaM":["Other Videos"],"nSW2Lv":[["days","plural",{"one":["#"," day"],"other":["#"," days"]}]],"nV6twc":["Organize"],"nYD/Cq":["Ascending"],"nZXc7r":["Unlink from group"],"nfAddt":["FFmpeg Transcode Path"],"nfxRnc":["Tunarr is currently configured to use the AC3 audio encoder. This audio format is not supported by browsers. The resultant stream will likely not have audio or will not play at all."],"njIcYs":["Save as new collection…"],"ntJ9rt":["HLS Direct Output Format"],"nzDzPp":["toggle access token visibility"],"o0+Ul2":["Add Flex"],"o2Ucvk":["Libraries"],"o6OQlp":["Edit Channel"],"o7J4JM":["Filter"],"o7Y4WO":["Error saving new Emby server. See browser console and server logs for details"],"oADXRC":["Calculated ",["humanizedDuration"]," (",["numShows"]," programs) of programming in ",["duration"],"ms"],"oCHfGC":["Level"],"oCpfQF":["This feature is currently experimental. Proceed with caution and if you experience an issue, try disabling caching."],"oEZmaP":[["count","plural",{"one":["#"," season"],"other":["#"," seasons"]}]],"oMA2jd":["Removes any specials from the schedule. Specials are episodes with season \'00\'."],"oPWgse":["Maximum number of breaks per program (0 = unlimited)"],"ofUcbc":["Random"],"oihuQr":["Number of Replications"],"ousf2V":["Random…"],"ovBPCi":["Default"],"oxvBx3":["If set, any programming group with fewer episodes will be looped in order to make perfectly even blocks."],"p/78dY":["Position"],"p/KgUp":["The channel\'s regular programming between the specified hours. Flex time will fill up the remaining hours."],"p04z/V":["# Programs"],"p4XZFD":["Local Path"],"pDwcFl":["Save Smart Collection"],"pKYBXC":["Last Scheduled Execution"],"paEQ75":["\\"Stealth\\" channels are hidden from TV guides, spoofed HDHR, m3u playlist, etc. The channel can still be streamed directly or be used as a redirect target."],"pcRxi1":["How frequently libraries should be scanned (starting from midnight)."],"pdlmIS":["<0>Error deleting filler list: ",["0"],"<1/>Please consider opening a bug with details!"],"pkERVr":["Download JSON"],"pqarBu":["Asc"],"pvnfJD":["Dark"],"pwPreK":["Restrict Hours"],"pxh+PI":["Builder"],"q6GKgP":["VAAPI Capabilities"],"q6nlo/":["Subtitle Action"],"q9p3Xw":["Bitrate cannot be changed when copying input audio"],"qAGp2O":["Proceed"],"qG6T/X":["Add Programming"],"qKNcv7":["Generating Bug Report Link..."],"qV9xkb":["Passthrough audio unchanged. Other settings will not apply."],"qiXmlF":["Add Media"],"qjW34v":["This channel is set up to use <0>",["0"],"Slots for programming. Any manual changes on this page will likely make this channel stop adhering to that schedule."],"qlR1dD":["Delete Channel \\"",["0"],"\\"?"],"qs/mhD":["Ensures programs start only at a particular interval within the hour. This makes for nice looking schedules. Flex time is scheduled to facilitate."],"r3ptXC":["Manually add an access token from your Jellyfin server"],"r9sc/0":["Duration must be numeric"],"rAx5u1":["End Time"],"rPEEWz":["Successfully saved config!"],"rSZlvN":["Programming Start"],"rhEkXj":["Head"],"rl/8FN":["Commit"],"rnbEQB":["Copy M3U URL"],"roIf2/":["On-Demand?"],"rtDDIV":["Edit Slot"],"ru5qTc":["Edit Media Source"],"rx5Ria":["All lists are used"],"rxumR2":["Match any of"],"s2OE0W":["Enter a name for your Jellyfin Server"],"s4iETe":["Transcode Config"],"s6lNC3":["Fallback Mode"],"s8zbIS":["Include Seasons"],"sA8Jt7":["This slot replays content aired by continue slots earlier in the period."],"sBJ5MF":["Sources"],"sNnXh6":["Order of programming within the slot"],"sUtIRs":["about "],"sVVcvs":["Experimental Features"],"sfbjgG":["Audio Format"],"sxkWRg":["Advanced"],"sxwNOp":["Logs Directory:"],"sztQMJ":["Programs a Flex time slot. Normally you\'d use pad times, restrict times or add breaks to add a large quantity of Flex times at once, but this exists for more specific cases."],"t/YqKh":["Remove"],"t3hvHq":["Sync Now"],"t5q6kk":["For more details on manually retrieving a Plex token, see <0>here"],"t6+QCF":[["count"]," ",["programLabel"],", ",["0"]],"t8Hzw3":["Cyclic Shuffle randomly shuffles groups of programming."],"tDuQbQ":["Stream Mode"],"tEvsql":["Subtitles"],"tH1aCG":["Video Bitrate"],"tMxWK0":["Adds Flex breaks after each TV episode or movie to ensure that the program starts at one of the allowed minute marks. For example, you can use this to ensure that all your programs start at either XX:00 times or XX:30 times. Removes any existing Flex periods before adding the new ones. This button might be disabled if the channel is already too large."],"tPGTPB":["Roll the log file on a fixed schedule, regardless of file size."],"tRgOE5":["Balance Programming"],"tXkhj/":["Start"],"tXub8j":["Display Watermark on Leading Edge"],"tYuxvA":["FFMPEG"],"tfDRzk":["Save"],"tgPwON":["Operator"],"ti6ugP":["Error while saving transcode config. See console log for details."],"tkDYSE":[["hours","plural",{"one":["#"," hour"],"other":["#"," hours"]}]],"tlMRNb":["The loaded version of the Tunarr UI does not match the server. Reload the browser to get the latest. If this message persists, clear your browser cache and reload."],"tlNobE":["Custom Show: ",["0"]],"tlmh8e":["Add all selected programs to channel"],"tsqRRB":[["0"]," Poster"],"ty8rVI":["Now Playing:"],"tzwArf":["View in ",["0"]],"u+VWhB":["Copied to clipboard!"],"u+zFIr":["Restrict search fields"],"uAQUqI":["Status"],"uHTa9V":["To use Tunarr, you need to first connect a media source. This will allow you to build custom channels with your content."],"uLiDe/":["Enable embedded subtitle extraction"],"uUTf8r":["Delete Custom Show \\"",["0"],"\\"?"],"uamufO":["Add TV Shows or Movies to programming list."],"ueG1bp":["Program Count"],"ueLbrY":["If true, adjusting the weight of one slot will scale the weights of other slots such that all weights total 100%. Otherwise, weights can be adjusted freely and the weight of each slot is only relative to the total weight."],"uixVel":["By default, saves backups in the server\'s run directory, or, if running in Docker, to /config/tunarr/backups"],"uyR9ei":["Block Shuffle"],"v4nbQ4":["If no more programs can fit into a duration-based slot, flex time is added to fill the gap. This setting determines how flex is added <0>within the slot to ensure all time is filled.<1/><2>Between: Flex time is added between videos within a slot, if there are multiple<3/><4>End: Flex time is added at the end of the slot"],"v5IstB":["after every program"],"v5URfV":["Like Random Shuffle, but tries to preserve the sequence of episodes for each TV show. If a TV show has multiple instances of its episodes, they are also cycled appropriately."],"vAK/B1":["Audio Action"],"vCBet9":["Not a valid number"],"vERlcd":["Profile"],"vGRvxs":["Channel group is required"],"vLf7qg":["Interval (minutes)"],"vSJd18":["Video"],"vU/Hht":["Distribution"],"vXIe7J":["Language"],"vcvFVw":["Escape Hatches"],"vkA4W/":["Source Type"],"vn3SVH":["Could not parse this filter expression. Check the <0>documentation for information about filter expressions."],"vreTxe":[["count","plural",{"one":["#"," program"],"other":["#"," programs"]}]],"vwFKu0":["Cast & Crew"],"vyL1gO":["Release Date (desc)"],"w/bY7R":["Logs"],"w2pCRr":["Show:"],"w3KBq0":["Allows programs to play a bit late if the previous program took longer than usual. If a program is too late, Flex is scheduled instead."],"w3g+lo":["Let\'s get started..."],"wBmIEf":["Number of hours to include in the XMLTV file"],"wBo/7A":["Error while scheduling ",["taskId"],". Check server logs for details"],"wKClDM":["Adds a channel redirect. During this period of time, the channel will redirect to another channel."],"wMHvYH":["Value"],"wOUKOZ":["Max True Peak"],"wZOYCY":["Video Format"],"wdfBIP":["Sort By..."],"wdxz7K":["Source"],"wkQ2tb":["Adds Flex breaks after each TV episode or movie to ensure that the program starts at one of the allowed minute marks."],"wlYdUk":[["count","plural",{"one":["hour"],"other":["hours"]}]],"wpT1VN":["Condition"],"wtuVU4":["Frequency"],"wwu18a":["Icon"],"x+AjXa":["Channel Fallback"],"x/dwZe":["Enable if the watermark is an animated GIF or PNG. The watermark will loop according to the image\'s configuration. If this option is enabled and the image is not animated, there will be playback errors."],"x1tGMH":["Override how programs within this slot are padded."],"x6/Zc6":["Tail"],"x63PSs":["Search for shows"],"x7PDL5":["Logging"],"xCJdfg":["Clear"],"xDAtGP":["Message"],"xDPFrK":["Scan ",["0"]],"xGVfLh":["Continue"],"xGYZfl":["Edit Libraries"],"xIn7qU":["Disable Hardware Decoding"],"xJIepX":["Default Config"],"xOkMus":["Hardware Accel."],"xPmesF":["Loudness Range Target"],"xQC5se":["Advanced Video Options"],"xXrtPO":["Failed to load item details! Check logs for details"],"xazqmy":["Seasons"],"xbtgIC":["HW Acceleration"],"xdA/+p":["Tools"],"xmBknQ":["Filler Lists"],"xptXTM":["Select Artists to Remove"],"xqIrnW":["Library Clip (not yet implemented)"],"xu3Kah":[["0","plural",{"one":["#"," program"],"other":["#"," programs"]}]],"y28hnO":["Post"],"y4Jmre":["Break Duration"],"y4iKY3":[["count","plural",{"one":["#"," album"],"other":["#"," albums"]}]],"y5x0aB":[["0"]," Info"],"y7wpam":[["value","plural",{"one":["#"," program"],"other":["#"," programs"]}]],"yDUcwc":["Manually add an access token from your Emby server"],"yEDNx2":["Tunarr will update Plex\'s \\"now playing\\" state while channels are active."],"yPE51X":["Configure transcoding settings for Tunarr\'s streams. Each channel is assigned one transcode configuration."],"yPK7+5":["Auto-Update Guide"],"yQE2r9":["Loading"],"yRkqG9":["Limit"],"yX8Rkw":["Add All"],"yftDqj":["New Filler List"],"yjzkvk":["Stop Transcode Session"],"ysJk7v":["Movie Sort Order"],"ysecYP":["Search for a program"],"ytXxnP":["Forced"],"yz/C2/":["Rerun"],"yz7wBu":["Close"],"z4K9d+":["Roll based on size"],"z61uNR":["Add Flex Time"],"zV6tsp":["Consolidate"],"zV9awV":["Force Scan"],"zpylsE":["Transcoding Settings"],"zrmjn/":["Max Duration"],"zthKEs":["The streaming mode affects the type of underlying transcoding process used to create the channel\'s video stream.<0/>Learn more about Tunarr\'s stream modes <1>here!"],"zvjEp6":["Filler cooldown must be a number"],"zx4BuL":["Week"],"zyLvkd":["Category Log Levels"]}', +) as Messages; diff --git a/web/src/locales/es/messages.po b/web/src/locales/es/messages.po index 2a35f50eb..1bf0c442d 100644 --- a/web/src/locales/es/messages.po +++ b/web/src/locales/es/messages.po @@ -298,16 +298,16 @@ msgstr "" msgid "about " msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:362 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:398 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:439 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:455 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:382 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:424 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:456 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:472 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:265 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:281 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:367 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:405 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:451 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:468 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:432 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:474 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:511 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:528 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:269 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:286 msgid "Access Token" msgstr "" @@ -315,10 +315,10 @@ msgstr "" #: src/components/settings/AddPlexServer.tsx:14 #: src/components/settings/media_source/AddMediaSourceButton.tsx:83 #: src/components/settings/media_source/EditPathReplacementsForm.tsx:34 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:499 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:516 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:514 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:596 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:338 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:360 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:394 #: src/hooks/useRouteName.ts:83 msgid "Add" msgstr "" @@ -444,7 +444,7 @@ msgstr "" msgid "Adds Flex breaks between programs, attempting to avoid groups of consecutive programs that exceed the specified number of minutes." msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:196 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:233 msgid "Adjust the output volume (not recommended). Values higher than 100 will boost the audio." msgstr "" @@ -458,7 +458,7 @@ msgstr "" #~ msgid "Advanced" #~ msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:255 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:292 msgid "Advanced options relating to audio. In general, do not change these unless you know what you are doing!" msgstr "" @@ -466,7 +466,7 @@ msgstr "" msgid "Advanced options relating to transcoding. In general, do not change these unless you know what you are doing! These settings exist in order to leave some parity with the old dizqueTV transcode pipeline as well as to provide mechanisms to aid in debugging streaming issues." msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:252 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:289 #: src/components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx:223 msgid "Advanced Video Options" msgstr "" @@ -596,19 +596,19 @@ msgstr "" msgid "Audio Action" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:102 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:139 msgid "Audio Bitrate" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:131 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:168 msgid "Audio Buffer Size" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:185 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:222 msgid "Audio Channels" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:80 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:117 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:139 msgid "Audio Format" msgstr "" @@ -617,8 +617,8 @@ msgstr "" msgid "Audio Language Preferences" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:211 -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:214 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:248 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:251 msgid "Audio Loudness Normalization" msgstr "" @@ -626,7 +626,7 @@ msgstr "" msgid "Audio Options" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:161 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:198 msgid "Audio Sample Rate" msgstr "" @@ -634,7 +634,7 @@ msgstr "" msgid "Audio Streams" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:195 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:232 msgid "Audio Volume" msgstr "" @@ -650,7 +650,7 @@ msgstr "" msgid "Auto uses the time convention for the selected language." msgstr "" -#: src/components/settings/media_source/PlexServerEditDialog.tsx:344 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:352 msgid "Auto-Update Guide" msgstr "" @@ -703,7 +703,7 @@ msgstr "" msgid "Bit Depth" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:113 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:150 msgid "Bitrate cannot be changed when copying input audio" msgstr "" @@ -736,7 +736,7 @@ msgstr "" msgid "Break Positioning" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:142 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:179 msgid "Buffer size cannot be changed when copying input audio" msgstr "" @@ -786,10 +786,10 @@ msgstr "" #: src/components/programming_controls/BalanceProgrammingModal.tsx:68 #: src/components/programming_controls/RemoveShowsModal.tsx:429 #: src/components/programming_controls/ShuffleProgrammingModal.tsx:76 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:486 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:503 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:501 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:583 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:330 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:353 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:387 #: src/components/settings/UnsavedNavigationAlert.tsx:67 #: src/components/slot_scheduler/EditRandomSlotDialogContent.tsx:576 #: src/components/slot_scheduler/EditTimeSlotDialogContent.tsx:408 @@ -804,9 +804,9 @@ msgstr "" msgid "Cancel" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:280 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:294 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:214 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:281 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:342 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:215 msgid "Cannot be empty" msgstr "" @@ -1291,7 +1291,7 @@ msgstr "" msgid "Details" msgstr "" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:196 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:203 msgid "Did not receive an accessToken or userId from Jellyfin server." msgstr "" @@ -1315,7 +1315,7 @@ msgstr "" msgid "Disable Watermarks" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:219 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:256 #: src/pages/settings/FfmpegSettingsPage.tsx:224 #: src/pages/system/StatusPage.tsx:334 msgid "Disabled" @@ -1473,14 +1473,14 @@ msgstr "" #. placeholder {0}: server.name #. placeholder {0}: source.name -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:78 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:75 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:79 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:78 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:214 msgid "Editing \"{0}\"" msgstr "" #. placeholder {0}: server.name -#: src/components/settings/media_source/PlexServerEditDialog.tsx:77 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:78 msgid "Editing Plex Server \"{0}\"" msgstr "" @@ -1497,7 +1497,7 @@ msgstr "" msgid "Empty Trash" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:226 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:263 msgid "Enable <0>EBU R 128 loudness normalization via the <1>loudnorm FFmpeg filter. May increase CPU usage during streaming." msgstr "" @@ -1554,7 +1554,7 @@ msgstr "" msgid "Enabled" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:222 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:259 msgid "Enabled (loudnorm)" msgstr "" @@ -1578,11 +1578,11 @@ msgstr "" msgid "Ensures programs start only at a particular interval within the hour. This makes for nice looking schedules. Flex time is scheduled to facilitate." msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:342 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:345 msgid "Enter a name for your Emby Server" msgstr "" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:356 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:406 msgid "Enter a name for your Jellyfin Server" msgstr "" @@ -1590,11 +1590,11 @@ msgstr "" msgid "Enter a name for your Local Media Source" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:413 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:420 msgid "Enter your Emby password to generate a new access token." msgstr "" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:439 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:489 msgid "Enter your Jellyfin password to generate a new access token.<0/><1>NOTE: These are never saved to the Tunarr DB. Instead they are sent to Jellyfin to exchange for a session token." msgstr "" @@ -1636,11 +1636,11 @@ msgstr "" msgid "Error querying Plex. Check console log and consider reporting a bug!" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:146 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:147 msgid "Error saving new Emby server. See browser console and server logs for details" msgstr "" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:115 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:122 msgid "Error saving new Jellyfin server. See browser console and server logs for details" msgstr "" @@ -1950,7 +1950,7 @@ msgstr "" msgid "Flex Style" msgstr "" -#: src/components/settings/media_source/PlexServerEditDialog.tsx:292 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:297 msgid "For more details on manually retrieving a Plex token, see <0>here" msgstr "" @@ -2368,15 +2368,15 @@ msgstr "" msgid "Loop Short Programs" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:281 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:318 msgid "Loudness Range Target" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:271 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:308 msgid "Loudness Target" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:263 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:300 msgid "Loudnorm Options" msgstr "" @@ -2396,11 +2396,11 @@ msgstr "" msgid "Manual" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:467 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:480 msgid "Manually add an access token from your Emby server" msgstr "" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:484 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:540 msgid "Manually add an access token from your Jellyfin server" msgstr "" @@ -2438,7 +2438,7 @@ msgstr "" msgid "Max Lateness" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:291 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:328 msgid "Max True Peak" msgstr "" @@ -2573,10 +2573,10 @@ msgstr "" #: src/components/settings/ConnectMediaSources.tsx:44 #: src/components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx:95 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:93 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:335 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:349 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:338 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:399 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:238 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:317 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:325 #: src/components/smart_collections/CreateSmartCollectionDialog.tsx:162 #: src/components/smart_collections/EditSmartCollectionDialog.tsx:108 #: src/components/smart_collections/SmartCollectionsTable.tsx:59 @@ -2589,10 +2589,10 @@ msgstr "" msgid "Name" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:330 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:344 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:333 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:394 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:233 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:312 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:320 msgid "Name can only contain alphanumeric characters, dashes, and underscores" msgstr "" @@ -2623,7 +2623,7 @@ msgstr "" msgid "New Custom Show" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:78 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:79 msgid "New Emby Media Source" msgstr "" @@ -2635,11 +2635,11 @@ msgstr "" msgid "New Local Media Source" msgstr "" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:75 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:78 msgid "New Media Source" msgstr "" -#: src/components/settings/media_source/PlexServerEditDialog.tsx:78 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:79 msgid "New Plex Server" msgstr "" @@ -2711,9 +2711,9 @@ msgstr "" msgid "Not a valid number" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:282 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:296 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:216 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:283 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:344 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:217 msgid "Not a valid URL" msgstr "" @@ -2781,8 +2781,8 @@ msgstr "" msgid "Options" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:418 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:448 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:428 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:501 msgid "OR" msgstr "" @@ -2858,12 +2858,12 @@ msgstr "" msgid "Pad Times" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:85 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:122 msgid "Passthrough audio unchanged. Other settings will not apply." msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:382 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:407 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:388 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:457 msgid "Password" msgstr "" @@ -3030,9 +3030,9 @@ msgstr "" msgid "Properties" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:284 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:298 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:218 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:285 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:346 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:219 msgid "Protocol must be HTTP or HTTPS" msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Running..." msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:172 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:209 msgid "Sample rate cannot be changed when copying input audio" msgstr "" @@ -3449,9 +3449,9 @@ msgstr "" msgid "Selected Subtitle" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:305 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:319 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:239 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:307 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:368 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:241 msgid "Server is unreachable" msgstr "" @@ -4006,11 +4006,11 @@ msgstr "" msgid "Today" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:390 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:447 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:416 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:464 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:273 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:397 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:460 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:466 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:520 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:278 msgid "toggle access token visibility" msgstr "" @@ -4085,6 +4085,18 @@ msgstr "" msgid "Tunarr runs various tasks, sometimes on a schedule, for background operations." msgstr "" +#: src/components/settings/media_source/PlexServerEditDialog.tsx:355 +msgid "Tunarr will attempt to get Plex to pull Tunarr's updated XMLTV upon regeneration" +msgstr "" + +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:571 +msgid "Tunarr will update Jellyfin's \"now playing\" state while channels are active." +msgstr "" + +#: src/components/settings/media_source/PlexServerEditDialog.tsx:375 +msgid "Tunarr will update Plex's \"now playing\" state while channels are active." +msgstr "" + #: src/pages/settings/HdhrSettingsPage.tsx:105 #: src/pages/settings/HdhrSettingsPage.tsx:108 msgid "Tuner Count" @@ -4122,16 +4134,21 @@ msgstr "" #~ msgid "Unlink from group" #~ msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:499 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:516 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:514 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:596 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:338 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:360 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:394 msgid "Update" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:291 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:305 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:225 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:568 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:372 +msgid "Update Play Status" +msgstr "" + +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:292 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:353 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:226 #: src/pages/settings/MediaSourceSettingsPage.tsx:88 msgid "URL" msgstr "" @@ -4148,8 +4165,8 @@ msgstr "" msgid "Use these settings to override global ffmpeg settings for this channel." msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:357 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:376 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:361 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:426 msgid "Username" msgstr "" diff --git a/web/src/locales/es/messages.ts b/web/src/locales/es/messages.ts index 731487c79..95077bf61 100644 --- a/web/src/locales/es/messages.ts +++ b/web/src/locales/es/messages.ts @@ -1 +1,4 @@ -/*eslint-disable*/import type{Messages}from"@lingui/core";export const messages=JSON.parse("{\"++nzCr\":[\"Bit Depth\"],\"+2JHIs\":[\"Link to existing slot\"],\"+406Vu\":[\"View Full Details\"],\"+4YwQF\":[\"# of Programs\"],\"+4mjS6\":[\"Remove icon\"],\"+9EErD\":[\"Music Videos\"],\"+DmLct\":[\"Programs\"],\"+SA5Ao\":[\"A root path to scan for media. Local sources can search many different paths.\"],\"+TZiPJ\":[\"Server is unreachable\"],\"+UPOiB\":[[\"count\",\"plural\",{\"one\":[\"min\"],\"other\":[\"mins\"]}]],\"+Xg5cX\":[\"Filler is picked fresh at stream time like Flex time. The guide shows \\\"Commercial Break\\\" placeholders.\"],\"+YdE7b\":[\"Enable rolling log files using time and/or size based criteria\"],\"+hl/7A\":[\"Channels configured to use the HLS Direct stream mode will output in the selected container format.\"],\"+k9lxR\":[\"Enter a name for your Local Media Source\"],\"+mdNfU\":[[\"count\",\"plural\",{\"one\":[\"#\",\" track\"],\"other\":[\"#\",\" tracks\"]}]],\"+suWTj\":[\"Adds Flex breaks between programs, attempting to avoid groups of consecutive programs that exceed the specified number of minutes.\"],\"+tlhMz\":[\"Plex (Manual)\"],\"+yEE7s\":[\"New Media Source\"],\"+yOcRn\":[\"HDHR\"],\"+ya1pX\":[\"Delete Slot\"],\"+zY9Xc\":[\"Configure Cyclic Shuffle\"],\"+zy2Nq\":[\"Type\"],\"/+ZaFm\":[\"Soundtrack\"],\"/4gGIX\":[\"Copy to clipboard\"],\"/6iIT9\":[\"Settings Saved!\"],\"/DTWjr\":[\"Congrats, you're ready to start building channels! Just click Finish below to start working on your first channel.\"],\"/QmYEW\":[\"Balance...\"],\"/TEOcd\":[\"Presets\"],\"/e88IO\":[\"Schedule programming in blocks that are either count or duration based. Can be used to generate random schedules.\"],\"/gavzH\":[\"Basic button group\"],\"/j3jjC\":[\"Error while saving settings. Please check console for details.\"],\"/n/HCO\":[\"Keywords\"],\"/rTz0M\":[\"Audio\"],\"/vJase\":[\"Streaming\"],\"09gg05\":[\"Programming\"],\"0IAEaX\":[\"Match\"],\"0MWZh1\":[\"Search is currently scoped to this Media Source Library.\"],\"0VHz2s\":[\"Filler Options\"],\"0cULRy\":[\"Experimental: Make perfect schedule loop\"],\"0dy9K6\":[\"Read Less\"],\"0mEBXY\":[\"Delete Transcoding Config \\\"\",[\"0\"],\"\\\"?\"],\"0wJVK+\":[\"Basic\"],\"0zpgxV\":[\"Options\"],\"1/dAym\":[\"Grouping works as follows:\"],\"14PdY0\":[\"Config\"],\"1AdBl9\":[\"Break Positioning\"],\"1BDPP1\":[\"Looks like something went wrong.\"],\"1BGQfg\":[\"Alphabetically\"],\"1CFAQ+\":[\"Set by environment variable\"],\"1DxLRi\":[\"No programming scheduled for this time period\"],\"1PQRWr\":[\"Start Time\"],\"1QfxQT\":[\"Dismiss\"],\"1TYXl0\":[\"Enter your Emby password to generate a new access token.\"],\"1V3Prt\":[\"Deleting a Filler will remove all programming from the channel. This action cannot be undone.\"],\"1Z90J4\":[\"Days to Precalculate\"],\"1hKEom\":[\"Priority\"],\"1jqDmP\":[\"Successfully scheduled \",[\"taskId\"],\" (running in background).\"],\"1njn7W\":[\"Light\"],\"2BBAbc\":[\"List\"],\"2BRPyl\":[\"System Info\"],\"2CVuYr\":[\"Smart Collection - \",[\"0\"]],\"2L7cj6\":[\"You haven't created any channels yet.\"],\"2QLniG\":[\"Existing query: \",[\"filterString\"]],\"2eFlmt\":[\"Tracks\"],\"2hOCU2\":[\"Smart Collections\"],\"2imNg3\":[\"Web version = \",[\"0\"],\", Server version = \",[\"1\"]],\"2mAJXf\":[\"Makes multiple copies of the schedule and plays them in sequence. Normally this isn't necessary, because Tunarr will always play the schedule back from the beginning when it finishes. But creating replicas is a useful intermediary step sometimes before applying other transformations. Note that because very large channels can be problematic, the number of replicas will be limited to avoid creating really large channels.\"],\"2oWehJ\":[\"Reset to current date/time\"],\"2vxecF\":[\"Show Stealth\"],\"2x4THe\":[\"\\\"\",[\"0\"],\"\\\" Sessions\"],\"312fSE\":[\"Select Shows to Remove\"],\"315BhT\":[\"Alphabetical\"],\"3JIYke\":[\"Healthy?\"],\"3JQkm5\":[\"Path Replacements\"],\"3JjdaA\":[\"Run\"],\"3LfNqe\":[\"Channel Number\"],\"3SH6Vv\":[\"Copied channel \\\"\",[\"channelName\"],\"\\\" m3u link to clipboard\"],\"3YNjnA\":[\"System Environment\"],\"3b1vGb\":[\"New Local Media Source\"],\"3mAQJI\":[\"How often the XMLTV file is regenerated\"],\"3nLdaX\":[\"Add \",[\"0\"]],\"3nwcC5\":[\"Filler - \",[\"0\"]],\"49dCCB\":[\"Use Show Poster\"],\"4Fpcxu\":[\"Initial Delay (minutes)\"],\"4NbDEd\":[\"Deleting a Custom Show will remove its programming from channels that use it. This action cannot be undone.\"],\"4Uc/2h\":[\"Server Listen Port\"],\"4VxpoP\":[\"Music tracks are grouped by artist\"],\"4XSc4l\":[\"Weekly\"],\"4XfYeY\":[\"Random (by show)\"],\"4fLgiT\":[\"Allow Image Based\"],\"4qmJK4\":[\"Tunarr Backend URL\"],\"4wkwyL\":[\"Disable Hardware Filters\"],\"4yQF++\":[\"Custom show programs are grouped by their parent show\"],\"50whWJ\":[\"XMLTV Link:\"],\"53/4tH\":[\"Audio Options\"],\"536Xwe\":[\"Error copying to clipboard!\"],\"53tfay\":[\"This allows to schedule specific shows to run at specific time slots of the day or a week. It's recommended you first populate the channel with the episodes from the shows you want to play and/or other content like movies and redirects.\"],\"5ABghp\":[\"FFmpeg Settings\"],\"5V93hk\":[\"Schedule programming using slots assigned a start time and duration.\"],\"5WeWGz\":[\"Selected Subtitle\"],\"5k0NLb\":[\"Review\"],\"5lSgNP\":[\"Enable SSDP server\"],\"5nsbxB\":[\"Alternates TV shows in blocks of episodes. You can pick the number of episodes per show in each block and if the order of shows in each block should be randomized. Movies are moved to the bottom.\"],\"5qV3NN\":[\"Flex Style\"],\"5yIPLp\":[\"Oops!\"],\"6/dCYd\":[\"Overview\"],\"63/DSM\":[\"Transcoding Configs\"],\"63driG\":[\"Stream JSON\"],\"67RoFa\":[\"Pipeline\"],\"6Y9c2m\":[\"This slot is linked with \",[\"0\"],\" other slot(s). Content fields are shared across the group.\"],\"6YtxFj\":[\"Name\"],\"6ZMWKw\":[\"XMLTV\"],\"6bbWRs\":[\"Add programming to custom show\"],\"6dvIbw\":[\"Unlink\"],\"6jAi8c\":[\"Range\"],\"6jfS51\":[\"Welcome\"],\"6ki7F2\":[[\"0\",\"plural\",{\"one\":[\"#\",\" item\"],\"other\":[\"#\",\" items\"]}]],\"6mJ9tF\":[\"FFMPEG is not detected.\"],\"6mpwdR\":[\"Match all of\"],\"6pL6be\":[\"Configure what appears on your channel when there is no suitable filler content available. Using channel fallbacks requires ffmpeg transcoding.\"],\"6w0yiE\":[\"FFMPEG Log Level\"],\"6zfUar\":[\"Stream Selection\"],\"71O7b0\":[\"Media Info\"],\"73XwX0\":[\"No programs selected\"],\"73flfT\":[\"QSV Device\"],\"7B3lfh\":[\"Items from any filler list will not be chosen more frequently than this cooldown setting.\"],\"7LWPgS\":[\"Enabled (loudnorm)\"],\"7ODkf5\":[\"Log level to pass to ffmpeg. Read more about ffmpeg's log levels <0>here\"],\"7Q5AKf\":[[\"count\",\"plural\",{\"one\":[\"track\"],\"other\":[\"tracks\"]}]],\"7b2stB\":[\"Media Type\"],\"7eMo+U\":[\"Go Home\"],\"7eZlTH\":[\"Sort TV Shows (asc)\"],\"7iJlKU\":[\"Please choose a value greater than 1\"],\"7pMNGK\":[\"Programs saved!\"],\"7sNhEz\":[\"Username\"],\"7tvV2B\":[\"Min Duration (minutes)\"],\"7uohY3\":[\"TV shows are grouped by show\"],\"80t7Ii\":[\"Increasing \\\"Max Lateness\\\" for the schedule.\"],\"87a/t/\":[\"Label\"],\"8E9KXK\":[\"Feature flags saved!\"],\"8MIU1T\":[\"Program\"],\"8TMaZI\":[\"Timestamp\"],\"8ZsakT\":[\"Password\"],\"8vETh9\":[\"Show\"],\"8wngZM\":[\"Fallback\"],\"8wu9lr\":[\"Queued\"],\"9+90+V\":[\"Enable Log File Rolling\"],\"94qSvE\":[\"Synced with external playlist\"],\"96zw7M\":[\"This show is marked as missing in the database.\"],\"983IRa\":[\"All linked slots show the same episode, advancing only after all have played.\"],\"9E+eyD\":[\"Output video at a constant frame rate.\"],\"9E9tRC\":[\"Fill with Flex\"],\"9Eq43e\":[\"If set, all watermark overlays will be disabled for channels assigned this transcode config.\"],\"9GPYnX\":[\"Do not group programs at all. Normal shuffle.\"],\"9WG5wy\":[\"Specials\"],\"9asVsi\":[\"How long each commercial break lasts\"],\"9qdNKR\":[\"Error Options\"],\"9sqrEU\":[\"Filler List\"],\"9td1Wl\":[\"Check\"],\"9vtG84\":[\" Scheduling Strategy\"],\"A+GCyx\":[\"Hide Advanced\"],\"A0+T6c\":[\"Reset Changes\"],\"A1taO8\":[\"Search\"],\"A7WmPm\":[\"New Plex Server\"],\"A9Rhec\":[\"Channel Name\"],\"ACKu03\":[\"Refresh Preview\"],\"AKjNTL\":[\"Add Padding\"],\"AM972O\":[\"Add Redirect\"],\"ANICN0\":[\"No media sources connected.\"],\"AO2Z5d\":[\"Movie, \",[\"0\"]],\"AOHgZp\":[\"Episodes\"],\"AVKoQM\":[\"Redirect to \\\"\",[\"0\"],\"\\\"\"],\"AXg7m0\":[\"Search is currently scoped to this Media Source.\"],\"AXjA78\":[\"Field\"],\"AdfhAd\":[\"If there are issues playing a video, Tunarr will try to use an error screen as a placeholder while retrying loading the video every 60 seconds.\"],\"AdogaJ\":[\"Pipeline Steps\"],\"AlfqgK\":[\"Watch\"],\"ApsQAb\":[\"HDHR: Loading...\"],\"AyInY5\":[\"Video Options\"],\"AzCYkg\":[\"Connect Media Sources\"],\"B+HsXP\":[\"FFMPEG: \",[\"0\"]],\"B1NOvD\":[\"Removes all programs from schedule\"],\"B1W8vw\":[\"Delete \\\"\",[\"0\"],\"\\\"\"],\"BGHH1t\":[\"Min. Visible in Guide Duration Program (seconds)\"],\"BJjJuo\":[\"EPG (Hours)\"],\"BMlGCC\":[\"Click to preview the items in this Custom Show. Note that only the whole show can be added at once.\"],\"BQsifH\":[\"Stream Info\"],\"BWTzAb\":[\"Manual\"],\"BXXjCD\":[\"FFmpeg not found. For all features to work, we recommend installing FFmpeg 7.1+ or update your FFmpeg executable path in settings.\"],\"BaUuhR\":[\"Codec\"],\"BlmmxH\":[\"FFmpeg Log\"],\"Bq0ryo\":[\"Reset Options\"],\"BtL93c\":[[\"0\",\"plural\",{\"one\":[\"#\",\" source connected.\"],\"other\":[\"#\",\" sources connected.\"]}]],\"C4KL42\":[\"Consolidates contiguous match flex and redirect blocks into singular spans\"],\"C6jEO3\":[\"Log Level\"],\"CAiikc\":[\"Enter your Jellyfin password to generate a new access token.<0/><1>NOTE: These are never saved to the Tunarr DB. Instead they are sent to Jellyfin to exchange for a session token.\"],\"CJkEfx\":[\"Block\"],\"CKQ3t3\":[\"Total Runtime\"],\"CMQ09J\":[\"Scanning\"],\"COv7As\":[\"Cooldown (seconds)\"],\"CRsuq4\":[\"Every\"],\"CVqySE\":[[\"len\",\"plural\",{\"one\":[\"There is \",\"#\",\" warning. Click for details.\"],\"other\":[\"There are \",\"#\",\" warnings. Click for details.\"]}]],\"CWRFGq\":[\"Modify Programming\"],\"CXDHcv\":[\"Grid\"],\"CcX8VV\":[\"Completely randomizes the order of programs.\"],\"CeyB7O\":[\"FFmpeg Executable Path\"],\"CfOWar\":[\"Logarithmic decay, lighter weighting.\"],\"CfUvtM\":[\"Error saving new Smart Collection. Check server logs and browser console for details.\"],\"CfxLtO\":[\"Program JSON\"],\"Cko536\":[\"Descending\"],\"Cp5Awv\":[\"Duration must be greater than 0.\"],\"CqSP2T\":[\"Edit Channel Redirect\"],\"CsrDsg\":[\"12-hour\"],\"Cxqf0C\":[\"Plex (Auto)\"],\"D+NlUC\":[\"System\"],\"D1Fhv3\":[[\"count\",\"plural\",{\"one\":[\"episode\"],\"other\":[\"episodes\"]}]],\"DPfwMq\":[\"Done\"],\"DRya1t\":[\"Audio Volume\"],\"DSwJ9W\":[\"Enable Animation\"],\"DUd3Ss\":[\"Sorts the list by TV Show and the episodes in each TV show by their season/episode number. Movies are moved to the bottom of the schedule.\"],\"DbouLP\":[\"Back to Programming\"],\"Dd9orS\":[\"Remove All \",[\"movieCount\"],\" \",[\"movieCount\",\"plural\",{\"one\":[\"Movie\"],\"other\":[\"Movies\"]}]],\"Dnn2XG\":[\"Automatic\"],\"DoJzLz\":[\"Collections\"],\"DxvGLB\":[\"Add Slot\"],\"E/QGRL\":[\"Disabled\"],\"E5ipHC\":[\"Balance By:\"],\"E8oclZ\":[\"Copied Channel ID!\"],\"EKlukx\":[\"Copy Full Report\"],\"EL4/HD\":[[\"0\",\"plural\",{\"one\":[\"program\"],\"other\":[\"programs\"]}]],\"EdQY6l\":[\"None\"],\"EkH9pt\":[\"Update\"],\"Etie0Q\":[\"All channels assigned to this config will be set to use the default configuration. If this is the last configuration, a new default configuration will be created.\"],\"Eu20Os\":[\"Time Slots\"],\"Ev2r9A\":[\"No results\"],\"F1l877\":[\"Subtitle Streams\"],\"F3bW6y\":[\"Platform\"],\"F3smBd\":[\"Maximum number of days to precalculate the schedule. Note that the length of the schedule is also bounded by the maximum number of programs allowed in a channel.<0/><1>Note: Previewing the schedule in the browser for long lengths of time can cause UI performance issues\"],\"FDEfoy\":[\"Deleting a media source will remove all of its associated programs from Tunarr.\"],\"FXCwT9\":[\"FFprobe Executable Path\"],\"FZg3wM\":[\"Operation\"],\"FmN5me\":[\"Resolution\"],\"FnChN1\":[\"Enable <0>EBU R 128 loudness normalization via the <1>loudnorm FFmpeg filter. May increase CPU usage during streaming.\"],\"Fp7p73\":[\"Time between subsequent breaks\"],\"FqCHF/\":[\"Threads\"],\"FrRP21\":[\"There was an error when submitting the form. Please see console logs for details.\"],\"FsF4bb\":[\"Audio Loudness Normalization\"],\"FssFce\":[\"Configure preferred audio languages globally.\"],\"Fzn/BQ\":[\"Release Date\"],\"G+8qH5\":[\"Channel name is required\"],\"GDKKxT\":[\"Access Token\"],\"GHOK4Z\":[\"Time Format\"],\"GJ1P5j\":[\"File a Bug Report\"],\"GKLqtE\":[\"Set the host of your Tunarr backend. When empty, the web UI will use the current host/port to communicate with the backend.\"],\"GLOZdc\":[\"Custom Shows\"],\"GP/CFo\":[\"HW Accel\"],\"GQ3O42\":[\"Trash\"],\"GRCrpV\":[\"Manage Libraries\"],\"GUtCZC\":[\"Version: \",[\"0\"]],\"GhZ4GX\":[\"Error while copying to clipboard. Check browser logs for details\"],\"GmP0oY\":[\"Slot Warnings\"],\"GmTnBN\":[\"Enable ffmpeg logging to different sinks. Outputting to a file will create a new log file for every spawned ffmpeg process in the Tunarr log directory. These files are automatically cleaned up by a background process.\"],\"Gr1Ik2\":[\"Nvidia Capabilities\"],\"GtycJ/\":[\"Tasks\"],\"GzzMwi\":[\"Roll on Schedule\"],\"H0QGc9\":[\"Filler List Cooldown (seconds)\"],\"H1OFlu\":[\"Inverse linear decay, heavier weighting.\"],\"H1V+2G\":[\"To use Tunarr, you must first connect at least one media source. Media sources provide all content used to create channels in Tunarr. Plex and Jellyfin are currently supported.\"],\"H3OF1s\":[\"Tuner Count\"],\"H7OUPr\":[\"Day\"],\"H8100o\":[\"Filler lists are collections of videos that you may want to play during 'flex' time segments. Flex is time within a channel that does not have a program scheduled (usually used for padding).\"],\"HDoQBx\":[\"Channel settings saved!\"],\"HEH0PR\":[\"Must define at least one language preference\"],\"HErtdg\":[\"Name can only contain alphanumeric characters, dashes, and underscores\"],\"HLlLPP\":[\"Channel Stream Mode\"],\"HMWEIt\":[\"Edit Flex Time\"],\"HOLbdk\":[\"Failed to load stream details! Check logs for details\"],\"HSfauP\":[\"This slot is linked with \",[\"0\"],\" other \",[\"1\",\"plural\",{\"one\":[\"slot\"],\"other\":[\"slots\"]}],\". Content fields are shared across the group.\"],\"HVpg3x\":[\"Failed to load Smart Collection\"],\"HXx+vU\":[\"Controls what happens when this slot runs out of replayed content from earlier continue slots.\"],\"HYCPKT\":[\"Add Selected Media\"],\"HajiZl\":[\"Month\"],\"HdE1If\":[\"Channel\"],\"Hjfx9G\":[\"Audio & Subtitles\"],\"HmHwcC\":[\"Fixed Interval\"],\"HptUxX\":[\"Number\"],\"HqUilK\":[\"Keywords perform full text search across all (or configured) fields\"],\"HzV8B2\":[\"Skip mid-roll for programs shorter than this\"],\"I+FvbD\":[\"Scan\"],\"I2Bar3\":[\"Shows\"],\"I5BU70\":[\"Smart Collection: \",[\"0\"]],\"I6gXOa\":[\"Path\"],\"IDlmXg\":[\"Tunarr Backend URL:\"],\"IFiQdD\":[\"Channels M3U Link:\"],\"IMxI++\":[\"Not a valid URL\"],\"INCbO6\":[\"On-Demand channels resume from where you left off. Programming is paused when the channel is not streaming.<0/><1>NOTE: While the channel is inactive, the TV Guide for the channel will be empty.\"],\"IagCbF\":[\"URL\"],\"IetKlB\":[\"New Custom Show\"],\"IgC1fP\":[\"Enable light Mode\"],\"IiBgkW\":[\"Failed to update Media Source settings. Please check server and browser logs for details.\"],\"IoSxk9\":[\"Protocol must be HTTP or HTTPS\"],\"IvkbIT\":[\"Read More\"],\"J/eF78\":[\"Removing overrun programs from the channel.\"],\"J0NKO1\":[\"Exclude Seasons\"],\"J2eKUI\":[\"File\"],\"J2lnQW\":[\"Pre\"],\"J41wt0\":[\"Slot Editor\"],\"J4Ngmi\":[\"Loop Short Programs\"],\"J50/e4\":[\"Filter Type\"],\"J8X80J\":[\"Stealth?\"],\"JCGCcQ\":[\"Sorts everything by its release date. This will only work correctly if the release dates in Plex are correct. In case any item does not have a release date specified, it will be moved to the bottom.\"],\"JCOZTc\":[\"Audio & Subtitle Options\"],\"JOFDLs\":[\"Program Playback Troubleshooter\"],\"JeAvlS\":[\"Pad Times\"],\"JeL1O4\":[\"Redirect duration\"],\"Jj3SJk\":[\"A-Z (asc)\"],\"JmZ/+d\":[\"Finish\"],\"Jpe9a8\":[\"Attempts to balance programming groups by either total lineup duration or number of unique programs. For instance, for a channel with many seasons of one show and few seasons of another, balancing will attempt to create an even mix of both shows by inserting repeats of the show with fewer episodes.\"],\"JryIGL\":[\"Adjust Weights\"],\"Jsel0T\":[\"This channel has an existing time slot schedule. A channel can only use one scheduling type at a time. Saving a schedule here will remove the existing time slot schedule.\"],\"Jtbzxr\":[\"Version: unknown\"],\"JxE+Bh\":[\"Allows you to pick specific programming to remove from the channel.\"],\"JyHA6G\":[\"Displays the last \",[\"0\"],\" system log events. Use the buttons below to export these logs or download the entire log file for debugging.\"],\"JzJk+4\":[\"Add Language Preference\"],\"K09nyY\":[\"Linked slots advance episode progression together sequentially.\"],\"K8+dbZ\":[[\"totalConnections\"],\" total\"],\"K9pQ8Q\":[\"Disable Watermarks\"],\"KRjDf4\":[\"Audio Streams\"],\"Khe/Vb\":[\"Watch Channel\"],\"KkOthv\":[\"Guide\"],\"Km5fSd\":[\"If you are confident FFMPEG is installed, you may just need to update the executable path in the settings. To do so, simply click Edit above to update the path.\"],\"L+8pV5\":[\"Sync with external playlist\"],\"L/KmPM\":[\"Usually slots need to add flex time to ensure that the next slot starts at the correct time. When there are multiple videos in the slot, you might prefer to distribute the flex time between the videos or to place most of the flex time at the end of the slot.\"],\"L6Mhe6\":[\"You have unsaved changes!\"],\"L8Hb+D\":[\"Sets the number of threads used to decode the input stream. Set to 0 to let ffmpeg automatically decide how many threads to use. Read more about this option <0>here. <1>Note: this option is overridden to 1 when using hardware accelearation for stability reasons.\"],\"LKPR6G\":[\"Playlist\"],\"LKSv28\":[\"Smart Collections are self-updating content lists. You set the query and the collection automatically adds any new content from your library that fits those rules. Any newly added content matching query will not modify existing channel programming at this time.\"],\"LMMGPr\":[\"Submitting...\"],\"LRvqnF\":[\"Error saving new Jellyfin server. See browser console and server logs for details\"],\"LTC198\":[\"Running...\"],\"LTYRAI\":[\"View Library\"],\"LiCr5o\":[\"Limit must be numeric\"],\"MHrjPM\":[\"Title\"],\"MKK96e\":[\"View Collection\"],\"MR6Nlf\":[\"Change the verbosity of specific categories of logs. Useful if debugging a specific feature.\"],\"MS1Dhi\":[\"Max file size (bytes)\"],\"MVBLYK\":[\"Remove...\"],\"MW42Hp\":[\"Customize how movie blocks are sorted\"],\"Md/eZS\":[[\"count\",\"plural\",{\"one\":[\"#\",\" item\"],\"other\":[\"#\",\" items\"]}]],\"MfkGXC\":[\"Shuffle Grouping\"],\"MkMcGz\":[\"Refresh Libraries\"],\"Ml7h3C\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Program\"],\"other\":[\"#\",\" Programs\"]}]],\"Mrdyk9\":[\"Genre\"],\"Mv+xQh\":[\"New Channel\"],\"N15e5e\":[\"Remove custom icon\"],\"NGOfis\":[\"Disable Image Scaling\"],\"NGSThJ\":[\"Smart Collection\"],\"NL/bON\":[\"FFmpeg Command\"],\"NQ7yht\":[\"Must use a valid URL, or empty.\"],\"NaDxQ2\":[\"Auto Deinterlace Video\"],\"Nb+B9K\":[\"Adjust the output volume (not recommended). Values higher than 100 will boost the audio.\"],\"NcV1df\":[\"Pad Start Times\"],\"NfTP7a\":[\"Advanced options relating to audio. In general, do not change these unless you know what you are doing!\"],\"NfZ8rc\":[\"24-hour\"],\"Nkn5MW\":[\"Removes all Flex periods from the schedule.\"],\"NnH3pK\":[\"Test\"],\"NnuRri\":[\"This allows you to pick the weights for each of the shows, so you can decide that some shows should be less frequent than other shows.\"],\"NtQvjo\":[\"Period\"],\"Nu4oKW\":[\"Description\"],\"Ny7dz3\":[\"Albums\"],\"NyfQ4q\":[\"Save as Smart Collection\"],\"O1xfOi\":[\"Random...\"],\"O5izWu\":[\"This custom show is synced with an external playlist. Content is updated automatically and cannot be edited manually.\"],\"O8g6Na\":[\"Last Scanned: \",[\"0\"]],\"OPw3KG\":[\"Connect Media Source\"],\"OVmXHk\":[\"Refresh Timer (Hours)\"],\"Ob+B6e\":[\"Buffer size cannot be changed when copying input audio\"],\"OfC/JK\":[\"Custom Show - \",[\"0\"]],\"OfYtUi\":[\"Filler Content\"],\"OfhWJH\":[\"Reset\"],\"OrDu0o\":[\"Video Buffer Size\"],\"Osn70z\":[\"Debug\"],\"P/TyYO\":[\"The type of media in the provided paths\"],\"P1BU0j\":[\"Frame Rate\"],\"P29ZKI\":[\"Enter a name for your Emby Server\"],\"P2DGHD\":[\"Programming starts at \",[\"startTime\"],\" and stops at \",[\"endTime\"]],\"P3i3NN\":[\"Edit Channel Settings\"],\"P6Io39\":[\"Max Lateness\"],\"P6c7YE\":[\"Remove Programming\"],\"PCBfmf\":[\"Renders a channel icon (also known as bug or Digital On-screen Graphic) on top of the channel's stream.\"],\"PJ/u9s\":[\"Copied \",[\"0\"],\" URL to clipboard\"],\"PT6k0T\":[\"Pixel Format\"],\"PX1WM1\":[\"Successfully emptied trash.\"],\"Pazp7r\":[\"There was an error generating time slots. Check the browser console log for more information\"],\"PeBTGz\":[\"Clear Schedule\"],\"PeBylA\":[\"You must create at least one <0>filler list before assigning filler to a lot.\"],\"Pfatg8\":[[\"minutes\",\"plural\",{\"one\":[\"#\",\" minute\"],\"other\":[\"#\",\" minutes\"]}]],\"PgdRhI\":[\"Weighting\"],\"Ph+yE0\":[\"0 mins\"],\"PhKcf0\":[\"Edit Transcode Config\"],\"PiY0nu\":[\"You have no Filler Lists. Create your first Filler List <0>here.\"],\"Pol2QS\":[\"Emby\"],\"PpZkda\":[\"Features\"],\"PwpUBp\":[\"This is the name of the fake program that will appear in the TV guide when there are no programs to display in that time slot guide, e.g when a large Flex block is scheduled.\"],\"Pwqkdw\":[\"Loading…\"],\"Q8L6q9\":[\"Video Streams\"],\"QAUrt0\":[\"Refresh Page\"],\"QEb4hu\":[\"Stealth Mode\"],\"QG2xdt\":[\"Create Rerun Block\"],\"QHRTYn\":[\"Slots Editor...\"],\"QKMxhc\":[\"Tunarr runs various tasks, sometimes on a schedule, for background operations.\"],\"QUxTIQ\":[\"Filler is resolved at schedule time. The guide shows specific filler titles.\"],\"Qll2Tb\":[\"Desc\"],\"QlrQ/Z\":[\"Next Scheduled Execution\"],\"Qm1NmK\":[\"OR\"],\"Qu844y\":[\"Time Slot Editor\"],\"QvKdb0\":[\"Placeholder Program Title\"],\"Qx971g\":[\"After Every\"],\"R/7J0Z\":[\"Artists\"],\"R/N+HY\":[\"No programming added yet\"],\"R/xSFi\":[\"Editing \\\"\",[\"0\"],\"\\\"\"],\"R0yni2\":[\"Attempt Auto-Fix\"],\"R40oLk\":[\"Will force use of a software encoder despite hardware acceleration settings.\"],\"R6kHq+\":[\"Link Mode\"],\"R9Khdg\":[\"Auto\"],\"RCeEAd\":[\"Global Options\"],\"RGf6l7\":[\"Select a slot to link to\"],\"RI4u49\":[\"<0>You can edit this location in your settings.json within your Tunarr data directory<1/><2>NOTE: When manually adding the XMLTV location to a client like Plex, do not use this file directly. Instead, use the generated XMLTV from the Tunarr API endpoint: \",[\"0\"],\"\"],\"RTxUjI\":[\"Copy to Clipboard\"],\"RUYsn0\":[\"Clear All\"],\"RVl9/c\":[\"Alternate programs in blocks. You can pick the number of programs per-type in each block and if the order of shows in each block should be randomized.\"],\"RYP47R\":[[\"0\",\"plural\",{\"one\":[\"Day\"],\"other\":[\"Days\"]}]],\"RYlQY0\":[\"Repeats\"],\"RaHlqV\":[[\"totalConnections\",\"plural\",{\"one\":[\"#\",\" connection\"],\"other\":[\"#\",\" connections\"]}]],\"RavMGr\":[[\"count\",\"plural\",{\"one\":[\"second\"],\"other\":[\"seconds\"]}]],\"RbgUS/\":[\"Copy Channel ID\"],\"RtPRIb\":[\"Maximum number of days to precalculate the schedule. Note that the length of the schedule is also bounded by the maximum number of programs allowed in a channel.\"],\"RxzN1M\":[\"Enabled\"],\"S/CawK\":[\"Movies are grouped altogether\"],\"S5v5/h\":[\"Enabling embedded subtitle extaction will periodically scan your upcoming programming for embedded text-based subtitle streams and extract them to a local cache. This is necessary in order to enable subtitle burning for text-based subtitles which are not external streams.\"],\"S60KP9\":[\"Server Settings\"],\"S8zZJK\":[\"Welcome to Tunarr!\"],\"SBtwzo\":[\"Version Mismatch!\"],\"SCZJhh\":[\"Audio Bitrate\"],\"SFjIKS\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Selected Item\"],\"other\":[\"#\",\" Selected Items\"]}]],\"SOXW6w\":[\"All Genres\"],\"SY1gRl\":[\"Media Source\"],\"SYGPcm\":[\"You have no smart collections. Smart collections can be created on the <0>search page.\"],\"SZcfpX\":[\"Pad Style\"],\"SZzr30\":[\"The selected languages will be considered in order they are selected.\"],\"Sbs5dW\":[\"Filler\"],\"Sg3laT\":[\"Min Duration\"],\"SoRsRS\":[\"Calculates a schedule where all programs end at the same time, creating a perfectly looping schedule.\"],\"SuubHr\":[\"Deleting a Plex server will remove all programming from your channels associated with this plex server. Missing programming will be replaced with Flex time. This action cannot be undone.\"],\"SywaS+\":[\"Data Directory:\"],\"T5wfux\":[\"Makes multiple copies of the schedule and plays them in sequence\"],\"T8drou\":[\"System Health\"],\"TEM0vH\":[\"Removes all programs from custom show\"],\"TMADKS\":[\"Divides the programming in blocks of 4, 6, 8 or 12 hours then repeats each of the blocks the specified number of times.\"],\"TMju4P\":[\"Delete Media Source \\\"\",[\"0\"],\"\\\"?\"],\"TS0lwx\":[\"Encountered an error when emptying trash. Check console logs for details.\"],\"TZKpsF\":[\"No Media Sources detected.\"],\"TpqW74\":[\"Fixed\"],\"Ts6Zfm\":[\"Error updating Smart Collection. Check logs for details.\"],\"Ts8Q+i\":[\"EPG\"],\"TvY/XA\":[\"Documentation\"],\"Tz0i8g\":[\"Settings\"],\"TzyoiK\":[\"When enabling, Tunarr will generate an initial backup immediately\"],\"U0sC6H\":[\"Daily\"],\"U3+jR/\":[\"Replicate Programs\"],\"UC1lMc\":[\"Failed to save feature flags.\"],\"UE2eVC\":[\"Sorts alphabetically by program title\"],\"UHu/Uf\":[\"Show only synced libraries\"],\"UOMT7z\":[\"This option is disabled because it would calculate a schedule that is too long.\"],\"URmyfc\":[\"Details\"],\"UXC1jS\":[\"NodeJS: \",[\"0\"]],\"UYUgdb\":[\"Order\"],\"UYW9jU\":[\"Successfully ran system fixer \",[\"fixerId\"]],\"Uf/h/w\":[\"Pick specific programming to remove from the channel.\"],\"UirGxE\":[\"Errors\"],\"UnI8zh\":[\"Channel #\",[\"0\"]],\"UweSf9\":[\"Add Channel Redirect\"],\"V8B1wG\":[\"Last synced \",[\"0\"]],\"V9UVpb\":[\"Total hits: \",[\"0\"]],\"VBsY8N\":[\"Set to 0 to never delete backups\"],\"VIHbrI\":[\"Advanced options relating to transcoding. In general, do not change these unless you know what you are doing! These settings exist in order to leave some parity with the old dizqueTV transcode pipeline as well as to provide mechanisms to aid in debugging streaming issues.\"],\"VP2oPP\":[\"Slots\"],\"VVAgOP\":[\"Rescan Interval (hours)\"],\"VXdzY3\":[\"Disable Hardware Encoding\"],\"Va3xJe\":[\"Add field\"],\"VfWz27\":[\"Weight %\"],\"VlEnCC\":[\"Archive Format\"],\"VlWKwW\":[\"Lazy\"],\"Vmvp5H\":[[\"count\",\"plural\",{\"one\":[\"day\"],\"other\":[\"days\"]}]],\"VrBtVn\":[\"Backups:\"],\"Vw5EeW\":[\"Enable Backups\"],\"VyUuZb\":[\"Image URL\"],\"WAakm9\":[\"Delete Channel\"],\"WDgJiV\":[\"Scanner\"],\"WGkxNZ\":[\"Error querying Plex. Check console log and consider reporting a bug!\"],\"WKHqM+\":[\"Weight\"],\"WMQchs\":[\"Audio Buffer Size\"],\"WT1Ibn\":[\"Last run\"],\"Wb3E4g\":[\"Run now\"],\"Weq9zb\":[\"General\"],\"WhJZoS\":[\"Choose the transcode configuration to use for this channel. Configure transcode configurations on the <0>FFmpeg settings page.\"],\"WjUHH8\":[\"Movie Sort\"],\"WnW1QF\":[[\"block\"],\" Hours\"],\"WzNAIP\":[[\"0\",\"plural\",{\"one\":[\"Hour\"],\"other\":[\"Hours\"]}]],\"X0mSqw\":[\"Will force use of a software filters (e.g. scale, pad, etc.) despite hardware acceleration settings.\"],\"X9EHMa\":[\"Editing Smart Collection \\\"\",[\"0\"],\"\\\"\"],\"XDT85c\":[\"Media Sources\"],\"XIgmo9\":[\"Did not receive an accessToken or userId from Jellyfin server.\"],\"XNtsE7\":[\"Calculating Slots...\"],\"XNw99A\":[\"Software (No GPU)\"],\"XOgcN3\":[\"Filler List: \",[\"0\"]],\"XOuE6F\":[\"This could cause the following slot's programs to go unscheduled. Possible solutions include:\"],\"XSkU3F\":[\"* Restart required\"],\"XWYqJx\":[\"Duplicate Channel\"],\"XXwX66\":[\"Set the log level for the Tunarr server.<0/>Selecting <1>\\\"Use environment settings\\\" will instruct the server to use the <2>LOG_LEVEL environment variable, if set, or system default \\\"info\\\".\"],\"XePUKr\":[\"Test Transcode\"],\"XhWvkJ\":[[\"0\"],\" of \",[\"1\"],\" \",[\"2\"],\" exceed the length of this slot (\",[\"3\"],\"). Average program length: \",[\"4\"]],\"Xkppm4\":[\"Enable Watermark\"],\"Xm/WEQ\":[\"Channel Group\"],\"XsR2HX\":[\"Test Duration (seconds)\"],\"Xuml3I\":[\"By default, time slots are time of the day-based, you can change it to time of the day + day of the week. That means scheduling 7x the number of time slots. If you change from daily to weekly, the current schedule will be repeated 7 times. If you change from weekly to daily, many of the slots will be deleted.\"],\"XwU6BE\":[\"You haven't created any filler lists yet! Go to the <0>Filler Lists page to create one.\"],\"Y2ngGV\":[\"Add a Filler List\"],\"Y5XZLy\":[\"<0>Pad Slot: Align slot start times to the specified pad time.<1/><2>Pad Episode: Align episode start times (within a slot) to the specified pad time. <3>NOTE: Depending on slot length and the chosen pad time, this could potentially create a lot of flex.\"],\"Y84UgQ\":[\"Loudness Target\"],\"YAKCkm\":[\"An error occurred: \",[\"0\"]],\"YDlcs3\":[\"Shuffle Programming\"],\"YLUnu0\":[\"Test Playback\"],\"YN7vx3\":[\"Custom Show\"],\"YRQaPv\":[\"Last Synced\"],\"YRT1+e\":[\"Creates a new collection\"],\"YSptU0\":[\"Replicate...\"],\"YT5/eK\":[\"Media Source: \\\"\",[\"0\"],\"\\\"\"],\"YXwR3a\":[\"Restore default logo\"],\"YY/JN7\":[\" the following day.\"],\"YYLNVW\":[\"Insert breaks at these percentages of the program duration\"],\"YdIZFA\":[\"This channel number has already been used\"],\"Yf/Mtb\":[\"You're All Set!\"],\"Z10t2U\":[\"Removes repeated programs.\"],\"Z3FXyt\":[\"Loading...\"],\"Z4IQ8m\":[\"Channel Transcode Config\"],\"Z5IrB3\":[\"Open in \",[\"0\"]],\"Z6dMWq\":[\"Error while running system fixer \",[\"fixerId\"],\". Check server logs for details.\"],\"ZND/fh\":[\"Cannot be empty\"],\"ZNZzTe\":[\"Cannot disable libraries when they are locked\"],\"ZShzvn\":[\"\\\"\",[\"0\"],\"\\\" Live\"],\"ZWRt1W\":[\"Output Path\"],\"ZkdKVr\":[\"Redirect to Channel \",[\"0\"]],\"Zky8hA\":[\"The image will be rendered at its actual size without any scaling applied.\"],\"Zs2GWW\":[\"New Emby Media Source\"],\"Zul8Ry\":[\"never\"],\"Zvipe1\":[\"Editing Plex Server \\\"\",[\"0\"],\"\\\"\"],\"ZxwuFV\":[\"Deleting a Channel will remove all programming from the channel. This action cannot be undone.\"],\"a+Pr3s\":[\"Apply to Program Types (empty = all)\"],\"a4N/Bg\":[\"Load More\"],\"aE3UMm\":[\"<0>None: slots are picked in the order they are specified in the table (i.e. not randomly)<1/><2>Uniform: all slots have an equal chance to be picked.<3/><4>Weighted: each slot is picked with a specified probability\"],\"aOaCIk\":[\"Allow External\"],\"aScBGS\":[\"Add a filter expression to fine-tune results of the search\"],\"aSwfbR\":[\"Unit\"],\"ak3N0i\":[\"Item was not present during the last scan\"],\"aoLy25\":[\"Opacity\"],\"b0Uv6P\":[[\"0\",\"plural\",{\"one\":[\"Path\"],\"other\":[\"Paths\"]}]],\"b6sx4K\":[\"No active sessions\"],\"bDY29m\":[\"Logarithmic\"],\"bGG6B1\":[\"Jellyfin\"],\"bHNlfr\":[\"Increasing the slot duration.\"],\"bNEQeI\":[\"Cooldown\"],\"bORfbY\":[\"Cannot use a channel number <= 0\"],\"bPJiZF\":[\"Show: \",[\"0\"]],\"bSIBDb\":[\"Release Date (asc)\"],\"bm8pgG\":[\"Add group\"],\"boItSp\":[\"Delete Media Source?\"],\"buS8nL\":[\"Enable Subtitles\"],\"bxyuno\":[\"Override global audio and subtitle settings for this channel.\"],\"bydide\":[\"FFMPEG Log Method\"],\"c6fsNw\":[\"When enabled, intermittent watermarks fade in immediately when a stream is initialized. When disabled, the first watermark fade-in occurs after a full period.\"],\"cF5KzV\":[\"Edit Filler List\"],\"cFTdM+\":[\"Console\"],\"cHYx4E\":[\"Empty Trash\"],\"cLgGtf\":[\"Reset programming to most recently saved state\"],\"cN5Dty\":[\"No Programming scheduled\"],\"cOvZFM\":[\"Dynamic\"],\"cXkSYc\":[\"There was an error submitting the request to update Media Source settings. Please check the form and try again\"],\"caSM6R\":[\"This is used by iptv clients to categorize the channels. You can leave it as 'tunarr' if you don't need this sort of classification.\"],\"cgo+Ch\":[[\"remainingTime\"],\" left\"],\"cheWPw\":[\"Duplicates\"],\"cjX7aq\":[\"Are you sure you want to delete Smart Collection \\\"\",[\"0\"],\"\\\"?\"],\"cmKYIw\":[\"Overflow Behavior\"],\"cmlWKg\":[\"<0>Error deleting custom show: \",[\"0\"],\"<1/>Please consider opening a bug with details!\"],\"cnCAaO\":[\"Percentage-Based\"],\"cnGeoo\":[\"Delete\"],\"cv/ykT\":[\"Search Server URL:\"],\"cxrM1O\":[\"Connect Sources\"],\"d5zxa4\":[\"Local\"],\"d72gcv\":[\"Loudnorm Options\"],\"d9HhJj\":[\"This media source has no enabled or scanned libraries. Enable libraries for this source on the <0>Media Sources page or manually trigger scans on the <1>Library page.\"],\"d9Tsiy\":[\"Error updating channel.<0/>Check browser console for details\"],\"d9XR+x\":[\"Transcode Config <0> <1/>\"],\"dBV/FP\":[\"Lock Weights\"],\"dDX6oS\":[\"Videos from the filler list will be randomly picked to play unless there are cooldown restrictions to place or if no videos are short enough for the remaining Flex time.<0/>Each filler can be assigned a cooldown, which restricts how frequently the list will be chosen during flex time.\"],\"dEgA5A\":[\"Cancel\"],\"dH8AwH\":[\"Add Breaks\"],\"dK3Z9j\":[\"Component\"],\"dQvGiF\":[[\"0\",\"plural\",{\"one\":[\"#\",\" session\"],\"other\":[\"#\",\" sessions\"]}]],\"dScixt\":[\"Enable dark Mode\"],\"dUyQn5\":[\"On-Demand\"],\"daSf8d\":[\"Group episode programs by their show.\"],\"djpQ8z\":[\"Reload Stream\"],\"dkURuB\":[\"Tail Buffer (minutes)\"],\"dnCwNB\":[\"Successfully copied to clipboard!\"],\"eARDm/\":[[\"0\",\"plural\",{\"one\":[\"#\",\" season\"],\"other\":[\"#\",\" seasons\"]}],\", \",[\"1\",\"plural\",{\"one\":[\"#\",\" total episode\"],\"other\":[\"#\",\" total episodes\"]}]],\"eEpDfJ\":[\"Will force use of a software decoder despite hardware acceleration settings.\"],\"eNorwJ\":[\"Programs Too Long\"],\"ePK91l\":[\"Edit\"],\"eSsduj\":[\"VA-API Device\"],\"eZTFiP\":[\"Review Selections\"],\"eZe0fr\":[\"Audio Channels\"],\"ecUA8p\":[\"Today\"],\"efuwN9\":[\"These settings are stored in your browser and are saved automatically when changed.\"],\"eg6m1K\":[\"Edit Transcode Config: \\\"\",[\"0\"],\"\\\"\"],\"ep+NHZ\":[\"If you proceed, all unsaved changes will be lost. Are you sure you want to proceed?\"],\"et+mIi\":[\"Troubleshoot\"],\"euChZN\":[\"Cyclic Shuffle\"],\"euc6Ns\":[\"Duplicate\"],\"exYcTF\":[\"Library\"],\"eyRsaH\":[\"Root\"],\"f0w0IC\":[\"Leave blank to use the channel's icon.\"],\"f6Hub0\":[\"Sort\"],\"f6pgxW\":[\"Temporarily caches responses from Plex based by request path. Could potentially speed up channel editing.\"],\"f7DWm5\":[\"Need at least one path\"],\"fD+lMD\":[\"Select the port the Tunarr server will listen on. This requires a server restart to take effect.\"],\"fI+mNw\":[\"Playlists\"],\"fJfo1A\":[\"Server Path\"],\"fN4bgn\":[\"Delete Filler List \\\"\",[\"0\"],\"\\\"?\"],\"fQ9phi\":[\"Remove All\"],\"fSRZCh\":[\"Restore Default Settings\"],\"fU1065\":[\"Mid-Roll\"],\"fWj7Tt\":[\"Shuffle programming in a channel, optionally grouping programs by certain criteria.\"],\"fcqkKg\":[\"Not found!\"],\"fsBGk0\":[\"Balance\"],\"ftF4U5\":[\"Show Advanced\"],\"fxTyFe\":[\"This slot is linked with \",[\"0\"],\" other \",[\"1\",\"plural\",{\"one\":[\"slot\"],\"other\":[\"slots\"]}],\"Content fields are shared across the group.\"],\"fyo+NB\":[\"The End.\"],\"fzWV5a\":[\"Sort TV Shows (desc)\"],\"g2Pro3\":[\"Reset changes made to the channel's lineup\"],\"g6LxbB\":[\"Break Interval (minutes)\"],\"g7LzUS\":[\"Install FFMPEG\"],\"gBx20d\":[\"Custom Program\"],\"gH5Gbn\":[\"Shuffle\"],\"gJrGqR\":[\"FFmpeg version 7.1+ recommended. Check your current version in the sidebar\"],\"gL9DoB\":[\"Programs shorter than this value will be treated the same as Flex time. Meaning that the TV Guide will try to meld them with the previous program or display the block of programs as the \\\"place holder program\\\" if they make a large continuous group. Use 0 to disable this feature or use a large value to make the channel report only the placeholder program and not the real programming.\\n\",[\"0\"]],\"gR/hgc\":[\"Error Audio\"],\"gcD6jw\":[\"Hide watermark during filler\"],\"gf/bM4\":[\"Continue with New Content\"],\"gg9/ya\":[\"Remove \",[\"count\"],\" \",[\"0\"]],\"ghGSuE\":[\"Ensures programs have a nice-looking start time, it will add Flex time to fill the gaps.\"],\"glVpbE\":[\"Eager\"],\"h/qU8b\":[\"Override the default \",[\"0\"],\" device path (defaults to <0>/dev/dri/renderD128 on Linux and blank otherwise)\"],\"h4yKYk\":[\"Next run\"],\"h8WhoR\":[\"Slot Scheduler\"],\"hBGuBW\":[\"Use channel default\"],\"hBzeL7\":[\"Time before first break\"],\"hG89Ed\":[\"Image\"],\"hISVAG\":[\"Media Sources are where Tunarr sources your content. Media can come from your filesystem or a remote server, like Plex or Jellyfin. At least one Media Source is necessary to create channels and play media in Tunarr.\"],\"hQRttt\":[\"Submit\"],\"hQSabA\":[\"TO\"],\"hXfj39\":[\"Audio Sample Rate\"],\"hXzOVo\":[\"Next\"],\"hYgDIe\":[\"Create\"],\"he3ygx\":[\"Copy\"],\"hehnjM\":[\"Amount\"],\"hhukVU\":[\"Trashed items are items that were previously scanned, but not found in a recent scan. This could be due to missing files or a media server no longer returning the item from its API. These items will be unplayable in channels in their current state. When the trash is emptied, their spots in channels will be replaced with flex.\"],\"hjerov\":[\"Guide Start Time\"],\"hlIKor\":[\"None:\"],\"hnFEC+\":[\"Initial Delay + Interval\"],\"hrdWlG\":[\"Add Show\"],\"hvo+jE\":[\"Add point (%)\"],\"i1+yww\":[\"FFprobe version 6.0+ recommended. Check your current version in the sidebar\"],\"i2QuB6\":[\"Error Screen\"],\"i9rcQ/\":[\"Movies\"],\"iH8pgl\":[\"Back\"],\"iQWhqk\":[\"FFMPEG is installed. Detected version \",[\"0\"]],\"iTjV+L\":[\"A-Z (desc)\"],\"iXJkMB\":[\"Cooldown (s)\"],\"ih+n6S\":[\"Linear\"],\"ihCTE6\":[\"Error occurred while loading channels, please try again soon.\"],\"ihn4zD\":[\"Search…\"],\"ilkCYA\":[[\"0\",\"plural\",{\"one\":[\"Selected Item\"],\"other\":[\"Selected Items\"]}]],\"imrPBy\":[\"Watermark Image URL\"],\"isC0OF\":[\"Use these settings to override global ffmpeg settings for this channel.\"],\"isRobC\":[\"New\"],\"isyw73\":[\"Auto uses the time convention for the selected language.\"],\"jETaUB\":[\"Buffer size effects how frequently ffmpeg reconsiders the output bitrate. <0>Read more\"],\"jHjfnS\":[\"Add filler\"],\"jZlrte\":[\"Color\"],\"jl3Q84\":[\"Create a Channel\"],\"jz1oG0\":[\"Selected Audio\"],\"k6TRai\":[\"FFMPEG transcoding is required for some features like channel overlay, subtitles, and measures to prevent issues when switching episodes.\"],\"kAidIP\":[\"Failed to load feature flags.\"],\"kBJRjR\":[\"Download all logs\"],\"kIYDzY\":[\"Successfully updated Media Source settings.\"],\"kKgsI0\":[\"<0>Configure the directory where Tunarr writes HLS segment files when transcoding. Tunarr will create the target directory (but not intermediate directories) if it doesn't exist.<1/>Changing this field will only affect new sessions. Existing sessions will continue writing to the previous setting, but will clean out segments when the segment ends.<2/>When unset, Tunarr will write segments to its current working directory.\"],\"kKk153\":[\"Load Stream\"],\"kO0aVB\":[\"Break Duration (minutes)\"],\"kThBL9\":[\"Sample rate cannot be changed when copying input audio\"],\"kdkZBD\":[\"Increment\"],\"kii1WH\":[\"Programming Preview\"],\"kolyzq\":[\"This \",[\"0\"],\" is marked as missing in the database.\"],\"kpfZ0g\":[\"Minimum Program Duration (minutes)\"],\"kq6sAD\":[\"Add TV Shows or Movies to filler\"],\"ksFZi3\":[\"<0>Experimental: Enable Plex Request Cache\"],\"kvMAno\":[\"Web Settings\"],\"l/UFPv\":[\"Properties\"],\"l0VyMh\":[\"Flex\"],\"l15zKW\":[\"All Set!\"],\"lBADOx\":[[\"count\",\"plural\",{\"one\":[\"#\",\" episode\"],\"other\":[\"#\",\" episodes\"]}]],\"lC2oeQ\":[\"Max Duration (minutes)\"],\"lCF0wC\":[\"Refresh\"],\"lIUgjN\":[\"Error copying channel m3u link to clipboard\"],\"lJSUC1\":[\"Watermark\"],\"lKCfnI\":[\"Audio Language Preferences\"],\"lS14fB\":[\"Theme Settings\"],\"lW3FB1\":[\"Download last \",[\"0\"],\" \",[\"1\",\"plural\",{\"one\":[\"#\",\" row\"],\"other\":[\"#\",\" rows\"]}]],\"lWmRHf\":[\"Time Slots...\"],\"lZMqZ5\":[\"If enabled, TV show episodes will use the poster of their show, instead of the individual episode poster.\"],\"laQT4o\":[\"Thumbnail URL\"],\"lfFsZ4\":[\"Channels\"],\"lkz6PL\":[\"Duration\"],\"llDXYJ\":[\"Backups\"],\"lnABVQ\":[\"Run Troubleshooter\"],\"m+8qnB\":[\"Library: \",[\"0\"]],\"m0Gp21\":[\"Select a program and channel to test playback. The troubleshooter will analyze stream selection, build the FFmpeg pipeline, and run a short test transcode.\"],\"m16xKo\":[\"Add\"],\"m48LOH\":[\"Hardware Acceleration\"],\"mCB6Je\":[\"Select All\"],\"mDcLzR\":[\"Caching\"],\"mF+u2B\":[\"Don't see the library you want here? Ensure it is enabled in the <0>Media Source Settings.\"],\"mGM6Aa\":[\"Custom Shows are sequences of videos that represent a episodes of a virtual TV show. When you add these shows to a channel, the schedule tools will treat the videos as if they belonged to a single TV show.\"],\"mHTMS1\":[\"Normalize Frame Rate\"],\"mQt7fl\":[[\"count\",\"plural\",{\"one\":[\"program\"],\"other\":[\"programs\"]}]],\"mRWiYM\":[\"Duration (seconds)\"],\"mWbpso\":[\"Max Backups\"],\"mYBORk\":[\"Movie\"],\"mYJG1x\":[\"Your list will be replicated \",[\"0\"],\" times\"],\"mZFYjJ\":[\"Error saving programs. \",[\"0\"]],\"mZFr14\":[\"HLS not supported in this browser!\"],\"md42bg\":[\"Transcode Config (optional override)\"],\"mgcp8D\":[\"How often to insert a break\"],\"migeCK\":[\"Filter which subtitle tracks are considered<0/><1>Any: All subtitle tracks are considered <2/><3>Forced: Only consider <4>\\\"forced\\\"subtitle tracks <5/><6>Default: Only consider default subtitle tracks <7/><8>None: Do not select any subtitles\"],\"mtQjGe\":[\"Configure subtitle preferences. Preferences are evaluated in order of priority. The first matching subtitle stream on a program will be used.\"],\"mvU6s8\":[\"Sort TV Shows\"],\"mwtge0\":[\"Started \",[\"startedAgo\"],\" - \",[\"remainingTime\"],\"remaining\"],\"n+7HJk\":[\"When file paths on the remote server differ from the paths Tunarr can see, use Path Replacements to instruct Tunarr how to stream media from disk.\"],\"n9nSNJ\":[\"Time format\"],\"nH6YaM\":[\"Other Videos\"],\"nSW2Lv\":[[\"days\",\"plural\",{\"one\":[\"#\",\" day\"],\"other\":[\"#\",\" days\"]}]],\"nV6twc\":[\"Organize\"],\"nYD/Cq\":[\"Ascending\"],\"nZXc7r\":[\"Unlink from group\"],\"nfAddt\":[\"FFmpeg Transcode Path\"],\"nfxRnc\":[\"Tunarr is currently configured to use the AC3 audio encoder. This audio format is not supported by browsers. The resultant stream will likely not have audio or will not play at all.\"],\"njIcYs\":[\"Save as new collection…\"],\"ntJ9rt\":[\"HLS Direct Output Format\"],\"nzDzPp\":[\"toggle access token visibility\"],\"o0+Ul2\":[\"Add Flex\"],\"o2Ucvk\":[\"Libraries\"],\"o6OQlp\":[\"Edit Channel\"],\"o7J4JM\":[\"Filter\"],\"o7Y4WO\":[\"Error saving new Emby server. See browser console and server logs for details\"],\"oADXRC\":[\"Calculated \",[\"humanizedDuration\"],\" (\",[\"numShows\"],\" programs) of programming in \",[\"duration\"],\"ms\"],\"oCHfGC\":[\"Level\"],\"oCpfQF\":[\"This feature is currently experimental. Proceed with caution and if you experience an issue, try disabling caching.\"],\"oEZmaP\":[[\"count\",\"plural\",{\"one\":[\"#\",\" season\"],\"other\":[\"#\",\" seasons\"]}]],\"oMA2jd\":[\"Removes any specials from the schedule. Specials are episodes with season '00'.\"],\"oPWgse\":[\"Maximum number of breaks per program (0 = unlimited)\"],\"ofUcbc\":[\"Random\"],\"oihuQr\":[\"Number of Replications\"],\"ousf2V\":[\"Random…\"],\"ovBPCi\":[\"Default\"],\"oxvBx3\":[\"If set, any programming group with fewer episodes will be looped in order to make perfectly even blocks.\"],\"p/78dY\":[\"Position\"],\"p/KgUp\":[\"The channel's regular programming between the specified hours. Flex time will fill up the remaining hours.\"],\"p04z/V\":[\"# Programs\"],\"p4XZFD\":[\"Local Path\"],\"pDwcFl\":[\"Save Smart Collection\"],\"pKYBXC\":[\"Last Scheduled Execution\"],\"paEQ75\":[\"\\\"Stealth\\\" channels are hidden from TV guides, spoofed HDHR, m3u playlist, etc. The channel can still be streamed directly or be used as a redirect target.\"],\"pcRxi1\":[\"How frequently libraries should be scanned (starting from midnight).\"],\"pdlmIS\":[\"<0>Error deleting filler list: \",[\"0\"],\"<1/>Please consider opening a bug with details!\"],\"pkERVr\":[\"Download JSON\"],\"pqarBu\":[\"Asc\"],\"pvnfJD\":[\"Dark\"],\"pwPreK\":[\"Restrict Hours\"],\"pxh+PI\":[\"Builder\"],\"q6GKgP\":[\"VAAPI Capabilities\"],\"q6nlo/\":[\"Subtitle Action\"],\"q9p3Xw\":[\"Bitrate cannot be changed when copying input audio\"],\"qAGp2O\":[\"Proceed\"],\"qG6T/X\":[\"Add Programming\"],\"qKNcv7\":[\"Generating Bug Report Link...\"],\"qV9xkb\":[\"Passthrough audio unchanged. Other settings will not apply.\"],\"qiXmlF\":[\"Add Media\"],\"qjW34v\":[\"This channel is set up to use <0>\",[\"0\"],\"Slots for programming. Any manual changes on this page will likely make this channel stop adhering to that schedule.\"],\"qlR1dD\":[\"Delete Channel \\\"\",[\"0\"],\"\\\"?\"],\"qs/mhD\":[\"Ensures programs start only at a particular interval within the hour. This makes for nice looking schedules. Flex time is scheduled to facilitate.\"],\"r3ptXC\":[\"Manually add an access token from your Jellyfin server\"],\"r9sc/0\":[\"Duration must be numeric\"],\"rAx5u1\":[\"End Time\"],\"rPEEWz\":[\"Successfully saved config!\"],\"rSZlvN\":[\"Programming Start\"],\"rhEkXj\":[\"Head\"],\"rl/8FN\":[\"Commit\"],\"rnbEQB\":[\"Copy M3U URL\"],\"roIf2/\":[\"On-Demand?\"],\"rtDDIV\":[\"Edit Slot\"],\"ru5qTc\":[\"Edit Media Source\"],\"rx5Ria\":[\"All lists are used\"],\"rxumR2\":[\"Match any of\"],\"s2OE0W\":[\"Enter a name for your Jellyfin Server\"],\"s4iETe\":[\"Transcode Config\"],\"s6lNC3\":[\"Fallback Mode\"],\"s8zbIS\":[\"Include Seasons\"],\"sA8Jt7\":[\"This slot replays content aired by continue slots earlier in the period.\"],\"sBJ5MF\":[\"Sources\"],\"sNnXh6\":[\"Order of programming within the slot\"],\"sUtIRs\":[\"about \"],\"sVVcvs\":[\"Experimental Features\"],\"sfbjgG\":[\"Audio Format\"],\"sxkWRg\":[\"Advanced\"],\"sxwNOp\":[\"Logs Directory:\"],\"sztQMJ\":[\"Programs a Flex time slot. Normally you'd use pad times, restrict times or add breaks to add a large quantity of Flex times at once, but this exists for more specific cases.\"],\"t/YqKh\":[\"Remove\"],\"t3hvHq\":[\"Sync Now\"],\"t5q6kk\":[\"For more details on manually retrieving a Plex token, see <0>here\"],\"t6+QCF\":[[\"count\"],\" \",[\"programLabel\"],\", \",[\"0\"]],\"t8Hzw3\":[\"Cyclic Shuffle randomly shuffles groups of programming.\"],\"tDuQbQ\":[\"Stream Mode\"],\"tEvsql\":[\"Subtitles\"],\"tH1aCG\":[\"Video Bitrate\"],\"tMxWK0\":[\"Adds Flex breaks after each TV episode or movie to ensure that the program starts at one of the allowed minute marks. For example, you can use this to ensure that all your programs start at either XX:00 times or XX:30 times. Removes any existing Flex periods before adding the new ones. This button might be disabled if the channel is already too large.\"],\"tPGTPB\":[\"Roll the log file on a fixed schedule, regardless of file size.\"],\"tRgOE5\":[\"Balance Programming\"],\"tXkhj/\":[\"Start\"],\"tXub8j\":[\"Display Watermark on Leading Edge\"],\"tYuxvA\":[\"FFMPEG\"],\"tfDRzk\":[\"Save\"],\"tgPwON\":[\"Operator\"],\"ti6ugP\":[\"Error while saving transcode config. See console log for details.\"],\"tkDYSE\":[[\"hours\",\"plural\",{\"one\":[\"#\",\" hour\"],\"other\":[\"#\",\" hours\"]}]],\"tlMRNb\":[\"The loaded version of the Tunarr UI does not match the server. Reload the browser to get the latest. If this message persists, clear your browser cache and reload.\"],\"tlNobE\":[\"Custom Show: \",[\"0\"]],\"tlmh8e\":[\"Add all selected programs to channel\"],\"tsqRRB\":[[\"0\"],\" Poster\"],\"ty8rVI\":[\"Now Playing:\"],\"tzwArf\":[\"View in \",[\"0\"]],\"u+VWhB\":[\"Copied to clipboard!\"],\"u+zFIr\":[\"Restrict search fields\"],\"uAQUqI\":[\"Status\"],\"uHTa9V\":[\"To use Tunarr, you need to first connect a media source. This will allow you to build custom channels with your content.\"],\"uLiDe/\":[\"Enable embedded subtitle extraction\"],\"uUTf8r\":[\"Delete Custom Show \\\"\",[\"0\"],\"\\\"?\"],\"uamufO\":[\"Add TV Shows or Movies to programming list.\"],\"ueG1bp\":[\"Program Count\"],\"ueLbrY\":[\"If true, adjusting the weight of one slot will scale the weights of other slots such that all weights total 100%. Otherwise, weights can be adjusted freely and the weight of each slot is only relative to the total weight.\"],\"uixVel\":[\"By default, saves backups in the server's run directory, or, if running in Docker, to /config/tunarr/backups\"],\"uyR9ei\":[\"Block Shuffle\"],\"v4nbQ4\":[\"If no more programs can fit into a duration-based slot, flex time is added to fill the gap. This setting determines how flex is added <0>within the slot to ensure all time is filled.<1/><2>Between: Flex time is added between videos within a slot, if there are multiple<3/><4>End: Flex time is added at the end of the slot\"],\"v5IstB\":[\"after every program\"],\"v5URfV\":[\"Like Random Shuffle, but tries to preserve the sequence of episodes for each TV show. If a TV show has multiple instances of its episodes, they are also cycled appropriately.\"],\"vAK/B1\":[\"Audio Action\"],\"vCBet9\":[\"Not a valid number\"],\"vERlcd\":[\"Profile\"],\"vGRvxs\":[\"Channel group is required\"],\"vLf7qg\":[\"Interval (minutes)\"],\"vSJd18\":[\"Video\"],\"vU/Hht\":[\"Distribution\"],\"vXIe7J\":[\"Language\"],\"vcvFVw\":[\"Escape Hatches\"],\"vkA4W/\":[\"Source Type\"],\"vn3SVH\":[\"Could not parse this filter expression. Check the <0>documentation for information about filter expressions.\"],\"vreTxe\":[[\"count\",\"plural\",{\"one\":[\"#\",\" program\"],\"other\":[\"#\",\" programs\"]}]],\"vwFKu0\":[\"Cast & Crew\"],\"vyL1gO\":[\"Release Date (desc)\"],\"w/bY7R\":[\"Logs\"],\"w2pCRr\":[\"Show:\"],\"w3KBq0\":[\"Allows programs to play a bit late if the previous program took longer than usual. If a program is too late, Flex is scheduled instead.\"],\"w3g+lo\":[\"Let's get started...\"],\"wBmIEf\":[\"Number of hours to include in the XMLTV file\"],\"wBo/7A\":[\"Error while scheduling \",[\"taskId\"],\". Check server logs for details\"],\"wKClDM\":[\"Adds a channel redirect. During this period of time, the channel will redirect to another channel.\"],\"wMHvYH\":[\"Value\"],\"wOUKOZ\":[\"Max True Peak\"],\"wZOYCY\":[\"Video Format\"],\"wdfBIP\":[\"Sort By...\"],\"wdxz7K\":[\"Source\"],\"wkQ2tb\":[\"Adds Flex breaks after each TV episode or movie to ensure that the program starts at one of the allowed minute marks.\"],\"wlYdUk\":[[\"count\",\"plural\",{\"one\":[\"hour\"],\"other\":[\"hours\"]}]],\"wpT1VN\":[\"Condition\"],\"wtuVU4\":[\"Frequency\"],\"wwu18a\":[\"Icon\"],\"x+AjXa\":[\"Channel Fallback\"],\"x/dwZe\":[\"Enable if the watermark is an animated GIF or PNG. The watermark will loop according to the image's configuration. If this option is enabled and the image is not animated, there will be playback errors.\"],\"x1tGMH\":[\"Override how programs within this slot are padded.\"],\"x6/Zc6\":[\"Tail\"],\"x63PSs\":[\"Search for shows\"],\"x7PDL5\":[\"Logging\"],\"xCJdfg\":[\"Clear\"],\"xDAtGP\":[\"Message\"],\"xDPFrK\":[\"Scan \",[\"0\"]],\"xGVfLh\":[\"Continue\"],\"xGYZfl\":[\"Edit Libraries\"],\"xIn7qU\":[\"Disable Hardware Decoding\"],\"xJIepX\":[\"Default Config\"],\"xOkMus\":[\"Hardware Accel.\"],\"xPmesF\":[\"Loudness Range Target\"],\"xQC5se\":[\"Advanced Video Options\"],\"xXrtPO\":[\"Failed to load item details! Check logs for details\"],\"xazqmy\":[\"Seasons\"],\"xbtgIC\":[\"HW Acceleration\"],\"xdA/+p\":[\"Tools\"],\"xmBknQ\":[\"Filler Lists\"],\"xptXTM\":[\"Select Artists to Remove\"],\"xqIrnW\":[\"Library Clip (not yet implemented)\"],\"xu3Kah\":[[\"0\",\"plural\",{\"one\":[\"#\",\" program\"],\"other\":[\"#\",\" programs\"]}]],\"y28hnO\":[\"Post\"],\"y4Jmre\":[\"Break Duration\"],\"y4iKY3\":[[\"count\",\"plural\",{\"one\":[\"#\",\" album\"],\"other\":[\"#\",\" albums\"]}]],\"y5x0aB\":[[\"0\"],\" Info\"],\"y7wpam\":[[\"value\",\"plural\",{\"one\":[\"#\",\" program\"],\"other\":[\"#\",\" programs\"]}]],\"yDUcwc\":[\"Manually add an access token from your Emby server\"],\"yPE51X\":[\"Configure transcoding settings for Tunarr's streams. Each channel is assigned one transcode configuration.\"],\"yPK7+5\":[\"Auto-Update Guide\"],\"yQE2r9\":[\"Loading\"],\"yRkqG9\":[\"Limit\"],\"yX8Rkw\":[\"Add All\"],\"yftDqj\":[\"New Filler List\"],\"yjzkvk\":[\"Stop Transcode Session\"],\"ysJk7v\":[\"Movie Sort Order\"],\"ysecYP\":[\"Search for a program\"],\"ytXxnP\":[\"Forced\"],\"yz/C2/\":[\"Rerun\"],\"yz7wBu\":[\"Close\"],\"z4K9d+\":[\"Roll based on size\"],\"z61uNR\":[\"Add Flex Time\"],\"zV6tsp\":[\"Consolidate\"],\"zV9awV\":[\"Force Scan\"],\"zpylsE\":[\"Transcoding Settings\"],\"zrmjn/\":[\"Max Duration\"],\"zthKEs\":[\"The streaming mode affects the type of underlying transcoding process used to create the channel's video stream.<0/>Learn more about Tunarr's stream modes <1>here!\"],\"zvjEp6\":[\"Filler cooldown must be a number\"],\"zx4BuL\":[\"Week\"],\"zyLvkd\":[\"Category Log Levels\"]}")as Messages; \ No newline at end of file + import type { Messages } from '@lingui/core'; +export const messages = JSON.parse( + '{"++nzCr":["Bit Depth"],"+2JHIs":["Link to existing slot"],"+406Vu":["View Full Details"],"+4YwQF":["# of Programs"],"+4mjS6":["Remove icon"],"+9EErD":["Music Videos"],"+DmLct":["Programs"],"+SA5Ao":["A root path to scan for media. Local sources can search many different paths."],"+TZiPJ":["Server is unreachable"],"+UPOiB":[["count","plural",{"one":["min"],"other":["mins"]}]],"+Xg5cX":["Filler is picked fresh at stream time like Flex time. The guide shows \\"Commercial Break\\" placeholders."],"+YdE7b":["Enable rolling log files using time and/or size based criteria"],"+hl/7A":["Channels configured to use the HLS Direct stream mode will output in the selected container format."],"+k9lxR":["Enter a name for your Local Media Source"],"+mdNfU":[["count","plural",{"one":["#"," track"],"other":["#"," tracks"]}]],"+suWTj":["Adds Flex breaks between programs, attempting to avoid groups of consecutive programs that exceed the specified number of minutes."],"+tlhMz":["Plex (Manual)"],"+yEE7s":["New Media Source"],"+yOcRn":["HDHR"],"+ya1pX":["Delete Slot"],"+zY9Xc":["Configure Cyclic Shuffle"],"+zy2Nq":["Type"],"/+ZaFm":["Soundtrack"],"/4gGIX":["Copy to clipboard"],"/6iIT9":["Settings Saved!"],"/DTWjr":["Congrats, you\'re ready to start building channels! Just click Finish below to start working on your first channel."],"/QmYEW":["Balance..."],"/TEOcd":["Presets"],"/e88IO":["Schedule programming in blocks that are either count or duration based. Can be used to generate random schedules."],"/gavzH":["Basic button group"],"/j3jjC":["Error while saving settings. Please check console for details."],"/n/HCO":["Keywords"],"/rTz0M":["Audio"],"/vJase":["Streaming"],"09gg05":["Programming"],"0IAEaX":["Match"],"0MWZh1":["Search is currently scoped to this Media Source Library."],"0VHz2s":["Filler Options"],"0cULRy":["Experimental: Make perfect schedule loop"],"0dy9K6":["Read Less"],"0mEBXY":["Delete Transcoding Config \\"",["0"],"\\"?"],"0wJVK+":["Basic"],"0zpgxV":["Options"],"1/dAym":["Grouping works as follows:"],"14PdY0":["Config"],"1AdBl9":["Break Positioning"],"1BDPP1":["Looks like something went wrong."],"1BGQfg":["Alphabetically"],"1CFAQ+":["Set by environment variable"],"1DxLRi":["No programming scheduled for this time period"],"1PQRWr":["Start Time"],"1QfxQT":["Dismiss"],"1TYXl0":["Enter your Emby password to generate a new access token."],"1V3Prt":["Deleting a Filler will remove all programming from the channel. This action cannot be undone."],"1Z90J4":["Days to Precalculate"],"1hKEom":["Priority"],"1jqDmP":["Successfully scheduled ",["taskId"]," (running in background)."],"1njn7W":["Light"],"2BBAbc":["List"],"2BRPyl":["System Info"],"2CVuYr":["Smart Collection - ",["0"]],"2L7cj6":["You haven\'t created any channels yet."],"2QLniG":["Existing query: ",["filterString"]],"2eFlmt":["Tracks"],"2hOCU2":["Smart Collections"],"2imNg3":["Web version = ",["0"],", Server version = ",["1"]],"2mAJXf":["Makes multiple copies of the schedule and plays them in sequence. Normally this isn\'t necessary, because Tunarr will always play the schedule back from the beginning when it finishes. But creating replicas is a useful intermediary step sometimes before applying other transformations. Note that because very large channels can be problematic, the number of replicas will be limited to avoid creating really large channels."],"2oWehJ":["Reset to current date/time"],"2vxecF":["Show Stealth"],"2x4THe":["\\"",["0"],"\\" Sessions"],"312fSE":["Select Shows to Remove"],"315BhT":["Alphabetical"],"3JIYke":["Healthy?"],"3JQkm5":["Path Replacements"],"3JjdaA":["Run"],"3LfNqe":["Channel Number"],"3SH6Vv":["Copied channel \\"",["channelName"],"\\" m3u link to clipboard"],"3YNjnA":["System Environment"],"3b1vGb":["New Local Media Source"],"3mAQJI":["How often the XMLTV file is regenerated"],"3nLdaX":["Add ",["0"]],"3nwcC5":["Filler - ",["0"]],"49dCCB":["Use Show Poster"],"4Fpcxu":["Initial Delay (minutes)"],"4NbDEd":["Deleting a Custom Show will remove its programming from channels that use it. This action cannot be undone."],"4Uc/2h":["Server Listen Port"],"4VxpoP":["Music tracks are grouped by artist"],"4XSc4l":["Weekly"],"4XfYeY":["Random (by show)"],"4fLgiT":["Allow Image Based"],"4qmJK4":["Tunarr Backend URL"],"4wkwyL":["Disable Hardware Filters"],"4yQF++":["Custom show programs are grouped by their parent show"],"50whWJ":["XMLTV Link:"],"53/4tH":["Audio Options"],"536Xwe":["Error copying to clipboard!"],"53tfay":["This allows to schedule specific shows to run at specific time slots of the day or a week. It\'s recommended you first populate the channel with the episodes from the shows you want to play and/or other content like movies and redirects."],"5ABghp":["FFmpeg Settings"],"5V93hk":["Schedule programming using slots assigned a start time and duration."],"5WeWGz":["Selected Subtitle"],"5jWg+L":["Tunarr will attempt to get Plex to pull Tunarr\'s updated XMLTV upon regeneration"],"5k0NLb":["Review"],"5lSgNP":["Enable SSDP server"],"5nsbxB":["Alternates TV shows in blocks of episodes. You can pick the number of episodes per show in each block and if the order of shows in each block should be randomized. Movies are moved to the bottom."],"5qV3NN":["Flex Style"],"5yIPLp":["Oops!"],"6/dCYd":["Overview"],"63/DSM":["Transcoding Configs"],"63driG":["Stream JSON"],"67RoFa":["Pipeline"],"6Y9c2m":["This slot is linked with ",["0"]," other slot(s). Content fields are shared across the group."],"6YtxFj":["Name"],"6ZMWKw":["XMLTV"],"6bbWRs":["Add programming to custom show"],"6dvIbw":["Unlink"],"6jAi8c":["Range"],"6jfS51":["Welcome"],"6ki7F2":[["0","plural",{"one":["#"," item"],"other":["#"," items"]}]],"6mJ9tF":["FFMPEG is not detected."],"6mpwdR":["Match all of"],"6pL6be":["Configure what appears on your channel when there is no suitable filler content available. Using channel fallbacks requires ffmpeg transcoding."],"6w0yiE":["FFMPEG Log Level"],"6zfUar":["Stream Selection"],"71O7b0":["Media Info"],"73XwX0":["No programs selected"],"73flfT":["QSV Device"],"7B3lfh":["Items from any filler list will not be chosen more frequently than this cooldown setting."],"7LWPgS":["Enabled (loudnorm)"],"7ODkf5":["Log level to pass to ffmpeg. Read more about ffmpeg\'s log levels <0>here"],"7Q5AKf":[["count","plural",{"one":["track"],"other":["tracks"]}]],"7b2stB":["Media Type"],"7eMo+U":["Go Home"],"7eZlTH":["Sort TV Shows (asc)"],"7iJlKU":["Please choose a value greater than 1"],"7pMNGK":["Programs saved!"],"7sNhEz":["Username"],"7tvV2B":["Min Duration (minutes)"],"7uohY3":["TV shows are grouped by show"],"80t7Ii":["Increasing \\"Max Lateness\\" for the schedule."],"87a/t/":["Label"],"8E9KXK":["Feature flags saved!"],"8MIU1T":["Program"],"8TMaZI":["Timestamp"],"8ZsakT":["Password"],"8vETh9":["Show"],"8wngZM":["Fallback"],"8wu9lr":["Queued"],"9+90+V":["Enable Log File Rolling"],"94qSvE":["Synced with external playlist"],"96zw7M":["This show is marked as missing in the database."],"983IRa":["All linked slots show the same episode, advancing only after all have played."],"9E+eyD":["Output video at a constant frame rate."],"9E9tRC":["Fill with Flex"],"9Eq43e":["If set, all watermark overlays will be disabled for channels assigned this transcode config."],"9GPYnX":["Do not group programs at all. Normal shuffle."],"9WG5wy":["Specials"],"9asVsi":["How long each commercial break lasts"],"9qdNKR":["Error Options"],"9sqrEU":["Filler List"],"9td1Wl":["Check"],"9vtG84":[" Scheduling Strategy"],"A+GCyx":["Hide Advanced"],"A0+T6c":["Reset Changes"],"A1taO8":["Search"],"A7WmPm":["New Plex Server"],"A9Rhec":["Channel Name"],"ACKu03":["Refresh Preview"],"AKjNTL":["Add Padding"],"AM972O":["Add Redirect"],"ANICN0":["No media sources connected."],"AO2Z5d":["Movie, ",["0"]],"AOHgZp":["Episodes"],"AVKoQM":["Redirect to \\"",["0"],"\\""],"AXg7m0":["Search is currently scoped to this Media Source."],"AXjA78":["Field"],"AdfhAd":["If there are issues playing a video, Tunarr will try to use an error screen as a placeholder while retrying loading the video every 60 seconds."],"AdogaJ":["Pipeline Steps"],"AlfqgK":["Watch"],"ApsQAb":["HDHR: Loading..."],"AyInY5":["Video Options"],"AzCYkg":["Connect Media Sources"],"B+HsXP":["FFMPEG: ",["0"]],"B1NOvD":["Removes all programs from schedule"],"B1W8vw":["Delete \\"",["0"],"\\""],"BGHH1t":["Min. Visible in Guide Duration Program (seconds)"],"BJjJuo":["EPG (Hours)"],"BMlGCC":["Click to preview the items in this Custom Show. Note that only the whole show can be added at once."],"BQsifH":["Stream Info"],"BWTzAb":["Manual"],"BXXjCD":["FFmpeg not found. For all features to work, we recommend installing FFmpeg 7.1+ or update your FFmpeg executable path in settings."],"BaUuhR":["Codec"],"BlmmxH":["FFmpeg Log"],"Bq0ryo":["Reset Options"],"BtL93c":[["0","plural",{"one":["#"," source connected."],"other":["#"," sources connected."]}]],"C4KL42":["Consolidates contiguous match flex and redirect blocks into singular spans"],"C6jEO3":["Log Level"],"CAiikc":["Enter your Jellyfin password to generate a new access token.<0/><1>NOTE: These are never saved to the Tunarr DB. Instead they are sent to Jellyfin to exchange for a session token."],"CJkEfx":["Block"],"CKQ3t3":["Total Runtime"],"CMQ09J":["Scanning"],"COv7As":["Cooldown (seconds)"],"CRsuq4":["Every"],"CVqySE":[["len","plural",{"one":["There is ","#"," warning. Click for details."],"other":["There are ","#"," warnings. Click for details."]}]],"CWRFGq":["Modify Programming"],"CXDHcv":["Grid"],"CcX8VV":["Completely randomizes the order of programs."],"CeyB7O":["FFmpeg Executable Path"],"CfOWar":["Logarithmic decay, lighter weighting."],"CfUvtM":["Error saving new Smart Collection. Check server logs and browser console for details."],"CfxLtO":["Program JSON"],"Cko536":["Descending"],"Cp5Awv":["Duration must be greater than 0."],"CqSP2T":["Edit Channel Redirect"],"CsrDsg":["12-hour"],"Cxqf0C":["Plex (Auto)"],"D+NlUC":["System"],"D1Fhv3":[["count","plural",{"one":["episode"],"other":["episodes"]}]],"DPfwMq":["Done"],"DRya1t":["Audio Volume"],"DSwJ9W":["Enable Animation"],"DUd3Ss":["Sorts the list by TV Show and the episodes in each TV show by their season/episode number. Movies are moved to the bottom of the schedule."],"DbouLP":["Back to Programming"],"Dd9orS":["Remove All ",["movieCount"]," ",["movieCount","plural",{"one":["Movie"],"other":["Movies"]}]],"Dnn2XG":["Automatic"],"DoJzLz":["Collections"],"DxvGLB":["Add Slot"],"E/QGRL":["Disabled"],"E5ipHC":["Balance By:"],"E8oclZ":["Copied Channel ID!"],"EKlukx":["Copy Full Report"],"EL4/HD":[["0","plural",{"one":["program"],"other":["programs"]}]],"EdQY6l":["None"],"EkH9pt":["Update"],"Etie0Q":["All channels assigned to this config will be set to use the default configuration. If this is the last configuration, a new default configuration will be created."],"Eu20Os":["Time Slots"],"Ev2r9A":["No results"],"F1l877":["Subtitle Streams"],"F3bW6y":["Platform"],"F3smBd":["Maximum number of days to precalculate the schedule. Note that the length of the schedule is also bounded by the maximum number of programs allowed in a channel.<0/><1>Note: Previewing the schedule in the browser for long lengths of time can cause UI performance issues"],"FDEfoy":["Deleting a media source will remove all of its associated programs from Tunarr."],"FXCwT9":["FFprobe Executable Path"],"FZg3wM":["Operation"],"FmN5me":["Resolution"],"FnChN1":["Enable <0>EBU R 128 loudness normalization via the <1>loudnorm FFmpeg filter. May increase CPU usage during streaming."],"Fp7p73":["Time between subsequent breaks"],"FqCHF/":["Threads"],"FrRP21":["There was an error when submitting the form. Please see console logs for details."],"FsF4bb":["Audio Loudness Normalization"],"FssFce":["Configure preferred audio languages globally."],"Fzn/BQ":["Release Date"],"G+8qH5":["Channel name is required"],"GDKKxT":["Access Token"],"GHOK4Z":["Time Format"],"GJ1P5j":["File a Bug Report"],"GKLqtE":["Set the host of your Tunarr backend. When empty, the web UI will use the current host/port to communicate with the backend."],"GLOZdc":["Custom Shows"],"GP/CFo":["HW Accel"],"GQ3O42":["Trash"],"GRCrpV":["Manage Libraries"],"GUtCZC":["Version: ",["0"]],"GhZ4GX":["Error while copying to clipboard. Check browser logs for details"],"GmP0oY":["Slot Warnings"],"GmTnBN":["Enable ffmpeg logging to different sinks. Outputting to a file will create a new log file for every spawned ffmpeg process in the Tunarr log directory. These files are automatically cleaned up by a background process."],"Gr1Ik2":["Nvidia Capabilities"],"GtycJ/":["Tasks"],"GzzMwi":["Roll on Schedule"],"H0QGc9":["Filler List Cooldown (seconds)"],"H1OFlu":["Inverse linear decay, heavier weighting."],"H1V+2G":["To use Tunarr, you must first connect at least one media source. Media sources provide all content used to create channels in Tunarr. Plex and Jellyfin are currently supported."],"H3OF1s":["Tuner Count"],"H7OUPr":["Day"],"H8100o":["Filler lists are collections of videos that you may want to play during \'flex\' time segments. Flex is time within a channel that does not have a program scheduled (usually used for padding)."],"HDoQBx":["Channel settings saved!"],"HEH0PR":["Must define at least one language preference"],"HErtdg":["Name can only contain alphanumeric characters, dashes, and underscores"],"HLlLPP":["Channel Stream Mode"],"HMWEIt":["Edit Flex Time"],"HOLbdk":["Failed to load stream details! Check logs for details"],"HSfauP":["This slot is linked with ",["0"]," other ",["1","plural",{"one":["slot"],"other":["slots"]}],". Content fields are shared across the group."],"HVpg3x":["Failed to load Smart Collection"],"HXx+vU":["Controls what happens when this slot runs out of replayed content from earlier continue slots."],"HYCPKT":["Add Selected Media"],"HajiZl":["Month"],"HdE1If":["Channel"],"Hjfx9G":["Audio & Subtitles"],"HmHwcC":["Fixed Interval"],"HptUxX":["Number"],"HqUilK":["Keywords perform full text search across all (or configured) fields"],"HzV8B2":["Skip mid-roll for programs shorter than this"],"I+FvbD":["Scan"],"I2Bar3":["Shows"],"I5BU70":["Smart Collection: ",["0"]],"I6gXOa":["Path"],"IDlmXg":["Tunarr Backend URL:"],"IE9OdF":["Update Play Status"],"IFiQdD":["Channels M3U Link:"],"IMxI++":["Not a valid URL"],"INCbO6":["On-Demand channels resume from where you left off. Programming is paused when the channel is not streaming.<0/><1>NOTE: While the channel is inactive, the TV Guide for the channel will be empty."],"IagCbF":["URL"],"IetKlB":["New Custom Show"],"IgC1fP":["Enable light Mode"],"IiBgkW":["Failed to update Media Source settings. Please check server and browser logs for details."],"IoSxk9":["Protocol must be HTTP or HTTPS"],"IvkbIT":["Read More"],"J/eF78":["Removing overrun programs from the channel."],"J0NKO1":["Exclude Seasons"],"J2eKUI":["File"],"J2lnQW":["Pre"],"J41wt0":["Slot Editor"],"J4Ngmi":["Loop Short Programs"],"J50/e4":["Filter Type"],"J8X80J":["Stealth?"],"JCGCcQ":["Sorts everything by its release date. This will only work correctly if the release dates in Plex are correct. In case any item does not have a release date specified, it will be moved to the bottom."],"JCOZTc":["Audio & Subtitle Options"],"JOFDLs":["Program Playback Troubleshooter"],"JeAvlS":["Pad Times"],"JeL1O4":["Redirect duration"],"Jj3SJk":["A-Z (asc)"],"JmZ/+d":["Finish"],"Jpe9a8":["Attempts to balance programming groups by either total lineup duration or number of unique programs. For instance, for a channel with many seasons of one show and few seasons of another, balancing will attempt to create an even mix of both shows by inserting repeats of the show with fewer episodes."],"JryIGL":["Adjust Weights"],"Jsel0T":["This channel has an existing time slot schedule. A channel can only use one scheduling type at a time. Saving a schedule here will remove the existing time slot schedule."],"Jtbzxr":["Version: unknown"],"JxE+Bh":["Allows you to pick specific programming to remove from the channel."],"JyHA6G":["Displays the last ",["0"]," system log events. Use the buttons below to export these logs or download the entire log file for debugging."],"JzJk+4":["Add Language Preference"],"K09nyY":["Linked slots advance episode progression together sequentially."],"K8+dbZ":[["totalConnections"]," total"],"K8ebg0":["Tunarr will update Jellyfin\'s \\"now playing\\" state while channels are active."],"K9pQ8Q":["Disable Watermarks"],"KRjDf4":["Audio Streams"],"Khe/Vb":["Watch Channel"],"KkOthv":["Guide"],"Km5fSd":["If you are confident FFMPEG is installed, you may just need to update the executable path in the settings. To do so, simply click Edit above to update the path."],"L+8pV5":["Sync with external playlist"],"L/KmPM":["Usually slots need to add flex time to ensure that the next slot starts at the correct time. When there are multiple videos in the slot, you might prefer to distribute the flex time between the videos or to place most of the flex time at the end of the slot."],"L6Mhe6":["You have unsaved changes!"],"L8Hb+D":["Sets the number of threads used to decode the input stream. Set to 0 to let ffmpeg automatically decide how many threads to use. Read more about this option <0>here. <1>Note: this option is overridden to 1 when using hardware accelearation for stability reasons."],"LKPR6G":["Playlist"],"LKSv28":["Smart Collections are self-updating content lists. You set the query and the collection automatically adds any new content from your library that fits those rules. Any newly added content matching query will not modify existing channel programming at this time."],"LMMGPr":["Submitting..."],"LRvqnF":["Error saving new Jellyfin server. See browser console and server logs for details"],"LTC198":["Running..."],"LTYRAI":["View Library"],"LiCr5o":["Limit must be numeric"],"MHrjPM":["Title"],"MKK96e":["View Collection"],"MR6Nlf":["Change the verbosity of specific categories of logs. Useful if debugging a specific feature."],"MS1Dhi":["Max file size (bytes)"],"MVBLYK":["Remove..."],"MW42Hp":["Customize how movie blocks are sorted"],"Md/eZS":[["count","plural",{"one":["#"," item"],"other":["#"," items"]}]],"MfkGXC":["Shuffle Grouping"],"MkMcGz":["Refresh Libraries"],"Ml7h3C":[["0","plural",{"one":["#"," Program"],"other":["#"," Programs"]}]],"Mrdyk9":["Genre"],"Mv+xQh":["New Channel"],"N15e5e":["Remove custom icon"],"NGOfis":["Disable Image Scaling"],"NGSThJ":["Smart Collection"],"NL/bON":["FFmpeg Command"],"NQ7yht":["Must use a valid URL, or empty."],"NaDxQ2":["Auto Deinterlace Video"],"Nb+B9K":["Adjust the output volume (not recommended). Values higher than 100 will boost the audio."],"NcV1df":["Pad Start Times"],"NfTP7a":["Advanced options relating to audio. In general, do not change these unless you know what you are doing!"],"NfZ8rc":["24-hour"],"Nkn5MW":["Removes all Flex periods from the schedule."],"NnH3pK":["Test"],"NnuRri":["This allows you to pick the weights for each of the shows, so you can decide that some shows should be less frequent than other shows."],"NtQvjo":["Period"],"Nu4oKW":["Description"],"Ny7dz3":["Albums"],"NyfQ4q":["Save as Smart Collection"],"O1xfOi":["Random..."],"O5izWu":["This custom show is synced with an external playlist. Content is updated automatically and cannot be edited manually."],"O8g6Na":["Last Scanned: ",["0"]],"OPw3KG":["Connect Media Source"],"OVmXHk":["Refresh Timer (Hours)"],"Ob+B6e":["Buffer size cannot be changed when copying input audio"],"OfC/JK":["Custom Show - ",["0"]],"OfYtUi":["Filler Content"],"OfhWJH":["Reset"],"OrDu0o":["Video Buffer Size"],"Osn70z":["Debug"],"P/TyYO":["The type of media in the provided paths"],"P1BU0j":["Frame Rate"],"P29ZKI":["Enter a name for your Emby Server"],"P2DGHD":["Programming starts at ",["startTime"]," and stops at ",["endTime"]],"P3i3NN":["Edit Channel Settings"],"P6Io39":["Max Lateness"],"P6c7YE":["Remove Programming"],"PCBfmf":["Renders a channel icon (also known as bug or Digital On-screen Graphic) on top of the channel\'s stream."],"PJ/u9s":["Copied ",["0"]," URL to clipboard"],"PT6k0T":["Pixel Format"],"PX1WM1":["Successfully emptied trash."],"Pazp7r":["There was an error generating time slots. Check the browser console log for more information"],"PeBTGz":["Clear Schedule"],"PeBylA":["You must create at least one <0>filler list before assigning filler to a lot."],"Pfatg8":[["minutes","plural",{"one":["#"," minute"],"other":["#"," minutes"]}]],"PgdRhI":["Weighting"],"Ph+yE0":["0 mins"],"PhKcf0":["Edit Transcode Config"],"PiY0nu":["You have no Filler Lists. Create your first Filler List <0>here."],"Pol2QS":["Emby"],"PpZkda":["Features"],"PwpUBp":["This is the name of the fake program that will appear in the TV guide when there are no programs to display in that time slot guide, e.g when a large Flex block is scheduled."],"Pwqkdw":["Loading…"],"Q8L6q9":["Video Streams"],"QAUrt0":["Refresh Page"],"QEb4hu":["Stealth Mode"],"QG2xdt":["Create Rerun Block"],"QHRTYn":["Slots Editor..."],"QKMxhc":["Tunarr runs various tasks, sometimes on a schedule, for background operations."],"QUxTIQ":["Filler is resolved at schedule time. The guide shows specific filler titles."],"Qll2Tb":["Desc"],"QlrQ/Z":["Next Scheduled Execution"],"Qm1NmK":["OR"],"Qu844y":["Time Slot Editor"],"QvKdb0":["Placeholder Program Title"],"Qx971g":["After Every"],"R/7J0Z":["Artists"],"R/N+HY":["No programming added yet"],"R/xSFi":["Editing \\"",["0"],"\\""],"R0yni2":["Attempt Auto-Fix"],"R40oLk":["Will force use of a software encoder despite hardware acceleration settings."],"R6kHq+":["Link Mode"],"R9Khdg":["Auto"],"RCeEAd":["Global Options"],"RGf6l7":["Select a slot to link to"],"RI4u49":["<0>You can edit this location in your settings.json within your Tunarr data directory<1/><2>NOTE: When manually adding the XMLTV location to a client like Plex, do not use this file directly. Instead, use the generated XMLTV from the Tunarr API endpoint: ",["0"],""],"RTxUjI":["Copy to Clipboard"],"RUYsn0":["Clear All"],"RVl9/c":["Alternate programs in blocks. You can pick the number of programs per-type in each block and if the order of shows in each block should be randomized."],"RYP47R":[["0","plural",{"one":["Day"],"other":["Days"]}]],"RYlQY0":["Repeats"],"RaHlqV":[["totalConnections","plural",{"one":["#"," connection"],"other":["#"," connections"]}]],"RavMGr":[["count","plural",{"one":["second"],"other":["seconds"]}]],"RbgUS/":["Copy Channel ID"],"RtPRIb":["Maximum number of days to precalculate the schedule. Note that the length of the schedule is also bounded by the maximum number of programs allowed in a channel."],"RxzN1M":["Enabled"],"S/CawK":["Movies are grouped altogether"],"S5v5/h":["Enabling embedded subtitle extaction will periodically scan your upcoming programming for embedded text-based subtitle streams and extract them to a local cache. This is necessary in order to enable subtitle burning for text-based subtitles which are not external streams."],"S60KP9":["Server Settings"],"S8zZJK":["Welcome to Tunarr!"],"SBtwzo":["Version Mismatch!"],"SCZJhh":["Audio Bitrate"],"SFjIKS":[["0","plural",{"one":["#"," Selected Item"],"other":["#"," Selected Items"]}]],"SOXW6w":["All Genres"],"SY1gRl":["Media Source"],"SYGPcm":["You have no smart collections. Smart collections can be created on the <0>search page."],"SZcfpX":["Pad Style"],"SZzr30":["The selected languages will be considered in order they are selected."],"Sbs5dW":["Filler"],"Sg3laT":["Min Duration"],"SoRsRS":["Calculates a schedule where all programs end at the same time, creating a perfectly looping schedule."],"SuubHr":["Deleting a Plex server will remove all programming from your channels associated with this plex server. Missing programming will be replaced with Flex time. This action cannot be undone."],"SywaS+":["Data Directory:"],"T5wfux":["Makes multiple copies of the schedule and plays them in sequence"],"T8drou":["System Health"],"TEM0vH":["Removes all programs from custom show"],"TMADKS":["Divides the programming in blocks of 4, 6, 8 or 12 hours then repeats each of the blocks the specified number of times."],"TMju4P":["Delete Media Source \\"",["0"],"\\"?"],"TS0lwx":["Encountered an error when emptying trash. Check console logs for details."],"TZKpsF":["No Media Sources detected."],"TpqW74":["Fixed"],"Ts6Zfm":["Error updating Smart Collection. Check logs for details."],"Ts8Q+i":["EPG"],"TvY/XA":["Documentation"],"Tz0i8g":["Settings"],"TzyoiK":["When enabling, Tunarr will generate an initial backup immediately"],"U0sC6H":["Daily"],"U3+jR/":["Replicate Programs"],"UC1lMc":["Failed to save feature flags."],"UE2eVC":["Sorts alphabetically by program title"],"UHu/Uf":["Show only synced libraries"],"UOMT7z":["This option is disabled because it would calculate a schedule that is too long."],"URmyfc":["Details"],"UXC1jS":["NodeJS: ",["0"]],"UYUgdb":["Order"],"UYW9jU":["Successfully ran system fixer ",["fixerId"]],"Uf/h/w":["Pick specific programming to remove from the channel."],"UirGxE":["Errors"],"UnI8zh":["Channel #",["0"]],"UweSf9":["Add Channel Redirect"],"V8B1wG":["Last synced ",["0"]],"V9UVpb":["Total hits: ",["0"]],"VBsY8N":["Set to 0 to never delete backups"],"VIHbrI":["Advanced options relating to transcoding. In general, do not change these unless you know what you are doing! These settings exist in order to leave some parity with the old dizqueTV transcode pipeline as well as to provide mechanisms to aid in debugging streaming issues."],"VP2oPP":["Slots"],"VVAgOP":["Rescan Interval (hours)"],"VXdzY3":["Disable Hardware Encoding"],"Va3xJe":["Add field"],"VfWz27":["Weight %"],"VlEnCC":["Archive Format"],"VlWKwW":["Lazy"],"Vmvp5H":[["count","plural",{"one":["day"],"other":["days"]}]],"VrBtVn":["Backups:"],"Vw5EeW":["Enable Backups"],"VyUuZb":["Image URL"],"WAakm9":["Delete Channel"],"WDgJiV":["Scanner"],"WGkxNZ":["Error querying Plex. Check console log and consider reporting a bug!"],"WKHqM+":["Weight"],"WMQchs":["Audio Buffer Size"],"WT1Ibn":["Last run"],"Wb3E4g":["Run now"],"Weq9zb":["General"],"WhJZoS":["Choose the transcode configuration to use for this channel. Configure transcode configurations on the <0>FFmpeg settings page."],"WjUHH8":["Movie Sort"],"WnW1QF":[["block"]," Hours"],"WzNAIP":[["0","plural",{"one":["Hour"],"other":["Hours"]}]],"X0mSqw":["Will force use of a software filters (e.g. scale, pad, etc.) despite hardware acceleration settings."],"X9EHMa":["Editing Smart Collection \\"",["0"],"\\""],"XDT85c":["Media Sources"],"XIgmo9":["Did not receive an accessToken or userId from Jellyfin server."],"XNtsE7":["Calculating Slots..."],"XNw99A":["Software (No GPU)"],"XOgcN3":["Filler List: ",["0"]],"XOuE6F":["This could cause the following slot\'s programs to go unscheduled. Possible solutions include:"],"XSkU3F":["* Restart required"],"XWYqJx":["Duplicate Channel"],"XXwX66":["Set the log level for the Tunarr server.<0/>Selecting <1>\\"Use environment settings\\" will instruct the server to use the <2>LOG_LEVEL environment variable, if set, or system default \\"info\\"."],"XePUKr":["Test Transcode"],"XhWvkJ":[["0"]," of ",["1"]," ",["2"]," exceed the length of this slot (",["3"],"). Average program length: ",["4"]],"Xkppm4":["Enable Watermark"],"Xm/WEQ":["Channel Group"],"XsR2HX":["Test Duration (seconds)"],"Xuml3I":["By default, time slots are time of the day-based, you can change it to time of the day + day of the week. That means scheduling 7x the number of time slots. If you change from daily to weekly, the current schedule will be repeated 7 times. If you change from weekly to daily, many of the slots will be deleted."],"XwU6BE":["You haven\'t created any filler lists yet! Go to the <0>Filler Lists page to create one."],"Y2ngGV":["Add a Filler List"],"Y5XZLy":["<0>Pad Slot: Align slot start times to the specified pad time.<1/><2>Pad Episode: Align episode start times (within a slot) to the specified pad time. <3>NOTE: Depending on slot length and the chosen pad time, this could potentially create a lot of flex."],"Y84UgQ":["Loudness Target"],"YAKCkm":["An error occurred: ",["0"]],"YDlcs3":["Shuffle Programming"],"YLUnu0":["Test Playback"],"YN7vx3":["Custom Show"],"YRQaPv":["Last Synced"],"YRT1+e":["Creates a new collection"],"YSptU0":["Replicate..."],"YT5/eK":["Media Source: \\"",["0"],"\\""],"YXwR3a":["Restore default logo"],"YY/JN7":[" the following day."],"YYLNVW":["Insert breaks at these percentages of the program duration"],"YdIZFA":["This channel number has already been used"],"Yf/Mtb":["You\'re All Set!"],"Z10t2U":["Removes repeated programs."],"Z3FXyt":["Loading..."],"Z4IQ8m":["Channel Transcode Config"],"Z5IrB3":["Open in ",["0"]],"Z6dMWq":["Error while running system fixer ",["fixerId"],". Check server logs for details."],"ZND/fh":["Cannot be empty"],"ZNZzTe":["Cannot disable libraries when they are locked"],"ZShzvn":["\\"",["0"],"\\" Live"],"ZWRt1W":["Output Path"],"ZkdKVr":["Redirect to Channel ",["0"]],"Zky8hA":["The image will be rendered at its actual size without any scaling applied."],"Zs2GWW":["New Emby Media Source"],"Zul8Ry":["never"],"Zvipe1":["Editing Plex Server \\"",["0"],"\\""],"ZxwuFV":["Deleting a Channel will remove all programming from the channel. This action cannot be undone."],"a+Pr3s":["Apply to Program Types (empty = all)"],"a4N/Bg":["Load More"],"aE3UMm":["<0>None: slots are picked in the order they are specified in the table (i.e. not randomly)<1/><2>Uniform: all slots have an equal chance to be picked.<3/><4>Weighted: each slot is picked with a specified probability"],"aOaCIk":["Allow External"],"aScBGS":["Add a filter expression to fine-tune results of the search"],"aSwfbR":["Unit"],"ak3N0i":["Item was not present during the last scan"],"aoLy25":["Opacity"],"b0Uv6P":[["0","plural",{"one":["Path"],"other":["Paths"]}]],"b6sx4K":["No active sessions"],"bDY29m":["Logarithmic"],"bGG6B1":["Jellyfin"],"bHNlfr":["Increasing the slot duration."],"bNEQeI":["Cooldown"],"bORfbY":["Cannot use a channel number <= 0"],"bPJiZF":["Show: ",["0"]],"bSIBDb":["Release Date (asc)"],"bm8pgG":["Add group"],"boItSp":["Delete Media Source?"],"buS8nL":["Enable Subtitles"],"bxyuno":["Override global audio and subtitle settings for this channel."],"bydide":["FFMPEG Log Method"],"c6fsNw":["When enabled, intermittent watermarks fade in immediately when a stream is initialized. When disabled, the first watermark fade-in occurs after a full period."],"cF5KzV":["Edit Filler List"],"cFTdM+":["Console"],"cHYx4E":["Empty Trash"],"cLgGtf":["Reset programming to most recently saved state"],"cN5Dty":["No Programming scheduled"],"cOvZFM":["Dynamic"],"cXkSYc":["There was an error submitting the request to update Media Source settings. Please check the form and try again"],"caSM6R":["This is used by iptv clients to categorize the channels. You can leave it as \'tunarr\' if you don\'t need this sort of classification."],"cgo+Ch":[["remainingTime"]," left"],"cheWPw":["Duplicates"],"cjX7aq":["Are you sure you want to delete Smart Collection \\"",["0"],"\\"?"],"cmKYIw":["Overflow Behavior"],"cmlWKg":["<0>Error deleting custom show: ",["0"],"<1/>Please consider opening a bug with details!"],"cnCAaO":["Percentage-Based"],"cnGeoo":["Delete"],"cv/ykT":["Search Server URL:"],"cxrM1O":["Connect Sources"],"d5zxa4":["Local"],"d72gcv":["Loudnorm Options"],"d9HhJj":["This media source has no enabled or scanned libraries. Enable libraries for this source on the <0>Media Sources page or manually trigger scans on the <1>Library page."],"d9Tsiy":["Error updating channel.<0/>Check browser console for details"],"d9XR+x":["Transcode Config <0> <1/>"],"dBV/FP":["Lock Weights"],"dDX6oS":["Videos from the filler list will be randomly picked to play unless there are cooldown restrictions to place or if no videos are short enough for the remaining Flex time.<0/>Each filler can be assigned a cooldown, which restricts how frequently the list will be chosen during flex time."],"dEgA5A":["Cancel"],"dH8AwH":["Add Breaks"],"dK3Z9j":["Component"],"dQvGiF":[["0","plural",{"one":["#"," session"],"other":["#"," sessions"]}]],"dScixt":["Enable dark Mode"],"dUyQn5":["On-Demand"],"daSf8d":["Group episode programs by their show."],"djpQ8z":["Reload Stream"],"dkURuB":["Tail Buffer (minutes)"],"dnCwNB":["Successfully copied to clipboard!"],"eARDm/":[["0","plural",{"one":["#"," season"],"other":["#"," seasons"]}],", ",["1","plural",{"one":["#"," total episode"],"other":["#"," total episodes"]}]],"eEpDfJ":["Will force use of a software decoder despite hardware acceleration settings."],"eNorwJ":["Programs Too Long"],"ePK91l":["Edit"],"eSsduj":["VA-API Device"],"eZTFiP":["Review Selections"],"eZe0fr":["Audio Channels"],"ecUA8p":["Today"],"efuwN9":["These settings are stored in your browser and are saved automatically when changed."],"eg6m1K":["Edit Transcode Config: \\"",["0"],"\\""],"ep+NHZ":["If you proceed, all unsaved changes will be lost. Are you sure you want to proceed?"],"et+mIi":["Troubleshoot"],"euChZN":["Cyclic Shuffle"],"euc6Ns":["Duplicate"],"exYcTF":["Library"],"eyRsaH":["Root"],"f0w0IC":["Leave blank to use the channel\'s icon."],"f6Hub0":["Sort"],"f6pgxW":["Temporarily caches responses from Plex based by request path. Could potentially speed up channel editing."],"f7DWm5":["Need at least one path"],"fD+lMD":["Select the port the Tunarr server will listen on. This requires a server restart to take effect."],"fI+mNw":["Playlists"],"fJfo1A":["Server Path"],"fN4bgn":["Delete Filler List \\"",["0"],"\\"?"],"fQ9phi":["Remove All"],"fSRZCh":["Restore Default Settings"],"fU1065":["Mid-Roll"],"fWj7Tt":["Shuffle programming in a channel, optionally grouping programs by certain criteria."],"fcqkKg":["Not found!"],"fsBGk0":["Balance"],"ftF4U5":["Show Advanced"],"fxTyFe":["This slot is linked with ",["0"]," other ",["1","plural",{"one":["slot"],"other":["slots"]}],"Content fields are shared across the group."],"fyo+NB":["The End."],"fzWV5a":["Sort TV Shows (desc)"],"g2Pro3":["Reset changes made to the channel\'s lineup"],"g6LxbB":["Break Interval (minutes)"],"g7LzUS":["Install FFMPEG"],"gBx20d":["Custom Program"],"gH5Gbn":["Shuffle"],"gJrGqR":["FFmpeg version 7.1+ recommended. Check your current version in the sidebar"],"gL9DoB":["Programs shorter than this value will be treated the same as Flex time. Meaning that the TV Guide will try to meld them with the previous program or display the block of programs as the \\"place holder program\\" if they make a large continuous group. Use 0 to disable this feature or use a large value to make the channel report only the placeholder program and not the real programming.\\n",["0"]],"gR/hgc":["Error Audio"],"gcD6jw":["Hide watermark during filler"],"gf/bM4":["Continue with New Content"],"gg9/ya":["Remove ",["count"]," ",["0"]],"ghGSuE":["Ensures programs have a nice-looking start time, it will add Flex time to fill the gaps."],"glVpbE":["Eager"],"h/qU8b":["Override the default ",["0"]," device path (defaults to <0>/dev/dri/renderD128 on Linux and blank otherwise)"],"h4yKYk":["Next run"],"h8WhoR":["Slot Scheduler"],"hBGuBW":["Use channel default"],"hBzeL7":["Time before first break"],"hG89Ed":["Image"],"hISVAG":["Media Sources are where Tunarr sources your content. Media can come from your filesystem or a remote server, like Plex or Jellyfin. At least one Media Source is necessary to create channels and play media in Tunarr."],"hQRttt":["Submit"],"hQSabA":["TO"],"hXfj39":["Audio Sample Rate"],"hXzOVo":["Next"],"hYgDIe":["Create"],"he3ygx":["Copy"],"hehnjM":["Amount"],"hhukVU":["Trashed items are items that were previously scanned, but not found in a recent scan. This could be due to missing files or a media server no longer returning the item from its API. These items will be unplayable in channels in their current state. When the trash is emptied, their spots in channels will be replaced with flex."],"hjerov":["Guide Start Time"],"hlIKor":["None:"],"hnFEC+":["Initial Delay + Interval"],"hrdWlG":["Add Show"],"hvo+jE":["Add point (%)"],"i1+yww":["FFprobe version 6.0+ recommended. Check your current version in the sidebar"],"i2QuB6":["Error Screen"],"i9rcQ/":["Movies"],"iH8pgl":["Back"],"iQWhqk":["FFMPEG is installed. Detected version ",["0"]],"iTjV+L":["A-Z (desc)"],"iXJkMB":["Cooldown (s)"],"ih+n6S":["Linear"],"ihCTE6":["Error occurred while loading channels, please try again soon."],"ihn4zD":["Search…"],"ilkCYA":[["0","plural",{"one":["Selected Item"],"other":["Selected Items"]}]],"imrPBy":["Watermark Image URL"],"isC0OF":["Use these settings to override global ffmpeg settings for this channel."],"isRobC":["New"],"isyw73":["Auto uses the time convention for the selected language."],"jETaUB":["Buffer size effects how frequently ffmpeg reconsiders the output bitrate. <0>Read more"],"jHjfnS":["Add filler"],"jZlrte":["Color"],"jl3Q84":["Create a Channel"],"jz1oG0":["Selected Audio"],"k6TRai":["FFMPEG transcoding is required for some features like channel overlay, subtitles, and measures to prevent issues when switching episodes."],"kAidIP":["Failed to load feature flags."],"kBJRjR":["Download all logs"],"kIYDzY":["Successfully updated Media Source settings."],"kKgsI0":["<0>Configure the directory where Tunarr writes HLS segment files when transcoding. Tunarr will create the target directory (but not intermediate directories) if it doesn\'t exist.<1/>Changing this field will only affect new sessions. Existing sessions will continue writing to the previous setting, but will clean out segments when the segment ends.<2/>When unset, Tunarr will write segments to its current working directory."],"kKk153":["Load Stream"],"kO0aVB":["Break Duration (minutes)"],"kThBL9":["Sample rate cannot be changed when copying input audio"],"kdkZBD":["Increment"],"kii1WH":["Programming Preview"],"kolyzq":["This ",["0"]," is marked as missing in the database."],"kpfZ0g":["Minimum Program Duration (minutes)"],"kq6sAD":["Add TV Shows or Movies to filler"],"ksFZi3":["<0>Experimental: Enable Plex Request Cache"],"kvMAno":["Web Settings"],"l/UFPv":["Properties"],"l0VyMh":["Flex"],"l15zKW":["All Set!"],"lBADOx":[["count","plural",{"one":["#"," episode"],"other":["#"," episodes"]}]],"lC2oeQ":["Max Duration (minutes)"],"lCF0wC":["Refresh"],"lIUgjN":["Error copying channel m3u link to clipboard"],"lJSUC1":["Watermark"],"lKCfnI":["Audio Language Preferences"],"lS14fB":["Theme Settings"],"lW3FB1":["Download last ",["0"]," ",["1","plural",{"one":["#"," row"],"other":["#"," rows"]}]],"lWmRHf":["Time Slots..."],"lZMqZ5":["If enabled, TV show episodes will use the poster of their show, instead of the individual episode poster."],"laQT4o":["Thumbnail URL"],"lfFsZ4":["Channels"],"lkz6PL":["Duration"],"llDXYJ":["Backups"],"lnABVQ":["Run Troubleshooter"],"m+8qnB":["Library: ",["0"]],"m0Gp21":["Select a program and channel to test playback. The troubleshooter will analyze stream selection, build the FFmpeg pipeline, and run a short test transcode."],"m16xKo":["Add"],"m48LOH":["Hardware Acceleration"],"mCB6Je":["Select All"],"mDcLzR":["Caching"],"mF+u2B":["Don\'t see the library you want here? Ensure it is enabled in the <0>Media Source Settings."],"mGM6Aa":["Custom Shows are sequences of videos that represent a episodes of a virtual TV show. When you add these shows to a channel, the schedule tools will treat the videos as if they belonged to a single TV show."],"mHTMS1":["Normalize Frame Rate"],"mQt7fl":[["count","plural",{"one":["program"],"other":["programs"]}]],"mRWiYM":["Duration (seconds)"],"mWbpso":["Max Backups"],"mYBORk":["Movie"],"mYJG1x":["Your list will be replicated ",["0"]," times"],"mZFYjJ":["Error saving programs. ",["0"]],"mZFr14":["HLS not supported in this browser!"],"md42bg":["Transcode Config (optional override)"],"mgcp8D":["How often to insert a break"],"migeCK":["Filter which subtitle tracks are considered<0/><1>Any: All subtitle tracks are considered <2/><3>Forced: Only consider <4>\\"forced\\"subtitle tracks <5/><6>Default: Only consider default subtitle tracks <7/><8>None: Do not select any subtitles"],"mtQjGe":["Configure subtitle preferences. Preferences are evaluated in order of priority. The first matching subtitle stream on a program will be used."],"mvU6s8":["Sort TV Shows"],"mwtge0":["Started ",["startedAgo"]," - ",["remainingTime"],"remaining"],"n+7HJk":["When file paths on the remote server differ from the paths Tunarr can see, use Path Replacements to instruct Tunarr how to stream media from disk."],"n9nSNJ":["Time format"],"nH6YaM":["Other Videos"],"nSW2Lv":[["days","plural",{"one":["#"," day"],"other":["#"," days"]}]],"nV6twc":["Organize"],"nYD/Cq":["Ascending"],"nZXc7r":["Unlink from group"],"nfAddt":["FFmpeg Transcode Path"],"nfxRnc":["Tunarr is currently configured to use the AC3 audio encoder. This audio format is not supported by browsers. The resultant stream will likely not have audio or will not play at all."],"njIcYs":["Save as new collection…"],"ntJ9rt":["HLS Direct Output Format"],"nzDzPp":["toggle access token visibility"],"o0+Ul2":["Add Flex"],"o2Ucvk":["Libraries"],"o6OQlp":["Edit Channel"],"o7J4JM":["Filter"],"o7Y4WO":["Error saving new Emby server. See browser console and server logs for details"],"oADXRC":["Calculated ",["humanizedDuration"]," (",["numShows"]," programs) of programming in ",["duration"],"ms"],"oCHfGC":["Level"],"oCpfQF":["This feature is currently experimental. Proceed with caution and if you experience an issue, try disabling caching."],"oEZmaP":[["count","plural",{"one":["#"," season"],"other":["#"," seasons"]}]],"oMA2jd":["Removes any specials from the schedule. Specials are episodes with season \'00\'."],"oPWgse":["Maximum number of breaks per program (0 = unlimited)"],"ofUcbc":["Random"],"oihuQr":["Number of Replications"],"ousf2V":["Random…"],"ovBPCi":["Default"],"oxvBx3":["If set, any programming group with fewer episodes will be looped in order to make perfectly even blocks."],"p/78dY":["Position"],"p/KgUp":["The channel\'s regular programming between the specified hours. Flex time will fill up the remaining hours."],"p04z/V":["# Programs"],"p4XZFD":["Local Path"],"pDwcFl":["Save Smart Collection"],"pKYBXC":["Last Scheduled Execution"],"paEQ75":["\\"Stealth\\" channels are hidden from TV guides, spoofed HDHR, m3u playlist, etc. The channel can still be streamed directly or be used as a redirect target."],"pcRxi1":["How frequently libraries should be scanned (starting from midnight)."],"pdlmIS":["<0>Error deleting filler list: ",["0"],"<1/>Please consider opening a bug with details!"],"pkERVr":["Download JSON"],"pqarBu":["Asc"],"pvnfJD":["Dark"],"pwPreK":["Restrict Hours"],"pxh+PI":["Builder"],"q6GKgP":["VAAPI Capabilities"],"q6nlo/":["Subtitle Action"],"q9p3Xw":["Bitrate cannot be changed when copying input audio"],"qAGp2O":["Proceed"],"qG6T/X":["Add Programming"],"qKNcv7":["Generating Bug Report Link..."],"qV9xkb":["Passthrough audio unchanged. Other settings will not apply."],"qiXmlF":["Add Media"],"qjW34v":["This channel is set up to use <0>",["0"],"Slots for programming. Any manual changes on this page will likely make this channel stop adhering to that schedule."],"qlR1dD":["Delete Channel \\"",["0"],"\\"?"],"qs/mhD":["Ensures programs start only at a particular interval within the hour. This makes for nice looking schedules. Flex time is scheduled to facilitate."],"r3ptXC":["Manually add an access token from your Jellyfin server"],"r9sc/0":["Duration must be numeric"],"rAx5u1":["End Time"],"rPEEWz":["Successfully saved config!"],"rSZlvN":["Programming Start"],"rhEkXj":["Head"],"rl/8FN":["Commit"],"rnbEQB":["Copy M3U URL"],"roIf2/":["On-Demand?"],"rtDDIV":["Edit Slot"],"ru5qTc":["Edit Media Source"],"rx5Ria":["All lists are used"],"rxumR2":["Match any of"],"s2OE0W":["Enter a name for your Jellyfin Server"],"s4iETe":["Transcode Config"],"s6lNC3":["Fallback Mode"],"s8zbIS":["Include Seasons"],"sA8Jt7":["This slot replays content aired by continue slots earlier in the period."],"sBJ5MF":["Sources"],"sNnXh6":["Order of programming within the slot"],"sUtIRs":["about "],"sVVcvs":["Experimental Features"],"sfbjgG":["Audio Format"],"sxkWRg":["Advanced"],"sxwNOp":["Logs Directory:"],"sztQMJ":["Programs a Flex time slot. Normally you\'d use pad times, restrict times or add breaks to add a large quantity of Flex times at once, but this exists for more specific cases."],"t/YqKh":["Remove"],"t3hvHq":["Sync Now"],"t5q6kk":["For more details on manually retrieving a Plex token, see <0>here"],"t6+QCF":[["count"]," ",["programLabel"],", ",["0"]],"t8Hzw3":["Cyclic Shuffle randomly shuffles groups of programming."],"tDuQbQ":["Stream Mode"],"tEvsql":["Subtitles"],"tH1aCG":["Video Bitrate"],"tMxWK0":["Adds Flex breaks after each TV episode or movie to ensure that the program starts at one of the allowed minute marks. For example, you can use this to ensure that all your programs start at either XX:00 times or XX:30 times. Removes any existing Flex periods before adding the new ones. This button might be disabled if the channel is already too large."],"tPGTPB":["Roll the log file on a fixed schedule, regardless of file size."],"tRgOE5":["Balance Programming"],"tXkhj/":["Start"],"tXub8j":["Display Watermark on Leading Edge"],"tYuxvA":["FFMPEG"],"tfDRzk":["Save"],"tgPwON":["Operator"],"ti6ugP":["Error while saving transcode config. See console log for details."],"tkDYSE":[["hours","plural",{"one":["#"," hour"],"other":["#"," hours"]}]],"tlMRNb":["The loaded version of the Tunarr UI does not match the server. Reload the browser to get the latest. If this message persists, clear your browser cache and reload."],"tlNobE":["Custom Show: ",["0"]],"tlmh8e":["Add all selected programs to channel"],"tsqRRB":[["0"]," Poster"],"ty8rVI":["Now Playing:"],"tzwArf":["View in ",["0"]],"u+VWhB":["Copied to clipboard!"],"u+zFIr":["Restrict search fields"],"uAQUqI":["Status"],"uHTa9V":["To use Tunarr, you need to first connect a media source. This will allow you to build custom channels with your content."],"uLiDe/":["Enable embedded subtitle extraction"],"uUTf8r":["Delete Custom Show \\"",["0"],"\\"?"],"uamufO":["Add TV Shows or Movies to programming list."],"ueG1bp":["Program Count"],"ueLbrY":["If true, adjusting the weight of one slot will scale the weights of other slots such that all weights total 100%. Otherwise, weights can be adjusted freely and the weight of each slot is only relative to the total weight."],"uixVel":["By default, saves backups in the server\'s run directory, or, if running in Docker, to /config/tunarr/backups"],"uyR9ei":["Block Shuffle"],"v4nbQ4":["If no more programs can fit into a duration-based slot, flex time is added to fill the gap. This setting determines how flex is added <0>within the slot to ensure all time is filled.<1/><2>Between: Flex time is added between videos within a slot, if there are multiple<3/><4>End: Flex time is added at the end of the slot"],"v5IstB":["after every program"],"v5URfV":["Like Random Shuffle, but tries to preserve the sequence of episodes for each TV show. If a TV show has multiple instances of its episodes, they are also cycled appropriately."],"vAK/B1":["Audio Action"],"vCBet9":["Not a valid number"],"vERlcd":["Profile"],"vGRvxs":["Channel group is required"],"vLf7qg":["Interval (minutes)"],"vSJd18":["Video"],"vU/Hht":["Distribution"],"vXIe7J":["Language"],"vcvFVw":["Escape Hatches"],"vkA4W/":["Source Type"],"vn3SVH":["Could not parse this filter expression. Check the <0>documentation for information about filter expressions."],"vreTxe":[["count","plural",{"one":["#"," program"],"other":["#"," programs"]}]],"vwFKu0":["Cast & Crew"],"vyL1gO":["Release Date (desc)"],"w/bY7R":["Logs"],"w2pCRr":["Show:"],"w3KBq0":["Allows programs to play a bit late if the previous program took longer than usual. If a program is too late, Flex is scheduled instead."],"w3g+lo":["Let\'s get started..."],"wBmIEf":["Number of hours to include in the XMLTV file"],"wBo/7A":["Error while scheduling ",["taskId"],". Check server logs for details"],"wKClDM":["Adds a channel redirect. During this period of time, the channel will redirect to another channel."],"wMHvYH":["Value"],"wOUKOZ":["Max True Peak"],"wZOYCY":["Video Format"],"wdfBIP":["Sort By..."],"wdxz7K":["Source"],"wkQ2tb":["Adds Flex breaks after each TV episode or movie to ensure that the program starts at one of the allowed minute marks."],"wlYdUk":[["count","plural",{"one":["hour"],"other":["hours"]}]],"wpT1VN":["Condition"],"wtuVU4":["Frequency"],"wwu18a":["Icon"],"x+AjXa":["Channel Fallback"],"x/dwZe":["Enable if the watermark is an animated GIF or PNG. The watermark will loop according to the image\'s configuration. If this option is enabled and the image is not animated, there will be playback errors."],"x1tGMH":["Override how programs within this slot are padded."],"x6/Zc6":["Tail"],"x63PSs":["Search for shows"],"x7PDL5":["Logging"],"xCJdfg":["Clear"],"xDAtGP":["Message"],"xDPFrK":["Scan ",["0"]],"xGVfLh":["Continue"],"xGYZfl":["Edit Libraries"],"xIn7qU":["Disable Hardware Decoding"],"xJIepX":["Default Config"],"xOkMus":["Hardware Accel."],"xPmesF":["Loudness Range Target"],"xQC5se":["Advanced Video Options"],"xXrtPO":["Failed to load item details! Check logs for details"],"xazqmy":["Seasons"],"xbtgIC":["HW Acceleration"],"xdA/+p":["Tools"],"xmBknQ":["Filler Lists"],"xptXTM":["Select Artists to Remove"],"xqIrnW":["Library Clip (not yet implemented)"],"xu3Kah":[["0","plural",{"one":["#"," program"],"other":["#"," programs"]}]],"y28hnO":["Post"],"y4Jmre":["Break Duration"],"y4iKY3":[["count","plural",{"one":["#"," album"],"other":["#"," albums"]}]],"y5x0aB":[["0"]," Info"],"y7wpam":[["value","plural",{"one":["#"," program"],"other":["#"," programs"]}]],"yDUcwc":["Manually add an access token from your Emby server"],"yEDNx2":["Tunarr will update Plex\'s \\"now playing\\" state while channels are active."],"yPE51X":["Configure transcoding settings for Tunarr\'s streams. Each channel is assigned one transcode configuration."],"yPK7+5":["Auto-Update Guide"],"yQE2r9":["Loading"],"yRkqG9":["Limit"],"yX8Rkw":["Add All"],"yftDqj":["New Filler List"],"yjzkvk":["Stop Transcode Session"],"ysJk7v":["Movie Sort Order"],"ysecYP":["Search for a program"],"ytXxnP":["Forced"],"yz/C2/":["Rerun"],"yz7wBu":["Close"],"z4K9d+":["Roll based on size"],"z61uNR":["Add Flex Time"],"zV6tsp":["Consolidate"],"zV9awV":["Force Scan"],"zpylsE":["Transcoding Settings"],"zrmjn/":["Max Duration"],"zthKEs":["The streaming mode affects the type of underlying transcoding process used to create the channel\'s video stream.<0/>Learn more about Tunarr\'s stream modes <1>here!"],"zvjEp6":["Filler cooldown must be a number"],"zx4BuL":["Week"],"zyLvkd":["Category Log Levels"]}', +) as Messages; diff --git a/web/src/locales/pseudo-LOCALE/messages.po b/web/src/locales/pseudo-LOCALE/messages.po index cac49203a..dd51b90b8 100644 --- a/web/src/locales/pseudo-LOCALE/messages.po +++ b/web/src/locales/pseudo-LOCALE/messages.po @@ -298,16 +298,16 @@ msgstr "" msgid "about " msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:362 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:398 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:439 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:455 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:382 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:424 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:456 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:472 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:265 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:281 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:367 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:405 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:451 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:468 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:432 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:474 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:511 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:528 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:269 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:286 msgid "Access Token" msgstr "" @@ -315,10 +315,10 @@ msgstr "" #: src/components/settings/AddPlexServer.tsx:14 #: src/components/settings/media_source/AddMediaSourceButton.tsx:83 #: src/components/settings/media_source/EditPathReplacementsForm.tsx:34 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:499 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:516 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:514 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:596 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:338 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:360 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:394 #: src/hooks/useRouteName.ts:83 msgid "Add" msgstr "" @@ -444,7 +444,7 @@ msgstr "" msgid "Adds Flex breaks between programs, attempting to avoid groups of consecutive programs that exceed the specified number of minutes." msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:196 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:233 msgid "Adjust the output volume (not recommended). Values higher than 100 will boost the audio." msgstr "" @@ -458,7 +458,7 @@ msgstr "" #~ msgid "Advanced" #~ msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:255 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:292 msgid "Advanced options relating to audio. In general, do not change these unless you know what you are doing!" msgstr "" @@ -466,7 +466,7 @@ msgstr "" msgid "Advanced options relating to transcoding. In general, do not change these unless you know what you are doing! These settings exist in order to leave some parity with the old dizqueTV transcode pipeline as well as to provide mechanisms to aid in debugging streaming issues." msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:252 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:289 #: src/components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx:223 msgid "Advanced Video Options" msgstr "" @@ -596,19 +596,19 @@ msgstr "" msgid "Audio Action" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:102 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:139 msgid "Audio Bitrate" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:131 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:168 msgid "Audio Buffer Size" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:185 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:222 msgid "Audio Channels" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:80 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:117 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:139 msgid "Audio Format" msgstr "" @@ -617,8 +617,8 @@ msgstr "" msgid "Audio Language Preferences" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:211 -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:214 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:248 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:251 msgid "Audio Loudness Normalization" msgstr "" @@ -626,7 +626,7 @@ msgstr "" msgid "Audio Options" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:161 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:198 msgid "Audio Sample Rate" msgstr "" @@ -634,7 +634,7 @@ msgstr "" msgid "Audio Streams" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:195 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:232 msgid "Audio Volume" msgstr "" @@ -650,7 +650,7 @@ msgstr "" msgid "Auto uses the time convention for the selected language." msgstr "" -#: src/components/settings/media_source/PlexServerEditDialog.tsx:344 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:352 msgid "Auto-Update Guide" msgstr "" @@ -703,7 +703,7 @@ msgstr "" msgid "Bit Depth" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:113 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:150 msgid "Bitrate cannot be changed when copying input audio" msgstr "" @@ -736,7 +736,7 @@ msgstr "" msgid "Break Positioning" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:142 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:179 msgid "Buffer size cannot be changed when copying input audio" msgstr "" @@ -786,10 +786,10 @@ msgstr "" #: src/components/programming_controls/BalanceProgrammingModal.tsx:68 #: src/components/programming_controls/RemoveShowsModal.tsx:429 #: src/components/programming_controls/ShuffleProgrammingModal.tsx:76 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:486 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:503 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:501 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:583 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:330 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:353 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:387 #: src/components/settings/UnsavedNavigationAlert.tsx:67 #: src/components/slot_scheduler/EditRandomSlotDialogContent.tsx:576 #: src/components/slot_scheduler/EditTimeSlotDialogContent.tsx:408 @@ -804,9 +804,9 @@ msgstr "" msgid "Cancel" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:280 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:294 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:214 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:281 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:342 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:215 msgid "Cannot be empty" msgstr "" @@ -1291,7 +1291,7 @@ msgstr "" msgid "Details" msgstr "" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:196 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:203 msgid "Did not receive an accessToken or userId from Jellyfin server." msgstr "" @@ -1315,7 +1315,7 @@ msgstr "" msgid "Disable Watermarks" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:219 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:256 #: src/pages/settings/FfmpegSettingsPage.tsx:224 #: src/pages/system/StatusPage.tsx:334 msgid "Disabled" @@ -1473,14 +1473,14 @@ msgstr "" #. placeholder {0}: server.name #. placeholder {0}: source.name -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:78 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:75 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:79 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:78 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:214 msgid "Editing \"{0}\"" msgstr "" #. placeholder {0}: server.name -#: src/components/settings/media_source/PlexServerEditDialog.tsx:77 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:78 msgid "Editing Plex Server \"{0}\"" msgstr "" @@ -1497,7 +1497,7 @@ msgstr "" msgid "Empty Trash" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:226 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:263 msgid "Enable <0>EBU R 128 loudness normalization via the <1>loudnorm FFmpeg filter. May increase CPU usage during streaming." msgstr "" @@ -1554,7 +1554,7 @@ msgstr "" msgid "Enabled" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:222 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:259 msgid "Enabled (loudnorm)" msgstr "" @@ -1578,11 +1578,11 @@ msgstr "" msgid "Ensures programs start only at a particular interval within the hour. This makes for nice looking schedules. Flex time is scheduled to facilitate." msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:342 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:345 msgid "Enter a name for your Emby Server" msgstr "" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:356 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:406 msgid "Enter a name for your Jellyfin Server" msgstr "" @@ -1590,11 +1590,11 @@ msgstr "" msgid "Enter a name for your Local Media Source" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:413 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:420 msgid "Enter your Emby password to generate a new access token." msgstr "" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:439 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:489 msgid "Enter your Jellyfin password to generate a new access token.<0/><1>NOTE: These are never saved to the Tunarr DB. Instead they are sent to Jellyfin to exchange for a session token." msgstr "" @@ -1636,11 +1636,11 @@ msgstr "" msgid "Error querying Plex. Check console log and consider reporting a bug!" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:146 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:147 msgid "Error saving new Emby server. See browser console and server logs for details" msgstr "" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:115 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:122 msgid "Error saving new Jellyfin server. See browser console and server logs for details" msgstr "" @@ -1950,7 +1950,7 @@ msgstr "" msgid "Flex Style" msgstr "" -#: src/components/settings/media_source/PlexServerEditDialog.tsx:292 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:297 msgid "For more details on manually retrieving a Plex token, see <0>here" msgstr "" @@ -2368,15 +2368,15 @@ msgstr "" msgid "Loop Short Programs" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:281 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:318 msgid "Loudness Range Target" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:271 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:308 msgid "Loudness Target" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:263 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:300 msgid "Loudnorm Options" msgstr "" @@ -2396,11 +2396,11 @@ msgstr "" msgid "Manual" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:467 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:480 msgid "Manually add an access token from your Emby server" msgstr "" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:484 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:540 msgid "Manually add an access token from your Jellyfin server" msgstr "" @@ -2438,7 +2438,7 @@ msgstr "" msgid "Max Lateness" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:291 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:328 msgid "Max True Peak" msgstr "" @@ -2573,10 +2573,10 @@ msgstr "" #: src/components/settings/ConnectMediaSources.tsx:44 #: src/components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx:95 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:93 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:335 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:349 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:338 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:399 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:238 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:317 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:325 #: src/components/smart_collections/CreateSmartCollectionDialog.tsx:162 #: src/components/smart_collections/EditSmartCollectionDialog.tsx:108 #: src/components/smart_collections/SmartCollectionsTable.tsx:59 @@ -2589,10 +2589,10 @@ msgstr "" msgid "Name" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:330 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:344 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:333 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:394 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:233 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:312 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:320 msgid "Name can only contain alphanumeric characters, dashes, and underscores" msgstr "" @@ -2623,7 +2623,7 @@ msgstr "" msgid "New Custom Show" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:78 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:79 msgid "New Emby Media Source" msgstr "" @@ -2635,11 +2635,11 @@ msgstr "" msgid "New Local Media Source" msgstr "" -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:75 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:78 msgid "New Media Source" msgstr "" -#: src/components/settings/media_source/PlexServerEditDialog.tsx:78 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:79 msgid "New Plex Server" msgstr "" @@ -2711,9 +2711,9 @@ msgstr "" msgid "Not a valid number" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:282 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:296 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:216 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:283 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:344 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:217 msgid "Not a valid URL" msgstr "" @@ -2781,8 +2781,8 @@ msgstr "" msgid "Options" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:418 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:448 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:428 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:501 msgid "OR" msgstr "" @@ -2858,12 +2858,12 @@ msgstr "" msgid "Pad Times" msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:85 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:122 msgid "Passthrough audio unchanged. Other settings will not apply." msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:382 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:407 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:388 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:457 msgid "Password" msgstr "" @@ -3030,9 +3030,9 @@ msgstr "" msgid "Properties" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:284 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:298 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:218 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:285 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:346 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:219 msgid "Protocol must be HTTP or HTTPS" msgstr "" @@ -3314,7 +3314,7 @@ msgstr "" msgid "Running..." msgstr "" -#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:172 +#: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:209 msgid "Sample rate cannot be changed when copying input audio" msgstr "" @@ -3449,9 +3449,9 @@ msgstr "" msgid "Selected Subtitle" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:305 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:319 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:239 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:307 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:368 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:241 msgid "Server is unreachable" msgstr "" @@ -4006,11 +4006,11 @@ msgstr "" msgid "Today" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:390 -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:447 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:416 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:464 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:273 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:397 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:460 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:466 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:520 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:278 msgid "toggle access token visibility" msgstr "" @@ -4085,6 +4085,18 @@ msgstr "" msgid "Tunarr runs various tasks, sometimes on a schedule, for background operations." msgstr "" +#: src/components/settings/media_source/PlexServerEditDialog.tsx:355 +msgid "Tunarr will attempt to get Plex to pull Tunarr's updated XMLTV upon regeneration" +msgstr "" + +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:571 +msgid "Tunarr will update Jellyfin's \"now playing\" state while channels are active." +msgstr "" + +#: src/components/settings/media_source/PlexServerEditDialog.tsx:375 +msgid "Tunarr will update Plex's \"now playing\" state while channels are active." +msgstr "" + #: src/pages/settings/HdhrSettingsPage.tsx:105 #: src/pages/settings/HdhrSettingsPage.tsx:108 msgid "Tuner Count" @@ -4122,16 +4134,21 @@ msgstr "" #~ msgid "Unlink from group" #~ msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:499 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:516 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:514 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:596 #: src/components/settings/media_source/LocalMediaEditDialog.tsx:338 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:360 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:394 msgid "Update" msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:291 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:305 -#: src/components/settings/media_source/PlexServerEditDialog.tsx:225 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:568 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:372 +msgid "Update Play Status" +msgstr "" + +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:292 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:353 +#: src/components/settings/media_source/PlexServerEditDialog.tsx:226 #: src/pages/settings/MediaSourceSettingsPage.tsx:88 msgid "URL" msgstr "" @@ -4148,8 +4165,8 @@ msgstr "" msgid "Use these settings to override global ffmpeg settings for this channel." msgstr "" -#: src/components/settings/media_source/EmbyServerEditDialog.tsx:357 -#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:376 +#: src/components/settings/media_source/EmbyServerEditDialog.tsx:361 +#: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:426 msgid "Username" msgstr "" diff --git a/web/src/locales/pseudo-LOCALE/messages.ts b/web/src/locales/pseudo-LOCALE/messages.ts index 6a878a6ea..bc39a770f 100644 --- a/web/src/locales/pseudo-LOCALE/messages.ts +++ b/web/src/locales/pseudo-LOCALE/messages.ts @@ -1 +1,4 @@ -/*eslint-disable*/import type{Messages}from"@lingui/core";export const messages=JSON.parse("{\"++nzCr\":[\"ßĩţ Ďēƥţĥ\"],\"+2JHIs\":[\"Ĺĩńķ ţō ēxĩśţĩńĝ śĺōţ\"],\"+406Vu\":[\"Vĩēŵ Ƒũĺĺ Ďēţàĩĺś\"],\"+4YwQF\":[\"# ōƒ Ƥŕōĝŕàḿś\"],\"+4mjS6\":[\"Ŕēḿōvē ĩćōń\"],\"+9EErD\":[\"Ḿũśĩć Vĩďēōś\"],\"+DmLct\":[\"Ƥŕōĝŕàḿś\"],\"+SA5Ao\":[\"À ŕōōţ ƥàţĥ ţō śćàń ƒōŕ ḿēďĩà. Ĺōćàĺ śōũŕćēś ćàń śēàŕćĥ ḿàńŷ ďĩƒƒēŕēńţ ƥàţĥś.\"],\"+TZiPJ\":[\"Śēŕvēŕ ĩś ũńŕēàćĥàƀĺē\"],\"+UPOiB\":[[\"count\",\"plural\",{\"one\":[\"ḿĩń\"],\"other\":[\"ḿĩńś\"]}]],\"+Xg5cX\":[\"Ƒĩĺĺēŕ ĩś ƥĩćķēď ƒŕēśĥ àţ śţŕēàḿ ţĩḿē ĺĩķē Ƒĺēx ţĩḿē. Ţĥē ĝũĩďē śĥōŵś \\\"Ćōḿḿēŕćĩàĺ ßŕēàķ\\\" ƥĺàćēĥōĺďēŕś.\"],\"+YdE7b\":[\"Ēńàƀĺē ŕōĺĺĩńĝ ĺōĝ ƒĩĺēś ũśĩńĝ ţĩḿē àńď/ōŕ śĩźē ƀàśēď ćŕĩţēŕĩà\"],\"+hl/7A\":[\"Ćĥàńńēĺś ćōńƒĩĝũŕēď ţō ũśē ţĥē ĤĹŚ Ďĩŕēćţ śţŕēàḿ ḿōďē ŵĩĺĺ ōũţƥũţ ĩń ţĥē śēĺēćţēď ćōńţàĩńēŕ ƒōŕḿàţ.\"],\"+k9lxR\":[\"Ēńţēŕ à ńàḿē ƒōŕ ŷōũŕ Ĺōćàĺ Ḿēďĩà Śōũŕćē\"],\"+mdNfU\":[[\"count\",\"plural\",{\"one\":[\"#\",\" ţŕàćķ\"],\"other\":[\"#\",\" ţŕàćķś\"]}]],\"+suWTj\":[\"Àďďś Ƒĺēx ƀŕēàķś ƀēţŵēēń ƥŕōĝŕàḿś, àţţēḿƥţĩńĝ ţō àvōĩď ĝŕōũƥś ōƒ ćōńśēćũţĩvē ƥŕōĝŕàḿś ţĥàţ ēxćēēď ţĥē śƥēćĩƒĩēď ńũḿƀēŕ ōƒ ḿĩńũţēś.\"],\"+tlhMz\":[\"Ƥĺēx (Ḿàńũàĺ)\"],\"+yEE7s\":[\"Ńēŵ Ḿēďĩà Śōũŕćē\"],\"+yOcRn\":[\"ĤĎĤŔ\"],\"+ya1pX\":[\"Ďēĺēţē Śĺōţ\"],\"+zY9Xc\":[\"Ćōńƒĩĝũŕē Ćŷćĺĩć Śĥũƒƒĺē\"],\"+zy2Nq\":[\"Ţŷƥē\"],\"/+ZaFm\":[\"Śōũńďţŕàćķ\"],\"/4gGIX\":[\"Ćōƥŷ ţō ćĺĩƥƀōàŕď\"],\"/6iIT9\":[\"Śēţţĩńĝś Śàvēď!\"],\"/DTWjr\":[\"Ćōńĝŕàţś, ŷōũ'ŕē ŕēàďŷ ţō śţàŕţ ƀũĩĺďĩńĝ ćĥàńńēĺś! ĵũśţ ćĺĩćķ Ƒĩńĩśĥ ƀēĺōŵ ţō śţàŕţ ŵōŕķĩńĝ ōń ŷōũŕ ƒĩŕśţ ćĥàńńēĺ.\"],\"/QmYEW\":[\"ßàĺàńćē...\"],\"/TEOcd\":[\"Ƥŕēśēţś\"],\"/e88IO\":[\"Śćĥēďũĺē ƥŕōĝŕàḿḿĩńĝ ĩń ƀĺōćķś ţĥàţ àŕē ēĩţĥēŕ ćōũńţ ōŕ ďũŕàţĩōń ƀàśēď. Ćàń ƀē ũśēď ţō ĝēńēŕàţē ŕàńďōḿ śćĥēďũĺēś.\"],\"/gavzH\":[\"ßàśĩć ƀũţţōń ĝŕōũƥ\"],\"/j3jjC\":[\"Ēŕŕōŕ ŵĥĩĺē śàvĩńĝ śēţţĩńĝś. Ƥĺēàśē ćĥēćķ ćōńśōĺē ƒōŕ ďēţàĩĺś.\"],\"/n/HCO\":[\"Ķēŷŵōŕďś\"],\"/rTz0M\":[\"Àũďĩō\"],\"/vJase\":[\"Śţŕēàḿĩńĝ\"],\"09gg05\":[\"Ƥŕōĝŕàḿḿĩńĝ\"],\"0IAEaX\":[\"Ḿàţćĥ\"],\"0MWZh1\":[\"Śēàŕćĥ ĩś ćũŕŕēńţĺŷ śćōƥēď ţō ţĥĩś Ḿēďĩà Śōũŕćē Ĺĩƀŕàŕŷ.\"],\"0VHz2s\":[\"Ƒĩĺĺēŕ Ōƥţĩōńś\"],\"0cULRy\":[\"Ēxƥēŕĩḿēńţàĺ: Ḿàķē ƥēŕƒēćţ śćĥēďũĺē ĺōōƥ\"],\"0dy9K6\":[\"Ŕēàď Ĺēśś\"],\"0mEBXY\":[\"Ďēĺēţē Ţŕàńśćōďĩńĝ Ćōńƒĩĝ \\\"\",[\"0\"],\"\\\"?\"],\"0wJVK+\":[\"ßàśĩć\"],\"0zpgxV\":[\"Ōƥţĩōńś\"],\"1/dAym\":[\"Ĝŕōũƥĩńĝ ŵōŕķś àś ƒōĺĺōŵś:\"],\"14PdY0\":[\"Ćōńƒĩĝ\"],\"1AdBl9\":[\"ßŕēàķ Ƥōśĩţĩōńĩńĝ\"],\"1BDPP1\":[\"Ĺōōķś ĺĩķē śōḿēţĥĩńĝ ŵēńţ ŵŕōńĝ.\"],\"1BGQfg\":[\"Àĺƥĥàƀēţĩćàĺĺŷ\"],\"1CFAQ+\":[\"Śēţ ƀŷ ēńvĩŕōńḿēńţ vàŕĩàƀĺē\"],\"1DxLRi\":[\"Ńō ƥŕōĝŕàḿḿĩńĝ śćĥēďũĺēď ƒōŕ ţĥĩś ţĩḿē ƥēŕĩōď\"],\"1PQRWr\":[\"Śţàŕţ Ţĩḿē\"],\"1QfxQT\":[\"Ďĩśḿĩśś\"],\"1TYXl0\":[\"Ēńţēŕ ŷōũŕ Ēḿƀŷ ƥàśśŵōŕď ţō ĝēńēŕàţē à ńēŵ àććēśś ţōķēń.\"],\"1V3Prt\":[\"Ďēĺēţĩńĝ à Ƒĩĺĺēŕ ŵĩĺĺ ŕēḿōvē àĺĺ ƥŕōĝŕàḿḿĩńĝ ƒŕōḿ ţĥē ćĥàńńēĺ. Ţĥĩś àćţĩōń ćàńńōţ ƀē ũńďōńē.\"],\"1Z90J4\":[\"Ďàŷś ţō Ƥŕēćàĺćũĺàţē\"],\"1hKEom\":[\"Ƥŕĩōŕĩţŷ\"],\"1jqDmP\":[\"Śũććēśśƒũĺĺŷ śćĥēďũĺēď \",[\"taskId\"],\" (ŕũńńĩńĝ ĩń ƀàćķĝŕōũńď).\"],\"1njn7W\":[\"Ĺĩĝĥţ\"],\"2BBAbc\":[\"Ĺĩśţ\"],\"2BRPyl\":[\"Śŷśţēḿ Ĩńƒō\"],\"2CVuYr\":[\"Śḿàŕţ Ćōĺĺēćţĩōń - \",[\"0\"]],\"2L7cj6\":[\"Ŷōũ ĥàvēń'ţ ćŕēàţēď àńŷ ćĥàńńēĺś ŷēţ.\"],\"2QLniG\":[\"Ēxĩśţĩńĝ ǫũēŕŷ: \",[\"filterString\"]],\"2eFlmt\":[\"Ţŕàćķś\"],\"2hOCU2\":[\"Śḿàŕţ Ćōĺĺēćţĩōńś\"],\"2imNg3\":[\"Ŵēƀ vēŕśĩōń = \",[\"0\"],\", Śēŕvēŕ vēŕśĩōń = \",[\"1\"]],\"2mAJXf\":[\"Ḿàķēś ḿũĺţĩƥĺē ćōƥĩēś ōƒ ţĥē śćĥēďũĺē àńď ƥĺàŷś ţĥēḿ ĩń śēǫũēńćē. Ńōŕḿàĺĺŷ ţĥĩś ĩśń'ţ ńēćēśśàŕŷ, ƀēćàũśē Ţũńàŕŕ ŵĩĺĺ àĺŵàŷś ƥĺàŷ ţĥē śćĥēďũĺē ƀàćķ ƒŕōḿ ţĥē ƀēĝĩńńĩńĝ ŵĥēń ĩţ ƒĩńĩśĥēś. ßũţ ćŕēàţĩńĝ ŕēƥĺĩćàś ĩś à ũśēƒũĺ ĩńţēŕḿēďĩàŕŷ śţēƥ śōḿēţĩḿēś ƀēƒōŕē àƥƥĺŷĩńĝ ōţĥēŕ ţŕàńśƒōŕḿàţĩōńś. Ńōţē ţĥàţ ƀēćàũśē vēŕŷ ĺàŕĝē ćĥàńńēĺś ćàń ƀē ƥŕōƀĺēḿàţĩć, ţĥē ńũḿƀēŕ ōƒ ŕēƥĺĩćàś ŵĩĺĺ ƀē ĺĩḿĩţēď ţō àvōĩď ćŕēàţĩńĝ ŕēàĺĺŷ ĺàŕĝē ćĥàńńēĺś.\"],\"2oWehJ\":[\"Ŕēśēţ ţō ćũŕŕēńţ ďàţē/ţĩḿē\"],\"2vxecF\":[\"Śĥōŵ Śţēàĺţĥ\"],\"2x4THe\":[\"\\\"\",[\"0\"],\"\\\" Śēśśĩōńś\"],\"312fSE\":[\"Śēĺēćţ Śĥōŵś ţō Ŕēḿōvē\"],\"315BhT\":[\"Àĺƥĥàƀēţĩćàĺ\"],\"3JIYke\":[\"Ĥēàĺţĥŷ?\"],\"3JQkm5\":[\"Ƥàţĥ Ŕēƥĺàćēḿēńţś\"],\"3JjdaA\":[\"Ŕũń\"],\"3LfNqe\":[\"Ćĥàńńēĺ Ńũḿƀēŕ\"],\"3SH6Vv\":[\"Ćōƥĩēď ćĥàńńēĺ \\\"\",[\"channelName\"],\"\\\" ḿ3ũ ĺĩńķ ţō ćĺĩƥƀōàŕď\"],\"3YNjnA\":[\"Śŷśţēḿ Ēńvĩŕōńḿēńţ\"],\"3b1vGb\":[\"Ńēŵ Ĺōćàĺ Ḿēďĩà Śōũŕćē\"],\"3mAQJI\":[\"Ĥōŵ ōƒţēń ţĥē XḾĹŢV ƒĩĺē ĩś ŕēĝēńēŕàţēď\"],\"3nLdaX\":[\"Àďď \",[\"0\"]],\"3nwcC5\":[\"Ƒĩĺĺēŕ - \",[\"0\"]],\"49dCCB\":[\"Ũśē Śĥōŵ Ƥōśţēŕ\"],\"4Fpcxu\":[\"Ĩńĩţĩàĺ Ďēĺàŷ (ḿĩńũţēś)\"],\"4NbDEd\":[\"Ďēĺēţĩńĝ à Ćũśţōḿ Śĥōŵ ŵĩĺĺ ŕēḿōvē ĩţś ƥŕōĝŕàḿḿĩńĝ ƒŕōḿ ćĥàńńēĺś ţĥàţ ũśē ĩţ. Ţĥĩś àćţĩōń ćàńńōţ ƀē ũńďōńē.\"],\"4Uc/2h\":[\"Śēŕvēŕ Ĺĩśţēń Ƥōŕţ\"],\"4VxpoP\":[\"Ḿũśĩć ţŕàćķś àŕē ĝŕōũƥēď ƀŷ àŕţĩśţ\"],\"4XSc4l\":[\"Ŵēēķĺŷ\"],\"4XfYeY\":[\"Ŕàńďōḿ (ƀŷ śĥōŵ)\"],\"4fLgiT\":[\"Àĺĺōŵ Ĩḿàĝē ßàśēď\"],\"4qmJK4\":[\"Ţũńàŕŕ ßàćķēńď ŨŔĹ\"],\"4wkwyL\":[\"Ďĩśàƀĺē Ĥàŕďŵàŕē Ƒĩĺţēŕś\"],\"4yQF++\":[\"Ćũśţōḿ śĥōŵ ƥŕōĝŕàḿś àŕē ĝŕōũƥēď ƀŷ ţĥēĩŕ ƥàŕēńţ śĥōŵ\"],\"50whWJ\":[\"XḾĹŢV Ĺĩńķ:\"],\"53/4tH\":[\"Àũďĩō Ōƥţĩōńś\"],\"536Xwe\":[\"Ēŕŕōŕ ćōƥŷĩńĝ ţō ćĺĩƥƀōàŕď!\"],\"53tfay\":[\"Ţĥĩś àĺĺōŵś ţō śćĥēďũĺē śƥēćĩƒĩć śĥōŵś ţō ŕũń àţ śƥēćĩƒĩć ţĩḿē śĺōţś ōƒ ţĥē ďàŷ ōŕ à ŵēēķ. Ĩţ'ś ŕēćōḿḿēńďēď ŷōũ ƒĩŕśţ ƥōƥũĺàţē ţĥē ćĥàńńēĺ ŵĩţĥ ţĥē ēƥĩśōďēś ƒŕōḿ ţĥē śĥōŵś ŷōũ ŵàńţ ţō ƥĺàŷ àńď/ōŕ ōţĥēŕ ćōńţēńţ ĺĩķē ḿōvĩēś àńď ŕēďĩŕēćţś.\"],\"5ABghp\":[\"ƑƑḿƥēĝ Śēţţĩńĝś\"],\"5V93hk\":[\"Śćĥēďũĺē ƥŕōĝŕàḿḿĩńĝ ũśĩńĝ śĺōţś àśśĩĝńēď à śţàŕţ ţĩḿē àńď ďũŕàţĩōń.\"],\"5WeWGz\":[\"Śēĺēćţēď Śũƀţĩţĺē\"],\"5k0NLb\":[\"Ŕēvĩēŵ\"],\"5lSgNP\":[\"Ēńàƀĺē ŚŚĎƤ śēŕvēŕ\"],\"5nsbxB\":[\"Àĺţēŕńàţēś ŢV śĥōŵś ĩń ƀĺōćķś ōƒ ēƥĩśōďēś. Ŷōũ ćàń ƥĩćķ ţĥē ńũḿƀēŕ ōƒ ēƥĩśōďēś ƥēŕ śĥōŵ ĩń ēàćĥ ƀĺōćķ àńď ĩƒ ţĥē ōŕďēŕ ōƒ śĥōŵś ĩń ēàćĥ ƀĺōćķ śĥōũĺď ƀē ŕàńďōḿĩźēď. Ḿōvĩēś àŕē ḿōvēď ţō ţĥē ƀōţţōḿ.\"],\"5qV3NN\":[\"Ƒĺēx Śţŷĺē\"],\"5yIPLp\":[\"Ōōƥś!\"],\"6/dCYd\":[\"Ōvēŕvĩēŵ\"],\"63/DSM\":[\"Ţŕàńśćōďĩńĝ Ćōńƒĩĝś\"],\"63driG\":[\"Śţŕēàḿ ĵŚŌŃ\"],\"67RoFa\":[\"Ƥĩƥēĺĩńē\"],\"6Y9c2m\":[\"Ţĥĩś śĺōţ ĩś ĺĩńķēď ŵĩţĥ \",[\"0\"],\" ōţĥēŕ śĺōţ(ś). Ćōńţēńţ ƒĩēĺďś àŕē śĥàŕēď àćŕōśś ţĥē ĝŕōũƥ.\"],\"6YtxFj\":[\"Ńàḿē\"],\"6ZMWKw\":[\"XḾĹŢV\"],\"6bbWRs\":[\"Àďď ƥŕōĝŕàḿḿĩńĝ ţō ćũśţōḿ śĥōŵ\"],\"6dvIbw\":[\"Ũńĺĩńķ\"],\"6jAi8c\":[\"Ŕàńĝē\"],\"6jfS51\":[\"Ŵēĺćōḿē\"],\"6ki7F2\":[[\"0\",\"plural\",{\"one\":[\"#\",\" ĩţēḿ\"],\"other\":[\"#\",\" ĩţēḿś\"]}]],\"6mJ9tF\":[\"ƑƑḾƤĒĜ ĩś ńōţ ďēţēćţēď.\"],\"6mpwdR\":[\"Ḿàţćĥ àĺĺ ōƒ\"],\"6pL6be\":[\"Ćōńƒĩĝũŕē ŵĥàţ àƥƥēàŕś ōń ŷōũŕ ćĥàńńēĺ ŵĥēń ţĥēŕē ĩś ńō śũĩţàƀĺē ƒĩĺĺēŕ ćōńţēńţ àvàĩĺàƀĺē. Ũśĩńĝ ćĥàńńēĺ ƒàĺĺƀàćķś ŕēǫũĩŕēś ƒƒḿƥēĝ ţŕàńśćōďĩńĝ.\"],\"6w0yiE\":[\"ƑƑḾƤĒĜ Ĺōĝ Ĺēvēĺ\"],\"6zfUar\":[\"Śţŕēàḿ Śēĺēćţĩōń\"],\"71O7b0\":[\"Ḿēďĩà Ĩńƒō\"],\"73XwX0\":[\"Ńō ƥŕōĝŕàḿś śēĺēćţēď\"],\"73flfT\":[\"ǪŚV Ďēvĩćē\"],\"7B3lfh\":[\"Ĩţēḿś ƒŕōḿ àńŷ ƒĩĺĺēŕ ĺĩśţ ŵĩĺĺ ńōţ ƀē ćĥōśēń ḿōŕē ƒŕēǫũēńţĺŷ ţĥàń ţĥĩś ćōōĺďōŵń śēţţĩńĝ.\"],\"7LWPgS\":[\"Ēńàƀĺēď (ĺōũďńōŕḿ)\"],\"7ODkf5\":[\"Ĺōĝ ĺēvēĺ ţō ƥàśś ţō ƒƒḿƥēĝ. Ŕēàď ḿōŕē àƀōũţ ƒƒḿƥēĝ'ś ĺōĝ ĺēvēĺś <0>ĥēŕē\"],\"7Q5AKf\":[[\"count\",\"plural\",{\"one\":[\"ţŕàćķ\"],\"other\":[\"ţŕàćķś\"]}]],\"7b2stB\":[\"Ḿēďĩà Ţŷƥē\"],\"7eMo+U\":[\"Ĝō Ĥōḿē\"],\"7eZlTH\":[\"Śōŕţ ŢV Śĥōŵś (àść)\"],\"7iJlKU\":[\"Ƥĺēàśē ćĥōōśē à vàĺũē ĝŕēàţēŕ ţĥàń 1\"],\"7pMNGK\":[\"Ƥŕōĝŕàḿś śàvēď!\"],\"7sNhEz\":[\"Ũśēŕńàḿē\"],\"7tvV2B\":[\"Ḿĩń Ďũŕàţĩōń (ḿĩńũţēś)\"],\"7uohY3\":[\"ŢV śĥōŵś àŕē ĝŕōũƥēď ƀŷ śĥōŵ\"],\"80t7Ii\":[\"Ĩńćŕēàśĩńĝ \\\"Ḿàx Ĺàţēńēśś\\\" ƒōŕ ţĥē śćĥēďũĺē.\"],\"87a/t/\":[\"Ĺàƀēĺ\"],\"8E9KXK\":[\"Ƒēàţũŕē ƒĺàĝś śàvēď!\"],\"8MIU1T\":[\"Ƥŕōĝŕàḿ\"],\"8TMaZI\":[\"Ţĩḿēśţàḿƥ\"],\"8ZsakT\":[\"Ƥàśśŵōŕď\"],\"8vETh9\":[\"Śĥōŵ\"],\"8wngZM\":[\"Ƒàĺĺƀàćķ\"],\"8wu9lr\":[\"Ǫũēũēď\"],\"9+90+V\":[\"Ēńàƀĺē Ĺōĝ Ƒĩĺē Ŕōĺĺĩńĝ\"],\"94qSvE\":[\"Śŷńćēď ŵĩţĥ ēxţēŕńàĺ ƥĺàŷĺĩśţ\"],\"96zw7M\":[\"Ţĥĩś śĥōŵ ĩś ḿàŕķēď àś ḿĩśśĩńĝ ĩń ţĥē ďàţàƀàśē.\"],\"983IRa\":[\"Àĺĺ ĺĩńķēď śĺōţś śĥōŵ ţĥē śàḿē ēƥĩśōďē, àďvàńćĩńĝ ōńĺŷ àƒţēŕ àĺĺ ĥàvē ƥĺàŷēď.\"],\"9E+eyD\":[\"Ōũţƥũţ vĩďēō àţ à ćōńśţàńţ ƒŕàḿē ŕàţē.\"],\"9E9tRC\":[\"Ƒĩĺĺ ŵĩţĥ Ƒĺēx\"],\"9Eq43e\":[\"Ĩƒ śēţ, àĺĺ ŵàţēŕḿàŕķ ōvēŕĺàŷś ŵĩĺĺ ƀē ďĩśàƀĺēď ƒōŕ ćĥàńńēĺś àśśĩĝńēď ţĥĩś ţŕàńśćōďē ćōńƒĩĝ.\"],\"9GPYnX\":[\"Ďō ńōţ ĝŕōũƥ ƥŕōĝŕàḿś àţ àĺĺ. Ńōŕḿàĺ śĥũƒƒĺē.\"],\"9WG5wy\":[\"Śƥēćĩàĺś\"],\"9asVsi\":[\"Ĥōŵ ĺōńĝ ēàćĥ ćōḿḿēŕćĩàĺ ƀŕēàķ ĺàśţś\"],\"9qdNKR\":[\"Ēŕŕōŕ Ōƥţĩōńś\"],\"9sqrEU\":[\"Ƒĩĺĺēŕ Ĺĩśţ\"],\"9td1Wl\":[\"Ćĥēćķ\"],\"9vtG84\":[\" Śćĥēďũĺĩńĝ Śţŕàţēĝŷ\"],\"A+GCyx\":[\"Ĥĩďē Àďvàńćēď\"],\"A0+T6c\":[\"Ŕēśēţ Ćĥàńĝēś\"],\"A1taO8\":[\"Śēàŕćĥ\"],\"A7WmPm\":[\"Ńēŵ Ƥĺēx Śēŕvēŕ\"],\"A9Rhec\":[\"Ćĥàńńēĺ Ńàḿē\"],\"ACKu03\":[\"Ŕēƒŕēśĥ Ƥŕēvĩēŵ\"],\"AKjNTL\":[\"Àďď Ƥàďďĩńĝ\"],\"AM972O\":[\"Àďď Ŕēďĩŕēćţ\"],\"ANICN0\":[\"Ńō ḿēďĩà śōũŕćēś ćōńńēćţēď.\"],\"AO2Z5d\":[\"Ḿōvĩē, \",[\"0\"]],\"AOHgZp\":[\"Ēƥĩśōďēś\"],\"AVKoQM\":[\"Ŕēďĩŕēćţ ţō \\\"\",[\"0\"],\"\\\"\"],\"AXg7m0\":[\"Śēàŕćĥ ĩś ćũŕŕēńţĺŷ śćōƥēď ţō ţĥĩś Ḿēďĩà Śōũŕćē.\"],\"AXjA78\":[\"Ƒĩēĺď\"],\"AdfhAd\":[\"Ĩƒ ţĥēŕē àŕē ĩśśũēś ƥĺàŷĩńĝ à vĩďēō, Ţũńàŕŕ ŵĩĺĺ ţŕŷ ţō ũśē àń ēŕŕōŕ śćŕēēń àś à ƥĺàćēĥōĺďēŕ ŵĥĩĺē ŕēţŕŷĩńĝ ĺōàďĩńĝ ţĥē vĩďēō ēvēŕŷ 60 śēćōńďś.\"],\"AdogaJ\":[\"Ƥĩƥēĺĩńē Śţēƥś\"],\"AlfqgK\":[\"Ŵàţćĥ\"],\"ApsQAb\":[\"ĤĎĤŔ: Ĺōàďĩńĝ...\"],\"AyInY5\":[\"Vĩďēō Ōƥţĩōńś\"],\"AzCYkg\":[\"Ćōńńēćţ Ḿēďĩà Śōũŕćēś\"],\"B+HsXP\":[\"ƑƑḾƤĒĜ: \",[\"0\"]],\"B1NOvD\":[\"Ŕēḿōvēś àĺĺ ƥŕōĝŕàḿś ƒŕōḿ śćĥēďũĺē\"],\"B1W8vw\":[\"Ďēĺēţē \\\"\",[\"0\"],\"\\\"\"],\"BGHH1t\":[\"Ḿĩń. Vĩśĩƀĺē ĩń Ĝũĩďē Ďũŕàţĩōń Ƥŕōĝŕàḿ (śēćōńďś)\"],\"BJjJuo\":[\"ĒƤĜ (Ĥōũŕś)\"],\"BMlGCC\":[\"Ćĺĩćķ ţō ƥŕēvĩēŵ ţĥē ĩţēḿś ĩń ţĥĩś Ćũśţōḿ Śĥōŵ. Ńōţē ţĥàţ ōńĺŷ ţĥē ŵĥōĺē śĥōŵ ćàń ƀē àďďēď àţ ōńćē.\"],\"BQsifH\":[\"Śţŕēàḿ Ĩńƒō\"],\"BWTzAb\":[\"Ḿàńũàĺ\"],\"BXXjCD\":[\"ƑƑḿƥēĝ ńōţ ƒōũńď. Ƒōŕ àĺĺ ƒēàţũŕēś ţō ŵōŕķ, ŵē ŕēćōḿḿēńď ĩńśţàĺĺĩńĝ ƑƑḿƥēĝ 7.1+ ōŕ ũƥďàţē ŷōũŕ ƑƑḿƥēĝ ēxēćũţàƀĺē ƥàţĥ ĩń śēţţĩńĝś.\"],\"BaUuhR\":[\"Ćōďēć\"],\"BlmmxH\":[\"ƑƑḿƥēĝ Ĺōĝ\"],\"Bq0ryo\":[\"Ŕēśēţ Ōƥţĩōńś\"],\"BtL93c\":[[\"0\",\"plural\",{\"one\":[\"#\",\" śōũŕćē ćōńńēćţēď.\"],\"other\":[\"#\",\" śōũŕćēś ćōńńēćţēď.\"]}]],\"C4KL42\":[\"Ćōńśōĺĩďàţēś ćōńţĩĝũōũś ḿàţćĥ ƒĺēx àńď ŕēďĩŕēćţ ƀĺōćķś ĩńţō śĩńĝũĺàŕ śƥàńś\"],\"C6jEO3\":[\"Ĺōĝ Ĺēvēĺ\"],\"CAiikc\":[\"Ēńţēŕ ŷōũŕ ĵēĺĺŷƒĩń ƥàśśŵōŕď ţō ĝēńēŕàţē à ńēŵ àććēśś ţōķēń.<0/><1>ŃŌŢĒ: Ţĥēśē àŕē ńēvēŕ śàvēď ţō ţĥē Ţũńàŕŕ Ďß. Ĩńśţēàď ţĥēŷ àŕē śēńţ ţō ĵēĺĺŷƒĩń ţō ēxćĥàńĝē ƒōŕ à śēśśĩōń ţōķēń.\"],\"CJkEfx\":[\"ßĺōćķ\"],\"CKQ3t3\":[\"Ţōţàĺ Ŕũńţĩḿē\"],\"CMQ09J\":[\"Śćàńńĩńĝ\"],\"COv7As\":[\"Ćōōĺďōŵń (śēćōńďś)\"],\"CRsuq4\":[\"Ēvēŕŷ\"],\"CVqySE\":[[\"len\",\"plural\",{\"one\":[\"Ţĥēŕē ĩś \",\"#\",\" ŵàŕńĩńĝ. Ćĺĩćķ ƒōŕ ďēţàĩĺś.\"],\"other\":[\"Ţĥēŕē àŕē \",\"#\",\" ŵàŕńĩńĝś. Ćĺĩćķ ƒōŕ ďēţàĩĺś.\"]}]],\"CWRFGq\":[\"Ḿōďĩƒŷ Ƥŕōĝŕàḿḿĩńĝ\"],\"CXDHcv\":[\"Ĝŕĩď\"],\"CcX8VV\":[\"Ćōḿƥĺēţēĺŷ ŕàńďōḿĩźēś ţĥē ōŕďēŕ ōƒ ƥŕōĝŕàḿś.\"],\"CeyB7O\":[\"ƑƑḿƥēĝ Ēxēćũţàƀĺē Ƥàţĥ\"],\"CfOWar\":[\"Ĺōĝàŕĩţĥḿĩć ďēćàŷ, ĺĩĝĥţēŕ ŵēĩĝĥţĩńĝ.\"],\"CfUvtM\":[\"Ēŕŕōŕ śàvĩńĝ ńēŵ Śḿàŕţ Ćōĺĺēćţĩōń. Ćĥēćķ śēŕvēŕ ĺōĝś àńď ƀŕōŵśēŕ ćōńśōĺē ƒōŕ ďēţàĩĺś.\"],\"CfxLtO\":[\"Ƥŕōĝŕàḿ ĵŚŌŃ\"],\"Cko536\":[\"Ďēśćēńďĩńĝ\"],\"Cp5Awv\":[\"Ďũŕàţĩōń ḿũśţ ƀē ĝŕēàţēŕ ţĥàń 0.\"],\"CqSP2T\":[\"Ēďĩţ Ćĥàńńēĺ Ŕēďĩŕēćţ\"],\"CsrDsg\":[\"12-ĥōũŕ\"],\"Cxqf0C\":[\"Ƥĺēx (Àũţō)\"],\"D+NlUC\":[\"Śŷśţēḿ\"],\"D1Fhv3\":[[\"count\",\"plural\",{\"one\":[\"ēƥĩśōďē\"],\"other\":[\"ēƥĩśōďēś\"]}]],\"DPfwMq\":[\"Ďōńē\"],\"DRya1t\":[\"Àũďĩō Vōĺũḿē\"],\"DSwJ9W\":[\"Ēńàƀĺē Àńĩḿàţĩōń\"],\"DUd3Ss\":[\"Śōŕţś ţĥē ĺĩśţ ƀŷ ŢV Śĥōŵ àńď ţĥē ēƥĩśōďēś ĩń ēàćĥ ŢV śĥōŵ ƀŷ ţĥēĩŕ śēàśōń/ēƥĩśōďē ńũḿƀēŕ. Ḿōvĩēś àŕē ḿōvēď ţō ţĥē ƀōţţōḿ ōƒ ţĥē śćĥēďũĺē.\"],\"DbouLP\":[\"ßàćķ ţō Ƥŕōĝŕàḿḿĩńĝ\"],\"Dd9orS\":[\"Ŕēḿōvē Àĺĺ \",[\"movieCount\"],\" \",[\"movieCount\",\"plural\",{\"one\":[\"Ḿōvĩē\"],\"other\":[\"Ḿōvĩēś\"]}]],\"Dnn2XG\":[\"Àũţōḿàţĩć\"],\"DoJzLz\":[\"Ćōĺĺēćţĩōńś\"],\"DxvGLB\":[\"Àďď Śĺōţ\"],\"E/QGRL\":[\"Ďĩśàƀĺēď\"],\"E5ipHC\":[\"ßàĺàńćē ßŷ:\"],\"E8oclZ\":[\"Ćōƥĩēď Ćĥàńńēĺ ĨĎ!\"],\"EKlukx\":[\"Ćōƥŷ Ƒũĺĺ Ŕēƥōŕţ\"],\"EL4/HD\":[[\"0\",\"plural\",{\"one\":[\"ƥŕōĝŕàḿ\"],\"other\":[\"ƥŕōĝŕàḿś\"]}]],\"EdQY6l\":[\"Ńōńē\"],\"EkH9pt\":[\"Ũƥďàţē\"],\"Etie0Q\":[\"Àĺĺ ćĥàńńēĺś àśśĩĝńēď ţō ţĥĩś ćōńƒĩĝ ŵĩĺĺ ƀē śēţ ţō ũśē ţĥē ďēƒàũĺţ ćōńƒĩĝũŕàţĩōń. Ĩƒ ţĥĩś ĩś ţĥē ĺàśţ ćōńƒĩĝũŕàţĩōń, à ńēŵ ďēƒàũĺţ ćōńƒĩĝũŕàţĩōń ŵĩĺĺ ƀē ćŕēàţēď.\"],\"Eu20Os\":[\"Ţĩḿē Śĺōţś\"],\"Ev2r9A\":[\"Ńō ŕēśũĺţś\"],\"F1l877\":[\"Śũƀţĩţĺē Śţŕēàḿś\"],\"F3bW6y\":[\"Ƥĺàţƒōŕḿ\"],\"F3smBd\":[\"Ḿàxĩḿũḿ ńũḿƀēŕ ōƒ ďàŷś ţō ƥŕēćàĺćũĺàţē ţĥē śćĥēďũĺē. Ńōţē ţĥàţ ţĥē ĺēńĝţĥ ōƒ ţĥē śćĥēďũĺē ĩś àĺśō ƀōũńďēď ƀŷ ţĥē ḿàxĩḿũḿ ńũḿƀēŕ ōƒ ƥŕōĝŕàḿś àĺĺōŵēď ĩń à ćĥàńńēĺ.<0/><1>Ńōţē: Ƥŕēvĩēŵĩńĝ ţĥē śćĥēďũĺē ĩń ţĥē ƀŕōŵśēŕ ƒōŕ ĺōńĝ ĺēńĝţĥś ōƒ ţĩḿē ćàń ćàũśē ŨĨ ƥēŕƒōŕḿàńćē ĩśśũēś\"],\"FDEfoy\":[\"Ďēĺēţĩńĝ à ḿēďĩà śōũŕćē ŵĩĺĺ ŕēḿōvē àĺĺ ōƒ ĩţś àśśōćĩàţēď ƥŕōĝŕàḿś ƒŕōḿ Ţũńàŕŕ.\"],\"FXCwT9\":[\"ƑƑƥŕōƀē Ēxēćũţàƀĺē Ƥàţĥ\"],\"FZg3wM\":[\"Ōƥēŕàţĩōń\"],\"FmN5me\":[\"Ŕēśōĺũţĩōń\"],\"FnChN1\":[\"Ēńàƀĺē <0>ĒßŨ Ŕ 128 ĺōũďńēśś ńōŕḿàĺĩźàţĩōń vĩà ţĥē <1>ĺōũďńōŕḿ ƑƑḿƥēĝ ƒĩĺţēŕ. Ḿàŷ ĩńćŕēàśē ĆƤŨ ũśàĝē ďũŕĩńĝ śţŕēàḿĩńĝ.\"],\"Fp7p73\":[\"Ţĩḿē ƀēţŵēēń śũƀśēǫũēńţ ƀŕēàķś\"],\"FqCHF/\":[\"Ţĥŕēàďś\"],\"FrRP21\":[\"Ţĥēŕē ŵàś àń ēŕŕōŕ ŵĥēń śũƀḿĩţţĩńĝ ţĥē ƒōŕḿ. Ƥĺēàśē śēē ćōńśōĺē ĺōĝś ƒōŕ ďēţàĩĺś.\"],\"FsF4bb\":[\"Àũďĩō Ĺōũďńēśś Ńōŕḿàĺĩźàţĩōń\"],\"FssFce\":[\"Ćōńƒĩĝũŕē ƥŕēƒēŕŕēď àũďĩō ĺàńĝũàĝēś ĝĺōƀàĺĺŷ.\"],\"Fzn/BQ\":[\"Ŕēĺēàśē Ďàţē\"],\"G+8qH5\":[\"Ćĥàńńēĺ ńàḿē ĩś ŕēǫũĩŕēď\"],\"GDKKxT\":[\"Àććēśś Ţōķēń\"],\"GHOK4Z\":[\"Ţĩḿē Ƒōŕḿàţ\"],\"GJ1P5j\":[\"Ƒĩĺē à ßũĝ Ŕēƥōŕţ\"],\"GKLqtE\":[\"Śēţ ţĥē ĥōśţ ōƒ ŷōũŕ Ţũńàŕŕ ƀàćķēńď. Ŵĥēń ēḿƥţŷ, ţĥē ŵēƀ ŨĨ ŵĩĺĺ ũśē ţĥē ćũŕŕēńţ ĥōśţ/ƥōŕţ ţō ćōḿḿũńĩćàţē ŵĩţĥ ţĥē ƀàćķēńď.\"],\"GLOZdc\":[\"Ćũśţōḿ Śĥōŵś\"],\"GP/CFo\":[\"ĤŴ Àććēĺ\"],\"GQ3O42\":[\"Ţŕàśĥ\"],\"GRCrpV\":[\"Ḿàńàĝē Ĺĩƀŕàŕĩēś\"],\"GUtCZC\":[\"Vēŕśĩōń: \",[\"0\"]],\"GhZ4GX\":[\"Ēŕŕōŕ ŵĥĩĺē ćōƥŷĩńĝ ţō ćĺĩƥƀōàŕď. Ćĥēćķ ƀŕōŵśēŕ ĺōĝś ƒōŕ ďēţàĩĺś\"],\"GmP0oY\":[\"Śĺōţ Ŵàŕńĩńĝś\"],\"GmTnBN\":[\"Ēńàƀĺē ƒƒḿƥēĝ ĺōĝĝĩńĝ ţō ďĩƒƒēŕēńţ śĩńķś. Ōũţƥũţţĩńĝ ţō à ƒĩĺē ŵĩĺĺ ćŕēàţē à ńēŵ ĺōĝ ƒĩĺē ƒōŕ ēvēŕŷ śƥàŵńēď ƒƒḿƥēĝ ƥŕōćēśś ĩń ţĥē Ţũńàŕŕ ĺōĝ ďĩŕēćţōŕŷ. Ţĥēśē ƒĩĺēś àŕē àũţōḿàţĩćàĺĺŷ ćĺēàńēď ũƥ ƀŷ à ƀàćķĝŕōũńď ƥŕōćēśś.\"],\"Gr1Ik2\":[\"Ńvĩďĩà Ćàƥàƀĩĺĩţĩēś\"],\"GtycJ/\":[\"Ţàśķś\"],\"GzzMwi\":[\"Ŕōĺĺ ōń Śćĥēďũĺē\"],\"H0QGc9\":[\"Ƒĩĺĺēŕ Ĺĩśţ Ćōōĺďōŵń (śēćōńďś)\"],\"H1OFlu\":[\"Ĩńvēŕśē ĺĩńēàŕ ďēćàŷ, ĥēàvĩēŕ ŵēĩĝĥţĩńĝ.\"],\"H1V+2G\":[\"Ţō ũśē Ţũńàŕŕ, ŷōũ ḿũśţ ƒĩŕśţ ćōńńēćţ àţ ĺēàśţ ōńē ḿēďĩà śōũŕćē. Ḿēďĩà śōũŕćēś ƥŕōvĩďē àĺĺ ćōńţēńţ ũśēď ţō ćŕēàţē ćĥàńńēĺś ĩń Ţũńàŕŕ. Ƥĺēx àńď ĵēĺĺŷƒĩń àŕē ćũŕŕēńţĺŷ śũƥƥōŕţēď.\"],\"H3OF1s\":[\"Ţũńēŕ Ćōũńţ\"],\"H7OUPr\":[\"Ďàŷ\"],\"H8100o\":[\"Ƒĩĺĺēŕ ĺĩśţś àŕē ćōĺĺēćţĩōńś ōƒ vĩďēōś ţĥàţ ŷōũ ḿàŷ ŵàńţ ţō ƥĺàŷ ďũŕĩńĝ 'ƒĺēx' ţĩḿē śēĝḿēńţś. Ƒĺēx ĩś ţĩḿē ŵĩţĥĩń à ćĥàńńēĺ ţĥàţ ďōēś ńōţ ĥàvē à ƥŕōĝŕàḿ śćĥēďũĺēď (ũśũàĺĺŷ ũśēď ƒōŕ ƥàďďĩńĝ).\"],\"HDoQBx\":[\"Ćĥàńńēĺ śēţţĩńĝś śàvēď!\"],\"HEH0PR\":[\"Ḿũśţ ďēƒĩńē àţ ĺēàśţ ōńē ĺàńĝũàĝē ƥŕēƒēŕēńćē\"],\"HErtdg\":[\"Ńàḿē ćàń ōńĺŷ ćōńţàĩń àĺƥĥàńũḿēŕĩć ćĥàŕàćţēŕś, ďàśĥēś, àńď ũńďēŕśćōŕēś\"],\"HLlLPP\":[\"Ćĥàńńēĺ Śţŕēàḿ Ḿōďē\"],\"HMWEIt\":[\"Ēďĩţ Ƒĺēx Ţĩḿē\"],\"HOLbdk\":[\"Ƒàĩĺēď ţō ĺōàď śţŕēàḿ ďēţàĩĺś! Ćĥēćķ ĺōĝś ƒōŕ ďēţàĩĺś\"],\"HSfauP\":[\"Ţĥĩś śĺōţ ĩś ĺĩńķēď ŵĩţĥ \",[\"0\"],\" ōţĥēŕ \",[\"1\",\"plural\",{\"one\":[\"śĺōţ\"],\"other\":[\"śĺōţś\"]}],\". Ćōńţēńţ ƒĩēĺďś àŕē śĥàŕēď àćŕōśś ţĥē ĝŕōũƥ.\"],\"HVpg3x\":[\"Ƒàĩĺēď ţō ĺōàď Śḿàŕţ Ćōĺĺēćţĩōń\"],\"HXx+vU\":[\"Ćōńţŕōĺś ŵĥàţ ĥàƥƥēńś ŵĥēń ţĥĩś śĺōţ ŕũńś ōũţ ōƒ ŕēƥĺàŷēď ćōńţēńţ ƒŕōḿ ēàŕĺĩēŕ ćōńţĩńũē śĺōţś.\"],\"HYCPKT\":[\"Àďď Śēĺēćţēď Ḿēďĩà\"],\"HajiZl\":[\"Ḿōńţĥ\"],\"HdE1If\":[\"Ćĥàńńēĺ\"],\"Hjfx9G\":[\"Àũďĩō & Śũƀţĩţĺēś\"],\"HmHwcC\":[\"Ƒĩxēď Ĩńţēŕvàĺ\"],\"HptUxX\":[\"Ńũḿƀēŕ\"],\"HqUilK\":[\"Ķēŷŵōŕďś ƥēŕƒōŕḿ ƒũĺĺ ţēxţ śēàŕćĥ àćŕōśś àĺĺ (ōŕ ćōńƒĩĝũŕēď) ƒĩēĺďś\"],\"HzV8B2\":[\"Śķĩƥ ḿĩď-ŕōĺĺ ƒōŕ ƥŕōĝŕàḿś śĥōŕţēŕ ţĥàń ţĥĩś\"],\"I+FvbD\":[\"Śćàń\"],\"I2Bar3\":[\"Śĥōŵś\"],\"I5BU70\":[\"Śḿàŕţ Ćōĺĺēćţĩōń: \",[\"0\"]],\"I6gXOa\":[\"Ƥàţĥ\"],\"IDlmXg\":[\"Ţũńàŕŕ ßàćķēńď ŨŔĹ:\"],\"IFiQdD\":[\"Ćĥàńńēĺś Ḿ3Ũ Ĺĩńķ:\"],\"IMxI++\":[\"Ńōţ à vàĺĩď ŨŔĹ\"],\"INCbO6\":[\"Ōń-Ďēḿàńď ćĥàńńēĺś ŕēśũḿē ƒŕōḿ ŵĥēŕē ŷōũ ĺēƒţ ōƒƒ. Ƥŕōĝŕàḿḿĩńĝ ĩś ƥàũśēď ŵĥēń ţĥē ćĥàńńēĺ ĩś ńōţ śţŕēàḿĩńĝ.<0/><1>ŃŌŢĒ: Ŵĥĩĺē ţĥē ćĥàńńēĺ ĩś ĩńàćţĩvē, ţĥē ŢV Ĝũĩďē ƒōŕ ţĥē ćĥàńńēĺ ŵĩĺĺ ƀē ēḿƥţŷ.\"],\"IagCbF\":[\"ŨŔĹ\"],\"IetKlB\":[\"Ńēŵ Ćũśţōḿ Śĥōŵ\"],\"IgC1fP\":[\"Ēńàƀĺē ĺĩĝĥţ Ḿōďē\"],\"IiBgkW\":[\"Ƒàĩĺēď ţō ũƥďàţē Ḿēďĩà Śōũŕćē śēţţĩńĝś. Ƥĺēàśē ćĥēćķ śēŕvēŕ àńď ƀŕōŵśēŕ ĺōĝś ƒōŕ ďēţàĩĺś.\"],\"IoSxk9\":[\"Ƥŕōţōćōĺ ḿũśţ ƀē ĤŢŢƤ ōŕ ĤŢŢƤŚ\"],\"IvkbIT\":[\"Ŕēàď Ḿōŕē\"],\"J/eF78\":[\"Ŕēḿōvĩńĝ ōvēŕŕũń ƥŕōĝŕàḿś ƒŕōḿ ţĥē ćĥàńńēĺ.\"],\"J0NKO1\":[\"Ēxćĺũďē Śēàśōńś\"],\"J2eKUI\":[\"Ƒĩĺē\"],\"J2lnQW\":[\"Ƥŕē\"],\"J41wt0\":[\"Śĺōţ Ēďĩţōŕ\"],\"J4Ngmi\":[\"Ĺōōƥ Śĥōŕţ Ƥŕōĝŕàḿś\"],\"J50/e4\":[\"Ƒĩĺţēŕ Ţŷƥē\"],\"J8X80J\":[\"Śţēàĺţĥ?\"],\"JCGCcQ\":[\"Śōŕţś ēvēŕŷţĥĩńĝ ƀŷ ĩţś ŕēĺēàśē ďàţē. Ţĥĩś ŵĩĺĺ ōńĺŷ ŵōŕķ ćōŕŕēćţĺŷ ĩƒ ţĥē ŕēĺēàśē ďàţēś ĩń Ƥĺēx àŕē ćōŕŕēćţ. Ĩń ćàśē àńŷ ĩţēḿ ďōēś ńōţ ĥàvē à ŕēĺēàśē ďàţē śƥēćĩƒĩēď, ĩţ ŵĩĺĺ ƀē ḿōvēď ţō ţĥē ƀōţţōḿ.\"],\"JCOZTc\":[\"Àũďĩō & Śũƀţĩţĺē Ōƥţĩōńś\"],\"JOFDLs\":[\"Ƥŕōĝŕàḿ Ƥĺàŷƀàćķ Ţŕōũƀĺēśĥōōţēŕ\"],\"JeAvlS\":[\"Ƥàď Ţĩḿēś\"],\"JeL1O4\":[\"Ŕēďĩŕēćţ ďũŕàţĩōń\"],\"Jj3SJk\":[\"À-Ź (àść)\"],\"JmZ/+d\":[\"Ƒĩńĩśĥ\"],\"Jpe9a8\":[\"Àţţēḿƥţś ţō ƀàĺàńćē ƥŕōĝŕàḿḿĩńĝ ĝŕōũƥś ƀŷ ēĩţĥēŕ ţōţàĺ ĺĩńēũƥ ďũŕàţĩōń ōŕ ńũḿƀēŕ ōƒ ũńĩǫũē ƥŕōĝŕàḿś. Ƒōŕ ĩńśţàńćē, ƒōŕ à ćĥàńńēĺ ŵĩţĥ ḿàńŷ śēàśōńś ōƒ ōńē śĥōŵ àńď ƒēŵ śēàśōńś ōƒ àńōţĥēŕ, ƀàĺàńćĩńĝ ŵĩĺĺ àţţēḿƥţ ţō ćŕēàţē àń ēvēń ḿĩx ōƒ ƀōţĥ śĥōŵś ƀŷ ĩńśēŕţĩńĝ ŕēƥēàţś ōƒ ţĥē śĥōŵ ŵĩţĥ ƒēŵēŕ ēƥĩśōďēś.\"],\"JryIGL\":[\"ÀďĴũśţ Ŵēĩĝĥţś\"],\"Jsel0T\":[\"Ţĥĩś ćĥàńńēĺ ĥàś àń ēxĩśţĩńĝ ţĩḿē śĺōţ śćĥēďũĺē. À ćĥàńńēĺ ćàń ōńĺŷ ũśē ōńē śćĥēďũĺĩńĝ ţŷƥē àţ à ţĩḿē. Śàvĩńĝ à śćĥēďũĺē ĥēŕē ŵĩĺĺ ŕēḿōvē ţĥē ēxĩśţĩńĝ ţĩḿē śĺōţ śćĥēďũĺē.\"],\"Jtbzxr\":[\"Vēŕśĩōń: ũńķńōŵń\"],\"JxE+Bh\":[\"Àĺĺōŵś ŷōũ ţō ƥĩćķ śƥēćĩƒĩć ƥŕōĝŕàḿḿĩńĝ ţō ŕēḿōvē ƒŕōḿ ţĥē ćĥàńńēĺ.\"],\"JyHA6G\":[\"Ďĩśƥĺàŷś ţĥē ĺàśţ \",[\"0\"],\" śŷśţēḿ ĺōĝ ēvēńţś. Ũśē ţĥē ƀũţţōńś ƀēĺōŵ ţō ēxƥōŕţ ţĥēśē ĺōĝś ōŕ ďōŵńĺōàď ţĥē ēńţĩŕē ĺōĝ ƒĩĺē ƒōŕ ďēƀũĝĝĩńĝ.\"],\"JzJk+4\":[\"Àďď Ĺàńĝũàĝē Ƥŕēƒēŕēńćē\"],\"K09nyY\":[\"Ĺĩńķēď śĺōţś àďvàńćē ēƥĩśōďē ƥŕōĝŕēśśĩōń ţōĝēţĥēŕ śēǫũēńţĩàĺĺŷ.\"],\"K8+dbZ\":[[\"totalConnections\"],\" ţōţàĺ\"],\"K9pQ8Q\":[\"Ďĩśàƀĺē Ŵàţēŕḿàŕķś\"],\"KRjDf4\":[\"Àũďĩō Śţŕēàḿś\"],\"Khe/Vb\":[\"Ŵàţćĥ Ćĥàńńēĺ\"],\"KkOthv\":[\"Ĝũĩďē\"],\"Km5fSd\":[\"Ĩƒ ŷōũ àŕē ćōńƒĩďēńţ ƑƑḾƤĒĜ ĩś ĩńśţàĺĺēď, ŷōũ ḿàŷ Ĵũśţ ńēēď ţō ũƥďàţē ţĥē ēxēćũţàƀĺē ƥàţĥ ĩń ţĥē śēţţĩńĝś. Ţō ďō śō, śĩḿƥĺŷ ćĺĩćķ Ēďĩţ àƀōvē ţō ũƥďàţē ţĥē ƥàţĥ.\"],\"L+8pV5\":[\"Śŷńć ŵĩţĥ ēxţēŕńàĺ ƥĺàŷĺĩśţ\"],\"L/KmPM\":[\"Ũśũàĺĺŷ śĺōţś ńēēď ţō àďď ƒĺēx ţĩḿē ţō ēńśũŕē ţĥàţ ţĥē ńēxţ śĺōţ śţàŕţś àţ ţĥē ćōŕŕēćţ ţĩḿē. Ŵĥēń ţĥēŕē àŕē ḿũĺţĩƥĺē vĩďēōś ĩń ţĥē śĺōţ, ŷōũ ḿĩĝĥţ ƥŕēƒēŕ ţō ďĩśţŕĩƀũţē ţĥē ƒĺēx ţĩḿē ƀēţŵēēń ţĥē vĩďēōś ōŕ ţō ƥĺàćē ḿōśţ ōƒ ţĥē ƒĺēx ţĩḿē àţ ţĥē ēńď ōƒ ţĥē śĺōţ.\"],\"L6Mhe6\":[\"Ŷōũ ĥàvē ũńśàvēď ćĥàńĝēś!\"],\"L8Hb+D\":[\"Śēţś ţĥē ńũḿƀēŕ ōƒ ţĥŕēàďś ũśēď ţō ďēćōďē ţĥē ĩńƥũţ śţŕēàḿ. Śēţ ţō 0 ţō ĺēţ ƒƒḿƥēĝ àũţōḿàţĩćàĺĺŷ ďēćĩďē ĥōŵ ḿàńŷ ţĥŕēàďś ţō ũśē. Ŕēàď ḿōŕē àƀōũţ ţĥĩś ōƥţĩōń <0>ĥēŕē. <1>Ńōţē: ţĥĩś ōƥţĩōń ĩś ōvēŕŕĩďďēń ţō 1 ŵĥēń ũśĩńĝ ĥàŕďŵàŕē àććēĺēàŕàţĩōń ƒōŕ śţàƀĩĺĩţŷ ŕēàśōńś.\"],\"LKPR6G\":[\"Ƥĺàŷĺĩśţ\"],\"LKSv28\":[\"Śḿàŕţ Ćōĺĺēćţĩōńś àŕē śēĺƒ-ũƥďàţĩńĝ ćōńţēńţ ĺĩśţś. Ŷōũ śēţ ţĥē ǫũēŕŷ àńď ţĥē ćōĺĺēćţĩōń àũţōḿàţĩćàĺĺŷ àďďś àńŷ ńēŵ ćōńţēńţ ƒŕōḿ ŷōũŕ ĺĩƀŕàŕŷ ţĥàţ ƒĩţś ţĥōśē ŕũĺēś. Àńŷ ńēŵĺŷ àďďēď ćōńţēńţ ḿàţćĥĩńĝ ǫũēŕŷ ŵĩĺĺ ńōţ ḿōďĩƒŷ ēxĩśţĩńĝ ćĥàńńēĺ ƥŕōĝŕàḿḿĩńĝ àţ ţĥĩś ţĩḿē.\"],\"LMMGPr\":[\"Śũƀḿĩţţĩńĝ...\"],\"LRvqnF\":[\"Ēŕŕōŕ śàvĩńĝ ńēŵ ĵēĺĺŷƒĩń śēŕvēŕ. Śēē ƀŕōŵśēŕ ćōńśōĺē àńď śēŕvēŕ ĺōĝś ƒōŕ ďēţàĩĺś\"],\"LTC198\":[\"Ŕũńńĩńĝ...\"],\"LTYRAI\":[\"Vĩēŵ Ĺĩƀŕàŕŷ\"],\"LiCr5o\":[\"Ĺĩḿĩţ ḿũśţ ƀē ńũḿēŕĩć\"],\"MHrjPM\":[\"Ţĩţĺē\"],\"MKK96e\":[\"Vĩēŵ Ćōĺĺēćţĩōń\"],\"MR6Nlf\":[\"Ćĥàńĝē ţĥē vēŕƀōśĩţŷ ōƒ śƥēćĩƒĩć ćàţēĝōŕĩēś ōƒ ĺōĝś. Ũśēƒũĺ ĩƒ ďēƀũĝĝĩńĝ à śƥēćĩƒĩć ƒēàţũŕē.\"],\"MS1Dhi\":[\"Ḿàx ƒĩĺē śĩźē (ƀŷţēś)\"],\"MVBLYK\":[\"Ŕēḿōvē...\"],\"MW42Hp\":[\"Ćũśţōḿĩźē ĥōŵ ḿōvĩē ƀĺōćķś àŕē śōŕţēď\"],\"Md/eZS\":[[\"count\",\"plural\",{\"one\":[\"#\",\" ĩţēḿ\"],\"other\":[\"#\",\" ĩţēḿś\"]}]],\"MfkGXC\":[\"Śĥũƒƒĺē Ĝŕōũƥĩńĝ\"],\"MkMcGz\":[\"Ŕēƒŕēśĥ Ĺĩƀŕàŕĩēś\"],\"Ml7h3C\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Ƥŕōĝŕàḿ\"],\"other\":[\"#\",\" Ƥŕōĝŕàḿś\"]}]],\"Mrdyk9\":[\"Ĝēńŕē\"],\"Mv+xQh\":[\"Ńēŵ Ćĥàńńēĺ\"],\"N15e5e\":[\"Ŕēḿōvē ćũśţōḿ ĩćōń\"],\"NGOfis\":[\"Ďĩśàƀĺē Ĩḿàĝē Śćàĺĩńĝ\"],\"NGSThJ\":[\"Śḿàŕţ Ćōĺĺēćţĩōń\"],\"NL/bON\":[\"ƑƑḿƥēĝ Ćōḿḿàńď\"],\"NQ7yht\":[\"Ḿũśţ ũśē à vàĺĩď ŨŔĹ, ōŕ ēḿƥţŷ.\"],\"NaDxQ2\":[\"Àũţō Ďēĩńţēŕĺàćē Vĩďēō\"],\"Nb+B9K\":[\"ÀďĴũśţ ţĥē ōũţƥũţ vōĺũḿē (ńōţ ŕēćōḿḿēńďēď). Vàĺũēś ĥĩĝĥēŕ ţĥàń 100 ŵĩĺĺ ƀōōśţ ţĥē àũďĩō.\"],\"NcV1df\":[\"Ƥàď Śţàŕţ Ţĩḿēś\"],\"NfTP7a\":[\"Àďvàńćēď ōƥţĩōńś ŕēĺàţĩńĝ ţō àũďĩō. Ĩń ĝēńēŕàĺ, ďō ńōţ ćĥàńĝē ţĥēśē ũńĺēśś ŷōũ ķńōŵ ŵĥàţ ŷōũ àŕē ďōĩńĝ!\"],\"NfZ8rc\":[\"24-ĥōũŕ\"],\"Nkn5MW\":[\"Ŕēḿōvēś àĺĺ Ƒĺēx ƥēŕĩōďś ƒŕōḿ ţĥē śćĥēďũĺē.\"],\"NnH3pK\":[\"Ţēśţ\"],\"NnuRri\":[\"Ţĥĩś àĺĺōŵś ŷōũ ţō ƥĩćķ ţĥē ŵēĩĝĥţś ƒōŕ ēàćĥ ōƒ ţĥē śĥōŵś, śō ŷōũ ćàń ďēćĩďē ţĥàţ śōḿē śĥōŵś śĥōũĺď ƀē ĺēśś ƒŕēǫũēńţ ţĥàń ōţĥēŕ śĥōŵś.\"],\"NtQvjo\":[\"Ƥēŕĩōď\"],\"Nu4oKW\":[\"Ďēśćŕĩƥţĩōń\"],\"Ny7dz3\":[\"Àĺƀũḿś\"],\"NyfQ4q\":[\"Śàvē àś Śḿàŕţ Ćōĺĺēćţĩōń\"],\"O1xfOi\":[\"Ŕàńďōḿ...\"],\"O5izWu\":[\"Ţĥĩś ćũśţōḿ śĥōŵ ĩś śŷńćēď ŵĩţĥ àń ēxţēŕńàĺ ƥĺàŷĺĩśţ. Ćōńţēńţ ĩś ũƥďàţēď àũţōḿàţĩćàĺĺŷ àńď ćàńńōţ ƀē ēďĩţēď ḿàńũàĺĺŷ.\"],\"O8g6Na\":[\"Ĺàśţ Śćàńńēď: \",[\"0\"]],\"OPw3KG\":[\"Ćōńńēćţ Ḿēďĩà Śōũŕćē\"],\"OVmXHk\":[\"Ŕēƒŕēśĥ Ţĩḿēŕ (Ĥōũŕś)\"],\"Ob+B6e\":[\"ßũƒƒēŕ śĩźē ćàńńōţ ƀē ćĥàńĝēď ŵĥēń ćōƥŷĩńĝ ĩńƥũţ àũďĩō\"],\"OfC/JK\":[\"Ćũśţōḿ Śĥōŵ - \",[\"0\"]],\"OfYtUi\":[\"Ƒĩĺĺēŕ Ćōńţēńţ\"],\"OfhWJH\":[\"Ŕēśēţ\"],\"OrDu0o\":[\"Vĩďēō ßũƒƒēŕ Śĩźē\"],\"Osn70z\":[\"Ďēƀũĝ\"],\"P/TyYO\":[\"Ţĥē ţŷƥē ōƒ ḿēďĩà ĩń ţĥē ƥŕōvĩďēď ƥàţĥś\"],\"P1BU0j\":[\"Ƒŕàḿē Ŕàţē\"],\"P29ZKI\":[\"Ēńţēŕ à ńàḿē ƒōŕ ŷōũŕ Ēḿƀŷ Śēŕvēŕ\"],\"P2DGHD\":[\"Ƥŕōĝŕàḿḿĩńĝ śţàŕţś àţ \",[\"startTime\"],\" àńď śţōƥś àţ \",[\"endTime\"]],\"P3i3NN\":[\"Ēďĩţ Ćĥàńńēĺ Śēţţĩńĝś\"],\"P6Io39\":[\"Ḿàx Ĺàţēńēśś\"],\"P6c7YE\":[\"Ŕēḿōvē Ƥŕōĝŕàḿḿĩńĝ\"],\"PCBfmf\":[\"Ŕēńďēŕś à ćĥàńńēĺ ĩćōń (àĺśō ķńōŵń àś ƀũĝ ōŕ Ďĩĝĩţàĺ Ōń-śćŕēēń Ĝŕàƥĥĩć) ōń ţōƥ ōƒ ţĥē ćĥàńńēĺ'ś śţŕēàḿ.\"],\"PJ/u9s\":[\"Ćōƥĩēď \",[\"0\"],\" ŨŔĹ ţō ćĺĩƥƀōàŕď\"],\"PT6k0T\":[\"Ƥĩxēĺ Ƒōŕḿàţ\"],\"PX1WM1\":[\"Śũććēśśƒũĺĺŷ ēḿƥţĩēď ţŕàśĥ.\"],\"Pazp7r\":[\"Ţĥēŕē ŵàś àń ēŕŕōŕ ĝēńēŕàţĩńĝ ţĩḿē śĺōţś. Ćĥēćķ ţĥē ƀŕōŵśēŕ ćōńśōĺē ĺōĝ ƒōŕ ḿōŕē ĩńƒōŕḿàţĩōń\"],\"PeBTGz\":[\"Ćĺēàŕ Śćĥēďũĺē\"],\"PeBylA\":[\"Ŷōũ ḿũśţ ćŕēàţē àţ ĺēàśţ ōńē <0>ƒĩĺĺēŕ ĺĩśţ ƀēƒōŕē àśśĩĝńĩńĝ ƒĩĺĺēŕ ţō à ĺōţ.\"],\"Pfatg8\":[[\"minutes\",\"plural\",{\"one\":[\"#\",\" ḿĩńũţē\"],\"other\":[\"#\",\" ḿĩńũţēś\"]}]],\"PgdRhI\":[\"Ŵēĩĝĥţĩńĝ\"],\"Ph+yE0\":[\"0 ḿĩńś\"],\"PhKcf0\":[\"Ēďĩţ Ţŕàńśćōďē Ćōńƒĩĝ\"],\"PiY0nu\":[\"Ŷōũ ĥàvē ńō Ƒĩĺĺēŕ Ĺĩśţś. Ćŕēàţē ŷōũŕ ƒĩŕśţ Ƒĩĺĺēŕ Ĺĩśţ <0>ĥēŕē.\"],\"Pol2QS\":[\"Ēḿƀŷ\"],\"PpZkda\":[\"Ƒēàţũŕēś\"],\"PwpUBp\":[\"Ţĥĩś ĩś ţĥē ńàḿē ōƒ ţĥē ƒàķē ƥŕōĝŕàḿ ţĥàţ ŵĩĺĺ àƥƥēàŕ ĩń ţĥē ŢV ĝũĩďē ŵĥēń ţĥēŕē àŕē ńō ƥŕōĝŕàḿś ţō ďĩśƥĺàŷ ĩń ţĥàţ ţĩḿē śĺōţ ĝũĩďē, ē.ĝ ŵĥēń à ĺàŕĝē Ƒĺēx ƀĺōćķ ĩś śćĥēďũĺēď.\"],\"Pwqkdw\":[\"Ĺōàďĩńĝ…\"],\"Q8L6q9\":[\"Vĩďēō Śţŕēàḿś\"],\"QAUrt0\":[\"Ŕēƒŕēśĥ Ƥàĝē\"],\"QEb4hu\":[\"Śţēàĺţĥ Ḿōďē\"],\"QG2xdt\":[\"Ćŕēàţē Ŕēŕũń ßĺōćķ\"],\"QHRTYn\":[\"Śĺōţś Ēďĩţōŕ...\"],\"QKMxhc\":[\"Ţũńàŕŕ ŕũńś vàŕĩōũś ţàśķś, śōḿēţĩḿēś ōń à śćĥēďũĺē, ƒōŕ ƀàćķĝŕōũńď ōƥēŕàţĩōńś.\"],\"QUxTIQ\":[\"Ƒĩĺĺēŕ ĩś ŕēśōĺvēď àţ śćĥēďũĺē ţĩḿē. Ţĥē ĝũĩďē śĥōŵś śƥēćĩƒĩć ƒĩĺĺēŕ ţĩţĺēś.\"],\"Qll2Tb\":[\"Ďēść\"],\"QlrQ/Z\":[\"Ńēxţ Śćĥēďũĺēď Ēxēćũţĩōń\"],\"Qm1NmK\":[\"ŌŔ\"],\"Qu844y\":[\"Ţĩḿē Śĺōţ Ēďĩţōŕ\"],\"QvKdb0\":[\"Ƥĺàćēĥōĺďēŕ Ƥŕōĝŕàḿ Ţĩţĺē\"],\"Qx971g\":[\"Àƒţēŕ Ēvēŕŷ\"],\"R/7J0Z\":[\"Àŕţĩśţś\"],\"R/N+HY\":[\"Ńō ƥŕōĝŕàḿḿĩńĝ àďďēď ŷēţ\"],\"R/xSFi\":[\"Ēďĩţĩńĝ \\\"\",[\"0\"],\"\\\"\"],\"R0yni2\":[\"Àţţēḿƥţ Àũţō-Ƒĩx\"],\"R40oLk\":[\"Ŵĩĺĺ ƒōŕćē ũśē ōƒ à śōƒţŵàŕē ēńćōďēŕ ďēśƥĩţē ĥàŕďŵàŕē àććēĺēŕàţĩōń śēţţĩńĝś.\"],\"R6kHq+\":[\"Ĺĩńķ Ḿōďē\"],\"R9Khdg\":[\"Àũţō\"],\"RCeEAd\":[\"Ĝĺōƀàĺ Ōƥţĩōńś\"],\"RGf6l7\":[\"Śēĺēćţ à śĺōţ ţō ĺĩńķ ţō\"],\"RI4u49\":[\"<0>Ŷōũ ćàń ēďĩţ ţĥĩś ĺōćàţĩōń ĩń ŷōũŕ śēţţĩńĝś.Ĵśōń ŵĩţĥĩń ŷōũŕ Ţũńàŕŕ ďàţà ďĩŕēćţōŕŷ<1/><2>ŃŌŢĒ: Ŵĥēń ḿàńũàĺĺŷ àďďĩńĝ ţĥē XḾĹŢV ĺōćàţĩōń ţō à ćĺĩēńţ ĺĩķē Ƥĺēx, ďō ńōţ ũśē ţĥĩś ƒĩĺē ďĩŕēćţĺŷ. Ĩńśţēàď, ũśē ţĥē ĝēńēŕàţēď XḾĹŢV ƒŕōḿ ţĥē Ţũńàŕŕ ÀƤĨ ēńďƥōĩńţ: \",[\"0\"],\"\"],\"RTxUjI\":[\"Ćōƥŷ ţō Ćĺĩƥƀōàŕď\"],\"RUYsn0\":[\"Ćĺēàŕ Àĺĺ\"],\"RVl9/c\":[\"Àĺţēŕńàţē ƥŕōĝŕàḿś ĩń ƀĺōćķś. Ŷōũ ćàń ƥĩćķ ţĥē ńũḿƀēŕ ōƒ ƥŕōĝŕàḿś ƥēŕ-ţŷƥē ĩń ēàćĥ ƀĺōćķ àńď ĩƒ ţĥē ōŕďēŕ ōƒ śĥōŵś ĩń ēàćĥ ƀĺōćķ śĥōũĺď ƀē ŕàńďōḿĩźēď.\"],\"RYP47R\":[[\"0\",\"plural\",{\"one\":[\"Ďàŷ\"],\"other\":[\"Ďàŷś\"]}]],\"RYlQY0\":[\"Ŕēƥēàţś\"],\"RaHlqV\":[[\"totalConnections\",\"plural\",{\"one\":[\"#\",\" ćōńńēćţĩōń\"],\"other\":[\"#\",\" ćōńńēćţĩōńś\"]}]],\"RavMGr\":[[\"count\",\"plural\",{\"one\":[\"śēćōńď\"],\"other\":[\"śēćōńďś\"]}]],\"RbgUS/\":[\"Ćōƥŷ Ćĥàńńēĺ ĨĎ\"],\"RtPRIb\":[\"Ḿàxĩḿũḿ ńũḿƀēŕ ōƒ ďàŷś ţō ƥŕēćàĺćũĺàţē ţĥē śćĥēďũĺē. Ńōţē ţĥàţ ţĥē ĺēńĝţĥ ōƒ ţĥē śćĥēďũĺē ĩś àĺśō ƀōũńďēď ƀŷ ţĥē ḿàxĩḿũḿ ńũḿƀēŕ ōƒ ƥŕōĝŕàḿś àĺĺōŵēď ĩń à ćĥàńńēĺ.\"],\"RxzN1M\":[\"Ēńàƀĺēď\"],\"S/CawK\":[\"Ḿōvĩēś àŕē ĝŕōũƥēď àĺţōĝēţĥēŕ\"],\"S5v5/h\":[\"Ēńàƀĺĩńĝ ēḿƀēďďēď śũƀţĩţĺē ēxţàćţĩōń ŵĩĺĺ ƥēŕĩōďĩćàĺĺŷ śćàń ŷōũŕ ũƥćōḿĩńĝ ƥŕōĝŕàḿḿĩńĝ ƒōŕ ēḿƀēďďēď ţēxţ-ƀàśēď śũƀţĩţĺē śţŕēàḿś àńď ēxţŕàćţ ţĥēḿ ţō à ĺōćàĺ ćàćĥē. Ţĥĩś ĩś ńēćēśśàŕŷ ĩń ōŕďēŕ ţō ēńàƀĺē śũƀţĩţĺē ƀũŕńĩńĝ ƒōŕ ţēxţ-ƀàśēď śũƀţĩţĺēś ŵĥĩćĥ àŕē ńōţ ēxţēŕńàĺ śţŕēàḿś.\"],\"S60KP9\":[\"Śēŕvēŕ Śēţţĩńĝś\"],\"S8zZJK\":[\"Ŵēĺćōḿē ţō Ţũńàŕŕ!\"],\"SBtwzo\":[\"Vēŕśĩōń Ḿĩśḿàţćĥ!\"],\"SCZJhh\":[\"Àũďĩō ßĩţŕàţē\"],\"SFjIKS\":[[\"0\",\"plural\",{\"one\":[\"#\",\" Śēĺēćţēď Ĩţēḿ\"],\"other\":[\"#\",\" Śēĺēćţēď Ĩţēḿś\"]}]],\"SOXW6w\":[\"Àĺĺ Ĝēńŕēś\"],\"SY1gRl\":[\"Ḿēďĩà Śōũŕćē\"],\"SYGPcm\":[\"Ŷōũ ĥàvē ńō śḿàŕţ ćōĺĺēćţĩōńś. Śḿàŕţ ćōĺĺēćţĩōńś ćàń ƀē ćŕēàţēď ōń ţĥē <0>śēàŕćĥ ƥàĝē.\"],\"SZcfpX\":[\"Ƥàď Śţŷĺē\"],\"SZzr30\":[\"Ţĥē śēĺēćţēď ĺàńĝũàĝēś ŵĩĺĺ ƀē ćōńśĩďēŕēď ĩń ōŕďēŕ ţĥēŷ àŕē śēĺēćţēď.\"],\"Sbs5dW\":[\"Ƒĩĺĺēŕ\"],\"Sg3laT\":[\"Ḿĩń Ďũŕàţĩōń\"],\"SoRsRS\":[\"Ćàĺćũĺàţēś à śćĥēďũĺē ŵĥēŕē àĺĺ ƥŕōĝŕàḿś ēńď àţ ţĥē śàḿē ţĩḿē, ćŕēàţĩńĝ à ƥēŕƒēćţĺŷ ĺōōƥĩńĝ śćĥēďũĺē.\"],\"SuubHr\":[\"Ďēĺēţĩńĝ à Ƥĺēx śēŕvēŕ ŵĩĺĺ ŕēḿōvē àĺĺ ƥŕōĝŕàḿḿĩńĝ ƒŕōḿ ŷōũŕ ćĥàńńēĺś àśśōćĩàţēď ŵĩţĥ ţĥĩś ƥĺēx śēŕvēŕ. Ḿĩśśĩńĝ ƥŕōĝŕàḿḿĩńĝ ŵĩĺĺ ƀē ŕēƥĺàćēď ŵĩţĥ Ƒĺēx ţĩḿē. Ţĥĩś àćţĩōń ćàńńōţ ƀē ũńďōńē.\"],\"SywaS+\":[\"Ďàţà Ďĩŕēćţōŕŷ:\"],\"T5wfux\":[\"Ḿàķēś ḿũĺţĩƥĺē ćōƥĩēś ōƒ ţĥē śćĥēďũĺē àńď ƥĺàŷś ţĥēḿ ĩń śēǫũēńćē\"],\"T8drou\":[\"Śŷśţēḿ Ĥēàĺţĥ\"],\"TEM0vH\":[\"Ŕēḿōvēś àĺĺ ƥŕōĝŕàḿś ƒŕōḿ ćũśţōḿ śĥōŵ\"],\"TMADKS\":[\"Ďĩvĩďēś ţĥē ƥŕōĝŕàḿḿĩńĝ ĩń ƀĺōćķś ōƒ 4, 6, 8 ōŕ 12 ĥōũŕś ţĥēń ŕēƥēàţś ēàćĥ ōƒ ţĥē ƀĺōćķś ţĥē śƥēćĩƒĩēď ńũḿƀēŕ ōƒ ţĩḿēś.\"],\"TMju4P\":[\"Ďēĺēţē Ḿēďĩà Śōũŕćē \\\"\",[\"0\"],\"\\\"?\"],\"TS0lwx\":[\"Ēńćōũńţēŕēď àń ēŕŕōŕ ŵĥēń ēḿƥţŷĩńĝ ţŕàśĥ. Ćĥēćķ ćōńśōĺē ĺōĝś ƒōŕ ďēţàĩĺś.\"],\"TZKpsF\":[\"Ńō Ḿēďĩà Śōũŕćēś ďēţēćţēď.\"],\"TpqW74\":[\"Ƒĩxēď\"],\"Ts6Zfm\":[\"Ēŕŕōŕ ũƥďàţĩńĝ Śḿàŕţ Ćōĺĺēćţĩōń. Ćĥēćķ ĺōĝś ƒōŕ ďēţàĩĺś.\"],\"Ts8Q+i\":[\"ĒƤĜ\"],\"TvY/XA\":[\"Ďōćũḿēńţàţĩōń\"],\"Tz0i8g\":[\"Śēţţĩńĝś\"],\"TzyoiK\":[\"Ŵĥēń ēńàƀĺĩńĝ, Ţũńàŕŕ ŵĩĺĺ ĝēńēŕàţē àń ĩńĩţĩàĺ ƀàćķũƥ ĩḿḿēďĩàţēĺŷ\"],\"U0sC6H\":[\"Ďàĩĺŷ\"],\"U3+jR/\":[\"Ŕēƥĺĩćàţē Ƥŕōĝŕàḿś\"],\"UC1lMc\":[\"Ƒàĩĺēď ţō śàvē ƒēàţũŕē ƒĺàĝś.\"],\"UE2eVC\":[\"Śōŕţś àĺƥĥàƀēţĩćàĺĺŷ ƀŷ ƥŕōĝŕàḿ ţĩţĺē\"],\"UHu/Uf\":[\"Śĥōŵ ōńĺŷ śŷńćēď ĺĩƀŕàŕĩēś\"],\"UOMT7z\":[\"Ţĥĩś ōƥţĩōń ĩś ďĩśàƀĺēď ƀēćàũśē ĩţ ŵōũĺď ćàĺćũĺàţē à śćĥēďũĺē ţĥàţ ĩś ţōō ĺōńĝ.\"],\"URmyfc\":[\"Ďēţàĩĺś\"],\"UXC1jS\":[\"ŃōďēĵŚ: \",[\"0\"]],\"UYUgdb\":[\"Ōŕďēŕ\"],\"UYW9jU\":[\"Śũććēśśƒũĺĺŷ ŕàń śŷśţēḿ ƒĩxēŕ \",[\"fixerId\"]],\"Uf/h/w\":[\"Ƥĩćķ śƥēćĩƒĩć ƥŕōĝŕàḿḿĩńĝ ţō ŕēḿōvē ƒŕōḿ ţĥē ćĥàńńēĺ.\"],\"UirGxE\":[\"Ēŕŕōŕś\"],\"UnI8zh\":[\"Ćĥàńńēĺ #\",[\"0\"]],\"UweSf9\":[\"Àďď Ćĥàńńēĺ Ŕēďĩŕēćţ\"],\"V8B1wG\":[\"Ĺàśţ śŷńćēď \",[\"0\"]],\"V9UVpb\":[\"Ţōţàĺ ĥĩţś: \",[\"0\"]],\"VBsY8N\":[\"Śēţ ţō 0 ţō ńēvēŕ ďēĺēţē ƀàćķũƥś\"],\"VIHbrI\":[\"Àďvàńćēď ōƥţĩōńś ŕēĺàţĩńĝ ţō ţŕàńśćōďĩńĝ. Ĩń ĝēńēŕàĺ, ďō ńōţ ćĥàńĝē ţĥēśē ũńĺēśś ŷōũ ķńōŵ ŵĥàţ ŷōũ àŕē ďōĩńĝ! Ţĥēśē śēţţĩńĝś ēxĩśţ ĩń ōŕďēŕ ţō ĺēàvē śōḿē ƥàŕĩţŷ ŵĩţĥ ţĥē ōĺď ďĩźǫũēŢV ţŕàńśćōďē ƥĩƥēĺĩńē àś ŵēĺĺ àś ţō ƥŕōvĩďē ḿēćĥàńĩśḿś ţō àĩď ĩń ďēƀũĝĝĩńĝ śţŕēàḿĩńĝ ĩśśũēś.\"],\"VP2oPP\":[\"Śĺōţś\"],\"VVAgOP\":[\"Ŕēśćàń Ĩńţēŕvàĺ (ĥōũŕś)\"],\"VXdzY3\":[\"Ďĩśàƀĺē Ĥàŕďŵàŕē Ēńćōďĩńĝ\"],\"Va3xJe\":[\"Àďď ƒĩēĺď\"],\"VfWz27\":[\"Ŵēĩĝĥţ %\"],\"VlEnCC\":[\"Àŕćĥĩvē Ƒōŕḿàţ\"],\"VlWKwW\":[\"Ĺàźŷ\"],\"Vmvp5H\":[[\"count\",\"plural\",{\"one\":[\"ďàŷ\"],\"other\":[\"ďàŷś\"]}]],\"VrBtVn\":[\"ßàćķũƥś:\"],\"Vw5EeW\":[\"Ēńàƀĺē ßàćķũƥś\"],\"VyUuZb\":[\"Ĩḿàĝē ŨŔĹ\"],\"WAakm9\":[\"Ďēĺēţē Ćĥàńńēĺ\"],\"WDgJiV\":[\"Śćàńńēŕ\"],\"WGkxNZ\":[\"Ēŕŕōŕ ǫũēŕŷĩńĝ Ƥĺēx. Ćĥēćķ ćōńśōĺē ĺōĝ àńď ćōńśĩďēŕ ŕēƥōŕţĩńĝ à ƀũĝ!\"],\"WKHqM+\":[\"Ŵēĩĝĥţ\"],\"WMQchs\":[\"Àũďĩō ßũƒƒēŕ Śĩźē\"],\"WT1Ibn\":[\"Ĺàśţ ŕũń\"],\"Wb3E4g\":[\"Ŕũń ńōŵ\"],\"Weq9zb\":[\"Ĝēńēŕàĺ\"],\"WhJZoS\":[\"Ćĥōōśē ţĥē ţŕàńśćōďē ćōńƒĩĝũŕàţĩōń ţō ũśē ƒōŕ ţĥĩś ćĥàńńēĺ. Ćōńƒĩĝũŕē ţŕàńśćōďē ćōńƒĩĝũŕàţĩōńś ōń ţĥē <0>ƑƑḿƥēĝ śēţţĩńĝś ƥàĝē.\"],\"WjUHH8\":[\"Ḿōvĩē Śōŕţ\"],\"WnW1QF\":[[\"block\"],\" Ĥōũŕś\"],\"WzNAIP\":[[\"0\",\"plural\",{\"one\":[\"Ĥōũŕ\"],\"other\":[\"Ĥōũŕś\"]}]],\"X0mSqw\":[\"Ŵĩĺĺ ƒōŕćē ũśē ōƒ à śōƒţŵàŕē ƒĩĺţēŕś (ē.ĝ. śćàĺē, ƥàď, ēţć.) ďēśƥĩţē ĥàŕďŵàŕē àććēĺēŕàţĩōń śēţţĩńĝś.\"],\"X9EHMa\":[\"Ēďĩţĩńĝ Śḿàŕţ Ćōĺĺēćţĩōń \\\"\",[\"0\"],\"\\\"\"],\"XDT85c\":[\"Ḿēďĩà Śōũŕćēś\"],\"XIgmo9\":[\"Ďĩď ńōţ ŕēćēĩvē àń àććēśśŢōķēń ōŕ ũśēŕĨď ƒŕōḿ ĵēĺĺŷƒĩń śēŕvēŕ.\"],\"XNtsE7\":[\"Ćàĺćũĺàţĩńĝ Śĺōţś...\"],\"XNw99A\":[\"Śōƒţŵàŕē (Ńō ĜƤŨ)\"],\"XOgcN3\":[\"Ƒĩĺĺēŕ Ĺĩśţ: \",[\"0\"]],\"XOuE6F\":[\"Ţĥĩś ćōũĺď ćàũśē ţĥē ƒōĺĺōŵĩńĝ śĺōţ'ś ƥŕōĝŕàḿś ţō ĝō ũńśćĥēďũĺēď. Ƥōśśĩƀĺē śōĺũţĩōńś ĩńćĺũďē:\"],\"XSkU3F\":[\"* Ŕēśţàŕţ ŕēǫũĩŕēď\"],\"XWYqJx\":[\"Ďũƥĺĩćàţē Ćĥàńńēĺ\"],\"XXwX66\":[\"Śēţ ţĥē ĺōĝ ĺēvēĺ ƒōŕ ţĥē Ţũńàŕŕ śēŕvēŕ.<0/>Śēĺēćţĩńĝ <1>\\\"Ũśē ēńvĩŕōńḿēńţ śēţţĩńĝś\\\" ŵĩĺĺ ĩńśţŕũćţ ţĥē śēŕvēŕ ţō ũśē ţĥē <2>ĹŌĜ_ĹĒVĒĹ ēńvĩŕōńḿēńţ vàŕĩàƀĺē, ĩƒ śēţ, ōŕ śŷśţēḿ ďēƒàũĺţ \\\"ĩńƒō\\\".\"],\"XePUKr\":[\"Ţēśţ Ţŕàńśćōďē\"],\"XhWvkJ\":[[\"0\"],\" ōƒ \",[\"1\"],\" \",[\"2\"],\" ēxćēēď ţĥē ĺēńĝţĥ ōƒ ţĥĩś śĺōţ (\",[\"3\"],\"). Àvēŕàĝē ƥŕōĝŕàḿ ĺēńĝţĥ: \",[\"4\"]],\"Xkppm4\":[\"Ēńàƀĺē Ŵàţēŕḿàŕķ\"],\"Xm/WEQ\":[\"Ćĥàńńēĺ Ĝŕōũƥ\"],\"XsR2HX\":[\"Ţēśţ Ďũŕàţĩōń (śēćōńďś)\"],\"Xuml3I\":[\"ßŷ ďēƒàũĺţ, ţĩḿē śĺōţś àŕē ţĩḿē ōƒ ţĥē ďàŷ-ƀàśēď, ŷōũ ćàń ćĥàńĝē ĩţ ţō ţĩḿē ōƒ ţĥē ďàŷ + ďàŷ ōƒ ţĥē ŵēēķ. Ţĥàţ ḿēàńś śćĥēďũĺĩńĝ 7x ţĥē ńũḿƀēŕ ōƒ ţĩḿē śĺōţś. Ĩƒ ŷōũ ćĥàńĝē ƒŕōḿ ďàĩĺŷ ţō ŵēēķĺŷ, ţĥē ćũŕŕēńţ śćĥēďũĺē ŵĩĺĺ ƀē ŕēƥēàţēď 7 ţĩḿēś. Ĩƒ ŷōũ ćĥàńĝē ƒŕōḿ ŵēēķĺŷ ţō ďàĩĺŷ, ḿàńŷ ōƒ ţĥē śĺōţś ŵĩĺĺ ƀē ďēĺēţēď.\"],\"XwU6BE\":[\"Ŷōũ ĥàvēń'ţ ćŕēàţēď àńŷ ƒĩĺĺēŕ ĺĩśţś ŷēţ! Ĝō ţō ţĥē <0>Ƒĩĺĺēŕ Ĺĩśţś ƥàĝē ţō ćŕēàţē ōńē.\"],\"Y2ngGV\":[\"Àďď à Ƒĩĺĺēŕ Ĺĩśţ\"],\"Y5XZLy\":[\"<0>Ƥàď Śĺōţ: Àĺĩĝń śĺōţ śţàŕţ ţĩḿēś ţō ţĥē śƥēćĩƒĩēď ƥàď ţĩḿē.<1/><2>Ƥàď Ēƥĩśōďē: Àĺĩĝń ēƥĩśōďē śţàŕţ ţĩḿēś (ŵĩţĥĩń à śĺōţ) ţō ţĥē śƥēćĩƒĩēď ƥàď ţĩḿē. <3>ŃŌŢĒ: Ďēƥēńďĩńĝ ōń śĺōţ ĺēńĝţĥ àńď ţĥē ćĥōśēń ƥàď ţĩḿē, ţĥĩś ćōũĺď ƥōţēńţĩàĺĺŷ ćŕēàţē à ĺōţ ōƒ ƒĺēx.\"],\"Y84UgQ\":[\"Ĺōũďńēśś Ţàŕĝēţ\"],\"YAKCkm\":[\"Àń ēŕŕōŕ ōććũŕŕēď: \",[\"0\"]],\"YDlcs3\":[\"Śĥũƒƒĺē Ƥŕōĝŕàḿḿĩńĝ\"],\"YLUnu0\":[\"Ţēśţ Ƥĺàŷƀàćķ\"],\"YN7vx3\":[\"Ćũśţōḿ Śĥōŵ\"],\"YRQaPv\":[\"Ĺàśţ Śŷńćēď\"],\"YRT1+e\":[\"Ćŕēàţēś à ńēŵ ćōĺĺēćţĩōń\"],\"YSptU0\":[\"Ŕēƥĺĩćàţē...\"],\"YT5/eK\":[\"Ḿēďĩà Śōũŕćē: \\\"\",[\"0\"],\"\\\"\"],\"YXwR3a\":[\"Ŕēśţōŕē ďēƒàũĺţ ĺōĝō\"],\"YY/JN7\":[\" ţĥē ƒōĺĺōŵĩńĝ ďàŷ.\"],\"YYLNVW\":[\"Ĩńśēŕţ ƀŕēàķś àţ ţĥēśē ƥēŕćēńţàĝēś ōƒ ţĥē ƥŕōĝŕàḿ ďũŕàţĩōń\"],\"YdIZFA\":[\"Ţĥĩś ćĥàńńēĺ ńũḿƀēŕ ĥàś àĺŕēàďŷ ƀēēń ũśēď\"],\"Yf/Mtb\":[\"Ŷōũ'ŕē Àĺĺ Śēţ!\"],\"Z10t2U\":[\"Ŕēḿōvēś ŕēƥēàţēď ƥŕōĝŕàḿś.\"],\"Z3FXyt\":[\"Ĺōàďĩńĝ...\"],\"Z4IQ8m\":[\"Ćĥàńńēĺ Ţŕàńśćōďē Ćōńƒĩĝ\"],\"Z5IrB3\":[\"Ōƥēń ĩń \",[\"0\"]],\"Z6dMWq\":[\"Ēŕŕōŕ ŵĥĩĺē ŕũńńĩńĝ śŷśţēḿ ƒĩxēŕ \",[\"fixerId\"],\". Ćĥēćķ śēŕvēŕ ĺōĝś ƒōŕ ďēţàĩĺś.\"],\"ZND/fh\":[\"Ćàńńōţ ƀē ēḿƥţŷ\"],\"ZNZzTe\":[\"Ćàńńōţ ďĩśàƀĺē ĺĩƀŕàŕĩēś ŵĥēń ţĥēŷ àŕē ĺōćķēď\"],\"ZShzvn\":[\"\\\"\",[\"0\"],\"\\\" Ĺĩvē\"],\"ZWRt1W\":[\"Ōũţƥũţ Ƥàţĥ\"],\"ZkdKVr\":[\"Ŕēďĩŕēćţ ţō Ćĥàńńēĺ \",[\"0\"]],\"Zky8hA\":[\"Ţĥē ĩḿàĝē ŵĩĺĺ ƀē ŕēńďēŕēď àţ ĩţś àćţũàĺ śĩźē ŵĩţĥōũţ àńŷ śćàĺĩńĝ àƥƥĺĩēď.\"],\"Zs2GWW\":[\"Ńēŵ Ēḿƀŷ Ḿēďĩà Śōũŕćē\"],\"Zul8Ry\":[\"ńēvēŕ\"],\"Zvipe1\":[\"Ēďĩţĩńĝ Ƥĺēx Śēŕvēŕ \\\"\",[\"0\"],\"\\\"\"],\"ZxwuFV\":[\"Ďēĺēţĩńĝ à Ćĥàńńēĺ ŵĩĺĺ ŕēḿōvē àĺĺ ƥŕōĝŕàḿḿĩńĝ ƒŕōḿ ţĥē ćĥàńńēĺ. Ţĥĩś àćţĩōń ćàńńōţ ƀē ũńďōńē.\"],\"a+Pr3s\":[\"Àƥƥĺŷ ţō Ƥŕōĝŕàḿ Ţŷƥēś (ēḿƥţŷ = àĺĺ)\"],\"a4N/Bg\":[\"Ĺōàď Ḿōŕē\"],\"aE3UMm\":[\"<0>Ńōńē: śĺōţś àŕē ƥĩćķēď ĩń ţĥē ōŕďēŕ ţĥēŷ àŕē śƥēćĩƒĩēď ĩń ţĥē ţàƀĺē (ĩ.ē. ńōţ ŕàńďōḿĺŷ)<1/><2>Ũńĩƒōŕḿ: àĺĺ śĺōţś ĥàvē àń ēǫũàĺ ćĥàńćē ţō ƀē ƥĩćķēď.<3/><4>Ŵēĩĝĥţēď: ēàćĥ śĺōţ ĩś ƥĩćķēď ŵĩţĥ à śƥēćĩƒĩēď ƥŕōƀàƀĩĺĩţŷ\"],\"aOaCIk\":[\"Àĺĺōŵ Ēxţēŕńàĺ\"],\"aScBGS\":[\"Àďď à ƒĩĺţēŕ ēxƥŕēśśĩōń ţō ƒĩńē-ţũńē ŕēśũĺţś ōƒ ţĥē śēàŕćĥ\"],\"aSwfbR\":[\"Ũńĩţ\"],\"ak3N0i\":[\"Ĩţēḿ ŵàś ńōţ ƥŕēśēńţ ďũŕĩńĝ ţĥē ĺàśţ śćàń\"],\"aoLy25\":[\"Ōƥàćĩţŷ\"],\"b0Uv6P\":[[\"0\",\"plural\",{\"one\":[\"Ƥàţĥ\"],\"other\":[\"Ƥàţĥś\"]}]],\"b6sx4K\":[\"Ńō àćţĩvē śēśśĩōńś\"],\"bDY29m\":[\"Ĺōĝàŕĩţĥḿĩć\"],\"bGG6B1\":[\"ĵēĺĺŷƒĩń\"],\"bHNlfr\":[\"Ĩńćŕēàśĩńĝ ţĥē śĺōţ ďũŕàţĩōń.\"],\"bNEQeI\":[\"Ćōōĺďōŵń\"],\"bORfbY\":[\"Ćàńńōţ ũśē à ćĥàńńēĺ ńũḿƀēŕ <= 0\"],\"bPJiZF\":[\"Śĥōŵ: \",[\"0\"]],\"bSIBDb\":[\"Ŕēĺēàśē Ďàţē (àść)\"],\"bm8pgG\":[\"Àďď ĝŕōũƥ\"],\"boItSp\":[\"Ďēĺēţē Ḿēďĩà Śōũŕćē?\"],\"buS8nL\":[\"Ēńàƀĺē Śũƀţĩţĺēś\"],\"bxyuno\":[\"Ōvēŕŕĩďē ĝĺōƀàĺ àũďĩō àńď śũƀţĩţĺē śēţţĩńĝś ƒōŕ ţĥĩś ćĥàńńēĺ.\"],\"bydide\":[\"ƑƑḾƤĒĜ Ĺōĝ Ḿēţĥōď\"],\"c6fsNw\":[\"Ŵĥēń ēńàƀĺēď, ĩńţēŕḿĩţţēńţ ŵàţēŕḿàŕķś ƒàďē ĩń ĩḿḿēďĩàţēĺŷ ŵĥēń à śţŕēàḿ ĩś ĩńĩţĩàĺĩźēď. Ŵĥēń ďĩśàƀĺēď, ţĥē ƒĩŕśţ ŵàţēŕḿàŕķ ƒàďē-ĩń ōććũŕś àƒţēŕ à ƒũĺĺ ƥēŕĩōď.\"],\"cF5KzV\":[\"Ēďĩţ Ƒĩĺĺēŕ Ĺĩśţ\"],\"cFTdM+\":[\"Ćōńśōĺē\"],\"cHYx4E\":[\"Ēḿƥţŷ Ţŕàśĥ\"],\"cLgGtf\":[\"Ŕēśēţ ƥŕōĝŕàḿḿĩńĝ ţō ḿōśţ ŕēćēńţĺŷ śàvēď śţàţē\"],\"cN5Dty\":[\"Ńō Ƥŕōĝŕàḿḿĩńĝ śćĥēďũĺēď\"],\"cOvZFM\":[\"Ďŷńàḿĩć\"],\"cXkSYc\":[\"Ţĥēŕē ŵàś àń ēŕŕōŕ śũƀḿĩţţĩńĝ ţĥē ŕēǫũēśţ ţō ũƥďàţē Ḿēďĩà Śōũŕćē śēţţĩńĝś. Ƥĺēàśē ćĥēćķ ţĥē ƒōŕḿ àńď ţŕŷ àĝàĩń\"],\"caSM6R\":[\"Ţĥĩś ĩś ũśēď ƀŷ ĩƥţv ćĺĩēńţś ţō ćàţēĝōŕĩźē ţĥē ćĥàńńēĺś. Ŷōũ ćàń ĺēàvē ĩţ àś 'ţũńàŕŕ' ĩƒ ŷōũ ďōń'ţ ńēēď ţĥĩś śōŕţ ōƒ ćĺàśśĩƒĩćàţĩōń.\"],\"cgo+Ch\":[[\"remainingTime\"],\" ĺēƒţ\"],\"cheWPw\":[\"Ďũƥĺĩćàţēś\"],\"cjX7aq\":[\"Àŕē ŷōũ śũŕē ŷōũ ŵàńţ ţō ďēĺēţē Śḿàŕţ Ćōĺĺēćţĩōń \\\"\",[\"0\"],\"\\\"?\"],\"cmKYIw\":[\"Ōvēŕƒĺōŵ ßēĥàvĩōŕ\"],\"cmlWKg\":[\"<0>Ēŕŕōŕ ďēĺēţĩńĝ ćũśţōḿ śĥōŵ: \",[\"0\"],\"<1/>Ƥĺēàśē ćōńśĩďēŕ ōƥēńĩńĝ à ƀũĝ ŵĩţĥ ďēţàĩĺś!\"],\"cnCAaO\":[\"Ƥēŕćēńţàĝē-ßàśēď\"],\"cnGeoo\":[\"Ďēĺēţē\"],\"cv/ykT\":[\"Śēàŕćĥ Śēŕvēŕ ŨŔĹ:\"],\"cxrM1O\":[\"Ćōńńēćţ Śōũŕćēś\"],\"d5zxa4\":[\"Ĺōćàĺ\"],\"d72gcv\":[\"Ĺōũďńōŕḿ Ōƥţĩōńś\"],\"d9HhJj\":[\"Ţĥĩś ḿēďĩà śōũŕćē ĥàś ńō ēńàƀĺēď ōŕ śćàńńēď ĺĩƀŕàŕĩēś. Ēńàƀĺē ĺĩƀŕàŕĩēś ƒōŕ ţĥĩś śōũŕćē ōń ţĥē <0>Ḿēďĩà Śōũŕćēś ƥàĝē ōŕ ḿàńũàĺĺŷ ţŕĩĝĝēŕ śćàńś ōń ţĥē <1>Ĺĩƀŕàŕŷ ƥàĝē.\"],\"d9Tsiy\":[\"Ēŕŕōŕ ũƥďàţĩńĝ ćĥàńńēĺ.<0/>Ćĥēćķ ƀŕōŵśēŕ ćōńśōĺē ƒōŕ ďēţàĩĺś\"],\"d9XR+x\":[\"Ţŕàńśćōďē Ćōńƒĩĝ <0> <1/>\"],\"dBV/FP\":[\"Ĺōćķ Ŵēĩĝĥţś\"],\"dDX6oS\":[\"Vĩďēōś ƒŕōḿ ţĥē ƒĩĺĺēŕ ĺĩśţ ŵĩĺĺ ƀē ŕàńďōḿĺŷ ƥĩćķēď ţō ƥĺàŷ ũńĺēśś ţĥēŕē àŕē ćōōĺďōŵń ŕēśţŕĩćţĩōńś ţō ƥĺàćē ōŕ ĩƒ ńō vĩďēōś àŕē śĥōŕţ ēńōũĝĥ ƒōŕ ţĥē ŕēḿàĩńĩńĝ Ƒĺēx ţĩḿē.<0/>Ēàćĥ ƒĩĺĺēŕ ćàń ƀē àśśĩĝńēď à ćōōĺďōŵń, ŵĥĩćĥ ŕēśţŕĩćţś ĥōŵ ƒŕēǫũēńţĺŷ ţĥē ĺĩśţ ŵĩĺĺ ƀē ćĥōśēń ďũŕĩńĝ ƒĺēx ţĩḿē.\"],\"dEgA5A\":[\"Ćàńćēĺ\"],\"dH8AwH\":[\"Àďď ßŕēàķś\"],\"dK3Z9j\":[\"Ćōḿƥōńēńţ\"],\"dQvGiF\":[[\"0\",\"plural\",{\"one\":[\"#\",\" śēśśĩōń\"],\"other\":[\"#\",\" śēśśĩōńś\"]}]],\"dScixt\":[\"Ēńàƀĺē ďàŕķ Ḿōďē\"],\"dUyQn5\":[\"Ōń-Ďēḿàńď\"],\"daSf8d\":[\"Ĝŕōũƥ ēƥĩśōďē ƥŕōĝŕàḿś ƀŷ ţĥēĩŕ śĥōŵ.\"],\"djpQ8z\":[\"Ŕēĺōàď Śţŕēàḿ\"],\"dkURuB\":[\"Ţàĩĺ ßũƒƒēŕ (ḿĩńũţēś)\"],\"dnCwNB\":[\"Śũććēśśƒũĺĺŷ ćōƥĩēď ţō ćĺĩƥƀōàŕď!\"],\"eARDm/\":[[\"0\",\"plural\",{\"one\":[\"#\",\" śēàśōń\"],\"other\":[\"#\",\" śēàśōńś\"]}],\", \",[\"1\",\"plural\",{\"one\":[\"#\",\" ţōţàĺ ēƥĩśōďē\"],\"other\":[\"#\",\" ţōţàĺ ēƥĩśōďēś\"]}]],\"eEpDfJ\":[\"Ŵĩĺĺ ƒōŕćē ũśē ōƒ à śōƒţŵàŕē ďēćōďēŕ ďēśƥĩţē ĥàŕďŵàŕē àććēĺēŕàţĩōń śēţţĩńĝś.\"],\"eNorwJ\":[\"Ƥŕōĝŕàḿś Ţōō Ĺōńĝ\"],\"ePK91l\":[\"Ēďĩţ\"],\"eSsduj\":[\"VÀ-ÀƤĨ Ďēvĩćē\"],\"eZTFiP\":[\"Ŕēvĩēŵ Śēĺēćţĩōńś\"],\"eZe0fr\":[\"Àũďĩō Ćĥàńńēĺś\"],\"ecUA8p\":[\"Ţōďàŷ\"],\"efuwN9\":[\"Ţĥēśē śēţţĩńĝś àŕē śţōŕēď ĩń ŷōũŕ ƀŕōŵśēŕ àńď àŕē śàvēď àũţōḿàţĩćàĺĺŷ ŵĥēń ćĥàńĝēď.\"],\"eg6m1K\":[\"Ēďĩţ Ţŕàńśćōďē Ćōńƒĩĝ: \\\"\",[\"0\"],\"\\\"\"],\"ep+NHZ\":[\"Ĩƒ ŷōũ ƥŕōćēēď, àĺĺ ũńśàvēď ćĥàńĝēś ŵĩĺĺ ƀē ĺōśţ. Àŕē ŷōũ śũŕē ŷōũ ŵàńţ ţō ƥŕōćēēď?\"],\"et+mIi\":[\"Ţŕōũƀĺēśĥōōţ\"],\"euChZN\":[\"Ćŷćĺĩć Śĥũƒƒĺē\"],\"euc6Ns\":[\"Ďũƥĺĩćàţē\"],\"exYcTF\":[\"Ĺĩƀŕàŕŷ\"],\"eyRsaH\":[\"Ŕōōţ\"],\"f0w0IC\":[\"Ĺēàvē ƀĺàńķ ţō ũśē ţĥē ćĥàńńēĺ'ś ĩćōń.\"],\"f6Hub0\":[\"Śōŕţ\"],\"f6pgxW\":[\"Ţēḿƥōŕàŕĩĺŷ ćàćĥēś ŕēśƥōńśēś ƒŕōḿ Ƥĺēx ƀàśēď ƀŷ ŕēǫũēśţ ƥàţĥ. Ćōũĺď ƥōţēńţĩàĺĺŷ śƥēēď ũƥ ćĥàńńēĺ ēďĩţĩńĝ.\"],\"f7DWm5\":[\"Ńēēď àţ ĺēàśţ ōńē ƥàţĥ\"],\"fD+lMD\":[\"Śēĺēćţ ţĥē ƥōŕţ ţĥē Ţũńàŕŕ śēŕvēŕ ŵĩĺĺ ĺĩśţēń ōń. Ţĥĩś ŕēǫũĩŕēś à śēŕvēŕ ŕēśţàŕţ ţō ţàķē ēƒƒēćţ.\"],\"fI+mNw\":[\"Ƥĺàŷĺĩśţś\"],\"fJfo1A\":[\"Śēŕvēŕ Ƥàţĥ\"],\"fN4bgn\":[\"Ďēĺēţē Ƒĩĺĺēŕ Ĺĩśţ \\\"\",[\"0\"],\"\\\"?\"],\"fQ9phi\":[\"Ŕēḿōvē Àĺĺ\"],\"fSRZCh\":[\"Ŕēśţōŕē Ďēƒàũĺţ Śēţţĩńĝś\"],\"fU1065\":[\"Ḿĩď-Ŕōĺĺ\"],\"fWj7Tt\":[\"Śĥũƒƒĺē ƥŕōĝŕàḿḿĩńĝ ĩń à ćĥàńńēĺ, ōƥţĩōńàĺĺŷ ĝŕōũƥĩńĝ ƥŕōĝŕàḿś ƀŷ ćēŕţàĩń ćŕĩţēŕĩà.\"],\"fcqkKg\":[\"Ńōţ ƒōũńď!\"],\"fsBGk0\":[\"ßàĺàńćē\"],\"ftF4U5\":[\"Śĥōŵ Àďvàńćēď\"],\"fxTyFe\":[\"Ţĥĩś śĺōţ ĩś ĺĩńķēď ŵĩţĥ \",[\"0\"],\" ōţĥēŕ \",[\"1\",\"plural\",{\"one\":[\"śĺōţ\"],\"other\":[\"śĺōţś\"]}],\"Ćōńţēńţ ƒĩēĺďś àŕē śĥàŕēď àćŕōśś ţĥē ĝŕōũƥ.\"],\"fyo+NB\":[\"Ţĥē Ēńď.\"],\"fzWV5a\":[\"Śōŕţ ŢV Śĥōŵś (ďēść)\"],\"g2Pro3\":[\"Ŕēśēţ ćĥàńĝēś ḿàďē ţō ţĥē ćĥàńńēĺ'ś ĺĩńēũƥ\"],\"g6LxbB\":[\"ßŕēàķ Ĩńţēŕvàĺ (ḿĩńũţēś)\"],\"g7LzUS\":[\"Ĩńśţàĺĺ ƑƑḾƤĒĜ\"],\"gBx20d\":[\"Ćũśţōḿ Ƥŕōĝŕàḿ\"],\"gH5Gbn\":[\"Śĥũƒƒĺē\"],\"gJrGqR\":[\"ƑƑḿƥēĝ vēŕśĩōń 7.1+ ŕēćōḿḿēńďēď. Ćĥēćķ ŷōũŕ ćũŕŕēńţ vēŕśĩōń ĩń ţĥē śĩďēƀàŕ\"],\"gL9DoB\":[\"Ƥŕōĝŕàḿś śĥōŕţēŕ ţĥàń ţĥĩś vàĺũē ŵĩĺĺ ƀē ţŕēàţēď ţĥē śàḿē àś Ƒĺēx ţĩḿē. Ḿēàńĩńĝ ţĥàţ ţĥē ŢV Ĝũĩďē ŵĩĺĺ ţŕŷ ţō ḿēĺď ţĥēḿ ŵĩţĥ ţĥē ƥŕēvĩōũś ƥŕōĝŕàḿ ōŕ ďĩśƥĺàŷ ţĥē ƀĺōćķ ōƒ ƥŕōĝŕàḿś àś ţĥē \\\"ƥĺàćē ĥōĺďēŕ ƥŕōĝŕàḿ\\\" ĩƒ ţĥēŷ ḿàķē à ĺàŕĝē ćōńţĩńũōũś ĝŕōũƥ. Ũśē 0 ţō ďĩśàƀĺē ţĥĩś ƒēàţũŕē ōŕ ũśē à ĺàŕĝē vàĺũē ţō ḿàķē ţĥē ćĥàńńēĺ ŕēƥōŕţ ōńĺŷ ţĥē ƥĺàćēĥōĺďēŕ ƥŕōĝŕàḿ àńď ńōţ ţĥē ŕēàĺ ƥŕōĝŕàḿḿĩńĝ.\\n\",[\"0\"]],\"gR/hgc\":[\"Ēŕŕōŕ Àũďĩō\"],\"gcD6jw\":[\"Ĥĩďē ŵàţēŕḿàŕķ ďũŕĩńĝ ƒĩĺĺēŕ\"],\"gf/bM4\":[\"Ćōńţĩńũē ŵĩţĥ Ńēŵ Ćōńţēńţ\"],\"gg9/ya\":[\"Ŕēḿōvē \",[\"count\"],\" \",[\"0\"]],\"ghGSuE\":[\"Ēńśũŕēś ƥŕōĝŕàḿś ĥàvē à ńĩćē-ĺōōķĩńĝ śţàŕţ ţĩḿē, ĩţ ŵĩĺĺ àďď Ƒĺēx ţĩḿē ţō ƒĩĺĺ ţĥē ĝàƥś.\"],\"glVpbE\":[\"Ēàĝēŕ\"],\"h/qU8b\":[\"Ōvēŕŕĩďē ţĥē ďēƒàũĺţ \",[\"0\"],\" ďēvĩćē ƥàţĥ (ďēƒàũĺţś ţō <0>/ďēv/ďŕĩ/ŕēńďēŕĎ128 ōń Ĺĩńũx àńď ƀĺàńķ ōţĥēŕŵĩśē)\"],\"h4yKYk\":[\"Ńēxţ ŕũń\"],\"h8WhoR\":[\"Śĺōţ Śćĥēďũĺēŕ\"],\"hBGuBW\":[\"Ũśē ćĥàńńēĺ ďēƒàũĺţ\"],\"hBzeL7\":[\"Ţĩḿē ƀēƒōŕē ƒĩŕśţ ƀŕēàķ\"],\"hG89Ed\":[\"Ĩḿàĝē\"],\"hISVAG\":[\"Ḿēďĩà Śōũŕćēś àŕē ŵĥēŕē Ţũńàŕŕ śōũŕćēś ŷōũŕ ćōńţēńţ. Ḿēďĩà ćàń ćōḿē ƒŕōḿ ŷōũŕ ƒĩĺēśŷśţēḿ ōŕ à ŕēḿōţē śēŕvēŕ, ĺĩķē Ƥĺēx ōŕ ĵēĺĺŷƒĩń. Àţ ĺēàśţ ōńē Ḿēďĩà Śōũŕćē ĩś ńēćēśśàŕŷ ţō ćŕēàţē ćĥàńńēĺś àńď ƥĺàŷ ḿēďĩà ĩń Ţũńàŕŕ.\"],\"hQRttt\":[\"Śũƀḿĩţ\"],\"hQSabA\":[\"ŢŌ\"],\"hXfj39\":[\"Àũďĩō Śàḿƥĺē Ŕàţē\"],\"hXzOVo\":[\"Ńēxţ\"],\"hYgDIe\":[\"Ćŕēàţē\"],\"he3ygx\":[\"Ćōƥŷ\"],\"hehnjM\":[\"Àḿōũńţ\"],\"hhukVU\":[\"Ţŕàśĥēď ĩţēḿś àŕē ĩţēḿś ţĥàţ ŵēŕē ƥŕēvĩōũśĺŷ śćàńńēď, ƀũţ ńōţ ƒōũńď ĩń à ŕēćēńţ śćàń. Ţĥĩś ćōũĺď ƀē ďũē ţō ḿĩśśĩńĝ ƒĩĺēś ōŕ à ḿēďĩà śēŕvēŕ ńō ĺōńĝēŕ ŕēţũŕńĩńĝ ţĥē ĩţēḿ ƒŕōḿ ĩţś ÀƤĨ. Ţĥēśē ĩţēḿś ŵĩĺĺ ƀē ũńƥĺàŷàƀĺē ĩń ćĥàńńēĺś ĩń ţĥēĩŕ ćũŕŕēńţ śţàţē. Ŵĥēń ţĥē ţŕàśĥ ĩś ēḿƥţĩēď, ţĥēĩŕ śƥōţś ĩń ćĥàńńēĺś ŵĩĺĺ ƀē ŕēƥĺàćēď ŵĩţĥ ƒĺēx.\"],\"hjerov\":[\"Ĝũĩďē Śţàŕţ Ţĩḿē\"],\"hlIKor\":[\"Ńōńē:\"],\"hnFEC+\":[\"Ĩńĩţĩàĺ Ďēĺàŷ + Ĩńţēŕvàĺ\"],\"hrdWlG\":[\"Àďď Śĥōŵ\"],\"hvo+jE\":[\"Àďď ƥōĩńţ (%)\"],\"i1+yww\":[\"ƑƑƥŕōƀē vēŕśĩōń 6.0+ ŕēćōḿḿēńďēď. Ćĥēćķ ŷōũŕ ćũŕŕēńţ vēŕśĩōń ĩń ţĥē śĩďēƀàŕ\"],\"i2QuB6\":[\"Ēŕŕōŕ Śćŕēēń\"],\"i9rcQ/\":[\"Ḿōvĩēś\"],\"iH8pgl\":[\"ßàćķ\"],\"iQWhqk\":[\"ƑƑḾƤĒĜ ĩś ĩńśţàĺĺēď. Ďēţēćţēď vēŕśĩōń \",[\"0\"]],\"iTjV+L\":[\"À-Ź (ďēść)\"],\"iXJkMB\":[\"Ćōōĺďōŵń (ś)\"],\"ih+n6S\":[\"Ĺĩńēàŕ\"],\"ihCTE6\":[\"Ēŕŕōŕ ōććũŕŕēď ŵĥĩĺē ĺōàďĩńĝ ćĥàńńēĺś, ƥĺēàśē ţŕŷ àĝàĩń śōōń.\"],\"ihn4zD\":[\"Śēàŕćĥ…\"],\"ilkCYA\":[[\"0\",\"plural\",{\"one\":[\"Śēĺēćţēď Ĩţēḿ\"],\"other\":[\"Śēĺēćţēď Ĩţēḿś\"]}]],\"imrPBy\":[\"Ŵàţēŕḿàŕķ Ĩḿàĝē ŨŔĹ\"],\"isC0OF\":[\"Ũśē ţĥēśē śēţţĩńĝś ţō ōvēŕŕĩďē ĝĺōƀàĺ ƒƒḿƥēĝ śēţţĩńĝś ƒōŕ ţĥĩś ćĥàńńēĺ.\"],\"isRobC\":[\"Ńēŵ\"],\"isyw73\":[\"Àũţō ũśēś ţĥē ţĩḿē ćōńvēńţĩōń ƒōŕ ţĥē śēĺēćţēď ĺàńĝũàĝē.\"],\"jETaUB\":[\"ßũƒƒēŕ śĩźē ēƒƒēćţś ĥōŵ ƒŕēǫũēńţĺŷ ƒƒḿƥēĝ ŕēćōńśĩďēŕś ţĥē ōũţƥũţ ƀĩţŕàţē. <0>Ŕēàď ḿōŕē\"],\"jHjfnS\":[\"Àďď ƒĩĺĺēŕ\"],\"jZlrte\":[\"Ćōĺōŕ\"],\"jl3Q84\":[\"Ćŕēàţē à Ćĥàńńēĺ\"],\"jz1oG0\":[\"Śēĺēćţēď Àũďĩō\"],\"k6TRai\":[\"ƑƑḾƤĒĜ ţŕàńśćōďĩńĝ ĩś ŕēǫũĩŕēď ƒōŕ śōḿē ƒēàţũŕēś ĺĩķē ćĥàńńēĺ ōvēŕĺàŷ, śũƀţĩţĺēś, àńď ḿēàśũŕēś ţō ƥŕēvēńţ ĩśśũēś ŵĥēń śŵĩţćĥĩńĝ ēƥĩśōďēś.\"],\"kAidIP\":[\"Ƒàĩĺēď ţō ĺōàď ƒēàţũŕē ƒĺàĝś.\"],\"kBJRjR\":[\"Ďōŵńĺōàď àĺĺ ĺōĝś\"],\"kIYDzY\":[\"Śũććēśśƒũĺĺŷ ũƥďàţēď Ḿēďĩà Śōũŕćē śēţţĩńĝś.\"],\"kKgsI0\":[\"<0>Ćōńƒĩĝũŕē ţĥē ďĩŕēćţōŕŷ ŵĥēŕē Ţũńàŕŕ ŵŕĩţēś ĤĹŚ śēĝḿēńţ ƒĩĺēś ŵĥēń ţŕàńśćōďĩńĝ. Ţũńàŕŕ ŵĩĺĺ ćŕēàţē ţĥē ţàŕĝēţ ďĩŕēćţōŕŷ (ƀũţ ńōţ ĩńţēŕḿēďĩàţē ďĩŕēćţōŕĩēś) ĩƒ ĩţ ďōēśń'ţ ēxĩśţ.<1/>Ćĥàńĝĩńĝ ţĥĩś ƒĩēĺď ŵĩĺĺ ōńĺŷ àƒƒēćţ ńēŵ śēśśĩōńś. Ēxĩśţĩńĝ śēśśĩōńś ŵĩĺĺ ćōńţĩńũē ŵŕĩţĩńĝ ţō ţĥē ƥŕēvĩōũś śēţţĩńĝ, ƀũţ ŵĩĺĺ ćĺēàń ōũţ śēĝḿēńţś ŵĥēń ţĥē śēĝḿēńţ ēńďś.<2/>Ŵĥēń ũńśēţ, Ţũńàŕŕ ŵĩĺĺ ŵŕĩţē śēĝḿēńţś ţō ĩţś ćũŕŕēńţ ŵōŕķĩńĝ ďĩŕēćţōŕŷ.\"],\"kKk153\":[\"Ĺōàď Śţŕēàḿ\"],\"kO0aVB\":[\"ßŕēàķ Ďũŕàţĩōń (ḿĩńũţēś)\"],\"kThBL9\":[\"Śàḿƥĺē ŕàţē ćàńńōţ ƀē ćĥàńĝēď ŵĥēń ćōƥŷĩńĝ ĩńƥũţ àũďĩō\"],\"kdkZBD\":[\"Ĩńćŕēḿēńţ\"],\"kii1WH\":[\"Ƥŕōĝŕàḿḿĩńĝ Ƥŕēvĩēŵ\"],\"kolyzq\":[\"Ţĥĩś \",[\"0\"],\" ĩś ḿàŕķēď àś ḿĩśśĩńĝ ĩń ţĥē ďàţàƀàśē.\"],\"kpfZ0g\":[\"Ḿĩńĩḿũḿ Ƥŕōĝŕàḿ Ďũŕàţĩōń (ḿĩńũţēś)\"],\"kq6sAD\":[\"Àďď ŢV Śĥōŵś ōŕ Ḿōvĩēś ţō ƒĩĺĺēŕ\"],\"ksFZi3\":[\"<0>Ēxƥēŕĩḿēńţàĺ: Ēńàƀĺē Ƥĺēx Ŕēǫũēśţ Ćàćĥē\"],\"kvMAno\":[\"Ŵēƀ Śēţţĩńĝś\"],\"l/UFPv\":[\"Ƥŕōƥēŕţĩēś\"],\"l0VyMh\":[\"Ƒĺēx\"],\"l15zKW\":[\"Àĺĺ Śēţ!\"],\"lBADOx\":[[\"count\",\"plural\",{\"one\":[\"#\",\" ēƥĩśōďē\"],\"other\":[\"#\",\" ēƥĩśōďēś\"]}]],\"lC2oeQ\":[\"Ḿàx Ďũŕàţĩōń (ḿĩńũţēś)\"],\"lCF0wC\":[\"Ŕēƒŕēśĥ\"],\"lIUgjN\":[\"Ēŕŕōŕ ćōƥŷĩńĝ ćĥàńńēĺ ḿ3ũ ĺĩńķ ţō ćĺĩƥƀōàŕď\"],\"lJSUC1\":[\"Ŵàţēŕḿàŕķ\"],\"lKCfnI\":[\"Àũďĩō Ĺàńĝũàĝē Ƥŕēƒēŕēńćēś\"],\"lS14fB\":[\"Ţĥēḿē Śēţţĩńĝś\"],\"lW3FB1\":[\"Ďōŵńĺōàď ĺàśţ \",[\"0\"],\" \",[\"1\",\"plural\",{\"one\":[\"#\",\" ŕōŵ\"],\"other\":[\"#\",\" ŕōŵś\"]}]],\"lWmRHf\":[\"Ţĩḿē Śĺōţś...\"],\"lZMqZ5\":[\"Ĩƒ ēńàƀĺēď, ŢV śĥōŵ ēƥĩśōďēś ŵĩĺĺ ũśē ţĥē ƥōśţēŕ ōƒ ţĥēĩŕ śĥōŵ, ĩńśţēàď ōƒ ţĥē ĩńďĩvĩďũàĺ ēƥĩśōďē ƥōśţēŕ.\"],\"laQT4o\":[\"Ţĥũḿƀńàĩĺ ŨŔĹ\"],\"lfFsZ4\":[\"Ćĥàńńēĺś\"],\"lkz6PL\":[\"Ďũŕàţĩōń\"],\"llDXYJ\":[\"ßàćķũƥś\"],\"lnABVQ\":[\"Ŕũń Ţŕōũƀĺēśĥōōţēŕ\"],\"m+8qnB\":[\"Ĺĩƀŕàŕŷ: \",[\"0\"]],\"m0Gp21\":[\"Śēĺēćţ à ƥŕōĝŕàḿ àńď ćĥàńńēĺ ţō ţēśţ ƥĺàŷƀàćķ. Ţĥē ţŕōũƀĺēśĥōōţēŕ ŵĩĺĺ àńàĺŷźē śţŕēàḿ śēĺēćţĩōń, ƀũĩĺď ţĥē ƑƑḿƥēĝ ƥĩƥēĺĩńē, àńď ŕũń à śĥōŕţ ţēśţ ţŕàńśćōďē.\"],\"m16xKo\":[\"Àďď\"],\"m48LOH\":[\"Ĥàŕďŵàŕē Àććēĺēŕàţĩōń\"],\"mCB6Je\":[\"Śēĺēćţ Àĺĺ\"],\"mDcLzR\":[\"Ćàćĥĩńĝ\"],\"mF+u2B\":[\"Ďōń'ţ śēē ţĥē ĺĩƀŕàŕŷ ŷōũ ŵàńţ ĥēŕē? Ēńśũŕē ĩţ ĩś ēńàƀĺēď ĩń ţĥē <0>Ḿēďĩà Śōũŕćē Śēţţĩńĝś.\"],\"mGM6Aa\":[\"Ćũśţōḿ Śĥōŵś àŕē śēǫũēńćēś ōƒ vĩďēōś ţĥàţ ŕēƥŕēśēńţ à ēƥĩśōďēś ōƒ à vĩŕţũàĺ ŢV śĥōŵ. Ŵĥēń ŷōũ àďď ţĥēśē śĥōŵś ţō à ćĥàńńēĺ, ţĥē śćĥēďũĺē ţōōĺś ŵĩĺĺ ţŕēàţ ţĥē vĩďēōś àś ĩƒ ţĥēŷ ƀēĺōńĝēď ţō à śĩńĝĺē ŢV śĥōŵ.\"],\"mHTMS1\":[\"Ńōŕḿàĺĩźē Ƒŕàḿē Ŕàţē\"],\"mQt7fl\":[[\"count\",\"plural\",{\"one\":[\"ƥŕōĝŕàḿ\"],\"other\":[\"ƥŕōĝŕàḿś\"]}]],\"mRWiYM\":[\"Ďũŕàţĩōń (śēćōńďś)\"],\"mWbpso\":[\"Ḿàx ßàćķũƥś\"],\"mYBORk\":[\"Ḿōvĩē\"],\"mYJG1x\":[\"Ŷōũŕ ĺĩśţ ŵĩĺĺ ƀē ŕēƥĺĩćàţēď \",[\"0\"],\" ţĩḿēś\"],\"mZFYjJ\":[\"Ēŕŕōŕ śàvĩńĝ ƥŕōĝŕàḿś. \",[\"0\"]],\"mZFr14\":[\"ĤĹŚ ńōţ śũƥƥōŕţēď ĩń ţĥĩś ƀŕōŵśēŕ!\"],\"md42bg\":[\"Ţŕàńśćōďē Ćōńƒĩĝ (ōƥţĩōńàĺ ōvēŕŕĩďē)\"],\"mgcp8D\":[\"Ĥōŵ ōƒţēń ţō ĩńśēŕţ à ƀŕēàķ\"],\"migeCK\":[\"Ƒĩĺţēŕ ŵĥĩćĥ śũƀţĩţĺē ţŕàćķś àŕē ćōńśĩďēŕēď<0/><1>Àńŷ: Àĺĺ śũƀţĩţĺē ţŕàćķś àŕē ćōńśĩďēŕēď <2/><3>Ƒōŕćēď: Ōńĺŷ ćōńśĩďēŕ <4>\\\"ƒōŕćēď\\\"śũƀţĩţĺē ţŕàćķś <5/><6>Ďēƒàũĺţ: Ōńĺŷ ćōńśĩďēŕ ďēƒàũĺţ śũƀţĩţĺē ţŕàćķś <7/><8>Ńōńē: Ďō ńōţ śēĺēćţ àńŷ śũƀţĩţĺēś\"],\"mtQjGe\":[\"Ćōńƒĩĝũŕē śũƀţĩţĺē ƥŕēƒēŕēńćēś. Ƥŕēƒēŕēńćēś àŕē ēvàĺũàţēď ĩń ōŕďēŕ ōƒ ƥŕĩōŕĩţŷ. Ţĥē ƒĩŕśţ ḿàţćĥĩńĝ śũƀţĩţĺē śţŕēàḿ ōń à ƥŕōĝŕàḿ ŵĩĺĺ ƀē ũśēď.\"],\"mvU6s8\":[\"Śōŕţ ŢV Śĥōŵś\"],\"mwtge0\":[\"Śţàŕţēď \",[\"startedAgo\"],\" - \",[\"remainingTime\"],\"ŕēḿàĩńĩńĝ\"],\"n+7HJk\":[\"Ŵĥēń ƒĩĺē ƥàţĥś ōń ţĥē ŕēḿōţē śēŕvēŕ ďĩƒƒēŕ ƒŕōḿ ţĥē ƥàţĥś Ţũńàŕŕ ćàń śēē, ũśē Ƥàţĥ Ŕēƥĺàćēḿēńţś ţō ĩńśţŕũćţ Ţũńàŕŕ ĥōŵ ţō śţŕēàḿ ḿēďĩà ƒŕōḿ ďĩśķ.\"],\"n9nSNJ\":[\"Ţĩḿē ƒōŕḿàţ\"],\"nH6YaM\":[\"Ōţĥēŕ Vĩďēōś\"],\"nSW2Lv\":[[\"days\",\"plural\",{\"one\":[\"#\",\" ďàŷ\"],\"other\":[\"#\",\" ďàŷś\"]}]],\"nV6twc\":[\"Ōŕĝàńĩźē\"],\"nYD/Cq\":[\"Àśćēńďĩńĝ\"],\"nZXc7r\":[\"Ũńĺĩńķ ƒŕōḿ ĝŕōũƥ\"],\"nfAddt\":[\"ƑƑḿƥēĝ Ţŕàńśćōďē Ƥàţĥ\"],\"nfxRnc\":[\"Ţũńàŕŕ ĩś ćũŕŕēńţĺŷ ćōńƒĩĝũŕēď ţō ũśē ţĥē ÀĆ3 àũďĩō ēńćōďēŕ. Ţĥĩś àũďĩō ƒōŕḿàţ ĩś ńōţ śũƥƥōŕţēď ƀŷ ƀŕōŵśēŕś. Ţĥē ŕēśũĺţàńţ śţŕēàḿ ŵĩĺĺ ĺĩķēĺŷ ńōţ ĥàvē àũďĩō ōŕ ŵĩĺĺ ńōţ ƥĺàŷ àţ àĺĺ.\"],\"njIcYs\":[\"Śàvē àś ńēŵ ćōĺĺēćţĩōń…\"],\"ntJ9rt\":[\"ĤĹŚ Ďĩŕēćţ Ōũţƥũţ Ƒōŕḿàţ\"],\"nzDzPp\":[\"ţōĝĝĺē àććēśś ţōķēń vĩśĩƀĩĺĩţŷ\"],\"o0+Ul2\":[\"Àďď Ƒĺēx\"],\"o2Ucvk\":[\"Ĺĩƀŕàŕĩēś\"],\"o6OQlp\":[\"Ēďĩţ Ćĥàńńēĺ\"],\"o7J4JM\":[\"Ƒĩĺţēŕ\"],\"o7Y4WO\":[\"Ēŕŕōŕ śàvĩńĝ ńēŵ Ēḿƀŷ śēŕvēŕ. Śēē ƀŕōŵśēŕ ćōńśōĺē àńď śēŕvēŕ ĺōĝś ƒōŕ ďēţàĩĺś\"],\"oADXRC\":[\"Ćàĺćũĺàţēď \",[\"humanizedDuration\"],\" (\",[\"numShows\"],\" ƥŕōĝŕàḿś) ōƒ ƥŕōĝŕàḿḿĩńĝ ĩń \",[\"duration\"],\"ḿś\"],\"oCHfGC\":[\"Ĺēvēĺ\"],\"oCpfQF\":[\"Ţĥĩś ƒēàţũŕē ĩś ćũŕŕēńţĺŷ ēxƥēŕĩḿēńţàĺ. Ƥŕōćēēď ŵĩţĥ ćàũţĩōń àńď ĩƒ ŷōũ ēxƥēŕĩēńćē àń ĩśśũē, ţŕŷ ďĩśàƀĺĩńĝ ćàćĥĩńĝ.\"],\"oEZmaP\":[[\"count\",\"plural\",{\"one\":[\"#\",\" śēàśōń\"],\"other\":[\"#\",\" śēàśōńś\"]}]],\"oMA2jd\":[\"Ŕēḿōvēś àńŷ śƥēćĩàĺś ƒŕōḿ ţĥē śćĥēďũĺē. Śƥēćĩàĺś àŕē ēƥĩśōďēś ŵĩţĥ śēàśōń '00'.\"],\"oPWgse\":[\"Ḿàxĩḿũḿ ńũḿƀēŕ ōƒ ƀŕēàķś ƥēŕ ƥŕōĝŕàḿ (0 = ũńĺĩḿĩţēď)\"],\"ofUcbc\":[\"Ŕàńďōḿ\"],\"oihuQr\":[\"Ńũḿƀēŕ ōƒ Ŕēƥĺĩćàţĩōńś\"],\"ousf2V\":[\"Ŕàńďōḿ…\"],\"ovBPCi\":[\"Ďēƒàũĺţ\"],\"oxvBx3\":[\"Ĩƒ śēţ, àńŷ ƥŕōĝŕàḿḿĩńĝ ĝŕōũƥ ŵĩţĥ ƒēŵēŕ ēƥĩśōďēś ŵĩĺĺ ƀē ĺōōƥēď ĩń ōŕďēŕ ţō ḿàķē ƥēŕƒēćţĺŷ ēvēń ƀĺōćķś.\"],\"p/78dY\":[\"Ƥōśĩţĩōń\"],\"p/KgUp\":[\"Ţĥē ćĥàńńēĺ'ś ŕēĝũĺàŕ ƥŕōĝŕàḿḿĩńĝ ƀēţŵēēń ţĥē śƥēćĩƒĩēď ĥōũŕś. Ƒĺēx ţĩḿē ŵĩĺĺ ƒĩĺĺ ũƥ ţĥē ŕēḿàĩńĩńĝ ĥōũŕś.\"],\"p04z/V\":[\"# Ƥŕōĝŕàḿś\"],\"p4XZFD\":[\"Ĺōćàĺ Ƥàţĥ\"],\"pDwcFl\":[\"Śàvē Śḿàŕţ Ćōĺĺēćţĩōń\"],\"pKYBXC\":[\"Ĺàśţ Śćĥēďũĺēď Ēxēćũţĩōń\"],\"paEQ75\":[\"\\\"Śţēàĺţĥ\\\" ćĥàńńēĺś àŕē ĥĩďďēń ƒŕōḿ ŢV ĝũĩďēś, śƥōōƒēď ĤĎĤŔ, ḿ3ũ ƥĺàŷĺĩśţ, ēţć. Ţĥē ćĥàńńēĺ ćàń śţĩĺĺ ƀē śţŕēàḿēď ďĩŕēćţĺŷ ōŕ ƀē ũśēď àś à ŕēďĩŕēćţ ţàŕĝēţ.\"],\"pcRxi1\":[\"Ĥōŵ ƒŕēǫũēńţĺŷ ĺĩƀŕàŕĩēś śĥōũĺď ƀē śćàńńēď (śţàŕţĩńĝ ƒŕōḿ ḿĩďńĩĝĥţ).\"],\"pdlmIS\":[\"<0>Ēŕŕōŕ ďēĺēţĩńĝ ƒĩĺĺēŕ ĺĩśţ: \",[\"0\"],\"<1/>Ƥĺēàśē ćōńśĩďēŕ ōƥēńĩńĝ à ƀũĝ ŵĩţĥ ďēţàĩĺś!\"],\"pkERVr\":[\"Ďōŵńĺōàď ĵŚŌŃ\"],\"pqarBu\":[\"Àść\"],\"pvnfJD\":[\"Ďàŕķ\"],\"pwPreK\":[\"Ŕēśţŕĩćţ Ĥōũŕś\"],\"pxh+PI\":[\"ßũĩĺďēŕ\"],\"q6GKgP\":[\"VÀÀƤĨ Ćàƥàƀĩĺĩţĩēś\"],\"q6nlo/\":[\"Śũƀţĩţĺē Àćţĩōń\"],\"q9p3Xw\":[\"ßĩţŕàţē ćàńńōţ ƀē ćĥàńĝēď ŵĥēń ćōƥŷĩńĝ ĩńƥũţ àũďĩō\"],\"qAGp2O\":[\"Ƥŕōćēēď\"],\"qG6T/X\":[\"Àďď Ƥŕōĝŕàḿḿĩńĝ\"],\"qKNcv7\":[\"Ĝēńēŕàţĩńĝ ßũĝ Ŕēƥōŕţ Ĺĩńķ...\"],\"qV9xkb\":[\"Ƥàśśţĥŕōũĝĥ àũďĩō ũńćĥàńĝēď. Ōţĥēŕ śēţţĩńĝś ŵĩĺĺ ńōţ àƥƥĺŷ.\"],\"qiXmlF\":[\"Àďď Ḿēďĩà\"],\"qjW34v\":[\"Ţĥĩś ćĥàńńēĺ ĩś śēţ ũƥ ţō ũśē <0>\",[\"0\"],\"Śĺōţś ƒōŕ ƥŕōĝŕàḿḿĩńĝ. Àńŷ ḿàńũàĺ ćĥàńĝēś ōń ţĥĩś ƥàĝē ŵĩĺĺ ĺĩķēĺŷ ḿàķē ţĥĩś ćĥàńńēĺ śţōƥ àďĥēŕĩńĝ ţō ţĥàţ śćĥēďũĺē.\"],\"qlR1dD\":[\"Ďēĺēţē Ćĥàńńēĺ \\\"\",[\"0\"],\"\\\"?\"],\"qs/mhD\":[\"Ēńśũŕēś ƥŕōĝŕàḿś śţàŕţ ōńĺŷ àţ à ƥàŕţĩćũĺàŕ ĩńţēŕvàĺ ŵĩţĥĩń ţĥē ĥōũŕ. Ţĥĩś ḿàķēś ƒōŕ ńĩćē ĺōōķĩńĝ śćĥēďũĺēś. Ƒĺēx ţĩḿē ĩś śćĥēďũĺēď ţō ƒàćĩĺĩţàţē.\"],\"r3ptXC\":[\"Ḿàńũàĺĺŷ àďď àń àććēśś ţōķēń ƒŕōḿ ŷōũŕ ĵēĺĺŷƒĩń śēŕvēŕ\"],\"r9sc/0\":[\"Ďũŕàţĩōń ḿũśţ ƀē ńũḿēŕĩć\"],\"rAx5u1\":[\"Ēńď Ţĩḿē\"],\"rPEEWz\":[\"Śũććēśśƒũĺĺŷ śàvēď ćōńƒĩĝ!\"],\"rSZlvN\":[\"Ƥŕōĝŕàḿḿĩńĝ Śţàŕţ\"],\"rhEkXj\":[\"Ĥēàď\"],\"rl/8FN\":[\"Ćōḿḿĩţ\"],\"rnbEQB\":[\"Ćōƥŷ Ḿ3Ũ ŨŔĹ\"],\"roIf2/\":[\"Ōń-Ďēḿàńď?\"],\"rtDDIV\":[\"Ēďĩţ Śĺōţ\"],\"ru5qTc\":[\"Ēďĩţ Ḿēďĩà Śōũŕćē\"],\"rx5Ria\":[\"Àĺĺ ĺĩśţś àŕē ũśēď\"],\"rxumR2\":[\"Ḿàţćĥ àńŷ ōƒ\"],\"s2OE0W\":[\"Ēńţēŕ à ńàḿē ƒōŕ ŷōũŕ ĵēĺĺŷƒĩń Śēŕvēŕ\"],\"s4iETe\":[\"Ţŕàńśćōďē Ćōńƒĩĝ\"],\"s6lNC3\":[\"Ƒàĺĺƀàćķ Ḿōďē\"],\"s8zbIS\":[\"Ĩńćĺũďē Śēàśōńś\"],\"sA8Jt7\":[\"Ţĥĩś śĺōţ ŕēƥĺàŷś ćōńţēńţ àĩŕēď ƀŷ ćōńţĩńũē śĺōţś ēàŕĺĩēŕ ĩń ţĥē ƥēŕĩōď.\"],\"sBJ5MF\":[\"Śōũŕćēś\"],\"sNnXh6\":[\"Ōŕďēŕ ōƒ ƥŕōĝŕàḿḿĩńĝ ŵĩţĥĩń ţĥē śĺōţ\"],\"sUtIRs\":[\"àƀōũţ \"],\"sVVcvs\":[\"Ēxƥēŕĩḿēńţàĺ Ƒēàţũŕēś\"],\"sfbjgG\":[\"Àũďĩō Ƒōŕḿàţ\"],\"sxkWRg\":[\"Àďvàńćēď\"],\"sxwNOp\":[\"Ĺōĝś Ďĩŕēćţōŕŷ:\"],\"sztQMJ\":[\"Ƥŕōĝŕàḿś à Ƒĺēx ţĩḿē śĺōţ. Ńōŕḿàĺĺŷ ŷōũ'ď ũśē ƥàď ţĩḿēś, ŕēśţŕĩćţ ţĩḿēś ōŕ àďď ƀŕēàķś ţō àďď à ĺàŕĝē ǫũàńţĩţŷ ōƒ Ƒĺēx ţĩḿēś àţ ōńćē, ƀũţ ţĥĩś ēxĩśţś ƒōŕ ḿōŕē śƥēćĩƒĩć ćàśēś.\"],\"t/YqKh\":[\"Ŕēḿōvē\"],\"t3hvHq\":[\"Śŷńć Ńōŵ\"],\"t5q6kk\":[\"Ƒōŕ ḿōŕē ďēţàĩĺś ōń ḿàńũàĺĺŷ ŕēţŕĩēvĩńĝ à Ƥĺēx ţōķēń, śēē <0>ĥēŕē\"],\"t6+QCF\":[[\"count\"],\" \",[\"programLabel\"],\", \",[\"0\"]],\"t8Hzw3\":[\"Ćŷćĺĩć Śĥũƒƒĺē ŕàńďōḿĺŷ śĥũƒƒĺēś ĝŕōũƥś ōƒ ƥŕōĝŕàḿḿĩńĝ.\"],\"tDuQbQ\":[\"Śţŕēàḿ Ḿōďē\"],\"tEvsql\":[\"Śũƀţĩţĺēś\"],\"tH1aCG\":[\"Vĩďēō ßĩţŕàţē\"],\"tMxWK0\":[\"Àďďś Ƒĺēx ƀŕēàķś àƒţēŕ ēàćĥ ŢV ēƥĩśōďē ōŕ ḿōvĩē ţō ēńśũŕē ţĥàţ ţĥē ƥŕōĝŕàḿ śţàŕţś àţ ōńē ōƒ ţĥē àĺĺōŵēď ḿĩńũţē ḿàŕķś. Ƒōŕ ēxàḿƥĺē, ŷōũ ćàń ũśē ţĥĩś ţō ēńśũŕē ţĥàţ àĺĺ ŷōũŕ ƥŕōĝŕàḿś śţàŕţ àţ ēĩţĥēŕ XX:00 ţĩḿēś ōŕ XX:30 ţĩḿēś. Ŕēḿōvēś àńŷ ēxĩśţĩńĝ Ƒĺēx ƥēŕĩōďś ƀēƒōŕē àďďĩńĝ ţĥē ńēŵ ōńēś. Ţĥĩś ƀũţţōń ḿĩĝĥţ ƀē ďĩśàƀĺēď ĩƒ ţĥē ćĥàńńēĺ ĩś àĺŕēàďŷ ţōō ĺàŕĝē.\"],\"tPGTPB\":[\"Ŕōĺĺ ţĥē ĺōĝ ƒĩĺē ōń à ƒĩxēď śćĥēďũĺē, ŕēĝàŕďĺēśś ōƒ ƒĩĺē śĩźē.\"],\"tRgOE5\":[\"ßàĺàńćē Ƥŕōĝŕàḿḿĩńĝ\"],\"tXkhj/\":[\"Śţàŕţ\"],\"tXub8j\":[\"Ďĩśƥĺàŷ Ŵàţēŕḿàŕķ ōń Ĺēàďĩńĝ Ēďĝē\"],\"tYuxvA\":[\"ƑƑḾƤĒĜ\"],\"tfDRzk\":[\"Śàvē\"],\"tgPwON\":[\"Ōƥēŕàţōŕ\"],\"ti6ugP\":[\"Ēŕŕōŕ ŵĥĩĺē śàvĩńĝ ţŕàńśćōďē ćōńƒĩĝ. Śēē ćōńśōĺē ĺōĝ ƒōŕ ďēţàĩĺś.\"],\"tkDYSE\":[[\"hours\",\"plural\",{\"one\":[\"#\",\" ĥōũŕ\"],\"other\":[\"#\",\" ĥōũŕś\"]}]],\"tlMRNb\":[\"Ţĥē ĺōàďēď vēŕśĩōń ōƒ ţĥē Ţũńàŕŕ ŨĨ ďōēś ńōţ ḿàţćĥ ţĥē śēŕvēŕ. Ŕēĺōàď ţĥē ƀŕōŵśēŕ ţō ĝēţ ţĥē ĺàţēśţ. Ĩƒ ţĥĩś ḿēśśàĝē ƥēŕśĩśţś, ćĺēàŕ ŷōũŕ ƀŕōŵśēŕ ćàćĥē àńď ŕēĺōàď.\"],\"tlNobE\":[\"Ćũśţōḿ Śĥōŵ: \",[\"0\"]],\"tlmh8e\":[\"Àďď àĺĺ śēĺēćţēď ƥŕōĝŕàḿś ţō ćĥàńńēĺ\"],\"tsqRRB\":[[\"0\"],\" Ƥōśţēŕ\"],\"ty8rVI\":[\"Ńōŵ Ƥĺàŷĩńĝ:\"],\"tzwArf\":[\"Vĩēŵ ĩń \",[\"0\"]],\"u+VWhB\":[\"Ćōƥĩēď ţō ćĺĩƥƀōàŕď!\"],\"u+zFIr\":[\"Ŕēśţŕĩćţ śēàŕćĥ ƒĩēĺďś\"],\"uAQUqI\":[\"Śţàţũś\"],\"uHTa9V\":[\"Ţō ũśē Ţũńàŕŕ, ŷōũ ńēēď ţō ƒĩŕśţ ćōńńēćţ à ḿēďĩà śōũŕćē. Ţĥĩś ŵĩĺĺ àĺĺōŵ ŷōũ ţō ƀũĩĺď ćũśţōḿ ćĥàńńēĺś ŵĩţĥ ŷōũŕ ćōńţēńţ.\"],\"uLiDe/\":[\"Ēńàƀĺē ēḿƀēďďēď śũƀţĩţĺē ēxţŕàćţĩōń\"],\"uUTf8r\":[\"Ďēĺēţē Ćũśţōḿ Śĥōŵ \\\"\",[\"0\"],\"\\\"?\"],\"uamufO\":[\"Àďď ŢV Śĥōŵś ōŕ Ḿōvĩēś ţō ƥŕōĝŕàḿḿĩńĝ ĺĩśţ.\"],\"ueG1bp\":[\"Ƥŕōĝŕàḿ Ćōũńţ\"],\"ueLbrY\":[\"Ĩƒ ţŕũē, àďĴũśţĩńĝ ţĥē ŵēĩĝĥţ ōƒ ōńē śĺōţ ŵĩĺĺ śćàĺē ţĥē ŵēĩĝĥţś ōƒ ōţĥēŕ śĺōţś śũćĥ ţĥàţ àĺĺ ŵēĩĝĥţś ţōţàĺ 100%. Ōţĥēŕŵĩśē, ŵēĩĝĥţś ćàń ƀē àďĴũśţēď ƒŕēēĺŷ àńď ţĥē ŵēĩĝĥţ ōƒ ēàćĥ śĺōţ ĩś ōńĺŷ ŕēĺàţĩvē ţō ţĥē ţōţàĺ ŵēĩĝĥţ.\"],\"uixVel\":[\"ßŷ ďēƒàũĺţ, śàvēś ƀàćķũƥś ĩń ţĥē śēŕvēŕ'ś ŕũń ďĩŕēćţōŕŷ, ōŕ, ĩƒ ŕũńńĩńĝ ĩń Ďōćķēŕ, ţō /ćōńƒĩĝ/ţũńàŕŕ/ƀàćķũƥś\"],\"uyR9ei\":[\"ßĺōćķ Śĥũƒƒĺē\"],\"v4nbQ4\":[\"Ĩƒ ńō ḿōŕē ƥŕōĝŕàḿś ćàń ƒĩţ ĩńţō à ďũŕàţĩōń-ƀàśēď śĺōţ, ƒĺēx ţĩḿē ĩś àďďēď ţō ƒĩĺĺ ţĥē ĝàƥ. Ţĥĩś śēţţĩńĝ ďēţēŕḿĩńēś ĥōŵ ƒĺēx ĩś àďďēď <0>ŵĩţĥĩń ţĥē śĺōţ ţō ēńśũŕē àĺĺ ţĩḿē ĩś ƒĩĺĺēď.<1/><2>ßēţŵēēń: Ƒĺēx ţĩḿē ĩś àďďēď ƀēţŵēēń vĩďēōś ŵĩţĥĩń à śĺōţ, ĩƒ ţĥēŕē àŕē ḿũĺţĩƥĺē<3/><4>Ēńď: Ƒĺēx ţĩḿē ĩś àďďēď àţ ţĥē ēńď ōƒ ţĥē śĺōţ\"],\"v5IstB\":[\"àƒţēŕ ēvēŕŷ ƥŕōĝŕàḿ\"],\"v5URfV\":[\"Ĺĩķē Ŕàńďōḿ Śĥũƒƒĺē, ƀũţ ţŕĩēś ţō ƥŕēśēŕvē ţĥē śēǫũēńćē ōƒ ēƥĩśōďēś ƒōŕ ēàćĥ ŢV śĥōŵ. Ĩƒ à ŢV śĥōŵ ĥàś ḿũĺţĩƥĺē ĩńśţàńćēś ōƒ ĩţś ēƥĩśōďēś, ţĥēŷ àŕē àĺśō ćŷćĺēď àƥƥŕōƥŕĩàţēĺŷ.\"],\"vAK/B1\":[\"Àũďĩō Àćţĩōń\"],\"vCBet9\":[\"Ńōţ à vàĺĩď ńũḿƀēŕ\"],\"vERlcd\":[\"Ƥŕōƒĩĺē\"],\"vGRvxs\":[\"Ćĥàńńēĺ ĝŕōũƥ ĩś ŕēǫũĩŕēď\"],\"vLf7qg\":[\"Ĩńţēŕvàĺ (ḿĩńũţēś)\"],\"vSJd18\":[\"Vĩďēō\"],\"vU/Hht\":[\"Ďĩśţŕĩƀũţĩōń\"],\"vXIe7J\":[\"Ĺàńĝũàĝē\"],\"vcvFVw\":[\"Ēśćàƥē Ĥàţćĥēś\"],\"vkA4W/\":[\"Śōũŕćē Ţŷƥē\"],\"vn3SVH\":[\"Ćōũĺď ńōţ ƥàŕśē ţĥĩś ƒĩĺţēŕ ēxƥŕēśśĩōń. Ćĥēćķ ţĥē <0>ďōćũḿēńţàţĩōń ƒōŕ ĩńƒōŕḿàţĩōń àƀōũţ ƒĩĺţēŕ ēxƥŕēśśĩōńś.\"],\"vreTxe\":[[\"count\",\"plural\",{\"one\":[\"#\",\" ƥŕōĝŕàḿ\"],\"other\":[\"#\",\" ƥŕōĝŕàḿś\"]}]],\"vwFKu0\":[\"Ćàśţ & Ćŕēŵ\"],\"vyL1gO\":[\"Ŕēĺēàśē Ďàţē (ďēść)\"],\"w/bY7R\":[\"Ĺōĝś\"],\"w2pCRr\":[\"Śĥōŵ:\"],\"w3KBq0\":[\"Àĺĺōŵś ƥŕōĝŕàḿś ţō ƥĺàŷ à ƀĩţ ĺàţē ĩƒ ţĥē ƥŕēvĩōũś ƥŕōĝŕàḿ ţōōķ ĺōńĝēŕ ţĥàń ũśũàĺ. Ĩƒ à ƥŕōĝŕàḿ ĩś ţōō ĺàţē, Ƒĺēx ĩś śćĥēďũĺēď ĩńśţēàď.\"],\"w3g+lo\":[\"Ĺēţ'ś ĝēţ śţàŕţēď...\"],\"wBmIEf\":[\"Ńũḿƀēŕ ōƒ ĥōũŕś ţō ĩńćĺũďē ĩń ţĥē XḾĹŢV ƒĩĺē\"],\"wBo/7A\":[\"Ēŕŕōŕ ŵĥĩĺē śćĥēďũĺĩńĝ \",[\"taskId\"],\". Ćĥēćķ śēŕvēŕ ĺōĝś ƒōŕ ďēţàĩĺś\"],\"wKClDM\":[\"Àďďś à ćĥàńńēĺ ŕēďĩŕēćţ. Ďũŕĩńĝ ţĥĩś ƥēŕĩōď ōƒ ţĩḿē, ţĥē ćĥàńńēĺ ŵĩĺĺ ŕēďĩŕēćţ ţō àńōţĥēŕ ćĥàńńēĺ.\"],\"wMHvYH\":[\"Vàĺũē\"],\"wOUKOZ\":[\"Ḿàx Ţŕũē Ƥēàķ\"],\"wZOYCY\":[\"Vĩďēō Ƒōŕḿàţ\"],\"wdfBIP\":[\"Śōŕţ ßŷ...\"],\"wdxz7K\":[\"Śōũŕćē\"],\"wkQ2tb\":[\"Àďďś Ƒĺēx ƀŕēàķś àƒţēŕ ēàćĥ ŢV ēƥĩśōďē ōŕ ḿōvĩē ţō ēńśũŕē ţĥàţ ţĥē ƥŕōĝŕàḿ śţàŕţś àţ ōńē ōƒ ţĥē àĺĺōŵēď ḿĩńũţē ḿàŕķś.\"],\"wlYdUk\":[[\"count\",\"plural\",{\"one\":[\"ĥōũŕ\"],\"other\":[\"ĥōũŕś\"]}]],\"wpT1VN\":[\"Ćōńďĩţĩōń\"],\"wtuVU4\":[\"Ƒŕēǫũēńćŷ\"],\"wwu18a\":[\"Ĩćōń\"],\"x+AjXa\":[\"Ćĥàńńēĺ Ƒàĺĺƀàćķ\"],\"x/dwZe\":[\"Ēńàƀĺē ĩƒ ţĥē ŵàţēŕḿàŕķ ĩś àń àńĩḿàţēď ĜĨƑ ōŕ ƤŃĜ. Ţĥē ŵàţēŕḿàŕķ ŵĩĺĺ ĺōōƥ àććōŕďĩńĝ ţō ţĥē ĩḿàĝē'ś ćōńƒĩĝũŕàţĩōń. Ĩƒ ţĥĩś ōƥţĩōń ĩś ēńàƀĺēď àńď ţĥē ĩḿàĝē ĩś ńōţ àńĩḿàţēď, ţĥēŕē ŵĩĺĺ ƀē ƥĺàŷƀàćķ ēŕŕōŕś.\"],\"x1tGMH\":[\"Ōvēŕŕĩďē ĥōŵ ƥŕōĝŕàḿś ŵĩţĥĩń ţĥĩś śĺōţ àŕē ƥàďďēď.\"],\"x6/Zc6\":[\"Ţàĩĺ\"],\"x63PSs\":[\"Śēàŕćĥ ƒōŕ śĥōŵś\"],\"x7PDL5\":[\"Ĺōĝĝĩńĝ\"],\"xCJdfg\":[\"Ćĺēàŕ\"],\"xDAtGP\":[\"Ḿēśśàĝē\"],\"xDPFrK\":[\"Śćàń \",[\"0\"]],\"xGVfLh\":[\"Ćōńţĩńũē\"],\"xGYZfl\":[\"Ēďĩţ Ĺĩƀŕàŕĩēś\"],\"xIn7qU\":[\"Ďĩśàƀĺē Ĥàŕďŵàŕē Ďēćōďĩńĝ\"],\"xJIepX\":[\"Ďēƒàũĺţ Ćōńƒĩĝ\"],\"xOkMus\":[\"Ĥàŕďŵàŕē Àććēĺ.\"],\"xPmesF\":[\"Ĺōũďńēśś Ŕàńĝē Ţàŕĝēţ\"],\"xQC5se\":[\"Àďvàńćēď Vĩďēō Ōƥţĩōńś\"],\"xXrtPO\":[\"Ƒàĩĺēď ţō ĺōàď ĩţēḿ ďēţàĩĺś! Ćĥēćķ ĺōĝś ƒōŕ ďēţàĩĺś\"],\"xazqmy\":[\"Śēàśōńś\"],\"xbtgIC\":[\"ĤŴ Àććēĺēŕàţĩōń\"],\"xdA/+p\":[\"Ţōōĺś\"],\"xmBknQ\":[\"Ƒĩĺĺēŕ Ĺĩśţś\"],\"xptXTM\":[\"Śēĺēćţ Àŕţĩśţś ţō Ŕēḿōvē\"],\"xqIrnW\":[\"Ĺĩƀŕàŕŷ Ćĺĩƥ (ńōţ ŷēţ ĩḿƥĺēḿēńţēď)\"],\"xu3Kah\":[[\"0\",\"plural\",{\"one\":[\"#\",\" ƥŕōĝŕàḿ\"],\"other\":[\"#\",\" ƥŕōĝŕàḿś\"]}]],\"y28hnO\":[\"Ƥōśţ\"],\"y4Jmre\":[\"ßŕēàķ Ďũŕàţĩōń\"],\"y4iKY3\":[[\"count\",\"plural\",{\"one\":[\"#\",\" àĺƀũḿ\"],\"other\":[\"#\",\" àĺƀũḿś\"]}]],\"y5x0aB\":[[\"0\"],\" Ĩńƒō\"],\"y7wpam\":[[\"value\",\"plural\",{\"one\":[\"#\",\" ƥŕōĝŕàḿ\"],\"other\":[\"#\",\" ƥŕōĝŕàḿś\"]}]],\"yDUcwc\":[\"Ḿàńũàĺĺŷ àďď àń àććēśś ţōķēń ƒŕōḿ ŷōũŕ Ēḿƀŷ śēŕvēŕ\"],\"yPE51X\":[\"Ćōńƒĩĝũŕē ţŕàńśćōďĩńĝ śēţţĩńĝś ƒōŕ Ţũńàŕŕ'ś śţŕēàḿś. Ēàćĥ ćĥàńńēĺ ĩś àśśĩĝńēď ōńē ţŕàńśćōďē ćōńƒĩĝũŕàţĩōń.\"],\"yPK7+5\":[\"Àũţō-Ũƥďàţē Ĝũĩďē\"],\"yQE2r9\":[\"Ĺōàďĩńĝ\"],\"yRkqG9\":[\"Ĺĩḿĩţ\"],\"yX8Rkw\":[\"Àďď Àĺĺ\"],\"yftDqj\":[\"Ńēŵ Ƒĩĺĺēŕ Ĺĩśţ\"],\"yjzkvk\":[\"Śţōƥ Ţŕàńśćōďē Śēśśĩōń\"],\"ysJk7v\":[\"Ḿōvĩē Śōŕţ Ōŕďēŕ\"],\"ysecYP\":[\"Śēàŕćĥ ƒōŕ à ƥŕōĝŕàḿ\"],\"ytXxnP\":[\"Ƒōŕćēď\"],\"yz/C2/\":[\"Ŕēŕũń\"],\"yz7wBu\":[\"Ćĺōśē\"],\"z4K9d+\":[\"Ŕōĺĺ ƀàśēď ōń śĩźē\"],\"z61uNR\":[\"Àďď Ƒĺēx Ţĩḿē\"],\"zV6tsp\":[\"Ćōńśōĺĩďàţē\"],\"zV9awV\":[\"Ƒōŕćē Śćàń\"],\"zpylsE\":[\"Ţŕàńśćōďĩńĝ Śēţţĩńĝś\"],\"zrmjn/\":[\"Ḿàx Ďũŕàţĩōń\"],\"zthKEs\":[\"Ţĥē śţŕēàḿĩńĝ ḿōďē àƒƒēćţś ţĥē ţŷƥē ōƒ ũńďēŕĺŷĩńĝ ţŕàńśćōďĩńĝ ƥŕōćēśś ũśēď ţō ćŕēàţē ţĥē ćĥàńńēĺ'ś vĩďēō śţŕēàḿ.<0/>Ĺēàŕń ḿōŕē àƀōũţ Ţũńàŕŕ'ś śţŕēàḿ ḿōďēś <1>ĥēŕē!\"],\"zvjEp6\":[\"Ƒĩĺĺēŕ ćōōĺďōŵń ḿũśţ ƀē à ńũḿƀēŕ\"],\"zx4BuL\":[\"Ŵēēķ\"],\"zyLvkd\":[\"Ćàţēĝōŕŷ Ĺōĝ Ĺēvēĺś\"]}")as Messages; \ No newline at end of file + import type { Messages } from '@lingui/core'; +export const messages = JSON.parse( + '{"++nzCr":["ßĩţ Ďēƥţĥ"],"+2JHIs":["Ĺĩńķ ţō ēxĩśţĩńĝ śĺōţ"],"+406Vu":["Vĩēŵ Ƒũĺĺ Ďēţàĩĺś"],"+4YwQF":["# ōƒ Ƥŕōĝŕàḿś"],"+4mjS6":["Ŕēḿōvē ĩćōń"],"+9EErD":["Ḿũśĩć Vĩďēōś"],"+DmLct":["Ƥŕōĝŕàḿś"],"+SA5Ao":["À ŕōōţ ƥàţĥ ţō śćàń ƒōŕ ḿēďĩà. Ĺōćàĺ śōũŕćēś ćàń śēàŕćĥ ḿàńŷ ďĩƒƒēŕēńţ ƥàţĥś."],"+TZiPJ":["Śēŕvēŕ ĩś ũńŕēàćĥàƀĺē"],"+UPOiB":[["count","plural",{"one":["ḿĩń"],"other":["ḿĩńś"]}]],"+Xg5cX":["Ƒĩĺĺēŕ ĩś ƥĩćķēď ƒŕēśĥ àţ śţŕēàḿ ţĩḿē ĺĩķē Ƒĺēx ţĩḿē. Ţĥē ĝũĩďē śĥōŵś \\"Ćōḿḿēŕćĩàĺ ßŕēàķ\\" ƥĺàćēĥōĺďēŕś."],"+YdE7b":["Ēńàƀĺē ŕōĺĺĩńĝ ĺōĝ ƒĩĺēś ũśĩńĝ ţĩḿē àńď/ōŕ śĩźē ƀàśēď ćŕĩţēŕĩà"],"+hl/7A":["Ćĥàńńēĺś ćōńƒĩĝũŕēď ţō ũśē ţĥē ĤĹŚ Ďĩŕēćţ śţŕēàḿ ḿōďē ŵĩĺĺ ōũţƥũţ ĩń ţĥē śēĺēćţēď ćōńţàĩńēŕ ƒōŕḿàţ."],"+k9lxR":["Ēńţēŕ à ńàḿē ƒōŕ ŷōũŕ Ĺōćàĺ Ḿēďĩà Śōũŕćē"],"+mdNfU":[["count","plural",{"one":["#"," ţŕàćķ"],"other":["#"," ţŕàćķś"]}]],"+suWTj":["Àďďś Ƒĺēx ƀŕēàķś ƀēţŵēēń ƥŕōĝŕàḿś, àţţēḿƥţĩńĝ ţō àvōĩď ĝŕōũƥś ōƒ ćōńśēćũţĩvē ƥŕōĝŕàḿś ţĥàţ ēxćēēď ţĥē śƥēćĩƒĩēď ńũḿƀēŕ ōƒ ḿĩńũţēś."],"+tlhMz":["Ƥĺēx (Ḿàńũàĺ)"],"+yEE7s":["Ńēŵ Ḿēďĩà Śōũŕćē"],"+yOcRn":["ĤĎĤŔ"],"+ya1pX":["Ďēĺēţē Śĺōţ"],"+zY9Xc":["Ćōńƒĩĝũŕē Ćŷćĺĩć Śĥũƒƒĺē"],"+zy2Nq":["Ţŷƥē"],"/+ZaFm":["Śōũńďţŕàćķ"],"/4gGIX":["Ćōƥŷ ţō ćĺĩƥƀōàŕď"],"/6iIT9":["Śēţţĩńĝś Śàvēď!"],"/DTWjr":["Ćōńĝŕàţś, ŷōũ\'ŕē ŕēàďŷ ţō śţàŕţ ƀũĩĺďĩńĝ ćĥàńńēĺś! ĵũśţ ćĺĩćķ Ƒĩńĩśĥ ƀēĺōŵ ţō śţàŕţ ŵōŕķĩńĝ ōń ŷōũŕ ƒĩŕśţ ćĥàńńēĺ."],"/QmYEW":["ßàĺàńćē..."],"/TEOcd":["Ƥŕēśēţś"],"/e88IO":["Śćĥēďũĺē ƥŕōĝŕàḿḿĩńĝ ĩń ƀĺōćķś ţĥàţ àŕē ēĩţĥēŕ ćōũńţ ōŕ ďũŕàţĩōń ƀàśēď. Ćàń ƀē ũśēď ţō ĝēńēŕàţē ŕàńďōḿ śćĥēďũĺēś."],"/gavzH":["ßàśĩć ƀũţţōń ĝŕōũƥ"],"/j3jjC":["Ēŕŕōŕ ŵĥĩĺē śàvĩńĝ śēţţĩńĝś. Ƥĺēàśē ćĥēćķ ćōńśōĺē ƒōŕ ďēţàĩĺś."],"/n/HCO":["Ķēŷŵōŕďś"],"/rTz0M":["Àũďĩō"],"/vJase":["Śţŕēàḿĩńĝ"],"09gg05":["Ƥŕōĝŕàḿḿĩńĝ"],"0IAEaX":["Ḿàţćĥ"],"0MWZh1":["Śēàŕćĥ ĩś ćũŕŕēńţĺŷ śćōƥēď ţō ţĥĩś Ḿēďĩà Śōũŕćē Ĺĩƀŕàŕŷ."],"0VHz2s":["Ƒĩĺĺēŕ Ōƥţĩōńś"],"0cULRy":["Ēxƥēŕĩḿēńţàĺ: Ḿàķē ƥēŕƒēćţ śćĥēďũĺē ĺōōƥ"],"0dy9K6":["Ŕēàď Ĺēśś"],"0mEBXY":["Ďēĺēţē Ţŕàńśćōďĩńĝ Ćōńƒĩĝ \\"",["0"],"\\"?"],"0wJVK+":["ßàśĩć"],"0zpgxV":["Ōƥţĩōńś"],"1/dAym":["Ĝŕōũƥĩńĝ ŵōŕķś àś ƒōĺĺōŵś:"],"14PdY0":["Ćōńƒĩĝ"],"1AdBl9":["ßŕēàķ Ƥōśĩţĩōńĩńĝ"],"1BDPP1":["Ĺōōķś ĺĩķē śōḿēţĥĩńĝ ŵēńţ ŵŕōńĝ."],"1BGQfg":["Àĺƥĥàƀēţĩćàĺĺŷ"],"1CFAQ+":["Śēţ ƀŷ ēńvĩŕōńḿēńţ vàŕĩàƀĺē"],"1DxLRi":["Ńō ƥŕōĝŕàḿḿĩńĝ śćĥēďũĺēď ƒōŕ ţĥĩś ţĩḿē ƥēŕĩōď"],"1PQRWr":["Śţàŕţ Ţĩḿē"],"1QfxQT":["Ďĩśḿĩśś"],"1TYXl0":["Ēńţēŕ ŷōũŕ Ēḿƀŷ ƥàśśŵōŕď ţō ĝēńēŕàţē à ńēŵ àććēśś ţōķēń."],"1V3Prt":["Ďēĺēţĩńĝ à Ƒĩĺĺēŕ ŵĩĺĺ ŕēḿōvē àĺĺ ƥŕōĝŕàḿḿĩńĝ ƒŕōḿ ţĥē ćĥàńńēĺ. Ţĥĩś àćţĩōń ćàńńōţ ƀē ũńďōńē."],"1Z90J4":["Ďàŷś ţō Ƥŕēćàĺćũĺàţē"],"1hKEom":["Ƥŕĩōŕĩţŷ"],"1jqDmP":["Śũććēśśƒũĺĺŷ śćĥēďũĺēď ",["taskId"]," (ŕũńńĩńĝ ĩń ƀàćķĝŕōũńď)."],"1njn7W":["Ĺĩĝĥţ"],"2BBAbc":["Ĺĩśţ"],"2BRPyl":["Śŷśţēḿ Ĩńƒō"],"2CVuYr":["Śḿàŕţ Ćōĺĺēćţĩōń - ",["0"]],"2L7cj6":["Ŷōũ ĥàvēń\'ţ ćŕēàţēď àńŷ ćĥàńńēĺś ŷēţ."],"2QLniG":["Ēxĩśţĩńĝ ǫũēŕŷ: ",["filterString"]],"2eFlmt":["Ţŕàćķś"],"2hOCU2":["Śḿàŕţ Ćōĺĺēćţĩōńś"],"2imNg3":["Ŵēƀ vēŕśĩōń = ",["0"],", Śēŕvēŕ vēŕśĩōń = ",["1"]],"2mAJXf":["Ḿàķēś ḿũĺţĩƥĺē ćōƥĩēś ōƒ ţĥē śćĥēďũĺē àńď ƥĺàŷś ţĥēḿ ĩń śēǫũēńćē. Ńōŕḿàĺĺŷ ţĥĩś ĩśń\'ţ ńēćēśśàŕŷ, ƀēćàũśē Ţũńàŕŕ ŵĩĺĺ àĺŵàŷś ƥĺàŷ ţĥē śćĥēďũĺē ƀàćķ ƒŕōḿ ţĥē ƀēĝĩńńĩńĝ ŵĥēń ĩţ ƒĩńĩśĥēś. ßũţ ćŕēàţĩńĝ ŕēƥĺĩćàś ĩś à ũśēƒũĺ ĩńţēŕḿēďĩàŕŷ śţēƥ śōḿēţĩḿēś ƀēƒōŕē àƥƥĺŷĩńĝ ōţĥēŕ ţŕàńśƒōŕḿàţĩōńś. Ńōţē ţĥàţ ƀēćàũśē vēŕŷ ĺàŕĝē ćĥàńńēĺś ćàń ƀē ƥŕōƀĺēḿàţĩć, ţĥē ńũḿƀēŕ ōƒ ŕēƥĺĩćàś ŵĩĺĺ ƀē ĺĩḿĩţēď ţō àvōĩď ćŕēàţĩńĝ ŕēàĺĺŷ ĺàŕĝē ćĥàńńēĺś."],"2oWehJ":["Ŕēśēţ ţō ćũŕŕēńţ ďàţē/ţĩḿē"],"2vxecF":["Śĥōŵ Śţēàĺţĥ"],"2x4THe":["\\"",["0"],"\\" Śēśśĩōńś"],"312fSE":["Śēĺēćţ Śĥōŵś ţō Ŕēḿōvē"],"315BhT":["Àĺƥĥàƀēţĩćàĺ"],"3JIYke":["Ĥēàĺţĥŷ?"],"3JQkm5":["Ƥàţĥ Ŕēƥĺàćēḿēńţś"],"3JjdaA":["Ŕũń"],"3LfNqe":["Ćĥàńńēĺ Ńũḿƀēŕ"],"3SH6Vv":["Ćōƥĩēď ćĥàńńēĺ \\"",["channelName"],"\\" ḿ3ũ ĺĩńķ ţō ćĺĩƥƀōàŕď"],"3YNjnA":["Śŷśţēḿ Ēńvĩŕōńḿēńţ"],"3b1vGb":["Ńēŵ Ĺōćàĺ Ḿēďĩà Śōũŕćē"],"3mAQJI":["Ĥōŵ ōƒţēń ţĥē XḾĹŢV ƒĩĺē ĩś ŕēĝēńēŕàţēď"],"3nLdaX":["Àďď ",["0"]],"3nwcC5":["Ƒĩĺĺēŕ - ",["0"]],"49dCCB":["Ũśē Śĥōŵ Ƥōśţēŕ"],"4Fpcxu":["Ĩńĩţĩàĺ Ďēĺàŷ (ḿĩńũţēś)"],"4NbDEd":["Ďēĺēţĩńĝ à Ćũśţōḿ Śĥōŵ ŵĩĺĺ ŕēḿōvē ĩţś ƥŕōĝŕàḿḿĩńĝ ƒŕōḿ ćĥàńńēĺś ţĥàţ ũśē ĩţ. Ţĥĩś àćţĩōń ćàńńōţ ƀē ũńďōńē."],"4Uc/2h":["Śēŕvēŕ Ĺĩśţēń Ƥōŕţ"],"4VxpoP":["Ḿũśĩć ţŕàćķś àŕē ĝŕōũƥēď ƀŷ àŕţĩśţ"],"4XSc4l":["Ŵēēķĺŷ"],"4XfYeY":["Ŕàńďōḿ (ƀŷ śĥōŵ)"],"4fLgiT":["Àĺĺōŵ Ĩḿàĝē ßàśēď"],"4qmJK4":["Ţũńàŕŕ ßàćķēńď ŨŔĹ"],"4wkwyL":["Ďĩśàƀĺē Ĥàŕďŵàŕē Ƒĩĺţēŕś"],"4yQF++":["Ćũśţōḿ śĥōŵ ƥŕōĝŕàḿś àŕē ĝŕōũƥēď ƀŷ ţĥēĩŕ ƥàŕēńţ śĥōŵ"],"50whWJ":["XḾĹŢV Ĺĩńķ:"],"53/4tH":["Àũďĩō Ōƥţĩōńś"],"536Xwe":["Ēŕŕōŕ ćōƥŷĩńĝ ţō ćĺĩƥƀōàŕď!"],"53tfay":["Ţĥĩś àĺĺōŵś ţō śćĥēďũĺē śƥēćĩƒĩć śĥōŵś ţō ŕũń àţ śƥēćĩƒĩć ţĩḿē śĺōţś ōƒ ţĥē ďàŷ ōŕ à ŵēēķ. Ĩţ\'ś ŕēćōḿḿēńďēď ŷōũ ƒĩŕśţ ƥōƥũĺàţē ţĥē ćĥàńńēĺ ŵĩţĥ ţĥē ēƥĩśōďēś ƒŕōḿ ţĥē śĥōŵś ŷōũ ŵàńţ ţō ƥĺàŷ àńď/ōŕ ōţĥēŕ ćōńţēńţ ĺĩķē ḿōvĩēś àńď ŕēďĩŕēćţś."],"5ABghp":["ƑƑḿƥēĝ Śēţţĩńĝś"],"5V93hk":["Śćĥēďũĺē ƥŕōĝŕàḿḿĩńĝ ũśĩńĝ śĺōţś àśśĩĝńēď à śţàŕţ ţĩḿē àńď ďũŕàţĩōń."],"5WeWGz":["Śēĺēćţēď Śũƀţĩţĺē"],"5jWg+L":["Ţũńàŕŕ ŵĩĺĺ àţţēḿƥţ ţō ĝēţ Ƥĺēx ţō ƥũĺĺ Ţũńàŕŕ\'ś ũƥďàţēď XḾĹŢV ũƥōń ŕēĝēńēŕàţĩōń"],"5k0NLb":["Ŕēvĩēŵ"],"5lSgNP":["Ēńàƀĺē ŚŚĎƤ śēŕvēŕ"],"5nsbxB":["Àĺţēŕńàţēś ŢV śĥōŵś ĩń ƀĺōćķś ōƒ ēƥĩśōďēś. Ŷōũ ćàń ƥĩćķ ţĥē ńũḿƀēŕ ōƒ ēƥĩśōďēś ƥēŕ śĥōŵ ĩń ēàćĥ ƀĺōćķ àńď ĩƒ ţĥē ōŕďēŕ ōƒ śĥōŵś ĩń ēàćĥ ƀĺōćķ śĥōũĺď ƀē ŕàńďōḿĩźēď. Ḿōvĩēś àŕē ḿōvēď ţō ţĥē ƀōţţōḿ."],"5qV3NN":["Ƒĺēx Śţŷĺē"],"5yIPLp":["Ōōƥś!"],"6/dCYd":["Ōvēŕvĩēŵ"],"63/DSM":["Ţŕàńśćōďĩńĝ Ćōńƒĩĝś"],"63driG":["Śţŕēàḿ ĵŚŌŃ"],"67RoFa":["Ƥĩƥēĺĩńē"],"6Y9c2m":["Ţĥĩś śĺōţ ĩś ĺĩńķēď ŵĩţĥ ",["0"]," ōţĥēŕ śĺōţ(ś). Ćōńţēńţ ƒĩēĺďś àŕē śĥàŕēď àćŕōśś ţĥē ĝŕōũƥ."],"6YtxFj":["Ńàḿē"],"6ZMWKw":["XḾĹŢV"],"6bbWRs":["Àďď ƥŕōĝŕàḿḿĩńĝ ţō ćũśţōḿ śĥōŵ"],"6dvIbw":["Ũńĺĩńķ"],"6jAi8c":["Ŕàńĝē"],"6jfS51":["Ŵēĺćōḿē"],"6ki7F2":[["0","plural",{"one":["#"," ĩţēḿ"],"other":["#"," ĩţēḿś"]}]],"6mJ9tF":["ƑƑḾƤĒĜ ĩś ńōţ ďēţēćţēď."],"6mpwdR":["Ḿàţćĥ àĺĺ ōƒ"],"6pL6be":["Ćōńƒĩĝũŕē ŵĥàţ àƥƥēàŕś ōń ŷōũŕ ćĥàńńēĺ ŵĥēń ţĥēŕē ĩś ńō śũĩţàƀĺē ƒĩĺĺēŕ ćōńţēńţ àvàĩĺàƀĺē. Ũśĩńĝ ćĥàńńēĺ ƒàĺĺƀàćķś ŕēǫũĩŕēś ƒƒḿƥēĝ ţŕàńśćōďĩńĝ."],"6w0yiE":["ƑƑḾƤĒĜ Ĺōĝ Ĺēvēĺ"],"6zfUar":["Śţŕēàḿ Śēĺēćţĩōń"],"71O7b0":["Ḿēďĩà Ĩńƒō"],"73XwX0":["Ńō ƥŕōĝŕàḿś śēĺēćţēď"],"73flfT":["ǪŚV Ďēvĩćē"],"7B3lfh":["Ĩţēḿś ƒŕōḿ àńŷ ƒĩĺĺēŕ ĺĩśţ ŵĩĺĺ ńōţ ƀē ćĥōśēń ḿōŕē ƒŕēǫũēńţĺŷ ţĥàń ţĥĩś ćōōĺďōŵń śēţţĩńĝ."],"7LWPgS":["Ēńàƀĺēď (ĺōũďńōŕḿ)"],"7ODkf5":["Ĺōĝ ĺēvēĺ ţō ƥàśś ţō ƒƒḿƥēĝ. Ŕēàď ḿōŕē àƀōũţ ƒƒḿƥēĝ\'ś ĺōĝ ĺēvēĺś <0>ĥēŕē"],"7Q5AKf":[["count","plural",{"one":["ţŕàćķ"],"other":["ţŕàćķś"]}]],"7b2stB":["Ḿēďĩà Ţŷƥē"],"7eMo+U":["Ĝō Ĥōḿē"],"7eZlTH":["Śōŕţ ŢV Śĥōŵś (àść)"],"7iJlKU":["Ƥĺēàśē ćĥōōśē à vàĺũē ĝŕēàţēŕ ţĥàń 1"],"7pMNGK":["Ƥŕōĝŕàḿś śàvēď!"],"7sNhEz":["Ũśēŕńàḿē"],"7tvV2B":["Ḿĩń Ďũŕàţĩōń (ḿĩńũţēś)"],"7uohY3":["ŢV śĥōŵś àŕē ĝŕōũƥēď ƀŷ śĥōŵ"],"80t7Ii":["Ĩńćŕēàśĩńĝ \\"Ḿàx Ĺàţēńēśś\\" ƒōŕ ţĥē śćĥēďũĺē."],"87a/t/":["Ĺàƀēĺ"],"8E9KXK":["Ƒēàţũŕē ƒĺàĝś śàvēď!"],"8MIU1T":["Ƥŕōĝŕàḿ"],"8TMaZI":["Ţĩḿēśţàḿƥ"],"8ZsakT":["Ƥàśśŵōŕď"],"8vETh9":["Śĥōŵ"],"8wngZM":["Ƒàĺĺƀàćķ"],"8wu9lr":["Ǫũēũēď"],"9+90+V":["Ēńàƀĺē Ĺōĝ Ƒĩĺē Ŕōĺĺĩńĝ"],"94qSvE":["Śŷńćēď ŵĩţĥ ēxţēŕńàĺ ƥĺàŷĺĩśţ"],"96zw7M":["Ţĥĩś śĥōŵ ĩś ḿàŕķēď àś ḿĩśśĩńĝ ĩń ţĥē ďàţàƀàśē."],"983IRa":["Àĺĺ ĺĩńķēď śĺōţś śĥōŵ ţĥē śàḿē ēƥĩśōďē, àďvàńćĩńĝ ōńĺŷ àƒţēŕ àĺĺ ĥàvē ƥĺàŷēď."],"9E+eyD":["Ōũţƥũţ vĩďēō àţ à ćōńśţàńţ ƒŕàḿē ŕàţē."],"9E9tRC":["Ƒĩĺĺ ŵĩţĥ Ƒĺēx"],"9Eq43e":["Ĩƒ śēţ, àĺĺ ŵàţēŕḿàŕķ ōvēŕĺàŷś ŵĩĺĺ ƀē ďĩśàƀĺēď ƒōŕ ćĥàńńēĺś àśśĩĝńēď ţĥĩś ţŕàńśćōďē ćōńƒĩĝ."],"9GPYnX":["Ďō ńōţ ĝŕōũƥ ƥŕōĝŕàḿś àţ àĺĺ. Ńōŕḿàĺ śĥũƒƒĺē."],"9WG5wy":["Śƥēćĩàĺś"],"9asVsi":["Ĥōŵ ĺōńĝ ēàćĥ ćōḿḿēŕćĩàĺ ƀŕēàķ ĺàśţś"],"9qdNKR":["Ēŕŕōŕ Ōƥţĩōńś"],"9sqrEU":["Ƒĩĺĺēŕ Ĺĩśţ"],"9td1Wl":["Ćĥēćķ"],"9vtG84":[" Śćĥēďũĺĩńĝ Śţŕàţēĝŷ"],"A+GCyx":["Ĥĩďē Àďvàńćēď"],"A0+T6c":["Ŕēśēţ Ćĥàńĝēś"],"A1taO8":["Śēàŕćĥ"],"A7WmPm":["Ńēŵ Ƥĺēx Śēŕvēŕ"],"A9Rhec":["Ćĥàńńēĺ Ńàḿē"],"ACKu03":["Ŕēƒŕēśĥ Ƥŕēvĩēŵ"],"AKjNTL":["Àďď Ƥàďďĩńĝ"],"AM972O":["Àďď Ŕēďĩŕēćţ"],"ANICN0":["Ńō ḿēďĩà śōũŕćēś ćōńńēćţēď."],"AO2Z5d":["Ḿōvĩē, ",["0"]],"AOHgZp":["Ēƥĩśōďēś"],"AVKoQM":["Ŕēďĩŕēćţ ţō \\"",["0"],"\\""],"AXg7m0":["Śēàŕćĥ ĩś ćũŕŕēńţĺŷ śćōƥēď ţō ţĥĩś Ḿēďĩà Śōũŕćē."],"AXjA78":["Ƒĩēĺď"],"AdfhAd":["Ĩƒ ţĥēŕē àŕē ĩśśũēś ƥĺàŷĩńĝ à vĩďēō, Ţũńàŕŕ ŵĩĺĺ ţŕŷ ţō ũśē àń ēŕŕōŕ śćŕēēń àś à ƥĺàćēĥōĺďēŕ ŵĥĩĺē ŕēţŕŷĩńĝ ĺōàďĩńĝ ţĥē vĩďēō ēvēŕŷ 60 śēćōńďś."],"AdogaJ":["Ƥĩƥēĺĩńē Śţēƥś"],"AlfqgK":["Ŵàţćĥ"],"ApsQAb":["ĤĎĤŔ: Ĺōàďĩńĝ..."],"AyInY5":["Vĩďēō Ōƥţĩōńś"],"AzCYkg":["Ćōńńēćţ Ḿēďĩà Śōũŕćēś"],"B+HsXP":["ƑƑḾƤĒĜ: ",["0"]],"B1NOvD":["Ŕēḿōvēś àĺĺ ƥŕōĝŕàḿś ƒŕōḿ śćĥēďũĺē"],"B1W8vw":["Ďēĺēţē \\"",["0"],"\\""],"BGHH1t":["Ḿĩń. Vĩśĩƀĺē ĩń Ĝũĩďē Ďũŕàţĩōń Ƥŕōĝŕàḿ (śēćōńďś)"],"BJjJuo":["ĒƤĜ (Ĥōũŕś)"],"BMlGCC":["Ćĺĩćķ ţō ƥŕēvĩēŵ ţĥē ĩţēḿś ĩń ţĥĩś Ćũśţōḿ Śĥōŵ. Ńōţē ţĥàţ ōńĺŷ ţĥē ŵĥōĺē śĥōŵ ćàń ƀē àďďēď àţ ōńćē."],"BQsifH":["Śţŕēàḿ Ĩńƒō"],"BWTzAb":["Ḿàńũàĺ"],"BXXjCD":["ƑƑḿƥēĝ ńōţ ƒōũńď. Ƒōŕ àĺĺ ƒēàţũŕēś ţō ŵōŕķ, ŵē ŕēćōḿḿēńď ĩńśţàĺĺĩńĝ ƑƑḿƥēĝ 7.1+ ōŕ ũƥďàţē ŷōũŕ ƑƑḿƥēĝ ēxēćũţàƀĺē ƥàţĥ ĩń śēţţĩńĝś."],"BaUuhR":["Ćōďēć"],"BlmmxH":["ƑƑḿƥēĝ Ĺōĝ"],"Bq0ryo":["Ŕēśēţ Ōƥţĩōńś"],"BtL93c":[["0","plural",{"one":["#"," śōũŕćē ćōńńēćţēď."],"other":["#"," śōũŕćēś ćōńńēćţēď."]}]],"C4KL42":["Ćōńśōĺĩďàţēś ćōńţĩĝũōũś ḿàţćĥ ƒĺēx àńď ŕēďĩŕēćţ ƀĺōćķś ĩńţō śĩńĝũĺàŕ śƥàńś"],"C6jEO3":["Ĺōĝ Ĺēvēĺ"],"CAiikc":["Ēńţēŕ ŷōũŕ ĵēĺĺŷƒĩń ƥàśśŵōŕď ţō ĝēńēŕàţē à ńēŵ àććēśś ţōķēń.<0/><1>ŃŌŢĒ: Ţĥēśē àŕē ńēvēŕ śàvēď ţō ţĥē Ţũńàŕŕ Ďß. Ĩńśţēàď ţĥēŷ àŕē śēńţ ţō ĵēĺĺŷƒĩń ţō ēxćĥàńĝē ƒōŕ à śēśśĩōń ţōķēń."],"CJkEfx":["ßĺōćķ"],"CKQ3t3":["Ţōţàĺ Ŕũńţĩḿē"],"CMQ09J":["Śćàńńĩńĝ"],"COv7As":["Ćōōĺďōŵń (śēćōńďś)"],"CRsuq4":["Ēvēŕŷ"],"CVqySE":[["len","plural",{"one":["Ţĥēŕē ĩś ","#"," ŵàŕńĩńĝ. Ćĺĩćķ ƒōŕ ďēţàĩĺś."],"other":["Ţĥēŕē àŕē ","#"," ŵàŕńĩńĝś. Ćĺĩćķ ƒōŕ ďēţàĩĺś."]}]],"CWRFGq":["Ḿōďĩƒŷ Ƥŕōĝŕàḿḿĩńĝ"],"CXDHcv":["Ĝŕĩď"],"CcX8VV":["Ćōḿƥĺēţēĺŷ ŕàńďōḿĩźēś ţĥē ōŕďēŕ ōƒ ƥŕōĝŕàḿś."],"CeyB7O":["ƑƑḿƥēĝ Ēxēćũţàƀĺē Ƥàţĥ"],"CfOWar":["Ĺōĝàŕĩţĥḿĩć ďēćàŷ, ĺĩĝĥţēŕ ŵēĩĝĥţĩńĝ."],"CfUvtM":["Ēŕŕōŕ śàvĩńĝ ńēŵ Śḿàŕţ Ćōĺĺēćţĩōń. Ćĥēćķ śēŕvēŕ ĺōĝś àńď ƀŕōŵśēŕ ćōńśōĺē ƒōŕ ďēţàĩĺś."],"CfxLtO":["Ƥŕōĝŕàḿ ĵŚŌŃ"],"Cko536":["Ďēśćēńďĩńĝ"],"Cp5Awv":["Ďũŕàţĩōń ḿũśţ ƀē ĝŕēàţēŕ ţĥàń 0."],"CqSP2T":["Ēďĩţ Ćĥàńńēĺ Ŕēďĩŕēćţ"],"CsrDsg":["12-ĥōũŕ"],"Cxqf0C":["Ƥĺēx (Àũţō)"],"D+NlUC":["Śŷśţēḿ"],"D1Fhv3":[["count","plural",{"one":["ēƥĩśōďē"],"other":["ēƥĩśōďēś"]}]],"DPfwMq":["Ďōńē"],"DRya1t":["Àũďĩō Vōĺũḿē"],"DSwJ9W":["Ēńàƀĺē Àńĩḿàţĩōń"],"DUd3Ss":["Śōŕţś ţĥē ĺĩśţ ƀŷ ŢV Śĥōŵ àńď ţĥē ēƥĩśōďēś ĩń ēàćĥ ŢV śĥōŵ ƀŷ ţĥēĩŕ śēàśōń/ēƥĩśōďē ńũḿƀēŕ. Ḿōvĩēś àŕē ḿōvēď ţō ţĥē ƀōţţōḿ ōƒ ţĥē śćĥēďũĺē."],"DbouLP":["ßàćķ ţō Ƥŕōĝŕàḿḿĩńĝ"],"Dd9orS":["Ŕēḿōvē Àĺĺ ",["movieCount"]," ",["movieCount","plural",{"one":["Ḿōvĩē"],"other":["Ḿōvĩēś"]}]],"Dnn2XG":["Àũţōḿàţĩć"],"DoJzLz":["Ćōĺĺēćţĩōńś"],"DxvGLB":["Àďď Śĺōţ"],"E/QGRL":["Ďĩśàƀĺēď"],"E5ipHC":["ßàĺàńćē ßŷ:"],"E8oclZ":["Ćōƥĩēď Ćĥàńńēĺ ĨĎ!"],"EKlukx":["Ćōƥŷ Ƒũĺĺ Ŕēƥōŕţ"],"EL4/HD":[["0","plural",{"one":["ƥŕōĝŕàḿ"],"other":["ƥŕōĝŕàḿś"]}]],"EdQY6l":["Ńōńē"],"EkH9pt":["Ũƥďàţē"],"Etie0Q":["Àĺĺ ćĥàńńēĺś àśśĩĝńēď ţō ţĥĩś ćōńƒĩĝ ŵĩĺĺ ƀē śēţ ţō ũśē ţĥē ďēƒàũĺţ ćōńƒĩĝũŕàţĩōń. Ĩƒ ţĥĩś ĩś ţĥē ĺàśţ ćōńƒĩĝũŕàţĩōń, à ńēŵ ďēƒàũĺţ ćōńƒĩĝũŕàţĩōń ŵĩĺĺ ƀē ćŕēàţēď."],"Eu20Os":["Ţĩḿē Śĺōţś"],"Ev2r9A":["Ńō ŕēśũĺţś"],"F1l877":["Śũƀţĩţĺē Śţŕēàḿś"],"F3bW6y":["Ƥĺàţƒōŕḿ"],"F3smBd":["Ḿàxĩḿũḿ ńũḿƀēŕ ōƒ ďàŷś ţō ƥŕēćàĺćũĺàţē ţĥē śćĥēďũĺē. Ńōţē ţĥàţ ţĥē ĺēńĝţĥ ōƒ ţĥē śćĥēďũĺē ĩś àĺśō ƀōũńďēď ƀŷ ţĥē ḿàxĩḿũḿ ńũḿƀēŕ ōƒ ƥŕōĝŕàḿś àĺĺōŵēď ĩń à ćĥàńńēĺ.<0/><1>Ńōţē: Ƥŕēvĩēŵĩńĝ ţĥē śćĥēďũĺē ĩń ţĥē ƀŕōŵśēŕ ƒōŕ ĺōńĝ ĺēńĝţĥś ōƒ ţĩḿē ćàń ćàũśē ŨĨ ƥēŕƒōŕḿàńćē ĩśśũēś"],"FDEfoy":["Ďēĺēţĩńĝ à ḿēďĩà śōũŕćē ŵĩĺĺ ŕēḿōvē àĺĺ ōƒ ĩţś àśśōćĩàţēď ƥŕōĝŕàḿś ƒŕōḿ Ţũńàŕŕ."],"FXCwT9":["ƑƑƥŕōƀē Ēxēćũţàƀĺē Ƥàţĥ"],"FZg3wM":["Ōƥēŕàţĩōń"],"FmN5me":["Ŕēśōĺũţĩōń"],"FnChN1":["Ēńàƀĺē <0>ĒßŨ Ŕ 128 ĺōũďńēśś ńōŕḿàĺĩźàţĩōń vĩà ţĥē <1>ĺōũďńōŕḿ ƑƑḿƥēĝ ƒĩĺţēŕ. Ḿàŷ ĩńćŕēàśē ĆƤŨ ũśàĝē ďũŕĩńĝ śţŕēàḿĩńĝ."],"Fp7p73":["Ţĩḿē ƀēţŵēēń śũƀśēǫũēńţ ƀŕēàķś"],"FqCHF/":["Ţĥŕēàďś"],"FrRP21":["Ţĥēŕē ŵàś àń ēŕŕōŕ ŵĥēń śũƀḿĩţţĩńĝ ţĥē ƒōŕḿ. Ƥĺēàśē śēē ćōńśōĺē ĺōĝś ƒōŕ ďēţàĩĺś."],"FsF4bb":["Àũďĩō Ĺōũďńēśś Ńōŕḿàĺĩźàţĩōń"],"FssFce":["Ćōńƒĩĝũŕē ƥŕēƒēŕŕēď àũďĩō ĺàńĝũàĝēś ĝĺōƀàĺĺŷ."],"Fzn/BQ":["Ŕēĺēàśē Ďàţē"],"G+8qH5":["Ćĥàńńēĺ ńàḿē ĩś ŕēǫũĩŕēď"],"GDKKxT":["Àććēśś Ţōķēń"],"GHOK4Z":["Ţĩḿē Ƒōŕḿàţ"],"GJ1P5j":["Ƒĩĺē à ßũĝ Ŕēƥōŕţ"],"GKLqtE":["Śēţ ţĥē ĥōśţ ōƒ ŷōũŕ Ţũńàŕŕ ƀàćķēńď. Ŵĥēń ēḿƥţŷ, ţĥē ŵēƀ ŨĨ ŵĩĺĺ ũśē ţĥē ćũŕŕēńţ ĥōśţ/ƥōŕţ ţō ćōḿḿũńĩćàţē ŵĩţĥ ţĥē ƀàćķēńď."],"GLOZdc":["Ćũśţōḿ Śĥōŵś"],"GP/CFo":["ĤŴ Àććēĺ"],"GQ3O42":["Ţŕàśĥ"],"GRCrpV":["Ḿàńàĝē Ĺĩƀŕàŕĩēś"],"GUtCZC":["Vēŕśĩōń: ",["0"]],"GhZ4GX":["Ēŕŕōŕ ŵĥĩĺē ćōƥŷĩńĝ ţō ćĺĩƥƀōàŕď. Ćĥēćķ ƀŕōŵśēŕ ĺōĝś ƒōŕ ďēţàĩĺś"],"GmP0oY":["Śĺōţ Ŵàŕńĩńĝś"],"GmTnBN":["Ēńàƀĺē ƒƒḿƥēĝ ĺōĝĝĩńĝ ţō ďĩƒƒēŕēńţ śĩńķś. Ōũţƥũţţĩńĝ ţō à ƒĩĺē ŵĩĺĺ ćŕēàţē à ńēŵ ĺōĝ ƒĩĺē ƒōŕ ēvēŕŷ śƥàŵńēď ƒƒḿƥēĝ ƥŕōćēśś ĩń ţĥē Ţũńàŕŕ ĺōĝ ďĩŕēćţōŕŷ. Ţĥēśē ƒĩĺēś àŕē àũţōḿàţĩćàĺĺŷ ćĺēàńēď ũƥ ƀŷ à ƀàćķĝŕōũńď ƥŕōćēśś."],"Gr1Ik2":["Ńvĩďĩà Ćàƥàƀĩĺĩţĩēś"],"GtycJ/":["Ţàśķś"],"GzzMwi":["Ŕōĺĺ ōń Śćĥēďũĺē"],"H0QGc9":["Ƒĩĺĺēŕ Ĺĩśţ Ćōōĺďōŵń (śēćōńďś)"],"H1OFlu":["Ĩńvēŕśē ĺĩńēàŕ ďēćàŷ, ĥēàvĩēŕ ŵēĩĝĥţĩńĝ."],"H1V+2G":["Ţō ũśē Ţũńàŕŕ, ŷōũ ḿũśţ ƒĩŕśţ ćōńńēćţ àţ ĺēàśţ ōńē ḿēďĩà śōũŕćē. Ḿēďĩà śōũŕćēś ƥŕōvĩďē àĺĺ ćōńţēńţ ũśēď ţō ćŕēàţē ćĥàńńēĺś ĩń Ţũńàŕŕ. Ƥĺēx àńď ĵēĺĺŷƒĩń àŕē ćũŕŕēńţĺŷ śũƥƥōŕţēď."],"H3OF1s":["Ţũńēŕ Ćōũńţ"],"H7OUPr":["Ďàŷ"],"H8100o":["Ƒĩĺĺēŕ ĺĩśţś àŕē ćōĺĺēćţĩōńś ōƒ vĩďēōś ţĥàţ ŷōũ ḿàŷ ŵàńţ ţō ƥĺàŷ ďũŕĩńĝ \'ƒĺēx\' ţĩḿē śēĝḿēńţś. Ƒĺēx ĩś ţĩḿē ŵĩţĥĩń à ćĥàńńēĺ ţĥàţ ďōēś ńōţ ĥàvē à ƥŕōĝŕàḿ śćĥēďũĺēď (ũśũàĺĺŷ ũśēď ƒōŕ ƥàďďĩńĝ)."],"HDoQBx":["Ćĥàńńēĺ śēţţĩńĝś śàvēď!"],"HEH0PR":["Ḿũśţ ďēƒĩńē àţ ĺēàśţ ōńē ĺàńĝũàĝē ƥŕēƒēŕēńćē"],"HErtdg":["Ńàḿē ćàń ōńĺŷ ćōńţàĩń àĺƥĥàńũḿēŕĩć ćĥàŕàćţēŕś, ďàśĥēś, àńď ũńďēŕśćōŕēś"],"HLlLPP":["Ćĥàńńēĺ Śţŕēàḿ Ḿōďē"],"HMWEIt":["Ēďĩţ Ƒĺēx Ţĩḿē"],"HOLbdk":["Ƒàĩĺēď ţō ĺōàď śţŕēàḿ ďēţàĩĺś! Ćĥēćķ ĺōĝś ƒōŕ ďēţàĩĺś"],"HSfauP":["Ţĥĩś śĺōţ ĩś ĺĩńķēď ŵĩţĥ ",["0"]," ōţĥēŕ ",["1","plural",{"one":["śĺōţ"],"other":["śĺōţś"]}],". Ćōńţēńţ ƒĩēĺďś àŕē śĥàŕēď àćŕōśś ţĥē ĝŕōũƥ."],"HVpg3x":["Ƒàĩĺēď ţō ĺōàď Śḿàŕţ Ćōĺĺēćţĩōń"],"HXx+vU":["Ćōńţŕōĺś ŵĥàţ ĥàƥƥēńś ŵĥēń ţĥĩś śĺōţ ŕũńś ōũţ ōƒ ŕēƥĺàŷēď ćōńţēńţ ƒŕōḿ ēàŕĺĩēŕ ćōńţĩńũē śĺōţś."],"HYCPKT":["Àďď Śēĺēćţēď Ḿēďĩà"],"HajiZl":["Ḿōńţĥ"],"HdE1If":["Ćĥàńńēĺ"],"Hjfx9G":["Àũďĩō & Śũƀţĩţĺēś"],"HmHwcC":["Ƒĩxēď Ĩńţēŕvàĺ"],"HptUxX":["Ńũḿƀēŕ"],"HqUilK":["Ķēŷŵōŕďś ƥēŕƒōŕḿ ƒũĺĺ ţēxţ śēàŕćĥ àćŕōśś àĺĺ (ōŕ ćōńƒĩĝũŕēď) ƒĩēĺďś"],"HzV8B2":["Śķĩƥ ḿĩď-ŕōĺĺ ƒōŕ ƥŕōĝŕàḿś śĥōŕţēŕ ţĥàń ţĥĩś"],"I+FvbD":["Śćàń"],"I2Bar3":["Śĥōŵś"],"I5BU70":["Śḿàŕţ Ćōĺĺēćţĩōń: ",["0"]],"I6gXOa":["Ƥàţĥ"],"IDlmXg":["Ţũńàŕŕ ßàćķēńď ŨŔĹ:"],"IE9OdF":["Ũƥďàţē Ƥĺàŷ Śţàţũś"],"IFiQdD":["Ćĥàńńēĺś Ḿ3Ũ Ĺĩńķ:"],"IMxI++":["Ńōţ à vàĺĩď ŨŔĹ"],"INCbO6":["Ōń-Ďēḿàńď ćĥàńńēĺś ŕēśũḿē ƒŕōḿ ŵĥēŕē ŷōũ ĺēƒţ ōƒƒ. Ƥŕōĝŕàḿḿĩńĝ ĩś ƥàũśēď ŵĥēń ţĥē ćĥàńńēĺ ĩś ńōţ śţŕēàḿĩńĝ.<0/><1>ŃŌŢĒ: Ŵĥĩĺē ţĥē ćĥàńńēĺ ĩś ĩńàćţĩvē, ţĥē ŢV Ĝũĩďē ƒōŕ ţĥē ćĥàńńēĺ ŵĩĺĺ ƀē ēḿƥţŷ."],"IagCbF":["ŨŔĹ"],"IetKlB":["Ńēŵ Ćũśţōḿ Śĥōŵ"],"IgC1fP":["Ēńàƀĺē ĺĩĝĥţ Ḿōďē"],"IiBgkW":["Ƒàĩĺēď ţō ũƥďàţē Ḿēďĩà Śōũŕćē śēţţĩńĝś. Ƥĺēàśē ćĥēćķ śēŕvēŕ àńď ƀŕōŵśēŕ ĺōĝś ƒōŕ ďēţàĩĺś."],"IoSxk9":["Ƥŕōţōćōĺ ḿũśţ ƀē ĤŢŢƤ ōŕ ĤŢŢƤŚ"],"IvkbIT":["Ŕēàď Ḿōŕē"],"J/eF78":["Ŕēḿōvĩńĝ ōvēŕŕũń ƥŕōĝŕàḿś ƒŕōḿ ţĥē ćĥàńńēĺ."],"J0NKO1":["Ēxćĺũďē Śēàśōńś"],"J2eKUI":["Ƒĩĺē"],"J2lnQW":["Ƥŕē"],"J41wt0":["Śĺōţ Ēďĩţōŕ"],"J4Ngmi":["Ĺōōƥ Śĥōŕţ Ƥŕōĝŕàḿś"],"J50/e4":["Ƒĩĺţēŕ Ţŷƥē"],"J8X80J":["Śţēàĺţĥ?"],"JCGCcQ":["Śōŕţś ēvēŕŷţĥĩńĝ ƀŷ ĩţś ŕēĺēàśē ďàţē. Ţĥĩś ŵĩĺĺ ōńĺŷ ŵōŕķ ćōŕŕēćţĺŷ ĩƒ ţĥē ŕēĺēàśē ďàţēś ĩń Ƥĺēx àŕē ćōŕŕēćţ. Ĩń ćàśē àńŷ ĩţēḿ ďōēś ńōţ ĥàvē à ŕēĺēàśē ďàţē śƥēćĩƒĩēď, ĩţ ŵĩĺĺ ƀē ḿōvēď ţō ţĥē ƀōţţōḿ."],"JCOZTc":["Àũďĩō & Śũƀţĩţĺē Ōƥţĩōńś"],"JOFDLs":["Ƥŕōĝŕàḿ Ƥĺàŷƀàćķ Ţŕōũƀĺēśĥōōţēŕ"],"JeAvlS":["Ƥàď Ţĩḿēś"],"JeL1O4":["Ŕēďĩŕēćţ ďũŕàţĩōń"],"Jj3SJk":["À-Ź (àść)"],"JmZ/+d":["Ƒĩńĩśĥ"],"Jpe9a8":["Àţţēḿƥţś ţō ƀàĺàńćē ƥŕōĝŕàḿḿĩńĝ ĝŕōũƥś ƀŷ ēĩţĥēŕ ţōţàĺ ĺĩńēũƥ ďũŕàţĩōń ōŕ ńũḿƀēŕ ōƒ ũńĩǫũē ƥŕōĝŕàḿś. Ƒōŕ ĩńśţàńćē, ƒōŕ à ćĥàńńēĺ ŵĩţĥ ḿàńŷ śēàśōńś ōƒ ōńē śĥōŵ àńď ƒēŵ śēàśōńś ōƒ àńōţĥēŕ, ƀàĺàńćĩńĝ ŵĩĺĺ àţţēḿƥţ ţō ćŕēàţē àń ēvēń ḿĩx ōƒ ƀōţĥ śĥōŵś ƀŷ ĩńśēŕţĩńĝ ŕēƥēàţś ōƒ ţĥē śĥōŵ ŵĩţĥ ƒēŵēŕ ēƥĩśōďēś."],"JryIGL":["ÀďĴũśţ Ŵēĩĝĥţś"],"Jsel0T":["Ţĥĩś ćĥàńńēĺ ĥàś àń ēxĩśţĩńĝ ţĩḿē śĺōţ śćĥēďũĺē. À ćĥàńńēĺ ćàń ōńĺŷ ũśē ōńē śćĥēďũĺĩńĝ ţŷƥē àţ à ţĩḿē. Śàvĩńĝ à śćĥēďũĺē ĥēŕē ŵĩĺĺ ŕēḿōvē ţĥē ēxĩśţĩńĝ ţĩḿē śĺōţ śćĥēďũĺē."],"Jtbzxr":["Vēŕśĩōń: ũńķńōŵń"],"JxE+Bh":["Àĺĺōŵś ŷōũ ţō ƥĩćķ śƥēćĩƒĩć ƥŕōĝŕàḿḿĩńĝ ţō ŕēḿōvē ƒŕōḿ ţĥē ćĥàńńēĺ."],"JyHA6G":["Ďĩśƥĺàŷś ţĥē ĺàśţ ",["0"]," śŷśţēḿ ĺōĝ ēvēńţś. Ũśē ţĥē ƀũţţōńś ƀēĺōŵ ţō ēxƥōŕţ ţĥēśē ĺōĝś ōŕ ďōŵńĺōàď ţĥē ēńţĩŕē ĺōĝ ƒĩĺē ƒōŕ ďēƀũĝĝĩńĝ."],"JzJk+4":["Àďď Ĺàńĝũàĝē Ƥŕēƒēŕēńćē"],"K09nyY":["Ĺĩńķēď śĺōţś àďvàńćē ēƥĩśōďē ƥŕōĝŕēśśĩōń ţōĝēţĥēŕ śēǫũēńţĩàĺĺŷ."],"K8+dbZ":[["totalConnections"]," ţōţàĺ"],"K8ebg0":["Ţũńàŕŕ ŵĩĺĺ ũƥďàţē ĵēĺĺŷƒĩń\'ś \\"ńōŵ ƥĺàŷĩńĝ\\" śţàţē ŵĥĩĺē ćĥàńńēĺś àŕē àćţĩvē."],"K9pQ8Q":["Ďĩśàƀĺē Ŵàţēŕḿàŕķś"],"KRjDf4":["Àũďĩō Śţŕēàḿś"],"Khe/Vb":["Ŵàţćĥ Ćĥàńńēĺ"],"KkOthv":["Ĝũĩďē"],"Km5fSd":["Ĩƒ ŷōũ àŕē ćōńƒĩďēńţ ƑƑḾƤĒĜ ĩś ĩńśţàĺĺēď, ŷōũ ḿàŷ Ĵũśţ ńēēď ţō ũƥďàţē ţĥē ēxēćũţàƀĺē ƥàţĥ ĩń ţĥē śēţţĩńĝś. Ţō ďō śō, śĩḿƥĺŷ ćĺĩćķ Ēďĩţ àƀōvē ţō ũƥďàţē ţĥē ƥàţĥ."],"L+8pV5":["Śŷńć ŵĩţĥ ēxţēŕńàĺ ƥĺàŷĺĩśţ"],"L/KmPM":["Ũśũàĺĺŷ śĺōţś ńēēď ţō àďď ƒĺēx ţĩḿē ţō ēńśũŕē ţĥàţ ţĥē ńēxţ śĺōţ śţàŕţś àţ ţĥē ćōŕŕēćţ ţĩḿē. Ŵĥēń ţĥēŕē àŕē ḿũĺţĩƥĺē vĩďēōś ĩń ţĥē śĺōţ, ŷōũ ḿĩĝĥţ ƥŕēƒēŕ ţō ďĩśţŕĩƀũţē ţĥē ƒĺēx ţĩḿē ƀēţŵēēń ţĥē vĩďēōś ōŕ ţō ƥĺàćē ḿōśţ ōƒ ţĥē ƒĺēx ţĩḿē àţ ţĥē ēńď ōƒ ţĥē śĺōţ."],"L6Mhe6":["Ŷōũ ĥàvē ũńśàvēď ćĥàńĝēś!"],"L8Hb+D":["Śēţś ţĥē ńũḿƀēŕ ōƒ ţĥŕēàďś ũśēď ţō ďēćōďē ţĥē ĩńƥũţ śţŕēàḿ. Śēţ ţō 0 ţō ĺēţ ƒƒḿƥēĝ àũţōḿàţĩćàĺĺŷ ďēćĩďē ĥōŵ ḿàńŷ ţĥŕēàďś ţō ũśē. Ŕēàď ḿōŕē àƀōũţ ţĥĩś ōƥţĩōń <0>ĥēŕē. <1>Ńōţē: ţĥĩś ōƥţĩōń ĩś ōvēŕŕĩďďēń ţō 1 ŵĥēń ũśĩńĝ ĥàŕďŵàŕē àććēĺēàŕàţĩōń ƒōŕ śţàƀĩĺĩţŷ ŕēàśōńś."],"LKPR6G":["Ƥĺàŷĺĩśţ"],"LKSv28":["Śḿàŕţ Ćōĺĺēćţĩōńś àŕē śēĺƒ-ũƥďàţĩńĝ ćōńţēńţ ĺĩśţś. Ŷōũ śēţ ţĥē ǫũēŕŷ àńď ţĥē ćōĺĺēćţĩōń àũţōḿàţĩćàĺĺŷ àďďś àńŷ ńēŵ ćōńţēńţ ƒŕōḿ ŷōũŕ ĺĩƀŕàŕŷ ţĥàţ ƒĩţś ţĥōśē ŕũĺēś. Àńŷ ńēŵĺŷ àďďēď ćōńţēńţ ḿàţćĥĩńĝ ǫũēŕŷ ŵĩĺĺ ńōţ ḿōďĩƒŷ ēxĩśţĩńĝ ćĥàńńēĺ ƥŕōĝŕàḿḿĩńĝ àţ ţĥĩś ţĩḿē."],"LMMGPr":["Śũƀḿĩţţĩńĝ..."],"LRvqnF":["Ēŕŕōŕ śàvĩńĝ ńēŵ ĵēĺĺŷƒĩń śēŕvēŕ. Śēē ƀŕōŵśēŕ ćōńśōĺē àńď śēŕvēŕ ĺōĝś ƒōŕ ďēţàĩĺś"],"LTC198":["Ŕũńńĩńĝ..."],"LTYRAI":["Vĩēŵ Ĺĩƀŕàŕŷ"],"LiCr5o":["Ĺĩḿĩţ ḿũśţ ƀē ńũḿēŕĩć"],"MHrjPM":["Ţĩţĺē"],"MKK96e":["Vĩēŵ Ćōĺĺēćţĩōń"],"MR6Nlf":["Ćĥàńĝē ţĥē vēŕƀōśĩţŷ ōƒ śƥēćĩƒĩć ćàţēĝōŕĩēś ōƒ ĺōĝś. Ũśēƒũĺ ĩƒ ďēƀũĝĝĩńĝ à śƥēćĩƒĩć ƒēàţũŕē."],"MS1Dhi":["Ḿàx ƒĩĺē śĩźē (ƀŷţēś)"],"MVBLYK":["Ŕēḿōvē..."],"MW42Hp":["Ćũśţōḿĩźē ĥōŵ ḿōvĩē ƀĺōćķś àŕē śōŕţēď"],"Md/eZS":[["count","plural",{"one":["#"," ĩţēḿ"],"other":["#"," ĩţēḿś"]}]],"MfkGXC":["Śĥũƒƒĺē Ĝŕōũƥĩńĝ"],"MkMcGz":["Ŕēƒŕēśĥ Ĺĩƀŕàŕĩēś"],"Ml7h3C":[["0","plural",{"one":["#"," Ƥŕōĝŕàḿ"],"other":["#"," Ƥŕōĝŕàḿś"]}]],"Mrdyk9":["Ĝēńŕē"],"Mv+xQh":["Ńēŵ Ćĥàńńēĺ"],"N15e5e":["Ŕēḿōvē ćũśţōḿ ĩćōń"],"NGOfis":["Ďĩśàƀĺē Ĩḿàĝē Śćàĺĩńĝ"],"NGSThJ":["Śḿàŕţ Ćōĺĺēćţĩōń"],"NL/bON":["ƑƑḿƥēĝ Ćōḿḿàńď"],"NQ7yht":["Ḿũśţ ũśē à vàĺĩď ŨŔĹ, ōŕ ēḿƥţŷ."],"NaDxQ2":["Àũţō Ďēĩńţēŕĺàćē Vĩďēō"],"Nb+B9K":["ÀďĴũśţ ţĥē ōũţƥũţ vōĺũḿē (ńōţ ŕēćōḿḿēńďēď). Vàĺũēś ĥĩĝĥēŕ ţĥàń 100 ŵĩĺĺ ƀōōśţ ţĥē àũďĩō."],"NcV1df":["Ƥàď Śţàŕţ Ţĩḿēś"],"NfTP7a":["Àďvàńćēď ōƥţĩōńś ŕēĺàţĩńĝ ţō àũďĩō. Ĩń ĝēńēŕàĺ, ďō ńōţ ćĥàńĝē ţĥēśē ũńĺēśś ŷōũ ķńōŵ ŵĥàţ ŷōũ àŕē ďōĩńĝ!"],"NfZ8rc":["24-ĥōũŕ"],"Nkn5MW":["Ŕēḿōvēś àĺĺ Ƒĺēx ƥēŕĩōďś ƒŕōḿ ţĥē śćĥēďũĺē."],"NnH3pK":["Ţēśţ"],"NnuRri":["Ţĥĩś àĺĺōŵś ŷōũ ţō ƥĩćķ ţĥē ŵēĩĝĥţś ƒōŕ ēàćĥ ōƒ ţĥē śĥōŵś, śō ŷōũ ćàń ďēćĩďē ţĥàţ śōḿē śĥōŵś śĥōũĺď ƀē ĺēśś ƒŕēǫũēńţ ţĥàń ōţĥēŕ śĥōŵś."],"NtQvjo":["Ƥēŕĩōď"],"Nu4oKW":["Ďēśćŕĩƥţĩōń"],"Ny7dz3":["Àĺƀũḿś"],"NyfQ4q":["Śàvē àś Śḿàŕţ Ćōĺĺēćţĩōń"],"O1xfOi":["Ŕàńďōḿ..."],"O5izWu":["Ţĥĩś ćũśţōḿ śĥōŵ ĩś śŷńćēď ŵĩţĥ àń ēxţēŕńàĺ ƥĺàŷĺĩśţ. Ćōńţēńţ ĩś ũƥďàţēď àũţōḿàţĩćàĺĺŷ àńď ćàńńōţ ƀē ēďĩţēď ḿàńũàĺĺŷ."],"O8g6Na":["Ĺàśţ Śćàńńēď: ",["0"]],"OPw3KG":["Ćōńńēćţ Ḿēďĩà Śōũŕćē"],"OVmXHk":["Ŕēƒŕēśĥ Ţĩḿēŕ (Ĥōũŕś)"],"Ob+B6e":["ßũƒƒēŕ śĩźē ćàńńōţ ƀē ćĥàńĝēď ŵĥēń ćōƥŷĩńĝ ĩńƥũţ àũďĩō"],"OfC/JK":["Ćũśţōḿ Śĥōŵ - ",["0"]],"OfYtUi":["Ƒĩĺĺēŕ Ćōńţēńţ"],"OfhWJH":["Ŕēśēţ"],"OrDu0o":["Vĩďēō ßũƒƒēŕ Śĩźē"],"Osn70z":["Ďēƀũĝ"],"P/TyYO":["Ţĥē ţŷƥē ōƒ ḿēďĩà ĩń ţĥē ƥŕōvĩďēď ƥàţĥś"],"P1BU0j":["Ƒŕàḿē Ŕàţē"],"P29ZKI":["Ēńţēŕ à ńàḿē ƒōŕ ŷōũŕ Ēḿƀŷ Śēŕvēŕ"],"P2DGHD":["Ƥŕōĝŕàḿḿĩńĝ śţàŕţś àţ ",["startTime"]," àńď śţōƥś àţ ",["endTime"]],"P3i3NN":["Ēďĩţ Ćĥàńńēĺ Śēţţĩńĝś"],"P6Io39":["Ḿàx Ĺàţēńēśś"],"P6c7YE":["Ŕēḿōvē Ƥŕōĝŕàḿḿĩńĝ"],"PCBfmf":["Ŕēńďēŕś à ćĥàńńēĺ ĩćōń (àĺśō ķńōŵń àś ƀũĝ ōŕ Ďĩĝĩţàĺ Ōń-śćŕēēń Ĝŕàƥĥĩć) ōń ţōƥ ōƒ ţĥē ćĥàńńēĺ\'ś śţŕēàḿ."],"PJ/u9s":["Ćōƥĩēď ",["0"]," ŨŔĹ ţō ćĺĩƥƀōàŕď"],"PT6k0T":["Ƥĩxēĺ Ƒōŕḿàţ"],"PX1WM1":["Śũććēśśƒũĺĺŷ ēḿƥţĩēď ţŕàśĥ."],"Pazp7r":["Ţĥēŕē ŵàś àń ēŕŕōŕ ĝēńēŕàţĩńĝ ţĩḿē śĺōţś. Ćĥēćķ ţĥē ƀŕōŵśēŕ ćōńśōĺē ĺōĝ ƒōŕ ḿōŕē ĩńƒōŕḿàţĩōń"],"PeBTGz":["Ćĺēàŕ Śćĥēďũĺē"],"PeBylA":["Ŷōũ ḿũśţ ćŕēàţē àţ ĺēàśţ ōńē <0>ƒĩĺĺēŕ ĺĩśţ ƀēƒōŕē àśśĩĝńĩńĝ ƒĩĺĺēŕ ţō à ĺōţ."],"Pfatg8":[["minutes","plural",{"one":["#"," ḿĩńũţē"],"other":["#"," ḿĩńũţēś"]}]],"PgdRhI":["Ŵēĩĝĥţĩńĝ"],"Ph+yE0":["0 ḿĩńś"],"PhKcf0":["Ēďĩţ Ţŕàńśćōďē Ćōńƒĩĝ"],"PiY0nu":["Ŷōũ ĥàvē ńō Ƒĩĺĺēŕ Ĺĩśţś. Ćŕēàţē ŷōũŕ ƒĩŕśţ Ƒĩĺĺēŕ Ĺĩśţ <0>ĥēŕē."],"Pol2QS":["Ēḿƀŷ"],"PpZkda":["Ƒēàţũŕēś"],"PwpUBp":["Ţĥĩś ĩś ţĥē ńàḿē ōƒ ţĥē ƒàķē ƥŕōĝŕàḿ ţĥàţ ŵĩĺĺ àƥƥēàŕ ĩń ţĥē ŢV ĝũĩďē ŵĥēń ţĥēŕē àŕē ńō ƥŕōĝŕàḿś ţō ďĩśƥĺàŷ ĩń ţĥàţ ţĩḿē śĺōţ ĝũĩďē, ē.ĝ ŵĥēń à ĺàŕĝē Ƒĺēx ƀĺōćķ ĩś śćĥēďũĺēď."],"Pwqkdw":["Ĺōàďĩńĝ…"],"Q8L6q9":["Vĩďēō Śţŕēàḿś"],"QAUrt0":["Ŕēƒŕēśĥ Ƥàĝē"],"QEb4hu":["Śţēàĺţĥ Ḿōďē"],"QG2xdt":["Ćŕēàţē Ŕēŕũń ßĺōćķ"],"QHRTYn":["Śĺōţś Ēďĩţōŕ..."],"QKMxhc":["Ţũńàŕŕ ŕũńś vàŕĩōũś ţàśķś, śōḿēţĩḿēś ōń à śćĥēďũĺē, ƒōŕ ƀàćķĝŕōũńď ōƥēŕàţĩōńś."],"QUxTIQ":["Ƒĩĺĺēŕ ĩś ŕēśōĺvēď àţ śćĥēďũĺē ţĩḿē. Ţĥē ĝũĩďē śĥōŵś śƥēćĩƒĩć ƒĩĺĺēŕ ţĩţĺēś."],"Qll2Tb":["Ďēść"],"QlrQ/Z":["Ńēxţ Śćĥēďũĺēď Ēxēćũţĩōń"],"Qm1NmK":["ŌŔ"],"Qu844y":["Ţĩḿē Śĺōţ Ēďĩţōŕ"],"QvKdb0":["Ƥĺàćēĥōĺďēŕ Ƥŕōĝŕàḿ Ţĩţĺē"],"Qx971g":["Àƒţēŕ Ēvēŕŷ"],"R/7J0Z":["Àŕţĩśţś"],"R/N+HY":["Ńō ƥŕōĝŕàḿḿĩńĝ àďďēď ŷēţ"],"R/xSFi":["Ēďĩţĩńĝ \\"",["0"],"\\""],"R0yni2":["Àţţēḿƥţ Àũţō-Ƒĩx"],"R40oLk":["Ŵĩĺĺ ƒōŕćē ũśē ōƒ à śōƒţŵàŕē ēńćōďēŕ ďēśƥĩţē ĥàŕďŵàŕē àććēĺēŕàţĩōń śēţţĩńĝś."],"R6kHq+":["Ĺĩńķ Ḿōďē"],"R9Khdg":["Àũţō"],"RCeEAd":["Ĝĺōƀàĺ Ōƥţĩōńś"],"RGf6l7":["Śēĺēćţ à śĺōţ ţō ĺĩńķ ţō"],"RI4u49":["<0>Ŷōũ ćàń ēďĩţ ţĥĩś ĺōćàţĩōń ĩń ŷōũŕ śēţţĩńĝś.Ĵśōń ŵĩţĥĩń ŷōũŕ Ţũńàŕŕ ďàţà ďĩŕēćţōŕŷ<1/><2>ŃŌŢĒ: Ŵĥēń ḿàńũàĺĺŷ àďďĩńĝ ţĥē XḾĹŢV ĺōćàţĩōń ţō à ćĺĩēńţ ĺĩķē Ƥĺēx, ďō ńōţ ũśē ţĥĩś ƒĩĺē ďĩŕēćţĺŷ. Ĩńśţēàď, ũśē ţĥē ĝēńēŕàţēď XḾĹŢV ƒŕōḿ ţĥē Ţũńàŕŕ ÀƤĨ ēńďƥōĩńţ: ",["0"],""],"RTxUjI":["Ćōƥŷ ţō Ćĺĩƥƀōàŕď"],"RUYsn0":["Ćĺēàŕ Àĺĺ"],"RVl9/c":["Àĺţēŕńàţē ƥŕōĝŕàḿś ĩń ƀĺōćķś. Ŷōũ ćàń ƥĩćķ ţĥē ńũḿƀēŕ ōƒ ƥŕōĝŕàḿś ƥēŕ-ţŷƥē ĩń ēàćĥ ƀĺōćķ àńď ĩƒ ţĥē ōŕďēŕ ōƒ śĥōŵś ĩń ēàćĥ ƀĺōćķ śĥōũĺď ƀē ŕàńďōḿĩźēď."],"RYP47R":[["0","plural",{"one":["Ďàŷ"],"other":["Ďàŷś"]}]],"RYlQY0":["Ŕēƥēàţś"],"RaHlqV":[["totalConnections","plural",{"one":["#"," ćōńńēćţĩōń"],"other":["#"," ćōńńēćţĩōńś"]}]],"RavMGr":[["count","plural",{"one":["śēćōńď"],"other":["śēćōńďś"]}]],"RbgUS/":["Ćōƥŷ Ćĥàńńēĺ ĨĎ"],"RtPRIb":["Ḿàxĩḿũḿ ńũḿƀēŕ ōƒ ďàŷś ţō ƥŕēćàĺćũĺàţē ţĥē śćĥēďũĺē. Ńōţē ţĥàţ ţĥē ĺēńĝţĥ ōƒ ţĥē śćĥēďũĺē ĩś àĺśō ƀōũńďēď ƀŷ ţĥē ḿàxĩḿũḿ ńũḿƀēŕ ōƒ ƥŕōĝŕàḿś àĺĺōŵēď ĩń à ćĥàńńēĺ."],"RxzN1M":["Ēńàƀĺēď"],"S/CawK":["Ḿōvĩēś àŕē ĝŕōũƥēď àĺţōĝēţĥēŕ"],"S5v5/h":["Ēńàƀĺĩńĝ ēḿƀēďďēď śũƀţĩţĺē ēxţàćţĩōń ŵĩĺĺ ƥēŕĩōďĩćàĺĺŷ śćàń ŷōũŕ ũƥćōḿĩńĝ ƥŕōĝŕàḿḿĩńĝ ƒōŕ ēḿƀēďďēď ţēxţ-ƀàśēď śũƀţĩţĺē śţŕēàḿś àńď ēxţŕàćţ ţĥēḿ ţō à ĺōćàĺ ćàćĥē. Ţĥĩś ĩś ńēćēśśàŕŷ ĩń ōŕďēŕ ţō ēńàƀĺē śũƀţĩţĺē ƀũŕńĩńĝ ƒōŕ ţēxţ-ƀàśēď śũƀţĩţĺēś ŵĥĩćĥ àŕē ńōţ ēxţēŕńàĺ śţŕēàḿś."],"S60KP9":["Śēŕvēŕ Śēţţĩńĝś"],"S8zZJK":["Ŵēĺćōḿē ţō Ţũńàŕŕ!"],"SBtwzo":["Vēŕśĩōń Ḿĩśḿàţćĥ!"],"SCZJhh":["Àũďĩō ßĩţŕàţē"],"SFjIKS":[["0","plural",{"one":["#"," Śēĺēćţēď Ĩţēḿ"],"other":["#"," Śēĺēćţēď Ĩţēḿś"]}]],"SOXW6w":["Àĺĺ Ĝēńŕēś"],"SY1gRl":["Ḿēďĩà Śōũŕćē"],"SYGPcm":["Ŷōũ ĥàvē ńō śḿàŕţ ćōĺĺēćţĩōńś. Śḿàŕţ ćōĺĺēćţĩōńś ćàń ƀē ćŕēàţēď ōń ţĥē <0>śēàŕćĥ ƥàĝē."],"SZcfpX":["Ƥàď Śţŷĺē"],"SZzr30":["Ţĥē śēĺēćţēď ĺàńĝũàĝēś ŵĩĺĺ ƀē ćōńśĩďēŕēď ĩń ōŕďēŕ ţĥēŷ àŕē śēĺēćţēď."],"Sbs5dW":["Ƒĩĺĺēŕ"],"Sg3laT":["Ḿĩń Ďũŕàţĩōń"],"SoRsRS":["Ćàĺćũĺàţēś à śćĥēďũĺē ŵĥēŕē àĺĺ ƥŕōĝŕàḿś ēńď àţ ţĥē śàḿē ţĩḿē, ćŕēàţĩńĝ à ƥēŕƒēćţĺŷ ĺōōƥĩńĝ śćĥēďũĺē."],"SuubHr":["Ďēĺēţĩńĝ à Ƥĺēx śēŕvēŕ ŵĩĺĺ ŕēḿōvē àĺĺ ƥŕōĝŕàḿḿĩńĝ ƒŕōḿ ŷōũŕ ćĥàńńēĺś àśśōćĩàţēď ŵĩţĥ ţĥĩś ƥĺēx śēŕvēŕ. Ḿĩśśĩńĝ ƥŕōĝŕàḿḿĩńĝ ŵĩĺĺ ƀē ŕēƥĺàćēď ŵĩţĥ Ƒĺēx ţĩḿē. Ţĥĩś àćţĩōń ćàńńōţ ƀē ũńďōńē."],"SywaS+":["Ďàţà Ďĩŕēćţōŕŷ:"],"T5wfux":["Ḿàķēś ḿũĺţĩƥĺē ćōƥĩēś ōƒ ţĥē śćĥēďũĺē àńď ƥĺàŷś ţĥēḿ ĩń śēǫũēńćē"],"T8drou":["Śŷśţēḿ Ĥēàĺţĥ"],"TEM0vH":["Ŕēḿōvēś àĺĺ ƥŕōĝŕàḿś ƒŕōḿ ćũśţōḿ śĥōŵ"],"TMADKS":["Ďĩvĩďēś ţĥē ƥŕōĝŕàḿḿĩńĝ ĩń ƀĺōćķś ōƒ 4, 6, 8 ōŕ 12 ĥōũŕś ţĥēń ŕēƥēàţś ēàćĥ ōƒ ţĥē ƀĺōćķś ţĥē śƥēćĩƒĩēď ńũḿƀēŕ ōƒ ţĩḿēś."],"TMju4P":["Ďēĺēţē Ḿēďĩà Śōũŕćē \\"",["0"],"\\"?"],"TS0lwx":["Ēńćōũńţēŕēď àń ēŕŕōŕ ŵĥēń ēḿƥţŷĩńĝ ţŕàśĥ. Ćĥēćķ ćōńśōĺē ĺōĝś ƒōŕ ďēţàĩĺś."],"TZKpsF":["Ńō Ḿēďĩà Śōũŕćēś ďēţēćţēď."],"TpqW74":["Ƒĩxēď"],"Ts6Zfm":["Ēŕŕōŕ ũƥďàţĩńĝ Śḿàŕţ Ćōĺĺēćţĩōń. Ćĥēćķ ĺōĝś ƒōŕ ďēţàĩĺś."],"Ts8Q+i":["ĒƤĜ"],"TvY/XA":["Ďōćũḿēńţàţĩōń"],"Tz0i8g":["Śēţţĩńĝś"],"TzyoiK":["Ŵĥēń ēńàƀĺĩńĝ, Ţũńàŕŕ ŵĩĺĺ ĝēńēŕàţē àń ĩńĩţĩàĺ ƀàćķũƥ ĩḿḿēďĩàţēĺŷ"],"U0sC6H":["Ďàĩĺŷ"],"U3+jR/":["Ŕēƥĺĩćàţē Ƥŕōĝŕàḿś"],"UC1lMc":["Ƒàĩĺēď ţō śàvē ƒēàţũŕē ƒĺàĝś."],"UE2eVC":["Śōŕţś àĺƥĥàƀēţĩćàĺĺŷ ƀŷ ƥŕōĝŕàḿ ţĩţĺē"],"UHu/Uf":["Śĥōŵ ōńĺŷ śŷńćēď ĺĩƀŕàŕĩēś"],"UOMT7z":["Ţĥĩś ōƥţĩōń ĩś ďĩśàƀĺēď ƀēćàũśē ĩţ ŵōũĺď ćàĺćũĺàţē à śćĥēďũĺē ţĥàţ ĩś ţōō ĺōńĝ."],"URmyfc":["Ďēţàĩĺś"],"UXC1jS":["ŃōďēĵŚ: ",["0"]],"UYUgdb":["Ōŕďēŕ"],"UYW9jU":["Śũććēśśƒũĺĺŷ ŕàń śŷśţēḿ ƒĩxēŕ ",["fixerId"]],"Uf/h/w":["Ƥĩćķ śƥēćĩƒĩć ƥŕōĝŕàḿḿĩńĝ ţō ŕēḿōvē ƒŕōḿ ţĥē ćĥàńńēĺ."],"UirGxE":["Ēŕŕōŕś"],"UnI8zh":["Ćĥàńńēĺ #",["0"]],"UweSf9":["Àďď Ćĥàńńēĺ Ŕēďĩŕēćţ"],"V8B1wG":["Ĺàśţ śŷńćēď ",["0"]],"V9UVpb":["Ţōţàĺ ĥĩţś: ",["0"]],"VBsY8N":["Śēţ ţō 0 ţō ńēvēŕ ďēĺēţē ƀàćķũƥś"],"VIHbrI":["Àďvàńćēď ōƥţĩōńś ŕēĺàţĩńĝ ţō ţŕàńśćōďĩńĝ. Ĩń ĝēńēŕàĺ, ďō ńōţ ćĥàńĝē ţĥēśē ũńĺēśś ŷōũ ķńōŵ ŵĥàţ ŷōũ àŕē ďōĩńĝ! Ţĥēśē śēţţĩńĝś ēxĩśţ ĩń ōŕďēŕ ţō ĺēàvē śōḿē ƥàŕĩţŷ ŵĩţĥ ţĥē ōĺď ďĩźǫũēŢV ţŕàńśćōďē ƥĩƥēĺĩńē àś ŵēĺĺ àś ţō ƥŕōvĩďē ḿēćĥàńĩśḿś ţō àĩď ĩń ďēƀũĝĝĩńĝ śţŕēàḿĩńĝ ĩśśũēś."],"VP2oPP":["Śĺōţś"],"VVAgOP":["Ŕēśćàń Ĩńţēŕvàĺ (ĥōũŕś)"],"VXdzY3":["Ďĩśàƀĺē Ĥàŕďŵàŕē Ēńćōďĩńĝ"],"Va3xJe":["Àďď ƒĩēĺď"],"VfWz27":["Ŵēĩĝĥţ %"],"VlEnCC":["Àŕćĥĩvē Ƒōŕḿàţ"],"VlWKwW":["Ĺàźŷ"],"Vmvp5H":[["count","plural",{"one":["ďàŷ"],"other":["ďàŷś"]}]],"VrBtVn":["ßàćķũƥś:"],"Vw5EeW":["Ēńàƀĺē ßàćķũƥś"],"VyUuZb":["Ĩḿàĝē ŨŔĹ"],"WAakm9":["Ďēĺēţē Ćĥàńńēĺ"],"WDgJiV":["Śćàńńēŕ"],"WGkxNZ":["Ēŕŕōŕ ǫũēŕŷĩńĝ Ƥĺēx. Ćĥēćķ ćōńśōĺē ĺōĝ àńď ćōńśĩďēŕ ŕēƥōŕţĩńĝ à ƀũĝ!"],"WKHqM+":["Ŵēĩĝĥţ"],"WMQchs":["Àũďĩō ßũƒƒēŕ Śĩźē"],"WT1Ibn":["Ĺàśţ ŕũń"],"Wb3E4g":["Ŕũń ńōŵ"],"Weq9zb":["Ĝēńēŕàĺ"],"WhJZoS":["Ćĥōōśē ţĥē ţŕàńśćōďē ćōńƒĩĝũŕàţĩōń ţō ũśē ƒōŕ ţĥĩś ćĥàńńēĺ. Ćōńƒĩĝũŕē ţŕàńśćōďē ćōńƒĩĝũŕàţĩōńś ōń ţĥē <0>ƑƑḿƥēĝ śēţţĩńĝś ƥàĝē."],"WjUHH8":["Ḿōvĩē Śōŕţ"],"WnW1QF":[["block"]," Ĥōũŕś"],"WzNAIP":[["0","plural",{"one":["Ĥōũŕ"],"other":["Ĥōũŕś"]}]],"X0mSqw":["Ŵĩĺĺ ƒōŕćē ũśē ōƒ à śōƒţŵàŕē ƒĩĺţēŕś (ē.ĝ. śćàĺē, ƥàď, ēţć.) ďēśƥĩţē ĥàŕďŵàŕē àććēĺēŕàţĩōń śēţţĩńĝś."],"X9EHMa":["Ēďĩţĩńĝ Śḿàŕţ Ćōĺĺēćţĩōń \\"",["0"],"\\""],"XDT85c":["Ḿēďĩà Śōũŕćēś"],"XIgmo9":["Ďĩď ńōţ ŕēćēĩvē àń àććēśśŢōķēń ōŕ ũśēŕĨď ƒŕōḿ ĵēĺĺŷƒĩń śēŕvēŕ."],"XNtsE7":["Ćàĺćũĺàţĩńĝ Śĺōţś..."],"XNw99A":["Śōƒţŵàŕē (Ńō ĜƤŨ)"],"XOgcN3":["Ƒĩĺĺēŕ Ĺĩśţ: ",["0"]],"XOuE6F":["Ţĥĩś ćōũĺď ćàũśē ţĥē ƒōĺĺōŵĩńĝ śĺōţ\'ś ƥŕōĝŕàḿś ţō ĝō ũńśćĥēďũĺēď. Ƥōśśĩƀĺē śōĺũţĩōńś ĩńćĺũďē:"],"XSkU3F":["* Ŕēśţàŕţ ŕēǫũĩŕēď"],"XWYqJx":["Ďũƥĺĩćàţē Ćĥàńńēĺ"],"XXwX66":["Śēţ ţĥē ĺōĝ ĺēvēĺ ƒōŕ ţĥē Ţũńàŕŕ śēŕvēŕ.<0/>Śēĺēćţĩńĝ <1>\\"Ũśē ēńvĩŕōńḿēńţ śēţţĩńĝś\\" ŵĩĺĺ ĩńśţŕũćţ ţĥē śēŕvēŕ ţō ũśē ţĥē <2>ĹŌĜ_ĹĒVĒĹ ēńvĩŕōńḿēńţ vàŕĩàƀĺē, ĩƒ śēţ, ōŕ śŷśţēḿ ďēƒàũĺţ \\"ĩńƒō\\"."],"XePUKr":["Ţēśţ Ţŕàńśćōďē"],"XhWvkJ":[["0"]," ōƒ ",["1"]," ",["2"]," ēxćēēď ţĥē ĺēńĝţĥ ōƒ ţĥĩś śĺōţ (",["3"],"). Àvēŕàĝē ƥŕōĝŕàḿ ĺēńĝţĥ: ",["4"]],"Xkppm4":["Ēńàƀĺē Ŵàţēŕḿàŕķ"],"Xm/WEQ":["Ćĥàńńēĺ Ĝŕōũƥ"],"XsR2HX":["Ţēśţ Ďũŕàţĩōń (śēćōńďś)"],"Xuml3I":["ßŷ ďēƒàũĺţ, ţĩḿē śĺōţś àŕē ţĩḿē ōƒ ţĥē ďàŷ-ƀàśēď, ŷōũ ćàń ćĥàńĝē ĩţ ţō ţĩḿē ōƒ ţĥē ďàŷ + ďàŷ ōƒ ţĥē ŵēēķ. Ţĥàţ ḿēàńś śćĥēďũĺĩńĝ 7x ţĥē ńũḿƀēŕ ōƒ ţĩḿē śĺōţś. Ĩƒ ŷōũ ćĥàńĝē ƒŕōḿ ďàĩĺŷ ţō ŵēēķĺŷ, ţĥē ćũŕŕēńţ śćĥēďũĺē ŵĩĺĺ ƀē ŕēƥēàţēď 7 ţĩḿēś. Ĩƒ ŷōũ ćĥàńĝē ƒŕōḿ ŵēēķĺŷ ţō ďàĩĺŷ, ḿàńŷ ōƒ ţĥē śĺōţś ŵĩĺĺ ƀē ďēĺēţēď."],"XwU6BE":["Ŷōũ ĥàvēń\'ţ ćŕēàţēď àńŷ ƒĩĺĺēŕ ĺĩśţś ŷēţ! Ĝō ţō ţĥē <0>Ƒĩĺĺēŕ Ĺĩśţś ƥàĝē ţō ćŕēàţē ōńē."],"Y2ngGV":["Àďď à Ƒĩĺĺēŕ Ĺĩśţ"],"Y5XZLy":["<0>Ƥàď Śĺōţ: Àĺĩĝń śĺōţ śţàŕţ ţĩḿēś ţō ţĥē śƥēćĩƒĩēď ƥàď ţĩḿē.<1/><2>Ƥàď Ēƥĩśōďē: Àĺĩĝń ēƥĩśōďē śţàŕţ ţĩḿēś (ŵĩţĥĩń à śĺōţ) ţō ţĥē śƥēćĩƒĩēď ƥàď ţĩḿē. <3>ŃŌŢĒ: Ďēƥēńďĩńĝ ōń śĺōţ ĺēńĝţĥ àńď ţĥē ćĥōśēń ƥàď ţĩḿē, ţĥĩś ćōũĺď ƥōţēńţĩàĺĺŷ ćŕēàţē à ĺōţ ōƒ ƒĺēx."],"Y84UgQ":["Ĺōũďńēśś Ţàŕĝēţ"],"YAKCkm":["Àń ēŕŕōŕ ōććũŕŕēď: ",["0"]],"YDlcs3":["Śĥũƒƒĺē Ƥŕōĝŕàḿḿĩńĝ"],"YLUnu0":["Ţēśţ Ƥĺàŷƀàćķ"],"YN7vx3":["Ćũśţōḿ Śĥōŵ"],"YRQaPv":["Ĺàśţ Śŷńćēď"],"YRT1+e":["Ćŕēàţēś à ńēŵ ćōĺĺēćţĩōń"],"YSptU0":["Ŕēƥĺĩćàţē..."],"YT5/eK":["Ḿēďĩà Śōũŕćē: \\"",["0"],"\\""],"YXwR3a":["Ŕēśţōŕē ďēƒàũĺţ ĺōĝō"],"YY/JN7":[" ţĥē ƒōĺĺōŵĩńĝ ďàŷ."],"YYLNVW":["Ĩńśēŕţ ƀŕēàķś àţ ţĥēśē ƥēŕćēńţàĝēś ōƒ ţĥē ƥŕōĝŕàḿ ďũŕàţĩōń"],"YdIZFA":["Ţĥĩś ćĥàńńēĺ ńũḿƀēŕ ĥàś àĺŕēàďŷ ƀēēń ũśēď"],"Yf/Mtb":["Ŷōũ\'ŕē Àĺĺ Śēţ!"],"Z10t2U":["Ŕēḿōvēś ŕēƥēàţēď ƥŕōĝŕàḿś."],"Z3FXyt":["Ĺōàďĩńĝ..."],"Z4IQ8m":["Ćĥàńńēĺ Ţŕàńśćōďē Ćōńƒĩĝ"],"Z5IrB3":["Ōƥēń ĩń ",["0"]],"Z6dMWq":["Ēŕŕōŕ ŵĥĩĺē ŕũńńĩńĝ śŷśţēḿ ƒĩxēŕ ",["fixerId"],". Ćĥēćķ śēŕvēŕ ĺōĝś ƒōŕ ďēţàĩĺś."],"ZND/fh":["Ćàńńōţ ƀē ēḿƥţŷ"],"ZNZzTe":["Ćàńńōţ ďĩśàƀĺē ĺĩƀŕàŕĩēś ŵĥēń ţĥēŷ àŕē ĺōćķēď"],"ZShzvn":["\\"",["0"],"\\" Ĺĩvē"],"ZWRt1W":["Ōũţƥũţ Ƥàţĥ"],"ZkdKVr":["Ŕēďĩŕēćţ ţō Ćĥàńńēĺ ",["0"]],"Zky8hA":["Ţĥē ĩḿàĝē ŵĩĺĺ ƀē ŕēńďēŕēď àţ ĩţś àćţũàĺ śĩźē ŵĩţĥōũţ àńŷ śćàĺĩńĝ àƥƥĺĩēď."],"Zs2GWW":["Ńēŵ Ēḿƀŷ Ḿēďĩà Śōũŕćē"],"Zul8Ry":["ńēvēŕ"],"Zvipe1":["Ēďĩţĩńĝ Ƥĺēx Śēŕvēŕ \\"",["0"],"\\""],"ZxwuFV":["Ďēĺēţĩńĝ à Ćĥàńńēĺ ŵĩĺĺ ŕēḿōvē àĺĺ ƥŕōĝŕàḿḿĩńĝ ƒŕōḿ ţĥē ćĥàńńēĺ. Ţĥĩś àćţĩōń ćàńńōţ ƀē ũńďōńē."],"a+Pr3s":["Àƥƥĺŷ ţō Ƥŕōĝŕàḿ Ţŷƥēś (ēḿƥţŷ = àĺĺ)"],"a4N/Bg":["Ĺōàď Ḿōŕē"],"aE3UMm":["<0>Ńōńē: śĺōţś àŕē ƥĩćķēď ĩń ţĥē ōŕďēŕ ţĥēŷ àŕē śƥēćĩƒĩēď ĩń ţĥē ţàƀĺē (ĩ.ē. ńōţ ŕàńďōḿĺŷ)<1/><2>Ũńĩƒōŕḿ: àĺĺ śĺōţś ĥàvē àń ēǫũàĺ ćĥàńćē ţō ƀē ƥĩćķēď.<3/><4>Ŵēĩĝĥţēď: ēàćĥ śĺōţ ĩś ƥĩćķēď ŵĩţĥ à śƥēćĩƒĩēď ƥŕōƀàƀĩĺĩţŷ"],"aOaCIk":["Àĺĺōŵ Ēxţēŕńàĺ"],"aScBGS":["Àďď à ƒĩĺţēŕ ēxƥŕēśśĩōń ţō ƒĩńē-ţũńē ŕēśũĺţś ōƒ ţĥē śēàŕćĥ"],"aSwfbR":["Ũńĩţ"],"ak3N0i":["Ĩţēḿ ŵàś ńōţ ƥŕēśēńţ ďũŕĩńĝ ţĥē ĺàśţ śćàń"],"aoLy25":["Ōƥàćĩţŷ"],"b0Uv6P":[["0","plural",{"one":["Ƥàţĥ"],"other":["Ƥàţĥś"]}]],"b6sx4K":["Ńō àćţĩvē śēśśĩōńś"],"bDY29m":["Ĺōĝàŕĩţĥḿĩć"],"bGG6B1":["ĵēĺĺŷƒĩń"],"bHNlfr":["Ĩńćŕēàśĩńĝ ţĥē śĺōţ ďũŕàţĩōń."],"bNEQeI":["Ćōōĺďōŵń"],"bORfbY":["Ćàńńōţ ũśē à ćĥàńńēĺ ńũḿƀēŕ <= 0"],"bPJiZF":["Śĥōŵ: ",["0"]],"bSIBDb":["Ŕēĺēàśē Ďàţē (àść)"],"bm8pgG":["Àďď ĝŕōũƥ"],"boItSp":["Ďēĺēţē Ḿēďĩà Śōũŕćē?"],"buS8nL":["Ēńàƀĺē Śũƀţĩţĺēś"],"bxyuno":["Ōvēŕŕĩďē ĝĺōƀàĺ àũďĩō àńď śũƀţĩţĺē śēţţĩńĝś ƒōŕ ţĥĩś ćĥàńńēĺ."],"bydide":["ƑƑḾƤĒĜ Ĺōĝ Ḿēţĥōď"],"c6fsNw":["Ŵĥēń ēńàƀĺēď, ĩńţēŕḿĩţţēńţ ŵàţēŕḿàŕķś ƒàďē ĩń ĩḿḿēďĩàţēĺŷ ŵĥēń à śţŕēàḿ ĩś ĩńĩţĩàĺĩźēď. Ŵĥēń ďĩśàƀĺēď, ţĥē ƒĩŕśţ ŵàţēŕḿàŕķ ƒàďē-ĩń ōććũŕś àƒţēŕ à ƒũĺĺ ƥēŕĩōď."],"cF5KzV":["Ēďĩţ Ƒĩĺĺēŕ Ĺĩśţ"],"cFTdM+":["Ćōńśōĺē"],"cHYx4E":["Ēḿƥţŷ Ţŕàśĥ"],"cLgGtf":["Ŕēśēţ ƥŕōĝŕàḿḿĩńĝ ţō ḿōśţ ŕēćēńţĺŷ śàvēď śţàţē"],"cN5Dty":["Ńō Ƥŕōĝŕàḿḿĩńĝ śćĥēďũĺēď"],"cOvZFM":["Ďŷńàḿĩć"],"cXkSYc":["Ţĥēŕē ŵàś àń ēŕŕōŕ śũƀḿĩţţĩńĝ ţĥē ŕēǫũēśţ ţō ũƥďàţē Ḿēďĩà Śōũŕćē śēţţĩńĝś. Ƥĺēàśē ćĥēćķ ţĥē ƒōŕḿ àńď ţŕŷ àĝàĩń"],"caSM6R":["Ţĥĩś ĩś ũśēď ƀŷ ĩƥţv ćĺĩēńţś ţō ćàţēĝōŕĩźē ţĥē ćĥàńńēĺś. Ŷōũ ćàń ĺēàvē ĩţ àś \'ţũńàŕŕ\' ĩƒ ŷōũ ďōń\'ţ ńēēď ţĥĩś śōŕţ ōƒ ćĺàśśĩƒĩćàţĩōń."],"cgo+Ch":[["remainingTime"]," ĺēƒţ"],"cheWPw":["Ďũƥĺĩćàţēś"],"cjX7aq":["Àŕē ŷōũ śũŕē ŷōũ ŵàńţ ţō ďēĺēţē Śḿàŕţ Ćōĺĺēćţĩōń \\"",["0"],"\\"?"],"cmKYIw":["Ōvēŕƒĺōŵ ßēĥàvĩōŕ"],"cmlWKg":["<0>Ēŕŕōŕ ďēĺēţĩńĝ ćũśţōḿ śĥōŵ: ",["0"],"<1/>Ƥĺēàśē ćōńśĩďēŕ ōƥēńĩńĝ à ƀũĝ ŵĩţĥ ďēţàĩĺś!"],"cnCAaO":["Ƥēŕćēńţàĝē-ßàśēď"],"cnGeoo":["Ďēĺēţē"],"cv/ykT":["Śēàŕćĥ Śēŕvēŕ ŨŔĹ:"],"cxrM1O":["Ćōńńēćţ Śōũŕćēś"],"d5zxa4":["Ĺōćàĺ"],"d72gcv":["Ĺōũďńōŕḿ Ōƥţĩōńś"],"d9HhJj":["Ţĥĩś ḿēďĩà śōũŕćē ĥàś ńō ēńàƀĺēď ōŕ śćàńńēď ĺĩƀŕàŕĩēś. Ēńàƀĺē ĺĩƀŕàŕĩēś ƒōŕ ţĥĩś śōũŕćē ōń ţĥē <0>Ḿēďĩà Śōũŕćēś ƥàĝē ōŕ ḿàńũàĺĺŷ ţŕĩĝĝēŕ śćàńś ōń ţĥē <1>Ĺĩƀŕàŕŷ ƥàĝē."],"d9Tsiy":["Ēŕŕōŕ ũƥďàţĩńĝ ćĥàńńēĺ.<0/>Ćĥēćķ ƀŕōŵśēŕ ćōńśōĺē ƒōŕ ďēţàĩĺś"],"d9XR+x":["Ţŕàńśćōďē Ćōńƒĩĝ <0> <1/>"],"dBV/FP":["Ĺōćķ Ŵēĩĝĥţś"],"dDX6oS":["Vĩďēōś ƒŕōḿ ţĥē ƒĩĺĺēŕ ĺĩśţ ŵĩĺĺ ƀē ŕàńďōḿĺŷ ƥĩćķēď ţō ƥĺàŷ ũńĺēśś ţĥēŕē àŕē ćōōĺďōŵń ŕēśţŕĩćţĩōńś ţō ƥĺàćē ōŕ ĩƒ ńō vĩďēōś àŕē śĥōŕţ ēńōũĝĥ ƒōŕ ţĥē ŕēḿàĩńĩńĝ Ƒĺēx ţĩḿē.<0/>Ēàćĥ ƒĩĺĺēŕ ćàń ƀē àśśĩĝńēď à ćōōĺďōŵń, ŵĥĩćĥ ŕēśţŕĩćţś ĥōŵ ƒŕēǫũēńţĺŷ ţĥē ĺĩśţ ŵĩĺĺ ƀē ćĥōśēń ďũŕĩńĝ ƒĺēx ţĩḿē."],"dEgA5A":["Ćàńćēĺ"],"dH8AwH":["Àďď ßŕēàķś"],"dK3Z9j":["Ćōḿƥōńēńţ"],"dQvGiF":[["0","plural",{"one":["#"," śēśśĩōń"],"other":["#"," śēśśĩōńś"]}]],"dScixt":["Ēńàƀĺē ďàŕķ Ḿōďē"],"dUyQn5":["Ōń-Ďēḿàńď"],"daSf8d":["Ĝŕōũƥ ēƥĩśōďē ƥŕōĝŕàḿś ƀŷ ţĥēĩŕ śĥōŵ."],"djpQ8z":["Ŕēĺōàď Śţŕēàḿ"],"dkURuB":["Ţàĩĺ ßũƒƒēŕ (ḿĩńũţēś)"],"dnCwNB":["Śũććēśśƒũĺĺŷ ćōƥĩēď ţō ćĺĩƥƀōàŕď!"],"eARDm/":[["0","plural",{"one":["#"," śēàśōń"],"other":["#"," śēàśōńś"]}],", ",["1","plural",{"one":["#"," ţōţàĺ ēƥĩśōďē"],"other":["#"," ţōţàĺ ēƥĩśōďēś"]}]],"eEpDfJ":["Ŵĩĺĺ ƒōŕćē ũśē ōƒ à śōƒţŵàŕē ďēćōďēŕ ďēśƥĩţē ĥàŕďŵàŕē àććēĺēŕàţĩōń śēţţĩńĝś."],"eNorwJ":["Ƥŕōĝŕàḿś Ţōō Ĺōńĝ"],"ePK91l":["Ēďĩţ"],"eSsduj":["VÀ-ÀƤĨ Ďēvĩćē"],"eZTFiP":["Ŕēvĩēŵ Śēĺēćţĩōńś"],"eZe0fr":["Àũďĩō Ćĥàńńēĺś"],"ecUA8p":["Ţōďàŷ"],"efuwN9":["Ţĥēśē śēţţĩńĝś àŕē śţōŕēď ĩń ŷōũŕ ƀŕōŵśēŕ àńď àŕē śàvēď àũţōḿàţĩćàĺĺŷ ŵĥēń ćĥàńĝēď."],"eg6m1K":["Ēďĩţ Ţŕàńśćōďē Ćōńƒĩĝ: \\"",["0"],"\\""],"ep+NHZ":["Ĩƒ ŷōũ ƥŕōćēēď, àĺĺ ũńśàvēď ćĥàńĝēś ŵĩĺĺ ƀē ĺōśţ. Àŕē ŷōũ śũŕē ŷōũ ŵàńţ ţō ƥŕōćēēď?"],"et+mIi":["Ţŕōũƀĺēśĥōōţ"],"euChZN":["Ćŷćĺĩć Śĥũƒƒĺē"],"euc6Ns":["Ďũƥĺĩćàţē"],"exYcTF":["Ĺĩƀŕàŕŷ"],"eyRsaH":["Ŕōōţ"],"f0w0IC":["Ĺēàvē ƀĺàńķ ţō ũśē ţĥē ćĥàńńēĺ\'ś ĩćōń."],"f6Hub0":["Śōŕţ"],"f6pgxW":["Ţēḿƥōŕàŕĩĺŷ ćàćĥēś ŕēśƥōńśēś ƒŕōḿ Ƥĺēx ƀàśēď ƀŷ ŕēǫũēśţ ƥàţĥ. Ćōũĺď ƥōţēńţĩàĺĺŷ śƥēēď ũƥ ćĥàńńēĺ ēďĩţĩńĝ."],"f7DWm5":["Ńēēď àţ ĺēàśţ ōńē ƥàţĥ"],"fD+lMD":["Śēĺēćţ ţĥē ƥōŕţ ţĥē Ţũńàŕŕ śēŕvēŕ ŵĩĺĺ ĺĩśţēń ōń. Ţĥĩś ŕēǫũĩŕēś à śēŕvēŕ ŕēśţàŕţ ţō ţàķē ēƒƒēćţ."],"fI+mNw":["Ƥĺàŷĺĩśţś"],"fJfo1A":["Śēŕvēŕ Ƥàţĥ"],"fN4bgn":["Ďēĺēţē Ƒĩĺĺēŕ Ĺĩśţ \\"",["0"],"\\"?"],"fQ9phi":["Ŕēḿōvē Àĺĺ"],"fSRZCh":["Ŕēśţōŕē Ďēƒàũĺţ Śēţţĩńĝś"],"fU1065":["Ḿĩď-Ŕōĺĺ"],"fWj7Tt":["Śĥũƒƒĺē ƥŕōĝŕàḿḿĩńĝ ĩń à ćĥàńńēĺ, ōƥţĩōńàĺĺŷ ĝŕōũƥĩńĝ ƥŕōĝŕàḿś ƀŷ ćēŕţàĩń ćŕĩţēŕĩà."],"fcqkKg":["Ńōţ ƒōũńď!"],"fsBGk0":["ßàĺàńćē"],"ftF4U5":["Śĥōŵ Àďvàńćēď"],"fxTyFe":["Ţĥĩś śĺōţ ĩś ĺĩńķēď ŵĩţĥ ",["0"]," ōţĥēŕ ",["1","plural",{"one":["śĺōţ"],"other":["śĺōţś"]}],"Ćōńţēńţ ƒĩēĺďś àŕē śĥàŕēď àćŕōśś ţĥē ĝŕōũƥ."],"fyo+NB":["Ţĥē Ēńď."],"fzWV5a":["Śōŕţ ŢV Śĥōŵś (ďēść)"],"g2Pro3":["Ŕēśēţ ćĥàńĝēś ḿàďē ţō ţĥē ćĥàńńēĺ\'ś ĺĩńēũƥ"],"g6LxbB":["ßŕēàķ Ĩńţēŕvàĺ (ḿĩńũţēś)"],"g7LzUS":["Ĩńśţàĺĺ ƑƑḾƤĒĜ"],"gBx20d":["Ćũśţōḿ Ƥŕōĝŕàḿ"],"gH5Gbn":["Śĥũƒƒĺē"],"gJrGqR":["ƑƑḿƥēĝ vēŕśĩōń 7.1+ ŕēćōḿḿēńďēď. Ćĥēćķ ŷōũŕ ćũŕŕēńţ vēŕśĩōń ĩń ţĥē śĩďēƀàŕ"],"gL9DoB":["Ƥŕōĝŕàḿś śĥōŕţēŕ ţĥàń ţĥĩś vàĺũē ŵĩĺĺ ƀē ţŕēàţēď ţĥē śàḿē àś Ƒĺēx ţĩḿē. Ḿēàńĩńĝ ţĥàţ ţĥē ŢV Ĝũĩďē ŵĩĺĺ ţŕŷ ţō ḿēĺď ţĥēḿ ŵĩţĥ ţĥē ƥŕēvĩōũś ƥŕōĝŕàḿ ōŕ ďĩśƥĺàŷ ţĥē ƀĺōćķ ōƒ ƥŕōĝŕàḿś àś ţĥē \\"ƥĺàćē ĥōĺďēŕ ƥŕōĝŕàḿ\\" ĩƒ ţĥēŷ ḿàķē à ĺàŕĝē ćōńţĩńũōũś ĝŕōũƥ. Ũśē 0 ţō ďĩśàƀĺē ţĥĩś ƒēàţũŕē ōŕ ũśē à ĺàŕĝē vàĺũē ţō ḿàķē ţĥē ćĥàńńēĺ ŕēƥōŕţ ōńĺŷ ţĥē ƥĺàćēĥōĺďēŕ ƥŕōĝŕàḿ àńď ńōţ ţĥē ŕēàĺ ƥŕōĝŕàḿḿĩńĝ.\\n",["0"]],"gR/hgc":["Ēŕŕōŕ Àũďĩō"],"gcD6jw":["Ĥĩďē ŵàţēŕḿàŕķ ďũŕĩńĝ ƒĩĺĺēŕ"],"gf/bM4":["Ćōńţĩńũē ŵĩţĥ Ńēŵ Ćōńţēńţ"],"gg9/ya":["Ŕēḿōvē ",["count"]," ",["0"]],"ghGSuE":["Ēńśũŕēś ƥŕōĝŕàḿś ĥàvē à ńĩćē-ĺōōķĩńĝ śţàŕţ ţĩḿē, ĩţ ŵĩĺĺ àďď Ƒĺēx ţĩḿē ţō ƒĩĺĺ ţĥē ĝàƥś."],"glVpbE":["Ēàĝēŕ"],"h/qU8b":["Ōvēŕŕĩďē ţĥē ďēƒàũĺţ ",["0"]," ďēvĩćē ƥàţĥ (ďēƒàũĺţś ţō <0>/ďēv/ďŕĩ/ŕēńďēŕĎ128 ōń Ĺĩńũx àńď ƀĺàńķ ōţĥēŕŵĩśē)"],"h4yKYk":["Ńēxţ ŕũń"],"h8WhoR":["Śĺōţ Śćĥēďũĺēŕ"],"hBGuBW":["Ũśē ćĥàńńēĺ ďēƒàũĺţ"],"hBzeL7":["Ţĩḿē ƀēƒōŕē ƒĩŕśţ ƀŕēàķ"],"hG89Ed":["Ĩḿàĝē"],"hISVAG":["Ḿēďĩà Śōũŕćēś àŕē ŵĥēŕē Ţũńàŕŕ śōũŕćēś ŷōũŕ ćōńţēńţ. Ḿēďĩà ćàń ćōḿē ƒŕōḿ ŷōũŕ ƒĩĺēśŷśţēḿ ōŕ à ŕēḿōţē śēŕvēŕ, ĺĩķē Ƥĺēx ōŕ ĵēĺĺŷƒĩń. Àţ ĺēàśţ ōńē Ḿēďĩà Śōũŕćē ĩś ńēćēśśàŕŷ ţō ćŕēàţē ćĥàńńēĺś àńď ƥĺàŷ ḿēďĩà ĩń Ţũńàŕŕ."],"hQRttt":["Śũƀḿĩţ"],"hQSabA":["ŢŌ"],"hXfj39":["Àũďĩō Śàḿƥĺē Ŕàţē"],"hXzOVo":["Ńēxţ"],"hYgDIe":["Ćŕēàţē"],"he3ygx":["Ćōƥŷ"],"hehnjM":["Àḿōũńţ"],"hhukVU":["Ţŕàśĥēď ĩţēḿś àŕē ĩţēḿś ţĥàţ ŵēŕē ƥŕēvĩōũśĺŷ śćàńńēď, ƀũţ ńōţ ƒōũńď ĩń à ŕēćēńţ śćàń. Ţĥĩś ćōũĺď ƀē ďũē ţō ḿĩśśĩńĝ ƒĩĺēś ōŕ à ḿēďĩà śēŕvēŕ ńō ĺōńĝēŕ ŕēţũŕńĩńĝ ţĥē ĩţēḿ ƒŕōḿ ĩţś ÀƤĨ. Ţĥēśē ĩţēḿś ŵĩĺĺ ƀē ũńƥĺàŷàƀĺē ĩń ćĥàńńēĺś ĩń ţĥēĩŕ ćũŕŕēńţ śţàţē. Ŵĥēń ţĥē ţŕàśĥ ĩś ēḿƥţĩēď, ţĥēĩŕ śƥōţś ĩń ćĥàńńēĺś ŵĩĺĺ ƀē ŕēƥĺàćēď ŵĩţĥ ƒĺēx."],"hjerov":["Ĝũĩďē Śţàŕţ Ţĩḿē"],"hlIKor":["Ńōńē:"],"hnFEC+":["Ĩńĩţĩàĺ Ďēĺàŷ + Ĩńţēŕvàĺ"],"hrdWlG":["Àďď Śĥōŵ"],"hvo+jE":["Àďď ƥōĩńţ (%)"],"i1+yww":["ƑƑƥŕōƀē vēŕśĩōń 6.0+ ŕēćōḿḿēńďēď. Ćĥēćķ ŷōũŕ ćũŕŕēńţ vēŕśĩōń ĩń ţĥē śĩďēƀàŕ"],"i2QuB6":["Ēŕŕōŕ Śćŕēēń"],"i9rcQ/":["Ḿōvĩēś"],"iH8pgl":["ßàćķ"],"iQWhqk":["ƑƑḾƤĒĜ ĩś ĩńśţàĺĺēď. Ďēţēćţēď vēŕśĩōń ",["0"]],"iTjV+L":["À-Ź (ďēść)"],"iXJkMB":["Ćōōĺďōŵń (ś)"],"ih+n6S":["Ĺĩńēàŕ"],"ihCTE6":["Ēŕŕōŕ ōććũŕŕēď ŵĥĩĺē ĺōàďĩńĝ ćĥàńńēĺś, ƥĺēàśē ţŕŷ àĝàĩń śōōń."],"ihn4zD":["Śēàŕćĥ…"],"ilkCYA":[["0","plural",{"one":["Śēĺēćţēď Ĩţēḿ"],"other":["Śēĺēćţēď Ĩţēḿś"]}]],"imrPBy":["Ŵàţēŕḿàŕķ Ĩḿàĝē ŨŔĹ"],"isC0OF":["Ũśē ţĥēśē śēţţĩńĝś ţō ōvēŕŕĩďē ĝĺōƀàĺ ƒƒḿƥēĝ śēţţĩńĝś ƒōŕ ţĥĩś ćĥàńńēĺ."],"isRobC":["Ńēŵ"],"isyw73":["Àũţō ũśēś ţĥē ţĩḿē ćōńvēńţĩōń ƒōŕ ţĥē śēĺēćţēď ĺàńĝũàĝē."],"jETaUB":["ßũƒƒēŕ śĩźē ēƒƒēćţś ĥōŵ ƒŕēǫũēńţĺŷ ƒƒḿƥēĝ ŕēćōńśĩďēŕś ţĥē ōũţƥũţ ƀĩţŕàţē. <0>Ŕēàď ḿōŕē"],"jHjfnS":["Àďď ƒĩĺĺēŕ"],"jZlrte":["Ćōĺōŕ"],"jl3Q84":["Ćŕēàţē à Ćĥàńńēĺ"],"jz1oG0":["Śēĺēćţēď Àũďĩō"],"k6TRai":["ƑƑḾƤĒĜ ţŕàńśćōďĩńĝ ĩś ŕēǫũĩŕēď ƒōŕ śōḿē ƒēàţũŕēś ĺĩķē ćĥàńńēĺ ōvēŕĺàŷ, śũƀţĩţĺēś, àńď ḿēàśũŕēś ţō ƥŕēvēńţ ĩśśũēś ŵĥēń śŵĩţćĥĩńĝ ēƥĩśōďēś."],"kAidIP":["Ƒàĩĺēď ţō ĺōàď ƒēàţũŕē ƒĺàĝś."],"kBJRjR":["Ďōŵńĺōàď àĺĺ ĺōĝś"],"kIYDzY":["Śũććēśśƒũĺĺŷ ũƥďàţēď Ḿēďĩà Śōũŕćē śēţţĩńĝś."],"kKgsI0":["<0>Ćōńƒĩĝũŕē ţĥē ďĩŕēćţōŕŷ ŵĥēŕē Ţũńàŕŕ ŵŕĩţēś ĤĹŚ śēĝḿēńţ ƒĩĺēś ŵĥēń ţŕàńśćōďĩńĝ. Ţũńàŕŕ ŵĩĺĺ ćŕēàţē ţĥē ţàŕĝēţ ďĩŕēćţōŕŷ (ƀũţ ńōţ ĩńţēŕḿēďĩàţē ďĩŕēćţōŕĩēś) ĩƒ ĩţ ďōēśń\'ţ ēxĩśţ.<1/>Ćĥàńĝĩńĝ ţĥĩś ƒĩēĺď ŵĩĺĺ ōńĺŷ àƒƒēćţ ńēŵ śēśśĩōńś. Ēxĩśţĩńĝ śēśśĩōńś ŵĩĺĺ ćōńţĩńũē ŵŕĩţĩńĝ ţō ţĥē ƥŕēvĩōũś śēţţĩńĝ, ƀũţ ŵĩĺĺ ćĺēàń ōũţ śēĝḿēńţś ŵĥēń ţĥē śēĝḿēńţ ēńďś.<2/>Ŵĥēń ũńśēţ, Ţũńàŕŕ ŵĩĺĺ ŵŕĩţē śēĝḿēńţś ţō ĩţś ćũŕŕēńţ ŵōŕķĩńĝ ďĩŕēćţōŕŷ."],"kKk153":["Ĺōàď Śţŕēàḿ"],"kO0aVB":["ßŕēàķ Ďũŕàţĩōń (ḿĩńũţēś)"],"kThBL9":["Śàḿƥĺē ŕàţē ćàńńōţ ƀē ćĥàńĝēď ŵĥēń ćōƥŷĩńĝ ĩńƥũţ àũďĩō"],"kdkZBD":["Ĩńćŕēḿēńţ"],"kii1WH":["Ƥŕōĝŕàḿḿĩńĝ Ƥŕēvĩēŵ"],"kolyzq":["Ţĥĩś ",["0"]," ĩś ḿàŕķēď àś ḿĩśśĩńĝ ĩń ţĥē ďàţàƀàśē."],"kpfZ0g":["Ḿĩńĩḿũḿ Ƥŕōĝŕàḿ Ďũŕàţĩōń (ḿĩńũţēś)"],"kq6sAD":["Àďď ŢV Śĥōŵś ōŕ Ḿōvĩēś ţō ƒĩĺĺēŕ"],"ksFZi3":["<0>Ēxƥēŕĩḿēńţàĺ: Ēńàƀĺē Ƥĺēx Ŕēǫũēśţ Ćàćĥē"],"kvMAno":["Ŵēƀ Śēţţĩńĝś"],"l/UFPv":["Ƥŕōƥēŕţĩēś"],"l0VyMh":["Ƒĺēx"],"l15zKW":["Àĺĺ Śēţ!"],"lBADOx":[["count","plural",{"one":["#"," ēƥĩśōďē"],"other":["#"," ēƥĩśōďēś"]}]],"lC2oeQ":["Ḿàx Ďũŕàţĩōń (ḿĩńũţēś)"],"lCF0wC":["Ŕēƒŕēśĥ"],"lIUgjN":["Ēŕŕōŕ ćōƥŷĩńĝ ćĥàńńēĺ ḿ3ũ ĺĩńķ ţō ćĺĩƥƀōàŕď"],"lJSUC1":["Ŵàţēŕḿàŕķ"],"lKCfnI":["Àũďĩō Ĺàńĝũàĝē Ƥŕēƒēŕēńćēś"],"lS14fB":["Ţĥēḿē Śēţţĩńĝś"],"lW3FB1":["Ďōŵńĺōàď ĺàśţ ",["0"]," ",["1","plural",{"one":["#"," ŕōŵ"],"other":["#"," ŕōŵś"]}]],"lWmRHf":["Ţĩḿē Śĺōţś..."],"lZMqZ5":["Ĩƒ ēńàƀĺēď, ŢV śĥōŵ ēƥĩśōďēś ŵĩĺĺ ũśē ţĥē ƥōśţēŕ ōƒ ţĥēĩŕ śĥōŵ, ĩńśţēàď ōƒ ţĥē ĩńďĩvĩďũàĺ ēƥĩśōďē ƥōśţēŕ."],"laQT4o":["Ţĥũḿƀńàĩĺ ŨŔĹ"],"lfFsZ4":["Ćĥàńńēĺś"],"lkz6PL":["Ďũŕàţĩōń"],"llDXYJ":["ßàćķũƥś"],"lnABVQ":["Ŕũń Ţŕōũƀĺēśĥōōţēŕ"],"m+8qnB":["Ĺĩƀŕàŕŷ: ",["0"]],"m0Gp21":["Śēĺēćţ à ƥŕōĝŕàḿ àńď ćĥàńńēĺ ţō ţēśţ ƥĺàŷƀàćķ. Ţĥē ţŕōũƀĺēśĥōōţēŕ ŵĩĺĺ àńàĺŷźē śţŕēàḿ śēĺēćţĩōń, ƀũĩĺď ţĥē ƑƑḿƥēĝ ƥĩƥēĺĩńē, àńď ŕũń à śĥōŕţ ţēśţ ţŕàńśćōďē."],"m16xKo":["Àďď"],"m48LOH":["Ĥàŕďŵàŕē Àććēĺēŕàţĩōń"],"mCB6Je":["Śēĺēćţ Àĺĺ"],"mDcLzR":["Ćàćĥĩńĝ"],"mF+u2B":["Ďōń\'ţ śēē ţĥē ĺĩƀŕàŕŷ ŷōũ ŵàńţ ĥēŕē? Ēńśũŕē ĩţ ĩś ēńàƀĺēď ĩń ţĥē <0>Ḿēďĩà Śōũŕćē Śēţţĩńĝś."],"mGM6Aa":["Ćũśţōḿ Śĥōŵś àŕē śēǫũēńćēś ōƒ vĩďēōś ţĥàţ ŕēƥŕēśēńţ à ēƥĩśōďēś ōƒ à vĩŕţũàĺ ŢV śĥōŵ. Ŵĥēń ŷōũ àďď ţĥēśē śĥōŵś ţō à ćĥàńńēĺ, ţĥē śćĥēďũĺē ţōōĺś ŵĩĺĺ ţŕēàţ ţĥē vĩďēōś àś ĩƒ ţĥēŷ ƀēĺōńĝēď ţō à śĩńĝĺē ŢV śĥōŵ."],"mHTMS1":["Ńōŕḿàĺĩźē Ƒŕàḿē Ŕàţē"],"mQt7fl":[["count","plural",{"one":["ƥŕōĝŕàḿ"],"other":["ƥŕōĝŕàḿś"]}]],"mRWiYM":["Ďũŕàţĩōń (śēćōńďś)"],"mWbpso":["Ḿàx ßàćķũƥś"],"mYBORk":["Ḿōvĩē"],"mYJG1x":["Ŷōũŕ ĺĩśţ ŵĩĺĺ ƀē ŕēƥĺĩćàţēď ",["0"]," ţĩḿēś"],"mZFYjJ":["Ēŕŕōŕ śàvĩńĝ ƥŕōĝŕàḿś. ",["0"]],"mZFr14":["ĤĹŚ ńōţ śũƥƥōŕţēď ĩń ţĥĩś ƀŕōŵśēŕ!"],"md42bg":["Ţŕàńśćōďē Ćōńƒĩĝ (ōƥţĩōńàĺ ōvēŕŕĩďē)"],"mgcp8D":["Ĥōŵ ōƒţēń ţō ĩńśēŕţ à ƀŕēàķ"],"migeCK":["Ƒĩĺţēŕ ŵĥĩćĥ śũƀţĩţĺē ţŕàćķś àŕē ćōńśĩďēŕēď<0/><1>Àńŷ: Àĺĺ śũƀţĩţĺē ţŕàćķś àŕē ćōńśĩďēŕēď <2/><3>Ƒōŕćēď: Ōńĺŷ ćōńśĩďēŕ <4>\\"ƒōŕćēď\\"śũƀţĩţĺē ţŕàćķś <5/><6>Ďēƒàũĺţ: Ōńĺŷ ćōńśĩďēŕ ďēƒàũĺţ śũƀţĩţĺē ţŕàćķś <7/><8>Ńōńē: Ďō ńōţ śēĺēćţ àńŷ śũƀţĩţĺēś"],"mtQjGe":["Ćōńƒĩĝũŕē śũƀţĩţĺē ƥŕēƒēŕēńćēś. Ƥŕēƒēŕēńćēś àŕē ēvàĺũàţēď ĩń ōŕďēŕ ōƒ ƥŕĩōŕĩţŷ. Ţĥē ƒĩŕśţ ḿàţćĥĩńĝ śũƀţĩţĺē śţŕēàḿ ōń à ƥŕōĝŕàḿ ŵĩĺĺ ƀē ũśēď."],"mvU6s8":["Śōŕţ ŢV Śĥōŵś"],"mwtge0":["Śţàŕţēď ",["startedAgo"]," - ",["remainingTime"],"ŕēḿàĩńĩńĝ"],"n+7HJk":["Ŵĥēń ƒĩĺē ƥàţĥś ōń ţĥē ŕēḿōţē śēŕvēŕ ďĩƒƒēŕ ƒŕōḿ ţĥē ƥàţĥś Ţũńàŕŕ ćàń śēē, ũśē Ƥàţĥ Ŕēƥĺàćēḿēńţś ţō ĩńśţŕũćţ Ţũńàŕŕ ĥōŵ ţō śţŕēàḿ ḿēďĩà ƒŕōḿ ďĩśķ."],"n9nSNJ":["Ţĩḿē ƒōŕḿàţ"],"nH6YaM":["Ōţĥēŕ Vĩďēōś"],"nSW2Lv":[["days","plural",{"one":["#"," ďàŷ"],"other":["#"," ďàŷś"]}]],"nV6twc":["Ōŕĝàńĩźē"],"nYD/Cq":["Àśćēńďĩńĝ"],"nZXc7r":["Ũńĺĩńķ ƒŕōḿ ĝŕōũƥ"],"nfAddt":["ƑƑḿƥēĝ Ţŕàńśćōďē Ƥàţĥ"],"nfxRnc":["Ţũńàŕŕ ĩś ćũŕŕēńţĺŷ ćōńƒĩĝũŕēď ţō ũśē ţĥē ÀĆ3 àũďĩō ēńćōďēŕ. Ţĥĩś àũďĩō ƒōŕḿàţ ĩś ńōţ śũƥƥōŕţēď ƀŷ ƀŕōŵśēŕś. Ţĥē ŕēśũĺţàńţ śţŕēàḿ ŵĩĺĺ ĺĩķēĺŷ ńōţ ĥàvē àũďĩō ōŕ ŵĩĺĺ ńōţ ƥĺàŷ àţ àĺĺ."],"njIcYs":["Śàvē àś ńēŵ ćōĺĺēćţĩōń…"],"ntJ9rt":["ĤĹŚ Ďĩŕēćţ Ōũţƥũţ Ƒōŕḿàţ"],"nzDzPp":["ţōĝĝĺē àććēśś ţōķēń vĩśĩƀĩĺĩţŷ"],"o0+Ul2":["Àďď Ƒĺēx"],"o2Ucvk":["Ĺĩƀŕàŕĩēś"],"o6OQlp":["Ēďĩţ Ćĥàńńēĺ"],"o7J4JM":["Ƒĩĺţēŕ"],"o7Y4WO":["Ēŕŕōŕ śàvĩńĝ ńēŵ Ēḿƀŷ śēŕvēŕ. Śēē ƀŕōŵśēŕ ćōńśōĺē àńď śēŕvēŕ ĺōĝś ƒōŕ ďēţàĩĺś"],"oADXRC":["Ćàĺćũĺàţēď ",["humanizedDuration"]," (",["numShows"]," ƥŕōĝŕàḿś) ōƒ ƥŕōĝŕàḿḿĩńĝ ĩń ",["duration"],"ḿś"],"oCHfGC":["Ĺēvēĺ"],"oCpfQF":["Ţĥĩś ƒēàţũŕē ĩś ćũŕŕēńţĺŷ ēxƥēŕĩḿēńţàĺ. Ƥŕōćēēď ŵĩţĥ ćàũţĩōń àńď ĩƒ ŷōũ ēxƥēŕĩēńćē àń ĩśśũē, ţŕŷ ďĩśàƀĺĩńĝ ćàćĥĩńĝ."],"oEZmaP":[["count","plural",{"one":["#"," śēàśōń"],"other":["#"," śēàśōńś"]}]],"oMA2jd":["Ŕēḿōvēś àńŷ śƥēćĩàĺś ƒŕōḿ ţĥē śćĥēďũĺē. Śƥēćĩàĺś àŕē ēƥĩśōďēś ŵĩţĥ śēàśōń \'00\'."],"oPWgse":["Ḿàxĩḿũḿ ńũḿƀēŕ ōƒ ƀŕēàķś ƥēŕ ƥŕōĝŕàḿ (0 = ũńĺĩḿĩţēď)"],"ofUcbc":["Ŕàńďōḿ"],"oihuQr":["Ńũḿƀēŕ ōƒ Ŕēƥĺĩćàţĩōńś"],"ousf2V":["Ŕàńďōḿ…"],"ovBPCi":["Ďēƒàũĺţ"],"oxvBx3":["Ĩƒ śēţ, àńŷ ƥŕōĝŕàḿḿĩńĝ ĝŕōũƥ ŵĩţĥ ƒēŵēŕ ēƥĩśōďēś ŵĩĺĺ ƀē ĺōōƥēď ĩń ōŕďēŕ ţō ḿàķē ƥēŕƒēćţĺŷ ēvēń ƀĺōćķś."],"p/78dY":["Ƥōśĩţĩōń"],"p/KgUp":["Ţĥē ćĥàńńēĺ\'ś ŕēĝũĺàŕ ƥŕōĝŕàḿḿĩńĝ ƀēţŵēēń ţĥē śƥēćĩƒĩēď ĥōũŕś. Ƒĺēx ţĩḿē ŵĩĺĺ ƒĩĺĺ ũƥ ţĥē ŕēḿàĩńĩńĝ ĥōũŕś."],"p04z/V":["# Ƥŕōĝŕàḿś"],"p4XZFD":["Ĺōćàĺ Ƥàţĥ"],"pDwcFl":["Śàvē Śḿàŕţ Ćōĺĺēćţĩōń"],"pKYBXC":["Ĺàśţ Śćĥēďũĺēď Ēxēćũţĩōń"],"paEQ75":["\\"Śţēàĺţĥ\\" ćĥàńńēĺś àŕē ĥĩďďēń ƒŕōḿ ŢV ĝũĩďēś, śƥōōƒēď ĤĎĤŔ, ḿ3ũ ƥĺàŷĺĩśţ, ēţć. Ţĥē ćĥàńńēĺ ćàń śţĩĺĺ ƀē śţŕēàḿēď ďĩŕēćţĺŷ ōŕ ƀē ũśēď àś à ŕēďĩŕēćţ ţàŕĝēţ."],"pcRxi1":["Ĥōŵ ƒŕēǫũēńţĺŷ ĺĩƀŕàŕĩēś śĥōũĺď ƀē śćàńńēď (śţàŕţĩńĝ ƒŕōḿ ḿĩďńĩĝĥţ)."],"pdlmIS":["<0>Ēŕŕōŕ ďēĺēţĩńĝ ƒĩĺĺēŕ ĺĩśţ: ",["0"],"<1/>Ƥĺēàśē ćōńśĩďēŕ ōƥēńĩńĝ à ƀũĝ ŵĩţĥ ďēţàĩĺś!"],"pkERVr":["Ďōŵńĺōàď ĵŚŌŃ"],"pqarBu":["Àść"],"pvnfJD":["Ďàŕķ"],"pwPreK":["Ŕēśţŕĩćţ Ĥōũŕś"],"pxh+PI":["ßũĩĺďēŕ"],"q6GKgP":["VÀÀƤĨ Ćàƥàƀĩĺĩţĩēś"],"q6nlo/":["Śũƀţĩţĺē Àćţĩōń"],"q9p3Xw":["ßĩţŕàţē ćàńńōţ ƀē ćĥàńĝēď ŵĥēń ćōƥŷĩńĝ ĩńƥũţ àũďĩō"],"qAGp2O":["Ƥŕōćēēď"],"qG6T/X":["Àďď Ƥŕōĝŕàḿḿĩńĝ"],"qKNcv7":["Ĝēńēŕàţĩńĝ ßũĝ Ŕēƥōŕţ Ĺĩńķ..."],"qV9xkb":["Ƥàśśţĥŕōũĝĥ àũďĩō ũńćĥàńĝēď. Ōţĥēŕ śēţţĩńĝś ŵĩĺĺ ńōţ àƥƥĺŷ."],"qiXmlF":["Àďď Ḿēďĩà"],"qjW34v":["Ţĥĩś ćĥàńńēĺ ĩś śēţ ũƥ ţō ũśē <0>",["0"],"Śĺōţś ƒōŕ ƥŕōĝŕàḿḿĩńĝ. Àńŷ ḿàńũàĺ ćĥàńĝēś ōń ţĥĩś ƥàĝē ŵĩĺĺ ĺĩķēĺŷ ḿàķē ţĥĩś ćĥàńńēĺ śţōƥ àďĥēŕĩńĝ ţō ţĥàţ śćĥēďũĺē."],"qlR1dD":["Ďēĺēţē Ćĥàńńēĺ \\"",["0"],"\\"?"],"qs/mhD":["Ēńśũŕēś ƥŕōĝŕàḿś śţàŕţ ōńĺŷ àţ à ƥàŕţĩćũĺàŕ ĩńţēŕvàĺ ŵĩţĥĩń ţĥē ĥōũŕ. Ţĥĩś ḿàķēś ƒōŕ ńĩćē ĺōōķĩńĝ śćĥēďũĺēś. Ƒĺēx ţĩḿē ĩś śćĥēďũĺēď ţō ƒàćĩĺĩţàţē."],"r3ptXC":["Ḿàńũàĺĺŷ àďď àń àććēśś ţōķēń ƒŕōḿ ŷōũŕ ĵēĺĺŷƒĩń śēŕvēŕ"],"r9sc/0":["Ďũŕàţĩōń ḿũśţ ƀē ńũḿēŕĩć"],"rAx5u1":["Ēńď Ţĩḿē"],"rPEEWz":["Śũććēśśƒũĺĺŷ śàvēď ćōńƒĩĝ!"],"rSZlvN":["Ƥŕōĝŕàḿḿĩńĝ Śţàŕţ"],"rhEkXj":["Ĥēàď"],"rl/8FN":["Ćōḿḿĩţ"],"rnbEQB":["Ćōƥŷ Ḿ3Ũ ŨŔĹ"],"roIf2/":["Ōń-Ďēḿàńď?"],"rtDDIV":["Ēďĩţ Śĺōţ"],"ru5qTc":["Ēďĩţ Ḿēďĩà Śōũŕćē"],"rx5Ria":["Àĺĺ ĺĩśţś àŕē ũśēď"],"rxumR2":["Ḿàţćĥ àńŷ ōƒ"],"s2OE0W":["Ēńţēŕ à ńàḿē ƒōŕ ŷōũŕ ĵēĺĺŷƒĩń Śēŕvēŕ"],"s4iETe":["Ţŕàńśćōďē Ćōńƒĩĝ"],"s6lNC3":["Ƒàĺĺƀàćķ Ḿōďē"],"s8zbIS":["Ĩńćĺũďē Śēàśōńś"],"sA8Jt7":["Ţĥĩś śĺōţ ŕēƥĺàŷś ćōńţēńţ àĩŕēď ƀŷ ćōńţĩńũē śĺōţś ēàŕĺĩēŕ ĩń ţĥē ƥēŕĩōď."],"sBJ5MF":["Śōũŕćēś"],"sNnXh6":["Ōŕďēŕ ōƒ ƥŕōĝŕàḿḿĩńĝ ŵĩţĥĩń ţĥē śĺōţ"],"sUtIRs":["àƀōũţ "],"sVVcvs":["Ēxƥēŕĩḿēńţàĺ Ƒēàţũŕēś"],"sfbjgG":["Àũďĩō Ƒōŕḿàţ"],"sxkWRg":["Àďvàńćēď"],"sxwNOp":["Ĺōĝś Ďĩŕēćţōŕŷ:"],"sztQMJ":["Ƥŕōĝŕàḿś à Ƒĺēx ţĩḿē śĺōţ. Ńōŕḿàĺĺŷ ŷōũ\'ď ũśē ƥàď ţĩḿēś, ŕēśţŕĩćţ ţĩḿēś ōŕ àďď ƀŕēàķś ţō àďď à ĺàŕĝē ǫũàńţĩţŷ ōƒ Ƒĺēx ţĩḿēś àţ ōńćē, ƀũţ ţĥĩś ēxĩśţś ƒōŕ ḿōŕē śƥēćĩƒĩć ćàśēś."],"t/YqKh":["Ŕēḿōvē"],"t3hvHq":["Śŷńć Ńōŵ"],"t5q6kk":["Ƒōŕ ḿōŕē ďēţàĩĺś ōń ḿàńũàĺĺŷ ŕēţŕĩēvĩńĝ à Ƥĺēx ţōķēń, śēē <0>ĥēŕē"],"t6+QCF":[["count"]," ",["programLabel"],", ",["0"]],"t8Hzw3":["Ćŷćĺĩć Śĥũƒƒĺē ŕàńďōḿĺŷ śĥũƒƒĺēś ĝŕōũƥś ōƒ ƥŕōĝŕàḿḿĩńĝ."],"tDuQbQ":["Śţŕēàḿ Ḿōďē"],"tEvsql":["Śũƀţĩţĺēś"],"tH1aCG":["Vĩďēō ßĩţŕàţē"],"tMxWK0":["Àďďś Ƒĺēx ƀŕēàķś àƒţēŕ ēàćĥ ŢV ēƥĩśōďē ōŕ ḿōvĩē ţō ēńśũŕē ţĥàţ ţĥē ƥŕōĝŕàḿ śţàŕţś àţ ōńē ōƒ ţĥē àĺĺōŵēď ḿĩńũţē ḿàŕķś. Ƒōŕ ēxàḿƥĺē, ŷōũ ćàń ũśē ţĥĩś ţō ēńśũŕē ţĥàţ àĺĺ ŷōũŕ ƥŕōĝŕàḿś śţàŕţ àţ ēĩţĥēŕ XX:00 ţĩḿēś ōŕ XX:30 ţĩḿēś. Ŕēḿōvēś àńŷ ēxĩśţĩńĝ Ƒĺēx ƥēŕĩōďś ƀēƒōŕē àďďĩńĝ ţĥē ńēŵ ōńēś. Ţĥĩś ƀũţţōń ḿĩĝĥţ ƀē ďĩśàƀĺēď ĩƒ ţĥē ćĥàńńēĺ ĩś àĺŕēàďŷ ţōō ĺàŕĝē."],"tPGTPB":["Ŕōĺĺ ţĥē ĺōĝ ƒĩĺē ōń à ƒĩxēď śćĥēďũĺē, ŕēĝàŕďĺēśś ōƒ ƒĩĺē śĩźē."],"tRgOE5":["ßàĺàńćē Ƥŕōĝŕàḿḿĩńĝ"],"tXkhj/":["Śţàŕţ"],"tXub8j":["Ďĩśƥĺàŷ Ŵàţēŕḿàŕķ ōń Ĺēàďĩńĝ Ēďĝē"],"tYuxvA":["ƑƑḾƤĒĜ"],"tfDRzk":["Śàvē"],"tgPwON":["Ōƥēŕàţōŕ"],"ti6ugP":["Ēŕŕōŕ ŵĥĩĺē śàvĩńĝ ţŕàńśćōďē ćōńƒĩĝ. Śēē ćōńśōĺē ĺōĝ ƒōŕ ďēţàĩĺś."],"tkDYSE":[["hours","plural",{"one":["#"," ĥōũŕ"],"other":["#"," ĥōũŕś"]}]],"tlMRNb":["Ţĥē ĺōàďēď vēŕśĩōń ōƒ ţĥē Ţũńàŕŕ ŨĨ ďōēś ńōţ ḿàţćĥ ţĥē śēŕvēŕ. Ŕēĺōàď ţĥē ƀŕōŵśēŕ ţō ĝēţ ţĥē ĺàţēśţ. Ĩƒ ţĥĩś ḿēśśàĝē ƥēŕśĩśţś, ćĺēàŕ ŷōũŕ ƀŕōŵśēŕ ćàćĥē àńď ŕēĺōàď."],"tlNobE":["Ćũśţōḿ Śĥōŵ: ",["0"]],"tlmh8e":["Àďď àĺĺ śēĺēćţēď ƥŕōĝŕàḿś ţō ćĥàńńēĺ"],"tsqRRB":[["0"]," Ƥōśţēŕ"],"ty8rVI":["Ńōŵ Ƥĺàŷĩńĝ:"],"tzwArf":["Vĩēŵ ĩń ",["0"]],"u+VWhB":["Ćōƥĩēď ţō ćĺĩƥƀōàŕď!"],"u+zFIr":["Ŕēśţŕĩćţ śēàŕćĥ ƒĩēĺďś"],"uAQUqI":["Śţàţũś"],"uHTa9V":["Ţō ũśē Ţũńàŕŕ, ŷōũ ńēēď ţō ƒĩŕśţ ćōńńēćţ à ḿēďĩà śōũŕćē. Ţĥĩś ŵĩĺĺ àĺĺōŵ ŷōũ ţō ƀũĩĺď ćũśţōḿ ćĥàńńēĺś ŵĩţĥ ŷōũŕ ćōńţēńţ."],"uLiDe/":["Ēńàƀĺē ēḿƀēďďēď śũƀţĩţĺē ēxţŕàćţĩōń"],"uUTf8r":["Ďēĺēţē Ćũśţōḿ Śĥōŵ \\"",["0"],"\\"?"],"uamufO":["Àďď ŢV Śĥōŵś ōŕ Ḿōvĩēś ţō ƥŕōĝŕàḿḿĩńĝ ĺĩśţ."],"ueG1bp":["Ƥŕōĝŕàḿ Ćōũńţ"],"ueLbrY":["Ĩƒ ţŕũē, àďĴũśţĩńĝ ţĥē ŵēĩĝĥţ ōƒ ōńē śĺōţ ŵĩĺĺ śćàĺē ţĥē ŵēĩĝĥţś ōƒ ōţĥēŕ śĺōţś śũćĥ ţĥàţ àĺĺ ŵēĩĝĥţś ţōţàĺ 100%. Ōţĥēŕŵĩśē, ŵēĩĝĥţś ćàń ƀē àďĴũśţēď ƒŕēēĺŷ àńď ţĥē ŵēĩĝĥţ ōƒ ēàćĥ śĺōţ ĩś ōńĺŷ ŕēĺàţĩvē ţō ţĥē ţōţàĺ ŵēĩĝĥţ."],"uixVel":["ßŷ ďēƒàũĺţ, śàvēś ƀàćķũƥś ĩń ţĥē śēŕvēŕ\'ś ŕũń ďĩŕēćţōŕŷ, ōŕ, ĩƒ ŕũńńĩńĝ ĩń Ďōćķēŕ, ţō /ćōńƒĩĝ/ţũńàŕŕ/ƀàćķũƥś"],"uyR9ei":["ßĺōćķ Śĥũƒƒĺē"],"v4nbQ4":["Ĩƒ ńō ḿōŕē ƥŕōĝŕàḿś ćàń ƒĩţ ĩńţō à ďũŕàţĩōń-ƀàśēď śĺōţ, ƒĺēx ţĩḿē ĩś àďďēď ţō ƒĩĺĺ ţĥē ĝàƥ. Ţĥĩś śēţţĩńĝ ďēţēŕḿĩńēś ĥōŵ ƒĺēx ĩś àďďēď <0>ŵĩţĥĩń ţĥē śĺōţ ţō ēńśũŕē àĺĺ ţĩḿē ĩś ƒĩĺĺēď.<1/><2>ßēţŵēēń: Ƒĺēx ţĩḿē ĩś àďďēď ƀēţŵēēń vĩďēōś ŵĩţĥĩń à śĺōţ, ĩƒ ţĥēŕē àŕē ḿũĺţĩƥĺē<3/><4>Ēńď: Ƒĺēx ţĩḿē ĩś àďďēď àţ ţĥē ēńď ōƒ ţĥē śĺōţ"],"v5IstB":["àƒţēŕ ēvēŕŷ ƥŕōĝŕàḿ"],"v5URfV":["Ĺĩķē Ŕàńďōḿ Śĥũƒƒĺē, ƀũţ ţŕĩēś ţō ƥŕēśēŕvē ţĥē śēǫũēńćē ōƒ ēƥĩśōďēś ƒōŕ ēàćĥ ŢV śĥōŵ. Ĩƒ à ŢV śĥōŵ ĥàś ḿũĺţĩƥĺē ĩńśţàńćēś ōƒ ĩţś ēƥĩśōďēś, ţĥēŷ àŕē àĺśō ćŷćĺēď àƥƥŕōƥŕĩàţēĺŷ."],"vAK/B1":["Àũďĩō Àćţĩōń"],"vCBet9":["Ńōţ à vàĺĩď ńũḿƀēŕ"],"vERlcd":["Ƥŕōƒĩĺē"],"vGRvxs":["Ćĥàńńēĺ ĝŕōũƥ ĩś ŕēǫũĩŕēď"],"vLf7qg":["Ĩńţēŕvàĺ (ḿĩńũţēś)"],"vSJd18":["Vĩďēō"],"vU/Hht":["Ďĩśţŕĩƀũţĩōń"],"vXIe7J":["Ĺàńĝũàĝē"],"vcvFVw":["Ēśćàƥē Ĥàţćĥēś"],"vkA4W/":["Śōũŕćē Ţŷƥē"],"vn3SVH":["Ćōũĺď ńōţ ƥàŕśē ţĥĩś ƒĩĺţēŕ ēxƥŕēśśĩōń. Ćĥēćķ ţĥē <0>ďōćũḿēńţàţĩōń ƒōŕ ĩńƒōŕḿàţĩōń àƀōũţ ƒĩĺţēŕ ēxƥŕēśśĩōńś."],"vreTxe":[["count","plural",{"one":["#"," ƥŕōĝŕàḿ"],"other":["#"," ƥŕōĝŕàḿś"]}]],"vwFKu0":["Ćàśţ & Ćŕēŵ"],"vyL1gO":["Ŕēĺēàśē Ďàţē (ďēść)"],"w/bY7R":["Ĺōĝś"],"w2pCRr":["Śĥōŵ:"],"w3KBq0":["Àĺĺōŵś ƥŕōĝŕàḿś ţō ƥĺàŷ à ƀĩţ ĺàţē ĩƒ ţĥē ƥŕēvĩōũś ƥŕōĝŕàḿ ţōōķ ĺōńĝēŕ ţĥàń ũśũàĺ. Ĩƒ à ƥŕōĝŕàḿ ĩś ţōō ĺàţē, Ƒĺēx ĩś śćĥēďũĺēď ĩńśţēàď."],"w3g+lo":["Ĺēţ\'ś ĝēţ śţàŕţēď..."],"wBmIEf":["Ńũḿƀēŕ ōƒ ĥōũŕś ţō ĩńćĺũďē ĩń ţĥē XḾĹŢV ƒĩĺē"],"wBo/7A":["Ēŕŕōŕ ŵĥĩĺē śćĥēďũĺĩńĝ ",["taskId"],". Ćĥēćķ śēŕvēŕ ĺōĝś ƒōŕ ďēţàĩĺś"],"wKClDM":["Àďďś à ćĥàńńēĺ ŕēďĩŕēćţ. Ďũŕĩńĝ ţĥĩś ƥēŕĩōď ōƒ ţĩḿē, ţĥē ćĥàńńēĺ ŵĩĺĺ ŕēďĩŕēćţ ţō àńōţĥēŕ ćĥàńńēĺ."],"wMHvYH":["Vàĺũē"],"wOUKOZ":["Ḿàx Ţŕũē Ƥēàķ"],"wZOYCY":["Vĩďēō Ƒōŕḿàţ"],"wdfBIP":["Śōŕţ ßŷ..."],"wdxz7K":["Śōũŕćē"],"wkQ2tb":["Àďďś Ƒĺēx ƀŕēàķś àƒţēŕ ēàćĥ ŢV ēƥĩśōďē ōŕ ḿōvĩē ţō ēńśũŕē ţĥàţ ţĥē ƥŕōĝŕàḿ śţàŕţś àţ ōńē ōƒ ţĥē àĺĺōŵēď ḿĩńũţē ḿàŕķś."],"wlYdUk":[["count","plural",{"one":["ĥōũŕ"],"other":["ĥōũŕś"]}]],"wpT1VN":["Ćōńďĩţĩōń"],"wtuVU4":["Ƒŕēǫũēńćŷ"],"wwu18a":["Ĩćōń"],"x+AjXa":["Ćĥàńńēĺ Ƒàĺĺƀàćķ"],"x/dwZe":["Ēńàƀĺē ĩƒ ţĥē ŵàţēŕḿàŕķ ĩś àń àńĩḿàţēď ĜĨƑ ōŕ ƤŃĜ. Ţĥē ŵàţēŕḿàŕķ ŵĩĺĺ ĺōōƥ àććōŕďĩńĝ ţō ţĥē ĩḿàĝē\'ś ćōńƒĩĝũŕàţĩōń. Ĩƒ ţĥĩś ōƥţĩōń ĩś ēńàƀĺēď àńď ţĥē ĩḿàĝē ĩś ńōţ àńĩḿàţēď, ţĥēŕē ŵĩĺĺ ƀē ƥĺàŷƀàćķ ēŕŕōŕś."],"x1tGMH":["Ōvēŕŕĩďē ĥōŵ ƥŕōĝŕàḿś ŵĩţĥĩń ţĥĩś śĺōţ àŕē ƥàďďēď."],"x6/Zc6":["Ţàĩĺ"],"x63PSs":["Śēàŕćĥ ƒōŕ śĥōŵś"],"x7PDL5":["Ĺōĝĝĩńĝ"],"xCJdfg":["Ćĺēàŕ"],"xDAtGP":["Ḿēśśàĝē"],"xDPFrK":["Śćàń ",["0"]],"xGVfLh":["Ćōńţĩńũē"],"xGYZfl":["Ēďĩţ Ĺĩƀŕàŕĩēś"],"xIn7qU":["Ďĩśàƀĺē Ĥàŕďŵàŕē Ďēćōďĩńĝ"],"xJIepX":["Ďēƒàũĺţ Ćōńƒĩĝ"],"xOkMus":["Ĥàŕďŵàŕē Àććēĺ."],"xPmesF":["Ĺōũďńēśś Ŕàńĝē Ţàŕĝēţ"],"xQC5se":["Àďvàńćēď Vĩďēō Ōƥţĩōńś"],"xXrtPO":["Ƒàĩĺēď ţō ĺōàď ĩţēḿ ďēţàĩĺś! Ćĥēćķ ĺōĝś ƒōŕ ďēţàĩĺś"],"xazqmy":["Śēàśōńś"],"xbtgIC":["ĤŴ Àććēĺēŕàţĩōń"],"xdA/+p":["Ţōōĺś"],"xmBknQ":["Ƒĩĺĺēŕ Ĺĩśţś"],"xptXTM":["Śēĺēćţ Àŕţĩśţś ţō Ŕēḿōvē"],"xqIrnW":["Ĺĩƀŕàŕŷ Ćĺĩƥ (ńōţ ŷēţ ĩḿƥĺēḿēńţēď)"],"xu3Kah":[["0","plural",{"one":["#"," ƥŕōĝŕàḿ"],"other":["#"," ƥŕōĝŕàḿś"]}]],"y28hnO":["Ƥōśţ"],"y4Jmre":["ßŕēàķ Ďũŕàţĩōń"],"y4iKY3":[["count","plural",{"one":["#"," àĺƀũḿ"],"other":["#"," àĺƀũḿś"]}]],"y5x0aB":[["0"]," Ĩńƒō"],"y7wpam":[["value","plural",{"one":["#"," ƥŕōĝŕàḿ"],"other":["#"," ƥŕōĝŕàḿś"]}]],"yDUcwc":["Ḿàńũàĺĺŷ àďď àń àććēśś ţōķēń ƒŕōḿ ŷōũŕ Ēḿƀŷ śēŕvēŕ"],"yEDNx2":["Ţũńàŕŕ ŵĩĺĺ ũƥďàţē Ƥĺēx\'ś \\"ńōŵ ƥĺàŷĩńĝ\\" śţàţē ŵĥĩĺē ćĥàńńēĺś àŕē àćţĩvē."],"yPE51X":["Ćōńƒĩĝũŕē ţŕàńśćōďĩńĝ śēţţĩńĝś ƒōŕ Ţũńàŕŕ\'ś śţŕēàḿś. Ēàćĥ ćĥàńńēĺ ĩś àśśĩĝńēď ōńē ţŕàńśćōďē ćōńƒĩĝũŕàţĩōń."],"yPK7+5":["Àũţō-Ũƥďàţē Ĝũĩďē"],"yQE2r9":["Ĺōàďĩńĝ"],"yRkqG9":["Ĺĩḿĩţ"],"yX8Rkw":["Àďď Àĺĺ"],"yftDqj":["Ńēŵ Ƒĩĺĺēŕ Ĺĩśţ"],"yjzkvk":["Śţōƥ Ţŕàńśćōďē Śēśśĩōń"],"ysJk7v":["Ḿōvĩē Śōŕţ Ōŕďēŕ"],"ysecYP":["Śēàŕćĥ ƒōŕ à ƥŕōĝŕàḿ"],"ytXxnP":["Ƒōŕćēď"],"yz/C2/":["Ŕēŕũń"],"yz7wBu":["Ćĺōśē"],"z4K9d+":["Ŕōĺĺ ƀàśēď ōń śĩźē"],"z61uNR":["Àďď Ƒĺēx Ţĩḿē"],"zV6tsp":["Ćōńśōĺĩďàţē"],"zV9awV":["Ƒōŕćē Śćàń"],"zpylsE":["Ţŕàńśćōďĩńĝ Śēţţĩńĝś"],"zrmjn/":["Ḿàx Ďũŕàţĩōń"],"zthKEs":["Ţĥē śţŕēàḿĩńĝ ḿōďē àƒƒēćţś ţĥē ţŷƥē ōƒ ũńďēŕĺŷĩńĝ ţŕàńśćōďĩńĝ ƥŕōćēśś ũśēď ţō ćŕēàţē ţĥē ćĥàńńēĺ\'ś vĩďēō śţŕēàḿ.<0/>Ĺēàŕń ḿōŕē àƀōũţ Ţũńàŕŕ\'ś śţŕēàḿ ḿōďēś <1>ĥēŕē!"],"zvjEp6":["Ƒĩĺĺēŕ ćōōĺďōŵń ḿũśţ ƀē à ńũḿƀēŕ"],"zx4BuL":["Ŵēēķ"],"zyLvkd":["Ćàţēĝōŕŷ Ĺōĝ Ĺēvēĺś"]}', +) as Messages;