1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Merge remote-tracking branch 'upstream/master' into global-globalize

This commit is contained in:
ferferga 2020-04-03 15:14:06 +02:00
commit 54e84a4a2f
40 changed files with 982 additions and 1086 deletions

View file

@ -33,7 +33,7 @@ jobs:
- task: NodeTool@0 - task: NodeTool@0
displayName: 'Install Node' displayName: 'Install Node'
inputs: inputs:
versionSpec: '10.x' versionSpec: '12.x'
- task: Cache@2 - task: Cache@2
displayName: 'Check Cache' displayName: 'Check Cache'
@ -82,7 +82,7 @@ jobs:
- task: NodeTool@0 - task: NodeTool@0
displayName: 'Install Node' displayName: 'Install Node'
inputs: inputs:
versionSpec: '10.x' versionSpec: '12.x'
- task: Cache@2 - task: Cache@2
displayName: 'Check Cache' displayName: 'Check Cache'

584
.gitignore vendored
View file

@ -1,578 +1,10 @@
# config
config.json
# Created by https://www.gitignore.io/api/node,rider,macos,linux,windows,visualstudio,visualstudiocode # npm
# Edit at https://www.gitignore.io/?templates=node,rider,macos,linux,windows,visualstudio,visualstudiocode
### Linux ###
*~
# temporary files which can be created if a process still has a handle open of a deleted file
.fuse_hidden*
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
# .nfs files are created when an open file is removed but is still being accessed
.nfs*
### macOS ###
# General
.DS_Store
.AppleDouble
.LSOverride
# Icon must end with two \r
Icon
# Thumbnails
._*
# Files that might appear in the root of a volume
.DocumentRevisions-V100
.fseventsd
.Spotlight-V100
.TemporaryItems
.Trashes
.VolumeIcon.icns
.com.apple.timemachine.donotpresent
# Directories potentially created on remote AFP share
.AppleDB
.AppleDesktop
Network Trash Folder
Temporary Items
.apdisk
### Node ###
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# Dependency lockfile
package-lock.json
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
.env.test
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless/
# FuseBox cache
.fusebox/
# DynamoDB Local files
.dynamodb/
### Rider ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Generated files
.idea/**/contentModel.xml
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# CMake
cmake-build-*/
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties
# Editor-based Rest Client
.idea/httpRequests
# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser
### VisualStudioCode ###
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
### VisualStudioCode Patch ###
# Ignore all local history of files
.history
### Windows ###
# Windows thumbnail cache files
Thumbs.db
ehthumbs.db
ehthumbs_vista.db
# Dump file
*.stackdump
# Folder config file
[Dd]esktop.ini
# Recycle Bin used on file shares
$RECYCLE.BIN/
# Windows Installer files
*.cab
*.msi
*.msix
*.msm
*.msp
# Windows shortcuts
*.lnk
### VisualStudio ###
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# ASP.NET Core default setup: bower directory is configured as wwwroot/lib/ and bower restore is true
**/wwwroot/lib/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- Backup*.rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# End of https://www.gitignore.io/api/node,rider,macos,linux,windows,visualstudio,visualstudiocode
# dist for webpack output
dist dist
node_modules
# ide
.idea
.vscode

View file

