From 4662df20a964ceb52215a8a5042dea20b6d3240a Mon Sep 17 00:00:00 2001 From: Christian Benincasa Date: Thu, 14 May 2026 20:00:24 -0400 Subject: [PATCH 1/2] feat: integrate new stream selector with the ffmpeg pipeline --- server/src/ffmpeg/FFmpegModule.ts | 2 + server/src/ffmpeg/FfmpegStreamFactory.ts | 38 +- .../ffmpeg/StreamSelectionEvaluator.test.ts | 375 ++++++++++++++++++ server/src/ffmpeg/StreamSelectionEvaluator.ts | 57 ++- server/src/ffmpeg/StreamSelector.ts | 4 + .../StreamSelectionProfileResolver.ts | 35 +- types/src/schemas/streamSelectionSchema.ts | 2 + 7 files changed, 470 insertions(+), 43 deletions(-) diff --git a/server/src/ffmpeg/FFmpegModule.ts b/server/src/ffmpeg/FFmpegModule.ts index 13399c14b..f8271849f 100644 --- a/server/src/ffmpeg/FFmpegModule.ts +++ b/server/src/ffmpeg/FFmpegModule.ts @@ -5,6 +5,7 @@ import { ContainerModule } from 'inversify'; import type { ChannelOrm } from '../db/schema/Channel.ts'; import { bindAssistedFactory } from '../util/assistedInject.ts'; import { FfmpegInfo } from './ffmpegInfo.ts'; +import { StreamSelector } from './StreamSelector.ts'; export type FFmpegAssistedFactory = ( transcodeConfig: TranscodeConfigOrm, @@ -19,6 +20,7 @@ const FFmpegModule = new ContainerModule(({ bind }) => { ); bind(FfmpegInfo).toSelf().inSingletonScope(); + bind(StreamSelector).toSelf().inSingletonScope(); }); export { FFmpegModule }; diff --git a/server/src/ffmpeg/FfmpegStreamFactory.ts b/server/src/ffmpeg/FfmpegStreamFactory.ts index 87f882df2..9a41b69e4 100644 --- a/server/src/ffmpeg/FfmpegStreamFactory.ts +++ b/server/src/ffmpeg/FfmpegStreamFactory.ts @@ -23,7 +23,6 @@ import { injectable } from 'inversify'; import { isUndefined } from 'lodash-es'; import type { DeepReadonly } from 'ts-essentials'; import { match, P } from 'ts-pattern'; -import type { IChannelDB } from '../db/interfaces/IChannelDB.ts'; import { FeatureFlagService } from '../services/FeatureFlagService.ts'; import { isImageBasedSubtitle } from '../stream/util.ts'; import { KEYS } from '../types/inject.ts'; @@ -34,7 +33,6 @@ import { FfmpegPlaybackParamsCalculator } from './FfmpegPlaybackParamsCalculator import { FfmpegProcess } from './FfmpegProcess.ts'; import { FfmpegTranscodeSession } from './FfmpegTrancodeSession.ts'; import { StreamSelector } from './StreamSelector.ts'; -import { SubtitleStreamPicker } from './SubtitleStreamPicker.ts'; import { AudioStream, EmbeddedSubtitleStream, @@ -101,7 +99,6 @@ export class FfmpegStreamFactory extends IFFMPEG { @injected(KEYS.SettingsDB) private settingsDB: ISettingsDB, @injected(KEYS.PipelineBuilderFactory) private pipelineBuilderFactory: PipelineBuilderFactory, - @injected(KEYS.ChannelDB) private channelDB: IChannelDB, @injected(FeatureFlagService) private featureFlagService: FeatureFlagService, @injected(StreamSelector) private streamSelector: StreamSelector, @@ -452,6 +449,7 @@ export class FfmpegStreamFactory extends IFFMPEG { lineupItem, audioStreams: streamDetails.audioDetails, subtitleStreams: streamDetails.subtitleDetails ?? [], + hints: { preferTextBased: true }, }); audioInput = new AudioInputSource( @@ -532,24 +530,21 @@ export class FfmpegStreamFactory extends IFFMPEG { // sidecar (Convert) is available since we're not re-encoding video for // burn-in. if ( - isDefined(streamDetails.subtitleDetails) && - this.channel.subtitlesEnabled + isDefined(streamDetails.audioDetails) && + isDefined(streamDetails.subtitleDetails) ) { const sidecarEnabled = this.featureFlagService.get( 'webvttSidecarEnabled', ); - const subtitlePreferences = - await this.channelDB.getChannelSubtitlePreferences(this.channel.uuid); - - const pickedSubtitleStream = await SubtitleStreamPicker.pickSubtitles( - subtitlePreferences, - lineupItem, - streamDetails.subtitleDetails, - // In copy-all mode, always prefer text-based subs for sidecar - // since burn-in is not available. - { preferTextBased: isPassthrough || sidecarEnabled }, - ); + const { subtitleStream: pickedSubtitleStream } = + await this.streamSelector.selectAudioAndSubtitleStreams({ + channel: this.channel, + lineupItem, + audioStreams: streamDetails.audioDetails, + subtitleStreams: streamDetails.subtitleDetails, + hints: sidecarEnabled ? { preferTextBased: true } : undefined, + }); if (pickedSubtitleStream) { this.logger.trace('Using subtitle stream: %O', pickedSubtitleStream); @@ -653,17 +648,6 @@ export class FfmpegStreamFactory extends IFFMPEG { }); } } - } else if (!this.channel.subtitlesEnabled) { - this.logger.trace( - 'Channel %s (number = %d) does not have subtitles enabled. Skipping subtitles.', - this.channel.uuid, - this.channel.number, - ); - } else if (!streamDetails.subtitleDetails) { - this.logger.debug( - 'Program %s has no subtitle streams to choose from.', - lineupItem.program.uuid, - ); } const effectiveHwAccel = isPassthrough diff --git a/server/src/ffmpeg/StreamSelectionEvaluator.test.ts b/server/src/ffmpeg/StreamSelectionEvaluator.test.ts index 0f28f7cbb..34f7f4463 100644 --- a/server/src/ffmpeg/StreamSelectionEvaluator.test.ts +++ b/server/src/ffmpeg/StreamSelectionEvaluator.test.ts @@ -1289,4 +1289,379 @@ describe('evaluateStreamSelectionProfile', () => { expect(result.subtitleStream).toBeNull(); }); }); + + describe('preferTextBased', () => { + it('without preferTextBased, by_language picks first matching stream regardless of codec type', async () => { + // Image-based sub appears first in stream order, text-based second. + // Without preferTextBased, the image-based sub should be picked + // because it comes first and allowImageBased is true. + const subs: SubtitleStreamDetails[] = [ + makeSubtitleStream({ + index: 2, + languageCodeISO6392: 'eng', + codec: 'hdmv_pgs_subtitle', + type: 'embedded', + }), + makeSubtitleStream({ + index: 3, + languageCodeISO6392: 'eng', + codec: 'srt', + type: 'embedded', + }), + ]; + const profile = makeProfile([ + makeRule({ + subtitleAction: { + type: 'by_language', + languages: ['eng'], + filterType: 'any', + allowImageBased: true, + allowExternal: true, + // preferTextBased not set (defaults to false) + }, + }), + ]); + const celService = makeCelService(true); + + const result = await evaluateStreamSelectionProfile( + profile, + audioStreams, + subs, + celService, + celContext, + lineupItem, + ); + + expect(result.subtitleStream).not.toBeNull(); + // Image-based sub is first and should be selected + expect(result.subtitleStream!.index).toBe(2); + expect(result.subtitleStream!.codec).toBe('hdmv_pgs_subtitle'); + }); + + it('without preferTextBased, embedded text sub goes through extraction', async () => { + // The mock adds path: '/fake/path.vtt' via getSubtitleDetailsWithExtractedPath. + // Without preferTextBased, embedded text subs must go through that extraction + // step, so the returned stream should have the mock's path property. + const subs: SubtitleStreamDetails[] = [ + makeSubtitleStream({ + index: 2, + languageCodeISO6392: 'eng', + codec: 'srt', + type: 'embedded', + }), + ]; + const profile = makeProfile([ + makeRule({ + subtitleAction: { + type: 'by_language', + languages: ['eng'], + filterType: 'any', + allowImageBased: true, + allowExternal: true, + // preferTextBased not set (defaults to false) + }, + }), + ]); + const celService = makeCelService(true); + + const result = await evaluateStreamSelectionProfile( + profile, + audioStreams, + subs, + celService, + celContext, + lineupItem, + ); + + expect(result.subtitleStream).not.toBeNull(); + // Extraction mock adds path — confirms the extraction path was taken + expect((result.subtitleStream as Record)['path']).toBe( + '/fake/path.vtt', + ); + }); + + it('without preferTextBased, default embedded text sub goes through extraction', async () => { + const subs: SubtitleStreamDetails[] = [ + makeSubtitleStream({ + index: 2, + default: true, + codec: 'srt', + type: 'embedded', + }), + ]; + const profile = makeProfile([ + makeRule({ + subtitleAction: { type: 'default' }, + }), + ]); + const celService = makeCelService(true); + + const result = await evaluateStreamSelectionProfile( + profile, + audioStreams, + subs, + celService, + celContext, + lineupItem, + ); + + expect(result.subtitleStream).not.toBeNull(); + expect((result.subtitleStream as Record)['path']).toBe( + '/fake/path.vtt', + ); + }); + + it('by_language with action preferTextBased selects text-based sub over image-based', async () => { + // Image-based sub appears first in stream order, text-based second. + // With preferTextBased, text-based should be selected. + const subs: SubtitleStreamDetails[] = [ + makeSubtitleStream({ + index: 2, + languageCodeISO6392: 'eng', + codec: 'hdmv_pgs_subtitle', + type: 'embedded', + }), + makeSubtitleStream({ + index: 3, + languageCodeISO6392: 'eng', + codec: 'srt', + type: 'embedded', + }), + ]; + const profile = makeProfile([ + makeRule({ + subtitleAction: { + type: 'by_language', + languages: ['eng'], + filterType: 'any', + allowImageBased: true, + allowExternal: true, + preferTextBased: true, + }, + }), + ]); + const celService = makeCelService(true); + + const result = await evaluateStreamSelectionProfile( + profile, + audioStreams, + subs, + celService, + celContext, + lineupItem, + ); + + expect(result.subtitleStream).not.toBeNull(); + expect(result.subtitleStream!.index).toBe(3); + expect(result.subtitleStream!.codec).toBe('srt'); + }); + + it('by_language with runtime hint preferTextBased selects text-based sub over image-based', async () => { + const subs: SubtitleStreamDetails[] = [ + makeSubtitleStream({ + index: 2, + languageCodeISO6392: 'eng', + codec: 'hdmv_pgs_subtitle', + type: 'embedded', + }), + makeSubtitleStream({ + index: 3, + languageCodeISO6392: 'eng', + codec: 'srt', + type: 'embedded', + }), + ]; + const profile = makeProfile([ + makeRule({ + subtitleAction: { + type: 'by_language', + languages: ['eng'], + filterType: 'any', + allowImageBased: true, + allowExternal: true, + }, + }), + ]); + const celService = makeCelService(true); + + const result = await evaluateStreamSelectionProfile( + profile, + audioStreams, + subs, + celService, + celContext, + lineupItem, + { preferTextBased: true }, + ); + + expect(result.subtitleStream).not.toBeNull(); + expect(result.subtitleStream!.index).toBe(3); + expect(result.subtitleStream!.codec).toBe('srt'); + }); + + it('by_language with preferTextBased returns embedded text sub without extraction', async () => { + // When preferTextBased is active, embedded text-based subs should be + // returned directly (no call to getSubtitleDetailsWithExtractedPath), + // meaning they won't have the fake path added by the mock. + const subs: SubtitleStreamDetails[] = [ + makeSubtitleStream({ + index: 2, + languageCodeISO6392: 'eng', + codec: 'srt', + type: 'embedded', + }), + ]; + const profile = makeProfile([ + makeRule({ + subtitleAction: { + type: 'by_language', + languages: ['eng'], + filterType: 'any', + allowImageBased: true, + allowExternal: true, + preferTextBased: true, + }, + }), + ]); + const celService = makeCelService(true); + + const result = await evaluateStreamSelectionProfile( + profile, + audioStreams, + subs, + celService, + celContext, + lineupItem, + ); + + expect(result.subtitleStream).not.toBeNull(); + // The mock adds path: '/fake/path.vtt' — since preferTextBased bypasses + // extraction, the original stream is returned without that property. + expect(result.subtitleStream!.index).toBe(2); + expect( + (result.subtitleStream as Record)['path'], + ).toBeUndefined(); + }); + + it('default with preferTextBased returns embedded text sub without extraction', async () => { + const subs: SubtitleStreamDetails[] = [ + makeSubtitleStream({ + index: 2, + default: true, + codec: 'srt', + type: 'embedded', + }), + ]; + const profile = makeProfile([ + makeRule({ + subtitleAction: { + type: 'default', + preferTextBased: true, + }, + }), + ]); + const celService = makeCelService(true); + + const result = await evaluateStreamSelectionProfile( + profile, + audioStreams, + subs, + celService, + celContext, + lineupItem, + ); + + expect(result.subtitleStream).not.toBeNull(); + expect(result.subtitleStream!.index).toBe(2); + expect( + (result.subtitleStream as Record)['path'], + ).toBeUndefined(); + }); + + it('runtime hint overrides action preferTextBased=false', async () => { + const subs: SubtitleStreamDetails[] = [ + makeSubtitleStream({ + index: 2, + languageCodeISO6392: 'eng', + codec: 'hdmv_pgs_subtitle', + type: 'embedded', + }), + makeSubtitleStream({ + index: 3, + languageCodeISO6392: 'eng', + codec: 'srt', + type: 'embedded', + }), + ]; + // Action has preferTextBased: false (default) + const profile = makeProfile([ + makeRule({ + subtitleAction: { + type: 'by_language', + languages: ['eng'], + filterType: 'any', + allowImageBased: true, + allowExternal: true, + preferTextBased: false, + }, + }), + ]); + const celService = makeCelService(true); + + // Runtime hint overrides to true + const result = await evaluateStreamSelectionProfile( + profile, + audioStreams, + subs, + celService, + celContext, + lineupItem, + { preferTextBased: true }, + ); + + expect(result.subtitleStream).not.toBeNull(); + expect(result.subtitleStream!.index).toBe(3); + expect(result.subtitleStream!.codec).toBe('srt'); + }); + + it('default with preferTextBased sorts text-based before image-based for default selection', async () => { + const subs: SubtitleStreamDetails[] = [ + makeSubtitleStream({ + index: 2, + default: true, + codec: 'hdmv_pgs_subtitle', + type: 'embedded', + }), + makeSubtitleStream({ + index: 3, + default: true, + codec: 'srt', + type: 'embedded', + }), + ]; + const profile = makeProfile([ + makeRule({ + subtitleAction: { + type: 'default', + preferTextBased: true, + }, + }), + ]); + const celService = makeCelService(true); + + const result = await evaluateStreamSelectionProfile( + profile, + audioStreams, + subs, + celService, + celContext, + lineupItem, + ); + + // Text-based default should be found first due to sorting + expect(result.subtitleStream).not.toBeNull(); + expect(result.subtitleStream!.index).toBe(3); + expect(result.subtitleStream!.codec).toBe('srt'); + }); + }); }); diff --git a/server/src/ffmpeg/StreamSelectionEvaluator.ts b/server/src/ffmpeg/StreamSelectionEvaluator.ts index 7126e9a82..6ce1df5aa 100644 --- a/server/src/ffmpeg/StreamSelectionEvaluator.ts +++ b/server/src/ffmpeg/StreamSelectionEvaluator.ts @@ -83,6 +83,10 @@ export function buildCelContext( }; } +export type StreamSelectionHints = { + preferTextBased?: boolean; +}; + export async function evaluateStreamSelectionProfile( profile: StreamSelectionProfile, audioStreams: NonEmptyArray, @@ -90,6 +94,7 @@ export async function evaluateStreamSelectionProfile( celService: CelEvaluationService, celContext: StreamSelectionCelContext, lineupItem: ContentBackedStreamLineupItem, + hints?: StreamSelectionHints, ): Promise { for (const rule of profile.rules) { const conditionResult = celService.evaluate(rule.condition, celContext); @@ -104,6 +109,7 @@ export async function evaluateStreamSelectionProfile( rule.subtitleAction, subtitleStreams, lineupItem, + hints, ); return { audioStream, subtitleStream }; } @@ -177,6 +183,7 @@ async function resolveSubtitleAction( action: SubtitleAction, subtitleStreams: SubtitleStreamDetails[] | undefined, lineupItem: ContentBackedStreamLineupItem, + hints?: StreamSelectionHints, ): Promise { switch (action.type) { case 'disable': @@ -186,10 +193,34 @@ async function resolveSubtitleAction( if (!subtitleStreams || subtitleStreams.length === 0) { return null; } - const defaultStream = subtitleStreams.find((s) => s.default); + + const effectivePreferText = + hints?.preferTextBased || action.preferTextBased; + + const candidates = [...subtitleStreams]; + if (effectivePreferText) { + candidates.sort((a, b) => { + const aImage = isImageBasedSubtitle(a.codec) ? 1 : 0; + const bImage = isImageBasedSubtitle(b.codec) ? 1 : 0; + return aImage - bImage; + }); + } + + const defaultStream = candidates.find((s) => s.default); if (!defaultStream) { return null; } + + // When preferTextBased is active and the default is an embedded text-based + // sub, return it directly — the caller will extract via the pipeline. + if ( + effectivePreferText && + defaultStream.type === 'embedded' && + !isImageBasedSubtitle(defaultStream.codec) + ) { + return defaultStream; + } + const extracted = await SubtitleStreamPicker.getSubtitleDetailsWithExtractedPath( lineupItem, @@ -216,9 +247,21 @@ async function resolveSubtitleAction( return null; } + const effectivePreferText = + hints?.preferTextBased || action.preferTextBased; + + const candidates = [...subtitleStreams]; + if (effectivePreferText) { + candidates.sort((a, b) => { + const aImage = isImageBasedSubtitle(a.codec) ? 1 : 0; + const bImage = isImageBasedSubtitle(b.codec) ? 1 : 0; + return aImage - bImage; + }); + } + for (const lang of action.languages) { const langLower = lang.toLowerCase(); - for (const stream of subtitleStreams) { + for (const stream of candidates) { // Language match if ( stream.languageCodeISO6392?.toLowerCase() !== langLower && @@ -246,6 +289,16 @@ async function resolveSubtitleAction( continue; } + // When preferTextBased is active and we have an embedded text-based + // sub, return it directly — the caller will extract via the pipeline. + if ( + effectivePreferText && + !isImageBasedSubtitle(stream.codec) && + stream.type === 'embedded' + ) { + return stream; + } + // For embedded text-based subs, verify extraction if ( !isImageBasedSubtitle(stream.codec) && diff --git a/server/src/ffmpeg/StreamSelector.ts b/server/src/ffmpeg/StreamSelector.ts index 56009d268..3d9939c00 100644 --- a/server/src/ffmpeg/StreamSelector.ts +++ b/server/src/ffmpeg/StreamSelector.ts @@ -13,12 +13,14 @@ import { buildCelContext, evaluateStreamSelectionProfile, } from './StreamSelectionEvaluator.ts'; +import type { StreamSelectionHints } from './StreamSelectionEvaluator.ts'; type StreamSelectRequest = { channel: ChannelOrm; lineupItem: ContentBackedStreamLineupItem; audioStreams: NonEmptyArray; subtitleStreams: Array; + hints?: StreamSelectionHints; }; @injectable() @@ -34,6 +36,7 @@ export class StreamSelector { lineupItem, audioStreams, subtitleStreams, + hints, }: StreamSelectRequest) { const selectionCtx = { channelId: channel.uuid, @@ -61,6 +64,7 @@ export class StreamSelector { this.celService, celContext, lineupItem, + hints, ); } } diff --git a/server/src/services/StreamSelectionProfileResolver.ts b/server/src/services/StreamSelectionProfileResolver.ts index 9c1fbd2a1..baa0bd28a 100644 --- a/server/src/services/StreamSelectionProfileResolver.ts +++ b/server/src/services/StreamSelectionProfileResolver.ts @@ -168,23 +168,30 @@ export class StreamSelectionProfileResolver { } : { type: 'default' as const }; - // Build subtitle action from channel subtitle preferences - const subtitlePrefs = - await this.channelDB.getChannelSubtitlePreferences(channelId); + // Check if the channel has subtitles enabled + const channel = await this.channelDB.getChannel(channelId); let subtitleAction: StreamSelectionRule['subtitleAction']; - if (subtitlePrefs.length > 0) { - const sorted = orderBy(subtitlePrefs, 'priority', 'asc'); - const topPref = sorted[0]!; - subtitleAction = { - type: 'by_language' as const, - languages: sorted.map((p) => p.languageCode), - filterType: topPref.filterType ?? 'any', - allowImageBased: Boolean(topPref.allowImageBased ?? true), - allowExternal: Boolean(topPref.allowExternal ?? true), - }; + if (!channel?.subtitlesEnabled) { + subtitleAction = { type: 'disable' as const }; } else { - subtitleAction = { type: 'default' as const }; + // Build subtitle action from channel subtitle preferences + const subtitlePrefs = + await this.channelDB.getChannelSubtitlePreferences(channelId); + + if (subtitlePrefs.length > 0) { + const sorted = orderBy(subtitlePrefs, 'priority', 'asc'); + const topPref = sorted[0]!; + subtitleAction = { + type: 'by_language' as const, + languages: sorted.map((p) => p.languageCode), + filterType: topPref.filterType ?? 'any', + allowImageBased: Boolean(topPref.allowImageBased ?? true), + allowExternal: Boolean(topPref.allowExternal ?? true), + }; + } else { + subtitleAction = { type: 'default' as const }; + } } rules.push({ diff --git a/types/src/schemas/streamSelectionSchema.ts b/types/src/schemas/streamSelectionSchema.ts index 90faa7a41..c550355bb 100644 --- a/types/src/schemas/streamSelectionSchema.ts +++ b/types/src/schemas/streamSelectionSchema.ts @@ -36,10 +36,12 @@ export const SubtitleActionByLanguageSchema = z.object({ filterType: SubtitleFilterSchema.default('any'), allowImageBased: z.boolean().default(true), allowExternal: z.boolean().default(true), + preferTextBased: z.boolean().default(false), }); export const SubtitleActionDefaultSchema = z.object({ type: z.literal('default'), + preferTextBased: z.boolean().default(false), }); export const SubtitleActionSchema = z.discriminatedUnion('type', [ From efc020d0e32b4c4fa49abc944731cee9d8ecd175 Mon Sep 17 00:00:00 2001 From: Christian Benincasa Date: Fri, 15 May 2026 16:05:10 -0400 Subject: [PATCH 2/2] feat: add stream selection UI; first pass --- server/src/ffmpeg/StreamSelectionEvaluator.ts | 8 +- web/src/components/LanguageAutocomplete.tsx | 23 +- .../profiles/StreamSelectionProfilesTable.tsx | 172 ++++++ .../profiles/StreamSelectionRuleEditor.tsx | 541 ++++++++++++++++++ .../condition/ConditionClauseEditor.tsx | 231 ++++++++ .../profiles/condition/ConditionEditor.tsx | 169 ++++++ .../condition/ConditionGroupEditor.tsx | 171 ++++++ .../profiles/condition/celGenerator.test.ts | 294 ++++++++++ .../profiles/condition/celGenerator.ts | 80 +++ .../profiles/condition/celParser.ts | 318 ++++++++++ .../components/profiles/condition/index.ts | 8 + .../components/profiles/condition/types.ts | 92 +++ .../profiles/streamSelectionFormTypes.ts | 59 ++ .../ffmpeg/TranscodeConfigSettingsForm.tsx | 105 +--- .../settings/ffmpeg/TranscodeConfigsTable.tsx | 24 +- web/src/hooks/useNavItems.tsx | 27 +- web/src/hooks/useRouteName.ts | 8 + web/src/locales/en/messages.po | 309 +++++++++- web/src/locales/en/messages.ts | 2 +- web/src/locales/es/messages.po | 309 +++++++++- web/src/locales/es/messages.ts | 2 +- web/src/locales/pseudo-LOCALE/messages.po | 309 +++++++++- web/src/locales/pseudo-LOCALE/messages.ts | 2 +- .../profiles/StreamSelectionProfilePage.tsx | 350 +++++++++++ .../profiles/StreamSelectionProfilesPage.tsx | 23 + .../pages/profiles/TranscodeConfigPage.tsx | 50 ++ .../pages/profiles/TranscodeConfigsPage.tsx | 24 + web/src/pages/settings/FfmpegSettingsPage.tsx | 37 +- web/src/routeTree.gen.ts | 108 ++++ web/src/routes/channels_/$channelId/route.tsx | 12 +- web/src/routes/channels_/test.tsx | 6 +- .../media_sources_/$mediaSourceId/index.tsx | 4 +- .../$mediaSourceId/libraries_.$libraryId.tsx | 12 +- web/src/routes/profiles/stream-selection.tsx | 9 + .../profiles/stream-selection_/$profileId.tsx | 13 + .../routes/profiles/stream-selection_/new.tsx | 6 + web/src/routes/profiles/transcode.tsx | 6 + .../routes/profiles/transcode_/$configId.tsx | 11 + 38 files changed, 3726 insertions(+), 208 deletions(-) create mode 100644 web/src/components/profiles/StreamSelectionProfilesTable.tsx create mode 100644 web/src/components/profiles/StreamSelectionRuleEditor.tsx create mode 100644 web/src/components/profiles/condition/ConditionClauseEditor.tsx create mode 100644 web/src/components/profiles/condition/ConditionEditor.tsx create mode 100644 web/src/components/profiles/condition/ConditionGroupEditor.tsx create mode 100644 web/src/components/profiles/condition/celGenerator.test.ts create mode 100644 web/src/components/profiles/condition/celGenerator.ts create mode 100644 web/src/components/profiles/condition/celParser.ts create mode 100644 web/src/components/profiles/condition/index.ts create mode 100644 web/src/components/profiles/condition/types.ts create mode 100644 web/src/components/profiles/streamSelectionFormTypes.ts create mode 100644 web/src/pages/profiles/StreamSelectionProfilePage.tsx create mode 100644 web/src/pages/profiles/StreamSelectionProfilesPage.tsx create mode 100644 web/src/pages/profiles/TranscodeConfigPage.tsx create mode 100644 web/src/pages/profiles/TranscodeConfigsPage.tsx create mode 100644 web/src/routes/profiles/stream-selection.tsx create mode 100644 web/src/routes/profiles/stream-selection_/$profileId.tsx create mode 100644 web/src/routes/profiles/stream-selection_/new.tsx create mode 100644 web/src/routes/profiles/transcode.tsx create mode 100644 web/src/routes/profiles/transcode_/$configId.tsx diff --git a/server/src/ffmpeg/StreamSelectionEvaluator.ts b/server/src/ffmpeg/StreamSelectionEvaluator.ts index 6ce1df5aa..222837e24 100644 --- a/server/src/ffmpeg/StreamSelectionEvaluator.ts +++ b/server/src/ffmpeg/StreamSelectionEvaluator.ts @@ -153,7 +153,7 @@ export function resolveAudioAction( } } // Fallback to default behavior - return selectDefautlAudioStream(audioStreams); + return selectDefaultAudioStream(audioStreams); } case 'by_title': { @@ -161,15 +161,15 @@ export function resolveAudioAction( const match = audioStreams.find((s) => s.title?.toLowerCase().includes(titleLower), ); - return match ?? selectDefautlAudioStream(audioStreams); + return match ?? selectDefaultAudioStream(audioStreams); } case 'default': - return selectDefautlAudioStream(audioStreams); + return selectDefaultAudioStream(audioStreams); } } -function selectDefautlAudioStream( +function selectDefaultAudioStream( audioStreams: NonEmptyArray, ) { return ( diff --git a/web/src/components/LanguageAutocomplete.tsx b/web/src/components/LanguageAutocomplete.tsx index 5db87534c..4246d44f1 100644 --- a/web/src/components/LanguageAutocomplete.tsx +++ b/web/src/components/LanguageAutocomplete.tsx @@ -1,5 +1,5 @@ -import { useLingui } from '@lingui/react/macro'; import languages from '@cospired/i18n-iso-languages/index'; +import { useLingui } from '@lingui/react/macro'; import type { AutocompleteChangeReason, AutocompleteProps, @@ -7,13 +7,13 @@ import type { } from '@mui/material'; import { Autocomplete, TextField } from '@mui/material'; import { seq } from '@tunarr/shared/util'; -import { entries, isUndefined, map, reject, sortBy } from 'lodash-es'; +import { entries, isUndefined, reject, sortBy } from 'lodash-es'; import { useCallback, useMemo } from 'react'; import type { FieldError } from 'react-hook-form'; import { isNonEmptyString } from '../helpers/util.ts'; type Props = { - values: LanguagePreferenceValue[]; + values: string[]; // iso6392 onSelect: ( v: LanguagePreferenceValue, allValues: LanguagePreferenceValue[], @@ -51,10 +51,6 @@ export const LanguageAutocomplete = ({ ...rest }: Props) => { const { t } = useLingui(); - const selectedCodes = useMemo( - () => map(values, (pref) => pref.iso6392), - [values], - ); const languageOptions = useMemo( () => @@ -103,16 +99,19 @@ export const LanguageAutocomplete = ({ if (allowMultiple) { return languageOptions; } - return reject(languageOptions, ({ iso6392 }) => - selectedCodes.includes(iso6392), - ); - }, [allowMultiple, languageOptions, selectedCodes]); + return reject(languageOptions, ({ iso6392 }) => values.includes(iso6392)); + }, [allowMultiple, languageOptions, values]); + + const formValues = useMemo(() => { + const selected = new Set(values); + return opts.filter((opt) => selected.has(opt.iso6392)); + }, [opts, values]); return ( { if (details) { handleChange(details.option, reason, newValue); diff --git a/web/src/components/profiles/StreamSelectionProfilesTable.tsx b/web/src/components/profiles/StreamSelectionProfilesTable.tsx new file mode 100644 index 000000000..bf710a7ba --- /dev/null +++ b/web/src/components/profiles/StreamSelectionProfilesTable.tsx @@ -0,0 +1,172 @@ +import { DeleteConfirmationDialog } from '@/components/DeleteConfirmationDialog'; +import { + deleteApiStreamSelectionProfilesByIdMutation, + getApiStreamSelectionProfilesOptions, + getApiStreamSelectionProfilesQueryKey, +} from '@/generated/@tanstack/react-query.gen'; +import type { GetApiStreamSelectionProfilesResponse } from '@/generated/types.gen'; +import { t } from '@lingui/core/macro'; +import { Trans } from '@lingui/react/macro'; +import { AddCircle, Delete, Edit } from '@mui/icons-material'; +import { Box, Button, Chip, IconButton, Stack, Tooltip } from '@mui/material'; +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { Link } from '@tanstack/react-router'; +import { + MaterialReactTable, + useMaterialReactTable, + type MRT_ColumnDef, + type MRT_Row, +} from 'material-react-table'; +import { useCallback, useMemo, useState } from 'react'; + +type Profile = GetApiStreamSelectionProfilesResponse[number]; + +export const StreamSelectionProfilesTable = () => { + const queryClient = useQueryClient(); + const { data: profiles = [] } = useQuery({ + ...getApiStreamSelectionProfilesOptions(), + }); + + const [confirmDelete, setConfirmDelete] = useState(null); + + const deleteMutation = useMutation({ + ...deleteApiStreamSelectionProfilesByIdMutation(), + onSuccess: async () => { + setConfirmDelete(null); + await queryClient.invalidateQueries({ + queryKey: getApiStreamSelectionProfilesQueryKey(), + }); + }, + }); + + const renderRowActions = useCallback( + ({ row: { original: profile } }: { row: MRT_Row }) => { + return ( + + + + + + + + setConfirmDelete(profile)}> + + + + + ); + }, + [], + ); + + const columns = useMemo[]>( + () => [ + { + header: t`Name`, + accessorKey: 'name', + }, + { + header: t`Rules`, + accessorFn: (row) => row.rules.length, + size: 100, + }, + { + header: t`Used By`, + size: 200, + Cell({ row: { original } }) { + const total = + original.usedByChannels + + original.usedByFillers + + original.usedByPrograms; + if (total === 0) { + return ( + + ); + } + return ( + + {original.usedByChannels > 0 && ( + + )} + {original.usedByFillers > 0 && ( + + )} + {original.usedByPrograms > 0 && ( + + )} + + ); + }, + }, + ], + [], + ); + + const table = useMaterialReactTable({ + data: profiles, + columns, + renderRowActions, + enableRowActions: true, + displayColumnDefOptions: { + 'mrt-row-actions': { + size: 80, + grow: false, + Header: '', + visibleInShowHideMenu: false, + }, + }, + renderTopToolbarCustomActions() { + return ( + + + + ); + }, + }); + + return ( + <> + + { + if (confirmDelete) { + deleteMutation.mutate({ path: { id: confirmDelete.uuid } }); + } + }} + onClose={() => setConfirmDelete(null)} + dialogProps={{ + maxWidth: 'sm', + fullWidth: true, + }} + /> + + ); +}; diff --git a/web/src/components/profiles/StreamSelectionRuleEditor.tsx b/web/src/components/profiles/StreamSelectionRuleEditor.tsx new file mode 100644 index 000000000..f86a544ce --- /dev/null +++ b/web/src/components/profiles/StreamSelectionRuleEditor.tsx @@ -0,0 +1,541 @@ +import { msg, t } from '@lingui/core/macro'; +import { Trans } from '@lingui/react/macro'; +import { + Delete, + DragIndicator, + ExpandMore, + KeyboardArrowDown, + KeyboardArrowUp, +} from '@mui/icons-material'; +import { + Accordion, + AccordionDetails, + AccordionSummary, + Autocomplete, + Box, + Chip, + FormControl, + FormControlLabel, + IconButton, + InputLabel, + MenuItem, + Select, + Stack, + Switch, + TextField, + Tooltip, + Typography, +} from '@mui/material'; +import { Controller, useFormContext, useWatch } from 'react-hook-form'; +import { LanguageAutocomplete } from '../LanguageAutocomplete.tsx'; +import { ConditionEditor } from './condition/ConditionEditor.tsx'; +import type { + AudioAction, + StreamSelectionProfileFormValues, + SubtitleAction, +} from './streamSelectionFormTypes'; + +// ISO 639-1 common languages for the autocomplete +const COMMON_LANGUAGES = [ + { code: 'en', label: 'English' }, + { code: 'es', label: 'Spanish' }, + { code: 'fr', label: 'French' }, + { code: 'de', label: 'German' }, + { code: 'it', label: 'Italian' }, + { code: 'pt', label: 'Portuguese' }, + { code: 'ja', label: 'Japanese' }, + { code: 'ko', label: 'Korean' }, + { code: 'zh', label: 'Chinese' }, + { code: 'ru', label: 'Russian' }, + { code: 'ar', label: 'Arabic' }, + { code: 'hi', label: 'Hindi' }, + { code: 'nl', label: 'Dutch' }, + { code: 'sv', label: 'Swedish' }, + { code: 'no', label: 'Norwegian' }, + { code: 'da', label: 'Danish' }, + { code: 'fi', label: 'Finnish' }, + { code: 'pl', label: 'Polish' }, + { code: 'cs', label: 'Czech' }, + { code: 'th', label: 'Thai' }, +] as const; + +interface Props { + index: number; + totalRules: number; + expanded: boolean; + onToggleExpand: () => void; + onMoveUp: () => void; + onMoveDown: () => void; + onRemove: () => void; + onValidateCondition: (expression: string) => Promise; +} + +function getAudioSummary(audioType: AudioAction['type']) { + switch (audioType) { + case 'by_language': + return msg`By Language`; + case 'by_title': + return msg`By Title`; + case 'default': + return msg`Default`; + } +} + +function getSubtitleSummary(subtitleType: SubtitleAction['type']) { + switch (subtitleType) { + case 'by_language': + return msg`By Language`; + case 'default': + return msg`Default`; + case 'disable': + return msg`Disable`; + } +} + +export function StreamSelectionRuleEditor({ + index, + totalRules, + expanded, + onToggleExpand, + onMoveUp, + onMoveDown, + onRemove, + onValidateCondition, +}: Props) { + const { control } = useFormContext(); + + const prefix = `rules.${index}` as const; + const [audioType, subtitleType, label, condition] = useWatch({ + control, + name: [ + `${prefix}.audioAction.type`, + `${prefix}.subtitleAction.type`, + `${prefix}.label`, + `${prefix}.condition`, + ], + }); + + return ( + + } + sx={{ '& .MuiAccordionSummary-content': { alignItems: 'center' } }} + > + + + + Rule {index + 1} + + {!expanded && ( + <> + {label && } + + {condition || t`No condition`} + + + + + )} + + e.stopPropagation()}> + + + + + + + + + + + + + + + + + + + + + + + + + + {/* Label */} + ( + + )} + /> + + {/* Condition */} + + + + + Audio Selection + + + + Which audio track(s) to select when the condition holds + + + + ( + + + Audio Strategy + + + + )} + /> + + {audioType === 'by_language' && ( + + )} + {audioType === 'by_title' && } + + + + + + Subtitle Selection + + + + Which subtitle track(s) to select when the condition holds + + + + ( + + + Subtitle Strategy + + + + )} + /> + + {subtitleType === 'by_language' && ( + + )} + + + + + + ); +} + +function AudioByLanguageFields({ index }: { index: number }) { + const { control } = useFormContext(); + const prefix = `rules.${index}.audioAction` as const; + + return ( + + + !v || v.length === 0 + ? t`At least one language is required` + : undefined, + }} + render={({ field, fieldState: { error } }) => ( + + field.onChange((field.value ?? []).filter((v) => v !== iso6392)) + } + onSelect={({ iso6392 }) => { + field.onChange([...(field.value ?? []), iso6392]); + }} + onClear={() => field.onChange([])} + allowMultiple + helperText={ + error?.message ?? + t`Preferred languages in priority order. Type a code to add custom.` + } + textFieldProps={{ + size: 'small', + error: !!error, + }} + /> + // l.code)} + // getOptionLabel={(option) => { + // const lang = COMMON_LANGUAGES.find((l) => l.code === option); + // return lang ? `${lang.label} (${lang.code})` : option; + // }} + // value={field.value ?? []} + // onChange={(_, newValue) => field.onChange(newValue)} + // renderTags={(value, getTagProps) => + // value.map((code, i) => { + // const lang = COMMON_LANGUAGES.find((l) => l.code === code); + // return ( + // + // ); + // }) + // } + // renderInput={(params) => ( + // + // )} + // /> + )} + /> + ( + + + Prefer Channel Count + + + + )} + /> + + ); +} + +function AudioByTitleFields({ index }: { index: number }) { + const { control } = useFormContext(); + + return ( + ( + + )} + /> + ); +} + +function SubtitleByLanguageFields({ index }: { index: number }) { + const { control } = useFormContext(); + const prefix = `rules.${index}.subtitleAction` as const; + + return ( + + + !v || v.length === 0 + ? t`At least one language is required` + : undefined, + }} + render={({ field, fieldState: { error } }) => ( + l.code)} + getOptionLabel={(option) => { + const lang = COMMON_LANGUAGES.find((l) => l.code === option); + return lang ? `${lang.label} (${lang.code})` : option; + }} + value={field.value ?? []} + onChange={(_, newValue) => field.onChange(newValue)} + renderTags={(value, getTagProps) => + value.map((code, i) => { + const lang = COMMON_LANGUAGES.find((l) => l.code === code); + return ( + + ); + }) + } + renderInput={(params) => ( + + )} + /> + )} + /> + ( + + + Filter + + + + )} + /> + + ( + + } + label={t`Allow image-based subtitles`} + /> + )} + /> + ( + + } + label={t`Allow external subtitles`} + /> + )} + /> + + + ); +} diff --git a/web/src/components/profiles/condition/ConditionClauseEditor.tsx b/web/src/components/profiles/condition/ConditionClauseEditor.tsx new file mode 100644 index 000000000..3fd996ac0 --- /dev/null +++ b/web/src/components/profiles/condition/ConditionClauseEditor.tsx @@ -0,0 +1,231 @@ +import { Delete } from '@mui/icons-material'; +import { + FormControl, + IconButton, + InputLabel, + MenuItem, + Select, + Stack, + TextField, + Tooltip, +} from '@mui/material'; +import { t } from '@lingui/core/macro'; +import { Trans } from '@lingui/react/macro'; +import type { ConditionClause, ClauseType } from './types.ts'; +import { + CLAUSE_TYPE_LABELS, + COMPARISON_OPERATOR_LABELS, + LIST_OPERATOR_LABELS, + NUMERIC_OPERATOR_LABELS, + PROGRAM_TYPES, +} from './types.ts'; +import type { ComparisonOperator, ListOperator, NumericOperator } from './types.ts'; +import { LanguageAutocomplete } from '@/components/LanguageAutocomplete.tsx'; + +interface Props { + clause: ConditionClause; + onChange: (clause: ConditionClause) => void; + onRemove: () => void; + canRemove: boolean; +} + +const CLAUSE_TYPES: ClauseType[] = [ + 'program_type', + 'audio_language', + 'subtitle_language', + 'audio_channels', +]; + +export function ConditionClauseEditor({ + clause, + onChange, + onRemove, + canRemove, +}: Props) { + const handleTypeChange = (newType: ClauseType) => { + switch (newType) { + case 'always': + onChange({ type: 'always' }); + break; + case 'program_type': + onChange({ type: 'program_type', operator: 'eq', value: 'movie' }); + break; + case 'audio_language': + onChange({ type: 'audio_language', operator: 'in', value: 'eng' }); + break; + case 'subtitle_language': + onChange({ type: 'subtitle_language', operator: 'in', value: 'eng' }); + break; + case 'audio_channels': + onChange({ type: 'audio_channels', operator: 'gte', value: 6 }); + break; + } + }; + + return ( + + {/* Clause type selector */} + + + Field + + + + + {/* Operator + value fields based on clause type */} + {clause.type === 'program_type' && ( + <> + + + + + + + + )} + + {clause.type === 'audio_language' && ( + <> + + + + onChange({ ...clause, value: iso6392 })} + onRemove={() => onChange({ ...clause, value: '' })} + onClear={() => onChange({ ...clause, value: '' })} + textFieldProps={{ + size: 'small', + sx: { minWidth: 180 }, + }} + /> + + )} + + {clause.type === 'subtitle_language' && ( + <> + + + + onChange({ ...clause, value: iso6392 })} + onRemove={() => onChange({ ...clause, value: '' })} + onClear={() => onChange({ ...clause, value: '' })} + textFieldProps={{ + size: 'small', + sx: { minWidth: 180 }, + }} + /> + + )} + + {clause.type === 'audio_channels' && ( + <> + + + + { + const val = parseInt(e.target.value, 10); + if (!isNaN(val)) { + onChange({ ...clause, value: val }); + } + }} + slotProps={{ htmlInput: { min: 1, max: 16 } }} + sx={{ width: 80 }} + /> + + )} + + {/* Remove button */} + + + + + + + + + ); +} diff --git a/web/src/components/profiles/condition/ConditionEditor.tsx b/web/src/components/profiles/condition/ConditionEditor.tsx new file mode 100644 index 000000000..bbe2f2f03 --- /dev/null +++ b/web/src/components/profiles/condition/ConditionEditor.tsx @@ -0,0 +1,169 @@ +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { + Alert, + Box, + Stack, + TextField, + ToggleButton, + ToggleButtonGroup, + Typography, +} from '@mui/material'; +import { t } from '@lingui/core/macro'; +import { Trans } from '@lingui/react/macro'; +import { Controller, useFormContext } from 'react-hook-form'; +import type { StreamSelectionProfileFormValues } from '../streamSelectionFormTypes.ts'; +import type { ConditionGroup, ConditionMode } from './types.ts'; +import { createDefaultGroup } from './types.ts'; +import { celToBasicCondition } from './celParser.ts'; +import { basicConditionToCel } from './celGenerator.ts'; +import { ConditionGroupEditor } from './ConditionGroupEditor.tsx'; + +interface Props { + index: number; + onValidateCondition: (value: string) => Promise; +} + +export function ConditionEditor({ index, onValidateCondition }: Props) { + const { control, setValue, getValues } = + useFormContext(); + + const prefix = `rules.${index}` as const; + + // Try to parse the current CEL value on mount + const initialCel = getValues(`${prefix}.condition`); + const initialParsed = useMemo(() => celToBasicCondition(initialCel), [initialCel]); + + const [mode, setMode] = useState( + initialParsed ? 'basic' : 'cel', + ); + const [basicCondition, setBasicCondition] = useState( + initialParsed ?? createDefaultGroup(), + ); + const [switchError, setSwitchError] = useState(null); + + // Sync basic condition changes to the form's condition field + const updateFromBasic = useCallback( + (group: ConditionGroup) => { + setBasicCondition(group); + const cel = basicConditionToCel(group); + setValue(`${prefix}.condition`, cel, { + shouldValidate: true, + shouldDirty: true, + }); + }, + [prefix, setValue], + ); + + // When first mounting in basic mode, ensure the form field matches + useEffect(() => { + if (mode === 'basic') { + const cel = basicConditionToCel(basicCondition); + const current = getValues(`${prefix}.condition`); + if (cel !== current) { + setValue(`${prefix}.condition`, cel, { shouldDirty: true }); + } + } + // Only on mount + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const handleModeChange = ( + _: React.MouseEvent, + newMode: ConditionMode | null, + ) => { + if (newMode === null) return; + setSwitchError(null); + + if (newMode === 'basic') { + // Try to parse the current CEL string + const currentCel = getValues(`${prefix}.condition`); + const parsed = celToBasicCondition(currentCel); + if (parsed) { + setBasicCondition(parsed); + setMode('basic'); + } else { + setSwitchError( + t`This expression can't be represented in Basic mode. Edit it in CEL mode or simplify it first.`, + ); + } + } else { + // Switching to CEL — condition field already has the generated string + setMode('cel'); + } + }; + + return ( + + {/* Mode toggle */} + + + Condition + + + + Basic + + + CEL + + + + + {switchError && ( + setSwitchError(null)}> + {switchError} + + )} + + {mode === 'basic' ? ( + + + + ) : ( + { + if (!value) return t`Condition is required`; + const result = await onValidateCondition(value); + return result ?? true; + }, + }} + render={({ field, fieldState: { error } }) => ( + + )} + /> + )} + + ); +} diff --git a/web/src/components/profiles/condition/ConditionGroupEditor.tsx b/web/src/components/profiles/condition/ConditionGroupEditor.tsx new file mode 100644 index 000000000..209ea8bcc --- /dev/null +++ b/web/src/components/profiles/condition/ConditionGroupEditor.tsx @@ -0,0 +1,171 @@ +import { Add } from '@mui/icons-material'; +import { + Box, + Button, + Stack, + ToggleButton, + ToggleButtonGroup, + Typography, +} from '@mui/material'; +import { t } from '@lingui/core/macro'; +import { Trans } from '@lingui/react/macro'; +import type { ConditionEntry, ConditionGroup, ConditionOperator } from './types.ts'; +import { createDefaultClause, createDefaultGroup, isConditionGroup } from './types.ts'; +import { ConditionClauseEditor } from './ConditionClauseEditor.tsx'; + +interface Props { + group: ConditionGroup; + onChange: (group: ConditionGroup) => void; + depth?: number; +} + +// Total number of leaf clauses across the entire tree +function countLeaves(group: ConditionGroup): number { + let count = 0; + for (const entry of group.conditions) { + if (isConditionGroup(entry)) { + count += countLeaves(entry); + } else { + count++; + } + } + return count; +} + +const BORDER_COLORS = [ + 'primary.main', + 'secondary.main', + 'warning.main', + 'info.main', +] as const; + +export function ConditionGroupEditor({ group, onChange, depth = 0 }: Props) { + const borderColor = BORDER_COLORS[depth % BORDER_COLORS.length]; + const totalLeaves = countLeaves(group); + + const handleOperatorChange = ( + _: React.MouseEvent, + newOp: ConditionOperator | null, + ) => { + if (newOp !== null) { + onChange({ ...group, operator: newOp }); + } + }; + + const updateEntry = (index: number, entry: ConditionEntry) => { + const next = [...group.conditions]; + next[index] = entry; + onChange({ ...group, conditions: next }); + }; + + const removeEntry = (index: number) => { + const next = group.conditions.filter((_, i) => i !== index); + onChange({ ...group, conditions: next }); + }; + + const addClause = () => { + onChange({ + ...group, + conditions: [...group.conditions, createDefaultClause()], + }); + }; + + const addGroup = () => { + onChange({ + ...group, + conditions: [...group.conditions, createDefaultGroup()], + }); + }; + + return ( + + + {/* Operator toggle */} + + + Match + + + + {t`ALL`} + + + {t`ANY`} + + + + of the following + + + + {/* Condition entries */} + {group.conditions.map((entry, idx) => { + if (isConditionGroup(entry)) { + return ( + + updateEntry(idx, updated)} + depth={depth + 1} + /> + + + ); + } + + return ( + updateEntry(idx, updated)} + onRemove={() => removeEntry(idx)} + canRemove={totalLeaves > 1} + /> + ); + })} + + {/* Add buttons */} + + + {depth < 2 && ( + + )} + + + + ); +} diff --git a/web/src/components/profiles/condition/celGenerator.test.ts b/web/src/components/profiles/condition/celGenerator.test.ts new file mode 100644 index 000000000..3604fbb44 --- /dev/null +++ b/web/src/components/profiles/condition/celGenerator.test.ts @@ -0,0 +1,294 @@ +import { describe, expect, it } from 'vitest'; +import { basicConditionToCel } from './celGenerator.ts'; +import { celToBasicCondition } from './celParser.ts'; +import type { ConditionGroup } from './types.ts'; + +describe('basicConditionToCel', () => { + it('generates "true" for always clause', () => { + const group: ConditionGroup = { + type: 'group', + operator: 'and', + conditions: [{ type: 'always' }], + }; + expect(basicConditionToCel(group)).toBe('true'); + }); + + it('generates program type equality', () => { + const group: ConditionGroup = { + type: 'group', + operator: 'and', + conditions: [{ type: 'program_type', operator: 'eq', value: 'movie' }], + }; + expect(basicConditionToCel(group)).toBe('program.type == "movie"'); + }); + + it('generates program type inequality', () => { + const group: ConditionGroup = { + type: 'group', + operator: 'and', + conditions: [ + { type: 'program_type', operator: 'neq', value: 'episode' }, + ], + }; + expect(basicConditionToCel(group)).toBe('program.type != "episode"'); + }); + + it('generates audio language in', () => { + const group: ConditionGroup = { + type: 'group', + operator: 'and', + conditions: [{ type: 'audio_language', operator: 'in', value: 'eng' }], + }; + expect(basicConditionToCel(group)).toBe('"eng" in audio.languages'); + }); + + it('generates audio language not_in', () => { + const group: ConditionGroup = { + type: 'group', + operator: 'and', + conditions: [ + { type: 'audio_language', operator: 'not_in', value: 'eng' }, + ], + }; + expect(basicConditionToCel(group)).toBe('!("eng" in audio.languages)'); + }); + + it('generates subtitle language in', () => { + const group: ConditionGroup = { + type: 'group', + operator: 'and', + conditions: [ + { type: 'subtitle_language', operator: 'in', value: 'jpn' }, + ], + }; + expect(basicConditionToCel(group)).toBe('"jpn" in subtitle.languages'); + }); + + it('generates audio channels exists', () => { + const group: ConditionGroup = { + type: 'group', + operator: 'and', + conditions: [ + { type: 'audio_channels', operator: 'gte', value: 6 }, + ], + }; + expect(basicConditionToCel(group)).toBe( + 'audio.streams.exists(s, s.channels >= 6)', + ); + }); + + it('generates AND of multiple clauses', () => { + const group: ConditionGroup = { + type: 'group', + operator: 'and', + conditions: [ + { type: 'program_type', operator: 'eq', value: 'movie' }, + { type: 'audio_language', operator: 'in', value: 'eng' }, + ], + }; + expect(basicConditionToCel(group)).toBe( + 'program.type == "movie" && "eng" in audio.languages', + ); + }); + + it('generates OR of multiple clauses', () => { + const group: ConditionGroup = { + type: 'group', + operator: 'or', + conditions: [ + { type: 'program_type', operator: 'eq', value: 'movie' }, + { type: 'program_type', operator: 'eq', value: 'episode' }, + ], + }; + expect(basicConditionToCel(group)).toBe( + 'program.type == "movie" || program.type == "episode"', + ); + }); + + it('wraps nested group with different operator in parens', () => { + const group: ConditionGroup = { + type: 'group', + operator: 'and', + conditions: [ + { type: 'program_type', operator: 'eq', value: 'movie' }, + { + type: 'group', + operator: 'or', + conditions: [ + { type: 'audio_language', operator: 'in', value: 'eng' }, + { type: 'audio_language', operator: 'in', value: 'jpn' }, + ], + }, + ], + }; + expect(basicConditionToCel(group)).toBe( + 'program.type == "movie" && ("eng" in audio.languages || "jpn" in audio.languages)', + ); + }); +}); + +describe('celToBasicCondition', () => { + it('parses "true"', () => { + const result = celToBasicCondition('true'); + expect(result).toEqual({ + type: 'group', + operator: 'and', + conditions: [{ type: 'always' }], + }); + }); + + it('parses program type equality', () => { + const result = celToBasicCondition('program.type == "movie"'); + expect(result).toEqual({ + type: 'group', + operator: 'and', + conditions: [ + { type: 'program_type', operator: 'eq', value: 'movie' }, + ], + }); + }); + + it('parses audio language in', () => { + const result = celToBasicCondition('"eng" in audio.languages'); + expect(result).toEqual({ + type: 'group', + operator: 'and', + conditions: [ + { type: 'audio_language', operator: 'in', value: 'eng' }, + ], + }); + }); + + it('parses negated audio language', () => { + const result = celToBasicCondition('!("eng" in audio.languages)'); + expect(result).toEqual({ + type: 'group', + operator: 'and', + conditions: [ + { type: 'audio_language', operator: 'not_in', value: 'eng' }, + ], + }); + }); + + it('parses AND conditions', () => { + const result = celToBasicCondition( + 'program.type == "movie" && "eng" in audio.languages', + ); + expect(result).toEqual({ + type: 'group', + operator: 'and', + conditions: [ + { type: 'program_type', operator: 'eq', value: 'movie' }, + { type: 'audio_language', operator: 'in', value: 'eng' }, + ], + }); + }); + + it('parses OR conditions', () => { + const result = celToBasicCondition( + 'program.type == "movie" || program.type == "episode"', + ); + expect(result).toEqual({ + type: 'group', + operator: 'or', + conditions: [ + { type: 'program_type', operator: 'eq', value: 'movie' }, + { type: 'program_type', operator: 'eq', value: 'episode' }, + ], + }); + }); + + it('parses nested groups', () => { + const result = celToBasicCondition( + 'program.type == "movie" && ("eng" in audio.languages || "jpn" in audio.languages)', + ); + expect(result).toEqual({ + type: 'group', + operator: 'and', + conditions: [ + { type: 'program_type', operator: 'eq', value: 'movie' }, + { + type: 'group', + operator: 'or', + conditions: [ + { type: 'audio_language', operator: 'in', value: 'eng' }, + { type: 'audio_language', operator: 'in', value: 'jpn' }, + ], + }, + ], + }); + }); + + it('parses audio channels exists', () => { + const result = celToBasicCondition( + 'audio.streams.exists(s, s.channels >= 6)', + ); + expect(result).toEqual({ + type: 'group', + operator: 'and', + conditions: [ + { type: 'audio_channels', operator: 'gte', value: 6 }, + ], + }); + }); + + it('returns null for unrecognized expression', () => { + expect(celToBasicCondition('some.unknown.field == 42')).toBeNull(); + }); + + it('returns null for empty string', () => { + expect(celToBasicCondition('')).toBeNull(); + }); +}); + +describe('round-trip', () => { + const cases: ConditionGroup[] = [ + { type: 'group', operator: 'and', conditions: [{ type: 'always' }] }, + { + type: 'group', + operator: 'and', + conditions: [ + { type: 'program_type', operator: 'eq', value: 'movie' }, + ], + }, + { + type: 'group', + operator: 'and', + conditions: [ + { type: 'program_type', operator: 'eq', value: 'movie' }, + { type: 'audio_language', operator: 'in', value: 'eng' }, + ], + }, + { + type: 'group', + operator: 'or', + conditions: [ + { type: 'audio_language', operator: 'in', value: 'eng' }, + { type: 'audio_language', operator: 'in', value: 'jpn' }, + ], + }, + { + type: 'group', + operator: 'and', + conditions: [ + { type: 'program_type', operator: 'eq', value: 'episode' }, + { + type: 'group', + operator: 'or', + conditions: [ + { type: 'audio_language', operator: 'in', value: 'eng' }, + { type: 'subtitle_language', operator: 'in', value: 'eng' }, + ], + }, + ], + }, + ]; + + cases.forEach((group, i) => { + it(`round-trips case ${i}`, () => { + const cel = basicConditionToCel(group); + const parsed = celToBasicCondition(cel); + expect(parsed).toEqual(group); + }); + }); +}); diff --git a/web/src/components/profiles/condition/celGenerator.ts b/web/src/components/profiles/condition/celGenerator.ts new file mode 100644 index 000000000..46acba0cd --- /dev/null +++ b/web/src/components/profiles/condition/celGenerator.ts @@ -0,0 +1,80 @@ +import type { + ConditionClause, + ConditionEntry, + ConditionGroup, +} from './types.ts'; +import { isConditionGroup } from './types.ts'; + +function clauseToCel(clause: ConditionClause): string { + switch (clause.type) { + case 'always': + return 'true'; + + case 'program_type': { + const op = clause.operator === 'eq' ? '==' : '!='; + return `program.type ${op} "${clause.value}"`; + } + + case 'audio_language': { + const lang = JSON.stringify(clause.value); + if (clause.operator === 'in') { + return `${lang} in audio.languages`; + } + return `!(${lang} in audio.languages)`; + } + + case 'subtitle_language': { + const lang = JSON.stringify(clause.value); + if (clause.operator === 'in') { + return `${lang} in subtitle.languages`; + } + return `!(${lang} in subtitle.languages)`; + } + + case 'audio_channels': { + const opMap = { + eq: '==', + gte: '>=', + lte: '<=', + gt: '>', + lt: '<', + } as const; + return `audio.streams.exists(s, s.channels ${opMap[clause.operator]} ${clause.value})`; + } + } +} + +function entryToCel(entry: ConditionEntry, parentOperator?: string): string { + if (!isConditionGroup(entry)) { + return clauseToCel(entry); + } + return groupToCel(entry, parentOperator); +} + +function groupToCel( + group: ConditionGroup, + parentOperator?: string, +): string { + if (group.conditions.length === 0) { + return 'true'; + } + + if (group.conditions.length === 1) { + return entryToCel(group.conditions[0], group.operator); + } + + const joiner = group.operator === 'and' ? ' && ' : ' || '; + const parts = group.conditions.map((c) => entryToCel(c, group.operator)); + const joined = parts.join(joiner); + + // Wrap in parens if this is a nested group with a different parent operator + if (parentOperator !== undefined && parentOperator !== group.operator) { + return `(${joined})`; + } + + return joined; +} + +export function basicConditionToCel(condition: ConditionGroup): string { + return groupToCel(condition); +} diff --git a/web/src/components/profiles/condition/celParser.ts b/web/src/components/profiles/condition/celParser.ts new file mode 100644 index 000000000..08ae3ead9 --- /dev/null +++ b/web/src/components/profiles/condition/celParser.ts @@ -0,0 +1,318 @@ +// Best-effort parser: converts known CEL patterns back to a ConditionGroup. +// Returns null when the expression uses constructs the basic builder can't represent. + +import type { + ComparisonOperator, + ConditionClause, + ConditionEntry, + ConditionGroup, + ListOperator, + NumericOperator, +} from './types.ts'; + +// Tokenizer for a small subset of CEL we care about. +// Rather than a full parser, we match known leaf patterns first, +// then handle && / || / parentheses structurally. + +type Token = + | { kind: 'leaf'; clause: ConditionClause } + | { kind: 'and' } + | { kind: 'or' } + | { kind: 'lparen' } + | { kind: 'rparen' }; + +const LEAF_PATTERNS: Array<{ + regex: RegExp; + extract: (m: RegExpMatchArray) => ConditionClause | null; +}> = [ + // "true" + { + regex: /^true$/, + extract: () => ({ type: 'always' }), + }, + // program.type == "movie" / program.type != "movie" + { + regex: /^program\.type\s*(==|!=)\s*"([^"]+)"$/, + extract: (m) => ({ + type: 'program_type', + operator: (m[1] === '==' ? 'eq' : 'neq') as ComparisonOperator, + value: m[2], + }), + }, + // "eng" in audio.languages + { + regex: /^"([^"]+)"\s+in\s+audio\.languages$/, + extract: (m) => ({ + type: 'audio_language', + operator: 'in' as ListOperator, + value: m[1], + }), + }, + // !("eng" in audio.languages) + { + regex: /^!\("([^"]+)"\s+in\s+audio\.languages\)$/, + extract: (m) => ({ + type: 'audio_language', + operator: 'not_in' as ListOperator, + value: m[1], + }), + }, + // "eng" in subtitle.languages + { + regex: /^"([^"]+)"\s+in\s+subtitle\.languages$/, + extract: (m) => ({ + type: 'subtitle_language', + operator: 'in' as ListOperator, + value: m[1], + }), + }, + // !("eng" in subtitle.languages) + { + regex: /^!\("([^"]+)"\s+in\s+subtitle\.languages\)$/, + extract: (m) => ({ + type: 'subtitle_language', + operator: 'not_in' as ListOperator, + value: m[1], + }), + }, + // audio.streams.exists(s, s.channels >= 6) + { + regex: + /^audio\.streams\.exists\(s,\s*s\.channels\s*(==|>=|<=|>|<)\s*(\d+)\)$/, + extract: (m) => { + const opMap: Record = { + '==': 'eq', + '>=': 'gte', + '<=': 'lte', + '>': 'gt', + '<': 'lt', + }; + const op = opMap[m[1]]; + if (op === undefined) return null; + return { + type: 'audio_channels', + operator: op, + value: parseInt(m[2], 10), + }; + }, + }, +]; + +function tryParseLeaf(expr: string): ConditionClause | null { + const trimmed = expr.trim(); + for (const pattern of LEAF_PATTERNS) { + const m = trimmed.match(pattern.regex); + if (m) { + return pattern.extract(m); + } + } + return null; +} + +// Tokenize a CEL string into leaves, operators, and parens. +// This is a simplified approach that works for expressions we generate. +function tokenize(input: string): Token[] | null { + const tokens: Token[] = []; + let pos = 0; + const s = input.trim(); + + while (pos < s.length) { + // Skip whitespace + while (pos < s.length && /\s/.test(s[pos])) pos++; + if (pos >= s.length) break; + + // Parentheses + if (s[pos] === '(') { + tokens.push({ kind: 'lparen' }); + pos++; + continue; + } + if (s[pos] === ')') { + tokens.push({ kind: 'rparen' }); + pos++; + continue; + } + + // && or || + if (s.startsWith('&&', pos)) { + tokens.push({ kind: 'and' }); + pos += 2; + continue; + } + if (s.startsWith('||', pos)) { + tokens.push({ kind: 'or' }); + pos += 2; + continue; + } + + // Try to match a leaf expression starting at pos. + // Leaves can contain parens (like the negated and exists patterns), + // so we need to be careful. + const rest = s.slice(pos); + const leafEnd = findLeafEnd(rest); + if (leafEnd <= 0) return null; // can't parse + + const leafStr = rest.slice(0, leafEnd).trim(); + const clause = tryParseLeaf(leafStr); + if (!clause) return null; // unknown expression + tokens.push({ kind: 'leaf', clause }); + pos += leafEnd; + } + + return tokens.length > 0 ? tokens : null; +} + +// Find where a leaf expression ends by tracking balanced parens and +// stopping at an unbalanced ) or a top-level && / ||. +function findLeafEnd(s: string): number { + let depth = 0; + let i = 0; + + // Handle leading !( for negation patterns + if (s[i] === '!') i++; + + while (i < s.length) { + if (s[i] === '(') { + depth++; + i++; + } else if (s[i] === ')') { + if (depth === 0) return i; // unbalanced — end of leaf + depth--; + i++; + } else if ( + depth === 0 && + (s.startsWith('&&', i) || s.startsWith('||', i)) + ) { + return i; + } else if (s[i] === '"') { + // Skip string literal + i++; + while (i < s.length && s[i] !== '"') { + if (s[i] === '\\') i++; // skip escape + i++; + } + if (i < s.length) i++; // closing quote + } else { + i++; + } + } + + return depth === 0 ? i : -1; +} + +// Recursive descent parser for tokens. +// Grammar: +// expr = group +// group = primary (('&&' | '||') primary)* +// primary = leaf | '(' expr ')' +function parseTokens( + tokens: Token[], + start: number, +): { entry: ConditionEntry; next: number } | null { + return parseGroup(tokens, start); +} + +function parseGroup( + tokens: Token[], + start: number, +): { entry: ConditionEntry; next: number } | null { + const first = parsePrimary(tokens, start); + if (!first) return null; + + const entries: ConditionEntry[] = [first.entry]; + let operator: 'and' | 'or' | null = null; + let pos = first.next; + + while (pos < tokens.length) { + const tok = tokens[pos]; + if (tok.kind !== 'and' && tok.kind !== 'or') break; + + const thisOp = tok.kind === 'and' ? 'and' : 'or'; + // All operators in a flat group must be the same + if (operator !== null && operator !== thisOp) { + // Mixed operators without parens — can't represent in basic mode + return null; + } + operator = thisOp as 'and' | 'or'; + pos++; + + const next = parsePrimary(tokens, pos); + if (!next) return null; + entries.push(next.entry); + pos = next.next; + } + + if (entries.length === 1) { + return { entry: entries[0], next: pos }; + } + + const group: ConditionGroup = { + type: 'group', + operator: operator ?? 'and', + conditions: entries, + }; + return { entry: group, next: pos }; +} + +function parsePrimary( + tokens: Token[], + start: number, +): { entry: ConditionEntry; next: number } | null { + if (start >= tokens.length) return null; + + const tok = tokens[start]; + if (tok.kind === 'leaf') { + return { entry: tok.clause, next: start + 1 }; + } + + if (tok.kind === 'lparen') { + const inner = parseGroup(tokens, start + 1); + if (!inner) return null; + if ( + inner.next >= tokens.length || + tokens[inner.next].kind !== 'rparen' + ) { + return null; + } + return { entry: inner.entry, next: inner.next + 1 }; + } + + return null; +} + +/** + * Attempt to parse a CEL expression string into a basic ConditionGroup. + * Returns null if the expression uses constructs the basic builder can't represent. + */ +export function celToBasicCondition(cel: string): ConditionGroup | null { + const trimmed = cel.trim(); + if (!trimmed) return null; + + // Fast path: single leaf + const singleLeaf = tryParseLeaf(trimmed); + if (singleLeaf) { + return { + type: 'group', + operator: 'and', + conditions: [singleLeaf], + }; + } + + const tokens = tokenize(trimmed); + if (!tokens) return null; + + const result = parseTokens(tokens, 0); + if (!result || result.next !== tokens.length) return null; + + // Ensure top level is a group + const entry = result.entry; + if (entry.type === 'group') { + return entry; + } + + return { + type: 'group', + operator: 'and', + conditions: [entry], + }; +} diff --git a/web/src/components/profiles/condition/index.ts b/web/src/components/profiles/condition/index.ts new file mode 100644 index 000000000..de1cb3028 --- /dev/null +++ b/web/src/components/profiles/condition/index.ts @@ -0,0 +1,8 @@ +export { ConditionEditor } from './ConditionEditor.tsx'; +export type { + ConditionClause, + ConditionEntry, + ConditionGroup, + ConditionMode, + ConditionOperator, +} from './types.ts'; diff --git a/web/src/components/profiles/condition/types.ts b/web/src/components/profiles/condition/types.ts new file mode 100644 index 000000000..81d3c6608 --- /dev/null +++ b/web/src/components/profiles/condition/types.ts @@ -0,0 +1,92 @@ +// Structured condition types for the basic condition builder. +// These are a UI-only concern — the API always stores a CEL string. + +import { msg } from '@lingui/core/macro'; +import type { MessageDescriptor } from '@lingui/core'; + +export type ConditionOperator = 'and' | 'or'; + +export type ClauseType = + | 'always' + | 'program_type' + | 'audio_language' + | 'subtitle_language' + | 'audio_channels'; + +export type ComparisonOperator = 'eq' | 'neq'; +export type ListOperator = 'in' | 'not_in'; +export type NumericOperator = 'eq' | 'gte' | 'lte' | 'gt' | 'lt'; + +export type ConditionClause = + | { type: 'always' } + | { type: 'program_type'; operator: ComparisonOperator; value: string } + | { type: 'audio_language'; operator: ListOperator; value: string } + | { type: 'subtitle_language'; operator: ListOperator; value: string } + | { + type: 'audio_channels'; + operator: NumericOperator; + value: number; + }; + +export interface ConditionGroup { + type: 'group'; + operator: ConditionOperator; + conditions: ConditionEntry[]; +} + +export type ConditionEntry = ConditionClause | ConditionGroup; + +export type ConditionMode = 'basic' | 'cel'; + +export const PROGRAM_TYPES: ReadonlyArray<{ + value: string; + label: MessageDescriptor; +}> = [ + { value: 'movie', label: msg`Movie` }, + { value: 'episode', label: msg`Episode` }, + { value: 'track', label: msg`Track` }, + { value: 'music_video', label: msg`Music Video` }, + { value: 'other_video', label: msg`Other Video` }, +]; + +export const CLAUSE_TYPE_LABELS: Record = { + always: msg`Always match`, + program_type: msg`Program type`, + audio_language: msg`Audio language`, + subtitle_language: msg`Subtitle language`, + audio_channels: msg`Audio channel count`, +}; + +export const COMPARISON_OPERATOR_LABELS: Record = { + eq: msg`is`, + neq: msg`is not`, +}; + +export const LIST_OPERATOR_LABELS: Record = { + in: msg`includes`, + not_in: msg`does not include`, +}; + +export const NUMERIC_OPERATOR_LABELS: Record = { + eq: '=', + gte: '≥', + lte: '≤', + gt: '>', + lt: '<', +}; + +export function isConditionGroup(entry: ConditionEntry): entry is ConditionGroup { + return entry.type === 'group'; +} + +export function createDefaultClause(): ConditionClause { + return { type: 'program_type', operator: 'eq', value: 'movie' }; +} + +export function createDefaultGroup(): ConditionGroup { + return { + type: 'group', + operator: 'and', + conditions: [createDefaultClause()], + }; +} diff --git a/web/src/components/profiles/streamSelectionFormTypes.ts b/web/src/components/profiles/streamSelectionFormTypes.ts new file mode 100644 index 000000000..c2f589e68 --- /dev/null +++ b/web/src/components/profiles/streamSelectionFormTypes.ts @@ -0,0 +1,59 @@ +export interface AudioActionByLanguage { + type: 'by_language'; + languages: string[]; + preferChannels?: 'most' | 'least' | ''; +} + +export interface AudioActionByTitle { + type: 'by_title'; + titleContains: string; +} + +export interface AudioActionDefault { + type: 'default'; +} + +export type AudioAction = + | AudioActionByLanguage + | AudioActionByTitle + | AudioActionDefault; + +export interface SubtitleActionDisable { + type: 'disable'; +} + +export interface SubtitleActionByLanguage { + type: 'by_language'; + languages: string[]; + filterType?: 'none' | 'forced' | 'default' | 'any'; + allowImageBased?: boolean; + allowExternal?: boolean; +} + +export interface SubtitleActionDefault { + type: 'default'; +} + +export type SubtitleAction = + | SubtitleActionDisable + | SubtitleActionByLanguage + | SubtitleActionDefault; + +export interface StreamSelectionRuleFormValues { + label?: string; + condition: string; + audioAction: AudioAction; + subtitleAction: SubtitleAction; +} + +export interface StreamSelectionProfileFormValues { + name: string; + rules: StreamSelectionRuleFormValues[]; +} + +export const defaultRule: StreamSelectionRuleFormValues = { + label: '', + condition: 'true', + audioAction: { type: 'default' }, + subtitleAction: { type: 'default' }, +}; diff --git a/web/src/components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx b/web/src/components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx index e349ee554..04afef5c2 100644 --- a/web/src/components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx +++ b/web/src/components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx @@ -1,6 +1,5 @@ import { useAppForm } from '@/hooks/form.ts'; import { Trans, useLingui } from '@lingui/react/macro'; -import { Check, VisibilityOff } from '@mui/icons-material'; import { Box, Button, @@ -13,15 +12,13 @@ import { Link as MuiLink, Stack, TextField, - ToggleButton, Typography, } from '@mui/material'; import type { TranscodeConfig } from '@tunarr/types'; import type { TranscodeConfigSchema } from '@tunarr/types/schemas'; import type z from 'zod'; import useStore from '../../../store/index.ts'; -import { setShowAdvancedSettings } from '../../../store/settings/actions.ts'; -import Breadcrumbs from '../../Breadcrumbs.tsx'; +import UnsavedNavigationAlert from '../UnsavedNavigationAlert.tsx'; import { TranscodeConfigAdvancedOptions } from './TranscodeConfigAdvancedOptions.tsx'; import { TranscodeConfigAudioSettingsForm } from './TranscodeConfigAudioSettingsForm.tsx'; import { TranscodeConfigErrorOptions } from './TranscodeConfigErrorOptions.tsx'; @@ -62,27 +59,8 @@ export const TranscodeConfigSettingsForm = ({ transcodeConfigForm.handleSubmit().catch(console.error); }} > - }> - - - Edit Transcode Config: "{initialConfig.name}" - - setShowAdvancedSettings(!showAdvancedSettings)} - sx={{ ml: 'auto' }} - > - {showAdvancedSettings ? ( - - ) : ( - - )}{' '} - {showAdvancedSettings ? Hide Advanced : Show Advanced} - - General @@ -95,31 +73,6 @@ export const TranscodeConfigSettingsForm = ({ )} /> - {/* ( - - )} - /> */} )} /> - {/* - 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{' '} - - here - - . Note: this option is overridden to 1 - when using hardware accelearation for stability reasons. - - ), - }} - /> */} @@ -191,17 +120,14 @@ export const TranscodeConfigSettingsForm = ({ /> )} /> - - // } label={t`Disable Watermarks`} /> - If set, all watermark overlays will be disabled for channels - assigned this transcode config. + + If set, all watermark overlays will be disabled for + channels assigned this transcode config. + @@ -223,11 +149,13 @@ export const TranscodeConfigSettingsForm = ({ Advanced Video Options - 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. + + 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. + - {isSubmitting ? Submitting... : Submit} + {isSubmitting ? ( + Saving... + ) : ( + Save + )} + )} /> diff --git a/web/src/components/settings/ffmpeg/TranscodeConfigsTable.tsx b/web/src/components/settings/ffmpeg/TranscodeConfigsTable.tsx index d2354a137..2ff3c7488 100644 --- a/web/src/components/settings/ffmpeg/TranscodeConfigsTable.tsx +++ b/web/src/components/settings/ffmpeg/TranscodeConfigsTable.tsx @@ -4,7 +4,7 @@ import { AddCircle, ContentCopy, Delete, Edit } from '@mui/icons-material'; import CheckCircleOutlineIcon from '@mui/icons-material/CheckCircleOutline'; import { Box, Button, IconButton, Stack, Tooltip } from '@mui/material'; import { useMutation, useQueryClient } from '@tanstack/react-query'; -import { Link } from '@tanstack/react-router'; +import { Link, useNavigate } from '@tanstack/react-router'; import type { TranscodeConfig } from '@tunarr/types'; import type { SupportedHardwareAccels } from '@tunarr/types/schemas'; import { isNull } from 'lodash-es'; @@ -28,6 +28,7 @@ export const TranscodeConfigsTable = () => { const queryClient = useQueryClient(); const transcodeConfigs = useTranscodeConfigs(); const tableSettings = useStoreBackedTableSettings('TranscodeConfigs'); + const navigate = useNavigate({ from: '/' }); const [confirmDeleteTranscodeConfig, setConfirmDeleteTranscodeConfig] = useState(null); @@ -111,6 +112,15 @@ export const TranscodeConfigsTable = () => { accessorFn(originalRow) { return `${originalRow.resolution.widthPx}x${originalRow.resolution.heightPx}`; }, + sortingFn(rowA, rowB) { + const totalA = + rowA.original.resolution.widthPx * + rowA.original.resolution.heightPx; + const totalB = + rowB.original.resolution.widthPx * + rowB.original.resolution.heightPx; + return totalA > totalB ? 1 : totalA < totalB ? -1 : 0; + }, }, { header: t`Hardware Accel.`, @@ -155,6 +165,18 @@ export const TranscodeConfigsTable = () => { visibleInShowHideMenu: false, }, }, + muiTableBodyRowProps: ({ row }) => ({ + sx: { + cursor: 'pointer', + }, + onClick: (ev) => { + ev.stopPropagation(); + navigate({ + to: '/profiles/transcode/$configId', + params: { configId: row.original.id }, + }).catch(console.error); + }, + }), renderTopToolbarCustomActions() { return ( diff --git a/web/src/hooks/useNavItems.tsx b/web/src/hooks/useNavItems.tsx index 59c3c1ac8..03e36757c 100644 --- a/web/src/hooks/useNavItems.tsx +++ b/web/src/hooks/useNavItems.tsx @@ -3,6 +3,7 @@ import { t } from '@lingui/core/macro'; import { Computer, Delete, + Headphones, Home, Preview, Psychology, @@ -10,8 +11,10 @@ import { SettingsRemote, Storage as StorageIcon, Theaters, + Tune, Tv, VideoLibrary, + VideoSettings, } from '@mui/icons-material'; import type { BadgeProps } from '@mui/material'; import { useRouterState } from '@tanstack/react-router'; @@ -64,7 +67,11 @@ export const useNavItems = () => { path: '/channels', icon: , }, - // { name: 'Watch', path: '/watch', hidden: true, icon: }, + { + name: t`Sources`, + path: '/media_sources', + icon: , + }, { name: t`Library`, path: '/library', @@ -93,9 +100,21 @@ export const useNavItems = () => { ], }, { - name: t`Sources`, - path: '/media_sources', - icon: , + name: t`Profiles`, + path: '/profiles/transcode', + icon: , + children: [ + { + name: t`Transcode Configs`, + path: '/profiles/transcode', + icon: , + }, + { + name: t`Stream Selection`, + path: '/profiles/stream-selection', + icon: , + }, + ], }, { name: t`System`, diff --git a/web/src/hooks/useRouteName.ts b/web/src/hooks/useRouteName.ts index c66dd0add..948009490 100644 --- a/web/src/hooks/useRouteName.ts +++ b/web/src/hooks/useRouteName.ts @@ -142,6 +142,14 @@ const useNamedRoutes = () => { matcher: entityPageMatcher('settings/ffmpeg', ''), name: t`Edit Transcode Config`, }, + { + matcher: /^\/profiles\/transcode$/g, + name: t`Transcode Configs`, + }, + { + matcher: entityPageMatcher('profiles/transcode', ''), + name: t`Edit Transcode Config`, + }, { matcher: entityPageMatcher('library', ''), name: t`Search`, diff --git a/web/src/locales/en/messages.po b/web/src/locales/en/messages.po index d8665d0fc..4dd4ca9b5 100644 --- a/web/src/locales/en/messages.po +++ b/web/src/locales/en/messages.po @@ -103,6 +103,16 @@ msgstr "{0, plural, one {program} other {programs}}" msgid "{0, plural, one {Selected Item} other {Selected Items}}" msgstr "{0, plural, one {Selected Item} other {Selected Items}}" +#. placeholder {0}: original.usedByChannels +#: src/components/profiles/StreamSelectionProfilesTable.tsx:93 +msgid "{0} channel(s)" +msgstr "{0} channel(s)" + +#. placeholder {0}: original.usedByFillers +#: src/components/profiles/StreamSelectionProfilesTable.tsx:101 +msgid "{0} filler(s)" +msgstr "{0} filler(s)" + #. placeholder {0}: prettifySnakeCaseString(programType) #: src/components/programs/ProgramDetailsDialog.tsx:180 msgid "{0} Info" @@ -122,6 +132,11 @@ msgstr "{0} of {1} {2} exceed the length of this slot ({3}). Average program len msgid "{0} Poster" msgstr "{0} Poster" +#. placeholder {0}: original.usedByPrograms +#: src/components/profiles/StreamSelectionProfilesTable.tsx:109 +msgid "{0} program(s)" +msgstr "{0} program(s)" + #: src/components/programming_controls/AddRerunBlockModal.tsx:64 msgid "{block} Hours" msgstr "{block} Hours" @@ -406,6 +421,10 @@ msgstr "Add programming to custom show" msgid "Add Redirect" msgstr "Add Redirect" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:278 +msgid "Add Rule" +msgstr "Add Rule" + #: src/components/channel_config/SelectedProgrammingActions.tsx:209 msgid "Add Selected Media" msgstr "Add Selected Media" @@ -488,6 +507,10 @@ msgstr "Albums" msgid "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." msgstr "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." +#: src/components/profiles/StreamSelectionProfilesTable.tsx:158 +msgid "All channels, fillers, and programs using this profile will have their stream selection reset to defaults." +msgstr "All channels, fillers, and programs using this profile will have their stream selection reset to defaults." + #: src/components/channel_config/jellyfin/JellyfinLibrarySelector.tsx:104 #~ msgid "All Genres" #~ msgstr "All Genres" @@ -508,10 +531,18 @@ msgstr "All Set!" msgid "Allow External" msgstr "Allow External" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:509 +msgid "Allow external subtitles" +msgstr "Allow external subtitles" + #: src/components/channel_config/ChannelSubtitlePreferencesTable.tsx:64 msgid "Allow Image Based" msgstr "Allow Image Based" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:494 +msgid "Allow image-based subtitles" +msgstr "Allow image-based subtitles" + #: src/pages/channels/TimeSlotEditorPage.tsx:383 msgid "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." msgstr "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." @@ -546,6 +577,10 @@ msgstr "Amount" msgid "An error occurred: {0}" msgstr "An error occurred: {0}" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:467 +msgid "Any" +msgstr "Any" + #: src/components/slot_scheduler/MidRollConfigPanel.tsx:502 msgid "Apply to Program Types (empty = all)" msgstr "Apply to Program Types (empty = all)" @@ -572,6 +607,11 @@ msgstr "Asc" msgid "Ascending" msgstr "Ascending" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:308 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:418 +msgid "At least one language is required" +msgstr "At least one language is required" + #: src/pages/system/StatusPage.tsx:184 msgid "Attempt Auto-Fix" msgstr "Attempt Auto-Fix" @@ -630,6 +670,15 @@ msgstr "Audio Options" msgid "Audio Sample Rate" msgstr "Audio Sample Rate" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:223 +msgid "Audio Selection" +msgstr "Audio Selection" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:232 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:234 +msgid "Audio Strategy" +msgstr "Audio Strategy" + #: src/pages/system/TroubleshootPage.tsx:622 msgid "Audio Streams" msgstr "Audio Streams" @@ -638,6 +687,10 @@ msgstr "Audio Streams" msgid "Audio Volume" msgstr "Audio Volume" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:127 +msgid "Audio: {audioSummary}" +msgstr "Audio: {audioSummary}" + #: src/components/settings/general/WebSettings.tsx:99 msgid "Auto" msgstr "Auto" @@ -756,6 +809,18 @@ msgstr "By default, saves backups in the server's run directory, or, if running msgid "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." msgstr "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." +#: src/components/profiles/StreamSelectionRuleEditor.tsx:92 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:99 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:239 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:278 +msgid "By Language" +msgstr "By Language" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:93 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:242 +msgid "By Title" +msgstr "By Title" + #: src/components/settings/general/GeneralSettingsForm.tsx:434 msgid "Caching" msgstr "Caching" @@ -826,6 +891,10 @@ msgstr "Cast & Crew" msgid "Category Log Levels" msgstr "Category Log Levels" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:211 +msgid "CEL expression. Use \"true\" to always match." +msgstr "CEL expression. Use \"true\" to always match." + #: src/components/settings/general/GeneralSettingsForm.tsx:385 msgid "Change the verbosity of specific categories of logs. Useful if debugging a specific feature." msgstr "Change the verbosity of specific categories of logs. Useful if debugging a specific feature." @@ -883,7 +952,7 @@ msgid "Channel Transcode Config" msgstr "Channel Transcode Config" #: src/App.tsx:95 -#: src/hooks/useNavItems.tsx:63 +#: src/hooks/useNavItems.tsx:64 #: src/hooks/useRouteName.ts:38 #: src/pages/channels/ChannelsPage.tsx:566 #: src/pages/system/TroubleshootPage.tsx:636 @@ -959,10 +1028,16 @@ msgstr "Completely randomizes the order of programs." msgid "Component" msgstr "Component" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:208 #: src/pages/system/TroubleshootPage.tsx:751 msgid "Condition" msgstr "Condition" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:199 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:201 +msgid "Condition is required" +msgstr "Condition is required" + #: src/components/slot_scheduler/EditTimeSlotDialogContent.tsx:278 msgid "Config" msgstr "Config" @@ -1092,6 +1167,10 @@ msgstr "Create" msgid "Create a Channel" msgstr "Create a Channel" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:343 +msgid "Create Profile" +msgstr "Create Profile" + #: src/components/programming_controls/AddRerunBlockModal.tsx:31 msgid "Create Rerun Block" msgstr "Create Rerun Block" @@ -1128,7 +1207,7 @@ msgid "Custom Show: {0}" msgstr "Custom Show: {0}" #: src/components/channel_config/ProgrammingSelector.tsx:267 -#: src/hooks/useNavItems.tsx:84 +#: src/hooks/useNavItems.tsx:85 #: src/hooks/useRouteName.ts:121 #: src/pages/library/CustomShowsPage.tsx:207 msgid "Custom Shows" @@ -1176,24 +1255,36 @@ msgstr "Day" msgid "Days to Precalculate" msgstr "Days to Precalculate" -#: src/hooks/useNavItems.tsx:117 +#: src/hooks/useNavItems.tsx:129 #: src/pages/system/SystemLayout.tsx:32 msgid "Debug" msgstr "Debug" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:90 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:98 #: src/pages/system/TroubleshootPage.tsx:642 #: src/pages/system/TroubleshootPage.tsx:686 msgid "Default" msgstr "Default" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:236 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:275 +msgid "Default (first stream)" +msgstr "Default (first stream)" + #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:99 msgid "Default Config" msgstr "Default Config" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:473 +msgid "Default only" +msgstr "Default only" + #: src/components/channel_config/ChannelProgrammingDeleteOptions.tsx:32 #: src/components/channels/ChannelDeleteDialog.tsx:86 #: src/components/custom-shows/CustomShowSortToolsMenu.tsx:186 #: src/components/DeleteConfirmationDialog.tsx:59 +#: src/components/profiles/StreamSelectionProfilesTable.tsx:54 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:75 #: src/components/smart_collections/SmartCollectionsTable.tsx:124 #: src/pages/channels/ChannelsPage.tsx:206 @@ -1238,6 +1329,11 @@ msgstr "Delete Media Source \"{0}\"?" #~ msgid "Delete Media Source?" #~ msgstr "Delete Media Source?" +#. placeholder {0}: confirmDelete?.name ?? '' +#: src/components/profiles/StreamSelectionProfilesTable.tsx:157 +msgid "Delete Profile \"{0}\"?" +msgstr "Delete Profile \"{0}\"?" + #: src/components/slot_scheduler/RandomSlotTable.tsx:427 #: src/components/slot_scheduler/TimeSlotTable.tsx:395 msgid "Delete Slot" @@ -1283,7 +1379,7 @@ msgstr "Descending" msgid "Description" msgstr "Description" -#: src/components/channels/ChannelNowPlayingCard.tsx:227 +#: src/components/channels/ChannelNowPlayingCard.tsx:259 msgid "Details" msgstr "Details" @@ -1311,6 +1407,8 @@ msgstr "Disable Image Scaling" msgid "Disable Watermarks" msgstr "Disable Watermarks" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:96 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:272 #: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:219 #: src/pages/settings/FfmpegSettingsPage.tsx:224 #: src/pages/system/StatusPage.tsx:334 @@ -1411,6 +1509,7 @@ msgstr "Dynamic" msgid "Eager" msgstr "Eager" +#: src/components/profiles/StreamSelectionProfilesTable.tsx:46 #: src/components/settings/ConnectMediaSources.tsx:47 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:65 #: src/components/smart_collections/SmartCollectionsTable.tsx:117 @@ -1458,6 +1557,10 @@ msgstr "Edit Media Source" msgid "Edit Slot" msgstr "Edit Slot" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:238 +msgid "Edit Stream Selection Profile" +msgstr "Edit Stream Selection Profile" + #: src/hooks/useRouteName.ts:143 msgid "Edit Transcode Config" msgstr "Edit Transcode Config" @@ -1735,6 +1838,10 @@ msgstr "Failed to save feature flags." msgid "Failed to update Media Source settings. Please check server and browser logs for details." msgstr "Failed to update Media Source settings. Please check server and browser logs for details." +#: src/pages/profiles/StreamSelectionProfilePage.tsx:204 +msgid "Failed to validate expression" +msgstr "Failed to validate expression" + #: src/components/slot_scheduler/SlotFillerDialogPanel.tsx:203 msgid "Fallback" msgstr "Fallback" @@ -1884,7 +1991,7 @@ msgstr "Filler List Cooldown (seconds)" msgid "Filler List: {0}" msgstr "Filler List: {0}" -#: src/hooks/useNavItems.tsx:74 +#: src/hooks/useNavItems.tsx:75 #: src/hooks/useRouteName.ts:99 #: src/pages/library/FillerListsPage.tsx:219 msgid "Filler Lists" @@ -1899,6 +2006,8 @@ msgid "Filler Options" msgstr "Filler Options" #: src/components/channel_config/ChannelSubtitlePreferencesTable.tsx:85 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:463 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:465 #: src/components/search/PointAndClickSearchBuilder.tsx:27 #: src/components/search/SearchFilterBuilder.tsx:73 #: src/components/smart_collections/CreateSmartCollectionDialog.tsx:178 @@ -1958,6 +2067,10 @@ msgstr "Force Scan" msgid "Forced" msgstr "Forced" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:470 +msgid "Forced only" +msgstr "Forced only" + #: src/pages/system/TroubleshootPage.tsx:574 msgid "Frame Rate" msgstr "Frame Rate" @@ -2001,7 +2114,7 @@ msgstr "Group episode programs by their show." msgid "Grouping works as follows:" msgstr "Grouping works as follows:" -#: src/hooks/useNavItems.tsx:61 +#: src/hooks/useNavItems.tsx:62 #: src/pages/guide/GuidePage.tsx:120 msgid "Guide" msgstr "Guide" @@ -2157,6 +2270,10 @@ msgstr "Install FFMPEG" msgid "Interval (minutes)" msgstr "Interval (minutes)" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:202 +msgid "Invalid expression" +msgstr "Invalid expression" + #: src/components/slot_scheduler/SlotOrderFormControl.tsx:46 msgid "Inverse linear decay, heavier weighting." msgstr "Inverse linear decay, heavier weighting." @@ -2182,6 +2299,7 @@ msgstr "Keywords" msgid "Keywords perform full text search across all (or configured) fields" msgstr "Keywords perform full text search across all (or configured) fields" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:187 #: src/pages/system/TroubleshootPage.tsx:748 msgid "Label" msgstr "Label" @@ -2197,6 +2315,11 @@ msgstr "Label" msgid "Language" msgstr "Language" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:338 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:448 +msgid "Languages" +msgstr "Languages" + #: src/pages/settings/TaskSettingsPage.tsx:236 msgid "Last run" msgstr "Last run" @@ -2223,6 +2346,10 @@ msgstr "Last synced {0}" msgid "Lazy" msgstr "Lazy" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:370 +msgid "Least channels (e.g. stereo)" +msgstr "Least channels (e.g. stereo)" + #: src/components/channel_config/ChannelTranscodingConfig.tsx:353 msgid "Leave blank to use the channel's icon." msgstr "Leave blank to use the channel's icon." @@ -2241,7 +2368,7 @@ msgstr "Libraries" #: src/components/channel_config/ImportedLibrarySeletor.tsx:102 #: src/components/channel_config/ImportedLibrarySeletor.tsx:104 -#: src/hooks/useNavItems.tsx:69 +#: src/hooks/useNavItems.tsx:70 #: src/hooks/useRouteName.ts:95 #: src/pages/library/LibraryIndexPage.tsx:12 msgid "Library" @@ -2252,7 +2379,7 @@ msgid "Library Clip (not yet implemented)" msgstr "Library Clip (not yet implemented)" #. placeholder {0}: library.name -#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:36 +#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:39 msgid "Library: {0}" msgstr "Library: {0}" @@ -2347,7 +2474,7 @@ msgstr "Logarithmic decay, lighter weighting." msgid "Logging" msgstr "Logging" -#: src/hooks/useNavItems.tsx:122 +#: src/hooks/useNavItems.tsx:134 #: src/pages/system/SystemLayout.tsx:33 msgid "Logs" msgstr "Logs" @@ -2412,6 +2539,10 @@ msgstr "Match all of" msgid "Match any of" msgstr "Match any of" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:395 +msgid "Match audio streams whose title contains this text (case-insensitive)" +msgstr "Match audio streams whose title contains this text (case-insensitive)" + #: src/components/settings/general/BackupForm.tsx:87 #: src/components/settings/general/BackupForm.tsx:90 msgid "Max Backups" @@ -2462,8 +2593,8 @@ msgstr "Media Source" #. placeholder {0}: library.mediaSource.name #. placeholder {0}: mediaSource.name -#: src/routes/media_sources_/$mediaSourceId/index.tsx:35 -#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:33 +#: src/routes/media_sources_/$mediaSourceId/index.tsx:36 +#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:34 msgid "Media Source: \"{0}\"" msgstr "Media Source: \"{0}\"" @@ -2515,6 +2646,18 @@ msgstr "Modify Programming" msgid "Month" msgstr "Month" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:367 +msgid "Most channels (e.g. 7.1 surround)" +msgstr "Most channels (e.g. 7.1 surround)" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:153 +msgid "Move down" +msgstr "Move down" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:142 +msgid "Move up" +msgstr "Move up" + #: src/components/channel_config/SelectedProgrammingList.tsx:76 #: src/hooks/slot_scheduler/useSlotName.ts:13 msgid "Movie" @@ -2566,6 +2709,7 @@ msgstr "Must use a valid URL, or empty." #: src/components/custom-shows/EditCustomShowForm.tsx:270 #: src/components/filler/EditFillerListForm.tsx:137 #: src/components/MediaSourceLibraryTable.tsx:264 +#: src/components/profiles/StreamSelectionProfilesTable.tsx:68 #: src/components/settings/ConnectMediaSources.tsx:44 #: src/components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx:95 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:93 @@ -2600,6 +2744,7 @@ msgstr "Need at least one path" msgid "never" msgstr "never" +#: src/components/profiles/StreamSelectionProfilesTable.tsx:145 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:167 #: src/hooks/useRouteName.ts:51 #: src/hooks/useRouteName.ts:113 @@ -2639,6 +2784,14 @@ msgstr "New Media Source" msgid "New Plex Server" msgstr "New Plex Server" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:230 +msgid "New Profile" +msgstr "New Profile" + +#: src/pages/profiles/StreamSelectionProfilePage.tsx:236 +msgid "New Stream Selection Profile" +msgstr "New Stream Selection Profile" + #: src/pages/welcome/WelcomePage.tsx:242 msgid "Next" msgstr "Next" @@ -2656,6 +2809,10 @@ msgstr "Next Scheduled Execution" msgid "No active sessions" msgstr "No active sessions" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:124 +msgid "No condition" +msgstr "No condition" + #: src/pages/welcome/WelcomePage.tsx:142 msgid "No media sources connected." msgstr "No media sources connected." @@ -2664,6 +2821,10 @@ msgstr "No media sources connected." msgid "No Media Sources detected." msgstr "No Media Sources detected." +#: src/components/profiles/StreamSelectionRuleEditor.tsx:364 +msgid "No preference" +msgstr "No preference" + #: src/components/channel_config/ChannelLineupList.tsx:500 msgid "No programming added yet" msgstr "No programming added yet" @@ -2695,6 +2856,10 @@ msgstr "NodeJS: {0}" msgid "None" msgstr "None" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:476 +msgid "None (no filter)" +msgstr "None (no filter)" + #: src/components/programming_controls/ShuffleProgrammingModal.tsx:64 msgid "None:" msgstr "None:" @@ -2713,11 +2878,15 @@ msgstr "Not a valid number" msgid "Not a valid URL" msgstr "Not a valid URL" +#: src/components/profiles/StreamSelectionProfilesTable.tsx:86 +msgid "Not assigned" +msgstr "Not assigned" + #: src/routes/__root.tsx:68 msgid "Not found!" msgstr "Not found!" -#: src/components/channels/ChannelNowPlayingCard.tsx:212 +#: src/components/channels/ChannelNowPlayingCard.tsx:244 msgid "Now Playing:" msgstr "Now Playing:" @@ -2773,6 +2942,10 @@ msgstr "Open in {0}" msgid "Operator" msgstr "Operator" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:188 +msgid "Optional friendly name for this rule" +msgstr "Optional friendly name for this rule" + #: src/components/channels/ChannelOptionsButton.tsx:58 msgid "Options" msgstr "Options" @@ -2939,6 +3112,19 @@ msgstr "Post" msgid "Pre" msgstr "Pre" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:356 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:361 +msgid "Prefer Channel Count" +msgstr "Prefer Channel Count" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:343 +msgid "Preferred languages in priority order. Type a code to add custom." +msgstr "Preferred languages in priority order. Type a code to add custom." + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:451 +msgid "Preferred subtitle languages" +msgstr "Preferred subtitle languages" + #: src/components/slot_scheduler/RandomSlotPresetButton.tsx:48 msgid "Presets" msgstr "Presets" @@ -2955,6 +3141,26 @@ msgstr "Proceed" msgid "Profile" msgstr "Profile" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:155 +msgid "Profile created" +msgstr "Profile created" + +#: src/pages/profiles/StreamSelectionProfilePage.tsx:252 +msgid "Profile Name" +msgstr "Profile Name" + +#: src/pages/profiles/StreamSelectionProfilePage.tsx:248 +msgid "Profile name is required" +msgstr "Profile name is required" + +#: src/pages/profiles/StreamSelectionProfilePage.tsx:169 +msgid "Profile saved" +msgstr "Profile saved" + +#: src/hooks/useNavItems.tsx:102 +msgid "Profiles" +msgstr "Profiles" + #: src/components/ProgramSearchAutocomplete.tsx:38 #: src/components/slot_scheduler/RandomSlotTable.tsx:259 #: src/components/slot_scheduler/RedirectProgrammingForm.tsx:46 @@ -3161,6 +3367,10 @@ msgstr "Remove icon" msgid "Remove Programming" msgstr "Remove Programming" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:164 +msgid "Remove rule" +msgstr "Remove rule" + #: src/components/channel_config/ChannelProgrammingDeleteOptions.tsx:96 msgid "Remove..." msgstr "Remove..." @@ -3222,6 +3432,7 @@ msgstr "Reset" #: src/components/channel_config/ChannelEditActions.tsx:80 #: src/components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx:268 +#: src/pages/profiles/StreamSelectionProfilePage.tsx:335 #: src/pages/settings/FeaturesSettingsPage.tsx:162 #: src/pages/settings/FfmpegSettingsPage.tsx:407 #: src/pages/settings/HdhrSettingsPage.tsx:142 @@ -3296,6 +3507,20 @@ msgstr "Roll the log file on a fixed schedule, regardless of file size." msgid "Root" msgstr "Root" +#. placeholder {0}: index + 1 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:113 +msgid "Rule {0}" +msgstr "Rule {0}" + +#: src/components/profiles/StreamSelectionProfilesTable.tsx:72 +#: src/pages/profiles/StreamSelectionProfilePage.tsx:270 +msgid "Rules" +msgstr "Rules" + +#: src/pages/profiles/StreamSelectionProfilePage.tsx:283 +msgid "Rules are evaluated in order. The first rule whose condition matches determines the audio and subtitle streams for playback." +msgstr "Rules are evaluated in order. The first rule whose condition matches determines the audio and subtitle streams for playback." + #: src/pages/settings/TaskSettingsPage.tsx:179 msgid "Run" msgstr "Run" @@ -3336,6 +3561,7 @@ msgstr "Sample rate cannot be changed when copying input audio" #: src/components/smart_collections/EditSmartCollectionDialog.tsx:121 #: src/pages/channels/RandomSlotEditorPage.tsx:270 #: src/pages/channels/TimeSlotEditorPage.tsx:542 +#: src/pages/profiles/StreamSelectionProfilePage.tsx:343 #: src/pages/settings/FeaturesSettingsPage.tsx:170 #: src/pages/settings/FfmpegSettingsPage.tsx:417 #: src/pages/settings/HdhrSettingsPage.tsx:152 @@ -3394,11 +3620,11 @@ msgstr "Search for a program" msgid "Search for shows" msgstr "Search for shows" -#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:38 +#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:42 msgid "Search is currently scoped to this Media Source Library." msgstr "Search is currently scoped to this Media Source Library." -#: src/routes/media_sources_/$mediaSourceId/index.tsx:39 +#: src/routes/media_sources_/$mediaSourceId/index.tsx:41 msgid "Search is currently scoped to this Media Source." msgstr "Search is currently scoped to this Media Source." @@ -3486,7 +3712,7 @@ msgid "Sets the number of threads used to decode the input stream. Set to 0 to l msgstr "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." #: src/components/slot_scheduler/RandomSlotSettingsForm.tsx:83 -#: src/hooks/useNavItems.tsx:129 +#: src/hooks/useNavItems.tsx:141 #: src/pages/channels/TimeSlotEditorPage.tsx:313 #: src/pages/settings/SettingsLayout.tsx:16 msgid "Settings" @@ -3589,7 +3815,7 @@ msgstr "Smart Collection - {0}" msgid "Smart Collection: {0}" msgstr "Smart Collection: {0}" -#: src/hooks/useNavItems.tsx:79 +#: src/hooks/useNavItems.tsx:80 #: src/hooks/useRouteName.ts:117 #: src/routes/library/smart_collections/index.tsx:20 msgid "Smart Collections" @@ -3649,7 +3875,7 @@ msgstr "Source" msgid "Source Type" msgstr "Source Type" -#: src/hooks/useNavItems.tsx:96 +#: src/hooks/useNavItems.tsx:97 msgid "Sources" msgstr "Sources" @@ -3667,11 +3893,11 @@ msgstr "Start" msgid "Start Time" msgstr "Start Time" -#: src/components/channels/ChannelNowPlayingCard.tsx:219 +#: src/components/channels/ChannelNowPlayingCard.tsx:251 msgid "Started {startedAgo} - {remainingTime}remaining" msgstr "Started {startedAgo} - {remainingTime}remaining" -#: src/hooks/useNavItems.tsx:112 +#: src/hooks/useNavItems.tsx:124 #: src/pages/system/SystemLayout.tsx:31 msgid "Status" msgstr "Status" @@ -3700,10 +3926,20 @@ msgstr "Stream JSON" msgid "Stream Mode" msgstr "Stream Mode" +#: src/hooks/useNavItems.tsx:107 #: src/pages/system/TroubleshootPage.tsx:725 msgid "Stream Selection" msgstr "Stream Selection" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:227 +#: src/pages/profiles/StreamSelectionProfilesPage.tsx:9 +msgid "Stream Selection Profiles" +msgstr "Stream Selection Profiles" + +#: src/pages/profiles/StreamSelectionProfilesPage.tsx:13 +msgid "Stream selection profiles control which audio and subtitle streams are selected during transcoding. Assign profiles to channels, filler lists, or individual programs." +msgstr "Stream selection profiles control which audio and subtitle streams are selected during transcoding. Assign profiles to channels, filler lists, or individual programs." + #: src/components/channel_config/EditChannelForm.tsx:248 msgid "Streaming" msgstr "Streaming" @@ -3716,10 +3952,23 @@ msgstr "Submit" msgid "Submitting..." msgstr "Submitting..." +#: src/components/profiles/StreamSelectionRuleEditor.tsx:133 +msgid "Subs: {subtitleSummary}" +msgstr "Subs: {subtitleSummary}" + #: src/pages/system/TroubleshootPage.tsx:757 msgid "Subtitle Action" msgstr "Subtitle Action" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:259 +msgid "Subtitle Selection" +msgstr "Subtitle Selection" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:268 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:270 +msgid "Subtitle Strategy" +msgstr "Subtitle Strategy" + #: src/pages/system/TroubleshootPage.tsx:669 msgid "Subtitle Streams" msgstr "Subtitle Streams" @@ -3766,7 +4015,7 @@ msgid "Synced with external playlist" msgstr "Synced with external playlist" #: src/components/settings/DarkModeButton.tsx:47 -#: src/hooks/useNavItems.tsx:101 +#: src/hooks/useNavItems.tsx:113 #: src/pages/system/SystemLayout.tsx:17 msgid "System" msgstr "System" @@ -3801,7 +4050,7 @@ msgstr "Tasks" msgid "Temporarily caches responses from Plex based by request path. Could potentially speed up channel editing." msgstr "Temporarily caches responses from Plex based by request path. Could potentially speed up channel editing." -#: src/routes/channels_/test.tsx:5 +#: src/routes/channels_/test.tsx:7 msgid "Test" msgstr "Test" @@ -3988,6 +4237,14 @@ msgstr "Timestamp" msgid "Title" msgstr "Title" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:392 +msgid "Title Contains" +msgstr "Title Contains" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:387 +msgid "Title filter is required" +msgstr "Title filter is required" + #: src/components/programming_controls/AddRestrictHoursModal.tsx:120 msgid "TO" msgstr "TO" @@ -4053,7 +4310,7 @@ msgstr "Transcoding Configs" msgid "Transcoding Settings" msgstr "Transcoding Settings" -#: src/hooks/useNavItems.tsx:89 +#: src/hooks/useNavItems.tsx:90 #: src/hooks/useRouteName.ts:129 #: src/pages/library/TrashPage.tsx:100 msgid "Trash" @@ -4146,6 +4403,10 @@ 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/profiles/StreamSelectionProfilesTable.tsx:77 +msgid "Used By" +msgstr "Used By" + #: src/components/settings/media_source/EmbyServerEditDialog.tsx:349 #: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:374 msgid "Username" @@ -4225,7 +4486,7 @@ msgstr "View Full Details" #. placeholder {0}: capitalize(firstProgram.program.sourceType) #. placeholder {0}: capitalize(program.sourceType) -#: src/components/channels/ChannelNowPlayingCard.tsx:245 +#: src/components/channels/ChannelNowPlayingCard.tsx:277 #: src/components/ProgramMetadataDialogContent.tsx:144 msgid "View in {0}" msgstr "View in {0}" @@ -4282,7 +4543,7 @@ msgstr "Weight %" msgid "Weighting" msgstr "Weighting" -#: src/hooks/useNavItems.tsx:56 +#: src/hooks/useNavItems.tsx:57 msgid "Welcome" msgstr "Welcome" diff --git a/web/src/locales/en/messages.ts b/web/src/locales/en/messages.ts index 2cf68537f..d65b0a4d2 100644 --- a/web/src/locales/en/messages.ts +++ b/web/src/locales/en/messages.ts @@ -1,4 +1,4 @@ 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)"],"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"]}', + '{"++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."],"/JQh8n":["Match audio streams whose title contains this text (case-insensitive)"],"/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"],"3Ib6FN":["Move down"],"3JIYke":["Healthy?"],"3JQkm5":["Path Replacements"],"3JjdaA":["Run"],"3LfNqe":["Channel Number"],"3SH6Vv":["Copied channel \\"",["channelName"],"\\" m3u link to clipboard"],"3T+8r+":["Forced only"],"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"],"4EZrJN":["Rules"],"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."],"5oyVZS":["Prefer Channel Count"],"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"],"7739L7":["Stream Selection Profiles"],"7B3lfh":["Items from any filler list will not be chosen more frequently than this cooldown setting."],"7BAOFm":["Not assigned"],"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)"],"7fLSqD":[["0"]," channel(s)"],"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"],"8Ch9cS":["No preference"],"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"],"BigE6r":["Audio Strategy"],"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"],"ClUxys":["Optional friendly name for this rule"],"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"]}]],"D5IOoq":["Title filter is required"],"DDR4V1":["Preferred languages in priority order. Type a code to add custom."],"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"],"DrfvUu":["Allow image-based subtitles"],"DxvGLB":["Add Slot"],"E/QGRL":["Disabled"],"E5ipHC":["Balance By:"],"E8KFsc":["Audio: ",["audioSummary"]],"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"],"FY1Ztd":["Invalid expression"],"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"],"GAmD3h":["Languages"],"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"],"GwO5g4":["Failed to validate expression"],"GzzMwi":["Roll on Schedule"],"H+4ZaX":["Condition is required"],"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"],"KGFLpf":["Used By"],"KRjDf4":["Audio Streams"],"KTtYr9":["By Title"],"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."],"LCj67s":["Subs: ",["subtitleSummary"]],"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"],"MJr3i9":["Title Contains"],"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"],"Pi0TLp":["Default (first stream)"],"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"],"QyioBP":["Move up"],"R+X/he":["Profile Name"],"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."],"RY3VxI":["No condition"],"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"],"SjxzXf":["Remove rule"],"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:"],"SzNZRr":["Subtitle Selection"],"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."],"TkzAPg":["Profile name is required"],"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."],"UDaVJs":[["0"]," program(s)"],"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"],"WxMod2":["Edit Stream Selection Profile"],"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"],"XoYeBe":["Preferred subtitle languages"],"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."],"Zm5ZtK":["All channels, fillers, and programs using this profile will have their stream selection reset to defaults."],"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"],"aOnWmo":["Rules are evaluated in order. The first rule whose condition matches determines the audio and subtitle streams for playback."],"aScBGS":["Add a filter expression to fine-tune results of the search"],"aSwfbR":["Unit"],"ad9wBQ":["New Profile"],"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"],"bmQLn5":["Add Rule"],"boItSp":["Delete Media Source?"],"buS8nL":["Enable Subtitles"],"bxyuno":["Override global audio and subtitle settings for this channel."],"bydide":["FFMPEG Log Method"],"c1f0Qv":["Delete Profile \\"",["0"],"\\"?"],"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."],"ccH5/A":["Create Profile"],"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"],"eauqYh":["Stream selection profiles control which audio and subtitle streams are selected during transcoding. Assign profiles to channels, filler lists, or individual programs."],"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"],"gVcD5M":["CEL expression. Use \\"true\\" to always match."],"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"],"gpwdq7":[["0"]," filler(s)"],"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"],"hV0YJc":["At least one language is required"],"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"],"iLVyZt":["Most channels (e.g. 7.1 surround)"],"iQWhqk":["FFMPEG is installed. Detected version ",["0"]],"iTjV+L":["A-Z (desc)"],"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"],"lnr2QQ":["Least channels (e.g. stereo)"],"lu2qW5":["Any"],"m+8qnB":["Library: ",["0"]],"m+9pF8":["By Language"],"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."],"n4EJAA":["Subtitle Strategy"],"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"],"nyS8Ib":["Audio Selection"],"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"],"op6W0V":["Allow external subtitles"],"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"],"r6Yf/m":["New Stream Selection Profile"],"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"],"snAR/S":["None (no filter)"],"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."],"vq2FYw":["Rule ",["0"]],"vrQQgz":["Profiles"],"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"],"wTXT7g":["Default only"],"wYqXX9":["Profile saved"],"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"],"zXeOax":["Profile created"],"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 cdabc3ffa..56a0519b1 100644 --- a/web/src/locales/es/messages.po +++ b/web/src/locales/es/messages.po @@ -103,6 +103,16 @@ msgstr "" msgid "{0, plural, one {Selected Item} other {Selected Items}}" msgstr "" +#. placeholder {0}: original.usedByChannels +#: src/components/profiles/StreamSelectionProfilesTable.tsx:93 +msgid "{0} channel(s)" +msgstr "" + +#. placeholder {0}: original.usedByFillers +#: src/components/profiles/StreamSelectionProfilesTable.tsx:101 +msgid "{0} filler(s)" +msgstr "" + #. placeholder {0}: prettifySnakeCaseString(programType) #: src/components/programs/ProgramDetailsDialog.tsx:180 msgid "{0} Info" @@ -122,6 +132,11 @@ msgstr "" msgid "{0} Poster" msgstr "" +#. placeholder {0}: original.usedByPrograms +#: src/components/profiles/StreamSelectionProfilesTable.tsx:109 +msgid "{0} program(s)" +msgstr "" + #: src/components/programming_controls/AddRerunBlockModal.tsx:64 msgid "{block} Hours" msgstr "" @@ -406,6 +421,10 @@ msgstr "" msgid "Add Redirect" msgstr "" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:278 +msgid "Add Rule" +msgstr "" + #: src/components/channel_config/SelectedProgrammingActions.tsx:209 msgid "Add Selected Media" msgstr "" @@ -488,6 +507,10 @@ msgstr "" msgid "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." msgstr "" +#: src/components/profiles/StreamSelectionProfilesTable.tsx:158 +msgid "All channels, fillers, and programs using this profile will have their stream selection reset to defaults." +msgstr "" + #: src/components/channel_config/jellyfin/JellyfinLibrarySelector.tsx:104 #~ msgid "All Genres" #~ msgstr "" @@ -508,10 +531,18 @@ msgstr "" msgid "Allow External" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:509 +msgid "Allow external subtitles" +msgstr "" + #: src/components/channel_config/ChannelSubtitlePreferencesTable.tsx:64 msgid "Allow Image Based" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:494 +msgid "Allow image-based subtitles" +msgstr "" + #: src/pages/channels/TimeSlotEditorPage.tsx:383 msgid "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." msgstr "" @@ -546,6 +577,10 @@ msgstr "" msgid "An error occurred: {0}" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:467 +msgid "Any" +msgstr "" + #: src/components/slot_scheduler/MidRollConfigPanel.tsx:502 msgid "Apply to Program Types (empty = all)" msgstr "" @@ -572,6 +607,11 @@ msgstr "" msgid "Ascending" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:308 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:418 +msgid "At least one language is required" +msgstr "" + #: src/pages/system/StatusPage.tsx:184 msgid "Attempt Auto-Fix" msgstr "" @@ -630,6 +670,15 @@ msgstr "" msgid "Audio Sample Rate" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:223 +msgid "Audio Selection" +msgstr "" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:232 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:234 +msgid "Audio Strategy" +msgstr "" + #: src/pages/system/TroubleshootPage.tsx:622 msgid "Audio Streams" msgstr "" @@ -638,6 +687,10 @@ msgstr "" msgid "Audio Volume" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:127 +msgid "Audio: {audioSummary}" +msgstr "" + #: src/components/settings/general/WebSettings.tsx:99 msgid "Auto" msgstr "" @@ -756,6 +809,18 @@ msgstr "" msgid "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." msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:92 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:99 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:239 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:278 +msgid "By Language" +msgstr "" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:93 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:242 +msgid "By Title" +msgstr "" + #: src/components/settings/general/GeneralSettingsForm.tsx:434 msgid "Caching" msgstr "" @@ -826,6 +891,10 @@ msgstr "" msgid "Category Log Levels" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:211 +msgid "CEL expression. Use \"true\" to always match." +msgstr "" + #: src/components/settings/general/GeneralSettingsForm.tsx:385 msgid "Change the verbosity of specific categories of logs. Useful if debugging a specific feature." msgstr "" @@ -883,7 +952,7 @@ msgid "Channel Transcode Config" msgstr "" #: src/App.tsx:95 -#: src/hooks/useNavItems.tsx:63 +#: src/hooks/useNavItems.tsx:64 #: src/hooks/useRouteName.ts:38 #: src/pages/channels/ChannelsPage.tsx:566 #: src/pages/system/TroubleshootPage.tsx:636 @@ -959,10 +1028,16 @@ msgstr "" msgid "Component" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:208 #: src/pages/system/TroubleshootPage.tsx:751 msgid "Condition" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:199 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:201 +msgid "Condition is required" +msgstr "" + #: src/components/slot_scheduler/EditTimeSlotDialogContent.tsx:278 msgid "Config" msgstr "" @@ -1092,6 +1167,10 @@ msgstr "" msgid "Create a Channel" msgstr "" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:343 +msgid "Create Profile" +msgstr "" + #: src/components/programming_controls/AddRerunBlockModal.tsx:31 msgid "Create Rerun Block" msgstr "" @@ -1128,7 +1207,7 @@ msgid "Custom Show: {0}" msgstr "" #: src/components/channel_config/ProgrammingSelector.tsx:267 -#: src/hooks/useNavItems.tsx:84 +#: src/hooks/useNavItems.tsx:85 #: src/hooks/useRouteName.ts:121 #: src/pages/library/CustomShowsPage.tsx:207 msgid "Custom Shows" @@ -1176,24 +1255,36 @@ msgstr "" msgid "Days to Precalculate" msgstr "" -#: src/hooks/useNavItems.tsx:117 +#: src/hooks/useNavItems.tsx:129 #: src/pages/system/SystemLayout.tsx:32 msgid "Debug" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:90 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:98 #: src/pages/system/TroubleshootPage.tsx:642 #: src/pages/system/TroubleshootPage.tsx:686 msgid "Default" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:236 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:275 +msgid "Default (first stream)" +msgstr "" + #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:99 msgid "Default Config" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:473 +msgid "Default only" +msgstr "" + #: src/components/channel_config/ChannelProgrammingDeleteOptions.tsx:32 #: src/components/channels/ChannelDeleteDialog.tsx:86 #: src/components/custom-shows/CustomShowSortToolsMenu.tsx:186 #: src/components/DeleteConfirmationDialog.tsx:59 +#: src/components/profiles/StreamSelectionProfilesTable.tsx:54 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:75 #: src/components/smart_collections/SmartCollectionsTable.tsx:124 #: src/pages/channels/ChannelsPage.tsx:206 @@ -1238,6 +1329,11 @@ msgstr "" #~ msgid "Delete Media Source?" #~ msgstr "" +#. placeholder {0}: confirmDelete?.name ?? '' +#: src/components/profiles/StreamSelectionProfilesTable.tsx:157 +msgid "Delete Profile \"{0}\"?" +msgstr "" + #: src/components/slot_scheduler/RandomSlotTable.tsx:427 #: src/components/slot_scheduler/TimeSlotTable.tsx:395 msgid "Delete Slot" @@ -1283,7 +1379,7 @@ msgstr "" msgid "Description" msgstr "" -#: src/components/channels/ChannelNowPlayingCard.tsx:227 +#: src/components/channels/ChannelNowPlayingCard.tsx:259 msgid "Details" msgstr "" @@ -1311,6 +1407,8 @@ msgstr "" msgid "Disable Watermarks" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:96 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:272 #: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:219 #: src/pages/settings/FfmpegSettingsPage.tsx:224 #: src/pages/system/StatusPage.tsx:334 @@ -1411,6 +1509,7 @@ msgstr "" msgid "Eager" msgstr "" +#: src/components/profiles/StreamSelectionProfilesTable.tsx:46 #: src/components/settings/ConnectMediaSources.tsx:47 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:65 #: src/components/smart_collections/SmartCollectionsTable.tsx:117 @@ -1458,6 +1557,10 @@ msgstr "" msgid "Edit Slot" msgstr "" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:238 +msgid "Edit Stream Selection Profile" +msgstr "" + #: src/hooks/useRouteName.ts:143 msgid "Edit Transcode Config" msgstr "" @@ -1735,6 +1838,10 @@ msgstr "" msgid "Failed to update Media Source settings. Please check server and browser logs for details." msgstr "" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:204 +msgid "Failed to validate expression" +msgstr "" + #: src/components/slot_scheduler/SlotFillerDialogPanel.tsx:203 msgid "Fallback" msgstr "" @@ -1884,7 +1991,7 @@ msgstr "" msgid "Filler List: {0}" msgstr "" -#: src/hooks/useNavItems.tsx:74 +#: src/hooks/useNavItems.tsx:75 #: src/hooks/useRouteName.ts:99 #: src/pages/library/FillerListsPage.tsx:219 msgid "Filler Lists" @@ -1899,6 +2006,8 @@ msgid "Filler Options" msgstr "" #: src/components/channel_config/ChannelSubtitlePreferencesTable.tsx:85 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:463 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:465 #: src/components/search/PointAndClickSearchBuilder.tsx:27 #: src/components/search/SearchFilterBuilder.tsx:73 #: src/components/smart_collections/CreateSmartCollectionDialog.tsx:178 @@ -1958,6 +2067,10 @@ msgstr "" msgid "Forced" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:470 +msgid "Forced only" +msgstr "" + #: src/pages/system/TroubleshootPage.tsx:574 msgid "Frame Rate" msgstr "" @@ -2001,7 +2114,7 @@ msgstr "" msgid "Grouping works as follows:" msgstr "" -#: src/hooks/useNavItems.tsx:61 +#: src/hooks/useNavItems.tsx:62 #: src/pages/guide/GuidePage.tsx:120 msgid "Guide" msgstr "" @@ -2157,6 +2270,10 @@ msgstr "" msgid "Interval (minutes)" msgstr "" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:202 +msgid "Invalid expression" +msgstr "" + #: src/components/slot_scheduler/SlotOrderFormControl.tsx:46 msgid "Inverse linear decay, heavier weighting." msgstr "" @@ -2182,6 +2299,7 @@ msgstr "" msgid "Keywords perform full text search across all (or configured) fields" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:187 #: src/pages/system/TroubleshootPage.tsx:748 msgid "Label" msgstr "" @@ -2197,6 +2315,11 @@ msgstr "" msgid "Language" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:338 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:448 +msgid "Languages" +msgstr "" + #: src/pages/settings/TaskSettingsPage.tsx:236 msgid "Last run" msgstr "" @@ -2223,6 +2346,10 @@ msgstr "" msgid "Lazy" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:370 +msgid "Least channels (e.g. stereo)" +msgstr "" + #: src/components/channel_config/ChannelTranscodingConfig.tsx:353 msgid "Leave blank to use the channel's icon." msgstr "" @@ -2241,7 +2368,7 @@ msgstr "" #: src/components/channel_config/ImportedLibrarySeletor.tsx:102 #: src/components/channel_config/ImportedLibrarySeletor.tsx:104 -#: src/hooks/useNavItems.tsx:69 +#: src/hooks/useNavItems.tsx:70 #: src/hooks/useRouteName.ts:95 #: src/pages/library/LibraryIndexPage.tsx:12 msgid "Library" @@ -2252,7 +2379,7 @@ msgid "Library Clip (not yet implemented)" msgstr "" #. placeholder {0}: library.name -#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:36 +#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:39 msgid "Library: {0}" msgstr "" @@ -2347,7 +2474,7 @@ msgstr "" msgid "Logging" msgstr "" -#: src/hooks/useNavItems.tsx:122 +#: src/hooks/useNavItems.tsx:134 #: src/pages/system/SystemLayout.tsx:33 msgid "Logs" msgstr "" @@ -2412,6 +2539,10 @@ msgstr "" msgid "Match any of" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:395 +msgid "Match audio streams whose title contains this text (case-insensitive)" +msgstr "" + #: src/components/settings/general/BackupForm.tsx:87 #: src/components/settings/general/BackupForm.tsx:90 msgid "Max Backups" @@ -2462,8 +2593,8 @@ msgstr "" #. placeholder {0}: library.mediaSource.name #. placeholder {0}: mediaSource.name -#: src/routes/media_sources_/$mediaSourceId/index.tsx:35 -#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:33 +#: src/routes/media_sources_/$mediaSourceId/index.tsx:36 +#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:34 msgid "Media Source: \"{0}\"" msgstr "" @@ -2515,6 +2646,18 @@ msgstr "" msgid "Month" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:367 +msgid "Most channels (e.g. 7.1 surround)" +msgstr "" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:153 +msgid "Move down" +msgstr "" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:142 +msgid "Move up" +msgstr "" + #: src/components/channel_config/SelectedProgrammingList.tsx:76 #: src/hooks/slot_scheduler/useSlotName.ts:13 msgid "Movie" @@ -2566,6 +2709,7 @@ msgstr "" #: src/components/custom-shows/EditCustomShowForm.tsx:270 #: src/components/filler/EditFillerListForm.tsx:137 #: src/components/MediaSourceLibraryTable.tsx:264 +#: src/components/profiles/StreamSelectionProfilesTable.tsx:68 #: src/components/settings/ConnectMediaSources.tsx:44 #: src/components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx:95 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:93 @@ -2600,6 +2744,7 @@ msgstr "" msgid "never" msgstr "" +#: src/components/profiles/StreamSelectionProfilesTable.tsx:145 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:167 #: src/hooks/useRouteName.ts:51 #: src/hooks/useRouteName.ts:113 @@ -2639,6 +2784,14 @@ msgstr "" msgid "New Plex Server" msgstr "" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:230 +msgid "New Profile" +msgstr "" + +#: src/pages/profiles/StreamSelectionProfilePage.tsx:236 +msgid "New Stream Selection Profile" +msgstr "" + #: src/pages/welcome/WelcomePage.tsx:242 msgid "Next" msgstr "" @@ -2656,6 +2809,10 @@ msgstr "" msgid "No active sessions" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:124 +msgid "No condition" +msgstr "" + #: src/pages/welcome/WelcomePage.tsx:142 msgid "No media sources connected." msgstr "" @@ -2664,6 +2821,10 @@ msgstr "" msgid "No Media Sources detected." msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:364 +msgid "No preference" +msgstr "" + #: src/components/channel_config/ChannelLineupList.tsx:500 msgid "No programming added yet" msgstr "" @@ -2695,6 +2856,10 @@ msgstr "" msgid "None" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:476 +msgid "None (no filter)" +msgstr "" + #: src/components/programming_controls/ShuffleProgrammingModal.tsx:64 msgid "None:" msgstr "" @@ -2713,11 +2878,15 @@ msgstr "" msgid "Not a valid URL" msgstr "" +#: src/components/profiles/StreamSelectionProfilesTable.tsx:86 +msgid "Not assigned" +msgstr "" + #: src/routes/__root.tsx:68 msgid "Not found!" msgstr "" -#: src/components/channels/ChannelNowPlayingCard.tsx:212 +#: src/components/channels/ChannelNowPlayingCard.tsx:244 msgid "Now Playing:" msgstr "" @@ -2773,6 +2942,10 @@ msgstr "" msgid "Operator" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:188 +msgid "Optional friendly name for this rule" +msgstr "" + #: src/components/channels/ChannelOptionsButton.tsx:58 msgid "Options" msgstr "" @@ -2939,6 +3112,19 @@ msgstr "" msgid "Pre" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:356 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:361 +msgid "Prefer Channel Count" +msgstr "" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:343 +msgid "Preferred languages in priority order. Type a code to add custom." +msgstr "" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:451 +msgid "Preferred subtitle languages" +msgstr "" + #: src/components/slot_scheduler/RandomSlotPresetButton.tsx:48 msgid "Presets" msgstr "" @@ -2955,6 +3141,26 @@ msgstr "" msgid "Profile" msgstr "" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:155 +msgid "Profile created" +msgstr "" + +#: src/pages/profiles/StreamSelectionProfilePage.tsx:252 +msgid "Profile Name" +msgstr "" + +#: src/pages/profiles/StreamSelectionProfilePage.tsx:248 +msgid "Profile name is required" +msgstr "" + +#: src/pages/profiles/StreamSelectionProfilePage.tsx:169 +msgid "Profile saved" +msgstr "" + +#: src/hooks/useNavItems.tsx:102 +msgid "Profiles" +msgstr "" + #: src/components/ProgramSearchAutocomplete.tsx:38 #: src/components/slot_scheduler/RandomSlotTable.tsx:259 #: src/components/slot_scheduler/RedirectProgrammingForm.tsx:46 @@ -3159,6 +3365,10 @@ msgstr "" msgid "Remove Programming" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:164 +msgid "Remove rule" +msgstr "" + #: src/components/channel_config/ChannelProgrammingDeleteOptions.tsx:96 msgid "Remove..." msgstr "" @@ -3220,6 +3430,7 @@ msgstr "" #: src/components/channel_config/ChannelEditActions.tsx:80 #: src/components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx:268 +#: src/pages/profiles/StreamSelectionProfilePage.tsx:335 #: src/pages/settings/FeaturesSettingsPage.tsx:162 #: src/pages/settings/FfmpegSettingsPage.tsx:407 #: src/pages/settings/HdhrSettingsPage.tsx:142 @@ -3294,6 +3505,20 @@ msgstr "" msgid "Root" msgstr "" +#. placeholder {0}: index + 1 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:113 +msgid "Rule {0}" +msgstr "" + +#: src/components/profiles/StreamSelectionProfilesTable.tsx:72 +#: src/pages/profiles/StreamSelectionProfilePage.tsx:270 +msgid "Rules" +msgstr "" + +#: src/pages/profiles/StreamSelectionProfilePage.tsx:283 +msgid "Rules are evaluated in order. The first rule whose condition matches determines the audio and subtitle streams for playback." +msgstr "" + #: src/pages/settings/TaskSettingsPage.tsx:179 msgid "Run" msgstr "" @@ -3334,6 +3559,7 @@ msgstr "" #: src/components/smart_collections/EditSmartCollectionDialog.tsx:121 #: src/pages/channels/RandomSlotEditorPage.tsx:270 #: src/pages/channels/TimeSlotEditorPage.tsx:542 +#: src/pages/profiles/StreamSelectionProfilePage.tsx:343 #: src/pages/settings/FeaturesSettingsPage.tsx:170 #: src/pages/settings/FfmpegSettingsPage.tsx:417 #: src/pages/settings/HdhrSettingsPage.tsx:152 @@ -3392,11 +3618,11 @@ msgstr "" msgid "Search for shows" msgstr "" -#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:38 +#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:42 msgid "Search is currently scoped to this Media Source Library." msgstr "" -#: src/routes/media_sources_/$mediaSourceId/index.tsx:39 +#: src/routes/media_sources_/$mediaSourceId/index.tsx:41 msgid "Search is currently scoped to this Media Source." msgstr "" @@ -3484,7 +3710,7 @@ msgid "Sets the number of threads used to decode the input stream. Set to 0 to l msgstr "" #: src/components/slot_scheduler/RandomSlotSettingsForm.tsx:83 -#: src/hooks/useNavItems.tsx:129 +#: src/hooks/useNavItems.tsx:141 #: src/pages/channels/TimeSlotEditorPage.tsx:313 #: src/pages/settings/SettingsLayout.tsx:16 msgid "Settings" @@ -3587,7 +3813,7 @@ msgstr "" msgid "Smart Collection: {0}" msgstr "" -#: src/hooks/useNavItems.tsx:79 +#: src/hooks/useNavItems.tsx:80 #: src/hooks/useRouteName.ts:117 #: src/routes/library/smart_collections/index.tsx:20 msgid "Smart Collections" @@ -3647,7 +3873,7 @@ msgstr "" msgid "Source Type" msgstr "" -#: src/hooks/useNavItems.tsx:96 +#: src/hooks/useNavItems.tsx:97 msgid "Sources" msgstr "" @@ -3665,11 +3891,11 @@ msgstr "" msgid "Start Time" msgstr "" -#: src/components/channels/ChannelNowPlayingCard.tsx:219 +#: src/components/channels/ChannelNowPlayingCard.tsx:251 msgid "Started {startedAgo} - {remainingTime}remaining" msgstr "" -#: src/hooks/useNavItems.tsx:112 +#: src/hooks/useNavItems.tsx:124 #: src/pages/system/SystemLayout.tsx:31 msgid "Status" msgstr "" @@ -3698,10 +3924,20 @@ msgstr "" msgid "Stream Mode" msgstr "" +#: src/hooks/useNavItems.tsx:107 #: src/pages/system/TroubleshootPage.tsx:725 msgid "Stream Selection" msgstr "" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:227 +#: src/pages/profiles/StreamSelectionProfilesPage.tsx:9 +msgid "Stream Selection Profiles" +msgstr "" + +#: src/pages/profiles/StreamSelectionProfilesPage.tsx:13 +msgid "Stream selection profiles control which audio and subtitle streams are selected during transcoding. Assign profiles to channels, filler lists, or individual programs." +msgstr "" + #: src/components/channel_config/EditChannelForm.tsx:248 msgid "Streaming" msgstr "" @@ -3714,10 +3950,23 @@ msgstr "" msgid "Submitting..." msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:133 +msgid "Subs: {subtitleSummary}" +msgstr "" + #: src/pages/system/TroubleshootPage.tsx:757 msgid "Subtitle Action" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:259 +msgid "Subtitle Selection" +msgstr "" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:268 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:270 +msgid "Subtitle Strategy" +msgstr "" + #: src/pages/system/TroubleshootPage.tsx:669 msgid "Subtitle Streams" msgstr "" @@ -3764,7 +4013,7 @@ msgid "Synced with external playlist" msgstr "" #: src/components/settings/DarkModeButton.tsx:47 -#: src/hooks/useNavItems.tsx:101 +#: src/hooks/useNavItems.tsx:113 #: src/pages/system/SystemLayout.tsx:17 msgid "System" msgstr "" @@ -3799,7 +4048,7 @@ msgstr "" msgid "Temporarily caches responses from Plex based by request path. Could potentially speed up channel editing." msgstr "" -#: src/routes/channels_/test.tsx:5 +#: src/routes/channels_/test.tsx:7 msgid "Test" msgstr "" @@ -3986,6 +4235,14 @@ msgstr "" msgid "Title" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:392 +msgid "Title Contains" +msgstr "" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:387 +msgid "Title filter is required" +msgstr "" + #: src/components/programming_controls/AddRestrictHoursModal.tsx:120 msgid "TO" msgstr "" @@ -4051,7 +4308,7 @@ msgstr "" msgid "Transcoding Settings" msgstr "" -#: src/hooks/useNavItems.tsx:89 +#: src/hooks/useNavItems.tsx:90 #: src/hooks/useRouteName.ts:129 #: src/pages/library/TrashPage.tsx:100 msgid "Trash" @@ -4144,6 +4401,10 @@ msgstr "" msgid "Use these settings to override global ffmpeg settings for this channel." msgstr "" +#: src/components/profiles/StreamSelectionProfilesTable.tsx:77 +msgid "Used By" +msgstr "" + #: src/components/settings/media_source/EmbyServerEditDialog.tsx:349 #: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:374 msgid "Username" @@ -4223,7 +4484,7 @@ msgstr "" #. placeholder {0}: capitalize(firstProgram.program.sourceType) #. placeholder {0}: capitalize(program.sourceType) -#: src/components/channels/ChannelNowPlayingCard.tsx:245 +#: src/components/channels/ChannelNowPlayingCard.tsx:277 #: src/components/ProgramMetadataDialogContent.tsx:144 msgid "View in {0}" msgstr "" @@ -4280,7 +4541,7 @@ msgstr "" msgid "Weighting" msgstr "" -#: src/hooks/useNavItems.tsx:56 +#: src/hooks/useNavItems.tsx:57 msgid "Welcome" msgstr "" diff --git a/web/src/locales/es/messages.ts b/web/src/locales/es/messages.ts index 2cf68537f..d65b0a4d2 100644 --- a/web/src/locales/es/messages.ts +++ b/web/src/locales/es/messages.ts @@ -1,4 +1,4 @@ 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)"],"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"]}', + '{"++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."],"/JQh8n":["Match audio streams whose title contains this text (case-insensitive)"],"/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"],"3Ib6FN":["Move down"],"3JIYke":["Healthy?"],"3JQkm5":["Path Replacements"],"3JjdaA":["Run"],"3LfNqe":["Channel Number"],"3SH6Vv":["Copied channel \\"",["channelName"],"\\" m3u link to clipboard"],"3T+8r+":["Forced only"],"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"],"4EZrJN":["Rules"],"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."],"5oyVZS":["Prefer Channel Count"],"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"],"7739L7":["Stream Selection Profiles"],"7B3lfh":["Items from any filler list will not be chosen more frequently than this cooldown setting."],"7BAOFm":["Not assigned"],"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)"],"7fLSqD":[["0"]," channel(s)"],"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"],"8Ch9cS":["No preference"],"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"],"BigE6r":["Audio Strategy"],"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"],"ClUxys":["Optional friendly name for this rule"],"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"]}]],"D5IOoq":["Title filter is required"],"DDR4V1":["Preferred languages in priority order. Type a code to add custom."],"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"],"DrfvUu":["Allow image-based subtitles"],"DxvGLB":["Add Slot"],"E/QGRL":["Disabled"],"E5ipHC":["Balance By:"],"E8KFsc":["Audio: ",["audioSummary"]],"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"],"FY1Ztd":["Invalid expression"],"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"],"GAmD3h":["Languages"],"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"],"GwO5g4":["Failed to validate expression"],"GzzMwi":["Roll on Schedule"],"H+4ZaX":["Condition is required"],"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"],"KGFLpf":["Used By"],"KRjDf4":["Audio Streams"],"KTtYr9":["By Title"],"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."],"LCj67s":["Subs: ",["subtitleSummary"]],"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"],"MJr3i9":["Title Contains"],"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"],"Pi0TLp":["Default (first stream)"],"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"],"QyioBP":["Move up"],"R+X/he":["Profile Name"],"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."],"RY3VxI":["No condition"],"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"],"SjxzXf":["Remove rule"],"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:"],"SzNZRr":["Subtitle Selection"],"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."],"TkzAPg":["Profile name is required"],"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."],"UDaVJs":[["0"]," program(s)"],"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"],"WxMod2":["Edit Stream Selection Profile"],"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"],"XoYeBe":["Preferred subtitle languages"],"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."],"Zm5ZtK":["All channels, fillers, and programs using this profile will have their stream selection reset to defaults."],"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"],"aOnWmo":["Rules are evaluated in order. The first rule whose condition matches determines the audio and subtitle streams for playback."],"aScBGS":["Add a filter expression to fine-tune results of the search"],"aSwfbR":["Unit"],"ad9wBQ":["New Profile"],"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"],"bmQLn5":["Add Rule"],"boItSp":["Delete Media Source?"],"buS8nL":["Enable Subtitles"],"bxyuno":["Override global audio and subtitle settings for this channel."],"bydide":["FFMPEG Log Method"],"c1f0Qv":["Delete Profile \\"",["0"],"\\"?"],"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."],"ccH5/A":["Create Profile"],"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"],"eauqYh":["Stream selection profiles control which audio and subtitle streams are selected during transcoding. Assign profiles to channels, filler lists, or individual programs."],"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"],"gVcD5M":["CEL expression. Use \\"true\\" to always match."],"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"],"gpwdq7":[["0"]," filler(s)"],"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"],"hV0YJc":["At least one language is required"],"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"],"iLVyZt":["Most channels (e.g. 7.1 surround)"],"iQWhqk":["FFMPEG is installed. Detected version ",["0"]],"iTjV+L":["A-Z (desc)"],"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"],"lnr2QQ":["Least channels (e.g. stereo)"],"lu2qW5":["Any"],"m+8qnB":["Library: ",["0"]],"m+9pF8":["By Language"],"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."],"n4EJAA":["Subtitle Strategy"],"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"],"nyS8Ib":["Audio Selection"],"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"],"op6W0V":["Allow external subtitles"],"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"],"r6Yf/m":["New Stream Selection Profile"],"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"],"snAR/S":["None (no filter)"],"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."],"vq2FYw":["Rule ",["0"]],"vrQQgz":["Profiles"],"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"],"wTXT7g":["Default only"],"wYqXX9":["Profile saved"],"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"],"zXeOax":["Profile created"],"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 0d7a67c38..bfc3cb998 100644 --- a/web/src/locales/pseudo-LOCALE/messages.po +++ b/web/src/locales/pseudo-LOCALE/messages.po @@ -103,6 +103,16 @@ msgstr "" msgid "{0, plural, one {Selected Item} other {Selected Items}}" msgstr "" +#. placeholder {0}: original.usedByChannels +#: src/components/profiles/StreamSelectionProfilesTable.tsx:93 +msgid "{0} channel(s)" +msgstr "" + +#. placeholder {0}: original.usedByFillers +#: src/components/profiles/StreamSelectionProfilesTable.tsx:101 +msgid "{0} filler(s)" +msgstr "" + #. placeholder {0}: prettifySnakeCaseString(programType) #: src/components/programs/ProgramDetailsDialog.tsx:180 msgid "{0} Info" @@ -122,6 +132,11 @@ msgstr "" msgid "{0} Poster" msgstr "" +#. placeholder {0}: original.usedByPrograms +#: src/components/profiles/StreamSelectionProfilesTable.tsx:109 +msgid "{0} program(s)" +msgstr "" + #: src/components/programming_controls/AddRerunBlockModal.tsx:64 msgid "{block} Hours" msgstr "" @@ -406,6 +421,10 @@ msgstr "" msgid "Add Redirect" msgstr "" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:278 +msgid "Add Rule" +msgstr "" + #: src/components/channel_config/SelectedProgrammingActions.tsx:209 msgid "Add Selected Media" msgstr "" @@ -488,6 +507,10 @@ msgstr "" msgid "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." msgstr "" +#: src/components/profiles/StreamSelectionProfilesTable.tsx:158 +msgid "All channels, fillers, and programs using this profile will have their stream selection reset to defaults." +msgstr "" + #: src/components/channel_config/jellyfin/JellyfinLibrarySelector.tsx:104 #~ msgid "All Genres" #~ msgstr "" @@ -508,10 +531,18 @@ msgstr "" msgid "Allow External" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:509 +msgid "Allow external subtitles" +msgstr "" + #: src/components/channel_config/ChannelSubtitlePreferencesTable.tsx:64 msgid "Allow Image Based" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:494 +msgid "Allow image-based subtitles" +msgstr "" + #: src/pages/channels/TimeSlotEditorPage.tsx:383 msgid "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." msgstr "" @@ -546,6 +577,10 @@ msgstr "" msgid "An error occurred: {0}" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:467 +msgid "Any" +msgstr "" + #: src/components/slot_scheduler/MidRollConfigPanel.tsx:502 msgid "Apply to Program Types (empty = all)" msgstr "" @@ -572,6 +607,11 @@ msgstr "" msgid "Ascending" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:308 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:418 +msgid "At least one language is required" +msgstr "" + #: src/pages/system/StatusPage.tsx:184 msgid "Attempt Auto-Fix" msgstr "" @@ -630,6 +670,15 @@ msgstr "" msgid "Audio Sample Rate" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:223 +msgid "Audio Selection" +msgstr "" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:232 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:234 +msgid "Audio Strategy" +msgstr "" + #: src/pages/system/TroubleshootPage.tsx:622 msgid "Audio Streams" msgstr "" @@ -638,6 +687,10 @@ msgstr "" msgid "Audio Volume" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:127 +msgid "Audio: {audioSummary}" +msgstr "" + #: src/components/settings/general/WebSettings.tsx:99 msgid "Auto" msgstr "" @@ -756,6 +809,18 @@ msgstr "" msgid "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." msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:92 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:99 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:239 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:278 +msgid "By Language" +msgstr "" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:93 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:242 +msgid "By Title" +msgstr "" + #: src/components/settings/general/GeneralSettingsForm.tsx:434 msgid "Caching" msgstr "" @@ -826,6 +891,10 @@ msgstr "" msgid "Category Log Levels" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:211 +msgid "CEL expression. Use \"true\" to always match." +msgstr "" + #: src/components/settings/general/GeneralSettingsForm.tsx:385 msgid "Change the verbosity of specific categories of logs. Useful if debugging a specific feature." msgstr "" @@ -883,7 +952,7 @@ msgid "Channel Transcode Config" msgstr "" #: src/App.tsx:95 -#: src/hooks/useNavItems.tsx:63 +#: src/hooks/useNavItems.tsx:64 #: src/hooks/useRouteName.ts:38 #: src/pages/channels/ChannelsPage.tsx:566 #: src/pages/system/TroubleshootPage.tsx:636 @@ -959,10 +1028,16 @@ msgstr "" msgid "Component" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:208 #: src/pages/system/TroubleshootPage.tsx:751 msgid "Condition" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:199 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:201 +msgid "Condition is required" +msgstr "" + #: src/components/slot_scheduler/EditTimeSlotDialogContent.tsx:278 msgid "Config" msgstr "" @@ -1092,6 +1167,10 @@ msgstr "" msgid "Create a Channel" msgstr "" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:343 +msgid "Create Profile" +msgstr "" + #: src/components/programming_controls/AddRerunBlockModal.tsx:31 msgid "Create Rerun Block" msgstr "" @@ -1128,7 +1207,7 @@ msgid "Custom Show: {0}" msgstr "" #: src/components/channel_config/ProgrammingSelector.tsx:267 -#: src/hooks/useNavItems.tsx:84 +#: src/hooks/useNavItems.tsx:85 #: src/hooks/useRouteName.ts:121 #: src/pages/library/CustomShowsPage.tsx:207 msgid "Custom Shows" @@ -1176,24 +1255,36 @@ msgstr "" msgid "Days to Precalculate" msgstr "" -#: src/hooks/useNavItems.tsx:117 +#: src/hooks/useNavItems.tsx:129 #: src/pages/system/SystemLayout.tsx:32 msgid "Debug" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:90 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:98 #: src/pages/system/TroubleshootPage.tsx:642 #: src/pages/system/TroubleshootPage.tsx:686 msgid "Default" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:236 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:275 +msgid "Default (first stream)" +msgstr "" + #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:99 msgid "Default Config" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:473 +msgid "Default only" +msgstr "" + #: src/components/channel_config/ChannelProgrammingDeleteOptions.tsx:32 #: src/components/channels/ChannelDeleteDialog.tsx:86 #: src/components/custom-shows/CustomShowSortToolsMenu.tsx:186 #: src/components/DeleteConfirmationDialog.tsx:59 +#: src/components/profiles/StreamSelectionProfilesTable.tsx:54 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:75 #: src/components/smart_collections/SmartCollectionsTable.tsx:124 #: src/pages/channels/ChannelsPage.tsx:206 @@ -1238,6 +1329,11 @@ msgstr "" #~ msgid "Delete Media Source?" #~ msgstr "" +#. placeholder {0}: confirmDelete?.name ?? '' +#: src/components/profiles/StreamSelectionProfilesTable.tsx:157 +msgid "Delete Profile \"{0}\"?" +msgstr "" + #: src/components/slot_scheduler/RandomSlotTable.tsx:427 #: src/components/slot_scheduler/TimeSlotTable.tsx:395 msgid "Delete Slot" @@ -1283,7 +1379,7 @@ msgstr "" msgid "Description" msgstr "" -#: src/components/channels/ChannelNowPlayingCard.tsx:227 +#: src/components/channels/ChannelNowPlayingCard.tsx:259 msgid "Details" msgstr "" @@ -1311,6 +1407,8 @@ msgstr "" msgid "Disable Watermarks" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:96 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:272 #: src/components/settings/ffmpeg/TranscodeConfigAudioSettingsForm.tsx:219 #: src/pages/settings/FfmpegSettingsPage.tsx:224 #: src/pages/system/StatusPage.tsx:334 @@ -1411,6 +1509,7 @@ msgstr "" msgid "Eager" msgstr "" +#: src/components/profiles/StreamSelectionProfilesTable.tsx:46 #: src/components/settings/ConnectMediaSources.tsx:47 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:65 #: src/components/smart_collections/SmartCollectionsTable.tsx:117 @@ -1458,6 +1557,10 @@ msgstr "" msgid "Edit Slot" msgstr "" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:238 +msgid "Edit Stream Selection Profile" +msgstr "" + #: src/hooks/useRouteName.ts:143 msgid "Edit Transcode Config" msgstr "" @@ -1735,6 +1838,10 @@ msgstr "" msgid "Failed to update Media Source settings. Please check server and browser logs for details." msgstr "" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:204 +msgid "Failed to validate expression" +msgstr "" + #: src/components/slot_scheduler/SlotFillerDialogPanel.tsx:203 msgid "Fallback" msgstr "" @@ -1884,7 +1991,7 @@ msgstr "" msgid "Filler List: {0}" msgstr "" -#: src/hooks/useNavItems.tsx:74 +#: src/hooks/useNavItems.tsx:75 #: src/hooks/useRouteName.ts:99 #: src/pages/library/FillerListsPage.tsx:219 msgid "Filler Lists" @@ -1899,6 +2006,8 @@ msgid "Filler Options" msgstr "" #: src/components/channel_config/ChannelSubtitlePreferencesTable.tsx:85 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:463 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:465 #: src/components/search/PointAndClickSearchBuilder.tsx:27 #: src/components/search/SearchFilterBuilder.tsx:73 #: src/components/smart_collections/CreateSmartCollectionDialog.tsx:178 @@ -1958,6 +2067,10 @@ msgstr "" msgid "Forced" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:470 +msgid "Forced only" +msgstr "" + #: src/pages/system/TroubleshootPage.tsx:574 msgid "Frame Rate" msgstr "" @@ -2001,7 +2114,7 @@ msgstr "" msgid "Grouping works as follows:" msgstr "" -#: src/hooks/useNavItems.tsx:61 +#: src/hooks/useNavItems.tsx:62 #: src/pages/guide/GuidePage.tsx:120 msgid "Guide" msgstr "" @@ -2157,6 +2270,10 @@ msgstr "" msgid "Interval (minutes)" msgstr "" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:202 +msgid "Invalid expression" +msgstr "" + #: src/components/slot_scheduler/SlotOrderFormControl.tsx:46 msgid "Inverse linear decay, heavier weighting." msgstr "" @@ -2182,6 +2299,7 @@ msgstr "" msgid "Keywords perform full text search across all (or configured) fields" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:187 #: src/pages/system/TroubleshootPage.tsx:748 msgid "Label" msgstr "" @@ -2197,6 +2315,11 @@ msgstr "" msgid "Language" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:338 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:448 +msgid "Languages" +msgstr "" + #: src/pages/settings/TaskSettingsPage.tsx:236 msgid "Last run" msgstr "" @@ -2223,6 +2346,10 @@ msgstr "" msgid "Lazy" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:370 +msgid "Least channels (e.g. stereo)" +msgstr "" + #: src/components/channel_config/ChannelTranscodingConfig.tsx:353 msgid "Leave blank to use the channel's icon." msgstr "" @@ -2241,7 +2368,7 @@ msgstr "" #: src/components/channel_config/ImportedLibrarySeletor.tsx:102 #: src/components/channel_config/ImportedLibrarySeletor.tsx:104 -#: src/hooks/useNavItems.tsx:69 +#: src/hooks/useNavItems.tsx:70 #: src/hooks/useRouteName.ts:95 #: src/pages/library/LibraryIndexPage.tsx:12 msgid "Library" @@ -2252,7 +2379,7 @@ msgid "Library Clip (not yet implemented)" msgstr "" #. placeholder {0}: library.name -#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:36 +#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:39 msgid "Library: {0}" msgstr "" @@ -2347,7 +2474,7 @@ msgstr "" msgid "Logging" msgstr "" -#: src/hooks/useNavItems.tsx:122 +#: src/hooks/useNavItems.tsx:134 #: src/pages/system/SystemLayout.tsx:33 msgid "Logs" msgstr "" @@ -2412,6 +2539,10 @@ msgstr "" msgid "Match any of" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:395 +msgid "Match audio streams whose title contains this text (case-insensitive)" +msgstr "" + #: src/components/settings/general/BackupForm.tsx:87 #: src/components/settings/general/BackupForm.tsx:90 msgid "Max Backups" @@ -2462,8 +2593,8 @@ msgstr "" #. placeholder {0}: library.mediaSource.name #. placeholder {0}: mediaSource.name -#: src/routes/media_sources_/$mediaSourceId/index.tsx:35 -#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:33 +#: src/routes/media_sources_/$mediaSourceId/index.tsx:36 +#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:34 msgid "Media Source: \"{0}\"" msgstr "" @@ -2515,6 +2646,18 @@ msgstr "" msgid "Month" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:367 +msgid "Most channels (e.g. 7.1 surround)" +msgstr "" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:153 +msgid "Move down" +msgstr "" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:142 +msgid "Move up" +msgstr "" + #: src/components/channel_config/SelectedProgrammingList.tsx:76 #: src/hooks/slot_scheduler/useSlotName.ts:13 msgid "Movie" @@ -2566,6 +2709,7 @@ msgstr "" #: src/components/custom-shows/EditCustomShowForm.tsx:270 #: src/components/filler/EditFillerListForm.tsx:137 #: src/components/MediaSourceLibraryTable.tsx:264 +#: src/components/profiles/StreamSelectionProfilesTable.tsx:68 #: src/components/settings/ConnectMediaSources.tsx:44 #: src/components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx:95 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:93 @@ -2600,6 +2744,7 @@ msgstr "" msgid "never" msgstr "" +#: src/components/profiles/StreamSelectionProfilesTable.tsx:145 #: src/components/settings/ffmpeg/TranscodeConfigsTable.tsx:167 #: src/hooks/useRouteName.ts:51 #: src/hooks/useRouteName.ts:113 @@ -2639,6 +2784,14 @@ msgstr "" msgid "New Plex Server" msgstr "" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:230 +msgid "New Profile" +msgstr "" + +#: src/pages/profiles/StreamSelectionProfilePage.tsx:236 +msgid "New Stream Selection Profile" +msgstr "" + #: src/pages/welcome/WelcomePage.tsx:242 msgid "Next" msgstr "" @@ -2656,6 +2809,10 @@ msgstr "" msgid "No active sessions" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:124 +msgid "No condition" +msgstr "" + #: src/pages/welcome/WelcomePage.tsx:142 msgid "No media sources connected." msgstr "" @@ -2664,6 +2821,10 @@ msgstr "" msgid "No Media Sources detected." msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:364 +msgid "No preference" +msgstr "" + #: src/components/channel_config/ChannelLineupList.tsx:500 msgid "No programming added yet" msgstr "" @@ -2695,6 +2856,10 @@ msgstr "" msgid "None" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:476 +msgid "None (no filter)" +msgstr "" + #: src/components/programming_controls/ShuffleProgrammingModal.tsx:64 msgid "None:" msgstr "" @@ -2713,11 +2878,15 @@ msgstr "" msgid "Not a valid URL" msgstr "" +#: src/components/profiles/StreamSelectionProfilesTable.tsx:86 +msgid "Not assigned" +msgstr "" + #: src/routes/__root.tsx:68 msgid "Not found!" msgstr "" -#: src/components/channels/ChannelNowPlayingCard.tsx:212 +#: src/components/channels/ChannelNowPlayingCard.tsx:244 msgid "Now Playing:" msgstr "" @@ -2773,6 +2942,10 @@ msgstr "" msgid "Operator" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:188 +msgid "Optional friendly name for this rule" +msgstr "" + #: src/components/channels/ChannelOptionsButton.tsx:58 msgid "Options" msgstr "" @@ -2939,6 +3112,19 @@ msgstr "" msgid "Pre" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:356 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:361 +msgid "Prefer Channel Count" +msgstr "" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:343 +msgid "Preferred languages in priority order. Type a code to add custom." +msgstr "" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:451 +msgid "Preferred subtitle languages" +msgstr "" + #: src/components/slot_scheduler/RandomSlotPresetButton.tsx:48 msgid "Presets" msgstr "" @@ -2955,6 +3141,26 @@ msgstr "" msgid "Profile" msgstr "" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:155 +msgid "Profile created" +msgstr "" + +#: src/pages/profiles/StreamSelectionProfilePage.tsx:252 +msgid "Profile Name" +msgstr "" + +#: src/pages/profiles/StreamSelectionProfilePage.tsx:248 +msgid "Profile name is required" +msgstr "" + +#: src/pages/profiles/StreamSelectionProfilePage.tsx:169 +msgid "Profile saved" +msgstr "" + +#: src/hooks/useNavItems.tsx:102 +msgid "Profiles" +msgstr "" + #: src/components/ProgramSearchAutocomplete.tsx:38 #: src/components/slot_scheduler/RandomSlotTable.tsx:259 #: src/components/slot_scheduler/RedirectProgrammingForm.tsx:46 @@ -3159,6 +3365,10 @@ msgstr "" msgid "Remove Programming" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:164 +msgid "Remove rule" +msgstr "" + #: src/components/channel_config/ChannelProgrammingDeleteOptions.tsx:96 msgid "Remove..." msgstr "" @@ -3220,6 +3430,7 @@ msgstr "" #: src/components/channel_config/ChannelEditActions.tsx:80 #: src/components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx:268 +#: src/pages/profiles/StreamSelectionProfilePage.tsx:335 #: src/pages/settings/FeaturesSettingsPage.tsx:162 #: src/pages/settings/FfmpegSettingsPage.tsx:407 #: src/pages/settings/HdhrSettingsPage.tsx:142 @@ -3294,6 +3505,20 @@ msgstr "" msgid "Root" msgstr "" +#. placeholder {0}: index + 1 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:113 +msgid "Rule {0}" +msgstr "" + +#: src/components/profiles/StreamSelectionProfilesTable.tsx:72 +#: src/pages/profiles/StreamSelectionProfilePage.tsx:270 +msgid "Rules" +msgstr "" + +#: src/pages/profiles/StreamSelectionProfilePage.tsx:283 +msgid "Rules are evaluated in order. The first rule whose condition matches determines the audio and subtitle streams for playback." +msgstr "" + #: src/pages/settings/TaskSettingsPage.tsx:179 msgid "Run" msgstr "" @@ -3334,6 +3559,7 @@ msgstr "" #: src/components/smart_collections/EditSmartCollectionDialog.tsx:121 #: src/pages/channels/RandomSlotEditorPage.tsx:270 #: src/pages/channels/TimeSlotEditorPage.tsx:542 +#: src/pages/profiles/StreamSelectionProfilePage.tsx:343 #: src/pages/settings/FeaturesSettingsPage.tsx:170 #: src/pages/settings/FfmpegSettingsPage.tsx:417 #: src/pages/settings/HdhrSettingsPage.tsx:152 @@ -3392,11 +3618,11 @@ msgstr "" msgid "Search for shows" msgstr "" -#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:38 +#: src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx:42 msgid "Search is currently scoped to this Media Source Library." msgstr "" -#: src/routes/media_sources_/$mediaSourceId/index.tsx:39 +#: src/routes/media_sources_/$mediaSourceId/index.tsx:41 msgid "Search is currently scoped to this Media Source." msgstr "" @@ -3484,7 +3710,7 @@ msgid "Sets the number of threads used to decode the input stream. Set to 0 to l msgstr "" #: src/components/slot_scheduler/RandomSlotSettingsForm.tsx:83 -#: src/hooks/useNavItems.tsx:129 +#: src/hooks/useNavItems.tsx:141 #: src/pages/channels/TimeSlotEditorPage.tsx:313 #: src/pages/settings/SettingsLayout.tsx:16 msgid "Settings" @@ -3587,7 +3813,7 @@ msgstr "" msgid "Smart Collection: {0}" msgstr "" -#: src/hooks/useNavItems.tsx:79 +#: src/hooks/useNavItems.tsx:80 #: src/hooks/useRouteName.ts:117 #: src/routes/library/smart_collections/index.tsx:20 msgid "Smart Collections" @@ -3647,7 +3873,7 @@ msgstr "" msgid "Source Type" msgstr "" -#: src/hooks/useNavItems.tsx:96 +#: src/hooks/useNavItems.tsx:97 msgid "Sources" msgstr "" @@ -3665,11 +3891,11 @@ msgstr "" msgid "Start Time" msgstr "" -#: src/components/channels/ChannelNowPlayingCard.tsx:219 +#: src/components/channels/ChannelNowPlayingCard.tsx:251 msgid "Started {startedAgo} - {remainingTime}remaining" msgstr "" -#: src/hooks/useNavItems.tsx:112 +#: src/hooks/useNavItems.tsx:124 #: src/pages/system/SystemLayout.tsx:31 msgid "Status" msgstr "" @@ -3698,10 +3924,20 @@ msgstr "" msgid "Stream Mode" msgstr "" +#: src/hooks/useNavItems.tsx:107 #: src/pages/system/TroubleshootPage.tsx:725 msgid "Stream Selection" msgstr "" +#: src/pages/profiles/StreamSelectionProfilePage.tsx:227 +#: src/pages/profiles/StreamSelectionProfilesPage.tsx:9 +msgid "Stream Selection Profiles" +msgstr "" + +#: src/pages/profiles/StreamSelectionProfilesPage.tsx:13 +msgid "Stream selection profiles control which audio and subtitle streams are selected during transcoding. Assign profiles to channels, filler lists, or individual programs." +msgstr "" + #: src/components/channel_config/EditChannelForm.tsx:248 msgid "Streaming" msgstr "" @@ -3714,10 +3950,23 @@ msgstr "" msgid "Submitting..." msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:133 +msgid "Subs: {subtitleSummary}" +msgstr "" + #: src/pages/system/TroubleshootPage.tsx:757 msgid "Subtitle Action" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:259 +msgid "Subtitle Selection" +msgstr "" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:268 +#: src/components/profiles/StreamSelectionRuleEditor.tsx:270 +msgid "Subtitle Strategy" +msgstr "" + #: src/pages/system/TroubleshootPage.tsx:669 msgid "Subtitle Streams" msgstr "" @@ -3764,7 +4013,7 @@ msgid "Synced with external playlist" msgstr "" #: src/components/settings/DarkModeButton.tsx:47 -#: src/hooks/useNavItems.tsx:101 +#: src/hooks/useNavItems.tsx:113 #: src/pages/system/SystemLayout.tsx:17 msgid "System" msgstr "" @@ -3799,7 +4048,7 @@ msgstr "" msgid "Temporarily caches responses from Plex based by request path. Could potentially speed up channel editing." msgstr "" -#: src/routes/channels_/test.tsx:5 +#: src/routes/channels_/test.tsx:7 msgid "Test" msgstr "" @@ -3986,6 +4235,14 @@ msgstr "" msgid "Title" msgstr "" +#: src/components/profiles/StreamSelectionRuleEditor.tsx:392 +msgid "Title Contains" +msgstr "" + +#: src/components/profiles/StreamSelectionRuleEditor.tsx:387 +msgid "Title filter is required" +msgstr "" + #: src/components/programming_controls/AddRestrictHoursModal.tsx:120 msgid "TO" msgstr "" @@ -4051,7 +4308,7 @@ msgstr "" msgid "Transcoding Settings" msgstr "" -#: src/hooks/useNavItems.tsx:89 +#: src/hooks/useNavItems.tsx:90 #: src/hooks/useRouteName.ts:129 #: src/pages/library/TrashPage.tsx:100 msgid "Trash" @@ -4144,6 +4401,10 @@ msgstr "" msgid "Use these settings to override global ffmpeg settings for this channel." msgstr "" +#: src/components/profiles/StreamSelectionProfilesTable.tsx:77 +msgid "Used By" +msgstr "" + #: src/components/settings/media_source/EmbyServerEditDialog.tsx:349 #: src/components/settings/media_source/JelllyfinServerEditDialog.tsx:374 msgid "Username" @@ -4223,7 +4484,7 @@ msgstr "" #. placeholder {0}: capitalize(firstProgram.program.sourceType) #. placeholder {0}: capitalize(program.sourceType) -#: src/components/channels/ChannelNowPlayingCard.tsx:245 +#: src/components/channels/ChannelNowPlayingCard.tsx:277 #: src/components/ProgramMetadataDialogContent.tsx:144 msgid "View in {0}" msgstr "" @@ -4280,7 +4541,7 @@ msgstr "" msgid "Weighting" msgstr "" -#: src/hooks/useNavItems.tsx:56 +#: src/hooks/useNavItems.tsx:57 msgid "Welcome" msgstr "" diff --git a/web/src/locales/pseudo-LOCALE/messages.ts b/web/src/locales/pseudo-LOCALE/messages.ts index f89208bf2..e310cb396 100644 --- a/web/src/locales/pseudo-LOCALE/messages.ts +++ b/web/src/locales/pseudo-LOCALE/messages.ts @@ -1,4 +1,4 @@ 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":["À-Ź (ďēść)"],"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ēĺś"]}', + '{"++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":["Ćōńĝŕàţś, ŷōũ\'ŕē ŕēàďŷ ţō śţàŕţ ƀũĩĺďĩńĝ ćĥàńńēĺś! ĵũśţ ćĺĩćķ Ƒĩńĩśĥ ƀēĺōŵ ţō śţàŕţ ŵōŕķĩńĝ ōń ŷōũŕ ƒĩŕśţ ćĥàńńēĺ."],"/JQh8n":["Ḿàţćĥ àũďĩō śţŕēàḿś ŵĥōśē ţĩţĺē ćōńţàĩńś ţĥĩś ţēxţ (ćàśē-ĩńśēńśĩţĩvē)"],"/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":["Àĺƥĥàƀēţĩćàĺ"],"3Ib6FN":["Ḿōvē ďōŵń"],"3JIYke":["Ĥēàĺţĥŷ?"],"3JQkm5":["Ƥàţĥ Ŕēƥĺàćēḿēńţś"],"3JjdaA":["Ŕũń"],"3LfNqe":["Ćĥàńńēĺ Ńũḿƀēŕ"],"3SH6Vv":["Ćōƥĩēď ćĥàńńēĺ \\"",["channelName"],"\\" ḿ3ũ ĺĩńķ ţō ćĺĩƥƀōàŕď"],"3T+8r+":["Ƒōŕćēď ōńĺŷ"],"3YNjnA":["Śŷśţēḿ Ēńvĩŕōńḿēńţ"],"3b1vGb":["Ńēŵ Ĺōćàĺ Ḿēďĩà Śōũŕćē"],"3mAQJI":["Ĥōŵ ōƒţēń ţĥē XḾĹŢV ƒĩĺē ĩś ŕēĝēńēŕàţēď"],"3nLdaX":["Àďď ",["0"]],"3nwcC5":["Ƒĩĺĺēŕ - ",["0"]],"49dCCB":["Ũśē Śĥōŵ Ƥōśţēŕ"],"4EZrJN":["Ŕũĺēś"],"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ēď ţō ţĥē ƀōţţōḿ."],"5oyVZS":["Ƥŕēƒēŕ Ćĥàńńēĺ Ćōũńţ"],"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ĩćē"],"7739L7":["Śţŕēàḿ Śēĺēćţĩōń Ƥŕōƒĩĺēś"],"7B3lfh":["Ĩţēḿś ƒŕōḿ àńŷ ƒĩĺĺēŕ ĺĩśţ ŵĩĺĺ ńōţ ƀē ćĥōśēń ḿōŕē ƒŕēǫũēńţĺŷ ţĥàń ţĥĩś ćōōĺďōŵń śēţţĩńĝ."],"7BAOFm":["Ńōţ àśśĩĝńēď"],"7LWPgS":["Ēńàƀĺēď (ĺōũďńōŕḿ)"],"7ODkf5":["Ĺōĝ ĺēvēĺ ţō ƥàśś ţō ƒƒḿƥēĝ. Ŕēàď ḿōŕē àƀōũţ ƒƒḿƥēĝ\'ś ĺōĝ ĺēvēĺś <0>ĥēŕē"],"7Q5AKf":[["count","plural",{"one":["ţŕàćķ"],"other":["ţŕàćķś"]}]],"7b2stB":["Ḿēďĩà Ţŷƥē"],"7eMo+U":["Ĝō Ĥōḿē"],"7eZlTH":["Śōŕţ ŢV Śĥōŵś (àść)"],"7fLSqD":[["0"]," ćĥàńńēĺ(ś)"],"7iJlKU":["Ƥĺēàśē ćĥōōśē à vàĺũē ĝŕēàţēŕ ţĥàń 1"],"7pMNGK":["Ƥŕōĝŕàḿś śàvēď!"],"7sNhEz":["Ũśēŕńàḿē"],"7tvV2B":["Ḿĩń Ďũŕàţĩōń (ḿĩńũţēś)"],"7uohY3":["ŢV śĥōŵś àŕē ĝŕōũƥēď ƀŷ śĥōŵ"],"80t7Ii":["Ĩńćŕēàśĩńĝ \\"Ḿàx Ĺàţēńēśś\\" ƒōŕ ţĥē śćĥēďũĺē."],"87a/t/":["Ĺàƀēĺ"],"8Ch9cS":["Ńō ƥŕēƒēŕēńćē"],"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":["Ćōďēć"],"BigE6r":["Àũďĩō Śţŕàţēĝŷ"],"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":["Ďēśćēńďĩńĝ"],"ClUxys":["Ōƥţĩōńàĺ ƒŕĩēńďĺŷ ńàḿē ƒōŕ ţĥĩś ŕũĺē"],"Cp5Awv":["Ďũŕàţĩōń ḿũśţ ƀē ĝŕēàţēŕ ţĥàń 0."],"CqSP2T":["Ēďĩţ Ćĥàńńēĺ Ŕēďĩŕēćţ"],"CsrDsg":["12-ĥōũŕ"],"Cxqf0C":["Ƥĺēx (Àũţō)"],"D+NlUC":["Śŷśţēḿ"],"D1Fhv3":[["count","plural",{"one":["ēƥĩśōďē"],"other":["ēƥĩśōďēś"]}]],"D5IOoq":["Ţĩţĺē ƒĩĺţēŕ ĩś ŕēǫũĩŕēď"],"DDR4V1":["Ƥŕēƒēŕŕēď ĺàńĝũàĝēś ĩń ƥŕĩōŕĩţŷ ōŕďēŕ. Ţŷƥē à ćōďē ţō àďď ćũśţōḿ."],"DPfwMq":["Ďōńē"],"DRya1t":["Àũďĩō Vōĺũḿē"],"DSwJ9W":["Ēńàƀĺē Àńĩḿàţĩōń"],"DUd3Ss":["Śōŕţś ţĥē ĺĩśţ ƀŷ ŢV Śĥōŵ àńď ţĥē ēƥĩśōďēś ĩń ēàćĥ ŢV śĥōŵ ƀŷ ţĥēĩŕ śēàśōń/ēƥĩśōďē ńũḿƀēŕ. Ḿōvĩēś àŕē ḿōvēď ţō ţĥē ƀōţţōḿ ōƒ ţĥē śćĥēďũĺē."],"DbouLP":["ßàćķ ţō Ƥŕōĝŕàḿḿĩńĝ"],"Dd9orS":["Ŕēḿōvē Àĺĺ ",["movieCount"]," ",["movieCount","plural",{"one":["Ḿōvĩē"],"other":["Ḿōvĩēś"]}]],"Dnn2XG":["Àũţōḿàţĩć"],"DoJzLz":["Ćōĺĺēćţĩōńś"],"DrfvUu":["Àĺĺōŵ ĩḿàĝē-ƀàśēď śũƀţĩţĺēś"],"DxvGLB":["Àďď Śĺōţ"],"E/QGRL":["Ďĩśàƀĺēď"],"E5ipHC":["ßàĺàńćē ßŷ:"],"E8KFsc":["Àũďĩō: ",["audioSummary"]],"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ēćũţàƀĺē Ƥàţĥ"],"FY1Ztd":["Ĩńvàĺĩď ēxƥŕēśśĩōń"],"FZg3wM":["Ōƥēŕàţĩōń"],"FmN5me":["Ŕēśōĺũţĩōń"],"FnChN1":["Ēńàƀĺē <0>ĒßŨ Ŕ 128 ĺōũďńēśś ńōŕḿàĺĩźàţĩōń vĩà ţĥē <1>ĺōũďńōŕḿ ƑƑḿƥēĝ ƒĩĺţēŕ. Ḿàŷ ĩńćŕēàśē ĆƤŨ ũśàĝē ďũŕĩńĝ śţŕēàḿĩńĝ."],"Fp7p73":["Ţĩḿē ƀēţŵēēń śũƀśēǫũēńţ ƀŕēàķś"],"FqCHF/":["Ţĥŕēàďś"],"FrRP21":["Ţĥēŕē ŵàś àń ēŕŕōŕ ŵĥēń śũƀḿĩţţĩńĝ ţĥē ƒōŕḿ. Ƥĺēàśē śēē ćōńśōĺē ĺōĝś ƒōŕ ďēţàĩĺś."],"FsF4bb":["Àũďĩō Ĺōũďńēśś Ńōŕḿàĺĩźàţĩōń"],"FssFce":["Ćōńƒĩĝũŕē ƥŕēƒēŕŕēď àũďĩō ĺàńĝũàĝēś ĝĺōƀàĺĺŷ."],"Fzn/BQ":["Ŕēĺēàśē Ďàţē"],"G+8qH5":["Ćĥàńńēĺ ńàḿē ĩś ŕēǫũĩŕēď"],"GAmD3h":["Ĺàńĝũàĝēś"],"GDKKxT":["Àććēśś Ţōķēń"],"GHOK4Z":["Ţĩḿē Ƒōŕḿàţ"],"GJ1P5j":["Ƒĩĺē à ßũĝ Ŕēƥōŕţ"],"GKLqtE":["Śēţ ţĥē ĥōśţ ōƒ ŷōũŕ Ţũńàŕŕ ƀàćķēńď. Ŵĥēń ēḿƥţŷ, ţĥē ŵēƀ ŨĨ ŵĩĺĺ ũśē ţĥē ćũŕŕēńţ ĥōśţ/ƥōŕţ ţō ćōḿḿũńĩćàţē ŵĩţĥ ţĥē ƀàćķēńď."],"GLOZdc":["Ćũśţōḿ Śĥōŵś"],"GP/CFo":["ĤŴ Àććēĺ"],"GQ3O42":["Ţŕàśĥ"],"GRCrpV":["Ḿàńàĝē Ĺĩƀŕàŕĩēś"],"GUtCZC":["Vēŕśĩōń: ",["0"]],"GhZ4GX":["Ēŕŕōŕ ŵĥĩĺē ćōƥŷĩńĝ ţō ćĺĩƥƀōàŕď. Ćĥēćķ ƀŕōŵśēŕ ĺōĝś ƒōŕ ďēţàĩĺś"],"GmP0oY":["Śĺōţ Ŵàŕńĩńĝś"],"GmTnBN":["Ēńàƀĺē ƒƒḿƥēĝ ĺōĝĝĩńĝ ţō ďĩƒƒēŕēńţ śĩńķś. Ōũţƥũţţĩńĝ ţō à ƒĩĺē ŵĩĺĺ ćŕēàţē à ńēŵ ĺōĝ ƒĩĺē ƒōŕ ēvēŕŷ śƥàŵńēď ƒƒḿƥēĝ ƥŕōćēśś ĩń ţĥē Ţũńàŕŕ ĺōĝ ďĩŕēćţōŕŷ. Ţĥēśē ƒĩĺēś àŕē àũţōḿàţĩćàĺĺŷ ćĺēàńēď ũƥ ƀŷ à ƀàćķĝŕōũńď ƥŕōćēśś."],"Gr1Ik2":["Ńvĩďĩà Ćàƥàƀĩĺĩţĩēś"],"GtycJ/":["Ţàśķś"],"GwO5g4":["Ƒàĩĺēď ţō vàĺĩďàţē ēxƥŕēśśĩōń"],"GzzMwi":["Ŕōĺĺ ōń Śćĥēďũĺē"],"H+4ZaX":["Ćōńďĩţĩōń ĩś ŕēǫũĩŕēď"],"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":["Ďĩśàƀĺē Ŵàţēŕḿàŕķś"],"KGFLpf":["Ũśēď ßŷ"],"KRjDf4":["Àũďĩō Śţŕēàḿś"],"KTtYr9":["ßŷ Ţĩţĺē"],"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 ŵĥēń ũśĩńĝ ĥàŕďŵàŕē àććēĺēàŕàţĩōń ƒōŕ śţàƀĩĺĩţŷ ŕēàśōńś."],"LCj67s":["Śũƀś: ",["subtitleSummary"]],"LKPR6G":["Ƥĺàŷĺĩśţ"],"LKSv28":["Śḿàŕţ Ćōĺĺēćţĩōńś àŕē śēĺƒ-ũƥďàţĩńĝ ćōńţēńţ ĺĩśţś. Ŷōũ śēţ ţĥē ǫũēŕŷ àńď ţĥē ćōĺĺēćţĩōń àũţōḿàţĩćàĺĺŷ àďďś àńŷ ńēŵ ćōńţēńţ ƒŕōḿ ŷōũŕ ĺĩƀŕàŕŷ ţĥàţ ƒĩţś ţĥōśē ŕũĺēś. Àńŷ ńēŵĺŷ àďďēď ćōńţēńţ ḿàţćĥĩńĝ ǫũēŕŷ ŵĩĺĺ ńōţ ḿōďĩƒŷ ēxĩśţĩńĝ ćĥàńńēĺ ƥŕōĝŕàḿḿĩńĝ àţ ţĥĩś ţĩḿē."],"LMMGPr":["Śũƀḿĩţţĩńĝ..."],"LRvqnF":["Ēŕŕōŕ śàvĩńĝ ńēŵ ĵēĺĺŷƒĩń śēŕvēŕ. Śēē ƀŕōŵśēŕ ćōńśōĺē àńď śēŕvēŕ ĺōĝś ƒōŕ ďēţàĩĺś"],"LTC198":["Ŕũńńĩńĝ..."],"LTYRAI":["Vĩēŵ Ĺĩƀŕàŕŷ"],"LiCr5o":["Ĺĩḿĩţ ḿũśţ ƀē ńũḿēŕĩć"],"MHrjPM":["Ţĩţĺē"],"MJr3i9":["Ţĩţĺē Ćōńţàĩńś"],"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":["Ēďĩţ Ţŕàńśćōďē Ćōńƒĩĝ"],"Pi0TLp":["Ďēƒàũĺţ (ƒĩŕśţ śţŕēàḿ)"],"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ēŕŷ"],"QyioBP":["Ḿōvē ũƥ"],"R+X/he":["Ƥŕōƒĩĺē Ńàḿē"],"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":["Àĺţēŕńàţē ƥŕōĝŕàḿś ĩń ƀĺōćķś. Ŷōũ ćàń ƥĩćķ ţĥē ńũḿƀēŕ ōƒ ƥŕōĝŕàḿś ƥēŕ-ţŷƥē ĩń ēàćĥ ƀĺōćķ àńď ĩƒ ţĥē ōŕďēŕ ōƒ śĥōŵś ĩń ēàćĥ ƀĺōćķ śĥōũĺď ƀē ŕàńďōḿĩźēď."],"RY3VxI":["Ńō ćōńďĩţĩōń"],"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":["Ḿĩń Ďũŕàţĩōń"],"SjxzXf":["Ŕēḿōvē ŕũĺē"],"SoRsRS":["Ćàĺćũĺàţēś à śćĥēďũĺē ŵĥēŕē àĺĺ ƥŕōĝŕàḿś ēńď àţ ţĥē śàḿē ţĩḿē, ćŕēàţĩńĝ à ƥēŕƒēćţĺŷ ĺōōƥĩńĝ śćĥēďũĺē."],"SuubHr":["Ďēĺēţĩńĝ à Ƥĺēx śēŕvēŕ ŵĩĺĺ ŕēḿōvē àĺĺ ƥŕōĝŕàḿḿĩńĝ ƒŕōḿ ŷōũŕ ćĥàńńēĺś àśśōćĩàţēď ŵĩţĥ ţĥĩś ƥĺēx śēŕvēŕ. Ḿĩśśĩńĝ ƥŕōĝŕàḿḿĩńĝ ŵĩĺĺ ƀē ŕēƥĺàćēď ŵĩţĥ Ƒĺēx ţĩḿē. Ţĥĩś àćţĩōń ćàńńōţ ƀē ũńďōńē."],"SywaS+":["Ďàţà Ďĩŕēćţōŕŷ:"],"SzNZRr":["Śũƀţĩţĺē Śēĺēćţĩōń"],"T5wfux":["Ḿàķēś ḿũĺţĩƥĺē ćōƥĩēś ōƒ ţĥē śćĥēďũĺē àńď ƥĺàŷś ţĥēḿ ĩń śēǫũēńćē"],"T8drou":["Śŷśţēḿ Ĥēàĺţĥ"],"TEM0vH":["Ŕēḿōvēś àĺĺ ƥŕōĝŕàḿś ƒŕōḿ ćũśţōḿ śĥōŵ"],"TMADKS":["Ďĩvĩďēś ţĥē ƥŕōĝŕàḿḿĩńĝ ĩń ƀĺōćķś ōƒ 4, 6, 8 ōŕ 12 ĥōũŕś ţĥēń ŕēƥēàţś ēàćĥ ōƒ ţĥē ƀĺōćķś ţĥē śƥēćĩƒĩēď ńũḿƀēŕ ōƒ ţĩḿēś."],"TMju4P":["Ďēĺēţē Ḿēďĩà Śōũŕćē \\"",["0"],"\\"?"],"TS0lwx":["Ēńćōũńţēŕēď àń ēŕŕōŕ ŵĥēń ēḿƥţŷĩńĝ ţŕàśĥ. Ćĥēćķ ćōńśōĺē ĺōĝś ƒōŕ ďēţàĩĺś."],"TZKpsF":["Ńō Ḿēďĩà Śōũŕćēś ďēţēćţēď."],"TkzAPg":["Ƥŕōƒĩĺē ńàḿē ĩś ŕēǫũĩŕēď"],"TpqW74":["Ƒĩxēď"],"Ts6Zfm":["Ēŕŕōŕ ũƥďàţĩńĝ Śḿàŕţ Ćōĺĺēćţĩōń. Ćĥēćķ ĺōĝś ƒōŕ ďēţàĩĺś."],"Ts8Q+i":["ĒƤĜ"],"TvY/XA":["Ďōćũḿēńţàţĩōń"],"Tz0i8g":["Śēţţĩńĝś"],"TzyoiK":["Ŵĥēń ēńàƀĺĩńĝ, Ţũńàŕŕ ŵĩĺĺ ĝēńēŕàţē àń ĩńĩţĩàĺ ƀàćķũƥ ĩḿḿēďĩàţēĺŷ"],"U0sC6H":["Ďàĩĺŷ"],"U3+jR/":["Ŕēƥĺĩćàţē Ƥŕōĝŕàḿś"],"UC1lMc":["Ƒàĩĺēď ţō śàvē ƒēàţũŕē ƒĺàĝś."],"UDaVJs":[["0"]," ƥŕōĝŕàḿ(ś)"],"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"]," Ĥōũŕś"],"WxMod2":["Ēďĩţ Śţŕēàḿ Śēĺēćţĩōń Ƥŕōƒĩĺē"],"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":["Ćĥàńńēĺ Ĝŕōũƥ"],"XoYeBe":["Ƥŕēƒēŕŕēď śũƀţĩţĺē ĺàńĝũàĝēś"],"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":["Ţĥē ĩḿàĝē ŵĩĺĺ ƀē ŕēńďēŕēď àţ ĩţś àćţũàĺ śĩźē ŵĩţĥōũţ àńŷ śćàĺĩńĝ àƥƥĺĩēď."],"Zm5ZtK":["Àĺĺ ćĥàńńēĺś, ƒĩĺĺēŕś, àńď ƥŕōĝŕàḿś ũśĩńĝ ţĥĩś ƥŕōƒĩĺē ŵĩĺĺ ĥàvē ţĥēĩŕ śţŕēàḿ śēĺēćţĩōń ŕēśēţ ţō ďēƒàũĺţś."],"Zs2GWW":["Ńēŵ Ēḿƀŷ Ḿēďĩà Śōũŕćē"],"Zul8Ry":["ńēvēŕ"],"Zvipe1":["Ēďĩţĩńĝ Ƥĺēx Śēŕvēŕ \\"",["0"],"\\""],"ZxwuFV":["Ďēĺēţĩńĝ à Ćĥàńńēĺ ŵĩĺĺ ŕēḿōvē àĺĺ ƥŕōĝŕàḿḿĩńĝ ƒŕōḿ ţĥē ćĥàńńēĺ. Ţĥĩś àćţĩōń ćàńńōţ ƀē ũńďōńē."],"a+Pr3s":["Àƥƥĺŷ ţō Ƥŕōĝŕàḿ Ţŷƥēś (ēḿƥţŷ = àĺĺ)"],"a4N/Bg":["Ĺōàď Ḿōŕē"],"aE3UMm":["<0>Ńōńē: śĺōţś àŕē ƥĩćķēď ĩń ţĥē ōŕďēŕ ţĥēŷ àŕē śƥēćĩƒĩēď ĩń ţĥē ţàƀĺē (ĩ.ē. ńōţ ŕàńďōḿĺŷ)<1/><2>Ũńĩƒōŕḿ: àĺĺ śĺōţś ĥàvē àń ēǫũàĺ ćĥàńćē ţō ƀē ƥĩćķēď.<3/><4>Ŵēĩĝĥţēď: ēàćĥ śĺōţ ĩś ƥĩćķēď ŵĩţĥ à śƥēćĩƒĩēď ƥŕōƀàƀĩĺĩţŷ"],"aOaCIk":["Àĺĺōŵ Ēxţēŕńàĺ"],"aOnWmo":["Ŕũĺēś àŕē ēvàĺũàţēď ĩń ōŕďēŕ. Ţĥē ƒĩŕśţ ŕũĺē ŵĥōśē ćōńďĩţĩōń ḿàţćĥēś ďēţēŕḿĩńēś ţĥē àũďĩō àńď śũƀţĩţĺē śţŕēàḿś ƒōŕ ƥĺàŷƀàćķ."],"aScBGS":["Àďď à ƒĩĺţēŕ ēxƥŕēśśĩōń ţō ƒĩńē-ţũńē ŕēśũĺţś ōƒ ţĥē śēàŕćĥ"],"aSwfbR":["Ũńĩţ"],"ad9wBQ":["Ńēŵ Ƥŕōƒĩĺē"],"ak3N0i":["Ĩţēḿ ŵàś ńōţ ƥŕēśēńţ ďũŕĩńĝ ţĥē ĺàśţ śćàń"],"aoLy25":["Ōƥàćĩţŷ"],"b0Uv6P":[["0","plural",{"one":["Ƥàţĥ"],"other":["Ƥàţĥś"]}]],"b6sx4K":["Ńō àćţĩvē śēśśĩōńś"],"bDY29m":["Ĺōĝàŕĩţĥḿĩć"],"bGG6B1":["ĵēĺĺŷƒĩń"],"bHNlfr":["Ĩńćŕēàśĩńĝ ţĥē śĺōţ ďũŕàţĩōń."],"bNEQeI":["Ćōōĺďōŵń"],"bORfbY":["Ćàńńōţ ũśē à ćĥàńńēĺ ńũḿƀēŕ <= 0"],"bPJiZF":["Śĥōŵ: ",["0"]],"bSIBDb":["Ŕēĺēàśē Ďàţē (àść)"],"bm8pgG":["Àďď ĝŕōũƥ"],"bmQLn5":["Àďď Ŕũĺē"],"boItSp":["Ďēĺēţē Ḿēďĩà Śōũŕćē?"],"buS8nL":["Ēńàƀĺē Śũƀţĩţĺēś"],"bxyuno":["Ōvēŕŕĩďē ĝĺōƀàĺ àũďĩō àńď śũƀţĩţĺē śēţţĩńĝś ƒōŕ ţĥĩś ćĥàńńēĺ."],"bydide":["ƑƑḾƤĒĜ Ĺōĝ Ḿēţĥōď"],"c1f0Qv":["Ďēĺēţē Ƥŕōƒĩĺē \\"",["0"],"\\"?"],"c6fsNw":["Ŵĥēń ēńàƀĺēď, ĩńţēŕḿĩţţēńţ ŵàţēŕḿàŕķś ƒàďē ĩń ĩḿḿēďĩàţēĺŷ ŵĥēń à śţŕēàḿ ĩś ĩńĩţĩàĺĩźēď. Ŵĥēń ďĩśàƀĺēď, ţĥē ƒĩŕśţ ŵàţēŕḿàŕķ ƒàďē-ĩń ōććũŕś àƒţēŕ à ƒũĺĺ ƥēŕĩōď."],"cF5KzV":["Ēďĩţ Ƒĩĺĺēŕ Ĺĩśţ"],"cFTdM+":["Ćōńśōĺē"],"cHYx4E":["Ēḿƥţŷ Ţŕàśĥ"],"cLgGtf":["Ŕēśēţ ƥŕōĝŕàḿḿĩńĝ ţō ḿōśţ ŕēćēńţĺŷ śàvēď śţàţē"],"cN5Dty":["Ńō Ƥŕōĝŕàḿḿĩńĝ śćĥēďũĺēď"],"cOvZFM":["Ďŷńàḿĩć"],"cXkSYc":["Ţĥēŕē ŵàś àń ēŕŕōŕ śũƀḿĩţţĩńĝ ţĥē ŕēǫũēśţ ţō ũƥďàţē Ḿēďĩà Śōũŕćē śēţţĩńĝś. Ƥĺēàśē ćĥēćķ ţĥē ƒōŕḿ àńď ţŕŷ àĝàĩń"],"caSM6R":["Ţĥĩś ĩś ũśēď ƀŷ ĩƥţv ćĺĩēńţś ţō ćàţēĝōŕĩźē ţĥē ćĥàńńēĺś. Ŷōũ ćàń ĺēàvē ĩţ àś \'ţũńàŕŕ\' ĩƒ ŷōũ ďōń\'ţ ńēēď ţĥĩś śōŕţ ōƒ ćĺàśśĩƒĩćàţĩōń."],"ccH5/A":["Ćŕēàţē Ƥŕōƒĩĺē"],"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":["Àũďĩō Ćĥàńńēĺś"],"eauqYh":["Śţŕēàḿ śēĺēćţĩōń ƥŕōƒĩĺēś ćōńţŕōĺ ŵĥĩćĥ àũďĩō àńď śũƀţĩţĺē śţŕēàḿś àŕē śēĺēćţēď ďũŕĩńĝ ţŕàńśćōďĩńĝ. Àśśĩĝń ƥŕōƒĩĺēś ţō ćĥàńńēĺś, ƒĩĺĺēŕ ĺĩśţś, ōŕ ĩńďĩvĩďũàĺ ƥŕōĝŕàḿś."],"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":["Ēŕŕōŕ Àũďĩō"],"gVcD5M":["ĆĒĹ ēxƥŕēśśĩōń. Ũśē \\"ţŕũē\\" ţō àĺŵàŷś ḿàţćĥ."],"gcD6jw":["Ĥĩďē ŵàţēŕḿàŕķ ďũŕĩńĝ ƒĩĺĺēŕ"],"gf/bM4":["Ćōńţĩńũē ŵĩţĥ Ńēŵ Ćōńţēńţ"],"gg9/ya":["Ŕēḿōvē ",["count"]," ",["0"]],"ghGSuE":["Ēńśũŕēś ƥŕōĝŕàḿś ĥàvē à ńĩćē-ĺōōķĩńĝ śţàŕţ ţĩḿē, ĩţ ŵĩĺĺ àďď Ƒĺēx ţĩḿē ţō ƒĩĺĺ ţĥē ĝàƥś."],"glVpbE":["Ēàĝēŕ"],"gpwdq7":[["0"]," ƒĩĺĺēŕ(ś)"],"h/qU8b":["Ōvēŕŕĩďē ţĥē ďēƒàũĺţ ",["0"]," ďēvĩćē ƥàţĥ (ďēƒàũĺţś ţō <0>/ďēv/ďŕĩ/ŕēńďēŕĎ128 ōń Ĺĩńũx àńď ƀĺàńķ ōţĥēŕŵĩśē)"],"h4yKYk":["Ńēxţ ŕũń"],"h8WhoR":["Śĺōţ Śćĥēďũĺēŕ"],"hBGuBW":["Ũśē ćĥàńńēĺ ďēƒàũĺţ"],"hBzeL7":["Ţĩḿē ƀēƒōŕē ƒĩŕśţ ƀŕēàķ"],"hG89Ed":["Ĩḿàĝē"],"hISVAG":["Ḿēďĩà Śōũŕćēś àŕē ŵĥēŕē Ţũńàŕŕ śōũŕćēś ŷōũŕ ćōńţēńţ. Ḿēďĩà ćàń ćōḿē ƒŕōḿ ŷōũŕ ƒĩĺēśŷśţēḿ ōŕ à ŕēḿōţē śēŕvēŕ, ĺĩķē Ƥĺēx ōŕ ĵēĺĺŷƒĩń. Àţ ĺēàśţ ōńē Ḿēďĩà Śōũŕćē ĩś ńēćēśśàŕŷ ţō ćŕēàţē ćĥàńńēĺś àńď ƥĺàŷ ḿēďĩà ĩń Ţũńàŕŕ."],"hQRttt":["Śũƀḿĩţ"],"hQSabA":["ŢŌ"],"hV0YJc":["Àţ ĺēàśţ ōńē ĺàńĝũàĝē ĩś ŕēǫũĩŕēď"],"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":["ßàćķ"],"iLVyZt":["Ḿōśţ ćĥàńńēĺś (ē.ĝ. 7.1 śũŕŕōũńď)"],"iQWhqk":["ƑƑḾƤĒĜ ĩś ĩńśţàĺĺēď. Ďēţēćţēď vēŕśĩōń ",["0"]],"iTjV+L":["À-Ź (ďēść)"],"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":["Ŕũń Ţŕōũƀĺēśĥōōţēŕ"],"lnr2QQ":["Ĺēàśţ ćĥàńńēĺś (ē.ĝ. śţēŕēō)"],"lu2qW5":["Àńŷ"],"m+8qnB":["Ĺĩƀŕàŕŷ: ",["0"]],"m+9pF8":["ßŷ Ĺàńĝũàĝē"],"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ēŕ ďĩƒƒēŕ ƒŕōḿ ţĥē ƥàţĥś Ţũńàŕŕ ćàń śēē, ũśē Ƥàţĥ Ŕēƥĺàćēḿēńţś ţō ĩńśţŕũćţ Ţũńàŕŕ ĥōŵ ţō śţŕēàḿ ḿēďĩà ƒŕōḿ ďĩśķ."],"n4EJAA":["Śũƀţĩţĺē Śţŕàţēĝŷ"],"n9nSNJ":["Ţĩḿē ƒōŕḿàţ"],"nH6YaM":["Ōţĥēŕ Vĩďēōś"],"nSW2Lv":[["days","plural",{"one":["#"," ďàŷ"],"other":["#"," ďàŷś"]}]],"nV6twc":["Ōŕĝàńĩźē"],"nYD/Cq":["Àśćēńďĩńĝ"],"nZXc7r":["Ũńĺĩńķ ƒŕōḿ ĝŕōũƥ"],"nfAddt":["ƑƑḿƥēĝ Ţŕàńśćōďē Ƥàţĥ"],"nfxRnc":["Ţũńàŕŕ ĩś ćũŕŕēńţĺŷ ćōńƒĩĝũŕēď ţō ũśē ţĥē ÀĆ3 àũďĩō ēńćōďēŕ. Ţĥĩś àũďĩō ƒōŕḿàţ ĩś ńōţ śũƥƥōŕţēď ƀŷ ƀŕōŵśēŕś. Ţĥē ŕēśũĺţàńţ śţŕēàḿ ŵĩĺĺ ĺĩķēĺŷ ńōţ ĥàvē àũďĩō ōŕ ŵĩĺĺ ńōţ ƥĺàŷ àţ àĺĺ."],"njIcYs":["Śàvē àś ńēŵ ćōĺĺēćţĩōń…"],"ntJ9rt":["ĤĹŚ Ďĩŕēćţ Ōũţƥũţ Ƒōŕḿàţ"],"nyS8Ib":["Àũďĩō Śēĺēćţĩōń"],"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":["Ńũḿƀēŕ ōƒ Ŕēƥĺĩćàţĩōńś"],"op6W0V":["Àĺĺōŵ ēxţēŕńàĺ śũƀţĩţĺēś"],"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ēŕ"],"r6Yf/m":["Ńēŵ Śţŕēàḿ Śēĺēćţĩōń Ƥŕōƒĩĺē"],"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":["Àũďĩō Ƒōŕḿàţ"],"snAR/S":["Ńōńē (ńō ƒĩĺţēŕ)"],"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ƥŕēśśĩōńś."],"vq2FYw":["Ŕũĺē ",["0"]],"vrQQgz":["Ƥŕōƒĩĺēś"],"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 Ţŕũē Ƥēàķ"],"wTXT7g":["Ďēƒàũĺţ ōńĺŷ"],"wYqXX9":["Ƥŕōƒĩĺē śàvēď"],"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":["Ƒōŕćē Śćàń"],"zXeOax":["Ƥŕōƒĩĺē ćŕēàţēď"],"zpylsE":["Ţŕàńśćōďĩńĝ Śēţţĩńĝś"],"zrmjn/":["Ḿàx Ďũŕàţĩōń"],"zthKEs":["Ţĥē śţŕēàḿĩńĝ ḿōďē àƒƒēćţś ţĥē ţŷƥē ōƒ ũńďēŕĺŷĩńĝ ţŕàńśćōďĩńĝ ƥŕōćēśś ũśēď ţō ćŕēàţē ţĥē ćĥàńńēĺ\'ś vĩďēō śţŕēàḿ.<0/>Ĺēàŕń ḿōŕē àƀōũţ Ţũńàŕŕ\'ś śţŕēàḿ ḿōďēś <1>ĥēŕē!"],"zvjEp6":["Ƒĩĺĺēŕ ćōōĺďōŵń ḿũśţ ƀē à ńũḿƀēŕ"],"zx4BuL":["Ŵēēķ"],"zyLvkd":["Ćàţēĝōŕŷ Ĺōĝ Ĺēvēĺś"]}', ) as Messages; diff --git a/web/src/pages/profiles/StreamSelectionProfilePage.tsx b/web/src/pages/profiles/StreamSelectionProfilePage.tsx new file mode 100644 index 000000000..c284b99f1 --- /dev/null +++ b/web/src/pages/profiles/StreamSelectionProfilePage.tsx @@ -0,0 +1,350 @@ +import { + defaultRule, + type StreamSelectionProfileFormValues, + type StreamSelectionRuleFormValues, +} from '@/components/profiles/streamSelectionFormTypes'; +import { StreamSelectionRuleEditor } from '@/components/profiles/StreamSelectionRuleEditor'; +import { + getApiStreamSelectionProfilesByIdOptions, + getApiStreamSelectionProfilesQueryKey, + postApiStreamSelectionProfilesMutation, + putApiStreamSelectionProfilesByIdMutation, +} from '@/generated/@tanstack/react-query.gen'; +import { postApiStreamSelectionProfilesValidateExpression } from '@/generated/sdk.gen'; +import type { GetApiStreamSelectionProfilesByIdResponse } from '@/generated/types.gen'; +import { t } from '@lingui/core/macro'; +import { Trans } from '@lingui/react/macro'; +import { AddCircle } from '@mui/icons-material'; +import { + Box, + Breadcrumbs, + Button, + Paper, + Stack, + TextField, + Typography, +} from '@mui/material'; +import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'; +import { Link, useNavigate, useParams } from '@tanstack/react-router'; +import { useSnackbar } from 'notistack'; +import { useCallback, useState } from 'react'; +import { + Controller, + FormProvider, + useFieldArray, + useForm, +} from 'react-hook-form'; + +function profileToFormValues( + profile: GetApiStreamSelectionProfilesByIdResponse, +): StreamSelectionProfileFormValues { + return { + name: profile.name, + rules: profile.rules.map((rule) => ({ + label: rule.label ?? '', + condition: rule.condition, + audioAction: rule.audioAction, + subtitleAction: rule.subtitleAction, + })) as StreamSelectionRuleFormValues[], + }; +} + +function formValuesToBody(values: StreamSelectionProfileFormValues) { + return { + name: values.name, + rules: values.rules.map((rule) => { + const audioAction = cleanAudioAction(rule.audioAction); + const subtitleAction = cleanSubtitleAction(rule.subtitleAction); + return { + label: rule.label || undefined, + condition: rule.condition, + audioAction, + subtitleAction, + }; + }), + }; +} + +function cleanAudioAction( + action: StreamSelectionRuleFormValues['audioAction'], +) { + switch (action.type) { + case 'by_language': + return { + type: 'by_language' as const, + languages: action.languages, + preferChannels: + action.preferChannels === '' ? undefined : action.preferChannels, + }; + case 'by_title': + return { type: 'by_title' as const, titleContains: action.titleContains }; + case 'default': + return { type: 'default' as const }; + } +} + +function cleanSubtitleAction( + action: StreamSelectionRuleFormValues['subtitleAction'], +) { + switch (action.type) { + case 'by_language': + return { + type: 'by_language' as const, + languages: action.languages, + filterType: action.filterType, + allowImageBased: action.allowImageBased, + allowExternal: action.allowExternal, + }; + case 'default': + return { type: 'default' as const }; + case 'disable': + return { type: 'disable' as const }; + } +} + +interface Props { + isNew: boolean; +} + +export function StreamSelectionProfilePage({ isNew }: Props) { + const navigate = useNavigate(); + const snackbar = useSnackbar(); + const queryClient = useQueryClient(); + + const params = useParams({ strict: false }); + const profileId = (params as Record)['profileId']; + + const { data: existingProfile } = useQuery({ + ...getApiStreamSelectionProfilesByIdOptions({ + path: { id: profileId ?? '' }, + }), + enabled: !isNew && profileId !== undefined, + }); + + const methods = useForm({ + defaultValues: isNew + ? { name: '', rules: [{ ...defaultRule }] } + : existingProfile + ? profileToFormValues(existingProfile) + : undefined, + values: + !isNew && existingProfile + ? profileToFormValues(existingProfile) + : undefined, + }); + + const { + control, + handleSubmit, + formState: { isDirty, isValid, isSubmitting }, + reset, + } = methods; + + const { fields, append, remove, move } = useFieldArray({ + control, + name: 'rules', + }); + + const [expandedRule, setExpandedRule] = useState( + isNew ? 0 : null, + ); + + const createMutation = useMutation({ + ...postApiStreamSelectionProfilesMutation(), + onSuccess: async (data) => { + snackbar.enqueueSnackbar(t`Profile created`, { variant: 'success' }); + await queryClient.invalidateQueries({ + queryKey: getApiStreamSelectionProfilesQueryKey(), + }); + await navigate({ + to: '/profiles/stream-selection/$profileId', + params: { profileId: data.uuid }, + }); + }, + }); + + const updateMutation = useMutation({ + ...putApiStreamSelectionProfilesByIdMutation(), + onSuccess: async () => { + snackbar.enqueueSnackbar(t`Profile saved`, { variant: 'success' }); + await queryClient.invalidateQueries({ + queryKey: getApiStreamSelectionProfilesQueryKey(), + }); + reset(methods.getValues()); + }, + }); + + const onSubmit = useCallback( + (values: StreamSelectionProfileFormValues) => { + const body = formValuesToBody(values); + if (isNew) { + createMutation.mutate({ body }); + } else if (profileId) { + updateMutation.mutate({ body, path: { id: profileId } }); + } + }, + [isNew, profileId, createMutation, updateMutation], + ); + + const validateCondition = useCallback( + async (expression: string): Promise => { + try { + const { data } = await postApiStreamSelectionProfilesValidateExpression( + { + body: { expression }, + }, + ); + if (data && 'valid' in data && data.valid) { + return undefined; + } + // Error response + const errorData = data as { valid: false; error?: string } | undefined; + return errorData?.error ?? t`Invalid expression`; + } catch { + return t`Failed to validate expression`; + } + }, + [], + ); + + const handleAddRule = useCallback(() => { + append({ ...defaultRule }); + setExpandedRule(fields.length); + }, [append, fields.length]); + + return ( + + + + Stream Selection Profiles + + + {isNew ? New Profile : (existingProfile?.name ?? '')} + + + + + {isNew ? ( + New Stream Selection Profile + ) : ( + Edit Stream Selection Profile + )} + + + + + + ( + + )} + /> + + + + Rules + + + + + + + Rules are evaluated in order. The first rule whose condition + matches determines the audio and subtitle streams for playback. + + + + + {fields.map((field, index) => ( + + setExpandedRule(expandedRule === index ? null : index) + } + onMoveUp={() => { + move(index, index - 1); + setExpandedRule(index - 1); + }} + onMoveDown={() => { + move(index, index + 1); + setExpandedRule(index + 1); + }} + onRemove={() => { + remove(index); + if (expandedRule === index) { + setExpandedRule(null); + } else if (expandedRule !== null && expandedRule > index) { + setExpandedRule(expandedRule - 1); + } + }} + onValidateCondition={validateCondition} + /> + ))} + + + + + {isDirty && ( + + )} + + + + + + ); +} diff --git a/web/src/pages/profiles/StreamSelectionProfilesPage.tsx b/web/src/pages/profiles/StreamSelectionProfilesPage.tsx new file mode 100644 index 000000000..0c77aa0a5 --- /dev/null +++ b/web/src/pages/profiles/StreamSelectionProfilesPage.tsx @@ -0,0 +1,23 @@ +import { StreamSelectionProfilesTable } from '@/components/profiles/StreamSelectionProfilesTable'; +import { Trans } from '@lingui/react/macro'; +import { Box, Paper, Typography } from '@mui/material'; + +export default function StreamSelectionProfilesPage() { + return ( + + + Stream Selection Profiles + + + + Stream selection profiles control which audio and subtitle streams are + selected during transcoding. Assign profiles to channels, filler + lists, or individual programs. + + + + + + + ); +} diff --git a/web/src/pages/profiles/TranscodeConfigPage.tsx b/web/src/pages/profiles/TranscodeConfigPage.tsx new file mode 100644 index 000000000..5b2261b8c --- /dev/null +++ b/web/src/pages/profiles/TranscodeConfigPage.tsx @@ -0,0 +1,50 @@ +import { Trans } from '@lingui/react/macro'; +import { Check, VisibilityOff } from '@mui/icons-material'; +import { Paper, Stack, ToggleButton, Typography } from '@mui/material'; +import Breadcrumbs from '../../components/Breadcrumbs.tsx'; +import { TranscodeConfigSettingsForm } from '../../components/settings/ffmpeg/TranscodeConfigSettingsForm.tsx'; +import { useTranscodeConfig } from '../../hooks/settingsHooks.ts'; +import useStore from '../../store/index.ts'; +import { setShowAdvancedSettings } from '../../store/settings/actions.ts'; + +type Props = { + configId: string; +}; + +export default function TranscodeConfigPage({ configId }: Props) { + const transcodeConfig = useTranscodeConfig(configId); + const showAdvancedSettings = useStore( + (s) => s.settings.ui.showAdvancedSettings, + ); + + return ( + + + + + {transcodeConfig.data.name} + + setShowAdvancedSettings(!showAdvancedSettings)} + sx={{ ml: 'auto' }} + > + {showAdvancedSettings ? ( + + ) : ( + + )}{' '} + {showAdvancedSettings ? ( + Hide Advanced + ) : ( + Show Advanced + )} + + + + + + + ); +} diff --git a/web/src/pages/profiles/TranscodeConfigsPage.tsx b/web/src/pages/profiles/TranscodeConfigsPage.tsx new file mode 100644 index 000000000..31a6a8abc --- /dev/null +++ b/web/src/pages/profiles/TranscodeConfigsPage.tsx @@ -0,0 +1,24 @@ +import { Trans, useLingui } from '@lingui/react/macro'; +import { Paper, Stack, Typography } from '@mui/material'; +import { TranscodeConfigsTable } from '../../components/settings/ffmpeg/TranscodeConfigsTable.tsx'; + +export default function TranscodeConfigsPage() { + const { t } = useLingui(); + + return ( + + + Transcoding Configs + + + + Configure transcoding settings for Tunarr's streams. Each channel is + assigned one transcode configuration. + + + + + + + ); +} diff --git a/web/src/pages/settings/FfmpegSettingsPage.tsx b/web/src/pages/settings/FfmpegSettingsPage.tsx index 42f1b2935..b822b84d7 100644 --- a/web/src/pages/settings/FfmpegSettingsPage.tsx +++ b/web/src/pages/settings/FfmpegSettingsPage.tsx @@ -149,8 +149,6 @@ export default function FfmpegSettingsPage() { const deleteTranscodeConfig = useMutation({ ...deleteApiTranscodeConfigsByIdMutation(), - // mutationFn: (id: string) => - // apiClient.deleteTranscodeConfig(undefined, { params: { id } }), }); const updateFfmpegSettings: SubmitHandler< @@ -221,17 +219,23 @@ export default function FfmpegSettingsPage() { handleFfmpegLogChange(e.target.value) } > - Disabled - Console - File + + Disabled + + + Console + + + File + 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. + the Tunarr log directory. These files are automatically + cleaned up by a background process. @@ -297,8 +301,8 @@ export default function FfmpegSettingsPage() { /> - Channels configured to use the HLS Direct stream mode will output in - the selected container format. + Channels configured to use the HLS Direct stream mode will output + in the selected container format. @@ -318,9 +322,10 @@ export default function FfmpegSettingsPage() { directory (but not intermediate directories) if it doesn't exist.
- 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. + 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.
When unset, Tunarr will write segments to its current working directory. @@ -339,7 +344,9 @@ export default function FfmpegSettingsPage() { - Subtitles + + Subtitles + 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 + 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. diff --git a/web/src/routeTree.gen.ts b/web/src/routeTree.gen.ts index b8f803340..5013400b2 100644 --- a/web/src/routeTree.gen.ts +++ b/web/src/routeTree.gen.ts @@ -30,6 +30,8 @@ import { Route as SettingsHdhrRouteImport } from './routes/settings/hdhr'; import { Route as SettingsGeneralRouteImport } from './routes/settings/general'; import { Route as SettingsFfmpegRouteImport } from './routes/settings/ffmpeg'; import { Route as SettingsFeaturesRouteImport } from './routes/settings/features'; +import { Route as ProfilesTranscodeRouteImport } from './routes/profiles/transcode'; +import { Route as ProfilesStreamSelectionRouteImport } from './routes/profiles/stream-selection'; import { Route as LibraryFillersRouteImport } from './routes/library/fillers'; import { Route as LibraryCustomShowsRouteImport } from './routes/library/custom-shows'; import { Route as ChannelsTestRouteImport } from './routes/channels_/test'; @@ -41,6 +43,9 @@ import { Route as LibrarySmart_collectionsIndexRouteImport } from './routes/libr import { Route as ChannelsChannelIdIndexRouteImport } from './routes/channels_/$channelId/index'; import { Route as SettingsFfmpegNewRouteImport } from './routes/settings/ffmpeg_/new'; import { Route as SettingsFfmpegConfigIdRouteImport } from './routes/settings/ffmpeg_/$configId'; +import { Route as ProfilesTranscodeConfigIdRouteImport } from './routes/profiles/transcode_/$configId'; +import { Route as ProfilesStreamSelectionNewRouteImport } from './routes/profiles/stream-selection_/new'; +import { Route as ProfilesStreamSelectionProfileIdRouteImport } from './routes/profiles/stream-selection_/$profileId'; import { Route as MediaProgramTypeProgramIdRouteImport } from './routes/media_/$programType.$programId'; import { Route as LibrarySmart_collectionsIdRouteImport } from './routes/library/smart_collections/$id'; import { Route as ChannelsChannelIdWatchRouteImport } from './routes/channels_/$channelId/watch'; @@ -168,6 +173,16 @@ const SettingsFeaturesRoute = SettingsFeaturesRouteImport.update({ path: '/features', getParentRoute: () => SettingsRoute, } as any); +const ProfilesTranscodeRoute = ProfilesTranscodeRouteImport.update({ + id: '/profiles/transcode', + path: '/profiles/transcode', + getParentRoute: () => rootRouteImport, +} as any); +const ProfilesStreamSelectionRoute = ProfilesStreamSelectionRouteImport.update({ + id: '/profiles/stream-selection', + path: '/profiles/stream-selection', + getParentRoute: () => rootRouteImport, +} as any); const LibraryFillersRoute = LibraryFillersRouteImport.update({ id: '/library/fillers', path: '/library/fillers', @@ -225,6 +240,24 @@ const SettingsFfmpegConfigIdRoute = SettingsFfmpegConfigIdRouteImport.update({ path: '/ffmpeg/$configId', getParentRoute: () => SettingsRoute, } as any); +const ProfilesTranscodeConfigIdRoute = + ProfilesTranscodeConfigIdRouteImport.update({ + id: '/profiles/transcode_/$configId', + path: '/profiles/transcode/$configId', + getParentRoute: () => rootRouteImport, + } as any); +const ProfilesStreamSelectionNewRoute = + ProfilesStreamSelectionNewRouteImport.update({ + id: '/profiles/stream-selection_/new', + path: '/profiles/stream-selection/new', + getParentRoute: () => rootRouteImport, + } as any); +const ProfilesStreamSelectionProfileIdRoute = + ProfilesStreamSelectionProfileIdRouteImport.update({ + id: '/profiles/stream-selection_/$profileId', + path: '/profiles/stream-selection/$profileId', + getParentRoute: () => rootRouteImport, + } as any); const MediaProgramTypeProgramIdRoute = MediaProgramTypeProgramIdRouteImport.update({ id: '/media_/$programType/$programId', @@ -361,6 +394,8 @@ export interface FileRoutesByFullPath { '/channels/test': typeof ChannelsTestRoute; '/library/custom-shows': typeof LibraryCustomShowsRoute; '/library/fillers': typeof LibraryFillersRoute; + '/profiles/stream-selection': typeof ProfilesStreamSelectionRoute; + '/profiles/transcode': typeof ProfilesTranscodeRoute; '/settings/features': typeof SettingsFeaturesRoute; '/settings/ffmpeg': typeof SettingsFfmpegRoute; '/settings/general': typeof SettingsGeneralRoute; @@ -383,6 +418,9 @@ export interface FileRoutesByFullPath { '/channels/$channelId/watch': typeof ChannelsChannelIdWatchRoute; '/library/smart_collections/$id': typeof LibrarySmart_collectionsIdRoute; '/media/$programType/$programId': typeof MediaProgramTypeProgramIdRoute; + '/profiles/stream-selection/$profileId': typeof ProfilesStreamSelectionProfileIdRoute; + '/profiles/stream-selection/new': typeof ProfilesStreamSelectionNewRoute; + '/profiles/transcode/$configId': typeof ProfilesTranscodeConfigIdRoute; '/settings/ffmpeg/$configId': typeof SettingsFfmpegConfigIdRoute; '/settings/ffmpeg/new': typeof SettingsFfmpegNewRoute; '/channels/$channelId/': typeof ChannelsChannelIdIndexRoute; @@ -414,6 +452,8 @@ export interface FileRoutesByTo { '/channels/test': typeof ChannelsTestRoute; '/library/custom-shows': typeof LibraryCustomShowsRoute; '/library/fillers': typeof LibraryFillersRoute; + '/profiles/stream-selection': typeof ProfilesStreamSelectionRoute; + '/profiles/transcode': typeof ProfilesTranscodeRoute; '/settings/features': typeof SettingsFeaturesRoute; '/settings/ffmpeg': typeof SettingsFfmpegRoute; '/settings/general': typeof SettingsGeneralRoute; @@ -434,6 +474,9 @@ export interface FileRoutesByTo { '/channels/$channelId/watch': typeof ChannelsChannelIdWatchRoute; '/library/smart_collections/$id': typeof LibrarySmart_collectionsIdRoute; '/media/$programType/$programId': typeof MediaProgramTypeProgramIdRoute; + '/profiles/stream-selection/$profileId': typeof ProfilesStreamSelectionProfileIdRoute; + '/profiles/stream-selection/new': typeof ProfilesStreamSelectionNewRoute; + '/profiles/transcode/$configId': typeof ProfilesTranscodeConfigIdRoute; '/settings/ffmpeg/$configId': typeof SettingsFfmpegConfigIdRoute; '/settings/ffmpeg/new': typeof SettingsFfmpegNewRoute; '/channels/$channelId': typeof ChannelsChannelIdIndexRoute; @@ -468,6 +511,8 @@ export interface FileRoutesById { '/channels_/test': typeof ChannelsTestRoute; '/library/custom-shows': typeof LibraryCustomShowsRoute; '/library/fillers': typeof LibraryFillersRoute; + '/profiles/stream-selection': typeof ProfilesStreamSelectionRoute; + '/profiles/transcode': typeof ProfilesTranscodeRoute; '/settings/features': typeof SettingsFeaturesRoute; '/settings/ffmpeg': typeof SettingsFfmpegRoute; '/settings/general': typeof SettingsGeneralRoute; @@ -490,6 +535,9 @@ export interface FileRoutesById { '/channels_/$channelId/watch': typeof ChannelsChannelIdWatchRoute; '/library/smart_collections/$id': typeof LibrarySmart_collectionsIdRoute; '/media_/$programType/$programId': typeof MediaProgramTypeProgramIdRoute; + '/profiles/stream-selection_/$profileId': typeof ProfilesStreamSelectionProfileIdRoute; + '/profiles/stream-selection_/new': typeof ProfilesStreamSelectionNewRoute; + '/profiles/transcode_/$configId': typeof ProfilesTranscodeConfigIdRoute; '/settings/ffmpeg_/$configId': typeof SettingsFfmpegConfigIdRoute; '/settings/ffmpeg_/new': typeof SettingsFfmpegNewRoute; '/channels_/$channelId/': typeof ChannelsChannelIdIndexRoute; @@ -525,6 +573,8 @@ export interface FileRouteTypes { | '/channels/test' | '/library/custom-shows' | '/library/fillers' + | '/profiles/stream-selection' + | '/profiles/transcode' | '/settings/features' | '/settings/ffmpeg' | '/settings/general' @@ -547,6 +597,9 @@ export interface FileRouteTypes { | '/channels/$channelId/watch' | '/library/smart_collections/$id' | '/media/$programType/$programId' + | '/profiles/stream-selection/$profileId' + | '/profiles/stream-selection/new' + | '/profiles/transcode/$configId' | '/settings/ffmpeg/$configId' | '/settings/ffmpeg/new' | '/channels/$channelId/' @@ -578,6 +631,8 @@ export interface FileRouteTypes { | '/channels/test' | '/library/custom-shows' | '/library/fillers' + | '/profiles/stream-selection' + | '/profiles/transcode' | '/settings/features' | '/settings/ffmpeg' | '/settings/general' @@ -598,6 +653,9 @@ export interface FileRouteTypes { | '/channels/$channelId/watch' | '/library/smart_collections/$id' | '/media/$programType/$programId' + | '/profiles/stream-selection/$profileId' + | '/profiles/stream-selection/new' + | '/profiles/transcode/$configId' | '/settings/ffmpeg/$configId' | '/settings/ffmpeg/new' | '/channels/$channelId' @@ -631,6 +689,8 @@ export interface FileRouteTypes { | '/channels_/test' | '/library/custom-shows' | '/library/fillers' + | '/profiles/stream-selection' + | '/profiles/transcode' | '/settings/features' | '/settings/ffmpeg' | '/settings/general' @@ -653,6 +713,9 @@ export interface FileRouteTypes { | '/channels_/$channelId/watch' | '/library/smart_collections/$id' | '/media_/$programType/$programId' + | '/profiles/stream-selection_/$profileId' + | '/profiles/stream-selection_/new' + | '/profiles/transcode_/$configId' | '/settings/ffmpeg_/$configId' | '/settings/ffmpeg_/new' | '/channels_/$channelId/' @@ -687,6 +750,8 @@ export interface RootRouteChildren { ChannelsTestRoute: typeof ChannelsTestRoute; LibraryCustomShowsRoute: typeof LibraryCustomShowsRoute; LibraryFillersRoute: typeof LibraryFillersRoute; + ProfilesStreamSelectionRoute: typeof ProfilesStreamSelectionRoute; + ProfilesTranscodeRoute: typeof ProfilesTranscodeRoute; ChannelsIndexRoute: typeof ChannelsIndexRoute; LibraryIndexRoute: typeof LibraryIndexRoute; Media_sourcesIndexRoute: typeof Media_sourcesIndexRoute; @@ -696,6 +761,9 @@ export interface RootRouteChildren { LibraryFillersNewRouteRoute: typeof LibraryFillersNewRouteRouteWithChildren; LibrarySmart_collectionsIdRoute: typeof LibrarySmart_collectionsIdRoute; MediaProgramTypeProgramIdRoute: typeof MediaProgramTypeProgramIdRoute; + ProfilesStreamSelectionProfileIdRoute: typeof ProfilesStreamSelectionProfileIdRoute; + ProfilesStreamSelectionNewRoute: typeof ProfilesStreamSelectionNewRoute; + ProfilesTranscodeConfigIdRoute: typeof ProfilesTranscodeConfigIdRoute; LibrarySmart_collectionsIndexRoute: typeof LibrarySmart_collectionsIndexRoute; LibraryTrashIndexRoute: typeof LibraryTrashIndexRoute; Media_sourcesMediaSourceIdIndexRoute: typeof Media_sourcesMediaSourceIdIndexRoute; @@ -851,6 +919,20 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof SettingsFeaturesRouteImport; parentRoute: typeof SettingsRoute; }; + '/profiles/transcode': { + id: '/profiles/transcode'; + path: '/profiles/transcode'; + fullPath: '/profiles/transcode'; + preLoaderRoute: typeof ProfilesTranscodeRouteImport; + parentRoute: typeof rootRouteImport; + }; + '/profiles/stream-selection': { + id: '/profiles/stream-selection'; + path: '/profiles/stream-selection'; + fullPath: '/profiles/stream-selection'; + preLoaderRoute: typeof ProfilesStreamSelectionRouteImport; + parentRoute: typeof rootRouteImport; + }; '/library/fillers': { id: '/library/fillers'; path: '/library/fillers'; @@ -928,6 +1010,27 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof SettingsFfmpegConfigIdRouteImport; parentRoute: typeof SettingsRoute; }; + '/profiles/transcode_/$configId': { + id: '/profiles/transcode_/$configId'; + path: '/profiles/transcode/$configId'; + fullPath: '/profiles/transcode/$configId'; + preLoaderRoute: typeof ProfilesTranscodeConfigIdRouteImport; + parentRoute: typeof rootRouteImport; + }; + '/profiles/stream-selection_/new': { + id: '/profiles/stream-selection_/new'; + path: '/profiles/stream-selection/new'; + fullPath: '/profiles/stream-selection/new'; + preLoaderRoute: typeof ProfilesStreamSelectionNewRouteImport; + parentRoute: typeof rootRouteImport; + }; + '/profiles/stream-selection_/$profileId': { + id: '/profiles/stream-selection_/$profileId'; + path: '/profiles/stream-selection/$profileId'; + fullPath: '/profiles/stream-selection/$profileId'; + preLoaderRoute: typeof ProfilesStreamSelectionProfileIdRouteImport; + parentRoute: typeof rootRouteImport; + }; '/media_/$programType/$programId': { id: '/media_/$programType/$programId'; path: '/media/$programType/$programId'; @@ -1233,6 +1336,8 @@ const rootRouteChildren: RootRouteChildren = { ChannelsTestRoute: ChannelsTestRoute, LibraryCustomShowsRoute: LibraryCustomShowsRoute, LibraryFillersRoute: LibraryFillersRoute, + ProfilesStreamSelectionRoute: ProfilesStreamSelectionRoute, + ProfilesTranscodeRoute: ProfilesTranscodeRoute, ChannelsIndexRoute: ChannelsIndexRoute, LibraryIndexRoute: LibraryIndexRoute, Media_sourcesIndexRoute: Media_sourcesIndexRoute, @@ -1244,6 +1349,9 @@ const rootRouteChildren: RootRouteChildren = { LibraryFillersNewRouteRoute: LibraryFillersNewRouteRouteWithChildren, LibrarySmart_collectionsIdRoute: LibrarySmart_collectionsIdRoute, MediaProgramTypeProgramIdRoute: MediaProgramTypeProgramIdRoute, + ProfilesStreamSelectionProfileIdRoute: ProfilesStreamSelectionProfileIdRoute, + ProfilesStreamSelectionNewRoute: ProfilesStreamSelectionNewRoute, + ProfilesTranscodeConfigIdRoute: ProfilesTranscodeConfigIdRoute, LibrarySmart_collectionsIndexRoute: LibrarySmart_collectionsIndexRoute, LibraryTrashIndexRoute: LibraryTrashIndexRoute, Media_sourcesMediaSourceIdIndexRoute: Media_sourcesMediaSourceIdIndexRoute, diff --git a/web/src/routes/channels_/$channelId/route.tsx b/web/src/routes/channels_/$channelId/route.tsx index aa84ba762..e570466f3 100644 --- a/web/src/routes/channels_/$channelId/route.tsx +++ b/web/src/routes/channels_/$channelId/route.tsx @@ -1,9 +1,9 @@ -import { createFileRoute, Outlet } from '@tanstack/react-router'; -import { setCurrentEntityType } from '../../../store/channelEditor/actions.ts'; +import { createFileRoute } from '@tanstack/react-router'; export const Route = createFileRoute('/channels_/$channelId')({ - loader() { - setCurrentEntityType('channel'); - }, - component: Outlet, + component: RouteComponent, }); + +function RouteComponent() { + return
Hello "/channels_/$channelId"!
; +} diff --git a/web/src/routes/channels_/test.tsx b/web/src/routes/channels_/test.tsx index 8feb96c3c..313bf2c81 100644 --- a/web/src/routes/channels_/test.tsx +++ b/web/src/routes/channels_/test.tsx @@ -2,5 +2,9 @@ import { Trans } from '@lingui/react/macro'; import { createFileRoute } from '@tanstack/react-router'; export const Route = createFileRoute('/channels_/test')({ - component: () =>
Test
, + component: () => ( +
+ Test +
+ ), }); diff --git a/web/src/routes/media_sources_/$mediaSourceId/index.tsx b/web/src/routes/media_sources_/$mediaSourceId/index.tsx index fc8ef4a51..f3a418cc8 100644 --- a/web/src/routes/media_sources_/$mediaSourceId/index.tsx +++ b/web/src/routes/media_sources_/$mediaSourceId/index.tsx @@ -32,7 +32,9 @@ function MediaSourceBrowserPage() { - Media Source: "{mediaSource.name}" + + Media Source: "{mediaSource.name}" + diff --git a/web/src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx b/web/src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx index 2cfd4bd41..214d8ebeb 100644 --- a/web/src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx +++ b/web/src/routes/media_sources_/$mediaSourceId/libraries_.$libraryId.tsx @@ -30,12 +30,18 @@ function MediaSourceBrowserPage() { - Media Source: "{library.mediaSource.name}" + + Media Source: "{library.mediaSource.name}" + - Library: {library.name} - Search is currently scoped to this Media Source Library. + Library: {library.name} + + + + Search is currently scoped to this Media Source Library. + diff --git a/web/src/routes/profiles/stream-selection.tsx b/web/src/routes/profiles/stream-selection.tsx new file mode 100644 index 000000000..d50deadf8 --- /dev/null +++ b/web/src/routes/profiles/stream-selection.tsx @@ -0,0 +1,9 @@ +import StreamSelectionProfilesPage from '@/pages/profiles/StreamSelectionProfilesPage'; +import { createFileRoute } from '@tanstack/react-router'; +import { getApiStreamSelectionProfilesOptions } from '../../generated/@tanstack/react-query.gen'; + +export const Route = createFileRoute('/profiles/stream-selection')({ + loader: ({ context: { queryClient } }) => + queryClient.ensureQueryData(getApiStreamSelectionProfilesOptions()), + component: StreamSelectionProfilesPage, +}); diff --git a/web/src/routes/profiles/stream-selection_/$profileId.tsx b/web/src/routes/profiles/stream-selection_/$profileId.tsx new file mode 100644 index 000000000..72d8f0815 --- /dev/null +++ b/web/src/routes/profiles/stream-selection_/$profileId.tsx @@ -0,0 +1,13 @@ +import { StreamSelectionProfilePage } from '@/pages/profiles/StreamSelectionProfilePage'; +import { createFileRoute } from '@tanstack/react-router'; +import { getApiStreamSelectionProfilesByIdOptions } from '../../../generated/@tanstack/react-query.gen'; + +export const Route = createFileRoute('/profiles/stream-selection_/$profileId')({ + loader: ({ params, context }) => + context.queryClient.ensureQueryData( + getApiStreamSelectionProfilesByIdOptions({ + path: { id: params.profileId }, + }), + ), + component: () => , +}); diff --git a/web/src/routes/profiles/stream-selection_/new.tsx b/web/src/routes/profiles/stream-selection_/new.tsx new file mode 100644 index 000000000..0c2d8689c --- /dev/null +++ b/web/src/routes/profiles/stream-selection_/new.tsx @@ -0,0 +1,6 @@ +import { StreamSelectionProfilePage } from '@/pages/profiles/StreamSelectionProfilePage'; +import { createFileRoute } from '@tanstack/react-router'; + +export const Route = createFileRoute('/profiles/stream-selection_/new')({ + component: () => , +}); diff --git a/web/src/routes/profiles/transcode.tsx b/web/src/routes/profiles/transcode.tsx new file mode 100644 index 000000000..8847e3de6 --- /dev/null +++ b/web/src/routes/profiles/transcode.tsx @@ -0,0 +1,6 @@ +import { createFileRoute } from '@tanstack/react-router'; +import TranscodeConfigsPage from '../../pages/profiles/TranscodeConfigsPage.tsx'; + +export const Route = createFileRoute('/profiles/transcode')({ + component: TranscodeConfigsPage, +}); diff --git a/web/src/routes/profiles/transcode_/$configId.tsx b/web/src/routes/profiles/transcode_/$configId.tsx new file mode 100644 index 000000000..d2ecea47f --- /dev/null +++ b/web/src/routes/profiles/transcode_/$configId.tsx @@ -0,0 +1,11 @@ +import { createFileRoute } from '@tanstack/react-router'; +import TranscodeConfigPage from '../../../pages/profiles/TranscodeConfigPage.tsx'; + +export const Route = createFileRoute('/profiles/transcode_/$configId')({ + component: RouteComponent, +}); + +function RouteComponent() { + const { configId } = Route.useParams(); + return ; +}