diff --git a/.ci/azure-pipelines-package.yml b/.ci/azure-pipelines-package.yml index 2249bd20eb..bf4234ec97 100644 --- a/.ci/azure-pipelines-package.yml +++ b/.ci/azure-pipelines-package.yml @@ -36,6 +36,14 @@ jobs: targetPath: '$(Build.SourcesDirectory)/deployment/dist' artifactName: 'jellyfin-web-$(BuildConfiguration)' + - task: SSH@0 + displayName: 'Create target directory on repository server' + condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')) + inputs: + sshEndpoint: repository + runOptions: 'inline' + inline: 'mkdir -p /srv/repository/incoming/azure/$(Build.BuildNumber)/$(BuildConfiguration)' + - task: CopyFilesOverSSH@0 displayName: 'Upload artifacts to repository server' condition: or(startsWith(variables['Build.SourceBranch'], 'refs/tags'), startsWith(variables['Build.SourceBranch'], 'refs/heads/master')) diff --git a/.dependabot/config.yml b/.dependabot/config.yml index 02dfd18aac..4ee827471a 100644 --- a/.dependabot/config.yml +++ b/.dependabot/config.yml @@ -2,4 +2,4 @@ version: 1 update_configs: - package_manager: "javascript" directory: "/" - update_schedule: "weekly" + update_schedule: "live" diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index a35eb9981f..186dbcd12c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,4 +1,6 @@ .ci @dkanada @EraYaN .github @jellyfin/core -build.sh @joshuaboniface +fedora @joshuaboniface +debian @joshuaboniface +.copr @joshuaboniface deployment @joshuaboniface diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/1-bug-report.md similarity index 67% rename from .github/ISSUE_TEMPLATE/bug_report.md rename to .github/ISSUE_TEMPLATE/1-bug-report.md index 137a689e8b..15efff9954 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/1-bug-report.md @@ -1,23 +1,20 @@ --- -name: Bug report -about: Create a bug report -title: '' +name: Bug Report +about: You have noticed a general issue or regression, and would like to report it labels: bug -assignees: '' - --- -**Describe the bug** +**Describe The Bug** -**To Reproduce** +**Steps To Reproduce** 1. Go to '...' 2. Click on '....' 3. Scroll down to '....' 4. See error -**Expected behavior** +**Expected Behavior** **Logs** @@ -27,9 +24,9 @@ assignees: '' **System (please complete the following information):** - - OS: [e.g. Docker, Debian, Windows] + - Platform: [e.g. Linux, Windows, iPhone, Tizen] - Browser: [e.g. Firefox, Chrome, Safari] - - Jellyfin Version: [e.g. 10.0.1] + - Jellyfin Version: [e.g. 10.6.0] -**Additional context** +**Additional Context** diff --git a/.github/ISSUE_TEMPLATE/2-playback-issue.md b/.github/ISSUE_TEMPLATE/2-playback-issue.md new file mode 100644 index 0000000000..bed7315abb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/2-playback-issue.md @@ -0,0 +1,22 @@ +--- +name: Playback Issue +about: You have playback issues with some files +labels: playback +--- + +**Describe The Bug** + + +**Media Information** + + +**Screenshots** + + +**System (please complete the following information):** + - Platform: [e.g. Linux, Windows, iPhone, Tizen] + - Browser: [e.g. Firefox, Chrome, Safari] + - Jellyfin Version: [e.g. 10.6.0] + +**Additional Context** + diff --git a/.github/ISSUE_TEMPLATE/3-technical-discussion.md b/.github/ISSUE_TEMPLATE/3-technical-discussion.md new file mode 100644 index 0000000000..d8140fce75 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/3-technical-discussion.md @@ -0,0 +1,13 @@ +--- +name: Technical Discussion +about: You want to discuss technical aspects of changes you intend to make +labels: enhancement +--- + + diff --git a/.github/ISSUE_TEMPLATE/4-meta-issue.md b/.github/ISSUE_TEMPLATE/4-meta-issue.md new file mode 100644 index 0000000000..e034302e45 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/4-meta-issue.md @@ -0,0 +1,9 @@ +--- +name: Meta Issue +about: You want to track a number of other issues as part of a larger project +labels: meta +--- + +* [ ] Issue 1 [#123] +* [ ] Issue 2 [#456] +* [ ] ... diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..2ed06fae39 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Feature Request + url: https://features.jellyfin.org/ + about: Please head over to our feature request hub to vote on or submit a feature. + - name: Help Or Question + url: https://matrix.to/#/#jellyfin-troubleshooting:matrix.org + about: Please join the troubleshooting Matrix channel to get some help. diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md new file mode 100644 index 0000000000..a62bc7522a --- /dev/null +++ b/.github/SUPPORT.md @@ -0,0 +1,24 @@ +# Support + +Jellyfin contributors have limited availability to address general support +questions. Please make sure you are using the latest version of Jellyfin. + +When looking for support or information, please first search for your +question in these venues: + +* [Jellyfin Forum](https://forum.jellyfin.org) +* [Jellyfin Documentation](https://docs.jellyfin.org) +* [Open or **closed** issues in the organization](https://github.com/issues?q=sort%3Aupdated-desc+org%3Ajellyfin+is%3Aissue+) + +If you didn't find an answer in the resources above, contributors and other +users are reachable through the following channels: + +* #jellyfin on [Matrix](https://matrix.to/#/#jellyfin:matrix.org%22) or [IRC](https://webchat.freenode.net/#jellyfin) +* #jellyfin-troubleshooting on [Matrix](https://matrix.to/#/#jellyfin-troubleshooting:matrix.org) or [IRC](https://webchat.freenode.net/#jellyfin-troubleshooting) +* [/r/jellyfin on Reddit](https://www.reddit.com/r/jellyfin) + +GitHub issues are for tracking enhancements and bugs, not general support. + +The open source license grants you the freedom to use Jellyfin. +It does not guarantee commitments of other people's time. +Please be respectful and manage your expectations. diff --git a/gulpfile.js b/gulpfile.js index 84f4558e6a..8b407ec2aa 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -184,7 +184,12 @@ function copy(query) { function injectBundle() { return src(options.injectBundle.query, { base: './src/' }) .pipe(inject( - src(['src/scripts/apploader.js'], { read: false }, { base: './src/' }), { relative: true } + src(['src/scripts/apploader.js'], { read: false }, { base: './src/' }), { + relative: true, + transform: function (filepath) { + return ``; + } + } )) .pipe(dest('dist/')) .pipe(browserSync.stream()); diff --git a/package.json b/package.json index 579e5e85d7..bcaa2c1e4a 100644 --- a/package.json +++ b/package.json @@ -5,16 +5,16 @@ "repository": "https://github.com/jellyfin/jellyfin-web", "license": "GPL-2.0-or-later", "devDependencies": { - "@babel/core": "^7.10.3", + "@babel/core": "^7.10.5", "@babel/plugin-proposal-class-properties": "^7.10.1", "@babel/plugin-proposal-private-methods": "^7.10.1", - "@babel/plugin-transform-modules-amd": "^7.9.6", + "@babel/plugin-transform-modules-amd": "^7.10.5", "@babel/polyfill": "^7.8.7", "@babel/preset-env": "^7.10.3", - "autoprefixer": "^9.8.2", + "autoprefixer": "^9.8.5", "babel-eslint": "^11.0.0-beta.2", "babel-loader": "^8.0.6", - "browser-sync": "^2.26.7", + "browser-sync": "^2.26.10", "copy-webpack-plugin": "^5.1.1", "css-loader": "^3.6.0", "cssnano": "^4.1.10", @@ -57,16 +57,15 @@ "blurhash": "^1.1.3", "classlist.js": "https://github.com/eligrey/classList.js/archive/1.2.20180112.tar.gz", "core-js": "^3.6.5", - "date-fns": "^2.14.0", - "document-register-element": "^1.14.3", + "date-fns": "^2.15.0", "epubjs": "^0.3.85", "fast-text-encoding": "^1.0.3", "flv.js": "^1.5.0", "headroom.js": "^0.11.0", - "hls.js": "^0.13.1", + "hls.js": "^0.14.3", "howler": "^2.2.0", - "intersection-observer": "^0.10.0", - "jellyfin-apiclient": "^1.2.2", + "intersection-observer": "^0.11.0", + "jellyfin-apiclient": "^1.4.1", "jellyfin-noto": "https://github.com/jellyfin/jellyfin-noto", "jquery": "^3.5.1", "jstree": "^3.3.10", @@ -77,11 +76,11 @@ "query-string": "^6.13.1", "resize-observer-polyfill": "^1.5.1", "screenfull": "^5.0.2", - "shaka-player": "^3.0.1", + "shaka-player": "^2.5.13", "sortablejs": "^1.10.2", "swiper": "^5.4.5", "webcomponents.js": "^0.7.24", - "whatwg-fetch": "^3.0.0" + "whatwg-fetch": "^3.2.0" }, "babel": { "presets": [ @@ -174,6 +173,7 @@ "src/controllers/dashboard/metadataImages.js", "src/controllers/dashboard/metadatanfo.js", "src/controllers/dashboard/plugins/repositories.js", +<<<<<<< HEAD "src/controllers/dashboard/streaming.js", "src/controllers/dashboard/mediaLibrary.js", "src/controllers/dashboard/networking.js", @@ -230,6 +230,14 @@ "src/elements/emby-button/paper-icon-button-light.js", "src/elements/emby-collapse/emby-collapse.js", "src/elements/emby-input/emby-input.js", +======= + "src/controllers/playback/nowplaying.js", + "src/controllers/playback/videoosd.js", + "src/controllers/user/display.js", + "src/controllers/user/home.js", + "src/controllers/user/playback.js", + "src/controllers/user/subtitles.js", +>>>>>>> upstream/master "src/plugins/bookPlayer/plugin.js", "src/plugins/bookPlayer/tableOfContents.js", "src/plugins/photoPlayer/plugin.js", diff --git a/src/assets/css/dashboard.css b/src/assets/css/dashboard.css index 894d7332f4..48e6fe807e 100644 --- a/src/assets/css/dashboard.css +++ b/src/assets/css/dashboard.css @@ -235,6 +235,15 @@ div[data-role=controlgroup] a.ui-btn-active { width: 50%; } +.localUsers .cardText-secondary { + white-space: pre-wrap; + height: 3em; +} + +.customCssContainer textarea { + resize: none; +} + @media all and (min-width: 70em) { .dashboardSections { -webkit-flex-wrap: wrap; diff --git a/src/assets/css/flexstyles.css b/src/assets/css/flexstyles.css index a5a479f2f5..429ed7a650 100644 --- a/src/assets/css/flexstyles.css +++ b/src/assets/css/flexstyles.css @@ -30,6 +30,10 @@ align-items: flex-start; } +.align-items-flex-end { + align-items: flex-end; +} + .justify-content-center { justify-content: center; } @@ -38,6 +42,10 @@ justify-content: flex-end; } +.justify-content-space-between { + justify-content: space-between; +} + .flex-wrap-wrap { flex-wrap: wrap; } diff --git a/src/assets/css/ios.css b/src/assets/css/ios.css index 57de0c5fdd..2b61f49a4e 100644 --- a/src/assets/css/ios.css +++ b/src/assets/css/ios.css @@ -1,8 +1,3 @@ html { font-size: 82% !important; } - -.formDialogFooter { - position: static !important; - margin: 0 -1em !important; -} diff --git a/src/assets/css/librarybrowser.css b/src/assets/css/librarybrowser.css index 88598fb94d..61815a590f 100644 --- a/src/assets/css/librarybrowser.css +++ b/src/assets/css/librarybrowser.css @@ -24,10 +24,6 @@ padding-top: 7em !important; } -.layout-mobile .libraryPage { - padding-top: 4em !important; -} - .itemDetailPage { padding-top: 0 !important; } @@ -164,6 +160,7 @@ display: flex; flex-direction: column; contain: layout style paint; + transition: background ease-in-out 0.5s; } .hiddenViewMenuBar .skinHeader { @@ -178,6 +175,10 @@ width: 100%; } +.layout-tv .sectionTabs { + width: 55%; +} + .selectedMediaFolder { background-color: #f2f2f2 !important; } @@ -272,7 +273,7 @@ } } -@media all and (max-width: 84em) { +@media all and (max-width: 100em) { .withSectionTabs .headerTop { padding-bottom: 0.55em; } @@ -280,9 +281,13 @@ .sectionTabs { font-size: 83.5%; } + + .layout-tv .sectionTabs { + width: 100%; + } } -@media all and (min-width: 84em) { +@media all and (min-width: 100em) { .headerTop { padding: 0.8em 0.8em; } @@ -438,12 +443,14 @@ background-repeat: no-repeat; background-position: center; background-attachment: fixed; - height: 50vh; + height: 40vh; position: relative; + animation: backdrop-fadein 800ms ease-in normal both; } .layout-mobile .itemBackdrop { background-attachment: scroll; + height: 26.5vh; } .layout-desktop .itemBackdrop::after, @@ -463,10 +470,20 @@ .detailPageContent { display: flex; flex-direction: column; - padding-left: 2%; + padding-left: 32.45vw; padding-right: 2%; } +.layout-mobile .detailPageContent { + padding-left: 5%; + padding-right: 5%; +} + +.layout-desktop .detailPageContent .emby-scroller, +.layout-tv .detailPageContent .emby-scroller { + margin-left: 0; +} + .layout-desktop .noBackdrop .detailPageContent, .layout-tv .noBackdrop .detailPageContent { margin-top: 2.5em; @@ -477,6 +494,10 @@ margin-top: 0; } +.detailSectionContent a { + color: inherit; +} + .personBackdrop { background-size: contain; } @@ -495,7 +516,23 @@ .parentName { display: block; - margin-bottom: 0.5em; + margin: 0 0 0; +} + +.layout-mobile .parentName { + margin: 0.6em 0 0; +} + +.musicParentName { + margin: 0.15em 0 0.2em; +} + +.layout-mobile .musicParentName { + margin: -0.25em 0 0.25em; +} + +.layout-mobile .itemExternalLinks { + display: none; } .mainDetailButtons { @@ -503,8 +540,6 @@ -webkit-box-align: center; -webkit-align-items: center; align-items: center; - -webkit-flex-wrap: wrap; - flex-wrap: wrap; margin: 1em 0; } @@ -520,6 +555,35 @@ font-weight: 600; } +.itemName.originalTitle { + margin: 0.2em 0 0.2em; +} + +.itemName.parentNameLast { + margin: 0 0 0; +} + +.layout-mobile .itemName.parentNameLast { + margin: 0.4em 0 0.4em; +} + +.layout-mobile h1.itemName, +.layout-mobile h1.parentName { + font-size: 1.6em; +} + +.itemName.parentNameLast.withOriginalTitle { + margin: 0 0 0; +} + +.layout-mobile .itemName.parentNameLast.withOriginalTitle { + margin: 0.6em 0 0; +} + +.layout-mobile .itemName.originalTitle { + margin: 0.5em 0 0.5em; +} + .nameContainer { display: flex; flex-direction: column; @@ -546,6 +610,19 @@ text-align: center; } +.layout-mobile .mainDetailButtons { + margin-top: 1em; + margin-bottom: 0.5em; +} + +.subtitle { + margin: 0.15em 0 0.2em; +} + +.layout-mobile .subtitle { + margin: 0.2em 0 0.2em; +} + .detailPagePrimaryContainer { display: flex; align-items: center; @@ -556,7 +633,7 @@ .layout-mobile .detailPagePrimaryContainer { display: block; position: relative; - top: 0; + padding: 0.5em 3.3% 0.5em; } .layout-tv #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer, @@ -566,13 +643,14 @@ padding-left: 32.45vw; } -.layout-desktop .detailSticky, -.layout-tv .detailSticky { +.layout-desktop .detailRibbon, +.layout-tv .detailRibbon { margin-top: -7.2em; + height: 7.18em; } -.layout-desktop .noBackdrop .detailSticky, -.layout-tv .noBackdrop .detailSticky { +.layout-desktop .noBackdrop .detailRibbon, +.layout-tv .noBackdrop .detailRibbon { margin-top: 0; } @@ -584,6 +662,9 @@ white-space: nowrap; text-overflow: ellipsis; text-align: left; + min-width: 0; + max-width: 100%; + overflow: hidden; } .layout-mobile .infoText { @@ -594,13 +675,29 @@ margin: 1.25em 0; } -.detailImageContainer { - position: relative; - margin-top: -25vh; - margin-bottom: 10vh; +.layout-mobile .detailPageSecondaryContainer { + margin: 1em 0; +} + +.layout-mobile .detailImageContainer { + display: none; +} + +.detailImageContainer .card { + position: absolute; + top: 50%; float: left; width: 25vw; z-index: 3; + transform: translateY(-50%); +} + +.detailImageContainer .card.backdropCard { + top: 35%; +} + +.detailImageContainer .card.squareCard { + top: 40%; } .layout-desktop .noBackdrop .detailImageContainer, @@ -613,11 +710,11 @@ } .detailLogo { - width: 30vw; - height: 25vh; + width: 25vw; + height: 16vh; position: absolute; top: 10vh; - right: 20vw; + right: 25vw; background-size: contain; } @@ -657,14 +754,19 @@ div.itemDetailGalleryLink.defaultCardBackground { position: relative; } - .layout-desktop .detailPageWrapperContainer, - .layout-tv .detailPageWrapperContainer { - margin-top: 7.2em; + .layout-desktop .itemBackdrop, + .layout-tv .itemBackdrop { + height: 40vh; } - .layout-tv #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer, - .layout-desktop #itemDetailPage:not(.noBackdrop) .detailPagePrimaryContainer { - padding-left: 3.3%; + .layout-desktop .detailPageWrapperContainer, + .layout-tv .detailPageWrapperContainer { + margin-top: 0.1em; + } + + .layout-desktop .detailImageContainer .card, + .layout-tv .detailImageContainer .card { + top: 10%; } .btnPlaySimple { @@ -680,12 +782,12 @@ div.itemDetailGalleryLink.defaultCardBackground { .emby-button.detailFloatingButton { position: absolute; - background-color: rgba(0, 0, 0, 0.5) !important; - z-index: 1; - top: 50%; - left: 50%; + background-color: rgba(0, 0, 0, 0.5); + z-index: 3; + top: 100%; + left: 90%; margin: -2.2em 0 0 -2.2em; - padding: 0.4em !important; + padding: 0.4em; color: rgba(255, 255, 255, 0.76); } @@ -695,16 +797,12 @@ div.itemDetailGalleryLink.defaultCardBackground { @media all and (max-width: 62.5em) { .parentName { - margin-bottom: 1em; + margin-bottom: 0; } .itemDetailPage { padding-top: 0 !important; } - - .detailimg-hidemobile { - display: none; - } } @media all and (min-width: 31.25em) { @@ -820,21 +918,7 @@ div.itemDetailGalleryLink.defaultCardBackground { } } -@media all and (min-width: 62.5em) { - .headerTop { - padding-left: 0.8em; - padding-right: 0.8em; - } - - .headerTabs { - align-self: center; - width: auto; - align-items: center; - justify-content: center; - margin-top: -4.2em; - position: relative; - } - +@media all and (min-width: 100em) { .detailFloatingButton { display: none !important; } @@ -868,6 +952,10 @@ div.itemDetailGalleryLink.defaultCardBackground { } } +.detailVerticalSection .emby-scrollbuttons { + padding-top: 0.4em; +} + .layout-tv .detailVerticalSection { margin-bottom: 3.4em !important; } @@ -956,6 +1044,10 @@ div.itemDetailGalleryLink.defaultCardBackground { margin-bottom: 2.7em; } +.layout-mobile .verticalSection-extrabottompadding { + margin-bottom: 1em; +} + .sectionTitleButton, .sectionTitleIconButton { margin-right: 0 !important; @@ -981,7 +1073,13 @@ div.itemDetailGalleryLink.defaultCardBackground { div:not(.sectionTitleContainer-cards) > .sectionTitle-cards { margin: 0; - padding-top: 1.25em; + padding-top: 0.5em; + padding-bottom: 0.2em; +} + +.layout-mobile :not(.sectionTitleContainer-cards) > .sectionTitle-cards { + margin: 0; + padding-top: 0.5em; } .sectionTitleButton { @@ -1134,6 +1232,12 @@ div:not(.sectionTitleContainer-cards) > .sectionTitle-cards { .trackSelections .selectContainer .selectLabel { margin: 0 0.2em 0 0; + line-height: 1.75; +} + +.layout-mobile .detailsGroupItem .label, +.layout-mobile .trackSelections .selectContainer .selectLabel { + flex-basis: 4.5em; } .trackSelections .selectContainer .detailTrackSelect { diff --git a/src/assets/css/scrollstyles.css b/src/assets/css/scrollstyles.css index 1cb3207e06..67c6202252 100644 --- a/src/assets/css/scrollstyles.css +++ b/src/assets/css/scrollstyles.css @@ -12,6 +12,7 @@ .hiddenScrollX, .layout-tv .scrollX { -ms-overflow-style: none; + scrollbar-width: none; } .hiddenScrollX-forced { @@ -40,6 +41,7 @@ .hiddenScrollY, .layout-tv .smoothScrollY { -ms-overflow-style: none; + scrollbar-width: none; /* Can't do this because it not only hides the scrollbar, but also prevents scrolling */ diff --git a/src/assets/css/site.css b/src/assets/css/site.css index 9fbd8a4fca..f6326f4c9e 100644 --- a/src/assets/css/site.css +++ b/src/assets/css/site.css @@ -5,6 +5,12 @@ html { height: 100%; } +.layout-mobile, +.layout-tv { + -webkit-touch-callout: none; + user-select: none; +} + .clipForScreenReader { clip: rect(1px, 1px, 1px, 1px); clip-path: inset(50%); @@ -18,7 +24,7 @@ html { .material-icons { /* Fix font ligatures on older WebOS versions */ - -webkit-font-feature-settings: "liga"; + font-feature-settings: "liga"; } .backgroundContainer { @@ -34,16 +40,6 @@ html { line-height: 1.35; } -.layout-mobile, -.layout-tv { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - body { overflow-x: hidden; background-color: transparent !important; @@ -133,3 +129,7 @@ div[data-role=page] { .hide-scroll { overflow-y: hidden; } + +.w-100 { + width: 100%; +} diff --git a/src/bundle.js b/src/bundle.js index 41648f7c4f..dd1ff6548b 100644 --- a/src/bundle.js +++ b/src/bundle.js @@ -4,12 +4,6 @@ // Use define from require.js not webpack's define var _define = window.define; -// document-register-element -var docRegister = require('document-register-element'); -_define('document-register-element', function() { - return docRegister; -}); - // fetch var fetch = require('whatwg-fetch'); _define('fetch', function() { @@ -65,12 +59,6 @@ _define('resize-observer-polyfill', function() { return resize; }); -// shaka -var shaka = require('shaka-player'); -_define('shaka', function() { - return shaka; -}); - // swiper var swiper = require('swiper/js/swiper'); require('swiper/css/swiper.min.css'); @@ -90,6 +78,12 @@ _define('webcomponents', function() { return webcomponents; }); +// shaka +var shaka = require('shaka-player'); +_define('shaka', function() { + return shaka; +}); + // libass-wasm var libassWasm = require('libass-wasm'); _define('JavascriptSubtitlesOctopus', function() { diff --git a/src/components/actionSheet/actionSheet.js b/src/components/actionSheet/actionSheet.js index 1c8992bf55..a68d6a6acd 100644 --- a/src/components/actionSheet/actionSheet.js +++ b/src/components/actionSheet/actionSheet.js @@ -16,7 +16,7 @@ function getOffsets(elems) { return results; } - for (let elem of elems) { + for (const elem of elems) { let box = elem.getBoundingClientRect(); results.push({ @@ -135,7 +135,7 @@ export function show(options) { let renderIcon = false; let icons = []; let itemIcon; - for (let item of options.items) { + for (const item of options.items) { itemIcon = item.icon || (item.selected ? 'check' : null); diff --git a/src/components/appRouter.js b/src/components/appRouter.js index ace35ac851..8054279c92 100644 --- a/src/components/appRouter.js +++ b/src/components/appRouter.js @@ -222,46 +222,13 @@ define(['loading', 'globalize', 'events', 'viewManager', 'skinManager', 'backdro } function normalizeImageOptions(options) { - var scaleFactor = browser.tv ? 0.8 : 1; - var setQuality; - if (options.maxWidth) { - options.maxWidth = Math.round(options.maxWidth * scaleFactor); + if (options.maxWidth || options.width || options.maxHeight || options.height) { setQuality = true; } - if (options.width) { - options.width = Math.round(options.width * scaleFactor); - setQuality = true; - } - - if (options.maxHeight) { - options.maxHeight = Math.round(options.maxHeight * scaleFactor); - setQuality = true; - } - - if (options.height) { - options.height = Math.round(options.height * scaleFactor); - setQuality = true; - } - - if (setQuality) { - var quality; - var type = options.type || 'Primary'; - - if (browser.tv || browser.slow) { - // TODO: wtf - if (browser.chrome) { - // webp support - quality = type === 'Primary' ? 40 : 50; - } else { - quality = type === 'Backdrop' ? 60 : 50; - } - } else { - quality = type === 'Backdrop' ? 70 : 90; - } - - options.quality = quality; + if (setQuality && !options.quality) { + options.quality = 90; } } diff --git a/src/components/cardbuilder/card.css b/src/components/cardbuilder/card.css index d77fe5660c..ef5ea6604c 100644 --- a/src/components/cardbuilder/card.css +++ b/src/components/cardbuilder/card.css @@ -167,8 +167,9 @@ button::-moz-focus-inner { position: relative; background-clip: content-box !important; color: inherit; +} - /* This is only needed for scalable cards */ +.cardScalable .cardImageContainer { height: 100%; contain: strict; } diff --git a/src/components/cardbuilder/cardBuilder.js b/src/components/cardbuilder/cardBuilder.js index 1c59a7ae94..f3bbaad58d 100644 --- a/src/components/cardbuilder/cardBuilder.js +++ b/src/components/cardbuilder/cardBuilder.js @@ -1310,7 +1310,7 @@ import 'programStyles'; } const mediaSourceCount = item.MediaSourceCount || 1; - if (mediaSourceCount > 1) { + if (mediaSourceCount > 1 && options.disableIndicators !== true) { innerCardFooter += '
' + mediaSourceCount + '
'; } @@ -1391,34 +1391,44 @@ import 'programStyles'; cardBoxClose = ''; cardScalableClose = ''; - let indicatorsHtml = ''; + if (options.disableIndicators !== true) { + let indicatorsHtml = ''; - if (options.missingIndicator !== false) { - indicatorsHtml += indicators.getMissingIndicator(item); - } + if (options.missingIndicator !== false) { + indicatorsHtml += indicators.getMissingIndicator(item); + } - indicatorsHtml += indicators.getSyncIndicator(item); - indicatorsHtml += indicators.getTimerIndicator(item); + indicatorsHtml += indicators.getSyncIndicator(item); + indicatorsHtml += indicators.getTimerIndicator(item); - indicatorsHtml += indicators.getTypeIndicator(item); + indicatorsHtml += indicators.getTypeIndicator(item); - if (options.showGroupCount) { + if (options.showGroupCount) { - indicatorsHtml += indicators.getChildCountIndicatorHtml(item, { - minCount: 1 - }); - } else { - indicatorsHtml += indicators.getPlayedIndicatorHtml(item); - } + indicatorsHtml += indicators.getChildCountIndicatorHtml(item, { + minCount: 1 + }); + } else { + indicatorsHtml += indicators.getPlayedIndicatorHtml(item); + } +<<<<<<< HEAD if (item.Type === 'CollectionFolder' || item.CollectionType) { const refreshClass = item.RefreshProgress ? '' : ' class="hide"'; indicatorsHtml += '
'; importRefreshIndicator(); } +======= + if (item.Type === 'CollectionFolder' || item.CollectionType) { + const refreshClass = item.RefreshProgress ? '' : ' class="hide"'; + indicatorsHtml += '
'; + requireRefreshIndicator(); + } +>>>>>>> upstream/master - if (indicatorsHtml) { - cardImageContainerOpen += '
' + indicatorsHtml + '
'; + if (indicatorsHtml) { + cardImageContainerOpen += '
' + indicatorsHtml + '
'; + } } if (!imgUrl) { @@ -1466,8 +1476,8 @@ import 'programStyles'; let additionalCardContent = ''; - if (layoutManager.desktop) { - additionalCardContent += getHoverMenuHtml(item, action); + if (layoutManager.desktop && !options.disableHoverMenu) { + additionalCardContent += getHoverMenuHtml(item, action, options); } return '<' + tagName + ' data-index="' + index + '"' + timerAttributes + actionAttribute + ' data-isfolder="' + (item.IsFolder || false) + '" data-serverid="' + (item.ServerId || options.serverId) + '" data-id="' + (item.Id || item.ItemId) + '" data-type="' + item.Type + '"' + mediaTypeData + collectionTypeData + channelIdData + positionTicksData + collectionIdData + playlistIdData + contextData + parentIdData + ' data-prefix="' + prefix + '" class="' + className + '">' + cardImageContainerOpen + innerCardFooter + cardImageContainerClose + overlayButtons + additionalCardContent + cardScalableClose + outerCardFooter + cardBoxClose + ''; @@ -1477,9 +1487,10 @@ import 'programStyles'; * Generates HTML markup for the card overlay. * @param {object} item - Item used to generate the card overlay. * @param {string} action - Action assigned to the overlay. + * @param {Array} options - Card builder options. * @returns {string} HTML markup of the card overlay. */ - function getHoverMenuHtml(item, action) { + function getHoverMenuHtml(item, action, options) { let html = ''; html += '
'; @@ -1508,7 +1519,6 @@ import 'programStyles'; } html += ''; - html += '
'; html += ''; @@ -1532,6 +1542,8 @@ import 'programStyles'; case 'MusicArtist': case 'Person': return ''; + case 'Audio': + return ''; case 'Movie': return ''; case 'Series': @@ -1540,6 +1552,12 @@ import 'programStyles'; return ''; case 'Folder': return ''; + case 'BoxSet': + return ''; + case 'Playlist': + return ''; + case 'PhotoAlbum': + return ''; } if (options && options.defaultCardImageIcon) { diff --git a/src/components/groupedcards.js b/src/components/groupedcards.js index 543b295fea..3c474d9f6e 100644 --- a/src/components/groupedcards.js +++ b/src/components/groupedcards.js @@ -25,7 +25,7 @@ import connectionManager from 'connectionManager'; return void appRouter.showItem(items[0]); } - var url = 'itemdetails.html?id=' + itemId + '&serverId=' + serverId; + var url = 'details?id=' + itemId + '&serverId=' + serverId; Dashboard.navigate(url); }); e.stopPropagation(); diff --git a/src/components/guide/guide.js b/src/components/guide/guide.js index 4ae2041223..bb4a36497c 100644 --- a/src/components/guide/guide.js +++ b/src/components/guide/guide.js @@ -1,4 +1,4 @@ -define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', 'scrollHelper', 'serverNotifications', 'loading', 'datetime', 'focusManager', 'playbackManager', 'userSettings', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'dom', 'css!./guide.css', 'programStyles', 'material-icons', 'scrollStyles', 'emby-programcell', 'emby-button', 'paper-icon-button-light', 'emby-tabs', 'emby-scroller', 'flexStyles', 'registerElement'], function (require, inputManager, browser, globalize, connectionManager, scrollHelper, serverNotifications, loading, datetime, focusManager, playbackManager, userSettings, imageLoader, events, layoutManager, itemShortcuts, dom) { +define(['require', 'inputManager', 'browser', 'globalize', 'connectionManager', 'scrollHelper', 'serverNotifications', 'loading', 'datetime', 'focusManager', 'playbackManager', 'userSettings', 'imageLoader', 'events', 'layoutManager', 'itemShortcuts', 'dom', 'css!./guide.css', 'programStyles', 'material-icons', 'scrollStyles', 'emby-programcell', 'emby-button', 'paper-icon-button-light', 'emby-tabs', 'emby-scroller', 'flexStyles', 'webcomponents'], function (require, inputManager, browser, globalize, connectionManager, scrollHelper, serverNotifications, loading, datetime, focusManager, playbackManager, userSettings, imageLoader, events, layoutManager, itemShortcuts, dom) { 'use strict'; function showViewSettings(instance) { diff --git a/src/components/images/imageLoader.js b/src/components/images/imageLoader.js index f7183515c5..069d32fb8b 100644 --- a/src/components/images/imageLoader.js +++ b/src/components/images/imageLoader.js @@ -12,7 +12,7 @@ import 'css!./style'; fillImageElement(elem, source); } - async function itemBlurhashing(target, blurhashstr) { + function itemBlurhashing(target, blurhashstr) { if (blurhash.isBlurhashValid(blurhashstr)) { // Although the default values recommended by Blurhash developers is 32x32, a size of 18x18 seems to be the sweet spot for us, // improving the performance and reducing the memory usage, while retaining almost full blur quality. @@ -36,24 +36,18 @@ import 'css!./style'; imgData.data.set(pixels); ctx.putImageData(imgData, 0, 0); - let child = target.appendChild(canvas); - child.classList.add('blurhash-canvas'); - child.style.opacity = 1; - if (userSettings.enableFastFadein()) { - child.classList.add('lazy-blurhash-fadein-fast'); - } else { - child.classList.add('lazy-blurhash-fadein'); - } + requestAnimationFrame(() => { + canvas.classList.add('blurhash-canvas'); + if (userSettings.enableFastFadein()) { + canvas.classList.add('lazy-blurhash-fadein-fast'); + } else { + canvas.classList.add('lazy-blurhash-fadein'); + } - target.classList.add('blurhashed'); - target.removeAttribute('data-blurhash'); - } - } - - function switchCanvas(elem) { - let child = elem.getElementsByClassName('blurhash-canvas')[0]; - if (child) { - child.style.opacity = elem.getAttribute('data-src') ? 1 : 0; + target.parentNode.insertBefore(canvas, target); + target.classList.add('blurhashed'); + target.removeAttribute('data-blurhash'); + }); } } @@ -66,23 +60,16 @@ import 'css!./style'; if (target) { source = target.getAttribute('data-src'); - var blurhashstr = target.getAttribute('data-blurhash'); } else { source = entry; } - if (userSettings.enableBlurhash()) { - if (!target.classList.contains('blurhashed', 'non-blurhashable') && blurhashstr) { - itemBlurhashing(target, blurhashstr); - } else if (!blurhashstr && !target.classList.contains('blurhashed')) { - target.classList.add('non-blurhashable'); - } - } - if (entry.intersectionRatio > 0) { if (source) fillImageElement(target, source); } else if (!source) { - emptyImageElement(target); + requestAnimationFrame(() => { + emptyImageElement(target); + }); } } @@ -94,29 +81,24 @@ import 'css!./style'; let preloaderImg = new Image(); preloaderImg.src = url; - // This is necessary here, so changing blurhash settings without reloading the page works - if (!userSettings.enableBlurhash() || elem.classList.contains('non-blurhashable')) { - elem.classList.add('lazy-hidden'); - } + elem.classList.add('lazy-hidden'); preloaderImg.addEventListener('load', () => { - if (elem.tagName !== 'IMG') { - elem.style.backgroundImage = "url('" + url + "')"; - } else { - elem.setAttribute('src', url); - } - elem.removeAttribute('data-src'); + requestAnimationFrame(() => { + if (elem.tagName !== 'IMG') { + elem.style.backgroundImage = "url('" + url + "')"; + } else { + elem.setAttribute('src', url); + } + elem.removeAttribute('data-src'); - if (elem.classList.contains('non-blurhashable') || !userSettings.enableBlurhash()) { elem.classList.remove('lazy-hidden'); if (userSettings.enableFastFadein()) { elem.classList.add('lazy-image-fadein-fast'); } else { elem.classList.add('lazy-image-fadein'); } - } else { - switchCanvas(elem); - } + }); }); } @@ -132,15 +114,21 @@ import 'css!./style'; } elem.setAttribute('data-src', url); - if (elem.classList.contains('non-blurhashable') || !userSettings.enableBlurhash()) { - elem.classList.remove('lazy-image-fadein-fast', 'lazy-image-fadein'); - elem.classList.add('lazy-hidden'); - } else { - switchCanvas(elem); - } + elem.classList.remove('lazy-image-fadein-fast', 'lazy-image-fadein'); + elem.classList.add('lazy-hidden'); } export function lazyChildren(elem) { + if (userSettings.enableBlurhash()) { + for (const lazyElem of elem.querySelectorAll('.lazy')) { + const blurhashstr = lazyElem.getAttribute('data-blurhash'); + if (!lazyElem.classList.contains('blurhashed', 'non-blurhashable') && blurhashstr) { + itemBlurhashing(lazyElem, blurhashstr); + } else if (!blurhashstr && !lazyElem.classList.contains('blurhashed')) { + lazyElem.classList.add('non-blurhashable'); + } + } + } lazyLoader.lazyChildren(elem, fillImage); } @@ -212,8 +200,15 @@ import 'css!./style'; } } + export function setLazyImage(element, url) { + element.classList.add('lazy'); + element.setAttribute('data-src', url); + lazyImage(element); + } + /* eslint-enable indent */ export default { + serLazyImage: setLazyImage, fillImages: fillImages, fillImage: fillImage, lazyImage: lazyImage, diff --git a/src/components/images/style.css b/src/components/images/style.css index 2b09da2da4..7e8b01aff2 100644 --- a/src/components/images/style.css +++ b/src/components/images/style.css @@ -12,12 +12,22 @@ opacity: 0; } +@keyframes fadein { + from { + opacity: 0; + } + + to { + opacity: 1; + } +} + .lazy-blurhash-fadein-fast { - transition: opacity 0.2s; + animation: fadein 0.1s; } .lazy-blurhash-fadein { - transition: opacity 0.7s; + animation: fadein 0.4s; } .blurhash-canvas { @@ -28,6 +38,5 @@ left: 0; width: 100%; height: 100%; - z-index: 100; pointer-events: none; } diff --git a/src/components/itemContextMenu.js b/src/components/itemContextMenu.js index 96a5cb71d7..7c89f7aeae 100644 --- a/src/components/itemContextMenu.js +++ b/src/components/itemContextMenu.js @@ -38,6 +38,23 @@ import actionsheet from 'actionsheet'; } } + if (playbackManager.getCurrentPlayer() !== null) { + if (options.stopPlayback) { + commands.push({ + name: globalize.translate('StopPlayback'), + id: 'stopPlayback', + icon: 'stop' + }); + } + if (options.clearQueue) { + commands.push({ + name: globalize.translate('ClearQueue'), + id: 'clearQueue', + icon: 'clear_all' + }); + } + } + if (playbackManager.canQueue(item)) { if (options.queue !== false) { commands.push({ @@ -54,13 +71,6 @@ import actionsheet from 'actionsheet'; icon: 'playlist_add' }); } - - //if (options.queueAllFromHere) { - // commands.push({ - // name: globalize.translate("QueueAllFromHere"), - // id: "queueallfromhere" - // }); - //} } if (item.IsFolder || item.Type === 'MusicArtist' || item.Type === 'MusicGenre') { @@ -298,10 +308,11 @@ import actionsheet from 'actionsheet'; icon: 'album' }); } - - if (options.openArtist !== false && item.ArtistItems && item.ArtistItems.length) { + // Show Album Artist by default, as a song can have multiple artists, which specific one would this option refer to? + // Although some albums can have multiple artists, it's not as common as songs. + if (options.openArtist !== false && item.AlbumArtists && item.AlbumArtists.length) { commands.push({ - name: globalize.translate('ViewArtist'), + name: globalize.translate('ViewAlbumArtist'), id: 'artist', icon: 'person' }); @@ -441,6 +452,12 @@ import actionsheet from 'actionsheet'; play(item, false, true, true); getResolveFunction(resolve, id)(); break; + case 'stopPlayback': + playbackManager.stop(); + break; + case 'clearQueue': + playbackManager.clearQueue(); + break; case 'record': import('recordingCreator').then(({default: recordingCreator}) => { recordingCreator.show(itemId, serverId).then(getResolveFunction(resolve, id, true), getResolveFunction(resolve, id)); @@ -469,7 +486,7 @@ import actionsheet from 'actionsheet'; getResolveFunction(resolve, id)(); break; case 'artist': - appRouter.showItem(item.ArtistItems[0].Id, item.ServerId); + appRouter.showItem(item.AlbumArtists[0].Id, item.ServerId); getResolveFunction(resolve, id)(); break; case 'playallfromhere': diff --git a/src/components/itemHelper.js b/src/components/itemHelper.js index b18f37110c..3508866bdb 100644 --- a/src/components/itemHelper.js +++ b/src/components/itemHelper.js @@ -1,14 +1,12 @@ define(['apphost', 'globalize'], function (appHost, globalize) { 'use strict'; - function getDisplayName(item, options) { + function getDisplayName(item, options = {}) { if (!item) { throw new Error('null item passed into getDisplayName'); } - options = options || {}; - if (item.Type === 'Timer') { item = item.ProgramInfo || item; } diff --git a/src/components/itemidentifier/itemidentifier.js b/src/components/itemidentifier/itemidentifier.js index 11e164dede..f4ecf43d71 100644 --- a/src/components/itemidentifier/itemidentifier.js +++ b/src/components/itemidentifier/itemidentifier.js @@ -240,13 +240,19 @@ import 'cardStyle'; html += ''; html += ''; +<<<<<<< HEAD let numLines = 2; +======= + var numLines = 3; +>>>>>>> upstream/master if (currentItemType === 'MusicAlbum') { numLines++; } const lines = [result.Name]; + lines.push(result.SearchProviderName); + if (result.AlbumArtist) { lines.push(result.AlbumArtist.Name); } diff --git a/src/components/listview/listview.js b/src/components/listview/listview.js index 692d74d38b..7b9e77abb6 100644 --- a/src/components/listview/listview.js +++ b/src/components/listview/listview.js @@ -1,3 +1,4 @@ +<<<<<<< HEAD /* eslint-disable indent */ /** @@ -15,6 +16,10 @@ import datetime from 'datetime'; import 'css!./listview'; import 'emby-ratingbutton'; import 'emby-playstatebutton'; +======= +define(['itemHelper', 'mediaInfo', 'indicators', 'connectionManager', 'layoutManager', 'globalize', 'datetime', 'cardBuilder', 'css!./listview', 'emby-ratingbutton', 'emby-playstatebutton'], function (itemHelper, mediaInfo, indicators, connectionManager, layoutManager, globalize, datetime, cardBuilder) { + 'use strict'; +>>>>>>> upstream/master function getIndex(item, options) { @@ -106,11 +111,8 @@ import 'emby-playstatebutton'; itemId = item.ParentPrimaryImageItemId; } - let blurHashes = item.ImageBlurHashes || {}; - let blurhashstr = (blurHashes[options.type] || {})[options.tag]; - if (itemId) { - return { url: apiClient.getScaledImageUrl(itemId, options), blurhash: blurhashstr }; + return apiClient.getScaledImageUrl(itemId, options); } return null; } @@ -126,24 +128,30 @@ import 'emby-playstatebutton'; if (item.ChannelId && item.ChannelPrimaryImageTag) { options.tag = item.ChannelPrimaryImageTag; } - let blurHashes = item.ImageBlurHashes || {}; - let blurhashstr = (blurHashes[options.type])[options.tag]; if (item.ChannelId) { - return { url: apiClient.getScaledImageUrl(item.ChannelId, options), blurhash: blurhashstr }; + return apiClient.getScaledImageUrl(item.ChannelId, options); } } function getTextLinesHtml(textlines, isLargeStyle) { +<<<<<<< HEAD let html = ''; +======= + var html = ''; +>>>>>>> upstream/master const largeTitleTagName = layoutManager.tv ? 'h2' : 'div'; +<<<<<<< HEAD for (let i = 0, length = textlines.length; i < length; i++) { const text = textlines[i]; +======= + for (const [i, text] of textlines.entries()) { +>>>>>>> upstream/master if (!text) { continue; } @@ -284,10 +292,8 @@ import 'emby-playstatebutton'; } if (options.image !== false) { - let imgData = options.imageSource === 'channel' ? getChannelImageUrl(item, downloadWidth) : getImageUrl(item, downloadWidth); - let imgUrl = imgData.url; - let blurhash = imgData.blurhash; - let imageClass = isLargeStyle ? 'listItemImage listItemImage-large' : 'listItemImage'; + var imgUrl = options.imageSource === 'channel' ? getChannelImageUrl(item, downloadWidth) : getImageUrl(item, downloadWidth); + var imageClass = isLargeStyle ? 'listItemImage listItemImage-large' : 'listItemImage'; if (isLargeStyle && layoutManager.tv) { imageClass += ' listItemImage-large-tv'; @@ -299,6 +305,7 @@ import 'emby-playstatebutton'; imageClass += ' itemAction'; } +<<<<<<< HEAD const imageAction = playOnImageClick ? 'resume' : action; let blurhashAttrib = ''; @@ -310,6 +317,14 @@ import 'emby-playstatebutton'; html += `
`; } else { html += `
`; +======= + var imageAction = playOnImageClick ? 'link' : action; + + if (imgUrl) { + html += '
'; + } else { + html += '
' + cardBuilder.getDefaultText(item, options); +>>>>>>> upstream/master } let indicatorsHtml = ''; @@ -449,8 +464,6 @@ import 'emby-playstatebutton'; html += `
`; - const moreIcon = 'more_vert'; - html += getTextLinesHtml(textlines, isLargeStyle); if (options.mediaInfo !== false) { @@ -505,10 +518,13 @@ import 'emby-playstatebutton'; html += ''; } +<<<<<<< HEAD if (options.moreButton !== false) { html += ``; } +======= +>>>>>>> upstream/master if (options.infoButton) { html += ''; } @@ -522,13 +538,26 @@ import 'emby-playstatebutton'; const userData = item.UserData || {}; const likes = userData.Likes == null ? '' : userData.Likes; +<<<<<<< HEAD if (itemHelper.canMarkPlayed(item)) { html += ``; } if (itemHelper.canRate(item)) { html += ``; +======= + if (itemHelper.canMarkPlayed(item) && options.enablePlayedButton !== false) { + html += ''; } + + if (itemHelper.canRate(item) && options.enableRatingButton !== false) { + html += ''; +>>>>>>> upstream/master + } + } + + if (options.moreButton !== false) { + html += ''; } } html += '
'; diff --git a/src/components/loading/loader.gif b/src/components/loading/loader.gif deleted file mode 100644 index 86fb6daa79..0000000000 Binary files a/src/components/loading/loader.gif and /dev/null differ diff --git a/src/components/loading/loading.js b/src/components/loading/loading.js index 9a9aa3ca7d..f36e41f44d 100644 --- a/src/components/loading/loading.js +++ b/src/components/loading/loading.js @@ -1,10 +1,6 @@ -define(['components/loading/loadingLegacy', 'browser', 'css!./loading'], function (loadingLegacy, browser) { +define(['css!./loading'], function () { 'use strict'; - if (browser.tizen || browser.operaTv || browser.chromecast || browser.orsay || browser.web0s || browser.ps4) { - return loadingLegacy; - } - var loadingElem; var layer1; var layer2; diff --git a/src/components/loading/loadingLegacy.css b/src/components/loading/loadingLegacy.css deleted file mode 100644 index 17ea94950e..0000000000 --- a/src/components/loading/loadingLegacy.css +++ /dev/null @@ -1,10 +0,0 @@ -.loading-spinner { - margin-top: -3em; - margin-left: -3em; - width: 6em; - height: 6em; - position: fixed; - top: 50%; - left: 50%; - z-index: 9999999; -} diff --git a/src/components/loading/loadingLegacy.js b/src/components/loading/loadingLegacy.js deleted file mode 100644 index d766a4aca4..0000000000 --- a/src/components/loading/loadingLegacy.js +++ /dev/null @@ -1,28 +0,0 @@ -define(['require', 'css!./loadingLegacy'], function (require) { - 'use strict'; - - var loadingElem; - - return { - show: function () { - var elem = loadingElem; - if (!elem) { - elem = document.createElement('img'); - elem.src = require.toUrl('.').split('?')[0] + '/loader.gif'; - - loadingElem = elem; - elem.classList.add('loading-spinner'); - - document.body.appendChild(elem); - } - - elem.classList.remove('hide'); - }, - hide: function () { - var elem = loadingElem; - if (elem) { - elem.classList.add('hide'); - } - } - }; -}); diff --git a/src/components/mediainfo/mediainfo.css b/src/components/mediainfo/mediainfo.css index 1883b78726..508c9d96ad 100644 --- a/src/components/mediainfo/mediainfo.css +++ b/src/components/mediainfo/mediainfo.css @@ -41,6 +41,8 @@ width: auto !important; height: auto !important; font-size: 1.4em; + margin-right: 0.125em; + color: #f2b01e; } .mediaInfoCriticRating { diff --git a/src/components/metadataEditor/metadataEditor.js b/src/components/metadataEditor/metadataEditor.js index 28bc8a6dae..e3577f9a21 100644 --- a/src/components/metadataEditor/metadataEditor.js +++ b/src/components/metadataEditor/metadataEditor.js @@ -266,6 +266,43 @@ import 'flexStyles'; }); } + function afterDeleted(context, item) { + var parentId = item.ParentId || item.SeasonId || item.SeriesId; + + if (parentId) { + reload(context, parentId, item.ServerId); + } else { + require(['appRouter'], function (appRouter) { + appRouter.goHome(); + }); + } + } + + function showMoreMenu(context, button, user) { + require(['itemContextMenu'], function (itemContextMenu) { + var item = currentItem; + + itemContextMenu.show({ + item: item, + positionTo: button, + edit: false, + editImages: true, + editSubtitles: true, + sync: false, + share: false, + play: false, + queue: false, + user: user + }).then(function (result) { + if (result.deleted) { + afterDeleted(context, item); + } else if (result.updated) { + reload(context, item.Id, item.ServerId); + } + }); + }); + } + function onEditorClick(e) { const btnRemoveFromEditorList = dom.parentWithClass(e.target, 'btnRemoveFromEditorList'); @@ -291,7 +328,6 @@ import 'flexStyles'; } function init(context, apiClient) { - context.querySelector('.externalIds').addEventListener('click', function (e) { const btnOpenExternalId = dom.parentWithClass(e.target, 'btnOpenExternalId'); if (btnOpenExternalId) { @@ -315,13 +351,17 @@ import 'flexStyles'; closeDialog(false); }); - context.querySelector('.btnHeaderSave').addEventListener('click', function (e) { + context.querySelector('.btnMore').addEventListener('click', function (e) { + getApiClient().getCurrentUser().then(function (user) { + showMoreMenu(context, e.target, user); + }); + }); + context.querySelector('.btnHeaderSave').addEventListener('click', function (e) { context.querySelector('.btnSave').click(); }); context.querySelector('#chkLockData').addEventListener('click', function (e) { - if (!e.target.checked) { showElement('.providerSettingsContainer'); } else { @@ -1107,6 +1147,7 @@ import 'flexStyles'; elem.innerHTML = globalize.translateHtml(template, 'core'); elem.querySelector('.formDialogFooter').classList.remove('formDialogFooter'); + elem.querySelector('.btnClose').classList.add('hide'); elem.querySelector('.btnHeaderSave').classList.remove('hide'); elem.querySelector('.btnCancel').classList.add('hide'); diff --git a/src/components/metadataEditor/metadataEditor.template.html b/src/components/metadataEditor/metadataEditor.template.html index 4b4e2cf965..aad3557bad 100644 --- a/src/components/metadataEditor/metadataEditor.template.html +++ b/src/components/metadataEditor/metadataEditor.template.html @@ -8,6 +8,9 @@ ${Save} + diff --git a/src/components/nowPlayingBar/nowPlayingBar.css b/src/components/nowPlayingBar/nowPlayingBar.css index b1e77715ff..a884f65769 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.css +++ b/src/components/nowPlayingBar/nowPlayingBar.css @@ -56,8 +56,8 @@ text-align: left; flex-grow: 1; font-size: 92%; - margin-right: 2.4em; - margin-left: 1em; + margin-right: 1em; + margin-left: 0.5em; } .nowPlayingBarCenter { @@ -114,8 +114,6 @@ .nowPlayingBarUserDataButtons { display: inline-block; - margin-left: 1em; - margin-right: 1em; } .nowPlayingBarPositionSlider::-webkit-slider-thumb { @@ -133,33 +131,50 @@ .toggleRepeatButton { display: none !important; } -} -@media all and (max-width: 62em) { - .nowPlayingBarCenter .nowPlayingBarCurrentTime { + .nowPlayingBar .btnShuffleQueue { display: none !important; } } +@media all and (max-width: 80em) { + .nowPlayingBarCenter .nowPlayingBarCurrentTime, + .nowPlayingBarCenter .stopButton { + display: none !important; + } + + .nowPlayingBarInfoContainer { + width: 45%; + } +} + +.layout-mobile .nowPlayingBarRight button:not(.playPauseButton, .nextTrackButton) { + display: none; +} + +.layout-desktop .nowPlayingBarRight .playPauseButton, +.layout-tv .nowPlayingBarRight .playPauseButton { + display: none; +} + +.layout-mobile .nowPlayingBarRight input, +.layout-mobile .nowPlayingBarRight div { + display: none; +} + @media all and (max-width: 56em) { .nowPlayingBarCenter { display: none !important; } } -@media all and (min-width: 56em) { - .nowPlayingBarRight .playPauseButton { - display: none; - } -} - -@media all and (max-width: 36em) { +@media all and (max-width: 60em) { .nowPlayingBarRight .nowPlayingBarVolumeSliderContainer { display: none !important; } .nowPlayingBarInfoContainer { - width: 70%; + width: 100%; } } diff --git a/src/components/nowPlayingBar/nowPlayingBar.js b/src/components/nowPlayingBar/nowPlayingBar.js index ec413cb7ae..3d2ef4f30f 100644 --- a/src/components/nowPlayingBar/nowPlayingBar.js +++ b/src/components/nowPlayingBar/nowPlayingBar.js @@ -62,7 +62,9 @@ import 'emby-ratingbutton'; html += ''; html += ''; - html += ''; + if (!layoutManager.mobile) { + html += ''; + } html += '
'; html += '
'; @@ -76,12 +78,17 @@ import 'emby-ratingbutton'; html += '
'; html += ''; + html += ''; html += '
'; html += '
'; html += ''; - html += ''; + if (layoutManager.mobile) { + html += ''; + } else { + html += ''; + } html += '
'; html += '
'; @@ -132,8 +139,13 @@ import 'emby-ratingbutton'; nowPlayingImageElement = elem.querySelector('.nowPlayingImage'); nowPlayingTextElement = elem.querySelector('.nowPlayingBarText'); nowPlayingUserData = elem.querySelector('.nowPlayingBarUserDataButtons'); - + positionSlider = elem.querySelector('.nowPlayingBarPositionSlider'); muteButton = elem.querySelector('.muteButton'); + playPauseButtons = elem.querySelectorAll('.playPauseButton'); + toggleRepeatButton = elem.querySelector('.toggleRepeatButton'); + volumeSlider = elem.querySelector('.nowPlayingBarVolumeSlider'); + volumeSliderContainer = elem.querySelector('.nowPlayingBarVolumeSliderContainer'); + muteButton.addEventListener('click', function () { if (currentPlayer) { @@ -149,7 +161,6 @@ import 'emby-ratingbutton'; } }); - playPauseButtons = elem.querySelectorAll('.playPauseButton'); playPauseButtons.forEach((button) => { button.addEventListener('click', onPlayPauseClick); }); @@ -161,54 +172,59 @@ import 'emby-ratingbutton'; } }); - elem.querySelector('.previousTrackButton').addEventListener('click', function () { + elem.querySelector('.previousTrackButton').addEventListener('click', function (e) { + if (currentPlayer) { + if (lastPlayerState.NowPlayingItem.MediaType === 'Audio' && (currentPlayer._currentTime >= 5 || !playbackManager.previousTrack(currentPlayer))) { + // Cancel this event if doubleclick is fired + if (e.detail > 1 && playbackManager.previousTrack(currentPlayer)) { + return; + } + playbackManager.seekPercent(0, currentPlayer); + // This is done automatically by playbackManager, however, setting this here gives instant visual feedback. + // TODO: Check why seekPercentage doesn't reflect the changes inmmediately, so we can remove this workaround. + positionSlider.value = 0; + } else { + playbackManager.previousTrack(currentPlayer); + } + } + }); + elem.querySelector('.previousTrackButton').addEventListener('dblclick', function () { if (currentPlayer) { playbackManager.previousTrack(currentPlayer); } }); + elem.querySelector('.btnShuffleQueue').addEventListener('click', function () { + if (currentPlayer) { + playbackManager.toggleQueueShuffleMode(); + } + }); + toggleRepeatButton = elem.querySelector('.toggleRepeatButton'); toggleRepeatButton.addEventListener('click', function () { - - if (currentPlayer) { - - switch (playbackManager.getRepeatMode(currentPlayer)) { - case 'RepeatAll': - playbackManager.setRepeatMode('RepeatOne', currentPlayer); - break; - case 'RepeatOne': - playbackManager.setRepeatMode('RepeatNone', currentPlayer); - break; - default: - playbackManager.setRepeatMode('RepeatAll', currentPlayer); - break; - } + switch (playbackManager.getRepeatMode()) { + case 'RepeatAll': + playbackManager.setRepeatMode('RepeatOne'); + break; + case 'RepeatOne': + playbackManager.setRepeatMode('RepeatNone'); + break; + case 'RepeatNone': + playbackManager.setRepeatMode('RepeatAll'); } }); toggleRepeatButtonIcon = toggleRepeatButton.querySelector('.material-icons'); - volumeSlider = elem.querySelector('.nowPlayingBarVolumeSlider'); - volumeSliderContainer = elem.querySelector('.nowPlayingBarVolumeSliderContainer'); + volumeSliderContainer.classList.toggle('hide', appHost.supports('physicalvolumecontrol')); - if (appHost.supports('physicalvolumecontrol')) { - volumeSliderContainer.classList.add('hide'); - } else { - volumeSliderContainer.classList.remove('hide'); - } - - function setVolume() { + volumeSlider.addEventListener('input', (e) => { if (currentPlayer) { - currentPlayer.setVolume(this.value); + currentPlayer.setVolume(e.target.value); } - } + }); - volumeSlider.addEventListener('change', setVolume); - volumeSlider.addEventListener('mousemove', setVolume); - volumeSlider.addEventListener('touchmove', setVolume); - - positionSlider = elem.querySelector('.nowPlayingBarPositionSlider'); positionSlider.addEventListener('change', function () { if (currentPlayer) { @@ -277,6 +293,11 @@ import 'emby-ratingbutton'; parentContainer.insertAdjacentHTML('afterbegin', getNowPlayingBarHtml()); nowPlayingBarElement = parentContainer.querySelector('.nowPlayingBar'); + if (layoutManager.mobile) { + hideButton(nowPlayingBarElement.querySelector('.btnShuffleQueue')); + hideButton(nowPlayingBarElement.querySelector('.nowPlayingBarCenter')); + } + if (browser.safari && browser.slow) { // Not handled well here. The wrong elements receive events, bar doesn't update quickly enough, etc. nowPlayingBarElement.classList.add('noMediaProgress'); @@ -329,7 +350,8 @@ import 'emby-ratingbutton'; toggleRepeatButton.classList.remove('hide'); } - updateRepeatModeDisplay(playState.RepeatMode); + updateRepeatModeDisplay(playbackManager.getRepeatMode()); + onQueueShuffleModeChange(); updatePlayerVolumeState(playState.IsMuted, playState.VolumeLevel); @@ -349,32 +371,39 @@ import 'emby-ratingbutton'; function updateRepeatModeDisplay(repeatMode) { toggleRepeatButtonIcon.classList.remove('repeat', 'repeat_one'); + const cssClass = 'buttonActive'; - if (repeatMode === 'RepeatAll') { - toggleRepeatButtonIcon.classList.add('repeat'); - toggleRepeatButton.classList.add('repeatButton-active'); - } else if (repeatMode === 'RepeatOne') { - toggleRepeatButtonIcon.classList.add('repeat_one'); - toggleRepeatButton.classList.add('repeatButton-active'); - } else { - toggleRepeatButtonIcon.classList.add('repeat'); - toggleRepeatButton.classList.remove('repeatButton-active'); + switch (repeatMode) { + case 'RepeatAll': + toggleRepeatButtonIcon.classList.add('repeat'); + toggleRepeatButton.classList.add(cssClass); + break; + case 'RepeatOne': + toggleRepeatButtonIcon.classList.add('repeat_one'); + toggleRepeatButton.classList.add(cssClass); + break; + case 'RepeatNone': + default: + toggleRepeatButtonIcon.classList.add('repeat'); + toggleRepeatButton.classList.remove(cssClass); + break; } } function updateTimeDisplay(positionTicks, runtimeTicks, bufferedRanges) { - // See bindEvents for why this is necessary if (positionSlider && !positionSlider.dragging) { if (runtimeTicks) { +<<<<<<< HEAD let pct = positionTicks / runtimeTicks; +======= + var pct = positionTicks / runtimeTicks; +>>>>>>> upstream/master pct *= 100; positionSlider.value = pct; - } else { - positionSlider.value = 0; } } @@ -384,9 +413,13 @@ import 'emby-ratingbutton'; } if (currentTimeElement) { +<<<<<<< HEAD let timeText = positionTicks == null ? '--:--' : datetime.getDisplayRunningTime(positionTicks); +======= + var timeText = positionTicks == null ? '--:--' : datetime.getDisplayRunningTime(positionTicks); +>>>>>>> upstream/master if (runtimeTicks) { timeText += ' / ' + datetime.getDisplayRunningTime(runtimeTicks); } @@ -428,11 +461,7 @@ import 'emby-ratingbutton'; // See bindEvents for why this is necessary if (volumeSlider) { - if (showVolumeSlider) { - volumeSliderContainer.classList.remove('hide'); - } else { - volumeSliderContainer.classList.add('hide'); - } + volumeSliderContainer.classList.toggle('hide', !showVolumeSlider); if (!volumeSlider.dragging) { volumeSlider.value = volumeLevel || 0; @@ -440,15 +469,6 @@ import 'emby-ratingbutton'; } } - function getTextActionButton(item, text) { - - if (!text) { - text = itemHelper.getDisplayName(item); - } - - return `${text}`; - } - function seriesImageUrl(item, options) { if (!item) { @@ -520,6 +540,7 @@ import 'emby-ratingbutton'; const nowPlayingItem = state.NowPlayingItem; +<<<<<<< HEAD const textLines = nowPlayingItem ? nowPlayingHelper.getNowPlayingNames(nowPlayingItem) : []; if (textLines.length > 1) { textLines[1].secondary = true; @@ -536,6 +557,31 @@ import 'emby-ratingbutton'; return `
${nowPlayingText}
`; }).join(''); +======= + var textLines = nowPlayingItem ? nowPlayingHelper.getNowPlayingNames(nowPlayingItem) : []; + nowPlayingTextElement.innerHTML = ''; + if (textLines) { + let itemText = document.createElement('div'); + let secondaryText = document.createElement('div'); + secondaryText.classList.add('nowPlayingBarSecondaryText'); + if (textLines.length > 1) { + textLines[1].secondary = true; + if (textLines[1].text) { + let text = document.createElement('a'); + text.innerHTML = textLines[1].text; + secondaryText.appendChild(text); + } + } + + if (textLines[0].text) { + let text = document.createElement('a'); + text.innerHTML = textLines[0].text; + itemText.appendChild(text); + } + nowPlayingTextElement.appendChild(itemText); + nowPlayingTextElement.appendChild(secondaryText); + } +>>>>>>> upstream/master const imgHeight = 70; @@ -553,8 +599,12 @@ import 'emby-ratingbutton'; if (url) { imageLoader.lazyImage(nowPlayingImageElement, url); + nowPlayingImageElement.style.display = null; + nowPlayingTextElement.style.marginLeft = null; } else { nowPlayingImageElement.style.backgroundImage = ''; + nowPlayingImageElement.style.display = 'none'; + nowPlayingTextElement.style.marginLeft = '1em'; } } @@ -563,6 +613,7 @@ import 'emby-ratingbutton'; const apiClient = connectionManager.getApiClient(nowPlayingItem.ServerId); apiClient.getItem(apiClient.getCurrentUserId(), nowPlayingItem.Id).then(function (item) { +<<<<<<< HEAD const userData = item.UserData || {}; const likes = userData.Likes == null ? '' : userData.Likes; const contextButton = document.querySelector('.btnToggleContextMenu'); @@ -578,8 +629,32 @@ import 'emby-ratingbutton'; item: item, user: user }, options )); +======= + var userData = item.UserData || {}; + var likes = userData.Likes == null ? '' : userData.Likes; + if (!layoutManager.mobile) { + let contextButton = nowPlayingBarElement.querySelector('.btnToggleContextMenu'); + // We remove the previous event listener by replacing the item in each update event + let contextButtonClone = contextButton.cloneNode(true); + contextButton.parentNode.replaceChild(contextButtonClone, contextButton); + contextButton = nowPlayingBarElement.querySelector('.btnToggleContextMenu'); + let options = { + play: false, + queue: false, + clearQueue: true, + positionTo: contextButton + }; + apiClient.getCurrentUser().then(function (user) { + contextButton.addEventListener('click', function () { + itemContextMenu.show(Object.assign({ + item: item, + user: user + }, options)); + }); +>>>>>>> upstream/master }); - }); + } + nowPlayingUserData.innerHTML = ''; }); } } else { @@ -589,25 +664,49 @@ import 'emby-ratingbutton'; function onPlaybackStart(e, state) { console.debug('nowplaying event: ' + e.type); +<<<<<<< HEAD const player = this; +======= + var player = this; +>>>>>>> upstream/master onStateChanged.call(player, e, state); } - function onRepeatModeChange(e) { - + function onRepeatModeChange() { if (!isEnabled) { return; } +<<<<<<< HEAD const player = this; +======= + updateRepeatModeDisplay(playbackManager.getRepeatMode()); + } - updateRepeatModeDisplay(playbackManager.getRepeatMode(player)); + function onQueueShuffleModeChange() { + if (!isEnabled) { + return; + } +>>>>>>> upstream/master + + let shuffleMode = playbackManager.getQueueShuffleMode(); + let context = nowPlayingBarElement; + const cssClass = 'buttonActive'; + let toggleShuffleButton = context.querySelector('.btnShuffleQueue'); + switch (shuffleMode) { + case 'Shuffle': + toggleShuffleButton.classList.add(cssClass); + break; + case 'Sorted': + default: + toggleShuffleButton.classList.remove(cssClass); + break; + } } function showNowPlayingBar() { - if (!isVisibilityAllowed) { hideNowPlayingBar(); return; @@ -711,6 +810,7 @@ import 'emby-ratingbutton'; events.off(player, 'playbackstart', onPlaybackStart); events.off(player, 'statechange', onPlaybackStart); events.off(player, 'repeatmodechange', onRepeatModeChange); + events.off(player, 'shufflequeuemodechange', onQueueShuffleModeChange); events.off(player, 'playbackstop', onPlaybackStopped); events.off(player, 'volumechange', onVolumeChanged); events.off(player, 'pause', onPlayPauseStateChanged); @@ -759,6 +859,7 @@ import 'emby-ratingbutton'; events.on(player, 'playbackstart', onPlaybackStart); events.on(player, 'statechange', onPlaybackStart); events.on(player, 'repeatmodechange', onRepeatModeChange); + events.on(player, 'shufflequeuemodechange', onQueueShuffleModeChange); events.on(player, 'playbackstop', onPlaybackStopped); events.on(player, 'volumechange', onVolumeChanged); events.on(player, 'pause', onPlayPauseStateChanged); diff --git a/src/components/playback/playbackmanager.js b/src/components/playback/playbackmanager.js index b74ca5fb3d..fe3ff11250 100644 --- a/src/components/playback/playbackmanager.js +++ b/src/components/playback/playbackmanager.js @@ -1,9 +1,6 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'playQueueManager', 'userSettings', 'globalize', 'connectionManager', 'loading', 'apphost', 'screenfull'], function (events, datetime, appSettings, itemHelper, pluginManager, PlayQueueManager, userSettings, globalize, connectionManager, loading, apphost, screenfull) { 'use strict'; - /** Delay time in ms for reportPlayback logging */ - const reportPlaybackLogDelay = 1e3; - function enableLocalPlaylistManagement(player) { if (player.getPlaylist) { @@ -43,12 +40,6 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla events.trigger(playbackManagerInstance, 'playerchange', [newPlayer, newTarget, previousPlayer]); } - /** Last invoked method */ - let reportPlaybackLastMethod; - - /** Last invoke time of method */ - let reportPlaybackLastTime; - function reportPlayback(playbackManagerInstance, state, player, reportPlaylist, serverId, method, progressEventName) { if (!serverId) { @@ -69,14 +60,6 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla addPlaylistToPlaybackReport(playbackManagerInstance, info, player, serverId); } - const now = (new Date).getTime(); - - if (method !== reportPlaybackLastMethod || now - (reportPlaybackLastTime || 0) >= reportPlaybackLogDelay) { - console.debug(method + '-' + JSON.stringify(info)); - reportPlaybackLastMethod = method; - reportPlaybackLastTime = now; - } - var apiClient = connectionManager.getApiClient(serverId); var reportPlaybackPromise = apiClient[method](info); // Notify that report has been sent @@ -2097,6 +2080,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla state.PlayState.IsMuted = player.isMuted(); state.PlayState.IsPaused = player.paused(); state.PlayState.RepeatMode = self.getRepeatMode(player); + state.PlayState.ShuffleMode = self.getQueueShuffleMode(player); state.PlayState.MaxStreamingBitrate = self.getMaxStreamingBitrate(player); state.PlayState.PositionTicks = getCurrentTicks(player); @@ -2877,11 +2861,11 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } }; - self.queue = function (options, player) { + self.queue = function (options, player = this._currentPlayer) { queue(options, '', player); }; - self.queueNext = function (options, player) { + self.queueNext = function (options, player = this._currentPlayer) { queue(options, 'next', player); }; @@ -2969,6 +2953,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla } else { self._playQueueManager.queue(items); } + events.trigger(player, 'playlistitemadd'); } function onPlayerProgressInterval() { @@ -3304,6 +3289,11 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla sendProgressUpdate(player, 'repeatmodechange'); } + function onShuffleQueueModeChange() { + var player = this; + sendProgressUpdate(player, 'shufflequeuemodechange'); + } + function onPlaylistItemMove(e) { var player = this; sendProgressUpdate(player, 'playlistitemmove', true); @@ -3358,6 +3348,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla events.on(player, 'unpause', onPlaybackUnpause); events.on(player, 'volumechange', onPlaybackVolumeChange); events.on(player, 'repeatmodechange', onRepeatModeChange); + events.on(player, 'shufflequeuemodechange', onShuffleQueueModeChange); events.on(player, 'playlistitemmove', onPlaylistItemMove); events.on(player, 'playlistitemremove', onPlaylistItemRemove); events.on(player, 'playlistitemadd', onPlaylistItemAdd); @@ -3370,6 +3361,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla events.on(player, 'unpause', onPlaybackUnpause); events.on(player, 'volumechange', onPlaybackVolumeChange); events.on(player, 'repeatmodechange', onRepeatModeChange); + events.on(player, 'shufflequeuemodechange', onShuffleQueueModeChange); events.on(player, 'playlistitemmove', onPlaylistItemMove); events.on(player, 'playlistitemremove', onPlaylistItemRemove); events.on(player, 'playlistitemadd', onPlaylistItemAdd); @@ -3655,6 +3647,14 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla this.seek(parseInt(ticks), player); }; + PlaybackManager.prototype.seekMs = function (ms, player) { + + player = player || this._currentPlayer; + + var ticks = ms * 10000; + this.seek(ticks, player); + }; + PlaybackManager.prototype.playTrailers = function (item) { var player = this._currentPlayer; @@ -3702,7 +3702,6 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }; PlaybackManager.prototype.stop = function (player) { - player = player || this._currentPlayer; if (player) { @@ -3811,7 +3810,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla }); }; - PlaybackManager.prototype.shuffle = function (shuffleItem, player, queryOptions) { + PlaybackManager.prototype.shuffle = function (shuffleItem, player) { player = player || this._currentPlayer; if (player && player.shuffle) { @@ -3878,6 +3877,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla 'GoToSearch', 'DisplayMessage', 'SetRepeatMode', + 'SetShuffleQueue', 'PlayMediaSource', 'PlayTrailers' ]; @@ -3911,9 +3911,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return info ? info.supportedCommands : []; }; - PlaybackManager.prototype.setRepeatMode = function (value, player) { - - player = player || this._currentPlayer; + PlaybackManager.prototype.setRepeatMode = function (value, player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.setRepeatMode(value); } @@ -3922,9 +3920,7 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla events.trigger(player, 'repeatmodechange'); }; - PlaybackManager.prototype.getRepeatMode = function (player) { - - player = player || this._currentPlayer; + PlaybackManager.prototype.getRepeatMode = function (player = this._currentPlayer) { if (player && !enableLocalPlaylistManagement(player)) { return player.getRepeatMode(); } @@ -3932,6 +3928,52 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla return this._playQueueManager.getRepeatMode(); }; + PlaybackManager.prototype.setQueueShuffleMode = function (value, player = this._currentPlayer) { + if (player && !enableLocalPlaylistManagement(player)) { + return player.setQueueShuffleMode(value); + } + + this._playQueueManager.setShuffleMode(value); + events.trigger(player, 'shufflequeuemodechange'); + }; + + PlaybackManager.prototype.getQueueShuffleMode = function (player = this._currentPlayer) { + if (player && !enableLocalPlaylistManagement(player)) { + return player.getQueueShuffleMode(); + } + + return this._playQueueManager.getShuffleMode(); + }; + + PlaybackManager.prototype.toggleQueueShuffleMode = function (player = this._currentPlayer) { + let currentvalue; + if (player && !enableLocalPlaylistManagement(player)) { + currentvalue = player.getQueueShuffleMode(); + switch (currentvalue) { + case 'Shuffle': + player.setQueueShuffleMode('Sorted'); + break; + case 'Sorted': + player.setQueueShuffleMode('Shuffle'); + break; + default: + throw new TypeError('current value for shufflequeue is invalid'); + } + } else { + this._playQueueManager.toggleShuffleMode(); + } + events.trigger(player, 'shufflequeuemodechange'); + }; + + PlaybackManager.prototype.clearQueue = function (clearCurrentItem = false, player = this._currentPlayer) { + if (player && !enableLocalPlaylistManagement(player)) { + return player.clearQueue(clearCurrentItem); + } + + this._playQueueManager.clearPlaylist(clearCurrentItem); + events.trigger(player, 'playlistitemremove'); + }; + PlaybackManager.prototype.trySetActiveDeviceName = function (name) { name = normalizeName(name); @@ -4000,6 +4042,9 @@ define(['events', 'datetime', 'appSettings', 'itemHelper', 'pluginManager', 'pla case 'SetRepeatMode': this.setRepeatMode(cmd.Arguments.RepeatMode, player); break; + case 'SetShuffleQueue': + this.setQueueShuffleMode(cmd.Arguments.ShuffleMode, player); + break; case 'VolumeUp': this.volumeUp(player); break; diff --git a/src/components/playback/playqueuemanager.js b/src/components/playback/playqueuemanager.js index 565cb6993e..2f411091c6 100644 --- a/src/components/playback/playqueuemanager.js +++ b/src/components/playback/playqueuemanager.js @@ -24,8 +24,10 @@ define([], function () { function PlayQueueManager() { + this._sortedPlaylist = []; this._playlist = []; this._repeatMode = 'RepeatNone'; + this._shuffleMode = 'Sorted'; } PlayQueueManager.prototype.getPlaylist = function () { @@ -56,6 +58,40 @@ define([], function () { } }; + PlayQueueManager.prototype.shufflePlaylist = function () { + this._sortedPlaylist = []; + for (const item of this._playlist) { + this._sortedPlaylist.push(item); + } + const currentPlaylistItem = this._playlist.splice(this.getCurrentPlaylistIndex(), 1)[0]; + + for (let i = this._playlist.length - 1; i > 0; i--) { + const j = Math.floor(Math.random() * i); + const temp = this._playlist[i]; + this._playlist[i] = this._playlist[j]; + this._playlist[j] = temp; + } + this._playlist.unshift(currentPlaylistItem); + this._shuffleMode = 'Shuffle'; + }; + + PlayQueueManager.prototype.sortShuffledPlaylist = function () { + this._playlist = []; + for (let item of this._sortedPlaylist) { + this._playlist.push(item); + } + this._sortedPlaylist = []; + this._shuffleMode = 'Sorted'; + }; + + PlayQueueManager.prototype.clearPlaylist = function (clearCurrentItem = false) { + const currentPlaylistItem = this._playlist.splice(this.getCurrentPlaylistIndex(), 1)[0]; + this._playlist = []; + if (!clearCurrentItem) { + this._playlist.push(currentPlaylistItem); + } + }; + function arrayInsertAt(destArray, pos, arrayToInsert) { var args = []; args.push(pos); // where to insert @@ -116,9 +152,7 @@ define([], function () { PlayQueueManager.prototype.removeFromPlaylist = function (playlistItemIds) { - var playlist = this.getPlaylist(); - - if (playlist.length <= playlistItemIds.length) { + if (this._playlist.length <= playlistItemIds.length) { return { result: 'empty' }; @@ -127,8 +161,12 @@ define([], function () { var currentPlaylistItemId = this.getCurrentPlaylistItemId(); var isCurrentIndex = playlistItemIds.indexOf(currentPlaylistItemId) !== -1; - this._playlist = playlist.filter(function (item) { - return playlistItemIds.indexOf(item.PlaylistItemId) === -1; + this._sortedPlaylist = this._sortedPlaylist.filter(function (item) { + return !playlistItemIds.includes(item.PlaylistItemId); + }); + + this._playlist = this._playlist.filter(function (item) { + return !playlistItemIds.includes(item.PlaylistItemId); }); return { @@ -176,21 +214,56 @@ define([], function () { PlayQueueManager.prototype.reset = function () { + this._sortedPlaylist = []; this._playlist = []; this._currentPlaylistItemId = null; this._repeatMode = 'RepeatNone'; + this._shuffleMode = 'Sorted'; }; PlayQueueManager.prototype.setRepeatMode = function (value) { - - this._repeatMode = value; + const repeatModes = ['RepeatOne', 'RepeatAll', 'RepeatNone']; + if (repeatModes.includes(value)) { + this._repeatMode = value; + } else { + throw new TypeError('invalid value provided for setRepeatMode'); + } }; PlayQueueManager.prototype.getRepeatMode = function () { - return this._repeatMode; }; + PlayQueueManager.prototype.setShuffleMode = function (value) { + switch (value) { + case 'Shuffle': + this.shufflePlaylist(); + break; + case 'Sorted': + this.sortShuffledPlaylist(); + break; + default: + throw new TypeError('invalid value provided to setShuffleMode'); + } + }; + + PlayQueueManager.prototype.toggleShuffleMode = function () { + switch (this._shuffleMode) { + case 'Shuffle': + this.setShuffleMode('Sorted'); + break; + case 'Sorted': + this.setShuffleMode('Shuffle'); + break; + default: + throw new TypeError('current value for shufflequeue is invalid'); + } + }; + + PlayQueueManager.prototype.getShuffleMode = function () { + return this._shuffleMode; + }; + PlayQueueManager.prototype.getNextItemInfo = function () { var newIndex; diff --git a/src/components/playerstats/playerstats.js b/src/components/playerstats/playerstats.js index ca9d6dc20e..fce37c1507 100644 --- a/src/components/playerstats/playerstats.js +++ b/src/components/playerstats/playerstats.js @@ -415,7 +415,8 @@ import 'css!./playerstats'; name: 'Original Media Info' }); - if (syncPlayManager.isSyncPlayEnabled()) { + var apiClient = connectionManager.getApiClient(playbackManager.currentItem(player).ServerId); + if (syncPlayManager.isSyncPlayEnabled() && apiClient.isMinServerVersion('10.6.0')) { categories.push({ stats: getSyncPlayStats(), name: 'SyncPlay Info' diff --git a/src/components/remotecontrol/remotecontrol.css b/src/components/remotecontrol/remotecontrol.css index 073c925339..c260799585 100644 --- a/src/components/remotecontrol/remotecontrol.css +++ b/src/components/remotecontrol/remotecontrol.css @@ -157,43 +157,110 @@ } .nowPlayingSecondaryButtons { - display: -webkit-box; - display: -webkit-flex; display: flex; - -webkit-box-align: center; - -webkit-align-items: center; align-items: center; - -webkit-flex-wrap: wrap; flex-wrap: wrap; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; justify-content: flex-end; z-index: 0; } +.layout-mobile .playlistSectionButtonTransparent { + background: rgba(0, 0, 0, 0) !important; +} + +.layout-mobile .playlistSection .playlist, +.layout-mobile .playlistSection .contextMenu { + position: absolute; + top: 12.2em; + bottom: 4.2em; + overflow: scroll; + padding: 0 1em; + display: inline-block; + left: 0; + right: 0; + z-index: 1000; +} + +.layout-mobile .playlistSectionButton { + position: fixed; + bottom: 0; + left: 0; + height: 4.2em; + right: 0; + padding-left: 7.3%; + padding-right: 7.3%; +} + +.layout-desktop .playlistSectionButton, +.layout-tv .playlistSectionButton { + background: none; +} + +.layout-desktop .nowPlayingPlaylist, +.layout-tv .nowPlayingPlaylist { + background: none; +} + +.layout-mobile .playlistSectionButton .btnTogglePlaylist { + font-size: larger; + margin: 0; +} + +.layout-mobile .playlistSectionButton .btnSavePlaylist { + margin: 0; + border-radius: 0; +} + +.layout-mobile .playlistSectionButton .volumecontrol { + margin: 0; + padding-right: 0; + border-radius: 0; +} + +.layout-mobile .playlistSectionButton .btnToggleContextMenu { + font-size: larger; + margin: 0; +} + +.layout-mobile .nowPlayingSecondaryButtons .btnShuffleQueue { + display: none; +} + +.layout-mobile .nowPlayingSecondaryButtons .volumecontrol { + display: none; +} + +.layout-mobile .nowPlayingSecondaryButtons .btnRepeat { + display: none; +} + +.layout-desktop .nowPlayingInfoButtons .btnRepeat, +.layout-tv .nowPlayingInfoButtons .btnRepeat { + display: none; +} + +.layout-desktop .nowPlayingInfoButtons .btnShuffleQueue, +.layout-tv .nowPlayingInfoButtons .btnShuffleQueue { + display: none; +} + +.layout-desktop .playlistSectionButton .volumecontrol, +.layout-tv .playlistSectionButton .volumecontrol { + display: none; +} + +.nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle { + display: none; +} + +.layout-mobile .nowPlayingPageUserDataButtons { + display: none; +} + @media all and (min-width: 63em) { .nowPlayingPage { padding: 8em 0 0 0 !important; } - - .nowPlayingSecondaryButtons { - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - flex-grow: 1; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - justify-content: flex-end; - } - - .nowPlayingPageUserDataButtonsTitle { - display: none !important; - } - - .playlistSectionButton, - .nowPlayingPlaylist, - .nowPlayingContextMenu { - background: unset !important; - } } @media all and (min-width: 80em) { @@ -202,7 +269,7 @@ } } -@media all and (orientation: portrait) and (max-width: 47em) { +@media all and (orientation: portrait) and (max-width: 43em) { .remoteControlContent { padding-left: 7.3% !important; padding-right: 7.3% !important; @@ -211,6 +278,10 @@ flex-direction: column; } + .layout-desktop .nowPlayingPageUserDataButtons { + display: none; + } + .nowPlayingInfoContainer { -webkit-box-orient: vertical !important; -webkit-box-direction: normal !important; @@ -280,6 +351,7 @@ .nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle { width: 20%; font-size: large; + display: unset; } .nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle button { @@ -290,7 +362,7 @@ border-radius: 0; } - .nowPlayingInfoButtons .btnRewind { + .nowPlayingInfoButtons .btnRepeat { position: absolute; left: 0; margin-left: 0; @@ -298,7 +370,7 @@ font-size: smaller; } - .nowPlayingInfoButtons .btnFastForward { + .nowPlayingInfoButtons .btnShuffleQueue { position: absolute; right: 0; margin-right: 0; @@ -342,250 +414,6 @@ width: auto; } - #nowPlayingPage .playlistSection .playlist, - #nowPlayingPage .playlistSection .contextMenu { - position: absolute; - top: 12.2em; - bottom: 4.2em; - overflow: scroll; - padding: 0 1em; - display: inline-block; - left: 0; - right: 0; - z-index: 1000; - } - - .playlistSectionButton { - position: fixed; - bottom: 0; - left: 0; - height: 4.2em; - right: 0; - padding-left: 7.3%; - padding-right: 7.3%; - } - - .playlistSectionButton .btnTogglePlaylist { - font-size: larger; - margin: 0; - padding-left: 0; - } - - .playlistSectionButton .btnSavePlaylist { - margin: 0; - padding-right: 0; - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - flex-grow: 1; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - justify-content: flex-end; - border-radius: 0; - } - - .playlistSectionButton .btnToggleContextMenu { - font-size: larger; - margin: 0; - padding-right: 0; - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - flex-grow: 1; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - justify-content: flex-end; - border-radius: 0; - } - - .playlistSectionButton .volumecontrol { - width: 100%; - } - - .remoteControlSection { - margin: 0; - padding: 0 0 4.2em 0; - } - - .nowPlayingButtonsContainer { - display: flex; - height: 100%; - flex-direction: column; - } -} - -@media all and (orientation: landscape) and (max-width: 63em) { - .remoteControlContent { - padding-left: 4.3% !important; - padding-right: 4.3% !important; - display: flex; - height: 100%; - flex-direction: column; - } - - .nowPlayingInfoContainer { - -webkit-box-orient: horizontal !important; - -webkit-box-direction: normal !important; - -webkit-flex-direction: row !important; - flex-direction: row !important; - -webkit-box-align: center; - -webkit-align-items: center; - align-items: center; - width: 100%; - height: calc(100% - 4.2em); - } - - .nowPlayingPageTitle { - /* text-align: center; */ - margin: 0; - } - - .nowPlayingInfoContainerMedia { - text-align: left !important; - width: 80%; - } - - .nowPlayingPositionSliderContainer { - margin: 0.2em 1em 0.2em 1em; - } - - .nowPlayingInfoButtons { - /* margin: 1.5em 0 0 0; */ - -webkit-box-pack: center; - -webkit-justify-content: center; - justify-content: center; - font-size: x-large; - height: 100%; - } - - .nowPlayingPageImageContainer { - width: 30%; - margin: auto 1em auto auto; - } - - .nowPlayingPageImageContainerNoAlbum .cardImageContainer .cardImageIcon { - font-size: 12em; - color: inherit; - } - - .nowPlayingInfoControls { - margin: 0.5em 0 1em 0; - width: 100%; - -webkit-box-pack: start !important; - -webkit-justify-content: start !important; - justify-content: start !important; - } - - .nowPlayingSecondaryButtons { - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - flex-grow: 1; - -webkit-box-pack: center; - -webkit-justify-content: center; - justify-content: center; - } - - .nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle { - width: 20%; - font-size: large; - } - - .nowPlayingInfoControls .nowPlayingPageUserDataButtonsTitle button { - padding-top: 0; - padding-right: 0; - margin-right: 0; - float: right; - border-radius: 0; - } - - .paper-icon-button-light:hover { - color: #fff !important; - background-color: transparent !important; - } - - .btnPlayPause { - padding: 0; - margin: 0; - font-size: 1.7em; - } - - .btnPlayPause:hover { - background-color: transparent !important; - } - - .nowPlayingPageImage { - /* width: inherit; */ - overflow-y: hidden; - overflow: hidden; - margin: 0 auto; - } - - .nowPlayingPageImage.nowPlayingPageImageAudio { - width: 100%; - } - - .nowPlayingPageImageContainer.nowPlayingPageImagePoster { - height: 100%; - overflow: hidden; - } - - .nowPlayingPageImageContainer.nowPlayingPageImagePoster img { - height: 100%; - width: auto; - } - - #nowPlayingPage .playlistSection .playlist, - #nowPlayingPage .playlistSection .contextMenu { - position: absolute; - top: 7.2em; - bottom: 4.2em; - overflow: scroll; - padding: 0 1em; - display: inline-block; - left: 0; - right: 0; - z-index: 1000; - } - - .playlistSectionButton { - position: fixed; - bottom: 0; - left: 0; - height: 4.2em; - right: 0; - padding-left: 4.3%; - padding-right: 4.3%; - } - - .playlistSectionButton .btnTogglePlaylist { - font-size: larger; - margin: 0; - padding-left: 0; - } - - .playlistSectionButton .btnSavePlaylist { - margin: 0; - padding-right: 0; - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - flex-grow: 1; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - justify-content: flex-end; - border-radius: 0; - } - - .playlistSectionButton .btnToggleContextMenu { - font-size: larger; - margin: 0; - padding-right: 0; - -webkit-box-flex: 1; - -webkit-flex-grow: 1; - flex-grow: 1; - -webkit-box-pack: end; - -webkit-justify-content: flex-end; - justify-content: flex-end; - border-radius: 0; - } - .playlistSectionButton .volumecontrol { width: 100%; } @@ -627,6 +455,10 @@ background-image: url(../../assets/img/equalizer.gif) !important; } +.playlistIndexIndicatorImage > * { + display: none; +} + .hideVideoButtons .videoButton { display: none; } @@ -636,7 +468,6 @@ } @media all and (max-width: 63em) { - .nowPlayingSecondaryButtons .nowPlayingPageUserDataButtons, .nowPlayingSecondaryButtons .repeatToggleButton, .nowPlayingInfoButtons .playlist .listItemMediaInfo, .nowPlayingInfoButtons .btnStop { diff --git a/src/components/remotecontrol/remotecontrol.js b/src/components/remotecontrol/remotecontrol.js index fe239e9579..874137155c 100644 --- a/src/components/remotecontrol/remotecontrol.js +++ b/src/components/remotecontrol/remotecontrol.js @@ -1,5 +1,7 @@ -define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageLoader', 'playbackManager', 'nowPlayingHelper', 'events', 'connectionManager', 'apphost', 'globalize', 'layoutManager', 'userSettings', 'cardBuilder', 'cardStyle', 'emby-itemscontainer', 'css!./remotecontrol.css', 'emby-ratingbutton'], function (browser, datetime, backdrop, libraryBrowser, listView, imageLoader, playbackManager, nowPlayingHelper, events, connectionManager, appHost, globalize, layoutManager, userSettings, cardBuilder) { +define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageLoader', 'playbackManager', 'nowPlayingHelper', 'events', 'connectionManager', 'apphost', 'globalize', 'layoutManager', 'userSettings', 'cardBuilder', 'itemContextMenu', 'cardStyle', 'emby-itemscontainer', 'css!./remotecontrol.css', 'emby-ratingbutton'], function (browser, datetime, backdrop, libraryBrowser, listView, imageLoader, playbackManager, nowPlayingHelper, events, connectionManager, appHost, globalize, layoutManager, userSettings, cardBuilder, itemContextMenu) { 'use strict'; + var showMuteButton = true; + var showVolumeSlider = true; function showAudioMenu(context, player, button, item) { var currentIndex = playbackManager.getAudioStreamIndex(player); @@ -118,30 +120,41 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL if (item.Type == 'Audio' || item.MediaStreams[0].Type == 'Audio') { var songName = item.Name; if (item.Album != null && item.Artists != null) { + var artistsSeries = ''; var albumName = item.Album; - var artistName; if (item.ArtistItems != null) { - artistName = item.ArtistItems[0].Name; - context.querySelector('.nowPlayingAlbum').innerHTML = '${albumName}`; - context.querySelector('.nowPlayingArtist').innerHTML = '${artistName}`; - context.querySelector('.contextMenuAlbum').innerHTML = ' ` + globalize.translate('ViewAlbum') + ''; - context.querySelector('.contextMenuArtist').innerHTML = ' ` + globalize.translate('ViewArtist') + ''; - } else { - artistName = item.Artists; - context.querySelector('.nowPlayingAlbum').innerHTML = albumName; - context.querySelector('.nowPlayingArtist').innerHTML = artistName; + for (const artist of item.ArtistItems) { + let artistName = artist.Name; + let artistId = artist.Id; + artistsSeries += `${artistName}`; + if (artist !== item.ArtistItems.slice(-1)[0]) { + artistsSeries += ', '; + } + } + } else if (item.Artists) { + // For some reason, Chromecast Player doesn't return a item.ArtistItems object, so we need to fallback + // to normal item.Artists item. + // TODO: Normalise fields returned by all the players + for (const artist of item.Artists) { + artistsSeries += `${artist}`; + if (artist !== item.Artists.slice(-1)[0]) { + artistsSeries += ', '; + } + } } + context.querySelector('.nowPlayingArtist').innerHTML = artistsSeries; + context.querySelector('.nowPlayingAlbum').innerHTML = '${albumName}`; } context.querySelector('.nowPlayingSongName').innerHTML = songName; } else if (item.Type == 'Episode') { if (item.SeasonName != null) { var seasonName = item.SeasonName; - context.querySelector('.nowPlayingSeason').innerHTML = '${seasonName}`; + context.querySelector('.nowPlayingSeason').innerHTML = '${seasonName}`; } if (item.SeriesName != null) { var seriesName = item.SeriesName; if (item.SeriesId != null) { - context.querySelector('.nowPlayingSerie').innerHTML = '${seriesName}`; + context.querySelector('.nowPlayingSerie').innerHTML = '${seriesName}`; } else { context.querySelector('.nowPlayingSerie').innerHTML = seriesName; } @@ -163,11 +176,38 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL maxHeight: 300 * 2 }) : null; - console.debug('updateNowPlayingInfo'); + let contextButton = context.querySelector('.btnToggleContextMenu'); + // We remove the previous event listener by replacing the item in each update event + const autoFocusContextButton = document.activeElement === contextButton; + let contextButtonClone = contextButton.cloneNode(true); + contextButton.parentNode.replaceChild(contextButtonClone, contextButton); + contextButton = context.querySelector('.btnToggleContextMenu'); + if (autoFocusContextButton) { + contextButton.focus(); + } + const stopPlayback = !!layoutManager.mobile; + var options = { + play: false, + queue: false, + stopPlayback: stopPlayback, + clearQueue: true, + openAlbum: false, + positionTo: contextButton + }; + var apiClient = connectionManager.getApiClient(item.ServerId); + apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (fullItem) { + apiClient.getCurrentUser().then(function (user) { + contextButton.addEventListener('click', function () { + itemContextMenu.show(Object.assign({ + item: fullItem, + user: user + }, options)); + }); + }); + }); setImageUrl(context, state, url); if (item) { backdrop.setBackdrops([item]); - var apiClient = connectionManager.getApiClient(item.ServerId); apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (fullItem) { var userData = fullItem.UserData || {}; var likes = null == userData.Likes ? '' : userData.Likes; @@ -219,20 +259,16 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL var currentImgUrl; return function () { - function toggleRepeat(player) { - if (player) { - switch (playbackManager.getRepeatMode(player)) { - case 'RepeatNone': - playbackManager.setRepeatMode('RepeatAll', player); - break; - - case 'RepeatAll': - playbackManager.setRepeatMode('RepeatOne', player); - break; - - case 'RepeatOne': - playbackManager.setRepeatMode('RepeatNone', player); - } + function toggleRepeat() { + switch (playbackManager.getRepeatMode()) { + case 'RepeatAll': + playbackManager.setRepeatMode('RepeatOne'); + break; + case 'RepeatOne': + playbackManager.setRepeatMode('RepeatNone'); + break; + case 'RepeatNone': + playbackManager.setRepeatMode('RepeatAll'); } } @@ -275,8 +311,13 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL buttonVisible(context.querySelector('.btnStop'), null != item); buttonVisible(context.querySelector('.btnNextTrack'), null != item); buttonVisible(context.querySelector('.btnPreviousTrack'), null != item); - buttonVisible(context.querySelector('.btnRewind'), null != item); - buttonVisible(context.querySelector('.btnFastForward'), null != item); + if (layoutManager.mobile) { + buttonVisible(context.querySelector('.btnRewind'), false); + buttonVisible(context.querySelector('.btnFastForward'), false); + } else { + buttonVisible(context.querySelector('.btnRewind'), null != item); + buttonVisible(context.querySelector('.btnFastForward'), null != item); + } var positionSlider = context.querySelector('.nowPlayingPositionSlider'); if (positionSlider && item && item.RunTimeTicks) { @@ -300,7 +341,8 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL context.classList.add('hideVideoButtons'); } - updateRepeatModeDisplay(playState.RepeatMode); + updateRepeatModeDisplay(playbackManager.getRepeatMode()); + onShuffleQueueModeChange(false); updateNowPlayingInfo(context, state); } @@ -316,25 +358,32 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function updateRepeatModeDisplay(repeatMode) { var context = dlg; - var toggleRepeatButton = context.querySelector('.repeatToggleButton'); + let toggleRepeatButtons = context.querySelectorAll('.repeatToggleButton'); + const cssClass = 'buttonActive'; + let innHtml = ''; + let repeatOn = true; - if ('RepeatAll' == repeatMode) { - toggleRepeatButton.innerHTML = ""; - toggleRepeatButton.classList.add('repeatButton-active'); - } else if ('RepeatOne' == repeatMode) { - toggleRepeatButton.innerHTML = ""; - toggleRepeatButton.classList.add('repeatButton-active'); - } else { - toggleRepeatButton.innerHTML = ""; - toggleRepeatButton.classList.remove('repeatButton-active'); + switch (repeatMode) { + case 'RepeatAll': + break; + case 'RepeatOne': + innHtml = ''; + break; + case 'RepeatNone': + default: + repeatOn = false; + break; + } + + for (const toggleRepeatButton of toggleRepeatButtons) { + toggleRepeatButton.classList.toggle(cssClass, repeatOn); + toggleRepeatButton.innerHTML = innHtml; } } function updatePlayerVolumeState(context, isMuted, volumeLevel) { var view = context; var supportedCommands = currentPlayerSupportedCommands; - var showMuteButton = true; - var showVolumeSlider = true; if (-1 === supportedCommands.indexOf('Mute')) { showMuteButton = false; @@ -362,24 +411,21 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL buttonMuteIcon.classList.add('volume_up'); } - if (showMuteButton) { - buttonMute.classList.remove('hide'); + if (!showMuteButton && !showVolumeSlider) { + context.querySelector('.volumecontrol').classList.add('hide'); } else { - buttonMute.classList.add('hide'); - } + buttonMute.classList.toggle('hide', !showMuteButton); - var nowPlayingVolumeSlider = context.querySelector('.nowPlayingVolumeSlider'); - var nowPlayingVolumeSliderContainer = context.querySelector('.nowPlayingVolumeSliderContainer'); + var nowPlayingVolumeSlider = context.querySelector('.nowPlayingVolumeSlider'); + var nowPlayingVolumeSliderContainer = context.querySelector('.nowPlayingVolumeSliderContainer'); - if (nowPlayingVolumeSlider) { - if (showVolumeSlider) { - nowPlayingVolumeSliderContainer.classList.remove('hide'); - } else { - nowPlayingVolumeSliderContainer.classList.add('hide'); - } + if (nowPlayingVolumeSlider) { - if (!nowPlayingVolumeSlider.dragging) { - nowPlayingVolumeSlider.value = volumeLevel || 0; + nowPlayingVolumeSliderContainer.classList.toggle('hide', !showVolumeSlider); + + if (!nowPlayingVolumeSlider.dragging) { + nowPlayingVolumeSlider.value = volumeLevel || 0; + } } } } @@ -420,11 +466,21 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function loadPlaylist(context, player) { getPlaylistItems(player).then(function (items) { var html = ''; + let favoritesEnabled = true; + if (layoutManager.mobile) { + if (items.length > 0) { + context.querySelector('.btnTogglePlaylist').classList.remove('hide'); + } else { + context.querySelector('.btnTogglePlaylist').classList.add('hide'); + } + favoritesEnabled = false; + } + html += listView.getListViewHtml({ items: items, smallIcon: true, action: 'setplaylistindex', - enableUserDataButtons: false, + enableUserDataButtons: favoritesEnabled, rightButtons: [{ icon: 'remove_circle_outline', title: globalize.translate('ButtonRemove'), @@ -433,18 +489,21 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL dragHandle: true }); - if (items.length) { - context.querySelector('.btnTogglePlaylist').classList.remove('hide'); - } else { - context.querySelector('.btnTogglePlaylist').classList.add('hide'); + var itemsContainer = context.querySelector('.playlist'); + let focusedItemPlaylistId = itemsContainer.querySelector('button:focus'); + itemsContainer.innerHTML = html; + if (focusedItemPlaylistId !== null) { + focusedItemPlaylistId = focusedItemPlaylistId.getAttribute('data-playlistitemid'); + const newFocusedItem = itemsContainer.querySelector(`button[data-playlistitemid="${focusedItemPlaylistId}"]`); + if (newFocusedItem !== null) { + newFocusedItem.focus(); + } } - var itemsContainer = context.querySelector('.playlist'); - itemsContainer.innerHTML = html; var playlistItemId = playbackManager.getCurrentPlaylistItemId(player); if (playlistItemId) { - var img = itemsContainer.querySelector('.listItem[data-playlistItemId="' + playlistItemId + '"] .listItemImage'); + var img = itemsContainer.querySelector(`.listItem[data-playlistItemId="${playlistItemId}"] .listItemImage`); if (img) { img.classList.remove('lazy'); @@ -453,9 +512,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } imageLoader.lazyChildren(itemsContainer); - context.querySelector('.playlist').classList.add('hide'); - context.querySelector('.contextMenu').classList.add('hide'); - context.querySelector('.btnSavePlaylist').classList.add('hide'); }); } @@ -465,9 +521,31 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL onStateChanged.call(player, e, state); } - function onRepeatModeChange(e) { - var player = this; - updateRepeatModeDisplay(playbackManager.getRepeatMode(player)); + function onRepeatModeChange() { + updateRepeatModeDisplay(playbackManager.getRepeatMode()); + } + + function onShuffleQueueModeChange(updateView = true) { + let shuffleMode = playbackManager.getQueueShuffleMode(this); + let context = dlg; + const cssClass = 'buttonActive'; + let shuffleButtons = context.querySelectorAll('.btnShuffleQueue'); + + for (let shuffleButton of shuffleButtons) { + switch (shuffleMode) { + case 'Shuffle': + shuffleButton.classList.add(cssClass); + break; + case 'Sorted': + default: + shuffleButton.classList.remove(cssClass); + break; + } + } + + if (updateView) { + onPlaylistUpdate(); + } } function onPlaylistUpdate(e) { @@ -476,14 +554,18 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function onPlaylistItemRemoved(e, info) { var context = dlg; - var playlistItemIds = info.playlistItemIds; + if (info !== undefined) { + var playlistItemIds = info.playlistItemIds; - for (var i = 0, length = playlistItemIds.length; i < length; i++) { - var listItem = context.querySelector('.listItem[data-playlistItemId="' + playlistItemIds[i] + '"]'); + for (var i = 0, length = playlistItemIds.length; i < length; i++) { + var listItem = context.querySelector('.listItem[data-playlistItemId="' + playlistItemIds[i] + '"]'); - if (listItem) { - listItem.parentNode.removeChild(listItem); + if (listItem) { + listItem.parentNode.removeChild(listItem); + } } + } else { + onPlaylistUpdate(); } } @@ -493,7 +575,6 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL if (!state.NextMediaType) { updatePlayerState(player, dlg, {}); - loadPlaylist(dlg); Emby.Page.back(); } } @@ -505,7 +586,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function onStateChanged(event, state) { var player = this; updatePlayerState(player, dlg, state); - loadPlaylist(dlg, player); + onPlaylistUpdate(); } function onTimeUpdate(e) { @@ -531,8 +612,10 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL events.off(player, 'playbackstart', onPlaybackStart); events.off(player, 'statechange', onStateChanged); events.off(player, 'repeatmodechange', onRepeatModeChange); - events.off(player, 'playlistitemremove', onPlaylistUpdate); + events.off(player, 'shufflequeuemodechange', onShuffleQueueModeChange); + events.off(player, 'playlistitemremove', onPlaylistItemRemoved); events.off(player, 'playlistitemmove', onPlaylistUpdate); + events.off(player, 'playlistitemadd', onPlaylistUpdate); events.off(player, 'playbackstop', onPlaybackStopped); events.off(player, 'volumechange', onVolumeChanged); events.off(player, 'pause', onPlayPauseStateChanged); @@ -551,8 +634,10 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL events.on(player, 'playbackstart', onPlaybackStart); events.on(player, 'statechange', onStateChanged); events.on(player, 'repeatmodechange', onRepeatModeChange); + events.on(player, 'shufflequeuemodechange', onShuffleQueueModeChange); events.on(player, 'playlistitemremove', onPlaylistItemRemoved); events.on(player, 'playlistitemmove', onPlaylistUpdate); + events.on(player, 'playlistitemadd', onPlaylistUpdate); events.on(player, 'playbackstop', onPlaybackStopped); events.on(player, 'volumechange', onVolumeChanged); events.on(player, 'pause', onPlayPauseStateChanged); @@ -568,7 +653,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function onBtnCommandClick() { if (currentPlayer) { if (this.classList.contains('repeatToggleButton')) { - toggleRepeat(currentPlayer); + toggleRepeat(); } else { playbackManager.sendCommand({ Name: this.getAttribute('data-command') @@ -603,6 +688,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL function bindEvents(context) { var btnCommand = context.querySelectorAll('.btnCommand'); + var positionSlider = context.querySelector('.nowPlayingPositionSlider'); for (var i = 0, length = btnCommand.length; i < length; i++) { btnCommand[i].addEventListener('click', onBtnCommandClick); @@ -650,12 +736,37 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL playbackManager.fastForward(currentPlayer); } }); - context.querySelector('.btnPreviousTrack').addEventListener('click', function () { + for (const shuffleButton of context.querySelectorAll('.btnShuffleQueue')) { + shuffleButton.addEventListener('click', function () { + if (currentPlayer) { + playbackManager.toggleQueueShuffleMode(currentPlayer); + } + }); + } + + context.querySelector('.btnPreviousTrack').addEventListener('click', function (e) { + if (currentPlayer) { + if (lastPlayerState.NowPlayingItem.MediaType === 'Audio' && (currentPlayer._currentTime >= 5 || !playbackManager.previousTrack(currentPlayer))) { + // Cancel this event if doubleclick is fired + if (e.detail > 1 && playbackManager.previousTrack(currentPlayer)) { + return; + } + playbackManager.seekPercent(0, currentPlayer); + // This is done automatically by playbackManager. However, setting this here gives instant visual feedback. + // TODO: Check why seekPercentage doesn't reflect the changes inmmediately, so we can remove this workaround. + positionSlider.value = 0; + } else { + playbackManager.previousTrack(currentPlayer); + } + } + }); + + context.querySelector('.btnPreviousTrack').addEventListener('dblclick', function () { if (currentPlayer) { playbackManager.previousTrack(currentPlayer); } }); - context.querySelector('.nowPlayingPositionSlider').addEventListener('change', function () { + positionSlider.addEventListener('change', function () { var value = this.value; if (currentPlayer) { @@ -664,7 +775,7 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } }); - context.querySelector('.nowPlayingPositionSlider').getBubbleText = function (value) { + positionSlider.getBubbleText = function (value) { var state = lastPlayerState; if (!state || !state.NowPlayingItem || !currentRuntimeTicks) { @@ -677,13 +788,10 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL return datetime.getDisplayRunningTime(ticks); }; - function setVolume() { - playbackManager.setVolume(this.value, currentPlayer); - } + context.querySelector('.nowPlayingVolumeSlider').addEventListener('input', (e) => { + playbackManager.setVolume(e.target.value, currentPlayer); + }); - context.querySelector('.nowPlayingVolumeSlider').addEventListener('change', setVolume); - context.querySelector('.nowPlayingVolumeSlider').addEventListener('mousemove', setVolume); - context.querySelector('.nowPlayingVolumeSlider').addEventListener('touchmove', setVolume); context.querySelector('.buttonMute').addEventListener('click', function () { playbackManager.toggleMute(currentPlayer); }); @@ -701,21 +809,19 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL if (context.querySelector('.playlist').classList.contains('hide')) { context.querySelector('.playlist').classList.remove('hide'); context.querySelector('.btnSavePlaylist').classList.remove('hide'); - context.querySelector('.contextMenu').classList.add('hide'); context.querySelector('.volumecontrol').classList.add('hide'); + if (layoutManager.mobile) { + context.querySelector('.playlistSectionButton').classList.remove('playlistSectionButtonTransparent'); + } } else { context.querySelector('.playlist').classList.add('hide'); context.querySelector('.btnSavePlaylist').classList.add('hide'); - context.querySelector('.volumecontrol').classList.remove('hide'); - } - }); - context.querySelector('.btnToggleContextMenu').addEventListener('click', function () { - if (context.querySelector('.contextMenu').classList.contains('hide')) { - context.querySelector('.contextMenu').classList.remove('hide'); - context.querySelector('.btnSavePlaylist').classList.add('hide'); - context.querySelector('.playlist').classList.add('hide'); - } else { - context.querySelector('.contextMenu').classList.add('hide'); + if (showMuteButton || showVolumeSlider) { + context.querySelector('.volumecontrol').classList.remove('hide'); + } + if (layoutManager.mobile) { + context.querySelector('.playlistSectionButton').classList.add('playlistSectionButtonTransparent'); + } } }); } @@ -764,16 +870,24 @@ define(['browser', 'datetime', 'backdrop', 'libraryBrowser', 'listView', 'imageL } function init(ownerView, context) { - let contextmenuHtml = ``; let volumecontrolHtml = '
'; volumecontrolHtml += ``; volumecontrolHtml += '
'; volumecontrolHtml += '
'; + let optionsSection = context.querySelector('.playlistSectionButton'); if (!layoutManager.mobile) { - context.querySelector('.nowPlayingSecondaryButtons').innerHTML += volumecontrolHtml; - context.querySelector('.playlistSectionButton').innerHTML += contextmenuHtml; + context.querySelector('.nowPlayingSecondaryButtons').insertAdjacentHTML('beforeend', volumecontrolHtml); + optionsSection.classList.remove('align-items-center', 'justify-content-center'); + optionsSection.classList.add('align-items-right', 'justify-content-flex-end'); + context.querySelector('.playlist').classList.remove('hide'); + context.querySelector('.btnSavePlaylist').classList.remove('hide'); + context.classList.add('padded-bottom'); } else { - context.querySelector('.playlistSectionButton').innerHTML += volumecontrolHtml + contextmenuHtml; + optionsSection.querySelector('.btnTogglePlaylist').insertAdjacentHTML('afterend', volumecontrolHtml); + optionsSection.classList.add('playlistSectionButtonTransparent'); + context.querySelector('.btnTogglePlaylist').classList.remove('hide'); + context.querySelector('.playlistSectionButton').classList.remove('justify-content-center'); + context.querySelector('.playlistSectionButton').classList.add('justify-content-space-between'); } bindEvents(context); diff --git a/src/components/search/searchresults.js b/src/components/search/searchresults.js index 0044763eb4..e16b6a1cd4 100644 --- a/src/components/search/searchresults.js +++ b/src/components/search/searchresults.js @@ -474,7 +474,7 @@ import 'emby-button'; showTitle: true, overlayText: false, centerText: true, - action: 'play' + overlayPlayButton: true }); diff --git a/src/components/slideshow/slideshow.js b/src/components/slideshow/slideshow.js index b027c203a5..f7026a007e 100644 --- a/src/components/slideshow/slideshow.js +++ b/src/components/slideshow/slideshow.js @@ -224,6 +224,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f }); inputManager.on(window, onInputCommand); + /* eslint-disable-next-line compat/compat */ document.addEventListener((window.PointerEvent ? 'pointermove' : 'mousemove'), onPointerMove); dialog.addEventListener('close', onDialogClosed); @@ -489,6 +490,7 @@ define(['dialogHelper', 'inputManager', 'connectionManager', 'layoutManager', 'f } inputManager.off(window, onInputCommand); + /* eslint-disable-next-line compat/compat */ document.removeEventListener((window.PointerEvent ? 'pointermove' : 'mousemove'), onPointerMove); // Shows page scrollbar document.body.classList.remove('hide-scroll'); diff --git a/src/components/subtitlesync/subtitlesync.css b/src/components/subtitlesync/subtitlesync.css index 2ff8a3e905..a63d9915bb 100644 --- a/src/components/subtitlesync/subtitlesync.css +++ b/src/components/subtitlesync/subtitlesync.css @@ -1,12 +1,18 @@ +.subtitleSync { + position: absolute; + width: 100%; +} + .subtitleSyncContainer { width: 40%; - margin-left: 30%; - margin-right: 30%; + min-width: 18em; + margin-left: auto; + margin-right: auto; height: 4.2em; background: rgba(28, 28, 28, 0.8); border-radius: 0.3em; color: #fff; - position: absolute; + position: relative; } .subtitleSync-closeButton { diff --git a/src/components/subtitlesync/subtitlesync.js b/src/components/subtitlesync/subtitlesync.js index fb986ec348..a3e60593e8 100644 --- a/src/components/subtitlesync/subtitlesync.js +++ b/src/components/subtitlesync/subtitlesync.js @@ -65,6 +65,9 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html', event.preventDefault(); } } + + // FIXME: TV layout will require special handling for navigation keys. But now field is not focusable + event.stopPropagation(); }); subtitleSyncTextField.blur = function() { @@ -87,14 +90,6 @@ define(['playbackManager', 'layoutManager', 'text!./subtitlesync.template.html', getOffsetFromPercentage(this.value)); }); - subtitleSyncSlider.addEventListener('touchmove', function () { - // set new offset - playbackManager.setSubtitleOffset(getOffsetFromPercentage(this.value), player); - // synchronize with textField value - subtitleSyncTextField.updateOffset( - getOffsetFromPercentage(this.value)); - }); - subtitleSyncSlider.getBubbleHtml = function (value) { var newOffset = getOffsetFromPercentage(value); return '

' + diff --git a/src/components/subtitlesync/subtitlesync.template.html b/src/components/subtitlesync/subtitlesync.template.html index 4ca039aa03..fe202ebf60 100644 --- a/src/components/subtitlesync/subtitlesync.template.html +++ b/src/components/subtitlesync/subtitlesync.template.html @@ -1,7 +1,9 @@ -
- -
0s
-
- +
+
+ +
0s
+
+ +
diff --git a/src/components/syncPlay/groupSelectionMenu.js b/src/components/syncPlay/groupSelectionMenu.js index 067100ad73..360aa0b0c2 100644 --- a/src/components/syncPlay/groupSelectionMenu.js +++ b/src/components/syncPlay/groupSelectionMenu.js @@ -37,7 +37,7 @@ function showNewJoinGroupSelection (button, user, apiClient) { console.debug('No item is currently playing.'); } - apiClient.sendSyncPlayCommand(sessionId, 'ListGroups').then(function (response) { + apiClient.getSyncPlayGroups().then(function (response) { response.json().then(function (groups) { var menuItems = groups.map(function (group) { return { @@ -83,9 +83,9 @@ function showNewJoinGroupSelection (button, user, apiClient) { actionsheet.show(menuOptions).then(function (id) { if (id == 'new-group') { - apiClient.sendSyncPlayCommand(sessionId, 'NewGroup'); - } else { - apiClient.sendSyncPlayCommand(sessionId, 'JoinGroup', { + apiClient.createSyncPlayGroup(); + } else if (id) { + apiClient.joinSyncPlayGroup({ GroupId: id, PlayingItemId: playingItemId }); @@ -140,7 +140,7 @@ function showLeaveGroupSelection (button, user, apiClient) { actionsheet.show(menuOptions).then(function (id) { if (id == 'leave-group') { - apiClient.sendSyncPlayCommand(sessionId, 'LeaveGroup'); + apiClient.leaveSyncPlayGroup(); } }).catch((error) => { console.error('SyncPlay: unexpected error showing group menu:', error); diff --git a/src/components/syncPlay/syncPlayManager.js b/src/components/syncPlay/syncPlayManager.js index 6116884d7c..c8660b2bc4 100644 --- a/src/components/syncPlay/syncPlayManager.js +++ b/src/components/syncPlay/syncPlayManager.js @@ -139,7 +139,7 @@ class SyncPlayManager { return; } - apiClient.sendSyncPlayCommand(sessionId, 'UpdatePing', { + apiClient.sendSyncPlayPing({ Ping: ping }); } @@ -212,6 +212,7 @@ class SyncPlayManager { if (!this.lastPlaybackWaiting) { this.lastPlaybackWaiting = new Date(); } + events.trigger(this, 'waiting'); } @@ -288,6 +289,7 @@ class SyncPlayManager { player.setPlaybackRate(this.localPlayerPlaybackRate); this.localPlayerPlaybackRate = 1.0; } + this.currentPlayer = null; this.playbackRateSupported = false; } @@ -433,6 +435,7 @@ class SyncPlayManager { }); return; } + // Get playing item id let playingItemId; try { @@ -447,7 +450,7 @@ class SyncPlayManager { if (!success) { console.warning('Error reporting playback state to server. Joining group will fail.'); } - apiClient.sendSyncPlayCommand(sessionId, 'JoinGroup', { + apiClient.joinSyncPlayGroup({ GroupId: groupId, PlayingItemId: playingItemId }); @@ -619,6 +622,7 @@ class SyncPlayManager { if (this.currentPlayer) { this.currentPlayer.setPlaybackRate(1); } + this.clearSyncIcon(); } @@ -658,8 +662,7 @@ class SyncPlayManager { */ playRequest (player) { var apiClient = connectionManager.currentApiClient(); - var sessionId = getActivePlayerId(); - apiClient.sendSyncPlayCommand(sessionId, 'PlayRequest'); + apiClient.requestSyncPlayStart(); } /** @@ -667,8 +670,7 @@ class SyncPlayManager { */ pauseRequest (player) { var apiClient = connectionManager.currentApiClient(); - var sessionId = getActivePlayerId(); - apiClient.sendSyncPlayCommand(sessionId, 'PauseRequest'); + apiClient.requestSyncPlayPause(); // Pause locally as well, to give the user some little control playbackManager._localUnpause(player); } @@ -678,8 +680,7 @@ class SyncPlayManager { */ seekRequest (PositionTicks, player) { var apiClient = connectionManager.currentApiClient(); - var sessionId = getActivePlayerId(); - apiClient.sendSyncPlayCommand(sessionId, 'SeekRequest', { + apiClient.requestSyncPlaySeek({ PositionTicks: PositionTicks }); } diff --git a/src/controllers/auth/login.js b/src/controllers/auth/login.js index fb16413ae7..034e4e157d 100644 --- a/src/controllers/auth/login.js +++ b/src/controllers/auth/login.js @@ -1,3 +1,4 @@ +<<<<<<< HEAD import appHost from 'apphost'; import appSettings from 'appSettings'; import dom from 'dom'; @@ -8,6 +9,10 @@ import browser from 'browser'; import globalize from 'globalize'; import 'cardStyle'; import 'emby-checkbox'; +======= +define(['apphost', 'appSettings', 'dom', 'connectionManager', 'loading', 'layoutManager', 'libraryMenu', 'browser', 'globalize', 'cardStyle', 'emby-checkbox'], function (appHost, appSettings, dom, connectionManager, loading, layoutManager, libraryMenu, browser, globalize) { + 'use strict'; +>>>>>>> upstream/master /* eslint-disable indent */ @@ -16,6 +21,7 @@ import 'emby-checkbox'; function authenticateUserByName(page, apiClient, username, password) { loading.show(); apiClient.authenticateUserByName(username, password).then(function (result) { +<<<<<<< HEAD const user = result.User; const serverId = getParameterByName('serverid'); let newUrl; @@ -26,9 +32,13 @@ import 'emby-checkbox'; newUrl = 'home.html'; } +======= + var user = result.User; +>>>>>>> upstream/master loading.hide(); + Dashboard.onServerChanged(user.Id, result.AccessToken, apiClient); - Dashboard.navigate(newUrl); + Dashboard.navigate('home.html'); }, function (response) { page.querySelector('#txtManualName').value = ''; page.querySelector('#txtManualPassword').value = ''; @@ -204,6 +214,7 @@ import 'emby-checkbox'; }); view.addEventListener('viewshow', function (e) { loading.show(); + libraryMenu.setTransparentMenu(true); if (!appHost.supports('multiserver')) { view.querySelector('.btnSelectServer').classList.add('hide'); @@ -225,6 +236,14 @@ import 'emby-checkbox'; view.querySelector('.disclaimer').textContent = options.LoginDisclaimer || ''; }); }); +<<<<<<< HEAD } /* eslint-enable indent */ +======= + view.addEventListener('viewhide', function (e) { + libraryMenu.setTransparentMenu(false); + }); + }; +}); +>>>>>>> upstream/master diff --git a/src/controllers/auth/selectserver.js b/src/controllers/auth/selectserver.js index 6847e79435..1184590f11 100644 --- a/src/controllers/auth/selectserver.js +++ b/src/controllers/auth/selectserver.js @@ -1,3 +1,4 @@ +<<<<<<< HEAD import loading from 'loading'; import appRouter from 'appRouter'; import layoutManager from 'layoutManager'; @@ -19,6 +20,12 @@ import 'emby-button'; /* eslint-disable indent */ const enableFocusTransform = !browser.slow && !browser.edge; +======= +define(['loading', 'appRouter', 'layoutManager', 'libraryMenu', 'appSettings', 'apphost', 'focusManager', 'connectionManager', 'globalize', 'actionsheet', 'dom', 'browser', 'material-icons', 'flexStyles', 'emby-scroller', 'emby-itemscontainer', 'cardStyle', 'emby-button'], function (loading, appRouter, layoutManager, libraryMenu, appSettings, appHost, focusManager, connectionManager, globalize, actionSheet, dom, browser) { + 'use strict'; + + var enableFocusTransform = !browser.slow && !browser.edge; +>>>>>>> upstream/master function renderSelectServerItems(view, servers) { const items = servers.map(function (server) { @@ -200,6 +207,7 @@ import 'emby-button'; view.addEventListener('viewshow', function (e) { const isRestored = e.detail.isRestored; appRouter.setTitle(null); + libraryMenu.setTransparentMenu(true); if (!isRestored) { loadServers(); diff --git a/src/controllers/dashboard/dashboard.js b/src/controllers/dashboard/dashboard.js index 7aa706840d..41abb8d915 100644 --- a/src/controllers/dashboard/dashboard.js +++ b/src/controllers/dashboard/dashboard.js @@ -189,6 +189,7 @@ import 'emby-itemscontainer'; function reloadSystemInfo(view, apiClient) { apiClient.getSystemInfo().then(function (systemInfo) { view.querySelector('#serverName').innerHTML = globalize.translate('DashboardServerName', systemInfo.ServerName); +<<<<<<< HEAD let localizedVersion = globalize.translate('DashboardVersionNumber', systemInfo.Version); if (systemInfo.SystemUpdateLevel !== 'Release') { @@ -196,6 +197,9 @@ import 'emby-itemscontainer'; } view.querySelector('#versionNumber').innerHTML = localizedVersion; +======= + view.querySelector('#versionNumber').innerHTML = globalize.translate('DashboardVersionNumber', systemInfo.Version); +>>>>>>> upstream/master view.querySelector('#operatingSystem').innerHTML = globalize.translate('DashboardOperatingSystem', systemInfo.OperatingSystem); view.querySelector('#architecture').innerHTML = globalize.translate('DashboardArchitecture', systemInfo.SystemArchitecture); diff --git a/src/controllers/dashboard/mediaLibrary.js b/src/controllers/dashboard/mediaLibrary.js index 0b01a9488f..b958e69d22 100644 --- a/src/controllers/dashboard/mediaLibrary.js +++ b/src/controllers/dashboard/mediaLibrary.js @@ -170,7 +170,7 @@ import 'emby-itemrefreshindicator'; showType: false, showLocations: false, showMenu: false, - showNameWithIcon: true + showNameWithIcon: false }); for (let i = 0; i < virtualFolders.length; i++) { @@ -185,7 +185,7 @@ import 'emby-itemrefreshindicator'; $('.btnCardMenu', divVirtualFolders).on('click', function () { showCardMenu(page, this, virtualFolders); }); - divVirtualFolders.querySelector('.addLibrary').addEventListener('click', function () { + divVirtualFolders.querySelector('#addLibrary').addEventListener('click', function () { addVirtualFolder(page); }); $('.editLibrary', divVirtualFolders).on('click', function () { @@ -256,7 +256,12 @@ import 'emby-itemrefreshindicator'; style += 'min-width:33.3%;'; } - html += '
'; + if (virtualFolder.Locations.length == 0) { + html += '
'; + } else { + html += '
'; + } + html += '
'; html += '
'; html += '
'; diff --git a/src/controllers/dashboard/users/useredit.js b/src/controllers/dashboard/users/useredit.js index ba14cbe1b2..c67be6363e 100644 --- a/src/controllers/dashboard/users/useredit.js +++ b/src/controllers/dashboard/users/useredit.js @@ -105,7 +105,9 @@ import globalize from 'globalize'; $('#chkEnableSharing', page).prop('checked', user.Policy.EnablePublicSharing); $('#txtRemoteClientBitrateLimit', page).val(user.Policy.RemoteClientBitrateLimit / 1e6 || ''); $('#txtLoginAttemptsBeforeLockout', page).val(user.Policy.LoginAttemptsBeforeLockout || '0'); - $('#selectSyncPlayAccess').val(user.Policy.SyncPlayAccess); + if (ApiClient.isMinServerVersion('10.6.0')) { + $('#selectSyncPlayAccess').val(user.Policy.SyncPlayAccess); + } loading.hide(); } @@ -147,7 +149,9 @@ import globalize from 'globalize'; }).map(function (c) { return c.getAttribute('data-id'); }); - user.Policy.SyncPlayAccess = page.querySelector('#selectSyncPlayAccess').value; + if (ApiClient.isMinServerVersion('10.6.0')) { + user.Policy.SyncPlayAccess = page.querySelector('#selectSyncPlayAccess').value; + } ApiClient.updateUser(user).then(function () { ApiClient.updateUserPolicy(user.Id, user.Policy).then(function () { onSaveComplete(page, user); diff --git a/src/itemdetails.html b/src/controllers/itemDetails/index.html similarity index 73% rename from src/itemdetails.html rename to src/controllers/itemDetails/index.html index 44ca561d40..ddb7be3aec 100644 --- a/src/itemdetails.html +++ b/src/controllers/itemDetails/index.html @@ -1,8 +1,5 @@ -
+
-
@@ -15,94 +12,75 @@
- - - - - - - - - - - - - -
@@ -110,7 +88,7 @@
-
+
@@ -124,6 +102,11 @@
+ +
+
+
+
@@ -164,15 +147,15 @@
-

${HeaderSchedule}

-
+

${HeaderSchedule}

+
-
+
-

${HeaderNextUp}

-
+

${HeaderNextUp}

+
@@ -180,64 +163,64 @@
-

+

-
+
-

${HeaderAdditionalParts}

-
+

${HeaderAdditionalParts}

+
-
-

+
+

-
-

+
+

-

${HeaderCastCrew}

+

${HeaderCastCrew}

-

${HeaderUpcomingOnTV}

-
+

${HeaderUpcomingOnTV}

+
-

${HeaderSpecialFeatures}

-
+

${HeaderSpecialFeatures}

+
-

${HeaderMusicVideos}

-
+

${HeaderMusicVideos}

+
-
-

${HeaderScenes}

+
+

${HeaderScenes}

-
-

${HeaderMoreLikeThis}

+
+

${HeaderMoreLikeThis}

diff --git a/src/controllers/itemDetails.js b/src/controllers/itemDetails/index.js similarity index 83% rename from src/controllers/itemDetails.js rename to src/controllers/itemDetails/index.js index d7c0c74ee2..168fb75e51 100644 --- a/src/controllers/itemDetails.js +++ b/src/controllers/itemDetails/index.js @@ -28,15 +28,11 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function hideAll(page, className, show) { - var i; - var length; - var elems = page.querySelectorAll('.' + className); - - for (i = 0, length = elems.length; i < length; i++) { + for (const elem of page.querySelectorAll('.' + className)) { if (show) { - elems[i].classList.remove('hide'); + elem.classList.remove('hide'); } else { - elems[i].classList.add('hide'); + elem.classList.add('hide'); } } } @@ -51,17 +47,19 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti positionTo: button, cancelTimer: false, record: false, - deleteItem: true === item.IsFolder, + deleteItem: item.CanDelete === true, shuffle: false, instantMix: false, user: user, share: true }; + return options; } function getProgramScheduleHtml(items) { var html = ''; + html += '
'; html += listView.getListViewHtml({ items: items, @@ -75,7 +73,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti moreButton: false, recordButton: false }); - return html += '
'; + + html += '
'; + + return html; } function renderSeriesTimerSchedule(page, apiClient, seriesTimerId) { @@ -143,9 +144,12 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti var mediaSources = item.MediaSources; instance._currentPlaybackMediaSources = mediaSources; + page.querySelector('.trackSelections').classList.remove('hide'); select.setLabel(globalize.translate('LabelVersion')); + var currentValue = select.value; + var selectedId = mediaSources[0].Id; select.innerHTML = mediaSources.map(function (v) { var selected = v.Id === selectedId ? ' selected' : ''; @@ -163,7 +167,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti renderAudioSelections(page, mediaSources); renderSubtitleSelections(page, mediaSources); } - } function renderVideoSelections(page, mediaSources) { @@ -171,9 +174,11 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti var mediaSource = mediaSources.filter(function (m) { return m.Id === mediaSourceId; })[0]; + var tracks = mediaSource.MediaStreams.filter(function (m) { - return 'Video' === m.Type; + return m.Type === 'Video'; }); + var select = page.querySelector('.selectVideo'); select.setLabel(globalize.translate('LabelVideo')); var selectedId = tracks.length ? tracks[0].Index : -1; @@ -242,12 +247,24 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti select.setLabel(globalize.translate('LabelSubtitles')); var selectedId = null == mediaSource.DefaultSubtitleStreamIndex ? -1 : mediaSource.DefaultSubtitleStreamIndex; - if (tracks.length) { + var videoTracks = mediaSource.MediaStreams.filter(function (m) { + return 'Video' === m.Type; + }); + + // This only makes sense on Video items + if (videoTracks.length) { var selected = -1 === selectedId ? ' selected' : ''; select.innerHTML = '' + tracks.map(function (v) { selected = v.Index === selectedId ? ' selected' : ''; return ''; }).join(''); + + if (tracks.length > 0) { + select.removeAttribute('disabled'); + } else { + select.setAttribute('disabled', 'disabled'); + } + page.querySelector('.selectSubtitlesContainer').classList.remove('hide'); } else { select.innerHTML = ''; @@ -278,7 +295,15 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti var enableShuffle = item.IsFolder || -1 !== ['MusicAlbum', 'MusicGenre', 'MusicArtist'].indexOf(item.Type); hideAll(page, 'btnShuffle', enableShuffle); canPlay = true; - hideAll(page, 'btnResume', item.UserData && item.UserData.PlaybackPositionTicks > 0); + + const isResumable = item.UserData && item.UserData.PlaybackPositionTicks > 0; + hideAll(page, 'btnResume', isResumable); + + if (isResumable) { + for (const elem of page.querySelectorAll('.btnPlay')) { + elem.querySelector('.detailButton-icon').classList.replace('play_arrow', 'replay'); + } + } } else { hideAll(page, 'btnPlay'); hideAll(page, 'btnResume'); @@ -324,8 +349,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti function getArtistLinksHtml(artists, serverId, context) { var html = []; - for (var i = 0, length = artists.length; i < length; i++) { - var artist = artists[i]; + for (const artist of artists) { var href = appRouter.getRouteUrl(artist, { context: context, itemType: 'MusicArtist', @@ -333,10 +357,18 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti }); html.push('' + artist.Name + ''); } + html = html.join(' / '); - return html = html.join(' / '); + return html; } - function renderName(item, container, isStatic, context) { + + /** + * Renders the item's name block + * @param {Object} item - Item used to render the name. + * @param {HTMLDivElement} container - Container to render the information into. + * @param {Object} context - Application context. + */ + function renderName(item, container, context) { var parentRoute; var parentNameHtml = []; var parentNameLast = false; @@ -410,16 +442,12 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti if (parentNameLast) { // Music if (layoutManager.mobile) { - html = '

' + parentNameHtml.join('
') + '

'; + html = '

' + parentNameHtml.join('
') + '

'; } else { - html = '

' + parentNameHtml.join(' - ') + '

'; + html = '

' + parentNameHtml.join(' - ') + '

'; } } else { - if (layoutManager.mobile) { - html = '

' + parentNameHtml.join('
') + '

'; - } else { - html = '

' + tvShowHtml + '

'; - } + html = '

' + tvShowHtml + '

'; } } @@ -428,17 +456,19 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti }); if (html && !parentNameLast) { - if (!layoutManager.mobile && tvSeasonHtml) { - html += '

' + tvSeasonHtml + ' - ' + name + '

'; + if (tvSeasonHtml) { + html += '

' + tvSeasonHtml + ' - ' + name + '

'; } else { - html += '

' + name + '

'; + html += '

' + name + '

'; } + } else if (item.OriginalTitle && item.OriginalTitle != item.Name) { + html = '

' + name + '

' + html; } else { - html = '

' + name + '

' + html; + html = '

' + name + '

' + html; } if (item.OriginalTitle && item.OriginalTitle != item.Name) { - html += '

' + item.OriginalTitle + '

'; + html += '

' + item.OriginalTitle + '

'; } container.innerHTML = html; @@ -470,43 +500,18 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti var imgUrl; var hasbackdrop = false; var itemBackdropElement = page.querySelector('#itemBackdrop'); - var usePrimaryImage = item.MediaType === 'Video' && item.Type !== 'Movie' && item.Type !== 'Trailer' || - item.MediaType && item.MediaType !== 'Video' || - item.Type === 'MusicAlbum' || - item.Type === 'Person'; if (!layoutManager.mobile && !userSettings.detailsBanner()) { return false; } - if ('Program' === item.Type && item.ImageTags && item.ImageTags.Thumb) { - imgUrl = apiClient.getScaledImageUrl(item.Id, { - type: 'Thumb', - maxWidth: dom.getScreenWidth(), - index: 0, - tag: item.ImageTags.Thumb - }); - page.classList.remove('noBackdrop'); - imageLoader.lazyImage(itemBackdropElement, imgUrl); - hasbackdrop = true; - } else if (usePrimaryImage && item.ImageTags && item.ImageTags.Primary) { - imgUrl = apiClient.getScaledImageUrl(item.Id, { - type: 'Primary', - maxWidth: dom.getScreenWidth(), - index: 0, - tag: item.ImageTags.Primary - }); - page.classList.remove('noBackdrop'); - imageLoader.lazyImage(itemBackdropElement, imgUrl); - hasbackdrop = true; - } else if (item.BackdropImageTags && item.BackdropImageTags.length) { + if (item.BackdropImageTags && item.BackdropImageTags.length) { imgUrl = apiClient.getScaledImageUrl(item.Id, { type: 'Backdrop', maxWidth: dom.getScreenWidth(), index: 0, tag: item.BackdropImageTags[0] }); - page.classList.remove('noBackdrop'); imageLoader.lazyImage(itemBackdropElement, imgUrl); hasbackdrop = true; } else if (item.ParentBackdropItemId && item.ParentBackdropImageTags && item.ParentBackdropImageTags.length) { @@ -516,50 +521,35 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti index: 0, tag: item.ParentBackdropImageTags[0] }); - page.classList.remove('noBackdrop'); - imageLoader.lazyImage(itemBackdropElement, imgUrl); - hasbackdrop = true; - } else if (item.ImageTags && item.ImageTags.Thumb) { - imgUrl = apiClient.getScaledImageUrl(item.Id, { - type: 'Thumb', - maxWidth: dom.getScreenWidth(), - index: 0, - tag: item.ImageTags.Thumb - }); - page.classList.remove('noBackdrop'); imageLoader.lazyImage(itemBackdropElement, imgUrl); hasbackdrop = true; } else { itemBackdropElement.style.backgroundImage = ''; } - if ('Person' === item.Type) { - // FIXME: This hides the backdrop on all persons to fix a margin issue. Ideally, a proper fix should be made. - page.classList.add('noBackdrop'); - itemBackdropElement.classList.add('personBackdrop'); - } else { - itemBackdropElement.classList.remove('personBackdrop'); - } - return hasbackdrop; } function reloadFromItem(instance, page, params, item, user) { - var context = params.context; - page.querySelector('.detailPagePrimaryContainer').classList.add('detailSticky'); + const apiClient = connectionManager.getApiClient(item.ServerId); - renderName(item, page.querySelector('.nameContainer'), false, context); - var apiClient = connectionManager.getApiClient(item.ServerId); - renderSeriesTimerEditor(page, item, apiClient, user); - renderTimerEditor(page, item, apiClient, user); - renderImage(page, item, apiClient, user); - renderLogo(page, item, apiClient); Emby.Page.setTitle(''); - setInitialCollapsibleState(page, item, apiClient, context, user); - renderDetails(page, item, apiClient, context); - renderTrackSelections(page, instance, item); + + // Start rendering the artwork first + renderImage(page, item); + renderLogo(page, item, apiClient); renderBackdrop(item); renderDetailPageBackdrop(page, item, apiClient); + + // Render the main information for the item + page.querySelector('.detailPagePrimaryContainer').classList.add('detailRibbon'); + renderName(item, page.querySelector('.nameContainer'), params.context); + renderDetails(page, item, apiClient, params.context); + renderTrackSelections(page, instance, item); + + renderSeriesTimerEditor(page, item, apiClient, user); + renderTimerEditor(page, item, apiClient, user); + setInitialCollapsibleState(page, item, apiClient, params.context, user); var canPlay = reloadPlayButtons(page, item); if ((item.LocalTrailerCount || item.RemoteTrailers && item.RemoteTrailers.length) && -1 !== playbackManager.getSupportedCommands().indexOf('PlayTrailers')) { @@ -570,12 +560,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti setTrailerButtonVisibility(page, item); - if (item.CanDelete && !item.IsFolder) { - hideAll(page, 'btnDeleteItem', true); - } else { - hideAll(page, 'btnDeleteItem'); - } - if ('Program' !== item.Type || canPlay) { hideAll(page, 'mainDetailButtons', true); } else { @@ -667,18 +651,15 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderLogo(page, item, apiClient) { - var url = logoImageUrl(item, apiClient, { - maxWidth: 400 - }); var detailLogo = page.querySelector('.detailLogo'); + var url = logoImageUrl(item, apiClient, {}); + if (!layoutManager.mobile && !userSettings.enableBackdrops()) { detailLogo.classList.add('hide'); } else if (url) { detailLogo.classList.remove('hide'); - detailLogo.classList.add('lazy'); - detailLogo.setAttribute('data-src', url); - imageLoader.lazyImage(detailLogo); + imageLoader.setLazyImage(detailLogo, url); } else { detailLogo.classList.add('hide'); } @@ -704,172 +685,59 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } } - function renderLinks(linksElem, item) { - var html = []; + function renderLinks(page, item) { + var externalLinksElem = page.querySelector('.itemExternalLinks'); var links = []; if (!layoutManager.tv && item.HomePageUrl) { - links.push('' + globalize.translate('ButtonWebsite') + ''); + links.push(`${globalize.translate('ButtonWebsite')}`); } + if (item.ExternalUrls) { - for (var i = 0, length = item.ExternalUrls.length; i < length; i++) { - var url = item.ExternalUrls[i]; - links.push('' + url.Name + ''); + for (const url of item.ExternalUrls) { + links.push(`${url.Name}`); } } + var html = []; if (links.length) { html.push(links.join(', ')); } - linksElem.innerHTML = html.join(', '); + externalLinksElem.innerHTML = html.join(', '); if (html.length) { - linksElem.classList.remove('hide'); + externalLinksElem.classList.remove('hide'); } else { - linksElem.classList.add('hide'); + externalLinksElem.classList.add('hide'); } } - function renderDetailImage(page, elem, item, apiClient, editable, imageLoader, indicators) { - if ('SeriesTimer' === item.Type || 'Program' === item.Type) { - editable = false; - } + function renderDetailImage(elem, item, imageLoader) { + const itemArray = []; + itemArray.push(item); + const cardHtml = cardBuilder.getCardsHtml(itemArray, { + shape: 'auto', + showTitle: false, + centerText: true, + overlayText: false, + transition: false, + disableIndicators: true, + disableHoverMenu: true, + overlayPlayButton: true, + width: dom.getWindowSize().innerWidth * 0.5 + }); - elem.classList.add('detailimg-hidemobile'); - - var imageTags = item.ImageTags || {}; - - if (item.PrimaryImageTag) { - imageTags.Primary = item.PrimaryImageTag; - } - - var url; - var html = ''; - var shape = 'portrait'; - var detectRatio = false; - - /* In the following section, getScreenWidth() is multiplied by 0.5 as the posters - are 25vw and we need double the resolution to counter Skia's scaling. */ - // TODO: Find a reliable way to get the poster width - if (imageTags.Primary) { - url = apiClient.getScaledImageUrl(item.Id, { - type: 'Primary', - maxWidth: Math.round(dom.getScreenWidth() * 0.5), - tag: item.ImageTags.Primary - }); - detectRatio = true; - } else if (item.BackdropImageTags && item.BackdropImageTags.length) { - url = apiClient.getScaledImageUrl(item.Id, { - type: 'Backdrop', - maxWidth: Math.round(dom.getScreenWidth() * 0.5), - tag: item.BackdropImageTags[0] - }); - shape = 'thumb'; - } else if (imageTags.Thumb) { - url = apiClient.getScaledImageUrl(item.Id, { - type: 'Thumb', - maxWidth: Math.round(dom.getScreenWidth() * 0.5), - tag: item.ImageTags.Thumb - }); - shape = 'thumb'; - } else if (imageTags.Disc) { - url = apiClient.getScaledImageUrl(item.Id, { - type: 'Disc', - maxWidth: Math.round(dom.getScreenWidth() * 0.5), - tag: item.ImageTags.Disc - }); - shape = 'square'; - } else if (item.AlbumId && item.AlbumPrimaryImageTag) { - url = apiClient.getScaledImageUrl(item.AlbumId, { - type: 'Primary', - maxWidth: Math.round(dom.getScreenWidth() * 0.5), - tag: item.AlbumPrimaryImageTag - }); - shape = 'square'; - } else if (item.SeriesId && item.SeriesPrimaryImageTag) { - url = apiClient.getScaledImageUrl(item.SeriesId, { - type: 'Primary', - maxWidth: Math.round(dom.getScreenWidth() * 0.5), - tag: item.SeriesPrimaryImageTag - }); - } else if (item.ParentPrimaryImageItemId && item.ParentPrimaryImageTag) { - url = apiClient.getScaledImageUrl(item.ParentPrimaryImageItemId, { - type: 'Primary', - maxWidth: Math.round(dom.getScreenWidth() * 0.5), - tag: item.ParentPrimaryImageTag - }); - } - - if (editable && url === undefined) { - html += ""; - } else if (!editable && url === undefined) { - html += "'; - } - - var progressHtml = item.IsFolder || !item.UserData ? '' : indicators.getProgressBarHtml(item); - html += '
'; - - if (progressHtml) { - html += progressHtml; - } - - html += '
'; - elem.innerHTML = html; - - if (detectRatio && item.PrimaryImageAspectRatio) { - if (item.PrimaryImageAspectRatio >= 1.48) { - shape = 'thumb'; - } else if (item.PrimaryImageAspectRatio >= 0.85 && item.PrimaryImageAspectRatio <= 1.34) { - shape = 'square'; - } - } - - if ('thumb' == shape) { - elem.classList.add('thumbDetailImageContainer'); - elem.classList.remove('portraitDetailImageContainer'); - elem.classList.remove('squareDetailImageContainer'); - } else if ('square' == shape) { - elem.classList.remove('thumbDetailImageContainer'); - elem.classList.remove('portraitDetailImageContainer'); - elem.classList.add('squareDetailImageContainer'); - } else { - elem.classList.remove('thumbDetailImageContainer'); - elem.classList.add('portraitDetailImageContainer'); - elem.classList.remove('squareDetailImageContainer'); - } - - if (url) { - imageLoader.lazyImage(elem.querySelector('img'), url); - } + elem.innerHTML = cardHtml; + imageLoader.lazyChildren(elem); } - function renderImage(page, item, apiClient, user) { + function renderImage(page, item) { renderDetailImage( - page, page.querySelector('.detailImageContainer'), item, - apiClient, - user.Policy.IsAdministrator && 'Photo' != item.MediaType, - imageLoader, - indicators + imageLoader ); } @@ -985,54 +853,41 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } } - function renderOverview(elems, item) { - for (var i = 0, length = elems.length; i < length; i++) { - var elem = elems[i]; + function renderOverview(page, item) { + for (const overviewElemnt of page.querySelectorAll('.overview')) { var overview = item.Overview || ''; if (overview) { - elem.innerHTML = overview; - elem.classList.remove('hide'); - elem.classList.add('detail-clamp-text'); + overviewElemnt.innerHTML = overview; + overviewElemnt.classList.remove('hide'); + overviewElemnt.classList.add('detail-clamp-text'); // Grab the sibling element to control the expand state - var expandButton = elem.parentElement.querySelector('.overview-expand'); + var expandButton = overviewElemnt.parentElement.querySelector('.overview-expand'); // Detect if we have overflow of text. Based on this StackOverflow answer // https://stackoverflow.com/a/35157976 - if (Math.abs(elem.scrollHeight - elem.offsetHeight) > 2) { + if (Math.abs(overviewElemnt.scrollHeight - overviewElemnt.offsetHeight) > 2) { expandButton.classList.remove('hide'); } else { expandButton.classList.add('hide'); } - expandButton.addEventListener('click', toggleLineClamp.bind(null, elem)); + expandButton.addEventListener('click', toggleLineClamp.bind(null, overviewElemnt)); - var anchors = elem.querySelectorAll('a'); - - for (var j = 0, length2 = anchors.length; j < length2; j++) { - anchors[j].setAttribute('target', '_blank'); + for (const anchor of overviewElemnt.querySelectorAll('a')) { + anchor.setAttribute('target', '_blank'); } } else { - elem.innerHTML = ''; - elem.classList.add('hide'); + overviewElemnt.innerHTML = ''; + overviewElemnt.classList.add('hide'); } } } - function renderGenres(page, item, context) { - context = context || inferContext(item); - var type; + function renderGenres(page, item, context = inferContext(item)) { var genres = item.GenreItems || []; - - switch (context) { - case 'music': - type = 'MusicGenre'; - break; - - default: - type = 'Genre'; - } + var type = context === 'music' ? 'MusicGenre' : 'Genre'; var html = genres.map(function (p) { return '' + p.Name + ''; + }) + '">' + person.Name + ''; + }).join(', '); + + var writersLabel = page.querySelector('.writersLabel'); + writersLabel.innerHTML = globalize.translate(writers.length > 1 ? 'Writers' : 'Writer'); + var writersValue = page.querySelector('.writers'); + writersValue.innerHTML = html; + + var writersGroup = page.querySelector('.writersGroup'); + if (writers.length) { + writersGroup.classList.remove('hide'); + } else { + writersGroup.classList.add('hide'); + } + } + + function renderDirector(page, item, context) { + var directors = (item.People || []).filter(function (person) { + return person.Type === 'Director'; + }); + + var html = directors.map(function (person) { + return '' + person.Name + ''; }).join(', '); var directorsLabel = page.querySelector('.directorsLabel'); @@ -1086,13 +971,39 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } } - function renderDetails(page, item, apiClient, context, isStatic) { - renderSimilarItems(page, item, context); - renderMoreFromSeason(page, item, apiClient); - renderMoreFromArtist(page, item, apiClient); - renderDirector(page, item, context); - renderGenres(page, item, context); - renderChannelGuide(page, apiClient, item); + function renderMiscInfo(page, item) { + const primaryItemMiscInfo = page.querySelectorAll('.itemMiscInfo-primary'); + + for (const miscInfo of primaryItemMiscInfo) { + mediaInfo.fillPrimaryMediaInfo(miscInfo, item, { + interactive: true, + episodeTitle: false, + subtitles: false + }); + + if (miscInfo.innerHTML && 'SeriesTimer' !== item.Type) { + miscInfo.classList.remove('hide'); + } else { + miscInfo.classList.add('hide'); + } + } + + const secondaryItemMiscInfo = page.querySelectorAll('.itemMiscInfo-secondary'); + + for (const miscInfo of secondaryItemMiscInfo) { + mediaInfo.fillSecondaryMediaInfo(miscInfo, item, { + interactive: true + }); + + if (miscInfo.innerHTML && 'SeriesTimer' !== item.Type) { + miscInfo.classList.remove('hide'); + } else { + miscInfo.classList.add('hide'); + } + } + } + + function renderTagline(page, item) { var taglineElement = page.querySelector('.tagline'); if (item.Taglines && item.Taglines.length) { @@ -1101,44 +1012,21 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } else { taglineElement.classList.add('hide'); } + } - var overview = page.querySelector('.overview'); - var externalLinksElem = page.querySelector('.itemExternalLinks'); - - renderOverview([overview], item); - - var i; - var itemMiscInfo; - itemMiscInfo = page.querySelectorAll('.itemMiscInfo-primary'); - for (i = 0; i < itemMiscInfo.length; i++) { - mediaInfo.fillPrimaryMediaInfo(itemMiscInfo[i], item, { - interactive: true, - episodeTitle: false, - subtitles: false - }); - - if (itemMiscInfo[i].innerHTML && 'SeriesTimer' !== item.Type) { - itemMiscInfo[i].classList.remove('hide'); - } else { - itemMiscInfo[i].classList.add('hide'); - } - } - - itemMiscInfo = page.querySelectorAll('.itemMiscInfo-secondary'); - for (i = 0; i < itemMiscInfo.length; i++) { - mediaInfo.fillSecondaryMediaInfo(itemMiscInfo[i], item, { - interactive: true - }); - - if (itemMiscInfo[i].innerHTML && 'SeriesTimer' !== item.Type) { - itemMiscInfo[i].classList.remove('hide'); - } else { - itemMiscInfo[i].classList.add('hide'); - } - } - + function renderDetails(page, item, apiClient, context, isStatic) { + renderSimilarItems(page, item, context); + renderMoreFromSeason(page, item, apiClient); + renderMoreFromArtist(page, item, apiClient); + renderDirector(page, item, context); + renderWriter(page, item, context); + renderGenres(page, item, context); + renderChannelGuide(page, apiClient, item); + renderTagline(page, item); + renderOverview(page, item); + renderMiscInfo(page, item); reloadUserDataButtons(page, item); - renderLinks(externalLinksElem, item); + renderLinks(page, item); renderTags(page, item); renderSeriesAirTime(page, item, isStatic); } @@ -1426,8 +1314,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti action: 'playallfromhere', image: false, artist: 'auto', - containerAlbumArtists: item.AlbumArtists, - addToListButton: true + containerAlbumArtists: item.AlbumArtists }); isList = true; } else if ('Series' == item.Type) { @@ -1469,11 +1356,12 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti items: result.Items, showIndexNumber: false, enableOverview: true, + enablePlayedButton: layoutManager.mobile ? false : true, + infoButton: layoutManager.mobile ? false : true, imageSize: 'large', enableSideMediaInfo: false, highlight: false, - action: layoutManager.tv ? 'resume' : 'none', - infoButton: true, + action: !layoutManager.desktop ? 'link' : 'none', imagePlayButton: true, includeParentInfoInTitle: false }); @@ -1500,6 +1388,9 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti childrenItemsContainer.classList.remove('vertical-list'); } } + if (layoutManager.mobile) { + childrenItemsContainer.classList.remove('padded-right'); + } childrenItemsContainer.innerHTML = html; imageLoader.lazyChildren(childrenItemsContainer); if ('BoxSet' == item.Type) { @@ -1701,12 +1592,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function renderCollectionItems(page, parentItem, types, items) { + page.querySelector('.collectionItems').classList.remove('hide'); page.querySelector('.collectionItems').innerHTML = ''; - var i; - var length; - for (i = 0, length = types.length; i < length; i++) { - var type = types[i]; + for (const type of types) { var typeItems = filterItemsByCollectionItemType(items, type); if (typeItems.length) { @@ -1739,8 +1628,8 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti renderChildren(page, parentItem); }; - for (i = 0, length = containers.length; i < length; i++) { - containers[i].notifyRefreshNeeded = notifyRefreshNeeded; + for (const container of containers) { + container.notifyRefreshNeeded = notifyRefreshNeeded; } // if nothing in the collection can be played hide play and shuffle buttons @@ -1876,7 +1765,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti function renderCast(page, item) { var people = (item.People || []).filter(function (p) { - return 'Director' !== p.Type; + return p.Type === 'Actor'; }); if (!people.length) { @@ -1905,12 +1794,10 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti } function bindAll(view, selector, eventName, fn) { - var i; - var length; var elems = view.querySelectorAll(selector); - for (i = 0, length = elems.length; i < length; i++) { - elems[i].addEventListener(eventName, fn); + for (const elem of elems) { + elem.addEventListener(eventName, fn); } } @@ -1923,13 +1810,14 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti return function (view, params) { function reload(instance, page, params) { loading.show(); + var apiClient = params.serverId ? connectionManager.getApiClient(params.serverId) : ApiClient; - var promises = [getPromise(apiClient, params), apiClient.getCurrentUser()]; - Promise.all(promises).then(function (responses) { - var item = responses[0]; - var user = responses[1]; + + Promise.all([getPromise(apiClient, params), apiClient.getCurrentUser()]).then(([item, user]) => { currentItem = item; reloadFromItem(instance, page, params, item, user); + }).catch((error) => { + console.error('failed to get item or current user: ', error); }); } @@ -1980,7 +1868,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti }); } - playItem(item, item.UserData && 'resume' === mode ? item.UserData.PlaybackPositionTicks : 0); + playItem(item, item.UserData && mode === 'resume' ? item.UserData.PlaybackPositionTicks : 0); } function onPlayClick() { @@ -1995,15 +1883,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti playbackManager.shuffle(currentItem); } - function onDeleteClick() { - require(['deleteHelper'], function (deleteHelper) { - deleteHelper.deleteItem({ - item: currentItem, - navigate: true - }); - }); - } - function onCancelSeriesTimerClick() { require(['recordingHelper'], function (recordingHelper) { recordingHelper.cancelSeriesTimerWithConfirmation(currentItem.Id, currentItem.ServerId).then(function () { @@ -2092,7 +1971,6 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti bindAll(view, '.btnPlayTrailer', 'click', onPlayTrailerClick); bindAll(view, '.btnCancelSeriesTimer', 'click', onCancelSeriesTimerClick); bindAll(view, '.btnCancelTimer', 'click', onCancelTimerClick); - bindAll(view, '.btnDeleteItem', 'click', onDeleteClick); bindAll(view, '.btnDownload', 'click', onDownloadClick); view.querySelector('.trackSelections').addEventListener('submit', onTrackSelectionsSubmit); view.querySelector('.btnSplitVersions').addEventListener('click', function () { @@ -2125,9 +2003,7 @@ define(['loading', 'appRouter', 'layoutManager', 'connectionManager', 'userSetti view.addEventListener('viewshow', function (e) { var page = this; - if (layoutManager.mobile) { - libraryMenu.setTransparentMenu(true); - } + libraryMenu.setTransparentMenu(true); if (e.detail.isRestored) { if (currentItem) { diff --git a/src/controllers/playback/nowplaying.js b/src/controllers/playback/nowplaying.js index 98c9945e84..581b5f4b8a 100644 --- a/src/controllers/playback/nowplaying.js +++ b/src/controllers/playback/nowplaying.js @@ -1,22 +1,22 @@ -define(['components/remotecontrol/remotecontrol', 'libraryMenu', 'emby-button'], function (remotecontrolFactory, libraryMenu) { - 'use strict'; +import remotecontrolFactory from 'components/remotecontrol/remotecontrol'; +import libraryMenu from 'libraryMenu'; +import 'emby-button'; - return function (view, params) { - var remoteControl = new remotecontrolFactory(); - remoteControl.init(view, view.querySelector('.remoteControlContent')); - view.addEventListener('viewshow', function (e) { - libraryMenu.setTransparentMenu(true); +export default function (view, params) { + const remoteControl = new remotecontrolFactory(); + remoteControl.init(view, view.querySelector('.remoteControlContent')); + view.addEventListener('viewshow', function (e) { + libraryMenu.setTransparentMenu(true); - if (remoteControl) { - remoteControl.onShow(); - } - }); - view.addEventListener('viewbeforehide', function (e) { - libraryMenu.setTransparentMenu(false); + if (remoteControl) { + remoteControl.onShow(); + } + }); + view.addEventListener('viewbeforehide', function (e) { + libraryMenu.setTransparentMenu(false); - if (remoteControl) { - remoteControl.destroy(); - } - }); - }; -}); + if (remoteControl) { + remoteControl.destroy(); + } + }); +} diff --git a/src/controllers/playback/videoosd.js b/src/controllers/playback/videoosd.js index 94fbcf5df3..7452102082 100644 --- a/src/controllers/playback/videoosd.js +++ b/src/controllers/playback/videoosd.js @@ -1,5 +1,26 @@ -define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'mediaInfo', 'focusManager', 'imageLoader', 'scrollHelper', 'events', 'connectionManager', 'browser', 'globalize', 'apphost', 'layoutManager', 'userSettings', 'keyboardnavigation', 'scrollStyles', 'emby-slider', 'paper-icon-button-light', 'css!assets/css/videoosd'], function (playbackManager, dom, inputManager, datetime, itemHelper, mediaInfo, focusManager, imageLoader, scrollHelper, events, connectionManager, browser, globalize, appHost, layoutManager, userSettings, keyboardnavigation) { - 'use strict'; +import playbackManager from 'playbackManager'; +import dom from 'dom'; +import inputManager from 'inputManager'; +import datetime from 'datetime'; +import itemHelper from 'itemHelper'; +import mediaInfo from 'mediaInfo'; +import focusManager from 'focusManager'; +import imageLoader from 'imageLoader'; +import scrollHelper from 'scrollHelper'; +import events from 'events'; +import connectionManager from 'connectionManager'; +import browser from 'browser'; +import globalize from 'globalize'; +import appHost from 'apphost'; +import layoutManager from 'layoutManager'; +import * as userSettings from 'userSettings'; +import keyboardnavigation from 'keyboardnavigation'; +import 'scrollStyles'; +import 'emby-slider'; +import 'paper-icon-button-light'; +import 'css!assets/css/videoosd'; + +/* eslint-disable indent */ function seriesImageUrl(item, options) { if ('Episode' !== item.Type) { @@ -45,13 +66,13 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med return null; } - return function (view, params) { + export default function (view, params) { function onVerticalSwipe(e, elem, data) { - var player = currentPlayer; + const player = currentPlayer; if (player) { - var deltaY = data.currentDeltaY; - var windowSize = dom.getWindowSize(); + const deltaY = data.currentDeltaY; + const windowSize = dom.getWindowSize(); if (supportsBrightnessChange && data.clientX < windowSize.innerWidth / 2) { return void doBrightnessTouch(deltaY, player, windowSize.innerHeight); @@ -62,23 +83,23 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function doBrightnessTouch(deltaY, player, viewHeight) { - var delta = -deltaY / viewHeight * 100; - var newValue = playbackManager.getBrightness(player) + delta; + const delta = -deltaY / viewHeight * 100; + let newValue = playbackManager.getBrightness(player) + delta; newValue = Math.min(newValue, 100); newValue = Math.max(newValue, 0); playbackManager.setBrightness(newValue, player); } function doVolumeTouch(deltaY, player, viewHeight) { - var delta = -deltaY / viewHeight * 100; - var newValue = playbackManager.getVolume(player) + delta; + const delta = -deltaY / viewHeight * 100; + let newValue = playbackManager.getVolume(player) + delta; newValue = Math.min(newValue, 100); newValue = Math.max(newValue, 0); playbackManager.setVolume(newValue, player); } function onDoubleClick(e) { - var clientX = e.clientX; + const clientX = e.clientX; if (null != clientX) { if (clientX < dom.getWindowSize().innerWidth / 2) { @@ -94,7 +115,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function getDisplayItem(item) { if ('TvChannel' === item.Type) { - var apiClient = connectionManager.getApiClient(item.ServerId); + const apiClient = connectionManager.getApiClient(item.ServerId); return apiClient.getItem(apiClient.getCurrentUserId(), item.Id).then(function (refreshedItem) { return { originalItem: refreshedItem, @@ -120,7 +141,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med connectionManager.getApiClient(item.ServerId).getCurrentUser().then(function (user) { if (user.Policy.EnableLiveTvManagement) { - require(['recordingButton'], function (RecordingButton) { + import('recordingButton').then(({default: RecordingButton}) => { if (recordingButtonManager) { return void recordingButtonManager.refreshItem(item); } @@ -136,22 +157,22 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function updateDisplayItem(itemInfo) { - var item = itemInfo.originalItem; + const item = itemInfo.originalItem; currentItem = item; - var displayItem = itemInfo.displayItem || item; + const displayItem = itemInfo.displayItem || item; updateRecordingButton(displayItem); setPoster(displayItem, item); - var parentName = displayItem.SeriesName || displayItem.Album; + let parentName = displayItem.SeriesName || displayItem.Album; if (displayItem.EpisodeTitle || displayItem.IsSeries) { parentName = displayItem.Name; } setTitle(displayItem, parentName); - var titleElement; - var osdTitle = view.querySelector('.osdTitle'); + let titleElement; + const osdTitle = view.querySelector('.osdTitle'); titleElement = osdTitle; - var displayName = itemHelper.getDisplayName(displayItem, { + let displayName = itemHelper.getDisplayName(displayItem, { includeParentInfo: 'Program' !== displayItem.Type, includeIndexNumber: 'Program' !== displayItem.Type }); @@ -168,7 +189,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med titleElement.classList.add('hide'); } - var mediaInfoHtml = mediaInfo.getPrimaryMediaInfoHtml(displayItem, { + const mediaInfoHtml = mediaInfo.getPrimaryMediaInfoHtml(displayItem, { runtime: false, subtitles: false, tomatoes: false, @@ -178,7 +199,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med episodeTitleIndexNumber: 'Program' !== displayItem.Type, programIndicator: false }); - var osdMediaInfo = view.querySelector('.osdMediaInfo'); + const osdMediaInfo = view.querySelector('.osdMediaInfo'); osdMediaInfo.innerHTML = mediaInfoHtml; if (mediaInfoHtml) { @@ -187,8 +208,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med osdMediaInfo.classList.add('hide'); } - var secondaryMediaInfo = view.querySelector('.osdSecondaryMediaInfo'); - var secondaryMediaInfoHtml = mediaInfo.getSecondaryMediaInfoHtml(displayItem, { + const secondaryMediaInfo = view.querySelector('.osdSecondaryMediaInfo'); + const secondaryMediaInfoHtml = mediaInfo.getSecondaryMediaInfoHtml(displayItem, { startDate: false, programTime: false }); @@ -236,7 +257,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function setDisplayTime(elem, date) { - var html; + let html; if (date) { date = datetime.parseISO8601Date(date); @@ -251,7 +272,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function updateNowPlayingInfo(player, state) { - var item = state.NowPlayingItem; + const item = state.NowPlayingItem; currentItem = item; if (!item) { @@ -294,7 +315,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function setTitle(item, parentName) { Emby.Page.setTitle(parentName || ''); - var documentTitle = parentName || (item ? item.Name : null); + const documentTitle = parentName || (item ? item.Name : null); if (documentTitle) { document.title = documentTitle; @@ -302,10 +323,10 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function setPoster(item, secondaryItem) { - var osdPoster = view.querySelector('.osdPoster'); + const osdPoster = view.querySelector('.osdPoster'); if (item) { - var imgUrl = seriesImageUrl(item, { + let imgUrl = seriesImageUrl(item, { maxWidth: osdPoster.clientWidth * 2, type: 'Primary' }) || seriesImageUrl(item, { @@ -333,13 +354,21 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med osdPoster.innerHTML = ''; } + let osdLockCount = 0; + function showOsd() { slideDownToShow(headerElement); showMainOsdControls(); - startOsdHideTimer(); + if (!osdLockCount) { + startOsdHideTimer(); + } } function hideOsd() { + if (osdLockCount) { + return; + } + slideUpToHide(headerElement); hideMainOsdControls(); } @@ -352,6 +381,19 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } } + function lockOsd() { + osdLockCount++; + stopOsdHideTimer(); + } + + function unlockOsd() { + osdLockCount--; + // Restart hide timer if OSD is currently visible + if (currentVisibleMenu && !osdLockCount) { + startOsdHideTimer(); + } + } + function startOsdHideTimer() { stopOsdHideTimer(); osdHideTimeout = setTimeout(hideOsd, 3e3); @@ -379,7 +421,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function onHideAnimationComplete(e) { - var elem = e.target; + const elem = e.target; if (elem != osdBottomElement) return; elem.classList.add('hide'); @@ -390,7 +432,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function showMainOsdControls() { if (!currentVisibleMenu) { - var elem = osdBottomElement; + const elem = osdBottomElement; currentVisibleMenu = 'osd'; clearHideAnimationEventListeners(elem); elem.classList.remove('hide'); @@ -407,7 +449,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function hideMainOsdControls() { if ('osd' === currentVisibleMenu) { - var elem = osdBottomElement; + const elem = osdBottomElement; clearHideAnimationEventListeners(elem); elem.classList.add('videoOsdBottom-hidden'); dom.addEventListener(elem, transitionEndEventName, onHideAnimationComplete, { @@ -425,9 +467,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function onPointerMove(e) { if ('mouse' === (e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse'))) { - var eventX = e.screenX || 0; - var eventY = e.screenY || 0; - var obj = lastPointerMoveData; + const eventX = e.screenX || 0; + const eventY = e.screenY || 0; + const obj = lastPointerMoveData; if (!obj) { lastPointerMoveData = { @@ -448,7 +490,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function onInputCommand(e) { - var player = currentPlayer; + const player = currentPlayer; switch (e.detail.command) { case 'left': @@ -507,7 +549,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function onRecordingCommand() { - var btnRecord = view.querySelector('.btnRecord'); + const btnRecord = view.querySelector('.btnRecord'); if (!btnRecord.classList.contains('hide')) { btnRecord.click(); @@ -534,7 +576,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function onStateChanged(event, state) { - var player = this; + const player = this; if (state.NowPlayingItem) { isEnabled = true; @@ -552,21 +594,21 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function onVolumeChanged(e) { if (isEnabled) { - var player = this; + const player = this; updatePlayerVolumeState(player, player.isMuted(), player.getVolume()); } } function onPlaybackStart(e, state) { console.debug('nowplaying event: ' + e.type); - var player = this; + const player = this; onStateChanged.call(player, e, state); resetUpNextDialog(); } function resetUpNextDialog() { comingUpNextDisplayed = false; - var dlg = currentUpNextDialog; + const dlg = currentUpNextDialog; if (dlg) { dlg.destroy(); @@ -586,8 +628,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function onMediaStreamsChanged(e) { - var player = this; - var state = playbackManager.getPlayerState(player); + const player = this; + const state = playbackManager.getPlayerState(player); onStateChanged.call(player, { type: 'init' }, state); @@ -607,7 +649,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med currentPlayer = player; if (!player) return; } - var state = playbackManager.getPlayerState(player); + const state = playbackManager.getPlayerState(player); onStateChanged.call(player, { type: 'init' }, state); @@ -632,7 +674,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med destroyStats(); destroySubtitleSync(); resetUpNextDialog(); - var player = currentPlayer; + const player = currentPlayer; if (player) { events.off(player, 'playbackstart', onPlaybackStart); @@ -650,15 +692,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function onTimeUpdate(e) { // Test for 'currentItem' is required for Firefox since its player spams 'timeupdate' events even being at breakpoint if (isEnabled && currentItem) { - var now = new Date().getTime(); + const now = new Date().getTime(); if (!(now - lastUpdateTime < 700)) { lastUpdateTime = now; - var player = this; + const player = this; currentRuntimeTicks = playbackManager.duration(player); - var currentTime = playbackManager.currentTime(player); + const currentTime = playbackManager.currentTime(player); updateTimeDisplay(currentTime, currentRuntimeTicks, playbackManager.playbackStartTime(player), playbackManager.getBufferedRanges(player)); - var item = currentItem; + const item = currentItem; refreshProgramInfoIfNeeded(player, item); showComingUpNextIfNeeded(player, item, currentTime, currentRuntimeTicks); } @@ -667,9 +709,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function showComingUpNextIfNeeded(player, currentItem, currentTimeTicks, runtimeTicks) { if (runtimeTicks && currentTimeTicks && !comingUpNextDisplayed && !currentVisibleMenu && 'Episode' === currentItem.Type && userSettings.enableNextVideoInfoOverlay()) { - var showAtSecondsLeft = runtimeTicks >= 3e10 ? 40 : runtimeTicks >= 24e9 ? 35 : 30; - var showAtTicks = runtimeTicks - 1e3 * showAtSecondsLeft * 1e4; - var timeRemainingTicks = runtimeTicks - currentTimeTicks; + const showAtSecondsLeft = runtimeTicks >= 3e10 ? 40 : runtimeTicks >= 24e9 ? 35 : 30; + const showAtTicks = runtimeTicks - 1e3 * showAtSecondsLeft * 1e4; + const timeRemainingTicks = runtimeTicks - currentTimeTicks; if (currentTimeTicks >= showAtTicks && runtimeTicks >= 6e9 && timeRemainingTicks >= 2e8) { showComingUpNext(player); @@ -684,7 +726,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function showComingUpNext(player) { - require(['upNextDialog'], function (UpNextDialog) { + import('upNextDialog').then(({default: UpNextDialog}) => { if (!(currentVisibleMenu || currentUpNextDialog)) { currentVisibleMenu = 'upnext'; comingUpNextDisplayed = true; @@ -702,15 +744,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med function refreshProgramInfoIfNeeded(player, item) { if ('TvChannel' === item.Type) { - var program = item.CurrentProgram; + const program = item.CurrentProgram; if (program && program.EndDate) { try { - var endDate = datetime.parseISO8601Date(program.EndDate); + const endDate = datetime.parseISO8601Date(program.EndDate); if (new Date().getTime() >= endDate.getTime()) { console.debug('program info needs to be refreshed'); - var state = playbackManager.getPlayerState(player); + const state = playbackManager.getPlayerState(player); onStateChanged.call(player, { type: 'init' }, state); @@ -738,9 +780,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function updatePlayerStateInternal(event, player, state) { - var playState = state.PlayState || {}; + const playState = state.PlayState || {}; updatePlayPauseState(playState.IsPaused); - var supportedCommands = playbackManager.getSupportedCommands(player); + const supportedCommands = playbackManager.getSupportedCommands(player); currentPlayerSupportedCommands = supportedCommands; supportsBrightnessChange = -1 !== supportedCommands.indexOf('SetBrightness'); updatePlayerVolumeState(player, playState.IsMuted, playState.VolumeLevel); @@ -751,7 +793,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med btnFastForward.disabled = !playState.CanSeek; btnRewind.disabled = !playState.CanSeek; - var nowPlayingItem = state.NowPlayingItem || {}; + const nowPlayingItem = state.NowPlayingItem || {}; playbackStartTimeTicks = playState.PlaybackStartTimeTicks; updateTimeDisplay(playState.PositionTicks, nowPlayingItem.RunTimeTicks, playState.PlaybackStartTimeTicks, playState.BufferedRanges || []); updateNowPlayingInfo(player, state); @@ -762,7 +804,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med view.querySelector('.btnVideoOsdSettings').classList.add('hide'); } - var isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks; + const isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks; nowPlayingPositionSlider.setIsClear(isProgressClear); if (nowPlayingItem.RunTimeTicks) { @@ -799,12 +841,12 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med if (enableProgressByTimeOfDay) { if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) { if (programStartDateMs && programEndDateMs) { - var currentTimeMs = (playbackStartTimeTicks + (positionTicks || 0)) / 1e4; - var programRuntimeMs = programEndDateMs - programStartDateMs; + const currentTimeMs = (playbackStartTimeTicks + (positionTicks || 0)) / 1e4; + const programRuntimeMs = programEndDateMs - programStartDateMs; if (nowPlayingPositionSlider.value = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, currentTimeMs), bufferedRanges.length) { - var rangeStart = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].start || 0)) / 1e4); - var rangeEnd = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].end || 0)) / 1e4); + const rangeStart = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].start || 0)) / 1e4); + const rangeEnd = getDisplayPercentByTimeOfDay(programStartDateMs, programRuntimeMs, (playbackStartTimeTicks + (bufferedRanges[0].end || 0)) / 1e4); nowPlayingPositionSlider.setBufferedRanges([{ start: rangeStart, end: rangeEnd @@ -823,7 +865,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } else { if (nowPlayingPositionSlider && !nowPlayingPositionSlider.dragging) { if (runtimeTicks) { - var pct = positionTicks / runtimeTicks; + let pct = positionTicks / runtimeTicks; pct *= 100; nowPlayingPositionSlider.value = pct; } else { @@ -847,9 +889,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function updatePlayerVolumeState(player, isMuted, volumeLevel) { - var supportedCommands = currentPlayerSupportedCommands; - var showMuteButton = true; - var showVolumeSlider = true; + const supportedCommands = currentPlayerSupportedCommands; + let showMuteButton = true; + let showVolumeSlider = true; if (-1 === supportedCommands.indexOf('Mute')) { showMuteButton = false; @@ -897,8 +939,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function updatePlaylist(player) { - var btnPreviousTrack = view.querySelector('.btnPreviousTrack'); - var btnNextTrack = view.querySelector('.btnNextTrack'); + const btnPreviousTrack = view.querySelector('.btnPreviousTrack'); + const btnNextTrack = view.querySelector('.btnNextTrack'); btnPreviousTrack.classList.remove('hide'); btnNextTrack.classList.remove('hide'); btnNextTrack.disabled = false; @@ -911,7 +953,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med return; } - var html = datetime.getDisplayRunningTime(ticks); + let html = datetime.getDisplayRunningTime(ticks); if (divider) { html = ' / ' + html; @@ -921,15 +963,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function onSettingsButtonClick(e) { - var btn = this; + const btn = this; - require(['playerSettingsMenu'], function (playerSettingsMenu) { - var player = currentPlayer; + import('playerSettingsMenu').then(({default: playerSettingsMenu}) => { + const player = currentPlayer; if (player) { // show subtitle offset feature only if player and media support it - var showSubOffset = playbackManager.supportSubtitleOffset(player) && + const showSubOffset = playbackManager.supportSubtitleOffset(player) && playbackManager.canHandleOffsetOnCurrentSubtitle(player); playerSettingsMenu.show({ @@ -948,7 +990,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med if ('stats' === selectedOption) { toggleStats(); } else if ('suboffset' === selectedOption) { - var player = currentPlayer; + const player = currentPlayer; if (player) { playbackManager.enableShowingSubtitleOffset(player); toggleSubtitleSync(); @@ -957,8 +999,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function toggleStats() { - require(['playerStats'], function (PlayerStats) { - var player = currentPlayer; + import('playerStats').then(({default: PlayerStats}) => { + const player = currentPlayer; if (player) { if (statsOverlay) { @@ -980,11 +1022,11 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function showAudioTrackSelection() { - var player = currentPlayer; - var audioTracks = playbackManager.audioTracks(player); - var currentIndex = playbackManager.getAudioStreamIndex(player); - var menuItems = audioTracks.map(function (stream) { - var opt = { + const player = currentPlayer; + const audioTracks = playbackManager.audioTracks(player); + const currentIndex = playbackManager.getAudioStreamIndex(player); + const menuItems = audioTracks.map(function (stream) { + const opt = { name: stream.DisplayTitle, id: stream.Index }; @@ -995,15 +1037,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med return opt; }); - var positionTo = this; + const positionTo = this; - require(['actionsheet'], function (actionsheet) { + import('actionsheet').then(({default: actionsheet}) => { actionsheet.show({ items: menuItems, title: globalize.translate('Audio'), positionTo: positionTo }).then(function (id) { - var index = parseInt(id); + const index = parseInt(id); if (index !== currentIndex) { playbackManager.setAudioStreamIndex(index, player); @@ -1013,9 +1055,9 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function showSubtitleTrackSelection() { - var player = currentPlayer; - var streams = playbackManager.subtitleTracks(player); - var currentIndex = playbackManager.getSubtitleStreamIndex(player); + const player = currentPlayer; + const streams = playbackManager.subtitleTracks(player); + let currentIndex = playbackManager.getSubtitleStreamIndex(player); if (null == currentIndex) { currentIndex = -1; @@ -1025,8 +1067,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med Index: -1, DisplayTitle: globalize.translate('Off') }); - var menuItems = streams.map(function (stream) { - var opt = { + const menuItems = streams.map(function (stream) { + const opt = { name: stream.DisplayTitle, id: stream.Index }; @@ -1037,15 +1079,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med return opt; }); - var positionTo = this; + const positionTo = this; - require(['actionsheet'], function (actionsheet) { + import('actionsheet').then(({default: actionsheet}) => { actionsheet.show({ title: globalize.translate('Subtitles'), items: menuItems, positionTo: positionTo }).then(function (id) { - var index = parseInt(id); + const index = parseInt(id); if (index !== currentIndex) { playbackManager.setSubtitleStreamIndex(index, player); @@ -1057,8 +1099,8 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function toggleSubtitleSync(action) { - require(['subtitleSync'], function (SubtitleSync) { - var player = currentPlayer; + import('subtitleSync').then(({default: SubtitleSync}) => { + const player = currentPlayer; if (subtitleSyncOverlay) { subtitleSyncOverlay.toggle(action); } else if (player) { @@ -1078,12 +1120,12 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med * Clicked element. * To skip 'click' handling on Firefox/Edge. */ - var clickedElement; + let clickedElement; - function onWindowKeyDown(e) { + function onKeyDown(e) { clickedElement = e.srcElement; - var key = keyboardnavigation.getKeyName(e); + const key = keyboardnavigation.getKeyName(e); if (!currentVisibleMenu && 32 === e.keyCode) { playbackManager.playPause(currentPlayer); @@ -1187,19 +1229,37 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med case '6': case '7': case '8': - case '9': - var percent = parseInt(key, 10) * 10; + case '9': { + const percent = parseInt(key, 10) * 10; playbackManager.seekPercent(percent, currentPlayer); break; + } + } + } + + function onKeyDownCapture() { + // Restart hide timer if OSD is currently visible + if (currentVisibleMenu) { + showOsd(); } } function onWindowMouseDown(e) { clickedElement = e.srcElement; + lockOsd(); + } + + function onWindowMouseUp() { + unlockOsd(); } function onWindowTouchStart(e) { clickedElement = e.srcElement; + lockOsd(); + } + + function onWindowTouchEnd() { + unlockOsd(); } function getImgUrl(item, chapter, index, maxWidth, apiClient) { @@ -1216,11 +1276,11 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } function getChapterBubbleHtml(apiClient, item, chapters, positionTicks) { - var chapter; - var index = -1; + let chapter; + let index = -1; - for (var i = 0, length = chapters.length; i < length; i++) { - var currentChapter = chapters[i]; + for (let i = 0, length = chapters.length; i < length; i++) { + const currentChapter = chapters[i]; if (positionTicks >= currentChapter.StartPositionTicks) { chapter = currentChapter; @@ -1232,10 +1292,10 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med return null; } - var src = getImgUrl(item, chapter, index, 400, apiClient); + const src = getImgUrl(item, chapter, index, 400, apiClient); if (src) { - var html = '
'; + let html = '
'; html += ''; html += '
'; html += '
'; @@ -1251,15 +1311,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med return null; } - var playPauseClickTimeout; + let playPauseClickTimeout; function onViewHideStopPlayback() { if (playbackManager.isPlayingVideo()) { - require(['shell'], function (shell) { + import('shell').then(({default: shell}) => { shell.disableFullscreen(); }); clearTimeout(playPauseClickTimeout); - var player = currentPlayer; + const player = currentPlayer; view.removeEventListener('viewbeforehide', onViewHideStopPlayback); releaseCurrentPlayer(); playbackManager.stop(player); @@ -1274,47 +1334,49 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med } } - require(['shell'], function (shell) { + import('shell').then(({default: shell}) => { shell.enableFullscreen(); }); - var currentPlayer; - var comingUpNextDisplayed; - var currentUpNextDialog; - var isEnabled; - var currentItem; - var recordingButtonManager; - var enableProgressByTimeOfDay; - var supportsBrightnessChange; - var currentVisibleMenu; - var statsOverlay; - var osdHideTimeout; - var lastPointerMoveData; - var self = this; - var currentPlayerSupportedCommands = []; - var currentRuntimeTicks = 0; - var lastUpdateTime = 0; - var programStartDateMs = 0; - var programEndDateMs = 0; - var playbackStartTimeTicks = 0; - var subtitleSyncOverlay; - var nowPlayingVolumeSlider = view.querySelector('.osdVolumeSlider'); - var nowPlayingVolumeSliderContainer = view.querySelector('.osdVolumeSliderContainer'); - var nowPlayingPositionSlider = view.querySelector('.osdPositionSlider'); - var nowPlayingPositionText = view.querySelector('.osdPositionText'); - var nowPlayingDurationText = view.querySelector('.osdDurationText'); - var startTimeText = view.querySelector('.startTimeText'); - var endTimeText = view.querySelector('.endTimeText'); - var endsAtText = view.querySelector('.endsAtText'); - var btnRewind = view.querySelector('.btnRewind'); - var btnFastForward = view.querySelector('.btnFastForward'); - var transitionEndEventName = dom.whichTransitionEvent(); - var headerElement = document.querySelector('.skinHeader'); - var osdBottomElement = document.querySelector('.videoOsdBottom-maincontrols'); + let currentPlayer; + let comingUpNextDisplayed; + let currentUpNextDialog; + let isEnabled; + let currentItem; + let recordingButtonManager; + let enableProgressByTimeOfDay; + let supportsBrightnessChange; + let currentVisibleMenu; + let statsOverlay; + let osdHideTimeout; + let lastPointerMoveData; + const self = this; + let currentPlayerSupportedCommands = []; + let currentRuntimeTicks = 0; + let lastUpdateTime = 0; + let programStartDateMs = 0; + let programEndDateMs = 0; + let playbackStartTimeTicks = 0; + let subtitleSyncOverlay; + const nowPlayingVolumeSlider = view.querySelector('.osdVolumeSlider'); + const nowPlayingVolumeSliderContainer = view.querySelector('.osdVolumeSliderContainer'); + const nowPlayingPositionSlider = view.querySelector('.osdPositionSlider'); + const nowPlayingPositionText = view.querySelector('.osdPositionText'); + const nowPlayingDurationText = view.querySelector('.osdDurationText'); + const startTimeText = view.querySelector('.startTimeText'); + const endTimeText = view.querySelector('.endTimeText'); + const endsAtText = view.querySelector('.endsAtText'); + const btnRewind = view.querySelector('.btnRewind'); + const btnFastForward = view.querySelector('.btnFastForward'); + const transitionEndEventName = dom.whichTransitionEvent(); + const headerElement = document.querySelector('.skinHeader'); + const osdBottomElement = document.querySelector('.videoOsdBottom-maincontrols'); + + nowPlayingPositionSlider.enableKeyboardDragging(); + nowPlayingVolumeSlider.enableKeyboardDragging(); if (layoutManager.tv) { nowPlayingPositionSlider.classList.add('focusable'); - nowPlayingPositionSlider.enableKeyboardDragging(); } view.addEventListener('viewbeforeshow', function (e) { @@ -1325,23 +1387,35 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med try { events.on(playbackManager, 'playerchange', onPlayerChange); bindToPlayer(playbackManager.getCurrentPlayer()); + /* eslint-disable-next-line compat/compat */ dom.addEventListener(document, window.PointerEvent ? 'pointermove' : 'mousemove', onPointerMove, { passive: true }); showOsd(); inputManager.on(window, onInputCommand); - dom.addEventListener(window, 'keydown', onWindowKeyDown, { + document.addEventListener('keydown', onKeyDown); + dom.addEventListener(document, 'keydown', onKeyDownCapture, { capture: true }); + /* eslint-disable-next-line compat/compat */ dom.addEventListener(window, window.PointerEvent ? 'pointerdown' : 'mousedown', onWindowMouseDown, { passive: true }); + /* eslint-disable-next-line compat/compat */ + dom.addEventListener(window, window.PointerEvent ? 'pointerup' : 'mouseup', onWindowMouseUp, { + passive: true + }); dom.addEventListener(window, 'touchstart', onWindowTouchStart, { passive: true }); + ['touchend', 'touchcancel'].forEach((event) => { + dom.addEventListener(window, event, onWindowTouchEnd, { + passive: true + }); + }); } catch (e) { - require(['appRouter'], function(appRouter) { - appRouter.showDirect('/'); + import('appRouter').then(({default: appRouter}) => { + appRouter.goHome(); }); } }); @@ -1350,18 +1424,30 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med statsOverlay.enabled(false); } - dom.removeEventListener(window, 'keydown', onWindowKeyDown, { + document.removeEventListener('keydown', onKeyDown); + dom.removeEventListener(document, 'keydown', onKeyDownCapture, { capture: true }); + /* eslint-disable-next-line compat/compat */ dom.removeEventListener(window, window.PointerEvent ? 'pointerdown' : 'mousedown', onWindowMouseDown, { passive: true }); + /* eslint-disable-next-line compat/compat */ + dom.removeEventListener(window, window.PointerEvent ? 'pointerup' : 'mouseup', onWindowMouseUp, { + passive: true + }); dom.removeEventListener(window, 'touchstart', onWindowTouchStart, { passive: true }); + ['touchend', 'touchcancel'].forEach((event) => { + dom.removeEventListener(window, event, onWindowTouchEnd, { + passive: true + }); + }); stopOsdHideTimer(); headerElement.classList.remove('osdHeader'); headerElement.classList.remove('osdHeader-hidden'); + /* eslint-disable-next-line compat/compat */ dom.removeEventListener(document, window.PointerEvent ? 'pointermove' : 'mousemove', onPointerMove, { passive: true }); @@ -1396,14 +1482,15 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med destroyStats(); destroySubtitleSync(); }); - var lastPointerDown = 0; + let lastPointerDown = 0; + /* eslint-disable-next-line compat/compat */ dom.addEventListener(view, window.PointerEvent ? 'pointerdown' : 'click', function (e) { if (dom.parentWithClass(e.target, ['videoOsdBottom', 'upNextContainer'])) { return void showOsd(); } - var pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse'); - var now = new Date().getTime(); + const pointerType = e.pointerType || (layoutManager.mobile ? 'touch' : 'mouse'); + const now = new Date().getTime(); switch (pointerType) { case 'touch': @@ -1441,31 +1528,28 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med if (browser.touch) { dom.addEventListener(view, 'dblclick', onDoubleClick, {}); } else { - var options = { passive: true }; + const options = { passive: true }; dom.addEventListener(view, 'dblclick', function () { playbackManager.toggleFullscreen(currentPlayer); }, options); } - function setVolume() { - playbackManager.setVolume(this.value, currentPlayer); - } - view.querySelector('.buttonMute').addEventListener('click', function () { playbackManager.toggleMute(currentPlayer); }); - nowPlayingVolumeSlider.addEventListener('change', setVolume); - nowPlayingVolumeSlider.addEventListener('mousemove', setVolume); - nowPlayingVolumeSlider.addEventListener('touchmove', setVolume); + + nowPlayingVolumeSlider.addEventListener('input', (e) => { + playbackManager.setVolume(e.target.value, currentPlayer); + }); nowPlayingPositionSlider.addEventListener('change', function () { - var player = currentPlayer; + const player = currentPlayer; if (player) { - var newPercent = parseFloat(this.value); + const newPercent = parseFloat(this.value); if (enableProgressByTimeOfDay) { - var seekAirTimeTicks = newPercent / 100 * (programEndDateMs - programStartDateMs) * 1e4; + let seekAirTimeTicks = newPercent / 100 * (programEndDateMs - programStartDateMs) * 1e4; seekAirTimeTicks += 1e4 * programStartDateMs; seekAirTimeTicks -= playbackStartTimeTicks; playbackManager.seek(seekAirTimeTicks, player); @@ -1479,7 +1563,7 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med showOsd(); if (enableProgressByTimeOfDay) { if (programStartDateMs && programEndDateMs) { - var ms = programEndDateMs - programStartDateMs; + let ms = programEndDateMs - programStartDateMs; ms /= 100; ms *= value; ms += programStartDateMs; @@ -1493,13 +1577,13 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med return '--:--'; } - var ticks = currentRuntimeTicks; + let ticks = currentRuntimeTicks; ticks /= 100; ticks *= value; - var item = currentItem; + const item = currentItem; if (item && item.Chapters && item.Chapters.length && item.Chapters[0].ImageTag) { - var html = getChapterBubbleHtml(connectionManager.getApiClient(item.ServerId), item, item.Chapters, ticks); + let html = getChapterBubbleHtml(connectionManager.getApiClient(item.ServerId), item, item.Chapters, ticks); if (html) { return html; @@ -1532,8 +1616,13 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med if (browser.touch) { (function () { +<<<<<<< HEAD require(['touchHelper'], function (TouchHelper) { self.touchHelper = new TouchHelper.default(view, { +======= + import('touchHelper').then(({default: TouchHelper}) => { + self.touchHelper = new TouchHelper(view, { +>>>>>>> upstream/master swipeYThreshold: 30, triggerOnMove: true, preventDefaultOnMove: true, @@ -1544,5 +1633,6 @@ define(['playbackManager', 'dom', 'inputManager', 'datetime', 'itemHelper', 'med }); })(); } - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/user/display.js b/src/controllers/user/display.js index 408631b383..e6c1448ee4 100644 --- a/src/controllers/user/display.js +++ b/src/controllers/user/display.js @@ -1,20 +1,23 @@ -define(['displaySettings', 'userSettings', 'autoFocuser'], function (DisplaySettings, userSettings, autoFocuser) { - 'use strict'; +import DisplaySettings from 'displaySettings'; +import * as userSettings from 'userSettings'; +import autoFocuser from 'autoFocuser'; + +/* eslint-disable indent */ // Shortcuts const UserSettings = userSettings.UserSettings; - return function (view, params) { + export default function (view, params) { function onBeforeUnload(e) { if (hasChanges) { e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?'; } } - var settingsInstance; - var hasChanges; - var userId = params.userId || ApiClient.getCurrentUserId(); - var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); + let settingsInstance; + let hasChanges; + const userId = params.userId || ApiClient.getCurrentUserId(); + const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); view.addEventListener('viewshow', function () { window.addEventListener('beforeunload', onBeforeUnload); @@ -26,28 +29,23 @@ define(['displaySettings', 'userSettings', 'autoFocuser'], function (DisplaySett userId: userId, element: view.querySelector('.settingsContainer'), userSettings: currentSettings, - enableSaveButton: false, - enableSaveConfirmation: false, + enableSaveButton: true, + enableSaveConfirmation: true, autoFocus: autoFocuser.isEnabled() }); } }); + view.addEventListener('change', function () { hasChanges = true; }); - view.addEventListener('viewbeforehide', function () { - window.removeEventListener('beforeunload', onBeforeUnload); - hasChanges = false; - if (settingsInstance) { - settingsInstance.submit(); - } - }); view.addEventListener('viewdestroy', function () { if (settingsInstance) { settingsInstance.destroy(); settingsInstance = null; } }); - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/user/home.js b/src/controllers/user/home.js index 117a457d3f..404868acf4 100644 --- a/src/controllers/user/home.js +++ b/src/controllers/user/home.js @@ -1,20 +1,27 @@ -define(['homescreenSettings', 'dom', 'globalize', 'loading', 'userSettings', 'autoFocuser', 'listViewStyle'], function (HomescreenSettings, dom, globalize, loading, userSettings, autoFocuser) { - 'use strict'; +import HomescreenSettings from 'homescreenSettings'; +import dom from 'dom'; +import globalize from 'globalize'; +import loading from 'loading'; +import * as userSettings from 'userSettings'; +import autoFocuser from 'autoFocuser'; +import 'listViewStyle'; + +/* eslint-disable indent */ // Shortcuts const UserSettings = userSettings.UserSettings; - return function (view, params) { + export default function (view, params) { function onBeforeUnload(e) { if (hasChanges) { e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?'; } } - var homescreenSettingsInstance; - var hasChanges; - var userId = params.userId || ApiClient.getCurrentUserId(); - var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); + let homescreenSettingsInstance; + let hasChanges; + const userId = params.userId || ApiClient.getCurrentUserId(); + const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); view.addEventListener('viewshow', function () { window.addEventListener('beforeunload', onBeforeUnload); @@ -26,27 +33,23 @@ define(['homescreenSettings', 'dom', 'globalize', 'loading', 'userSettings', 'au userId: userId, element: view.querySelector('.homeScreenSettingsContainer'), userSettings: currentSettings, - enableSaveButton: false, - enableSaveConfirmation: false, + enableSaveButton: true, + enableSaveConfirmation: true, autoFocus: autoFocuser.isEnabled() }); } }); + view.addEventListener('change', function () { hasChanges = true; }); - view.addEventListener('viewbeforehide', function () { - hasChanges = false; - if (homescreenSettingsInstance) { - homescreenSettingsInstance.submit(); - } - }); view.addEventListener('viewdestroy', function () { if (homescreenSettingsInstance) { homescreenSettingsInstance.destroy(); homescreenSettingsInstance = null; } }); - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/user/playback.js b/src/controllers/user/playback.js index c138b5a86d..33dd7af734 100644 --- a/src/controllers/user/playback.js +++ b/src/controllers/user/playback.js @@ -1,20 +1,27 @@ -define(['playbackSettings', 'dom', 'globalize', 'loading', 'userSettings', 'autoFocuser', 'listViewStyle'], function (PlaybackSettings, dom, globalize, loading, userSettings, autoFocuser) { - 'use strict'; +import PlaybackSettings from 'playbackSettings'; +import dom from 'dom'; +import globalize from 'globalize'; +import loading from 'loading'; +import * as userSettings from 'userSettings'; +import autoFocuser from 'autoFocuser'; +import 'listViewStyle'; + +/* eslint-disable indent */ // Shortcuts const UserSettings = userSettings.UserSettings; - return function (view, params) { + export default function (view, params) { function onBeforeUnload(e) { if (hasChanges) { e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?'; } } - var settingsInstance; - var hasChanges; - var userId = params.userId || ApiClient.getCurrentUserId(); - var currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); + let settingsInstance; + let hasChanges; + const userId = params.userId || ApiClient.getCurrentUserId(); + const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); view.addEventListener('viewshow', function () { window.addEventListener('beforeunload', onBeforeUnload); @@ -26,27 +33,23 @@ define(['playbackSettings', 'dom', 'globalize', 'loading', 'userSettings', 'auto userId: userId, element: view.querySelector('.settingsContainer'), userSettings: currentSettings, - enableSaveButton: false, - enableSaveConfirmation: false, + enableSaveButton: true, + enableSaveConfirmation: true, autoFocus: autoFocuser.isEnabled() }); } }); + view.addEventListener('change', function () { hasChanges = true; }); - view.addEventListener('viewbeforehide', function () { - hasChanges = false; - if (settingsInstance) { - settingsInstance.submit(); - } - }); view.addEventListener('viewdestroy', function () { if (settingsInstance) { settingsInstance.destroy(); settingsInstance = null; } }); - }; -}); + } + +/* eslint-enable indent */ diff --git a/src/controllers/user/subtitles.js b/src/controllers/user/subtitles.js index c14b4424ac..ae2d33de33 100644 --- a/src/controllers/user/subtitles.js +++ b/src/controllers/user/subtitles.js @@ -1,6 +1,14 @@ +<<<<<<< HEAD import subtitleSettings from 'subtitleSettings'; import {UserSettings, currentSettings as userSettings} from 'userSettings'; import autoFocuser from 'autoFocuser'; +======= +import SubtitleSettings from 'subtitleSettings'; +import * as userSettings from 'userSettings'; +import autoFocuser from 'autoFocuser'; + +/* eslint-disable indent */ +>>>>>>> upstream/master export class SubtitleController { constructor(view, params) { @@ -10,6 +18,7 @@ export class SubtitleController { this.subtitleSettingsInstance = null; this.view = view; +<<<<<<< HEAD view.addEventListener('viewshow', this.viewShow.bind(this)); view.addEventListener('change', this.change.bind(this)); view.addEventListener('viewbeforehide', this.viewBeforeHide.bind(this)); @@ -56,8 +65,53 @@ export class SubtitleController { beforeUnload(e) { if (this.hasChanges) { e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?'; +======= + export default function (view, params) { + function onBeforeUnload(e) { + if (hasChanges) { + e.returnValue = 'You currently have unsaved changes. Are you sure you wish to leave?'; + } +>>>>>>> upstream/master } } } +<<<<<<< HEAD export default SubtitleController; +======= + let subtitleSettingsInstance; + let hasChanges; + const userId = params.userId || ApiClient.getCurrentUserId(); + const currentSettings = userId === ApiClient.getCurrentUserId() ? userSettings : new UserSettings(); + view.addEventListener('viewshow', function () { + window.addEventListener('beforeunload', onBeforeUnload); + + if (subtitleSettingsInstance) { + subtitleSettingsInstance.loadData(); + } else { + subtitleSettingsInstance = new SubtitleSettings({ + serverId: ApiClient.serverId(), + userId: userId, + element: view.querySelector('.settingsContainer'), + userSettings: currentSettings, + enableSaveButton: true, + enableSaveConfirmation: true, + autoFocus: autoFocuser.isEnabled() + }); + } + }); + + view.addEventListener('change', function () { + hasChanges = true; + }); + + view.addEventListener('viewdestroy', function () { + if (subtitleSettingsInstance) { + subtitleSettingsInstance.destroy(); + subtitleSettingsInstance = null; + } + }); + } + +/* eslint-enable indent */ +>>>>>>> upstream/master diff --git a/src/elements/emby-button/emby-button.js b/src/elements/emby-button/emby-button.js index 683c59cca0..bfc47296b6 100644 --- a/src/elements/emby-button/emby-button.js +++ b/src/elements/emby-button/emby-button.js @@ -1,3 +1,4 @@ +<<<<<<< HEAD import browser from 'browser'; import dom from 'dom'; import layoutManager from 'layoutManager'; @@ -6,6 +7,10 @@ import appRouter from 'appRouter'; import appHost from 'apphost'; import 'css!./emby-button'; import 'registerElement'; +======= +define(['browser', 'dom', 'layoutManager', 'shell', 'appRouter', 'apphost', 'css!./emby-button', 'webcomponents'], function (browser, dom, layoutManager, shell, appRouter, appHost) { + 'use strict'; +>>>>>>> upstream/master const EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype); const EmbyLinkButtonPrototype = Object.create(HTMLAnchorElement.prototype); diff --git a/src/elements/emby-button/paper-icon-button-light.js b/src/elements/emby-button/paper-icon-button-light.js index 609dec2967..76a76626de 100644 --- a/src/elements/emby-button/paper-icon-button-light.js +++ b/src/elements/emby-button/paper-icon-button-light.js @@ -1,6 +1,11 @@ +<<<<<<< HEAD import layoutManager from 'layoutManager'; import 'css!./emby-button'; import 'registerElement'; +======= +define(['layoutManager', 'css!./emby-button', 'webcomponents'], function (layoutManager) { + 'use strict'; +>>>>>>> upstream/master const EmbyButtonPrototype = Object.create(HTMLButtonElement.prototype); diff --git a/src/elements/emby-checkbox/emby-checkbox.js b/src/elements/emby-checkbox/emby-checkbox.js index b22ff151af..4f3419dae7 100644 --- a/src/elements/emby-checkbox/emby-checkbox.js +++ b/src/elements/emby-checkbox/emby-checkbox.js @@ -1,7 +1,12 @@ +<<<<<<< HEAD import browser from 'browser'; import dom from 'dom'; import 'css!./emby-checkbox'; import 'registerElement'; +======= +define(['browser', 'dom', 'css!./emby-checkbox', 'webcomponents'], function (browser, dom) { + 'use strict'; +>>>>>>> upstream/master /* eslint-disable indent */ diff --git a/src/elements/emby-collapse/emby-collapse.js b/src/elements/emby-collapse/emby-collapse.js index 805e40afd9..cfd42f8537 100644 --- a/src/elements/emby-collapse/emby-collapse.js +++ b/src/elements/emby-collapse/emby-collapse.js @@ -1,7 +1,12 @@ +<<<<<<< HEAD import browser from 'browser'; import 'css!./emby-collapse'; import 'registerElement'; import 'emby-button'; +======= +define(['browser', 'css!./emby-collapse', 'webcomponents', 'emby-button'], function (browser) { + 'use strict'; +>>>>>>> upstream/master /* eslint-disable indent */ diff --git a/src/elements/emby-input/emby-input.js b/src/elements/emby-input/emby-input.js index f5c60ca92f..778c707a85 100644 --- a/src/elements/emby-input/emby-input.js +++ b/src/elements/emby-input/emby-input.js @@ -1,8 +1,13 @@ +<<<<<<< HEAD import layoutManager from 'layoutManager'; import browser from 'browser'; import dom from 'dom'; import 'css!./emby-input'; import 'registerElement'; +======= +define(['layoutManager', 'browser', 'dom', 'css!./emby-input', 'webcomponents'], function (layoutManager, browser, dom) { + 'use strict'; +>>>>>>> upstream/master /* eslint-disable indent */ diff --git a/src/elements/emby-itemrefreshindicator/emby-itemrefreshindicator.js b/src/elements/emby-itemrefreshindicator/emby-itemrefreshindicator.js index 493d291ce0..4e1f683c92 100644 --- a/src/elements/emby-itemrefreshindicator/emby-itemrefreshindicator.js +++ b/src/elements/emby-itemrefreshindicator/emby-itemrefreshindicator.js @@ -1,3 +1,4 @@ +<<<<<<< HEAD import EmbyProgressRing from 'emby-progressring'; import dom from 'dom'; import serverNotifications from 'serverNotifications'; @@ -5,6 +6,10 @@ import events from 'events'; import 'registerElement'; /* eslint-disable indent */ +======= +define(['emby-progressring', 'dom', 'serverNotifications', 'events', 'webcomponents'], function (EmbyProgressRing, dom, serverNotifications, events) { + 'use strict'; +>>>>>>> upstream/master function addNotificationEvent(instance, name, handler) { diff --git a/src/elements/emby-itemscontainer/emby-itemscontainer.js b/src/elements/emby-itemscontainer/emby-itemscontainer.js index 58e8565289..a9b09e345e 100644 --- a/src/elements/emby-itemscontainer/emby-itemscontainer.js +++ b/src/elements/emby-itemscontainer/emby-itemscontainer.js @@ -1,3 +1,4 @@ +<<<<<<< HEAD import itemShortcuts from 'itemShortcuts'; import inputManager from 'inputManager'; import connectionManager from 'connectionManager'; @@ -15,6 +16,12 @@ import 'registerElement'; /* eslint-disable indent */ const ItemsContainerPrototype = Object.create(HTMLDivElement.prototype); +======= +define(['itemShortcuts', 'inputManager', 'connectionManager', 'playbackManager', 'imageLoader', 'layoutManager', 'browser', 'dom', 'loading', 'focusManager', 'serverNotifications', 'events', 'webcomponents'], function (itemShortcuts, inputManager, connectionManager, playbackManager, imageLoader, layoutManager, browser, dom, loading, focusManager, serverNotifications, events) { + 'use strict'; + + var ItemsContainerPrototype = Object.create(HTMLDivElement.prototype); +>>>>>>> upstream/master function onClick(e) { const itemsContainer = this; @@ -42,7 +49,7 @@ import 'registerElement'; // check for serverId, it won't be present on selectserver if (card && card.getAttribute('data-serverid')) { - inputManager.trigger('menu', { + inputManager.handleCommand('menu', { sourceElement: card }); diff --git a/src/elements/emby-progressring/emby-progressring.js b/src/elements/emby-progressring/emby-progressring.js index d266d884a0..7c46c55fd8 100644 --- a/src/elements/emby-progressring/emby-progressring.js +++ b/src/elements/emby-progressring/emby-progressring.js @@ -1,6 +1,11 @@ +<<<<<<< HEAD import require from 'require'; import 'css!./emby-progressring'; import 'webcomponents'; +======= +define(['require', 'css!./emby-progressring', 'webcomponents'], function (require) { + 'use strict'; +>>>>>>> upstream/master /* eslint-disable indent */ diff --git a/src/elements/emby-radio/emby-radio.js b/src/elements/emby-radio/emby-radio.js index d989326d25..73c5f1359a 100644 --- a/src/elements/emby-radio/emby-radio.js +++ b/src/elements/emby-radio/emby-radio.js @@ -1,6 +1,11 @@ +<<<<<<< HEAD import layoutManager from 'layoutManager'; import 'css!./emby-radio'; import 'registerElement'; +======= +define(['layoutManager', 'css!./emby-radio', 'webcomponents'], function (layoutManager) { + 'use strict'; +>>>>>>> upstream/master /* eslint-disable indent */ diff --git a/src/elements/emby-scrollbuttons/emby-scrollbuttons.css b/src/elements/emby-scrollbuttons/emby-scrollbuttons.css index b2e0d3bc23..5af739bac1 100644 --- a/src/elements/emby-scrollbuttons/emby-scrollbuttons.css +++ b/src/elements/emby-scrollbuttons/emby-scrollbuttons.css @@ -6,7 +6,7 @@ justify-content: center; min-width: 104px; min-height: 24px; - padding-top: 1.25em; + padding-top: 0.85em; z-index: 1; color: #fff; display: flex; diff --git a/src/elements/emby-scrollbuttons/emby-scrollbuttons.js b/src/elements/emby-scrollbuttons/emby-scrollbuttons.js index b4b0ffb3b9..5c002ed193 100644 --- a/src/elements/emby-scrollbuttons/emby-scrollbuttons.js +++ b/src/elements/emby-scrollbuttons/emby-scrollbuttons.js @@ -1,8 +1,13 @@ +<<<<<<< HEAD import layoutManager from 'layoutManager'; import dom from 'dom'; import 'css!./emby-scrollbuttons'; import 'registerElement'; import 'paper-icon-button-light'; +======= +define(['layoutManager', 'dom', 'css!./emby-scrollbuttons', 'webcomponents', 'paper-icon-button-light'], function (layoutManager, dom) { + 'use strict'; +>>>>>>> upstream/master /* eslint-disable indent */ diff --git a/src/elements/emby-scroller/emby-scroller.js b/src/elements/emby-scroller/emby-scroller.js index aa56dd84e7..5084e65f26 100644 --- a/src/elements/emby-scroller/emby-scroller.js +++ b/src/elements/emby-scroller/emby-scroller.js @@ -1,3 +1,4 @@ +<<<<<<< HEAD import scroller from 'scroller'; import dom from 'dom'; import layoutManager from 'layoutManager'; @@ -6,6 +7,10 @@ import focusManager from 'focusManager'; import browser from 'browser'; import 'registerElement'; import 'css!./emby-scroller'; +======= +define(['scroller', 'dom', 'layoutManager', 'inputManager', 'focusManager', 'browser', 'webcomponents', 'css!./emby-scroller'], function (scroller, dom, layoutManager, inputManager, focusManager, browser) { + 'use strict'; +>>>>>>> upstream/master /* eslint-disable indent */ diff --git a/src/elements/emby-select/emby-select.js b/src/elements/emby-select/emby-select.js index cba9b8da7c..aa9eec7620 100644 --- a/src/elements/emby-select/emby-select.js +++ b/src/elements/emby-select/emby-select.js @@ -1,8 +1,13 @@ +<<<<<<< HEAD import layoutManager from 'layoutManager'; import browser from 'browser'; import actionsheet from 'actionsheet'; import 'css!./emby-select'; import 'registerElement'; +======= +define(['layoutManager', 'browser', 'actionsheet', 'css!./emby-select', 'webcomponents'], function (layoutManager, browser, actionsheet) { + 'use strict'; +>>>>>>> upstream/master /* eslint-disable indent */ diff --git a/src/elements/emby-slider/emby-slider.js b/src/elements/emby-slider/emby-slider.js index e872f6c78b..bcd85fab86 100644 --- a/src/elements/emby-slider/emby-slider.js +++ b/src/elements/emby-slider/emby-slider.js @@ -1,3 +1,4 @@ +<<<<<<< HEAD import browser from 'browser'; import dom from 'dom'; import layoutManager from 'layoutManager'; @@ -5,6 +6,10 @@ import keyboardnavigation from 'keyboardnavigation'; import 'css!./emby-slider'; import 'webcomponents'; import 'emby-input'; +======= +define(['browser', 'dom', 'layoutManager', 'keyboardnavigation', 'css!./emby-slider', 'webcomponents', 'emby-input'], function (browser, dom, layoutManager, keyboardnavigation) { + 'use strict'; +>>>>>>> upstream/master /* eslint-disable indent */ diff --git a/src/elements/emby-tabs/emby-tabs.css b/src/elements/emby-tabs/emby-tabs.css index 355f904cb8..fe29f46143 100644 --- a/src/elements/emby-tabs/emby-tabs.css +++ b/src/elements/emby-tabs/emby-tabs.css @@ -31,11 +31,6 @@ .emby-tabs-slider { position: relative; - overflow: hidden; -} - -.layout-mobile .emby-tabs-slider { - overflow: auto; } .tabContent:not(.is-active) { diff --git a/src/elements/emby-tabs/emby-tabs.js b/src/elements/emby-tabs/emby-tabs.js index c36a5c7f06..63de9333c7 100644 --- a/src/elements/emby-tabs/emby-tabs.js +++ b/src/elements/emby-tabs/emby-tabs.js @@ -1,3 +1,4 @@ +<<<<<<< HEAD import dom from 'dom'; import scroller from 'scroller'; import browser from 'browser'; @@ -6,6 +7,10 @@ import focusManager from 'focusManager'; import 'registerElement'; import 'css!./emby-tabs'; import 'scrollStyles'; +======= +define(['dom', 'scroller', 'browser', 'layoutManager', 'focusManager', 'webcomponents', 'css!./emby-tabs', 'scrollStyles'], function (dom, scroller, browser, layoutManager, focusManager) { + 'use strict'; +>>>>>>> upstream/master /* eslint-disable indent */ diff --git a/src/elements/emby-textarea/emby-textarea.js b/src/elements/emby-textarea/emby-textarea.js index 3b7624e74a..b48ff5c314 100644 --- a/src/elements/emby-textarea/emby-textarea.js +++ b/src/elements/emby-textarea/emby-textarea.js @@ -1,3 +1,4 @@ +<<<<<<< HEAD import layoutManager from 'layoutManager'; import browser from 'browser'; import 'css!./emby-textarea'; @@ -5,6 +6,10 @@ import 'registerElement'; import 'emby-input'; /* eslint-disable indent */ +======= +define(['layoutManager', 'browser', 'css!./emby-textarea', 'webcomponents', 'emby-input'], function (layoutManager, browser) { + 'use strict'; +>>>>>>> upstream/master function autoGrow(textarea, maxLines) { const self = this; diff --git a/src/elements/emby-toggle/emby-toggle.js b/src/elements/emby-toggle/emby-toggle.js index 99856923e9..b5807e70fc 100644 --- a/src/elements/emby-toggle/emby-toggle.js +++ b/src/elements/emby-toggle/emby-toggle.js @@ -1,5 +1,10 @@ +<<<<<<< HEAD import 'css!./emby-toggle'; import 'registerElement'; +======= +define(['css!./emby-toggle', 'webcomponents'], function () { + 'use strict'; +>>>>>>> upstream/master /* eslint-disable indent */ diff --git a/src/index.html b/src/index.html index ed63ca1a98..f8d867cb1a 100644 --- a/src/index.html +++ b/src/index.html @@ -52,7 +52,7 @@ - + @@ -69,12 +69,19 @@ Jellyfin @@ -103,7 +148,9 @@
-
+
+ +
diff --git a/src/login.html b/src/login.html index 8e48901c11..fd52b4bf58 100644 --- a/src/login.html +++ b/src/login.html @@ -1,7 +1,9 @@ -
+
- -

${HeaderPleaseSignIn}

+ +
+

${HeaderPleaseSignIn}

+
@@ -29,8 +31,6 @@ ${ButtonCancel}
-
-
diff --git a/src/nowplaying.html b/src/nowplaying.html index 5f235a562e..592807737f 100644 --- a/src/nowplaying.html +++ b/src/nowplaying.html @@ -5,7 +5,7 @@
- +
@@ -15,9 +15,9 @@
- +
- +
@@ -25,15 +25,20 @@
- -
- + +
+
- + + + - + @@ -49,15 +54,19 @@ - + - + + +
- + @@ -65,14 +74,19 @@ - +
- + + @@ -162,21 +176,18 @@
-
- - +
-
-
-
-
-
-
diff --git a/src/plugins/chromecastPlayer/plugin.js b/src/plugins/chromecastPlayer/plugin.js index dad95691fc..3d4f293cc8 100644 --- a/src/plugins/chromecastPlayer/plugin.js +++ b/src/plugins/chromecastPlayer/plugin.js @@ -548,7 +548,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' events.trigger(instance, 'playbackstop', [state]); - var state = instance.lastPlayerData.PlayState || {}; + state = instance.lastPlayerData.PlayState || {}; var volume = state.VolumeLevel || 0.5; var mute = state.IsMuted || false; @@ -572,6 +572,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' bindEventForRelay(instance, 'unpause'); bindEventForRelay(instance, 'volumechange'); bindEventForRelay(instance, 'repeatmodechange'); + bindEventForRelay(instance, 'shufflequeuemodechange'); events.on(instance._castPlayer, 'playstatechange', function (e, data) { @@ -651,6 +652,7 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' 'SetSubtitleStreamIndex', 'DisplayContent', 'SetRepeatMode', + 'SetShuffleQueue', 'EndSession', 'PlayMediaSource', 'PlayTrailers' @@ -864,6 +866,12 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' return state.RepeatMode; }; + ChromecastPlayer.prototype.getQueueShuffleMode = function () { + var state = this.lastPlayerData || {}; + state = state.PlayState || {}; + return state.ShuffleMode; + }; + ChromecastPlayer.prototype.playTrailers = function (item) { this._castPlayer.sendMessage({ @@ -884,6 +892,15 @@ define(['appSettings', 'userSettings', 'playbackManager', 'connectionManager', ' }); }; + ChromecastPlayer.prototype.setQueueShuffleMode = function (value) { + this._castPlayer.sendMessage({ + options: { + ShuffleMode: value + }, + command: 'SetShuffleQueue' + }); + }; + ChromecastPlayer.prototype.toggleMute = function () { this._castPlayer.sendMessage({ diff --git a/src/plugins/htmlVideoPlayer/plugin.js b/src/plugins/htmlVideoPlayer/plugin.js index f8ba7c415c..cc312bb956 100644 --- a/src/plugins/htmlVideoPlayer/plugin.js +++ b/src/plugins/htmlVideoPlayer/plugin.js @@ -649,7 +649,7 @@ define(['browser', 'require', 'events', 'apphost', 'loading', 'dom', 'playbackMa function setTrackEventsSubtitleOffset(trackEvents, offsetValue) { if (Array.isArray(trackEvents)) { - offsetValue = updateCurrentTrackOffset(offsetValue); + offsetValue = updateCurrentTrackOffset(offsetValue) * 1e7; // ticks trackEvents.forEach(function(trackEvent) { trackEvent.StartPositionTicks -= offsetValue; trackEvent.EndPositionTicks -= offsetValue; diff --git a/src/plugins/sessionPlayer/plugin.js b/src/plugins/sessionPlayer/plugin.js index 489b57493d..084aa027cf 100644 --- a/src/plugins/sessionPlayer/plugin.js +++ b/src/plugins/sessionPlayer/plugin.js @@ -263,7 +263,7 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager'] appName: s.Client, playableMediaTypes: s.PlayableMediaTypes, isLocalPlayer: false, - supportedCommands: s.SupportedCommands, + supportedCommands: s.Capabilities.SupportedCommands, user: s.UserId ? { Id: s.UserId, @@ -506,6 +506,17 @@ define(['playbackManager', 'events', 'serverNotifications', 'connectionManager'] }); }; + SessionPlayer.prototype.setQueueShuffleMode = function (mode) { + + sendCommandByName(this, 'SetShuffleQueue', { + ShuffleMode: mode + }); + }; + + SessionPlayer.prototype.getQueueShuffleMode = function () { + + }; + SessionPlayer.prototype.displayContent = function (options) { sendCommandByName(this, 'DisplayContent', options); diff --git a/src/scripts/apploader.js b/src/scripts/apploader.js index 0353c9535c..183b765d16 100644 --- a/src/scripts/apploader.js +++ b/src/scripts/apploader.js @@ -11,6 +11,7 @@ src += `?v=${self.dashboardVersion}`; } script.src = src; + script.setAttribute('async', ''); if (onload) { script.onload = onload; diff --git a/src/scripts/browserDeviceProfile.js b/src/scripts/browserDeviceProfile.js index 0ee2a0f068..fcbe002549 100644 --- a/src/scripts/browserDeviceProfile.js +++ b/src/scripts/browserDeviceProfile.js @@ -60,7 +60,7 @@ define(['browser'], function (browser) { function canPlayHlsWithMSE() { // text tracks don’t work with this in firefox - return window.MediaSource != null; + return window.MediaSource != null; /* eslint-disable-line compat/compat */ } function supportsAc3(videoTestElement) { diff --git a/src/scripts/dom.js b/src/scripts/dom.js index a3d157f337..080bff66ae 100644 --- a/src/scripts/dom.js +++ b/src/scripts/dom.js @@ -211,7 +211,7 @@ 'MozAnimation': 'animationend', 'WebkitAnimation': 'webkitAnimationEnd' }; - for (let t in animations) { + for (const t in animations) { if (el.style[t] !== undefined) { _animationEvent = animations[t]; return animations[t]; @@ -251,7 +251,7 @@ 'MozTransition': 'transitionend', 'WebkitTransition': 'webkitTransitionEnd' }; - for (let t in transitions) { + for (const t in transitions) { if (el.style[t] !== undefined) { _transitionEvent = transitions[t]; return transitions[t]; diff --git a/src/scripts/inputManager.js b/src/scripts/inputManager.js index 8af52c77e8..915324cfc0 100644 --- a/src/scripts/inputManager.js +++ b/src/scripts/inputManager.js @@ -201,6 +201,9 @@ import appHost from 'apphost'; 'rewind': () => { playbackManager.rewind(); }, + 'seek': () => { + playbackManager.seekMs(options); + }, 'togglefullscreen': () => { playbackManager.toggleFullscreen(); }, @@ -235,9 +238,6 @@ import appHost from 'apphost'; } } - // Alias for backward compatibility - export const trigger = handleCommand; - dom.addEventListener(document, 'click', notify, { passive: true }); @@ -245,8 +245,7 @@ import appHost from 'apphost'; /* eslint-enable indent */ export default { - trigger: handleCommand, - handle: handleCommand, + handleCommand: handleCommand, notify: notify, notifyMouseMove: notifyMouseMove, idleTime: idleTime, diff --git a/src/scripts/itembynamedetailpage.js b/src/scripts/itembynamedetailpage.js index 44eca55589..fd29724225 100644 --- a/src/scripts/itembynamedetailpage.js +++ b/src/scripts/itembynamedetailpage.js @@ -71,12 +71,12 @@ define(['connectionManager', 'listView', 'cardBuilder', 'imageLoader', 'libraryB html += '
'; html += '
'; - html += '

'; + html += '

'; html += section.name; html += '

'; html += ''; html += '
'; - html += '
'; + html += '
'; html += '
'; return html += '
'; }).join(''); diff --git a/src/scripts/keyboardNavigation.js b/src/scripts/keyboardNavigation.js index 7cd402b83a..7cc4df9553 100644 --- a/src/scripts/keyboardNavigation.js +++ b/src/scripts/keyboardNavigation.js @@ -78,7 +78,7 @@ export function isNavigationKey(key) { } export function enable() { - document.addEventListener('keydown', function (e) { + window.addEventListener('keydown', function (e) { const key = getKeyName(e); // Ignore navigation keys for non-TV @@ -90,53 +90,53 @@ export function enable() { switch (key) { case 'ArrowLeft': - inputManager.handle('left'); + inputManager.handleCommand('left'); break; case 'ArrowUp': - inputManager.handle('up'); + inputManager.handleCommand('up'); break; case 'ArrowRight': - inputManager.handle('right'); + inputManager.handleCommand('right'); break; case 'ArrowDown': - inputManager.handle('down'); + inputManager.handleCommand('down'); break; case 'Back': - inputManager.handle('back'); + inputManager.handleCommand('back'); break; case 'Escape': if (layoutManager.tv) { - inputManager.handle('back'); + inputManager.handleCommand('back'); } else { capture = false; } break; case 'MediaPlay': - inputManager.handle('play'); + inputManager.handleCommand('play'); break; case 'Pause': - inputManager.handle('pause'); + inputManager.handleCommand('pause'); break; case 'MediaPlayPause': - inputManager.handle('playpause'); + inputManager.handleCommand('playpause'); break; case 'MediaRewind': - inputManager.handle('rewind'); + inputManager.handleCommand('rewind'); break; case 'MediaFastForward': - inputManager.handle('fastforward'); + inputManager.handleCommand('fastforward'); break; case 'MediaStop': - inputManager.handle('stop'); + inputManager.handleCommand('stop'); break; case 'MediaTrackPrevious': - inputManager.handle('previoustrack'); + inputManager.handleCommand('previoustrack'); break; case 'MediaTrackNext': - inputManager.handle('nexttrack'); + inputManager.handleCommand('nexttrack'); break; default: diff --git a/src/scripts/libraryMenu.js b/src/scripts/libraryMenu.js index a055530442..f228b46cec 100644 --- a/src/scripts/libraryMenu.js +++ b/src/scripts/libraryMenu.js @@ -13,7 +13,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' html += '
'; html += ''; html += ``; - html += ''; + html += ``; html += ``; html += ``; html += ''; @@ -89,7 +89,8 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' var policy = user.Policy ? user.Policy : user.localUser.Policy; - if (headerSyncButton && policy && policy.SyncPlayAccess !== 'None') { + var apiClient = getCurrentApiClient(); + if (headerSyncButton && policy && policy.SyncPlayAccess !== 'None' && apiClient.isMinServerVersion('10.6.0')) { headerSyncButton.classList.remove('hide'); } } else { @@ -116,7 +117,7 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' } function showSearch() { - inputManager.trigger('search'); + inputManager.handleCommand('search'); } function onHeaderUserButtonClick(e) { @@ -967,8 +968,10 @@ define(['dom', 'layoutManager', 'inputManager', 'connectionManager', 'events', ' updateUserInHeader(); }); events.on(playbackManager, 'playerchange', updateCastIcon); + events.on(syncPlayManager, 'enabled', onSyncPlayEnabled); events.on(syncPlayManager, 'syncing', onSyncPlaySyncing); + loadNavDrawer(); return LibraryMenu; }); diff --git a/src/scripts/mouseManager.js b/src/scripts/mouseManager.js index e6117fa851..84fe58e7e5 100644 --- a/src/scripts/mouseManager.js +++ b/src/scripts/mouseManager.js @@ -136,6 +136,7 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd stopMouseInterval(); + /* eslint-disable-next-line compat/compat */ dom.removeEventListener(document, (window.PointerEvent ? 'pointermove' : 'mousemove'), onPointerMove, { passive: true }); @@ -148,6 +149,7 @@ define(['inputManager', 'focusManager', 'browser', 'layoutManager', 'events', 'd }); } + /* eslint-disable-next-line compat/compat */ dom.removeEventListener(document, (window.PointerEvent ? 'pointerenter' : 'mouseenter'), onPointerEnter, { capture: true, passive: true diff --git a/src/scripts/routes.js b/src/scripts/routes.js index b5bb04683b..ab12b53abf 100644 --- a/src/scripts/routes.js +++ b/src/scripts/routes.js @@ -15,7 +15,7 @@ define([ 'detailtablecss'], function () { function defineRoute(newRoute) { - var path = newRoute.path; + var path = newRoute.alias ? newRoute.alias : newRoute.path; console.debug('defining route: ' + path); newRoute.dictionary = 'core'; Emby.Page.addRoute(path, newRoute); @@ -240,8 +240,9 @@ define([ transition: 'fade' }); defineRoute({ - path: '/itemdetails.html', - controller: 'itemDetails', + alias: '/details', + path: '/controllers/itemDetails/index.html', + controller: 'itemDetails/index', autoFocus: false, transition: 'fade' }); diff --git a/src/scripts/serverNotifications.js b/src/scripts/serverNotifications.js index 8e212ab718..331a75329c 100644 --- a/src/scripts/serverNotifications.js +++ b/src/scripts/serverNotifications.js @@ -36,28 +36,28 @@ define(['connectionManager', 'playbackManager', 'syncPlayManager', 'events', 'in console.debug('Received command: ' + cmd.Name); switch (cmd.Name) { case 'Select': - inputManager.trigger('select'); + inputManager.handleCommand('select'); return; case 'Back': - inputManager.trigger('back'); + inputManager.handleCommand('back'); return; case 'MoveUp': - inputManager.trigger('up'); + inputManager.handleCommand('up'); return; case 'MoveDown': - inputManager.trigger('down'); + inputManager.handleCommand('down'); return; case 'MoveLeft': - inputManager.trigger('left'); + inputManager.handleCommand('left'); return; case 'MoveRight': - inputManager.trigger('right'); + inputManager.handleCommand('right'); return; case 'PageUp': - inputManager.trigger('pageup'); + inputManager.handleCommand('pageup'); return; case 'PageDown': - inputManager.trigger('pagedown'); + inputManager.handleCommand('pagedown'); return; case 'PlayTrailers': playTrailers(apiClient, cmd.Arguments.ItemId); @@ -65,26 +65,29 @@ define(['connectionManager', 'playbackManager', 'syncPlayManager', 'events', 'in case 'SetRepeatMode': playbackManager.setRepeatMode(cmd.Arguments.RepeatMode); break; + case 'SetShuffleQueue': + playbackManager.setQueueShuffleMode(cmd.Arguments.ShuffleMode); + break; case 'VolumeUp': - inputManager.trigger('volumeup'); + inputManager.handleCommand('volumeup'); return; case 'VolumeDown': - inputManager.trigger('volumedown'); + inputManager.handleCommand('volumedown'); return; case 'ChannelUp': - inputManager.trigger('channelup'); + inputManager.handleCommand('channelup'); return; case 'ChannelDown': - inputManager.trigger('channeldown'); + inputManager.handleCommand('channeldown'); return; case 'Mute': - inputManager.trigger('mute'); + inputManager.handleCommand('mute'); return; case 'Unmute': - inputManager.trigger('unmute'); + inputManager.handleCommand('unmute'); return; case 'ToggleMute': - inputManager.trigger('togglemute'); + inputManager.handleCommand('togglemute'); return; case 'SetVolume': notifyApp(); @@ -99,19 +102,19 @@ define(['connectionManager', 'playbackManager', 'syncPlayManager', 'events', 'in playbackManager.setSubtitleStreamIndex(parseInt(cmd.Arguments.Index)); break; case 'ToggleFullscreen': - inputManager.trigger('togglefullscreen'); + inputManager.handleCommand('togglefullscreen'); return; case 'GoHome': - inputManager.trigger('home'); + inputManager.handleCommand('home'); return; case 'GoToSettings': - inputManager.trigger('settings'); + inputManager.handleCommand('settings'); return; case 'DisplayContent': displayContent(cmd, apiClient); break; case 'GoToSearch': - inputManager.trigger('search'); + inputManager.handleCommand('search'); return; case 'DisplayMessage': displayMessage(cmd); @@ -162,19 +165,19 @@ define(['connectionManager', 'playbackManager', 'syncPlayManager', 'events', 'in } } else if (msg.MessageType === 'Playstate') { if (msg.Data.Command === 'Stop') { - inputManager.trigger('stop'); + inputManager.handleCommand('stop'); } else if (msg.Data.Command === 'Pause') { - inputManager.trigger('pause'); + inputManager.handleCommand('pause'); } else if (msg.Data.Command === 'Unpause') { - inputManager.trigger('play'); + inputManager.handleCommand('play'); } else if (msg.Data.Command === 'PlayPause') { - inputManager.trigger('playpause'); + inputManager.handleCommand('playpause'); } else if (msg.Data.Command === 'Seek') { playbackManager.seek(msg.Data.SeekPositionTicks); } else if (msg.Data.Command === 'NextTrack') { - inputManager.trigger('next'); + inputManager.handleCommand('next'); } else if (msg.Data.Command === 'PreviousTrack') { - inputManager.trigger('previous'); + inputManager.handleCommand('previous'); } else { notifyApp(); } diff --git a/src/scripts/site.js b/src/scripts/site.js index 4976b65afb..57b0b6c5ac 100644 --- a/src/scripts/site.js +++ b/src/scripts/site.js @@ -196,7 +196,7 @@ var Dashboard = { capabilities: function (appHost) { var capabilities = { PlayableMediaTypes: ['Audio', 'Video'], - SupportedCommands: ['MoveUp', 'MoveDown', 'MoveLeft', 'MoveRight', 'PageUp', 'PageDown', 'PreviousLetter', 'NextLetter', 'ToggleOsd', 'ToggleContextMenu', 'Select', 'Back', 'SendKey', 'SendString', 'GoHome', 'GoToSettings', 'VolumeUp', 'VolumeDown', 'Mute', 'Unmute', 'ToggleMute', 'SetVolume', 'SetAudioStreamIndex', 'SetSubtitleStreamIndex', 'DisplayContent', 'GoToSearch', 'DisplayMessage', 'SetRepeatMode', 'ChannelUp', 'ChannelDown', 'PlayMediaSource', 'PlayTrailers'], + SupportedCommands: ['MoveUp', 'MoveDown', 'MoveLeft', 'MoveRight', 'PageUp', 'PageDown', 'PreviousLetter', 'NextLetter', 'ToggleOsd', 'ToggleContextMenu', 'Select', 'Back', 'SendKey', 'SendString', 'GoHome', 'GoToSettings', 'VolumeUp', 'VolumeDown', 'Mute', 'Unmute', 'ToggleMute', 'SetVolume', 'SetAudioStreamIndex', 'SetSubtitleStreamIndex', 'DisplayContent', 'GoToSearch', 'DisplayMessage', 'SetRepeatMode', 'SetShuffleQueue', 'ChannelUp', 'ChannelDown', 'PlayMediaSource', 'PlayTrailers'], SupportsPersistentIdentifier: 'cordova' === self.appMode || 'android' === self.appMode, SupportsMediaControl: true }; @@ -387,8 +387,6 @@ var AppInfo = {}; define('lazyLoader', [componentsPath + '/lazyLoader/lazyLoaderIntersectionObserver'], returnFirstDependency); define('shell', [scriptsPath + '/shell'], returnFirstDependency); - define('registerElement', ['document-register-element'], returnFirstDependency); - define('alert', [componentsPath + '/alert'], returnFirstDependency); defineResizeObserver(); @@ -672,7 +670,6 @@ var AppInfo = {}; }, bundles: { bundle: [ - 'document-register-element', 'fetch', 'flvjs', 'jstree', @@ -1039,7 +1036,7 @@ var AppInfo = {}; } if ('SeriesTimer' == itemType) { - return 'itemdetails.html?seriesTimerId=' + id + '&serverId=' + serverId; + return 'details?seriesTimerId=' + id + '&serverId=' + serverId; } if ('livetv' == item.CollectionType) { @@ -1109,13 +1106,13 @@ var AppInfo = {}; var itemTypes = ['Playlist', 'TvChannel', 'Program', 'BoxSet', 'MusicAlbum', 'MusicGenre', 'Person', 'Recording', 'MusicArtist']; if (itemTypes.indexOf(itemType) >= 0) { - return 'itemdetails.html?id=' + id + '&serverId=' + serverId; + return 'details?id=' + id + '&serverId=' + serverId; } var contextSuffix = context ? '&context=' + context : ''; if ('Series' == itemType || 'Season' == itemType || 'Episode' == itemType) { - return 'itemdetails.html?id=' + id + contextSuffix + '&serverId=' + serverId; + return 'details?id=' + id + contextSuffix + '&serverId=' + serverId; } if (item.IsFolder) { @@ -1126,7 +1123,7 @@ var AppInfo = {}; return '#'; } - return 'itemdetails.html?id=' + id + '&serverId=' + serverId; + return 'details?id=' + id + '&serverId=' + serverId; }; appRouter.showItem = showItem; diff --git a/src/selectserver.html b/src/selectserver.html index 2c84525174..3318a6b80e 100644 --- a/src/selectserver.html +++ b/src/selectserver.html @@ -1,10 +1,10 @@ -
-
-
+
+
+

${HeaderSelectServer}

-
+
diff --git a/src/strings/ar.json b/src/strings/ar.json index c1898bb1f9..e7217b425b 100644 --- a/src/strings/ar.json +++ b/src/strings/ar.json @@ -146,8 +146,8 @@ "HeaderAlbums": "الألبومات", "HeaderAlert": "تنبيه", "HeaderAllowMediaDeletionFrom": "السماح بحذف الوسائط من قبل", - "HeaderApiKey": "مفتاح api", - "HeaderApiKeys": "مفاتيح api", + "HeaderApiKey": "مفتاح API", + "HeaderApiKeys": "مفاتيح API", "HeaderApiKeysHelp": "التطبيقات الخارجية تحتاج أن تمتلك مفتاح api لكي تتصل بخادم أمبي. هذه المفاتيح تُصدر عن طريق تسجيل الدخول بحساب أمبي، أو عن طريق منح التطبيق مفتاحاً أصدر يدوياً.", "HeaderApp": "التطبيق", "HeaderAudioSettings": "إعدادات الصوت", @@ -162,7 +162,7 @@ "HeaderCodecProfileHelp": "عرائض الكودك تشير إلى محدودية جهاز ما عند تشغيل وسيطة مشفر بكودك معيّن. إن كان هناك أي محدودية مذكورة فستحال الوسيطة إلى التشغير البيني، حتى لو كانت الصيغة مضبوطة للعمل بتلقائية.", "HeaderConfirmPluginInstallation": "أكد عملية تثبيت الملحق", "HeaderConfirmProfileDeletion": "أكّد حذف العريضة", - "HeaderConfirmRevokeApiKey": "أرفض مفتاح api", + "HeaderConfirmRevokeApiKey": "أرفض مفتاح API", "HeaderConnectToServer": "اتصل إلى الخادم", "HeaderConnectionFailure": "فشل في الاتصال", "HeaderContainerProfile": "عريضة الحاوية", @@ -193,7 +193,7 @@ "HeaderFrequentlyPlayed": "تم تشغيله مراراً", "HeaderGenres": "أنواع الأفلام", "HeaderGuideProviders": "مزودو الأدلة", - "HeaderHttpHeaders": "رؤوس http", + "HeaderHttpHeaders": "رؤوس HTTP", "HeaderIdentification": "التعريفة", "HeaderIdentificationCriteriaHelp": "أدخل على الأقل معيار واحد للتعريف.", "HeaderIdentificationHeader": "رأس التعريفة", @@ -922,7 +922,7 @@ "ValueSpecialEpisodeName": "خاص - {0}", "HeaderFavoriteAlbums": "الألبومات المفضلة", "HeaderAlbumArtists": "فناني الألبومات", - "Genres": "الأنواع", + "Genres": "التضنيفات", "Folders": "المجلدات", "Favorites": "المفضلة", "Collections": "مجموعات", @@ -964,7 +964,7 @@ "AllEpisodes": "كل الحلقات", "AllComplexFormats": "جميع التنسيقات المعقدة (ASS ، SSA ، VOBSUB ، PGS ، SUB / IDX ، ...)", "AllChannels": "كل القنوات", - "Albums": "ألبومات", + "Albums": "البومات", "Aired": "عرضت", "AirDate": "تاريخ العرض", "AddedOnValue": "أضيفت", @@ -1151,5 +1151,8 @@ "DisplayInOtherHomeScreenSections": "عرض في أقسام الشاشة الرئيسية مثل أحدث الوسائط واستمر في المشاهدة", "DisplayInMyMedia": "عرض على الشاشة الرئيسية", "Display": "عرض", - "Dislike": "لم يعجبنى" + "Dislike": "لم يعجبنى", + "ButtonSyncPlay": "SyncPlay", + "ExtraLarge": "كبير جدا", + "EnableNextVideoInfoOverlayHelp": "في نهاية الفيديو, عرض معلومات عن الفيديو القادم في قائمة التشغيل." } diff --git a/src/strings/be-by.json b/src/strings/be-by.json index c3675b310e..28cf51bcde 100644 --- a/src/strings/be-by.json +++ b/src/strings/be-by.json @@ -19,5 +19,6 @@ "ThisWizardWillGuideYou": "Гэты памочнік правядзе вас праз усе фазы ўстаноўкі і налады. Спачатку абярыце упадабаную мову.", "UserProfilesIntro": "У Jellyfin існуе ўбудаваная падтрымка для карыстальніцкіх профіляў, дазваляючы кожнаму карыстальніку валодаць сваімі ўласнымі параметрамі адлюстравання, станам прайгравання і кіраваннем ўтрымання.", "WelcomeToProject": "Пачатак працы ў Jellyfin!", - "WizardCompleted": "Гэта ўсё, што нам трэба зараз. Jellyfin пачынае збіраць звесткі аб вашай медыятэцы. Азнаёмцеся пакуль з некаторымі нашымі праграмамі, а затым націсніце Гатова, каб праглядзець Инфопанель сервера." + "WizardCompleted": "Гэта ўсё, што нам трэба зараз. Jellyfin пачынае збіраць звесткі аб вашай медыятэцы. Азнаёмцеся пакуль з некаторымі нашымі праграмамі, а затым націсніце Гатова, каб праглядзець Инфопанель сервера.", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/bg-bg.json b/src/strings/bg-bg.json index 7d14080f70..71fdf80e32 100644 --- a/src/strings/bg-bg.json +++ b/src/strings/bg-bg.json @@ -1382,7 +1382,7 @@ "MessagePleaseWait": "Моля,изчакайте. Това може да отнеме минута.", "MessagePlayAccessRestricted": "Възпроизвеждането на това съдържание в момента е ограничено.Моля, свържете се с администратора на вашия сървър за повече информация.", "MessagePasswordResetForUsers": "Следните потребители са занулили паролите си.Те вече могат да влязат с пин кодовете, използвани за извършване на нулирането.", - "MessageNoTrailersFound": "Не са намерени трейлъри.За да подобрите филмовото изживяване инсталирайте канал за трейлъри,може да подредите няколко канала в библиотека.", + "MessageNoTrailersFound": "За да подобрите филмовото изживяване инсталирайте канал за трейлъри,може да подредите няколко канала в библиотека.", "MessageNoServersAvailable": "Не са намерени сървъри, използващи функцията за автоматично откриване на сървър.", "MessageNoMovieSuggestionsAvailable": "Понастоящем няма предложени филми. Започнете да гледате и оценявате филмите си, а след това се върнете, за да видите препоръките си.", "MessageNoCollectionsAvailable": "Колекциите ви позволяват да се наслаждавате на персонализирани групи от филми, сериали и албуми. Кликнете върху бутона +, за да започнете да създавате колекции.", @@ -1551,5 +1551,20 @@ "LabelSonyAggregationFlagsHelp": "Определя съдържанието на aggregationFlags елемента във urn:schemas-sonycom:av пространство от имена.", "LabelXDlnaDocHelp": "Определя съдържанието на X_DLNADOC елемента в urn:schemas-dlna-org:device-1-0 пространство от имена.", "LabelSkipForwardLength": "Време за придвижване напред:", - "LabelSkipBackLength": "Време за придвижване назад:" + "LabelSkipBackLength": "Време за придвижване назад:", + "LabelRepositoryUrlHelp": "Местоположението на манифеста на хранилището, което искате да включите.", + "MessageNoGenresAvailable": "Доставчиците на метаданни ще могат да изтеглят жанрове от интернет.", + "MessageAddRepository": "Ако искате да добавите хранилище, щракнете върху бутона до заглавната част и попълнете исканата информация.", + "LabelRepositoryNameHelp": "Персонализирано име за разграничаване на това хранилище от всички останали добавени към вашия сървър.", + "LabelRepositoryName": "Име на хранилището", + "LabelRepositoryUrl": "Адрес на хранилището", + "HeaderNewRepository": "Ново хранилище", + "MessageNoRepositories": "Няма хранилища.", + "EnableFasterAnimationsHelp": "Използвайте по-бързи анимации и преходи", + "EnableFasterAnimations": "Бързи анимации", + "EnableDecodingColorDepth10Vp9": "Включи 10 битово хардуерно декодиране за VP9", + "EnableDecodingColorDepth10Hevc": "Включи 10 битово хардуерно декодиране за HEVC", + "ButtonCast": "Стриймване", + "ButtonSyncPlay": "SyncPlay", + "TabRepositories": "Хранилища" } diff --git a/src/strings/ca.json b/src/strings/ca.json index df1cdf28f6..680be3ef77 100644 --- a/src/strings/ca.json +++ b/src/strings/ca.json @@ -818,5 +818,6 @@ "AllowFfmpegThrottling": "Transcodes de l’acceleració", "AllowOnTheFlySubtitleExtractionHelp": "Els subtítols incrustats es poden extreure de vídeos i entregar-los a clients en text senzill per tal d'evitar la transcodificació de vídeo. En alguns sistemes, això pot trigar molt i fer que la reproducció de vídeo s’aturi durant el procés d’extracció. Desactiveu-ho per tenir subtítols incrustats incrustats amb la transcodificació de vídeo quan no són compatibles amb el dispositiu client de forma nativa.", "AlbumArtist": "Album artista", - "Album": "Album" + "Album": "Album", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/cs.json b/src/strings/cs.json index 45a4643012..5299165415 100644 --- a/src/strings/cs.json +++ b/src/strings/cs.json @@ -1200,7 +1200,7 @@ "Wednesday": "Středa", "WelcomeToProject": "Vítejte v Jellyfin!", "WizardCompleted": "To je zatím vše, co potřebujeme. Server Jellyfin začal shromažďovat informace o vaší knihovně médií. Vyzkoušejte některé z našich aplikací a potom klikněte na tlačítko Dokončit pro zobrazení nástěnky.", - "Writer": "Napsal", + "Writer": "Scénárista", "XmlDocumentAttributeListHelp": "Tyto atributy jsou použity na kořenový prvek každé XML odpovědi.", "XmlTvKidsCategoriesHelp": "Programy s těmito kategoriemi budou zobrazeny jako programy pro děti. Více kategorií oddělte \"|\".", "XmlTvMovieCategoriesHelp": "Programy s těmito kategoriemi budou zobrazeny jako filmy. Více kategorií oddělte \"|\".", @@ -1231,7 +1231,7 @@ "AutoBasedOnLanguageSetting": "Automaticky (na základě jazykového nastavení)", "Banner": "Výřez plakátu", "BestFit": "Nejvhodnější", - "Blacklist": "Černá listina", + "Blacklist": "Zakázat vše kromě výjimek", "BobAndWeaveWithHelp": "Bob and weave (vyšší kvalita, ale pomalejší)", "Browse": "Procházet", "BurnSubtitlesHelp": "Určuje, zda má server při překódování videa vypálit titulky do obrazu. Tato funkce má velký negativní vliv na výkon. Chcete-li vypálit grafické formáty titulků (VOBSUB, PGS, SUB, IDX, atd.) a některé titulky ASS nebo SSA, vyberte možnost Automaticky.", @@ -1488,7 +1488,7 @@ "Vertical": "Svisle", "VideoRange": "Rozsah videa", "ViewPlaybackInfo": "Zobrazení informací o přehrávání", - "Whitelist": "Bílá listina", + "Whitelist": "Povolit vše kromě výjimek", "HeaderHome": "Domů", "DashboardOperatingSystem": "Operační systém: {0}", "DashboardArchitecture": "Architektura: {0}", @@ -1635,7 +1635,7 @@ "EnableBlurhashHelp": "Nenačtené obrázky budou zobrazeny pomocí neurčitých zástupných obrázků", "EnableBlurhash": "Povolit zástupné obrázky", "ButtonCast": "Přehrát v zařízení", - "ButtonSyncPlay": "Synchronizace přehrávání", + "ButtonSyncPlay": "SyncPlay", "MessageNoGenresAvailable": "Povolit některým poskytovatelům metadat stahovat informace o žánrech z Internetu.", "EnableFasterAnimationsHelp": "Použít rychlejší animace a přechody", "EnableFasterAnimations": "Rychlejší animace", @@ -1648,5 +1648,10 @@ "LabelRepositoryUrlHelp": "Umístění manifestu repozitáře, který chcete zahrnout.", "LabelRepositoryUrl": "URL adresa repozitáře", "HeaderNewRepository": "Nový repozitář", - "MessageNoRepositories": "Neexistují žádné repozitáře." + "MessageNoRepositories": "Neexistují žádné repozitáře.", + "ButtonPlayer": "Přehrávač", + "Writers": "Scénáristé", + "ClearQueue": "Vymazat frontu", + "StopPlayback": "Zastavit přehrávání", + "ViewAlbumArtist": "Zobrazit interpreta alba" } diff --git a/src/strings/da.json b/src/strings/da.json index 12b01f7da0..5e29e1574c 100644 --- a/src/strings/da.json +++ b/src/strings/da.json @@ -1608,5 +1608,6 @@ "Filter": "Filtrer", "New": "Nye", "ButtonTogglePlaylist": "Spilleliste", - "ButtonToggleContextMenu": "Mere" + "ButtonToggleContextMenu": "Mere", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/de.json b/src/strings/de.json index 2318cf8104..eda47a1c0d 100644 --- a/src/strings/de.json +++ b/src/strings/de.json @@ -10,7 +10,7 @@ "AddToPlaylist": "Zur Wiedergabeliste hinzufügen", "AddUser": "Benutzer anlegen", "AddedOnValue": "{0} hinzugefügt", - "AdditionalNotificationServices": "Durchsuche den Pluginkatalog, um weitere Benachrichtigungsdienste zu installieren.", + "AdditionalNotificationServices": "Durchsuchen sie den Pluginkatalog um weitere Benachrichtigungsdienste zu installieren.", "AirDate": "Erstausstrahlung", "Aired": "Ausgestrahlt", "Albums": "Alben", @@ -446,7 +446,7 @@ "HeaderTunerDevices": "Tuner", "HeaderTuners": "Tuner", "HeaderTypeText": "Texteingabe", - "HeaderUpcomingOnTV": "Bald im TV", + "HeaderUpcomingOnTV": "Demnächst im Fernsehen", "HeaderUploadImage": "Bild hochladen", "HeaderUser": "Benutzer", "HeaderUsers": "Benutzer", @@ -461,7 +461,7 @@ "Help": "Hilfe", "Hide": "Verstecke", "HideWatchedContentFromLatestMedia": "Verberge gesehene Inhalte von neuesten Medien", - "HttpsRequiresCert": "Um sichere Verbindungen zu ermöglichen, musst du ein vertrauenswürdiges SSL-Zertifikat, wie beispielsweise eines von Let's Encrypt, bereitstellen. Stelle bitte entweder ein Zertifikat zur Verfügung oder deaktiviere sichere Verbindungen.", + "HttpsRequiresCert": "Um https für externe Verbindungen zu erzwingen, benötigst du ein vertrauenswürdiges SSL-Zertifikat, z.B. von Let's Encrypt. Bitte stelle entweder ein Zertifikat bereit, oder deaktiviere sichere Verbindungen.", "Identify": "Identifizieren", "Images": "Bilder", "ImportFavoriteChannelsHelp": "Wenn aktiviert, werden nur auf dem Tuner favorisierte Kanäle importiert.", @@ -509,7 +509,7 @@ "LabelBlockContentWithTags": "Blockiere Inhalte mit Tags:", "LabelBurnSubtitles": "Untertitel einbrennen:", "LabelCachePath": "Cache Pfad:", - "LabelCachePathHelp": "Legen Sie ein eigenes Verzeichnis für den Server Zwischenspeicher fest (z.B. für Bilder). Lassen Sie dieses Feld leer um die Standardeinstellung zu verwenden.", + "LabelCachePathHelp": "Gib einen benutzerdefinierten Speicherort für Server-Cache-Dateien wie beispielsweise Bilder an. Lasse das Feld leer, um den Server-Standard zu verwenden.", "LabelCancelled": "Abgebrochen", "LabelCertificatePassword": "Zertifikat Passwort:", "LabelCertificatePasswordHelp": "Wenn Dein Zertifikat ein Passwort benötigt, gib es hier ein.", @@ -548,7 +548,7 @@ "LabelDisplayOrder": "Anzeigereihenfolge:", "LabelDisplaySpecialsWithinSeasons": "Zeige Sonderinhalt innerhalb der Staffel in der er ausgestrahlt wurde", "LabelDownMixAudioScale": "Audio Verstärkung bei Downmixing:", - "LabelDownMixAudioScaleHelp": "Erhöhe die Audiolautstärke beim Heruntermischen. Setze auf 1, um die ursprüngliche Lautstärke beizubehalten.", + "LabelDownMixAudioScaleHelp": "Erhöhe die Audiolautstärke beim Zusammenmischen zu Stereo. Setze den Wert auf 1 um die Originallautstärke zu erhalten.", "LabelDownloadLanguages": "Herunterzuladende Sprachen:", "LabelDropImageHere": "Fotos hierher ziehen oder klicken im zu browsen.", "LabelDropShadow": "Schlagschatten:", @@ -562,9 +562,9 @@ "LabelEnableDlnaClientDiscoveryInterval": "Client-Entdeckungs Intervall (Sekunden)", "LabelEnableDlnaClientDiscoveryIntervalHelp": "Ermittelt die Zeit in Sekunden zwischen SSDP Suchanfragen die durch Jellyfin ausgeführt wurden.", "LabelEnableDlnaDebugLogging": "Aktiviere DLNA Debug Logging", - "LabelEnableDlnaDebugLoggingHelp": "Erstellt große Logdateien und sollte nur bei Bedarf zur Fehlersuche verwendet werden.", + "LabelEnableDlnaDebugLoggingHelp": "Erzeugt große Logdateien und sollte nur zur Fehlerbehebung benutzt werden.", "LabelEnableDlnaPlayTo": "Aktiviere DLNA Play To", - "LabelEnableDlnaPlayToHelp": "Geräte in deinem Netzwerk erkennen und deren Fernsteuerung ermöglichen.", + "LabelEnableDlnaPlayToHelp": "Jellyfin kann Geräte in Ihrem Netzwerk erkennen und bietet die Möglichkeit, diese fernzusteuern.", "LabelEnableDlnaServer": "DLNA-Server aktivieren", "LabelEnableDlnaServerHelp": "Erlaubt UPnP Geräten in Ihrem Netzwerk den Zugriff und die Wiedergabe von Inhalten.", "LabelEnableHardwareDecodingFor": "Aktiviere Hardware-Decoding für:", @@ -577,14 +577,14 @@ "LabelEvent": "Ereignis:", "LabelEveryXMinutes": "Alle:", "LabelExtractChaptersDuringLibraryScan": "Erzeuge Kapitelbilder während des Bibliothekscans", - "LabelExtractChaptersDuringLibraryScanHelp": "Generiert Kapitelbilder während des Imports von Videos beim Bibliothekenscan erzeugt. Anderenfalls werden die Kapitelbilder während einer eigens dafür geplanten Aufgabe erstellt, was den regelmäßig Bibliothekenscan beschleunigt.", + "LabelExtractChaptersDuringLibraryScanHelp": "Falls aktiviert, werden die Kapitelbilder während des Imports von Videos beim Bibliothekenscan erzeugt. Falls deaktiviert, werden die Kapitelbilder während einer eigens dafür geplanten Aufgabe erstellt, was den regelmäßig Bibliothekenscan beschleunigt.", "LabelFailed": "Fehlgeschlagen", "LabelFileOrUrl": "Datei oder URL:", "LabelFinish": "Fertig", "LabelFont": "Schriftart:", "LabelForgotPasswordUsernameHelp": "Bitte gib deinen Benutzernamen ein, falls du dich daran erinnerst.", "LabelFriendlyName": "Benutzerfreundlicher Name:", - "LabelServerNameHelp": "Dieser Name wird benutzt um den Server zu identifizieren, normalerweise wird der Server-/Computername verwendet.", + "LabelServerNameHelp": "Dieser Name wird benutzt um den Server zu identifizieren, standardmäßig wird der Server-/Computername verwendet.", "LabelGroupMoviesIntoCollections": "Gruppiere Filme in Collections", "LabelGroupMoviesIntoCollectionsHelp": "Wenn Filmlisten angezeigt werden, dann werden Filme, die zu einer Collection gehören, als ein gruppiertes Element angezeigt.", "LabelEncoderPreset": "H264 Encoding Voreinstellung:", @@ -597,42 +597,42 @@ "LabelIconMaxHeight": "Maximale Iconhöhe:", "LabelIconMaxHeightHelp": "Maximale Auflösung für durch UPnP übermittelte Icons:icon.", "LabelIconMaxWidth": "Maximale Iconbreite:", - "LabelIconMaxWidthHelp": "Maximale Auflösung für durch UPnP übermittelte Icons:icon.", + "LabelIconMaxWidthHelp": "Maximale Auflösung der Icons, die über upnp:icon angezeigt werden.", "LabelIdentificationFieldHelp": "Ein Teilstring oder Regex Ausdruck, der keine Groß- und Kleinschreibung berücksichtigt.", "LabelImageFetchersHelp": "Aktiviere und ordne deine bevorzugten Bildquellen nach Präferenzen.", "LabelImageType": "Bildtyp:", "LabelImportOnlyFavoriteChannels": "Beschränke auf favorisierte Kanäle", "LabelInNetworkSignInWithEasyPassword": "Schalte Login mit einfachen Passwort für das eigene Netzwerk ein", - "LabelInNetworkSignInWithEasyPasswordHelp": "Wenn aktiviert, können Sie sich in ihrem eigenen Netzwerk mit dem vereinfachten PIN bei Jellyfin Apps anmelden. Ihr reguläres Kennwort wird nur benötigt, wenn Sie unterwegs sind. Wenn Sie den PIN frei lassen, so benötigen Sie in Ihrem Netzwerk keinen PIN.", + "LabelInNetworkSignInWithEasyPasswordHelp": "Einfachen Pin verwenden, um sich bei Jellyfin Apps im lokalen Netzwerk anzumelden. Ihr reguläres Kennwort wird nur benötigt, wenn Sie unterwegs sind. Wenn Sie den PIN frei lassen, so benötigen Sie in Ihrem Netzwerk keinen PIN.", "LabelInternetQuality": "Internetqualität:", "LabelKeepUpTo": "Fortführen:", "LabelKidsCategories": "Kinderkategorien:", "LabelKodiMetadataDateFormat": "Veröffentlichungsdatum Format:", - "LabelKodiMetadataDateFormatHelp": "Alle Daten innerhalb von NFO-Dateien werden in diesem Format analysiert.", - "LabelKodiMetadataEnableExtraThumbs": "Kopiere Extrafanart in Extrathumbs", + "LabelKodiMetadataDateFormatHelp": "Alle Daten innerhalb von NFO-Dateien werden in diesem Format gelesen.", + "LabelKodiMetadataEnableExtraThumbs": "Kopiere Extra-Fanart- nach Extra-Vorschau-Feld", "LabelKodiMetadataEnableExtraThumbsHelp": "Beim downloaden von Bildern können diese sowohl als Extrafanart als auch als Extrathumb gespeichert werden, um maximale Kodi Kompatibilität zu erzielen.", "LabelKodiMetadataEnablePathSubstitution": "Aktiviere Pfadersetzung", "LabelKodiMetadataEnablePathSubstitutionHelp": "Aktiviert die Pfadersetzung für Bildpfade durch Benutzung der Server Pfadersetzung Einstellungen.", "LabelKodiMetadataSaveImagePaths": "Speicher Bildpfade innerhalb der NFO Dateien", "LabelKodiMetadataSaveImagePathsHelp": "Dies ist empfehlenswert wenn du Dateinamen hast, die nicht den Kodi Richtlinien entsprechen.", - "LabelKodiMetadataUser": "Speichere den \"Gesehen\" Status von Benutzern in NFO's für:", - "LabelKodiMetadataUserHelp": "Aktivieren, um den \"Gesehen\" Status in NFO-Dateien zu speichern, damit diese von anderen Anwendungen verwendet werden können.", + "LabelKodiMetadataUser": "Speichere den \"Gesehen\" Status von Benutzern in NFO-Dateien für:", + "LabelKodiMetadataUserHelp": "\"Gesehen\" Status in NFO-Dateien speichern, damit diese von anderen Anwendungen verwendet werden können.", "LabelLanNetworks": "Lokale Netzwerke:", "LabelLanguage": "Sprache:", "LabelLineup": "TV Programm:", "LabelLocalHttpServerPortNumber": "Lokale HTTP Portnummer:", - "LabelLocalHttpServerPortNumberHelp": "Die TCP Port Nummer, auf die der Jellyfin http Server hört.", + "LabelLocalHttpServerPortNumberHelp": "Die TCP-Portnummer, die der HTTP-Server von Jellyfin verwenden soll.", "LabelLockItemToPreventChanges": "Sperre diesen Eintrag um zukünftige Änderungen zu verhindern", "LabelLoginDisclaimer": "Anmeldung Haftungsausschluss:", - "LabelLoginDisclaimerHelp": "Dies wird am Boden des Anmeldebildschirms angezeigt.", + "LabelLoginDisclaimerHelp": "Diese Nachricht wird am unteren Ende des Anmeldebildschirms angezeigt.", "LabelManufacturer": "Hersteller:", - "LabelManufacturerUrl": "Hersteller URL", + "LabelManufacturerUrl": "Hersteller-URL", "LabelMatchType": "Übereinstimmungstyp:", "LabelMaxBackdropsPerItem": "Maximale Anzahl von Hintergründen pro Element:", "LabelMaxChromecastBitrate": "Max Chromcast Datenrate:", "LabelMaxParentalRating": "Höchste erlaubte elterlich Bewertung:", "LabelMaxResumePercentage": "Maximale Prozent für Wiederaufnahme:", - "LabelMaxResumePercentageHelp": "Titel werden als \"vollständig gesehen\" markiert, wenn sie nach dieser Zeitmarke gestoppt werden.", + "LabelMaxResumePercentageHelp": "Titel werden als vollständig gesehen markiert, wenn sie nach dieser Zeit gestoppt werden.", "LabelMaxScreenshotsPerItem": "Maximale Anzahl von Screenshots pro Element:", "LabelMaxStreamingBitrate": "Maximale Streaming-Qualität:", "LabelMaxStreamingBitrateHelp": "Wähle die maximale Bitrate während des streamens.", @@ -645,12 +645,12 @@ "LabelMetadataPathHelp": "Wähle ein Verzeichnis, für die heruntergeladenen Artworks und Metadaten.", "LabelMetadataReaders": "Metadatenleser:", "LabelMetadataReadersHelp": "Lege deine bevorzugte lokale Metadatenquelle fest und ordne sie nach Prioritäten. Die erste Datei die gefunden wird, wird verwendet.", - "LabelMetadataSavers": "Metadatenspeicherer:", - "LabelMetadataSaversHelp": "Wähle das Dateiformat in dem deine Metadaten gespeichert werden sollen.", + "LabelMetadataSavers": "Metadaten-Speicherer:", + "LabelMetadataSaversHelp": "Wähle das Dateiformat, in dem deine Metadaten gespeichert werden sollen.", "LabelMethod": "Methode:", "LabelMinBackdropDownloadWidth": "Minimale Breite für zu herunterladende Hintergründe:", "LabelMinResumeDuration": "Minimale Dauer für Wiederaufnahme:", - "LabelMinResumeDurationHelp": "Die Videolänge in Sekunden, ab der die Wiedergabeposition gespeichert wird und dich fortsetzen lässt.", + "LabelMinResumeDurationHelp": "Die kürzeste Videolänge in Sekunden, die den Wiedergabeposition speichert und dich fortsetzen lässt.", "LabelMinResumePercentage": "Minimale Prozent für Wiederaufnahme:", "LabelMinResumePercentageHelp": "Titel werden als \"Ungesehen\" eingetragen, wenn sie vor dieser Zeit gestoppt werden.", "LabelMinScreenshotDownloadWidth": "Minimale Breite für zu herunterladende Screenshot:", @@ -661,7 +661,7 @@ "LabelMonitorUsers": "Überwache Aktivität von:", "LabelMovieCategories": "Filmkategorien:", "LabelMoviePrefix": "Filmpräfix:", - "LabelMoviePrefixHelp": "Wenn ein Präfix in Filmtiteln angewendet wird, gib es hier ein damit Jellyfin es korrekt behandeln kann.", + "LabelMoviePrefixHelp": "Wenn ein Präfix in Filmtiteln angewendet wird, gib es hier ein damit der Server es korrekt behandeln kann.", "LabelMovieRecordingPath": "Film Aufnahmepfad (Optional):", "LabelMusicStreamingTranscodingBitrate": "Musik-Transkodierung Bitrate:", "LabelMusicStreamingTranscodingBitrateHelp": "Wähle die maximale Bitrate für das streamen von Musik.", @@ -767,7 +767,7 @@ "LabelTitle": "Titel:", "LabelTrackNumber": "Stück Nummer:", "LabelTranscodingAudioCodec": "Audio Codec:", - "LabelTranscodingTempPathHelp": "Dieses Verzeichnis beinhaltet Dateien die für den Betrieb des Transcoders benutzt werden. Wähle einen eigenen Pfad oder lasse das Feld frei, um den Standardspeicherort im Server Datenverzeichnis zu nutzen.", + "LabelTranscodingTempPathHelp": "Wähle einen eigenen Pfad für transkodierte Dateien. Lasse das Feld frei, um den Standardspeicherort zu nutzen.", "LabelTranscodingThreadCount": "Anzahl Transkodierungs-Threads:", "LabelTranscodingThreadCountHelp": "Legen Sie die maximale Anzahl von Transkodierungs-Threads fest. Das Reduzieren der Thread-Anzahl verringert die CPU Auslastung, wird aber möglicherweise die Transkodierung nicht schnell genug für eine störungsfrei Wiedergabe ermöglichen.", "LabelTranscodingVideoCodec": "Video Codec:", @@ -801,7 +801,7 @@ "Large": "Groß", "LatestFromLibrary": "Neueste {0}", "LearnHowYouCanContribute": "Erfahre, wie du unterstützen kannst.", - "LibraryAccessHelp": "Wähle die Medienverzeichnisse die du mit diesem Benutzer teilen möchtest. Administratoren können den Metadaten-Manager verwenden um alle Ordner zu bearbeiten.", + "LibraryAccessHelp": "Wähle die Bibliotheken aus, die du mit diesem Benutzer teilen möchtest. Administratoren können den Metadaten-Manager verwenden um alle Ordner zu bearbeiten.", "Like": "Mag ich", "List": "Liste", "LiveBroadcasts": "Liveübertragungen", @@ -841,7 +841,7 @@ "MessageConfirmRemoveMediaLocation": "Bist du dir sicher diese Medienquelle entfernen zu wollen?", "MessageConfirmRestart": "Möchten Sie Jellyfin Server wirklich neu starten?", "MessageConfirmRevokeApiKey": "Möchten Sie diesen API Schlüssel wirklich löschen? Die Verbindung der Anwendung zum Jellyfin Server wird sofort unterbrochen.", - "MessageConfirmShutdown": "Möchsten Sie Jellyfin Server wirklich beenden?", + "MessageConfirmShutdown": "Möchten Sie den Server wirklich herunterfahren?", "MessageContactAdminToResetPassword": "Bitte kontaktiere deinen Systemadministrator, um dein Passwort zurücksetzen zu lassen.", "MessageCreateAccountAt": "Erstellen Sie ein Konto bei {0}", "MessageDeleteTaskTrigger": "Bist du dir sicher, dass du diesen Aufgabenauslöser entfernen möchtest?", @@ -887,7 +887,7 @@ "MoreUsersCanBeAddedLater": "Weitere Benutzer können später über das Dashboard hinzugefügt werden.", "MoveLeft": "Nach links bewegen", "MoveRight": "Nach rechts bewegen", - "MovieLibraryHelp": "Überprüfe den {0}Filmbenennungsguide{1}.", + "MovieLibraryHelp": "Überprüfe den {0}Filmbenennungsleitfaden{1}.", "Movies": "Filme", "Mute": "Stumm", "MySubtitles": "Meine Untertitel", @@ -1122,7 +1122,7 @@ "SearchForMissingMetadata": "Suche nach fehlenden Metadaten", "SearchForSubtitles": "Suche nach Untertiteln", "SearchResults": "Suchergebnisse", - "SendMessage": "Sende Nachricht", + "SendMessage": "Nachricht senden", "Series": "Serien", "SeriesCancelled": "Serie abgebrochen.", "SeriesDisplayOrderHelp": "Sortiere Episoden nach Ausstrahlungsdatum, DVD Reihenfolge oder absoluter Nummerierung.", @@ -1222,7 +1222,7 @@ "TrackCount": "{0} Titel", "Trailers": "Trailer", "Tuesday": "Dienstag", - "TvLibraryHelp": "Überprüfe den {0}Serienbenennungsguide{1}.", + "TvLibraryHelp": "Überprüfe den {0}Serienbenennungsleitfaden{1}.", "Uniform": "Einheitlich", "UninstallPluginConfirmation": "Möchtest du {0} wirklich deinstallieren?", "UninstallPluginHeader": "Plugin deinstallieren", @@ -1232,7 +1232,7 @@ "Up": "Hoch", "Upload": "Hochladen", "UserAgentHelp": "Stelle einen benutzerdefinierten User-Agent HTTP header zur Verfügung.", - "UserProfilesIntro": "Jellyfin bietet die Unterstützung von Benutzerprofilen, mit eigenen Ansichten, Altersfreigaben und Spielstände von Medien.", + "UserProfilesIntro": "Jellyfin bietet Unterstützung für Benutzerprofile mit eigenen Ansichtseinstellungen, Wiedergabepositionen und Altersfreigaben.", "ValueAlbumCount": "{0} Alben", "ValueConditions": "Bedingungen: {0}", "ValueEpisodeCount": "{0} Episoden", @@ -1321,7 +1321,7 @@ "LabelVersion": "Version:", "LabelVersionNumber": "Version {0}", "LabelVideo": "Video", - "LeaveBlankToNotSetAPassword": "Du kannst dieses Feld frei lassen um kein Passwort zu setzen.", + "LeaveBlankToNotSetAPassword": "Dieses Feld frei lassen, um kein Passwort zu setzen.", "LinksValue": "Links: {0}", "MessageImageFileTypeAllowed": "Nur JPEG- und PNG-Dateien werden unterstützt.", "MessageImageTypeNotSelected": "Bitte wähle einen Bildtyp aus dem Drop-Down Menü aus.", @@ -1396,7 +1396,7 @@ "Thumb": "Miniaturansicht", "TitleSupport": "Hilfe", "Whitelist": "Erlaubt", - "AuthProviderHelp": "Wähle einen Authentifizierungsanbieter aus, der zur Authentifizierung des Passworts dieses Benutzers verwendet werden soll.", + "AuthProviderHelp": "Wähle einen Authentifizierungsanbieter, der zur Authentifizierung des Passworts dieses Benutzes verwendet werden soll.", "Features": "Funktionen", "HeaderFavoriteBooks": "Lieblingsbücher", "HeaderFavoriteMovies": "Lieblingsfilme", @@ -1433,7 +1433,7 @@ "LabelAudioBitrate": "Tonbitrate:", "ButtonAddImage": "Bild hinzufügen", "LabelSize": "Größe:", - "LabelTranscodes": "Transkoder:", + "LabelTranscodes": "Transcodiert:", "LabelTranscodingProgress": "Transcodierungsfortschritt:", "LabelAudioBitDepth": "Audio-Bittiefe:", "LabelPleaseRestart": "Die Änderungen werden nach dem manuellen Neuladen des Webclients wirksam.", @@ -1456,7 +1456,7 @@ "MessageNoServersAvailable": "Die automatische Serversuche konnte keinen Server finden.", "LabelPlayer": "Schauspieler:", "MediaInfoCodecTag": "Codec Tag", - "SubtitleOffset": "Untertitelvorlauf", + "SubtitleOffset": "Untertitel-Synchronisierung", "PlaybackData": "Wiedergabeinformationen", "OptionThumbCard": "Vorschaukarte", "OptionPosterCard": "Posterkarte", @@ -1469,8 +1469,8 @@ "OptionRandom": "Zufällig", "TabNetworking": "Netzwerk", "VideoRange": "Videobereich", - "ButtonSplit": "Aufteilen", - "SelectAdminUsername": "Bitte einen Benutzernamen für das Administrator-Konto auswählen.", + "ButtonSplit": "Trennen", + "SelectAdminUsername": "Bitte wählen Sie einen Benutzernamen für den Administrator-Account.", "HeaderNavigation": "Navigation", "CopyStreamURLError": "Beim Kopieren der URL ist ein Fehler aufgetreten.", "MessageConfirmAppExit": "Wirklich verlassen?", @@ -1547,7 +1547,7 @@ "MessageSyncPlayGroupDoesNotExist": "Konnte der Gruppe nicht beitreten, da sie nicht existiert.", "MessageSyncPlayPlaybackPermissionRequired": "Wiedergabegenehmigung erforderlich.", "MessageSyncPlayNoGroupsAvailable": "Keine Gruppen verfügbar. Fange an, etwas abzuspielen.", - "MessageSyncPlayGroupWait": "{0} ist am laden...", + "MessageSyncPlayGroupWait": "{0} ist am laden…", "MessageSyncPlayUserLeft": "{0} hat die Gruppe verlassen.", "MessageSyncPlayUserJoined": "{0} ist der Gruppe beigetreten.", "MessageSyncPlayDisabled": "SyncPlay deaktiviert.", @@ -1586,5 +1586,10 @@ "LabelRepositoryName": "Name des Repository", "LabelRepositoryUrl": "URL des Repository", "HeaderNewRepository": "Neues Repository", - "MessageNoRepositories": "Keine Repositories." + "MessageNoRepositories": "Keine Repositories.", + "ButtonPlayer": "Player", + "Writers": "Autoren", + "ClearQueue": "Wiedergabeliste leeren", + "StopPlayback": "Wiedergabe anhalten", + "ViewAlbumArtist": "Zeige Albumkünstler" } diff --git a/src/strings/el.json b/src/strings/el.json index 3137f8682a..24fd7c0934 100644 --- a/src/strings/el.json +++ b/src/strings/el.json @@ -1234,5 +1234,6 @@ "AllowFfmpegThrottlingHelp": "Όταν ένας διακωδικοποιητής ή remux φτάσει αρκετά μπροστά από την τρέχουσα θέση αναπαραγωγής, διακόψτε τη διαδικασία ώστε να καταναλώσει λιγότερους πόρους. Αυτό είναι πιο χρήσιμο όταν παρακολουθείτε χωρίς να αναζητάτε συχνά. Απενεργοποιήστε το εάν αντιμετωπίζετε προβλήματα αναπαραγωγής.", "ButtonTogglePlaylist": "Λίστα αναπαραγωγής", "ButtonToggleContextMenu": "Περισσότερα", - "ButtonSplit": "Διαχωρισμός" + "ButtonSplit": "Διαχωρισμός", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/en-gb.json b/src/strings/en-gb.json index d9e6055d62..8b63def2a2 100644 --- a/src/strings/en-gb.json +++ b/src/strings/en-gb.json @@ -1574,5 +1574,10 @@ "EnableDetailsBannerHelp": "Display a banner image at the top of the item details page.", "EnableDetailsBanner": "Details Banner", "EnableDecodingColorDepth10Vp9": "Enable 10-Bit hardware decoding for VP9", - "EnableDecodingColorDepth10Hevc": "Enable 10-Bit hardware decoding for HEVC" + "EnableDecodingColorDepth10Hevc": "Enable 10-Bit hardware decoding for HEVC", + "ViewAlbumArtist": "View album artist", + "ClearQueue": "Clear queue", + "StopPlayback": "Stop playback", + "ButtonPlayer": "Player", + "Writers": "Writers" } diff --git a/src/strings/en-us.json b/src/strings/en-us.json index fc3883963c..c1ea50431d 100644 --- a/src/strings/en-us.json +++ b/src/strings/en-us.json @@ -1054,7 +1054,7 @@ "MessageSyncPlayDisabled": "SyncPlay disabled.", "MessageSyncPlayUserJoined": "{0} has joined the group.", "MessageSyncPlayUserLeft": "{0} has left the group.", - "MessageSyncPlayGroupWait": "{0} is buffering...", + "MessageSyncPlayGroupWait": "{0} is buffering…", "MessageSyncPlayNoGroupsAvailable": "No groups available. Start playing something first.", "MessageSyncPlayPlaybackPermissionRequired": "Playback permission required.", "MessageSyncPlayGroupDoesNotExist": "Failed to join group because it does not exist.", @@ -1527,7 +1527,7 @@ "Vertical": "Vertical", "VideoRange": "Video range", "ViewAlbum": "View album", - "ViewArtist": "View artist", + "ViewAlbumArtist": "View album artist", "ViewPlaybackInfo": "View playback info", "Watched": "Watched", "Wednesday": "Wednesday", @@ -1535,6 +1535,7 @@ "Whitelist": "Whitelist", "WizardCompleted": "That's all we need for now. Jellyfin has begun collecting information about your media library. Check out some of our apps, and then click Finish to view the Dashboard.", "Writer": "Writer", + "Writers": "Writers", "XmlDocumentAttributeListHelp": "These attributes are applied to the root element of every XML response.", "XmlTvKidsCategoriesHelp": "Programs with these categories will be displayed as programs for children. Separate multiple with '|'.", "XmlTvMovieCategoriesHelp": "Programs with these categories will be displayed as movies. Separate multiple with '|'.", @@ -1561,5 +1562,8 @@ "EnableBlurhash": "Enable blurred placeholders for images", "EnableBlurhashHelp": "Images that are still being loaded will be displayed with a blurred placeholder", "ButtonSyncPlay": "SyncPlay", - "ButtonCast": "Cast" + "ButtonCast": "Cast", + "ButtonPlayer": "Player", + "StopPlayback": "Stop playback", + "ClearQueue": "Clear queue" } diff --git a/src/strings/eo.json b/src/strings/eo.json index 5f0e658efa..e2eebac174 100644 --- a/src/strings/eo.json +++ b/src/strings/eo.json @@ -1,5 +1,24 @@ { "AddToCollection": "Aldoni al kolekto", "Actor": "Aktoro", - "Absolute": "Absoluta" + "Absolute": "Absoluta", + "ButtonSyncPlay": "SyncPlay", + "AllLanguages": "Ĉiuj lingvoj", + "AllEpisodes": "ĉiuj epizodoj", + "AllComplexFormats": "Ĉiuj Kompleksaj Formatoj (ASS, SSA, VOBSUB, PGS, SUB, IDX, ...)", + "AllChannels": "Ĉiuj kanaloj", + "All": "Ĉiuj", + "Alerts": "Alertoj", + "Albums": "Albumoj", + "AlbumArtist": "Albumo-Artisto", + "Album": "albumo", + "Aired": "Aerumita", + "AirDate": "Aera dato", + "AdditionalNotificationServices": "Foliumu la kromprogramon por instali aldonajn sciigajn servojn.", + "AddedOnValue": "aldonis {0}", + "AddToPlaylist": "aldoni al playlist", + "AddToPlayQueue": "Aldonu ludi voston", + "AddItemToCollectionHelp": "Aldonu erojn al kolektoj serĉante ilin kaj uzante ĝian alklakon aŭ frapetu menuojn por aldoni ilin al kolekto.", + "Add": "Aldoni", + "AccessRestrictedTryAgainLater": "Aliro nuntempe estas restriktita. Bonvolu reprovi poste." } diff --git a/src/strings/es-ar.json b/src/strings/es-ar.json index 388be4fd25..d4030f13ff 100644 --- a/src/strings/es-ar.json +++ b/src/strings/es-ar.json @@ -414,7 +414,7 @@ "HeaderAppearsOn": "Aparece en", "HeaderApp": "Aplicación", "HeaderApiKeysHelp": "Se requiere que las aplicaciones externas tengan una clave de API para comunicarse con el servidor Jellyfin. Las claves se emiten iniciando sesión con una cuenta Jellyfin, u otorgando manualmente una clave a la aplicación.", - "HeaderApiKeys": "Llaves API", + "HeaderApiKeys": "Claves de API", "HeaderApiKey": "Contraseña API", "HeaderAllowMediaDeletionFrom": "Permitir el borrado de medios desde", "HeaderAlert": "Alerta", @@ -686,7 +686,7 @@ "LabelCertificatePasswordHelp": "Si su certificado requiere una contraseña, ingrésela aquí.", "LabelCertificatePassword": "Contraseña del certificado:", "LabelCancelled": "Cancelado", - "LabelCachePath": "Ruta de caché:", + "LabelCachePath": "Ruta a la caché:", "LabelCache": "Caché:", "LabelBurnSubtitles": "Grabar subtítulos:", "LabelAudioBitDepth": "Profundidad de bits de audio:", @@ -942,7 +942,7 @@ "LabelMetadataReadersHelp": "Clasifique sus fuentes de metadatos locales preferidas en orden de prioridad. Se leerá el primer archivo encontrado.", "LabelMetadataReaders": "Lectores de metadatos:", "LabelMetadataPathHelp": "Especifique una ubicación personalizada para las ilustraciones y los metadatos descargados.", - "LabelMetadataPath": "Ruta de metadatos:", + "LabelMetadataPath": "Ruta a los metadatos:", "LabelMetadataDownloadersHelp": "Habilite y clasifique sus descargadores de metadatos preferidos en orden de prioridad. Los descargadores de menor prioridad solo se utilizarán para completar la información que falta.", "LabelMetadataDownloadLanguage": "Idioma de descarga preferido:", "LabelMetadata": "Metadatos:", @@ -1190,7 +1190,7 @@ "LabelTunerIpAddress": "Dirección IP del sintonizador:", "LabelTriggerType": "Tipo de disparador:", "LabelTranscodingVideoCodec": "Códec de vídeo:", - "LabelTranscodingThreadCountHelp": "Seleccione el número máximo de hilos para usar al transcodificar. Reducir el recuento de hilos disminuirá el uso de la CPU, pero es posible que no se convierta lo suficientemente rápido para una experiencia de reproducción fluida.", + "LabelTranscodingThreadCountHelp": "Elija el número máximo de hilos para usar al transcodificar. Reducir el recuento de hilos disminuirá el uso de la CPU, pero es posible que no se convierta lo suficientemente rápido para una experiencia de reproducción fluida.", "LabelTranscodingThreadCount": "Conteo de hilos de transcodificación:", "LabelTranscodingProgress": "Progreso de transcodificación:", "LabelTranscodingFramerate": "Velocidad de fotogramas de transcodificación:", @@ -1648,5 +1648,10 @@ "Runtime": "Tiempo de ejecución", "RunAtStartup": "Ejecutar en el arranque", "Rewind": "Rebobinar", - "ResumeAt": "Reanudar desde {0}" + "ResumeAt": "Reanudar desde {0}", + "ButtonPlayer": "Reproductor", + "Writers": "Escritores", + "ClearQueue": "Eliminar cola", + "StopPlayback": "Detener reproducción", + "ViewAlbumArtist": "Ver artista del álbum" } diff --git a/src/strings/es-mx.json b/src/strings/es-mx.json index f7762e396e..ca4973bd71 100644 --- a/src/strings/es-mx.json +++ b/src/strings/es-mx.json @@ -1066,7 +1066,7 @@ "OptionReportByteRangeSeekingWhenTranscodingHelp": "Esto es requerido para algunos dispositivos que no pueden hacer búsquedas de tiempo muy bien.", "OptionRequirePerfectSubtitleMatch": "Solo descargar subtítulos que coincidan perfectamente con mis archivos de video", "OptionRequirePerfectSubtitleMatchHelp": "Solicitar una coincidencia perfecta filtrará los subtítulos para incluir solo aquellos que han sido probados y verificados exactamente con tu archivo de video. Desmarcar esta opción incrementará las probabilidades de que se descarguen subtítulos, pero incrementará las posibilidades de obtener subtítulos mal sincronizados o con texto incorrecto.", - "OptionResElement": "elemento res", + "OptionResElement": "Elemento res", "OptionResumable": "Reanudable", "OptionRuntime": "Duración", "OptionSaturday": "Sábado", @@ -1424,7 +1424,7 @@ "ValueSeriesCount": "{0} series", "Vertical": "Vertical", "OptionThumb": "Miniatura", - "OptionThumbCard": "Tarjeta miniatura", + "OptionThumbCard": "Miniatura", "HeaderFavoriteBooks": "Libros favoritos", "LabelPleaseRestart": "Los cambios tendrán efecto después de recargar manualmente el cliente web.", "LabelPlayMethod": "Método de reproducción:", @@ -1487,7 +1487,7 @@ "HeaderFavoritePeople": "Personas favoritas", "Episode": "Episodio", "ClientSettings": "Configuración del cliente", - "BoxSet": "Box Set", + "BoxSet": "Colección", "AskAdminToCreateLibrary": "Pide a un administrador crear una biblioteca.", "Artist": "Artista", "AllowFfmpegThrottlingHelp": "Cuando una transcodificación o remuxeado se adelanta lo suficiente de la posición de reproducción actual, se pausa el proceso para que consuma menos recursos. Esto es más útil cuando se mira sin buscar con frecuencia. Apaga esto si experimentas problemas de reproducción.", @@ -1521,7 +1521,7 @@ "HeaderHttpsSettings": "Opciones HTTPS", "HeaderDVR": "DVR", "ApiKeysCaption": "Lista de claves API actualmente habilitadas", - "SyncPlayAccessHelp": "Selecciona el nivel de acceso que este usuario tiene a la función SyncPlay. SyncPlay permite sincronizar la reproducción con otros dispositivos.", + "SyncPlayAccessHelp": "Selecciona el nivel de acceso que este usuario tiene en la función SyncPlay. SyncPlay permite sincronizar la reproducción con otros dispositivos.", "MessageSyncPlayErrorMedia": "¡Fallo al activar SyncPlay! Error en el archivo de medios.", "MessageSyncPlayErrorMissingSession": "¡Fallo al activar SyncPlay! Falta la sesión.", "MessageSyncPlayErrorNoActivePlayer": "No se ha encontrado ningún reproductor activo. SyncPlay ha sido desactivado.", @@ -1552,5 +1552,29 @@ "HeaderSyncPlayEnabled": "SyncPlay habilitado", "HeaderSyncPlaySelectGroup": "Unirse a un grupo", "EnableDetailsBannerHelp": "Mostrar una imagen banner en la parte superior de la página de detalles del elemento.", - "EnableDetailsBanner": "Banner de detalles" + "EnableDetailsBanner": "Banner de detalles", + "ButtonSyncPlay": "SyncPlay", + "ButtonPlayer": "Reproductor", + "ButtonCast": "Elenco", + "EnableBlurhashHelp": "Imágenes que aún están siendo cargadas serán mostradas difuminadas", + "EnableBlurhash": "Habilitar imágenes de fondo difuminadas", + "TabRepositories": "Repositorios", + "ShowMore": "Mostrar más", + "ShowLess": "Mostrar menos", + "MessageNoGenresAvailable": "Habilitar algunos proveedores de metadatos para traer los generos desde internet.", + "MessageAddRepository": "Si desea agregar un repositorio, haz click en el botón junto al encabezado y completa la información requerida.", + "LabelRepositoryNameHelp": "Un nombre personalizado para distinguir este repositorio de otros añadidos a tu servidor.", + "LabelRepositoryName": "Nombre del repositorio", + "LabelRepositoryUrlHelp": "La ubicación del repositorio que desea agregar.", + "LabelRepositoryUrl": "URL del repositorio", + "HeaderNewRepository": "Nuevo repositorio", + "MessageNoRepositories": "Sin repositorios.", + "EnableFasterAnimationsHelp": "Usar animaciones y transiciones más rapidas", + "EnableFasterAnimations": "Animaciones más rápidas", + "EnableDecodingColorDepth10Vp9": "Habilitar la decodificación por hardware de 10 bit para VP9", + "EnableDecodingColorDepth10Hevc": "Habilitar la decodificación por hardware de 10 bit para HEVC", + "ClearQueue": "Limpiar cola", + "StopPlayback": "Detener reproducción", + "Writers": "Escritores", + "ViewAlbumArtist": "Ver el artista del album" } diff --git a/src/strings/es.json b/src/strings/es.json index f55994eee1..640a51d634 100644 --- a/src/strings/es.json +++ b/src/strings/es.json @@ -192,7 +192,7 @@ "ExitFullscreen": "Quitar pantalla completa", "ExtraLarge": "Extragrande", "ExtractChapterImagesHelp": "La extracción de imágenes de capítulos permitirá a los clientes mostrar gráficamente la selección de escenas. El proceso puede ser lento, intensivo en recursos y requerir varios gigabytes de espacio. Se ejecuta cuando se añaden vídeos y también como tarea programable por la noche. El horario es configurable en el área de tareas programadas. No se recomienda ejecutar esta tarea durante las horas pico de uso.", - "FFmpegSavePathNotFound": "No podemos localizar FFmpeg usando la ruta que has ingresado. FFprobe también es necesario y debe existir en la misma carpeta. Estos componentes normalmente se agrupan juntos en la misma descarga. Compruebe la ruta y vuelva a intentarlo.", + "FFmpegSavePathNotFound": "No se ha podido localizar ffmpeg ni ffprobe en la ruta especificada. Comprueba la ruta y vuelva a intentarlo.", "FastForward": "Avanzar rápido", "Favorite": "Favorito", "Favorites": "Favoritos", @@ -249,7 +249,7 @@ "HeaderChannels": "Canales", "HeaderChapterImages": "Imágenes de capítulos", "HeaderCodecProfile": "Perfil de códec", - "HeaderCodecProfileHelp": "Perfiles de códec indican las limitaciones de un dispositivo cuando se reproducen códecs específicos. Si se aplica una limitación entonces el medio se transcodificará, incluso si el códec está configurado para reproducción directa.", + "HeaderCodecProfileHelp": "Los perfiles de los códecs indican las limitaciones de un dispositivo cuando reproduce un códec en específico. Si lo que se va a reproducir no está dentro de estos límites (por ejemplo, bitrate demasiado alto), el contenido se convertirá, incluso si el códec está configurado para reproducción directa.", "HeaderConfigureRemoteAccess": "Configurar acceso remoto", "HeaderConfirmPluginInstallation": "Confirmar la instalación del complemento", "HeaderConfirmProfileDeletion": "Confirmar borrado del perfil", @@ -257,7 +257,7 @@ "HeaderConnectToServer": "Conectar al servidor", "HeaderConnectionFailure": "Fallo de conexión", "HeaderContainerProfile": "Perfil de contenedor", - "HeaderContainerProfileHelp": "Perfiles de códec indican las limitaciones de un dispositivo mientras reproduce formatos específicos. Si se aplica una limitación entonces el medio se transcodificará, incluso si el formato está configurado para reproducción directa.", + "HeaderContainerProfileHelp": "Los perfiles de los contenedores indican las limitaciones de un dispositivo cuando reproduce contenido en un formato en específico. Si lo que se va a reproducir no está dentro de estos límites, el contenedor del contenido se cambiará, incluso si el formato está configurado para reproducción directa.", "HeaderContinueListening": "Continuar escuchando", "HeaderContinueWatching": "Continuar viendo", "HeaderCustomDlnaProfiles": "Perfiles personalizados", @@ -375,7 +375,7 @@ "HeaderSelectServer": "Selecionar servidor", "HeaderSelectServerCachePath": "Seleccione la ruta para el caché del servidor", "HeaderSelectServerCachePathHelp": "Navega o introduce la ruta para alojar los archivos caché del servidor. Tienes que tener permisos de escritura en esa carpeta.", - "HeaderSelectTranscodingPath": "Seleccione la ruta temporal del transcodificador", + "HeaderSelectTranscodingPath": "Ruta para los archivos temporales de las conversiones", "HeaderSelectTranscodingPathHelp": "Busca o escribe la ruta que se utilizará para guardar los archivos temporales que se generarán mientras se convierten los archivos. Jellyfin debe tener permisos de escritura en la carpeta.", "HeaderSendMessage": "Enviar mensaje", "HeaderSeries": "Series", @@ -404,7 +404,7 @@ "HeaderTunerDevices": "Sintonizadores", "HeaderTuners": "Sintonizadores", "HeaderTypeImageFetchers": "{0} capturadores de imágenes", - "HeaderTypeText": "Entrar texto", + "HeaderTypeText": "Introducir texto", "HeaderUpcomingOnTV": "Próximamente en la televisión", "HeaderUploadImage": "Subir imagen", "HeaderUser": "Usuario", @@ -621,7 +621,7 @@ "LabelMoviePrefixHelp": "Si se aplica un prefijo a títulos de películas, escríbalo para que el servidor pueda manejarlo correctamente.", "LabelMovieRecordingPath": "Ruta de grabaciones de películas (opcional):", "LabelMusicStreamingTranscodingBitrate": "Tasa de bits para la reproducción de música:", - "LabelMusicStreamingTranscodingBitrateHelp": "Especifique una tasa de bits máxima cuando transmita música.", + "LabelMusicStreamingTranscodingBitrateHelp": "Tasa de bits máxima para la música.", "LabelName": "Nombre:", "LabelNewName": "Nuevo nombre:", "LabelNewPassword": "Nueva contraseña:", @@ -674,7 +674,7 @@ "LabelRefreshMode": "Modo de refresco:", "LabelReleaseDate": "Fecha de lanzamiento:", "LabelRemoteClientBitrateLimit": "Límite de la transmisión de tasa de bits por internet (Mbps):", - "LabelRemoteClientBitrateLimitHelp": "Un límite opcional de tasa de bits para todos los dispositivos fuera de la red. Esto es útil para evitar que los dispositivos soliciten una tasa de bits más alta que la que su conexión a Internet puede manejar. Esto puede ocasionar una mayor carga de la CPU en su servidor para transcodificar vídeos sobre la marcha a una tasa de bits más baja.", + "LabelRemoteClientBitrateLimitHelp": "Especifica el bitrate máximo para los dispositivos que se encuentren fuera de la red local. Esto es útil para permitir la reproducción del contenido que tengas con una tasa de bits muy alta cuando la conexión a internet de tu servidor o la del cliente no sea lo suficientemente rápida. Esto ocasionará mayor carga, ya que el contenido que supere esta tasa de bits se convertirá para que esté dentro del límite establecido.", "LabelRuntimeMinutes": "Tiempo de ejecución (minutos):", "LabelSaveLocalMetadata": "Guardar imágenes y etiquetas en las carpetas de medios", "LabelSaveLocalMetadataHelp": "Guardar imágenes y etiquetas directamente en las carpetas en las que estén los elementos hará que se puedan editar más fácilmente.", @@ -749,8 +749,8 @@ "LabelYourFirstName": "Tu nombre:", "LabelYoureDone": "¡Ya está!", "LabelZipCode": "Código postal:", - "LabelffmpegPath": "Ruta de FFmpeg:", - "LabelffmpegPathHelp": "a ruta de acceso al archivo de la aplicación FFmpeg o la carpeta que contiene FFmpeg.", + "LabelffmpegPath": "Ruta de ffmpeg:", + "LabelffmpegPathHelp": "Carpeta donde se encuentra ffmpeg, el componente utilizado para realizar las conversiones. No la cambies a no ser que sepas lo que haces.", "LanNetworksHelp": "Lista de direcciones IP separadas por comas o entradas de dirección IP / máscara de red para redes que se considerarán en la red local al imponer restricciones de ancho de banda. Si se establece, todas las demás direcciones IP se considerarán en la red externa y estarán sujetas a las restricciones de ancho de banda externo. Si se deja en blanco, solo se considera que la subred del servidor está en la red local.", "Large": "Grande", "LatestFromLibrary": "Reciente en {0}", @@ -935,7 +935,7 @@ "OptionEnableM2tsModeHelp": "Activar modo M2TS cuando se codifique a MPEGTS.", "OptionEnded": "Finalizado", "OptionEquals": "Igual", - "OptionEstimateContentLength": "Estimar la longitud del contenido al transcodificar", + "OptionEstimateContentLength": "Estimar la longitud del contenido al convertirse", "OptionEveryday": "Todos los días", "OptionExternallyDownloaded": "Descarga externa", "OptionExtractChapterImage": "Habilitar la extracción de imágenes de los capítulos", @@ -973,8 +973,8 @@ "OptionProfileVideoAudio": "Vídeo y audio", "OptionProtocolHls": "Emisión HTTP en directo", "OptionReleaseDate": "Fecha de lanzamiento", - "OptionReportByteRangeSeekingWhenTranscoding": "Indicar que el servidor soporta la búsqueda de byte al transcodificar", - "OptionReportByteRangeSeekingWhenTranscodingHelp": "Esto es necesario para algunos dispositivos que no buscan el tiempo muy bien.", + "OptionReportByteRangeSeekingWhenTranscoding": "Indicar que el servidor soporta la búsqueda de byte al convertir", + "OptionReportByteRangeSeekingWhenTranscodingHelp": "Esto es necesario para los dispositivos que no cambian entre los diferentes puntos de tiempo del contenido correctamente.", "OptionRequirePerfectSubtitleMatch": "Sólo descargar subtítulos que son una combinación perfecta para mis archivos de vídeo", "OptionRequirePerfectSubtitleMatchHelp": "Requerir una coincidencia perfecta filtra los subtítulos para incluir sólo aquellos que coinciden con el archivo de vídeo. Desmarcando esta opción, aumentará la probabilidad de que los subtítulos se descarguen, pero puede que el texto del subtítulo no coincida con el vídeo.", "OptionResElement": "Elemento res", @@ -1205,7 +1205,7 @@ "ValueTimeLimitSingleHour": "Tiempo límite: 1 hora", "ValueVideoCodec": "Códec de video: {0}", "ViewAlbum": "Ver album", - "ViewArtist": "Ver artista", + "ViewAlbumArtist": "Ver artista del álbum", "ViewPlaybackInfo": "Ver información de la reproducción", "Watched": "Visto", "Wednesday": "Miércoles", @@ -1355,7 +1355,7 @@ "LabelPasswordResetProvider": "Proveedor de restablecimiento de contraseña:", "LabelServerName": "Nombre del servidor:", "LabelTranscodePath": "Ruta para los archivos temporales de las conversiones:", - "LabelTranscodes": "Transcodificaciones:", + "LabelTranscodes": "Archivos temporales de las conversiones:", "LabelUserLoginAttemptsBeforeLockout": "Intentos fallidos de inicio de sesión antes de que el usuario sea bloqueado:", "DashboardVersionNumber": "Versión: {0}", "DashboardServerName": "Servidor: {0}", @@ -1497,7 +1497,7 @@ "AlbumArtist": "Artista del álbum", "Album": "Álbum", "LabelDeinterlaceMethod": "Metodo de desentrelazar:", - "DeinterlaceMethodHelp": "Seleccione el método de desentrelazar para el transcodificar de contenido entrelazado.", + "DeinterlaceMethodHelp": "Seleccione el tipo de filtro que se aplicará para desentrelazar el contenido que esté entrelazado durante la conversión.", "LabelLibraryPageSize": "Tamaño de la página de la biblioteca:", "LabelLibraryPageSizeHelp": "Establece la cantidad de artículos a mostrar en una página de la biblioteca. Ponlo en 0 para desactivar la paginación.", "UnsupportedPlayback": "No es posible desencriptar contenido protegido mediante DRM; sin embargo se intentará su reproducción. Algunos archivos pueden aparecer completamente negros debido a encriptación u otras características no soportadas, como títulos interactivos.", @@ -1525,7 +1525,7 @@ "EnableBlurhash": "Mostrar una representación de las imágenes mientras cargan", "EnableBlurhashHelp": "Aparecerá una representación de los colores de las imágenes antes de que terminen de cargar", "HeaderDVR": "DVR", - "SyncPlayAccessHelp": "Selecciona los permisos de este usuario para utilizar SyncPlay. SyncPlay te permite sincronizar la reproducción entre varios dispositivos.", + "SyncPlayAccessHelp": "Selecciona el nivel de acceso de este usuario para utilizar SyncPlay. SyncPlay te permite sincronizar la reproducción entre varios dispositivos.", "MessageSyncPlayErrorMedia": "¡No se pudo activar SyncPlay! Error de medio.", "MessageSyncPlayErrorMissingSession": "¡No se pudo activar SyncPlay! Sesión desconectada.", "MessageSyncPlayErrorNoActivePlayer": "No hay reproductor activo. SyncPlay ha sido desactivado.", @@ -1562,6 +1562,18 @@ "ButtonSyncPlay": "SyncPlay", "ButtonCast": "Enviar", "MessageNoGenresAvailable": "Permitir a algunos proveedores de metadatos extraer géneros de Internet.", - "EnableDecodingColorDepth10Vp9": "Habilite la decodificación por hardware de 10 bits para Vp9", - "EnableDecodingColorDepth10Hevc": "Habilite la decodificación por hardware de 10 bits para HEVC" + "EnableDecodingColorDepth10Vp9": "Habilite la decodificación por hardware de 10 bits para VP9", + "EnableDecodingColorDepth10Hevc": "Habilite la decodificación por hardware de 10 bits para HEVC", + "ButtonPlayer": "Reproductor", + "TabRepositories": "Repositorios", + "MessageAddRepository": "Si desea agregar un repositorio, haga click en el botón cerca del encabezado y complete la información requerida.", + "LabelRepositoryNameHelp": "Un nombre personalizado para distinguir este repositorio de otros agregados a su servidor.", + "LabelRepositoryName": "Nombre del repositorio", + "LabelRepositoryUrlHelp": "La ubicación del repositorio que desea incluir.", + "LabelRepositoryUrl": "URL del repositorio", + "HeaderNewRepository": "Nuevo repositorio", + "MessageNoRepositories": "Sin repositorios.", + "Writers": "Escritores", + "StopPlayback": "Detener la reproducción", + "ClearQueue": "Borrar la cola" } diff --git a/src/strings/es_419.json b/src/strings/es_419.json index 29ef1a163d..871f43a372 100644 --- a/src/strings/es_419.json +++ b/src/strings/es_419.json @@ -43,12 +43,12 @@ "Trailers": "Trailers", "TabTrailers": "Trailers", "ReleaseGroup": "Grupo que lo estrenó", - "OptionThumbCard": "Tarjeta miniatura", - "OptionResElement": "elemento res", + "OptionThumbCard": "Miniatura de imagen", + "OptionResElement": "elemento reanudable", "OptionCaptionInfoExSamsung": "CaptionInfoEx (Samsung)", "OptionBluray": "Blu-ray", "OptionBlockTrailers": "Trailers", - "LabelNightly": "Nocturno", + "LabelNightly": "Construcciones nocturnas", "HeaderVideos": "Videos", "Director": "Director", "Depressed": "No presionado", @@ -370,7 +370,7 @@ "MessagePlayAccessRestricted": "La reproducción de este contenido está actualmente restringida. Por favor, contacta al administrador del servidor para obtener más información.", "MessagePasswordResetForUsers": "Los siguientes usuarios han restablecido sus contraseñas. Ahora pueden iniciar sesión con los códigos PIN que se usaron para realizar el restablecimiento.", "MessageNothingHere": "Nada aquí.", - "MessageNoTrailersFound": "No se encontraron trailers. Instala el canal de trailers para mejorar tu experiencia con películas al agregar una biblioteca de trailers desde Internet.", + "MessageNoTrailersFound": "Instale el canal de Avances para mejorar su experiencia cinematográfica agregando una biblioteca de Avances desde Internet.", "MessageNoServersAvailable": "No se encontraron servidores utilizando el descubrimiento automático de servidores.", "MessageNoPluginsInstalled": "No tienes complementos instalados.", "MessageNoMovieSuggestionsAvailable": "No hay sugerencias de películas disponibles en este momento. Comienza a ver y a calificar tus películas, y luego regresa para ver tus recomendaciones.", @@ -827,7 +827,7 @@ "LabelEnableSingleImageInDidlLimit": "Limitar a una sola imagen incrustada", "LabelEnableRealtimeMonitorHelp": "Los cambios en los archivos serán procesados inmediatamente, en los sistemas de archivo soportados.", "LabelEnableRealtimeMonitor": "Activar monitoreo en tiempo real", - "LabelEnableHttpsHelp": "Permite al servidor escuchar en el puerto HTTPS configurado. Un certificado válido también debe ser configurado para que esto tenga efecto.", + "LabelEnableHttpsHelp": "Permite que el servidor escuche en el puerto HTTPS configurado. También se debe configurar un certificado válido para que esto surta efecto.", "LabelEnableHttps": "Habilitar HTTPS", "LabelEnableHardwareDecodingFor": "Habilitar decodificación por hardware para:", "LabelEnableDlnaServerHelp": "Permite a dispositivos UPnP en tu red explorar y reproducir contenido.", @@ -1548,5 +1548,25 @@ "EnableBlurhash": "Habilitar marcadores de posición borrosos para imágenes", "ShowMore": "Mostrar más", "ShowLess": "Mostrar menos", - "EnableBlurhashHelp": "Las imágenes que aún se están cargando se mostrarán con un marcador de posición borroso" + "EnableBlurhashHelp": "Las imágenes que aún se están cargando se mostrarán con un marcador de posición borroso", + "ButtonSyncPlay": "SyncPlay", + "MessageNoGenresAvailable": "Permitir a algunos proveedores de metadatos obtener géneros desde Internet.", + "MessageAddRepository": "Si desea agregar un repositorio, haga clic en el botón al lado del encabezado y complete la información solicitada.", + "LabelRepositoryNameHelp": "Un nombre personalizado para distinguir este repositorio de cualquier otro agregado a su servidor.", + "LabelRepositoryName": "Nombre del repositorio", + "LabelRepositoryUrlHelp": "La ubicación del manifiesto del repositorio que desea incluir.", + "LabelRepositoryUrl": "URL del repositorio", + "HeaderNewRepository": "Nuevo repositorio", + "MessageNoRepositories": "Sin repositorios.", + "EnableFasterAnimationsHelp": "Usar animaciones y transiciones más rápidas", + "EnableFasterAnimations": "Animaciones más rápidas", + "EnableDecodingColorDepth10Vp9": "Habilitar la decodificación de hardware de 10-Bit para VP9", + "EnableDecodingColorDepth10Hevc": "Habilitar la decodificación de hardware de 10-Bit para HEVC", + "ClearQueue": "Limpiar cola", + "StopPlayback": "Detener reproducción", + "ButtonPlayer": "Reproducir", + "ButtonCast": "Emitir", + "Writers": "Escritores", + "ViewAlbumArtist": "Ver Álbum de Artista", + "TabRepositories": "Repositorios" } diff --git a/src/strings/es_DO.json b/src/strings/es_DO.json index 7c42778a1c..9f5d299631 100644 --- a/src/strings/es_DO.json +++ b/src/strings/es_DO.json @@ -12,5 +12,6 @@ "Books": "Libros", "Albums": "Álbumes", "Artists": "Artistas", - "Channels": "Canales" + "Channels": "Canales", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/fa.json b/src/strings/fa.json index ad32c135f1..877c0af490 100644 --- a/src/strings/fa.json +++ b/src/strings/fa.json @@ -1553,5 +1553,6 @@ "EnableFastImageFadeIn": "Faster animations", "EnableFastImageFadeInHelp": "Use faster animations and transitions", "EnableBlurhash": "Enable blurred placeholders for images", - "EnableBlurhashHelp": "Images that are still being loaded will be displayed with a blurred placeholder" + "EnableBlurhashHelp": "Images that are still being loaded will be displayed with a blurred placeholder", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/fi.json b/src/strings/fi.json index 3ccf278025..b50ed369e1 100644 --- a/src/strings/fi.json +++ b/src/strings/fi.json @@ -354,7 +354,7 @@ "OptionPlayCount": "Toistokerrat", "OptionPlayed": "Toistettu", "OptionOnAppStartup": "Käynnistyksen yhteydessä", - "OptionNew": "Uusi...", + "OptionNew": "Uusi…", "OptionNameSort": "Nimi", "OptionMonday": "Maanantai", "OptionMissingEpisode": "Puuttuvat jaksot", @@ -428,7 +428,7 @@ "LabelPreferredDisplayLanguage": "Ensisijainen näyttökieli:", "LabelOriginalTitle": "Alkuperäinen nimi:", "LabelOriginalAspectRatio": "Alkuperäinen kuvasuhde:", - "LabelEnableAutomaticPortMapHelp": "Yritä automaattisesti yhdistää julkinen ja paikallinen portti UPnP:n kautta. Tämä ei välttämättä toimi kaikkien reitittimien kanssa. Muutokset tulevat voimaan vasta palvelimen uudelleenkäynnistyksen yhteydessä.", + "LabelEnableAutomaticPortMapHelp": "Automaattisesti ohjaa reitittimesi julkiset portit palvelimesi paikallisiin portteihin UPnP:n kautta. Tämä ei välttämättä toimi kaikkien reitittimien tai verkkoasetusten kanssa. Muutokset tulevat voimaan vasta palvelimen uudelleenkäynnistyksen yhteydessä.", "LabelEnableAutomaticPortMap": "Salli reitittimen porttien automaattinen avaaminen (UPnP)", "LabelDownloadLanguages": "Latauskielet:", "LabelDisplaySpecialsWithinSeasons": "Näytä erityiset jaksot kausien sisällä, jolloin ne ilmestyivät", @@ -1206,7 +1206,7 @@ "LabelOverview": "Yleiskatsaus:", "LabelPasswordResetProvider": "Salasanan nollauksen palveluntarjoaja:", "LabelParentalRating": "Ikäraja:", - "LabelOptionalNetworkPathHelp": "Jos tämä kansio on jaettu verkossa, polun jakaminen voi mahdollistaa Jellyfin-sovellusten muilla laitteilla käyttää mediatiedostoja suoraan.", + "LabelOptionalNetworkPathHelp": "Jos tämä kansio on jaettu verkossasi, polun jakaminen voi mahdollistaa muilla laitteilla olevien Jellyfin-sovellusten pääsyn suoraan mediatiedostoihin. Esimerkiksi {0} tai {1}.", "LabelMovieRecordingPath": "Elokuvien tallenteiden polku (valinnainen):", "LabelMusicStreamingTranscodingBitrateHelp": "Määritä enimmäisnopeus musiikkia suoratoistettaessa.", "LabelMusicStreamingTranscodingBitrate": "Musiikin transkoodauksen bitrate:", @@ -1246,5 +1246,33 @@ "MediaInfoAnamorphic": "Anamorfinen", "ErrorGettingTvLineups": "TV esiintyjälistan lataamisessa tapahtui virhe. Varmista, että tiedot on oikein ja yritä uudelleen.", "EnableDetailsBannerHelp": "Näyttää julistekuvan yksityiskohdat -sivun ylälaidassa.", - "EnableDetailsBanner": "Yksityiskohtien banneri" + "EnableDetailsBanner": "Yksityiskohtien banneri", + "ButtonSyncPlay": "SyncPlay", + "HeaderAccessSchedule": "Käyttöoikeusaikataulu", + "HeaderAccessScheduleHelp": "Luo käyttöoikeusaikataulu rajoittaaksesi käyttöä tietylle aikavälille.", + "HardwareAccelerationWarning": "Hardwarekiihdytyksen käyttöönotto voi aiheuttaa epävakautta joissain ympäristöissä. Varmista että sekä käyttöjärjestelmäsi että videoajurisi ovat ajan tasalla. Mikäli huomaat ongelmia videotoistossa säädettyäsi tätä asetusta, sinun täytyy muuttaa asetus takaisin kohtaan \"Ei mitään\".", + "EncoderPresetHelp": "Valitse nopeampi arvo kohentaaksesi suorituskykyä tai hitaampi arvo parantaaksesi kuvanlaatua.", + "H264CrfHelp": "Constant Rate Factor (CRF) on x264 -enkooderin kuvanlaadun vakioasetus. Voit valita arvon lukujen 0 ja 51 väliltä, jossa matalammat arvot tarkoittavat parempaa kuvanlaatua (suurempien tiedostokokojen hinnalla). Järkevät arvot ovat väliltä 18-28. Vakioarvo x264:lle on 23, joten voit käyttää sitä lähtökohtana.", + "GuideProviderSelectListings": "Valitse listaukset", + "GuideProviderLogin": "Kirjaudu", + "GuestStar": "Vieraileva tähti", + "GroupVersions": "Ryhmitä versiot", + "FFmpegSavePathNotFound": "Emme löytäneet FFmpegiä syöttämästäsi tiedostopolusta. Huomioi, että myös FFprobe vaaditaan ja sen täytyy sijaita samassa kansiossa. Nämä komponentit jaetaan normaalisti samassa paketissa. Varmista, että syöttämäsi polku on oikein ja yritä uudestaan.", + "ErrorSavingTvProvider": "TV-palveluntarjoajaa lisättäessä tapahtui virhe. Varmista sen saatavuus ja yritä uudestaan.", + "ErrorPleaseSelectLineup": "Valitse lineup ja yritä uudestaan. Mikäli lineuppeja ei ole saatavilla, varmista että käyttäjätunnuksesi, salasanasi sekä postinumerosi ovat oikein.", + "ErrorAddingListingsToSchedulesDirect": "Lineuppia Schedules Direct -käyttäjätunnuksellesi lisättäessä ilmeni virhe. Schedules Direct sallii vain rajallisen määrän lineuppeja yhdelle käyttäjätunnukselle. Mikäli haluat jatkaa, voit esimerkiksi kirjautua Schedules Direct -sivustolle ja poistaa muita listauksia käyttäjätunnukseltasi.", + "EnableDecodingColorDepth10Vp9": "Salli 10-bittinen hardware dekoodaus (VP9)", + "EnableDecodingColorDepth10Hevc": "Salli 10-bittinen hardware dekoodaus (HEVC)", + "HeaderCastCrew": "Näyttelijät ja henkilökunta", + "HeaderCastAndCrew": "Näyttelijät ja henkilökunta", + "HeaderCancelSeries": "Peruuta sarja", + "HeaderCancelRecording": "Peruuta tallennus", + "HeaderBranding": "Brändäys", + "HeaderBlockItemsWithNoRating": "Estä kaikki joissa ei ole luokitusta tai jonka luokitusta ei voida tunnistaa:", + "HeaderAppearsOn": "Esiintyy seuraavissa", + "ApiKeysCaption": "Lista aktiivisista API-avaimista", + "HeaderApiKeysHelp": "Ulkoiset sovellukset tarvitsevat API-avaimen voidakseen toimia Jellyfin -palvelimen kanssa. Avaimet myönnetään joko kirjautumalla sisään Jellyfin -käyttäjätunnuksella tai myöntämällä sellainen sovellukselle manuaalisesti.", + "HeaderAdditionalParts": "Muut osat", + "HeaderAddScheduledTaskTrigger": "Lisää laukaisin", + "HeaderActiveRecordings": "Käynnissä olevat nauhoitukset" } diff --git a/src/strings/fr-ca.json b/src/strings/fr-ca.json index 61dce082c9..5f03a9d43f 100644 --- a/src/strings/fr-ca.json +++ b/src/strings/fr-ca.json @@ -97,7 +97,7 @@ "AllowMediaConversion": "Autoriser la conversion des médias", "AllowMediaConversionHelp": "Autoriser ou refuser l'accès à la fonctionnalité de conversion des médias.", "AllowOnTheFlySubtitleExtraction": "Autoriser l'extraction des sous-titres à la volée", - "AllowOnTheFlySubtitleExtractionHelp": "Les sous-titres intégrés peuvent être extraits des vidéos et distribués aux applications Jellyfin au format texte pour éviter le transcodage. Sur certains systèmes, cela peut prendre du temps et arrêter la lecture de la vidéo pendant le processus d'extraction. Désactivez cette option pour graver les sous-titres avec un transcodage quand l'appareil ne les prend pas en charge nativement.", + "AllowOnTheFlySubtitleExtractionHelp": "Les sous-titres intégrés peuvent être extraits des vidéos et distribués aux clients en format texte pour éviter le transcodage. Sur certains systèmes, cela peut prendre du temps et arrêter la lecture de la vidéo pendant le processus d'extraction. Désactivez cette option pour graver les sous-titres avec un transcodage quand l'appareil ne les prend pas en charge nativement.", "AllowRemoteAccess": "Autoriser les connexions distantes à ce serveur Jellyfin.", "AllowRemoteAccessHelp": "Si l'option est désactivée, toutes les connexions distantes seront bloquées.", "Artists": "Artistes", @@ -134,13 +134,13 @@ "BirthLocation": "Lieu de naissance", "BirthPlaceValue": "Lieu de naissance : {0}", "Blacklist": "Liste noire", - "BookLibraryHelp": "Les livres audios et formats textes sont supportés. Consultez le {0}Guide de nommage de livres de Jellyfin{1}.", + "BookLibraryHelp": "Les livres audios et formats textes sont supportés. Consultez le {0} Guide de nommage de livres {1}.", "Box": "Boîtier", "BoxRear": "Dos de boîtier", "Browse": "Parcourir", "BrowsePluginCatalogMessage": "Explorer notre catalogue des plugins pour voir les plugins disponibles.", - "AllowHWTranscodingHelp": "Permet au récepteur TV de transcoder les flux à la volée. Cela peut aider à réduire le transcodage requis par le serveur Jellyfin.", - "BurnSubtitlesHelp": "Détermine si le serveur doit graver les sous-titres lors de la conversion vidéo en fonction du format des sous-titres. Éviter la gravure des sous-titres améliorera les performances du serveur. Sélectionnez Auto pour graver les formats basés sur l'image (par exemple, VOBSUB, PGS, SUB/IDX etc) ainsi que certains sous-titres ASS/SSA", + "AllowHWTranscodingHelp": "Permets au syntonisateur de transcoder les flux à la volée. Cela peut aider à réduire le transcodage requis par le serveur.", + "BurnSubtitlesHelp": "Détermine si le serveur doit graver les sous-titres lors du transcodage vidéo. Éviter ceci améliorera les performances du serveur. Sélectionnez Auto pour graver les formats basés sur l'image (par exemple, VOBSUB, PGS, SUB/IDX etc) ainsi que certains sous-titres ASS/SSA.", "ButtonAccept": "Accepter", "ButtonAdd": "Ajouter", "ButtonAddMediaLibrary": "Ajouter une médiathèque", @@ -187,7 +187,7 @@ "ButtonMore": "Plus", "ButtonNetwork": "Réseau", "AspectRatio": "Format de visionnement", - "AskAdminToCreateLibrary": "Demander à l'administrateur pour créer une bibliothèque de média.", + "AskAdminToCreateLibrary": "Demander un administrateur de créer une médiathèque.", "Artist": "Artiste", "AllowFfmpegThrottlingHelp": "Quand un transcodage ou rémux se déplace après la position de relecture, suspendre le processus pour consommer moins de ressources. Ceci est le plus utile pour chercher moins. Désactiver s'il y a des problèmes de relecture.", "AllowFfmpegThrottling": "Restreindre la vitesse de transcodage", @@ -198,5 +198,68 @@ "HeaderFavoriteShows": "Séries favorites", "HeaderFavoriteEpisodes": "Épisodes favoris", "HeaderFavoriteArtists": "Artistes favoris", - "HeaderFavoriteAlbums": "Albums favoris" + "HeaderFavoriteAlbums": "Albums favoris", + "ButtonSyncPlay": "SyncPlay", + "Default": "Défaut", + "DeathDateValue": "Mort: {0}", + "DatePlayed": "Date écoutée", + "DateAdded": "Date d'ajout", + "CriticRating": "Évaluation critique", + "CopyStreamURLError": "Une erreur est survenue en essayant de copier l'URL.", + "CopyStreamURLSuccess": "L'URL a été copié avec succès.", + "CopyStreamURL": "Copier l'URL du stream", + "ContinueWatching": "Continuer à visionner", + "Connect": "Connexion", + "ConfirmEndPlayerSession": "Voulez-vous éteindre Jellyfin sur {0}?", + "ConfirmDeletion": "Confirmer la suppression", + "ConfirmDeleteItems": "Supprimer ceux-ci les effacera du système de fichiers et votre médiathèque. Êtes-vous sûr de vouloir continuer?", + "ConfirmDeleteImage": "Effacer l'image?", + "ClientSettings": "Paramètres du client", + "ChannelNumber": "Numéro de canal", + "ChannelNameOnly": "Canal {0} seulment", + "ChannelAccessHelp": "Sélectionner les canaux que vous désirer partager avec cet usager. Les administrateurs seront capable de modifier tout les canaux en utilisant le gestionnaire des métadonnées.", + "Categories": "Catégories", + "CancelSeries": "Annuler la série", + "CancelRecording": "Annuler l'enregistrement", + "ButtonWebsite": "Site web", + "ButtonViewWebsite": "Voir le site web", + "ButtonUp": "Vers le haut", + "ButtonUninstall": "Désinstaller", + "ButtonTogglePlaylist": "Liste de lecture", + "ButtonToggleContextMenu": "Plus", + "ButtonSubtitles": "Sous-titres", + "ButtonSubmit": "Soumettre", + "ButtonStop": "Arrêt", + "ButtonStart": "Démarrer", + "ButtonSort": "Trier", + "ButtonSignIn": "Se connecter", + "ButtonShutdown": "Éteindre", + "ButtonShuffle": "Lecture aléatoire", + "ButtonSettings": "Paramètres", + "ButtonSend": "Envoyer", + "ButtonSelectServer": "Sélectionner le serveur", + "ButtonSelectDirectory": "Sélectionner le répertoire", + "ButtonSearch": "Rechercher", + "ButtonScanAllLibraries": "Analyser toutes les médiathèques", + "ButtonSave": "Sauvegarder", + "ButtonRevoke": "Révoquer", + "ButtonResume": "Reprendre la lecture", + "ButtonResetPassword": "Réinitialiser le mot de passe", + "ButtonResetEasyPassword": "Remettre à nouveau le code NIP facile", + "ButtonRepeat": "Répéter", + "ButtonRename": "Renommer", + "ButtonRemove": "Enlever", + "ButtonRefreshGuideData": "Rafraîchir les données de guide", + "ButtonRefresh": "Rafraîchir", + "ButtonProfile": "Profil", + "ButtonPreviousTrack": "Piste précédente", + "ButtonPlay": "Lecture", + "ButtonPause": "Pause", + "ButtonParentalControl": "Contrôle parentale", + "ButtonOpen": "Ouvrir", + "ButtonOk": "OK", + "ButtonNextTrack": "Prochaine piste", + "ButtonNew": "Nouveau", + "ButtonAddImage": "Ajouter l'image", + "BoxSet": "Coffret" } diff --git a/src/strings/fr.json b/src/strings/fr.json index 941b7c117c..c71afef661 100644 --- a/src/strings/fr.json +++ b/src/strings/fr.json @@ -1506,7 +1506,7 @@ "HeaderFavoritePlaylists": "Listes de lecture favorites", "TabDVR": "DVR", "LabelChromecastVersion": "Version de Chromecast", - "LabelEnableHttpsHelp": "Autorise le serveur à écouter les requêtes HTTPS sur le port configurée. Un certificat valide doit être configuré pour permettre ce mode de fonctionnement.", + "LabelEnableHttpsHelp": "Autorise le serveur à écouter les requêtes HTTPS sur le port configuré. Un certificat valide doit être configuré pour permettre ce mode de fonctionnement.", "LabelEnableHttps": "Activer HTTPS", "HeaderServerAddressSettings": "Paramètres adresses serveur", "HeaderRemoteAccessSettings": "Paramètres d'accès distant", @@ -1521,7 +1521,7 @@ "EnableDetailsBanner": "Bannière des détails", "EnableDetailsBannerHelp": "Affichez une image de bannière en haut de la page de détails de l'article.", "HeaderSyncPlaySelectGroup": "Rejoindre un groupe", - "LabelSyncPlayAccessCreateAndJoinGroups": "Autoriser l'utilisateur à créer un ou rejoindre un groupe", + "LabelSyncPlayAccessCreateAndJoinGroups": "Autoriser l'utilisateur à créer ou rejoindre un groupe", "LabelSyncPlayLeaveGroupDescription": "Désactiver SyncPlay", "LabelSyncPlayLeaveGroup": "Quitter le groupe", "LabelSyncPlayNewGroupDescription": "Créer un nouveau groupe", @@ -1529,15 +1529,15 @@ "LabelSyncPlaySyncMethod": "Méthode de synchronisation :", "LabelSyncPlayPlaybackDiff": "Décalage de la lecture :", "MillisecondsUnit": "ms", - "LabelSyncPlayTimeOffset": "Décalage de temps avec le serveur  :", + "LabelSyncPlayTimeOffset": "Décalage de temps avec le serveur :", "HeaderSyncPlayEnabled": "SyncPlay activé", "MessageSyncPlayLibraryAccessDenied": "L'accès à ce contenu est restreint.", "MessageSyncPlayJoinGroupDenied": "Permission requise pour utiliser SyncPlay.", "MessageSyncPlayCreateGroupDenied": "Permission requise pour créer un groupe.", "MessageSyncPlayGroupDoesNotExist": "Impossible de rejoindre le groupe car il n'existe pas.", "MessageSyncPlayPlaybackPermissionRequired": "Autorisation de lecture requise.", - "MessageSyncPlayNoGroupsAvailable": "Aucun groupe disponible. Commencez par lancer quelque chose.", - "MessageSyncPlayGroupWait": "{0} est en train de charger...", + "MessageSyncPlayNoGroupsAvailable": "Aucun groupe disponible. Commencez par lire quelque chose.", + "MessageSyncPlayGroupWait": "{0} est en train de charger…", "MessageSyncPlayUserLeft": "{0} a quitté le groupe.", "MessageSyncPlayUserJoined": "{0} a rejoint le groupe.", "MessageSyncPlayDisabled": "SyncPlay désactivé.", @@ -1545,17 +1545,17 @@ "LabelSyncPlayAccess": "Accès SyncPlay", "LabelSyncPlayAccessNone": "Désactivé pour cet utilisateur", "LabelSyncPlayAccessJoinGroups": "Autoriser l'utilisateur à rejoindre un groupe", - "SyncPlayAccessHelp": "Sélectionner le niveau d'accès de cet utilisateur pour la fonctionnalité SyncPlay. SyncPlay permet de synchroniser la lecture avec d'autres utilisateurs.", + "SyncPlayAccessHelp": "Sélectionner le niveau d'accès de cet utilisateur pour la fonctionnalité SyncPlay. SyncPlay permet de synchroniser la lecture avec d'autres appareils.", "MessageSyncPlayErrorMedia": "Impossible d'activer SyncPlay ! Erreur média.", "MessageSyncPlayErrorMissingSession": "Impossible d'activer SyncPlay ! Session manquante.", - "MessageSyncPlayErrorNoActivePlayer": "Aucun player actif trouvé. SyncPlay a été désactivé.", + "MessageSyncPlayErrorNoActivePlayer": "Aucun lecteur actif trouvé. SyncPlay a été désactivé.", "MessageSyncPlayErrorAccessingGroups": "Une erreur s'est produite pendant l'accès à la liste de groupes.", "ShowMore": "Voir plus", "ShowLess": "Voir moins", "EnableBlurhashHelp": "Les images qui sont encore en cours de chargement seront remplacées par une image générique floue", "EnableBlurhash": "Utilise des images génériques floues à la place des images", "ButtonCast": "Diffuser", - "ButtonSyncPlay": "Lecture synchronisée", + "ButtonSyncPlay": "SyncPlay", "TabRepositories": "Dépôts", "MessageNoGenresAvailable": "Utiliser des fournisseurs de métadonnées pour récupérer les genres depuis internet.", "MessageAddRepository": "Si vous souhaitez ajouter un dépôt, cliquez sur le bouton près de l'entête et renseignez les informations demandées.", @@ -1568,5 +1568,10 @@ "EnableFasterAnimationsHelp": "Utiliser des animations et des transitions plus rapides", "EnableFasterAnimations": "Animations plus rapides", "EnableDecodingColorDepth10Vp9": "Activer le décodage hardware 10-Bit pour VP9", - "EnableDecodingColorDepth10Hevc": "Activer le décodage hardware 10-Bit pour HEVC" + "EnableDecodingColorDepth10Hevc": "Activer le décodage hardware 10-Bit pour HEVC", + "ClearQueue": "Vider la file d'attente", + "StopPlayback": "Arrêter", + "ButtonPlayer": "Démarrer", + "Writers": "Écrivains", + "ViewAlbumArtist": "Voir l'album de l'artiste" } diff --git a/src/strings/gl.json b/src/strings/gl.json index 5341462de7..e87ce46770 100644 --- a/src/strings/gl.json +++ b/src/strings/gl.json @@ -11,5 +11,6 @@ "AirDate": "Data de emisión", "Aired": "Emitido", "AddToPlaylist": "Engadir á lista de reprodución", - "Add": "Engadir" + "Add": "Engadir", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/gsw.json b/src/strings/gsw.json index e396313856..d7cd980b80 100644 --- a/src/strings/gsw.json +++ b/src/strings/gsw.json @@ -164,6 +164,13 @@ "ValueSpecialEpisodeName": "Extra - {0}", "VersionNumber": "Version {0}", "Absolute": "Absolut", - "Actor": "Schauspiler", - "AccessRestrictedTryAgainLater": "Zuegriff isch momentan beschränkt. Probier bitte später nomau. " + "Actor": "Schauspieler", + "AccessRestrictedTryAgainLater": "Zuegriff isch momentan beschränkt. Probiers bitte spöter nomol.", + "ButtonSyncPlay": "SyncPlay", + "AdditionalNotificationServices": "Durchsuech de Plugin Katalog zum zuesätzlichi Benochrichtigungsdienst zinstalliere.", + "AddedOnValue": "hinzuegfüegt", + "AddToPlaylist": "Zur Playlist hinzuefüege", + "AddToPlayQueue": "Zur Warteschlange hinzuefüege", + "AddToCollection": "Zur Collection hinzuefüege", + "Add": "hinzuefüege" } diff --git a/src/strings/he.json b/src/strings/he.json index 5df0ba4fe4..31bc228bb2 100644 --- a/src/strings/he.json +++ b/src/strings/he.json @@ -771,5 +771,9 @@ "LabelSource": "מקור:", "LabelSoundEffects": "אפקטי סאונד:", "ButtonTogglePlaylist": "רשימת ניגון", - "ButtonToggleContextMenu": "עוד" + "ButtonToggleContextMenu": "עוד", + "ButtonSyncPlay": "SyncPlay", + "ButtonPlayer": "נגן", + "StopPlayback": "הפסק הפעלה", + "ClearQueue": "נקה תור" } diff --git a/src/strings/hi-in.json b/src/strings/hi-in.json index 7a51a4f695..48b82c601f 100644 --- a/src/strings/hi-in.json +++ b/src/strings/hi-in.json @@ -73,10 +73,10 @@ "ButtonAddScheduledTaskTrigger": "ट्रिगर जोड़ें", "ButtonAddMediaLibrary": "मीडिया लाइब्रेरी जोड़ें", "ButtonAddImage": "छवि जोड़ें", - "ButtonAdd": "जोड़ना", + "ButtonAdd": "जोड़ें", "UnsupportedPlayback": "Jellyfin DRM द्वारा संरक्षित सामग्री को डिक्रिप्ट नहीं कर सकता है, लेकिन सभी सामग्री की परवाह किए बिना, संरक्षित शीर्षकों सहित प्रयास किया जाएगा। एन्क्रिप्शन या अन्य असमर्थित सुविधाओं जैसे इंटरेक्टिव शीर्षक के कारण कुछ फाइलें पूरी तरह से काली दिखाई दे सकती हैं।", "BoxRear": "बॉक्स (पीछे)", - "Box": "डिब्बा", + "Box": "बॉक्स", "Books": "पुस्तकें", "BookLibraryHelp": "ऑडियो और पाठ्य पुस्तकें समर्थित हैं। {0} पुस्तक नामकरण गाइड {1} की समीक्षा करें।", "Blacklist": "काला सूची में डालना", @@ -112,5 +112,10 @@ "AlbumArtist": "चित्राधार कलाकार", "AllowOnTheFlySubtitleExtraction": "मक्खी पर उपशीर्षक निष्कर्षण की अनुमति दें", "Album": "एल्बम", - "AddItemToCollectionHelp": "उनके लिए खोज करके संग्रह में आइटम जोड़ें और उन्हें संग्रह में जोड़ने के लिए उनके राइट-क्लिक या टैप मेनू का उपयोग करें।" + "AddItemToCollectionHelp": "उनके लिए खोज करके संग्रह में आइटम जोड़ें और उन्हें संग्रह में जोड़ने के लिए उनके राइट-क्लिक या टैप मेनू का उपयोग करें।", + "ButtonSyncPlay": "SyncPlay", + "BrowsePluginCatalogMessage": "उपलब्ध प्लगिन्स देखने के लिए हमारे कैटलॉग को ब्राउज़ करें।", + "Browse": "ब्राउज़", + "BoxSet": "बॉक्स सेट", + "BurnSubtitlesHelp": "निर्धारित करता है कि वीडियो ट्रांसकोडिंग करते समय सर्वर को उपशीर्षक बर्न-इन करना चाहिए। इससे बचने से प्रदर्शन में बहुत सुधार होगा। छवि आधारित उपशीर्षक (VOBSUB, PGS, SUB, IDX, …) एवं ASS अथवा SSA जैसे उपशीर्षक बर्न-इन करने के लिए ऑटो का चयन करें।" } diff --git a/src/strings/hr.json b/src/strings/hr.json index 16a2ab05dd..69f5dfaa65 100644 --- a/src/strings/hr.json +++ b/src/strings/hr.json @@ -1050,5 +1050,193 @@ "Alerts": "Upozorenja", "AlbumArtist": "Izvođač na albumu", "Album": "Album", - "AddToPlayQueue": "Dodaj u red izvođenja" + "AddToPlayQueue": "Dodaj u red izvođenja", + "Banner": "Zaglavlje", + "AutoBasedOnLanguageSetting": "Automatski (prema jezičnim postavkama)", + "AspectRatio": "Omjer", + "Ascending": "Uzlazno", + "Art": "Grafike", + "Absolute": "Apsolutno", + "CopyStreamURLSuccess": "URL uspješno kopiran.", + "CopyStreamURL": "Kopiraj URL streama", + "ContinueWatching": "Nastavi gledati", + "Connect": "Spoji", + "ClientSettings": "Postavke klijenta", + "ButtonTogglePlaylist": "Lista izvođenja", + "ButtonToggleContextMenu": "Više", + "ButtonSplit": "Odvoji", + "ButtonStop": "Stop", + "ButtonScanAllLibraries": "Skeniraj sve biblioteke", + "ButtonInfo": "Info", + "ButtonFilter": "Filtriraj", + "ButtonAddImage": "Dodaj sliku", + "Box": "Kutija", + "AskAdminToCreateLibrary": "Traži administratora da kreira biblioteku.", + "PictureInPicture": "Slika u slici", + "OtherArtist": "Ostali izvođači", + "OptionThumb": "Sličica", + "OptionProtocolHttp": "HTTP", + "OptionProfileVideo": "Video", + "OptionProfileAudio": "Audio", + "OptionPoster": "Poster", + "OptionList": "Lista", + "OptionIsSD": "SD", + "OptionIsHD": "HD", + "OptionDvd": "DVD", + "OptionDownloadLogoImage": "Logo", + "OptionBluray": "Blu-ray", + "OptionBanner": "Zaglavlje", + "Option3D": "3D", + "OneChannel": "Jedan kanal", + "Off": "Isključi", + "Normal": "Normalno", + "None": "Ništa", + "NoSubtitles": "Ništa", + "No": "Ne", + "NextUp": "Slijedi", + "Next": "Slijedeće", + "Never": "Nikada", + "MusicVideo": "Glazbeni spot", + "Movie": "Film", + "Metadata": "Meta podaci", + "MessageSyncPlayLibraryAccessDenied": "Pristup ovom sadržaju je ograničen.", + "MessageSyncPlayDisabled": "SyncPlay onemogućen.", + "MessageSyncPlayEnabled": "SyncPlay omogućen.", + "MessagePleaseWait": "Molimo pričekajte. Ovo može potrajati nekoliko minuta.", + "LabelRepositoryName": "Naziv repozitorija", + "LabelRepositoryUrl": "URL repozitorija", + "HeaderNewRepository": "Novi repozitorij", + "MessageNoRepositories": "Nema repozitorija.", + "MessageConfirmAppExit": "Da li želite izaći?", + "Menu": "Meni", + "MediaInfoStreamTypeVideo": "Video", + "MediaInfoStreamTypeSubtitle": "Prijevod", + "MediaInfoStreamTypeData": "Podaci", + "MediaInfoStreamTypeAudio": "Audio", + "MediaInfoSoftware": "Softver", + "Logo": "Logo", + "List": "Lista", + "LabelYear": "Godina:", + "LabelVideo": "Video", + "DashboardArchitecture": "Arhitektura: {0}", + "DashboardOperatingSystem": "Operativni sustav: {0}", + "DashboardServerName": "Server: {0}", + "DashboardVersionNumber": "Verzija: {0}", + "LabelVersion": "Verzija:", + "LabelTheme": "Tema:", + "LabelTextSize": "Veličina teksta:", + "LabelTextColor": "Boja teksta:", + "LabelSyncPlayAccess": "SyncPlay pristup", + "LabelSyncPlayAccessNone": "Onemogućeno za ovog korisnika", + "LabelSyncPlayAccessJoinGroups": "Dozvoli korisniku da se pridruži grupama", + "LabelSyncPlayAccessCreateAndJoinGroups": "Dozvoli korisniku da kreira i pridruži se grupama", + "LabelSyncPlayLeaveGroupDescription": "Onemogući SyncPlay", + "LabelSyncPlayLeaveGroup": "Napusti grupu", + "LabelSyncPlayNewGroupDescription": "Kreiraj novu grupu", + "LabelSyncPlayNewGroup": "Nova grupa", + "MillisecondsUnit": "ms", + "LabelSubtitles": "Prijevodi", + "LabelStatus": "Status:", + "LabelSoundEffects": "Zvučni efekti:", + "LabelSortOrder": "Redoslijed sortiranja:", + "LabelSortBy": "Sortiranje po:", + "LabelSize": "Veličina:", + "LabelServerName": "Naziv servera:", + "EnableFasterAnimations": "Brže animacije", + "LabelReasonForTranscoding": "Razlog transkodiranja:", + "LabelPreferredSubtitleLanguage": "Preferirani jezik prijevoda:", + "LabelStable": "Stabilna", + "LabelLanNetworks": "LAN mreže:", + "LabelInternetQuality": "Internet kvaliteta:", + "LabelHomeNetworkQuality": "Kvaliteta kućne mreže:", + "LabelFormat": "Format:", + "LabelFont": "Font:", + "LabelFolder": "Mapa:", + "LabelEnableHttps": "Omogući HTTPS", + "LabelEnableHardwareDecodingFor": "Omogući hardversko dekodiranje za:", + "LabelDisplayLanguageHelp": "Prevođenje Jellyfin-a je projekt u tijeku.", + "LabelDisplayLanguage": "Jezik prikaza:", + "LabelAutomaticallyRefreshInternetMetadataEvery": "Automatski osvježi meta podatke sa interneta:", + "LabelAudioChannels": "Audio kanali:", + "LabelAudio": "Audio", + "LabelAlbum": "Album:", + "Label3DFormat": "3D format:", + "Items": "Stavke", + "Horizontal": "Horizontalno", + "Home": "Početna", + "Hide": "Sakrij", + "HeaderSyncPlayEnabled": "SyncPlay omogućen", + "HeaderSyncPlaySelectGroup": "Pridruži se grupi", + "HeaderSubtitleDownloads": "Preuzimanje prijevoda", + "HeaderSubtitleAppearance": "Prikaz prijevoda", + "HeaderStopRecording": "Zaustavi snimanje", + "HeaderStatus": "Status", + "HeaderSeriesStatus": "Status serije", + "HeaderSecondsValue": "{0} sekundi", + "HeaderRemoteAccessSettings": "Postavke udaljenog pristupa", + "HeaderPlaybackError": "Pogreška reprodukcije", + "HeaderPlayAll": "Reproduciraj sve", + "HeaderOnNow": "Trenutno", + "HeaderNextVideoPlayingInValue": "Slijedeći video se reproducira za {0}", + "HeaderNextEpisodePlayingInValue": "Slijedeća epizoda se reproducira za {0}", + "HeaderNewDevices": "Novi uređaji", + "HeaderNavigation": "Navigacija", + "HeaderMyDevice": "Moj uređaj", + "HeaderLibrarySettings": "Postavke biblioteke", + "HeaderHome": "Početna", + "HeaderGenres": "Žanrovi", + "HeaderFavoritePeople": "Omiljeni ljudi", + "HeaderFavoriteMovies": "Omiljeni filmovi", + "HeaderFavoriteBooks": "Omiljene knjige", + "HeaderDVR": "DVR", + "HeaderDownloadSync": "Preuzmi i sinkroniziraj", + "HeaderContinueListening": "Nastavi slušati", + "HeaderConfigureRemoteAccess": "Konfiguriraj udaljeni pristup", + "HeaderAudioBooks": "Audio knjige", + "ApiKeysCaption": "Popis trenutno dostupnih API ključeva", + "HeaderAllowMediaDeletionFrom": "Dozvoli brisanje datoteka iz", + "HeaderAlbums": "Albumi", + "HeaderAdmin": "Administrator", + "Guide": "Vodič", + "GroupBySeries": "Grupiraj po serijama", + "Genre": "Žanr", + "General": "Općenito", + "Fullscreen": "Prikaz cijelog ekrana", + "Filters": "Filteri", + "FetchingData": "Dohvaćanje dodatnih podataka", + "Features": "Mogućnosti", + "Extras": "Dodaci", + "ExtraLarge": "Ekstra veliko", + "ExitFullscreen": "Izađi iz prikaza cijelog ekrana", + "EveryNDays": "Svakih {0} dana", + "Episodes": "Epizode", + "Episode": "Epizoda", + "EnableHardwareEncoding": "Omogući hardversko enkodiranje", + "EnableExternalVideoPlayers": "Vanjski video player", + "EnableDecodingColorDepth10Vp9": "Omogući 10-Bitno hardversko dekodiranje za VP9", + "EnableDecodingColorDepth10Hevc": "Omogući 10-Bitno hardversko dekodiranje za HEVC", + "EnableCinemaMode": "Kino mod", + "EnableBackdrops": "Pozadine", + "EditMetadata": "Izmijeni meta podatke", + "DisplayMissingEpisodesWithinSeasons": "Prikaži epizode koje nedostaju unutar sezona", + "DisplayInMyMedia": "Prikaz na početnom ekranu", + "Display": "Prikaz", + "Disconnect": "Odspoji", + "Disc": "Disk", + "Disabled": "Onemogućeno", + "Directors": "Režiseri", + "DirectPlaying": "Direktna reprodukcija", + "DetectingDevices": "Tražim uređaje", + "Descending": "Silazno", + "DefaultMetadataLangaugeDescription": "Ovo su vaše zadane postavke te se mogu prilagoditi na razini biblioteke.", + "Default": "Zadano", + "DatePlayed": "Datum reprodukcije", + "DateAdded": "Datum dodavanja", + "CriticRating": "Rejting kritičara", + "CopyStreamURLError": "Došlo je do greške prilikom kopiranja URLa.", + "ConfirmEndPlayerSession": "Da li želite ugasiti Jellyfin na {0}?", + "CommunityRating": "Rejting zajednice", + "Browse": "Pretraži", + "BoxRear": "Kutija (stražnja)", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/hu.json b/src/strings/hu.json index 6b32e87858..5559e2f10a 100644 --- a/src/strings/hu.json +++ b/src/strings/hu.json @@ -1521,7 +1521,7 @@ "TabDVR": "DVR", "HeaderDVR": "DVR", "SaveChanges": "Változtatások mentése", - "MessageSyncPlayGroupWait": "{0} bufferel...", + "MessageSyncPlayGroupWait": "{0} pufferel…", "MessageSyncPlayUserLeft": "{0} elhagyta a csoportot.", "MessageSyncPlayUserJoined": "{0} csatlakozott a csoporthoz.", "MessageSyncPlayDisabled": "SyncPlay letiltva.", @@ -1562,6 +1562,19 @@ "MessageNoGenresAvailable": "Engedélyezz néhány metaadat szolgáltatót, hogy műfaj adatokat tölthess le az internetről.", "EnableFasterAnimationsHelp": "Gyorsabb animációk és áttűnések használata", "EnableFasterAnimations": "Gyorsabb animációk", - "EnableDecodingColorDepth10Vp9": "10 bites hardveres dekódolás engedélyezése Vp9-hez", - "EnableDecodingColorDepth10Hevc": "10 bites hardveres dekódolás engedélyezése HEVC-hez" + "EnableDecodingColorDepth10Vp9": "10 bites hardveres dekódolás engedélyezése VP9-hez", + "EnableDecodingColorDepth10Hevc": "10 bites hardveres dekódolás engedélyezése HEVC-hez", + "TabRepositories": "Tárolók", + "MessageAddRepository": "Ha új tárolót szeretnél hozzáadni, kattints a gombra a fejlécben, és add meg a szükséges adatokat.", + "LabelRepositoryNameHelp": "Egy egyedi név, amivel megkülönböztetheted a tárolót a többi, a szervezhez hozzáadott tárolótól.", + "LabelRepositoryName": "Tároló neve", + "LabelRepositoryUrlHelp": "A hivatkozni kívánt tároló manifeszt helye.", + "LabelRepositoryUrl": "Tároló URL-je", + "HeaderNewRepository": "Új tároló", + "MessageNoRepositories": "Nincs tároló.", + "Writers": "Írók", + "ClearQueue": "Sor ürítése", + "StopPlayback": "Lejátszás leállítása", + "ViewAlbumArtist": "Album előadójának megtekintése", + "ButtonPlayer": "Lejátszó" } diff --git a/src/strings/id.json b/src/strings/id.json index 8085767984..9d347b7dcc 100644 --- a/src/strings/id.json +++ b/src/strings/id.json @@ -192,8 +192,8 @@ "AddToPlayQueue": "Tambah ke dalam antrean putar", "AddToCollection": "Tambah ke dalam koleksi", "AddItemToCollectionHelp": "Tambahkan item ke dalam koleksi melalui pencarian dan gunakan klik kanan atau ketuk menu untuk menambahkannya ke dalam koleksi.", - "AccessRestrictedTryAgainLater": "Akses sedang dibatasi. Silakan coba kembali nanti.", - "Absolute": "Mutlak", + "AccessRestrictedTryAgainLater": "Akses sedang dibatasi. Mohon tunggu beberapa saat lagi", + "Absolute": "Absolut", "Songs": "Lagu", "Playlists": "Daftar putar", "ValueSpecialEpisodeName": "Spesial - {0}", @@ -204,5 +204,6 @@ "Alerts": "Peringatan", "AddedOnValue": "Ditambahkan {0}", "AllowFfmpegThrottling": "Transcode Tercekik", - "AllowOnTheFlySubtitleExtractionHelp": "Subtitle yang melekat di video dapat dikeluarkan dan dikirimkan kepada klien dalam bentuk text biasa dengan tujuan untuk menghalau terjadinya transcoding pada video. Pada beberapa system ini membutuhkan waktu yang lama dan dapat menyebabkan video playback menjadi terhenti dikarenakan proses ekstraksi. Non-aktifkan fitur ini untuk membiarkan subtitle langsung dilekatkan kepada video dengan cara transcoding ketika klien tidak mendukung fitur ini." + "AllowOnTheFlySubtitleExtractionHelp": "Subtitle yang melekat di video dapat dikeluarkan dan dikirimkan kepada klien dalam bentuk text biasa dengan tujuan untuk menghalau terjadinya transcoding pada video. Pada beberapa system ini membutuhkan waktu yang lama dan dapat menyebabkan video playback menjadi terhenti dikarenakan proses ekstraksi. Non-aktifkan fitur ini untuk membiarkan subtitle langsung dilekatkan kepada video dengan cara transcoding ketika klien tidak mendukung fitur ini.", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/is-is.json b/src/strings/is-is.json index f0d39a1d06..ff8f924e22 100644 --- a/src/strings/is-is.json +++ b/src/strings/is-is.json @@ -547,5 +547,6 @@ "ConfirmDeleteItems": "Ef þessum skrám er eytt verða þær fjarlægðar úr bæði stýrikerfinu og miðlasafninu. Ertu viss um að þú viljir halda áfram?", "CommunityRating": "Mat samfélagsins", "ButtonStart": "Byrja", - "BoxSet": "Kassasett" + "BoxSet": "Kassasett", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/it.json b/src/strings/it.json index 5b20ea184e..69919fbd76 100644 --- a/src/strings/it.json +++ b/src/strings/it.json @@ -1156,7 +1156,7 @@ "SortChannelsBy": "Ordina canali per:", "SortName": "Nome ordinamento", "Sports": "Sport", - "StopRecording": "Ferma registrazione", + "StopRecording": "Interrompi registrazione", "SubtitleAppearanceSettingsAlsoPassedToCastDevices": "Queste impostazioni si applicano anche a qualsiasi riproduzione di Chromecast avviata da questo dispositivo.", "SubtitleAppearanceSettingsDisclaimer": "Queste impostazioni non si applicano a sottotitoli grafici (PGS, DVD, ecc.) o sottotitoli ASS/SSA che hanno i propri stili.", "SubtitleDownloadersHelp": "Abilita e classifica i tuoi downloader di sottotitoli preferiti in ordine di priorità.", @@ -1567,5 +1567,10 @@ "LabelRepositoryUrlHelp": "URL del repository manifest che si vuole includere.", "LabelRepositoryUrl": "URL Repository", "HeaderNewRepository": "Nuovo Repository", - "MessageNoRepositories": "Nessun repository." + "MessageNoRepositories": "Nessun repository.", + "ButtonPlayer": "Player", + "ViewAlbumArtist": "Visualizza artista dell'album", + "Writers": "Scrittori", + "ClearQueue": "Svuota la coda", + "StopPlayback": "Interrompi riproduzione" } diff --git a/src/strings/ja.json b/src/strings/ja.json index bf2cdc6153..60c814843a 100644 --- a/src/strings/ja.json +++ b/src/strings/ja.json @@ -14,7 +14,7 @@ "Alerts": "アーティスト", "All": "すべて", "AllChannels": "すべてのチャンネル", - "AllComplexFormats": "すべての複雑なフォーマット (ASS, SSA, VOBSUB, PGS, SUB/IDX, etc.)", + "AllComplexFormats": "すべての複雑なフォーマット (ASS, SSA, VOBSUB, PGS, SUB, IDX など)", "AllEpisodes": "すべてのエピソード", "AllLanguages": "すべての言語", "AllLibraries": "すべてのライブラリ", @@ -22,15 +22,15 @@ "AllowMediaConversion": "メディアの変換を許可する", "AllowMediaConversionHelp": "メディア変換機能へのアクセスを許可もしくは、拒否します。", "AllowOnTheFlySubtitleExtraction": "字幕の抽出の許可/拒否", - "AllowOnTheFlySubtitleExtractionHelp": "埋め込まれた字幕は、ビデオのトランスコーディングを防ぐために、ビデオから抽出してプレーンテキストでクライアントに配信できます。 システムによっては、これに時間がかかり、抽出中にビデオの再生が止まることがあります。 これを無効にし、埋め込み字幕がクライアントデバイスでネイティブにサポートされていない場合、ビデオのトランスコーディングが強制されます。", + "AllowOnTheFlySubtitleExtractionHelp": "埋め込まれた字幕は、ビデオのトランスコードを防ぐために、ビデオから抽出してプレーンテキストでクライアントに配信できます。 システムによっては、これに時間がかかり、抽出中にビデオの再生が止まることがあります。 これを無効にし、埋め込み字幕がクライアントデバイスでネイティブにサポートされていない場合、ビデオのトランスコードが強制されます。", "AllowRemoteAccess": "Jellyfin Serverへのリモート接続の許可。", "AllowRemoteAccessHelp": "チェックが入っていない場合すべてのリモート接続をブロックします。", "AllowedRemoteAddressesHelp": "リモート接続を許可するネットワークのIPアドレスまたはIPアドレス/マスク長 空白のままにすると、すべてのリモートアドレスが許可されます。", - "AlwaysPlaySubtitles": "字幕を常に有効にする", + "AlwaysPlaySubtitles": "常に有効", "AlwaysPlaySubtitlesHelp": "言語に合った字幕が音声言語に関係なく読み込まれます。", - "AnyLanguage": "いずれかの言語", + "AnyLanguage": "任意の言語", "Anytime": "いつでも", - "AroundTime": "{0}頃", + "AroundTime": "だいたい", "Art": "アート", "Artists": "アーティスト", "AsManyAsPossible": "できるだけ多く", @@ -47,13 +47,13 @@ "BirthLocation": "生まれた場所", "BirthPlaceValue": "生まれた場所: {0}", "Blacklist": "ブラックリスト", - "BookLibraryHelp": "オーディオブックとテキストブックに対応しています。{0}Jellyfinブック命名ガイド{1}.", + "BookLibraryHelp": "オーディオブックとテキストブックに対応しています。{0} の資料、ブック命名ガイド {1} を参照。", "Books": "ブック", "Box": "ボックス", "BoxRear": "ボックス(後)", "Browse": "ブラウズ", "BrowsePluginCatalogMessage": "利用可能なプラグインを表示するには、プラグインカタログを参照してください。", - "BurnSubtitlesHelp": "字幕フォーマットに応じて、ビデオを変換するときにサーバーが字幕を直接書き込むかどうかを決定します。 字幕の書き込みを避けると、サーバーのパフォーマンスが向上します。 特定のASS / SSA字幕だけでなく画像ベースのフォーマット(VOBSUB, PGS, SUB/IDX, etc)を焼くには自動を選択します", + "BurnSubtitlesHelp": "ビデオのトランスコード時にサーバーが字幕を焼付けるかどうかを決定します。 この字幕焼付けを避けると、サーバーのパフォーマンスが非常に向上します。 画像ベースの形式 (VOBSUB, PGS, SUB, IDX など) と特定の ASS または SSA 字幕でだけ焼付けを行うには、自動を選んでください。", "ButtonAdd": "追加", "ButtonAddMediaLibrary": "メディアライブラリを追加", "ButtonAddScheduledTaskTrigger": "トリガーを追加", @@ -186,7 +186,7 @@ "DisplayInOtherHomeScreenSections": "最新のメディアなどをホーム画面に表示する", "DisplayMissingEpisodesWithinSeasons": "シーズンの欠けているエピソードを表示する", "DisplayMissingEpisodesWithinSeasonsHelp": "これは サーバーのTVライブラリ設定でも有効にする必要があります。", - "DisplayModeHelp": "ellyfinを実行している画面の種類を選択します。", + "DisplayModeHelp": "インターフェース用のお好みのレイアウトスタイルを選びます。", "DoNotRecord": "記録しない", "Down": "下", "Download": "ダウンロード", @@ -830,7 +830,7 @@ "HeaderXmlDocumentAttribute": "XMLドキュメント属性", "HeaderXmlDocumentAttributes": "XMLドキュメント属性", "Images": "画像", - "InstallingPackage": "インストール中 {0}", + "InstallingPackage": "{0} (バージョン {1} )をインストールしています", "ItemCount": "{0} アイテム", "Items": "アイテム", "Kids": "子供", @@ -1143,5 +1143,51 @@ "ClientSettings": "クライアント設定", "Artist": "アーティスト", "AlbumArtist": "アルバム アーティスト", - "Album": "アルバム" + "Album": "アルバム", + "ButtonSyncPlay": "SyncPlay", + "DeinterlaceMethodHelp": "インターレースコンテンツをトランスコードする際に使用するデインターレース方式を選びます。", + "ButtonTogglePlaylist": "プレイリスト", + "ButtonToggleContextMenu": "さらに表示", + "BoxSet": "ボックスセット", + "AllowFfmpegThrottlingHelp": "トランスコードや remux が現在の再生位置から十分に先に進んだ場合、処理を一時停止してリソースの消費を抑えます。これは、あまり早送り・早戻しをしないで視聴する場合に便利です。再生に問題が発生した場合は、この機能をオフにしてください。", + "LabelDisplaySpecialsWithinSeasons": "放送されたシーズン内のスペシャルを表示", + "LabelDeinterlaceMethod": "インターレス解除方法:", + "LabelDefaultUserHelp": "接続されたデバイスに表示するユーザーライブラリを決定します。これは、プロファイルを使用して各デバイスに対してオーバーライドすることができます。", + "LabelDateAddedBehavior": "新規コンテンツの追加日のふるまい:", + "LabelCustomCertificatePathHelp": "カスタムドメインでTLSサポートを有効にするための証明書と秘密鍵を含むPKCS #12ファイルのパス。", + "LabelCachePathHelp": "画像などのサーバーキャッシュファイルの場所を指定します。空欄にしておくと、サーバーのデフォルトを使います。", + "LabelBlastMessageIntervalHelp": "ブラスト アライブ メッセージ間の時間を秒単位で指定します。", + "LabelBindToLocalNetworkAddressHelp": "追加の設定。http サーバをバインドするローカル IP アドレスを上書きします。空のままにしておくと、サーバは利用可能なすべてのアドレスにバインドします。この値を変更するには、Jellyfin Server を再起動する必要があります。", + "LabelAlbumArtMaxWidthHelp": "upnp:albumArtURI で公開するアルバムアートの最大解像度。", + "LabelAlbumArtMaxHeightHelp": "upnp:albumArtURI で公開するアルバムアートの最大解像度。", + "LabelAlbumArtHelp": "upnp:albumArtURI の dlna:profileID 属性で、アルバムアートに使われるPN。デバイスによっては、画像のサイズと無関係に特定の値を要求するものもあります。", + "HeaderSyncPlayEnabled": "SyncPlay を有効にしました", + "HeaderSyncPlaySelectGroup": "グループに参加", + "HeaderServerAddressSettings": "サーバー アドレス設定", + "HeaderRemoteAccessSettings": "リモート接続設定", + "HeaderHttpsSettings": "HTTPS 設定", + "HeaderFavoritePlaylists": "お気に入りのプレイリスト", + "HeaderDVR": "DVR", + "ApiKeysCaption": "現在有効にしている API キー一覧", + "EnableDetailsBannerHelp": "項目の詳細ページのトップに、バナー画像を表示します。", + "EnableDetailsBanner": "詳細画面バナー", + "EnableDecodingColorDepth10Vp9": "VP9 の10ビット ハードウェア デコードを有効に", + "EnableDecodingColorDepth10Hevc": "HEVC の 10ビット ハードウェア デコードを有効に", + "LabelEnableBlastAliveMessagesHelp": "ネットワーク上の他の UPnP デバイスによってサーバーが確実に検出されない場合、この設定を有効にします。", + "LabelEnableAutomaticPortMapHelp": "ルーター上のパブリックポートを、UPnP 経由でサーバーのローカルポートに自動的に転送します。これはルータのモデルやネットワーク構成によっては動作しない場合があります。変更はサーバーを再起動するまで適用されません。", + "LabelEmbedAlbumArtDidlHelp": "一部のデバイスでは、アルバムアートを取得するためにこの方法が好まれています。その他のデバイスでは、このオプションを有効にしても再生できない場合があります。", + "LabelDownMixAudioScaleHelp": "ダウンミックス時にオーディオの音量を増幅します。値が 1 の場合、元の音量を維持します。", + "LabelEnableHttps": "HTTPS を有効にする", + "LabelEnableDlnaPlayToHelp": "ネットワーク内のデバイスを検出し、それらをリモートコントロールできるようにします。", + "LabelEnableDlnaPlayTo": "DLNA 再生を有効にする", + "LabelEnableDlnaDebugLoggingHelp": "巨大なログファイルを作成します。トラブルシューティングでの必要な際にだけ使用してください。", + "LabelEnableDlnaClientDiscoveryIntervalHelp": "Jellyfin が実行する SSDP 検索の間隔を決めます(秒単位)。", + "LabelGroupMoviesIntoCollectionsHelp": "ムービーリストを表示する際、コレクションに属するムービーを1つのグループとして表示します。", + "LabelServerNameHelp": "この名前はサーバーを識別するために使用します。デフォルトではサーバーのコンピュータ名です。", + "LabelExtractChaptersDuringLibraryScanHelp": "ライブラリー スキャン中に動画を取り込んだときに、チャプター画像を生成します。もしくは、スケジュールタスクの中でチャプター画像を抽出することで、通常のライブラリー スキャンをより速く完了させることができます。", + "LabelExtractChaptersDuringLibraryScan": "ライブラリーをスキャンしながら、チャプター画像を生成する", + "LabelBaseUrlHelp": "サーバーの URL にカスタム サブディレクトリを加えます。例 : http://example.com/<baseurl>", + "LabelEnableSingleImageInDidlLimitHelp": "Didl 内に複数の画像が埋め込まれている場合、一部のデバイスでは正しくレンダリングされません。", + "LabelEnableRealtimeMonitorHelp": "ファイルへの変更は、サポートされているファイルシステム上ですぐに処理されます。", + "LabelEnableHttpsHelp": "構成された HTTPS ポートからサーバーがリッスンするのを有効にします。この機能を有効にするには、適切な証明書を設定する必要があります。" } diff --git a/src/strings/kk.json b/src/strings/kk.json index 6acd5e46b7..5532af90f5 100644 --- a/src/strings/kk.json +++ b/src/strings/kk.json @@ -1543,5 +1543,6 @@ "HeaderRemoteAccessSettings": "Qashyqtan qatynaý parametrleri", "HeaderHttpsSettings": "HTTPS parametrleri", "HeaderFavoritePlaylists": "Tańdaýly oınatý tizimder", - "HeaderDVR": "DVR" + "HeaderDVR": "DVR", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/ko.json b/src/strings/ko.json index cc5f63e541..660b3d34a0 100644 --- a/src/strings/ko.json +++ b/src/strings/ko.json @@ -810,7 +810,7 @@ "AirDate": "방영 일자", "Aired": "방영됨", "Alerts": "알림", - "AllComplexFormats": "모든 복잡한 포맷 (ASS, SSA, VOBSUB, PGS, SUB, IDX)", + "AllComplexFormats": "모든 복잡한 포맷 (ASS, SSA, VOBSUB, PGS, SUB, IDX,...)", "AllLibraries": "모든 라이브러리", "AllowMediaConversion": "미디어 변환 허용", "AllowOnTheFlySubtitleExtraction": "실시간 자막 추출 허용", @@ -821,7 +821,7 @@ "AlwaysPlaySubtitles": "항상 표시", "AlwaysPlaySubtitlesHelp": "오디오 언어를 불문하고 언어 설정에 적합한 자막을 불러옵니다.", "AnyLanguage": "모든 언어", - "AroundTime": "대략 {0}", + "AroundTime": "대략", "Art": "아트", "AsManyAsPossible": "최대한 많이", "Ascending": "오름차순", @@ -1429,5 +1429,9 @@ "ButtonToggleContextMenu": "더보기", "Rate": "평", "PerfectMatch": "정확히 일치", - "OtherArtist": "다른 아티스트" + "OtherArtist": "다른 아티스트", + "ButtonSyncPlay": "SyncPlay", + "HeaderDVR": "DVR", + "EnableDecodingColorDepth10Vp9": "10비트 VP9하드웨어 디코딩 사용합니다", + "EnableDecodingColorDepth10Hevc": "10비트 HEVC하드웨어 디코딩 사용합니다" } diff --git a/src/strings/lt-lt.json b/src/strings/lt-lt.json index 773a7c5c8b..c8c2b6e448 100644 --- a/src/strings/lt-lt.json +++ b/src/strings/lt-lt.json @@ -1014,5 +1014,6 @@ "ButtonToggleContextMenu": "Daugiau", "ButtonSplit": "Skirstyti", "AskAdminToCreateLibrary": "Prašyti administratoriaus, kad sukurtų mediateka.", - "Album": "Albumas" + "Album": "Albumas", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/lv.json b/src/strings/lv.json index c58374ad24..18346bbda0 100644 --- a/src/strings/lv.json +++ b/src/strings/lv.json @@ -602,14 +602,14 @@ "AsManyAsPossible": "Cik vien iespējams", "Artists": "Izpildītāji", "Art": "Māksla", - "AroundTime": "Ap {0}", + "AroundTime": "Ap", "Anytime": "Jebkad", "AnyLanguage": "Jebkura Valoda", "AlwaysPlaySubtitles": "Vienmēr Rādīt", "AllowedRemoteAddressesHelp": "Ar komatiem atdalīts IP adrešu vai IP/tīkla masku saraksts, kas norāda uz tīkliem, kas var pieslēgties attālināti. Ja atstāts tukšs, visas attālinātās adreses tiks atļautas.", "AllowRemoteAccessHelp": "Ja atķeksēts, visi attālinātie savienojumi tiks bloķēti.", "AllowRemoteAccess": "Atļaut attālinātus savienojumus šim Jellyfin Serverim.", - "AllowOnTheFlySubtitleExtraction": " ", + "AllowOnTheFlySubtitleExtraction": "Atļaut subtitru izvilkšanu atskaņošanas laikā", "AllowMediaConversion": "Atļaut multimēdiju pārveidošanu", "AllLibraries": "Visas bibliotēkas", "AllLanguages": "Visas valodas", @@ -1231,5 +1231,7 @@ "MessageUnauthorizedUser": "Jūs neesat autorizēti lai piekļūtu serverim šajā brīdī. Lūdzu sazinieties ar savu servera administratoru priekš papildus informācijas.", "MessageInstallPluginFromApp": "Šis paplašinājums ir jāuzstāda no lietotnes, kurā jūs to vēlaties izmantot.", "LabelEmbedAlbumArtDidl": "Ievietot albumu vākus iekš Didl", - "LabelSelectFolderGroups": "Automātiski grupēt saturu no sekojošām datnēm skatos kā Filmas, Mūzika un TV:" + "LabelSelectFolderGroups": "Automātiski grupēt saturu no sekojošām datnēm skatos kā Filmas, Mūzika un TV:", + "AllowFfmpegThrottlingHelp": "Kad trans-kodējums vai remux tiek pietiekami tālu priekšā pašreizējai atskaņošanas vietai, process tiks pauzēts lai patērētu mazāk resursu. Tas ir noderīgākais skatoties bez biežas pārlēkšanas. Atspējo šo ja saskaries ar atskaņošanas problēmām.", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/mr.json b/src/strings/mr.json index 381c609a9e..37cbc403de 100644 --- a/src/strings/mr.json +++ b/src/strings/mr.json @@ -97,5 +97,7 @@ "ButtonRemove": "काढून टाका", "ButtonPreviousTrack": "मागचा ट्रॅक", "ButtonPlay": "प्ले", - "ButtonPause": "पॉझ" + "ButtonPause": "पॉझ", + "ButtonSyncPlay": "SyncPlay", + "Collections": "संग्रह" } diff --git a/src/strings/ms.json b/src/strings/ms.json index c377e52af1..d5f9259c21 100644 --- a/src/strings/ms.json +++ b/src/strings/ms.json @@ -102,5 +102,17 @@ "HeaderContinueWatching": "Terus Menonton", "Genres": "Genre-genre", "Collections": "Koleksi", - "Channels": "Saluran" + "Channels": "Saluran", + "ButtonSyncPlay": "SyncPlay", + "Movies": "Filem", + "HeaderNextUp": "Seterusnya", + "HeaderLiveTV": "TV Siaran Langsung", + "HeaderFavoriteSongs": "Lagu-lagu Kegemaran", + "HeaderFavoriteShows": "Rancangan-rancangan Kegemaran", + "HeaderFavoriteEpisodes": "Episod-episod Kegemaran", + "HeaderFavoriteArtists": "Artis-artis Kegemaran", + "HeaderFavoriteAlbums": "Album-album Kegemaran", + "HeaderAlbumArtists": "Album Artis-artis", + "Folders": "Fail-fail", + "Favorites": "Kegemaran" } diff --git a/src/strings/nb.json b/src/strings/nb.json index aed96da2c6..d729b0c025 100644 --- a/src/strings/nb.json +++ b/src/strings/nb.json @@ -729,7 +729,7 @@ "MessageNoAvailablePlugins": "Ingen tilgjengelige programtillegg.", "MessageNoMovieSuggestionsAvailable": "Ingen filmforslag er tilgjengelige enda. Begynn å se og vurdere filmer, og kom tilbake hit etterpå for se anbefalingene dine.", "MessageNoPluginsInstalled": "Du har ingen programtillegg installert.", - "MessageNoTrailersFound": "Ingen trailere funnet. Installer trailer-tilleggskanalen for å forbedre filmopplevelsen ved å legge til et bibliotek med trailere fra Internett.", + "MessageNoTrailersFound": "Installer trailer-tilleggskanalen for å forbedre filmopplevelsen ved å legge til et bibliotek med trailere fra Internett.", "MessageNothingHere": "Ingenting her.", "MessagePasswordResetForUsers": "Følgende brukere har fått passordet sitt tilbakestilt. De kan nå logge inn med PIN-kodene som ble brukt til å utføre tilbakestillingen.", "MessagePlayAccessRestricted": "Avspilling av dette innholdet er for tiden begrenset. Ta kontakt med serverens administrator for mer informasjon.", @@ -1449,7 +1449,7 @@ "HeaderFavoritePeople": "Favorittpersoner", "Raised": "Opphøyet", "ButtonSplit": "Del opp", - "SelectAdminUsername": "Vennligst velg et brukernavn for administrator kontoen. ", + "SelectAdminUsername": "Vennligst velg et brukernavn for administrator-kontoen.", "HeaderNavigation": "Navigering", "MessageConfirmAppExit": "Vil du avslutte?", "CopyStreamURLError": "Det var en feil under kopiering av URL'en.", @@ -1470,8 +1470,8 @@ "Artist": "Artist", "AlbumArtist": "Albumartist", "Album": "Album", - "LabelLibraryPageSizeHelp": "Velger hvor mange elementer som skal bli vist på en bibliotek side. Velg 0 for å deaktivere.", - "LabelLibraryPageSize": "Biblioteks side størrelse:", + "LabelLibraryPageSizeHelp": "Angir hvor mange elementer som vises på en bibliotekside. Velg 0 for å deaktivere oppdeling i sider.", + "LabelLibraryPageSize": "Størrelse på bibliotekside:", "LabelDeinterlaceMethod": "Deinterlacing metode:", "HeaderFavoritePlaylists": "Favorittspillelister", "DeinterlaceMethodHelp": "Velg deinterlacing metoden som skal bli brukt når man transkoder interlaced innhold.", @@ -1552,5 +1552,25 @@ "HeaderDVR": "Opptak", "ApiKeysCaption": "Liste over aktive API-nøkler", "EnableDetailsBannerHelp": "Viser et bildebanner øverst på detaljsiden.", - "EnableDetailsBanner": "Detaljebanner" + "EnableDetailsBanner": "Detaljebanner", + "ButtonSyncPlay": "SyncPlay", + "LabelRepositoryName": "Navn på kilde", + "LabelRepositoryUrlHelp": "Lokasjonen til kilde-manifestet som du ønsker å inkludere.", + "LabelRepositoryUrl": "URL for kilde", + "HeaderNewRepository": "Ny kilde", + "MessageNoRepositories": "Ingen kilder.", + "EnableFasterAnimationsHelp": "Bruk raskere animasjoner og overganger", + "EnableFasterAnimations": "Raskere animasjoner", + "EnableDecodingColorDepth10Vp9": "Aktiver maskinvaredekoding for VP9", + "EnableDecodingColorDepth10Hevc": "Aktiver maskinvaredekoding for 10-Bit HEVC", + "ButtonPlayer": "Spiller", + "ButtonCast": "Cast", + "Writers": "Forfattere", + "TabRepositories": "Kilder", + "MessageNoGenresAvailable": "Aktiver noen metadata-kilder for å hente sjangre fra internett.", + "MessageAddRepository": "Hvis du ønsker å legge til en ny kilde klikker du på knappen ved siden av overskriften og fyller ut forespurt informasjon.", + "LabelRepositoryNameHelp": "Et egendefinert navn for å skille denne kilden fra andre som er lagt til på serveren din.", + "ClearQueue": "Tøm køen", + "ViewAlbumArtist": "Vis albumartist", + "StopPlayback": "Stopp avspilling" } diff --git a/src/strings/nl.json b/src/strings/nl.json index 32c5d20b11..242c3d7f15 100644 --- a/src/strings/nl.json +++ b/src/strings/nl.json @@ -846,7 +846,7 @@ "MessageNoAvailablePlugins": "Geen beschikbare Plugins.", "MessageNoMovieSuggestionsAvailable": "Er zijn momenteel geen film suggesties beschikbaar. Begin met het bekijken en waardeer uw films, kom daarna terug om uw aanbevelingen te bekijken.", "MessageNoPluginsInstalled": "U heeft geen plugins geïnstalleerd.", - "MessageNoTrailersFound": "Geen trailers gevonden. Installeer het Trailers kanaal om uw film ervaring te verbeteren door middel van het toevoegen van een bibliotheek met internet trailers.", + "MessageNoTrailersFound": "Installeer het Trailers kanaal om uw film ervaring te verbeteren door middel van het toevoegen van een bibliotheek met internet trailers.", "MessageNothingHere": "Lijst is leeg.", "MessagePasswordResetForUsers": "De volgende gebruikers hebben hun wachtwoord laten herstellen. Zij kunnen nu inloggen met de pin codes die gebruikt werden om de herstel te voltooien.", "MessagePlayAccessRestricted": "Afspelen hiervan is op dit moment niet toegestaan. Neem contact op met uw server beheerder voor meer informatie.", @@ -1558,5 +1558,13 @@ "HeaderRemoteAccessSettings": "Externe toegang instellingen", "HeaderHttpsSettings": "HTTPS instellingen", "HeaderDVR": "DVR", - "ApiKeysCaption": "Lijst met de momenteel ingeschakelde API-sleutels" + "ApiKeysCaption": "Lijst met de momenteel ingeschakelde API-sleutels", + "ButtonSyncPlay": "SyncPlay", + "ShowMore": "Laat meer zien", + "ShowLess": "Laat minder zien", + "MessageNoGenresAvailable": "Stel sommige metadataproviders in staat om genres van internet te halen.", + "EnableFasterAnimationsHelp": "Gebruik snellere animaties en overgangen", + "EnableFasterAnimations": "Snellere animaties", + "EnableDecodingColorDepth10Vp9": "Schakel 10-bits hardwarecodering in voor VP9", + "EnableDecodingColorDepth10Hevc": "Schakel 10-bits hardwarecodering in voor HEVC" } diff --git a/src/strings/pl.json b/src/strings/pl.json index 3c470640e1..fcb35e0643 100644 --- a/src/strings/pl.json +++ b/src/strings/pl.json @@ -1436,8 +1436,8 @@ "LabelTranscodingFramerate": "Transkodowanie w kl/s:", "LabelSize": "Wielkość:", "LabelPleaseRestart": "Zmiany zaczną obowiązywać po ręcznym przeładowaniu klienta WWW.", - "LabelPlayMethod": "Meroda odtwarzania:", - "LabelPlayer": "Gracz:", + "LabelPlayMethod": "Metoda odtwarzania:", + "LabelPlayer": "Odtwarzacz:", "LabelBaseUrlHelp": "Możesz tutaj dodać niestandardowy podkatalog, aby uzyskać dostęp do serwera z bardziej unikalnego adresu URL.", "LabelBaseUrl": "Podstawowy adres URL:", "LabelBitrate": "Bitrate:", @@ -1479,5 +1479,6 @@ "DeinterlaceMethodHelp": "Wybierz metodę usuwania przeplotu używaną podczas transkodowania.", "ClientSettings": "Ustawienia klienta", "ButtonTogglePlaylist": "Playlista", - "ButtonToggleContextMenu": "Więcej" + "ButtonToggleContextMenu": "Więcej", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/pr.json b/src/strings/pr.json index 20dc534f54..ea27024045 100644 --- a/src/strings/pr.json +++ b/src/strings/pr.json @@ -22,5 +22,8 @@ "HeaderCastCrew": "Mateys", "Add": "Upend", "Actor": "Privateer", - "AccessRestrictedTryAgainLater": "Ye arn't appearin' on the list o' the livin'!" + "AccessRestrictedTryAgainLater": "Ye arn't appearin' on the list o' the livin'!", + "ButtonSyncPlay": "SyncPlay", + "AddedOnValue": "Upended {0}", + "AddToCollection": "Add to ye collection" } diff --git a/src/strings/pt-br.json b/src/strings/pt-br.json index d043b19767..1f3c160c12 100644 --- a/src/strings/pt-br.json +++ b/src/strings/pt-br.json @@ -564,7 +564,7 @@ "LabelDynamicExternalId": "Id de {0}:", "LabelEasyPinCode": "Código pin fácil:", "LabelEmbedAlbumArtDidl": "Arte do álbum incorporada no Didl", - "LabelEmbedAlbumArtDidlHelp": "Alguns dispositivos preferem este método para obter a arte do álbum. Outros podem falhar ao reproduzir com esta opção ativada.", + "LabelEmbedAlbumArtDidlHelp": "Alguns dispositivos preferem este método para obter a arte do álbum. Outros podem falhar para reproduzir com esta opção ativada.", "LabelEnableAutomaticPortMap": "Ativar mapeamento automático de portas", "LabelEnableAutomaticPortMapHelp": "Tentar mapear automaticamente a porta pública para a porta local do seu servidor através de UPnP. Pode não funcionar em alguns modelos de roteadores. As mudanças não serão aplicadas até a reinicialização do servidor.", "LabelEnableBlastAliveMessages": "Mensagens ao vivo", @@ -601,7 +601,7 @@ "LabelH264Crf": "CRF de codificação H264:", "LabelEncoderPreset": "Preset de codificação H264:", "LabelHardwareAccelerationType": "Aceleração de hardware:", - "LabelHardwareAccelerationTypeHelp": "Aceleração por hardware requer configurações adicionais.", + "LabelHardwareAccelerationTypeHelp": "A aceleração de hardware requer configuração adicional.", "LabelHomeNetworkQuality": "Qualidade da rede local:", "LabelHomeScreenSectionValue": "Seção {0} da tela inicial:", "LabelHttpsPort": "Número da porta local de HTTPS:", @@ -626,7 +626,7 @@ "LabelKodiMetadataEnablePathSubstitution": "Ativar substituição de local", "LabelKodiMetadataEnablePathSubstitutionHelp": "Ativa a substituição do local das imagens usando as configurações de substituição de local do servidor.", "LabelKodiMetadataSaveImagePaths": "Salvar o local das imagens dentro dos arquivos nfo", - "LabelKodiMetadataSaveImagePathsHelp": "Isto é recomendado se os nomes dos arquivos de imagem não estão de acordo com as exigências do Kodi.", + "LabelKodiMetadataSaveImagePathsHelp": "Isto é recomendado se os nomes dos arquivos de imagem não estão de acordo com as recomendações do Kodi.", "LabelKodiMetadataUser": "Salvar informações do que o usuário assiste aos NFO's para:", "LabelKodiMetadataUserHelp": "Salva os dados para arquivos NFO para que outras aplicações possam usar.", "LabelLanNetworks": "Redes LAN:", @@ -662,7 +662,7 @@ "LabelMethod": "Método:", "LabelMinBackdropDownloadWidth": "Tamanho mínimo da imagem de fundo para download:", "LabelMinResumeDuration": "Duração mínima para retomar:", - "LabelMinResumeDurationHelp": "Tempo mínimo do vídeo em segundos que permitirá continuar a reprodução a partir do ponto que parou.", + "LabelMinResumeDurationHelp": "A menor duração de vídeo em segundos que salvará o local de reprodução e permitirá que retome.", "LabelMinResumePercentage": "Porcentagem mínima para retomar:", "LabelMinResumePercentageHelp": "Títulos são considerados como não reproduzidos se parados antes deste tempo.", "LabelMinScreenshotDownloadWidth": "Tamanho mínimo da captura de tela para download:", @@ -676,7 +676,7 @@ "LabelMoviePrefixHelp": "Se os títulos dos filmes devem ter um prefixo, digite-o aqui para que o servidor possa usá-lo corretamente.", "LabelMovieRecordingPath": "Local de gravação de filme (opcional):", "LabelMusicStreamingTranscodingBitrate": "Bitrate da transcodificação de músicas:", - "LabelMusicStreamingTranscodingBitrateHelp": "Especifique uma taxa de bits máxima ao transmitir músicas.", + "LabelMusicStreamingTranscodingBitrateHelp": "Define o bitrate máximo do streaming de músicas.", "LabelName": "Nome:", "LabelNewName": "Novo nome:", "LabelNewPassword": "Nova senha:", @@ -1323,7 +1323,7 @@ "Horizontal": "Horizontal", "LabelAbortedByServerShutdown": "(Abortado devido ao desligamento do servidor)", "LabelCache": "Cache:", - "LabelLogs": "Logs:", + "LabelLogs": "Registros:", "LabelProfileCodecs": "Codecs:", "LabelSkin": "Tema:", "LabelStatus": "Status:", @@ -1511,7 +1511,7 @@ "LabelNightly": "Nightly", "LabelStable": "Estável", "LabelChromecastVersion": "Versão do Chromecast", - "LabelEnableHttpsHelp": "Habilita que o servidor escute na porta HTTPS configurada. Um certificado válido também deve ser configurado para que isso entre em vigor.", + "LabelEnableHttpsHelp": "Permite que o servidor escute na porta HTTPS configurada. Um certificado válido também deve ser configurado para que isso entre em vigor.", "LabelEnableHttps": "Habilitar HTTPS", "HeaderServerAddressSettings": "Configurações da localização do servidor", "HeaderRemoteAccessSettings": "Configurações de acesso remoto", @@ -1529,7 +1529,7 @@ "MessageSyncPlayGroupDoesNotExist": "Falha ao participar de grupo pois o mesmo não existe.", "MessageSyncPlayPlaybackPermissionRequired": "É necessária permissão de reprodução.", "MessageSyncPlayNoGroupsAvailable": "Nenhum grupo disponível. Comece a reproduzir algo primeiro.", - "MessageSyncPlayGroupWait": "{0} está carregando...", + "MessageSyncPlayGroupWait": "{0} está carregando. . .", "MessageSyncPlayUserLeft": "{0} deixou o grupo.", "MessageSyncPlayUserJoined": "{0} se juntou ao grupo.", "MessageSyncPlayDisabled": "SyncPlay desativado.", @@ -1567,5 +1567,10 @@ "LabelRepositoryUrlHelp": "A localização do manifesto do repositório que você deseja incluir.", "LabelRepositoryUrl": "URL do repositório", "HeaderNewRepository": "Novo repositório", - "MessageNoRepositories": "Não há repositórios." + "MessageNoRepositories": "Não há repositórios.", + "ButtonPlayer": "Reprodutor", + "Writers": "Escritores", + "ClearQueue": "Limpar fila", + "StopPlayback": "Parar reprodução", + "ViewAlbumArtist": "Ver artista do álbum" } diff --git a/src/strings/pt-pt.json b/src/strings/pt-pt.json index 6f8e218a4c..b482189ffb 100644 --- a/src/strings/pt-pt.json +++ b/src/strings/pt-pt.json @@ -320,7 +320,7 @@ "LabelEmbedAlbumArtDidl": "Incorporar a capa do álbum no DIDL", "LabelEmbedAlbumArtDidlHelp": "Alguns dispositivos preferem este método para obter a capa do álbum. Noutros pode falhar a reprodução com esta opção ativada.", "LabelEnableAutomaticPortMap": "Ativar mapeamento automático de portas", - "LabelEnableAutomaticPortMapHelp": "Tenta mapear automaticamente o porto público para o porto local através de UPnP. Isto poderá não funcionar em alguns modelos de routers.", + "LabelEnableAutomaticPortMapHelp": "Automaticamente encaminha o porto público para o porto local através de UPnP. Isto poderá não funcionar em alguns modelos de routers ou devido às configurações da rede. As alterações só serão aplicadas após o reiniciar do servidor", "LabelEnableBlastAliveMessages": "Enviar mensagens de reconhecimento", "LabelEnableBlastAliveMessagesHelp": "Ativar esta opção se o servidor não for convenientemente detetado por outros dispositivos UPnP na rede.", "LabelEnableDlnaClientDiscoveryInterval": "Intervalo para descoberta de clientes (segundos)", @@ -605,7 +605,7 @@ "OptionMissingEpisode": "Episódios em Falta", "OptionMonday": "Segunda", "OptionNameSort": "Nome", - "OptionNew": "Nova...", + "OptionNew": "Nova…", "OptionNone": "Nenhum", "OptionOnAppStartup": "Ao iniciar a aplicação", "OptionOnInterval": "Num intervalo", @@ -768,13 +768,13 @@ "AllowMediaConversion": "Permitir conversão multimédia", "AllowMediaConversionHelp": "Permitir ou negar acesso à funcionalidade de conversão multimédia.", "AllowOnTheFlySubtitleExtraction": "Permitir a extração de legendas em tempo real", - "AllowOnTheFlySubtitleExtractionHelp": "Legendas integradas podem ser extraídas do vídeo e enviadas como texto simples para os clientes para evitar transcodificação. Em certos dispositivos, esta poderá ser uma operação demorada e pode causar paragens de reprodução durante o processo de extração. Desative esta opção para que as legendas sejam integradas no vídeo durante a conversão para um formato suportado pelo dispositivo de destino.", + "AllowOnTheFlySubtitleExtractionHelp": "Legendas integradas podem ser extraídas do vídeo e enviadas como texto simples para os clientes para evitar transcodificação. Em certos dispositivos, esta poderá ser uma operação demorada e pode causar interrupções de reprodução durante o processo de extração. Desative esta opção para que as legendas sejam integradas no vídeo durante a conversão para um formato suportado pelo dispositivo de destino.", "AllowRemoteAccess": "Permitir ligações remotas a este Jellyfin Server.", "AllowRemoteAccessHelp": "Se inativo, todas as ligações remotas serão bloqueadas.", "AllowedRemoteAddressesHelp": "Lista de IP ou IP/Máscara, separados por vírgulas, com permissão para se ligar remotamente. Se deixado em branco, todos os endereços remotos serão permitidos.", - "AlwaysPlaySubtitles": "Mostrar sempre legendas", + "AlwaysPlaySubtitles": "Reproduzir Sempre", "AlwaysPlaySubtitlesHelp": "Legendas correspondentes à língua preferencial vão ser sempre carregadas, independentemente do idioma do áudio.", - "AnyLanguage": "Qualquer idioma", + "AnyLanguage": "Qualquer linguagem", "Artists": "Artistas", "Ascending": "Crescente", "AspectRatio": "Proporção", @@ -785,7 +785,7 @@ "BirthPlaceValue": "Local de nascimento: {0}", "Blacklist": "Lista Negra", "Books": "Livros", - "BurnSubtitlesHelp": "Determina se o servidor deve integrar as legendas durante a conversão de vídeo, dependendo do formato da legenda. Evitar integração de legendas melhora o desempenho do servidor. Selecione Auto para que legendas baseadas em imagem (VOBSUB, PGS, SUB/IDX), e certos formatos ASS/SSA sejam integrados.", + "BurnSubtitlesHelp": "Determina se o servidor deve integrar as legendas durante a conversão de vídeo. Evitar a integração de legendas melhora o desempenho do servidor. Selecione Auto para que legendas baseadas em imagem (VOBSUB, PGS, SUB/IDX), e certos formatos ASS/SSA sejam integrados.", "Channels": "Canais", "Collections": "Coleções", "Favorites": "Favoritos", @@ -831,7 +831,7 @@ "Browse": "Procurar", "BoxRear": "Caixa (verso)", "Box": "Caixa", - "BookLibraryHelp": "Livros de texto e áudio são suportados. Consulte o guia de nomenclatura de livros{1}.", + "BookLibraryHelp": "Livros digitais e áudio livros são suportados. Consulte o guia de nomenclatura de livros{1}.", "BirthLocation": "Local de nascimento", "AsManyAsPossible": "Tantos quanto possível", "Art": "Capa", @@ -963,7 +963,7 @@ "LabelAbortedByServerShutdown": "(Abortado - Servidor encerrado)", "Kids": "Crianças", "Items": "Itens", - "InstallingPackage": "A instalar {0}", + "InstallingPackage": "A instalar {0} (version {1})", "HttpsRequiresCert": "Para activar ligações seguras, é necessário fornecer um certificado SSL confiável. Forneça um certificado SSL ou desactive as ligações seguras.", "DirectStreamHelp1": "O tipo de multimédia (H.264, AC3, etc.) e a sua resolução são compatíveis com o dispositivo, no entanto, o formato (mkv, avi, wmv, etc.) não é. O conteúdo é reempacotado em tempo real antes de ser enviado para o dispositivo.", "DirectPlaying": "Reprodução direta", @@ -1041,7 +1041,7 @@ "HeaderPlayOn": "Reproduzir Em", "HeaderNextVideoPlayingInValue": "Reprodução do próximo vídeo a iniciar em {0}", "HeaderNextEpisodePlayingInValue": "Reprodução do próximo episódio a iniciar em {0}", - "HardwareAccelerationWarning": "Ativar a aceleração por hardware pode causar instabilidade em alguns ambientes. Garanta que o sistema operativo e os controladores da placa gráfica estão completamente atualizados. Se tiver dificuldades em reproduzir vídeo depois de alterar esta opção, pode ser necessário repôr em \\\"Auto\\\".", + "HardwareAccelerationWarning": "Ativar a aceleração por hardware pode causar instabilidade em alguns ambientes. Garanta que o sistema operativo e os controladores da placa gráfica estão completamente atualizados. Se tiver dificuldades em reproduzir vídeo depois de alterar esta opção, pode ser necessário repôr as definições para o parâmetro \\\"Nenhum\\\".", "Display": "Visualização", "ManageLibrary": "Gerir biblioteca", "HeaderLibraryOrder": "Ordenação da Biblioteca", @@ -1102,7 +1102,7 @@ "HeaderNewDevices": "Novos Dispositivos", "HeaderRecordingOptions": "Opções de Gravação", "HeaderSortOrder": "Direção de Ordenação", - "LabelBaseUrlHelp": "Pode adicionar uma sub-pasta personalizada aqui para aceder ao servidor através de um URL mais direto.", + "LabelBaseUrlHelp": "Adiciona uma sub-pasta personalizada ao URL do servidor. Por exemplo: http://exemplo.com/<baseurl>", "LabelMoviePrefixHelp": "Se aplicar um prefixo aos títulos dos filmes, introduza-o aqui para que o servidor consiga tratá-los corretamente.", "LabelPleaseRestart": "As alterações produzirão efeito depois de recarregar a página web.", "LabelRecordingPathHelp": "Especifique a localização por defeito para guardar as gravações. Se for deixado em branco, será utilizada a pasta base do servidor.", @@ -1112,7 +1112,7 @@ "HeaderMusicQuality": "Qualidade da Música", "HeaderMyDevice": "O Meu Dispositivo", "HeaderSortBy": "Ordenar Por", - "LabelOptionalNetworkPathHelp": "Se esta pasta estiver partilhada na rede, fornecer o caminho de rede pode permitir aos clientes aceder diretamente aos ficheiros multimédia.", + "LabelOptionalNetworkPathHelp": "Se esta pasta estiver partilhada na rede, fornecer o caminho de rede pode permitir aos clientes aceder diretamente aos ficheiros multimédia. For example, {0} or {1}.", "LabelPersonRoleHelp": "Exemplo: motorista da carrinha de gelados", "LabelPlayer": "Reprodutor:", "LabelServerName": "Nome do servidor:", @@ -1326,7 +1326,7 @@ "No": "Não", "OptionRegex": "Expressão Regular", "OptionCaptionInfoExSamsung": "CaptionInfoEx (Samsung)", - "NoSubtitles": " Sem legendas", + "NoSubtitles": "Sem legendas", "NoSubtitleSearchResultsFound": "Sem resultados.", "NoNewDevicesFound": "Não foi encontrado nenhum dispositivo novo. Para adicionar um novo sintonizador, feche este diálogo e introduza manualmente as informações do dispositivo.", "NextUp": "A Seguir", @@ -1337,7 +1337,7 @@ "Name": "Nome", "MusicVideo": "Videoclip", "MusicArtist": "Artista de Música", - "MusicAlbum": " Álbum de Música", + "MusicAlbum": "Álbum de Música", "MoreMediaInfo": "Informações", "MediaInfoBitrate": "Taxa de Bits", "LabelUserAgent": "User-Agent:", @@ -1452,5 +1452,55 @@ "AllowFfmpegThrottlingHelp": "Suspende o processo de transcodificação assim que este avance o suficiente após o ponto de reprodução atual, para poupança de recursos. Esta funcionalidade é mais útil quando a reprodução é maioritariamente contínua, sem avançar ou recuar manualmente. Desative esta opção caso haja problemas de reprodução.", "AllowFfmpegThrottling": "Reduzir Taxa de Transcodificação", "PreferEmbeddedTitlesOverFileNamesHelp": "Determina o título a apresentar por defeito quando não é possível carregar metadados locais nem da Internet.", - "OptionSaveMetadataAsHiddenHelp": "Alterar esta definição apenas afetará metadados guardados futuramente. Ficheiros existentes serão atualizados assim que forem alterados pelo Servidor Jellyfin." + "OptionSaveMetadataAsHiddenHelp": "Alterar esta definição apenas afetará metadados guardados futuramente. Ficheiros existentes serão atualizados assim que forem alterados pelo Servidor Jellyfin.", + "ButtonSyncPlay": "SyncPlay", + "LabelRepositoryUrl": "URL do Repositório", + "HeaderNewRepository": "Novo Repositório", + "MessageNoRepositories": "Sem repositórios.", + "MessageUnauthorizedUser": "Não está autorizado a aceder ao servidor neste momento. Por favor contacte o administador deste servidor para informação mais detalhada.", + "LabelSyncPlayAccess": "Acesso \"SyncPlay\"", + "LabelSyncPlayAccessNone": "Desativar para este utilizador", + "LabelSyncPlayAccessJoinGroups": "Permitir utilizador a aderir a grupos", + "LabelSyncPlayAccessCreateAndJoinGroups": "Autorizar utilizadores a criar e aderir a grupos", + "LabelSyncPlayLeaveGroupDescription": "Desativar \"SyncPlay\"", + "LabelSyncPlayLeaveGroup": "Abandonar grupo", + "LabelSyncPlayNewGroupDescription": "Criar novo grupo", + "LabelSyncPlayNewGroup": "Novo grupo", + "LabelSyncPlaySyncMethod": "Método de Sincronização:", + "LabelSyncPlayPlaybackDiff": "Diferença no tempo de Reprodução:", + "MillisecondsUnit": "ms", + "LabelSyncPlayTimeOffset": "Diferença de tempo com o servidor:", + "EnableFasterAnimationsHelp": "Utilizar animações e transições mais rápidas", + "EnableFasterAnimations": "Animações Rápidas", + "LabelRequireHttpsHelp": "Se selecionado, o servidor irá automaticamente redirecionar todos os pedidos em HTTP para HTTPS. Isto não surte efeito caso o servidor não esteja configurado em HTTPS.", + "LabelRequireHttps": "Exigir HTTPS", + "LabelNightly": "\"Nightly\"", + "LabelStable": "Estável", + "LabelChromecastVersion": "Versão do \"Chromecast\"", + "LabelLibraryPageSizeHelp": "Define a quantidade de items a apresentar na página de uma Biblioteca. Para desativar a existência de paginação, introduza o valor 0.", + "LabelLibraryPageSize": "Tamanho da página da Biblioteca:", + "LabelEnableHttpsHelp": "Permite que o servidor escute na porta HTTPS configurada. Um certificado válido também deve ser configurado para que isso entre em vigor.", + "LabelEnableHttps": "Ativar HTTPS", + "LabelDeinterlaceMethod": "Método de desentrelaçamento:", + "HeaderSyncPlayEnabled": "SyncPlay ativado", + "HeaderSyncPlaySelectGroup": "Aderir a um grupo", + "HeaderServerAddressSettings": "Definições da Localização do Servidor", + "HeaderRemoteAccessSettings": "Definições do Acesso Remoto", + "HeaderHttpsSettings": "Definições de HTTPS", + "HeaderFavoritePlaylists": "Listas de Reprodução Favoritas", + "HeaderDVR": "Gravações (DVR)", + "ApiKeysCaption": "Lista das chaves de API atualmente ativadas", + "Episode": "Episódio", + "EnableDetailsBannerHelp": "Mostra uma imagem no topo da página dos detalhes do item.", + "EnableDetailsBanner": "Cartaz de Detalhes", + "EnableDecodingColorDepth10Vp9": "Ativar descodificação de hardware de 10-Bits para VP9", + "EnableDecodingColorDepth10Hevc": "Ativar descodificação de hardware de 10-Bits para HEVC", + "DeinterlaceMethodHelp": "Selecionar um método de desentrelaçamento para converter conteúdo entrelaçado.", + "ClientSettings": "Definições do Cliente", + "ButtonTogglePlaylist": "Lista de Reprodução", + "ButtonToggleContextMenu": "Mais", + "BoxSet": "Coleção", + "Artist": "Artista", + "AlbumArtist": "Artista do Álbum", + "Album": "Álbum" } diff --git a/src/strings/pt.json b/src/strings/pt.json index 60b2c1cd97..9d6f3faf37 100644 --- a/src/strings/pt.json +++ b/src/strings/pt.json @@ -1416,5 +1416,6 @@ "HeaderDVR": "DVR", "ApiKeysCaption": "Lista das chaves de API ativadas no momento", "ButtonTogglePlaylist": "Lista de leitura", - "ButtonToggleContextMenu": "Mais" + "ButtonToggleContextMenu": "Mais", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/ro.json b/src/strings/ro.json index 8b560a341e..c1ef5caf1a 100644 --- a/src/strings/ro.json +++ b/src/strings/ro.json @@ -1558,5 +1558,15 @@ "EnableFasterAnimationsHelp": "Utilizați animații și tranziții mai rapide", "EnableFasterAnimations": "Animații mai rapide", "EnableDecodingColorDepth10Vp9": "Activați decodarea hardware pe 10 biți pentru VP9", - "EnableDecodingColorDepth10Hevc": "Activați decodarea hardware pe 10 biți pentru HEVC" + "EnableDecodingColorDepth10Hevc": "Activați decodarea hardware pe 10 biți pentru HEVC", + "LabelRepositoryName": "Nume Repertoriu", + "LabelRepositoryUrlHelp": "Locația manifestului repertoriului pe care doriți să o includeți.", + "LabelRepositoryUrl": "URL Repertoriu", + "HeaderNewRepository": "Repertoriu Nou", + "MessageNoRepositories": "Fără repertoriu.", + "ButtonPlayer": "Redare", + "Writers": "Scriitori", + "TabRepositories": "Repertorii", + "MessageAddRepository": "Dacă doriți să adăugați un repertoriu, faceți clic pe butonul de lângă antet și completați informațiile solicitate.", + "LabelRepositoryNameHelp": "Un nume personalizat pentru a distinge acest repertoriu de altele adăugate la serverul dvs." } diff --git a/src/strings/ru.json b/src/strings/ru.json index ae086d220b..9212ee4fb4 100644 --- a/src/strings/ru.json +++ b/src/strings/ru.json @@ -669,7 +669,7 @@ "LabelMaxResumePercentageHelp": "Произведения предполагаются воспроизведёнными полностью, при остановке с данного момента.", "LabelMaxScreenshotsPerItem": "Макс. число снимков экрана на элемент:", "LabelMaxStreamingBitrate": "Макс. качество трансляции:", - "LabelMaxStreamingBitrateHelp": "Укажите макс. потоковую скорость трансляции.", + "LabelMaxStreamingBitrateHelp": "Укажите максимальный битрейт трансляции.", "LabelMessageText": "Текст сообщения:", "LabelMessageTitle": "Заголовок сообщения:", "LabelMetadata": "Метаданные:", @@ -697,8 +697,8 @@ "LabelMoviePrefix": "Префикс фильма:", "LabelMoviePrefixHelp": "При применении к названиям фильмов префикса, введите его здесь, чтобы он правильно обрабатывался на сервере.", "LabelMovieRecordingPath": "Путь к записываемым фильмам (необязательно):", - "LabelMusicStreamingTranscodingBitrate": "Поток. скорость перекодировки музыки:", - "LabelMusicStreamingTranscodingBitrateHelp": "Укажите максимальную потоковую скорость при трансляции музыки.", + "LabelMusicStreamingTranscodingBitrate": "Битрейт перекодировки музыки:", + "LabelMusicStreamingTranscodingBitrateHelp": "Укажите максимальный битрейт при трансляции музыки.", "LabelName": "Имя:", "LabelNewName": "Новое название:", "LabelNewPassword": "Новый пароль:", @@ -752,8 +752,8 @@ "LabelRecordingPathHelp": "Укажите стандартное расположение для сохранения записей. Если поле пусто, то используется папка program data сервера.", "LabelRefreshMode": "Режим обновления:", "LabelReleaseDate": "Дата выпуска:", - "LabelRemoteClientBitrateLimit": "Предел потоковой скорости интернет-трансляции, Мбит/с:", - "LabelRemoteClientBitrateLimitHelp": "Необязательный предел скорости на поток для каждого из сетевых устройств. Это целесообразно, чтобы не допускать запрашивание устройствами более высокой скорости, чем способно пропустить интернет-соединение. Это может привести к увеличению загрузки процессора на вашем сервере, при динамическом перекодировании видео до более низкой скорости.", + "LabelRemoteClientBitrateLimit": "Ограничение битрейта интернет-трансляции, Мбит/с:", + "LabelRemoteClientBitrateLimitHelp": "Необязательное ограничение битрейта для каждого из сетевых устройств. Может потребоваться, чтобы не допускать использования устройствами большего битрейта, чем способно пропустить интернет-соединение. Может привести к росту загрузки процессора на вашем сервере, так как потребуется динамическое перекодирование видео для снижения битрейта.", "LabelRuntimeMinutes": "Длительность, мин:", "LabelSaveLocalMetadata": "Сохранять иллюстрации внутри медиапапок", "LabelSaveLocalMetadataHelp": "При сохранении иллюстраций внутри медиапапок, те помещаются в месте, где их можно легко править.", @@ -824,7 +824,7 @@ "LabelUserAgent": "Агент пользователя:", "LabelUserLibrary": "Медиатека пользователя:", "LabelUserLibraryHelp": "Выберите, чью медиатеку отображать на устройстве. Не заполняйте, чтобы наследовать параметр по умолчанию.", - "LabelUserRemoteClientBitrateLimitHelp": "Переопределияются глобальные значения по умолчанию, установленные в параметрах воспроизведения сервера.", + "LabelUserRemoteClientBitrateLimitHelp": "Переопределяются глобальные значения по умолчанию, установленные в параметрах воспроизведения сервера.", "LabelUsername": "Имя пользователя:", "LabelVaapiDevice": "Устройство VA-API:", "LabelVaapiDeviceHelp": "Это является узлом отрисовки, который используется для аппаратного ускорения.", @@ -864,7 +864,7 @@ "MediaInfoAnamorphic": "Анаморфность", "MediaInfoAspectRatio": "Соотношение сторон", "MediaInfoBitDepth": "Глубина цвета", - "MediaInfoBitrate": "Поток. ск-ть", + "MediaInfoBitrate": "Битрейт", "MediaInfoChannels": "Каналы", "MediaInfoCodec": "Кодек", "MediaInfoCodecTag": "Тег кодека", @@ -1431,7 +1431,7 @@ "LabelPlayer": "Проигрыватель:", "MoreMediaInfo": "О медиаданных", "LabelVideoCodec": "Видео кодек:", - "LabelVideoBitrate": "Потоковая скорость аудио:", + "LabelVideoBitrate": "Битрейт видео:", "LabelTranscodingProgress": "Прогресс перекодировки:", "LabelTranscodingFramerate": "Частота кадров перекодировки:", "LabelSize": "Размер:", @@ -1442,7 +1442,7 @@ "LabelAudioSampleRate": "Частота дискретизации аудио:", "LabelAudioCodec": "Аудио кодек:", "LabelAudioChannels": "Аудио каналы:", - "LabelAudioBitrate": "Потоковая скорость аудио:", + "LabelAudioBitrate": "Битрейт аудио:", "LabelAudioBitDepth": "Битовая глубина аудио:", "HeaderFavoriteBooks": "Избранные книги", "CopyStreamURL": "Копировать URL потока", @@ -1504,7 +1504,7 @@ "MessageUnauthorizedUser": "В настоящее время у вас нет доступа к серверу. Пожалуйста, свяжитесь с администратором сервера для получения дополнительной информации.", "HeaderFavoritePlaylists": "Избранные плей-листы", "LabelRequireHttpsHelp": "Если этот флажок установлен, сервер будет автоматически перенаправлять все запросы через HTTP на HTTPS. Это не имеет никакого эффекта, если сервер не слушает HTTPS.", - "LabelEnableHttpsHelp": "Позволяет серверу слушать сконфигурированный HTTPS-порт. Действительный сертификат также должен быть сконфигурирован для того, чтобы это вступило в силу.", + "LabelEnableHttpsHelp": "Позволяет серверу слушать HTTPS-порт. Для работы необходим действующий сертификат.", "ApiKeysCaption": "Список действующих текущих API-ключей", "TabDVR": "DVR", "SaveChanges": "Сохранить изменения", @@ -1532,7 +1532,7 @@ "MessageSyncPlayGroupDoesNotExist": "Не удалось присоединиться к группе, поскольку она не существует.", "MessageSyncPlayPlaybackPermissionRequired": "Требуется разрешение на воспроизведение.", "MessageSyncPlayNoGroupsAvailable": "Никакие группы не доступны. Сначала начните воспроизводить что-нибудь.", - "MessageSyncPlayGroupWait": "{0} буферизуется...", + "MessageSyncPlayGroupWait": "{0} буферизуется…", "MessageSyncPlayUserLeft": "{0} покинул группу.", "MessageSyncPlayUserJoined": "{0} присоединил группу.", "LabelSyncPlayAccessNone": "Отключено для данного пользователя", @@ -1545,12 +1545,32 @@ "LabelSyncPlayPlaybackDiff": "Разница времени воспроизведения:", "MillisecondsUnit": "мс", "LabelSyncPlayTimeOffset": "Сдвиг времени относительно сервера:", - "SyncPlayAccessHelp": "Выберите уровень доступа данного пользователя к функциональности SyncPlay. SyncPlay позволяет синхронизировать воспроизведение с другими устройствами.", + "SyncPlayAccessHelp": "Выберите уровень доступа данного пользователя к функции SyncPlay. SyncPlay позволяет синхронизировать воспроизведение с другими устройствами.", "MessageSyncPlayErrorMedia": "Не удалось включить SyncPlay! Ошибка медиаданных.", "MessageSyncPlayErrorMissingSession": "Не удалось включить SyncPlay! Отсутствует сеанс.", "MessageSyncPlayErrorNoActivePlayer": "Активный проигрыватель не найден. SyncPlay был отключен.", "ShowMore": "Показать больше", "ShowLess": "Показать меньше", "EnableBlurhashHelp": "Рисунки, которые всё ещё загружаются, будут отображаться с размытым заполнением", - "EnableBlurhash": "Включить размытые заполнители для изображений" + "EnableBlurhash": "Включить размытые заполнители для изображений", + "ButtonSyncPlay": "SyncPlay", + "ButtonCast": "В ролях", + "TabRepositories": "Репозитории", + "MessageNoGenresAvailable": "Разрешить поставщикам метаданных получать жанры из интернета.", + "MessageAddRepository": "Если вы хотите добавить репозиторий, нажмите кнопку рядом с заголовком и заполните необходимую информацию.", + "LabelRepositoryNameHelp": "Имя репозитория для показа на этом сервере.", + "LabelRepositoryName": "Название репозитория", + "LabelRepositoryUrlHelp": "Расположение манифеста добавляемого репозитория.", + "LabelRepositoryUrl": "URL репозитория", + "HeaderNewRepository": "Новый репозиторий", + "MessageNoRepositories": "Репозитории отсутствуют.", + "EnableFasterAnimationsHelp": "Использовать ускоренную анимацию и переходы", + "EnableFasterAnimations": "Ускоренная анимация", + "EnableDecodingColorDepth10Vp9": "Включить аппаратный декодер VP9 10-Bit", + "EnableDecodingColorDepth10Hevc": "Включить аппаратный декодер HEVC 10-Bit", + "StopPlayback": "Остановить проигрывание", + "Writers": "Сценаристы", + "ViewAlbumArtist": "Посмотреть альбом исполнителя", + "ClearQueue": "Очистить очередь", + "ButtonPlayer": "Проигрыватель" } diff --git a/src/strings/sk.json b/src/strings/sk.json index 2a1e6e61a9..a99d686523 100644 --- a/src/strings/sk.json +++ b/src/strings/sk.json @@ -1528,7 +1528,7 @@ "MessageSyncPlayGroupDoesNotExist": "Pripojenie ku skupine zlyhalo, pretože skupina neexistuje.", "MessageSyncPlayPlaybackPermissionRequired": "K prehrávaniu je potrebné povolenie.", "MessageSyncPlayNoGroupsAvailable": "Nie je dostupná žiadna skupina. Skúste najskôr začať niečo prehrávať.", - "MessageSyncPlayGroupWait": "Prehrávanie používateľa {0} sa načítava...", + "MessageSyncPlayGroupWait": "{0} sa načítava…", "MessageSyncPlayUserLeft": "Používateľ {0} opustil skupinu.", "MessageSyncPlayUserJoined": "Používateľ {0} sa pripojil k skupine.", "MessageSyncPlayDisabled": "SyncPlay zakázaný.", @@ -1568,5 +1568,10 @@ "MessageAddRepository": "Pokiaľ chcete pridať repozitár, kliknite na tlačidlo vedľa hlavičky a vyplňte požadované informácie.", "LabelRepositoryNameHelp": "Vlastné pomenovanie, ktoré slúži na odlíšenie tohto repozitára od ostatných repozitárov pridaných na vašom serveri.", "LabelRepositoryName": "Názov repozitára", - "LabelRepositoryUrlHelp": "Umiestnenie manifestu repozitára, ktorý chcete zahrnúť." + "LabelRepositoryUrlHelp": "Umiestnenie manifestu repozitára, ktorý chcete zahrnúť.", + "ButtonPlayer": "Prehrávač", + "Writers": "Scenáristi", + "ClearQueue": "Vymazať frontu", + "StopPlayback": "Zastaviť prehrávanie", + "ViewAlbumArtist": "Zobraziť interpreta albumu" } diff --git a/src/strings/sl-si.json b/src/strings/sl-si.json index 66b21b8a19..b7837089cd 100644 --- a/src/strings/sl-si.json +++ b/src/strings/sl-si.json @@ -77,7 +77,7 @@ "Alerts": "Alarmi", "All": "Vse", "AllChannels": "Vsi kanali", - "AllComplexFormats": "Vsi kompleksni formati (ASS, SSA, VOBSUB, PGS, SUB/IDX, itd.)", + "AllComplexFormats": "Vsi kompleksni formati (ASS, SSA, VOBSUB, PGS, SUB, IDX, itd.)", "AllEpisodes": "Vse epizode", "AllLanguages": "Vsi jeziki", "AllLibraries": "Vse knjižnice", @@ -85,7 +85,7 @@ "AllowMediaConversion": "Dovoli pretvarjanje predstavnosti", "AllowMediaConversionHelp": "Dovoli ali zavrni dostop do pretvarjanja predstavnosti.", "AllowOnTheFlySubtitleExtraction": "Dovoli sprotno izluščenje podnapisov", - "AllowOnTheFlySubtitleExtractionHelp": "Vdelani podnapisi so lahko izluščeni iz videa in poslani odjemalcem kot navaden tekst, kar zmanjša potrebo po prekodiranju. Na nekaterih napravah lahko to traja dalj časa in povzroča zatikanje med predvajanjem. Onemogočite, za vžig vdelanih podnapisov v video med prekodiranjem, za naprave ki ne podpirajo podnapisov.", + "AllowOnTheFlySubtitleExtractionHelp": "Vdelani podnapisi so lahko izluščeni iz videa in poslani odjemalcem kot navaden tekst, kar zmanjša potrebo po prekodiranju. Na nekaterih napravah lahko to traja dalj časa in povzroča zatikanje med predvajanjem. Onemogočite to možnost, za vžig vdelanih podnapisov v video s prekodiranjem, za naprave ki sicer ne podpirajo podnapisov.", "AllowRemoteAccess": "Dovoli oddaljene povezave s tem Jellyfin strežnikom.", "AllowRemoteAccessHelp": "Če ni označeno, bodo vse oddaljene povezave blokirane.", "Artists": "Izvajalci", @@ -105,12 +105,12 @@ "Movies": "Filmi", "AddItemToCollectionHelp": "Dodajte elemente v zbirke tako, da jih poiščete in jih z desnim klikom ali dotikom menija dodate v zbirko.", "AllowedRemoteAddressesHelp": "Z vejico ločen seznam IP naslovov ali IP/maska omrežij, ki jim je dovoljen oddaljeni dostop. Če pustite prazno, bodo dovoljeni vsi oddaljeni naslovi.", - "AlwaysPlaySubtitles": "Vedno predvajaj podnapise", + "AlwaysPlaySubtitles": "Vedno prikaži", "AlwaysPlaySubtitlesHelp": "Podnapisi, ki se ujemajo s prednostnim jezikom bodo naloženi ne glede na jezik zvoka.", "AnamorphicVideoNotSupported": "Anamorfni video ni podprt", "AnyLanguage": "Poljubni jezik", "Anytime": "Kadarkoli", - "AroundTime": "Okrog {0}", + "AroundTime": "Okrog", "Art": "Umetnost", "AsManyAsPossible": "Kolikor je mogoče", "Ascending": "Naraščajoče", @@ -131,12 +131,12 @@ "BirthDateValue": "Rojen: {0}", "BirthLocation": "Kraj rojstva", "BirthPlaceValue": "Kraj rojstva: {0}", - "BookLibraryHelp": "Zvočne in e-knjige so podprte. Preglej {0}navodila za poimenovanje knjig{0}.", + "BookLibraryHelp": "Zvočne in e-knjige so podprte. Preglejte {0} napotke za poimenovanje knjig {1}.", "Box": "Ovitek", "BoxRear": "Ovitek (zadnja stran)", "Browse": "Brskaj", "BrowsePluginCatalogMessage": "Poišči razpoložljive dodatke v našem katalogu.", - "BurnSubtitlesHelp": "Na podlagi formata podnapisov določi, ali naj strežnik vžge podnapise pri pretvarjanju videa. Izogibanje vžiganju podnapisov izboljša delovanje strežnika. Izberi Samodejno za vžig slikovnih formatov podnapisov (VOBSUB, PGS, SUB/IDX, itd.) in nekaterih ASS/SSA podnapisov.", + "BurnSubtitlesHelp": "Določi ali naj strežnik vžge podnapise pri prekodiranju videa. Izogibanje temu lahko občutno izboljša delovanje strežnika. Izberite Samodejno za vžig slikovnih formatov podnapisov (VOBSUB, PGS, SUB, IDX, ...) in nekaterih ASS oziroma SSA podnapisov.", "ButtonAccept": "Sprejmi", "ButtonAdd": "Dodaj", "MessageNamedServerConfigurationUpdatedWithValue": "Oddelek nastavitve strežnika {0} je bil posodobljen", @@ -288,7 +288,7 @@ "ValueSpecialEpisodeName": "Poseben - {0}", "Shows": "Serije", "DoNotRecord": "Ne snemaj", - "DisplayModeHelp": "Izberite tip zaslona na katerem uporabljate Jellyfin.", + "DisplayModeHelp": "Izberite želeno razporeditev uporabniškega vmesnika.", "DisplayMissingEpisodesWithinSeasonsHelp": "To mora biti omogočeno tudi za TV knjižnice v nastavitvah strežnika.", "DisplayMissingEpisodesWithinSeasons": "Prikaži manjkajoče epizode znotraj sezon", "DisplayInOtherHomeScreenSections": "Prikaži na razdelkih domačega zaslona kot so najnovejše in nadaljuj gledanje", @@ -311,7 +311,7 @@ "HeaderSeasons": "Sezone", "HeaderSchedule": "Urnik", "HeaderScenes": "Scene", - "HeaderRunningTasks": "Aktivni procesi", + "HeaderRunningTasks": "Aktivna opravila", "HeaderRestart": "Ponovni zagon", "HeaderResponseProfileHelp": "Profili odziva omogočajo prilagoditev informacij poslanih sprejemniku pri predvajanju določenih vrst predstavnosti.", "HeaderResponseProfile": "Profil odziva", @@ -336,7 +336,7 @@ "HeaderPasswordReset": "Ponastavi geslo", "HeaderPassword": "Geslo", "HeaderParentalRatings": "Ocena za starše", - "HeaderOnNow": "Zdaj", + "HeaderOnNow": "Trenutno", "HeaderNextVideoPlayingInValue": "Naslednji video se bo predvajal čez {0}", "HeaderNextEpisodePlayingInValue": "Naslednja epizoda se bo predvajala čez {0}", "HeaderNewDevices": "Nove naprave", @@ -393,21 +393,21 @@ "HeaderEditImages": "Uredi slike", "HeaderDownloadSync": "Prenos in sinhronizacija", "HeaderDisplay": "Prikaz", - "HeaderDirectPlayProfileHelp": "Dodaj profil za neposredno predvajanje in določi katere formate naprava podpira", + "HeaderDirectPlayProfileHelp": "Dodaj profil za neposredno predvajanje in določi katere formate naprava podpira.", "HeaderDirectPlayProfile": "Profil za neposredno predvajanje", "HeaderDevices": "Naprave", "HeaderDeveloperInfo": "Informacije o razvijalcu", "HeaderDetectMyDevices": "Zaznaj moje naprave", "HeaderDeleteTaskTrigger": "Izbriši sprožilec opravila", "HeaderDeleteProvider": "Izbriši ponudnika", - "HeaderDeleteItems": "Izbriši predmete", - "HeaderDeleteItem": "Izbriši predmet", + "HeaderDeleteItems": "Izbriši vsebine", + "HeaderDeleteItem": "Izbriši vsebino", "HeaderDeleteDevice": "Izbriši napravo", "HeaderDefaultRecordingSettings": "Privzete nastavitve snemanja", "HeaderDateIssued": "Datum izdaje", "HeaderCustomDlnaProfiles": "Profili po meri", "HeaderContinueListening": "Nadaljuj s poslušanjem", - "HeaderConnectionFailure": "Napaka pri povezovanju", + "HeaderConnectionFailure": "Napaka povezave", "HeaderConnectToServer": "Poveži s strežnikom", "HeaderConfirmRevokeApiKey": "Prekliči API ključ", "HeaderConfirmProfileDeletion": "Potrdi brisanje profila", @@ -649,7 +649,7 @@ "LabelEnableDlnaClientDiscoveryInterval": "Interval odkrivanja sprejemnikov (sekunde)", "LabelEnableBlastAliveMessagesHelp": "Omogočite, če imajo UPnP naprave težave z zaznavanjem strežnika v omrežju.", "LabelEnableBlastAliveMessages": "Oddajaj sporočila o dostopnosti", - "LabelEnableAutomaticPortMapHelp": "Poskuša avtomatično povezati javna vrata z lokalnimi preko UPnP. To ne deluje z nekaterimi usmerjevalniki. Spremembe bodo uveljavljene po ponovnem zagonu strežnika.", + "LabelEnableAutomaticPortMapHelp": "Avtomatično posreduje javna vrata na vašem usmerjevalnuku z lokalnimi vrati strežnika preko UPnP. To ne deluje z nekaterimi usmerjevalniki ali omrežnimi nastavitvami. Spremembe bodo uveljavljene po ponovnem zagonu strežnika.", "LabelEnableAutomaticPortMap": "Omogoči avtomatično mapiranje vrat", "LabelEmbedAlbumArtDidl": "Vdelaj grafike albuma v Didl", "LabelEasyPinCode": "Enostavna PIN koda:", @@ -662,7 +662,7 @@ "LabelDisplayName": "Prikazano ime:", "LabelDisplayMode": "Način prikaza:", "LabelBindToLocalNetworkAddressHelp": "Neobvezno. Preglasi lokalni IP naslov za povezavo s HTTP strežnikom. V kolikor pustite prazno se strežnik poveže z vsemi možnimi naslovi. Sprememba vrednosti zahteva ponovni zagon Jellyfin strežnika.", - "InstallingPackage": "Nameščanje {0}", + "InstallingPackage": "Nameščanje {0} (različica {1})", "ImportMissingEpisodesHelp": "Če je omogočeno, bodo podatki o manjkajočih epizodah dodani v Jellyfin bazo podatkov in prikazani znotraj sezon in serij. To lahko občutno podaljša uvoz v knjižnjico.", "ImportFavoriteChannelsHelp": "Če je omogočeno, bodo uvoženi zgolj kanali, ki so na sprejemniku označeni kot priljubljeni.", "LabelEnableDlnaServerHelp": "Omogoči UPnP napravam v omrežju da brskajo in predvajajo vsebine.", @@ -762,7 +762,7 @@ "LabelKodiMetadataEnablePathSubstitutionHelp": "Omogoči zamenjavo poti za poti slik glede na nastavitve zamenjave poti strežnika.", "LabelKodiMetadataSaveImagePaths": "Shrani poti slik znotraj nfo datotek", "LabelMetadataDownloadersHelp": "Omogoči in uredi želene vire metapodatkov po prioriteti. Viri z nižjo prioriteto bodo uporabljeni zgolj za dopolnjevanje manjkajočih informacij.", - "LabelBaseUrlHelp": "Tukaj lahko dodate podmapo po meri, za dostop do strežnika z bolj unikatnega URL naslova.", + "LabelBaseUrlHelp": "Doda podnaslov po meri na konec URL-ja strežnika. Na primer: http://example.com/<baseurl>", "LabelExtractChaptersDuringLibraryScanHelp": "Ustvari slike poglavij med uvozom videov pri preiskovanju knjižnjice. Sicer bodo ustvarjene med načrtovanim opravilom, kar omogoča hitrejše preiskovanje knjižnjice.", "LabelForgotPasswordUsernameHelp": "Vpišite svoje uporabniško ime, v kolikor se ga spomnite.", "LabelInNetworkSignInWithEasyPasswordHelp": "Uporabi enostavno PIN kodo za prijavo v naprave znotraj lokalnega omrežja. Vaše geslo bo potrebno zgolj za prijave zunaj domačega omrežja. Če pustite prazno, za prijavo v domačem omrežju omrežju ne boste potrebovali gesla.", @@ -853,7 +853,7 @@ "Quality": "Kvaliteta", "PlaceFavoriteChannelsAtBeginning": "Postavi priljubljene kanale na začetek", "LabelOptionalNetworkPath": "(Neobvezno) Omrežna mapa:", - "LabelOptionalNetworkPathHelp": "V primeru, da je mapa deljena v vašem omrežju, lahko Jellyfin deli omrežno pot z ostalimi napravami in jim omogoči neposreden dostop do predstavnosti.", + "LabelOptionalNetworkPathHelp": "V primeru, da je mapa deljena v vašem omrežju, lahko Jellyfin deli omrežno pot z ostalimi napravami in jim omogoči neposreden dostop do vsebin. Na primer {0} ali {1}.", "LabelRemoteClientBitrateLimitHelp": "Neobvezna omejitev bitne hitrosti na posamezno predvajanje za vse naprave izven domačega omrežja. S tem lahko preprečite, da bi naprave zahtevale višjo bitno hitrost predvajanja, kot jo lahko prenese vaše omrežje. To lahko poveča obremenitev CPU-ja, saj bo morda potrebno sprotno prekodiranje za zmanjšanje bitne hitrosti.", "LanNetworksHelp": "Z vejico ločen seznam IP naslovov ali IP/maska omrežji, ki bodo upoštevana kot lokalna pri uveljavljanju omejitev pasovne širine. Če nastavite, se bodo vsi ostali naslovi upoštevali kot zunanji in bodo predmet omejitve pasovne širine. Če pustite prazno, bo kot lokalno omrežje upoštevano zgolj omrežje strežnika.", "MessageDirectoryPickerInstruction": "Omrežne poti lahko vnesete ročno, v kolikor gumb Omrežje ne uspe najti vaših naprav. Primer {0} ali {1}.", @@ -1275,5 +1275,57 @@ "Episode": "Epizoda", "EnableDetailsBannerHelp": "Prikaži sliko pasice na vrhu strani podrobnosti.", "EnableDetailsBanner": "Pasica podrobnosti", - "DeinterlaceMethodHelp": "Izberite način razpletanja pri prekodiranju prepletenih vsebin." + "DeinterlaceMethodHelp": "Izberite način razpletanja pri prekodiranju prepletenih vsebin.", + "ButtonSyncPlay": "SyncPlay", + "LabelDynamicExternalId": "{0} Id:", + "LabelDroppedFrames": "Izpuščene sličice:", + "LabelDeinterlaceMethod": "Način razpletanja:", + "LabelCorruptedFrames": "Poškodovane sličice:", + "LabelBlockContentWithTags": "Blokiraj vsebine z oznakami:", + "LabelAlbumArtHelp": "PN se uporablja za grafiko albuma znotraj atributa dlna:profileID na upnp:albumArtURI. Nekatere naprave zahtevajo specifično vrednost, ne gledena velikost slike.", + "InstantMix": "Hitri miks", + "HeaderSyncPlayEnabled": "SyncPlay je omogočen", + "HeaderSyncPlaySelectGroup": "Pridruži se skupini", + "HeaderServerAddressSettings": "Nastavitve naslova strežnika", + "HeaderRemoteAccessSettings": "Nastavitve oddaljenega dostopa", + "HeaderOtherItems": "Ostale vsebine", + "HeaderNavigation": "Navigacija", + "HeaderItems": "Vsebine", + "EnableDecodingColorDepth10Vp9": "Omogoči strojno dekodiranje za 10-bit VP9", + "EnableDecodingColorDepth10Hevc": "Omogoči strojno dekodiranje za 10-bit HEVC", + "LabelEnableHttpsHelp": "Omogoči strežniku, da posluša na nastavljenih HTTPS vratih. Za uveljavitev te možnosti mora biti nastavljen tudi veljaven certifikat.", + "LabelEnableHttps": "Omogoči HTTPS", + "LabelEmbedAlbumArtDidlHelp": "Nekatere naprave delujejo bolje s tem načinom pridobivanja grafike albuma. Pri drugih predvajanje morda ne bo delovalo v tem načinu.", + "MessageReenableUser": "Za ponovno omogočanje poglejte spodaj", + "MessageNoGenresAvailable": "Omogočite nekatere ponudnike metapodatkov za pridobivanje žanrov s spleta.", + "MessageAddRepository": "Če želite dodati repozitorij, kliknite gumb poleg glave in vnesite zahtevane podatke.", + "LabelRepositoryNameHelp": "Ime po meri za razlikovanje od drugih repozitorijev v vašem strežniku.", + "LabelRepositoryName": "Ime repozitorija", + "LabelRepositoryUrlHelp": "Lokacija manifesta repozitorija, ki ga želite dodati.", + "LabelRepositoryUrl": "URL repozitorija", + "HeaderNewRepository": "Nov repozitorij", + "MessageNoRepositories": "Ni repozitorijev.", + "MessageUnauthorizedUser": "Trenutno nimate dovoljenja za dostop do tega strežnika. Kontaktirajte skrbnika strežnika za več informacij.", + "MediaInfoAspectRatio": "Razmerje stranic", + "MediaInfoAnamorphic": "Anamorfno", + "MaxParentalRatingHelp": "Vsebine z višjo oceno bodo za tega uporabnika skrite.", + "MarkUnplayed": "Označi kot nepredvajano", + "MarkPlayed": "Označi kot predvajano", + "MapChannels": "Uredi programe", + "ManageRecording": "Upravljaj posnetke", + "ManageLibrary": "Upravljaj knjižnico", + "Logo": "Logo", + "LiveBroadcasts": "Prenosi v živo", + "Live": "V živo", + "List": "Seznam", + "LabelUserAgent": "Uporabniški agent:", + "EnableFasterAnimationsHelp": "Uporabi hitrejše animacije in prehode", + "EnableFasterAnimations": "Hitrejše animacije", + "LabelNightly": "Nestabilna", + "LabelStable": "Stabilna", + "LabelChromecastVersion": "Različica Chromecast", + "LabelLibraryPageSizeHelp": "Nastavi število prikazanih vsebin na strani knjižnice. Nastavite na 0 za neskončno dolgo stran.", + "LabelLibraryPageSize": "Velikost strani knjižnice:", + "LabelKodiMetadataEnableExtraThumbsHelp": "Pri prenašanju slik so le te lahko shranjene v tako extrafanart in extrathumbs polji za največjo kompatibilnost s Kodi preoblekami.", + "LabelKodiMetadataEnableExtraThumbs": "Kopiraj extrafanart v polje extrathumbs" } diff --git a/src/strings/sr.json b/src/strings/sr.json index dc329c1309..d1ed50e87b 100644 --- a/src/strings/sr.json +++ b/src/strings/sr.json @@ -194,5 +194,6 @@ "AlbumArtist": "Извођач албума", "Album": "Албум", "AirDate": "Премијера", - "AdditionalNotificationServices": "Прегледајте каталог додатака да бисте инсталирали сервисе за обавештења." + "AdditionalNotificationServices": "Прегледајте каталог додатака да бисте инсталирали сервисе за обавештења.", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/sv.json b/src/strings/sv.json index 7cee76407e..621172f7ea 100644 --- a/src/strings/sv.json +++ b/src/strings/sv.json @@ -19,7 +19,7 @@ "AllLibraries": "Alla bibliotek", "AllowHWTranscodingHelp": "Tillåt TV-mottagaren att omkoda strömmar. Det kan minska behovet av omkodning på Jellyfin Servern.", "AllowOnTheFlySubtitleExtraction": "Tillåt undertextsextrahering under uppspelning", - "AllowOnTheFlySubtitleExtractionHelp": "Inbäddade undertexter kan extraheras ur videor och skickas till klienter i textformat för att förhindra omkodning. I vissa system kan detta ta en lång tid och stoppa videouppspelningen under extraheringsprocessen. Avaktivera detta för att bränna in inbäddade undertexter genom omkodning när de inte stöds av klienten.", + "AllowOnTheFlySubtitleExtractionHelp": "Inbäddade undertexter kan extraheras ur videor och skickas till klienter i textformat för att förhindra omkodning. I vissa system kan detta ta en lång tid och förhindra videouppspelningen under extraheringsprocessen. Avaktivera detta för att bränna in inbäddade undertexter genom omkodning när de inte stöds av klienten.", "AllowRemoteAccess": "Tillåt fjärranslutningar till denna Jellyfin-server.", "AllowRemoteAccessHelp": "Om avaktiverat så blockeras alla fjärranslutningar.", "AlwaysPlaySubtitles": "Visa alltid", @@ -540,7 +540,7 @@ "LabelEmbedAlbumArtDidl": "Bädda in omslagsbilder i Didl", "LabelEmbedAlbumArtDidlHelp": "Vissa enheter föredrar den här metoden att ta fram omslagsbilder. Andra kanske avbryter avspelningen om detta val är aktiverat.", "LabelEnableAutomaticPortMap": "Aktivera automatisk koppling av portar", - "LabelEnableAutomaticPortMapHelp": "Automatisk länkning av publik och lokal port via UPnP. Detta kanske inte fungerar med alla routrar. Obs. Ingenting kommer att ändras förrän servern startats om.", + "LabelEnableAutomaticPortMapHelp": "Automatisk länkning av publik port på routern och lokal port på servern via UPnP. Detta kanske inte fungerar med alla routrar och nätverks konfigurationer. Obs. Ingenting kommer att ändras förrän servern startats om.", "LabelEnableBlastAliveMessages": "Skicka ut \"jag lever\"-meddelanden", "LabelEnableBlastAliveMessagesHelp": "Aktivera detta om andra UPnP-enheter på nätverket har problem att upptäcka servern.", "LabelEnableDlnaClientDiscoveryInterval": "Intervall för upptäckt av klienter (i sekunder)", @@ -1513,5 +1513,13 @@ "HeaderServerAddressSettings": "Serveradressinställningar", "HeaderRemoteAccessSettings": "Inställningar för fjärråtkomst", "HeaderHttpsSettings": "HTTPS-inställningar", - "HeaderDVR": "PVR" + "HeaderDVR": "PVR", + "ButtonSyncPlay": "SyncPlay", + "LabelStable": "Stabil", + "HeaderSyncPlaySelectGroup": "Gå med i en grupp", + "EnableDecodingColorDepth10Vp9": "Aktivera 10-Bitars hårdvaru avcodning för VP9", + "EnableDecodingColorDepth10Hevc": "Aktivera 10-Bitars hårdvaru avcodning för HEVC", + "HeaderSyncPlayEnabled": "SyncPlay påslaget", + "EnableDetailsBannerHelp": "Visa en bannerbild högst upp på sidan för detaljsidan .", + "EnableDetailsBanner": "Information banner" } diff --git a/src/strings/tr.json b/src/strings/tr.json index 7c5656dbda..3e3c94d742 100644 --- a/src/strings/tr.json +++ b/src/strings/tr.json @@ -768,5 +768,6 @@ "LabelSkipIfAudioTrackPresent": "Varsayılan ses izi indirme diliyle uyuşuyorsa atla", "LabelSize": "Boyut:", "LabelSimultaneousConnectionLimit": "Eşzamanlı yayın limiti:", - "LabelServerName": "Sunucu adı:" + "LabelServerName": "Sunucu adı:", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/uk.json b/src/strings/uk.json index 5a859a4aee..0b93964474 100644 --- a/src/strings/uk.json +++ b/src/strings/uk.json @@ -159,5 +159,6 @@ "AllowOnTheFlySubtitleExtractionHelp": "Вбудовані субтитри можуть бути експортовані з відео і надіслані, по черзі, клієнтам у вигляді тексту. Це допоможе уникнути перекодування відео. На деяких системах, перекодування може зайняти тривалий час і зупинити відтворення відео, для того щоб забезпечити експортування. Вимкнення цієї функції дозволить вбудованим субтитрам бути інтегрованим у відео, під час перекодування, якщо вбудовані субтитри не підтримуються на стороні клієнта.", "AllowOnTheFlySubtitleExtraction": "Дозволити експортування субтитрів «на льоту»", "AllowHWTranscodingHelp": "Дозволити клієнту перекодування на «на льоту». Це дозволить відмикати перекодування, якщо вона вимагається сервером.", - "AllComplexFormats": "Усі складні формати (ASS, SSA, VOBSUB, PGS, SUB, IDX, …)" + "AllComplexFormats": "Усі складні формати (ASS, SSA, VOBSUB, PGS, SUB, IDX, …)", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/ur_PK.json b/src/strings/ur_PK.json index 0967ef424b..2942bba2a6 100644 --- a/src/strings/ur_PK.json +++ b/src/strings/ur_PK.json @@ -1 +1,3 @@ -{} +{ + "ButtonSyncPlay": "SyncPlay" +} diff --git a/src/strings/vi.json b/src/strings/vi.json index 84aacf6280..a5b319a86f 100644 --- a/src/strings/vi.json +++ b/src/strings/vi.json @@ -825,5 +825,6 @@ "LabelMaxStreamingBitrateHelp": "Thiết lập bitrate tối đa khi truyền tải.", "LabelMaxStreamingBitrate": "Chất lượng phát tối đa:", "LabelMaxScreenshotsPerItem": "Số lượng ảnh chụp tối đa mỗi mục:", - "LabelMaxResumePercentageHelp": "Nội dung sẽ được cho là đã kết thúc nếu ngừng phát sau thời gian này." + "LabelMaxResumePercentageHelp": "Nội dung sẽ được cho là đã kết thúc nếu ngừng phát sau thời gian này.", + "ButtonSyncPlay": "SyncPlay" } diff --git a/src/strings/zh-cn.json b/src/strings/zh-cn.json index 6b188783bd..0b2767fda3 100644 --- a/src/strings/zh-cn.json +++ b/src/strings/zh-cn.json @@ -1134,7 +1134,7 @@ "RunAtStartup": "开机时启动", "Runtime": "播放时长", "Saturday": "星期六", - "Save": "储存", + "Save": "保存", "SaveSubtitlesIntoMediaFolders": "保存字幕到媒体所在文件夹", "SaveSubtitlesIntoMediaFoldersHelp": "将字幕存储在视频文件旁边可以跟方便的管理他们。", "ScanForNewAndUpdatedFiles": "扫描新的和有修改的文件", @@ -1357,7 +1357,7 @@ "LabelKeepUpTo": "保持:", "LabelPasswordResetProvider": "密码重置提供者:", "LabelPersonRoleHelp": "示例:冰淇淋卡车司机", - "LabelSelectFolderGroups": "自动将来自下列文件夹的内容分组至电影、音乐、电视等视图中", + "LabelSelectFolderGroups": "自动将来自下列文件夹的内容分组至电影、音乐、电视等视图中:", "LabelSelectFolderGroupsHelp": "未选中的文件夹将显示在自身的视图中。", "LabelUserLoginAttemptsBeforeLockout": "用户被封禁前可尝试的次数:", "DashboardVersionNumber": "版本:{0}", @@ -1516,7 +1516,7 @@ "LabelRequireHttpsHelp": "开启后服务器将自动将所有 HTTP 请求重定向到 HTTPS。如果服务器没有启用 HTTPS 则不生效。", "LabelRequireHttps": "强制 HTTPS", "LabelStable": "稳定版", - "LabelEnableHttpsHelp": "开启服务器对所配置HTTPS 端口的监听。必须配置有效的证书才会生效。", + "LabelEnableHttpsHelp": "开启服务器对所配置 HTTPS 端口的监听。必须配置有效的证书才会生效。", "LabelEnableHttps": "启用 HTTPS", "LabelChromecastVersion": "Chromecast版本", "HeaderDVR": "DVR", @@ -1526,7 +1526,7 @@ "MessageSyncPlayCreateGroupDenied": "需要权限以创建群组。", "MessageSyncPlayGroupDoesNotExist": "无法加入群组,因为该群组不存在。", "MessageSyncPlayPlaybackPermissionRequired": "需要播放权限。", - "MessageSyncPlayGroupWait": "{0} 正在缓冲...", + "MessageSyncPlayGroupWait": "{0} 正在缓冲…", "MessageSyncPlayUserLeft": "{0} 已离开群组。", "MessageSyncPlayUserJoined": "{0} 已加入该群组。", "LabelSyncPlayAccessNone": "禁用此用户", @@ -1546,7 +1546,7 @@ "LabelSyncPlayLeaveGroupDescription": "关闭同步播放", "EnableDetailsBanner": "详细信息页面的横幅", "ButtonCast": "投射", - "ButtonSyncPlay": "同步播放", + "ButtonSyncPlay": "SyncPlay", "EnableBlurhashHelp": "仍在加载的图片将显示带有模糊的占位符", "EnableBlurhash": "为图片启用模糊的占位符", "SyncPlayAccessHelp": "为此用户选择对同步播放功能的访问级别。同步播放让你可以和其他设备同步播放进度。", @@ -1573,5 +1573,10 @@ "LabelRepositoryUrlHelp": "您要添加的存储库清单的位置。", "LabelRepositoryUrl": "存储库 URL", "MessageNoRepositories": "暂无存储库。", - "LabelSyncPlayAccess": "同步播放访问控制" + "LabelSyncPlayAccess": "同步播放访问控制", + "ButtonPlayer": "播放器", + "ClearQueue": "清空队列", + "StopPlayback": "停止播放", + "Writers": "作者", + "ViewAlbumArtist": "查看专辑艺术家" } diff --git a/src/strings/zh-hk.json b/src/strings/zh-hk.json index 97b2d2d1f7..551f6ec1ae 100644 --- a/src/strings/zh-hk.json +++ b/src/strings/zh-hk.json @@ -1,7 +1,7 @@ { "Add": "添加", - "ButtonAdd": "新增", - "ButtonAddScheduledTaskTrigger": "新增觸發", + "ButtonAdd": "增加", + "ButtonAddScheduledTaskTrigger": "新增觸發點", "ButtonAddUser": "添加用戶", "ButtonCancel": "取消", "ButtonDelete": "删除", @@ -10,12 +10,12 @@ "ButtonFilter": "過濾", "ButtonHelp": "幫助", "ButtonManualLogin": "手動登入", - "ButtonNew": "最新", + "ButtonNew": "新增", "ButtonOk": "確定", "ButtonPlay": "播放", "ButtonQuickStartGuide": "快速入門指南", "ButtonRefresh": "重新整理", - "ButtonRefreshGuideData": "重新整理電視指南資料", + "ButtonRefreshGuideData": "重新整理指南資料", "ButtonRemove": "清除", "ButtonRename": "重新命名", "ButtonResetPassword": "重設密碼", @@ -378,17 +378,17 @@ "Ascending": "上升", "Artist": "藝人", "Art": "藝術", - "AroundTime": "大約{0}", + "AroundTime": "大約", "AlwaysPlaySubtitlesHelp": "無論語言是哪種音頻,都將加載與語言首選項匹配的字幕。", "AllowedRemoteAddressesHelp": "IP地址或IP /網絡掩碼條目的逗號分隔列表,用於允許遠程連接的網絡。 如果保留為空白,將允許所有遠程地址。", "AllowRemoteAccessHelp": "如果未選中,則將阻止所有遠程連接。", "AllowRemoteAccess": "允許與此Jellyfin服務器的遠程連接。", - "AllowFfmpegThrottlingHelp": "當轉碼或remux距離當前播放位置足夠遠時,請暫停該過程,以減少資源消耗。 在不經常觀看的情況下,此功能最為有用。 如果遇到播放問題,請關閉此功能。", + "AllowFfmpegThrottlingHelp": "當轉碼或無損複製進度遠超於當前播放位置,暫停進程可減少資源消耗。 在不經常觀看的情況下,此功能最為有用。 如果遇到播放問題,請關閉此功能。", "AllowOnTheFlySubtitleExtractionHelp": "可以從視頻中提取嵌入式字幕,然後以純文本格式將其交付給客戶端,以幫助防止視頻轉碼。 在某些系統上,這可能需要很長時間,並且會導致提取過程中視頻播放停止。 如果客戶端設備本身不支持嵌入的字幕,則可以禁用此選項以通過視頻轉碼刻錄字幕。", "AllowOnTheFlySubtitleExtraction": "允許即時提取字幕", "AllowMediaConversionHelp": "授予或拒絕訪問轉換媒體功能的權限。", "AllowMediaConversion": "允許媒體轉換", - "AllowHWTranscodingHelp": "允許調諧器即時轉碼流。 這可以幫助減少服務器所需的代碼轉換。", + "AllowHWTranscodingHelp": "允許調諧器即時轉碼。 這可減少使用伺服器轉碼。", "AllLibraries": "所有媒體庫", "AllEpisodes": "所有劇集", "AllComplexFormats": "所有格式(ASS,SSA,VOBSUB,PGS,SUB,IDX等)", @@ -399,8 +399,112 @@ "Aired": "已播出", "AirDate": "播出日期", "AdditionalNotificationServices": "瀏覽插件目錄以安裝其他通知服務。", - "AddToPlayQueue": "添加到播放列", + "AddToPlayQueue": "添加到播放隊列", "AddToCollection": "添加到收藏", - "AddItemToCollectionHelp": "通過搜索項目並使用右鍵單擊或點擊菜單將其添加到集合中,從而將它們添加到集合中。", - "AccessRestrictedTryAgainLater": "目前限制訪問。 請稍後再試。" + "AddItemToCollectionHelp": "搜尋物件並使用右鍵點擊或點擊菜單將他們添加到收藏中。", + "AccessRestrictedTryAgainLater": "目前存取受限。 請稍後再試。", + "AllowFfmpegThrottling": "轉碼調節器", + "Dislike": "不喜歡", + "Disconnect": "中斷連接", + "Disc": "片", + "Disabled": "已停用", + "Directors": "導演", + "Director": "導演", + "DirectStreaming": "直接直播", + "DirectPlaying": "直接播放", + "DetectingDevices": "偵測裝置中", + "Desktop": "桌面", + "Descending": "倒序", + "DeleteUserConfirmation": "你確定要刪除此用戶嗎?", + "DeleteUser": "刪除用戶", + "DeleteMedia": "刪除媒體", + "DeleteImageConfirmation": "你確定要刪除此圖片嗎?", + "DeleteImage": "刪除圖片", + "DefaultErrorMessage": "處理此請求時發生錯誤,請稍後再嘗試。", + "Default": "預設", + "DateAdded": "日期已新增", + "CopyStreamURLError": "複製URL時發生錯誤。", + "CopyStreamURLSuccess": "成功複製URL。", + "CopyStreamURL": "複製直播URL", + "ContinueWatching": "繼續觀看", + "Connect": "連接", + "ConfirmEndPlayerSession": "你要關閉 {0} 的Jellyfin嗎?", + "ConfirmDeleteImage": "刪除圖片?", + "CommunityRating": "社群分數", + "ClientSettings": "客戶端設定", + "ChannelNumber": "頻道號碼", + "ChannelNameOnly": "只有頻道 {0}", + "Categories": "分類", + "CancelSeries": "取消片集", + "CancelRecording": "取消錄影", + "ButtonWebsite": "網頁", + "ButtonViewWebsite": "瀏覽網頁", + "ButtonUninstall": "解除安裝", + "ButtonTrailer": "預告", + "ButtonTogglePlaylist": "播放清單", + "ButtonToggleContextMenu": "更多", + "ButtonSplit": "分開", + "ButtonStop": "停止", + "ButtonStart": "開始", + "ButtonShutdown": "關閉", + "ButtonSettings": "設定", + "ButtonSend": "傳送", + "ButtonSelectServer": "選擇伺服器", + "ButtonSearch": "搜尋", + "ButtonScanAllLibraries": "掃瞄所有媒體櫃", + "ButtonRevoke": "撤銷", + "ButtonResume": "恢復", + "ButtonResetEasyPassword": "重設PIN碼", + "ButtonRepeat": "重複", + "ButtonProfile": "檔案", + "ButtonPause": "暫停", + "ButtonParentalControl": "家長控制", + "ButtonOpen": "開啟", + "ButtonNetwork": "網絡", + "ButtonMore": "更多", + "ButtonLearnMore": "了解更多", + "ButtonInfo": "資訊", + "ButtonHome": "主頁", + "ButtonGuide": "教學", + "ButtonGotIt": "了解", + "ButtonFullscreen": "全螢幕", + "ButtonForgotPassword": "忘記密碼", + "ButtonEditOtherUserPreferences": "更改用戶個人檔案,圖片及個人偏好。", + "ButtonEditImages": "更改圖片", + "ButtonDownload": "下載", + "ButtonConnect": "連接", + "ButtonChangeServer": "更換伺服器", + "ButtonBack": "返回", + "ButtonAudioTracks": "音軌", + "ButtonArrowUp": "箭咀上", + "ButtonArrowRight": "箭咀右", + "ButtonArrowLeft": "箭咀左", + "ButtonArrowDown": "箭咀下", + "ButtonAddServer": "新增伺服器", + "ButtonAddMediaLibrary": "新增媒體櫃", + "ButtonAddImage": "新增圖片", + "Browse": "瀏覽", + "Blacklist": "黑名單", + "BirthPlaceValue": "出生地點", + "BirthDateValue": "出生日期", + "Banner": "橫幅", + "Backdrops": "背景", + "Backdrop": "背景", + "AlwaysPlaySubtitles": "經常播放", + "Display": "顯示", + "EnableBackdrops": "背景", + "EditImages": "更改圖片", + "DownloadsValue": "下載數目 {0}", + "Download": "下載", + "DisplayInMyMedia": "在主頁顯示", + "ButtonSyncPlay": "SyncPlay", + "ButtonDown": "向下", + "BurnSubtitlesHelp": "確定若服務器對視頻進行轉碼時是否嵌入字幕。 關閉這功能將使用更少時間。 選擇'自動'可嵌入基於圖像的格式字幕(VOBSUB,PGS,SUB,IDX等)和某些ASS或SSA字幕。", + "BrowsePluginCatalogMessage": "瀏覽我們的插件目錄以查看可用的插件。", + "BoxRear": "盒裝(背面)", + "BoxSet": "套裝", + "Box": "盒裝", + "Composer": "作曲家", + "ButtonPreviousTrack": "上一曲", + "ButtonNextTrack": "下一曲" } diff --git a/src/strings/zh-tw.json b/src/strings/zh-tw.json index a1e7337ce0..4c090dcf25 100644 --- a/src/strings/zh-tw.json +++ b/src/strings/zh-tw.json @@ -1015,7 +1015,7 @@ "LabelEnableDlnaServerHelp": "允許網絡上的 UPnP 設備瀏覽和播放內容。", "LabelEnableHardwareDecodingFor": "為以下啟用硬體解碼:", "LabelEpisodeNumber": "集:", - "LabelBaseUrlHelp": "您可以在此處新增自訂路徑來進入伺服器。", + "LabelBaseUrlHelp": "您可以在此處自訂伺服器URL路徑的子目錄。", "LabelExtractChaptersDuringLibraryScan": "於媒體庫掃描時擷取章節圖片", "LabelHttpsPort": "本地 HTTPS 端口:", "LabelFailed": "失敗", @@ -1655,5 +1655,22 @@ "New": "新增", "ApiKeysCaption": "目前已啟用的API金鑰列表", "ButtonTogglePlaylist": "播放清單", - "ButtonToggleContextMenu": "更多" + "ButtonToggleContextMenu": "更多", + "ButtonSyncPlay": "SyncPlay", + "LabelRequireHttpsHelp": "如果選中,伺服器將自動將所有通過HTTP的請求重定向到HTTPS。 如果伺服器未在HTTPS上偵聽則此項無效。", + "EnableFasterAnimationsHelp": "使用更快的動畫和過渡效果", + "EnableFasterAnimations": "更快的動畫", + "LabelRequireHttps": "要求HTTPS", + "LabelNightly": "每日更新版", + "LabelStable": "穩定版", + "LabelChromecastVersion": "Chromecast版本", + "LabelEnableHttpsHelp": "使伺服器能夠偵聽已配置的HTTPS端口。 要使其生效,必須配置一個有效的證書。", + "LabelEnableHttps": "啟用HTTPS", + "HeaderServerAddressSettings": "伺服器地址設定", + "HeaderRemoteAccessSettings": "遠程訪問設定", + "HeaderHttpsSettings": "HTTPS設定", + "EnableDetailsBannerHelp": "在項目詳細信息頁面的頂部顯示橫幅圖像。", + "EnableDetailsBanner": "詳情橫幅", + "EnableDecodingColorDepth10Vp9": "啟用10比特VP9硬體解碼", + "EnableDecodingColorDepth10Hevc": "啟用10比特HEVC硬體解碼" } diff --git a/src/themes/appletv/theme.css b/src/themes/appletv/theme.css index bf6f6c2a51..41540ce0dd 100644 --- a/src/themes/appletv/theme.css +++ b/src/themes/appletv/theme.css @@ -125,6 +125,7 @@ html { .visualCardBox, .cardBox:not(.visualCardBox) .cardPadder { background-color: rgba(0, 0, 0, 0.1); + border-radius: 0.5rem; } .defaultCardBackground1 { @@ -173,6 +174,10 @@ html { opacity: 0.5; } +.cardImageContainer { + border-radius: 0.5rem; +} + .formDialogHeader a, .toast { color: #fff; @@ -227,7 +232,7 @@ html { color: #fff !important; } -.detailSticky { +.detailRibbon { background: #303030; background: -webkit-gradient(linear, left top, right top, from(#bcbcbc), color-stop(#a7b4b7), color-stop(#beb5a5), color-stop(#adbec2), to(#b9c7cb)); background: -webkit-linear-gradient(left, #bcbcbc, #a7b4b7, #beb5a5, #adbec2, #b9c7cb); @@ -257,11 +262,6 @@ html { background: #fff; } -.mediaInfoTimerIcon, -.starIcon { - color: #cb272a; -} - .emby-input, .emby-textarea { color: inherit; @@ -291,7 +291,10 @@ html { border-color: #fff; } -.emby-checkbox:checked + span + .checkboxOutline, +.emby-checkbox:checked + span + .checkboxOutline { + background-color: #00a4dc; +} + .itemProgressBarForeground { background: linear-gradient(90deg, rgba(0, 210, 201, 1) 0%, rgba(13, 194, 98, 1) 28%, rgba(0, 75, 185, 1) 100%); } @@ -446,15 +449,25 @@ html { color: #c33; } -.repeatButton-active { - color: #4285f4; +.buttonActive { + color: #00a4dc !important; } .card:focus .cardBox.visualCardBox, .card:focus .cardBox:not(.visualCardBox) .cardScalable { + border-radius: 0.5rem; border-color: #00a4dc !important; } +.card.show-focus:not(.show-animation) .cardBox.visualCardBox, +.card.show-focus:not(.show-animation) .cardBox:not(.visualCardBox) .cardScalable { + border-radius: 1rem; +} + +.blurhash-canvas { + border-radius: 0.5rem; +} + .itemDetailImage, .cardOverlayContainer { border-radius: 0.5rem; diff --git a/src/themes/blueradiance/theme.css b/src/themes/blueradiance/theme.css index 08ab576aa3..7ecc4a74a5 100644 --- a/src/themes/blueradiance/theme.css +++ b/src/themes/blueradiance/theme.css @@ -223,7 +223,7 @@ html { color: #fff !important; } -.detailSticky { +.detailRibbon { background: #303030; background: -webkit-gradient(linear, left top, right top, from(#291a31), color-stop(#033664), color-stop(#011432), color-stop(#141a3a), to(#291a31)); background: -webkit-linear-gradient(left, #291a31, #033664, #011432, #141a3a, #291a31); @@ -261,11 +261,6 @@ html { background: rgba(170, 170, 190, 0.2); } -.mediaInfoTimerIcon, -.starIcon { - color: #cb272a; -} - .emby-input, .emby-textarea { color: inherit; @@ -446,8 +441,8 @@ html { color: #c33; } -.repeatButton-active { - color: #4285f4; +.buttonActive { + color: #00a4dc !important; } .cardBox:not(.visualCardBox) .cardPadder { diff --git a/src/themes/dark/theme.css b/src/themes/dark/theme.css index a32e606386..be2b9269af 100644 --- a/src/themes/dark/theme.css +++ b/src/themes/dark/theme.css @@ -109,7 +109,7 @@ html { .formDialogHeader:not(.formDialogHeader-clear), .paperList, .visualCardBox { - background-color: #242424; + background-color: #202020; } .defaultCardBackground1 { @@ -203,11 +203,11 @@ html { background: rgba(30, 30, 30, 0.9); } -.detailSticky { +.detailRibbon { background: rgba(32, 32, 32, 0.8); } -.noBackdrop .detailSticky { +.noBackdrop .detailRibbon { background: #202020; } @@ -236,11 +236,6 @@ html { background: rgba(170, 170, 190, 0.2); } -.mediaInfoTimerIcon, -.starIcon { - color: #cb272a; -} - .emby-input, .emby-textarea { color: inherit; @@ -417,8 +412,8 @@ html { color: #c33; } -.repeatButton-active { - color: #4285f4; +.buttonActive { + color: #00a4dc !important; } .card:focus .cardBox.visualCardBox, @@ -437,6 +432,7 @@ html { .layout-desktop ::-webkit-scrollbar { width: 0.4em; + height: 0.4em; } ::-webkit-scrollbar-thumb:horizontal, @@ -453,3 +449,8 @@ html { .metadataSidebarIcon { color: #00a4dc; } + +.emby-button.detailFloatingButton { + background-color: #00a4dc; + color: #fff; +} diff --git a/src/themes/light/theme.css b/src/themes/light/theme.css index acea3f1d68..c5161985cd 100644 --- a/src/themes/light/theme.css +++ b/src/themes/light/theme.css @@ -57,6 +57,10 @@ html { background-color: #f0f0f0; } +.emby-scrollbuttons .paper-icon-button-light { + color: #000; +} + .paper-icon-button-light:hover:not(:disabled) { color: #00a4dc; background-color: rgba(0, 164, 220, 0.2); @@ -221,7 +225,7 @@ html { color: #fff !important; } -.detailSticky { +.detailRibbon { background-color: #303030; color: #ccc; color: rgba(255, 255, 255, 0.87); @@ -234,7 +238,7 @@ html { } .listItem-border { - border-color: #f0f0f0 !important; + border-color: #a7a7a7 !important; } .listItem:focus { @@ -250,11 +254,6 @@ html { background: #fff; } -.mediaInfoTimerIcon, -.starIcon { - color: #cb272a; -} - .emby-input, .emby-textarea { color: inherit; @@ -428,8 +427,8 @@ html { color: #c33; } -.repeatButton-active { - color: #4285f4; +.buttonActive { + color: #00a4dc !important; } .cardBox:not(.visualCardBox) .cardPadder { diff --git a/src/themes/purplehaze/theme.css b/src/themes/purplehaze/theme.css index a311fd3104..1d82afc23a 100644 --- a/src/themes/purplehaze/theme.css +++ b/src/themes/purplehaze/theme.css @@ -199,7 +199,7 @@ a[data-role=button] { } .cardContent { - border-radius: 1em; + border-radius: 0.8em; } .collapseContent, @@ -208,13 +208,17 @@ a[data-role=button] { .paperList, .visualCardBox { background-color: rgba(0, 0, 0, 0.5); - border-radius: 1em; + border-radius: 0.8em; } .cardOverlayContainer { border-radius: 0.8em; } +.blurhash-canvas { + border-radius: 0.8em; +} + .visualCardBox .cardOverlayContainer { border-bottom-right-radius: 0; border-bottom-left-radius: 0; @@ -307,7 +311,7 @@ a[data-role=button] { color: #f8f8fe !important; } -.detailSticky { +.detailRibbon { background: #000420; background: -moz-linear-gradient(left, #000420 0%, #06256f 18%, #2b052b 38%, #2b052b 68%, #06256f 81%, #000420 100%); background: -webkit-linear-gradient(left, #000420 0%, #06256f 18%, #2b052b 38%, #2b052b 68%, #06256f 81%, #000420 100%); @@ -344,11 +348,6 @@ a[data-role=button] { background: rgba(170, 170, 190, 0.2); } -.mediaInfoTimerIcon, -.starIcon { - color: #f2b01e; -} - .emby-input, .emby-textarea { color: inherit; @@ -543,8 +542,8 @@ a[data-role=button] { color: #c33; } -.repeatButton-active { - color: #4285f4; +.buttonActive { + color: #00a4dc !important; } .personCard .cardScalable { @@ -554,7 +553,7 @@ a[data-role=button] { .cardBox:not(.visualCardBox) .cardPadder { background-color: rgba(0, 0, 0, 0.5); - border-radius: 1em; + border-radius: 0.8em; } .card:focus .cardBox.visualCardBox, @@ -564,7 +563,7 @@ a[data-role=button] { .card.show-focus:not(.show-animation) .cardBox.visualCardBox, .card.show-focus:not(.show-animation) .cardBox:not(.visualCardBox) .cardScalable { - border-radius: 1.5em; + border-radius: 1.3em; } .layout-desktop, diff --git a/src/themes/wmc/theme.css b/src/themes/wmc/theme.css index 97c08caf80..4a7375a129 100644 --- a/src/themes/wmc/theme.css +++ b/src/themes/wmc/theme.css @@ -209,7 +209,7 @@ html { color: #fff !important; } -.detailSticky { +.detailRibbon { background-color: #081b3b; } @@ -243,11 +243,6 @@ html { background: rgba(170, 170, 190, 0.2); } -.mediaInfoTimerIcon, -.starIcon { - color: #cb272a; -} - .emby-input, .emby-textarea { color: inherit; @@ -426,8 +421,8 @@ html { color: #c33; } -.repeatButton-active { - color: #4285f4; +.buttonActive { + color: #00a4dc !important; } .cardBox:not(.visualCardBox) .cardPadder { diff --git a/webpack.dev.js b/webpack.dev.js index 17377acf1c..3d0c2a48a0 100644 --- a/webpack.dev.js +++ b/webpack.dev.js @@ -15,7 +15,7 @@ module.exports = merge(common, { rules: [ { test: /\.js$/, - exclude: /node_modules[\\/](?!date-fns|epubjs|jellyfin-apiclient|query-string|split-on-first|strict-uri-encode)/, + exclude: /node_modules[\\/](?!date-fns|epubjs|jellyfin-apiclient|query-string|split-on-first|strict-uri-encode|xmldom)/, use: { loader: 'babel-loader', options: { diff --git a/webpack.prod.js b/webpack.prod.js index 1b7f4d029e..52d6d0a865 100644 --- a/webpack.prod.js +++ b/webpack.prod.js @@ -8,7 +8,7 @@ module.exports = merge(common, { rules: [ { test: /\.js$/, - exclude: /node_modules[\\/](?!date-fns|epubjs|jellyfin-apiclient|query-string|split-on-first|strict-uri-encode)/, + exclude: /node_modules[\\/](?!date-fns|epubjs|jellyfin-apiclient|query-string|split-on-first|strict-uri-encode|xmldom)/, use: { loader: 'babel-loader', options: { diff --git a/yarn.lock b/yarn.lock index 3696566154..9e0b77a95a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,384 +2,349 @@ # yarn lockfile v1 -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.3.tgz#324bcfd8d35cd3d47dae18cde63d752086435e9a" - integrity sha512-fDx9eNW0qz0WkUeqL6tXEXzVlPh6Y5aCDEZesl0xBGA8ndRukX91Uk44ZqnkECp01NAZUdCAl+aiQNGi0k88Eg== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" + integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== dependencies: - "@babel/highlight" "^7.10.3" + "@babel/highlight" "^7.10.4" -"@babel/compat-data@^7.10.1", "@babel/compat-data@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.10.3.tgz#9af3e033f36e8e2d6e47570db91e64a846f5d382" - integrity sha512-BDIfJ9uNZuI0LajPfoYV28lX8kyCPMHY6uY4WH1lJdcicmAfxCK5ASzaeV0D/wsUaRH/cLk+amuxtC37sZ8TUg== +"@babel/compat-data@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.10.4.tgz#706a6484ee6f910b719b696a9194f8da7d7ac241" + integrity sha512-t+rjExOrSVvjQQXNp5zAIYDp00KjdvGl/TpDX5REPr0S9IAIPQMTilcfG6q8c0QFmj9lSTVySV2VTsyggvtNIw== dependencies: browserslist "^4.12.0" invariant "^2.2.4" semver "^5.5.0" -"@babel/core@>=7.2.2", "@babel/core@>=7.9.0", "@babel/core@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.3.tgz#73b0e8ddeec1e3fdd7a2de587a60e17c440ec77e" - integrity sha512-5YqWxYE3pyhIi84L84YcwjeEgS+fa7ZjK6IBVGTjDVfm64njkR2lfDhVR5OudLk8x2GK59YoSyVv+L/03k1q9w== +"@babel/core@>=7.2.2", "@babel/core@>=7.9.0", "@babel/core@^7.10.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.5.tgz#1f15e2cca8ad9a1d78a38ddba612f5e7cdbbd330" + integrity sha512-O34LQooYVDXPl7QWCdW9p4NR+QlzOr7xShPPJz8GsuCU3/8ua/wqTr7gmnxXv+WBESiGU/G5s16i6tUvHkNb+w== dependencies: - "@babel/code-frame" "^7.10.3" - "@babel/generator" "^7.10.3" - "@babel/helper-module-transforms" "^7.10.1" - "@babel/helpers" "^7.10.1" - "@babel/parser" "^7.10.3" - "@babel/template" "^7.10.3" - "@babel/traverse" "^7.10.3" - "@babel/types" "^7.10.3" + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.10.5" + "@babel/helper-module-transforms" "^7.10.5" + "@babel/helpers" "^7.10.4" + "@babel/parser" "^7.10.5" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.5" + "@babel/types" "^7.10.5" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" json5 "^2.1.2" - lodash "^4.17.13" + lodash "^4.17.19" resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.3.tgz#32b9a0d963a71d7a54f5f6c15659c3dbc2a523a5" - integrity sha512-drt8MUHbEqRzNR0xnF8nMehbY11b1SDkRw03PSNH/3Rb2Z35oxkddVSi3rcaak0YJQ86PCuE7Qx1jSFhbLNBMA== +"@babel/generator@^7.10.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.5.tgz#1b903554bc8c583ee8d25f1e8969732e6b829a69" + integrity sha512-3vXxr3FEW7E7lJZiWQ3bM4+v/Vyr9C+hpolQ8BGFr9Y8Ri2tFLWTixmwKBafDujO1WVah4fhZBeU1bieKdghig== dependencies: - "@babel/types" "^7.10.3" + "@babel/types" "^7.10.5" jsesc "^2.5.1" - lodash "^4.17.13" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz#f6d08acc6f70bbd59b436262553fb2e259a1a268" - integrity sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw== +"@babel/helper-annotate-as-pure@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" + integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA== dependencies: - "@babel/types" "^7.10.1" + "@babel/types" "^7.10.4" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.1.tgz#0ec7d9be8174934532661f87783eb18d72290059" - integrity sha512-cQpVq48EkYxUU0xozpGCLla3wlkdRRqLWu1ksFMXA9CM5KQmyyRpSEsYXbao7JUkOw/tAaYKCaYyZq6HOFYtyw== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" + integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== dependencies: - "@babel/helper-explode-assignable-expression" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/helper-explode-assignable-expression" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/helper-compilation-targets@^7.10.2": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.2.tgz#a17d9723b6e2c750299d2a14d4637c76936d8285" - integrity sha512-hYgOhF4To2UTB4LTaZepN/4Pl9LD4gfbJx8A34mqoluT8TLbof1mhUlYuNWTEebONa8+UlCC4X0TEXu7AOUyGA== +"@babel/helper-compilation-targets@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz#804ae8e3f04376607cc791b9d47d540276332bd2" + integrity sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ== dependencies: - "@babel/compat-data" "^7.10.1" + "@babel/compat-data" "^7.10.4" browserslist "^4.12.0" invariant "^2.2.4" levenary "^1.1.1" semver "^5.5.0" -"@babel/helper-create-class-features-plugin@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.1.tgz#6d8a45aafe492378d0e6fc0b33e5dea132eae21c" - integrity sha512-bwhdehBJZt84HuPUcP1HaTLuc/EywVS8rc3FgsEPDcivg+DCW+SHuLHVkYOmcBA1ZfI+Z/oZjQc/+bPmIO7uAA== +"@babel/helper-create-class-features-plugin@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.4.tgz#2d4015d0136bd314103a70d84a7183e4b344a355" + integrity sha512-9raUiOsXPxzzLjCXeosApJItoMnX3uyT4QdM2UldffuGApNrF8e938MwNpDCK9CPoyxrEoCgT+hObJc3mZa6lQ== dependencies: - "@babel/helper-function-name" "^7.10.1" - "@babel/helper-member-expression-to-functions" "^7.10.1" - "@babel/helper-optimise-call-expression" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-replace-supers" "^7.10.1" - "@babel/helper-split-export-declaration" "^7.10.1" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-member-expression-to-functions" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" -"@babel/helper-create-regexp-features-plugin@^7.10.1", "@babel/helper-create-regexp-features-plugin@^7.8.3": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.1.tgz#1b8feeab1594cbcfbf3ab5a3bbcabac0468efdbd" - integrity sha512-Rx4rHS0pVuJn5pJOqaqcZR4XSgeF9G/pO/79t+4r7380tXFJdzImFnxMU19f83wjSrmKHq6myrM10pFHTGzkUA== +"@babel/helper-create-regexp-features-plugin@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz#fdd60d88524659a0b6959c0579925e425714f3b8" + integrity sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-regex" "^7.10.1" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-regex" "^7.10.4" regexpu-core "^4.7.0" -"@babel/helper-define-map@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.3.tgz#d27120a5e57c84727b30944549b2dfeca62401a8" - integrity sha512-bxRzDi4Sin/k0drWCczppOhov1sBSdBvXJObM1NLHQzjhXhwRtn7aRWGvLJWCYbuu2qUk3EKs6Ci9C9ps8XokQ== +"@babel/helper-define-map@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.4.tgz#f037ad794264f729eda1889f4ee210b870999092" + integrity sha512-nIij0oKErfCnLUCWaCaHW0Bmtl2RO9cN7+u2QT8yqTywgALKlyUVOvHDElh+b5DwVC6YB1FOYFOTWcN/+41EDA== dependencies: - "@babel/helper-function-name" "^7.10.3" - "@babel/types" "^7.10.3" + "@babel/helper-function-name" "^7.10.4" + "@babel/types" "^7.10.4" lodash "^4.17.13" -"@babel/helper-explode-assignable-expression@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.1.tgz#e9d76305ee1162ca467357ae25df94f179af2b7e" - integrity sha512-vcUJ3cDjLjvkKzt6rHrl767FeE7pMEYfPanq5L16GRtrXIoznc0HykNW2aEYkcnP76P0isoqJ34dDMFZwzEpJg== +"@babel/helper-explode-assignable-expression@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.4.tgz#40a1cd917bff1288f699a94a75b37a1a2dbd8c7c" + integrity sha512-4K71RyRQNPRrR85sr5QY4X3VwG4wtVoXZB9+L3r1Gp38DhELyHCtovqydRi7c1Ovb17eRGiQ/FD5s8JdU0Uy5A== dependencies: - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/helper-function-name@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz#92bd63829bfc9215aca9d9defa85f56b539454f4" - integrity sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ== +"@babel/helper-function-name@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" + integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== dependencies: - "@babel/helper-get-function-arity" "^7.10.1" - "@babel/template" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/helper-get-function-arity" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/helper-function-name@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.3.tgz#79316cd75a9fa25ba9787ff54544307ed444f197" - integrity sha512-FvSj2aiOd8zbeqijjgqdMDSyxsGHaMt5Tr0XjQsGKHD3/1FP3wksjnLAWzxw7lvXiej8W1Jt47SKTZ6upQNiRw== +"@babel/helper-get-function-arity@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" + integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== dependencies: - "@babel/helper-get-function-arity" "^7.10.3" - "@babel/template" "^7.10.3" - "@babel/types" "^7.10.3" + "@babel/types" "^7.10.4" -"@babel/helper-get-function-arity@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz#7303390a81ba7cb59613895a192b93850e373f7d" - integrity sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw== +"@babel/helper-hoist-variables@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e" + integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA== dependencies: - "@babel/types" "^7.10.1" + "@babel/types" "^7.10.4" -"@babel/helper-get-function-arity@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.3.tgz#3a28f7b28ccc7719eacd9223b659fdf162e4c45e" - integrity sha512-iUD/gFsR+M6uiy69JA6fzM5seno8oE85IYZdbVVEuQaZlEzMO2MXblh+KSPJgsZAUx0EEbWXU0yJaW7C9CdAVg== +"@babel/helper-member-expression-to-functions@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.4.tgz#7cd04b57dfcf82fce9aeae7d4e4452fa31b8c7c4" + integrity sha512-m5j85pK/KZhuSdM/8cHUABQTAslV47OjfIB9Cc7P+PvlAoBzdb79BGNfw8RhT5Mq3p+xGd0ZfAKixbrUZx0C7A== dependencies: - "@babel/types" "^7.10.3" + "@babel/types" "^7.10.4" -"@babel/helper-hoist-variables@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.3.tgz#d554f52baf1657ffbd7e5137311abc993bb3f068" - integrity sha512-9JyafKoBt5h20Yv1+BXQMdcXXavozI1vt401KBiRc2qzUepbVnd7ogVNymY1xkQN9fekGwfxtotH2Yf5xsGzgg== +"@babel/helper-module-imports@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" + integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw== dependencies: - "@babel/types" "^7.10.3" + "@babel/types" "^7.10.4" -"@babel/helper-member-expression-to-functions@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz#432967fd7e12a4afef66c4687d4ca22bc0456f15" - integrity sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g== +"@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.10.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.10.5.tgz#120c271c0b3353673fcdfd8c053db3c544a260d6" + integrity sha512-4P+CWMJ6/j1W915ITJaUkadLObmCRRSC234uctJfn/vHrsLNxsR8dwlcXv9ZhJWzl77awf+mWXSZEKt5t0OnlA== dependencies: - "@babel/types" "^7.10.1" + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-simple-access" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.5" + lodash "^4.17.19" -"@babel/helper-module-imports@^7.10.1", "@babel/helper-module-imports@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.3.tgz#766fa1d57608e53e5676f23ae498ec7a95e1b11a" - integrity sha512-Jtqw5M9pahLSUWA+76nhK9OG8nwYXzhQzVIGFoNaHnXF/r4l7kz4Fl0UAW7B6mqC5myoJiBP5/YQlXQTMfHI9w== +"@babel/helper-optimise-call-expression@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" + integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== dependencies: - "@babel/types" "^7.10.3" + "@babel/types" "^7.10.4" -"@babel/helper-module-transforms@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz#24e2f08ee6832c60b157bb0936c86bef7210c622" - integrity sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg== - dependencies: - "@babel/helper-module-imports" "^7.10.1" - "@babel/helper-replace-supers" "^7.10.1" - "@babel/helper-simple-access" "^7.10.1" - "@babel/helper-split-export-declaration" "^7.10.1" - "@babel/template" "^7.10.1" - "@babel/types" "^7.10.1" - lodash "^4.17.13" +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" + integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== -"@babel/helper-optimise-call-expression@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz#b4a1f2561870ce1247ceddb02a3860fa96d72543" - integrity sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg== - dependencies: - "@babel/types" "^7.10.1" - -"@babel/helper-optimise-call-expression@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.3.tgz#f53c4b6783093195b0f69330439908841660c530" - integrity sha512-kT2R3VBH/cnSz+yChKpaKRJQJWxdGoc6SjioRId2wkeV3bK0wLLioFpJROrX0U4xr/NmxSSAWT/9Ih5snwIIzg== - dependencies: - "@babel/types" "^7.10.3" - -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.1", "@babel/helper-plugin-utils@^7.10.3", "@babel/helper-plugin-utils@^7.8.0": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.3.tgz#aac45cccf8bc1873b99a85f34bceef3beb5d3244" - integrity sha512-j/+j8NAWUTxOtx4LKHybpSClxHoq6I91DQ/mKgAXn5oNUPIUiGppjPIX3TDtJWPrdfP9Kfl7e4fgVMiQR9VE/g== - -"@babel/helper-regex@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.1.tgz#021cf1a7ba99822f993222a001cc3fec83255b96" - integrity sha512-7isHr19RsIJWWLLFn21ubFt223PjQyg1HY7CZEMRr820HttHPpVvrsIN3bUOo44DEfFV4kBXO7Abbn9KTUZV7g== +"@babel/helper-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.4.tgz#59b373daaf3458e5747dece71bbaf45f9676af6d" + integrity sha512-inWpnHGgtg5NOF0eyHlC0/74/VkdRITY9dtTpB2PrxKKn+AkVMRiZz/Adrx+Ssg+MLDesi2zohBW6MVq6b4pOQ== dependencies: lodash "^4.17.13" -"@babel/helper-remap-async-to-generator@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.1.tgz#bad6aaa4ff39ce8d4b82ccaae0bfe0f7dbb5f432" - integrity sha512-RfX1P8HqsfgmJ6CwaXGKMAqbYdlleqglvVtht0HGPMSsy2V6MqLlOJVF/0Qyb/m2ZCi2z3q3+s6Pv7R/dQuZ6A== +"@babel/helper-remap-async-to-generator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.4.tgz#fce8bea4e9690bbe923056ded21e54b4e8b68ed5" + integrity sha512-86Lsr6NNw3qTNl+TBcF1oRZMaVzJtbWTyTko+CQL/tvNvcGYEFKbLXDPxtW0HKk3McNOk4KzY55itGWCAGK5tg== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-wrap-function" "^7.10.1" - "@babel/template" "^7.10.1" - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-wrap-function" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/helper-remap-async-to-generator@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.3.tgz#18564f8a6748be466970195b876e8bba3bccf442" - integrity sha512-sLB7666ARbJUGDO60ZormmhQOyqMX/shKBXZ7fy937s+3ID8gSrneMvKSSb+8xIM5V7Vn6uNVtOY1vIm26XLtA== +"@babel/helper-replace-supers@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz#d585cd9388ea06e6031e4cd44b6713cbead9e6cf" + integrity sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-wrap-function" "^7.10.1" - "@babel/template" "^7.10.3" - "@babel/traverse" "^7.10.3" - "@babel/types" "^7.10.3" + "@babel/helper-member-expression-to-functions" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/helper-replace-supers@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz#ec6859d20c5d8087f6a2dc4e014db7228975f13d" - integrity sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A== +"@babel/helper-simple-access@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461" + integrity sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw== dependencies: - "@babel/helper-member-expression-to-functions" "^7.10.1" - "@babel/helper-optimise-call-expression" "^7.10.1" - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/helper-simple-access@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz#08fb7e22ace9eb8326f7e3920a1c2052f13d851e" - integrity sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw== +"@babel/helper-split-export-declaration@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.4.tgz#2c70576eaa3b5609b24cb99db2888cc3fc4251d1" + integrity sha512-pySBTeoUff56fL5CBU2hWm9TesA4r/rOkI9DyJLvvgz09MB9YtfIYe3iBriVaYNaPe+Alua0vBIOVOLs2buWhg== dependencies: - "@babel/template" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/types" "^7.10.4" -"@babel/helper-split-export-declaration@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz#c6f4be1cbc15e3a868e4c64a17d5d31d754da35f" - integrity sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g== +"@babel/helper-validator-identifier@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" + integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== + +"@babel/helper-wrap-function@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz#8a6f701eab0ff39f765b5a1cfef409990e624b87" + integrity sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug== dependencies: - "@babel/types" "^7.10.1" + "@babel/helper-function-name" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/helper-validator-identifier@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.3.tgz#60d9847f98c4cea1b279e005fdb7c28be5412d15" - integrity sha512-bU8JvtlYpJSBPuj1VUmKpFGaDZuLxASky3LhaKj3bmpSTY6VWooSM8msk+Z0CZoErFye2tlABF6yDkT3FOPAXw== - -"@babel/helper-wrap-function@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.1.tgz#956d1310d6696257a7afd47e4c42dfda5dfcedc9" - integrity sha512-C0MzRGteVDn+H32/ZgbAv5r56f2o1fZSA/rj/TYo8JEJNHg+9BdSmKBUND0shxWRztWhjlT2cvHYuynpPsVJwQ== +"@babel/helpers@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044" + integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA== dependencies: - "@babel/helper-function-name" "^7.10.1" - "@babel/template" "^7.10.1" - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/helpers@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.1.tgz#a6827b7cb975c9d9cef5fd61d919f60d8844a973" - integrity sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw== +"@babel/highlight@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" + integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== dependencies: - "@babel/template" "^7.10.1" - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.1" - -"@babel/highlight@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.3.tgz#c633bb34adf07c5c13156692f5922c81ec53f28d" - integrity sha512-Ih9B/u7AtgEnySE2L2F0Xm0GaM729XqqLfHkalTsbjXGyqmf/6M0Cu0WpvqueUlW+xk88BHw9Nkpj49naU+vWw== - dependencies: - "@babel/helper-validator-identifier" "^7.10.3" + "@babel/helper-validator-identifier" "^7.10.4" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.3.tgz#7e71d892b0d6e7d04a1af4c3c79d72c1f10f5315" - integrity sha512-oJtNJCMFdIMwXGmx+KxuaD7i3b8uS7TTFYW/FNG2BT8m+fmGHoiPYoH0Pe3gya07WuFmM5FCDIr1x0irkD/hyA== +"@babel/parser@^7.10.4", "@babel/parser@^7.10.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.5.tgz#e7c6bf5a7deff957cec9f04b551e2762909d826b" + integrity sha512-wfryxy4bE1UivvQKSQDU4/X6dr+i8bctjUjj8Zyt3DQy7NtPizJXT8M52nqpNKL+nq2PW8lxk4ZqLj0fD4B4hQ== -"@babel/plugin-proposal-async-generator-functions@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.3.tgz#5a02453d46e5362e2073c7278beab2e53ad7d939" - integrity sha512-WUUWM7YTOudF4jZBAJIW9D7aViYC/Fn0Pln4RIHlQALyno3sXSjqmTA4Zy1TKC2D49RCR8Y/Pn4OIUtEypK3CA== +"@babel/plugin-proposal-async-generator-functions@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.4.tgz#4b65abb3d9bacc6c657aaa413e56696f9f170fc6" + integrity sha512-MJbxGSmejEFVOANAezdO39SObkURO5o/8b6fSH6D1pi9RZQt+ldppKPXfqgUWpSQ9asM6xaSaSJIaeWMDRP0Zg== dependencies: - "@babel/helper-plugin-utils" "^7.10.3" - "@babel/helper-remap-async-to-generator" "^7.10.3" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.10.4" "@babel/plugin-syntax-async-generators" "^7.8.0" -"@babel/plugin-proposal-class-properties@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.1.tgz#046bc7f6550bb08d9bd1d4f060f5f5a4f1087e01" - integrity sha512-sqdGWgoXlnOdgMXU+9MbhzwFRgxVLeiGBqTrnuS7LC2IBU31wSsESbTUreT2O418obpfPdGUR2GbEufZF1bpqw== +"@babel/plugin-proposal-class-properties@^7.10.1", "@babel/plugin-proposal-class-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz#a33bf632da390a59c7a8c570045d1115cd778807" + integrity sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-create-class-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-proposal-dynamic-import@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.1.tgz#e36979dc1dc3b73f6d6816fc4951da2363488ef0" - integrity sha512-Cpc2yUVHTEGPlmiQzXj026kqwjEQAD9I4ZC16uzdbgWgitg/UHKHLffKNCQZ5+y8jpIZPJcKcwsr2HwPh+w3XA== +"@babel/plugin-proposal-dynamic-import@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz#ba57a26cb98b37741e9d5bca1b8b0ddf8291f17e" + integrity sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-dynamic-import" "^7.8.0" -"@babel/plugin-proposal-json-strings@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.1.tgz#b1e691ee24c651b5a5e32213222b2379734aff09" - integrity sha512-m8r5BmV+ZLpWPtMY2mOKN7wre6HIO4gfIiV+eOmsnZABNenrt/kzYBwrh+KOfgumSWpnlGs5F70J8afYMSJMBg== +"@babel/plugin-proposal-json-strings@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz#593e59c63528160233bd321b1aebe0820c2341db" + integrity sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-json-strings" "^7.8.0" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.1.tgz#02dca21673842ff2fe763ac253777f235e9bbf78" - integrity sha512-56cI/uHYgL2C8HVuHOuvVowihhX0sxb3nnfVRzUeVHTWmRHTZrKuAh/OBIMggGU/S1g/1D2CRCXqP+3u7vX7iA== +"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz#02a7e961fc32e6d5b2db0649e01bf80ddee7e04a" + integrity sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" -"@babel/plugin-proposal-numeric-separator@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.1.tgz#a9a38bc34f78bdfd981e791c27c6fdcec478c123" - integrity sha512-jjfym4N9HtCiNfyyLAVD8WqPYeHUrw4ihxuAynWj6zzp2gf9Ey2f7ImhFm6ikB3CLf5Z/zmcJDri6B4+9j9RsA== +"@babel/plugin-proposal-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz#ce1590ff0a65ad12970a609d78855e9a4c1aef06" + integrity sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-syntax-numeric-separator" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.3.tgz#b8d0d22f70afa34ad84b7a200ff772f9b9fce474" - integrity sha512-ZZh5leCIlH9lni5bU/wB/UcjtcVLgR8gc+FAgW2OOY+m9h1II3ItTO1/cewNUcsIDZSYcSaz/rYVls+Fb0ExVQ== +"@babel/plugin-proposal-object-rest-spread@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.4.tgz#50129ac216b9a6a55b3853fdd923e74bf553a4c0" + integrity sha512-6vh4SqRuLLarjgeOf4EaROJAHjvu9Gl+/346PbDH9yWbJyfnJ/ah3jmYKYtswEyCoWZiidvVHjHshd4WgjB9BA== dependencies: - "@babel/helper-plugin-utils" "^7.10.3" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-object-rest-spread" "^7.8.0" - "@babel/plugin-transform-parameters" "^7.10.1" + "@babel/plugin-transform-parameters" "^7.10.4" -"@babel/plugin-proposal-optional-catch-binding@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.1.tgz#c9f86d99305f9fa531b568ff5ab8c964b8b223d2" - integrity sha512-VqExgeE62YBqI3ogkGoOJp1R6u12DFZjqwJhqtKc2o5m1YTUuUWnos7bZQFBhwkxIFpWYJ7uB75U7VAPPiKETA== +"@babel/plugin-proposal-optional-catch-binding@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz#31c938309d24a78a49d68fdabffaa863758554dd" + integrity sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" -"@babel/plugin-proposal-optional-chaining@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.3.tgz#9a726f94622b653c0a3a7a59cdce94730f526f7c" - integrity sha512-yyG3n9dJ1vZ6v5sfmIlMMZ8azQoqx/5/nZTSWX1td6L1H1bsjzA8TInDChpafCZiJkeOFzp/PtrfigAQXxI1Ng== +"@babel/plugin-proposal-optional-chaining@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.4.tgz#750f1255e930a1f82d8cdde45031f81a0d0adff7" + integrity sha512-ZIhQIEeavTgouyMSdZRap4VPPHqJJ3NEs2cuHs5p0erH+iz6khB0qfgU8g7UuJkG88+fBMy23ZiU+nuHvekJeQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.3" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-optional-chaining" "^7.8.0" -"@babel/plugin-proposal-private-methods@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.1.tgz#ed85e8058ab0fe309c3f448e5e1b73ca89cdb598" - integrity sha512-RZecFFJjDiQ2z6maFprLgrdnm0OzoC23Mx89xf1CcEsxmHuzuXOdniEuI+S3v7vjQG4F5sa6YtUp+19sZuSxHg== +"@babel/plugin-proposal-private-methods@^7.10.1", "@babel/plugin-proposal-private-methods@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz#b160d972b8fdba5c7d111a145fc8c421fc2a6909" + integrity sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-create-class-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-proposal-unicode-property-regex@^7.10.1", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.1.tgz#dc04feb25e2dd70c12b05d680190e138fa2c0c6f" - integrity sha512-JjfngYRvwmPwmnbRZyNiPFI8zxCZb8euzbCG/LxyKdeTb59tVciKo9GK9bi6JYKInk1H11Dq9j/zRqIH4KigfQ== +"@babel/plugin-proposal-unicode-property-regex@^7.10.4", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz#4483cda53041ce3413b7fe2f00022665ddfaa75d" + integrity sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-async-generators@^7.8.0": version "7.8.4" @@ -388,12 +353,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-class-properties@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz#d5bc0645913df5b17ad7eda0fa2308330bde34c5" - integrity sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ== +"@babel/plugin-syntax-class-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz#6644e6a0baa55a61f9e3231f6c9eeb6ee46c124c" + integrity sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-dynamic-import@^7.8.0": version "7.8.3" @@ -416,12 +381,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-numeric-separator@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz#25761ee7410bc8cf97327ba741ee94e4a61b7d99" - integrity sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg== +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-object-rest-spread@^7.8.0": version "7.8.3" @@ -444,336 +409,336 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-top-level-await@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.1.tgz#8b8733f8c57397b3eaa47ddba8841586dcaef362" - integrity sha512-hgA5RYkmZm8FTFT3yu2N9Bx7yVVOKYT6yEdXXo6j2JTm0wNxgqaGeQVaSHRjhfnQbX91DtjFB6McRFSlcJH3xQ== +"@babel/plugin-syntax-top-level-await@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz#4bbeb8917b54fcf768364e0a81f560e33a3ef57d" + integrity sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-arrow-functions@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.1.tgz#cb5ee3a36f0863c06ead0b409b4cc43a889b295b" - integrity sha512-6AZHgFJKP3DJX0eCNJj01RpytUa3SOGawIxweHkNX2L6PYikOZmoh5B0d7hIHaIgveMjX990IAa/xK7jRTN8OA== +"@babel/plugin-transform-arrow-functions@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz#e22960d77e697c74f41c501d44d73dbf8a6a64cd" + integrity sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-async-to-generator@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.1.tgz#e5153eb1a3e028f79194ed8a7a4bf55f862b2062" - integrity sha512-XCgYjJ8TY2slj6SReBUyamJn3k2JLUIiiR5b6t1mNCMSvv7yx+jJpaewakikp0uWFQSF7ChPPoe3dHmXLpISkg== +"@babel/plugin-transform-async-to-generator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz#41a5017e49eb6f3cda9392a51eef29405b245a37" + integrity sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ== dependencies: - "@babel/helper-module-imports" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-remap-async-to-generator" "^7.10.1" + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.10.4" -"@babel/plugin-transform-block-scoped-functions@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.1.tgz#146856e756d54b20fff14b819456b3e01820b85d" - integrity sha512-B7K15Xp8lv0sOJrdVAoukKlxP9N59HS48V1J3U/JGj+Ad+MHq+am6xJVs85AgXrQn4LV8vaYFOB+pr/yIuzW8Q== +"@babel/plugin-transform-block-scoped-functions@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz#1afa595744f75e43a91af73b0d998ecfe4ebc2e8" + integrity sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-block-scoping@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.1.tgz#47092d89ca345811451cd0dc5d91605982705d5e" - integrity sha512-8bpWG6TtF5akdhIm/uWTyjHqENpy13Fx8chg7pFH875aNLwX8JxIxqm08gmAT+Whe6AOmaTeLPe7dpLbXt+xUw== +"@babel/plugin-transform-block-scoping@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.4.tgz#a670d1364bb5019a621b9ea2001482876d734787" + integrity sha512-J3b5CluMg3hPUii2onJDRiaVbPtKFPLEaV5dOPY5OeAbDi1iU/UbbFFTgwb7WnanaDy7bjU35kc26W3eM5Qa0A== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" lodash "^4.17.13" -"@babel/plugin-transform-classes@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.3.tgz#8d9a656bc3d01f3ff69e1fccb354b0f9d72ac544" - integrity sha512-irEX0ChJLaZVC7FvvRoSIxJlmk0IczFLcwaRXUArBKYHCHbOhe57aG8q3uw/fJsoSXvZhjRX960hyeAGlVBXZw== +"@babel/plugin-transform-classes@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz#405136af2b3e218bc4a1926228bc917ab1a0adc7" + integrity sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-define-map" "^7.10.3" - "@babel/helper-function-name" "^7.10.3" - "@babel/helper-optimise-call-expression" "^7.10.3" - "@babel/helper-plugin-utils" "^7.10.3" - "@babel/helper-replace-supers" "^7.10.1" - "@babel/helper-split-export-declaration" "^7.10.1" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-define-map" "^7.10.4" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.3.tgz#d3aa6eef67cb967150f76faff20f0abbf553757b" - integrity sha512-GWzhaBOsdbjVFav96drOz7FzrcEW6AP5nax0gLIpstiFaI3LOb2tAg06TimaWU6YKOfUACK3FVrxPJ4GSc5TgA== +"@babel/plugin-transform-computed-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz#9ded83a816e82ded28d52d4b4ecbdd810cdfc0eb" + integrity sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw== dependencies: - "@babel/helper-plugin-utils" "^7.10.3" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-destructuring@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.1.tgz#abd58e51337815ca3a22a336b85f62b998e71907" - integrity sha512-V/nUc4yGWG71OhaTH705pU8ZSdM6c1KmmLP8ys59oOYbT7RpMYAR3MsVOt6OHL0WzG7BlTU076va9fjJyYzJMA== +"@babel/plugin-transform-destructuring@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz#70ddd2b3d1bea83d01509e9bb25ddb3a74fc85e5" + integrity sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-dotall-regex@^7.10.1", "@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.1.tgz#920b9fec2d78bb57ebb64a644d5c2ba67cc104ee" - integrity sha512-19VIMsD1dp02RvduFUmfzj8uknaO3uiHHF0s3E1OHnVsNj8oge8EQ5RzHRbJjGSetRnkEuBYO7TG1M5kKjGLOA== +"@babel/plugin-transform-dotall-regex@^7.10.4", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz#469c2062105c1eb6a040eaf4fac4b488078395ee" + integrity sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-duplicate-keys@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.1.tgz#c900a793beb096bc9d4d0a9d0cde19518ffc83b9" - integrity sha512-wIEpkX4QvX8Mo9W6XF3EdGttrIPZWozHfEaDTU0WJD/TDnXMvdDh30mzUl/9qWhnf7naicYartcEfUghTCSNpA== +"@babel/plugin-transform-duplicate-keys@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz#697e50c9fee14380fe843d1f306b295617431e47" + integrity sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-exponentiation-operator@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.1.tgz#279c3116756a60dd6e6f5e488ba7957db9c59eb3" - integrity sha512-lr/przdAbpEA2BUzRvjXdEDLrArGRRPwbaF9rvayuHRvdQ7lUTTkZnhZrJ4LE2jvgMRFF4f0YuPQ20vhiPYxtA== +"@babel/plugin-transform-exponentiation-operator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz#5ae338c57f8cf4001bdb35607ae66b92d665af2e" + integrity sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-for-of@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.1.tgz#ff01119784eb0ee32258e8646157ba2501fcfda5" - integrity sha512-US8KCuxfQcn0LwSCMWMma8M2R5mAjJGsmoCBVwlMygvmDUMkTCykc84IqN1M7t+agSfOmLYTInLCHJM+RUoz+w== +"@babel/plugin-transform-for-of@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz#c08892e8819d3a5db29031b115af511dbbfebae9" + integrity sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-function-name@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.1.tgz#4ed46fd6e1d8fde2a2ec7b03c66d853d2c92427d" - integrity sha512-//bsKsKFBJfGd65qSNNh1exBy5Y9gD9ZN+DvrJ8f7HXr4avE5POW6zB7Rj6VnqHV33+0vXWUwJT0wSHubiAQkw== +"@babel/plugin-transform-function-name@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz#6a467880e0fc9638514ba369111811ddbe2644b7" + integrity sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg== dependencies: - "@babel/helper-function-name" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-literals@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.1.tgz#5794f8da82846b22e4e6631ea1658bce708eb46a" - integrity sha512-qi0+5qgevz1NHLZroObRm5A+8JJtibb7vdcPQF1KQE12+Y/xxl8coJ+TpPW9iRq+Mhw/NKLjm+5SHtAHCC7lAw== +"@babel/plugin-transform-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz#9f42ba0841100a135f22712d0e391c462f571f3c" + integrity sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-member-expression-literals@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.1.tgz#90347cba31bca6f394b3f7bd95d2bbfd9fce2f39" - integrity sha512-UmaWhDokOFT2GcgU6MkHC11i0NQcL63iqeufXWfRy6pUOGYeCGEKhvfFO6Vz70UfYJYHwveg62GS83Rvpxn+NA== +"@babel/plugin-transform-member-expression-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz#b1ec44fcf195afcb8db2c62cd8e551c881baf8b7" + integrity sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-modules-amd@^7.10.1", "@babel/plugin-transform-modules-amd@^7.9.6": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.1.tgz#65950e8e05797ebd2fe532b96e19fc5482a1d52a" - integrity sha512-31+hnWSFRI4/ACFr1qkboBbrTxoBIzj7qA69qlq8HY8p7+YCzkCT6/TvQ1a4B0z27VeWtAeJd6pr5G04dc1iHw== +"@babel/plugin-transform-modules-amd@^7.10.4", "@babel/plugin-transform-modules-amd@^7.10.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz#1b9cddaf05d9e88b3aad339cb3e445c4f020a9b1" + integrity sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw== dependencies: - "@babel/helper-module-transforms" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-module-transforms" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.1.tgz#d5ff4b4413ed97ffded99961056e1fb980fb9301" - integrity sha512-AQG4fc3KOah0vdITwt7Gi6hD9BtQP/8bhem7OjbaMoRNCH5Djx42O2vYMfau7QnAzQCa+RJnhJBmFFMGpQEzrg== +"@babel/plugin-transform-modules-commonjs@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz#66667c3eeda1ebf7896d41f1f16b17105a2fbca0" + integrity sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w== dependencies: - "@babel/helper-module-transforms" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-simple-access" "^7.10.1" + "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-simple-access" "^7.10.4" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.3.tgz#004ae727b122b7b146b150d50cba5ffbff4ac56b" - integrity sha512-GWXWQMmE1GH4ALc7YXW56BTh/AlzvDWhUNn9ArFF0+Cz5G8esYlVbXfdyHa1xaD1j+GnBoCeoQNlwtZTVdiG/A== +"@babel/plugin-transform-modules-systemjs@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.4.tgz#8f576afd943ac2f789b35ded0a6312f929c633f9" + integrity sha512-Tb28LlfxrTiOTGtZFsvkjpyjCl9IoaRI52AEU/VIwOwvDQWtbNJsAqTXzh+5R7i74e/OZHH2c2w2fsOqAfnQYQ== dependencies: - "@babel/helper-hoist-variables" "^7.10.3" - "@babel/helper-module-transforms" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.3" + "@babel/helper-hoist-variables" "^7.10.4" + "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.1.tgz#ea080911ffc6eb21840a5197a39ede4ee67b1595" - integrity sha512-EIuiRNMd6GB6ulcYlETnYYfgv4AxqrswghmBRQbWLHZxN4s7mupxzglnHqk9ZiUpDI4eRWewedJJNj67PWOXKA== +"@babel/plugin-transform-modules-umd@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz#9a8481fe81b824654b3a0b65da3df89f3d21839e" + integrity sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA== dependencies: - "@babel/helper-module-transforms" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-named-capturing-groups-regex@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.3.tgz#a4f8444d1c5a46f35834a410285f2c901c007ca6" - integrity sha512-I3EH+RMFyVi8Iy/LekQm948Z4Lz4yKT7rK+vuCAeRm0kTa6Z5W7xuhRxDNJv0FPya/her6AUgrDITb70YHtTvA== +"@babel/plugin-transform-named-capturing-groups-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz#78b4d978810b6f3bcf03f9e318f2fc0ed41aecb6" + integrity sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.8.3" + "@babel/helper-create-regexp-features-plugin" "^7.10.4" -"@babel/plugin-transform-new-target@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.1.tgz#6ee41a5e648da7632e22b6fb54012e87f612f324" - integrity sha512-MBlzPc1nJvbmO9rPr1fQwXOM2iGut+JC92ku6PbiJMMK7SnQc1rytgpopveE3Evn47gzvGYeCdgfCDbZo0ecUw== +"@babel/plugin-transform-new-target@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz#9097d753cb7b024cb7381a3b2e52e9513a9c6888" + integrity sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-object-super@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.1.tgz#2e3016b0adbf262983bf0d5121d676a5ed9c4fde" - integrity sha512-WnnStUDN5GL+wGQrJylrnnVlFhFmeArINIR9gjhSeYyvroGhBrSAXYg/RHsnfzmsa+onJrTJrEClPzgNmmQ4Gw== +"@babel/plugin-transform-object-super@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz#d7146c4d139433e7a6526f888c667e314a093894" + integrity sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-replace-supers" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" -"@babel/plugin-transform-parameters@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.1.tgz#b25938a3c5fae0354144a720b07b32766f683ddd" - integrity sha512-tJ1T0n6g4dXMsL45YsSzzSDZCxiHXAQp/qHrucOq5gEHncTA3xDxnd5+sZcoQp+N1ZbieAaB8r/VUCG0gqseOg== +"@babel/plugin-transform-parameters@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.4.tgz#7b4d137c87ea7adc2a0f3ebf53266871daa6fced" + integrity sha512-RurVtZ/D5nYfEg0iVERXYKEgDFeesHrHfx8RT05Sq57ucj2eOYAP6eu5fynL4Adju4I/mP/I6SO0DqNWAXjfLQ== dependencies: - "@babel/helper-get-function-arity" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-get-function-arity" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-property-literals@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.1.tgz#cffc7315219230ed81dc53e4625bf86815b6050d" - integrity sha512-Kr6+mgag8auNrgEpbfIWzdXYOvqDHZOF0+Bx2xh4H2EDNwcbRb9lY6nkZg8oSjsX+DH9Ebxm9hOqtKW+gRDeNA== +"@babel/plugin-transform-property-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz#f6fe54b6590352298785b83edd815d214c42e3c0" + integrity sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-regenerator@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.3.tgz#6ec680f140a5ceefd291c221cb7131f6d7e8cb6d" - integrity sha512-H5kNeW0u8mbk0qa1jVIVTeJJL6/TJ81ltD4oyPx0P499DhMJrTmmIFCmJ3QloGpQG8K9symccB7S7SJpCKLwtw== +"@babel/plugin-transform-regenerator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz#2015e59d839074e76838de2159db421966fd8b63" + integrity sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw== dependencies: regenerator-transform "^0.14.2" -"@babel/plugin-transform-reserved-words@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.1.tgz#0fc1027312b4d1c3276a57890c8ae3bcc0b64a86" - integrity sha512-qN1OMoE2nuqSPmpTqEM7OvJ1FkMEV+BjVeZZm9V9mq/x1JLKQ4pcv8riZJMNN3u2AUGl0ouOMjRr2siecvHqUQ== +"@babel/plugin-transform-reserved-words@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz#8f2682bcdcef9ed327e1b0861585d7013f8a54dd" + integrity sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-shorthand-properties@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.1.tgz#e8b54f238a1ccbae482c4dce946180ae7b3143f3" - integrity sha512-AR0E/lZMfLstScFwztApGeyTHJ5u3JUKMjneqRItWeEqDdHWZwAOKycvQNCasCK/3r5YXsuNG25funcJDu7Y2g== +"@babel/plugin-transform-shorthand-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz#9fd25ec5cdd555bb7f473e5e6ee1c971eede4dd6" + integrity sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-spread@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.1.tgz#0c6d618a0c4461a274418460a28c9ccf5239a7c8" - integrity sha512-8wTPym6edIrClW8FI2IoaePB91ETOtg36dOkj3bYcNe7aDMN2FXEoUa+WrmPc4xa1u2PQK46fUX2aCb+zo9rfw== +"@babel/plugin-transform-spread@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.4.tgz#4e2c85ea0d6abaee1b24dcfbbae426fe8d674cff" + integrity sha512-1e/51G/Ni+7uH5gktbWv+eCED9pP8ZpRhZB3jOaI3mmzfvJTWHkuyYTv0Z5PYtyM+Tr2Ccr9kUdQxn60fI5WuQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-sticky-regex@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.1.tgz#90fc89b7526228bed9842cff3588270a7a393b00" - integrity sha512-j17ojftKjrL7ufX8ajKvwRilwqTok4q+BjkknmQw9VNHnItTyMP5anPFzxFJdCQs7clLcWpCV3ma+6qZWLnGMA== +"@babel/plugin-transform-sticky-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz#8f3889ee8657581130a29d9cc91d7c73b7c4a28d" + integrity sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-regex" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-regex" "^7.10.4" -"@babel/plugin-transform-template-literals@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.3.tgz#69d39b3d44b31e7b4864173322565894ce939b25" - integrity sha512-yaBn9OpxQra/bk0/CaA4wr41O0/Whkg6nqjqApcinxM7pro51ojhX6fv1pimAnVjVfDy14K0ULoRL70CA9jWWA== +"@babel/plugin-transform-template-literals@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.4.tgz#e6375407b30fcb7fcfdbba3bb98ef3e9d36df7bc" + integrity sha512-4NErciJkAYe+xI5cqfS8pV/0ntlY5N5Ske/4ImxAVX7mk9Rxt2bwDTGv1Msc2BRJvWQcmYEC+yoMLdX22aE4VQ== dependencies: - "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.3" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-typeof-symbol@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.1.tgz#60c0239b69965d166b80a84de7315c1bc7e0bb0e" - integrity sha512-qX8KZcmbvA23zDi+lk9s6hC1FM7jgLHYIjuLgULgc8QtYnmB3tAVIYkNoKRQ75qWBeyzcoMoK8ZQmogGtC/w0g== +"@babel/plugin-transform-typeof-symbol@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz#9509f1a7eec31c4edbffe137c16cc33ff0bc5bfc" + integrity sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-unicode-escapes@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.1.tgz#add0f8483dab60570d9e03cecef6c023aa8c9940" - integrity sha512-zZ0Poh/yy1d4jeDWpx/mNwbKJVwUYJX73q+gyh4bwtG0/iUlzdEu0sLMda8yuDFS6LBQlT/ST1SJAR6zYwXWgw== +"@babel/plugin-transform-unicode-escapes@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz#feae523391c7651ddac115dae0a9d06857892007" + integrity sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-unicode-regex@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.1.tgz#6b58f2aea7b68df37ac5025d9c88752443a6b43f" - integrity sha512-Y/2a2W299k0VIUdbqYm9X2qS6fE0CUBhhiPpimK6byy7OJ/kORLlIX+J6UrjgNu5awvs62k+6RSslxhcvVw2Tw== +"@babel/plugin-transform-unicode-regex@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz#e56d71f9282fac6db09c82742055576d5e6d80a8" + integrity sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" "@babel/polyfill@^7.8.7": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.10.1.tgz#d56d4c8be8dd6ec4dce2649474e9b707089f739f" - integrity sha512-TviueJ4PBW5p48ra8IMtLXVkDucrlOZAIZ+EXqS3Ot4eukHbWiqcn7DcqpA1k5PcKtmJ4Xl9xwdv6yQvvcA+3g== + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/polyfill/-/polyfill-7.10.4.tgz#915e5bfe61490ac0199008e35ca9d7d151a8e45a" + integrity sha512-8BYcnVqQ5kMD2HXoHInBH7H1b/uP3KdnwCYXOqFnXqguOyuu443WXusbIUbWEfY3Z0Txk0M1uG/8YuAMhNl6zg== dependencies: core-js "^2.6.5" regenerator-runtime "^0.13.4" "@babel/preset-env@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.10.3.tgz#3e58c9861bbd93b6a679987c7e4bd365c56c80c9" - integrity sha512-jHaSUgiewTmly88bJtMHbOd1bJf2ocYxb5BWKSDQIP5tmgFuS/n0gl+nhSrYDhT33m0vPxp+rP8oYYgPgMNQlg== + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.10.4.tgz#fbf57f9a803afd97f4f32e4f798bb62e4b2bef5f" + integrity sha512-tcmuQ6vupfMZPrLrc38d0sF2OjLT3/bZ0dry5HchNCQbrokoQi4reXqclvkkAT5b+gWc23meVWpve5P/7+w/zw== dependencies: - "@babel/compat-data" "^7.10.3" - "@babel/helper-compilation-targets" "^7.10.2" - "@babel/helper-module-imports" "^7.10.3" - "@babel/helper-plugin-utils" "^7.10.3" - "@babel/plugin-proposal-async-generator-functions" "^7.10.3" - "@babel/plugin-proposal-class-properties" "^7.10.1" - "@babel/plugin-proposal-dynamic-import" "^7.10.1" - "@babel/plugin-proposal-json-strings" "^7.10.1" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.1" - "@babel/plugin-proposal-numeric-separator" "^7.10.1" - "@babel/plugin-proposal-object-rest-spread" "^7.10.3" - "@babel/plugin-proposal-optional-catch-binding" "^7.10.1" - "@babel/plugin-proposal-optional-chaining" "^7.10.3" - "@babel/plugin-proposal-private-methods" "^7.10.1" - "@babel/plugin-proposal-unicode-property-regex" "^7.10.1" + "@babel/compat-data" "^7.10.4" + "@babel/helper-compilation-targets" "^7.10.4" + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-proposal-async-generator-functions" "^7.10.4" + "@babel/plugin-proposal-class-properties" "^7.10.4" + "@babel/plugin-proposal-dynamic-import" "^7.10.4" + "@babel/plugin-proposal-json-strings" "^7.10.4" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.4" + "@babel/plugin-proposal-numeric-separator" "^7.10.4" + "@babel/plugin-proposal-object-rest-spread" "^7.10.4" + "@babel/plugin-proposal-optional-catch-binding" "^7.10.4" + "@babel/plugin-proposal-optional-chaining" "^7.10.4" + "@babel/plugin-proposal-private-methods" "^7.10.4" + "@babel/plugin-proposal-unicode-property-regex" "^7.10.4" "@babel/plugin-syntax-async-generators" "^7.8.0" - "@babel/plugin-syntax-class-properties" "^7.10.1" + "@babel/plugin-syntax-class-properties" "^7.10.4" "@babel/plugin-syntax-dynamic-import" "^7.8.0" "@babel/plugin-syntax-json-strings" "^7.8.0" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" - "@babel/plugin-syntax-numeric-separator" "^7.10.1" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" "@babel/plugin-syntax-object-rest-spread" "^7.8.0" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" "@babel/plugin-syntax-optional-chaining" "^7.8.0" - "@babel/plugin-syntax-top-level-await" "^7.10.1" - "@babel/plugin-transform-arrow-functions" "^7.10.1" - "@babel/plugin-transform-async-to-generator" "^7.10.1" - "@babel/plugin-transform-block-scoped-functions" "^7.10.1" - "@babel/plugin-transform-block-scoping" "^7.10.1" - "@babel/plugin-transform-classes" "^7.10.3" - "@babel/plugin-transform-computed-properties" "^7.10.3" - "@babel/plugin-transform-destructuring" "^7.10.1" - "@babel/plugin-transform-dotall-regex" "^7.10.1" - "@babel/plugin-transform-duplicate-keys" "^7.10.1" - "@babel/plugin-transform-exponentiation-operator" "^7.10.1" - "@babel/plugin-transform-for-of" "^7.10.1" - "@babel/plugin-transform-function-name" "^7.10.1" - "@babel/plugin-transform-literals" "^7.10.1" - "@babel/plugin-transform-member-expression-literals" "^7.10.1" - "@babel/plugin-transform-modules-amd" "^7.10.1" - "@babel/plugin-transform-modules-commonjs" "^7.10.1" - "@babel/plugin-transform-modules-systemjs" "^7.10.3" - "@babel/plugin-transform-modules-umd" "^7.10.1" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.3" - "@babel/plugin-transform-new-target" "^7.10.1" - "@babel/plugin-transform-object-super" "^7.10.1" - "@babel/plugin-transform-parameters" "^7.10.1" - "@babel/plugin-transform-property-literals" "^7.10.1" - "@babel/plugin-transform-regenerator" "^7.10.3" - "@babel/plugin-transform-reserved-words" "^7.10.1" - "@babel/plugin-transform-shorthand-properties" "^7.10.1" - "@babel/plugin-transform-spread" "^7.10.1" - "@babel/plugin-transform-sticky-regex" "^7.10.1" - "@babel/plugin-transform-template-literals" "^7.10.3" - "@babel/plugin-transform-typeof-symbol" "^7.10.1" - "@babel/plugin-transform-unicode-escapes" "^7.10.1" - "@babel/plugin-transform-unicode-regex" "^7.10.1" + "@babel/plugin-syntax-top-level-await" "^7.10.4" + "@babel/plugin-transform-arrow-functions" "^7.10.4" + "@babel/plugin-transform-async-to-generator" "^7.10.4" + "@babel/plugin-transform-block-scoped-functions" "^7.10.4" + "@babel/plugin-transform-block-scoping" "^7.10.4" + "@babel/plugin-transform-classes" "^7.10.4" + "@babel/plugin-transform-computed-properties" "^7.10.4" + "@babel/plugin-transform-destructuring" "^7.10.4" + "@babel/plugin-transform-dotall-regex" "^7.10.4" + "@babel/plugin-transform-duplicate-keys" "^7.10.4" + "@babel/plugin-transform-exponentiation-operator" "^7.10.4" + "@babel/plugin-transform-for-of" "^7.10.4" + "@babel/plugin-transform-function-name" "^7.10.4" + "@babel/plugin-transform-literals" "^7.10.4" + "@babel/plugin-transform-member-expression-literals" "^7.10.4" + "@babel/plugin-transform-modules-amd" "^7.10.4" + "@babel/plugin-transform-modules-commonjs" "^7.10.4" + "@babel/plugin-transform-modules-systemjs" "^7.10.4" + "@babel/plugin-transform-modules-umd" "^7.10.4" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.4" + "@babel/plugin-transform-new-target" "^7.10.4" + "@babel/plugin-transform-object-super" "^7.10.4" + "@babel/plugin-transform-parameters" "^7.10.4" + "@babel/plugin-transform-property-literals" "^7.10.4" + "@babel/plugin-transform-regenerator" "^7.10.4" + "@babel/plugin-transform-reserved-words" "^7.10.4" + "@babel/plugin-transform-shorthand-properties" "^7.10.4" + "@babel/plugin-transform-spread" "^7.10.4" + "@babel/plugin-transform-sticky-regex" "^7.10.4" + "@babel/plugin-transform-template-literals" "^7.10.4" + "@babel/plugin-transform-typeof-symbol" "^7.10.4" + "@babel/plugin-transform-unicode-escapes" "^7.10.4" + "@babel/plugin-transform-unicode-regex" "^7.10.4" "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.10.3" + "@babel/types" "^7.10.4" browserslist "^4.12.0" core-js-compat "^3.6.2" invariant "^2.2.2" @@ -792,9 +757,9 @@ esutils "^2.0.2" "@babel/runtime@^7.8.4": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.1.tgz#b6eb75cac279588d3100baecd1b9894ea2840822" - integrity sha512-nQbbCbQc9u/rpg1XCxoMYQTbSMVZjCDxErQ1ClCn9Pvcmv1lGads19ep0a2VsEiIJeHqjZley6EQGEC3Yo1xMA== + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.4.tgz#a6724f1a6b8d2f6ea5236dbfe58c7d7ea9c5eb99" + integrity sha512-UpTN5yUJr9b4EX2CnGNWIvER7Ab83ibv0pcvvHc4UOdrBI5jb8bj+32cCwPX6xu0mt2daFNjYhoi+X7beH0RSw== dependencies: regenerator-runtime "^0.13.4" @@ -805,37 +770,37 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.10.1", "@babel/template@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.3.tgz#4d13bc8e30bf95b0ce9d175d30306f42a2c9a7b8" - integrity sha512-5BjI4gdtD+9fHZUsaxPHPNpwa+xRkDO7c7JbhYn2afvrkDu5SfAAbi9AIMXw2xEhO/BR35TqiW97IqNvCo/GqA== +"@babel/template@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" + integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== dependencies: - "@babel/code-frame" "^7.10.3" - "@babel/parser" "^7.10.3" - "@babel/types" "^7.10.3" + "@babel/code-frame" "^7.10.4" + "@babel/parser" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/traverse@^7.10.1", "@babel/traverse@^7.10.3": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.3.tgz#0b01731794aa7b77b214bcd96661f18281155d7e" - integrity sha512-qO6623eBFhuPm0TmmrUFMT1FulCmsSeJuVGhiLodk2raUDFhhTECLd9E9jC4LBIWziqt4wgF6KuXE4d+Jz9yug== +"@babel/traverse@^7.10.4", "@babel/traverse@^7.10.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.5.tgz#77ce464f5b258be265af618d8fddf0536f20b564" + integrity sha512-yc/fyv2gUjPqzTz0WHeRJH2pv7jA9kA7mBX2tXl/x5iOE81uaVPuGPtaYk7wmkx4b67mQ7NqI8rmT2pF47KYKQ== dependencies: - "@babel/code-frame" "^7.10.3" - "@babel/generator" "^7.10.3" - "@babel/helper-function-name" "^7.10.3" - "@babel/helper-split-export-declaration" "^7.10.1" - "@babel/parser" "^7.10.3" - "@babel/types" "^7.10.3" + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.10.5" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" + "@babel/parser" "^7.10.5" + "@babel/types" "^7.10.5" debug "^4.1.0" globals "^11.1.0" - lodash "^4.17.13" + lodash "^4.17.19" -"@babel/types@^7.10.1", "@babel/types@^7.10.3", "@babel/types@^7.4.4": - version "7.10.3" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.3.tgz#6535e3b79fea86a6b09e012ea8528f935099de8e" - integrity sha512-nZxaJhBXBQ8HVoIcGsf9qWep3Oh3jCENK54V4mRF7qaJabVsAYdbTtmSD8WmAp1R6ytPiu5apMwSXyxB1WlaBA== +"@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.4.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.5.tgz#d88ae7e2fde86bfbfe851d4d81afa70a997b5d15" + integrity sha512-ixV66KWfCI6GKoA/2H9v6bQdbfXEwwpOdQ8cRvb4F+eyvhlaHxWFMQB4+3d9QFJXZsiiiqVrewNV0DFEQpyT4Q== dependencies: - "@babel/helper-validator-identifier" "^7.10.3" - lodash "^4.17.13" + "@babel/helper-validator-identifier" "^7.10.4" + lodash "^4.17.19" to-fast-properties "^2.0.0" "@csstools/convert-colors@^1.4.0": @@ -955,13 +920,6 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha1-7ihweulOEdK4J7y+UnC86n8+ce4= -"@types/jszip@^3.4.1": - version "3.4.1" - resolved "https://registry.yarnpkg.com/@types/jszip/-/jszip-3.4.1.tgz#e7a4059486e494c949ef750933d009684227846f" - integrity sha512-TezXjmf3lj+zQ651r6hPqvSScqBLvyPI9FxdXBqpEwBijNGQ2NXpaFW/7joGzveYkKQUil7iiDHLo6LV71Pc0A== - dependencies: - jszip "*" - "@types/localforage@0.0.34": version "0.0.34" resolved "https://registry.yarnpkg.com/@types/localforage/-/localforage-0.0.34.tgz#5e31c32dd8791ec4b9ff3ef47c9cb55b2d0d9438" @@ -1357,7 +1315,7 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" -ansi-styles@^4.1.0: +ansi-styles@^4.0.0, ansi-styles@^4.1.0: version "4.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== @@ -1383,6 +1341,14 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + append-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" @@ -1588,10 +1554,10 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= -ast-metadata-inferer@^0.2.0-0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/ast-metadata-inferer/-/ast-metadata-inferer-0.2.0.tgz#a470e5d1d7402b18c6f7a1f3d6900723cfa07392" - integrity sha512-6yPph2NeCHNxoI/ZmjklYaLOSZDAx+0L0+wsXnF56FxmjxvUlYZSWcj1KXtXO8IufruQTzVFOjg1+IzdDazSPg== +ast-metadata-inferer@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/ast-metadata-inferer/-/ast-metadata-inferer-0.4.0.tgz#6be85ceeffcf267bd79db8e1ae731da44880b45f" + integrity sha512-tKHdBe8N/Vq2nLAm4YPBVREVZjMux6KrqyPfNQgIbDl0t7HaNSmy8w4OyVHYg/cvyn5BW7o7pVwpjPte89Zhcg== astral-regex@^1.0.0: version "1.0.0" @@ -1650,14 +1616,14 @@ atob@^2.1.2: resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.2.tgz#6d9517eb9e030d2436666651e86bd9f6f13533c9" integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== -autoprefixer@^9.0.0, autoprefixer@^9.6.1, autoprefixer@^9.8.0, autoprefixer@^9.8.2: - version "9.8.2" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.2.tgz#7347396ee576b18687041bfbacd76d78e27baa56" - integrity sha512-9UwMMU8Rg7Fj0c55mbOpXrr/2WrRqoOwOlLNTyyYt+nhiyQdIBWipp5XWzt+Lge8r3DK5y+EHMc1OBf8VpZA6Q== +autoprefixer@^9.0.0, autoprefixer@^9.6.1, autoprefixer@^9.8.0, autoprefixer@^9.8.5: + version "9.8.5" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.5.tgz#2c225de229ddafe1d1424c02791d0c3e10ccccaa" + integrity sha512-C2p5KkumJlsTHoNv9w31NrBRgXhf6eCMteJuHZi2xhkgC+5Vm40MEtCKPhc0qdgAOhox0YPy1SQHTAky05UoKg== dependencies: browserslist "^4.12.0" - caniuse-lite "^1.0.30001084" - kleur "^4.0.1" + caniuse-lite "^1.0.30001097" + colorette "^1.2.0" normalize-range "^0.1.2" num2fraction "^1.2.2" postcss "^7.0.32" @@ -1848,6 +1814,11 @@ binary-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== +binary-extensions@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" + integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== + bindings@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/bindings/-/bindings-1.5.0.tgz#10353c9e945334bc0511a6d90b38fbc7c9c504df" @@ -1919,7 +1890,7 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" -braces@^3.0.1: +braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -1931,20 +1902,20 @@ brorand@^1.0.1: resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" integrity sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8= -browser-sync-client@^2.26.6: - version "2.26.6" - resolved "https://registry.yarnpkg.com/browser-sync-client/-/browser-sync-client-2.26.6.tgz#e5201d3ace8aee88af17656b7b0c0620b6f8e4ab" - integrity sha512-mGrkZdNzttKdf/16I+y+2dTQxoMCIpKbVIMJ/uP8ZpnKu9f9qa/2CYVtLtbjZG8nsM14EwiCrjuFTGBEnT3Gjw== +browser-sync-client@^2.26.10: + version "2.26.10" + resolved "https://registry.yarnpkg.com/browser-sync-client/-/browser-sync-client-2.26.10.tgz#ca9309ba19f9695e7945b95062da8a7ef3156711" + integrity sha512-8pYitKwpVva7hzXJI8lTljNDbA9fjMEobHSxWqegIUon/GjJAG3UgHB/+lBWnOLzTY8rGX66MvGqL1Aknyrj7g== dependencies: etag "1.8.1" fresh "0.5.2" mitt "^1.1.3" rxjs "^5.5.6" -browser-sync-ui@^2.26.4: - version "2.26.4" - resolved "https://registry.yarnpkg.com/browser-sync-ui/-/browser-sync-ui-2.26.4.tgz#3772f13c6b93f2d7d333f4be0ca1ec02aae97dba" - integrity sha512-u20P3EsZoM8Pt+puoi3BU3KlbQAH1lAcV+/O4saF26qokrBqIDotmGonfWwoRbUmdxZkM9MBmA0K39ZTG1h4sA== +browser-sync-ui@^2.26.10: + version "2.26.10" + resolved "https://registry.yarnpkg.com/browser-sync-ui/-/browser-sync-ui-2.26.10.tgz#7b4b378de204b3913d4b8a6f93b16b1ba769d4bc" + integrity sha512-UfNSBItlXcmEvJ9RE4JooNtIsiIfHowp+7/52Jz4VFfQD4v78QK5/NV9DVrG41oMM3zLyhW4f/RliOb4ysStZg== dependencies: async-each-series "0.1.1" connect-history-api-fallback "^1" @@ -1953,16 +1924,16 @@ browser-sync-ui@^2.26.4: socket.io-client "^2.0.4" stream-throttle "^0.1.3" -browser-sync@^2.26.7: - version "2.26.7" - resolved "https://registry.yarnpkg.com/browser-sync/-/browser-sync-2.26.7.tgz#120287716eb405651a76cc74fe851c31350557f9" - integrity sha512-lY3emme0OyvA2ujEMpRmyRy9LY6gHLuTr2/ABxhIm3lADOiRXzP4dgekvnDrQqZ/Ec2Fz19lEjm6kglSG5766w== +browser-sync@^2.26.10: + version "2.26.10" + resolved "https://registry.yarnpkg.com/browser-sync/-/browser-sync-2.26.10.tgz#f03c043f615cf53c9294ccb2a5a5e25cfe11a230" + integrity sha512-JeVQP3CARvNA1DELj+ZGWj+/0pzE8+Omvq1WNgzaTXVdP3lNEbGxZbkjvLK7hHpQywjQ1sDJWlJQZT6V59XDTg== dependencies: - browser-sync-client "^2.26.6" - browser-sync-ui "^2.26.4" + browser-sync-client "^2.26.10" + browser-sync-ui "^2.26.10" bs-recipes "1.3.4" bs-snippet-injector "^2.0.1" - chokidar "^2.0.4" + chokidar "^3.4.1" connect "3.6.6" connect-history-api-fallback "^1" dev-ip "^1.0.1" @@ -1971,10 +1942,10 @@ browser-sync@^2.26.7: etag "^1.8.1" fresh "^0.5.2" fs-extra "3.0.1" - http-proxy "1.15.2" + http-proxy "^1.18.1" immutable "^3" - localtunnel "1.9.2" - micromatch "^3.1.10" + localtunnel "^2.0.0" + micromatch "^4.0.2" opn "5.3.0" portscanner "2.1.1" qs "6.2.3" @@ -1986,8 +1957,8 @@ browser-sync@^2.26.7: serve-static "1.13.2" server-destroy "1.0.1" socket.io "2.1.1" - ua-parser-js "0.7.17" - yargs "6.4.0" + ua-parser-js "^0.7.18" + yargs "^15.4.1" browserify-aes@^1.0.0, browserify-aes@^1.0.4: version "1.2.0" @@ -2056,15 +2027,15 @@ browserslist@^1.1.3: caniuse-db "^1.0.30000639" electron-to-chromium "^1.2.7" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.6.4, browserslist@^4.8.5: - version "4.12.0" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.12.0.tgz#06c6d5715a1ede6c51fc39ff67fd647f740b656d" - integrity sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg== +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.12.2, browserslist@^4.6.4, browserslist@^4.8.5: + version "4.12.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.12.2.tgz#76653d7e4c57caa8a1a28513e2f4e197dc11a711" + integrity sha512-MfZaeYqR8StRZdstAK9hCKDd2StvePCYp5rHzQCPicUjfFliDgmuaBNPHYUTpAywBN8+Wc/d7NYVFkO0aqaBUw== dependencies: - caniuse-lite "^1.0.30001043" - electron-to-chromium "^1.3.413" - node-releases "^1.1.53" - pkg-up "^2.0.0" + caniuse-lite "^1.0.30001088" + electron-to-chromium "^1.3.483" + escalade "^3.0.1" + node-releases "^1.1.58" bs-recipes@1.3.4: version "1.3.4" @@ -2306,15 +2277,15 @@ caniuse-db@^1.0.30000639: resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001036.tgz#8761fb6cd423ef2d3f8d96a21d898932252dc477" integrity sha512-plRkihXQyiDaFUXC7x/jAIXXTKiiaWvfAagsruh/vmstnRQ+a2a95HyENxiTr5WrkPSvmFUIvsRUalVFyeh2/w== -caniuse-db@^1.0.30001059: - version "1.0.30001068" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001068.tgz#79fa671a063f03485c663f4165252f039c312c36" - integrity sha512-FF4o1nUDSnYY8rPCldTJ1486rqcgSZasQtWIMvSC3WOllFJNvmwhuBcApuWC1CD2TKTRnIBXqM4d4lJsCdRJzQ== +caniuse-db@^1.0.30001090: + version "1.0.30001093" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001093.tgz#5a1cae72d94df1156f40f15d9079456e1b29d050" + integrity sha512-XqXxHR6Z9IN0BXLKMaTJ1NZ+US74cbKritholD6uaDLUWHiDj0QilpSb708wOcoGz0PmPRsXT/6zE+bjx+QSMw== -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001043, caniuse-lite@^1.0.30001084: - version "1.0.30001085" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001085.tgz#bed28bd51ff7425d33ee23e730c7f3b703711db6" - integrity sha512-x0YRFRE0pmOD90z+9Xk7jwO58p4feVNXP+U8kWV+Uo/HADyrgESlepzIkUqPgaXkpyceZU6siM1gsK7sHgplqA== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001088, caniuse-lite@^1.0.30001097: + version "1.0.30001099" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001099.tgz#540118fcc6842d1fde62f4ee5521d1ec6afdb40e" + integrity sha512-sdS9A+sQTk7wKoeuZBN/YMAHVztUfVnjDi4/UV3sDE8xoh7YR12hKW+pIdB3oqKGwr9XaFL2ovfzt9w8eUI5CA== caseless@~0.12.0: version "0.12.0" @@ -2397,7 +2368,7 @@ chardet@^0.7.0: resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.7.0.tgz#90094849f0937f2eedc2425d0d28a9e5f0cbad9e" integrity sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA== -chokidar@^2.0.0, chokidar@^2.0.4, chokidar@^2.1.8: +chokidar@^2.0.0, chokidar@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.1.8.tgz#804b3a7b6a99358c3c5c61e71d8728f041cff917" integrity sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg== @@ -2416,6 +2387,21 @@ chokidar@^2.0.0, chokidar@^2.0.4, chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" +chokidar@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.1.tgz#e905bdecf10eaa0a0b1db0c664481cc4cbc22ba1" + integrity sha512-TQTJyr2stihpC4Sya9hs2Xh+O2wf+igjL36Y75xx2WdHuiICcn/XJza46Jwt0eT5hVpQOzo3FpY3cj3RVYLX0g== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.4.0" + optionalDependencies: + fsevents "~2.1.2" + chownr@^1.1.1: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" @@ -2492,6 +2478,15 @@ cliui@^5.0.0: strip-ansi "^5.2.0" wrap-ansi "^5.1.0" +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + clone-buffer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" @@ -2629,6 +2624,11 @@ color@^3.0.0: color-convert "^1.9.1" color-string "^1.5.2" +colorette@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.0.tgz#45306add826d196e8c87236ac05d797f25982e63" + integrity sha512-soRSroY+OF/8OdA3PTQXwaDJeMc7TfknKKrxeSCencL2a4+Tx5zhxmmv7hdpCjhKBjehzp8+bwe/T68K0hpIjw== + combined-stream@^1.0.6, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" @@ -3172,10 +3172,10 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -date-fns@^2.14.0: - version "2.14.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.14.0.tgz#359a87a265bb34ef2e38f93ecf63ac453f9bc7ba" - integrity sha512-1zD+68jhFgDIM0rF05rcwYO8cExdNqxjq4xP1QKM60Q45mnO6zaMWB4tOzrIr4M4GSLntsKeE4c9Bdl2jhL/yw== +date-fns@^2.15.0: + version "2.15.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.15.0.tgz#424de6b3778e4e69d3ff27046ec136af58ae5d5f" + integrity sha512-ZCPzAMJZn3rNUvvQIMlXhDr4A+Ar07eLeGsGREoWU19a3Pqf5oYa+ccd+B3F6XVtQY6HANMFdOQ8A+ipFnvJdQ== dateformat@^2.0.0: version "2.2.0" @@ -3438,13 +3438,6 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -document-register-element@^1.14.3: - version "1.14.3" - resolved "https://registry.yarnpkg.com/document-register-element/-/document-register-element-1.14.3.tgz#3335d4578df6a1536a34595b91cca36dd5db61d7" - integrity sha512-SbJTzoQXLTcYxnpdDNRZXu/gwsGSShemXpvj6Pa6ujRwJFpJ41siil4tk4y+cQXnqylS6mc2Rtxp/PkMzfkqyQ== - dependencies: - lightercollective "^0.3.0" - dom-converter@^0.2: version "0.2.0" resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" @@ -3632,10 +3625,10 @@ electron-to-chromium@^1.2.7: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.427.tgz#ea43d02908a8c71f47ebb46e09de5a3cf8236f04" integrity sha512-/rG5G7Opcw68/Yrb4qYkz07h3bESVRJjUl4X/FrKLXzoUJleKm6D7K7rTTz8V5LUWnd+BbTOyxJX2XprRqHD8A== -electron-to-chromium@^1.3.413: - version "1.3.453" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.453.tgz#758a8565a64b7889b27132a51d2abb8b135c9d01" - integrity sha512-IQbCfjJR0NDDn/+vojTlq7fPSREcALtF8M1n01gw7nQghCtfFYrJ2dfhsp8APr8bANoFC8vRTFVXMOGpT0eetw== +electron-to-chromium@^1.3.483: + version "1.3.488" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.488.tgz#9226229f5fbc825959210e81e0bb3e63035d1c06" + integrity sha512-NReBdOugu1yl8ly+0VDtiQ6Yw/1sLjnvflWq0gvY1nfUXU2PbA+1XAVuEb7ModnwL/MfUPjby7e4pAFnSHiy6Q== elliptic@^6.0.0: version "6.5.2" @@ -3770,21 +3763,19 @@ entities@^2.0.0: integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw== epubjs@^0.3.85: - version "0.3.87" - resolved "https://registry.yarnpkg.com/epubjs/-/epubjs-0.3.87.tgz#0a2a94e59777e04548deff49a1c713ccbf3378fc" - integrity sha512-UlzXj04JQaUJ4p6ux/glQcVC4ayBtnpHT7niw4ozGy8EOQTAr8+/z7UZEHUmqQj4yHIoPYC4qGXtmzNqImWx1A== + version "0.3.88" + resolved "https://registry.yarnpkg.com/epubjs/-/epubjs-0.3.88.tgz#bc365e7e21893cf2d92717ce10927c1071275347" + integrity sha512-VRumULpUELYmYwzypyfbDwoSIqDp2LXOXCtY3o55o3YDW5Zm32UjtZuX/xaWFGqyZORNNMWWQ8VlMaY1djnDYg== dependencies: - "@types/jszip" "^3.4.1" "@types/localforage" "0.0.34" + core-js "^3.6.5" event-emitter "^0.3.5" jszip "^3.4.0" localforage "^1.7.3" lodash "^4.17.15" marks-pane "^1.0.9" path-webpack "0.0.3" - stream-browserify "^2.0.1" - url-polyfill "^1.1.9" - xmldom "^0.1.27" + xmldom "^0.3.0" errno@^0.1.3, errno@~0.1.7: version "0.1.7" @@ -3800,7 +3791,24 @@ error-ex@^1.2.0, error-ex@^1.3.1: dependencies: is-arrayish "^0.2.1" -es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5: +es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.5: + version "1.17.6" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" + integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== + dependencies: + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.1" + is-callable "^1.2.0" + is-regex "^1.1.0" + object-inspect "^1.7.0" + object-keys "^1.1.1" + object.assign "^4.1.0" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" + +es-abstract@^1.17.2: version "1.17.5" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== @@ -3867,6 +3875,11 @@ es6-weak-map@^2.0.1, es6-weak-map@^2.0.2: es6-iterator "^2.0.3" es6-symbol "^3.1.1" +escalade@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.0.1.tgz#52568a77443f6927cd0ab9c73129137533c965ed" + integrity sha512-DR6NO3h9niOT+MZs7bjxlj2a1k+POu5RN8CLTPX2+i78bRi9eLe7+0zXgUHMnGXWybYcL61E9hGhPKqedy8tQA== + escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -3883,9 +3896,9 @@ escape-string-regexp@^2.0.0: integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w== eslint-import-resolver-node@^0.3.3: - version "0.3.3" - resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz#dbaa52b6b2816b50bc6711af75422de808e98404" - integrity sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg== + version "0.3.4" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.4.tgz#85ffa81942c25012d8231096ddf679c03042c717" + integrity sha512-ogtf+5AB/O+nM6DIeBUNr2fuT7ot9Qg/1harBfBtaP13ekEWFQEEMP94BCB7zaNW3gyY+8SHYF00rnqYwXKWOA== dependencies: debug "^2.6.9" resolve "^1.13.1" @@ -3899,16 +3912,17 @@ eslint-module-utils@^2.6.0: pkg-dir "^2.0.0" eslint-plugin-compat@^3.5.1: - version "3.7.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-compat/-/eslint-plugin-compat-3.7.0.tgz#03f1ebb350a3c7eb93b6f461e200048e6008594b" - integrity sha512-A3uzSYqUjNj6rMyaBuU3l8wSCadZjeZRZ7WF3eU9vUT0JItiqRysjmYELkHHCpH8l7wRprUu4MZPr37lFCw7iA== + version "3.8.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-compat/-/eslint-plugin-compat-3.8.0.tgz#2348d6105e7e87b823ae3b97b349512a2a45a7f2" + integrity sha512-5CuWUSZXZkXLCQJBriEpndn/YWrvggDSHTpRJq++kR8GVcsWbTdp8Eh+nBA7JlrNi7ZJ/+kniOVXmn3bpnxuRA== dependencies: - ast-metadata-inferer "^0.2.0-0" - browserslist "^4.12.0" - caniuse-db "^1.0.30001059" + ast-metadata-inferer "^0.4.0" + browserslist "^4.12.2" + caniuse-db "^1.0.30001090" core-js "^3.6.5" + find-up "^4.1.0" lodash.memoize "4.1.2" - mdn-browser-compat-data "^1.0.21" + mdn-browser-compat-data "^1.0.28" semver "7.3.2" eslint-plugin-eslint-comments@^3.2.0: @@ -3920,9 +3934,9 @@ eslint-plugin-eslint-comments@^3.2.0: ignore "^5.0.5" eslint-plugin-import@^2.21.2: - version "2.21.2" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.21.2.tgz#8fef77475cc5510801bedc95f84b932f7f334a7c" - integrity sha512-FEmxeGI6yaz+SnEB6YgNHlQK1Bs2DKLM+YF+vuTk5H8J9CLbJLtlPvRFgZZ2+sXiKAlN5dpdlrWOjK8ZoZJpQA== + version "2.22.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.22.0.tgz#92f7736fe1fde3e2de77623c838dd992ff5ffb7e" + integrity sha512-66Fpf1Ln6aIS5Gr/55ts19eUuoDhAbZgnr6UxK5hbDx6l/QgQgx61AePq+BV4PP2uXQFClgMVzep5zZ94qqsxg== dependencies: array-includes "^3.1.1" array.prototype.flat "^1.2.3" @@ -4070,15 +4084,10 @@ event-emitter@^0.3.5: d "1" es5-ext "~0.10.14" -eventemitter3@1.x.x: - version "1.2.0" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" - integrity sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg= - -eventemitter3@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.0.tgz#090b4d6cdbd645ed10bf750d4b5407942d7ba163" - integrity sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA== +eventemitter3@^4.0.0, eventemitter3@^4.0.3: + version "4.0.4" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.4.tgz#b5463ace635a083d018bdc7c917b4c5f10a85384" + integrity sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ== events@^3.0.0: version "3.1.0" @@ -4564,6 +4573,11 @@ follow-redirects@1.5.10: dependencies: debug "=3.1.0" +follow-redirects@^1.0.0: + version "1.12.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.12.1.tgz#de54a6205311b93d60398ebc01cf7015682312b6" + integrity sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg== + for-in@^1.0.1, for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" @@ -4660,6 +4674,11 @@ fsevents@^1.2.7: bindings "^1.5.0" nan "^2.12.1" +fsevents@~2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + fstream@^1.0.0, fstream@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.12.tgz#4e8ba8ee2d48be4f7d0de505455548eae5932045" @@ -4800,7 +4819,7 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-parent@^5.0.0, glob-parent@^5.1.0: +glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@~5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== @@ -5403,12 +5422,12 @@ hex-color-regex@^1.1.0: resolved "https://registry.yarnpkg.com/hex-color-regex/-/hex-color-regex-1.1.0.tgz#4c06fccb4602fe2602b3c93df82d7e7dbf1a8a8e" integrity sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ== -hls.js@^0.13.1: - version "0.13.2" - resolved "https://registry.yarnpkg.com/hls.js/-/hls.js-0.13.2.tgz#3e7dd28e3787c69c6aba42b64b11eb2c3c8c29f1" - integrity sha512-sIg2t4uGpWQLzuK1Iid9614WOKqxj4OYg+EbFbhhTDCsxpENBN+Du3yBFnoi+a83DuOOHdiQd1ydnti9loSGXw== +hls.js@^0.14.3: + version "0.14.3" + resolved "https://registry.yarnpkg.com/hls.js/-/hls.js-0.14.3.tgz#07f30710576376327f0b29c1316fd0bff31ca23a" + integrity sha512-j+lbGBH5eU9r8A8kYQQHw/8x+G+mGCmtBaP5n4LS4qY7dUEbZRfa/RHfS2jM+4OgCfjdL/hgkYWYSZmwTgG5KQ== dependencies: - eventemitter3 "3.1.0" + eventemitter3 "^4.0.3" url-toolkit "^2.1.6" hmac-drbg@^1.0.0: @@ -5541,13 +5560,14 @@ http-errors@~1.6.2: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" -http-proxy@1.15.2: - version "1.15.2" - resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.15.2.tgz#642fdcaffe52d3448d2bda3b0079e9409064da31" - integrity sha1-ZC/cr/5S00SNK9o7AHnpQJBk2jE= +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== dependencies: - eventemitter3 "1.x.x" - requires-port "1.x.x" + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" http-signature@~1.2.0: version "1.2.0" @@ -5794,10 +5814,10 @@ interpret@^1.4.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== -intersection-observer@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/intersection-observer/-/intersection-observer-0.10.0.tgz#4d11d63c1ff67e21e62987be24d55218da1a1a69" - integrity sha512-fn4bQ0Xq8FTej09YC/jqKZwtijpvARlRp6wxL5WTA6yPe2YWSJ5RJh7Nm79rK2qB0wr6iDQzH60XGq5V/7u8YQ== +intersection-observer@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/intersection-observer/-/intersection-observer-0.11.0.tgz#f4ea067070326f68393ee161cc0a2ca4c0040c6f" + integrity sha512-KZArj2QVnmdud9zTpKf279m2bbGfG+4/kn16UU0NL3pTVl52ZHiJ9IRNSsnn6jaHrL9EGLFM5eWjTx2fz/+zoQ== into-stream@^3.1.0: version "3.1.0" @@ -5891,6 +5911,13 @@ is-binary-path@^1.0.0: dependencies: binary-extensions "^1.0.0" +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-buffer@^1.1.5: version "1.1.6" resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" @@ -5901,10 +5928,10 @@ is-buffer@^2.0.0, is-buffer@^2.0.2: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== -is-callable@^1.1.4, is-callable@^1.1.5: - version "1.1.5" - resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab" - integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q== +is-callable@^1.1.4, is-callable@^1.1.5, is-callable@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" + integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== is-color-stop@^1.0.0: version "1.1.0" @@ -6018,7 +6045,7 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" -is-glob@^4.0.0, is-glob@^4.0.1: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== @@ -6116,12 +6143,12 @@ is-promise@^2.1: resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.2.2.tgz#39ab959ccbf9a774cf079f7b40c7a26f763135f1" integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== -is-regex@^1.0.5: - version "1.0.5" - resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae" - integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ== +is-regex@^1.0.5, is-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" + integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw== dependencies: - has "^1.0.3" + has-symbols "^1.0.1" is-regexp@^1.0.0: version "1.0.0" @@ -6273,10 +6300,10 @@ isurl@^1.0.0-alpha5: has-to-string-tag-x "^1.2.0" is-object "^1.0.1" -jellyfin-apiclient@^1.2.2: - version "1.2.2" - resolved "https://registry.yarnpkg.com/jellyfin-apiclient/-/jellyfin-apiclient-1.2.2.tgz#64f058320603df02d926f4c1b929b42c6acc4527" - integrity sha512-UwC56orm4darWlnNQJ1nbKo+W8ywlheJSJC6d9zm06CslYtOc/Dkv9kz2PadQEh+6EiBsB0hAZCc7FJ9ahOoGQ== +jellyfin-apiclient@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jellyfin-apiclient/-/jellyfin-apiclient-1.4.1.tgz#5e544a19bc001b16669eb7ecf46bb7d652365e41" + integrity sha512-BTTRucQ4tCLyiZ9kR9nAoxqxYp5/z+MCzkayy9vmMZ5C7jlVVsnxAXuuZjoa+AgXMjohXcM5Ci54myfJM1pRkA== "jellyfin-noto@https://github.com/jellyfin/jellyfin-noto": version "1.0.3" @@ -6388,10 +6415,10 @@ jstree@^3.3.10: dependencies: jquery ">=1.9.1" -jszip@*, jszip@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.4.0.tgz#1a69421fa5f0bb9bc222a46bca88182fba075350" - integrity sha512-gZAOYuPl4EhPTXT0GjhI3o+ZAz3su6EhLrKUoAivcKqyqC7laS5JEv4XWZND9BgcDcF83vI85yGbDmDR6UhrIg== +jszip@^3.4.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/jszip/-/jszip-3.5.0.tgz#b4fd1f368245346658e781fec9675802489e15f6" + integrity sha512-WRtu7TPCmYePR1nazfrtuF216cIVon/3GWOvHS9QR5bIwSbnxtdpma6un3jyGGNhHsKCSzn5Ypk+EkDRvTGiFA== dependencies: lie "~3.3.0" pako "~1.0.2" @@ -6439,11 +6466,6 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== -kleur@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.0.1.tgz#3d4948534b666e2578f93b6fafb62108e64f05ef" - integrity sha512-Qs6SqCLm63rd0kNVh+wO4XsWLU6kgfwwaPYsLiClWf0Tewkzsa6MvB21bespb8cz+ANS+2t3So1ge3gintzhlw== - known-css-properties@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/known-css-properties/-/known-css-properties-0.11.0.tgz#0da784f115ea77c76b81536d7052e90ee6c86a8a" @@ -6547,11 +6569,6 @@ liftoff@^3.1.0: rechoir "^0.6.2" resolve "^1.1.7" -lightercollective@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/lightercollective/-/lightercollective-0.3.0.tgz#1f07638642ec645d70bdb69ab2777676f35a28f0" - integrity sha512-RFOLSUVvwdK3xA0P8o6G7QGXLIyy1L2qv5caEI7zXN5ciaEjbAriRF182kbsoJ1S1TgvpyGcN485fMky6qxOPw== - limiter@^1.0.5: version "1.1.5" resolved "https://registry.yarnpkg.com/limiter/-/limiter-1.1.5.tgz#8f92a25b3b16c6131293a0cc834b4a838a2aa7c2" @@ -6617,21 +6634,21 @@ loader-utils@^2.0.0: json5 "^2.1.2" localforage@*, localforage@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.7.3.tgz#0082b3ca9734679e1bd534995bdd3b24cf10f204" - integrity sha512-1TulyYfc4udS7ECSBT2vwJksWbkwwTX8BzeUIiq8Y07Riy7bDAAnxDaPU/tWyOVmQAcWJIEIFP9lPfBGqVoPgQ== + version "1.7.4" + resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.7.4.tgz#88b59cc9b25ae54c76bb2c080b21ec832c22d3f6" + integrity sha512-3EmVZatmNVeCo/t6Te7P06h2alGwbq8wXlSkcSXMvDE2/edPmsVqTPlzGnZaqwZZDBs6v+kxWpqjVsqsNJT8jA== dependencies: lie "3.1.1" -localtunnel@1.9.2: - version "1.9.2" - resolved "https://registry.yarnpkg.com/localtunnel/-/localtunnel-1.9.2.tgz#0012fcabc29cf964c130a01858768aa2bb65b5af" - integrity sha512-NEKF7bDJE9U3xzJu3kbayF0WTvng6Pww7tzqNb/XtEARYwqw7CKEX7BvOMg98FtE9es2CRizl61gkV3hS8dqYg== +localtunnel@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/localtunnel/-/localtunnel-2.0.0.tgz#2ea71174fa80e34cce91b2a7ce416e6a57d9ff7c" + integrity sha512-g6E0aLgYYDvQDxIjIXkgJo2+pHj3sGg4Wz/XP3h2KtZnRsWPbOQY+hw1H8Z91jep998fkcVE9l+kghO+97vllg== dependencies: axios "0.19.0" debug "4.1.1" openurl "1.1.1" - yargs "6.6.0" + yargs "13.3.0" locate-path@^2.0.0: version "2.0.0" @@ -6795,10 +6812,10 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" 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.4, lodash@~4.17.12: - version "4.17.15" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" - integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== +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.19, lodash@^4.17.4, lodash@~4.17.12: + version "4.17.19" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" + integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== log-symbols@^1.0.2: version "1.0.2" @@ -7029,10 +7046,10 @@ mdast-util-compact@^2.0.0: dependencies: unist-util-visit "^2.0.0" -mdn-browser-compat-data@^1.0.21: - version "1.0.23" - resolved "https://registry.yarnpkg.com/mdn-browser-compat-data/-/mdn-browser-compat-data-1.0.23.tgz#52e21d74e52d40bacf1cc3377755897ef1639033" - integrity sha512-qzabBf9lN1UG6Ju6am5j4bsy8PJSxlE8zQEyDXzKqD+nAQsAnA8apvbkgTSIA/ZpKgz/7qOtpJgtgGN00MEsIg== +mdn-browser-compat-data@^1.0.28: + version "1.0.29" + resolved "https://registry.yarnpkg.com/mdn-browser-compat-data/-/mdn-browser-compat-data-1.0.29.tgz#9edddaa953221050c6959a538c993e915e619220" + integrity sha512-R9/8Xi1d9by2Ag5O7Sur3zoe8k/61a+yYeC4f6S5UhbEZb2ICmYNZuprm+2IO9bBcT3Pa2BtEx+xKoX/8v8tPw== dependencies: extend "3.0.2" @@ -7449,10 +7466,10 @@ node-libs-browser@^2.2.1: util "^0.11.0" vm-browserify "^1.0.1" -node-releases@^1.1.53: - version "1.1.57" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.57.tgz#f6754ce225fad0611e61228df3e09232e017ea19" - integrity sha512-ZQmnWS7adi61A9JsllJ2gdj2PauElcjnOwTp2O011iGzoakTxUsDGSe+6vD7wXbKdqhSFymC0OSx35aAMhrSdw== +node-releases@^1.1.58: + version "1.1.58" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.58.tgz#8ee20eef30fa60e52755fcc0942def5a734fe935" + integrity sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg== node-sass@^4.13.1: version "4.14.1" @@ -7524,7 +7541,7 @@ normalize-path@^2.0.1, normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" -normalize-path@^3.0.0: +normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== @@ -7632,9 +7649,9 @@ object-copy@^0.1.0: kind-of "^3.0.3" object-inspect@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" - integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + version "1.8.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" + integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1: version "1.1.1" @@ -8199,7 +8216,7 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -picomatch@^2.0.5, picomatch@^2.2.1: +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: version "2.2.2" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== @@ -8245,13 +8262,6 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" -pkg-up@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-2.0.0.tgz#c819ac728059a461cab1c3889a2be3c49a004d7f" - integrity sha1-yBmscoBZpGHKscOImivjxJoATX8= - dependencies: - find-up "^2.1.0" - plugin-error@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-1.0.1.tgz#77016bd8919d0ac377fdcdd0322328953ca5781c" @@ -9071,11 +9081,6 @@ pretty-hrtime@^1.0.0: resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" integrity sha1-t+PqQkNaTJsnWdmeDyAesZWALuE= -private@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" - integrity sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg== - process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" @@ -9369,6 +9374,13 @@ readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" +readdirp@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" + integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== + dependencies: + picomatch "^2.2.1" + rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -9408,9 +9420,9 @@ regenerate-unicode-properties@^8.2.0: regenerate "^1.4.0" regenerate@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" - integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg== + version "1.4.1" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.1.tgz#cad92ad8e6b591773485fbe05a485caf4f457e6f" + integrity sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A== regenerator-runtime@^0.13.4: version "0.13.5" @@ -9418,12 +9430,11 @@ regenerator-runtime@^0.13.4: integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== regenerator-transform@^0.14.2: - version "0.14.4" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.4.tgz#5266857896518d1616a78a0479337a30ea974cc7" - integrity sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw== + version "0.14.5" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" + integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== dependencies: "@babel/runtime" "^7.8.4" - private "^0.1.8" regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" @@ -9683,7 +9694,7 @@ require-main-filename@^2.0.0: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== -requires-port@1.x.x: +requires-port@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= @@ -10074,10 +10085,10 @@ sha.js@^2.4.0, sha.js@^2.4.8: inherits "^2.0.1" safe-buffer "^5.0.1" -shaka-player@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/shaka-player/-/shaka-player-3.0.1.tgz#abb87b28e4060e82266211f9d406aa28e789a281" - integrity sha512-sd//nbjJUlEZKRnGk6IBu0YW+Iw0ia8m5Zm4MxoL19VtDaiv0YuHo7ydFYkE3TcNOn++SCMQ+YntWtbNvRuQHw== +shaka-player@^2.5.13: + version "2.5.13" + resolved "https://registry.yarnpkg.com/shaka-player/-/shaka-player-2.5.13.tgz#f8c493b825c735fc86d619cba8b2eb2f2a382233" + integrity sha512-rEh7juGlTvvF10oD7+EukS12EysZXI2fiGvNLqO7GsBQ5R/sFwcTGEB8A6lWlHQXeGVbT+MxZWKMZwFE805G6A== dependencies: eme-encryption-scheme-polyfill "^2.0.1" @@ -10312,9 +10323,9 @@ sparkles@^1.0.0: integrity sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw== spdx-correct@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" - integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q== + version "3.1.1" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9" + integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w== dependencies: spdx-expression-parse "^3.0.0" spdx-license-ids "^3.0.0" @@ -10325,9 +10336,9 @@ spdx-exceptions@^2.1.0: integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== spdx-expression-parse@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" - integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg== + version "3.0.1" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679" + integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q== dependencies: spdx-exceptions "^2.1.0" spdx-license-ids "^3.0.0" @@ -10550,7 +10561,7 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.0" -string.prototype.trimend@^1.0.0: +string.prototype.trimend@^1.0.0, string.prototype.trimend@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== @@ -10576,7 +10587,7 @@ string.prototype.trimright@^2.1.1: es-abstract "^1.17.5" string.prototype.trimend "^1.0.0" -string.prototype.trimstart@^1.0.0: +string.prototype.trimstart@^1.0.0, string.prototype.trimstart@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== @@ -11351,10 +11362,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -ua-parser-js@0.7.17: - version "0.7.17" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.17.tgz#e9ec5f9498b9ec910e7ae3ac626a805c4d09ecac" - integrity sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g== +ua-parser-js@^0.7.18: + version "0.7.21" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.21.tgz#853cf9ce93f642f67174273cc34565ae6f308777" + integrity sha512-+O8/qh/Qj8CgC6eYBVBykMrNtp5Gebn4dlGD/kKXVkJNDwyrAwSIqwz8CDf+tsAIWVycKcku6gIXJ0qwx/ZXaQ== uglify-js@3.4.x: version "3.4.10" @@ -11649,11 +11660,6 @@ url-parse-lax@^3.0.0: dependencies: prepend-http "^2.0.0" -url-polyfill@^1.1.9: - version "1.1.9" - resolved "https://registry.yarnpkg.com/url-polyfill/-/url-polyfill-1.1.9.tgz#2c8d4224889a5c942800f708f5585368085603d9" - integrity sha512-q/R5sowGuRfKHm497swkV+s9cPYtZRkHxzpDjRhqLO58FwdWTIkt6Y/fJlznUD/exaKx/XnDzCYXz0V16ND7ow== - url-to-options@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" @@ -11977,10 +11983,10 @@ webworkify@^1.5.0: resolved "https://registry.yarnpkg.com/webworkify/-/webworkify-1.5.0.tgz#734ad87a774de6ebdd546e1d3e027da5b8f4a42c" integrity sha512-AMcUeyXAhbACL8S2hqqdqOLqvJ8ylmIbNwUIqQujRSouf4+eUFaXbG6F1Rbu+srlJMmxQWsiU7mOJi0nMBfM1g== -whatwg-fetch@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.0.0.tgz#fc804e458cc460009b1a2b966bc8817d2578aefb" - integrity sha512-9GSJUgz1D4MfyKU7KRqwOjXCXTqWdFNvEr7eUBYchQiVc744mqK/MzXPNR2WsPkmkOa4ywfg8C2n8h+13Bey1Q== +whatwg-fetch@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.2.0.tgz#8e134f701f0a4ab5fda82626f113e2b647fd16dc" + integrity sha512-SdGPoQMMnzVYThUbSrEvqTlkvC1Ux27NehaJ/GUHBfNrh5Mjg+1/uRyFMwVnxO2MrikMWvWAqUGgQOfVU4hT7w== which-module@^1.0.0: version "1.0.0" @@ -12006,11 +12012,6 @@ wide-align@^1.1.0: dependencies: string-width "^1.0.2 || 2" -window-size@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.2.0.tgz#b4315bb4214a3d7058ebeee892e13fa24d98b075" - integrity sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU= - word-wrap@~1.2.3: version "1.2.3" resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" @@ -12040,6 +12041,15 @@ wrap-ansi@^5.1.0: string-width "^3.0.0" strip-ansi "^5.0.0" +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -12088,10 +12098,10 @@ x-is-string@^0.1.0: resolved "https://registry.yarnpkg.com/x-is-string/-/x-is-string-0.1.0.tgz#474b50865af3a49a9c4657f05acd145458f77d82" integrity sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI= -xmldom@^0.1.27: - version "0.1.31" - resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.31.tgz#b76c9a1bd9f0a9737e5a72dc37231cf38375e2ff" - integrity sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ== +xmldom@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.3.0.tgz#e625457f4300b5df9c2e1ecb776147ece47f3e5a" + integrity sha512-z9s6k3wxE+aZHgXYxSTpGDo7BYOUfJsIRyoZiX6HTjwpwfS2wpQBQKa2fD+ShLyPkqDYo5ud7KitmLZ2Cd6r0g== xmlhttprequest-ssl@~1.5.4: version "1.5.5" @@ -12137,7 +12147,7 @@ yargs-parser@^10.0.0: dependencies: camelcase "^4.1.0" -yargs-parser@^13.1.2: +yargs-parser@^13.1.1, yargs-parser@^13.1.2: version "13.1.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== @@ -12145,7 +12155,7 @@ yargs-parser@^13.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^18.1.3: +yargs-parser@^18.1.2, yargs-parser@^18.1.3: version "18.1.3" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== @@ -12153,13 +12163,6 @@ yargs-parser@^18.1.3: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^4.1.0, yargs-parser@^4.2.0: - version "4.2.1" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" - integrity sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw= - dependencies: - camelcase "^3.0.0" - yargs-parser@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-5.0.0.tgz#275ecf0d7ffe05c77e64e7c86e4cd94bf0e1228a" @@ -12167,44 +12170,21 @@ yargs-parser@^5.0.0: dependencies: camelcase "^3.0.0" -yargs@6.4.0: - version "6.4.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.4.0.tgz#816e1a866d5598ccf34e5596ddce22d92da490d4" - integrity sha1-gW4ahm1VmMzzTlWW3c4i2S2kkNQ= +yargs@13.3.0: + version "13.3.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.0.tgz#4c657a55e07e5f2cf947f8a366567c04a0dedc83" + integrity sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA== dependencies: - camelcase "^3.0.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" + cliui "^5.0.0" + find-up "^3.0.0" + get-caller-file "^2.0.1" require-directory "^2.1.1" - require-main-filename "^1.0.1" + require-main-filename "^2.0.0" set-blocking "^2.0.0" - string-width "^1.0.2" - which-module "^1.0.0" - window-size "^0.2.0" - y18n "^3.2.1" - yargs-parser "^4.1.0" - -yargs@6.6.0: - version "6.6.0" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" - integrity sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg= - dependencies: - camelcase "^3.0.0" - cliui "^3.2.0" - decamelize "^1.1.1" - get-caller-file "^1.0.1" - os-locale "^1.4.0" - read-pkg-up "^1.0.1" - require-directory "^2.1.1" - require-main-filename "^1.0.1" - set-blocking "^2.0.0" - string-width "^1.0.2" - which-module "^1.0.0" - y18n "^3.2.1" - yargs-parser "^4.2.0" + string-width "^3.0.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^13.1.1" yargs@^13.3.2: version "13.3.2" @@ -12222,6 +12202,23 @@ yargs@^13.3.2: y18n "^4.0.0" yargs-parser "^13.1.2" +yargs@^15.4.1: + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.2" + yargs@^7.0.0, yargs@^7.1.0: version "7.1.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-7.1.0.tgz#6ba318eb16961727f5d284f8ea003e8d6154d0c8"