@ -6,8 +6,8 @@
"license": "GPL-2.0-or-later", "license": "GPL-2.0-or-later",
"devDependencies": { "devDependencies": {
"@babel/core": "^7.8.6", "@babel/core": "^7.8.6",
"@babel/polyfill": "^7.8.7",
"@babel/plugin-transform-modules-amd": "^7.8.3", "@babel/plugin-transform-modules-amd": "^7.8.3",
"@babel/polyfill": "^7.8.7",
"@babel/preset-env": "^7.8.6", "@babel/preset-env": "^7.8.6",
"autoprefixer": "^9.7.4", "autoprefixer": "^9.7.4",
"babel-loader": "^8.0.6", "babel-loader": "^8.0.6",
@ -18,7 +18,7 @@
"cssnano": "^4.1.10", "cssnano": "^4.1.10",
"del": "^5.1.0", "del": "^5.1.0",
"eslint": "^6.8.0", "eslint": "^6.8.0",
"file-loader": "^5.0.2", "file-loader": "^6.0.0",
"gulp": "^4.0.2", "gulp": "^4.0.2",
"gulp-babel": "^8.0.0", "gulp-babel": "^8.0.0",
"gulp-cli": "^2.2.0", "gulp-cli": "^2.2.0",
@ -32,7 +32,7 @@
"gulp-sass": "^4.0.2", "gulp-sass": "^4.0.2",
"gulp-sourcemaps": "^2.6.5", "gulp-sourcemaps": "^2.6.5",
"gulp-terser": "^1.2.0", "gulp-terser": "^1.2.0",
"html-webpack-plugin": "^3.2.0", "html-webpack-plugin": "^4.0.2",
"lazypipe": "^1.0.2", "lazypipe": "^1.0.2",
"node-sass": "^4.13.1", "node-sass": "^4.13.1",
"postcss-loader": "^3.0.0", "postcss-loader": "^3.0.0",
@ -59,30 +59,40 @@
"jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto", "jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto",
"jquery": "^3.4.1", "jquery": "^3.4.1",
"jstree": "^3.3.7", "jstree": "^3.3.7",
"libass-wasm": "https://github.com/jellyfin/JavascriptSubtitlesOctopus", "libass-wasm": "https://github.com/jellyfin/JavascriptSubtitlesOctopus#4.0.0-jf",
"material-design-icons-iconfont": "^5.0.1", "material-design-icons-iconfont": "^5.0.1",
"native-promise-only": "^0.8.0-a", "native-promise-only": "^0.8.0-a",
"page": "^1.11.5", "page": "^1.11.5",
"query-string": "^6.11.1", "query-string": "^6.11.1",
"resize-observer-polyfill": "^1.5.1", "resize-observer-polyfill": "^1.5.1",
"shaka-player": "^2.5.9", "shaka-player": "^2.5.10",
"sortablejs": "^1.10.2", "sortablejs": "^1.10.2",
"swiper": "^5.3.1", "swiper": "^5.3.1",
"webcomponents.js": "^0.7.24", "webcomponents.js": "^0.7.24",
"whatwg-fetch": "^3.0.0" "whatwg-fetch": "^3.0.0"
}, },
"babel": { "babel": {
"presets": ["@babel/preset-env"], "presets": [
"overrides": [{ "@babel/preset-env"
],
"overrides": [
{
"test": [ "test": [
"src/components/autoFocuser.js",
"src/components/cardbuilder/cardBuilder.js", "src/components/cardbuilder/cardBuilder.js",
"src/components/dom.js",
"src/components/filedownloader.js", "src/components/filedownloader.js",
"src/components/filesystem.js", "src/components/filesystem.js",
"src/components/input/keyboardnavigation.js", "src/components/input/keyboardnavigation.js",
"src/components/sanatizefilename.js" "src/components/sanatizefilename.js",
"src/scripts/settings/webSettings.js",
"src/components/scrollManager.js"
], ],
"plugins": ["@babel/plugin-transform-modules-amd"] "plugins": [
}] "@babel/plugin-transform-modules-amd"
]
}
]
}, },
"browserslist": [ "browserslist": [
"last 2 Firefox versions", "last 2 Firefox versions",

View file

@ -1,4 +1,4 @@
define(["appSettings", "browser", "events", "htmlMediaHelper", "globalize"], function (appSettings, browser, events, htmlMediaHelper, globalize) { define(["appSettings", "browser", "events", "htmlMediaHelper", "webSettings", "globalize"], function (appSettings, browser, events, htmlMediaHelper, webSettings, globalize) {
"use strict"; "use strict";
function getBaseProfileOptions(item) { function getBaseProfileOptions(item) {
@ -276,10 +276,12 @@ define(["appSettings", "browser", "events", "htmlMediaHelper", "globalize"], fun
features.push("otherapppromotions"); features.push("otherapppromotions");
features.push("displaymode"); features.push("displaymode");
features.push("targetblank"); features.push("targetblank");
// allows users to connect to more than one server
//features.push("multiserver");
features.push("screensaver"); features.push("screensaver");
webSettings.enableMultiServer().then(enabled => {
if (enabled) features.push("multiserver")
})
if (!browser.orsay && !browser.msie && (browser.firefox || browser.ps4 || browser.edge || supportsCue())) { if (!browser.orsay && !browser.msie && (browser.firefox || browser.ps4 || browser.edge || supportsCue())) {
features.push("subtitleappearancesettings"); features.push("subtitleappearancesettings");
} }

View file

@ -1,22 +1,29 @@
define(["focusManager", "layoutManager"], function (focusManager, layoutManager) { /* eslint-disable indent */
"use strict";
/**
* Module for performing auto-focus.
* @module components/autoFocuser
*/
import focusManager from "focusManager";
import layoutManager from "layoutManager";
/** /**
* Previously selected element. * Previously selected element.
*/ */
var activeElement; let activeElement;
/** /**
* Returns true if AutoFocuser is enabled. * Returns _true_ if AutoFocuser is enabled.
*/ */
function isEnabled() { export function isEnabled() {
return layoutManager.tv; return layoutManager.tv;
} }
/** /**
* Start AutoFocuser * Start AutoFocuser.
*/ */
function enable() { export function enable() {
if (!isEnabled()) { if (!isEnabled()) {
return; return;
} }
@ -28,24 +35,19 @@ define(["focusManager", "layoutManager"], function (focusManager, layoutManager)
console.debug("AutoFocuser enabled"); console.debug("AutoFocuser enabled");
} }
/**
* Create an array from some source.
*/
var arrayFrom = Array.prototype.from || function (src) {
return Array.prototype.slice.call(src);
}
/** /**
* Set focus on a suitable element, taking into account the previously selected. * Set focus on a suitable element, taking into account the previously selected.
* @param {HTMLElement} [container] - Element to limit scope.
* @returns {HTMLElement} Focused element.
*/ */
function autoFocus(container) { export function autoFocus(container) {
if (!isEnabled()) { if (!isEnabled()) {
return; return null;
} }
container = container || document.body; container = container || document.body;
var candidates = []; let candidates = [];
if (activeElement) { if (activeElement) {
// These elements are recreated // These elements are recreated
@ -62,10 +64,10 @@ define(["focusManager", "layoutManager"], function (focusManager, layoutManager)
candidates.push(activeElement); candidates.push(activeElement);
} }
candidates = candidates.concat(arrayFrom(container.querySelectorAll(".btnResume"))); candidates = candidates.concat(Array.from(container.querySelectorAll(".btnResume")));
candidates = candidates.concat(arrayFrom(container.querySelectorAll(".btnPlay"))); candidates = candidates.concat(Array.from(container.querySelectorAll(".btnPlay")));
var focusedElement; let focusedElement;
candidates.every(function (element) { candidates.every(function (element) {
if (focusManager.isCurrentlyFocusable(element)) { if (focusManager.isCurrentlyFocusable(element)) {
@ -79,7 +81,7 @@ define(["focusManager", "layoutManager"], function (focusManager, layoutManager)
if (!focusedElement) { if (!focusedElement) {
// FIXME: Multiple itemsContainers // FIXME: Multiple itemsContainers
var itemsContainer = container.querySelector(".itemsContainer"); const itemsContainer = container.querySelector(".itemsContainer");
if (itemsContainer) { if (itemsContainer) {
focusedElement = focusManager.autoFocus(itemsContainer); focusedElement = focusManager.autoFocus(itemsContainer);
@ -93,9 +95,8 @@ define(["focusManager", "layoutManager"], function (focusManager, layoutManager)
return focusedElement; return focusedElement;
} }
return { export default {
isEnabled: isEnabled, isEnabled: isEnabled,
enable: enable, enable: enable,
autoFocus: autoFocus autoFocus: autoFocus
}; };
});

View file

@ -1853,3 +1853,14 @@ import 'programStyles';
cell.removeAttribute('data-seriestimerid'); cell.removeAttribute('data-seriestimerid');
} }
} }
export default {
getCardsHtml: getCardsHtml,
getDefaultBackgroundClass: getDefaultBackgroundClass,
getDefaultText: getDefaultText,
buildCards: buildCards,
onUserDataChanged: onUserDataChanged,
onTimerCreated: onTimerCreated,
onTimerCancelled: onTimerCancelled,
onSeriesTimerCancelled: onSeriesTimerCancelled
};

View file

@ -1,18 +1,7 @@
define(["dialogHelper", "loading", "connectionManager", "globalize", "actionsheet", "emby-input", "paper-icon-button-light", "emby-button", "listViewStyle", "material-icons", "formDialogStyle"], function (dialogHelper, loading, connectionManager, globalize, actionsheet) { define(["dom", "dialogHelper", "loading", "connectionManager", "globalize", "actionsheet", "emby-input", "paper-icon-button-light", "emby-button", "listViewStyle", "material-icons", "formDialogStyle"], function (dom, dialogHelper, loading, connectionManager, globalize, actionsheet) {
"use strict"; "use strict";
return function (options) { return function (options) {
function parentWithClass(elem, className) {
while (!elem.classList || !elem.classList.contains(className)) {
elem = elem.parentNode;
if (!elem) {
return null;
}
}
return elem;
}
function mapChannel(button, channelId, providerChannelId) { function mapChannel(button, channelId, providerChannelId) {
loading.show(); loading.show();
var providerId = options.providerId; var providerId = options.providerId;
@ -26,7 +15,7 @@ define(["dialogHelper", "loading", "connectionManager", "globalize", "actionshee
}, },
dataType: "json" dataType: "json"
}).then(function (mapping) { }).then(function (mapping) {
var listItem = parentWithClass(button, "listItem"); var listItem = dom.parentWithClass(button, "listItem");
button.setAttribute("data-providerid", mapping.ProviderChannelId); button.setAttribute("data-providerid", mapping.ProviderChannelId);
listItem.querySelector(".secondary").innerHTML = getMappingSecondaryName(mapping, currentMappingOptions.ProviderName); listItem.querySelector(".secondary").innerHTML = getMappingSecondaryName(mapping, currentMappingOptions.ProviderName);
loading.hide(); loading.hide();
@ -34,7 +23,7 @@ define(["dialogHelper", "loading", "connectionManager", "globalize", "actionshee
} }
function onChannelsElementClick(e) { function onChannelsElementClick(e) {
var btnMap = parentWithClass(e.target, "btnMap"); var btnMap = dom.parentWithClass(e.target, "btnMap");
if (btnMap) { if (btnMap) {
var channelId = btnMap.getAttribute("data-id"); var channelId = btnMap.getAttribute("data-id");

View file

@ -1,25 +1,12 @@
define(['dialogHelper', 'loading', 'apphost', 'layoutManager', 'connectionManager', 'appRouter', 'globalize', 'emby-checkbox', 'emby-input', 'paper-icon-button-light', 'emby-select', 'material-icons', 'css!./../formdialog', 'emby-button', 'flexStyles'], function (dialogHelper, loading, appHost, layoutManager, connectionManager, appRouter, globalize) { define(['dom', 'dialogHelper', 'loading', 'apphost', 'layoutManager', 'connectionManager', 'appRouter', 'globalize', 'emby-checkbox', 'emby-input', 'paper-icon-button-light', 'emby-select', 'material-icons', 'css!./../formdialog', 'emby-button', 'flexStyles'], function (dom, dialogHelper, loading, appHost, layoutManager, connectionManager, appRouter, globalize) {
'use strict'; 'use strict';
var currentServerId; var currentServerId;
function parentWithClass(elem, className) {
while (!elem.classList || !elem.classList.contains(className)) {
elem = elem.parentNode;
if (!elem) {
return null;
}
}
return elem;
}
function onSubmit(e) { function onSubmit(e) {
loading.show(); loading.show();
var panel = parentWithClass(this, 'dialog'); var panel = dom.parentWithClass(this, 'dialog');
var collectionId = panel.querySelector('#selectCollectionToAddTo').value; var collectionId = panel.querySelector('#selectCollectionToAddTo').value;

View file

@ -63,7 +63,7 @@
<div class="selectContainer fldDateTimeLocale hide"> <div class="selectContainer fldDateTimeLocale hide">
<select is="emby-select" class="selectDateTimeLocale" label="${LabelDateTimeLocale}"> <select is="emby-select" class="selectDateTimeLocale" label="${LabelDateTimeLocale}">
<option value="">${AutoBasedOnLanguageSetting}</option> <option value="">${Auto}</option>
<option value="ar">Arabic</option> <option value="ar">Arabic</option>
<option value="be-BY">Belarusian (Belarus)</option> <option value="be-BY">Belarusian (Belarus)</option>
<option value="bg-BG">Bulgarian (Bulgaria)</option> <option value="bg-BG">Bulgarian (Bulgaria)</option>

View file

@ -1,8 +1,18 @@
define([], function () { /* eslint-disable indent */
'use strict';
function parentWithAttribute(elem, name, value) { /**
* Useful DOM utilities.
* @module components/dom
*/
/**
* Returns parent of element with specified attribute value.
* @param {HTMLElement} elem - Element whose parent need to find.
* @param {string} name - Attribute name.
* @param {mixed} value - Attribute value.
* @returns {HTMLElement} Parent with specified attribute value.
*/
export function parentWithAttribute(elem, name, value) {
while ((value ? elem.getAttribute(name) !== value : !elem.getAttribute(name))) { while ((value ? elem.getAttribute(name) !== value : !elem.getAttribute(name))) {
elem = elem.parentNode; elem = elem.parentNode;
@ -14,8 +24,13 @@ define([], function () {
return elem; return elem;
} }
function parentWithTag(elem, tagNames) { /**
* Returns parent of element with one of specified tag names.
* @param {HTMLElement} elem - Element whose parent need to find.
* @param {(string|Array)} tagNames - Tag name or array of tag names.
* @returns {HTMLElement} Parent with one of specified tag names.
*/
export function parentWithTag(elem, tagNames) {
// accept both string and array passed in // accept both string and array passed in
if (!Array.isArray(tagNames)) { if (!Array.isArray(tagNames)) {
tagNames = [tagNames]; tagNames = [tagNames];
@ -32,9 +47,14 @@ define([], function () {
return elem; return elem;
} }
/**
* Returns _true_ if class list contains one of specified names.
* @param {DOMTokenList} classList - Class list.
* @param {Array} classNames - Array of class names.
* @returns {boolean} _true_ if class list contains one of specified names.
*/
function containsAnyClass(classList, classNames) { function containsAnyClass(classList, classNames) {
for (let i = 0, length = classNames.length; i < length; i++) {
for (var i = 0, length = classNames.length; i < length; i++) {
if (classList.contains(classNames[i])) { if (classList.contains(classNames[i])) {
return true; return true;
} }
@ -42,8 +62,13 @@ define([], function () {
return false; return false;
} }
function parentWithClass(elem, classNames) { /**
* Returns parent of element with one of specified class names.
* @param {HTMLElement} elem - Element whose parent need to find.
* @param {(string|Array)} classNames - Class name or array of class names.
* @returns {HTMLElement} Parent with one of specified class names.
*/
export function parentWithClass(elem, classNames) {
// accept both string and array passed in // accept both string and array passed in
if (!Array.isArray(classNames)) { if (!Array.isArray(classNames)) {
classNames = [classNames]; classNames = [classNames];
@ -60,9 +85,9 @@ define([], function () {
return elem; return elem;
} }
var supportsCaptureOption = false; let supportsCaptureOption = false;
try { try {
var opts = Object.defineProperty({}, 'capture', { const opts = Object.defineProperty({}, 'capture', {
// eslint-disable-next-line getter-return // eslint-disable-next-line getter-return
get: function () { get: function () {
supportsCaptureOption = true; supportsCaptureOption = true;
@ -73,29 +98,58 @@ define([], function () {
console.debug('error checking capture support'); console.debug('error checking capture support');
} }
function addEventListenerWithOptions(target, type, handler, options) { /**
var optionsOrCapture = options || {}; * Adds event listener to specified target.
* @param {EventTarget} target - Event target.
* @param {string} type - Event type.
* @param {function} handler - Event handler.
* @param {Object} [options] - Listener options.
*/
export function addEventListener(target, type, handler, options) {
let optionsOrCapture = options || {};
if (!supportsCaptureOption) { if (!supportsCaptureOption) {
optionsOrCapture = optionsOrCapture.capture; optionsOrCapture = optionsOrCapture.capture;
} }
target.addEventListener(type, handler, optionsOrCapture); target.addEventListener(type, handler, optionsOrCapture);
} }
function removeEventListenerWithOptions(target, type, handler, options) { /**
var optionsOrCapture = options || {}; * Removes event listener from specified target.
* @param {EventTarget} target - Event target.
* @param {string} type - Event type.
* @param {function} handler - Event handler.
* @param {Object} [options] - Listener options.
*/
export function removeEventListener(target, type, handler, options) {
let optionsOrCapture = options || {};
if (!supportsCaptureOption) { if (!supportsCaptureOption) {
optionsOrCapture = optionsOrCapture.capture; optionsOrCapture = optionsOrCapture.capture;
} }
target.removeEventListener(type, handler, optionsOrCapture); target.removeEventListener(type, handler, optionsOrCapture);
} }
var windowSize; /**
var windowSizeEventsBound; * Cached window size.
*/
let windowSize;
/**
* Flag of event listener bound.
*/
let windowSizeEventsBound;
/**
* Resets cached window size.
*/
function clearWindowSize() { function clearWindowSize() {
windowSize = null; windowSize = null;
} }
function getWindowSize() { /**
* Returns window size.
* @returns {Object} Window size.
*/
export function getWindowSize() {
if (!windowSize) { if (!windowSize) {
windowSize = { windowSize = {
innerHeight: window.innerHeight, innerHeight: window.innerHeight,
@ -104,46 +158,60 @@ define([], function () {
if (!windowSizeEventsBound) { if (!windowSizeEventsBound) {
windowSizeEventsBound = true; windowSizeEventsBound = true;
addEventListenerWithOptions(window, "orientationchange", clearWindowSize, { passive: true }); addEventListener(window, "orientationchange", clearWindowSize, { passive: true });
addEventListenerWithOptions(window, 'resize', clearWindowSize, { passive: true }); addEventListener(window, 'resize', clearWindowSize, { passive: true });
} }
} }
return windowSize; return windowSize;
} }
var standardWidths = [480, 720, 1280, 1440, 1920, 2560, 3840, 5120, 7680]; /**
function getScreenWidth() { * Standard screen widths.
var width = window.innerWidth; */
var height = window.innerHeight; const standardWidths = [480, 720, 1280, 1440, 1920, 2560, 3840, 5120, 7680];
/**
* Returns screen width.
* @returns {number} Screen width.
*/
export function getScreenWidth() {
let width = window.innerWidth;
const height = window.innerHeight;
if (height > width) { if (height > width) {
width = height * (16.0 / 9.0); width = height * (16.0 / 9.0);
} }
var closest = standardWidths.sort(function (a, b) { const closest = standardWidths.sort(function (a, b) {
return Math.abs(width - a) - Math.abs(width - b); return Math.abs(width - a) - Math.abs(width - b);
})[0]; })[0];
return closest; return closest;
} }
var _animationEvent; /**
function whichAnimationEvent() { * Name of animation end event.
*/
let _animationEvent;
/**
* Returns name of animation end event.
* @returns {string} Name of animation end event.
*/
export function whichAnimationEvent() {
if (_animationEvent) { if (_animationEvent) {
return _animationEvent; return _animationEvent;
} }
var t; const el = document.createElement("div");
var el = document.createElement("div"); const animations = {
var animations = {
"animation": "animationend", "animation": "animationend",
"OAnimation": "oAnimationEnd", "OAnimation": "oAnimationEnd",
"MozAnimation": "animationend", "MozAnimation": "animationend",
"WebkitAnimation": "webkitAnimationEnd" "WebkitAnimation": "webkitAnimationEnd"
}; };
for (t in animations) { for (let t in animations) {
if (el.style[t] !== undefined) { if (el.style[t] !== undefined) {
_animationEvent = animations[t]; _animationEvent = animations[t];
return animations[t]; return animations[t];
@ -154,26 +222,36 @@ define([], function () {
return _animationEvent; return _animationEvent;
} }
function whichAnimationCancelEvent() { /**
* Returns name of animation cancel event.
* @returns {string} Name of animation cancel event.
*/
export function whichAnimationCancelEvent() {
return whichAnimationEvent().replace('animationend', 'animationcancel').replace('AnimationEnd', 'AnimationCancel'); return whichAnimationEvent().replace('animationend', 'animationcancel').replace('AnimationEnd', 'AnimationCancel');
} }
var _transitionEvent; /**
function whichTransitionEvent() { * Name of transition end event.
*/
let _transitionEvent;
/**
* Returns name of transition end event.
* @returns {string} Name of transition end event.
*/
export function whichTransitionEvent() {
if (_transitionEvent) { if (_transitionEvent) {
return _transitionEvent; return _transitionEvent;
} }
var t; const el = document.createElement("div");
var el = document.createElement("div"); const transitions = {
var transitions = {
"transition": "transitionend", "transition": "transitionend",
"OTransition": "oTransitionEnd", "OTransition": "oTransitionEnd",
"MozTransition": "transitionend", "MozTransition": "transitionend",
"WebkitTransition": "webkitTransitionEnd" "WebkitTransition": "webkitTransitionEnd"
}; };
for (t in transitions) { for (let t in transitions) {
if (el.style[t] !== undefined) { if (el.style[t] !== undefined) {
_transitionEvent = transitions[t]; _transitionEvent = transitions[t];
return transitions[t]; return transitions[t];
@ -184,16 +262,15 @@ define([], function () {
return _transitionEvent; return _transitionEvent;
} }
return { export default {
parentWithAttribute: parentWithAttribute, parentWithAttribute: parentWithAttribute,
parentWithClass: parentWithClass, parentWithClass: parentWithClass,
parentWithTag: parentWithTag, parentWithTag: parentWithTag,
addEventListener: addEventListenerWithOptions, addEventListener: addEventListener,
removeEventListener: removeEventListenerWithOptions, removeEventListener: removeEventListener,
getWindowSize: getWindowSize, getWindowSize: getWindowSize,
getScreenWidth: getScreenWidth, getScreenWidth: getScreenWidth,
whichTransitionEvent: whichTransitionEvent, whichTransitionEvent: whichTransitionEvent,
whichAnimationEvent: whichAnimationEvent, whichAnimationEvent: whichAnimationEvent,
whichAnimationCancelEvent: whichAnimationCancelEvent whichAnimationCancelEvent: whichAnimationCancelEvent
}; };
});

View file

@ -1,4 +1,4 @@
define(["dialogHelper", "globalize", "connectionManager", "events", "browser", "require", "emby-checkbox", "emby-collapse", "css!./style"], function (dialogHelper, globalize, connectionManager, events, browser, require) { define(["dom", "dialogHelper", "globalize", "connectionManager", "events", "browser", "require", "emby-checkbox", "emby-collapse", "css!./style"], function (dom, dialogHelper, globalize, connectionManager, events, browser, require) {
"use strict"; "use strict";
function renderOptions(context, selector, cssClass, items, isCheckedFn) { function renderOptions(context, selector, cssClass, items, isCheckedFn) {
@ -106,16 +106,6 @@ define(["dialogHelper", "globalize", "connectionManager", "events", "browser", "
events.trigger(instance, "filterchange"); events.trigger(instance, "filterchange");
} }
function parentWithClass(elem, className) {
while (!elem.classList || !elem.classList.contains(className)) {
elem = elem.parentNode;
if (!elem) {
return null;
}
}
return elem;
}
function setVisibility(context, options) { function setVisibility(context, options) {
if (options.mode == "livetvchannels" || options.mode == "albums" || options.mode == "artists" || options.mode == "albumartists" || options.mode == "songs") { if (options.mode == "livetvchannels" || options.mode == "albums" || options.mode == "artists" || options.mode == "albumartists" || options.mode == "songs") {
hideByClass(context, "videoStandard"); hideByClass(context, "videoStandard");
@ -320,7 +310,7 @@ define(["dialogHelper", "globalize", "connectionManager", "events", "browser", "
triggerChange(self); triggerChange(self);
}); });
context.addEventListener("change", function (e) { context.addEventListener("change", function (e) {
var chkGenreFilter = parentWithClass(e.target, "chkGenreFilter"); var chkGenreFilter = dom.parentWithClass(e.target, "chkGenreFilter");
if (chkGenreFilter) { if (chkGenreFilter) {
var filterName = chkGenreFilter.getAttribute("data-filter"); var filterName = chkGenreFilter.getAttribute("data-filter");
var filters = query.Genres || ""; var filters = query.Genres || "";
@ -334,7 +324,7 @@ define(["dialogHelper", "globalize", "connectionManager", "events", "browser", "
triggerChange(self); triggerChange(self);
return; return;
} }
var chkTagFilter = parentWithClass(e.target, "chkTagFilter"); var chkTagFilter = dom.parentWithClass(e.target, "chkTagFilter");
if (chkTagFilter) { if (chkTagFilter) {
var filterName = chkTagFilter.getAttribute("data-filter"); var filterName = chkTagFilter.getAttribute("data-filter");
var filters = query.Tags || ""; var filters = query.Tags || "";
@ -348,7 +338,7 @@ define(["dialogHelper", "globalize", "connectionManager", "events", "browser", "
triggerChange(self); triggerChange(self);
return; return;
} }
var chkYearFilter = parentWithClass(e.target, "chkYearFilter"); var chkYearFilter = dom.parentWithClass(e.target, "chkYearFilter");
if (chkYearFilter) { if (chkYearFilter) {
var filterName = chkYearFilter.getAttribute("data-filter"); var filterName = chkYearFilter.getAttribute("data-filter");
var filters = query.Years || ""; var filters = query.Years || "";
@ -362,7 +352,7 @@ define(["dialogHelper", "globalize", "connectionManager", "events", "browser", "
triggerChange(self); triggerChange(self);
return; return;
} }
var chkOfficialRatingFilter = parentWithClass(e.target, "chkOfficialRatingFilter"); var chkOfficialRatingFilter = dom.parentWithClass(e.target, "chkOfficialRatingFilter");
if (chkOfficialRatingFilter) { if (chkOfficialRatingFilter) {
var filterName = chkOfficialRatingFilter.getAttribute("data-filter"); var filterName = chkOfficialRatingFilter.getAttribute("data-filter");
var filters = query.OfficialRatings || ""; var filters = query.OfficialRatings || "";

View file

@ -1058,7 +1058,19 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa
legacyWorkerUrl: appRouter.baseUrl() + "/libraries/subtitles-octopus-worker-legacy.js", legacyWorkerUrl: appRouter.baseUrl() + "/libraries/subtitles-octopus-worker-legacy.js",
onError: function() { onError: function() {
htmlMediaHelper.onErrorInternal(self, 'mediadecodeerror'); htmlMediaHelper.onErrorInternal(self, 'mediadecodeerror');
} },
// new octopus options; override all, even defaults
renderMode: 'blend',
dropAllAnimations: false,
libassMemoryLimit: 40,
libassGlyphLimit: 40,
targetFps: 24,
prescaleTradeoff: 0.8,
softHeightLimit: 1080,
hardHeightLimit: 2160,
resizeVariation: 0.2,
renderAhead: 90
}; };
require(['JavascriptSubtitlesOctopus'], function(SubtitlesOctopus) { require(['JavascriptSubtitlesOctopus'], function(SubtitlesOctopus) {
currentSubtitlesOctopus = new SubtitlesOctopus(options); currentSubtitlesOctopus = new SubtitlesOctopus(options);

View file

@ -1,4 +1,4 @@
define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader', 'browser', 'layoutManager', 'scrollHelper', 'globalize', 'require', 'emby-checkbox', 'paper-icon-button-light', 'emby-button', 'formDialogStyle', 'cardStyle'], function (loading, appHost, dialogHelper, connectionManager, imageLoader, browser, layoutManager, scrollHelper, globalize, require) { define(['dom', 'loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader', 'browser', 'layoutManager', 'scrollHelper', 'globalize', 'require', 'emby-checkbox', 'paper-icon-button-light', 'emby-button', 'formDialogStyle', 'cardStyle'], function (dom, loading, appHost, dialogHelper, connectionManager, imageLoader, browser, layoutManager, scrollHelper, globalize, require) {
'use strict'; 'use strict';
var enableFocusTransform = !browser.slow && !browser.edge; var enableFocusTransform = !browser.slow && !browser.edge;
@ -126,21 +126,7 @@ define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader'
return html; return html;
} }
function parentWithClass(elem, className) {
while (!elem.classList || !elem.classList.contains(className)) {
elem = elem.parentNode;
if (!elem) {
return null;
}
}
return elem;
}
function downloadRemoteImage(page, apiClient, url, type, provider) { function downloadRemoteImage(page, apiClient, url, type, provider) {
var options = getBaseRemoteOptions(); var options = getBaseRemoteOptions();
options.Type = type; options.Type = type;
@ -152,7 +138,7 @@ define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader'
apiClient.downloadRemoteImage(options).then(function () { apiClient.downloadRemoteImage(options).then(function () {
hasChanges = true; hasChanges = true;
var dlg = parentWithClass(page, 'dialog'); var dlg = dom.parentWithClass(page, 'dialog');
dialogHelper.close(dlg); dialogHelper.close(dlg);
}); });
} }
@ -162,7 +148,6 @@ define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader'
} }
function getRemoteImageHtml(image, imageType, apiClient) { function getRemoteImageHtml(image, imageType, apiClient) {
var tagName = layoutManager.tv ? 'button' : 'div'; var tagName = layoutManager.tv ? 'button' : 'div';
var enableFooterButtons = !layoutManager.tv; var enableFooterButtons = !layoutManager.tv;
@ -293,7 +278,6 @@ define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader'
} }
function initEditor(page, apiClient) { function initEditor(page, apiClient) {
page.querySelector('#selectBrowsableImageType').addEventListener('change', function () { page.querySelector('#selectBrowsableImageType').addEventListener('change', function () {
browsableImageType = this.value; browsableImageType = this.value;
browsableImageStartIndex = 0; browsableImageStartIndex = 0;
@ -319,14 +303,14 @@ define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader'
page.addEventListener('click', function (e) { page.addEventListener('click', function (e) {
var btnDownloadRemoteImage = parentWithClass(e.target, 'btnDownloadRemoteImage'); var btnDownloadRemoteImage = dom.parentWithClass(e.target, 'btnDownloadRemoteImage');
if (btnDownloadRemoteImage) { if (btnDownloadRemoteImage) {
var card = parentWithClass(btnDownloadRemoteImage, 'card'); var card = dom.parentWithClass(btnDownloadRemoteImage, 'card');
downloadRemoteImage(page, apiClient, card.getAttribute('data-imageurl'), card.getAttribute('data-imagetype'), card.getAttribute('data-imageprovider')); downloadRemoteImage(page, apiClient, card.getAttribute('data-imageurl'), card.getAttribute('data-imagetype'), card.getAttribute('data-imageprovider'));
return; return;
} }
var btnImageCard = parentWithClass(e.target, 'btnImageCard'); var btnImageCard = dom.parentWithClass(e.target, 'btnImageCard');
if (btnImageCard) { if (btnImageCard) {
downloadRemoteImage(page, apiClient, btnImageCard.getAttribute('data-imageurl'), btnImageCard.getAttribute('data-imagetype'), btnImageCard.getAttribute('data-imageprovider')); downloadRemoteImage(page, apiClient, btnImageCard.getAttribute('data-imageurl'), btnImageCard.getAttribute('data-imagetype'), btnImageCard.getAttribute('data-imageprovider'));
} }
@ -334,7 +318,6 @@ define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader'
} }
function showEditor(itemId, serverId, itemType) { function showEditor(itemId, serverId, itemType) {
loading.show(); loading.show();
require(['text!./imagedownloader.template.html'], function (template) { require(['text!./imagedownloader.template.html'], function (template) {
@ -380,7 +363,6 @@ define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader'
} }
function onDialogClosed() { function onDialogClosed() {
var dlg = this; var dlg = this;
if (layoutManager.tv) { if (layoutManager.tv) {
@ -397,9 +379,7 @@ define(['loading', 'apphost', 'dialogHelper', 'connectionManager', 'imageLoader'
return { return {
show: function (itemId, serverId, itemType, imageType) { show: function (itemId, serverId, itemType, imageType) {
return new Promise(function (resolve, reject) { return new Promise(function (resolve, reject) {
currentResolve = resolve; currentResolve = resolve;
currentReject = reject; currentReject = reject;
hasChanges = false; hasChanges = false;

View file

@ -1,3 +1,8 @@
/**
* Module for performing keyboard navigation.
* @module components/input/keyboardnavigation
*/
import inputManager from "inputManager"; import inputManager from "inputManager";
import layoutManager from "layoutManager"; import layoutManager from "layoutManager";
@ -55,8 +60,8 @@ if (!hasFieldKey) {
/** /**
* Returns key name from event. * Returns key name from event.
* *
* @param {KeyboardEvent} event keyboard event * @param {KeyboardEvent} event - Keyboard event.
* @return {string} key name * @return {string} Key name.
*/ */
export function getKeyName(event) { export function getKeyName(event) {
return KeyNames[event.keyCode] || event.key; return KeyNames[event.keyCode] || event.key;
@ -65,8 +70,8 @@ export function getKeyName(event) {
/** /**
* Returns _true_ if key is used for navigation. * Returns _true_ if key is used for navigation.
* *
* @param {string} key name * @param {string} key - Key name.
* @return {boolean} _true_ if key is used for navigation * @return {boolean} _true_ if key is used for navigation.
*/ */
export function isNavigationKey(key) { export function isNavigationKey(key) {
return NavigationKeys.indexOf(key) != -1; return NavigationKeys.indexOf(key) != -1;
@ -155,3 +160,9 @@ function attachGamepadScript(e) {
// No need to check for gamepads manually at load time, the eventhandler will be fired for that // No need to check for gamepads manually at load time, the eventhandler will be fired for that
window.addEventListener("gamepadconnected", attachGamepadScript); window.addEventListener("gamepadconnected", attachGamepadScript);
export default {
enable: enable,
getKeyName: getKeyName,
isNavigationKey: isNavigationKey
};

View file

@ -296,8 +296,6 @@ define(["dialogHelper", "loading", "connectionManager", "require", "globalize",
var html = ""; var html = "";
var providerIds = item.ProviderIds || {};
for (var i = 0, length = idList.length; i < length; i++) { for (var i = 0, length = idList.length; i < length; i++) {
var idInfo = idList[i]; var idInfo = idList[i];
@ -306,9 +304,12 @@ define(["dialogHelper", "loading", "connectionManager", "require", "globalize",
html += '<div class="inputContainer">'; html += '<div class="inputContainer">';
var idLabel = globalize.translate("LabelDynamicExternalId").replace("{0}", idInfo.Name); var fullName = idInfo.Name;
if (idInfo.Type) {
fullName = idInfo.Name + " " + globalize.translate(idInfo.Type);
}
var value = providerIds[idInfo.Key] || ""; var idLabel = globalize.translate("LabelDynamicExternalId").replace("{0}", fullName);
html += '<input is="emby-input" class="txtLookupId" data-providerkey="' + idInfo.Key + '" id="' + id + '" label="' + idLabel + '"/>'; html += '<input is="emby-input" class="txtLookupId" data-providerkey="' + idInfo.Key + '" id="' + id + '" label="' + idLabel + '"/>';

View file

@ -465,7 +465,12 @@ define(['itemHelper', 'dom', 'layoutManager', 'dialogHelper', 'datetime', 'loadi
var id = "txt1" + idInfo.Key; var id = "txt1" + idInfo.Key;
var formatString = idInfo.UrlFormatString || ''; var formatString = idInfo.UrlFormatString || '';
var labelText = globalize.translate('LabelDynamicExternalId').replace('{0}', idInfo.Name); var fullName = idInfo.Name;
if (idInfo.Type) {
fullName = idInfo.Name + " " + globalize.translate(idInfo.Type);
}
var labelText = globalize.translate("LabelDynamicExternalId").replace("{0}", fullName);
html += '<div class="inputContainer">'; html += '<div class="inputContainer">';
html += '<div class="flex align-items-center">'; html += '<div class="flex align-items-center">';

View file

@ -1,24 +1,10 @@
define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager', 'connectionManager', 'userSettings', 'appRouter', 'globalize', 'emby-input', 'paper-icon-button-light', 'emby-select', 'material-icons', 'css!./../formdialog', 'emby-button'], function (shell, dialogHelper, loading, layoutManager, playbackManager, connectionManager, userSettings, appRouter, globalize) { define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager', 'connectionManager', 'userSettings', 'appRouter', 'globalize', 'emby-input', 'paper-icon-button-light', 'emby-select', 'material-icons', 'css!./../formdialog', 'emby-button'], function (dom, shell, dialogHelper, loading, layoutManager, playbackManager, connectionManager, userSettings, appRouter, globalize) {
'use strict'; 'use strict';
var currentServerId; var currentServerId;
function parentWithClass(elem, className) {
while (!elem.classList || !elem.classList.contains(className)) {
elem = elem.parentNode;
if (!elem) {
return null;
}
}
return elem;
}
function onSubmit(e) { function onSubmit(e) {
var panel = dom.parentWithClass(this, 'dialog');
var panel = parentWithClass(this, 'dialog');
var playlistId = panel.querySelector('#selectPlaylistToAddTo').value; var playlistId = panel.querySelector('#selectPlaylistToAddTo').value;
var apiClient = connectionManager.getApiClient(currentServerId); var apiClient = connectionManager.getApiClient(currentServerId);
@ -35,11 +21,9 @@ define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager',
} }
function createPlaylist(apiClient, dlg) { function createPlaylist(apiClient, dlg) {
loading.show(); loading.show();
var url = apiClient.getUrl("Playlists", { var url = apiClient.getUrl("Playlists", {
Name: dlg.querySelector('#txtNewPlaylistName').value, Name: dlg.querySelector('#txtNewPlaylistName').value,
Ids: dlg.querySelector('.fldSelectedItemIds').value || '', Ids: dlg.querySelector('.fldSelectedItemIds').value || '',
userId: apiClient.getCurrentUserId() userId: apiClient.getCurrentUserId()
@ -50,9 +34,7 @@ define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager',
type: "POST", type: "POST",
url: url, url: url,
dataType: "json" dataType: "json"
}).then(function (result) { }).then(function (result) {
loading.hide(); loading.hide();
var id = result.Id; var id = result.Id;
@ -63,16 +45,13 @@ define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager',
} }
function redirectToPlaylist(apiClient, id) { function redirectToPlaylist(apiClient, id) {
appRouter.showItem(id, apiClient.serverId()); appRouter.showItem(id, apiClient.serverId());
} }
function addToPlaylist(apiClient, dlg, id) { function addToPlaylist(apiClient, dlg, id) {
var itemIds = dlg.querySelector('.fldSelectedItemIds').value || ''; var itemIds = dlg.querySelector('.fldSelectedItemIds').value || '';
if (id === 'queue') { if (id === 'queue') {
playbackManager.queue({ playbackManager.queue({
serverId: apiClient.serverId(), serverId: apiClient.serverId(),
ids: itemIds.split(',') ids: itemIds.split(',')
@ -85,7 +64,6 @@ define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager',
loading.show(); loading.show();
var url = apiClient.getUrl("Playlists/" + id + "/Items", { var url = apiClient.getUrl("Playlists/" + id + "/Items", {
Ids: itemIds, Ids: itemIds,
userId: apiClient.getCurrentUserId() userId: apiClient.getCurrentUserId()
}); });
@ -95,7 +73,6 @@ define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager',
url: url url: url
}).then(function () { }).then(function () {
loading.hide(); loading.hide();
dlg.submitted = true; dlg.submitted = true;
@ -108,7 +85,6 @@ define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager',
} }
function populatePlaylists(editorOptions, panel) { function populatePlaylists(editorOptions, panel) {
var select = panel.querySelector('#selectPlaylistToAddTo'); var select = panel.querySelector('#selectPlaylistToAddTo');
loading.hide(); loading.hide();
@ -116,7 +92,6 @@ define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager',
panel.querySelector('.newPlaylistInfo').classList.add('hide'); panel.querySelector('.newPlaylistInfo').classList.add('hide');
var options = { var options = {
Recursive: true, Recursive: true,
IncludeItemTypes: "Playlist", IncludeItemTypes: "Playlist",
SortBy: 'SortName', SortBy: 'SortName',
@ -125,7 +100,6 @@ define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager',
var apiClient = connectionManager.getApiClient(currentServerId); var apiClient = connectionManager.getApiClient(currentServerId);
apiClient.getItems(apiClient.getCurrentUserId(), options).then(function (result) { apiClient.getItems(apiClient.getCurrentUserId(), options).then(function (result) {
var html = ''; var html = '';
if (editorOptions.enableAddToPlayQueue !== false && playbackManager.isPlaying()) { if (editorOptions.enableAddToPlayQueue !== false && playbackManager.isPlaying()) {
@ -135,7 +109,6 @@ define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager',
html += '<option value="">' + globalize.translate('OptionNew') + '</option>'; html += '<option value="">' + globalize.translate('OptionNew') + '</option>';
html += result.Items.map(function (i) { html += result.Items.map(function (i) {
return '<option value="' + i.Id + '">' + i.Name + '</option>'; return '<option value="' + i.Id + '">' + i.Name + '</option>';
}); });
@ -159,7 +132,6 @@ define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager',
} }
function getEditorHtml(items) { function getEditorHtml(items) {
var html = ''; var html = '';
html += '<div class="formDialogContent smoothScrollY" style="padding-top:2em;">'; html += '<div class="formDialogContent smoothScrollY" style="padding-top:2em;">';
@ -195,7 +167,6 @@ define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager',
} }
function initEditor(content, options, items) { function initEditor(content, options, items) {
content.querySelector('#selectPlaylistToAddTo').addEventListener('change', function () { content.querySelector('#selectPlaylistToAddTo').addEventListener('change', function () {
if (this.value) { if (this.value) {
content.querySelector('.newPlaylistInfo').classList.add('hide'); content.querySelector('.newPlaylistInfo').classList.add('hide');
@ -235,7 +206,6 @@ define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager',
} }
PlaylistEditor.prototype.show = function (options) { PlaylistEditor.prototype.show = function (options) {
var items = options.items || {}; var items = options.items || {};
currentServerId = options.serverId; currentServerId = options.serverId;
@ -272,7 +242,6 @@ define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager',
initEditor(dlg, options, items); initEditor(dlg, options, items);
dlg.querySelector('.btnCancel').addEventListener('click', function () { dlg.querySelector('.btnCancel').addEventListener('click', function () {
dialogHelper.close(dlg); dialogHelper.close(dlg);
}); });
@ -281,7 +250,6 @@ define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'playbackManager',
} }
return dialogHelper.open(dlg).then(function () { return dialogHelper.open(dlg).then(function () {
if (layoutManager.tv) { if (layoutManager.tv) {
centerFocus(dlg.querySelector('.formDialogContent'), false, false); centerFocus(dlg.querySelector('.formDialogContent'), false, false);
} }

View file

@ -1,19 +1,6 @@
define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'connectionManager', 'appRouter', 'globalize', 'emby-input', 'emby-checkbox', 'paper-icon-button-light', 'emby-select', 'material-icons', 'css!./../formdialog', 'emby-button'], function (shell, dialogHelper, loading, layoutManager, connectionManager, appRouter, globalize) { define(['dom', 'shell', 'dialogHelper', 'loading', 'layoutManager', 'connectionManager', 'appRouter', 'globalize', 'emby-input', 'emby-checkbox', 'paper-icon-button-light', 'emby-select', 'material-icons', 'css!./../formdialog', 'emby-button'], function (dom, shell, dialogHelper, loading, layoutManager, connectionManager, appRouter, globalize) {
'use strict'; 'use strict';
function parentWithClass(elem, className) {
while (!elem.classList || !elem.classList.contains(className)) {
elem = elem.parentNode;
if (!elem) {
return null;
}
}
return elem;
}
function getEditorHtml() { function getEditorHtml() {
var html = ''; var html = '';
@ -65,7 +52,7 @@ define(['shell', 'dialogHelper', 'loading', 'layoutManager', 'connectionManager'
loading.show(); loading.show();
var instance = this; var instance = this;
var dlg = parentWithClass(e.target, 'dialog'); var dlg = dom.parentWithClass(e.target, 'dialog');
var options = instance.options; var options = instance.options;
var apiClient = connectionManager.getApiClient(options.serverId); var apiClient = connectionManager.getApiClient(options.serverId);

View file

@ -1,38 +1,46 @@
define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManager) { /* eslint-disable indent */
"use strict";
/**
* Module for controlling scroll behavior.
* @module components/scrollManager
*/
import dom from "dom";
import browser from "browser";
import layoutManager from "layoutManager";
/** /**
* Scroll time in ms. * Scroll time in ms.
*/ */
var ScrollTime = 270; const ScrollTime = 270;
/** /**
* Epsilon for comparing values. * Epsilon for comparing values.
*/ */
var Epsilon = 1e-6; const Epsilon = 1e-6;
// FIXME: Need to scroll to top of page to fully show the top menu. This can be solved by some marker of top most elements or their containers // FIXME: Need to scroll to top of page to fully show the top menu. This can be solved by some marker of top most elements or their containers
/** /**
* Returns minimum vertical scroll. * Returns minimum vertical scroll.
* Scroll less than that value will be zeroed. * Scroll less than that value will be zeroed.
* *
* @return {number} minimum vertical scroll * @return {number} Minimum vertical scroll.
*/ */
function minimumScrollY() { function minimumScrollY() {
var topMenu = document.querySelector(".headerTop"); const topMenu = document.querySelector(".headerTop");
if (topMenu) { if (topMenu) {
return topMenu.clientHeight; return topMenu.clientHeight;
} }
return 0; return 0;
} }
var supportsSmoothScroll = "scrollBehavior" in document.documentElement.style; const supportsSmoothScroll = "scrollBehavior" in document.documentElement.style;
var supportsScrollToOptions = false; let supportsScrollToOptions = false;
try { try {
var elem = document.createElement("div"); const elem = document.createElement("div");
var opts = Object.defineProperty({}, "behavior", { const opts = Object.defineProperty({}, "behavior", {
// eslint-disable-next-line getter-return // eslint-disable-next-line getter-return
get: function () { get: function () {
supportsScrollToOptions = true; supportsScrollToOptions = true;
@ -47,10 +55,10 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
/** /**
* Returns value clamped by range [min, max]. * Returns value clamped by range [min, max].
* *
* @param {number} value clamped value * @param {number} value - Clamped value.
* @param {number} min begining of range * @param {number} min - Begining of range.
* @param {number} max ending of range * @param {number} max - Ending of range.
* @return {number} clamped value * @return {number} Clamped value.
*/ */
function clamp(value, min, max) { function clamp(value, min, max) {
return value <= min ? min : value >= max ? max : value; return value <= min ? min : value >= max ? max : value;
@ -60,15 +68,15 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
* Returns the required delta to fit range 1 into range 2. * Returns the required delta to fit range 1 into range 2.
* In case of range 1 is bigger than range 2 returns delta to fit most out of range part. * In case of range 1 is bigger than range 2 returns delta to fit most out of range part.
* *
* @param {number} begin1 begining of range 1 * @param {number} begin1 - Begining of range 1.
* @param {number} end1 ending of range 1 * @param {number} end1 - Ending of range 1.
* @param {number} begin2 begining of range 2 * @param {number} begin2 - Begining of range 2.
* @param {number} end2 ending of range 2 * @param {number} end2 - Ending of range 2.
* @return {number} delta: <0 move range1 to the left, >0 - to the right * @return {number} Delta: <0 move range1 to the left, >0 - to the right.
*/ */
function fitRange(begin1, end1, begin2, end2) { function fitRange(begin1, end1, begin2, end2) {
var delta1 = begin1 - begin2; const delta1 = begin1 - begin2;
var delta2 = end2 - end1; const delta2 = end2 - end1;
if (delta1 < 0 && delta1 < delta2) { if (delta1 < 0 && delta1 < delta2) {
return -delta1; return -delta1;
} else if (delta2 < 0) { } else if (delta2 < 0) {
@ -80,13 +88,21 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
/** /**
* Ease value. * Ease value.
* *
* @param {number} t value in range [0, 1] * @param {number} t - Value in range [0, 1].
* @return {number} eased value in range [0, 1] * @return {number} Eased value in range [0, 1].
*/ */
function ease(t) { function ease(t) {
return t*(2 - t); // easeOutQuad === ease-out return t*(2 - t); // easeOutQuad === ease-out
} }
/**
* @typedef {Object} Rect
* @property {number} left - X coordinate of top-left corner.
* @property {number} top - Y coordinate of top-left corner.
* @property {number} width - Width.
* @property {number} height - Height.
*/
/** /**
* Document scroll wrapper helps to unify scrolling and fix issues of some browsers. * Document scroll wrapper helps to unify scrolling and fix issues of some browsers.
* *
@ -100,41 +116,68 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
* *
* Tizen 5 Browser/Native: scrolls documentElement (and window); has a document.scrollingElement * Tizen 5 Browser/Native: scrolls documentElement (and window); has a document.scrollingElement
*/ */
function DocumentScroller() { class DocumentScroller {
} /**
* Horizontal scroll position.
DocumentScroller.prototype = { * @type {number}
*/
get scrollLeft() { get scrollLeft() {
return window.pageXOffset; return window.pageXOffset;
}, }
set scrollLeft(val) { set scrollLeft(val) {
window.scroll(val, window.pageYOffset); window.scroll(val, window.pageYOffset);
}, }
/**
* Vertical scroll position.
* @type {number}
*/
get scrollTop() { get scrollTop() {
return window.pageYOffset; return window.pageYOffset;
}, }
set scrollTop(val) { set scrollTop(val) {
window.scroll(window.pageXOffset, val); window.scroll(window.pageXOffset, val);
}, }
/**
* Horizontal scroll size (scroll width).
* @type {number}
*/
get scrollWidth() { get scrollWidth() {
return Math.max(document.documentElement.scrollWidth, document.body.scrollWidth); return Math.max(document.documentElement.scrollWidth, document.body.scrollWidth);
}, }
/**
* Vertical scroll size (scroll height).
* @type {number}
*/
get scrollHeight() { get scrollHeight() {
return Math.max(document.documentElement.scrollHeight, document.body.scrollHeight); return Math.max(document.documentElement.scrollHeight, document.body.scrollHeight);
}, }
/**
* Horizontal client size (client width).
* @type {number}
*/
get clientWidth() { get clientWidth() {
return Math.min(document.documentElement.clientWidth, document.body.clientWidth); return Math.min(document.documentElement.clientWidth, document.body.clientWidth);
}, }
/**
* Vertical client size (client height).
* @type {number}
*/
get clientHeight() { get clientHeight() {
return Math.min(document.documentElement.clientHeight, document.body.clientHeight); return Math.min(document.documentElement.clientHeight, document.body.clientHeight);
}, }
getBoundingClientRect: function() { /**
* Returns bounding client rect.
* @return {Rect} Bounding client rect.
*/
getBoundingClientRect() {
// Make valid viewport coordinates: documentElement.getBoundingClientRect returns rect of entire document relative to viewport // Make valid viewport coordinates: documentElement.getBoundingClientRect returns rect of entire document relative to viewport
return { return {
left: 0, left: 0,
@ -142,26 +185,34 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
width: this.clientWidth, width: this.clientWidth,
height: this.clientHeight height: this.clientHeight
}; };
},
scrollTo: function() {
window.scrollTo.apply(window, arguments);
} }
};
var documentScroller = new DocumentScroller();
/** /**
* Returns parent element that can be scrolled. If no such, returns documentElement. * Scrolls window.
* @param {...mixed} args See window.scrollTo.
*/
scrollTo() {
window.scrollTo.apply(window, arguments);
}
}
/**
* Default (document) scroller.
*/
const documentScroller = new DocumentScroller();
/**
* Returns parent element that can be scrolled. If no such, returns document scroller.
* *
* @param {HTMLElement} element element for which parent is being searched * @param {HTMLElement} element - Element for which parent is being searched.
* @param {boolean} vertical search for vertical scrollable parent * @param {boolean} vertical - Search for vertical scrollable parent.
* @param {HTMLElement|DocumentScroller} Parent element that can be scrolled or document scroller.
*/ */
function getScrollableParent(element, vertical) { function getScrollableParent(element, vertical) {
if (element) { if (element) {
var nameScroll = "scrollWidth"; let nameScroll = "scrollWidth";
var nameClient = "clientWidth"; let nameClient = "clientWidth";
var nameClass = "scrollX"; let nameClass = "scrollX";
if (vertical) { if (vertical) {
nameScroll = "scrollHeight"; nameScroll = "scrollHeight";
@ -169,7 +220,7 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
nameClass = "scrollY"; nameClass = "scrollY";
} }
var parent = element.parentElement; let parent = element.parentElement;
while (parent) { while (parent) {
// Skip 'emby-scroller' because it scrolls by itself // Skip 'emby-scroller' because it scrolls by itself
@ -187,20 +238,20 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
/** /**
* @typedef {Object} ScrollerData * @typedef {Object} ScrollerData
* @property {number} scrollPos current scroll position * @property {number} scrollPos - Current scroll position.
* @property {number} scrollSize scroll size * @property {number} scrollSize - Scroll size.
* @property {number} clientSize client size * @property {number} clientSize - Client size.
*/ */
/** /**
* Returns scroll data for specified orientation. * Returns scroller data for specified orientation.
* *
* @param {HTMLElement} scroller scroller * @param {HTMLElement} scroller - Scroller.
* @param {boolean} vertical vertical scroll data * @param {boolean} vertical - Vertical scroller data.
* @return {ScrollerData} scroll data * @return {ScrollerData} Scroller data.
*/ */
function getScrollerData(scroller, vertical) { function getScrollerData(scroller, vertical) {
var data = {}; let data = {};
if (!vertical) { if (!vertical) {
data.scrollPos = scroller.scrollLeft; data.scrollPos = scroller.scrollLeft;
@ -218,14 +269,14 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
/** /**
* Returns position of child of scroller for specified orientation. * Returns position of child of scroller for specified orientation.
* *
* @param {HTMLElement} scroller scroller * @param {HTMLElement} scroller - Scroller.
* @param {HTMLElement} element child of scroller * @param {HTMLElement} element - Child of scroller.
* @param {boolean} vertical vertical scroll * @param {boolean} vertical - Vertical scroll.
* @return {number} child position * @return {number} Child position.
*/ */
function getScrollerChildPos(scroller, element, vertical) { function getScrollerChildPos(scroller, element, vertical) {
var elementRect = element.getBoundingClientRect(); const elementRect = element.getBoundingClientRect();
var scrollerRect = scroller.getBoundingClientRect(); const scrollerRect = scroller.getBoundingClientRect();
if (!vertical) { if (!vertical) {
return scroller.scrollLeft + elementRect.left - scrollerRect.left; return scroller.scrollLeft + elementRect.left - scrollerRect.left;
@ -237,21 +288,21 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
/** /**
* Returns scroll position for element. * Returns scroll position for element.
* *
* @param {ScrollerData} scrollerData scroller data * @param {ScrollerData} scrollerData - Scroller data.
* @param {number} elementPos child element position * @param {number} elementPos - Child element position.
* @param {number} elementSize child element size * @param {number} elementSize - Child element size.
* @param {boolean} centered scroll to center * @param {boolean} centered - Scroll to center.
* @return {number} scroll position * @return {number} Scroll position.
*/ */
function calcScroll(scrollerData, elementPos, elementSize, centered) { function calcScroll(scrollerData, elementPos, elementSize, centered) {
var maxScroll = scrollerData.scrollSize - scrollerData.clientSize; const maxScroll = scrollerData.scrollSize - scrollerData.clientSize;
var scroll; let scroll;
if (centered) { if (centered) {
scroll = elementPos + (elementSize - scrollerData.clientSize) / 2; scroll = elementPos + (elementSize - scrollerData.clientSize) / 2;
} else { } else {
var delta = fitRange(elementPos, elementPos + elementSize - 1, scrollerData.scrollPos, scrollerData.scrollPos + scrollerData.clientSize - 1); const delta = fitRange(elementPos, elementPos + elementSize - 1, scrollerData.scrollPos, scrollerData.scrollPos + scrollerData.clientSize - 1);
scroll = scrollerData.scrollPos - delta; scroll = scrollerData.scrollPos - delta;
} }
@ -261,14 +312,14 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
/** /**
* Calls scrollTo function in proper way. * Calls scrollTo function in proper way.
* *
* @param {HTMLElement} scroller scroller * @param {HTMLElement} scroller - Scroller.
* @param {ScrollToOptions} options scroll options * @param {ScrollToOptions} options - Scroll options.
*/ */
function scrollToHelper(scroller, options) { function scrollToHelper(scroller, options) {
if ("scrollTo" in scroller) { if ("scrollTo" in scroller) {
if (!supportsScrollToOptions) { if (!supportsScrollToOptions) {
var scrollX = (options.left !== undefined ? options.left : scroller.scrollLeft); const scrollX = (options.left !== undefined ? options.left : scroller.scrollLeft);
var scrollY = (options.top !== undefined ? options.top : scroller.scrollTop); const scrollY = (options.top !== undefined ? options.top : scroller.scrollTop);
scroller.scrollTo(scrollX, scrollY); scroller.scrollTo(scrollX, scrollY);
} else { } else {
scroller.scrollTo(options); scroller.scrollTo(options);
@ -286,14 +337,14 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
/** /**
* Performs built-in scroll. * Performs built-in scroll.
* *
* @param {HTMLElement} xScroller horizontal scroller * @param {HTMLElement} xScroller - Horizontal scroller.
* @param {number} scrollX horizontal coordinate * @param {number} scrollX - Horizontal coordinate.
* @param {HTMLElement} yScroller vertical scroller * @param {HTMLElement} yScroller - Vertical scroller.
* @param {number} scrollY vertical coordinate * @param {number} scrollY - Vertical coordinate.
* @param {boolean} smooth smooth scrolling * @param {boolean} smooth - Smooth scrolling.
*/ */
function builtinScroll(xScroller, scrollX, yScroller, scrollY, smooth) { function builtinScroll(xScroller, scrollX, yScroller, scrollY, smooth) {
var scrollBehavior = smooth ? "smooth" : "instant"; const scrollBehavior = smooth ? "smooth" : "instant";
if (xScroller !== yScroller) { if (xScroller !== yScroller) {
scrollToHelper(xScroller, {left: scrollX, behavior: scrollBehavior}); scrollToHelper(xScroller, {left: scrollX, behavior: scrollBehavior});
@ -303,7 +354,10 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
} }
} }
var scrollTimer; /**
* Requested frame for animated scroll.
*/
let scrollTimer;
/** /**
* Resets scroll timer to stop scrolling. * Resets scroll timer to stop scrolling.
@ -316,29 +370,29 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
/** /**
* Performs animated scroll. * Performs animated scroll.
* *
* @param {HTMLElement} xScroller horizontal scroller * @param {HTMLElement} xScroller - Horizontal scroller.
* @param {number} scrollX horizontal coordinate * @param {number} scrollX - Horizontal coordinate.
* @param {HTMLElement} yScroller vertical scroller * @param {HTMLElement} yScroller - Vertical scroller.
* @param {number} scrollY vertical coordinate * @param {number} scrollY - Vertical coordinate.
*/ */
function animateScroll(xScroller, scrollX, yScroller, scrollY) { function animateScroll(xScroller, scrollX, yScroller, scrollY) {
var ox = xScroller.scrollLeft; const ox = xScroller.scrollLeft;
var oy = yScroller.scrollTop; const oy = yScroller.scrollTop;
var dx = scrollX - ox; const dx = scrollX - ox;
var dy = scrollY - oy; const dy = scrollY - oy;
if (Math.abs(dx) < Epsilon && Math.abs(dy) < Epsilon) { if (Math.abs(dx) < Epsilon && Math.abs(dy) < Epsilon) {
return; return;
} }
var start; let start;
function scrollAnim(currentTimestamp) { function scrollAnim(currentTimestamp) {
start = start || currentTimestamp; start = start || currentTimestamp;
var k = Math.min(1, (currentTimestamp - start) / ScrollTime); let k = Math.min(1, (currentTimestamp - start) / ScrollTime);
if (k === 1) { if (k === 1) {
resetScrollTimer(); resetScrollTimer();
@ -348,8 +402,8 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
k = ease(k); k = ease(k);
var x = ox + dx*k; const x = ox + dx*k;
var y = oy + dy*k; const y = oy + dy*k;
builtinScroll(xScroller, x, yScroller, y, false); builtinScroll(xScroller, x, yScroller, y, false);
@ -362,11 +416,11 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
/** /**
* Performs scroll. * Performs scroll.
* *
* @param {HTMLElement} xScroller horizontal scroller * @param {HTMLElement} xScroller - Horizontal scroller.
* @param {number} scrollX horizontal coordinate * @param {number} scrollX - Horizontal coordinate.
* @param {HTMLElement} yScroller vertical scroller * @param {HTMLElement} yScroller - Vertical scroller.
* @param {number} scrollY vertical coordinate * @param {number} scrollY - Vertical coordinate.
* @param {boolean} smooth smooth scrolling * @param {boolean} smooth - Smooth scrolling.
*/ */
function doScroll(xScroller, scrollX, yScroller, scrollY, smooth) { function doScroll(xScroller, scrollX, yScroller, scrollY, smooth) {
@ -403,26 +457,26 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
/** /**
* Returns true if scroll manager is enabled. * Returns true if scroll manager is enabled.
*/ */
var isEnabled = function() { export function isEnabled() {
return layoutManager.tv; return layoutManager.tv;
}; }
/** /**
* Scrolls the document to a given position. * Scrolls the document to a given position.
* *
* @param {number} scrollX horizontal coordinate * @param {number} scrollX - Horizontal coordinate.
* @param {number} scrollY vertical coordinate * @param {number} scrollY - Vertical coordinate.
* @param {boolean} [smooth=false] smooth scrolling * @param {boolean} [smooth=false] - Smooth scrolling.
*/ */
var scrollTo = function(scrollX, scrollY, smooth) { export function scrollTo(scrollX, scrollY, smooth) {
smooth = !!smooth; smooth = !!smooth;
// Scroller is document itself by default // Scroller is document itself by default
var scroller = getScrollableParent(null, false); const scroller = getScrollableParent(null, false);
var xScrollerData = getScrollerData(scroller, false); const xScrollerData = getScrollerData(scroller, false);
var yScrollerData = getScrollerData(scroller, true); const yScrollerData = getScrollerData(scroller, true);
scrollX = clamp(Math.round(scrollX), 0, xScrollerData.scrollSize - xScrollerData.clientSize); scrollX = clamp(Math.round(scrollX), 0, xScrollerData.scrollSize - xScrollerData.clientSize);
scrollY = clamp(Math.round(scrollY), 0, yScrollerData.scrollSize - yScrollerData.clientSize); scrollY = clamp(Math.round(scrollY), 0, yScrollerData.scrollSize - yScrollerData.clientSize);
@ -433,39 +487,39 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
/** /**
* Scrolls the document to a given element. * Scrolls the document to a given element.
* *
* @param {HTMLElement} element target element of scroll task * @param {HTMLElement} element - Target element of scroll task.
* @param {boolean} [smooth=false] smooth scrolling * @param {boolean} [smooth=false] - Smooth scrolling.
*/ */
var scrollToElement = function(element, smooth) { export function scrollToElement(element, smooth) {
smooth = !!smooth; smooth = !!smooth;
var scrollCenterX = true; let scrollCenterX = true;
var scrollCenterY = true; let scrollCenterY = true;
var offsetParent = element.offsetParent; const offsetParent = element.offsetParent;
// In Firefox offsetParent.offsetParent is BODY // In Firefox offsetParent.offsetParent is BODY
var isFixed = offsetParent && (!offsetParent.offsetParent || window.getComputedStyle(offsetParent).position === "fixed"); const isFixed = offsetParent && (!offsetParent.offsetParent || window.getComputedStyle(offsetParent).position === "fixed");
// Scroll fixed elements to nearest edge (or do not scroll at all) // Scroll fixed elements to nearest edge (or do not scroll at all)
if (isFixed) { if (isFixed) {
scrollCenterX = scrollCenterY = false; scrollCenterX = scrollCenterY = false;
} }
var xScroller = getScrollableParent(element, false); const xScroller = getScrollableParent(element, false);
var yScroller = getScrollableParent(element, true); const yScroller = getScrollableParent(element, true);
var elementRect = element.getBoundingClientRect(); const elementRect = element.getBoundingClientRect();
var xScrollerData = getScrollerData(xScroller, false); const xScrollerData = getScrollerData(xScroller, false);
var yScrollerData = getScrollerData(yScroller, true); const yScrollerData = getScrollerData(yScroller, true);
var xPos = getScrollerChildPos(xScroller, element, false); const xPos = getScrollerChildPos(xScroller, element, false);
var yPos = getScrollerChildPos(yScroller, element, true); const yPos = getScrollerChildPos(yScroller, element, true);
var scrollX = calcScroll(xScrollerData, xPos, elementRect.width, scrollCenterX); const scrollX = calcScroll(xScrollerData, xPos, elementRect.width, scrollCenterX);
var scrollY = calcScroll(yScrollerData, yPos, elementRect.height, scrollCenterY); let scrollY = calcScroll(yScrollerData, yPos, elementRect.height, scrollCenterY);
// HACK: Scroll to top for top menu because it is hidden // HACK: Scroll to top for top menu because it is hidden
// FIXME: Need a marker to scroll top/bottom // FIXME: Need a marker to scroll top/bottom
@ -490,9 +544,8 @@ define(["dom", "browser", "layoutManager"], function (dom, browser, layoutManage
}, {capture: true}); }, {capture: true});
} }
return { export default {
isEnabled: isEnabled, isEnabled: isEnabled,
scrollTo: scrollTo, scrollTo: scrollTo,
scrollToElement: scrollToElement scrollToElement: scrollToElement
}; };
});

View file

@ -116,8 +116,8 @@ define(['apphost', 'userSettings', 'browser', 'events', 'pluginManager', 'backdr
var linkUrl = info.stylesheetPath; var linkUrl = info.stylesheetPath;
unloadTheme(); unloadTheme();
var link = document.createElement('link');
var link = document.createElement('link');
link.setAttribute('rel', 'stylesheet'); link.setAttribute('rel', 'stylesheet');
link.setAttribute('type', 'text/css'); link.setAttribute('type', 'text/css');
link.onload = function () { link.onload = function () {

View file

@ -2,15 +2,11 @@ define(['require', 'globalize', 'appSettings', 'apphost', 'focusManager', 'loadi
"use strict"; "use strict";
function populateLanguages(select, languages) { function populateLanguages(select, languages) {
var html = ""; var html = "";
html += "<option value=''>" + globalize.translate('AnyLanguage') + "</option>"; html += "<option value=''>" + globalize.translate('AnyLanguage') + "</option>";
for (var i = 0, length = languages.length; i < length; i++) { for (var i = 0, length = languages.length; i < length; i++) {
var culture = languages[i]; var culture = languages[i];
html += "<option value='" + culture.ThreeLetterISOLanguageName + "'>" + culture.DisplayName + "</option>"; html += "<option value='" + culture.ThreeLetterISOLanguageName + "'>" + culture.DisplayName + "</option>";
} }
@ -18,7 +14,6 @@ define(['require', 'globalize', 'appSettings', 'apphost', 'focusManager', 'loadi
} }
function getSubtitleAppearanceObject(context) { function getSubtitleAppearanceObject(context) {
var appearanceSettings = {}; var appearanceSettings = {};
appearanceSettings.textSize = context.querySelector('#selectTextSize').value; appearanceSettings.textSize = context.querySelector('#selectTextSize').value;
@ -102,14 +97,12 @@ define(['require', 'globalize', 'appSettings', 'apphost', 'focusManager', 'loadi
} }
function onSubmit(e) { function onSubmit(e) {
var self = this; var self = this;
var apiClient = connectionManager.getApiClient(self.options.serverId); var apiClient = connectionManager.getApiClient(self.options.serverId);
var userId = self.options.userId; var userId = self.options.userId;
var userSettings = self.options.userSettings; var userSettings = self.options.userSettings;
userSettings.setUserInfo(userId, apiClient).then(function () { userSettings.setUserInfo(userId, apiClient).then(function () {
var enableSaveConfirmation = self.options.enableSaveConfirmation; var enableSaveConfirmation = self.options.enableSaveConfirmation;
save(self, self.options.element, userId, userSettings, apiClient, enableSaveConfirmation); save(self, self.options.element, userId, userSettings, apiClient, enableSaveConfirmation);
}); });
@ -118,6 +111,7 @@ define(['require', 'globalize', 'appSettings', 'apphost', 'focusManager', 'loadi
if (e) { if (e) {
e.preventDefault(); e.preventDefault();
} }
return false; return false;
} }
@ -197,9 +191,7 @@ define(['require', 'globalize', 'appSettings', 'apphost', 'focusManager', 'loadi
var userSettings = self.options.userSettings; var userSettings = self.options.userSettings;
apiClient.getUser(userId).then(function (user) { apiClient.getUser(userId).then(function (user) {
userSettings.setUserInfo(userId, apiClient).then(function () { userSettings.setUserInfo(userId, apiClient).then(function () {
self.dataLoaded = true; self.dataLoaded = true;
var appearanceSettings = userSettings.getSubtitleAppearanceSettings(self.options.appearanceKey); var appearanceSettings = userSettings.getSubtitleAppearanceSettings(self.options.appearanceKey);
@ -214,7 +206,6 @@ define(['require', 'globalize', 'appSettings', 'apphost', 'focusManager', 'loadi
}; };
SubtitleSettings.prototype.destroy = function () { SubtitleSettings.prototype.destroy = function () {
this.options = null; this.options = null;
}; };

View file

@ -1,7 +1,5 @@
<form style="margin:0 auto;"> <form style="margin:0 auto;">
<div class="verticalSection"> <div class="verticalSection">
<h2 class="sectionTitle"> <h2 class="sectionTitle">
${Subtitles} ${Subtitles}
</h2> </h2>
@ -9,6 +7,7 @@
<div class="selectContainer"> <div class="selectContainer">
<select is="emby-select" id="selectSubtitleLanguage" label="${LabelPreferredSubtitleLanguage}"></select> <select is="emby-select" id="selectSubtitleLanguage" label="${LabelPreferredSubtitleLanguage}"></select>
</div> </div>
<div class="selectContainer"> <div class="selectContainer">
<select is="emby-select" id="selectSubtitlePlaybackMode" label="${LabelSubtitlePlaybackMode}"> <select is="emby-select" id="selectSubtitlePlaybackMode" label="${LabelSubtitlePlaybackMode}">
<option value="Default">${Default}</option> <option value="Default">${Default}</option>
@ -23,6 +22,7 @@
<div class="fieldDescription subtitlesOnlyForcedHelp subtitlesHelp hide">${OnlyForcedSubtitlesHelp}</div> <div class="fieldDescription subtitlesOnlyForcedHelp subtitlesHelp hide">${OnlyForcedSubtitlesHelp}</div>
<div class="fieldDescription subtitlesNoneHelp subtitlesHelp hide">${NoSubtitlesHelp}</div> <div class="fieldDescription subtitlesNoneHelp subtitlesHelp hide">${NoSubtitlesHelp}</div>
</div> </div>
<div class="selectContainer fldBurnIn hide"> <div class="selectContainer fldBurnIn hide">
<select is="emby-select" id="selectSubtitleBurnIn" label="${LabelBurnSubtitles}"> <select is="emby-select" id="selectSubtitleBurnIn" label="${LabelBurnSubtitles}">
<option value="">${Auto}</option> <option value="">${Auto}</option>
@ -34,7 +34,6 @@
</div> </div>
<div class="verticalSection subtitleAppearanceSection hide"> <div class="verticalSection subtitleAppearanceSection hide">
<h2 class="sectionTitle"> <h2 class="sectionTitle">
${HeaderSubtitleAppearance} ${HeaderSubtitleAppearance}
</h2> </h2>
@ -61,6 +60,7 @@
<option value="extralarge">${ExtraLarge}</option> <option value="extralarge">${ExtraLarge}</option>
</select> </select>
</div> </div>
<div class="selectContainer"> <div class="selectContainer">
<select is="emby-select" id="selectFont" label="${LabelFont}"> <select is="emby-select" id="selectFont" label="${LabelFont}">
<option value="">${Default}</option> <option value="">${Default}</option>
@ -71,12 +71,15 @@
<option value="smallcaps">${SmallCaps}</option> <option value="smallcaps">${SmallCaps}</option>
</select> </select>
</div> </div>
<div class="inputContainer hide"> <div class="inputContainer hide">
<input is="emby-input" id="inputTextBackground" label="${LabelTextBackgroundColor}" type="text" /> <input is="emby-input" id="inputTextBackground" label="${LabelTextBackgroundColor}" type="text" />
</div> </div>
<div class="inputContainer hide"> <div class="inputContainer hide">
<input is="emby-input" id="inputTextColor" label="${LabelTextColor}" type="text" /> <input is="emby-input" id="inputTextColor" label="${LabelTextColor}" type="text" />
</div> </div>
<div class="selectContainer"> <div class="selectContainer">
<select is="emby-select" id="selectDropShadow" label="${LabelDropShadow}"> <select is="emby-select" id="selectDropShadow" label="${LabelDropShadow}">
<option value="none">${None}</option> <option value="none">${None}</option>

3
src/config.example.json Normal file
View file

@ -0,0 +1,3 @@
{
"multiserver": true
}

View file

@ -433,14 +433,10 @@ define(['browser'], function (browser) {
var supportsDts = browser.tizen || browser.orsay || browser.web0s || options.supportsDts; var supportsDts = browser.tizen || browser.orsay || browser.web0s || options.supportsDts;
if (self.tizen && self.tizen.systeminfo) {
var v = tizen.systeminfo.getCapability('http://tizen.org/feature/platform.version');
// DTS audio not supported in 2018 models (Tizen 4.0) // DTS audio not supported in 2018 models (Tizen 4.0)
if (v && parseFloat(v) >= parseFloat('4.0')) { if (browser.tizenVersion >= 4) {
supportsDts = false; supportsDts = false;
} }
}
if (supportsDts) { if (supportsDts) {
videoAudioCodecs.push('dca'); videoAudioCodecs.push('dca');
@ -766,6 +762,11 @@ define(['browser'], function (browser) {
maxH264Level = 51; maxH264Level = 51;
} }
// Support H264 Level 52 (Tizen 5.0) - app only
if (browser.tizenVersion >= 5 && window.NativeShell) {
maxH264Level = 52;
}
if (browser.tizen || browser.orsay || if (browser.tizen || browser.orsay ||
videoTestElement.canPlayType('video/mp4; codecs="avc1.6e0033"').replace(/no/, '')) { videoTestElement.canPlayType('video/mp4; codecs="avc1.6e0033"').replace(/no/, '')) {

View file

@ -20,6 +20,14 @@ define(['appStorage', 'events'], function (appStorage, events) {
return this.get('enableAutoLogin') !== 'false'; return this.get('enableAutoLogin') !== 'false';
}; };
AppSettings.prototype.enableSystemExternalPlayers = function (val) {
if (val !== null) {
this.set('enableSystemExternalPlayers', val.toString());
}
return this.get('enableSystemExternalPlayers') === 'true';
};
AppSettings.prototype.enableAutomaticBitrateDetection = function (isInNetwork, mediaType, val) { AppSettings.prototype.enableAutomaticBitrateDetection = function (isInNetwork, mediaType, val) {
var key = 'enableautobitratebitrate-' + mediaType + '-' + isInNetwork; var key = 'enableautobitratebitrate-' + mediaType + '-' + isInNetwork;
if (val != null) { if (val != null) {
@ -123,13 +131,5 @@ define(['appStorage', 'events'], function (appStorage, events) {
return appStorage.getItem(getKey(name, userId)); return appStorage.getItem(getKey(name, userId));
}; };
AppSettings.prototype.enableSystemExternalPlayers = function (val) {
if (val != null) {
this.set('enableSystemExternalPlayers', val.toString());
}
return this.get('enableSystemExternalPlayers') === 'true';
};
return new AppSettings(); return new AppSettings();
}); });

View file

@ -0,0 +1,15 @@
let data;
function getConfig() {
if (data) return Promise.resolve(data);
return fetch("/config.json?nocache=" + new Date().getUTCMilliseconds()).then(function (response) {
data = response.json();
return data;
});
}
export function enableMultiServer() {
return getConfig().then(config => {
return config.multiserver;
});
}

View file

@ -766,6 +766,7 @@ var AppInfo = {};
define("emby-textarea", [elementsPath + "/emby-textarea/emby-textarea"], returnFirstDependency); define("emby-textarea", [elementsPath + "/emby-textarea/emby-textarea"], returnFirstDependency);
define("emby-toggle", [elementsPath + "/emby-toggle/emby-toggle"], returnFirstDependency); define("emby-toggle", [elementsPath + "/emby-toggle/emby-toggle"], returnFirstDependency);
define("webSettings", [scriptsPath + "/settings/webSettings"], returnFirstDependency);
define("appSettings", [scriptsPath + "/settings/appSettings"], returnFirstDependency); define("appSettings", [scriptsPath + "/settings/appSettings"], returnFirstDependency);
define("userSettingsBuilder", [scriptsPath + "/settings/userSettingsBuilder"], returnFirstDependency); define("userSettingsBuilder", [scriptsPath + "/settings/userSettingsBuilder"], returnFirstDependency);
define("userSettings", ["userSettingsBuilder"], function(userSettingsBuilder) { define("userSettings", ["userSettingsBuilder"], function(userSettingsBuilder) {

View file

@ -918,7 +918,7 @@
"HeaderFavoriteEpisodes": "الحلقات المفضلة", "HeaderFavoriteEpisodes": "الحلقات المفضلة",
"HeaderFavoriteArtists": "الفنانون المفضلون", "HeaderFavoriteArtists": "الفنانون المفضلون",
"Shows": "الحلقات", "Shows": "الحلقات",
"Books": "كتب", "Books": "الكتب",
"ValueSpecialEpisodeName": "مميز - {0}", "ValueSpecialEpisodeName": "مميز - {0}",
"HeaderFavoriteAlbums": "الألبومات المفضلة", "HeaderFavoriteAlbums": "الألبومات المفضلة",
"HeaderAlbumArtists": "فناني الألبومات", "HeaderAlbumArtists": "فناني الألبومات",

View file

@ -10,7 +10,7 @@
"All": "Всички", "All": "Всички",
"AllLibraries": "Всички библиотеки", "AllLibraries": "Всички библиотеки",
"Art": "Картина", "Art": "Картина",
"Artists": "Изпълнители", "Artists": "Артисти",
"AttributeNew": "Нови", "AttributeNew": "Нови",
"Audio": "Звук", "Audio": "Звук",
"Auto": "Автоматично", "Auto": "Автоматично",
@ -303,9 +303,9 @@
"LabelCriticRating": "Оценка на критиците:", "LabelCriticRating": "Оценка на критиците:",
"LabelCurrentPassword": "Текуща парола:", "LabelCurrentPassword": "Текуща парола:",
"LabelCustomCertificatePath": "Път към потребителския сертификат:", "LabelCustomCertificatePath": "Път към потребителския сертификат:",
"LabelCustomCertificatePathHelp": "Път до файл с шифровъчен стандарт №12, съдържащ сертификат и частен ключ за поддръжка на протокол TLS на собствен домейн.", "LabelCustomCertificatePathHelp": "Път до файл с шифровъчен стандарт №12 (PKCS #12), съдържащ сертификат и частен ключ за поддръжка на протокол TLS на собствен домейн.",
"LabelCustomCss": "CSS по избор:", "LabelCustomCss": "CSS по избор:",
"LabelCustomCssHelp": "Използвайте собствен CSS към уеб интерфейса.", "LabelCustomCssHelp": "Използвайте собствен CSS към мрежовия интерфейс.",
"LabelCustomDeviceDisplayName": "Показвано име:", "LabelCustomDeviceDisplayName": "Показвано име:",
"LabelCustomRating": "Оценка по избор:", "LabelCustomRating": "Оценка по избор:",
"LabelDashboardTheme": "Облик на сървърното табло:", "LabelDashboardTheme": "Облик на сървърното табло:",
@ -834,5 +834,12 @@
"AllowOnTheFlySubtitleExtraction": "Позволява моментално извличане на поднадписи", "AllowOnTheFlySubtitleExtraction": "Позволява моментално извличане на поднадписи",
"AllowHWTranscodingHelp": "Позволява на тунера да прекодира моментално. Това може да помогне за редуциране на прекодирането от сървъра.", "AllowHWTranscodingHelp": "Позволява на тунера да прекодира моментално. Това може да помогне за редуциране на прекодирането от сървъра.",
"AddItemToCollectionHelp": "Добавяне към колекция чрез търсенето им и използване на дясно-щракване с мишката или контекстното меню.", "AddItemToCollectionHelp": "Добавяне към колекция чрез търсенето им и използване на дясно-щракване с мишката или контекстното меню.",
"Absolute": "Aбсолютен" "Absolute": "Aбсолютен",
"LabelLanNetworks": "Локални мрежи:",
"LabelKodiMetadataSaveImagePathsHelp": "Препоръчително е ако имате изображения, пътят към които не е съобразен с изискванията на Коди.",
"LabelKodiMetadataSaveImagePaths": "Записване на пътеките към изображенията в nfo файловете",
"LabelChannels": "Канали:",
"DropShadow": "Сянка",
"Raised": "Повишено",
"OptionResElement": "рес. елемент"
} }

View file

@ -1401,7 +1401,7 @@
"TitleSupport": "Hilfe", "TitleSupport": "Hilfe",
"Whitelist": "Erlaubt", "Whitelist": "Erlaubt",
"AuthProviderHelp": "Auswählen eines Authentifizierungsanbieter, der zur Authentifizierung des Passworts dieses Benutzes verwendet werden soll.", "AuthProviderHelp": "Auswählen eines Authentifizierungsanbieter, der zur Authentifizierung des Passworts dieses Benutzes verwendet werden soll.",
"Features": "Features", "Features": "Funktionen",
"HeaderFavoriteBooks": "Lieblingsbücher", "HeaderFavoriteBooks": "Lieblingsbücher",
"HeaderFavoriteMovies": "Lieblingsfilme", "HeaderFavoriteMovies": "Lieblingsfilme",
"HeaderFavoriteShows": "Lieblingsserien", "HeaderFavoriteShows": "Lieblingsserien",

View file

@ -11,11 +11,13 @@
"AdditionalNotificationServices": "Browse the plugin catalog to install additional notification services.", "AdditionalNotificationServices": "Browse the plugin catalog to install additional notification services.",
"AirDate": "Air date", "AirDate": "Air date",
"Aired": "Aired", "Aired": "Aired",
"Album": "Album",
"AlbumArtist": "Album Artist",
"Albums": "Albums", "Albums": "Albums",
"Alerts": "Alerts", "Alerts": "Alerts",
"All": "All", "All": "All",
"AllChannels": "All channels", "AllChannels": "All channels",
"AllComplexFormats": "All complex formats (ASS, SSA, VOBSUB, PGS, SUB/IDX, etc.)", "AllComplexFormats": "All Complex Formats (ASS, SSA, VOBSUB, PGS, SUB, IDX)",
"AllEpisodes": "All episodes", "AllEpisodes": "All episodes",
"AllLanguages": "All languages", "AllLanguages": "All languages",
"AllLibraries": "All libraries", "AllLibraries": "All libraries",
@ -29,12 +31,13 @@
"AllowRemoteAccess": "Allow remote connections to this Jellyfin Server.", "AllowRemoteAccess": "Allow remote connections to this Jellyfin Server.",
"AllowRemoteAccessHelp": "If unchecked, all remote connections will be blocked.", "AllowRemoteAccessHelp": "If unchecked, all remote connections will be blocked.",
"AllowedRemoteAddressesHelp": "Comma separated list of IP addresses or IP/netmask entries for networks that will be allowed to connect remotely. If left blank, all remote addresses will be allowed.", "AllowedRemoteAddressesHelp": "Comma separated list of IP addresses or IP/netmask entries for networks that will be allowed to connect remotely. If left blank, all remote addresses will be allowed.",
"AlwaysPlaySubtitles": "Always play subtitles", "AlwaysPlaySubtitles": "Always Play",
"AlwaysPlaySubtitlesHelp": "Subtitles matching the language preference will be loaded regardless of the audio language.", "AlwaysPlaySubtitlesHelp": "Subtitles matching the language preference will be loaded regardless of the audio language.",
"AnyLanguage": "Any language", "AnyLanguage": "Any Language",
"Anytime": "Anytime", "Anytime": "Anytime",
"AroundTime": "Around {0}", "AroundTime": "Around {0}",
"Art": "Art", "Art": "Art",
"Artist": "Artist",
"Artists": "Artists", "Artists": "Artists",
"AsManyAsPossible": "As many as possible", "AsManyAsPossible": "As many as possible",
"Ascending": "Ascending", "Ascending": "Ascending",
@ -55,10 +58,11 @@
"BookLibraryHelp": "Audio and text books are supported. Review the {0}book naming guide{1}.", "BookLibraryHelp": "Audio and text books are supported. Review the {0}book naming guide{1}.",
"Books": "Books", "Books": "Books",
"Box": "Box", "Box": "Box",
"BoxSet": "Box Set",
"BoxRear": "Box (rear)", "BoxRear": "Box (rear)",
"Browse": "Browse", "Browse": "Browse",
"BrowsePluginCatalogMessage": "Browse our plugin catalog to view available plugins.", "BrowsePluginCatalogMessage": "Browse our plugin catalog to view available plugins.",
"BurnSubtitlesHelp": "Determines if the server should burn in subtitles when converting video depending on the subtitle format. Avoiding burning in subtitles will improve server performance. Select Auto to burn image based formats (VOBSUB, PGS, SUB/IDX, etc) and certain ASS/SSA subtitles.", "BurnSubtitlesHelp": "Determines if the server should burn in subtitles when transcoding videos. Avoiding this will greatly improve performance. Select Auto to burn image based formats (VOBSUB, PGS, SUB, IDX) and certain ASS or SSA subtitles.",
"ButtonAdd": "Add", "ButtonAdd": "Add",
"ButtonAddImage": "Add Image", "ButtonAddImage": "Add Image",
"ButtonAddMediaLibrary": "Add Media Library", "ButtonAddMediaLibrary": "Add Media Library",
@ -202,7 +206,7 @@
"DisplayInOtherHomeScreenSections": "Display in home screen sections such as latest media and continue watching", "DisplayInOtherHomeScreenSections": "Display in home screen sections such as latest media and continue watching",
"DisplayMissingEpisodesWithinSeasons": "Display missing episodes within seasons", "DisplayMissingEpisodesWithinSeasons": "Display missing episodes within seasons",
"DisplayMissingEpisodesWithinSeasonsHelp": "This must also be enabled for TV libraries in the server configuration.", "DisplayMissingEpisodesWithinSeasonsHelp": "This must also be enabled for TV libraries in the server configuration.",
"DisplayModeHelp": "Select the type of screen you're running Jellyfin on.", "DisplayModeHelp": "Select the layout style you want for the interface.",
"DoNotRecord": "Do not record", "DoNotRecord": "Do not record",
"Down": "Down", "Down": "Down",
"Download": "Download", "Download": "Download",
@ -234,6 +238,7 @@
"EnableThemeVideosHelp": "Play theme videos in the background while browsing the library.", "EnableThemeVideosHelp": "Play theme videos in the background while browsing the library.",
"Ended": "Ended", "Ended": "Ended",
"EndsAtValue": "Ends at {0}", "EndsAtValue": "Ends at {0}",
"Episode": "Episode",
"Episodes": "Episodes", "Episodes": "Episodes",
"ErrorAddingListingsToSchedulesDirect": "There was an error adding the lineup to your Schedules Direct account. Schedules Direct only allows a limited number of lineups per account. You may need to log into the Schedules Direct website and remove others listings from your account before proceeding.", "ErrorAddingListingsToSchedulesDirect": "There was an error adding the lineup to your Schedules Direct account. Schedules Direct only allows a limited number of lineups per account. You may need to log into the Schedules Direct website and remove others listings from your account before proceeding.",
"ErrorAddingMediaPathToVirtualFolder": "There was an error adding the media path. Please ensure the path is valid and the Jellyfin Server process has access to that location.", "ErrorAddingMediaPathToVirtualFolder": "There was an error adding the media path. Please ensure the path is valid and the Jellyfin Server process has access to that location.",
@ -1016,6 +1021,7 @@
"MoveLeft": "Move left", "MoveLeft": "Move left",
"MoveRight": "Move right", "MoveRight": "Move right",
"MovieLibraryHelp": "Review the {0}movie naming guide{1}.", "MovieLibraryHelp": "Review the {0}movie naming guide{1}.",
"Movie": "Movie",
"Movies": "Movies", "Movies": "Movies",
"MusicAlbum": "Music Album", "MusicAlbum": "Music Album",
"MusicArtist": "Music Artist", "MusicArtist": "Music Artist",
@ -1039,16 +1045,16 @@
"NoNextUpItemsMessage": "None found. Start watching your shows!", "NoNextUpItemsMessage": "None found. Start watching your shows!",
"NoPluginConfigurationMessage": "This plugin has no settings to configure.", "NoPluginConfigurationMessage": "This plugin has no settings to configure.",
"NoSubtitleSearchResultsFound": "No results found.", "NoSubtitleSearchResultsFound": "No results found.",
"NoSubtitles": "No subtitles", "NoSubtitles": "None",
"NoSubtitlesHelp": "Subtitles will not be loaded by default. They can still be turned on manually during playback.", "NoSubtitlesHelp": "Subtitles will not be loaded by default. They can still be turned on manually during playback.",
"None": "None", "None": "None",
"Normal": "Normal", "Normal": "Normal",
"NumLocationsValue": "{0} folders", "NumLocationsValue": "{0} folders",
"Off": "Off", "Off": "Off",
"OneChannel": "One channel", "OneChannel": "One channel",
"OnlyForcedSubtitles": "Only forced subtitles", "OnlyForcedSubtitles": "Only Forced",
"OnlyForcedSubtitlesHelp": "Only subtitles marked as forced will be loaded.", "OnlyForcedSubtitlesHelp": "Only subtitles marked as forced will be loaded.",
"OnlyImageFormats": "Only image formats (VOBSUB, PGS, SUB, etc)", "OnlyImageFormats": "Only Image Formats (VOBSUB, PGS, SUB)",
"Option3D": "3D", "Option3D": "3D",
"OptionAdminUsers": "Administrators", "OptionAdminUsers": "Administrators",
"OptionAlbum": "Album", "OptionAlbum": "Album",
@ -1202,6 +1208,7 @@
"OptionWeekends": "Weekends", "OptionWeekends": "Weekends",
"OptionWeekly": "Weekly", "OptionWeekly": "Weekly",
"OriginalAirDateValue": "Original air date: {0}", "OriginalAirDateValue": "Original air date: {0}",
"OtherArtist": "Other Artist",
"Overview": "Overview", "Overview": "Overview",
"PackageInstallCancelled": "{0} installation cancelled.", "PackageInstallCancelled": "{0} installation cancelled.",
"PackageInstallCompleted": "{0} installation completed.", "PackageInstallCompleted": "{0} installation completed.",
@ -1215,6 +1222,7 @@
"PasswordSaved": "Password saved.", "PasswordSaved": "Password saved.",
"People": "People", "People": "People",
"PerfectMatch": "Perfect match", "PerfectMatch": "Perfect match",
"Person": "Person",
"Photos": "Photos", "Photos": "Photos",
"PictureInPicture": "Picture in picture", "PictureInPicture": "Picture in picture",
"PinCodeResetComplete": "The pin code has been reset.", "PinCodeResetComplete": "The pin code has been reset.",
@ -1268,6 +1276,7 @@
"RefreshMetadata": "Refresh metadata", "RefreshMetadata": "Refresh metadata",
"RefreshQueued": "Refresh queued.", "RefreshQueued": "Refresh queued.",
"ReleaseDate": "Release date", "ReleaseDate": "Release date",
"ReleaseGroup": "Release Group",
"RememberMe": "Remember me", "RememberMe": "Remember me",
"RemoveFromCollection": "Remove from collection", "RemoveFromCollection": "Remove from collection",
"RemoveFromPlaylist": "Remove from playlist", "RemoveFromPlaylist": "Remove from playlist",
@ -1298,6 +1307,7 @@
"SearchForMissingMetadata": "Search for missing metadata", "SearchForMissingMetadata": "Search for missing metadata",
"SearchForSubtitles": "Search for Subtitles", "SearchForSubtitles": "Search for Subtitles",
"SearchResults": "Search Results", "SearchResults": "Search Results",
"Season": "Season",
"SelectAdminUsername": "Please select a username for the admin account.", "SelectAdminUsername": "Please select a username for the admin account.",
"SendMessage": "Send message", "SendMessage": "Send message",
"Series": "Series", "Series": "Series",
@ -1413,6 +1423,7 @@
"TitleHardwareAcceleration": "Hardware Acceleration", "TitleHardwareAcceleration": "Hardware Acceleration",
"TitleHostingSettings": "Hosting Settings", "TitleHostingSettings": "Hosting Settings",
"TitlePlayback": "Playback", "TitlePlayback": "Playback",
"Track": "Track",
"TrackCount": "{0} tracks", "TrackCount": "{0} tracks",
"Trailers": "Trailers", "Trailers": "Trailers",
"Transcoding": "Transcoding", "Transcoding": "Transcoding",

View file

@ -183,7 +183,7 @@
"ErrorAddingListingsToSchedulesDirect": "Ha habido un error añadiendo la alineación a tu cuenta de Schedules Direct. Schedules Direct solo permite un determinado número de alineaciones por cuenta. Necesitarás iniciar sesión en la web de Schedules Direct y quitar otras listas de tu cuenta antes de proceder.", "ErrorAddingListingsToSchedulesDirect": "Ha habido un error añadiendo la alineación a tu cuenta de Schedules Direct. Schedules Direct solo permite un determinado número de alineaciones por cuenta. Necesitarás iniciar sesión en la web de Schedules Direct y quitar otras listas de tu cuenta antes de proceder.",
"ErrorAddingMediaPathToVirtualFolder": "Ha habido un error añadiendo la ruta de los medios. Por favor, asegúrate de que la ruta es válida y que el proceso del servidor Jellyfin tiene acceso a esa ubicación.", "ErrorAddingMediaPathToVirtualFolder": "Ha habido un error añadiendo la ruta de los medios. Por favor, asegúrate de que la ruta es válida y que el proceso del servidor Jellyfin tiene acceso a esa ubicación.",
"ErrorAddingTunerDevice": "Ha habido un error añadiendo el dispositivo sintonizador. Por favor, asegúrate de que es accesible e inténtalo otra vez.", "ErrorAddingTunerDevice": "Ha habido un error añadiendo el dispositivo sintonizador. Por favor, asegúrate de que es accesible e inténtalo otra vez.",
"ErrorAddingXmlTvFile": "Hubo un un error accediendo el archivo XML. Por favor, asegurese que el archivo existe e inténtalo de nuevo.", "ErrorAddingXmlTvFile": "Ha sucedido un error accediendo al archivo XML. Por favor, asegúrate que el archivo existe e inténtalo de nuevo.",
"ErrorGettingTvLineups": "Ha habido un error descargando la programación de TV. Por favor, asegúrese que la información es correcta e inténtalo de nuevo.", "ErrorGettingTvLineups": "Ha habido un error descargando la programación de TV. Por favor, asegúrese que la información es correcta e inténtalo de nuevo.",
"ErrorMessageStartHourGreaterThanEnd": "La hora de finalización tiene que ser mayor que la de inicio.", "ErrorMessageStartHourGreaterThanEnd": "La hora de finalización tiene que ser mayor que la de inicio.",
"ErrorPleaseSelectLineup": "Por favor selecciona una alineación e inténtalo otra vez. Si no hay alineaciones disponibles, revisa que tu nombre de usuario, contraseña y código postal son correctos.", "ErrorPleaseSelectLineup": "Por favor selecciona una alineación e inténtalo otra vez. Si no hay alineaciones disponibles, revisa que tu nombre de usuario, contraseña y código postal son correctos.",
@ -420,7 +420,7 @@
"Help": "Ayuda", "Help": "Ayuda",
"Hide": "Ocultar", "Hide": "Ocultar",
"HideWatchedContentFromLatestMedia": "Esconder medios vistos de los medios más recientes", "HideWatchedContentFromLatestMedia": "Esconder medios vistos de los medios más recientes",
"HttpsRequiresCert": "Para activar la conexión segura, necesitas un certificado SSL de confianza, como Let's Encrypt. De lo contrario, desactive las conexiones seguras", "HttpsRequiresCert": "Para activar la conexión segura, necesitas un certificado SSL de confianza, como Let's Encrypt. De lo contrario, desactive las conexiones seguras.",
"Identify": "Identificar", "Identify": "Identificar",
"Images": "Imágenes", "Images": "Imágenes",
"ImportFavoriteChannelsHelp": "Si está activado, sólo los canales guardados como favoritos en el sintonizador se importarán.", "ImportFavoriteChannelsHelp": "Si está activado, sólo los canales guardados como favoritos en el sintonizador se importarán.",
@ -1248,14 +1248,14 @@
"Descending": "Descendiente", "Descending": "Descendiente",
"DirectStreamHelp1": "El tipo de archivo (H.264, AC3, etc.) y la resolución son compatibles con el dispositivo, pero no el contenedor (mkv, avi, wmv, etc.). El vídeo será re-empaquetado al vuelo antes de transmitirlo al dispositivo.", "DirectStreamHelp1": "El tipo de archivo (H.264, AC3, etc.) y la resolución son compatibles con el dispositivo, pero no el contenedor (mkv, avi, wmv, etc.). El vídeo será re-empaquetado al vuelo antes de transmitirlo al dispositivo.",
"DirectStreamHelp2": "La transmisión directa del archivo usa muy poco procesamiento sin ninguna pérdida de calidad en el vídeo.", "DirectStreamHelp2": "La transmisión directa del archivo usa muy poco procesamiento sin ninguna pérdida de calidad en el vídeo.",
"Director": "Director", "Director": "Dirección",
"Directors": "Directores", "Directors": "Directores",
"Display": "Mostrar", "Display": "Mostrar",
"DisplayInMyMedia": "Mostrar en la pantalla de inicio", "DisplayInMyMedia": "Mostrar en la pantalla de inicio",
"DisplayInOtherHomeScreenSections": "Mostrar en las secciones de la pantalla de inicio al igual que \"últimos\" y \"continuar viendo\"", "DisplayInOtherHomeScreenSections": "Mostrar en las secciones de la pantalla de inicio al igual que \"últimos\" y \"continuar viendo\"",
"DisplayMissingEpisodesWithinSeasons": "Mostrar episodios ausentes en las temporadas", "DisplayMissingEpisodesWithinSeasons": "Mostrar episodios ausentes en las temporadas",
"DisplayMissingEpisodesWithinSeasonsHelp": "Esto también debe ser habilitado para la biblioteca de TV en la configuración del servidor.", "DisplayMissingEpisodesWithinSeasonsHelp": "Esto también debe ser habilitado para la biblioteca de TV en la configuración del servidor.",
"DropShadow": "Sombra", "DropShadow": "Eliminar sombra",
"EditMetadata": "Editar etiquetas", "EditMetadata": "Editar etiquetas",
"EnableBackdrops": "Imágenes de fondo", "EnableBackdrops": "Imágenes de fondo",
"EnableBackdropsHelp": "Mostrar imágenes de fondo en algunas páginas mientras se explora la biblioteca.", "EnableBackdropsHelp": "Mostrar imágenes de fondo en algunas páginas mientras se explora la biblioteca.",
@ -1404,7 +1404,7 @@
"RunAtStartup": "Ejecutar al iniciar", "RunAtStartup": "Ejecutar al iniciar",
"Series": "Series", "Series": "Series",
"SeriesDisplayOrderHelp": "Ordena los episodios por fecha de emisión, orden de DVD o número absoluto.", "SeriesDisplayOrderHelp": "Ordena los episodios por fecha de emisión, orden de DVD o número absoluto.",
"ShowTitle": "Mostrar título", "ShowTitle": "Título del show",
"ShowYear": "Año del show", "ShowYear": "Año del show",
"SmallCaps": "Letras minúsculas", "SmallCaps": "Letras minúsculas",
"Smaller": "Más pequeño", "Smaller": "Más pequeño",
@ -1455,9 +1455,9 @@
"MusicLibraryHelp": "Revisar la {0}guía de nombres de música{1}.", "MusicLibraryHelp": "Revisar la {0}guía de nombres de música{1}.",
"FetchingData": "Obteniendo datos adicionales", "FetchingData": "Obteniendo datos adicionales",
"ButtonAddImage": "Añadir imagen", "ButtonAddImage": "Añadir imagen",
"HeaderFavoritePeople": "Gente Favorita", "HeaderFavoritePeople": "Gente favorita",
"OptionRandom": "Aleatorio", "OptionRandom": "Aleatorio",
"SelectAdminUsername": "Por favor seleccione un nombre de usuario para la cuenta de administrador.", "SelectAdminUsername": "Por favor seleccione un nombre de usuario para la cuenta administrador.",
"ButtonSplit": "Dividir", "ButtonSplit": "Dividir",
"HeaderNavigation": "Navegación", "HeaderNavigation": "Navegación",
"MessageConfirmAppExit": "¿Quieres salir?", "MessageConfirmAppExit": "¿Quieres salir?",
@ -1474,5 +1474,8 @@
"LabelDroppedFrames": "Frames perdidos:", "LabelDroppedFrames": "Frames perdidos:",
"LabelCorruptedFrames": "Frames corruptos:", "LabelCorruptedFrames": "Frames corruptos:",
"AskAdminToCreateLibrary": "Solo un administrador puede crear librerías.", "AskAdminToCreateLibrary": "Solo un administrador puede crear librerías.",
"AllowFfmpegThrottling": "Acelerar transcodificación" "AllowFfmpegThrottling": "Acelerar transcodificación",
"ClientSettings": "Ajustes de cliente",
"PreferEmbeddedEpisodeInfosOverFileNames": "Priorizar la información embebida sobre los nombres de archivos",
"PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Usar la información de episodio de los metadatos embebidos si está disponible."
} }

View file

@ -33,9 +33,9 @@
"HeaderFilters": "فیلتر ها", "HeaderFilters": "فیلتر ها",
"HeaderImageOptions": "گزینه های تصویر", "HeaderImageOptions": "گزینه های تصویر",
"HeaderInstantMix": "درهم کردن فوری", "HeaderInstantMix": "درهم کردن فوری",
"HeaderKodiMetadataHelp": "برای فعال یا غیرفعال سازی متاداده های Nfo ، یک کتابخانه را در صفحه تنظیم کتابخانه Jellyfin ویرایش کرده و قسمت سرورهای متاداده را مسیردهی کنید.", "HeaderKodiMetadataHelp": "برای فعال یا غیرفعال سازی ابرداده‌های Nfo ، یک کتابخانه را در صفحه تنظیم کتابخانه Jellyfin ویرایش کرده و قسمت سرورهای ابرداده را مسیردهی کنید.",
"HeaderLatestEpisodes": "آخرین قسمت ها", "HeaderLatestEpisodes": "آخرین قسمت ها",
"HeaderNextUp": "بعدی", "HeaderNextUp": "قسمت بعدی",
"HeaderPaths": "مسیرها", "HeaderPaths": "مسیرها",
"HeaderPlayAll": "پخش همه", "HeaderPlayAll": "پخش همه",
"HeaderPreferredMetadataLanguage": "زبان مدنظر اطلاعات محتوی", "HeaderPreferredMetadataLanguage": "زبان مدنظر اطلاعات محتوی",
@ -113,34 +113,307 @@
"UserProfilesIntro": "Jellyfin دارای پشتیبانی داخلی از پروفایل کاربران می باشد. با فعال سازی هر کاربر، او می تواند تنظیمات ، وضعیت پخش و کنترل والدین خاص خودش را داشته باشد.", "UserProfilesIntro": "Jellyfin دارای پشتیبانی داخلی از پروفایل کاربران می باشد. با فعال سازی هر کاربر، او می تواند تنظیمات ، وضعیت پخش و کنترل والدین خاص خودش را داشته باشد.",
"WelcomeToProject": "به Jellyfin خوش آمدید!", "WelcomeToProject": "به Jellyfin خوش آمدید!",
"WizardCompleted": "همه چیزی که فعلا می خواهیم همین است.جمع آوری اطلاعات کتابخانه های شما هم اکنون توسط Jellyfin آغاز شده است. اپلیکیشن های ما را امتحان کنید و سپس بر روی <b> پایان </b> کلیک کنید تا <b> پیشخوان سرور </b> را مشاهده نمایید.", "WizardCompleted": "همه چیزی که فعلا می خواهیم همین است.جمع آوری اطلاعات کتابخانه های شما هم اکنون توسط Jellyfin آغاز شده است. اپلیکیشن های ما را امتحان کنید و سپس بر روی <b> پایان </b> کلیک کنید تا <b> پیشخوان سرور </b> را مشاهده نمایید.",
"Albums": "آلبوم ها", "Albums": "آلبومها",
"Artists": "هنرمندان", "Artists": "هنرمندان",
"Books": "کتاب ها", "Books": "کتابها",
"Channels": "کانال ها", "Channels": "کانالها",
"Collections": "کلکسیون ها", "Collections": "مجموعه‌ها",
"Favorites": "مورد علاقه ها", "Favorites": "مورد علاقهها",
"Folders": "پوشه ها", "Folders": "پوشهها",
"Genres": "ژانرها", "Genres": "ژانرها",
"HeaderAlbumArtists": "هنرمندان آلبوم", "HeaderAlbumArtists": "هنرمندان آلبوم",
"HeaderFavoriteShows": "سریال های مورد علاقه", "HeaderFavoriteShows": "سریالهای مورد علاقه",
"HeaderFavoriteEpisodes": "قسمت های مورد علاقه", "HeaderFavoriteEpisodes": "قسمتهای مورد علاقه",
"HeaderFavoriteAlbums": "آلبوم های مورد علاقه", "HeaderFavoriteAlbums": "آلبومهای مورد علاقه",
"HeaderFavoriteArtists": "هنرمندان مورد علاقه", "HeaderFavoriteArtists": "هنرمندان مورد علاقه",
"HeaderFavoriteSongs": "آهنگ های مورد علاقه", "HeaderFavoriteSongs": "آهنگهای مورد علاقه",
"HeaderLiveTV": "پخش زنده تلویزیون", "HeaderLiveTV": "پخش زنده تلویزیون",
"Movies": "فیلم های سینمایی", "Movies": "فیلمها",
"Photos": "عکس ها", "Photos": "عکسها",
"Playlists": "لیست های پخش", "Playlists": "لیستهای پخش",
"Shows": "سریال ها", "Shows": "سریالها",
"Songs": "آهنگ ها", "Songs": "موسیقی‌ها",
"Sync": "همگامسازی", "Sync": "همگامسازی",
"ValueSpecialEpisodeName": "ویژه- {0}", "ValueSpecialEpisodeName": "ویژه - {0}",
"AllEpisodes": "تمام قسمت ها", "AllEpisodes": "تمام قسمت ها",
"AllLanguages": "تمام زبان ها", "AllLanguages": "تمام زبان ها",
"AllLibraries": "تمام کتابخانه ها", "AllLibraries": "تمام کتابخانه ها",
"AllowHWTranscodingHelp": "اگر فعال شود, اجازه میدهید تبدیل ( کم و زیاد کردن کیفیت ) درلحظه و توسط کارت دریافت سیگنال صورت گیرد. این کمک میکند به اینکه سرور جلیفین کمتر عمل تبدیل را انجام دهد.", "AllowHWTranscodingHelp": "اگر فعال شود, اجازه می‌دهید تبدیل کیفیت در لحظه انجام شود. این ممکن است به کاهش کدگذاری لازم برای Jellyfin منجر بشود.",
"AllowOnTheFlySubtitleExtraction": "اجازه میدهد در لحظه زیرنویس بازشود", "AllowOnTheFlySubtitleExtraction": "اجازه میدهد در لحظه زیرنویس بازشود",
"Add": "افزودن", "Add": "افزودن",
"Actor": "بازیگر", "Actor": "بازیگر",
"AccessRestrictedTryAgainLater": "دسترسی در حال حاضر محدود شده است. لطفا دوباره تلاش کنید." "AccessRestrictedTryAgainLater": "دسترسی در حال حاضر محدود شده است. لطفا دوباره تلاش کنید.",
"ButtonShuffle": "مخلوط کردن",
"ButtonSettings": "تنظیمات",
"ButtonSend": "ارسال",
"ButtonSelectView": "انتخاب نما",
"ButtonSelectServer": "انتخاب سرور",
"ButtonSearch": "جستجو",
"ButtonScanAllLibraries": "پویش تمام کتابخانه‌ها",
"ButtonRevoke": "ابطال",
"ButtonResume": "ادامه",
"ButtonRestart": "راه اندازی مجدد",
"ButtonResetEasyPassword": "بازنشانی کد پین آسان",
"ButtonRepeat": "تکرار",
"ButtonRename": "تغییر نام",
"ButtonRemove": "حذف",
"ButtonRefreshGuideData": "به‌روز‌رسانی داده‌ی راهنما",
"ButtonRefresh": "به‌روز‌رسانی",
"ButtonProfile": "نمایه",
"ButtonNextTrack": "ترانه پسین",
"ButtonPreviousTrack": "ترانه پیشین",
"ButtonPause": "مکث",
"ButtonParentalControl": "کنترل والدین",
"ButtonOpen": "باز",
"ButtonOff": "خاموش",
"ButtonNetwork": "شبکه",
"ButtonMore": "بیشتر",
"ButtonManualLogin": "ورود دستی",
"ButtonLibraryAccess": "دسترسی به کتابخانه",
"ButtonLearnMore": "بیشتر بدانید",
"ButtonInfo": "اطلاعات",
"ButtonHome": "خانه",
"ButtonHelp": "کمک",
"ButtonGuide": "راهنما",
"ButtonGotIt": "متوجه شدم",
"ButtonFullscreen": "تمام صفحه",
"ButtonForgotPassword": "فراموشی گذرواژه",
"ButtonEditImages": "ویرایش عکس‌ها",
"ButtonEdit": "ویرایش",
"ButtonDownload": "بارگیری",
"ButtonDown": "پایین",
"ButtonDelete": "حذف",
"ButtonConnect": "اتصال",
"ButtonChangeServer": "تغییر سرور",
"ButtonBack": "بازگشت",
"ButtonArrowUp": "بالا",
"ButtonArrowRight": "راست",
"ButtonArrowLeft": "چپ",
"ButtonArrowDown": "پایین",
"ButtonAddServer": "افزودن سرور",
"ButtonAddScheduledTaskTrigger": "افزودن راه انداز",
"ButtonAddMediaLibrary": "افزودن کتابخانه رسانه",
"ButtonAddImage": "افزودن تصویر",
"ButtonAdd": "افزودن",
"BoxRear": "جعبه (پشت)",
"Box": "جعبه",
"Blacklist": "لیست سیاه",
"BirthPlaceValue": "محل تولد: {0}",
"BirthLocation": "محل تولد",
"BirthDateValue": "متولد: {0}",
"Banner": "سرصفحه",
"Backdrops": "پس زمینه‌ها",
"Backdrop": "پس زمینه",
"AutoBasedOnLanguageSetting": "خودکار (بر اساس تنظیمات زبانی)",
"Auto": "خودکار",
"Audio": "صدا",
"AttributeNew": "جدید",
"AspectRatio": "نسبت ابعاد",
"AskAdminToCreateLibrary": "از کاربر مدیر بخواهید که یک کتابخانه ایجاد کند.",
"Ascending": "بالا رونده",
"AsManyAsPossible": "تا حدی که ممکن است",
"AroundTime": "حدود {0}",
"Anytime": "هر زمانی",
"AnyLanguage": "هر زبانی",
"AlwaysPlaySubtitles": "همیشه زیرنویس را نمایش بده",
"AllowFfmpegThrottling": "گلوگاه تبدیل کیفیت",
"AllChannels": "همه‌ی کانال‌ها",
"Alerts": "هشدارها",
"Aired": "پخش شده",
"AirDate": "تاریخ پخش",
"AddedOnValue": "{0} افزوده شد",
"AddToPlaylist": "افزودن به لیست پخش",
"AddToPlayQueue": "افزودن به صف پخش",
"AddToCollection": "افزودن به مجموعه",
"ExitFullscreen": "خروج از تمام صفحه",
"EveryNDays": "هر {0} روز",
"ErrorMessageStartHourGreaterThanEnd": "زمان پایان باید پس از زمان شروع باشد.",
"Episodes": "قسمت‌ها",
"EndsAtValue": "تمام شده در {0}",
"Ended": "تمام شده",
"EnableThemeVideos": "تم فیلم‌ها",
"EnableThemeSongs": "آهنگ‌های تم",
"EnableStreamLooping": "چرخش خودکار پخش‌های زنده",
"EnablePhotos": "نمایش عکس‌ها",
"EnableNextVideoInfoOverlay": "نمایش اطلاعات ودیوی بعدی حین پخش ویدیو",
"EnableHardwareEncoding": "فعال سازی رمزگذاری سخت افزاری",
"EnableExternalVideoPlayersHelp": "یک منوی پخش کننده ویدیوی خارجی، زمانی که شروع به پخش ویدیو می‌شود نمایش داده خواهد شد.",
"EnableExternalVideoPlayers": "پخش کننده ویدیوی خارجی",
"EnableDisplayMirroring": "نمایش حالت آینه",
"EnableCinemaMode": "حالت سینما",
"EnableBackdrops": "پشت‌زمینه‌ها",
"EditSubtitles": "ویرایش زیرنویس‌ها",
"EditMetadata": "ویرایش ابرداده",
"EditImages": "ویرایش عکس‌ها",
"Edit": "ویرایش",
"DropShadow": "سایه پشت زمینه",
"DrmChannelsNotImported": "کانال‌ها با DRM وارد نخواند شد.",
"DownloadsValue": "{0} بارگیری‌ها",
"Download": "بارگیری",
"Down": "پایین",
"DoNotRecord": "ضبط نکن",
"DisplayModeHelp": "نوع صفحه نمایشی که Jellyfin را اجرا می‌کنید را انتخاب کنید‌‌.",
"DisplayMissingEpisodesWithinSeasons": "قسمت‌های ناموجود در فصل‌ها را نمایش بده",
"DisplayInMyMedia": "نمایش در صفحه‌ی خانه",
"Display": "نمایش",
"Dislike": "دوست نداشتن",
"Disconnect": "قطع اتصال",
"Disc": "دیسک",
"Directors": "کارگردانان",
"Director": "کارگردان",
"DirectStreaming": "پخش مستقیم",
"DirectStreamHelp2": "پخش مستقیم فایل از قدرت پردازش بسیار کمی بدون از دست دادن کیفیت ویدیو استفاده می‌کند.",
"DirectPlaying": "پخش مستقیم",
"DetectingDevices": "در حال تشخیص دستگاه‌ها",
"Descending": "پایین رونده",
"Depressed": "پژمرده",
"DeleteUserConfirmation": "آیا اطمینان دارید که می‌خواهید این کاربر را حذف کنید؟",
"DeleteUser": "حذف کاربر",
"DeleteImageConfirmation": "آیا اطمینان دارید که می‌خواهید این تصویر را حذف کنید؟",
"DeleteImage": "حذف تصویر",
"DeleteDeviceConfirmation": "آیا از حذف این دستگاه اطمینان دارید؟ هنگامی که یک کاربر دوباره با آن دستگاه وارد شود، دوباره نمایش داده می‌شود.",
"Delete": "حذف",
"DefaultMetadataLangaugeDescription": "این موارد پیشفرض‌های شماست و می‌توانید برای هر کتابخانه آن را شخصی سازی کنید.",
"DefaultErrorMessage": "خطایی در پردازش درخواست رخ داد. لطفا اندکی بعد دوباره تلاش کنید.",
"Default": "پیشفرض",
"DeathDateValue": "تلف شد: {0}",
"DatePlayed": "تاریخ پخش شده",
"DateAdded": "تاریخ اضافه شده",
"CriticRating": "امتیاز منتقدان",
"CopyStreamURLError": "در کپی کردن آدرس خطایی رخ داد.",
"CopyStreamURLSuccess": "آدرس با موفقیت کپی شد.",
"CopyStreamURL": "کپی آدرس پخش",
"Continuing": "ادامه",
"ContinueWatching": "ادامه تماشا",
"Connect": "اتصال",
"ConfirmEndPlayerSession": "آیا می‌خواهید Jellyfin را روی {0} خاموش کنید؟",
"ConfirmDeletion": "تایید حذف",
"ConfirmDeleteImage": "حذف تصویر؟",
"Composer": "آهنگساز",
"CommunityRating": "امتیاز عمومی",
"ColorTransfer": "انتقال رنگ",
"ColorSpace": "فضای رنگی",
"ColorPrimaries": "مقدمات رنگی",
"ClientSettings": "تنظیمات مشتری",
"ChannelNumber": "شماره کانال",
"ChannelNameOnly": "تنها کانال {0}",
"Categories": "دسته‌بندی‌ها",
"CancelSeries": "لغو سریال‌ها",
"CancelRecording": "لغو ضبط",
"ButtonWebsite": "وبسایت",
"ButtonViewWebsite": "بازدید وبسایت",
"ButtonUp": "بالا",
"ButtonUninstall": "حذف نصب",
"ButtonTrailer": "تریلر",
"ButtonSubtitles": "زیرنویس‌ها",
"ButtonSubmit": "تایید",
"ButtonSplit": "جدا کردن",
"ButtonStop": "توقف",
"ButtonStart": "شروع",
"ButtonSignIn": "ورود",
"ButtonShutdown": "خاموش",
"ButtonSelectDirectory": "انتخاب مسیر",
"ButtonEditOtherUserPreferences": "نمایه، تصویر و ترجیحات شخصی این کاربر را ویرایش کنید.",
"BrowsePluginCatalogMessage": "برای مرور کردن افزونه‌های موجود، به فروشگاه افزونه‌های ما سر بزنید.",
"AuthProviderHelp": "ارائه دهنده تأیید اعتبار را انتخاب کنید تا برای تأیید اعتبار گذرواژه این کاربر استفاده شود.",
"HeaderRecordingPostProcessing": "در حال ضبط پس پردازش",
"HeaderRecordingOptions": "گزینه‌های ضبط",
"HeaderRecentlyPlayed": "به تازگی پخش شده",
"HeaderProfileInformation": "اطلاعات نمایه",
"HeaderProfile": "نمایه",
"HeaderPluginInstallation": "نصب افزونه",
"HeaderPleaseSignIn": "لطفا وارد شوید",
"HeaderPlaybackError": "خطای پخش",
"HeaderPlayback": "پخش رسانه",
"HeaderPlayOn": "پخش در",
"HeaderPinCodeReset": "بازنشانی پین کد",
"HeaderPhotoAlbums": "آلبوم‌های عکس",
"HeaderPeople": "افراد",
"HeaderPendingInvitations": "دعوت‌های در انتظار",
"HeaderPasswordReset": "بازنشانی گذرواژه",
"HeaderPassword": "گذرواژه",
"HeaderParentalRatings": "رتبه بندی والدین",
"HeaderOtherItems": "آیتم‌های دیگر",
"HeaderOnNow": "هم اکنون",
"HeaderNextVideoPlayingInValue": "پخش ویدیوی بعد در {0}",
"HeaderNextEpisodePlayingInValue": "پخش قسمت بعدی در {0}",
"HeaderNewDevices": "دستگاه جدید",
"HeaderNewApiKey": "کلید API جدید",
"HeaderMyMediaSmall": "رسانه‌ی من (کوچک)",
"HeaderMyMedia": "رسانه‌ی من",
"HeaderMyDevice": "دستگاه‌های من",
"HeaderMusicVideos": "موزیک ویدیوها",
"HeaderMusicQuality": "کیفیت آهنگ",
"HeaderMovies": "فیلم‌ها",
"HeaderMoreLikeThis": "موارد مشابه با این",
"HeaderMetadataSettings": "تنظیمات ابرداده",
"HeaderMediaInfo": "اطلاعات رسانه",
"HeaderMediaFolders": "پوشه‌های رسانه",
"HeaderMedia": "رسانه",
"HeaderLoginFailure": "ورود ناموفق",
"HeaderLiveTvTunerSetup": "تنظیم تلویزیون زنده",
"HeaderLiveTv": "تلویزیون زنده",
"HeaderLibrarySettings": "تنظیمات کتابخانه",
"HeaderLibraryOrder": "ترتیت کتابخانه",
"HeaderLibraryFolders": "پوشه‌های کتابخانه",
"HeaderLibraryAccess": "دسترسی به کتابخانه",
"HeaderLibraries": "کتابخانه‌ها",
"HeaderLatestRecordings": "آخرین ضبط‌ها",
"HeaderLatestMusic": "آخرین آهنگ‌ها",
"HeaderLatestMovies": "آخرین فیلم‌ها",
"HeaderLatestMedia": "آخرین رسانه‌ها",
"HeaderKeepSeries": "سریال ادامه دهید",
"HeaderKeepRecording": "ضبط را ادامه دهید",
"HeaderItems": "موارد",
"HeaderInstall": "نصب",
"HeaderImageSettings": "تنظیمات عکس",
"HeaderIdentifyItemHelp": "یک یا بیشتر مورد برای جستجو وارد کنید. موارد را حذف کنید تا نتیجه جستجو را افزایش دهید.",
"HeaderIdentificationHeader": "سرفصل تعیین هویت",
"HeaderIdentificationCriteriaHelp": "حداقل یک مورد تعیین هویت وارد کنید.",
"HeaderIdentification": "تعیین هویت",
"HeaderHttpHeaders": "سرفصل‌های HTTP",
"HeaderHome": "خانه",
"HeaderGuideProviders": "ارائه دهنده داده راهنمای تلویزیونی",
"HeaderGenres": "ژانرها",
"HeaderFrequentlyPlayed": "اغلب پخش شده",
"HeaderForgotPassword": "فراموشی گذرواژه",
"HeaderForKids": "برای کودکان",
"HeaderFetchImages": "دریافت عکس‌ها:",
"HeaderFeatures": "برجسته‌ها",
"HeaderFeatureAccess": "دسترسی‌های برجسته",
"HeaderFavoriteVideos": "ویدیو‌های مورد علاقه",
"HeaderFavoritePeople": "افراد مورد علاقه",
"HeaderFavoriteMovies": "فیلم‌های مورد علاقه",
"HeaderFavoriteBooks": "کتاب‌های مورد علاقه",
"HeaderExternalIds": "ID های خارجی:",
"HeaderError": "خطا",
"HeaderEpisodes": "قسمت‌ها",
"HeaderEnabledFieldsHelp": "یک فیلد را برای جلوگیری از تغییر در داده‌ی آن علامت بزنید تا قفل بشود.",
"HeaderEnabledFields": "فیلد‌های فعال شده",
"HeaderEditImages": "ویرایش عکس‌ها",
"HeaderDownloadSync": "بارگیری و همگام‌سازی",
"HeaderDisplay": "نمایش",
"HeaderDirectPlayProfileHelp": "نمایه‌ی پخش مستقیم را اضافه کنید تا مشخص کنید با چه فرمی دستگاه می‌تواند محلی برخورد کند.",
"HeaderDirectPlayProfile": "نمایه‌ی پخش مستقیم",
"HeaderDevices": "دستگاه‌ها",
"HeaderDeveloperInfo": "اطلاعات توسعه دهنده",
"HeaderDetectMyDevices": "تشخیص دستگاه‌های من",
"HeaderDeleteTaskTrigger": "حذف راه انداز وظیفه",
"HeaderDeleteProvider": "حذف ارائه‌دهنده",
"HeaderDeleteItems": "حذف آیتم‌ها",
"HeaderDeleteItem": "حذف آیتم",
"HeaderDeleteDevice": "حذف دستگاه",
"HeaderDefaultRecordingSettings": "تنظمیات پیش‌فرض ضبط",
"HeaderDateIssued": "تاریخ صدور",
"HeaderCodecProfileHelp": "نمایه‌های کدک محدودیت‌های یک دستگاه را هنگام پخش کدک‌های خاص نشان می‌دهد. اگر محدودیتی اعمال شود، رسانه‌ها کد گذاری می‌شوند ، حتی اگر کدک برای پخش مستقیم پیکربندی شده باشد.",
"HeaderCodecProfile": "نمایه کدک",
"HeaderChapterImages": "عکس‌های سکانس",
"HeaderChannels": "کانال‌ها",
"HeaderChannelAccess": "دسترسی به کانال",
"HeaderCastCrew": "بازیگران و کارکنان",
"HeaderCastAndCrew": "بازیگران و کارکنان",
"HeaderCancelSeries": "لغو سریال",
"HeaderCancelRecording": "لغو ضبط",
"HeaderBooks": "کتاب‌ها",
"HeaderBlockItemsWithNoRating": "موارد مسدود شده با نقص یا عدم وجود اطلاعات امتیاز:"
} }

View file

@ -14,7 +14,7 @@
"Alerts": "Alertes", "Alerts": "Alertes",
"All": "Tout", "All": "Tout",
"AllChannels": "Toutes les chaînes", "AllChannels": "Toutes les chaînes",
"AllComplexFormats": "Tous les formats complexes (ASS, SSA, VOBSUB, PGS, SUB/IDX, etc…)", "AllComplexFormats": "Tous les formats complexes (ASS, SSA, VOBSUB, PGS, SUB, IDX, etc…)",
"AllEpisodes": "Tous les épisodes", "AllEpisodes": "Tous les épisodes",
"AllLanguages": "Toutes les langues", "AllLanguages": "Toutes les langues",
"AllLibraries": "Toutes les médiathèques", "AllLibraries": "Toutes les médiathèques",
@ -51,7 +51,7 @@
"BoxRear": "Dos de boîtier", "BoxRear": "Dos de boîtier",
"Browse": "Parcourir", "Browse": "Parcourir",
"BrowsePluginCatalogMessage": "Explorer notre catalogue des plugins pour voir les plugins disponibles.", "BrowsePluginCatalogMessage": "Explorer notre catalogue des plugins pour voir les plugins disponibles.",
"BurnSubtitlesHelp": "Détermine si le serveur doit incruster les sous-titres lors de la conversion vidéo en fonction du format des sous-titres. Éviter l'incrustation des sous-titres améliorera les performances du serveur. Sélectionnez Auto pour incruster les formats basés sur l'image (VOBSUB, PGS, SUB/IDX etc) et certains sous-titres ASS/SSA.", "BurnSubtitlesHelp": "Détermine si le serveur doit incruster les sous-titres lors du transcodage de la vidéo. Éviter cela améliorera nettement la performance. Sélectionnez Auto pour incruster les formats basés sur l'image (VOBSUB, PGS, SUB, IDX etc) et certains sous-titres ASS ou SSA.",
"ButtonAdd": "Ajouter", "ButtonAdd": "Ajouter",
"ButtonAddMediaLibrary": "Ajouter une médiathèque", "ButtonAddMediaLibrary": "Ajouter une médiathèque",
"ButtonAddScheduledTaskTrigger": "Ajouter un déclencheur", "ButtonAddScheduledTaskTrigger": "Ajouter un déclencheur",
@ -186,7 +186,7 @@
"DisplayInOtherHomeScreenSections": "Afficher dans les sections de lécran daccueil comme Ajouts récents et Reprendre", "DisplayInOtherHomeScreenSections": "Afficher dans les sections de lécran daccueil comme Ajouts récents et Reprendre",
"DisplayMissingEpisodesWithinSeasons": "Afficher les épisodes manquants dans les saisons", "DisplayMissingEpisodesWithinSeasons": "Afficher les épisodes manquants dans les saisons",
"DisplayMissingEpisodesWithinSeasonsHelp": "Cette option doit aussi être activée pour les médiathèques TV dans les paramètres du serveur.", "DisplayMissingEpisodesWithinSeasonsHelp": "Cette option doit aussi être activée pour les médiathèques TV dans les paramètres du serveur.",
"DisplayModeHelp": "Sélectionner le type d'écran sur lequel vous utilisez Jellyfin.", "DisplayModeHelp": "Sélectionner l'agencement que vous désirez pour l'interface.",
"DoNotRecord": "Ne pas enregistrer", "DoNotRecord": "Ne pas enregistrer",
"Down": "Bas", "Down": "Bas",
"Download": "Téléchargement", "Download": "Téléchargement",
@ -948,7 +948,7 @@
"OneChannel": "Une chaîne", "OneChannel": "Une chaîne",
"OnlyForcedSubtitles": "Seulement les sous-titres forcés", "OnlyForcedSubtitles": "Seulement les sous-titres forcés",
"OnlyForcedSubtitlesHelp": "Seuls les sous-titres marqués comme forcés seront chargés.", "OnlyForcedSubtitlesHelp": "Seuls les sous-titres marqués comme forcés seront chargés.",
"OnlyImageFormats": "Seulement les formats image (VOBSUB, PGS, SUB, etc)", "OnlyImageFormats": "Seulement les formats image (VOBSUB, PGS, SUB)",
"OptionAdminUsers": "Administrateurs", "OptionAdminUsers": "Administrateurs",
"OptionAlbumArtist": "Artiste de l'album", "OptionAlbumArtist": "Artiste de l'album",
"OptionAllUsers": "Tous les utilisateurs", "OptionAllUsers": "Tous les utilisateurs",
@ -1446,7 +1446,7 @@
"LabelAudioChannels": "Canaux audio :", "LabelAudioChannels": "Canaux audio :",
"HeaderFavoriteBooks": "Livres préférés", "HeaderFavoriteBooks": "Livres préférés",
"FetchingData": "Récuperer des données suplémentaires", "FetchingData": "Récuperer des données suplémentaires",
"CopyStreamURLSuccess": "URL copiée.", "CopyStreamURLSuccess": "URL copiée avec succès.",
"CopyStreamURL": "Copier l'URL du flux", "CopyStreamURL": "Copier l'URL du flux",
"LabelBaseUrlHelp": "Vous pouvez ajouter un sous-répertoire personalisé ici pour accéder au serveur depuis une URL plus exclusive.", "LabelBaseUrlHelp": "Vous pouvez ajouter un sous-répertoire personalisé ici pour accéder au serveur depuis une URL plus exclusive.",
"HeaderFavoritePeople": "Personnes préférées", "HeaderFavoritePeople": "Personnes préférées",
@ -1460,9 +1460,9 @@
"LabelStreamType": "Type de flux :", "LabelStreamType": "Type de flux :",
"EnableFastImageFadeInHelp": "Activer un transition plus rapide pour images téléchargées", "EnableFastImageFadeInHelp": "Activer un transition plus rapide pour images téléchargées",
"EnableFastImageFadeIn": "Transition d'image rapide", "EnableFastImageFadeIn": "Transition d'image rapide",
"LabelPlayerDimensions": "Dimension du lecteur:", "LabelPlayerDimensions": "Dimension du lecteur :",
"LabelDroppedFrames": "Images perdues:", "LabelDroppedFrames": "Images perdues :",
"LabelCorruptedFrames": "Images corrompues:", "LabelCorruptedFrames": "Images corrompues:",
"CopyStreamURLError": "Il y a eu une erreur lors de la copie du URL.", "CopyStreamURLError": "Il y a eu une erreur lors de la copie du URL.",
"AskAdminToCreateLibrary": "Demander à un administrateur de créer une médiathèque.", "AskAdminToCreateLibrary": "Demander à un administrateur de créer une médiathèque.",
"AllowFfmpegThrottlingHelp": "Quand le transcodage ou le remultiplexage est suffisamment loin de la position de lecture, le processus se mettra en pause afin déconomiser des ressources. Plus utile lors dune lecture continue. À désactiver en cas de problèmes de lecture.", "AllowFfmpegThrottlingHelp": "Quand le transcodage ou le remultiplexage est suffisamment loin de la position de lecture, le processus se mettra en pause afin déconomiser des ressources. Plus utile lors dune lecture continue. À désactiver en cas de problèmes de lecture.",
@ -1470,5 +1470,6 @@
"NoCreatedLibraries": "Il semblerait que vous n'ayez créé aucune librairie. {0}Voulez-vous en créer une maintenant ?{1}", "NoCreatedLibraries": "Il semblerait que vous n'ayez créé aucune librairie. {0}Voulez-vous en créer une maintenant ?{1}",
"PlaybackErrorNoCompatibleStream": "Problème de profil client, le serveur na pas pu envoyer un format média compatible.", "PlaybackErrorNoCompatibleStream": "Problème de profil client, le serveur na pas pu envoyer un format média compatible.",
"PreferEmbeddedEpisodeInfosOverFileNames": "Préférer les informations intégrées aux noms de fichiers", "PreferEmbeddedEpisodeInfosOverFileNames": "Préférer les informations intégrées aux noms de fichiers",
"PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Utilise les informations des métadonnées intégrées, si disponible." "PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Utilise les informations des métadonnées intégrées, si disponible.",
"ClientSettings": "Paramètres Client"
} }

View file

@ -14,7 +14,7 @@
"Albums": "Album", "Albums": "Album",
"All": "Tutto", "All": "Tutto",
"AllChannels": "Tutti i canali", "AllChannels": "Tutti i canali",
"AllComplexFormats": "Tutti i formati complessi (ASS, SSA, VOBSUB, PGS, SUB / IDX, ecc.)", "AllComplexFormats": "Tutti i formati complessi (ASS, SSA, VOBSUB, PGS, SUB, IDX)",
"AllEpisodes": "Tutti gli episodi", "AllEpisodes": "Tutti gli episodi",
"AllLanguages": "Tutte le lingue", "AllLanguages": "Tutte le lingue",
"AllLibraries": "Tutte le librerie", "AllLibraries": "Tutte le librerie",
@ -24,7 +24,7 @@
"AllowRemoteAccess": "Abilita connessioni remote a questo Server Jellyfin.", "AllowRemoteAccess": "Abilita connessioni remote a questo Server Jellyfin.",
"AllowRemoteAccessHelp": "Se deselezionato, tutte le connessioni remote saranno bloccate.", "AllowRemoteAccessHelp": "Se deselezionato, tutte le connessioni remote saranno bloccate.",
"AllowedRemoteAddressesHelp": "Elenco separato da virgola di indirizzi IP o voci IP / maschera di rete per reti che potranno connettersi da remoto. Se lasciato vuoto, saranno consentiti tutti gli indirizzi remoti.", "AllowedRemoteAddressesHelp": "Elenco separato da virgola di indirizzi IP o voci IP / maschera di rete per reti che potranno connettersi da remoto. Se lasciato vuoto, saranno consentiti tutti gli indirizzi remoti.",
"AlwaysPlaySubtitles": "Visualizza sempre i sottotitoli", "AlwaysPlaySubtitles": "Riproduci sempre",
"AlwaysPlaySubtitlesHelp": "I sottotitoli corrispondenti alla lingua preferita saranno caricati a prescindere dalla lingua dell'audio.", "AlwaysPlaySubtitlesHelp": "I sottotitoli corrispondenti alla lingua preferita saranno caricati a prescindere dalla lingua dell'audio.",
"AnyLanguage": "Qualsiasi lingua", "AnyLanguage": "Qualsiasi lingua",
"Anytime": "In qualsiasi momento", "Anytime": "In qualsiasi momento",
@ -45,7 +45,7 @@
"BoxRear": "Box (retro)", "BoxRear": "Box (retro)",
"Browse": "Esplora", "Browse": "Esplora",
"BrowsePluginCatalogMessage": "Sfoglia il catalogo dei Plugins.", "BrowsePluginCatalogMessage": "Sfoglia il catalogo dei Plugins.",
"BurnSubtitlesHelp": "Determina se il server deve applicare i sottotitoli quando si convertono video in base al formato dei sottotitoli. Evitando di applicare i sottotitoli migliorerà le prestazioni del server. Selezionare Auto per applicare formati basati sull'immagine (VOBSUB, PGS, SUB / IDX, ecc.) e alcuni sottotitoli ASS / SSA.", "BurnSubtitlesHelp": "Determina se il server deve imprimere i sottotitoli quando i video vengono convertiti. Evitare ciò migliorerà di molto le prestazioni. Selezionare Auto per imprimere formati basati sull'immagine (VOBSUB, PGS, SUB, IDX) e alcuni sottotitoli ASS o SSA.",
"ButtonAdd": "Aggiungi", "ButtonAdd": "Aggiungi",
"ButtonAddMediaLibrary": "Aggiungi raccolta multimediale", "ButtonAddMediaLibrary": "Aggiungi raccolta multimediale",
"ButtonAddScheduledTaskTrigger": "Aggiungi operazione", "ButtonAddScheduledTaskTrigger": "Aggiungi operazione",
@ -175,7 +175,7 @@
"DisplayInOtherHomeScreenSections": "Mostra le sezioni della schermata home come gli ultimi media e continua a guardare", "DisplayInOtherHomeScreenSections": "Mostra le sezioni della schermata home come gli ultimi media e continua a guardare",
"DisplayMissingEpisodesWithinSeasons": "Visualizza gli episodi mancanti nelle stagioni", "DisplayMissingEpisodesWithinSeasons": "Visualizza gli episodi mancanti nelle stagioni",
"DisplayMissingEpisodesWithinSeasonsHelp": "Questo deve anche essere abilitato per le librerie TV nella configurazione del server.", "DisplayMissingEpisodesWithinSeasonsHelp": "Questo deve anche essere abilitato per le librerie TV nella configurazione del server.",
"DisplayModeHelp": "Scegli il tipo di schermo su cui stai utilizzando Jellyfin.", "DisplayModeHelp": "Seleziona lo stile del layout che vuoi per l'interfaccia.",
"DoNotRecord": "Non registrare", "DoNotRecord": "Non registrare",
"Down": "Giù", "Down": "Giù",
"Download": "Scarica", "Download": "Scarica",
@ -264,7 +264,7 @@
"HeaderAddUser": "Aggiungi utente", "HeaderAddUser": "Aggiungi utente",
"HeaderAdditionalParts": "Parti addizionali", "HeaderAdditionalParts": "Parti addizionali",
"HeaderAdmin": "Admin", "HeaderAdmin": "Admin",
"HeaderAlbumArtists": "Artisti dell' Album", "HeaderAlbumArtists": "Artisti degli Album",
"HeaderAlbums": "Album", "HeaderAlbums": "Album",
"HeaderAlert": "Avviso", "HeaderAlert": "Avviso",
"HeaderAllowMediaDeletionFrom": "Abilita Eliminazione Media Da", "HeaderAllowMediaDeletionFrom": "Abilita Eliminazione Media Da",
@ -572,7 +572,7 @@
"LabelEvent": "Evento:", "LabelEvent": "Evento:",
"LabelEveryXMinutes": "Tutti:", "LabelEveryXMinutes": "Tutti:",
"LabelExtractChaptersDuringLibraryScan": "Estrarre immagini capitolo durante la scansione della libreria", "LabelExtractChaptersDuringLibraryScan": "Estrarre immagini capitolo durante la scansione della libreria",
"LabelExtractChaptersDuringLibraryScanHelp": "Genera le immagini del capitolo quando i video vengono importati durante la scansione della libreria. Altrimenti verranno estratti durante l'operazione pianificata di estrazione delle immagini capitolo, permettendo la scansione della libreria più velocemente.", "LabelExtractChaptersDuringLibraryScanHelp": "Genera le immagini capitolo quando i video vengono importati durante la scansione della libreria. Alternativamente, verranno estratti durante l'operazione pianificata di estrazione delle immagini capitolo, permettendo la scansione della libreria più velocemente.",
"LabelFailed": "Fallito", "LabelFailed": "Fallito",
"LabelFileOrUrl": "File o URL:", "LabelFileOrUrl": "File o URL:",
"LabelFinish": "Finito", "LabelFinish": "Finito",
@ -901,16 +901,16 @@
"NoNextUpItemsMessage": "Trovato niente. Inizia a guardare i tuoi programmi!", "NoNextUpItemsMessage": "Trovato niente. Inizia a guardare i tuoi programmi!",
"NoPluginConfigurationMessage": "Questo Plugin non ha impostazioni da configurare.", "NoPluginConfigurationMessage": "Questo Plugin non ha impostazioni da configurare.",
"NoSubtitleSearchResultsFound": "Nessun risultato.", "NoSubtitleSearchResultsFound": "Nessun risultato.",
"NoSubtitles": "Nessun Sottotitolo", "NoSubtitles": "Nessuno",
"NoSubtitlesHelp": "I sottotitoli non verranno caricati per impostazione predefinita.Possono essere ancora caricati manualmente durante la riproduzione.", "NoSubtitlesHelp": "I sottotitoli non verranno caricati per impostazione predefinita.Possono essere ancora caricati manualmente durante la riproduzione.",
"None": "Nessuno", "None": "Nessuno",
"Normal": "Normale", "Normal": "Normale",
"NumLocationsValue": "{0} cartelle", "NumLocationsValue": "{0} cartelle",
"Off": "Spento", "Off": "Spento",
"OneChannel": "Un canale", "OneChannel": "Un canale",
"OnlyForcedSubtitles": "Solo i sottotitoli forzati", "OnlyForcedSubtitles": "Solo forzati",
"OnlyForcedSubtitlesHelp": "Solo i sottotitoli contrassegnati come forzati saranno caricati.", "OnlyForcedSubtitlesHelp": "Solo i sottotitoli contrassegnati come forzati saranno caricati.",
"OnlyImageFormats": "Solo formati immagine (VOBSUB, PGS, SUB, ecc)", "OnlyImageFormats": "Solo formati immagine (VOBSUB, PGS, SUB)",
"OptionAdminUsers": "Amministratori", "OptionAdminUsers": "Amministratori",
"OptionAlbumArtist": "Artista Album", "OptionAlbumArtist": "Artista Album",
"OptionAllUsers": "Tutti gli utenti", "OptionAllUsers": "Tutti gli utenti",
@ -947,8 +947,8 @@
"OptionCustomUsers": "Personalizza", "OptionCustomUsers": "Personalizza",
"OptionDaily": "Giornaliero", "OptionDaily": "Giornaliero",
"OptionDateAdded": "Aggiunto il", "OptionDateAdded": "Aggiunto il",
"OptionDateAddedFileTime": "Utilizzare file di data di creazione", "OptionDateAddedFileTime": "Utilizzare la data di creazione del file",
"OptionDateAddedImportTime": "Utilizza la data scansionato in biblioteca", "OptionDateAddedImportTime": "Utilizza la data di scansione nella libreria",
"OptionDatePlayed": "Visto il", "OptionDatePlayed": "Visto il",
"OptionDescending": "Decrescente", "OptionDescending": "Decrescente",
"OptionDisableUser": "Disabilita questo utente", "OptionDisableUser": "Disabilita questo utente",
@ -1013,7 +1013,7 @@
"OptionReportByteRangeSeekingWhenTranscodingHelp": "Questo è necessario per alcuni dispositivi che non hanno l'avanzamento rapido che funziona bene.", "OptionReportByteRangeSeekingWhenTranscodingHelp": "Questo è necessario per alcuni dispositivi che non hanno l'avanzamento rapido che funziona bene.",
"OptionRequirePerfectSubtitleMatch": "Scarica solo i sottotitoli che corrispondono perfettamente ai miei file video", "OptionRequirePerfectSubtitleMatch": "Scarica solo i sottotitoli che corrispondono perfettamente ai miei file video",
"OptionRequirePerfectSubtitleMatchHelp": "La richiesta di una corrispondenza perfetta filtrerà i sottotitoli per includere solo quelli che sono stati testati e verificati con il file video esatto. Deselezionando questo aumenterà la probabilità che i sottotitoli vengono scaricati, ma aumenteranno le probabilità di testo sottotitolato impreciso o errato.", "OptionRequirePerfectSubtitleMatchHelp": "La richiesta di una corrispondenza perfetta filtrerà i sottotitoli per includere solo quelli che sono stati testati e verificati con il file video esatto. Deselezionando questo aumenterà la probabilità che i sottotitoli vengono scaricati, ma aumenteranno le probabilità di testo sottotitolato impreciso o errato.",
"OptionResElement": "elemento res", "OptionResElement": "res element",
"OptionResumable": "Interrotto", "OptionResumable": "Interrotto",
"OptionRuntime": "Durata", "OptionRuntime": "Durata",
"OptionSaturday": "Sabato", "OptionSaturday": "Sabato",
@ -1076,7 +1076,7 @@
"Programs": "Programmi", "Programs": "Programmi",
"Quality": "Qualità", "Quality": "Qualità",
"QueueAllFromHere": "In coda tutto da qui in poi", "QueueAllFromHere": "In coda tutto da qui in poi",
"Raised": "Sospeso", "Raised": "Rilievo",
"Rate": "Vota", "Rate": "Vota",
"RecentlyWatched": "Visti di recente", "RecentlyWatched": "Visti di recente",
"RecommendationBecauseYouLike": "Perché ti piace {0}", "RecommendationBecauseYouLike": "Perché ti piace {0}",
@ -1168,7 +1168,7 @@
"SystemDlnaProfilesHelp": "I profili di sistema sono in sola lettura. Le modifiche ad un profilo di sistema verranno salvate in un nuovo profilo personalizzato.", "SystemDlnaProfilesHelp": "I profili di sistema sono in sola lettura. Le modifiche ad un profilo di sistema verranno salvate in un nuovo profilo personalizzato.",
"TabAccess": "Accesso", "TabAccess": "Accesso",
"TabAdvanced": "Avanzato", "TabAdvanced": "Avanzato",
"TabAlbumArtists": "Artisti degli album", "TabAlbumArtists": "Artisti degli Album",
"TabAlbums": "Album", "TabAlbums": "Album",
"TabArtists": "Artisti", "TabArtists": "Artisti",
"TabCatalog": "Catalogo", "TabCatalog": "Catalogo",
@ -1312,7 +1312,7 @@
"HeaderFavoriteArtists": "Artisti Preferiti", "HeaderFavoriteArtists": "Artisti Preferiti",
"HeaderFavoriteSongs": "Brani Preferiti", "HeaderFavoriteSongs": "Brani Preferiti",
"HeaderFavoriteVideos": "Video Preferiti", "HeaderFavoriteVideos": "Video Preferiti",
"HeaderFetcherSettings": "Impostazioni Fetcher", "HeaderFetcherSettings": "Impostazioni del Fetcher",
"HeaderImageOptions": "Opzioni Immagine", "HeaderImageOptions": "Opzioni Immagine",
"HeaderRestartingServer": "Riavvio Server", "HeaderRestartingServer": "Riavvio Server",
"Home": "Home", "Home": "Home",
@ -1467,5 +1467,8 @@
"LabelCorruptedFrames": "Frame corrotti:", "LabelCorruptedFrames": "Frame corrotti:",
"AskAdminToCreateLibrary": "Chiedi ad un amministratore di creare una libreria.", "AskAdminToCreateLibrary": "Chiedi ad un amministratore di creare una libreria.",
"AllowFfmpegThrottlingHelp": "Quando una transcodifica o un remux sono abbastanza avanti rispetto alla corrente posizione di riproduzione, pausa il processo così da consumare meno risorse. Questo è utile quando si guarda un video senza avanzare spesso durante la riproduzione. Disattiva questa opzione se stai avendo problemi di riproduzione.", "AllowFfmpegThrottlingHelp": "Quando una transcodifica o un remux sono abbastanza avanti rispetto alla corrente posizione di riproduzione, pausa il processo così da consumare meno risorse. Questo è utile quando si guarda un video senza avanzare spesso durante la riproduzione. Disattiva questa opzione se stai avendo problemi di riproduzione.",
"AllowFfmpegThrottling": "Acceleratore Transcodifica" "AllowFfmpegThrottling": "Acceleratore Transcodifica",
"PreferEmbeddedEpisodeInfosOverFileNames": "Preferisci le informazioni incorporate nell'episodio rispetto ai nomi dei file",
"PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Questo utilizza le informazioni dell'episodio provenienti dai metadata incorporati, se disponibili.",
"ClientSettings": "Impostazioni del client"
} }

View file

@ -1467,5 +1467,8 @@
"PlaybackErrorNoCompatibleStream": "Houve um erro na criação de perfil do cliente e o servidor não está enviando um formato de mídia compatível.", "PlaybackErrorNoCompatibleStream": "Houve um erro na criação de perfil do cliente e o servidor não está enviando um formato de mídia compatível.",
"EnableFastImageFadeInHelp": "Habilitar animações rápidas de aparecimento para imagens carregadas", "EnableFastImageFadeInHelp": "Habilitar animações rápidas de aparecimento para imagens carregadas",
"LabelDroppedFrames": "Quadros caídos:", "LabelDroppedFrames": "Quadros caídos:",
"AllowFfmpegThrottlingHelp": "Quando uma transcodificação ou remux estiver suficientemente avançada da posição atual de reprodução, pause o processo para que consuma menos recursos. Isso é mais proveitoso para quando não há avanço ou retrocesso do vídeo com frequência. Desative se tiver problemas de reprodução." "AllowFfmpegThrottlingHelp": "Quando uma transcodificação ou remux estiver suficientemente avançada da posição atual de reprodução, pause o processo para que consuma menos recursos. Isso é mais proveitoso para quando não há avanço ou retrocesso do vídeo com frequência. Desative se tiver problemas de reprodução.",
"PreferEmbeddedEpisodeInfosOverFileNames": "Preferir as informações incorporadas nos arquivos dos episódios ao invés dos nomes",
"PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Isso utiliza as informações dos episódios incorporadas nos metadados dos arquivos se estiverem disponíveis.",
"ClientSettings": "Configurações do cliente"
} }

View file

@ -229,7 +229,7 @@
"AllLibraries": "Toate librăriile", "AllLibraries": "Toate librăriile",
"AllLanguages": "Toate limbile", "AllLanguages": "Toate limbile",
"AllEpisodes": "Toate episoadele", "AllEpisodes": "Toate episoadele",
"AllComplexFormats": "Toate formatele complexe (ASS, SSA, VOBSUB, PGS, SUB/IDX, etc.)", "AllComplexFormats": "Toate formatele complexe (ASS, SSA, VOBSUB, PGS, SUB, IDX)",
"AllChannels": "Toate canalele", "AllChannels": "Toate canalele",
"Alerts": "Alerte", "Alerts": "Alerte",
"Albums": "Albume", "Albums": "Albume",
@ -251,8 +251,8 @@
"Collections": "Colecții", "Collections": "Colecții",
"AllowRemoteAccess": "Permite conexiuni externe către serverul Jellyfin.", "AllowRemoteAccess": "Permite conexiuni externe către serverul Jellyfin.",
"AllowRemoteAccessHelp": "Dacă este nebifat, toate conexiunile externe vor fi blocate.", "AllowRemoteAccessHelp": "Dacă este nebifat, toate conexiunile externe vor fi blocate.",
"AlwaysPlaySubtitles": "Întotdeauna folosește subtitrări", "AlwaysPlaySubtitles": "Întotdeauna arată",
"AnyLanguage": "Orice limbă", "AnyLanguage": "Orice Limbă",
"Anytime": "Oricând", "Anytime": "Oricând",
"Art": "Artă", "Art": "Artă",
"AlwaysPlaySubtitlesHelp": "Subtitrările care se potrivesc cu preferințele limbii utilizate vor fi încărcate indiferent de limba audio.", "AlwaysPlaySubtitlesHelp": "Subtitrările care se potrivesc cu preferințele limbii utilizate vor fi încărcate indiferent de limba audio.",
@ -288,7 +288,7 @@
"Director": "Regizor", "Director": "Regizor",
"AllowOnTheFlySubtitleExtractionHelp": "Subtitrările încorporate pot fi extrase din video și transmise către client în mod text pentru a preveni transcodarea videoului. Pe unele sisteme acest lucru poate dura mult timp și poate cauza oprirea redării video în timpul procesului de extragere. Dezactivează opțiunea pentru a avea subtitrările încorporate incluse în videoul transcodat atunci când nu sunt nativ suportate de către dispozitivul client.", "AllowOnTheFlySubtitleExtractionHelp": "Subtitrările încorporate pot fi extrase din video și transmise către client în mod text pentru a preveni transcodarea videoului. Pe unele sisteme acest lucru poate dura mult timp și poate cauza oprirea redării video în timpul procesului de extragere. Dezactivează opțiunea pentru a avea subtitrările încorporate incluse în videoul transcodat atunci când nu sunt nativ suportate de către dispozitivul client.",
"BirthLocation": "Locul nașterii", "BirthLocation": "Locul nașterii",
"BurnSubtitlesHelp": "Determină dacă serverul ar trebui să includă subtitrări când face conversia video depinzând de formatul subtitrărilor. Evitând includerea subtitrărilor va îmbunătăți performanța serverului. Selectează Auto pentru includerea formaturilor bazate pe imagini (VOBSUB, PGS, SUB/IDX, etc) și anumitor subtitrări ASS/SSA.", "BurnSubtitlesHelp": "Determină dacă serverul ar trebui să includă subtitrări când face transcodarea video. Evitând acest lucru va îmbunătăți performanța serverului. Selectează Auto pentru includerea formaturilor bazate pe imagini (VOBSUB, PGS, SUB, IDX) și anumitor subtitrări ASS sau SSA.",
"ButtonPreviousTrack": "Calea anterioară", "ButtonPreviousTrack": "Calea anterioară",
"ButtonRevoke": "Revocă", "ButtonRevoke": "Revocă",
"ButtonSettings": "Setări", "ButtonSettings": "Setări",
@ -588,7 +588,7 @@
"DisplayInOtherHomeScreenSections": "Afișați în secțiuni ecranul principal, cum ar fi cele mai noi suporturi și continuați să vizionați", "DisplayInOtherHomeScreenSections": "Afișați în secțiuni ecranul principal, cum ar fi cele mai noi suporturi și continuați să vizionați",
"DisplayMissingEpisodesWithinSeasons": "Afișați episoade lipsă din sezoane", "DisplayMissingEpisodesWithinSeasons": "Afișați episoade lipsă din sezoane",
"DisplayMissingEpisodesWithinSeasonsHelp": "Acesta trebuie de asemenea activat pentru bibliotecile TV din configurația serverului.", "DisplayMissingEpisodesWithinSeasonsHelp": "Acesta trebuie de asemenea activat pentru bibliotecile TV din configurația serverului.",
"DisplayModeHelp": "Selectați tipul de ecran pe care executați Jellyfin.", "DisplayModeHelp": "Selectați stilul schemei pe care îl doriți pentru interfață.",
"Download": "Descarcă", "Download": "Descarcă",
"DrmChannelsNotImported": "Canalele cu DRM nu vor fi importate.", "DrmChannelsNotImported": "Canalele cu DRM nu vor fi importate.",
"DropShadow": "Umbra", "DropShadow": "Umbra",
@ -1000,16 +1000,16 @@
"OptionAlbum": "Album", "OptionAlbum": "Album",
"OptionAdminUsers": "Administratorii", "OptionAdminUsers": "Administratorii",
"Option3D": "3D", "Option3D": "3D",
"OnlyImageFormats": "Numai formate de imagine (VOBSUB, PGS, SUB, etc)", "OnlyImageFormats": "Numai formate de imagine (VOBSUB, PGS, SUB)",
"OnlyForcedSubtitlesHelp": "Se vor încărca doar subtitrările marcate drept forțate.", "OnlyForcedSubtitlesHelp": "Se vor încărca doar subtitrările marcate drept forțate.",
"OnlyForcedSubtitles": "Numai subtitrări forțate", "OnlyForcedSubtitles": "Numai forțate",
"OneChannel": "Un canal", "OneChannel": "Un canal",
"Off": "Oprit", "Off": "Oprit",
"NumLocationsValue": "{0} dosare", "NumLocationsValue": "{0} dosare",
"Normal": "Normal", "Normal": "Normal",
"None": "Nici unul", "None": "Nici unul",
"NoSubtitlesHelp": "Subtitrările nu vor fi încărcate în mod implicit. Acestea pot fi însă activate manual în timpul redării.", "NoSubtitlesHelp": "Subtitrările nu vor fi încărcate în mod implicit. Acestea pot fi însă activate manual în timpul redării.",
"NoSubtitles": "Fără subtitrare", "NoSubtitles": "Fără",
"NoSubtitleSearchResultsFound": "Nici un rezultat găsit.", "NoSubtitleSearchResultsFound": "Nici un rezultat găsit.",
"NoPluginConfigurationMessage": "Acest plugin nu are setări de configurat.", "NoPluginConfigurationMessage": "Acest plugin nu are setări de configurat.",
"NoNewDevicesFound": "Nu s-au găsit dispozitive noi. Pentru a adăuga un nou tuner, închideți acest dialog și introduceți informațiile dispozitivului manual.", "NoNewDevicesFound": "Nu s-au găsit dispozitive noi. Pentru a adăuga un nou tuner, închideți acest dialog și introduceți informațiile dispozitivului manual.",
@ -1466,5 +1466,19 @@
"AskAdminToCreateLibrary": "Cereți unui administrator să creeze o bibliotecă.", "AskAdminToCreateLibrary": "Cereți unui administrator să creeze o bibliotecă.",
"PlaybackErrorNoCompatibleStream": "A apărut o problemă cu profilarea clientului, iar serverul nu trimite un format media compatibil.", "PlaybackErrorNoCompatibleStream": "A apărut o problemă cu profilarea clientului, iar serverul nu trimite un format media compatibil.",
"AllowFfmpegThrottlingHelp": "Când un transcod sau un remux se află destul de departe înainte de poziția actuală de redare, întrerupeți procesul, astfel încât să consume mai puține resurse. Acest lucru este cel mai util când priviți fără a derula des. Dezactivați acestă opțiune dacă întâmpinați probleme de redare.", "AllowFfmpegThrottlingHelp": "Când un transcod sau un remux se află destul de departe înainte de poziția actuală de redare, întrerupeți procesul, astfel încât să consume mai puține resurse. Acest lucru este cel mai util când priviți fără a derula des. Dezactivați acestă opțiune dacă întâmpinați probleme de redare.",
"AllowFfmpegThrottling": "Accelerare Transcod-uri" "AllowFfmpegThrottling": "Accelerare Transcod-uri",
"Track": "Cale",
"Season": "Sezon",
"ReleaseGroup": "Gruparea lansării",
"PreferEmbeddedEpisodeInfosOverFileNames": "Preferați informațiile despre episod încorporate în fișier decât numele fișierelor",
"PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Aceasta folosește informațiile despre episod din metadatele încorporate, dacă sunt disponibile.",
"Person": "Persoană",
"OtherArtist": "Alt artist",
"Movie": "Film",
"Episode": "Episod",
"ClientSettings": "Setări pentru client",
"BoxSet": "Set de colecție",
"Artist": "Artist",
"AlbumArtist": "Artistul albumului",
"Album": "Album"
} }

View file

@ -1468,5 +1468,8 @@
"AskAdminToCreateLibrary": "Pokiaľ chcete vytvoriť knižnicu, musíte sa spýtať administrátora.", "AskAdminToCreateLibrary": "Pokiaľ chcete vytvoriť knižnicu, musíte sa spýtať administrátora.",
"PlaybackErrorNoCompatibleStream": "Nastal problém s profilom klienta a server preto neposiela kompatibilný mediálny formát.", "PlaybackErrorNoCompatibleStream": "Nastal problém s profilom klienta a server preto neposiela kompatibilný mediálny formát.",
"AllowFfmpegThrottlingHelp": "Keď sa transkódovanie alebo remuxovanie dostane do bodu, kedy je dostatočne vopred voči súčasnej polohe prehrávania, pozastaví proces aby spotrebovával menej zdrojov. Toto je najviac užitočné, keď sa pozerá obsah bez pretáčania. Vypnite túto možnosť, pokiaľ má vaše prehrávanie problémy.", "AllowFfmpegThrottlingHelp": "Keď sa transkódovanie alebo remuxovanie dostane do bodu, kedy je dostatočne vopred voči súčasnej polohe prehrávania, pozastaví proces aby spotrebovával menej zdrojov. Toto je najviac užitočné, keď sa pozerá obsah bez pretáčania. Vypnite túto možnosť, pokiaľ má vaše prehrávanie problémy.",
"AllowFfmpegThrottling": "Obmedzenie transkódovania" "AllowFfmpegThrottling": "Obmedzenie transkódovania",
"PreferEmbeddedEpisodeInfosOverFileNames": "Preferovať vložené informácie o epizóde pred názvom súboru",
"PreferEmbeddedEpisodeInfosOverFileNamesHelp": "Toto využíva informácie o epizóde z vložených metadát, pokiaľ sú dostupne.",
"ClientSettings": "Nastavenie klienta"
} }

View file

@ -217,7 +217,7 @@
"EveryNDays": "每 {0} 天", "EveryNDays": "每 {0} 天",
"ExitFullscreen": "退出全屏", "ExitFullscreen": "退出全屏",
"ExtraLarge": "特大", "ExtraLarge": "特大",
"ExtractChapterImagesHelp": "提取章节图像将允许客户端显示一个图像形式的场景选择菜单。这个提取的过程可能会非常缓慢、占用大量 CPU 资源并且可能需要几个GB的硬盘空间。提取将会在视频被发现时启动同时也作为一个夜间计划任务运行。这个任务可以在“计划任务”选项中进行设置。不建议在高峰使用时间运行这个任务。", "ExtractChapterImagesHelp": "提取剧集图片将允许客户端显示一个图像形式的场景选择菜单。这个提取的过程可能会非常缓慢、占用大量 CPU 资源并且可能需要几个GB的硬盘空间。提取将会在视频被发现时启动同时也作为一个夜间计划任务运行。这个任务可以在“计划任务”选项中进行设置。不建议在高峰使用时间运行这个任务。",
"Extras": "额外", "Extras": "额外",
"FFmpegSavePathNotFound": "我们无法通过你输入的路径定位 FFmpeg。FFprobe 同样也是必要的并且应该被放在同一个文件夹中。他们通常会被打包在一起以供下载。请检查这个路径然后再试一次。", "FFmpegSavePathNotFound": "我们无法通过你输入的路径定位 FFmpeg。FFprobe 同样也是必要的并且应该被放在同一个文件夹中。他们通常会被打包在一起以供下载。请检查这个路径然后再试一次。",
"FastForward": "快进", "FastForward": "快进",
@ -277,7 +277,7 @@
"HeaderCastCrew": "演职人员", "HeaderCastCrew": "演职人员",
"HeaderChannelAccess": "频道访问", "HeaderChannelAccess": "频道访问",
"HeaderChannels": "频道", "HeaderChannels": "频道",
"HeaderChapterImages": "章节图片", "HeaderChapterImages": "剧集图片",
"HeaderCodecProfile": "编解码器配置", "HeaderCodecProfile": "编解码器配置",
"HeaderCodecProfileHelp": "编解码器的配置文件标明了设备播放特定编码时的限制。如果在限制之内则媒体将被转码,否则编解码器将被配置为直接播放。", "HeaderCodecProfileHelp": "编解码器的配置文件标明了设备播放特定编码时的限制。如果在限制之内则媒体将被转码,否则编解码器将被配置为直接播放。",
"HeaderConfigureRemoteAccess": "配置远程访问", "HeaderConfigureRemoteAccess": "配置远程访问",
@ -568,8 +568,8 @@
"LabelEpisodeNumber": "集号:", "LabelEpisodeNumber": "集号:",
"LabelEvent": "事件:", "LabelEvent": "事件:",
"LabelEveryXMinutes": "每:", "LabelEveryXMinutes": "每:",
"LabelExtractChaptersDuringLibraryScan": "媒体库扫描过程中解压章节图像", "LabelExtractChaptersDuringLibraryScan": "媒体库扫描过程中解压剧集图片",
"LabelExtractChaptersDuringLibraryScanHelp": "当媒体库导入视频并扫描时,将提取章节图像。否则,章节图像将在之后的计划任务提取,而媒体库会更快完成扫描。", "LabelExtractChaptersDuringLibraryScanHelp": "当媒体库导入视频并扫描时,将提取剧集图片。否则,剧集图片将在之后的计划任务提取,而媒体库会更快完成扫描。",
"LabelFailed": "失败", "LabelFailed": "失败",
"LabelFileOrUrl": "文件或网址:", "LabelFileOrUrl": "文件或网址:",
"LabelFinish": "完成", "LabelFinish": "完成",
@ -998,7 +998,7 @@
"OptionEstimateContentLength": "转码时,估计内容长度", "OptionEstimateContentLength": "转码时,估计内容长度",
"OptionEveryday": "每天", "OptionEveryday": "每天",
"OptionExternallyDownloaded": "外部下载", "OptionExternallyDownloaded": "外部下载",
"OptionExtractChapterImage": "开启章节图像提取", "OptionExtractChapterImage": "开启剧集图片提取",
"OptionFavorite": "我的最爱", "OptionFavorite": "我的最爱",
"OptionFriday": "星期五", "OptionFriday": "星期五",
"OptionHasSpecialFeatures": "特殊功能", "OptionHasSpecialFeatures": "特殊功能",

164
yarn.lock
View file

@ -1649,11 +1649,6 @@ better-assert@~1.0.0:
dependencies: dependencies:
callsite "1.0.0" callsite "1.0.0"
big.js@^3.1.3:
version "3.2.0"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e"
integrity sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q==
big.js@^5.2.2: big.js@^5.2.2:
version "5.2.2" version "5.2.2"
resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328"
@ -2129,6 +2124,14 @@ camel-case@3.0.x:
no-case "^2.2.0" no-case "^2.2.0"
upper-case "^1.1.1" upper-case "^1.1.1"
camel-case@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.1.tgz#1fc41c854f00e2f7d0139dfeba1542d6896fe547"
integrity sha512-7fa2WcG4fYFkclIvEmxBbTvmibwF2/agfEBc6q3lOpVu0A13ltLsA+Hr/8Hp6kp5f+G7hKi6t8lys6XxP+1K6Q==
dependencies:
pascal-case "^3.1.1"
tslib "^1.10.0"
camelcase-keys@^2.0.0: camelcase-keys@^2.0.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7"
@ -2317,7 +2320,7 @@ class-utils@^0.3.5:
isobject "^3.0.0" isobject "^3.0.0"
static-extend "^0.1.1" static-extend "^0.1.1"
clean-css@4.2.x: clean-css@4.2.x, clean-css@^4.2.3:
version "4.2.3" version "4.2.3"
resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78" resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.3.tgz#507b5de7d97b48ee53d84adb0160ff6216380f78"
integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA== integrity sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==
@ -2530,6 +2533,11 @@ commander@^2.2.0, commander@^2.20.0:
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
commander@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068"
integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==
commander@~2.13.0: commander@~2.13.0:
version "2.13.0" version "2.13.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
@ -3463,6 +3471,14 @@ domutils@^1.5.1, domutils@^1.7.0:
dom-serializer "0" dom-serializer "0"
domelementtype "1" domelementtype "1"
dot-case@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.3.tgz#21d3b52efaaba2ea5fda875bb1aa8124521cf4aa"
integrity sha512-7hwEmg6RiSQfm/GwPL4AAWXKy3YNNZA3oFv2Pdiey0mwkRCPZ9x6SZbkLcn8Ma5PYeVokzoD4Twv2n7LKp5WeA==
dependencies:
no-case "^3.0.3"
tslib "^1.10.0"
dot-prop@^5.2.0: dot-prop@^5.2.0:
version "5.2.0" version "5.2.0"
resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb" resolved "https://registry.yarnpkg.com/dot-prop/-/dot-prop-5.2.0.tgz#c34ecc29556dc45f1f4c22697b6f4904e0cc4fcb"
@ -3595,7 +3611,7 @@ elliptic@^6.0.0:
minimalistic-assert "^1.0.0" minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.0" minimalistic-crypto-utils "^1.0.0"
eme-encryption-scheme-polyfill@^2.0.0: eme-encryption-scheme-polyfill@^2.0.1:
version "2.0.1" version "2.0.1"
resolved "https://registry.yarnpkg.com/eme-encryption-scheme-polyfill/-/eme-encryption-scheme-polyfill-2.0.1.tgz#b080b01bffd74c75c9cf8044c1cabedf3b83954f" resolved "https://registry.yarnpkg.com/eme-encryption-scheme-polyfill/-/eme-encryption-scheme-polyfill-2.0.1.tgz#b080b01bffd74c75c9cf8044c1cabedf3b83954f"
integrity sha512-Wz+Ro1c0/2Wsx2RLFvTOO0m4LvYn+7cSnq3XOvRvLLBq8jbvUACH/zpU9s0/5+mQa5oaelkU69x+q0z/iWYrFA== integrity sha512-Wz+Ro1c0/2Wsx2RLFvTOO0m4LvYn+7cSnq3XOvRvLLBq8jbvUACH/zpU9s0/5+mQa5oaelkU69x+q0z/iWYrFA==
@ -4286,13 +4302,13 @@ file-entry-cache@^5.0.1:
dependencies: dependencies:
flat-cache "^2.0.1" flat-cache "^2.0.1"
file-loader@^5.0.2: file-loader@^6.0.0:
version "5.1.0" version "6.0.0"
resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-5.1.0.tgz#cb56c070efc0e40666424309bd0d9e45ac6f2bb8" resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.0.0.tgz#97bbfaab7a2460c07bcbd72d3a6922407f67649f"
integrity sha512-u/VkLGskw3Ue59nyOwUwXI/6nuBCo7KBkniB/l7ICwr/7cPNGsL1WCXUp3GB0qgOOKU1TiP49bv4DZF/LJqprg== integrity sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ==
dependencies: dependencies:
loader-utils "^1.4.0" loader-utils "^2.0.0"
schema-utils "^2.5.0" schema-utils "^2.6.5"
file-type@5.2.0, file-type@^5.2.0: file-type@5.2.0, file-type@^5.2.0:
version "5.2.0" version "5.2.0"
@ -5372,7 +5388,7 @@ hash.js@^1.0.0, hash.js@^1.0.3:
inherits "^2.0.3" inherits "^2.0.3"
minimalistic-assert "^1.0.1" minimalistic-assert "^1.0.1"
he@1.2.x: he@1.2.x, he@^1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
@ -5446,7 +5462,20 @@ html-entities@^1.2.1:
resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f"
integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8= integrity sha1-DfKTUfByEWNRXfueVUPl9u7VFi8=
html-minifier@^3.2.3, html-minifier@^3.5.20: html-minifier-terser@^5.0.1:
version "5.0.5"
resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.0.5.tgz#8f12f639789f04faa9f5cf2ff9b9f65607f21f8b"
integrity sha512-cBSFFghQh/uHcfSiL42KxxIRMF7A144+3E44xdlctIjxEmkEfCvouxNyFH2wysXk1fCGBPwtcr3hDWlGTfkDew==
dependencies:
camel-case "^4.1.1"
clean-css "^4.2.3"
commander "^4.1.1"
he "^1.2.0"
param-case "^3.0.3"
relateurl "^0.2.7"
terser "^4.6.3"
html-minifier@^3.5.20:
version "3.5.21" version "3.5.21"
resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c" resolved "https://registry.yarnpkg.com/html-minifier/-/html-minifier-3.5.21.tgz#d0040e054730e354db008463593194015212d20c"
integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA== integrity sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==
@ -5469,17 +5498,16 @@ html-tags@^3.1.0:
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140" resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140"
integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg== integrity sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==
html-webpack-plugin@^3.2.0: html-webpack-plugin@^4.0.2:
version "3.2.0" version "4.0.2"
resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-3.2.0.tgz#b01abbd723acaaa7b37b6af4492ebda03d9dd37b" resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.0.2.tgz#c96a48d0ee53d33dcc909d6b65ad28f3d627efd4"
integrity sha1-sBq71yOsqqeze2r0SS69oD2d03s= integrity sha512-dCyjg2dEBf0Azni2byDcwfk5l5XKNEnA3OU4cejovqkKGc4ZixC6Aw6+U2sAG/ellHIjoiQhyU4oKMO6fQFaYA==
dependencies: dependencies:
html-minifier "^3.2.3" html-minifier-terser "^5.0.1"
loader-utils "^0.2.16" loader-utils "^1.2.3"
lodash "^4.17.3" lodash "^4.17.15"
pretty-error "^2.0.2" pretty-error "^2.1.1"
tapable "^1.0.0" tapable "^1.1.3"
toposort "^1.0.0"
util.promisify "1.0.0" util.promisify "1.0.0"
htmlparser2@^3.10.0, htmlparser2@^3.3.0: htmlparser2@^3.10.0, htmlparser2@^3.3.0:
@ -6409,11 +6437,6 @@ json3@^3.3.2:
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81"
integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==
json5@^0.5.0:
version "0.5.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821"
integrity sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=
json5@^1.0.1: json5@^1.0.1:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe"
@ -6576,9 +6599,9 @@ levn@^0.3.0, levn@~0.3.0:
prelude-ls "~1.1.2" prelude-ls "~1.1.2"
type-check "~0.3.2" type-check "~0.3.2"
"libass-wasm@https://github.com/jellyfin/JavascriptSubtitlesOctopus": "libass-wasm@https://github.com/jellyfin/JavascriptSubtitlesOctopus#4.0.0-jf":
version "4.0.0" version "4.0.0"
resolved "https://github.com/jellyfin/JavascriptSubtitlesOctopus#1d12af0b04fb2337570b57d706dd97db2f904b9d" resolved "https://github.com/jellyfin/JavascriptSubtitlesOctopus#7e6b75dcab9f7dad12719983510d05242803707c"
liftoff@^3.1.0: liftoff@^3.1.0:
version "3.1.0" version "3.1.0"
@ -6644,16 +6667,6 @@ loader-utils@1.2.3:
emojis-list "^2.0.0" emojis-list "^2.0.0"
json5 "^1.0.1" json5 "^1.0.1"
loader-utils@^0.2.16:
version "0.2.17"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348"
integrity sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=
dependencies:
big.js "^3.1.3"
emojis-list "^2.0.0"
json5 "^0.5.0"
object-assign "^4.0.1"
loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0:
version "1.4.0" version "1.4.0"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613"
@ -6663,6 +6676,15 @@ loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0:
emojis-list "^3.0.0" emojis-list "^3.0.0"
json5 "^1.0.1" json5 "^1.0.1"
loader-utils@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0"
integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ==
dependencies:
big.js "^5.2.2"
emojis-list "^3.0.0"
json5 "^2.1.2"
localtunnel@1.9.2: localtunnel@1.9.2:
version "1.9.2" version "1.9.2"
resolved "https://registry.yarnpkg.com/localtunnel/-/localtunnel-1.9.2.tgz#0012fcabc29cf964c130a01858768aa2bb65b5af" resolved "https://registry.yarnpkg.com/localtunnel/-/localtunnel-1.9.2.tgz#0012fcabc29cf964c130a01858768aa2bb65b5af"
@ -6840,7 +6862,7 @@ lodash.uniq@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=
lodash@^4.0.0, lodash@^4.1.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.3, lodash@^4.17.4, lodash@~4.17.12: lodash@^4.0.0, lodash@^4.1.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@~4.17.12:
version "4.17.15" version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
@ -6909,6 +6931,13 @@ lower-case@^1.1.1:
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac" resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-1.1.4.tgz#9a2cabd1b9e8e0ae993a4bf7d5875c39c42e8eac"
integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw= integrity sha1-miyr0bno4K6ZOkv31YdcOcQujqw=
lower-case@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.1.tgz#39eeb36e396115cc05e29422eaea9e692c9408c7"
integrity sha512-LiWgfDLLb1dwbFQZsSglpRj+1ctGnayXz3Uv0/WO8n558JycT5fg6zkNcnW0G68Nn0aEldTFeEfmjCfmqry/rQ==
dependencies:
tslib "^1.10.0"
lowercase-keys@1.0.0: lowercase-keys@1.0.0:
version "1.0.0" version "1.0.0"
resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306"
@ -7463,6 +7492,14 @@ no-case@^2.2.0:
dependencies: dependencies:
lower-case "^1.1.1" lower-case "^1.1.1"
no-case@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.3.tgz#c21b434c1ffe48b39087e86cfb4d2582e9df18f8"
integrity sha512-ehY/mVQCf9BL0gKfsJBvFJen+1V//U+0HQMPrWct40ixE4jnv0bfvxDbWtAHL9EcaPEOJHVVYKoQn1TlZUB8Tw==
dependencies:
lower-case "^2.0.1"
tslib "^1.10.0"
node-forge@0.9.0: node-forge@0.9.0:
version "0.9.0" version "0.9.0"
resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579"
@ -8062,6 +8099,14 @@ param-case@2.1.x:
dependencies: dependencies:
no-case "^2.2.0" no-case "^2.2.0"
param-case@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.3.tgz#4be41f8399eff621c56eebb829a5e451d9801238"
integrity sha512-VWBVyimc1+QrzappRs7waeN2YmoZFCGXWASRYX1/rGHtXqEcrGEIDm+jqIwFa2fRXNgQEwrxaYuIrX0WcAguTA==
dependencies:
dot-case "^3.0.3"
tslib "^1.10.0"
parent-module@^1.0.0: parent-module@^1.0.0:
version "1.0.1" version "1.0.1"
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
@ -8156,6 +8201,14 @@ parseurl@~1.3.2, parseurl@~1.3.3:
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==
pascal-case@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.1.tgz#5ac1975133ed619281e88920973d2cd1f279de5f"
integrity sha512-XIeHKqIrsquVTQL2crjq3NfJUxmdLasn3TYOU0VBM+UX2a6ztAWBlJQBePLGY7VHW8+2dRadeIPK5+KImwTxQA==
dependencies:
no-case "^3.0.3"
tslib "^1.10.0"
pascalcase@^0.1.1: pascalcase@^0.1.1:
version "0.1.1" version "0.1.1"
resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14"
@ -9135,7 +9188,7 @@ pretty-bytes@^5.3.0:
resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.3.0.tgz#f2849e27db79fb4d6cfe24764fc4134f165989f2"
integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg== integrity sha512-hjGrh+P926p4R4WbaB6OckyRtO0F0/lQBiT+0gnxjV+5kjPBrfVBFCsCLbMqVQeydvIoouYTCmmEURiH3R1Bdg==
pretty-error@^2.0.2: pretty-error@^2.1.1:
version "2.1.1" version "2.1.1"
resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3" resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.1.tgz#5f4f87c8f91e5ae3f3ba87ab4cf5e03b1a17f1a3"
integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM= integrity sha1-X0+HyPkeWuPzuoerTPXgOxoX8aM=
@ -9558,7 +9611,7 @@ regjsparser@^0.6.4:
dependencies: dependencies:
jsesc "~0.5.0" jsesc "~0.5.0"
relateurl@0.2.x: relateurl@0.2.x, relateurl@^0.2.7:
version "0.2.7" version "0.2.7"
resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9"
integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk= integrity sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=
@ -9951,7 +10004,7 @@ schema-utils@^1.0.0:
ajv-errors "^1.0.0" ajv-errors "^1.0.0"
ajv-keywords "^3.1.0" ajv-keywords "^3.1.0"
schema-utils@^2.5.0, schema-utils@^2.6.0, schema-utils@^2.6.4, schema-utils@^2.6.5: schema-utils@^2.6.0, schema-utils@^2.6.4, schema-utils@^2.6.5:
version "2.6.5" version "2.6.5"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.5.tgz#c758f0a7e624263073d396e29cd40aa101152d8a" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.6.5.tgz#c758f0a7e624263073d396e29cd40aa101152d8a"
integrity sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ== integrity sha512-5KXuwKziQrTVHh8j/Uxz+QUbxkaLW9X/86NBlx/gnKgtsZA2GIVMUn17qWhRFwF8jdYb3Dig5hRO/W5mZqy6SQ==
@ -10151,12 +10204,12 @@ sha.js@^2.4.0, sha.js@^2.4.8:
inherits "^2.0.1" inherits "^2.0.1"
safe-buffer "^5.0.1" safe-buffer "^5.0.1"
shaka-player@^2.5.9: shaka-player@^2.5.10:
version "2.5.9" version "2.5.10"
resolved "https://registry.yarnpkg.com/shaka-player/-/shaka-player-2.5.9.tgz#007dc19df2bb5d3d959d278b2d894af05adffe38" resolved "https://registry.yarnpkg.com/shaka-player/-/shaka-player-2.5.10.tgz#6f4e72e2433002d11824a223b02edd5004e30e2b"
integrity sha512-XavLBqxvIbvLOPfk7VKZu5fbMJyVko9bBfzxmMWdX5bvQwUSjU7ZhV8v2tHqXQYafpHml1hlGHzKkLs7idouNQ== integrity sha512-kS9TQL6bWODo4XNnozERZWsEiWlLZ6huspPx4ZjmMjeOBL9gwqlULLfLyO+5gA3CYV/dk9LaAi1WAEaLWckGpA==
dependencies: dependencies:
eme-encryption-scheme-polyfill "^2.0.0" eme-encryption-scheme-polyfill "^2.0.1"
shebang-command@^1.2.0: shebang-command@^1.2.0:
version "1.2.0" version "1.2.0"
@ -11143,7 +11196,7 @@ terser-webpack-plugin@^1.4.3:
webpack-sources "^1.4.0" webpack-sources "^1.4.0"
worker-farm "^1.7.0" worker-farm "^1.7.0"
terser@^4.0.0, terser@^4.1.2: terser@^4.0.0, terser@^4.1.2, terser@^4.6.3:
version "4.6.7" version "4.6.7"
resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.7.tgz#478d7f9394ec1907f0e488c5f6a6a9a2bad55e72" resolved "https://registry.yarnpkg.com/terser/-/terser-4.6.7.tgz#478d7f9394ec1907f0e488c5f6a6a9a2bad55e72"
integrity sha512-fmr7M1f7DBly5cX2+rFDvmGBAaaZyPrHYK4mMdHEDAdNTqXSZgSOfqsfGq2HqPGT/1V0foZZuCZFx8CHKgAk3g== integrity sha512-fmr7M1f7DBly5cX2+rFDvmGBAaaZyPrHYK4mMdHEDAdNTqXSZgSOfqsfGq2HqPGT/1V0foZZuCZFx8CHKgAk3g==
@ -11314,11 +11367,6 @@ toidentifier@1.0.0:
resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553"
integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==
toposort@^1.0.0:
version "1.0.7"
resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029"
integrity sha1-LmhELZ9k7HILjMieZEOsbKqVACk=
tough-cookie@~2.5.0: tough-cookie@~2.5.0:
version "2.5.0" version "2.5.0"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
@ -11371,7 +11419,7 @@ trough@^1.0.0:
dependencies: dependencies:
glob "^7.1.2" glob "^7.1.2"
tslib@^1.9.0: tslib@^1.10.0, tslib@^1.9.0:
version "1.11.1" version "1.11.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.11.1.tgz#eb15d128827fbee2841549e171f45ed338ac7e35"
integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA== integrity sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==