diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index be962be83..333ba2a71 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,6 +3,7 @@ name: CI Build on: push: branches: [ develop, master ] + workflow_dispatch: jobs: build-ui: @@ -38,7 +39,7 @@ jobs: - uses: actions/checkout@v2 - uses: actions/setup-dotnet@v1 with: - dotnet-version: '5.0.x' + dotnet-version: '6.0.x' - name: Nuget Cache uses: actions/cache@v2 @@ -67,7 +68,7 @@ jobs: uses: TriPSs/conventional-changelog-action@v3 with: version-file: 'version.json' - release-count: 20 + release-count: 40 skip-on-empty: 'false' git-message: 'chore(release): :rocket: {version}' @@ -103,6 +104,12 @@ jobs: format: tar.gz steps: - uses: actions/checkout@v2 + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: '6.0.x' + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: '5.0.x' - name: Nuget Cache uses: actions/cache@v2 @@ -183,6 +190,7 @@ jobs: if: contains(github.ref, 'develop') with: prerelease: true + generate_release_notes: true body: ${{ needs.versioning.outputs.changelog }} name: ${{ needs.versioning.outputs.tag }} tag_name: ${{ needs.versioning.outputs.tag }} diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml new file mode 100644 index 000000000..47917439c --- /dev/null +++ b/.github/workflows/chromatic.yml @@ -0,0 +1,47 @@ +name: 'Chromatic' + +# Event for the workflow +on: + push: + workflow_dispatch: + +# List of jobs +jobs: + storybook-build: + # Operating System + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + with: + fetch-depth: 0 + + - name: NodeModules Cache + uses: actions/cache@v2 + with: + path: '**/node_modules' + key: node_modules-${{ hashFiles('**/yarn.lock') }} + + - name: Install dependencies + working-directory: ./src/Ombi/ClientApp + run: yarn + + - name: Publish to Chromatic + if: github.ref != 'refs/heads/master' + uses: chromaui/action@v1 + with: + projectToken: 7c47e1a1a4bd + exitZeroOnChanges: true + workingDir: ./src/Ombi/ClientApp + buildScriptName: storybookbuild + exitOnceUploaded: true + + - name: Publish to Chromatic and auto accept changes + if: github.ref == 'refs/heads/master' + uses: chromaui/action@v1 + with: + projectToken: 7c47e1a1a4bd + autoAcceptChanges: true # 👈 Option to accept all changes + workingDir: ./src/Ombi/ClientApp + buildScriptName: storybookbuild + exitOnceUploaded: true diff --git a/.github/workflows/cypress.yml b/.github/workflows/cypress.yml index 499cd272d..9101bdb60 100644 --- a/.github/workflows/cypress.yml +++ b/.github/workflows/cypress.yml @@ -7,6 +7,7 @@ on: branches: [ develop ] schedule: - cron: '0 0 * * *' + workflow_dispatch: jobs: automation-tests: @@ -18,7 +19,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v1 with: - dotnet-version: 5.0.x + dotnet-version: 6.0.x - uses: actions/setup-node@v2 with: node-version: '14' @@ -33,15 +34,17 @@ jobs: - name: Install Frontend Deps run: yarn --cwd ./src/Ombi/ClientApp install + - name: Start Frontend + run: | + nohup yarn --cwd ./src/Ombi/ClientApp start & + - name: Install Automation Deps run: yarn --cwd ./tests install - name: Start Backend run: | - nohup dotnet run -p ./src/Ombi -- --host http://*:3577 & - - name: Start Frontend - run: | - nohup yarn --cwd ./src/Ombi/ClientApp start & + nohup dotnet run --project ./src/Ombi -- --host http://*:3577 & + - name: Cypress Tests uses: cypress-io/github-action@v2.8.2 with: @@ -50,8 +53,8 @@ jobs: headless: true working-directory: tests wait-on: http://localhost:3577/ - # 7 minutes - wait-on-timeout: 420 + # 10 minutes + wait-on-timeout: 600 env: CYPRESS_RECORD_KEY: ${{ secrets.CYPRESS_RECORD_KEY }} GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/issue-check.yml b/.github/workflows/issue-check.yml index 9dfe5cc45..51b87b8d3 100644 --- a/.github/workflows/issue-check.yml +++ b/.github/workflows/issue-check.yml @@ -8,9 +8,6 @@ jobs: issueCheck: runs-on: ubuntu-latest steps: - - name: Output version - run: | - echo "log: ${{ github.event.issue.body }}" - if: startsWith(github.event.issue.body , '**Describe the bug**') == false name: Close Issue diff --git a/.github/workflows/label.yml b/.github/workflows/label.yml index 7c724a62a..402c5ffd0 100644 --- a/.github/workflows/label.yml +++ b/.github/workflows/label.yml @@ -8,6 +8,8 @@ name: Labeler on: [pull_request] +permissions: write-all + jobs: label: diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index e353dce4d..7465635cc 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -3,6 +3,12 @@ name: PR Build on: pull_request: types: [opened, synchronize, reopened] + workflow_dispatch: + +permissions: + pull-requests: write + issues: write + repository-projects: write jobs: build-ui: @@ -27,11 +33,12 @@ jobs: unit-test: runs-on: ubuntu-latest + steps: - uses: actions/checkout@v2 - uses: actions/setup-dotnet@v1 with: - dotnet-version: '5.0.x' + dotnet-version: '6.0.x' - name: Nuget Cache uses: actions/cache@v2 @@ -44,7 +51,7 @@ jobs: - name: Run Unit Tests run: | cd src - dotnet test --logger trx --results-directory "TestResults" + dotnet test --configuration "Release" --logger "trx;LogFileName=test-results.trx" analysis: runs-on: ubuntu-latest @@ -89,6 +96,9 @@ jobs: format: tar.gz steps: - uses: actions/checkout@v2 + - uses: actions/setup-dotnet@v1 + with: + dotnet-version: '6.0.x' - name: Nuget Cache uses: actions/cache@v2 diff --git a/.gitignore b/.gitignore index 845eda385..cae15017a 100644 --- a/.gitignore +++ b/.gitignore @@ -251,3 +251,4 @@ _Pvt_Extensions /src/Ombi/databases.json /src/Ombi/healthchecksdb /src/Ombi/ClientApp/package-lock.json +/src/Ombi.Core/Properties/launchSettings.json diff --git a/.mergify.yml b/.mergify.yml new file mode 100644 index 000000000..fac2166e3 --- /dev/null +++ b/.mergify.yml @@ -0,0 +1,7 @@ +pull_request_rules: + - name: Automatic merge on approval + conditions: + - "#approved-reviews-by>=1" + actions: + merge: + method: merge diff --git a/CHANGELOG.md b/CHANGELOG.md index 0191c7064..63ab88463 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,62 +1,361 @@ -## [4.3.3](https://github.com/Ombi-app/Ombi/compare/v4.3.2...v4.3.3) (2021-11-05) - - - -## [4.3.2](https://github.com/Ombi-app/Ombi/compare/v4.3.1...v4.3.2) (2021-11-02) +## [4.22.3](https://github.com/Ombi-app/Ombi/compare/v4.22.2...v4.22.3) (2022-07-28) ### Bug Fixes -* **translations:** 🌐 Localization - Ensuring all of the app including backend are localized [#4366](https://github.com/Ombi-app/Ombi/issues/4366) ([5e140ab](https://github.com/Ombi-app/Ombi/commit/5e140ab6183b887a7665f5e870eb0bd05d487ace)) +* Override Sonarr V3 Profiles endpoint ([#4678](https://github.com/Ombi-app/Ombi/issues/4678)) ([875da95](https://github.com/Ombi-app/Ombi/commit/875da959f353119b05138d68ee6d32a49e14b91e)) -## [4.3.1](https://github.com/Ombi-app/Ombi/compare/v4.3.0...v4.3.1) (2021-10-27) +## [4.22.2](https://github.com/Ombi-app/Ombi/compare/v4.22.1...v4.22.2) (2022-07-25) ### Bug Fixes -* :bug: Hides no results message during search. ([#4375](https://github.com/Ombi-app/Ombi/issues/4375)) ([b819b0e](https://github.com/Ombi-app/Ombi/commit/b819b0e007e578bf3d8425f19591f87029c64d06)) +* fixed an issue where I broke images for some users ([81ddc85](https://github.com/Ombi-app/Ombi/commit/81ddc8553b9094c3f6843b036daebb2eb9262e00)) -# [4.3.0](https://github.com/Ombi-app/Ombi/compare/v4.2.13...v4.3.0) (2021-10-20) +## [4.22.1](https://github.com/Ombi-app/Ombi/compare/v4.22.0...v4.22.1) (2022-07-25) ### Bug Fixes -* **translations:** 🌐 New translations from Crowdin [skip ci] ([b0f3abb](https://github.com/Ombi-app/Ombi/commit/b0f3abb9ceebdbe5d6c20af98b7355df2999eb58)) -* **translations:** 🌐 New translations from Crowdin [skip ci] ([77d017b](https://github.com/Ombi-app/Ombi/commit/77d017b3d8ffd1714a2f6efecc8c900d56d062e4)) -* **translations:** 🌐 New translations from Crowdin [skip ci] ([f6e9784](https://github.com/Ombi-app/Ombi/commit/f6e9784367d3678d899ed79bef6caa52005b6661)) -* **translations:** 🌐 New translations from Crowdin [skip ci] ([601a877](https://github.com/Ombi-app/Ombi/commit/601a87762a2ad393ee5fa2fe52052ceeeefb1bef)) -* **translations:** 🌐 New translations from Crowdin [skip ci] ([a4a80ba](https://github.com/Ombi-app/Ombi/commit/a4a80ba4da49733a65e691003646c0f349bd4c5f)) -* **translations:** 🌐 New translations from Crowdin [skip ci] ([2961319](https://github.com/Ombi-app/Ombi/commit/2961319f61e95b2871480152b86ddca3375576a1)) -* **translations:** 🌐 New translations from Crowdin [skip ci] ([fc8d108](https://github.com/Ombi-app/Ombi/commit/fc8d108b660d53f499538328bfc271b05ac47d2b)) -* **translations:** 🌐 New translations from Crowdin [skip ci] ([1e03651](https://github.com/Ombi-app/Ombi/commit/1e03651c3b0eb77e45f9f6c55d31ee672eacd51e)) -* **translations:** 🌐 New translations from Crowdin [skip ci] ([c0dd327](https://github.com/Ombi-app/Ombi/commit/c0dd327426514e305a88750d7c3deb21c194108f)) -* **translations:** 🌐 New translations from Crowdin [skip ci] ([2156129](https://github.com/Ombi-app/Ombi/commit/2156129f175335746f204bb123035c070f518e96)) -* **translations:** 🌐 New translations from Crowdin [skip ci] ([aef0368](https://github.com/Ombi-app/Ombi/commit/aef0368de3aec306245bd1b16bc0de596a20d451)) -* **translations:** 🌐 New translations from Crowdin [skip ci] ([a38090b](https://github.com/Ombi-app/Ombi/commit/a38090b8dde17d1d150af0bca2830ea45d013a0e)) -* **translations:** 🌐 New translations from Crowdin [skip ci] ([c5f1d33](https://github.com/Ombi-app/Ombi/commit/c5f1d3355758a5c3648479d44e50397c7f6c1a9d)) -* **translations:** 🌐 New translations from Crowdin [skip ci] ([3846d56](https://github.com/Ombi-app/Ombi/commit/3846d56a6e561a1b1dc65c385151d90fdd6217ee)) -* **translations:** 🌐 New translations from Crowdin [skip ci] ([dafe9c1](https://github.com/Ombi-app/Ombi/commit/dafe9c1a19d84f00c13f0a51ba90927c24282926)) -* **translations:** 🌐 New translations from Crowdin [skip ci] ([edb418a](https://github.com/Ombi-app/Ombi/commit/edb418a6f05887c68a0c24c48decc691996f97e4)) -* **translations:** 🌐 New translations from Crowdin [skip ci] ([dadabf9](https://github.com/Ombi-app/Ombi/commit/dadabf93e1582a0c39321fd9bf3de3fb11e3f406)) +* **discover:** :bug: Created new Image component to handle 429's from TMDB ([#4698](https://github.com/Ombi-app/Ombi/issues/4698)) and fixed [#4635](https://github.com/Ombi-app/Ombi/issues/4635) ([#4699](https://github.com/Ombi-app/Ombi/issues/4699)) ([f22d3da](https://github.com/Ombi-app/Ombi/commit/f22d3da765799365455b919027f7563e52b347c3)) + + + +# [4.22.0](https://github.com/Ombi-app/Ombi/compare/v4.21.2...v4.22.0) (2022-07-22) ### Features -* **request-limits:** :sparkles: Added the new request limit options into the user importer ([01d4f4d](https://github.com/Ombi-app/Ombi/commit/01d4f4d718fe85ac181dae52565fb1b427965b4f)) -* **request-limits:** :sparkles: Added the new request limit options to the bulk edit ([03bc23a](https://github.com/Ombi-app/Ombi/commit/03bc23a74e4308aa6b4c6b25636edcdeb65c1f0e)) +* **discover:** ✨ Added infinite scroll on advanced search results ([898bc89](https://github.com/Ombi-app/Ombi/commit/898bc89fa78245c1f3de9481f6c724f087a16e39)) -## [4.2.13](https://github.com/Ombi-app/Ombi/compare/v4.2.12...v4.2.13) (2021-10-20) +## [4.21.2](https://github.com/Ombi-app/Ombi/compare/v4.21.1...v4.21.2) (2022-07-22) ### Bug Fixes -* **translations:** 🌐 New translations %two_letters_code% from Crowdin [skip ci] ([8fbd267](https://github.com/Ombi-app/Ombi/commit/8fbd267b516ddaa80fd16c091bae532b860fbf45)) +* Landing and Login page improvements ([#4690](https://github.com/Ombi-app/Ombi/issues/4690)) ([6d423b5](https://github.com/Ombi-app/Ombi/commit/6d423b5447c52c5e59d8d2bd92a23b47468eb736)) + + + +## [4.21.1](https://github.com/Ombi-app/Ombi/compare/v4.21.0...v4.21.1) (2022-07-11) + + +### Bug Fixes + +* **images:** Retry images with a backoff when we get a Too Many requests from TheMovieDb [#4685](https://github.com/Ombi-app/Ombi/issues/4685) ([3f1f35d](https://github.com/Ombi-app/Ombi/commit/3f1f35df3164db6739691cdda8f925c296239791)) + + + +# [4.21.0](https://github.com/Ombi-app/Ombi/compare/v4.20.4...v4.21.0) (2022-06-22) + + +### Features + +* Upgrade to Angular14 ([#4668](https://github.com/Ombi-app/Ombi/issues/4668)) ([b9d55a4](https://github.com/Ombi-app/Ombi/commit/b9d55a469b412558cbf67c1e25db7fdda5964cd8)) + + +### Performance Improvements + +* stop populating obsolete subscribe fields ([#4625](https://github.com/Ombi-app/Ombi/issues/4625)) ([9a73463](https://github.com/Ombi-app/Ombi/commit/9a734637665f671b17c2bb440d93b35a891c142b)) + + + +## [4.20.4](https://github.com/Ombi-app/Ombi/compare/v4.20.3...v4.20.4) (2022-06-15) + + +### Bug Fixes + +* fixed build ([f877921](https://github.com/Ombi-app/Ombi/commit/f8779219146051ea74f8b6408658ff7975afb88b)) + + + +## [4.20.3](https://github.com/Ombi-app/Ombi/compare/v4.20.2...v4.20.3) (2022-06-05) + + +### Bug Fixes + +* **plex:** 🐛 Fixed an issue with the Plex Sync ([ab1a11a](https://github.com/Ombi-app/Ombi/commit/ab1a11af78efbe9d37bd55aa80a640796c138a98)) + + + +## [4.20.2](https://github.com/Ombi-app/Ombi/compare/v4.20.1...v4.20.2) (2022-06-03) + + +### Bug Fixes + +* :bug: Fixed the Request on Behalf of having blanks ([#4667](https://github.com/Ombi-app/Ombi/issues/4667)) ([7dd9b1c](https://github.com/Ombi-app/Ombi/commit/7dd9b1cac07f571dd35b362544e4fe0226c4b817)) + + + +## [4.20.1](https://github.com/Ombi-app/Ombi/compare/v4.20.0...v4.20.1) (2022-05-27) + + +### Bug Fixes + +* added media type tag to media type text ([#4638](https://github.com/Ombi-app/Ombi/issues/4638)) ([fe501d3](https://github.com/Ombi-app/Ombi/commit/fe501d34a0c36ac9f000b107eca49dbc6694d006)) +* **API:** Fix pagination in some edge cases ([#4649](https://github.com/Ombi-app/Ombi/issues/4649)) ([a70bf8f](https://github.com/Ombi-app/Ombi/commit/a70bf8f46c76d74c9dfdf908c53bd9955ca0a35d)) +* **discover:** Carousel touch not working when scrolling page and recommendations and similar movie navigation ([#4633](https://github.com/Ombi-app/Ombi/issues/4633)) ([d5ef1d5](https://github.com/Ombi-app/Ombi/commit/d5ef1d53e5f77d19dba8b8059c80b538a3e14f2a)) +* Improve Swagger documentation ([#4652](https://github.com/Ombi-app/Ombi/issues/4652)) ([181892b](https://github.com/Ombi-app/Ombi/commit/181892bcfe88e6d76febf49ef57745d04552d08e)) +* Missing Poster broken link fix ([#4637](https://github.com/Ombi-app/Ombi/issues/4637)) ([4070f0d](https://github.com/Ombi-app/Ombi/commit/4070f0d093b1c92487a1c80cabad8283a9650f51)) +* **sickrage:** Fixed issue with incorrect handling of SiCKRAGE episode results returned during episode status changes, now expects array of objects from data path if present ([#4648](https://github.com/Ombi-app/Ombi/issues/4648)) ([6d16442](https://github.com/Ombi-app/Ombi/commit/6d16442d4d714920367df065a3ced42b729f4233)) +* **sync:** Emby+Jellyfin - sync multi-episode files of 3+ episodes ([bd8fd89](https://github.com/Ombi-app/Ombi/commit/bd8fd890554c9d85d6da4d2cee813e82ce698e52)) + + + +# [4.20.0](https://github.com/Ombi-app/Ombi/compare/v4.19.1...v4.20.0) (2022-04-28) + + +### Features + +* **discover:** Show more relevant shows in upcoming TV ([8357819](https://github.com/Ombi-app/Ombi/commit/8357819b53b8c675c0b246d7006b5a778bdba33f)) + + + +## [4.19.1](https://github.com/Ombi-app/Ombi/compare/v4.19.0...v4.19.1) (2022-04-27) + + + +# [4.19.0](https://github.com/Ombi-app/Ombi/compare/v4.18.0...v4.19.0) (2022-04-27) + + +### Features + +* **sync:** Detect reidentified movies in Emby and Jellyfin ([5938077](https://github.com/Ombi-app/Ombi/commit/5938077d82a5357f79c07b218b3986557a5816e8)) +* **sync:** Detect reidentified series in Emby and Jellyfin ([9096e91](https://github.com/Ombi-app/Ombi/commit/9096e91d55d268819bce22831f8a8b27f2a1776b)) + + + +# [4.18.0](https://github.com/Ombi-app/Ombi/compare/v4.17.0...v4.18.0) (2022-04-26) + + +### Bug Fixes + +* **discover:** Fix cache mix up ([03d9422](https://github.com/Ombi-app/Ombi/commit/03d94220c7eaafb50c6c80a6ed1150794b873ac3)) +* **discover:** Fix new trending feature detection ([6794b88](https://github.com/Ombi-app/Ombi/commit/6794b887f6544fb41528bdd9728b7824b65e47ee)) +* **settings:** Allow toggling features when there are more than one ([a373359](https://github.com/Ombi-app/Ombi/commit/a373359ae8e6bad42b558a6e01a8ff2840d3bbaa)) + + +### Features + +* **discover:** Add new trending source experimental feature ([1a0823c](https://github.com/Ombi-app/Ombi/commit/1a0823ca80559417c67323aaeaa1ef5243e98031)) +* **discover:** Default trending source to new logic ([4f12939](https://github.com/Ombi-app/Ombi/commit/4f12939e22020a67a5ee75e2907923faea136e8d)) + + + +# [4.17.0](https://github.com/Ombi-app/Ombi/compare/v4.16.17...v4.17.0) (2022-04-25) + + +### Features + +* **discover:** Add original language filter ([ef7ec86](https://github.com/Ombi-app/Ombi/commit/ef7ec861d8aede2a4817752c990617f583805391)) + + + +## [4.16.17](https://github.com/Ombi-app/Ombi/compare/v4.16.16...v4.16.17) (2022-04-25) + + + +## [4.16.16](https://github.com/Ombi-app/Ombi/compare/v4.16.15...v4.16.16) (2022-04-25) + + +### Bug Fixes + +* **4616:** :bug: fixed mandatory fields ([d8f2260](https://github.com/Ombi-app/Ombi/commit/d8f2260c7ae3ed48386743b7adbd06e284487034)) + + + +## [4.16.15](https://github.com/Ombi-app/Ombi/compare/v4.16.14...v4.16.15) (2022-04-24) + + + +## [4.16.14](https://github.com/Ombi-app/Ombi/compare/v4.16.13...v4.16.14) (2022-04-19) + + + +## [4.16.13](https://github.com/Ombi-app/Ombi/compare/v4.16.12...v4.16.13) (2022-04-19) + + + +## [4.16.12](https://github.com/Ombi-app/Ombi/compare/v4.16.11...v4.16.12) (2022-04-19) + + + +## [4.16.11](https://github.com/Ombi-app/Ombi/compare/v4.16.10...v4.16.11) (2022-04-14) + + +### Bug Fixes + +* Set the default job for the watchlist import to hourly instead of daily ([75906af](https://github.com/Ombi-app/Ombi/commit/75906af0adee3e3c68d825c3aaa8f7b918461b1f)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([0e8a64b](https://github.com/Ombi-app/Ombi/commit/0e8a64b8ca00d210fbe843ac2c3f6af218d80cbc)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([7b0ad61](https://github.com/Ombi-app/Ombi/commit/7b0ad61bfcff3986b33180dc64022cba7ea8eefb)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([4fc2c1f](https://github.com/Ombi-app/Ombi/commit/4fc2c1f24534085a783a3d5791f5533b68272153)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([76ab733](https://github.com/Ombi-app/Ombi/commit/76ab733b91791e4d93d184f3c7d0779c6a388695)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([06e4cef](https://github.com/Ombi-app/Ombi/commit/06e4cefa7b4e55b860da9a64f461f6ec8fa17367)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([c12d89d](https://github.com/Ombi-app/Ombi/commit/c12d89d6781a337520977ad285f8d08c93f434dd)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([bc0c2f6](https://github.com/Ombi-app/Ombi/commit/bc0c2f622e34fb5a2711039d9ed7aad34f982b15)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([e4b00e6](https://github.com/Ombi-app/Ombi/commit/e4b00e6b3468bd9389eeb02fc6ad7daf27abc3b3)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([d1998d3](https://github.com/Ombi-app/Ombi/commit/d1998d326f999a38586d0a351a20c5448df95842)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([bee4ccb](https://github.com/Ombi-app/Ombi/commit/bee4ccb804594e7385b1fbdc9fe2ef5c42e0d21f)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([80233ed](https://github.com/Ombi-app/Ombi/commit/80233ed560cc976e83570d0655c3472f20171fb3)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([8a78adc](https://github.com/Ombi-app/Ombi/commit/8a78adc9bb62f277f2b213dcb3847ed6d0089fcb)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([d04c60a](https://github.com/Ombi-app/Ombi/commit/d04c60aa5909b47ba6bffa6f66b03079cbd43521)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([92a785e](https://github.com/Ombi-app/Ombi/commit/92a785e736fa4b72a45270da2d0f4661df433078)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([634982d](https://github.com/Ombi-app/Ombi/commit/634982df2661cefab5ea9f5163fe04a005cc0171)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([b404baa](https://github.com/Ombi-app/Ombi/commit/b404baad6d0aeaa1561701e0db8db4e78613a364)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([d14f11e](https://github.com/Ombi-app/Ombi/commit/d14f11e0eb20ab0a68e765ee77968b3b3e54e995)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([7cf64f9](https://github.com/Ombi-app/Ombi/commit/7cf64f909d78908edaabeffb8a39a7d02e73fe7e)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([0c9e1ec](https://github.com/Ombi-app/Ombi/commit/0c9e1ec090827080cc8f7393e5e91456ff37d691)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([3b0b730](https://github.com/Ombi-app/Ombi/commit/3b0b730cb02efe24f6d4026e5fdb20d37e495119)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([6ed1a03](https://github.com/Ombi-app/Ombi/commit/6ed1a03b7ff4077f09ea9e13394b18b0d138f4c3)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([2941acd](https://github.com/Ombi-app/Ombi/commit/2941acd3b2ec74a5e6aeea275ab5a39d2653f37f)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([c075a1a](https://github.com/Ombi-app/Ombi/commit/c075a1a66784d975eaf60f2dfbbcbe048f2f63d7)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([76bd81c](https://github.com/Ombi-app/Ombi/commit/76bd81c3ca55a98c6ec944a838dc01294a6193a6)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([0d38275](https://github.com/Ombi-app/Ombi/commit/0d3827507e002bcf58f673e97ffcc3bd25dcf337)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([5c99601](https://github.com/Ombi-app/Ombi/commit/5c99601b07aec1a65d0186a4c4327440811e64c6)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([01546a0](https://github.com/Ombi-app/Ombi/commit/01546a0f7f86379528b486463246ef9bdfb9033e)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([d7fea78](https://github.com/Ombi-app/Ombi/commit/d7fea7843aaaab7ddff8dc31ca6d2a9117471dcc)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([1a6b95d](https://github.com/Ombi-app/Ombi/commit/1a6b95d45c220310213b8d811272a63f0f6ff42b)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([fa10174](https://github.com/Ombi-app/Ombi/commit/fa1017422c4efd4b0897871bd3c671151774d7c3)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([0c31e62](https://github.com/Ombi-app/Ombi/commit/0c31e628df376aac6d56ae67c7c705a9a4a7c080)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([6399643](https://github.com/Ombi-app/Ombi/commit/63996437a02fe10ffae6822ffa15369bec0a6b36)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([5826e2d](https://github.com/Ombi-app/Ombi/commit/5826e2d9a1c3f1210a87fa270dc0c81bac32944a)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([d434514](https://github.com/Ombi-app/Ombi/commit/d43451405be489254d7cdc7755d5f516a1e495a5)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([0b9596d](https://github.com/Ombi-app/Ombi/commit/0b9596d807178f5e071113ec0347868ec7f0960b)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([8c4c0b2](https://github.com/Ombi-app/Ombi/commit/8c4c0b262978c1303767af360d802c4b4c2b4d24)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([289ab77](https://github.com/Ombi-app/Ombi/commit/289ab77b0e04aae235b6f6cebc86e0a8d1f0cf2b)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([30e3417](https://github.com/Ombi-app/Ombi/commit/30e3417285a4eed18d429d7776f0e74096e834c0)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([6c0a5da](https://github.com/Ombi-app/Ombi/commit/6c0a5dadd4b8f37760252eb0fe7f88908f55506d)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([d5bf969](https://github.com/Ombi-app/Ombi/commit/d5bf9692ce1fc0ccfe7beca6dd200c78be177bdc)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([8a9e7ea](https://github.com/Ombi-app/Ombi/commit/8a9e7ea588aefbcd73ed82625887e3614e1703ea)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([01047a3](https://github.com/Ombi-app/Ombi/commit/01047a3fd67153f3ff16f860d2c7b50213e8d9b2)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([698a23f](https://github.com/Ombi-app/Ombi/commit/698a23fb83f323cdd1dd57cb49803079d44214a7)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([24eb842](https://github.com/Ombi-app/Ombi/commit/24eb842fc4424f7bcc3ec2949d7f5472492e96f6)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([ac8b16a](https://github.com/Ombi-app/Ombi/commit/ac8b16a3051ad71dbd54a8973c7dd847b564a515)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([f428ce6](https://github.com/Ombi-app/Ombi/commit/f428ce6a700c081437703839bc84d2f2b1138bcc)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([94b16df](https://github.com/Ombi-app/Ombi/commit/94b16dfe09bf1d2cd6286777d74eb5d4496abbbb)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([4881775](https://github.com/Ombi-app/Ombi/commit/4881775eda69a8f136ce0d8fbbf970e3d0406dc9)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([8297db9](https://github.com/Ombi-app/Ombi/commit/8297db91e85da308bde6fb09ad78347dee063630)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([d1152ab](https://github.com/Ombi-app/Ombi/commit/d1152ab7674243daa528c524c0cdc87d81ad49c9)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([eb2788b](https://github.com/Ombi-app/Ombi/commit/eb2788b761b55c487a59a049427ca08f6c10e836)) +* **translations:** 🌐 New translations from Crowdin [skip ci] ([21a794c](https://github.com/Ombi-app/Ombi/commit/21a794cbc0a5fa735ca0347c8f7f1ac04a487fbc)) + + + +## [4.10.2](https://github.com/Ombi-app/Ombi/compare/v4.10.1...v4.10.2) (2022-01-22) + + + +## [4.16.10](https://github.com/Ombi-app/Ombi/compare/v4.16.9...v4.16.10) (2022-04-13) + + + +## [4.16.9](https://github.com/Ombi-app/Ombi/compare/v4.16.8...v4.16.9) (2022-04-13) + + +### Bug Fixes + +* **plex-watchlist:** Only request the latest season when importing from the watchlist ([77a47ff](https://github.com/Ombi-app/Ombi/commit/77a47ff157c6c5feafe3f2a29a3fcba8df4fdfef)) + + + +## [4.16.8](https://github.com/Ombi-app/Ombi/compare/v4.16.7...v4.16.8) (2022-04-13) + + +### Bug Fixes + +* **availability:** Fixed an issue where we wouldn't mark a available 4k movie as available (when 4K request feature is disabled) ([b492699](https://github.com/Ombi-app/Ombi/commit/b49269961d4830a530e3054976a47f519524948b)) + + + +## [4.16.7](https://github.com/Ombi-app/Ombi/compare/v4.16.6...v4.16.7) (2022-04-12) + + + +## [4.16.6](https://github.com/Ombi-app/Ombi/compare/v4.16.5...v4.16.6) (2022-04-11) + + + +## [4.16.5](https://github.com/Ombi-app/Ombi/compare/v4.16.4...v4.16.5) (2022-04-08) + + +### Bug Fixes + +* **watchlist:** actually fixed it this time... ([d962a32](https://github.com/Ombi-app/Ombi/commit/d962a3211eca29520662ddce962676e3aea17ec5)) + + + +## [4.16.4](https://github.com/Ombi-app/Ombi/compare/v4.16.3...v4.16.4) (2022-04-08) + + + +## [4.16.3](https://github.com/Ombi-app/Ombi/compare/v4.16.2...v4.16.3) (2022-04-08) + + +### Bug Fixes + +* **plex-watchlist:** :bug: Fixed the issue where the watchlist didn't work for users logging in via OAuth ([6398f6a](https://github.com/Ombi-app/Ombi/commit/6398f6a4f7755281ebeac537e3ff623df5cfa0f3)) + + + +## [4.16.2](https://github.com/Ombi-app/Ombi/compare/v4.16.1...v4.16.2) (2022-04-07) + + +### Bug Fixes + +* **wizard:** Fixed an issue when using Plex OAuth it could fail setting up ([b743cf4](https://github.com/Ombi-app/Ombi/commit/b743cf4fafa7341ad1b163276f006d7ab0e9dcff)) + + + +## [4.16.1](https://github.com/Ombi-app/Ombi/compare/v4.16.0...v4.16.1) (2022-04-07) + + + +# [4.16.0](https://github.com/Ombi-app/Ombi/compare/v4.15.6...v4.16.0) (2022-04-07) + + + +## [4.15.6](https://github.com/Ombi-app/Ombi/compare/v4.15.5...v4.15.6) (2022-04-07) + + +### Bug Fixes + +* **radarr:** Fixed an issue where we couldn't sync radarr content [#4577](https://github.com/Ombi-app/Ombi/issues/4577) ([a5355a3](https://github.com/Ombi-app/Ombi/commit/a5355a3023e6900c4dd1b0da4722d7596c03907f)) + + + +## [4.15.5](https://github.com/Ombi-app/Ombi/compare/v4.15.4...v4.15.5) (2022-04-06) + + + +## [4.15.4](https://github.com/Ombi-app/Ombi/compare/v4.15.3...v4.15.4) (2022-03-29) + + + +## [4.15.3](https://github.com/Ombi-app/Ombi/compare/v4.15.2...v4.15.3) (2022-03-24) + + + +## [4.15.2](https://github.com/Ombi-app/Ombi/compare/v4.15.1...v4.15.2) (2022-03-23) + + +### Bug Fixes + +* **metadata:** improved the metadata job to also lookup the media in Plex to see if it has any more uptodate metadata ([83d1a15](https://github.com/Ombi-app/Ombi/commit/83d1a15cc9d0ee91be73bd91c4672cf1bcf2728a)) + + + +## [4.15.1](https://github.com/Ombi-app/Ombi/compare/v4.15.0...v4.15.1) (2022-03-18) + + +### Bug Fixes + +* **mediaserver:** fixed an issue where we were not detecting available content correctly [#4542](https://github.com/Ombi-app/Ombi/issues/4542) ([9cdd6f4](https://github.com/Ombi-app/Ombi/commit/9cdd6f41cdab8825a984905c089611409c53c753)) diff --git a/README.md b/README.md index 636c58c3e..f7b2e58ff 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,7 @@ Don't worry, it's grandma friendly, and more importantly; has wife approval cert | Service | Stable | Develop |----------|:---------------------------:|:----------------------------:| -| Build Status | [![CI Build](https://github.com/Ombi-app/Ombi/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/Ombi-app/Ombi/actions/workflows/build.yml) | [![CI Build](https://github.com/Ombi-app/Ombi/actions/workflows/build.yml/badge.svg)](https://github.com/Ombi-app/Ombi/actions/workflows/build.yml) | [![Build Status](https://dev.azure.com/tidusjar/Ombi/_apis/build/status/Ombi%20CI?branchName=feature%2Fv4)](https://dev.azure.com/tidusjar/Ombi/_build/latest?definitionId=18&branchName=feature%2Fv4) +| Build Status | [![CI Build](https://github.com/Ombi-app/Ombi/actions/workflows/build.yml/badge.svg?branch=master)](https://github.com/Ombi-app/Ombi/actions/workflows/build.yml) | [![CI Build](https://github.com/Ombi-app/Ombi/actions/workflows/build.yml/badge.svg?branch=develop)](https://github.com/Ombi-app/Ombi/actions/workflows/build.yml) | [![Build Status](https://dev.azure.com/tidusjar/Ombi/_apis/build/status/Ombi%20CI?branchName=feature%2Fv4)](https://dev.azure.com/tidusjar/Ombi/_build/latest?definitionId=18&branchName=feature%2Fv4) | Download |[![Download](https://img.shields.io/badge/-Download-blue)](https://github.com/Ombi-app/Ombi/releases) | [![Download](https://img.shields.io/badge/-Download-blue)](https://ci.appveyor.com/project/tidusjar/requestplex/branch/develop/artifacts) | [![Download](https://img.shields.io/badge/-Download-blue)](https://github.com/ombi-app/ombi/releases) | # Feature Requests @@ -99,21 +99,28 @@ Here are some of the features Ombi has: Drew + + + sephrat +
+ Sephrat +
+ anojht
Anojh Thayaparan
- + + Magikarplvl4
Magikarp Lvl 4
- - + MrTopCat @@ -148,15 +155,15 @@ Here are some of the features Ombi has:
Dhruv Bhavsar
- + + joshuaboniface
Joshua M. Boniface
- - + bruvv @@ -164,13 +171,6 @@ Here are some of the features Ombi has: Bruvv - - - sephrat -
- Sephrat -
- louis-lau @@ -222,10 +222,10 @@ Here are some of the features Ombi has: - - stefangross + + grimsan55
- Stefangross + Stefan
@@ -243,6 +243,13 @@ Here are some of the features Ombi has: + + + fservida +
+ Francesco Servida +
+ Patricol @@ -277,6 +284,14 @@ Here are some of the features Ombi has:
Aptalca
+ + + + + dr3am37 +
+ Dr3amer +
@@ -284,8 +299,7 @@ Here are some of the features Ombi has:
Mhann
- - + ombi-bot @@ -313,7 +327,8 @@ Here are some of the features Ombi has:
Austin Jackson
- + + D34DC3N73R @@ -327,8 +342,7 @@ Here are some of the features Ombi has:
David Pooley
- - + Fredrik81 @@ -356,7 +370,8 @@ Here are some of the features Ombi has:
Jeffrey Peters
- + + MariusSchiffer @@ -370,8 +385,7 @@ Here are some of the features Ombi has:
Qstick
- - + Vbgf @@ -399,7 +413,8 @@ Here are some of the features Ombi has:
Abe Kline
- + + XanderStrike @@ -413,8 +428,7 @@ Here are some of the features Ombi has:
Aljosa Asanovic
- - + Ashyni @@ -442,7 +456,8 @@ Here are some of the features Ombi has:
Chris Lees
- + + cdemi @@ -456,8 +471,7 @@ Here are some of the features Ombi has:
Codehhh
- - + danopia @@ -485,7 +499,8 @@ Here are some of the features Ombi has:
Devin Buhl
- + + elisspace @@ -499,8 +514,7 @@ Here are some of the features Ombi has:
Fish2
- - + hariesramdhani @@ -508,6 +522,13 @@ Here are some of the features Ombi has: Haries Ramdhani + + + comigor +
+ Igor Borges +
+ ImgBotApp @@ -521,7 +542,8 @@ Here are some of the features Ombi has:
Jacob Pyke
- + + jamesmacwhite @@ -542,8 +564,7 @@ Here are some of the features Ombi has:
Joe Harvey
- - + jonbloom @@ -564,7 +585,8 @@ Here are some of the features Ombi has:
Kris Klosterman
- + + kmlucy @@ -579,20 +601,41 @@ Here are some of the features Ombi has: Lightkeeper + + + Lucane +
+ Lucane +
+ devbymadde
Madeleine Schönemann
- - + + + + marleypowell +
+ Marley +
+ mattmattmatt
Matt
+ + + + + LMaxence +
+ Maxence Lecanu +
@@ -608,6 +651,13 @@ Here are some of the features Ombi has: Nathan Miller + + + cqxmzz +
+ Qiming Chen +
+ randallbruder @@ -621,15 +671,15 @@ Here are some of the features Ombi has:
Rob Gökemeijer
- + + sambartik
Samuel Bartík
- - + seancallinan @@ -644,6 +694,13 @@ Here are some of the features Ombi has: Shoghi + + + Teifun2 +
+ Teifun2 +
+ thomasvt1 @@ -657,7 +714,8 @@ Here are some of the features Ombi has:
Tim Trott
- + + tombomb @@ -671,8 +729,7 @@ Here are some of the features Ombi has:
Torkil
- - + bybeet @@ -700,7 +757,8 @@ Here are some of the features Ombi has:
Blake Drumm
- + + camjac251 @@ -714,8 +772,7 @@ Here are some of the features Ombi has:
Michael DiStaula
- - + baikunz @@ -723,6 +780,13 @@ Here are some of the features Ombi has: Dorian ALKOUM + + + echel0n +
+ Echel0n +
+ m4tta @@ -730,6 +794,14 @@ Here are some of the features Ombi has: M4tta + + + maartenheebink +
+ Maartenheebink +
+ + masterhuck @@ -757,8 +829,7 @@ Here are some of the features Ombi has:
Mike
- - + zobe123 diff --git a/crowdin.yml b/crowdin.yml index b7f48ef88..170fc200d 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,10 +1,10 @@ - commit_message: "fix(translations): 🌐 New translations from Crowdin [skip ci]" append_commit_message: false pull_request_title: "🌐 Translations Update" pull_request_labels: - translations - files: - source: /src/Ombi/wwwroot/translations/en.json translation: /src/Ombi/wwwroot/translations/%two_letters_code%.json + - source: /src/Ombi.I18n/Resources/Texts.resx + translation: /src/Ombi.I18n/Resources/Texts.%two_letters_code%.resx diff --git a/makefile b/makefile new file mode 100644 index 000000000..62c11e5b5 --- /dev/null +++ b/makefile @@ -0,0 +1,17 @@ +backend: + cd src/Ombi && dotnet watch run -- --host http://*:3577 + +frontend: + cd src/Ombi/ClientApp && yarn start + +install-frontend: + cd src/Ombi/ClientApp && yarn + +install-frontend-tests: + cd tests && yarn + +frontend-tests: + cd tests && npx cypress run + +backend-tests: + cd src/Ombi.Core.Tests && dotnet test \ No newline at end of file diff --git a/src/.idea/.idea.Ombi/.idea/contentModel.xml b/src/.idea/.idea.Ombi/.idea/contentModel.xml index 4affa7aee..438274536 100644 --- a/src/.idea/.idea.Ombi/.idea/contentModel.xml +++ b/src/.idea/.idea.Ombi/.idea/contentModel.xml @@ -929,7 +929,7 @@ - + @@ -1876,7 +1876,7 @@ - + diff --git a/src/Ombi.Api.CloudService/Ombi.Api.CloudService.csproj b/src/Ombi.Api.CloudService/Ombi.Api.CloudService.csproj index 0701967d1..5939549de 100644 --- a/src/Ombi.Api.CloudService/Ombi.Api.CloudService.csproj +++ b/src/Ombi.Api.CloudService/Ombi.Api.CloudService.csproj @@ -1,7 +1,7 @@  - net5.0 + net6.0 Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.CouchPotato/Ombi.Api.CouchPotato.csproj b/src/Ombi.Api.CouchPotato/Ombi.Api.CouchPotato.csproj index 320c51076..89c47d251 100644 --- a/src/Ombi.Api.CouchPotato/Ombi.Api.CouchPotato.csproj +++ b/src/Ombi.Api.CouchPotato/Ombi.Api.CouchPotato.csproj @@ -1,8 +1,8 @@  - net5.0 - 8.0 + net6.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Discord/Ombi.Api.Discord.csproj b/src/Ombi.Api.Discord/Ombi.Api.Discord.csproj index 20c8a9aef..70032d638 100644 --- a/src/Ombi.Api.Discord/Ombi.Api.Discord.csproj +++ b/src/Ombi.Api.Discord/Ombi.Api.Discord.csproj @@ -1,12 +1,12 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.DogNzb/Ombi.Api.DogNzb.csproj b/src/Ombi.Api.DogNzb/Ombi.Api.DogNzb.csproj index 320c51076..89c47d251 100644 --- a/src/Ombi.Api.DogNzb/Ombi.Api.DogNzb.csproj +++ b/src/Ombi.Api.DogNzb/Ombi.Api.DogNzb.csproj @@ -1,8 +1,8 @@  - net5.0 - 8.0 + net6.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Emby/EmbyApi.cs b/src/Ombi.Api.Emby/EmbyApi.cs index c413ecded..e9e5f0fca 100644 --- a/src/Ombi.Api.Emby/EmbyApi.cs +++ b/src/Ombi.Api.Emby/EmbyApi.cs @@ -1,12 +1,8 @@ -using System; -using System.Collections.Generic; -using System.Linq; +using System.Collections.Generic; using System.Net.Http; using System.Threading.Tasks; -using Microsoft.EntityFrameworkCore.Internal; using Newtonsoft.Json; using Ombi.Api.Emby.Models; -using Ombi.Api.Emby.Models.Media; using Ombi.Api.Emby.Models.Media.Tv; using Ombi.Api.Emby.Models.Movie; using Ombi.Helpers; @@ -110,7 +106,7 @@ namespace Ombi.Api.Emby request.AddQueryString("Fields", "ProviderIds,Overview"); - request.AddQueryString("IsVirtualItem", "False"); + request.AddQueryString("IsMissing", "False"); return await Api.Request>(request); } @@ -124,22 +120,36 @@ namespace Ombi.Api.Emby return response; } - public async Task> GetAllMovies(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri) { return await GetAll("Movie", apiKey, userId, baseUri, true, startIndex, count, parentIdFilder); } + public async Task> RecentlyAddedMovies(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri) + { + return await RecentlyAdded("Movie", apiKey, userId, baseUri, true, startIndex, count, parentIdFilder); + } + public async Task> GetAllEpisodes(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri) { return await GetAll("Episode", apiKey, userId, baseUri, false, startIndex, count, parentIdFilder); } + public async Task> RecentlyAddedEpisodes(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri) + { + return await RecentlyAdded("Episode", apiKey, userId, baseUri, false, startIndex, count, parentIdFilder); + } + public async Task> GetAllShows(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri) { return await GetAll("Series", apiKey, userId, baseUri, false, startIndex, count, parentIdFilder); } + public async Task> RecentlyAddedShows(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri) + { + return await RecentlyAdded("Series", apiKey, userId, baseUri, false, startIndex, count, parentIdFilder); + } + public async Task GetSeriesInformation(string mediaId, string apiKey, string userId, string baseUrl) { return await GetInformation(mediaId, apiKey, userId, baseUrl); @@ -154,6 +164,31 @@ namespace Ombi.Api.Emby return await GetInformation(mediaId, apiKey, userId, baseUrl); } + private async Task> RecentlyAdded(string type, string apiKey, string userId, string baseUri, bool includeOverview, int startIndex, int count, string parentIdFilder = default) + { + var request = new Request($"emby/users/{userId}/items", baseUri, HttpMethod.Get); + + request.AddQueryString("Recursive", true.ToString()); + request.AddQueryString("IncludeItemTypes", type); + request.AddQueryString("Fields", includeOverview ? "ProviderIds,MediaStreams,Overview" : "ProviderIds,MediaStreams "); + request.AddQueryString("startIndex", startIndex.ToString()); + request.AddQueryString("limit", count.ToString()); + request.AddQueryString("sortBy", "DateCreated"); + request.AddQueryString("SortOrder", "Descending"); + if (!string.IsNullOrEmpty(parentIdFilder)) + { + request.AddQueryString("ParentId", parentIdFilder); + } + + request.AddQueryString("IsMissing", "False"); + + AddHeaders(request, apiKey); + + + var obj = await Api.Request>(request); + return obj; + } + private async Task GetInformation(string mediaId, string apiKey, string userId, string baseUrl) { var request = new Request($"emby/users/{userId}/items/{mediaId}", baseUrl, HttpMethod.Get); @@ -172,7 +207,7 @@ namespace Ombi.Api.Emby request.AddQueryString("IncludeItemTypes", type); request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview" : "ProviderIds"); - request.AddQueryString("IsVirtualItem", "False"); + request.AddQueryString("IsMissing", "False"); AddHeaders(request, apiKey); @@ -186,7 +221,7 @@ namespace Ombi.Api.Emby request.AddQueryString("Recursive", true.ToString()); request.AddQueryString("IncludeItemTypes", type); - request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview" : "ProviderIds"); + request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview,MediaStreams" : "ProviderIds,MediaStreams"); request.AddQueryString("startIndex", startIndex.ToString()); request.AddQueryString("limit", count.ToString()); if (!string.IsNullOrEmpty(parentIdFilder)) @@ -194,7 +229,7 @@ namespace Ombi.Api.Emby request.AddQueryString("ParentId", parentIdFilder); } - request.AddQueryString("IsVirtualItem", "False"); + request.AddQueryString("isMissing", "False"); AddHeaders(request, apiKey); diff --git a/src/Ombi.Api.Emby/IBaseEmbyApi.cs b/src/Ombi.Api.Emby/IBaseEmbyApi.cs index 4de81073d..248c0a88f 100644 --- a/src/Ombi.Api.Emby/IBaseEmbyApi.cs +++ b/src/Ombi.Api.Emby/IBaseEmbyApi.cs @@ -29,5 +29,8 @@ namespace Ombi.Api.Emby Task GetMovieInformation(string mediaId, string apiKey, string userId, string baseUrl); Task GetEpisodeInformation(string mediaId, string apiKey, string userId, string baseUrl); Task GetPublicInformation(string baseUrl); + Task> RecentlyAddedMovies(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri); + Task> RecentlyAddedEpisodes(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri); + Task> RecentlyAddedShows(string apiKey, string parentIdFilder, int startIndex, int count, string userId, string baseUri); } } \ No newline at end of file diff --git a/src/Ombi.Api.Emby/Models/EmbyMediaType.cs b/src/Ombi.Api.Emby/Models/EmbyMediaType.cs deleted file mode 100644 index 7b33f8972..000000000 --- a/src/Ombi.Api.Emby/Models/EmbyMediaType.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ombi.Api.Emby.Models -{ - public enum EmbyMediaType - { - Movie = 0, - Series = 1, - Music = 2, - Episode = 3 - } -} \ No newline at end of file diff --git a/src/Ombi.Api.Emby/Models/Media/EmbyMediastream.cs b/src/Ombi.Api.Emby/Models/Media/EmbyMediastream.cs index 01032e0e7..f633f4ce0 100644 --- a/src/Ombi.Api.Emby/Models/Media/EmbyMediastream.cs +++ b/src/Ombi.Api.Emby/Models/Media/EmbyMediastream.cs @@ -2,35 +2,6 @@ namespace Ombi.Api.Emby.Models.Movie { public class EmbyMediastream { - public string Codec { get; set; } - public string Language { get; set; } - public string TimeBase { get; set; } - public string CodecTimeBase { get; set; } - public string NalLengthSize { get; set; } - public bool IsInterlaced { get; set; } - public bool IsAVC { get; set; } - public int BitRate { get; set; } - public int BitDepth { get; set; } - public int RefFrames { get; set; } - public bool IsDefault { get; set; } - public bool IsForced { get; set; } - public int Height { get; set; } - public int Width { get; set; } - public float AverageFrameRate { get; set; } - public float RealFrameRate { get; set; } - public string Profile { get; set; } - public string Type { get; set; } - public string AspectRatio { get; set; } - public int Index { get; set; } - public bool IsExternal { get; set; } - public bool IsTextSubtitleStream { get; set; } - public bool SupportsExternalStream { get; set; } - public string PixelFormat { get; set; } - public int Level { get; set; } - public bool IsAnamorphic { get; set; } public string DisplayTitle { get; set; } - public string ChannelLayout { get; set; } - public int Channels { get; set; } - public int SampleRate { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Api.Emby/Models/Media/EmbyProviderids.cs b/src/Ombi.Api.Emby/Models/Media/EmbyProviderids.cs index 8302ee3ee..4a19025de 100644 --- a/src/Ombi.Api.Emby/Models/Media/EmbyProviderids.cs +++ b/src/Ombi.Api.Emby/Models/Media/EmbyProviderids.cs @@ -1,12 +1,10 @@ -namespace Ombi.Api.Emby.Models.Movie -{ - public class EmbyProviderids - { - public string Tmdb { get; set; } - public string Imdb { get; set; } - public string TmdbCollection { get; set; } +using Ombi.Api.MediaServer.Models; - public string Tvdb { get; set; } +namespace Ombi.Api.Emby.Models.Movie +{ + public class EmbyProviderids: BaseProviderids + { + public string TmdbCollection { get; set; } public string Zap2It { get; set; } public string TvRage { get; set; } } diff --git a/src/Ombi.Api.Emby/Models/Media/Movie/EmbyMovie.cs b/src/Ombi.Api.Emby/Models/Media/Movie/EmbyMovie.cs index a10ddaae6..e127f75f6 100644 --- a/src/Ombi.Api.Emby/Models/Media/Movie/EmbyMovie.cs +++ b/src/Ombi.Api.Emby/Models/Media/Movie/EmbyMovie.cs @@ -30,5 +30,6 @@ namespace Ombi.Api.Emby.Models.Movie public int CriticRating { get; set; } public string Overview { get; set; } public EmbyProviderids ProviderIds { get; set; } + public EmbyMediastream[] MediaStreams { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Api.Emby/Ombi.Api.Emby.csproj b/src/Ombi.Api.Emby/Ombi.Api.Emby.csproj index 3008c9230..f60971192 100644 --- a/src/Ombi.Api.Emby/Ombi.Api.Emby.csproj +++ b/src/Ombi.Api.Emby/Ombi.Api.Emby.csproj @@ -1,17 +1,18 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild + diff --git a/src/Ombi.Api.FanartTv/Ombi.Api.FanartTv.csproj b/src/Ombi.Api.FanartTv/Ombi.Api.FanartTv.csproj index 20c8a9aef..70032d638 100644 --- a/src/Ombi.Api.FanartTv/Ombi.Api.FanartTv.csproj +++ b/src/Ombi.Api.FanartTv/Ombi.Api.FanartTv.csproj @@ -1,12 +1,12 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Github/Ombi.Api.Github.csproj b/src/Ombi.Api.Github/Ombi.Api.Github.csproj index 320c51076..89c47d251 100644 --- a/src/Ombi.Api.Github/Ombi.Api.Github.csproj +++ b/src/Ombi.Api.Github/Ombi.Api.Github.csproj @@ -1,8 +1,8 @@  - net5.0 - 8.0 + net6.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Gotify/Ombi.Api.Gotify.csproj b/src/Ombi.Api.Gotify/Ombi.Api.Gotify.csproj index 7065a1e65..be32916f8 100644 --- a/src/Ombi.Api.Gotify/Ombi.Api.Gotify.csproj +++ b/src/Ombi.Api.Gotify/Ombi.Api.Gotify.csproj @@ -1,12 +1,12 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.GroupMe/Ombi.Api.GroupMe.csproj b/src/Ombi.Api.GroupMe/Ombi.Api.GroupMe.csproj index 320c51076..89c47d251 100644 --- a/src/Ombi.Api.GroupMe/Ombi.Api.GroupMe.csproj +++ b/src/Ombi.Api.GroupMe/Ombi.Api.GroupMe.csproj @@ -1,8 +1,8 @@  - net5.0 - 8.0 + net6.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Jellyfin/JellyfinApi.cs b/src/Ombi.Api.Jellyfin/JellyfinApi.cs index 2fafbfd86..0604cb984 100644 --- a/src/Ombi.Api.Jellyfin/JellyfinApi.cs +++ b/src/Ombi.Api.Jellyfin/JellyfinApi.cs @@ -82,7 +82,7 @@ namespace Ombi.Api.Jellyfin request.AddQueryString("Fields", "ProviderIds,Overview"); - request.AddQueryString("IsVirtualItem", "False"); + request.AddQueryString("isMissing", "False"); return await Api.Request>(request); } @@ -143,7 +143,7 @@ namespace Ombi.Api.Jellyfin request.AddQueryString("IncludeItemTypes", type); request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview" : "ProviderIds"); - request.AddQueryString("IsVirtualItem", "False"); + request.AddQueryString("isMissing", "False"); AddHeaders(request, apiKey); @@ -157,7 +157,7 @@ namespace Ombi.Api.Jellyfin request.AddQueryString("Recursive", true.ToString()); request.AddQueryString("IncludeItemTypes", type); - request.AddQueryString("Fields", includeOverview ? "ProviderIds,Overview,ParentId" : "ProviderIds,ParentId"); + request.AddQueryString("Fields", includeOverview ? "ProviderIds,MediaStreams Overview,ParentId" : "ProviderIds,ParentId,MediaStreams"); request.AddQueryString("startIndex", startIndex.ToString()); request.AddQueryString("limit", count.ToString()); if(!string.IsNullOrEmpty(parentIdFilder)) @@ -165,7 +165,7 @@ namespace Ombi.Api.Jellyfin request.AddQueryString("ParentId", parentIdFilder); } - request.AddQueryString("IsVirtualItem", "False"); + request.AddQueryString("isMissing", "False"); AddHeaders(request, apiKey); diff --git a/src/Ombi.Api.Jellyfin/Models/JellyfinMediaType.cs b/src/Ombi.Api.Jellyfin/Models/JellyfinMediaType.cs deleted file mode 100644 index 2c4f75be0..000000000 --- a/src/Ombi.Api.Jellyfin/Models/JellyfinMediaType.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace Ombi.Api.Jellyfin.Models -{ - public enum JellyfinMediaType - { - Movie = 0, - Series = 1, - Music = 2, - Episode = 3 - } -} \ No newline at end of file diff --git a/src/Ombi.Api.Jellyfin/Models/Media/JellyfinMediastream.cs b/src/Ombi.Api.Jellyfin/Models/Media/JellyfinMediastream.cs index 89da2651a..e15a21e7b 100644 --- a/src/Ombi.Api.Jellyfin/Models/Media/JellyfinMediastream.cs +++ b/src/Ombi.Api.Jellyfin/Models/Media/JellyfinMediastream.cs @@ -2,35 +2,6 @@ namespace Ombi.Api.Jellyfin.Models.Movie { public class JellyfinMediastream { - public string Codec { get; set; } - public string Language { get; set; } - public string TimeBase { get; set; } - public string CodecTimeBase { get; set; } - public string NalLengthSize { get; set; } - public bool IsInterlaced { get; set; } - public bool IsAVC { get; set; } - public int BitRate { get; set; } - public int BitDepth { get; set; } - public int RefFrames { get; set; } - public bool IsDefault { get; set; } - public bool IsForced { get; set; } - public int Height { get; set; } - public int Width { get; set; } - public float AverageFrameRate { get; set; } - public float RealFrameRate { get; set; } - public string Profile { get; set; } - public string Type { get; set; } - public string AspectRatio { get; set; } - public int Index { get; set; } - public bool IsExternal { get; set; } - public bool IsTextSubtitleStream { get; set; } - public bool SupportsExternalStream { get; set; } - public string PixelFormat { get; set; } - public int Level { get; set; } - public bool IsAnamorphic { get; set; } public string DisplayTitle { get; set; } - public string ChannelLayout { get; set; } - public int Channels { get; set; } - public int SampleRate { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Api.Jellyfin/Models/Media/JellyfinProviderids.cs b/src/Ombi.Api.Jellyfin/Models/Media/JellyfinProviderids.cs index 9b47f9a1a..0896ec4e9 100644 --- a/src/Ombi.Api.Jellyfin/Models/Media/JellyfinProviderids.cs +++ b/src/Ombi.Api.Jellyfin/Models/Media/JellyfinProviderids.cs @@ -1,12 +1,10 @@ -namespace Ombi.Api.Jellyfin.Models.Movie -{ - public class JellyfinProviderids - { - public string Tmdb { get; set; } - public string Imdb { get; set; } - public string TmdbCollection { get; set; } +using Ombi.Api.MediaServer.Models; - public string Tvdb { get; set; } +namespace Ombi.Api.Jellyfin.Models.Movie +{ + public class JellyfinProviderids: BaseProviderids + { + public string TmdbCollection { get; set; } public string Zap2It { get; set; } public string TvRage { get; set; } } diff --git a/src/Ombi.Api.Jellyfin/Models/Media/Movie/JellyfinMovie.cs b/src/Ombi.Api.Jellyfin/Models/Media/Movie/JellyfinMovie.cs index d86bf5047..a83e1f087 100644 --- a/src/Ombi.Api.Jellyfin/Models/Media/Movie/JellyfinMovie.cs +++ b/src/Ombi.Api.Jellyfin/Models/Media/Movie/JellyfinMovie.cs @@ -30,5 +30,6 @@ namespace Ombi.Api.Jellyfin.Models.Movie public int CriticRating { get; set; } public string Overview { get; set; } public JellyfinProviderids ProviderIds { get; set; } + public JellyfinMediastream[] MediaStreams { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Api.Jellyfin/Ombi.Api.Jellyfin.csproj b/src/Ombi.Api.Jellyfin/Ombi.Api.Jellyfin.csproj index 3008c9230..0c745556e 100644 --- a/src/Ombi.Api.Jellyfin/Ombi.Api.Jellyfin.csproj +++ b/src/Ombi.Api.Jellyfin/Ombi.Api.Jellyfin.csproj @@ -1,18 +1,19 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild + \ No newline at end of file diff --git a/src/Ombi.Api.Lidarr/Ombi.Api.Lidarr.csproj b/src/Ombi.Api.Lidarr/Ombi.Api.Lidarr.csproj index 320c51076..89c47d251 100644 --- a/src/Ombi.Api.Lidarr/Ombi.Api.Lidarr.csproj +++ b/src/Ombi.Api.Lidarr/Ombi.Api.Lidarr.csproj @@ -1,8 +1,8 @@  - net5.0 - 8.0 + net6.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Mattermost/Ombi.Api.Mattermost.csproj b/src/Ombi.Api.Mattermost/Ombi.Api.Mattermost.csproj index 5742fd3a5..16c3a8558 100644 --- a/src/Ombi.Api.Mattermost/Ombi.Api.Mattermost.csproj +++ b/src/Ombi.Api.Mattermost/Ombi.Api.Mattermost.csproj @@ -1,12 +1,12 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.MediaServer/Models/BaseProviderids.cs b/src/Ombi.Api.MediaServer/Models/BaseProviderids.cs new file mode 100644 index 000000000..6044288c6 --- /dev/null +++ b/src/Ombi.Api.MediaServer/Models/BaseProviderids.cs @@ -0,0 +1,11 @@ +namespace Ombi.Api.MediaServer.Models +{ + public class BaseProviderids + { + public string Tmdb { get; set; } + public string Imdb { get; set; } + public string Tvdb { get; set; } + public bool Any() => + !string.IsNullOrEmpty(Imdb) || !string.IsNullOrEmpty(Tmdb) || !string.IsNullOrEmpty(Tvdb); + } +} \ No newline at end of file diff --git a/src/Ombi.Api.MediaServer/Ombi.Api.MediaServer.csproj b/src/Ombi.Api.MediaServer/Ombi.Api.MediaServer.csproj new file mode 100644 index 000000000..a1b98b765 --- /dev/null +++ b/src/Ombi.Api.MediaServer/Ombi.Api.MediaServer.csproj @@ -0,0 +1,18 @@ + + + + net6.0 + 3.0.0.0 + 3.0.0.0 + + + latest + Debug;Release;NonUiBuild + + + + + + + + \ No newline at end of file diff --git a/src/Ombi.Api.MusicBrainz/Ombi.Api.MusicBrainz.csproj b/src/Ombi.Api.MusicBrainz/Ombi.Api.MusicBrainz.csproj index 65b4175d4..c8a78e491 100644 --- a/src/Ombi.Api.MusicBrainz/Ombi.Api.MusicBrainz.csproj +++ b/src/Ombi.Api.MusicBrainz/Ombi.Api.MusicBrainz.csproj @@ -1,8 +1,8 @@  - net5.0 - 8.0 + net6.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Notifications/Ombi.Api.Notifications.csproj b/src/Ombi.Api.Notifications/Ombi.Api.Notifications.csproj index 312aa49f2..6406ef9de 100644 --- a/src/Ombi.Api.Notifications/Ombi.Api.Notifications.csproj +++ b/src/Ombi.Api.Notifications/Ombi.Api.Notifications.csproj @@ -1,8 +1,8 @@  - net5.0 - 8.0 + net6.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Plex/IPlexApi.cs b/src/Ombi.Api.Plex/IPlexApi.cs index a4597765e..746c85b77 100644 --- a/src/Ombi.Api.Plex/IPlexApi.cs +++ b/src/Ombi.Api.Plex/IPlexApi.cs @@ -1,4 +1,5 @@ using System; +using System.Threading; using System.Threading.Tasks; using Ombi.Api.Plex.Models; using Ombi.Api.Plex.Models.Friends; @@ -16,9 +17,9 @@ namespace Ombi.Api.Plex Task GetServer(string authToken); Task GetLibrarySections(string authToken, string plexFullHost); Task GetLibrary(string authToken, string plexFullHost, string libraryId); - Task GetEpisodeMetaData(string authToken, string host, int ratingKey); - Task GetMetadata(string authToken, string plexFullHost, int itemId); - Task GetSeasons(string authToken, string plexFullHost, int ratingKey); + Task GetEpisodeMetaData(string authToken, string host, string ratingKey); + Task GetMetadata(string authToken, string plexFullHost, string itemId); + Task GetSeasons(string authToken, string plexFullHost, string ratingKey); Task GetAllEpisodes(string authToken, string host, string section, int start, int retCount); Task GetUsers(string authToken); Task GetAccount(string authToken); @@ -26,5 +27,7 @@ namespace Ombi.Api.Plex Task GetPin(int pinId); Task GetOAuthUrl(string code, string applicationUrl); Task AddUser(string emailAddress, string serverId, string authToken, int[] libs); + Task GetWatchlist(string plexToken, CancellationToken cancellationToken); + Task GetWatchlistMetadata(string ratingKey, string plexToken, CancellationToken cancellationToken); } } \ No newline at end of file diff --git a/src/Ombi.Api.Plex/Models/Metadata.cs b/src/Ombi.Api.Plex/Models/Metadata.cs index d0bb227ad..97cab391b 100644 --- a/src/Ombi.Api.Plex/Models/Metadata.cs +++ b/src/Ombi.Api.Plex/Models/Metadata.cs @@ -1,10 +1,11 @@ using System.Collections.Generic; +using Newtonsoft.Json; namespace Ombi.Api.Plex.Models { public class Metadata { - public int ratingKey { get; set; } + public string ratingKey { get; set; } public string key { get; set; } public string studio { get; set; } public string type { get; set; } @@ -12,26 +13,18 @@ namespace Ombi.Api.Plex.Models public string contentRating { get; set; } public string summary { get; set; } public int index { get; set; } - public float rating { get; set; } - //public int viewCount { get; set; } - //public int lastViewedAt { get; set; } public int year { get; set; } public string thumb { get; set; } public string art { get; set; } public string banner { get; set; } public string theme { get; set; } - //public string duration { get; set; } - //public string originallyAvailableAt { get; set; } public int leafCount { get; set; } public int viewedLeafCount { get; set; } public int childCount { get; set; } - //public long addedAt { get; set; } - //public int updatedAt { get; set; } public Genre[] Genre { get; set; } - //public Role[] Role { get; set; } public string primaryExtraKey { get; set; } - public int parentRatingKey { get; set; } - public int grandparentRatingKey { get; set; } + public string parentRatingKey { get; set; } + public string grandparentRatingKey { get; set; } public string guid { get; set; } public int librarySectionID { get; set; } public string librarySectionKey { get; set; } @@ -47,12 +40,10 @@ namespace Ombi.Api.Plex.Models public string chapterSource { get; set; } public Medium[] Media { get; set; } public List Guid { get; set; } = new List(); - // public Director[] Director { get; set; } - // public Writer[] Writer { get; set; } } public class PlexGuids { public string Id { get; set; } } -} \ No newline at end of file +} diff --git a/src/Ombi.Api.Plex/Models/PlexWatchlist.cs b/src/Ombi.Api.Plex/Models/PlexWatchlist.cs new file mode 100644 index 000000000..52ca82cf9 --- /dev/null +++ b/src/Ombi.Api.Plex/Models/PlexWatchlist.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; + +namespace Ombi.Api.Plex.Models +{ + public class PlexWatchlist + { + public string librarySectionID { get; set; } + public string librarySectionTitle { get; set; } + public int offset { get; set; } + public int totalSize { get; set; } + public int size { get; set; } + public List Metadata { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/src/Ombi.Api.Plex/Models/PlexWatchlistContainer.cs b/src/Ombi.Api.Plex/Models/PlexWatchlistContainer.cs new file mode 100644 index 000000000..b208c189f --- /dev/null +++ b/src/Ombi.Api.Plex/Models/PlexWatchlistContainer.cs @@ -0,0 +1,9 @@ +using System.Collections.Generic; + +namespace Ombi.Api.Plex.Models +{ + public class PlexWatchlistContainer + { + public PlexWatchlist MediaContainer { get; set; } + } +} \ No newline at end of file diff --git a/src/Ombi.Api.Plex/Models/PlexWatchlistMetadataContainer.cs b/src/Ombi.Api.Plex/Models/PlexWatchlistMetadataContainer.cs new file mode 100644 index 000000000..b582ca4e1 --- /dev/null +++ b/src/Ombi.Api.Plex/Models/PlexWatchlistMetadataContainer.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; + +namespace Ombi.Api.Plex.Models +{ + public class PlexWatchlistMetadataContainer + { + public PlexWatchlistMetadata MediaContainer { get; set; } + } + + + public class PlexWatchlistMetadata + { + public int offset { get; set; } + public int totalSize { get; set; } + public string identifier { get; set; } + public int size { get; set; } + public WatchlistMetadata[] Metadata { get; set; } + } + + public class WatchlistMetadata + { + public string guid { get; set; } + public string key { get; set; } + public string primaryExtraKey { get; set; } + public string ratingKey { get; set; } + public string type { get; set; } + public string slug { get; set; } + public string title { get; set; } + public List Guid { get; set; } = new List(); + } +} \ No newline at end of file diff --git a/src/Ombi.Api.Plex/Ombi.Api.Plex.csproj b/src/Ombi.Api.Plex/Ombi.Api.Plex.csproj index 20c8a9aef..70032d638 100644 --- a/src/Ombi.Api.Plex/Ombi.Api.Plex.csproj +++ b/src/Ombi.Api.Plex/Ombi.Api.Plex.csproj @@ -1,12 +1,12 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Plex/PlexApi.cs b/src/Ombi.Api.Plex/PlexApi.cs index 176af31ec..9f91c540c 100644 --- a/src/Ombi.Api.Plex/PlexApi.cs +++ b/src/Ombi.Api.Plex/PlexApi.cs @@ -1,5 +1,6 @@ using System; using System.Net.Http; +using System.Threading; using System.Threading.Tasks; using Newtonsoft.Json; using Ombi.Api.Plex.Models; @@ -66,6 +67,7 @@ namespace Ombi.Api.Plex private const string FriendsUri = "https://plex.tv/pms/friends/all"; private const string GetAccountUri = "https://plex.tv/users/account.json"; private const string ServerUri = "https://plex.tv/pms/servers.xml"; + private const string WatchlistUri = "https://metadata.provider.plex.tv/"; /// /// Sign into the Plex API @@ -145,21 +147,21 @@ namespace Ombi.Api.Plex /// /// /// - public async Task GetEpisodeMetaData(string authToken, string plexFullHost, int ratingKey) + public async Task GetEpisodeMetaData(string authToken, string plexFullHost, string ratingKey) { var request = new Request($"/library/metadata/{ratingKey}", plexFullHost, HttpMethod.Get); await AddHeaders(request, authToken); return await Api.Request(request); } - public async Task GetMetadata(string authToken, string plexFullHost, int itemId) + public async Task GetMetadata(string authToken, string plexFullHost, string itemId) { var request = new Request($"library/metadata/{itemId}", plexFullHost, HttpMethod.Get); await AddHeaders(request, authToken); return await Api.Request(request); } - public async Task GetSeasons(string authToken, string plexFullHost, int ratingKey) + public async Task GetSeasons(string authToken, string plexFullHost, string ratingKey) { var request = new Request($"library/metadata/{ratingKey}/children", plexFullHost, HttpMethod.Get); await AddHeaders(request, authToken); @@ -288,6 +290,26 @@ namespace Ombi.Api.Plex } } + public async Task GetWatchlist(string plexToken, CancellationToken cancellationToken) + { + var request = new Request("library/sections/watchlist/all", WatchlistUri, HttpMethod.Get); + await AddHeaders(request, plexToken); + + var result = await Api.Request(request, cancellationToken); + + return result; + } + + public async Task GetWatchlistMetadata(string ratingKey, string plexToken, CancellationToken cancellationToken) + { + var request = new Request($"library/metadata/{ratingKey}", WatchlistUri, HttpMethod.Get); + await AddHeaders(request, plexToken); + + var result = await Api.Request(request, cancellationToken); + + return result; + } + /// /// Adds the required headers and also the authorization header diff --git a/src/Ombi.Api.Pushbullet/Ombi.Api.Pushbullet.csproj b/src/Ombi.Api.Pushbullet/Ombi.Api.Pushbullet.csproj index 20c8a9aef..70032d638 100644 --- a/src/Ombi.Api.Pushbullet/Ombi.Api.Pushbullet.csproj +++ b/src/Ombi.Api.Pushbullet/Ombi.Api.Pushbullet.csproj @@ -1,12 +1,12 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Pushover/Ombi.Api.Pushover.csproj b/src/Ombi.Api.Pushover/Ombi.Api.Pushover.csproj index 7065a1e65..be32916f8 100644 --- a/src/Ombi.Api.Pushover/Ombi.Api.Pushover.csproj +++ b/src/Ombi.Api.Pushover/Ombi.Api.Pushover.csproj @@ -1,12 +1,12 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Radarr/Models/V2/MovieResponse.cs b/src/Ombi.Api.Radarr/Models/V2/MovieResponse.cs index 6eb2f1c5a..f40dfcd80 100644 --- a/src/Ombi.Api.Radarr/Models/V2/MovieResponse.cs +++ b/src/Ombi.Api.Radarr/Models/V2/MovieResponse.cs @@ -44,7 +44,10 @@ namespace Ombi.Api.Radarr.Models public int id { get; set; } } - + public class MovieQuality + { + public V3.Quality quality { get; set; } + } public class Moviefile { public int movieId { get; set; } @@ -54,7 +57,7 @@ namespace Ombi.Api.Radarr.Models public DateTime dateAdded { get; set; } public string sceneName { get; set; } public int indexerFlags { get; set; } - public V3.Quality quality { get; set; } + public MovieQuality quality { get; set; } public Mediainfo mediaInfo { get; set; } public string originalFilePath { get; set; } public bool qualityCutoffNotMet { get; set; } @@ -74,13 +77,10 @@ namespace Ombi.Api.Radarr.Models public class Mediainfo { public string audioAdditionalFeatures { get; set; } - public int audioBitrate { get; set; } public float audioChannels { get; set; } public string audioCodec { get; set; } public string audioLanguages { get; set; } public int audioStreamCount { get; set; } - public int videoBitDepth { get; set; } - public int videoBitrate { get; set; } public string videoCodec { get; set; } public float videoFps { get; set; } public string resolution { get; set; } @@ -119,4 +119,4 @@ namespace Ombi.Api.Radarr.Models public int id { get; set; } public string name { get; set; } } -} \ No newline at end of file +} diff --git a/src/Ombi.Api.Radarr/Models/V3/RadarrV3QualityProfile.cs b/src/Ombi.Api.Radarr/Models/V3/RadarrV3QualityProfile.cs index d985da358..6eca4af87 100644 --- a/src/Ombi.Api.Radarr/Models/V3/RadarrV3QualityProfile.cs +++ b/src/Ombi.Api.Radarr/Models/V3/RadarrV3QualityProfile.cs @@ -25,5 +25,4 @@ public int resolution { get; set; } public string modifier { get; set; } } - } diff --git a/src/Ombi.Api.Radarr/Ombi.Api.Radarr.csproj b/src/Ombi.Api.Radarr/Ombi.Api.Radarr.csproj index c8ace891e..889aa0ea6 100644 --- a/src/Ombi.Api.Radarr/Ombi.Api.Radarr.csproj +++ b/src/Ombi.Api.Radarr/Ombi.Api.Radarr.csproj @@ -1,17 +1,17 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild - + diff --git a/src/Ombi.Api.RottenTomatoes/Ombi.Api.RottenTomatoes.csproj b/src/Ombi.Api.RottenTomatoes/Ombi.Api.RottenTomatoes.csproj index 795629ea6..89c47d251 100644 --- a/src/Ombi.Api.RottenTomatoes/Ombi.Api.RottenTomatoes.csproj +++ b/src/Ombi.Api.RottenTomatoes/Ombi.Api.RottenTomatoes.csproj @@ -1,8 +1,8 @@ - + - net5.0 - 8.0 + net6.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Service/Ombi.Api.Service.csproj b/src/Ombi.Api.Service/Ombi.Api.Service.csproj index 0b83f88e0..38bcd678a 100644 --- a/src/Ombi.Api.Service/Ombi.Api.Service.csproj +++ b/src/Ombi.Api.Service/Ombi.Api.Service.csproj @@ -1,19 +1,19 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 Ombi.Api.Service Ombi.Api.Service - 8.0 + latest Debug;Release;NonUiBuild - + diff --git a/src/Ombi.Api.SickRage/Models/SickRageEpisodeStatus.cs b/src/Ombi.Api.SickRage/Models/SickRageEpisodeStatus.cs index 4f131d5e3..9142e2b42 100644 --- a/src/Ombi.Api.SickRage/Models/SickRageEpisodeStatus.cs +++ b/src/Ombi.Api.SickRage/Models/SickRageEpisodeStatus.cs @@ -9,7 +9,7 @@ public class SickRageEpisodeSetStatus { - public Data data { get; set; } + public Data[] data { get; set; } public string message { get; set; } public string result { get; set; } } diff --git a/src/Ombi.Api.SickRage/Ombi.Api.SickRage.csproj b/src/Ombi.Api.SickRage/Ombi.Api.SickRage.csproj index 320c51076..89c47d251 100644 --- a/src/Ombi.Api.SickRage/Ombi.Api.SickRage.csproj +++ b/src/Ombi.Api.SickRage/Ombi.Api.SickRage.csproj @@ -1,8 +1,8 @@  - net5.0 - 8.0 + net6.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Slack/Ombi.Api.Slack.csproj b/src/Ombi.Api.Slack/Ombi.Api.Slack.csproj index 20c8a9aef..70032d638 100644 --- a/src/Ombi.Api.Slack/Ombi.Api.Slack.csproj +++ b/src/Ombi.Api.Slack/Ombi.Api.Slack.csproj @@ -1,12 +1,12 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Sonarr/Ombi.Api.Sonarr.csproj b/src/Ombi.Api.Sonarr/Ombi.Api.Sonarr.csproj index 20c8a9aef..70032d638 100644 --- a/src/Ombi.Api.Sonarr/Ombi.Api.Sonarr.csproj +++ b/src/Ombi.Api.Sonarr/Ombi.Api.Sonarr.csproj @@ -1,12 +1,12 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Sonarr/SonarrApi.cs b/src/Ombi.Api.Sonarr/SonarrApi.cs index d2df50cd9..50e4f04ff 100644 --- a/src/Ombi.Api.Sonarr/SonarrApi.cs +++ b/src/Ombi.Api.Sonarr/SonarrApi.cs @@ -19,7 +19,7 @@ namespace Ombi.Api.Sonarr protected IApi Api { get; } protected virtual string ApiBaseUrl => "/api/"; - public async Task> GetProfiles(string apiKey, string baseUrl) + public virtual async Task> GetProfiles(string apiKey, string baseUrl) { var request = new Request($"{ApiBaseUrl}profile", baseUrl, HttpMethod.Get); request.AddHeader("X-Api-Key", apiKey); diff --git a/src/Ombi.Api.Sonarr/SonarrV3Api.cs b/src/Ombi.Api.Sonarr/SonarrV3Api.cs index 64377ee4a..71c230f35 100644 --- a/src/Ombi.Api.Sonarr/SonarrV3Api.cs +++ b/src/Ombi.Api.Sonarr/SonarrV3Api.cs @@ -1,6 +1,8 @@ using System.Net.Http; using System.Collections.Generic; using System.Threading.Tasks; + +using Ombi.Api.Sonarr.Models; using Ombi.Api.Sonarr.Models.V3; namespace Ombi.Api.Sonarr @@ -21,5 +23,12 @@ namespace Ombi.Api.Sonarr return await Api.Request>(request); } + + public override async Task> GetProfiles(string apiKey, string baseUrl) + { + var request = new Request($"{ApiBaseUrl}qualityprofile", baseUrl, HttpMethod.Get); + request.AddHeader("X-Api-Key", apiKey); + return await Api.Request>(request); + } } } diff --git a/src/Ombi.Api.Telegram/Ombi.Api.Telegram.csproj b/src/Ombi.Api.Telegram/Ombi.Api.Telegram.csproj index 320c51076..89c47d251 100644 --- a/src/Ombi.Api.Telegram/Ombi.Api.Telegram.csproj +++ b/src/Ombi.Api.Telegram/Ombi.Api.Telegram.csproj @@ -1,8 +1,8 @@  - net5.0 - 8.0 + net6.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Trakt/Ombi.Api.Trakt.csproj b/src/Ombi.Api.Trakt/Ombi.Api.Trakt.csproj index f499f594e..fd9632e56 100644 --- a/src/Ombi.Api.Trakt/Ombi.Api.Trakt.csproj +++ b/src/Ombi.Api.Trakt/Ombi.Api.Trakt.csproj @@ -1,12 +1,12 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.TvMaze/ITvMazeApi.cs b/src/Ombi.Api.TvMaze/ITvMazeApi.cs index 819051d83..983858810 100644 --- a/src/Ombi.Api.TvMaze/ITvMazeApi.cs +++ b/src/Ombi.Api.TvMaze/ITvMazeApi.cs @@ -8,10 +8,8 @@ namespace Ombi.Api.TvMaze public interface ITvMazeApi { Task> EpisodeLookup(int showId); - Task> GetSeasons(int id); Task> Search(string searchTerm); Task ShowLookup(int showId); Task ShowLookupByTheTvDbId(int theTvDbId); - Task GetTvFullInformation(int id); } } \ No newline at end of file diff --git a/src/Ombi.Api.TvMaze/Ombi.Api.TvMaze.csproj b/src/Ombi.Api.TvMaze/Ombi.Api.TvMaze.csproj index 3008c9230..a1b98b765 100644 --- a/src/Ombi.Api.TvMaze/Ombi.Api.TvMaze.csproj +++ b/src/Ombi.Api.TvMaze/Ombi.Api.TvMaze.csproj @@ -1,12 +1,12 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.TvMaze/TvMazeApi.cs b/src/Ombi.Api.TvMaze/TvMazeApi.cs index 5d761da47..3f37d7488 100644 --- a/src/Ombi.Api.TvMaze/TvMazeApi.cs +++ b/src/Ombi.Api.TvMaze/TvMazeApi.cs @@ -64,27 +64,5 @@ namespace Ombi.Api.TvMaze return null; } } - - public async Task> GetSeasons(int id) - { - var request = new Request($"shows/{id}/seasons", Uri, HttpMethod.Get); - - request.AddContentHeader("Content-Type", "application/json"); - - return await Api.Request>(request); - } - - public async Task GetTvFullInformation(int id) - { - var request = new Request($"shows/{id}", Uri, HttpMethod.Get); - - request.AddQueryString("embed[]", "cast"); - request.AddQueryString("embed[]", "crew"); - request.AddQueryString("embed[]", "episodes"); - - request.AddContentHeader("Content-Type", "application/json"); - - return await Api.Request(request); - } } } diff --git a/src/Ombi.Api.Twilio/Ombi.Api.Twilio.csproj b/src/Ombi.Api.Twilio/Ombi.Api.Twilio.csproj index a5bb9ea19..8e12c7c67 100644 --- a/src/Ombi.Api.Twilio/Ombi.Api.Twilio.csproj +++ b/src/Ombi.Api.Twilio/Ombi.Api.Twilio.csproj @@ -1,7 +1,7 @@  - net5.0 + net6.0 Debug;Release;NonUiBuild diff --git a/src/Ombi.Api.Webhook/Ombi.Api.Webhook.csproj b/src/Ombi.Api.Webhook/Ombi.Api.Webhook.csproj index 109e3e3f1..7748aad45 100644 --- a/src/Ombi.Api.Webhook/Ombi.Api.Webhook.csproj +++ b/src/Ombi.Api.Webhook/Ombi.Api.Webhook.csproj @@ -1,7 +1,7 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 diff --git a/src/Ombi.Api/ApiHelper.cs b/src/Ombi.Api/ApiHelper.cs index fa9d3e7ab..f88525869 100644 --- a/src/Ombi.Api/ApiHelper.cs +++ b/src/Ombi.Api/ApiHelper.cs @@ -66,6 +66,8 @@ namespace Ombi.Api startingTag = builder.Query.Contains("?") ? "&" : "?"; } + value = Uri.EscapeDataString(value); + builder.Query = hasQuery ? $"{builder.Query}{startingTag}{parameter}={value}" : $"{startingTag}{parameter}={value}"; diff --git a/src/Ombi.Api/Ombi.Api.csproj b/src/Ombi.Api/Ombi.Api.csproj index 02969e665..7670d4d14 100644 --- a/src/Ombi.Api/Ombi.Api.csproj +++ b/src/Ombi.Api/Ombi.Api.csproj @@ -1,18 +1,18 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild - - + + diff --git a/src/Ombi.Core.Tests/Engine/CalendarEngineTests.cs b/src/Ombi.Core.Tests/Engine/CalendarEngineTests.cs index b922a21c0..0a85fd058 100644 --- a/src/Ombi.Core.Tests/Engine/CalendarEngineTests.cs +++ b/src/Ombi.Core.Tests/Engine/CalendarEngineTests.cs @@ -10,6 +10,7 @@ using Ombi.Core.Authentication; using Ombi.Core.Engine.V2; using Ombi.Store.Entities.Requests; using Ombi.Store.Repository.Requests; +using Ombi.Core.Helpers; namespace Ombi.Core.Tests.Engine { @@ -25,7 +26,7 @@ namespace Ombi.Core.Tests.Engine { MovieRepo = new Mock(); TvRepo = new Mock(); - var principle = new Mock(); + var principle = new Mock(); var identity = new Mock(); identity.Setup(x => x.Name).Returns("UnitTest"); principle.Setup(x => x.Identity).Returns(identity.Object); diff --git a/src/Ombi.Core.Tests/Engine/MovieRequestEngineTests.cs b/src/Ombi.Core.Tests/Engine/MovieRequestEngineTests.cs index 9b12e0b01..f8ced161f 100644 --- a/src/Ombi.Core.Tests/Engine/MovieRequestEngineTests.cs +++ b/src/Ombi.Core.Tests/Engine/MovieRequestEngineTests.cs @@ -1,135 +1,520 @@ -//using System.Collections.Generic; -//using System.Linq; -//using System.Threading.Tasks; -//using Moq; -//using NUnit.Framework; -//using Ombi.Core.Engine; -//using Ombi.Core.Models.Requests; -//using Ombi.Store.Entities.Requests; -//using Ombi.Store.Repository; -//using Assert = Xunit.Assert; +using MockQueryable.Moq; +using Moq; +using Moq.AutoMock; +using NUnit.Framework; +using Ombi.Core.Authentication; +using Ombi.Core.Engine; +using Ombi.Core.Helpers; +using Ombi.Core.Models.Requests; +using Ombi.Store.Entities; +using Ombi.Store.Entities.Requests; +using Ombi.Store.Repository; +using Ombi.Store.Repository.Requests; +using Ombi.Test.Common; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Security.Principal; +using System.Threading.Tasks; -//namespace Ombi.Core.Tests.Engine -//{ -// [TestFixture] -// public class MovieRequestEngineTests -// { -// public MovieRequestEngineTests() -// { -// RequestService = new Mock(); -// var requestService = new RequestService(null, RequestService.Object); -// Engine = new MovieRequestEngine(null, requestService, null, null, null, null, null, null); -// } +namespace Ombi.Core.Tests.Engine +{ + [TestFixture] + public class MovieRequestEngineTests + { + private MovieRequestEngine _subject; + private Mock _repoMock; + private AutoMocker _mocker; -// private MovieRequestEngine Engine { get; } -// private Mock RequestService { get; } + [SetUp] + public void Setup() + { + _mocker = new AutoMocker(); + var userManager = MockHelper.MockUserManager(new List { new OmbiUser { NormalizedUserName = "TEST", Id = "a" } }); + userManager.Setup(x => x.IsInRoleAsync(It.IsAny(), It.IsAny())).ReturnsAsync(true); + var principle = new Mock(); + var identity = new Mock(); + identity.Setup(x => x.Name).Returns("Test"); + principle.Setup(x => x.Identity).Returns(identity.Object); + var currentUser = new Mock(); + currentUser.Setup(x => x.Identity).Returns(identity.Object); + currentUser.Setup(x => x.Username).Returns("Test"); + currentUser.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { NormalizedUserName = "TEST", Id = "a" }); -// [Test] -// public async Task GetNewRequests_Should_ReturnEmpty_WhenThereAreNoNewRequests() -// { -// var requests = new List -// { -// new MovieRequests { Available = true }, -// new MovieRequests { Approved = true }, -// }; + _repoMock = new Mock(); + var requestServiceMock = new Mock(); + requestServiceMock.Setup(x => x.MovieRequestService).Returns(_repoMock.Object); -// var r = DbHelper.GetQueryable(requests[0], requests[1]); -// RequestService.Setup(x => x.Get()).Returns(r); + _mocker.Use(principle.Object); + _mocker.Use(currentUser.Object); + _mocker.Use(userManager.Object); + _mocker.Use(requestServiceMock); -// var result = await Engine.GetNewRequests(); + _subject = _mocker.CreateInstance(); + var list = DbHelper.GetQueryableMockDbSet(new RequestSubscription()); + _mocker.Setup, IQueryable>(x => x.GetAll()).Returns(new List().AsQueryable().BuildMock().Object); + } -// Assert.False(result.Any()); -// } + [Test] + public async Task GetRequestByStatus_PendingRequests_Non4K() + { + var movies = RegularRequestData(); + _repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable()); -// [Test] -// public async Task GetNewRequests_Should_ReturnOnlyNewRequests_WhenThereAreMultipleRequests() -// { -// var requests = new List -// { -// new MovieRequests { Available = true }, -// new MovieRequests { Approved = true }, -// new MovieRequests(), -// }; -// RequestService.Setup(x => x.Get()).Returns(requests.AsQueryable); + var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", Models.Requests.RequestStatus.PendingApproval); -// var result = await Engine.GetNewRequests(); + Assert.That(result.Total, Is.EqualTo(1)); + Assert.That(result.Collection.First().Id, Is.EqualTo(4)); + } -// Assert.Single(result); -// Assert.All(result, x => -// { -// Assert.False(x.Available); -// Assert.False(x.Approved); -// }); -// } + [Test] + public async Task GetRequestByStatus_PendingRequests_4K() + { + var movies = new List + { + new MovieRequests + { + Id= 1, + Approved4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 2, + Approved4K = false, + Available4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 3, + Denied4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 4, + Has4KRequest = true, + Approved4K = false, + Available4K = false, + Denied4K = false, + RequestedDate = DateTime.MinValue + } + }; + _repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable()); -// [Test] -// public async Task GetApprovedRequests_Should_ReturnEmpty_WhenThereAreNoApprovedRequests() -// { -// var requests = new List -// { -// new MovieRequests { Available = true }, -// }; -// RequestService.Setup(x => x.Get()).Returns(requests.AsQueryable); + var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", RequestStatus.PendingApproval); -// var result = await Engine.GetApprovedRequests(); + Assert.That(result.Total, Is.EqualTo(1)); + Assert.That(result.Collection.First().Id, Is.EqualTo(4)); + } -// Assert.False(result.Any()); -// } -// [Test] -// public async Task GetApprovedRequests_Should_ReturnOnlyApprovedRequests_WhenThereAreMultipleRequests() -// { -// var requests = new List -// { -// new MovieRequests { Available = true }, -// new MovieRequests { Approved = true }, -// new MovieRequests(), -// }; -// RequestService.Setup(x => x.Get()).Returns(requests.AsQueryable); + [Test] + public async Task GetRequestByStatus_PendingRequests_Both4K_And_Regular() + { + var movies = new List + { + new MovieRequests + { + Id= 1, + Approved = false, + Approved4K = true, + Has4KRequest = true, + RequestedDate = DateTime.Now + }, + new MovieRequests + { + Id = 2, + Approved4K = false, + Available4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 3, + Denied4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 4, + Has4KRequest = true, + Approved4K = false, + Available4K = false, + Denied4K = false, + RequestedDate = DateTime.MinValue + } + }; + _repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable()); -// var result = await Engine.GetApprovedRequests(); + var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", RequestStatus.PendingApproval); -// Assert.Single(result); -// Assert.All(result, x => -// { -// Assert.False(x.Available); -// Assert.True(x.Approved); -// }); -// } + Assert.That(result.Total, Is.EqualTo(2)); + Assert.That(result.Collection.First().Id, Is.EqualTo(1)); + Assert.That(result.Collection.ToArray()[1].Id, Is.EqualTo(4)); + } -// [Test] -// public async Task GetAvailableRequests_Should_ReturnEmpty_WhenThereAreNoAvailableRequests() -// { -// var requests = new List -// { -// new MovieRequests { Approved = true }, -// }; -// RequestService.Setup(x => x.Get()).Returns(requests.AsQueryable); -// var result = await Engine.GetAvailableRequests(); + [Test] + public async Task GetRequestByStatus_ProcessingRequests_Non4K() + { + var movies = RegularRequestData(); + _repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable()); -// Assert.False(result.Any()); -// } + var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", Models.Requests.RequestStatus.ProcessingRequest); -// [Test] -// public async Task GetAvailableRequests_Should_ReturnOnlyAvailableRequests_WhenThereAreMultipleRequests() -// { -// var requests = new List -// { -// new MovieRequests { Available = true }, -// new MovieRequests { Approved = true }, -// new MovieRequests(), -// }; -// RequestService.Setup(x => x.Get()).Returns(requests.AsQueryable); + Assert.That(result.Total, Is.EqualTo(1)); + Assert.That(result.Collection.First().Id, Is.EqualTo(1)); + } -// var result = await Engine.GetAvailableRequests(); + [Test] + public async Task GetRequestByStatus_ProcessingRequests_4K() + { + var movies = new List + { + new MovieRequests + { + Id= 1, + Approved4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 2, + Approved4K = false, + Available4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 3, + Denied4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 4, + Has4KRequest = true, + Approved4K = false, + Available4K = false, + Denied4K = false, + RequestedDate = DateTime.MinValue + } + }; + _repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable()); -// Assert.Single(result); -// Assert.All(result, x => -// { -// Assert.True(x.Available); -// Assert.False(x.Approved); -// }); -// } -// } -//} \ No newline at end of file + var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", RequestStatus.ProcessingRequest); + + Assert.That(result.Total, Is.EqualTo(1)); + Assert.That(result.Collection.First().Id, Is.EqualTo(1)); + } + + + [Test] + public async Task GetRequestByStatus_ProcessingRequests_Both4K_And_Regular() + { + var movies = new List + { + new MovieRequests + { + Id= 1, + Approved = false, + Approved4K = true, + Has4KRequest = true, + RequestedDate = DateTime.Now + }, + new MovieRequests + { + Id = 2, + Approved4K = false, + Available4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 3, + Denied4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 4, + Has4KRequest = true, + Approved4K = false, + Approved = true, + Available4K = false, + Denied4K = false, + RequestedDate = DateTime.Now + } + }; + _repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable()); + + var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", RequestStatus.ProcessingRequest); + + Assert.That(result.Total, Is.EqualTo(2)); + Assert.That(result.Collection.First().Id, Is.EqualTo(1)); + Assert.That(result.Collection.ToArray()[1].Id, Is.EqualTo(4)); + } + + + [Test] + public async Task GetRequestByStatus_AvailableRequests_Non4K() + { + List movies = RegularRequestData(); + _repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable()); + + var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", Models.Requests.RequestStatus.Available); + + Assert.That(result.Total, Is.EqualTo(1)); + Assert.That(result.Collection.First().Id, Is.EqualTo(2)); + } + + + + [Test] + public async Task GetRequestByStatus_AvailableRequests_4K() + { + var movies = new List + { + new MovieRequests + { + Id= 1, + Approved4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 2, + Approved4K = false, + Available4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 3, + Denied4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 4, + Has4KRequest = true, + Approved4K = false, + Available4K = false, + Denied4K = false, + RequestedDate = DateTime.MinValue + } + }; + _repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable()); + + var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", RequestStatus.Available); + + Assert.That(result.Total, Is.EqualTo(1)); + Assert.That(result.Collection.First().Id, Is.EqualTo(2)); + } + + + [Test] + public async Task GetRequestByStatus_AvailableRequests_Both4K_And_Regular() + { + var movies = new List + { + new MovieRequests + { + Id= 1, + Available = true, + Approved = false, + Approved4K = true, + Has4KRequest = true, + RequestedDate = DateTime.Now + }, + new MovieRequests + { + Id = 2, + Approved4K = false, + Available4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 3, + Denied4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 4, + Has4KRequest = true, + Approved4K = false, + Approved = true, + Available4K = false, + Denied4K = false, + RequestedDate = DateTime.Now + } + }; + _repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable()); + + var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", RequestStatus.Available); + + Assert.That(result.Total, Is.EqualTo(2)); + Assert.That(result.Collection.First().Id, Is.EqualTo(1)); + Assert.That(result.Collection.ToArray()[1].Id, Is.EqualTo(2)); + } + + [Test] + public async Task GetRequestByStatus_DeniedRequests_Non4K() + { + List movies = RegularRequestData(); + _repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable()); + + var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", Models.Requests.RequestStatus.Denied); + + Assert.That(result.Total, Is.EqualTo(1)); + Assert.That(result.Collection.First().Id, Is.EqualTo(3)); + } + + [Test] + public async Task GetRequestByStatus_DeniedRequests_4K() + { + var movies = new List + { + new MovieRequests + { + Id= 1, + Approved4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 2, + Approved4K = false, + Available4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 3, + Denied4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 4, + Has4KRequest = true, + Approved4K = false, + Available4K = false, + Denied4K = false, + RequestedDate = DateTime.MinValue + } + }; + _repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable()); + + var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", RequestStatus.Denied); + + Assert.That(result.Total, Is.EqualTo(1)); + Assert.That(result.Collection.First().Id, Is.EqualTo(3)); + } + + + [Test] + public async Task GetRequestByStatus_DeniedRequests_Both4K_And_Regular() + { + var movies = new List + { + new MovieRequests + { + Id= 1, + Available = true, + Approved = false, + Approved4K = true, + Has4KRequest = true, + RequestedDate = DateTime.Now + }, + new MovieRequests + { + Id = 2, + Approved4K = false, + Available4K = true, + Denied = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 3, + Denied4K = true, + Has4KRequest = true, + RequestedDate = DateTime.MinValue + }, + new MovieRequests + { + Id = 4, + Has4KRequest = true, + Approved4K = false, + Approved = true, + Available4K = false, + Denied4K = false, + RequestedDate = DateTime.Now + } + }; + _repoMock.Setup(x => x.GetWithUser()).Returns(movies.AsQueryable()); + + var result = await _subject.GetRequestsByStatus(10, 0, "id", "asc", RequestStatus.Denied); + + Assert.That(result.Total, Is.EqualTo(2)); + Assert.That(result.Collection.First().Id, Is.EqualTo(2)); + Assert.That(result.Collection.ToArray()[1].Id, Is.EqualTo(3)); + } + + private static List RegularRequestData() + { + return new List + { + new MovieRequests + { + Id= 1, + Approved = true, + RequestedDate = DateTime.Now + }, + new MovieRequests + { + Id = 2, + Approved = false, + Available = true, + RequestedDate = DateTime.Now + }, + new MovieRequests + { + Id = 3, + Denied = true, + RequestedDate = DateTime.Now + }, + new MovieRequests + { + Id = 4, + Approved = false, + RequestedDate = DateTime.Now + } + }; + } + } +} \ No newline at end of file diff --git a/src/Ombi.Core.Tests/Engine/MovieRequestLimitsTests.cs b/src/Ombi.Core.Tests/Engine/MovieRequestLimitsTests.cs index a28081ebc..88e1c75d2 100644 --- a/src/Ombi.Core.Tests/Engine/MovieRequestLimitsTests.cs +++ b/src/Ombi.Core.Tests/Engine/MovieRequestLimitsTests.cs @@ -4,6 +4,7 @@ using Moq.AutoMock; using NUnit.Framework; using Ombi.Core.Authentication; using Ombi.Core.Engine; +using Ombi.Core.Helpers; using Ombi.Core.Models; using Ombi.Core.Services; using Ombi.Helpers; @@ -36,6 +37,13 @@ namespace Ombi.Core.Tests.Engine var identityMock = new Mock(); identityMock.SetupGet(x => x.Name).Returns("Test"); principleMock.SetupGet(x => x.Identity).Returns(identityMock.Object); + + var currentUser = new Mock(); + currentUser.Setup(x => x.Identity).Returns(identityMock.Object); + currentUser.Setup(x => x.Username).Returns("Test"); + currentUser.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "Test", NormalizedUserName = "TEST", Id = "a" }); + + _mocker.Use(currentUser.Object); _mocker.Use(principleMock.Object); _subject = _mocker.CreateInstance(); @@ -429,6 +437,7 @@ namespace Ombi.Core.Tests.Engine Id = "id1" }; var lastWeek = new DateTime(2020, 09, 05).AddMonths(-1).AddDays(-1); + var today = new DateTime(2020, 09, 15, 13, 0, 0); var log = new List { new RequestLog @@ -441,7 +450,7 @@ namespace Ombi.Core.Tests.Engine var repoMock = _mocker.GetMock>(); repoMock.Setup(x => x.GetAll()).Returns(log.AsQueryable().BuildMock().Object); - var result = await _subject.GetRemainingMovieRequests(user); + var result = await _subject.GetRemainingMovieRequests(user, today); Assert.That(result, Is.InstanceOf() .With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true) @@ -474,7 +483,7 @@ namespace Ombi.Core.Tests.Engine var repoMock = _mocker.GetMock>(); repoMock.Setup(x => x.GetAll()).Returns(log.AsQueryable().BuildMock().Object); - var result = await _subject.GetRemainingMovieRequests(user); + var result = await _subject.GetRemainingMovieRequests(user, today); Assert.That(result, Is.InstanceOf() .With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true) @@ -494,7 +503,7 @@ namespace Ombi.Core.Tests.Engine MovieRequestLimitType = RequestLimitType.Month, Id = "id1" }; - var today = DateTime.UtcNow; + var today = new DateTime(2022,2,2,13,0,0); var firstDayOfMonth = new DateTime(today.Year, today.Month, 1); var log = new List { @@ -514,7 +523,7 @@ namespace Ombi.Core.Tests.Engine var repoMock = _mocker.GetMock>(); repoMock.Setup(x => x.GetAll()).Returns(log.AsQueryable().BuildMock().Object); - var result = await _subject.GetRemainingMovieRequests(user); + var result = await _subject.GetRemainingMovieRequests(user, today); Assert.That(result, Is.InstanceOf() .With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true) diff --git a/src/Ombi.Core.Tests/Engine/MusicRequestLimitTests.cs b/src/Ombi.Core.Tests/Engine/MusicRequestLimitTests.cs index d79e70322..93dd5050d 100644 --- a/src/Ombi.Core.Tests/Engine/MusicRequestLimitTests.cs +++ b/src/Ombi.Core.Tests/Engine/MusicRequestLimitTests.cs @@ -4,6 +4,7 @@ using Moq.AutoMock; using NUnit.Framework; using Ombi.Core.Authentication; using Ombi.Core.Engine; +using Ombi.Core.Helpers; using Ombi.Core.Models; using Ombi.Core.Services; using Ombi.Helpers; @@ -36,7 +37,12 @@ namespace Ombi.Core.Tests.Engine var identityMock = new Mock(); identityMock.SetupGet(x => x.Name).Returns("Test"); principleMock.SetupGet(x => x.Identity).Returns(identityMock.Object); + var currentUser = new Mock(); + currentUser.Setup(x => x.Identity).Returns(identityMock.Object); + currentUser.Setup(x => x.Username).Returns("Test"); + currentUser.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "Test", NormalizedUserName = "TEST", Id = "a" }); _mocker.Use(principleMock.Object); + _mocker.Use(currentUser.Object); _subject = _mocker.CreateInstance(); } @@ -494,7 +500,7 @@ namespace Ombi.Core.Tests.Engine MusicRequestLimitType = RequestLimitType.Month, Id = "id1" }; - var today = DateTime.UtcNow; + var today = new DateTime(2022, 2, 2, 13, 0, 0); var firstDayOfMonth = new DateTime(today.Year, today.Month, 1); var log = new List { @@ -514,7 +520,7 @@ namespace Ombi.Core.Tests.Engine var repoMock = _mocker.GetMock>(); repoMock.Setup(x => x.GetAll()).Returns(log.AsQueryable().BuildMock().Object); - var result = await _subject.GetRemainingMusicRequests(user); + var result = await _subject.GetRemainingMusicRequests(user, today); Assert.That(result, Is.InstanceOf() .With.Property(nameof(RequestQuotaCountModel.HasLimit)).EqualTo(true) diff --git a/src/Ombi.Core.Tests/Engine/TvRequestLimitsTests.cs b/src/Ombi.Core.Tests/Engine/TvRequestLimitsTests.cs index e601ab84d..ba383da6c 100644 --- a/src/Ombi.Core.Tests/Engine/TvRequestLimitsTests.cs +++ b/src/Ombi.Core.Tests/Engine/TvRequestLimitsTests.cs @@ -4,6 +4,7 @@ using Moq.AutoMock; using NUnit.Framework; using Ombi.Core.Authentication; using Ombi.Core.Engine; +using Ombi.Core.Helpers; using Ombi.Core.Models; using Ombi.Core.Services; using Ombi.Helpers; @@ -33,7 +34,12 @@ namespace Ombi.Core.Tests.Engine var identityMock = new Mock(); identityMock.SetupGet(x => x.Name).Returns("Test"); principleMock.SetupGet(x => x.Identity).Returns(identityMock.Object); + var currentUser = new Mock(); + currentUser.Setup(x => x.Identity).Returns(identityMock.Object); + currentUser.Setup(x => x.Username).Returns("Test"); + currentUser.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "Test", NormalizedUserName = "TEST", Id = "a" }); _mocker.Use(principleMock.Object); + _mocker.Use(currentUser.Object); _subject = _mocker.CreateInstance(); } diff --git a/src/Ombi.Core.Tests/Engine/V2/MovieRequestEngineTests.cs b/src/Ombi.Core.Tests/Engine/V2/MovieRequestEngineTests.cs index 3c651b167..16b7cb811 100644 --- a/src/Ombi.Core.Tests/Engine/V2/MovieRequestEngineTests.cs +++ b/src/Ombi.Core.Tests/Engine/V2/MovieRequestEngineTests.cs @@ -7,8 +7,10 @@ using Moq; using NUnit.Framework; using Ombi.Api.TheMovieDb; using Ombi.Core.Engine; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Core.Rule.Interfaces; +using Ombi.Core.Services; using Ombi.Core.Settings; using Ombi.Helpers; using Ombi.Settings.Settings.Models; @@ -32,7 +34,7 @@ namespace Ombi.Core.Tests.Engine.V2 var requestService = new Mock(); _movieRequestRepository = new Mock(); requestService.Setup(x => x.MovieRequestService).Returns(_movieRequestRepository.Object); - var user = new Mock(); + var user = new Mock(); var notificationHelper = new Mock(); var rules = new Mock(); var movieSender = new Mock(); @@ -43,8 +45,9 @@ namespace Ombi.Core.Tests.Engine.V2 var ombiSettings = new Mock>(); var requestSubs = new Mock>(); var mediaCache = new Mock(); + var featureService = new Mock(); _engine = new MovieRequestEngine(movieApi.Object, requestService.Object, user.Object, notificationHelper.Object, rules.Object, movieSender.Object, - logger.Object, userManager.Object, requestLogRepo.Object, cache.Object, ombiSettings.Object, requestSubs.Object, mediaCache.Object); + logger.Object, userManager.Object, requestLogRepo.Object, cache.Object, ombiSettings.Object, requestSubs.Object, mediaCache.Object, featureService.Object); } [Test] diff --git a/src/Ombi.Core.Tests/Engine/V2/MusicSearchEngineV2Tests.cs b/src/Ombi.Core.Tests/Engine/V2/MusicSearchEngineV2Tests.cs index 50ab63346..1b773f060 100644 --- a/src/Ombi.Core.Tests/Engine/V2/MusicSearchEngineV2Tests.cs +++ b/src/Ombi.Core.Tests/Engine/V2/MusicSearchEngineV2Tests.cs @@ -23,6 +23,7 @@ using Ombi.Store.Entities; using Ombi.Store.Repository; using Ombi.Test.Common; using Artist = Hqub.MusicBrainz.API.Entities.Artist; +using Ombi.Core.Helpers; namespace Ombi.Core.Tests.Engine.V2 { @@ -45,7 +46,7 @@ namespace Ombi.Core.Tests.Engine.V2 .ForEach(b => F.Behaviors.Remove(b)); F.Behaviors.Add(new OmitOnRecursionBehavior()); - var principle = new Mock(); + var principle = new Mock(); var requestService = new Mock(); var ruleEval = new Mock(); var um = MockHelper.MockUserManager(new List()); diff --git a/src/Ombi.Core.Tests/Engine/VoteEngineTests.cs b/src/Ombi.Core.Tests/Engine/VoteEngineTests.cs index be874669c..4194ae0ea 100644 --- a/src/Ombi.Core.Tests/Engine/VoteEngineTests.cs +++ b/src/Ombi.Core.Tests/Engine/VoteEngineTests.cs @@ -9,6 +9,7 @@ using NUnit.Framework; using Ombi.Core.Authentication; using Ombi.Core.Engine; using Ombi.Core.Engine.Interfaces; +using Ombi.Core.Helpers; using Ombi.Core.Models; using Ombi.Core.Rule.Interfaces; using Ombi.Core.Settings; @@ -32,8 +33,9 @@ namespace Ombi.Core.Tests.Engine TvRequestEngine = new Mock(); MovieRequestEngine = new Mock(); MovieRequestEngine = new Mock(); - User = new Mock(); - User.Setup(x => x.Identity.Name).Returns("abc"); + User = new Mock(); + User.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "abc", NormalizedUserName = "ABC", Id = "abc" }); + UserManager = MockHelper.MockUserManager(new List { new OmbiUser { Id = "abc", UserName = "abc", NormalizedUserName = "ABC" } }); Rule = new Mock(); Engine = new VoteEngine(VoteRepository.Object, User.Object, UserManager.Object, Rule.Object, VoteSettings.Object, MusicRequestEngine.Object, @@ -48,7 +50,7 @@ namespace Ombi.Core.Tests.Engine public Fixture F { get; set; } public VoteEngine Engine { get; set; } - public Mock User { get; set; } + public Mock User { get; set; } public Mock UserManager { get; set; } public Mock Rule { get; set; } public Mock> VoteRepository { get; set; } @@ -83,7 +85,7 @@ namespace Ombi.Core.Tests.Engine Assert.That(result.Result, Is.True); VoteRepository.Verify(x => x.Add(It.Is(c => c.UserId == "abc" && c.VoteType == type)), Times.Once); VoteRepository.Verify(x => x.Delete(It.IsAny()), Times.Never); - MovieRequestEngine.Verify(x => x.ApproveMovieById(1), Times.Never); + MovieRequestEngine.Verify(x => x.ApproveMovieById(1, false), Times.Never); } public static IEnumerable VoteData { @@ -129,7 +131,7 @@ namespace Ombi.Core.Tests.Engine Assert.That(result.Result, Is.False); VoteRepository.Verify(x => x.Delete(It.IsAny()), Times.Never); - MovieRequestEngine.Verify(x => x.ApproveMovieById(1), Times.Never); + MovieRequestEngine.Verify(x => x.ApproveMovieById(1, false), Times.Never); } public static IEnumerable AttemptedTwiceData { @@ -175,7 +177,7 @@ namespace Ombi.Core.Tests.Engine Assert.That(result.Result, Is.True); VoteRepository.Verify(x => x.Delete(It.IsAny()), Times.Once); VoteRepository.Verify(x => x.Add(It.Is(v => v.VoteType == type)), Times.Once); - MovieRequestEngine.Verify(x => x.ApproveMovieById(1), Times.Never); + MovieRequestEngine.Verify(x => x.ApproveMovieById(1, false), Times.Never); } public static IEnumerable VoteConvertData { diff --git a/src/Ombi.Core.Tests/Ombi.Core.Tests.csproj b/src/Ombi.Core.Tests/Ombi.Core.Tests.csproj index fcbdab967..4e01e32cd 100644 --- a/src/Ombi.Core.Tests/Ombi.Core.Tests.csproj +++ b/src/Ombi.Core.Tests/Ombi.Core.Tests.csproj @@ -1,7 +1,7 @@  - net5.0 + net6.0 true true Debug;Release;NonUiBuild @@ -9,7 +9,7 @@ - + diff --git a/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs b/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs index 595ba39e0..c73237097 100644 --- a/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Request/AutoApproveRuleTests.cs @@ -10,6 +10,8 @@ using Ombi.Test.Common; using System.Collections.Generic; using Ombi.Store.Entities; using System; +using Ombi.Core.Services; +using Ombi.Core.Helpers; namespace Ombi.Core.Tests.Rule.Request { @@ -26,23 +28,26 @@ namespace Ombi.Core.Tests.Rule.Request public void Setup() { - PrincipalMock = new Mock(); - PrincipalMock.Setup(x => x.Identity.Name).Returns("abc"); + FeatureService = new Mock(); + + PrincipalMock = new Mock(); + PrincipalMock.Setup(x => x.Username).Returns("abc"); + PrincipalMock.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "abc", NormalizedUserName = "ABC", Id = "a" }); UserManager = MockHelper.MockUserManager(_users); - Rule = new AutoApproveRule(PrincipalMock.Object, UserManager.Object); + Rule = new AutoApproveRule(PrincipalMock.Object, UserManager.Object, FeatureService.Object); } - private AutoApproveRule Rule { get; set; } - private Mock PrincipalMock { get; set; } + private Mock PrincipalMock { get; set; } private Mock UserManager { get; set; } + private Mock FeatureService { get; set; } [Test] public async Task Should_ReturnSuccess_WhenAdminAndRequestMovie() { UserManager.Setup(x => x.IsInRoleAsync(It.IsAny(), OmbiRoles.Admin)).ReturnsAsync(true); - var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie }; + var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie }; var result = await Rule.Execute(request); Assert.True(result.Success); @@ -64,7 +69,7 @@ namespace Ombi.Core.Tests.Rule.Request public async Task Should_ReturnSuccess_WhenAutoApproveMovieAndRequestMovie() { UserManager.Setup(x => x.IsInRoleAsync(It.IsAny(), OmbiRoles.AutoApproveMovie)).ReturnsAsync(true); - var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie }; + var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie }; var result = await Rule.Execute(request); Assert.True(result.Success); @@ -96,7 +101,8 @@ namespace Ombi.Core.Tests.Rule.Request [Test] public async Task Should_ReturnSuccess_WhenSystemUserAndRequestTV() { - PrincipalMock.Setup(x => x.Identity.Name).Returns("sys"); + PrincipalMock.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "sys", NormalizedUserName = "SYS", Id = "a" }); + UserManager.Setup(x => x.IsInRoleAsync(It.IsAny(), OmbiRoles.AutoApproveTv)).ReturnsAsync(false); var request = new BaseRequest() { RequestType = Store.Entities.RequestType.TvShow }; var result = await Rule.Execute(request); @@ -137,5 +143,17 @@ namespace Ombi.Core.Tests.Rule.Request Assert.True(result.Success); Assert.False(request.Approved); } + + [Test] + public async Task Should_ReturnFail_When4kRequestAndFeatureNotEnabled() + { + UserManager.Setup(x => x.IsInRoleAsync(It.IsAny(), It.IsAny())).ReturnsAsync(false); + var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Is4kRequest = true }; + var result = await Rule.Execute(request); + + Assert.True(result.Success); + Assert.False(request.Approved); + Assert.False(request.Approved4K); + } } } diff --git a/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs b/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs index 03dc6f68c..9d8db25d1 100644 --- a/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Request/CanRequestRuleTests.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using Moq; using NUnit.Framework; using Ombi.Core.Authentication; +using Ombi.Core.Helpers; using Ombi.Core.Rule.Rules; using Ombi.Core.Rule.Rules.Request; using Ombi.Helpers; @@ -26,8 +27,9 @@ namespace Ombi.Core.Tests.Rule.Request public void Setup() { - PrincipalMock = new Mock(); - PrincipalMock.Setup(x => x.Identity.Name).Returns("abc"); + PrincipalMock = new Mock(); + PrincipalMock.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "abc", NormalizedUserName = "ABC", Id = "a" }); + UserManager = MockHelper.MockUserManager(_users); Rule = new CanRequestRule(PrincipalMock.Object, UserManager.Object); @@ -35,14 +37,49 @@ namespace Ombi.Core.Tests.Rule.Request private CanRequestRule Rule { get; set; } - private Mock PrincipalMock { get; set; } + private Mock PrincipalMock { get; set; } private Mock UserManager { get; set; } [Test] public async Task Should_ReturnSuccess_WhenRequestingMovieWithMovieRole() { UserManager.Setup(x => x.IsInRoleAsync(It.IsAny(), OmbiRoles.RequestMovie)).ReturnsAsync(true); - var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie }; + var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie }; + var result = await Rule.Execute(request); + + Assert.True(result.Success); + } + + [Test] + public async Task Should_ReturnSuccess_WhenRequestingMovie4KWithMovieRole() + { + UserManager.Setup(x => x.IsInRoleAsync(It.IsAny(), OmbiRoles.RequestMovie)).ReturnsAsync(true); + UserManager.Setup(x => x.IsInRoleAsync(It.IsAny(), OmbiRoles.Request4KMovie)).ReturnsAsync(true); + var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Has4KRequest = true }; + var result = await Rule.Execute(request); + + Assert.True(result.Success); + } + + [Test] + public async Task Should_ReturnFailure_WhenRequestingMovie4KWithMovieRole() + { + UserManager.Setup(x => x.IsInRoleAsync(It.IsAny(), OmbiRoles.RequestMovie)).ReturnsAsync(true); + UserManager.Setup(x => x.IsInRoleAsync(It.IsAny(), OmbiRoles.Request4KMovie)).ReturnsAsync(false); + var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Is4kRequest = true }; + var result = await Rule.Execute(request); + + Assert.False(result.Success); + Assert.False(string.IsNullOrEmpty(result.Message)); + } + + [Test] + public async Task Should_ReturnSuccess_WhenRequestingMovie4KWithAutoApprove() + { + UserManager.Setup(x => x.IsInRoleAsync(It.IsAny(), OmbiRoles.RequestMovie)).ReturnsAsync(true); + UserManager.Setup(x => x.IsInRoleAsync(It.IsAny(), OmbiRoles.AutoApproveMovie)).ReturnsAsync(true); + UserManager.Setup(x => x.IsInRoleAsync(It.IsAny(), OmbiRoles.Request4KMovie)).ReturnsAsync(false); + var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie, Has4KRequest = true }; var result = await Rule.Execute(request); Assert.True(result.Success); @@ -52,7 +89,7 @@ namespace Ombi.Core.Tests.Rule.Request public async Task Should_ReturnFail_WhenRequestingMovieWithoutMovieRole() { UserManager.Setup(x => x.IsInRoleAsync(It.IsAny(), OmbiRoles.RequestMovie)).ReturnsAsync(false); - var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie }; + var request = new MovieRequests() { RequestType = Store.Entities.RequestType.Movie }; var result = await Rule.Execute(request); Assert.False(result.Success); @@ -72,7 +109,8 @@ namespace Ombi.Core.Tests.Rule.Request [Test] public async Task Should_ReturnSuccess_WhenRequestingMovieWithSystemRole() { - PrincipalMock.Setup(x => x.Identity.Name).Returns("sys"); + PrincipalMock.Setup(x => x.GetUser()).ReturnsAsync(new OmbiUser { UserName = "sys", NormalizedUserName = "SYS", Id = "a" }); + UserManager.Setup(x => x.IsInRoleAsync(It.IsAny(), OmbiRoles.Admin)).ReturnsAsync(false); var request = new BaseRequest() { RequestType = Store.Entities.RequestType.Movie }; var result = await Rule.Execute(request); diff --git a/src/Ombi.Core.Tests/Rule/Request/ExistingMovieRequestRuleTests.cs b/src/Ombi.Core.Tests/Rule/Request/ExistingMovieRequestRuleTests.cs index 7ff69c9f2..682d4bf4d 100644 --- a/src/Ombi.Core.Tests/Rule/Request/ExistingMovieRequestRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Request/ExistingMovieRequestRuleTests.cs @@ -9,7 +9,9 @@ using NUnit.Framework; using Ombi.Core.Authentication; using Ombi.Core.Rule.Rules; using Ombi.Core.Rule.Rules.Request; +using Ombi.Core.Services; using Ombi.Helpers; +using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; using Ombi.Store.Repository.Requests; @@ -24,12 +26,14 @@ namespace Ombi.Core.Tests.Rule.Request public void Setup() { ContextMock = new Mock(); - Rule = new ExistingMovieRequestRule(ContextMock.Object); + FeatureService = new Mock(); + Rule = new ExistingMovieRequestRule(ContextMock.Object, FeatureService.Object); } private ExistingMovieRequestRule Rule { get; set; } private Mock ContextMock { get; set; } + private Mock FeatureService { get; set; } [Test] public async Task ExistingRequestRule_Movie_Has_Been_Requested_With_TheMovieDBId() @@ -96,5 +100,82 @@ namespace Ombi.Core.Tests.Rule.Request Assert.That(result.Success, Is.True); Assert.That(result.Message, Is.Null.Or.Empty); } + + [Test] + public async Task ExistingRequestRule_Movie_HasAlready4K_Request() + { + ContextMock.Setup(x => x.GetAll()).Returns(new List + { + new MovieRequests + { + TheMovieDbId = 2, + ImdbId = "2", + RequestType = RequestType.Movie, + Is4kRequest = true + } + }.AsQueryable().BuildMock().Object); + var o = new MovieRequests + { + TheMovieDbId = 2, + ImdbId = "1", + Has4KRequest = true + }; + var result = await Rule.Execute(o); + + Assert.That(result.Success, Is.False); + Assert.That(result.Message, Is.Not.Empty); + } + + [Test] + public async Task ExistingRequestRule_Movie_4K_Request() + { + FeatureService.Setup(x => x.FeatureEnabled(FeatureNames.Movie4KRequests)).ReturnsAsync(true); + ContextMock.Setup(x => x.GetAll()).Returns(new List + { + new MovieRequests + { + TheMovieDbId = 2, + ImdbId = "2", + RequestType = RequestType.Movie, + Is4kRequest = false + } + }.AsQueryable().BuildMock().Object); + var o = new MovieRequests + { + TheMovieDbId = 2, + ImdbId = "1", + Is4kRequest = true + }; + var result = await Rule.Execute(o); + + Assert.That(result.Success, Is.True); + Assert.That(result.Message, Is.Null.Or.Empty); + } + + [Test] + public async Task ExistingRequestRule_Movie_4K_Request_FeatureNotEnabled() + { + FeatureService.Setup(x => x.FeatureEnabled(FeatureNames.Movie4KRequests)).ReturnsAsync(false); + ContextMock.Setup(x => x.GetAll()).Returns(new List + { + new MovieRequests + { + TheMovieDbId = 2, + ImdbId = "2", + RequestType = RequestType.Movie, + Is4kRequest = false + } + }.AsQueryable().BuildMock().Object); + var o = new MovieRequests + { + TheMovieDbId = 2, + ImdbId = "1", + Is4kRequest = true + }; + var result = await Rule.Execute(o); + + Assert.That(result.Success, Is.False); + Assert.That(result.Message, Is.Not.Null); + } } } diff --git a/src/Ombi.Core.Tests/Rule/Request/ExistingPlexRequestRuleTests.cs b/src/Ombi.Core.Tests/Rule/Request/ExistingPlexRequestRuleTests.cs index f5a362303..314b543b8 100644 --- a/src/Ombi.Core.Tests/Rule/Request/ExistingPlexRequestRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Request/ExistingPlexRequestRuleTests.cs @@ -1,6 +1,7 @@ using MockQueryable.Moq; using Moq; using NUnit.Framework; +using Ombi.Core.Engine; using Ombi.Core.Rule.Rules.Request; using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; @@ -176,17 +177,58 @@ namespace Ombi.Core.Tests.Rule.Request Assert.That(result.Success, Is.True); } + [Test] + public async Task RequestMovie_IsSuccessful() + { + SetupMockData(); + + var req = new MovieRequests + { + RequestType = RequestType.Movie, + TheMovieDbId = 123, + Id = 1, + }; + var result = await Rule.Execute(req); + + + Assert.That(result.Success, Is.True); + } + + [Test] + public async Task RequestMovie_IsAlreadyAvailable() + { + var content = new List { + new PlexServerContent + { + TheMovieDbId = 123.ToString(), + } + }; + PlexContentRepo.Setup(x => x.GetAll()).Returns(content.AsQueryable().BuildMock().Object); + + var req = new MovieRequests + { + RequestType = RequestType.Movie, + TheMovieDbId = 123, + Id = 1, + }; + var result = await Rule.Execute(req); + + + Assert.That(result.Success, Is.False); + Assert.That(result.ErrorCode, Is.EqualTo(ErrorCode.AlreadyRequested)); + } + private void SetupMockData() { var childRequests = new List { new PlexServerContent { - Type = PlexMediaTypeEntity.Show, + Type = MediaType.Series, TheMovieDbId = "1", Title = "Test", ReleaseYear = "2001", - Episodes = new List + Episodes = new List { new PlexEpisode { diff --git a/src/Ombi.Core.Tests/Rule/Search/EmbyAvailabilityRuleTests.cs b/src/Ombi.Core.Tests/Rule/Search/EmbyAvailabilityRuleTests.cs index 132f51e49..484e872e2 100644 --- a/src/Ombi.Core.Tests/Rule/Search/EmbyAvailabilityRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Search/EmbyAvailabilityRuleTests.cs @@ -1,11 +1,14 @@ using System.Collections.Generic; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; using Moq; using NUnit.Framework; using Ombi.Core.Models.Search; using Ombi.Core.Rule.Rules.Search; +using Ombi.Core.Services; using Ombi.Core.Settings; using Ombi.Core.Settings.Models.External; +using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; using Ombi.Store.Repository; using Ombi.Store.Repository.Requests; @@ -18,21 +21,23 @@ namespace Ombi.Core.Tests.Rule.Search public void Setup() { ContextMock = new Mock(); - SettingsMock = new Mock>(); - Rule = new EmbyAvailabilityRule(ContextMock.Object, SettingsMock.Object); + LoggerMock = new Mock>(); + FeatureMock = new Mock(); + Rule = new EmbyAvailabilityRule(ContextMock.Object, LoggerMock.Object, FeatureMock.Object); } private EmbyAvailabilityRule Rule { get; set; } private Mock ContextMock { get; set; } - private Mock> SettingsMock { get; set; } + private Mock> LoggerMock { get; set; } + private Mock FeatureMock { get; set; } [Test] public async Task Movie_ShouldBe_Available_WhenFoundInEmby() { - SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings()); ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny())).ReturnsAsync(new EmbyContent { - ProviderId = "123" + TheMovieDbId = "123", + Quality = "1" }); var search = new SearchMovieViewModel() { @@ -45,24 +50,13 @@ namespace Ombi.Core.Tests.Rule.Search } [Test] - public async Task Movie_Has_Custom_Url_When_Specified_In_Settings() + public async Task Movie_ShouldBe_Available_WhenFoundInEmby_4K() { - SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings - { - Enable = true, - Servers = new List - { - new EmbyServers - { - ServerHostname = "http://test.com/", - ServerId = "8" - } - } - }); + FeatureMock.Setup(x => x.FeatureEnabled(FeatureNames.Movie4KRequests)).ReturnsAsync(true); ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny())).ReturnsAsync(new EmbyContent { - ProviderId = "123", - EmbyId = 1.ToString(), + TheMovieDbId = "123", + Has4K = true }); var search = new SearchMovieViewModel() { @@ -71,28 +65,19 @@ namespace Ombi.Core.Tests.Rule.Search var result = await Rule.Execute(search); Assert.True(result.Success); - Assert.That(search.EmbyUrl, Is.EqualTo("http://test.com/web/index.html#!/item?id=1&serverId=8")); + Assert.True(search.Available4K); + Assert.False(search.Available); } [Test] - public async Task Movie_Uses_Default_Url_When() + public async Task Movie_ShouldBe_Available_WhenFoundInEmby_Both() { - SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new EmbySettings - { - Enable = true, - Servers = new List - { - new EmbyServers - { - ServerHostname = string.Empty, - ServerId = "8" - } - } - }); + FeatureMock.Setup(x => x.FeatureEnabled(FeatureNames.Movie4KRequests)).ReturnsAsync(true); ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny())).ReturnsAsync(new EmbyContent { - ProviderId = "123", - EmbyId = 1.ToString() + TheMovieDbId = "123", + Has4K = true, + Quality = "1" }); var search = new SearchMovieViewModel() { @@ -101,7 +86,8 @@ namespace Ombi.Core.Tests.Rule.Search var result = await Rule.Execute(search); Assert.True(result.Success); - Assert.That(search.EmbyUrl, Is.EqualTo("https://app.emby.media/web/index.html#!/item?id=1&serverId=8")); + Assert.True(search.Available4K); + Assert.True(search.Available); } [Test] diff --git a/src/Ombi.Core.Tests/Rule/Search/ExistingRequestRuleTests.cs b/src/Ombi.Core.Tests/Rule/Search/ExistingRequestRuleTests.cs index ea9208cf7..66601f936 100644 --- a/src/Ombi.Core.Tests/Rule/Search/ExistingRequestRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Search/ExistingRequestRuleTests.cs @@ -30,13 +30,14 @@ namespace Ombi.Core.Tests.Rule.Search [Test] - public async Task ShouldBe_Requested_WhenExisitngMovie() + public async Task ShouldBe_Requested_WhenExistingMovie() { var list = new MovieRequests { TheMovieDbId = 123, Approved = true, - RequestType = RequestType.Movie + RequestType = RequestType.Movie, + RequestedDate = System.DateTime.Now, }; MovieMock.Setup(x => x.GetRequestAsync(123)).ReturnsAsync(list); @@ -130,5 +131,76 @@ namespace Ombi.Core.Tests.Rule.Search Assert.False(search.Approved); Assert.False(search.Requested); } + + [Test] + public async Task ShouldBeFullyAvailable_NoFutureAiredEpisodes_NoRequest() + { + var search = new SearchTvShowViewModel() + { + Id = 999, + SeasonRequests = new List + { + new SeasonRequests + { + Episodes = new List + { + new EpisodeRequests + { + Available = true, + AirDate = new System.DateTime(2020,01,01) + }, + new EpisodeRequests + { + Available = true, + AirDate = new System.DateTime(2020,01,02) + }, + } + } + } + }; + var result = await Rule.Execute(search); + + Assert.True(result.Success); + Assert.That(search.FullyAvailable, Is.True); + Assert.That(search.PartlyAvailable, Is.False); + } + + [Test] + public async Task ShouldBeFullyAvailable_AndPartly_FutureAiredEpisodes_NoRequest() + { + var search = new SearchTvShowViewModel() + { + Id = 999, + SeasonRequests = new List + { + new SeasonRequests + { + Episodes = new List + { + new EpisodeRequests + { + Available = true, + AirDate = new System.DateTime(2020,01,01) + }, + new EpisodeRequests + { + Available = true, + AirDate = new System.DateTime(2020,01,02) + }, + new EpisodeRequests + { + Available = true, + AirDate = new System.DateTime(2029,01,02) + }, + } + } + } + }; + var result = await Rule.Execute(search); + + Assert.True(result.Success); + Assert.That(search.FullyAvailable, Is.True); + Assert.That(search.PartlyAvailable, Is.True); + } } } \ No newline at end of file diff --git a/src/Ombi.Core.Tests/Rule/Search/JellyfinAvailabilityRuleTests.cs b/src/Ombi.Core.Tests/Rule/Search/JellyfinAvailabilityRuleTests.cs index 1b838f102..f56876e48 100644 --- a/src/Ombi.Core.Tests/Rule/Search/JellyfinAvailabilityRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Search/JellyfinAvailabilityRuleTests.cs @@ -1,11 +1,14 @@ using System.Collections.Generic; using System.Threading.Tasks; +using Microsoft.Extensions.Logging; using Moq; using NUnit.Framework; using Ombi.Core.Models.Search; using Ombi.Core.Rule.Rules.Search; +using Ombi.Core.Services; using Ombi.Core.Settings; using Ombi.Core.Settings.Models.External; +using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; using Ombi.Store.Repository; using Ombi.Store.Repository.Requests; @@ -18,21 +21,23 @@ namespace Ombi.Core.Tests.Rule.Search public void Setup() { ContextMock = new Mock(); - SettingsMock = new Mock>(); - Rule = new JellyfinAvailabilityRule(ContextMock.Object, SettingsMock.Object); + LoggerMock = new Mock>(); + FeatureMock = new Mock(); + Rule = new JellyfinAvailabilityRule(ContextMock.Object, LoggerMock.Object, FeatureMock.Object); } private JellyfinAvailabilityRule Rule { get; set; } private Mock ContextMock { get; set; } - private Mock> SettingsMock { get; set; } + private Mock> LoggerMock { get; set; } + private Mock FeatureMock { get; set; } [Test] public async Task Movie_ShouldBe_Available_WhenFoundInJellyfin() { - SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings()); ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny())).ReturnsAsync(new JellyfinContent { - ProviderId = "123" + TheMovieDbId = "123", + Quality = "1080" }); var search = new SearchMovieViewModel() { @@ -45,24 +50,13 @@ namespace Ombi.Core.Tests.Rule.Search } [Test] - public async Task Movie_Has_Custom_Url_When_Specified_In_Settings() + public async Task Movie_ShouldBe_Available_WhenFoundInJellyfin_4K() { - SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings - { - Enable = true, - Servers = new List - { - new JellyfinServers - { - ServerHostname = "http://test.com/", - ServerId = "8" - } - } - }); + FeatureMock.Setup(x => x.FeatureEnabled(FeatureNames.Movie4KRequests)).ReturnsAsync(true); ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny())).ReturnsAsync(new JellyfinContent { - ProviderId = "123", - JellyfinId = 1.ToString(), + TheMovieDbId = "123", + Has4K = true }); var search = new SearchMovieViewModel() { @@ -71,29 +65,37 @@ namespace Ombi.Core.Tests.Rule.Search var result = await Rule.Execute(search); Assert.True(result.Success); - Assert.That(search.JellyfinUrl, Is.EqualTo("http://test.com/web/index.html#!/details?id=1&serverId=8")); + Assert.False(search.Available); + Assert.True(search.Available4K); + } + + [Test] + public async Task Movie_ShouldBe_Available_WhenFoundInJellyfin_Both() + { + FeatureMock.Setup(x => x.FeatureEnabled(FeatureNames.Movie4KRequests)).ReturnsAsync(true); + ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny())).ReturnsAsync(new JellyfinContent + { + TheMovieDbId = "123", + Has4K = true, + Quality = "1" + }); + var search = new SearchMovieViewModel() + { + TheMovieDbId = "123", + }; + var result = await Rule.Execute(search); + + Assert.True(result.Success); + Assert.True(search.Available); + Assert.True(search.Available4K); } [Test] public async Task Movie_Uses_Default_Url_When() { - SettingsMock.Setup(x => x.GetSettingsAsync()).ReturnsAsync(new JellyfinSettings - { - Enable = true, - Servers = new List - { - new JellyfinServers - { - Ip = "8080", - Port = 9090, - ServerHostname = string.Empty, - ServerId = "8" - } - } - }); ContextMock.Setup(x => x.GetByTheMovieDbId(It.IsAny())).ReturnsAsync(new JellyfinContent { - ProviderId = "123", + TheMovieDbId = "123", JellyfinId = 1.ToString() }); var search = new SearchMovieViewModel() diff --git a/src/Ombi.Core.Tests/Rule/Search/RadarrCacheRuleTests.cs b/src/Ombi.Core.Tests/Rule/Search/RadarrCacheRuleTests.cs index 94efe89a2..8c5e0c662 100644 --- a/src/Ombi.Core.Tests/Rule/Search/RadarrCacheRuleTests.cs +++ b/src/Ombi.Core.Tests/Rule/Search/RadarrCacheRuleTests.cs @@ -28,25 +28,67 @@ namespace Ombi.Core.Tests.Rule.Search { var list = new List(){new RadarrCache { - TheMovieDbId = 123 + TheMovieDbId = 123, + HasRegular = true }}.AsQueryable(); - + ContextMock.Setup(x => x.GetAll()).Returns(list); var request = new SearchMovieViewModel { Id = 123 }; - var result =await Rule.Execute(request); + var result = await Rule.Execute(request); Assert.True(result.Success); Assert.True(request.Approved); } + [Test] + public async Task Should_ReturnAvailabl_WhenMovieIsInRadarr_4K() + { + var list = new List(){new RadarrCache + { + TheMovieDbId = 123, + Has4K = true, + HasFile = true + }}.AsQueryable(); + + ContextMock.Setup(x => x.GetAll()).Returns(list); + + var request = new SearchMovieViewModel { Id = 123 }; + var result = await Rule.Execute(request); + + Assert.True(result.Success); + Assert.False(request.Available); + Assert.True(request.Available4K); + } + + [Test] + public async Task Should_ReturnAvailable_WhenMovieIsInRadarr_Both() + { + var list = new List(){new RadarrCache + { + TheMovieDbId = 123, + Has4K = true, + HasRegular = true, + HasFile = true + }}.AsQueryable(); + + ContextMock.Setup(x => x.GetAll()).Returns(list); + + var request = new SearchMovieViewModel { Id = 123 }; + var result = await Rule.Execute(request); + + Assert.True(result.Success); + Assert.True(request.Available); + Assert.True(request.Available4K); + + } [Test] public async Task Should_ReturnNotApproved_WhenMovieIsNotInRadarr() { var list = DbHelper.GetQueryableMockDbSet(new RadarrCache { - TheMovieDbId = 000012 + TheMovieDbId = 000012, }); ContextMock.Setup(x => x.GetAll()).Returns(list); diff --git a/src/Ombi.Core.Tests/Senders/MassEmailSenderTests.cs b/src/Ombi.Core.Tests/Senders/MassEmailSenderTests.cs new file mode 100644 index 000000000..5c5cedabe --- /dev/null +++ b/src/Ombi.Core.Tests/Senders/MassEmailSenderTests.cs @@ -0,0 +1,228 @@ +using Microsoft.Extensions.Logging; +using MockQueryable.Moq; +using Moq; +using Moq.AutoMock; +using NUnit.Framework; +using Ombi.Core.Authentication; +using Ombi.Core.Models; +using Ombi.Core.Senders; +using Ombi.Notifications; +using Ombi.Notifications.Models; +using Ombi.Settings.Settings.Models.Notifications; +using Ombi.Store.Entities; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Ombi.Core.Tests.Senders +{ + [TestFixture] + public class MassEmailSenderTests + { + + private MassEmailSender _subject; + private AutoMocker _mocker; + + [SetUp] + public void Setup() + { + _mocker = new AutoMocker(); + _subject = _mocker.CreateInstance(); + } + + [Test] + public async Task SendMassEmail_SingleUser() + { + var model = new MassEmailModel + { + Body = "Test", + Subject = "Subject", + Users = new List + { + new OmbiUser + { + Id = "a" + } + } + }; + + _mocker.Setup>(x => x.Users).Returns(new List + { + new OmbiUser + { + Id = "a", + Email = "Test@test.com" + } + }.AsQueryable().BuildMock().Object); + + var result = await _subject.SendMassEmail(model); + + _mocker.Verify(x => x.SendAdHoc(It.Is(m => m.Subject == model.Subject + && m.Message == model.Body + && m.To == "Test@test.com"), It.IsAny()), Times.Once); + } + + [Test] + public async Task SendMassEmail_MultipleUsers() + { + var model = new MassEmailModel + { + Body = "Test", + Subject = "Subject", + Users = new List + { + new OmbiUser + { + Id = "a" + }, + new OmbiUser + { + Id = "b" + } + } + }; + + _mocker.Setup>(x => x.Users).Returns(new List + { + new OmbiUser + { + Id = "a", + Email = "Test@test.com" + }, + new OmbiUser + { + Id = "b", + Email = "b@test.com" + } + }.AsQueryable().BuildMock().Object); + + var result = await _subject.SendMassEmail(model); + + _mocker.Verify(x => x.SendAdHoc(It.Is(m => m.Subject == model.Subject + && m.Message == model.Body + && m.To == "Test@test.com"), It.IsAny()), Times.Once); + _mocker.Verify(x => x.SendAdHoc(It.Is(m => m.Subject == model.Subject + && m.Message == model.Body + && m.To == "b@test.com"), It.IsAny()), Times.Once); + } + + [Test] + public async Task SendMassEmail_UserNoEmail() + { + var model = new MassEmailModel + { + Body = "Test", + Subject = "Subject", + Users = new List + { + new OmbiUser + { + Id = "a" + } + } + }; + + _mocker.Setup>(x => x.Users).Returns(new List + { + new OmbiUser + { + Id = "a", + } + }.AsQueryable().BuildMock().Object); + + var result = await _subject.SendMassEmail(model); + _mocker.Verify>( + x => x.Log( + LogLevel.Information, + It.IsAny(), + It.IsAny(), + It.IsAny(), + It.IsAny>()), + Times.Once); + + _mocker.Verify(x => x.SendAdHoc(It.IsAny(), It.IsAny()), Times.Never); + } + + [Test] + public async Task SendMassEmail_Bcc() + { + var model = new MassEmailModel + { + Body = "Test", + Subject = "Subject", + Bcc = true, + Users = new List + { + new OmbiUser + { + Id = "a" + }, + new OmbiUser + { + Id = "b" + } + } + }; + + _mocker.Setup>(x => x.Users).Returns(new List + { + new OmbiUser + { + Id = "a", + Email = "Test@test.com" + }, + new OmbiUser + { + Id = "b", + Email = "b@test.com" + } + }.AsQueryable().BuildMock().Object); + + var result = await _subject.SendMassEmail(model); + + _mocker.Verify(x => x.SendAdHoc(It.Is(m => m.Subject == model.Subject + && m.Message == model.Body + && m.Other["bcc"] == "Test@test.com,b@test.com"), It.IsAny()), Times.Once); + } + + [Test] + public async Task SendMassEmail_Bcc_NoEmails() + { + var model = new MassEmailModel + { + Body = "Test", + Subject = "Subject", + Bcc = true, + Users = new List + { + new OmbiUser + { + Id = "a" + }, + new OmbiUser + { + Id = "b" + } + } + }; + + _mocker.Setup>(x => x.Users).Returns(new List + { + new OmbiUser + { + Id = "a", + }, + new OmbiUser + { + Id = "b", + } + }.AsQueryable().BuildMock().Object); + + var result = await _subject.SendMassEmail(model); + + _mocker.Verify(x => x.SendAdHoc(It.IsAny(), It.IsAny()), Times.Never); + } + + } +} diff --git a/src/Ombi.Core/Authentication/OmbiUserManager.cs b/src/Ombi.Core/Authentication/OmbiUserManager.cs index 87f82c1de..124ff1aeb 100644 --- a/src/Ombi.Core/Authentication/OmbiUserManager.cs +++ b/src/Ombi.Core/Authentication/OmbiUserManager.cs @@ -116,16 +116,25 @@ namespace Ombi.Core.Authentication public async Task GetOmbiUserFromPlexToken(string plexToken) { var plexAccount = await _plexApi.GetAccount(plexToken); - + // Check for a ombi user - if (plexAccount?.user != null) + if (plexAccount?.user == null) { - var potentialOmbiUser = await Users.FirstOrDefaultAsync(x => - x.ProviderUserId == plexAccount.user.id); - return potentialOmbiUser; + return null; } - return null; + var potentialOmbiUser = await Users.FirstOrDefaultAsync(x => + x.ProviderUserId == plexAccount.user.id); + // Update ombi user with the token + + if (potentialOmbiUser != null) + { + potentialOmbiUser.MediaServerToken = plexAccount.user.authentication_token; + await UpdateAsync(potentialOmbiUser); + } + + return potentialOmbiUser; + } @@ -142,6 +151,10 @@ namespace Ombi.Core.Authentication var result = await _plexApi.SignIn(new UserRequest { password = password, login = login }); if (result.user?.authentication_token != null) { + // Update ombi user with the token + user.MediaServerToken = result.user?.authentication_token; + await UpdateAsync(user); + return true; } return false; diff --git a/src/Ombi.Core/Engine/BaseMediaEngine.cs b/src/Ombi.Core/Engine/BaseMediaEngine.cs index 91f8a58b0..ee1ce55a8 100644 --- a/src/Ombi.Core/Engine/BaseMediaEngine.cs +++ b/src/Ombi.Core/Engine/BaseMediaEngine.cs @@ -26,7 +26,7 @@ namespace Ombi.Core.Engine private Dictionary _dbMovies; private Dictionary _dbTv; - protected BaseMediaEngine(IPrincipal identity, IRequestServiceMain requestService, + protected BaseMediaEngine(ICurrentUser identity, IRequestServiceMain requestService, IRuleEvaluator rules, OmbiUserManager um, ICacheService cache, ISettingsService ombiSettings, IRepository sub) : base(identity, um, rules) { RequestService = requestService; @@ -78,6 +78,32 @@ namespace Ombi.Core.Engine return _dbTv; } + protected async Task CheckCanManageRequest(BaseRequest request) { + var errorResult = new RequestEngineResult { + Result = false, + ErrorCode = ErrorCode.NoPermissions + }; + var successResult = new RequestEngineResult { Result = true }; + + // Admins can always manage requests + var isAdmin = await IsInRole(OmbiRoles.PowerUser) || await IsInRole(OmbiRoles.Admin); + if (isAdmin) { + return successResult; + } + + // Users with 'ManageOwnRequests' can only manage their own requests + var canManageOwnRequests = await IsInRole(OmbiRoles.ManageOwnRequests); + if (!canManageOwnRequests) { + return errorResult; + } + var isRequestedBySameUser = ( await GetUser() ).Id == request.RequestedUser?.Id; + if (isRequestedBySameUser) { + return successResult; + } + + return errorResult; + } + public RequestCountModel RequestCount() { var movieQuery = MovieRepository.GetAll(); diff --git a/src/Ombi.Core/Engine/Demo/DemoMovieSearchEngine.cs b/src/Ombi.Core/Engine/Demo/DemoMovieSearchEngine.cs index f392bf7ad..af88813d9 100644 --- a/src/Ombi.Core/Engine/Demo/DemoMovieSearchEngine.cs +++ b/src/Ombi.Core/Engine/Demo/DemoMovieSearchEngine.cs @@ -11,6 +11,7 @@ using Ombi.Api.TheMovieDb; using Ombi.Api.TheMovieDb.Models; using Ombi.Config; using Ombi.Core.Authentication; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Core.Models.Search; using Ombi.Core.Rule.Interfaces; @@ -24,7 +25,7 @@ namespace Ombi.Core.Engine.Demo { public class DemoMovieSearchEngine : MovieSearchEngine, IDemoMovieSearchEngine { - public DemoMovieSearchEngine(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, + public DemoMovieSearchEngine(ICurrentUser identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, ILogger logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService s, IRepository sub, IOptions lists) : base(identity, service, movApi, mapper, logger, r, um, mem, s, sub) diff --git a/src/Ombi.Core/Engine/Demo/DemoTvSearchEngine.cs b/src/Ombi.Core/Engine/Demo/DemoTvSearchEngine.cs index 2c91a458f..706a5337d 100644 --- a/src/Ombi.Core/Engine/Demo/DemoTvSearchEngine.cs +++ b/src/Ombi.Core/Engine/Demo/DemoTvSearchEngine.cs @@ -4,6 +4,7 @@ using Ombi.Api.Trakt; using Ombi.Api.TvMaze; using Ombi.Config; using Ombi.Core.Authentication; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Core.Models.Search; using Ombi.Core.Rule.Interfaces; @@ -24,7 +25,7 @@ namespace Ombi.Core.Engine.Demo public class DemoTvSearchEngine : TvSearchEngine, IDemoTvSearchEngine { - public DemoTvSearchEngine(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, + public DemoTvSearchEngine(ICurrentUser identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ICacheService memCache, ISettingsService s, IRepository sub, IOptions lists, IImageService imageService, ISettingsService custom) diff --git a/src/Ombi.Core/Engine/IMusicRequestEngine.cs b/src/Ombi.Core/Engine/IMusicRequestEngine.cs index 4dbb3b16a..fcdb06496 100644 --- a/src/Ombi.Core/Engine/IMusicRequestEngine.cs +++ b/src/Ombi.Core/Engine/IMusicRequestEngine.cs @@ -18,7 +18,7 @@ namespace Ombi.Core.Engine Task GetTotal(); Task MarkAvailable(int modelId); Task MarkUnavailable(int modelId); - Task RemoveAlbumRequest(int requestId); + Task RemoveAlbumRequest(int requestId); Task RequestAlbum(MusicAlbumRequestViewModel model); Task> SearchAlbumRequest(string search); Task UserHasRequest(string userId); diff --git a/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs b/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs index e949ac297..2c68ea371 100644 --- a/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs +++ b/src/Ombi.Core/Engine/Interfaces/BaseEngine.cs @@ -1,42 +1,35 @@ using System; using Ombi.Core.Rule; using System.Collections.Generic; -using System.Security.Principal; using System.Threading.Tasks; using Ombi.Core.Models.Search; using Ombi.Core.Rule.Interfaces; using Ombi.Store.Entities.Requests; using Ombi.Store.Entities; -using Microsoft.EntityFrameworkCore; using Ombi.Core.Authentication; -using Ombi.Helpers; +using Ombi.Core.Helpers; namespace Ombi.Core.Engine.Interfaces { public abstract class BaseEngine { - protected BaseEngine(IPrincipal user, OmbiUserManager um, IRuleEvaluator rules) + protected BaseEngine(ICurrentUser user, OmbiUserManager um, IRuleEvaluator rules) { - UserPrinciple = user; + CurrentUser = user; Rules = rules; UserManager = um; } - protected IPrincipal UserPrinciple { get; } + protected ICurrentUser CurrentUser { get; } protected IRuleEvaluator Rules { get; } - protected OmbiUserManager UserManager { get; } - protected string Username => UserPrinciple.Identity.Name; + protected OmbiUserManager UserManager { get; } + protected string Username => CurrentUser.Username; + protected Task GetUser() => CurrentUser.GetUser(); - private OmbiUser _user; - protected async Task GetUser() - { - if(!Username.HasValue()) - { - return null; - } - var username = Username.ToUpper(); - return _user ??= await UserManager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username); - } + /// + /// Only used for background tasks + /// + public void SetUser(OmbiUser user) => CurrentUser.SetUser(user); protected async Task UserAlias() { @@ -45,9 +38,14 @@ namespace Ombi.Core.Engine.Interfaces protected async Task IsInRole(string roleName) { - return await UserManager.IsInRoleAsync(await GetUser(), roleName); + if (Username.Equals("API", StringComparison.CurrentCultureIgnoreCase)) + { + return true; + } + var user = await GetUser(); + return await UserManager.IsInRoleAsync(user, roleName); } - + public async Task> RunRequestRules(BaseRequest model) { var ruleResults = await Rules.StartRequestRules(model); diff --git a/src/Ombi.Core/Engine/Interfaces/IMovieRequestEngine.cs b/src/Ombi.Core/Engine/Interfaces/IMovieRequestEngine.cs index dfcd1b1da..ab7a9079a 100644 --- a/src/Ombi.Core/Engine/Interfaces/IMovieRequestEngine.cs +++ b/src/Ombi.Core/Engine/Interfaces/IMovieRequestEngine.cs @@ -14,13 +14,13 @@ namespace Ombi.Core.Engine.Interfaces Task> SearchMovieRequest(string search); Task RequestCollection(int collectionId, CancellationToken cancellationToken); - Task RemoveMovieRequest(int requestId); + Task RemoveMovieRequest(int requestId); Task RemoveAllMovieRequests(); Task GetRequest(int requestId); Task UpdateMovieRequest(MovieRequests request); - Task ApproveMovie(MovieRequests request); - Task ApproveMovieById(int requestId); - Task DenyMovieById(int modelId, string denyReason); + Task ApproveMovie(MovieRequests request, bool is4K); + Task ApproveMovieById(int requestId, bool is4K); + Task DenyMovieById(int modelId, string denyReason, bool is4K); Task> GetRequests(int count, int position, string sortProperty, string sortOrder); Task> GetUnavailableRequests(int count, int position, string sortProperty, diff --git a/src/Ombi.Core/Engine/Interfaces/IRequestEngine.cs b/src/Ombi.Core/Engine/Interfaces/IRequestEngine.cs index 44278753f..01300287e 100644 --- a/src/Ombi.Core/Engine/Interfaces/IRequestEngine.cs +++ b/src/Ombi.Core/Engine/Interfaces/IRequestEngine.cs @@ -19,11 +19,12 @@ namespace Ombi.Core.Engine.Interfaces Task> GetRequests(); Task UserHasRequest(string userId); - Task MarkUnavailable(int modelId); - Task MarkAvailable(int modelId); + Task MarkUnavailable(int modelId, bool is4K); + Task MarkAvailable(int modelId, bool is4K); Task GetTotal(); Task UnSubscribeRequest(int requestId, RequestType type); Task SubscribeToRequest(int requestId, RequestType type); - Task ReProcessRequest(int requestId, CancellationToken cancellationToken); + Task ReProcessRequest(int requestId, bool is4K, CancellationToken cancellationToken); + void SetUser(OmbiUser user); } } \ No newline at end of file diff --git a/src/Ombi.Core/Engine/Interfaces/ITvRequestEngine.cs b/src/Ombi.Core/Engine/Interfaces/ITvRequestEngine.cs index c93403b3e..6fdf52c56 100644 --- a/src/Ombi.Core/Engine/Interfaces/ITvRequestEngine.cs +++ b/src/Ombi.Core/Engine/Interfaces/ITvRequestEngine.cs @@ -20,7 +20,7 @@ namespace Ombi.Core.Engine.Interfaces Task UpdateTvRequest(TvRequests request); Task> GetAllChldren(int tvId); Task UpdateChildRequest(ChildRequests request); - Task RemoveTvChild(int requestId); + Task RemoveTvChild(int requestId); Task ApproveChildRequest(int id); Task> GetRequestsLite(); Task UpdateQualityProfile(int requestId, int profileId); diff --git a/src/Ombi.Core/Engine/Interfaces/ITvSearchEngineV2.cs b/src/Ombi.Core/Engine/Interfaces/ITvSearchEngineV2.cs index 25a3c2621..2e01e739e 100644 --- a/src/Ombi.Core/Engine/Interfaces/ITvSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/Interfaces/ITvSearchEngineV2.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; +using Ombi.Api.TheMovieDb.Models; using Ombi.Core.Models.Search; using Ombi.Core.Models.Search.V2; @@ -10,6 +11,7 @@ namespace Ombi.Core { Task GetShowInformation(string tvdbid, CancellationToken token); Task GetShowByRequest(int requestId, CancellationToken token); + Task GetTvByActor(int actorId, string langCode); Task> GetStreamInformation(int movieDbId, CancellationToken cancellationToken); Task> Popular(int currentlyLoaded, int amountToLoad, string langCustomCode = null); Task> Anticipated(int currentlyLoaded, int amountToLoad); diff --git a/src/Ombi.Core/Engine/MovieRequestEngine.cs b/src/Ombi.Core/Engine/MovieRequestEngine.cs index 63aa0d376..e5114677b 100644 --- a/src/Ombi.Core/Engine/MovieRequestEngine.cs +++ b/src/Ombi.Core/Engine/MovieRequestEngine.cs @@ -22,15 +22,18 @@ using Ombi.Store.Entities.Requests; using Ombi.Store.Repository; using Ombi.Core.Models; using System.Threading; +using Ombi.Core.Services; +using Ombi.Core.Helpers; namespace Ombi.Core.Engine { public class MovieRequestEngine : BaseMediaEngine, IMovieRequestEngine { - public MovieRequestEngine(IMovieDbApi movieApi, IRequestServiceMain requestService, IPrincipal user, + public MovieRequestEngine(IMovieDbApi movieApi, IRequestServiceMain requestService, ICurrentUser user, INotificationHelper helper, IRuleEvaluator r, IMovieSender sender, ILogger log, OmbiUserManager manager, IRepository rl, ICacheService cache, - ISettingsService ombiSettings, IRepository sub, IMediaCacheService mediaCacheService) + ISettingsService ombiSettings, IRepository sub, IMediaCacheService mediaCacheService, + IFeatureService featureService) : base(user, requestService, r, manager, cache, ombiSettings, sub) { MovieApi = movieApi; @@ -39,6 +42,7 @@ namespace Ombi.Core.Engine Logger = log; _requestLog = rl; _mediaCacheService = mediaCacheService; + _featureService = featureService; } private IMovieDbApi MovieApi { get; } @@ -47,6 +51,7 @@ namespace Ombi.Core.Engine private ILogger Logger { get; } private readonly IRepository _requestLog; private readonly IMediaCacheService _mediaCacheService; + private readonly IFeatureService _featureService; /// /// Requests the movie. @@ -72,7 +77,8 @@ namespace Ombi.Core.Engine var userDetails = await GetUser(); var canRequestOnBehalf = model.RequestOnBehalf.HasValue(); - var isAdmin = await UserManager.IsInRoleAsync(userDetails, OmbiRoles.PowerUser) || await UserManager.IsInRoleAsync(userDetails, OmbiRoles.Admin); + var isAdmin = await UserManager.IsInRoleAsync(userDetails, OmbiRoles.PowerUser) + || await UserManager.IsInRoleAsync(userDetails, OmbiRoles.Admin); if (canRequestOnBehalf && !isAdmin) { return new RequestEngineResult @@ -93,32 +99,60 @@ namespace Ombi.Core.Engine }; } - var requestModel = new MovieRequests + var is4kFeatureEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests); + var is4kRequest = is4kFeatureEnabled && model.Is4kRequest; + + MovieRequests requestModel; + bool isExisting = false; + // Do we already have a request? 4k or non 4k + var existingRequest = await MovieRepository.GetRequestAsync(movieInfo.Id); + if (existingRequest != null && is4kFeatureEnabled) { - TheMovieDbId = movieInfo.Id, - RequestType = RequestType.Movie, - Overview = movieInfo.Overview, - ImdbId = movieInfo.ImdbId, - PosterPath = PosterPathHelper.FixPosterPath(movieInfo.PosterPath), - Title = movieInfo.Title, - ReleaseDate = !string.IsNullOrEmpty(movieInfo.ReleaseDate) - ? DateTime.Parse(movieInfo.ReleaseDate) - : DateTime.MinValue, - Status = movieInfo.Status, - RequestedDate = DateTime.UtcNow, - Approved = false, - RequestedUserId = canRequestOnBehalf ? model.RequestOnBehalf : userDetails.Id, - Background = movieInfo.BackdropPath, - LangCode = model.LanguageCode, - RequestedByAlias = model.RequestedByAlias, - RootPathOverride = model.RootFolderOverride.GetValueOrDefault(), - QualityOverride = model.QualityPathOverride.GetValueOrDefault() - }; + if (model.Is4kRequest) + { + existingRequest.Is4kRequest = true; + existingRequest.RequestedDate4k = DateTime.Now; + } + else + { + existingRequest.RequestedDate = DateTime.Now; + } + isExisting = true; + requestModel = existingRequest; + } + else + { + requestModel = new MovieRequests + { + TheMovieDbId = movieInfo.Id, + RequestType = RequestType.Movie, + Overview = movieInfo.Overview, + ImdbId = movieInfo.ImdbId, + PosterPath = PosterPathHelper.FixPosterPath(movieInfo.PosterPath), + Title = movieInfo.Title, + ReleaseDate = !string.IsNullOrEmpty(movieInfo.ReleaseDate) + ? DateTime.Parse(movieInfo.ReleaseDate) + : DateTime.MinValue, + Status = movieInfo.Status, + RequestedDate = model.Is4kRequest ? DateTime.MinValue : DateTime.Now, + Approved = false, + Approved4K = false, + RequestedUserId = canRequestOnBehalf ? model.RequestOnBehalf : userDetails.Id, + Background = movieInfo.BackdropPath, + LangCode = model.LanguageCode, + RequestedByAlias = model.RequestedByAlias, + RootPathOverride = model.RootFolderOverride.GetValueOrDefault(), + QualityOverride = model.QualityPathOverride.GetValueOrDefault(), + RequestedDate4k = model.Is4kRequest ? DateTime.Now : DateTime.MinValue, + Is4kRequest = model.Is4kRequest, + Source = model.Source + }; + } var usDates = movieInfo.ReleaseDates?.Results?.FirstOrDefault(x => x.IsoCode == "US"); requestModel.DigitalReleaseDate = usDates?.ReleaseDate ?.FirstOrDefault(x => x.Type == ReleaseDateType.Digital)?.ReleaseDate; - + var ruleResults = (await RunRequestRules(requestModel)).ToList(); var ruleResultInError = ruleResults.Find(x => !x.Success); if (ruleResultInError != null) @@ -130,12 +164,12 @@ namespace Ombi.Core.Engine }; } - if (requestModel.Approved) // The rules have auto approved this + if (requestModel.Approved || requestModel.Approved4K) // The rules have auto approved this { - var requestEngineResult = await AddMovieRequest(requestModel, fullMovieName, model.RequestOnBehalf); + var requestEngineResult = await AddMovieRequest(requestModel, fullMovieName, model.RequestOnBehalf, isExisting, is4kRequest); if (requestEngineResult.Result) { - var result = await ApproveMovie(requestModel); + var result = await ApproveMovie(requestModel, model.Is4kRequest); if (result.IsError) { Logger.LogWarning("Tried auto sending movie but failed. Message: {0}", result.Message); @@ -153,7 +187,7 @@ namespace Ombi.Core.Engine // If there are no providers then it's successful but movie has not been sent } - return await AddMovieRequest(requestModel, fullMovieName, model.RequestOnBehalf); + return await AddMovieRequest(requestModel, fullMovieName, model.RequestOnBehalf, isExisting, is4kRequest); } @@ -218,7 +252,7 @@ namespace Ombi.Core.Engine var requests = await (OrderMovies(allRequests, orderFilter.OrderType)).Skip(position).Take(count) .ToListAsync(); - await CheckForSubscription(shouldHide, requests); + await CheckForSubscription(shouldHide.UserId, requests); return new RequestsViewModel { Collection = requests, @@ -262,7 +296,7 @@ namespace Ombi.Core.Engine var total = requests.Count(); requests = requests.Skip(position).Take(count).ToList(); - await CheckForSubscription(shouldHide, requests); + await CheckForSubscription(shouldHide.UserId, requests); return new RequestsViewModel { Collection = requests, @@ -290,21 +324,44 @@ namespace Ombi.Core.Engine switch (status) { case RequestStatus.PendingApproval: - allRequests = allRequests.Where(x => !x.Approved && !x.Available && (!x.Denied.HasValue || !x.Denied.Value)); + allRequests = allRequests.Where(x => + (x.RequestedDate != DateTime.MinValue && !x.Approved && !x.Available && (!x.Denied.HasValue || !x.Denied.Value)) + || + (x.Has4KRequest && !x.Approved4K && !x.Available4K && (!x.Denied4K.HasValue || !x.Denied4K.Value)) + ); break; case RequestStatus.ProcessingRequest: - allRequests = allRequests.Where(x => x.Approved && !x.Available && (!x.Denied.HasValue || !x.Denied.Value)); + allRequests = allRequests.Where(x => + (x.RequestedDate != DateTime.MinValue && x.Approved && !x.Available && (!x.Denied.HasValue || !x.Denied.Value)) + || + (x.Has4KRequest && x.Approved4K && !x.Available4K && (!x.Denied4K.HasValue || !x.Denied4K.Value)) + ); break; case RequestStatus.Available: - allRequests = allRequests.Where(x => x.Available); + allRequests = allRequests.Where(x => x.Available || x.Available4K); break; case RequestStatus.Denied: - allRequests = allRequests.Where(x => x.Denied.HasValue && x.Denied.Value && !x.Available); + allRequests = allRequests.Where(x => + (x.Denied.HasValue && x.Denied.Value && !x.Available) + || + (x.Has4KRequest && x.Denied4K.HasValue && x.Denied4K.Value && !x.Available4K) + ); break; default: break; } + var requests = allRequests.ToList(); + var total = requests.Count; + if (total == 0) + { + return new RequestsViewModel + { + Collection = Enumerable.Empty(), + Total = total + }; + } + var prop = TypeDescriptor.GetProperties(typeof(MovieRequests)).Find(sortProperty, true); if (sortProperty.Contains('.')) @@ -317,14 +374,14 @@ namespace Ombi.Core.Engine //var secondProp = TypeDescriptor.GetProperties(propType).Find(properties[1], true); } - // TODO fix this so we execute this on the server - var requests = sortOrder.Equals("asc", StringComparison.InvariantCultureIgnoreCase) + requests = sortOrder.Equals("asc", StringComparison.InvariantCultureIgnoreCase) ? allRequests.ToList().OrderBy(x => prop.GetValue(x)).ToList() : allRequests.ToList().OrderByDescending(x => prop.GetValue(x)).ToList(); - var total = requests.Count(); + + // TODO fix this so we execute this on the server requests = requests.Skip(position).Take(count).ToList(); - await CheckForSubscription(shouldHide, requests); + await CheckForSubscription(shouldHide.UserId, requests); return new RequestsViewModel { Collection = requests, @@ -367,7 +424,7 @@ namespace Ombi.Core.Engine var total = requests.Count(); requests = requests.Skip(position).Take(count).ToList(); - await CheckForSubscription(shouldHide, requests); + await CheckForSubscription(shouldHide.UserId, requests); return new RequestsViewModel { Collection = requests, @@ -449,7 +506,7 @@ namespace Ombi.Core.Engine allRequests = await MovieRepository.GetWithUser().ToListAsync(); } - await CheckForSubscription(shouldHide, allRequests); + await CheckForSubscription(shouldHide.UserId, allRequests); return allRequests; } @@ -457,27 +514,30 @@ namespace Ombi.Core.Engine public async Task GetRequest(int requestId) { var request = await MovieRepository.GetWithUser().Where(x => x.Id == requestId).FirstOrDefaultAsync(); - await CheckForSubscription(new HideResult(), new List { request }); + await CheckForSubscription((await GetUser()).Id, new List { request }); return request; } - private async Task CheckForSubscription(HideResult shouldHide, List movieRequests) + private async Task CheckForSubscription(string UserId, List movieRequests) { var requestIds = movieRequests.Select(x => x.Id); var sub = await _subscriptionRepository.GetAll().Where(s => - s.UserId == shouldHide.UserId && requestIds.Contains(s.RequestId) && s.RequestType == RequestType.Movie) + s.UserId == UserId && requestIds.Contains(s.RequestId) && s.RequestType == RequestType.Movie) .ToListAsync(); foreach (var x in movieRequests) { x.PosterPath = PosterPathHelper.FixPosterPath(x.PosterPath); - if (shouldHide.UserId == x.RequestedUserId) + if (UserId == x.RequestedUserId) { x.ShowSubscribe = false; } else { - x.ShowSubscribe = true; + if (!x.Available && !x.Available4K && (!x.Denied ?? true) && (!x.Denied4K ?? true)) + { + x.ShowSubscribe = true; + } var hasSub = sub.FirstOrDefault(r => r.RequestId == x.Id); x.Subscribed = hasSub != null; } @@ -503,18 +563,18 @@ namespace Ombi.Core.Engine } var results = allRequests.Where(x => x.Title.Contains(search, CompareOptions.IgnoreCase)).ToList(); - await CheckForSubscription(shouldHide, results); + await CheckForSubscription(shouldHide.UserId, results); return results; } - public async Task ApproveMovieById(int requestId) + public async Task ApproveMovieById(int requestId, bool is4K) { var request = await MovieRepository.Find(requestId); - return await ApproveMovie(request); + return await ApproveMovie(request, is4K); } - public async Task DenyMovieById(int modelId, string denyReason) + public async Task DenyMovieById(int modelId, string denyReason, bool is4K) { var request = await MovieRepository.Find(modelId); if (request == null) @@ -525,13 +585,22 @@ namespace Ombi.Core.Engine }; } - request.Denied = true; - request.DeniedReason = denyReason; - // We are denying a request - await NotificationHelper.Notify(request, NotificationType.RequestDeclined); + if (is4K) + { + request.Denied4K = true; + request.DeniedReason4K = denyReason; + } + else + { + request.Denied = true; + request.DeniedReason = denyReason; + } await MovieRepository.Update(request); await _mediaCacheService.Purge(); + // We are denying a request + await NotificationHelper.Notify(request, NotificationType.RequestDeclined); + return new RequestEngineResult { Result = true, @@ -539,7 +608,7 @@ namespace Ombi.Core.Engine }; } - public async Task ApproveMovie(MovieRequests request) + public async Task ApproveMovie(MovieRequests request, bool is4K) { if (request == null) { @@ -549,9 +618,18 @@ namespace Ombi.Core.Engine }; } - request.MarkedAsApproved = DateTime.Now; - request.Approved = true; - request.Denied = false; + if (is4K) + { + request.MarkedAsApproved4K = DateTime.Now; + request.Approved4K = true; + request.Denied4K = false; + } + else + { + request.MarkedAsApproved = DateTime.Now; + request.Approved = true; + request.Denied = false; + } await MovieRepository.Update(request); var canNotify = await RunSpecificRule(request, SpecificRules.CanSendNotification, string.Empty); @@ -561,7 +639,7 @@ namespace Ombi.Core.Engine } await _mediaCacheService.Purge(); - return await ProcessSendingMovie(request); + return await ProcessSendingMovie(request, is4K); } public async Task RequestCollection(int collectionId, CancellationToken cancellationToken) @@ -589,11 +667,11 @@ namespace Ombi.Core.Engine return new RequestEngineResult { Result = true, Message = $"The collection {collections.name} has been successfully added!", RequestId = results.FirstOrDefault().RequestId }; } - private async Task ProcessSendingMovie(MovieRequests request) + private async Task ProcessSendingMovie(MovieRequests request, bool is4K) { - if (request.Approved) + if (is4K ? request.Approved4K : request.Approved) { - var result = await Sender.Send(request); + var result = await Sender.Send(request, is4K); if (result.Success && result.Sent) { return new RequestEngineResult @@ -654,11 +732,20 @@ namespace Ombi.Core.Engine /// /// The request identifier. /// - public async Task RemoveMovieRequest(int requestId) + public async Task RemoveMovieRequest(int requestId) { var request = await MovieRepository.GetAll().FirstOrDefaultAsync(x => x.Id == requestId); + + var result = await CheckCanManageRequest(request); + if (result.IsError) + return result; + await MovieRepository.Delete(request); await _mediaCacheService.Purge(); + return new RequestEngineResult + { + Result = true, + }; } public async Task RemoveAllMovieRequests() @@ -673,7 +760,7 @@ namespace Ombi.Core.Engine return await MovieRepository.GetAll().AnyAsync(x => x.RequestedUserId == userId); } - public async Task ReProcessRequest(int requestId, CancellationToken cancellationToken) + public async Task ReProcessRequest(int requestId, bool is4K, CancellationToken cancellationToken) { var request = await MovieRepository.Find(requestId); if (request == null) @@ -685,10 +772,10 @@ namespace Ombi.Core.Engine }; } - return await ProcessSendingMovie(request); + return await ProcessSendingMovie(request, is4K); } - public async Task MarkUnavailable(int modelId) + public async Task MarkUnavailable(int modelId, bool is4K) { var request = await MovieRepository.Find(modelId); if (request == null) @@ -699,7 +786,14 @@ namespace Ombi.Core.Engine }; } - request.Available = false; + if (is4K) + { + request.Available4K = false; + } + else + { + request.Available = false; + } await MovieRepository.Update(request); await _mediaCacheService.Purge(); @@ -710,7 +804,7 @@ namespace Ombi.Core.Engine }; } - public async Task MarkAvailable(int modelId) + public async Task MarkAvailable(int modelId, bool is4K) { var request = await MovieRepository.Find(modelId); if (request == null) @@ -720,9 +814,16 @@ namespace Ombi.Core.Engine ErrorMessage = "Request does not exist" }; } - - request.Available = true; - request.MarkedAsAvailable = DateTime.Now; + if (!is4K) + { + request.Available = true; + request.MarkedAsAvailable = DateTime.Now; + } + else + { + request.Available4K = true; + request.MarkedAsAvailable4K = DateTime.Now; + } await NotificationHelper.Notify(request, NotificationType.RequestAvailable); await MovieRepository.Update(request); await _mediaCacheService.Purge(); @@ -734,9 +835,20 @@ namespace Ombi.Core.Engine }; } - private async Task AddMovieRequest(MovieRequests model, string movieName, string requestOnBehalf) + private async Task AddMovieRequest(MovieRequests model, string movieName, string requestOnBehalf, bool isExisting, bool is4k) { - await MovieRepository.Add(model); + if (is4k) + { + model.Has4KRequest = true; + } + if (!isExisting) + { + await MovieRepository.Add(model); + } + else + { + await MovieRepository.Update(model); + } var result = await RunSpecificRule(model, SpecificRules.CanSendNotification, requestOnBehalf); if (result.Success) diff --git a/src/Ombi.Core/Engine/MovieSearchEngine.cs b/src/Ombi.Core/Engine/MovieSearchEngine.cs index d911c1cf5..ae24e275a 100644 --- a/src/Ombi.Core/Engine/MovieSearchEngine.cs +++ b/src/Ombi.Core/Engine/MovieSearchEngine.cs @@ -4,6 +4,7 @@ using Microsoft.Extensions.Logging; using Ombi.Api.TheMovieDb; using Ombi.Api.TheMovieDb.Models; using Ombi.Core.Authentication; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Core.Models.Search; using Ombi.Core.Rule.Interfaces; @@ -15,14 +16,13 @@ using Ombi.Store.Repository; using System; using System.Collections.Generic; using System.Linq; -using System.Security.Principal; using System.Threading.Tasks; namespace Ombi.Core.Engine { public class MovieSearchEngine : BaseMediaEngine, IMovieEngine { - public MovieSearchEngine(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, + public MovieSearchEngine(ICurrentUser identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, ILogger logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService s, IRepository sub) : base(identity, service, r, um, mem, s, sub) { @@ -46,7 +46,7 @@ namespace Ombi.Core.Engine { langCode = await DefaultLanguageCode(langCode); var movieInfo = await Cache.GetOrAddAsync(nameof(LookupImdbInformation) + langCode + theMovieDbId, - () => MovieApi.GetMovieInformationWithExtraInfo(theMovieDbId, langCode), + () => MovieApi.GetMovieInformationWithExtraInfo(theMovieDbId, langCode), DateTimeOffset.Now.AddHours(12)); var viewMovie = Mapper.Map(movieInfo); @@ -81,11 +81,11 @@ namespace Ombi.Core.Engine { return resultSet; } - + // Get this person movie credits var credits = await MovieApi.GetActorMovieCredits(person.id, langaugeCode); // Grab results from both cast and crew, prefer items in cast. we can handle directors like this. - var movieResults = (from role in credits.cast select new { Id = role.id, Title = role.title, ReleaseDate = role.release_date }).ToList(); + var movieResults = (from role in credits.cast select new { Id = role.id, Title = role.title, ReleaseDate = role.release_date }).ToList(); movieResults.AddRange((from job in credits.crew select new { Id = job.id, Title = job.title, ReleaseDate = job.release_date }).ToList()); movieResults = movieResults.Take(10).ToList(); @@ -120,7 +120,7 @@ namespace Ombi.Core.Engine /// public async Task> PopularMovies() { - + var result = await Cache.GetOrAddAsync(CacheKeys.PopularMovies, async () => { var langCode = await DefaultLanguageCode(null); @@ -160,7 +160,7 @@ namespace Ombi.Core.Engine var result = await Cache.GetOrAddAsync(CacheKeys.UpcomingMovies, async () => { var langCode = await DefaultLanguageCode(null); - return await MovieApi.Upcoming(langCode); + return await MovieApi.UpcomingMovies(langCode); }, DateTimeOffset.Now.AddHours(12)); if (result != null) { @@ -201,7 +201,7 @@ namespace Ombi.Core.Engine protected async Task ProcessSingleMovie(SearchMovieViewModel viewMovie, bool lookupExtraInfo = false) { - if (lookupExtraInfo && viewMovie.ImdbId.IsNullOrEmpty()) + if (lookupExtraInfo && viewMovie.ImdbId.IsNullOrEmpty() && viewMovie.Id > 0) { var showInfo = await MovieApi.GetMovieInformation(viewMovie.Id); viewMovie.Id = showInfo.Id; // TheMovieDbId @@ -215,34 +215,9 @@ namespace Ombi.Core.Engine await RunSearchRules(viewMovie); - // This requires the rules to be run first to populate the RequestId property - await CheckForSubscription(viewMovie); - return viewMovie; } - private async Task CheckForSubscription(SearchMovieViewModel viewModel) - { - // Check if this user requested it - var user = await GetUser(); - if (user == null) - { - return; - } - var request = await RequestService.MovieRequestService.GetAll() - .AnyAsync(x => x.RequestedUserId.Equals(user.Id) && x.TheMovieDbId == viewModel.Id); - if (request || viewModel.Available) - { - viewModel.ShowSubscribe = false; - } - else - { - viewModel.ShowSubscribe = true; - var sub = await _subscriptionRepository.GetAll().FirstOrDefaultAsync(s => s.UserId == user.Id - && s.RequestId == viewModel.RequestId && s.RequestType == RequestType.Movie); - viewModel.Subscribed = sub != null; - } - } private async Task ProcessSingleMovie(MovieDbSearchResult movie) { diff --git a/src/Ombi.Core/Engine/MusicRequestEngine.cs b/src/Ombi.Core/Engine/MusicRequestEngine.cs index d0a9cc5d7..67caa81a2 100644 --- a/src/Ombi.Core/Engine/MusicRequestEngine.cs +++ b/src/Ombi.Core/Engine/MusicRequestEngine.cs @@ -24,12 +24,13 @@ using Ombi.Settings.Settings.Models.External; using Ombi.Store.Entities.Requests; using Ombi.Store.Repository; using System.ComponentModel; +using Ombi.Core.Helpers; namespace Ombi.Core.Engine { public class MusicRequestEngine : BaseMediaEngine, IMusicRequestEngine { - public MusicRequestEngine(IRequestServiceMain requestService, IPrincipal user, + public MusicRequestEngine(IRequestServiceMain requestService, ICurrentUser user, INotificationHelper helper, IRuleEvaluator r, ILogger log, OmbiUserManager manager, IRepository rl, ICacheService cache, ISettingsService ombiSettings, IRepository sub, ILidarrApi lidarr, @@ -269,7 +270,10 @@ namespace Ombi.Core.Engine } else { - x.ShowSubscribe = true; + if (!x.Available && (!x.Denied ?? false)) + { + x.ShowSubscribe = true; + } var hasSub = sub.FirstOrDefault(r => r.RequestId == x.Id); x.Subscribed = hasSub != null; } @@ -404,10 +408,20 @@ namespace Ombi.Core.Engine /// /// The request identifier. /// - public async Task RemoveAlbumRequest(int requestId) + public async Task RemoveAlbumRequest(int requestId) { var request = await MusicRepository.GetAll().FirstOrDefaultAsync(x => x.Id == requestId); + + var result = await CheckCanManageRequest(request); + if (result.IsError) + return result; + await MusicRepository.Delete(request); + + return new RequestEngineResult + { + Result = true, + }; } public async Task UserHasRequest(string userId) diff --git a/src/Ombi.Core/Engine/MusicSearchEngine.cs b/src/Ombi.Core/Engine/MusicSearchEngine.cs index 89bae7069..2602bf71e 100644 --- a/src/Ombi.Core/Engine/MusicSearchEngine.cs +++ b/src/Ombi.Core/Engine/MusicSearchEngine.cs @@ -27,7 +27,7 @@ namespace Ombi.Core.Engine { public class MusicSearchEngine : BaseMediaEngine, IMusicSearchEngine { - public MusicSearchEngine(IPrincipal identity, IRequestServiceMain service, ILidarrApi lidarrApi, IMapper mapper, + public MusicSearchEngine(ICurrentUser identity, IRequestServiceMain service, ILidarrApi lidarrApi, IMapper mapper, ILogger logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService s, IRepository sub, ISettingsService lidarrSettings) : base(identity, service, r, um, mem, s, sub) diff --git a/src/Ombi.Core/Engine/RecentlyAddedEngine.cs b/src/Ombi.Core/Engine/RecentlyAddedEngine.cs index d597ec80b..25aba5547 100644 --- a/src/Ombi.Core/Engine/RecentlyAddedEngine.cs +++ b/src/Ombi.Core/Engine/RecentlyAddedEngine.cs @@ -30,26 +30,26 @@ namespace Ombi.Core.Engine public IEnumerable GetRecentlyAddedMovies(DateTime from, DateTime to) { - var plexMovies = _plex.GetAll().Where(x => x.Type == PlexMediaTypeEntity.Movie && x.AddedAt > from && x.AddedAt < to); - var embyMovies = _emby.GetAll().Where(x => x.Type == EmbyMediaType.Movie && x.AddedAt > from && x.AddedAt < to); - var jellyfinMovies = _jellyfin.GetAll().Where(x => x.Type == JellyfinMediaType.Movie && x.AddedAt > from && x.AddedAt < to); + var plexMovies = _plex.GetAll().Where(x => x.Type == MediaType.Movie && x.AddedAt > from && x.AddedAt < to); + var embyMovies = _emby.GetAll().Where(x => x.Type == MediaType.Movie && x.AddedAt > from && x.AddedAt < to); + var jellyfinMovies = _jellyfin.GetAll().Where(x => x.Type == MediaType.Movie && x.AddedAt > from && x.AddedAt < to); return GetRecentlyAddedMovies(plexMovies, embyMovies, jellyfinMovies).Take(30); } public IEnumerable GetRecentlyAddedMovies() { - var plexMovies = _plex.GetAll().Where(x => x.Type == PlexMediaTypeEntity.Movie); - var embyMovies = _emby.GetAll().Where(x => x.Type == EmbyMediaType.Movie); - var jellyfinMovies = _jellyfin.GetAll().Where(x => x.Type == JellyfinMediaType.Movie); + var plexMovies = _plex.GetAll().Where(x => x.Type == MediaType.Movie); + var embyMovies = _emby.GetAll().Where(x => x.Type == MediaType.Movie); + var jellyfinMovies = _jellyfin.GetAll().Where(x => x.Type == MediaType.Movie); return GetRecentlyAddedMovies(plexMovies, embyMovies, jellyfinMovies); } public IEnumerable GetRecentlyAddedTv(DateTime from, DateTime to, bool groupBySeason) { - var plexTv = _plex.GetAll().Include(x => x.Seasons).Include(x => x.Episodes).Where(x => x.Type == PlexMediaTypeEntity.Show && x.AddedAt > from && x.AddedAt < to); - var embyTv = _emby.GetAll().Include(x => x.Episodes).Where(x => x.Type == EmbyMediaType.Series && x.AddedAt > from && x.AddedAt < to); - var jellyfinTv = _jellyfin.GetAll().Include(x => x.Episodes).Where(x => x.Type == JellyfinMediaType.Series && x.AddedAt > from && x.AddedAt < to); + var plexTv = _plex.GetAll().Include(x => x.Seasons).Include(x => x.Episodes).Where(x => x.Type == MediaType.Series && x.AddedAt > from && x.AddedAt < to); + var embyTv = _emby.GetAll().Include(x => x.Episodes).Where(x => x.Type == MediaType.Series && x.AddedAt > from && x.AddedAt < to); + var jellyfinTv = _jellyfin.GetAll().Include(x => x.Episodes).Where(x => x.Type == MediaType.Series && x.AddedAt > from && x.AddedAt < to); return GetRecentlyAddedTv(plexTv, embyTv, jellyfinTv, groupBySeason).Take(30); } @@ -57,9 +57,9 @@ namespace Ombi.Core.Engine public IEnumerable GetRecentlyAddedTv(bool groupBySeason) { - var plexTv = _plex.GetAll().Include(x => x.Seasons).Include(x => x.Episodes).Where(x => x.Type == PlexMediaTypeEntity.Show); - var embyTv = _emby.GetAll().Include(x => x.Episodes).Where(x => x.Type == EmbyMediaType.Series); - var jellyfinTv = _jellyfin.GetAll().Include(x => x.Episodes).Where(x => x.Type == JellyfinMediaType.Series); + var plexTv = _plex.GetAll().Include(x => x.Seasons).Include(x => x.Episodes).Where(x => x.Type == MediaType.Series); + var embyTv = _emby.GetAll().Include(x => x.Episodes).Where(x => x.Type == MediaType.Series); + var jellyfinTv = _jellyfin.GetAll().Include(x => x.Episodes).Where(x => x.Type == MediaType.Series); return GetRecentlyAddedTv(plexTv, embyTv, jellyfinTv, groupBySeason); } @@ -76,7 +76,7 @@ namespace Ombi.Core.Engine { continue; } - if (p.Type == PlexMediaTypeEntity.Movie) + if (p.Type == MediaType.Movie) { recentlyAddedLog.Add(new RecentlyAddedLog { @@ -114,7 +114,7 @@ namespace Ombi.Core.Engine { continue; } - if (e.Type == EmbyMediaType.Movie) + if (e.Type == MediaType.Movie) { recentlyAddedLog.Add(new RecentlyAddedLog { @@ -152,7 +152,7 @@ namespace Ombi.Core.Engine { continue; } - if (e.Type == JellyfinMediaType.Movie) + if (e.Type == MediaType.Movie) { recentlyAddedLog.Add(new RecentlyAddedLog { diff --git a/src/Ombi.Core/Engine/RequestEngineResult.cs b/src/Ombi.Core/Engine/RequestEngineResult.cs index 08c61b7ae..a2f4f93f4 100644 --- a/src/Ombi.Core/Engine/RequestEngineResult.cs +++ b/src/Ombi.Core/Engine/RequestEngineResult.cs @@ -7,7 +7,7 @@ namespace Ombi.Core.Engine { public bool Result { get; set; } public string Message { get; set; } - public bool IsError => !string.IsNullOrEmpty(ErrorMessage); + public bool IsError => ( !string.IsNullOrEmpty(ErrorMessage) || ErrorCode != null ); public string ErrorMessage { get; set; } public ErrorCode? ErrorCode { get; set; } public int RequestId { get; set; } diff --git a/src/Ombi.Core/Engine/TvRequestEngine.cs b/src/Ombi.Core/Engine/TvRequestEngine.cs index fd306f951..8ccc6d17e 100644 --- a/src/Ombi.Core/Engine/TvRequestEngine.cs +++ b/src/Ombi.Core/Engine/TvRequestEngine.cs @@ -32,7 +32,7 @@ namespace Ombi.Core.Engine { public class TvRequestEngine : BaseMediaEngine, ITvRequestEngine { - public TvRequestEngine(ITvMazeApi tvApi, IMovieDbApi movApi, IRequestServiceMain requestService, IPrincipal user, + public TvRequestEngine(ITvMazeApi tvApi, IMovieDbApi movApi, IRequestServiceMain requestService, ICurrentUser user, INotificationHelper helper, IRuleEvaluator rule, OmbiUserManager manager, ILogger logger, ITvSender sender, IRepository rl, ISettingsService settings, ICacheService cache, IRepository sub, IMediaCacheService mediaCacheService) : base(user, requestService, rule, manager, cache, settings, sub) @@ -188,7 +188,7 @@ namespace Ombi.Core.Engine (await tvBuilder .GetShowInfo(tv.TheMovieDbId, tv.languageCode)) .CreateTvList(tv) - .CreateChild(tv, canRequestOnBehalf ? tv.RequestOnBehalf : user.Id); + .CreateChild(tv, canRequestOnBehalf ? tv.RequestOnBehalf : user.Id, tv.Source); await tvBuilder.BuildEpisodes(tv); @@ -710,7 +710,11 @@ namespace Ombi.Core.Engine if (request.Approved) { - await NotificationHelper.Notify(request, NotificationType.RequestApproved); + var canNotify = await RunSpecificRule(request, SpecificRules.CanSendNotification, string.Empty); + if (canNotify.Success) + { + await NotificationHelper.Notify(request, NotificationType.RequestApproved); + } // Autosend await TvSender.Send(request); } @@ -749,10 +753,14 @@ namespace Ombi.Core.Engine return request; } - public async Task RemoveTvChild(int requestId) + public async Task RemoveTvChild(int requestId) { var request = await TvRepository.GetChild().FirstOrDefaultAsync(x => x.Id == requestId); + var result = await CheckCanManageRequest(request); + if (result.IsError) + return result; + TvRepository.Db.ChildRequests.Remove(request); var all = TvRepository.Db.TvRequests.Include(x => x.ChildRequests); var parent = all.FirstOrDefault(x => x.Id == request.ParentRequestId); @@ -766,6 +774,11 @@ namespace Ombi.Core.Engine await TvRepository.Db.SaveChangesAsync(); await _mediaCacheService.Purge(); + + return new RequestEngineResult + { + Result = true, + }; } public async Task RemoveTvRequest(int requestId) @@ -780,7 +793,7 @@ namespace Ombi.Core.Engine return await TvRepository.GetChild().AnyAsync(x => x.RequestedUserId == userId); } - public async Task MarkUnavailable(int modelId) + public async Task MarkUnavailable(int modelId, bool is4K) { var request = await TvRepository.GetChild().FirstOrDefaultAsync(x => x.Id == modelId); if (request == null) @@ -808,7 +821,7 @@ namespace Ombi.Core.Engine }; } - public async Task MarkAvailable(int modelId) + public async Task MarkAvailable(int modelId, bool is4K) { ChildRequests request = await TvRepository.GetChild().FirstOrDefaultAsync(x => x.Id == modelId); if (request == null) @@ -873,7 +886,10 @@ namespace Ombi.Core.Engine } else { - x.ShowSubscribe = true; + if (!x.Available && (!x.Denied ?? true)) + { + x.ShowSubscribe = true; + } var result = relevantSubs.FirstOrDefault(s => s.RequestId == x.Id); x.Subscribed = result != null; } @@ -905,7 +921,7 @@ namespace Ombi.Core.Engine return await AfterRequest(model.ChildRequests.FirstOrDefault(), requestOnBehalf); } - public async Task ReProcessRequest(int requestId, CancellationToken cancellationToken) + public async Task ReProcessRequest(int requestId, bool is4K, CancellationToken cancellationToken) { var request = await TvRepository.GetChild().FirstOrDefaultAsync(x => x.Id == requestId, cancellationToken); if (request == null) @@ -948,7 +964,11 @@ namespace Ombi.Core.Engine if (model.Approved) { // Autosend - await NotificationHelper.Notify(model, NotificationType.RequestApproved); + var canNotify = await RunSpecificRule(model, SpecificRules.CanSendNotification, string.Empty); + if (canNotify.Success) + { + await NotificationHelper.Notify(model, NotificationType.RequestApproved); + } var result = await TvSender.Send(model); if (result.Success) { diff --git a/src/Ombi.Core/Engine/TvSearchEngine.cs b/src/Ombi.Core/Engine/TvSearchEngine.cs index 518b97720..ac2ed9979 100644 --- a/src/Ombi.Core/Engine/TvSearchEngine.cs +++ b/src/Ombi.Core/Engine/TvSearchEngine.cs @@ -23,6 +23,7 @@ using Ombi.Api.TheMovieDb; using Ombi.Api.TheMovieDb.Models; using System.Threading; using TraktSharp.Entities; +using Ombi.Core.Helpers; namespace Ombi.Core.Engine { @@ -32,7 +33,7 @@ namespace Ombi.Core.Engine private readonly IImageService _imageService; private readonly IMovieDbApi _theMovieDbApi; - public TvSearchEngine(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, + public TvSearchEngine(ICurrentUser identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ISettingsService customizationSettings, ICacheService memCache, ISettingsService s, IRepository sub, IImageService imageService, IMovieDbApi theMovieDbApi) @@ -105,11 +106,17 @@ namespace Ombi.Core.Engine SeasonNumber = e.season, Episodes = new List() }; + var hasAirDate = e.airstamp.HasValue(); + var airDate = DateTime.MinValue; + if (hasAirDate) + { + hasAirDate = DateTime.TryParse(e.airdate, out airDate); + } newSeason.Episodes.Add(new EpisodeRequests { Url = e.url.ToHttpsUrl(), Title = e.name, - AirDate = e.airstamp.HasValue() ? DateTime.Parse(e.airstamp) : DateTime.MinValue, + AirDate = airDate, EpisodeNumber = e.number, }); @@ -117,12 +124,18 @@ namespace Ombi.Core.Engine } else { + var hasAirDate = e.airstamp.HasValue(); + var airDate = DateTime.MinValue; + if (hasAirDate) + { + hasAirDate = DateTime.TryParse(e.airdate, out airDate); + } // We already have the season, so just add the episode season.Episodes.Add(new EpisodeRequests { Url = e.url.ToHttpsUrl(), Title = e.name, - AirDate = e.airstamp.HasValue() ? DateTime.Parse(e.airstamp) : DateTime.MinValue, + AirDate = airDate, EpisodeNumber = e.number, }); } diff --git a/src/Ombi.Core/Engine/V2/CalendarEngine.cs b/src/Ombi.Core/Engine/V2/CalendarEngine.cs index b7ecc8ec6..8347141bb 100644 --- a/src/Ombi.Core/Engine/V2/CalendarEngine.cs +++ b/src/Ombi.Core/Engine/V2/CalendarEngine.cs @@ -5,6 +5,7 @@ using System.Security.Principal; using System.Threading.Tasks; using Ombi.Core.Authentication; using Ombi.Core.Engine.Interfaces; +using Ombi.Core.Helpers; using Ombi.Core.Models.Search.V2; using Ombi.Core.Rule.Interfaces; using Ombi.Store.Entities; @@ -17,7 +18,7 @@ namespace Ombi.Core.Engine.V2 { public DateTime DaysAgo => DateTime.Now.AddDays(-90); public DateTime DaysAhead => DateTime.Now.AddDays(90); - public CalendarEngine(IPrincipal user, OmbiUserManager um, IRuleEvaluator rules, IMovieRequestRepository movieRepo, + public CalendarEngine(ICurrentUser user, OmbiUserManager um, IRuleEvaluator rules, IMovieRequestRepository movieRepo, ITvRequestRepository tvRequestRepo) : base(user, um, rules) { _movieRepo = movieRepo; diff --git a/src/Ombi.Core/Engine/V2/IMultiSearchEngine.cs b/src/Ombi.Core/Engine/V2/IMultiSearchEngine.cs index 1b78eaea5..7666db6fe 100644 --- a/src/Ombi.Core/Engine/V2/IMultiSearchEngine.cs +++ b/src/Ombi.Core/Engine/V2/IMultiSearchEngine.cs @@ -3,11 +3,18 @@ using System.Threading; using System.Threading.Tasks; using Ombi.Api.TheMovieDb.Models; using Ombi.Core.Models.Search.V2; +using Ombi.TheMovieDbApi.Models; + +// Due to conflicting Genre models in +// Ombi.TheMovieDbApi.Models and Ombi.Api.TheMovieDb.Models +using Genre = Ombi.TheMovieDbApi.Models.Genre; namespace Ombi.Core.Engine.V2 { public interface IMultiSearchEngine { Task> MultiSearch(string searchTerm, MultiSearchFilter filter, CancellationToken cancellationToken); + Task> GetGenres(string media, CancellationToken requestAborted); + Task> GetLanguages(CancellationToken requestAborted); } } \ No newline at end of file diff --git a/src/Ombi.Core/Engine/V2/IssuesEngine.cs b/src/Ombi.Core/Engine/V2/IssuesEngine.cs index 830dd4295..177ba599e 100644 --- a/src/Ombi.Core/Engine/V2/IssuesEngine.cs +++ b/src/Ombi.Core/Engine/V2/IssuesEngine.cs @@ -33,7 +33,7 @@ namespace Ombi.Core.Engine.V2 public async Task> GetIssues(int position, int take, IssueStatus status, CancellationToken token) { var issues = await _issues.GetAll().Where(x => x.Status == status && x.ProviderId != null).Skip(position).Take(take).OrderBy(x => x.Title).ToListAsync(token); - var grouped = issues.GroupBy(x => x.Title, (key, g) => new { Title = key, Issues = g }); + var grouped = issues.GroupBy(x => new { x.Title, x.ProviderId }, (key, g) => new { key = key, Issues = g }); var model = new List(); @@ -42,8 +42,8 @@ namespace Ombi.Core.Engine.V2 model.Add(new IssuesSummaryModel { Count = group.Issues.Count(), - Title = group.Title, - ProviderId = group.Issues.FirstOrDefault()?.ProviderId + Title = group.key.Title, + ProviderId = group.key.ProviderId }); } diff --git a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs index e865c6465..044d79969 100644 --- a/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/MovieSearchEngineV2.cs @@ -5,11 +5,13 @@ using Ombi.Api.TheMovieDb; using Ombi.Api.TheMovieDb.Models; using Ombi.Core.Authentication; using Ombi.Core.Engine.Interfaces; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Core.Models.Search; using Ombi.Core.Models.Search.V2; using Ombi.Core.Models.UI; using Ombi.Core.Rule.Interfaces; +using Ombi.Core.Services; using Ombi.Core.Settings; using Ombi.Helpers; using Ombi.Settings.Settings.Models; @@ -28,9 +30,10 @@ namespace Ombi.Core.Engine.V2 { public class MovieSearchEngineV2 : BaseMediaEngine, IMovieEngineV2 { - public MovieSearchEngineV2(IPrincipal identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, + public MovieSearchEngineV2(ICurrentUser identity, IRequestServiceMain service, IMovieDbApi movApi, IMapper mapper, ILogger logger, IRuleEvaluator r, OmbiUserManager um, ICacheService mem, ISettingsService s, IRepository sub, - ISettingsService customizationSettings, IMovieRequestEngine movieRequestEngine, IHttpClientFactory httpClientFactory) + ISettingsService customizationSettings, IMovieRequestEngine movieRequestEngine, IHttpClientFactory httpClientFactory, + IFeatureService feature) : base(identity, service, r, um, mem, s, sub) { MovieApi = movApi; @@ -39,6 +42,7 @@ namespace Ombi.Core.Engine.V2 _customizationSettings = customizationSettings; _movieRequestEngine = movieRequestEngine; _client = httpClientFactory.CreateClient(); + _feature = feature; } private IMovieDbApi MovieApi { get; } @@ -47,6 +51,7 @@ namespace Ombi.Core.Engine.V2 private readonly ISettingsService _customizationSettings; private readonly IMovieRequestEngine _movieRequestEngine; private readonly HttpClient _client; + private readonly IFeatureService _feature; public async Task GetFullMovieInformation(int theMovieDbId, CancellationToken cancellationToken, string langCode = null) { @@ -147,15 +152,15 @@ namespace Ombi.Core.Engine.V2 { var langCode = await DefaultLanguageCode(null); - //var pages = PaginationHelper.GetNextPages(currentlyLoaded, toLoad, _theMovieDbMaxPageItems); + var pages = PaginationHelper.GetNextPages(currentlyLoaded, toLoad, _theMovieDbMaxPageItems); var results = new List(); - //foreach (var pagesToLoad in pages) - //{ - var apiResult = await MovieApi.AdvancedSearch(model, cancellationToken); - //results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); - //} - return await TransformMovieResultsToResponse(apiResult); + foreach (var pagesToLoad in pages) + { + var apiResult = await MovieApi.AdvancedSearch(model, pagesToLoad.Page, cancellationToken); + results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); + } + return await TransformMovieResultsToResponse(results); } /// @@ -195,14 +200,19 @@ namespace Ombi.Core.Engine.V2 public async Task> NowPlayingMovies(int currentPosition, int amountToLoad) { var langCode = await DefaultLanguageCode(null); + var isOldTrendingSourceEnabled = await _feature.FeatureEnabled(FeatureNames.OldTrendingSource); var pages = PaginationHelper.GetNextPages(currentPosition, amountToLoad, _theMovieDbMaxPageItems); var results = new List(); foreach (var pagesToLoad in pages) { + var search = () => (isOldTrendingSourceEnabled) ? + MovieApi.NowPlaying(langCode, pagesToLoad.Page) + : MovieApi.TrendingMovies(langCode, pagesToLoad.Page); + var apiResult = await Cache.GetOrAddAsync(nameof(NowPlayingMovies) + pagesToLoad.Page + langCode, - () => MovieApi.NowPlaying(langCode, pagesToLoad.Page), DateTimeOffset.Now.AddHours(12)); + search, DateTimeOffset.Now.AddHours(12)); results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); } return await TransformMovieResultsToResponse(results); @@ -277,7 +287,7 @@ namespace Ombi.Core.Engine.V2 var result = await Cache.GetOrAddAsync(CacheKeys.UpcomingMovies, async () => { var langCode = await DefaultLanguageCode(null); - return await MovieApi.Upcoming(langCode); + return await MovieApi.UpcomingMovies(langCode); }, DateTimeOffset.Now.AddHours(12)); if (result != null) { @@ -297,7 +307,7 @@ namespace Ombi.Core.Engine.V2 foreach (var pagesToLoad in pages) { var apiResult = await Cache.GetOrAddAsync(nameof(UpcomingMovies) + pagesToLoad.Page + langCode, - () => MovieApi.Upcoming(langCode, pagesToLoad.Page), DateTimeOffset.Now.AddHours(12)); + () => MovieApi.UpcomingMovies(langCode, pagesToLoad.Page), DateTimeOffset.Now.AddHours(12)); results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); } return await TransformMovieResultsToResponse(results); @@ -323,6 +333,7 @@ namespace Ombi.Core.Engine.V2 public async Task GetMoviesByActor(int actorId, string langCode) { + langCode = await DefaultLanguageCode(langCode); var result = await Cache.GetOrAddAsync(nameof(GetMoviesByActor) + actorId + langCode, () => MovieApi.GetActorMovieCredits(actorId, langCode), DateTimeOffset.Now.AddHours(12)); // Later we run this through the rules engine @@ -391,20 +402,25 @@ namespace Ombi.Core.Engine.V2 await RunSearchRules(viewMovie); - // This requires the rules to be run first to populate the RequestId property - await CheckForSubscription(viewMovie); var mapped = Mapper.Map(movie); mapped.Available = viewMovie.Available; mapped.Approved = viewMovie.Approved; + mapped.Denied = viewMovie.Denied; + mapped.DeniedReason = viewMovie.DeniedReason; mapped.RequestId = viewMovie.RequestId; mapped.Requested = viewMovie.Requested; mapped.PlexUrl = viewMovie.PlexUrl; mapped.EmbyUrl = viewMovie.EmbyUrl; mapped.JellyfinUrl = viewMovie.JellyfinUrl; - mapped.Subscribed = viewMovie.Subscribed; - mapped.ShowSubscribe = viewMovie.ShowSubscribe; mapped.DigitalReleaseDate = viewMovie.DigitalReleaseDate; + mapped.RequestedDate4k = viewMovie.RequestedDate4k; + mapped.Approved4K = viewMovie.Approved4K; + mapped.Available4K = viewMovie.Available4K; + mapped.Denied4K = viewMovie.Denied4K; + mapped.DeniedReason4K = viewMovie.DeniedReason4K; + mapped.Has4KRequest = viewMovie.Has4KRequest; + return mapped; } @@ -418,8 +434,6 @@ namespace Ombi.Core.Engine.V2 var mappedMovie = Mapper.Map(movie); await RunSearchRules(mappedMovie); - // This requires the rules to be run first to populate the RequestId property - await CheckForSubscription(mappedMovie); var mapped = Mapper.Map(movie); mapped.Available = movie.Available; @@ -429,8 +443,6 @@ namespace Ombi.Core.Engine.V2 mapped.PlexUrl = movie.PlexUrl; mapped.EmbyUrl = movie.EmbyUrl; mapped.JellyfinUrl = movie.JellyfinUrl; - mapped.Subscribed = movie.Subscribed; - mapped.ShowSubscribe = movie.ShowSubscribe; mapped.ReleaseDate = movie.ReleaseDate; } return viewMovie; @@ -459,34 +471,9 @@ namespace Ombi.Core.Engine.V2 await RunSearchRules(viewMovie); - // This requires the rules to be run first to populate the RequestId property - await CheckForSubscription(viewMovie); - return viewMovie; } - private async Task CheckForSubscription(SearchViewModel viewModel) - { - // Check if this user requested it - var user = await GetUser(); - if (user == null) - { - return; - } - var request = await RequestService.MovieRequestService.GetAll() - .AnyAsync(x => x.RequestedUserId.Equals(user.Id) && x.TheMovieDbId == viewModel.Id); - if (request) - { - viewModel.ShowSubscribe = false; - } - else - { - viewModel.ShowSubscribe = true; - var sub = await _subscriptionRepository.GetAll().FirstOrDefaultAsync(s => s.UserId == user.Id - && s.RequestId == viewModel.RequestId && s.RequestType == RequestType.Movie); - viewModel.Subscribed = sub != null; - } - } public async Task GetMovieInfoByImdbId(string imdbId, CancellationToken cancellationToken) { diff --git a/src/Ombi.Core/Engine/V2/MultiSearchEngine.cs b/src/Ombi.Core/Engine/V2/MultiSearchEngine.cs index fc2595676..3f96f1598 100644 --- a/src/Ombi.Core/Engine/V2/MultiSearchEngine.cs +++ b/src/Ombi.Core/Engine/V2/MultiSearchEngine.cs @@ -7,6 +7,7 @@ using Ombi.Api.MusicBrainz; using Ombi.Api.TheMovieDb; using Ombi.Api.TheMovieDb.Models; using Ombi.Core.Authentication; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Core.Models.Search.V2; using Ombi.Core.Rule.Interfaces; @@ -16,12 +17,17 @@ using Ombi.Settings.Settings.Models; using Ombi.Settings.Settings.Models.External; using Ombi.Store.Entities; using Ombi.Store.Repository; +using Ombi.TheMovieDbApi.Models; + +// Due to conflicting Genre models in +// Ombi.TheMovieDbApi.Models and Ombi.Api.TheMovieDb.Models +using Genre = Ombi.TheMovieDbApi.Models.Genre; namespace Ombi.Core.Engine.V2 { public class MultiSearchEngine : BaseMediaEngine, IMultiSearchEngine { - public MultiSearchEngine(IPrincipal identity, IRequestServiceMain requestService, IRuleEvaluator rules, + public MultiSearchEngine(ICurrentUser identity, IRequestServiceMain requestService, IRuleEvaluator rules, OmbiUserManager um, ICacheService cache, ISettingsService ombiSettings, IRepository sub, IMovieDbApi movieDbApi, ISettingsService lidarrSettings, IMusicBrainzApi musicApi) : base(identity, requestService, rules, um, cache, ombiSettings, sub) @@ -113,5 +119,15 @@ namespace Ombi.Core.Engine.V2 return model; } + + public async Task> GetGenres(string media, CancellationToken cancellationToken) + { + var lang = await DefaultLanguageCode(null); + return await _movieDbApi.GetGenres(media, cancellationToken, lang); + } + public async Task> GetLanguages(CancellationToken cancellationToken) + { + return await _movieDbApi.GetLanguages(cancellationToken); + } } } diff --git a/src/Ombi.Core/Engine/V2/MusicSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/MusicSearchEngineV2.cs index b7d9575db..fc3fcf40e 100644 --- a/src/Ombi.Core/Engine/V2/MusicSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/MusicSearchEngineV2.cs @@ -11,6 +11,7 @@ using Ombi.Api.Lidarr.Models; using Ombi.Api.MusicBrainz; using Ombi.Core.Authentication; using Ombi.Core.Engine.Interfaces; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Core.Models.Search.V2.Music; using Ombi.Core.Rule.Interfaces; @@ -31,7 +32,7 @@ namespace Ombi.Core.Engine.V2 private readonly ISettingsService _lidarrSettings; private readonly ILidarrApi _lidarrApi; - public MusicSearchEngineV2(IPrincipal identity, IRequestServiceMain requestService, IRuleEvaluator rules, + public MusicSearchEngineV2(ICurrentUser identity, IRequestServiceMain requestService, IRuleEvaluator rules, OmbiUserManager um, ICacheService cache, ISettingsService ombiSettings, IRepository sub, IMusicBrainzApi musicBrainzApi, ISettingsService lidarrSettings, ILidarrApi lidarrApi) diff --git a/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs b/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs index 26cba7c14..ee21db8dd 100644 --- a/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs +++ b/src/Ombi.Core/Engine/V2/TvSearchEngineV2.cs @@ -25,6 +25,8 @@ using Ombi.Api.TheMovieDb.Models; using System.Diagnostics; using Ombi.Core.Engine.Interfaces; using Ombi.Core.Models.UI; +using Ombi.Core.Helpers; +using Ombi.Core.Services; namespace Ombi.Core.Engine.V2 { @@ -36,10 +38,12 @@ namespace Ombi.Core.Engine.V2 private readonly IMovieDbApi _movieApi; private readonly ISettingsService _customization; private readonly ITvRequestEngine _requestEngine; + private readonly IFeatureService _feature; - public TvSearchEngineV2(IPrincipal identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, + public TvSearchEngineV2(ICurrentUser identity, IRequestServiceMain service, ITvMazeApi tvMaze, IMapper mapper, ITraktApi trakt, IRuleEvaluator r, OmbiUserManager um, ICacheService memCache, ISettingsService s, - IRepository sub, IMovieDbApi movieApi, ISettingsService customization, ITvRequestEngine requestEngine) + IRepository sub, IMovieDbApi movieApi, ISettingsService customization, ITvRequestEngine requestEngine, + IFeatureService feature) : base(identity, service, r, um, memCache, s, sub) { _tvMaze = tvMaze; @@ -48,6 +52,7 @@ namespace Ombi.Core.Engine.V2 _movieApi = movieApi; _customization = customization; _requestEngine = requestEngine; + _feature = feature; } @@ -89,7 +94,7 @@ namespace Ombi.Core.Engine.V2 foreach (var tvSeason in show.seasons.Where(x => x.season_number != 0)) // skip the first season { - var seasonEpisodes = (await _movieApi.GetSeasonEpisodes(show.id, tvSeason.season_number, token)); + var seasonEpisodes = (await _movieApi.GetSeasonEpisodes(show.id, tvSeason.season_number, token, langCode)); MapSeasons(mapped.SeasonRequests, tvSeason, seasonEpisodes); } @@ -131,15 +136,19 @@ namespace Ombi.Core.Engine.V2 } public async Task> Trending(int currentlyLoaded, int amountToLoad) - { + { var langCode = await DefaultLanguageCode(null); + var isOldTrendingSourceEnabled = await _feature.FeatureEnabled(FeatureNames.OldTrendingSource); var pages = PaginationHelper.GetNextPages(currentlyLoaded, amountToLoad, ResultLimit); var results = new List(); foreach (var pagesToLoad in pages) { + var search = ( async () => (isOldTrendingSourceEnabled) ? + await _movieApi.TopRatedTv(langCode, pagesToLoad.Page) + : await _movieApi.TrendingTv(langCode, pagesToLoad.Page)); var apiResult = await Cache.GetOrAddAsync(nameof(Trending) + langCode + pagesToLoad.Page, - async () => await _movieApi.TopRatedTv(langCode, pagesToLoad.Page), DateTimeOffset.Now.AddHours(12)); + search, DateTimeOffset.Now.AddHours(12)); results.AddRange(apiResult.Skip(pagesToLoad.Skip).Take(pagesToLoad.Take)); } @@ -147,6 +156,13 @@ namespace Ombi.Core.Engine.V2 return await processed; } + public async Task GetTvByActor(int actorId, string langCode) + { + langCode = await DefaultLanguageCode(langCode); + var result = await Cache.GetOrAddAsync(nameof(GetTvByActor) + actorId + langCode, + () => _movieApi.GetActorTvCredits(actorId, langCode), DateTimeOffset.Now.AddHours(12)); + return result; + } public async Task> GetStreamInformation(int movieDbId, CancellationToken cancellationToken) { @@ -256,11 +272,17 @@ namespace Ombi.Core.Engine.V2 Overview = tvSeason.overview, Episodes = new List() }; + var hasAirDate = episode.air_date.HasValue(); + var airDate = DateTime.MinValue; + if (hasAirDate) + { + DateTime.TryParse(episode.air_date, out airDate); + } newSeason.Episodes.Add(new EpisodeRequests { //Url = episode...ToHttpsUrl(), Title = episode.name, - AirDate = episode.air_date.HasValue() ? DateTime.Parse(episode.air_date) : DateTime.MinValue, + AirDate = airDate, EpisodeNumber = episode.episode_number, }); @@ -268,12 +290,18 @@ namespace Ombi.Core.Engine.V2 } else { + var hasAirDate = episode.air_date.HasValue(); + var airDate = DateTime.MinValue; + if (hasAirDate) + { + DateTime.TryParse(episode.air_date, out airDate); + } // We already have the season, so just add the episode season.Episodes.Add(new EpisodeRequests { //Url = e.url.ToHttpsUrl(), Title = episode.name, - AirDate = episode.air_date.HasValue() ? DateTime.Parse(episode.air_date) : DateTime.MinValue, + AirDate = airDate, EpisodeNumber = episode.episode_number, }); } @@ -300,6 +328,8 @@ namespace Ombi.Core.Engine.V2 item.PartlyAvailable = oldModel.PartlyAvailable; item.Requested = oldModel.Requested; item.Available = oldModel.Available; + item.Denied = oldModel.Denied; + item.DeniedReason = oldModel.DeniedReason; item.Approved = oldModel.Approved; item.SeasonRequests = oldModel.SeasonRequests; item.RequestId = oldModel.RequestId; diff --git a/src/Ombi.Core/Engine/VoteEngine.cs b/src/Ombi.Core/Engine/VoteEngine.cs index 5c73e03d9..3e7f6f542 100644 --- a/src/Ombi.Core/Engine/VoteEngine.cs +++ b/src/Ombi.Core/Engine/VoteEngine.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Ombi.Core.Authentication; using Ombi.Core.Engine.Interfaces; +using Ombi.Core.Helpers; using Ombi.Core.Models; using Ombi.Core.Models.UI; using Ombi.Core.Rule.Interfaces; @@ -20,7 +21,7 @@ namespace Ombi.Core.Engine { public class VoteEngine : BaseEngine, IVoteEngine { - public VoteEngine(IRepository votes, IPrincipal user, OmbiUserManager um, IRuleEvaluator r, ISettingsService voteSettings, + public VoteEngine(IRepository votes, ICurrentUser user, OmbiUserManager um, IRuleEvaluator r, ISettingsService voteSettings, IMusicRequestEngine musicRequestEngine, ITvRequestEngine tvRequestEngine, IMovieRequestEngine movieRequestEngine) : base(user, um, r) { _voteRepository = votes; @@ -193,7 +194,7 @@ namespace Ombi.Core.Engine case RequestType.Movie: if (totalVotes >= voteSettings.MovieVoteMax) { - result = await _movieRequestEngine.ApproveMovieById(requestId); + result = await _movieRequestEngine.ApproveMovieById(requestId, false); } break; case RequestType.Album: diff --git a/src/Ombi.Core/Helpers/CurrentUser.cs b/src/Ombi.Core/Helpers/CurrentUser.cs new file mode 100644 index 000000000..974d59cd6 --- /dev/null +++ b/src/Ombi.Core/Helpers/CurrentUser.cs @@ -0,0 +1,47 @@ +using Microsoft.EntityFrameworkCore; +using Ombi.Core.Authentication; +using Ombi.Helpers; +using Ombi.Store.Entities; +using System.Security.Principal; +using System.Threading.Tasks; + +namespace Ombi.Core.Helpers +{ + public class CurrentUser : ICurrentUser + { + private readonly IPrincipal _principle; + private readonly OmbiUserManager _userManager; + private OmbiUser _user; + public IIdentity Identity { get; set; } + + public CurrentUser(IPrincipal principle, OmbiUserManager userManager) + { + _principle = principle; + _userManager = userManager; + Identity = _principle?.Identity ?? null; + } + + public void SetUser(OmbiUser user) + { + _user = user; + } + + public string Username => Identity?.Name ?? _user?.UserName; + public async Task GetUser() + { + if (!Username.HasValue() && _user == null) + { + return null; + } + + if (_user != null) + { + return _user; + } + + var username = Username.ToUpper(); + return _user ??= await _userManager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username); + } + + } +} diff --git a/src/Ombi.Core/Helpers/ICurrentUser.cs b/src/Ombi.Core/Helpers/ICurrentUser.cs new file mode 100644 index 000000000..1cce973f3 --- /dev/null +++ b/src/Ombi.Core/Helpers/ICurrentUser.cs @@ -0,0 +1,15 @@ +using Ombi.Store.Entities; +using System.Security.Principal; +using System.Threading.Tasks; + +namespace Ombi.Core.Helpers +{ + public interface ICurrentUser + { + string Username { get; } + + Task GetUser(); + void SetUser(OmbiUser user); + IIdentity Identity { get; set; } + } +} \ No newline at end of file diff --git a/src/Ombi.Core/Helpers/TvShowRequestBuilder.cs b/src/Ombi.Core/Helpers/TvShowRequestBuilder.cs index fc66d197d..5fe378465 100644 --- a/src/Ombi.Core/Helpers/TvShowRequestBuilder.cs +++ b/src/Ombi.Core/Helpers/TvShowRequestBuilder.cs @@ -261,9 +261,16 @@ namespace Ombi.Core.Helpers return this; } - private DateTime FormatDate(string date) + private static DateTime FormatDate(string date) { - return string.IsNullOrEmpty(date) ? DateTime.MinValue : DateTime.Parse(date); + if (date.HasValue()) + { + if (DateTime.TryParse(date, out var d)) + { + return d; + } + } + return DateTime.MinValue; } } } \ No newline at end of file diff --git a/src/Ombi.Core/Helpers/TvShowRequestBuilderV2.cs b/src/Ombi.Core/Helpers/TvShowRequestBuilderV2.cs index 6843332c0..5bb4e61fd 100644 --- a/src/Ombi.Core/Helpers/TvShowRequestBuilderV2.cs +++ b/src/Ombi.Core/Helpers/TvShowRequestBuilderV2.cs @@ -9,6 +9,7 @@ using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; using Ombi.Store.Repository.Requests; using System.Threading; +using Ombi.Helpers; namespace Ombi.Core.Helpers { @@ -53,7 +54,7 @@ namespace Ombi.Core.Helpers return this; } - public TvShowRequestBuilderV2 CreateChild(TvRequestViewModelV2 model, string userId) + public TvShowRequestBuilderV2 CreateChild(TvRequestViewModelV2 model, string userId, RequestSource source) { var animationGenre = TheMovieDbRecord.genres?.Any(s => s.name.Equals("Animation", StringComparison.InvariantCultureIgnoreCase)) ?? false; var animeKeyword = TheMovieDbRecord.Keywords?.KeywordsValue?.Any(s => s.Name.Equals("Anime", StringComparison.InvariantCultureIgnoreCase)) ?? false; @@ -68,7 +69,8 @@ namespace Ombi.Core.Helpers Title = TheMovieDbRecord.name, ReleaseYear = FirstAir, RequestedByAlias = model.RequestedByAlias, - SeriesType = animationGenre && animeKeyword ? SeriesType.Anime : SeriesType.Standard + SeriesType = animationGenre && animeKeyword ? SeriesType.Anime : SeriesType.Standard, + Source = source }; return this; @@ -254,9 +256,16 @@ namespace Ombi.Core.Helpers return this; } - private DateTime FormatDate(string date) + private static DateTime FormatDate(string date) { - return string.IsNullOrEmpty(date) ? DateTime.MinValue : DateTime.Parse(date); + if (date.HasValue()) + { + if (DateTime.TryParse(date, out var d)) + { + return d; + } + } + return DateTime.MinValue; } } } \ No newline at end of file diff --git a/src/Ombi.Core/Models/MassEmailModel.cs b/src/Ombi.Core/Models/MassEmailModel.cs index ad09f0cb9..e175c0886 100644 --- a/src/Ombi.Core/Models/MassEmailModel.cs +++ b/src/Ombi.Core/Models/MassEmailModel.cs @@ -35,6 +35,8 @@ namespace Ombi.Core.Models public string Subject { get; set; } public string Body { get; set; } + public bool Bcc { get; set; } + public List Users { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Core/Models/Requests/MovieRequestViewModel.cs b/src/Ombi.Core/Models/Requests/MovieRequestViewModel.cs index 05eec3e3f..18125ed71 100644 --- a/src/Ombi.Core/Models/Requests/MovieRequestViewModel.cs +++ b/src/Ombi.Core/Models/Requests/MovieRequestViewModel.cs @@ -1,31 +1,5 @@ -#region Copyright -// /************************************************************************ -// Copyright (c) 2018 Jamie Rees -// File: MovieRequestViewModel.cs -// Created By: Jamie Rees -// -// Permission is hereby granted, free of charge, to any person obtaining -// a copy of this software and associated documentation files (the -// "Software"), to deal in the Software without restriction, including -// without limitation the rights to use, copy, modify, merge, publish, -// distribute, sublicense, and/or sell copies of the Software, and to -// permit persons to whom the Software is furnished to do so, subject to -// the following conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// ************************************************************************/ -#endregion - -using Newtonsoft.Json; +using Newtonsoft.Json; +using Ombi.Store.Entities.Requests; namespace Ombi.Core.Models.Requests { @@ -34,10 +8,18 @@ namespace Ombi.Core.Models.Requests public int TheMovieDbId { get; set; } public string LanguageCode { get; set; } = "en"; + public bool Is4kRequest { get; set; } + /// /// This is only set from a HTTP Header /// [JsonIgnore] public string RequestedByAlias { get; set; } + + /// + /// Only set via list imports + /// + [JsonIgnore] + public RequestSource Source { get; set; } = RequestSource.Ombi; } } \ No newline at end of file diff --git a/src/Ombi.Core/Models/Requests/TvRequestViewModelV2.cs b/src/Ombi.Core/Models/Requests/TvRequestViewModelV2.cs index a9742fb32..e1df9553f 100644 --- a/src/Ombi.Core/Models/Requests/TvRequestViewModelV2.cs +++ b/src/Ombi.Core/Models/Requests/TvRequestViewModelV2.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Newtonsoft.Json; +using Ombi.Store.Entities.Requests; namespace Ombi.Core.Models.Requests { @@ -7,5 +8,6 @@ namespace Ombi.Core.Models.Requests { public int TheMovieDbId { get; set; } public string languageCode { get; set; } = "en"; + public RequestSource Source { get; set; } = RequestSource.Ombi; } } \ No newline at end of file diff --git a/src/Ombi.Core/Models/Search/SearchMovieViewModel.cs b/src/Ombi.Core/Models/Search/SearchMovieViewModel.cs index 4d0d05a49..10cc76404 100644 --- a/src/Ombi.Core/Models/Search/SearchMovieViewModel.cs +++ b/src/Ombi.Core/Models/Search/SearchMovieViewModel.cs @@ -28,5 +28,14 @@ namespace Ombi.Core.Models.Search public override RequestType Type => RequestType.Movie; public ReleaseDatesDto ReleaseDates { get; set; } public DateTime? DigitalReleaseDate { get; set; } + public bool Has4KRequest { get; set; } + public bool Approved4K { get; set; } + public DateTime MarkedAsApproved4K { get; set; } + public DateTime RequestedDate4k { get; set; } + public bool Available4K { get; set; } + public DateTime? MarkedAsAvailable4K { get; set; } + public bool? Denied4K { get; set; } + public DateTime MarkedAsDenied4K { get; set; } + public string DeniedReason4K { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Core/Models/Search/SearchViewModel.cs b/src/Ombi.Core/Models/Search/SearchViewModel.cs index 4cf812982..4dda0444e 100644 --- a/src/Ombi.Core/Models/Search/SearchViewModel.cs +++ b/src/Ombi.Core/Models/Search/SearchViewModel.cs @@ -1,4 +1,5 @@ -using System.ComponentModel.DataAnnotations.Schema; +using System; +using System.ComponentModel.DataAnnotations.Schema; using Ombi.Store.Entities; namespace Ombi.Core.Models.Search @@ -32,8 +33,10 @@ namespace Ombi.Core.Models.Search public string TheMovieDbId { get; set; } [NotMapped] + [Obsolete("Use request service instead")] public bool Subscribed { get; set; } [NotMapped] + [Obsolete("Use request service instead")] public bool ShowSubscribe { get; set; } } } diff --git a/src/Ombi.Core/Models/Search/V2/MovieFullInfoViewModel.cs b/src/Ombi.Core/Models/Search/V2/MovieFullInfoViewModel.cs index 8e8dac9b1..847780e57 100644 --- a/src/Ombi.Core/Models/Search/V2/MovieFullInfoViewModel.cs +++ b/src/Ombi.Core/Models/Search/V2/MovieFullInfoViewModel.cs @@ -41,6 +41,15 @@ namespace Ombi.Core.Models.Search.V2 public Recommendations Recommendations { get; set; } public ExternalIds ExternalIds { get; set; } public Keywords Keywords { get; set; } + public bool Has4KRequest { get; set; } + public bool Approved4K { get; set; } + public DateTime MarkedAsApproved4K { get; set; } + public DateTime RequestedDate4k { get; set; } + public bool Available4K { get; set; } + public DateTime? MarkedAsAvailable4K { get; set; } + public bool? Denied4K { get; set; } + public DateTime MarkedAsDenied4K { get; set; } + public string DeniedReason4K { get; set; } } public class Keywords { diff --git a/src/Ombi.Core/Ombi.Core.csproj b/src/Ombi.Core/Ombi.Core.csproj index 857de0bab..67ecdbe13 100644 --- a/src/Ombi.Core/Ombi.Core.csproj +++ b/src/Ombi.Core/Ombi.Core.csproj @@ -1,20 +1,20 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild - - + + @@ -36,6 +36,7 @@ + diff --git a/src/Ombi.Core/Rule/Rules/Request/AutoApproveRule.cs b/src/Ombi.Core/Rule/Rules/Request/AutoApproveRule.cs index f427434f0..23d26625b 100644 --- a/src/Ombi.Core/Rule/Rules/Request/AutoApproveRule.cs +++ b/src/Ombi.Core/Rule/Rules/Request/AutoApproveRule.cs @@ -3,9 +3,12 @@ using System.Security.Principal; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Ombi.Core.Authentication; +using Ombi.Core.Helpers; using Ombi.Core.Models.Requests; using Ombi.Core.Rule.Interfaces; +using Ombi.Core.Services; using Ombi.Helpers; +using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; @@ -13,32 +16,58 @@ namespace Ombi.Core.Rule.Rules.Request { public class AutoApproveRule : BaseRequestRule, IRules { - public AutoApproveRule(IPrincipal principal, OmbiUserManager um) + public AutoApproveRule(ICurrentUser principal, OmbiUserManager um, IFeatureService featureService) { User = principal; _manager = um; + _featureService = featureService; } - private IPrincipal User { get; } + private ICurrentUser User { get; } private readonly OmbiUserManager _manager; + private readonly IFeatureService _featureService; public async Task Execute(BaseRequest obj) { - var username = User.Identity.Name.ToUpper(); + var currentUser = await User.GetUser(); + var username = currentUser.UserName.ToUpper(); var user = await _manager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username); if (await _manager.IsInRoleAsync(user, OmbiRoles.Admin) || user.IsSystemUser) { - obj.Approved = true; + if (obj is MovieRequests movie) + { + await Check4K(movie); + } + else + { + obj.Approved = true; + } return Success(); } if (obj.RequestType == RequestType.Movie && await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveMovie)) - obj.Approved = true; + { + var movie = (MovieRequests)obj; + await Check4K(movie); + } if (obj.RequestType == RequestType.TvShow && await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveTv)) obj.Approved = true; if (obj.RequestType == RequestType.Album && await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveMusic)) obj.Approved = true; return Success(); // We don't really care, we just don't set the obj to approve } + + private async Task Check4K(MovieRequests movie) + { + var featureEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests); + if (movie.Is4kRequest && featureEnabled) + { + movie.Approved4K = true; + } + else + { + movie.Approved = true; + } + } } } \ No newline at end of file diff --git a/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs b/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs index 1c720a385..e2e81e612 100644 --- a/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs +++ b/src/Ombi.Core/Rule/Rules/Request/CanRequestRule.cs @@ -10,31 +10,48 @@ using Ombi.Core.Engine; using Ombi.Core.Rule.Interfaces; using Ombi.Helpers; using Ombi.Store.Entities.Requests; +using Ombi.Core.Helpers; namespace Ombi.Core.Rule.Rules.Request { public class CanRequestRule : BaseRequestRule, IRules { - public CanRequestRule(IPrincipal principal, OmbiUserManager manager) + public CanRequestRule(ICurrentUser principal, OmbiUserManager manager) { User = principal; _manager = manager; } - private IPrincipal User { get; } + private ICurrentUser User { get; } private readonly OmbiUserManager _manager; public async Task Execute(BaseRequest obj) { - var username = User.Identity.Name.ToUpper(); + var currentUser = await User.GetUser(); + var username = currentUser.UserName.ToUpper(); var user = await _manager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username); if (await _manager.IsInRoleAsync(user, OmbiRoles.Admin) || user.IsSystemUser) return Success(); if (obj.RequestType == RequestType.Movie) { - if (await _manager.IsInRoleAsync(user, OmbiRoles.RequestMovie) || await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveMovie)) - return Success(); + var movie = (MovieRequests)obj; + var hasAutoApprove = await _manager.IsInRoleAsync(user, OmbiRoles.AutoApproveMovie); + if (await _manager.IsInRoleAsync(user, OmbiRoles.RequestMovie) || hasAutoApprove) + { + if (movie.Is4kRequest && !hasAutoApprove) + { + var has4kPermission = await _manager.IsInRoleAsync(user, OmbiRoles.Request4KMovie); + if (has4kPermission) + { + return Success(); + } + } + else + { + return Success(); + } + } return Fail(ErrorCode.NoPermissionsRequestMovie, "You do not have permissions to Request a Movie"); } diff --git a/src/Ombi.Core/Rule/Rules/Request/ExistingMovieRequestRule.cs b/src/Ombi.Core/Rule/Rules/Request/ExistingMovieRequestRule.cs index c837c42d1..17533a570 100644 --- a/src/Ombi.Core/Rule/Rules/Request/ExistingMovieRequestRule.cs +++ b/src/Ombi.Core/Rule/Rules/Request/ExistingMovieRequestRule.cs @@ -1,21 +1,24 @@ -using System; -using System.Threading.Tasks; +using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Ombi.Core.Rule.Interfaces; using Ombi.Helpers; using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; -using Ombi.Store.Repository; using Ombi.Core.Engine; using Ombi.Store.Repository.Requests; +using Ombi.Core.Services; +using Ombi.Settings.Settings.Models; namespace Ombi.Core.Rule.Rules.Request { public class ExistingMovieRequestRule : BaseRequestRule, IRules { - public ExistingMovieRequestRule(IMovieRequestRepository movie) + private readonly IFeatureService _featureService; + + public ExistingMovieRequestRule(IMovieRequestRepository movie, IFeatureService featureService) { Movie = movie; + _featureService = featureService; } private IMovieRequestRepository Movie { get; } @@ -35,7 +38,7 @@ namespace Ombi.Core.Rule.Rules.Request var existing = await movieRequests.FirstOrDefaultAsync(x => x.TheMovieDbId == movie.TheMovieDbId); if (existing != null) // Do we already have a request for this? { - found = true; + found = await Check4KRequests(movie, existing); } if (!found && movie.ImdbId.HasValue()) @@ -45,15 +48,30 @@ namespace Ombi.Core.Rule.Rules.Request x.ImdbId == movie.ImdbId); if (existing != null) { - found = true; + found = await Check4KRequests(movie, existing); } } - if(found) + if (found) { return Fail(ErrorCode.AlreadyRequested, $"\"{obj.Title}\" has already been requested"); } } return Success(); } + + private async Task Check4KRequests(MovieRequests movie, MovieRequests existing) + { + var featureEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests); + if (movie.Is4kRequest && existing.Has4KRequest && featureEnabled) + { + return true; + } + if (!movie.Is4kRequest && !existing.Has4KRequest || !featureEnabled) + { + return true; + } + + return false; + } } } \ No newline at end of file diff --git a/src/Ombi.Core/Rule/Rules/Request/ExistingPlexRequestRule.cs b/src/Ombi.Core/Rule/Rules/Request/ExistingPlexRequestRule.cs index ef38fb973..4f32c2eb8 100644 --- a/src/Ombi.Core/Rule/Rules/Request/ExistingPlexRequestRule.cs +++ b/src/Ombi.Core/Rule/Rules/Request/ExistingPlexRequestRule.cs @@ -32,7 +32,7 @@ namespace Ombi.Core.Rule.Rules.Request { var tvRequest = (ChildRequests) obj; - var tvContent = _plexContent.GetAll().Include(x => x.Episodes).Where(x => x.Type == PlexMediaTypeEntity.Show); + var tvContent = _plexContent.GetAll().Include(x => x.Episodes).Where(x => x.Type == MediaType.Series); // We need to do a check on the TVDBId var anyMovieDbMatches = await tvContent.FirstOrDefaultAsync(x => x.TheMovieDbId.Length > 0 && x.TheMovieDbId == tvRequest.Id.ToString()); if (anyMovieDbMatches == null) @@ -54,6 +54,15 @@ namespace Ombi.Core.Rule.Rules.Request // looks like we have a match on the TVDbID return CheckExistingContent(tvRequest, anyMovieDbMatches); } + if (obj.RequestType == RequestType.Movie) + { + var movie = (MovieRequests)obj; + var exists = _plexContent.GetAll().Where(x => x.Type == MediaType.Movie).Any(x => x.TheMovieDbId == movie.Id.ToString() || x.TheMovieDbId == movie.TheMovieDbId.ToString()); + if (exists) + { + return Fail(ErrorCode.AlreadyRequested, "This movie is already available." ); + } + } return Success(); } diff --git a/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs b/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs index fe062e851..630e4ac81 100644 --- a/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs +++ b/src/Ombi.Core/Rule/Rules/Search/AvailabilityRuleHelper.cs @@ -46,10 +46,10 @@ namespace Ombi.Core.Rule.Rules.Search } } - public static async Task SingleEpisodeCheck(bool useImdb, IQueryable allEpisodes, EpisodeRequests episode, - SeasonRequests season, PlexServerContent item, bool useTheMovieDb, bool useTvDb, ILogger log) + public static async Task SingleEpisodeCheck(bool useImdb, IQueryable allEpisodes, EpisodeRequests episode, + SeasonRequests season, IMediaServerContent item, bool useTheMovieDb, bool useTvDb, ILogger log) { - PlexEpisode epExists = null; + IMediaServerEpisode epExists = null; try { @@ -79,66 +79,6 @@ namespace Ombi.Core.Rule.Rules.Search log.LogError(e, "Exception thrown when attempting to check if something is available"); } - if (epExists != null) - { - episode.Available = true; - } - } - public static async Task SingleEpisodeCheck(bool useImdb, IQueryable allEpisodes, EpisodeRequests episode, - SeasonRequests season, EmbyContent item, bool useTheMovieDb, bool useTvDb) - { - EmbyEpisode epExists = null; - if (useImdb) - { - epExists = await allEpisodes.FirstOrDefaultAsync(x => - x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.ImdbId == item.ImdbId); - } - - if (useTheMovieDb) - { - epExists = await allEpisodes.FirstOrDefaultAsync(x => - x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.TheMovieDbId == item.TheMovieDbId); - } - - if (useTvDb) - { - epExists = await allEpisodes.FirstOrDefaultAsync(x => - x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.TvDbId == item.TvDbId); - } - - if (epExists != null) - { - episode.Available = true; - } - } - public static async Task SingleEpisodeCheck(bool useImdb, IQueryable allEpisodes, EpisodeRequests episode, - SeasonRequests season, JellyfinContent item, bool useTheMovieDb, bool useTvDb) - { - JellyfinEpisode epExists = null; - if (useImdb) - { - epExists = await allEpisodes.FirstOrDefaultAsync(x => - x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.ImdbId == item.ImdbId); - } - - if (useTheMovieDb) - { - epExists = await allEpisodes.FirstOrDefaultAsync(x => - x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.TheMovieDbId == item.TheMovieDbId); - } - - if (useTvDb) - { - epExists = await allEpisodes.FirstOrDefaultAsync(x => - x.EpisodeNumber == episode.EpisodeNumber && x.SeasonNumber == season.SeasonNumber && - x.Series.TvDbId == item.TvDbId); - } - if (epExists != null) { episode.Available = true; diff --git a/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs index 7f6718a6b..d28f50cc0 100644 --- a/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/EmbyAvailabilityRule.cs @@ -1,11 +1,12 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; using Ombi.Core.Models.Search; using Ombi.Core.Rule.Interfaces; -using Ombi.Core.Settings; -using Ombi.Core.Settings.Models.External; +using Ombi.Core.Services; using Ombi.Helpers; +using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; using Ombi.Store.Repository; @@ -13,14 +14,17 @@ namespace Ombi.Core.Rule.Rules.Search { public class EmbyAvailabilityRule : BaseSearchRule, IRules { - public EmbyAvailabilityRule(IEmbyContentRepository repo, ISettingsService s) + private readonly IFeatureService _featureService; + + public EmbyAvailabilityRule(IEmbyContentRepository repo, ILogger log, IFeatureService featureService) { EmbyContentRepository = repo; - EmbySettings = s; + Log = log; + _featureService = featureService; } private IEmbyContentRepository EmbyContentRepository { get; } - private ISettingsService EmbySettings { get; } + private ILogger Log { get; } public async Task Execute(SearchViewModel obj) { @@ -60,22 +64,36 @@ namespace Ombi.Core.Rule.Rules.Search } } } - + if (item != null) { - obj.Available = true; - var s = await EmbySettings.GetSettingsAsync(); - if (s.Enable) + if (obj is SearchMovieViewModel movie) { - var server = s.Servers.FirstOrDefault(); - if ((server?.ServerHostname ?? string.Empty).HasValue()) + var is4kEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests); + + if (item.Has4K && is4kEnabled) { - obj.EmbyUrl = EmbyHelper.GetEmbyMediaUrl(item.EmbyId, server?.ServerId, server?.ServerHostname); + movie.Available4K = true; + obj.EmbyUrl = item.Url; } else { - obj.EmbyUrl = EmbyHelper.GetEmbyMediaUrl(item.EmbyId, server?.ServerId, null); + obj.Available = true; + obj.EmbyUrl = item.Url; + obj.Quality = item.Quality; } + + if (item.Quality.HasValue()) + { + obj.Available = true; + obj.EmbyUrl = item.Url; + obj.Quality = item.Quality; + } + } + else + { + obj.Available = true; + obj.EmbyUrl = item.Url; } if (obj.Type == RequestType.TvShow) @@ -89,7 +107,7 @@ namespace Ombi.Core.Rule.Rules.Search { foreach (var episode in season.Episodes) { - await AvailabilityRuleHelper.SingleEpisodeCheck(useImdb, allEpisodes, episode, season, item, useTheMovieDb, useTvDb); + await AvailabilityRuleHelper.SingleEpisodeCheck(useImdb, allEpisodes, episode, season, item, useTheMovieDb, useTvDb, Log); } } } diff --git a/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs b/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs index a7cd43336..9c98b7708 100644 --- a/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/ExistingRule.cs @@ -26,17 +26,27 @@ namespace Ombi.Core.Rule.Rules.Search public async Task Execute(SearchViewModel obj) { - if (obj.Type == RequestType.Movie) + if (obj is SearchMovieViewModel movie) { var movieRequests = await Movie.GetRequestAsync(obj.Id); if (movieRequests != null) // Do we already have a request for this? { - obj.Requested = true; - obj.RequestId = movieRequests.Id; - obj.Approved = movieRequests.Approved; - obj.Denied = movieRequests.Denied ?? false; - obj.DeniedReason = movieRequests.DeniedReason; - obj.Available = movieRequests.Available; + // If the RequestDate is a min value, that means there's only a 4k request + movie.Requested = movieRequests.RequestedDate != DateTime.MinValue; + movie.RequestId = movieRequests.Id; + movie.Approved = movieRequests.Approved; + movie.Denied = movieRequests.Denied ?? false; + movie.DeniedReason = movieRequests.DeniedReason; + movie.Available = movieRequests.Available; + movie.Has4KRequest = movieRequests.Has4KRequest; + movie.RequestedDate4k = movieRequests.RequestedDate4k; + movie.Approved4K = movieRequests.Approved4K; + movie.Available4K = movieRequests.Available4K; + movie.Denied4K = movieRequests.Denied4K; + movie.DeniedReason4K = movieRequests.DeniedReason4K; + movie.MarkedAsApproved4K = movieRequests.MarkedAsApproved4K; + movie.MarkedAsAvailable4K = movieRequests.MarkedAsAvailable4K; + movie.MarkedAsDenied4K = movieRequests.MarkedAsDenied4K; return Success(); } @@ -51,7 +61,6 @@ namespace Ombi.Core.Rule.Rules.Search request.RequestId = tvRequests.Id; request.Requested = true; request.Approved = tvRequests.ChildRequests.Any(x => x.Approved); - request.Denied = tvRequests.ChildRequests.Any(x => x.Denied ?? false); // Let's modify the seasonsrequested to reflect what we have requested... foreach (var season in request.SeasonRequests) @@ -75,7 +84,8 @@ namespace Ombi.Core.Rule.Rules.Search episodeSearching.Requested = true; episodeSearching.Available = ep.Available; episodeSearching.Approved = ep.Season.ChildRequest.Approved; - episodeSearching.Denied = request.Denied; + episodeSearching.Denied = ep.Season.ChildRequest.Denied; + episodeSearching.DeniedReason = ep.Season.ChildRequest.DeniedReason; } } } @@ -85,11 +95,24 @@ namespace Ombi.Core.Rule.Rules.Search { request.FullyAvailable = true; } - if (request.SeasonRequests.Any() && request.SeasonRequests.All(x => x.Episodes.Any(e => e.Available && e.AirDate > DateTime.MinValue))) + if (request.SeasonRequests.Any() && request.SeasonRequests.All(x => x.Episodes.Any(e => e.Available && e.AirDate > DateTime.MinValue && e.AirDate <= DateTime.UtcNow))) { request.PartlyAvailable = true; } + if (request.SeasonRequests.Any() && request.SeasonRequests.All(x => x.Episodes.All(e => e.Denied ?? false))) + { + request.Denied = true; + request.DeniedReason = tvRequests.ChildRequests.FirstOrDefault(x => x.Denied ?? false)?.DeniedReason; + } + + var hasUnairedRequests = request.SeasonRequests.Any() && request.SeasonRequests.All(x => x.Episodes.Any(e => e.AirDate >= DateTime.UtcNow)); + + if (request.FullyAvailable) + { + request.PartlyAvailable = hasUnairedRequests; + } + return Success(); } if (obj.Type == RequestType.Album) @@ -100,7 +123,7 @@ namespace Ombi.Core.Rule.Rules.Search if (albumRequest != null) // Do we already have a request for this? { obj.Requested = true; - obj.RequestId = albumRequest.Id; + obj.RequestId = albumRequest.Id; obj.Denied = albumRequest.Denied; obj.DeniedReason = albumRequest.DeniedReason; obj.Approved = albumRequest.Approved; diff --git a/src/Ombi.Core/Rule/Rules/Search/JellyfinAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/JellyfinAvailabilityRule.cs index c51645112..514731740 100644 --- a/src/Ombi.Core/Rule/Rules/Search/JellyfinAvailabilityRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/JellyfinAvailabilityRule.cs @@ -1,11 +1,12 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Logging; using Ombi.Core.Models.Search; using Ombi.Core.Rule.Interfaces; -using Ombi.Core.Settings; -using Ombi.Core.Settings.Models.External; +using Ombi.Core.Services; using Ombi.Helpers; +using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; using Ombi.Store.Repository; @@ -13,14 +14,17 @@ namespace Ombi.Core.Rule.Rules.Search { public class JellyfinAvailabilityRule : BaseSearchRule, IRules { - public JellyfinAvailabilityRule(IJellyfinContentRepository repo, ISettingsService s) + private readonly IFeatureService _featureService; + + public JellyfinAvailabilityRule(IJellyfinContentRepository repo, ILogger log, IFeatureService featureService) { JellyfinContentRepository = repo; - JellyfinSettings = s; + Log = log; + _featureService = featureService; } private IJellyfinContentRepository JellyfinContentRepository { get; } - private ISettingsService JellyfinSettings { get; } + private ILogger Log { get; } public async Task Execute(SearchViewModel obj) { @@ -77,20 +81,32 @@ namespace Ombi.Core.Rule.Rules.Search obj.TheMovieDbId = obj.Id.ToString(); useTheMovieDb = true; } - obj.Available = true; - var s = await JellyfinSettings.GetSettingsAsync(); - if (s.Enable) + if (obj is SearchMovieViewModel movie) { - var server = s.Servers.FirstOrDefault(x => x.ServerHostname != null); - if ((server?.ServerHostname ?? string.Empty).HasValue()) + var is4kEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests); + if (item.Has4K && is4kEnabled) { - obj.JellyfinUrl = JellyfinHelper.GetJellyfinMediaUrl(item.JellyfinId, server?.ServerId, server?.ServerHostname); - } + movie.Available4K = true; + obj.JellyfinUrl = item.Url; + } else { - var firstServer = s.Servers?.FirstOrDefault(); - obj.JellyfinUrl = JellyfinHelper.GetJellyfinMediaUrl(item.JellyfinId, firstServer.ServerId, firstServer.FullUri); + obj.Available = true; + obj.JellyfinUrl = item.Url; + obj.Quality = item.Quality; } + + if (item.Quality.HasValue()) + { + obj.Available = true; + obj.JellyfinUrl = item.Url; + obj.Quality = item.Quality; + } + } + else + { + obj.Available = true; + obj.JellyfinUrl = item.Url; } if (obj.Type == RequestType.TvShow) @@ -104,7 +120,7 @@ namespace Ombi.Core.Rule.Rules.Search { foreach (var episode in season.Episodes) { - await AvailabilityRuleHelper.SingleEpisodeCheck(useImdb, allEpisodes, episode, season, item, useTheMovieDb, useTvDb); + await AvailabilityRuleHelper.SingleEpisodeCheck(useImdb, allEpisodes, episode, season, item, useTheMovieDb, useTvDb, Log); } } } diff --git a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs index 42e97f5f7..ab5b3a6c6 100644 --- a/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/PlexAvailabilityRule.cs @@ -3,9 +3,11 @@ using System.Threading.Tasks; using Microsoft.Extensions.Logging; using Ombi.Core.Models.Search; using Ombi.Core.Rule.Interfaces; +using Ombi.Core.Services; using Ombi.Core.Settings; using Ombi.Core.Settings.Models.External; using Ombi.Helpers; +using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; using Ombi.Store.Repository; @@ -14,12 +16,15 @@ namespace Ombi.Core.Rule.Rules.Search public class PlexAvailabilityRule : BaseSearchRule, IRules { private readonly ISettingsService _plexSettings; + private readonly IFeatureService _featureService; - public PlexAvailabilityRule(IPlexContentRepository repo, ILogger log, ISettingsService plexSettings) + public PlexAvailabilityRule(IPlexContentRepository repo, ILogger log, ISettingsService plexSettings, + IFeatureService featureService) { PlexContentRepository = repo; Log = log; _plexSettings = plexSettings; + _featureService = featureService; } private IPlexContentRepository PlexContentRepository { get; } @@ -33,7 +38,7 @@ namespace Ombi.Core.Rule.Rules.Search var useId = false; var useTvDb = false; - PlexMediaTypeEntity type = ConvertType(obj.Type); + MediaType type = ConvertType(obj.Type); if (obj.ImdbId.HasValue()) { @@ -89,13 +94,44 @@ namespace Ombi.Core.Rule.Rules.Search obj.TheMovieDbId = obj.Id.ToString(); useTheMovieDb = true; } - obj.Available = true; - obj.PlexUrl = PlexHelper.BuildPlexMediaUrl(item.Url, host); - obj.Quality = item.Quality; - - if (obj.Type == RequestType.TvShow) + + if (obj is SearchMovieViewModel movie) + { + var is4kEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests); + + if (item.Has4K && is4kEnabled) + { + movie.Available4K = true; + } + else + { + obj.Available = true; + obj.Quality = item.Quality; + } + + if (item.Quality.HasValue()) + { + obj.Available = true; + obj.Quality = item.Quality; + } + } + else + { + obj.Available = true; + } + + if (item.Url.StartsWith("http")) + { + obj.PlexUrl = item.Url; + } + else + { + // legacy content + obj.PlexUrl = PlexHelper.BuildPlexMediaUrl(item.Url, host); + } + + if (obj is SearchTvShowViewModel search) { - var search = (SearchTvShowViewModel)obj; // Let's go through the episodes now if (search.SeasonRequests.Any()) { @@ -115,12 +151,12 @@ namespace Ombi.Core.Rule.Rules.Search return Success(); } - private PlexMediaTypeEntity ConvertType(RequestType type) => + private MediaType ConvertType(RequestType type) => type switch { - RequestType.Movie => PlexMediaTypeEntity.Movie, - RequestType.TvShow => PlexMediaTypeEntity.Show, - _ => PlexMediaTypeEntity.Movie, + RequestType.Movie => MediaType.Movie, + RequestType.TvShow => MediaType.Series, + _ => MediaType.Movie, }; } } \ No newline at end of file diff --git a/src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs b/src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs index 105681c82..63546f8c8 100644 --- a/src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs +++ b/src/Ombi.Core/Rule/Rules/Search/RadarrCacheRule.cs @@ -18,16 +18,23 @@ namespace Ombi.Core.Rule.Rules.Search public Task Execute(SearchViewModel obj) { - if (obj.Type == RequestType.Movie) + if (obj is SearchMovieViewModel movie) { // Check if it's in Radarr var result = _db.GetAll().FirstOrDefault(x => x.TheMovieDbId == obj.Id); if (result != null) { - obj.Approved = true; // It's in radarr so it's approved... Maybe have a new property called "Processing" or something? + movie.Approved = true; // It's in radarr so it's approved... Maybe have a new property called "Processing" or something? if (result.HasFile) { - obj.Available = true; + if (result.Has4K) + { + movie.Available4K = true; + } + if (result.HasRegular) + { + movie.Available = true; + } } } } diff --git a/src/Ombi.Core/Senders/IMovieSender.cs b/src/Ombi.Core/Senders/IMovieSender.cs index cf8ddf33b..dcf3f766f 100644 --- a/src/Ombi.Core/Senders/IMovieSender.cs +++ b/src/Ombi.Core/Senders/IMovieSender.cs @@ -6,6 +6,6 @@ namespace Ombi.Core { public interface IMovieSender { - Task Send(MovieRequests model); + Task Send(MovieRequests model, bool is4K); } } \ No newline at end of file diff --git a/src/Ombi.Core/Senders/MassEmailSender.cs b/src/Ombi.Core/Senders/MassEmailSender.cs index 604224b34..106a63f49 100644 --- a/src/Ombi.Core/Senders/MassEmailSender.cs +++ b/src/Ombi.Core/Senders/MassEmailSender.cs @@ -25,7 +25,9 @@ // ************************************************************************/ #endregion +using System; using System.Collections.Generic; +using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; @@ -64,6 +66,63 @@ namespace Ombi.Core.Senders var customization = await _customizationService.GetSettingsAsync(); var email = await _emailService.GetSettingsAsync(); var messagesSent = new List(); + if (model.Bcc) + { + await SendBccMails(model, customization, email, messagesSent); + } + else + { + await SendIndividualEmails(model, customization, email, messagesSent); + } + + await Task.WhenAll(messagesSent); + + return true; + } + + private async Task SendBccMails(MassEmailModel model, CustomizationSettings customization, EmailNotificationSettings email, List messagesSent) + { + var resolver = new NotificationMessageResolver(); + var curlys = new NotificationMessageCurlys(); + + var validUsers = new List(); + foreach (var user in model.Users) + { + var fullUser = await _userManager.Users.FirstOrDefaultAsync(x => x.Id == user.Id); + if (!fullUser.Email.HasValue()) + { + _log.LogInformation("User {0} has no email, cannot send mass email to this user", fullUser.UserName); + continue; + } + + validUsers.Add(fullUser); + } + + if (!validUsers.Any()) + { + return; + } + + var firstUser = validUsers.FirstOrDefault(); + + var bccAddress = string.Join(',', validUsers.Select(x => x.Email)); + curlys.Setup(firstUser, customization); + var template = new NotificationTemplates() { Message = model.Body, Subject = model.Subject }; + var content = resolver.ParseMessage(template, curlys); + var msg = new NotificationMessage + { + Message = content.Message, + Subject = content.Subject, + Other = new Dictionary { { "bcc", bccAddress } } + }; + + messagesSent.Add(_email.SendAdHoc(msg, email)); + } + + private async Task SendIndividualEmails(MassEmailModel model, CustomizationSettings customization, EmailNotificationSettings email, List messagesSent) + { + var resolver = new NotificationMessageResolver(); + var curlys = new NotificationMessageCurlys(); foreach (var user in model.Users) { var fullUser = await _userManager.Users.FirstOrDefaultAsync(x => x.Id == user.Id); @@ -72,8 +131,6 @@ namespace Ombi.Core.Senders _log.LogInformation("User {0} has no email, cannot send mass email to this user", fullUser.UserName); continue; } - var resolver = new NotificationMessageResolver(); - var curlys = new NotificationMessageCurlys(); curlys.Setup(fullUser, customization); var template = new NotificationTemplates() { Message = model.Body, Subject = model.Subject }; var content = resolver.ParseMessage(template, curlys); @@ -83,13 +140,19 @@ namespace Ombi.Core.Senders To = fullUser.Email, Subject = content.Subject }; - messagesSent.Add(_email.SendAdHoc(msg, email)); + messagesSent.Add(DelayEmail(msg, email)); _log.LogInformation("Sent mass email to user {0} @ {1}", fullUser.UserName, fullUser.Email); } + } - await Task.WhenAll(messagesSent); - - return true; + /// + /// This will add a 2 second delay, this is to help with concurrent connection limits + /// + /// + private async Task DelayEmail(NotificationMessage msg, EmailNotificationSettings email) + { + await Task.Delay(2000); + await _email.SendAdHoc(msg, email); } } } \ No newline at end of file diff --git a/src/Ombi.Core/Senders/MovieSender.cs b/src/Ombi.Core/Senders/MovieSender.cs index 87d686d35..36d40bdad 100644 --- a/src/Ombi.Core/Senders/MovieSender.cs +++ b/src/Ombi.Core/Senders/MovieSender.cs @@ -20,13 +20,12 @@ namespace Ombi.Core.Senders { public class MovieSender : IMovieSender { - public MovieSender(ISettingsService radarrSettings, IRadarrApi api, ILogger log, + public MovieSender(ISettingsService radarrSettings, ISettingsService radarr4kSettings, ILogger log, ISettingsService dogSettings, IDogNzbApi dogApi, ISettingsService cpSettings, ICouchPotatoApi cpApi, IRepository userProfiles, IRepository requestQueue, INotificationHelper notify, IRadarrV3Api radarrV3Api) { _radarrSettings = radarrSettings; - _radarrV2Api = api; _log = log; _dogNzbSettings = dogSettings; _dogNzbApi = dogApi; @@ -36,10 +35,11 @@ namespace Ombi.Core.Senders _requestQueuRepository = requestQueue; _notificationHelper = notify; _radarrV3Api = radarrV3Api; + _radarr4KSettings = radarr4kSettings; } private readonly ISettingsService _radarrSettings; - private readonly IRadarrApi _radarrV2Api; + private readonly ISettingsService _radarr4KSettings; private readonly ILogger _log; private readonly IDogNzbApi _dogNzbApi; private readonly ISettingsService _dogNzbSettings; @@ -50,16 +50,24 @@ namespace Ombi.Core.Senders private readonly INotificationHelper _notificationHelper; private readonly IRadarrV3Api _radarrV3Api; - public async Task Send(MovieRequests model) + public async Task Send(MovieRequests model, bool is4K) { try { var cpSettings = await _couchPotatoSettings.GetSettingsAsync(); - //var watcherSettings = await WatcherSettings.GetSettingsAsync(); - var radarrSettings = await _radarrSettings.GetSettingsAsync(); + + RadarrSettings radarrSettings; + if (is4K) + { + radarrSettings = await _radarr4KSettings.GetSettingsAsync(); + } + else + { + radarrSettings = await _radarrSettings.GetSettingsAsync(); + } if (radarrSettings.Enabled) { - return await SendToRadarr(model, radarrSettings); + return await SendToRadarr(model, is4K, radarrSettings); } var dogSettings = await _dogNzbSettings.GetSettingsAsync(); @@ -123,7 +131,7 @@ namespace Ombi.Core.Senders return await _dogNzbApi.AddMovie(settings.ApiKey, id); } - private async Task SendToRadarr(MovieRequests model, RadarrSettings settings) + private async Task SendToRadarr(MovieRequests model, bool is4K, RadarrSettings settings) { var qualityToUse = int.Parse(settings.DefaultQualityProfile); diff --git a/src/Ombi.Core/Senders/MusicSender.cs b/src/Ombi.Core/Senders/MusicSender.cs index 6390578dd..260b008fe 100644 --- a/src/Ombi.Core/Senders/MusicSender.cs +++ b/src/Ombi.Core/Senders/MusicSender.cs @@ -70,7 +70,7 @@ namespace Ombi.Core.Senders } - return new SenderResult { Success = false, Sent = false, Message = "Something went wrong!" }; + return new SenderResult { Success = false, Sent = false }; } private async Task SendToLidarr(AlbumRequest model, LidarrSettings settings) diff --git a/src/Ombi.Core/Senders/TvSender.cs b/src/Ombi.Core/Senders/TvSender.cs index 2f42a12c0..22f6aadcd 100644 --- a/src/Ombi.Core/Senders/TvSender.cs +++ b/src/Ombi.Core/Senders/TvSender.cs @@ -133,8 +133,7 @@ namespace Ombi.Core.Senders return new SenderResult { - Success = false, - Message = "Something went wrong!" + Success = false }; } @@ -239,7 +238,7 @@ namespace Ombi.Core.Senders languageProfileId = languageProfile; } } - + try { // Does the series actually exist? @@ -309,6 +308,22 @@ namespace Ombi.Core.Senders private async Task SendToSonarr(ChildRequests model, SonarrSeries result, SonarrSettings s) { + // Check to ensure we have the all the seasons, ensure the Sonarr metadata has grabbed all the data + Season existingSeason = null; + foreach (var season in model.SeasonRequests) + { + var attempt = 0; + existingSeason = result.seasons.FirstOrDefault(x => x.seasonNumber == season.SeasonNumber); + while (existingSeason == null && attempt < 5) + { + attempt++; + Logger.LogInformation("There was no season numer {0} in Sonarr for title {1}. Will try again as the metadata did not get created", season.SeasonNumber, model.ParentRequest.Title); + result = await SonarrApi.GetSeriesById(result.id, s.ApiKey, s.FullUri); + existingSeason = result.seasons.FirstOrDefault(x => x.seasonNumber == season.SeasonNumber); + await Task.Delay(500); + } + } + var episodesToUpdate = new List(); // Ok, now let's sort out the episodes. @@ -327,104 +342,51 @@ namespace Ombi.Core.Senders await Task.Delay(500); } - - foreach (var req in model.SeasonRequests) + foreach (var season in model.SeasonRequests) { - foreach (var ep in req.Episodes) + foreach (var ep in season.Episodes) { var sonarrEp = sonarrEpList.FirstOrDefault(x => - x.episodeNumber == ep.EpisodeNumber && x.seasonNumber == req.SeasonNumber); + x.episodeNumber == ep.EpisodeNumber && x.seasonNumber == season.SeasonNumber); if (sonarrEp != null && !sonarrEp.monitored) { sonarrEp.monitored = true; episodesToUpdate.Add(sonarrEp); } } - } - var seriesChanges = false; - foreach (var season in model.SeasonRequests) - { - var sonarrEpisodeList = sonarrEpList.Where(x => x.seasonNumber == season.SeasonNumber).ToList(); - var sonarrEpCount = sonarrEpisodeList.Count; - var ourRequestCount = season.Episodes.Count; + existingSeason = result.seasons.FirstOrDefault(x => x.seasonNumber == season.SeasonNumber); - var ourEpisodes = season.Episodes.Select(x => x.EpisodeNumber).ToList(); - var unairedEpisodes = sonarrEpisodeList.Where(x => x.airDateUtc > DateTime.UtcNow).Select(x => x.episodeNumber).ToList(); - //// Check if we have requested all the latest episodes, if we have then monitor - //// NOTE, not sure if needed since ombi ui displays future episodes anyway... - //ourEpisodes.AddRange(unairedEpisodes); - //var distinctEpisodes = ourEpisodes.Distinct().ToList(); - //var missingEpisodes = Enumerable.Range(distinctEpisodes.Min(), distinctEpisodes.Count).Except(distinctEpisodes); - - var existingSeason = - result.seasons.FirstOrDefault(x => x.seasonNumber == season.SeasonNumber); - if (existingSeason == null) + // Make sure this season is set to monitored + if (!existingSeason.monitored) { - Logger.LogError("There was no season numer {0} in Sonarr for title {1}", season.SeasonNumber, model.ParentRequest.Title); - continue; - } + // We need to monitor it, problem being is all episodes will now be monitored + // So we need to monitor the series but unmonitor every episode + existingSeason.monitored = true; + var sea = result.seasons.FirstOrDefault(x => x.seasonNumber == existingSeason.seasonNumber); + sea.monitored = true; - - if (sonarrEpCount == ourRequestCount /*|| !missingEpisodes.Any()*/) - { - // We have the same amount of requests as all of the episodes in the season. - - if (!existingSeason.monitored) + result = await SonarrApi.UpdateSeries(result, s.ApiKey, s.FullUri); + var epToUnmonitored = new List(); + var newEpList = sonarrEpList.ConvertAll(ep => new Episode(ep)); // Clone it so we don't modify the original member + foreach (var ep in newEpList.Where(x => x.seasonNumber == existingSeason.seasonNumber).ToList()) { - existingSeason.monitored = true; - seriesChanges = true; + ep.monitored = false; + epToUnmonitored.Add(ep); } - // Now update the episodes that need updating - foreach (var epToUpdate in episodesToUpdate.Where(x => x.seasonNumber == season.SeasonNumber)) + + foreach (var epToUpdate in epToUnmonitored) { await SonarrApi.UpdateEpisode(epToUpdate, s.ApiKey, s.FullUri); } } - else + // Now update the episodes that need updating + foreach (var epToUpdate in episodesToUpdate.Where(x => x.seasonNumber == season.SeasonNumber)) { - // Make sure this season is set to monitored - if (!existingSeason.monitored) - { - // We need to monitor it, problem being is all episodes will now be monitored - // So we need to monitor the series but unmonitor every episode - // Except the episodes that are already monitored before we update the series (we do not want to unmonitored episodes that are monitored beforehand) - existingSeason.monitored = true; - var sea = result.seasons.FirstOrDefault(x => x.seasonNumber == existingSeason.seasonNumber); - sea.monitored = true; - //var previouslyMonitoredEpisodes = sonarrEpList.Where(x => - // x.seasonNumber == existingSeason.seasonNumber && x.monitored).Select(x => x.episodeNumber).ToList(); // We probably don't actually care about this - result = await SonarrApi.UpdateSeries(result, s.ApiKey, s.FullUri); - var epToUnmonitored = new List(); - var newEpList = sonarrEpList.ConvertAll(ep => new Episode(ep)); // Clone it so we don't modify the original member - foreach (var ep in newEpList.Where(x => x.seasonNumber == existingSeason.seasonNumber).ToList()) - { - //if (previouslyMonitoredEpisodes.Contains(ep.episodeNumber)) - //{ - // // This was previously monitored. - // continue; - //} - ep.monitored = false; - epToUnmonitored.Add(ep); - } - - foreach (var epToUpdate in epToUnmonitored) - { - await SonarrApi.UpdateEpisode(epToUpdate, s.ApiKey, s.FullUri); - } - } - // Now update the episodes that need updating - foreach (var epToUpdate in episodesToUpdate.Where(x => x.seasonNumber == season.SeasonNumber)) - { - await SonarrApi.UpdateEpisode(epToUpdate, s.ApiKey, s.FullUri); - } + await SonarrApi.UpdateEpisode(epToUpdate, s.ApiKey, s.FullUri); } } - if (seriesChanges) - { - await SonarrApi.SeasonPass(s.ApiKey, s.FullUri, result); - } if (!s.AddOnly) { @@ -438,7 +400,6 @@ namespace Ombi.Core.Senders var seasonsToUpdate = new List(); for (var i = 0; i < model.ParentRequest.TotalSeasons + 1; i++) { - var index = i; var sea = new Season { seasonNumber = i, diff --git a/src/Ombi.Core/Services/FeatureService.cs b/src/Ombi.Core/Services/FeatureService.cs new file mode 100644 index 000000000..279c5c2c5 --- /dev/null +++ b/src/Ombi.Core/Services/FeatureService.cs @@ -0,0 +1,28 @@ +using Ombi.Core.Settings; +using Ombi.Settings.Settings.Models; +using System.Linq; +using System.Threading.Tasks; + +namespace Ombi.Core.Services +{ + public interface IFeatureService + { + Task FeatureEnabled(string featureName); + } + + public class FeatureService : IFeatureService + { + private readonly ISettingsService _featureSettings; + + public FeatureService(ISettingsService featureSettings) + { + _featureSettings = featureSettings; + } + + public async Task FeatureEnabled(string featureName) + { + var settings = await _featureSettings.GetSettingsAsync(); + return settings.Features?.Where(x => x.Name.Equals(featureName, System.StringComparison.InvariantCultureIgnoreCase)).Select(x => x.Enabled)?.FirstOrDefault() ?? false; + } + } +} diff --git a/src/Ombi.Core/Services/RequestLimitService.cs b/src/Ombi.Core/Services/RequestLimitService.cs index 7a8ecd8f0..d90e0d77c 100644 --- a/src/Ombi.Core/Services/RequestLimitService.cs +++ b/src/Ombi.Core/Services/RequestLimitService.cs @@ -1,5 +1,6 @@ using Microsoft.EntityFrameworkCore; using Ombi.Core.Authentication; +using Ombi.Core.Helpers; using Ombi.Core.Models; using Ombi.Helpers; using Ombi.Store.Entities; @@ -20,11 +21,11 @@ namespace Ombi.Core.Services } public class RequestLimitService : IRequestLimitService { - private readonly IPrincipal _user; + private readonly ICurrentUser _user; private readonly OmbiUserManager _userManager; private readonly IRepository _requestLog; - public RequestLimitService(IPrincipal user, OmbiUserManager userManager, IRepository rl) + public RequestLimitService(ICurrentUser user, OmbiUserManager userManager, IRepository rl) { _user = user; _userManager = userManager; @@ -82,7 +83,7 @@ namespace Ombi.Core.Services } - return await CalculateBasicRemaingRequests(user, limit, user.MovieRequestLimitType ?? RequestLimitType.Day, log, now); + return await CalculateBasicRemaingRequests(limit, user.MovieRequestLimitType ?? RequestLimitType.Day, log, now); } public async Task GetRemainingMusicRequests(OmbiUser user, DateTime now = default) @@ -136,16 +137,17 @@ namespace Ombi.Core.Services }; } - return await CalculateBasicRemaingRequests(user, limit, user.MusicRequestLimitType ?? RequestLimitType.Day, log, now); + return await CalculateBasicRemaingRequests(limit, user.MusicRequestLimitType ?? RequestLimitType.Day, log, now); } private async Task GetUser() { - var username = _user.Identity.Name.ToUpper(); + var currentUser = await _user.GetUser(); + var username = currentUser.UserName.ToUpper(); return await _userManager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username); } - private static async Task CalculateBasicRemaingRequests(OmbiUser user, int limit, RequestLimitType type, IQueryable log, DateTime now) + private static async Task CalculateBasicRemaingRequests(int limit, RequestLimitType type, IQueryable log, DateTime now) { int count = 0; DateTime oldestRequestedAt = DateTime.Now; diff --git a/src/Ombi.DependencyInjection/IocExtensions.cs b/src/Ombi.DependencyInjection/IocExtensions.cs index ca1fbaba8..c866f4442 100644 --- a/src/Ombi.DependencyInjection/IocExtensions.cs +++ b/src/Ombi.DependencyInjection/IocExtensions.cs @@ -70,6 +70,7 @@ using Ombi.Api.RottenTomatoes; using System.Net.Http; using Microsoft.Extensions.Logging; using Ombi.Core.Services; +using Ombi.Core.Helpers; namespace Ombi.DependencyInjection { @@ -124,6 +125,8 @@ namespace Ombi.DependencyInjection var runtimeVersion = AssemblyHelper.GetRuntimeVersion(); services.AddSingleton(); services.AddScoped(sp => sp.GetService().HttpContext.User); + // HttpContext User is null for background jobs + services.AddScoped(sp => new CurrentUser(sp.GetService()?.HttpContext?.User ?? null, sp.GetService())); services.AddHttpClient("OmbiClient", client => { client.DefaultRequestHeaders.Add("User-Agent", $"Ombi/{runtimeVersion} (https://ombi.io/)"); @@ -224,6 +227,7 @@ namespace Ombi.DependencyInjection services.AddTransient(); services.AddTransient(); services.AddTransient(); + services.AddScoped(); services.AddTransient(); } @@ -233,6 +237,7 @@ namespace Ombi.DependencyInjection services.AddSingleton(); services.AddTransient(); + services.AddTransient(); services.AddTransient(); services.AddTransient(); services.AddTransient(); diff --git a/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj b/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj index 9d6efcd69..93b839c07 100644 --- a/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj +++ b/src/Ombi.DependencyInjection/Ombi.DependencyInjection.csproj @@ -1,20 +1,20 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild - + - - + + diff --git a/src/Ombi.HealthChecks/Ombi.HealthChecks.csproj b/src/Ombi.HealthChecks/Ombi.HealthChecks.csproj index 1abcc9a8d..e228dd0d2 100644 --- a/src/Ombi.HealthChecks/Ombi.HealthChecks.csproj +++ b/src/Ombi.HealthChecks/Ombi.HealthChecks.csproj @@ -1,7 +1,7 @@  - net5.0 + net6.0 Debug;Release;NonUiBuild diff --git a/src/Ombi.Helpers.Tests/Ombi.Helpers.Tests.csproj b/src/Ombi.Helpers.Tests/Ombi.Helpers.Tests.csproj index 53725b2b0..370440d1c 100644 --- a/src/Ombi.Helpers.Tests/Ombi.Helpers.Tests.csproj +++ b/src/Ombi.Helpers.Tests/Ombi.Helpers.Tests.csproj @@ -1,7 +1,7 @@  - net5.0 + net6.0 false @@ -10,7 +10,7 @@ - + diff --git a/src/Ombi.Helpers.Tests/PagnationHelperTests.cs b/src/Ombi.Helpers.Tests/PagnationHelperTests.cs index 4b058c403..44bbfdd8e 100644 --- a/src/Ombi.Helpers.Tests/PagnationHelperTests.cs +++ b/src/Ombi.Helpers.Tests/PagnationHelperTests.cs @@ -83,6 +83,8 @@ namespace Ombi.Helpers.Tests .SetName("PaginationPosition_Load_SecondHalf_FirstPage_FirstHalf_SecondPage"); yield return new TestCaseData(0, 40, 20, new List { new MultiplePagesTestData(1, 20, 0), new MultiplePagesTestData(2, 20, 0) }) .SetName("PaginationPosition_Load_Full_First_And_SecondPage"); + yield return new TestCaseData(40, 40, 20, new List { new MultiplePagesTestData(3, 20, 0), new MultiplePagesTestData(4, 20, 0) }) + .SetName("PaginationPosition_Load_Full_Third_And_ForthPage"); yield return new TestCaseData(35, 15, 20, new List { new MultiplePagesTestData(2, 5, 15), new MultiplePagesTestData(3, 10, 0) }) .SetName("PaginationPosition_Load_EndSecondPage_Beginning_ThirdPage"); yield return new TestCaseData(18, 22, 20, new List { new MultiplePagesTestData(1, 2, 18), new MultiplePagesTestData(2, 20, 0) }) diff --git a/src/Ombi.Helpers/JobDataKeys.cs b/src/Ombi.Helpers/JobDataKeys.cs index e0e2f7451..277834431 100644 --- a/src/Ombi.Helpers/JobDataKeys.cs +++ b/src/Ombi.Helpers/JobDataKeys.cs @@ -3,6 +3,7 @@ public class JobDataKeys { public const string RecentlyAddedSearch = "recentlyAddedSearch"; + public const string EmbyRecentlyAddedSearch = nameof(EmbyRecentlyAddedSearch); public const string NotificationOptions = nameof(NotificationOptions); } } \ No newline at end of file diff --git a/src/Ombi.Helpers/LinqHelpers.cs b/src/Ombi.Helpers/LinqHelpers.cs index af8d44633..4e8012653 100644 --- a/src/Ombi.Helpers/LinqHelpers.cs +++ b/src/Ombi.Helpers/LinqHelpers.cs @@ -6,16 +6,6 @@ namespace Ombi.Helpers { public static class LinqHelpers { - public static IEnumerable DistinctBy(this IEnumerable source, Func keySelector) - { - HashSet knownKeys = new HashSet(); - foreach (TSource source1 in source) - { - if (knownKeys.Add(keySelector(source1))) - yield return source1; - } - } - public static HashSet ToHashSet( this IEnumerable source, IEqualityComparer comparer = null) diff --git a/src/Ombi.Helpers/MediaCacheService.cs b/src/Ombi.Helpers/MediaCacheService.cs index d99090b62..8d244f4b3 100644 --- a/src/Ombi.Helpers/MediaCacheService.cs +++ b/src/Ombi.Helpers/MediaCacheService.cs @@ -53,17 +53,18 @@ namespace Ombi.Helpers _memoryCache.Set(CacheKey, mediaServiceCache); } - public async Task Purge() + public Task Purge() { var keys = _memoryCache.Get>(CacheKey); if (keys == null) { - return; + return Task.CompletedTask; } foreach (var key in keys) { base.Remove(key); } + return Task.CompletedTask; } } diff --git a/src/Ombi.Helpers/NotificationSubstitues.cs b/src/Ombi.Helpers/NotificationSubstitues.cs new file mode 100644 index 000000000..69b91304d --- /dev/null +++ b/src/Ombi.Helpers/NotificationSubstitues.cs @@ -0,0 +1,18 @@ +namespace Ombi.Helpers +{ + public static class NotificationSubstitues + { + public const string Title = nameof(Title); + public const string IssueDescription = nameof(IssueDescription); + public const string IssueCategory = nameof(IssueCategory); + public const string IssueStatus = nameof(IssueStatus); + public const string IssueSubject = nameof(IssueSubject); + public const string IssueUser = nameof(IssueUser); + public const string IssueUserAlias = nameof(IssueUserAlias); + public const string RequestType = nameof(RequestType); + public const string PosterPath = nameof(PosterPath); + public const string NewIssueComment = nameof(NewIssueComment); + public const string IssueId = nameof(IssueId); + public const string AdminComment = nameof(AdminComment); + } +} diff --git a/src/Ombi.Helpers/Ombi.Helpers.csproj b/src/Ombi.Helpers/Ombi.Helpers.csproj index 2c32cc1bc..2098fa51f 100644 --- a/src/Ombi.Helpers/Ombi.Helpers.csproj +++ b/src/Ombi.Helpers/Ombi.Helpers.csproj @@ -1,20 +1,20 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild - - + + diff --git a/src/Ombi.Helpers/OmbiRoles.cs b/src/Ombi.Helpers/OmbiRoles.cs index 02a480fdf..3174419c4 100644 --- a/src/Ombi.Helpers/OmbiRoles.cs +++ b/src/Ombi.Helpers/OmbiRoles.cs @@ -16,5 +16,6 @@ public const string ReceivesNewsletter = nameof(ReceivesNewsletter); public const string ManageOwnRequests = nameof(ManageOwnRequests); public const string EditCustomPage = nameof(EditCustomPage); + public const string Request4KMovie = nameof(Request4KMovie); } } \ No newline at end of file diff --git a/src/Ombi.Helpers/PaginationHelper.cs b/src/Ombi.Helpers/PaginationHelper.cs index 520f56b19..2caafe186 100644 --- a/src/Ombi.Helpers/PaginationHelper.cs +++ b/src/Ombi.Helpers/PaginationHelper.cs @@ -17,7 +17,7 @@ namespace Ombi.Helpers var lastPage = lastItemIndex / maxItemsPerPage + 1; var stopPos = lastItemIndex % maxItemsPerPage + 1; - while (currentlyLoaded > maxItemsPerPage) + while (currentlyLoaded >= maxItemsPerPage) { currentlyLoaded -= maxItemsPerPage; } diff --git a/src/Ombi.Helpers/PlexHelper.cs b/src/Ombi.Helpers/PlexHelper.cs index 3e5aeff70..4ae39f6ce 100644 --- a/src/Ombi.Helpers/PlexHelper.cs +++ b/src/Ombi.Helpers/PlexHelper.cs @@ -104,11 +104,11 @@ namespace Ombi.Helpers return new ProviderId(); } - public static string GetPlexMediaUrl(string machineId, int mediaId) + public static string GetPlexMediaUrl(string machineId, string mediaId, string plexHost) { var url = $"web/#!/server/{machineId}/details?key=%2flibrary%2Fmetadata%2F{mediaId}"; - return url; + return BuildPlexMediaUrl(url, plexHost); } public static string BuildPlexMediaUrl(string savedUrl, string plexHost) @@ -180,6 +180,8 @@ namespace Ombi.Helpers public string ImdbId { get; set; } public bool Plex { get; set; } + public bool Any() => TheTvDb.HasValue() || TheMovieDb.HasValue() || ImdbId.HasValue(); + public ProviderType Type { get diff --git a/src/Ombi.Hubs/Ombi.Hubs.csproj b/src/Ombi.Hubs/Ombi.Hubs.csproj index 613221552..f6bee2eb1 100644 --- a/src/Ombi.Hubs/Ombi.Hubs.csproj +++ b/src/Ombi.Hubs/Ombi.Hubs.csproj @@ -1,8 +1,8 @@  - net5.0 - 8.0 + net6.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.I18n/Ombi.I18n.csproj b/src/Ombi.I18n/Ombi.I18n.csproj new file mode 100644 index 000000000..a3387cdea --- /dev/null +++ b/src/Ombi.I18n/Ombi.I18n.csproj @@ -0,0 +1,30 @@ + + + + net6.0 + 3.0.0.0 + 3.0.0.0 + + + latest + Debug;Release;NonUiBuild + + + + Always + + + + + True + True + Texts.resx + + + + + PublicResXFileCodeGenerator + Texts.Designer.cs + + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.Designer.cs b/src/Ombi.I18n/Resources/Texts.Designer.cs new file mode 100644 index 000000000..22991cf96 --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.Designer.cs @@ -0,0 +1,171 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace Ombi.I18n.Resources { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Texts { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Texts() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Ombi.I18n.Resources.Texts", typeof(Texts).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to Album. + /// + public static string Album { + get { + return ResourceManager.GetString("Album", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Type:. + /// + public static string AlbumTypeLabel { + get { + return ResourceManager.GetString("AlbumTypeLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Episodes:. + /// + public static string EpisodesLabel { + get { + return ResourceManager.GetString("EpisodesLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Genres:. + /// + public static string GenresLabel { + get { + return ResourceManager.GetString("GenresLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Movie. + /// + public static string Movie { + get { + return ResourceManager.GetString("Movie", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New Albums. + /// + public static string NewAlbums { + get { + return ResourceManager.GetString("NewAlbums", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New Movies. + /// + public static string NewMovies { + get { + return ResourceManager.GetString("NewMovies", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to New TV. + /// + public static string NewTV { + get { + return ResourceManager.GetString("NewTV", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Powered by. + /// + public static string PoweredBy { + get { + return ResourceManager.GetString("PoweredBy", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Season:. + /// + public static string SeasonLabel { + get { + return ResourceManager.GetString("SeasonLabel", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to TV Show. + /// + public static string TvShow { + get { + return ResourceManager.GetString("TvShow", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Unsubscribe. + /// + public static string Unsubscribe { + get { + return ResourceManager.GetString("Unsubscribe", resourceCulture); + } + } + } +} diff --git a/src/Ombi.I18n/Resources/Texts.bg.resx b/src/Ombi.I18n/Resources/Texts.bg.resx new file mode 100644 index 000000000..81fa9fc9c --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.bg.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + New Albums + + + New Movies + + + New TV + + + Жанрове: + + + Type: + + + Сезон: + + + Episodes: + + + Powered by + + + Unsubscribe + + + Album + + + Movie + + + TV Show + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.cs.resx b/src/Ombi.I18n/Resources/Texts.cs.resx new file mode 100644 index 000000000..80d3b2d95 --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.cs.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Nová alba + + + Nové filmy + + + Nové TV Pořady + + + Žánry: + + + Typ: + + + Série: + + + Epizody: + + + Powered by + + + Odhlásit odběr + + + Album + + + Film + + + TV Pořad + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.da.resx b/src/Ombi.I18n/Resources/Texts.da.resx new file mode 100644 index 000000000..2f217736e --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.da.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Nye Album + + + Nye Film + + + Nye TV-Serier + + + Genre: + + + Type: + + + Sæson: + + + Episoder: + + + Drevet af + + + Afmeld + + + Album + + + Film + + + TV-Serier + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.de.resx b/src/Ombi.I18n/Resources/Texts.de.resx new file mode 100644 index 000000000..91a4aced4 --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.de.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Neue Alben + + + Neue Filme + + + Neue Serien + + + Genres: + + + Typ: + + + Staffel: + + + Episoden: + + + Betrieben durch + + + Abbestellen + + + Album + + + Film + + + TV-Serie + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.es.resx b/src/Ombi.I18n/Resources/Texts.es.resx new file mode 100644 index 000000000..2268cc561 --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.es.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Nuevos Álbumes + + + Nuevas Películas + + + Series Nuevas + + + Géneros: + + + Tipo: + + + Temporada: + + + Episodios: + + + Desarrollado por + + + Anular Suscripción + + + Álbum + + + Película + + + Serie TV + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.fr.resx b/src/Ombi.I18n/Resources/Texts.fr.resx new file mode 100644 index 000000000..9b9d96e48 --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.fr.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Nouveaux Albums + + + Nouveaux films + + + Nouvelles séries + + + Genres : + + + Type : + + + Saison : + + + Épisodes : + + + Propulsé par + + + Se désinscrire + + + Album + + + Film + + + Série + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.hu.resx b/src/Ombi.I18n/Resources/Texts.hu.resx new file mode 100644 index 000000000..4e7cebcfd --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.hu.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + New Albums + + + New Movies + + + New TV + + + Műfaj: + + + Típus: + + + Évad: + + + Epizódok: + + + Powered by + + + Unsubscribe + + + Album + + + Movie + + + TV Show + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.it.resx b/src/Ombi.I18n/Resources/Texts.it.resx new file mode 100644 index 000000000..9d27090b7 --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.it.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Nuovi Album + + + Nuovi Film + + + Nuove Serie + + + Generi: + + + Tipo: + + + Stagione: + + + Episodi: + + + Offerto da + + + Disiscriviti + + + Album + + + Film + + + Serie TV + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.nl.resx b/src/Ombi.I18n/Resources/Texts.nl.resx new file mode 100644 index 000000000..e785eb494 --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.nl.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Nieuwe albums + + + Nieuwe films + + + Nieuwe TV Series + + + Genres: + + + Type: + + + Seizoen: + + + Afleveringen: + + + Mogelijk gemaakt door + + + Uitschrijven + + + Album + + + Movie + + + TV Show + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.no.resx b/src/Ombi.I18n/Resources/Texts.no.resx new file mode 100644 index 000000000..bf0daa456 --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.no.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + New Albums + + + New Movies + + + New TV + + + Genres: + + + Type: + + + Sesong: + + + Episodes: + + + Powered by + + + Unsubscribe + + + Album + + + Movie + + + TV Show + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.pl.resx b/src/Ombi.I18n/Resources/Texts.pl.resx new file mode 100644 index 000000000..f7833ced6 --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.pl.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Nowe Albumy + + + Nowe filmy + + + Nowe seriale + + + Gatunki: + + + Typ: + + + Sezon: + + + Odcinki: + + + Wspierane przez + + + Wypisz się + + + Album + + + Film + + + Serial + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.pt-BR.resx b/src/Ombi.I18n/Resources/Texts.pt-BR.resx new file mode 100644 index 000000000..1dcd24317 --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.pt-BR.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + New Albums + + + New Movies + + + New TV + + + Gêneros: + + + Type: + + + Temporada: + + + Episodes: + + + Powered by + + + Unsubscribe + + + Album + + + Movie + + + TV Show + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.pt.resx b/src/Ombi.I18n/Resources/Texts.pt.resx new file mode 100644 index 000000000..f619ffb16 --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.pt.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + New Albums + + + New Movies + + + New TV + + + Genres: + + + Type: + + + Season: + + + Episodes: + + + Powered by + + + Unsubscribe + + + Album + + + Movie + + + TV Show + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.resx b/src/Ombi.I18n/Resources/Texts.resx new file mode 100644 index 000000000..fcfcebfff --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + New Albums + + + New Movies + + + New TV + + + Genres: + + + Type: + + + Season: + + + Episodes: + + + Powered by + + + Unsubscribe + + + Album + + + Movie + + + TV Show + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.ru.resx b/src/Ombi.I18n/Resources/Texts.ru.resx new file mode 100644 index 000000000..357d1156c --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.ru.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + New Albums + + + New Movies + + + New TV + + + Genres: + + + Type: + + + Сезон: + + + Episodes: + + + Powered by + + + Unsubscribe + + + Album + + + Movie + + + TV Show + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.sk.resx b/src/Ombi.I18n/Resources/Texts.sk.resx new file mode 100644 index 000000000..8fb4b7157 --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.sk.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + New Albums + + + New Movies + + + New TV + + + Žánre: + + + Typ: + + + Séria: + + + Epizódy: + + + Powered by + + + Unsubscribe + + + Album + + + Movie + + + TV Show + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.sv.resx b/src/Ombi.I18n/Resources/Texts.sv.resx new file mode 100644 index 000000000..779be9937 --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.sv.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + New Albums + + + New Movies + + + New TV + + + Genrer: + + + Type: + + + Säsong: + + + Episodes: + + + Powered by + + + Unsubscribe + + + Album + + + Movie + + + TV Show + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.zh-TW.resx b/src/Ombi.I18n/Resources/Texts.zh-TW.resx new file mode 100644 index 000000000..ca17c4bf6 --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.zh-TW.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + New Albums + + + New Movies + + + New TV + + + 流派 + + + 类型: + + + 季: + + + 集: + + + Powered by + + + Unsubscribe + + + Album + + + Movie + + + TV Show + + \ No newline at end of file diff --git a/src/Ombi.I18n/Resources/Texts.zh.resx b/src/Ombi.I18n/Resources/Texts.zh.resx new file mode 100644 index 000000000..03f696076 --- /dev/null +++ b/src/Ombi.I18n/Resources/Texts.zh.resx @@ -0,0 +1,156 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + 新专辑 + + + 新电影 + + + 新电视节目 + + + 流派 + + + 类型: + + + 季: + + + 集: + + + 技术支持: + + + 取消订阅 + + + 专辑 + + + 电影 + + + 电视节目 + + \ No newline at end of file diff --git a/src/Ombi.Mapping/Ombi.Mapping.csproj b/src/Ombi.Mapping/Ombi.Mapping.csproj index f6a5194d9..322942cf2 100644 --- a/src/Ombi.Mapping/Ombi.Mapping.csproj +++ b/src/Ombi.Mapping/Ombi.Mapping.csproj @@ -1,12 +1,12 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Notifications.Templates/EmailBasicTemplate.cs b/src/Ombi.Notifications.Templates/EmailBasicTemplate.cs index 15ec9b286..4bac4b3d8 100644 --- a/src/Ombi.Notifications.Templates/EmailBasicTemplate.cs +++ b/src/Ombi.Notifications.Templates/EmailBasicTemplate.cs @@ -13,7 +13,7 @@ namespace Ombi.Notifications.Templates if (string.IsNullOrEmpty(_templateLocation)) { #if DEBUG - _templateLocation = Path.Combine(Directory.GetCurrentDirectory(), "bin", "Debug", "net5.0", "Templates", + _templateLocation = Path.Combine(Directory.GetCurrentDirectory(), "bin", "Debug", "net6.0", "Templates", "BasicTemplate.html"); #else _templateLocation = Path.Combine(Directory.GetCurrentDirectory(), "Templates","BasicTemplate.html"); @@ -31,16 +31,35 @@ namespace Ombi.Notifications.Templates private const string DateKey = "{@DATENOW}"; private const string Logo = "{@LOGO}"; - public string LoadTemplate(string subject, string body, string imgsrc = default(string), string logo = default(string)) + public string LoadTemplate(string subject, string body, string imgsrc = default(string), string logo = default(string), string url = default(string)) { var sb = new StringBuilder(File.ReadAllText(TemplateLocation)); sb.Replace(SubjectKey, subject); sb.Replace(BodyKey, body); sb.Replace(DateKey, DateTime.Now.ToString("f")); - sb.Replace(Poster, string.IsNullOrEmpty(imgsrc) ? string.Empty : $"\"Poster\""); + sb.Replace(Poster, GetPosterContent(imgsrc, url)); sb.Replace(Logo, string.IsNullOrEmpty(logo) ? OmbiLogo : logo); return sb.ToString(); } + + private string GetPosterContent(string imgsrc, string url) { + string posterContent; + + if (string.IsNullOrEmpty(imgsrc)) + { + posterContent = string.Empty; + } + else + { + posterContent = $"\"Poster\""; + if (!string.IsNullOrEmpty(url)) + { + posterContent = $"{posterContent}"; + } + posterContent = $"{posterContent}"; + } + return posterContent; + } } } diff --git a/src/Ombi.Notifications.Templates/IEmailBasicTemplate.cs b/src/Ombi.Notifications.Templates/IEmailBasicTemplate.cs index 99d7c881a..0a68c0e6b 100644 --- a/src/Ombi.Notifications.Templates/IEmailBasicTemplate.cs +++ b/src/Ombi.Notifications.Templates/IEmailBasicTemplate.cs @@ -2,7 +2,7 @@ { public interface IEmailBasicTemplate { - string LoadTemplate(string subject, string body, string img = default(string), string logo = default(string)); + string LoadTemplate(string subject, string body, string img = default(string), string logo = default(string), string url = default(string)); string TemplateLocation { get; } } } \ No newline at end of file diff --git a/src/Ombi.Notifications.Templates/NewsletterTemplate.cs b/src/Ombi.Notifications.Templates/NewsletterTemplate.cs index f2f0cbf12..9d3b1632a 100644 --- a/src/Ombi.Notifications.Templates/NewsletterTemplate.cs +++ b/src/Ombi.Notifications.Templates/NewsletterTemplate.cs @@ -1,6 +1,7 @@ using System; using System.IO; using System.Text; +using Ombi.I18n.Resources; namespace Ombi.Notifications.Templates { @@ -13,7 +14,7 @@ namespace Ombi.Notifications.Templates if (string.IsNullOrEmpty(_templateLocation)) { #if DEBUG - _templateLocation = Path.Combine(Directory.GetCurrentDirectory(), "bin", "Debug", "net5.0", "Templates", "NewsletterTemplate.html"); + _templateLocation = Path.Combine(Directory.GetCurrentDirectory(), "bin", "Debug", "net6.0", "Templates", "NewsletterTemplate.html"); #else _templateLocation = Path.Combine(Directory.GetCurrentDirectory(), "Templates", "NewsletterTemplate.html"); #endif @@ -30,6 +31,8 @@ namespace Ombi.Notifications.Templates private const string TableLocation = "{@RECENTLYADDED}"; private const string IntroText = "{@INTRO}"; private const string Unsubscribe = "{@UNSUBSCRIBE}"; + private const string UnsubscribeText = "{@UNSUBSCRIBETEXT}"; + private const string PoweredByText = "{@POWEREDBYTEXT}"; public string LoadTemplate(string subject, string intro, string tableHtml, string logo, string unsubscribeLink) @@ -41,6 +44,8 @@ namespace Ombi.Notifications.Templates sb.Replace(DateKey, DateTime.Now.ToString("f")); sb.Replace(Logo, string.IsNullOrEmpty(logo) ? OmbiLogo : logo); sb.Replace(Unsubscribe, string.IsNullOrEmpty(unsubscribeLink) ? string.Empty : unsubscribeLink); + sb.Replace(UnsubscribeText, string.IsNullOrEmpty(unsubscribeLink) ? string.Empty : Texts.Unsubscribe); + sb.Replace(PoweredByText, Texts.PoweredBy); return sb.ToString(); } diff --git a/src/Ombi.Notifications.Templates/Ombi.Notifications.Templates.csproj b/src/Ombi.Notifications.Templates/Ombi.Notifications.Templates.csproj index 47f701083..99e7509b4 100644 --- a/src/Ombi.Notifications.Templates/Ombi.Notifications.Templates.csproj +++ b/src/Ombi.Notifications.Templates/Ombi.Notifications.Templates.csproj @@ -1,12 +1,12 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild @@ -17,6 +17,7 @@ Always + \ No newline at end of file diff --git a/src/Ombi.Notifications.Templates/Templates/NewsletterTemplate.html b/src/Ombi.Notifications.Templates/Templates/NewsletterTemplate.html index 71666ba67..fdafdb609 100644 --- a/src/Ombi.Notifications.Templates/Templates/NewsletterTemplate.html +++ b/src/Ombi.Notifications.Templates/Templates/NewsletterTemplate.html @@ -453,12 +453,12 @@ - Unsubscribe + {@UNSUBSCRIBETEXT} - Powered by Ombi + {@POWEREDBYTEXT} Ombi diff --git a/src/Ombi.Notifications.Tests/NotificationMessageCurlysTests.cs b/src/Ombi.Notifications.Tests/NotificationMessageCurlysTests.cs index 960e552df..783844a82 100644 --- a/src/Ombi.Notifications.Tests/NotificationMessageCurlysTests.cs +++ b/src/Ombi.Notifications.Tests/NotificationMessageCurlysTests.cs @@ -76,6 +76,7 @@ namespace Ombi.Notifications.Tests { "IssueUser", "User" }, { "IssueUserAlias", "alias" }, { "RequestType", "Movie" }, + { "PosterPath", "aaaaa" } } }; var req = F.Build() @@ -94,6 +95,39 @@ namespace Ombi.Notifications.Tests Assert.That("Movie", Is.EqualTo(sut.Type)); } + [Test] + public void IssueNotificationTests_NoRequest() + { + var notificationOptions = new NotificationOptions + { + Substitutes = new Dictionary + { + { "IssueDescription", "Desc" }, + { "IssueCategory", "Cat" }, + { "IssueStatus", "state" }, + { "IssueSubject", "sub" }, + { "NewIssueComment", "a" }, + { "IssueUser", "User" }, + { "IssueUserAlias", "alias" }, + { "RequestType", "Movie" }, + { "PosterPath", "aaaaa" } + } + }; + + var customization = new CustomizationSettings(); + var userPrefs = new UserNotificationPreferences(); + sut.Setup(notificationOptions, (MovieRequests)null, customization, userPrefs); + + Assert.That("Desc", Is.EqualTo(sut.IssueDescription)); + Assert.That("Cat", Is.EqualTo(sut.IssueCategory)); + Assert.That("state", Is.EqualTo(sut.IssueStatus)); + Assert.That("a", Is.EqualTo(sut.NewIssueComment)); + Assert.That("User", Is.EqualTo(sut.UserName)); + Assert.That("alias", Is.EqualTo(sut.Alias)); + Assert.That("Movie", Is.EqualTo(sut.Type)); + Assert.That("https://image.tmdb.org/t/p/w300/aaaaa", Is.EqualTo(sut.PosterImage)); + } + [Test] public void MovieNotificationUserPreferences() { diff --git a/src/Ombi.Notifications.Tests/NotificationServiceTests.cs b/src/Ombi.Notifications.Tests/NotificationServiceTests.cs new file mode 100644 index 000000000..fedd7707e --- /dev/null +++ b/src/Ombi.Notifications.Tests/NotificationServiceTests.cs @@ -0,0 +1,42 @@ +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; +using Moq.AutoMock; +using NUnit.Framework; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Ombi.Notifications.Tests +{ + [TestFixture] + public class NotificationServiceTests + { + + private NotitficationServiceTestFacade _subject; + + [SetUp] + public void Setup() + { + var mocker = new AutoMocker(); + mocker.Use(NullLogger.Instance); + _subject = mocker.CreateInstance(); + } + + [Test] + public void PopulateAgentsTests() + { + Assert.That(_subject.Agents, Has.Count.EqualTo(12)); + Assert.That(_subject.Agents.DistinctBy(x => x.NotificationName).ToList(), Has.Count.EqualTo(12)); + } + } + + + public class NotitficationServiceTestFacade : NotificationService + { + public NotitficationServiceTestFacade(IServiceProvider provider, ILogger log) : base(provider, log) + { + } + + public List Agents => base.NotificationAgents; + } +} diff --git a/src/Ombi.Notifications.Tests/Ombi.Notifications.Tests.csproj b/src/Ombi.Notifications.Tests/Ombi.Notifications.Tests.csproj index 495df8cdc..e936c9072 100644 --- a/src/Ombi.Notifications.Tests/Ombi.Notifications.Tests.csproj +++ b/src/Ombi.Notifications.Tests/Ombi.Notifications.Tests.csproj @@ -1,7 +1,7 @@  - net5.0 + net6.0 Debug;Release;NonUiBuild @@ -10,9 +10,10 @@ - + + diff --git a/src/Ombi.Notifications/Agents/DiscordNotification.cs b/src/Ombi.Notifications/Agents/DiscordNotification.cs index 0cc0c9b89..ae344116f 100644 --- a/src/Ombi.Notifications/Agents/DiscordNotification.cs +++ b/src/Ombi.Notifications/Agents/DiscordNotification.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; using Ombi.Api.Discord; using Ombi.Api.Discord.Models; @@ -21,8 +22,8 @@ namespace Ombi.Notifications.Agents public DiscordNotification(IDiscordApi api, ISettingsService sn, ILogger log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, ISettingsService s, IRepository sub, IMusicRequestRepository music, - IRepository userPref) - : base(sn, r, m, t, s, log, sub, music, userPref) + IRepository userPref, UserManager um) + : base(sn, r, m, t, s, log, sub, music, userPref, um) { Api = api; Logger = log; diff --git a/src/Ombi.Notifications/Agents/EmailNotification.cs b/src/Ombi.Notifications/Agents/EmailNotification.cs index f41406d0e..8f6de1aa3 100644 --- a/src/Ombi.Notifications/Agents/EmailNotification.cs +++ b/src/Ombi.Notifications/Agents/EmailNotification.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using MailKit.Net.Smtp; @@ -22,7 +23,7 @@ namespace Ombi.Notifications.Agents { public EmailNotification(ISettingsService settings, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, IEmailProvider prov, ISettingsService c, ILogger log, UserManager um, IRepository sub, IMusicRequestRepository music, - IRepository userPref) : base(settings, r, m, t, c, log, sub, music, userPref) + IRepository userPref) : base(settings, r, m, t, c, log, sub, music, userPref, um) { EmailProvider = prov; Logger = log; @@ -46,7 +47,7 @@ namespace Ombi.Notifications.Agents return false; } } - if (string.IsNullOrEmpty(settings.Host) || string.IsNullOrEmpty(settings.AdminEmail) || string.IsNullOrEmpty(settings.Port.ToString())) + if (string.IsNullOrEmpty(settings.Host) || string.IsNullOrEmpty(settings.Port.ToString())) { return false; } @@ -63,7 +64,7 @@ namespace Ombi.Notifications.Agents return null; } var email = new EmailBasicTemplate(); - var html = email.LoadTemplate(parsed.Subject, parsed.Message, parsed.Image, Customization.Logo); + var html = email.LoadTemplate(parsed.Subject, parsed.Message, parsed.Image, Customization.Logo, parsed.DetailsUrl); var message = new NotificationMessage @@ -72,26 +73,6 @@ namespace Ombi.Notifications.Agents Subject = parsed.Subject, }; - if (model.Substitutes.TryGetValue("AdminComment", out var isAdminString)) - { - var isAdmin = bool.Parse(isAdminString); - if (isAdmin) - { - var user = _userManager.Users.FirstOrDefault(x => x.Id == model.UserId); - // Send to user - message.To = user.Email; - } - else - { - // Send to admin - message.To = settings.AdminEmail; - } - } - else - { - // Send to admin - message.To = settings.AdminEmail; - } return message; } @@ -114,7 +95,15 @@ namespace Ombi.Notifications.Agents var plaintext = await LoadPlainTextMessage(NotificationType.NewRequest, model, settings); message.Other.Add("PlainTextBody", plaintext); - await Send(message, settings); + foreach (var recipient in (await GetPrivilegedUsers()).DistinctBy(x => x.Email)) + { + if (recipient.Email.IsNullOrEmpty()) + { + continue; + } + message.To = recipient.Email; + await Send(message, settings); + } } protected override async Task NewIssue(NotificationOptions model, EmailNotificationSettings settings) @@ -129,9 +118,7 @@ namespace Ombi.Notifications.Agents message.Other.Add("PlainTextBody", plaintext); // Issues should be sent to admin - message.To = settings.AdminEmail; - - await Send(message, settings); + await SendToAdmins(message, settings); } protected override async Task IssueComment(NotificationOptions model, EmailNotificationSettings settings) @@ -145,18 +132,16 @@ namespace Ombi.Notifications.Agents var plaintext = await LoadPlainTextMessage(NotificationType.IssueComment, model, settings); message.Other.Add("PlainTextBody", plaintext); - if (model.Substitutes.TryGetValue("AdminComment", out var isAdminString)) + if (model.Substitutes.TryGetValue("AdminComment", out var isAdminString) && !bool.Parse(isAdminString)) { - var isAdmin = bool.Parse(isAdminString); - message.To = isAdmin ? model.Recipient : settings.AdminEmail; + await SendToAdmins(message, settings); } else { message.To = model.Recipient; + await Send(message, settings); } - - await Send(message, settings); } protected override async Task IssueResolved(NotificationOptions model, EmailNotificationSettings settings) @@ -195,9 +180,7 @@ namespace Ombi.Notifications.Agents var plaintext = await LoadPlainTextMessage(NotificationType.ItemAddedToFaultQueue, model, settings); message.Other.Add("PlainTextBody", plaintext); - // Issues resolved should be sent to the user - message.To = settings.AdminEmail; - await Send(message, settings); + await SendToAdmins(message, settings); } protected override async Task RequestDeclined(NotificationOptions model, EmailNotificationSettings settings) @@ -296,6 +279,19 @@ namespace Ombi.Notifications.Agents { await EmailProvider.Send(model, settings); } + + protected async Task SendToAdmins(NotificationMessage message, EmailNotificationSettings settings) + { + foreach (var recipient in (await GetAdminUsers()).DistinctBy(x => x.Email)) + { + if (recipient.Email.IsNullOrEmpty()) + { + continue; + } + message.To = recipient.Email; + await Send(message, settings); + } + } protected override async Task Test(NotificationOptions model, EmailNotificationSettings settings) { @@ -307,12 +303,11 @@ namespace Ombi.Notifications.Agents { Message = html, Subject = $"Ombi: Test", - To = settings.AdminEmail, }; message.Other.Add("PlainTextBody", "This is just a test! Success!"); - await Send(message, settings); + await SendToAdmins(message, settings); } } } diff --git a/src/Ombi.Notifications/Agents/GotifyNotification.cs b/src/Ombi.Notifications/Agents/GotifyNotification.cs index 00b62c343..e948c4d89 100644 --- a/src/Ombi.Notifications/Agents/GotifyNotification.cs +++ b/src/Ombi.Notifications/Agents/GotifyNotification.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; using Ombi.Api.Gotify; using Ombi.Core.Settings; @@ -17,7 +18,7 @@ namespace Ombi.Notifications.Agents { public GotifyNotification(IGotifyApi api, ISettingsService sn, ILogger log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, ISettingsService s, IRepository sub, IMusicRequestRepository music, - IRepository userPref) : base(sn, r, m, t, s, log, sub, music, userPref) + IRepository userPref, UserManager um) : base(sn, r, m, t, s, log, sub, music, userPref, um) { Api = api; Logger = log; diff --git a/src/Ombi.Notifications/Agents/LegacyMobileNotification.cs b/src/Ombi.Notifications/Agents/LegacyMobileNotification.cs index c2d71e0d0..9df7c6a94 100644 --- a/src/Ombi.Notifications/Agents/LegacyMobileNotification.cs +++ b/src/Ombi.Notifications/Agents/LegacyMobileNotification.cs @@ -23,7 +23,7 @@ namespace Ombi.Notifications.Agents public LegacyMobileNotification(IOneSignalApi api, ISettingsService sn, ILogger log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, ISettingsService s, IRepository notification, UserManager um, IRepository sub, IMusicRequestRepository music, IRepository issueRepository, - IRepository userPref) : base(sn, r, m, t, s, log, sub, music, userPref) + IRepository userPref) : base(sn, r, m, t, s, log, sub, music, userPref, um) { _api = api; _logger = log; @@ -59,7 +59,7 @@ namespace Ombi.Notifications.Agents }; // Get admin devices - var playerIds = await GetAdmins(NotificationType.NewRequest); + var playerIds = await GetPrivilegedUsersPlayerIds(); await Send(playerIds, notification, settings, model, true); } @@ -77,7 +77,7 @@ namespace Ombi.Notifications.Agents }; // Get admin devices - var playerIds = await GetAdmins(NotificationType.Issue); + var playerIds = await GetAdmins(); await Send(playerIds, notification, settings, model); } @@ -106,7 +106,7 @@ namespace Ombi.Notifications.Agents else { // Send to admin - var playerIds = await GetAdmins(NotificationType.IssueComment); + var playerIds = await GetAdmins(); await Send(playerIds, notification, settings, model); } } @@ -147,7 +147,7 @@ namespace Ombi.Notifications.Agents }; // Get admin devices - var playerIds = await GetAdmins(NotificationType.Test); + var playerIds = await GetAdmins(); await Send(playerIds, notification, settings, model); } @@ -241,15 +241,25 @@ namespace Ombi.Notifications.Agents await Send(playerIds, notification, settings, model); } - private async Task> GetAdmins(NotificationType type) + private async Task> GetAdmins() { - var adminUsers = (await _userManager.GetUsersInRoleAsync(OmbiRoles.Admin)).Select(x => x.Id).ToList(); + return await GetNotificationRecipients(await _userManager.GetUsersInRoleAsync(OmbiRoles.Admin)); + } + private async Task> GetPrivilegedUsersPlayerIds() + { + return await GetNotificationRecipients(await GetPrivilegedUsers()); + } + + private async Task> GetNotificationRecipients(IEnumerable users) + { + + var adminUsers = users.Select(x => x.Id).ToList(); var notificationUsers = _notifications.GetAll().Include(x => x.User).Where(x => adminUsers.Contains(x.UserId)); var playerIds = await notificationUsers.Select(x => x.PlayerId).ToListAsync(); if (!playerIds.Any()) { _logger.LogInformation( - $"there are no admins to send a notification for {type}, for agent {NotificationAgent.Mobile}"); + $"there are no users to send a notification for agent {NotificationAgent.Mobile}"); return null; } return playerIds; diff --git a/src/Ombi.Notifications/Agents/MattermostNotification.cs b/src/Ombi.Notifications/Agents/MattermostNotification.cs index 39e87e334..4b5b570c7 100644 --- a/src/Ombi.Notifications/Agents/MattermostNotification.cs +++ b/src/Ombi.Notifications/Agents/MattermostNotification.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; using Ombi.Api.Mattermost; using Ombi.Api.Mattermost.Models; @@ -19,7 +20,7 @@ namespace Ombi.Notifications.Agents { public MattermostNotification(IMattermostApi api, ISettingsService sn, ILogger log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, ISettingsService s, IRepository sub, IMusicRequestRepository music, - IRepository userPref) : base(sn, r, m, t, s, log, sub, music, userPref) + IRepository userPref, UserManager um) : base(sn, r, m, t, s, log, sub, music, userPref, um) { Api = api; Logger = log; diff --git a/src/Ombi.Notifications/Agents/MobileNotification.cs b/src/Ombi.Notifications/Agents/MobileNotification.cs index b7ada4838..0d21f39a5 100644 --- a/src/Ombi.Notifications/Agents/MobileNotification.cs +++ b/src/Ombi.Notifications/Agents/MobileNotification.cs @@ -23,7 +23,7 @@ namespace Ombi.Notifications.Agents public MobileNotification(ICloudMobileNotification api, ISettingsService sn, ILogger log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, ISettingsService s, IRepository notification, UserManager um, IRepository sub, IMusicRequestRepository music, IRepository issueRepository, - IRepository userPref) : base(sn, r, m, t, s, log, sub, music, userPref) + IRepository userPref) : base(sn, r, m, t, s, log, sub, music, userPref, um) { _api = api; _logger = log; @@ -62,7 +62,7 @@ namespace Ombi.Notifications.Agents }; // Get admin devices - var playerIds = await GetAdmins(NotificationType.NewRequest); + var playerIds = await GetPrivilegedUsersPlayerIds(); await Send(playerIds, notification, settings, model, true); } @@ -82,7 +82,7 @@ namespace Ombi.Notifications.Agents }; // Get admin devices - var playerIds = await GetAdmins(NotificationType.Issue); + var playerIds = await GetAdmins(); await Send(playerIds, notification, settings, model); } @@ -112,7 +112,7 @@ namespace Ombi.Notifications.Agents else { // Send to admin - var playerIds = await GetAdmins(NotificationType.IssueComment); + var playerIds = await GetAdmins(); await Send(playerIds, notification, settings, model); } } @@ -157,7 +157,7 @@ namespace Ombi.Notifications.Agents }; // Get admin devices - var playerIds = await GetAdmins(NotificationType.Test); + var playerIds = await GetAdmins(); await Send(playerIds, notification, settings, model); } @@ -279,15 +279,25 @@ namespace Ombi.Notifications.Agents await Send(playerIds, notification, settings, model); } - private async Task> GetAdmins(NotificationType type) + private async Task> GetAdmins() { - var adminUsers = (await _userManager.GetUsersInRoleAsync(OmbiRoles.Admin)).Select(x => x.Id).ToList(); + return await GetNotificationRecipients(await _userManager.GetUsersInRoleAsync(OmbiRoles.Admin)); + } + private async Task> GetPrivilegedUsersPlayerIds() + { + return await GetNotificationRecipients(await GetPrivilegedUsers()); + } + + private async Task> GetNotificationRecipients(IEnumerable users) + { + + var adminUsers = users.Select(x => x.Id).ToList(); var notificationUsers = _notifications.GetAll().Include(x => x.User).Where(x => adminUsers.Contains(x.UserId)); var playerIds = await notificationUsers.Select(x => x.Token).ToListAsync(); if (!playerIds.Any()) { _logger.LogInformation( - $"there are no admins to send a notification for {type}, for agent {NotificationAgent.Mobile}"); + $"there are no users to send a notification for agent {NotificationAgent.Mobile}"); return null; } return playerIds; @@ -377,7 +387,7 @@ namespace Ombi.Notifications.Agents }; // Get admin devices - var playerIds = await GetAdmins(NotificationType.PartiallyAvailable); + var playerIds = await GetAdmins(); await Send(playerIds, notification, settings, model, true); } } diff --git a/src/Ombi.Notifications/Agents/PushbulletNotification.cs b/src/Ombi.Notifications/Agents/PushbulletNotification.cs index fd4be12a2..3823afe13 100644 --- a/src/Ombi.Notifications/Agents/PushbulletNotification.cs +++ b/src/Ombi.Notifications/Agents/PushbulletNotification.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; using Ombi.Api.Pushbullet; using Ombi.Core.Settings; @@ -17,7 +18,7 @@ namespace Ombi.Notifications.Agents { public PushbulletNotification(IPushbulletApi api, ISettingsService sn, ILogger log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, ISettingsService s, IRepository sub, IMusicRequestRepository music, - IRepository userPref) : base(sn, r, m, t, s, log, sub, music, userPref) + IRepository userPref, UserManager um) : base(sn, r, m, t, s, log, sub, music, userPref, um) { Api = api; Logger = log; diff --git a/src/Ombi.Notifications/Agents/PushoverNotification.cs b/src/Ombi.Notifications/Agents/PushoverNotification.cs index 21352b8d6..3edcd62e2 100644 --- a/src/Ombi.Notifications/Agents/PushoverNotification.cs +++ b/src/Ombi.Notifications/Agents/PushoverNotification.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; using Ombi.Api.Pushbullet; using Ombi.Api.Pushover; @@ -18,7 +19,7 @@ namespace Ombi.Notifications.Agents { public PushoverNotification(IPushoverApi api, ISettingsService sn, ILogger log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, ISettingsService s, IRepository sub, IMusicRequestRepository music, - IRepository userPref) : base(sn, r, m, t, s, log, sub, music, userPref) + IRepository userPref, UserManager um) : base(sn, r, m, t, s, log, sub, music, userPref, um) { Api = api; Logger = log; diff --git a/src/Ombi.Notifications/Agents/SlackNotification.cs b/src/Ombi.Notifications/Agents/SlackNotification.cs index 8dbf14a7d..7ea5b628a 100644 --- a/src/Ombi.Notifications/Agents/SlackNotification.cs +++ b/src/Ombi.Notifications/Agents/SlackNotification.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; using Ombi.Api.Slack; using Ombi.Api.Slack.Models; @@ -18,7 +19,7 @@ namespace Ombi.Notifications.Agents { public SlackNotification(ISlackApi api, ISettingsService sn, ILogger log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, ISettingsService s, IRepository sub, IMusicRequestRepository music, - IRepository userPref) : base(sn, r, m, t, s, log, sub, music, userPref) + IRepository userPref, UserManager um) : base(sn, r, m, t, s, log, sub, music, userPref, um) { Api = api; Logger = log; diff --git a/src/Ombi.Notifications/Agents/TelegramNotification.cs b/src/Ombi.Notifications/Agents/TelegramNotification.cs index 6561a2494..7d5d9ea54 100644 --- a/src/Ombi.Notifications/Agents/TelegramNotification.cs +++ b/src/Ombi.Notifications/Agents/TelegramNotification.cs @@ -10,6 +10,7 @@ using Ombi.Store.Entities; using Ombi.Store.Repository; using Ombi.Store.Repository.Requests; using Ombi.Api.Telegram; +using Microsoft.AspNetCore.Identity; namespace Ombi.Notifications.Agents { @@ -19,7 +20,7 @@ namespace Ombi.Notifications.Agents INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, ISettingsService s , IRepository sub, IMusicRequestRepository music, - IRepository userPref) : base(sn, r, m, t,s,log, sub, music, userPref) + IRepository userPref, UserManager um) : base(sn, r, m, t,s,log, sub, music, userPref, um) { Api = api; Logger = log; diff --git a/src/Ombi.Notifications/Agents/WebhookNotification.cs b/src/Ombi.Notifications/Agents/WebhookNotification.cs index c226d048a..6ed62605e 100644 --- a/src/Ombi.Notifications/Agents/WebhookNotification.cs +++ b/src/Ombi.Notifications/Agents/WebhookNotification.cs @@ -1,6 +1,7 @@ using System; using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Logging; using Ombi.Api.Webhook; using Ombi.Core.Settings; @@ -18,7 +19,7 @@ namespace Ombi.Notifications.Agents { public WebhookNotification(IWebhookApi api, ISettingsService sn, ILogger log, INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, ISettingsService s, IRepository sub, IMusicRequestRepository music, - IRepository userPref) : base(sn, r, m, t, s, log, sub, music, userPref) + IRepository userPref, UserManager um) : base(sn, r, m, t, s, log, sub, music, userPref, um) { Api = api; Logger = log; diff --git a/src/Ombi.Notifications/Agents/WhatsAppNotification.cs b/src/Ombi.Notifications/Agents/WhatsAppNotification.cs index cf97f498f..7956af18a 100644 --- a/src/Ombi.Notifications/Agents/WhatsAppNotification.cs +++ b/src/Ombi.Notifications/Agents/WhatsAppNotification.cs @@ -10,6 +10,7 @@ using Ombi.Store.Entities; using Ombi.Store.Repository; using Ombi.Store.Repository.Requests; using Ombi.Api.Twilio; +using Microsoft.AspNetCore.Identity; namespace Ombi.Notifications.Agents { @@ -19,7 +20,7 @@ namespace Ombi.Notifications.Agents INotificationTemplatesRepository r, IMovieRequestRepository m, ITvRequestRepository t, ISettingsService s , IRepository sub, IMusicRequestRepository music, - IRepository userPref) : base(sn, r, m, t,s,log, sub, music, userPref) + IRepository userPref, UserManager um) : base(sn, r, m, t,s,log, sub, music, userPref, um) { Api = api; Logger = log; diff --git a/src/Ombi.Notifications/BaseNotification.cs b/src/Ombi.Notifications/BaseNotification.cs index ac9de5736..97e2a676d 100644 --- a/src/Ombi.Notifications/BaseNotification.cs +++ b/src/Ombi.Notifications/BaseNotification.cs @@ -1,6 +1,8 @@ using System; +using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Microsoft.AspNetCore.Identity; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Ombi.Core.Settings; @@ -19,7 +21,7 @@ namespace Ombi.Notifications { protected BaseNotification(ISettingsService settings, INotificationTemplatesRepository templateRepo, IMovieRequestRepository movie, ITvRequestRepository tv, ISettingsService customization, ILogger> log, IRepository sub, IMusicRequestRepository album, - IRepository notificationUserPreferences) + IRepository notificationUserPreferences, UserManager um) { Settings = settings; TemplateRepository = templateRepo; @@ -30,7 +32,8 @@ namespace Ombi.Notifications _log = log; AlbumRepository = album; UserNotificationPreferences = notificationUserPreferences; - Settings.ClearCache(); + _userManager = um; + Settings?.ClearCache(); } protected ISettingsService Settings { get; } @@ -43,6 +46,7 @@ namespace Ombi.Notifications protected IRepository UserNotificationPreferences { get; set; } private ISettingsService CustomizationSettings { get; } private readonly ILogger> _log; + private readonly UserManager _userManager; protected ChildRequests TvRequest { get; set; } @@ -60,7 +64,11 @@ namespace Ombi.Notifications public async Task NotifyAsync(NotificationOptions model, Settings.Settings.Models.Settings settings) { - if (settings == null) await NotifyAsync(model); + if (settings == null) + { + await NotifyAsync(model); + return; + } var notificationSettings = (T)settings; @@ -110,15 +118,13 @@ namespace Ombi.Notifications case NotificationType.IssueComment: await IssueComment(model, notificationSettings); break; - case NotificationType.AdminNote: - break; - case NotificationType.WelcomeEmail: - break; - case NotificationType.Newsletter: - break; case NotificationType.PartiallyAvailable: await PartiallyAvailable(model, notificationSettings); break; + case NotificationType.AdminNote: + case NotificationType.WelcomeEmail: + case NotificationType.Newsletter: + break; default: throw new ArgumentOutOfRangeException(); } @@ -210,6 +216,18 @@ namespace Ombi.Notifications .FirstOrDefault(x => x.Agent == agent && x.UserId == userId); } + protected async Task> GetAdminUsers() + { + IEnumerable recipients = await _userManager.GetUsersInRoleAsync(OmbiRoles.Admin); + return recipients; + } + protected async Task> GetPrivilegedUsers() + { + IEnumerable recipients = await GetAdminUsers(); + recipients = recipients.Concat(await _userManager.GetUsersInRoleAsync(OmbiRoles.PowerUser)); + return recipients; + } + private NotificationMessageContent Parse(NotificationOptions model, NotificationTemplates template, NotificationAgent agent) { var resolver = new NotificationMessageResolver(); diff --git a/src/Ombi.Notifications/GenericEmailProvider.cs b/src/Ombi.Notifications/GenericEmailProvider.cs index 15f17af92..fdeb1f49c 100644 --- a/src/Ombi.Notifications/GenericEmailProvider.cs +++ b/src/Ombi.Notifications/GenericEmailProvider.cs @@ -64,7 +64,20 @@ namespace Ombi.Notifications MessageId = messageId }; message.From.Add(new MailboxAddress(string.IsNullOrEmpty(settings.SenderName) ? settings.SenderAddress : settings.SenderName, settings.SenderAddress)); - message.To.Add(new MailboxAddress(model.To, model.To)); + if (model.To.HasValue()) + { + message.To.Add(new MailboxAddress(model.To, model.To)); + } + + // Check for BCC + if (model.Other.TryGetValue("bcc", out var bcc)) + { + var bccList = bcc.Split(',', StringSplitOptions.RemoveEmptyEntries); + foreach (var item in bccList) + { + message.Bcc.Add(new MailboxAddress(item, item)); + } + } using (var client = new SmtpClient()) { diff --git a/src/Ombi.Notifications/NotificationMessageContent.cs b/src/Ombi.Notifications/NotificationMessageContent.cs index 901b3bcb2..7141bbedd 100644 --- a/src/Ombi.Notifications/NotificationMessageContent.cs +++ b/src/Ombi.Notifications/NotificationMessageContent.cs @@ -7,6 +7,7 @@ namespace Ombi.Notifications public bool Disabled { get; set; } public string Subject { get; set; } public string Message { get; set; } + public string DetailsUrl { get; set; } public string Image { get; set; } public IReadOnlyDictionary Data { get; set; } } diff --git a/src/Ombi.Notifications/NotificationMessageCurlys.cs b/src/Ombi.Notifications/NotificationMessageCurlys.cs index 392fc9412..7696c9c16 100644 --- a/src/Ombi.Notifications/NotificationMessageCurlys.cs +++ b/src/Ombi.Notifications/NotificationMessageCurlys.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using Humanizer; using Ombi.Helpers; +using Ombi.I18n.Resources; using Ombi.Notifications.Models; using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; @@ -39,7 +40,22 @@ namespace Ombi.Notifications Year = req?.ReleaseDate.Year.ToString(); Overview = req?.Overview; AdditionalInformation = opts?.AdditionalInformation ?? string.Empty; - PosterImage = $"https://image.tmdb.org/t/p/w300/{req?.PosterPath?.TrimStart('/') ?? string.Empty}"; + + var img = req?.PosterPath ?? string.Empty; + if (img.HasValue()) + { + if (img.StartsWith("http")) + { + // This means it's a legacy request from when we used TvMaze as a provider. + // The poster url is the fully qualified address, so just use it + PosterImage = img; + } + else + { + PosterImage = + $"https://image.tmdb.org/t/p/w300/{img?.TrimStart('/') ?? string.Empty}"; + } + } CalculateRequestStatus(req); } @@ -53,8 +69,21 @@ namespace Ombi.Notifications Year = req?.ParentRequest?.ReleaseDate.Year.ToString(); Overview = req?.ParentRequest?.Overview; AdditionalInformation = opts.AdditionalInformation; - PosterImage = - $"https://image.tmdb.org/t/p/w300/{req?.ParentRequest?.PosterPath?.TrimStart('/') ?? string.Empty}"; + var img = req?.ParentRequest?.PosterPath ?? string.Empty; + if (img.HasValue()) + { + if (img.StartsWith("http")) + { + // This means it's a legacy request from when we used TvMaze as a provider. + // The poster url is the fully qualified address, so just use it + PosterImage = img; + } + else + { + PosterImage = + $"https://image.tmdb.org/t/p/w300/{img?.TrimStart('/') ?? string.Empty}"; + } + } // Generate episode list. StringBuilder epSb = new StringBuilder(); @@ -94,16 +123,24 @@ namespace Ombi.Notifications private void LoadIssues(NotificationOptions opts) { - IssueDescription = opts.Substitutes.TryGetValue("IssueDescription", out string val) ? val : string.Empty; - IssueCategory = opts.Substitutes.TryGetValue("IssueCategory", out val) ? val : string.Empty; - IssueStatus = opts.Substitutes.TryGetValue("IssueStatus", out val) ? val : string.Empty; - IssueSubject = opts.Substitutes.TryGetValue("IssueSubject", out val) ? val : string.Empty; - NewIssueComment = opts.Substitutes.TryGetValue("NewIssueComment", out val) ? val : string.Empty; - UserName = opts.Substitutes.TryGetValue("IssueUser", out val) ? val : string.Empty; - Alias = opts.Substitutes.TryGetValue("IssueUserAlias", out val) ? val : string.Empty; - Type = opts.Substitutes.TryGetValue("RequestType", out val) && Enum.TryParse(val, out RequestType type) + IssueDescription = opts.Substitutes.TryGetValue(NotificationSubstitues.IssueDescription, out string val) ? val : string.Empty; + IssueCategory = opts.Substitutes.TryGetValue(NotificationSubstitues.IssueCategory, out val) ? val : string.Empty; + IssueStatus = opts.Substitutes.TryGetValue(NotificationSubstitues.IssueStatus, out val) ? val : string.Empty; + IssueSubject = opts.Substitutes.TryGetValue(NotificationSubstitues.IssueSubject, out val) ? val : string.Empty; + NewIssueComment = opts.Substitutes.TryGetValue(NotificationSubstitues.NewIssueComment, out val) ? val : string.Empty; + UserName = opts.Substitutes.TryGetValue(NotificationSubstitues.IssueUser, out val) ? val : string.Empty; + Alias = opts.Substitutes.TryGetValue(NotificationSubstitues.IssueUserAlias, out val) ? val : string.Empty; + Type = opts.Substitutes.TryGetValue(NotificationSubstitues.RequestType, out val) && Enum.TryParse(val, out RequestType type) ? HumanizeReturnType(type) : string.Empty; + if (opts.Substitutes.TryGetValue(NotificationSubstitues.PosterPath, out val) && val.HasValue()) + { + PosterImage = $"https://image.tmdb.org/t/p/w300/{val.TrimStart('/')}"; + } + else + { + PosterImage = string.Empty; + } } private void LoadCommon(BaseRequest req, CustomizationSettings s, UserNotificationPreferences pref, NotificationOptions opts) @@ -115,6 +152,7 @@ namespace Ombi.Notifications RequestId = req?.Id.ToString(); RequestedUser = req?.RequestedUser?.UserName; RequestedDate = req?.RequestedDate.ToString("D"); + DetailsUrl = GetDetailsUrl(s, req); if (Type.IsNullOrEmpty()) { @@ -156,7 +194,9 @@ namespace Ombi.Notifications return requestType switch { null => string.Empty, - RequestType.TvShow => "TV Show", + RequestType.TvShow => Texts.TvShow, + RequestType.Album => Texts.Album, + RequestType.Movie => Texts.Movie, _ => requestType.Humanize() }; } @@ -178,6 +218,26 @@ namespace Ombi.Notifications } } + private string GetDetailsUrl(CustomizationSettings s, BaseRequest req) + { + if (string.IsNullOrEmpty(s.ApplicationUrl)) + { + return string.Empty; + } + + switch (req) + { + case MovieRequests movieRequest: + return $"{s.ApplicationUrl}/details/movie/{movieRequest.TheMovieDbId}"; + case ChildRequests tvRequest: + return $"{s.ApplicationUrl}/details/tv/{tvRequest.ParentRequest.ExternalProviderId}"; + case AlbumRequest albumRequest: + return $"{s.ApplicationUrl}/details/artist/{albumRequest.ForeignArtistId}"; + default: + return string.Empty; + } + } + private void CalculateRequestStatus(BaseRequest req) { RequestStatus = string.Empty; @@ -219,6 +279,7 @@ namespace Ombi.Notifications public string Year { get; set; } public string EpisodesList { get; set; } public string SeasonsList { get; set; } + public string DetailsUrl { get; set; } public string PosterImage { get; set; } public string ApplicationName { get; set; } public string ApplicationUrl { get; set; } diff --git a/src/Ombi.Notifications/NotificationMessageResolver.cs b/src/Ombi.Notifications/NotificationMessageResolver.cs index fe6102eda..5475f1a97 100644 --- a/src/Ombi.Notifications/NotificationMessageResolver.cs +++ b/src/Ombi.Notifications/NotificationMessageResolver.cs @@ -26,6 +26,7 @@ namespace Ombi.Notifications { var content = Resolve(notification.Message, notification.Subject, c.Curlys); content.Image = c.PosterImage; + content.DetailsUrl = c.DetailsUrl; return content; } diff --git a/src/Ombi.Notifications/NotificationService.cs b/src/Ombi.Notifications/NotificationService.cs index 8a24382aa..f22800cdc 100644 --- a/src/Ombi.Notifications/NotificationService.cs +++ b/src/Ombi.Notifications/NotificationService.cs @@ -23,7 +23,7 @@ namespace Ombi.Notifications PopulateAgents(); } - private List NotificationAgents { get; } + protected List NotificationAgents { get; } private ILogger Log { get; } /// @@ -55,7 +55,7 @@ namespace Ombi.Notifications } - private void PopulateAgents() + protected void PopulateAgents() { var baseSearchType = typeof(BaseNotification<>).Name; diff --git a/src/Ombi.Notifications/Ombi.Notifications.csproj b/src/Ombi.Notifications/Ombi.Notifications.csproj index ab65285b3..41fd3ae17 100644 --- a/src/Ombi.Notifications/Ombi.Notifications.csproj +++ b/src/Ombi.Notifications/Ombi.Notifications.csproj @@ -1,12 +1,12 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Schedule.Tests/Ombi.Schedule.Tests.csproj b/src/Ombi.Schedule.Tests/Ombi.Schedule.Tests.csproj index 1203d731d..d8e698d0e 100644 --- a/src/Ombi.Schedule.Tests/Ombi.Schedule.Tests.csproj +++ b/src/Ombi.Schedule.Tests/Ombi.Schedule.Tests.csproj @@ -1,7 +1,7 @@  - net5.0 + net6.0 Debug;Release;NonUiBuild @@ -11,7 +11,7 @@ - + @@ -19,6 +19,7 @@ + diff --git a/src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs b/src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs index a86afcad0..6a549458b 100644 --- a/src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs +++ b/src/Ombi.Schedule.Tests/PlexAvailabilityCheckerTests.cs @@ -18,6 +18,7 @@ using Ombi.Store.Entities.Requests; using Ombi.Store.Repository; using Ombi.Store.Repository.Requests; using Ombi.Helpers; +using Ombi.Core.Services; namespace Ombi.Schedule.Tests { @@ -36,7 +37,7 @@ namespace Ombi.Schedule.Tests hub.Setup(x => x.Clients.Clients(It.IsAny>()).SendCoreAsync(It.IsAny(), It.IsAny(), It.IsAny())); NotificationHub.UsersOnline.TryAdd("A", new HubUsers()); - Checker = new PlexAvailabilityChecker(_repo.Object, _tv.Object, _movie.Object, _notify.Object, null, hub.Object); + Checker = new PlexAvailabilityChecker(_repo.Object, _tv.Object, _movie.Object, _notify.Object, null, hub.Object, Mock.Of()); } diff --git a/src/Ombi.Schedule.Tests/PlexContentSyncTests.cs b/src/Ombi.Schedule.Tests/PlexContentSyncTests.cs index 3b9fa33b0..8540f0037 100644 --- a/src/Ombi.Schedule.Tests/PlexContentSyncTests.cs +++ b/src/Ombi.Schedule.Tests/PlexContentSyncTests.cs @@ -47,7 +47,7 @@ namespace Ombi.Schedule.Tests } }; var contentToAdd = new HashSet(); - var contentProcessed = new Dictionary(); + var contentProcessed = new Dictionary(); _mocker.Setup(x => x.GetFirstContentByCustom(It.IsAny>>())) .Returns(Task.FromResult(new PlexServerContent())); @@ -76,18 +76,18 @@ namespace Ombi.Schedule.Tests Id = "imdb://tt0322259" } }, - ratingKey = 1 + ratingKey = "1" }, } }; var contentToAdd = new HashSet(); - var contentProcessed = new Dictionary(); + var contentProcessed = new Dictionary(); await _subject.MovieLoop(new PlexServers(), content, contentToAdd, contentProcessed); var first = contentToAdd.First(); Assert.That(first.ImdbId, Is.EqualTo("tt0322259")); - _mocker.Verify(x => x.GetMetadata(It.IsAny(), It.IsAny(),It.IsAny()), Times.Never); + _mocker.Verify(x => x.GetMetadata(It.IsAny(), It.IsAny(),It.IsAny()), Times.Never); } [Test] @@ -99,7 +99,7 @@ namespace Ombi.Schedule.Tests { new Metadata { - ratingKey = 11, + ratingKey = "11", title = "test1", year = 2021, type = "movie", @@ -107,8 +107,8 @@ namespace Ombi.Schedule.Tests } }; var contentToAdd = new HashSet(); - var contentProcessed = new Dictionary(); - _mocker.Setup(x => x.GetMetadata(It.IsAny(), It.IsAny(), It.IsAny())) + var contentProcessed = new Dictionary(); + _mocker.Setup(x => x.GetMetadata(It.IsAny(), It.IsAny(), It.IsAny())) .Returns(Task.FromResult(new PlexMetadata { MediaContainer = new Mediacontainer @@ -117,7 +117,7 @@ namespace Ombi.Schedule.Tests { new Metadata { - ratingKey = 11, + ratingKey = "11", title = "test1", year = 2021, type = "movie", @@ -133,12 +133,88 @@ namespace Ombi.Schedule.Tests } })); - await _subject.MovieLoop(new PlexServers { Ip = "http://test.com/", Port = 80}, content, contentToAdd, contentProcessed); + await _subject.MovieLoop(new PlexServers { Ip = "http://test.com/", Port = 80 }, content, contentToAdd, contentProcessed); var first = contentToAdd.First(); Assert.That(first.ImdbId, Is.EqualTo("tt0322259")); - _mocker.Verify(x => x.GetMetadata(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.GetMetadata(It.IsAny(), It.IsAny(), It.IsAny()), Times.Once); + } + + [Test] + public async Task UpdatesExistingMovieWhen_WeFindAnotherQuality() + { + var content = new Mediacontainer + { + Metadata = new[] + { + new Metadata + { + ratingKey = "11", + title = "test1", + year = 2021, + type = "movie", + Media = new Medium[1] + { + new Medium + { + videoResolution = "4k" + } + } + }, + } + }; + var contentToAdd = new HashSet(); + var contentProcessed = new Dictionary(); + _mocker.Setup(x => + x.GetFirstContentByCustom(It.IsAny>>())) + .Returns(Task.FromResult(new PlexServerContent + { + Quality = "1080" + })); + + await _subject.MovieLoop(new PlexServers(), content, contentToAdd, contentProcessed); + + Assert.That(contentToAdd, Is.Empty); + _mocker.Verify(x => x.Update(It.Is(x => x.Quality == "1080" && x.Has4K)), Times.Once); + } + + [Test] + public async Task DoesNotUpdatesExistingMovieWhen_WeFindSameQuality() + { + var content = new Mediacontainer + { + Metadata = new[] + { + new Metadata + { + ratingKey = "11", + title = "test1", + year = 2021, + type = "movie", + Media = new Medium[1] + { + new Medium + { + videoResolution = "1080" + } + } + }, + } + }; + var contentToAdd = new HashSet(); + var contentProcessed = new Dictionary(); + _mocker.Setup(x => + x.GetFirstContentByCustom(It.IsAny>>())) + .Returns(Task.FromResult(new PlexServerContent + { + Quality = "1080" + })); + + await _subject.MovieLoop(new PlexServers(), content, contentToAdd, contentProcessed); + + Assert.That(contentToAdd, Is.Empty); + _mocker.Verify(x => x.Update(It.IsAny()), Times.Never); } } } diff --git a/src/Ombi.Schedule.Tests/PlexWatchlistImportTests.cs b/src/Ombi.Schedule.Tests/PlexWatchlistImportTests.cs new file mode 100644 index 000000000..950f6f431 --- /dev/null +++ b/src/Ombi.Schedule.Tests/PlexWatchlistImportTests.cs @@ -0,0 +1,468 @@ +using Moq; +using Moq.AutoMock; +using NUnit.Framework; +using Ombi.Api.Plex; +using Ombi.Api.Plex.Models; +using Ombi.Core.Engine; +using Ombi.Core.Engine.Interfaces; +using Ombi.Core.Models.Requests; +using Ombi.Core.Settings; +using Ombi.Core.Settings.Models.External; +using Ombi.Schedule.Jobs.Plex; +using Ombi.Store.Entities; +using Ombi.Store.Repository; +using Ombi.Test.Common; +using Quartz; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Ombi.Schedule.Tests +{ + [TestFixture] + public class PlexWatchlistImportTests + { + + private PlexWatchlistImport _subject; + private AutoMocker _mocker; + private Mock _context; + + [SetUp] + public void Setup() + { + _mocker = new AutoMocker(); + var um = MockHelper.MockUserManager(new List { new OmbiUser { Id = "abc", UserType = UserType.PlexUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" } }); + _mocker.Use(um); + _context = _mocker.GetMock(); + _context.Setup(x => x.CancellationToken).Returns(CancellationToken.None); + _subject = _mocker.CreateInstance(); + } + + [Test] + public async Task TerminatesWhenPlexIsNotEnabled() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = false, EnableWatchlistImport = true }); + await _subject.Execute(null); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + _mocker.Verify(x => x.GetWatchlist(It.IsAny(), It.IsAny()), Times.Never); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + _mocker.Verify>(x => x.GetAll(), Times.Never); + _mocker.Verify>(x => x.Add(It.IsAny()), Times.Never); + } + [Test] + public async Task TerminatesWhenWatchlistIsNotEnabled() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = false }); + await _subject.Execute(null); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + _mocker.Verify(x => x.GetWatchlist(It.IsAny(), It.IsAny()), Times.Never); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + _mocker.Verify>(x => x.GetAll(), Times.Never); + _mocker.Verify>(x => x.Add(It.IsAny()), Times.Never); + } + + [Test] + public async Task EmptyWatchList() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + _mocker.Setup>(x => x.GetWatchlist(It.IsAny(), It.IsAny())).ReturnsAsync(new PlexWatchlistContainer()); + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + _mocker.Verify(x => x.GetWatchlist(It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + _mocker.Verify>(x => x.GetAll(), Times.Never); + _mocker.Verify>(x => x.Add(It.IsAny()), Times.Never); + } + + [Test] + public async Task NoPlexUsersWithToken() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + var um = MockHelper.MockUserManager(new List + { + new OmbiUser { Id = "abc", UserType = UserType.EmbyUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" }, + new OmbiUser { Id = "abc", UserType = UserType.LocalUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" }, + new OmbiUser { Id = "abc", UserType = UserType.SystemUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" }, + new OmbiUser { Id = "abc", UserType = UserType.JellyfinUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" }, + new OmbiUser { Id = "abc", UserType = UserType.EmbyConnectUser, MediaServerToken = "abc", UserName = "abc", NormalizedUserName = "ABC" }, + new OmbiUser { Id = "abc", UserType = UserType.PlexUser, UserName = "abc", NormalizedUserName = "ABC" }, + }); + _mocker.Use(um); + _subject = _mocker.CreateInstance(); + + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.GetWatchlist(It.IsAny(), It.IsAny()), Times.Never); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + _mocker.Verify>(x => x.GetAll(), Times.Never); + _mocker.Verify>(x => x.Add(It.IsAny()), Times.Never); + } + + + [Test] + public async Task MultipleUsers() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + var um = MockHelper.MockUserManager(new List + { + new OmbiUser { Id = "abc1", UserType = UserType.PlexUser, MediaServerToken = "abc1", UserName = "abc1", NormalizedUserName = "ABC1" }, + new OmbiUser { Id = "abc2", UserType = UserType.PlexUser, MediaServerToken = "abc2", UserName = "abc2", NormalizedUserName = "ABC2" }, + new OmbiUser { Id = "abc3", UserType = UserType.PlexUser, MediaServerToken = "abc3", UserName = "abc3", NormalizedUserName = "ABC3" }, + new OmbiUser { Id = "abc4", UserType = UserType.PlexUser, MediaServerToken = "abc4", UserName = "abc4", NormalizedUserName = "ABC4" }, + new OmbiUser { Id = "abc5", UserType = UserType.PlexUser, MediaServerToken = "abc5", UserName = "abc5", NormalizedUserName = "ABC5" }, + }); + _mocker.Use(um); + _subject = _mocker.CreateInstance(); + + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.GetWatchlist(It.IsAny(), It.IsAny()), Times.Exactly(5)); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + _mocker.Verify>(x => x.GetAll(), Times.Never); + _mocker.Verify>(x => x.Add(It.IsAny()), Times.Never); + } + + + [Test] + public async Task MovieRequestFromWatchList_NoGuid() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + _mocker.Setup>(x => x.GetWatchlist(It.IsAny(), It.IsAny())).ReturnsAsync(new PlexWatchlistContainer + { + MediaContainer = new PlexWatchlist + { + Metadata = new List + { + new Metadata + { + type = "movie", + ratingKey = "abc" + } + } + } + }); + _mocker.Setup>(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny())) + .ReturnsAsync(new PlexWatchlistMetadataContainer + { + MediaContainer = new PlexWatchlistMetadata + { + Metadata = new WatchlistMetadata[] + { + new WatchlistMetadata + { + Guid = new List + { + new PlexGuids + { + Id = "tmdb://123" + } + } + } + } + + } + }); + _mocker.Setup>(x => x.RequestMovie(It.IsAny())) + .ReturnsAsync(new RequestEngineResult { RequestId = 1 }); + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.RequestMovie(It.Is(x => x.TheMovieDbId == 123)), Times.Once); + _mocker.Verify(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.SetUser(It.Is(x => x.Id == "abc")), Times.Once); + _mocker.Verify>(x => x.GetAll(), Times.Once); + _mocker.Verify>(x => x.Add(It.IsAny()), Times.Once); + } + + + [Test] + public async Task TvRequestFromWatchList_NoGuid() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + _mocker.Setup>(x => x.GetWatchlist(It.IsAny(), It.IsAny())).ReturnsAsync(new PlexWatchlistContainer + { + MediaContainer = new PlexWatchlist + { + Metadata = new List + { + new Metadata + { + type = "show", + ratingKey = "abc" + } + } + } + }); + _mocker.Setup>(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny())) + .ReturnsAsync(new PlexWatchlistMetadataContainer + { + MediaContainer = new PlexWatchlistMetadata + { + Metadata = new WatchlistMetadata[] + { + new WatchlistMetadata + { + Guid = new List + { + new PlexGuids + { + Id = "tmdb://123" + } + } + } + } + + } + }); + _mocker.Setup>(x => x.RequestTvShow(It.IsAny())) + .ReturnsAsync(new RequestEngineResult { RequestId = 1 }); + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.RequestTvShow(It.Is(x => x.TheMovieDbId == 123 && x.LatestSeason == true)), Times.Once); + _mocker.Verify(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.SetUser(It.Is(x => x.Id == "abc")), Times.Once); + _mocker.Verify>(x => x.GetAll(), Times.Once); + _mocker.Verify>(x => x.Add(It.IsAny()), Times.Once); + } + + [Test] + public async Task MovieRequestFromWatchList_AlreadyRequested() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + _mocker.Setup>(x => x.GetWatchlist(It.IsAny(), It.IsAny())).ReturnsAsync(new PlexWatchlistContainer + { + MediaContainer = new PlexWatchlist + { + Metadata = new List + { + new Metadata + { + type = "movie", + ratingKey = "abc" + } + } + } + }); + _mocker.Setup>(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny())) + .ReturnsAsync(new PlexWatchlistMetadataContainer + { + MediaContainer = new PlexWatchlistMetadata + { + Metadata = new WatchlistMetadata[] + { + new WatchlistMetadata + { + Guid = new List + { + new PlexGuids + { + Id = "tmdb://123" + } + } + } + } + + } + }); + _mocker.Setup>(x => x.RequestMovie(It.IsAny())) + .ReturnsAsync(new RequestEngineResult { ErrorCode = ErrorCode.AlreadyRequested, ErrorMessage = "Requested" }); + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.RequestMovie(It.Is(x => x.TheMovieDbId == 123)), Times.Once); + _mocker.Verify(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.SetUser(It.Is(x => x.Id == "abc")), Times.Once); + _mocker.Verify>(x => x.GetAll(), Times.Once); + _mocker.Verify>(x => x.Add(It.IsAny()), Times.Once); + } + + [Test] + public async Task TvRequestFromWatchList_AlreadyRequested() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + _mocker.Setup>(x => x.GetWatchlist(It.IsAny(), It.IsAny())).ReturnsAsync(new PlexWatchlistContainer + { + MediaContainer = new PlexWatchlist + { + Metadata = new List + { + new Metadata + { + type = "show", + ratingKey = "abc" + } + } + } + }); + _mocker.Setup>(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny())) + .ReturnsAsync(new PlexWatchlistMetadataContainer + { + MediaContainer = new PlexWatchlistMetadata + { + Metadata = new WatchlistMetadata[] + { + new WatchlistMetadata + { + Guid = new List + { + new PlexGuids + { + Id = "tmdb://123" + } + } + } + } + + } + }); + _mocker.Setup>(x => x.RequestTvShow(It.IsAny())) + .ReturnsAsync(new RequestEngineResult { ErrorCode = ErrorCode.AlreadyRequested, ErrorMessage = "Requested" }); + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.RequestTvShow(It.Is(x => x.TheMovieDbId == 123)), Times.Once); + _mocker.Verify(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.SetUser(It.Is(x => x.Id == "abc")), Times.Once); + _mocker.Verify>(x => x.GetAll(), Times.Once); + _mocker.Verify>(x => x.Add(It.IsAny()), Times.Once); + } + + [Test] + public async Task MovieRequestFromWatchList_NoTmdbGuid() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + _mocker.Setup>(x => x.GetWatchlist(It.IsAny(), It.IsAny())).ReturnsAsync(new PlexWatchlistContainer + { + MediaContainer = new PlexWatchlist + { + Metadata = new List + { + new Metadata + { + type = "movie", + ratingKey = "abc" + } + } + } + }); + _mocker.Setup>(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny())) + .ReturnsAsync(new PlexWatchlistMetadataContainer + { + MediaContainer = new PlexWatchlistMetadata + { + Metadata = new WatchlistMetadata[] + { + new WatchlistMetadata + { + Guid = new List + { + new PlexGuids + { + Id = "imdb://123" + } + } + } + } + + } + }); + _mocker.Setup>(x => x.RequestMovie(It.IsAny())) + .ReturnsAsync(new RequestEngineResult { RequestId = 1 }); + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + _mocker.Verify(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.SetUser(It.Is(x => x.Id == "abc")), Times.Never); + _mocker.Verify>(x => x.Add(It.IsAny()), Times.Never); + _mocker.Verify>(x => x.GetAll(), Times.Never); + } + + [Test] + public async Task TvRequestFromWatchList_NoTmdbGuid() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + _mocker.Setup>(x => x.GetWatchlist(It.IsAny(), It.IsAny())).ReturnsAsync(new PlexWatchlistContainer + { + MediaContainer = new PlexWatchlist + { + Metadata = new List + { + new Metadata + { + type = "movie", + ratingKey = "abc" + } + } + } + }); + _mocker.Setup>(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny())) + .ReturnsAsync(new PlexWatchlistMetadataContainer + { + MediaContainer = new PlexWatchlistMetadata + { + Metadata = new WatchlistMetadata[] + { + new WatchlistMetadata + { + Guid = new List + { + new PlexGuids + { + Id = "imdb://123" + } + } + } + } + + } + }); + _mocker.Setup>(x => x.RequestTvShow(It.IsAny())) + .ReturnsAsync(new RequestEngineResult { RequestId = 1 }); + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.RequestTvShow(It.IsAny()), Times.Never); + _mocker.Verify(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.SetUser(It.Is(x => x.Id == "abc")), Times.Never); + _mocker.Verify>(x => x.Add(It.IsAny()), Times.Never); + _mocker.Verify>(x => x.GetAll(), Times.Never); + } + + [Test] + public async Task MovieRequestFromWatchList_AlreadyImported() + { + _mocker.Setup, Task>(x => x.GetSettingsAsync()).ReturnsAsync(new PlexSettings { Enable = true, EnableWatchlistImport = true }); + _mocker.Setup>(x => x.GetWatchlist(It.IsAny(), It.IsAny())).ReturnsAsync(new PlexWatchlistContainer + { + MediaContainer = new PlexWatchlist + { + Metadata = new List + { + new Metadata + { + type = "movie", + ratingKey = "abc" + } + } + } + }); + _mocker.Setup>(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny())) + .ReturnsAsync(new PlexWatchlistMetadataContainer + { + MediaContainer = new PlexWatchlistMetadata + { + Metadata = new WatchlistMetadata[] + { + new WatchlistMetadata + { + Guid = new List + { + new PlexGuids + { + Id = "tmdb://123" + } + } + } + } + + } + }); + _mocker.Setup, IQueryable>(x => x.GetAll()).Returns(new List { new PlexWatchlistHistory { Id = 1, TmdbId = "123" } }.AsQueryable()); + await _subject.Execute(_context.Object); + _mocker.Verify(x => x.RequestMovie(It.IsAny()), Times.Never); + _mocker.Verify(x => x.GetWatchlistMetadata("abc", It.IsAny(), It.IsAny()), Times.Once); + _mocker.Verify(x => x.SetUser(It.Is(x => x.Id == "abc")), Times.Never); + _mocker.Verify>(x => x.Add(It.IsAny()), Times.Never); + _mocker.Verify>(x => x.GetAll(), Times.Once); + } + } +} diff --git a/src/Ombi.Schedule/Jobs/ArrAvailabilityChecker.cs b/src/Ombi.Schedule/Jobs/ArrAvailabilityChecker.cs index 0020bb24f..d20f906c6 100644 --- a/src/Ombi.Schedule/Jobs/ArrAvailabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/ArrAvailabilityChecker.cs @@ -73,23 +73,37 @@ namespace Ombi.Schedule.Jobs.Radarr private async Task ProcessMovies() { var availableRadarrMovies = _radarrRepo.GetAll().Where(x => x.HasFile).ToImmutableHashSet(); - var unavailableMovieRequests = _movies.GetAll().Where(x => !x.Available).ToImmutableHashSet(); + var unavailableMovieRequests = _movies.GetAll().Where(x => !x.Available || (!x.Available4K && x.Has4KRequest)).ToImmutableHashSet(); var itemsForAvailability = new List(); foreach (var movieRequest in unavailableMovieRequests) { // Do we have an item in the radarr list - var available = availableRadarrMovies.Any(x => x.TheMovieDbId == movieRequest.TheMovieDbId); - if (available) + var available = availableRadarrMovies.FirstOrDefault(x => x.TheMovieDbId == movieRequest.TheMovieDbId); + if (available != null) { _logger.LogInformation($"Found move '{movieRequest.Title}' available in Radarr"); - movieRequest.Available = true; - movieRequest.MarkedAsAvailable = DateTime.UtcNow; - itemsForAvailability.Add(new AvailabilityModel + if (available.Has4K && !movieRequest.Available4K) { - Id = movieRequest.Id, - RequestedUser = movieRequest.RequestedUser != null ? movieRequest.RequestedUser.Email : string.Empty - }); + itemsForAvailability.Add(new AvailabilityModel + { + Id = movieRequest.Id, + RequestedUser = movieRequest.RequestedUser != null ? movieRequest.RequestedUser.Email : string.Empty + }); + movieRequest.Available4K = true; + movieRequest.MarkedAsAvailable4K = DateTime.UtcNow; + } + if (available.HasRegular) + { + itemsForAvailability.Add(new AvailabilityModel + { + Id = movieRequest.Id, + RequestedUser = movieRequest.RequestedUser != null ? movieRequest.RequestedUser.Email : string.Empty + }); + movieRequest.Available = true; + movieRequest.MarkedAsAvailable = DateTime.UtcNow; + } + await _movies.SaveChangesAsync(); } } @@ -97,7 +111,6 @@ namespace Ombi.Schedule.Jobs.Radarr { await _hub.Clients.Clients(NotificationHub.AdminConnectionIds) .SendAsync(NotificationHub.NotificationEvent, "Radarr Availability Checker found some new available movies!"); - await _movies.SaveChangesAsync(); } foreach (var item in itemsForAvailability) { @@ -110,7 +123,6 @@ namespace Ombi.Schedule.Jobs.Radarr Recipient = item.RequestedUser }); } - } public async Task ProcessTvShows() diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyAvaliabilityChecker.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyAvaliabilityChecker.cs index 608d6cb82..8e8b75e45 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyAvaliabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyAvaliabilityChecker.cs @@ -7,10 +7,12 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Ombi.Core; using Ombi.Core.Notifications; +using Ombi.Core.Services; using Ombi.Helpers; using Ombi.Hubs; using Ombi.Notifications.Models; using Ombi.Schedule.Jobs.Ombi; +using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; using Ombi.Store.Repository; using Ombi.Store.Repository.Requests; @@ -21,7 +23,7 @@ namespace Ombi.Schedule.Jobs.Emby public class EmbyAvaliabilityChecker : IEmbyAvaliabilityChecker { public EmbyAvaliabilityChecker(IEmbyContentRepository repo, ITvRequestRepository t, IMovieRequestRepository m, - INotificationHelper n, ILogger log, IHubContext notification) + INotificationHelper n, ILogger log, IHubContext notification, IFeatureService featureService) { _repo = repo; _tvRepo = t; @@ -29,6 +31,7 @@ namespace Ombi.Schedule.Jobs.Emby _notificationService = n; _log = log; _notification = notification; + _featureService = featureService; } private readonly ITvRequestRepository _tvRepo; @@ -37,6 +40,7 @@ namespace Ombi.Schedule.Jobs.Emby private readonly INotificationHelper _notificationService; private readonly ILogger _log; private readonly IHubContext _notification; + private readonly IFeatureService _featureService; public async Task Execute(IJobExecutionContext job) { @@ -53,10 +57,12 @@ namespace Ombi.Schedule.Jobs.Emby private async Task ProcessMovies() { - var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available); + var feature4kEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests); + var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available || (!x.Available4K && x.Has4KRequest)); foreach (var movie in movies) { + var has4kRequest = movie.Has4KRequest; EmbyContent embyContent = null; if (movie.TheMovieDbId > 0) { @@ -75,9 +81,23 @@ namespace Ombi.Schedule.Jobs.Emby _log.LogInformation("We have found the request {0} on Emby, sending the notification", movie?.Title ?? string.Empty); - movie.Available = true; - movie.MarkedAsAvailable = DateTime.Now; - if (movie.Available) + var notify = false; + + if (has4kRequest && embyContent.Has4K && !movie.Available4K) + { + movie.Available4K = true; + movie.MarkedAsAvailable4K = DateTime.Now; + notify = true; + } + + // If we have a non-4k version or we don't care about versions, then mark as available + if (!movie.Available && ( !feature4kEnabled || embyContent.Quality != null )) + { + movie.Available = true; + movie.MarkedAsAvailable = DateTime.Now; + notify = true; + } + if (notify) { var recipient = movie.RequestedUser.Email.HasValue() ? movie.RequestedUser.Email : string.Empty; @@ -124,7 +144,7 @@ namespace Ombi.Schedule.Jobs.Emby var tvDbId = child.ParentRequest.TvDbId; var imdbId = child.ParentRequest.ImdbId; - IQueryable seriesEpisodes = null; + IQueryable seriesEpisodes = null; if (useImdb) { seriesEpisodes = embyEpisodes.Where(x => x.Series.ImdbId == imdbId.ToString()); diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs index 0630c0b28..27cdf0f3a 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyContentSync.cs @@ -1,10 +1,13 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.SignalR; using Microsoft.Extensions.Logging; using Ombi.Api.Emby; +using Ombi.Api.Emby.Models; +using Ombi.Api.Emby.Models.Media.Tv; using Ombi.Api.Emby.Models.Movie; using Ombi.Core.Settings; using Ombi.Core.Settings.Models.External; @@ -14,7 +17,7 @@ using Ombi.Schedule.Jobs.Ombi; using Ombi.Store.Entities; using Ombi.Store.Repository; using Quartz; -using EmbyMediaType = Ombi.Store.Entities.EmbyMediaType; +using MediaType = Ombi.Store.Entities.MediaType; namespace Ombi.Schedule.Jobs.Emby { @@ -36,24 +39,33 @@ namespace Ombi.Schedule.Jobs.Emby private readonly IEmbyContentRepository _repo; private readonly IHubContext _notification; + private const int AmountToTake = 100; + private IEmbyApi Api { get; set; } - public async Task Execute(IJobExecutionContext job) + public async Task Execute(IJobExecutionContext context) { + JobDataMap dataMap = context.JobDetail.JobDataMap; + var recentlyAddedSearch = false; + if (dataMap.TryGetValue(JobDataKeys.EmbyRecentlyAddedSearch, out var recentlyAddedObj)) + { + recentlyAddedSearch = Convert.ToBoolean(recentlyAddedObj); + } + var embySettings = await _settings.GetSettingsAsync(); if (!embySettings.Enable) return; - + Api = _apiFactory.CreateClient(embySettings); await _notification.Clients.Clients(NotificationHub.AdminConnectionIds) - .SendAsync(NotificationHub.NotificationEvent, "Emby Content Sync Started"); + .SendAsync(NotificationHub.NotificationEvent, recentlyAddedSearch ? "Emby Recently Added Started" : "Emby Content Sync Started"); foreach (var server in embySettings.Servers) { try { - await StartServerCache(server, embySettings); + await StartServerCache(server, recentlyAddedSearch); } catch (Exception e) { @@ -67,17 +79,18 @@ namespace Ombi.Schedule.Jobs.Emby .SendAsync(NotificationHub.NotificationEvent, "Emby Content Sync Finished"); // Episodes - await OmbiQuartz.TriggerJob(nameof(IEmbyEpisodeSync), "Emby"); + + await OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(IEmbyEpisodeSync), "Emby"), new JobDataMap(new Dictionary { { JobDataKeys.EmbyRecentlyAddedSearch, recentlyAddedSearch.ToString() } })); } - private async Task StartServerCache(EmbyServers server, EmbySettings settings) + private async Task StartServerCache(EmbyServers server, bool recentlyAdded) { if (!ValidateSettings(server)) + { return; + } - //await _repo.ExecuteSql("DELETE FROM EmbyEpisode"); - //await _repo.ExecuteSql("DELETE FROM EmbyContent"); if (server.EmbySelectedLibraries.Any() && server.EmbySelectedLibraries.Any(x => x.Enabled)) { @@ -86,14 +99,14 @@ namespace Ombi.Schedule.Jobs.Emby foreach (var movieParentIdFilder in movieLibsToFilter) { _logger.LogInformation($"Scanning Lib '{movieParentIdFilder.Title}'"); - await ProcessMovies(server, movieParentIdFilder.Key); + await ProcessMovies(server, recentlyAdded, movieParentIdFilder.Key); } var tvLibsToFilter = server.EmbySelectedLibraries.Where(x => x.Enabled && x.CollectionType == "tvshows"); foreach (var tvParentIdFilter in tvLibsToFilter) { _logger.LogInformation($"Scanning Lib '{tvParentIdFilter.Title}'"); - await ProcessTv(server, tvParentIdFilter.Key); + await ProcessTv(server, recentlyAdded, tvParentIdFilter.Key); } @@ -101,68 +114,85 @@ namespace Ombi.Schedule.Jobs.Emby foreach (var m in mixedLibs) { _logger.LogInformation($"Scanning Lib '{m.Title}'"); - await ProcessTv(server, m.Key); - await ProcessMovies(server, m.Key); + await ProcessTv(server, recentlyAdded, m.Key); + await ProcessMovies(server, recentlyAdded, m.Key); } } else { - await ProcessMovies(server); - await ProcessTv(server); + await ProcessMovies(server, recentlyAdded); + await ProcessTv(server, recentlyAdded); } } - private async Task ProcessTv(EmbyServers server, string parentId = default) + private async Task ProcessTv(EmbyServers server, bool recentlyAdded, string parentId = default) { // TV Time var mediaToAdd = new HashSet(); - var tv = await Api.GetAllShows(server.ApiKey, parentId, 0, 200, server.AdministratorId, server.FullUri); + EmbyItemContainer tv; + if (recentlyAdded) + { + var recentlyAddedAmountToTake = AmountToTake / 2; + tv = await Api.RecentlyAddedShows(server.ApiKey, parentId, 0, recentlyAddedAmountToTake, server.AdministratorId, server.FullUri); + if (tv.TotalRecordCount > recentlyAddedAmountToTake) + { + tv.TotalRecordCount = recentlyAddedAmountToTake; + } + } + else + { + tv = await Api.GetAllShows(server.ApiKey, parentId, 0, AmountToTake, server.AdministratorId, server.FullUri); + } var totalTv = tv.TotalRecordCount; - var processed = 1; + var processed = 0; while (processed < totalTv) { foreach (var tvShow in tv.Items) { - try + processed++; + if (!tvShow.ProviderIds.Any()) { - - processed++; - if (string.IsNullOrEmpty(tvShow.ProviderIds?.Tvdb)) - { - _logger.LogInformation("Provider Id on tv {0} is null", tvShow.Name); - continue; - } - - var existingTv = await _repo.GetByEmbyId(tvShow.Id); - if (existingTv == null) - { - _logger.LogDebug("Adding new TV Show {0}", tvShow.Name); - mediaToAdd.Add(new EmbyContent - { - TvDbId = tvShow.ProviderIds?.Tvdb, - ImdbId = tvShow.ProviderIds?.Imdb, - TheMovieDbId = tvShow.ProviderIds?.Tmdb, - Title = tvShow.Name, - Type = EmbyMediaType.Series, - EmbyId = tvShow.Id, - Url = EmbyHelper.GetEmbyMediaUrl(tvShow.Id, server?.ServerId, server.ServerHostname), - AddedAt = DateTime.UtcNow - }); - } - else - { - _logger.LogDebug("We already have TV Show {0}", tvShow.Name); - } - + _logger.LogInformation("Provider Id on tv {0} is null", tvShow.Name); + continue; } - catch (Exception) - { - throw; + var existingTv = await _repo.GetByEmbyId(tvShow.Id); + + if (existingTv != null && + ( existingTv.ImdbId != tvShow.ProviderIds?.Imdb + || existingTv.TheMovieDbId != tvShow.ProviderIds?.Tmdb + || existingTv.TvDbId != tvShow.ProviderIds?.Tvdb)) + { + _logger.LogDebug($"Series '{tvShow.Name}' has different IDs, probably a reidentification."); + await _repo.DeleteTv(existingTv); + existingTv = null; + } + + if (existingTv == null) + { + _logger.LogDebug("Adding TV Show {0}", tvShow.Name); + mediaToAdd.Add(new EmbyContent + { + TvDbId = tvShow.ProviderIds?.Tvdb, + ImdbId = tvShow.ProviderIds?.Imdb, + TheMovieDbId = tvShow.ProviderIds?.Tmdb, + Title = tvShow.Name, + Type = MediaType.Series, + EmbyId = tvShow.Id, + Url = EmbyHelper.GetEmbyMediaUrl(tvShow.Id, server?.ServerId, server.ServerHostname), + AddedAt = DateTime.UtcNow, + }); + } + else + { + _logger.LogDebug("We already have TV Show {0}", tvShow.Name); } } // Get the next batch - tv = await Api.GetAllShows(server.ApiKey, parentId, processed, 200, server.AdministratorId, server.FullUri); + if (!recentlyAdded) + { + tv = await Api.GetAllShows(server.ApiKey, parentId, processed, AmountToTake, server.AdministratorId, server.FullUri); + } await _repo.AddRange(mediaToAdd); mediaToAdd.Clear(); } @@ -171,12 +201,27 @@ namespace Ombi.Schedule.Jobs.Emby await _repo.AddRange(mediaToAdd); } - private async Task ProcessMovies(EmbyServers server, string parentId = default) + private async Task ProcessMovies(EmbyServers server, bool recentlyAdded, string parentId = default) { - var movies = await Api.GetAllMovies(server.ApiKey, parentId, 0, 200, server.AdministratorId, server.FullUri); + EmbyItemContainer movies; + if (recentlyAdded) + { + var recentlyAddedAmountToTake = AmountToTake / 2; + movies = await Api.RecentlyAddedMovies(server.ApiKey, parentId, 0, recentlyAddedAmountToTake, server.AdministratorId, server.FullUri); + // Setting this so we don't attempt to grab more than we need + if (movies.TotalRecordCount > recentlyAddedAmountToTake) + { + movies.TotalRecordCount = recentlyAddedAmountToTake; + } + } + else + { + movies = await Api.GetAllMovies(server.ApiKey, parentId, 0, AmountToTake, server.AdministratorId, server.FullUri); + } var totalCount = movies.TotalRecordCount; - var processed = 1; + var processed = 0; var mediaToAdd = new HashSet(); + var mediaToUpdate = new HashSet(); while (processed < totalCount) { foreach (var movie in movies.Items) @@ -187,53 +232,99 @@ namespace Ombi.Schedule.Jobs.Emby await Api.GetCollection(movie.Id, server.ApiKey, server.AdministratorId, server.FullUri); foreach (var item in movieInfo.Items) { - await ProcessMovies(item, mediaToAdd, server); + await ProcessMovies(item, mediaToAdd, mediaToUpdate, server); } - - processed++; } else { - processed++; // Regular movie - await ProcessMovies(movie, mediaToAdd, server); + await ProcessMovies(movie, mediaToAdd, mediaToUpdate, server); } + + processed++; } // Get the next batch - movies = await Api.GetAllMovies(server.ApiKey, parentId, processed, 200, server.AdministratorId, server.FullUri); + // Recently Added should never be checked as the TotalRecords should equal the amount to take + if (!recentlyAdded) + { + movies = await Api.GetAllMovies(server.ApiKey, parentId, processed, AmountToTake, server.AdministratorId, server.FullUri); + } await _repo.AddRange(mediaToAdd); + await _repo.UpdateRange(mediaToUpdate); mediaToAdd.Clear(); - } } - private async Task ProcessMovies(EmbyMovie movieInfo, ICollection content, EmbyServers server) + private async Task ProcessMovies(EmbyMovie movieInfo, ICollection content, ICollection toUpdate, EmbyServers server) { + var quality = movieInfo.MediaStreams?.FirstOrDefault()?.DisplayTitle ?? string.Empty; + var has4K = false; + if (quality.Contains("4K", CompareOptions.IgnoreCase)) + { + has4K = true; + } + // Check if it exists var existingMovie = await _repo.GetByEmbyId(movieInfo.Id); var alreadyGoingToAdd = content.Any(x => x.EmbyId == movieInfo.Id); if (existingMovie == null && !alreadyGoingToAdd) { - _logger.LogDebug("Adding new movie {0}", movieInfo.Name); - content.Add(new EmbyContent + if (!movieInfo.ProviderIds.Any()) { - ImdbId = movieInfo.ProviderIds.Imdb, - TheMovieDbId = movieInfo.ProviderIds?.Tmdb, - Title = movieInfo.Name, - Type = EmbyMediaType.Movie, - EmbyId = movieInfo.Id, - Url = EmbyHelper.GetEmbyMediaUrl(movieInfo.Id, server?.ServerId, server.ServerHostname), - AddedAt = DateTime.UtcNow, - }); + _logger.LogWarning($"Movie {movieInfo.Name} has no relevant metadata. Skipping."); + return; + } + _logger.LogDebug($"Adding new movie {movieInfo.Name}"); + var newMovie = new EmbyContent(); + newMovie.AddedAt = DateTime.UtcNow; + MapEmbyContent(newMovie, movieInfo, server, has4K, quality); + content.Add(newMovie); } else { - // we have this - _logger.LogDebug("We already have movie {0}", movieInfo.Name); + var movieHasChanged = false; + if (existingMovie.ImdbId != movieInfo.ProviderIds.Imdb || existingMovie.TheMovieDbId != movieInfo.ProviderIds.Tmdb) + { + _logger.LogDebug($"Updating existing movie '{movieInfo.Name}'"); + MapEmbyContent(existingMovie, movieInfo, server, has4K, quality); + movieHasChanged = true; + } + else if (!quality.Equals(existingMovie?.Quality, StringComparison.InvariantCultureIgnoreCase)) + { + _logger.LogDebug($"We have found another quality for Movie '{movieInfo.Name}', Quality: '{quality}'"); + existingMovie.Quality = has4K ? null : quality; + existingMovie.Has4K = has4K; + + // Probably could refactor here + // If a 4k movie comes in (we don't store the quality on 4k) + // it will always get updated even know it's not changed + movieHasChanged = true; + } + + if (movieHasChanged) + { + toUpdate.Add(existingMovie); + } + else + { + // we have this + _logger.LogDebug($"We already have movie {movieInfo.Name}"); + } } } + private void MapEmbyContent(EmbyContent content, EmbyMovie movieInfo, EmbyServers server, bool has4K, string quality){ + content.ImdbId = movieInfo.ProviderIds.Imdb; + content.TheMovieDbId = movieInfo.ProviderIds?.Tmdb; + content.Title = movieInfo.Name; + content.Type = MediaType.Movie; + content.EmbyId = movieInfo.Id; + content.Url = EmbyHelper.GetEmbyMediaUrl(movieInfo.Id, server?.ServerId, server.ServerHostname); + content.Quality = has4K ? null : quality; + content.Has4K = has4K; + } + private bool ValidateSettings(EmbyServers server) { if (server?.Ip == null || string.IsNullOrEmpty(server?.ApiKey)) diff --git a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs index 1a55da6c9..5293d30b4 100644 --- a/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Emby/EmbyEpisodeSync.cs @@ -40,6 +40,8 @@ using Ombi.Store.Entities; using Ombi.Store.Repository; using Quartz; using Ombi.Schedule.Jobs.Ombi; +using Ombi.Api.Emby.Models; +using Ombi.Api.Emby.Models.Media.Tv; namespace Ombi.Schedule.Jobs.Emby { @@ -61,13 +63,22 @@ namespace Ombi.Schedule.Jobs.Emby private readonly IEmbyContentRepository _repo; private readonly IHubContext _notification; + private const int AmountToTake = 100; + private IEmbyApi Api { get; set; } - public async Task Execute(IJobExecutionContext job) + public async Task Execute(IJobExecutionContext context) { + JobDataMap dataMap = context.MergedJobDataMap; + var recentlyAddedSearch = false; + if (dataMap.TryGetValue(JobDataKeys.EmbyRecentlyAddedSearch, out var recentlyAddedObj)) + { + recentlyAddedSearch = Convert.ToBoolean(recentlyAddedObj); + } + var settings = await _settings.GetSettingsAsync(); - + Api = _apiFactory.CreateClient(settings); await _notification.Clients.Clients(NotificationHub.AdminConnectionIds) .SendAsync(NotificationHub.NotificationEvent, "Emby Episode Sync Started"); @@ -79,12 +90,12 @@ namespace Ombi.Schedule.Jobs.Emby foreach (var tvParentIdFilter in tvLibsToFilter) { _logger.LogInformation($"Scanning Lib for episodes '{tvParentIdFilter.Title}'"); - await CacheEpisodes(server, tvParentIdFilter.Key); + await CacheEpisodes(server, recentlyAddedSearch, tvParentIdFilter.Key); } } else { - await CacheEpisodes(server, string.Empty); + await CacheEpisodes(server, recentlyAddedSearch, string.Empty); } } @@ -94,11 +105,24 @@ namespace Ombi.Schedule.Jobs.Emby await OmbiQuartz.TriggerJob(nameof(IRefreshMetadata), "System"); } - private async Task CacheEpisodes(EmbyServers server, string parentIdFilter) + private async Task CacheEpisodes(EmbyServers server, bool recentlyAdded, string parentIdFilter) { - var allEpisodes = await Api.GetAllEpisodes(server.ApiKey, parentIdFilter, 0, 200, server.AdministratorId, server.FullUri); + EmbyItemContainer allEpisodes; + if (recentlyAdded) + { + var recentlyAddedAmountToTake = AmountToTake; + allEpisodes = await Api.RecentlyAddedEpisodes(server.ApiKey, parentIdFilter, 0, recentlyAddedAmountToTake, server.AdministratorId, server.FullUri); + if (allEpisodes.TotalRecordCount > recentlyAddedAmountToTake) + { + allEpisodes.TotalRecordCount = recentlyAddedAmountToTake; + } + } + else + { + allEpisodes = await Api.GetAllEpisodes(server.ApiKey, parentIdFilter, 0, AmountToTake, server.AdministratorId, server.FullUri); + } var total = allEpisodes.TotalRecordCount; - var processed = 1; + var processed = 0; var epToAdd = new HashSet(); while (processed < total) { @@ -106,12 +130,6 @@ namespace Ombi.Schedule.Jobs.Emby { processed++; - if (ep.LocationType?.Equals("Virtual", StringComparison.InvariantCultureIgnoreCase) ?? false) - { - // For some reason Emby is not respecting the `IsVirtualItem` field. - continue; - } - // Let's make sure we have the parent request, stop those pesky forign key errors, // Damn me having data integrity var parent = await _repo.GetByEmbyId(ep.SeriesId); @@ -128,6 +146,13 @@ namespace Ombi.Schedule.Jobs.Emby if (existingEpisode == null && !existingInList) { + // Sanity checks + if (ep.IndexNumber == 0) + { + _logger.LogWarning($"Episode {ep.Name} has no episode number. Skipping."); + continue; + } + _logger.LogDebug("Adding new episode {0} to parent {1}", ep.Name, ep.SeriesName); // add it epToAdd.Add(new EmbyEpisode @@ -145,25 +170,36 @@ namespace Ombi.Schedule.Jobs.Emby if (ep.IndexNumberEnd.HasValue && ep.IndexNumberEnd.Value != ep.IndexNumber) { - epToAdd.Add(new EmbyEpisode + int episodeNumber = ep.IndexNumber; + do { - EmbyId = ep.Id, - EpisodeNumber = ep.IndexNumberEnd.Value, - SeasonNumber = ep.ParentIndexNumber, - ParentId = ep.SeriesId, - TvDbId = ep.ProviderIds.Tvdb, - TheMovieDbId = ep.ProviderIds.Tmdb, - ImdbId = ep.ProviderIds.Imdb, - Title = ep.Name, - AddedAt = DateTime.UtcNow - }); + _logger.LogDebug($"Multiple-episode file detected. Adding episode ${episodeNumber}"); + episodeNumber++; + epToAdd.Add(new EmbyEpisode + { + EmbyId = ep.Id, + EpisodeNumber = episodeNumber, + SeasonNumber = ep.ParentIndexNumber, + ParentId = ep.SeriesId, + TvDbId = ep.ProviderIds.Tvdb, + TheMovieDbId = ep.ProviderIds.Tmdb, + ImdbId = ep.ProviderIds.Imdb, + Title = ep.Name, + AddedAt = DateTime.UtcNow + }); + + } while (episodeNumber < ep.IndexNumberEnd.Value); + } } } await _repo.AddRange(epToAdd); epToAdd.Clear(); - allEpisodes = await Api.GetAllEpisodes(server.ApiKey, parentIdFilter, processed, 200, server.AdministratorId, server.FullUri); + if (!recentlyAdded) + { + allEpisodes = await Api.GetAllEpisodes(server.ApiKey, parentIdFilter, processed, AmountToTake, server.AdministratorId, server.FullUri); + } } if (epToAdd.Any()) diff --git a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinAvaliabilityChecker.cs b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinAvaliabilityChecker.cs index 1a621ebce..79eb5d6a4 100644 --- a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinAvaliabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinAvaliabilityChecker.cs @@ -33,11 +33,11 @@ using Microsoft.AspNetCore.SignalR; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Ombi.Core; -using Ombi.Core.Notifications; +using Ombi.Core.Services; using Ombi.Helpers; using Ombi.Hubs; using Ombi.Notifications.Models; -using Ombi.Schedule.Jobs.Ombi; +using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; using Ombi.Store.Repository; using Ombi.Store.Repository.Requests; @@ -48,7 +48,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin public class JellyfinAvaliabilityChecker : IJellyfinAvaliabilityChecker { public JellyfinAvaliabilityChecker(IJellyfinContentRepository repo, ITvRequestRepository t, IMovieRequestRepository m, - INotificationHelper n, ILogger log, IHubContext notification) + INotificationHelper n, ILogger log, IHubContext notification, IFeatureService featureService) { _repo = repo; _tvRepo = t; @@ -56,6 +56,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin _notificationService = n; _log = log; _notification = notification; + _featureService = featureService; } private readonly ITvRequestRepository _tvRepo; @@ -64,6 +65,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin private readonly INotificationHelper _notificationService; private readonly ILogger _log; private readonly IHubContext _notification; + private readonly IFeatureService _featureService; public async Task Execute(IJobExecutionContext job) { @@ -80,10 +82,12 @@ namespace Ombi.Schedule.Jobs.Jellyfin private async Task ProcessMovies() { - var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available); + var feature4kEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests); + var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available || (!x.Available4K && x.Has4KRequest)); foreach (var movie in movies) { + var has4kRequest = movie.Has4KRequest; JellyfinContent jellyfinContent = null; if (movie.TheMovieDbId > 0) { @@ -102,9 +106,24 @@ namespace Ombi.Schedule.Jobs.Jellyfin _log.LogInformation("We have found the request {0} on Jellyfin, sending the notification", movie?.Title ?? string.Empty); - movie.Available = true; - movie.MarkedAsAvailable = DateTime.Now; - if (movie.Available) + var notify = false; + + if (has4kRequest && jellyfinContent.Has4K && !movie.Available4K) + { + movie.Available4K = true; + movie.MarkedAsAvailable4K = DateTime.Now; + notify = true; + } + + // If we have a non-4k version or we don't care about versions, then mark as available + if (!movie.Available && ( !feature4kEnabled || jellyfinContent.Quality != null )) + { + movie.Available = true; + movie.MarkedAsAvailable = DateTime.Now; + notify = true; + } + + if (notify) { var recipient = movie.RequestedUser.Email.HasValue() ? movie.RequestedUser.Email : string.Empty; @@ -151,7 +170,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin var tvDbId = child.ParentRequest.TvDbId; var imdbId = child.ParentRequest.ImdbId; - IQueryable seriesEpisodes = null; + IQueryable seriesEpisodes = null; if (useImdb) { seriesEpisodes = jellyfinEpisodes.Where(x => x.Series.ImdbId == imdbId.ToString()); diff --git a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs index 2a950fcf4..5519b3413 100644 --- a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinContentSync.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.SignalR; @@ -14,7 +15,7 @@ using Ombi.Schedule.Jobs.Ombi; using Ombi.Store.Entities; using Ombi.Store.Repository; using Quartz; -using JellyfinMediaType = Ombi.Store.Entities.JellyfinMediaType; +using MediaType = Ombi.Store.Entities.MediaType; namespace Ombi.Schedule.Jobs.Jellyfin { @@ -77,9 +78,6 @@ namespace Ombi.Schedule.Jobs.Jellyfin return; } - //await _repo.ExecuteSql("DELETE FROM JellyfinEpisode"); - //await _repo.ExecuteSql("DELETE FROM JellyfinContent"); - if (server.JellyfinSelectedLibraries.Any() && server.JellyfinSelectedLibraries.Any(x => x.Enabled)) { var movieLibsToFilter = server.JellyfinSelectedLibraries.Where(x => x.Enabled && x.CollectionType == "movies"); @@ -118,7 +116,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin var mediaToAdd = new HashSet(); var tv = await Api.GetAllShows(server.ApiKey, parentId, 0, 200, server.AdministratorId, server.FullUri); var totalTv = tv.TotalRecordCount; - var processed = 1; + var processed = 0; while (processed < totalTv) { foreach (var tvShow in tv.Items) @@ -127,23 +125,34 @@ namespace Ombi.Schedule.Jobs.Jellyfin { processed++; - if (string.IsNullOrEmpty(tvShow.ProviderIds?.Tvdb)) + if (!tvShow.ProviderIds.Any()) { _logger.LogInformation("Provider Id on tv {0} is null", tvShow.Name); continue; } var existingTv = await _repo.GetByJellyfinId(tvShow.Id); + + if (existingTv != null && + ( existingTv.ImdbId != tvShow.ProviderIds?.Imdb + || existingTv.TheMovieDbId != tvShow.ProviderIds?.Tmdb + || existingTv.TvDbId != tvShow.ProviderIds?.Tvdb)) + { + _logger.LogDebug($"Series '{tvShow.Name}' has different IDs, probably a reidentification."); + await _repo.DeleteTv(existingTv); + existingTv = null; + } + if (existingTv == null) { - _logger.LogDebug("Adding new TV Show {0}", tvShow.Name); + _logger.LogDebug("Adding TV Show {0}", tvShow.Name); mediaToAdd.Add(new JellyfinContent { TvDbId = tvShow.ProviderIds?.Tvdb, ImdbId = tvShow.ProviderIds?.Imdb, TheMovieDbId = tvShow.ProviderIds?.Tmdb, Title = tvShow.Name, - Type = JellyfinMediaType.Series, + Type = MediaType.Series, JellyfinId = tvShow.Id, Url = JellyfinHelper.GetJellyfinMediaUrl(tvShow.Id, server?.ServerId, server.ServerHostname), AddedAt = DateTime.UtcNow @@ -177,8 +186,9 @@ namespace Ombi.Schedule.Jobs.Jellyfin { var movies = await Api.GetAllMovies(server.ApiKey, parentId, 0, 200, server.AdministratorId, server.FullUri); var totalCount = movies.TotalRecordCount; - var processed = 1; + var processed = 0; var mediaToAdd = new HashSet(); + var mediaToUpdate = new HashSet(); while (processed < totalCount) { foreach (var movie in movies.Items) @@ -189,7 +199,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin await Api.GetCollection(movie.Id, server.ApiKey, server.AdministratorId, server.FullUri); foreach (var item in movieInfo.Items) { - await ProcessMovies(item, mediaToAdd, server); + await ProcessMovies(item, mediaToAdd, mediaToUpdate, server); } processed++; @@ -198,44 +208,90 @@ namespace Ombi.Schedule.Jobs.Jellyfin { processed++; // Regular movie - await ProcessMovies(movie, mediaToAdd, server); + await ProcessMovies(movie, mediaToAdd, mediaToUpdate, server); } } // Get the next batch movies = await Api.GetAllMovies(server.ApiKey, parentId, processed, 200, server.AdministratorId, server.FullUri); await _repo.AddRange(mediaToAdd); + await _repo.UpdateRange(mediaToUpdate); mediaToAdd.Clear(); } } - private async Task ProcessMovies(JellyfinMovie movieInfo, ICollection content, JellyfinServers server) + private async Task ProcessMovies(JellyfinMovie movieInfo, ICollection content, ICollection toUpdate, JellyfinServers server) { + var quality = movieInfo.MediaStreams?.FirstOrDefault()?.DisplayTitle ?? string.Empty; + var has4K = false; + if (quality.Contains("4K", CompareOptions.IgnoreCase)) + { + has4K = true; + } + // Check if it exists var existingMovie = await _repo.GetByJellyfinId(movieInfo.Id); var alreadyGoingToAdd = content.Any(x => x.JellyfinId == movieInfo.Id); if (existingMovie == null && !alreadyGoingToAdd) { - _logger.LogDebug("Adding new movie {0}", movieInfo.Name); - content.Add(new JellyfinContent + if (!movieInfo.ProviderIds.Any()) { - ImdbId = movieInfo.ProviderIds.Imdb, - TheMovieDbId = movieInfo.ProviderIds?.Tmdb, - Title = movieInfo.Name, - Type = JellyfinMediaType.Movie, - JellyfinId = movieInfo.Id, - Url = JellyfinHelper.GetJellyfinMediaUrl(movieInfo.Id, server?.ServerId, server.ServerHostname), - AddedAt = DateTime.UtcNow, - }); + _logger.LogWarning($"Movie {movieInfo.Name} has no relevant metadata. Skipping."); + return; + } + _logger.LogDebug($"Adding new movie {movieInfo.Name}"); + var newMovie = new JellyfinContent(); + newMovie.AddedAt = DateTime.UtcNow; + MapJellyfinMovie(newMovie, movieInfo, server, has4K, quality); + content.Add(newMovie);; } else { - // we have this - _logger.LogDebug("We already have movie {0}", movieInfo.Name); + var movieHasChanged = false; + if (existingMovie.ImdbId != movieInfo.ProviderIds.Imdb || existingMovie.TheMovieDbId != movieInfo.ProviderIds.Tmdb) + { + _logger.LogDebug($"Updating existing movie '{movieInfo.Name}'"); + MapJellyfinMovie(existingMovie, movieInfo, server, has4K, quality); + movieHasChanged = true; + } + else if (!quality.Equals(existingMovie?.Quality, StringComparison.InvariantCultureIgnoreCase)) + { + _logger.LogDebug($"We have found another quality for Movie '{movieInfo.Name}', Quality: '{quality}'"); + existingMovie.Quality = has4K ? null : quality; + existingMovie.Has4K = has4K; + + // Probably could refactor here + // If a 4k movie comes in (we don't store the quality on 4k) + // it will always get updated even know it's not changed + toUpdate.Add(existingMovie); + movieHasChanged = true; + } + + if (movieHasChanged) + { + toUpdate.Add(existingMovie); + } + else + { + // we have this + _logger.LogDebug($"We already have movie {movieInfo.Name}"); + } } } + private void MapJellyfinMovie(JellyfinContent content, JellyfinMovie movieInfo, JellyfinServers server, bool has4K, string quality) + { + content.ImdbId = movieInfo.ProviderIds.Imdb; + content.TheMovieDbId = movieInfo.ProviderIds?.Tmdb; + content.Title = movieInfo.Name; + content.Type = MediaType.Movie; + content.JellyfinId = movieInfo.Id; + content.Url = JellyfinHelper.GetJellyfinMediaUrl(movieInfo.Id, server?.ServerId, server.ServerHostname); + content.Quality = has4K ? null : quality; + content.Has4K = has4K; + } + private bool ValidateSettings(JellyfinServers server) { if (server?.Ip == null || string.IsNullOrEmpty(server?.ApiKey)) diff --git a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinEpisodeSync.cs index 60f500d19..31b880114 100644 --- a/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Jellyfin/JellyfinEpisodeSync.cs @@ -66,7 +66,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin public async Task Execute(IJobExecutionContext job) { var settings = await _settings.GetSettingsAsync(); - + Api = _apiFactory.CreateClient(settings); await _notification.Clients.Clients(NotificationHub.AdminConnectionIds) .SendAsync(NotificationHub.NotificationEvent, "Jellyfin Episode Sync Started"); @@ -98,7 +98,7 @@ namespace Ombi.Schedule.Jobs.Jellyfin { var allEpisodes = await Api.GetAllEpisodes(server.ApiKey, parentIdFilter, 0, 200, server.AdministratorId, server.FullUri); var total = allEpisodes.TotalRecordCount; - var processed = 1; + var processed = 0; var epToAdd = new HashSet(); while (processed < total) { @@ -106,12 +106,6 @@ namespace Ombi.Schedule.Jobs.Jellyfin { processed++; - if (ep.LocationType?.Equals("Virtual", StringComparison.InvariantCultureIgnoreCase) ?? false) - { - // For some reason Jellyfin is not respecting the `IsVirtualItem` field. - continue; - } - // Let's make sure we have the parent request, stop those pesky forign key errors, // Damn me having data integrity var parent = await _repo.GetByJellyfinId(ep.SeriesId); @@ -128,6 +122,13 @@ namespace Ombi.Schedule.Jobs.Jellyfin if (existingEpisode == null && !existingInList) { + // Sanity checks + if (ep.IndexNumber == 0) // no check on season number, Season 0 can be Specials + { + _logger.LogWarning($"Episode {ep.Name} has no episode number. Skipping."); + continue; + } + _logger.LogDebug("Adding new episode {0} to parent {1}", ep.Name, ep.SeriesName); // add it epToAdd.Add(new JellyfinEpisode @@ -145,18 +146,25 @@ namespace Ombi.Schedule.Jobs.Jellyfin if (ep.IndexNumberEnd.HasValue && ep.IndexNumberEnd.Value != ep.IndexNumber) { - epToAdd.Add(new JellyfinEpisode + int episodeNumber = ep.IndexNumber; + do { - JellyfinId = ep.Id, - EpisodeNumber = ep.IndexNumberEnd.Value, - SeasonNumber = ep.ParentIndexNumber, - ParentId = ep.SeriesId, - TvDbId = ep.ProviderIds.Tvdb, - TheMovieDbId = ep.ProviderIds.Tmdb, - ImdbId = ep.ProviderIds.Imdb, - Title = ep.Name, - AddedAt = DateTime.UtcNow - }); + _logger.LogDebug($"Multiple-episode file detected. Adding episode ${episodeNumber}"); + episodeNumber++; + epToAdd.Add(new JellyfinEpisode + { + JellyfinId = ep.Id, + EpisodeNumber = episodeNumber, + SeasonNumber = ep.ParentIndexNumber, + ParentId = ep.SeriesId, + TvDbId = ep.ProviderIds.Tvdb, + TheMovieDbId = ep.ProviderIds.Tmdb, + ImdbId = ep.ProviderIds.Imdb, + Title = ep.Name, + AddedAt = DateTime.UtcNow + }); + + } while (episodeNumber < ep.IndexNumberEnd.Value); } } } diff --git a/src/Ombi.Schedule/Jobs/Ombi/AutoDeleteRequests.cs b/src/Ombi.Schedule/Jobs/Ombi/AutoDeleteRequests.cs index 6625a3bbb..eba3c4998 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/AutoDeleteRequests.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/AutoDeleteRequests.cs @@ -16,14 +16,16 @@ namespace Ombi.Schedule.Jobs.Ombi private readonly ISettingsService _ombiSettings; private readonly IMovieRequestRepository _movieRequests; private readonly ITvRequestRepository _tvRequestRepository; + private readonly IMusicRequestRepository _musicRequestRepository; private readonly ILogger _logger; public AutoDeleteRequests(ISettingsService ombiSettings, IMovieRequestRepository movieRequest, - ILogger logger, ITvRequestRepository tvRequestRepository) + ILogger logger, ITvRequestRepository tvRequestRepository, IMusicRequestRepository musicRequestRepository) { _ombiSettings = ombiSettings; _movieRequests = movieRequest; _tvRequestRepository = tvRequestRepository; + _musicRequestRepository = musicRequestRepository; _logger = logger; } @@ -37,6 +39,7 @@ namespace Ombi.Schedule.Jobs.Ombi var date = DateTime.UtcNow.AddDays(-settings.AutoDeleteAfterDays).Date; await ProcessMovieRequests(date); await ProcessTvRequests(date); + await ProcessMusicRequests(date); } private async Task ProcessMovieRequests(DateTime date) @@ -66,6 +69,20 @@ namespace Ombi.Schedule.Jobs.Ombi await _tvRequestRepository.DeleteRange(parentRequests); } + private async Task ProcessMusicRequests(DateTime date) + { + var requestsToDelete = await _musicRequestRepository.GetAll().Where(x => x.Available && x.MarkedAsAvailable.HasValue && x.MarkedAsAvailable.Value < date).ToListAsync(); + + _logger.LogInformation($"Deleting {requestsToDelete.Count} music requests that have now been scheduled for deletion, All available requests before {date::MM/dd/yyyy} will be deleted"); + foreach (var r in requestsToDelete) + { + _logger.LogInformation($"Deleting music title {r.Title} as it was approved on {r.MarkedAsApproved:MM/dd/yyyy hh:mm tt}"); + } + + await _musicRequestRepository.DeleteRange(requestsToDelete); + + } + private bool _disposed; protected virtual void Dispose(bool disposing) diff --git a/src/Ombi.Schedule/Jobs/Ombi/HtmlTemplateGenerator.cs b/src/Ombi.Schedule/Jobs/Ombi/HtmlTemplateGenerator.cs index 54d1d1133..9d49fe2f1 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/HtmlTemplateGenerator.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/HtmlTemplateGenerator.cs @@ -5,7 +5,8 @@ namespace Ombi.Schedule.Jobs.Ombi { public abstract class HtmlTemplateGenerator { - protected virtual void AddBackgroundInsideTable(StringBuilder sb, string url) + protected StringBuilder sb; + protected virtual void AddBackgroundInsideTable(string url) { sb.Append(""); sb.AppendFormat("", url); @@ -14,14 +15,14 @@ namespace Ombi.Schedule.Jobs.Ombi sb.Append("
"); } - protected virtual void AddPosterInsideTable(StringBuilder sb, string url) + protected virtual void AddPosterInsideTable(string url) { sb.Append(""); sb.Append("
"); sb.AppendFormat("", url); } - protected virtual void AddMediaServerUrl(StringBuilder sb, string mediaurl, string url) + protected virtual void AddMediaServerUrl(string mediaurl, string url) { if (url.HasValue()) { @@ -41,14 +42,14 @@ namespace Ombi.Schedule.Jobs.Ombi sb.Append(""); } - protected virtual void AddInfoTable(StringBuilder sb) + protected virtual void AddInfoTable() { sb.Append( "
"); sb.Append(""); } - protected virtual void AddTitle(StringBuilder sb, string url, string title) + protected virtual void AddTitle( string url, string title) { sb.Append(""); sb.Append(""); } - protected virtual void AddParagraph(StringBuilder sb, string text) + protected virtual void AddParagraph(string text) { sb.Append(""); sb.Append(""); } - protected virtual void AddTvParagraph(StringBuilder sb, string episodes, string summary) + protected virtual void AddTvParagraph(string episodes, string summary) { sb.Append(""); sb.Append(""); } - protected virtual void AddGenres(StringBuilder sb, string text) + protected virtual void AddGenres(string text) { sb.Append(""); sb.Append(" diff --git a/src/Ombi/ClientApp/src/app/wizard/createadmin/createadmin.component.html b/src/Ombi/ClientApp/src/app/wizard/createadmin/createadmin.component.html index ff44f7093..5d79f5ebd 100644 --- a/src/Ombi/ClientApp/src/app/wizard/createadmin/createadmin.component.html +++ b/src/Ombi/ClientApp/src/app/wizard/createadmin/createadmin.component.html @@ -1,6 +1,6 @@ 
- +
diff --git a/src/Ombi/ClientApp/src/app/wizard/ombiconfig/ombiconfig.component.html b/src/Ombi/ClientApp/src/app/wizard/ombiconfig/ombiconfig.component.html index 33d15bb58..a8d7d212e 100644 --- a/src/Ombi/ClientApp/src/app/wizard/ombiconfig/ombiconfig.component.html +++ b/src/Ombi/ClientApp/src/app/wizard/ombiconfig/ombiconfig.component.html @@ -1,6 +1,6 @@ 
- +
diff --git a/src/Ombi/ClientApp/src/app/wizard/welcome/welcome.component.html b/src/Ombi/ClientApp/src/app/wizard/welcome/welcome.component.html index 7ca3de4ce..97d027c5d 100644 --- a/src/Ombi/ClientApp/src/app/wizard/welcome/welcome.component.html +++ b/src/Ombi/ClientApp/src/app/wizard/welcome/welcome.component.html @@ -1,6 +1,6 @@ 
- + Welcome @@ -53,7 +53,7 @@ -
+ Ombi config
@@ -67,7 +67,7 @@ Done
- +
@@ -81,6 +81,6 @@
- +
\ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/wizard/welcome/welcome.component.ts b/src/Ombi/ClientApp/src/app/wizard/welcome/welcome.component.ts index 849977b55..2ab230980 100644 --- a/src/Ombi/ClientApp/src/app/wizard/welcome/welcome.component.ts +++ b/src/Ombi/ClientApp/src/app/wizard/welcome/welcome.component.ts @@ -1,11 +1,12 @@ -import { AfterViewInit, Component, OnInit, ViewChild } from "@angular/core"; -import { Router } from "@angular/router"; +import { Component, OnInit, ViewChild } from "@angular/core"; +import { IdentityService, NotificationService, SettingsService } from "../../services"; + +import { CustomizationFacade } from "../../state/customization/customization.facade"; import { ICreateWizardUser } from "../../interfaces"; -import { IdentityService, NotificationService } from "../../services"; import { IOmbiConfigModel } from "../models/OmbiConfigModel"; +import { MatStepper } from'@angular/material/stepper'; +import { Router } from "@angular/router"; import { WizardService } from "../services/wizard.service"; -import { MatHorizontalStepper } from'@angular/material/stepper'; -import { StepperSelectionEvent } from "@angular/cdk/stepper"; @Component({ templateUrl: "./welcome.component.html", @@ -13,12 +14,13 @@ import { StepperSelectionEvent } from "@angular/cdk/stepper"; }) export class WelcomeComponent implements OnInit { - @ViewChild('stepper', {static: false}) public stepper: MatHorizontalStepper; + @ViewChild('stepper', {static: false}) public stepper: MatStepper; public localUser: ICreateWizardUser; public config: IOmbiConfigModel; constructor(private router: Router, private identityService: IdentityService, - private notificationService: NotificationService, private WizardService: WizardService) { } + private notificationService: NotificationService, private WizardService: WizardService, + private settingsService: SettingsService, private customizationFacade: CustomizationFacade) { } public ngOnInit(): void { this.localUser = { @@ -34,20 +36,40 @@ export class WelcomeComponent implements OnInit { } public createUser() { - this.WizardService.addOmbiConfig(this.config).subscribe(config => { - if(config != null) { - this.identityService.createWizardUser(this.localUser).subscribe(x => { - if (x.result) { - // save the config - this.router.navigate(["login"]); + if (this.config.applicationUrl) { + this.settingsService.verifyUrl(this.config.applicationUrl).subscribe(x => { + if (!x) { + this.notificationService.error(`The URL "${this.config.applicationUrl}" is not valid. Please format it correctly e.g. http://www.google.com/`); + this.stepper.selectedIndex = 3; + return; + } + this.saveConfig(); + }); } else { - if (x.errors.length > 0) { - this.notificationService.error(x.errors[0]); - this.stepper.previous(); - } + this.saveConfig(); } - }); } - }, configErr => this.notificationService.error(configErr)); + + private saveConfig() { + this.WizardService.addOmbiConfig(this.config).subscribe({ + next: (config) => { + if(config != null) { + this.identityService.createWizardUser(this.localUser).subscribe(x => { + if (x.result) { + this.customizationFacade.loadCustomziationSettings().subscribe(); + // save the config + this.router.navigate(["login"]); + } else { + if (x.errors.length > 0) { + this.notificationService.error(x.errors[0]); + this.stepper.previous(); + } + } + }); + } + }, + error: (configErr) => this.notificationService.error(configErr) + }); } + } diff --git a/src/Ombi/ClientApp/src/index.html b/src/Ombi/ClientApp/src/index.html index e9c1ed486..4f7786647 100644 --- a/src/Ombi/ClientApp/src/index.html +++ b/src/Ombi/ClientApp/src/index.html @@ -1,12 +1,12 @@ - + - + diff --git a/src/Ombi/ClientApp/src/styles/Styles.scss b/src/Ombi/ClientApp/src/styles/Styles.scss index 115555410..5b466c3a2 100644 --- a/src/Ombi/ClientApp/src/styles/Styles.scss +++ b/src/Ombi/ClientApp/src/styles/Styles.scss @@ -142,6 +142,10 @@ background-color: $ombi-active; } + a.mat-raised-button { + text-decoration:none; + } + hr { border-top: 1px solid $accent-dark; } diff --git a/src/Ombi/ClientApp/src/tsconfig.json b/src/Ombi/ClientApp/src/tsconfig.json new file mode 100644 index 000000000..b36a82bae --- /dev/null +++ b/src/Ombi/ClientApp/src/tsconfig.json @@ -0,0 +1,36 @@ +{ + "compileOnSave": false, + "compilerOptions": { + "baseUrl": "./", + "module": "esnext", + "outDir": "./dist/out-tsc", + "sourceMap": true, + "declaration": false, + "moduleResolution": "node", + "emitDecoratorMetadata": true, + "experimentalDecorators": true, + "target": "es2020", + "types": [ + "node" + ], + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + "typeRoots": [ + "node_modules/@types" + ], + "lib": [ + "es2017", + "dom" + ] + }, + "files": [ + "main.ts", + "polyfills.ts" + ], + "include": [ + "src/**/*.d.ts" + ], + "exclude": [ + "**/*.stories.*" + ] +} diff --git a/src/Ombi/ClientApp/src/typings/globals.d.ts b/src/Ombi/ClientApp/src/typings/globals.d.ts index a52f87871..6539fc0c6 100644 --- a/src/Ombi/ClientApp/src/typings/globals.d.ts +++ b/src/Ombi/ClientApp/src/typings/globals.d.ts @@ -1,6 +1,7 @@ // Globals -declare var __webpack_public_path__: any; +// declare var __webpack_public_path__: any; // declare module "*.json" { // const value: any; // export default value; -// } \ No newline at end of file +// } + diff --git a/src/Ombi/ClientApp/src/tsconfig.app.json b/src/Ombi/ClientApp/tsconfig.json similarity index 95% rename from src/Ombi/ClientApp/src/tsconfig.app.json rename to src/Ombi/ClientApp/tsconfig.json index aef5c882b..df0ec93ed 100644 --- a/src/Ombi/ClientApp/src/tsconfig.app.json +++ b/src/Ombi/ClientApp/tsconfig.json @@ -9,7 +9,7 @@ "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, - "target": "es2015", + "target": "es2020", "types": ["node"], "resolveJsonModule":true, "allowSyntheticDefaultImports":true, diff --git a/src/Ombi/ClientApp/yarn.lock b/src/Ombi/ClientApp/yarn.lock index 6585ff2f9..b343db55b 100644 --- a/src/Ombi/ClientApp/yarn.lock +++ b/src/Ombi/ClientApp/yarn.lock @@ -2,301 +2,309 @@ # yarn lockfile v1 -"@ampproject/remapping@1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-1.0.1.tgz#1398e73e567c2a7992df6554c15bb94a89b68ba2" - integrity sha512-Ta9bMA3EtUHDaZJXqUoT5cn/EecwOp+SXpKJqxDbDuMbLvEMu6YTyDDuvTWeStODfdmXyfMo7LymQyPkN3BicA== - dependencies: - "@jridgewell/resolve-uri" "1.0.0" - sourcemap-codec "1.4.8" +"@aduh95/viz.js@^3.1.0": + version "3.7.0" + resolved "https://registry.yarnpkg.com/@aduh95/viz.js/-/viz.js-3.7.0.tgz#a20d86c5fc8f6abebdc39b96a4326e10375d77c0" + integrity sha512-20Pk2Z98fbPLkECcrZSJszKos/OgtvJJR3NcbVfgCJ6EQjDNzW2P1BKqImOz3tJ952dvO2DWEhcLhQ1Wz1e9ng== -"@angular-devkit/architect@0.1202.10": - version "0.1202.10" - resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1202.10.tgz#6aae8e97ea209949507443cd9c414be94d258813" - integrity sha512-/sLgtXaFsNouxub5M/bQ2sBkiMIlPubuz6QMh+pA2jia82vJ3hcRMt4AnJTXuXpVY+aew4FiG0i9nt/8HETQsw== +"@ampproject/remapping@2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" + integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== dependencies: - "@angular-devkit/core" "12.2.10" + "@jridgewell/gen-mapping" "^0.1.0" + "@jridgewell/trace-mapping" "^0.3.9" + +"@ampproject/remapping@^2.1.0": + version "2.1.2" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.2.tgz#4edca94973ded9630d20101cd8559cedb8d8bd34" + integrity sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg== + dependencies: + "@jridgewell/trace-mapping" "^0.3.0" + +"@angular-devkit/architect@0.1400.0": + version "0.1400.0" + resolved "https://registry.yarnpkg.com/@angular-devkit/architect/-/architect-0.1400.0.tgz#ad2d55ac898daead4bcb791499ab2b98b40803ed" + integrity sha512-INPO+r5CHElPdFLOrwUYShZqtr37/kTJegAoWpSNC8Zy8WgTlecvA+y5eHy0bNeXMjWbZ3YCZJ1jXYpJJNL1Kg== + dependencies: + "@angular-devkit/core" "14.0.0" rxjs "6.6.7" -"@angular-devkit/build-angular@~12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-12.2.10.tgz#aef9d1ab44e9f83dd8cd5625d7d10eaf81dd0e74" - integrity sha512-MuViuSmXmB67Wge3NpyfY2aAU4O4K+BbcHj1W1k1A9WTx/Hyh6jR6Zgwy/EsNh64zjdUg/Jlg/oHxIVabsWfvQ== +"@angular-devkit/build-angular@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-angular/-/build-angular-14.0.0.tgz#68825037c7f110a80a05c1c0c838ba98d6cf3fa7" + integrity sha512-SUFanOcIJ6XWBltQ7U038zGGhsT40h4I1Pqkf+qlPLGctARz8wfD3GPD1a0pRlrIH6J/f7Xbb7QrQvGfG4g/NQ== dependencies: - "@ampproject/remapping" "1.0.1" - "@angular-devkit/architect" "0.1202.10" - "@angular-devkit/build-optimizer" "0.1202.10" - "@angular-devkit/build-webpack" "0.1202.10" - "@angular-devkit/core" "12.2.10" - "@babel/core" "7.14.8" - "@babel/generator" "7.14.8" - "@babel/helper-annotate-as-pure" "7.14.5" - "@babel/plugin-proposal-async-generator-functions" "7.14.7" - "@babel/plugin-transform-async-to-generator" "7.14.5" - "@babel/plugin-transform-runtime" "7.14.5" - "@babel/preset-env" "7.14.8" - "@babel/runtime" "7.14.8" - "@babel/template" "7.14.5" - "@discoveryjs/json-ext" "0.5.3" - "@jsdevtools/coverage-istanbul-loader" "3.0.5" - "@ngtools/webpack" "12.2.10" + "@ampproject/remapping" "2.2.0" + "@angular-devkit/architect" "0.1400.0" + "@angular-devkit/build-webpack" "0.1400.0" + "@angular-devkit/core" "14.0.0" + "@babel/core" "7.17.10" + "@babel/generator" "7.17.10" + "@babel/helper-annotate-as-pure" "7.16.7" + "@babel/plugin-proposal-async-generator-functions" "7.16.8" + "@babel/plugin-transform-async-to-generator" "7.16.8" + "@babel/plugin-transform-runtime" "7.17.10" + "@babel/preset-env" "7.17.10" + "@babel/runtime" "7.17.9" + "@babel/template" "7.16.7" + "@discoveryjs/json-ext" "0.5.7" + "@ngtools/webpack" "14.0.0" ansi-colors "4.1.1" - babel-loader "8.2.2" + babel-loader "8.2.5" + babel-plugin-istanbul "6.1.1" browserslist "^4.9.1" - cacache "15.2.0" - caniuse-lite "^1.0.30001032" - circular-dependency-plugin "5.2.2" - copy-webpack-plugin "9.0.1" - core-js "3.16.0" - critters "0.0.10" - css-loader "6.2.0" - css-minimizer-webpack-plugin "3.0.2" - esbuild-wasm "0.13.4" - find-cache-dir "3.3.1" - glob "7.1.7" - https-proxy-agent "5.0.0" - inquirer "8.1.2" + cacache "16.0.7" + copy-webpack-plugin "10.2.4" + critters "0.0.16" + css-loader "6.7.1" + esbuild-wasm "0.14.38" + glob "8.0.1" + https-proxy-agent "5.0.1" + inquirer "8.2.4" + jsonc-parser "3.0.0" karma-source-map-support "1.4.0" - less "4.1.1" - less-loader "10.0.1" - license-webpack-plugin "2.3.20" - loader-utils "2.0.0" - mini-css-extract-plugin "2.2.1" - minimatch "3.0.4" - open "8.2.1" + less "4.1.2" + less-loader "10.2.0" + license-webpack-plugin "4.0.2" + loader-utils "3.2.0" + mini-css-extract-plugin "2.6.0" + minimatch "5.0.1" + open "8.4.0" ora "5.4.1" parse5-html-rewriting-stream "6.0.1" - piscina "3.1.0" - postcss "8.3.6" - postcss-import "14.0.2" - postcss-loader "6.1.1" - postcss-preset-env "6.7.0" + piscina "3.2.0" + postcss "8.4.13" + postcss-import "14.1.0" + postcss-loader "6.2.1" + postcss-preset-env "7.5.0" regenerator-runtime "0.13.9" - resolve-url-loader "4.0.0" + resolve-url-loader "5.0.0" rxjs "6.6.7" - sass "1.36.0" - sass-loader "12.1.0" - semver "7.3.5" - source-map-loader "3.0.0" - source-map-support "0.5.19" - style-loader "3.2.1" - stylus "0.54.8" - stylus-loader "6.1.0" - terser "5.7.1" - terser-webpack-plugin "5.1.4" + sass "1.51.0" + sass-loader "12.6.0" + semver "7.3.7" + source-map-loader "3.0.1" + source-map-support "0.5.21" + stylus "0.57.0" + stylus-loader "6.2.0" + terser "5.13.1" text-table "0.2.0" tree-kill "1.2.2" - tslib "2.3.0" - webpack "5.50.0" - webpack-dev-middleware "5.0.0" - webpack-dev-server "3.11.2" + tslib "2.4.0" + webpack "5.72.1" + webpack-dev-middleware "5.3.1" + webpack-dev-server "4.9.0" webpack-merge "5.8.0" - webpack-subresource-integrity "1.5.2" + webpack-subresource-integrity "5.1.0" optionalDependencies: - esbuild "0.13.4" + esbuild "0.14.38" -"@angular-devkit/build-optimizer@0.1202.10": - version "0.1202.10" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-optimizer/-/build-optimizer-0.1202.10.tgz#f72c76e873e10139e95633d0ac3c4c8112d3f40b" - integrity sha512-NcFEtj4Vfc7gXJtXEVf1mnpk0CJ0htlkm/LbidPcs1PEQbJ/yDgZ44fO+53Pt6NzLmsmPHXOmRzN7O6HkxolPA== +"@angular-devkit/build-webpack@0.1400.0": + version "0.1400.0" + resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1400.0.tgz#c96bf0f658a86ac91fae5e431b2e1553c6da2420" + integrity sha512-aKbDjWAwHcscqLhxfmkHrkWvAJ3X8nQoIrAP/RbTQ1qRCv5nnqIHe8u5X/1ZCCYCyPJr1UeDTrQiRXCTN4jYvA== dependencies: - source-map "0.7.3" - tslib "2.3.0" - typescript "4.3.5" - -"@angular-devkit/build-webpack@0.1202.10": - version "0.1202.10" - resolved "https://registry.yarnpkg.com/@angular-devkit/build-webpack/-/build-webpack-0.1202.10.tgz#ad92b8865623092951b4fddf6f603661f7910865" - integrity sha512-xGSy12g+wa/qeYOaPGkeoJp3zatlS+HZxECtw0Up3ES85Ewrx9PvraexHSuRxnkuBQykRORKf6WbPt/WYIAVGQ== - dependencies: - "@angular-devkit/architect" "0.1202.10" + "@angular-devkit/architect" "0.1400.0" rxjs "6.6.7" -"@angular-devkit/core@12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-12.2.10.tgz#3da62eceef3904f92cd3f860618b4ae513029ce2" - integrity sha512-0qhmS7Qvl0hiRVTHxEC/ipFAfzYofPstw0ZITDpEMw+pgHlOZolOlnFrv8LyOXWNqlSIH5fS9D3WF7Hpm7ApYA== +"@angular-devkit/core@13.3.9": + version "13.3.9" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-13.3.9.tgz#71a662feb2c3f6f79a1f27db31cb2f7021195c77" + integrity sha512-XqCuIWyoqIsLABjV3GQL/+EiBCt3xVPPtNp3Mg4gjBsDLW7PEnvbb81yGkiZQmIsq4EIyQC/6fQa3VdjsCshGg== dependencies: - ajv "8.6.2" - ajv-formats "2.1.0" + ajv "8.9.0" + ajv-formats "2.1.1" fast-json-stable-stringify "2.1.0" magic-string "0.25.7" rxjs "6.6.7" source-map "0.7.3" -"@angular-devkit/schematics@12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-12.2.10.tgz#b8d4031053fd76d93caa7f33aeeb67383e37f0ab" - integrity sha512-oQ2EWdkEDE+eAttHeviXsvBi85PsntQT+IffjKUZdbQU+Leuk/pKUpTeea1YosU1p4Cz3PKYF+P/Nl5Jy3B7IQ== +"@angular-devkit/core@14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@angular-devkit/core/-/core-14.0.0.tgz#33e56337257fdda3e429b36548820814d9fafbc2" + integrity sha512-xQXpNbIeBjnbY68OFkrpFm6v7xlmTLFk6zGPIkI4T/hrqT2kNmg0y1/FcN6yMBgCEC9WVWR8SHGaPWrc5VVZMw== dependencies: - "@angular-devkit/core" "12.2.10" + ajv "8.11.0" + ajv-formats "2.1.1" + jsonc-parser "3.0.0" + rxjs "6.6.7" + source-map "0.7.3" + +"@angular-devkit/schematics@14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-14.0.0.tgz#b66c5fccd6ecadc90df24cb0f1e68979f3998f92" + integrity sha512-/ycPygU1XpdGrROdxHJUUFGwxCf5vRrcBQvVbZhB2s7+DfDAaZHyWEItDeGK04hqpeTFq4m0NUP6ylXZospWvQ== + dependencies: + "@angular-devkit/core" "14.0.0" + jsonc-parser "3.0.0" + magic-string "0.26.1" ora "5.4.1" rxjs "6.6.7" -"@angular/animations@^12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-12.2.10.tgz#c6610fc7b2021451c46dcfe27bd4fcc8e3789e08" - integrity sha512-K1WT3m/StW5a4SE9wKT+D7eteyWK+MW3pAwFPaKH8EU9k6dItlLr3jWZsve5w2u/GLSnrOMGJNU/JmTfskV9LA== +"@angular-devkit/schematics@^13.2.4": + version "13.3.9" + resolved "https://registry.yarnpkg.com/@angular-devkit/schematics/-/schematics-13.3.9.tgz#72df522e1737fb727359e60e4d7df0fd8310b2e8" + integrity sha512-oNHLNtwbtEJ0dYPPXy1NpfRdSiFsYBl7+ozJklLgNV/AEOxlSi2qlVx6DoxNVjz5XgQ7Z+eoVDMw7ewGPnGSyA== dependencies: - tslib "^2.2.0" + "@angular-devkit/core" "13.3.9" + jsonc-parser "3.0.0" + magic-string "0.25.7" + ora "5.4.1" + rxjs "6.6.7" -"@angular/cdk@^12.2.9": - version "12.2.9" - resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-12.2.9.tgz#f39e4d7cdb3568ad8e1d412e3500772e2d4c605c" - integrity sha512-9Wgj69iGAZ4teQqW/zPbVg2RGna+m9i3v0zkWGx/+Uo95rikJCUZBQM4bfeOe+bSJrS77jV5EisBWG7ayNUSzQ== +"@angular/animations@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@angular/animations/-/animations-14.0.0.tgz#58ed4d4466a2c0c4aa6194906b6a574440f4fe65" + integrity sha512-HVcS4l0eStcA2RDDQcxqChFHVN3BfQdvx68HRTuVDYbUSS4xdL5Hsk8OMkczV1pFDn+URKH1A363bTy5juyDaQ== dependencies: - tslib "^2.2.0" + tslib "^2.3.0" + +"@angular/cdk@^13.2.0": + version "13.2.2" + resolved "https://registry.yarnpkg.com/@angular/cdk/-/cdk-13.2.2.tgz#4d41b1da6e92e3bc80d28aabe2049fa7ca40f5b1" + integrity sha512-cT5DIaz+NI9IGb3X61Wh26+L6zdRcOXT1BP37iRbK2Qa2qM8/0VNeK6hrBBIblyoHKR/WUmRlS8XYf6mmArpZw== + dependencies: + tslib "^2.3.0" optionalDependencies: parse5 "^5.0.0" -"@angular/cli@~12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-12.2.10.tgz#73062d433434b7b25073863940d82e4e6f7fa924" - integrity sha512-gx2XlOUjAAYyJBBIz4QkgsLLRMdFTQbcOR41/Yv0kgpR6AStrOWhz7tpYPbU6vWMjehpuTaWv4NE5eGjwVTZqg== +"@angular/cli@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@angular/cli/-/cli-14.0.0.tgz#ce761693bef18e8cf46eeebc01c85ea49f0a110f" + integrity sha512-dGIP0FdKnZ52VJZo83r+eQlCnUDVj08Dx3v3szD/IT/f7bhv7Ob6Bdae+c7CgM5yIt1DBIYe6xX8uZ/JIGtBoQ== dependencies: - "@angular-devkit/architect" "0.1202.10" - "@angular-devkit/core" "12.2.10" - "@angular-devkit/schematics" "12.2.10" - "@schematics/angular" "12.2.10" + "@angular-devkit/architect" "0.1400.0" + "@angular-devkit/core" "14.0.0" + "@angular-devkit/schematics" "14.0.0" + "@schematics/angular" "14.0.0" "@yarnpkg/lockfile" "1.1.0" ansi-colors "4.1.1" - debug "4.3.2" - ini "2.0.0" - inquirer "8.1.2" + debug "4.3.4" + ini "3.0.0" + inquirer "8.2.4" jsonc-parser "3.0.0" - npm-package-arg "8.1.5" - npm-pick-manifest "6.1.1" - open "8.2.1" + npm-package-arg "9.0.2" + npm-pick-manifest "7.0.1" + open "8.4.0" ora "5.4.1" - pacote "11.3.5" - resolve "1.20.0" - semver "7.3.5" + pacote "13.3.0" + resolve "1.22.0" + semver "7.3.7" symbol-observable "4.0.0" uuid "8.3.2" + yargs "17.4.1" -"@angular/common@^12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@angular/common/-/common-12.2.10.tgz#1298fc0d7becfdf5368676ceb01a7df97331d412" - integrity sha512-7IjD0frrKG/nt3/fo4mKDH0Tx5Nn8f2G8Ks/aq6xnJssy/V841COjua0ZyfPOkPS1r0VEaQJB5ieqMrp2T6MWg== +"@angular/common@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@angular/common/-/common-14.0.0.tgz#65245a5386819449a6ccc35cdb3f7ebd61a1d753" + integrity sha512-VYydSXelPlcAnWZs6SKkOxV+rNe8zOtHKLf9jBTYT5nP5P66+va4zITo1C9bs5tbK+mRssayf615+SIGEXyJFg== dependencies: - tslib "^2.2.0" + tslib "^2.3.0" -"@angular/compiler-cli@^12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-12.2.10.tgz#c6b19af123d5772a8a53ac7872401fdc726f7b57" - integrity sha512-cPWxNMwPTM7IsEBxMrh4yY9XZi4gZRv7EmKWOfBw6hiW0SEmthIQWOvCaoL5CPsdUhInNxXWvwAoFggk/tfJ5g== +"@angular/compiler-cli@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@angular/compiler-cli/-/compiler-cli-14.0.0.tgz#8562151e16d26f3a2143ff0be86074f133bedd98" + integrity sha512-5T9AjguK4NsCjk4mdrSLV7BrifijKb79wFyDOQX5+p7GVRag47U6E6qQAKhsqZxLy7grrBX4fb0PFARL2OrkLQ== dependencies: - "@babel/core" "^7.8.6" - "@babel/types" "^7.8.6" - canonical-path "1.0.0" + "@babel/core" "^7.17.2" chokidar "^3.0.0" convert-source-map "^1.5.1" dependency-graph "^0.11.0" - magic-string "^0.25.0" - minimist "^1.2.0" + magic-string "^0.26.0" reflect-metadata "^0.1.2" semver "^7.0.0" - source-map "^0.6.1" sourcemap-codec "^1.4.8" - tslib "^2.2.0" - yargs "^17.0.0" + tslib "^2.3.0" + yargs "^17.2.1" "@angular/compiler@9.0.0": version "9.0.0" resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-9.0.0.tgz#87e0bef4c369b6cadae07e3a4295778fc93799d5" integrity sha512-ctjwuntPfZZT2mNj2NDIVu51t9cvbhl/16epc5xEwyzyDt76pX9UgwvY+MbXrf/C/FWwdtmNtfP698BKI+9leQ== -"@angular/compiler@^12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-12.2.10.tgz#7da81b341f90e779d29f7f96c82c93e57f84c02e" - integrity sha512-5fuzX8P74z28CRYTamsZgsdUyh0c53shytZYfa0cGFXyV8VD/r8AMIyQ4y7Y5Fmt4Nr+65EVeYb3sI7IzYiueg== +"@angular/compiler@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@angular/compiler/-/compiler-14.0.0.tgz#71e47e1a9bc1c0d599fd3636061bcca16a4df5c5" + integrity sha512-yWpru4coLOE2Ivn+1ltXPsaxai5MOUABPmYZfm47HN7vfVsxcTC44QDxGY73M9e18sngTIFi6qgr8vci1AT9lg== dependencies: - tslib "^2.2.0" + tslib "^2.3.0" "@angular/core@9.0.0": version "9.0.0" resolved "https://registry.yarnpkg.com/@angular/core/-/core-9.0.0.tgz#227dc53e1ac81824f998c6e76000b7efc522641e" integrity sha512-6Pxgsrf0qF9iFFqmIcWmjJGkkCaCm6V5QNnxMy2KloO3SDq6QuMVRbN9RtC8Urmo25LP+eZ6ZgYqFYpdD8Hd9w== -"@angular/core@^12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@angular/core/-/core-12.2.10.tgz#899f5b6e44c33790640d04df2a6981b622a9e6d7" - integrity sha512-xG1IbmEAV7gWpiY2MSFc87MlmB3yff8/TAlSE8Tj2ZFzb1lFjeFnrZ1y50Hi2AcVyX/KA1mx/RyJ0M7fmQ1ayw== +"@angular/core@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@angular/core/-/core-14.0.0.tgz#74a3df2988f81eb7ca00b5961a3145dadfa05e92" + integrity sha512-Mj3r8iMlWfMbY+9DRUFZx1gKnA27Jwx3ff/VXeXBgfxaEKDYmlZSnliZSV6ssiHSUwn/U6yxDXFgcZL090zNBQ== dependencies: - tslib "^2.2.0" + tslib "^2.3.0" -"@angular/forms@^12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-12.2.10.tgz#c1a2f6f07354d56d78dc1dfc1f9ff92750ea4daa" - integrity sha512-ntTJOaLeH+7th5W4LEm3/yHsBvaFpfRgn0Uc88Th8p2gvorqCgpJMWogJIx/yESNolSFItY6k/x7kjuMBgm9mA== +"@angular/forms@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@angular/forms/-/forms-14.0.0.tgz#70201bb66f20580fd25b744d109c5d15f4afc8b7" + integrity sha512-r2FHcJve+/rXU4wdCA50nwySGKB5/bxqpULOGeWs4FIdKcUoTnzHtqMsd7sUa7wOA40O4fBHAxKPDGPJPl5CEA== dependencies: - tslib "^2.2.0" + tslib "^2.3.0" -"@angular/language-service@^12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-12.2.10.tgz#051d92813185535c7b1c496f4306f10a729b335e" - integrity sha512-o9KY39+1bw9xB6vsMWAbcPFWNdTQ/6TSKyQkmAyYca7T6LlNOe/qWln2655ZFPhyG6d9R8nbTi3X0MhMP+H7xQ== +"@angular/language-service@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@angular/language-service/-/language-service-14.0.0.tgz#749b52642fe0ba04f8475667d2eac0b3cf60d400" + integrity sha512-05P+3IJ+pT9WQdUcXVM4NGY1a8V1bGKRVEE6BFFPYG+ElrM2aR7e0j997zAPIwPLWT1Z8/oC1wJ3MCBBTbECVQ== -"@angular/localize@^12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-12.2.10.tgz#25bab8bc6e8b247e83a7146df4dbf39b73d0ecfe" - integrity sha512-YTvDYvhjo+qakuLdyWTpgz7Hd4nzmCLdzk/P2a46SiYWG4i/ShBmfkhJNAgZfVnnM6oSt15z/VCgB31lS7JrYg== +"@angular/localize@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@angular/localize/-/localize-14.0.0.tgz#e0db604639dce5edf1c1c95ef3eb31e462b51001" + integrity sha512-Aguw6uTGWx5ZzCLeDblwsNSuqD5apL3WWE7ZNl3xDcxgSZNH5KggaAgP8afEqO2f53Hy38TV/9TwDew1yM6p1g== dependencies: - "@babel/core" "7.8.3" - glob "7.1.7" - yargs "^17.0.0" + "@babel/core" "7.17.12" + glob "8.0.3" + yargs "^17.2.1" -"@angular/material@^12.2.9": - version "12.2.9" - resolved "https://registry.yarnpkg.com/@angular/material/-/material-12.2.9.tgz#b4a1e138c7fd2341bd27aa6012b4738f61b5ad2d" - integrity sha512-+eM67RF038S56m3wsj37h0PyyRD18cQ8V2zmKG1UezH0nnosbmCAwzH9BfcNiIB+/V+k5QMJ/JVu5MjDQqX37w== +"@angular/material@^13.2.0": + version "13.2.2" + resolved "https://registry.yarnpkg.com/@angular/material/-/material-13.2.2.tgz#d673f68b0c9357ada2ee82ffeaf11f10f5d49b27" + integrity sha512-YAjPp2+/wuEOPfkAxdRVdbWHiK4P3DgMZa9qP/NizN2lTXNrftEfD09ZlPIFMZRnnExezJ2LnO7eyELpc1VSKg== dependencies: - tslib "^2.2.0" + tslib "^2.3.0" -"@angular/platform-browser-dynamic@^12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-12.2.10.tgz#c30ef29587a09fbcfd0d9921b64ce264e6650893" - integrity sha512-CLYHCdTCzpxvMwITRBLlUoa44orDdogMaQfKIMEQsWrynf+zGZKYe5chAut9P/A54PVPUtKeQrfEVFjmbdYR2w== +"@angular/platform-browser-dynamic@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@angular/platform-browser-dynamic/-/platform-browser-dynamic-14.0.0.tgz#2538558a3564fdad6b66fc252bef5e9976700d8a" + integrity sha512-gmLRgTNJi3qEEBfOJA8EcSX3qAmTQ7nBu+TQosiFIFaZG98oa7F5W/PXZx0zOC5ElsqPClvPdgtM6MC7cwSqXQ== dependencies: - tslib "^2.2.0" + tslib "^2.3.0" -"@angular/platform-browser@^12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-12.2.10.tgz#402132b528f6dc0235c5571cdf0f29ef1a79277a" - integrity sha512-2pYoscOJijbqFsnYpKX6o4ojt4XfZiNhODTf9RDOPVKjVqFsRNVThg76kdKtN+N8q6N1z4I01x6aX4EeWqQqIA== +"@angular/platform-browser@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@angular/platform-browser/-/platform-browser-14.0.0.tgz#174c80c02c13a2e4bef22791e2d9d626d7f418d1" + integrity sha512-zijIhUxu3nJxoI3mTWxs1d7dh9ovldI09diumlm/rOhj/46j4SvGn8swJvWr0eo/QipkdP+i2Q1lAlpmRfI+tQ== dependencies: - tslib "^2.2.0" + tslib "^2.3.0" -"@angular/platform-server@^12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-12.2.10.tgz#8e11dea472db244c2fa71ec0d08911d52151b3b5" - integrity sha512-g2m2/+e+6mxbvMYICe+1zDP/KGMwmf9gu/fz+I9UFpGuAx4S7eBL/GCII2gnrrbavZ2vxczY0Ff4JU7AEBrGug== +"@angular/platform-server@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@angular/platform-server/-/platform-server-14.0.0.tgz#28e5f28ba28c8a2e1184492c5d947b688bfb7ac6" + integrity sha512-kl2yexQ9kXVCpdn/IF5z0Ea8wWx2dNwbrXbnVvqWGNLtKwsp6p0B35FHgfMHMN818BCeMHn4am0i2ucNQH5O6g== dependencies: domino "^2.1.2" - tslib "^2.2.0" + tslib "^2.3.0" xhr2 "^0.2.0" -"@angular/router@^12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@angular/router/-/router-12.2.10.tgz#53d64ce59a65cde096e4a0125b117b6040d08fa8" - integrity sha512-e9sqOdLNF3pVRZPZtD6OdvERdTWKP7Et8Mz4OSNT8GEe6SctRAaptTAqY09AGpi4BO2+LsxVBERYfhZw9bZ2bA== +"@angular/router@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@angular/router/-/router-14.0.0.tgz#f9d8735a8899b73b61c64243458e824c8abccbb3" + integrity sha512-8ctwkPkwAbBgxu0O3OfoUYgn7GmOM877Wi/CST/AXXHXMs9v2O2MWAV63ITAjwVD1p6/V+IhUNkiypvQW+0Afw== dependencies: - tslib "^2.2.0" + tslib "^2.3.0" "@angularclass/hmr@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@angularclass/hmr/-/hmr-3.0.0.tgz#6d0c31a237a46af99085de65082a97975575eda5" integrity sha512-4A/DKmSafWUcffv7f536oY6RbpXEAD7f0NCGVLlRj9Gna8dkGc9JOHSr3NCWHd/NRc4ey8x+V0itsBqlPxEJ/A== -"@aspnet/signalr@^1.1.0": - version "1.1.4" - resolved "https://registry.yarnpkg.com/@aspnet/signalr/-/signalr-1.1.4.tgz#417cf808f4074a8aec45d27f03c4b8df9d96bb0b" - integrity sha512-Jp9nPc8hmmhbG9OKiHe2fOKskBHfg+3Y9foSKHxjgGtyI743hXjGFv3uFlUg503K9f8Ilu63gQt3fDkLICBRyg== - dependencies: - eventsource "^1.0.7" - request "^2.88.0" - ws "^6.0.0" - "@assemblyscript/loader@^0.10.1": version "0.10.1" resolved "https://registry.yarnpkg.com/@assemblyscript/loader/-/loader-0.10.1.tgz#70e45678f06c72fa2e350e8553ec4a4d72b92e06" @@ -309,91 +317,193 @@ dependencies: tslib "^2.0.0" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.14.5", "@babel/code-frame@^7.15.8", "@babel/code-frame@^7.8.3": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.14.5": version "7.15.8" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.15.8.tgz#45990c47adadb00c03677baa89221f7cc23d2503" integrity sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg== dependencies: "@babel/highlight" "^7.14.5" -"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.14.7", "@babel/compat-data@^7.15.0": +"@babel/code-frame@^7.10.4", "@babel/code-frame@^7.18.6", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a" + integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q== + dependencies: + "@babel/highlight" "^7.18.6" + +"@babel/code-frame@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789" + integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg== + dependencies: + "@babel/highlight" "^7.16.7" + +"@babel/compat-data@^7.13.11", "@babel/compat-data@^7.15.0": version "7.15.0" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.15.0.tgz#2dbaf8b85334796cafbb0f5793a90a2fc010b176" integrity sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA== -"@babel/core@7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.14.8.tgz#20cdf7c84b5d86d83fac8710a8bc605a7ba3f010" - integrity sha512-/AtaeEhT6ErpDhInbXmjHcUQXH0L0TEgscfcxk1qbOvLuKCa5aZT0SOOtDKFY96/CLROwbLSKyFor6idgNaU4Q== - dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/generator" "^7.14.8" - "@babel/helper-compilation-targets" "^7.14.5" - "@babel/helper-module-transforms" "^7.14.8" - "@babel/helpers" "^7.14.8" - "@babel/parser" "^7.14.8" - "@babel/template" "^7.14.5" - "@babel/traverse" "^7.14.8" - "@babel/types" "^7.14.8" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.1.2" - semver "^6.3.0" - source-map "^0.5.0" +"@babel/compat-data@^7.16.4": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.0.tgz#86850b8597ea6962089770952075dcaabb8dba34" + integrity sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng== -"@babel/core@7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.8.3.tgz#30b0ebb4dd1585de6923a0b4d179e0b9f5d82941" - integrity sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA== +"@babel/compat-data@^7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.10.tgz#711dc726a492dfc8be8220028b1b92482362baab" + integrity sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw== + +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.18.8": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.18.8.tgz#2483f565faca607b8535590e84e7de323f27764d" + integrity sha512-HSmX4WZPPK3FUxYp7g2T6EyO8j96HlZJlxmKPSh6KAcqwyDrfx7hKjXpAW/0FhFfTJsR0Yt4lAjLI2coMptIHQ== + +"@babel/core@7.12.9": + version "7.12.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.12.9.tgz#fd450c4ec10cdbb980e2928b7aa7a28484593fc8" + integrity sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ== dependencies: - "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.3" - "@babel/helpers" "^7.8.3" - "@babel/parser" "^7.8.3" - "@babel/template" "^7.8.3" - "@babel/traverse" "^7.8.3" - "@babel/types" "^7.8.3" + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.12.5" + "@babel/helper-module-transforms" "^7.12.1" + "@babel/helpers" "^7.12.5" + "@babel/parser" "^7.12.7" + "@babel/template" "^7.12.7" + "@babel/traverse" "^7.12.9" + "@babel/types" "^7.12.7" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" - json5 "^2.1.0" - lodash "^4.17.13" + json5 "^2.1.2" + lodash "^4.17.19" resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" -"@babel/core@^7.7.5", "@babel/core@^7.8.6": - version "7.15.8" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.15.8.tgz#195b9f2bffe995d2c6c159e72fe525b4114e8c10" - integrity sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og== +"@babel/core@7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.10.tgz#74ef0fbf56b7dfc3f198fc2d927f4f03e12f4b05" + integrity sha512-liKoppandF3ZcBnIYFjfSDHZLKdLHGJRkoWtG8zQyGJBQfIYobpnVGI5+pLBNtS6psFLDzyq8+h5HiVljW9PNA== dependencies: - "@babel/code-frame" "^7.15.8" - "@babel/generator" "^7.15.8" - "@babel/helper-compilation-targets" "^7.15.4" - "@babel/helper-module-transforms" "^7.15.8" - "@babel/helpers" "^7.15.4" - "@babel/parser" "^7.15.8" - "@babel/template" "^7.15.4" - "@babel/traverse" "^7.15.4" - "@babel/types" "^7.15.6" + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.10" + "@babel/helper-compilation-targets" "^7.17.10" + "@babel/helper-module-transforms" "^7.17.7" + "@babel/helpers" "^7.17.9" + "@babel/parser" "^7.17.10" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.10" + "@babel/types" "^7.17.10" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + +"@babel/core@7.17.12": + version "7.17.12" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.12.tgz#b4eb2d7ebc3449b062381644c93050db545b70ee" + integrity sha512-44ODe6O1IVz9s2oJE3rZ4trNNKTX9O7KpQpfAP4t8QII/zwrVRHL7i2pxhqtcY7tqMLrrKfMlBKnm1QlrRFs5w== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.12" + "@babel/helper-compilation-targets" "^7.17.10" + "@babel/helper-module-transforms" "^7.17.12" + "@babel/helpers" "^7.17.9" + "@babel/parser" "^7.17.12" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.12" + "@babel/types" "^7.17.12" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + +"@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.17.5", "@babel/core@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.9.tgz#805461f967c77ff46c74ca0460ccf4fe933ddd59" + integrity sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.9" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-module-transforms" "^7.18.9" + "@babel/helpers" "^7.18.9" + "@babel/parser" "^7.18.9" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" + +"@babel/core@^7.12.3": + version "7.17.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.4.tgz#a22f1ae8999122873b3d18865e98c7a3936b8c8b" + integrity sha512-R9x5r4t4+hBqZTmioSnkrW+I6NmbojwjGT8p4G2Gw1thWbXIHGDnmGdLdFw0/7ljucdIrNRp7Npgb4CyBYzzJg== + dependencies: + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.3" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helpers" "^7.17.2" + "@babel/parser" "^7.17.3" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.3" + "@babel/types" "^7.17.0" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.1.2" semver "^6.3.0" - source-map "^0.5.0" -"@babel/generator@7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.14.8.tgz#bf86fd6af96cf3b74395a8ca409515f89423e070" - integrity sha512-cYDUpvIzhBVnMzRoY1fkSEhK/HmwEVwlyULYgn/tMQYd6Obag3ylCjONle3gdErfXBW61SVTlR9QR7uWlgeIkg== +"@babel/core@^7.17.2": + version "7.18.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.18.2.tgz#87b2fcd7cce9becaa7f5acebdc4f09f3dd19d876" + integrity sha512-A8pri1YJiC5UnkdrWcmfZTJTV85b4UXTAfImGmCfYmax4TR9Cw8sDS0MOk++Gp2mE/BefVJ5nwy5yzqNJbP/DQ== dependencies: - "@babel/types" "^7.14.8" - jsesc "^2.5.1" - source-map "^0.5.0" + "@ampproject/remapping" "^2.1.0" + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.18.2" + "@babel/helper-compilation-targets" "^7.18.2" + "@babel/helper-module-transforms" "^7.18.0" + "@babel/helpers" "^7.18.2" + "@babel/parser" "^7.18.0" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.18.2" + "@babel/types" "^7.18.2" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.1" + semver "^6.3.0" -"@babel/generator@^7.14.8", "@babel/generator@^7.15.4", "@babel/generator@^7.15.8", "@babel/generator@^7.8.3": +"@babel/generator@7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.10.tgz#c281fa35b0c349bbe9d02916f4ae08fc85ed7189" + integrity sha512-46MJZZo9y3o4kmhBVc7zW7i8dtR1oIK/sdO5NcfcZRhTGYi+KKJRtHNgsU6c4VUcJmUNV/LQdebD/9Dlv4K+Tg== + dependencies: + "@babel/types" "^7.17.10" + "@jridgewell/gen-mapping" "^0.1.0" + jsesc "^2.5.1" + +"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.9.tgz#68337e9ea8044d6ddc690fb29acae39359cca0a5" + integrity sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug== + dependencies: + "@babel/types" "^7.18.9" + "@jridgewell/gen-mapping" "^0.3.2" + jsesc "^2.5.1" + +"@babel/generator@^7.15.4": version "7.15.8" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.15.8.tgz#fa56be6b596952ceb231048cf84ee499a19c0cd1" integrity sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g== @@ -402,29 +512,62 @@ jsesc "^2.5.1" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.14.5.tgz#7bf478ec3b71726d56a8ca5775b046fc29879e61" - integrity sha512-EivH9EgBIb+G8ij1B2jAwSH36WnGvkQSEC6CkX/6v6ZFlw5fVOHvsgGF4uiEHO2GzMvunZb6tDLQEQSdrdocrA== +"@babel/generator@^7.17.10", "@babel/generator@^7.17.12", "@babel/generator@^7.18.2": + version "7.18.2" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.18.2.tgz#33873d6f89b21efe2da63fe554460f3df1c5880d" + integrity sha512-W1lG5vUwFvfMd8HVXqdfbuG7RuaSrTCCD8cl8fP8wOivdbtbIg2Db3IWUcgvfxKbbn6ZBGYRW/Zk1MIwK49mgw== dependencies: - "@babel/types" "^7.14.5" + "@babel/types" "^7.18.2" + "@jridgewell/gen-mapping" "^0.3.0" + jsesc "^2.5.1" -"@babel/helper-annotate-as-pure@^7.14.5", "@babel/helper-annotate-as-pure@^7.15.4": +"@babel/generator@^7.17.3": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.3.tgz#a2c30b0c4f89858cb87050c3ffdfd36bdf443200" + integrity sha512-+R6Dctil/MgUsZsZAkYgK+ADNSZzJRRy0TvY65T71z/CR854xHQ1EweBYXdfT+HNeN7w0cSJJEzgxZMv40pxsg== + dependencies: + "@babel/types" "^7.17.0" + jsesc "^2.5.1" + source-map "^0.5.0" + +"@babel/helper-annotate-as-pure@7.16.7", "@babel/helper-annotate-as-pure@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.16.7.tgz#bb2339a7534a9c128e3102024c60760a3a7f3862" + integrity sha512-s6t2w/IPQVTAET1HitoowRGXooX8mCgtuP5195wD/QJPV6wYjpujCGF7JuMODVX2ZAJOf1GT6DT9MHEZvLOFSw== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-annotate-as-pure@^7.14.5": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.15.4.tgz#3d0e43b00c5e49fdb6c57e421601a7a658d5f835" integrity sha512-QwrtdNvUNsPCj2lfNQacsGSQvGX8ee1ttrBrcozUP2Sv/jylewBP/8QFe6ZkBsC8T/GYWonNAWJV4aRR9AL2DA== dependencies: "@babel/types" "^7.15.4" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.14.5": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.15.4.tgz#21ad815f609b84ee0e3058676c33cf6d1670525f" - integrity sha512-P8o7JP2Mzi0SdC6eWr1zF+AEYvrsZa7GSY1lTayjF5XJhVH0kjLYUZPvTMflP7tBgZoe9gIhTa60QwFpqh/E0Q== +"@babel/helper-annotate-as-pure@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz#eaa49f6f80d5a33f9a5dd2276e6d6e451be0a6bb" + integrity sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA== dependencies: - "@babel/helper-explode-assignable-expression" "^7.15.4" - "@babel/types" "^7.15.4" + "@babel/types" "^7.18.6" -"@babel/helper-compilation-targets@^7.13.0", "@babel/helper-compilation-targets@^7.14.5", "@babel/helper-compilation-targets@^7.15.4": +"@babel/helper-builder-binary-assignment-operator-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.16.7.tgz#38d138561ea207f0f69eb1626a418e4f7e6a580b" + integrity sha512-C6FdbRaxYjwVu/geKW4ZeQ0Q31AftgRcdSnZ5/jsH6BzCJbtvXvhpfkbkThYSuutZA7nCXpPR6AD9zd1dprMkA== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-builder-binary-assignment-operator-visitor@^7.18.6": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.18.9.tgz#acd4edfd7a566d1d51ea975dff38fd52906981bb" + integrity sha512-yFQ0YCHoIqarl8BCRwBL8ulYUaZpz3bNsA7oFepAzee+8/+ImtADXNOmO5vJvsPff3qi+hvpkY/NYBTrBQgdNw== + dependencies: + "@babel/helper-explode-assignable-expression" "^7.18.6" + "@babel/types" "^7.18.9" + +"@babel/helper-compilation-targets@^7.13.0": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.15.4.tgz#cf6d94f30fbefc139123e27dd6b02f65aeedb7b9" integrity sha512-rMWPCirulnPSe4d+gwdWXLfAXTTBj8M3guAf5xFQJ0nvFY7tfNAFnWdqaHegHlgDZOCT4qvhF3BYlSJag8yhqQ== @@ -434,17 +577,74 @@ browserslist "^4.16.6" semver "^6.3.0" -"@babel/helper-create-class-features-plugin@^7.14.5", "@babel/helper-create-class-features-plugin@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.15.4.tgz#7f977c17bd12a5fba363cb19bea090394bf37d2e" - integrity sha512-7ZmzFi+DwJx6A7mHRwbuucEYpyBwmh2Ca0RvI6z2+WLZYCqV0JOaLb+u0zbtmDicebgKBZgqbYfLaKNqSgv5Pw== +"@babel/helper-compilation-targets@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.16.7.tgz#06e66c5f299601e6c7da350049315e83209d551b" + integrity sha512-mGojBwIWcwGD6rfqgRXVlVYmPAv7eOpIemUG3dGnDdCY4Pae70ROij3XmfrH6Fa1h1aiDylpglbZyktfzyo/hA== dependencies: - "@babel/helper-annotate-as-pure" "^7.15.4" - "@babel/helper-function-name" "^7.15.4" - "@babel/helper-member-expression-to-functions" "^7.15.4" - "@babel/helper-optimise-call-expression" "^7.15.4" - "@babel/helper-replace-supers" "^7.15.4" - "@babel/helper-split-export-declaration" "^7.15.4" + "@babel/compat-data" "^7.16.4" + "@babel/helper-validator-option" "^7.16.7" + browserslist "^4.17.5" + semver "^6.3.0" + +"@babel/helper-compilation-targets@^7.17.10", "@babel/helper-compilation-targets@^7.18.2": + version "7.18.2" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.2.tgz#67a85a10cbd5fc7f1457fec2e7f45441dc6c754b" + integrity sha512-s1jnPotJS9uQnzFtiZVBUxe67CuBa679oWFHpxYYnTpRL/1ffhyX44R9uYiXoa/pLXcY9H2moJta0iaanlk/rQ== + dependencies: + "@babel/compat-data" "^7.17.10" + "@babel/helper-validator-option" "^7.16.7" + browserslist "^4.20.2" + semver "^6.3.0" + +"@babel/helper-compilation-targets@^7.17.7", "@babel/helper-compilation-targets@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.18.9.tgz#69e64f57b524cde3e5ff6cc5a9f4a387ee5563bf" + integrity sha512-tzLCyVmqUiFlcFoAPLA/gL9TeYrF61VLNtb+hvkuVaB5SUjW7jcfrglBIX1vUIoT7CLP3bBlIMeyEsIl2eFQNg== + dependencies: + "@babel/compat-data" "^7.18.8" + "@babel/helper-validator-option" "^7.18.6" + browserslist "^4.20.2" + semver "^6.3.0" + +"@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7": + version "7.17.1" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.1.tgz#9699f14a88833a7e055ce57dcd3ffdcd25186b21" + integrity sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-member-expression-to-functions" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + +"@babel/helper-create-class-features-plugin@^7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.0.tgz#fac430912606331cb075ea8d82f9a4c145a4da19" + integrity sha512-Kh8zTGR9de3J63e5nS0rQUdRs/kbtwoeQQ0sriS0lItjC96u8XXZN6lKpuyWd2coKSU13py/y+LTmThLuVX0Pg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.17.9" + "@babel/helper-member-expression-to-functions" "^7.17.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + +"@babel/helper-create-class-features-plugin@^7.18.6", "@babel/helper-create-class-features-plugin@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.18.9.tgz#d802ee16a64a9e824fcbf0a2ffc92f19d58550ce" + integrity sha512-WvypNAYaVh23QcjpMR24CwZY2Nz6hqdOcFdPbNpV56hL5H6KiFheO7Xm1aPdlLQ7d5emYZX7VZwPp9x3z+2opw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-split-export-declaration" "^7.18.6" "@babel/helper-create-regexp-features-plugin@^7.14.5": version "7.14.5" @@ -454,10 +654,34 @@ "@babel/helper-annotate-as-pure" "^7.14.5" regexpu-core "^4.7.1" -"@babel/helper-define-polyfill-provider@^0.2.2": - version "0.2.3" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.3.tgz#0525edec5094653a282688d34d846e4c75e9c0b6" - integrity sha512-RH3QDAfRMzj7+0Nqu5oqgO5q9mFtQEVvCRsi8qCEfzLR9p2BHfn5FzhSB2oj1fF7I2+DcTORkYaQ6aTR9Cofew== +"@babel/helper-create-regexp-features-plugin@^7.16.7": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz#1dcc7d40ba0c6b6b25618997c5dbfd310f186fe1" + integrity sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + regexpu-core "^5.0.1" + +"@babel/helper-create-regexp-features-plugin@^7.17.12": + version "7.17.12" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.12.tgz#bb37ca467f9694bbe55b884ae7a5cc1e0084e4fd" + integrity sha512-b2aZrV4zvutr9AIa6/gA3wsZKRwTKYoDxYiFKcESS3Ug2GTXzwBEvMuuFLhCQpEnRXs1zng4ISAXSUxxKBIcxw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + regexpu-core "^5.0.1" + +"@babel/helper-create-regexp-features-plugin@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.18.6.tgz#3e35f4e04acbbf25f1b3534a657610a000543d3c" + integrity sha512-7LcpH1wnQLGrI+4v+nPp+zUvIkF9x0ddv1Hkdue10tg3gmRnLy97DXh4STiOf1qeIInyD69Qv5kKSZzKD8B/7A== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + regexpu-core "^5.1.0" + +"@babel/helper-define-polyfill-provider@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz#3c2f91b7971b9fc11fe779c945c014065dea340e" + integrity sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg== dependencies: "@babel/helper-compilation-targets" "^7.13.0" "@babel/helper-module-imports" "^7.12.13" @@ -468,14 +692,64 @@ resolve "^1.14.2" semver "^6.1.2" -"@babel/helper-explode-assignable-expression@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.15.4.tgz#f9aec9d219f271eaf92b9f561598ca6b2682600c" - integrity sha512-J14f/vq8+hdC2KoWLIQSsGrC9EFBKE4NFts8pfMpymfApds+fPqR30AOUWc4tyr56h9l/GA1Sxv2q3dLZWbQ/g== +"@babel/helper-define-polyfill-provider@^0.3.1": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz#52411b445bdb2e676869e5a74960d2d3826d2665" + integrity sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA== dependencies: - "@babel/types" "^7.15.4" + "@babel/helper-compilation-targets" "^7.13.0" + "@babel/helper-module-imports" "^7.12.13" + "@babel/helper-plugin-utils" "^7.13.0" + "@babel/traverse" "^7.13.0" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" -"@babel/helper-function-name@^7.14.5", "@babel/helper-function-name@^7.15.4": +"@babel/helper-define-polyfill-provider@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.2.tgz#bd10d0aca18e8ce012755395b05a79f45eca5073" + integrity sha512-r9QJJ+uDWrd+94BSPcP6/de67ygLtvVy6cK4luE6MOuDsZIdoaPBnfSpbO/+LTifjPckbKXRuI9BB/Z2/y3iTg== + dependencies: + "@babel/helper-compilation-targets" "^7.17.7" + "@babel/helper-plugin-utils" "^7.16.7" + debug "^4.1.1" + lodash.debounce "^4.0.8" + resolve "^1.14.2" + semver "^6.1.2" + +"@babel/helper-environment-visitor@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz#ff484094a839bde9d89cd63cba017d7aae80ecd7" + integrity sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-environment-visitor@^7.18.2": + version "7.18.2" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.2.tgz#8a6d2dedb53f6bf248e31b4baf38739ee4a637bd" + integrity sha512-14GQKWkX9oJzPiQQ7/J36FTXcD4kSp8egKjO9nINlSKiHITRA9q/R74qu8S9xlc/b/yjsJItQUeeh3xnGN0voQ== + +"@babel/helper-environment-visitor@^7.18.6", "@babel/helper-environment-visitor@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be" + integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg== + +"@babel/helper-explode-assignable-expression@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.16.7.tgz#12a6d8522fdd834f194e868af6354e8650242b7a" + integrity sha512-KyUenhWMC8VrxzkGP0Jizjo4/Zx+1nNZhgocs+gLzyZyB8SHidhoq9KK/8Ato4anhwsivfkBLftky7gvzbZMtQ== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-explode-assignable-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.18.6.tgz#41f8228ef0a6f1a036b8dfdfec7ce94f9a6bc096" + integrity sha512-eyAYAsQmB80jNfg4baAtLeWAQHfHFiR483rzFK+BhETlGZaQC9bsfrugfXDCbRHLQbIA7U5NxhhOxN7p/dWIcg== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-function-name@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.15.4.tgz#845744dafc4381a4a5fb6afa6c3d36f98a787ebc" integrity sha512-Z91cOMM4DseLIGOnog+Z8OI6YseR9bua+HpvLAQ2XayUGU+neTtX+97caALaLdyu53I/fjhbeCnWnRH1O3jFOw== @@ -484,6 +758,31 @@ "@babel/template" "^7.15.4" "@babel/types" "^7.15.4" +"@babel/helper-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.16.7.tgz#f1ec51551fb1c8956bc8dd95f38523b6cf375f8f" + integrity sha512-QfDfEnIUyyBSR3HtrtGECuZ6DAyCkYFp7GHl75vFtTnn6pjKeK0T1DB5lLkFvBea8MdaiUABx3osbgLyInoejA== + dependencies: + "@babel/helper-get-function-arity" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-function-name@^7.17.9": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.17.9.tgz#136fcd54bc1da82fcb47565cf16fd8e444b1ff12" + integrity sha512-7cRisGlVtiVqZ0MW0/yFB4atgpGLWEHUVYnb448hZK4x+vih0YO5UoS11XIYtZYqHd0dIPMdUSv8q5K4LdMnIg== + dependencies: + "@babel/template" "^7.16.7" + "@babel/types" "^7.17.0" + +"@babel/helper-function-name@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.18.9.tgz#940e6084a55dee867d33b4e487da2676365e86b0" + integrity sha512-fJgWlZt7nxGksJS9a0XdSaI4XvpExnNIgRP+rVefWh5U7BL8pPuir6SJUmFKRfjWQ51OtWSzwOxhaH/EBWWc0A== + dependencies: + "@babel/template" "^7.18.6" + "@babel/types" "^7.18.9" + "@babel/helper-get-function-arity@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.15.4.tgz#098818934a137fce78b536a3e015864be1e2879b" @@ -491,6 +790,13 @@ dependencies: "@babel/types" "^7.15.4" +"@babel/helper-get-function-arity@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.16.7.tgz#ea08ac753117a669f1508ba06ebcc49156387419" + integrity sha512-flc+RLSOBXzNzVhcLu6ujeHUrD6tANAOU5ojrRx/as+tbzf8+stUCj7+IfRRoAbEZqj/ahXEMsjhOhgeZsrnTw== + dependencies: + "@babel/types" "^7.16.7" + "@babel/helper-hoist-variables@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.15.4.tgz#09993a3259c0e918f99d104261dfdfc033f178df" @@ -498,78 +804,218 @@ dependencies: "@babel/types" "^7.15.4" -"@babel/helper-member-expression-to-functions@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.15.4.tgz#bfd34dc9bba9824a4658b0317ec2fd571a51e6ef" - integrity sha512-cokOMkxC/BTyNP1AlY25HuBWM32iCEsLPI4BHDpJCHHm1FU2E7dKWWIXJgQgSFiu4lp8q3bL1BIKwqkSUviqtA== +"@babel/helper-hoist-variables@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.16.7.tgz#86bcb19a77a509c7b77d0e22323ef588fa58c246" + integrity sha512-m04d/0Op34H5v7pbZw6pSKP7weA6lsMvfiIAMeIvkY/R4xQtBSMFEigu9QTZ2qB/9l22vsxtM8a+Q8CzD255fg== dependencies: - "@babel/types" "^7.15.4" + "@babel/types" "^7.16.7" -"@babel/helper-module-imports@^7.12.13", "@babel/helper-module-imports@^7.14.5", "@babel/helper-module-imports@^7.15.4": +"@babel/helper-hoist-variables@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" + integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-member-expression-to-functions@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.16.7.tgz#42b9ca4b2b200123c3b7e726b0ae5153924905b0" + integrity sha512-VtJ/65tYiU/6AbMTDwyoXGPKHgTsfRarivm+YbB5uAzKUyuPjgZSgAFeG87FCigc7KNHu2Pegh1XIT3lXjvz3Q== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-member-expression-to-functions@^7.17.7": + version "7.17.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.17.7.tgz#a34013b57d8542a8c4ff8ba3f747c02452a4d8c4" + integrity sha512-thxXgnQ8qQ11W2wVUObIqDL4p148VMxkt5T/qpN5k2fboRyzFGFmKsTGViquyM5QHKUy48OZoca8kw4ajaDPyw== + dependencies: + "@babel/types" "^7.17.0" + +"@babel/helper-member-expression-to-functions@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.18.9.tgz#1531661e8375af843ad37ac692c132841e2fd815" + integrity sha512-RxifAh2ZoVU67PyKIO4AMi1wTenGfMR/O/ae0CCRqwgBAt5v7xjdtRw7UoSbsreKrQn5t7r89eruK/9JjYHuDg== + dependencies: + "@babel/types" "^7.18.9" + +"@babel/helper-module-imports@^7.12.13": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.15.4.tgz#e18007d230632dea19b47853b984476e7b4e103f" integrity sha512-jeAHZbzUwdW/xHgHQ3QmWR4Jg6j15q4w/gCfwZvtqOxoo5DKtLHk8Bsf4c5RZRC7NmLEs+ohkdq8jFefuvIxAA== dependencies: "@babel/types" "^7.15.4" -"@babel/helper-module-transforms@^7.14.5", "@babel/helper-module-transforms@^7.14.8", "@babel/helper-module-transforms@^7.15.4", "@babel/helper-module-transforms@^7.15.8": - version "7.15.8" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz#d8c0e75a87a52e374a8f25f855174786a09498b2" - integrity sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg== +"@babel/helper-module-imports@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz#25612a8091a999704461c8a222d0efec5d091437" + integrity sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg== dependencies: - "@babel/helper-module-imports" "^7.15.4" - "@babel/helper-replace-supers" "^7.15.4" - "@babel/helper-simple-access" "^7.15.4" - "@babel/helper-split-export-declaration" "^7.15.4" - "@babel/helper-validator-identifier" "^7.15.7" - "@babel/template" "^7.15.4" - "@babel/traverse" "^7.15.4" - "@babel/types" "^7.15.6" + "@babel/types" "^7.16.7" -"@babel/helper-optimise-call-expression@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.15.4.tgz#f310a5121a3b9cc52d9ab19122bd729822dee171" - integrity sha512-E/z9rfbAOt1vDW1DR7k4SzhzotVV5+qMciWV6LaG1g4jeFrkDlJedjtV4h0i4Q/ITnUu+Pk08M7fczsB9GXBDw== +"@babel/helper-module-imports@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e" + integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA== dependencies: - "@babel/types" "^7.15.4" + "@babel/types" "^7.18.6" + +"@babel/helper-module-transforms@^7.12.1", "@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.9.tgz#5a1079c005135ed627442df31a42887e80fcb712" + integrity sha512-KYNqY0ICwfv19b31XzvmI/mfcylOzbLtowkw+mfvGPAQ3kfCnMLYbED3YecL5tPd8nAYFQFAd6JHp2LxZk/J1g== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.18.6" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helper-module-transforms@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.16.7.tgz#7665faeb721a01ca5327ddc6bba15a5cb34b6a41" + integrity sha512-gaqtLDxJEFCeQbYp9aLAefjhkKdjKcdh6DB7jniIGU3Pz52WAmP268zK0VgPz9hUNkMSYeH976K2/Y6yPadpng== + dependencies: + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-simple-access" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-module-transforms@^7.17.12", "@babel/helper-module-transforms@^7.17.7", "@babel/helper-module-transforms@^7.18.0": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.18.0.tgz#baf05dec7a5875fb9235bd34ca18bad4e21221cd" + integrity sha512-kclUYSUBIjlvnzN2++K9f2qzYKFgjmnmjwL4zlmU5f8ZtzgWe8s0rUPSTGy2HmK4P8T52MQsS+HTQAgZd3dMEA== + dependencies: + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-simple-access" "^7.17.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/helper-validator-identifier" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.18.0" + "@babel/types" "^7.18.0" + +"@babel/helper-optimise-call-expression@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.16.7.tgz#a34e3560605abbd31a18546bd2aad3e6d9a174f2" + integrity sha512-EtgBhg7rd/JcnpZFXpBy0ze1YRfdm7BnBX4uKMBd3ixa3RGAE002JZB66FJyNH7g0F38U05pXmA5P8cBh7z+1w== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-optimise-call-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" + integrity sha512-HP59oD9/fEHQkdcbgFCnbmgH5vIQTJbxh2yf+CdM89/glUNnuzr87Q8GIjGEnOktTROemO0Pe0iPAYbqZuOUiA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-plugin-utils@7.10.4": + 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-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.13.0", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.14.5.tgz#5ac822ce97eec46741ab70a517971e443a70c5a9" integrity sha512-/37qQCE3K0vvZKwoK4XU/irIJQdIfCJuhU5eKnNxpFDsOkgFaUAwbv+RYw6eYgsC0E4hS7r5KqGULUogqui0fQ== -"@babel/helper-remap-async-to-generator@^7.14.5", "@babel/helper-remap-async-to-generator@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.15.4.tgz#2637c0731e4c90fbf58ac58b50b2b5a192fc970f" - integrity sha512-v53MxgvMK/HCwckJ1bZrq6dNKlmwlyRNYM6ypaRTdXWGOE2c1/SCa6dL/HimhPulGhZKw9W0QhREM583F/t0vQ== - dependencies: - "@babel/helper-annotate-as-pure" "^7.15.4" - "@babel/helper-wrap-function" "^7.15.4" - "@babel/types" "^7.15.4" +"@babel/helper-plugin-utils@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.16.7.tgz#aa3a8ab4c3cceff8e65eb9e73d87dc4ff320b2f5" + integrity sha512-Qg3Nk7ZxpgMrsox6HreY1ZNKdBq7K72tDSliA6dCl5f007jR4ne8iD5UzuNnCJH2xBf2BEEVGr+/OL6Gdp7RxA== -"@babel/helper-replace-supers@^7.14.5", "@babel/helper-replace-supers@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.15.4.tgz#52a8ab26ba918c7f6dee28628b07071ac7b7347a" - integrity sha512-/ztT6khaXF37MS47fufrKvIsiQkx1LBRvSJNzRqmbyeZnTwU9qBxXYLaaT/6KaxfKhjs2Wy8kG8ZdsFUuWBjzw== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.15.4" - "@babel/helper-optimise-call-expression" "^7.15.4" - "@babel/traverse" "^7.15.4" - "@babel/types" "^7.15.4" +"@babel/helper-plugin-utils@^7.17.12": + version "7.17.12" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz#86c2347da5acbf5583ba0a10aed4c9bf9da9cf96" + integrity sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA== -"@babel/helper-simple-access@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.15.4.tgz#ac368905abf1de8e9781434b635d8f8674bcc13b" - integrity sha512-UzazrDoIVOZZcTeHHEPYrr1MvTR/K+wgLg6MY6e1CJyaRhbibftF6fR2KU2sFRtI/nERUZR9fBd6aKgBlIBaPg== - dependencies: - "@babel/types" "^7.15.4" +"@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.18.9.tgz#4b8aea3b069d8cb8a72cdfe28ddf5ceca695ef2f" + integrity sha512-aBXPT3bmtLryXaoJLyYPXPlSD4p1ld9aYeR+sJNOZjJJGiOpb+fKfh3NkcCu7J54nUJwCERPBExCCpyCOHnu/w== -"@babel/helper-skip-transparent-expression-wrappers@^7.14.5", "@babel/helper-skip-transparent-expression-wrappers@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.15.4.tgz#707dbdba1f4ad0fa34f9114fc8197aec7d5da2eb" - integrity sha512-BMRLsdh+D1/aap19TycS4eD1qELGrCBJwzaY9IE8LrpJtJb+H7rQkPIdsfgnMtLBA6DJls7X9z93Z4U8h7xw0A== +"@babel/helper-remap-async-to-generator@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.16.8.tgz#29ffaade68a367e2ed09c90901986918d25e57e3" + integrity sha512-fm0gH7Flb8H51LqJHy3HJ3wnE1+qtYR2A99K06ahwrawLdOFsCEWjZOrYricXJHoPSudNKxrMBUPEIPxiIIvBw== dependencies: - "@babel/types" "^7.15.4" + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-wrap-function" "^7.16.8" + "@babel/types" "^7.16.8" + +"@babel/helper-remap-async-to-generator@^7.18.6": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz#997458a0e3357080e54e1d79ec347f8a8cd28519" + integrity sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-wrap-function" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helper-replace-supers@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.16.7.tgz#e9f5f5f32ac90429c1a4bdec0f231ef0c2838ab1" + integrity sha512-y9vsWilTNaVnVh6xiJfABzsNpgDPKev9HnAgz6Gb1p6UUwf9NepdlsV7VXGCftJM+jqD5f7JIEubcpLjZj5dBw== + dependencies: + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-member-expression-to-functions" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/traverse" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/helper-replace-supers@^7.18.6", "@babel/helper-replace-supers@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.18.9.tgz#1092e002feca980fbbb0bd4d51b74a65c6a500e6" + integrity sha512-dNsWibVI4lNT6HiuOIBr1oyxo40HvIVmbwPUm3XZ7wMh4k2WxrxTqZwSqw/eEmXDS9np0ey5M2bz9tBmO9c+YQ== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-member-expression-to-functions" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helper-simple-access@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.16.7.tgz#d656654b9ea08dbb9659b69d61063ccd343ff0f7" + integrity sha512-ZIzHVyoeLMvXMN/vok/a4LWRy8G2v205mNP0XOuf9XRLyX5/u9CnVulUtDgUTama3lT+bf/UqucuZjqiGuTS1g== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-simple-access@^7.17.7", "@babel/helper-simple-access@^7.18.2": + version "7.18.2" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.2.tgz#4dc473c2169ac3a1c9f4a51cfcd091d1c36fcff9" + integrity sha512-7LIrjYzndorDY88MycupkpQLKS1AFfsVRm2k/9PtKScSy5tZq0McZTj+DiMRynboZfIqOKvo03pmhTaUgiD6fQ== + dependencies: + "@babel/types" "^7.18.2" + +"@babel/helper-simple-access@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz#d6d8f51f4ac2978068df934b569f08f29788c7ea" + integrity sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-skip-transparent-expression-wrappers@^7.16.0": + version "7.16.0" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.16.0.tgz#0ee3388070147c3ae051e487eca3ebb0e2e8bb09" + integrity sha512-+il1gTy0oHwUsBQZyJvukbB4vPMdcYBrFHa0Uc4AizLxbq6BOYC51Rv4tWocX9BLBDLZ4kc6qUFpQ6HRgL+3zw== + dependencies: + "@babel/types" "^7.16.0" + +"@babel/helper-skip-transparent-expression-wrappers@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.18.9.tgz#778d87b3a758d90b471e7b9918f34a9a02eb5818" + integrity sha512-imytd2gHi3cJPsybLRbmFrF7u5BIEuI2cNheyKi3/iOBC63kNn3q8Crn2xVuESli0aM4KYsyEqKyS7lFL8YVtw== + dependencies: + "@babel/types" "^7.18.9" "@babel/helper-split-export-declaration@^7.15.4": version "7.15.4" @@ -578,34 +1024,96 @@ dependencies: "@babel/types" "^7.15.4" -"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9", "@babel/helper-validator-identifier@^7.15.7": +"@babel/helper-split-export-declaration@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.16.7.tgz#0b648c0c42da9d3920d85ad585f2778620b8726b" + integrity sha512-xbWoy/PFoxSWazIToT9Sif+jJTlrMcndIsaOKvTA6u7QEo7ilkRZpjew18/W3c7nm8fXdUDXh02VXTbZ0pGDNw== + dependencies: + "@babel/types" "^7.16.7" + +"@babel/helper-split-export-declaration@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075" + integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA== + dependencies: + "@babel/types" "^7.18.6" + +"@babel/helper-validator-identifier@^7.14.5", "@babel/helper-validator-identifier@^7.14.9": version "7.15.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.15.7.tgz#220df993bfe904a4a6b02ab4f3385a5ebf6e2389" integrity sha512-K4JvCtQqad9OY2+yTU8w+E82ywk/fe+ELNlt1G8z3bVGlZfn/hOcQQsUhGhW/N+tb3fxK800wLtKOE/aM0m72w== +"@babel/helper-validator-identifier@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad" + integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw== + +"@babel/helper-validator-identifier@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz#9c97e30d31b2b8c72a1d08984f2ca9b574d7a076" + integrity sha512-MmetCkz9ej86nJQV+sFCxoGGrUbU3q02kgLciwkrt9QqEB7cP39oKEY0PakknEO0Gu20SskMRi+AYZ3b1TpN9g== + "@babel/helper-validator-option@^7.14.5": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.14.5.tgz#6e72a1fff18d5dfcb878e1e62f1a021c4b72d5a3" integrity sha512-OX8D5eeX4XwcroVW45NMvoYaIuFI+GQpA2a8Gi+X/U/cDUIRsV37qQfF905F0htTRCREQIB4KqPeaveRJUl3Ow== -"@babel/helper-wrap-function@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.15.4.tgz#6f754b2446cfaf3d612523e6ab8d79c27c3a3de7" - integrity sha512-Y2o+H/hRV5W8QhIfTpRIBwl57y8PrZt6JM3V8FOo5qarjshHItyH5lXlpMfBfmBefOqSCpKZs/6Dxqp0E/U+uw== - dependencies: - "@babel/helper-function-name" "^7.15.4" - "@babel/template" "^7.15.4" - "@babel/traverse" "^7.15.4" - "@babel/types" "^7.15.4" +"@babel/helper-validator-option@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz#b203ce62ce5fe153899b617c08957de860de4d23" + integrity sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ== -"@babel/helpers@^7.14.8", "@babel/helpers@^7.15.4", "@babel/helpers@^7.8.3": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.15.4.tgz#5f40f02050a3027121a3cf48d497c05c555eaf43" - integrity sha512-V45u6dqEJ3w2rlryYYXf6i9rQ5YMNu4FLS6ngs8ikblhu2VdR1AqAd6aJjBzmf2Qzh6KOLqKHxEN9+TFbAkAVQ== +"@babel/helper-validator-option@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" + integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + +"@babel/helper-wrap-function@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.16.8.tgz#58afda087c4cd235de92f7ceedebca2c41274200" + integrity sha512-8RpyRVIAW1RcDDGTA+GpPAwV22wXCfKOoM9bet6TLkGIFTkRQSkH1nMQ5Yet4MpoXe1ZwHPVtNasc2w0uZMqnw== dependencies: - "@babel/template" "^7.15.4" - "@babel/traverse" "^7.15.4" - "@babel/types" "^7.15.4" + "@babel/helper-function-name" "^7.16.7" + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.16.8" + "@babel/types" "^7.16.8" + +"@babel/helper-wrap-function@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.18.9.tgz#ae1feddc6ebbaa2fd79346b77821c3bd73a39646" + integrity sha512-cG2ru3TRAL6a60tfQflpEfs4ldiPwF6YW3zfJiRgmoFVIaC1vGnBBgatfec+ZUziPHkHSaXAuEck3Cdkf3eRpQ== + dependencies: + "@babel/helper-function-name" "^7.18.9" + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helpers@^7.12.5", "@babel/helpers@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.9.tgz#4bef3b893f253a1eced04516824ede94dcfe7ff9" + integrity sha512-Jf5a+rbrLoR4eNdUmnFu8cN5eNJT6qdTdOg5IHIzq87WwyRw9PwguLFOWYgktN/60IP4fgDUawJvs7PjQIzELQ== + dependencies: + "@babel/template" "^7.18.6" + "@babel/traverse" "^7.18.9" + "@babel/types" "^7.18.9" + +"@babel/helpers@^7.17.2": + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.2.tgz#23f0a0746c8e287773ccd27c14be428891f63417" + integrity sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ== + dependencies: + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.17.0" + "@babel/types" "^7.17.0" + +"@babel/helpers@^7.17.9", "@babel/helpers@^7.18.2": + version "7.18.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.18.2.tgz#970d74f0deadc3f5a938bfa250738eb4ac889384" + integrity sha512-j+d+u5xT5utcQSzrh9p+PaJX94h++KN+ng9b9WEJq7pkUPAd61FGqhjuUEdfknb3E/uDBb7ruwEeKkIxNJPIrg== + dependencies: + "@babel/template" "^7.16.7" + "@babel/traverse" "^7.18.2" + "@babel/types" "^7.18.2" "@babel/highlight@^7.14.5": version "7.14.5" @@ -616,150 +1124,362 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.14.5", "@babel/parser@^7.14.8", "@babel/parser@^7.15.4", "@babel/parser@^7.15.8", "@babel/parser@^7.8.3": +"@babel/highlight@^7.16.7": + version "7.16.10" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88" + integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/highlight@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf" + integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + chalk "^2.0.0" + js-tokens "^4.0.0" + +"@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.18.6", "@babel/parser@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.9.tgz#f2dde0c682ccc264a9a8595efd030a5cc8fd2539" + integrity sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg== + +"@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.3": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.3.tgz#b07702b982990bf6fdc1da5049a23fece4c5c3d0" + integrity sha512-7yJPvPV+ESz2IUTPbOL+YkIGyCqOyNIzdguKQuJGnH7bg1WTIifuM21YqokFt/THWh1AkCRn9IgoykTRCBVpzA== + +"@babel/parser@^7.15.4": version "7.15.8" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.15.8.tgz#7bacdcbe71bdc3ff936d510c15dcea7cf0b99016" integrity sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA== -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.14.5": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.15.4.tgz#dbdeabb1e80f622d9f0b583efb2999605e0a567e" - integrity sha512-eBnpsl9tlhPhpI10kU06JHnrYXwg3+V6CaP2idsCXNef0aeslpqyITXQ74Vfk5uHgY7IG7XP0yIH8b42KSzHog== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.15.4" - "@babel/plugin-proposal-optional-chaining" "^7.14.5" +"@babel/parser@^7.17.10", "@babel/parser@^7.17.12", "@babel/parser@^7.18.0": + version "7.18.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.18.4.tgz#6774231779dd700e0af29f6ad8d479582d7ce5ef" + integrity sha512-FDge0dFazETFcxGw/EXzOkN8uJp0PC7Qbm+Pe9T+av2zlBpOgunFHkQPPn+eRuClU73JF+98D531UgayY89tow== -"@babel/plugin-proposal-async-generator-functions@7.14.7": - version "7.14.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.14.7.tgz#784a48c3d8ed073f65adcf30b57bcbf6c8119ace" - integrity sha512-RK8Wj7lXLY3bqei69/cc25gwS5puEc3dknoFPFbqfy3XxYQBQFvu4ioWpafMBAB+L9NyptQK4nMOa5Xz16og8Q== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.7.tgz#4eda6d6c2a0aa79c70fa7b6da67763dfe2141050" + integrity sha512-anv/DObl7waiGEnC24O9zqL0pSuI9hljihqiDuFHC8d7/bjr/4RLGPWuc8rYOff/QPzbEPSkzG8wGG9aDuhHRg== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-remap-async-to-generator" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.18.6.tgz#da5b8f9a580acdfbe53494dba45ea389fb09a4d2" + integrity sha512-Dgxsyg54Fx1d4Nge8UnvTrED63vrwOdPmyvPzlNN/boaliRP54pm3pGzZD1SJUwrBA+Cs/xdG8kXX6Mn/RfISQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.16.7.tgz#cc001234dfc139ac45f6bcf801866198c8c72ff9" + integrity sha512-di8vUHRdf+4aJ7ltXhaDbPoszdkh59AQtJM5soLsuHpQJdFQZOA4uGj0V2u/CZ8bJ/u8ULDL5yq6FO/bCXnKHw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-proposal-optional-chaining" "^7.16.7" + +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.18.9.tgz#a11af19aa373d68d561f08e0a57242350ed0ec50" + integrity sha512-AHrP9jadvH7qlOj6PINbgSuphjQUAK7AOT7DPjBo9EHoLhQTnnK5u45e1Hd4DbSQEO9nqPWtQ89r+XEOWFScKg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" + "@babel/plugin-proposal-optional-chaining" "^7.18.9" + +"@babel/plugin-proposal-async-generator-functions@7.16.8", "@babel/plugin-proposal-async-generator-functions@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.8.tgz#3bdd1ebbe620804ea9416706cd67d60787504bc8" + integrity sha512-71YHIvMuiuqWJQkebWJtdhQTfd4Q4mF76q2IX37uZPkG9+olBxsX+rH1vkhFto4UeJZ9dPY2s+mDvhDm1u2BGQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-remap-async-to-generator" "^7.16.8" "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-proposal-async-generator-functions@^7.14.7": - version "7.15.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.15.8.tgz#a3100f785fab4357987c4223ab1b02b599048403" - integrity sha512-2Z5F2R2ibINTc63mY7FLqGfEbmofrHU9FitJW1Q7aPaKFhiPvSq6QEt/BoWN5oME3GVyjcRuNNSRbb9LC0CSWA== +"@babel/plugin-proposal-async-generator-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.6.tgz#aedac81e6fc12bb643374656dd5f2605bf743d17" + integrity sha512-WAz4R9bvozx4qwf74M+sfqPMKfSqwM0phxPTR6iJIi8robgzXwkEgmeJG1gEKhm6sDqT/U9aV3lfcqybIpev8w== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-remap-async-to-generator" "^7.15.4" + "@babel/helper-environment-visitor" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-remap-async-to-generator" "^7.18.6" "@babel/plugin-syntax-async-generators" "^7.8.4" -"@babel/plugin-proposal-class-properties@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.14.5.tgz#40d1ee140c5b1e31a350f4f5eed945096559b42e" - integrity sha512-q/PLpv5Ko4dVc1LYMpCY7RVAAO4uk55qPwrIuJ5QJ8c6cVuAmhu7I/49JOppXL6gXf7ZHzpRVEUZdYoPLM04Gg== +"@babel/plugin-proposal-class-properties@^7.12.1", "@babel/plugin-proposal-class-properties@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.18.6.tgz#b110f59741895f7ec21a6fff696ec46265c446a3" + integrity sha512-cumfXOF0+nzZrrN8Rf0t7M+tF6sZc7vhQwYQck9q1/5w2OExlD+b4v4RpMJFaV1Z7WcDRgO6FqvxqxGlwo+RHQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-proposal-class-static-block@^7.14.5": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.15.4.tgz#3e7ca6128453c089e8b477a99f970c63fc1cb8d7" - integrity sha512-M682XWrrLNk3chXCjoPUQWOyYsB93B9z3mRyjtqqYJWDf2mfCdIYgDrA11cgNVhAQieaq6F2fn2f3wI0U4aTjA== +"@babel/plugin-proposal-class-properties@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.16.7.tgz#925cad7b3b1a2fcea7e59ecc8eb5954f961f91b0" + integrity sha512-IobU0Xme31ewjYOShSIqd/ZGM/r/cuOz2z0MDbNrhF5FW+ZVgi0f2lyeoj9KFPDOAqsYxmLWZte1WOwlvY9aww== dependencies: - "@babel/helper-create-class-features-plugin" "^7.15.4" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-proposal-class-static-block@^7.17.6": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.0.tgz#7d02253156e3c3793bdb9f2faac3a1c05f0ba710" + integrity sha512-t+8LsRMMDE74c6sV7KShIw13sqbqd58tlqNrsWoWBTIMw7SVQ0cZ905wLNS/FBCy/3PyooRHLFFlfrUNyyz5lA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.0" + "@babel/helper-plugin-utils" "^7.17.12" "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-proposal-dynamic-import@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.14.5.tgz#0c6617df461c0c1f8fff3b47cd59772360101d2c" - integrity sha512-ExjiNYc3HDN5PXJx+bwC50GIx/KKanX2HiggnIUAYedbARdImiCU4RhhHfdf0Kd7JNXGpsBBBCOm+bBVy3Gb0g== +"@babel/plugin-proposal-class-static-block@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-static-block/-/plugin-proposal-class-static-block-7.18.6.tgz#8aa81d403ab72d3962fc06c26e222dacfc9b9020" + integrity sha512-+I3oIiNxrCpup3Gi8n5IGMwj0gOCAjcJUSQEcotNnCCPMEnixawOQ+KeJPlgfjzx+FKQ1QSyZOWe7wmoJp7vhw== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + +"@babel/plugin-proposal-decorators@^7.12.12": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.18.9.tgz#d09d41ffc74af8499d2ac706ed0dbd5474711665" + integrity sha512-KD7zDNaD14CRpjQjVbV4EnH9lsKYlcpUrhZH37ei2IY+AlXrfAPy5pTmRUE4X6X1k8EsKXPraykxeaogqQvSGA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/plugin-syntax-decorators" "^7.18.6" + +"@babel/plugin-proposal-dynamic-import@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.16.7.tgz#c19c897eaa46b27634a00fee9fb7d829158704b2" + integrity sha512-I8SW9Ho3/8DRSdmDdH3gORdyUuYnk1m4cMxUAdu5oy4n3OfN8flDEH+d60iG7dUfi0KkYwSvoalHzzdRzpWHTg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-proposal-export-namespace-from@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.14.5.tgz#dbad244310ce6ccd083072167d8cea83a52faf76" - integrity sha512-g5POA32bXPMmSBu5Dx/iZGLGnKmKPc5AiY7qfZgurzrCYgIztDlHFbznSNCoQuv57YQLnQfaDi7dxCtLDIdXdA== +"@babel/plugin-proposal-dynamic-import@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.18.6.tgz#72bcf8d408799f547d759298c3c27c7e7faa4d94" + integrity sha512-1auuwmK+Rz13SJj36R+jqFPMJWyKEDd7lLSdOj4oJK0UTgGueSAtkrCvz9ewmgyU/P941Rv2fQwZJN8s6QruXw== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + +"@babel/plugin-proposal-export-default-from@^7.12.1": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.18.9.tgz#9dfad26452e53cae8f045c6153e82dc50e9bee89" + integrity sha512-1qtsLNCDm5awHLIt+2qAFDi31XC94r4QepMQcOosC7FpY6O+Bgay5f2IyAQt2wvm1TARumpFprnQt5pTIJ9nUg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-export-default-from" "^7.18.6" + +"@babel/plugin-proposal-export-namespace-from@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.16.7.tgz#09de09df18445a5786a305681423ae63507a6163" + integrity sha512-ZxdtqDXLRGBL64ocZcs7ovt71L3jhC1RGSyR996svrCi3PYqHNkb3SwPJCs8RIzD86s+WPpt2S73+EHCGO+NUA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-proposal-json-strings@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.14.5.tgz#38de60db362e83a3d8c944ac858ddf9f0c2239eb" - integrity sha512-NSq2fczJYKVRIsUJyNxrVUMhB27zb7N7pOFGQOhBKJrChbGcgEAqyZrmZswkPk18VMurEeJAaICbfm57vUeTbQ== +"@babel/plugin-proposal-export-namespace-from@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.18.9.tgz#5f7313ab348cdb19d590145f9247540e94761203" + integrity sha512-k1NtHyOMvlDDFeb9G5PhUXuGj8m/wiwojgQVEhJ/fsVsMCpLyOP4h0uGEjYJKrRI+EVPlb5Jk+Gt9P97lOGwtA== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-json-strings@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.16.7.tgz#9732cb1d17d9a2626a08c5be25186c195b6fa6e8" + integrity sha512-lNZ3EEggsGY78JavgbHsK9u5P3pQaW7k4axlgFLYkMd7UBsiNahCITShLjNQschPyjtO6dADrL24757IdhBrsQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-proposal-logical-assignment-operators@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.14.5.tgz#6e6229c2a99b02ab2915f82571e0cc646a40c738" - integrity sha512-YGn2AvZAo9TwyhlLvCCWxD90Xq8xJ4aSgaX3G5D/8DW94L8aaT+dS5cSP+Z06+rCJERGSr9GxMBZ601xoc2taw== +"@babel/plugin-proposal-json-strings@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.18.6.tgz#7e8788c1811c393aff762817e7dbf1ebd0c05f0b" + integrity sha512-lr1peyn9kOdbYc0xr0OdHTZ5FMqS6Di+H0Fz2I/JwMzGmzJETNeOFq2pBySw6X/KFL5EWDjlJuMsUGRFb8fQgQ== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-json-strings" "^7.8.3" + +"@babel/plugin-proposal-logical-assignment-operators@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.16.7.tgz#be23c0ba74deec1922e639832904be0bea73cdea" + integrity sha512-K3XzyZJGQCr00+EtYtrDjmwX7o7PLK6U9bi1nCwkQioRFVUv6dJoxbQjtWVtP+bCPy82bONBKG8NPyQ4+i6yjg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.14.5.tgz#ee38589ce00e2cc59b299ec3ea406fcd3a0fdaf6" - integrity sha512-gun/SOnMqjSb98Nkaq2rTKMwervfdAoz6NphdY0vTfuzMfryj+tDGb2n6UkDKwez+Y8PZDhE3D143v6Gepp4Hg== +"@babel/plugin-proposal-logical-assignment-operators@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.18.9.tgz#8148cbb350483bf6220af06fa6db3690e14b2e23" + integrity sha512-128YbMpjCrP35IOExw2Fq+x55LMP42DzhOhX2aNNIdI9avSWl2PI0yuBWarr3RYpZBSPtabfadkH2yeRiMD61Q== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.12.1", "@babel/plugin-proposal-nullish-coalescing-operator@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.18.6.tgz#fdd940a99a740e577d6c753ab6fbb43fdb9467e1" + integrity sha512-wQxQzxYeJqHcfppzBDnm1yAY0jSRkUXR2z8RePZYrKwMKgMlE8+Z6LUno+bd6LvbGh8Gltvy74+9pIYkr+XkKA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-proposal-numeric-separator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.14.5.tgz#83631bf33d9a51df184c2102a069ac0c58c05f18" - integrity sha512-yiclALKe0vyZRZE0pS6RXgjUOt87GWv6FYa5zqj15PvhOGFO69R5DusPlgK/1K5dVnCtegTiWu9UaBSrLLJJBg== +"@babel/plugin-proposal-nullish-coalescing-operator@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.16.7.tgz#141fc20b6857e59459d430c850a0011e36561d99" + integrity sha512-aUOrYU3EVtjf62jQrCj63pYZ7k6vns2h/DQvHPWGmsJRYzWXZ6/AsfgpiRy6XiuIDADhJzP2Q9MwSMKauBQ+UQ== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + +"@babel/plugin-proposal-numeric-separator@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.16.7.tgz#d6b69f4af63fb38b6ca2558442a7fb191236eba9" + integrity sha512-vQgPMknOIgiuVqbokToyXbkY/OmmjAzr/0lhSIbG/KmnzXPGwW/AdhdKpi+O4X/VkWiWjnkKOBiqJrTaC98VKw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-object-rest-spread@^7.14.7": - version "7.15.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.15.6.tgz#ef68050c8703d07b25af402cb96cf7f34a68ed11" - integrity sha512-qtOHo7A1Vt+O23qEAX+GdBpqaIuD3i9VRrWgCJeq7WO6H2d14EK3q11urj5Te2MAeK97nMiIdRpwd/ST4JFbNg== +"@babel/plugin-proposal-numeric-separator@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.18.6.tgz#899b14fbafe87f053d2c5ff05b36029c62e13c75" + integrity sha512-ozlZFogPqoLm8WBr5Z8UckIoE4YQ5KESVcNudyXOR8uqIkliTEgJ3RoketfG6pmzLdeZF0H/wjE9/cCEitBl7Q== dependencies: - "@babel/compat-data" "^7.15.0" - "@babel/helper-compilation-targets" "^7.15.4" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.15.4" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-proposal-optional-catch-binding@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.14.5.tgz#939dd6eddeff3a67fdf7b3f044b5347262598c3c" - integrity sha512-3Oyiixm0ur7bzO5ybNcZFlmVsygSIQgdOa7cTfOYCMY+wEPAYhZAJxi3mixKFCTCKUhQXuCTtQ1MzrpL3WT8ZQ== +"@babel/plugin-proposal-object-rest-spread@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz#def9bd03cea0f9b72283dac0ec22d289c7691069" + integrity sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.12.1" + +"@babel/plugin-proposal-object-rest-spread@^7.12.1", "@babel/plugin-proposal-object-rest-spread@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.9.tgz#f9434f6beb2c8cae9dfcf97d2a5941bbbf9ad4e7" + integrity sha512-kDDHQ5rflIeY5xl69CEqGEZ0KY369ehsCIEbTGb4siHG5BE9sga/T0r0OUwyZNLMmZE79E1kbsqAjwFCW4ds6Q== + dependencies: + "@babel/compat-data" "^7.18.8" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.18.8" + +"@babel/plugin-proposal-object-rest-spread@^7.17.3": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.18.0.tgz#79f2390c892ba2a68ec112eb0d895cfbd11155e8" + integrity sha512-nbTv371eTrFabDfHLElkn9oyf9VG+VKK6WMzhY2o4eHKaG19BToD9947zzGMO6I/Irstx9d8CwX6njPNIAR/yw== + dependencies: + "@babel/compat-data" "^7.17.10" + "@babel/helper-compilation-targets" "^7.17.10" + "@babel/helper-plugin-utils" "^7.17.12" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-transform-parameters" "^7.17.12" + +"@babel/plugin-proposal-optional-catch-binding@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.16.7.tgz#c623a430674ffc4ab732fd0a0ae7722b67cb74cf" + integrity sha512-eMOH/L4OvWSZAE1VkHbr1vckLG1WUcHGJSLqqQwl2GaUqG6QjddvrOaTUMNYiv77H5IKPMZ9U9P7EaHwvAShfA== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.14.5.tgz#fa83651e60a360e3f13797eef00b8d519695b603" - integrity sha512-ycz+VOzo2UbWNI1rQXxIuMOzrDdHGrI23fRiz/Si2R4kv2XZQ1BK8ccdHwehMKBlcH/joGW/tzrUmo67gbJHlQ== +"@babel/plugin-proposal-optional-catch-binding@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.18.6.tgz#f9400d0e6a3ea93ba9ef70b09e72dd6da638a2cb" + integrity sha512-Q40HEhs9DJQyaZfUjjn6vE8Cv4GmMHCYuMGIWUnlxH6400VGxOuwWsPt4FxXxJkC/5eOzgn0z21M9gMT4MOhbw== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.14.5" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + +"@babel/plugin-proposal-optional-chaining@^7.12.7", "@babel/plugin-proposal-optional-chaining@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.18.9.tgz#e8e8fe0723f2563960e4bf5e9690933691915993" + integrity sha512-v5nwt4IqBXihxGsW2QmCWMDS3B3bzGIk/EQVZz2ei7f3NJl8NzAJVvUmpDW5q1CRNY+Beb/k58UAH1Km1N411w== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-proposal-private-methods@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.14.5.tgz#37446495996b2945f30f5be5b60d5e2aa4f5792d" - integrity sha512-838DkdUA1u+QTCplatfq4B7+1lnDa/+QMI89x5WZHBcnNv+47N8QEj2k9I2MUU9xIv8XJ4XvPCviM/Dj7Uwt9g== +"@babel/plugin-proposal-optional-chaining@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.7.tgz#7cd629564724816c0e8a969535551f943c64c39a" + integrity sha512-eC3xy+ZrUcBtP7x+sq62Q/HYd674pPTb/77XZMb5wbDPGWIdUbSr4Agr052+zaUPSb+gGRnjxXfKFvx5iMJ+DA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-proposal-private-property-in-object@^7.14.5": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.15.4.tgz#55c5e3b4d0261fd44fe637e3f624cfb0f484e3e5" - integrity sha512-X0UTixkLf0PCCffxgu5/1RQyGGbgZuKoI+vXP4iSbJSYwPb7hu06omsFGBvQ9lJEvwgrxHdS8B5nbfcd8GyUNA== +"@babel/plugin-proposal-private-methods@^7.12.1", "@babel/plugin-proposal-private-methods@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.18.6.tgz#5209de7d213457548a98436fa2882f52f4be6bea" + integrity sha512-nutsvktDItsNn4rpGItSNV2sz1XwS+nfU0Rg8aCx3W3NOKVzdMjJRu0O5OkgDp3ZGICSTbgRpxZoWsxoKRvbeA== dependencies: - "@babel/helper-annotate-as-pure" "^7.15.4" - "@babel/helper-create-class-features-plugin" "^7.15.4" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-proposal-private-methods@^7.16.11": + version "7.16.11" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.16.11.tgz#e8df108288555ff259f4527dbe84813aac3a1c50" + integrity sha512-F/2uAkPlXDr8+BHpZvo19w3hLFKge+k75XUprE6jaqKxjGkSYcK+4c+bup5PdW/7W/Rpjwql7FTVEDW+fRAQsw== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.16.10" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-proposal-private-property-in-object@^7.12.1", "@babel/plugin-proposal-private-property-in-object@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.18.6.tgz#a64137b232f0aca3733a67eb1a144c192389c503" + integrity sha512-9Rysx7FOctvT5ouj5JODjAFAkgGoudQuLPamZb0v1TGLpapdNaftzifU8NTWQm0IRjqoYypdrSmyWgkocDQ8Dw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-proposal-unicode-property-regex@^7.14.5", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": +"@babel/plugin-proposal-private-property-in-object@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.16.7.tgz#b0b8cef543c2c3d57e59e2c611994861d46a3fce" + integrity sha512-rMQkjcOFbm+ufe3bTZLyOfsOUOxyvLXZJCTARhJr+8UMSoZmqTe1K1BgkFcrW37rAchWg57yI69ORxiWvUINuQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-create-class-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + +"@babel/plugin-proposal-unicode-property-regex@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.16.7.tgz#635d18eb10c6214210ffc5ff4932552de08188a2" + integrity sha512-QRK0YI/40VLhNVGIjRNAAQkEHws0cswSdFFjpFyt943YmJIU1da9uW63Iu6NFV6CxTZW5eTDCrwZUstBWgp/Rg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-proposal-unicode-property-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.18.6.tgz#af613d2cd5e643643b65cded64207b15c85cb78e" + integrity sha512-2BShG/d5yoZyXZfVePH91urL5wTG6ASZU9M4o03lKK8u8UW1y08OMttBSOADTcJrnPMpvDXRG3G8fyLh4ovs8w== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-proposal-unicode-property-regex@^7.4.4": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.14.5.tgz#0f95ee0e757a5d647f378daa0eca7e93faa8bbe8" integrity sha512-6axIeOU5LnY471KenAB9vI8I5j7NQ2d652hIYwVyRfgaZT5UpiqFKCuVXCDMSrU+3VFafnu2c5m3lrWIlr6A5Q== @@ -788,6 +1508,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" +"@babel/plugin-syntax-decorators@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.18.6.tgz#2e45af22835d0b0f8665da2bfd4463649ce5dbc1" + integrity sha512-fqyLgjcxf/1yhyZ6A+yo1u9gJ7eleFQod2lkaUsF9DQ7sbbY3Ligym3L0+I2c0WmqNKDpoD9UTb1AKP3qRMOAQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-dynamic-import@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" @@ -795,6 +1522,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" +"@babel/plugin-syntax-export-default-from@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.18.6.tgz#8df076711a4818c4ce4f23e61d622b0ba2ff84bc" + integrity sha512-Kr//z3ujSVNx6E9z9ih5xXXMqK07VVTuqPmqGe6Mss/zW5XPeLZeSDZoP9ab/hT4wPKqAgjl2PnhPrcpk8Seew== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-export-namespace-from@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" @@ -802,6 +1536,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" +"@babel/plugin-syntax-import-assertions@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.18.6.tgz#cd6190500a4fa2fe31990a963ffab4b63e4505e4" + integrity sha512-/DU3RXad9+bZwrgWJQKbr39gYbJpLJHezqEzRzi/BHRlJ9zsQb4CK2CA/5apllXNomwA1qHwzvHl+AdEmC5krQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-json-strings@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" @@ -809,6 +1550,20 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" +"@babel/plugin-syntax-jsx@7.12.1": + version "7.12.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.12.1.tgz#9d9d357cc818aa7ae7935917c1257f67677a0926" + integrity sha512-1yRi7yAtB0ETgxdY9ti/p2TivUxJkTdhu/ZbF9MshVGqOx1TdB3b7xCXs49Fupgg50N45KcAsRP/ZqWjs9SRjg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-syntax-jsx@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz#a8feef63b010150abd97f1649ec296e849943ca0" + integrity sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-logical-assignment-operators@^7.10.4": version "7.10.4" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" @@ -830,7 +1585,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-object-rest-spread@^7.8.3": +"@babel/plugin-syntax-object-rest-spread@7.8.3", "@babel/plugin-syntax-object-rest-spread@^7.8.0", "@babel/plugin-syntax-object-rest-spread@^7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== @@ -865,64 +1620,146 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-arrow-functions@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.14.5.tgz#f7187d9588a768dd080bf4c9ffe117ea62f7862a" - integrity sha512-KOnO0l4+tD5IfOdi4x8C1XmEIRWUjNRV8wc6K2vz/3e8yAOoZZvsRXRRIF/yo/MAOFb4QjtAw9xSxMXbSMRy8A== +"@babel/plugin-syntax-typescript@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz#1c09cd25795c7c2b8a4ba9ae49394576d4133285" + integrity sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-async-to-generator@7.14.5", "@babel/plugin-transform-async-to-generator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.14.5.tgz#72c789084d8f2094acb945633943ef8443d39e67" - integrity sha512-szkbzQ0mNk0rpu76fzDdqSyPu0MuvpXgC+6rz5rpMb5OIRxdmHfQxrktL8CYolL2d8luMCZTR0DpIMIdL27IjA== +"@babel/plugin-transform-arrow-functions@^7.12.1", "@babel/plugin-transform-arrow-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.18.6.tgz#19063fcf8771ec7b31d742339dac62433d0611fe" + integrity sha512-9S9X9RUefzrsHZmKMbDXxweEH+YlE8JJEuat9FdvW9Qh1cw7W64jELCtWNkPBPX5En45uy28KGvA/AySqUh8CQ== dependencies: - "@babel/helper-module-imports" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-remap-async-to-generator" "^7.14.5" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-block-scoped-functions@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.14.5.tgz#e48641d999d4bc157a67ef336aeb54bc44fd3ad4" - integrity sha512-dtqWqdWZ5NqBX3KzsVCWfQI3A53Ft5pWFCT2eCVUftWZgjc5DpDponbIF1+c+7cSGk2wN0YK7HGL/ezfRbpKBQ== +"@babel/plugin-transform-arrow-functions@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.16.7.tgz#44125e653d94b98db76369de9c396dc14bef4154" + integrity sha512-9ffkFFMbvzTvv+7dTp/66xvZAWASuPD5Tl9LK3Z9vhOmANo6j94rik+5YMBt4CwHVMWLWpMsriIc2zsa3WW3xQ== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-block-scoping@^7.14.5": - version "7.15.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.15.3.tgz#94c81a6e2fc230bcce6ef537ac96a1e4d2b3afaf" - integrity sha512-nBAzfZwZb4DkaGtOes1Up1nOAp9TDRRFw4XBzBBSG9QK7KVFmYzgj9o9sbPv7TX5ofL4Auq4wZnxCoPnI/lz2Q== +"@babel/plugin-transform-async-to-generator@7.16.8", "@babel/plugin-transform-async-to-generator@^7.16.8": + version "7.16.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.16.8.tgz#b83dff4b970cf41f1b819f8b49cc0cfbaa53a808" + integrity sha512-MtmUmTJQHCnyJVrScNzNlofQJ3dLFuobYn3mwOTKHnSCMtbNsqvF71GQmJfFjdrXSsAA7iysFmYWw4bXZ20hOg== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-remap-async-to-generator" "^7.16.8" -"@babel/plugin-transform-classes@^7.14.5": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.15.4.tgz#50aee17aaf7f332ae44e3bce4c2e10534d5d3bf1" - integrity sha512-Yjvhex8GzBmmPQUvpXRPWQ9WnxXgAFuZSrqOK/eJlOGIXwvv8H3UEdUigl1gb/bnjTrln+e8bkZUYCBt/xYlBg== +"@babel/plugin-transform-async-to-generator@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.18.6.tgz#ccda3d1ab9d5ced5265fdb13f1882d5476c71615" + integrity sha512-ARE5wZLKnTgPW7/1ftQmSi1CmkqqHo2DNmtztFhvgtOWSDfq0Cq9/9L+KnZNYSNrydBekhW3rwShduf59RoXag== dependencies: - "@babel/helper-annotate-as-pure" "^7.15.4" - "@babel/helper-function-name" "^7.15.4" - "@babel/helper-optimise-call-expression" "^7.15.4" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-replace-supers" "^7.15.4" - "@babel/helper-split-export-declaration" "^7.15.4" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-remap-async-to-generator" "^7.18.6" + +"@babel/plugin-transform-block-scoped-functions@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.16.7.tgz#4d0d57d9632ef6062cdf354bb717102ee042a620" + integrity sha512-JUuzlzmF40Z9cXyytcbZEZKckgrQzChbQJw/5PuEHYeqzCsvebDx0K0jWnIIVcmmDOAVctCgnYs0pMcrYj2zJg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-block-scoped-functions@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.18.6.tgz#9187bf4ba302635b9d70d986ad70f038726216a8" + integrity sha512-ExUcOqpPWnliRcPqves5HJcJOvHvIIWfuS4sroBUenPuMdmW+SMHDakmtS7qOo13sVppmUijqeTv7qqGsvURpQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-block-scoping@^7.12.12", "@babel/plugin-transform-block-scoping@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.18.9.tgz#f9b7e018ac3f373c81452d6ada8bd5a18928926d" + integrity sha512-5sDIJRV1KtQVEbt/EIBwGy4T01uYIo4KRB3VUqzkhrAIOGx7AoctL9+Ux88btY0zXdDyPJ9mW+bg+v+XEkGmtw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-block-scoping@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.7.tgz#f50664ab99ddeaee5bc681b8f3a6ea9d72ab4f87" + integrity sha512-ObZev2nxVAYA4bhyusELdo9hb3H+A56bxH3FZMbEImZFiEDYVHXQSJ1hQKFlDnlt8G9bBrCZ5ZpURZUrV4G5qQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-classes@^7.12.1", "@babel/plugin-transform-classes@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.18.9.tgz#90818efc5b9746879b869d5ce83eb2aa48bbc3da" + integrity sha512-EkRQxsxoytpTlKJmSPYrsOMjCILacAjtSVkd4gChEe2kXjFCun3yohhW5I7plXJhCemM0gKsaGMcO8tinvCA5g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-replace-supers" "^7.18.9" + "@babel/helper-split-export-declaration" "^7.18.6" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.14.5.tgz#1b9d78987420d11223d41195461cc43b974b204f" - integrity sha512-pWM+E4283UxaVzLb8UBXv4EIxMovU4zxT1OPnpHJcmnvyY9QbPPTKZfEj31EUvG3/EQRbYAGaYEUZ4yWOBC2xg== +"@babel/plugin-transform-classes@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.16.7.tgz#8f4b9562850cd973de3b498f1218796eb181ce00" + integrity sha512-WY7og38SFAGYRe64BrjKf8OrE6ulEHtr5jEYaZMwox9KebgqPi67Zqz8K53EKk1fFEJgm96r32rkKZ3qA2nCWQ== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-annotate-as-pure" "^7.16.7" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-optimise-call-expression" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + globals "^11.1.0" -"@babel/plugin-transform-destructuring@^7.14.7": - version "7.14.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.14.7.tgz#0ad58ed37e23e22084d109f185260835e5557576" - integrity sha512-0mDE99nK+kVh3xlc5vKwB6wnP9ecuSj+zQCa/n0voENtP/zymdT4HH6QEb65wjjcbqr1Jb/7z9Qp7TF5FtwYGw== +"@babel/plugin-transform-computed-properties@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.16.7.tgz#66dee12e46f61d2aae7a73710f591eb3df616470" + integrity sha512-gN72G9bcmenVILj//sv1zLNaPyYcOzUho2lIJBMh/iakJ9ygCo/hEF9cpGb61SCMEDxbbyBoVQxrt+bWKu5KGw== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-dotall-regex@^7.14.5", "@babel/plugin-transform-dotall-regex@^7.4.4": +"@babel/plugin-transform-computed-properties@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.18.9.tgz#2357a8224d402dad623caf6259b611e56aec746e" + integrity sha512-+i0ZU1bCDymKakLxn5srGHrsAPRELC2WIbzwjLhHW9SIE1cPYkLCL0NlnXMZaM1vhfgA2+M7hySk42VBvrkBRw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-destructuring@^7.12.1", "@babel/plugin-transform-destructuring@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.9.tgz#68906549c021cb231bee1db21d3b5b095f8ee292" + integrity sha512-p5VCYNddPLkZTq4XymQIaIfZNJwT9YsjkPOhkVEqt6QIpQFZVM9IltqqYpOEkJoN1DPznmxUDyZ5CTZs/ZCuHA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-destructuring@^7.17.7": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.18.0.tgz#dc4f92587e291b4daa78aa20cc2d7a63aa11e858" + integrity sha512-Mo69klS79z6KEfrLg/1WkmVnB8javh75HX4pi2btjvlIoasuxilEyjtsQW6XPrubNd7AQy0MMaNIaQE4e7+PQw== + dependencies: + "@babel/helper-plugin-utils" "^7.17.12" + +"@babel/plugin-transform-dotall-regex@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.16.7.tgz#6b2d67686fab15fb6a7fd4bd895d5982cfc81241" + integrity sha512-Lyttaao2SjZF6Pf4vk1dVKv8YypMpomAbygW+mU5cYP3S5cWTfCJjG8xV6CFdzGFlfWK81IjL9viiTvpb6G7gQ== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-dotall-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.18.6.tgz#b286b3e7aae6c7b861e45bed0a2fafd6b1a4fef8" + integrity sha512-6S3jpun1eEbAxq7TdjLotAsl4WpQI9DxfkycRcKrjhQYzU87qpXdknpBg/e+TdcMehqGnLFi7tnFUBR02Vq6wg== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-dotall-regex@^7.4.4": version "7.14.5" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.14.5.tgz#2f6bf76e46bdf8043b4e7e16cf24532629ba0c7a" integrity sha512-loGlnBdj02MDsFaHhAIJzh7euK89lBrGIdM9EAtHFo6xKygCUGuuWe07o1oZVk287amtW1n0808sQM99aZt3gw== @@ -930,226 +1767,465 @@ "@babel/helper-create-regexp-features-plugin" "^7.14.5" "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-duplicate-keys@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.14.5.tgz#365a4844881bdf1501e3a9f0270e7f0f91177954" - integrity sha512-iJjbI53huKbPDAsJ8EmVmvCKeeq21bAze4fu9GBQtSLqfvzj2oRuHVx4ZkDwEhg1htQ+5OBZh/Ab0XDf5iBZ7A== +"@babel/plugin-transform-duplicate-keys@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.16.7.tgz#2207e9ca8f82a0d36a5a67b6536e7ef8b08823c9" + integrity sha512-03DvpbRfvWIXyK0/6QiR1KMTWeT6OcQ7tbhjrXyFS02kjuX/mu5Bvnh5SDSWHxyawit2g5aWhKwI86EE7GUnTw== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-exponentiation-operator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.14.5.tgz#5154b8dd6a3dfe6d90923d61724bd3deeb90b493" - integrity sha512-jFazJhMBc9D27o9jDnIE5ZErI0R0m7PbKXVq77FFvqFbzvTMuv8jaAwLZ5PviOLSFttqKIW0/wxNSDbjLk0tYA== +"@babel/plugin-transform-duplicate-keys@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.18.9.tgz#687f15ee3cdad6d85191eb2a372c4528eaa0ae0e" + integrity sha512-d2bmXCtZXYc59/0SanQKbiWINadaJXqtvIQIzd4+hNwkWBgyCd5F/2t1kXoUdvPMrxzPvhK6EMQRROxsue+mfw== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-for-of@^7.14.5": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.15.4.tgz#25c62cce2718cfb29715f416e75d5263fb36a8c2" - integrity sha512-DRTY9fA751AFBDh2oxydvVm4SYevs5ILTWLs6xKXps4Re/KG5nfUkr+TdHCrRWB8C69TlzVgA9b3RmGWmgN9LA== +"@babel/plugin-transform-exponentiation-operator@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.16.7.tgz#efa9862ef97e9e9e5f653f6ddc7b665e8536fe9b" + integrity sha512-8UYLSlyLgRixQvlYH3J2ekXFHDFLQutdy7FfFAMm3CPZ6q9wHCwnUyiXpQCe3gVVnQlHc5nsuiEVziteRNTXEA== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-function-name@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.14.5.tgz#e81c65ecb900746d7f31802f6bed1f52d915d6f2" - integrity sha512-vbO6kv0fIzZ1GpmGQuvbwwm+O4Cbm2NrPzwlup9+/3fdkuzo1YqOZcXw26+YUJB84Ja7j9yURWposEHLYwxUfQ== +"@babel/plugin-transform-exponentiation-operator@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.18.6.tgz#421c705f4521888c65e91fdd1af951bfefd4dacd" + integrity sha512-wzEtc0+2c88FVR34aQmiz56dxEkxr2g8DQb/KfaFa1JYXOFVsbhvAonFN6PwVWj++fKmku8NP80plJ5Et4wqHw== dependencies: - "@babel/helper-function-name" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-literals@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.14.5.tgz#41d06c7ff5d4d09e3cf4587bd3ecf3930c730f78" - integrity sha512-ql33+epql2F49bi8aHXxvLURHkxJbSmMKl9J5yHqg4PLtdE6Uc48CH1GS6TQvZ86eoB/ApZXwm7jlA+B3kra7A== +"@babel/plugin-transform-for-of@^7.12.1", "@babel/plugin-transform-for-of@^7.18.8": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.18.8.tgz#6ef8a50b244eb6a0bdbad0c7c61877e4e30097c1" + integrity sha512-yEfTRnjuskWYo0k1mHUqrVWaZwrdq8AYbfrpqULOJOaucGSp4mNMVps+YtA8byoevxS/urwU75vyhQIxcCgiBQ== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-member-expression-literals@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.14.5.tgz#b39cd5212a2bf235a617d320ec2b48bcc091b8a7" - integrity sha512-WkNXxH1VXVTKarWFqmso83xl+2V3Eo28YY5utIkbsmXoItO8Q3aZxN4BTS2k0hz9dGUloHK26mJMyQEYfkn/+Q== +"@babel/plugin-transform-for-of@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.16.7.tgz#649d639d4617dff502a9a158c479b3b556728d8c" + integrity sha512-/QZm9W92Ptpw7sjI9Nx1mbcsWz33+l8kuMIQnDwgQBG5s3fAfQvkRjQ7NqXhtNcKOnPkdICmUHyCaWW06HCsqg== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-modules-amd@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.14.5.tgz#4fd9ce7e3411cb8b83848480b7041d83004858f7" - integrity sha512-3lpOU8Vxmp3roC4vzFpSdEpGUWSMsHFreTWOMMLzel2gNGfHE5UWIh/LN6ghHs2xurUp4jRFYMUIZhuFbody1g== +"@babel/plugin-transform-function-name@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.16.7.tgz#5ab34375c64d61d083d7d2f05c38d90b97ec65cf" + integrity sha512-SU/C68YVwTRxqWj5kgsbKINakGag0KTgq9f2iZEXdStoAbOzLHEBRYzImmA6yFo8YZhJVflvXmIHUO7GWHmxxA== dependencies: - "@babel/helper-module-transforms" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-compilation-targets" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-function-name@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.18.9.tgz#cc354f8234e62968946c61a46d6365440fc764e0" + integrity sha512-WvIBoRPaJQ5yVHzcnJFor7oS5Ls0PYixlTYE63lCj2RtdQEl15M68FXQlxnG6wdraJIXRdR7KI+hQ7q/9QjrCQ== + dependencies: + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-literals@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.16.7.tgz#254c9618c5ff749e87cb0c0cef1a0a050c0bdab1" + integrity sha512-6tH8RTpTWI0s2sV6uq3e/C9wPo4PTqqZps4uF0kzQ9/xPLFQtipynvmT1g/dOfEJ+0EQsHhkQ/zyRId8J2b8zQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-literals@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.18.9.tgz#72796fdbef80e56fba3c6a699d54f0de557444bc" + integrity sha512-IFQDSRoTPnrAIrI5zoZv73IFeZu2dhu6irxQjY9rNjTT53VmKg9fenjvoiOWOkJ6mm4jKVPtdMzBY98Fp4Z4cg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-member-expression-literals@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.16.7.tgz#6e5dcf906ef8a098e630149d14c867dd28f92384" + integrity sha512-mBruRMbktKQwbxaJof32LT9KLy2f3gH+27a5XSuXo6h7R3vqltl0PgZ80C8ZMKw98Bf8bqt6BEVi3svOh2PzMw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-member-expression-literals@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.18.6.tgz#ac9fdc1a118620ac49b7e7a5d2dc177a1bfee88e" + integrity sha512-qSF1ihLGO3q+/g48k85tUjD033C29TNTVB2paCwZPVmOsjn9pClvYYrM2VeJpBY2bcNkuny0YUyTNRyRxJ54KA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-modules-amd@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.16.7.tgz#b28d323016a7daaae8609781d1f8c9da42b13186" + integrity sha512-KaaEtgBL7FKYwjJ/teH63oAmE3lP34N3kshz8mm4VMAw7U3PxjVwwUmxEFksbgsNUaO3wId9R2AVQYSEGRa2+g== + dependencies: + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-commonjs@^7.14.5": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.15.4.tgz#8201101240eabb5a76c08ef61b2954f767b6b4c1" - integrity sha512-qg4DPhwG8hKp4BbVDvX1s8cohM8a6Bvptu4l6Iingq5rW+yRUAhe/YRup/YcW2zCOlrysEWVhftIcKzrEZv3sA== +"@babel/plugin-transform-modules-amd@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.18.6.tgz#8c91f8c5115d2202f277549848874027d7172d21" + integrity sha512-Pra5aXsmTsOnjM3IajS8rTaLCy++nGM4v3YR4esk5PCsyg9z8NA5oQLwxzMUtDBd8F+UmVza3VxoAaWCbzH1rg== dependencies: - "@babel/helper-module-transforms" "^7.15.4" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-simple-access" "^7.15.4" + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.14.5": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.15.4.tgz#b42890c7349a78c827719f1d2d0cd38c7d268132" - integrity sha512-fJUnlQrl/mezMneR72CKCgtOoahqGJNVKpompKwzv3BrEXdlPspTcyxrZ1XmDTIr9PpULrgEQo3qNKp6dW7ssw== +"@babel/plugin-transform-modules-commonjs@^7.17.9": + version "7.18.2" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.2.tgz#1aa8efa2e2a6e818b6a7f2235fceaf09bdb31e9e" + integrity sha512-f5A865gFPAJAEE0K7F/+nm5CmAE3y8AWlMBG9unu5j9+tk50UQVK0QS8RNxSp7MJf0wh97uYyLWt3Zvu71zyOQ== dependencies: - "@babel/helper-hoist-variables" "^7.15.4" - "@babel/helper-module-transforms" "^7.15.4" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-validator-identifier" "^7.14.9" + "@babel/helper-module-transforms" "^7.18.0" + "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-simple-access" "^7.18.2" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-umd@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.14.5.tgz#fb662dfee697cce274a7cda525190a79096aa6e0" - integrity sha512-RfPGoagSngC06LsGUYyM9QWSXZ8MysEjDJTAea1lqRjNECE3y0qIJF/qbvJxc4oA4s99HumIMdXOrd+TdKaAAA== +"@babel/plugin-transform-modules-commonjs@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.18.6.tgz#afd243afba166cca69892e24a8fd8c9f2ca87883" + integrity sha512-Qfv2ZOWikpvmedXQJDSbxNqy7Xr/j2Y8/KfijM0iJyKkBTmWuvCA1yeH1yDM7NJhBW/2aXxeucLj6i80/LAJ/Q== dependencies: - "@babel/helper-module-transforms" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-simple-access" "^7.18.6" + babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-named-capturing-groups-regex@^7.14.7": - version "7.14.9" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.14.9.tgz#c68f5c5d12d2ebaba3762e57c2c4f6347a46e7b2" - integrity sha512-l666wCVYO75mlAtGFfyFwnWmIXQm3kSH0C3IRnJqWcZbWkoihyAdDhFm2ZWaxWTqvBvhVFfJjMRQ0ez4oN1yYA== +"@babel/plugin-transform-modules-systemjs@^7.17.8": + version "7.18.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.4.tgz#3d6fd9868c735cce8f38d6ae3a407fb7e61e6d46" + integrity sha512-lH2UaQaHVOAeYrUUuZ8i38o76J/FnO8vu21OE+tD1MyP9lxdZoSfz+pDbWkq46GogUrdrMz3tiz/FYGB+bVThg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.14.5" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-module-transforms" "^7.18.0" + "@babel/helper-plugin-utils" "^7.17.12" + "@babel/helper-validator-identifier" "^7.16.7" + babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-new-target@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.14.5.tgz#31bdae8b925dc84076ebfcd2a9940143aed7dbf8" - integrity sha512-Nx054zovz6IIRWEB49RDRuXGI4Gy0GMgqG0cII9L3MxqgXz/+rgII+RU58qpo4g7tNEx1jG7rRVH4ihZoP4esQ== +"@babel/plugin-transform-modules-systemjs@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.18.9.tgz#545df284a7ac6a05125e3e405e536c5853099a06" + integrity sha512-zY/VSIbbqtoRoJKo2cDTewL364jSlZGvn0LKOf9ntbfxOvjfmyrdtEEOAdswOswhZEb8UH3jDkCKHd1sPgsS0A== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-module-transforms" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-validator-identifier" "^7.18.6" + babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-object-super@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.14.5.tgz#d0b5faeac9e98597a161a9cf78c527ed934cdc45" - integrity sha512-MKfOBWzK0pZIrav9z/hkRqIk/2bTv9qvxHzPQc12RcVkMOzpIKnFCNYJip00ssKWYkd8Sf5g0Wr7pqJ+cmtuFg== +"@babel/plugin-transform-modules-umd@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.16.7.tgz#23dad479fa585283dbd22215bff12719171e7618" + integrity sha512-EMh7uolsC8O4xhudF2F6wedbSHm1HHZ0C6aJ7K67zcDNidMzVcxWdGr+htW9n21klm+bOn+Rx4CBsAntZd3rEQ== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-replace-supers" "^7.14.5" + "@babel/helper-module-transforms" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-parameters@^7.14.5", "@babel/plugin-transform-parameters@^7.15.4": - version "7.15.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.15.4.tgz#5f2285cc3160bf48c8502432716b48504d29ed62" - integrity sha512-9WB/GUTO6lvJU3XQsSr6J/WKvBC2hcs4Pew8YxZagi6GkTdniyqp8On5kqdK8MN0LMeu0mGbhPN+O049NV/9FQ== +"@babel/plugin-transform-modules-umd@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.18.6.tgz#81d3832d6034b75b54e62821ba58f28ed0aab4b9" + integrity sha512-dcegErExVeXcRqNtkRU/z8WlBLnvD4MRnHgNs3MytRO1Mn1sHRyhbcpYbVMGclAqOjdW+9cfkdZno9dFdfKLfQ== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-module-transforms" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-property-literals@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.14.5.tgz#0ddbaa1f83db3606f1cdf4846fa1dfb473458b34" - integrity sha512-r1uilDthkgXW8Z1vJz2dKYLV1tuw2xsbrp3MrZmD99Wh9vsfKoob+JTgri5VUb/JqyKRXotlOtwgu4stIYCmnw== +"@babel/plugin-transform-named-capturing-groups-regex@^7.17.10": + version "7.17.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.17.12.tgz#9c4a5a5966e0434d515f2675c227fd8cc8606931" + integrity sha512-vWoWFM5CKaTeHrdUJ/3SIOTRV+MBVGybOC9mhJkaprGNt5demMymDW24yC74avb915/mIRe3TgNb/d8idvnCRA== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-create-regexp-features-plugin" "^7.17.12" + "@babel/helper-plugin-utils" "^7.17.12" -"@babel/plugin-transform-regenerator@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.14.5.tgz#9676fd5707ed28f522727c5b3c0aa8544440b04f" - integrity sha512-NVIY1W3ITDP5xQl50NgTKlZ0GrotKtLna08/uGY6ErQt6VEQZXla86x/CTddm5gZdcr+5GSsvMeTmWA5Ii6pkg== +"@babel/plugin-transform-named-capturing-groups-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.18.6.tgz#c89bfbc7cc6805d692f3a49bc5fc1b630007246d" + integrity sha512-UmEOGF8XgaIqD74bC8g7iV3RYj8lMf0Bw7NJzvnS9qQhM4mg+1WHKotUIdjxgD2RGrgFLZZPCFPFj3P/kVDYhg== dependencies: - regenerator-transform "^0.14.2" + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-reserved-words@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.14.5.tgz#c44589b661cfdbef8d4300dcc7469dffa92f8304" - integrity sha512-cv4F2rv1nD4qdexOGsRQXJrOcyb5CrgjUH9PKrrtyhSDBNWGxd0UIitjyJiWagS+EbUGjG++22mGH1Pub8D6Vg== +"@babel/plugin-transform-new-target@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.16.7.tgz#9967d89a5c243818e0800fdad89db22c5f514244" + integrity sha512-xiLDzWNMfKoGOpc6t3U+etCE2yRnn3SM09BXqWPIZOBpL2gvVrBWUKnsJx0K/ADi5F5YC5f8APFfWrz25TdlGg== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-runtime@7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.14.5.tgz#30491dad49c6059f8f8fa5ee8896a0089e987523" - integrity sha512-fPMBhh1AV8ZyneiCIA+wYYUH1arzlXR1UMcApjvchDhfKxhy2r2lReJv8uHEyihi4IFIGlr1Pdx7S5fkESDQsg== +"@babel/plugin-transform-new-target@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.18.6.tgz#d128f376ae200477f37c4ddfcc722a8a1b3246a8" + integrity sha512-DjwFA/9Iu3Z+vrAn+8pBUGcjhxKguSMlsFqeCKbhb9BAV756v0krzVK04CRDi/4aqmk8BsHb4a/gFcaA5joXRw== dependencies: - "@babel/helper-module-imports" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - babel-plugin-polyfill-corejs2 "^0.2.2" - babel-plugin-polyfill-corejs3 "^0.2.2" - babel-plugin-polyfill-regenerator "^0.2.2" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-object-super@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.16.7.tgz#ac359cf8d32cf4354d27a46867999490b6c32a94" + integrity sha512-14J1feiQVWaGvRxj2WjyMuXS2jsBkgB3MdSN5HuC2G5nRspa5RK9COcs82Pwy5BuGcjb+fYaUj94mYcOj7rCvw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-replace-supers" "^7.16.7" + +"@babel/plugin-transform-object-super@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.18.6.tgz#fb3c6ccdd15939b6ff7939944b51971ddc35912c" + integrity sha512-uvGz6zk+pZoS1aTZrOvrbj6Pp/kK2mp45t2B+bTDre2UgsZZ8EZLSJtUg7m/no0zOJUWgFONpB7Zv9W2tSaFlA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-replace-supers" "^7.18.6" + +"@babel/plugin-transform-parameters@^7.12.1", "@babel/plugin-transform-parameters@^7.18.8": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.18.8.tgz#ee9f1a0ce6d78af58d0956a9378ea3427cccb48a" + integrity sha512-ivfbE3X2Ss+Fj8nnXvKJS6sjRG4gzwPMsP+taZC+ZzEGjAYlvENixmt1sZ5Ca6tWls+BlKSGKPJ6OOXvXCbkFg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-parameters@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.16.7.tgz#a1721f55b99b736511cb7e0152f61f17688f331f" + integrity sha512-AT3MufQ7zZEhU2hwOA11axBnExW0Lszu4RL/tAlUJBuNoRak+wehQW8h6KcXOcgjY42fHtDxswuMhMjFEuv/aw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-parameters@^7.17.12": + version "7.17.12" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.17.12.tgz#eb467cd9586ff5ff115a9880d6fdbd4a846b7766" + integrity sha512-6qW4rWo1cyCdq1FkYri7AHpauchbGLXpdwnYsfxFb+KtddHENfsY5JZb35xUwkK5opOLcJ3BNd2l7PhRYGlwIA== + dependencies: + "@babel/helper-plugin-utils" "^7.17.12" + +"@babel/plugin-transform-property-literals@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.16.7.tgz#2dadac85155436f22c696c4827730e0fe1057a55" + integrity sha512-z4FGr9NMGdoIl1RqavCqGG+ZuYjfZ/hkCIeuH6Do7tXmSm0ls11nYVSJqFEUOSJbDab5wC6lRE/w6YjVcr6Hqw== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-property-literals@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.18.6.tgz#e22498903a483448e94e032e9bbb9c5ccbfc93a3" + integrity sha512-cYcs6qlgafTud3PAzrrRNbQtfpQ8+y/+M5tKmksS9+M1ckbH6kzY8MrexEM9mcA6JDsukE19iIRvAyYl463sMg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-react-display-name@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.18.6.tgz#8b1125f919ef36ebdfff061d664e266c666b9415" + integrity sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-react-jsx-development@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.18.6.tgz#dbe5c972811e49c7405b630e4d0d2e1380c0ddc5" + integrity sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.18.6" + +"@babel/plugin-transform-react-jsx@^7.12.12", "@babel/plugin-transform-react-jsx@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.18.6.tgz#2721e96d31df96e3b7ad48ff446995d26bc028ff" + integrity sha512-Mz7xMPxoy9kPS/JScj6fJs03TZ/fZ1dJPlMjRAgTaxaS0fUBk8FV/A2rRgfPsVCZqALNwMexD+0Uaf5zlcKPpw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-jsx" "^7.18.6" + "@babel/types" "^7.18.6" + +"@babel/plugin-transform-react-pure-annotations@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.18.6.tgz#561af267f19f3e5d59291f9950fd7b9663d0d844" + integrity sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-regenerator@^7.17.9": + version "7.18.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.0.tgz#44274d655eb3f1af3f3a574ba819d3f48caf99d5" + integrity sha512-C8YdRw9uzx25HSIzwA7EM7YP0FhCe5wNvJbZzjVNHHPGVcDJ3Aie+qGYYdS1oVQgn+B3eAIJbWFLrJ4Jipv7nw== + dependencies: + "@babel/helper-plugin-utils" "^7.17.12" + regenerator-transform "^0.15.0" + +"@babel/plugin-transform-regenerator@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.18.6.tgz#585c66cb84d4b4bf72519a34cfce761b8676ca73" + integrity sha512-poqRI2+qiSdeldcz4wTSTXBRryoq3Gc70ye7m7UD5Ww0nE29IXqMl6r7Nd15WBgRd74vloEMlShtH6CKxVzfmQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + regenerator-transform "^0.15.0" + +"@babel/plugin-transform-reserved-words@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.16.7.tgz#1d798e078f7c5958eec952059c460b220a63f586" + integrity sha512-KQzzDnZ9hWQBjwi5lpY5v9shmm6IVG0U9pB18zvMu2i4H90xpT4gmqwPYsn8rObiadYe2M0gmgsiOIF5A/2rtg== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-reserved-words@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.18.6.tgz#b1abd8ebf8edaa5f7fe6bbb8d2133d23b6a6f76a" + integrity sha512-oX/4MyMoypzHjFrT1CdivfKZ+XvIPMFXwwxHp/r0Ddy2Vuomt4HDFGmft1TAY2yiTKiNSsh3kjBAzcM8kSdsjA== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-runtime@7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.17.10.tgz#b89d821c55d61b5e3d3c3d1d636d8d5a81040ae1" + integrity sha512-6jrMilUAJhktTr56kACL8LnWC5hx3Lf27BS0R0DSyW/OoJfb/iTHeE96V3b1dgKG3FSFdd/0culnYWMkjcKCig== + dependencies: + "@babel/helper-module-imports" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + babel-plugin-polyfill-corejs2 "^0.3.0" + babel-plugin-polyfill-corejs3 "^0.5.0" + babel-plugin-polyfill-regenerator "^0.3.0" semver "^6.3.0" -"@babel/plugin-transform-shorthand-properties@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.14.5.tgz#97f13855f1409338d8cadcbaca670ad79e091a58" - integrity sha512-xLucks6T1VmGsTB+GWK5Pl9Jl5+nRXD1uoFdA5TSO6xtiNjtXTjKkmPdFXVLGlK5A2/or/wQMKfmQ2Y0XJfn5g== +"@babel/plugin-transform-shorthand-properties@^7.12.1", "@babel/plugin-transform-shorthand-properties@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.18.6.tgz#6d6df7983d67b195289be24909e3f12a8f664dc9" + integrity sha512-eCLXXJqv8okzg86ywZJbRn19YJHU4XUa55oz2wbHhaQVn/MM+XhukiT7SYqp/7o00dg52Rj51Ny+Ecw4oyoygw== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-spread@^7.14.6": - version "7.15.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.15.8.tgz#79d5aa27f68d700449b2da07691dfa32d2f6d468" - integrity sha512-/daZ8s2tNaRekl9YJa9X4bzjpeRZLt122cpgFnQPLGUe61PH8zMEBmYqKkW5xF5JUEh5buEGXJoQpqBmIbpmEQ== +"@babel/plugin-transform-shorthand-properties@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.16.7.tgz#e8549ae4afcf8382f711794c0c7b6b934c5fbd2a" + integrity sha512-hah2+FEnoRoATdIb05IOXf+4GzXYTq75TVhIn1PewihbpyrNWUt2JbudKQOETWw6QpLe+AIUpJ5MVLYTQbeeUg== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-skip-transparent-expression-wrappers" "^7.15.4" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-sticky-regex@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.14.5.tgz#5b617542675e8b7761294381f3c28c633f40aeb9" - integrity sha512-Z7F7GyvEMzIIbwnziAZmnSNpdijdr4dWt+FJNBnBLz5mwDFkqIXU9wmBcWWad3QeJF5hMTkRe4dAq2sUZiG+8A== +"@babel/plugin-transform-spread@^7.12.1", "@babel/plugin-transform-spread@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.18.9.tgz#6ea7a6297740f381c540ac56caf75b05b74fb664" + integrity sha512-39Q814wyoOPtIB/qGopNIL9xDChOE1pNU0ZY5dO0owhiVt/5kFm4li+/bBtwc7QotG0u5EPzqhZdjMtmqBqyQA== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.18.9" -"@babel/plugin-transform-template-literals@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.14.5.tgz#a5f2bc233937d8453885dc736bdd8d9ffabf3d93" - integrity sha512-22btZeURqiepOfuy/VkFr+zStqlujWaarpMErvay7goJS6BWwdd6BY9zQyDLDa4x2S3VugxFb162IZ4m/S/+Gg== +"@babel/plugin-transform-spread@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.16.7.tgz#a303e2122f9f12e0105daeedd0f30fb197d8ff44" + integrity sha512-+pjJpgAngb53L0iaA5gU/1MLXJIfXcYepLgXB3esVRf4fqmj8f2cxM3/FKaHsZms08hFQJkFccEWuIpm429TXg== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" -"@babel/plugin-transform-typeof-symbol@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.14.5.tgz#39af2739e989a2bd291bf6b53f16981423d457d4" - integrity sha512-lXzLD30ffCWseTbMQzrvDWqljvZlHkXU+CnseMhkMNqU1sASnCsz3tSzAaH3vCUXb9PHeUb90ZT1BdFTm1xxJw== +"@babel/plugin-transform-sticky-regex@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.16.7.tgz#c84741d4f4a38072b9a1e2e3fd56d359552e8660" + integrity sha512-NJa0Bd/87QV5NZZzTuZG5BPJjLYadeSZ9fO6oOUoL4iQx+9EEuw/eEM92SrsT19Yc2jgB1u1hsjqDtH02c3Drw== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" -"@babel/plugin-transform-unicode-escapes@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.14.5.tgz#9d4bd2a681e3c5d7acf4f57fa9e51175d91d0c6b" - integrity sha512-crTo4jATEOjxj7bt9lbYXcBAM3LZaUrbP2uUdxb6WIorLmjNKSpHfIybgY4B8SRpbf8tEVIWH3Vtm7ayCrKocA== +"@babel/plugin-transform-sticky-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.18.6.tgz#c6706eb2b1524028e317720339583ad0f444adcc" + integrity sha512-kfiDrDQ+PBsQDO85yj1icueWMfGfJFKN1KCkndygtu/C9+XUfydLC8Iv5UYJqRwy4zk8EcplRxEOeLyjq1gm6Q== dependencies: - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-unicode-regex@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.14.5.tgz#4cd09b6c8425dd81255c7ceb3fb1836e7414382e" - integrity sha512-UygduJpC5kHeCiRw/xDVzC+wj8VaYSoKl5JNVmbP7MadpNinAm3SvZCxZ42H37KZBKztz46YC73i9yV34d0Tzw== +"@babel/plugin-transform-template-literals@^7.12.1", "@babel/plugin-transform-template-literals@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.18.9.tgz#04ec6f10acdaa81846689d63fae117dd9c243a5e" + integrity sha512-S8cOWfT82gTezpYOiVaGHrCbhlHgKhQt8XH5ES46P2XWmX92yisoZywf5km75wv5sYcXDUCLMmMxOLCtthDgMA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" + "@babel/helper-plugin-utils" "^7.18.9" -"@babel/preset-env@7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.14.8.tgz#254942f5ca80ccabcfbb2a9f524c74bca574005b" - integrity sha512-a9aOppDU93oArQ51H+B8M1vH+tayZbuBqzjOhntGetZVa+4tTu5jp+XTwqHGG2lxslqomPYVSjIxQkFwXzgnxg== +"@babel/plugin-transform-template-literals@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.16.7.tgz#f3d1c45d28967c8e80f53666fc9c3e50618217ab" + integrity sha512-VwbkDDUeenlIjmfNeDX/V0aWrQH2QiVyJtwymVQSzItFDTpxfyJh3EVaQiS0rIN/CqbLGr0VcGmuwyTdZtdIsA== dependencies: - "@babel/compat-data" "^7.14.7" - "@babel/helper-compilation-targets" "^7.14.5" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-validator-option" "^7.14.5" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.14.5" - "@babel/plugin-proposal-async-generator-functions" "^7.14.7" - "@babel/plugin-proposal-class-properties" "^7.14.5" - "@babel/plugin-proposal-class-static-block" "^7.14.5" - "@babel/plugin-proposal-dynamic-import" "^7.14.5" - "@babel/plugin-proposal-export-namespace-from" "^7.14.5" - "@babel/plugin-proposal-json-strings" "^7.14.5" - "@babel/plugin-proposal-logical-assignment-operators" "^7.14.5" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.14.5" - "@babel/plugin-proposal-numeric-separator" "^7.14.5" - "@babel/plugin-proposal-object-rest-spread" "^7.14.7" - "@babel/plugin-proposal-optional-catch-binding" "^7.14.5" - "@babel/plugin-proposal-optional-chaining" "^7.14.5" - "@babel/plugin-proposal-private-methods" "^7.14.5" - "@babel/plugin-proposal-private-property-in-object" "^7.14.5" - "@babel/plugin-proposal-unicode-property-regex" "^7.14.5" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-typeof-symbol@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.16.7.tgz#9cdbe622582c21368bd482b660ba87d5545d4f7e" + integrity sha512-p2rOixCKRJzpg9JB4gjnG4gjWkWa89ZoYUnl9snJ1cWIcTH/hvxZqfO+WjG6T8DRBpctEol5jw1O5rA8gkCokQ== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-typeof-symbol@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.18.9.tgz#c8cea68263e45addcd6afc9091429f80925762c0" + integrity sha512-SRfwTtF11G2aemAZWivL7PD+C9z52v9EvMqH9BuYbabyPuKUvSWks3oCg6041pT925L4zVFqaVBeECwsmlguEw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.9" + +"@babel/plugin-transform-typescript@^7.18.6": + version "7.18.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.18.8.tgz#303feb7a920e650f2213ef37b36bbf327e6fa5a0" + integrity sha512-p2xM8HI83UObjsZGofMV/EdYjamsDm6MoN3hXPYIT0+gxIoopE+B7rPYKAxfrz9K9PK7JafTTjqYC6qipLExYA== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/plugin-syntax-typescript" "^7.18.6" + +"@babel/plugin-transform-unicode-escapes@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.16.7.tgz#da8717de7b3287a2c6d659750c964f302b31ece3" + integrity sha512-TAV5IGahIz3yZ9/Hfv35TV2xEm+kaBDaZQCn2S/hG9/CZ0DktxJv9eKfPc7yYCvOYR4JGx1h8C+jcSOvgaaI/Q== + dependencies: + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-unicode-escapes@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.6.tgz#0d01fb7fb2243ae1c033f65f6e3b4be78db75f27" + integrity sha512-XNRwQUXYMP7VLuy54cr/KS/WeL3AZeORhrmeZ7iewgu+X2eBqmpaLI/hzqr9ZxCeUoq0ASK4GUzSM0BDhZkLFw== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/plugin-transform-unicode-regex@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.16.7.tgz#0f7aa4a501198976e25e82702574c34cfebe9ef2" + integrity sha512-oC5tYYKw56HO75KZVLQ+R/Nl3Hro9kf8iG0hXoaHP7tjAyCpvqBiSNe6vGrZni1Z6MggmUOC6A7VP7AVmw225Q== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.16.7" + "@babel/helper-plugin-utils" "^7.16.7" + +"@babel/plugin-transform-unicode-regex@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.18.6.tgz#194317225d8c201bbae103364ffe9e2cea36cdca" + integrity sha512-gE7A6Lt7YLnNOL3Pb9BNeZvi+d8l7tcRrG4+pwJjK9hD2xX4mEvjlQW60G9EEmfXVYRPv9VRQcyegIVHCql/AA== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.18.6" + "@babel/helper-plugin-utils" "^7.18.6" + +"@babel/preset-env@7.17.10": + version "7.17.10" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.17.10.tgz#a81b093669e3eb6541bb81a23173c5963c5de69c" + integrity sha512-YNgyBHZQpeoBSRBg0xixsZzfT58Ze1iZrajvv0lJc70qDDGuGfonEnMGfWeSY0mQ3JTuCWFbMkzFRVafOyJx4g== + dependencies: + "@babel/compat-data" "^7.17.10" + "@babel/helper-compilation-targets" "^7.17.10" + "@babel/helper-plugin-utils" "^7.16.7" + "@babel/helper-validator-option" "^7.16.7" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.16.7" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.16.7" + "@babel/plugin-proposal-async-generator-functions" "^7.16.8" + "@babel/plugin-proposal-class-properties" "^7.16.7" + "@babel/plugin-proposal-class-static-block" "^7.17.6" + "@babel/plugin-proposal-dynamic-import" "^7.16.7" + "@babel/plugin-proposal-export-namespace-from" "^7.16.7" + "@babel/plugin-proposal-json-strings" "^7.16.7" + "@babel/plugin-proposal-logical-assignment-operators" "^7.16.7" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.7" + "@babel/plugin-proposal-numeric-separator" "^7.16.7" + "@babel/plugin-proposal-object-rest-spread" "^7.17.3" + "@babel/plugin-proposal-optional-catch-binding" "^7.16.7" + "@babel/plugin-proposal-optional-chaining" "^7.16.7" + "@babel/plugin-proposal-private-methods" "^7.16.11" + "@babel/plugin-proposal-private-property-in-object" "^7.16.7" + "@babel/plugin-proposal-unicode-property-regex" "^7.16.7" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" "@babel/plugin-syntax-class-static-block" "^7.14.5" @@ -1164,50 +2240,131 @@ "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.14.5" - "@babel/plugin-transform-async-to-generator" "^7.14.5" - "@babel/plugin-transform-block-scoped-functions" "^7.14.5" - "@babel/plugin-transform-block-scoping" "^7.14.5" - "@babel/plugin-transform-classes" "^7.14.5" - "@babel/plugin-transform-computed-properties" "^7.14.5" - "@babel/plugin-transform-destructuring" "^7.14.7" - "@babel/plugin-transform-dotall-regex" "^7.14.5" - "@babel/plugin-transform-duplicate-keys" "^7.14.5" - "@babel/plugin-transform-exponentiation-operator" "^7.14.5" - "@babel/plugin-transform-for-of" "^7.14.5" - "@babel/plugin-transform-function-name" "^7.14.5" - "@babel/plugin-transform-literals" "^7.14.5" - "@babel/plugin-transform-member-expression-literals" "^7.14.5" - "@babel/plugin-transform-modules-amd" "^7.14.5" - "@babel/plugin-transform-modules-commonjs" "^7.14.5" - "@babel/plugin-transform-modules-systemjs" "^7.14.5" - "@babel/plugin-transform-modules-umd" "^7.14.5" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.14.7" - "@babel/plugin-transform-new-target" "^7.14.5" - "@babel/plugin-transform-object-super" "^7.14.5" - "@babel/plugin-transform-parameters" "^7.14.5" - "@babel/plugin-transform-property-literals" "^7.14.5" - "@babel/plugin-transform-regenerator" "^7.14.5" - "@babel/plugin-transform-reserved-words" "^7.14.5" - "@babel/plugin-transform-shorthand-properties" "^7.14.5" - "@babel/plugin-transform-spread" "^7.14.6" - "@babel/plugin-transform-sticky-regex" "^7.14.5" - "@babel/plugin-transform-template-literals" "^7.14.5" - "@babel/plugin-transform-typeof-symbol" "^7.14.5" - "@babel/plugin-transform-unicode-escapes" "^7.14.5" - "@babel/plugin-transform-unicode-regex" "^7.14.5" - "@babel/preset-modules" "^0.1.4" - "@babel/types" "^7.14.8" - babel-plugin-polyfill-corejs2 "^0.2.2" - babel-plugin-polyfill-corejs3 "^0.2.2" - babel-plugin-polyfill-regenerator "^0.2.2" - core-js-compat "^3.15.0" + "@babel/plugin-transform-arrow-functions" "^7.16.7" + "@babel/plugin-transform-async-to-generator" "^7.16.8" + "@babel/plugin-transform-block-scoped-functions" "^7.16.7" + "@babel/plugin-transform-block-scoping" "^7.16.7" + "@babel/plugin-transform-classes" "^7.16.7" + "@babel/plugin-transform-computed-properties" "^7.16.7" + "@babel/plugin-transform-destructuring" "^7.17.7" + "@babel/plugin-transform-dotall-regex" "^7.16.7" + "@babel/plugin-transform-duplicate-keys" "^7.16.7" + "@babel/plugin-transform-exponentiation-operator" "^7.16.7" + "@babel/plugin-transform-for-of" "^7.16.7" + "@babel/plugin-transform-function-name" "^7.16.7" + "@babel/plugin-transform-literals" "^7.16.7" + "@babel/plugin-transform-member-expression-literals" "^7.16.7" + "@babel/plugin-transform-modules-amd" "^7.16.7" + "@babel/plugin-transform-modules-commonjs" "^7.17.9" + "@babel/plugin-transform-modules-systemjs" "^7.17.8" + "@babel/plugin-transform-modules-umd" "^7.16.7" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.17.10" + "@babel/plugin-transform-new-target" "^7.16.7" + "@babel/plugin-transform-object-super" "^7.16.7" + "@babel/plugin-transform-parameters" "^7.16.7" + "@babel/plugin-transform-property-literals" "^7.16.7" + "@babel/plugin-transform-regenerator" "^7.17.9" + "@babel/plugin-transform-reserved-words" "^7.16.7" + "@babel/plugin-transform-shorthand-properties" "^7.16.7" + "@babel/plugin-transform-spread" "^7.16.7" + "@babel/plugin-transform-sticky-regex" "^7.16.7" + "@babel/plugin-transform-template-literals" "^7.16.7" + "@babel/plugin-transform-typeof-symbol" "^7.16.7" + "@babel/plugin-transform-unicode-escapes" "^7.16.7" + "@babel/plugin-transform-unicode-regex" "^7.16.7" + "@babel/preset-modules" "^0.1.5" + "@babel/types" "^7.17.10" + babel-plugin-polyfill-corejs2 "^0.3.0" + babel-plugin-polyfill-corejs3 "^0.5.0" + babel-plugin-polyfill-regenerator "^0.3.0" + core-js-compat "^3.22.1" semver "^6.3.0" -"@babel/preset-modules@^0.1.4": - version "0.1.4" - resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" - integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== +"@babel/preset-env@^7.12.11", "@babel/preset-env@^7.16.11": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.18.9.tgz#9b3425140d724fbe590322017466580844c7eaff" + integrity sha512-75pt/q95cMIHWssYtyfjVlvI+QEZQThQbKvR9xH+F/Agtw/s4Wfc2V9Bwd/P39VtixB7oWxGdH4GteTTwYJWMg== + dependencies: + "@babel/compat-data" "^7.18.8" + "@babel/helper-compilation-targets" "^7.18.9" + "@babel/helper-plugin-utils" "^7.18.9" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.18.6" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.18.9" + "@babel/plugin-proposal-async-generator-functions" "^7.18.6" + "@babel/plugin-proposal-class-properties" "^7.18.6" + "@babel/plugin-proposal-class-static-block" "^7.18.6" + "@babel/plugin-proposal-dynamic-import" "^7.18.6" + "@babel/plugin-proposal-export-namespace-from" "^7.18.9" + "@babel/plugin-proposal-json-strings" "^7.18.6" + "@babel/plugin-proposal-logical-assignment-operators" "^7.18.9" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.18.6" + "@babel/plugin-proposal-numeric-separator" "^7.18.6" + "@babel/plugin-proposal-object-rest-spread" "^7.18.9" + "@babel/plugin-proposal-optional-catch-binding" "^7.18.6" + "@babel/plugin-proposal-optional-chaining" "^7.18.9" + "@babel/plugin-proposal-private-methods" "^7.18.6" + "@babel/plugin-proposal-private-property-in-object" "^7.18.6" + "@babel/plugin-proposal-unicode-property-regex" "^7.18.6" + "@babel/plugin-syntax-async-generators" "^7.8.4" + "@babel/plugin-syntax-class-properties" "^7.12.13" + "@babel/plugin-syntax-class-static-block" "^7.14.5" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-import-assertions" "^7.18.6" + "@babel/plugin-syntax-json-strings" "^7.8.3" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.3" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" + "@babel/plugin-syntax-optional-chaining" "^7.8.3" + "@babel/plugin-syntax-private-property-in-object" "^7.14.5" + "@babel/plugin-syntax-top-level-await" "^7.14.5" + "@babel/plugin-transform-arrow-functions" "^7.18.6" + "@babel/plugin-transform-async-to-generator" "^7.18.6" + "@babel/plugin-transform-block-scoped-functions" "^7.18.6" + "@babel/plugin-transform-block-scoping" "^7.18.9" + "@babel/plugin-transform-classes" "^7.18.9" + "@babel/plugin-transform-computed-properties" "^7.18.9" + "@babel/plugin-transform-destructuring" "^7.18.9" + "@babel/plugin-transform-dotall-regex" "^7.18.6" + "@babel/plugin-transform-duplicate-keys" "^7.18.9" + "@babel/plugin-transform-exponentiation-operator" "^7.18.6" + "@babel/plugin-transform-for-of" "^7.18.8" + "@babel/plugin-transform-function-name" "^7.18.9" + "@babel/plugin-transform-literals" "^7.18.9" + "@babel/plugin-transform-member-expression-literals" "^7.18.6" + "@babel/plugin-transform-modules-amd" "^7.18.6" + "@babel/plugin-transform-modules-commonjs" "^7.18.6" + "@babel/plugin-transform-modules-systemjs" "^7.18.9" + "@babel/plugin-transform-modules-umd" "^7.18.6" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.18.6" + "@babel/plugin-transform-new-target" "^7.18.6" + "@babel/plugin-transform-object-super" "^7.18.6" + "@babel/plugin-transform-parameters" "^7.18.8" + "@babel/plugin-transform-property-literals" "^7.18.6" + "@babel/plugin-transform-regenerator" "^7.18.6" + "@babel/plugin-transform-reserved-words" "^7.18.6" + "@babel/plugin-transform-shorthand-properties" "^7.18.6" + "@babel/plugin-transform-spread" "^7.18.9" + "@babel/plugin-transform-sticky-regex" "^7.18.6" + "@babel/plugin-transform-template-literals" "^7.18.9" + "@babel/plugin-transform-typeof-symbol" "^7.18.9" + "@babel/plugin-transform-unicode-escapes" "^7.18.6" + "@babel/plugin-transform-unicode-regex" "^7.18.6" + "@babel/preset-modules" "^0.1.5" + "@babel/types" "^7.18.9" + babel-plugin-polyfill-corejs2 "^0.3.1" + babel-plugin-polyfill-corejs3 "^0.5.2" + babel-plugin-polyfill-regenerator "^0.3.1" + core-js-compat "^3.22.1" + semver "^6.3.0" + +"@babel/preset-modules@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.5.tgz#ef939d6e7f268827e1841638dc6ff95515e115d9" + integrity sha512-A57th6YRG7oR3cq/yt/Y84MvGgE0eJG2F1JLhKuyG+jFxEgrd/HAMJatiFtmOiZurz+0DkrvbheCLaV5f2JfjA== dependencies: "@babel/helper-plugin-utils" "^7.0.0" "@babel/plugin-proposal-unicode-property-regex" "^7.4.4" @@ -1215,10 +2372,56 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/runtime@7.14.8": - version "7.14.8" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.8.tgz#7119a56f421018852694290b9f9148097391b446" - integrity sha512-twj3L8Og5SaCRCErB4x4ajbvBIVV77CGeFglHpeg5WC5FF8TZzBWXtTJ4MqaD9QszLYTtr+IsaAL2rEUevb+eg== +"@babel/preset-react@^7.12.10": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.18.6.tgz#979f76d6277048dc19094c217b507f3ad517dd2d" + integrity sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-transform-react-display-name" "^7.18.6" + "@babel/plugin-transform-react-jsx" "^7.18.6" + "@babel/plugin-transform-react-jsx-development" "^7.18.6" + "@babel/plugin-transform-react-pure-annotations" "^7.18.6" + +"@babel/preset-typescript@^7.12.7": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz#ce64be3e63eddc44240c6358daefac17b3186399" + integrity sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ== + dependencies: + "@babel/helper-plugin-utils" "^7.18.6" + "@babel/helper-validator-option" "^7.18.6" + "@babel/plugin-transform-typescript" "^7.18.6" + +"@babel/register@^7.12.1": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.18.9.tgz#1888b24bc28d5cc41c412feb015e9ff6b96e439c" + integrity sha512-ZlbnXDcNYHMR25ITwwNKT88JiaukkdVj/nG7r3wnuXkOTHc60Uy05PwMCPre0hSkY68E6zK3xz+vUJSP2jWmcw== + dependencies: + clone-deep "^4.0.1" + find-cache-dir "^2.0.0" + make-dir "^2.1.0" + pirates "^4.0.5" + source-map-support "^0.5.16" + +"@babel/runtime@7.17.9": + version "7.17.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.9.tgz#d19fbf802d01a8cb6cf053a64e472d42c434ba72" + integrity sha512-lSiBBvodq29uShpWGNbgFdKYNiFDo5/HIYsaCEY9ff4sb10x9jizo2+pRrSyF4jKZCXqgzuqBOQKbUm90gQwJg== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/runtime@7.7.2": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.2.tgz#111a78002a5c25fc8e3361bedc9529c696b85a6a" + integrity sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw== + dependencies: + regenerator-runtime "^0.13.2" + +"@babel/runtime@^7.0.0", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.17.2", "@babel/runtime@^7.17.8", "@babel/runtime@^7.3.1", "@babel/runtime@^7.5.0": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" + integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== dependencies: regenerator-runtime "^0.13.4" @@ -1229,16 +2432,32 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/template@7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.14.5.tgz#a9bc9d8b33354ff6e55a9c60d1109200a68974f4" - integrity sha512-6Z3Po85sfxRGachLULUhOmvAaOo7xCvqGQtxINai2mEGPFm6pQ4z5QInFnUrRpfoSV60BnjyF5F3c+15fxFV1g== +"@babel/runtime@~7.5.4": + version "7.5.5" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.5.5.tgz#74fba56d35efbeca444091c7850ccd494fd2f132" + integrity sha512-28QvEGyQyNkB0/m2B4FU7IEZGK2NUrcMtT6BZEFALTguLk+AUT6ofsHtPk5QyjAdUkpMJ+/Em+quwz4HOt30AQ== dependencies: - "@babel/code-frame" "^7.14.5" - "@babel/parser" "^7.14.5" - "@babel/types" "^7.14.5" + regenerator-runtime "^0.13.2" -"@babel/template@^7.14.5", "@babel/template@^7.15.4", "@babel/template@^7.8.3": +"@babel/template@7.16.7", "@babel/template@^7.16.7": + version "7.16.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.16.7.tgz#8d126c8701fde4d66b264b3eba3d96f07666d155" + integrity sha512-I8j/x8kHUrbYRTUxXrrMbfCa7jxkE7tZre39x3kjr9hvI82cK1FfqLygotcWN5kdPGWcLdWMHpSBavse5tWw3w== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/parser" "^7.16.7" + "@babel/types" "^7.16.7" + +"@babel/template@^7.12.7", "@babel/template@^7.18.6": + version "7.18.6" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.18.6.tgz#1283f4993e00b929d6e2d3c72fdc9168a2977a31" + integrity sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/parser" "^7.18.6" + "@babel/types" "^7.18.6" + +"@babel/template@^7.15.4": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.15.4.tgz#51898d35dcf3faa670c4ee6afcfd517ee139f194" integrity sha512-UgBAfEa1oGuYgDIPM2G+aHa4Nlo9Lh6mGD2bDBGMTbYnc38vulXPuC1MGjYILIEmlwl6Rd+BPR9ee3gm20CBtg== @@ -1247,7 +2466,23 @@ "@babel/parser" "^7.15.4" "@babel/types" "^7.15.4" -"@babel/traverse@^7.13.0", "@babel/traverse@^7.14.8", "@babel/traverse@^7.15.4", "@babel/traverse@^7.8.3": +"@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.9.tgz#deeff3e8f1bad9786874cb2feda7a2d77a904f98" + integrity sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.18.9" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.18.9" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.18.9" + "@babel/types" "^7.18.9" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/traverse@^7.13.0": version "7.15.4" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.15.4.tgz#ff8510367a144bfbff552d9e18e28f3e2889c22d" integrity sha512-W6lQD8l4rUbQR/vYgSuCAE75ADyyQvOpFVsvPPdkhf6lATXAsQIG9YdtOcu8BB1dZ0LKu+Zo3c1wEcbKeuhdlA== @@ -1262,7 +2497,47 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.14.5", "@babel/types@^7.14.8", "@babel/types@^7.15.4", "@babel/types@^7.15.6", "@babel/types@^7.4.4", "@babel/types@^7.8.3", "@babel/types@^7.8.6": +"@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.0", "@babel/traverse@^7.17.3": + version "7.17.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.3.tgz#0ae0f15b27d9a92ba1f2263358ea7c4e7db47b57" + integrity sha512-5irClVky7TxRWIRtxlh2WPUUOLhcPN06AGgaQSB8AEwuyEBgJVuJ5imdHm5zxk8w0QS5T+tDfnDxAlhWjpb7cw== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.17.3" + "@babel/helper-environment-visitor" "^7.16.7" + "@babel/helper-function-name" "^7.16.7" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.17.3" + "@babel/types" "^7.17.0" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/traverse@^7.17.10", "@babel/traverse@^7.17.12", "@babel/traverse@^7.18.0", "@babel/traverse@^7.18.2": + version "7.18.2" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.18.2.tgz#b77a52604b5cc836a9e1e08dca01cba67a12d2e8" + integrity sha512-9eNwoeovJ6KH9zcCNnENY7DMFwTU9JdGCFtqNLfUAqtUHRCOsTOqWoffosP8vKmNYeSBUv3yVJXjfd8ucwOjUA== + dependencies: + "@babel/code-frame" "^7.16.7" + "@babel/generator" "^7.18.2" + "@babel/helper-environment-visitor" "^7.18.2" + "@babel/helper-function-name" "^7.17.9" + "@babel/helper-hoist-variables" "^7.16.7" + "@babel/helper-split-export-declaration" "^7.16.7" + "@babel/parser" "^7.18.0" + "@babel/types" "^7.18.2" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.18.6", "@babel/types@^7.18.9": + version "7.18.9" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.9.tgz#7148d64ba133d8d73a41b3172ac4b83a1452205f" + integrity sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg== + dependencies: + "@babel/helper-validator-identifier" "^7.18.6" + to-fast-properties "^2.0.0" + +"@babel/types@^7.15.4", "@babel/types@^7.15.6", "@babel/types@^7.4.4": version "7.15.6" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.15.6.tgz#99abdc48218b2881c058dd0a7ab05b99c9be758f" integrity sha512-BPU+7QhqNjmWyDO0/vitH/CuhpV8ZmK1wpKva8nuyNF5MJfuRNWMc+hc14+u9xT93kvykMdncrJT19h74uB1Ig== @@ -1270,20 +2545,304 @@ "@babel/helper-validator-identifier" "^7.14.9" to-fast-properties "^2.0.0" -"@csstools/convert-colors@^1.4.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" - integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== +"@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" + integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" -"@discoveryjs/json-ext@0.5.3": - version "0.5.3" - resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.3.tgz#90420f9f9c6d3987f176a19a7d8e764271a2f55d" - integrity sha512-Fxt+AfXgjMoin2maPIYzFZnQjAXjAL0PHscM5pRTtatFqB+vZxAM9tLp2Optnuw3QOQC40jTNeGYFOMvyf7v9g== +"@babel/types@^7.17.10", "@babel/types@^7.17.12", "@babel/types@^7.18.0", "@babel/types@^7.18.2": + version "7.18.4" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.18.4.tgz#27eae9b9fd18e9dccc3f9d6ad051336f307be354" + integrity sha512-ThN1mBcMq5pG/Vm2IcBmPPfyPXbd8S02rS+OBIDENdufvqC7Z/jHPCv9IcP01277aKtDI8g/2XysBN4hA8niiw== + dependencies: + "@babel/helper-validator-identifier" "^7.16.7" + to-fast-properties "^2.0.0" -"@fortawesome/fontawesome-free@^5.15.4": - version "5.15.4" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-5.15.4.tgz#ecda5712b61ac852c760d8b3c79c96adca5554e5" - integrity sha512-eYm8vijH/hpzr/6/1CJ/V/Eb1xQFW2nnUKArb3z+yUWv7HTwj6M7SP957oMjfZjAHU6qpoNc2wQvIxBLWYa/Jg== +"@cnakazawa/watch@^1.0.3": + version "1.0.4" + resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.4.tgz#f864ae85004d0fcab6f50be9141c4da368d1656a" + integrity sha512-v9kIhKwjeZThiWrLmj0y17CWoyddASLj9O2yvbZkbvw/N3rWOYy9zkV66ursAoVr0mV15bL8g0c4QZUE6cdDoQ== + dependencies: + exec-sh "^0.3.2" + minimist "^1.2.0" + +"@colors/colors@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.5.0.tgz#bb504579c1cae923e6576a4f5da43d25f97bdbd9" + integrity sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ== + +"@compodoc/compodoc@^1.1.19": + version "1.1.19" + resolved "https://registry.yarnpkg.com/@compodoc/compodoc/-/compodoc-1.1.19.tgz#69e518937b127857525d7f4603704726d835630e" + integrity sha512-09vdSIgoAXWD1MiLZNhiljLNQ1XzHw/w5shw5IPcUImr/I+1Y52srUL46mEXN8AXo0hbHb5LZcgs70mmrOvY7Q== + dependencies: + "@angular-devkit/schematics" "^13.2.4" + "@babel/core" "^7.17.5" + "@babel/preset-env" "^7.16.11" + "@compodoc/live-server" "^1.2.3" + "@compodoc/ngd-transformer" "^2.1.0" + chalk "4.1.2" + cheerio "^1.0.0-rc.10" + chokidar "^3.5.3" + colors "1.4.0" + commander "^9.0.0" + cosmiconfig "^7.0.1" + decache "^4.6.1" + fancy-log "^2.0.0" + findit2 "^2.2.3" + fs-extra "^10.0.1" + glob "^7.2.0" + handlebars "^4.7.7" + html-entities "^2.3.2" + i18next "^21.6.11" + inside "^1.0.0" + json5 "^2.2.0" + lodash "^4.17.21" + loglevel "^1.8.0" + loglevel-plugin-prefix "^0.8.4" + lunr "^2.3.9" + marked "^4.0.12" + minimist "^1.2.5" + opencollective-postinstall "^2.0.3" + os-name "4.0.1" + pdfjs-dist "^2.12.313" + pdfmake "^0.2.4" + semver "^7.3.5" + traverse "^0.6.6" + ts-morph "^13.0.3" + uuid "^8.3.2" + +"@compodoc/live-server@^1.2.3": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@compodoc/live-server/-/live-server-1.2.3.tgz#2e4b5920091a35e4b821cb99387123e3dfa30a63" + integrity sha512-hDmntVCyjjaxuJzPzBx68orNZ7TW4BtHWMnXlIVn5dqhK7vuFF/11hspO1cMmc+2QTYgqde1TBcb3127S7Zrow== + dependencies: + chokidar "^3.5.2" + colors "1.4.0" + connect "^3.7.0" + cors latest + event-stream "4.0.1" + faye-websocket "0.11.x" + http-auth "4.1.9" + http-auth-connect "^1.0.5" + morgan "^1.10.0" + object-assign latest + open "8.4.0" + proxy-middleware latest + send latest + serve-index "^1.9.1" + +"@compodoc/ngd-core@~2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@compodoc/ngd-core/-/ngd-core-2.1.0.tgz#965c5d34d6331d2608575291afe9498040c69acd" + integrity sha512-nyBH7J7SJJ2AV6OeZhJ02kRtVB7ALnZJKgShjoL9CNmOFEj8AkdhP9qTBIgjaDrbsW5pF4nx32KQL2fT7RFnqw== + dependencies: + ansi-colors "^4.1.1" + fancy-log "^1.3.3" + typescript "^4.0.3" + +"@compodoc/ngd-transformer@^2.1.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@compodoc/ngd-transformer/-/ngd-transformer-2.1.0.tgz#8d335a214d30a139ddc5b74a9127ab924bd10a20" + integrity sha512-Jo4VCMzIUtgIAdRmhHhOoRRE01gCjc5CyrUERRx0VgEzkkCm1Wmu/XHSsQP6tSpCYHBjERghqaDqH5DabkR2oQ== + dependencies: + "@aduh95/viz.js" "^3.1.0" + "@compodoc/ngd-core" "~2.1.0" + dot "^1.1.3" + fs-extra "^9.0.1" + +"@cordobo/qrcode@1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@cordobo/qrcode/-/qrcode-1.5.0.tgz#fe430514bad73413cd9e4bf4bdd4698353d82217" + integrity sha512-aZ5n3MYw10t4v68EGvRGE1DL7iWfAiTUy4MSZRoqjHTRYdjX40sYgJf48NZa6zZeXVuJOEB/1Ni9KzS+C/EC0w== + dependencies: + dijkstrajs "^1.0.1" + encode-utf8 "^1.0.3" + pngjs "^5.0.0" + yargs "^17.3.1" + +"@csstools/postcss-color-function@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-color-function/-/postcss-color-function-1.1.0.tgz#229966327747f58fbe586de35daa139db3ce1e5d" + integrity sha512-5D5ND/mZWcQoSfYnSPsXtuiFxhzmhxt6pcjrFLJyldj+p0ZN2vvRpYNX+lahFTtMhAYOa2WmkdGINr0yP0CvGA== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-font-format-keywords@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-font-format-keywords/-/postcss-font-format-keywords-1.0.0.tgz#7e7df948a83a0dfb7eb150a96e2390ac642356a1" + integrity sha512-oO0cZt8do8FdVBX8INftvIA4lUrKUSCcWUf9IwH9IPWOgKT22oAZFXeHLoDK7nhB2SmkNycp5brxfNMRLIhd6Q== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-hwb-function@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-hwb-function/-/postcss-hwb-function-1.0.1.tgz#5224db711ed09a965f85c80c18144ac1c2702fce" + integrity sha512-AMZwWyHbbNLBsDADWmoXT9A5yl5dsGEBeJSJRUJt8Y9n8Ziu7Wstt4MC8jtPW7xjcLecyfJwtnUTNSmOzcnWeg== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-ic-unit@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-ic-unit/-/postcss-ic-unit-1.0.0.tgz#f484db59fc94f35a21b6d680d23b0ec69b286b7f" + integrity sha512-i4yps1mBp2ijrx7E96RXrQXQQHm6F4ym1TOD0D69/sjDjZvQ22tqiEvaNw7pFZTUO5b9vWRHzbHzP9+UKuw+bA== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-is-pseudo-class@^2.0.2": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@csstools/postcss-is-pseudo-class/-/postcss-is-pseudo-class-2.0.4.tgz#6e8b49b96a7d3346d5316bd773dcff9c983b4183" + integrity sha512-T2Tmr5RIxkCEXxHwMVyValqwv3h5FTJPpmU8Mq/HDV+TY6C9srVaNMiMG/sp0QaxUnVQQrnXsuLU+1g2zrLDcQ== + dependencies: + "@csstools/selector-specificity" "^1.0.0" + postcss-selector-parser "^6.0.10" + +"@csstools/postcss-normalize-display-values@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-normalize-display-values/-/postcss-normalize-display-values-1.0.0.tgz#ce698f688c28517447aedf15a9037987e3d2dc97" + integrity sha512-bX+nx5V8XTJEmGtpWTO6kywdS725t71YSLlxWt78XoHUbELWgoCXeOFymRJmL3SU1TLlKSIi7v52EWqe60vJTQ== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-oklab-function@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-oklab-function/-/postcss-oklab-function-1.1.0.tgz#e9a269487a292e0930760948e923e1d46b638ee6" + integrity sha512-e/Q5HopQzmnQgqimG9v3w2IG4VRABsBq3itOcn4bnm+j4enTgQZ0nWsaH/m9GV2otWGQ0nwccYL5vmLKyvP1ww== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +"@csstools/postcss-progressive-custom-properties@^1.1.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.2.0.tgz#7d53b773de50874c3885918dcb10cac97bf66ed5" + integrity sha512-YLpFPK5OaLIRKZhUfnrZPT9s9cmtqltIOg7W6jPcxmiDpnZ4lk+odfufZttOAgcg6IHWvNLgcITSLpJxIQB/qQ== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-progressive-custom-properties@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-progressive-custom-properties/-/postcss-progressive-custom-properties-1.3.0.tgz#542292558384361776b45c85226b9a3a34f276fa" + integrity sha512-ASA9W1aIy5ygskZYuWams4BzafD12ULvSypmaLJT2jvQ8G0M3I8PRQhC0h7mG0Z3LI05+agZjqSR9+K9yaQQjA== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-stepped-value-functions@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/postcss-stepped-value-functions/-/postcss-stepped-value-functions-1.0.0.tgz#f8ffc05e163ba7bcbefc5fdcaf264ce9fd408c16" + integrity sha512-q8c4bs1GumAiRenmFjASBcWSLKrbzHzWl6C2HcaAxAXIiL2rUlUWbqQZUjwVG5tied0rld19j/Mm90K3qI26vw== + dependencies: + postcss-value-parser "^4.2.0" + +"@csstools/postcss-unset-value@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@csstools/postcss-unset-value/-/postcss-unset-value-1.0.1.tgz#2cc020785db5ec82cc9444afe4cdae2a65445f89" + integrity sha512-f1G1WGDXEU/RN1TWAxBPQgQudtLnLQPyiWdtypkPC+mVYNKFKH/HYXSxH4MVNqwF8M0eDsoiU7HumJHCg/L/jg== + +"@csstools/selector-specificity@1.0.0", "@csstools/selector-specificity@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@csstools/selector-specificity/-/selector-specificity-1.0.0.tgz#91c560df2ed8d9700e4c7ed4ac21a3a322c9d975" + integrity sha512-RkYG5KiGNX0fJ5YoI0f4Wfq2Yo74D25Hru4fxTOioYdQvHBxcrrtTTyT5Ozzh2ejcNrhFy7IEts2WyEY7yi5yw== + +"@design-systems/utils@2.12.0": + version "2.12.0" + resolved "https://registry.yarnpkg.com/@design-systems/utils/-/utils-2.12.0.tgz#955c108be07cb8f01532207cbfea8f848fa760c9" + integrity sha512-Y/d2Zzr+JJfN6u1gbuBUb1ufBuLMJJRZQk+dRmw8GaTpqKx5uf7cGUYGTwN02dIb3I+Tf+cW8jcGBTRiFxdYFg== + dependencies: + "@babel/runtime" "^7.11.2" + clsx "^1.0.4" + focus-lock "^0.8.0" + react-merge-refs "^1.0.0" + +"@devtools-ds/object-inspector@^1.1.2": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@devtools-ds/object-inspector/-/object-inspector-1.2.0.tgz#64a132fbd4159affa5a87c8cf6cf8540c337aed2" + integrity sha512-VztcwqVwScSvYdvJVZBJYsVO/2Pew3JPpFV3T9fuCHQLlHcLYOV3aU/kBS2ScuE2O1JN0ZbobLqFLa3vQF54Fw== + dependencies: + "@babel/runtime" "7.7.2" + "@devtools-ds/object-parser" "^1.2.0" + "@devtools-ds/themes" "^1.2.0" + "@devtools-ds/tree" "^1.2.0" + clsx "1.1.0" + +"@devtools-ds/object-parser@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@devtools-ds/object-parser/-/object-parser-1.2.0.tgz#8da39bf481687afdf113c78dbac5ced6fd8e30d1" + integrity sha512-SjGGyiFFY8dtUpiWXAvRSzRT+hE11EAAysrq2PsC/GVLf2ZLyT2nHlQO5kDStywyTz+fjw7S7pyDRj1HG9YTTA== + dependencies: + "@babel/runtime" "~7.5.4" + +"@devtools-ds/themes@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@devtools-ds/themes/-/themes-1.2.0.tgz#2fda60af9741e97bc09257b512e49a7aecf6f4bc" + integrity sha512-LimEITorE6yWZWWuMc6OiBfLQgPrQqWbyMEmfRUDPa3PHXoAY4SpDxczfg31fgyRDUNWnZhjaJH5bBbu8VEbIw== + dependencies: + "@babel/runtime" "~7.5.4" + "@design-systems/utils" "2.12.0" + clsx "1.1.0" + +"@devtools-ds/tree@^1.2.0": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@devtools-ds/tree/-/tree-1.2.0.tgz#e882d10ae13a30f2aa02e75c3eeb6c44a47a80c3" + integrity sha512-hC4g4ocuo2eg7jsnzKdauxH0sDQiPW3KSM2+uK3kRgcmr9PzpBD5Kob+Y/WFSVKswFleftOGKL4BQLuRv0sPxA== + dependencies: + "@babel/runtime" "7.7.2" + "@devtools-ds/themes" "^1.2.0" + clsx "1.1.0" + +"@discoveryjs/json-ext@0.5.7", "@discoveryjs/json-ext@^0.5.3": + version "0.5.7" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70" + integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw== + +"@foliojs-fork/fontkit@^1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@foliojs-fork/fontkit/-/fontkit-1.9.1.tgz#8124649168eb5273f580f66697a139fb5041296b" + integrity sha512-U589voc2/ROnvx1CyH9aNzOQWJp127JGU1QAylXGQ7LoEAF6hMmahZLQ4eqAcgHUw+uyW4PjtCItq9qudPkK3A== + dependencies: + "@foliojs-fork/restructure" "^2.0.2" + brfs "^2.0.0" + brotli "^1.2.0" + browserify-optional "^1.0.1" + clone "^1.0.4" + deep-equal "^1.0.0" + dfa "^1.2.0" + tiny-inflate "^1.0.2" + unicode-properties "^1.2.2" + unicode-trie "^2.0.0" + +"@foliojs-fork/linebreak@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@foliojs-fork/linebreak/-/linebreak-1.1.1.tgz#93ecd695b7d2bb0334b9481058c3e610e019a4eb" + integrity sha512-pgY/+53GqGQI+mvDiyprvPWgkTlVBS8cxqee03ejm6gKAQNsR1tCYCIvN9FHy7otZajzMqCgPOgC4cHdt4JPig== + dependencies: + base64-js "1.3.1" + brfs "^2.0.2" + unicode-trie "^2.0.0" + +"@foliojs-fork/pdfkit@^0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@foliojs-fork/pdfkit/-/pdfkit-0.13.0.tgz#54f5368d8cf74d8edc81a175ccda1fd9655f2db9" + integrity sha512-YXeG1fml9k97YNC9K8e292Pj2JzGt9uOIiBFuQFxHsdQ45BlxW+JU3RQK6JAvXU7kjhjP8rCcYvpk36JLD33sQ== + dependencies: + "@foliojs-fork/fontkit" "^1.9.1" + "@foliojs-fork/linebreak" "^1.1.1" + crypto-js "^4.0.0" + png-js "^1.0.0" + +"@foliojs-fork/restructure@^2.0.2": + version "2.0.2" + resolved "https://registry.yarnpkg.com/@foliojs-fork/restructure/-/restructure-2.0.2.tgz#73759aba2aff1da87b7c4554e6839c70d43c92b4" + integrity sha512-59SgoZ3EXbkfSX7b63tsou/SDGzwUEK6MuB5sKqgVK1/XE0fxmpsOb9DQI8LXW3KfGnAjImCGhhEb7uPPAUVNA== + +"@fortawesome/fontawesome-free@^6.0.0": + version "6.0.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.0.0.tgz#6f3bd8e42997c7d536a1246877ed8bcd4f005a54" + integrity sha512-6LB4PYBST1Rx40klypw1SmSDArjFOcfBf2LeX9Zg5EKJT2eXiyiJq+CyBYKeXyK0sXS2FsCJWSPr/luyhuvh0Q== "@fullcalendar/core@^4.2.0": version "4.4.2" @@ -1305,64 +2864,237 @@ resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.2.tgz#30aa825f11d438671d585bd44e7fd564535fc210" integrity sha512-82cpyJyKRoQoRi+14ibCeGPu0CwypgtBAdBhq1WfvagpCZNKqwXbKwXllYSMG91DhmG4jt9gN8eP6lGOtozuaw== +"@gar/promisify@^1.1.3": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@gar/promisify/-/promisify-1.1.3.tgz#555193ab2e3bb3b6adc3d551c9c030d9e860daf6" + integrity sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw== + +"@istanbuljs/load-nyc-config@^1.0.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz#fd3db1d59ecf7cf121e80650bb86712f9b55eced" + integrity sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ== + dependencies: + camelcase "^5.3.1" + find-up "^4.1.0" + get-package-type "^0.1.0" + js-yaml "^3.13.1" + resolve-from "^5.0.0" + "@istanbuljs/schema@^0.1.2": version "0.1.3" resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jridgewell/resolve-uri@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-1.0.0.tgz#3fdf5798f0b49e90155896f6291df186eac06c83" - integrity sha512-9oLAnygRMi8Q5QkYEU4XWK04B+nuoXoxjRvRxgjuChkLZFBja0YPSgdZ7dZtwhncLBcQe/I/E+fLuk5qxcYVJA== +"@jest/transform@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" + integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA== + dependencies: + "@babel/core" "^7.1.0" + "@jest/types" "^26.6.2" + babel-plugin-istanbul "^6.0.0" + chalk "^4.0.0" + convert-source-map "^1.4.0" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.2.4" + jest-haste-map "^26.6.2" + jest-regex-util "^26.0.0" + jest-util "^26.6.2" + micromatch "^4.0.2" + pirates "^4.0.1" + slash "^3.0.0" + source-map "^0.6.1" + write-file-atomic "^3.0.0" -"@jsdevtools/coverage-istanbul-loader@3.0.5": +"@jest/types@^26.6.2": + version "26.6.2" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" + integrity sha512-fC6QCp7Sc5sX6g8Tvbmj4XUTbyrik0akgRy03yjXbQaBWWNWGE7SGtJk98m0N8nzegD/7SggrUlivxo5ax4KWQ== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^15.0.0" + chalk "^4.0.0" + +"@jest/types@^27.5.1": + version "27.5.1" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-27.5.1.tgz#3c79ec4a8ba61c170bf937bcf9e98a9df175ec80" + integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + +"@jridgewell/gen-mapping@^0.1.0": + version "0.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" + integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + +"@jridgewell/gen-mapping@^0.3.0": + version "0.3.1" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.1.tgz#cf92a983c83466b8c0ce9124fadeaf09f7c66ea9" + integrity sha512-GcHwniMlA2z+WFPWuY8lp3fsza0I8xPFMWL5+n8LYyP6PSvPrXf4+n8stDHZY2DM0zy9sVkRDy1jDI4XGzYVqg== + dependencies: + "@jridgewell/set-array" "^1.0.0" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/gen-mapping@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9" + integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A== + dependencies: + "@jridgewell/set-array" "^1.0.1" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@jridgewell/trace-mapping" "^0.3.9" + +"@jridgewell/resolve-uri@^3.0.3": version "3.0.5" - resolved "https://registry.yarnpkg.com/@jsdevtools/coverage-istanbul-loader/-/coverage-istanbul-loader-3.0.5.tgz#2a4bc65d0271df8d4435982db4af35d81754ee26" - integrity sha512-EUCPEkaRPvmHjWAAZkWMT7JDzpw7FKB00WTISaiXsbNOd5hCHg77XLA8sLYLFDo1zepYLo2w7GstN8YBqRXZfA== + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.5.tgz#68eb521368db76d040a6315cdb24bf2483037b9c" + integrity sha512-VPeQ7+wH0itvQxnG+lIzWgkysKIr3L9sslimFW55rHMdGu/qCQ5z5h9zq4gI8uBtqkpHhsF4Z/OwExufUCThew== + +"@jridgewell/set-array@^1.0.0": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.1.tgz#36a6acc93987adcf0ba50c66908bd0b70de8afea" + integrity sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ== + +"@jridgewell/set-array@^1.0.1": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72" + integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw== + +"@jridgewell/source-map@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/source-map/-/source-map-0.3.2.tgz#f45351aaed4527a298512ec72f81040c998580fb" + integrity sha512-m7O9o2uR8k2ObDysZYzdfhb08VuEml5oWGiosa1VdaPZ/A6QyPkAJuwN0Q1lhULOf6B7MtQmHENS743hWtCrgw== dependencies: - convert-source-map "^1.7.0" - istanbul-lib-instrument "^4.0.3" - loader-utils "^2.0.0" - merge-source-map "^1.1.0" - schema-utils "^2.7.0" + "@jridgewell/gen-mapping" "^0.3.0" + "@jridgewell/trace-mapping" "^0.3.9" -"@ngtools/webpack@12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-12.2.10.tgz#38d4a5ee9cc39012e9ba2f987f6c1c07b132b19e" - integrity sha512-8ptz2WqEeqFLOMbiYJ6x6XARjzWIrCHzRzpGwvKS28L5iMWeYuvX2EB48uKkMFy/8RJ0SkwyAJkFClPNJvDfrQ== +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.11" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.11.tgz#771a1d8d744eeb71b6adb35808e1a6c7b9b8c8ec" + integrity sha512-Fg32GrJo61m+VqYSdRSjRXMjQ06j8YIYfcTqndLYVAaHmroZHLJZCydsWBOTDqXS2v+mjxohBWEMfg97GXmYQg== -"@ngu/carousel@^3.0.2": - version "3.0.2" - resolved "https://registry.yarnpkg.com/@ngu/carousel/-/carousel-3.0.2.tgz#e0349e32344655a63fce82c580560365a06c09fd" - integrity sha512-EGvCs0LoStIKJoJfQWGeEs1RYHOgxZiSiqi6Thr7F9NVPvJkkwxlSh40uA6AQoWIv6WWhhNr1Imrbp27NZGs6Q== +"@jridgewell/trace-mapping@^0.3.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.4.tgz#f6a0832dffd5b8a6aaa633b7d9f8e8e94c83a0c3" + integrity sha512-vFv9ttIedivx0ux3QSjhgtCVjPZd5l46ZOMDSCwnH1yUO2e964gO8LZGyv2QkqcgR6TnBU1v+1IFqmeoG+0UJQ== dependencies: - tslib "^2.0.0" + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" -"@ngx-translate/core@^13.0.0": - version "13.0.0" - resolved "https://registry.yarnpkg.com/@ngx-translate/core/-/core-13.0.0.tgz#60547cb8a0845a2a0abfde6b0bf5ec6516a63fd6" - integrity sha512-+tzEp8wlqEnw0Gc7jtVRAJ6RteUjXw6JJR4O65KlnxOmJrCGPI0xjV/lKRnQeU0w4i96PQs/jtpL921Wrb7PWg== +"@jridgewell/trace-mapping@^0.3.7": + version "0.3.14" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.14.tgz#b231a081d8f66796e475ad588a1ef473112701ed" + integrity sha512-bJWEfQ9lPTvm3SneWwRFVLzrh6nhjwqw7TUFFBEMzwvg7t7PCDenf2lDwqo4NQXzdpgBXyFgDWnQA+2vkruksQ== dependencies: - tslib "^2.0.0" + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" -"@ngx-translate/http-loader@^6.0.0": - version "6.0.0" - resolved "https://registry.yarnpkg.com/@ngx-translate/http-loader/-/http-loader-6.0.0.tgz#041393ab5753f50ecf64262d624703046b8c7570" - integrity sha512-LCekn6qCbeXWlhESCxU1rAbZz33WzDG0lI7Ig0pYC1o5YxJWrkU9y3Y4tNi+jakQ7R6YhTR2D3ox6APxDtA0wA== +"@jridgewell/trace-mapping@^0.3.9": + version "0.3.13" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.13.tgz#dcfe3e95f224c8fe97a87a5235defec999aa92ea" + integrity sha512-o1xbKhp9qnIAoHJSWd6KlCZfqslL4valSF81H8ImioOAxluWYWOpWkpyktY2vnt4tbrX9XYaxovq6cgowaJp2w== dependencies: - tslib "^2.0.0" + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" -"@ngxs/devtools-plugin@^3.7.2": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@ngxs/devtools-plugin/-/devtools-plugin-3.7.2.tgz#995424e5faf48df55a1b54b9e1b36ce9c47c1d52" - integrity sha512-kRuOx1GPXHHZZAeQMm1J1msTZxjgiAUY4NR7bzaQPn+UwSY2OgGEsd8driMM5YSTF1hOjcFHinaLCM1vmu8FmQ== +"@leichtgewicht/ip-codec@^2.0.1": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz#b2ac626d6cb9c8718ab459166d4bb405b8ffa78b" + integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== + +"@mdx-js/mdx@^1.6.22": + version "1.6.22" + resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba" + integrity sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA== + dependencies: + "@babel/core" "7.12.9" + "@babel/plugin-syntax-jsx" "7.12.1" + "@babel/plugin-syntax-object-rest-spread" "7.8.3" + "@mdx-js/util" "1.6.22" + babel-plugin-apply-mdx-type-prop "1.6.22" + babel-plugin-extract-import-names "1.6.22" + camelcase-css "2.0.1" + detab "2.0.4" + hast-util-raw "6.0.1" + lodash.uniq "4.5.0" + mdast-util-to-hast "10.0.1" + remark-footnotes "2.0.0" + remark-mdx "1.6.22" + remark-parse "8.0.3" + remark-squeeze-paragraphs "4.0.0" + style-to-object "0.3.0" + unified "9.2.0" + unist-builder "2.0.3" + unist-util-visit "2.0.3" + +"@mdx-js/react@^1.6.22": + version "1.6.22" + resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-1.6.22.tgz#ae09b4744fddc74714ee9f9d6f17a66e77c43573" + integrity sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg== + +"@mdx-js/util@1.6.22": + version "1.6.22" + resolved "https://registry.yarnpkg.com/@mdx-js/util/-/util-1.6.22.tgz#219dfd89ae5b97a8801f015323ffa4b62f45718b" + integrity sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA== + +"@microsoft/signalr@^6.0.7": + version "6.0.7" + resolved "https://registry.yarnpkg.com/@microsoft/signalr/-/signalr-6.0.7.tgz#8651d6807a0430575ce51960c254deab8d682b4c" + integrity sha512-CoIz8K0IpaCGbI4rr2W8RHYA8Yq0KqY8DNsJzHw3UEWTJ3KqhWqeVCE8R24czzcsoUrE28xltEQ6qNTXZDHf3g== + dependencies: + abort-controller "^3.0.0" + eventsource "^1.0.7" + fetch-cookie "^0.11.0" + node-fetch "^2.6.7" + ws "^7.4.5" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + integrity sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g== + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@ngtools/webpack@14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@ngtools/webpack/-/webpack-14.0.0.tgz#13a37933f13a8aa587697b7db7be6f1f20a360c1" + integrity sha512-lUcJ5DiRCY+Xj01R38bDbAlELbO+0yT3n4zshBeiuzo/Lc+yQM2XhVe9stsI5I+SwH6YsCU9kp+jb7iaZh7L7w== + +"@ngx-translate/core@^14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@ngx-translate/core/-/core-14.0.0.tgz#af421d0e1a28376843f0fed375cd2fae7630a5ff" + integrity sha512-UevdwNCXMRCdJv//0kC8h2eSfmi02r29xeE8E9gJ1Al4D4jEJ7eiLPdjslTMc21oJNGguqqWeEVjf64SFtvw2w== + dependencies: + tslib "^2.3.0" + +"@ngx-translate/http-loader@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@ngx-translate/http-loader/-/http-loader-7.0.0.tgz#905f38d8d13342621516635bf480ff9a4f73e9fc" + integrity sha512-j+NpXXlcGVdyUNyY/qsJrqqeAdJdizCd+GKh3usXExSqy1aE9866jlAIL+xrfDU4w+LiMoma5pgE4emvFebZmA== + dependencies: + tslib "^2.3.0" + +"@ngxs/devtools-plugin@^3.7.3": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@ngxs/devtools-plugin/-/devtools-plugin-3.7.3.tgz#0f8724ae15aabea4170b00edd632c594de16bd65" + integrity sha512-zkF2OyZKyXW8s/+WZZJgLbWpEguoDAA+EG9qWa/jlysRicYGDVCNZyoxZre4V9BkjwHvY+dQzcDHX4/Ng+Rf5w== dependencies: tslib "^1.9.0" -"@ngxs/store@^3.7.2": - version "3.7.2" - resolved "https://registry.yarnpkg.com/@ngxs/store/-/store-3.7.2.tgz#1088b0669adc382d36ca7ae8438c603e55879b42" - integrity sha512-1cnAjHOGCovfvhjtcAWBajrMXos97Un3c8ekKoS8FIHnq3aQOzY/ePspDRNi9kTcuBJ/r/xl097JC1ssEuNbyg== +"@ngxs/store@^3.7.3": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@ngxs/store/-/store-3.7.3.tgz#74e2878d527fc12dace343ce43fd79fa1a2645af" + integrity sha512-JjATXC7FsxxQu2SaayP/iLe4O+5/RkRov3/J7WkaQmV6/JWFNkkdOwbEa6pDbh/po0JO7DHHMk3huIUNpDu67g== dependencies: tslib "^1.9.0" @@ -1379,6 +3111,11 @@ resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz#5bd262af94e9d25bd1e71b05deed44876a222e8b" integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A== +"@nodelib/fs.stat@^1.1.2": + version "1.1.3" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz#2b5a3ab3f918cca48a8c754c08168e3f03eba61b" + integrity sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw== + "@nodelib/fs.walk@^1.2.3": version "1.2.8" resolved "https://registry.yarnpkg.com/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz#e95737e8bb6746ddedf69c556953494f196fe69a" @@ -1395,21 +3132,30 @@ "@gar/promisify" "^1.0.1" semver "^7.3.5" -"@npmcli/git@^2.1.0": +"@npmcli/fs@^2.1.0": version "2.1.0" - resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-2.1.0.tgz#2fbd77e147530247d37f325930d457b3ebe894f6" - integrity sha512-/hBFX/QG1b+N7PZBFs0bi+evgRZcK9nWBxQKZkGoXUT5hJSwl5c4d7y8/hm+NQZRPhQ67RzFaj5UM9YeyKoryw== + resolved "https://registry.yarnpkg.com/@npmcli/fs/-/fs-2.1.0.tgz#f2a21c28386e299d1a9fae8051d35ad180e33109" + integrity sha512-DmfBvNXGaetMxj9LTp8NAN9vEidXURrf5ZTslQzEAi/6GbW+4yjaLFQc6Tue5cpZ9Frlk4OBo/Snf1Bh/S7qTQ== dependencies: - "@npmcli/promise-spawn" "^1.3.2" - lru-cache "^6.0.0" + "@gar/promisify" "^1.1.3" + semver "^7.3.5" + +"@npmcli/git@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@npmcli/git/-/git-3.0.1.tgz#049b99b1381a2ddf7dc56ba3e91eaf76ca803a8d" + integrity sha512-UU85F/T+F1oVn3IsB/L6k9zXIMpXBuUBE25QDH0SsURwT6IOBqkC7M16uqo2vVZIyji3X1K4XH9luip7YekH1A== + dependencies: + "@npmcli/promise-spawn" "^3.0.0" + lru-cache "^7.4.4" mkdirp "^1.0.4" - npm-pick-manifest "^6.1.1" + npm-pick-manifest "^7.0.0" + proc-log "^2.0.0" promise-inflight "^1.0.1" promise-retry "^2.0.1" semver "^7.3.5" which "^2.0.2" -"@npmcli/installed-package-contents@^1.0.6": +"@npmcli/installed-package-contents@^1.0.7": version "1.0.7" resolved "https://registry.yarnpkg.com/@npmcli/installed-package-contents/-/installed-package-contents-1.0.7.tgz#ab7408c6147911b970a8abe261ce512232a3f4fa" integrity sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw== @@ -1425,56 +3171,1053 @@ mkdirp "^1.0.4" rimraf "^3.0.2" -"@npmcli/node-gyp@^1.0.2": - version "1.0.3" - resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-1.0.3.tgz#a912e637418ffc5f2db375e93b85837691a43a33" - integrity sha512-fnkhw+fmX65kiLqk6E3BFLXNC26rUhK90zVwe2yncPliVT/Qos3xjhTLE59Df8KnPlcwIERXKVlU1bXoUQ+liA== +"@npmcli/move-file@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/move-file/-/move-file-2.0.0.tgz#417f585016081a0184cef3e38902cd917a9bbd02" + integrity sha512-UR6D5f4KEGWJV6BGPH3Qb2EtgH+t+1XQ1Tt85c7qicN6cezzuHPdZwwAxqZr4JLtnQu0LZsTza/5gmNmSl8XLg== + dependencies: + mkdirp "^1.0.4" + rimraf "^3.0.2" -"@npmcli/promise-spawn@^1.2.0", "@npmcli/promise-spawn@^1.3.2": - version "1.3.2" - resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-1.3.2.tgz#42d4e56a8e9274fba180dabc0aea6e38f29274f5" - integrity sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg== +"@npmcli/node-gyp@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/node-gyp/-/node-gyp-2.0.0.tgz#8c20e53e34e9078d18815c1d2dda6f2420d75e35" + integrity sha512-doNI35wIe3bBaEgrlPfdJPaCpUR89pJWep4Hq3aRdh6gKazIVWfs0jHttvSSoq47ZXgC7h73kDsUl8AoIQUB+A== + +"@npmcli/promise-spawn@^3.0.0": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@npmcli/promise-spawn/-/promise-spawn-3.0.0.tgz#53283b5f18f855c6925f23c24e67c911501ef573" + integrity sha512-s9SgS+p3a9Eohe68cSI3fi+hpcZUmXq5P7w0kMlAsWVtR7XbK3ptkZqKT2cK1zLDObJ3sR+8P59sJE0w/KTL1g== dependencies: infer-owner "^1.0.4" -"@npmcli/run-script@^1.8.2": - version "1.8.6" - resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-1.8.6.tgz#18314802a6660b0d4baa4c3afe7f1ad39d8c28b7" - integrity sha512-e42bVZnC6VluBZBAFEr3YrdqSspG3bgilyg4nSLBJ7TRGNCzxHa92XAHxQBLYg0BmgwO4b2mf3h/l5EkEWRn3g== +"@npmcli/run-script@^3.0.1": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@npmcli/run-script/-/run-script-3.0.3.tgz#66afa6e0c4c3484056195f295fa6c1d1a45ddf58" + integrity sha512-ZXL6qgC5NjwfZJ2nET+ZSLEz/PJgJ/5CU90C2S66dZY4Jw73DasS4ZCXuy/KHWYP0imjJ4VtA+Gebb5BxxKp9Q== dependencies: - "@npmcli/node-gyp" "^1.0.2" - "@npmcli/promise-spawn" "^1.3.2" - node-gyp "^7.1.0" - read-package-json-fast "^2.0.1" + "@npmcli/node-gyp" "^2.0.0" + "@npmcli/promise-spawn" "^3.0.0" + node-gyp "^8.4.1" + read-package-json-fast "^2.0.3" -"@scarf/scarf@^1.1.0": - version "1.1.1" - resolved "https://registry.yarnpkg.com/@scarf/scarf/-/scarf-1.1.1.tgz#d8b9f20037b3a37dbf8dcdc4b3b72f9285bfce35" - integrity sha512-VGbKDbk1RFIaSmdVb0cNjjWJoRWRI/Weo23AjRCC2nryO0iAS8pzsToJfPVPtVs74WHw4L1UTADNdIYRLkirZQ== - -"@schematics/angular@12.2.10": - version "12.2.10" - resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-12.2.10.tgz#c640be969ea7588da14ee5c4d58a6a2ce63b97e6" - integrity sha512-hjOWrC/RlZ97oYWO92f5VRu6LDzPHnowDcyGDGvI9wCrfipL4Y7Is6LgFAiVZxCHdRz71MCnES1IXSj5w6UuBA== +"@schematics/angular@14.0.0": + version "14.0.0" + resolved "https://registry.yarnpkg.com/@schematics/angular/-/angular-14.0.0.tgz#de6cb4c86586ed5b06adfd7a759cc9908e627787" + integrity sha512-Or9sFl0kGnB9uUs03/4eRtBS5S9WW+HeSe5rS5kFyMaXdydeshAjAVffAbYB6sDp57Qw0E4LvBC0mHzuZGYp/A== dependencies: - "@angular-devkit/core" "12.2.10" - "@angular-devkit/schematics" "12.2.10" + "@angular-devkit/core" "14.0.0" + "@angular-devkit/schematics" "14.0.0" jsonc-parser "3.0.0" +"@storybook/addon-actions@6.5.9", "@storybook/addon-actions@^6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-6.5.9.tgz#d50d65631403e1a5b680961429d9c0d7bd383e68" + integrity sha512-wDYm3M1bN+zcYZV3Q24M03b/P8DDpvj1oSoY6VLlxDAi56h8qZB/voeIS2I6vWXOB79C5tbwljYNQO0GsufS0g== + dependencies: + "@storybook/addons" "6.5.9" + "@storybook/api" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/components" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/theming" "6.5.9" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.21" + polished "^4.2.2" + prop-types "^15.7.2" + react-inspector "^5.1.0" + regenerator-runtime "^0.13.7" + telejson "^6.0.8" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + uuid-browser "^3.1.0" + +"@storybook/addon-backgrounds@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-6.5.9.tgz#a9579fc9d73f783a768c6c6ceb97193c5a1ee708" + integrity sha512-9k+GiY5aiANLOct34ar29jqgdi5ZpCqpZ86zPH0GsEC6ifH6nzP4trLU0vFUe260XDCvB4g8YaI7JZKPhozERg== + dependencies: + "@storybook/addons" "6.5.9" + "@storybook/api" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/components" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/theming" "6.5.9" + core-js "^3.8.2" + global "^4.4.0" + memoizerific "^1.11.3" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + +"@storybook/addon-controls@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-6.5.9.tgz#8f6ef939c87b3dbad98f8bda7e124f0b34f668d2" + integrity sha512-VvjkgK32bGURKyWU2No6Q2B0RQZjLZk8D3neVNCnrWxwrl1G82StegxjRPn/UZm9+MZVPvTvI46nj1VdgOktnw== + dependencies: + "@storybook/addons" "6.5.9" + "@storybook/api" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/components" "6.5.9" + "@storybook/core-common" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/node-logger" "6.5.9" + "@storybook/store" "6.5.9" + "@storybook/theming" "6.5.9" + core-js "^3.8.2" + lodash "^4.17.21" + ts-dedent "^2.0.0" + +"@storybook/addon-docs@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-6.5.9.tgz#32b27fb298624afd738c1371a764d7ff4831fe6d" + integrity sha512-9lwOZyiOJFUgGd9ADVfcgpels5o0XOXqGMeVLuzT1160nopbZjNjo/3+YLJ0pyHRPpMJ4rmq2+vxRQR6PVRgPg== + dependencies: + "@babel/plugin-transform-react-jsx" "^7.12.12" + "@babel/preset-env" "^7.12.11" + "@jest/transform" "^26.6.2" + "@mdx-js/react" "^1.6.22" + "@storybook/addons" "6.5.9" + "@storybook/api" "6.5.9" + "@storybook/components" "6.5.9" + "@storybook/core-common" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/docs-tools" "6.5.9" + "@storybook/mdx1-csf" "^0.0.1" + "@storybook/node-logger" "6.5.9" + "@storybook/postinstall" "6.5.9" + "@storybook/preview-web" "6.5.9" + "@storybook/source-loader" "6.5.9" + "@storybook/store" "6.5.9" + "@storybook/theming" "6.5.9" + babel-loader "^8.0.0" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.21" + regenerator-runtime "^0.13.7" + remark-external-links "^8.0.0" + remark-slug "^6.0.0" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + +"@storybook/addon-essentials@^6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-6.5.9.tgz#32ba63acba4d153f4cf6ac33cbbf14b87d260788" + integrity sha512-V9ThjKQsde4A2Es20pLFBsn0MWx2KCJuoTcTsANP4JDcbvEmj8UjbDWbs8jAU+yzJT5r+CI6NoWmQudv12ZOgw== + dependencies: + "@storybook/addon-actions" "6.5.9" + "@storybook/addon-backgrounds" "6.5.9" + "@storybook/addon-controls" "6.5.9" + "@storybook/addon-docs" "6.5.9" + "@storybook/addon-measure" "6.5.9" + "@storybook/addon-outline" "6.5.9" + "@storybook/addon-toolbars" "6.5.9" + "@storybook/addon-viewport" "6.5.9" + "@storybook/addons" "6.5.9" + "@storybook/api" "6.5.9" + "@storybook/core-common" "6.5.9" + "@storybook/node-logger" "6.5.9" + core-js "^3.8.2" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + +"@storybook/addon-interactions@^6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-interactions/-/addon-interactions-6.5.9.tgz#4356e96beae8f44000955d8870c3acc6c8d1fb3a" + integrity sha512-p3xBbrhmYTHvRO8MqAIr2DucgrXt38nJE71rogLNLsJ01rUN4JsLI8OkQAMQbqfIpwC27irMjQxJTp4HSzkFJA== + dependencies: + "@devtools-ds/object-inspector" "^1.1.2" + "@storybook/addons" "6.5.9" + "@storybook/api" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/components" "6.5.9" + "@storybook/core-common" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/instrumenter" "6.5.9" + "@storybook/theming" "6.5.9" + core-js "^3.8.2" + global "^4.4.0" + jest-mock "^27.0.6" + polished "^4.2.2" + ts-dedent "^2.2.0" + +"@storybook/addon-links@^6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-links/-/addon-links-6.5.9.tgz#91cbca0c044796badf2498723fdd10dacea5748b" + integrity sha512-4BYC7pkxL3NLRnEgTA9jpIkObQKril+XFj1WtmY/lngF90vvK0Kc/TtvTA2/5tSgrHfxEuPevIdxMIyLJ4ejWQ== + dependencies: + "@storybook/addons" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/router" "6.5.9" + "@types/qs" "^6.9.5" + core-js "^3.8.2" + global "^4.4.0" + prop-types "^15.7.2" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + +"@storybook/addon-measure@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-6.5.9.tgz#f949d4f5f4025c839634114365f1399ea04bd0ae" + integrity sha512-0aA22wD0CIEUccsEbWkckCOXOwr4VffofMH1ToVCOeqBoyLOMB0gxFubESeprqM54CWsYh2DN1uujgD6508cwA== + dependencies: + "@storybook/addons" "6.5.9" + "@storybook/api" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/components" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + core-js "^3.8.2" + global "^4.4.0" + +"@storybook/addon-outline@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-outline/-/addon-outline-6.5.9.tgz#6ce9b3fb77e6a1a59607d7657c359c69f26cf6dd" + integrity sha512-oJ1DK3BDJr6aTlZc9axfOxV1oDkZO7hOohgUQDaKO1RZrSpyQsx2ViK2X6p/W7JhFJHKh7rv+nGCaVlLz3YIZA== + dependencies: + "@storybook/addons" "6.5.9" + "@storybook/api" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/components" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + core-js "^3.8.2" + global "^4.4.0" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + +"@storybook/addon-toolbars@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-6.5.9.tgz#feedfdac08482d43bb1f3cc00840d80322c5eace" + integrity sha512-6JFQNHYVZUwp17p5rppc+iQJ2QOIWPTF+ni1GMMThjc84mzXs2+899Sf1aPFTvrFJTklmT+bPX6x4aUTouVa1w== + dependencies: + "@storybook/addons" "6.5.9" + "@storybook/api" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/components" "6.5.9" + "@storybook/theming" "6.5.9" + core-js "^3.8.2" + regenerator-runtime "^0.13.7" + +"@storybook/addon-viewport@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-6.5.9.tgz#fc390ccebea56d2e874ed2fda085c09fe04dd240" + integrity sha512-thKS+iw6M7ueDQQ7M66STZ5rgtJKliAcIX6UCopo0Ffh4RaRYmX6MCjqtvBKk8joyXUvm9SpWQemJD9uBQrjgw== + dependencies: + "@storybook/addons" "6.5.9" + "@storybook/api" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/components" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/theming" "6.5.9" + core-js "^3.8.2" + global "^4.4.0" + memoizerific "^1.11.3" + prop-types "^15.7.2" + regenerator-runtime "^0.13.7" + +"@storybook/addons@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-6.5.9.tgz#5a9d7395c579a9cbc44dfc122362fb3c95dfb9d5" + integrity sha512-adwdiXg+mntfPocLc1KXjZXyLgGk7Aac699Fwe+OUYPEC5tW347Rm/kFatcE556d42o5czcRiq3ZSIGWnm9ieQ== + dependencies: + "@storybook/api" "6.5.9" + "@storybook/channels" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/router" "6.5.9" + "@storybook/theming" "6.5.9" + "@types/webpack-env" "^1.16.0" + core-js "^3.8.2" + global "^4.4.0" + regenerator-runtime "^0.13.7" + +"@storybook/angular@^6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/angular/-/angular-6.5.9.tgz#daa6843e1a2ba9d46d0cbfb432b0e50d5149bc97" + integrity sha512-V+Kt1qZBNxi6qVB1Uf5/mg9ma97sC8jzb0/w7SkwkcY+/PBSF9UtY9WqOdLVdicukVx0PhkEtVqpYEqhgU9IZw== + dependencies: + "@storybook/addons" "6.5.9" + "@storybook/api" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/core" "6.5.9" + "@storybook/core-common" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/docs-tools" "6.5.9" + "@storybook/node-logger" "6.5.9" + "@storybook/semver" "^7.3.2" + "@storybook/store" "6.5.9" + "@types/node" "^14.14.20 || ^16.0.0" + "@types/react" "^16.14.23" + "@types/react-dom" "^16.9.14" + "@types/webpack-env" "^1.16.0" + autoprefixer "^9.8.6" + core-js "^3.8.2" + find-up "^5.0.0" + fork-ts-checker-webpack-plugin "^4.1.6" + global "^4.4.0" + nanoid "^3.1.23" + p-limit "^3.1.0" + postcss "^7.0.36" + postcss-loader "^4.2.0" + raw-loader "^4.0.2" + react "^16.14.0" + react-dom "^16.14.0" + read-pkg-up "^7.0.1" + regenerator-runtime "^0.13.7" + sass-loader "^10.1.0" + telejson "^6.0.8" + ts-dedent "^2.0.0" + ts-loader "^8.0.14" + tsconfig-paths-webpack-plugin "^3.3.0" + util-deprecate "^1.0.2" + webpack ">=4.0.0 <6.0.0" + +"@storybook/api@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/api/-/api-6.5.9.tgz#303733214c9de0422d162f7c54ae05d088b89bf9" + integrity sha512-9ylztnty4Y+ALU/ehW3BML9czjCAFsWvrwuCi6UgcwNjswwjSX3VRLhfD1KT3pl16ho//95LgZ0LnSwROCcPOA== + dependencies: + "@storybook/channels" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/router" "6.5.9" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.5.9" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.21" + memoizerific "^1.11.3" + regenerator-runtime "^0.13.7" + store2 "^2.12.0" + telejson "^6.0.8" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + +"@storybook/builder-webpack4@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/builder-webpack4/-/builder-webpack4-6.5.9.tgz#4b37e1fa23a25aa4bfeaba640e5d318fcd511f95" + integrity sha512-YOeA4++9uRZ8Hog1wC60yjaxBOiI1FRQNtax7b9E7g+kP8UlSCPCGcv4gls9hFmzbzTOPfQTWnToA9Oa6jzRVw== + dependencies: + "@babel/core" "^7.12.10" + "@storybook/addons" "6.5.9" + "@storybook/api" "6.5.9" + "@storybook/channel-postmessage" "6.5.9" + "@storybook/channels" "6.5.9" + "@storybook/client-api" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/components" "6.5.9" + "@storybook/core-common" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/node-logger" "6.5.9" + "@storybook/preview-web" "6.5.9" + "@storybook/router" "6.5.9" + "@storybook/semver" "^7.3.2" + "@storybook/store" "6.5.9" + "@storybook/theming" "6.5.9" + "@storybook/ui" "6.5.9" + "@types/node" "^14.0.10 || ^16.0.0" + "@types/webpack" "^4.41.26" + autoprefixer "^9.8.6" + babel-loader "^8.0.0" + case-sensitive-paths-webpack-plugin "^2.3.0" + core-js "^3.8.2" + css-loader "^3.6.0" + file-loader "^6.2.0" + find-up "^5.0.0" + fork-ts-checker-webpack-plugin "^4.1.6" + glob "^7.1.6" + glob-promise "^3.4.0" + global "^4.4.0" + html-webpack-plugin "^4.0.0" + pnp-webpack-plugin "1.6.4" + postcss "^7.0.36" + postcss-flexbugs-fixes "^4.2.1" + postcss-loader "^4.2.0" + raw-loader "^4.0.2" + stable "^0.1.8" + style-loader "^1.3.0" + terser-webpack-plugin "^4.2.3" + ts-dedent "^2.0.0" + url-loader "^4.1.1" + util-deprecate "^1.0.2" + webpack "4" + webpack-dev-middleware "^3.7.3" + webpack-filter-warnings-plugin "^1.2.1" + webpack-hot-middleware "^2.25.1" + webpack-virtual-modules "^0.2.2" + +"@storybook/builder-webpack5@^6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/builder-webpack5/-/builder-webpack5-6.5.9.tgz#30b4e08622daff104bcccd015d3ee7902f99dd99" + integrity sha512-NUVZ4Qci6HWPuoH8U/zQkdBO5soGgu7QYrGC/LWU0tRfmmZxkjr7IUU14ppDpGPYgx3r7jkaQI1J/E1YEmSCWQ== + dependencies: + "@babel/core" "^7.12.10" + "@storybook/addons" "6.5.9" + "@storybook/api" "6.5.9" + "@storybook/channel-postmessage" "6.5.9" + "@storybook/channels" "6.5.9" + "@storybook/client-api" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/components" "6.5.9" + "@storybook/core-common" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/node-logger" "6.5.9" + "@storybook/preview-web" "6.5.9" + "@storybook/router" "6.5.9" + "@storybook/semver" "^7.3.2" + "@storybook/store" "6.5.9" + "@storybook/theming" "6.5.9" + "@types/node" "^14.0.10 || ^16.0.0" + babel-loader "^8.0.0" + babel-plugin-named-exports-order "^0.0.2" + browser-assert "^1.2.1" + case-sensitive-paths-webpack-plugin "^2.3.0" + core-js "^3.8.2" + css-loader "^5.0.1" + fork-ts-checker-webpack-plugin "^6.0.4" + glob "^7.1.6" + glob-promise "^3.4.0" + html-webpack-plugin "^5.0.0" + path-browserify "^1.0.1" + process "^0.11.10" + stable "^0.1.8" + style-loader "^2.0.0" + terser-webpack-plugin "^5.0.3" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + webpack "^5.9.0" + webpack-dev-middleware "^4.1.0" + webpack-hot-middleware "^2.25.1" + webpack-virtual-modules "^0.4.1" + +"@storybook/channel-postmessage@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-6.5.9.tgz#9cf4530f0364cee0d5e58f92d6fb5ce98e10257b" + integrity sha512-pX/0R8UW7ezBhCrafRaL20OvMRcmESYvQQCDgjqSzJyHkcG51GOhsd6Ge93eJ6QvRMm9+w0Zs93N2VKjVtz0Qw== + dependencies: + "@storybook/channels" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/core-events" "6.5.9" + core-js "^3.8.2" + global "^4.4.0" + qs "^6.10.0" + telejson "^6.0.8" + +"@storybook/channel-websocket@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/channel-websocket/-/channel-websocket-6.5.9.tgz#6b7a0127fec58ee5be4f6aebcf460adc564f2f34" + integrity sha512-xtHvSNwuOhkgALwVshKWsoFhDmuvcosdYfxcfFGEiYKXIu46tRS5ZXmpmgEC/0JAVkVoFj5nL8bV7IY5np6oaA== + dependencies: + "@storybook/channels" "6.5.9" + "@storybook/client-logger" "6.5.9" + core-js "^3.8.2" + global "^4.4.0" + telejson "^6.0.8" + +"@storybook/channels@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-6.5.9.tgz#abfab89a6587a2688e9926d4aafeb11c9d8b2e79" + integrity sha512-FvGA35nV38UPXWOl9ERapFTJaxwSTamQ339s2Ev7E9riyRG+GRkgTWzf5kECJgS1PAYKd/7m/RqKJT9BVv6A5g== + dependencies: + core-js "^3.8.2" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + +"@storybook/client-api@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-6.5.9.tgz#3e4a8ec1d277fd81325c5d959c553161a85fa182" + integrity sha512-pc7JKJoWLesixUKvG2nV36HukUuYoGRyAgD3PpIV7qSBS4JixqZ3VAHFUtqV1UzfOSQTovLSl4a0rIRnpie6gA== + dependencies: + "@storybook/addons" "6.5.9" + "@storybook/channel-postmessage" "6.5.9" + "@storybook/channels" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/store" "6.5.9" + "@types/qs" "^6.9.5" + "@types/webpack-env" "^1.16.0" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.21" + memoizerific "^1.11.3" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + store2 "^2.12.0" + synchronous-promise "^2.0.15" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + +"@storybook/client-logger@6.5.9", "@storybook/client-logger@^6.4.0": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-6.5.9.tgz#dc1669abe8c45af1cc38f74c6f4b15ff33e63014" + integrity sha512-DOHL6p0uiDd3gV/Sb2FR+Vh6OiPrrf8BrA06uvXWsMRIIvEEvnparxv9EvPg7FlmUX0T3nq7d3juwjx4F8Wbcg== + dependencies: + core-js "^3.8.2" + global "^4.4.0" + +"@storybook/components@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-6.5.9.tgz#97e07ffe11ab76c01ccee380888991bd161f75b2" + integrity sha512-BhfX980O9zn/1J4FNMeDo8ZvL1m5Ml3T4HRpfYmEBnf8oW5b5BeF6S2K2cwFStZRjWqm1feUcwNpZxCBVMkQnQ== + dependencies: + "@storybook/client-logger" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/theming" "6.5.9" + "@types/react-syntax-highlighter" "11.0.5" + core-js "^3.8.2" + memoizerific "^1.11.3" + qs "^6.10.0" + react-syntax-highlighter "^15.4.5" + regenerator-runtime "^0.13.7" + util-deprecate "^1.0.2" + +"@storybook/core-client@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/core-client/-/core-client-6.5.9.tgz#ea6035d1c90d2c68e860e3cf629979491856cd88" + integrity sha512-LY0QbhShowO+PQx3gao3wdVjpKMH1AaSLmuI95FrcjoMmSXGf96jVLKQp9mJRGeHIsAa93EQBYuCihZycM3Kbg== + dependencies: + "@storybook/addons" "6.5.9" + "@storybook/channel-postmessage" "6.5.9" + "@storybook/channel-websocket" "6.5.9" + "@storybook/client-api" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/preview-web" "6.5.9" + "@storybook/store" "6.5.9" + "@storybook/ui" "6.5.9" + airbnb-js-shims "^2.2.1" + ansi-to-html "^0.6.11" + core-js "^3.8.2" + global "^4.4.0" + lodash "^4.17.21" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + unfetch "^4.2.0" + util-deprecate "^1.0.2" + +"@storybook/core-common@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/core-common/-/core-common-6.5.9.tgz#7ca8258ea2634b1d64695c1e4262f71cc7457989" + integrity sha512-NxOK0mrOCo0TWZ7Npc5HU66EKoRHlrtg18/ZixblLDWQMIqY9XCck8K1kJ8QYpYCHla+aHIsYUArFe2vhlEfZA== + dependencies: + "@babel/core" "^7.12.10" + "@babel/plugin-proposal-class-properties" "^7.12.1" + "@babel/plugin-proposal-decorators" "^7.12.12" + "@babel/plugin-proposal-export-default-from" "^7.12.1" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" + "@babel/plugin-proposal-object-rest-spread" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.12.7" + "@babel/plugin-proposal-private-methods" "^7.12.1" + "@babel/plugin-proposal-private-property-in-object" "^7.12.1" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-transform-arrow-functions" "^7.12.1" + "@babel/plugin-transform-block-scoping" "^7.12.12" + "@babel/plugin-transform-classes" "^7.12.1" + "@babel/plugin-transform-destructuring" "^7.12.1" + "@babel/plugin-transform-for-of" "^7.12.1" + "@babel/plugin-transform-parameters" "^7.12.1" + "@babel/plugin-transform-shorthand-properties" "^7.12.1" + "@babel/plugin-transform-spread" "^7.12.1" + "@babel/preset-env" "^7.12.11" + "@babel/preset-react" "^7.12.10" + "@babel/preset-typescript" "^7.12.7" + "@babel/register" "^7.12.1" + "@storybook/node-logger" "6.5.9" + "@storybook/semver" "^7.3.2" + "@types/node" "^14.0.10 || ^16.0.0" + "@types/pretty-hrtime" "^1.0.0" + babel-loader "^8.0.0" + babel-plugin-macros "^3.0.1" + babel-plugin-polyfill-corejs3 "^0.1.0" + chalk "^4.1.0" + core-js "^3.8.2" + express "^4.17.1" + file-system-cache "^1.0.5" + find-up "^5.0.0" + fork-ts-checker-webpack-plugin "^6.0.4" + fs-extra "^9.0.1" + glob "^7.1.6" + handlebars "^4.7.7" + interpret "^2.2.0" + json5 "^2.1.3" + lazy-universal-dotenv "^3.0.1" + picomatch "^2.3.0" + pkg-dir "^5.0.0" + pretty-hrtime "^1.0.3" + resolve-from "^5.0.0" + slash "^3.0.0" + telejson "^6.0.8" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + webpack "4" + +"@storybook/core-events@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-6.5.9.tgz#5b0783c7d22a586c0f5e927a61fe1b1223e19637" + integrity sha512-tXt7a3ZvJOCeEKpNa/B5rQM5VI7UJLlOh3IHOImWn4HqoBRrZvbourmac+PRZAtXpos0h3c6554Hjapj/Sny5Q== + dependencies: + core-js "^3.8.2" + +"@storybook/core-server@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-6.5.9.tgz#749a881c1a81d7cf1a69f3782c06a7f0c39a505c" + integrity sha512-YeePGUrd5fQPvGzMhowh124KrcZURFpFXg1VB0Op3ESqCIsInoMZeObci4Gc+binMXC7vcv7aw3EwSLU37qJzQ== + dependencies: + "@discoveryjs/json-ext" "^0.5.3" + "@storybook/builder-webpack4" "6.5.9" + "@storybook/core-client" "6.5.9" + "@storybook/core-common" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/csf-tools" "6.5.9" + "@storybook/manager-webpack4" "6.5.9" + "@storybook/node-logger" "6.5.9" + "@storybook/semver" "^7.3.2" + "@storybook/store" "6.5.9" + "@storybook/telemetry" "6.5.9" + "@types/node" "^14.0.10 || ^16.0.0" + "@types/node-fetch" "^2.5.7" + "@types/pretty-hrtime" "^1.0.0" + "@types/webpack" "^4.41.26" + better-opn "^2.1.1" + boxen "^5.1.2" + chalk "^4.1.0" + cli-table3 "^0.6.1" + commander "^6.2.1" + compression "^1.7.4" + core-js "^3.8.2" + cpy "^8.1.2" + detect-port "^1.3.0" + express "^4.17.1" + fs-extra "^9.0.1" + global "^4.4.0" + globby "^11.0.2" + ip "^2.0.0" + lodash "^4.17.21" + node-fetch "^2.6.7" + open "^8.4.0" + pretty-hrtime "^1.0.3" + prompts "^2.4.0" + regenerator-runtime "^0.13.7" + serve-favicon "^2.5.0" + slash "^3.0.0" + telejson "^6.0.8" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + watchpack "^2.2.0" + webpack "4" + ws "^8.2.3" + x-default-browser "^0.4.0" + +"@storybook/core@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/core/-/core-6.5.9.tgz#da4f237391d99aed1228323f24b335cafbdf3499" + integrity sha512-Mt3TTQnjQt2/pa60A+bqDsAOrYpohapdtt4DDZEbS8h0V6u11KyYYh3w7FCySlL+sPEyogj63l5Ec76Jah3l2w== + dependencies: + "@storybook/core-client" "6.5.9" + "@storybook/core-server" "6.5.9" + +"@storybook/csf-tools@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/csf-tools/-/csf-tools-6.5.9.tgz#8e01df2305b53e228229f0b45ada3720e6e42a1c" + integrity sha512-RAdhsO2XmEDyWy0qNQvdKMLeIZAuyfD+tYlUwBHRU6DbByDucvwgMOGy5dF97YNJFmyo93EUYJzXjUrJs3U1LQ== + dependencies: + "@babel/core" "^7.12.10" + "@babel/generator" "^7.12.11" + "@babel/parser" "^7.12.11" + "@babel/plugin-transform-react-jsx" "^7.12.12" + "@babel/preset-env" "^7.12.11" + "@babel/traverse" "^7.12.11" + "@babel/types" "^7.12.11" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/mdx1-csf" "^0.0.1" + core-js "^3.8.2" + fs-extra "^9.0.1" + global "^4.4.0" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + +"@storybook/csf@0.0.2--canary.4566f4d.1": + version "0.0.2--canary.4566f4d.1" + resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.0.2--canary.4566f4d.1.tgz#dac52a21c40ef198554e71fe4d20d61e17f65327" + integrity sha512-9OVvMVh3t9znYZwb0Svf/YQoxX2gVOeQTGe2bses2yj+a3+OJnCrUF3/hGv6Em7KujtOdL2LL+JnG49oMVGFgQ== + dependencies: + lodash "^4.17.15" + +"@storybook/docs-tools@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/docs-tools/-/docs-tools-6.5.9.tgz#5ff304f881e972ce14923a5ffcfed3f052094889" + integrity sha512-UoTaXLvec8x+q+4oYIk/t8DBju9C3ZTGklqOxDIt+0kS3TFAqEgI3JhKXqQOXgN5zDcvLVSxi8dbVAeSxk2ktA== + dependencies: + "@babel/core" "^7.12.10" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/store" "6.5.9" + core-js "^3.8.2" + doctrine "^3.0.0" + lodash "^4.17.21" + regenerator-runtime "^0.13.7" + +"@storybook/instrumenter@6.5.9", "@storybook/instrumenter@^6.4.0": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/instrumenter/-/instrumenter-6.5.9.tgz#885d9dec31b7b7fa6ea29b446105480450e527b8" + integrity sha512-I2nu/6H0MAy8d+d3LY/G6oYEFyWlc8f2Qs2DhpYh5FiCgIpzvY0DMN05Lf8oaXdKHL3lPF/YLJH17FttekXs1w== + dependencies: + "@storybook/addons" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/core-events" "6.5.9" + core-js "^3.8.2" + global "^4.4.0" + +"@storybook/manager-webpack4@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/manager-webpack4/-/manager-webpack4-6.5.9.tgz#c75d2cced4550c8a786f00b0e57b203d613e706c" + integrity sha512-49LZlHqWc7zj9tQfOOANixPYmLxqWTTZceA6DSXnKd9xDiO2Gl23Y+l/CSPXNZGDB8QFAwpimwqyKJj/NLH45A== + dependencies: + "@babel/core" "^7.12.10" + "@babel/plugin-transform-template-literals" "^7.12.1" + "@babel/preset-react" "^7.12.10" + "@storybook/addons" "6.5.9" + "@storybook/core-client" "6.5.9" + "@storybook/core-common" "6.5.9" + "@storybook/node-logger" "6.5.9" + "@storybook/theming" "6.5.9" + "@storybook/ui" "6.5.9" + "@types/node" "^14.0.10 || ^16.0.0" + "@types/webpack" "^4.41.26" + babel-loader "^8.0.0" + case-sensitive-paths-webpack-plugin "^2.3.0" + chalk "^4.1.0" + core-js "^3.8.2" + css-loader "^3.6.0" + express "^4.17.1" + file-loader "^6.2.0" + find-up "^5.0.0" + fs-extra "^9.0.1" + html-webpack-plugin "^4.0.0" + node-fetch "^2.6.7" + pnp-webpack-plugin "1.6.4" + read-pkg-up "^7.0.1" + regenerator-runtime "^0.13.7" + resolve-from "^5.0.0" + style-loader "^1.3.0" + telejson "^6.0.8" + terser-webpack-plugin "^4.2.3" + ts-dedent "^2.0.0" + url-loader "^4.1.1" + util-deprecate "^1.0.2" + webpack "4" + webpack-dev-middleware "^3.7.3" + webpack-virtual-modules "^0.2.2" + +"@storybook/manager-webpack5@^6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/manager-webpack5/-/manager-webpack5-6.5.9.tgz#ce9dd6ea6298ab426b111f170c23deea7085ba08" + integrity sha512-J1GamphSsaZLNBEhn1awgxzOS8KfvzrHtVlAm2VHwW7j1E1DItROFJhGCgduYYuBiN9eqm+KIYrxcr6cRuoolQ== + dependencies: + "@babel/core" "^7.12.10" + "@babel/plugin-transform-template-literals" "^7.12.1" + "@babel/preset-react" "^7.12.10" + "@storybook/addons" "6.5.9" + "@storybook/core-client" "6.5.9" + "@storybook/core-common" "6.5.9" + "@storybook/node-logger" "6.5.9" + "@storybook/theming" "6.5.9" + "@storybook/ui" "6.5.9" + "@types/node" "^14.0.10 || ^16.0.0" + babel-loader "^8.0.0" + case-sensitive-paths-webpack-plugin "^2.3.0" + chalk "^4.1.0" + core-js "^3.8.2" + css-loader "^5.0.1" + express "^4.17.1" + find-up "^5.0.0" + fs-extra "^9.0.1" + html-webpack-plugin "^5.0.0" + node-fetch "^2.6.7" + process "^0.11.10" + read-pkg-up "^7.0.1" + regenerator-runtime "^0.13.7" + resolve-from "^5.0.0" + style-loader "^2.0.0" + telejson "^6.0.8" + terser-webpack-plugin "^5.0.3" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + webpack "^5.9.0" + webpack-dev-middleware "^4.1.0" + webpack-virtual-modules "^0.4.1" + +"@storybook/mdx1-csf@^0.0.1": + version "0.0.1" + resolved "https://registry.yarnpkg.com/@storybook/mdx1-csf/-/mdx1-csf-0.0.1.tgz#d4184e3f6486fade9f7a6bfaf934d9bc07718d5b" + integrity sha512-4biZIWWzoWlCarMZmTpqcJNgo/RBesYZwGFbQeXiGYsswuvfWARZnW9RE9aUEMZ4XPn7B1N3EKkWcdcWe/K2tg== + dependencies: + "@babel/generator" "^7.12.11" + "@babel/parser" "^7.12.11" + "@babel/preset-env" "^7.12.11" + "@babel/types" "^7.12.11" + "@mdx-js/mdx" "^1.6.22" + "@types/lodash" "^4.14.167" + js-string-escape "^1.0.1" + loader-utils "^2.0.0" + lodash "^4.17.21" + prettier ">=2.2.1 <=2.3.0" + ts-dedent "^2.0.0" + +"@storybook/node-logger@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-6.5.9.tgz#129cfe0d0f79cab4f6a2ba194d39516680b1626f" + integrity sha512-nZZNZG2Wtwv6Trxi3FrnIqUmB55xO+X/WQGPT5iKlqNjdRIu/T72mE7addcp4rbuWCQfZUhcDDGpBOwKtBxaGg== + dependencies: + "@types/npmlog" "^4.1.2" + chalk "^4.1.0" + core-js "^3.8.2" + npmlog "^5.0.1" + pretty-hrtime "^1.0.3" + +"@storybook/postinstall@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/postinstall/-/postinstall-6.5.9.tgz#a5a2565808e9d7bc310e78c279b09ce337fe3457" + integrity sha512-KQBupK+FMRrtSt8IL0MzCZ/w9qbd25Yxxp/+ajfWgZTRgsWgVFOqcDyMhS16eNbBp5qKIBCBDXfEF+/mK8HwQQ== + dependencies: + core-js "^3.8.2" + +"@storybook/preview-web@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/preview-web/-/preview-web-6.5.9.tgz#557d919e6df50d66259521aa36ebf4055bbd236e" + integrity sha512-4eMrO2HJyZUYyL/j+gUaDvry6iGedshwT5MQqe7J9FaA+Q2pNARQRB1X53f410w7S4sObRmYIAIluWPYdWym9w== + dependencies: + "@storybook/addons" "6.5.9" + "@storybook/channel-postmessage" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + "@storybook/store" "6.5.9" + ansi-to-html "^0.6.11" + core-js "^3.8.2" + global "^4.4.0" + lodash "^4.17.21" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + synchronous-promise "^2.0.15" + ts-dedent "^2.0.0" + unfetch "^4.2.0" + util-deprecate "^1.0.2" + +"@storybook/router@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/router/-/router-6.5.9.tgz#4740248f8517425b2056273fb366ace8a17c65e8" + integrity sha512-G2Xp/2r8vU2O34eelE+G5VbEEVFDeHcCURrVJEROh6dq2asFJAPbzslVXSeCqgOTNLSpRDJ2NcN5BckkNqmqJg== + dependencies: + "@storybook/client-logger" "6.5.9" + core-js "^3.8.2" + memoizerific "^1.11.3" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + +"@storybook/semver@^7.3.2": + version "7.3.2" + resolved "https://registry.yarnpkg.com/@storybook/semver/-/semver-7.3.2.tgz#f3b9c44a1c9a0b933c04e66d0048fcf2fa10dac0" + integrity sha512-SWeszlsiPsMI0Ps0jVNtH64cI5c0UF3f7KgjVKJoNP30crQ6wUSddY2hsdeczZXEKVJGEn50Q60flcGsQGIcrg== + dependencies: + core-js "^3.6.5" + find-up "^4.1.0" + +"@storybook/source-loader@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/source-loader/-/source-loader-6.5.9.tgz#7b6f065c6a6108c4b4ca7e45bfd78707373d84ac" + integrity sha512-H03nFKaP6borfWMTTa9igBA+Jm2ph+FoVJImWC/X+LAmLSJYYSXuqSgmiZ/DZvbjxS4k8vccE2HXogne1IvaRA== + dependencies: + "@storybook/addons" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + core-js "^3.8.2" + estraverse "^5.2.0" + global "^4.4.0" + loader-utils "^2.0.0" + lodash "^4.17.21" + prettier ">=2.2.1 <=2.3.0" + regenerator-runtime "^0.13.7" + +"@storybook/store@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/store/-/store-6.5.9.tgz#dc9963fc013636569082bd8f7200804866373735" + integrity sha512-80pcDTcCwK6wUA63aWOp13urI77jfipIVee9mpVvbNyfrNN8kGv1BS0z/JHDxuV6rC4g7LG1fb+BurR0yki7BA== + dependencies: + "@storybook/addons" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/csf" "0.0.2--canary.4566f4d.1" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.21" + memoizerific "^1.11.3" + regenerator-runtime "^0.13.7" + slash "^3.0.0" + stable "^0.1.8" + synchronous-promise "^2.0.15" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + +"@storybook/telemetry@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/telemetry/-/telemetry-6.5.9.tgz#8e1e0d4a89fc2387620045e5ea96c109d16a7247" + integrity sha512-JluoHCRhHAr4X0eUNVBSBi1JIBA92404Tu1TPdbN7x6gCZxHXXPTSUTAnspXp/21cTdMhY2x+kfZQ8fmlGK4MQ== + dependencies: + "@storybook/client-logger" "6.5.9" + "@storybook/core-common" "6.5.9" + chalk "^4.1.0" + core-js "^3.8.2" + detect-package-manager "^2.0.1" + fetch-retry "^5.0.2" + fs-extra "^9.0.1" + global "^4.4.0" + isomorphic-unfetch "^3.1.0" + nanoid "^3.3.1" + read-pkg-up "^7.0.1" + regenerator-runtime "^0.13.7" + +"@storybook/testing-library@^0.0.13": + version "0.0.13" + resolved "https://registry.yarnpkg.com/@storybook/testing-library/-/testing-library-0.0.13.tgz#417c87d4ea62895092ec5fdf67027ae201254f45" + integrity sha512-vRMeIGer4EjJkTgI8sQyK9W431ekPWYCWL//OmSDJ64IT3h7FnW7Xg6p+eqM3oII98/O5pcya5049GxnjaPtxw== + dependencies: + "@storybook/client-logger" "^6.4.0" + "@storybook/instrumenter" "^6.4.0" + "@testing-library/dom" "^8.3.0" + "@testing-library/user-event" "^13.2.1" + ts-dedent "^2.2.0" + +"@storybook/theming@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.5.9.tgz#13f60a3a3cd73ceb5caf9f188e1627e79f1891aa" + integrity sha512-KM0AMP5jMQPAdaO8tlbFCYqx9uYM/hZXGSVUhznhLYu7bhNAIK7ZVmXxyE/z/khM++8eUHzRoZGiO/cwCkg9Xw== + dependencies: + "@storybook/client-logger" "6.5.9" + core-js "^3.8.2" + memoizerific "^1.11.3" + regenerator-runtime "^0.13.7" + +"@storybook/ui@6.5.9": + version "6.5.9" + resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-6.5.9.tgz#41e59279323cccc0d613974ec9782d797220c8a7" + integrity sha512-ryuPxJgtbb0gPXKGgGAUC+Z185xGAd1IvQ0jM5fJ0SisHXI8jteG3RaWhntOehi9qCg+64Vv6eH/cj9QYNHt1Q== + dependencies: + "@storybook/addons" "6.5.9" + "@storybook/api" "6.5.9" + "@storybook/channels" "6.5.9" + "@storybook/client-logger" "6.5.9" + "@storybook/components" "6.5.9" + "@storybook/core-events" "6.5.9" + "@storybook/router" "6.5.9" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.5.9" + core-js "^3.8.2" + memoizerific "^1.11.3" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + resolve-from "^5.0.0" + +"@testing-library/dom@^8.3.0": + version "8.16.0" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-8.16.0.tgz#d6fc50250aed17b1035ca1bd64655e342db3936a" + integrity sha512-uxF4zmnLHHDlmW4l+0WDjcgLVwCvH+OVLpD8Dfp+Bjfz85prwxWGbwXgJdLtkgjD0qfOzkJF9SmA6YZPsMYX4w== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/runtime" "^7.12.5" + "@types/aria-query" "^4.2.0" + aria-query "^5.0.0" + chalk "^4.1.0" + dom-accessibility-api "^0.5.9" + lz-string "^1.4.4" + pretty-format "^27.0.2" + +"@testing-library/user-event@^13.2.1": + version "13.5.0" + resolved "https://registry.yarnpkg.com/@testing-library/user-event/-/user-event-13.5.0.tgz#69d77007f1e124d55314a2b73fd204b333b13295" + integrity sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg== + dependencies: + "@babel/runtime" "^7.12.5" + "@tootallnate/once@1": version "1.1.2" resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82" integrity sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw== -"@trysound/sax@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" - integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== +"@tootallnate/once@2": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" + integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== -"@types/eslint-scope@^3.7.0": - version "3.7.1" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.1.tgz#8dc390a7b4f9dd9f1284629efce982e41612116e" - integrity sha512-SCFeogqiptms4Fg29WpOTk5nHIzfpKCemSN63ksBQYKTcXoJEmJagV+DhVmbapZzY4/5YaOV1nZwrsU79fFm1g== +"@ts-morph/common@~0.12.3": + version "0.12.3" + resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.12.3.tgz#a96e250217cd30e480ab22ec6a0ebbe65fd784ff" + integrity sha512-4tUmeLyXJnJWvTFOKtcNJ1yh0a3SsTLi2MUoyj8iUNznFRN1ZquaNe7Oukqrnki2FzZkm0J9adCNLDZxUzvj+w== + dependencies: + fast-glob "^3.2.7" + minimatch "^3.0.4" + mkdirp "^1.0.4" + path-browserify "^1.0.1" + +"@types/aria-query@^4.2.0": + version "4.2.2" + resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.2.tgz#ed4e0ad92306a704f9fb132a0cfcf77486dbe2bc" + integrity sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig== + +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + +"@types/bonjour@^3.5.9": + version "3.5.10" + resolved "https://registry.yarnpkg.com/@types/bonjour/-/bonjour-3.5.10.tgz#0f6aadfe00ea414edc86f5d106357cda9701e275" + integrity sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw== + dependencies: + "@types/node" "*" + +"@types/connect-history-api-fallback@^1.3.5": + version "1.3.5" + resolved "https://registry.yarnpkg.com/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz#d1f7a8a09d0ed5a57aee5ae9c18ab9b803205dae" + integrity sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw== + dependencies: + "@types/express-serve-static-core" "*" + "@types/node" "*" + +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + +"@types/eslint-scope@^3.7.3": + version "3.7.3" + resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.3.tgz#125b88504b61e3c8bc6f870882003253005c3224" + integrity sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g== dependencies: "@types/eslint" "*" "@types/estree" "*" @@ -1487,19 +4230,98 @@ "@types/estree" "*" "@types/json-schema" "*" -"@types/estree@*", "@types/estree@^0.0.50": +"@types/estree@*": version "0.0.50" resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.50.tgz#1e0caa9364d3fccd2931c3ed96fdbeaa5d4cca83" integrity sha512-C6N5s2ZFtuZRj54k2/zyRhNDjJwwcViAM3Nbm8zjBpbqAdZ00mr0CFxvSKeO8Y/e03WVFLpQMdHYVfUd6SB+Hw== -"@types/glob@^7.1.1": - version "7.1.4" - resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.4.tgz#ea59e21d2ee5c517914cb4bc8e4153b99e566672" - integrity sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA== +"@types/estree@^0.0.51": + version "0.0.51" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.51.tgz#cfd70924a25a3fd32b218e5e420e6897e1ac4f40" + integrity sha512-CuPgU6f3eT/XgKKPqKd/gLZV1Xmvf1a2R5POBOGQa6uv82xpls89HU5zKeVoyR8XzHd1RGNOlQlvUe3CFkjWNQ== + +"@types/express-serve-static-core@*", "@types/express-serve-static-core@^4.17.18": + version "4.17.28" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz#c47def9f34ec81dc6328d0b1b5303d1ec98d86b8" + integrity sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@*", "@types/express@^4.17.13": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + +"@types/glob@*", "@types/glob@^7.1.1": + version "7.2.0" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.2.0.tgz#bc1b5bf3aa92f25bd5dd39f35c57361bdce5b2eb" + integrity sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA== dependencies: "@types/minimatch" "*" "@types/node" "*" +"@types/graceful-fs@^4.1.2": + version "4.1.5" + resolved "https://registry.yarnpkg.com/@types/graceful-fs/-/graceful-fs-4.1.5.tgz#21ffba0d98da4350db64891f92a9e5db3cdb4e15" + integrity sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw== + dependencies: + "@types/node" "*" + +"@types/hast@^2.0.0": + version "2.3.4" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc" + integrity sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g== + dependencies: + "@types/unist" "*" + +"@types/html-minifier-terser@^5.0.0": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-5.1.2.tgz#693b316ad323ea97eed6b38ed1a3cc02b1672b57" + integrity sha512-h4lTMgMJctJybDp8CQrxTUiiYmedihHWkjnF/8Pxseu2S6Nlfcy8kwboQ8yejh456rP2yWoEVm1sS/FVsfM48w== + +"@types/html-minifier-terser@^6.0.0": + version "6.1.0" + resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" + integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== + +"@types/http-proxy@^1.17.8": + version "1.17.8" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.8.tgz#968c66903e7e42b483608030ee85800f22d03f55" + integrity sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA== + dependencies: + "@types/node" "*" + +"@types/is-function@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.1.tgz#2d024eace950c836d9e3335a66b97960ae41d022" + integrity sha512-A79HEEiwXTFtfY+Bcbo58M2GRYzCr9itHWzbzHVFNEYCcoU/MMGwYYf721gBrnhpj1s6RGVVha/IgNFnR0Iw/Q== + +"@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0": + version "2.0.4" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" + integrity sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g== + +"@types/istanbul-lib-report@*": + version "3.0.0" + resolved "https://registry.yarnpkg.com/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz#c14c24f18ea8190c118ee7562b7ff99a36552686" + integrity sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg== + dependencies: + "@types/istanbul-lib-coverage" "*" + +"@types/istanbul-reports@^3.0.0": + version "3.0.1" + resolved "https://registry.yarnpkg.com/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz#9153fe98bba2bd565a63add9436d6f0d7f8468ff" + integrity sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw== + dependencies: + "@types/istanbul-lib-report" "*" + "@types/jasmine@*": version "3.9.1" resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-3.9.1.tgz#94c65ee8bf9d24d9e1d84abaed57b6e0da8b49de" @@ -1517,61 +4339,260 @@ dependencies: "@types/jasmine" "*" -"@types/jquery@^3.3.29": - version "3.5.7" - resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.5.7.tgz#07614671f79c6ad70633bb2d8977f01cea242e27" - integrity sha512-Why+9t1KuqWtIqYKtbk6wgWbE1PjyXJOyGkpmTUh0RX5p4HL7nnRuBkjAO9P2r9tGQP6bLWxl77jRLew3V5xXg== +"@types/jquery@^3.5.13": + version "3.5.13" + resolved "https://registry.yarnpkg.com/@types/jquery/-/jquery-3.5.13.tgz#5482d3ee325d5862f77a91c09369ae0a5b082bf3" + integrity sha512-ZxJrup8nz/ZxcU0vantG+TPdboMhB24jad2uSap50zE7Q9rUeYlCF25kFMSmHR33qoeOgqcdHEp3roaookC0Sg== dependencies: "@types/sizzle" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8": +"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.9" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== +"@types/json-schema@^7.0.4": + version "7.0.11" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.11.tgz#d421b6c527a3037f7c84433fd2c4229e016863d3" + integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== + +"@types/json5@^0.0.29": + version "0.0.29" + resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" + integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== + +"@types/lodash@^4.14.167": + version "4.14.182" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.182.tgz#05301a4d5e62963227eaafe0ce04dd77c54ea5c2" + integrity sha512-/THyiqyQAP9AfARo4pF+aCGcyiQ94tX/Is2I7HofNRqoYLgN1PBoOWu2/zTA5zMxzP5EFutMtWtGAFRKUe961Q== + +"@types/mdast@^3.0.0": + version "3.0.10" + resolved "https://registry.yarnpkg.com/@types/mdast/-/mdast-3.0.10.tgz#4724244a82a4598884cbbe9bcfd73dff927ee8af" + integrity sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA== + dependencies: + "@types/unist" "*" + +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + "@types/minimatch@*": version "3.0.5" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.5.tgz#1001cc5e6a3704b83c236027e77f2f58ea010f40" integrity sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ== -"@types/node@*", "@types/node@^16.10.9": +"@types/node-fetch@^2.5.7": + version "2.6.2" + resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.6.2.tgz#d1a9c5fd049d9415dce61571557104dec3ec81da" + integrity sha512-DHqhlq5jeESLy19TYhLakJ07kNumXWjcDdxXsLUMJZ6ue8VZJj4kLPQVE/2mdHh3xZziNF1xppu5lwmS53HR+A== + dependencies: + "@types/node" "*" + form-data "^3.0.0" + +"@types/node@*": version "16.10.9" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.10.9.tgz#8f1cdd517972f76a3b928298f4c0747cd6fef25a" integrity sha512-H9ReOt+yqIJPCutkTYjFjlyK6WEMQYT9hLZMlWtOjFQY2ItppsWZ6RJf8Aw+jz5qTYceuHvFgPIaKOHtLAEWBw== +"@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0", "@types/node@^16.11.45": + version "16.11.45" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.11.45.tgz#155b13a33c665ef2b136f7f245fa525da419e810" + integrity sha512-3rKg/L5x0rofKuuUt5zlXzOnKyIHXmIu5R8A0TuNDMF2062/AOIDBciFIjToLEJ/9F9DzkHNot+BpNsMI1OLdQ== + +"@types/normalize-package-data@^2.4.0": + version "2.4.1" + resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz#d3357479a0fdfdd5907fe67e17e0a85c906e1301" + integrity sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw== + +"@types/npmlog@^4.1.2": + version "4.1.4" + resolved "https://registry.yarnpkg.com/@types/npmlog/-/npmlog-4.1.4.tgz#30eb872153c7ead3e8688c476054ddca004115f6" + integrity sha512-WKG4gTr8przEZBiJ5r3s8ZIAoMXNbOgQ+j/d5O4X3x6kZJRLNvyUJuUK/KoG3+8BaOHPhp2m7WC6JKKeovDSzQ== + "@types/parse-json@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== +"@types/parse5@^5.0.0": + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/parse5/-/parse5-5.0.3.tgz#e7b5aebbac150f8b5fdd4a46e7f0bd8e65e19109" + integrity sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw== + +"@types/pretty-hrtime@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.1.tgz#72a26101dc567b0d68fd956cf42314556e42d601" + integrity sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ== + +"@types/prop-types@*": + version "15.7.5" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf" + integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w== + "@types/q@^0.0.32": version "0.0.32" resolved "https://registry.yarnpkg.com/@types/q/-/q-0.0.32.tgz#bd284e57c84f1325da702babfc82a5328190c0c5" integrity sha1-vShOV8hPEyXacCur/IKlMoGQwMU= +"@types/qs@*", "@types/qs@^6.9.5": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== + +"@types/react-dom@^16.9.14": + version "16.9.16" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.16.tgz#c591f2ed1c6f32e9759dfa6eb4abfd8041f29e39" + integrity sha512-Oqc0RY4fggGA3ltEgyPLc3IV9T73IGoWjkONbsyJ3ZBn+UPPCYpU2ec0i3cEbJuEdZtkqcCF2l1zf2pBdgUGSg== + dependencies: + "@types/react" "^16" + +"@types/react-syntax-highlighter@11.0.5": + version "11.0.5" + resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.5.tgz#0d546261b4021e1f9d85b50401c0a42acb106087" + integrity sha512-VIOi9i2Oj5XsmWWoB72p3KlZoEbdRAcechJa8Ztebw7bDl2YmR+odxIqhtJGp1q2EozHs02US+gzxJ9nuf56qg== + dependencies: + "@types/react" "*" + +"@types/react@*": + version "18.0.15" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.15.tgz#d355644c26832dc27f3e6cbf0c4f4603fc4ab7fe" + integrity sha512-iz3BtLuIYH1uWdsv6wXYdhozhqj20oD4/Hk2DNXIn1kFsmp9x8d9QB6FnPhfkbhd2PgEONt9Q1x/ebkwjfFLow== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/react@^16", "@types/react@^16.14.23": + version "16.14.28" + resolved "https://registry.yarnpkg.com/@types/react/-/react-16.14.28.tgz#073258f3fe7bb80c748842c1f93aeaafe16dffad" + integrity sha512-83zBE6+XUVXsdL3iFzOyUewdauaU+KviKCHEGOgSW52coAuqW7tEKQM0E9+ZC0Zk6TELQ2/JgogPvp7FavzFwg== + dependencies: + "@types/prop-types" "*" + "@types/scheduler" "*" + csstype "^3.0.2" + +"@types/retry@^0.12.0": + version "0.12.1" + resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.1.tgz#d8f1c0d0dc23afad6dc16a9e993a0865774b4065" + integrity sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g== + +"@types/scheduler@*": + version "0.16.2" + resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39" + integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew== + "@types/selenium-webdriver@^3.0.0": version "3.0.19" resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-3.0.19.tgz#28ecede76f15b13553b4e86074d4cf9a0bbe49c4" integrity sha512-OFUilxQg+rWL2FMxtmIgCkUDlJB6pskkpvmew7yeXfzzsOBb5rc+y2+DjHm+r3r1ZPPcJefK3DveNSYWGiy68g== +"@types/serve-index@^1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@types/serve-index/-/serve-index-1.9.1.tgz#1b5e85370a192c01ec6cec4735cf2917337a6278" + integrity sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg== + dependencies: + "@types/express" "*" + +"@types/serve-static@*": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + "@types/sizzle@*": version "2.3.3" resolved "https://registry.yarnpkg.com/@types/sizzle/-/sizzle-2.3.3.tgz#ff5e2f1902969d305225a047c8a0fd5c915cebef" integrity sha512-JYM8x9EGF163bEyhdJBpR2QX1R5naCJHC8ucJylJ3w9/CVBaskdQ8WqBf8MmQrd1kRvp/a4TS8HJ+bxzR7ZJYQ== +"@types/sockjs@^0.3.33": + version "0.3.33" + resolved "https://registry.yarnpkg.com/@types/sockjs/-/sockjs-0.3.33.tgz#570d3a0b99ac995360e3136fd6045113b1bd236f" + integrity sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw== + dependencies: + "@types/node" "*" + "@types/source-list-map@*": version "0.1.2" resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.2.tgz#0078836063ffaf17412349bba364087e0ac02ec9" integrity sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA== -"@types/webpack-sources@^0.1.5": - version "0.1.9" - resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-0.1.9.tgz#da69b06eb34f6432e6658acb5a6893c55d983920" - integrity sha512-bvzMnzqoK16PQIC8AYHNdW45eREJQMd6WG/msQWX5V2+vZmODCOPb4TJcbgRljTZZTwTM4wUMcsI8FftNA7new== +"@types/tapable@^1", "@types/tapable@^1.0.5": + version "1.0.8" + resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.8.tgz#b94a4391c85666c7b73299fd3ad79d4faa435310" + integrity sha512-ipixuVrh2OdNmauvtT51o3d8z12p6LtFW9in7U79der/kwejjdNchQC5UMn5u/KxNoM7VHHOs/l8KS8uHxhODQ== + +"@types/uglify-js@*": + version "3.16.0" + resolved "https://registry.yarnpkg.com/@types/uglify-js/-/uglify-js-3.16.0.tgz#2cf74a0e6ebb6cd54c0d48e509d5bd91160a9602" + integrity sha512-0yeUr92L3r0GLRnBOvtYK1v2SjqMIqQDHMl7GLb+l2L8+6LSFWEEWEIgVsPdMn5ImLM8qzWT8xFPtQYpp8co0g== + dependencies: + source-map "^0.6.1" + +"@types/unist@*", "@types/unist@^2.0.0", "@types/unist@^2.0.2", "@types/unist@^2.0.3": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" + integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== + +"@types/webpack-env@^1.16.0", "@types/webpack-env@^1.17.0": + version "1.17.0" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.17.0.tgz#f99ce359f1bfd87da90cc4a57cab0a18f34a48d0" + integrity sha512-eHSaNYEyxRA5IAG0Ym/yCyf86niZUIF/TpWKofQI/CVfh5HsMEUyfE2kwFxha4ow0s5g0LfISQxpDKjbRDrizw== + +"@types/webpack-sources@*": + version "3.2.0" + resolved "https://registry.yarnpkg.com/@types/webpack-sources/-/webpack-sources-3.2.0.tgz#16d759ba096c289034b26553d2df1bf45248d38b" + integrity sha512-Ft7YH3lEVRQ6ls8k4Ff1oB4jN6oy/XmU6tQISKdhfh+1mR+viZFphS6WL0IrtDOzvefmJg5a0s7ZQoRXwqTEFg== dependencies: "@types/node" "*" "@types/source-list-map" "*" - source-map "^0.6.1" + source-map "^0.7.3" + +"@types/webpack@^4.41.26", "@types/webpack@^4.41.8": + version "4.41.32" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.32.tgz#a7bab03b72904070162b2f169415492209e94212" + integrity sha512-cb+0ioil/7oz5//7tZUSwbrSAN/NWHrQylz5cW8G0dWTcF/g+/dSdMlKVZspBYuMAN1+WnwHrkxiRrLcwd0Heg== + dependencies: + "@types/node" "*" + "@types/tapable" "^1" + "@types/uglify-js" "*" + "@types/webpack-sources" "*" + anymatch "^3.0.0" + source-map "^0.6.0" + +"@types/ws@^8.5.1": + version "8.5.3" + resolved "https://registry.yarnpkg.com/@types/ws/-/ws-8.5.3.tgz#7d25a1ffbecd3c4f2d35068d0b283c037003274d" + integrity sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w== + dependencies: + "@types/node" "*" + +"@types/yargs-parser@*": + version "21.0.0" + resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-21.0.0.tgz#0c60e537fa790f5f9472ed2776c2b71ec117351b" + integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== + +"@types/yargs@^15.0.0": + version "15.0.14" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-15.0.14.tgz#26d821ddb89e70492160b66d10a0eb6df8f6fb06" + integrity sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ== + dependencies: + "@types/yargs-parser" "*" + +"@types/yargs@^16.0.0": + version "16.0.4" + resolved "https://registry.yarnpkg.com/@types/yargs/-/yargs-16.0.4.tgz#26aad98dd2c2a38e421086ea9ad42b9e51642977" + integrity sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw== + dependencies: + "@types/yargs-parser" "*" "@webassemblyjs/ast@1.11.1": version "1.11.1" @@ -1581,21 +4602,64 @@ "@webassemblyjs/helper-numbers" "1.11.1" "@webassemblyjs/helper-wasm-bytecode" "1.11.1" +"@webassemblyjs/ast@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" + integrity sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA== + dependencies: + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + "@webassemblyjs/floating-point-hex-parser@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.1.tgz#f6c61a705f0fd7a6aecaa4e8198f23d9dc179e4f" integrity sha512-iGRfyc5Bq+NnNuX8b5hwBrRjzf0ocrJPI6GWFodBFzmFnyvrQ83SHKhmilCU/8Jv67i4GJZBMhEzltxzcNagtQ== +"@webassemblyjs/floating-point-hex-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz#3c3d3b271bddfc84deb00f71344438311d52ffb4" + integrity sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA== + "@webassemblyjs/helper-api-error@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.1.tgz#1a63192d8788e5c012800ba6a7a46c705288fd16" integrity sha512-RlhS8CBCXfRUR/cwo2ho9bkheSXG0+NwooXcc3PAILALf2QLdFyj7KGsKRbVc95hZnhnERon4kW/D3SZpp6Tcg== +"@webassemblyjs/helper-api-error@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz#203f676e333b96c9da2eeab3ccef33c45928b6a2" + integrity sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw== + "@webassemblyjs/helper-buffer@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.1.tgz#832a900eb444884cde9a7cad467f81500f5e5ab5" integrity sha512-gwikF65aDNeeXa8JxXa2BAk+REjSyhrNC9ZwdT0f8jc4dQQeDQ7G4m0f2QCLPJiMTTO6wfDmRmj/pW0PsUvIcA== +"@webassemblyjs/helper-buffer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz#a1442d269c5feb23fcbc9ef759dac3547f29de00" + integrity sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA== + +"@webassemblyjs/helper-code-frame@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz#647f8892cd2043a82ac0c8c5e75c36f1d9159f27" + integrity sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA== + dependencies: + "@webassemblyjs/wast-printer" "1.9.0" + +"@webassemblyjs/helper-fsm@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz#c05256b71244214671f4b08ec108ad63b70eddb8" + integrity sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw== + +"@webassemblyjs/helper-module-context@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz#25d8884b76839871a08a6c6f806c3979ef712f07" + integrity sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-numbers@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.1.tgz#64d81da219fbbba1e3bd1bfc74f6e8c4e10a62ae" @@ -1610,6 +4674,11 @@ resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.1.tgz#f328241e41e7b199d0b20c18e88429c4433295e1" integrity sha512-PvpoOGiJwXeTrSf/qfudJhwlvDQxFgelbMqtq52WWiXC6Xgg1IREdngmPN3bs4RoO83PnL/nFrxucXj1+BX62Q== +"@webassemblyjs/helper-wasm-bytecode@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz#4fed8beac9b8c14f8c58b70d124d549dd1fe5790" + integrity sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw== + "@webassemblyjs/helper-wasm-section@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.1.tgz#21ee065a7b635f319e738f0dd73bfbda281c097a" @@ -1620,6 +4689,16 @@ "@webassemblyjs/helper-wasm-bytecode" "1.11.1" "@webassemblyjs/wasm-gen" "1.11.1" +"@webassemblyjs/helper-wasm-section@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz#5a4138d5a6292ba18b04c5ae49717e4167965346" + integrity sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/ieee754@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.11.1.tgz#963929e9bbd05709e7e12243a099180812992614" @@ -1627,6 +4706,13 @@ dependencies: "@xtuc/ieee754" "^1.2.0" +"@webassemblyjs/ieee754@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz#15c7a0fbaae83fb26143bbacf6d6df1702ad39e4" + integrity sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg== + dependencies: + "@xtuc/ieee754" "^1.2.0" + "@webassemblyjs/leb128@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.11.1.tgz#ce814b45574e93d76bae1fb2644ab9cdd9527aa5" @@ -1634,11 +4720,23 @@ dependencies: "@xtuc/long" "4.2.2" +"@webassemblyjs/leb128@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.9.0.tgz#f19ca0b76a6dc55623a09cffa769e838fa1e1c95" + integrity sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw== + dependencies: + "@xtuc/long" "4.2.2" + "@webassemblyjs/utf8@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.1.tgz#d1f8b764369e7c6e6bae350e854dec9a59f0a3ff" integrity sha512-9kqcxAEdMhiwQkHpkNiorZzqpGrodQQ2IGrHHxCy+Ozng0ofyMA0lTqiLkVs1uzTRejX+/O0EOT7KxqVPuXosQ== +"@webassemblyjs/utf8@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.9.0.tgz#04d33b636f78e6a6813227e82402f7637b6229ab" + integrity sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w== + "@webassemblyjs/wasm-edit@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.1.tgz#ad206ebf4bf95a058ce9880a8c092c5dec8193d6" @@ -1653,6 +4751,20 @@ "@webassemblyjs/wasm-parser" "1.11.1" "@webassemblyjs/wast-printer" "1.11.1" +"@webassemblyjs/wasm-edit@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz#3fe6d79d3f0f922183aa86002c42dd256cfee9cf" + integrity sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/helper-wasm-section" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-opt" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wast-printer" "1.9.0" + "@webassemblyjs/wasm-gen@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.1.tgz#86c5ea304849759b7d88c47a32f4f039ae3c8f76" @@ -1664,6 +4776,17 @@ "@webassemblyjs/leb128" "1.11.1" "@webassemblyjs/utf8" "1.11.1" +"@webassemblyjs/wasm-gen@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz#50bc70ec68ded8e2763b01a1418bf43491a7a49c" + integrity sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + "@webassemblyjs/wasm-opt@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.1.tgz#657b4c2202f4cf3b345f8a4c6461c8c2418985f2" @@ -1674,6 +4797,16 @@ "@webassemblyjs/wasm-gen" "1.11.1" "@webassemblyjs/wasm-parser" "1.11.1" +"@webassemblyjs/wasm-opt@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz#2211181e5b31326443cc8112eb9f0b9028721a61" + integrity sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-buffer" "1.9.0" + "@webassemblyjs/wasm-gen" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + "@webassemblyjs/wasm-parser@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.1.tgz#86ca734534f417e9bd3c67c7a1c75d8be41fb199" @@ -1686,6 +4819,30 @@ "@webassemblyjs/leb128" "1.11.1" "@webassemblyjs/utf8" "1.11.1" +"@webassemblyjs/wasm-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz#9d48e44826df4a6598294aa6c87469d642fff65e" + integrity sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-wasm-bytecode" "1.9.0" + "@webassemblyjs/ieee754" "1.9.0" + "@webassemblyjs/leb128" "1.9.0" + "@webassemblyjs/utf8" "1.9.0" + +"@webassemblyjs/wast-parser@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz#3031115d79ac5bd261556cecc3fa90a3ef451914" + integrity sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/floating-point-hex-parser" "1.9.0" + "@webassemblyjs/helper-api-error" "1.9.0" + "@webassemblyjs/helper-code-frame" "1.9.0" + "@webassemblyjs/helper-fsm" "1.9.0" + "@xtuc/long" "4.2.2" + "@webassemblyjs/wast-printer@1.11.1": version "1.11.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.11.1.tgz#d0c73beda8eec5426f10ae8ef55cee5e7084c2f0" @@ -1694,6 +4851,15 @@ "@webassemblyjs/ast" "1.11.1" "@xtuc/long" "4.2.2" +"@webassemblyjs/wast-printer@1.9.0": + version "1.9.0" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz#4935d54c85fef637b00ce9f52377451d00d47899" + integrity sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/wast-parser" "1.9.0" + "@xtuc/long" "4.2.2" + "@xtuc/ieee754@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790" @@ -1709,12 +4875,12 @@ resolved "https://registry.yarnpkg.com/@yarnpkg/lockfile/-/lockfile-1.1.0.tgz#e77a97fbd345b76d83245edcd17d393b1b41fb31" integrity sha512-GpSwvyXOcOOlV70vbnzjj4fW5xW/FdUF6nQEt1ENy7m4ZCczi1+/buVUPAqmGfqznsORNFzUMjctTIp8a9tuCQ== -"@yellowspot/ng-truncate@^1.4.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@yellowspot/ng-truncate/-/ng-truncate-1.7.0.tgz#36c0dd73f4f8cd2a35c881c97f31fe6c492d1598" - integrity sha512-UX1BqaGuY4H9hc+2u+OSR2jb4mzrtPW2tw+c1ca0er7PZJvWbNuXsKc1Hop2l8BMvddjEfRyCCe6I30zptC2Yg== +"@yellowspot/ng-truncate@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@yellowspot/ng-truncate/-/ng-truncate-2.0.0.tgz#e210fa537975ed454227b65befaa7866e7ef6f73" + integrity sha512-OzUPzcBLgC30gD1sqCgzOGDmZXlviJ51mr3C4HAEF70m9mSzFeCeiGpcJ8f7/SXSWkaMPs+Ar4xcFF4ZKtbFrA== dependencies: - tslib "^1.9.0" + tslib "^2.0.0" abab@^2.0.5: version "2.0.5" @@ -1726,7 +4892,14 @@ abbrev@1: resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== -accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +accepts@~1.3.4, accepts@~1.3.5: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" integrity sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA== @@ -1734,16 +4907,63 @@ accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: mime-types "~2.1.24" negotiator "0.6.2" +accepts@~1.3.8: + version "1.3.8" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.8.tgz#0bf0be125b67014adcb0b0921e62db7bffe16b2e" + integrity sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw== + dependencies: + mime-types "~2.1.34" + negotiator "0.6.3" + acorn-import-assertions@^1.7.6: version "1.8.0" resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.8.0.tgz#ba2b5939ce62c238db6d93d81c9b111b29b855e9" integrity sha512-m7VZ3jwz4eK6A4Vtt8Ew1/mNbP24u0FhdyfA7fSvnJR6LMdfOYnmuIrrJAgrYfYJ10F/otaHTtrtrtmHdMNzEw== +acorn-node@^1.3.0: + version "1.8.2" + resolved "https://registry.yarnpkg.com/acorn-node/-/acorn-node-1.8.2.tgz#114c95d64539e53dede23de8b9d96df7c7ae2af8" + integrity sha512-8mt+fslDufLYntIoPAaIMUe/lrbrehIiwmR3t2k9LljIzoigEPF27eLk2hy8zSGzmR/ogr7zbRKINMo1u0yh5A== + dependencies: + acorn "^7.0.0" + acorn-walk "^7.0.0" + xtend "^4.0.2" + +acorn-walk@^7.0.0: + version "7.2.0" + resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" + integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== + +acorn@^6.4.1: + version "6.4.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6" + integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ== + +acorn@^7.0.0: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== + acorn@^8.4.1: version "8.5.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.5.0.tgz#4512ccb99b3698c752591e9bb4472e38ad43cee2" integrity sha512-yXbYeFy+jUuYd3/CDcg2NkIYE991XYX/bje7LmjJigUciaeO1JR4XxXgCIV1/Zc/dRuFEyw1L0pbA+qynJkW5Q== +acorn@^8.5.0: + version "8.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.1.tgz#0197122c843d1bf6d0a5e83220a788f278f63c30" + integrity sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A== + +acorn@^8.7.1: + version "8.8.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.8.0.tgz#88c0187620435c7f6015803f5539dae05a9dbea8" + integrity sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w== + +address@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/address/-/address-1.2.0.tgz#d352a62c92fee90f89a693eccd2a8b2139ab02d9" + integrity sha512-tNEZYz5G/zYunxFm7sfhAxkXEuLj3K6BKwv6ZURlsF6yiUQ65z0Q2wZW9L5cPUl9ocofGvXOdFYbFHp0+6MOig== + adjust-sourcemap-loader@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/adjust-sourcemap-loader/-/adjust-sourcemap-loader-4.0.0.tgz#fc4a0fd080f7d10471f30a7320f25560ade28c99" @@ -1780,6 +5000,15 @@ agentkeepalive@^4.1.3: depd "^1.1.2" humanize-ms "^1.2.1" +agentkeepalive@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/agentkeepalive/-/agentkeepalive-4.2.1.tgz#a7975cbb9f83b367f06c90cc51ff28fe7d499717" + integrity sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA== + dependencies: + debug "^4.1.0" + depd "^1.1.2" + humanize-ms "^1.2.1" + aggregate-error@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/aggregate-error/-/aggregate-error-3.1.0.tgz#92670ff50f5359bdb7a3e0d40d0ec30c5737687a" @@ -1788,34 +5017,74 @@ aggregate-error@^3.0.0: clean-stack "^2.0.0" indent-string "^4.0.0" +airbnb-js-shims@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/airbnb-js-shims/-/airbnb-js-shims-2.2.1.tgz#db481102d682b98ed1daa4c5baa697a05ce5c040" + integrity sha512-wJNXPH66U2xjgo1Zwyjf9EydvJ2Si94+vSdk6EERcBfB2VZkeltpqIats0cqIZMLCXP3zcyaUKGYQeIBT6XjsQ== + dependencies: + array-includes "^3.0.3" + array.prototype.flat "^1.2.1" + array.prototype.flatmap "^1.2.1" + es5-shim "^4.5.13" + es6-shim "^0.35.5" + function.prototype.name "^1.1.0" + globalthis "^1.0.0" + object.entries "^1.1.0" + object.fromentries "^2.0.0 || ^1.0.0" + object.getownpropertydescriptors "^2.0.3" + object.values "^1.1.0" + promise.allsettled "^1.0.0" + promise.prototype.finally "^3.1.0" + string.prototype.matchall "^4.0.0 || ^3.0.1" + string.prototype.padend "^3.0.0" + string.prototype.padstart "^3.0.0" + symbol.prototype.description "^1.0.0" + ajv-errors@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/ajv-errors/-/ajv-errors-1.0.1.tgz#f35986aceb91afadec4102fbd85014950cefa64d" integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== -ajv-formats@2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.0.tgz#96eaf83e38d32108b66d82a9cb0cfa24886cdfeb" - integrity sha512-USH2jBb+C/hIpwD2iRjp0pe0k+MvzG0mlSn/FIdCgQhUb9ALPRjt2KIQdfZDS9r0ZIeUAg7gOu9KL0PFqGqr5Q== +ajv-formats@2.1.1, ajv-formats@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ajv-formats/-/ajv-formats-2.1.1.tgz#6e669400659eb74973bbf2e33327180a0996b520" + integrity sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA== dependencies: ajv "^8.0.0" -ajv-keywords@^3.1.0, ajv-keywords@^3.5.2: +ajv-keywords@^3.1.0, ajv-keywords@^3.4.1, ajv-keywords@^3.5.2: version "3.5.2" resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.2.tgz#31f29da5ab6e00d1c2d329acf7b5929614d5014d" integrity sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ== -ajv@8.6.2: - version "8.6.2" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.6.2.tgz#2fb45e0e5fcbc0813326c1c3da535d1881bb0571" - integrity sha512-9807RlWAgT564wT+DjeyU5OFMPjmzxVobvDFmNAhY+5zD6A2ly3jDp6sgnfyDtlIQ+7H97oc/DGCzzfu9rjw9w== +ajv-keywords@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-5.1.0.tgz#69d4d385a4733cdbeab44964a1170a88f87f0e16" + integrity sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw== + dependencies: + fast-deep-equal "^3.1.3" + +ajv@8.11.0: + version "8.11.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.11.0.tgz#977e91dd96ca669f54a11e23e378e33b884a565f" + integrity sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" require-from-string "^2.0.2" uri-js "^4.2.2" -ajv@^6.1.0, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: +ajv@8.9.0: + version "8.9.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.9.0.tgz#738019146638824dea25edcf299dcba1b0e7eb18" + integrity sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ== + dependencies: + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2, ajv@^6.12.3, ajv@^6.12.4, ajv@^6.12.5: version "6.12.6" resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.6.tgz#baf5a62e802b07d977034586f8c3baf5adf26df4" integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== @@ -1835,17 +5104,20 @@ ajv@^8.0.0: require-from-string "^2.0.2" uri-js "^4.2.2" -alphanum-sort@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/alphanum-sort/-/alphanum-sort-1.0.2.tgz#97a1119649b211ad33691d9f9f486a8ec9fbe0a3" - integrity sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM= - -angular-bootstrap-md@^7.5.4: - version "7.5.4" - resolved "https://registry.yarnpkg.com/angular-bootstrap-md/-/angular-bootstrap-md-7.5.4.tgz#1e6c482729380b98aea7dec9b4d7a4f4e187e08c" - integrity sha512-LBVqSswd49hJ3YNTkXzwM0Cn1+9SQ2kVYQxX36ZjxaKNeDQKaUk3V2Rb/y8krhDJrPJh37pDzRmlCDObg37EIA== +ajv@^8.8.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.10.0.tgz#e573f719bd3af069017e3b66538ab968d040e54d" + integrity sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw== dependencies: - tslib "^1.9.0" + fast-deep-equal "^3.1.1" + json-schema-traverse "^1.0.0" + require-from-string "^2.0.2" + uri-js "^4.2.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + integrity sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg== angular-router-loader@^0.8.5: version "0.8.5" @@ -1854,13 +5126,20 @@ angular-router-loader@^0.8.5: dependencies: loader-utils "^1.0.2" -angularx-qrcode@^11.0.0: - version "11.0.0" - resolved "https://registry.yarnpkg.com/angularx-qrcode/-/angularx-qrcode-11.0.0.tgz#03f1ccdd34c99fa1fa9f5666febb0b903e3c6881" - integrity sha512-qg6g288LO9daqBP5GCHewy9W0IMW7jDMEaAiklA1za0UhjCj6VH1Agydr4JVp7RMkw1LsLapFhWsVSYqrWaERA== +angularx-qrcode@^13.0.3: + version "13.0.3" + resolved "https://registry.yarnpkg.com/angularx-qrcode/-/angularx-qrcode-13.0.3.tgz#6f632163027354391bcb0e5eaa7da473593a2fa5" + integrity sha512-KzalrRy2MczdApSq29k2TBOml6taQ7NqdgZDNgPSQBd5/27+l3xHkOkhhDOmGruSyCcT2KdB8qeOT/6K48c+xw== dependencies: - qrcode "1.4.2" - tslib "^2.0.0" + "@cordobo/qrcode" "1.5.0" + tslib "^2.3.0" + +ansi-align@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" + integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== + dependencies: + string-width "^4.1.0" ansi-colors@4.1.1: version "4.1.1" @@ -1872,6 +5151,11 @@ ansi-colors@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-3.2.4.tgz#e3a3da4bfbae6c86a9c285625de124a234026fbf" integrity sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA== +ansi-colors@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.3.tgz#37611340eb2243e70cc604cad35d63270d48781b" + integrity sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw== + ansi-escapes@^4.2.1: version "4.3.2" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-4.3.2.tgz#6b2291d1db7d98b6521d5f1efa42d0f3a9feb65e" @@ -1879,10 +5163,17 @@ ansi-escapes@^4.2.1: dependencies: type-fest "^0.21.3" -ansi-html@0.0.7: - version "0.0.7" - resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" - integrity sha1-gTWEAhliqenm/QOflA0S9WynhZ4= +ansi-gray@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" + integrity sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw== + dependencies: + ansi-wrap "0.1.0" + +ansi-html-community@0.0.8, ansi-html-community@^0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/ansi-html-community/-/ansi-html-community-0.0.8.tgz#69fbc4d6ccbe383f9736934ae34c3f8290f1bf41" + integrity sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw== ansi-regex@^2.0.0: version "2.1.1" @@ -1894,11 +5185,6 @@ ansi-regex@^3.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg= -ansi-regex@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" - integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== - ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" @@ -1909,7 +5195,7 @@ ansi-styles@^2.2.1: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= -ansi-styles@^3.2.0, ansi-styles@^3.2.1: +ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA== @@ -1923,6 +5209,23 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" + integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== + +ansi-to-html@^0.6.11: + version "0.6.15" + resolved "https://registry.yarnpkg.com/ansi-to-html/-/ansi-to-html-0.6.15.tgz#ac6ad4798a00f6aa045535d7f6a9cb9294eebea7" + integrity sha512-28ijx2aHJGdzbs+O5SNQF65r6rrKYnkuwTYm8lZlChuoJ9P1vVzIpWO20sQTqTPDXYp6NFwk326vApTtLVFXpQ== + dependencies: + entities "^2.0.0" + +ansi-wrap@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" + integrity sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw== + anymatch@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" @@ -1931,7 +5234,7 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@~3.1.2: +anymatch@^3.0.0, anymatch@^3.0.3, anymatch@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== @@ -1939,6 +5242,23 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +apache-crypt@^1.1.2: + version "1.2.5" + resolved "https://registry.yarnpkg.com/apache-crypt/-/apache-crypt-1.2.5.tgz#4eb6b6dbaed2041ce5bc2d802f4421f5fdadc25e" + integrity sha512-ICnYQH+DFVmw+S4Q0QY2XRXD8Ne8ewh8HgbuFH4K7022zCxgHM0Hz1xkRnUlEfAXNbwp1Cnhbedu60USIfDxvg== + dependencies: + unix-crypt-td-js "^1.1.4" + +apache-md5@^1.0.6: + version "1.1.7" + resolved "https://registry.yarnpkg.com/apache-md5/-/apache-md5-1.1.7.tgz#dcef1802700cc231d60c5e08fd088f2f9b36375a" + integrity sha512-JtHjzZmJxtzfTSjsCyHgPR155HBe5WGyUyHTaEkfy46qhwCFKx1Epm6nAxgUG3WfUZP1dWhGqj9Z2NOBeZ+uBw== + +app-root-dir@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/app-root-dir/-/app-root-dir-1.0.2.tgz#38187ec2dea7577fff033ffcb12172692ff6e118" + integrity sha512-jlpIfsOoNoafl92Sz//64uQHGSyMrD2vYG5d8o2a4qGvyNCvXur7bzIsWtAC/6flI2RYAp3kv8rsfBtaLm7w0g== + app-root-path@^2.1.0: version "2.2.1" resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-2.2.1.tgz#d0df4a682ee408273583d43f6f79e9892624bc9a" @@ -1949,18 +5269,31 @@ app-root-path@^3.0.0: resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.0.0.tgz#210b6f43873227e18a4b810a032283311555d5ad" integrity sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw== -aproba@^1.0.3: +"aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + +aproba@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" integrity sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw== -are-we-there-yet@~1.1.2: - version "1.1.7" - resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.7.tgz#b15474a932adab4ff8a50d9adfa7e4e926f21146" - integrity sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g== +are-we-there-yet@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" + integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== dependencies: delegates "^1.0.0" - readable-stream "^2.0.6" + readable-stream "^3.6.0" + +are-we-there-yet@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz#ba20bd6b553e31d62fc8c31bd23d22b95734390d" + integrity sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" argparse@^1.0.7: version "1.0.10" @@ -1977,10 +5310,15 @@ aria-query@^3.0.0: ast-types-flow "0.0.7" commander "^2.11.0" +aria-query@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-5.0.0.tgz#210c21aaf469613ee8c9a62c7f86525e058db52c" + integrity sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg== + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" - integrity sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA= + integrity sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA== arr-flatten@^1.1.0: version "1.1.0" @@ -1990,19 +5328,40 @@ arr-flatten@^1.1.0: arr-union@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" - integrity sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ= + integrity sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q== + +array-find-index@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-find-index/-/array-find-index-1.0.2.tgz#df010aa1287e164bbda6f9723b0a96a1ec4187a1" + integrity sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw== array-flatten@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" integrity sha1-ml9pkFGx5wczKPKgCJaLZOopVdI= -array-flatten@^2.1.0: +array-flatten@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-2.1.2.tgz#24ef80a28c1a893617e2149b0c6d0d788293b099" integrity sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ== -array-union@^1.0.1: +array-from@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/array-from/-/array-from-2.1.1.tgz#cfe9d8c26628b9dc5aecc62a9f5d8f1f352c1195" + integrity sha512-GQTc6Uupx1FCavi5mPzBvVT7nEOeWMmUA9P95wpfpW1XwMSKs+KaymD5C2Up7KAUKg/mYwbsUYzdZWcoajlNZg== + +array-includes@^3.0.3: + version "3.1.5" + resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.5.tgz#2c320010db8d31031fd2a5f6b3bbd4b1aad31bdb" + integrity sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + get-intrinsic "^1.1.1" + is-string "^1.0.7" + +array-union@^1.0.1, array-union@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" integrity sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk= @@ -2014,6 +5373,11 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== +array-union@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-3.0.1.tgz#da52630d327f8b88cfbfb57728e2af5cd9b6b975" + integrity sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw== + array-uniq@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" @@ -2022,13 +5386,70 @@ array-uniq@^1.0.1: array-unique@^0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" - integrity sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg= + integrity sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ== + +array.prototype.flat@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz#0b0c1567bf57b38b56b4c97b8aa72ab45e4adc7b" + integrity sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.2" + es-shim-unscopables "^1.0.0" + +array.prototype.flatmap@^1.2.1: + version "1.3.0" + resolved "https://registry.yarnpkg.com/array.prototype.flatmap/-/array.prototype.flatmap-1.3.0.tgz#a7e8ed4225f4788a70cd910abcf0791e76a5534f" + integrity sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.2" + es-shim-unscopables "^1.0.0" + +array.prototype.map@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/array.prototype.map/-/array.prototype.map-1.0.4.tgz#0d97b640cfdd036c1b41cfe706a5e699aa0711f2" + integrity sha512-Qds9QnX7A0qISY7JT5WuJO0NJPE9CMlC6JzHQfhpqAAQQzufVRoeH7EzUY5GcPTx72voG8LV/5eo+b8Qi8hmhA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + es-array-method-boxes-properly "^1.0.0" + is-string "^1.0.7" + +array.prototype.reduce@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/array.prototype.reduce/-/array.prototype.reduce-1.0.4.tgz#8167e80089f78bff70a99e20bd4201d4663b0a6f" + integrity sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.2" + es-array-method-boxes-properly "^1.0.0" + is-string "^1.0.7" arrify@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0= +arrify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-2.0.1.tgz#c9655e9331e0abcd588d2a7cad7e9956f66701fa" + integrity sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug== + +asn1.js@^5.2.0: + version "5.4.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07" + integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA== + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + safer-buffer "^2.1.0" + asn1@~0.2.3: version "0.2.4" resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.4.tgz#8d2475dfab553bb33e77b54e59e880bb8ce23136" @@ -2041,44 +5462,71 @@ assert-plus@1.0.0, assert-plus@^1.0.0: resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" integrity sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU= +assert@^1.1.1: + version "1.5.0" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.5.0.tgz#55c109aaf6e0aefdb3dc4b71240c70bf574b18eb" + integrity sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA== + dependencies: + object-assign "^4.1.1" + util "0.10.3" + assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" - integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= + integrity sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw== + +ast-transform@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/ast-transform/-/ast-transform-0.0.0.tgz#74944058887d8283e189d954600947bc98fe0062" + integrity sha512-e/JfLiSoakfmL4wmTGPjv0HpTICVmxwXgYOB8x+mzozHL8v+dSfCbrJ8J8hJ0YBP0XcYu1aLZ6b/3TnxNK3P2A== + dependencies: + escodegen "~1.2.0" + esprima "~1.0.4" + through "~2.3.4" ast-types-flow@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= +ast-types@^0.7.0: + version "0.7.8" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.7.8.tgz#902d2e0d60d071bdcd46dc115e1809ed11c138a9" + integrity sha512-RIOpVnVlltB6PcBJ5BMLx+H+6JJ/zjDGU0t7f0L6c2M1dqcK92VQopLBlPQ9R80AVXelfqYgjcPLtHtDbNFg0Q== + async-each@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.3.tgz#b727dbf87d7651602f06f4d4ac387f47d91b0cbf" integrity sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ== -async-limiter@~1.0.0: - version "1.0.1" - resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.1.tgz#dd379e94f0db8310b08291f9d64c3209766617fd" - integrity sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ== - -async@^2.6.2: - version "2.6.3" - resolved "https://registry.yarnpkg.com/async/-/async-2.6.3.tgz#d72625e2344a3656e3a3ad4fa749fa83299d82ff" - integrity sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg== - dependencies: - lodash "^4.17.14" - asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" integrity sha1-x57Zf380y48robyXkLzDZkdLS3k= +at-least-node@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/at-least-node/-/at-least-node-1.0.0.tgz#602cd4b46e844ad4effc92a8011a3c46e0238dc2" + integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== + atob@^2.1.2: version "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.6.1: +autoprefixer@^10.4.6: + version "10.4.7" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-10.4.7.tgz#1db8d195f41a52ca5069b7593be167618edbbedf" + integrity sha512-ypHju4Y2Oav95SipEcCcI5J7CGPuvz8oat7sUtYj3ClK44bldfvtvcxK6IEK++7rqB7YchDGzweZIBG+SD0ZAA== + dependencies: + browserslist "^4.20.3" + caniuse-lite "^1.0.30001335" + fraction.js "^4.2.0" + normalize-range "^0.1.2" + picocolors "^1.0.0" + postcss-value-parser "^4.2.0" + +autoprefixer@^9.8.6: version "9.8.8" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.8.tgz#fd4bd4595385fa6f06599de749a4d5f7a474957a" integrity sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA== @@ -2108,16 +5556,24 @@ axobject-query@2.0.2: dependencies: ast-types-flow "0.0.7" -babel-loader@8.2.2: - version "8.2.2" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.2.tgz#9363ce84c10c9a40e6c753748e1441b60c8a0b81" - integrity sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g== +babel-loader@8.2.5, babel-loader@^8.0.0, babel-loader@^8.2.5: + version "8.2.5" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.5.tgz#d45f585e654d5a5d90f5350a779d7647c5ed512e" + integrity sha512-OSiFfH89LrEMiWd4pLNqGz4CwJDtbs2ZVc+iGu2HrkRfPxId9F2anQj38IxWpmRfsUY0aBZYi1EFcd3mhtRMLQ== dependencies: find-cache-dir "^3.3.1" - loader-utils "^1.4.0" + loader-utils "^2.0.0" make-dir "^3.1.0" schema-utils "^2.6.5" +babel-plugin-apply-mdx-type-prop@1.6.22: + version "1.6.22" + resolved "https://registry.yarnpkg.com/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz#d216e8fd0de91de3f1478ef3231e05446bc8705b" + integrity sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ== + dependencies: + "@babel/helper-plugin-utils" "7.10.4" + "@mdx-js/util" "1.6.22" + babel-plugin-dynamic-import-node@^2.3.3: version "2.3.3" resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" @@ -2125,36 +5581,103 @@ babel-plugin-dynamic-import-node@^2.3.3: dependencies: object.assign "^4.1.0" -babel-plugin-polyfill-corejs2@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz#e9124785e6fd94f94b618a7954e5693053bf5327" - integrity sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ== +babel-plugin-extract-import-names@1.6.22: + version "1.6.22" + resolved "https://registry.yarnpkg.com/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.22.tgz#de5f9a28eb12f3eb2578bf74472204e66d1a13dc" + integrity sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ== + dependencies: + "@babel/helper-plugin-utils" "7.10.4" + +babel-plugin-istanbul@6.1.1, babel-plugin-istanbul@^6.0.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz#fa88ec59232fd9b4e36dbbc540a8ec9a9b47da73" + integrity sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA== + dependencies: + "@babel/helper-plugin-utils" "^7.0.0" + "@istanbuljs/load-nyc-config" "^1.0.0" + "@istanbuljs/schema" "^0.1.2" + istanbul-lib-instrument "^5.0.4" + test-exclude "^6.0.0" + +babel-plugin-macros@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" + integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== + dependencies: + "@babel/runtime" "^7.12.5" + cosmiconfig "^7.0.0" + resolve "^1.19.0" + +babel-plugin-named-exports-order@^0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/babel-plugin-named-exports-order/-/babel-plugin-named-exports-order-0.0.2.tgz#ae14909521cf9606094a2048239d69847540cb09" + integrity sha512-OgOYHOLoRK+/mvXU9imKHlG6GkPLYrUCvFXG/CM93R/aNNO8pOOF4aS+S8CCHMDQoNSeiOYEZb/G6RwL95Jktw== + +babel-plugin-polyfill-corejs2@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz#440f1b70ccfaabc6b676d196239b138f8a2cfba5" + integrity sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w== dependencies: "@babel/compat-data" "^7.13.11" - "@babel/helper-define-polyfill-provider" "^0.2.2" + "@babel/helper-define-polyfill-provider" "^0.3.1" semver "^6.1.1" -babel-plugin-polyfill-corejs3@^0.2.2: - version "0.2.5" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.5.tgz#2779846a16a1652244ae268b1e906ada107faf92" - integrity sha512-ninF5MQNwAX9Z7c9ED+H2pGt1mXdP4TqzlHKyPIYmJIYz0N+++uwdM7RnJukklhzJ54Q84vA4ZJkgs7lu5vqcw== +babel-plugin-polyfill-corejs2@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.2.tgz#e4c31d4c89b56f3cf85b92558954c66b54bd972d" + integrity sha512-LPnodUl3lS0/4wN3Rb+m+UK8s7lj2jcLRrjho4gLw+OJs+I4bvGXshINesY5xx/apM+biTnQ9reDI8yj+0M5+Q== dependencies: - "@babel/helper-define-polyfill-provider" "^0.2.2" - core-js-compat "^3.16.2" + "@babel/compat-data" "^7.17.7" + "@babel/helper-define-polyfill-provider" "^0.3.2" + semver "^6.1.1" -babel-plugin-polyfill-regenerator@^0.2.2: - version "0.2.2" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz#b310c8d642acada348c1fa3b3e6ce0e851bee077" - integrity sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg== +babel-plugin-polyfill-corejs3@^0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz#80449d9d6f2274912e05d9e182b54816904befd0" + integrity sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw== dependencies: - "@babel/helper-define-polyfill-provider" "^0.2.2" + "@babel/helper-define-polyfill-provider" "^0.1.5" + core-js-compat "^3.8.1" + +babel-plugin-polyfill-corejs3@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72" + integrity sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.1" + core-js-compat "^3.21.0" + +babel-plugin-polyfill-corejs3@^0.5.2: + version "0.5.3" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz#d7e09c9a899079d71a8b670c6181af56ec19c5c7" + integrity sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.2" + core-js-compat "^3.21.0" + +babel-plugin-polyfill-regenerator@^0.3.0, babel-plugin-polyfill-regenerator@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz#2c0678ea47c75c8cc2fbb1852278d8fb68233990" + integrity sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A== + dependencies: + "@babel/helper-define-polyfill-provider" "^0.3.1" + +bail@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776" + integrity sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ== balanced-match@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -base64-js@^1.2.0, base64-js@^1.3.1: +base64-js@1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" + integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g== + +base64-js@^1.0.2, base64-js@^1.1.2, base64-js@^1.2.0, base64-js@^1.3.0, base64-js@^1.3.1: version "1.5.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== @@ -2172,6 +5695,13 @@ base@^0.11.1: mixin-deep "^1.2.0" pascalcase "^0.1.1" +basic-auth@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/basic-auth/-/basic-auth-2.0.1.tgz#b998279bf47ce38344b4f3cf916d4679bbf51e3a" + integrity sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg== + dependencies: + safe-buffer "5.1.2" + batch@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/batch/-/batch-0.6.1.tgz#dc34314f4e679318093fc760272525f94bf25c16" @@ -2184,6 +5714,23 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +bcryptjs@^2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-2.4.3.tgz#9ab5627b93e60621ff7cdac5da9733027df1d0cb" + integrity sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ== + +better-opn@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-2.1.1.tgz#94a55b4695dc79288f31d7d0e5f658320759f7c6" + integrity sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA== + dependencies: + open "^7.0.3" + +big-integer@^1.6.7: + version "1.6.51" + resolved "https://registry.yarnpkg.com/big-integer/-/big-integer-1.6.51.tgz#0df92a5d9880560d3ff2d5fd20245c889d130686" + integrity sha512-GPEid2Y9QU1Exl1rpO9B2IPJGHPSupF5GnVIP0blYvNOMer2bTvSWs1jGOUg04hTmu67nmLsQ9TBo1puaotBHg== + big.js@^5.2.2: version "5.2.2" resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" @@ -2222,33 +5769,48 @@ blocking-proxy@^1.0.0: dependencies: minimist "^1.2.0" -body-parser@1.19.0: - version "1.19.0" - resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.19.0.tgz#96b2709e57c9c4e09a6fd66a8fd979844f69f08a" - integrity sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw== +bluebird@^3.5.5: + version "3.7.2" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" + integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.11.9: + version "4.12.0" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.12.0.tgz#775b3f278efbb9718eec7361f483fb36fbbfea88" + integrity sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA== + +bn.js@^5.0.0, bn.js@^5.1.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-5.2.1.tgz#0bc527a6a0d18d0aa8d5b0538ce4a77dccfa7b70" + integrity sha512-eXRvHzWyYPBuB4NBy0cmYQjGitUrtqwbvlzP3G6VFnNRbsZQIxQ10PbKKHt8gZ/HW/D/747aDl+QkDqg3KQLMQ== + +body-parser@1.20.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.0.tgz#3de69bd89011c11573d7bfee6a64f11b6bd27cc5" + integrity sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg== dependencies: - bytes "3.1.0" + bytes "3.1.2" content-type "~1.0.4" debug "2.6.9" - depd "~1.1.2" - http-errors "1.7.2" + depd "2.0.0" + destroy "1.2.0" + http-errors "2.0.0" iconv-lite "0.4.24" - on-finished "~2.3.0" - qs "6.7.0" - raw-body "2.4.0" - type-is "~1.6.17" + on-finished "2.4.1" + qs "6.10.3" + raw-body "2.5.1" + type-is "~1.6.18" + unpipe "1.0.0" -bonjour@^3.5.0: - version "3.5.0" - resolved "https://registry.yarnpkg.com/bonjour/-/bonjour-3.5.0.tgz#8e890a183d8ee9a2393b3844c691a42bcf7bc9f5" - integrity sha1-jokKGD2O6aI5OzhExpGkK897yfU= +bonjour-service@^1.0.11: + version "1.0.12" + resolved "https://registry.yarnpkg.com/bonjour-service/-/bonjour-service-1.0.12.tgz#28fbd4683f5f2e36feedb833e24ba661cac960c3" + integrity sha512-pMmguXYCu63Ug37DluMKEHdxc+aaIf/ay4YbF8Gxtba+9d3u+rmEWy61VK3Z3hp8Rskok3BunHYnG0dUHAsblw== dependencies: - array-flatten "^2.1.0" - deep-equal "^1.0.1" + array-flatten "^2.1.2" dns-equal "^1.0.0" - dns-txt "^2.0.2" - multicast-dns "^6.0.1" - multicast-dns-service-types "^1.1.0" + fast-deep-equal "^3.1.3" + multicast-dns "^7.2.4" boolbase@^1.0.0: version "1.0.0" @@ -2260,6 +5822,27 @@ bootstrap@^4.2.1: resolved "https://registry.yarnpkg.com/bootstrap/-/bootstrap-4.6.0.tgz#97b9f29ac98f98dfa43bf7468262d84392552fd7" integrity sha512-Io55IuQY3kydzHtbGvQya3H+KorS/M9rSNyfCGCg9WZ4pyT/lCxIlpJgG1GXW/PswzC84Tr2fBYi+7+jFVQQBw== +boxen@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" + widest-line "^3.1.0" + wrap-ansi "^7.0.0" + +bplist-parser@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/bplist-parser/-/bplist-parser-0.1.1.tgz#d60d5dcc20cba6dc7e1f299b35d3e1f95dafbae6" + integrity sha512-2AEM0FXy8ZxVLBuqX0hqt1gDwcnz2zygEkQ6zaD5Wko/sB9paUNwlpawrFtKeHUAQUOzjVy9AO4oeonqIHKA9Q== + dependencies: + big-integer "^1.6.7" + brace-expansion@^1.1.7: version "1.1.11" resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" @@ -2268,6 +5851,13 @@ brace-expansion@^1.1.7: balanced-match "^1.0.0" concat-map "0.0.1" +brace-expansion@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae" + integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA== + dependencies: + balanced-match "^1.0.0" + braces@^2.3.1, braces@^2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" @@ -2284,14 +5874,128 @@ 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.2: +braces@^3.0.1, braces@^3.0.2, 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== dependencies: fill-range "^7.0.1" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4.16.0, browserslist@^4.16.6, browserslist@^4.17.3, browserslist@^4.6.4, browserslist@^4.9.1: +brfs@^2.0.0, brfs@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/brfs/-/brfs-2.0.2.tgz#44237878fa82aa479ce4f5fe2c1796ec69f07845" + integrity sha512-IrFjVtwu4eTJZyu8w/V2gxU7iLTtcHih67sgEdzrhjLBMHp2uYefUBfdM4k2UvcuWMgV7PQDZHSLeNWnLFKWVQ== + dependencies: + quote-stream "^1.0.1" + resolve "^1.1.5" + static-module "^3.0.2" + through2 "^2.0.0" + +brorand@^1.0.1, brorand@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + integrity sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w== + +brotli@^1.2.0: + version "1.3.3" + resolved "https://registry.yarnpkg.com/brotli/-/brotli-1.3.3.tgz#7365d8cc00f12cf765d2b2c898716bcf4b604d48" + integrity sha512-oTKjJdShmDuGW94SyyaoQvAjf30dZaHnjJ8uAF+u2/vGJkJbJPJAT1gDiOJP5v1Zb6f9KEyW/1HpuaWIXtGHPg== + dependencies: + base64-js "^1.1.2" + +browser-assert@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/browser-assert/-/browser-assert-1.2.1.tgz#9aaa5a2a8c74685c2ae05bfe46efd606f068c200" + integrity sha512-nfulgvOR6S4gt9UKCeGJOuSGBPGiFT6oQ/2UBnvTY/5aQ1PnksW72fhZkM30DzoRRv2WpwZf1vHHEr3mtuXIWQ== + +browser-resolve@^1.8.1: + version "1.11.3" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" + integrity sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ== + dependencies: + resolve "1.1.7" + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + integrity sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA== + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + integrity sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w== + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + integrity sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A== + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-optional@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-optional/-/browserify-optional-1.0.1.tgz#1e13722cfde0d85f121676c2a72ced533a018869" + integrity sha512-VrhjbZ+Ba5mDiSYEuPelekQMfTbhcA2DhLk2VQWqdcCROWeFqlTcXZ7yfRkXCIl8E+g4gINJYJiRB7WEtfomAQ== + dependencies: + ast-transform "0.0.0" + ast-types "^0.7.0" + browser-resolve "^1.8.1" + +browserify-rsa@^4.0.0, browserify-rsa@^4.0.1: + version "4.1.0" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.1.0.tgz#b2fd06b5b75ae297f7ce2dc651f918f5be158c8d" + integrity sha512-AdEER0Hkspgno2aR97SAf6vi0y0k8NuOpGnVH3O99rcA5Q6sh8QxcngtHuJ6uXwnfAXNM4Gn1Gb7/MV1+Ymbog== + dependencies: + bn.js "^5.0.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.2.1.tgz#eaf4add46dd54be3bb3b36c0cf15abbeba7956c3" + integrity sha512-/vrA5fguVAKKAVTNJjgSm1tRQDHUU6DbwO9IROu/0WAzC8PKhucDSh18J0RMvVeHAn5puMd+QHC2erPRNf8lmg== + dependencies: + bn.js "^5.1.1" + browserify-rsa "^4.0.1" + create-hash "^1.2.0" + create-hmac "^1.1.7" + elliptic "^6.5.3" + inherits "^2.0.4" + parse-asn1 "^5.1.5" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + integrity sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA== + dependencies: + pako "~1.0.5" + +browserslist@^4.12.0, browserslist@^4.21.2: + version "4.21.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.2.tgz#59a400757465535954946a400b841ed37e2b4ecf" + integrity sha512-MonuOgAtUB46uP5CezYbRaYKBNt2LxP0yX+Pmj4LkcDFGkn9Cbpi83d9sCjwQDErXsIJSzY5oKGDbgOlF/LPAA== + dependencies: + caniuse-lite "^1.0.30001366" + electron-to-chromium "^1.4.188" + node-releases "^2.0.6" + update-browserslist-db "^1.0.4" + +browserslist@^4.14.5, browserslist@^4.16.6, browserslist@^4.9.1: version "4.17.4" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.4.tgz#72e2508af2a403aec0a49847ef31bd823c57ead4" integrity sha512-Zg7RpbZpIJRW3am9Lyckue7PLytvVxxhJj1CaJVlCWENsGEAOlnlt8X0ZxGRPp7Bt9o8tIRM5SEXy4BCPMJjLQ== @@ -2302,6 +6006,28 @@ browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.14.5, browserslist@^4 node-releases "^2.0.0" picocolors "^1.0.0" +browserslist@^4.17.5, browserslist@^4.19.1: + version "4.19.1" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.19.1.tgz#4ac0435b35ab655896c31d53018b6dd5e9e4c9a3" + integrity sha512-u2tbbG5PdKRTUoctO3NBD8FQ5HdPh1ZXPHzp1rwaa5jTc+RV9/+RlWiAIKmjRPQF+xbGM9Kklj5bZQFa2s/38A== + dependencies: + caniuse-lite "^1.0.30001286" + electron-to-chromium "^1.4.17" + escalade "^3.1.1" + node-releases "^2.0.1" + picocolors "^1.0.0" + +browserslist@^4.20.2, browserslist@^4.20.3: + version "4.20.3" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.3.tgz#eb7572f49ec430e054f56d52ff0ebe9be915f8bf" + integrity sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg== + dependencies: + caniuse-lite "^1.0.30001332" + electron-to-chromium "^1.4.118" + escalade "^3.1.1" + node-releases "^2.0.3" + picocolors "^1.0.0" + browserstack@^1.5.1: version "1.6.1" resolved "https://registry.yarnpkg.com/browserstack/-/browserstack-1.6.1.tgz#e051f9733ec3b507659f395c7a4765a1b1e358b3" @@ -2309,15 +6035,36 @@ browserstack@^1.5.1: dependencies: https-proxy-agent "^2.2.1" +bser@2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.1.1.tgz#e6787da20ece9d07998533cfd9de6f5c38f4bc05" + integrity sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ== + dependencies: + node-int64 "^0.4.0" + +buffer-equal@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" + integrity sha512-RgSV6InVQ9ODPdLWJ5UAqBqJBOg370Nz6ZQtRzpt6nUjc8v0St97uJ4PYC6NztqIScrAXafKM3mZPMygSe1ggA== + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -buffer-indexof@^1.0.0: - version "1.1.1" - resolved "https://registry.yarnpkg.com/buffer-indexof/-/buffer-indexof-1.1.1.tgz#52fabcc6a606d1a00302802648ef68f639da268c" - integrity sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g== +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + integrity sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ== + +buffer@^4.3.0: + version "4.9.2" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.2.tgz#230ead344002988644841ab0244af8c44bbe3ef8" + integrity sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg== + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" buffer@^5.5.0: version "5.7.1" @@ -2332,44 +6079,73 @@ builtin-modules@^1.1.1: resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8= -builtins@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/builtins/-/builtins-1.0.3.tgz#cb94faeb61c8696451db36534e1422f94f0aee88" - integrity sha1-y5T662HIaWRR2zZTThQi+U8K7og= +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ== + +builtins@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.0.1.tgz#87f6db9ab0458be728564fa81d876d8d74552fa9" + integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ== + dependencies: + semver "^7.0.0" bytes@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048" integrity sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg= -bytes@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.0.tgz#f6cf7933a360e0588fa9fde85651cdc7f805d1f6" - integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg== +bytes@3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.1.2.tgz#8b0beeb98605adf1b128fa4386403c009e0221a5" + integrity sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg== -cacache@15.2.0: - version "15.2.0" - resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.2.0.tgz#73af75f77c58e72d8c630a7a2858cb18ef523389" - integrity sha512-uKoJSHmnrqXgthDFx/IU6ED/5xd+NNGe+Bb+kLZy7Ku4P+BaiWEUflAKPZ7eAzsYGcsAGASJZsybXp+quEcHTw== +cacache@16.0.7: + version "16.0.7" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.0.7.tgz#74a5d9bc4c17b4c0b373c1f5d42dadf5dc06638d" + integrity sha512-a4zfQpp5vm4Ipdvbj+ZrPonikRhm6WBEd4zT1Yc1DXsmAxrPgDwWBLF/u/wTVXSFPIgOJ1U3ghSa2Xm4s3h28w== dependencies: - "@npmcli/move-file" "^1.0.1" + "@npmcli/fs" "^2.1.0" + "@npmcli/move-file" "^2.0.0" chownr "^2.0.0" - fs-minipass "^2.0.0" - glob "^7.1.4" + fs-minipass "^2.1.0" + glob "^8.0.1" infer-owner "^1.0.4" - lru-cache "^6.0.0" - minipass "^3.1.1" + lru-cache "^7.7.1" + minipass "^3.1.6" minipass-collect "^1.0.2" minipass-flush "^1.0.5" - minipass-pipeline "^1.2.2" - mkdirp "^1.0.3" + minipass-pipeline "^1.2.4" + mkdirp "^1.0.4" p-map "^4.0.0" promise-inflight "^1.0.1" rimraf "^3.0.2" - ssri "^8.0.1" - tar "^6.0.2" + ssri "^9.0.0" + tar "^6.1.11" unique-filename "^1.1.1" +cacache@^12.0.2: + version "12.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c" + integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ== + dependencies: + bluebird "^3.5.5" + chownr "^1.1.1" + figgy-pudding "^3.5.1" + glob "^7.1.4" + graceful-fs "^4.1.15" + infer-owner "^1.0.3" + lru-cache "^5.1.1" + mississippi "^3.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.3" + ssri "^6.0.1" + unique-filename "^1.1.1" + y18n "^4.0.0" + cacache@^15.0.5, cacache@^15.2.0: version "15.3.0" resolved "https://registry.yarnpkg.com/cacache/-/cacache-15.3.0.tgz#dc85380fb2f556fe3dda4c719bfa0ec875a7f1eb" @@ -2394,6 +6170,30 @@ cacache@^15.0.5, cacache@^15.2.0: tar "^6.0.2" unique-filename "^1.1.1" +cacache@^16.0.0, cacache@^16.1.0: + version "16.1.1" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-16.1.1.tgz#4e79fb91d3efffe0630d5ad32db55cc1b870669c" + integrity sha512-VDKN+LHyCQXaaYZ7rA/qtkURU+/yYhviUdvqEv2LT6QPZU8jpyzEkEVAcKlKLt5dJ5BRp11ym8lo3NKLluEPLg== + dependencies: + "@npmcli/fs" "^2.1.0" + "@npmcli/move-file" "^2.0.0" + chownr "^2.0.0" + fs-minipass "^2.1.0" + glob "^8.0.1" + infer-owner "^1.0.4" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + mkdirp "^1.0.4" + p-map "^4.0.0" + promise-inflight "^1.0.1" + rimraf "^3.0.2" + ssri "^9.0.0" + tar "^6.1.11" + unique-filename "^1.1.1" + cache-base@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" @@ -2417,41 +6217,107 @@ call-bind@^1.0.0, call-bind@^1.0.2: function-bind "^1.1.1" get-intrinsic "^1.0.2" +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + integrity sha512-wCyFsDQkKPwwF8BDwOiWNx/9K45L/hvggQiDbve+viMNMQnWhrlYIuBk09offfwCRtCO9P6XwUttufzU11WCVw== + +callsite@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" + integrity sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ== + callsites@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73" integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ== -camelcase@^5.0.0: +camel-case@^4.1.1, camel-case@^4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/camel-case/-/camel-case-4.1.2.tgz#9728072a954f805228225a6deea6b38461e1bd5a" + integrity sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw== + dependencies: + pascal-case "^3.1.2" + tslib "^2.0.3" + +camelcase-css@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/camelcase-css/-/camelcase-css-2.0.1.tgz#ee978f6947914cc30c6b44741b6ed1df7f043fd5" + integrity sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA== + +camelcase-keys@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/camelcase-keys/-/camelcase-keys-2.1.0.tgz#308beeaffdf28119051efa1d932213c91b8f92e7" + integrity sha512-bA/Z/DERHKqoEOrp+qeGKw1QlvEQkGZSc0XaY6VnTxZr+Kv1G5zFwttpjv8qxZ/sBPT4nthwZaAcsAZTJlSKXQ== + dependencies: + camelcase "^2.0.0" + map-obj "^1.0.0" + +camelcase@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-2.1.1.tgz#7c1d16d679a1bbe59ca02cacecfb011e201f5a1f" + integrity sha512-DLIsRzJVBQu72meAKPkWQOLcujdXT32hwdfnkI1frSiSRMK1MofjKHf+MEx0SB6fjEFXL8fBDv1dKymBlOp4Qw== + +camelcase@^5.0.0, camelcase@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caniuse-api@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/caniuse-api/-/caniuse-api-3.0.0.tgz#5e4d90e2274961d46291997df599e3ed008ee4c0" - integrity sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw== - dependencies: - browserslist "^4.0.0" - caniuse-lite "^1.0.0" - lodash.memoize "^4.1.2" - lodash.uniq "^4.5.0" +camelcase@^6.2.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" + integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001032, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001265: +caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001366: + version "1.0.30001370" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001370.tgz#0a30d4f20d38b9e108cc5ae7cc62df9fe66cd5ba" + integrity sha512-3PDmaP56wz/qz7G508xzjx8C+MC2qEm4SYhSEzC9IBROo+dGXFWRuaXkWti0A9tuI00g+toiriVqxtWMgl350g== + +caniuse-lite@^1.0.30001265: version "1.0.30001267" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001267.tgz#b1cf2937175afc0570e4615fc2d2f9069fa0ed30" integrity sha512-r1mjTzAuJ9W8cPBGbbus8E0SKcUP7gn03R14Wk8FlAlqhH9hroy9nLqmpuXlfKEw/oILW+FGz47ipXV2O7x8lg== -canonical-path@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/canonical-path/-/canonical-path-1.0.0.tgz#fcb470c23958def85081856be7a86e904f180d1d" - integrity sha512-feylzsbDxi1gPZ1IjystzIQZagYYLvfKrSuygUCgf7z6x790VEzze5QEkdSV1U58RA7Hi0+v6fv4K54atOzATg== +caniuse-lite@^1.0.30001286: + version "1.0.30001312" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001312.tgz#e11eba4b87e24d22697dae05455d5aea28550d5f" + integrity sha512-Wiz1Psk2MEK0pX3rUzWaunLTZzqS2JYZFzNKqAiJGiuxIjRPLgV6+VDPOg6lQOUxmDwhTlh198JsTTi8Hzw6aQ== + +caniuse-lite@^1.0.30001332, caniuse-lite@^1.0.30001335: + version "1.0.30001346" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001346.tgz#e895551b46b9cc9cc9de852facd42f04839a8fbe" + integrity sha512-q6ibZUO2t88QCIPayP/euuDREq+aMAxFE5S70PkrLh0iTDj/zEhgvJRKC2+CvXY6EWc6oQwUR48lL5vCW6jiXQ== + +capture-exit@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-2.0.0.tgz#fb953bfaebeb781f62898239dabb426d08a509a4" + integrity sha512-PiT/hQmTonHhl/HFGN+Lx3JJUznrVYJ3+AQsnthneZbvW7x+f08Tk7yLJTLEOUvBTbduLeeBkxEaYXUOUrRq6g== + dependencies: + rsvp "^4.8.4" + +case-sensitive-paths-webpack-plugin@^2.3.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.4.0.tgz#db64066c6422eed2e08cc14b986ca43796dbc6d4" + integrity sha512-roIFONhcxog0JSSWbvVAh3OocukmSgpqOH6YpMkCvav/ySIV3JKg4Dc8vYtQjYi/UxpNE36r/9v+VqTQqgkYmw== caseless@~0.12.0: version "0.12.0" resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +ccount@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.1.0.tgz#246687debb6014735131be8abab2d93898f8d043" + integrity sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg== + +chalk@4.1.2, chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: + version "4.1.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" + integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== + dependencies: + ansi-styles "^4.1.0" + supports-color "^7.1.0" + chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -2463,7 +6329,7 @@ chalk@^1.1.1, chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" -chalk@^2.0.0, chalk@^2.3.0: +chalk@^2.0.0, chalk@^2.3.0, chalk@^2.4.1: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== @@ -2472,13 +6338,20 @@ chalk@^2.0.0, chalk@^2.3.0: escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.1.0, chalk@^4.1.1: - version "4.1.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" - integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" +character-entities-legacy@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz#94bc1845dce70a5bb9d2ecc748725661293d8fc1" + integrity sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA== + +character-entities@^1.0.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/character-entities/-/character-entities-1.2.4.tgz#e12c3939b7eaf4e5b15e7ad4c5e28e1d48c5b16b" + integrity sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw== + +character-reference-invalid@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz#083329cda0eae272ab3dbbf37e9a382c13af1560" + integrity sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg== chardet@^0.7.0: version "0.7.0" @@ -2508,6 +6381,31 @@ chartjs-color@^2.1.0: chartjs-color-string "^0.6.0" color-convert "^1.9.3" +cheerio-select@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cheerio-select/-/cheerio-select-2.1.0.tgz#4d8673286b8126ca2a8e42740d5e3c4884ae21b4" + integrity sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g== + dependencies: + boolbase "^1.0.0" + css-select "^5.1.0" + css-what "^6.1.0" + domelementtype "^2.3.0" + domhandler "^5.0.3" + domutils "^3.0.1" + +cheerio@^1.0.0-rc.10: + version "1.0.0-rc.12" + resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.12.tgz#788bf7466506b1c6bf5fae51d24a2c4d62e47683" + integrity sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q== + dependencies: + cheerio-select "^2.1.0" + dom-serializer "^2.0.0" + domhandler "^5.0.3" + domutils "^3.0.1" + htmlparser2 "^8.0.1" + parse5 "^7.0.0" + parse5-htmlparser2-tree-adapter "^7.0.0" + "chokidar@>=3.0.0 <4.0.0", chokidar@^3.0.0: version "3.5.2" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.2.tgz#dba3976fcadb016f66fd365021d91600d01c1e75" @@ -2542,20 +6440,55 @@ chokidar@^2.1.8: optionalDependencies: fsevents "^1.2.7" +chokidar@^3.4.1, chokidar@^3.4.2, chokidar@^3.5.2, chokidar@^3.5.3: + version "3.5.3" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.3.tgz#1cf37c8707b932bd1af1ae22c0432e2acd1903bd" + integrity sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw== + dependencies: + anymatch "~3.1.2" + braces "~3.0.2" + glob-parent "~5.1.2" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.6.0" + optionalDependencies: + fsevents "~2.3.2" + +chownr@^1.1.1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" + integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg== + chownr@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece" integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ== +chromatic@^6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/chromatic/-/chromatic-6.7.1.tgz#6548e51121269832709a203a55ce09e3bcfdda6d" + integrity sha512-iDVYnB24zPrMROvVBblIxlOaj5+vO1uDI0wRXObi5DVrkvCjDvHzsFfPwUoIHGiXE7f6tmw38ZZRI+LGarM9Ow== + dependencies: + "@types/webpack-env" "^1.17.0" + chrome-trace-event@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac" integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg== -circular-dependency-plugin@5.2.2: - version "5.2.2" - resolved "https://registry.yarnpkg.com/circular-dependency-plugin/-/circular-dependency-plugin-5.2.2.tgz#39e836079db1d3cf2f988dc48c5188a44058b600" - integrity sha512-g38K9Cm5WRwlaH6g03B9OEz/0qRizI+2I7n+Gz+L5DxXJAPAiWQvwlYNm1V1jkdpUv95bOe/ASm2vfi/G560jQ== +ci-info@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-2.0.0.tgz#67a9e964be31a51e15e5010d58e6f12834002f46" + integrity sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ== + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + integrity sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" class-utils@^0.3.5: version "0.3.6" @@ -2567,11 +6500,30 @@ class-utils@^0.3.5: isobject "^3.0.0" static-extend "^0.1.1" +clean-css@^4.2.3: + version "4.2.4" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-4.2.4.tgz#733bf46eba4e607c6891ea57c24a989356831178" + integrity sha512-EJUDT7nDVFDvaQgAo2G/PJvxmp1o/c6iXLbswsBbUFXi1Nr+AjA2cKmfbKDMjMvzEe75g3P6JkaDDAKk96A85A== + dependencies: + source-map "~0.6.0" + +clean-css@^5.2.2: + version "5.3.1" + resolved "https://registry.yarnpkg.com/clean-css/-/clean-css-5.3.1.tgz#d0610b0b90d125196a2894d35366f734e5d7aa32" + integrity sha512-lCr8OHhiWCTw4v8POJovCoh4T7I9U11yVsPjMWWnnMmp9ZowCxyad1Pathle/9HjaDp+fdQKjO9fQydE6RHTZg== + dependencies: + source-map "~0.6.0" + clean-stack@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== + cli-cursor@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-3.1.0.tgz#264305a7ae490d1d03bf0c9ba7c925d1753af307" @@ -2584,6 +6536,15 @@ cli-spinners@^2.5.0: resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.1.tgz#adc954ebe281c37a6319bfa401e6dd2488ffb70d" integrity sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g== +cli-table3@^0.6.1: + version "0.6.2" + resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.2.tgz#aaf5df9d8b5bf12634dc8b3040806a0c07120d2a" + integrity sha512-QyavHCaIC80cMivimWu4aWHilIpiDpfm3hGmqAmXVL1UsnbLuBSMd21hTX6VY4ZSDSM73ESLeF8TOYId3rBTbw== + dependencies: + string-width "^4.2.0" + optionalDependencies: + "@colors/colors" "1.5.0" + cli-width@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-3.0.0.tgz#a2f48437a2caa9a22436e794bf071ec9e61cedf6" @@ -2598,15 +6559,6 @@ cliui@^4.0.0: strip-ansi "^4.0.0" wrap-ansi "^2.0.0" -cliui@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/cliui/-/cliui-5.0.0.tgz#deefcfdb2e800784aa34f46fa08e06851c7bbbc5" - integrity sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA== - dependencies: - string-width "^3.1.0" - strip-ansi "^5.2.0" - wrap-ansi "^5.1.0" - cliui@^7.0.2: version "7.0.4" resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" @@ -2625,11 +6577,26 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" -clone@^1.0.2: +clone@^1.0.2, clone@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" integrity sha1-2jCcwmPfFZlMaIypAheco8fNfH4= +clsx@1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.0.tgz#62937c6adfea771247c34b54d320fb99624f5702" + integrity sha512-3avwM37fSK5oP6M5rQ9CNe99lwxhXDOeSWVPAOYF6OazUTgZCMb0yWlJpmdD74REy1gkEaFiub2ULv4fq9GUhA== + +clsx@^1.0.4: + version "1.2.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.2.1.tgz#0ddc4a20a549b59c93a4116bb26f5294ca17dc12" + integrity sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg== + +code-block-writer@^11.0.0: + version "11.0.2" + resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-11.0.2.tgz#263a1d5f982c640cda33d0704a8562057ae8b27d" + integrity sha512-goP2FghRVwp940jOvhtUrRDiSVU0h4Ah2jPX1gu2ueGW8boQmdQV4NwiHoM5MQQbUWLQuZopougO8+Ajljgpnw== + code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" @@ -2667,10 +6634,15 @@ codelyzer@^6.0.1: tslib "^1.10.0" zone.js "~0.10.3" +collapse-white-space@^1.0.2: + version "1.0.6" + resolved "https://registry.yarnpkg.com/collapse-white-space/-/collapse-white-space-1.0.6.tgz#e63629c0016665792060dbbeb79c42239d2c5287" + integrity sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ== + collection-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" - integrity sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA= + integrity sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw== dependencies: map-visit "^1.0.0" object-visit "^1.0.0" @@ -2699,32 +6671,62 @@ color-name@^1.0.0, color-name@~1.1.4: resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== -colord@^2.0.1, colord@^2.6: - version "2.8.0" - resolved "https://registry.yarnpkg.com/colord/-/colord-2.8.0.tgz#64fb7aa03de7652b5a39eee50271a104c2783b12" - integrity sha512-kNkVV4KFta3TYQv0bzs4xNwLaeag261pxgzGQSh4cQ1rEhYjcTJfFRP0SDlbhLONg0eSoLzrDd79PosjbltufA== +color-support@^1.1.2, color-support@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== colorette@^1.2.2: version "1.4.0" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g== -combined-stream@^1.0.6, combined-stream@~1.0.6: +colorette@^2.0.10: + version "2.0.16" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" + integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== + +colors@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" + integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== + +combined-stream@^1.0.6, combined-stream@^1.0.8, combined-stream@~1.0.6: version "1.0.8" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.8.tgz#c3d45a8b34fd730631a110a8a2520682b31d5a7f" integrity sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg== dependencies: delayed-stream "~1.0.0" +comma-separated-tokens@^1.0.0: + version "1.0.8" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" + integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== + commander@^2.11.0, commander@^2.12.1, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== -commander@^7.2.0: - version "7.2.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" - integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== +commander@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + +commander@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" + integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== + +commander@^8.3.0: + version "8.3.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" + integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== + +commander@^9.0.0: + version "9.4.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.4.0.tgz#bc4a40918fefe52e22450c111ecd6b7acce6f11c" + integrity sha512-sRPT+umqkz90UA8M1yqYfnHlZA7fF6nSphDtxeywPZ49ysjxDQybzk13CL+mXekDRG92skbcqCLVovuCusNmFw== commondir@^1.0.1: version "1.0.1" @@ -2761,29 +6763,59 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +concat-stream@^1.5.0, concat-stream@~1.6.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + connect-history-api-fallback@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz#8b32089359308d111115d81cad3fceab888f97bc" integrity sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg== -console-control-strings@^1.0.0, console-control-strings@~1.1.0: +connect@^3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/connect/-/connect-3.7.0.tgz#5d49348910caa5e07a01800b030d0c35f20484f8" + integrity sha512-ZqRXc+tZukToSNmh5C2iWMSoV3X1YUcPbqEM4DkEG5tNQXrQUZCNVGGv3IuicnkMtPfGf3Xtp8WCXs295iQ1pQ== + dependencies: + debug "2.6.9" + finalhandler "1.1.2" + parseurl "~1.3.3" + utils-merge "1.0.1" + +console-browserify@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" + integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== + +console-control-strings@^1.0.0, console-control-strings@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= -content-disposition@0.5.3: - version "0.5.3" - resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" - integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + integrity sha512-xFxOwqIzR/e1k1gLiWEophSCMqXcwVHIH7akf7b/vxcUeGunlj3hvZaaqxwHsTgn+IndtkQJgSztIDWeumWJDQ== + +content-disposition@0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.4.tgz#8b82b4efac82512a02bb0b1dcec9d2c5e8eb5bfe" + integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== dependencies: - safe-buffer "5.1.2" + safe-buffer "5.2.1" content-type@~1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.4.tgz#e138cc75e040c727b1966fe5e5f8c9aee256fe3b" integrity sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA== -convert-source-map@^1.5.1, convert-source-map@^1.7.0: +convert-source-map@^1.4.0, convert-source-map@^1.5.1, convert-source-map@^1.7.0: version "1.8.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" integrity sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA== @@ -2795,10 +6827,10 @@ cookie-signature@1.0.6: resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha1-4wOogrNCzD7oylE6eZmXNNqzriw= -cookie@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.0.tgz#beb437e7022b3b6d49019d088665303ebe9c14ba" - integrity sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg== +cookie@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== cookiejar@^2.1.0: version "2.1.3" @@ -2812,42 +6844,69 @@ copy-anything@^2.0.1: dependencies: is-what "^3.12.0" +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + integrity sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A== + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + copy-descriptor@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" - integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= + integrity sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw== -copy-webpack-plugin@9.0.1: - version "9.0.1" - resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-9.0.1.tgz#b71d21991599f61a4ee00ba79087b8ba279bbb59" - integrity sha512-14gHKKdYIxF84jCEgPgYXCPpldbwpxxLbCmA7LReY7gvbaT555DgeBWBgBZM116tv/fO6RRJrsivBqRyRlukhw== +copy-webpack-plugin@10.2.4: + version "10.2.4" + resolved "https://registry.yarnpkg.com/copy-webpack-plugin/-/copy-webpack-plugin-10.2.4.tgz#6c854be3fdaae22025da34b9112ccf81c63308fe" + integrity sha512-xFVltahqlsRcyyJqQbDY6EYTtyQZF9rf+JPjwHObLdPFMEISqkFkr7mFoVOC6BfYS/dNThyoQKvziugm+OnwBg== dependencies: - fast-glob "^3.2.5" - glob-parent "^6.0.0" - globby "^11.0.3" + fast-glob "^3.2.7" + glob-parent "^6.0.1" + globby "^12.0.2" normalize-path "^3.0.0" - p-limit "^3.1.0" - schema-utils "^3.0.0" + schema-utils "^4.0.0" serialize-javascript "^6.0.0" -core-js-compat@^3.15.0, core-js-compat@^3.16.2: - version "3.18.3" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.18.3.tgz#e0e7e87abc55efb547e7fa19169e45fa9df27a67" - integrity sha512-4zP6/y0a2RTHN5bRGT7PTq9lVt3WzvffTNjqnTKsXhkAYNDTkdCLOIfAdOLcQ/7TDdyRj3c+NeHe1NmF1eDScw== +core-js-compat@^3.21.0: + version "3.21.1" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.21.1.tgz#cac369f67c8d134ff8f9bd1623e3bc2c42068c82" + integrity sha512-gbgX5AUvMb8gwxC7FLVWYT7Kkgu/y7+h/h1X43yJkNqhlK2fuYyQimqvKGNZFAY6CKii/GFKJ2cp/1/42TN36g== dependencies: - browserslist "^4.17.3" + browserslist "^4.19.1" semver "7.0.0" -core-js@3.16.0: - version "3.16.0" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.16.0.tgz#1d46fb33720bc1fa7f90d20431f36a5540858986" - integrity sha512-5+5VxRFmSf97nM8Jr2wzOwLqRo6zphH2aX+7KsAUONObyzakDNq2G/bgbhinxB4PoV9L3aXQYhiDKyIKWd2c8g== +core-js-compat@^3.22.1: + version "3.22.8" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.22.8.tgz#46fa34ce1ddf742acd7f95f575f66bbb21e05d62" + integrity sha512-pQnwg4xtuvc2Bs/5zYQPaEYYSuTxsF7LBWF0SvnVhthZo/Qe+rJpcEekrdNK5DWwDJ0gv0oI9NNX5Mppdy0ctg== + dependencies: + browserslist "^4.20.3" + semver "7.0.0" + +core-js-compat@^3.8.1: + version "3.24.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.24.0.tgz#885958fac38bf3f4464a90f2663b4620f6aee6e3" + integrity sha512-F+2E63X3ff/nj8uIrf8Rf24UDGIz7p838+xjEp+Bx3y8OWXj+VTPPZNCtdqovPaS9o7Tka5mCH01Zn5vOd6UQg== + dependencies: + browserslist "^4.21.2" + semver "7.0.0" core-js@^2.5.4: version "2.6.12" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== +core-js@^3.0.4, core-js@^3.6.5, core-js@^3.8.2: + version "3.24.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.24.0.tgz#4928d4e99c593a234eb1a1f9abd3122b04d3ac57" + integrity sha512-IeOyT8A6iK37Ep4kZDD423mpi6JfPRoPUdQwEWYiGolvn4o6j2diaRzNfDfpTdu3a5qMbrGUzKUpYpRY8jXCkQ== + core-util-is@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -2858,7 +6917,26 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cosmiconfig@^7.0.0: +cors@latest: + version "2.8.5" + resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + +cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" + +cosmiconfig@^7.0.0, cosmiconfig@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d" integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ== @@ -2869,15 +6947,72 @@ cosmiconfig@^7.0.0: path-type "^4.0.0" yaml "^1.10.0" -critters@0.0.10: - version "0.0.10" - resolved "https://registry.yarnpkg.com/critters/-/critters-0.0.10.tgz#edd0e962fc5af6c4adb6dbf1a71bae2d3f917000" - integrity sha512-p5VKhP1803+f+0Jq5P03w1SbiHtpAKm+1EpJHkiPxQPq0Vu9QLZHviJ02GRrWi0dlcJqrmzMWInbwp4d22RsGw== +cp-file@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/cp-file/-/cp-file-7.0.0.tgz#b9454cfd07fe3b974ab9ea0e5f29655791a9b8cd" + integrity sha512-0Cbj7gyvFVApzpK/uhCtQ/9kE9UnYpxMzaq5nQQC/Dh4iaj5fxp7iEFIullrYwzj8nf0qnsI1Qsx34hAeAebvw== + dependencies: + graceful-fs "^4.1.2" + make-dir "^3.0.0" + nested-error-stacks "^2.0.0" + p-event "^4.1.0" + +cpy@^8.1.2: + version "8.1.2" + resolved "https://registry.yarnpkg.com/cpy/-/cpy-8.1.2.tgz#e339ea54797ad23f8e3919a5cffd37bfc3f25935" + integrity sha512-dmC4mUesv0OYH2kNFEidtf/skUwv4zePmGeepjyyJ0qTo5+8KhA1o99oIAwVVLzQMAeDJml74d6wPPKb6EZUTg== + dependencies: + arrify "^2.0.1" + cp-file "^7.0.0" + globby "^9.2.0" + has-glob "^1.0.0" + junk "^3.1.0" + nested-error-stacks "^2.1.0" + p-all "^2.1.0" + p-filter "^2.1.0" + p-map "^3.0.0" + +create-ecdh@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.4.tgz#d6e7f4bffa66736085a0762fd3a632684dabcc4e" + integrity sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A== + dependencies: + bn.js "^4.1.0" + elliptic "^6.5.3" + +create-hash@^1.1.0, create-hash@^1.1.2, create-hash@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + integrity sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg== + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.4, create-hmac@^1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + integrity sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg== + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +critters@0.0.16: + version "0.0.16" + resolved "https://registry.yarnpkg.com/critters/-/critters-0.0.16.tgz#ffa2c5561a65b43c53b940036237ce72dcebfe93" + integrity sha512-JwjgmO6i3y6RWtLYmXwO5jMd+maZt8Tnfu7VVISmEWyQqfLpB8soBswf8/2bu6SBXxtKA68Al3c+qIG1ApT68A== dependencies: chalk "^4.1.0" - css "^3.0.0" + css-select "^4.2.0" parse5 "^6.0.1" parse5-htmlparser2-tree-adapter "^6.0.1" + postcss "^8.3.7" pretty-bytes "^5.3.0" cross-spawn@^6.0.0: @@ -2891,84 +7026,137 @@ cross-spawn@^6.0.0: shebang-command "^1.2.0" which "^1.2.9" -css-blank-pseudo@^0.1.4: - version "0.1.4" - resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-0.1.4.tgz#dfdefd3254bf8a82027993674ccf35483bfcb3c5" - integrity sha512-LHz35Hr83dnFeipc7oqFDmsjHdljj3TQtxGGiNWSOsTLIAubSm4TEz8qCaKFpk7idaQ1GfWscF4E6mgpBysA1w== +cross-spawn@^7.0.0, cross-spawn@^7.0.3: + version "7.0.3" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" + integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== dependencies: - postcss "^7.0.5" + path-key "^3.1.0" + shebang-command "^2.0.0" + which "^2.0.1" -css-color-names@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/css-color-names/-/css-color-names-1.0.1.tgz#6ff7ee81a823ad46e020fa2fd6ab40a887e2ba67" - integrity sha512-/loXYOch1qU1biStIFsHH8SxTmOseh1IJqFvy8IujXOm1h+QjUdDhkzOrR5HG8K8mlxREj0yfi8ewCHx0eMxzA== - -css-declaration-sorter@^6.0.3: - version "6.1.3" - resolved "https://registry.yarnpkg.com/css-declaration-sorter/-/css-declaration-sorter-6.1.3.tgz#e9852e4cf940ba79f509d9425b137d1f94438dc2" - integrity sha512-SvjQjNRZgh4ULK1LDJ2AduPKUKxIqmtU7ZAyi47BTV+M90Qvxr9AB6lKlLbDUfXqI9IQeYA8LbAsCZPpJEV3aA== +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + integrity sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg== dependencies: - timsort "^0.3.0" + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" -css-has-pseudo@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-0.10.0.tgz#3c642ab34ca242c59c41a125df9105841f6966ee" - integrity sha512-Z8hnfsZu4o/kt+AuFzeGpLVhFOGO9mluyHBaA2bA8aCGTwah5sT3WV/fTHH8UNZUytOIImuGPrl/prlb4oX4qQ== +crypto-js@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-4.1.1.tgz#9e485bcf03521041bd85844786b83fb7619736cf" + integrity sha512-o2JlM7ydqd3Qk9CA0L4NL6mTzU2sdx96a+oOfPu8Mkl/PK51vSyoi8/rQ8NknZtk44vq15lmhAj9CIAGwgeWKw== + +css-blank-pseudo@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/css-blank-pseudo/-/css-blank-pseudo-3.0.3.tgz#36523b01c12a25d812df343a32c322d2a2324561" + integrity sha512-VS90XWtsHGqoM0t4KpH053c4ehxZ2E6HtGI7x68YFV0pTo/QmkV/YFA+NnlvK8guxZVNWGQhVNJGC39Q8XF4OQ== dependencies: - postcss "^7.0.6" - postcss-selector-parser "^5.0.0-rc.4" + postcss-selector-parser "^6.0.9" -css-loader@6.2.0: - version "6.2.0" - resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.2.0.tgz#9663d9443841de957a3cb9bcea2eda65b3377071" - integrity sha512-/rvHfYRjIpymZblf49w8jYcRo2y9gj6rV8UroHGmBxKrIyGLokpycyKzp9OkitvqT29ZSpzJ0Ic7SpnJX3sC8g== +css-has-pseudo@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/css-has-pseudo/-/css-has-pseudo-3.0.4.tgz#57f6be91ca242d5c9020ee3e51bbb5b89fc7af73" + integrity sha512-Vse0xpR1K9MNlp2j5w1pgWIJtm1a8qS0JwS9goFYcImjlHEmywP9VUF05aGBXzGpDJF86QXk4L0ypBmwPhGArw== + dependencies: + postcss-selector-parser "^6.0.9" + +css-loader@6.7.1: + version "6.7.1" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-6.7.1.tgz#e98106f154f6e1baf3fc3bc455cb9981c1d5fd2e" + integrity sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw== dependencies: icss-utils "^5.1.0" + postcss "^8.4.7" + postcss-modules-extract-imports "^3.0.0" + postcss-modules-local-by-default "^4.0.0" + postcss-modules-scope "^3.0.0" + postcss-modules-values "^4.0.0" + postcss-value-parser "^4.2.0" + semver "^7.3.5" + +css-loader@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" + integrity sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ== + dependencies: + camelcase "^5.3.1" + cssesc "^3.0.0" + icss-utils "^4.1.1" + loader-utils "^1.2.3" + normalize-path "^3.0.0" + postcss "^7.0.32" + postcss-modules-extract-imports "^2.0.0" + postcss-modules-local-by-default "^3.0.2" + postcss-modules-scope "^2.2.0" + postcss-modules-values "^3.0.0" + postcss-value-parser "^4.1.0" + schema-utils "^2.7.0" + semver "^6.3.0" + +css-loader@^5.0.1: + version "5.2.7" + resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-5.2.7.tgz#9b9f111edf6fb2be5dc62525644cbc9c232064ae" + integrity sha512-Q7mOvpBNBG7YrVGMxRxcBJZFL75o+cH2abNASdibkj/fffYD8qWbInZrD0S9ccI6vZclF3DsHE7njGlLtaHbhg== + dependencies: + icss-utils "^5.1.0" + loader-utils "^2.0.0" postcss "^8.2.15" postcss-modules-extract-imports "^3.0.0" postcss-modules-local-by-default "^4.0.0" postcss-modules-scope "^3.0.0" postcss-modules-values "^4.0.0" postcss-value-parser "^4.1.0" + schema-utils "^3.0.0" semver "^7.3.5" -css-minimizer-webpack-plugin@3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.0.2.tgz#8fadbdf10128cb40227bff275a4bb47412534245" - integrity sha512-B3I5e17RwvKPJwsxjjWcdgpU/zqylzK1bPVghcmpFHRL48DXiBgrtqz1BJsn68+t/zzaLp9kYAaEDvQ7GyanFQ== - dependencies: - cssnano "^5.0.6" - jest-worker "^27.0.2" - p-limit "^3.0.2" - postcss "^8.3.5" - schema-utils "^3.0.0" - serialize-javascript "^6.0.0" - source-map "^0.6.1" - -css-parse@~2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/css-parse/-/css-parse-2.0.0.tgz#a468ee667c16d81ccf05c58c38d2a97c780dbfd4" - integrity sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q= - dependencies: - css "^2.0.0" - -css-prefers-color-scheme@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-3.1.1.tgz#6f830a2714199d4f0d0d0bb8a27916ed65cff1f4" - integrity sha512-MTu6+tMs9S3EUqzmqLXEcgNRbNkkD/TGFvowpeoWJn5Vfq7FMgsmRQs9X5NXAURiOBmOxm/lLjsDNXDE6k9bhg== - dependencies: - postcss "^7.0.5" +css-prefers-color-scheme@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/css-prefers-color-scheme/-/css-prefers-color-scheme-6.0.3.tgz#ca8a22e5992c10a5b9d315155e7caee625903349" + integrity sha512-4BqMbZksRkJQx2zAjrokiGMd07RqOa2IxIrrN10lyBe9xhn9DEvjUK79J6jkeiv9D9hQFXKb6g1jwU62jziJZA== css-select@^4.1.3: - version "4.1.3" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.1.3.tgz#a70440f70317f2669118ad74ff105e65849c7067" - integrity sha512-gT3wBNd9Nj49rAbmtFHj1cljIAOLYSX1nZ8CB7TBO3INYckygm5B7LISU/szY//YmdiSLbJvDLOx9VnMVpMBxA== + version "4.3.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" + integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== dependencies: boolbase "^1.0.0" - css-what "^5.0.0" - domhandler "^4.2.0" - domutils "^2.6.0" - nth-check "^2.0.0" + css-what "^6.0.1" + domhandler "^4.3.1" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-select@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.2.1.tgz#9e665d6ae4c7f9d65dbe69d0316e3221fb274cdd" + integrity sha512-/aUslKhzkTNCQUB2qTX84lVmfia9NyjP3WpDGtj/WxhwBzWBYUV3DgUpurHTme8UTPcPlAD1DJ+b0nN/t50zDQ== + dependencies: + boolbase "^1.0.0" + css-what "^5.1.0" + domhandler "^4.3.0" + domutils "^2.8.0" + nth-check "^2.0.1" + +css-select@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/css-select/-/css-select-5.1.0.tgz#b8ebd6554c3637ccc76688804ad3f6a6fdaea8a6" + integrity sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg== + dependencies: + boolbase "^1.0.0" + css-what "^6.1.0" + domhandler "^5.0.2" + domutils "^3.0.1" + nth-check "^2.0.1" css-selector-tokenizer@^0.7.0, css-selector-tokenizer@^0.7.1: version "0.7.3" @@ -2978,28 +7166,15 @@ css-selector-tokenizer@^0.7.0, css-selector-tokenizer@^0.7.1: cssesc "^3.0.0" fastparse "^1.1.2" -css-tree@^1.1.2, css-tree@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" - integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== - dependencies: - mdn-data "2.0.14" - source-map "^0.6.1" - -css-what@^5.0.0: +css-what@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/css-what/-/css-what-5.1.0.tgz#3f7b707aadf633baf62c2ceb8579b545bb40f7fe" integrity sha512-arSMRWIIFY0hV8pIxZMEfmMI47Wj3R/aWpZDDxWYCPEiOMv6tfOrnpDtgxBYPEQD4V0Y/958+1TdC3iWTFcUPw== -css@^2.0.0: - version "2.2.4" - resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" - integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw== - dependencies: - inherits "^2.0.3" - source-map "^0.6.1" - source-map-resolve "^0.5.2" - urix "^0.1.0" +css-what@^6.0.1, css-what@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" + integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== css@^3.0.0: version "3.0.0" @@ -3017,83 +7192,51 @@ cssauron@^1.4.0: dependencies: through X.X.X -cssdb@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-4.4.0.tgz#3bf2f2a68c10f5c6a08abd92378331ee803cddb0" - integrity sha512-LsTAR1JPEM9TpGhl/0p3nQecC2LJ0kD8X5YARu1hk/9I1gril5vDtMZyNxcEpxxDj34YNck/ucjuoUd66K03oQ== - -cssesc@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-2.0.0.tgz#3b13bd1bb1cb36e1bcb5a4dcd27f54c5dcb35703" - integrity sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg== +cssdb@^6.6.1: + version "6.6.3" + resolved "https://registry.yarnpkg.com/cssdb/-/cssdb-6.6.3.tgz#1f331a2fab30c18d9f087301e6122a878bb1e505" + integrity sha512-7GDvDSmE+20+WcSMhP17Q1EVWUrLlbxxpMDqG731n8P99JhnQZHR9YvtjPvEHfjFUjvQJvdpKCjlKOX+xe4UVA== cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" integrity sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg== -cssnano-preset-default@^5.1.4: - version "5.1.4" - resolved "https://registry.yarnpkg.com/cssnano-preset-default/-/cssnano-preset-default-5.1.4.tgz#359943bf00c5c8e05489f12dd25f3006f2c1cbd2" - integrity sha512-sPpQNDQBI3R/QsYxQvfB4mXeEcWuw0wGtKtmS5eg8wudyStYMgKOQT39G07EbW1LB56AOYrinRS9f0ig4Y3MhQ== - dependencies: - css-declaration-sorter "^6.0.3" - cssnano-utils "^2.0.1" - postcss-calc "^8.0.0" - postcss-colormin "^5.2.0" - postcss-convert-values "^5.0.1" - postcss-discard-comments "^5.0.1" - postcss-discard-duplicates "^5.0.1" - postcss-discard-empty "^5.0.1" - postcss-discard-overridden "^5.0.1" - postcss-merge-longhand "^5.0.2" - postcss-merge-rules "^5.0.2" - postcss-minify-font-values "^5.0.1" - postcss-minify-gradients "^5.0.2" - postcss-minify-params "^5.0.1" - postcss-minify-selectors "^5.1.0" - postcss-normalize-charset "^5.0.1" - postcss-normalize-display-values "^5.0.1" - postcss-normalize-positions "^5.0.1" - postcss-normalize-repeat-style "^5.0.1" - postcss-normalize-string "^5.0.1" - postcss-normalize-timing-functions "^5.0.1" - postcss-normalize-unicode "^5.0.1" - postcss-normalize-url "^5.0.2" - postcss-normalize-whitespace "^5.0.1" - postcss-ordered-values "^5.0.2" - postcss-reduce-initial "^5.0.1" - postcss-reduce-transforms "^5.0.1" - postcss-svgo "^5.0.2" - postcss-unique-selectors "^5.0.1" +csstype@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.0.tgz#4ddcac3718d787cf9df0d1b7d15033925c8f29f2" + integrity sha512-uX1KG+x9h5hIJsaKR9xHUeUraxf8IODOwq9JLNPq6BwB04a/xgpq3rcx47l5BZu5zBPlgD342tdke3Hom/nJRA== -cssnano-utils@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/cssnano-utils/-/cssnano-utils-2.0.1.tgz#8660aa2b37ed869d2e2f22918196a9a8b6498ce2" - integrity sha512-i8vLRZTnEH9ubIyfdZCAdIdgnHAUeQeByEeQ2I7oTilvP9oHO6RScpeq3GsFUVqeB8uZgOQ9pw8utofNn32hhQ== - -cssnano@^5.0.6: - version "5.0.8" - resolved "https://registry.yarnpkg.com/cssnano/-/cssnano-5.0.8.tgz#39ad166256980fcc64faa08c9bb18bb5789ecfa9" - integrity sha512-Lda7geZU0Yu+RZi2SGpjYuQz4HI4/1Y+BhdD0jL7NXAQ5larCzVn+PUGuZbDMYz904AXXCOgO5L1teSvgu7aFg== +currently-unhandled@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea" + integrity sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng== dependencies: - cssnano-preset-default "^5.1.4" - is-resolvable "^1.1.0" - lilconfig "^2.0.3" - yaml "^1.10.2" + array-find-index "^1.0.1" -csso@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" - integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== +cyclist@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" + integrity sha512-NJGVKPS81XejHcLhaLJS7plab0fK3slPh11mESeeDq2W4ZI5kUKK/LRRdVDvjJseojbPB7ZwjnyOybg3Igea/A== + +d@1, d@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/d/-/d-1.0.1.tgz#8698095372d58dbee346ffd0c7093f99f8f9eb5a" + integrity sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA== dependencies: - css-tree "^1.1.2" + es5-ext "^0.10.50" + type "^1.0.1" damerau-levenshtein@^1.0.4: version "1.0.7" resolved "https://registry.yarnpkg.com/damerau-levenshtein/-/damerau-levenshtein-1.0.7.tgz#64368003512a1a6992593741a09a9d31a836f55d" integrity sha512-VvdQIPGdWP0SqFXghj79Wf/5LArmreyMsGLa6FG6iC4t3j7j5s71TrwWmT/4akbDQIqjfACkLZmjXhA7g2oUZw== +dash-ast@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/dash-ast/-/dash-ast-2.0.1.tgz#8d0fd2e601c59bf874cc22877ee7dd889f54dee8" + integrity sha512-5TXltWJGc+RdnabUGzhRae1TRq6m4gr+3K2wQX0is5/F2yS6MJXJvLyI3ErAnsAXuJoGqvfVD5icRgim07DrxQ== + dashdash@^1.12.0: version "1.14.1" resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" @@ -3101,35 +7244,49 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -debug@2.6.9, debug@^2.2.0, debug@^2.3.3: +debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA== dependencies: ms "2.0.0" -debug@4, debug@4.3.2, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: +debug@4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1: version "4.3.2" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== dependencies: ms "2.1.2" -debug@^3.1.0, debug@^3.1.1, debug@^3.2.6: +debug@4.3.4, debug@^4.3.3: + version "4.3.4" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" + integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== + dependencies: + ms "2.1.2" + +debug@^3.0.0, debug@^3.1.0, debug@^3.2.6: version "3.2.7" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a" integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ== dependencies: ms "^2.1.1" -debug@~3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" - integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== +debug@^4.3.2: + version "4.3.3" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.3.tgz#04266e0b70a98d4462e6e288e38259213332b664" + integrity sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q== dependencies: - ms "2.0.0" + ms "2.1.2" -decamelize@^1.2.0: +decache@^4.6.1: + version "4.6.1" + resolved "https://registry.yarnpkg.com/decache/-/decache-4.6.1.tgz#5928bfab97a6fcf22a65047a3d07999af36efaf0" + integrity sha512-ohApBM8u9ygepJCjgBrEZSSxPjc0T/PJkD+uNyxXPkqudyUpdXpwJYp0VISm2WrPVzASU6DZyIi6BWdyw7uJ2Q== + dependencies: + callsite "^1.0.0" + +decamelize@^1.1.2, decamelize@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" integrity sha1-9lNNFRSCabIDUue+4m9QH5oZEpA= @@ -3139,7 +7296,7 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= -deep-equal@^1.0.1: +deep-equal@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a" integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g== @@ -3151,13 +7308,31 @@ deep-equal@^1.0.1: object-keys "^1.1.1" regexp.prototype.flags "^1.2.0" -default-gateway@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-4.2.0.tgz#167104c7500c2115f6dd69b0a536bb8ed720552b" - integrity sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA== +deep-is@~0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.4.tgz#a6f2dce612fadd2ef1f519b73551f17e85199831" + integrity sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ== + +deepmerge@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.2.2.tgz#44d2ea3679b8f4d4ffba33f03d865fc1e7bf4955" + integrity sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg== + +default-browser-id@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/default-browser-id/-/default-browser-id-1.0.4.tgz#e59d09a5d157b828b876c26816e61c3d2a2c203a" + integrity sha512-qPy925qewwul9Hifs+3sx1ZYn14obHxpkX+mPD369w4Rzg+YkJBgi3SOvwUq81nWSjqGUegIgEPwD8u+HUnxlw== dependencies: - execa "^1.0.0" - ip-regex "^2.1.0" + bplist-parser "^0.1.0" + meow "^3.1.0" + untildify "^2.0.0" + +default-gateway@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/default-gateway/-/default-gateway-6.0.3.tgz#819494c888053bdb743edbf343d6cdf7f2943a71" + integrity sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg== + dependencies: + execa "^5.0.0" defaults@^1.0.3: version "1.0.3" @@ -3171,6 +7346,14 @@ define-lazy-prop@^2.0.0: resolved "https://registry.yarnpkg.com/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz#3f7ae421129bcaaac9bc74905c98a0009ec9ee7f" integrity sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og== +define-properties@^1.1.2, define-properties@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.4.tgz#0b14d7bd7fbeb2f3572c3a7eda80ea5d57fb05b1" + integrity sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA== + dependencies: + has-property-descriptors "^1.0.0" + object-keys "^1.1.1" + define-properties@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" @@ -3181,14 +7364,14 @@ define-properties@^1.1.3: define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" - integrity sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY= + integrity sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA== dependencies: is-descriptor "^0.1.0" define-property@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" - integrity sha1-dp66rz9KY6rTr56NMEybvnm/sOY= + integrity sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA== dependencies: is-descriptor "^1.0.0" @@ -3213,19 +7396,6 @@ del@^2.2.0: pinkie-promise "^2.0.0" rimraf "^2.2.8" -del@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/del/-/del-4.1.1.tgz#9e8f117222ea44a31ff3a156c049b99052a9f0b4" - integrity sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ== - dependencies: - "@types/glob" "^7.1.1" - globby "^6.1.0" - is-path-cwd "^2.0.0" - is-path-in-cwd "^2.0.0" - p-map "^2.0.0" - pify "^4.0.1" - rimraf "^2.6.3" - delayed-stream@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" @@ -3236,6 +7406,11 @@ delegates@^1.0.0: resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" integrity sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o= +depd@2.0.0, depd@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" + integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== + depd@^1.1.2, depd@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.2.tgz#9bcd52e14c097763e749b274c4346ed2e560b5a9" @@ -3246,16 +7421,51 @@ dependency-graph@^0.11.0: resolved "https://registry.yarnpkg.com/dependency-graph/-/dependency-graph-0.11.0.tgz#ac0ce7ed68a54da22165a85e97a01d53f5eb2e27" integrity sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg== -destroy@~1.0.4: - version "1.0.4" - resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" - integrity sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA= +des.js@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.1.tgz#5382142e1bdc53f85d86d53e5f4aa7deb91e0843" + integrity sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA== + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.2.0.tgz#4803735509ad8be552934c67df614f94e66fa015" + integrity sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg== + +detab@2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/detab/-/detab-2.0.4.tgz#b927892069aff405fbb9a186fe97a44a92a94b43" + integrity sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g== + dependencies: + repeat-string "^1.5.4" detect-node@^2.0.4: version "2.1.0" resolved "https://registry.yarnpkg.com/detect-node/-/detect-node-2.1.0.tgz#c9c70775a49c3d03bc2c06d9a73be550f978f8b1" integrity sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g== +detect-package-manager@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/detect-package-manager/-/detect-package-manager-2.0.1.tgz#6b182e3ae5e1826752bfef1de9a7b828cffa50d8" + integrity sha512-j/lJHyoLlWi6G1LDdLgvUtz60Zo5GEj+sVYtTVXnYLDPuzgC3llMxonXym9zIwhhUII8vjdw0LXxavpLqTbl1A== + dependencies: + execa "^5.1.1" + +detect-port@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/detect-port/-/detect-port-1.3.0.tgz#d9c40e9accadd4df5cac6a782aefd014d573d1f1" + integrity sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ== + dependencies: + address "^1.0.1" + debug "^2.6.0" + +dfa@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/dfa/-/dfa-1.2.0.tgz#96ac3204e2d29c49ea5b57af8d92c2ae12790657" + integrity sha512-ED3jP8saaweFTjeGX8HQPjeC1YYyZs98jGNZx6IiBvxW7JG5v492kamAQB3m2wop07CvU/RQmzcKr6bgcC5D/Q== + diff@^3.1.0: version "3.5.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" @@ -3266,11 +7476,27 @@ diff@^4.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-4.0.2.tgz#60f3aecb89d5fae520c11aa19efc2bb982aade7d" integrity sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A== +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + integrity sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg== + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + dijkstrajs@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/dijkstrajs/-/dijkstrajs-1.0.2.tgz#2e48c0d3b825462afe75ab4ad5e829c8ece36257" integrity sha512-QV6PMaHTCNmKSeP6QoXhVTw9snc9VD8MulTT0Bd99Pacp4SS1cjcrYPgBPmibqKVtMJJfqC6XvOXgPMEEPH/fg== +dir-glob@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.2.2.tgz#fa09f0694153c8918b18ba0deafae94769fc50c4" + integrity sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw== + dependencies: + path-type "^3.0.0" + dir-glob@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-3.0.1.tgz#56dbf73d992a4a93ba1584f4534063fd2e41717f" @@ -3283,20 +7509,31 @@ dns-equal@^1.0.0: resolved "https://registry.yarnpkg.com/dns-equal/-/dns-equal-1.0.0.tgz#b39e7f1da6eb0a75ba9c17324b34753c47e0654d" integrity sha1-s55/HabrCnW6nBcySzR1PEfgZU0= -dns-packet@^1.3.1: - version "1.3.4" - resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-1.3.4.tgz#e3455065824a2507ba886c55a89963bb107dec6f" - integrity sha512-BQ6F4vycLXBvdrJZ6S3gZewt6rcrks9KBgM9vrhW+knGRqc8uEdT7fuCwloc7nny5xNoMJ17HGH0R/6fpo8ECA== +dns-packet@^5.2.2: + version "5.3.1" + resolved "https://registry.yarnpkg.com/dns-packet/-/dns-packet-5.3.1.tgz#eb94413789daec0f0ebe2fcc230bdc9d7c91b43d" + integrity sha512-spBwIj0TK0Ey3666GwIdWVfUpLyubpU53BTCu8iPn4r4oXd9O14Hjg3EHw3ts2oed77/SeckunUYCyRlSngqHw== dependencies: - ip "^1.1.0" - safe-buffer "^5.0.1" + "@leichtgewicht/ip-codec" "^2.0.1" -dns-txt@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/dns-txt/-/dns-txt-2.0.2.tgz#b91d806f5d27188e4ab3e7d107d881a1cc4642b6" - integrity sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY= +doctrine@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-3.0.0.tgz#addebead72a6574db783639dc87a121773973961" + integrity sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w== dependencies: - buffer-indexof "^1.0.0" + esutils "^2.0.2" + +dom-accessibility-api@^0.5.9: + version "0.5.14" + resolved "https://registry.yarnpkg.com/dom-accessibility-api/-/dom-accessibility-api-0.5.14.tgz#56082f71b1dc7aac69d83c4285eef39c15d93f56" + integrity sha512-NMt+m9zFMPZe0JcY9gN224Qvk6qLIdqex29clBvc/y75ZBX9YA9wNK3frsYvu2DI1xcCIwxwnX+TlsJ2DSOADg== + +dom-converter@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/dom-converter/-/dom-converter-0.2.0.tgz#6721a9daee2e293682955b6afe416771627bb768" + integrity sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA== + dependencies: + utila "~0.4" dom-serializer@^1.0.1: version "1.3.2" @@ -3307,11 +7544,42 @@ dom-serializer@^1.0.1: domhandler "^4.2.0" entities "^2.0.0" +dom-serializer@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-2.0.0.tgz#e41b802e1eedf9f6cae183ce5e622d789d7d8e53" + integrity sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + entities "^4.2.0" + +dom-walk@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" + integrity sha512-6QvTW9mrGeIegrFXdtQi9pk7O/nSK6lSdXW2eqUspN5LWD7UTji2Fqw5V2YLjBpHEoU9Xl/eUWNpDeZvoyOv2w== + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + integrity sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA== + domelementtype@^2.0.1, domelementtype@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== +domelementtype@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.3.0.tgz#5c45e8e869952626331d7aab326d01daf65d589d" + integrity sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw== + +domhandler@^4.0.0, domhandler@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" + integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== + dependencies: + domelementtype "^2.2.0" + domhandler@^4.2.0: version "4.2.2" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.2.2.tgz#e825d721d19a86b8c201a35264e226c678ee755f" @@ -3319,12 +7587,31 @@ domhandler@^4.2.0: dependencies: domelementtype "^2.2.0" +domhandler@^4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.0.tgz#16c658c626cf966967e306f966b431f77d4a5626" + integrity sha512-fC0aXNQXqKSFTr2wDNZDhsEYjCiYsDWl3D01kwt25hm1YIPyDGHvvi3rw+PLqHAl/m71MaiF7d5zvBr0p5UB2g== + dependencies: + domelementtype "^2.2.0" + +domhandler@^5.0.1, domhandler@^5.0.2, domhandler@^5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-5.0.3.tgz#cc385f7f751f1d1fc650c21374804254538c7d31" + integrity sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w== + dependencies: + domelementtype "^2.3.0" + domino@^2.1.2: version "2.1.6" resolved "https://registry.yarnpkg.com/domino/-/domino-2.1.6.tgz#fe4ace4310526e5e7b9d12c7de01b7f485a57ffe" integrity sha512-3VdM/SXBZX2omc9JF9nOPCtDaYQ67BGp5CoLpIQlO2KCAPETs8TcDHacF26jXadGbvUteZzRTeos2fhID5+ucQ== -domutils@^2.6.0: +dommatrix@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/dommatrix/-/dommatrix-1.0.3.tgz#e7c18e8d6f3abdd1fef3dd4aa74c4d2e620a0525" + integrity sha512-l32Xp/TLgWb8ReqbVJAFIvXmY7go4nTxxlWiAFyhoQw9RKEOHBZNnyGvJWqDVSPmq3Y9HlM4npqF/T6VMOXhww== + +domutils@^2.5.2, domutils@^2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== @@ -3333,6 +7620,60 @@ domutils@^2.6.0: domelementtype "^2.2.0" domhandler "^4.2.0" +domutils@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/domutils/-/domutils-3.0.1.tgz#696b3875238338cb186b6c0612bd4901c89a4f1c" + integrity sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q== + dependencies: + dom-serializer "^2.0.0" + domelementtype "^2.3.0" + domhandler "^5.0.1" + +dot-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/dot-case/-/dot-case-3.0.4.tgz#9b2b670d00a431667a8a75ba29cd1b98809ce751" + integrity sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + +dot@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/dot/-/dot-1.1.3.tgz#351360e00a748bce9a1f8f27c00c394a7e4e1e9f" + integrity sha512-/nt74Rm+PcfnirXGEdhZleTwGC2LMnuKTeeTIlI82xb5loBBoXNYzr2ezCroPSMtilK8EZIfcNZwOcHN+ib1Lg== + +dotenv-expand@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" + integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== + +dotenv@^8.0.0: + version "8.6.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" + integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== + +duplexer2@~0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.1.4.tgz#8b12dab878c0d69e3e7891051662a32fc6bddcc1" + integrity sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA== + dependencies: + readable-stream "^2.0.2" + +duplexer@^0.1.1, duplexer@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.7.1" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.7.1.tgz#2a4df5317f6ccfd91f86d6fd25d8d8a103b88309" + integrity sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g== + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + ecc-jsbn@~0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" @@ -3351,10 +7692,33 @@ electron-to-chromium@^1.3.867: resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.868.tgz#ed835023b57ecf0ba63dfe7d50e16b53758ab1da" integrity sha512-kZYCHqwJ1ctGrYDlOcWQH+/AftAm/KD4lEnLDNwS0kKwx1x6dU4zv+GuDjsPPOGn/2TjnKBaZjDyjXaoix0q/A== -emoji-regex@^7.0.1: - version "7.0.3" - resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" - integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== +electron-to-chromium@^1.4.118: + version "1.4.145" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.145.tgz#5be3aa470cae3c2bccd20afc4d2a5efdca337b7b" + integrity sha512-g4VQCi61gA0t5fJHsalxAc8NpvxC/CEwLAGLfJ+DmkRXTEyntJA7H01771uVD6X6nnViv3GToPgb0QOVA8ivOQ== + +electron-to-chromium@^1.4.17: + version "1.4.71" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.71.tgz#17056914465da0890ce00351a3b946fd4cd51ff6" + integrity sha512-Hk61vXXKRb2cd3znPE9F+2pLWdIOmP7GjiTj45y6L3W/lO+hSnUSUhq+6lEaERWBdZOHbk2s3YV5c9xVl3boVw== + +electron-to-chromium@^1.4.188: + version "1.4.199" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.199.tgz#e0384fde79fdda89880e8be58196a9153e04db3b" + integrity sha512-WIGME0Cs7oob3mxsJwHbeWkH0tYkIE/sjkJ8ML2BYmuRcjhRl/q5kVDXG7W9LOOKwzPU5M0LBlXRq9rlSgnNlg== + +elliptic@^6.5.3: + version "6.5.4" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" + integrity sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ== + dependencies: + bn.js "^4.11.9" + brorand "^1.1.0" + hash.js "^1.0.0" + hmac-drbg "^1.0.1" + inherits "^2.0.4" + minimalistic-assert "^1.0.1" + minimalistic-crypto-utils "^1.0.1" emoji-regex@^8.0.0: version "8.0.0" @@ -3366,29 +7730,51 @@ emojis-list@^3.0.0: resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" integrity sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q== +encode-utf8@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/encode-utf8/-/encode-utf8-1.0.3.tgz#f30fdd31da07fb596f281beb2f6b027851994cda" + integrity sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw== + encodeurl@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.2.tgz#ad3ff4c86ec2d029322f5a02c3a9a606c95b3f59" integrity sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k= -encoding@^0.1.12: +encoding@^0.1.12, encoding@^0.1.13: version "0.1.13" resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.13.tgz#56574afdd791f54a8e9b2785c0582a2d26210fa9" integrity sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A== dependencies: iconv-lite "^0.6.2" -end-of-stream@^1.1.0: +end-of-stream@^1.0.0, end-of-stream@^1.1.0: version "1.4.4" resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0" integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q== dependencies: once "^1.4.0" -enhanced-resolve@^5.8.0: - version "5.8.3" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0" - integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA== +enhanced-resolve@^4.0.0, enhanced-resolve@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.5.0.tgz#2f3cfd84dbe3b487f18f2db2ef1e064a571ca5ec" + integrity sha512-Nv9m36S/vxpsI+Hc4/ZGRs0n9mXqSWGGq49zxb/cJfPAQMbUtttJAlNPS4AQzaBdw/pKskw5bMbekT/Y7W/Wlg== + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.5.0" + tapable "^1.0.0" + +enhanced-resolve@^5.10.0, enhanced-resolve@^5.7.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz#0dc579c3bb2a1032e357ac45b8f3a6f3ad4fb1e6" + integrity sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.2.0" + +enhanced-resolve@^5.9.3: + version "5.9.3" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.9.3.tgz#44a342c012cbc473254af5cc6ae20ebd0aae5d88" + integrity sha512-Bq9VSor+kjvW3f9/MiiR4eE3XYgOl7/rS8lnSxbRbF3kS0B2r+Y9w5krBWxZgDxASVZbdYrn5wT4j/Wb0J9qow== dependencies: graceful-fs "^4.2.4" tapable "^2.2.0" @@ -3398,6 +7784,11 @@ entities@^2.0.0: resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55" integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== +entities@^4.2.0, entities@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/entities/-/entities-4.3.1.tgz#c34062a94c865c322f9d67b4384e4169bcede6a4" + integrity sha512-o4q/dYJlmyjP2zfnaWDUC6A3BQFmVTX+tZPezK7k0GLSU9QYCauscf5Y+qcEPzKL+EixVouYDgLQK5H9GrLpkg== + env-paths@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/env-paths/-/env-paths-2.2.1.tgz#420399d416ce1fbe9bc0a07c62fa68d67fd0f8f2" @@ -3408,24 +7799,123 @@ err-code@^2.0.2: resolved "https://registry.yarnpkg.com/err-code/-/err-code-2.0.3.tgz#23c2f3b756ffdfc608d30e27c9a941024807e7f9" integrity sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA== -errno@^0.1.1, errno@^0.1.3: +errno@^0.1.1, errno@^0.1.3, errno@~0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.8.tgz#8bb3e9c7d463be4976ff888f76b4809ebc2e811f" integrity sha512-dJ6oBr5SQ1VSd9qkk7ByRgb/1SH4JZjCHSW/mr63/QcXO9zLVxvJ6Oy13nio03rxpSnVDDjFor75SjVeZWPW/A== dependencies: prr "~1.0.1" -error-ex@^1.3.1: +error-ex@^1.2.0, error-ex@^1.3.1: version "1.3.2" resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g== dependencies: is-arrayish "^0.2.1" -es-module-lexer@^0.7.1: - version "0.7.1" - resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.7.1.tgz#c2c8e0f46f2df06274cdaf0dd3f3b33e0a0b267d" - integrity sha512-MgtWFl5No+4S3TmhDmCz2ObFGm6lEpTnzbQi+Dd+pw4mlTIZTmM2iAs5gRlmx5zS9luzobCSBSI90JM/1/JgOw== +es-abstract@^1.19.0, es-abstract@^1.19.1, es-abstract@^1.19.2, es-abstract@^1.19.5, es-abstract@^1.20.1: + version "1.20.1" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.20.1.tgz#027292cd6ef44bd12b1913b828116f54787d1814" + integrity sha512-WEm2oBhfoI2sImeM4OF2zE2V3BYdSF+KnSi9Sidz51fQHd7+JuF8Xgcj9/0o+OWeIeIS/MiuNnlruQrJf16GQA== + dependencies: + call-bind "^1.0.2" + es-to-primitive "^1.2.1" + function-bind "^1.1.1" + function.prototype.name "^1.1.5" + get-intrinsic "^1.1.1" + get-symbol-description "^1.0.0" + has "^1.0.3" + has-property-descriptors "^1.0.0" + has-symbols "^1.0.3" + internal-slot "^1.0.3" + is-callable "^1.2.4" + is-negative-zero "^2.0.2" + is-regex "^1.1.4" + is-shared-array-buffer "^1.0.2" + is-string "^1.0.7" + is-weakref "^1.0.2" + object-inspect "^1.12.0" + object-keys "^1.1.1" + object.assign "^4.1.2" + regexp.prototype.flags "^1.4.3" + string.prototype.trimend "^1.0.5" + string.prototype.trimstart "^1.0.5" + unbox-primitive "^1.0.2" + +es-array-method-boxes-properly@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz#873f3e84418de4ee19c5be752990b2e44718d09e" + integrity sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA== + +es-get-iterator@^1.0.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/es-get-iterator/-/es-get-iterator-1.1.2.tgz#9234c54aba713486d7ebde0220864af5e2b283f7" + integrity sha512-+DTO8GYwbMCwbywjimwZMHp8AuYXOS2JZFWoi2AlPOS3ebnII9w/NLpNZtA7A0YLaVDw+O7KFCeoIV7OPvM7hQ== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.0" + has-symbols "^1.0.1" + is-arguments "^1.1.0" + is-map "^2.0.2" + is-set "^2.0.2" + is-string "^1.0.5" + isarray "^2.0.5" + +es-module-lexer@^0.9.0: + version "0.9.3" + resolved "https://registry.yarnpkg.com/es-module-lexer/-/es-module-lexer-0.9.3.tgz#6f13db00cc38417137daf74366f535c8eb438f19" + integrity sha512-1HQ2M2sPtxwnvOvT1ZClHyQDiggdNjURWpY2we6aMKCQiUVxTmVs2UYPLIrD84sS+kMdUwfBSylbJPwNnBrnHQ== + +es-shim-unscopables@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz#702e632193201e3edf8713635d083d378e510241" + integrity sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w== + dependencies: + has "^1.0.3" + +es-to-primitive@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.2.1.tgz#e55cd4c9cdc188bcefb03b366c736323fc5c898a" + integrity sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA== + dependencies: + is-callable "^1.1.4" + is-date-object "^1.0.1" + is-symbol "^1.0.2" + +es5-ext@^0.10.35, es5-ext@^0.10.50, es5-ext@~0.10.14: + version "0.10.61" + resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.61.tgz#311de37949ef86b6b0dcea894d1ffedb909d3269" + integrity sha512-yFhIqQAzu2Ca2I4SE2Au3rxVfmohU9Y7wqGR+s7+H7krk26NXhIRAZDgqd6xqjCEFUomDEA3/Bo/7fKmIkW1kA== + dependencies: + es6-iterator "^2.0.3" + es6-symbol "^3.1.3" + next-tick "^1.1.0" + +es5-shim@^4.5.13: + version "4.6.7" + resolved "https://registry.yarnpkg.com/es5-shim/-/es5-shim-4.6.7.tgz#bc67ae0fc3dd520636e0a1601cc73b450ad3e955" + integrity sha512-jg21/dmlrNQI7JyyA2w7n+yifSxBng0ZralnSfVZjoCawgNTCnS+yBCyVM9DL5itm7SUnDGgv7hcq2XCZX4iRQ== + +es6-iterator@^2.0.3, es6-iterator@~2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/es6-iterator/-/es6-iterator-2.0.3.tgz#a7de889141a05a94b0854403b2d0a0fbfa98f3b7" + integrity sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g== + dependencies: + d "1" + es5-ext "^0.10.35" + es6-symbol "^3.1.1" + +es6-map@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-map/-/es6-map-0.1.5.tgz#9136e0503dcc06a301690f0bb14ff4e364e949f0" + integrity sha512-mz3UqCh0uPCIqsw1SSAkB/p0rOzF/M0V++vyN7JqlPtSW/VsYgQBvVvqMLmfBuyMzTpLnNqi6JmcSizs4jy19A== + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-set "~0.1.5" + es6-symbol "~3.1.1" + event-emitter "~0.3.5" es6-promise@^4.0.3: version "4.2.8" @@ -3439,112 +7929,168 @@ es6-promisify@^5.0.0: dependencies: es6-promise "^4.0.3" -esbuild-android-arm64@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.13.4.tgz#5178a20d2b7aba741a31c19609f9e67b346996b9" - integrity sha512-elDJt+jNyoHFId0/dKsuVYUPke3EcquIyUwzJCH17a3ERglN3A9aMBI5zbz+xNZ+FbaDNdpn0RaJHCFLbZX+fA== +es6-set@^0.1.5, es6-set@~0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/es6-set/-/es6-set-0.1.5.tgz#d2b3ec5d4d800ced818db538d28974db0a73ccb1" + integrity sha512-7S8YXIcUfPMOr3rqJBVMePAbRsD1nWeSMQ86K/lDI76S3WKXz+KWILvTIPbTroubOkZTGh+b+7/xIIphZXNYbA== + dependencies: + d "1" + es5-ext "~0.10.14" + es6-iterator "~2.0.1" + es6-symbol "3.1.1" + event-emitter "~0.3.5" -esbuild-darwin-64@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.13.4.tgz#7a3e66c8e1271b650541b25eed65c84f3564a69d" - integrity sha512-zJQGyHRAdZUXlRzbN7W+7ykmEiGC+bq3Gc4GxKYjjWTgDRSEly98ym+vRNkDjXwXYD3gGzSwvH35+MiHAtWvLA== +es6-shim@^0.35.5: + version "0.35.6" + resolved "https://registry.yarnpkg.com/es6-shim/-/es6-shim-0.35.6.tgz#d10578301a83af2de58b9eadb7c2c9945f7388a0" + integrity sha512-EmTr31wppcaIAgblChZiuN/l9Y7DPyw8Xtbg7fIVngn6zMW+IEBJDJngeKC3x6wr0V/vcA2wqeFnaw1bFJbDdA== -esbuild-darwin-arm64@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.13.4.tgz#793feca6032b2a57ef291eb9b2d33768d60a49d6" - integrity sha512-r8oYvAtqSGq8HNTZCAx4TdLE7jZiGhX9ooGi5AQAey37MA6XNaP8ZNlw9OCpcgpx3ryU2WctXwIqPzkHO7a8dg== +es6-symbol@3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.1.tgz#bf00ef4fdab6ba1b46ecb7b629b4c7ed5715cc77" + integrity sha512-exfuQY8UGtn/N+gL1iKkH8fpNd5sJ760nJq6mmZAHldfxMD5kX07lbQuYlspoXsuknXNv9Fb7y2GsPOnQIbxHg== + dependencies: + d "1" + es5-ext "~0.10.14" -esbuild-freebsd-64@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.13.4.tgz#294aec3c2cf4b41fb6900212fc9c33dd8fbbb4a2" - integrity sha512-u9DRGkn09EN8+lCh6z7FKle7awi17PJRBuAKdRNgSo5ZrH/3m+mYaJK2PR2URHMpAfXiwJX341z231tSdVe3Yw== +es6-symbol@^3.1.1, es6-symbol@^3.1.3, es6-symbol@~3.1.1: + version "3.1.3" + resolved "https://registry.yarnpkg.com/es6-symbol/-/es6-symbol-3.1.3.tgz#bad5d3c1bcdac28269f4cb331e431c78ac705d18" + integrity sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA== + dependencies: + d "^1.0.1" + ext "^1.1.2" -esbuild-freebsd-arm64@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.13.4.tgz#09fe66c751c12f9b976976b1d83f3de594cb2787" - integrity sha512-q3B2k68Uf6gfjATjcK16DqxvjqRQkHL8aPoOfj4op+lSqegdXvBacB1d8jw8PxbWJ8JHpdTLdAVUYU80kotQXA== +esbuild-android-64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-android-64/-/esbuild-android-64-0.14.38.tgz#5b94a1306df31d55055f64a62ff6b763a47b7f64" + integrity sha512-aRFxR3scRKkbmNuGAK+Gee3+yFxkTJO/cx83Dkyzo4CnQl/2zVSurtG6+G86EQIZ+w+VYngVyK7P3HyTBKu3nw== -esbuild-linux-32@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.13.4.tgz#a9f0793d7bcc9cef4f4ffa4398c525877fba5839" - integrity sha512-UUYJPHSiKAO8KoN3Ls/iZtgDLZvK5HarES96aolDPWZnq9FLx4dIHM/x2z4Rxv9IYqQ/DxlPoE2Co1UPBIYYeA== +esbuild-android-arm64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-android-arm64/-/esbuild-android-arm64-0.14.38.tgz#78acc80773d16007de5219ccce544c036abd50b8" + integrity sha512-L2NgQRWuHFI89IIZIlpAcINy9FvBk6xFVZ7xGdOwIm8VyhX1vNCEqUJO3DPSSy945Gzdg98cxtNt8Grv1CsyhA== -esbuild-linux-64@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.13.4.tgz#c0d0b4c9d62e3bbf8bdf2cece37403aa6d60fc2e" - integrity sha512-+RnohAKiiUW4UHLGRkNR1AnENW1gCuDWuygEtd4jxTNPIoeC7lbXGor7rtgjj9AdUzFgOEvAXyNNX01kJ8NueQ== +esbuild-darwin-64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-darwin-64/-/esbuild-darwin-64-0.14.38.tgz#e02b1291f629ebdc2aa46fabfacc9aa28ff6aa46" + integrity sha512-5JJvgXkX87Pd1Og0u/NJuO7TSqAikAcQQ74gyJ87bqWRVeouky84ICoV4sN6VV53aTW+NE87qLdGY4QA2S7KNA== -esbuild-linux-arm64@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.13.4.tgz#1292d97bfa64a08d12728f8a7837bf92776c779b" - integrity sha512-+A188cAdd6QuSRxMIwRrWLjgphQA0LDAQ/ECVlrPVJwnx+1i64NjDZivoqPYLOTkSPIKntiWwMhhf0U5/RrPHQ== +esbuild-darwin-arm64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-darwin-arm64/-/esbuild-darwin-arm64-0.14.38.tgz#01eb6650ec010b18c990e443a6abcca1d71290a9" + integrity sha512-eqF+OejMI3mC5Dlo9Kdq/Ilbki9sQBw3QlHW3wjLmsLh+quNfHmGMp3Ly1eWm981iGBMdbtSS9+LRvR2T8B3eQ== -esbuild-linux-arm@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.13.4.tgz#186cd9b8885ac132b9953a4a0afe668168debd10" - integrity sha512-BH5gKve4jglS7UPSsfwHSX79I5agC/lm4eKoRUEyo8lwQs89frQSRp2Xup+6SFQnxt3md5EsKcd2Dbkqeb3gPA== +esbuild-freebsd-64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-64/-/esbuild-freebsd-64-0.14.38.tgz#790b8786729d4aac7be17648f9ea8e0e16475b5e" + integrity sha512-epnPbhZUt93xV5cgeY36ZxPXDsQeO55DppzsIgWM8vgiG/Rz+qYDLmh5ts3e+Ln1wA9dQ+nZmVHw+RjaW3I5Ig== -esbuild-linux-mips64le@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.13.4.tgz#42049bf72bc586817b4a51cc9e32148d13e5e807" - integrity sha512-0xkwtPaUkG5xMTFGaQPe1AadSe5QAiQuD4Gix1O9k5Xo/U8xGIkw9UFUTvfEUeu71vFb6ZgsIacfP1NLoFjWNw== +esbuild-freebsd-arm64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-freebsd-arm64/-/esbuild-freebsd-arm64-0.14.38.tgz#b66340ab28c09c1098e6d9d8ff656db47d7211e6" + integrity sha512-/9icXUYJWherhk+y5fjPI5yNUdFPtXHQlwP7/K/zg8t8lQdHVj20SqU9/udQmeUo5pDFHMYzcEFfJqgOVeKNNQ== -esbuild-linux-ppc64le@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.13.4.tgz#adf1ce2ef2302757c4383887da6ac4dd25be9d4f" - integrity sha512-E1+oJPP7A+j23GPo3CEpBhGwG1bni4B8IbTA3/3rvzjURwUMZdcN3Fhrz24rnjzdLSHmULtOE4VsbT42h1Om4Q== +esbuild-linux-32@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-linux-32/-/esbuild-linux-32-0.14.38.tgz#7927f950986fd39f0ff319e92839455912b67f70" + integrity sha512-QfgfeNHRFvr2XeHFzP8kOZVnal3QvST3A0cgq32ZrHjSMFTdgXhMhmWdKzRXP/PKcfv3e2OW9tT9PpcjNvaq6g== -esbuild-openbsd-64@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.13.4.tgz#1c8122101898c52a20c8786935cf3eb7a19b83b4" - integrity sha512-xEkI1o5HYxDzbv9jSox0EsDxpwraG09SRiKKv0W8pH6O3bt+zPSlnoK7+I7Q69tkvONkpIq5n2o+c55uq0X7cw== +esbuild-linux-64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-linux-64/-/esbuild-linux-64-0.14.38.tgz#4893d07b229d9cfe34a2b3ce586399e73c3ac519" + integrity sha512-uuZHNmqcs+Bj1qiW9k/HZU3FtIHmYiuxZ/6Aa+/KHb/pFKr7R3aVqvxlAudYI9Fw3St0VCPfv7QBpUITSmBR1Q== -esbuild-sunos-64@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.13.4.tgz#4ec95faa14a60f295fe485bebffefff408739337" - integrity sha512-bjXUMcODMnB6hQicLBBmmnBl7OMDyVpFahKvHGXJfDChIi5udiIRKCmFUFIRn+AUAKVlfrofRKdyPC7kBsbvGQ== +esbuild-linux-arm64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm64/-/esbuild-linux-arm64-0.14.38.tgz#8442402e37d0b8ae946ac616784d9c1a2041056a" + integrity sha512-HlMGZTEsBrXrivr64eZ/EO0NQM8H8DuSENRok9d+Jtvq8hOLzrxfsAT9U94K3KOGk2XgCmkaI2KD8hX7F97lvA== -esbuild-wasm@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-wasm/-/esbuild-wasm-0.13.4.tgz#9ae8ec5234cc651b2d74b23d4adac984055cff1c" - integrity sha512-2dN7njr9/2QzKLqbTEgXr73vDbSqffdJMv4EfaMQoy04cej0owbGHH5apPgED0wN9I5e7sBT0/Q81tVy3wQBlA== +esbuild-linux-arm@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-linux-arm/-/esbuild-linux-arm-0.14.38.tgz#d5dbf32d38b7f79be0ec6b5fb2f9251fd9066986" + integrity sha512-FiFvQe8J3VKTDXG01JbvoVRXQ0x6UZwyrU4IaLBZeq39Bsbatd94Fuc3F1RGqPF5RbIWW7RvkVQjn79ejzysnA== -esbuild-windows-32@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.13.4.tgz#3182c380487b797b04d0ec2c80c2945666869080" - integrity sha512-z4CH07pfyVY0XF98TCsGmLxKCl0kyvshKDbdpTekW9f2d+dJqn5mmoUyWhpSVJ0SfYWJg86FoD9nMbbaMVyGdg== +esbuild-linux-mips64le@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-linux-mips64le/-/esbuild-linux-mips64le-0.14.38.tgz#95081e42f698bbe35d8ccee0e3a237594b337eb5" + integrity sha512-qd1dLf2v7QBiI5wwfil9j0HG/5YMFBAmMVmdeokbNAMbcg49p25t6IlJFXAeLzogv1AvgaXRXvgFNhScYEUXGQ== -esbuild-windows-64@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.13.4.tgz#b9e995f92d81f433a04f33611e603e82f9232e69" - integrity sha512-uVL11vORRPjocGLYam67rwFLd0LvkrHEs+JG+1oJN4UD9MQmNGZPa4gBHo6hDpF+kqRJ9kXgQSeDqUyRy0tj/Q== +esbuild-linux-ppc64le@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-linux-ppc64le/-/esbuild-linux-ppc64le-0.14.38.tgz#dceb0a1b186f5df679618882a7990bd422089b47" + integrity sha512-mnbEm7o69gTl60jSuK+nn+pRsRHGtDPfzhrqEUXyCl7CTOCLtWN2bhK8bgsdp6J/2NyS/wHBjs1x8aBWwP2X9Q== -esbuild-windows-arm64@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.13.4.tgz#fb239532f07b764d158f4cc787178ef4c6fadb5c" - integrity sha512-vA6GLvptgftRcDcWngD5cMlL4f4LbL8JjU2UMT9yJ0MT5ra6hdZNFWnOeOoEtY4GtJ6OjZ0i+81sTqhAB0fMkg== +esbuild-linux-riscv64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-linux-riscv64/-/esbuild-linux-riscv64-0.14.38.tgz#61fb8edb75f475f9208c4a93ab2bfab63821afd2" + integrity sha512-+p6YKYbuV72uikChRk14FSyNJZ4WfYkffj6Af0/Tw63/6TJX6TnIKE+6D3xtEc7DeDth1fjUOEqm+ApKFXbbVQ== -esbuild@0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.13.4.tgz#ce2deb56c4fb360938311cbfc67f8e467bb6841b" - integrity sha512-wMA5eUwpavTBiNl+It6j8OQuKVh69l6z4DKDLzoTIqC+gChnPpcmqdA8WNHptUHRnfyML+mKEQPlW7Mybj8gHg== +esbuild-linux-s390x@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-linux-s390x/-/esbuild-linux-s390x-0.14.38.tgz#34c7126a4937406bf6a5e69100185fd702d12fe0" + integrity sha512-0zUsiDkGJiMHxBQ7JDU8jbaanUY975CdOW1YDrurjrM0vWHfjv9tLQsW9GSyEb/heSK1L5gaweRjzfUVBFoybQ== + +esbuild-netbsd-64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-netbsd-64/-/esbuild-netbsd-64-0.14.38.tgz#322ea9937d9e529183ee281c7996b93eb38a5d95" + integrity sha512-cljBAApVwkpnJZfnRVThpRBGzCi+a+V9Ofb1fVkKhtrPLDYlHLrSYGtmnoTVWDQdU516qYI8+wOgcGZ4XIZh0Q== + +esbuild-openbsd-64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-openbsd-64/-/esbuild-openbsd-64-0.14.38.tgz#1ca29bb7a2bf09592dcc26afdb45108f08a2cdbd" + integrity sha512-CDswYr2PWPGEPpLDUO50mL3WO/07EMjnZDNKpmaxUPsrW+kVM3LoAqr/CE8UbzugpEiflYqJsGPLirThRB18IQ== + +esbuild-sunos-64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-sunos-64/-/esbuild-sunos-64-0.14.38.tgz#c9446f7d8ebf45093e7bb0e7045506a88540019b" + integrity sha512-2mfIoYW58gKcC3bck0j7lD3RZkqYA7MmujFYmSn9l6TiIcAMpuEvqksO+ntBgbLep/eyjpgdplF7b+4T9VJGOA== + +esbuild-wasm@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-wasm/-/esbuild-wasm-0.14.38.tgz#76a347f3e12d2ddd72f20fee0a43c3aee2c81665" + integrity sha512-mObTw5/3+KIOTShVgk3fuEn+INnHgOSbWJuGkInEZTWpUOh/+TCSgRxl5cDon4OkoaLU5rWm7R7Dkl/mJv8SGw== + +esbuild-windows-32@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-windows-32/-/esbuild-windows-32-0.14.38.tgz#f8e9b4602fd0ccbd48e5c8d117ec0ba4040f2ad1" + integrity sha512-L2BmEeFZATAvU+FJzJiRLFUP+d9RHN+QXpgaOrs2klshoAm1AE6Us4X6fS9k33Uy5SzScn2TpcgecbqJza1Hjw== + +esbuild-windows-64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-windows-64/-/esbuild-windows-64-0.14.38.tgz#280f58e69f78535f470905ce3e43db1746518107" + integrity sha512-Khy4wVmebnzue8aeSXLC+6clo/hRYeNIm0DyikoEqX+3w3rcvrhzpoix0S+MF9vzh6JFskkIGD7Zx47ODJNyCw== + +esbuild-windows-arm64@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild-windows-arm64/-/esbuild-windows-arm64-0.14.38.tgz#d97e9ac0f95a4c236d9173fa9f86c983d6a53f54" + integrity sha512-k3FGCNmHBkqdJXuJszdWciAH77PukEyDsdIryEHn9cKLQFxzhT39dSumeTuggaQcXY57UlmLGIkklWZo2qzHpw== + +esbuild@0.14.38: + version "0.14.38" + resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.38.tgz#99526b778cd9f35532955e26e1709a16cca2fb30" + integrity sha512-12fzJ0fsm7gVZX1YQ1InkOE5f9Tl7cgf6JPYXRJtPIoE0zkWAbHdPHVPPaLi9tYAcEBqheGzqLn/3RdTOyBfcA== optionalDependencies: - esbuild-android-arm64 "0.13.4" - esbuild-darwin-64 "0.13.4" - esbuild-darwin-arm64 "0.13.4" - esbuild-freebsd-64 "0.13.4" - esbuild-freebsd-arm64 "0.13.4" - esbuild-linux-32 "0.13.4" - esbuild-linux-64 "0.13.4" - esbuild-linux-arm "0.13.4" - esbuild-linux-arm64 "0.13.4" - esbuild-linux-mips64le "0.13.4" - esbuild-linux-ppc64le "0.13.4" - esbuild-openbsd-64 "0.13.4" - esbuild-sunos-64 "0.13.4" - esbuild-windows-32 "0.13.4" - esbuild-windows-64 "0.13.4" - esbuild-windows-arm64 "0.13.4" + esbuild-android-64 "0.14.38" + esbuild-android-arm64 "0.14.38" + esbuild-darwin-64 "0.14.38" + esbuild-darwin-arm64 "0.14.38" + esbuild-freebsd-64 "0.14.38" + esbuild-freebsd-arm64 "0.14.38" + esbuild-linux-32 "0.14.38" + esbuild-linux-64 "0.14.38" + esbuild-linux-arm "0.14.38" + esbuild-linux-arm64 "0.14.38" + esbuild-linux-mips64le "0.14.38" + esbuild-linux-ppc64le "0.14.38" + esbuild-linux-riscv64 "0.14.38" + esbuild-linux-s390x "0.14.38" + esbuild-netbsd-64 "0.14.38" + esbuild-openbsd-64 "0.14.38" + esbuild-sunos-64 "0.14.38" + esbuild-windows-32 "0.14.38" + esbuild-windows-64 "0.14.38" + esbuild-windows-arm64 "0.14.38" escalade@^3.1.1: version "3.1.1" @@ -3561,6 +8107,29 @@ escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= +escodegen@^1.11.1: + version "1.14.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" + integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== + dependencies: + esprima "^4.0.1" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +escodegen@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.2.0.tgz#09de7967791cc958b7f89a2ddb6d23451af327e1" + integrity sha512-yLy3Cc+zAC0WSmoT2fig3J87TpQ8UaZGx8ahCAs9FL8qNbyV7CVyPKS74DG4bsHiL5ew9sxdYx131OkBQMFnvA== + dependencies: + esprima "~1.0.4" + estraverse "~1.5.0" + esutils "~1.0.0" + optionalDependencies: + source-map "~0.1.30" + eslint-scope@5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c" @@ -3569,19 +8138,32 @@ eslint-scope@5.1.1: esrecurse "^4.3.0" estraverse "^4.1.1" -esprima@^4.0.0: +eslint-scope@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" + integrity sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg== + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +esprima@^4.0.0, esprima@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== -esrecurse@^4.3.0: +esprima@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.0.4.tgz#9f557e08fc3b4d26ece9dd34f8fbf476b62585ad" + integrity sha512-rp5dMKN8zEs9dfi9g0X1ClLmV//WRyk/R15mppFNICIFRG5P92VP7Z04p8pk++gABo9W2tY+kHyu6P1mEHgmTA== + +esrecurse@^4.1.0, esrecurse@^4.3.0: version "4.3.0" resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.3.0.tgz#7ad7964d679abb28bee72cec63758b1c5d2c9921" integrity sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag== dependencies: estraverse "^5.2.0" -estraverse@^4.1.1: +estraverse@^4.1.1, estraverse@^4.2.0: version "4.3.0" resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.3.0.tgz#398ad3f3c5a24948be7725e83d11a7de28cdbd1d" integrity sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw== @@ -3591,16 +8173,57 @@ estraverse@^5.2.0: resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.2.0.tgz#307df42547e6cc7324d3cf03c155d5cdb8c53880" integrity sha512-BxbNGGNm0RyRYvUdHpIwv9IWzeM9XClbOxwoATuFdOE7ZE6wHL+HQ5T8hoPM+zHvmKzzsEqhgy0GrQ5X13afiQ== +estraverse@~1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.5.1.tgz#867a3e8e58a9f84618afb6c2ddbcd916b7cbaf71" + integrity sha512-FpCjJDfmo3vsc/1zKSeqR5k42tcIhxFIlvq+h9j0fO2q/h2uLKyweq7rYJ+0CoVvrGQOxIS5wyBrW/+vF58BUQ== + +estree-is-function@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/estree-is-function/-/estree-is-function-1.0.0.tgz#c0adc29806d7f18a74db7df0f3b2666702e37ad2" + integrity sha512-nSCWn1jkSq2QAtkaVLJZY2ezwcFO161HVc174zL1KPW3RJ+O6C3eJb8Nx7OXzvhoEv+nLgSR1g71oWUHUDTrJA== + esutils@^2.0.2: version "2.0.3" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.3.tgz#74d2eb4de0b8da1293711910d50775b9b710ef64" integrity sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g== +esutils@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.0.0.tgz#8151d358e20c8acc7fb745e7472c0025fe496570" + integrity sha512-x/iYH53X3quDwfHRz4y8rn4XcEwwCJeWsul9pF1zldMbGtgOtMNBEOuYWwB1EQlK2LRa1fev3YAgym/RElp5Cg== + etag@~1.8.1: version "1.8.1" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= +event-emitter@~0.3.5: + version "0.3.5" + resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39" + integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA== + dependencies: + d "1" + es5-ext "~0.10.14" + +event-stream@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-4.0.1.tgz#4092808ec995d0dd75ea4580c1df6a74db2cde65" + integrity sha512-qACXdu/9VHPBzcyhdOWR5/IahhGMf0roTeZJfzz077GwylcDd90yOHLouhmv7GJ5XzPi6ekaQWd8AvPP2nOvpA== + dependencies: + duplexer "^0.1.1" + from "^0.1.7" + map-stream "0.0.7" + pause-stream "^0.0.11" + split "^1.0.1" + stream-combiner "^0.2.2" + through "^2.3.8" + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + eventemitter-asyncresource@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz#734ff2e44bf448e627f7748f905d6bdd57bdb65b" @@ -3616,7 +8239,7 @@ eventemitter3@^4.0.0: resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -events@^3.2.0: +events@^3.0.0, events@^3.2.0: version "3.3.0" resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== @@ -3628,6 +8251,19 @@ eventsource@^1.0.7: dependencies: original "^1.0.0" +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + integrity sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA== + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +exec-sh@^0.3.2: + version "0.3.6" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.3.6.tgz#ff264f9e325519a60cb5e273692943483cca63bc" + integrity sha512-nQn+hI3yp+oD0huYhKwvYI32+JFeq+XkNcD1GAo3Y/MjxsfVGmrrzrnzjWiNY6f+pUCP440fThsFh5gZrRAU/w== + execa@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" @@ -3641,6 +8277,36 @@ execa@^1.0.0: signal-exit "^3.0.0" strip-eof "^1.0.0" +execa@^4.0.2: + version "4.1.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-4.1.0.tgz#4e5491ad1572f2f17a77d388c6c857135b22847a" + integrity sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA== + dependencies: + cross-spawn "^7.0.0" + get-stream "^5.0.0" + human-signals "^1.1.1" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.0" + onetime "^5.1.0" + signal-exit "^3.0.2" + strip-final-newline "^2.0.0" + +execa@^5.0.0, execa@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/execa/-/execa-5.1.1.tgz#f80ad9cbf4298f7bd1d4c9555c21e93741c411dd" + integrity sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg== + dependencies: + cross-spawn "^7.0.3" + get-stream "^6.0.0" + human-signals "^2.1.0" + is-stream "^2.0.0" + merge-stream "^2.0.0" + npm-run-path "^4.0.1" + onetime "^5.1.2" + signal-exit "^3.0.3" + strip-final-newline "^2.0.0" + exit@^0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" @@ -3649,7 +8315,7 @@ exit@^0.1.2: expand-brackets@^2.1.4: version "2.1.4" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" - integrity sha1-t3c14xXOMPa27/D4OwQVGiJEliI= + integrity sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA== dependencies: debug "^2.3.3" define-property "^0.2.5" @@ -3659,53 +8325,61 @@ expand-brackets@^2.1.4: snapdragon "^0.8.1" to-regex "^3.0.1" -express@^4.17.1: - version "4.17.1" - resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" - integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== +express@^4.17.1, express@^4.17.3: + version "4.18.1" + resolved "https://registry.yarnpkg.com/express/-/express-4.18.1.tgz#7797de8b9c72c857b9cd0e14a5eea80666267caf" + integrity sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q== dependencies: - accepts "~1.3.7" + accepts "~1.3.8" array-flatten "1.1.1" - body-parser "1.19.0" - content-disposition "0.5.3" + body-parser "1.20.0" + content-disposition "0.5.4" content-type "~1.0.4" - cookie "0.4.0" + cookie "0.5.0" cookie-signature "1.0.6" debug "2.6.9" - depd "~1.1.2" + depd "2.0.0" encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" - finalhandler "~1.1.2" + finalhandler "1.2.0" fresh "0.5.2" + http-errors "2.0.0" merge-descriptors "1.0.1" methods "~1.1.2" - on-finished "~2.3.0" + on-finished "2.4.1" parseurl "~1.3.3" path-to-regexp "0.1.7" - proxy-addr "~2.0.5" - qs "6.7.0" + proxy-addr "~2.0.7" + qs "6.10.3" range-parser "~1.2.1" - safe-buffer "5.1.2" - send "0.17.1" - serve-static "1.14.1" - setprototypeof "1.1.1" - statuses "~1.5.0" + safe-buffer "5.2.1" + send "0.18.0" + serve-static "1.15.0" + setprototypeof "1.2.0" + statuses "2.0.1" type-is "~1.6.18" utils-merge "1.0.1" vary "~1.1.2" +ext@^1.1.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/ext/-/ext-1.6.0.tgz#3871d50641e874cc172e2b53f919842d19db4c52" + integrity sha512-sdBImtzkq2HpkdRLtlLWDa6w4DX22ijZLKx8BMPUuKe1c5lbN6xwQDQCxSfxBQnHZ13ls/FH0MQZx/q/gr6FQg== + dependencies: + type "^2.5.0" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" - integrity sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8= + integrity sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug== dependencies: is-extendable "^0.1.0" extend-shallow@^3.0.0, extend-shallow@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" - integrity sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg= + integrity sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q== dependencies: assign-symbols "^1.0.0" is-extendable "^1.0.1" @@ -3748,15 +8422,44 @@ extsprintf@^1.2.0: resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8= -fast-deep-equal@^3.1.1: +fancy-log@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" + integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== + dependencies: + ansi-gray "^0.1.1" + color-support "^1.1.3" + parse-node-version "^1.0.0" + time-stamp "^1.0.0" + +fancy-log@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-2.0.0.tgz#cad207b8396d69ae4796d74d17dff5f68b2f7343" + integrity sha512-9CzxZbACXMUXW13tS0tI8XsGGmxWzO2DmYrGuBJOJ8k8q2K7hwfJA5qHjuPPe8wtsco33YR9wc+Rlr5wYFvhSA== + dependencies: + color-support "^1.1.3" + +fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.1.1, fast-glob@^3.2.5: - version "3.2.7" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" - integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== +fast-glob@^2.2.6: + version "2.2.7" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.7.tgz#6953857c3afa475fff92ee6015d52da70a4cd39d" + integrity sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw== + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.1.2" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.3" + micromatch "^3.1.10" + +fast-glob@^3.2.7, fast-glob@^3.2.9: + version "3.2.11" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.11.tgz#a1172ad95ceb8a16e20caa5c5e56480e5129c1d9" + integrity sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew== dependencies: "@nodelib/fs.stat" "^2.0.2" "@nodelib/fs.walk" "^1.2.3" @@ -3769,6 +8472,11 @@ fast-json-stable-stringify@2.1.0, fast-json-stable-stringify@^2.0.0: resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633" integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw== +fast-levenshtein@~2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== + fastparse@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/fastparse/-/fastparse-1.1.2.tgz#91728c5a5942eced8531283c79441ee4122c35a9" @@ -3781,13 +8489,44 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" -faye-websocket@^0.11.3: +fault@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/fault/-/fault-1.0.4.tgz#eafcfc0a6d214fc94601e170df29954a4f842f13" + integrity sha512-CJ0HCB5tL5fYTEA7ToAq5+kTwd++Borf1/bifxd9iT70QcXr4MRrO3Llf8Ifs70q+SJcGHFtnIE/Nw6giCtECA== + dependencies: + format "^0.2.0" + +faye-websocket@0.11.x, faye-websocket@^0.11.3: version "0.11.4" resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.4.tgz#7f0d9275cfdd86a1c963dc8b65fcc451edcbb1da" integrity sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g== dependencies: websocket-driver ">=0.5.1" +fb-watchman@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.1.tgz#fc84fb39d2709cf3ff6d743706157bb5708a8a85" + integrity sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg== + dependencies: + bser "2.1.1" + +fetch-cookie@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/fetch-cookie/-/fetch-cookie-0.11.0.tgz#e046d2abadd0ded5804ce7e2cae06d4331c15407" + integrity sha512-BQm7iZLFhMWFy5CZ/162sAGjBfdNWb7a8LEqqnzsHFhxT/X/SVj/z2t2nu3aJvjlbQkrAlTUApplPRjWyH4mhA== + dependencies: + tough-cookie "^2.3.3 || ^3.0.1 || ^4.0.0" + +fetch-retry@^5.0.2: + version "5.0.3" + resolved "https://registry.yarnpkg.com/fetch-retry/-/fetch-retry-5.0.3.tgz#edfa3641892995f9afee94f25b168827aa97fe3d" + integrity sha512-uJQyMrX5IJZkhoEUBQ3EjxkeiZkppBd5jS/fMTJmfZxLSiaQjv2zD0kTvuvkSH89uFvgSlB6ueGpjD3HWN7Bxw== + +figgy-pudding@^3.5.1: + version "3.5.2" + resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e" + integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw== + figures@^3.0.0: version "3.2.0" resolved "https://registry.yarnpkg.com/figures/-/figures-3.2.0.tgz#625c18bd293c604dc4a8ddb2febf0c88341746af" @@ -3795,6 +8534,22 @@ figures@^3.0.0: dependencies: escape-string-regexp "^1.0.5" +file-loader@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +file-system-cache@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/file-system-cache/-/file-system-cache-1.1.0.tgz#984de17b976b75a77a27e08d6828137c1aa80fa1" + integrity sha512-IzF5MBq+5CR0jXx5RxPe4BICl/oEhBSXKaL9fLhAXrIfIUS77Hr4vzrYyqYMHN6uTt+BOqi3fDCTjjEBCjERKw== + dependencies: + fs-extra "^10.1.0" + ramda "^0.28.0" + file-uri-to-path@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz#553a7b8446ff6f684359c445f1e37a05dacc33dd" @@ -3803,7 +8558,7 @@ file-uri-to-path@1.0.0: fill-range@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" - integrity sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc= + integrity sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ== dependencies: extend-shallow "^2.0.1" is-number "^3.0.0" @@ -3817,7 +8572,7 @@ fill-range@^7.0.1: dependencies: to-regex-range "^5.0.1" -finalhandler@~1.1.2: +finalhandler@1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.1.2.tgz#b7e7d000ffd11938d0fdb053506f6ebabe9f587d" integrity sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA== @@ -3830,14 +8585,27 @@ finalhandler@~1.1.2: statuses "~1.5.0" unpipe "~1.0.0" -find-cache-dir@3.3.1: - version "3.3.1" - resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-3.3.1.tgz#89b33fad4a4670daa94f855f7fbe31d6d84fe880" - integrity sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ== +finalhandler@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.2.0.tgz#7d23fe5731b207b4640e4fcd00aec1f9207a7b32" + integrity sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg== + dependencies: + debug "2.6.9" + encodeurl "~1.0.2" + escape-html "~1.0.3" + on-finished "2.4.1" + parseurl "~1.3.3" + statuses "2.0.1" + unpipe "~1.0.0" + +find-cache-dir@^2.0.0, find-cache-dir@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-2.1.0.tgz#8d0f94cd13fe43c6c7c261a0d86115ca918c05f7" + integrity sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ== dependencies: commondir "^1.0.1" - make-dir "^3.0.2" - pkg-dir "^4.1.0" + make-dir "^2.0.0" + pkg-dir "^3.0.0" find-cache-dir@^3.3.1: version "3.3.2" @@ -3848,6 +8616,14 @@ find-cache-dir@^3.3.1: make-dir "^3.0.2" pkg-dir "^4.1.0" +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + integrity sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA== + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -3855,7 +8631,7 @@ find-up@^3.0.0: dependencies: locate-path "^3.0.0" -find-up@^4.0.0: +find-up@^4.0.0, find-up@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-4.1.0.tgz#97afe7d6cdc0bc5928584b7c8d7b16e8a9aa5d19" integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw== @@ -3863,10 +8639,33 @@ find-up@^4.0.0: locate-path "^5.0.0" path-exists "^4.0.0" -flatten@^1.0.2: - version "1.0.3" - resolved "https://registry.yarnpkg.com/flatten/-/flatten-1.0.3.tgz#c1283ac9f27b368abc1e36d1ff7b04501a30356b" - integrity sha512-dVsPA/UwQ8+2uoFe5GHtiBMu48dWLTdsuEd7CKGlZlD78r1TTWBvDuFaFGKCo/ZfEr95Uk56vZoX86OsHkUeIg== +find-up@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-5.0.0.tgz#4c92819ecb7083561e4f4a240a86be5198f536fc" + integrity sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng== + dependencies: + locate-path "^6.0.0" + path-exists "^4.0.0" + +findit2@^2.2.3: + version "2.2.3" + resolved "https://registry.yarnpkg.com/findit2/-/findit2-2.2.3.tgz#58a466697df8a6205cdfdbf395536b8bd777a5f6" + integrity sha512-lg/Moejf4qXovVutL0Lz4IsaPoNYMuxt4PA0nGqFxnJ1CTTGGlEO2wKgoDpwknhvZ8k4Q2F+eesgkLbG2Mxfog== + +flush-write-stream@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.1.1.tgz#8dd7d873a1babc207d94ead0c2e0e44276ebf2e8" + integrity sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w== + dependencies: + inherits "^2.0.3" + readable-stream "^2.3.6" + +focus-lock@^0.8.0: + version "0.8.1" + resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.8.1.tgz#bb36968abf77a2063fa173cb6c47b12ac8599d33" + integrity sha512-/LFZOIo82WDsyyv7h7oc0MJF9ACOvDRdx9rWPZ2pgMfNWu/z8hQDBtOchuB/0BVLmuFOZjV02YwUVzNsWx/EzA== + dependencies: + tslib "^1.9.3" follow-redirects@^1.0.0: version "1.14.4" @@ -3876,13 +8675,45 @@ follow-redirects@^1.0.0: for-in@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" - integrity sha1-gQaNKVqBQuwKxybG4iAMMPttXoA= + integrity sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ== forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= +fork-ts-checker-webpack-plugin@^4.1.6: + version "4.1.6" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz#5055c703febcf37fa06405d400c122b905167fc5" + integrity sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw== + dependencies: + "@babel/code-frame" "^7.5.5" + chalk "^2.4.1" + micromatch "^3.1.10" + minimatch "^3.0.4" + semver "^5.6.0" + tapable "^1.0.0" + worker-rpc "^0.1.0" + +fork-ts-checker-webpack-plugin@^6.0.4: + version "6.5.2" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.5.2.tgz#4f67183f2f9eb8ba7df7177ce3cf3e75cdafb340" + integrity sha512-m5cUmF30xkZ7h4tWUgTAcEaKmUW7tfyUyTqNNOz7OxWJ0v1VWKTcOvH8FWHUwSjlW/356Ijc9vi3XfcPstpQKA== + dependencies: + "@babel/code-frame" "^7.8.3" + "@types/json-schema" "^7.0.5" + chalk "^4.1.0" + chokidar "^3.4.2" + cosmiconfig "^6.0.0" + deepmerge "^4.2.2" + fs-extra "^9.0.0" + glob "^7.1.6" + memfs "^3.1.2" + minimatch "^3.0.4" + schema-utils "2.7.0" + semver "^7.3.2" + tapable "^1.0.0" + form-data@^2.3.1: version "2.5.1" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.1.tgz#f2cbec57b5e59e23716e128fe44d4e5dd23895f4" @@ -3892,6 +8723,15 @@ form-data@^2.3.1: combined-stream "^1.0.6" mime-types "^2.1.12" +form-data@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-3.0.1.tgz#ebd53791b78356a99af9a300d4282c4d5eb9755f" + integrity sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg== + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.8" + mime-types "^2.1.12" + form-data@~2.3.2: version "2.3.3" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.3.tgz#dcce52c05f644f298c6a7ab936bd724ceffbf3a6" @@ -3901,6 +8741,11 @@ form-data@~2.3.2: combined-stream "^1.0.6" mime-types "^2.1.12" +format@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" + integrity sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww== + formidable@^1.2.0: version "1.2.2" resolved "https://registry.yarnpkg.com/formidable/-/formidable-1.2.2.tgz#bf69aea2972982675f00865342b982986f6b8dd9" @@ -3911,10 +8756,15 @@ forwarded@0.2.0: resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" integrity sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow== +fraction.js@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.2.0.tgz#448e5109a313a3527f5a3ab2119ec4cf0e0e2950" + integrity sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA== + fragment-cache@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" - integrity sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk= + integrity sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA== dependencies: map-cache "^0.2.2" @@ -3923,6 +8773,38 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= +from2@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + integrity sha512-OMcX/4IC/uqEPVgGeyfN22LJk6AZrMkRZHxcHBMBvHScDGgwTm2GT2Wkgtocyd3JfZffjj2kYUDXXII0Fk9W0g== + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +from@^0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + integrity sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g== + +fs-extra@^10.0.1, fs-extra@^10.1.0: + version "10.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-10.1.0.tgz#02873cfbc4084dde127eaa5f9905eef2325d1abf" + integrity sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ== + dependencies: + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + +fs-extra@^9.0.0, fs-extra@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-9.1.0.tgz#5954460c764a8da2094ba3554bf839e6b9a7c86d" + integrity sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ== + dependencies: + at-least-node "^1.0.0" + graceful-fs "^4.2.0" + jsonfile "^6.0.1" + universalify "^2.0.0" + fs-minipass@^2.0.0, fs-minipass@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb" @@ -3930,11 +8812,21 @@ fs-minipass@^2.0.0, fs-minipass@^2.1.0: dependencies: minipass "^3.0.0" -fs-monkey@1.0.3: +fs-monkey@1.0.3, fs-monkey@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + integrity sha512-gehEzmPn2nAwr39eay+x3X34Ra+M2QlVUTLhkXPjWdeO8RF9kszk116avgBJM3ZyNHgHXBNx+VmPaFC36k0PzA== + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + fs.realpath@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" @@ -3948,7 +8840,7 @@ fsevents@^1.2.7: bindings "^1.5.0" nan "^2.12.1" -fsevents@~2.3.2: +fsevents@^2.1.2, fsevents@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a" integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA== @@ -3969,31 +8861,67 @@ function-bind@^1.1.1: resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A== -gauge@~2.7.3: - version "2.7.4" - resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" - integrity sha1-LANAXHU4w51+s3sxcCLjJfsBi/c= +function.prototype.name@^1.1.0, function.prototype.name@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/function.prototype.name/-/function.prototype.name-1.1.5.tgz#cce0505fe1ffb80503e6f9e46cc64e46a12a9621" + integrity sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA== dependencies: - aproba "^1.0.3" + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.0" + functions-have-names "^1.2.2" + +functions-have-names@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" + integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== + +gauge@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" + integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.2" console-control-strings "^1.0.0" - has-unicode "^2.0.0" - object-assign "^4.1.0" + has-unicode "^2.0.1" + object-assign "^4.1.1" signal-exit "^3.0.0" - string-width "^1.0.1" - strip-ansi "^3.0.1" - wide-align "^1.1.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.2" + +gauge@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-4.0.1.tgz#82984bc08c90357d60b0a46c03a296beb1affec4" + integrity sha512-zJ4jePUHR8cceduZ53b6temRalyGpkC2Kc2r3ecNphmL+uWNoJ3YcOcUjpbG6WwoE/Ef6/+aEZz63neI2WIa1Q== + dependencies: + ansi-regex "^5.0.1" + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.2" + console-control-strings "^1.0.0" + has-unicode "^2.0.1" + signal-exit "^3.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.2" gensync@^1.0.0-beta.1, gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg== +get-assigned-identifiers@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz#6dbf411de648cbaf8d9169ebb0d2d576191e2ff1" + integrity sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ== + get-caller-file@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" integrity sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w== -get-caller-file@^2.0.1, get-caller-file@^2.0.5: +get-caller-file@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== @@ -4007,6 +8935,25 @@ get-intrinsic@^1.0.2: has "^1.0.3" has-symbols "^1.0.1" +get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz#336975123e05ad0b7ba41f152ee4aadbea6cf598" + integrity sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA== + dependencies: + function-bind "^1.1.1" + has "^1.0.3" + has-symbols "^1.0.3" + +get-package-type@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/get-package-type/-/get-package-type-0.1.0.tgz#8de2d803cff44df3bc6c456e6668b36c3926e11a" + integrity sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q== + +get-stdin@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" + integrity sha512-F5aQMywwJ2n85s4hJPTT9RPxGmubonuB10MNYo17/xph174n2MIR33HRguhzVag10O/npM7SPk73LMZNP+FaWw== + get-stream@^4.0.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -4014,10 +8961,30 @@ get-stream@^4.0.0: dependencies: pump "^3.0.0" +get-stream@^5.0.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.2.0.tgz#4966a1795ee5ace65e706c4b7beb71257d6e22d3" + integrity sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA== + dependencies: + pump "^3.0.0" + +get-stream@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-6.0.1.tgz#a262d8eef67aced57c2852ad6167526a43cbf7b7" + integrity sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg== + +get-symbol-description@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/get-symbol-description/-/get-symbol-description-1.0.0.tgz#7fdb81c900101fbd564dd5f1a30af5aadc1e58d6" + integrity sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw== + dependencies: + call-bind "^1.0.2" + get-intrinsic "^1.1.1" + get-value@^2.0.3, get-value@^2.0.6: version "2.0.6" resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" - integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= + integrity sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA== getpass@^0.1.1: version "0.1.7" @@ -4026,10 +8993,15 @@ getpass@^0.1.1: dependencies: assert-plus "^1.0.0" +github-slugger@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/github-slugger/-/github-slugger-1.4.0.tgz#206eb96cdb22ee56fdc53a28d5a302338463444e" + integrity sha512-w0dzqw/nt51xMVmlaV1+JRzN+oCa1KfcgGEWhxUG16wbdA+Xnt/yoFO8Z8x/V82ZcZ0wy6ln9QDup5avbhiDhQ== + glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" - integrity sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4= + integrity sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA== dependencies: is-glob "^3.1.0" path-dirname "^1.0.0" @@ -4041,30 +9013,53 @@ glob-parent@^5.1.2, glob-parent@~5.1.2: dependencies: is-glob "^4.0.1" -glob-parent@^6.0.0: +glob-parent@^6.0.1: version "6.0.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-6.0.2.tgz#6d237d99083950c79290f24c7642a3de9a28f9e3" integrity sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A== dependencies: is-glob "^4.0.3" +glob-promise@^3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-3.4.0.tgz#b6b8f084504216f702dc2ce8c9bc9ac8866fdb20" + integrity sha512-q08RJ6O+eJn+dVanerAndJwIcumgbDdYiUT7zFQl3Wm1xD6fBKtah7H8ZJChj4wP+8C+QfeVy8xautR7rdmKEw== + dependencies: + "@types/glob" "*" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + integrity sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig== + glob-to-regexp@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== -glob@7.1.7: - version "7.1.7" - resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.7.tgz#3b193e9233f01d42d0b3f78294bbeeb418f94a90" - integrity sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ== +glob@8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.1.tgz#00308f5c035aa0b2a447cd37ead267ddff1577d3" + integrity sha512-cF7FYZZ47YzmCu7dDy50xSRRfO3ErRfrXuLZcNIuyiJEco0XSrGtuilG19L5xp3NcwTx7Gn+X6Tv3fmsUPTbow== dependencies: fs.realpath "^1.0.0" inflight "^1.0.4" inherits "2" - minimatch "^3.0.4" + minimatch "^5.0.1" once "^1.3.0" path-is-absolute "^1.0.0" +glob@8.0.3, glob@^8.0.1: + version "8.0.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-8.0.3.tgz#415c6eb2deed9e502c68fa44a272e6da6eeca42e" + integrity sha512-ull455NHSHI/Y1FqGaaYFaLGkNMMJbavMrEGFXG/PGrg6y7sutWHUHrz6gy6WEBH6akM1M414dWKCNs+IhKdiQ== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^5.0.1" + once "^1.3.0" + glob@^7.0.3, glob@^7.0.6, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.2.0" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" @@ -4077,23 +9072,62 @@ glob@^7.0.3, glob@^7.0.6, glob@^7.1.1, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.2.0: + version "7.2.3" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" + integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.1.1" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" + integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== + dependencies: + min-document "^2.19.0" + process "^0.11.10" + globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA== -globby@^11.0.3: - version "11.0.4" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" - integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== +globalthis@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.3.tgz#5852882a52b80dc301b0660273e1ed082f0b6ccf" + integrity sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA== + dependencies: + define-properties "^1.1.3" + +globby@^11.0.2: + version "11.1.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-11.1.0.tgz#bd4be98bb042f83d796f7e3811991fbe82a0d34b" + integrity sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g== dependencies: array-union "^2.1.0" dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" + fast-glob "^3.2.9" + ignore "^5.2.0" + merge2 "^1.4.1" slash "^3.0.0" +globby@^12.0.2: + version "12.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-12.2.0.tgz#2ab8046b4fba4ff6eede835b29f678f90e3d3c22" + integrity sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA== + dependencies: + array-union "^3.0.1" + dir-glob "^3.0.1" + fast-glob "^3.2.7" + ignore "^5.1.9" + merge2 "^1.4.1" + slash "^4.0.0" + globby@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/globby/-/globby-5.0.0.tgz#ebd84667ca0dbb330b99bcfc68eac2bc54370e0d" @@ -4106,27 +9140,52 @@ globby@^5.0.0: pify "^2.0.0" pinkie-promise "^2.0.0" -globby@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/globby/-/globby-6.1.0.tgz#f5a6d70e8395e21c858fb0489d64df02424d506c" - integrity sha1-9abXDoOV4hyFj7BInWTfAkJNUGw= +globby@^9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/globby/-/globby-9.2.0.tgz#fd029a706c703d29bdd170f4b6db3a3f7a7cb63d" + integrity sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg== dependencies: - array-union "^1.0.1" - glob "^7.0.3" - object-assign "^4.0.1" - pify "^2.0.0" - pinkie-promise "^2.0.0" + "@types/glob" "^7.1.1" + array-union "^1.0.2" + dir-glob "^2.2.2" + fast-glob "^2.2.6" + glob "^7.1.3" + ignore "^4.0.3" + pify "^4.0.1" + slash "^2.0.0" -graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.2.3, graceful-fs@^4.2.4: +graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.6, graceful-fs@^4.2.0: + version "4.2.10" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.10.tgz#147d3a006da4ca3ce14728c7aefc287c367d7a6c" + integrity sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA== + +graceful-fs@^4.1.2, graceful-fs@^4.2.4: version "4.2.8" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== +graceful-fs@^4.2.6, graceful-fs@^4.2.9: + version "4.2.9" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96" + integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ== + handle-thing@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-2.0.1.tgz#857f79ce359580c340d43081cc648970d0bb234e" integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== +handlebars@^4.7.7: + version "4.7.7" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1" + integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== + dependencies: + minimist "^1.2.5" + neo-async "^2.6.0" + source-map "^0.6.1" + wordwrap "^1.0.0" + optionalDependencies: + uglify-js "^3.1.4" + har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -4147,6 +9206,11 @@ has-ansi@^2.0.0: dependencies: ansi-regex "^2.0.0" +has-bigints@^1.0.1, has-bigints@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" + integrity sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ== + has-flag@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" @@ -4157,11 +9221,30 @@ has-flag@^4.0.0: resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b" integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ== -has-symbols@^1.0.1, has-symbols@^1.0.2: +has-glob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-glob/-/has-glob-1.0.0.tgz#9aaa9eedbffb1ba3990a7b0010fb678ee0081207" + integrity sha512-D+8A457fBShSEI3tFCj65PAbT++5sKiFtdCdOam0gnfBgw9D277OERk+HM9qYJXmdVLZ/znez10SqHN0BBQ50g== + dependencies: + is-glob "^3.0.0" + +has-property-descriptors@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz#610708600606d36961ed04c196193b6a607fa861" + integrity sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ== + dependencies: + get-intrinsic "^1.1.1" + +has-symbols@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== +has-symbols@^1.0.2, has-symbols@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.3.tgz#bb7b2c4349251dce87b125f7bdf874aa7c8b39f8" + integrity sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A== + has-tostringtag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-tostringtag/-/has-tostringtag-1.0.0.tgz#7e133818a7d394734f941e73c3d3f9291e658b25" @@ -4169,7 +9252,7 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" -has-unicode@^2.0.0: +has-unicode@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" integrity sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk= @@ -4177,7 +9260,7 @@ has-unicode@^2.0.0: has-value@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" - integrity sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8= + integrity sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q== dependencies: get-value "^2.0.3" has-values "^0.1.4" @@ -4186,7 +9269,7 @@ has-value@^0.3.1: has-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" - integrity sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc= + integrity sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw== dependencies: get-value "^2.0.6" has-values "^1.0.0" @@ -4195,23 +9278,108 @@ has-value@^1.0.0: has-values@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" - integrity sha1-bWHeldkd/Km5oCCJrThL/49it3E= + integrity sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ== has-values@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" - integrity sha1-lbC2P+whRmGab+V/51Yo1aOe/k8= + integrity sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ== dependencies: is-number "^3.0.0" kind-of "^4.0.0" -has@^1.0.3: +has@^1.0.1, has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw== dependencies: function-bind "^1.1.1" +hash-base@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.1.0.tgz#55c381d9e06e1d2997a883b4a3fddfe7f0d3af33" + integrity sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA== + dependencies: + inherits "^2.0.4" + readable-stream "^3.6.0" + safe-buffer "^5.2.0" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.7" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" + integrity sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA== + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +hast-to-hyperscript@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz#9b67fd188e4c81e8ad66f803855334173920218d" + integrity sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA== + dependencies: + "@types/unist" "^2.0.3" + comma-separated-tokens "^1.0.0" + property-information "^5.3.0" + space-separated-tokens "^1.0.0" + style-to-object "^0.3.0" + unist-util-is "^4.0.0" + web-namespaces "^1.0.0" + +hast-util-from-parse5@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz#554e34abdeea25ac76f5bd950a1f0180e0b3bc2a" + integrity sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA== + dependencies: + "@types/parse5" "^5.0.0" + hastscript "^6.0.0" + property-information "^5.0.0" + vfile "^4.0.0" + vfile-location "^3.2.0" + web-namespaces "^1.0.0" + +hast-util-parse-selector@^2.0.0: + version "2.2.5" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz#d57c23f4da16ae3c63b3b6ca4616683313499c3a" + integrity sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ== + +hast-util-raw@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/hast-util-raw/-/hast-util-raw-6.0.1.tgz#973b15930b7529a7b66984c98148b46526885977" + integrity sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig== + dependencies: + "@types/hast" "^2.0.0" + hast-util-from-parse5 "^6.0.0" + hast-util-to-parse5 "^6.0.0" + html-void-elements "^1.0.0" + parse5 "^6.0.0" + unist-util-position "^3.0.0" + vfile "^4.0.0" + web-namespaces "^1.0.0" + xtend "^4.0.0" + zwitch "^1.0.0" + +hast-util-to-parse5@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz#1ec44650b631d72952066cea9b1445df699f8479" + integrity sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ== + dependencies: + hast-to-hyperscript "^9.0.0" + property-information "^5.0.0" + web-namespaces "^1.0.0" + xtend "^4.0.0" + zwitch "^1.0.0" + +hastscript@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-6.0.0.tgz#e8768d7eac56c3fdeac8a92830d58e811e5bf640" + integrity sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w== + dependencies: + "@types/hast" "^2.0.0" + comma-separated-tokens "^1.0.0" + hast-util-parse-selector "^2.0.0" + property-information "^5.0.0" + space-separated-tokens "^1.0.0" + hdr-histogram-js@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/hdr-histogram-js/-/hdr-histogram-js-2.0.1.tgz#ecb1ff2bcb6181c3e93ff4af9472c28c7e97284e" @@ -4226,12 +9394,36 @@ hdr-histogram-percentiles-obj@^3.0.0: resolved "https://registry.yarnpkg.com/hdr-histogram-percentiles-obj/-/hdr-histogram-percentiles-obj-3.0.0.tgz#9409f4de0c2dda78e61de2d9d78b1e9f3cba283c" integrity sha512-7kIufnBqdsBGcSZLPJwqHT3yhk1QTsSlFsVD3kx5ixH/AlgBs9yM1q6DPhXZ8f8gtdqgh7N7/5btRLpQsS2gHw== -hosted-git-info@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.0.2.tgz#5e425507eede4fea846b7262f0838456c4209961" - integrity sha512-c9OGXbZ3guC/xOlCg1Ci/VgWlwsqDv1yMQL1CWqXDL0hDjXuNcq0zuR4xqPSuasI3kqFDhqSyTjREz5gzq0fXg== +he@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" + integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw== + +highlight.js@^10.4.1, highlight.js@~10.7.0: + version "10.7.3" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" + integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== + +hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + integrity sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg== dependencies: - lru-cache "^6.0.0" + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hosted-git-info@^2.1.4: + version "2.8.9" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" + integrity sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw== + +hosted-git-info@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-5.0.0.tgz#df7a06678b4ebd722139786303db80fdf302ea56" + integrity sha512-rRnjWu0Bxj+nIfUOkz0695C0H6tRrN5iYIzYejb0tDEefe2AekHu/U5Kn9pEie5vsJqpNQU02az7TGSH3qpz4Q== + dependencies: + lru-cache "^7.5.1" hpack.js@^2.1.6: version "2.1.6" @@ -4243,10 +9435,107 @@ hpack.js@^2.1.6: readable-stream "^2.0.1" wbuf "^1.1.0" -html-entities@^1.3.1: - version "1.4.0" - resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.4.0.tgz#cfbd1b01d2afaf9adca1b10ae7dffab98c71d2dc" - integrity sha512-8nxjcBcd8wovbeKx7h3wTji4e6+rhaVuPNpMqwWgnHh+N9ToqsCs6XztWRBPQ+UtzsoMAdKZtUENoVzU/EMtZA== +html-entities@^2.1.0: + version "2.3.3" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.3.tgz#117d7626bece327fc8baace8868fa6f5ef856e46" + integrity sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA== + +html-entities@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-2.3.2.tgz#760b404685cb1d794e4f4b744332e3b00dcfe488" + integrity sha512-c3Ab/url5ksaT0WyleslpBEthOzWhrjQbg75y7XUsfSzi3Dgzt0l8w5e7DylRn15MTlMMD58dTfzddNS2kcAjQ== + +html-minifier-terser@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-5.1.1.tgz#922e96f1f3bb60832c2634b79884096389b1f054" + integrity sha512-ZPr5MNObqnV/T9akshPKbVgyOqLmy+Bxo7juKCfTfnjNniTAMdy4hz21YQqoofMBJD2kdREaqPPdThoR78Tgxg== + dependencies: + camel-case "^4.1.1" + clean-css "^4.2.3" + commander "^4.1.1" + he "^1.2.0" + param-case "^3.0.3" + relateurl "^0.2.7" + terser "^4.6.3" + +html-minifier-terser@^6.0.2: + version "6.1.0" + resolved "https://registry.yarnpkg.com/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#bfc818934cc07918f6b3669f5774ecdfd48f32ab" + integrity sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw== + dependencies: + camel-case "^4.1.2" + clean-css "^5.2.2" + commander "^8.3.0" + he "^1.2.0" + param-case "^3.0.4" + relateurl "^0.2.7" + terser "^5.10.0" + +html-void-elements@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" + integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== + +html-webpack-plugin@^4.0.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.5.2.tgz#76fc83fa1a0f12dd5f7da0404a54e2699666bc12" + integrity sha512-q5oYdzjKUIPQVjOosjgvCHQOv9Ett9CYYHlgvJeXG0qQvdSojnBq4vAdQBwn1+yGveAwHCoe/rMR86ozX3+c2A== + dependencies: + "@types/html-minifier-terser" "^5.0.0" + "@types/tapable" "^1.0.5" + "@types/webpack" "^4.41.8" + html-minifier-terser "^5.0.1" + loader-utils "^1.2.3" + lodash "^4.17.20" + pretty-error "^2.1.1" + tapable "^1.1.3" + util.promisify "1.0.0" + +html-webpack-plugin@^5.0.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz#c3911936f57681c1f9f4d8b68c158cd9dfe52f50" + integrity sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw== + dependencies: + "@types/html-minifier-terser" "^6.0.0" + html-minifier-terser "^6.0.2" + lodash "^4.17.21" + pretty-error "^4.0.0" + tapable "^2.0.0" + +htmlparser2@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-6.1.0.tgz#c4d762b6c3371a05dbe65e94ae43a9f845fb8fb7" + integrity sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A== + dependencies: + domelementtype "^2.0.1" + domhandler "^4.0.0" + domutils "^2.5.2" + entities "^2.0.0" + +htmlparser2@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-8.0.1.tgz#abaa985474fcefe269bc761a779b544d7196d010" + integrity sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA== + dependencies: + domelementtype "^2.3.0" + domhandler "^5.0.2" + domutils "^3.0.1" + entities "^4.3.0" + +http-auth-connect@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/http-auth-connect/-/http-auth-connect-1.0.5.tgz#7796d361f9ac56d80ada8ff54c61aa857768335f" + integrity sha512-zykAOKpVAXyzhOLm6+xyB/RtRcfN3uDfH4Al73DIfeSb6B7nr0WToLI6UyyM6ohtcLmbBPksWXzVbEDStz8ObQ== + +http-auth@4.1.9: + version "4.1.9" + resolved "https://registry.yarnpkg.com/http-auth/-/http-auth-4.1.9.tgz#9f3204422a1d6ee53122c041711e61e8303a323e" + integrity sha512-kvPYxNGc9EKGTXvOMnTBQw2RZfuiSihK/mLw/a4pbtRueTE45S55Lw/3k5CktIf7Ak0veMKEIteDj4YkNmCzmQ== + dependencies: + apache-crypt "^1.1.2" + apache-md5 "^1.0.6" + bcryptjs "^2.4.3" + uuid "^8.3.2" http-cache-semantics@^4.1.0: version "4.1.0" @@ -4258,16 +9547,16 @@ http-deceiver@^1.2.7: resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" integrity sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc= -http-errors@1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.2.tgz#4f5029cf13239f31036e5b2e55292bcfbcc85c8f" - integrity sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg== +http-errors@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-2.0.0.tgz#b7774a1486ef73cf7667ac9ae0858c012c57b9d3" + integrity sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ== dependencies: - depd "~1.1.2" - inherits "2.0.3" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" + depd "2.0.0" + inherits "2.0.4" + setprototypeof "1.2.0" + statuses "2.0.1" + toidentifier "1.0.1" http-errors@~1.6.2: version "1.6.3" @@ -4279,17 +9568,6 @@ http-errors@~1.6.2: setprototypeof "1.1.0" statuses ">= 1.4.0 < 2" -http-errors@~1.7.2: - version "1.7.3" - resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.7.3.tgz#6c619e4f9c60308c38519498c14fbb10aacebb06" - integrity sha512-ZTTX0MWrsQ2ZAhA1cejAwDLycFsd7I7nVtnkT3Ol0aqodaKW+0CTZDQ1uBv5whptCnc8e8HeRRJxRs0kmm/Qfw== - dependencies: - depd "~1.1.2" - inherits "2.0.4" - setprototypeof "1.1.1" - statuses ">= 1.5.0 < 2" - toidentifier "1.0.0" - http-parser-js@>=0.5.1: version "0.5.3" resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.3.tgz#01d2709c79d41698bb01d4decc5e9da4e4a033d9" @@ -4304,17 +9582,27 @@ http-proxy-agent@^4.0.1: agent-base "6" debug "4" -http-proxy-middleware@0.19.1: - version "0.19.1" - resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz#183c7dc4aa1479150306498c210cdaf96080a43a" - integrity sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q== +http-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz#5129800203520d434f142bc78ff3c170800f2b43" + integrity sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w== dependencies: - http-proxy "^1.17.0" - is-glob "^4.0.0" - lodash "^4.17.11" - micromatch "^3.1.10" + "@tootallnate/once" "2" + agent-base "6" + debug "4" -http-proxy@^1.17.0: +http-proxy-middleware@^2.0.3: + version "2.0.6" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-2.0.6.tgz#e1a4dd6979572c7ab5a4e4b55095d1f32a74963f" + integrity sha512-ya/UeJ6HVBYxrgYotAZo1KvPWlgB48kUJLDePFeneHsVujFaW5WNj2NgWCAE//B1Dl02BIfYlpNgBy8Kf8Rjmw== + dependencies: + "@types/http-proxy" "^1.17.8" + http-proxy "^1.18.1" + is-glob "^4.0.1" + is-plain-obj "^3.0.0" + micromatch "^4.0.2" + +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== @@ -4332,10 +9620,15 @@ http-signature@~1.2.0: jsprim "^1.2.2" sshpk "^1.7.0" -https-proxy-agent@5.0.0, https-proxy-agent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" - integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== + +https-proxy-agent@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz#c59ef224a04fe8b754f3db0063a25ea30d0005d6" + integrity sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA== dependencies: agent-base "6" debug "4" @@ -4348,6 +9641,24 @@ https-proxy-agent@^2.2.1: agent-base "^4.3.0" debug "^3.1.0" +https-proxy-agent@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz#e2a90542abb68a762e0a0850f6c9edadfd8506b2" + integrity sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA== + dependencies: + agent-base "6" + debug "4" + +human-signals@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-1.1.1.tgz#c5b1cd14f50aeae09ab6c59fe63ba3395fe4dfa3" + integrity sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw== + +human-signals@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/human-signals/-/human-signals-2.1.0.tgz#dc91fcba42e4d06e4abaed33b3e7a3c02f514ea0" + integrity sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw== + humanize-ms@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/humanize-ms/-/humanize-ms-1.2.1.tgz#c46e3159a293f6b896da29316d8b6fe8bb79bbed" @@ -4355,6 +9666,13 @@ humanize-ms@^1.2.1: dependencies: ms "^2.0.0" +i18next@^21.6.11: + version "21.8.14" + resolved "https://registry.yarnpkg.com/i18next/-/i18next-21.8.14.tgz#03a3a669ef4520aadd9d152c80596f600e287c6a" + integrity sha512-4Yi+DtexvMm/Yw3Q9fllzY12SgLk+Mcmar+rCAccsOPul/2UmnBzoHbTGn/L48IPkFcmrNaH7xTLboBWIbH6pw== + dependencies: + "@babel/runtime" "^7.17.2" + iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: version "0.4.24" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b" @@ -4362,34 +9680,51 @@ iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4: dependencies: safer-buffer ">= 2.1.2 < 3" -iconv-lite@^0.6.2: +iconv-lite@^0.6.2, iconv-lite@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" integrity sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw== dependencies: safer-buffer ">= 2.1.2 < 3.0.0" +icss-utils@^4.0.0, icss-utils@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-4.1.1.tgz#21170b53789ee27447c2f47dd683081403f9a467" + integrity sha512-4aFq7wvWyMHKgxsH8QQtGpvbASCf+eM3wPRLI6R+MgAnTCZ6STYsRvttLvRWK0Nfif5piF394St3HeJDaljGPA== + dependencies: + postcss "^7.0.14" + icss-utils@^5.0.0, icss-utils@^5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== -ieee754@^1.1.13: +ieee754@^1.1.13, ieee754@^1.1.4: version "1.2.1" resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -ignore-walk@^3.0.3: - version "3.0.4" - resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.4.tgz#c9a09f69b7c7b479a5d74ac1a3c0d4236d2a6335" - integrity sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ== - dependencies: - minimatch "^3.0.4" +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + integrity sha512-DUNFN5j7Tln0D+TxzloUjKB+CtVu6myn0JEFak6dG18mNt9YkQ6lzGCdafwofISZ1lLF3xRHJ98VKy9ynkcFaA== -ignore@^5.1.4: - version "5.1.8" - resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.8.tgz#f150a8b50a34289b33e22f5889abd4d8016f0e57" - integrity sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw== +ignore-walk@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-5.0.1.tgz#5f199e23e1288f518d90358d461387788a154776" + integrity sha512-yemi4pMf51WKT7khInJqAvsIGzoqYXblnsz0ql8tM+yi1EKYTY1evX4NAbJrLL/Aanr2HyZeluqU+Oi7MGHokw== + dependencies: + minimatch "^5.0.1" + +ignore@^4.0.3: + version "4.0.6" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" + integrity sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg== + +ignore@^5.1.9, ignore@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.2.0.tgz#6d3bac8fa7fe0d45d9f9be7bac2fc279577e345a" + integrity sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ== image-size@~0.5.0: version "0.5.5" @@ -4406,7 +9741,12 @@ immer@^9.0.6: resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.6.tgz#7a96bf2674d06c8143e327cbf73539388ddf1a73" integrity sha512-G95ivKpy+EvVAnAab4fVa4YGYn24J1SpEktnJX7JJ45Bd7xqME/SCplFzYFmTbrkwZbQ4xJK1xMTUYBkN6pWsQ== -import-fresh@^3.2.1: +immutable@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-4.0.0.tgz#b86f78de6adef3608395efb269a91462797e2c23" + integrity sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw== + +import-fresh@^3.1.0, import-fresh@^3.2.1: version "3.3.0" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b" integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw== @@ -4414,30 +9754,24 @@ import-fresh@^3.2.1: parent-module "^1.0.0" resolve-from "^4.0.0" -import-local@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" - integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== - dependencies: - pkg-dir "^3.0.0" - resolve-cwd "^2.0.0" - imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" integrity sha1-khi5srkoojixPcT7a21XbyMUU+o= +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + integrity sha512-aqwDFWSgSgfRaEwao5lg5KEcVd/2a+D1rvoG7NdilmYz0NwRk6StWpWdz/Hpk34MKPpx7s8XxUqimfcQK6gGlg== + dependencies: + repeating "^2.0.0" + indent-string@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-4.0.0.tgz#624f8f4497d619b2d9768531d58f4122854d7251" integrity sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg== -indexes-of@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/indexes-of/-/indexes-of-1.0.1.tgz#f30f716c8e2bd346c7b67d3df3915566a7c05607" - integrity sha1-8w9xbI4r00bHtn0985FVZqfAVgc= - -infer-owner@^1.0.4: +infer-owner@^1.0.3, infer-owner@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/infer-owner/-/infer-owner-1.0.4.tgz#c4cefcaa8e51051c2a40ba2ce8a3d27295af9467" integrity sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A== @@ -4450,30 +9784,40 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.0, inherits@^2.0.1, inherits@^2.0.3, inherits@^2.0.4, inherits@~2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + integrity sha512-8nWq2nLTAwd02jTqJExUYFSD/fKq6VH9Y/oG2accc/kdI0V98Bag8d5a4gi3XHz73rDWa2PvTtvcWYquKqSENA== + inherits@2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ini/-/ini-2.0.0.tgz#e5fd556ecdd5726be978fa1001862eacb0a94bc5" - integrity sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA== +ini@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ini/-/ini-3.0.0.tgz#2f6de95006923aa75feed8894f5686165adc08f1" + integrity sha512-TxYQaeNW/N8ymDvwAxPyRbhMBtnEwuvaTYpOQkFx1nSeusgezHniEc/l35Vo4iCq/mMiTJbpD7oYxN98hFlfmw== ini@^1.3.4: version "1.3.8" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.8.tgz#a29da425b48806f34767a4efce397269af28432c" integrity sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew== -inquirer@8.1.2: - version "8.1.2" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.1.2.tgz#65b204d2cd7fb63400edd925dfe428bafd422e3d" - integrity sha512-DHLKJwLPNgkfwNmsuEUKSejJFbkv0FMO9SMiQbjI3n5NQuCrSIBqP66ggqyz2a6t2qEolKrMjhQ3+W/xXgUQ+Q== +inline-style-parser@0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/inline-style-parser/-/inline-style-parser-0.1.1.tgz#ec8a3b429274e9c0a1f1c4ffa9453a7fef72cea1" + integrity sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q== + +inquirer@8.2.4: + version "8.2.4" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-8.2.4.tgz#ddbfe86ca2f67649a67daa6f1051c128f684f0b4" + integrity sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg== dependencies: ansi-escapes "^4.2.1" chalk "^4.1.1" @@ -4483,42 +9827,59 @@ inquirer@8.1.2: figures "^3.0.0" lodash "^4.17.21" mute-stream "0.0.8" - ora "^5.3.0" + ora "^5.4.1" run-async "^2.4.0" - rxjs "^7.2.0" + rxjs "^7.5.5" string-width "^4.1.0" strip-ansi "^6.0.0" through "^2.3.6" + wrap-ansi "^7.0.0" -internal-ip@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-4.3.0.tgz#845452baad9d2ca3b69c635a137acb9a0dad0907" - integrity sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg== +inside@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/inside/-/inside-1.0.0.tgz#db45e993573cdb3db70b9832e8285bad46424770" + integrity sha512-tvFwvS4g7q6iDot/4FjtWFHwwpv6TVvEumbTdLQilk1F07ojakbXPQcvf3kMAlyNDpzKRzn+d33O3RuXODuxZQ== + +internal-slot@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/internal-slot/-/internal-slot-1.0.3.tgz#7347e307deeea2faac2ac6205d4bc7d34967f59c" + integrity sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA== dependencies: - default-gateway "^4.2.0" - ipaddr.js "^1.9.0" + get-intrinsic "^1.1.0" + has "^1.0.3" + side-channel "^1.0.4" + +interpret@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" + integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== invert-kv@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-2.0.0.tgz#7393f5afa59ec9ff5f67a27620d11c226e3eec02" integrity sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA== -ip-regex@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/ip-regex/-/ip-regex-2.1.0.tgz#fa78bf5d2e6913c911ce9f819ee5146bb6d844e9" - integrity sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk= - -ip@^1.1.0, ip@^1.1.5: +ip@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.5.tgz#bdded70114290828c0a039e72ef25f5aaec4354a" integrity sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo= -ipaddr.js@1.9.1, ipaddr.js@^1.9.0: +ip@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ip/-/ip-2.0.0.tgz#4cf4ab182fee2314c75ede1276f8c80b479936da" + integrity sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ== + +ipaddr.js@1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.9.1.tgz#bff38543eeb8984825079ff3a2a8e6cbd46781b3" integrity sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g== -is-absolute-url@^3.0.3: +ipaddr.js@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-2.0.1.tgz#eca256a7a877e917aeb368b0a7497ddf42ef81c0" + integrity sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng== + +is-absolute-url@^3.0.0: version "3.0.3" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-3.0.3.tgz#96c6a22b6a23929b11ea0afb1836c36ad4a5d698" integrity sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q== @@ -4526,7 +9887,7 @@ is-absolute-url@^3.0.3: is-accessor-descriptor@^0.1.6: version "0.1.6" resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" - integrity sha1-qeEss66Nh2cn7u84Q/igiXtcmNY= + integrity sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A== dependencies: kind-of "^3.0.2" @@ -4537,7 +9898,20 @@ is-accessor-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" -is-arguments@^1.0.4: +is-alphabetical@1.0.4, is-alphabetical@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-alphabetical/-/is-alphabetical-1.0.4.tgz#9e7d6b94916be22153745d184c298cbf986a686d" + integrity sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg== + +is-alphanumerical@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz#7eb9a2431f855f6b1ef1a78e326df515696c4dbf" + integrity sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A== + dependencies: + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + +is-arguments@^1.0.4, is-arguments@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.1.1.tgz#15b3f88fda01f2a97fec84ca761a560f123efa9b" integrity sha512-8Q7EARjzEnKpt/PCD7e1cgUS0a6X8u5tdSiMqXhojOdoV9TsMsiO+9VLC5vAmO8N7/GmXn7yjR8qnA6bVAEzfA== @@ -4550,10 +9924,17 @@ is-arrayish@^0.2.1: resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0= +is-bigint@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-bigint/-/is-bigint-1.0.4.tgz#08147a1875bc2b32005d41ccd8291dffc6691df3" + integrity sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg== + dependencies: + has-bigints "^1.0.1" + is-binary-path@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" - integrity sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg= + integrity sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q== dependencies: binary-extensions "^1.0.0" @@ -4564,11 +9945,36 @@ is-binary-path@~2.1.0: dependencies: binary-extensions "^2.0.0" +is-boolean-object@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.1.2.tgz#5c6dc200246dd9321ae4b885a114bb1f75f63719" + integrity sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA== + dependencies: + call-bind "^1.0.2" + has-tostringtag "^1.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" integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w== +is-buffer@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.5.tgz#ebc252e400d22ff8d77fa09888821a24a658c191" + integrity sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ== + +is-callable@^1.1.4, is-callable@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.4.tgz#47301d58dd0259407865547853df6d61fe471945" + integrity sha512-nsuwtxZfMX67Oryl9LCQ+upnC0Z0BgpwntpS89m1H/TLF0zNfzfLMV/9Wa/6MZsj0acpEjAO0KF1xT6ZdLl95w== + +is-ci@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-2.0.0.tgz#6bc6334181810e04b5c22b3d589fdca55026404c" + integrity sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w== + dependencies: + ci-info "^2.0.0" + is-core-module@^2.2.0: version "2.7.0" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.7.0.tgz#3c0ef7d31b4acfc574f80c58409d568a836848e3" @@ -4576,10 +9982,24 @@ is-core-module@^2.2.0: dependencies: has "^1.0.3" +is-core-module@^2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.8.1.tgz#f59fdfca701d5879d0a6b100a40aa1560ce27211" + integrity sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA== + dependencies: + has "^1.0.3" + +is-core-module@^2.9.0: + version "2.9.0" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.9.0.tgz#e1c34429cd51c6dd9e09e0799e396e27b19a9c69" + integrity sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A== + dependencies: + has "^1.0.3" + is-data-descriptor@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" - integrity sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y= + integrity sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg== dependencies: kind-of "^3.0.2" @@ -4597,6 +10017,11 @@ is-date-object@^1.0.1: dependencies: has-tostringtag "^1.0.0" +is-decimal@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.4.tgz#65a3a5958a1c5b63a706e1b333d7cd9f630d3fa5" + integrity sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw== + is-descriptor@^0.1.0: version "0.1.6" resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" @@ -4620,10 +10045,18 @@ is-docker@^2.0.0, is-docker@^2.1.1: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.2.1.tgz#33eeabe23cfe86f14bde4408a02c0cfb853acdaa" integrity sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ== +is-dom@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.1.0.tgz#af1fced292742443bb59ca3f76ab5e80907b4e8a" + integrity sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ== + dependencies: + is-object "^1.0.1" + is-window "^1.0.2" + is-extendable@^0.1.0, is-extendable@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" - integrity sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik= + integrity sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw== is-extendable@^1.0.1: version "1.0.1" @@ -4637,6 +10070,11 @@ is-extglob@^2.1.0, is-extglob@^2.1.1: resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" integrity sha1-qIwCU1eR8C7TfHahueqXc8gz+MI= +is-finite@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.1.0.tgz#904135c77fb42c0641d6aa1bcdbc4daa8da082f3" + integrity sha512-cdyMtqX/BOqqNBBiKlIVkytNHm49MtMlYyn1zxzvJKWmFMlGzm+ry5BBfYyeY9YmNKbRSo/o7OX9w9ale0wg3w== + is-fullwidth-code-point@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" @@ -4654,10 +10092,15 @@ is-fullwidth-code-point@^3.0.0: resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz#f116f8064fe90b3f7844a38997c0b75051269f1d" integrity sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg== -is-glob@^3.1.0: +is-function@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-function/-/is-function-1.0.2.tgz#4f097f30abf6efadac9833b17ca5dc03f8144e08" + integrity sha512-lw7DUp0aWXYg+CBCN+JKkcE0Q2RayZnSvnZBlwgxHBQhqt5pZNVy4Ri7H9GmmXkdu7LUthszM+Tor1u/2iBcpQ== + +is-glob@^3.0.0, is-glob@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" - integrity sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo= + integrity sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw== dependencies: is-extglob "^2.1.0" @@ -4668,6 +10111,11 @@ is-glob@^4.0.0, is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: dependencies: is-extglob "^2.1.1" +is-hexadecimal@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz#cc35c97588da4bd49a8eedd6bc4082d44dcb23a7" + integrity sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw== + is-interactive@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" @@ -4678,10 +10126,27 @@ is-lambda@^1.0.1: resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" integrity sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU= +is-map@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-map/-/is-map-2.0.2.tgz#00922db8c9bf73e81b7a335827bc2a43f2b91127" + integrity sha512-cOZFQQozTha1f4MxLFzlgKYPTyj26picdZTx82hbc/Xf4K/tZOOXSCkMvU4pKioRXGDLJRn0GM7Upe7kR721yg== + +is-negative-zero@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-negative-zero/-/is-negative-zero-2.0.2.tgz#7bf6f03a28003b8b3965de3ac26f664d765f3150" + integrity sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA== + +is-number-object@^1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-number-object/-/is-number-object-1.0.7.tgz#59d50ada4c45251784e9904f5246c742f07a42fc" + integrity sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ== + dependencies: + has-tostringtag "^1.0.0" + is-number@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" - integrity sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU= + integrity sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg== dependencies: kind-of "^3.0.2" @@ -4690,16 +10155,16 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-object@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.2.tgz#a56552e1c665c9e950b4a025461da87e72f86fcf" + integrity sha512-2rRIahhZr2UWb45fIOuvZGpFtz0TyOZLf32KxBbSoUCeZR495zCKlWUKKUByk3geS2eAs7ZAABt0Y/Rx0GiQGA== + is-path-cwd@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-1.0.0.tgz#d225ec23132e89edd38fda767472e62e65f1106d" integrity sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0= -is-path-cwd@^2.0.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/is-path-cwd/-/is-path-cwd-2.2.0.tgz#67d43b82664a7b5191fd9119127eb300048a9fdb" - integrity sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ== - is-path-in-cwd@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz#5ac48b345ef675339bd6c7a48a912110b241cf52" @@ -4707,13 +10172,6 @@ is-path-in-cwd@^1.0.0: dependencies: is-path-inside "^1.0.0" -is-path-in-cwd@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz#bfe2dca26c69f397265a4009963602935a053acb" - integrity sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ== - dependencies: - is-path-inside "^2.1.0" - is-path-inside@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-1.0.1.tgz#8ef5b7de50437a3fdca6b4e865ef7aa55cb48036" @@ -4721,12 +10179,15 @@ is-path-inside@^1.0.0: dependencies: path-is-inside "^1.0.1" -is-path-inside@^2.1.0: +is-plain-obj@^2.0.0: version "2.1.0" - resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-2.1.0.tgz#7c9810587d659a40d27bcdb4d5616eab059494b2" - integrity sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg== - dependencies: - path-is-inside "^1.0.2" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-2.1.0.tgz#45e42e37fccf1f40da8e5f76ee21515840c09287" + integrity sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA== + +is-plain-obj@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-3.0.0.tgz#af6f2ea14ac5a646183a5bbdb5baabbc156ad9d7" + integrity sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA== is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" @@ -4735,7 +10196,7 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-regex@^1.0.4: +is-regex@^1.0.4, is-regex@^1.1.2, is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== @@ -4743,17 +10204,43 @@ is-regex@^1.0.4: call-bind "^1.0.2" has-tostringtag "^1.0.0" -is-resolvable@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" - integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== +is-set@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/is-set/-/is-set-2.0.2.tgz#90755fa4c2562dc1c5d4024760d6119b94ca18ec" + integrity sha512-+2cnTEZeY5z/iXGbLhPrOAaK/Mau5k5eXq9j14CpRTftq0pAJu2MwVRSZhyZWBzx3o6X795Lz6Bpb6R0GKf37g== + +is-shared-array-buffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz#8f259c573b60b6a32d4058a1a07430c0a7344c79" + integrity sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA== + dependencies: + call-bind "^1.0.2" is-stream@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" integrity sha1-EtSj3U5o4Lec6428hBc66A2RykQ= -is-typedarray@~1.0.0: +is-stream@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-2.0.1.tgz#fac1e3d53b97ad5a9d0ae9cef2389f5810a5c077" + integrity sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg== + +is-string@^1.0.5, is-string@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/is-string/-/is-string-1.0.7.tgz#0dd12bf2006f255bb58f695110eff7491eebc0fd" + integrity sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg== + dependencies: + has-tostringtag "^1.0.0" + +is-symbol@^1.0.2, is-symbol@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.4.tgz#a6dac93b635b063ca6872236de88910a57af139c" + integrity sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg== + dependencies: + has-symbols "^1.0.2" + +is-typedarray@^1.0.0, is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" integrity sha1-5HnICFjfDBsR3dppQPlgEfzaSpo= @@ -4763,34 +10250,61 @@ is-unicode-supported@^0.1.0: resolved "https://registry.yarnpkg.com/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz#3f26c76a809593b52bfa2ecb5710ed2779b522a7" integrity sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw== +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + integrity sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q== + +is-weakref@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-weakref/-/is-weakref-1.0.2.tgz#9529f383a9338205e89765e0392efc2f100f06f2" + integrity sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ== + dependencies: + call-bind "^1.0.2" + is-what@^3.12.0: version "3.14.1" resolved "https://registry.yarnpkg.com/is-what/-/is-what-3.14.1.tgz#e1222f46ddda85dead0fd1c9df131760e77755c1" integrity sha512-sNxgpk9793nzSs7bA6JQJGeIuRBQhAaNGG77kzYQgMkrID+lS6SlK07K5LaptscDlSaIgH+GPFzf+d75FVxozA== +is-whitespace-character@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz#0858edd94a95594c7c9dd0b5c174ec6e45ee4aa7" + integrity sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w== + +is-window@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-window/-/is-window-1.0.2.tgz#2c896ca53db97de45d3c33133a65d8c9f563480d" + integrity sha512-uj00kdXyZb9t9RcAUAwMZAnkBUwdYGhYlt7djMXhfyhUCzwNba50tIiBKR7q0l7tdoBtFVw/3JmLY6fI3rmZmg== + is-windows@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" integrity sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA== +is-word-character@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-word-character/-/is-word-character-1.0.4.tgz#ce0e73216f98599060592f62ff31354ddbeb0230" + integrity sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA== + is-wsl@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-1.1.0.tgz#1f16e4aa22b04d1336b66188a66af3c600c3a66d" - integrity sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0= + integrity sha512-gfygJYZ2gLTDlmbWMI0CE2MwnFzSN/2SZfkMlItC4K/JBlsWVDB0bO6XhqcY13YXE7iMcAJnzTCJjPiTeJJ0Mw== -is-wsl@^2.2.0: +is-wsl@^2.1.1, is-wsl@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/is-wsl/-/is-wsl-2.2.0.tgz#74a4c76e77ca9fd3f932f290c17ea326cd157271" integrity sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww== dependencies: is-docker "^2.0.0" -isarray@1.0.0, isarray@~1.0.0: +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" integrity sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE= -isarray@^2.0.1: +isarray@^2.0.5: version "2.0.5" resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.5.tgz#8af1e4c1221244cc62459faf38940d4e644a5723" integrity sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw== @@ -4803,7 +10317,7 @@ isexe@^2.0.0: isobject@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" - integrity sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk= + integrity sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA== dependencies: isarray "1.0.0" @@ -4812,26 +10326,53 @@ isobject@^3.0.0, isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha1-TkMekrEalzFjaqH5yNHMvP2reN8= +isobject@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" + integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== + +isomorphic-unfetch@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz#87341d5f4f7b63843d468438128cb087b7c3e98f" + integrity sha512-geDJjpoZ8N0kWexiwkX8F9NkTsXhetLPVbZFQ+JTW239QNOwvB0gniuR1Wc6f0AMTn7/mFGyXvHTifrCp/GH8Q== + dependencies: + node-fetch "^2.6.1" + unfetch "^4.2.0" + isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo= -istanbul-lib-coverage@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.2.tgz#36786d4d82aad2ea5911007e255e2da6b5f80d86" - integrity sha512-o5+eTUYzCJ11/+JhW5/FUCdfsdoYVdQ/8I/OveE2XsjehYn5DdeSnNQAbjYaO8gQ6hvGTN6GM6ddQqpTVG5j8g== +istanbul-lib-coverage@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz#189e7909d0a39fa5a3dfad5b03f71947770191d3" + integrity sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw== -istanbul-lib-instrument@^4.0.3: - version "4.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz#873c6fff897450118222774696a3f28902d77c1d" - integrity sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ== +istanbul-lib-instrument@^5.0.4: + version "5.1.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz#7b49198b657b27a730b8e9cb601f1e1bff24c59a" + integrity sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q== dependencies: - "@babel/core" "^7.7.5" + "@babel/core" "^7.12.3" + "@babel/parser" "^7.14.7" "@istanbuljs/schema" "^0.1.2" - istanbul-lib-coverage "^3.0.0" + istanbul-lib-coverage "^3.2.0" semver "^6.3.0" +iterate-iterator@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.2.tgz#551b804c9eaa15b847ea6a7cdc2f5bf1ec150f91" + integrity sha512-t91HubM4ZDQ70M9wqp+pcNpu8OyJ9UAtXntT/Bcsvp5tZMnz9vRa+IunKXeI8AnfZMTv0jNuVEmGeLSMjVvfPw== + +iterate-value@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/iterate-value/-/iterate-value-1.0.2.tgz#935115bd37d006a52046535ebc8d07e9c9337f57" + integrity sha512-A6fMAio4D2ot2r/TYzr4yUWrmwNdsN5xL7+HUiyACE4DXm+q8HtPcnFTp+NnW3k4N05tZ7FVYFFb2CR13NxyHQ== + dependencies: + es-get-iterator "^1.0.2" + iterate-iterator "^1.0.1" + jasmine-core@~2.8.0: version "2.8.0" resolved "https://registry.yarnpkg.com/jasmine-core/-/jasmine-core-2.8.0.tgz#bcc979ae1f9fd05701e45e52e65d3a5d63f1a24e" @@ -4851,7 +10392,70 @@ jasminewd2@^2.1.0: resolved "https://registry.yarnpkg.com/jasminewd2/-/jasminewd2-2.2.0.tgz#e37cf0b17f199cce23bea71b2039395246b4ec4e" integrity sha1-43zwsX8ZnM4jvqcbIDk5Uka07E4= -jest-worker@^27.0.2, jest-worker@^27.0.6: +jest-haste-map@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-26.6.2.tgz#dd7e60fe7dc0e9f911a23d79c5ff7fb5c2cafeaa" + integrity sha512-easWIJXIw71B2RdR8kgqpjQrbMRWQBgiBwXYEhtGUTaX+doCjBheluShdDMeR8IMfJiTqH4+zfhtg29apJf/8w== + dependencies: + "@jest/types" "^26.6.2" + "@types/graceful-fs" "^4.1.2" + "@types/node" "*" + anymatch "^3.0.3" + fb-watchman "^2.0.0" + graceful-fs "^4.2.4" + jest-regex-util "^26.0.0" + jest-serializer "^26.6.2" + jest-util "^26.6.2" + jest-worker "^26.6.2" + micromatch "^4.0.2" + sane "^4.0.3" + walker "^1.0.7" + optionalDependencies: + fsevents "^2.1.2" + +jest-mock@^27.0.6: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-27.5.1.tgz#19948336d49ef4d9c52021d34ac7b5f36ff967d6" + integrity sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og== + dependencies: + "@jest/types" "^27.5.1" + "@types/node" "*" + +jest-regex-util@^26.0.0: + version "26.0.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-26.0.0.tgz#d25e7184b36e39fd466c3bc41be0971e821fee28" + integrity sha512-Gv3ZIs/nA48/Zvjrl34bf+oD76JHiGDUxNOVgUjh3j890sblXryjY4rss71fPtD/njchl6PSE2hIhvyWa1eT0A== + +jest-serializer@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-26.6.2.tgz#d139aafd46957d3a448f3a6cdabe2919ba0742d1" + integrity sha512-S5wqyz0DXnNJPd/xfIzZ5Xnp1HrJWBczg8mMfMpN78OJ5eDxXyf+Ygld9wX1DnUWbIbhM1YDY95NjR4CBXkb2g== + dependencies: + "@types/node" "*" + graceful-fs "^4.2.4" + +jest-util@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-26.6.2.tgz#907535dbe4d5a6cb4c47ac9b926f6af29576cbc1" + integrity sha512-MDW0fKfsn0OI7MS7Euz6h8HNDXVQ0gaM9uW6RjfDmd1DAFcaxX9OqIakHIqhbnmF08Cf2DLDG+ulq8YQQ0Lp0Q== + dependencies: + "@jest/types" "^26.6.2" + "@types/node" "*" + chalk "^4.0.0" + graceful-fs "^4.2.4" + is-ci "^2.0.0" + micromatch "^4.0.2" + +jest-worker@^26.5.0, jest-worker@^26.6.2: + version "26.6.2" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" + integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^7.0.0" + +jest-worker@^27.0.6: version "27.2.5" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.2.5.tgz#ed42865661959488aa020e8a325df010597c36d4" integrity sha512-HTjEPZtcNKZ4LnhSp02NEH4vE+5OpJ0EsOWYvGQpHgUMLngydESAAMH5Wd/asPf29+XUDQZszxpLg1BkIIA2aw== @@ -4860,12 +10464,26 @@ jest-worker@^27.0.2, jest-worker@^27.0.6: merge-stream "^2.0.0" supports-color "^8.0.0" +jest-worker@^27.4.5: + version "27.5.1" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.5.1.tgz#8d146f0900e8973b106b6f73cc1e9a8cb86f8db0" + integrity sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg== + dependencies: + "@types/node" "*" + merge-stream "^2.0.0" + supports-color "^8.0.0" + jquery@3.3.1: version "3.3.1" resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca" integrity sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg== -js-tokens@^4.0.0: +js-string-escape@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/js-string-escape/-/js-string-escape-1.0.1.tgz#e2625badbc0d67c7533e9edc1068c587ae4137ef" + integrity sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg== + +"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ== @@ -4898,7 +10516,7 @@ json-parse-better-errors@^1.0.2: resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" integrity sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw== -json-parse-even-better-errors@^2.3.0: +json-parse-even-better-errors@^2.3.0, json-parse-even-better-errors@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d" integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w== @@ -4923,11 +10541,6 @@ json-stringify-safe@~5.0.1: resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" integrity sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus= -json3@^3.3.3: - version "3.3.3" - resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.3.tgz#7fc10e375fc5ae42c4705a5cc0aa6f62be305b81" - integrity sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA== - json5@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/json5/-/json5-1.0.1.tgz#779fb0018604fa854eacbf6252180d83543e3dbe" @@ -4935,18 +10548,32 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.1.0, json5@^2.1.2: +json5@^2.1.2: version "2.2.0" resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== dependencies: minimist "^1.2.5" +json5@^2.1.3, json5@^2.2.0, json5@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c" + integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA== + jsonc-parser@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.0.0.tgz#abdd785701c7e7eaca8a9ec8cf070ca51a745a22" integrity sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA== +jsonfile@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" + integrity sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ== + dependencies: + universalify "^2.0.0" + optionalDependencies: + graceful-fs "^4.1.6" + jsonparse@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/jsonparse/-/jsonparse-1.3.1.tgz#3f4dae4a91fac315f71062f8521cc239f1366280" @@ -4972,6 +10599,11 @@ jszip@^3.1.3: readable-stream "~2.3.6" set-immediate-shim "~1.0.1" +junk@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/junk/-/junk-3.1.0.tgz#31499098d902b7e98c5d9b9c80f43457a88abfa1" + integrity sha512-pBxcB3LFc8QVgdggvZWyeys+hnrNWg4OcZIU/1X59k5jQdLBlCsYGRQaz234SqoRLTCgMH00fY0xRJH+F9METQ== + karma-source-map-support@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz#58526ceccf7e8730e56effd97a4de8d712ac0d6b" @@ -4979,22 +10611,17 @@ karma-source-map-support@1.4.0: dependencies: source-map-support "^0.5.5" -killable@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/killable/-/killable-1.0.1.tgz#4c8ce441187a061c7474fb87ca08e2a638194892" - integrity sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg== - kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: version "3.2.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" - integrity sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ= + integrity sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ== dependencies: is-buffer "^1.1.5" kind-of@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" - integrity sha1-IIE989cSkosgc3hpGkUGb65y3Vc= + integrity sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw== dependencies: is-buffer "^1.1.5" @@ -5008,11 +10635,32 @@ 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@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + klona@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.4.tgz#7bb1e3affb0cb8624547ef7e8f6708ea2e39dfc0" integrity sha512-ZRbnvdg/NxqzC7L9Uyqzf4psi1OM4Cuc+sJAkQPjO6XkQIJTNbfK2Rsmbw8fx1p2mkZdp2FZYo2+LwXYY/uwIA== +klona@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/klona/-/klona-2.0.5.tgz#d166574d90076395d9963aa7a928fabb8d76afbc" + integrity sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ== + +lazy-universal-dotenv@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lazy-universal-dotenv/-/lazy-universal-dotenv-3.0.1.tgz#a6c8938414bca426ab8c9463940da451a911db38" + integrity sha512-prXSYk799h3GY3iOWnC6ZigYzMPjxN2svgjJ9shk7oMadSNX3wXy0B6F32PMJv7qtMnrIbUxoEHzbutvxR2LBQ== + dependencies: + "@babel/runtime" "^7.5.0" + app-root-dir "^1.0.2" + core-js "^3.0.4" + dotenv "^8.0.0" + dotenv-expand "^5.1.0" + lcid@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/lcid/-/lcid-2.0.0.tgz#6ef5d2df60e52f82eb228a4c373e8d1f397253cf" @@ -5020,21 +10668,21 @@ lcid@^2.0.0: dependencies: invert-kv "^2.0.0" -less-loader@10.0.1: - version "10.0.1" - resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-10.0.1.tgz#c05aaba68d00400820275f21c2ad87cb9fa9923f" - integrity sha512-Crln//HpW9M5CbtdfWm3IO66Cvx1WhZQvNybXgfB2dD/6Sav9ppw+IWqs/FQKPBFO4B6X0X28Z0WNznshgwUzA== +less-loader@10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/less-loader/-/less-loader-10.2.0.tgz#97286d8797dc3dc05b1d16b0ecec5f968bdd4e32" + integrity sha512-AV5KHWvCezW27GT90WATaDnfXBv99llDbtaj4bshq6DvAihMdNjaPDcUMa6EXKLRF+P2opFenJp89BXg91XLYg== dependencies: klona "^2.0.4" -less@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/less/-/less-4.1.1.tgz#15bf253a9939791dc690888c3ff424f3e6c7edba" - integrity sha512-w09o8tZFPThBscl5d0Ggp3RcrKIouBoQscnOMgFH3n5V3kN/CXGHNfCkRPtxJk6nKryDXaV9aHLK55RXuH4sAw== +less@4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/less/-/less-4.1.2.tgz#6099ee584999750c2624b65f80145f8674e4b4b0" + integrity sha512-EoQp/Et7OSOVu0aJknJOtlXZsnr8XE8KwuzTHOLeVSEx8pVWUICc8Q0VYRHgzyjX78nMEyC/oztWFbgyhtNfDA== dependencies: copy-anything "^2.0.1" parse-node-version "^1.0.1" - tslib "^1.10.0" + tslib "^2.3.0" optionalDependencies: errno "^0.1.1" graceful-fs "^4.1.2" @@ -5044,13 +10692,20 @@ less@4.1.1: needle "^2.5.2" source-map "~0.6.0" -license-webpack-plugin@2.3.20: - version "2.3.20" - resolved "https://registry.yarnpkg.com/license-webpack-plugin/-/license-webpack-plugin-2.3.20.tgz#f51fb674ca31519dbedbe1c7aabc036e5a7f2858" - integrity sha512-AHVueg9clOKACSHkhmEI+PCC9x8+qsQVuKECZD3ETxETK5h/PCv5/MUzyG1gm8OMcip/s1tcNxqo9Qb7WhjGsg== +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + integrity sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA== dependencies: - "@types/webpack-sources" "^0.1.5" - webpack-sources "^1.2.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + +license-webpack-plugin@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/license-webpack-plugin/-/license-webpack-plugin-4.0.2.tgz#1e18442ed20b754b82f1adeff42249b81d11aec6" + integrity sha512-771TFWFD70G1wLTC4oU2Cw4qvtmNrIw+wRvBtn+okgHl7slJVi7zfNcdmqDL72BojM30VNJ2UHylr1o77U37Jw== + dependencies: + webpack-sources "^3.0.0" lie@~3.3.0: version "3.3.0" @@ -5059,31 +10714,38 @@ lie@~3.3.0: dependencies: immediate "~3.0.5" -lilconfig@^2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/lilconfig/-/lilconfig-2.0.3.tgz#68f3005e921dafbd2a2afb48379986aa6d2579fd" - integrity sha512-EHKqr/+ZvdKCifpNrJCKxBTgk5XupZA3y/aCPY9mxfgBzmgh93Mt/WqjjQ38oMxXuvDokaKiM3lAgvSH2sjtHg== - lines-and-columns@^1.1.6: version "1.1.6" resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + integrity sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A== + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +loader-runner@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" + integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== + loader-runner@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-4.2.0.tgz#d7022380d66d14c5fb1d496b89864ebcfd478384" integrity sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw== -loader-utils@2.0.0, loader-utils@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" - integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== - dependencies: - big.js "^5.2.2" - emojis-list "^3.0.0" - json5 "^2.1.2" +loader-utils@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-3.2.0.tgz#bcecc51a7898bee7473d4bc6b845b23af8304d4f" + integrity sha512-HVl9ZqccQihZ7JM85dco1MvO9G+ONvxoGa9rkhzFsneGLKSUg1gJf9bWzhRhcvm2qChhWpebQhP44qxjKIUCaQ== -loader-utils@^1.0.2, loader-utils@^1.4.0: +loader-utils@^1.0.2, loader-utils@^1.2.3: version "1.4.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== @@ -5092,6 +10754,15 @@ loader-utils@^1.0.2, loader-utils@^1.4.0: emojis-list "^3.0.0" json5 "^1.0.1" +loader-utils@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-2.0.0.tgz#e4cace5b816d425a166b5f097e10cd12b36064b0" + integrity sha512-rP4F0h2RaWSvPEkD7BLDFQnvSf+nK+wr3ESUjNTyAGobqrijmW92zc+SO6d4p4B1wh7+B/Jg1mkQe5NYUEHtHQ== + dependencies: + big.js "^5.2.2" + emojis-list "^3.0.0" + json5 "^2.1.2" + locate-path@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-3.0.0.tgz#dbec3b3ab759758071b58fe59fc41871af21400e" @@ -5107,22 +10778,29 @@ locate-path@^5.0.0: dependencies: p-locate "^4.1.0" +locate-path@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" + integrity sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw== + dependencies: + p-locate "^5.0.0" + lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" integrity sha1-gteb/zCmfEAF/9XiUVMArZyk168= -lodash.memoize@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" - integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + integrity sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA== -lodash.uniq@^4.5.0: +lodash.uniq@4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" - integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= + integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== -lodash@^4.17.11, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.21: +lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -5135,10 +10813,52 @@ log-symbols@^4.1.0: chalk "^4.1.0" is-unicode-supported "^0.1.0" -loglevel@^1.6.8: - version "1.7.1" - resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197" - integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw== +loglevel-plugin-prefix@^0.8.4: + version "0.8.4" + resolved "https://registry.yarnpkg.com/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz#2fe0e05f1a820317d98d8c123e634c1bd84ff644" + integrity sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g== + +loglevel@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.8.0.tgz#e7ec73a57e1e7b419cb6c6ac06bf050b67356114" + integrity sha512-G6A/nJLRgWOuuwdNuA6koovfEV1YpqqAG4pRUlFaz3jj2QNZ8M4vBqnVA+HBTmU/AMNUtlOsMmSpF6NyOjztbA== + +loose-envify@^1.1.0, loose-envify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q== + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +loud-rejection@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/loud-rejection/-/loud-rejection-1.6.0.tgz#5b46f80147edee578870f086d04821cf998e551f" + integrity sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ== + dependencies: + currently-unhandled "^0.4.1" + signal-exit "^3.0.0" + +lower-case@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/lower-case/-/lower-case-2.0.2.tgz#6fa237c63dbdc4a82ca0fd882e4722dc5e634e28" + integrity sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg== + dependencies: + tslib "^2.0.3" + +lowlight@^1.17.0: + version "1.20.0" + resolved "https://registry.yarnpkg.com/lowlight/-/lowlight-1.20.0.tgz#ddb197d33462ad0d93bf19d17b6c301aa3941888" + integrity sha512-8Ktj+prEb1RoCPkEOrPMYUN/nCggB7qAWe3a7OpMjWQkh3l2RD5wKRQ+o8Q8YuI9RG/xs95waaI/E6ym/7NsTw== + dependencies: + fault "^1.0.0" + highlight.js "~10.7.0" + +lru-cache@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" + integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w== + dependencies: + yallist "^3.0.2" lru-cache@^6.0.0: version "6.0.0" @@ -5147,19 +10867,60 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: + version "7.10.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.10.1.tgz#db577f42a94c168f676b638d15da8fb073448cab" + integrity sha512-BQuhQxPuRl79J5zSXRP+uNzPOyZw2oFI9JLRQ80XswSvg21KMKNtQza9eF42rfI/3Z40RvzBdXgziEkudzjo8A== + +lunr@^2.3.9: + version "2.3.9" + resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1" + integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow== + luxon@^1.10.0, luxon@^1.21.3: version "1.28.0" resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.28.0.tgz#e7f96daad3938c06a62de0fb027115d251251fbf" integrity sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ== -magic-string@0.25.7, magic-string@^0.25.0: +lz-string@^1.4.4: + version "1.4.4" + resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.4.4.tgz#c0d8eaf36059f705796e1e344811cf4c498d3a26" + integrity sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ== + +macos-release@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.5.0.tgz#067c2c88b5f3fb3c56a375b2ec93826220fa1ff2" + integrity sha512-EIgv+QZ9r+814gjJj0Bt5vSLJLzswGmSUbUpbi9AIr/fsN2IWFBl2NucV9PAiek+U1STK468tEkxmVYUtuAN3g== + +magic-string@0.25.1: + version "0.25.1" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.1.tgz#b1c248b399cd7485da0fe7385c2fc7011843266e" + integrity sha512-sCuTz6pYom8Rlt4ISPFn6wuFodbKMIHUMv4Qko9P17dpxb7s52KJTmRuZZqHdGmLCK9AOcDare039nRIcfdkEg== + dependencies: + sourcemap-codec "^1.4.1" + +magic-string@0.25.7: version "0.25.7" resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.7.tgz#3f497d6fd34c669c6798dcb821f2ef31f5445051" integrity sha512-4CrMT5DOHTDk4HYDlzmwu4FVCcIYI8gauveasrdCu2IKIFOJ3f0v/8MDGJCDL9oD2ppz/Av1b0Nj345H9M+XIA== dependencies: sourcemap-codec "^1.4.4" -make-dir@^2.1.0: +magic-string@0.26.1: + version "0.26.1" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.1.tgz#ba9b651354fa9512474199acecf9c6dbe93f97fd" + integrity sha512-ndThHmvgtieXe8J/VGPjG+Apu7v7ItcD5mhEIvOscWjPF/ccOiLxHaSuCAS2G+3x4GKsAbT8u7zdyamupui8Tg== + dependencies: + sourcemap-codec "^1.4.8" + +magic-string@^0.26.0: + version "0.26.2" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.26.2.tgz#5331700e4158cd6befda738bb6b0c7b93c0d4432" + integrity sha512-NzzlXpclt5zAbmo6h6jNc8zl2gNRGHvmsZW4IvZhTC4W7k4OlLP+S5YLussa/r3ixNT66KOQfNORlXHSOy/X4A== + dependencies: + sourcemap-codec "^1.4.8" + +make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" integrity sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA== @@ -5167,7 +10928,7 @@ make-dir@^2.1.0: pify "^4.0.1" semver "^5.6.0" -make-dir@^3.0.2, make-dir@^3.1.0: +make-dir@^3.0.0, make-dir@^3.0.2, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== @@ -5179,7 +10940,29 @@ make-error@^1.1.1: resolved "https://registry.yarnpkg.com/make-error/-/make-error-1.3.6.tgz#2eb2e37ea9b67c4891f684a1394799af484cf7a2" integrity sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw== -make-fetch-happen@^9.0.1: +make-fetch-happen@^10.0.6: + version "10.1.7" + resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-10.1.7.tgz#b1402cb3c9fad92b380ff3a863cdae5414a42f76" + integrity sha512-J/2xa2+7zlIUKqfyXDCXFpH3ypxO4k3rgkZHPSZkyUYcBT/hM80M3oyKLM/9dVriZFiGeGGS2Ei+0v2zfhqj3Q== + dependencies: + agentkeepalive "^4.2.1" + cacache "^16.1.0" + http-cache-semantics "^4.1.0" + http-proxy-agent "^5.0.0" + https-proxy-agent "^5.0.0" + is-lambda "^1.0.1" + lru-cache "^7.7.1" + minipass "^3.1.6" + minipass-collect "^1.0.2" + minipass-fetch "^2.0.3" + minipass-flush "^1.0.5" + minipass-pipeline "^1.2.4" + negotiator "^0.6.3" + promise-retry "^2.0.1" + socks-proxy-agent "^7.0.0" + ssri "^9.0.0" + +make-fetch-happen@^9.1.0: version "9.1.0" resolved "https://registry.yarnpkg.com/make-fetch-happen/-/make-fetch-happen-9.1.0.tgz#53085a09e7971433e6765f7971bf63f4e05cb968" integrity sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg== @@ -5201,6 +10984,13 @@ make-fetch-happen@^9.0.1: socks-proxy-agent "^6.0.0" ssri "^8.0.0" +makeerror@1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.12.tgz#3e5dd2079a82e812e983cc6610c4a2cb0eaa801a" + integrity sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg== + dependencies: + tmpl "1.0.5" + map-age-cleaner@^0.1.1, map-age-cleaner@^0.1.3: version "0.1.3" resolved "https://registry.yarnpkg.com/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz#7d583a7306434c055fe474b0f45078e6e1b4b92a" @@ -5211,19 +11001,86 @@ map-age-cleaner@^0.1.1, map-age-cleaner@^0.1.3: map-cache@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" - integrity sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8= + integrity sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg== + +map-obj@^1.0.0, map-obj@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-1.0.1.tgz#d933ceb9205d82bdcf4886f6742bdc2b4dea146d" + integrity sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg== + +map-or-similar@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/map-or-similar/-/map-or-similar-1.5.0.tgz#6de2653174adfb5d9edc33c69d3e92a1b76faf08" + integrity sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg== + +map-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.0.7.tgz#8a1f07896d82b10926bd3744a2420009f88974a8" + integrity sha512-C0X0KQmGm3N2ftbTGBhSyuydQ+vV1LC3f3zPvT3RXHXNZrvfPZcoXp/N5DOa8vedX/rTMm2CjTtivFg2STJMRQ== map-visit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" - integrity sha1-7Nyo8TFE5mDxtb1B8S80edmN+48= + integrity sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w== dependencies: object-visit "^1.0.0" -mdn-data@2.0.14: - version "2.0.14" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" - integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== +markdown-escapes@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535" + integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg== + +marked@^4.0.12: + version "4.0.18" + resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.18.tgz#cd0ac54b2e5610cfb90e8fd46ccaa8292c9ed569" + integrity sha512-wbLDJ7Zh0sqA0Vdg6aqlbT+yPxqLblpAZh1mK2+AO2twQkPywvvqQNfEPVwSSRjZ7dZcdeVBIAgiO7MMp3Dszw== + +md5.js@^1.3.4: + version "1.3.5" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" + integrity sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +mdast-squeeze-paragraphs@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz#7c4c114679c3bee27ef10b58e2e015be79f1ef97" + integrity sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ== + dependencies: + unist-util-remove "^2.0.0" + +mdast-util-definitions@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz#c5c1a84db799173b4dcf7643cda999e440c24db2" + integrity sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ== + dependencies: + unist-util-visit "^2.0.0" + +mdast-util-to-hast@10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz#0cfc82089494c52d46eb0e3edb7a4eb2aea021eb" + integrity sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA== + dependencies: + "@types/mdast" "^3.0.0" + "@types/unist" "^2.0.0" + mdast-util-definitions "^4.0.0" + mdurl "^1.0.0" + unist-builder "^2.0.0" + unist-util-generated "^1.0.0" + unist-util-position "^3.0.0" + unist-util-visit "^2.0.0" + +mdast-util-to-string@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz#27055500103f51637bd07d01da01eb1967a43527" + integrity sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A== + +mdurl@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e" + integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g== media-typer@0.3.0: version "0.3.0" @@ -5247,39 +11104,84 @@ mem@^8.1.1: map-age-cleaner "^0.1.3" mimic-fn "^3.1.0" -memfs@^3.2.2: - version "3.3.0" - resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.3.0.tgz#4da2d1fc40a04b170a56622c7164c6be2c4cbef2" - integrity sha512-BEE62uMfKOavX3iG7GYX43QJ+hAeeWnwIAuJ/R6q96jaMtiLzhsxHJC8B1L7fK7Pt/vXDRwb3SG/yBpNGDPqzg== +memfs@^3.1.2, memfs@^3.2.2: + version "3.4.7" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.7.tgz#e5252ad2242a724f938cb937e3c4f7ceb1f70e5a" + integrity sha512-ygaiUSNalBX85388uskeCyhSAoOSgzBbtVCr9jA2RROssFL9Q19/ZXFqS+2Th2sr1ewNIWgFdLzLC3Yl1Zv+lw== + dependencies: + fs-monkey "^1.0.3" + +memfs@^3.4.1: + version "3.4.1" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.1.tgz#b78092f466a0dce054d63d39275b24c71d3f1305" + integrity sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw== dependencies: fs-monkey "1.0.3" +memfs@^3.4.3: + version "3.4.4" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.4.4.tgz#e8973cd8060548916adcca58a248e7805c715e89" + integrity sha512-W4gHNUE++1oSJVn8Y68jPXi+mkx3fXR5ITE/Ubz6EQ3xRpCN5k2CQ4AUR8094Z7211F876TyoBACGsIveqgiGA== + dependencies: + fs-monkey "1.0.3" + +memoizerific@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/memoizerific/-/memoizerific-1.11.3.tgz#7c87a4646444c32d75438570905f2dbd1b1a805a" + integrity sha512-/EuHYwAPdLtXwAwSZkh/Gutery6pD2KYd44oQLhAvQp/50mpyduZh8Q7PYHXTCJ+wuXxt7oij2LXyIJOOYFPog== + dependencies: + map-or-similar "^1.5.0" + memory-fs@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" - integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= + integrity sha512-cda4JKCxReDXFXRqOHPQscuIYg1PvxbE2S2GP45rnwfEK+vZaXC8C1OFvdHIbgw0DLzowXGVoxLaAmlgRy14GQ== dependencies: errno "^0.1.3" readable-stream "^2.0.1" +memory-fs@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.5.0.tgz#324c01288b88652966d161db77838720845a8e3c" + integrity sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA== + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +meow@^3.1.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/meow/-/meow-3.7.0.tgz#72cb668b425228290abbfa856892587308a801fb" + integrity sha512-TNdwZs0skRlpPpCUK25StC4VH+tP5GgeY1HQOOGP+lQ2xtdkN2VtT/5tiX9k3IWpkBPV9b3LsAWXn4GGi/PrSA== + dependencies: + camelcase-keys "^2.0.0" + decamelize "^1.1.2" + loud-rejection "^1.0.0" + map-obj "^1.0.1" + minimist "^1.1.3" + normalize-package-data "^2.3.4" + object-assign "^4.0.1" + read-pkg-up "^1.0.1" + redent "^1.0.0" + trim-newlines "^1.0.0" + merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= -merge-source-map@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" - integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== +merge-source-map@1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.0.4.tgz#a5de46538dae84d4114cc5ea02b4772a6346701f" + integrity sha512-PGSmS0kfnTnMJCzJ16BLLCEe6oeYCamKFFdQKshi4BmM6FUwipjVOcBFGxqtQtirtAG4iZvHlqST9CpZKqlRjA== dependencies: - source-map "^0.6.1" + source-map "^0.5.6" merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w== -merge2@^1.3.0: +merge2@^1.2.3, merge2@^1.3.0, merge2@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae" integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg== @@ -5289,6 +11191,11 @@ methods@^1.1.1, methods@~1.1.2: resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" integrity sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4= +microevent.ts@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" + integrity sha512-jo1OfR4TaEwd5HOrt5+tAZ9mqT4jmpNAusXtyfNzqVm9uiSYFZlKM1wYL4oU7azZW/PxQW53wM0S6OR1JHNa2g== + micromatch@^3.1.10, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" @@ -5308,7 +11215,15 @@ micromatch@^3.1.10, micromatch@^3.1.4: snapdragon "^0.8.1" to-regex "^3.0.2" -micromatch@^4.0.4: +micromatch@^4.0.0: + version "4.0.5" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.5.tgz#bc8999a7cbbf77cdc89f132f6e467051b49090c6" + integrity sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA== + dependencies: + braces "^3.0.2" + picomatch "^2.3.1" + +micromatch@^4.0.2, micromatch@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.4.tgz#896d519dfe9db25fce94ceb7a500919bf881ebf9" integrity sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg== @@ -5316,11 +11231,24 @@ micromatch@^4.0.4: braces "^3.0.1" picomatch "^2.2.3" +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + integrity sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA== + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + mime-db@1.50.0, "mime-db@>= 1.43.0 < 2": version "1.50.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.50.0.tgz#abd4ac94e98d3c0e185016c67ab45d5fde40c11f" integrity sha512-9tMZCDlYHqeERXEHO9f/hKfNXhre5dK2eE/krIvUjZbS2KPcqGDfNShIWS1uW9XOTKQKqK6qbeOci18rbfW77A== +mime-db@1.52.0: + version "1.52.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" + integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== + mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: version "2.1.33" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.33.tgz#1fa12a904472fafd068e48d9e8401f74d3f70edb" @@ -5328,15 +11256,22 @@ mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.31, mime-types@~2.1.17, dependencies: mime-db "1.50.0" +mime-types@^2.1.30, mime-types@~2.1.34: + version "2.1.35" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.35.tgz#381a871b62a734450660ae3deee44813f70d959a" + integrity sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw== + dependencies: + mime-db "1.52.0" + mime@1.6.0, mime@^1.4.1: version "1.6.0" resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1" integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg== mime@^2.4.4: - version "2.5.2" - resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" - integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== + version "2.6.0" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.6.0.tgz#a2a682a95cd4d0cb1d6257e28f83da7e35800367" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== mimic-fn@^2.0.0, mimic-fn@^2.1.0: version "2.1.0" @@ -5348,25 +11283,63 @@ mimic-fn@^3.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-3.1.0.tgz#65755145bbf3e36954b949c16450427451d5ca74" integrity sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ== -mini-css-extract-plugin@2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.2.1.tgz#a44bbfc8ede9211f31474b91c4e8863bf52dd294" - integrity sha512-A0GBXpz8WIPgh2HfASJ0EeY8grd2dGxmC4R8uTujFJXZY7zFy0nvYSYW6SKCLKlz7y45BdHONfaxZQMIZpeF/w== +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + integrity sha512-9Wy1B3m3f66bPPmU5hdA4DR4PB2OfDU/+GS3yAB7IQozE3tqXaVv2zOjgla7MEGSRv95+ILmOuvhLkOK6wJtCQ== dependencies: - schema-utils "^3.1.0" + dom-walk "^0.1.0" -minimalistic-assert@^1.0.0: +mini-css-extract-plugin@2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.0.tgz#578aebc7fc14d32c0ad304c2c34f08af44673f5e" + integrity sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w== + dependencies: + schema-utils "^4.0.0" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@3.0.4, minimatch@^3.0.4: +minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== + +minimatch@5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.0.1.tgz#fb9022f7528125187c92bd9e9b6366be1cf3415b" + integrity sha512-nLDxIFRyhDblz3qMuq+SoRZED4+miJ/G+tdDrjkkkRnjAsBexeGpgjLEQ0blJy7rHhR2b93rhQY4SvyWu9v03g== + dependencies: + brace-expansion "^2.0.1" + +minimatch@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== dependencies: brace-expansion "^1.1.7" +minimatch@^3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" + integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== + dependencies: + brace-expansion "^1.1.7" + +minimatch@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7" + integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg== + dependencies: + brace-expansion "^2.0.1" + +minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.6.tgz#8637a5b759ea0d6e98702cfb3a9283323c93af44" + integrity sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q== + minimist@^1.2.0, minimist@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" @@ -5379,7 +11352,7 @@ minipass-collect@^1.0.2: dependencies: minipass "^3.0.0" -minipass-fetch@^1.3.0, minipass-fetch@^1.3.2: +minipass-fetch@^1.3.2: version "1.4.1" resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-1.4.1.tgz#d75e0091daac1b0ffd7e9d41629faff7d0c1f1b6" integrity sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw== @@ -5390,6 +11363,17 @@ minipass-fetch@^1.3.0, minipass-fetch@^1.3.2: optionalDependencies: encoding "^0.1.12" +minipass-fetch@^2.0.3: + version "2.1.0" + resolved "https://registry.yarnpkg.com/minipass-fetch/-/minipass-fetch-2.1.0.tgz#ca1754a5f857a3be99a9271277246ac0b44c3ff8" + integrity sha512-H9U4UVBGXEyyWJnqYDCLp1PwD8XIkJ4akNHp1aGVI+2Ym7wQMlxDKi4IB4JbmyU+pl9pEs/cVrK6cOuvmbK4Sg== + dependencies: + minipass "^3.1.6" + minipass-sized "^1.0.3" + minizlib "^2.1.2" + optionalDependencies: + encoding "^0.1.13" + minipass-flush@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/minipass-flush/-/minipass-flush-1.0.5.tgz#82e7135d7e89a50ffe64610a787953c4c4cbb373" @@ -5426,7 +11410,14 @@ minipass@^3.0.0, minipass@^3.1.0, minipass@^3.1.1, minipass@^3.1.3: dependencies: yallist "^4.0.0" -minizlib@^2.0.0, minizlib@^2.1.1: +minipass@^3.1.6: + version "3.1.6" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.6.tgz#3b8150aa688a711a1521af5e8779c1d3bb4f45ee" + integrity sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ== + dependencies: + yallist "^4.0.0" + +minizlib@^2.0.0, minizlib@^2.1.1, minizlib@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.2.tgz#e90d3466ba209b932451508a11ce3d3632145931" integrity sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg== @@ -5434,6 +11425,22 @@ minizlib@^2.0.0, minizlib@^2.1.1: minipass "^3.0.0" yallist "^4.0.0" +mississippi@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" + integrity sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA== + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^3.0.0" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + mixin-deep@^1.2.0: version "1.3.2" resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.2.tgz#1120b43dc359a785dce65b55b82e257ccf479566" @@ -5442,14 +11449,21 @@ mixin-deep@^1.2.0: for-in "^1.0.2" is-extendable "^1.0.1" -mkdirp@^0.5.1, mkdirp@^0.5.5: +mkdirp@^0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ== dependencies: minimist "^1.2.5" -mkdirp@^1.0.3, mkdirp@^1.0.4, mkdirp@~1.0.4: +mkdirp@^0.5.3: + version "0.5.6" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + +mkdirp@^1.0.3, mkdirp@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== @@ -5466,6 +11480,29 @@ moment-timezone@^0.5.23: resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.1.tgz#b2be769fa31940be9eeea6469c075e35006fa3d3" integrity sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ== +morgan@^1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/morgan/-/morgan-1.10.0.tgz#091778abc1fc47cd3509824653dae1faab6b17d7" + integrity sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ== + dependencies: + basic-auth "~2.0.1" + debug "2.6.9" + depd "~2.0.0" + on-finished "~2.3.0" + on-headers "~1.0.2" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + integrity sha512-hdrFxZOycD/g6A6SoI2bB5NA/5NEqD0569+S47WZhPvm46sD50ZHdYaFmnua5lndde9rCHGjmfK7Z8BuCt/PcQ== + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -5481,22 +11518,17 @@ ms@2.1.2: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== -ms@^2.0.0, ms@^2.1.1: +ms@2.1.3, ms@^2.0.0, ms@^2.1.1: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== -multicast-dns-service-types@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz#899f11d9686e5e05cb91b35d5f0e63b773cfc901" - integrity sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE= - -multicast-dns@^6.0.1: - version "6.2.3" - resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-6.2.3.tgz#a0ec7bd9055c4282f790c3c82f4e28db3b31b229" - integrity sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g== +multicast-dns@^7.2.4: + version "7.2.5" + resolved "https://registry.yarnpkg.com/multicast-dns/-/multicast-dns-7.2.5.tgz#77eb46057f4d7adbd16d9290fa7299f6fa64cced" + integrity sha512-2eznPJP8z2BFLX50tf0LuODrpINqP1RVIm/CObbTcBRITQgmC/TjcREF1NeTBzIcR5XO/ukWo+YHOjBbFwIupg== dependencies: - dns-packet "^1.3.1" + dns-packet "^5.2.2" thunky "^1.0.2" mute-stream@0.0.8: @@ -5505,19 +11537,19 @@ mute-stream@0.0.8: integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== nan@^2.12.1: - version "2.15.0" - resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee" - integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ== + version "2.16.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.16.0.tgz#664f43e45460fb98faf00edca0bb0d7b8dce7916" + integrity sha512-UdAqHyFngu7TfQKsCBgAA6pWDkT8MAO7d0jyOecVhN5354xbLqdn8mV9Tat9gepAupm0bt2DbeaSC8vS52MuFA== -nanocolors@^0.1.12: - version "0.1.12" - resolved "https://registry.yarnpkg.com/nanocolors/-/nanocolors-0.1.12.tgz#8577482c58cbd7b5bb1681db4cf48f11a87fd5f6" - integrity sha512-2nMHqg1x5PU+unxX7PGY7AuYxl2qDx7PSrTRjizr8sxdd3l/3hBuWWaki62qmtYm2U5i4Z5E7GbjlyDFhs9/EQ== +nanoid@^3.1.23, nanoid@^3.3.1, nanoid@^3.3.3, nanoid@^3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab" + integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw== -nanoid@^3.1.23, nanoid@^3.1.28: - version "3.1.30" - resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.1.30.tgz#63f93cc548d2a113dc5dfbc63bfa09e2b9b64362" - integrity sha512-zJpuPDwOv8D2zq2WRoMe1HsfZthVewpel9CAvTfc/2mBD1uUT/agc5f7GHGWXlYkFvi1mVxe4IjvP2HNrop7nQ== +nanoid@^3.2.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.0.tgz#5906f776fd886c66c24f3653e0c46fcb1d4ad6b0" + integrity sha512-JzxqqT5u/x+/KOFSd7JP15DOo9nOoHpx6DYatqIHUW2+flybkm+mdcraotSQR5WcnZr+qhGVh8Ted0KdfSMxlg== nanomatch@^1.2.9: version "1.2.13" @@ -5550,11 +11582,26 @@ negotiator@0.6.2, negotiator@^0.6.2: resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb" integrity sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw== -neo-async@^2.6.2: +negotiator@0.6.3, negotiator@^0.6.3: + version "0.6.3" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.3.tgz#58e323a72fedc0d6f9cd4d31fe49f51479590ccd" + integrity sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg== + +neo-async@^2.5.0, neo-async@^2.6.0, neo-async@^2.6.1, neo-async@^2.6.2: version "2.6.2" resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +nested-error-stacks@^2.0.0, nested-error-stacks@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/nested-error-stacks/-/nested-error-stacks-2.1.1.tgz#26c8a3cee6cc05fbcf1e333cd2fc3e003326c0b5" + integrity sha512-9iN1ka/9zmX1ZvLV9ewJYEk9h7RyRRtqdK0woXcqohu8EWIerfPUjYJPg0ULy0UqP7cslmdGc8xKDJcojlKiaw== + +next-tick@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" + integrity sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ== + ng2-cookies@^1.0.12: version "1.0.12" resolved "https://registry.yarnpkg.com/ng2-cookies/-/ng2-cookies-1.0.12.tgz#3f3e613e0137b0649b705c678074b4bd08149ccc" @@ -5568,13 +11615,12 @@ ngx-clipboard@^12.1.0: ngx-window-token "^2.0.0" tslib "^1.9.0" -ngx-infinite-scroll@^9.0.0: - version "9.1.0" - resolved "https://registry.yarnpkg.com/ngx-infinite-scroll/-/ngx-infinite-scroll-9.1.0.tgz#6716a47613ff59f236b85c3ce291b2fd57106824" - integrity sha512-ZulbahgFsoPmP8cz7qPGDeFX9nKiSm74aav8vXNSI1ZoPiGYY5FQd8AK+yXqygY7tyCJRyt8Wp3DIg7zgP5dPA== +ngx-infinite-scroll@^14.0.0: + version "14.0.0" + resolved "https://registry.yarnpkg.com/ngx-infinite-scroll/-/ngx-infinite-scroll-14.0.0.tgz#395b15be5f451c3e3d2ad7ce2aeb66f8c66aba5d" + integrity sha512-YZB5PBPXSERNtCGQRZTVflbgkh5asp01NPfC8KPItemmQik1Ip8ZCCbcyHA77TDTdilmaiu8TbguA3geg/LMWw== dependencies: - "@scarf/scarf" "^1.1.0" - opencollective-postinstall "^2.0.2" + tslib "^2.3.0" ngx-moment@^3.0.1: version "3.5.0" @@ -5583,10 +11629,10 @@ ngx-moment@^3.0.1: dependencies: tslib "^1.9.0" -ngx-order-pipe@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ngx-order-pipe/-/ngx-order-pipe-2.1.1.tgz#981b7ff2fac20bc88a1e9922527e2e61da0ff4f1" - integrity sha512-yBaG0uYWsXBlmAuCYvBedKxl3kRUSXNXsMrD0m2E4tBA8I9TJSomucp5SHFlyfMQK8V6pjRGdz17Sjb9YwLhSg== +ngx-order-pipe@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ngx-order-pipe/-/ngx-order-pipe-2.2.0.tgz#14ab50dfe0a679e5216138ff9a0820a83173a4fe" + integrity sha512-fym4A3j0XMqETskCm0tHUHQWCgB1p1MrIstFA3jCClJqNU9KjtQh/AE4C7srUkz9U3HIBIAN9D3ty2L9l/jvmA== dependencies: tslib "^2.0.0" @@ -5610,42 +11656,106 @@ nice-try@^1.0.4: resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366" integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ== +no-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/no-case/-/no-case-3.0.4.tgz#d361fd5c9800f558551a8369fc0dcd4662b6124d" + integrity sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg== + dependencies: + lower-case "^2.0.2" + tslib "^2.0.3" + node-addon-api@^3.0.0: version "3.2.1" resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161" integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== -node-forge@^0.10.0: - version "0.10.0" - resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.10.0.tgz#32dea2afb3e9926f02ee5ce8794902691a676bf3" - integrity sha512-PPmu8eEeG9saEUvI97fm4OYxXVB6bFvyNTyiUOBichBpFG8A1Ljw3bY62+5oOjDEMHRnd0Y7HQ+x7uzxOzC6JA== +node-fetch@^2.6.1, node-fetch@^2.6.7: + version "2.6.7" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.7.tgz#24de9fba827e3b4ae44dc8b20256a379160052ad" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + +node-forge@^1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-1.3.1.tgz#be8da2af243b2417d5f646a770663a92b7e9ded3" + integrity sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA== node-gyp-build@^4.2.2: version "4.3.0" resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.3.0.tgz#9f256b03e5826150be39c764bf51e993946d71a3" integrity sha512-iWjXZvmboq0ja1pUGULQBexmxq8CV4xBhX7VDOTbL7ZR4FOowwY/VOtRxBN/yKxmdGoIp4j5ysNT4u3S2pDQ3Q== -node-gyp@^7.1.0: - version "7.1.2" - resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-7.1.2.tgz#21a810aebb187120251c3bcec979af1587b188ae" - integrity sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ== +node-gyp@^8.4.1: + version "8.4.1" + resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-8.4.1.tgz#3d49308fc31f768180957d6b5746845fbd429937" + integrity sha512-olTJRgUtAb/hOXG0E93wZDs5YiJlgbXxTwQAFHyNlRsXQnYzUaF2aGgujZbw+hR8aF4ZG/rST57bWMWD16jr9w== dependencies: env-paths "^2.2.0" glob "^7.1.4" - graceful-fs "^4.2.3" + graceful-fs "^4.2.6" + make-fetch-happen "^9.1.0" nopt "^5.0.0" - npmlog "^4.1.2" - request "^2.88.2" + npmlog "^6.0.0" rimraf "^3.0.2" - semver "^7.3.2" - tar "^6.0.2" + semver "^7.3.5" + tar "^6.1.2" which "^2.0.2" +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== + +node-libs-browser@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" + integrity sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q== + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^3.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.1" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.11.0" + vm-browserify "^1.0.1" + node-releases@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.0.tgz#67dc74903100a7deb044037b8a2e5f453bb05400" integrity sha512-aA87l0flFYMzCHpTM3DERFSYxc6lv/BltdbRTOMZuxZ0cwZCD3mejE5n9vLhSJCN++/eOqr77G1IO5uXxlQYWA== +node-releases@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01" + integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg== + +node-releases@^2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.5.tgz#280ed5bc3eba0d96ce44897d8aee478bfb3d9666" + integrity sha512-U9h1NLROZTq9uE1SNffn6WuPDg8icmi3ns4rEl/oTfIle4iLjTliCzgTsbaIFMq/Xn078/lfY/BL0GWZ+psK4Q== + +node-releases@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.6.tgz#8a7088c63a55e493845683ebf3c828d8c51c5503" + integrity sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg== + nopt@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" @@ -5653,10 +11763,30 @@ nopt@^5.0.0: dependencies: abbrev "1" +normalize-package-data@^2.3.2, normalize-package-data@^2.3.4, normalize-package-data@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" + integrity sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA== + dependencies: + hosted-git-info "^2.1.4" + resolve "^1.10.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-package-data@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-4.0.0.tgz#1122d5359af21d4cd08718b92b058a658594177c" + integrity sha512-m+GL22VXJKkKbw62ZaBBjv8u6IE3UI4Mh5QakIqs3fWiKe0Xyi6L97hakwZK41/LD4R/2ly71Bayx0NLMwLA/g== + dependencies: + hosted-git-info "^5.0.0" + is-core-module "^2.8.1" + semver "^7.3.5" + validate-npm-package-license "^3.0.4" + normalize-path@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" - integrity sha1-GrKLVW4Zg2Oowab35vogE3/mrtk= + integrity sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w== dependencies: remove-trailing-separator "^1.0.1" @@ -5670,22 +11800,17 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= -normalize-url@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-6.1.0.tgz#40d0885b535deffe3f3147bec877d05fe4c5668a" - integrity sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A== - -npm-bundled@^1.1.1: +npm-bundled@^1.1.1, npm-bundled@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.1.2.tgz#944c78789bd739035b70baa2ca5cc32b8d860bc1" integrity sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ== dependencies: npm-normalize-package-bin "^1.0.1" -npm-install-checks@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-4.0.0.tgz#a37facc763a2fde0497ef2c6d0ac7c3fbe00d7b4" - integrity sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w== +npm-install-checks@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/npm-install-checks/-/npm-install-checks-5.0.0.tgz#5ff27d209a4e3542b8ac6b0c1db6063506248234" + integrity sha512-65lUsMI8ztHCxFz5ckCEC44DRvEGdZX5usQFriauxHEwt7upv1FKaQEmAtU0YnOAdwuNWCmk64xYiQABNrEyLA== dependencies: semver "^7.1.1" @@ -5694,46 +11819,47 @@ npm-normalize-package-bin@^1.0.1: resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" integrity sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA== -npm-package-arg@8.1.5, npm-package-arg@^8.0.0, npm-package-arg@^8.0.1, npm-package-arg@^8.1.2: - version "8.1.5" - resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-8.1.5.tgz#3369b2d5fe8fdc674baa7f1786514ddc15466e44" - integrity sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q== +npm-package-arg@9.0.2, npm-package-arg@^9.0.0, npm-package-arg@^9.0.1: + version "9.0.2" + resolved "https://registry.yarnpkg.com/npm-package-arg/-/npm-package-arg-9.0.2.tgz#f3ef7b1b3b02e82564af2d5228b4c36567dcd389" + integrity sha512-v/miORuX8cndiOheW8p2moNuPJ7QhcFh9WGlTorruG8hXSA23vMTEp5hTCmDxic0nD8KHhj/NQgFuySD3GYY3g== dependencies: - hosted-git-info "^4.0.1" - semver "^7.3.4" - validate-npm-package-name "^3.0.0" + hosted-git-info "^5.0.0" + semver "^7.3.5" + validate-npm-package-name "^4.0.0" -npm-packlist@^2.1.4: - version "2.2.2" - resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-2.2.2.tgz#076b97293fa620f632833186a7a8f65aaa6148c8" - integrity sha512-Jt01acDvJRhJGthnUJVF/w6gumWOZxO7IkpY/lsX9//zqQgnF7OJaxgQXcerd4uQOLu7W5bkb4mChL9mdfm+Zg== +npm-packlist@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-5.1.0.tgz#f3fd52903a021009913a133732022132eb355ce7" + integrity sha512-a04sqF6FbkyOAFA19AA0e94gS7Et5T2/IMj3VOT9nOF2RaRdVPQ1Q17Fb/HaDRFs+gbC7HOmhVZ29adpWgmDZg== dependencies: - glob "^7.1.6" - ignore-walk "^3.0.3" - npm-bundled "^1.1.1" + glob "^8.0.1" + ignore-walk "^5.0.1" + npm-bundled "^1.1.2" npm-normalize-package-bin "^1.0.1" -npm-pick-manifest@6.1.1, npm-pick-manifest@^6.0.0, npm-pick-manifest@^6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-6.1.1.tgz#7b5484ca2c908565f43b7f27644f36bb816f5148" - integrity sha512-dBsdBtORT84S8V8UTad1WlUyKIY9iMsAmqxHbLdeEeBNMLQDlDWWra3wYUx9EBEIiG/YwAy0XyNHDd2goAsfuA== +npm-pick-manifest@7.0.1, npm-pick-manifest@^7.0.0: + version "7.0.1" + resolved "https://registry.yarnpkg.com/npm-pick-manifest/-/npm-pick-manifest-7.0.1.tgz#76dda30a7cd6b99be822217a935c2f5eacdaca4c" + integrity sha512-IA8+tuv8KujbsbLQvselW2XQgmXWS47t3CB0ZrzsRZ82DbDfkcFunOaPm4X7qNuhMfq+FmV7hQT4iFVpHqV7mg== dependencies: - npm-install-checks "^4.0.0" + npm-install-checks "^5.0.0" npm-normalize-package-bin "^1.0.1" - npm-package-arg "^8.1.2" - semver "^7.3.4" + npm-package-arg "^9.0.0" + semver "^7.3.5" -npm-registry-fetch@^11.0.0: - version "11.0.0" - resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-11.0.0.tgz#68c1bb810c46542760d62a6a965f85a702d43a76" - integrity sha512-jmlgSxoDNuhAtxUIG6pVwwtz840i994dL14FoNVZisrmZW5kWd63IUTNv1m/hyRSGSqWjCUp/YZlS1BJyNp9XA== +npm-registry-fetch@^13.0.1: + version "13.1.1" + resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-13.1.1.tgz#26dc4b26d0a545886e807748032ba2aefaaae96b" + integrity sha512-5p8rwe6wQPLJ8dMqeTnA57Dp9Ox6GH9H60xkyJup07FmVlu3Mk7pf/kIIpl9gaN5bM8NM+UUx3emUWvDNTt39w== dependencies: - make-fetch-happen "^9.0.1" - minipass "^3.1.3" - minipass-fetch "^1.3.0" + make-fetch-happen "^10.0.6" + minipass "^3.1.6" + minipass-fetch "^2.0.3" minipass-json-stream "^1.0.1" - minizlib "^2.0.0" - npm-package-arg "^8.0.0" + minizlib "^2.1.2" + npm-package-arg "^9.0.1" + proc-log "^2.0.0" npm-run-path@^2.0.0: version "2.0.2" @@ -5742,17 +11868,34 @@ npm-run-path@^2.0.0: dependencies: path-key "^2.0.0" -npmlog@^4.1.2: - version "4.1.2" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" - integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg== +npm-run-path@^4.0.0, npm-run-path@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" + integrity sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw== dependencies: - are-we-there-yet "~1.1.2" - console-control-strings "~1.1.0" - gauge "~2.7.3" - set-blocking "~2.0.0" + path-key "^3.0.0" -nth-check@^2.0.0: +npmlog@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" + integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== + dependencies: + are-we-there-yet "^2.0.0" + console-control-strings "^1.1.0" + gauge "^3.0.0" + set-blocking "^2.0.0" + +npmlog@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-6.0.1.tgz#06f1344a174c06e8de9c6c70834cfba2964bba17" + integrity sha512-BTHDvY6nrRHuRfyjt1MAufLxYdVXZfd099H4+i1f0lPywNQyI4foeNXJRObB/uy+TYqUW0vAD9gbdSOXPst7Eg== + dependencies: + are-we-there-yet "^3.0.0" + console-control-strings "^1.1.0" + gauge "^4.0.0" + set-blocking "^2.0.0" + +nth-check@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2" integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w== @@ -5762,7 +11905,7 @@ nth-check@^2.0.0: num2fraction@^1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/num2fraction/-/num2fraction-1.2.2.tgz#6f682b6a027a4e9ddfa4564cd2589d1d4e669ede" - integrity sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4= + integrity sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg== number-is-nan@^1.0.0: version "1.0.1" @@ -5774,7 +11917,7 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== -object-assign@^4.0.1, object-assign@^4.1.0: +object-assign@^4, object-assign@^4.0.1, object-assign@^4.1.1, object-assign@latest: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= @@ -5782,12 +11925,17 @@ object-assign@^4.0.1, object-assign@^4.1.0: object-copy@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" - integrity sha1-fn2Fi3gb18mRpBupde04EnVOmYw= + integrity sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ== dependencies: copy-descriptor "^0.1.0" define-property "^0.2.5" kind-of "^3.0.3" +object-inspect@^1.12.0, object-inspect@^1.6.0: + version "1.12.2" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.12.2.tgz#c0641f26394532f28ab8d796ab954e43c009a8ea" + integrity sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ== + object-inspect@^1.9.0: version "1.11.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" @@ -5809,11 +11957,11 @@ object-keys@^1.0.12, object-keys@^1.1.1: object-visit@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" - integrity sha1-95xEk68MU3e1n+OdOV5BBC3QRbs= + integrity sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA== dependencies: isobject "^3.0.0" -object.assign@^4.1.0: +object.assign@^4.1.0, object.assign@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.2.tgz#0ed54a342eceb37b38ff76eb831a0e788cb63940" integrity sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ== @@ -5823,22 +11971,66 @@ object.assign@^4.1.0: has-symbols "^1.0.1" object-keys "^1.1.1" +object.entries@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.5.tgz#e1acdd17c4de2cd96d5a08487cfb9db84d881861" + integrity sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +"object.fromentries@^2.0.0 || ^1.0.0": + version "2.0.5" + resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.5.tgz#7b37b205109c21e741e605727fe8b0ad5fa08251" + integrity sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +object.getownpropertydescriptors@^2.0.3, object.getownpropertydescriptors@^2.1.2: + version "2.1.4" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.4.tgz#7965e6437a57278b587383831a9b829455a4bc37" + integrity sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ== + dependencies: + array.prototype.reduce "^1.0.4" + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.20.1" + object.pick@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" - integrity sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c= + integrity sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ== dependencies: isobject "^3.0.1" +object.values@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.1.5.tgz#959f63e3ce9ef108720333082131e4a459b716ac" + integrity sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + obuf@^1.0.0, obuf@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.2.tgz#09bea3343d41859ebd446292d11c9d4db619084e" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== +on-finished@2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.4.1.tgz#58c8c44116e54845ad57f14ab10b03533184ac3f" + integrity sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg== + dependencies: + ee-first "1.1.1" + on-finished@~2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" - integrity sha1-IPEzZIGwg811M3mSoWlxqi2QaUc= + integrity sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww== dependencies: ee-first "1.1.1" @@ -5854,35 +12046,48 @@ once@^1.3.0, once@^1.3.1, once@^1.4.0: dependencies: wrappy "1" -onetime@^5.1.0: +onetime@^5.1.0, onetime@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/onetime/-/onetime-5.1.2.tgz#d0e96ebb56b07476df1dd9c4806e5237985ca45e" integrity sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg== dependencies: mimic-fn "^2.1.0" -open@8.2.1: - version "8.2.1" - resolved "https://registry.yarnpkg.com/open/-/open-8.2.1.tgz#82de42da0ccbf429bc12d099dad2e0975e14e8af" - integrity sha512-rXILpcQlkF/QuFez2BJDf3GsqpjGKbkUUToAIGo9A0Q6ZkoSGogZJulrUdwRkrAsoQvoZsrjCYt8+zblOk7JQQ== +open@8.4.0, open@^8.0.9, open@^8.4.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/open/-/open-8.4.0.tgz#345321ae18f8138f82565a910fdc6b39e8c244f8" + integrity sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q== dependencies: define-lazy-prop "^2.0.0" is-docker "^2.1.1" is-wsl "^2.2.0" -opencollective-postinstall@^2.0.2: +open@^7.0.3: + version "7.4.2" + resolved "https://registry.yarnpkg.com/open/-/open-7.4.2.tgz#b8147e26dcf3e426316c730089fd71edd29c2321" + integrity sha512-MVHddDVweXZF3awtlAS+6pgKLlm/JgxZ90+/NBurBoQctVOOB/zDdVjcyPzQ+0laDGbsWgrRkflI65sQeOgT9Q== + dependencies: + is-docker "^2.0.0" + is-wsl "^2.1.1" + +opencollective-postinstall@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/opencollective-postinstall/-/opencollective-postinstall-2.0.3.tgz#7a0fff978f6dbfa4d006238fbac98ed4198c3259" integrity sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q== -opn@^5.5.0: - version "5.5.0" - resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc" - integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA== +optionator@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.3.tgz#84fa1d036fe9d3c7e21d99884b601167ec8fb495" + integrity sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA== dependencies: - is-wsl "^1.1.0" + deep-is "~0.1.3" + fast-levenshtein "~2.0.6" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + word-wrap "~1.2.3" -ora@5.4.1, ora@^5.3.0: +ora@5.4.1, ora@^5.4.1: version "5.4.1" resolved "https://registry.yarnpkg.com/ora/-/ora-5.4.1.tgz#1b2678426af4ac4a509008e5e4ac9e9959db9e18" integrity sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ== @@ -5904,6 +12109,16 @@ original@^1.0.0: dependencies: url-parse "^1.4.3" +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + integrity sha512-gjcpUc3clBf9+210TRaDWbf+rZZZEshZ+DlXMRCeAjp0xhTrnQsKHypIy1J3d5hKdUzj69t708EHtU8P6bUn0A== + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + integrity sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ== + os-locale@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" @@ -5913,16 +12128,45 @@ os-locale@^3.0.0: lcid "^2.0.0" mem "^4.0.0" +os-name@4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/os-name/-/os-name-4.0.1.tgz#32cee7823de85a8897647ba4d76db46bf845e555" + integrity sha512-xl9MAoU97MH1Xt5K9ERft2YfCAoaO6msy1OBA0ozxEC0x0TmIoE6K3QvgJMMZA9yKGLmHXNY/YZoDbiGDj4zYw== + dependencies: + macos-release "^2.5.0" + windows-release "^4.0.0" + os-tmpdir@~1.0.1, os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" integrity sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ= +p-all@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-all/-/p-all-2.1.0.tgz#91419be56b7dee8fe4c5db875d55e0da084244a0" + integrity sha512-HbZxz5FONzz/z2gJfk6bFca0BCiSRF8jU3yCsWOen/vR6lZjfPOu/e7L3uFzTW1i0H8TlC3vqQstEJPQL4/uLA== + dependencies: + p-map "^2.0.0" + p-defer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-defer/-/p-defer-1.0.0.tgz#9f6eb182f6c9aa8cd743004a7d4f96b196b0fb0c" integrity sha1-n26xgvbJqozXQwBKfU+WsZaw+ww= +p-event@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.2.0.tgz#af4b049c8acd91ae81083ebd1e6f5cae2044c1b5" + integrity sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ== + dependencies: + p-timeout "^3.1.0" + +p-filter@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/p-filter/-/p-filter-2.1.0.tgz#1b1472562ae7a0f742f0f3d3d3718ea66ff9c09c" + integrity sha512-ZBxxZ5sL2HghephhpGAQdoskxplTwr7ICaehZwLIlfL6acuVgZPm8yBNuRAFBGEqtD/hmUeq9eqLg2ys9Xr/yw== + dependencies: + p-map "^2.0.0" + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" @@ -5961,11 +12205,25 @@ p-locate@^4.1.0: dependencies: p-limit "^2.2.0" +p-locate@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-5.0.0.tgz#83c8315c6785005e3bd021839411c9e110e6d834" + integrity sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw== + dependencies: + p-limit "^3.0.2" + p-map@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" integrity sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw== +p-map@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-3.0.0.tgz#d704d9af8a2ba684e2600d9a215983d4141a979d" + integrity sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ== + dependencies: + aggregate-error "^3.0.0" + p-map@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-4.0.0.tgz#bb2f95a5eda2ec168ec9274e06a747c3e2904d2b" @@ -5973,48 +12231,80 @@ p-map@^4.0.0: dependencies: aggregate-error "^3.0.0" -p-retry@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" - integrity sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w== +p-retry@^4.5.0: + version "4.6.1" + resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-4.6.1.tgz#8fcddd5cdf7a67a0911a9cf2ef0e5df7f602316c" + integrity sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA== dependencies: - retry "^0.12.0" + "@types/retry" "^0.12.0" + retry "^0.13.1" + +p-timeout@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-3.2.0.tgz#c7e17abc971d2a7962ef83626b35d635acf23dfe" + integrity sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg== + dependencies: + p-finally "^1.0.0" p-try@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== -pacote@11.3.5: - version "11.3.5" - resolved "https://registry.yarnpkg.com/pacote/-/pacote-11.3.5.tgz#73cf1fc3772b533f575e39efa96c50be8c3dc9d2" - integrity sha512-fT375Yczn4zi+6Hkk2TBe1x1sP8FgFsEIZ2/iWaXY2r/NkhDJfxbcn5paz1+RTFCyNf+dPnaoBDJoAxXSU8Bkg== +pacote@13.3.0: + version "13.3.0" + resolved "https://registry.yarnpkg.com/pacote/-/pacote-13.3.0.tgz#e221febc17ce2435ce9f31de411832327a34c5ad" + integrity sha512-auhJAUlfC2TALo6I0s1vFoPvVFgWGx+uz/PnIojTTgkGwlK3Np8sGJ0ghfFhiuzJXTZoTycMLk8uLskdntPbDw== dependencies: - "@npmcli/git" "^2.1.0" - "@npmcli/installed-package-contents" "^1.0.6" - "@npmcli/promise-spawn" "^1.2.0" - "@npmcli/run-script" "^1.8.2" - cacache "^15.0.5" + "@npmcli/git" "^3.0.0" + "@npmcli/installed-package-contents" "^1.0.7" + "@npmcli/promise-spawn" "^3.0.0" + "@npmcli/run-script" "^3.0.1" + cacache "^16.0.0" chownr "^2.0.0" fs-minipass "^2.1.0" infer-owner "^1.0.4" - minipass "^3.1.3" - mkdirp "^1.0.3" - npm-package-arg "^8.0.1" - npm-packlist "^2.1.4" - npm-pick-manifest "^6.0.0" - npm-registry-fetch "^11.0.0" + minipass "^3.1.6" + mkdirp "^1.0.4" + npm-package-arg "^9.0.0" + npm-packlist "^5.0.0" + npm-pick-manifest "^7.0.0" + npm-registry-fetch "^13.0.1" + proc-log "^2.0.0" promise-retry "^2.0.1" - read-package-json-fast "^2.0.1" + read-package-json "^5.0.0" + read-package-json-fast "^2.0.3" rimraf "^3.0.2" - ssri "^8.0.1" - tar "^6.1.0" + ssri "^9.0.0" + tar "^6.1.11" -pako@^1.0.3, pako@~1.0.2: +pako@^0.2.5: + version "0.2.9" + resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" + integrity sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA== + +pako@^1.0.3, pako@~1.0.2, pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" integrity sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw== +parallel-transform@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.2.0.tgz#9049ca37d6cb2182c3b1d2c720be94d14a5814fc" + integrity sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg== + dependencies: + cyclist "^1.0.1" + inherits "^2.0.3" + readable-stream "^2.1.5" + +param-case@^3.0.3, param-case@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" + integrity sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A== + dependencies: + dot-case "^3.0.4" + tslib "^2.0.3" + parent-module@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2" @@ -6022,6 +12312,36 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parse-asn1@^5.0.0, parse-asn1@^5.1.5: + version "5.1.6" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.6.tgz#385080a3ec13cb62a62d39409cb3e88844cdaed4" + integrity sha512-RnZRo1EPU6JBnra2vGHj0yhp6ebyjBZpmUCLHWiFhxlzvBCCpAuZ7elsBp1PVAbQN0/04VD/19rfzlBSwLstMw== + dependencies: + asn1.js "^5.2.0" + browserify-aes "^1.0.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + safe-buffer "^5.1.1" + +parse-entities@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-2.0.0.tgz#53c6eb5b9314a1f4ec99fa0fdf7ce01ecda0cbe8" + integrity sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ== + dependencies: + character-entities "^1.0.0" + character-entities-legacy "^1.0.0" + character-reference-invalid "^1.0.0" + is-alphanumerical "^1.0.0" + is-decimal "^1.0.0" + is-hexadecimal "^1.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + integrity sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ== + dependencies: + error-ex "^1.2.0" + parse-json@^5.0.0: version "5.2.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd" @@ -6032,7 +12352,7 @@ parse-json@^5.0.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" -parse-node-version@^1.0.1: +parse-node-version@^1.0.0, parse-node-version@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== @@ -6052,6 +12372,14 @@ parse5-htmlparser2-tree-adapter@^6.0.1: dependencies: parse5 "^6.0.1" +parse5-htmlparser2-tree-adapter@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1" + integrity sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g== + dependencies: + domhandler "^5.0.2" + parse5 "^7.0.0" + parse5-sax-parser@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5-sax-parser/-/parse5-sax-parser-6.0.1.tgz#98b4d366b5b266a7cd90b4b58906667af882daba" @@ -6064,25 +12392,57 @@ parse5@^5.0.0: resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== -parse5@^6.0.1: +parse5@^6.0.0, parse5@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== +parse5@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.0.0.tgz#51f74a5257f5fcc536389e8c2d0b3802e1bfa91a" + integrity sha512-y/t8IXSPWTuRZqXc0ajH/UwDj4mnqLEbSttNbThcFhGrZuOyoyvNBO85PBp2jQa55wY9d07PBNjsK8ZP3K5U6g== + dependencies: + entities "^4.3.0" + parseurl@~1.3.2, parseurl@~1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== +pascal-case@^3.1.2: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pascal-case/-/pascal-case-3.1.2.tgz#b48e0ef2b98e205e7c1dae747d0b1508237660eb" + integrity sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g== + dependencies: + no-case "^3.0.4" + tslib "^2.0.3" + pascalcase@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" - integrity sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ= + integrity sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw== + +path-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.1.tgz#e6c4ddd7ed3aa27c68a20cc4e50e1a4ee83bbc4a" + integrity sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ== + +path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== path-dirname@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" - integrity sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA= + integrity sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q== + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + integrity sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ== + dependencies: + pinkie-promise "^2.0.0" path-exists@^3.0.0: version "3.0.0" @@ -6099,7 +12459,7 @@ path-is-absolute@^1.0.0: resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18= -path-is-inside@^1.0.1, path-is-inside@^1.0.2: +path-is-inside@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53" integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM= @@ -6109,7 +12469,12 @@ path-key@^2.0.0, path-key@^2.0.1: resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A= -path-parse@^1.0.6: +path-key@^3.0.0, path-key@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-3.1.1.tgz#581f6ade658cbba65a0d3380de7753295054f375" + integrity sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q== + +path-parse@^1.0.6, path-parse@^1.0.7: version "1.0.7" resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== @@ -6119,11 +12484,63 @@ path-to-regexp@0.1.7: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" integrity sha1-32BBeABfUi8V60SQ5yR6G/qmf4w= +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + integrity sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg== + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + integrity sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg== + dependencies: + pify "^3.0.0" + path-type@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +pause-stream@^0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + integrity sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A== + dependencies: + through "~2.3" + +pbkdf2@^3.0.3: + version "3.1.2" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" + integrity sha512-iuh7L6jA7JEGu2WxDwtQP1ddOpaJNC4KlDEFfdQajSGgGPNi4OyDc2R7QnbY2bR9QjBVGwgvTdNJZoE7RaxUMA== + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +pdfjs-dist@^2.12.313: + version "2.14.305" + resolved "https://registry.yarnpkg.com/pdfjs-dist/-/pdfjs-dist-2.14.305.tgz#ed2ecb439ff8af5446c90a310ebd30bc1a91df62" + integrity sha512-5f7i25J1dKIBczhgfxEgNxfYNIxXEdxqo6Qb4ehY7Ja+p6AI4uUmk/OcVGXfRGm2ys5iaJJhJUwBFwv6Jl/Qww== + dependencies: + dommatrix "^1.0.1" + web-streams-polyfill "^3.2.1" + +pdfmake@^0.2.4: + version "0.2.5" + resolved "https://registry.yarnpkg.com/pdfmake/-/pdfmake-0.2.5.tgz#48b17670d69dae3860a5d8721ff12f7988140613" + integrity sha512-NlayjehMtuZEdw2Lyipf/MxOCR2vATZQ7jn8cH0/dHwsNb+mqof9/6SW4jZT5p+So4qz+0mD21KG81+dDQSEhA== + dependencies: + "@foliojs-fork/linebreak" "^1.1.1" + "@foliojs-fork/pdfkit" "^0.13.0" + iconv-lite "^0.6.3" + xmldoc "^1.1.2" + performance-now@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" @@ -6144,11 +12561,21 @@ picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== +picomatch@^2.3.0, picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + pify@^2.0.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + integrity sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg== + pify@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" @@ -6166,10 +12593,15 @@ pinkie@^2.0.0: resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" integrity sha1-clVrgM+g1IqXToDnckjoDtT3+HA= -piscina@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/piscina/-/piscina-3.1.0.tgz#2333636865b6cb69c5a370bbc499a98cabcf3e04" - integrity sha512-KTW4sjsCD34MHrUbx9eAAbuUSpVj407hQSgk/6Epkg0pbRBmv4a3UX7Sr8wxm9xYqQLnsN4mFOjqGDzHAdgKQg== +pirates@^4.0.1, pirates@^4.0.5: + version "4.0.5" + resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" + integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== + +piscina@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/piscina/-/piscina-3.2.0.tgz#f5a1dde0c05567775690cccefe59d9223924d154" + integrity sha512-yn/jMdHRw+q2ZJhFhyqsmANcbF6V2QwmD84c6xRau+QpQOmtrBCoRGdvTfeuFDYXB5W2m6MfLkjkvQa9lUSmIA== dependencies: eventemitter-asyncresource "^1.0.0" hdr-histogram-js "^2.0.1" @@ -6191,321 +12623,235 @@ pkg-dir@^4.1.0: dependencies: find-up "^4.0.0" -please-wait@^0.0.5: - version "0.0.5" - resolved "https://registry.yarnpkg.com/please-wait/-/please-wait-0.0.5.tgz#67098ce6260e92e0809e2d3b7c23f1d167dad960" - integrity sha1-ZwmM5iYOkuCAni07fCPx0Wfa2WA= +pkg-dir@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" + integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== + dependencies: + find-up "^5.0.0" -pngjs@^3.3.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-3.4.0.tgz#99ca7d725965fb655814eaf65f38f12bbdbf555f" - integrity sha512-NCrCHhWmnQklfH4MtJMRjZ2a8c80qXeMlQMv2uVp9ISJMTt562SbGd6n2oq0PaPgKm7Z6pL9E2UlLIhC+SHL3w== +png-js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/png-js/-/png-js-1.0.0.tgz#e5484f1e8156996e383aceebb3789fd75df1874d" + integrity sha512-k+YsbhpA9e+EFfKjTCH3VW6aoKlyNYI6NYdTfDL4CIvFnvsuO84ttonmZE7rc+v23SLTH8XX+5w/Ak9v0xGY4g== + +pngjs@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-5.0.0.tgz#e79dd2b215767fd9c04561c01236df960bce7fbb" + integrity sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw== + +pnp-webpack-plugin@1.6.4: + version "1.6.4" + resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz#c9711ac4dc48a685dabafc86f8b6dd9f8df84149" + integrity sha512-7Wjy+9E3WwLOEL30D+m8TSTF7qJJUJLONBnwQp0518siuMxUQUbgZwssaFX+QKlZkjHZcw/IpZCt/H0srrntSg== + dependencies: + ts-pnp "^1.1.6" + +polished@^4.2.2: + version "4.2.2" + resolved "https://registry.yarnpkg.com/polished/-/polished-4.2.2.tgz#2529bb7c3198945373c52e34618c8fe7b1aa84d1" + integrity sha512-Sz2Lkdxz6F2Pgnpi9U5Ng/WdWAUZxmHrNPoVlm3aAemxoy2Qy7LGjQg4uf8qKelDAUW94F4np3iH2YPf2qefcQ== + dependencies: + "@babel/runtime" "^7.17.8" popper.js@^1.14.3: version "1.16.1" resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" integrity sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ== -portfinder@^1.0.26: - version "1.0.28" - resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.28.tgz#67c4622852bd5374dd1dd900f779f53462fac778" - integrity sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA== - dependencies: - async "^2.6.2" - debug "^3.1.1" - mkdirp "^0.5.5" - posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" - integrity sha1-AerA/jta9xoqbAL+q7jB/vfgDqs= + integrity sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg== -postcss-attribute-case-insensitive@^4.0.1: - version "4.0.2" - resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-4.0.2.tgz#d93e46b504589e94ac7277b0463226c68041a880" - integrity sha512-clkFxk/9pcdb4Vkn0hAHq3YnxBQ2p0CGD1dy24jN+reBck+EWxMbxSUqN4Yj7t0w8csl87K6p0gxBe1utkJsYA== +postcss-attribute-case-insensitive@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-attribute-case-insensitive/-/postcss-attribute-case-insensitive-5.0.0.tgz#39cbf6babf3ded1e4abf37d09d6eda21c644105c" + integrity sha512-b4g9eagFGq9T5SWX4+USfVyjIb3liPnjhHHRMP7FMB2kFVpYyfEscV0wP3eaXhKlcHKUut8lt5BGoeylWA/dBQ== dependencies: - postcss "^7.0.2" postcss-selector-parser "^6.0.2" -postcss-calc@^8.0.0: +postcss-clamp@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/postcss-clamp/-/postcss-clamp-4.1.0.tgz#7263e95abadd8c2ba1bd911b0b5a5c9c93e02363" + integrity sha512-ry4b1Llo/9zz+PKC+030KUnPITTJAHeOwjfAyyB60eT0AorGLdzp52s31OsPRHRf8NchkgFoG2y6fCfn1IV1Ow== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-functional-notation@^4.2.2: + version "4.2.3" + resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-4.2.3.tgz#23c9d73c76113b75473edcf66f443c6f1872bd0f" + integrity sha512-5fbr6FzFzjwHXKsVnkmEYrJYG8VNNzvD1tAXaPPWR97S6rhKI5uh2yOfV5TAzhDkZoq4h+chxEplFDc8GeyFtw== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-hex-alpha@^8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-8.0.3.tgz#61a0fd151d28b128aa6a8a21a2dad24eebb34d52" + integrity sha512-fESawWJCrBV035DcbKRPAVmy21LpoyiXdPTuHUfWJ14ZRjY7Y7PA6P4g8z6LQGYhU1WAxkTxjIjurXzoe68Glw== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-color-rebeccapurple@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-7.0.2.tgz#5d397039424a58a9ca628762eb0b88a61a66e079" + integrity sha512-SFc3MaocHaQ6k3oZaFwH8io6MdypkUtEy/eXzXEB1vEQlO3S3oDc/FSZA8AsS04Z25RirQhlDlHLh3dn7XewWw== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-custom-media@^8.0.0: version "8.0.0" - resolved "https://registry.yarnpkg.com/postcss-calc/-/postcss-calc-8.0.0.tgz#a05b87aacd132740a5db09462a3612453e5df90a" - integrity sha512-5NglwDrcbiy8XXfPM11F3HeC6hoT9W7GUH/Zi5U/p7u3Irv4rHhdDcIZwG0llHXV4ftsBjpfWMXAnXNl4lnt8g== - dependencies: - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.0.2" + resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-8.0.0.tgz#1be6aff8be7dc9bf1fe014bde3b71b92bb4552f1" + integrity sha512-FvO2GzMUaTN0t1fBULDeIvxr5IvbDXcIatt6pnJghc736nqNgsGao5NT+5+WVLAQiTt6Cb3YUms0jiPaXhL//g== -postcss-color-functional-notation@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-color-functional-notation/-/postcss-color-functional-notation-2.0.1.tgz#5efd37a88fbabeb00a2966d1e53d98ced93f74e0" - integrity sha512-ZBARCypjEDofW4P6IdPVTLhDNXPRn8T2s1zHbZidW6rPaaZvcnCS2soYFIQJrMZSxiePJ2XIYTlcb2ztr/eT2g== +postcss-custom-properties@^12.1.7: + version "12.1.7" + resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-12.1.7.tgz#ca470fd4bbac5a87fd868636dafc084bc2a78b41" + integrity sha512-N/hYP5gSoFhaqxi2DPCmvto/ZcRDVjE3T1LiAMzc/bg53hvhcHOLpXOHb526LzBBp5ZlAUhkuot/bfpmpgStJg== dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" + postcss-value-parser "^4.2.0" -postcss-color-gray@^5.0.0: +postcss-custom-selectors@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-6.0.0.tgz#022839e41fbf71c47ae6e316cb0e6213012df5ef" + integrity sha512-/1iyBhz/W8jUepjGyu7V1OPcGbc636snN1yXEQCinb6Bwt7KxsiU7/bLQlp8GwAXzCh7cobBU5odNn/2zQWR8Q== + dependencies: + postcss-selector-parser "^6.0.4" + +postcss-dir-pseudo-class@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-6.0.4.tgz#9afe49ea631f0cb36fa0076e7c2feb4e7e3f049c" + integrity sha512-I8epwGy5ftdzNWEYok9VjW9whC4xnelAtbajGv4adql4FIF09rnrxnA9Y8xSHN47y7gqFIv10C5+ImsLeJpKBw== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-double-position-gradients@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-3.1.1.tgz#a12cfdb7d11fa1a99ccecc747f0c19718fb37152" + integrity sha512-jM+CGkTs4FcG53sMPjrrGE0rIvLDdCrqMzgDC5fLI7JHDO7o6QG8C5TQBtExb13hdBdoH9C2QVbG4jo2y9lErQ== + dependencies: + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" + +postcss-env-function@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-4.0.6.tgz#7b2d24c812f540ed6eda4c81f6090416722a8e7a" + integrity sha512-kpA6FsLra+NqcFnL81TnsU+Z7orGtDTxcOhl6pwXeEq1yFPpRMkCDpHhrz8CFQDr/Wfm0jLiNQ1OsGGPjlqPwA== + dependencies: + postcss-value-parser "^4.2.0" + +postcss-flexbugs-fixes@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz#9218a65249f30897deab1033aced8578562a6690" + integrity sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ== + dependencies: + postcss "^7.0.26" + +postcss-focus-visible@^6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-6.0.4.tgz#50c9ea9afa0ee657fb75635fabad25e18d76bf9e" + integrity sha512-QcKuUU/dgNsstIK6HELFRT5Y3lbrMLEOwG+A4s5cA+fx3A3y/JTq3X9LaOj3OC3ALH0XqyrgQIgey/MIZ8Wczw== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-focus-within@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-5.0.4.tgz#5b1d2ec603195f3344b716c0b75f61e44e8d2e20" + integrity sha512-vvjDN++C0mu8jz4af5d52CB184ogg/sSxAFS+oUJQq2SuCe7T5U2iIsVJtsCp2d6R4j0jr5+q3rPkBVZkXD9fQ== + dependencies: + postcss-selector-parser "^6.0.9" + +postcss-font-variant@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-color-gray/-/postcss-color-gray-5.0.0.tgz#532a31eb909f8da898ceffe296fdc1f864be8547" - integrity sha512-q6BuRnAGKM/ZRpfDascZlIZPjvwsRye7UDNalqVz3s7GDxMtqPY6+Q871liNxsonUw8oC61OG+PSaysYpl1bnw== - dependencies: - "@csstools/convert-colors" "^1.4.0" - postcss "^7.0.5" - postcss-values-parser "^2.0.0" + resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-5.0.0.tgz#efd59b4b7ea8bb06127f2d031bfbb7f24d32fa66" + integrity sha512-1fmkBaCALD72CK2a9i468mA/+tr9/1cBxRRMXOUaZqO43oWPR5imcyPjXwuv7PXbCid4ndlP5zWhidQVVa3hmA== -postcss-color-hex-alpha@^5.0.3: - version "5.0.3" - resolved "https://registry.yarnpkg.com/postcss-color-hex-alpha/-/postcss-color-hex-alpha-5.0.3.tgz#a8d9ca4c39d497c9661e374b9c51899ef0f87388" - integrity sha512-PF4GDel8q3kkreVXKLAGNpHKilXsZ6xuu+mOQMHWHLPNyjiUBOr75sp5ZKJfmv1MCus5/DWUGcK9hm6qHEnXYw== - dependencies: - postcss "^7.0.14" - postcss-values-parser "^2.0.1" - -postcss-color-mod-function@^3.0.3: +postcss-gap-properties@^3.0.3: version "3.0.3" - resolved "https://registry.yarnpkg.com/postcss-color-mod-function/-/postcss-color-mod-function-3.0.3.tgz#816ba145ac11cc3cb6baa905a75a49f903e4d31d" - integrity sha512-YP4VG+xufxaVtzV6ZmhEtc+/aTXH3d0JLpnYfxqTvwZPbJhWqp8bSY3nfNzNRFLgB4XSaBA82OE4VjOOKpCdVQ== + resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-3.0.3.tgz#6401bb2f67d9cf255d677042928a70a915e6ba60" + integrity sha512-rPPZRLPmEKgLk/KlXMqRaNkYTUpE7YC+bOIQFN5xcu1Vp11Y4faIXv6/Jpft6FMnl6YRxZqDZG0qQOW80stzxQ== + +postcss-image-set-function@^4.0.6: + version "4.0.6" + resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-4.0.6.tgz#bcff2794efae778c09441498f40e0c77374870a9" + integrity sha512-KfdC6vg53GC+vPd2+HYzsZ6obmPqOk6HY09kttU19+Gj1nC3S3XBVEXDHxkhxTohgZqzbUb94bKXvKDnYWBm/A== dependencies: - "@csstools/convert-colors" "^1.4.0" - postcss "^7.0.2" - postcss-values-parser "^2.0.0" + postcss-value-parser "^4.2.0" -postcss-color-rebeccapurple@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-color-rebeccapurple/-/postcss-color-rebeccapurple-4.0.1.tgz#c7a89be872bb74e45b1e3022bfe5748823e6de77" - integrity sha512-aAe3OhkS6qJXBbqzvZth2Au4V3KieR5sRQ4ptb2b2O8wgvB3SJBsdG+jsn2BZbbwekDG8nTfcCNKcSfe/lEy8g== - dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-colormin@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/postcss-colormin/-/postcss-colormin-5.2.0.tgz#2b620b88c0ff19683f3349f4cf9e24ebdafb2c88" - integrity sha512-+HC6GfWU3upe5/mqmxuqYZ9B2Wl4lcoUUNkoaX59nEWV4EtADCMiBqui111Bu8R8IvaZTmqmxrqOAqjbHIwXPw== - dependencies: - browserslist "^4.16.6" - caniuse-api "^3.0.0" - colord "^2.0.1" - postcss-value-parser "^4.1.0" - -postcss-convert-values@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-convert-values/-/postcss-convert-values-5.0.1.tgz#4ec19d6016534e30e3102fdf414e753398645232" - integrity sha512-C3zR1Do2BkKkCgC0g3sF8TS0koF2G+mN8xxayZx3f10cIRmTaAnpgpRQZjNekTZxM2ciSPoh2IWJm0VZx8NoQg== - dependencies: - postcss-value-parser "^4.1.0" - -postcss-custom-media@^7.0.8: - version "7.0.8" - resolved "https://registry.yarnpkg.com/postcss-custom-media/-/postcss-custom-media-7.0.8.tgz#fffd13ffeffad73621be5f387076a28b00294e0c" - integrity sha512-c9s5iX0Ge15o00HKbuRuTqNndsJUbaXdiNsksnVH8H4gdc+zbLzr/UasOwNG6CTDpLFekVY4672eWdiiWu2GUg== - dependencies: - postcss "^7.0.14" - -postcss-custom-properties@^8.0.11: - version "8.0.11" - resolved "https://registry.yarnpkg.com/postcss-custom-properties/-/postcss-custom-properties-8.0.11.tgz#2d61772d6e92f22f5e0d52602df8fae46fa30d97" - integrity sha512-nm+o0eLdYqdnJ5abAJeXp4CEU1c1k+eB2yMCvhgzsds/e0umabFrN6HoTy/8Q4K5ilxERdl/JD1LO5ANoYBeMA== - dependencies: - postcss "^7.0.17" - postcss-values-parser "^2.0.1" - -postcss-custom-selectors@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/postcss-custom-selectors/-/postcss-custom-selectors-5.1.2.tgz#64858c6eb2ecff2fb41d0b28c9dd7b3db4de7fba" - integrity sha512-DSGDhqinCqXqlS4R7KGxL1OSycd1lydugJ1ky4iRXPHdBRiozyMHrdu0H3o7qNOCiZwySZTUI5MV0T8QhCLu+w== - dependencies: - postcss "^7.0.2" - postcss-selector-parser "^5.0.0-rc.3" - -postcss-dir-pseudo-class@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-dir-pseudo-class/-/postcss-dir-pseudo-class-5.0.0.tgz#6e3a4177d0edb3abcc85fdb6fbb1c26dabaeaba2" - integrity sha512-3pm4oq8HYWMZePJY+5ANriPs3P07q+LW6FAdTlkFH2XqDdP4HeeJYMOzn0HYLhRSjBO3fhiqSwwU9xEULSrPgw== - dependencies: - postcss "^7.0.2" - postcss-selector-parser "^5.0.0-rc.3" - -postcss-discard-comments@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-comments/-/postcss-discard-comments-5.0.1.tgz#9eae4b747cf760d31f2447c27f0619d5718901fe" - integrity sha512-lgZBPTDvWrbAYY1v5GYEv8fEO/WhKOu/hmZqmCYfrpD6eyDWWzAOsl2rF29lpvziKO02Gc5GJQtlpkTmakwOWg== - -postcss-discard-duplicates@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-duplicates/-/postcss-discard-duplicates-5.0.1.tgz#68f7cc6458fe6bab2e46c9f55ae52869f680e66d" - integrity sha512-svx747PWHKOGpAXXQkCc4k/DsWo+6bc5LsVrAsw+OU+Ibi7klFZCyX54gjYzX4TH+f2uzXjRviLARxkMurA2bA== - -postcss-discard-empty@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-empty/-/postcss-discard-empty-5.0.1.tgz#ee136c39e27d5d2ed4da0ee5ed02bc8a9f8bf6d8" - integrity sha512-vfU8CxAQ6YpMxV2SvMcMIyF2LX1ZzWpy0lqHDsOdaKKLQVQGVP1pzhrI9JlsO65s66uQTfkQBKBD/A5gp9STFw== - -postcss-discard-overridden@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-discard-overridden/-/postcss-discard-overridden-5.0.1.tgz#454b41f707300b98109a75005ca4ab0ff2743ac6" - integrity sha512-Y28H7y93L2BpJhrdUR2SR2fnSsT+3TVx1NmVQLbcnZWwIUpJ7mfcTC6Za9M2PG6w8j7UQRfzxqn8jU2VwFxo3Q== - -postcss-double-position-gradients@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/postcss-double-position-gradients/-/postcss-double-position-gradients-1.0.0.tgz#fc927d52fddc896cb3a2812ebc5df147e110522e" - integrity sha512-G+nV8EnQq25fOI8CH/B6krEohGWnF5+3A6H/+JEpOncu5dCnkS1QQ6+ct3Jkaepw1NGVqqOZH6lqrm244mCftA== - dependencies: - postcss "^7.0.5" - postcss-values-parser "^2.0.0" - -postcss-env-function@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/postcss-env-function/-/postcss-env-function-2.0.2.tgz#0f3e3d3c57f094a92c2baf4b6241f0b0da5365d7" - integrity sha512-rwac4BuZlITeUbiBq60h/xbLzXY43qOsIErngWa4l7Mt+RaSkT7QBjXVGTcBHupykkblHMDrBFh30zchYPaOUw== - dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-focus-visible@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-focus-visible/-/postcss-focus-visible-4.0.0.tgz#477d107113ade6024b14128317ade2bd1e17046e" - integrity sha512-Z5CkWBw0+idJHSV6+Bgf2peDOFf/x4o+vX/pwcNYrWpXFrSfTkQ3JQ1ojrq9yS+upnAlNRHeg8uEwFTgorjI8g== - dependencies: - postcss "^7.0.2" - -postcss-focus-within@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-focus-within/-/postcss-focus-within-3.0.0.tgz#763b8788596cee9b874c999201cdde80659ef680" - integrity sha512-W0APui8jQeBKbCGZudW37EeMCjDeVxKgiYfIIEo8Bdh5SpB9sxds/Iq8SEuzS0Q4YFOlG7EPFulbbxujpkrV2w== - dependencies: - postcss "^7.0.2" - -postcss-font-variant@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-font-variant/-/postcss-font-variant-4.0.1.tgz#42d4c0ab30894f60f98b17561eb5c0321f502641" - integrity sha512-I3ADQSTNtLTTd8uxZhtSOrTCQ9G4qUVKPjHiDk0bV75QSxXjVWiJVJ2VLdspGUi9fbW9BcjKJoRvxAH1pckqmA== - dependencies: - postcss "^7.0.2" - -postcss-gap-properties@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-gap-properties/-/postcss-gap-properties-2.0.0.tgz#431c192ab3ed96a3c3d09f2ff615960f902c1715" - integrity sha512-QZSqDaMgXCHuHTEzMsS2KfVDOq7ZFiknSpkrPJY6jmxbugUPTuSzs/vuE5I3zv0WAS+3vhrlqhijiprnuQfzmg== - dependencies: - postcss "^7.0.2" - -postcss-image-set-function@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/postcss-image-set-function/-/postcss-image-set-function-3.0.1.tgz#28920a2f29945bed4c3198d7df6496d410d3f288" - integrity sha512-oPTcFFip5LZy8Y/whto91L9xdRHCWEMs3e1MdJxhgt4jy2WYXfhkng59fH5qLXSCPN8k4n94p1Czrfe5IOkKUw== - dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-import@14.0.2: - version "14.0.2" - resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-14.0.2.tgz#60eff77e6be92e7b67fe469ec797d9424cae1aa1" - integrity sha512-BJ2pVK4KhUyMcqjuKs9RijV5tatNzNa73e/32aBVE/ejYPe37iH+6vAu9WvqUkB5OAYgLHzbSvzHnorybJCm9g== +postcss-import@14.1.0: + version "14.1.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-14.1.0.tgz#a7333ffe32f0b8795303ee9e40215dac922781f0" + integrity sha512-flwI+Vgm4SElObFVPpTIT7SU7R3qk2L7PyduMcokiaVKuWv9d/U+Gm/QAd8NDLuykTWTkcrjOeD2Pp1rMeBTGw== dependencies: postcss-value-parser "^4.0.0" read-cache "^1.0.0" resolve "^1.1.7" -postcss-initial@^3.0.0: - version "3.0.4" - resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-3.0.4.tgz#9d32069a10531fe2ecafa0b6ac750ee0bc7efc53" - integrity sha512-3RLn6DIpMsK1l5UUy9jxQvoDeUN4gP939tDcKUHD/kM8SGSKbFAnvkpFpj3Bhtz3HGk1jWY5ZNWX6mPta5M9fg== - dependencies: - postcss "^7.0.2" +postcss-initial@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-4.0.1.tgz#529f735f72c5724a0fb30527df6fb7ac54d7de42" + integrity sha512-0ueD7rPqX8Pn1xJIjay0AZeIuDoF+V+VvMt/uOnn+4ezUKhZM/NokDeP6DwMNyIoYByuN/94IQnt5FEkaN59xQ== -postcss-lab-function@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-2.0.1.tgz#bb51a6856cd12289ab4ae20db1e3821ef13d7d2e" - integrity sha512-whLy1IeZKY+3fYdqQFuDBf8Auw+qFuVnChWjmxm/UhHWqNHZx+B99EwxTvGYmUBqe3Fjxs4L1BoZTJmPu6usVg== +postcss-lab-function@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-lab-function/-/postcss-lab-function-4.2.0.tgz#e054e662c6480202f5760887ec1ae0d153357123" + integrity sha512-Zb1EO9DGYfa3CP8LhINHCcTTCTLI+R3t7AX2mKsDzdgVQ/GkCpHOTgOr6HBHslP7XDdVbqgHW5vvRPMdVANQ8w== dependencies: - "@csstools/convert-colors" "^1.4.0" - postcss "^7.0.2" - postcss-values-parser "^2.0.0" + "@csstools/postcss-progressive-custom-properties" "^1.1.0" + postcss-value-parser "^4.2.0" -postcss-loader@6.1.1: - version "6.1.1" - resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-6.1.1.tgz#58dd0a3accd9bc87cc52eff75244db578d11301a" - integrity sha512-lBmJMvRh1D40dqpWKr9Rpygwxn8M74U9uaCSeYGNKLGInbk9mXBt1ultHf2dH9Ghk6Ue4UXlXWwGMH9QdUJ5ug== +postcss-loader@6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-6.2.1.tgz#0895f7346b1702103d30fdc66e4d494a93c008ef" + integrity sha512-WbbYpmAaKcux/P66bZ40bpWsBucjx/TTgVVzRZ9yUO8yQfVBlameJ0ZGVaPfH64hNSBh63a+ICP5nqOpBA0w+Q== + dependencies: + cosmiconfig "^7.0.0" + klona "^2.0.5" + semver "^7.3.5" + +postcss-loader@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-4.3.0.tgz#2c4de9657cd4f07af5ab42bd60a673004da1b8cc" + integrity sha512-M/dSoIiNDOo8Rk0mUqoj4kpGq91gcxCfb9PoyZVdZ76/AuhxylHDYZblNE8o+EQ9AMSASeMFEKxZf5aU6wlx1Q== dependencies: cosmiconfig "^7.0.0" klona "^2.0.4" - semver "^7.3.5" + loader-utils "^2.0.0" + schema-utils "^3.0.0" + semver "^7.3.4" -postcss-logical@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-3.0.0.tgz#2495d0f8b82e9f262725f75f9401b34e7b45d5b5" - integrity sha512-1SUKdJc2vuMOmeItqGuNaC+N8MzBWFWEkAnRnLpFYj1tGGa7NqyVBujfRtgNa2gXR+6RkGUiB2O5Vmh7E2RmiA== - dependencies: - postcss "^7.0.2" +postcss-logical@^5.0.4: + version "5.0.4" + resolved "https://registry.yarnpkg.com/postcss-logical/-/postcss-logical-5.0.4.tgz#ec75b1ee54421acc04d5921576b7d8db6b0e6f73" + integrity sha512-RHXxplCeLh9VjinvMrZONq7im4wjWGlRJAqmAVLXyZaXwfDWP73/oq4NdIp+OZwhQUMj0zjqDfM5Fj7qby+B4g== -postcss-media-minmax@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-4.0.0.tgz#b75bb6cbc217c8ac49433e12f22048814a4f5ed5" - integrity sha512-fo9moya6qyxsjbFAYl97qKO9gyre3qvbMnkOZeZwlsW6XYFsvs2DMGDlchVLfAd8LHPZDxivu/+qW2SMQeTHBw== - dependencies: - postcss "^7.0.2" +postcss-media-minmax@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/postcss-media-minmax/-/postcss-media-minmax-5.0.0.tgz#7140bddec173e2d6d657edbd8554a55794e2a5b5" + integrity sha512-yDUvFf9QdFZTuCUg0g0uNSHVlJ5X1lSzDZjPSFaiCWvjgsvu8vEVxtahPrLMinIDEEGnx6cBe6iqdx5YWz08wQ== -postcss-merge-longhand@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-merge-longhand/-/postcss-merge-longhand-5.0.2.tgz#277ada51d9a7958e8ef8cf263103c9384b322a41" - integrity sha512-BMlg9AXSI5G9TBT0Lo/H3PfUy63P84rVz3BjCFE9e9Y9RXQZD3+h3YO1kgTNsNJy7bBc1YQp8DmSnwLIW5VPcw== +postcss-modules-extract-imports@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-2.0.0.tgz#818719a1ae1da325f9832446b01136eeb493cd7e" + integrity sha512-LaYLDNS4SG8Q5WAWqIJgdHPJrDDr/Lv775rMBFUbgjTz6j34lUznACHcdRWroPvXANP2Vj7yNK57vp9eFqzLWQ== dependencies: - css-color-names "^1.0.1" - postcss-value-parser "^4.1.0" - stylehacks "^5.0.1" - -postcss-merge-rules@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-merge-rules/-/postcss-merge-rules-5.0.2.tgz#d6e4d65018badbdb7dcc789c4f39b941305d410a" - integrity sha512-5K+Md7S3GwBewfB4rjDeol6V/RZ8S+v4B66Zk2gChRqLTCC8yjnHQ601omj9TKftS19OPGqZ/XzoqpzNQQLwbg== - dependencies: - browserslist "^4.16.6" - caniuse-api "^3.0.0" - cssnano-utils "^2.0.1" - postcss-selector-parser "^6.0.5" - vendors "^1.0.3" - -postcss-minify-font-values@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-minify-font-values/-/postcss-minify-font-values-5.0.1.tgz#a90cefbfdaa075bd3dbaa1b33588bb4dc268addf" - integrity sha512-7JS4qIsnqaxk+FXY1E8dHBDmraYFWmuL6cgt0T1SWGRO5bzJf8sUoelwa4P88LEWJZweHevAiDKxHlofuvtIoA== - dependencies: - postcss-value-parser "^4.1.0" - -postcss-minify-gradients@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-minify-gradients/-/postcss-minify-gradients-5.0.2.tgz#7c175c108f06a5629925d698b3c4cf7bd3864ee5" - integrity sha512-7Do9JP+wqSD6Prittitt2zDLrfzP9pqKs2EcLX7HJYxsxCOwrrcLt4x/ctQTsiOw+/8HYotAoqNkrzItL19SdQ== - dependencies: - colord "^2.6" - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - -postcss-minify-params@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-minify-params/-/postcss-minify-params-5.0.1.tgz#371153ba164b9d8562842fdcd929c98abd9e5b6c" - integrity sha512-4RUC4k2A/Q9mGco1Z8ODc7h+A0z7L7X2ypO1B6V8057eVK6mZ6xwz6QN64nHuHLbqbclkX1wyzRnIrdZehTEHw== - dependencies: - alphanum-sort "^1.0.2" - browserslist "^4.16.0" - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - uniqs "^2.0.0" - -postcss-minify-selectors@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/postcss-minify-selectors/-/postcss-minify-selectors-5.1.0.tgz#4385c845d3979ff160291774523ffa54eafd5a54" - integrity sha512-NzGBXDa7aPsAcijXZeagnJBKBPMYLaJJzB8CQh6ncvyl2sIndLVWfbcDi0SBjRWk5VqEjXvf8tYwzoKf4Z07og== - dependencies: - alphanum-sort "^1.0.2" - postcss-selector-parser "^6.0.5" + postcss "^7.0.5" postcss-modules-extract-imports@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== +postcss-modules-local-by-default@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-3.0.3.tgz#bb14e0cc78279d504dbdcbfd7e0ca28993ffbbb0" + integrity sha512-e3xDq+LotiGesympRlKNgaJ0PCzoUIdpH0dj47iWAui/kyTgh3CiAr1qP54uodmJhl6p9rN6BoNcdEDVJx9RDw== + dependencies: + icss-utils "^4.1.1" + postcss "^7.0.32" + postcss-selector-parser "^6.0.2" + postcss-value-parser "^4.1.0" + postcss-modules-local-by-default@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" @@ -6515,6 +12861,14 @@ postcss-modules-local-by-default@^4.0.0: postcss-selector-parser "^6.0.2" postcss-value-parser "^4.1.0" +postcss-modules-scope@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-2.2.0.tgz#385cae013cc7743f5a7d7602d1073a89eaae62ee" + integrity sha512-YyEgsTMRpNd+HmyC7H/mh3y+MeFWevy7V1evVhJWewmMbjDHIbZbOXICC2y+m1xI1UVfIT1HMW/O04Hxyu9oXQ== + dependencies: + postcss "^7.0.6" + postcss-selector-parser "^6.0.0" + postcss-modules-scope@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" @@ -6522,6 +12876,14 @@ postcss-modules-scope@^3.0.0: dependencies: postcss-selector-parser "^6.0.4" +postcss-modules-values@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-3.0.0.tgz#5b5000d6ebae29b4255301b4a3a54574423e7f10" + integrity sha512-1//E5jCBrZ9DmRX+zCtmQtRSV6PV42Ix7Bzj9GbwJceduuf7IqP8MgeTXuRDHOWj2m0VzZD5+roFWDuU8RQjcg== + dependencies: + icss-utils "^4.0.0" + postcss "^7.0.6" + postcss-modules-values@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" @@ -6529,210 +12891,115 @@ postcss-modules-values@^4.0.0: dependencies: icss-utils "^5.0.0" -postcss-nesting@^7.0.0: - version "7.0.1" - resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-7.0.1.tgz#b50ad7b7f0173e5b5e3880c3501344703e04c052" - integrity sha512-FrorPb0H3nuVq0Sff7W2rnc3SmIcruVC6YwpcS+k687VxyxO33iE1amna7wHuRVzM8vfiYofXSBHNAZ3QhLvYg== +postcss-nesting@^10.1.4: + version "10.1.7" + resolved "https://registry.yarnpkg.com/postcss-nesting/-/postcss-nesting-10.1.7.tgz#0101bd6c7d386e7ad8e2e86ebcc0e0109833b86e" + integrity sha512-Btho5XzDTpl117SmB3tvUHP8txg5n7Ayv7vQ5m4b1zXkfs1Y52C67uZjZ746h7QvOJ+rLRg50OlhhjFW+IQY6A== dependencies: - postcss "^7.0.2" + "@csstools/selector-specificity" "1.0.0" + postcss-selector-parser "^6.0.10" -postcss-normalize-charset@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-5.0.1.tgz#121559d1bebc55ac8d24af37f67bd4da9efd91d0" - integrity sha512-6J40l6LNYnBdPSk+BHZ8SF+HAkS4q2twe5jnocgd+xWpz/mx/5Sa32m3W1AA8uE8XaXN+eg8trIlfu8V9x61eg== +postcss-opacity-percentage@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/postcss-opacity-percentage/-/postcss-opacity-percentage-1.1.2.tgz#bd698bb3670a0a27f6d657cc16744b3ebf3b1145" + integrity sha512-lyUfF7miG+yewZ8EAk9XUBIlrHyUE6fijnesuz+Mj5zrIHIEw6KcIZSOk/elVMqzLvREmXB83Zi/5QpNRYd47w== -postcss-normalize-display-values@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-display-values/-/postcss-normalize-display-values-5.0.1.tgz#62650b965981a955dffee83363453db82f6ad1fd" - integrity sha512-uupdvWk88kLDXi5HEyI9IaAJTE3/Djbcrqq8YgjvAVuzgVuqIk3SuJWUisT2gaJbZm1H9g5k2w1xXilM3x8DjQ== +postcss-overflow-shorthand@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-3.0.3.tgz#ebcfc0483a15bbf1b27fdd9b3c10125372f4cbc2" + integrity sha512-CxZwoWup9KXzQeeIxtgOciQ00tDtnylYIlJBBODqkgS/PU2jISuWOL/mYLHmZb9ZhZiCaNKsCRiLp22dZUtNsg== + +postcss-page-break@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-3.0.4.tgz#7fbf741c233621622b68d435babfb70dd8c1ee5f" + integrity sha512-1JGu8oCjVXLa9q9rFTo4MbeeA5FMe00/9C7lN4va606Rdb+HkxXtXsmEDrIraQ11fGz/WvKWa8gMuCKkrXpTsQ== + +postcss-place@^7.0.4: + version "7.0.4" + resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-7.0.4.tgz#eb026650b7f769ae57ca4f938c1addd6be2f62c9" + integrity sha512-MrgKeiiu5OC/TETQO45kV3npRjOFxEHthsqGtkh3I1rPbZSbXGD/lZVi9j13cYh+NA8PIAPyk6sGjT9QbRyvSg== dependencies: - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" + postcss-value-parser "^4.2.0" -postcss-normalize-positions@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-positions/-/postcss-normalize-positions-5.0.1.tgz#868f6af1795fdfa86fbbe960dceb47e5f9492fe5" - integrity sha512-rvzWAJai5xej9yWqlCb1OWLd9JjW2Ex2BCPzUJrbaXmtKtgfL8dBMOOMTX6TnvQMtjk3ei1Lswcs78qKO1Skrg== +postcss-preset-env@7.5.0: + version "7.5.0" + resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-7.5.0.tgz#0c1f23933597d55dab4a90f61eda30b76e710658" + integrity sha512-0BJzWEfCdTtK2R3EiKKSdkE51/DI/BwnhlnicSW482Ym6/DGHud8K0wGLcdjip1epVX0HKo4c8zzTeV/SkiejQ== dependencies: - postcss-value-parser "^4.1.0" + "@csstools/postcss-color-function" "^1.1.0" + "@csstools/postcss-font-format-keywords" "^1.0.0" + "@csstools/postcss-hwb-function" "^1.0.0" + "@csstools/postcss-ic-unit" "^1.0.0" + "@csstools/postcss-is-pseudo-class" "^2.0.2" + "@csstools/postcss-normalize-display-values" "^1.0.0" + "@csstools/postcss-oklab-function" "^1.1.0" + "@csstools/postcss-progressive-custom-properties" "^1.3.0" + "@csstools/postcss-stepped-value-functions" "^1.0.0" + "@csstools/postcss-unset-value" "^1.0.0" + autoprefixer "^10.4.6" + browserslist "^4.20.3" + css-blank-pseudo "^3.0.3" + css-has-pseudo "^3.0.4" + css-prefers-color-scheme "^6.0.3" + cssdb "^6.6.1" + postcss-attribute-case-insensitive "^5.0.0" + postcss-clamp "^4.1.0" + postcss-color-functional-notation "^4.2.2" + postcss-color-hex-alpha "^8.0.3" + postcss-color-rebeccapurple "^7.0.2" + postcss-custom-media "^8.0.0" + postcss-custom-properties "^12.1.7" + postcss-custom-selectors "^6.0.0" + postcss-dir-pseudo-class "^6.0.4" + postcss-double-position-gradients "^3.1.1" + postcss-env-function "^4.0.6" + postcss-focus-visible "^6.0.4" + postcss-focus-within "^5.0.4" + postcss-font-variant "^5.0.0" + postcss-gap-properties "^3.0.3" + postcss-image-set-function "^4.0.6" + postcss-initial "^4.0.1" + postcss-lab-function "^4.2.0" + postcss-logical "^5.0.4" + postcss-media-minmax "^5.0.0" + postcss-nesting "^10.1.4" + postcss-opacity-percentage "^1.1.2" + postcss-overflow-shorthand "^3.0.3" + postcss-page-break "^3.0.4" + postcss-place "^7.0.4" + postcss-pseudo-class-any-link "^7.1.2" + postcss-replace-overflow-wrap "^4.0.0" + postcss-selector-not "^5.0.0" + postcss-value-parser "^4.2.0" -postcss-normalize-repeat-style@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.0.1.tgz#cbc0de1383b57f5bb61ddd6a84653b5e8665b2b5" - integrity sha512-syZ2itq0HTQjj4QtXZOeefomckiV5TaUO6ReIEabCh3wgDs4Mr01pkif0MeVwKyU/LHEkPJnpwFKRxqWA/7O3w== +postcss-pseudo-class-any-link@^7.1.2: + version "7.1.4" + resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-7.1.4.tgz#ac72aac4fe11fc4a0a368691f8fd5fe89e95aba4" + integrity sha512-JxRcLXm96u14N3RzFavPIE9cRPuOqLDuzKeBsqi4oRk4vt8n0A7I0plFs/VXTg7U2n7g/XkQi0OwqTO3VWBfEg== dependencies: - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" + postcss-selector-parser "^6.0.10" -postcss-normalize-string@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-string/-/postcss-normalize-string-5.0.1.tgz#d9eafaa4df78c7a3b973ae346ef0e47c554985b0" - integrity sha512-Ic8GaQ3jPMVl1OEn2U//2pm93AXUcF3wz+OriskdZ1AOuYV25OdgS7w9Xu2LO5cGyhHCgn8dMXh9bO7vi3i9pA== - dependencies: - postcss-value-parser "^4.1.0" - -postcss-normalize-timing-functions@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.0.1.tgz#8ee41103b9130429c6cbba736932b75c5e2cb08c" - integrity sha512-cPcBdVN5OsWCNEo5hiXfLUnXfTGtSFiBU9SK8k7ii8UD7OLuznzgNRYkLZow11BkQiiqMcgPyh4ZqXEEUrtQ1Q== - dependencies: - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - -postcss-normalize-unicode@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-unicode/-/postcss-normalize-unicode-5.0.1.tgz#82d672d648a411814aa5bf3ae565379ccd9f5e37" - integrity sha512-kAtYD6V3pK0beqrU90gpCQB7g6AOfP/2KIPCVBKJM2EheVsBQmx/Iof+9zR9NFKLAx4Pr9mDhogB27pmn354nA== - dependencies: - browserslist "^4.16.0" - postcss-value-parser "^4.1.0" - -postcss-normalize-url@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-normalize-url/-/postcss-normalize-url-5.0.2.tgz#ddcdfb7cede1270740cf3e4dfc6008bd96abc763" - integrity sha512-k4jLTPUxREQ5bpajFQZpx8bCF2UrlqOTzP9kEqcEnOfwsRshWs2+oAFIHfDQB8GO2PaUaSE0NlTAYtbluZTlHQ== - dependencies: - is-absolute-url "^3.0.3" - normalize-url "^6.0.1" - postcss-value-parser "^4.1.0" - -postcss-normalize-whitespace@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.0.1.tgz#b0b40b5bcac83585ff07ead2daf2dcfbeeef8e9a" - integrity sha512-iPklmI5SBnRvwceb/XH568yyzK0qRVuAG+a1HFUsFRf11lEJTiQQa03a4RSCQvLKdcpX7XsI1Gen9LuLoqwiqA== - dependencies: - postcss-value-parser "^4.1.0" - -postcss-ordered-values@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-ordered-values/-/postcss-ordered-values-5.0.2.tgz#1f351426977be00e0f765b3164ad753dac8ed044" - integrity sha512-8AFYDSOYWebJYLyJi3fyjl6CqMEG/UVworjiyK1r573I56kb3e879sCJLGvR3merj+fAdPpVplXKQZv+ey6CgQ== - dependencies: - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - -postcss-overflow-shorthand@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-overflow-shorthand/-/postcss-overflow-shorthand-2.0.0.tgz#31ecf350e9c6f6ddc250a78f0c3e111f32dd4c30" - integrity sha512-aK0fHc9CBNx8jbzMYhshZcEv8LtYnBIRYQD5i7w/K/wS9c2+0NSR6B3OVMu5y0hBHYLcMGjfU+dmWYNKH0I85g== - dependencies: - postcss "^7.0.2" - -postcss-page-break@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/postcss-page-break/-/postcss-page-break-2.0.0.tgz#add52d0e0a528cabe6afee8b46e2abb277df46bf" - integrity sha512-tkpTSrLpfLfD9HvgOlJuigLuk39wVTbbd8RKcy8/ugV2bNBUW3xU+AIqyxhDrQr1VUj1RmyJrBn1YWrqUm9zAQ== - dependencies: - postcss "^7.0.2" - -postcss-place@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-place/-/postcss-place-4.0.1.tgz#e9f39d33d2dc584e46ee1db45adb77ca9d1dcc62" - integrity sha512-Zb6byCSLkgRKLODj/5mQugyuj9bvAAw9LqJJjgwz5cYryGeXfFZfSXoP1UfveccFmeq0b/2xxwcTEVScnqGxBg== - dependencies: - postcss "^7.0.2" - postcss-values-parser "^2.0.0" - -postcss-preset-env@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/postcss-preset-env/-/postcss-preset-env-6.7.0.tgz#c34ddacf8f902383b35ad1e030f178f4cdf118a5" - integrity sha512-eU4/K5xzSFwUFJ8hTdTQzo2RBLbDVt83QZrAvI07TULOkmyQlnYlpwep+2yIK+K+0KlZO4BvFcleOCCcUtwchg== - dependencies: - autoprefixer "^9.6.1" - browserslist "^4.6.4" - caniuse-lite "^1.0.30000981" - css-blank-pseudo "^0.1.4" - css-has-pseudo "^0.10.0" - css-prefers-color-scheme "^3.1.1" - cssdb "^4.4.0" - postcss "^7.0.17" - postcss-attribute-case-insensitive "^4.0.1" - postcss-color-functional-notation "^2.0.1" - postcss-color-gray "^5.0.0" - postcss-color-hex-alpha "^5.0.3" - postcss-color-mod-function "^3.0.3" - postcss-color-rebeccapurple "^4.0.1" - postcss-custom-media "^7.0.8" - postcss-custom-properties "^8.0.11" - postcss-custom-selectors "^5.1.2" - postcss-dir-pseudo-class "^5.0.0" - postcss-double-position-gradients "^1.0.0" - postcss-env-function "^2.0.2" - postcss-focus-visible "^4.0.0" - postcss-focus-within "^3.0.0" - postcss-font-variant "^4.0.0" - postcss-gap-properties "^2.0.0" - postcss-image-set-function "^3.0.1" - postcss-initial "^3.0.0" - postcss-lab-function "^2.0.1" - postcss-logical "^3.0.0" - postcss-media-minmax "^4.0.0" - postcss-nesting "^7.0.0" - postcss-overflow-shorthand "^2.0.0" - postcss-page-break "^2.0.0" - postcss-place "^4.0.1" - postcss-pseudo-class-any-link "^6.0.0" - postcss-replace-overflow-wrap "^3.0.0" - postcss-selector-matches "^4.0.0" - postcss-selector-not "^4.0.0" - -postcss-pseudo-class-any-link@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/postcss-pseudo-class-any-link/-/postcss-pseudo-class-any-link-6.0.0.tgz#2ed3eed393b3702879dec4a87032b210daeb04d1" - integrity sha512-lgXW9sYJdLqtmw23otOzrtbDXofUdfYzNm4PIpNE322/swES3VU9XlXHeJS46zT2onFO7V1QFdD4Q9LiZj8mew== - dependencies: - postcss "^7.0.2" - postcss-selector-parser "^5.0.0-rc.3" - -postcss-reduce-initial@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-reduce-initial/-/postcss-reduce-initial-5.0.1.tgz#9d6369865b0f6f6f6b165a0ef5dc1a4856c7e946" - integrity sha512-zlCZPKLLTMAqA3ZWH57HlbCjkD55LX9dsRyxlls+wfuRfqCi5mSlZVan0heX5cHr154Dq9AfbH70LyhrSAezJw== - dependencies: - browserslist "^4.16.0" - caniuse-api "^3.0.0" - -postcss-reduce-transforms@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-reduce-transforms/-/postcss-reduce-transforms-5.0.1.tgz#93c12f6a159474aa711d5269923e2383cedcf640" - integrity sha512-a//FjoPeFkRuAguPscTVmRQUODP+f3ke2HqFNgGPwdYnpeC29RZdCBvGRGTsKpMURb/I3p6jdKoBQ2zI+9Q7kA== - dependencies: - cssnano-utils "^2.0.1" - postcss-value-parser "^4.1.0" - -postcss-replace-overflow-wrap@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-3.0.0.tgz#61b360ffdaedca84c7c918d2b0f0d0ea559ab01c" - integrity sha512-2T5hcEHArDT6X9+9dVSPQdo7QHzG4XKclFT8rU5TzJPDN7RIRTbO9c4drUISOVemLj03aezStHCR2AIcr8XLpw== - dependencies: - postcss "^7.0.2" - -postcss-selector-matches@^4.0.0: +postcss-replace-overflow-wrap@^4.0.0: version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-matches/-/postcss-selector-matches-4.0.0.tgz#71c8248f917ba2cc93037c9637ee09c64436fcff" - integrity sha512-LgsHwQR/EsRYSqlwdGzeaPKVT0Ml7LAT6E75T8W8xLJY62CE4S/l03BWIt3jT8Taq22kXP08s2SfTSzaraoPww== - dependencies: - balanced-match "^1.0.0" - postcss "^7.0.2" + resolved "https://registry.yarnpkg.com/postcss-replace-overflow-wrap/-/postcss-replace-overflow-wrap-4.0.0.tgz#d2df6bed10b477bf9c52fab28c568b4b29ca4319" + integrity sha512-KmF7SBPphT4gPPcKZc7aDkweHiKEEO8cla/GjcBK+ckKxiZslIu3C4GCRW3DNfL0o7yW7kMQu9xlZ1kXRXLXtw== -postcss-selector-not@^4.0.0: - version "4.0.1" - resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-4.0.1.tgz#263016eef1cf219e0ade9a913780fc1f48204cbf" - integrity sha512-YolvBgInEK5/79C+bdFMyzqTg6pkYqDbzZIST/PDMqa/o3qtXenD05apBG2jLgT0/BQ77d4U2UK12jWpilqMAQ== - dependencies: - balanced-match "^1.0.0" - postcss "^7.0.2" - -postcss-selector-parser@^5.0.0-rc.3, postcss-selector-parser@^5.0.0-rc.4: +postcss-selector-not@^5.0.0: version "5.0.0" - resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz#249044356697b33b64f1a8f7c80922dddee7195c" - integrity sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ== + resolved "https://registry.yarnpkg.com/postcss-selector-not/-/postcss-selector-not-5.0.0.tgz#ac5fc506f7565dd872f82f5314c0f81a05630dc7" + integrity sha512-/2K3A4TCP9orP4TNS7u3tGdRFVKqz/E6pX3aGnriPG0jU78of8wsUcqE4QAhWEU0d+WnMSF93Ah3F//vUtK+iQ== dependencies: - cssesc "^2.0.0" - indexes-of "^1.0.1" - uniq "^1.0.1" + balanced-match "^1.0.0" -postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector-parser@^6.0.5: +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.10: + version "6.0.10" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz#79b61e2c0d1bfc2602d549e11d0876256f8df88d" + integrity sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w== + dependencies: + cssesc "^3.0.0" + util-deprecate "^1.0.2" + +postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: version "6.0.6" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== @@ -6740,47 +13007,34 @@ postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4, postcss-selector cssesc "^3.0.0" util-deprecate "^1.0.2" -postcss-svgo@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/postcss-svgo/-/postcss-svgo-5.0.2.tgz#bc73c4ea4c5a80fbd4b45e29042c34ceffb9257f" - integrity sha512-YzQuFLZu3U3aheizD+B1joQ94vzPfE6BNUcSYuceNxlVnKKsOtdo6hL9/zyC168Q8EwfLSgaDSalsUGa9f2C0A== +postcss-selector-parser@^6.0.9: + version "6.0.9" + resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.9.tgz#ee71c3b9ff63d9cd130838876c13a2ec1a992b2f" + integrity sha512-UO3SgnZOVTwu4kyLR22UQ1xZh086RyNZppb7lLAKBFK8a32ttG5i87Y/P3+2bRSjZNyJ1B7hfFNo273tKe9YxQ== dependencies: - postcss-value-parser "^4.1.0" - svgo "^2.3.0" + cssesc "^3.0.0" + util-deprecate "^1.0.2" -postcss-unique-selectors@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/postcss-unique-selectors/-/postcss-unique-selectors-5.0.1.tgz#3be5c1d7363352eff838bd62b0b07a0abad43bfc" - integrity sha512-gwi1NhHV4FMmPn+qwBNuot1sG1t2OmacLQ/AX29lzyggnjd+MnVD5uqQmpXO3J17KGL2WAxQruj1qTd3H0gG/w== - dependencies: - alphanum-sort "^1.0.2" - postcss-selector-parser "^6.0.5" - uniqs "^2.0.0" - -postcss-value-parser@^4.0.0, postcss-value-parser@^4.0.2, postcss-value-parser@^4.1.0: +postcss-value-parser@^4.0.0, postcss-value-parser@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz#443f6a20ced6481a2bda4fa8532a6e55d789a2cb" integrity sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ== -postcss-values-parser@^2.0.0, postcss-values-parser@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/postcss-values-parser/-/postcss-values-parser-2.0.1.tgz#da8b472d901da1e205b47bdc98637b9e9e550e5f" - integrity sha512-2tLuBsA6P4rYTNKCXYG/71C7j1pU6pK503suYOmn4xYrQIzW+opD+7FAFNuGSdZC/3Qfy334QbeMu7MEb8gOxg== - dependencies: - flatten "^1.0.2" - indexes-of "^1.0.1" - uniq "^1.0.1" +postcss-value-parser@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" + integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@8.3.6: - version "8.3.6" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.6.tgz#2730dd76a97969f37f53b9a6096197be311cc4ea" - integrity sha512-wG1cc/JhRgdqB6WHEuyLTedf3KIRuD0hG6ldkFEZNCjRxiC+3i6kkWUUbiJQayP28iwG35cEmAbe98585BYV0A== +postcss@8.4.13: + version "8.4.13" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.13.tgz#7c87bc268e79f7f86524235821dfdf9f73e5d575" + integrity sha512-jtL6eTBrza5MPzy8oJLFuUscHDXTV5KcLlqAWHl5q5WYRfnNRGSmOZmOZ1T6Gy7A99mOZfqungmZMpMmCVJ8ZA== dependencies: - colorette "^1.2.2" - nanoid "^3.1.23" - source-map-js "^0.6.2" + nanoid "^3.3.3" + picocolors "^1.0.0" + source-map-js "^1.0.2" -postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.32, postcss@^7.0.35, postcss@^7.0.5, postcss@^7.0.6: +postcss@^7.0.14, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.36, postcss@^7.0.5, postcss@^7.0.6: version "7.0.39" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== @@ -6788,37 +13042,106 @@ postcss@^7.0.14, postcss@^7.0.17, postcss@^7.0.2, postcss@^7.0.32, postcss@^7.0. picocolors "^0.2.1" source-map "^0.6.1" -postcss@^8.2.15, postcss@^8.3.5: - version "8.3.9" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.3.9.tgz#98754caa06c4ee9eb59cc48bd073bb6bd3437c31" - integrity sha512-f/ZFyAKh9Dnqytx5X62jgjhhzttjZS7hMsohcI7HEI5tjELX/HxCy3EFhsRxyzGvrzFF+82XPvCS8T9TFleVJw== +postcss@^8.2.14, postcss@^8.3.7: + version "8.4.6" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.6.tgz#c5ff3c3c457a23864f32cb45ac9b741498a09ae1" + integrity sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA== dependencies: - nanoid "^3.1.28" - picocolors "^0.2.1" - source-map-js "^0.6.2" + nanoid "^3.2.0" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +postcss@^8.2.15, postcss@^8.4.7: + version "8.4.14" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.14.tgz#ee9274d5622b4858c1007a74d76e42e56fd21caf" + integrity sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig== + dependencies: + nanoid "^3.3.4" + picocolors "^1.0.0" + source-map-js "^1.0.2" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== + +"prettier@>=2.2.1 <=2.3.0": + version "2.3.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.3.0.tgz#b6a5bf1284026ae640f17f7ff5658a7567fc0d18" + integrity sha512-kXtO4s0Lz/DW/IJ9QdWhAf7/NmPWQXkFr/r/WkR3vyI+0v8amTDxiaQSLzs8NBlytfLWX/7uQUMIW677yLKl4w== pretty-bytes@^5.3.0: version "5.6.0" resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-5.6.0.tgz#356256f643804773c82f64723fe78c92c62beaeb" integrity sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg== -primeicons@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/primeicons/-/primeicons-4.1.0.tgz#19eaef8ef5594b0006358ae64e738d03e167c9bb" - integrity sha512-uEv2pSPk1zQCfaB2VgnUfnUxxlGryYi+5rbdxmZBBt5v9S/pscIQYS5YDLxsQZ7D9jn5c76+Tx5wX/2J1nK6sA== - -primeng@^12.2.0: - version "12.2.0" - resolved "https://registry.yarnpkg.com/primeng/-/primeng-12.2.0.tgz#f42fd389722959319dc225ff7a08386bf828eef4" - integrity sha512-EKU6VRDPbE9VzPzP/XbSTT2oEBV/RVbREzgXENUIIYdEmaPpRao/j6MDnX6niKKBe7VWA50hf18djhSQgAsCOg== +pretty-error@^2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-2.1.2.tgz#be89f82d81b1c86ec8fdfbc385045882727f93b6" + integrity sha512-EY5oDzmsX5wvuynAByrmY0P0hcp+QpnAKbJng2A2MPjVKXCxrDSUkzghVJ4ZGPIv+JC4gX8fPUWscC0RtjsWGw== dependencies: - tslib "^2.1.0" + lodash "^4.17.20" + renderkid "^2.0.4" + +pretty-error@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/pretty-error/-/pretty-error-4.0.0.tgz#90a703f46dd7234adb46d0f84823e9d1cb8f10d6" + integrity sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw== + dependencies: + lodash "^4.17.20" + renderkid "^3.0.0" + +pretty-format@^27.0.2: + version "27.5.1" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-27.5.1.tgz#2181879fdea51a7a5851fb39d920faa63f01d88e" + integrity sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ== + dependencies: + ansi-regex "^5.0.1" + ansi-styles "^5.0.0" + react-is "^17.0.1" + +pretty-hrtime@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" + integrity sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A== + +primeicons@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/primeicons/-/primeicons-5.0.0.tgz#73a0b6028a77c58a9eeb331ad13aaf085e8451ee" + integrity sha512-heygWF0X5HFI1otlZE62pp6ye7sZ8om78J9au2BRkg8O7Y8AHTZ9qKMRzchZUHLe8zUAvdi6hZzzm9XxgwIExw== + +primeng@^13.2.0: + version "13.2.0" + resolved "https://registry.yarnpkg.com/primeng/-/primeng-13.2.0.tgz#cbcc7fbc55b1479435e978c5156228e6e853c278" + integrity sha512-6rnjfXu91B1bVAFoJdbGTD7e3EXeTabPLvAJlVOg7/YFPbvzvOKjdFKa+8zomSun7TJgDLJTEa1ijgjc9b+uiA== + dependencies: + tslib "^2.3.0" + +prismjs@^1.27.0: + version "1.28.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.28.0.tgz#0d8f561fa0f7cf6ebca901747828b149147044b6" + integrity sha512-8aaXdYvl1F7iC7Xm1spqSaY/OJBpYW3v+KJ+F17iYxvdc8sfjW194COK5wVhMZX45tGteiBQgdvD/nhxcRwylw== + +prismjs@~1.27.0: + version "1.27.0" + resolved "https://registry.yarnpkg.com/prismjs/-/prismjs-1.27.0.tgz#bb6ee3138a0b438a3653dd4d6ce0cc6510a45057" + integrity sha512-t13BGPUlFDR7wRB5kQDG4jjl7XeuH6jbJGt11JHPL96qwsEHNX2+68tFXqc1/k+/jALsbSWJKUOT/hcYAZ5LkA== + +proc-log@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/proc-log/-/proc-log-2.0.1.tgz#8f3f69a1f608de27878f91f5c688b225391cb685" + integrity sha512-Kcmo2FhfDTXdcbfDH76N7uBYHINxc/8GW7UAVuVP9I+Va3uHSerrnKV6dLooga/gh7GlgzuCCr/eoldnL1muGw== 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" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" @@ -6832,6 +13155,51 @@ promise-retry@^2.0.1: err-code "^2.0.2" retry "^0.12.0" +promise.allsettled@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/promise.allsettled/-/promise.allsettled-1.0.5.tgz#2443f3d4b2aa8dfa560f6ac2aa6c4ea999d75f53" + integrity sha512-tVDqeZPoBC0SlzJHzWGZ2NKAguVq2oiYj7gbggbiTvH2itHohijTp7njOUA0aQ/nl+0lr/r6egmhoYu63UZ/pQ== + dependencies: + array.prototype.map "^1.0.4" + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + get-intrinsic "^1.1.1" + iterate-value "^1.0.2" + +promise.prototype.finally@^3.1.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.3.tgz#d3186e58fcf4df1682a150f934ccc27b7893389c" + integrity sha512-EXRF3fC9/0gz4qkt/f5EP5iW4kj9oFpBICNpCNOb/52+8nlHIX07FPLbi/q4qYBQ1xZqivMzTpNQSnArVASolQ== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +prompts@^2.4.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + +prop-types@^15.0.0, prop-types@^15.6.2, prop-types@^15.7.2: + version "15.8.1" + resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5" + integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg== + dependencies: + loose-envify "^1.4.0" + object-assign "^4.1.1" + react-is "^16.13.1" + +property-information@^5.0.0, property-information@^5.3.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69" + integrity sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA== + dependencies: + xtend "^4.0.0" + protractor@~5.4.0: version "5.4.4" resolved "https://registry.yarnpkg.com/protractor/-/protractor-5.4.4.tgz#b241466aaf83b76bc2c58df67deb9a5cdfc61529" @@ -6853,7 +13221,7 @@ protractor@~5.4.0: webdriver-manager "^12.0.6" yargs "^12.0.5" -proxy-addr@~2.0.5: +proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.7.tgz#f19fe69ceab311eeb94b42e70e8c2070f9ba1025" integrity sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg== @@ -6861,6 +13229,11 @@ proxy-addr@~2.0.5: forwarded "0.2.0" ipaddr.js "1.9.1" +proxy-middleware@latest: + version "0.15.0" + resolved "https://registry.yarnpkg.com/proxy-middleware/-/proxy-middleware-0.15.0.tgz#a3fdf1befb730f951965872ac2f6074c61477a56" + integrity sha512-EGCG8SeoIRVMhsqHQUdDigB2i7qU7fCsWASwn54+nPutYO8n4q6EiwMzyfWlC+dzRFExP+kvcnDFdBDHoZBU7Q== + prr@~1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" @@ -6871,6 +13244,31 @@ psl@^1.1.28: resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ== +psl@^1.1.33: + version "1.9.0" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" + integrity sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag== + +public-encrypt@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.3.tgz#4fcc9d77a07e48ba7527e7cbe0de33d0701331e0" + integrity sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q== + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + safe-buffer "^5.1.2" + +pump@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + integrity sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA== + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + pump@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64" @@ -6879,10 +13277,24 @@ pump@^3.0.0: end-of-stream "^1.1.0" once "^1.3.1" +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + integrity sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ== + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + punycode@1.3.2: version "1.3.2" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" - integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0= + integrity sha512-RofWgt/7fL5wP1Y7fxE7/EmTLzQVnB0ycyibJ0OOHIlJqTNzglYFxVwETOcIoJqJmpDXJ9xImDv+Fq34F/d4Dw== + +punycode@^1.2.4: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + integrity sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ== punycode@^2.1.0, punycode@^2.1.1: version "2.1.1" @@ -6899,20 +13311,19 @@ q@^1.4.1: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= -qrcode@1.4.2: - version "1.4.2" - resolved "https://registry.yarnpkg.com/qrcode/-/qrcode-1.4.2.tgz#e7c82a60140916d666541043bd2b0b72ee4e38a6" - integrity sha512-eR6RgxFYPDFH+zFLTJKtoNP/RlsHANQb52AUmQ2bGDPMuUw7jJb0F+DNEgx7qQGIElrbFxWYMc0/B91zLZPF9Q== +qs@6.10.3: + version "6.10.3" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.10.3.tgz#d6cde1b2ffca87b5aa57889816c5f81535e22e8e" + integrity sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ== dependencies: - dijkstrajs "^1.0.1" - isarray "^2.0.1" - pngjs "^3.3.0" - yargs "^13.2.4" + side-channel "^1.0.4" -qs@6.7.0: - version "6.7.0" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" - integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== +qs@^6.10.0: + version "6.11.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.0.tgz#fd0d963446f7a65e1367e01abd85429453f0c37a" + integrity sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q== + dependencies: + side-channel "^1.0.4" qs@^6.5.1: version "6.10.1" @@ -6926,10 +13337,20 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + integrity sha512-773xhDQnZBMFobEiztv8LIl70ch5MSF/jUQVlhwFyBILqq96anmoctVIYz+ZRp0qbCKATTn6ev02M3r7Ga5vqA== + querystring@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" - integrity sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA= + integrity sha512-X/xY82scca2tau62i9mDyU9K+I+djTMUsvwf7xnUX5GLvVzgJybOJf4Y6o9Zx3oJK/LSXg5tTZBjwzqVPaPO2g== + +querystring@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.1.tgz#40d77615bb09d16902a85c3e38aa8b5ed761c2dd" + integrity sha512-wkvS7mL/JMugcup3/rMitHmd9ecIGd2lhFhK9N3UUQ450h66d1r3Y9nvXzQAW1Lq+wyx61k/1pfKS5KuKiyEbg== querystringify@^2.1.1: version "2.2.0" @@ -6941,28 +13362,112 @@ queue-microtask@^1.2.2: resolved "https://registry.yarnpkg.com/queue-microtask/-/queue-microtask-1.2.3.tgz#4929228bbc724dfac43e0efb058caf7b6cfb6243" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== -randombytes@^2.1.0: +quote-stream@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/quote-stream/-/quote-stream-1.0.2.tgz#84963f8c9c26b942e153feeb53aae74652b7e0b2" + integrity sha512-kKr2uQ2AokadPjvTyKJQad9xELbZwYzWlNfI3Uz2j/ib5u6H9lDP7fUUR//rMycd0gv4Z5P1qXMfXR8YpIxrjQ== + dependencies: + buffer-equal "0.0.1" + minimist "^1.1.3" + through2 "^2.0.0" + +ramda@^0.28.0: + version "0.28.0" + resolved "https://registry.yarnpkg.com/ramda/-/ramda-0.28.0.tgz#acd785690100337e8b063cab3470019be427cc97" + integrity sha512-9QnLuG/kPVgWvMQ4aODhsBUFKOUmnbUnsSXACv+NCQZcHbeb+v8Lodp8OVxtRULN1/xOyYLLaL6npE6dMq5QTA== + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" integrity sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ== dependencies: safe-buffer "^5.1.0" +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + integrity sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw== + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + range-parser@^1.2.1, range-parser@~1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.1.tgz#3cf37023d199e1c24d1a55b84800c2f3e6468031" integrity sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg== -raw-body@2.4.0: - version "2.4.0" - resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.4.0.tgz#a1ce6fb9c9bc356ca52e89256ab59059e13d0332" - integrity sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q== +raw-body@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/raw-body/-/raw-body-2.5.1.tgz#fe1b1628b181b700215e5fd42389f98b71392857" + integrity sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig== dependencies: - bytes "3.1.0" - http-errors "1.7.2" + bytes "3.1.2" + http-errors "2.0.0" iconv-lite "0.4.24" unpipe "1.0.0" +raw-loader@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6" + integrity sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +react-dom@^16.14.0: + version "16.14.0" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.14.0.tgz#7ad838ec29a777fb3c75c3a190f661cf92ab8b89" + integrity sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + scheduler "^0.19.1" + +react-inspector@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-5.1.1.tgz#58476c78fde05d5055646ed8ec02030af42953c8" + integrity sha512-GURDaYzoLbW8pMGXwYPDBIv6nqei4kK7LPRZ9q9HCZF54wqXz/dnylBp/kfE9XmekBhHvLDdcYeyIwSrvtOiWg== + dependencies: + "@babel/runtime" "^7.0.0" + is-dom "^1.0.0" + prop-types "^15.0.0" + +react-is@^16.13.1: + version "16.13.1" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" + integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ== + +react-is@^17.0.1: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + +react-merge-refs@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/react-merge-refs/-/react-merge-refs-1.1.0.tgz#73d88b892c6c68cbb7a66e0800faa374f4c38b06" + integrity sha512-alTKsjEL0dKH/ru1Iyn7vliS2QRcBp9zZPGoWxUOvRGWPUYgjo+V01is7p04It6KhgrzhJGnIj9GgX8W4bZoCQ== + +react-syntax-highlighter@^15.4.5: + version "15.5.0" + resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-15.5.0.tgz#4b3eccc2325fa2ec8eff1e2d6c18fa4a9e07ab20" + integrity sha512-+zq2myprEnQmH5yw6Gqc8lD55QHnpKaU8TOcFeC/Lg/MQSs8UknEA0JC4nTZGFAXC2J2Hyj/ijJ7NlabyPi2gg== + dependencies: + "@babel/runtime" "^7.3.1" + highlight.js "^10.4.1" + lowlight "^1.17.0" + prismjs "^1.27.0" + refractor "^3.6.0" + +react@^16.14.0: + version "16.14.0" + resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d" + integrity sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + prop-types "^15.6.2" + read-cache@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/read-cache/-/read-cache-1.0.0.tgz#e664ef31161166c9751cdbe8dbcf86b5fb58f774" @@ -6970,7 +13475,7 @@ read-cache@^1.0.0: dependencies: pify "^2.3.0" -read-package-json-fast@^2.0.1: +read-package-json-fast@^2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/read-package-json-fast/-/read-package-json-fast-2.0.3.tgz#323ca529630da82cb34b36cc0b996693c98c2b83" integrity sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ== @@ -6978,7 +13483,53 @@ read-package-json-fast@^2.0.1: json-parse-even-better-errors "^2.3.0" npm-normalize-package-bin "^1.0.1" -readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable-stream@^2.3.5, readable-stream@~2.3.6: +read-package-json@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/read-package-json/-/read-package-json-5.0.1.tgz#1ed685d95ce258954596b13e2e0e76c7d0ab4c26" + integrity sha512-MALHuNgYWdGW3gKzuNMuYtcSSZbGQm94fAp16xt8VsYTLBjUSc55bLMKe6gzpWue0Tfi6CBgwCSdDAqutGDhMg== + dependencies: + glob "^8.0.1" + json-parse-even-better-errors "^2.3.1" + normalize-package-data "^4.0.0" + npm-normalize-package-bin "^1.0.1" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + integrity sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A== + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^7.0.1: + version "7.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-7.0.1.tgz#f3a6135758459733ae2b95638056e1854e7ef507" + integrity sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg== + dependencies: + find-up "^4.1.0" + read-pkg "^5.2.0" + type-fest "^0.8.1" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + integrity sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ== + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-5.2.0.tgz#7bf295438ca5a33e56cd30e053b34ee7250c93cc" + integrity sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg== + dependencies: + "@types/normalize-package-data" "^2.4.0" + normalize-package-data "^2.5.0" + parse-json "^5.0.0" + type-fest "^0.6.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@~2.3.3, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -6991,7 +13542,7 @@ readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.6, readable string_decoder "~1.1.1" util-deprecate "~1.0.1" -readable-stream@^3.0.6, readable-stream@^3.4.0: +readable-stream@^3.0.6, readable-stream@^3.4.0, readable-stream@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198" integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA== @@ -7016,11 +13567,35 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +redent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-1.0.0.tgz#cf916ab1fd5f1f16dfb20822dd6ec7f730c2afde" + integrity sha512-qtW5hKzGQZqKoh6JNSD+4lfitfPKGz42e6QwiRmPM5mmKtR0N41AbJRYu0xJi7nhOJ4WDgRkKvAk6tw4WIwR4g== + dependencies: + indent-string "^2.1.0" + strip-indent "^1.0.1" + reflect-metadata@^0.1.2: version "0.1.13" resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== +refractor@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/refractor/-/refractor-3.6.0.tgz#ac318f5a0715ead790fcfb0c71f4dd83d977935a" + integrity sha512-MY9W41IOWxxk31o+YvFCNyNzdkc9M20NoZK5vq6jkv4I/uh2zkWcfudj0Q1fovjUQJrNewS9NMzeTtqPf+n5EA== + dependencies: + hastscript "^6.0.0" + parse-entities "^2.0.0" + prismjs "~1.27.0" + +regenerate-unicode-properties@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" + integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties@^9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz#54d09c7115e1f53dc2314a974b32c1c344efe326" @@ -7033,15 +13608,15 @@ regenerate@^1.4.2: resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.2.tgz#b9346d8827e8f5a32f7ba29637d398b69014848a" integrity sha512-zrceR/XhGYU/d/opr2EKO7aRHUeiBI8qjtfHqADTwZd6Szfy16la6kqD0MIUs5z5hx6AaKa+PixpPrR289+I0A== -regenerator-runtime@0.13.9, regenerator-runtime@^0.13.4: +regenerator-runtime@0.13.9, regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7: version "0.13.9" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52" integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA== -regenerator-transform@^0.14.2: - version "0.14.5" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" - integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== +regenerator-transform@^0.15.0: + version "0.15.0" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.15.0.tgz#cbd9ead5d77fae1a48d957cf889ad0586adb6537" + integrity sha512-LsrGtPmbYg19bcPHwdtmXwbW+TqNvtY4riE3P83foeHRroMbH6/2ddFBfab3t7kbzc7v7p4wbkIecHImqt0QNg== dependencies: "@babel/runtime" "^7.8.4" @@ -7058,13 +13633,14 @@ regex-parser@^2.2.11: resolved "https://registry.yarnpkg.com/regex-parser/-/regex-parser-2.2.11.tgz#3b37ec9049e19479806e878cabe7c1ca83ccfe58" integrity sha512-jbD/FT0+9MBU2XAZluI7w2OBs1RBi6p9M83nkoZayQXXU9e8Robt69FcZc7wU4eJD/YFTjn1JdCk3rbMJajz8Q== -regexp.prototype.flags@^1.2.0: - version "1.3.1" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.3.1.tgz#7ef352ae8d159e758c0eadca6f8fcb4eef07be26" - integrity sha512-JiBdRBq91WlY7uRJ0ds7R+dU02i6LKi8r3BuQhNXn+kmeLN+EfHhfjqMRis1zJxnlu88hq/4dx0P2OP3APRTOA== +regexp.prototype.flags@^1.2.0, regexp.prototype.flags@^1.4.1, regexp.prototype.flags@^1.4.3: + version "1.4.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz#87cab30f80f66660181a3bb7bf5981a872b367ac" + integrity sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA== dependencies: call-bind "^1.0.2" define-properties "^1.1.3" + functions-have-names "^1.2.2" regexpu-core@^4.7.1: version "4.8.0" @@ -7078,11 +13654,40 @@ regexpu-core@^4.7.1: unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.0.0" +regexpu-core@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.0.1.tgz#c531122a7840de743dcf9c83e923b5560323ced3" + integrity sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^10.0.1" + regjsgen "^0.6.0" + regjsparser "^0.8.2" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" + +regexpu-core@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.1.0.tgz#2f8504c3fd0ebe11215783a41541e21c79942c6d" + integrity sha512-bb6hk+xWd2PEOkj5It46A16zFMs2mv86Iwpdu94la4S3sJ7C973h2dHpYKwIBGaWSO7cIRJ+UX0IeMaWcO4qwA== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^10.0.1" + regjsgen "^0.6.0" + regjsparser "^0.8.2" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.0.0" + regjsgen@^0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== +regjsgen@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" + integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== + regjsparser@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.7.0.tgz#a6b667b54c885e18b52554cb4960ef71187e9968" @@ -7090,22 +13695,131 @@ regjsparser@^0.7.0: dependencies: jsesc "~0.5.0" +regjsparser@^0.8.2: + version "0.8.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" + integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA== + dependencies: + jsesc "~0.5.0" + +relateurl@^0.2.7: + version "0.2.7" + resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" + integrity sha512-G08Dxvm4iDN3MLM0EsP62EDV9IuhXPR6blNz6Utcp7zyV3tr4HVNINt6MpaRWbxoOHT3Q7YN2P+jaHX8vUbgog== + +remark-external-links@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/remark-external-links/-/remark-external-links-8.0.0.tgz#308de69482958b5d1cd3692bc9b725ce0240f345" + integrity sha512-5vPSX0kHoSsqtdftSHhIYofVINC8qmp0nctkeU9YoJwV3YfiBRiI6cbFRJ0oI/1F9xS+bopXG0m2KS8VFscuKA== + dependencies: + extend "^3.0.0" + is-absolute-url "^3.0.0" + mdast-util-definitions "^4.0.0" + space-separated-tokens "^1.0.0" + unist-util-visit "^2.0.0" + +remark-footnotes@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/remark-footnotes/-/remark-footnotes-2.0.0.tgz#9001c4c2ffebba55695d2dd80ffb8b82f7e6303f" + integrity sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ== + +remark-mdx@1.6.22: + version "1.6.22" + resolved "https://registry.yarnpkg.com/remark-mdx/-/remark-mdx-1.6.22.tgz#06a8dab07dcfdd57f3373af7f86bd0e992108bbd" + integrity sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ== + dependencies: + "@babel/core" "7.12.9" + "@babel/helper-plugin-utils" "7.10.4" + "@babel/plugin-proposal-object-rest-spread" "7.12.1" + "@babel/plugin-syntax-jsx" "7.12.1" + "@mdx-js/util" "1.6.22" + is-alphabetical "1.0.4" + remark-parse "8.0.3" + unified "9.2.0" + +remark-parse@8.0.3: + version "8.0.3" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-8.0.3.tgz#9c62aa3b35b79a486454c690472906075f40c7e1" + integrity sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q== + dependencies: + ccount "^1.0.0" + collapse-white-space "^1.0.2" + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + is-whitespace-character "^1.0.0" + is-word-character "^1.0.0" + markdown-escapes "^1.0.0" + parse-entities "^2.0.0" + repeat-string "^1.5.4" + state-toggle "^1.0.0" + trim "0.0.1" + trim-trailing-lines "^1.0.0" + unherit "^1.0.4" + unist-util-remove-position "^2.0.0" + vfile-location "^3.0.0" + xtend "^4.0.1" + +remark-slug@^6.0.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/remark-slug/-/remark-slug-6.1.0.tgz#0503268d5f0c4ecb1f33315c00465ccdd97923ce" + integrity sha512-oGCxDF9deA8phWvxFuyr3oSJsdyUAxMFbA0mZ7Y1Sas+emILtO+e5WutF9564gDsEN4IXaQXm5pFo6MLH+YmwQ== + dependencies: + github-slugger "^1.0.0" + mdast-util-to-string "^1.0.0" + unist-util-visit "^2.0.0" + +remark-squeeze-paragraphs@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz#76eb0e085295131c84748c8e43810159c5653ead" + integrity sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw== + dependencies: + mdast-squeeze-paragraphs "^4.0.0" + remove-trailing-separator@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" - integrity sha1-wkvOKig62tW8P1jg1IJJuSN52O8= + integrity sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw== + +renderkid@^2.0.4: + version "2.0.7" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-2.0.7.tgz#464f276a6bdcee606f4a15993f9b29fc74ca8609" + integrity sha512-oCcFyxaMrKsKcTY59qnCAtmDVSLfPbrv6A3tVbPdFMMrv5jaK10V6m40cKsoPNhAqN6rmHW9sswW4o3ruSrwUQ== + dependencies: + css-select "^4.1.3" + dom-converter "^0.2.0" + htmlparser2 "^6.1.0" + lodash "^4.17.21" + strip-ansi "^3.0.1" + +renderkid@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/renderkid/-/renderkid-3.0.0.tgz#5fd823e4d6951d37358ecc9a58b1f06836b6268a" + integrity sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg== + dependencies: + css-select "^4.1.3" + dom-converter "^0.2.0" + htmlparser2 "^6.1.0" + lodash "^4.17.21" + strip-ansi "^6.0.1" repeat-element@^1.1.2: version "1.1.4" resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.4.tgz#be681520847ab58c7568ac75fbfad28ed42d39e9" integrity sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ== -repeat-string@^1.6.1: +repeat-string@^1.5.4, repeat-string@^1.6.1: version "1.6.1" resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" - integrity sha1-jcrkcOHIirwtYA//Sndihtp15jc= + integrity sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w== -request@^2.87.0, request@^2.88.0, request@^2.88.2: +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + integrity sha512-ZqtSMuVybkISo2OWvqvm7iHSWngvdaW3IpsT9/uP8v4gMi591LY6h35wdOfvQdWCKFWZWm2Y1Opp4kV7vQKT6A== + dependencies: + is-finite "^1.0.0" + +request@^2.87.0: version "2.88.2" resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3" integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== @@ -7146,50 +13860,61 @@ require-main-filename@^1.0.1: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" integrity sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE= -require-main-filename@^2.0.0: - version "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.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" integrity sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8= -resolve-cwd@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" - integrity sha1-AKn3OHVW4nA46uIyyqNypqWbZlo= - dependencies: - resolve-from "^3.0.0" - -resolve-from@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" - integrity sha1-six699nWiBvItuZTM17rywoYh0g= - resolve-from@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6" integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g== -resolve-url-loader@4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-4.0.0.tgz#d50d4ddc746bb10468443167acf800dcd6c3ad57" - integrity sha512-05VEMczVREcbtT7Bz+C+96eUO5HDNvdthIiMB34t7FcF8ehcu4wC0sSgPUubs3XW2Q3CNLJk/BJrCU9wVRymiA== +resolve-from@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" + integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== + +resolve-url-loader@5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/resolve-url-loader/-/resolve-url-loader-5.0.0.tgz#ee3142fb1f1e0d9db9524d539cfa166e9314f795" + integrity sha512-uZtduh8/8srhBoMx//5bwqjQ+rfYOUq8zC9NrMUGtjBiGTtFJM42s58/36+hTqeqINcnYe08Nj3LkK9lW4N8Xg== dependencies: adjust-sourcemap-loader "^4.0.0" convert-source-map "^1.7.0" loader-utils "^2.0.0" - postcss "^7.0.35" + postcss "^8.2.14" source-map "0.6.1" resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" - integrity sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo= + integrity sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg== -resolve@1.20.0, resolve@^1.1.7, resolve@^1.14.2, resolve@^1.3.2: +resolve@1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + integrity sha512-9znBF0vBcaSN3W2j7wKvdERPwqTxSpCq+if5C0WoTCyV9n24rua28jeuQ2pL/HOf+yUe/Mef+H/5p60K0Id3bg== + +resolve@1.22.0: + version "1.22.0" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.0.tgz#5e0b8c67c15df57a89bdbabe603a002f21731198" + integrity sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw== + dependencies: + is-core-module "^2.8.1" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve@^1.1.5, resolve@^1.10.0, resolve@^1.19.0: + version "1.22.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" + integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== + dependencies: + is-core-module "^2.9.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +resolve@^1.1.7, resolve@^1.14.2, resolve@^1.3.2: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -7215,6 +13940,11 @@ retry@^0.12.0: resolved "https://registry.yarnpkg.com/retry/-/retry-0.12.0.tgz#1b42a6266a21f07421d1b0b54b7dc167b01c013b" integrity sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs= +retry@^0.13.1: + version "0.13.1" + resolved "https://registry.yarnpkg.com/retry/-/retry-0.13.1.tgz#185b1587acf67919d63b357349e03537b2484658" + integrity sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg== + reusify@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/reusify/-/reusify-1.0.4.tgz#90da382b1e126efc02146e90845a88db12925d76" @@ -7234,6 +13964,14 @@ rimraf@^3.0.2: dependencies: glob "^7.1.3" +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + integrity sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA== + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + rrule@^2.6.0: version "2.6.8" resolved "https://registry.yarnpkg.com/rrule/-/rrule-2.6.8.tgz#c61714f246e7676e8efa16c2baabac199f20f6db" @@ -7243,6 +13981,11 @@ rrule@^2.6.0: optionalDependencies: luxon "^1.21.3" +rsvp@^4.8.4: + version "4.8.5" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-4.8.5.tgz#c8f155311d167f68f21e168df71ec5b083113734" + integrity sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA== + run-async@^2.4.0: version "2.4.1" resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455" @@ -7255,6 +13998,13 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + integrity sha512-ntymy489o0/QQplUDnpYAYUsO50K9SBrIVaKCWDOJzYJts0f9WH9RFJkyagebkw5+y1oi00R7ynNW/d12GBumg== + dependencies: + aproba "^1.1.1" + rxjs@6.6.7, rxjs@^6.5.3: version "6.6.7" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.6.7.tgz#90ac018acabf491bf65044235d5863c4dab804c9" @@ -7262,19 +14012,31 @@ rxjs@6.6.7, rxjs@^6.5.3: dependencies: tslib "^1.9.0" -rxjs@^7.2.0, rxjs@^7.4.0: - version "7.4.0" - resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.4.0.tgz#a12a44d7eebf016f5ff2441b87f28c9a51cebc68" - integrity sha512-7SQDi7xeTMCJpqViXh8gL/lebcwlp3d831F05+9B44A4B0WfsEwUQHR64gsH1kvJ+Ep/J9K2+n1hVl1CsGN23w== +rxjs@^7.5.4: + version "7.5.4" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.4.tgz#3d6bd407e6b7ce9a123e76b1e770dc5761aa368d" + integrity sha512-h5M3Hk78r6wAheJF0a5YahB1yRQKCsZ4MsGdZ5O9ETbVtjPcScGfrMmoOq7EBsCRzd4BDkvDJ7ogP8Sz5tTFiQ== dependencies: - tslib "~2.1.0" + tslib "^2.1.0" + +rxjs@^7.5.5: + version "7.5.5" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.5.5.tgz#2ebad89af0f560f460ad5cc4213219e1f7dd4e9f" + integrity sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw== + dependencies: + tslib "^2.1.0" + +safe-buffer@5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" + integrity sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg== safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: version "5.1.2" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== -safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-buffer@~5.2.0: +safe-buffer@5.2.1, safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== @@ -7282,7 +14044,7 @@ safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.2, safe-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" - integrity sha1-QKNmnzsHfR6UPURinhV91IAjvy4= + integrity sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg== dependencies: ret "~0.1.10" @@ -7291,25 +14053,53 @@ safe-regex@^1.1.0: resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== -sass-loader@12.1.0: - version "12.1.0" - resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.1.0.tgz#b73324622231009da6fba61ab76013256380d201" - integrity sha512-FVJZ9kxVRYNZTIe2xhw93n3xJNYZADr+q69/s98l9nTCrWASo+DR2Ot0s5xTKQDDEosUkatsGeHxcH4QBp5bSg== +sane@^4.0.3: + version "4.1.0" + resolved "https://registry.yarnpkg.com/sane/-/sane-4.1.0.tgz#ed881fd922733a6c461bc189dc2b6c006f3ffded" + integrity sha512-hhbzAgTIX8O7SHfp2c8/kREfEn4qO/9q8C9beyY6+tvZ87EpoZ3i1RIEvp27YBswnNbY9mWd6paKVmKbAgLfZA== + dependencies: + "@cnakazawa/watch" "^1.0.3" + anymatch "^2.0.0" + capture-exit "^2.0.0" + exec-sh "^0.3.2" + execa "^1.0.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + +sass-loader@12.6.0: + version "12.6.0" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-12.6.0.tgz#5148362c8e2cdd4b950f3c63ac5d16dbfed37bcb" + integrity sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA== dependencies: klona "^2.0.4" neo-async "^2.6.2" +sass-loader@^10.1.0: + version "10.3.1" + resolved "https://registry.yarnpkg.com/sass-loader/-/sass-loader-10.3.1.tgz#a45f0d1dd7ea90de7eb099239a18c83dea6e6341" + integrity sha512-y2aBdtYkbqorVavkC3fcJIUDGIegzDWPn3/LAFhsf3G+MzPKTJx37sROf5pXtUeggSVbNbmfj8TgRaSLMelXRA== + dependencies: + klona "^2.0.4" + loader-utils "^2.0.0" + neo-async "^2.6.2" + schema-utils "^3.0.0" + semver "^7.3.2" + sass-recursive-map-merge@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/sass-recursive-map-merge/-/sass-recursive-map-merge-1.0.1.tgz#d5460b9fe10df62d246ca27c48d823f25c2290cb" integrity sha512-OuDTGVGx2o2sPeaSgGob5s2Qf6LxoMU4LG7n6vCzNgfXyBz/y8tKzcEYdmvgyhjvGQVcGA1g2UJnP7WMmahuVg== -sass@1.36.0: - version "1.36.0" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.36.0.tgz#5912ef9d5d16714171ba11cb17edb274c4bbc07e" - integrity sha512-fQzEjipfOv5kh930nu3Imzq3ie/sGDc/4KtQMJlt7RRdrkQSfe37Bwi/Rf/gfuYHsIuE1fIlDMvpyMcEwjnPvg== +sass@1.51.0: + version "1.51.0" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.51.0.tgz#25ea36cf819581fe1fe8329e8c3a4eaaf70d2845" + integrity sha512-haGdpTgywJTvHC2b91GSq+clTKGbtkkZmVAb82jZQN/wTy6qs8DdFm2lhEQbEwrY0QDRgSQ3xDurqM977C3noA== dependencies: chokidar ">=3.0.0 <4.0.0" + immutable "^4.0.0" + source-map-js ">=0.6.2 <2.0.0" saucelabs@^1.5.0: version "1.5.0" @@ -7323,6 +14113,23 @@ sax@>=0.6.0, sax@^1.2.4, sax@~1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== +scheduler@^0.19.1: + version "0.19.1" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.19.1.tgz#4f3e2ed2c1a7d65681f4c854fa8c5a1ccb40f196" + integrity sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA== + dependencies: + loose-envify "^1.1.0" + object-assign "^4.1.1" + +schema-utils@2.7.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" + integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== + dependencies: + "@types/json-schema" "^7.0.4" + ajv "^6.12.2" + ajv-keywords "^3.4.1" + schema-utils@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770" @@ -7350,6 +14157,29 @@ schema-utils@^3.0.0, schema-utils@^3.1.0, schema-utils@^3.1.1: ajv "^6.12.5" ajv-keywords "^3.5.2" +schema-utils@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.0.0.tgz#60331e9e3ae78ec5d16353c467c34b3a0a1d3df7" + integrity sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg== + dependencies: + "@types/json-schema" "^7.0.9" + ajv "^8.8.0" + ajv-formats "^2.1.1" + ajv-keywords "^5.0.0" + +scope-analyzer@^2.0.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/scope-analyzer/-/scope-analyzer-2.1.2.tgz#b958162feb59823c2835c7b0229187a97c77e9cd" + integrity sha512-5cfCmsTYV/wPaRIItNxatw02ua/MThdIUNnUOCYp+3LSEJvnG804ANw2VLaavNILIfWXF1D1G2KNANkBBvInwQ== + dependencies: + array-from "^2.1.1" + dash-ast "^2.0.1" + es6-map "^0.1.5" + es6-set "^0.1.5" + es6-symbol "^3.1.1" + estree-is-function "^1.0.0" + get-assigned-identifiers "^1.1.0" + select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -7365,12 +14195,12 @@ selenium-webdriver@3.6.0, selenium-webdriver@^3.0.1: tmp "0.0.30" xml2js "^0.4.17" -selfsigned@^1.10.8: - version "1.10.11" - resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-1.10.11.tgz#24929cd906fe0f44b6d01fb23999a739537acbe9" - integrity sha512-aVmbPOfViZqOZPgRBT0+3u4yZFHpmnIghLMlAcb5/xhp5ZtB/RVnKhz5vl2M32CLXAqR4kha9zfhNg0Lf/sxKA== +selfsigned@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/selfsigned/-/selfsigned-2.0.1.tgz#8b2df7fa56bf014d19b6007655fff209c0ef0a56" + integrity sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ== dependencies: - node-forge "^0.10.0" + node-forge "^1" semver-dsl@^1.0.1: version "1.0.1" @@ -7379,46 +14209,67 @@ semver-dsl@^1.0.1: dependencies: semver "^5.3.0" +"semver@2 || 3 || 4 || 5", semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: + version "5.7.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" + integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== + semver@7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== -semver@7.3.5, semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== +semver@7.3.7, semver@^7.3.2, semver@^7.3.4: + version "7.3.7" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.7.tgz#12c5b649afdbf9049707796e22a4028814ce523f" + integrity sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g== dependencies: lru-cache "^6.0.0" -semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0: - version "5.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7" - integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ== - semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -send@0.17.1: - version "0.17.1" - resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8" - integrity sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg== +semver@^7.0.0, semver@^7.1.1, semver@^7.3.5: + version "7.3.5" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" + integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== + dependencies: + lru-cache "^6.0.0" + +send@0.18.0, send@latest: + version "0.18.0" + resolved "https://registry.yarnpkg.com/send/-/send-0.18.0.tgz#670167cc654b05f5aa4a767f9113bb371bc706be" + integrity sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg== dependencies: debug "2.6.9" - depd "~1.1.2" - destroy "~1.0.4" + depd "2.0.0" + destroy "1.2.0" encodeurl "~1.0.2" escape-html "~1.0.3" etag "~1.8.1" fresh "0.5.2" - http-errors "~1.7.2" + http-errors "2.0.0" mime "1.6.0" - ms "2.1.1" - on-finished "~2.3.0" + ms "2.1.3" + on-finished "2.4.1" range-parser "~1.2.1" - statuses "~1.5.0" + statuses "2.0.1" + +serialize-javascript@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" + integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== + dependencies: + randombytes "^2.1.0" + +serialize-javascript@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-5.0.1.tgz#7886ec848049a462467a97d3d918ebb2aaf934f4" + integrity sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA== + dependencies: + randombytes "^2.1.0" serialize-javascript@^6.0.0: version "6.0.0" @@ -7427,6 +14278,17 @@ serialize-javascript@^6.0.0: dependencies: randombytes "^2.1.0" +serve-favicon@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.5.0.tgz#935d240cdfe0f5805307fdfe967d88942a2cbcf0" + integrity sha512-FMW2RvqNr03x+C0WxTyu6sOv21oOjkq5j8tjquWccwa6ScNyGFOGJVpuS1NmTVGBAHS07xnSKotgf2ehQmf9iA== + dependencies: + etag "~1.8.1" + fresh "0.5.2" + ms "2.1.1" + parseurl "~1.3.2" + safe-buffer "5.1.1" + serve-index@^1.9.1: version "1.9.1" resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.1.tgz#d3768d69b1e7d82e5ce050fff5b453bea12a9239" @@ -7440,17 +14302,17 @@ serve-index@^1.9.1: mime-types "~2.1.17" parseurl "~1.3.2" -serve-static@1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.14.1.tgz#666e636dc4f010f7ef29970a88a674320898b2f9" - integrity sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg== +serve-static@1.15.0: + version "1.15.0" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.15.0.tgz#faaef08cffe0a1a62f60cad0c4e513cff0ac9540" + integrity sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g== dependencies: encodeurl "~1.0.2" escape-html "~1.0.3" parseurl "~1.3.3" - send "0.17.1" + send "0.18.0" -set-blocking@^2.0.0, set-blocking@~2.0.0: +set-blocking@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" integrity sha1-BF+XgtARrppoA93TgrJDkrPYkPc= @@ -7470,15 +14332,28 @@ set-value@^2.0.0, set-value@^2.0.1: is-plain-object "^2.0.3" split-string "^3.0.1" +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + integrity sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA== + setprototypeof@1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.0.tgz#d0bd85536887b6fe7c0d818cb962d9d91c54e656" integrity sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ== -setprototypeof@1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.1.1.tgz#7e95acb24aa92f5885e0abef5ba131330d4ae683" - integrity sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw== +setprototypeof@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.2.0.tgz#66c9a24a73f9fc28cbe66b09fed3d33dcaf1b424" + integrity sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw== + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" shallow-clone@^3.0.0: version "3.0.1" @@ -7487,6 +14362,11 @@ shallow-clone@^3.0.0: dependencies: kind-of "^6.0.2" +shallow-copy@~0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/shallow-copy/-/shallow-copy-0.0.1.tgz#415f42702d73d810330292cc5ee86eae1a11a170" + integrity sha512-b6i4ZpVuUxB9h5gfCxPiusKYkqTMOjEbBs4wMaFbkfia4yFv92UKZ6Df8WXcKbn08JNL/abvg3FnMAOfakDvUw== + shebang-command@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" @@ -7494,11 +14374,23 @@ shebang-command@^1.2.0: dependencies: shebang-regex "^1.0.0" +shebang-command@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" + integrity sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA== + dependencies: + shebang-regex "^3.0.0" + shebang-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" integrity sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM= +shebang-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" + integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A== + side-channel@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/side-channel/-/side-channel-1.0.4.tgz#efce5c8fdc104ee751b25c58d4290011fa5ea2cf" @@ -7513,12 +14405,32 @@ signal-exit@^3.0.0, signal-exit@^3.0.2: resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.5.tgz#9e3e8cc0c75a99472b44321033a7702e7738252f" integrity sha512-KWcOiKeQj6ZyXx7zq4YxSMgHRlod4czeBQZrPb8OKcohcqAXShm7E20kEMle9WBt26hFcAf0qLOcp5zmY7kOqQ== +signal-exit@^3.0.3: + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== + +sisteransi@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-1.0.5.tgz#134d681297756437cc05ca01370d3a7a571075ed" + integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== + +slash@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-2.0.0.tgz#de552851a1759df3a8f206535442f5ec4ddeab44" + integrity sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A== + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== -smart-buffer@^4.1.0: +slash@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-4.0.0.tgz#2422372176c4c6c5addb5e2ada885af984b396a7" + integrity sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew== + +smart-buffer@^4.1.0, smart-buffer@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/smart-buffer/-/smart-buffer-4.2.0.tgz#6e1d71fa4f18c05f7d0ff216dd16a481d0e8d9ae" integrity sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg== @@ -7553,18 +14465,6 @@ snapdragon@^0.8.1: source-map-resolve "^0.5.0" use "^3.1.0" -sockjs-client@^1.5.0: - version "1.5.2" - resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.5.2.tgz#4bc48c2da9ce4769f19dc723396b50f5c12330a3" - integrity sha512-ZzRxPBISQE7RpzlH4tKJMQbHM9pabHluk0WBaxAQ+wm/UieeBVBou0p4wVnSQGN9QmpAZygQ0cDIypWuqOFmFQ== - dependencies: - debug "^3.2.6" - eventsource "^1.0.7" - faye-websocket "^0.11.3" - inherits "^2.0.4" - json3 "^3.3.3" - url-parse "^1.5.3" - sockjs@^0.3.21: version "0.3.21" resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.21.tgz#b34ffb98e796930b60a0cfa11904d6a339a7d417" @@ -7583,6 +14483,15 @@ socks-proxy-agent@^6.0.0: debug "^4.3.1" socks "^2.6.1" +socks-proxy-agent@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz#dc069ecf34436621acb41e3efa66ca1b5fed15b6" + integrity sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww== + dependencies: + agent-base "^6.0.2" + debug "^4.3.3" + socks "^2.6.2" + socks@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.1.tgz#989e6534a07cf337deb1b1c94aaa44296520d30e" @@ -7591,26 +14500,34 @@ socks@^2.6.1: ip "^1.1.5" smart-buffer "^4.1.0" +socks@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/socks/-/socks-2.6.2.tgz#ec042d7960073d40d94268ff3bb727dc685f111a" + integrity sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA== + dependencies: + ip "^1.1.5" + smart-buffer "^4.2.0" + source-list-map@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== -source-map-js@^0.6.2: - version "0.6.2" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-0.6.2.tgz#0bb5de631b41cfbda6cfba8bd05a80efdfd2385e" - integrity sha512-/3GptzWzu0+0MBQFrDKzw/DvvMTUORvgY6k6jd/VS6iCR4RDTKWH6v6WPwQoUO8667uQEf9Oe38DxAYWY5F/Ug== +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c" + integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw== -source-map-loader@3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.0.tgz#f2a04ee2808ad01c774dea6b7d2639839f3b3049" - integrity sha512-GKGWqWvYr04M7tn8dryIWvb0s8YM41z82iQv01yBtIylgxax0CwvSy6gc2Y02iuXwEfGWRlMicH0nvms9UZphw== +source-map-loader@3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/source-map-loader/-/source-map-loader-3.0.1.tgz#9ae5edc7c2d42570934be4c95d1ccc6352eba52d" + integrity sha512-Vp1UsfyPvgujKQzi4pyDiTOnE3E4H+yHvkVRN3c/9PJmQS4CQJExvcDvaX/D+RV+xQben9HJ56jMJS3CgUeWyA== dependencies: abab "^2.0.5" - iconv-lite "^0.6.2" - source-map-js "^0.6.2" + iconv-lite "^0.6.3" + source-map-js "^1.0.1" -source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: +source-map-resolve@^0.5.0: version "0.5.3" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.3.tgz#190866bece7553e1f8f267a2ee82c606b5509a1a" integrity sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw== @@ -7629,15 +14546,15 @@ source-map-resolve@^0.6.0: atob "^2.1.2" decode-uri-component "^0.2.0" -source-map-support@0.5.19: - version "0.5.19" - resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.19.tgz#a98b62f86dcaf4f67399648c085291ab9e8fed61" - integrity sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw== +source-map-support@0.5.21, source-map-support@^0.5.16, source-map-support@~0.5.12: + version "0.5.21" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f" + integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w== dependencies: buffer-from "^1.0.0" source-map "^0.6.0" -source-map-support@^0.5.3, source-map-support@^0.5.5, source-map-support@~0.5.19, source-map-support@~0.5.20: +source-map-support@^0.5.3, source-map-support@^0.5.5, source-map-support@~0.5.20: version "0.5.20" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9" integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw== @@ -7672,11 +14589,56 @@ source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w= -sourcemap-codec@1.4.8, sourcemap-codec@^1.4.4, sourcemap-codec@^1.4.8: +source-map@~0.1.30: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + integrity sha512-VtCvB9SIQhk3aF6h+N85EaqIaBFIAfZ9Cu+NJHHVvc8BbEcnvDcFw6sqQ2dQrT6SlOrZq3tIvyD9+EGq/lJryQ== + dependencies: + amdefine ">=0.0.4" + +source-map@~0.8.0-beta.0: + version "0.8.0-beta.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.8.0-beta.0.tgz#d4c1bb42c3f7ee925f005927ba10709e0d1d1f11" + integrity sha512-2ymg6oRBpebeZi9UUNsgQ89bhx01TcTkmNTGnNO88imTmbSgy4nfujrgVEFKWpMTEGA11EDkTt7mqObTPdigIA== + dependencies: + whatwg-url "^7.0.0" + +sourcemap-codec@^1.4.1, sourcemap-codec@^1.4.4, sourcemap-codec@^1.4.8: version "1.4.8" resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4" integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA== +space-separated-tokens@^1.0.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" + integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== + +spdx-correct@^3.0.0: + 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" + +spdx-exceptions@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d" + integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A== + +spdx-expression-parse@^3.0.0: + 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" + +spdx-license-ids@^3.0.0: + version "3.0.11" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz#50c0d8c40a14ec1bf449bae69a0ea4685a9d9f95" + integrity sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g== + spdy-transport@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-3.0.0.tgz#00d4863a6400ad75df93361a1608605e5dcdcf31" @@ -7700,11 +14662,6 @@ spdy@^4.0.2: select-hose "^2.0.0" spdy-transport "^3.0.0" -spinkit@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/spinkit/-/spinkit-1.2.5.tgz#90f9f466a20e8e39ef24da959c1e611c2a30dd54" - integrity sha1-kPn0ZqIOjjnvJNqVnB5hHCow3VQ= - split-string@^3.0.1, split-string@^3.0.2: version "3.1.0" resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" @@ -7712,6 +14669,13 @@ split-string@^3.0.1, split-string@^3.0.2: dependencies: extend-shallow "^3.0.0" +split@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/split/-/split-1.0.1.tgz#605bd9be303aa59fb35f9229fbea0ddec9ea07d9" + integrity sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg== + dependencies: + through "2" + sprintf-js@^1.1.1, sprintf-js@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.1.2.tgz#da1765262bf8c0f571749f2ad6c26300207ae673" @@ -7737,6 +14701,13 @@ sshpk@^1.7.0: safer-buffer "^2.0.2" tweetnacl "~0.14.0" +ssri@^6.0.1: + version "6.0.2" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-6.0.2.tgz#157939134f20464e7301ddba3e90ffa8f7728ac5" + integrity sha512-cepbSq/neFK7xB6A50KHN0xHDotYzq58wWCa5LeWqnPrHG8GzfEjO/4O8kpmcGW+oaxkvhEJCWgbgNk4/ZV93Q== + dependencies: + figgy-pudding "^3.5.1" + ssri@^8.0.0, ssri@^8.0.1: version "8.0.1" resolved "https://registry.yarnpkg.com/ssri/-/ssri-8.0.1.tgz#638e4e439e2ffbd2cd289776d5ca457c4f51a2af" @@ -7744,29 +14715,118 @@ ssri@^8.0.0, ssri@^8.0.1: dependencies: minipass "^3.1.1" +ssri@^9.0.0: + version "9.0.1" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-9.0.1.tgz#544d4c357a8d7b71a19700074b6883fcb4eae057" + integrity sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q== + dependencies: + minipass "^3.1.1" + stable@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== +state-toggle@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/state-toggle/-/state-toggle-1.0.3.tgz#e123b16a88e143139b09c6852221bc9815917dfe" + integrity sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ== + +static-eval@^2.0.5: + version "2.1.0" + resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-2.1.0.tgz#a16dbe54522d7fa5ef1389129d813fd47b148014" + integrity sha512-agtxZ/kWSsCkI5E4QifRwsaPs0P0JmZV6dkLz6ILYfFYQGn+5plctanRN+IC8dJRiFkyXHrwEE3W9Wmx67uDbw== + dependencies: + escodegen "^1.11.1" + static-extend@^0.1.1: version "0.1.2" resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" - integrity sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY= + integrity sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g== dependencies: define-property "^0.2.5" object-copy "^0.1.0" -"statuses@>= 1.4.0 < 2", "statuses@>= 1.5.0 < 2", statuses@~1.5.0: +static-module@^3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/static-module/-/static-module-3.0.4.tgz#bfbd1d1c38dd1fbbf0bb4af0c1b3ae18a93a2b68" + integrity sha512-gb0v0rrgpBkifXCa3yZXxqVmXDVE+ETXj6YlC/jt5VzOnGXR2C15+++eXuMDUYsePnbhf+lwW0pE1UXyOLtGCw== + dependencies: + acorn-node "^1.3.0" + concat-stream "~1.6.0" + convert-source-map "^1.5.1" + duplexer2 "~0.1.4" + escodegen "^1.11.1" + has "^1.0.1" + magic-string "0.25.1" + merge-source-map "1.0.4" + object-inspect "^1.6.0" + readable-stream "~2.3.3" + scope-analyzer "^2.0.1" + shallow-copy "~0.0.1" + static-eval "^2.0.5" + through2 "~2.0.3" + +statuses@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" + integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== + +"statuses@>= 1.4.0 < 2", statuses@~1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c" integrity sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow= +store2@^2.12.0: + version "2.14.2" + resolved "https://registry.yarnpkg.com/store2/-/store2-2.14.2.tgz#56138d200f9fe5f582ad63bc2704dbc0e4a45068" + integrity sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w== + store@^2.0.12: version "2.0.12" resolved "https://registry.yarnpkg.com/store/-/store-2.0.12.tgz#8c534e2a0b831f72b75fc5f1119857c44ef5d593" integrity sha1-jFNOKguDH3K3X8XxEZhXxE711ZM= +stream-browserify@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.2.tgz#87521d38a44aa7ee91ce1cd2a47df0cb49dd660b" + integrity sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg== + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-combiner@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.2.2.tgz#aec8cbac177b56b6f4fa479ced8c1912cee52858" + integrity sha512-6yHMqgLYDzQDcAkL+tjJDC5nSNuNIx0vZtRZeiPh7Saef7VHX9H5Ijn9l2VIol2zaNYlYEX6KyuT/237A58qEQ== + dependencies: + duplexer "~0.1.1" + through "~2.3.4" + +stream-each@^1.1.0: + version "1.2.3" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.3.tgz#ebe27a0c389b04fbcc233642952e10731afa9bae" + integrity sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw== + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + integrity sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw== + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.1.tgz#d7088281559ab2778424279b0877da3c392d5a3d" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + string-width@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" @@ -7776,24 +14836,7 @@ string-width@^1.0.1: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^3.0.0, string-width@^3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" - integrity sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w== - dependencies: - emoji-regex "^7.0.1" - is-fullwidth-code-point "^2.0.0" - strip-ansi "^5.1.0" - -string-width@^4.1.0, string-width@^4.2.0: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -7802,7 +14845,65 @@ string-width@^4.1.0, string-width@^4.2.0: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string_decoder@^1.1.1: +string-width@^2.0.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +"string.prototype.matchall@^4.0.0 || ^3.0.1": + version "4.0.7" + resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.7.tgz#8e6ecb0d8a1fb1fda470d81acecb2dba057a481d" + integrity sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + get-intrinsic "^1.1.1" + has-symbols "^1.0.3" + internal-slot "^1.0.3" + regexp.prototype.flags "^1.4.1" + side-channel "^1.0.4" + +string.prototype.padend@^3.0.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/string.prototype.padend/-/string.prototype.padend-3.1.3.tgz#997a6de12c92c7cb34dc8a201a6c53d9bd88a5f1" + integrity sha512-jNIIeokznm8SD/TZISQsZKYu7RJyheFNt84DUPrh482GC8RVp2MKqm2O5oBRdGxbDQoXrhhWtPIWQOiy20svUg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +string.prototype.padstart@^3.0.0: + version "3.1.3" + resolved "https://registry.yarnpkg.com/string.prototype.padstart/-/string.prototype.padstart-3.1.3.tgz#4551d0117d9501692ec6000b15056ac3f816cfa5" + integrity sha512-NZydyOMtYxpTjGqp0VN5PYUF/tsU15yDMZnUdj16qRUIUiMJkHHSDElYyQFrMu+/WloTpA7MQSiADhBicDfaoA== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.3" + es-abstract "^1.19.1" + +string.prototype.trimend@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.5.tgz#914a65baaab25fbdd4ee291ca7dde57e869cb8d0" + integrity sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + +string.prototype.trimstart@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.5.tgz#5466d93ba58cfa2134839f81d7f42437e8c01fef" + integrity sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg== + dependencies: + call-bind "^1.0.2" + define-properties "^1.1.4" + es-abstract "^1.19.5" + +string_decoder@^1.0.0, string_decoder@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== @@ -7830,13 +14931,6 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" - integrity sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA== - dependencies: - ansi-regex "^4.1.0" - strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -7844,45 +14938,77 @@ strip-ansi@^6.0.0, strip-ansi@^6.0.1: dependencies: ansi-regex "^5.0.1" +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + integrity sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g== + dependencies: + is-utf8 "^0.2.0" + +strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + integrity sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA== + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= -style-loader@3.2.1: - version "3.2.1" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-3.2.1.tgz#63cb920ec145c8669e9a50e92961452a1ef5dcde" - integrity sha512-1k9ZosJCRFaRbY6hH49JFlRB0fVSbmnyq1iTPjNxUmGVjBNEmwrrHPenhlp+Lgo51BojHSf6pl2FcqYaN3PfVg== +strip-final-newline@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" + integrity sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA== -stylehacks@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/stylehacks/-/stylehacks-5.0.1.tgz#323ec554198520986806388c7fdaebc38d2c06fb" - integrity sha512-Es0rVnHIqbWzveU1b24kbw92HsebBepxfcqe5iix7t9j0PQqhs0IxXVXv0pY2Bxa08CgMkzD6OWql7kbGOuEdA== +strip-indent@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-1.0.1.tgz#0c7962a6adefa7bbd4ac366460a638552ae1a0a2" + integrity sha512-I5iQq6aFMM62fBEAIB/hXzwJD6EEZ0xEGCX2t7oXqaKPIRgt4WruAQ285BISgdkP+HLGWyeGmNJcpIwFeRYRUA== dependencies: - browserslist "^4.16.0" - postcss-selector-parser "^6.0.4" + get-stdin "^4.0.1" -stylus-loader@6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-6.1.0.tgz#7a3a719a27cb2b9617896d6da28fda94c3ed9762" - integrity sha512-qKO34QCsOtSJrXxQQmXsPeaVHh6hMumBAFIoJTcsSr2VzrA6o/CW9HCGR8spCjzJhN8oKQHdj/Ytx0wwXyElkw== +style-loader@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e" + integrity sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q== dependencies: - fast-glob "^3.2.5" + loader-utils "^2.0.0" + schema-utils "^2.7.0" + +style-loader@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-2.0.0.tgz#9669602fd4690740eaaec137799a03addbbc393c" + integrity sha512-Z0gYUJmzZ6ZdRUqpg1r8GsaFKypE+3xAzuFeMuoHgjc9KZv3wMyCRjQIWEbhoFSq7+7yoHXySDJyyWQaPajeiQ== + dependencies: + loader-utils "^2.0.0" + schema-utils "^3.0.0" + +style-to-object@0.3.0, style-to-object@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/style-to-object/-/style-to-object-0.3.0.tgz#b1b790d205991cc783801967214979ee19a76e46" + integrity sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA== + dependencies: + inline-style-parser "0.1.1" + +stylus-loader@6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/stylus-loader/-/stylus-loader-6.2.0.tgz#0ba499e744e7fb9d9b3977784c8639728a7ced8c" + integrity sha512-5dsDc7qVQGRoc6pvCL20eYgRUxepZ9FpeK28XhdXaIPP6kXr6nI1zAAKFQgP5OBkOfKaURp4WUpJzspg1f01Gg== + dependencies: + fast-glob "^3.2.7" klona "^2.0.4" normalize-path "^3.0.0" -stylus@0.54.8: - version "0.54.8" - resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.54.8.tgz#3da3e65966bc567a7b044bfe0eece653e099d147" - integrity sha512-vr54Or4BZ7pJafo2mpf0ZcwA74rpuYCZbxrHBsH8kbcXOwSfvBFwsRfpGO5OD5fhG5HDCFW737PKaawI7OqEAg== +stylus@0.57.0: + version "0.57.0" + resolved "https://registry.yarnpkg.com/stylus/-/stylus-0.57.0.tgz#a46f04f426c19ceef54abb1a9d189fd4e886df41" + integrity sha512-yOI6G8WYfr0q8v8rRvE91wbxFU+rJPo760Va4MF6K0I6BZjO4r+xSynkvyPBP9tV1CIEUeRsiidjIs2rzb1CnQ== dependencies: - css-parse "~2.0.0" - debug "~3.1.0" + css "^3.0.0" + debug "^4.3.2" glob "^7.1.6" - mkdirp "~1.0.4" safer-buffer "^2.1.2" sax "~1.2.4" - semver "^6.3.0" source-map "^0.7.3" superagent@^3.8.3: @@ -7913,14 +15039,7 @@ supports-color@^5.3.0: dependencies: has-flag "^3.0.0" -supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== - dependencies: - has-flag "^3.0.0" - -supports-color@^7.1.0: +supports-color@^7.0.0, supports-color@^7.1.0: version "7.2.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da" integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw== @@ -7934,30 +15053,42 @@ supports-color@^8.0.0: dependencies: has-flag "^4.0.0" -svgo@^2.3.0: - version "2.7.0" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.7.0.tgz#e164cded22f4408fe4978f082be80159caea1e2d" - integrity sha512-aDLsGkre4fTDCWvolyW+fs8ZJFABpzLXbtdK1y71CKnHzAnpDxKXPj2mNKj+pyOXUCzFHzuxRJ94XOFygOWV3w== - dependencies: - "@trysound/sax" "0.2.0" - commander "^7.2.0" - css-select "^4.1.3" - css-tree "^1.1.3" - csso "^4.2.0" - nanocolors "^0.1.12" - stable "^0.1.8" +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== symbol-observable@4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-4.0.0.tgz#5b425f192279e87f2f9b937ac8540d1984b39205" integrity sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ== -tapable@^2.1.1, tapable@^2.2.0: +symbol.prototype.description@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/symbol.prototype.description/-/symbol.prototype.description-1.0.5.tgz#d30e01263b6020fbbd2d2884a6276ce4d49ab568" + integrity sha512-x738iXRYsrAt9WBhRCVG5BtIC3B7CUkFwbHW2zOvGtwM33s7JjrCDyq8V0zgMYVb5ymsL8+qkzzpANH63CPQaQ== + dependencies: + call-bind "^1.0.2" + get-symbol-description "^1.0.0" + has-symbols "^1.0.2" + object.getownpropertydescriptors "^2.1.2" + +synchronous-promise@^2.0.15: + version "2.0.15" + resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-2.0.15.tgz#07ca1822b9de0001f5ff73595f3d08c4f720eb8e" + integrity sha512-k8uzYIkIVwmT+TcglpdN50pS2y1BDcUnBPK9iJeGu0Pl1lOI8pD6wtzgw91Pjpe+RxtTncw32tLxs/R0yNL2Mg== + +tapable@^1.0.0, tapable@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.1.3.tgz#a1fccc06b58db61fd7a45da2da44f5f3a3e67ba2" + integrity sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA== + +tapable@^2.0.0, tapable@^2.1.1, tapable@^2.2.0: version "2.2.1" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.1.tgz#1967a73ef4060a82f12ab96af86d52fdb76eeca0" integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== -tar@^6.0.2, tar@^6.1.0: +tar@^6.0.2, tar@^6.1.11, tar@^6.1.2: version "6.1.11" resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.11.tgz#6760a38f003afa1b2ffd0ffe9e9abbd0eab3d621" integrity sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA== @@ -7969,17 +15100,60 @@ tar@^6.0.2, tar@^6.1.0: mkdirp "^1.0.3" yallist "^4.0.0" -terser-webpack-plugin@5.1.4: - version "5.1.4" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.1.4.tgz#c369cf8a47aa9922bd0d8a94fe3d3da11a7678a1" - integrity sha512-C2WkFwstHDhVEmsmlCxrXUtVklS+Ir1A7twrYzrDrQQOIMOaVAYykaoo/Aq1K0QRkMoY2hhvDQY1cm4jnIMFwA== +telejson@^6.0.8: + version "6.0.8" + resolved "https://registry.yarnpkg.com/telejson/-/telejson-6.0.8.tgz#1c432db7e7a9212c1fbd941c3e5174ec385148f7" + integrity sha512-nerNXi+j8NK1QEfBHtZUN/aLdDcyupA//9kAboYLrtzZlPLpUfqbVGWb9zz91f/mIjRbAYhbgtnJHY8I1b5MBg== dependencies: - jest-worker "^27.0.2" - p-limit "^3.1.0" - schema-utils "^3.0.0" - serialize-javascript "^6.0.0" + "@types/is-function" "^1.0.0" + global "^4.4.0" + is-function "^1.0.2" + is-regex "^1.1.2" + is-symbol "^1.0.3" + isobject "^4.0.0" + lodash "^4.17.21" + memoizerific "^1.11.3" + +terser-webpack-plugin@^1.4.3: + version "1.4.5" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-1.4.5.tgz#a217aefaea330e734ffacb6120ec1fa312d6040b" + integrity sha512-04Rfe496lN8EYruwi6oPQkG0vo8C+HT49X687FZnpPF0qMAIHONI6HEXYPKDOE8e5HjXTyKfqRd/agHtH0kOtw== + dependencies: + cacache "^12.0.2" + find-cache-dir "^2.1.0" + is-wsl "^1.1.0" + schema-utils "^1.0.0" + serialize-javascript "^4.0.0" source-map "^0.6.1" - terser "^5.7.0" + terser "^4.1.2" + webpack-sources "^1.4.0" + worker-farm "^1.7.0" + +terser-webpack-plugin@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz#28daef4a83bd17c1db0297070adc07fc8cfc6a9a" + integrity sha512-jTgXh40RnvOrLQNgIkwEKnQ8rmHjHK4u+6UBEi+W+FPmvb+uo+chJXntKe7/3lW5mNysgSWD60KyesnhW8D6MQ== + dependencies: + cacache "^15.0.5" + find-cache-dir "^3.3.1" + jest-worker "^26.5.0" + p-limit "^3.0.2" + schema-utils "^3.0.0" + serialize-javascript "^5.0.1" + source-map "^0.6.1" + terser "^5.3.4" + webpack-sources "^1.4.3" + +terser-webpack-plugin@^5.0.3: + version "5.3.3" + resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.3.tgz#8033db876dd5875487213e87c627bca323e5ed90" + integrity sha512-Fx60G5HNYknNTNQnzQ1VePRuu89ZVYWfjRAeT5rITuCY/1b08s49e5kSQwHDirKZWuoKOBRFS98EUUoZ9kLEwQ== + dependencies: + "@jridgewell/trace-mapping" "^0.3.7" + jest-worker "^27.4.5" + schema-utils "^3.1.1" + serialize-javascript "^6.0.0" + terser "^5.7.2" terser-webpack-plugin@^5.1.3: version "5.2.4" @@ -7993,16 +15167,36 @@ terser-webpack-plugin@^5.1.3: source-map "^0.6.1" terser "^5.7.2" -terser@5.7.1: - version "5.7.1" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.7.1.tgz#2dc7a61009b66bb638305cb2a824763b116bf784" - integrity sha512-b3e+d5JbHAe/JSjwsC3Zn55wsBIM7AsHLjKxT31kGCldgbpFePaFo+PiddtO6uwRZWRw7sPXmAN8dTW61xmnSg== +terser@5.13.1: + version "5.13.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.13.1.tgz#66332cdc5a01b04a224c9fad449fc1a18eaa1799" + integrity sha512-hn4WKOfwnwbYfe48NgrQjqNOH9jzLqRcIfbYytOXCOv46LBfWr9bDS17MQqOi+BWGD0sJK3Sj5NC/gJjiojaoA== + dependencies: + acorn "^8.5.0" + commander "^2.20.0" + source-map "~0.8.0-beta.0" + source-map-support "~0.5.20" + +terser@^4.1.2, terser@^4.6.3: + version "4.8.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.1.tgz#a00e5634562de2239fd404c649051bf6fc21144f" + integrity sha512-4GnLC0x667eJG0ewJTa6z/yXrbLGv80D9Ru6HIpCQmO+Q4PfEtBFi0ObSckqwL6VyQv/7ENJieXHo2ANmdQwgw== dependencies: commander "^2.20.0" - source-map "~0.7.2" - source-map-support "~0.5.19" + source-map "~0.6.1" + source-map-support "~0.5.12" -terser@^5.7.0, terser@^5.7.2: +terser@^5.10.0, terser@^5.3.4: + version "5.14.2" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.14.2.tgz#9ac9f22b06994d736174f4091aa368db896f1c10" + integrity sha512-oL0rGeM/WFQCUd0y2QrWxYnq7tfSuKBiqTjRPWrRgB46WD/kiwHwF8T23z78H6Q6kGCuuHcPB+KULHRdxvVGQA== + dependencies: + "@jridgewell/source-map" "^0.3.2" + acorn "^8.5.0" + commander "^2.20.0" + source-map-support "~0.5.20" + +terser@^5.7.2: version "5.9.0" resolved "https://registry.yarnpkg.com/terser/-/terser-5.9.0.tgz#47d6e629a522963240f2b55fcaa3c99083d2c351" integrity sha512-h5hxa23sCdpzcye/7b8YqbE5OwKca/ni0RQz1uRX3tGh8haaGHqcuSqbGRybuAKNdntZ0mDgFNXPJ48xQ2RXKQ== @@ -8011,12 +15205,29 @@ terser@^5.7.0, terser@^5.7.2: source-map "~0.7.2" source-map-support "~0.5.20" +test-exclude@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-6.0.0.tgz#04a8698661d805ea6fa293b6cb9e63ac044ef15e" + integrity sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w== + dependencies: + "@istanbuljs/schema" "^0.1.2" + glob "^7.1.4" + minimatch "^3.0.4" + text-table@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= -through@X.X.X, through@^2.3.6: +through2@^2.0.0, through2@~2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd" + integrity sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ== + dependencies: + readable-stream "~2.3.6" + xtend "~4.0.1" + +through@2, through@X.X.X, through@^2.3.6, through@^2.3.8, through@~2.3, through@~2.3.4: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU= @@ -8026,10 +15237,22 @@ thunky@^1.0.2: resolved "https://registry.yarnpkg.com/thunky/-/thunky-1.1.0.tgz#5abaf714a9405db0504732bbccd2cedd9ef9537d" integrity sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA== -timsort@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4" - integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q= +time-stamp@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" + integrity sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw== + +timers-browserify@^2.0.4: + version "2.0.12" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.12.tgz#44a45c11fbf407f34f97bccd1577c652361b00ee" + integrity sha512-9phl76Cqm6FhSX9Xe1ZUAMLtm1BLkKj2Qd5ApyWkXzsMRaA7dgr81kf4wJmQf/hAvg8EEyJxDo3du/0KlhPiKQ== + dependencies: + setimmediate "^1.0.4" + +tiny-inflate@^1.0.0, tiny-inflate@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/tiny-inflate/-/tiny-inflate-1.0.3.tgz#122715494913a1805166aaf7c93467933eea26c4" + integrity sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw== tmp@0.0.30: version "0.0.30" @@ -8045,6 +15268,16 @@ tmp@^0.0.33: dependencies: os-tmpdir "~1.0.2" +tmpl@1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc" + integrity sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw== + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + integrity sha512-okFlQcoGTi4LQBG/PgSYblw9VOyptsz2KJZqc6qtgGdes8VktzUQkj4BI2blit072iS8VODNcMA+tvnS9dnuMA== + to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" @@ -8053,14 +15286,14 @@ to-fast-properties@^2.0.0: to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" - integrity sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68= + integrity sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg== dependencies: kind-of "^3.0.2" to-regex-range@^2.1.0: version "2.1.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" - integrity sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg= + integrity sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg== dependencies: is-number "^3.0.0" repeat-string "^1.6.1" @@ -8082,10 +15315,19 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -toidentifier@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" - integrity sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw== +toidentifier@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.1.tgz#3be34321a88a820ed1bd80dfaa33e479fbb8dd35" + integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== + +"tough-cookie@^2.3.3 || ^3.0.1 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-4.0.0.tgz#d822234eeca882f991f0f908824ad2622ddbece4" + integrity sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg== + dependencies: + psl "^1.1.33" + punycode "^2.1.1" + universalify "^0.1.2" tough-cookie@~2.5.0: version "2.5.0" @@ -8095,16 +15337,77 @@ tough-cookie@~2.5.0: psl "^1.1.28" punycode "^2.1.1" +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + integrity sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk= + dependencies: + punycode "^2.1.0" + +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + +traverse@^0.6.6: + version "0.6.6" + resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.6.6.tgz#cbdf560fd7b9af632502fed40f918c157ea97137" + integrity sha512-kdf4JKs8lbARxWdp7RKdNzoJBhGUcIalSYibuGyHJbmk40pOysQ0+QPvlkCOICOivDWU2IJo2rkrxyTK2AH4fw== + tree-kill@1.2.2: version "1.2.2" resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.2.2.tgz#4ca09a9092c88b73a7cdc5e8a01b507b0790a0cc" integrity sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A== +trim-newlines@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" + integrity sha512-Nm4cF79FhSTzrLKGDMi3I4utBtFv8qKy4sq1enftf2gMdpqI8oVQTAfySkTz5r49giVzDj88SVZXP4CeYQwjaw== + +trim-trailing-lines@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz#bd4abbec7cc880462f10b2c8b5ce1d8d1ec7c2c0" + integrity sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ== + +trim@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/trim/-/trim-0.0.1.tgz#5858547f6b290757ee95cccc666fb50084c460dd" + integrity sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ== + +trough@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406" + integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA== + +ts-dedent@^2.0.0, ts-dedent@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" + integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== + +ts-loader@^8.0.14: + version "8.4.0" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-8.4.0.tgz#e845ea0f38d140bdc3d7d60293ca18d12ff2720f" + integrity sha512-6nFY3IZ2//mrPc+ImY3hNWx1vCHyEhl6V+wLmL4CZcm6g1CqX7UKrkc6y0i4FwcfOhxyMPCfaEvh20f4r9GNpw== + dependencies: + chalk "^4.1.0" + enhanced-resolve "^4.0.0" + loader-utils "^2.0.0" + micromatch "^4.0.0" + semver "^7.3.4" + ts-md5@^1.2.7: version "1.2.9" resolved "https://registry.yarnpkg.com/ts-md5/-/ts-md5-1.2.9.tgz#22c9fd2baafdfdebee1068ff4d2dc215ff51df77" integrity sha512-/Efr7ZfGf8P+d9HXh0PLQD1CDipqD8j9apCFG96pODDoEaFLxXpV4En6tAc6y3fWyfhFGrqtNBRBS+eLVIB2uQ== +ts-morph@^13.0.3: + version "13.0.3" + resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-13.0.3.tgz#c0c51d1273ae2edb46d76f65161eb9d763444c1d" + integrity sha512-pSOfUMx8Ld/WUreoSzvMFQG5i9uEiWIsBYjpU9+TTASOeUa89j5HykomeqVULm1oqWtBdleI3KEFRLrlA3zGIw== + dependencies: + "@ts-morph/common" "~0.12.3" + code-block-writer "^11.0.0" + ts-node@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-5.0.1.tgz#78e5d1cb3f704de1b641e43b76be2d4094f06f81" @@ -8119,26 +15422,45 @@ ts-node@~5.0.1: source-map-support "^0.5.3" yn "^2.0.0" -tslib@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" - integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== +ts-pnp@^1.1.6: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.2.0.tgz#a500ad084b0798f1c3071af391e65912c86bca92" + integrity sha512-csd+vJOb/gkzvcCHgTGSChYpy5f1/XKNsmvBGO4JXS+z1v2HobugDz4s1IeFXM3wZB44uczs+eazB5Q/ccdhQw== -tslib@^1.10.0, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: +tsconfig-paths-webpack-plugin@^3.3.0: + version "3.5.2" + resolved "https://registry.yarnpkg.com/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-3.5.2.tgz#01aafff59130c04a8c4ebc96a3045c43c376449a" + integrity sha512-EhnfjHbzm5IYI9YPNVIxx1moxMI4bpHD2e0zTXeDNQcwjjRaGepP7IhTHJkyDBG0CAOoxRfe7jCG630Ou+C6Pw== + dependencies: + chalk "^4.1.0" + enhanced-resolve "^5.7.0" + tsconfig-paths "^3.9.0" + +tsconfig-paths@^3.9.0: + version "3.14.1" + resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz#ba0734599e8ea36c862798e920bcf163277b137a" + integrity sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ== + dependencies: + "@types/json5" "^0.0.29" + json5 "^1.0.1" + minimist "^1.2.6" + strip-bom "^3.0.0" + +tslib@2.4.0, tslib@^2.0.3: + version "2.4.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.4.0.tgz#7cecaa7f073ce680a05847aa77be941098f36dc3" + integrity sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ== + +tslib@^1.10.0, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: version "1.14.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.1.0, tslib@^2.2.0: +tslib@^2.0.0, tslib@^2.1.0, tslib@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== -tslib@~2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" - integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== - tslint-angular@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/tslint-angular/-/tslint-angular-1.1.2.tgz#5ce7020968e3b9dc7a40b6d15dadd6da34787309" @@ -8173,6 +15495,11 @@ tsutils@^2.29.0: dependencies: tslib "^1.8.1" +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + integrity sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw== + tunnel-agent@^0.6.0: version "0.6.0" resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" @@ -8185,12 +15512,34 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" integrity sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q= +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + integrity sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg== + dependencies: + prelude-ls "~1.1.2" + +type-fest@^0.20.2: + version "0.20.2" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4" + integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ== + type-fest@^0.21.3: version "0.21.3" resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37" integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w== -type-is@~1.6.17, type-is@~1.6.18: +type-fest@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.6.0.tgz#8d2a2370d3df886eb5c90ada1c5bf6188acf838b" + integrity sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg== + +type-fest@^0.8.1: + version "0.8.1" + resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d" + integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA== + +type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== @@ -8198,10 +15547,70 @@ type-is@~1.6.17, type-is@~1.6.18: media-typer "0.3.0" mime-types "~2.1.24" -typescript@4.3.5, typescript@~4.3.4: - version "4.3.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" - integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== +type@^1.0.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/type/-/type-1.2.0.tgz#848dd7698dafa3e54a6c479e759c4bc3f18847a0" + integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== + +type@^2.5.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f" + integrity sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ== + +typed-assert@^1.0.8: + version "1.0.8" + resolved "https://registry.yarnpkg.com/typed-assert/-/typed-assert-1.0.8.tgz#4bf9f1ce7f3f974d09c3afd7c68d12e1391a233c" + integrity sha512-5NkbXZUlmCE73Fs7gvkp1XXJWHYetPkg60QnQ2NXQmBYNFxbBr2zA8GCtaH4K2s2WhOmSlgiSTmrjrcm5tnM5g== + +typedarray-to-buffer@^3.1.5: + version "3.1.5" + resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080" + integrity sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q== + dependencies: + is-typedarray "^1.0.0" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== + +typescript@^4.0.3: + version "4.7.4" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" + integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== + +typescript@~4.7.3: + version "4.7.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.3.tgz#8364b502d5257b540f9de4c40be84c98e23a129d" + integrity sha512-WOkT3XYvrpXx4vMMqlD+8R8R37fZkjyLGlxavMc4iB8lrl8L0DeTcHbYgw/v0N/z9wAFsgBhcsF0ruoySS22mA== + +uglify-js@^3.1.4: + version "3.16.3" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.16.3.tgz#94c7a63337ee31227a18d03b8a3041c210fd1f1d" + integrity sha512-uVbFqx9vvLhQg0iBaau9Z75AxWJ8tqM9AV890dIZCLApF4rTcyHwmAvLeEdYRs+BzYWu8Iw81F79ah0EfTXbaw== + +unbox-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/unbox-primitive/-/unbox-primitive-1.0.2.tgz#29032021057d5e6cdbd08c5129c226dff8ed6f9e" + integrity sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw== + dependencies: + call-bind "^1.0.2" + has-bigints "^1.0.2" + has-symbols "^1.0.3" + which-boxed-primitive "^1.0.2" + +unfetch@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" + integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA== + +unherit@^1.0.4: + version "1.1.3" + resolved "https://registry.yarnpkg.com/unherit/-/unherit-1.1.3.tgz#6c9b503f2b41b262330c80e91c8614abdaa69c22" + integrity sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ== + dependencies: + inherits "^2.0.0" + xtend "^4.0.0" unicode-canonical-property-names-ecmascript@^2.0.0: version "2.0.0" @@ -8221,11 +15630,39 @@ unicode-match-property-value-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.0.0.tgz#1a01aa57247c14c568b89775a54938788189a714" integrity sha512-7Yhkc0Ye+t4PNYzOGKedDhXbYIBe1XEQYQxOPyhcXNMJ0WCABqqj6ckydd6pWRZTHV4GuCPKdBAUiMc60tsKVw== +unicode-properties@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/unicode-properties/-/unicode-properties-1.4.1.tgz#96a9cffb7e619a0dc7368c28da27e05fc8f9be5f" + integrity sha512-CLjCCLQ6UuMxWnbIylkisbRj31qxHPAurvena/0iwSVbQ2G1VY5/HjV0IRabOEbDHlzZlRdCrD4NhB0JtU40Pg== + dependencies: + base64-js "^1.3.0" + unicode-trie "^2.0.0" + unicode-property-aliases-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.0.0.tgz#0a36cb9a585c4f6abd51ad1deddb285c165297c8" integrity sha512-5Zfuy9q/DFr4tfO7ZPeVXb1aPoeQSdeFMLpYuFebehDAhbuevLs5yxSZmIFN1tP5F9Wl4IpJrYojg85/zgyZHQ== +unicode-trie@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unicode-trie/-/unicode-trie-2.0.0.tgz#8fd8845696e2e14a8b67d78fa9e0dd2cad62fec8" + integrity sha512-x7bc76x0bm4prf1VLg79uhAzKw8DVboClSN5VxJuQ+LKDOVEW9CdH+VY7SP+vX7xCYQqzzgQpFqz15zeLvAtZQ== + dependencies: + pako "^0.2.5" + tiny-inflate "^1.0.0" + +unified@9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/unified/-/unified-9.2.0.tgz#67a62c627c40589edebbf60f53edfd4d822027f8" + integrity sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg== + dependencies: + bail "^1.0.0" + extend "^3.0.0" + is-buffer "^2.0.0" + is-plain-obj "^2.0.0" + trough "^1.0.0" + vfile "^4.0.0" + union-value@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.1.tgz#0b6fe7b835aecda61c6ea4d4f02c14221e109847" @@ -8236,16 +15673,6 @@ union-value@^1.0.0: is-extendable "^0.1.1" set-value "^2.0.1" -uniq@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/uniq/-/uniq-1.0.1.tgz#b31c5ae8254844a3a8281541ce2b04b865a734ff" - integrity sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8= - -uniqs@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/uniqs/-/uniqs-2.0.0.tgz#ffede4b36b25290696e6e165d4a59edb998e6b02" - integrity sha1-/+3ks2slKQaW5uFl1KWe25mOawI= - unique-filename@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.1.tgz#1d69769369ada0583103a1e6ae87681b56573230" @@ -8260,6 +15687,79 @@ unique-slug@^2.0.0: dependencies: imurmurhash "^0.1.4" +unist-builder@2.0.3, unist-builder@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/unist-builder/-/unist-builder-2.0.3.tgz#77648711b5d86af0942f334397a33c5e91516436" + integrity sha512-f98yt5pnlMWlzP539tPc4grGMsFaQQlP/vM396b00jngsiINumNmsY8rkXjfoi1c6QaM8nQ3vaGDuoKWbe/1Uw== + +unist-util-generated@^1.0.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/unist-util-generated/-/unist-util-generated-1.1.6.tgz#5ab51f689e2992a472beb1b35f2ce7ff2f324d4b" + integrity sha512-cln2Mm1/CZzN5ttGK7vkoGw+RZ8VcUH6BtGbq98DDtRGquAAOXig1mrBQYelOwMXYS8rK+vZDyyojSjp7JX+Lg== + +unist-util-is@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-4.1.0.tgz#976e5f462a7a5de73d94b706bac1b90671b57797" + integrity sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg== + +unist-util-position@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/unist-util-position/-/unist-util-position-3.1.0.tgz#1c42ee6301f8d52f47d14f62bbdb796571fa2d47" + integrity sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA== + +unist-util-remove-position@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz#5d19ca79fdba712301999b2b73553ca8f3b352cc" + integrity sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA== + dependencies: + unist-util-visit "^2.0.0" + +unist-util-remove@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/unist-util-remove/-/unist-util-remove-2.1.0.tgz#b0b4738aa7ee445c402fda9328d604a02d010588" + integrity sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q== + dependencies: + unist-util-is "^4.0.0" + +unist-util-stringify-position@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz#cce3bfa1cdf85ba7375d1d5b17bdc4cada9bd9da" + integrity sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g== + dependencies: + "@types/unist" "^2.0.2" + +unist-util-visit-parents@^3.0.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-3.1.1.tgz#65a6ce698f78a6b0f56aa0e88f13801886cdaef6" + integrity sha512-1KROIZWo6bcMrZEwiH2UrXDyalAa0uqzWCxCJj6lPOvTve2WkfgCytoDTPaMnodXh1WrXOq0haVYHj99ynJlsg== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^4.0.0" + +unist-util-visit@2.0.3, unist-util-visit@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-2.0.3.tgz#c3703893146df47203bb8a9795af47d7b971208c" + integrity sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q== + dependencies: + "@types/unist" "^2.0.0" + unist-util-is "^4.0.0" + unist-util-visit-parents "^3.0.0" + +universalify@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + integrity sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg== + +universalify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-2.0.0.tgz#75a4984efedc4b08975c5aeb73f530d02df25717" + integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== + +unix-crypt-td-js@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/unix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz#4912dfad1c8aeb7d20fa0a39e4c31918c1d5d5dd" + integrity sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw== + unpipe@1.0.0, unpipe@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" @@ -8268,16 +15768,31 @@ unpipe@1.0.0, unpipe@~1.0.0: unset-value@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" - integrity sha1-g3aHP30jNRef+x5vw6jtDfyKtVk= + integrity sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ== dependencies: has-value "^0.3.1" isobject "^3.0.0" +untildify@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-2.1.0.tgz#17eb2807987f76952e9c0485fc311d06a826a2e0" + integrity sha512-sJjbDp2GodvkB0FZZcn7k6afVisqX5BZD7Yq3xp4nN2O15BBK0cLm3Vwn2vQaF7UDS0UUsrQMkkplmDI5fskig== + dependencies: + os-homedir "^1.0.0" + upath@^1.1.1: version "1.2.0" resolved "https://registry.yarnpkg.com/upath/-/upath-1.2.0.tgz#8f66dbcd55a883acdae4408af8b035a5044c1894" integrity sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg== +update-browserslist-db@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz#be06a5eedd62f107b7c19eb5bcefb194411abf38" + integrity sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q== + dependencies: + escalade "^3.1.1" + picocolors "^1.0.0" + uri-js@^4.2.2: version "4.4.1" resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" @@ -8288,9 +15803,18 @@ uri-js@^4.2.2: urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" - integrity sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI= + integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg== -url-parse@^1.4.3, url-parse@^1.5.3: +url-loader@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" + integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== + dependencies: + loader-utils "^2.0.0" + mime-types "^2.1.27" + schema-utils "^3.0.0" + +url-parse@^1.4.3: version "1.5.3" resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.5.3.tgz#71c1303d38fb6639ade183c2992c8cc0686df862" integrity sha512-IIORyIQD9rvj0A4CLWsHkBBJuNqWpFQe224b6j9t/ABmquIS0qDU2pY6kl6AuOrL5OkCXHMCFNe1jBcuAggjvQ== @@ -8301,7 +15825,7 @@ url-parse@^1.4.3, url-parse@^1.5.3: url@^0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" - integrity sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE= + integrity sha512-kbailJa29QrtXnxgq+DdCEGlbTeYM2eJUxsz6vjZavrCYPMIFHMKQmSKYAIuUK2i7hgPm28a8piX5NTUtM/LKQ== dependencies: punycode "1.3.2" querystring "0.2.0" @@ -8316,12 +15840,44 @@ util-deprecate@^1.0.1, util-deprecate@^1.0.2, util-deprecate@~1.0.1: resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8= +util.promisify@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + integrity sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA== + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + integrity sha512-5KiHfsmkqacuKjkRkdV7SsfDJ2EGiPsK92s2MhNSY0craxjTdKTtqKsJaCWp4LW33ZZ0OPUv1WO/TFvNQRiQxQ== + dependencies: + inherits "2.0.1" + +util@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/util/-/util-0.11.1.tgz#3236733720ec64bb27f6e26f421aaa2e1b588d61" + integrity sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ== + dependencies: + inherits "2.0.3" + +utila@~0.4: + version "0.4.0" + resolved "https://registry.yarnpkg.com/utila/-/utila-0.4.0.tgz#8a16a05d445657a3aea5eecc5b12a4fa5379772c" + integrity sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA== + utils-merge@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= -uuid@8.3.2: +uuid-browser@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/uuid-browser/-/uuid-browser-3.1.0.tgz#0f05a40aef74f9e5951e20efbf44b11871e56410" + integrity sha512-dsNgbLaTrd6l3MMxTtouOCFw4CBFc/3a+GgYA2YyrJvyQ1u6q4pcu3ktLoUZ/VN/Aw9WsauazbgsgdfVWgAKQg== + +uuid@8.3.2, uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== @@ -8331,23 +15887,26 @@ uuid@^3.3.2, uuid@^3.4.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -validate-npm-package-name@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz#5fa912d81eb7d0c74afc140de7317f0ca7df437e" - integrity sha1-X6kS2B630MdK/BQN5zF/DKffQ34= +validate-npm-package-license@^3.0.1, validate-npm-package-license@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" + integrity sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew== dependencies: - builtins "^1.0.3" + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" -vary@~1.1.2: +validate-npm-package-name@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/validate-npm-package-name/-/validate-npm-package-name-4.0.0.tgz#fe8f1c50ac20afdb86f177da85b3600f0ac0d747" + integrity sha512-mzR0L8ZDktZjpX4OB46KT+56MAhl4EIazWP/+G/HPGuvfdaqg4YsCdtOm6U9+LOFyYDoh4dpnpxZRB9MQQns5Q== + dependencies: + builtins "^5.0.0" + +vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.2.tgz#2299f02c6ded30d4a5961b0b9f74524a18f634fc" integrity sha1-IpnwLG3tMNSllhsLn3RSShj2NPw= -vendors@^1.0.3: - version "1.0.4" - resolved "https://registry.yarnpkg.com/vendors/-/vendors-1.0.4.tgz#e2b800a53e7a29b93506c3cf41100d16c4c4ad8e" - integrity sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w== - verror@1.10.0: version "1.10.0" resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" @@ -8357,10 +15916,71 @@ verror@1.10.0: core-util-is "1.0.2" extsprintf "^1.2.0" -watchpack@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.2.0.tgz#47d78f5415fe550ecd740f99fe2882323a58b1ce" - integrity sha512-up4YAn/XHgZHIxFBVCdlMiWDj6WaLKpwVeGQk2I5thdYxF/KmF0aaz6TfJZ/hfl1h/XlcDr7k1KH7ThDagpFaA== +vfile-location@^3.0.0, vfile-location@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/vfile-location/-/vfile-location-3.2.0.tgz#d8e41fbcbd406063669ebf6c33d56ae8721d0f3c" + integrity sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA== + +vfile-message@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/vfile-message/-/vfile-message-2.0.4.tgz#5b43b88171d409eae58477d13f23dd41d52c371a" + integrity sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ== + dependencies: + "@types/unist" "^2.0.0" + unist-util-stringify-position "^2.0.0" + +vfile@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/vfile/-/vfile-4.2.1.tgz#03f1dce28fc625c625bc6514350fbdb00fa9e624" + integrity sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA== + dependencies: + "@types/unist" "^2.0.0" + is-buffer "^2.0.0" + unist-util-stringify-position "^2.0.0" + vfile-message "^2.0.0" + +vm-browserify@^1.0.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" + integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ== + +walker@^1.0.7, walker@~1.0.5: + version "1.0.8" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.8.tgz#bd498db477afe573dc04185f011d3ab8a8d7653f" + integrity sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ== + dependencies: + makeerror "1.0.12" + +watchpack-chokidar2@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/watchpack-chokidar2/-/watchpack-chokidar2-2.0.1.tgz#38500072ee6ece66f3769936950ea1771be1c957" + integrity sha512-nCFfBIPKr5Sh61s4LPpy1Wtfi0HE8isJ3d2Yb5/Ppw2P2B/3eVSEBjKfN0fmHJSK14+31KwMKmcrzs2GM4P0Ww== + dependencies: + chokidar "^2.1.8" + +watchpack@^1.7.4: + version "1.7.5" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.7.5.tgz#1267e6c55e0b9b5be44c2023aed5437a2c26c453" + integrity sha512-9P3MWk6SrKjHsGkLT2KHXdQ/9SNkyoJbabxnKOoJepsvJjJG8uYTR3yTPxPQvNDI3w4Nz1xnE0TLHK4RIVe/MQ== + dependencies: + graceful-fs "^4.1.2" + neo-async "^2.5.0" + optionalDependencies: + chokidar "^3.4.1" + watchpack-chokidar2 "^2.0.1" + +watchpack@^2.2.0, watchpack@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.0.tgz#fa33032374962c78113f93c7f2fb4c54c9862a5d" + integrity sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg== + dependencies: + glob-to-regexp "^0.4.1" + graceful-fs "^4.1.2" + +watchpack@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.3.1.tgz#4200d9447b401156eeca7767ee610f8809bc9d25" + integrity sha512-x0t0JuydIo8qCNctdDrn1OzH/qDzk2+rdCOC3YzumZ42fiMqmQ7T3xQurykYMhYfHaPHTp4ZxAx2NfUo1K6QaA== dependencies: glob-to-regexp "^0.4.1" graceful-fs "^4.1.2" @@ -8379,6 +15999,16 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" +web-namespaces@^1.0.0: + version "1.1.4" + resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" + integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== + +web-streams-polyfill@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" + integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== + webdriver-js-extender@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/webdriver-js-extender/-/webdriver-js-extender-2.1.0.tgz#57d7a93c00db4cc8d556e4d3db4b5db0a80c3bb7" @@ -8404,19 +16034,28 @@ webdriver-manager@^12.0.6: semver "^5.3.0" xml2js "^0.4.17" -webpack-dev-middleware@5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.0.0.tgz#0abe825275720e0a339978aea5f0b03b140c1584" - integrity sha512-9zng2Z60pm6A98YoRcA0wSxw1EYn7B7y5owX/Tckyt9KGyULTkLtiavjaXlWqOMkM0YtqGgL3PvMOFgyFLq8vw== +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-3.0.1.tgz#24534275e2a7bc6be7bc86611cc16ae0a5654871" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + integrity sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg== + +webpack-dev-middleware@5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz#aa079a8dedd7e58bfeab358a9af7dab304cee57f" + integrity sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg== dependencies: - colorette "^1.2.2" - mem "^8.1.1" - memfs "^3.2.2" + colorette "^2.0.10" + memfs "^3.4.1" mime-types "^2.1.31" range-parser "^1.2.1" - schema-utils "^3.0.0" + schema-utils "^4.0.0" -webpack-dev-middleware@^3.7.2: +webpack-dev-middleware@^3.7.3: version "3.7.3" resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ== @@ -8427,44 +16066,77 @@ webpack-dev-middleware@^3.7.2: range-parser "^1.2.1" webpack-log "^2.0.0" -webpack-dev-server@3.11.2: - version "3.11.2" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-3.11.2.tgz#695ebced76a4929f0d5de7fd73fafe185fe33708" - integrity sha512-A80BkuHRQfCiNtGBS1EMf2ChTUs0x+B3wGDFmOeT4rmJOHhHTCH2naNxIHhmkr0/UillP4U3yeIyv1pNp+QDLQ== +webpack-dev-middleware@^4.1.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-4.3.0.tgz#179cc40795882cae510b1aa7f3710cbe93c9333e" + integrity sha512-PjwyVY95/bhBh6VUqt6z4THplYcsvQ8YNNBTBM873xLVmw8FLeALn0qurHbs9EmcfhzQis/eoqypSnZeuUz26w== dependencies: - ansi-html "0.0.7" - bonjour "^3.5.0" - chokidar "^2.1.8" + colorette "^1.2.2" + mem "^8.1.1" + memfs "^3.2.2" + mime-types "^2.1.30" + range-parser "^1.2.1" + schema-utils "^3.0.0" + +webpack-dev-middleware@^5.3.1: + version "5.3.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-5.3.3.tgz#efae67c2793908e7311f1d9b06f2a08dcc97e51f" + integrity sha512-hj5CYrY0bZLB+eTO+x/j67Pkrquiy7kWepMHmUMoPsmcUaeEnQJqFzHJOyxgWlq746/wUuA64p9ta34Kyb01pA== + dependencies: + colorette "^2.0.10" + memfs "^3.4.3" + mime-types "^2.1.31" + range-parser "^1.2.1" + schema-utils "^4.0.0" + +webpack-dev-server@4.9.0: + version "4.9.0" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.9.0.tgz#737dbf44335bb8bde68f8f39127fc401c97a1557" + integrity sha512-+Nlb39iQSOSsFv0lWUuUTim3jDQO8nhK3E68f//J2r5rIcp4lULHXz2oZ0UVdEeWXEh5lSzYUlzarZhDAeAVQw== + dependencies: + "@types/bonjour" "^3.5.9" + "@types/connect-history-api-fallback" "^1.3.5" + "@types/express" "^4.17.13" + "@types/serve-index" "^1.9.1" + "@types/sockjs" "^0.3.33" + "@types/ws" "^8.5.1" + ansi-html-community "^0.0.8" + bonjour-service "^1.0.11" + chokidar "^3.5.3" + colorette "^2.0.10" compression "^1.7.4" connect-history-api-fallback "^1.6.0" - debug "^4.1.1" - del "^4.1.1" - express "^4.17.1" - html-entities "^1.3.1" - http-proxy-middleware "0.19.1" - import-local "^2.0.0" - internal-ip "^4.3.0" - ip "^1.1.5" - is-absolute-url "^3.0.3" - killable "^1.0.1" - loglevel "^1.6.8" - opn "^5.5.0" - p-retry "^3.0.1" - portfinder "^1.0.26" - schema-utils "^1.0.0" - selfsigned "^1.10.8" - semver "^6.3.0" + default-gateway "^6.0.3" + express "^4.17.3" + graceful-fs "^4.2.6" + html-entities "^2.3.2" + http-proxy-middleware "^2.0.3" + ipaddr.js "^2.0.1" + open "^8.0.9" + p-retry "^4.5.0" + rimraf "^3.0.2" + schema-utils "^4.0.0" + selfsigned "^2.0.1" serve-index "^1.9.1" sockjs "^0.3.21" - sockjs-client "^1.5.0" spdy "^4.0.2" - strip-ansi "^3.0.1" - supports-color "^6.1.0" - url "^0.11.0" - webpack-dev-middleware "^3.7.2" - webpack-log "^2.0.0" - ws "^6.2.1" - yargs "^13.3.2" + webpack-dev-middleware "^5.3.1" + ws "^8.4.2" + +webpack-filter-warnings-plugin@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/webpack-filter-warnings-plugin/-/webpack-filter-warnings-plugin-1.2.1.tgz#dc61521cf4f9b4a336fbc89108a75ae1da951cdb" + integrity sha512-Ez6ytc9IseDMLPo0qCuNNYzgtUl8NovOqjIq4uAU8LTD4uoa1w1KpZyyzFtLTEMZpkkOkLfL9eN+KGYdk1Qtwg== + +webpack-hot-middleware@^2.25.1: + version "2.25.1" + resolved "https://registry.yarnpkg.com/webpack-hot-middleware/-/webpack-hot-middleware-2.25.1.tgz#581f59edf0781743f4ca4c200fd32c9266c6cf7c" + integrity sha512-Koh0KyU/RPYwel/khxbsDz9ibDivmUbrRuKSSQvW42KSDdO4w23WI3SkHpSUKHE76LrFnnM/L7JCrpBwu8AXYw== + dependencies: + ansi-html-community "0.0.8" + html-entities "^2.1.0" + querystring "^0.2.0" + strip-ansi "^6.0.0" webpack-log@^2.0.0: version "2.0.0" @@ -8482,7 +16154,7 @@ webpack-merge@5.8.0: clone-deep "^4.0.1" wildcard "^2.0.0" -webpack-sources@^1.2.0, webpack-sources@^1.3.0: +webpack-sources@^1.4.0, webpack-sources@^1.4.1, webpack-sources@^1.4.3: version "1.4.3" resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.4.3.tgz#eedd8ec0b928fbf1cbfe994e22d2d890f330a933" integrity sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ== @@ -8490,25 +16162,66 @@ webpack-sources@^1.2.0, webpack-sources@^1.3.0: source-list-map "^2.0.0" source-map "~0.6.1" -webpack-sources@^3.2.0: - version "3.2.1" - resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.1.tgz#251a7d9720d75ada1469ca07dbb62f3641a05b6d" - integrity sha512-t6BMVLQ0AkjBOoRTZgqrWm7xbXMBzD+XDq2EZ96+vMfn3qKgsvdXZhbPZ4ElUOpdv4u+iiGe+w3+J75iy/bYGA== +webpack-sources@^3.0.0, webpack-sources@^3.2.3: + version "3.2.3" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" + integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack-subresource-integrity@1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/webpack-subresource-integrity/-/webpack-subresource-integrity-1.5.2.tgz#e40b6578d3072e2d24104975249c52c66e9a743e" - integrity sha512-GBWYBoyalbo5YClwWop9qe6Zclp8CIXYGIz12OPclJhIrSplDxs1Ls1JDMH8xBPPrg1T6ISaTW9Y6zOrwEiAzw== +webpack-subresource-integrity@5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/webpack-subresource-integrity/-/webpack-subresource-integrity-5.1.0.tgz#8b7606b033c6ccac14e684267cb7fb1f5c2a132a" + integrity sha512-sacXoX+xd8r4WKsy9MvH/q/vBtEHr86cpImXwyg74pFIpERKt6FmB8cXpeuh0ZLgclOlHI4Wcll7+R5L02xk9Q== dependencies: - webpack-sources "^1.3.0" + typed-assert "^1.0.8" -webpack@5.50.0: - version "5.50.0" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.50.0.tgz#5562d75902a749eb4d75131f5627eac3a3192527" - integrity sha512-hqxI7t/KVygs0WRv/kTgUW8Kl3YC81uyWQSo/7WUs5LsuRw0htH/fCwbVBGCuiX/t4s7qzjXFcf41O8Reiypag== +webpack-virtual-modules@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.2.2.tgz#20863dc3cb6bb2104729fff951fbe14b18bd0299" + integrity sha512-kDUmfm3BZrei0y+1NTHJInejzxfhtU8eDj2M7OKb2IWrPFAeO1SOH2KuQ68MSZu9IGEHcxbkKKR1v18FrUSOmA== dependencies: - "@types/eslint-scope" "^3.7.0" - "@types/estree" "^0.0.50" + debug "^3.0.0" + +webpack-virtual-modules@^0.4.1: + version "0.4.4" + resolved "https://registry.yarnpkg.com/webpack-virtual-modules/-/webpack-virtual-modules-0.4.4.tgz#a19fcf371923c59c4712d63d7d194b1e4d8262cc" + integrity sha512-h9atBP/bsZohWpHnr+2sic8Iecb60GxftXsWNLLLSqewgIsGzByd2gcIID4nXcG+3tNe4GQG3dLcff3kXupdRA== + +webpack@4: + version "4.46.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.46.0.tgz#bf9b4404ea20a073605e0a011d188d77cb6ad542" + integrity sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q== + dependencies: + "@webassemblyjs/ast" "1.9.0" + "@webassemblyjs/helper-module-context" "1.9.0" + "@webassemblyjs/wasm-edit" "1.9.0" + "@webassemblyjs/wasm-parser" "1.9.0" + acorn "^6.4.1" + ajv "^6.10.2" + ajv-keywords "^3.4.1" + chrome-trace-event "^1.0.2" + enhanced-resolve "^4.5.0" + eslint-scope "^4.0.3" + json-parse-better-errors "^1.0.2" + loader-runner "^2.4.0" + loader-utils "^1.2.3" + memory-fs "^0.4.1" + micromatch "^3.1.10" + mkdirp "^0.5.3" + neo-async "^2.6.1" + node-libs-browser "^2.2.1" + schema-utils "^1.0.0" + tapable "^1.1.3" + terser-webpack-plugin "^1.4.3" + watchpack "^1.7.4" + webpack-sources "^1.4.1" + +webpack@5.72.1: + version "5.72.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.72.1.tgz#3500fc834b4e9ba573b9f430b2c0a61e1bb57d13" + integrity sha512-dXG5zXCLspQR4krZVR6QgajnZOjW2K/djHvdcRaDQvsjV9z9vaW6+ja5dZOYbqBBjF6kGXka/2ZyxNdc+8Jung== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^0.0.51" "@webassemblyjs/ast" "1.11.1" "@webassemblyjs/wasm-edit" "1.11.1" "@webassemblyjs/wasm-parser" "1.11.1" @@ -8516,21 +16229,51 @@ webpack@5.50.0: acorn-import-assertions "^1.7.6" browserslist "^4.14.5" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.8.0" - es-module-lexer "^0.7.1" + enhanced-resolve "^5.9.3" + es-module-lexer "^0.9.0" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" - graceful-fs "^4.2.4" - json-parse-better-errors "^1.0.2" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" schema-utils "^3.1.0" tapable "^2.1.1" terser-webpack-plugin "^5.1.3" - watchpack "^2.2.0" - webpack-sources "^3.2.0" + watchpack "^2.3.1" + webpack-sources "^3.2.3" + +"webpack@>=4.0.0 <6.0.0", webpack@^5.9.0: + version "5.74.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.74.0.tgz#02a5dac19a17e0bb47093f2be67c695102a55980" + integrity sha512-A2InDwnhhGN4LYctJj6M1JEaGL7Luj6LOmyBHjcI8529cm5p6VXiTIW2sn6ffvEAKmveLzvu4jrihwXtPojlAA== + dependencies: + "@types/eslint-scope" "^3.7.3" + "@types/estree" "^0.0.51" + "@webassemblyjs/ast" "1.11.1" + "@webassemblyjs/wasm-edit" "1.11.1" + "@webassemblyjs/wasm-parser" "1.11.1" + acorn "^8.7.1" + acorn-import-assertions "^1.7.6" + browserslist "^4.14.5" + chrome-trace-event "^1.0.2" + enhanced-resolve "^5.10.0" + es-module-lexer "^0.9.0" + eslint-scope "5.1.1" + events "^3.2.0" + glob-to-regexp "^0.4.1" + graceful-fs "^4.2.9" + json-parse-even-better-errors "^2.3.1" + loader-runner "^4.2.0" + mime-types "^2.1.27" + neo-async "^2.6.2" + schema-utils "^3.1.0" + tapable "^2.1.1" + terser-webpack-plugin "^5.1.3" + watchpack "^2.4.0" + webpack-sources "^3.2.3" websocket-driver@>=0.5.1, websocket-driver@^0.7.4: version "0.7.4" @@ -8546,6 +16289,34 @@ websocket-extensions@>=0.1.1: resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42" integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg== +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-5.0.0.tgz#966454e8765462e37644d3626f6742ce8b70965d" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + +whatwg-url@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.1.0.tgz#c2c492f1eca612988efd3d2266be1b9fc6170d06" + integrity sha512-WUu7Rg1DroM7oQvGWfOiAK21n74Gg+T4elXEQYkOhtyLeWiJFoOGLXPKI/9gzIie9CtwVLm8wtw6YJdKyxSjeg== + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-boxed-primitive@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6" + integrity sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg== + dependencies: + is-bigint "^1.0.1" + is-boolean-object "^1.1.0" + is-number-object "^1.0.4" + is-string "^1.0.5" + is-symbol "^1.0.3" + which-module@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" @@ -8558,25 +16329,63 @@ which@^1.2.9: dependencies: isexe "^2.0.0" -which@^2.0.2: +which@^2.0.1, which@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/which/-/which-2.0.2.tgz#7c6a8dd0a636a0327e10b59c9286eee93f3f51b1" integrity sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA== dependencies: isexe "^2.0.0" -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== +wide-align@^1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== dependencies: - string-width "^1.0.2 || 2" + string-width "^1.0.2 || 2 || 3 || 4" + +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" wildcard@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/wildcard/-/wildcard-2.0.0.tgz#a77d20e5200c6faaac979e4b3aadc7b3dd7f8fec" integrity sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw== +windows-release@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-4.0.0.tgz#4725ec70217d1bf6e02c7772413b29cdde9ec377" + integrity sha512-OxmV4wzDKB1x7AZaZgXMVsdJ1qER1ed83ZrTYd5Bwq2HfJVg3DJS8nqlAG4sMoJ7mu8cuRmLEYyU13BKwctRAg== + dependencies: + execa "^4.0.2" + +word-wrap@~1.2.3: + version "1.2.3" + resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" + integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== + +wordwrap@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + integrity sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q== + +worker-farm@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.7.0.tgz#26a94c5391bbca926152002f69b84a4bf772e5a8" + integrity sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw== + dependencies: + errno "~0.1.7" + +worker-rpc@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/worker-rpc/-/worker-rpc-0.1.1.tgz#cb565bd6d7071a8f16660686051e969ad32f54d5" + integrity sha512-P1WjMrUB3qgJNI9jfmpZ/htmBEjFh//6l/5y8SD9hg1Ef5zTTVVoRjTrTEzPrNBQvmhMxkoTsjOXN10GWU7aCg== + dependencies: + microevent.ts "~0.1.1" + wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" @@ -8585,15 +16394,6 @@ wrap-ansi@^2.0.0: string-width "^1.0.1" strip-ansi "^3.0.1" -wrap-ansi@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-5.1.0.tgz#1fd1f67235d5b6d0fee781056001bfb694c03b09" - integrity sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q== - dependencies: - ansi-styles "^3.2.0" - string-width "^3.0.0" - strip-ansi "^5.0.0" - wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" @@ -8608,12 +16408,37 @@ wrappy@1: resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8= -ws@^6.0.0, ws@^6.2.1: - version "6.2.2" - resolved "https://registry.yarnpkg.com/ws/-/ws-6.2.2.tgz#dd5cdbd57a9979916097652d78f1cc5faea0c32e" - integrity sha512-zmhltoSR8u1cnDsD43TX59mzoMZsLKqUweyYBAIvTngR3shc0W6aOZylZmq/7hqyVxPdi+5Ud2QInblgyE72fw== +write-file-atomic@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-3.0.3.tgz#56bd5c5a5c70481cd19c571bd39ab965a5de56e8" + integrity sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q== dependencies: - async-limiter "~1.0.0" + imurmurhash "^0.1.4" + is-typedarray "^1.0.0" + signal-exit "^3.0.2" + typedarray-to-buffer "^3.1.5" + +ws@^7.4.5: + version "7.5.9" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.9.tgz#54fa7db29f4c7cec68b1ddd3a89de099942bb591" + integrity sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q== + +ws@^8.2.3: + version "8.8.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.8.1.tgz#5dbad0feb7ade8ecc99b830c1d77c913d4955ff0" + integrity sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA== + +ws@^8.4.2: + version "8.7.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.7.0.tgz#eaf9d874b433aa00c0e0d8752532444875db3957" + integrity sha512-c2gsP0PRwcLFzUiA8Mkr37/MI7ilIlHQxaEAtd0uNMbVMoy8puJyafRlm0bV9MbGSabUPeLrRRaqIBcFcA2Pqg== + +x-default-browser@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/x-default-browser/-/x-default-browser-0.4.0.tgz#70cf0da85da7c0ab5cb0f15a897f2322a6bdd481" + integrity sha512-7LKo7RtWfoFN/rHx1UELv/2zHGMx8MkZKDq1xENmOCTkfIqZJ0zZ26NEJX8czhnPXVcqS0ARjjfJB+eJ0/5Cvw== + optionalDependencies: + default-browser-id "^1.0.4" xhr2@^0.2.0: version "0.2.1" @@ -8633,6 +16458,18 @@ xmlbuilder@~11.0.0: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== +xmldoc@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/xmldoc/-/xmldoc-1.2.0.tgz#7554371bfd8c138287cff01841ae4566d26e5541" + integrity sha512-2eN8QhjBsMW2uVj7JHLHkMytpvGHLHxKXBy4J3fAT/HujsEtM6yU84iGjpESYGHg6XwK0Vu4l+KgqQ2dv2cCqg== + dependencies: + sax "^1.2.4" + +xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" + integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== + "y18n@^3.2.1 || ^4.0.0", y18n@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.3.tgz#b5f259c82cd6e336921efd7bfd8bf560de9eeedf" @@ -8643,12 +16480,17 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@^3.0.2: + version "3.1.1" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" + integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== + yallist@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== -yaml@^1.10.0, yaml@^1.10.2: +yaml@^1.10.0, yaml@^1.7.2: version "1.10.2" resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b" integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg== @@ -8661,18 +16503,23 @@ yargs-parser@^11.1.1: camelcase "^5.0.0" decamelize "^1.2.0" -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== - dependencies: - camelcase "^5.0.0" - decamelize "^1.2.0" +yargs-parser@^21.0.0: + version "21.0.0" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.0.0.tgz#a485d3966be4317426dd56bdb6a30131b281dc55" + integrity sha512-z9kApYUOCwoeZ78rfRYYWdiU/iNL6mwwYlkkZfJoyMR1xps+NEBX5X7XmRpxkZHhXJ6+Ey00IwKxBBSW9FIjyA== -yargs-parser@^20.2.2: - version "20.2.9" - resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" - integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== +yargs@17.4.1: + version "17.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.4.1.tgz#ebe23284207bb75cee7c408c33e722bfb27b5284" + integrity sha512-WSZD9jgobAg3ZKuCQZSa3g9QOJeCCqLoLAykiWgmXnDo9EPnn4RPf5qVTtzgOx66o6/oqhcA5tHtJXpG8pMt3g== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.0.0" yargs@^12.0.5: version "12.0.5" @@ -8692,34 +16539,18 @@ yargs@^12.0.5: y18n "^3.2.1 || ^4.0.0" yargs-parser "^11.1.1" -yargs@^13.2.4, yargs@^13.3.2: - version "13.3.2" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.3.2.tgz#ad7ffefec1aa59565ac915f82dccb38a9c31a2dd" - integrity sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw== - dependencies: - cliui "^5.0.0" - find-up "^3.0.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 "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.2" - -yargs@^17.0.0: - version "17.2.1" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.2.1.tgz#e2c95b9796a0e1f7f3bf4427863b42e0418191ea" - integrity sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q== +yargs@^17.2.1, yargs@^17.3.1: + version "17.3.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.3.1.tgz#da56b28f32e2fd45aefb402ed9c26f42be4c07b9" + integrity sha512-WUANQeVgjLbNsEmGk20f+nlHgOqzRFpiGWVaBrYGYIGANIIu3lWjoyi0fNlFmJkvfhCZ6BXINe7/W2O2bV4iaA== dependencies: cliui "^7.0.2" escalade "^3.1.1" get-caller-file "^2.0.5" require-directory "^2.1.1" - string-width "^4.2.0" + string-width "^4.2.3" y18n "^5.0.5" - yargs-parser "^20.2.2" + yargs-parser "^21.0.0" yn@^2.0.0: version "2.0.0" @@ -8742,3 +16573,8 @@ zone.js@~0.11.4: integrity sha512-DDh2Ab+A/B+9mJyajPjHFPWfYU1H+pdun4wnnk0OcQTNjem1XQSZ2CDW+rfZEUDjv5M19SBqAkjZi0x5wuB5Qw== dependencies: tslib "^2.0.0" + +zwitch@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-1.0.5.tgz#d11d7381ffed16b742f6af7b3f223d5cd9fe9920" + integrity sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw== diff --git a/src/Ombi/Controllers/V1/External/TesterController.cs b/src/Ombi/Controllers/V1/External/TesterController.cs index 13bf44a1d..6ee0ebe22 100644 --- a/src/Ombi/Controllers/V1/External/TesterController.cs +++ b/src/Ombi/Controllers/V1/External/TesterController.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Security.Principal; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; @@ -48,7 +49,7 @@ namespace Ombi.Controllers.V1.External IPlexApi plex, IEmbyApiFactory emby, IRadarrV3Api radarr, ISonarrApi sonarr, ILogger log, IEmailProvider provider, ICouchPotatoApi cpApi, ITelegramNotification telegram, ISickRageApi srApi, INewsletterJob newsletter, ILegacyMobileNotification mobileNotification, ILidarrApi lidarrApi, IGotifyNotification gotifyNotification, IWhatsAppApi whatsAppApi, OmbiUserManager um, IWebhookNotification webhookNotification, - IJellyfinApi jellyfinApi) + IJellyfinApi jellyfinApi, IPrincipal user) { Service = service; DiscordNotification = notification; @@ -74,6 +75,7 @@ namespace Ombi.Controllers.V1.External UserManager = um; WebhookNotification = webhookNotification; _jellyfinApi = jellyfinApi; + UserPrinciple = user; } private INotificationService Service { get; } @@ -100,6 +102,7 @@ namespace Ombi.Controllers.V1.External private IWhatsAppApi WhatsAppApi { get; } private OmbiUserManager UserManager {get; } private readonly IJellyfinApi _jellyfinApi; + private IPrincipal UserPrinciple { get; } /// /// Sends a test message to discord using the provided settings @@ -279,11 +282,18 @@ namespace Ombi.Controllers.V1.External { try { + var currentUser = await GetCurrentUserAsync(); + + if (!currentUser.Email.HasValue()) + { + throw new Exception($"User '{currentUser.UserName}' has no email address set on their user profile."); + } + var message = new NotificationMessage { Message = "This is just a test! Success!", Subject = $"Ombi: Test", - To = settings.AdminEmail, + To = currentUser.Email, }; message.Other.Add("PlainTextBody", "This is just a test! Success!"); @@ -298,6 +308,11 @@ namespace Ombi.Controllers.V1.External return true; } + private async Task GetCurrentUserAsync() + { + return await UserManager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == UserPrinciple.Identity.Name.ToUpper()); + } + /// /// Checks if we can connect to Plex with the provided settings /// @@ -531,7 +546,7 @@ namespace Ombi.Controllers.V1.External { var user = await UserManager.Users.Include(x => x.UserNotificationPreferences).FirstOrDefaultAsync(x => x.UserName == HttpContext.User.Identity.Name); - + var status = await WhatsAppApi.SendMessage(new WhatsAppModel { From = settings.From, diff --git a/src/Ombi/Controllers/V1/External/TheMovieDbController.cs b/src/Ombi/Controllers/V1/External/TheMovieDbController.cs index f5fdb996f..4017c0b42 100644 --- a/src/Ombi/Controllers/V1/External/TheMovieDbController.cs +++ b/src/Ombi/Controllers/V1/External/TheMovieDbController.cs @@ -39,14 +39,6 @@ namespace Ombi.Controllers.External return keyword == null ? NotFound() : Ok(keyword); } - /// - /// Gets the genres for either Tv or Movies depending on media type - /// - /// Either `tv` or `movie`. - [HttpGet("Genres/{media}")] - public async Task> GetGenres(string media) => - await TmdbApi.GetGenres(media, HttpContext.RequestAborted); - /// /// Searches for the watch providers matching the specified term. /// diff --git a/src/Ombi/Controllers/V1/IdentityController.cs b/src/Ombi/Controllers/V1/IdentityController.cs index fded4cacc..5577b1809 100644 --- a/src/Ombi/Controllers/V1/IdentityController.cs +++ b/src/Ombi/Controllers/V1/IdentityController.cs @@ -46,57 +46,36 @@ namespace Ombi.Controllers.V1 [ApiController] public class IdentityController : Controller { - public IdentityController(OmbiUserManager user, IMapper mapper, RoleManager rm, IEmailProvider prov, + public IdentityController(OmbiUserManager user, + RoleManager rm, + IEmailProvider prov, ISettingsService s, ISettingsService c, ISettingsService ombiSettings, IWelcomeEmail welcome, - IMovieRequestRepository m, - ITvRequestRepository t, ILogger l, IPlexApi plexApi, ISettingsService settings, - IRepository requestLog, - IRepository issues, - IRepository issueComments, - IRepository notificationRepository, - IRepository subscriptionRepository, ISettingsService umSettings, IRepository notificationPreferences, IRepository userProfiles, - IMusicRequestRepository musicRepo, - IMovieRequestEngine movieRequestEngine, - ITvRequestEngine tvRequestEngine, - IMusicRequestEngine musicEngine, IUserDeletionEngine deletionEngine, IRequestLimitService requestLimitService, ICacheService cacheService) { UserManager = user; - Mapper = mapper; RoleManager = rm; EmailProvider = prov; EmailSettings = s; CustomizationSettings = c; WelcomeEmail = welcome; - MovieRepo = m; - MusicRepo = musicRepo; - TvRepo = t; _log = l; _plexApi = plexApi; _plexSettings = settings; - _issuesRepository = issues; - _requestLogRepository = requestLog; - _issueCommentsRepository = issueComments; OmbiSettings = ombiSettings; - _requestSubscriptionRepository = subscriptionRepository; - _notificationRepository = notificationRepository; _userManagementSettings = umSettings; - TvRequestEngine = tvRequestEngine; - MovieRequestEngine = movieRequestEngine; _userNotificationPreferences = notificationPreferences; _userQualityProfiles = userProfiles; - MusicRequestEngine = musicEngine; _deletionEngine = deletionEngine; _requestLimitService = requestLimitService; _cacheService = cacheService; @@ -108,27 +87,15 @@ namespace Ombi.Controllers.V1 private readonly ICacheService _cacheService; private RoleManager RoleManager { get; } - private IMapper Mapper { get; } private IEmailProvider EmailProvider { get; } private ISettingsService EmailSettings { get; } private ISettingsService CustomizationSettings { get; } private readonly ISettingsService _userManagementSettings; private ISettingsService OmbiSettings { get; } private IWelcomeEmail WelcomeEmail { get; } - private IMovieRequestRepository MovieRepo { get; } - private ITvRequestRepository TvRepo { get; } - private IMovieRequestEngine MovieRequestEngine { get; } - private IMusicRequestEngine MusicRequestEngine { get; } - private ITvRequestEngine TvRequestEngine { get; } - private IMusicRequestRepository MusicRepo { get; } private readonly ILogger _log; private readonly IPlexApi _plexApi; private readonly ISettingsService _plexSettings; - private readonly IRepository _issuesRepository; - private readonly IRepository _issueCommentsRepository; - private readonly IRepository _requestLogRepository; - private readonly IRepository _notificationRepository; - private readonly IRepository _requestSubscriptionRepository; private readonly IRepository _userNotificationPreferences; private readonly IRepository _userQualityProfiles; @@ -147,7 +114,9 @@ namespace Ombi.Controllers.V1 public async Task CreateWizardUser([FromBody] CreateUserWizardModel user) { var users = UserManager.Users; - if (users.Any(x => x.UserType == UserType.LocalUser)) + // There could be a SINGLE plex user as you can create that in the wizard flow, but there should not be anything else + var plexUsersCount = await users.CountAsync(x => x.UserType == UserType.PlexUser); + if (plexUsersCount > 1 || users.Any(x => x.UserType == UserType.LocalUser)) { // No one should be calling this. Only the wizard return new SaveWizardResult { Result = false, Errors = new List { "Looks like there is an existing user!" } }; @@ -258,6 +227,8 @@ namespace Ombi.Controllers.V1 await CreateRole(OmbiRoles.ReceivesNewsletter); await CreateRole(OmbiRoles.ManageOwnRequests); await CreateRole(OmbiRoles.EditCustomPage); + await CreateRole(OmbiRoles.EditCustomPage); + await CreateRole(OmbiRoles.Request4KMovie); } private async Task CreateRole(string role) @@ -926,7 +897,10 @@ namespace Ombi.Controllers.V1 [ApiExplorerSettings(IgnoreApi = true)] public async Task GetUserAccessToken() { - + if (!User.Identity?.Name.HasValue() ?? true) + { + return Guid.Empty.ToString("N"); + } var username = User.Identity.Name.ToUpper(); var user = await UserManager.Users.FirstOrDefaultAsync(x => x.NormalizedUserName == username); if (user == null) diff --git a/src/Ombi/Controllers/V1/ImagesController.cs b/src/Ombi/Controllers/V1/ImagesController.cs index 9683c54b0..0b8a6ce4c 100644 --- a/src/Ombi/Controllers/V1/ImagesController.cs +++ b/src/Ombi/Controllers/V1/ImagesController.cs @@ -45,9 +45,9 @@ namespace Ombi.Controllers.V1 { return string.Empty; } - var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); - var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvdbid}", () => FanartTvApi.GetTvImages(tvdbid, key.Value), DateTimeOffset.Now.AddDays(1)); + var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvdbid}", () => FanartTvApi.GetTvImages(tvdbid, key.Value), DateTimeOffset.Now.AddDays(1)); if (images == null) { return string.Empty; @@ -70,16 +70,16 @@ namespace Ombi.Controllers.V1 [HttpGet("poster")] public async Task GetRandomPoster() { - var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); var rand = new Random(); var val = rand.Next(1, 3); if (val == 1) { - var movies = (await _movieEngineV2.PopularMovies(0, 10, HttpContext.RequestAborted ,"en")).ToArray(); + var movies = (await _movieEngineV2.PopularMovies(0, 10, HttpContext.RequestAborted, "en")).ToArray(); var selectedMovieIndex = rand.Next(movies.Count()); var movie = movies[selectedMovieIndex]; - var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{movie.Id}", () => FanartTvApi.GetMovieImages(movie.Id.ToString(), key.Value), DateTimeOffset.Now.AddDays(1)); + var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{movie.Id}", () => FanartTvApi.GetMovieImages(movie.Id.ToString(), key.Value), DateTimeOffset.Now.AddDays(1)); if (images == null) { return string.Empty; @@ -99,7 +99,7 @@ namespace Ombi.Controllers.V1 { return images.moviethumb.OrderBy(x => x.likes).Select(x => x.url).FirstOrDefault(); } - } + } else { var tv = (await _tvSearchEngineV2.Popular(0, 10, "en")).ToArray(); @@ -114,9 +114,9 @@ namespace Ombi.Controllers.V1 [HttpGet("poster/movie/{movieDbId}")] public async Task GetMoviePoster(string movieDbId) { - var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); - var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{movieDbId}", () => FanartTvApi.GetMovieImages(movieDbId, key.Value), DateTimeOffset.Now.AddDays(1)); + var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{movieDbId}", () => FanartTvApi.GetMovieImages(movieDbId, key.Value), DateTimeOffset.Now.AddDays(1)); if (images == null) { @@ -148,9 +148,9 @@ namespace Ombi.Controllers.V1 { return string.Empty; } - var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); - var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvdbid}", () => FanartTvApi.GetTvImages(tvdbid, key.Value), DateTimeOffset.Now.AddDays(1)); + var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvdbid}", () => FanartTvApi.GetTvImages(tvdbid, key.Value), DateTimeOffset.Now.AddDays(1)); if (images == null) { @@ -178,10 +178,10 @@ namespace Ombi.Controllers.V1 [HttpGet("background/movie/{movieDbId}")] public async Task GetMovieBackground(string movieDbId) { - var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + + var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{movieDbId}", () => FanartTvApi.GetMovieImages(movieDbId, key.Value), DateTimeOffset.Now.AddDays(1)); - var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{movieDbId}", () => FanartTvApi.GetMovieImages(movieDbId, key.Value), DateTimeOffset.Now.AddDays(1)); - if (images == null) { return string.Empty; @@ -203,9 +203,9 @@ namespace Ombi.Controllers.V1 [HttpGet("banner/movie/{movieDbId}")] public async Task GetMovieBanner(string movieDbId) { - var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); - var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{movieDbId}", () => FanartTvApi.GetMovieImages(movieDbId, key.Value), DateTimeOffset.Now.AddDays(1)); + var images = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{movieDbId}", () => FanartTvApi.GetMovieImages(movieDbId, key.Value), DateTimeOffset.Now.AddDays(1)); if (images == null) { @@ -246,34 +246,34 @@ namespace Ombi.Controllers.V1 var movieUrl = string.Empty; var tvUrl = string.Empty; - var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); if (moviesArray.Length > 0) { var item = rand.Next(moviesArray.Length); - var result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{moviesArray[item]}", () => FanartTvApi.GetMovieImages(moviesArray[item].ToString(), key.Value), DateTimeOffset.Now.AddDays(1)); + var result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{moviesArray[item]}", () => FanartTvApi.GetMovieImages(moviesArray[item].ToString(), key.Value), DateTimeOffset.Now.AddDays(1)); while (!result.moviebackground?.Any() ?? true) { item = rand.Next(moviesArray.Length); - result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{moviesArray[item]}", () => FanartTvApi.GetMovieImages(moviesArray[item].ToString(), key.Value), DateTimeOffset.Now.AddDays(1)); + result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{moviesArray[item]}", () => FanartTvApi.GetMovieImages(moviesArray[item].ToString(), key.Value), DateTimeOffset.Now.AddDays(1)); } var otherRand = new Random(); var res = otherRand.Next(result.moviebackground.Length); - + movieUrl = result.moviebackground[res].url; } if (tvArray.Length > 0) { var item = rand.Next(tvArray.Length); - var result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvArray[item]}", () => FanartTvApi.GetTvImages(tvArray[item], key.Value), DateTimeOffset.Now.AddDays(1)); + var result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvArray[item]}", () => FanartTvApi.GetTvImages(tvArray[item], key.Value), DateTimeOffset.Now.AddDays(1)); while (!result.showbackground?.Any() ?? true) { item = rand.Next(tvArray.Length); - result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvArray[item]}", () => FanartTvApi.GetTvImages(tvArray[item], key.Value), DateTimeOffset.Now.AddDays(1)); + result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvArray[item]}", () => FanartTvApi.GetTvImages(tvArray[item], key.Value), DateTimeOffset.Now.AddDays(1)); } var otherRand = new Random(); var res = otherRand.Next(result.showbackground.Length); @@ -294,5 +294,67 @@ namespace Ombi.Controllers.V1 } return new { url = tvUrl }; } + + [HttpGet("background/info")] + public async Task GetBackgroundImageWithInfo() + { + var moviesArray = Options.Movies ?? Array.Empty(); + var tvArray = Options.TvShows ?? Array.Empty(); + + var rand = new Random(); + var movieUrl = string.Empty; + var movieName = string.Empty; + var tvName = string.Empty; + var tvUrl = string.Empty; + + var key = await _cache.GetOrAddAsync(CacheKeys.FanartTv, () => Config.GetAsync(Store.Entities.ConfigurationTypes.FanartTv), DateTimeOffset.Now.AddDays(1)); + + if (moviesArray.Length > 0) + { + var item = rand.Next(moviesArray.Length); + var result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{moviesArray[item]}", () => FanartTvApi.GetMovieImages(moviesArray[item].ToString(), key.Value), DateTimeOffset.Now.AddDays(1)); + + while (!result.moviebackground?.Any() ?? true) + { + item = rand.Next(moviesArray.Length); + result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}movie{moviesArray[item]}", () => FanartTvApi.GetMovieImages(moviesArray[item].ToString(), key.Value), DateTimeOffset.Now.AddDays(1)); + } + + var otherRand = new Random(); + var res = otherRand.Next(result.moviebackground.Length); + + movieUrl = result.moviebackground[res].url; + movieName = result.name; + } + if (tvArray.Length > 0) + { + var item = rand.Next(tvArray.Length); + var result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvArray[item]}", () => FanartTvApi.GetTvImages(tvArray[item], key.Value), DateTimeOffset.Now.AddDays(1)); + + while (!result.showbackground?.Any() ?? true) + { + item = rand.Next(tvArray.Length); + result = await _cache.GetOrAddAsync($"{CacheKeys.FanartTv}tv{tvArray[item]}", () => FanartTvApi.GetTvImages(tvArray[item], key.Value), DateTimeOffset.Now.AddDays(1)); + } + var otherRand = new Random(); + var res = otherRand.Next(result.showbackground.Length); + + tvUrl = result.showbackground[res].url; + tvName = result.name; + } + + if (!string.IsNullOrEmpty(movieUrl) && !string.IsNullOrEmpty(tvUrl)) + { + var result = rand.Next(2); + if (result == 0) return new { url = movieUrl, name = movieName }; + if (result == 1) return new { url = tvUrl, name = tvName }; + } + + if (!string.IsNullOrEmpty(movieUrl)) + { + return new { url = movieUrl, name = movieName }; + } + return new { url = tvUrl, name = tvName }; + } } } diff --git a/src/Ombi/Controllers/V1/IssuesController.cs b/src/Ombi/Controllers/V1/IssuesController.cs index 5222cf4e7..2828b5ef2 100644 --- a/src/Ombi/Controllers/V1/IssuesController.cs +++ b/src/Ombi/Controllers/V1/IssuesController.cs @@ -244,9 +244,9 @@ namespace Ombi.Controllers.V1 var isAdmin = await _userManager.IsInRoleAsync(user, OmbiRoles.Admin) || user.IsSystemUser; AddIssueNotificationSubstitutes(notificationModel, issue, user.UserName, user.UserAlias); - notificationModel.Substitutes.Add("NewIssueComment", comment.Comment); - notificationModel.Substitutes.Add("IssueId", comment.IssueId.ToString()); - notificationModel.Substitutes.Add("AdminComment", isAdmin.ToString()); + notificationModel.Substitutes.Add(NotificationSubstitues.NewIssueComment, comment.Comment); + notificationModel.Substitutes.Add(NotificationSubstitues.IssueId, comment.IssueId.ToString()); + notificationModel.Substitutes.Add(NotificationSubstitues.AdminComment, isAdmin.ToString()); if (isAdmin) { @@ -331,14 +331,15 @@ namespace Ombi.Controllers.V1 private static void AddIssueNotificationSubstitutes(NotificationOptions notificationModel, Issues issue, string issueReportedUsername, string alias) { - notificationModel.Substitutes.Add("Title", issue.Title); - notificationModel.Substitutes.Add("IssueDescription", issue.Description); - notificationModel.Substitutes.Add("IssueCategory", issue.IssueCategory?.Value); - notificationModel.Substitutes.Add("IssueStatus", issue.Status.ToString()); - notificationModel.Substitutes.Add("IssueSubject", issue.Subject); - notificationModel.Substitutes.Add("IssueUser", issueReportedUsername); - notificationModel.Substitutes.Add("IssueUserAlias", alias); - notificationModel.Substitutes.Add("RequestType", notificationModel.RequestType.ToString()); + notificationModel.Substitutes.Add(NotificationSubstitues.Title, issue.Title); + notificationModel.Substitutes.Add(NotificationSubstitues.IssueDescription, issue.Description); + notificationModel.Substitutes.Add(NotificationSubstitues.IssueCategory, issue.IssueCategory?.Value); + notificationModel.Substitutes.Add(NotificationSubstitues.IssueStatus, issue.Status.ToString()); + notificationModel.Substitutes.Add(NotificationSubstitues.IssueSubject, issue.Subject); + notificationModel.Substitutes.Add(NotificationSubstitues.IssueUser, issueReportedUsername); + notificationModel.Substitutes.Add(NotificationSubstitues.IssueUserAlias, alias); + notificationModel.Substitutes.Add(NotificationSubstitues.RequestType, notificationModel.RequestType.ToString()); + notificationModel.Substitutes.Add(NotificationSubstitues.PosterPath, issue.PosterPath); } } } \ No newline at end of file diff --git a/src/Ombi/Controllers/V1/JobController.cs b/src/Ombi/Controllers/V1/JobController.cs index 2dd694619..57ec060a2 100644 --- a/src/Ombi/Controllers/V1/JobController.cs +++ b/src/Ombi/Controllers/V1/JobController.cs @@ -91,6 +91,17 @@ namespace Ombi.Controllers.V1 return true; } + /// + /// Runs the Plex Watchlist Importer + /// + /// + [HttpPost("plexwatchlist")] + public async Task PlexWatchlistImport() + { + await OmbiQuartz.TriggerJob(nameof(IPlexWatchlistImport), "Plex"); + return true; + } + /// /// Runs the Emby User importer /// @@ -118,9 +129,9 @@ namespace Ombi.Controllers.V1 /// /// [HttpPost("plexcontentcacher")] - public bool StartPlexContentCacher() + public async Task StartPlexContentCacher() { - OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(IPlexContentSync), "Plex"), new JobDataMap(new Dictionary { { "recentlyAddedSearch", "false" } })); + await OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(IPlexContentSync), "Plex"), new JobDataMap(new Dictionary { { "recentlyAddedSearch", "false" } })); return true; } @@ -129,9 +140,9 @@ namespace Ombi.Controllers.V1 /// /// [HttpPost("clearmediaserverdata")] - public bool ClearMediaServerData() + public async Task ClearMediaServerData() { - OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(IMediaDatabaseRefresh), "System")); + await OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(IMediaDatabaseRefresh), "System")); return true; } @@ -140,9 +151,9 @@ namespace Ombi.Controllers.V1 /// /// [HttpPost("plexrecentlyadded")] - public bool StartRecentlyAdded() + public async Task StartRecentlyAdded() { - OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(IPlexContentSync) + "RecentlyAdded", "Plex"), new JobDataMap(new Dictionary { { "recentlyAddedSearch", "true" } })); + await OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(IPlexContentSync) + "RecentlyAdded", "Plex"), new JobDataMap(new Dictionary { { "recentlyAddedSearch", "true" } })); return true; } @@ -153,7 +164,18 @@ namespace Ombi.Controllers.V1 [HttpPost("embycontentcacher")] public async Task StartEmbyContentCacher() { - await OmbiQuartz.TriggerJob(nameof(IEmbyContentSync), "Emby"); + await OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(IEmbyContentSync), "Emby"), new JobDataMap(new Dictionary { { JobDataKeys.EmbyRecentlyAddedSearch, "false" } })); + return true; + } + + /// + /// Runs a smaller version of the content cacher + /// + /// + [HttpPost("embyrecentlyadded")] + public async Task StartEmbyRecentlyAdded() + { + await OmbiQuartz.Scheduler.TriggerJob(new JobKey(nameof(IEmbyContentSync) + "RecentlyAdded", "Emby"), new JobDataMap(new Dictionary { { JobDataKeys.EmbyRecentlyAddedSearch, "true" } })); return true; } diff --git a/src/Ombi/Controllers/V1/MusicRequestController.cs b/src/Ombi/Controllers/V1/MusicRequestController.cs index df9d2f406..289c7cca1 100644 --- a/src/Ombi/Controllers/V1/MusicRequestController.cs +++ b/src/Ombi/Controllers/V1/MusicRequestController.cs @@ -113,9 +113,9 @@ namespace Ombi.Controllers.V1 /// [HttpDelete("{requestId:int}")] [Authorize(Roles = "Admin,PowerUser,ManageOwnRequests")] - public async Task DeleteRequest(int requestId) + public async Task DeleteRequest(int requestId) { - await _engine.RemoveAlbumRequest(requestId); + return await _engine.RemoveAlbumRequest(requestId); } /// diff --git a/src/Ombi/Controllers/V1/RequestController.cs b/src/Ombi/Controllers/V1/RequestController.cs index 961969b6f..1220c3afc 100644 --- a/src/Ombi/Controllers/V1/RequestController.cs +++ b/src/Ombi/Controllers/V1/RequestController.cs @@ -128,9 +128,9 @@ namespace Ombi.Controllers.V1 /// [HttpDelete("movie/{requestId:int}")] [Authorize(Roles = "Admin,PowerUser,ManageOwnRequests")] - public async Task DeleteRequest(int requestId) + public async Task DeleteRequest(int requestId) { - await MovieRequestEngine.RemoveMovieRequest(requestId); + return await MovieRequestEngine.RemoveMovieRequest(requestId); } /// @@ -165,7 +165,7 @@ namespace Ombi.Controllers.V1 [PowerUser] public async Task ApproveMovie([FromBody] MovieUpdateModel model) { - return await MovieRequestEngine.ApproveMovieById(model.Id); + return await MovieRequestEngine.ApproveMovieById(model.Id, model.Is4K); } /// @@ -177,7 +177,7 @@ namespace Ombi.Controllers.V1 [PowerUser] public async Task MarkMovieAvailable([FromBody] MovieUpdateModel model) { - return await MovieRequestEngine.MarkAvailable(model.Id); + return await MovieRequestEngine.MarkAvailable(model.Id, model.Is4K); } /// @@ -189,7 +189,7 @@ namespace Ombi.Controllers.V1 [PowerUser] public async Task MarkMovieUnAvailable([FromBody] MovieUpdateModel model) { - return await MovieRequestEngine.MarkUnavailable(model.Id); + return await MovieRequestEngine.MarkUnavailable(model.Id, model.Is4K); } /// @@ -201,7 +201,7 @@ namespace Ombi.Controllers.V1 [PowerUser] public async Task DenyMovie([FromBody] DenyMovieModel model) { - return await MovieRequestEngine.DenyMovieById(model.Id, model.Reason); + return await MovieRequestEngine.DenyMovieById(model.Id, model.Reason, model.Is4K); } /// @@ -324,7 +324,7 @@ namespace Ombi.Controllers.V1 /// The request identifier. /// [HttpDelete("tv/{requestId:int}")] - [Authorize(Roles = "Admin,PowerUser,ManageOwnRequests")] + [Authorize(Roles = "Admin,PowerUser")] public async Task DeleteTvRequest(int requestId) { await TvRequestEngine.RemoveTvRequest(requestId); @@ -403,7 +403,7 @@ namespace Ombi.Controllers.V1 [PowerUser] public async Task MarkTvAvailable([FromBody] TvUpdateModel model) { - return await TvRequestEngine.MarkAvailable(model.Id); + return await TvRequestEngine.MarkAvailable(model.Id, false); } /// @@ -415,7 +415,7 @@ namespace Ombi.Controllers.V1 [PowerUser] public async Task MarkTvUnAvailable([FromBody] TvUpdateModel model) { - return await TvRequestEngine.MarkUnavailable(model.Id); + return await TvRequestEngine.MarkUnavailable(model.Id, false); } /// @@ -437,10 +437,9 @@ namespace Ombi.Controllers.V1 /// [Authorize(Roles = "Admin,PowerUser,ManageOwnRequests")] [HttpDelete("tv/child/{requestId:int}")] - public async Task DeleteChildRequest(int requestId) + public async Task DeleteChildRequest(int requestId) { - await TvRequestEngine.RemoveTvChild(requestId); - return true; + return await TvRequestEngine.RemoveTvChild(requestId); } diff --git a/src/Ombi/Controllers/V1/SettingsController.cs b/src/Ombi/Controllers/V1/SettingsController.cs index 9e7343472..0892b1dda 100644 --- a/src/Ombi/Controllers/V1/SettingsController.cs +++ b/src/Ombi/Controllers/V1/SettingsController.cs @@ -334,6 +334,7 @@ namespace Ombi.Controllers.V1 [ApiExplorerSettings(IgnoreApi = true)] [HttpPost("customization/urlverify")] + [AllowAnonymous] public bool VerifyUrl([FromBody]UrlVerifyModel url) { return Uri.TryCreate(url.Url, UriKind.Absolute, out var __); @@ -402,9 +403,13 @@ namespace Ombi.Controllers.V1 /// /// [HttpGet("radarr")] - public async Task RadarrSettings() + public async Task RadarrSettings() { - return await Get(); + return new RadarrCombinedModel + { + Radarr = await Get(), + Radarr4K = await Get(), + }; } /// @@ -473,9 +478,11 @@ namespace Ombi.Controllers.V1 /// The settings. /// [HttpPost("radarr")] - public async Task RadarrSettings([FromBody]RadarrSettings settings) + public async Task RadarrSettings([FromBody]RadarrCombinedModel settings) { - var result = await Save(settings); + var radarrResult = await Save(settings.Radarr); + var radarr4kResult = await Save(settings.Radarr4K); + var result = radarr4kResult && radarrResult; if (result) { _cache.Remove(CacheKeys.RadarrRootProfiles); @@ -618,6 +625,8 @@ namespace Ombi.Controllers.V1 j.RetryRequests = j.RetryRequests.HasValue() ? j.RetryRequests : JobSettingsHelper.ResendFailedRequests(j); j.MediaDatabaseRefresh = j.MediaDatabaseRefresh.HasValue() ? j.MediaDatabaseRefresh : JobSettingsHelper.MediaDatabaseRefresh(j); j.AutoDeleteRequests = j.AutoDeleteRequests.HasValue() ? j.AutoDeleteRequests : JobSettingsHelper.AutoDeleteRequests(j); + j.EmbyRecentlyAddedSync = j.EmbyRecentlyAddedSync.HasValue() ? j.EmbyRecentlyAddedSync : JobSettingsHelper.EmbyRecentlyAddedSync(j); + j.PlexWatchlistImport = j.PlexWatchlistImport.HasValue() ? j.PlexWatchlistImport : JobSettingsHelper.PlexWatchlistImport(j); return j; } diff --git a/src/Ombi/Controllers/V1/TokenController.cs b/src/Ombi/Controllers/V1/TokenController.cs index f9ea57a5c..657c95f91 100644 --- a/src/Ombi/Controllers/V1/TokenController.cs +++ b/src/Ombi/Controllers/V1/TokenController.cs @@ -6,39 +6,50 @@ using System.Security.Claims; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Options; using Microsoft.Extensions.Logging; using Microsoft.IdentityModel.Tokens; using Ombi.Core.Authentication; using Ombi.Helpers; using Ombi.Models; using Ombi.Models.External; -using Ombi.Models.Identity; using Ombi.Store.Entities; using Ombi.Store.Repository; +using Ombi.Core.Settings; +using Ombi.Settings.Settings.Models; +using System.Text.Json.Serialization; +using Newtonsoft.Json; namespace Ombi.Controllers.V1 { + + + public class Token + { + [JsonProperty("access_token")] + public string AccessToken { get; set; } + public DateTime Expiration { get; set; } + } + [ApiV1] [Produces("application/json")] [ApiController] public class TokenController : ControllerBase { - public TokenController(OmbiUserManager um, IOptions ta, ITokenRepository token, - IPlexOAuthManager oAuthManager, ILogger logger) + public TokenController(OmbiUserManager um, ITokenRepository token, + IPlexOAuthManager oAuthManager, ILogger logger, ISettingsService auth) { _userManager = um; - _tokenAuthenticationOptions = ta.Value; _token = token; _plexOAuthManager = oAuthManager; _log = logger; + _authSettings = auth; } - private readonly TokenAuthentication _tokenAuthenticationOptions; private readonly ITokenRepository _token; private readonly OmbiUserManager _userManager; private readonly IPlexOAuthManager _plexOAuthManager; private readonly ILogger _log; + private readonly ISettingsService _authSettings; /// /// Gets the token. @@ -47,6 +58,7 @@ namespace Ombi.Controllers.V1 /// [HttpPost] [ProducesResponseType(401)] + [ProducesResponseType(typeof(Token), 200)] public async Task GetToken([FromBody] UserAuthModel model) { if (!model.UsePlexOAuth) @@ -113,6 +125,7 @@ namespace Ombi.Controllers.V1 { return Unauthorized(); } + return await CreateToken(true, user); } @@ -143,7 +156,6 @@ namespace Ombi.Controllers.V1 var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(StartupSingleton.Instance.SecurityKey)); var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256); - var token = new JwtSecurityToken( claims: claims, expires: rememberMe ? DateTime.Now.AddYears(1) : DateTime.Now.AddDays(7), @@ -161,10 +173,10 @@ namespace Ombi.Controllers.V1 await _userManager.UpdateAsync(user); - return new JsonResult(new + return Ok(new Token { - access_token = accessToken, - expiration = token.ValidTo + AccessToken = accessToken, + Expiration = token.ValidTo }); } @@ -200,6 +212,9 @@ namespace Ombi.Controllers.V1 } } + user.MediaServerToken = account.user.authentication_token; + await _userManager.UpdateAsync(user); + return await CreateToken(true, user); } @@ -272,5 +287,38 @@ namespace Ombi.Controllers.V1 return ip; } + + [HttpPost("header_auth")] + [ProducesResponseType(401)] + [ProducesResponseType(200)] + public async Task HeaderAuth() + { + var authSettings = await _authSettings.GetSettingsAsync(); + _log.LogInformation("Logging with header: " + authSettings.HeaderAuthVariable); + if (authSettings.HeaderAuthVariable != null && authSettings.EnableHeaderAuth) + { + if (Request.HttpContext?.Request?.Headers != null && Request.HttpContext.Request.Headers.ContainsKey(authSettings.HeaderAuthVariable)) + { + var username = Request.HttpContext.Request.Headers[authSettings.HeaderAuthVariable].ToString(); + + // Check if user exists + var user = await _userManager.FindByNameAsync(username); + if (user == null) + { + return new UnauthorizedResult(); + } + + return await CreateToken(true, user); + } + else + { + return new UnauthorizedResult(); + } + } + else + { + return new UnauthorizedResult(); + } + } } } diff --git a/src/Ombi/Controllers/V2/FeaturesController.cs b/src/Ombi/Controllers/V2/FeaturesController.cs new file mode 100644 index 000000000..16c512b8c --- /dev/null +++ b/src/Ombi/Controllers/V2/FeaturesController.cs @@ -0,0 +1,88 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using Ombi.Attributes; +using Ombi.Core.Settings; +using Ombi.Settings.Settings.Models; +using System.Collections; +using System.Collections.Generic; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; + +namespace Ombi.Controllers.V2 +{ + public class FeaturesController : V2Controller + { + private readonly ISettingsService _features; + + public FeaturesController(ISettingsService features) => _features = features; + + [HttpGet] + [AllowAnonymous] + public async Task> GetFeatures() + { + var features = await _features.GetSettingsAsync(); + return PopulateFeatures(features?.Features ?? new List()); + } + + [HttpPost("enable")] + [Admin] + public async Task> Enable([FromBody] FeatureEnablement feature) + { + var featureSettings = await _features.GetSettingsAsync(); + var features = PopulateFeatures(featureSettings?.Features ?? new List()); + var featureToUpdate = features.First(x => x.Name.Equals(feature.Name)); + featureToUpdate.Enabled = true; + + featureSettings.Features = features; + + await _features.SaveSettingsAsync(featureSettings); + + return PopulateFeatures(featureSettings?.Features ?? new List()); + } + + [HttpPost("disable")] + [Admin] + public async Task> Disable([FromBody] FeatureEnablement feature) + { + var featureSettings = await _features.GetSettingsAsync(); + var features = PopulateFeatures(featureSettings?.Features ?? new List()); + var featureToUpdate = features.First(x => x.Name.Equals(feature.Name)); + featureToUpdate.Enabled = false; + + featureSettings.Features = features; + + await _features.SaveSettingsAsync(featureSettings); + + return PopulateFeatures(featureSettings?.Features ?? new List()); + } + + + private List PopulateFeatures(List existingFeatures) + { + var supported = GetSupportedFeatures().ToList(); + if (supported.Count == existingFeatures.Count) + { + return existingFeatures; + } + var diff = supported.Except(existingFeatures.Select(x => x.Name)); + + foreach (var feature in diff) + { + existingFeatures.Add(new FeatureEnablement + { + Name = feature + }); + } + return existingFeatures; + } + + private IEnumerable GetSupportedFeatures() + { + FieldInfo[] fieldInfos = typeof(FeatureNames).GetFields(BindingFlags.Public | + BindingFlags.Static | BindingFlags.FlattenHierarchy); + + return fieldInfos.Where(fi => fi.IsLiteral && !fi.IsInitOnly && fi.FieldType == typeof(string)).Select(x => (string)x.GetValue(x)); + } + } +} diff --git a/src/Ombi/Controllers/V2/RequestsController.cs b/src/Ombi/Controllers/V2/RequestsController.cs index 0dfe48a20..6c1ca4380 100644 --- a/src/Ombi/Controllers/V2/RequestsController.cs +++ b/src/Ombi/Controllers/V2/RequestsController.cs @@ -207,15 +207,15 @@ namespace Ombi.Controllers.V2 } [PowerUser] - [HttpPost("reprocess/{type}/{requestId}")] - public async Task ReProcessRequest(RequestType type, int requestId) + [HttpPost("reprocess/{type}/{requestId}/{is4K}")] + public async Task ReProcessRequest(RequestType type, int requestId, bool? is4K) { switch (type) { case RequestType.TvShow: - return Ok(await _tvRequestEngine.ReProcessRequest(requestId, HttpContext.RequestAborted)); + return Ok(await _tvRequestEngine.ReProcessRequest(requestId, false, HttpContext.RequestAborted)); case RequestType.Movie: - return Ok(await _movieRequestEngine.ReProcessRequest(requestId, HttpContext.RequestAborted)); + return Ok(await _movieRequestEngine.ReProcessRequest(requestId, is4K ?? false, HttpContext.RequestAborted)); } return BadRequest(); diff --git a/src/Ombi/Controllers/V2/SearchController.cs b/src/Ombi/Controllers/V2/SearchController.cs index 0b58244b3..429add7c8 100644 --- a/src/Ombi/Controllers/V2/SearchController.cs +++ b/src/Ombi/Controllers/V2/SearchController.cs @@ -16,6 +16,11 @@ using Ombi.Api.RottenTomatoes.Models; using Ombi.Api.RottenTomatoes; using Ombi.Helpers; +// Due to conflicting Genre models in +// Ombi.TheMovieDbApi.Models and Ombi.Api.TheMovieDb.Models +using Genre = Ombi.TheMovieDbApi.Models.Genre; +using Ombi.TheMovieDbApi.Models; + namespace Ombi.Controllers.V2 { public class SearchController : V2Controller @@ -52,7 +57,23 @@ namespace Ombi.Controllers.V2 [HttpPost("multi/{searchTerm}")] public async Task> MultiSearch(string searchTerm, [FromBody] MultiSearchFilter filter) { - return await _multiSearchEngine.MultiSearch(searchTerm, filter, Request.HttpContext.RequestAborted); + return await _multiSearchEngine.MultiSearch(Uri.UnescapeDataString(searchTerm), filter, Request.HttpContext.RequestAborted); + } + + /// + /// Gets the genres for either Tv or Movies depending on media type + /// + /// Either `tv` or `movie`. + [HttpGet("Genres/{media}")] + public Task> GetGenres(string media) + { + return _multiSearchEngine.GetGenres(media, HttpContext.RequestAborted); + } + + [HttpGet("Languages")] + public Task> GetLanguages() + { + return _multiSearchEngine.GetLanguages(HttpContext.RequestAborted); } /// @@ -371,14 +392,14 @@ namespace Ombi.Controllers.V2 /// /// Returns trending shows by page /// - /// We use Trakt.tv as the Provider + /// We use TheMovieDb as the Provider /// [HttpGet("tv/trending/{currentPosition}/{amountToLoad}")] [ProducesResponseType(StatusCodes.Status200OK)] [ProducesDefaultResponseType] - public Task> Trending(int currentPosition, int amountToLoad) + public Task> TrendingTv(int currentPosition, int amountToLoad) { - return _mediaCacheService.GetOrAddAsync(nameof(Trending) + currentPosition + amountToLoad, + return _mediaCacheService.GetOrAddAsync(nameof(TrendingTv) + currentPosition + amountToLoad, () => _tvEngineV2.Trending(currentPosition, amountToLoad), DateTimeOffset.Now.AddHours(12)); } @@ -395,6 +416,19 @@ namespace Ombi.Controllers.V2 { return await _movieEngineV2.GetMoviesByActor(actorId, null); } + + /// + /// Returns all the tv shows that is by the actor id + /// + /// TheMovieDb Actor ID + /// + [HttpGet("actor/{actorId}/tv")] + [ProducesResponseType(StatusCodes.Status200OK)] + [ProducesDefaultResponseType] + public async Task GetTvByActor(int actorId) + { + return await _tvEngineV2.GetTvByActor(actorId, null); + } [HttpGet("artist/{artistId}")] diff --git a/src/Ombi/Extensions/DatabaseExtensions.cs b/src/Ombi/Extensions/DatabaseExtensions.cs index 70bd8c70e..a96011f1c 100644 --- a/src/Ombi/Extensions/DatabaseExtensions.cs +++ b/src/Ombi/Extensions/DatabaseExtensions.cs @@ -120,9 +120,9 @@ namespace Ombi.Extensions public static void ConfigureMySql(DbContextOptionsBuilder options, PerDatabaseConfiguration config) { - options.UseMySql(config.ConnectionString, b => + options.UseMySql(config.ConnectionString, ServerVersion.AutoDetect(config.ConnectionString), b => { - b.CharSetBehavior(Pomelo.EntityFrameworkCore.MySql.Infrastructure.CharSetBehavior.NeverAppend); + //b.CharSetBehavior(Pomelo.EntityFrameworkCore.MySql.Infrastructure.CharSetBehavior.NeverAppend); // ##ISSUE, link to migrations? b.EnableRetryOnFailure(); }); } diff --git a/src/Ombi/Extensions/StartupExtensions.cs b/src/Ombi/Extensions/StartupExtensions.cs index e3253045a..227085e07 100644 --- a/src/Ombi/Extensions/StartupExtensions.cs +++ b/src/Ombi/Extensions/StartupExtensions.cs @@ -41,6 +41,21 @@ namespace Ombi Type = SecuritySchemeType.ApiKey }); + c.AddSecurityRequirement(new OpenApiSecurityRequirement + { + { + new OpenApiSecurityScheme + { + Reference = new OpenApiReference + { + Type = ReferenceType.SecurityScheme, + Id = "ApiKey" + } + }, + new string[] {} + } + }); + c.CustomSchemaIds(x => x.FullName); try @@ -64,6 +79,8 @@ namespace Ombi c.DescribeAllParametersInCamelCase(); }); + + services.AddSwaggerGenNewtonsoftSupport(); } public static void AddAppSettingsValues(this IServiceCollection services, IConfigurationRoot configuration) diff --git a/src/Ombi/Models/MovieUpdateModel.cs b/src/Ombi/Models/MovieUpdateModel.cs index db52d4f2b..72638db98 100644 --- a/src/Ombi/Models/MovieUpdateModel.cs +++ b/src/Ombi/Models/MovieUpdateModel.cs @@ -29,5 +29,6 @@ namespace Ombi.Core.Models.Requests public class MovieUpdateModel { public int Id { get; set; } + public bool Is4K { get; set; } } } \ No newline at end of file diff --git a/src/Ombi/Ombi.csproj b/src/Ombi/Ombi.csproj index 063dc65db..f0091002a 100644 --- a/src/Ombi/Ombi.csproj +++ b/src/Ombi/Ombi.csproj @@ -1,6 +1,6 @@  - net5.0 + net6.0 win10-x64;win10-x86;osx-x64;linux-x64;linux-arm;linux-arm64; false Latest @@ -62,27 +62,29 @@ - - + + runtime; build; native; contentfiles; analyzers; buildtransitive all - + - - + + - - + + - + + + - - + + @@ -95,6 +97,7 @@ + @@ -104,7 +107,7 @@ - + diff --git a/src/Ombi/Program.cs b/src/Ombi/Program.cs index 7f7a875d1..ff7723703 100644 --- a/src/Ombi/Program.cs +++ b/src/Ombi/Program.cs @@ -68,7 +68,9 @@ namespace Ombi var services = new ServiceCollection(); services.ConfigureDatabases(null); +#pragma warning disable ASP0000 // Do not call 'IServiceCollection.BuildServiceProvider' in 'ConfigureServices' using var provider = services.BuildServiceProvider(); +#pragma warning restore ASP0000 // Do not call 'IServiceCollection.BuildServiceProvider' in 'ConfigureServices' var settingsDb = provider.GetRequiredService(); var ombiDb = provider.GetRequiredService(); diff --git a/src/Ombi/Properties/launchSettings.json b/src/Ombi/Properties/launchSettings.json index 213b92518..b3899f8c3 100644 --- a/src/Ombi/Properties/launchSettings.json +++ b/src/Ombi/Properties/launchSettings.json @@ -22,7 +22,7 @@ }, "Ombi": { "commandName": "Project", - "commandLineArgs": "--host http://localhost:3577 --demo true", + "commandLineArgs": "--host http://localhost:3577", "environmentVariables": { "ASPNETCORE_ENVIRONMENT": "Development" }, diff --git a/src/Ombi/Startup.cs b/src/Ombi/Startup.cs index 95fd6447f..9fe01019e 100644 --- a/src/Ombi/Startup.cs +++ b/src/Ombi/Startup.cs @@ -49,7 +49,7 @@ namespace Ombi Configuration = builder.Build(); ILogger config = new LoggerConfiguration() - .MinimumLevel.Debug() + .ReadFrom.Configuration(Configuration) .WriteTo.RollingFile(Path.Combine(StoragePath.StoragePath.IsNullOrEmpty() ? env.ContentRootPath : StoragePath.StoragePath, "Logs", "log-{Date}.txt")) .CreateLogger(); @@ -109,7 +109,7 @@ namespace Ombi .AllowCredentials(); })); - services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Latest); + services.AddMvc(); services.AddSignalR(); services.AddSpaStaticFiles(configuration => configuration.RootPath = "ClientApp/dist"); diff --git a/src/Ombi/Views/Shared/_Layout.cshtml b/src/Ombi/Views/Shared/_Layout.cshtml index 5cee9c275..3cd9ccc56 100644 --- a/src/Ombi/Views/Shared/_Layout.cshtml +++ b/src/Ombi/Views/Shared/_Layout.cshtml @@ -23,6 +23,12 @@ appName = "Ombi"; } + var favicon = customization.Favicon; + if (string.IsNullOrEmpty(favicon)) + { + favicon = "images/favicon/favicon.ico"; + } + } diff --git a/src/Ombi/appsettings.Development.json b/src/Ombi/appsettings.Development.json index 645fb3aaa..0a2a2974c 100644 --- a/src/Ombi/appsettings.Development.json +++ b/src/Ombi/appsettings.Development.json @@ -8,5 +8,8 @@ "System.Net.Http.HttpClient.health-checks": "Information", "HealthChecks": "Information" } + }, + "Serilog": { + "MinimumLevel": "Debug" } } diff --git a/src/Ombi/appsettings.json b/src/Ombi/appsettings.json index 869428806..b27b627a9 100644 --- a/src/Ombi/appsettings.json +++ b/src/Ombi/appsettings.json @@ -10,6 +10,9 @@ "HealthChecks": "Warning" } }, + "Serilog": { + "MinimumLevel": "Information" + }, "ApplicationSettings": { "NotificationService": "https://ombinotifications.azurewebsites.net/api/", "OmbiService": "?" diff --git a/src/Ombi/wwwroot/images/trakt.svg b/src/Ombi/wwwroot/images/trakt.svg new file mode 100644 index 000000000..782305d6a --- /dev/null +++ b/src/Ombi/wwwroot/images/trakt.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/Ombi/wwwroot/translations/bg.json b/src/Ombi/wwwroot/translations/bg.json index 01a16bcce..95332204e 100644 --- a/src/Ombi/wwwroot/translations/bg.json +++ b/src/Ombi/wwwroot/translations/bg.json @@ -14,18 +14,26 @@ "Common": { "ContinueButton": "Продължаване", "Available": "Налично", - "Approved": "Approved", + "Available4K": "Available 4K", + "Approved": "Одобрени", + "Approve4K": "Approve 4K", "Pending": "Pending", "PartiallyAvailable": "Частично налично", "Monitored": "Наблюдавано", "NotAvailable": "Не е налично", "ProcessingRequest": "Обработване на заявката", + "ProcessingRequest4K": "Processing Request 4K", "PendingApproval": "Чака одобрение", + "PendingApproval4K": "Pending Approval 4K", "RequestDenied": "Заявката е отказана", + "RequestDenied4K": "Request Denied 4K", "NotRequested": "Не е заявено", + "NotRequested4K": "Not Requested 4K", "Requested": "Заявено", + "Requested4K": "Requested 4K", "Search": "Търсене", "Request": "Заявка", + "Request4K": "Request 4K", "Denied": "Отказано", "Approve": "Одобряване", "PartlyAvailable": "Частично налично", @@ -55,6 +63,10 @@ "OfflineParagraph": "Медийният сървър в момента е извън линия.", "CheckPageForUpdates": "Проверете тази страница за последни новини на сайта." }, + "ErrorPages": { + "NotFound": "Page not found", + "SomethingWentWrong": "Something went wrong!" + }, "NavigationBar": { "Discover": "Открийте", "Search": "Търсене", @@ -131,6 +143,9 @@ }, "AdvancedSearchInstructions": "Please choose what type of media you are searching for:", "YearOfRelease": "Year of Release", + "SearchGenre": "Search Genre", + "SearchKeyword": "Search Keyword", + "SearchProvider": "Search Provider", "KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb" }, "Requests": { @@ -155,9 +170,13 @@ "ChangeRootFolder": "Основна папка", "ChangeQualityProfile": "Профил на качеството", "MarkUnavailable": "Означаване като неналично", + "MarkUnavailable4K": "Mark Unavailable 4K", "MarkAvailable": "Означаване като налично", + "MarkAvailable4K": "Mark Available 4K", "Remove": "Премахване", "Deny": "Отказване", + "Deny4K": "Deny 4K", + "Has4KRequest": "Has 4K Request", "DenyReason": "Причина за отхвърляне", "DeniedReason": "Причина за отхвърляне", "Season": "Сезон", @@ -193,11 +212,16 @@ "RequestPanel": { "Delete": "Изтриване на заявка", "Approve": "Одобряване на заявка", + "Deny": "Deny Request", + "Approve4K": "Approve 4K Request", + "Deny4K": "Deny 4K Request", "ChangeAvailability": "Маркиране като налично", "Deleted": "Избраните елементи са изтрити успешно", - "Approved": "Избраните елементи са одобрени успешно" + "Approved": "Избраните елементи са одобрени успешно", + "Denied": "Successfully denied selected items" }, "SuccessfullyApproved": "Successfully Approved", + "SuccessfullyDeleted": "Request successfully deleted", "NowAvailable": "Request is now available", "NowUnavailable": "Request is now unavailable", "SuccessfullyReprocessed": "Successfully Re-processed the request", @@ -205,7 +229,7 @@ "RequestCollection": "Request Collection", "CollectionSuccesfullyAdded": "The collection {{name}} has been successfully added!", "NeedToSelectEpisodes": "You need to select some episodes!", - "RequestAddedSuccessfully": "Request for {{title}} has been added successfully", + "RequestAddedSuccessfully": "Заявката за {{title}} е успешно добавена", "ErrorCodes": { "AlreadyRequested": "This has already been requested", "EpisodesAlreadyRequested": "We already have episodes requested from this series", @@ -219,10 +243,16 @@ "MovieRequestQuotaExceeded": "You have exceeded your Movie request quota!", "TvRequestQuotaExceeded": "You have exceeded your Episode request quota!", "AlbumRequestQuotaExceeded": "You have exceeded your Album request quota!" - } + }, + "Notify": "Notify", + "RemoveNotification": "Remove Notifications", + "SuccessfulNotify": "You will now be notified for title {{title}}", + "SuccessfulUnNotify": "You will no longer be notified for title {{title}}", + "CouldntNotify": "Couldn't notify title {{title}}" }, "Issues": { "Title": "Проблеми", + "IssuesForTitle": "Issues for {{title}}", "PendingTitle": "Нерешени проблеми", "InProgressTitle": "Проблеми в процес на изпълнение", "ResolvedTitle": "Решени проблеми", @@ -255,6 +285,7 @@ "Delete": "Изтриване на проблем", "DeletedIssue": "Проблемът е изтрит", "Chat": "Чат", + "EnterYourMessage": "Enter Your Message", "Requested": "Заявено", "UserOnDate": "{{user}} on {{date}}" }, @@ -281,6 +312,8 @@ }, "MediaDetails": { "Denied": "Отказано", + "Denied4K": "Denied 4K", + "Trailers": "Trailers", "RecommendationsTitle": "Препоръчани", "SimilarTitle": "Подобни", "VideosTitle": "Видеоклипове", @@ -291,13 +324,13 @@ "ViewCollection": "Преглед на колекцията", "NotEnoughInfo": "За съжаление все още няма достатъчно информация за това предаване!", "AdvancedOptions": "Разширени настройки", - "AutoApproveOptions": "Можете да конфигурирате заявката си тук. След като бъде създадена, тя ще бъде изпратена до вашето записващо приложение (DVR) и ще бъде автоматично одобрена! Моля, обърнете внимание, че тази стъпка не е задължителна и можете да натиснете бутона Заявка за да я пропуснете!", - "AutoApproveOptionsTv": "Можете да конфигурирате заявката си тук. След като бъде създадена, тя ще бъде изпратена до вашето записващо приложение (DVR) и ще бъде автоматично одобрена! Ако заявката вече е обработена от Sonarr, програмата няма да промени основната папка или профила на качеството ако сте ги задали. Моля, обърнете внимание, че тази стъпка не е задължителна и можете да натиснете бутона Заявка за да я пропуснете!", - "AutoApproveOptionsTvShort": "Можете да конфигурирате заявката си тук. След като бъде създадена, тя ще бъде изпратена до вашето записващо приложение (DVR)! Ако заявката вече е обработена от Sonarr, програмата няма да промени основната папка или профила на качеството ако сте ги задали. Моля, обърнете внимание, че тази стъпка не е задължителна и можете да натиснете бутона Заявка за да я пропуснете!", + "AutoApproveOptions": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTv": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be sent to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", "QualityProfilesSelect": "Изберете профил на качеството", "RootFolderSelect": "Изберете основна папка", "LanguageProfileSelect": "Изберете езиков профил", - "Status": "Status:", + "Status": "Състояние:", "StatusValues": { "Rumored": "Rumored", "Planned": "Planned", @@ -311,22 +344,23 @@ }, "Seasons": "Seasons:", "Episodes": "Episodes:", - "Availability": "Availability:", - "RequestStatus": "Състояние на заявката", - "Quality": "Quality:", - "RootFolderOverride": "Root Folder Override:", - "QualityOverride": "Quality Override:", - "Network": "Network:", - "Genres": "Genres:", - "FirstAired": "First Aired:", - "TheatricalRelease": "Release:", - "DigitalRelease": "Digital Release:", - "Votes": "Votes:", - "Runtime": "Runtime:", + "Availability": "Наличност:", + "RequestStatus": "Request Status:", + "Quality": "Качество:", + "RootFolderOverride": "Ръчно задаване на основната папка:", + "QualityOverride": "Ръчно задаване на качеството:", + "Network": "Мрежа:", + "GenresLabel": "Жанрове:", + "Genres": "Жанрове", + "FirstAired": "Първо излъчено:", + "TheatricalRelease": "Кино премиера:", + "DigitalRelease": "Дигитална версия:", + "Votes": "Гласове:", + "Runtime": "Продължителност:", "Minutes": "{{runtime}} Минути", - "Revenue": "Revenue:", - "Budget": "Budget:", - "Keywords": "Keywords/Tags:", + "Revenue": "Приходи:", + "Budget": "Бюджет:", + "Keywords": "Ключови думи/тагове:", "Casts": { "CastTitle": "В ролите" }, @@ -335,23 +369,26 @@ "FirstSeasonTooltip": "Това ще заяви само първия сезон на това предаване", "LatestSeasonTooltip": "Това ще заяви само последния сезон на това предаване", "NoEpisodes": "За съжаление все още няма данни за епизоди на това предаване!", - "SeasonNumber": "Season {{number}}" + "SeasonNumber": "Сезон {{number}}" }, "SonarrConfiguration": "Конфигурация на Sonarr", "RadarrConfiguration": "Конфигурация на Radarr", "RequestOnBehalf": "Заявете от името на", "PleaseSelectUser": "Моля, изберете потребител", - "StreamingOn": "Streaming On:", - "RequestedBy": "Requested By:", - "RequestDate": "Request Date:", - "DeniedReason": "Denied Reason:", + "StreamingOn": "Поточното изпълнение е включено:", + "RequestedBy": "Заявено от:", + "RequestedByOn": "Requested By {{user}} on {{date}}", + "RequestDate": "Дата на заявка:", + "DeniedReason": "Причина за отхвърляне:", "ReProcessRequest": "Повтаряне на заявка", + "ReProcessRequest4K": "Re-Process 4K Request", "Music": { "Type": "Type:", "Country": "Country:", "StartDate": "Start Date:", "EndDate": "EndDate:" - } + }, + "RequestSource": "Source:" }, "Discovery": { "PopularTab": "Популярни", @@ -382,7 +419,7 @@ "DarkMode": "Тъмен режим", "Updated": "Обновяването е успешно", "StreamingCountry": "Страна на поточно предаване", - "StreamingCountryDescription": "Това е кодът на държавата, за който ще показваме поточна информация. Ако сте в САЩ, моля изберете САЩ и ще имате поточна информация, свързана със САЩ.", + "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will get US related streaming information.", "LanguageDescription": "Това е езикът, на който искате да се показва интерфейсът на Ombi.", "MobileQRCode": "Мобилен QR код", "LegacyApp": "Стартирайте старото приложение", @@ -391,12 +428,13 @@ "ChangeDetails": "Change Details", "NeedCurrentPassword": "You need your current password to make any changes here", "CurrentPassword": "Current Password", - "EmailAddress": "Email Address", + "EmailAddress": "Електронна поща", "NewPassword": "New Password", "NewPasswordConfirm": "New Password Confirm", "Security": "Security", "Profile": "Profile", - "UpdatedYourInformation": "Updated your information" + "UpdatedYourInformation": "Updated your information", + "Unsubscribed": "Unsubscribed!" }, "UserTypeLabel": { "1": "Local User", @@ -404,5 +442,14 @@ "3": "Emby User", "4": "Emby Connect User", "5": "Jellyfin User" + }, + "Paginator": { + "itemsPerPageLabel": "Items per page:", + "nextPageLabel": "Next page", + "previousPageLabel": "Previous page", + "firstPageLabel": "First page", + "lastPageLabel": "Last page", + "rangePageLabel1": "0 of {{length}}", + "rangePageLabel2": "{{startIndex}} – {{endIndex}} of {{length}}" } } diff --git a/src/Ombi/wwwroot/translations/cs.json b/src/Ombi/wwwroot/translations/cs.json new file mode 100644 index 000000000..42849dc44 --- /dev/null +++ b/src/Ombi/wwwroot/translations/cs.json @@ -0,0 +1,455 @@ +{ + "Login": { + "SignInButton": "Přihlásit se", + "UsernamePlaceholder": "Uživatelské jméno", + "PasswordPlaceholder": "Heslo", + "RememberMe": "Zapamatovat si mě", + "SignInWith": "Přihlásit se pomocí {{appName}}", + "SignInWithPlex": "Přihlásit se přes Plex", + "ForgottenPassword": "Zapomněli jste heslo?", + "Errors": { + "IncorrectCredentials": "Nesprávné uživatelské jméno nebo heslo" + } + }, + "Common": { + "ContinueButton": "Pokračovat", + "Available": "Dostupný", + "Available4K": "4K Dostupné", + "Approved": "Schváleno", + "Approve4K": "Schválit 4K", + "Pending": "Čeká na vyřízení", + "PartiallyAvailable": "Částečně dostupné", + "Monitored": "Monitorováno", + "NotAvailable": "Není k dispozici", + "ProcessingRequest": "Zpracovávání žádosti", + "ProcessingRequest4K": "Processing Request 4K", + "PendingApproval": "Čeká na schválení", + "PendingApproval4K": "Pending Approval 4K", + "RequestDenied": "Žádost zamítnuta", + "RequestDenied4K": "Request Denied 4K", + "NotRequested": "Nevyžádáno", + "NotRequested4K": "Not Requested 4K", + "Requested": "Vyžádáno", + "Requested4K": "Požádáno o 4K", + "Search": "Hledat", + "Request": "Žádost", + "Request4K": "Požádat o 4K", + "Denied": "Zamítnuto", + "Approve": "Schválit", + "PartlyAvailable": "Částečně k dispozici", + "ViewDetails": "Zobrazit Podrobnosti", + "Errors": { + "Validation": "Zkontrolujte prosím zadané hodnoty" + }, + "Cancel": "Zrušit", + "Submit": "Potvrdit", + "Update": "Upravit", + "tvShow": "TV Pořad", + "movie": "Film", + "album": "Album" + }, + "PasswordReset": { + "EmailAddressPlaceholder": "Emailová Adresa", + "ResetPasswordButton": "Obnovit Heslo" + }, + "LandingPage": { + "OnlineHeading": "Právě Online", + "OnlineParagraph": "Server je momentálně offline", + "PartiallyOnlineHeading": "Částečně online", + "PartiallyOnlineParagraph": "Mediální server je částečně online.", + "MultipleServersUnavailable": "There are {{serversUnavailable}} servers offline out of {{totalServers}}.", + "SingleServerUnavailable": "There is {{serversUnavailable}} server offline out of {{totalServers}}.", + "OfflineHeading": "Currently Offline", + "OfflineParagraph": "The media server is currently offline.", + "CheckPageForUpdates": "Check this page for continuous site updates." + }, + "ErrorPages": { + "NotFound": "Stránka nenalezena", + "SomethingWentWrong": "Something went wrong!" + }, + "NavigationBar": { + "Discover": "Objevit nové", + "Search": "Hledat", + "Requests": "Žádosti", + "UserManagement": "Uživatelé", + "Issues": "Problémy", + "Vote": "Hlasuj", + "Donate": "Přispějte!", + "DonateLibraryMaintainer": "Podpořte správce knihovny", + "DonateTooltip": "This is how I convince my wife to let me spend my spare time developing Ombi 😁", + "UpdateAvailableTooltip": "Update Available!", + "Settings": "Nastavení", + "Welcome": "Vítejte zpět, {{username}}!", + "UpdateDetails": "Upravit detaily", + "Logout": "Odhlásit se", + "OpenMobileApp": "Otevřít mobilní aplikaci", + "RecentlyAdded": "Naposledy přidané", + "ChangeTheme": "Změnit motiv", + "Calendar": "Kalendář", + "UserPreferences": "Nastavení", + "FeatureSuggestion": "Funkce", + "FeatureSuggestionTooltip": "Have a great new idea? Suggest it here!", + "Filter": { + "Movies": "Filmy", + "TvShows": "TV pořady", + "Music": "Hudba", + "People": "Lidé" + }, + "MorningWelcome": "Dobré ráno!", + "AfternoonWelcome": "Dobré odpoledne!", + "EveningWelcome": "Dobrý večer!" + }, + "Search": { + "Title": "Hledat", + "Paragraph": "Chcete sledovat něco co je aktuálně nedostupné? Není problém, zkuste to najít a požádat o to!", + "MoviesTab": "Filmy", + "TvTab": "TV pořady", + "MusicTab": "Hudba", + "AdvancedSearch": "Můžete vyplnit některou z níže uvedených možností pro objevení nových médií. Všechny výsledky jsou seřazeny podle oblíbenosti", + "AdvancedSearchHeader": "Pokročilé vyhledávání", + "Suggestions": "Návrhy", + "NoResults": "Omlouváme se, ale nenašli jsme žádné výsledky!", + "DigitalDate": "Digitální vydání: {{date}}", + "TheatricalRelease": "V kinech: {{date}}", + "ViewOnPlex": "Přehrát v Plex", + "ViewOnEmby": "Přehrát v Emby", + "ViewOnJellyfin": "Přehrát v Jellyfiny", + "RequestAdded": "Žádost o {{title}} byl úspěšně přidán", + "Similar": "Podobné", + "Refine": "Zpřesnit", + "SearchBarPlaceholder": "Pište sem pro vyhledávání", + "Movies": { + "PopularMovies": "Populární filmy", + "UpcomingMovies": "Nadcházející filmy", + "TopRatedMovies": "Nejlépe hodnocené filmy", + "NowPlayingMovies": "Právě hrajeme", + "HomePage": "Úvodní stránka", + "Trailer": "Upoutávka" + }, + "TvShows": { + "Popular": "Oblíbené", + "Trending": "Žhavé", + "MostWatched": "Nejsledovanější", + "MostAnticipated": "Nejočekávanější", + "Results": "Výsledky", + "AirDate": "Odvysíláno:", + "AllSeasons": "Všechny série", + "FirstSeason": "První série", + "LatestSeason": "Nejnovější série", + "Select": "Vyberte ...", + "SubmitRequest": "Odeslat žádost", + "Season": "Série {{seasonNumber}}", + "SelectAllInSeason": "Vybrat vše v sérii {{seasonNumber}}" + }, + "AdvancedSearchInstructions": "Vyberte prosím jaký typ médií hledáte:", + "YearOfRelease": "Rok vydání", + "SearchGenre": "Vyhledávání podle žánru", + "SearchKeyword": "Vyhledávání podle klíčových slov", + "SearchProvider": "Search Provider", + "KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb" + }, + "Requests": { + "Title": "Žádosti", + "Paragraph": "Below you can see yours and all other requests, as well as their download and approval status.", + "MoviesTab": "Filmy", + "ArtistName": "Umělec", + "AlbumName": "Název alba", + "TvTab": "TV pořady", + "MusicTab": "Hudba", + "RequestedBy": "Požadováno od", + "Status": "Stav", + "RequestStatus": "Stav požadavku", + "Denied": " Zamítnuto:", + "TheatricalRelease": "V kinech od: {{date}}", + "ReleaseDate": "Vydáno: {{date}}", + "TheatricalReleaseSort": "Vydáno v Kinech", + "DigitalRelease": "Digitální vydání: {{date}}", + "RequestDate": "Datum požadavku", + "QualityOverride": "Quality Override:", + "RootFolderOverride": "Root Folder Override:", + "ChangeRootFolder": "Root Folder", + "ChangeQualityProfile": "Quality Profile", + "MarkUnavailable": "Označit jako nedostupné", + "MarkUnavailable4K": "Označit jako nedostupné ve 4K", + "MarkAvailable": "Označit jako dostupné", + "MarkAvailable4K": "Označit jako dostupné ve 4K", + "Remove": "Odstranit", + "Deny": "Zamítnout", + "Deny4K": "Zamítnout 4 K", + "Has4KRequest": "Má 4K požadavek", + "DenyReason": "Důvod zamítnutí", + "DeniedReason": "Důvod zamítnutí", + "Season": "Série", + "GridTitle": "Název", + "AirDate": "Odvysíláno", + "GridStatus": "Stav", + "ReportIssue": "Nahlásit problém", + "Filter": "Třídit", + "Sort": "Seřadit", + "SeasonNumberHeading": "Série: {{seasonNumber}}", + "SortTitleAsc": "Název ▲", + "SortTitleDesc": "Název ▼", + "SortRequestDateAsc": "Datum žádosti ▲", + "SortRequestDateDesc": "Datum žádosti ▼", + "SortStatusAsc": "Stav ▲", + "SortStatusDesc": "Stav ▼", + "Remaining": { + "Quota": "Zbývá {{remaining}}/{{total}} požadavků", + "NextDays": "Another request will be added in {{time}} days", + "NextHours": "Another request will be added in {{time}} hours", + "NextMinutes": "Another request will be added in {{time}} minutes", + "NextMinute": "Another request will be added in {{time}} minute" + }, + "AllRequests": "Všechny požadavky", + "PendingRequests": "Nevyřízené požadavky", + "ProcessingRequests": "Zpracovávání požadavku", + "AvailableRequests": "Dostupné požadavky", + "DeniedRequests": "Zamítnuté požadavky", + "RequestsToDisplay": "Požadavky na zobrazení", + "RequestsTitle": "Název", + "Details": "Podrobnosti", + "Options": "Možnosti", + "RequestPanel": { + "Delete": "Odstranit požadavek", + "Approve": "Schválit požadavek", + "Deny": "Deny Request", + "Approve4K": "Schválit 4K požadavek", + "Deny4K": "Deny 4K Request", + "ChangeAvailability": "Označit jako dostupné", + "Deleted": "Vybrané položky úspěšně odstraněny", + "Approved": "Vybrané položky byly úspěšně schváleny", + "Denied": "Successfully denied selected items" + }, + "SuccessfullyApproved": "Úspěšně schváleno", + "SuccessfullyDeleted": "Požadavek byl úspěšně odstraněn", + "NowAvailable": "Požadavek je nyní k dispozici", + "NowUnavailable": "Požadavek je nyní nedostupný", + "SuccessfullyReprocessed": "Požadavek úspěšně znovu zprocesován", + "DeniedRequest": "Odmítnutý požadavek", + "RequestCollection": "Požádat o kolekci", + "CollectionSuccesfullyAdded": "Kolekce {{name}} byla úspěšně přidána!", + "NeedToSelectEpisodes": "Musíte vybrat nějaké epizody!", + "RequestAddedSuccessfully": "Žádost o {{title}} byla úspěšně přidána", + "ErrorCodes": { + "AlreadyRequested": "O toto již bylo požádáno", + "EpisodesAlreadyRequested": "Již máme epizody od této série vyžádány", + "NoPermissionsOnBehalf": "You do not have the correct permissions to request on behalf of users!", + "NoPermissions": "Nemáte dostatečná oprávnění!", + "RequestDoesNotExist": "Požadavek neexistuje", + "ChildRequestDoesNotExist": "Child Request does not exist", + "NoPermissionsRequestMovie": "Nemáte oprávnění k vyžádání filmu", + "NoPermissionsRequestTV": "Nemáte oprávnění požádat o TV Pořad", + "NoPermissionsRequestAlbum": "You do not have permissions to Request an Album", + "MovieRequestQuotaExceeded": "You have exceeded your Movie request quota!", + "TvRequestQuotaExceeded": "You have exceeded your Episode request quota!", + "AlbumRequestQuotaExceeded": "You have exceeded your Album request quota!" + }, + "Notify": "Notify", + "RemoveNotification": "Remove Notifications", + "SuccessfulNotify": "You will now be notified for title {{title}}", + "SuccessfulUnNotify": "You will no longer be notified for title {{title}}", + "CouldntNotify": "Couldn't notify title {{title}}" + }, + "Issues": { + "Title": "Issues", + "IssuesForTitle": "Issues for {{title}}", + "PendingTitle": "Pending Issues", + "InProgressTitle": "In Progress Issues", + "ResolvedTitle": "Resolved Issues", + "ColumnTitle": "Název", + "Count": "Počet", + "Category": "Kategorie", + "Status": "Stav", + "Details": "Podrobnosti", + "Description": "Popis", + "NoComments": "Žádné komentáře!", + "MarkInProgress": "Označit jako probíhající", + "MarkResolved": "Označit jako vyřešené", + "SendMessageButton": "Odeslat", + "Subject": "Předmět", + "Comments": "Komentáře", + "WriteMessagePlaceholder": "Sem napište zprávu…", + "ReportedBy": "Nahlášeno", + "IssueDialog": { + "Title": "Náhlásit chybu", + "DescriptionPlaceholder": "Popište problém", + "TitlePlaceholder": "Krátký název vašeho problému", + "SelectCategory": "Vybrat kategorii", + "IssueCreated": "Problém byl vytvořen" + }, + "Outstanding": "There are outstanding issues", + "ResolvedDate": "Resolved date", + "CreatedDate": "Raised on", + "MarkedAsResolved": "This issue has now been marked as resolved!", + "MarkedAsInProgress": "This issue has now been marked as in progress!", + "Delete": "Smazat případ", + "DeletedIssue": "Issue has been deleted", + "Chat": "Chat", + "EnterYourMessage": "Enter Your Message", + "Requested": "Vyžádáno", + "UserOnDate": "{{user}} dne {{date}}" + }, + "Filter": { + "ClearFilter": "Zrušit filtry", + "FilterHeaderAvailability": "Dostupnost", + "FilterHeaderRequestStatus": "Stav", + "Approved": "Schváleno", + "PendingApproval": "Čeká na schválení", + "WatchProviders": "Online poskytovatelé", + "Keywords": "Klíčová slova" + }, + "UserManagment": { + "TvRemaining": "TV: {{remaining}}/{{total}} zbývá", + "MovieRemaining": "Filmy: {{remaining}}/{{total}} zbývá", + "MusicRemaining": "Hudba: {{remaining}}/{{total}} zbývá", + "TvDue": "TV: {{date}}", + "MovieDue": "Film: {{date}}", + "MusicDue": "Hudba: {{date}}" + }, + "Votes": { + "CompletedVotesTab": "Odhlasováno", + "VotesTab": "Potřebné hlasy" + }, + "MediaDetails": { + "Denied": "Zamítnuto", + "Denied4K": "4K Zamítnuto", + "Trailers": "Upoutávky", + "RecommendationsTitle": "Doporučení", + "SimilarTitle": "Podobné", + "VideosTitle": "Videa", + "AlbumsTitle": "Alba", + "RequestAllAlbums": "Požádat o všechna alba", + "ClearSelection": "Vyčistit výběr", + "RequestSelectedAlbums": "Požádat o vybraná alba", + "ViewCollection": "Zobrazit kolekci", + "NotEnoughInfo": "Bohužel o tomto seriálu zatím není dostatek informací!", + "AdvancedOptions": "Pokročilá nastavení", + "AutoApproveOptions": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTv": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be sent to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "QualityProfilesSelect": "Vyberte Profil kvality", + "RootFolderSelect": "Vyberte kořenovou složku", + "LanguageProfileSelect": "Vyberte jazykový profil", + "Status": "Stav:", + "StatusValues": { + "Rumored": "Rumored", + "Planned": "Naplánováno", + "In Production": "V produkci", + "Post Production": "V post-produkci", + "Released": "Vydáno", + "Running": "Právě probíhá", + "Returning Series": "Vracející se seriál", + "Ended": "Ukončeno", + "Canceled": "Zrušeno" + }, + "Seasons": "Série:", + "Episodes": "Epizody:", + "Availability": "Dostupnost:", + "RequestStatus": "Request Status:", + "Quality": "Kvalita:", + "RootFolderOverride": "Root Folder Override:", + "QualityOverride": "Quality Override:", + "Network": "Síť:", + "GenresLabel": "Žánry:", + "Genres": "Žánry", + "FirstAired": "Poprvé vysíláno:", + "TheatricalRelease": "Vydáno:", + "DigitalRelease": "Digitální vydání:", + "Votes": "Hlasy:", + "Runtime": "Délka:", + "Minutes": "{{runtime}} minut", + "Revenue": "Příjmy:", + "Budget": "Rozpočet:", + "Keywords": "Klíčová slova/Tagy:", + "Casts": { + "CastTitle": "Hrají" + }, + "EpisodeSelector": { + "AllSeasonsTooltip": "Toto vyžádá všechny serie pro tento pořad", + "FirstSeasonTooltip": "Toto vyžádá jen první sérii pro tento pořad", + "LatestSeasonTooltip": "Toto vyžádá jen poslední sérii pro tento pořad", + "NoEpisodes": "There unfortunately is no episode data for this show yet!", + "SeasonNumber": "Série {{number}}" + }, + "SonarrConfiguration": "Sonarr Configuration", + "RadarrConfiguration": "Radarr Configuration", + "RequestOnBehalf": "Request on behalf of", + "PleaseSelectUser": "Please select a user", + "StreamingOn": "Streamuje na:", + "RequestedBy": "Požadováno od:", + "RequestedByOn": "Požádáno uživatelem {{user}} dne {{date}}", + "RequestDate": "Datum požadavku:", + "DeniedReason": "Důvod zamítnutí:", + "ReProcessRequest": "Znovu zpracovat žádost", + "ReProcessRequest4K": "Znovu zpracovat 4K žádost", + "Music": { + "Type": "Typ:", + "Country": "Stát:", + "StartDate": "Datum zahájení:", + "EndDate": "Datum ukončení:" + }, + "RequestSource": "Source:" + }, + "Discovery": { + "PopularTab": "Oblíbené", + "TrendingTab": "Žhavé", + "UpcomingTab": "Nadcházející", + "SeasonalTab": "Sezónní", + "RecentlyRequestedTab": "Nedávno vyžádané", + "Movies": "Filmy", + "Combined": "Kombinované", + "Tv": "TV", + "CardDetails": { + "Availability": "Dostupnost", + "Studio": "Studio", + "Network": "Síť", + "UnknownNetwork": "Neznámé", + "RequestStatus": "Stav požadavku", + "Director": "Režisér", + "InCinemas": "V Kinech", + "FirstAired": "Poprvé vysíláno", + "Writer": "Autor", + "ExecProducer": "Exekutivní Producent" + }, + "NoSearch": "Vašemu hledání neodpovídají žádné shody!" + }, + "UserPreferences": { + "Welcome": "Vítejte, {{username}}!", + "OmbiLanguage": "Jazyk", + "DarkMode": "Tmavý režim", + "Updated": "Úspěšně upraveno", + "StreamingCountry": "Streaming Country", + "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will get US related streaming information.", + "LanguageDescription": "This is the language you would like the Ombi interface to be displayed in.", + "MobileQRCode": "Mobilní QR Code", + "LegacyApp": "Launch Legacy App", + "NoQrCode": "Pro povolení QR kódů kontaktujte svého administrátora", + "UserType": "Typ uživatele:", + "ChangeDetails": "Změnit podrobnosti", + "NeedCurrentPassword": "K provedení změn potřebujete své současné heslo", + "CurrentPassword": "Aktuální heslo", + "EmailAddress": "Emailová Adresa", + "NewPassword": "Nové heslo", + "NewPasswordConfirm": "Potvrzení nového hesla", + "Security": "Bezpečnost", + "Profile": "Profil", + "UpdatedYourInformation": "Informace aktualizovány", + "Unsubscribed": "Odhlášeno!" + }, + "UserTypeLabel": { + "1": "Místní Uživatel", + "2": "Plex uživatel", + "3": "Emby User", + "4": "Emby Connect uživatel", + "5": "Jellyfin uživatel" + }, + "Paginator": { + "itemsPerPageLabel": "Položek na stránce:", + "nextPageLabel": "Další stránka", + "previousPageLabel": "Předchozí stránka", + "firstPageLabel": "První stránka", + "lastPageLabel": "Poslední strana", + "rangePageLabel1": "0 z {{length}}", + "rangePageLabel2": "{{startIndex}} – {{endIndex}} z {{length}}" + } +} diff --git a/src/Ombi/wwwroot/translations/da.json b/src/Ombi/wwwroot/translations/da.json index 6515ab2d7..4773dc32e 100644 --- a/src/Ombi/wwwroot/translations/da.json +++ b/src/Ombi/wwwroot/translations/da.json @@ -4,8 +4,8 @@ "UsernamePlaceholder": "Brugernavn", "PasswordPlaceholder": "Adgangskode", "RememberMe": "Husk mig", - "SignInWith": "Sign in with {{appName}}", - "SignInWithPlex": "Sign in with Plex", + "SignInWith": "Log ind med {{appName}}", + "SignInWithPlex": "Log ind med Plex", "ForgottenPassword": "Glemt adgangskode?", "Errors": { "IncorrectCredentials": "Forkert brugernavn eller adgangskode" @@ -14,30 +14,38 @@ "Common": { "ContinueButton": "Fortsæt", "Available": "Tilgængelig", - "Approved": "Approved", - "Pending": "Pending", + "Available4K": "Tilgængelig 4K", + "Approved": "Godkendt", + "Approve4K": "Godkend 4K", + "Pending": "Afventer", "PartiallyAvailable": "Delvist tilgængelig", "Monitored": "Overvåget", "NotAvailable": "Ikke tilgængelig", "ProcessingRequest": "Behandler anmodning", + "ProcessingRequest4K": "Processing Request 4K", "PendingApproval": "Afventer godkendelse", + "PendingApproval4K": "Pending Approval 4K", "RequestDenied": "Anmodning afvist", + "RequestDenied4K": "Request Denied 4K", "NotRequested": "Ikke anmodet", + "NotRequested4K": "Not Requested 4K", "Requested": "Anmodet", - "Search": "Search", + "Requested4K": "Anmodet 4K", + "Search": "Søg", "Request": "Anmod", + "Request4K": "Anmod 4K", "Denied": "Afvist", "Approve": "Godkendt", "PartlyAvailable": "Delvist tilgængelig", - "ViewDetails": "View Details", + "ViewDetails": "Vis detaljer", "Errors": { "Validation": "Tjek venligst dine indtastede værdier" }, - "Cancel": "Cancel", - "Submit": "Submit", - "Update": "Update", - "tvShow": "TV Show", - "movie": "Movie", + "Cancel": "Annuller", + "Submit": "Send", + "Update": "Opdater", + "tvShow": "TV-Serier", + "movie": "Film", "album": "Album" }, "PasswordReset": { @@ -55,8 +63,12 @@ "OfflineParagraph": "Medieserveren er offline.", "CheckPageForUpdates": "Tjek denne side for løbende opdateringer." }, + "ErrorPages": { + "NotFound": "Siden blev ikke fundet", + "SomethingWentWrong": "Noget gik galt!" + }, "NavigationBar": { - "Discover": "Discover", + "Discover": "Opdag", "Search": "Søg", "Requests": "Anmodninger", "UserManagement": "Brugeradministration", @@ -72,20 +84,20 @@ "Logout": "Log af", "OpenMobileApp": "Åbn mobilapp", "RecentlyAdded": "Senest tilføjet", - "ChangeTheme": "Change Theme", - "Calendar": "Calendar", - "UserPreferences": "Preferences", + "ChangeTheme": "Skift tema", + "Calendar": "Kalender", + "UserPreferences": "Præferencer", "FeatureSuggestion": "Feature Suggestion", - "FeatureSuggestionTooltip": "Have a great new idea? Suggest it here!", + "FeatureSuggestionTooltip": "Har du en god ny idé? Foreslå den her!", "Filter": { "Movies": "Film", "TvShows": "Tv-serier", "Music": "Musik", - "People": "People" + "People": "Personer" }, - "MorningWelcome": "Good morning!", - "AfternoonWelcome": "Good afternoon!", - "EveningWelcome": "Good evening!" + "MorningWelcome": "Godmorgen!", + "AfternoonWelcome": "Godeftermiddag!", + "EveningWelcome": "Godaften!" }, "Search": { "Title": "Søg", @@ -93,19 +105,19 @@ "MoviesTab": "Film", "TvTab": "Tv-serier", "MusicTab": "Musik", - "AdvancedSearch": "You can fill in any of the below to discover new media. All of the results are sorted by popularity", - "AdvancedSearchHeader": "Advanced Search", + "AdvancedSearch": "Du kan udfylde en eller flere af nedenstående for at opdage nye medier. Alle resultater er sorteret efter popularitet", + "AdvancedSearchHeader": "Avanceret Søgning", "Suggestions": "Forslag", "NoResults": "Beklager, vi fandt ingen resultater!", "DigitalDate": "Digital udgivelse: {{date}}", "TheatricalRelease": "Biografudgivelse: {{date}}", "ViewOnPlex": "Se på Plex", "ViewOnEmby": "Se på Emby", - "ViewOnJellyfin": "Play On Jellyfin", + "ViewOnJellyfin": "Afspil på Jellyfin", "RequestAdded": "{{title}} er anmodet med succes", "Similar": "Lignende", - "Refine": "Refine", - "SearchBarPlaceholder": "Type Here to Search", + "Refine": "Specificer", + "SearchBarPlaceholder": "Indtast her for at søge", "Movies": { "PopularMovies": "Populære film", "UpcomingMovies": "Kommende film", @@ -129,16 +141,19 @@ "Season": "Sæson {{seasonNumber}}", "SelectAllInSeason": "Vælg alle i sæson {{seasonNumber}}" }, - "AdvancedSearchInstructions": "Please choose what type of media you are searching for:", - "YearOfRelease": "Year of Release", - "KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb" + "AdvancedSearchInstructions": "Vælg venligst hvilken type medier, du søger efter:", + "YearOfRelease": "Udgivelsesår", + "SearchGenre": "Søg efter genre", + "SearchKeyword": "Søg efter nøgleord", + "SearchProvider": "Søgemaskiner", + "KeywordSearchingDisclaimer": "Bemærk venligst, at Nøgleord-søgning ikke altid er pålideligt grundet de inkonsistente data i TheMovieDb" }, "Requests": { "Title": "Anmodninger", "Paragraph": "Herunder kan du se dine og alle andre anmodninger, samt status for download og godkendelse.", "MoviesTab": "Film", - "ArtistName": "Artist", - "AlbumName": "Album Name", + "ArtistName": "Kunstner", + "AlbumName": "Albumnavn", "TvTab": "Tv-serier", "MusicTab": "Musik", "RequestedBy": "Anmodet af", @@ -155,11 +170,15 @@ "ChangeRootFolder": "Skift rodmappe", "ChangeQualityProfile": "Skift kvalitetsprofil", "MarkUnavailable": "Markér som utilgængelig", + "MarkUnavailable4K": "Marker Utilgængelig 4K", "MarkAvailable": "Markér som tilgængelig", + "MarkAvailable4K": "Marker Tilgængelig 4K", "Remove": "Fjern", "Deny": "Afvis", - "DenyReason": "Deny Reason", - "DeniedReason": "Denied Reason", + "Deny4K": "Afvis 4K", + "Has4KRequest": "Har 4K Anmodning", + "DenyReason": "Afvisningsårsag", + "DeniedReason": "Afvisningsårsag", "Season": "Sæson", "GridTitle": "Titel", "AirDate": "Sendt", @@ -181,53 +200,64 @@ "NextMinutes": "En anden anmodning vil blive tilføjet i {{time}} Minutter", "NextMinute": "En anden anmodning vil blive tilføjet i {{time}} Minut" }, - "AllRequests": "All Requests", - "PendingRequests": "Pending Requests", - "ProcessingRequests": "Processing Requests", - "AvailableRequests": "Available Requests", - "DeniedRequests": "Denied Requests", - "RequestsToDisplay": "Requests to display", + "AllRequests": "Alle anmodninger", + "PendingRequests": "Afventende anmodninger", + "ProcessingRequests": "Behandler anmodninger", + "AvailableRequests": "Tilgængelige anmodninger", + "DeniedRequests": "Afviste anmodninger", + "RequestsToDisplay": "Anmodninger at vise", "RequestsTitle": "Titel", "Details": "Detaljer", - "Options": "Options", + "Options": "Indstillinger", "RequestPanel": { - "Delete": "Delete Request", - "Approve": "Approve Request", - "ChangeAvailability": "Mark Available", - "Deleted": "Successfully deleted selected items", - "Approved": "Successfully approved selected items" + "Delete": "Slet Anmodning", + "Approve": "Godkend Andmodning", + "Deny": "Afvis Request", + "Approve4K": "Godkend 4K Anmodning", + "Deny4K": "Afvis 4K Request", + "ChangeAvailability": "Markér som tilgængelig", + "Deleted": "De valgte elementer blev slettet", + "Approved": "De valgte elementer blev godkendt", + "Denied": "De valgte elementer blev afvist" }, - "SuccessfullyApproved": "Successfully Approved", - "NowAvailable": "Request is now available", - "NowUnavailable": "Request is now unavailable", - "SuccessfullyReprocessed": "Successfully Re-processed the request", - "DeniedRequest": "Denied Request", - "RequestCollection": "Request Collection", - "CollectionSuccesfullyAdded": "The collection {{name}} has been successfully added!", - "NeedToSelectEpisodes": "You need to select some episodes!", - "RequestAddedSuccessfully": "Request for {{title}} has been added successfully", + "SuccessfullyApproved": "Godkendt", + "SuccessfullyDeleted": "Anmodningen blev slettet", + "NowAvailable": "Anmodningen er nu tilgængelig", + "NowUnavailable": "Anmodningen er nu utilgængelig", + "SuccessfullyReprocessed": "Anmodningen blev genbehandlet", + "DeniedRequest": "Anmodningen blev afvist", + "RequestCollection": "Anmod Om Samling", + "CollectionSuccesfullyAdded": "Samlingen {{name}} er blevet tilføjet!", + "NeedToSelectEpisodes": "Du skal vælge nogle episoder!", + "RequestAddedSuccessfully": "{{title}} er anmodet med succes", "ErrorCodes": { - "AlreadyRequested": "This has already been requested", - "EpisodesAlreadyRequested": "We already have episodes requested from this series", - "NoPermissionsOnBehalf": "You do not have the correct permissions to request on behalf of users!", - "NoPermissions": "You do not have the correct permissions!", - "RequestDoesNotExist": "Request does not exist", - "ChildRequestDoesNotExist": "Child Request does not exist", - "NoPermissionsRequestMovie": "You do not have permissions to Request a Movie", - "NoPermissionsRequestTV": "You do not have permissions to Request a TV Show", - "NoPermissionsRequestAlbum": "You do not have permissions to Request an Album", - "MovieRequestQuotaExceeded": "You have exceeded your Movie request quota!", - "TvRequestQuotaExceeded": "You have exceeded your Episode request quota!", - "AlbumRequestQuotaExceeded": "You have exceeded your Album request quota!" - } + "AlreadyRequested": "Dette er allerede blevet anmodet om", + "EpisodesAlreadyRequested": "Vi har allerede episoder anmodet fra denne serie", + "NoPermissionsOnBehalf": "Du har ikke de korrekte tilladelser til at anmode på vegne af brugere!", + "NoPermissions": "Du har ikke de nødvendige tilladelser!", + "RequestDoesNotExist": "Anmodningen eksisterer ikke", + "ChildRequestDoesNotExist": "Child-anmodning eksisterer ikke", + "NoPermissionsRequestMovie": "Du har ikke tilladelse til at anmode om en film", + "NoPermissionsRequestTV": "Du har ikke tilladelse til at anmode om en tv-serie", + "NoPermissionsRequestAlbum": "Du har ikke tilladelse til at anmode om et album", + "MovieRequestQuotaExceeded": "Du har overskredet din film-anmodningskvote!", + "TvRequestQuotaExceeded": "Du har overskredet din episode-anmodningskvote!", + "AlbumRequestQuotaExceeded": "Du har overskredet din album-anmodningskvote!" + }, + "Notify": "Giv besked", + "RemoveNotification": "Fjern Notifikationer", + "SuccessfulNotify": "Du vil nu få besked om titlen {{title}}", + "SuccessfulUnNotify": "Du vil ikke længere få besked om titlen {{title}}", + "CouldntNotify": "Titlen {{title}} kunne ikke meddeles" }, "Issues": { "Title": "Problemer", + "IssuesForTitle": "Problemer for {{title}}", "PendingTitle": "Afventende problemer", "InProgressTitle": "Igangværende probemer", "ResolvedTitle": "Løste problemer", "ColumnTitle": "Titel", - "Count": "Count", + "Count": "Antal", "Category": "Kategori", "Status": "Status", "Details": "Detaljer", @@ -241,22 +271,23 @@ "WriteMessagePlaceholder": "Indtast din besked her...", "ReportedBy": "Anmeldt af", "IssueDialog": { - "Title": "Report an issue", - "DescriptionPlaceholder": "Please describe the issue", - "TitlePlaceholder": "Short title of your issue", - "SelectCategory": "Select Category", - "IssueCreated": "Issue has been created" + "Title": "Rapporter en fejl", + "DescriptionPlaceholder": "Beskriv venligst problemet", + "TitlePlaceholder": "Kort titel på dit problem", + "SelectCategory": "Vælg kategori", + "IssueCreated": "Problemet er oprettet" }, - "Outstanding": "There are outstanding issues", - "ResolvedDate": "Resolved date", - "CreatedDate": "Raised on", - "MarkedAsResolved": "This issue has now been marked as resolved!", - "MarkedAsInProgress": "This issue has now been marked as in progress!", - "Delete": "Delete issue", - "DeletedIssue": "Issue has been deleted", + "Outstanding": "Der er uafklarede problemer", + "ResolvedDate": "Løst dato", + "CreatedDate": "Oprettet den", + "MarkedAsResolved": "Dette problem er nu blevet markeret som løst!", + "MarkedAsInProgress": "Dette problem er markeret som igangværende!", + "Delete": "Slet problem", + "DeletedIssue": "Problemet er slettet", "Chat": "Chat", - "Requested": "Requested", - "UserOnDate": "{{user}} on {{date}}" + "EnterYourMessage": "Indtast din besked", + "Requested": "Anmodet", + "UserOnDate": "{{user}} d. {{date}}" }, "Filter": { "ClearFilter": "Nulstil filter", @@ -264,8 +295,8 @@ "FilterHeaderRequestStatus": "Status", "Approved": "Godkendt", "PendingApproval": "Afventer godkendelse", - "WatchProviders": "Watch Providers", - "Keywords": "Keywords" + "WatchProviders": "Vælg udbydere", + "Keywords": "Nøgleord" }, "UserManagment": { "TvRemaining": "Tv: {{remaining}}/{{total}} Resterende", @@ -281,128 +312,144 @@ }, "MediaDetails": { "Denied": "Afvist", - "RecommendationsTitle": "Recommendations", + "Denied4K": "Afvist 4K", + "Trailers": "Trailers", + "RecommendationsTitle": "Anbefalinger", "SimilarTitle": "Lignende", - "VideosTitle": "Videos", - "AlbumsTitle": "Albums", - "RequestAllAlbums": "Request All Albums", - "ClearSelection": "Clear Selection", - "RequestSelectedAlbums": "Request Selected Albums", - "ViewCollection": "View Collection", - "NotEnoughInfo": "Unfortunately there is not enough information about this show yet!", - "AdvancedOptions": "Advanced Options", - "AutoApproveOptions": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTv": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be send to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "QualityProfilesSelect": "Select A Quality Profile", - "RootFolderSelect": "Select A Root Folder", - "LanguageProfileSelect": "Select A Language Profile", + "VideosTitle": "Video", + "AlbumsTitle": "Album", + "RequestAllAlbums": "Anmod Om Alle Albums", + "ClearSelection": "Ryd valgte", + "RequestSelectedAlbums": "Anmod Om Valgte Album", + "ViewCollection": "Vis Samling", + "NotEnoughInfo": "Der er desværre ikke nok information om dette show endnu!", + "AdvancedOptions": "Avancerede Indstillinger", + "AutoApproveOptions": "Du kan konfigurere anmodningen her. Når du har anmodet, vil den blive sendt til dit DVR program og vil blive godkendt automatisk! Bemærk venligst, at dette er valgfrit. Tryk blot på Anmodning for at springe over!", + "AutoApproveOptionsTv": "Du kan konfigurere anmodningen her. Når du har anmodet vil den blive sendt til dit DVR program og vil blive auto godkendt automatisk! Hvis anmodningen allerede er i Sonarr, vil vi ikke ændre root-mappen eller kvalitetsprofilen, hvis du indstiller den! Bemærk venligst, at dette er valgfrit. Tryk blot på Anmodning om at springe over!", + "AutoApproveOptionsTvShort": "Du kan konfigurere anmodningen her. Når du har anmodet vil den blive sendt til dit DVR program og vil blive auto godkendt automatisk! Hvis anmodningen allerede er i Sonarr, vil vi ikke ændre root-mappen eller kvalitetsprofilen, hvis du indstiller den! Bemærk venligst, at dette er valgfrit. Tryk blot på Anmodning om at springe over!", + "QualityProfilesSelect": "Vælg En kvalitetsprofil", + "RootFolderSelect": "Vælg en root mappe", + "LanguageProfileSelect": "Vælg En Sprogprofil", "Status": "Status:", "StatusValues": { - "Rumored": "Rumored", - "Planned": "Planned", - "In Production": "In Production", - "Post Production": "Post Production", - "Released": "Released", - "Running": "Running", - "Returning Series": "Returning Series", - "Ended": "Ended", - "Canceled": "Canceled" + "Rumored": "Rygtet", + "Planned": "Planlagt", + "In Production": "I Produktion", + "Post Production": "Postproduktion", + "Released": "Udgivet", + "Running": "Aktiv", + "Returning Series": "Tilbagevendende Serier", + "Ended": "Afsluttet", + "Canceled": "Annulleret" }, - "Seasons": "Seasons:", - "Episodes": "Episodes:", - "Availability": "Availability:", - "RequestStatus": "Request Status", - "Quality": "Quality:", - "RootFolderOverride": "Root Folder Override:", - "QualityOverride": "Quality Override:", - "Network": "Network:", - "Genres": "Genres:", - "FirstAired": "First Aired:", - "TheatricalRelease": "Release:", - "DigitalRelease": "Digital Release:", - "Votes": "Votes:", - "Runtime": "Runtime:", - "Minutes": "{{runtime}} Minutes", - "Revenue": "Revenue:", + "Seasons": "Sæsoner:", + "Episodes": "Episoder:", + "Availability": "Tilgængelighed:", + "RequestStatus": "Request Status:", + "Quality": "Kvalitet:", + "RootFolderOverride": "Tilsidesæt rodmappe:", + "QualityOverride": "Tilsidesæt kvalitet:", + "Network": "Netværk:", + "GenresLabel": "Genre:", + "Genres": "Genre", + "FirstAired": "Sendt første gang:", + "TheatricalRelease": "Biografudgivelse:", + "DigitalRelease": "Digital Udgivelse:", + "Votes": "Stemmer:", + "Runtime": "Spilletid:", + "Minutes": "{{runtime}} minutter", + "Revenue": "Indtægter:", "Budget": "Budget:", - "Keywords": "Keywords/Tags:", + "Keywords": "Nøgleord/Tags:", "Casts": { - "CastTitle": "Cast" + "CastTitle": "Medvirkende" }, "EpisodeSelector": { - "AllSeasonsTooltip": "This will request every season for this show", - "FirstSeasonTooltip": "This will only request the First Season for this show", - "LatestSeasonTooltip": "This will only request the Latest Season for this show", - "NoEpisodes": "There unfortunately is no episode data for this show yet!", - "SeasonNumber": "Season {{number}}" + "AllSeasonsTooltip": "Dette vil anmode om hver sæson for denne tv-serie", + "FirstSeasonTooltip": "Dette vil kun anmode om den første sæson for denne tv-serie", + "LatestSeasonTooltip": "Dette vil kun anmode den seneste sæson for denne tv-serie", + "NoEpisodes": "Der er desværre ingen episode data for denne tv-serie endnu!", + "SeasonNumber": "Sæson {{number}}" }, - "SonarrConfiguration": "Sonarr Configuration", - "RadarrConfiguration": "Radarr Configuration", - "RequestOnBehalf": "Request on behalf of", - "PleaseSelectUser": "Please select a user", - "StreamingOn": "Streaming On:", - "RequestedBy": "Requested By:", - "RequestDate": "Request Date:", - "DeniedReason": "Denied Reason:", - "ReProcessRequest": "Re-Process Request", + "SonarrConfiguration": "Konfiguration Af Sonarr", + "RadarrConfiguration": "Konfiguration Af Radarr", + "RequestOnBehalf": "Anmod på vegne af", + "PleaseSelectUser": "Vælg venligst en bruger", + "StreamingOn": "Streaming På:", + "RequestedBy": "Anmodet af:", + "RequestedByOn": "Anmodet af {{user}} d. {{date}}", + "RequestDate": "Dato for anmodning:", + "DeniedReason": "Afvisningsårsag:", + "ReProcessRequest": "Anmodning Om Genbehandling", + "ReProcessRequest4K": "Genbehandling af 4K Anmodning", "Music": { "Type": "Type:", - "Country": "Country:", - "StartDate": "Start Date:", - "EndDate": "EndDate:" - } + "Country": "Land:", + "StartDate": "Startdato:", + "EndDate": "Slutdato:" + }, + "RequestSource": "Kilde:" }, "Discovery": { "PopularTab": "Populære", "TrendingTab": "Aktuelle", - "UpcomingTab": "Upcoming", - "SeasonalTab": "Seasonal", - "RecentlyRequestedTab": "Recently Requested", + "UpcomingTab": "Kommende", + "SeasonalTab": "Sæsonbestemt", + "RecentlyRequestedTab": "Anmodet For Nyligt", "Movies": "Film", - "Combined": "Combined", + "Combined": "Kombineret", "Tv": "TV", "CardDetails": { "Availability": "Tilgængelighed", - "Studio": "Studio", - "Network": "Network", - "UnknownNetwork": "Unknown", - "RequestStatus": "Request Status", - "Director": "Director", - "InCinemas": "In Cinemas", - "FirstAired": "First Aired", - "Writer": "Writer", - "ExecProducer": "Exec Producer" + "Studio": "Studie", + "Network": "TV-netværk", + "UnknownNetwork": "Ukendt", + "RequestStatus": "Status for anmodning", + "Director": "Instruktør", + "InCinemas": "I Biografer", + "FirstAired": "Sendt første gang", + "Writer": "Skribent", + "ExecProducer": "Producer" }, - "NoSearch": "Sorry, nothing matches your search!" + "NoSearch": "Vi fandt desværre ikke noget, der matcher din søgning!" }, "UserPreferences": { "Welcome": "Velkommen til {{username}}!", - "OmbiLanguage": "Language", - "DarkMode": "Dark Mode", - "Updated": "Successfully Updated", - "StreamingCountry": "Streaming Country", - "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will have US related streaming information.", - "LanguageDescription": "This is the language you would like the Ombi interface to be displayed in.", - "MobileQRCode": "Mobile QR Code", - "LegacyApp": "Launch Legacy App", - "NoQrCode": "Please contact your administrator to enable QR codes", - "UserType": "User Type:", - "ChangeDetails": "Change Details", - "NeedCurrentPassword": "You need your current password to make any changes here", - "CurrentPassword": "Current Password", - "EmailAddress": "Email Address", - "NewPassword": "New Password", - "NewPasswordConfirm": "New Password Confirm", - "Security": "Security", - "Profile": "Profile", - "UpdatedYourInformation": "Updated your information" + "OmbiLanguage": "Sprog", + "DarkMode": "Mørk tilstand", + "Updated": "Opdateret", + "StreamingCountry": "Streaming Land", + "StreamingCountryDescription": "Dette er den landekode, som vi vil vise streaming information for. Hvis du er i USA, skal du vælge USA, og du vil få amerikanske relaterede streaming oplysninger.", + "LanguageDescription": "Dette er det sprog du gerne vil have Ombi grænsefladen skal vises i.", + "MobileQRCode": "Mobil QR Code", + "LegacyApp": "Start Gammel App", + "NoQrCode": "Kontakt venligst din administrator for at få adgang til QR koder", + "UserType": "Brugertype:", + "ChangeDetails": "Ændre detaljer", + "NeedCurrentPassword": "Vi behøver din nuværende adgangskode for at bekræfte dine ændringer", + "CurrentPassword": "Nuværende adgangskode", + "EmailAddress": "E-mail-adresse", + "NewPassword": "Ny adgangskode", + "NewPasswordConfirm": "Bekræft ny adgangskode", + "Security": "Sikkerhed", + "Profile": "Profil", + "UpdatedYourInformation": "Dine informationer blev opdateret", + "Unsubscribed": "Afmeldt!" }, "UserTypeLabel": { - "1": "Local User", - "2": "Plex User", - "3": "Emby User", - "4": "Emby Connect User", - "5": "Jellyfin User" + "1": "Lokal Bruger", + "2": "Plex Bruger", + "3": "Emby Bruger", + "4": "Forbind Emby Bruger", + "5": "Jellyfin Bruger" + }, + "Paginator": { + "itemsPerPageLabel": "Elementer per side:", + "nextPageLabel": "Næste side", + "previousPageLabel": "Forrige side", + "firstPageLabel": "Første side", + "lastPageLabel": "Sidste side", + "rangePageLabel1": "0 af {{length}}", + "rangePageLabel2": "{{startIndex}} – {{endIndex}} af {{length}}" } } diff --git a/src/Ombi/wwwroot/translations/de.json b/src/Ombi/wwwroot/translations/de.json index ce334e480..fa6385c66 100644 --- a/src/Ombi/wwwroot/translations/de.json +++ b/src/Ombi/wwwroot/translations/de.json @@ -4,8 +4,8 @@ "UsernamePlaceholder": "Benutzername", "PasswordPlaceholder": "Passwort", "RememberMe": "Eingeloggt bleiben", - "SignInWith": "Sign in with {{appName}}", - "SignInWithPlex": "Sign in with Plex", + "SignInWith": "Mit {{appName}} anmelden", + "SignInWithPlex": "Mit Plex anmelden", "ForgottenPassword": "Passwort vergessen?", "Errors": { "IncorrectCredentials": "Falscher Benutzername oder falsches Passwort" @@ -14,18 +14,26 @@ "Common": { "ContinueButton": "Weiter", "Available": "Verfügbar", - "Approved": "Approved", - "Pending": "Pending", + "Available4K": "In 4K verfügbar", + "Approved": "Genehmigt", + "Approve4K": "4K genehmigen", + "Pending": "steht aus", "PartiallyAvailable": "Teilweise verfügbar", "Monitored": "Überwacht", "NotAvailable": "Nicht verfügbar", "ProcessingRequest": "Anfrage wird bearbeitet", + "ProcessingRequest4K": "Processing Request 4K", "PendingApproval": "Genehmigung ausstehend", + "PendingApproval4K": "Pending Approval 4K", "RequestDenied": "Anfrage abgelehnt", + "RequestDenied4K": "Request Denied 4K", "NotRequested": "Nicht angefordert", + "NotRequested4K": "Not Requested 4K", "Requested": "Angefordert", - "Search": "Search", + "Requested4K": "In 4K angefragt", + "Search": "Suche", "Request": "Anfrage", + "Request4K": "In 4K anfragen", "Denied": "Abgelehnt", "Approve": "Genehmigen", "PartlyAvailable": "Teilweise verfügbar", @@ -33,11 +41,11 @@ "Errors": { "Validation": "Bitte überprüfen Sie die eingegebenen Werte" }, - "Cancel": "Cancel", - "Submit": "Submit", - "Update": "Update", - "tvShow": "TV Show", - "movie": "Movie", + "Cancel": "Abbrechen", + "Submit": "Senden", + "Update": "Aktualisierung", + "tvShow": "TV-Serie", + "movie": "Filme", "album": "Album" }, "PasswordReset": { @@ -55,6 +63,10 @@ "OfflineParagraph": "Der Mediaserver ist derzeit offline.", "CheckPageForUpdates": "Überprüfe diese Seite für kontinuierliche Website-Updates." }, + "ErrorPages": { + "NotFound": "Seite nicht gefunden", + "SomethingWentWrong": "Etwas ist schiefgelaufen!" + }, "NavigationBar": { "Discover": "Entdecken", "Search": "Suche", @@ -63,7 +75,7 @@ "Issues": "Probleme", "Vote": "Bewerten", "Donate": "Spenden!", - "DonateLibraryMaintainer": "Spende sie an den Bibliotheks Betreuer", + "DonateLibraryMaintainer": "Spende Sie an den Bibliotheks Betreuer", "DonateTooltip": "So überzeuge ich meine Frau, meine Freizeit mit der Entwicklung von Ombi zu verbringen ;)", "UpdateAvailableTooltip": "Update verfügbar!", "Settings": "Einstellungen", @@ -76,32 +88,32 @@ "Calendar": "Kalneder", "UserPreferences": "Einstellungen", "FeatureSuggestion": "Feature Suggestion", - "FeatureSuggestionTooltip": "Have a great new idea? Suggest it here!", + "FeatureSuggestionTooltip": "Sie haben eine tolle neue Idee? Schlagen Sie sie hier vor!", "Filter": { "Movies": "Filme", "TvShows": "Serien", "Music": "Musik", - "People": "People" + "People": "Personen" }, - "MorningWelcome": "Good morning!", - "AfternoonWelcome": "Good afternoon!", - "EveningWelcome": "Good evening!" + "MorningWelcome": "Guten Morgen!", + "AfternoonWelcome": "Guten Tag!", + "EveningWelcome": "Guten Abend!" }, "Search": { "Title": "Suche", - "Paragraph": "Möchtest du etwas sehen, das nicht verfügbar ist? Kein Problem, benutze einfach die Suchbox und fordere es an!", + "Paragraph": "Sie möchten etwas sehen, das nicht verfügbar ist? Kein Problem, benutzen Sie einfach das Suchfeld und fordern Sie es an!", "MoviesTab": "Filme", "TvTab": "Serien", "MusicTab": "Musik", - "AdvancedSearch": "You can fill in any of the below to discover new media. All of the results are sorted by popularity", - "AdvancedSearchHeader": "Advanced Search", + "AdvancedSearch": "Sie können die unten stehenden Felder ausfüllen, um neue Medien zu entdecken. Alle Ergebnisse sind nach Beliebtheit sortiert", + "AdvancedSearchHeader": "Erweiterte Suche", "Suggestions": "Vorschläge", "NoResults": "Es tut uns leid, wir haben keine Ergebnisse gefunden!", "DigitalDate": "Veröffentlichung der digitalen Version: {{date}}", "TheatricalRelease": "Kinostart: {{date}}", "ViewOnPlex": "In Plex anschauen", "ViewOnEmby": "In Emby anschauen", - "ViewOnJellyfin": "Play On Jellyfin", + "ViewOnJellyfin": "Auf Jellyfin ansehen", "RequestAdded": "Anfrage für {{title}} wurde erfolgreich hinzugefügt", "Similar": "Ähnliche", "Refine": "Auswahl verfeinern", @@ -116,29 +128,32 @@ }, "TvShows": { "Popular": "Beliebt", - "Trending": "im Trend", + "Trending": "Im Trend", "MostWatched": "Meist gesehen", "MostAnticipated": "Meist erwartet", "Results": "Ergebnisse", "AirDate": "Veröffentlicht am:", "AllSeasons": "Alle Staffeln", - "FirstSeason": "erste Staffel", - "LatestSeason": "aktuellste Staffel", + "FirstSeason": "Erste Staffel", + "LatestSeason": "Aktuellste Staffel", "Select": "Wähle...", "SubmitRequest": "Anfrage einreichen", "Season": "Staffel {{seasonNumber}}", "SelectAllInSeason": "Markiere alles in Staffel {{seasonNumber}}" }, - "AdvancedSearchInstructions": "Please choose what type of media you are searching for:", - "YearOfRelease": "Year of Release", - "KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb" + "AdvancedSearchInstructions": "Bitte wählen Sie aus, welche Art von Medien Sie suchen:", + "YearOfRelease": "Erscheinungsjahr", + "SearchGenre": "Genre suchen", + "SearchKeyword": "Schlagwort suchen", + "SearchProvider": "Anbieter suchen", + "KeywordSearchingDisclaimer": "Bitte beachten Sie, dass die Schlagwortsuche aufgrund der inkonsistenten Daten in TheMovieDb sehr unpräzise ist" }, "Requests": { "Title": "Anfragen", "Paragraph": "Unten sehen Sie Ihre und alle anderen Anfragen, sowie deren Download und Genehmigungsstatus.", "MoviesTab": "Filme", - "ArtistName": "Artist", - "AlbumName": "Album Name", + "ArtistName": "Künstler", + "AlbumName": "Albumname", "TvTab": "Serien", "MusicTab": "Musik", "RequestedBy": "Angefordert von", @@ -155,11 +170,15 @@ "ChangeRootFolder": "Stammordner ändern", "ChangeQualityProfile": "Qualitätsprofil ändern", "MarkUnavailable": "Als Nicht verfügbar markieren", + "MarkUnavailable4K": "4K als nicht verfügbar markieren", "MarkAvailable": "Als verfügbar markieren", + "MarkAvailable4K": "4K als verfügbar markieren", "Remove": "Entfernen", "Deny": "Ablehnen", + "Deny4K": "4K ablehnen", + "Has4KRequest": "Hat eine 4K Anfrage", "DenyReason": "Ablehnungsgrund", - "DeniedReason": "Denied Reason", + "DeniedReason": "Ablehnungsgrund", "Season": "Staffel", "GridTitle": "Titel", "AirDate": "Erstausstrahlung", @@ -181,53 +200,64 @@ "NextMinutes": "Eine weitere Anfrage wird in {{time}} Minuten hinzugefügt", "NextMinute": "Eine weitere Anfrage wird in {{time}} Minute hinzugefügt" }, - "AllRequests": "All Requests", - "PendingRequests": "Pending Requests", - "ProcessingRequests": "Processing Requests", - "AvailableRequests": "Available Requests", - "DeniedRequests": "Denied Requests", - "RequestsToDisplay": "Requests to display", + "AllRequests": "Alle Anfragen", + "PendingRequests": "Ausstehende Anfragen", + "ProcessingRequests": "Anfrage wird bearbeitet", + "AvailableRequests": "Verfügbare Anfragen", + "DeniedRequests": "Abgelehnte Anfragen", + "RequestsToDisplay": "Anzuzeigende Anfragen", "RequestsTitle": "Titel", "Details": "Details", - "Options": "Options", + "Options": "Optionen", "RequestPanel": { - "Delete": "Delete Request", - "Approve": "Approve Request", - "ChangeAvailability": "Mark Available", - "Deleted": "Successfully deleted selected items", - "Approved": "Successfully approved selected items" + "Delete": "Anfrage löschen", + "Approve": "Anfrage genehmigen", + "Deny": "Anfrage ablehnen", + "Approve4K": "4K Anfrage genehmigen", + "Deny4K": "4K Anfrage ablehnen", + "ChangeAvailability": "Als verfügbar markieren", + "Deleted": "Ausgewählte Elemente erfolgreich gelöscht", + "Approved": "Ausgewählte Elemente erfolgreich freigegeben", + "Denied": "Ausgewählte Elemente erfolgreich abgelehnt" }, - "SuccessfullyApproved": "Successfully Approved", - "NowAvailable": "Request is now available", - "NowUnavailable": "Request is now unavailable", - "SuccessfullyReprocessed": "Successfully Re-processed the request", - "DeniedRequest": "Denied Request", - "RequestCollection": "Request Collection", - "CollectionSuccesfullyAdded": "The collection {{name}} has been successfully added!", - "NeedToSelectEpisodes": "You need to select some episodes!", - "RequestAddedSuccessfully": "Request for {{title}} has been added successfully", + "SuccessfullyApproved": "Erfolgreich genehmigt", + "SuccessfullyDeleted": "Anfrage erfolgreich gelöscht", + "NowAvailable": "Anfrage ist jetzt verfügbar", + "NowUnavailable": "Anfrage ist jetzt verfügbar", + "SuccessfullyReprocessed": "Die Anfrage wurde erfolgreich neu verarbeitet", + "DeniedRequest": "Abgelehnte Anfrage", + "RequestCollection": "Anfrage Sammlung", + "CollectionSuccesfullyAdded": "Die Sammlung {{name}} wurde erfolgreich hinzugefügt!", + "NeedToSelectEpisodes": "Sie müssen einige Episoden auswählen!", + "RequestAddedSuccessfully": "Anfrage für {{title}} wurde erfolgreich hinzugefügt", "ErrorCodes": { - "AlreadyRequested": "This has already been requested", - "EpisodesAlreadyRequested": "We already have episodes requested from this series", - "NoPermissionsOnBehalf": "You do not have the correct permissions to request on behalf of users!", - "NoPermissions": "You do not have the correct permissions!", - "RequestDoesNotExist": "Request does not exist", - "ChildRequestDoesNotExist": "Child Request does not exist", - "NoPermissionsRequestMovie": "You do not have permissions to Request a Movie", - "NoPermissionsRequestTV": "You do not have permissions to Request a TV Show", - "NoPermissionsRequestAlbum": "You do not have permissions to Request an Album", - "MovieRequestQuotaExceeded": "You have exceeded your Movie request quota!", - "TvRequestQuotaExceeded": "You have exceeded your Episode request quota!", - "AlbumRequestQuotaExceeded": "You have exceeded your Album request quota!" - } + "AlreadyRequested": "Dies ist bereits beantragt worden", + "EpisodesAlreadyRequested": "Wir haben bereits Episoden aus dieser Serie angefordert", + "NoPermissionsOnBehalf": "Sie haben nicht die richtigen Berechtigungen, um im Namen von Benutzern anzufragen!", + "NoPermissions": "Sie haben nicht die nötigen Rechte!", + "RequestDoesNotExist": "Die Anfrage existiert nicht", + "ChildRequestDoesNotExist": "Untergeordnete Anfrage existiert nicht", + "NoPermissionsRequestMovie": "Sie haben keine Berechtigung, um einen Film anzufordern", + "NoPermissionsRequestTV": "Sie haben keine Berechtigung, um eine TV-Sendung anzufordern", + "NoPermissionsRequestAlbum": "Sie haben keine Berechtigung, um ein Album anzufordern", + "MovieRequestQuotaExceeded": "Sie haben Ihr Kontingent für Filmanfragen überschritten!", + "TvRequestQuotaExceeded": "Sie haben Ihr Kontingent für Episodenanfragen überschritten!", + "AlbumRequestQuotaExceeded": "Sie haben Ihr Kontingent für Albumanfragen überschritten!" + }, + "Notify": "Benachrichtigen", + "RemoveNotification": "Benachrichtigungen entfernen", + "SuccessfulNotify": "Sie werden nun für den Titel {{title}} benachrichtigt", + "SuccessfulUnNotify": "Sie werden für den Titel {{title}} nicht mehr benachrichtigt", + "CouldntNotify": "Konnte für den Titel {{title}} nicht benachrichtigen" }, "Issues": { "Title": "Probleme", + "IssuesForTitle": "Probleme mit {{title}}", "PendingTitle": "Ausstehende Probleme", "InProgressTitle": "Probleme in bearbeitung", "ResolvedTitle": "Behobene Probleme", "ColumnTitle": "Titel", - "Count": "Count", + "Count": "Anzahl", "Category": "Kategorie", "Status": "Status", "Details": "Details", @@ -241,22 +271,23 @@ "WriteMessagePlaceholder": "Nachricht eingeben...", "ReportedBy": "Gemeldet von", "IssueDialog": { - "Title": "Report an issue", - "DescriptionPlaceholder": "Please describe the issue", - "TitlePlaceholder": "Short title of your issue", - "SelectCategory": "Select Category", - "IssueCreated": "Issue has been created" + "Title": "Ein Problem melden", + "DescriptionPlaceholder": "Bitte beschreibe dein Problem", + "TitlePlaceholder": "Kurzer Titel Ihres Tickets", + "SelectCategory": "Kategorie auswählen", + "IssueCreated": "Ticket wurde erstellt" }, - "Outstanding": "There are outstanding issues", - "ResolvedDate": "Resolved date", - "CreatedDate": "Raised on", - "MarkedAsResolved": "This issue has now been marked as resolved!", - "MarkedAsInProgress": "This issue has now been marked as in progress!", - "Delete": "Delete issue", - "DeletedIssue": "Issue has been deleted", + "Outstanding": "Es gibt ausstehende Probleme", + "ResolvedDate": "Gelöst am", + "CreatedDate": "Erstellt am", + "MarkedAsResolved": "Dieses Problem wurde jetzt als gelöst markiert!", + "MarkedAsInProgress": "Dieses Problem wurde jetzt als in Bearbeitung markiert!", + "Delete": "Problem löschen", + "DeletedIssue": "Ticket wurde gelöscht", "Chat": "Chat", - "Requested": "Requested", - "UserOnDate": "{{user}} on {{date}}" + "EnterYourMessage": "Geben Sie Ihre Nachricht ein", + "Requested": "Angefordert", + "UserOnDate": "{{user}} am {{date}}" }, "Filter": { "ClearFilter": "Filter zurücksetzen", @@ -264,8 +295,8 @@ "FilterHeaderRequestStatus": "Status", "Approved": "Bestätigt", "PendingApproval": "Genehmigung ausstehend", - "WatchProviders": "Watch Providers", - "Keywords": "Keywords" + "WatchProviders": "Anbieter", + "Keywords": "Schlagwörter" }, "UserManagment": { "TvRemaining": "TV: {{remaining}}/{{total}} verbleibend", @@ -281,52 +312,55 @@ }, "MediaDetails": { "Denied": "Abgelehnt", + "Denied4K": "4K Abgelehnt", + "Trailers": "Trailers", "RecommendationsTitle": "Empfehlungen", "SimilarTitle": "Ähnliche", "VideosTitle": "Videos", - "AlbumsTitle": "Albums", - "RequestAllAlbums": "Request All Albums", - "ClearSelection": "Clear Selection", - "RequestSelectedAlbums": "Request Selected Albums", - "ViewCollection": "View Collection", - "NotEnoughInfo": "Unfortunately there is not enough information about this show yet!", - "AdvancedOptions": "Advanced Options", - "AutoApproveOptions": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTv": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be send to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "QualityProfilesSelect": "Select A Quality Profile", - "RootFolderSelect": "Select A Root Folder", - "LanguageProfileSelect": "Select A Language Profile", + "AlbumsTitle": "Alben", + "RequestAllAlbums": "Alle Alben anfragen", + "ClearSelection": "Auswahl leeren", + "RequestSelectedAlbums": "Ausgewählte Alben anfordern", + "ViewCollection": "Sammlung ansehen", + "NotEnoughInfo": "Leider gibt es noch nicht genügend Informationen über diese Serie!", + "AdvancedOptions": "Erweiterte Optionen", + "AutoApproveOptions": "Sie können die Anfrage hier konfigurieren. Sobald die Anfrage gestellt ist, wird sie an Ihre DVR-Anwendung gesendet und automatisch genehmigt! Bitte beachten Sie, dass dies optional ist, drücken Sie einfach auf Anfrage zum Überspringen!", + "AutoApproveOptionsTv": "Sie können die Anfrage hier konfigurieren. Sobald die Anfrage gestellt ist, wird sie an Ihre DVR-Anwendung gesendet und automatisch genehmigt! Wenn die Anfrage bereits in Sonarr ist, werden wir den Stammordner oder das Qualitätsprofil nicht ändern, wenn Sie es einstellen! Bitte beachten Sie, dass dies optional ist, drücken Sie einfach auf Anfrage zum Überspringen!", + "AutoApproveOptionsTvShort": "Sie können die Anfrage hier konfigurieren. Sobald die Anfrage gestellt ist, wird sie an Ihre DVR-Anwendung gesendet! Wenn die Anfrage bereits in Sonarr ist, werden wir den Stammordner oder das Qualitätsprofil nicht ändern, wenn Sie es einstellen! Bitte beachten Sie, dass dies optional ist, drücken Sie einfach auf Anfrage zum Überspringen!", + "QualityProfilesSelect": "Wähle ein Qualitätsprofil", + "RootFolderSelect": "Hauptverzeichnis auswählen", + "LanguageProfileSelect": "Wählen Sie ein Sprachprofil", "Status": "Status:", "StatusValues": { - "Rumored": "Rumored", - "Planned": "Planned", - "In Production": "In Production", - "Post Production": "Post Production", - "Released": "Released", - "Running": "Running", - "Returning Series": "Returning Series", - "Ended": "Ended", - "Canceled": "Canceled" + "Rumored": "Gerüchten zufolge", + "Planned": "Geplant", + "In Production": "In Produktion", + "Post Production": "Postproduktion", + "Released": "Veröffentlicht", + "Running": "Aktiv", + "Returning Series": "Wiederkehrende Serie", + "Ended": "Beendet", + "Canceled": "Abgesagt" }, - "Seasons": "Seasons:", - "Episodes": "Episodes:", - "Availability": "Availability:", - "RequestStatus": "Anfrage Status", - "Quality": "Quality:", - "RootFolderOverride": "Root Folder Override:", - "QualityOverride": "Quality Override:", - "Network": "Network:", - "Genres": "Genres:", - "FirstAired": "First Aired:", - "TheatricalRelease": "Release:", - "DigitalRelease": "Digital Release:", - "Votes": "Votes:", - "Runtime": "Runtime:", - "Minutes": "{{runtime}} Minutes", - "Revenue": "Revenue:", + "Seasons": "Staffeln:", + "Episodes": "Episoden:", + "Availability": "Verfügbarkeit:", + "RequestStatus": "Request Status:", + "Quality": "Qualität:", + "RootFolderOverride": "Stammverzeichnis Überschreiben:", + "QualityOverride": "Qualitäts Überschreiben:", + "Network": "Netzwerk:", + "GenresLabel": "Genres:", + "Genres": "Genres", + "FirstAired": "Erstausstrahlung:", + "TheatricalRelease": "Kinostart:", + "DigitalRelease": "Digitale Veröffentlichung:", + "Votes": "Abstimmungen:", + "Runtime": "Laufzeit:", + "Minutes": "{{runtime}} Minuten", + "Revenue": "Einspielergebnis:", "Budget": "Budget:", - "Keywords": "Keywords/Tags:", + "Keywords": "Schlagwörter/Tags:", "Casts": { "CastTitle": "Besetzung" }, @@ -334,33 +368,36 @@ "AllSeasonsTooltip": "Dies wird jede Saison für diese Show anfordern", "FirstSeasonTooltip": "Dies wird nur die erste Saison für diese Show anfordern", "LatestSeasonTooltip": "Dies wird nur die letzte Saison für diese Show anfordern", - "NoEpisodes": "There unfortunately is no episode data for this show yet!", - "SeasonNumber": "Season {{number}}" + "NoEpisodes": "Es gibt leider noch keine Episodendaten für diese Sendung!", + "SeasonNumber": "Staffel {{number}}" }, - "SonarrConfiguration": "Sonarr Configuration", - "RadarrConfiguration": "Radarr Configuration", - "RequestOnBehalf": "Request on behalf of", - "PleaseSelectUser": "Please select a user", - "StreamingOn": "Streaming On:", - "RequestedBy": "Requested By:", - "RequestDate": "Request Date:", - "DeniedReason": "Denied Reason:", - "ReProcessRequest": "Re-Process Request", + "SonarrConfiguration": "Sonarr Konfiguration", + "RadarrConfiguration": "Radarr Konfiguration", + "RequestOnBehalf": "Anfange im Namen von", + "PleaseSelectUser": "Bitte Benutzer auswählen", + "StreamingOn": "Wird gestreamt auf:", + "RequestedBy": "Angefordert von:", + "RequestedByOn": "Angefragt von {{user}} am {{date}}", + "RequestDate": "Datum der Anfrage:", + "DeniedReason": "Ablehnungsgrund:", + "ReProcessRequest": "Anfrage erneut bearbeiten", + "ReProcessRequest4K": "4K Anfrage erneut bearbeiten", "Music": { - "Type": "Type:", - "Country": "Country:", - "StartDate": "Start Date:", - "EndDate": "EndDate:" - } + "Type": "Typ:", + "Country": "Land:", + "StartDate": "Startdatum:", + "EndDate": "Enddatum:" + }, + "RequestSource": "Quelle:" }, "Discovery": { "PopularTab": "Beliebt", "TrendingTab": "Angesagt", "UpcomingTab": "Demnächst", - "SeasonalTab": "Seasonal", - "RecentlyRequestedTab": "Recently Requested", + "SeasonalTab": "Saisonal", + "RecentlyRequestedTab": "Kürzlich angefragt", "Movies": "Filme", - "Combined": "Combined", + "Combined": "Kombiniert", "Tv": "TV", "CardDetails": { "Availability": "Verfügbarkeit", @@ -374,35 +411,45 @@ "Writer": "AutorIn", "ExecProducer": "Ausführender Produzent" }, - "NoSearch": "Sorry, nothing matches your search!" + "NoSearch": "Entschuldigung, nichts stimmt mit deiner Suche überein!" }, "UserPreferences": { "Welcome": "Willkommen {{username}}!", - "OmbiLanguage": "Language", - "DarkMode": "Dark Mode", - "Updated": "Successfully Updated", - "StreamingCountry": "Streaming Country", - "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will have US related streaming information.", - "LanguageDescription": "This is the language you would like the Ombi interface to be displayed in.", - "MobileQRCode": "Mobile QR Code", - "LegacyApp": "Launch Legacy App", - "NoQrCode": "Please contact your administrator to enable QR codes", - "UserType": "User Type:", - "ChangeDetails": "Change Details", - "NeedCurrentPassword": "You need your current password to make any changes here", - "CurrentPassword": "Current Password", - "EmailAddress": "Email Address", - "NewPassword": "New Password", - "NewPasswordConfirm": "New Password Confirm", - "Security": "Security", - "Profile": "Profile", - "UpdatedYourInformation": "Updated your information" + "OmbiLanguage": "Sprache", + "DarkMode": "Dunkler Modus", + "Updated": "Erfolgreich aktualisiert", + "StreamingCountry": "Streaming Land", + "StreamingCountryDescription": "Dies ist der Ländercode, für den wir Streaming-Informationen anzeigen. Wenn Sie sich in den USA befinden, wählen Sie bitte US und Sie erhalten Streaming-Informationen für die USA.", + "LanguageDescription": "Dies ist die Sprache, in der Ombi angezeigt werden soll.", + "MobileQRCode": "Mobiler QR Code", + "LegacyApp": "Legacy-App starten", + "NoQrCode": "Bitte kontaktieren Sie Ihren Administrator, um QR-Codes zu aktivieren", + "UserType": "Benutzertyp:", + "ChangeDetails": "Details ändern", + "NeedCurrentPassword": "Sie benötigen Ihr aktuelles Passwort, um hier Änderungen vorzunehmen", + "CurrentPassword": "Aktuelles Passwort", + "EmailAddress": "E-Mail-Adresse", + "NewPassword": "Neues Passwort", + "NewPasswordConfirm": "Neues Passwort bestätigen", + "Security": "Sicherheit", + "Profile": "Profil", + "UpdatedYourInformation": "Aktualisieren Sie Ihre Informationen", + "Unsubscribed": "Abbestellt!" }, "UserTypeLabel": { - "1": "Local User", - "2": "Plex User", - "3": "Emby User", - "4": "Emby Connect User", - "5": "Jellyfin User" + "1": "Lokaler Benutzer", + "2": "Plex Benutzer", + "3": "Embe Benutzer", + "4": "Emby Connect Benutzer", + "5": "Jellyfin Server" + }, + "Paginator": { + "itemsPerPageLabel": "Elemente pro Seite:", + "nextPageLabel": "Nächste Seite", + "previousPageLabel": "Vorherige Seite", + "firstPageLabel": "Erste Seite", + "lastPageLabel": "Letzte Seite", + "rangePageLabel1": "0 von {{length}}", + "rangePageLabel2": "{{startIndex}} – {{endIndex}} von {{length}}" } } diff --git a/src/Ombi/wwwroot/translations/en.json b/src/Ombi/wwwroot/translations/en.json index ad9ee1ba2..de38effd3 100644 --- a/src/Ombi/wwwroot/translations/en.json +++ b/src/Ombi/wwwroot/translations/en.json @@ -12,33 +12,41 @@ } }, "Common": { - "ContinueButton": "Continue", - "Available": "Available", - "Approved": "Approved", - "Pending": "Pending", - "PartiallyAvailable": "Partially Available", - "Monitored": "Monitored", - "NotAvailable": "Not Available", - "ProcessingRequest": "Processing Request", - "PendingApproval": "Pending Approval", - "RequestDenied": "Request Denied", - "NotRequested": "Not Requested", - "Requested": "Requested", - "Search":"Search", - "Request": "Request", - "Denied": "Denied", - "Approve": "Approve", - "PartlyAvailable": "Partly Available", - "ViewDetails": "View Details", - "Errors": { - "Validation": "Please check your entered values" - }, - "Cancel": "Cancel", - "Submit": "Submit", - "Update": "Update", - "tvShow": "TV Show", - "movie": "Movie", - "album": "Album" + "ContinueButton": "Continue", + "Available": "Available", + "Available4K": "Available 4K", + "Approved": "Approved", + "Approve4K": "Approve 4K", + "Pending": "Pending", + "PartiallyAvailable": "Partially Available", + "Monitored": "Monitored", + "NotAvailable": "Not Available", + "ProcessingRequest": "Processing Request", + "ProcessingRequest4K": "Processing Request 4K", + "PendingApproval": "Pending Approval", + "PendingApproval4K": "Pending Approval 4K", + "RequestDenied": "Request Denied", + "RequestDenied4K": "Request Denied 4K", + "NotRequested": "Not Requested", + "NotRequested4K": "Not Requested 4K", + "Requested": "Requested", + "Requested4K": "Requested 4K", + "Search": "Search", + "Request": "Request", + "Request4K": "Request 4K", + "Denied": "Denied", + "Approve": "Approve", + "PartlyAvailable": "Partly Available", + "ViewDetails": "View Details", + "Errors": { + "Validation": "Please check your entered values" + }, + "Cancel": "Cancel", + "Submit": "Submit", + "Update": "Update", + "tvShow": "TV Show", + "movie": "Movie", + "album": "Album" }, "PasswordReset": { "EmailAddressPlaceholder": "Email Address", @@ -55,6 +63,10 @@ "OfflineParagraph": "The media server is currently offline.", "CheckPageForUpdates": "Check this page for continuous site updates." }, + "ErrorPages": { + "NotFound": "Page not found", + "SomethingWentWrong": "Something went wrong!" + }, "NavigationBar": { "Discover": "Discover", "Search": "Search", @@ -131,6 +143,9 @@ }, "AdvancedSearchInstructions": "Please choose what type of media you are searching for:", "YearOfRelease": "Year of Release", + "SearchGenre": "Search Genre", + "SearchKeyword": "Search Keyword", + "SearchProvider": "Search Provider", "KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb" }, "Requests": { @@ -155,9 +170,13 @@ "ChangeRootFolder": "Root Folder", "ChangeQualityProfile": "Quality Profile", "MarkUnavailable": "Mark Unavailable", + "MarkUnavailable4K": "Mark Unavailable 4K", "MarkAvailable": "Mark Available", + "MarkAvailable4K": "Mark Available 4K", "Remove": "Remove", "Deny": "Deny", + "Deny4K": "Deny 4K", + "Has4KRequest": "Has 4K Request", "DenyReason": "Deny Reason", "DeniedReason": "Denied Reason", "Season": "Season", @@ -193,11 +212,16 @@ "RequestPanel": { "Delete":"Delete Request", "Approve":"Approve Request", + "Deny":"Deny Request", + "Approve4K":"Approve 4K Request", + "Deny4K":"Deny 4K Request", "ChangeAvailability":"Mark Available", "Deleted": "Successfully deleted selected items", - "Approved": "Successfully approved selected items" + "Approved": "Successfully approved selected items", + "Denied": "Successfully denied selected items" }, "SuccessfullyApproved": "Successfully Approved", + "SuccessfullyDeleted": "Request successfully deleted", "NowAvailable": "Request is now available", "NowUnavailable": "Request is now unavailable", "SuccessfullyReprocessed": "Successfully Re-processed the request", @@ -219,10 +243,16 @@ "MovieRequestQuotaExceeded":"You have exceeded your Movie request quota!", "TvRequestQuotaExceeded":"You have exceeded your Episode request quota!", "AlbumRequestQuotaExceeded":"You have exceeded your Album request quota!" - } + }, + "Notify": "Notify", + "RemoveNotification": "Remove Notifications", + "SuccessfulNotify":"You will now be notified for title {{title}}", + "SuccessfulUnNotify":"You will no longer be notified for title {{title}}", + "CouldntNotify":"Couldn't notify title {{title}}" }, "Issues": { "Title": "Issues", + "IssuesForTitle": "Issues for {{title}}", "PendingTitle": "Pending Issues", "InProgressTitle": "In Progress Issues", "ResolvedTitle": "Resolved Issues", @@ -255,6 +285,7 @@ "Delete": "Delete issue", "DeletedIssue": "Issue has been deleted", "Chat":"Chat", + "EnterYourMessage":"Enter Your Message", "Requested":"Requested", "UserOnDate": "{{user}} on {{date}}" }, @@ -281,6 +312,8 @@ }, "MediaDetails": { "Denied": "Denied", + "Denied4K": "Denied 4K", + "Trailers": "Trailers", "RecommendationsTitle": "Recommendations", "SimilarTitle": "Similar", "VideosTitle": "Videos", @@ -291,9 +324,9 @@ "ViewCollection":"View Collection", "NotEnoughInfo": "Unfortunately there is not enough information about this show yet!", "AdvancedOptions":"Advanced Options", - "AutoApproveOptions":"You can configure the request here, once requested it will be send to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTv":"You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTvShort":"You can configure the request here, once requested it will be send to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptions":"You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTv":"You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTvShort":"You can configure the request here, once requested it will be sent to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", "QualityProfilesSelect":"Select A Quality Profile", "RootFolderSelect":"Select A Root Folder", "LanguageProfileSelect":"Select A Language Profile", @@ -312,12 +345,13 @@ "Seasons": "Seasons:", "Episodes": "Episodes:", "Availability":"Availability:", - "RequestStatus":"Request Status", + "RequestStatus":"Request Status:", "Quality":"Quality:", "RootFolderOverride":"Root Folder Override:", "QualityOverride":"Quality Override:", "Network":"Network:", - "Genres":"Genres:", + "GenresLabel":"Genres:", + "Genres":"Genres", "FirstAired":"First Aired:", "TheatricalRelease":"Release:", "DigitalRelease":"Digital Release:", @@ -343,15 +377,18 @@ "PleaseSelectUser": "Please select a user", "StreamingOn": "Streaming On:", "RequestedBy": "Requested By:", + "RequestedByOn": "Requested By {{user}} on {{date}}", "RequestDate": "Request Date:", "DeniedReason": "Denied Reason:", "ReProcessRequest": "Re-Process Request", + "ReProcessRequest4K": "Re-Process 4K Request", "Music": { "Type": "Type:", "Country": "Country:", "StartDate": "Start Date:", "EndDate": "EndDate:" - } + }, + "RequestSource":"Source:" }, "Discovery": { "PopularTab": "Popular", @@ -382,7 +419,7 @@ "DarkMode": "Dark Mode", "Updated": "Successfully Updated", "StreamingCountry":"Streaming Country", - "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will have US related streaming information.", + "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will get US related streaming information.", "LanguageDescription": "This is the language you would like the Ombi interface to be displayed in.", "MobileQRCode":"Mobile QR Code", "LegacyApp":"Launch Legacy App", @@ -396,7 +433,8 @@ "NewPasswordConfirm": "New Password Confirm", "Security": "Security", "Profile": "Profile", - "UpdatedYourInformation": "Updated your information" + "UpdatedYourInformation": "Updated your information", + "Unsubscribed": "Unsubscribed!" }, "UserTypeLabel": { "1": "Local User", @@ -404,6 +442,15 @@ "3": "Emby User", "4": "Emby Connect User", "5": "Jellyfin User" + }, + "Paginator": { + "itemsPerPageLabel": "Items per page:", + "nextPageLabel": "Next page", + "previousPageLabel": "Previous page", + "firstPageLabel": "First page", + "lastPageLabel": "Last page", + "rangePageLabel1": "0 of {{length}}", + "rangePageLabel2": "{{startIndex}} – {{endIndex}} of {{length}}" } } diff --git a/src/Ombi/wwwroot/translations/es.json b/src/Ombi/wwwroot/translations/es.json index 0a61ca8af..cc3cd9fb3 100644 --- a/src/Ombi/wwwroot/translations/es.json +++ b/src/Ombi/wwwroot/translations/es.json @@ -14,18 +14,26 @@ "Common": { "ContinueButton": "Continuar", "Available": "Disponible", + "Available4K": "Disponible 4K", "Approved": "Aprobado", + "Approve4K": "Aprobar 4K", "Pending": "Pendiente", "PartiallyAvailable": "Disponible parcialmente", "Monitored": "Monitoreado", "NotAvailable": "No disponible", "ProcessingRequest": "Procesando solicitud", + "ProcessingRequest4K": "Procesando Solicitud 4K", "PendingApproval": "Pendiente de aprobación", + "PendingApproval4K": "Pendiente de Aprobación 4K", "RequestDenied": "Solicitud denegada", + "RequestDenied4K": "Solicitud Denegada 4K", "NotRequested": "No solicitado", + "NotRequested4K": "No Solicitado 4K", "Requested": "Solicitado", + "Requested4K": "Solicitado 4K", "Search": "Buscar", "Request": "Solicitar", + "Request4K": "Solicitar 4K", "Denied": "Denegado", "Approve": "Aprobar", "PartlyAvailable": "Disponible parcialmente", @@ -38,7 +46,7 @@ "Update": "Actualización", "tvShow": "Programa de televisión", "movie": "Película", - "album": "Album" + "album": "Álbum" }, "PasswordReset": { "EmailAddressPlaceholder": "Correo electrónico", @@ -55,6 +63,10 @@ "OfflineParagraph": "El servidor de medios está fuera de línea.", "CheckPageForUpdates": "Consulta esta página para ver las últimas novedades." }, + "ErrorPages": { + "NotFound": "Página no encontrada", + "SomethingWentWrong": "¡Algo salió mal!" + }, "NavigationBar": { "Discover": "Descubre", "Search": "Buscar", @@ -131,6 +143,9 @@ }, "AdvancedSearchInstructions": "Por favor, elija el tipo de medio que está buscando:", "YearOfRelease": "Año de lanzamiento", + "SearchGenre": "Buscar por género", + "SearchKeyword": "Buscar palabra clave", + "SearchProvider": "Proveedor de búsqueda", "KeywordSearchingDisclaimer": "Por favor, ten en cuenta que la búsqueda de palabras clave es poco confiable debido a la inconsistencia en la base de datos de TheMovieDb" }, "Requests": { @@ -155,9 +170,13 @@ "ChangeRootFolder": "Carpeta raíz", "ChangeQualityProfile": "Perfil de calidad", "MarkUnavailable": "Marcar como no disponible", + "MarkUnavailable4K": "Marcar No Disponible 4K", "MarkAvailable": "Marcar Disponible", + "MarkAvailable4K": "Marcar Disponible 4K", "Remove": "Eliminar", "Deny": "Denegar", + "Deny4K": "Rechazar 4K", + "Has4KRequest": "Tiene Solicitud 4K", "DenyReason": "Razón Denegada", "DeniedReason": "Motivo de denegación", "Season": "Temporada", @@ -193,11 +212,16 @@ "RequestPanel": { "Delete": "Eliminar solicitud", "Approve": "Aprobar Solicitud", + "Deny": "Rechazar Solicitud", + "Approve4K": "Aprobar Solicitud 4K", + "Deny4K": "Rechazar Solicitud 4K", "ChangeAvailability": "Marcar como disponible", "Deleted": "Los elementos seleccionados ha sido eliminados correctamente", - "Approved": "Los elementos seleccionados ha sido aprobados correctamente" + "Approved": "Los elementos seleccionados ha sido aprobados correctamente", + "Denied": "Elementos seleccionados rechazados con éxito" }, "SuccessfullyApproved": "Se ha aprobado con éxito", + "SuccessfullyDeleted": "Solicitud eliminada con éxito", "NowAvailable": "La solicitud está disponible", "NowUnavailable": "La solicitud no está disponible", "SuccessfullyReprocessed": "La solicitud ha sido procesada correctamente", @@ -207,22 +231,28 @@ "NeedToSelectEpisodes": "¡Necesitas seleccionar algunos episodios!", "RequestAddedSuccessfully": "La solicitud de {{title}} se ha añadido correctamente", "ErrorCodes": { - "AlreadyRequested": "This has already been requested", - "EpisodesAlreadyRequested": "We already have episodes requested from this series", - "NoPermissionsOnBehalf": "You do not have the correct permissions to request on behalf of users!", - "NoPermissions": "You do not have the correct permissions!", - "RequestDoesNotExist": "Request does not exist", - "ChildRequestDoesNotExist": "Child Request does not exist", - "NoPermissionsRequestMovie": "You do not have permissions to Request a Movie", - "NoPermissionsRequestTV": "You do not have permissions to Request a TV Show", - "NoPermissionsRequestAlbum": "You do not have permissions to Request an Album", - "MovieRequestQuotaExceeded": "You have exceeded your Movie request quota!", - "TvRequestQuotaExceeded": "You have exceeded your Episode request quota!", - "AlbumRequestQuotaExceeded": "You have exceeded your Album request quota!" - } + "AlreadyRequested": "Ya se ha solicitado", + "EpisodesAlreadyRequested": "Ya tenemos episodios solicitados de esta serie", + "NoPermissionsOnBehalf": "No tienes los permisos correctos para solicitar en nombre de los usuarios!", + "NoPermissions": "¡No tienes los permisos apropiados!", + "RequestDoesNotExist": "Esta petición no existe", + "ChildRequestDoesNotExist": "Esta petición no existe", + "NoPermissionsRequestMovie": "No tienes permiso para solicitar una película", + "NoPermissionsRequestTV": "No tienes permiso para solicitar un Programa de televisión", + "NoPermissionsRequestAlbum": "No tienes permiso para solicitar un Álbum", + "MovieRequestQuotaExceeded": "¡Has superado tu cuota de solicitudes de películas!", + "TvRequestQuotaExceeded": "¡Has superado tu cuota de solicitudes de series!", + "AlbumRequestQuotaExceeded": "¡Has superado tu cuota de solicitudes de álbumes!" + }, + "Notify": "Notificar", + "RemoveNotification": "Eliminar notificación", + "SuccessfulNotify": "Se te notificará para el título {{title}}", + "SuccessfulUnNotify": "No se te notificará para el título {{title}}", + "CouldntNotify": "No se pudo notificar el título {{title}}" }, "Issues": { "Title": "Problemas", + "IssuesForTitle": "Problemas de {{title}}", "PendingTitle": "Problemas pendientes", "InProgressTitle": "Problemas en curso", "ResolvedTitle": "Problemas resueltos", @@ -255,6 +285,7 @@ "Delete": "Borrar problema", "DeletedIssue": "El problema ha sido borrado", "Chat": "Chat", + "EnterYourMessage": "Ingrese Su Mensaje", "Requested": "Solicitado", "UserOnDate": "{{user}} en {{date}}" }, @@ -281,6 +312,8 @@ }, "MediaDetails": { "Denied": "Denegado", + "Denied4K": "Rechazado 4K", + "Trailers": "Trailer", "RecommendationsTitle": "Recomendaciones", "SimilarTitle": "Similar", "VideosTitle": "Vídeos", @@ -291,42 +324,43 @@ "ViewCollection": "Ver Colección", "NotEnoughInfo": "Desafortunadamente todavía no hay suficiente información sobre este programa!", "AdvancedOptions": "Opciones Avanzadas", - "AutoApproveOptions": "Puede configurar la solicitud aquí. Una vez solicitado, se enviará a su aplicación DVR y se aprobará automáticamente. Tenga en cuenta que esto es opcional, presione \"Preguntar\" para saltar.", - "AutoApproveOptionsTv": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be send to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptions": "Puede configurar la solicitud aquí. Una vez solicitado, se te enviará a tu aplicación DVR y se aprobará automáticamente. Ten en cuenta que esto es opcional, presiona \"Solicitar\" para saltar!", + "AutoApproveOptionsTv": "Puede configurar la solicitud aquí, una vez solicitada será enviada a su aplicación DVR y será aprobada automáticamente! Si la solicitud ya está en Sonarr, no cambiaremos la carpeta raíz o el perfil de calidad! Ten en cuenta que esto es opcional, pulsa Solicitar para saltar!", + "AutoApproveOptionsTvShort": "Puede configurar la solicitud aquí. Una vez solicitado, se te enviará a tu aplicación DVR. Si la solicitud ya está en Sonarr, no cambiaremos la carpeta raíz o el perfil de calidad. Ten en cuenta que esto es opcional, presiona \"Solicitar\" para saltar!", "QualityProfilesSelect": "Seleccione un Perfil de Calidad", "RootFolderSelect": "Seleccione una Carpeta Raíz", - "LanguageProfileSelect": "Select A Language Profile", + "LanguageProfileSelect": "Seleccione un perfil de idioma", "Status": "Estado:", "StatusValues": { - "Rumored": "Rumored", + "Rumored": "Rumoreada", "Planned": "Planificado", "In Production": "En Producción", - "Post Production": "Post Production", + "Post Production": "Post-Producción", "Released": "En cines", - "Running": "Running", - "Returning Series": "Returning Series", + "Running": "En emisión", + "Returning Series": "Serie que regresa", "Ended": "Finalizada", "Canceled": "Cancelada" }, "Seasons": "Temporadas:", "Episodes": "Episodios:", "Availability": "Disponibilidad:", - "RequestStatus": "Estado de solicitud", + "RequestStatus": "Estado de Solicitud:", "Quality": "Calidad:", - "RootFolderOverride": "Root Folder Override:", - "QualityOverride": "Quality Override:", - "Network": "Network:", - "Genres": "Genres:", - "FirstAired": "First Aired:", - "TheatricalRelease": "Release:", - "DigitalRelease": "Digital Release:", - "Votes": "Votes:", - "Runtime": "Runtime:", + "RootFolderOverride": "Sobreescribir carpeta raíz:", + "QualityOverride": "Sobreescribir calidad:", + "Network": "Cadena:", + "GenresLabel": "Géneros:", + "Genres": "Géneros", + "FirstAired": "Emitido por primera vez:", + "TheatricalRelease": "Lanzamiento:", + "DigitalRelease": "Estreno Digital:", + "Votes": "Votos:", + "Runtime": "Duración:", "Minutes": "{{runtime}} Minutos", - "Revenue": "Revenue:", - "Budget": "Budget:", - "Keywords": "Keywords/Tags:", + "Revenue": "Ingresos:", + "Budget": "Presupuesto:", + "Keywords": "Palabras clave/Etiquetas:", "Casts": { "CastTitle": "Enviar pantalla" }, @@ -334,31 +368,34 @@ "AllSeasonsTooltip": "Esto solicitará cada temporada para este programa", "FirstSeasonTooltip": "Esto solo solicitará la primera temporada para este programa", "LatestSeasonTooltip": "Esto solo solicitará la última temporada para este programa", - "NoEpisodes": "There unfortunately is no episode data for this show yet!", - "SeasonNumber": "Season {{number}}" + "NoEpisodes": "Lamentablemente, no hay datos de episodio para este programa de televisión todavía!", + "SeasonNumber": "Temporada {{number}}" }, - "SonarrConfiguration": "Sonarr Configuration", - "RadarrConfiguration": "Radarr Configuration", - "RequestOnBehalf": "Request on behalf of", - "PleaseSelectUser": "Please select a user", - "StreamingOn": "Streaming On:", - "RequestedBy": "Requested By:", - "RequestDate": "Request Date:", - "DeniedReason": "Denied Reason:", - "ReProcessRequest": "Re-Process Request", + "SonarrConfiguration": "Configuración de Sonarr", + "RadarrConfiguration": "Configuración de Radarr", + "RequestOnBehalf": "Solicitar en nombre de", + "PleaseSelectUser": "Seleccione un usuario", + "StreamingOn": "Emitido en:", + "RequestedBy": "Solicitado por:", + "RequestedByOn": "Solicitado por {{user}} el {{date}}", + "RequestDate": "Fecha de solicitud:", + "DeniedReason": "Motivo de denegación:", + "ReProcessRequest": "Re-procesar solicitud", + "ReProcessRequest4K": "Reprocesar Solicitud 4K", "Music": { - "Type": "Type:", - "Country": "Country:", - "StartDate": "Start Date:", - "EndDate": "EndDate:" - } + "Type": "Tipo:", + "Country": "País:", + "StartDate": "Fecha de inicio:", + "EndDate": "Fecha de finalización:" + }, + "RequestSource": "Fuente:" }, "Discovery": { "PopularTab": "Popular", "TrendingTab": "Tendencias", "UpcomingTab": "Próximamente", - "SeasonalTab": "Seasonal", - "RecentlyRequestedTab": "Recently Requested", + "SeasonalTab": "Por Temporada", + "RecentlyRequestedTab": "Solicitudes recientes", "Movies": "Películas", "Combined": "Combinado", "Tv": "TV", @@ -374,35 +411,45 @@ "Writer": "Guionistas", "ExecProducer": "Productor ejecutivo" }, - "NoSearch": "Sorry, nothing matches your search!" + "NoSearch": "¡Lo sentimos, nada coincide con tu búsqueda!" }, "UserPreferences": { "Welcome": "Bienvenido {{username}}!", "OmbiLanguage": "Idioma", "DarkMode": "Modo Oscuro", - "Updated": "Successfully Updated", - "StreamingCountry": "Streaming Country", - "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will have US related streaming information.", - "LanguageDescription": "This is the language you would like the Ombi interface to be displayed in.", - "MobileQRCode": "Mobile QR Code", - "LegacyApp": "Launch Legacy App", - "NoQrCode": "Please contact your administrator to enable QR codes", - "UserType": "User Type:", - "ChangeDetails": "Change Details", - "NeedCurrentPassword": "You need your current password to make any changes here", - "CurrentPassword": "Current Password", - "EmailAddress": "Email Address", - "NewPassword": "New Password", - "NewPasswordConfirm": "New Password Confirm", - "Security": "Security", - "Profile": "Profile", - "UpdatedYourInformation": "Updated your information" + "Updated": "Actualizado correctamente", + "StreamingCountry": "País de emisión", + "StreamingCountryDescription": "Este es el código de país desde el que mostraremos información de emisión. Si estás en España, por favor selecciona ES y tendrás información relacionada con la emisión en España.", + "LanguageDescription": "Este es el idioma en el que desea mostrar la interfaz de Ombi.", + "MobileQRCode": "Código QR móvil", + "LegacyApp": "Iniciar aplicación antigua", + "NoQrCode": "Ponte en contacto con tu administrador para habilitar los códigos QR", + "UserType": "Tipo de usuario:", + "ChangeDetails": "Modificar mis datos", + "NeedCurrentPassword": "Necesitamos tu contraseña actual para confirmar los cambios", + "CurrentPassword": "Contraseña actual", + "EmailAddress": "Correo electrónico", + "NewPassword": "Nueva Contraseña", + "NewPasswordConfirm": "Confirmar contraseña", + "Security": "Seguridad", + "Profile": "Perfil", + "UpdatedYourInformation": "Información actualizada", + "Unsubscribed": "No suscrito!" }, "UserTypeLabel": { "1": "Usuario local", "2": "Usuario de Plex", "3": "Usuario de Emby", - "4": "Emby Connect User", + "4": "Conectar usuario de Emby", "5": "Usuario de Jellyfin" + }, + "Paginator": { + "itemsPerPageLabel": "Elementos por página:", + "nextPageLabel": "Página siguiente", + "previousPageLabel": "Página anterior", + "firstPageLabel": "Primera página", + "lastPageLabel": "Última página", + "rangePageLabel1": "0 de {{length}}", + "rangePageLabel2": "{{startIndex}} – {{endIndex}} de {{length}}" } } diff --git a/src/Ombi/wwwroot/translations/fr.json b/src/Ombi/wwwroot/translations/fr.json index e3f6ba8bb..24d1306ac 100644 --- a/src/Ombi/wwwroot/translations/fr.json +++ b/src/Ombi/wwwroot/translations/fr.json @@ -4,8 +4,8 @@ "UsernamePlaceholder": "Nom d’utilisateur", "PasswordPlaceholder": "Mot de passe", "RememberMe": "Se souvenir de moi", - "SignInWith": "Se Connecter avec {{appName}}", - "SignInWithPlex": "Se Connecter avec Plex", + "SignInWith": "Se connecter avec {{appName}}", + "SignInWithPlex": "Se connecter avec Plex", "ForgottenPassword": "Mot de passe oublié ?", "Errors": { "IncorrectCredentials": "Nom d'utilisateur ou mot de passe incorrect" @@ -14,24 +14,32 @@ "Common": { "ContinueButton": "Continuer", "Available": "Disponible", + "Available4K": "4K disponible", "Approved": "Approuvée", + "Approve4K": "Approuver 4K", "Pending": "En attente", "PartiallyAvailable": "Partiellement disponible", "Monitored": "Suivi", "NotAvailable": "Non disponible", "ProcessingRequest": "En cours de traitement", + "ProcessingRequest4K": "4K en cours de traitement", "PendingApproval": "En attente d'approbation", + "PendingApproval4K": "En attente d'approbation 4K", "RequestDenied": "Demande refusée", + "RequestDenied4K": "Demande 4K refusée", "NotRequested": "Non demandé", + "NotRequested4K": "4K non demandée", "Requested": "Demandé", + "Requested4K": "4K demandée", "Search": "Rechercher", "Request": "Demander", + "Request4K": "Demander en 4K", "Denied": "Refusé", "Approve": "Approuver", "PartlyAvailable": "Partiellement disponible", "ViewDetails": "Voir les détails", "Errors": { - "Validation": "Veuillez vérifier les valeurs entrées" + "Validation": "Veuillez vérifier les valeurs saisies" }, "Cancel": "Annuler", "Submit": "Envoyer", @@ -55,6 +63,10 @@ "OfflineParagraph": "Le serveur média est actuellement hors-ligne.", "CheckPageForUpdates": "Consultez cette page pour voir les mises à jour du site." }, + "ErrorPages": { + "NotFound": "Page non trouvée", + "SomethingWentWrong": "Une erreur s'est produite !" + }, "NavigationBar": { "Discover": "Découvrir", "Search": "Rechercher", @@ -62,14 +74,14 @@ "UserManagement": "Utilisateurs", "Issues": "Problèmes", "Vote": "Vote", - "Donate": "Faire un don !", + "Donate": "Faire un don", "DonateLibraryMaintainer": "Faire un don au mainteneur de la bibliothèque", "DonateTooltip": "C’est pour convaincre ma femme de me laisser passer mon temps libre à développer Ombi 😁", "UpdateAvailableTooltip": "Mise à jour disponible !", "Settings": "Paramètres", "Welcome": "Bienvenue {{username}}", "UpdateDetails": "Mettre à jour les informations", - "Logout": "Déconnexion", + "Logout": "Se déconnecter", "OpenMobileApp": "Ouvrir l'application", "RecentlyAdded": "Ajouts récents", "ChangeTheme": "Changer de thème", @@ -89,7 +101,7 @@ }, "Search": { "Title": "Rechercher", - "Paragraph": "Vous voulez regarder quelque chose qui n'est pas disponible actuellement ? Pas de problème, recherchez-le ci-dessous et demandez-le !", + "Paragraph": "Vous voulez regarder quelque chose qui n'est pas disponible actuellement ? Pas de problème, recherchez-le en bas et demandez-le !", "MoviesTab": "Films", "TvTab": "Séries", "MusicTab": "Musique", @@ -118,9 +130,9 @@ "Popular": "Populaire", "Trending": "Tendances", "MostWatched": "Les plus visionnées", - "MostAnticipated": "Les plus attendus", + "MostAnticipated": "Les plus attendues", "Results": "Résultats", - "AirDate": "Date de diffusion:", + "AirDate": "Date de diffusion :", "AllSeasons": "Toutes les saisons", "FirstSeason": "Première saison", "LatestSeason": "Dernière saison", @@ -131,6 +143,9 @@ }, "AdvancedSearchInstructions": "Veuillez choisir le type de média que vous recherchez :", "YearOfRelease": "Année de sortie", + "SearchGenre": "Rechercher un genre", + "SearchKeyword": "Rechercher un mot-clé", + "SearchProvider": "Rechercher un fournisseur", "KeywordSearchingDisclaimer": "Veuillez noter que la recherche de mots-clés n'est pas très fiable en raison de données incohérentes dans TheMovieDb" }, "Requests": { @@ -145,19 +160,23 @@ "Status": "Statut", "RequestStatus": "Statut de la demande", "Denied": " Refusé :", - "TheatricalRelease": "Sortie en salle: {{date}}", + "TheatricalRelease": "Sortie en salle : {{date}}", "ReleaseDate": "Sortie : {{date}}", "TheatricalReleaseSort": "Sortie en salle", - "DigitalRelease": "Sortie numérique: {{date}}", + "DigitalRelease": "Sortie numérique : {{date}}", "RequestDate": "Date de la demande", "QualityOverride": "Remplacement de la qualité :", "RootFolderOverride": "Remplacement du répertoire racine :", "ChangeRootFolder": "Répertoire racine", "ChangeQualityProfile": "Profil de qualité", - "MarkUnavailable": "Marquer comme non disponible", - "MarkAvailable": "Marquer comme disponible", + "MarkUnavailable": "Marquer indisponible", + "MarkUnavailable4K": "Marquer 4K indisponible", + "MarkAvailable": "Marquer disponible", + "MarkAvailable4K": "Marquer 4K disponible", "Remove": "Supprimer", "Deny": "Refuser", + "Deny4K": "Refuser 4K", + "Has4KRequest": "A une demande 4K", "DenyReason": "Motif de refus", "DeniedReason": "Motif de refus", "Season": "Saison", @@ -193,11 +212,16 @@ "RequestPanel": { "Delete": "Supprimer la demande", "Approve": "Approuver la demande", + "Deny": "Refuser la demande", + "Approve4K": "Approuver la demande 4K", + "Deny4K": "Refuser la demande 4K", "ChangeAvailability": "Marquer comme Disponible", "Deleted": "Éléments sélectionnés supprimés avec succès", - "Approved": "Éléments sélectionnés approuvés avec succès" + "Approved": "Éléments sélectionnés approuvés avec succès", + "Denied": "Les éléments sélectionnés ont été refusés" }, "SuccessfullyApproved": "Approuvée avec succès", + "SuccessfullyDeleted": "Demande supprimée avec succès", "NowAvailable": "La demande est maintenant disponible", "NowUnavailable": "La demande est maintenant indisponible", "SuccessfullyReprocessed": "La demande a été retraitée avec succès", @@ -215,14 +239,20 @@ "ChildRequestDoesNotExist": "La demande enfant n'existe pas", "NoPermissionsRequestMovie": "Vous n'avez pas la permission de demander un film", "NoPermissionsRequestTV": "Vous n'avez pas la permission de demander une série TV", - "NoPermissionsRequestAlbum": "Vous n'avez pas la permission de demander un album", - "MovieRequestQuotaExceeded": "Vous avez dépassé votre quota de demande de films !", - "TvRequestQuotaExceeded": "Vous avez dépassé votre quota de demande d'épisodes !", - "AlbumRequestQuotaExceeded": "Vous avez dépassé votre quota de demande d'albums !" - } + "NoPermissionsRequestAlbum": "Vous n'avez pas le droit de demander un album", + "MovieRequestQuotaExceeded": "Vous avez dépassé votre quota de demandes de films !", + "TvRequestQuotaExceeded": "Vous avez dépassé votre quota de demandes d'épisodes !", + "AlbumRequestQuotaExceeded": "Vous avez dépassé votre quota de demandes d'albums !" + }, + "Notify": "Notifier", + "RemoveNotification": "Supprimer les notifications", + "SuccessfulNotify": "Vous allez maintenant être notifié pour {{title}}", + "SuccessfulUnNotify": "Vous ne serez plus notifié pour {{title}}", + "CouldntNotify": "Impossible de notifier {{title}}" }, "Issues": { "Title": "Problèmes", + "IssuesForTitle": "Problèmes pour {{title}}", "PendingTitle": "Problèmes en attente", "InProgressTitle": "Problèmes en cours", "ResolvedTitle": "Problèmes résolus", @@ -236,7 +266,7 @@ "MarkInProgress": "Marquer en cours de traitement", "MarkResolved": "Marquer comme résolu", "SendMessageButton": "Envoyer", - "Subject": "Sujet", + "Subject": "Objet", "Comments": "Commentaires", "WriteMessagePlaceholder": "Écrivez votre message ici...", "ReportedBy": "Signalé par", @@ -255,6 +285,7 @@ "Delete": "Supprimer le problème", "DeletedIssue": "Problème supprimé", "Chat": "Discuter", + "EnterYourMessage": "Saisissez votre message", "Requested": "Demandé", "UserOnDate": "{{user}} le {{date}}" }, @@ -268,9 +299,9 @@ "Keywords": "Mots-clés" }, "UserManagment": { - "TvRemaining": "Séries : {{remaining}}/{{total}} restant(s)", - "MovieRemaining": "Films : {{remaining}}/{{total}} restant(s)", - "MusicRemaining": "Musique : {{remaining}}/{{total}} restant(s)", + "TvRemaining": "Séries : {{remaining}}/{{total}} restante(s)", + "MovieRemaining": "Films : {{remaining}}/{{total}} restante(s)", + "MusicRemaining": "Musique : {{remaining}}/{{total}} restante(s)", "TvDue": "Séries : {{date}}", "MovieDue": "Film : {{date}}", "MusicDue": "Musique : {{date}}" @@ -281,6 +312,8 @@ }, "MediaDetails": { "Denied": "Refusé", + "Denied4K": "4K refusée", + "Trailers": "Bandes-annonces", "RecommendationsTitle": "Recommandations", "SimilarTitle": "Similaires", "VideosTitle": "Vidéos", @@ -300,33 +333,34 @@ "Status": "Statut :", "StatusValues": { "Rumored": "Rumeur", - "Planned": "Planifié", + "Planned": "Prévu", "In Production": "En Production", "Post Production": "Post-production", "Released": "Sorti", "Running": "En cours", "Returning Series": "Série en cours", - "Ended": "Finie", + "Ended": "Terminée", "Canceled": "Annulée" }, "Seasons": "Saisons :", "Episodes": "Épisodes :", "Availability": "Disponibilité :", - "RequestStatus": "Statut de la Demande", + "RequestStatus": "Statut de la demande :", "Quality": "Qualité :", - "RootFolderOverride": "Remplacement du répertoire racine :", - "QualityOverride": "Remplacement de la qualité :", + "RootFolderOverride": "Répertoire racine remplacé :", + "QualityOverride": "Qualité remplacée :", "Network": "Diffuseur :", - "Genres": "Genres :", + "GenresLabel": "Genres :", + "Genres": "Genres", "FirstAired": "Première diffusion :", - "TheatricalRelease": "Sortie :", + "TheatricalRelease": "Sortie en salle :", "DigitalRelease": "Sortie numérique :", "Votes": "Votes :", "Runtime": "Durée :", "Minutes": "{{runtime}} Minutes", "Revenue": "Recettes :", "Budget": "Budget :", - "Keywords": "Mots-clés / Tags :", + "Keywords": "Mots-clés/Tags :", "Casts": { "CastTitle": "Casting" }, @@ -343,15 +377,18 @@ "PleaseSelectUser": "Veuillez sélectionner un utilisateur", "StreamingOn": "En streaming sur :", "RequestedBy": "Demandé par :", + "RequestedByOn": "Demandé par {{user}} le {{date}}", "RequestDate": "Date de la demande :", "DeniedReason": "Motif de refus :", "ReProcessRequest": "Refaire une demande", + "ReProcessRequest4K": "Retraiter la demande 4K", "Music": { "Type": "Type :", "Country": "Pays :", "StartDate": "Date de début :", "EndDate": "Date de fin :" - } + }, + "RequestSource": "Source :" }, "Discovery": { "PopularTab": "Populaire", @@ -367,23 +404,23 @@ "Studio": "Studio", "Network": "Diffuseur", "UnknownNetwork": "Inconnu", - "RequestStatus": "Statut de la Demande", + "RequestStatus": "Statut de la demande", "Director": "Réalisateur", - "InCinemas": "En Salles", - "FirstAired": "Première Diffusion", + "InCinemas": "En salles", + "FirstAired": "Première diffusion", "Writer": "Scénariste", - "ExecProducer": "Producteur Exécutif" + "ExecProducer": "Producteur exécutif" }, "NoSearch": "Désolé, rien ne correspond à votre recherche !" }, "UserPreferences": { "Welcome": "Bienvenue {{username}} !", "OmbiLanguage": "Langue", - "DarkMode": "Mode Sombre", + "DarkMode": "Mode sombre", "Updated": "Mise à jour réussie", "StreamingCountry": "Pays de diffusion", - "StreamingCountryDescription": "C'est le code du pays pour lequel nous afficherons des informations de diffusion. Si vous êtes en France, veuillez sélectionner la France et vous aurez des informations de streaming en relation avec la France.", - "LanguageDescription": "C'est la langue dans laquelle vous souhaitez que l'interface Ombi soit affichée.", + "StreamingCountryDescription": "C'est le code du pays dont nous afficherons les informations de diffusion. Si vous êtes en France, veuillez sélectionner la France et vous aurez des informations de streaming pour la France.", + "LanguageDescription": "C'est la langue dans laquelle vous souhaitez que le site d'Ombi soit affichée.", "MobileQRCode": "QR Code mobile", "LegacyApp": "Lancer l'ancienne application", "NoQrCode": "Veuillez contacter votre administrateur pour activer les QR codes", @@ -396,7 +433,8 @@ "NewPasswordConfirm": "Confirmation du nouveau mot de passe", "Security": "Sécurité", "Profile": "Profil", - "UpdatedYourInformation": "Informations mises à jour" + "UpdatedYourInformation": "Informations mises à jour", + "Unsubscribed": "Désabonné !" }, "UserTypeLabel": { "1": "Utilisateur local", @@ -404,5 +442,14 @@ "3": "Utilisateur Emby", "4": "Utilisateur Emby Connect", "5": "Utilisateur Jellyfin" + }, + "Paginator": { + "itemsPerPageLabel": "Éléments par page :", + "nextPageLabel": "Page suivante", + "previousPageLabel": "Page précédente", + "firstPageLabel": "Première page", + "lastPageLabel": "Dernière page", + "rangePageLabel1": "0 sur {{length}}", + "rangePageLabel2": "{{startIndex}} – {{endIndex}} sur {{length}}" } } diff --git a/src/Ombi/wwwroot/translations/hu.json b/src/Ombi/wwwroot/translations/hu.json index ecae7d9ff..aa27af9a7 100644 --- a/src/Ombi/wwwroot/translations/hu.json +++ b/src/Ombi/wwwroot/translations/hu.json @@ -14,18 +14,26 @@ "Common": { "ContinueButton": "Tovább", "Available": "Elérhető", + "Available4K": "Available 4K", "Approved": "Jóváhagyva", + "Approve4K": "Approve 4K", "Pending": "Függőben", "PartiallyAvailable": "Részlegesen elérhető", "Monitored": "Figyelve", "NotAvailable": "Nem elérhető", "ProcessingRequest": "Kérés feldolgozása", + "ProcessingRequest4K": "Processing Request 4K", "PendingApproval": "Jóváhagyásra vár", + "PendingApproval4K": "Pending Approval 4K", "RequestDenied": "Kérés megtagadva", + "RequestDenied4K": "Request Denied 4K", "NotRequested": "Nincs kérve", + "NotRequested4K": "Not Requested 4K", "Requested": "Kérve", + "Requested4K": "Requested 4K", "Search": "Keresés", "Request": "Kérés", + "Request4K": "Request 4K", "Denied": "Megtagadva", "Approve": "Jóváhagyva", "PartlyAvailable": "Részlegesen elérhető", @@ -55,11 +63,15 @@ "OfflineParagraph": "A médiaszerver jelenleg nem elérhető.", "CheckPageForUpdates": "Látogasd meg ezt az oldalt a frissítésekhez." }, + "ErrorPages": { + "NotFound": "Az oldal nem található", + "SomethingWentWrong": "Something went wrong!" + }, "NavigationBar": { "Discover": "Felfedezés", "Search": "Keresés", "Requests": "Kérések", - "UserManagement": "Felhasználók kezelése", + "UserManagement": "Felhasználók", "Issues": "Problémák", "Vote": "Szavazás", "Donate": "Adakozás!", @@ -75,7 +87,7 @@ "ChangeTheme": "Téma váltása", "Calendar": "Naptár", "UserPreferences": "Beállítások", - "FeatureSuggestion": "Feature Suggestion", + "FeatureSuggestion": "Funkciójavaslás", "FeatureSuggestionTooltip": "Van egy jó ötleted? Oszd meg itt!", "Filter": { "Movies": "Filmek", @@ -131,7 +143,10 @@ }, "AdvancedSearchInstructions": "Kérlek válaszd ki, milyen típusú médiát keresel:", "YearOfRelease": "Megjelenés éve", - "KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb" + "SearchGenre": "Műfaj keresése", + "SearchKeyword": "Keresés kulcsszóra", + "SearchProvider": "Keresési szolgáltató", + "KeywordSearchingDisclaimer": "Megjegyzés: A kulcsszó keresés funkció nem megbízható a TheMovieDb adatainak inkonzisztenciája miatt" }, "Requests": { "Title": "Kérések", @@ -155,11 +170,15 @@ "ChangeRootFolder": "Gyökér mappa", "ChangeQualityProfile": "Minőség profil", "MarkUnavailable": "Megjelölés nem elérhetőnek", + "MarkUnavailable4K": "Mark Unavailable 4K", "MarkAvailable": "Megjelölés elérhetőnek", + "MarkAvailable4K": "Mark Available 4K", "Remove": "Törlés", "Deny": "Elutasítás", + "Deny4K": "Deny 4K", + "Has4KRequest": "Has 4K Request", "DenyReason": "Elutasítási ok", - "DeniedReason": "Denied Reason", + "DeniedReason": "Elutasítás oka", "Season": "Évad", "GridTitle": "Cím", "AirDate": "Bemutató", @@ -193,41 +212,52 @@ "RequestPanel": { "Delete": "Kérés törlése", "Approve": "Kérés elfogadása", + "Deny": "Deny Request", + "Approve4K": "Approve 4K Request", + "Deny4K": "Deny 4K Request", "ChangeAvailability": "Elérhetőnek jelölés", - "Deleted": "Successfully deleted selected items", - "Approved": "Successfully approved selected items" + "Deleted": "A kijelölt elemek törlésre kerultek", + "Approved": "A kijelölt elemek jóváhagyásra kerultek", + "Denied": "Successfully denied selected items" }, - "SuccessfullyApproved": "Successfully Approved", - "NowAvailable": "Request is now available", - "NowUnavailable": "Request is now unavailable", - "SuccessfullyReprocessed": "Successfully Re-processed the request", + "SuccessfullyApproved": "Sikeresen jóváhagyva", + "SuccessfullyDeleted": "Kérés sikeresen törölve", + "NowAvailable": "Kérés elérhető", + "NowUnavailable": "Kérés nem elérhető", + "SuccessfullyReprocessed": "Kérés sikeresen újra-feldolgozva", "DeniedRequest": "Elutasított kérés", - "RequestCollection": "Request Collection", - "CollectionSuccesfullyAdded": "The collection {{name}} has been successfully added!", - "NeedToSelectEpisodes": "You need to select some episodes!", - "RequestAddedSuccessfully": "Request for {{title}} has been added successfully", + "RequestCollection": "Kérés gyűjtemény", + "CollectionSuccesfullyAdded": "A(z) {{name}} gyűjtemény sikeresen hozzáadva!", + "NeedToSelectEpisodes": "Ki kell választani néhány epizódot!", + "RequestAddedSuccessfully": "Kérés sikeresen leadva erre: {{title}}", "ErrorCodes": { - "AlreadyRequested": "This has already been requested", - "EpisodesAlreadyRequested": "We already have episodes requested from this series", - "NoPermissionsOnBehalf": "You do not have the correct permissions to request on behalf of users!", - "NoPermissions": "You do not have the correct permissions!", - "RequestDoesNotExist": "Request does not exist", - "ChildRequestDoesNotExist": "Child Request does not exist", - "NoPermissionsRequestMovie": "You do not have permissions to Request a Movie", - "NoPermissionsRequestTV": "You do not have permissions to Request a TV Show", - "NoPermissionsRequestAlbum": "You do not have permissions to Request an Album", - "MovieRequestQuotaExceeded": "You have exceeded your Movie request quota!", - "TvRequestQuotaExceeded": "You have exceeded your Episode request quota!", - "AlbumRequestQuotaExceeded": "You have exceeded your Album request quota!" - } + "AlreadyRequested": "Ez már kérve lett", + "EpisodesAlreadyRequested": "Már vannak kért epizódok ehhez a sorozathoz", + "NoPermissionsOnBehalf": "Nincs jogosultságod más felhasználók nevében kérni!", + "NoPermissions": "Nincs megfelelő jogosultságod!", + "RequestDoesNotExist": "A kérés nem létezik", + "ChildRequestDoesNotExist": "Gyerek kérés nem létezik", + "NoPermissionsRequestMovie": "Nincs jogosultságod filmet kérni", + "NoPermissionsRequestTV": "Nincs jogosultságod sorozatot kérni", + "NoPermissionsRequestAlbum": "Nincs jogosultságod albumot kérni", + "MovieRequestQuotaExceeded": "Túllépted a megszabott film kérési kereted!", + "TvRequestQuotaExceeded": "Túllépted a megszabott epizód kérési kereted!", + "AlbumRequestQuotaExceeded": "Túllépted a megszabott album kérési kereted!" + }, + "Notify": "Értesítés", + "RemoveNotification": "Értesítések törlése", + "SuccessfulNotify": "Mostantól értesítve leszel erről: {{title}}", + "SuccessfulUnNotify": "Mostantól nem leszel értesítve erről: {{title}}", + "CouldntNotify": "Nem lehetett értesíteni erről: {{title}}" }, "Issues": { "Title": "Problémák", + "IssuesForTitle": "{{title}} problémái", "PendingTitle": "Várakozó problémák", "InProgressTitle": "Folyamatban lévő problémák", "ResolvedTitle": "Megoldott problémák", "ColumnTitle": "Cím", - "Count": "Count", + "Count": "Mennyiség", "Category": "Kategória", "Status": "Állapot", "Details": "Részletek", @@ -247,16 +277,17 @@ "SelectCategory": "Válassz kategóriát", "IssueCreated": "Hibajegy létrehozva" }, - "Outstanding": "There are outstanding issues", + "Outstanding": "Lezáratlan problémák vannak", "ResolvedDate": "Megoldás dátuma", - "CreatedDate": "Raised on", - "MarkedAsResolved": "This issue has now been marked as resolved!", - "MarkedAsInProgress": "This issue has now been marked as in progress!", - "Delete": "Delete issue", - "DeletedIssue": "Issue has been deleted", + "CreatedDate": "Létrejött", + "MarkedAsResolved": "Ez a hibajegy megoldottnak lett jelölve!", + "MarkedAsInProgress": "Ez a hibajegy folyamatban lévőnek lett jelölve!", + "Delete": "Hibajegy törlése", + "DeletedIssue": "Hibajegy törölve lett", "Chat": "Csevegő", - "Requested": "Requested", - "UserOnDate": "{{user}} on {{date}}" + "EnterYourMessage": "Írd be az üzeneted", + "Requested": "Kérve", + "UserOnDate": "{{user}} ekkor: {{date}}" }, "Filter": { "ClearFilter": "Szűrő törlése", @@ -265,7 +296,7 @@ "Approved": "Jóváhagyva", "PendingApproval": "Jóváhagyásra vár", "WatchProviders": "Watch Providers", - "Keywords": "Keywords" + "Keywords": "Kulcsszavak" }, "UserManagment": { "TvRemaining": "TV: {{remaining}}/{{total}} maradt", @@ -281,7 +312,9 @@ }, "MediaDetails": { "Denied": "Megtagadva", - "RecommendationsTitle": "Recommendations", + "Denied4K": "Denied 4K", + "Trailers": "Előzetesek", + "RecommendationsTitle": "Ajánlások", "SimilarTitle": "Hasonló", "VideosTitle": "Videók", "AlbumsTitle": "Albumok", @@ -289,22 +322,22 @@ "ClearSelection": "Kijelölés törlése", "RequestSelectedAlbums": "Kiválasztott albumok kérése", "ViewCollection": "Gyűjtemény megnézése", - "NotEnoughInfo": "Unfortunately there is not enough information about this show yet!", + "NotEnoughInfo": "Sajnos nincs elég információ erről a műsorról!", "AdvancedOptions": "Részletes beállítások", - "AutoApproveOptions": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTv": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be send to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptions": "Itt állíthatod be a kérésed részleteit. A kérés elküldése után a DVR applikációba kerül, ahol automatikusan elfogadásra fog kerülni! Megjegyzés: A beállítások nem kötelezőek, a kihagyásukhoz nyomd meg a Kérés gombot!", + "AutoApproveOptionsTv": "Itt állíthatod be a kérésed részleteit. A kérés elküldése után a DVR applikációba kerül, ahol automatikusan elfogadásra fog kerülni! Ha a kérés már megtalálható a Sonarrban, nem fogjuk megváltoztatni a gyökérkönyvtárat vagy a minőségi profilt, ha beállítod! Megjegyzés: A beállítások nem kötelezőek, a kihagyásukhoz nyomd meg a Kérés gombot!", + "AutoApproveOptionsTvShort": "Itt állíthatod be a kérésed részleteit. A kérés elküldése után a DVR applikációba kerül! Ha a kérés már megtalálható a Sonarrban, nem fogjuk megváltoztatni a gyökérkönyvtárat vagy a minőségi profilt, ha beállítod! Megjegyzés: A beállítások nem kötelezőek, a kihagyásukhoz nyomd meg a Kérés gombot!", "QualityProfilesSelect": "Válassz ki egy minőségprofilt", "RootFolderSelect": "Válassz ki egy gyökérmappát", "LanguageProfileSelect": "Válassz ki egy nyelvi profilt", "Status": "Állapot:", "StatusValues": { - "Rumored": "Rumored", - "Planned": "Planned", - "In Production": "In Production", - "Post Production": "Post Production", - "Released": "Released", - "Running": "Running", + "Rumored": "Híresztelt", + "Planned": "Tervezett", + "In Production": "Gyártás alatt", + "Post Production": "Utómunka alatt", + "Released": "Megjelent", + "Running": "Folyamatban", "Returning Series": "Visszatérő sorozatok", "Ended": "Befejezett", "Canceled": "Megszakított" @@ -312,18 +345,19 @@ "Seasons": "Évadok:", "Episodes": "Epizódok:", "Availability": "Elérhetőség:", - "RequestStatus": "Kérés állapota", + "RequestStatus": "Request Status:", "Quality": "Minőség:", "RootFolderOverride": "Gyökér mappa felülírása:", "QualityOverride": "Minőség felülírása:", - "Network": "Network:", - "Genres": "Műfaj:", + "Network": "Hálózat:", + "GenresLabel": "Műfajok:", + "Genres": "Műfajok", "FirstAired": "Első sugárzás ideje:", - "TheatricalRelease": "Release:", - "DigitalRelease": "Digital Release:", - "Votes": "Votes:", - "Runtime": "Runtime:", - "Minutes": "{{runtime}} Minutes", + "TheatricalRelease": "Kiadás:", + "DigitalRelease": "Digitális megjelenés:", + "Votes": "Szavazatok:", + "Runtime": "Hossz:", + "Minutes": "{{runtime}} perc", "Revenue": "Bevétel:", "Budget": "Költségvetés:", "Keywords": "Kulcsszavak/Címkék:", @@ -334,43 +368,46 @@ "AllSeasonsTooltip": "Ezzel kérni fogja a sorozat összes évadát", "FirstSeasonTooltip": "Ezzel kérni fogja a sorozat első évadát", "LatestSeasonTooltip": "Ezzel kérni fogja a sorozat legutóbbi évadát", - "NoEpisodes": "There unfortunately is no episode data for this show yet!", + "NoEpisodes": "Sajnos még nincs epizód adat ehhez a sorozathoz!", "SeasonNumber": "{{number}}. évad" }, "SonarrConfiguration": "Sonarr konfiguráció", "RadarrConfiguration": "Radarr konfiguráció", "RequestOnBehalf": "Kérés más nevében", "PleaseSelectUser": "Válassz egy felhasználót", - "StreamingOn": "Streaming On:", + "StreamingOn": "Streaming csatorna:", "RequestedBy": "Kérte:", + "RequestedByOn": "Kérte: {{user}} ekkor: {{date}}", "RequestDate": "Kérés ideje:", "DeniedReason": "Elutasítás oka:", - "ReProcessRequest": "Re-Process Request", + "ReProcessRequest": "Kérés újrafeldolgozása", + "ReProcessRequest4K": "Re-Process 4K Request", "Music": { - "Type": "Type:", - "Country": "Country:", - "StartDate": "Start Date:", - "EndDate": "EndDate:" - } + "Type": "Típus:", + "Country": "Ország:", + "StartDate": "Kezdés dátuma:", + "EndDate": "Befejezés dátuma:" + }, + "RequestSource": "Source:" }, "Discovery": { "PopularTab": "Népszerű", "TrendingTab": "Felkapott", - "UpcomingTab": "Upcoming", - "SeasonalTab": "Seasonal", - "RecentlyRequestedTab": "Recently Requested", + "UpcomingTab": "Közelgő", + "SeasonalTab": "Évadok", + "RecentlyRequestedTab": "Kérések az utóbbi időben", "Movies": "Filmek", - "Combined": "Combined", + "Combined": "Kombinált", "Tv": "TV", "CardDetails": { "Availability": "Elérhetőség", "Studio": "Stúdió", - "Network": "Network", + "Network": "Hálózat", "UnknownNetwork": "Ismeretlen", "RequestStatus": "Kérés állapota", "Director": "Rendezte", "InCinemas": "A mozikban", - "FirstAired": "First Aired", + "FirstAired": "Első sugárzás ideje", "Writer": "Írta", "ExecProducer": "Gyártásvezető" }, @@ -381,28 +418,38 @@ "OmbiLanguage": "Nyelv", "DarkMode": "Sötét mód", "Updated": "Sikeresen frissítve", - "StreamingCountry": "Streaming Country", - "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will have US related streaming information.", - "LanguageDescription": "This is the language you would like the Ombi interface to be displayed in.", + "StreamingCountry": "Streaming ország", + "StreamingCountryDescription": "Ez az országkód, amire streaming információt jelenítünk meg. Amennyiben az Egyesült Államokban vagy, válaszd az US kódot az amerikai streaming információhoz.", + "LanguageDescription": "Ez a nyelv, amiben látni szeretnéd az Ombi felületét.", "MobileQRCode": "Mobil QR kód", - "LegacyApp": "Launch Legacy App", - "NoQrCode": "Please contact your administrator to enable QR codes", - "UserType": "User Type:", - "ChangeDetails": "Change Details", - "NeedCurrentPassword": "You need your current password to make any changes here", + "LegacyApp": "Eredeti applikáció indítása", + "NoQrCode": "A QR kód aktiválásához kérjük vegye fel a kapcsolatot az adminisztrátorával", + "UserType": "Felhasználó típusa:", + "ChangeDetails": "Részletek megváltoztatása", + "NeedCurrentPassword": "Az itteni változtatásokhoz a jelenlegi jelszavad szükséges", "CurrentPassword": "Jelenlegi jelszó", "EmailAddress": "E-mail cím", "NewPassword": "Új jelszó", "NewPasswordConfirm": "Új jelszó megerősítése", - "Security": "Security", + "Security": "Biztonság", "Profile": "Profil", - "UpdatedYourInformation": "Updated your information" + "UpdatedYourInformation": "Az információid frissítésre kerültek", + "Unsubscribed": "Leiratkozva!" }, "UserTypeLabel": { "1": "Helyi felhasználó", "2": "Plex felhasználó", "3": "Emby felhasználó", - "4": "Emby Connect User", + "4": "Emby Connect felhasználó", "5": "Jellyfin felhasználó" + }, + "Paginator": { + "itemsPerPageLabel": "Elemek oldalanként:", + "nextPageLabel": "Következő oldal", + "previousPageLabel": "Előző oldal", + "firstPageLabel": "Első oldal", + "lastPageLabel": "Utolsó oldal", + "rangePageLabel1": "0 ennyiből: {{length}}", + "rangePageLabel2": "{{startIndex}} - {{endIndex}} ennyiből: {{length}}" } } diff --git a/src/Ombi/wwwroot/translations/it.json b/src/Ombi/wwwroot/translations/it.json index 74feb48a0..c30f734cd 100644 --- a/src/Ombi/wwwroot/translations/it.json +++ b/src/Ombi/wwwroot/translations/it.json @@ -14,18 +14,26 @@ "Common": { "ContinueButton": "Continua", "Available": "Disponibile", - "Approved": "Approved", - "Pending": "Pending", + "Available4K": "Disponibile in 4K", + "Approved": "Approvato", + "Approve4K": "Approva 4K", + "Pending": "In Sospeso", "PartiallyAvailable": "Parzialmente disponibile", "Monitored": "Monitorato", "NotAvailable": "Non disponibile", "ProcessingRequest": "Richiesta in elaborazione", + "ProcessingRequest4K": "Richiesta 4K in Elaborazione", "PendingApproval": "In attesa di approvazione", + "PendingApproval4K": "4K in attesa di approvazione", "RequestDenied": "Richiesta negata", + "RequestDenied4K": "Richiesta 4K rifiutata", "NotRequested": "Non richiesta", + "NotRequested4K": "4K non richiesto", "Requested": "Richiesta", - "Search": "Search", + "Requested4K": "Richiesto 4K", + "Search": "Cerca", "Request": "Richiesta", + "Request4K": "Richiedi 4K", "Denied": "Negata", "Approve": "Approva", "PartlyAvailable": "Parzialmente disponibile", @@ -35,9 +43,9 @@ }, "Cancel": "Annulla", "Submit": "Invia", - "Update": "Update", - "tvShow": "TV Show", - "movie": "Movie", + "Update": "Aggiorna", + "tvShow": "Serie TV", + "movie": "Film", "album": "Album" }, "PasswordReset": { @@ -55,11 +63,15 @@ "OfflineParagraph": "Il server dei media è attualmente offline.", "CheckPageForUpdates": "Controlla questa pagina per aggiornamenti continui del sito." }, + "ErrorPages": { + "NotFound": "Pagina non trovata", + "SomethingWentWrong": "Qualcosa è andato storto!" + }, "NavigationBar": { "Discover": "Scopri", "Search": "Cerca", "Requests": "Richieste", - "UserManagement": "Gestione degli utenti", + "UserManagement": "Utenti", "Issues": "Problemi", "Vote": "Vota", "Donate": "Dona!", @@ -67,7 +79,7 @@ "DonateTooltip": "Questo è come convinco mia moglie a farmi spendere il mio tempo libero nello sviluppo di Ombi ;)", "UpdateAvailableTooltip": "Aggiornamento disponibile!", "Settings": "Impostazioni", - "Welcome": "Ti diamo il benvenuto {{username}}", + "Welcome": "Benvenuto {{username}}", "UpdateDetails": "Aggiorna dettagli", "Logout": "Esci", "OpenMobileApp": "Apri l'app Mobile", @@ -83,9 +95,9 @@ "Music": "Musica", "People": "Persone" }, - "MorningWelcome": "Buona mattina!", + "MorningWelcome": "Buongiorno!", "AfternoonWelcome": "Buon pomeriggio!", - "EveningWelcome": "Buona sera!" + "EveningWelcome": "Buonasera!" }, "Search": { "Title": "Cerca", @@ -93,15 +105,15 @@ "MoviesTab": "Film", "TvTab": "Serie TV", "MusicTab": "Musica", - "AdvancedSearch": "You can fill in any of the below to discover new media. All of the results are sorted by popularity", - "AdvancedSearchHeader": "Advanced Search", + "AdvancedSearch": "Compila uno dei seguenti campi per cercare nuovi media. I risultati sono in ordine di popolarità", + "AdvancedSearchHeader": "Ricerca Avanzata", "Suggestions": "Suggerimenti", - "NoResults": "Spiacenti, non abbiamo trovato nulla!", + "NoResults": "Nessun risultato trovato!", "DigitalDate": "Uscita in digitale: {{date}}", "TheatricalRelease": "Uscita nei cinema: {{date}}", "ViewOnPlex": "Guarda su Plex", "ViewOnEmby": "Guarda su Emby", - "ViewOnJellyfin": "Play On Jellyfin", + "ViewOnJellyfin": "Riproduci Su Jellyfin", "RequestAdded": "La richiesta per {{title}} è stata aggiunta con successo", "Similar": "Simili", "Refine": "Affina", @@ -129,9 +141,12 @@ "Season": "Stagione {{seasonNumber}}", "SelectAllInSeason": "Seleziona tutto nella stagione {{seasonNumber}}" }, - "AdvancedSearchInstructions": "Please choose what type of media you are searching for:", - "YearOfRelease": "Year of Release", - "KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb" + "AdvancedSearchInstructions": "Scegli che tipo di media cercare:", + "YearOfRelease": "Anno di Rilascio", + "SearchGenre": "Cerca per genere", + "SearchKeyword": "Cerca per parola chiave", + "SearchProvider": "Provider di ricerca", + "KeywordSearchingDisclaimer": "Attenzione: La ricerca per parola chiave è incostante a causa di dati non coerenti su TheMovieDb" }, "Requests": { "Title": "Richieste", @@ -155,11 +170,15 @@ "ChangeRootFolder": "Cartella radice", "ChangeQualityProfile": "Profilo qualità", "MarkUnavailable": "Rendi non disponibile", + "MarkUnavailable4K": "Rendi 4K non disponibile", "MarkAvailable": "Rendi disponibile", + "MarkAvailable4K": "Rendi 4K disponibile", "Remove": "Rimuovi", "Deny": "Nega", + "Deny4K": "Nega 4K", + "Has4KRequest": "Ha una Richiesta 4K", "DenyReason": "Nega Motivo", - "DeniedReason": "Denied Reason", + "DeniedReason": "Motivo di Negazione", "Season": "Stagione", "GridTitle": "Titolo", "AirDate": "Data di trasmissione", @@ -193,48 +212,59 @@ "RequestPanel": { "Delete": "Elimina Richiesta", "Approve": "Approva Richiesta", + "Deny": "Rifiuta Richiesta", + "Approve4K": "Approva Richiesta 4K", + "Deny4K": "Rifiuta Richiesta 4K", "ChangeAvailability": "Segna come Disponibile", - "Deleted": "Successfully deleted selected items", - "Approved": "Successfully approved selected items" + "Deleted": "Elementi selezionati eliminati correttamente", + "Approved": "Elementi selezionati approvati correttamente", + "Denied": "Elementi selezionati rifiutati con successo" }, - "SuccessfullyApproved": "Successfully Approved", - "NowAvailable": "Request is now available", - "NowUnavailable": "Request is now unavailable", - "SuccessfullyReprocessed": "Successfully Re-processed the request", - "DeniedRequest": "Denied Request", - "RequestCollection": "Request Collection", - "CollectionSuccesfullyAdded": "The collection {{name}} has been successfully added!", - "NeedToSelectEpisodes": "You need to select some episodes!", - "RequestAddedSuccessfully": "Request for {{title}} has been added successfully", + "SuccessfullyApproved": "Approvata", + "SuccessfullyDeleted": "Richiesta eliminata correttamente", + "NowAvailable": "Richiesta ora disponibile", + "NowUnavailable": "Richiesta ora non disponibile", + "SuccessfullyReprocessed": "Richiesta rielaborata correttamente", + "DeniedRequest": "Richiesta Rifiutata", + "RequestCollection": "Richiedi Raccolta", + "CollectionSuccesfullyAdded": "La raccolta {{name}} è stata aggiunta correttamente!", + "NeedToSelectEpisodes": "Devi selezionare degli episodi!", + "RequestAddedSuccessfully": "La richiesta per {{title}} è stata aggiunta correttamente", "ErrorCodes": { - "AlreadyRequested": "This has already been requested", - "EpisodesAlreadyRequested": "We already have episodes requested from this series", - "NoPermissionsOnBehalf": "You do not have the correct permissions to request on behalf of users!", - "NoPermissions": "You do not have the correct permissions!", - "RequestDoesNotExist": "Request does not exist", - "ChildRequestDoesNotExist": "Child Request does not exist", - "NoPermissionsRequestMovie": "You do not have permissions to Request a Movie", - "NoPermissionsRequestTV": "You do not have permissions to Request a TV Show", - "NoPermissionsRequestAlbum": "You do not have permissions to Request an Album", - "MovieRequestQuotaExceeded": "You have exceeded your Movie request quota!", - "TvRequestQuotaExceeded": "You have exceeded your Episode request quota!", - "AlbumRequestQuotaExceeded": "You have exceeded your Album request quota!" - } + "AlreadyRequested": "Questo è già stato richiesto", + "EpisodesAlreadyRequested": "Abbiamo già degli episodi richiesti da questa serie", + "NoPermissionsOnBehalf": "Non hai le autorizzazioni corrette per richiedere per conto degli utenti!", + "NoPermissions": "Non hai le autorizzazioni corrette!", + "RequestDoesNotExist": "La richiesta non esiste", + "ChildRequestDoesNotExist": "La Richiesta per Bambini non esiste", + "NoPermissionsRequestMovie": "Non hai le autorizzazioni per Richiedere un Film", + "NoPermissionsRequestTV": "Non hai le autorizzazioni per Richiedere una Serie TV", + "NoPermissionsRequestAlbum": "Non hai le autorizzazioni per Richiedere un Album", + "MovieRequestQuotaExceeded": "Hai superato la tua quota di richieste di Film!", + "TvRequestQuotaExceeded": "Hai superato la tua quota di richieste di Episodi!", + "AlbumRequestQuotaExceeded": "Hai superato la tua quota di richieste di Album!" + }, + "Notify": "Notifica", + "RemoveNotification": "Rimuovi Notifiche", + "SuccessfulNotify": "Sarai notificato per il titolo {{title}}", + "SuccessfulUnNotify": "Non sarai più notificato per il titolo {{title}}", + "CouldntNotify": "Impossibile notificare il titolo {{title}}" }, "Issues": { - "Title": "Problemi", - "PendingTitle": "Problemi In Attesa", - "InProgressTitle": "Problemi In Corso", - "ResolvedTitle": "Problemi Risolti", + "Title": "Segnalazioni", + "IssuesForTitle": "Segnalazioni per {{title}}", + "PendingTitle": "Segnalazioni In Attesa", + "InProgressTitle": "Segnalazioni In Risoluzione", + "ResolvedTitle": "Segnalazioni Risolte", "ColumnTitle": "Titolo", - "Count": "Count", + "Count": "Totale", "Category": "Categoria", "Status": "Stato", "Details": "Dettagli", "Description": "Descrizione", "NoComments": "Nessun Commento!", - "MarkInProgress": "Senza In Corso", - "MarkResolved": "Segna Risolto", + "MarkInProgress": "Approva", + "MarkResolved": "Risolvi", "SendMessageButton": "Invia", "Subject": "Oggetto", "Comments": "Commenti", @@ -255,8 +285,9 @@ "Delete": "Elimina problema", "DeletedIssue": "Il problema è stato eliminato", "Chat": "Chat", - "Requested": "Requested", - "UserOnDate": "{{user}} on {{date}}" + "EnterYourMessage": "Scrivi qualcosa...", + "Requested": "Richiesto", + "UserOnDate": "{{user}} il {{date}}" }, "Filter": { "ClearFilter": "Rimuovi filtro", @@ -264,8 +295,8 @@ "FilterHeaderRequestStatus": "Stato", "Approved": "Approvato", "PendingApproval": "In attesa di approvazione", - "WatchProviders": "Watch Providers", - "Keywords": "Keywords" + "WatchProviders": "Guarda i Fornitori", + "Keywords": "Parole Chiave" }, "UserManagment": { "TvRemaining": "TV: {{remaining}}/{{total}} rimanenti", @@ -281,84 +312,90 @@ }, "MediaDetails": { "Denied": "Rifiutato", - "RecommendationsTitle": "Raccomandazioni", + "Denied4K": "4K Negato", + "Trailers": "Trailer", + "RecommendationsTitle": "Raccomandati", "SimilarTitle": "Simili", "VideosTitle": "Video", "AlbumsTitle": "Album", - "RequestAllAlbums": "Richiedi Tutti gli Album", + "RequestAllAlbums": "Richiedi tutti gli Album", "ClearSelection": "Cancella Selezione", - "RequestSelectedAlbums": "Richiesta degli Album Selezionati", + "RequestSelectedAlbums": "Richiedi gli Album Selezionati", "ViewCollection": "Visualizza Raccolta", - "NotEnoughInfo": "Sfortunatamente ancora non ci sono abbastanza informazioni su questo show!", + "NotEnoughInfo": "Purtroppo ancora non ci sono abbastanza informazioni su questa serie!", "AdvancedOptions": "Opzioni Avanzate", - "AutoApproveOptions": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTv": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be send to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "QualityProfilesSelect": "Seleziona Un Profilo di Qualità", - "RootFolderSelect": "Seleziona Una Cartella di Root", - "LanguageProfileSelect": "Select A Language Profile", - "Status": "Status:", + "AutoApproveOptions": "Puoi configurare qui la tua richiesta, che verrà inviata alla tua applicazione DVR e automaticamente approvata! La configurazione è facoltativa, basta premere Richiedi per saltarla!", + "AutoApproveOptionsTv": "Puoi configurare qui la tua richiesta, che verrà inviata alla tua applicazione DVR e automaticamente approvata! Se la richiesta è già presente in Sonarr, la cartella radice o il profilo qualità non verrà cambiato! La configurazione è facoltativa, basta premere Richiedi per saltarla!", + "AutoApproveOptionsTvShort": "Puoi configurare qui la tua richiesta, che verrà inviata alla tua applicazione DVR! Se la richiesta è già presente in Sonarr, la cartella radice o il profilo qualità non verrà cambiato! La configurazione è facoltativa, basta premere Richiedi per saltarla!", + "QualityProfilesSelect": "Seleziona un Profilo per la Qualità", + "RootFolderSelect": "Seleziona una Cartella Principale", + "LanguageProfileSelect": "Seleziona un profilo per la Lingua", + "Status": "Stato:", "StatusValues": { - "Rumored": "Rumored", - "Planned": "Planned", - "In Production": "In Production", - "Post Production": "Post Production", - "Released": "Released", - "Running": "Running", - "Returning Series": "Returning Series", - "Ended": "Ended", - "Canceled": "Canceled" + "Rumored": "Rumor", + "Planned": "Pianificato", + "In Production": "In Produzione", + "Post Production": "Post Produzione", + "Released": "Rilasciato", + "Running": "In Corso", + "Returning Series": "Serie Rinnovate", + "Ended": "Conclusa", + "Canceled": "Cancellata" }, - "Seasons": "Seasons:", - "Episodes": "Episodes:", - "Availability": "Availability:", - "RequestStatus": "Stato Richiesta", - "Quality": "Quality:", - "RootFolderOverride": "Root Folder Override:", - "QualityOverride": "Quality Override:", - "Network": "Network:", - "Genres": "Genres:", - "FirstAired": "First Aired:", - "TheatricalRelease": "Release:", - "DigitalRelease": "Digital Release:", - "Votes": "Votes:", - "Runtime": "Runtime:", + "Seasons": "Stagioni:", + "Episodes": "Episodi:", + "Availability": "Disponibilità:", + "RequestStatus": "Stato richiesta:", + "Quality": "Qualità:", + "RootFolderOverride": "Sovrascrivi Cartella Principale:", + "QualityOverride": "Sovrascrivi Qualità:", + "Network": "Rete:", + "GenresLabel": "Generi:", + "Genres": "Generi", + "FirstAired": "Prima Trasmissione:", + "TheatricalRelease": "Uscita:", + "DigitalRelease": "Uscita Digitale:", + "Votes": "Voti:", + "Runtime": "Durata:", "Minutes": "{{runtime}} Minuti", - "Revenue": "Revenue:", + "Revenue": "Entrate:", "Budget": "Budget:", - "Keywords": "Keywords/Tags:", + "Keywords": "Parole Chiave/Tag:", "Casts": { "CastTitle": "Trasmetti" }, "EpisodeSelector": { - "AllSeasonsTooltip": "Questo richiederà ogni stagione per questo show", - "FirstSeasonTooltip": "Questo richiederà solo la Prima Stagione per questo show", - "LatestSeasonTooltip": "Questo richiederà solo l'Ultima Stagione per questo show", - "NoEpisodes": "There unfortunately is no episode data for this show yet!", - "SeasonNumber": "Season {{number}}" + "AllSeasonsTooltip": "Richiederà tutte le stagioni per questa serie", + "FirstSeasonTooltip": "Richiederà solo la Prima Stagione per questa serie", + "LatestSeasonTooltip": "Richiederà solo l'Ultima Stagione per questa serie", + "NoEpisodes": "Sfortunatamente, non c'è ancora alcun dato dell'episodio per questa serie!", + "SeasonNumber": "Stagione {{number}}" }, - "SonarrConfiguration": "Sonarr Configuration", - "RadarrConfiguration": "Radarr Configuration", - "RequestOnBehalf": "Request on behalf of", - "PleaseSelectUser": "Please select a user", - "StreamingOn": "Streaming On:", - "RequestedBy": "Requested By:", - "RequestDate": "Request Date:", - "DeniedReason": "Denied Reason:", - "ReProcessRequest": "Re-Process Request", + "SonarrConfiguration": "Configurazione di Sonarr", + "RadarrConfiguration": "Configurazione di Radarr", + "RequestOnBehalf": "Richiesta per conto di", + "PleaseSelectUser": "Sei pregato di selezionare un utente", + "StreamingOn": "In Streaming Su:", + "RequestedBy": "Richiesto Da:", + "RequestedByOn": "Richiesto da {{user}} il {{date}}", + "RequestDate": "Data di Richiesta:", + "DeniedReason": "Motivo di Negazione:", + "ReProcessRequest": "Ri-Elabora Richiesta", + "ReProcessRequest4K": "Ri-Elabora Richiesta 4K", "Music": { - "Type": "Type:", - "Country": "Country:", - "StartDate": "Start Date:", - "EndDate": "EndDate:" - } + "Type": "Tipo:", + "Country": "Paese:", + "StartDate": "Data Iniziale:", + "EndDate": "Data Finale:" + }, + "RequestSource": "Sorgente:" }, "Discovery": { "PopularTab": "Popolare", "TrendingTab": "Tendenze", "UpcomingTab": "In arrivo", - "SeasonalTab": "Seasonal", - "RecentlyRequestedTab": "Recently Requested", + "SeasonalTab": "Stagionale", + "RecentlyRequestedTab": "Richiesto Recentemente", "Movies": "Film", "Combined": "Combinato", "Tv": "TV", @@ -374,35 +411,45 @@ "Writer": "Scrittore", "ExecProducer": "Produttore Esecutivo" }, - "NoSearch": "Sorry, nothing matches your search!" + "NoSearch": "Spiacenti, nessun risultato corrisponde alla tua ricerca!" }, "UserPreferences": { "Welcome": "Benvenuto {{username}}!", "OmbiLanguage": "Lingua", "DarkMode": "Modalità Scura", - "Updated": "Successfully Updated", - "StreamingCountry": "Streaming Country", - "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will have US related streaming information.", - "LanguageDescription": "This is the language you would like the Ombi interface to be displayed in.", - "MobileQRCode": "Mobile QR Code", - "LegacyApp": "Launch Legacy App", - "NoQrCode": "Please contact your administrator to enable QR codes", - "UserType": "User Type:", - "ChangeDetails": "Change Details", - "NeedCurrentPassword": "You need your current password to make any changes here", - "CurrentPassword": "Current Password", - "EmailAddress": "Email Address", - "NewPassword": "New Password", - "NewPasswordConfirm": "New Password Confirm", - "Security": "Security", - "Profile": "Profile", - "UpdatedYourInformation": "Updated your information" + "Updated": "Aggiornate Correttamente", + "StreamingCountry": "Paese di Streaming", + "StreamingCountryDescription": "Questo è il codice del paese per cui mostreremo le informazioni dei media. Se sei in Italia, seleziona IT e ti mostreremo le informazioni dei media in Italiano.", + "LanguageDescription": "Questa è la lingua in cui vorresti fosse visualizzata l'interfaccia di Ombi.", + "MobileQRCode": "Codice QR Mobile", + "LegacyApp": "Avvia l'App Legacy", + "NoQrCode": "Contatta l'amministratore per abilitare i codici QR", + "UserType": "Tipo di Utente:", + "ChangeDetails": "Modifica i Dettagli", + "NeedCurrentPassword": "Hai bisogno della tua password attuale per apportare qualsiasi modifica qui", + "CurrentPassword": "Password Corrente", + "EmailAddress": "Indirizzo Email", + "NewPassword": "Nuova Password", + "NewPasswordConfirm": "Conferma Nuova Password", + "Security": "Sicurezza", + "Profile": "Profilo", + "UpdatedYourInformation": "Le tue informazioni sono state aggiornate", + "Unsubscribed": "Disiscritto!" }, "UserTypeLabel": { - "1": "Local User", - "2": "Plex User", - "3": "Emby User", - "4": "Emby Connect User", - "5": "Jellyfin User" + "1": "Utente Locale", + "2": "Utente Plex", + "3": "Utente Emby", + "4": "Connetti Utente di Emby", + "5": "Utente di Jellyfin" + }, + "Paginator": { + "itemsPerPageLabel": "Righe per pagina:", + "nextPageLabel": "Pagina successiva", + "previousPageLabel": "Pagina precedente", + "firstPageLabel": "Prima pagina", + "lastPageLabel": "Ultima pagina", + "rangePageLabel1": "0 su {{length}}", + "rangePageLabel2": "{{startIndex}} – {{endIndex}} su {{length}}" } } diff --git a/src/Ombi/wwwroot/translations/nl.json b/src/Ombi/wwwroot/translations/nl.json index da6ce4cc5..b0985224e 100644 --- a/src/Ombi/wwwroot/translations/nl.json +++ b/src/Ombi/wwwroot/translations/nl.json @@ -4,8 +4,8 @@ "UsernamePlaceholder": "Gebruikersnaam", "PasswordPlaceholder": "Wachtwoord", "RememberMe": "Onthoud Mij", - "SignInWith": "Sign in with {{appName}}", - "SignInWithPlex": "Sign in with Plex", + "SignInWith": "Inloggen met {{appName}}", + "SignInWithPlex": "Inloggen met Plex", "ForgottenPassword": "Wachtwoord vergeten?", "Errors": { "IncorrectCredentials": "Onjuiste gebruikersnaam of wachtwoord" @@ -14,18 +14,26 @@ "Common": { "ContinueButton": "Doorgaan", "Available": "Beschikbaar", - "Approved": "Approved", - "Pending": "Pending", + "Available4K": "Available 4K", + "Approved": "Goedgekeurd", + "Approve4K": "Approve 4K", + "Pending": "In afwachting", "PartiallyAvailable": "Deels Beschikbaar", "Monitored": "Gemonitord", "NotAvailable": "Niet Beschikbaar", "ProcessingRequest": "Verzoek wordt verwerkt", + "ProcessingRequest4K": "Processing Request 4K", "PendingApproval": "Wacht op goedkeuring", + "PendingApproval4K": "Pending Approval 4K", "RequestDenied": "Verzoek geweigerd", + "RequestDenied4K": "Request Denied 4K", "NotRequested": "Niet verzocht", + "NotRequested4K": "Not Requested 4K", "Requested": "Aangevraagd", - "Search": "Search", + "Requested4K": "Requested 4K", + "Search": "Zoeken", "Request": "Aanvragen", + "Request4K": "Request 4K", "Denied": "Afgewezen", "Approve": "Accepteer", "PartlyAvailable": "Deels Beschikbaar", @@ -33,11 +41,11 @@ "Errors": { "Validation": "Controleer de ingevulde waardes" }, - "Cancel": "Cancel", - "Submit": "Submit", + "Cancel": "Annuleren", + "Submit": "Verzenden", "Update": "Update", - "tvShow": "TV Show", - "movie": "Movie", + "tvShow": "Tv programma", + "movie": "Film", "album": "Album" }, "PasswordReset": { @@ -55,6 +63,10 @@ "OfflineParagraph": "De mediaserver is momenteel offline.", "CheckPageForUpdates": "Controleer deze pagina voor updates." }, + "ErrorPages": { + "NotFound": "Page not found", + "SomethingWentWrong": "Something went wrong!" + }, "NavigationBar": { "Discover": "Ontdekken", "Search": "Zoeken", @@ -76,16 +88,16 @@ "Calendar": "Agenda", "UserPreferences": "Instellingen", "FeatureSuggestion": "Feature Suggestion", - "FeatureSuggestionTooltip": "Have a great new idea? Suggest it here!", + "FeatureSuggestionTooltip": "Heb je een geweldig nieuw idee? Stel het hier voor!", "Filter": { "Movies": "Films", "TvShows": "TV Series", "Music": "Muziek", - "People": "People" + "People": "Personen" }, - "MorningWelcome": "Good morning!", - "AfternoonWelcome": "Good afternoon!", - "EveningWelcome": "Good evening!" + "MorningWelcome": "Goedemorgen!", + "AfternoonWelcome": "Goedemiddag!", + "EveningWelcome": "Goedenavond!" }, "Search": { "Title": "Zoeken", @@ -101,7 +113,7 @@ "TheatricalRelease": "Bioscoop Uitgave: {{date}}", "ViewOnPlex": "Bekijk op Plex", "ViewOnEmby": "Bekijk op Emby", - "ViewOnJellyfin": "Play On Jellyfin", + "ViewOnJellyfin": "Afspelen op Jellyfin", "RequestAdded": "Aanvraag voor {{title}} is succesvol toegevoegd", "Similar": "Vergelijkbaar", "Refine": "Verfijn", @@ -131,14 +143,17 @@ }, "AdvancedSearchInstructions": "Please choose what type of media you are searching for:", "YearOfRelease": "Year of Release", + "SearchGenre": "Search Genre", + "SearchKeyword": "Search Keyword", + "SearchProvider": "Search Provider", "KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb" }, "Requests": { "Title": "Verzoeken", "Paragraph": "Hieronder zie je jouw en alle andere verzoeken, evenals hun download en goedkeuring status.", "MoviesTab": "Films", - "ArtistName": "Artist", - "AlbumName": "Album Name", + "ArtistName": "Artiest", + "AlbumName": "Albumnaam", "TvTab": "TV Series", "MusicTab": "Muziek", "RequestedBy": "Verzocht Door", @@ -155,9 +170,13 @@ "ChangeRootFolder": "Hoofdmap wijzigen", "ChangeQualityProfile": "Kwaliteitsprofiel wijzigen", "MarkUnavailable": "Markeren als onbeschikbaar", + "MarkUnavailable4K": "Mark Unavailable 4K", "MarkAvailable": "Markeren als beschikbaar", + "MarkAvailable4K": "Mark Available 4K", "Remove": "Verwijderen", "Deny": "Weigeren", + "Deny4K": "Deny 4K", + "Has4KRequest": "Has 4K Request", "DenyReason": "Reden van afwijzing", "DeniedReason": "Denied Reason", "Season": "Seizoen", @@ -181,23 +200,28 @@ "NextMinutes": "Een ander verzoek zal worden toegevoegd in {{time}} Minuten", "NextMinute": "Een ander verzoek zal worden toegevoegd in {{time}} Minuut" }, - "AllRequests": "All Requests", - "PendingRequests": "Pending Requests", - "ProcessingRequests": "Processing Requests", - "AvailableRequests": "Available Requests", - "DeniedRequests": "Denied Requests", - "RequestsToDisplay": "Requests to display", + "AllRequests": "Alle verzoeken", + "PendingRequests": "Lopende verzoeken", + "ProcessingRequests": "Verzoeken in behandeling", + "AvailableRequests": "Beschikbare verzoeken", + "DeniedRequests": "Geweigerde verzoeken", + "RequestsToDisplay": "Verzoeken om weer te geven", "RequestsTitle": "Titel", "Details": "Details", - "Options": "Options", + "Options": "Opties", "RequestPanel": { - "Delete": "Delete Request", - "Approve": "Approve Request", - "ChangeAvailability": "Mark Available", + "Delete": "Verwijder Verzoek", + "Approve": "Verzoek Goedkeuren", + "Deny": "Deny Request", + "Approve4K": "Approve 4K Request", + "Deny4K": "Deny 4K Request", + "ChangeAvailability": "Markeer beschikbaar", "Deleted": "Successfully deleted selected items", - "Approved": "Successfully approved selected items" + "Approved": "Successfully approved selected items", + "Denied": "Successfully denied selected items" }, "SuccessfullyApproved": "Successfully Approved", + "SuccessfullyDeleted": "Request successfully deleted", "NowAvailable": "Request is now available", "NowUnavailable": "Request is now unavailable", "SuccessfullyReprocessed": "Successfully Re-processed the request", @@ -205,7 +229,7 @@ "RequestCollection": "Request Collection", "CollectionSuccesfullyAdded": "The collection {{name}} has been successfully added!", "NeedToSelectEpisodes": "You need to select some episodes!", - "RequestAddedSuccessfully": "Request for {{title}} has been added successfully", + "RequestAddedSuccessfully": "Aanvraag voor {{title}} is succesvol toegevoegd", "ErrorCodes": { "AlreadyRequested": "This has already been requested", "EpisodesAlreadyRequested": "We already have episodes requested from this series", @@ -219,10 +243,16 @@ "MovieRequestQuotaExceeded": "You have exceeded your Movie request quota!", "TvRequestQuotaExceeded": "You have exceeded your Episode request quota!", "AlbumRequestQuotaExceeded": "You have exceeded your Album request quota!" - } + }, + "Notify": "Notify", + "RemoveNotification": "Remove Notifications", + "SuccessfulNotify": "You will now be notified for title {{title}}", + "SuccessfulUnNotify": "You will no longer be notified for title {{title}}", + "CouldntNotify": "Couldn't notify title {{title}}" }, "Issues": { "Title": "Problemen", + "IssuesForTitle": "Issues for {{title}}", "PendingTitle": "Onopgeloste Problemen", "InProgressTitle": "Problemen in Behandeling", "ResolvedTitle": "Opgeloste Problemen", @@ -241,21 +271,22 @@ "WriteMessagePlaceholder": "Schrijf hier je bericht...", "ReportedBy": "Gerapporteerd door", "IssueDialog": { - "Title": "Report an issue", - "DescriptionPlaceholder": "Please describe the issue", - "TitlePlaceholder": "Short title of your issue", - "SelectCategory": "Select Category", - "IssueCreated": "Issue has been created" + "Title": "Meld een probleem", + "DescriptionPlaceholder": "Beschrijf het probleem", + "TitlePlaceholder": "Korte titel van het probleem", + "SelectCategory": "Selecteer categorie", + "IssueCreated": "Probleem is ingediend" }, - "Outstanding": "There are outstanding issues", - "ResolvedDate": "Resolved date", - "CreatedDate": "Raised on", - "MarkedAsResolved": "This issue has now been marked as resolved!", - "MarkedAsInProgress": "This issue has now been marked as in progress!", - "Delete": "Delete issue", - "DeletedIssue": "Issue has been deleted", + "Outstanding": "Er zijn nog openstaande problemen", + "ResolvedDate": "Oplosdatum", + "CreatedDate": "Ingediend op", + "MarkedAsResolved": "Dit probleem is nu gemarkeerd als opgelost!", + "MarkedAsInProgress": "Dit probleem is nu gemarkeerd als in behandeling!", + "Delete": "Verwijder probleem", + "DeletedIssue": "Probleem is verwijderd", "Chat": "Chat", - "Requested": "Requested", + "EnterYourMessage": "Enter Your Message", + "Requested": "Aangevraagd", "UserOnDate": "{{user}} on {{date}}" }, "Filter": { @@ -281,21 +312,23 @@ }, "MediaDetails": { "Denied": "Afgewezen", + "Denied4K": "Denied 4K", + "Trailers": "Trailers", "RecommendationsTitle": "Aanbevelingen", "SimilarTitle": "Vergelijkbaar", "VideosTitle": "Video's", "AlbumsTitle": "Albums", - "RequestAllAlbums": "Request All Albums", - "ClearSelection": "Clear Selection", - "RequestSelectedAlbums": "Request Selected Albums", - "ViewCollection": "View Collection", - "NotEnoughInfo": "Unfortunately there is not enough information about this show yet!", - "AdvancedOptions": "Advanced Options", - "AutoApproveOptions": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTv": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be send to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "QualityProfilesSelect": "Select A Quality Profile", - "RootFolderSelect": "Select A Root Folder", + "RequestAllAlbums": "Verzoek alle albums", + "ClearSelection": "Wis selectie", + "RequestSelectedAlbums": "Verzoek geselecteerde albums", + "ViewCollection": "Bekijk collectie", + "NotEnoughInfo": "Helaas is er nog niet genoeg informatie over deze tv-serie!", + "AdvancedOptions": "Geavanceerde opties", + "AutoApproveOptions": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTv": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be sent to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "QualityProfilesSelect": "Selecteer een kwaliteitsprofiel", + "RootFolderSelect": "Selecteer een hoofdmap", "LanguageProfileSelect": "Select A Language Profile", "Status": "Status:", "StatusValues": { @@ -310,23 +343,24 @@ "Canceled": "Canceled" }, "Seasons": "Seasons:", - "Episodes": "Episodes:", - "Availability": "Availability:", - "RequestStatus": "Aanvraagstatus", - "Quality": "Quality:", - "RootFolderOverride": "Root Folder Override:", - "QualityOverride": "Quality Override:", - "Network": "Network:", - "Genres": "Genres:", - "FirstAired": "First Aired:", + "Episodes": "Afleveringen:", + "Availability": "Beschikbaarheid:", + "RequestStatus": "Request Status:", + "Quality": "Kwaliteit:", + "RootFolderOverride": "Hoofdmap overschrijven:", + "QualityOverride": "Kwaliteit overschrijven:", + "Network": "Netwerk:", + "GenresLabel": "Genres:", + "Genres": "Genres", + "FirstAired": "Eerste uitzending:", "TheatricalRelease": "Release:", - "DigitalRelease": "Digital Release:", - "Votes": "Votes:", - "Runtime": "Runtime:", - "Minutes": "{{runtime}} Minutes", - "Revenue": "Revenue:", + "DigitalRelease": "Digitale release:", + "Votes": "Stemmen:", + "Runtime": "Looptijd:", + "Minutes": "{{runtime}} minuten", + "Revenue": "Omzet:", "Budget": "Budget:", - "Keywords": "Keywords/Tags:", + "Keywords": "Trefwoorden/Labels:", "Casts": { "CastTitle": "Acteurs" }, @@ -335,23 +369,26 @@ "FirstSeasonTooltip": "Dit verzoekt alleen het eerste seizoen van deze serie", "LatestSeasonTooltip": "Dit verzoekt alleen het laatste seizoen van deze show", "NoEpisodes": "There unfortunately is no episode data for this show yet!", - "SeasonNumber": "Season {{number}}" + "SeasonNumber": "Seizoen {{number}}" }, - "SonarrConfiguration": "Sonarr Configuration", - "RadarrConfiguration": "Radarr Configuration", - "RequestOnBehalf": "Request on behalf of", - "PleaseSelectUser": "Please select a user", - "StreamingOn": "Streaming On:", - "RequestedBy": "Requested By:", - "RequestDate": "Request Date:", + "SonarrConfiguration": "Sonarr configuratie", + "RadarrConfiguration": "Radarr configuratie", + "RequestOnBehalf": "Verzoek namens", + "PleaseSelectUser": "Selecteer een gebruiker", + "StreamingOn": "Streamt op:", + "RequestedBy": "Verzocht Door:", + "RequestedByOn": "Requested By {{user}} on {{date}}", + "RequestDate": "Aanvraag Datum:", "DeniedReason": "Denied Reason:", "ReProcessRequest": "Re-Process Request", + "ReProcessRequest4K": "Re-Process 4K Request", "Music": { "Type": "Type:", "Country": "Country:", "StartDate": "Start Date:", "EndDate": "EndDate:" - } + }, + "RequestSource": "Source:" }, "Discovery": { "PopularTab": "Populair", @@ -360,7 +397,7 @@ "SeasonalTab": "Seasonal", "RecentlyRequestedTab": "Recently Requested", "Movies": "Films", - "Combined": "Combined", + "Combined": "Gecombineerd", "Tv": "TV", "CardDetails": { "Availability": "Beschikbaarheid", @@ -374,29 +411,30 @@ "Writer": "Schrijver", "ExecProducer": "Uitvoerende producent" }, - "NoSearch": "Sorry, nothing matches your search!" + "NoSearch": "Sorry, niks komt overeen met jou zoekopdracht!" }, "UserPreferences": { "Welcome": "Welkom {{username}}!", - "OmbiLanguage": "Language", - "DarkMode": "Dark Mode", - "Updated": "Successfully Updated", - "StreamingCountry": "Streaming Country", - "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will have US related streaming information.", - "LanguageDescription": "This is the language you would like the Ombi interface to be displayed in.", - "MobileQRCode": "Mobile QR Code", - "LegacyApp": "Launch Legacy App", + "OmbiLanguage": "Taal", + "DarkMode": "Donkere Modus", + "Updated": "Succesvol bijgewerkt", + "StreamingCountry": "Streaming Land", + "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will get US related streaming information.", + "LanguageDescription": "Dit is de taal waarin Ombi in wordt weergegeven.", + "MobileQRCode": "QR code voor mobiel", + "LegacyApp": "Start legacy app", "NoQrCode": "Please contact your administrator to enable QR codes", "UserType": "User Type:", "ChangeDetails": "Change Details", "NeedCurrentPassword": "You need your current password to make any changes here", "CurrentPassword": "Current Password", - "EmailAddress": "Email Address", + "EmailAddress": "E-mail adres", "NewPassword": "New Password", "NewPasswordConfirm": "New Password Confirm", "Security": "Security", "Profile": "Profile", - "UpdatedYourInformation": "Updated your information" + "UpdatedYourInformation": "Updated your information", + "Unsubscribed": "Unsubscribed!" }, "UserTypeLabel": { "1": "Local User", @@ -404,5 +442,14 @@ "3": "Emby User", "4": "Emby Connect User", "5": "Jellyfin User" + }, + "Paginator": { + "itemsPerPageLabel": "Items per page:", + "nextPageLabel": "Next page", + "previousPageLabel": "Previous page", + "firstPageLabel": "First page", + "lastPageLabel": "Last page", + "rangePageLabel1": "0 of {{length}}", + "rangePageLabel2": "{{startIndex}} – {{endIndex}} of {{length}}" } } diff --git a/src/Ombi/wwwroot/translations/no.json b/src/Ombi/wwwroot/translations/no.json index c889a4f8f..d341036ef 100644 --- a/src/Ombi/wwwroot/translations/no.json +++ b/src/Ombi/wwwroot/translations/no.json @@ -4,8 +4,8 @@ "UsernamePlaceholder": "Brukernavn", "PasswordPlaceholder": "Passord", "RememberMe": "Husk meg", - "SignInWith": "Sign in with {{appName}}", - "SignInWithPlex": "Sign in with Plex", + "SignInWith": "Logg inn med {{appName}}", + "SignInWithPlex": "Logg inn med Plex", "ForgottenPassword": "Glemt passord?", "Errors": { "IncorrectCredentials": "Ugyldig brukernavn eller passord" @@ -14,26 +14,34 @@ "Common": { "ContinueButton": "Gå videre", "Available": "Tilgjengelig", - "Approved": "Approved", + "Available4K": "Available 4K", + "Approved": "Godkjent", + "Approve4K": "Approve 4K", "Pending": "Pending", "PartiallyAvailable": "Delvis tilgjengelig", "Monitored": "Overvåket", "NotAvailable": "Ikke tilgjengelig", "ProcessingRequest": "Behandler forespørsel", + "ProcessingRequest4K": "Processing Request 4K", "PendingApproval": "Venter på godkjenning", + "PendingApproval4K": "Pending Approval 4K", "RequestDenied": "Forespørsel avslått", + "RequestDenied4K": "Request Denied 4K", "NotRequested": "Ikke forespurt", + "NotRequested4K": "Not Requested 4K", "Requested": "Forespurt", - "Search": "Search", + "Requested4K": "Requested 4K", + "Search": "Søk", "Request": "Forespørsel", + "Request4K": "Request 4K", "Denied": "Avslått", "Approve": "Godkjenn", "PartlyAvailable": "Delvis tilgjengelig", - "ViewDetails": "View Details", + "ViewDetails": "Vis detaljer", "Errors": { "Validation": "Kontroller de angitte verdiene" }, - "Cancel": "Cancel", + "Cancel": "Avbryt", "Submit": "Submit", "Update": "Update", "tvShow": "TV Show", @@ -55,6 +63,10 @@ "OfflineParagraph": "Medieserveren er for øyeblikket utilgjengelig.", "CheckPageForUpdates": "Sjekk denne siden for kontinuerlige oppdateringer." }, + "ErrorPages": { + "NotFound": "Page not found", + "SomethingWentWrong": "Something went wrong!" + }, "NavigationBar": { "Discover": "Discover", "Search": "Søk", @@ -131,6 +143,9 @@ }, "AdvancedSearchInstructions": "Please choose what type of media you are searching for:", "YearOfRelease": "Year of Release", + "SearchGenre": "Search Genre", + "SearchKeyword": "Search Keyword", + "SearchProvider": "Search Provider", "KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb" }, "Requests": { @@ -155,9 +170,13 @@ "ChangeRootFolder": "Endre rotmappe", "ChangeQualityProfile": "Endre kvalitetsprofil", "MarkUnavailable": "Merk utilgjengelig", + "MarkUnavailable4K": "Mark Unavailable 4K", "MarkAvailable": "Merk tilgjengelig", + "MarkAvailable4K": "Mark Available 4K", "Remove": "Fjern", "Deny": "Avslå", + "Deny4K": "Deny 4K", + "Has4KRequest": "Has 4K Request", "DenyReason": "Deny Reason", "DeniedReason": "Denied Reason", "Season": "Sesong", @@ -193,11 +212,16 @@ "RequestPanel": { "Delete": "Delete Request", "Approve": "Approve Request", - "ChangeAvailability": "Mark Available", + "Deny": "Deny Request", + "Approve4K": "Approve 4K Request", + "Deny4K": "Deny 4K Request", + "ChangeAvailability": "Merk tilgjengelig", "Deleted": "Successfully deleted selected items", - "Approved": "Successfully approved selected items" + "Approved": "Successfully approved selected items", + "Denied": "Successfully denied selected items" }, "SuccessfullyApproved": "Successfully Approved", + "SuccessfullyDeleted": "Request successfully deleted", "NowAvailable": "Request is now available", "NowUnavailable": "Request is now unavailable", "SuccessfullyReprocessed": "Successfully Re-processed the request", @@ -205,7 +229,7 @@ "RequestCollection": "Request Collection", "CollectionSuccesfullyAdded": "The collection {{name}} has been successfully added!", "NeedToSelectEpisodes": "You need to select some episodes!", - "RequestAddedSuccessfully": "Request for {{title}} has been added successfully", + "RequestAddedSuccessfully": "Forespørsel om {{title}} er lagt til", "ErrorCodes": { "AlreadyRequested": "This has already been requested", "EpisodesAlreadyRequested": "We already have episodes requested from this series", @@ -219,10 +243,16 @@ "MovieRequestQuotaExceeded": "You have exceeded your Movie request quota!", "TvRequestQuotaExceeded": "You have exceeded your Episode request quota!", "AlbumRequestQuotaExceeded": "You have exceeded your Album request quota!" - } + }, + "Notify": "Notify", + "RemoveNotification": "Remove Notifications", + "SuccessfulNotify": "You will now be notified for title {{title}}", + "SuccessfulUnNotify": "You will no longer be notified for title {{title}}", + "CouldntNotify": "Couldn't notify title {{title}}" }, "Issues": { "Title": "Mangler", + "IssuesForTitle": "Issues for {{title}}", "PendingTitle": "Ventende løsninger", "InProgressTitle": "Mangler under behandling", "ResolvedTitle": "Løste mangler", @@ -255,7 +285,8 @@ "Delete": "Delete issue", "DeletedIssue": "Issue has been deleted", "Chat": "Chat", - "Requested": "Requested", + "EnterYourMessage": "Enter Your Message", + "Requested": "Forespurt", "UserOnDate": "{{user}} on {{date}}" }, "Filter": { @@ -281,6 +312,8 @@ }, "MediaDetails": { "Denied": "Avslått", + "Denied4K": "Denied 4K", + "Trailers": "Trailers", "RecommendationsTitle": "Recommendations", "SimilarTitle": "Lignende", "VideosTitle": "Videos", @@ -291,9 +324,9 @@ "ViewCollection": "View Collection", "NotEnoughInfo": "Unfortunately there is not enough information about this show yet!", "AdvancedOptions": "Advanced Options", - "AutoApproveOptions": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTv": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be send to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptions": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTv": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be sent to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", "QualityProfilesSelect": "Select A Quality Profile", "RootFolderSelect": "Select A Root Folder", "LanguageProfileSelect": "Select A Language Profile", @@ -311,15 +344,16 @@ }, "Seasons": "Seasons:", "Episodes": "Episodes:", - "Availability": "Availability:", - "RequestStatus": "Request Status", + "Availability": "Tilgjengelighet:", + "RequestStatus": "Request Status:", "Quality": "Quality:", - "RootFolderOverride": "Root Folder Override:", - "QualityOverride": "Quality Override:", + "RootFolderOverride": "Overstyring av rotmappe:", + "QualityOverride": "Overstyr kvalitet:", "Network": "Network:", - "Genres": "Genres:", + "GenresLabel": "Genres:", + "Genres": "Genres", "FirstAired": "First Aired:", - "TheatricalRelease": "Release:", + "TheatricalRelease": "Kinopremiere:", "DigitalRelease": "Digital Release:", "Votes": "Votes:", "Runtime": "Runtime:", @@ -335,23 +369,26 @@ "FirstSeasonTooltip": "This will only request the First Season for this show", "LatestSeasonTooltip": "This will only request the Latest Season for this show", "NoEpisodes": "There unfortunately is no episode data for this show yet!", - "SeasonNumber": "Season {{number}}" + "SeasonNumber": "Sesong {{number}}" }, "SonarrConfiguration": "Sonarr Configuration", "RadarrConfiguration": "Radarr Configuration", "RequestOnBehalf": "Request on behalf of", "PleaseSelectUser": "Please select a user", "StreamingOn": "Streaming On:", - "RequestedBy": "Requested By:", - "RequestDate": "Request Date:", + "RequestedBy": "Etterspurt av:", + "RequestedByOn": "Requested By {{user}} on {{date}}", + "RequestDate": "Dato for forespørsel:", "DeniedReason": "Denied Reason:", "ReProcessRequest": "Re-Process Request", + "ReProcessRequest4K": "Re-Process 4K Request", "Music": { "Type": "Type:", "Country": "Country:", "StartDate": "Start Date:", "EndDate": "EndDate:" - } + }, + "RequestSource": "Source:" }, "Discovery": { "PopularTab": "Populært", @@ -382,7 +419,7 @@ "DarkMode": "Dark Mode", "Updated": "Successfully Updated", "StreamingCountry": "Streaming Country", - "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will have US related streaming information.", + "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will get US related streaming information.", "LanguageDescription": "This is the language you would like the Ombi interface to be displayed in.", "MobileQRCode": "Mobile QR Code", "LegacyApp": "Launch Legacy App", @@ -391,12 +428,13 @@ "ChangeDetails": "Change Details", "NeedCurrentPassword": "You need your current password to make any changes here", "CurrentPassword": "Current Password", - "EmailAddress": "Email Address", + "EmailAddress": "E-postadresse", "NewPassword": "New Password", "NewPasswordConfirm": "New Password Confirm", "Security": "Security", "Profile": "Profile", - "UpdatedYourInformation": "Updated your information" + "UpdatedYourInformation": "Updated your information", + "Unsubscribed": "Unsubscribed!" }, "UserTypeLabel": { "1": "Local User", @@ -404,5 +442,14 @@ "3": "Emby User", "4": "Emby Connect User", "5": "Jellyfin User" + }, + "Paginator": { + "itemsPerPageLabel": "Items per page:", + "nextPageLabel": "Next page", + "previousPageLabel": "Previous page", + "firstPageLabel": "First page", + "lastPageLabel": "Last page", + "rangePageLabel1": "0 of {{length}}", + "rangePageLabel2": "{{startIndex}} – {{endIndex}} of {{length}}" } } diff --git a/src/Ombi/wwwroot/translations/pl.json b/src/Ombi/wwwroot/translations/pl.json index 3affb1ef9..6bf7e2698 100644 --- a/src/Ombi/wwwroot/translations/pl.json +++ b/src/Ombi/wwwroot/translations/pl.json @@ -4,8 +4,8 @@ "UsernamePlaceholder": "Nazwa użytkownika", "PasswordPlaceholder": "Hasło", "RememberMe": "Zapamiętaj mnie", - "SignInWith": "Sign in with {{appName}}", - "SignInWithPlex": "Sign in with Plex", + "SignInWith": "Zaloguj się z {{appName}}", + "SignInWithPlex": "Zaloguj się z Plex", "ForgottenPassword": "Nie pamiętasz hasła?", "Errors": { "IncorrectCredentials": "Nieprawidłowa nazwa użytkownika lub hasło" @@ -14,18 +14,26 @@ "Common": { "ContinueButton": "Kontynuuj", "Available": "Dostępne", - "Approved": "Approved", - "Pending": "Pending", + "Available4K": "Dostępne 4K", + "Approved": "Zatwierdzone", + "Approve4K": "Zatwierdź 4K", + "Pending": "Oczekuje", "PartiallyAvailable": "Częściowo dostępne", "Monitored": "Monitorowane", "NotAvailable": "Niedostępne", "ProcessingRequest": "Przetwarzanie zgłoszenia", + "ProcessingRequest4K": "Processing Request 4K", "PendingApproval": "Oczekujące na zatwierdzenie", + "PendingApproval4K": "Pending Approval 4K", "RequestDenied": "Zgłoszenie odrzucone", + "RequestDenied4K": "Request Denied 4K", "NotRequested": "Niezgłoszone", + "NotRequested4K": "Not Requested 4K", "Requested": "Zgłoszone", - "Search": "Search", + "Requested4K": "Żądane 4K", + "Search": "Szukaj", "Request": "Zgłoszenie", + "Request4K": "Żądanie 4K", "Denied": "Odrzucone", "Approve": "Zatwierdź", "PartlyAvailable": "Częściowo dostępne", @@ -33,11 +41,11 @@ "Errors": { "Validation": "Proszę sprawdzić wprowadzone wartości" }, - "Cancel": "Cancel", - "Submit": "Submit", - "Update": "Update", - "tvShow": "TV Show", - "movie": "Movie", + "Cancel": "Anuluj", + "Submit": "Wyślij", + "Update": "Aktualizacja", + "tvShow": "Serial", + "movie": "Film", "album": "Album" }, "PasswordReset": { @@ -55,6 +63,10 @@ "OfflineParagraph": "Serwer multimediów jest aktualnie offline.", "CheckPageForUpdates": "Tutaj znajdziesz aktualizacje dotyczące tej strony." }, + "ErrorPages": { + "NotFound": "Nie znaleziono strony", + "SomethingWentWrong": "Something went wrong!" + }, "NavigationBar": { "Discover": "Odkryj", "Search": "Szukaj", @@ -76,16 +88,16 @@ "Calendar": "Kalendarz", "UserPreferences": "Preferencje", "FeatureSuggestion": "Feature Suggestion", - "FeatureSuggestionTooltip": "Have a great new idea? Suggest it here!", + "FeatureSuggestionTooltip": "Masz świetny nowy pomysł? Zaproponuj go tutaj!", "Filter": { "Movies": "Filmy", "TvShows": "Programy TV", "Music": "Muzyka", - "People": "People" + "People": "Osoby" }, - "MorningWelcome": "Good morning!", - "AfternoonWelcome": "Good afternoon!", - "EveningWelcome": "Good evening!" + "MorningWelcome": "Dzień dobry!", + "AfternoonWelcome": "Dzień dobry!", + "EveningWelcome": "Dobry wieczór!" }, "Search": { "Title": "Szukaj", @@ -93,15 +105,15 @@ "MoviesTab": "Filmy", "TvTab": "Seriale", "MusicTab": "Muzyka", - "AdvancedSearch": "You can fill in any of the below to discover new media. All of the results are sorted by popularity", - "AdvancedSearchHeader": "Advanced Search", + "AdvancedSearch": "Możesz wypełnić dowolny z poniższych wpisów, aby odkryć nowe media. Wszystkie wyniki są posortowane według popularności", + "AdvancedSearchHeader": "Zaawansowane wyszukiwanie", "Suggestions": "Sugestie", "NoResults": "Niestety nic nie znaleziono!", "DigitalDate": "Wydanie cyfrowe: {{date}}", "TheatricalRelease": "Premiera kinowa: {{date}}", "ViewOnPlex": "Obejrzyj w Plex", "ViewOnEmby": "Obejrzyj w Emby", - "ViewOnJellyfin": "Play On Jellyfin", + "ViewOnJellyfin": "Odtwórz w Jellyfin", "RequestAdded": "Zgłoszenie dla {{title}} zostało pomyślnie dodane", "Similar": "Podobne", "Refine": "Zawęź", @@ -129,16 +141,19 @@ "Season": "Sezon {{seasonNumber}}", "SelectAllInSeason": "Wybierz wszystkie w sezonie {{seasonNumber}}" }, - "AdvancedSearchInstructions": "Please choose what type of media you are searching for:", - "YearOfRelease": "Year of Release", + "AdvancedSearchInstructions": "Wybierz jakiego rodzaju mediów szukasz:", + "YearOfRelease": "Rok wydania", + "SearchGenre": "Search Genre", + "SearchKeyword": "Search Keyword", + "SearchProvider": "Dostawcy wyszukiwania", "KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb" }, "Requests": { "Title": "Zgłoszenia", "Paragraph": "Poniżej znajdują się Twoje i wszystkie inne zgłoszenia, a także ich status akceptacji i pobierania.", "MoviesTab": "Filmy", - "ArtistName": "Artist", - "AlbumName": "Album Name", + "ArtistName": "Wykonawca", + "AlbumName": "Nazwa albumu", "TvTab": "Seriale", "MusicTab": "Muzyka", "RequestedBy": "Zgłoszone przez", @@ -155,11 +170,15 @@ "ChangeRootFolder": "Folder główny", "ChangeQualityProfile": "Profil jakości", "MarkUnavailable": "Oznacz jako niedostępne", + "MarkUnavailable4K": "Oznacz jako niedostępne 4K", "MarkAvailable": "Oznacz jako dostępne", + "MarkAvailable4K": "Oznacz jako Dostępne 4K", "Remove": "Usuń", "Deny": "Odrzuć", + "Deny4K": "Deny 4K", + "Has4KRequest": "Has 4K Request", "DenyReason": "Powód odrzucenia", - "DeniedReason": "Denied Reason", + "DeniedReason": "Powód odrzucenia", "Season": "Sezon", "GridTitle": "Tytuł", "AirDate": "Data emisji", @@ -181,48 +200,59 @@ "NextMinutes": "Kolejne zgłoszenie zostanie dodane za {{time}} minut(y)", "NextMinute": "Kolejne zgłoszenie zostanie dodane za {{time}} minut(y)" }, - "AllRequests": "All Requests", - "PendingRequests": "Pending Requests", - "ProcessingRequests": "Processing Requests", - "AvailableRequests": "Available Requests", - "DeniedRequests": "Denied Requests", - "RequestsToDisplay": "Requests to display", + "AllRequests": "Wszystkie zgłoszenia", + "PendingRequests": "Zgłoszenia oczekujące", + "ProcessingRequests": "Zgłoszenia przetwarzane", + "AvailableRequests": "Zgłoszenia dostępne", + "DeniedRequests": "Zgłoszenia odrzucone", + "RequestsToDisplay": "Zgłoszenia do wyświetlenia", "RequestsTitle": "Tytuł", "Details": "Szczegóły", - "Options": "Options", + "Options": "Opcje", "RequestPanel": { - "Delete": "Delete Request", - "Approve": "Approve Request", - "ChangeAvailability": "Mark Available", - "Deleted": "Successfully deleted selected items", - "Approved": "Successfully approved selected items" + "Delete": "Usuń zgłoszenie", + "Approve": "Zatwierdź zgłoszenie", + "Deny": "Deny Request", + "Approve4K": "Zatwierdź prośbę o 4K", + "Deny4K": "Deny 4K Request", + "ChangeAvailability": "Ozn. jako dostępne", + "Deleted": "Pomyślnie usunięto wybrane elementy", + "Approved": "Pomyślnie zatwierdzono wybrane elementy", + "Denied": "Successfully denied selected items" }, - "SuccessfullyApproved": "Successfully Approved", + "SuccessfullyApproved": "Zatwierdzono pomyślnie", + "SuccessfullyDeleted": "Prośba pomyślnie usunięta", "NowAvailable": "Request is now available", "NowUnavailable": "Request is now unavailable", "SuccessfullyReprocessed": "Successfully Re-processed the request", "DeniedRequest": "Denied Request", - "RequestCollection": "Request Collection", + "RequestCollection": "Poproś o kolekcję", "CollectionSuccesfullyAdded": "The collection {{name}} has been successfully added!", - "NeedToSelectEpisodes": "You need to select some episodes!", - "RequestAddedSuccessfully": "Request for {{title}} has been added successfully", + "NeedToSelectEpisodes": "Musisz wybrać jakieś odcinki!", + "RequestAddedSuccessfully": "Zgłoszenie dla {{title}} zostało pomyślnie dodane", "ErrorCodes": { "AlreadyRequested": "This has already been requested", "EpisodesAlreadyRequested": "We already have episodes requested from this series", "NoPermissionsOnBehalf": "You do not have the correct permissions to request on behalf of users!", "NoPermissions": "You do not have the correct permissions!", - "RequestDoesNotExist": "Request does not exist", + "RequestDoesNotExist": "Żądanie nie istnieje", "ChildRequestDoesNotExist": "Child Request does not exist", "NoPermissionsRequestMovie": "You do not have permissions to Request a Movie", "NoPermissionsRequestTV": "You do not have permissions to Request a TV Show", "NoPermissionsRequestAlbum": "You do not have permissions to Request an Album", "MovieRequestQuotaExceeded": "You have exceeded your Movie request quota!", - "TvRequestQuotaExceeded": "You have exceeded your Episode request quota!", - "AlbumRequestQuotaExceeded": "You have exceeded your Album request quota!" - } + "TvRequestQuotaExceeded": "Przekroczyłeś limit próśb odcinków!", + "AlbumRequestQuotaExceeded": "Przekroczyłeś limit próśb Albumów!" + }, + "Notify": "Powiadomienie", + "RemoveNotification": "Usuń powiadomienia", + "SuccessfulNotify": "Teraz otrzymasz powiadomienie o tytule {{title}}", + "SuccessfulUnNotify": "You will no longer be notified for title {{title}}", + "CouldntNotify": "Couldn't notify title {{title}}" }, "Issues": { "Title": "Problemy", + "IssuesForTitle": "Zgłoszenie dla {{title}}", "PendingTitle": "Oczekujące problemy", "InProgressTitle": "Problemy w trakcie", "ResolvedTitle": "Problemy rozwiązane", @@ -241,21 +271,22 @@ "WriteMessagePlaceholder": "Tutaj wpisz swoją wiadomość…", "ReportedBy": "Zgłoszone przez", "IssueDialog": { - "Title": "Report an issue", - "DescriptionPlaceholder": "Please describe the issue", - "TitlePlaceholder": "Short title of your issue", - "SelectCategory": "Select Category", - "IssueCreated": "Issue has been created" + "Title": "Zgłoś problem", + "DescriptionPlaceholder": "Proszę opisać problem", + "TitlePlaceholder": "Krótki tytuł Twojego problemu", + "SelectCategory": "Wybierz kategorię", + "IssueCreated": "Problem został zgłoszony" }, - "Outstanding": "There are outstanding issues", - "ResolvedDate": "Resolved date", - "CreatedDate": "Raised on", - "MarkedAsResolved": "This issue has now been marked as resolved!", - "MarkedAsInProgress": "This issue has now been marked as in progress!", - "Delete": "Delete issue", - "DeletedIssue": "Issue has been deleted", - "Chat": "Chat", - "Requested": "Requested", + "Outstanding": "Występują zaległe problemy", + "ResolvedDate": "Data rozwiązania", + "CreatedDate": "Zgłoszony", + "MarkedAsResolved": "Ten problem został oznaczony jako rozwiązany!", + "MarkedAsInProgress": "Ten problem został oznaczony jako rozwiązywany!", + "Delete": "Usuń zgłoszenie", + "DeletedIssue": "Problem został usunięty", + "Chat": "Czat", + "EnterYourMessage": "Wpisz swoją wiadomość", + "Requested": "Zgłoszone", "UserOnDate": "{{user}} on {{date}}" }, "Filter": { @@ -265,7 +296,7 @@ "Approved": "Zatwierdzone", "PendingApproval": "Oczekujące na zatwierdzenie", "WatchProviders": "Watch Providers", - "Keywords": "Keywords" + "Keywords": "Słowa kluczowe" }, "UserManagment": { "TvRemaining": "Seriale: pozostało {{remaining}}/{{total}}", @@ -281,52 +312,55 @@ }, "MediaDetails": { "Denied": "Odrzucone", + "Denied4K": "Denied 4K", + "Trailers": "Zwiastuny", "RecommendationsTitle": "Rekomendacje", "SimilarTitle": "Podobne", "VideosTitle": "Wideo", - "AlbumsTitle": "Albums", - "RequestAllAlbums": "Request All Albums", - "ClearSelection": "Clear Selection", - "RequestSelectedAlbums": "Request Selected Albums", - "ViewCollection": "View Collection", - "NotEnoughInfo": "Unfortunately there is not enough information about this show yet!", - "AdvancedOptions": "Advanced Options", - "AutoApproveOptions": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTv": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be send to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "QualityProfilesSelect": "Select A Quality Profile", - "RootFolderSelect": "Select A Root Folder", + "AlbumsTitle": "Albumy", + "RequestAllAlbums": "Zgłoś wszystkie albumy", + "ClearSelection": "Wyczyść zaznaczenie", + "RequestSelectedAlbums": "Zgłoś zaznaczone albumy", + "ViewCollection": "Pokaż kolekcję", + "NotEnoughInfo": "Niestety nie ma jeszcze wystarczających informacji na temat tego serialu!", + "AdvancedOptions": "Opcje zaawansowane", + "AutoApproveOptions": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTv": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be sent to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "QualityProfilesSelect": "Wybierz profil jakości", + "RootFolderSelect": "Wybierz katalog główny", "LanguageProfileSelect": "Select A Language Profile", - "Status": "Status:", + "Status": "Stan:", "StatusValues": { "Rumored": "Rumored", - "Planned": "Planned", + "Planned": "Planowany", "In Production": "In Production", "Post Production": "Post Production", - "Released": "Released", + "Released": "Wydany", "Running": "Running", "Returning Series": "Returning Series", - "Ended": "Ended", - "Canceled": "Canceled" + "Ended": "Zakończono", + "Canceled": "Anulowano" }, - "Seasons": "Seasons:", - "Episodes": "Episodes:", - "Availability": "Availability:", - "RequestStatus": "Status zgłoszenia", - "Quality": "Quality:", - "RootFolderOverride": "Root Folder Override:", - "QualityOverride": "Quality Override:", - "Network": "Network:", - "Genres": "Genres:", - "FirstAired": "First Aired:", - "TheatricalRelease": "Release:", - "DigitalRelease": "Digital Release:", - "Votes": "Votes:", - "Runtime": "Runtime:", - "Minutes": "{{runtime}} Minutes", - "Revenue": "Revenue:", - "Budget": "Budget:", - "Keywords": "Keywords/Tags:", + "Seasons": "Sezony:", + "Episodes": "Odcinków:", + "Availability": "Dostępność:", + "RequestStatus": "Request Status:", + "Quality": "Jakość:", + "RootFolderOverride": "Wymuszenie folderu głównego:", + "QualityOverride": "Wymuszenie jakości:", + "Network": "Stacja:", + "GenresLabel": "Gatunki:", + "Genres": "Gatunki", + "FirstAired": "Pierwsza emisja:", + "TheatricalRelease": "Premiera kinowa:", + "DigitalRelease": "Wydanie cyfrowe:", + "Votes": "Głosy:", + "Runtime": "Czas trwania:", + "Minutes": "{{runtime}} minut(y)", + "Revenue": "Przychód:", + "Budget": "Budżet:", + "Keywords": "Słowa kluczowe/tagi:", "Casts": { "CastTitle": "Obsada" }, @@ -335,33 +369,36 @@ "FirstSeasonTooltip": "Zgłoszenie obejmie pierwszy sezon tego serialu", "LatestSeasonTooltip": "Zgłoszenie obejmie najnowszy sezon tego serialu", "NoEpisodes": "There unfortunately is no episode data for this show yet!", - "SeasonNumber": "Season {{number}}" + "SeasonNumber": "Sezon {{number}}" }, - "SonarrConfiguration": "Sonarr Configuration", - "RadarrConfiguration": "Radarr Configuration", - "RequestOnBehalf": "Request on behalf of", - "PleaseSelectUser": "Please select a user", - "StreamingOn": "Streaming On:", - "RequestedBy": "Requested By:", - "RequestDate": "Request Date:", + "SonarrConfiguration": "Konfiguracja Sonarr", + "RadarrConfiguration": "Konfiguracja Radarr", + "RequestOnBehalf": "Zgłoszenie w imieniu", + "PleaseSelectUser": "Proszę wybrać użytkownika", + "StreamingOn": "Strumieniowane w:", + "RequestedBy": "Zgłoszone przez:", + "RequestedByOn": "Requested By {{user}} on {{date}}", + "RequestDate": "Data zgłoszenia:", "DeniedReason": "Denied Reason:", "ReProcessRequest": "Re-Process Request", + "ReProcessRequest4K": "Re-Process 4K Request", "Music": { - "Type": "Type:", - "Country": "Country:", - "StartDate": "Start Date:", - "EndDate": "EndDate:" - } + "Type": "Typ:", + "Country": "Kraj:", + "StartDate": "Data rozpoczęcia:", + "EndDate": "Data zakończenia:" + }, + "RequestSource": "Source:" }, "Discovery": { "PopularTab": "Popularne", "TrendingTab": "Zyskujące popularność", "UpcomingTab": "Nadchodzące", "SeasonalTab": "Seasonal", - "RecentlyRequestedTab": "Recently Requested", + "RecentlyRequestedTab": "Ostatnie prośby", "Movies": "Filmy", - "Combined": "Combined", - "Tv": "TV", + "Combined": "Połączone", + "Tv": "Seriale", "CardDetails": { "Availability": "Dostępność", "Studio": "Studio", @@ -374,35 +411,45 @@ "Writer": "Scenarzysta", "ExecProducer": "Producent wykonawczy" }, - "NoSearch": "Sorry, nothing matches your search!" + "NoSearch": "Przepraszamy, nic nie pasuje do Twojego wyszukiwania!" }, "UserPreferences": { "Welcome": "Witaj {{username}}!", - "OmbiLanguage": "Language", - "DarkMode": "Dark Mode", - "Updated": "Successfully Updated", - "StreamingCountry": "Streaming Country", - "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will have US related streaming information.", - "LanguageDescription": "This is the language you would like the Ombi interface to be displayed in.", - "MobileQRCode": "Mobile QR Code", - "LegacyApp": "Launch Legacy App", + "OmbiLanguage": "Język", + "DarkMode": "Tryb ciemny", + "Updated": "Zaktualizowano pomyślnie", + "StreamingCountry": "Kraj strumieniowania", + "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will get US related streaming information.", + "LanguageDescription": "To jest język, w którym ma być wyświetlany interfejs Ombi.", + "MobileQRCode": "Kod QR z telefonu", + "LegacyApp": "Uruchom starszą aplikację", "NoQrCode": "Please contact your administrator to enable QR codes", - "UserType": "User Type:", + "UserType": "Typ Użytkownika:", "ChangeDetails": "Change Details", - "NeedCurrentPassword": "You need your current password to make any changes here", - "CurrentPassword": "Current Password", - "EmailAddress": "Email Address", - "NewPassword": "New Password", - "NewPasswordConfirm": "New Password Confirm", - "Security": "Security", - "Profile": "Profile", - "UpdatedYourInformation": "Updated your information" + "NeedCurrentPassword": "Potrzebujesz swojego aktualnego hasła, aby potwierdzić zmiany", + "CurrentPassword": "Obecne hasło", + "EmailAddress": "Adres e-mail", + "NewPassword": "Nowe Hasło", + "NewPasswordConfirm": "Potwierdź nowe hasło", + "Security": "Ochrona", + "Profile": "Profil", + "UpdatedYourInformation": "Zaktualizuj swoje informacje", + "Unsubscribed": "Subskrypcja anulowana!" }, "UserTypeLabel": { - "1": "Local User", - "2": "Plex User", - "3": "Emby User", + "1": "Użytkownik lokalny", + "2": "Użytkownik Plex", + "3": "Użytkownik Emby", "4": "Emby Connect User", - "5": "Jellyfin User" + "5": "Użytkownik Jellyfin" + }, + "Paginator": { + "itemsPerPageLabel": "Wpisów na stronie:", + "nextPageLabel": "Następna strona", + "previousPageLabel": "Poprzednia strona", + "firstPageLabel": "Pierwsza strona", + "lastPageLabel": "Ostatnia Strona", + "rangePageLabel1": "0 z {{length}}", + "rangePageLabel2": "{{startIndex}} - {{endIndex}} z {{length}}" } } diff --git a/src/Ombi/wwwroot/translations/pt-BR.json b/src/Ombi/wwwroot/translations/pt-BR.json new file mode 100644 index 000000000..dd8190628 --- /dev/null +++ b/src/Ombi/wwwroot/translations/pt-BR.json @@ -0,0 +1,455 @@ +{ + "Login": { + "SignInButton": "Iniciar sessão", + "UsernamePlaceholder": "Nome de usuário", + "PasswordPlaceholder": "Senha", + "RememberMe": "Lembrar-me", + "SignInWith": "Entre com {{appName}}", + "SignInWithPlex": "Iniciar sessão com Plex", + "ForgottenPassword": "Esqueceu sua senha?", + "Errors": { + "IncorrectCredentials": "Nome de usuário ou senha incorretos" + } + }, + "Common": { + "ContinueButton": "Continuar", + "Available": "Disponível", + "Available4K": "Disponível", + "Approved": "Aprovado", + "Approve4K": "Aprovar", + "Pending": "Pendente", + "PartiallyAvailable": "Parcialmente Disponível", + "Monitored": "Monitorado", + "NotAvailable": "Não Disponível", + "ProcessingRequest": "Processando Solicitação", + "ProcessingRequest4K": "Processing Request 4K", + "PendingApproval": "Aprovação Pendente", + "PendingApproval4K": "Pending Approval 4K", + "RequestDenied": "Solicitação Negada", + "RequestDenied4K": "Request Denied 4K", + "NotRequested": "Não Solicitado", + "NotRequested4K": "Not Requested 4K", + "Requested": "Solicitado", + "Requested4K": "4K requisitado", + "Search": "Buscar", + "Request": "Solicitar", + "Request4K": "Requisitar 4K", + "Denied": "Negado", + "Approve": "Aprovar", + "PartlyAvailable": "Parcialmente Disponível", + "ViewDetails": "Ver detalhes", + "Errors": { + "Validation": "Por favor, verifique os dados inseridos" + }, + "Cancel": "Cancelar", + "Submit": "Submeter", + "Update": "Atualizar", + "tvShow": "Series", + "movie": "Filmes", + "album": "Álbum" + }, + "PasswordReset": { + "EmailAddressPlaceholder": "Endereço de e-mail", + "ResetPasswordButton": "Redefinir Senha" + }, + "LandingPage": { + "OnlineHeading": "Online no momento", + "OnlineParagraph": "O servidor de mídia está atualmente online", + "PartiallyOnlineHeading": "Parcialmente Online", + "PartiallyOnlineParagraph": "O servidor de mídia está parcialmente online.", + "MultipleServersUnavailable": "Existem {{serversUnavailable}} servidores offline de um total de {{totalServers}}.", + "SingleServerUnavailable": "Existe {{serversUnavailable}} servidor offline de um total de {{totalServers}}.", + "OfflineHeading": "Offline Agora", + "OfflineParagraph": "O servidor de mídia está atualmente offline.", + "CheckPageForUpdates": "Verifique esta página para acompanhar as atualizações do site." + }, + "ErrorPages": { + "NotFound": "Pagina não encontrada", + "SomethingWentWrong": "Algo deu errado!" + }, + "NavigationBar": { + "Discover": "Explorar", + "Search": "Pesquisar", + "Requests": "Solicitações", + "UserManagement": "User Management", + "Issues": "Problemas", + "Vote": "Votar", + "Donate": "Doações!", + "DonateLibraryMaintainer": "Doar para o Dono da Biblioteca", + "DonateTooltip": "É assim que convenço minha esposa a me deixar passar o meu tempo livre desenvolvendo o Ombi 😁", + "UpdateAvailableTooltip": "Atualização Disponível!", + "Settings": "Configurações", + "Welcome": "Bem-vindo(a), {{username}}", + "UpdateDetails": "Detalhes da Atualização", + "Logout": "Desconectar", + "OpenMobileApp": "Abrir Aplicativo do Celular", + "RecentlyAdded": "Recentemente Adicionado", + "ChangeTheme": "Trocar Tema", + "Calendar": "Calendário", + "UserPreferences": "Preferências", + "FeatureSuggestion": "Feature Suggestion", + "FeatureSuggestionTooltip": "Teve uma ótima idéia? Sugira aqui!", + "Filter": { + "Movies": "Filmes", + "TvShows": "Séries", + "Music": "Músicas", + "People": "Pessoas" + }, + "MorningWelcome": "Bom dia!", + "AfternoonWelcome": "Boa tarde!", + "EveningWelcome": "Boa noite!" + }, + "Search": { + "Title": "Pesquisar", + "Paragraph": "Quer assistir a algo que não está disponível? Sem problemas, basta pesquisar abaixo e solicitar!", + "MoviesTab": "Filmes", + "TvTab": "Séries", + "MusicTab": "Músicas", + "AdvancedSearch": "Você pode preencher qualquer um dos abaixo para descobrir novas mídias. Todos os resultados são classificados por popularidade", + "AdvancedSearchHeader": "Pesquisa avançada", + "Suggestions": "Sugestões", + "NoResults": "Desculpe, não encontramos nenhum resultado!", + "DigitalDate": "Lançamento Digital: {{date}}", + "TheatricalRelease": "Lançamento nos Cinemas: {{date}}", + "ViewOnPlex": "View On Plex", + "ViewOnEmby": "View On Emby", + "ViewOnJellyfin": "Assistir no Jellyfin", + "RequestAdded": "O pedido de {{title}} foi adicionado com sucesso", + "Similar": "Semelhantes", + "Refine": "Corrigir", + "SearchBarPlaceholder": "Digite Aqui para Pesquisar", + "Movies": { + "PopularMovies": "Filmes Populares", + "UpcomingMovies": "Filmes Em Breve", + "TopRatedMovies": "Filmes Mais Votados", + "NowPlayingMovies": "Filmes em Cartaz", + "HomePage": "Página Inicial", + "Trailer": "Trailer" + }, + "TvShows": { + "Popular": "Popular", + "Trending": "Tendências", + "MostWatched": "Mais Assistidos", + "MostAnticipated": "Mais Aguardados", + "Results": "Resultados", + "AirDate": "Data de Exibição:", + "AllSeasons": "Todas as Temporadas", + "FirstSeason": "Primeira temporada", + "LatestSeason": "Última Temporada", + "Select": "Selecionar...", + "SubmitRequest": "Enviar solicitação", + "Season": "Temporada: {{seasonNumber}}", + "SelectAllInSeason": "Selecione Tudo na Temporada {{seasonNumber}}" + }, + "AdvancedSearchInstructions": "Por favor, escolha o tipo de mídia que você está procurando:", + "YearOfRelease": "Ano de lançamento", + "SearchGenre": "Pesquisa por gênero", + "SearchKeyword": "Pesquisar palavras-chave", + "SearchProvider": "Provedores de pesquisa", + "KeywordSearchingDisclaimer": "Por favor, note que a busca por palavra-chave é muito acertada e perdida devido aos dados inconsistentes no TheMovieDb" + }, + "Requests": { + "Title": "Solicitações", + "Paragraph": "Abaixo, você pode ver o seu e todos os outros pedidos, bem como o seu download e status de aprovação.", + "MoviesTab": "Filmes", + "ArtistName": "Artistas", + "AlbumName": "Nome do álbum", + "TvTab": "Séries", + "MusicTab": "Músicas", + "RequestedBy": "Solicitado por", + "Status": "Status", + "RequestStatus": "Status da solicitação", + "Denied": " Negados:", + "TheatricalRelease": "Lançamento nos Cinemas: {{date}}", + "ReleaseDate": "Lançado: {{date}}", + "TheatricalReleaseSort": "Lançamento nos Cinemas", + "DigitalRelease": "Lançamento Digital: {{date}}", + "RequestDate": "Data da Solicitação", + "QualityOverride": "Substituição de Qualidade:", + "RootFolderOverride": "Substituição da Pasta Raiz:", + "ChangeRootFolder": "Pasta Raiz", + "ChangeQualityProfile": "Perfil de Qualidade", + "MarkUnavailable": "Marcar como Indisponível", + "MarkUnavailable4K": "Marcar indisponível 4K", + "MarkAvailable": "Marcar como Disponível", + "MarkAvailable4K": "Marcar disponível 4K", + "Remove": "Remover", + "Deny": "Negar", + "Deny4K": "Recusar 4K", + "Has4KRequest": "Pedido 4K existente", + "DenyReason": "Razão da rejeição", + "DeniedReason": "Razão da rejeição", + "Season": "Temporada", + "GridTitle": "Título", + "AirDate": "AirDate", + "GridStatus": "Status", + "ReportIssue": "Relatar Problema", + "Filter": "Filtro", + "Sort": "Ordenar por", + "SeasonNumberHeading": "Temporada: {seasonNumber}", + "SortTitleAsc": "Título ▲", + "SortTitleDesc": "Título ▼", + "SortRequestDateAsc": "Data da Solicitação ▲", + "SortRequestDateDesc": "Data da Solicitação ▼", + "SortStatusAsc": "Status ▲", + "SortStatusDesc": "Status ▼", + "Remaining": { + "Quota": "{{remaining}}/{{total}} solicitações restantes", + "NextDays": "Outra solicitação será adicionada em {{time}} dias", + "NextHours": "Outra solicitação será adicionada em {{time}} horas", + "NextMinutes": "Outra solicitação será adicionada em {{time}} minutos", + "NextMinute": "Outra solicitação será adicionada em {{time}} minuto" + }, + "AllRequests": "Todas solicitações", + "PendingRequests": "Solicitações pendentes", + "ProcessingRequests": "Solicitações em andamento", + "AvailableRequests": "Solicitação Disponíveis", + "DeniedRequests": "Solicitações Negadas", + "RequestsToDisplay": "Itens por página", + "RequestsTitle": "Título", + "Details": "Detalhes", + "Options": "Opções", + "RequestPanel": { + "Delete": "Apagar Solicitação", + "Approve": "Aprovar Solicitação", + "Deny": "Recusar pedido", + "Approve4K": "Aprovar pedido 4K", + "Deny4K": "Recusar pedido de 4K", + "ChangeAvailability": "Marcar Como Disponível", + "Deleted": "Itens selecionados excluídos com sucesso", + "Approved": "Itens selecionados aprovados com sucesso", + "Denied": "Itens selecionados negados com sucesso" + }, + "SuccessfullyApproved": "Aprovado com Sucesso", + "SuccessfullyDeleted": "Solicitação excluída com sucesso", + "NowAvailable": "O pedido agora está disponível", + "NowUnavailable": "A solicitação está indisponível", + "SuccessfullyReprocessed": "A solicitação foi reprocessada com sucesso", + "DeniedRequest": "Pedido negado", + "RequestCollection": "Solicitar Coleção", + "CollectionSuccesfullyAdded": "A coleção {{name}} foi adicionada com sucesso!", + "NeedToSelectEpisodes": "Você precisa selecionar alguns episódios!", + "RequestAddedSuccessfully": "Solicitação de {{title}} foi adicionada com sucesso", + "ErrorCodes": { + "AlreadyRequested": "Isso já foi solicitado", + "EpisodesAlreadyRequested": "Já temos episódios solicitados desta série", + "NoPermissionsOnBehalf": "Você não tem as permissões corretas para pedir em nome dos usuários!", + "NoPermissions": "Você não tem as permissões corretas!", + "RequestDoesNotExist": "A solicitação não existe", + "ChildRequestDoesNotExist": "Child Request does not exist", + "NoPermissionsRequestMovie": "You do not have permissions to Request a Movie", + "NoPermissionsRequestTV": "You do not have permissions to Request a TV Show", + "NoPermissionsRequestAlbum": "You do not have permissions to Request an Album", + "MovieRequestQuotaExceeded": "You have exceeded your Movie request quota!", + "TvRequestQuotaExceeded": "You have exceeded your Episode request quota!", + "AlbumRequestQuotaExceeded": "You have exceeded your Album request quota!" + }, + "Notify": "Notify", + "RemoveNotification": "Remove Notifications", + "SuccessfulNotify": "You will now be notified for title {{title}}", + "SuccessfulUnNotify": "You will no longer be notified for title {{title}}", + "CouldntNotify": "Couldn't notify title {{title}}" + }, + "Issues": { + "Title": "Problemas", + "IssuesForTitle": "Issues for {{title}}", + "PendingTitle": "Problemas pendentes", + "InProgressTitle": "Problemas em resolução", + "ResolvedTitle": "Problemas Resolvidos", + "ColumnTitle": "Título", + "Count": "Count", + "Category": "Categoria", + "Status": "Status", + "Details": "Detalhes", + "Description": "Descrição", + "NoComments": "Sem Comentários!", + "MarkInProgress": "Marcar como em andamento", + "MarkResolved": "Marcar como resolvido", + "SendMessageButton": "Enviar", + "Subject": "Assunto", + "Comments": "Comentários", + "WriteMessagePlaceholder": "Escreva sua mensagem aqui...", + "ReportedBy": "Reportado por", + "IssueDialog": { + "Title": "Reportar um problema", + "DescriptionPlaceholder": "Por favor, descreva o problema", + "TitlePlaceholder": "Título curto para o problema", + "SelectCategory": "Selecione Uma Categoria", + "IssueCreated": "Um registro de problema foi criado" + }, + "Outstanding": "Existem problemas pendentes", + "ResolvedDate": "Data da resolução", + "CreatedDate": "Notificado em", + "MarkedAsResolved": "Esse problema foi marcado como resolvido!", + "MarkedAsInProgress": "Esse problema foi marcado como resolvendo!", + "Delete": "Deletar problema", + "DeletedIssue": "O problema foi excluído", + "Chat": "Chat", + "EnterYourMessage": "Enter Your Message", + "Requested": "Solicitado", + "UserOnDate": "{{user}} on {{date}}" + }, + "Filter": { + "ClearFilter": "Limpar Filtro", + "FilterHeaderAvailability": "Disponibilidade", + "FilterHeaderRequestStatus": "Status", + "Approved": "Aprovado", + "PendingApproval": "Aprovação Pendente", + "WatchProviders": "Watch Providers", + "Keywords": "Keywords" + }, + "UserManagment": { + "TvRemaining": "Séries: {{remaining}}/{{total}} restantes", + "MovieRemaining": "Filmes: {{remaining}}/{{total}} restantes", + "MusicRemaining": "Músicas: {{remaining}}/{{total}} restantes", + "TvDue": "Série: {{date}}", + "MovieDue": "Filme: {{date}}", + "MusicDue": "Música: {{date}}" + }, + "Votes": { + "CompletedVotesTab": "Votado", + "VotesTab": "Votos necessários" + }, + "MediaDetails": { + "Denied": "Rejeitado", + "Denied4K": "4K recusado", + "Trailers": "Trailers", + "RecommendationsTitle": "Recomendações", + "SimilarTitle": "Semelhante", + "VideosTitle": "Vídeos", + "AlbumsTitle": "Álbuns", + "RequestAllAlbums": "Solicitar Todos Álbuns", + "ClearSelection": "Limpar Seleção", + "RequestSelectedAlbums": "Solicitar Álbuns Selecionados", + "ViewCollection": "Ver Coleção", + "NotEnoughInfo": "Infelizmente ainda não há informação sobre essa série!", + "AdvancedOptions": "Opções Avançadas", + "AutoApproveOptions": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTv": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be sent to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "QualityProfilesSelect": "Selecione um perfil de qualidade", + "RootFolderSelect": "Selecione o diretório raiz", + "LanguageProfileSelect": "Select A Language Profile", + "Status": "Status:", + "StatusValues": { + "Rumored": "Rumored", + "Planned": "Planned", + "In Production": "In Production", + "Post Production": "Post Production", + "Released": "Released", + "Running": "Running", + "Returning Series": "Returning Series", + "Ended": "Ended", + "Canceled": "Canceled" + }, + "Seasons": "Seasons:", + "Episodes": "Episodes:", + "Availability": "Disponibilidade:", + "RequestStatus": "Request Status:", + "Quality": "Qualidade:", + "RootFolderOverride": "Substituição da Pasta Raiz:", + "QualityOverride": "Substituição de Qualidade:", + "Network": "Rede:", + "GenresLabel": "Gêneros:", + "Genres": "Gêneros", + "FirstAired": "Primeira Exibição:", + "TheatricalRelease": "Theatrical Release:", + "DigitalRelease": "Lançamento Digital:", + "Votes": "Votos:", + "Runtime": "Tempo de execução:", + "Minutes": "{{runtime}} Minutos", + "Revenue": "Receita:", + "Budget": "Orçamento:", + "Keywords": "Palavras-Chave/Tags:", + "Casts": { + "CastTitle": "Elenco" + }, + "EpisodeSelector": { + "AllSeasonsTooltip": "Isto irá pedir todas as temporadas da série", + "FirstSeasonTooltip": "Isto somente irá pedir a 1ª temporada da série", + "LatestSeasonTooltip": "Isto somente irá pedir a última temporada da série", + "NoEpisodes": "There unfortunately is no episode data for this show yet!", + "SeasonNumber": "Temporada: {{number}}" + }, + "SonarrConfiguration": "Configuração do Sonarr", + "RadarrConfiguration": "Configuração do Radarr", + "RequestOnBehalf": "Pedido em nome de", + "PleaseSelectUser": "Por favor, selecione um usuário", + "StreamingOn": "Streaming On:", + "RequestedBy": "Solicitado por:", + "RequestedByOn": "Requested By {{user}} on {{date}}", + "RequestDate": "Data da Solicitação:", + "DeniedReason": "Razão da rejeição:", + "ReProcessRequest": "Re-Process Request", + "ReProcessRequest4K": "Reprocessar pedido 4K", + "Music": { + "Type": "Type:", + "Country": "Country:", + "StartDate": "Start Date:", + "EndDate": "EndDate:" + }, + "RequestSource": "Source:" + }, + "Discovery": { + "PopularTab": "Popular", + "TrendingTab": "Tendências", + "UpcomingTab": "Próximo", + "SeasonalTab": "Seasonal", + "RecentlyRequestedTab": "Recently Requested", + "Movies": "Filmes", + "Combined": "Combinados", + "Tv": "Serie", + "CardDetails": { + "Availability": "Disponibilidade", + "Studio": "Estúdio", + "Network": "Rede", + "UnknownNetwork": "Desconhecido", + "RequestStatus": "Estado da solicitação", + "Director": "Diretor", + "InCinemas": "Nos Cinemas", + "FirstAired": "Primeira Exibição", + "Writer": "Escritor", + "ExecProducer": "Produtor Executivo" + }, + "NoSearch": "Desculpe, nada corresponde à sua pesquisa!" + }, + "UserPreferences": { + "Welcome": "Bem-vindo, {{username}}!", + "OmbiLanguage": "Idioma", + "DarkMode": "Modo Escuro", + "Updated": "Atualizado com Sucesso", + "StreamingCountry": "País de Streaming", + "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will get US related streaming information.", + "LanguageDescription": "Este é o idioma que você gostaria de exibir na interface do Ombi.", + "MobileQRCode": "QR Code para Celular", + "LegacyApp": "Iniciar Legacy App", + "NoQrCode": "Please contact your administrator to enable QR codes", + "UserType": "User Type:", + "ChangeDetails": "Change Details", + "NeedCurrentPassword": "You need your current password to make any changes here", + "CurrentPassword": "Current Password", + "EmailAddress": "Endereço de e-mail", + "NewPassword": "New Password", + "NewPasswordConfirm": "New Password Confirm", + "Security": "Security", + "Profile": "Profile", + "UpdatedYourInformation": "Updated your information", + "Unsubscribed": "Unsubscribed!" + }, + "UserTypeLabel": { + "1": "Local User", + "2": "Plex User", + "3": "Emby User", + "4": "Emby Connect User", + "5": "Jellyfin User" + }, + "Paginator": { + "itemsPerPageLabel": "Items per page:", + "nextPageLabel": "Next page", + "previousPageLabel": "Previous page", + "firstPageLabel": "First page", + "lastPageLabel": "Last page", + "rangePageLabel1": "0 of {{length}}", + "rangePageLabel2": "{{startIndex}} – {{endIndex}} of {{length}}" + } +} diff --git a/src/Ombi/wwwroot/translations/pt.json b/src/Ombi/wwwroot/translations/pt.json index cd2a3d80a..0f10889c9 100644 --- a/src/Ombi/wwwroot/translations/pt.json +++ b/src/Ombi/wwwroot/translations/pt.json @@ -1,37 +1,45 @@ { "Login": { "SignInButton": "Iniciar sessão", - "UsernamePlaceholder": "Nome de usuário", - "PasswordPlaceholder": "Senha", - "RememberMe": "Lembrar-me", + "UsernamePlaceholder": "Nome de Usuário", + "PasswordPlaceholder": "Palavra-passe", + "RememberMe": "Recorde-me", "SignInWith": "Entre com {{appName}}", "SignInWithPlex": "Iniciar sessão com Plex", "ForgottenPassword": "Esqueceu sua senha?", "Errors": { - "IncorrectCredentials": "Nome de usuário ou senha incorretos" + "IncorrectCredentials": "Usuário ou senha incorretos" } }, "Common": { "ContinueButton": "Continuar", "Available": "Disponível", - "Approved": "Approved", + "Available4K": "Disponível 4K", + "Approved": "Aprovado", + "Approve4K": "Approve 4K", "Pending": "Pending", "PartiallyAvailable": "Parcialmente Disponível", - "Monitored": "Monitorado", - "NotAvailable": "Não Disponível", - "ProcessingRequest": "Processando Solicitação", + "Monitored": "Monitored", + "NotAvailable": "Não disponível", + "ProcessingRequest": "Processando o pedido", + "ProcessingRequest4K": "Processing Request 4K", "PendingApproval": "Aprovação Pendente", - "RequestDenied": "Solicitação Negada", + "PendingApproval4K": "Pending Approval 4K", + "RequestDenied": "Pedido Negado", + "RequestDenied4K": "Request Denied 4K", "NotRequested": "Não Solicitado", - "Requested": "Solicitado", + "NotRequested4K": "Not Requested 4K", + "Requested": "Pedido", + "Requested4K": "Requested 4K", "Search": "Search", "Request": "Solicitar", - "Denied": "Negado", + "Request4K": "Request 4K", + "Denied": "Recusado", "Approve": "Aprovar", "PartlyAvailable": "Parcialmente Disponível", "ViewDetails": "Ver detalhes", "Errors": { - "Validation": "Por favor, verifique os dados inseridos" + "Validation": "Por favor, verifique os valores inseridos" }, "Cancel": "Cancelar", "Submit": "Submeter", @@ -41,41 +49,45 @@ "album": "Album" }, "PasswordReset": { - "EmailAddressPlaceholder": "Endereço de e-mail", - "ResetPasswordButton": "Redefinir Senha" + "EmailAddressPlaceholder": "Email Address", + "ResetPasswordButton": "Nova senha" }, "LandingPage": { "OnlineHeading": "Online no momento", - "OnlineParagraph": "O servidor de mídia está atualmente online", - "PartiallyOnlineHeading": "Parcialmente Online", - "PartiallyOnlineParagraph": "O servidor de mídia está parcialmente online.", - "MultipleServersUnavailable": "Existem {{serversUnavailable}} servidores offline de um total de {{totalServers}}.", - "SingleServerUnavailable": "Existe {{serversUnavailable}} servidor offline de um total de {{totalServers}}.", - "OfflineHeading": "Offline Agora", - "OfflineParagraph": "O servidor de mídia está atualmente offline.", - "CheckPageForUpdates": "Verifique esta página para acompanhar as atualizações do site." + "OnlineParagraph": "The media server is currently online", + "PartiallyOnlineHeading": "Partially Online", + "PartiallyOnlineParagraph": "The media server is partially online.", + "MultipleServersUnavailable": "There are {{serversUnavailable}} servers offline out of {{totalServers}}.", + "SingleServerUnavailable": "There is {{serversUnavailable}} server offline out of {{totalServers}}.", + "OfflineHeading": "Currently Offline", + "OfflineParagraph": "The media server is currently offline.", + "CheckPageForUpdates": "Check this page for continuous site updates." + }, + "ErrorPages": { + "NotFound": "Page not found", + "SomethingWentWrong": "Something went wrong!" }, "NavigationBar": { "Discover": "Discover", - "Search": "Pesquisar", - "Requests": "Solicitações", - "UserManagement": "User Management", - "Issues": "Problemas", - "Vote": "Votar", - "Donate": "Doações!", - "DonateLibraryMaintainer": "Doar para o Dono da Biblioteca", + "Search": "Search", + "Requests": "Requests", + "UserManagement": "Users", + "Issues": "Issues", + "Vote": "Vote", + "Donate": "Donate!", + "DonateLibraryMaintainer": "Donate to Library Maintainer", "DonateTooltip": "This is how I convince my wife to let me spend my spare time developing Ombi 😁", - "UpdateAvailableTooltip": "Atualização Disponível!", - "Settings": "Configurações", - "Welcome": "Bem-vindo(a), {{username}}", - "UpdateDetails": "Detalhes da Atualização", - "Logout": "Desconectar", - "OpenMobileApp": "Abrir Aplicativo do Celular", - "RecentlyAdded": "Recentemente Adicionado", + "UpdateAvailableTooltip": "Update Available!", + "Settings": "Settings", + "Welcome": "Welcome {{username}}", + "UpdateDetails": "Update Details", + "Logout": "Logout", + "OpenMobileApp": "Open Mobile App", + "RecentlyAdded": "Recently Added", "ChangeTheme": "Change Theme", "Calendar": "Calendar", "UserPreferences": "Preferences", - "FeatureSuggestion": "Feature Suggestion", + "FeatureSuggestion": "Features", "FeatureSuggestionTooltip": "Have a great new idea? Suggest it here!", "Filter": { "Movies": "Movies", @@ -88,98 +100,105 @@ "EveningWelcome": "Good evening!" }, "Search": { - "Title": "Pesquisar", - "Paragraph": "Quer assistir a algo que não está disponível? Sem problemas, basta pesquisar abaixo e solicitar!", - "MoviesTab": "Filmes", - "TvTab": "Séries", - "MusicTab": "Músicas", + "Title": "Search", + "Paragraph": "Want to watch something that is not currently available? No problem, just search for it below and request it!", + "MoviesTab": "Movies", + "TvTab": "TV Shows", + "MusicTab": "Music", "AdvancedSearch": "You can fill in any of the below to discover new media. All of the results are sorted by popularity", "AdvancedSearchHeader": "Advanced Search", - "Suggestions": "Sugestões", - "NoResults": "Desculpe, não encontramos nenhum resultado!", - "DigitalDate": "Lançamento Digital: {{date}}", - "TheatricalRelease": "Lançamento nos Cinemas: {{date}}", - "ViewOnPlex": "View On Plex", - "ViewOnEmby": "View On Emby", + "Suggestions": "Suggestions", + "NoResults": "Sorry, we didn't find any results!", + "DigitalDate": "Digital Release: {{date}}", + "TheatricalRelease": "Theatrical Release: {{date}}", + "ViewOnPlex": "Play On Plex", + "ViewOnEmby": "Play On Emby", "ViewOnJellyfin": "Play On Jellyfin", - "RequestAdded": "O pedido de {{title}} foi adicionado com sucesso", - "Similar": "Semelhantes", - "Refine": "Corrigir", - "SearchBarPlaceholder": "Digite Aqui para Pesquisar", + "RequestAdded": "Request for {{title}} has been added successfully", + "Similar": "Similar", + "Refine": "Refine", + "SearchBarPlaceholder": "Type Here to Search", "Movies": { - "PopularMovies": "Filmes Populares", - "UpcomingMovies": "Filmes Em Breve", - "TopRatedMovies": "Filmes Mais Votados", - "NowPlayingMovies": "Filmes em Cartaz", - "HomePage": "Página Inicial", + "PopularMovies": "Popular Movies", + "UpcomingMovies": "Upcoming Movies", + "TopRatedMovies": "Top Rated Movies", + "NowPlayingMovies": "Now Playing Movies", + "HomePage": "Home Page", "Trailer": "Trailer" }, "TvShows": { "Popular": "Popular", - "Trending": "Tendências", - "MostWatched": "Mais Assistidos", - "MostAnticipated": "Mais Aguardados", - "Results": "Resultados", - "AirDate": "Data de Exibição:", - "AllSeasons": "Todas as Temporadas", - "FirstSeason": "Primeira temporada", - "LatestSeason": "Última Temporada", - "Select": "Selecionar...", - "SubmitRequest": "Enviar solicitação", + "Trending": "Trending", + "MostWatched": "Most Watched", + "MostAnticipated": "Most Anticipated", + "Results": "Results", + "AirDate": "Air Date:", + "AllSeasons": "All Seasons", + "FirstSeason": "First Season", + "LatestSeason": "Latest Season", + "Select": "Select ...", + "SubmitRequest": "Submit Request", "Season": "Season {{seasonNumber}}", - "SelectAllInSeason": "Selecione Tudo na Temporada {{seasonNumber}}" + "SelectAllInSeason": "Select All in Season {{seasonNumber}}" }, "AdvancedSearchInstructions": "Please choose what type of media you are searching for:", "YearOfRelease": "Year of Release", + "SearchGenre": "Search Genre", + "SearchKeyword": "Search Keyword", + "SearchProvider": "Search Provider", "KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb" }, "Requests": { - "Title": "Solicitações", - "Paragraph": "Abaixo, você pode ver o seu e todos os outros pedidos, bem como o seu download e status de aprovação.", - "MoviesTab": "Filmes", + "Title": "Requests", + "Paragraph": "Below you can see yours and all other requests, as well as their download and approval status.", + "MoviesTab": "Movies", "ArtistName": "Artist", "AlbumName": "Album Name", - "TvTab": "Séries", - "MusicTab": "Músicas", + "TvTab": "TV Shows", + "MusicTab": "Music", "RequestedBy": "Requested By", "Status": "Status", "RequestStatus": "Request status", - "Denied": " Negados:", - "TheatricalRelease": "Lançamento nos Cinemas: {{date}}", - "ReleaseDate": "Lançado: {{date}}", - "TheatricalReleaseSort": "Lançamento nos Cinemas", - "DigitalRelease": "Lançamento Digital: {{date}}", + "Denied": " Denied:", + "TheatricalRelease": "Theatrical Release: {{date}}", + "ReleaseDate": "Released: {{date}}", + "TheatricalReleaseSort": "Theatrical Release", + "DigitalRelease": "Digital Release: {{date}}", "RequestDate": "Request Date", - "QualityOverride": "Substituição de Qualidade:", - "RootFolderOverride": "Substituição da Pasta Raiz:", - "ChangeRootFolder": "Pasta Raiz", - "ChangeQualityProfile": "Perfil de Qualidade", - "MarkUnavailable": "Marcar como Indisponível", - "MarkAvailable": "Marcar como Disponível", - "Remove": "Remover", - "Deny": "Negar", + "QualityOverride": "Quality Override:", + "RootFolderOverride": "Root Folder Override:", + "ChangeRootFolder": "Root Folder", + "ChangeQualityProfile": "Quality Profile", + "MarkUnavailable": "Mark Unavailable", + "MarkUnavailable4K": "Mark Unavailable 4K", + "MarkAvailable": "Mark Available", + "MarkAvailable4K": "Mark Available 4K", + "Remove": "Remove", + "Deny": "Deny", + "Deny4K": "Deny 4K", + "Has4KRequest": "Has 4K Request", "DenyReason": "Deny Reason", "DeniedReason": "Denied Reason", "Season": "Season", - "GridTitle": "Título", - "AirDate": "AirDate", + "GridTitle": "Title", + "AirDate": "Air Date", "GridStatus": "Status", - "ReportIssue": "Relatar Problema", - "Filter": "Filtro", - "Sort": "Ordenar por", - "SeasonNumberHeading": "Temporada: {seasonNumber}", - "SortTitleAsc": "Título ▲", - "SortTitleDesc": "Título ▼", - "SortRequestDateAsc": "Data da Solicitação ▲", - "SortRequestDateDesc": "Data da Solicitação ▼", + "ReportIssue": "Report Issue", + "Filter": "Filter", + "Sort": "Sort", + "SeasonNumberHeading": "Season: {seasonNumber}", + "SortTitleAsc": "Title ▲", + "SortTitleDesc": "Title ▼", + "SortRequestDateAsc": "Request Date ▲", + "SortRequestDateDesc": "Request Date ▼", "SortStatusAsc": "Status ▲", "SortStatusDesc": "Status ▼", "Remaining": { - "Quota": "{{remaining}}/{{total}} solicitações restantes", - "NextDays": "Outra solicitação será adicionada em {{time}} dias", - "NextHours": "Outra solicitação será adicionada em {{time}} horas", - "NextMinutes": "Outra solicitação será adicionada em {{time}} minutos", - "NextMinute": "Outra solicitação será adicionada em {{time}} minuto" + "Quota": "{{remaining}}/{{total}} requests remaining", + "NextDays": "Another request will be added in {{time}} days", + "NextHours": "Another request will be added in {{time}} hours", + "NextMinutes": "Another request will be added in {{time}} minutes", + "NextMinute": "Another request will be added in {{time}} minute" }, "AllRequests": "All Requests", "PendingRequests": "Pending Requests", @@ -193,11 +212,16 @@ "RequestPanel": { "Delete": "Delete Request", "Approve": "Approve Request", + "Deny": "Deny Request", + "Approve4K": "Approve 4K Request", + "Deny4K": "Deny 4K Request", "ChangeAvailability": "Mark Available", "Deleted": "Successfully deleted selected items", - "Approved": "Successfully approved selected items" + "Approved": "Successfully approved selected items", + "Denied": "Successfully denied selected items" }, "SuccessfullyApproved": "Successfully Approved", + "SuccessfullyDeleted": "Request successfully deleted", "NowAvailable": "Request is now available", "NowUnavailable": "Request is now unavailable", "SuccessfullyReprocessed": "Successfully Re-processed the request", @@ -219,27 +243,33 @@ "MovieRequestQuotaExceeded": "You have exceeded your Movie request quota!", "TvRequestQuotaExceeded": "You have exceeded your Episode request quota!", "AlbumRequestQuotaExceeded": "You have exceeded your Album request quota!" - } + }, + "Notify": "Notify", + "RemoveNotification": "Remove Notifications", + "SuccessfulNotify": "You will now be notified for title {{title}}", + "SuccessfulUnNotify": "You will no longer be notified for title {{title}}", + "CouldntNotify": "Couldn't notify title {{title}}" }, "Issues": { - "Title": "Problemas", - "PendingTitle": "Problemas pendentes", - "InProgressTitle": "Problemas em resolução", - "ResolvedTitle": "Problemas Resolvidos", - "ColumnTitle": "Título", + "Title": "Issues", + "IssuesForTitle": "Issues for {{title}}", + "PendingTitle": "Pending Issues", + "InProgressTitle": "In Progress Issues", + "ResolvedTitle": "Resolved Issues", + "ColumnTitle": "Title", "Count": "Count", - "Category": "Categoria", + "Category": "Category", "Status": "Status", - "Details": "Detalhes", - "Description": "Descrição", - "NoComments": "Sem Comentários!", - "MarkInProgress": "Marcar como em andamento", - "MarkResolved": "Marcar como resolvido", - "SendMessageButton": "Enviar", - "Subject": "Assunto", - "Comments": "Comentários", - "WriteMessagePlaceholder": "Escreva sua mensagem aqui...", - "ReportedBy": "Reportado por", + "Details": "Details", + "Description": "Description", + "NoComments": "No Comments!", + "MarkInProgress": "Mark In Progress", + "MarkResolved": "Mark Resolved", + "SendMessageButton": "Send", + "Subject": "Subject", + "Comments": "Comments", + "WriteMessagePlaceholder": "Write your message here...", + "ReportedBy": "Reported By", "IssueDialog": { "Title": "Report an issue", "DescriptionPlaceholder": "Please describe the issue", @@ -255,32 +285,35 @@ "Delete": "Delete issue", "DeletedIssue": "Issue has been deleted", "Chat": "Chat", - "Requested": "Requested", + "EnterYourMessage": "Enter Your Message", + "Requested": "Pedido", "UserOnDate": "{{user}} on {{date}}" }, "Filter": { - "ClearFilter": "Limpar Filtro", - "FilterHeaderAvailability": "Disponibilidade", + "ClearFilter": "Clear Filter", + "FilterHeaderAvailability": "Availability", "FilterHeaderRequestStatus": "Status", - "Approved": "Aprovado", + "Approved": "Approved", "PendingApproval": "Aprovação Pendente", "WatchProviders": "Watch Providers", "Keywords": "Keywords" }, "UserManagment": { - "TvRemaining": "Séries: {{remaining}}/{{total}} restantes", - "MovieRemaining": "Filmes: {{remaining}}/{{total}} restantes", - "MusicRemaining": "Músicas: {{remaining}}/{{total}} restantes", - "TvDue": "Série: {{date}}", - "MovieDue": "Filme: {{date}}", - "MusicDue": "Música: {{date}}" + "TvRemaining": "TV: {{remaining}}/{{total}} remaining", + "MovieRemaining": "Movies: {{remaining}}/{{total}} remaining", + "MusicRemaining": "Music: {{remaining}}/{{total}} remaining", + "TvDue": "TV: {{date}}", + "MovieDue": "Movie: {{date}}", + "MusicDue": "Music: {{date}}" }, "Votes": { - "CompletedVotesTab": "Votado", - "VotesTab": "Votos necessários" + "CompletedVotesTab": "Voted", + "VotesTab": "Votes Needed" }, "MediaDetails": { - "Denied": "Denied", + "Denied": "Recusado", + "Denied4K": "Denied 4K", + "Trailers": "Trailers", "RecommendationsTitle": "Recommendations", "SimilarTitle": "Similar", "VideosTitle": "Videos", @@ -291,9 +324,9 @@ "ViewCollection": "View Collection", "NotEnoughInfo": "Unfortunately there is not enough information about this show yet!", "AdvancedOptions": "Advanced Options", - "AutoApproveOptions": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTv": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be send to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptions": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTv": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be sent to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", "QualityProfilesSelect": "Select A Quality Profile", "RootFolderSelect": "Select A Root Folder", "LanguageProfileSelect": "Select A Language Profile", @@ -312,12 +345,13 @@ "Seasons": "Seasons:", "Episodes": "Episodes:", "Availability": "Availability:", - "RequestStatus": "Request Status", + "RequestStatus": "Request Status:", "Quality": "Quality:", "RootFolderOverride": "Root Folder Override:", "QualityOverride": "Quality Override:", "Network": "Network:", - "Genres": "Genres:", + "GenresLabel": "Genres:", + "Genres": "Genres", "FirstAired": "First Aired:", "TheatricalRelease": "Release:", "DigitalRelease": "Digital Release:", @@ -343,15 +377,18 @@ "PleaseSelectUser": "Please select a user", "StreamingOn": "Streaming On:", "RequestedBy": "Requested By:", + "RequestedByOn": "Requested By {{user}} on {{date}}", "RequestDate": "Request Date:", "DeniedReason": "Denied Reason:", "ReProcessRequest": "Re-Process Request", + "ReProcessRequest4K": "Re-Process 4K Request", "Music": { "Type": "Type:", "Country": "Country:", "StartDate": "Start Date:", "EndDate": "EndDate:" - } + }, + "RequestSource": "Origem:" }, "Discovery": { "PopularTab": "Popular", @@ -382,7 +419,7 @@ "DarkMode": "Dark Mode", "Updated": "Successfully Updated", "StreamingCountry": "Streaming Country", - "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will have US related streaming information.", + "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will get US related streaming information.", "LanguageDescription": "This is the language you would like the Ombi interface to be displayed in.", "MobileQRCode": "Mobile QR Code", "LegacyApp": "Launch Legacy App", @@ -396,7 +433,8 @@ "NewPasswordConfirm": "New Password Confirm", "Security": "Security", "Profile": "Profile", - "UpdatedYourInformation": "Updated your information" + "UpdatedYourInformation": "Updated your information", + "Unsubscribed": "Unsubscribed!" }, "UserTypeLabel": { "1": "Local User", @@ -404,5 +442,14 @@ "3": "Emby User", "4": "Emby Connect User", "5": "Jellyfin User" + }, + "Paginator": { + "itemsPerPageLabel": "Items per page:", + "nextPageLabel": "Next page", + "previousPageLabel": "Previous page", + "firstPageLabel": "First page", + "lastPageLabel": "Last page", + "rangePageLabel1": "0 of {{length}}", + "rangePageLabel2": "{{startIndex}} – {{endIndex}} of {{length}}" } } diff --git a/src/Ombi/wwwroot/translations/ru.json b/src/Ombi/wwwroot/translations/ru.json index 3b0659f2d..fb63fe33c 100644 --- a/src/Ombi/wwwroot/translations/ru.json +++ b/src/Ombi/wwwroot/translations/ru.json @@ -14,18 +14,26 @@ "Common": { "ContinueButton": "Продолжить", "Available": "Доступно", - "Approved": "Approved", + "Available4K": "Available 4K", + "Approved": "Одобрено", + "Approve4K": "Approve 4K", "Pending": "Pending", "PartiallyAvailable": "Частично доступно", "Monitored": "Мониторинг", "NotAvailable": "Недоступно", "ProcessingRequest": "Обработка запроса", + "ProcessingRequest4K": "Processing Request 4K", "PendingApproval": "В ожидании одобрения", + "PendingApproval4K": "Pending Approval 4K", "RequestDenied": "Запрос отклонен", + "RequestDenied4K": "Request Denied 4K", "NotRequested": "Не запрошено", + "NotRequested4K": "Not Requested 4K", "Requested": "Запрошено", - "Search": "Search", + "Requested4K": "Requested 4K", + "Search": "Поиск", "Request": "Запросить", + "Request4K": "Request 4K", "Denied": "Отказано", "Approve": "Одобрить", "PartlyAvailable": "Частично доступно", @@ -55,6 +63,10 @@ "OfflineParagraph": "Медиа-сервер в настоящее время не в сети.", "CheckPageForUpdates": "Проверьте эту страницу для получения последних новостей сайта." }, + "ErrorPages": { + "NotFound": "Page not found", + "SomethingWentWrong": "Something went wrong!" + }, "NavigationBar": { "Discover": "Discover", "Search": "Поиск", @@ -131,6 +143,9 @@ }, "AdvancedSearchInstructions": "Please choose what type of media you are searching for:", "YearOfRelease": "Year of Release", + "SearchGenre": "Search Genre", + "SearchKeyword": "Search Keyword", + "SearchProvider": "Search Provider", "KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb" }, "Requests": { @@ -155,9 +170,13 @@ "ChangeRootFolder": "Корневая папка", "ChangeQualityProfile": "Профиль качества", "MarkUnavailable": "Отметить недоступным", + "MarkUnavailable4K": "Mark Unavailable 4K", "MarkAvailable": "Отметить доступным", + "MarkAvailable4K": "Mark Available 4K", "Remove": "Удалить", "Deny": "Отклонить", + "Deny4K": "Deny 4K", + "Has4KRequest": "Has 4K Request", "DenyReason": "Deny Reason", "DeniedReason": "Denied Reason", "Season": "Сезон", @@ -193,11 +212,16 @@ "RequestPanel": { "Delete": "Delete Request", "Approve": "Approve Request", - "ChangeAvailability": "Mark Available", + "Deny": "Deny Request", + "Approve4K": "Approve 4K Request", + "Deny4K": "Deny 4K Request", + "ChangeAvailability": "Отметить доступным", "Deleted": "Successfully deleted selected items", - "Approved": "Successfully approved selected items" + "Approved": "Successfully approved selected items", + "Denied": "Successfully denied selected items" }, "SuccessfullyApproved": "Successfully Approved", + "SuccessfullyDeleted": "Request successfully deleted", "NowAvailable": "Request is now available", "NowUnavailable": "Request is now unavailable", "SuccessfullyReprocessed": "Successfully Re-processed the request", @@ -205,7 +229,7 @@ "RequestCollection": "Request Collection", "CollectionSuccesfullyAdded": "The collection {{name}} has been successfully added!", "NeedToSelectEpisodes": "You need to select some episodes!", - "RequestAddedSuccessfully": "Request for {{title}} has been added successfully", + "RequestAddedSuccessfully": "Запрос на {{title}} успешно добавлен", "ErrorCodes": { "AlreadyRequested": "This has already been requested", "EpisodesAlreadyRequested": "We already have episodes requested from this series", @@ -219,10 +243,16 @@ "MovieRequestQuotaExceeded": "You have exceeded your Movie request quota!", "TvRequestQuotaExceeded": "You have exceeded your Episode request quota!", "AlbumRequestQuotaExceeded": "You have exceeded your Album request quota!" - } + }, + "Notify": "Notify", + "RemoveNotification": "Remove Notifications", + "SuccessfulNotify": "You will now be notified for title {{title}}", + "SuccessfulUnNotify": "You will no longer be notified for title {{title}}", + "CouldntNotify": "Couldn't notify title {{title}}" }, "Issues": { "Title": "Проблемы", + "IssuesForTitle": "Issues for {{title}}", "PendingTitle": "Проблемы в ожидании", "InProgressTitle": "Проблемы в процессе", "ResolvedTitle": "Решенные проблемы", @@ -255,7 +285,8 @@ "Delete": "Delete issue", "DeletedIssue": "Issue has been deleted", "Chat": "Chat", - "Requested": "Requested", + "EnterYourMessage": "Enter Your Message", + "Requested": "Запрошено", "UserOnDate": "{{user}} on {{date}}" }, "Filter": { @@ -281,6 +312,8 @@ }, "MediaDetails": { "Denied": "Отказано", + "Denied4K": "Denied 4K", + "Trailers": "Trailers", "RecommendationsTitle": "Recommendations", "SimilarTitle": "Похожие", "VideosTitle": "Videos", @@ -291,13 +324,13 @@ "ViewCollection": "View Collection", "NotEnoughInfo": "Unfortunately there is not enough information about this show yet!", "AdvancedOptions": "Advanced Options", - "AutoApproveOptions": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTv": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be send to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptions": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTv": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be sent to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", "QualityProfilesSelect": "Select A Quality Profile", "RootFolderSelect": "Select A Root Folder", "LanguageProfileSelect": "Select A Language Profile", - "Status": "Status:", + "Status": "Статус:", "StatusValues": { "Rumored": "Rumored", "Planned": "Planned", @@ -311,15 +344,16 @@ }, "Seasons": "Seasons:", "Episodes": "Episodes:", - "Availability": "Availability:", - "RequestStatus": "Request Status", + "Availability": "Доступность:", + "RequestStatus": "Request Status:", "Quality": "Quality:", - "RootFolderOverride": "Root Folder Override:", - "QualityOverride": "Quality Override:", + "RootFolderOverride": "Переопределение корневой папки:", + "QualityOverride": "Переопределение качества:", "Network": "Network:", - "Genres": "Genres:", + "GenresLabel": "Genres:", + "Genres": "Genres", "FirstAired": "First Aired:", - "TheatricalRelease": "Release:", + "TheatricalRelease": "Релиз в кинотеатрах:", "DigitalRelease": "Digital Release:", "Votes": "Votes:", "Runtime": "Runtime:", @@ -335,23 +369,26 @@ "FirstSeasonTooltip": "This will only request the First Season for this show", "LatestSeasonTooltip": "This will only request the Latest Season for this show", "NoEpisodes": "There unfortunately is no episode data for this show yet!", - "SeasonNumber": "Season {{number}}" + "SeasonNumber": "Сезон {{number}}" }, "SonarrConfiguration": "Sonarr Configuration", "RadarrConfiguration": "Radarr Configuration", "RequestOnBehalf": "Request on behalf of", "PleaseSelectUser": "Please select a user", "StreamingOn": "Streaming On:", - "RequestedBy": "Requested By:", - "RequestDate": "Request Date:", + "RequestedBy": "Автор запроса:", + "RequestedByOn": "Requested By {{user}} on {{date}}", + "RequestDate": "Дата запроса:", "DeniedReason": "Denied Reason:", "ReProcessRequest": "Re-Process Request", + "ReProcessRequest4K": "Re-Process 4K Request", "Music": { "Type": "Type:", "Country": "Country:", "StartDate": "Start Date:", "EndDate": "EndDate:" - } + }, + "RequestSource": "Source:" }, "Discovery": { "PopularTab": "Популярное", @@ -382,7 +419,7 @@ "DarkMode": "Dark Mode", "Updated": "Successfully Updated", "StreamingCountry": "Streaming Country", - "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will have US related streaming information.", + "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will get US related streaming information.", "LanguageDescription": "This is the language you would like the Ombi interface to be displayed in.", "MobileQRCode": "Mobile QR Code", "LegacyApp": "Launch Legacy App", @@ -391,12 +428,13 @@ "ChangeDetails": "Change Details", "NeedCurrentPassword": "You need your current password to make any changes here", "CurrentPassword": "Current Password", - "EmailAddress": "Email Address", + "EmailAddress": "Адрес эл. почты", "NewPassword": "New Password", "NewPasswordConfirm": "New Password Confirm", "Security": "Security", "Profile": "Profile", - "UpdatedYourInformation": "Updated your information" + "UpdatedYourInformation": "Updated your information", + "Unsubscribed": "Unsubscribed!" }, "UserTypeLabel": { "1": "Local User", @@ -404,5 +442,14 @@ "3": "Emby User", "4": "Emby Connect User", "5": "Jellyfin User" + }, + "Paginator": { + "itemsPerPageLabel": "Items per page:", + "nextPageLabel": "Next page", + "previousPageLabel": "Previous page", + "firstPageLabel": "First page", + "lastPageLabel": "Last page", + "rangePageLabel1": "0 of {{length}}", + "rangePageLabel2": "{{startIndex}} – {{endIndex}} of {{length}}" } } diff --git a/src/Ombi/wwwroot/translations/sk.json b/src/Ombi/wwwroot/translations/sk.json index 774445f95..fcf7e360f 100644 --- a/src/Ombi/wwwroot/translations/sk.json +++ b/src/Ombi/wwwroot/translations/sk.json @@ -14,18 +14,26 @@ "Common": { "ContinueButton": "Pokračovať", "Available": "Dostupné", - "Approved": "Approved", - "Pending": "Pending", + "Available4K": "Available 4K", + "Approved": "Schválené", + "Approve4K": "Approve 4K", + "Pending": "Čakajúce", "PartiallyAvailable": "Čiastočne dostupné", "Monitored": "Sledované", "NotAvailable": "Nie je k dispozícii", "ProcessingRequest": "Spracovávanie požiadavky", + "ProcessingRequest4K": "Processing Request 4K", "PendingApproval": "Čaká na schválenie", + "PendingApproval4K": "Pending Approval 4K", "RequestDenied": "Požiadavka zamietnutá", + "RequestDenied4K": "Request Denied 4K", "NotRequested": "Nepožiadané", + "NotRequested4K": "Not Requested 4K", "Requested": "Požiadané", - "Search": "Search", + "Requested4K": "Requested 4K", + "Search": "Hľadať", "Request": "Požiadať", + "Request4K": "Request 4K", "Denied": "Zamietnuté", "Approve": "Schválené", "PartlyAvailable": "Čiastočne dostupné", @@ -35,10 +43,10 @@ }, "Cancel": "Zrušiť", "Submit": "Odoslať", - "Update": "Update", - "tvShow": "TV Show", - "movie": "Movie", - "album": "Album" + "Update": "Aktualizovať", + "tvShow": "Seriály", + "movie": "Filmy", + "album": "Albumy" }, "PasswordReset": { "EmailAddressPlaceholder": "Emailová adresa", @@ -55,6 +63,10 @@ "OfflineParagraph": "Mediálny server je momentálne offline.", "CheckPageForUpdates": "Prezrite túto stránku pre aktualizácie." }, + "ErrorPages": { + "NotFound": "Stránka sa nenašla", + "SomethingWentWrong": "Something went wrong!" + }, "NavigationBar": { "Discover": "Objaviť", "Search": "Hľadať", @@ -93,15 +105,15 @@ "MoviesTab": "Filmy", "TvTab": "Seriály", "MusicTab": "Hudba", - "AdvancedSearch": "You can fill in any of the below to discover new media. All of the results are sorted by popularity", - "AdvancedSearchHeader": "Advanced Search", + "AdvancedSearch": "Ak chcete objaviť nové médiá, môžete vyplniť ktorýkoľvek z nižšie uvedených údajov. Všetky výsledky sú zoradené podľa obľúbenosti", + "AdvancedSearchHeader": "Rozšírené vyhľadávanie", "Suggestions": "Návrhy", "NoResults": "Ľutujeme, nenašli sme žiadne výsledky!", "DigitalDate": "Online vydanie: {{date}}", "TheatricalRelease": "Kino vydanie: {{date}}", "ViewOnPlex": "Zobraziť na Plex", "ViewOnEmby": "Zobraziť na Emby", - "ViewOnJellyfin": "Play On Jellyfin", + "ViewOnJellyfin": "Prehrať cez Jellyfin", "RequestAdded": "Žiadosť o {{title}} bola úspešne pridaná", "Similar": "Podobné", "Refine": "Filtrovať", @@ -129,9 +141,12 @@ "Season": "Séria {{seasonNumber}}", "SelectAllInSeason": "Vybrať všetko v danej sérii {{seasonNumber}}" }, - "AdvancedSearchInstructions": "Please choose what type of media you are searching for:", - "YearOfRelease": "Year of Release", - "KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb" + "AdvancedSearchInstructions": "Vyberte, aký typ médií hľadáte:", + "YearOfRelease": "Rok vydania", + "SearchGenre": "Hľadať podľa žánru", + "SearchKeyword": "Hľadať kľúčové slovo", + "SearchProvider": "Vyhľadávanie poskytovateľa", + "KeywordSearchingDisclaimer": "Upozorňujeme, že vyhľadávanie podľa kľúčových slov je kvôli nekonzistentným údajom v databáze TheMovieDb veľmi nepresné" }, "Requests": { "Title": "Požiadavky", @@ -155,11 +170,15 @@ "ChangeRootFolder": "Koreňový priečinok", "ChangeQualityProfile": "Profil kvality", "MarkUnavailable": "Označiť nedostupné", + "MarkUnavailable4K": "Mark Unavailable 4K", "MarkAvailable": "Označiť dostupné", + "MarkAvailable4K": "Mark Available 4K", "Remove": "Odstrániť", "Deny": "Odmietnuť", + "Deny4K": "Deny 4K", + "Has4KRequest": "Has 4K Request", "DenyReason": "Odmietnuť dôvod", - "DeniedReason": "Denied Reason", + "DeniedReason": "Odmietnuť dôvod", "Season": "Séria", "GridTitle": "Názov", "AirDate": "Dátum vysielania", @@ -186,48 +205,59 @@ "ProcessingRequests": "Spracovávané požiadavky", "AvailableRequests": "Dostupné požiadavky", "DeniedRequests": "Odmietnuté požiadavky", - "RequestsToDisplay": "Requests to display", + "RequestsToDisplay": "Požiadavky na zobrazenie", "RequestsTitle": "Názov", "Details": "Podrobnosti", "Options": "Možnosti", "RequestPanel": { "Delete": "Odstrániž požiadavku", "Approve": "Schváliť žiadosť", + "Deny": "Deny Request", + "Approve4K": "Approve 4K Request", + "Deny4K": "Deny 4K Request", "ChangeAvailability": "Označiť k dispozícií", - "Deleted": "Successfully deleted selected items", - "Approved": "Successfully approved selected items" + "Deleted": "Úspešne odstránené vybrané položky", + "Approved": "Úspešne schválené vybrané položky", + "Denied": "Successfully denied selected items" }, - "SuccessfullyApproved": "Successfully Approved", - "NowAvailable": "Request is now available", - "NowUnavailable": "Request is now unavailable", - "SuccessfullyReprocessed": "Successfully Re-processed the request", - "DeniedRequest": "Denied Request", - "RequestCollection": "Request Collection", - "CollectionSuccesfullyAdded": "The collection {{name}} has been successfully added!", - "NeedToSelectEpisodes": "You need to select some episodes!", - "RequestAddedSuccessfully": "Request for {{title}} has been added successfully", + "SuccessfullyApproved": "Úspešne schválené", + "SuccessfullyDeleted": "Žiadosť bola úspešne vymazaná", + "NowAvailable": "Žiadosť je teraz k dispozícii", + "NowUnavailable": "Žiadosť je teraz nedostupná", + "SuccessfullyReprocessed": "Úspešné opätovné spracovanie požiadavky", + "DeniedRequest": "Zamietnutá žiadosť", + "RequestCollection": "Zbierka žiadostí", + "CollectionSuccesfullyAdded": "Kolekcia {{name}} bola úspešne pridaná!", + "NeedToSelectEpisodes": "Musíte si vybrať nejaké epizódy!", + "RequestAddedSuccessfully": "Žiadosť o {{title}} bola úspešne pridaná", "ErrorCodes": { - "AlreadyRequested": "This has already been requested", - "EpisodesAlreadyRequested": "We already have episodes requested from this series", - "NoPermissionsOnBehalf": "You do not have the correct permissions to request on behalf of users!", - "NoPermissions": "You do not have the correct permissions!", - "RequestDoesNotExist": "Request does not exist", - "ChildRequestDoesNotExist": "Child Request does not exist", - "NoPermissionsRequestMovie": "You do not have permissions to Request a Movie", - "NoPermissionsRequestTV": "You do not have permissions to Request a TV Show", - "NoPermissionsRequestAlbum": "You do not have permissions to Request an Album", - "MovieRequestQuotaExceeded": "You have exceeded your Movie request quota!", - "TvRequestQuotaExceeded": "You have exceeded your Episode request quota!", - "AlbumRequestQuotaExceeded": "You have exceeded your Album request quota!" - } + "AlreadyRequested": "Táto požiadavka už bola zadaná", + "EpisodesAlreadyRequested": "Už máme požiadavky na epizódy z tejto série", + "NoPermissionsOnBehalf": "Nemáte správne oprávnenie žiadať v mene používateľov!", + "NoPermissions": "Nemáte potrebné oprávnenie!", + "RequestDoesNotExist": "Žiadosť neexistuje", + "ChildRequestDoesNotExist": "Žiadosť neexistuje", + "NoPermissionsRequestMovie": "Nemáte oprávnenia na vyžiadanie filmu", + "NoPermissionsRequestTV": "Nemáte oprávnenia na vyžiadanie TV seriálu", + "NoPermissionsRequestAlbum": "Nemáte oprávnenia na vyžiadanie albumu", + "MovieRequestQuotaExceeded": "Prekročili ste limit požiadaviek na filmy!", + "TvRequestQuotaExceeded": "Prekročili ste limit požiadaviek na epizódy!", + "AlbumRequestQuotaExceeded": "Prekročili ste limit požiadaviek na albumy!" + }, + "Notify": "Notify", + "RemoveNotification": "Remove Notifications", + "SuccessfulNotify": "You will now be notified for title {{title}}", + "SuccessfulUnNotify": "You will no longer be notified for title {{title}}", + "CouldntNotify": "Couldn't notify title {{title}}" }, "Issues": { "Title": "Problémy", + "IssuesForTitle": "Problémy pre {{title}}", "PendingTitle": "Nevyriešené problémy", "InProgressTitle": "Riešené problémy", "ResolvedTitle": "Vyiešené problémy", "ColumnTitle": "Názov", - "Count": "Count", + "Count": "Počet", "Category": "Kategória", "Status": "Stav", "Details": "Podrobnosti", @@ -247,7 +277,7 @@ "SelectCategory": "Vybrať kategóriu", "IssueCreated": "Problém bol nahlásený" }, - "Outstanding": "There are outstanding issues", + "Outstanding": "Existujú nevyriešené problémy", "ResolvedDate": "Dátum vyriešenia", "CreatedDate": "Nastolený", "MarkedAsResolved": "Tento problém bol označený ako vyriešený!", @@ -255,8 +285,9 @@ "Delete": "Odstrániť problém", "DeletedIssue": "Problém bol odstránený", "Chat": "Chat", - "Requested": "Requested", - "UserOnDate": "{{user}} on {{date}}" + "EnterYourMessage": "Zadaj správu", + "Requested": "Požiadané", + "UserOnDate": "{{user}} dňa {{date}}" }, "Filter": { "ClearFilter": "Vymazať filter", @@ -264,8 +295,8 @@ "FilterHeaderRequestStatus": "Stav", "Approved": "Schválené", "PendingApproval": "Čaká na schválenie", - "WatchProviders": "Watch Providers", - "Keywords": "Keywords" + "WatchProviders": "Sledovanie poskytovateľov", + "Keywords": "Kľúčové slová" }, "UserManagment": { "TvRemaining": "Seriál: {{remaining}}/{{total}} zostávajúce", @@ -281,6 +312,8 @@ }, "MediaDetails": { "Denied": "Zamietnuté", + "Denied4K": "Denied 4K", + "Trailers": "Upútavka", "RecommendationsTitle": "Odporúčania", "SimilarTitle": "Podobné", "VideosTitle": "Videá", @@ -291,42 +324,43 @@ "ViewCollection": "Pozrieť zbierku", "NotEnoughInfo": "Bohužiaľ, o tomto seriáli nie je k dispozícií dostatok informácií!", "AdvancedOptions": "Pokročilé možnosti", - "AutoApproveOptions": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTv": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be send to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptions": "Požiadavku môžete nakonfigurovať tu, po jej vyžiadaní sa odošle do aplikácie DVR a bude automaticky schválená! Upozorňujeme, že je to voliteľné, pre preskočenie stačí stlačiť Žiadosť!", + "AutoApproveOptionsTv": "Požiadavku môžete nakonfigurovať tu, po jej vyžiadaní sa odošle do aplikácie DVR a bude automaticky schválená! Ak je žiadosť už v Sonarr, nezmeníme koreňový priečinok ani profil kvality, ak ho už nastavíte! Upozorňujeme, že je to voliteľné, stačí stlačiť Žiadosť na preskočenie!", + "AutoApproveOptionsTvShort": "Požiadavku môžete nakonfigurovať tu, po jej vyžiadaní bude odoslaná do vašej aplikácie DVR! Ak je požiadavka už v Sonarr, nezmeníme koreňový priečinok ani profil kvality, ak ho už nastavíte! Upozorňujeme, že je to voliteľné, stačí stlačiť Žiadosť na preskočenie!", "QualityProfilesSelect": "Výber profilu kvality", "RootFolderSelect": "Výber koreňového priečinka", - "LanguageProfileSelect": "Select A Language Profile", - "Status": "Status:", + "LanguageProfileSelect": "Vyberte jazykový profil", + "Status": "Stav:", "StatusValues": { - "Rumored": "Rumored", - "Planned": "Planned", - "In Production": "In Production", - "Post Production": "Post Production", - "Released": "Released", - "Running": "Running", - "Returning Series": "Returning Series", - "Ended": "Ended", - "Canceled": "Canceled" + "Rumored": "Nepotvrdený", + "Planned": "Plánované", + "In Production": "V produkcii", + "Post Production": "V post-produkcii", + "Released": "Vydané", + "Running": "Premietané", + "Returning Series": "Vracajúca sa séria", + "Ended": "Ukončené", + "Canceled": "Zrušené" }, - "Seasons": "Seasons:", - "Episodes": "Episodes:", - "Availability": "Availability:", - "RequestStatus": "Požiadať stav", - "Quality": "Quality:", - "RootFolderOverride": "Root Folder Override:", - "QualityOverride": "Quality Override:", - "Network": "Network:", - "Genres": "Genres:", - "FirstAired": "First Aired:", - "TheatricalRelease": "Release:", - "DigitalRelease": "Digital Release:", - "Votes": "Votes:", - "Runtime": "Runtime:", + "Seasons": "Séria:", + "Episodes": "Epizódy:", + "Availability": "Dostupnosť:", + "RequestStatus": "Request Status:", + "Quality": "Kvalita:", + "RootFolderOverride": "Prepísanie koreňového priečinku:", + "QualityOverride": "Prepísanie kvality:", + "Network": "Sieť:", + "GenresLabel": "Žánre:", + "Genres": "Žánre", + "FirstAired": "Prvýkrát odvysielané:", + "TheatricalRelease": "Vydané:", + "DigitalRelease": "Digitálne vydanie:", + "Votes": "Hlasované:", + "Runtime": "Dĺžka:", "Minutes": "{{runtime}} minút", - "Revenue": "Revenue:", - "Budget": "Budget:", - "Keywords": "Keywords/Tags:", + "Revenue": "Výnos:", + "Budget": "Rozpočet:", + "Keywords": "Kľúčové slová/Tagy:", "Casts": { "CastTitle": "Obsadenie" }, @@ -334,31 +368,34 @@ "AllSeasonsTooltip": "Požiadať všetky sezóny série.", "FirstSeasonTooltip": "Požiadať iba prvú sezónu série.", "LatestSeasonTooltip": "Požiadať iba poslednú sezónu série", - "NoEpisodes": "There unfortunately is no episode data for this show yet!", - "SeasonNumber": "Season {{number}}" + "NoEpisodes": "Pre tento seriál zatiaľ nie sú k dispozícii žiadne údaje o epizódach!", + "SeasonNumber": "Séria {{number}}" }, - "SonarrConfiguration": "Sonarr Configuration", - "RadarrConfiguration": "Radarr Configuration", - "RequestOnBehalf": "Request on behalf of", - "PleaseSelectUser": "Please select a user", - "StreamingOn": "Streaming On:", - "RequestedBy": "Requested By:", - "RequestDate": "Request Date:", - "DeniedReason": "Denied Reason:", - "ReProcessRequest": "Re-Process Request", + "SonarrConfiguration": "Nastavenie Sonarr", + "RadarrConfiguration": "Nastavenie Radarr", + "RequestOnBehalf": "Požiadavka v mene", + "PleaseSelectUser": "Prosím vyberte uživatela", + "StreamingOn": "Streamovanie cez:", + "RequestedBy": "Vyžiadané od:", + "RequestedByOn": "Vyžiadané od {{user}} dňa {{date}}", + "RequestDate": "Dátum požiadavky:", + "DeniedReason": "Dôvod zamietnutia:", + "ReProcessRequest": "Žiadosť o opätovné spracovanie", + "ReProcessRequest4K": "Re-Process 4K Request", "Music": { - "Type": "Type:", - "Country": "Country:", - "StartDate": "Start Date:", - "EndDate": "EndDate:" - } + "Type": "Typ:", + "Country": "Krajina:", + "StartDate": "Dátum začatia:", + "EndDate": "Dátum ukončenia:" + }, + "RequestSource": "Source:" }, "Discovery": { "PopularTab": "Populárne", "TrendingTab": "Trendy", "UpcomingTab": "Čoskoro", - "SeasonalTab": "Seasonal", - "RecentlyRequestedTab": "Recently Requested", + "SeasonalTab": "Sezónne", + "RecentlyRequestedTab": "Nedávno vyžiadané", "Movies": "Filmy", "Combined": "Kombinované", "Tv": "Seriály", @@ -374,35 +411,45 @@ "Writer": "Autor", "ExecProducer": "Výkonný producent" }, - "NoSearch": "Sorry, nothing matches your search!" + "NoSearch": "Ospravedlňujeme sa, nič sa nezhoduje vášmu vyhľadávaniu!" }, "UserPreferences": { "Welcome": "Vitaj {{username}}!", "OmbiLanguage": "Jazyk", "DarkMode": "Tmavý režim", - "Updated": "Successfully Updated", - "StreamingCountry": "Streaming Country", - "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will have US related streaming information.", - "LanguageDescription": "This is the language you would like the Ombi interface to be displayed in.", - "MobileQRCode": "Mobile QR Code", - "LegacyApp": "Launch Legacy App", - "NoQrCode": "Please contact your administrator to enable QR codes", - "UserType": "User Type:", - "ChangeDetails": "Change Details", - "NeedCurrentPassword": "You need your current password to make any changes here", - "CurrentPassword": "Current Password", - "EmailAddress": "Email Address", - "NewPassword": "New Password", - "NewPasswordConfirm": "New Password Confirm", - "Security": "Security", - "Profile": "Profile", - "UpdatedYourInformation": "Updated your information" + "Updated": "Úspešne aktualizované", + "StreamingCountry": "Krajina streamovania", + "StreamingCountryDescription": "Toto je kód krajiny, pre ktorú budeme zobrazovať informácie o vysielaní. Ak sa nachádzate v USA, vyberte USA a zobrazia sa vám informácie o streamovaní týkajúce sa USA.", + "LanguageDescription": "Toto je jazyk, v ktorom by ste chceli zobrazovať rozhranie Ombi.", + "MobileQRCode": "Mobilný QR kód", + "LegacyApp": "Spustite Legacy App", + "NoQrCode": "Ak chcete povoliť QR kódy, obráťte sa na svojho administratora", + "UserType": "Typ používateľa:", + "ChangeDetails": "Zmeniť podrobnosti", + "NeedCurrentPassword": "Na vykonanie akýchkoľvek zmien tu potrebujete svoje aktuálne heslo", + "CurrentPassword": "Súčasné heslo", + "EmailAddress": "Emailová adresa", + "NewPassword": "Nové heslo", + "NewPasswordConfirm": "Potvrdenie nového hesla", + "Security": "Zabezpečenie", + "Profile": "Profil", + "UpdatedYourInformation": "Aktualizovať informácie", + "Unsubscribed": "Odhlásené z odberu!" }, "UserTypeLabel": { - "1": "Local User", - "2": "Plex User", - "3": "Emby User", - "4": "Emby Connect User", - "5": "Jellyfin User" + "1": "Miestny použivateľ", + "2": "Používateľ Plex", + "3": "Používateľ Emby", + "4": "Používateľ Emby Connect", + "5": "Používateľ Jellyfin" + }, + "Paginator": { + "itemsPerPageLabel": "Položiek na stránku:", + "nextPageLabel": "Ďalšia stránka", + "previousPageLabel": "Predchádzajúca stránka", + "firstPageLabel": "Prvá stránka", + "lastPageLabel": "Posledná stránka", + "rangePageLabel1": "0 z {{length}}", + "rangePageLabel2": "{{startIndex}} – {{endIndex}} z {{length}}" } } diff --git a/src/Ombi/wwwroot/translations/sv.json b/src/Ombi/wwwroot/translations/sv.json index a77e67ee5..4d78fe804 100644 --- a/src/Ombi/wwwroot/translations/sv.json +++ b/src/Ombi/wwwroot/translations/sv.json @@ -14,18 +14,26 @@ "Common": { "ContinueButton": "Fortsätt", "Available": "Tillgänglig", - "Approved": "Approved", + "Available4K": "Tillgänglig 4K", + "Approved": "Godkänd", + "Approve4K": "Godkänn 4K", "Pending": "Pending", "PartiallyAvailable": "Delvis tillgänglig", "Monitored": "Övervakad", "NotAvailable": "Inte tillgänglig", "ProcessingRequest": "Bearbetar förfrågan", + "ProcessingRequest4K": "Processing Request 4K", "PendingApproval": "Väntar på godkännande", + "PendingApproval4K": "Pending Approval 4K", "RequestDenied": "Efterfrågan nekas", + "RequestDenied4K": "Request Denied 4K", "NotRequested": "Inte begärd", + "NotRequested4K": "Not Requested 4K", "Requested": "Begärd", - "Search": "Search", + "Requested4K": "Begärd 4K", + "Search": "Sök", "Request": "Begär", + "Request4K": "Begär 4K", "Denied": "Nekad", "Approve": "Godkänn", "PartlyAvailable": "Delvis tillgänglig", @@ -55,6 +63,10 @@ "OfflineParagraph": "Medieservern är för närvarande offline.", "CheckPageForUpdates": "Håll utkik här för uppdateringar på denna sida." }, + "ErrorPages": { + "NotFound": "Page not found", + "SomethingWentWrong": "Something went wrong!" + }, "NavigationBar": { "Discover": "Upptäck", "Search": "Sök", @@ -101,7 +113,7 @@ "TheatricalRelease": "Biopremiär: {{date}}", "ViewOnPlex": "Visa på Plex", "ViewOnEmby": "Visa på Emby", - "ViewOnJellyfin": "Play On Jellyfin", + "ViewOnJellyfin": "Spela på Jellyfin", "RequestAdded": "Begäran av {{title}} har lagts till", "Similar": "Liknande", "Refine": "Förfina", @@ -131,6 +143,9 @@ }, "AdvancedSearchInstructions": "Please choose what type of media you are searching for:", "YearOfRelease": "Year of Release", + "SearchGenre": "Search Genre", + "SearchKeyword": "Search Keyword", + "SearchProvider": "Search Provider", "KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb" }, "Requests": { @@ -155,9 +170,13 @@ "ChangeRootFolder": "Byt rotmapp", "ChangeQualityProfile": "Byt kvalitétsprofil", "MarkUnavailable": "Markera Otillgänglig", + "MarkUnavailable4K": "Markera som ej tillgänglig 4K", "MarkAvailable": "Markera Tillgänglig", + "MarkAvailable4K": "Markera som tillgänglig 4K", "Remove": "Ta bort", "Deny": "Neka", + "Deny4K": "Neka 4K", + "Has4KRequest": "Har 4K-förfrågan", "DenyReason": "Anledning för nekande", "DeniedReason": "Denied Reason", "Season": "Säsong", @@ -193,11 +212,16 @@ "RequestPanel": { "Delete": "Ta bort förfrågan", "Approve": "Godkänn begäran", + "Deny": "Deny Request", + "Approve4K": "Godkänn 4K-begäran", + "Deny4K": "Deny 4K Request", "ChangeAvailability": "Markera Tillgänglig", "Deleted": "Successfully deleted selected items", - "Approved": "Successfully approved selected items" + "Approved": "Successfully approved selected items", + "Denied": "Successfully denied selected items" }, "SuccessfullyApproved": "Successfully Approved", + "SuccessfullyDeleted": "Request successfully deleted", "NowAvailable": "Request is now available", "NowUnavailable": "Request is now unavailable", "SuccessfullyReprocessed": "Successfully Re-processed the request", @@ -205,7 +229,7 @@ "RequestCollection": "Request Collection", "CollectionSuccesfullyAdded": "The collection {{name}} has been successfully added!", "NeedToSelectEpisodes": "You need to select some episodes!", - "RequestAddedSuccessfully": "Request for {{title}} has been added successfully", + "RequestAddedSuccessfully": "Begäran av {{title}} har lagts till", "ErrorCodes": { "AlreadyRequested": "This has already been requested", "EpisodesAlreadyRequested": "We already have episodes requested from this series", @@ -219,10 +243,16 @@ "MovieRequestQuotaExceeded": "You have exceeded your Movie request quota!", "TvRequestQuotaExceeded": "You have exceeded your Episode request quota!", "AlbumRequestQuotaExceeded": "You have exceeded your Album request quota!" - } + }, + "Notify": "Avisering", + "RemoveNotification": "Ta bort avisering", + "SuccessfulNotify": "Du kommer nu att aviseras för titel {{title}}", + "SuccessfulUnNotify": "Du kommer inte längre att aviseras för titel {{title}}", + "CouldntNotify": "Kunde inte avisera för {{title}}" }, "Issues": { "Title": "Problem", + "IssuesForTitle": "Issues for {{title}}", "PendingTitle": "Väntande problem", "InProgressTitle": "Pågående problem", "ResolvedTitle": "Lösta problem", @@ -255,7 +285,8 @@ "Delete": "Ta bort problem", "DeletedIssue": "Problemet har tagits bort", "Chat": "Chat", - "Requested": "Requested", + "EnterYourMessage": "Enter Your Message", + "Requested": "Begärd", "UserOnDate": "{{user}} on {{date}}" }, "Filter": { @@ -281,6 +312,8 @@ }, "MediaDetails": { "Denied": "Nekad", + "Denied4K": "Nekad 4K", + "Trailers": "Trailers", "RecommendationsTitle": "Rekommendationer", "SimilarTitle": "Liknande", "VideosTitle": "Videor", @@ -291,9 +324,9 @@ "ViewCollection": "Visa samling", "NotEnoughInfo": "Tyvärr finns det inte tillräckligt med information om denna serie ännu!", "AdvancedOptions": "Avancerade inställningar", - "AutoApproveOptions": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTv": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be send to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptions": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTv": "You can configure the request here, once requested it will be sent to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", + "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be sent to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", "QualityProfilesSelect": "Välj en kvalitetsprofil", "RootFolderSelect": "Välj en rotmapp", "LanguageProfileSelect": "Select A Language Profile", @@ -311,22 +344,23 @@ }, "Seasons": "Seasons:", "Episodes": "Episodes:", - "Availability": "Availability:", - "RequestStatus": "Status för begäran", - "Quality": "Quality:", - "RootFolderOverride": "Root Folder Override:", - "QualityOverride": "Quality Override:", - "Network": "Network:", - "Genres": "Genres:", - "FirstAired": "First Aired:", - "TheatricalRelease": "Release:", - "DigitalRelease": "Digital Release:", - "Votes": "Votes:", - "Runtime": "Runtime:", + "Availability": "Tillgänglighet:", + "RequestStatus": "Request Status:", + "Quality": "Kvalitet:", + "RootFolderOverride": "Rotmappsöverskridande:", + "QualityOverride": "Kvalitétsöverskridande:", + "Network": "Tv-nätverk:", + "GenresLabel": "Genrer:", + "Genres": "Genrer", + "FirstAired": "Sändes första gången:", + "TheatricalRelease": "Biopremiär:", + "DigitalRelease": "Digital release:", + "Votes": "Röster:", + "Runtime": "Speltid:", "Minutes": "{{runtime}} minuter", - "Revenue": "Revenue:", + "Revenue": "Intäkter:", "Budget": "Budget:", - "Keywords": "Keywords/Tags:", + "Keywords": "Nyckelord/Taggar:", "Casts": { "CastTitle": "Rollista" }, @@ -335,23 +369,26 @@ "FirstSeasonTooltip": "Detta kommer endast att begära den första säsongen för denna serie", "LatestSeasonTooltip": "Detta kommer endast att begära den senaste säsongen för denna serie", "NoEpisodes": "There unfortunately is no episode data for this show yet!", - "SeasonNumber": "Season {{number}}" + "SeasonNumber": "Säsong {{number}}" }, - "SonarrConfiguration": "Sonarr Configuration", - "RadarrConfiguration": "Radarr Configuration", - "RequestOnBehalf": "Request on behalf of", - "PleaseSelectUser": "Please select a user", - "StreamingOn": "Streaming On:", - "RequestedBy": "Requested By:", - "RequestDate": "Request Date:", + "SonarrConfiguration": "Sonarr Konfiguration", + "RadarrConfiguration": "Radarr Konfiguration", + "RequestOnBehalf": "På begäran av", + "PleaseSelectUser": "Vänligen välj en användare", + "StreamingOn": "Strömmar på:", + "RequestedBy": "Efterfrågats av:", + "RequestedByOn": "Requested By {{user}} on {{date}}", + "RequestDate": "Datum för begäran:", "DeniedReason": "Denied Reason:", "ReProcessRequest": "Re-Process Request", + "ReProcessRequest4K": "Omarbeta 4K-förfrågan", "Music": { "Type": "Type:", "Country": "Country:", "StartDate": "Start Date:", "EndDate": "EndDate:" - } + }, + "RequestSource": "Källa:" }, "Discovery": { "PopularTab": "Populära", @@ -374,15 +411,15 @@ "Writer": "Författare", "ExecProducer": "Exekutiv producent" }, - "NoSearch": "Sorry, nothing matches your search!" + "NoSearch": "Tyvärr, inget matchar din sökning!" }, "UserPreferences": { "Welcome": "Välkommen {{username}}!", "OmbiLanguage": "Språk", "DarkMode": "Mörkt läge", - "Updated": "Successfully Updated", + "Updated": "Uppdatering lyckades", "StreamingCountry": "Streaming Country", - "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will have US related streaming information.", + "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will get US related streaming information.", "LanguageDescription": "This is the language you would like the Ombi interface to be displayed in.", "MobileQRCode": "Mobile QR Code", "LegacyApp": "Launch Legacy App", @@ -391,12 +428,13 @@ "ChangeDetails": "Change Details", "NeedCurrentPassword": "You need your current password to make any changes here", "CurrentPassword": "Current Password", - "EmailAddress": "Email Address", + "EmailAddress": "E-postadress", "NewPassword": "New Password", "NewPasswordConfirm": "New Password Confirm", "Security": "Security", "Profile": "Profile", - "UpdatedYourInformation": "Updated your information" + "UpdatedYourInformation": "Updated your information", + "Unsubscribed": "Unsubscribed!" }, "UserTypeLabel": { "1": "Local User", @@ -404,5 +442,14 @@ "3": "Emby User", "4": "Emby Connect User", "5": "Jellyfin User" + }, + "Paginator": { + "itemsPerPageLabel": "Items per page:", + "nextPageLabel": "Next page", + "previousPageLabel": "Previous page", + "firstPageLabel": "First page", + "lastPageLabel": "Last page", + "rangePageLabel1": "0 of {{length}}", + "rangePageLabel2": "{{startIndex}} – {{endIndex}} of {{length}}" } } diff --git a/src/Ombi/wwwroot/translations/zh-TW.json b/src/Ombi/wwwroot/translations/zh-TW.json new file mode 100644 index 000000000..70f203e6f --- /dev/null +++ b/src/Ombi/wwwroot/translations/zh-TW.json @@ -0,0 +1,455 @@ +{ + "Login": { + "SignInButton": "登录", + "UsernamePlaceholder": "用户名", + "PasswordPlaceholder": "密码", + "RememberMe": "记住我", + "SignInWith": "使用 {{appName}} 登录", + "SignInWithPlex": "使用 Plex 登录", + "ForgottenPassword": "忘记密码?", + "Errors": { + "IncorrectCredentials": "用户名或密码错误" + } + }, + "Common": { + "ContinueButton": "继续", + "Available": "可播放", + "Available4K": "Available 4K", + "Approved": "已批准", + "Approve4K": "Approve 4K", + "Pending": "待审核", + "PartiallyAvailable": "部分可播放", + "Monitored": "监控中", + "NotAvailable": "不可播放", + "ProcessingRequest": "处理中请求", + "ProcessingRequest4K": "Processing Request 4K", + "PendingApproval": "等待批准", + "PendingApproval4K": "Pending Approval 4K", + "RequestDenied": "请求被拒绝", + "RequestDenied4K": "Request Denied 4K", + "NotRequested": "未请求", + "NotRequested4K": "Not Requested 4K", + "Requested": "已请求", + "Requested4K": "Requested 4K", + "Search": "搜索", + "Request": "请求", + "Request4K": "Request 4K", + "Denied": "已拒绝", + "Approve": "批准", + "PartlyAvailable": "部分可播放", + "ViewDetails": "查看详情", + "Errors": { + "Validation": "请检查您输入的值" + }, + "Cancel": "取消", + "Submit": "提交", + "Update": "更新", + "tvShow": "电视节目", + "movie": "电影", + "album": "专辑" + }, + "PasswordReset": { + "EmailAddressPlaceholder": "邮箱", + "ResetPasswordButton": "重置密码" + }, + "LandingPage": { + "OnlineHeading": "当前在线", + "OnlineParagraph": "媒体服务器当前在线", + "PartiallyOnlineHeading": "部分在线", + "PartiallyOnlineParagraph": "媒体服务器部分在线", + "MultipleServersUnavailable": "{{totalServers}} 个服务器中有{{serversUnavailable}} 个已离线", + "SingleServerUnavailable": "{{totalServers}} 个服务器中有{{serversUnavailable}} 个已离线", + "OfflineHeading": "当前离线", + "OfflineParagraph": "媒体服务器当前离线", + "CheckPageForUpdates": "检查此页面以获取站点连续更新。" + }, + "ErrorPages": { + "NotFound": "找不到页面", + "SomethingWentWrong": "Something went wrong!" + }, + "NavigationBar": { + "Discover": "发现", + "Search": "搜索", + "Requests": "请求", + "UserManagement": "用户", + "Issues": "问题", + "Vote": "投票", + "Donate": "捐助", + "DonateLibraryMaintainer": "捐赠给维护者", + "DonateTooltip": "这是我说服我妻子让我继续利用业余时间开发Ombi的途径 😁", + "UpdateAvailableTooltip": "有可用更新!", + "Settings": "设置", + "Welcome": "{{username}},欢迎您", + "UpdateDetails": "更新详请", + "Logout": "登出", + "OpenMobileApp": "打开移动应用", + "RecentlyAdded": "最近添加", + "ChangeTheme": "更改主题", + "Calendar": "日历", + "UserPreferences": "偏好设置", + "FeatureSuggestion": "功能", + "FeatureSuggestionTooltip": "有一个很棒的新想法吗?在这里建议!", + "Filter": { + "Movies": "电影", + "TvShows": "电视节目", + "Music": "音乐", + "People": "人员" + }, + "MorningWelcome": "早上好!", + "AfternoonWelcome": "下午好!", + "EveningWelcome": "晚上好!" + }, + "Search": { + "Title": "搜索", + "Paragraph": "想要观看当前无法观看的内容吗?没问题,只需在下方搜索并请求!", + "MoviesTab": "电影", + "TvTab": "电视节目", + "MusicTab": "音乐", + "AdvancedSearch": "您可以填写以下任何一项来发现新媒体,所有结果都按受欢迎程度排序。", + "AdvancedSearchHeader": "高级搜索", + "Suggestions": "建议", + "NoResults": "对不起,我们没有找到任何结果。", + "DigitalDate": "数字版发行:{{date}}", + "TheatricalRelease": "剧场版发行:{{date}}", + "ViewOnPlex": "在Plex上播放", + "ViewOnEmby": "在 Emby上播放", + "ViewOnJellyfin": "在 Jellyfin上播放", + "RequestAdded": "{{title}} 的请求已成功添加", + "Similar": "相似", + "Refine": "精选", + "SearchBarPlaceholder": "在这里输入搜索内容", + "Movies": { + "PopularMovies": "热门电影", + "UpcomingMovies": "即将上映的电影", + "TopRatedMovies": "高评分的电影", + "NowPlayingMovies": "正在播放的电影", + "HomePage": "主页", + "Trailer": "预告片" + }, + "TvShows": { + "Popular": "热门", + "Trending": "趋势", + "MostWatched": "观看次数最多", + "MostAnticipated": "最期待", + "Results": "结果", + "AirDate": "播出日期:", + "AllSeasons": "所有季", + "FirstSeason": "第一季", + "LatestSeason": "最新季", + "Select": "请选择...", + "SubmitRequest": "提交请求", + "Season": "第{{seasonNumber}} 季", + "SelectAllInSeason": "在所有季中选择第{{seasonNumber}} 季" + }, + "AdvancedSearchInstructions": "请选择您需要搜索的媒体类型:", + "YearOfRelease": "发行年份", + "SearchGenre": "按类型搜索", + "SearchKeyword": "按关键字搜索", + "SearchProvider": "按提供者搜索", + "KeywordSearchingDisclaimer": "请注意,由于TheMovieDb中的数据不一致,关键字搜索方式非常容易出错" + }, + "Requests": { + "Title": "请求", + "Paragraph": "您可以在下方看到您的和所有其他人的请求,以及他们的下载和批准状态", + "MoviesTab": "电影", + "ArtistName": "艺术家", + "AlbumName": "专辑名称", + "TvTab": "电视节目", + "MusicTab": "音乐", + "RequestedBy": "请求者", + "Status": "发行状态", + "RequestStatus": "申请状态", + "Denied": "已拒绝:", + "TheatricalRelease": "剧场版发行:{{date}}", + "ReleaseDate": "已发行: {{date}}", + "TheatricalReleaseSort": "剧场版发行", + "DigitalRelease": "数字版发行:{{date}}", + "RequestDate": "请求日期", + "QualityOverride": "质量覆盖:", + "RootFolderOverride": "根目录覆盖:", + "ChangeRootFolder": "根目录", + "ChangeQualityProfile": "画质配置文件", + "MarkUnavailable": "标记为不可用", + "MarkUnavailable4K": "Mark Unavailable 4K", + "MarkAvailable": "标记为可用", + "MarkAvailable4K": "Mark Available 4K", + "Remove": "删除", + "Deny": "拒绝", + "Deny4K": "Deny 4K", + "Has4KRequest": "Has 4K Request", + "DenyReason": "拒绝原因", + "DeniedReason": "被拒绝原因", + "Season": "季", + "GridTitle": "标题", + "AirDate": "播出日期:", + "GridStatus": "状态", + "ReportIssue": "反馈问题", + "Filter": "筛选", + "Sort": "排序", + "SeasonNumberHeading": "第{seasonNumber} 季", + "SortTitleAsc": "标题 ▲", + "SortTitleDesc": "标题 ▼", + "SortRequestDateAsc": "请求日期 ▲", + "SortRequestDateDesc": "请求日期 ▼", + "SortStatusAsc": "状态 ▲", + "SortStatusDesc": "状态 ▼", + "Remaining": { + "Quota": "{{remaining}}/{{total}} 个请求剩余", + "NextDays": "将在{{time}} 天内添加另一个请求", + "NextHours": "将在{{time}} 小时后添加另一个请求", + "NextMinutes": "将在{{time}} 分钟内添加另一个请求", + "NextMinute": "将在{{time}} 分钟内添加另一个请求" + }, + "AllRequests": "所有请求", + "PendingRequests": "待处理请求", + "ProcessingRequests": "处理中请求", + "AvailableRequests": "可用请求", + "DeniedRequests": "已拒绝请求", + "RequestsToDisplay": "显示请求", + "RequestsTitle": "标题", + "Details": "详情", + "Options": "选项", + "RequestPanel": { + "Delete": "删除请求", + "Approve": "批准请求", + "Deny": "Deny Request", + "Approve4K": "Approve 4K Request", + "Deny4K": "Deny 4K Request", + "ChangeAvailability": "标记为可用", + "Deleted": "所选项目已删除", + "Approved": "所选项目已批准", + "Denied": "Successfully denied selected items" + }, + "SuccessfullyApproved": "批准成功", + "SuccessfullyDeleted": "删除请求成功", + "NowAvailable": "请求现在可观看", + "NowUnavailable": "请求现在不可观看", + "SuccessfullyReprocessed": "重新处理请求成功", + "DeniedRequest": "已拒绝请求", + "RequestCollection": "请求合集", + "CollectionSuccesfullyAdded": "合集 {{name}} 已成功添加!", + "NeedToSelectEpisodes": "您需要选择集数!", + "RequestAddedSuccessfully": "{{title}} 的请求已成功添加", + "ErrorCodes": { + "AlreadyRequested": "请求已经存在", + "EpisodesAlreadyRequested": "已存在这个系列的剧集请求", + "NoPermissionsOnBehalf": "您没有代表用户请求的正确权限!", + "NoPermissions": "您没有正确的权限!", + "RequestDoesNotExist": "请求不存在", + "ChildRequestDoesNotExist": "子请求不存在", + "NoPermissionsRequestMovie": "您没有请求电影的权限", + "NoPermissionsRequestTV": "您没有请求电视节目的权限", + "NoPermissionsRequestAlbum": "您没有请求专辑的权限", + "MovieRequestQuotaExceeded": "您的电影请求已超出配额!", + "TvRequestQuotaExceeded": "您的剧集请求已超出配额!", + "AlbumRequestQuotaExceeded": "您的专辑请求已超出配额!" + }, + "Notify": "通知", + "RemoveNotification": "删除通知", + "SuccessfulNotify": "您将收到标题为 {{title}} 的通知", + "SuccessfulUnNotify": "您将不再收到标题为 {{title}} 的通知", + "CouldntNotify": "无法通知标题 {{title}}" + }, + "Issues": { + "Title": "问题", + "IssuesForTitle": "{{title}} 的问题", + "PendingTitle": "待处理的问题", + "InProgressTitle": "正在处理的问题", + "ResolvedTitle": "已解决的问题", + "ColumnTitle": "标题", + "Count": "总计", + "Category": "类别", + "Status": "状态", + "Details": "详情", + "Description": "描述", + "NoComments": "暂无评论", + "MarkInProgress": "标记为进行中", + "MarkResolved": "标记为已解决", + "SendMessageButton": "发送", + "Subject": "主题", + "Comments": "评论", + "WriteMessagePlaceholder": "在这里写下您的留言", + "ReportedBy": "报告人", + "IssueDialog": { + "Title": "反馈问题", + "DescriptionPlaceholder": "请描述您的问题", + "TitlePlaceholder": "简短标题", + "SelectCategory": "选择分类", + "IssueCreated": "问题已创建" + }, + "Outstanding": "未解决的问题", + "ResolvedDate": "解决日期", + "CreatedDate": "提出日期", + "MarkedAsResolved": "此问题已被标记为已解决!", + "MarkedAsInProgress": "此问题已被标记为正在处理中!", + "Delete": "删除问题", + "DeletedIssue": "问题已被删除", + "Chat": "聊天", + "EnterYourMessage": "输入您的消息", + "Requested": "已请求", + "UserOnDate": "{{user}} 在 {{date}}" + }, + "Filter": { + "ClearFilter": "清除筛选", + "FilterHeaderAvailability": "可用性", + "FilterHeaderRequestStatus": "状态", + "Approved": "已批准", + "PendingApproval": "待批准", + "WatchProviders": "观看提供商", + "Keywords": "关键字" + }, + "UserManagment": { + "TvRemaining": "电视节目:{{remaining}}/{{total}} 剩余", + "MovieRemaining": "电影: {{remaining}}/{{total}} 剩余", + "MusicRemaining": "音乐: {{remaining}}/{{total}} 剩余", + "TvDue": "电视节目:{{date}}", + "MovieDue": "电影: {{date}}", + "MusicDue": "音乐: {{date}}" + }, + "Votes": { + "CompletedVotesTab": "已投票", + "VotesTab": "需要投票" + }, + "MediaDetails": { + "Denied": "已拒绝", + "Denied4K": "Denied 4K", + "Trailers": "预告片", + "RecommendationsTitle": "推荐", + "SimilarTitle": "相似", + "VideosTitle": "视频", + "AlbumsTitle": "专辑", + "RequestAllAlbums": "请求所有专辑", + "ClearSelection": "清除已选择", + "RequestSelectedAlbums": "请求选中的专辑", + "ViewCollection": "查看合集", + "NotEnoughInfo": "很遗憾,这个节目还没有足够的信息!", + "AdvancedOptions": "高级选项", + "AutoApproveOptions": "您可以在这里配置请求,一旦请求它将被发送到您的DVR应用程序并将被自动批准! 请注意,这是可选的,只需按请求跳过!", + "AutoApproveOptionsTv": "您可以在这里配置请求,一旦请求它将被发送到您的DVR应用程序并将被自动批准! 如果请求已经在 Sonarr 中并且您设置了它,我们将不会更改根目录或画质配置文件! 请注意,这是可选的,只需按请求跳过!", + "AutoApproveOptionsTvShort": "您可以在这里配置请求,一旦请求它将被发送到您的DVR应用程序! 如果请求已经在 Sonarr 中并且您设置了它,我们将不会更改根目录或画质配置文件! 请注意,这是可选的,只需按请求跳过!", + "QualityProfilesSelect": "请选择画质配置文件", + "RootFolderSelect": "请选择根目录", + "LanguageProfileSelect": "请选择语言配置文件", + "Status": "状态:", + "StatusValues": { + "Rumored": "有想法", + "Planned": "计划中", + "In Production": "制作中", + "Post Production": "后期处理", + "Released": "已发布", + "Running": "运行中", + "Returning Series": "回归系列", + "Ended": "已结束", + "Canceled": "已取消" + }, + "Seasons": "季:", + "Episodes": "集:", + "Availability": "可用性:", + "RequestStatus": "Request Status:", + "Quality": "画质:", + "RootFolderOverride": "根目录覆盖:", + "QualityOverride": "质量覆盖:", + "Network": "网络:", + "GenresLabel": "流派", + "Genres": "流派", + "FirstAired": "首播", + "TheatricalRelease": "发行日:", + "DigitalRelease": "数字版发行:", + "Votes": "投票:", + "Runtime": "运行时间:", + "Minutes": "{{runtime}} 分钟", + "Revenue": "收入:", + "Budget": "预算:", + "Keywords": "关键词/标签:", + "Casts": { + "CastTitle": "演员" + }, + "EpisodeSelector": { + "AllSeasonsTooltip": "请求这个节目的每一季", + "FirstSeasonTooltip": "请求这个节目的第一季", + "LatestSeasonTooltip": "只请求这个节目的最新季", + "NoEpisodes": "很遗憾,目前还没有该节目的剧集数据!", + "SeasonNumber": "第{{number}} 季" + }, + "SonarrConfiguration": "Sonarr 配置", + "RadarrConfiguration": "Radarr 配置", + "RequestOnBehalf": "代表请求", + "PleaseSelectUser": "请选择用户", + "StreamingOn": "流媒体:", + "RequestedBy": "请求者:", + "RequestedByOn": "由 {{user}} 在 {{date}} 时请求", + "RequestDate": "请求日期:", + "DeniedReason": "被拒绝原因:", + "ReProcessRequest": "重新处理请求", + "ReProcessRequest4K": "Re-Process 4K Request", + "Music": { + "Type": "类型:", + "Country": "国家:", + "StartDate": "开始日期:", + "EndDate": "结束日期:" + }, + "RequestSource": "Source:" + }, + "Discovery": { + "PopularTab": "热门", + "TrendingTab": "趋势", + "UpcomingTab": "即将上映", + "SeasonalTab": "按季的", + "RecentlyRequestedTab": "最近请求", + "Movies": "电影", + "Combined": "混合", + "Tv": "电视节目", + "CardDetails": { + "Availability": "可用性", + "Studio": "工作室", + "Network": "网络", + "UnknownNetwork": "未知", + "RequestStatus": "请求状态", + "Director": "导演", + "InCinemas": "影院放映", + "FirstAired": "首播", + "Writer": "编剧", + "ExecProducer": "制作发行商" + }, + "NoSearch": "抱歉,没有符合您搜索条件的内容!" + }, + "UserPreferences": { + "Welcome": "{{username}},欢迎您!", + "OmbiLanguage": "语言", + "DarkMode": "深色模式", + "Updated": "更新成功", + "StreamingCountry": "流媒体国家", + "StreamingCountryDescription": "这是我们将显示流媒体信息的国家代码。 如果您在美国,请选择美国并获取美国相关的流媒体信息。", + "LanguageDescription": "您希望Ombi界面显示的语言", + "MobileQRCode": "手机二维码", + "LegacyApp": "启动旧版应用程序", + "NoQrCode": "请联系管理员以启用二维码", + "UserType": "用户类型:", + "ChangeDetails": "变更详情", + "NeedCurrentPassword": "您需要输入当前密码才能进行更改", + "CurrentPassword": "当前密码", + "EmailAddress": "邮箱地址", + "NewPassword": "新密码", + "NewPasswordConfirm": "确认新密码", + "Security": "安全选项", + "Profile": "用户信息", + "UpdatedYourInformation": "您的用户信息已更新", + "Unsubscribed": "取消订阅!" + }, + "UserTypeLabel": { + "1": "本地用户", + "2": "Plex用户", + "3": "Emby用户", + "4": "Emby Connect用户", + "5": "Jellyfin用户" + }, + "Paginator": { + "itemsPerPageLabel": "每页显示项目数:", + "nextPageLabel": "下一页", + "previousPageLabel": "上一页", + "firstPageLabel": "转到第一页", + "lastPageLabel": "转到最后一页", + "rangePageLabel1": "{{length}} 中的第0项", + "rangePageLabel2": "{{length}} 中的第{{startIndex}} 到{{endIndex}} 项" + } +} diff --git a/src/Ombi/wwwroot/translations/zh.json b/src/Ombi/wwwroot/translations/zh.json index 8e173c559..1eb81db48 100644 --- a/src/Ombi/wwwroot/translations/zh.json +++ b/src/Ombi/wwwroot/translations/zh.json @@ -1,408 +1,455 @@ { "Login": { - "SignInButton": "登入", - "UsernamePlaceholder": "帳戶名稱", - "PasswordPlaceholder": "密碼", - "RememberMe": "記住我", - "SignInWith": "Sign in with {{appName}}", - "SignInWithPlex": "Sign in with Plex", - "ForgottenPassword": "忘記密碼了嗎?", + "SignInButton": "登录", + "UsernamePlaceholder": "用户名", + "PasswordPlaceholder": "密码", + "RememberMe": "记住我", + "SignInWith": "使用 {{appName}} 登录", + "SignInWithPlex": "使用 Plex 登录", + "ForgottenPassword": "忘记密码?", "Errors": { - "IncorrectCredentials": "用戶名或密碼錯誤" + "IncorrectCredentials": "用户名或密码错误" } }, "Common": { - "ContinueButton": "繼續", - "Available": "已收錄", - "Approved": "Approved", - "Pending": "Pending", - "PartiallyAvailable": "部分已收錄", - "Monitored": "監控中", - "NotAvailable": "未收錄", - "ProcessingRequest": "處理請求", + "ContinueButton": "继续", + "Available": "可播放", + "Available4K": "4K可播放", + "Approved": "已批准", + "Approve4K": "批准4K", + "Pending": "待审核", + "PartiallyAvailable": "部分可播放", + "Monitored": "监控中", + "NotAvailable": "不可播放", + "ProcessingRequest": "处理中请求", + "ProcessingRequest4K": "Processing Request 4K", "PendingApproval": "等待批准", - "RequestDenied": "請求被拒絕", - "NotRequested": "未申請", - "Requested": "已申請", - "Search": "Search", - "Request": "請求內容", - "Denied": "拒絕", - "Approve": "確認", - "PartlyAvailable": "部分已收錄", - "ViewDetails": "View Details", + "PendingApproval4K": "Pending Approval 4K", + "RequestDenied": "请求被拒绝", + "RequestDenied4K": "Request Denied 4K", + "NotRequested": "未请求", + "NotRequested4K": "Not Requested 4K", + "Requested": "已请求", + "Requested4K": "请求4K", + "Search": "搜索", + "Request": "请求", + "Request4K": "请求4K", + "Denied": "已拒绝", + "Approve": "批准", + "PartlyAvailable": "部分可播放", + "ViewDetails": "查看详情", "Errors": { - "Validation": "請檢查您輸入的數值" + "Validation": "请检查您输入的值" }, - "Cancel": "Cancel", - "Submit": "Submit", - "Update": "Update", - "tvShow": "TV Show", - "movie": "Movie", - "album": "Album" + "Cancel": "取消", + "Submit": "提交", + "Update": "更新", + "tvShow": "电视节目", + "movie": "电影", + "album": "专辑" }, "PasswordReset": { - "EmailAddressPlaceholder": "電郵地址", - "ResetPasswordButton": "重設密碼" + "EmailAddressPlaceholder": "邮箱", + "ResetPasswordButton": "重置密码" }, "LandingPage": { - "OnlineHeading": "上線中", - "OnlineParagraph": "服務器當前離線。", - "PartiallyOnlineHeading": "部分上線", - "PartiallyOnlineParagraph": "媒體服務器部分在綫。", - "MultipleServersUnavailable": "{{totalServers}} 中有{{serversUnavailable}} 個服務器離綫。", - "SingleServerUnavailable": "在{{totalServers}} 服务器中,有{{serversUnavailable}} 服務器離綫。", - "OfflineHeading": "離線中", - "OfflineParagraph": "服務器當前離線。", - "CheckPageForUpdates": "檢查此頁面以獲取持續的站點更新。" + "OnlineHeading": "当前在线", + "OnlineParagraph": "媒体服务器当前在线", + "PartiallyOnlineHeading": "部分在线", + "PartiallyOnlineParagraph": "媒体服务器部分在线", + "MultipleServersUnavailable": "{{totalServers}} 个服务器中有{{serversUnavailable}} 个已离线", + "SingleServerUnavailable": "{{totalServers}} 个服务器中有{{serversUnavailable}} 个已离线", + "OfflineHeading": "当前离线", + "OfflineParagraph": "媒体服务器当前离线", + "CheckPageForUpdates": "检查此页面以获取站点连续更新。" + }, + "ErrorPages": { + "NotFound": "找不到页面", + "SomethingWentWrong": "出了些问题" }, "NavigationBar": { - "Discover": "Discover", + "Discover": "发现", "Search": "搜索", - "Requests": "請求", - "UserManagement": "Users", - "Issues": "問題", + "Requests": "请求", + "UserManagement": "用户", + "Issues": "问题", "Vote": "投票", - "Donate": "贊助", - "DonateLibraryMaintainer": "捐贈給維護者", - "DonateTooltip": "This is how I convince my wife to let me spend my spare time developing Ombi 😁", - "UpdateAvailableTooltip": "有可用的更新", - "Settings": "設定", - "Welcome": "歡迎您 {{username}}", - "UpdateDetails": "更新詳細資料", + "Donate": "捐助", + "DonateLibraryMaintainer": "捐赠给维护者", + "DonateTooltip": "这是我说服我妻子让我继续利用业余时间开发Ombi的途径 😁", + "UpdateAvailableTooltip": "有可用更新!", + "Settings": "设置", + "Welcome": "{{username}},欢迎您", + "UpdateDetails": "更新详请", "Logout": "登出", - "OpenMobileApp": "打開手機應用程序", - "RecentlyAdded": "最近新增", - "ChangeTheme": "Change Theme", - "Calendar": "Calendar", - "UserPreferences": "Preferences", - "FeatureSuggestion": "Features", - "FeatureSuggestionTooltip": "Have a great new idea? Suggest it here!", + "OpenMobileApp": "打开移动应用", + "RecentlyAdded": "最近添加", + "ChangeTheme": "更改主题", + "Calendar": "日历", + "UserPreferences": "偏好设置", + "FeatureSuggestion": "功能", + "FeatureSuggestionTooltip": "有一个很棒的新想法吗?在这里建议!", "Filter": { - "Movies": "Movies", - "TvShows": "TV Shows", - "Music": "Music", - "People": "People" + "Movies": "电影", + "TvShows": "电视节目", + "Music": "音乐", + "People": "人员" }, - "MorningWelcome": "Good morning!", - "AfternoonWelcome": "Good afternoon!", - "EveningWelcome": "Good evening!" + "MorningWelcome": "早上好!", + "AfternoonWelcome": "下午好!", + "EveningWelcome": "晚上好!" }, "Search": { "Title": "搜索", - "Paragraph": "想觀看目前無法觀看的內容嗎?沒問題,只需在下面搜索並請求它!", - "MoviesTab": "電影", - "TvTab": "電視節目", - "MusicTab": "音樂", - "AdvancedSearch": "You can fill in any of the below to discover new media. All of the results are sorted by popularity", - "AdvancedSearchHeader": "Advanced Search", - "Suggestions": "建議", - "NoResults": "抱歉,我們沒有找到任何結果!", - "DigitalDate": "數字發行:{{date}}", - "TheatricalRelease": "劇場版:{{date}}", - "ViewOnPlex": "Play On Plex", - "ViewOnEmby": "Play On Emby", - "ViewOnJellyfin": "Play On Jellyfin", - "RequestAdded": "已成功添加對 {{title}} 的請求", + "Paragraph": "想要观看当前无法观看的内容吗?没问题,只需在下方搜索并请求!", + "MoviesTab": "电影", + "TvTab": "电视节目", + "MusicTab": "音乐", + "AdvancedSearch": "您可以填写以下任何一项来发现新媒体,所有结果都按受欢迎程度排序。", + "AdvancedSearchHeader": "高级搜索", + "Suggestions": "建议", + "NoResults": "对不起,我们没有找到任何结果。", + "DigitalDate": "数字版发行:{{date}}", + "TheatricalRelease": "剧场版发行:{{date}}", + "ViewOnPlex": "在Plex上播放", + "ViewOnEmby": "在 Emby上播放", + "ViewOnJellyfin": "在 Jellyfin上播放", + "RequestAdded": "{{title}} 的请求已成功添加", "Similar": "相似", - "Refine": "精簡", - "SearchBarPlaceholder": "在這裡輸入以搜尋", + "Refine": "精选", + "SearchBarPlaceholder": "在这里输入搜索内容", "Movies": { - "PopularMovies": "熱門電影", - "UpcomingMovies": "即將上映的電影", - "TopRatedMovies": "评级最高的电影", - "NowPlayingMovies": "正在上映的電影", - "HomePage": "首頁", - "Trailer": "預告片" + "PopularMovies": "热门电影", + "UpcomingMovies": "即将上映的电影", + "TopRatedMovies": "高评分的电影", + "NowPlayingMovies": "正在播放的电影", + "HomePage": "主页", + "Trailer": "预告片" }, "TvShows": { - "Popular": "流行的", - "Trending": "趨勢", - "MostWatched": "最受矚目", + "Popular": "热门", + "Trending": "趋势", + "MostWatched": "观看次数最多", "MostAnticipated": "最期待", - "Results": "結果", + "Results": "结果", "AirDate": "播出日期:", - "AllSeasons": "全季", + "AllSeasons": "所有季", "FirstSeason": "第一季", - "LatestSeason": "最新一季", - "Select": "選擇...", - "SubmitRequest": "送出請求", - "Season": "Season {{seasonNumber}}", - "SelectAllInSeason": "選擇第 {{seasonNumber}} 季中的全部" + "LatestSeason": "最新季", + "Select": "请选择...", + "SubmitRequest": "提交请求", + "Season": "第{{seasonNumber}} 季", + "SelectAllInSeason": "在所有季中选择第{{seasonNumber}} 季" }, - "AdvancedSearchInstructions": "Please choose what type of media you are searching for:", - "YearOfRelease": "Year of Release", - "KeywordSearchingDisclaimer": "Please note that Keyword Searching is very hit and miss due to the inconsistent data in TheMovieDb" + "AdvancedSearchInstructions": "请选择您需要搜索的媒体类型:", + "YearOfRelease": "发行年份", + "SearchGenre": "按类型搜索", + "SearchKeyword": "按关键字搜索", + "SearchProvider": "按提供者搜索", + "KeywordSearchingDisclaimer": "请注意,由于TheMovieDb中的数据不一致,关键字搜索方式非常容易出错" }, "Requests": { - "Title": "請求", - "Paragraph": "您可以在下方看到您的請求和所有其他請求,以及它們的下載和批准狀態。", - "MoviesTab": "電影", - "ArtistName": "Artist", - "AlbumName": "Album Name", - "TvTab": "電視節目", - "MusicTab": "音樂", - "RequestedBy": "Requested By", - "Status": "Status", - "RequestStatus": "Request status", - "Denied": " 拒絕:", - "TheatricalRelease": "劇場版:{{date}}", - "ReleaseDate": "發佈日期:{{date}}", - "TheatricalReleaseSort": "劇場版", - "DigitalRelease": "數字發行:{{date}}", - "RequestDate": "Request Date", - "QualityOverride": "質量覆蓋:", - "RootFolderOverride": "根文件夾覆蓋:", - "ChangeRootFolder": "根文件夹", - "ChangeQualityProfile": "質量設置", - "MarkUnavailable": "標記未收錄", - "MarkAvailable": "標記已收錄", - "Remove": "移除", - "Deny": "拒絕", - "DenyReason": "Deny Reason", - "DeniedReason": "Denied Reason", - "Season": "Season", - "GridTitle": "標題", - "AirDate": "Air Date", - "GridStatus": "狀態", - "ReportIssue": "回報問題", - "Filter": "篩選", - "Sort": "分類", - "SeasonNumberHeading": "季: {seasonNumber}", - "SortTitleAsc": "標題 ▲", - "SortTitleDesc": "標題 ▼", + "Title": "请求", + "Paragraph": "您可以在下方看到您的和所有其他人的请求,以及他们的下载和批准状态", + "MoviesTab": "电影", + "ArtistName": "艺术家", + "AlbumName": "专辑名称", + "TvTab": "电视节目", + "MusicTab": "音乐", + "RequestedBy": "请求者", + "Status": "发行状态", + "RequestStatus": "申请状态", + "Denied": "已拒绝:", + "TheatricalRelease": "剧场版发行:{{date}}", + "ReleaseDate": "已发行: {{date}}", + "TheatricalReleaseSort": "剧场版发行", + "DigitalRelease": "数字版发行:{{date}}", + "RequestDate": "请求日期", + "QualityOverride": "质量覆盖:", + "RootFolderOverride": "根目录覆盖:", + "ChangeRootFolder": "根目录", + "ChangeQualityProfile": "画质配置文件", + "MarkUnavailable": "标记为不可用", + "MarkUnavailable4K": "标记为不可播放4K", + "MarkAvailable": "标记为可用", + "MarkAvailable4K": "标记为可播放4K", + "Remove": "删除", + "Deny": "拒绝", + "Deny4K": "拒绝4K", + "Has4KRequest": "已有4K请求", + "DenyReason": "拒绝原因", + "DeniedReason": "被拒绝原因", + "Season": "季", + "GridTitle": "标题", + "AirDate": "播出日期:", + "GridStatus": "状态", + "ReportIssue": "反馈问题", + "Filter": "筛选", + "Sort": "排序", + "SeasonNumberHeading": "第{seasonNumber} 季", + "SortTitleAsc": "标题 ▲", + "SortTitleDesc": "标题 ▼", "SortRequestDateAsc": "请求日期 ▲", "SortRequestDateDesc": "请求日期 ▼", - "SortStatusAsc": "狀態 ▲", - "SortStatusDesc": "狀態 ▼", + "SortStatusAsc": "状态 ▲", + "SortStatusDesc": "状态 ▼", "Remaining": { - "Quota": "{{remaining}}/{{total}} 個剩餘請求", - "NextDays": "將在 {{time}} 天內添加另一個請求", - "NextHours": "將在 {{time}} 小時內添加另一個請求", - "NextMinutes": "將在 {{time}} 分鐘內添加另一個請求", - "NextMinute": "將在 {{time}} 分鐘內添加另一個請求" + "Quota": "{{remaining}}/{{total}} 个请求剩余", + "NextDays": "将在{{time}} 天内添加另一个请求", + "NextHours": "将在{{time}} 小时后添加另一个请求", + "NextMinutes": "将在{{time}} 分钟内添加另一个请求", + "NextMinute": "将在{{time}} 分钟内添加另一个请求" }, - "AllRequests": "All Requests", - "PendingRequests": "Pending Requests", - "ProcessingRequests": "Processing Requests", - "AvailableRequests": "Available Requests", - "DeniedRequests": "Denied Requests", - "RequestsToDisplay": "Requests to display", - "RequestsTitle": "Title", - "Details": "Details", - "Options": "Options", + "AllRequests": "所有请求", + "PendingRequests": "待处理请求", + "ProcessingRequests": "处理中请求", + "AvailableRequests": "可用请求", + "DeniedRequests": "已拒绝请求", + "RequestsToDisplay": "显示请求", + "RequestsTitle": "标题", + "Details": "详情", + "Options": "选项", "RequestPanel": { - "Delete": "Delete Request", - "Approve": "Approve Request", - "ChangeAvailability": "Mark Available", - "Deleted": "Successfully deleted selected items", - "Approved": "Successfully approved selected items" + "Delete": "删除请求", + "Approve": "批准请求", + "Deny": "拒绝请求", + "Approve4K": "批准4K请求", + "Deny4K": "拒绝 4K 请求", + "ChangeAvailability": "标记为可用", + "Deleted": "所选项目已删除", + "Approved": "所选项目已批准", + "Denied": "所选项目已拒绝" }, - "SuccessfullyApproved": "Successfully Approved", - "NowAvailable": "Request is now available", - "NowUnavailable": "Request is now unavailable", - "SuccessfullyReprocessed": "Successfully Re-processed the request", - "DeniedRequest": "Denied Request", - "RequestCollection": "Request Collection", - "CollectionSuccesfullyAdded": "The collection {{name}} has been successfully added!", - "NeedToSelectEpisodes": "You need to select some episodes!", - "RequestAddedSuccessfully": "Request for {{title}} has been added successfully", + "SuccessfullyApproved": "批准成功", + "SuccessfullyDeleted": "删除请求成功", + "NowAvailable": "请求现在可观看", + "NowUnavailable": "请求现在不可观看", + "SuccessfullyReprocessed": "重新处理请求成功", + "DeniedRequest": "已拒绝请求", + "RequestCollection": "请求合集", + "CollectionSuccesfullyAdded": "合集 {{name}} 已成功添加!", + "NeedToSelectEpisodes": "您需要选择集数!", + "RequestAddedSuccessfully": "{{title}} 的请求已成功添加", "ErrorCodes": { - "AlreadyRequested": "This has already been requested", - "EpisodesAlreadyRequested": "We already have episodes requested from this series", - "NoPermissionsOnBehalf": "You do not have the correct permissions to request on behalf of users!", - "NoPermissions": "You do not have the correct permissions!", - "RequestDoesNotExist": "Request does not exist", - "ChildRequestDoesNotExist": "Child Request does not exist", - "NoPermissionsRequestMovie": "You do not have permissions to Request a Movie", - "NoPermissionsRequestTV": "You do not have permissions to Request a TV Show", - "NoPermissionsRequestAlbum": "You do not have permissions to Request an Album", - "MovieRequestQuotaExceeded": "You have exceeded your Movie request quota!", - "TvRequestQuotaExceeded": "You have exceeded your Episode request quota!", - "AlbumRequestQuotaExceeded": "You have exceeded your Album request quota!" - } + "AlreadyRequested": "请求已经存在", + "EpisodesAlreadyRequested": "已存在这个系列的剧集请求", + "NoPermissionsOnBehalf": "您没有代表用户请求的正确权限!", + "NoPermissions": "您没有正确的权限!", + "RequestDoesNotExist": "请求不存在", + "ChildRequestDoesNotExist": "子请求不存在", + "NoPermissionsRequestMovie": "您没有请求电影的权限", + "NoPermissionsRequestTV": "您没有请求电视节目的权限", + "NoPermissionsRequestAlbum": "您没有请求专辑的权限", + "MovieRequestQuotaExceeded": "您的电影请求已超出配额!", + "TvRequestQuotaExceeded": "您的剧集请求已超出配额!", + "AlbumRequestQuotaExceeded": "您的专辑请求已超出配额!" + }, + "Notify": "通知", + "RemoveNotification": "删除通知", + "SuccessfulNotify": "您将收到标题为 {{title}} 的通知", + "SuccessfulUnNotify": "您将不再收到标题为 {{title}} 的通知", + "CouldntNotify": "无法通知标题 {{title}}" }, "Issues": { - "Title": "問題", - "PendingTitle": "未決問題", - "InProgressTitle": "進行中的問題", - "ResolvedTitle": "已解決的問題", - "ColumnTitle": "標題", - "Count": "Count", - "Category": "分類", - "Status": "狀態", - "Details": "詳細資料", - "Description": "描述信息", - "NoComments": "暫無評論!", - "MarkInProgress": "標記為進行中", - "MarkResolved": "標記為已解決", - "SendMessageButton": "發送", - "Subject": "主題", - "Comments": "評論", - "WriteMessagePlaceholder": "在這裡撰寫訊息...", - "ReportedBy": "報告者:", + "Title": "问题", + "IssuesForTitle": "{{title}} 的问题", + "PendingTitle": "待处理的问题", + "InProgressTitle": "正在处理的问题", + "ResolvedTitle": "已解决的问题", + "ColumnTitle": "标题", + "Count": "总计", + "Category": "类别", + "Status": "状态", + "Details": "详情", + "Description": "描述", + "NoComments": "暂无评论", + "MarkInProgress": "标记为进行中", + "MarkResolved": "标记为已解决", + "SendMessageButton": "发送", + "Subject": "主题", + "Comments": "评论", + "WriteMessagePlaceholder": "在这里写下您的留言", + "ReportedBy": "报告人", "IssueDialog": { - "Title": "Report an issue", - "DescriptionPlaceholder": "Please describe the issue", - "TitlePlaceholder": "Short title of your issue", - "SelectCategory": "Select Category", - "IssueCreated": "Issue has been created" + "Title": "反馈问题", + "DescriptionPlaceholder": "请描述您的问题", + "TitlePlaceholder": "简短标题", + "SelectCategory": "选择分类", + "IssueCreated": "问题已创建" }, - "Outstanding": "There are outstanding issues", - "ResolvedDate": "Resolved date", - "CreatedDate": "Raised on", - "MarkedAsResolved": "This issue has now been marked as resolved!", - "MarkedAsInProgress": "This issue has now been marked as in progress!", - "Delete": "Delete issue", - "DeletedIssue": "Issue has been deleted", - "Chat": "Chat", - "Requested": "Requested", - "UserOnDate": "{{user}} on {{date}}" + "Outstanding": "未解决的问题", + "ResolvedDate": "解决日期", + "CreatedDate": "提出日期", + "MarkedAsResolved": "此问题已被标记为已解决!", + "MarkedAsInProgress": "此问题已被标记为正在处理中!", + "Delete": "删除问题", + "DeletedIssue": "问题已被删除", + "Chat": "聊天", + "EnterYourMessage": "输入您的消息", + "Requested": "已请求", + "UserOnDate": "{{user}} 在 {{date}}" }, "Filter": { - "ClearFilter": "清除篩選條件", + "ClearFilter": "清除筛选", "FilterHeaderAvailability": "可用性", - "FilterHeaderRequestStatus": "狀態", - "Approved": "已通過審核", - "PendingApproval": "待決審核", - "WatchProviders": "Watch Providers", - "Keywords": "Keywords" + "FilterHeaderRequestStatus": "状态", + "Approved": "已批准", + "PendingApproval": "待批准", + "WatchProviders": "观看提供商", + "Keywords": "关键字" }, "UserManagment": { - "TvRemaining": "電視:{{remaining}}/{{total}} 剩餘", - "MovieRemaining": "電影:{{remaining}}/{{total}} 剩餘", - "MusicRemaining": "音樂:{{remaining}}/{{total}} 剩餘", - "TvDue": "電視:{{date}}", - "MovieDue": "電影:{{date}}", - "MusicDue": "音樂:{{date}}" + "TvRemaining": "电视节目:{{remaining}}/{{total}} 剩余", + "MovieRemaining": "电影: {{remaining}}/{{total}} 剩余", + "MusicRemaining": "音乐: {{remaining}}/{{total}} 剩余", + "TvDue": "电视节目:{{date}}", + "MovieDue": "电影: {{date}}", + "MusicDue": "音乐: {{date}}" }, "Votes": { "CompletedVotesTab": "已投票", "VotesTab": "需要投票" }, "MediaDetails": { - "Denied": "Denied", - "RecommendationsTitle": "Recommendations", - "SimilarTitle": "Similar", - "VideosTitle": "Videos", - "AlbumsTitle": "Albums", - "RequestAllAlbums": "Request All Albums", - "ClearSelection": "Clear Selection", - "RequestSelectedAlbums": "Request Selected Albums", - "ViewCollection": "View Collection", - "NotEnoughInfo": "Unfortunately there is not enough information about this show yet!", - "AdvancedOptions": "Advanced Options", - "AutoApproveOptions": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTv": "You can configure the request here, once requested it will be send to your DVR application and will be auto approved! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "AutoApproveOptionsTvShort": "You can configure the request here, once requested it will be send to your DVR application! If the request is already in Sonarr, we will not change the root folder or quality profile if you set it! Please note, this is optional, just press Request to skip!", - "QualityProfilesSelect": "Select A Quality Profile", - "RootFolderSelect": "Select A Root Folder", - "LanguageProfileSelect": "Select A Language Profile", - "Status": "Status:", + "Denied": "已拒绝", + "Denied4K": "拒绝4K", + "Trailers": "预告片", + "RecommendationsTitle": "推荐", + "SimilarTitle": "相似", + "VideosTitle": "视频", + "AlbumsTitle": "专辑", + "RequestAllAlbums": "请求所有专辑", + "ClearSelection": "清除已选择", + "RequestSelectedAlbums": "请求选中的专辑", + "ViewCollection": "查看合集", + "NotEnoughInfo": "很遗憾,这个节目还没有足够的信息!", + "AdvancedOptions": "高级选项", + "AutoApproveOptions": "您可以在这里配置请求,一旦请求它将被发送到您的DVR应用程序并将被自动批准! 请注意,这是可选的,只需按请求跳过!", + "AutoApproveOptionsTv": "您可以在这里配置请求,一旦请求它将被发送到您的DVR应用程序并将被自动批准! 如果请求已经在 Sonarr 中并且您设置了它,我们将不会更改根目录或画质配置文件! 请注意,这是可选的,只需按请求跳过!", + "AutoApproveOptionsTvShort": "您可以在这里配置请求,一旦请求它将被发送到您的DVR应用程序! 如果请求已经在 Sonarr 中并且您设置了它,我们将不会更改根目录或画质配置文件! 请注意,这是可选的,只需按请求跳过!", + "QualityProfilesSelect": "请选择画质配置文件", + "RootFolderSelect": "请选择根目录", + "LanguageProfileSelect": "请选择语言配置文件", + "Status": "状态:", "StatusValues": { - "Rumored": "Rumored", - "Planned": "Planned", - "In Production": "In Production", - "Post Production": "Post Production", - "Released": "Released", - "Running": "Running", - "Returning Series": "Returning Series", - "Ended": "Ended", - "Canceled": "Canceled" + "Rumored": "有想法", + "Planned": "计划中", + "In Production": "制作中", + "Post Production": "后期处理", + "Released": "已发布", + "Running": "运行中", + "Returning Series": "回归系列", + "Ended": "已结束", + "Canceled": "已取消" }, - "Seasons": "Seasons:", - "Episodes": "Episodes:", - "Availability": "Availability:", - "RequestStatus": "Request Status", - "Quality": "Quality:", - "RootFolderOverride": "Root Folder Override:", - "QualityOverride": "Quality Override:", - "Network": "Network:", - "Genres": "Genres:", - "FirstAired": "First Aired:", - "TheatricalRelease": "Release:", - "DigitalRelease": "Digital Release:", - "Votes": "Votes:", - "Runtime": "Runtime:", - "Minutes": "{{runtime}} Minutes", - "Revenue": "Revenue:", - "Budget": "Budget:", - "Keywords": "Keywords/Tags:", + "Seasons": "季:", + "Episodes": "集:", + "Availability": "可用性:", + "RequestStatus": "Request Status:", + "Quality": "画质:", + "RootFolderOverride": "根目录覆盖:", + "QualityOverride": "质量覆盖:", + "Network": "网络:", + "GenresLabel": "流派", + "Genres": "流派", + "FirstAired": "首播", + "TheatricalRelease": "发行日:", + "DigitalRelease": "数字版发行:", + "Votes": "投票:", + "Runtime": "运行时间:", + "Minutes": "{{runtime}} 分钟", + "Revenue": "收入:", + "Budget": "预算:", + "Keywords": "关键词/标签:", "Casts": { - "CastTitle": "Cast" + "CastTitle": "演员" }, "EpisodeSelector": { - "AllSeasonsTooltip": "This will request every season for this show", - "FirstSeasonTooltip": "This will only request the First Season for this show", - "LatestSeasonTooltip": "This will only request the Latest Season for this show", - "NoEpisodes": "There unfortunately is no episode data for this show yet!", - "SeasonNumber": "Season {{number}}" + "AllSeasonsTooltip": "请求这个节目的每一季", + "FirstSeasonTooltip": "请求这个节目的第一季", + "LatestSeasonTooltip": "只请求这个节目的最新季", + "NoEpisodes": "很遗憾,目前还没有该节目的剧集数据!", + "SeasonNumber": "第{{number}} 季" }, - "SonarrConfiguration": "Sonarr Configuration", - "RadarrConfiguration": "Radarr Configuration", - "RequestOnBehalf": "Request on behalf of", - "PleaseSelectUser": "Please select a user", - "StreamingOn": "Streaming On:", - "RequestedBy": "Requested By:", - "RequestDate": "Request Date:", - "DeniedReason": "Denied Reason:", - "ReProcessRequest": "Re-Process Request", + "SonarrConfiguration": "Sonarr 配置", + "RadarrConfiguration": "Radarr 配置", + "RequestOnBehalf": "代表请求", + "PleaseSelectUser": "请选择用户", + "StreamingOn": "流媒体:", + "RequestedBy": "请求者:", + "RequestedByOn": "由 {{user}} 在 {{date}} 时请求", + "RequestDate": "请求日期:", + "DeniedReason": "被拒绝原因:", + "ReProcessRequest": "重新处理请求", + "ReProcessRequest4K": "重新处理4K请求", "Music": { - "Type": "Type:", - "Country": "Country:", - "StartDate": "Start Date:", - "EndDate": "EndDate:" - } + "Type": "类型:", + "Country": "国家:", + "StartDate": "开始日期:", + "EndDate": "结束日期:" + }, + "RequestSource": "来源:" }, "Discovery": { - "PopularTab": "Popular", - "TrendingTab": "Trending", - "UpcomingTab": "Upcoming", - "SeasonalTab": "Seasonal", - "RecentlyRequestedTab": "Recently Requested", - "Movies": "Movies", - "Combined": "Combined", - "Tv": "TV", + "PopularTab": "热门", + "TrendingTab": "趋势", + "UpcomingTab": "即将上映", + "SeasonalTab": "按季的", + "RecentlyRequestedTab": "最近请求", + "Movies": "电影", + "Combined": "混合", + "Tv": "电视节目", "CardDetails": { - "Availability": "Availability", - "Studio": "Studio", - "Network": "Network", - "UnknownNetwork": "Unknown", - "RequestStatus": "Request Status", - "Director": "Director", - "InCinemas": "In Cinemas", - "FirstAired": "First Aired", - "Writer": "Writer", - "ExecProducer": "Exec Producer" + "Availability": "可用性", + "Studio": "工作室", + "Network": "网络", + "UnknownNetwork": "未知", + "RequestStatus": "请求状态", + "Director": "导演", + "InCinemas": "影院放映", + "FirstAired": "首播", + "Writer": "编剧", + "ExecProducer": "制作发行商" }, - "NoSearch": "Sorry, nothing matches your search!" + "NoSearch": "抱歉,没有符合您搜索条件的内容!" }, "UserPreferences": { - "Welcome": "Welcome {{username}}!", - "OmbiLanguage": "Language", - "DarkMode": "Dark Mode", - "Updated": "Successfully Updated", - "StreamingCountry": "Streaming Country", - "StreamingCountryDescription": "This is the country code that we will display streaming information for. If you are in the US please select US and you will have US related streaming information.", - "LanguageDescription": "This is the language you would like the Ombi interface to be displayed in.", - "MobileQRCode": "Mobile QR Code", - "LegacyApp": "Launch Legacy App", - "NoQrCode": "Please contact your administrator to enable QR codes", - "UserType": "User Type:", - "ChangeDetails": "Change Details", - "NeedCurrentPassword": "You need your current password to make any changes here", - "CurrentPassword": "Current Password", - "EmailAddress": "Email Address", - "NewPassword": "New Password", - "NewPasswordConfirm": "New Password Confirm", - "Security": "Security", - "Profile": "Profile", - "UpdatedYourInformation": "Updated your information" + "Welcome": "{{username}},欢迎您!", + "OmbiLanguage": "语言", + "DarkMode": "深色模式", + "Updated": "更新成功", + "StreamingCountry": "流媒体国家", + "StreamingCountryDescription": "这是我们将显示流媒体信息的国家代码。 如果您在美国,请选择美国并获取美国相关的流媒体信息。", + "LanguageDescription": "您希望Ombi界面显示的语言", + "MobileQRCode": "手机二维码", + "LegacyApp": "启动旧版应用程序", + "NoQrCode": "请联系管理员以启用二维码", + "UserType": "用户类型:", + "ChangeDetails": "变更详情", + "NeedCurrentPassword": "您需要输入当前密码才能进行更改", + "CurrentPassword": "当前密码", + "EmailAddress": "邮箱地址", + "NewPassword": "新密码", + "NewPasswordConfirm": "确认新密码", + "Security": "安全选项", + "Profile": "用户信息", + "UpdatedYourInformation": "您的用户信息已更新", + "Unsubscribed": "取消订阅!" }, "UserTypeLabel": { - "1": "Local User", - "2": "Plex User", - "3": "Emby User", - "4": "Emby Connect User", - "5": "Jellyfin User" + "1": "本地用户", + "2": "Plex用户", + "3": "Emby用户", + "4": "Emby Connect用户", + "5": "Jellyfin用户" + }, + "Paginator": { + "itemsPerPageLabel": "每页显示项目数:", + "nextPageLabel": "下一页", + "previousPageLabel": "上一页", + "firstPageLabel": "转到第一页", + "lastPageLabel": "转到最后一页", + "rangePageLabel1": "{{length}} 中的第0项", + "rangePageLabel2": "{{length}} 中的第{{startIndex}} 到{{endIndex}} 项" } } diff --git a/tests/cypress/fixtures/api/v1/tv-search-extra-info.json b/tests/cypress/fixtures/api/v1/tv-search-extra-info.json index 03b894eb2..3421514a2 100644 --- a/tests/cypress/fixtures/api/v1/tv-search-extra-info.json +++ b/tests/cypress/fixtures/api/v1/tv-search-extra-info.json @@ -25,14 +25,14 @@ { "episodeNumber": 1, "title": "Our Cup Runneth Over", - "airDate": "2015-01-14T01:00:00+00:00", + "airDate": "2015-01-13T00:00:00", "url": "https://www.tvmaze.com/episodes/153107/schitts-creek-1x01-our-cup-runneth-over", "available": false, "approved": false, "requested": false, "seasonId": 0, "season": null, - "airDateDisplay": "01/14/2015 01:00:00", + "airDateDisplay": "01/13/2015 00:00:00", "requestStatus": "", "id": 0 }, diff --git a/tests/cypress/integration/page-objects/shared/DiscoverCard.ts b/tests/cypress/integration/page-objects/shared/DiscoverCard.ts index 619a0c048..fcbcb61fd 100644 --- a/tests/cypress/integration/page-objects/shared/DiscoverCard.ts +++ b/tests/cypress/integration/page-objects/shared/DiscoverCard.ts @@ -24,7 +24,7 @@ export class DiscoverCard { } get requestType(): Cypress.Chainable { - return cy.get(`#type${this.id}`); + return cy.get(`#type${this.id}-${this.movie ? 'movie': 'tvShow'}`); } get statusClass(): Cypress.Chainable { diff --git a/tests/cypress/tests/requests/requests.spec.ts b/tests/cypress/tests/requests/requests.spec.ts index 23c5ccb09..c161d0645 100644 --- a/tests/cypress/tests/requests/requests.spec.ts +++ b/tests/cypress/tests/requests/requests.spec.ts @@ -9,22 +9,27 @@ describe("Requests Tests", () => { cy.intercept("token").as("login"); cy.login(); - cy.requestAllTv(60735); // The Flash + const dbID = 60735; // The Flash + cy.requestAllTv(dbID); Page.visit(); Page.tvTab.click(); - const row = Page.tv.getGridRow(60735); + cy.waitUntil(() => { + const row = Page.tv.getGridRow(dbID); + return row.detailsButton.should("be.visible"); + }); + const row = Page.tv.getGridRow(dbID); row.detailsButton.click(); - cy.location("pathname").should("contains", "/details/tv/60735"); + cy.location("pathname").should("contains", "/details/tv/" + dbID); TvPage.title.contains("The Flash"); }); it("Deleting TV requests, removes from grid", () => { cy.intercept("POST", "request/tv").as("tvRequest"); cy.intercept("token").as("login"); - cy.intercept('DELETE', 'Request/tv/child/60735').as('deleteRequest'); + cy.intercept('DELETE','api/v1/Request/tv/child/60735').as('deleteRequest'); cy.login(); // cy.wait('@login'); @@ -39,7 +44,7 @@ describe("Requests Tests", () => { row.optionsDelete.click(); cy.wait('@deleteRequest').then((intercept) => { - expect(intercept.response.body).is.true; + expect(intercept.response.body.result).is.true; }) row.title.should('not.exist'); diff --git a/tests/cypress/tests/search/search.spec.ts b/tests/cypress/tests/search/search.spec.ts index 6bcef1712..a677e99b2 100644 --- a/tests/cypress/tests/search/search.spec.ts +++ b/tests/cypress/tests/search/search.spec.ts @@ -3,7 +3,7 @@ import { searchPage as Page } from "@/integration/page-objects"; describe("Search Tests", () => { beforeEach(() => { cy.login(); - cy.intercept("POST", "v2/search/multi/").as("searchResponse"); + cy.intercept("POST", "api/v2/search/multi/*").as("searchResponse"); }); it("Single result when TV Search Only", () => { @@ -101,7 +101,7 @@ describe("Search Tests", () => { it("No Movie results, enabling Tv filter we get results", () => { Page.navbar.searchFilter.applyFilter(false, true, false); - Page.visit("It's always sunny in Philadelphia"); + Page.visit("Dexter New Blood"); cy.wait('@searchResponse'); Page.noSearchResultMessage.should('exist'); @@ -110,11 +110,11 @@ describe("Search Tests", () => { Page.navbar.searchFilter.tvToggle.click(); cy.wait('@searchResponse'); - const card = Page.getCard('2710', false); + const card = Page.getCard('131927', false); card.topLevelCard.realHover(); - card.title.should('have.text', "It's Always Sunny in Philadelphia"); - card.overview.contains('Irish pub'); + card.title.should('have.text', "Dexter: New Blood"); + card.overview.contains('Iron Lake'); card.requestType.contains('TV Show'); card.requestButton.should('exist'); }); diff --git a/version.json b/version.json index 3f41f3df2..e5e478173 100644 --- a/version.json +++ b/version.json @@ -1,3 +1,3 @@ { - "version": "4.3.3" + "version": "4.22.3" } \ No newline at end of file
"); @@ -59,7 +60,7 @@ namespace Ombi.Schedule.Jobs.Ombi sb.Append("
"); @@ -68,7 +69,7 @@ namespace Ombi.Schedule.Jobs.Ombi sb.Append("
"); @@ -78,7 +79,7 @@ namespace Ombi.Schedule.Jobs.Ombi sb.Append("
"); diff --git a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs index 7752d298d..0782a796a 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/NewsletterJob.cs @@ -1,27 +1,22 @@ using System; -using System.Collections; using System.Collections.Generic; -using System.Collections.Immutable; using System.Linq; -using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; -using MailKit; using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.SignalR; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using MimeKit; -using Ombi.Api.CouchPotato.Models; using Ombi.Api.Lidarr; using Ombi.Api.Lidarr.Models; using Ombi.Api.TheMovieDb; using Ombi.Api.TheMovieDb.Models; -using Ombi.Api.TvMaze; using Ombi.Core.Settings; using Ombi.Core.Settings.Models.External; using Ombi.Helpers; using Ombi.Hubs; +using Ombi.I18n.Resources; using Ombi.Notifications; using Ombi.Notifications.Models; using Ombi.Notifications.Templates; @@ -30,7 +25,6 @@ using Ombi.Settings.Settings.Models.External; using Ombi.Settings.Settings.Models.Notifications; using Ombi.Store.Entities; using Ombi.Store.Repository; -using Org.BouncyCastle.Utilities.Collections; using Quartz; using ContentType = Ombi.Store.Entities.ContentType; @@ -39,7 +33,7 @@ namespace Ombi.Schedule.Jobs.Ombi public class NewsletterJob : HtmlTemplateGenerator, INewsletterJob { public NewsletterJob(IPlexContentRepository plex, IEmbyContentRepository emby, IJellyfinContentRepository jellyfin, IRepository addedLog, - IMovieDbApi movieApi, ITvMazeApi tvApi, IEmailProvider email, ISettingsService custom, + IMovieDbApi movieApi, IEmailProvider email, ISettingsService custom, ISettingsService emailSettings, INotificationTemplatesRepository templateRepo, UserManager um, ISettingsService newsletter, ILogger log, ILidarrApi lidarrApi, IExternalRepository albumCache, ISettingsService lidarrSettings, @@ -51,7 +45,6 @@ namespace Ombi.Schedule.Jobs.Ombi _jellyfin = jellyfin; _recentlyAddedLog = addedLog; _movieApi = movieApi; - _tvApi = tvApi; _email = email; _customizationSettings = custom; _templateRepo = templateRepo; @@ -74,12 +67,11 @@ namespace Ombi.Schedule.Jobs.Ombi _refreshMetadata = refreshMetadata; } - private readonly IPlexContentRepository _plex; - private readonly IEmbyContentRepository _emby; - private readonly IJellyfinContentRepository _jellyfin; + private readonly IMediaServerContentRepository _plex; + private readonly IMediaServerContentRepository _emby; + private readonly IMediaServerContentRepository _jellyfin; private readonly IRepository _recentlyAddedLog; private readonly IMovieDbApi _movieApi; - private readonly ITvMazeApi _tvApi; private readonly IEmailProvider _email; private readonly ISettingsService _customizationSettings; private readonly INotificationTemplatesRepository _templateRepo; @@ -122,88 +114,37 @@ namespace Ombi.Schedule.Jobs.Ombi try { - - var customization = await _customizationSettings.GetSettingsAsync(); - // Get the Content - var plexContent = _plex.GetAll().Include(x => x.Episodes).AsNoTracking(); - var embyContent = _emby.GetAll().Include(x => x.Episodes).AsNoTracking(); - var jellyfinContent = _jellyfin.GetAll().Include(x => x.Episodes).AsNoTracking(); - var lidarrContent = _lidarrAlbumRepository.GetAll().AsNoTracking().ToList().Where(x => x.FullyAvailable); - - var addedLog = _recentlyAddedLog.GetAll().ToList(); - - HashSet addedPlexMovieLogIds, addedEmbyMoviesLogIds, addedJellyfinMoviesLogIds; - HashSet addedAlbumLogIds; - GetRecentlyAddedMoviesData(addedLog, out addedPlexMovieLogIds, out addedEmbyMoviesLogIds, out addedJellyfinMoviesLogIds, out addedAlbumLogIds); - - var addedPlexEpisodesLogIds = - addedLog.Where(x => x.Type == RecentlyAddedType.Plex && x.ContentType == ContentType.Episode); - var addedEmbyEpisodesLogIds = - addedLog.Where(x => x.Type == RecentlyAddedType.Emby && x.ContentType == ContentType.Episode); - var addedJellyfinEpisodesLogIds = - addedLog.Where(x => x.Type == RecentlyAddedType.Jellyfin && x.ContentType == ContentType.Episode); - - - // Filter out the ones that we haven't sent yet - var plexContentLocalDataset = plexContent.Where(x => x.Type == PlexMediaTypeEntity.Movie && !string.IsNullOrEmpty(x.TheMovieDbId)).ToHashSet(); - var embyContentLocalDataset = embyContent.Where(x => x.Type == EmbyMediaType.Movie && !string.IsNullOrEmpty(x.TheMovieDbId)).ToHashSet(); - var jellyfinContentLocalDataset = jellyfinContent.Where(x => x.Type == JellyfinMediaType.Movie && !string.IsNullOrEmpty(x.TheMovieDbId)).ToHashSet(); - var plexContentMoviesToSend = plexContentLocalDataset.Where(x => !addedPlexMovieLogIds.Contains(StringHelper.IntParseLinq(x.TheMovieDbId))).ToHashSet(); - var embyContentMoviesToSend = embyContentLocalDataset.Where(x => !addedEmbyMoviesLogIds.Contains(StringHelper.IntParseLinq(x.TheMovieDbId))).ToHashSet(); - var jellyfinContentMoviesToSend = jellyfinContentLocalDataset.Where(x => !addedJellyfinMoviesLogIds.Contains(StringHelper.IntParseLinq(x.TheMovieDbId))).ToHashSet(); - var lidarrContentAlbumsToSend = lidarrContent.Where(x => !addedAlbumLogIds.Contains(x.ForeignAlbumId)).ToHashSet(); - _log.LogInformation("Plex Movies to send: {0}", plexContentMoviesToSend.Count()); - _log.LogInformation("Emby Movies to send: {0}", embyContentMoviesToSend.Count()); - _log.LogInformation("Jellyfin Movies to send: {0}", jellyfinContentMoviesToSend.Count()); - _log.LogInformation("Albums to send: {0}", lidarrContentAlbumsToSend.Count()); - - // Find the movies that do not yet have MovieDbIds - var needsMovieDbPlex = plexContent.Where(x => x.Type == PlexMediaTypeEntity.Movie && !string.IsNullOrEmpty(x.TheMovieDbId)).ToHashSet(); - var needsMovieDbEmby = embyContent.Where(x => x.Type == EmbyMediaType.Movie && !string.IsNullOrEmpty(x.TheMovieDbId)).ToHashSet(); - var needsMovieDbJellyfin = jellyfinContent.Where(x => x.Type == JellyfinMediaType.Movie && !string.IsNullOrEmpty(x.TheMovieDbId)).ToHashSet(); - var newPlexMovies = await GetMoviesWithoutId(addedPlexMovieLogIds, needsMovieDbPlex); - var newEmbyMovies = await GetMoviesWithoutId(addedEmbyMoviesLogIds, needsMovieDbEmby); - var newJellyfinMovies = await GetMoviesWithoutId(addedJellyfinMoviesLogIds, needsMovieDbJellyfin); - plexContentMoviesToSend = plexContentMoviesToSend.Union(newPlexMovies).ToHashSet(); - embyContentMoviesToSend = embyContentMoviesToSend.Union(newEmbyMovies).ToHashSet(); - jellyfinContentMoviesToSend = jellyfinContentMoviesToSend.Union(newJellyfinMovies).ToHashSet(); - - plexContentMoviesToSend = plexContentMoviesToSend.DistinctBy(x => x.Id).ToHashSet(); - embyContentMoviesToSend = embyContentMoviesToSend.DistinctBy(x => x.Id).ToHashSet(); - jellyfinContentMoviesToSend = jellyfinContentMoviesToSend.DistinctBy(x => x.Id).ToHashSet(); - - var plexEpisodesToSend = - FilterPlexEpisodes(_plex.GetAllEpisodes().Include(x => x.Series).AsNoTracking(), addedPlexEpisodesLogIds); - var embyEpisodesToSend = FilterEmbyEpisodes(_emby.GetAllEpisodes().Include(x => x.Series).AsNoTracking(), - addedEmbyEpisodesLogIds); - var jellyfinEpisodesToSend = FilterJellyfinEpisodes(_jellyfin.GetAllEpisodes().Include(x => x.Series).AsNoTracking(), - addedJellyfinEpisodesLogIds); - - _log.LogInformation("Plex Episodes to send: {0}", plexEpisodesToSend.Count()); - _log.LogInformation("Emby Episodes to send: {0}", embyEpisodesToSend.Count()); - _log.LogInformation("Jellyfin Episodes to send: {0}", jellyfinEpisodesToSend.Count()); var plexSettings = await _plexSettings.GetSettingsAsync(); var embySettings = await _embySettings.GetSettingsAsync(); var jellyfinSettings = await _jellyfinSettings.GetSettingsAsync(); - var body = string.Empty; - if (test) + + var customization = await _customizationSettings.GetSettingsAsync(); + + var moviesContents = new List(); + var seriesContents = new List(); + if (plexSettings.Enable) { - var plexm = plexContent.Where(x => x.Type == PlexMediaTypeEntity.Movie).OrderByDescending(x => x.AddedAt).Take(10); - var embym = embyContent.Where(x => x.Type == EmbyMediaType.Movie).OrderByDescending(x => x.AddedAt).Take(10); - var jellyfinm = jellyfinContent.Where(x => x.Type == JellyfinMediaType.Movie).OrderByDescending(x => x.AddedAt).Take(10); - var plext = _plex.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.Series.AddedAt).Take(10).ToHashSet(); - var embyt = _emby.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.AddedAt).Take(10).ToHashSet(); - var jellyfint = _jellyfin.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.AddedAt).Take(10).ToHashSet(); - var lidarr = lidarrContent.OrderByDescending(x => x.AddedAt).Take(10).ToHashSet(); - body = await BuildHtml(plexm, embym, jellyfinm, plext, embyt, jellyfint, lidarr, settings, embySettings, jellyfinSettings, plexSettings); + moviesContents.AddRange(await GetMoviesContent(_plex, test)); + seriesContents.AddRange(GetSeriesContent(_plex, test)); } - else + if (embySettings.Enable) { - body = await BuildHtml(plexContentMoviesToSend.AsQueryable(), embyContentMoviesToSend.AsQueryable(), jellyfinContentMoviesToSend.AsQueryable(), plexEpisodesToSend, embyEpisodesToSend, jellyfinEpisodesToSend, lidarrContentAlbumsToSend, settings, embySettings, jellyfinSettings, plexSettings); - if (body.IsNullOrEmpty()) - { - return; - } + moviesContents.AddRange(await GetMoviesContent(_emby, test)); + seriesContents.AddRange(GetSeriesContent(_emby, test)); + } + if (jellyfinSettings.Enable) + { + moviesContents.AddRange(await GetMoviesContent(_jellyfin, test)); + seriesContents.AddRange(GetSeriesContent(_jellyfin, test)); + } + + var albumsContents = GetMusicContent(_lidarrAlbumRepository, test); + + var body = await BuildHtml(moviesContents, seriesContents, albumsContents, settings); + + if (body.IsNullOrEmpty()) + { + return; } if (!test) @@ -223,7 +164,7 @@ namespace Ombi.Schedule.Jobs.Ombi if (!users.Any()) { return; - } + } var messageContent = ParseTemplate(template, customization); var email = new NewsletterTemplate(); @@ -258,84 +199,8 @@ namespace Ombi.Schedule.Jobs.Ombi // Now add all of this to the Recently Added log var recentlyAddedLog = new HashSet(); - foreach (var p in plexContentMoviesToSend) - { - recentlyAddedLog.Add(new RecentlyAddedLog - { - AddedAt = DateTime.Now, - Type = RecentlyAddedType.Plex, - ContentType = ContentType.Parent, - ContentId = StringHelper.IntParseLinq(p.TheMovieDbId), - }); - - } - - foreach (var p in plexEpisodesToSend) - { - recentlyAddedLog.Add(new RecentlyAddedLog - { - AddedAt = DateTime.Now, - Type = RecentlyAddedType.Plex, - ContentType = ContentType.Episode, - ContentId = StringHelper.IntParseLinq(p.Series.TvDbId), - EpisodeNumber = p.EpisodeNumber, - SeasonNumber = p.SeasonNumber - }); - } - foreach (var e in embyContentMoviesToSend) - { - if (e.Type == EmbyMediaType.Movie) - { - recentlyAddedLog.Add(new RecentlyAddedLog - { - AddedAt = DateTime.Now, - Type = RecentlyAddedType.Emby, - ContentType = ContentType.Parent, - ContentId = StringHelper.IntParseLinq(e.TheMovieDbId), - }); - } - } - - foreach (var p in embyEpisodesToSend) - { - recentlyAddedLog.Add(new RecentlyAddedLog - { - AddedAt = DateTime.Now, - Type = RecentlyAddedType.Emby, - ContentType = ContentType.Episode, - ContentId = StringHelper.IntParseLinq(p.Series.TvDbId), - EpisodeNumber = p.EpisodeNumber, - SeasonNumber = p.SeasonNumber - }); - } - - foreach (var e in jellyfinContentMoviesToSend) - { - if (e.Type == JellyfinMediaType.Movie) - { - recentlyAddedLog.Add(new RecentlyAddedLog - { - AddedAt = DateTime.Now, - Type = RecentlyAddedType.Jellyfin, - ContentType = ContentType.Parent, - ContentId = StringHelper.IntParseLinq(e.TheMovieDbId), - }); - } - } - - foreach (var p in jellyfinEpisodesToSend) - { - recentlyAddedLog.Add(new RecentlyAddedLog - { - AddedAt = DateTime.Now, - Type = RecentlyAddedType.Jellyfin, - ContentType = ContentType.Episode, - ContentId = StringHelper.IntParseLinq(p.Series.TvDbId), - EpisodeNumber = p.EpisodeNumber, - SeasonNumber = p.SeasonNumber - }); - } - + AddToRecentlyAddedLog(moviesContents, recentlyAddedLog); + AddToRecentlyAddedLog(seriesContents, recentlyAddedLog); await _recentlyAddedLog.AddRange(recentlyAddedLog); } else @@ -375,21 +240,118 @@ namespace Ombi.Schedule.Jobs.Ombi .SendAsync(NotificationHub.NotificationEvent, "Newsletter Finished"); } - private void GetRecentlyAddedMoviesData(List addedLog, out HashSet addedPlexMovieLogIds, out HashSet addedEmbyMoviesLogIds, out HashSet addedJellyfinMoviesLogIds, out HashSet addedAlbumLogIds) + private void AddToRecentlyAddedLog(ICollection moviesContents, + HashSet recentlyAddedLog) { - var plexParent = addedLog.Where(x => x.Type == RecentlyAddedType.Plex && x.ContentType == ContentType.Parent).ToList(); - addedPlexMovieLogIds = plexParent != null && plexParent.Any() ? (plexParent?.Select(x => x.ContentId)?.ToHashSet() ?? new HashSet()) : new HashSet(); - - var embyParent = addedLog.Where(x => x.Type == RecentlyAddedType.Emby && x.ContentType == ContentType.Parent); - addedEmbyMoviesLogIds = embyParent != null && embyParent.Any() ? (embyParent?.Select(x => x.ContentId)?.ToHashSet() ?? new HashSet()) : new HashSet(); - - var jellyFinParent = addedLog.Where(x => x.Type == RecentlyAddedType.Jellyfin && x.ContentType == ContentType.Parent); - addedJellyfinMoviesLogIds = jellyFinParent != null && jellyFinParent.Any() ? (jellyFinParent?.Select(x => x.ContentId)?.ToHashSet() ?? new HashSet()) : new HashSet(); + foreach (var p in moviesContents) + { + recentlyAddedLog.Add(new RecentlyAddedLog + { + AddedAt = DateTime.Now, + Type = p.RecentlyAddedType, + ContentType = ContentType.Parent, + ContentId = StringHelper.IntParseLinq(p.TheMovieDbId), + }); + } + } + private void AddToRecentlyAddedLog(ICollection episodes, + HashSet recentlyAddedLog) + { + foreach (var p in episodes) + { + recentlyAddedLog.Add(new RecentlyAddedLog + { + AddedAt = DateTime.Now, + Type = p.Series.RecentlyAddedType, + ContentType = ContentType.Episode, + ContentId = StringHelper.IntParseLinq(p.Series.TvDbId), + EpisodeNumber = p.EpisodeNumber, + SeasonNumber = p.SeasonNumber + }); + } + } + private void GetRecentlyAddedMoviesData(List addedLog, out HashSet addedAlbumLogIds) + { var lidarrParent = addedLog.Where(x => x.Type == RecentlyAddedType.Lidarr && x.ContentType == ContentType.Album); addedAlbumLogIds = lidarrParent != null && lidarrParent.Any() ? (lidarrParent?.Select(x => x.AlbumId)?.ToHashSet() ?? new HashSet()) : new HashSet(); } + private async Task> GetMoviesContent(IMediaServerContentRepository repository, bool test) where T : class, IMediaServerContent + { + IQueryable content = repository.GetAll().Include(x => x.Episodes).AsNoTracking().Where(x => x.Type == MediaType.Movie).OrderByDescending(x => x.AddedAt); + var localDataset = content.Where(x => x.Type == MediaType.Movie && !string.IsNullOrEmpty(x.TheMovieDbId)).ToHashSet(); + + HashSet moviesToSend; + if (test) + { + moviesToSend = content.Take(10).ToHashSet(); + } + else + { + // Filter out the ones that we haven't sent yet + var parent = _recentlyAddedLog.GetAll().Where(x => x.Type == repository.RecentlyAddedType + && x.ContentType == ContentType.Parent).ToList(); + var addedMovieLogIds = parent != null && parent.Any() ? (parent?.Select(x => x.ContentId)?.ToHashSet() ?? new HashSet()) : new HashSet(); + moviesToSend = localDataset.Where(x => !addedMovieLogIds.Contains(StringHelper.IntParseLinq(x.TheMovieDbId))).ToHashSet(); + _log.LogInformation("Movies to send: {0}", moviesToSend.Count()); + + // Find the movies that do not yet have MovieDbIds + var needsMovieDb = content.Where(x => x.Type == MediaType.Movie && !string.IsNullOrEmpty(x.TheMovieDbId)).ToHashSet(); + var newMovies = await GetMoviesWithoutId(addedMovieLogIds, needsMovieDb, repository); + moviesToSend = moviesToSend.Union(newMovies).ToHashSet(); + } + + _log.LogInformation("Movies to send: {0}", moviesToSend.Count()); + return moviesToSend.DistinctBy(x => x.Id).ToHashSet(); + } + + private HashSet GetSeriesContent(IMediaServerContentRepository repository, bool test) where T : class, IMediaServerContent + { + var content = repository.GetAllEpisodes().Include(x => x.Series).OrderByDescending(x => x.Series.AddedAt).AsNoTracking(); + + HashSet episodesToSend; + if (test) + { + var count = repository.GetAllEpisodes().Count(); + episodesToSend = content.Take(10).ToHashSet(); + } + else + { + // Filter out the ones that we haven't sent yet + var addedEpisodesLogIds = + _recentlyAddedLog.GetAll().Where(x => x.Type == repository.RecentlyAddedType && x.ContentType == ContentType.Episode); + episodesToSend = + FilterEpisodes(content, addedEpisodesLogIds); + } + + _log.LogInformation("Episodes to send: {0}", episodesToSend.Count()); + return episodesToSend; + + } + private HashSet GetMusicContent(IExternalRepository repository, bool test) + { + + var lidarrContent = repository.GetAll().AsNoTracking().ToList().Where(x => x.FullyAvailable); + + HashSet albumsToSend; + if (test) + { + albumsToSend = lidarrContent.OrderByDescending(x => x.AddedAt).Take(10).ToHashSet(); + } + else + { + // Filter out the ones that we haven't sent yet + var addedLog = _recentlyAddedLog.GetAll().ToList(); + HashSet addedAlbumLogIds; + GetRecentlyAddedMoviesData(addedLog, out addedAlbumLogIds); + albumsToSend = lidarrContent.Where(x => !addedAlbumLogIds.Contains(x.ForeignAlbumId)).ToHashSet(); + } + _log.LogInformation("Albums to send: {0}", albumsToSend.Count()); + return albumsToSend; + + } + public static string GenerateUnsubscribeLink(string applicationUrl, string id) { if (!applicationUrl.HasValue() || !id.HasValue()) @@ -405,49 +367,21 @@ namespace Ombi.Schedule.Jobs.Ombi return b.ToString(); } - private async Task> GetMoviesWithoutId(HashSet addedMovieLogIds, HashSet needsMovieDbPlex) + private async Task> GetMoviesWithoutId(HashSet addedMovieLogIds, HashSet needsMovieDb, IMediaServerContentRepository repository) where T : class, IMediaServerContent { - foreach (var movie in needsMovieDbPlex) + foreach (var movie in needsMovieDb) { var id = await _refreshMetadata.GetTheMovieDbId(false, true, null, movie.ImdbId, movie.Title, true); movie.TheMovieDbId = id.ToString(); } - var result = needsMovieDbPlex.Where(x => x.HasTheMovieDb && !addedMovieLogIds.Contains(StringHelper.IntParseLinq(x.TheMovieDbId))); - await UpdateTheMovieDbId(result); + var result = needsMovieDb.Where(x => x.HasTheMovieDb && !addedMovieLogIds.Contains(StringHelper.IntParseLinq(x.TheMovieDbId))); + await UpdateTheMovieDbId(result, repository); // Filter them out now return result.ToHashSet(); } - private async Task> GetMoviesWithoutId(HashSet addedMovieLogIds, HashSet needsMovieDbPlex) - { - foreach (var movie in needsMovieDbPlex) - { - var id = await _refreshMetadata.GetTheMovieDbId(false, true, null, movie.ImdbId, movie.Title, true); - movie.TheMovieDbId = id.ToString(); - } - - var result = needsMovieDbPlex.Where(x => x.HasTheMovieDb && !addedMovieLogIds.Contains(StringHelper.IntParseLinq(x.TheMovieDbId))); - await UpdateTheMovieDbId(result); - // Filter them out now - return result.ToHashSet(); - } - - private async Task> GetMoviesWithoutId(HashSet addedMovieLogIds, HashSet needsMovieDbJellyfin) - { - foreach (var movie in needsMovieDbJellyfin) - { - var id = await _refreshMetadata.GetTheMovieDbId(false, true, null, movie.ImdbId, movie.Title, true); - movie.TheMovieDbId = id.ToString(); - } - - var result = needsMovieDbJellyfin.Where(x => x.HasTheMovieDb && !addedMovieLogIds.Contains(StringHelper.IntParseLinq(x.TheMovieDbId))); - await UpdateTheMovieDbId(result); - // Filter them out now - return result.ToHashSet(); - } - - private async Task UpdateTheMovieDbId(IEnumerable content) + private async Task UpdateTheMovieDbId(IEnumerable content, IMediaServerContentRepository repository) where T : class, IMediaServerContent { foreach (var movie in content) { @@ -455,45 +389,15 @@ namespace Ombi.Schedule.Jobs.Ombi { continue; } - var entity = await _plex.Find(movie.Id); + var entity = await repository.Find(movie.Id); if (entity == null) { return; } entity.TheMovieDbId = movie.TheMovieDbId; - _plex.UpdateWithoutSave(entity); + repository.UpdateWithoutSave(entity); } - await _plex.SaveChangesAsync(); - } - - private async Task UpdateTheMovieDbId(IEnumerable content) - { - foreach (var movie in content) - { - if (!movie.HasTheMovieDb) - { - continue; - } - var entity = await _emby.Find(movie.Id); - entity.TheMovieDbId = movie.TheMovieDbId; - _emby.UpdateWithoutSave(entity); - } - await _plex.SaveChangesAsync(); - } - - private async Task UpdateTheMovieDbId(IEnumerable content) - { - foreach (var movie in content) - { - if (!movie.HasTheMovieDb) - { - continue; - } - var entity = await _jellyfin.Find(movie.Id); - entity.TheMovieDbId = movie.TheMovieDbId; - _jellyfin.UpdateWithoutSave(entity); - } - await _plex.SaveChangesAsync(); + await repository.SaveChangesAsync(); } public async Task Execute(IJobExecutionContext job) @@ -502,44 +406,12 @@ namespace Ombi.Schedule.Jobs.Ombi await Start(newsletterSettings, false); } - private HashSet FilterPlexEpisodes(IEnumerable source, IEnumerable recentlyAdded) + private HashSet FilterEpisodes(IEnumerable source, IEnumerable recentlyAdded) { - var itemsToReturn = new HashSet(); - foreach (var ep in source.Where(x => x.Series.HasTvDb)) - { - var tvDbId = StringHelper.IntParseLinq(ep.Series.TvDbId); - if (recentlyAdded.Any(x => x.ContentId == tvDbId && x.EpisodeNumber == ep.EpisodeNumber && x.SeasonNumber == ep.SeasonNumber)) - { - continue; - } - - itemsToReturn.Add(ep); - } - - return itemsToReturn; - } - - private HashSet FilterEmbyEpisodes(IEnumerable source, IEnumerable recentlyAdded) - { - var itemsToReturn = new HashSet(); - foreach (var ep in source.Where(x => x.Series.HasTvDb)) - { - var tvDbId = StringHelper.IntParseLinq(ep.Series.TvDbId); - if (recentlyAdded.Any(x => x.ContentId == tvDbId && x.EpisodeNumber == ep.EpisodeNumber && x.SeasonNumber == ep.SeasonNumber)) - { - continue; - } - - itemsToReturn.Add(ep); - } - - return itemsToReturn; - } - - private HashSet FilterJellyfinEpisodes(IEnumerable source, IEnumerable recentlyAdded) - { - var itemsToReturn = new HashSet(); - foreach (var ep in source.Where(x => x.Series.HasTvDb)) + var itemsToReturn = new HashSet(); + foreach (var ep in source.Where(x => x.Series.HasTvDb // needed for recentlyAddedLog + && x.Series.HasTheMovieDb // needed to fetch info to publish, this is just in case... + )) { var tvDbId = StringHelper.IntParseLinq(ep.Series.TvDbId); if (recentlyAdded.Any(x => x.ContentId == tvDbId && x.EpisodeNumber == ep.EpisodeNumber && x.SeasonNumber == ep.SeasonNumber)) @@ -563,40 +435,22 @@ namespace Ombi.Schedule.Jobs.Ombi return resolver.ParseMessage(template, curlys); } - private async Task BuildHtml(IQueryable plexContentToSend, IQueryable embyContentToSend, IQueryable jellyfinContentToSend, - HashSet plexEpisodes, HashSet embyEp, HashSet jellyfinEp, HashSet albums, NewsletterSettings settings, EmbySettings embySettings, JellyfinSettings jellyfinSettings, - PlexSettings plexSettings) + private async Task BuildHtml(ICollection movies, + IEnumerable episodes, HashSet albums, NewsletterSettings settings) { var ombiSettings = await _ombiSettings.GetSettingsAsync(); - var sb = new StringBuilder(); + sb = new StringBuilder(); - var plexMovies = plexContentToSend.Where(x => x.Type == PlexMediaTypeEntity.Movie); - var embyMovies = embyContentToSend.Where(x => x.Type == EmbyMediaType.Movie); - var jellyfinMovies = jellyfinContentToSend.Where(x => x.Type == JellyfinMediaType.Movie); - if ((plexMovies.Any() || embyMovies.Any() || jellyfinMovies.Any()) && !settings.DisableMovies) + if (movies.Any() && !settings.DisableMovies) { - sb.Append("

New Movies



"); + sb.Append($"

{Texts.NewMovies}



"); sb.Append( ""); sb.Append(""); sb.Append(""); @@ -604,30 +458,16 @@ namespace Ombi.Schedule.Jobs.Ombi sb.Append("
"); sb.Append(""); sb.Append(""); - if (plexSettings.Enable) - { - await ProcessPlexMovies(plexMovies, sb, ombiSettings.DefaultLanguageCode, plexSettings.Servers.FirstOrDefault().ServerHostname ?? string.Empty); - } - - if (embySettings.Enable) - { - await ProcessEmbyMovies(embyMovies, sb, ombiSettings.DefaultLanguageCode, embySettings.Servers.FirstOrDefault()?.ServerHostname ?? string.Empty); - } - - if (jellyfinSettings.Enable) - { - await ProcessJellyfinMovies(jellyfinMovies, sb, ombiSettings.DefaultLanguageCode, jellyfinSettings.Servers.FirstOrDefault()?.ServerHostname ?? string.Empty); - } - + await ProcessMovies(movies, ombiSettings.DefaultLanguageCode); sb.Append(""); sb.Append("
"); sb.Append("
"); } - if ((plexEpisodes.Any() || embyEp.Any() || jellyfinEp.Any()) && !settings.DisableTv) + if (episodes.Any() && !settings.DisableTv) { - sb.Append("

New TV



"); + sb.Append($"

{Texts.NewTV}



"); sb.Append( ""); sb.Append(""); sb.Append(""); @@ -638,14 +478,14 @@ namespace Ombi.Schedule.Jobs.Ombi if (albums.Any() && !settings.DisableMusic) { - sb.Append("

New Albums



"); + sb.Append($"

{Texts.NewAlbums}



"); sb.Append( "
"); sb.Append(""); sb.Append(""); - if (plexSettings.Enable) - { - await ProcessPlexTv(plexEpisodes, sb, ombiSettings.DefaultLanguageCode, plexSettings.Servers.FirstOrDefault().ServerHostname ?? string.Empty); - } - - if (embySettings.Enable) - { - await ProcessEmbyTv(embyEp, sb, ombiSettings.DefaultLanguageCode, embySettings.Servers.FirstOrDefault()?.ServerHostname ?? string.Empty); - } - - if (jellyfinSettings.Enable) - { - await ProcessJellyfinTv(jellyfinEp, sb, ombiSettings.DefaultLanguageCode, jellyfinSettings.Servers.FirstOrDefault()?.ServerHostname ?? string.Empty); - } - + await ProcessTv(episodes, ombiSettings.DefaultLanguageCode); sb.Append(""); sb.Append("
"); sb.Append("
"); sb.Append(""); sb.Append(""); @@ -656,35 +496,32 @@ namespace Ombi.Schedule.Jobs.Ombi return sb.ToString(); } - private async Task ProcessPlexMovies(IQueryable plexContentToSend, StringBuilder sb, string defaultLanguageCode, string mediaServerUrl) + private async Task ProcessMovies(ICollection plexContentToSend, string defaultLanguageCode) { int count = 0; - var ordered = plexContentToSend.OrderByDescending(x => x.AddedAt); + var ordered = plexContentToSend; foreach (var content in ordered) { int.TryParse(content.TheMovieDbId, out var movieDbId); - if (movieDbId <= 0) - { - continue; - } var info = await _movieApi.GetMovieInformationWithExtraInfo(movieDbId, defaultLanguageCode); - var mediaurl = PlexHelper.BuildPlexMediaUrl(content.Url, mediaServerUrl); + var mediaurl = content.Url; if (info == null) { + _log.LogError($"TMDB does not know movie {content.Title}. This shouldn't happen because our media server knows it as ID '{movieDbId}'."); continue; } try { - CreateMovieHtmlContent(sb, info, mediaurl); + CreateMovieHtmlContent(info, mediaurl); count += 1; } catch (Exception e) { - _log.LogError(e, "Error when Processing Plex Movies {0}", info.Title); + _log.LogError(e, "Error when Processing Movies {0}", info.Title); } finally { - EndLoopHtml(sb); + EndLoopHtml(); } if (count == 2) @@ -695,7 +532,7 @@ namespace Ombi.Schedule.Jobs.Ombi } } } - private async Task ProcessAlbums(HashSet albumsToSend, StringBuilder sb) + private async Task ProcessAlbums(HashSet albumsToSend) { var settings = await _lidarrSettings.GetSettingsAsync(); int count = 0; @@ -709,7 +546,7 @@ namespace Ombi.Schedule.Jobs.Ombi } try { - CreateAlbumHtmlContent(sb, info); + CreateAlbumHtmlContent(info); count += 1; } catch (Exception e) @@ -718,7 +555,7 @@ namespace Ombi.Schedule.Jobs.Ombi } finally { - EndLoopHtml(sb); + EndLoopHtml(); } if (count == 2) @@ -730,119 +567,13 @@ namespace Ombi.Schedule.Jobs.Ombi } } - private async Task ProcessEmbyMovies(IQueryable embyContent, StringBuilder sb, string defaultLangaugeCode, string customUrl) + private void CreateMovieHtmlContent(MovieResponseDto info, string mediaurl) { - int count = 0; - var ordered = embyContent.OrderByDescending(x => x.AddedAt); - foreach (var content in ordered) - { - var theMovieDbId = content.TheMovieDbId; - if (!content.TheMovieDbId.HasValue()) - { - var imdbId = content.ImdbId; - var findResult = await _movieApi.Find(imdbId, ExternalSource.imdb_id); - var result = findResult.movie_results?.FirstOrDefault(); - if (result == null) - { - continue; - } + AddBackgroundInsideTable($"https://image.tmdb.org/t/p/w1280/{info.BackdropPath}"); + AddPosterInsideTable($"https://image.tmdb.org/t/p/original{info.PosterPath}"); - theMovieDbId = result.id.ToString(); - } - - var mediaurl = content.Url; - if (customUrl.HasValue()) - { - mediaurl = customUrl; - } - var info = await _movieApi.GetMovieInformationWithExtraInfo(StringHelper.IntParseLinq(theMovieDbId), defaultLangaugeCode); - if (info == null) - { - continue; - } - try - { - CreateMovieHtmlContent(sb, info, mediaurl); - count += 1; - } - catch (Exception e) - { - _log.LogError(e, "Error when processing Emby Movies {0}", info.Title); - } - finally - { - EndLoopHtml(sb); - } - - if (count == 2) - { - count = 0; - sb.Append(""); - sb.Append(""); - } - } - } - - private async Task ProcessJellyfinMovies(IQueryable embyContent, StringBuilder sb, string defaultLangaugeCode, string customUrl) - { - int count = 0; - var ordered = embyContent.OrderByDescending(x => x.AddedAt); - foreach (var content in ordered) - { - var theMovieDbId = content.TheMovieDbId; - if (!content.TheMovieDbId.HasValue()) - { - var imdbId = content.ImdbId; - var findResult = await _movieApi.Find(imdbId, ExternalSource.imdb_id); - var result = findResult.movie_results?.FirstOrDefault(); - if (result == null) - { - continue; - } - - theMovieDbId = result.id.ToString(); - } - - var mediaurl = content.Url; - if (customUrl.HasValue()) - { - mediaurl = customUrl; - } - var info = await _movieApi.GetMovieInformationWithExtraInfo(StringHelper.IntParseLinq(theMovieDbId), defaultLangaugeCode); - if (info == null) - { - continue; - } - try - { - CreateMovieHtmlContent(sb, info, mediaurl); - count += 1; - } - catch (Exception e) - { - _log.LogError(e, "Error when processing Jellyfin Movies {0}", info.Title); - } - finally - { - EndLoopHtml(sb); - } - - if (count == 2) - { - count = 0; - sb.Append(""); - sb.Append(""); - } - } - } - - private void CreateMovieHtmlContent(StringBuilder sb, MovieResponseDto info, string mediaurl) - { - AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w1280/{info.BackdropPath}"); - AddPosterInsideTable(sb, $"https://image.tmdb.org/t/p/original{info.PosterPath}"); - - AddMediaServerUrl(sb, mediaurl, $"https://image.tmdb.org/t/p/original{info.PosterPath}"); - AddInfoTable(sb); + AddMediaServerUrl(mediaurl, $"https://image.tmdb.org/t/p/original{info.PosterPath}"); + AddInfoTable(); var releaseDate = string.Empty; try @@ -856,7 +587,7 @@ namespace Ombi.Schedule.Jobs.Ombi // Swallow, couldn't parse the date } - AddTitle(sb, $"https://www.imdb.com/title/{info.ImdbId}/", $"{info.Title} {releaseDate}"); + AddTitle($"https://www.imdb.com/title/{info.ImdbId}/", $"{info.Title} {releaseDate}"); var summary = info.Overview; if (summary.Length > 280) @@ -864,16 +595,15 @@ namespace Ombi.Schedule.Jobs.Ombi summary = summary.Remove(280); summary = summary + "...

"; } - AddParagraph(sb, summary); + AddParagraph(summary); if (info.Genres.Any()) { - AddGenres(sb, - $"Genres: {string.Join(", ", info.Genres.Select(x => x.Name.ToString()).ToArray())}"); + AddGenres($"{Texts.GenresLabel} {string.Join(", ", info.Genres.Select(x => x.Name.ToString()).ToArray())}"); } } - private void CreateAlbumHtmlContent(StringBuilder sb, AlbumLookup info) + private void CreateAlbumHtmlContent(AlbumLookup info) { var cover = info.images .FirstOrDefault(x => x.coverType.Equals("cover", StringComparison.InvariantCultureIgnoreCase))?.url; @@ -881,21 +611,21 @@ namespace Ombi.Schedule.Jobs.Ombi { cover = info.remoteCover; } - AddBackgroundInsideTable(sb, cover); + AddBackgroundInsideTable(cover); var disk = info.images .FirstOrDefault(x => x.coverType.Equals("disc", StringComparison.InvariantCultureIgnoreCase))?.url; if (disk.IsNullOrEmpty()) { disk = info.remoteCover; } - AddPosterInsideTable(sb, disk); + AddPosterInsideTable(disk); - AddMediaServerUrl(sb, string.Empty, string.Empty); - AddInfoTable(sb); + AddMediaServerUrl(string.Empty, string.Empty); + AddInfoTable(); var releaseDate = $"({info.releaseDate.Year})"; - AddTitle(sb, string.Empty, $"{info.title} {releaseDate}"); + AddTitle(string.Empty, $"{info.title} {releaseDate}"); var summary = info.artist?.artistName ?? string.Empty; if (summary.Length > 280) @@ -903,155 +633,27 @@ namespace Ombi.Schedule.Jobs.Ombi summary = summary.Remove(280); summary = summary + "...

"; } - AddParagraph(sb, summary); + AddParagraph(summary); - AddGenres(sb, $"Type: {info.albumType}"); + AddGenres($"{Texts.AlbumTypeLabel} {info.albumType}"); } - private async Task ProcessPlexTv(HashSet plexContent, StringBuilder sb, string languageCode, string serverHostname) + private async Task ProcessTv(IEnumerable episodes, string languageCode) { - var series = new List(); - foreach (var plexEpisode in plexContent) + var series = new List(); + foreach (var episode in episodes) { - var alreadyAdded = series.FirstOrDefault(x => x.Key == plexEpisode.Series.Key); - if (alreadyAdded != null) + var existingSeries = episode.SeriesIsIn(series); + if (existingSeries != null) { - var episodeExists = alreadyAdded.Episodes.Any(x => x.Key == plexEpisode.Key); - if (!episodeExists) + if (!episode.IsIn(existingSeries)) { - alreadyAdded.Episodes.Add(plexEpisode); + existingSeries.Episodes.Add(episode); } } else { - plexEpisode.Series.Episodes = new List { plexEpisode }; - series.Add(plexEpisode.Series); - } - } - - int count = 0; - var orderedTv = series.OrderByDescending(x => x.AddedAt); - foreach (var t in orderedTv) - { - if (!t.HasTvDb) - { - // We may need to use themoviedb for the imdbid or their own id to get info - if (t.HasTheMovieDb) - { - int.TryParse(t.TheMovieDbId, out var movieId); - var externals = await _movieApi.GetTvExternals(movieId); - if (externals == null || externals.tvdb_id <= 0) - { - continue; - } - t.TvDbId = externals.tvdb_id.ToString(); - } - // WE could check the below but we need to get the moviedb and then perform the above, let the metadata job figure this out. - //else if(t.HasImdb) - //{ - // // Check the imdbid - // var externals = await _movieApi.Find(t.ImdbId, ExternalSource.imdb_id); - // if (externals?.tv_results == null || externals.tv_results.Length <= 0) - // { - // continue; - // } - // t.TvDbId = externals.tv_results.FirstOrDefault()..ToString(); - //} - - } - - int.TryParse(t.TvDbId, out var tvdbId); - var info = await _tvApi.ShowLookupByTheTvDbId(tvdbId); - if (info == null) - { - continue; - } - - try - { - var banner = info.image?.original; - if (!string.IsNullOrEmpty(banner)) - { - banner = banner.ToHttpsUrl(); // Always use the Https banners - } - - var tvInfo = await _movieApi.GetTVInfo(t.TheMovieDbId, languageCode); - if (tvInfo != null && tvInfo.backdrop_path.HasValue()) - { - - AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w500{tvInfo.backdrop_path}"); - } - else - { - AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w1280/"); - } - AddPosterInsideTable(sb, banner); - AddMediaServerUrl(sb, PlexHelper.BuildPlexMediaUrl(t.Url, serverHostname), banner); - AddInfoTable(sb); - - AddTvTitle(sb, info, tvInfo); - - // Group by the season number - var results = t.Episodes.GroupBy(p => p.SeasonNumber, - (key, g) => new - { - SeasonNumber = key, - Episodes = g.ToList(), - EpisodeAirDate = tvInfo?.seasons?.Where(x => x.season_number == key)?.Select(x => x.air_date).FirstOrDefault() - } - ); - - // Group the episodes - var finalsb = new StringBuilder(); - foreach (var epInformation in results.OrderBy(x => x.SeasonNumber)) - { - var orderedEpisodes = epInformation.Episodes.OrderBy(x => x.EpisodeNumber).ToList(); - var episodeString = StringHelper.BuildEpisodeList(orderedEpisodes.Select(x => x.EpisodeNumber)); - var episodeAirDate = epInformation.EpisodeAirDate; - finalsb.Append($"Season: {epInformation.SeasonNumber} - Episodes: {episodeString} {episodeAirDate}"); - finalsb.Append("
"); - } - - AddTvEpisodesSummaryGenres(sb, finalsb.ToString(), tvInfo); - - } - catch (Exception e) - { - _log.LogError(e, "Error when processing Plex TV {0}", t.Title); - } - finally - { - EndLoopHtml(sb); - count += 1; - } - - if (count == 2) - { - count = 0; - sb.Append("
"); - sb.Append(""); - } - } - } - - - - private async Task ProcessEmbyTv(HashSet embyContent, StringBuilder sb, string languageCode, string serverUrl) - { - var series = new List(); - foreach (var episode in embyContent) - { - var alreadyAdded = series.FirstOrDefault(x => x.EmbyId == episode.Series.EmbyId); - if (alreadyAdded != null) - { - alreadyAdded.Episodes.Add(episode); - } - else - { - episode.Series.Episodes = new List - { - episode - }; + episode.Series.Episodes = new List { episode }; series.Add(episode.Series); } } @@ -1060,73 +662,48 @@ namespace Ombi.Schedule.Jobs.Ombi var orderedTv = series.OrderByDescending(x => x.AddedAt); foreach (var t in orderedTv) { - if (!t.TvDbId.HasValue()) - { - continue; - } - - int.TryParse(t.TvDbId, out var tvdbId); - var info = await _tvApi.ShowLookupByTheTvDbId(tvdbId); - if (info == null) - { - continue; - } - try { - var banner = info.image?.original; - if (!string.IsNullOrEmpty(banner)) + var tvInfo = await _movieApi.GetTVInfo(t.TheMovieDbId, languageCode); + if (tvInfo == null) { - banner = banner.ToHttpsUrl(); // Always use the Https banners + _log.LogError($"TMDB does not know series {t.Title}. This shouldn't happen because our media server knows it as ID '{t.TheMovieDbId}'."); + continue; } - var tvInfo = await _movieApi.GetTVInfo(t.TheMovieDbId, languageCode); - if (tvInfo != null && tvInfo.backdrop_path.HasValue()) - { - AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w500{tvInfo.backdrop_path}"); + if (tvInfo.backdrop_path.HasValue()) + { + AddBackgroundInsideTable($"https://image.tmdb.org/t/p/w500{tvInfo.backdrop_path}"); } else { - AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w1280/"); + AddBackgroundInsideTable($"https://image.tmdb.org/t/p/w1280/"); } - AddPosterInsideTable(sb, banner); - AddMediaServerUrl(sb, serverUrl.HasValue() ? serverUrl : t.Url, banner); - AddInfoTable(sb); - AddTvTitle(sb, info, tvInfo); - - // Group by the season number - var results = t.Episodes?.GroupBy(p => p.SeasonNumber, - (key, g) => new - { - SeasonNumber = key, - Episodes = g.ToList(), - EpisodeAirDate = tvInfo?.seasons?.Where(x => x.season_number == key)?.Select(x => x.air_date).FirstOrDefault() - } - ); - - // Group the episodes - var finalsb = new StringBuilder(); - foreach (var epInformation in results.OrderBy(x => x.SeasonNumber)) + var banner = tvInfo.poster_path; + if (!string.IsNullOrEmpty(banner)) { - var orderedEpisodes = epInformation.Episodes.OrderBy(x => x.EpisodeNumber).ToList(); - var episodeString = StringHelper.BuildEpisodeList(orderedEpisodes.Select(x => x.EpisodeNumber)); - var episodeAirDate = epInformation.EpisodeAirDate; - finalsb.Append($"Season: {epInformation.SeasonNumber} - Episodes: {episodeString} {episodeAirDate}"); - finalsb.Append("
"); - } + banner = $"https://image.tmdb.org/t/p/w300/{banner?.TrimStart('/') ?? string.Empty}"; + }; + AddPosterInsideTable(banner); + AddMediaServerUrl(t.Url, banner); - AddTvEpisodesSummaryGenres(sb, finalsb.ToString(), tvInfo); + AddInfoTable(); + + AddTvTitle(tvInfo); + + var tvEpisodesString = GetTvEpisodesString(tvInfo, t.Episodes); + AddTvEpisodesSummaryGenres(tvEpisodesString, tvInfo); } catch (Exception e) { - _log.LogError(e, "Error when processing Emby TV {0}", t.Title); + _log.LogError(e, "Error when processing TV {0}", t.Title); } finally { - EndLoopHtml(sb); + EndLoopHtml(); count += 1; } @@ -1139,124 +716,59 @@ namespace Ombi.Schedule.Jobs.Ombi } } - private async Task ProcessJellyfinTv(HashSet jellyfinContent, StringBuilder sb, string languageCode, string serverUrl) + private string GetTvEpisodesString(TvInfo tvInfo, ICollection episodes) { - var series = new List(); - foreach (var episode in jellyfinContent) + if (episodes.Count >= tvInfo.number_of_episodes) { - var alreadyAdded = series.FirstOrDefault(x => x.JellyfinId == episode.Series.JellyfinId); - if (alreadyAdded != null) + // do not list individual episodes when the series is complete + return string.Empty; + } + + var sb = new StringBuilder(); + // Group by the season number + var seasons = episodes.GroupBy(p => p.SeasonNumber, + (key, g) => new { - alreadyAdded.Episodes.Add(episode); + SeasonNumber = key, + Episodes = g.ToList(), + Header = tvInfo?.seasons?.Where(x => x.season_number == key).FirstOrDefault(), + } + ); + // Group the episodes + foreach (var season in seasons.OrderBy(x => x.SeasonNumber)) + { + string episodeList; + if (season.Episodes.Count >= season.Header.episode_count) + { + // do not list individual episodes when the season is complete + episodeList = string.Empty; } else { - episode.Series.Episodes = new List - { - episode - }; - series.Add(episode.Series); - } - } - - int count = 0; - var orderedTv = series.OrderByDescending(x => x.AddedAt); - foreach (var t in orderedTv) - { - if (!t.TvDbId.HasValue()) - { - continue; - } - - int.TryParse(t.TvDbId, out var tvdbId); - var info = await _tvApi.ShowLookupByTheTvDbId(tvdbId); - if (info == null) - { - continue; - } - - try - { - var banner = info.image?.original; - if (!string.IsNullOrEmpty(banner)) - { - banner = banner.ToHttpsUrl(); // Always use the Https banners - } - - var tvInfo = await _movieApi.GetTVInfo(t.TheMovieDbId, languageCode); - if (tvInfo != null && tvInfo.backdrop_path.HasValue()) - { - - AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w500{tvInfo.backdrop_path}"); - } - else - { - AddBackgroundInsideTable(sb, $"https://image.tmdb.org/t/p/w1280/"); - } - AddPosterInsideTable(sb, banner); - AddMediaServerUrl(sb, serverUrl.HasValue() ? serverUrl : t.Url, banner); - AddInfoTable(sb); - - AddTvTitle(sb, info, tvInfo); - - // Group by the season number - var results = t.Episodes?.GroupBy(p => p.SeasonNumber, - (key, g) => new - { - SeasonNumber = key, - Episodes = g.ToList(), - EpisodeAirDate = tvInfo?.seasons?.Where(x => x.season_number == key)?.Select(x => x.air_date).FirstOrDefault() - } - ); - - // Group the episodes - var finalsb = new StringBuilder(); - foreach (var epInformation in results.OrderBy(x => x.SeasonNumber)) - { - var orderedEpisodes = epInformation.Episodes.OrderBy(x => x.EpisodeNumber).ToList(); - var episodeString = StringHelper.BuildEpisodeList(orderedEpisodes.Select(x => x.EpisodeNumber)); - var episodeAirDate = epInformation.EpisodeAirDate; - finalsb.Append($"Season: {epInformation.SeasonNumber} - Episodes: {episodeString} {episodeAirDate}"); - finalsb.Append("
"); - } - - AddTvEpisodesSummaryGenres(sb, finalsb.ToString(), tvInfo); - - } - catch (Exception e) - { - _log.LogError(e, "Error when processing Jellyfin TV {0}", t.Title); - } - finally - { - EndLoopHtml(sb); - count += 1; - } - - if (count == 2) - { - count = 0; - sb.Append("
"); - sb.Append(""); + var orderedEpisodes = season.Episodes.OrderBy(x => x.EpisodeNumber).ToList(); + episodeList = $"{Texts.EpisodesLabel} {StringHelper.BuildEpisodeList(orderedEpisodes.Select(x => x.EpisodeNumber))}"; } + var episodeAirDate = season.Header.air_date; + sb.Append($"{Texts.SeasonLabel} {season.SeasonNumber} - {episodeList} {episodeAirDate}"); + sb.Append("
"); } + return sb.ToString(); } - - private void AddTvTitle(StringBuilder sb, Api.TvMaze.Models.TvMazeShow info, TvInfo tvInfo) + private void AddTvTitle(TvInfo tvInfo) { var title = ""; - if (!String.IsNullOrEmpty(info.premiered) && info.premiered.Length > 4) + if (!String.IsNullOrEmpty(tvInfo.first_air_date) && tvInfo.first_air_date.Length > 4) { - title = $"{tvInfo.name} ({info.premiered.Remove(4)})"; + title = $"{tvInfo.name} ({tvInfo.first_air_date.Remove(4)})"; } else { title = $"{tvInfo.name}"; } - AddTitle(sb, $"https://www.imdb.com/title/{info.externals.imdb}/", title); + AddTitle($"https://www.themoviedb.org/tv/{tvInfo.id}/", title); } - private void AddTvEpisodesSummaryGenres(StringBuilder sb, string episodes, TvInfo tvInfo) + private void AddTvEpisodesSummaryGenres(string episodes, TvInfo tvInfo) { var summary = tvInfo.overview; if (summary.Length > 280) @@ -1264,15 +776,15 @@ namespace Ombi.Schedule.Jobs.Ombi summary = summary.Remove(280); summary = summary + "...

"; } - AddTvParagraph(sb, episodes, summary); + AddTvParagraph(episodes, summary); if (tvInfo.genres.Any()) { - AddGenres(sb, $"Genres: {string.Join(", ", tvInfo.genres.Select(x => x.name.ToString()).ToArray())}"); + AddGenres($"{Texts.GenresLabel} {string.Join(", ", tvInfo.genres.Select(x => x.name.ToString()).ToArray())}"); } } - private void EndLoopHtml(StringBuilder sb) + private void EndLoopHtml() { //NOTE: BR have to be in TD's as per html spec or it will be put outside of the table... //Source: http://stackoverflow.com/questions/6588638/phantom-br-tag-rendered-by-browsers-prior-to-table-tag @@ -1299,7 +811,7 @@ namespace Ombi.Schedule.Jobs.Ombi return false; } } - if (string.IsNullOrEmpty(settings.Host) || string.IsNullOrEmpty(settings.AdminEmail) || string.IsNullOrEmpty(settings.Port.ToString())) + if (string.IsNullOrEmpty(settings.Host) || string.IsNullOrEmpty(settings.Port.ToString())) { return false; } diff --git a/src/Ombi.Schedule/Jobs/Ombi/OmbiAutomaticUpdater.cs b/src/Ombi.Schedule/Jobs/Ombi/OmbiAutomaticUpdater.cs index c2cf42441..4489a045e 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/OmbiAutomaticUpdater.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/OmbiAutomaticUpdater.cs @@ -321,7 +321,9 @@ namespace Ombi.Schedule.Jobs.Ombi public async Task DownloadAsync(string requestUri, string filename) { Logger.LogDebug(LoggingEvents.Updater, "Starting the DownloadAsync"); +#pragma warning disable SYSLIB0014 // Type or member is obsolete using (var client = new WebClient()) +#pragma warning restore SYSLIB0014 // Type or member is obsolete { await client.DownloadFileTaskAsync(requestUri, filename); } diff --git a/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs b/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs index a24d07da0..64abb2aac 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/RefreshMetadata.cs @@ -7,6 +7,7 @@ using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Ombi.Api.Emby; using Ombi.Api.Jellyfin; +using Ombi.Api.Plex; using Ombi.Api.TheMovieDb; using Ombi.Api.TheMovieDb.Models; using Ombi.Api.TvMaze; @@ -30,7 +31,8 @@ namespace Ombi.Schedule.Jobs.Ombi IMovieDbApi movieApi, ISettingsService embySettings, IEmbyApiFactory embyApi, ISettingsService jellyfinSettings, IJellyfinApiFactory jellyfinApi, - IHubContext notification, IMediaCacheService mediaCacheService) + IHubContext notification, IMediaCacheService mediaCacheService, + IPlexApi plexApi) { _plexRepo = plexRepo; _embyRepo = embyRepo; @@ -45,6 +47,7 @@ namespace Ombi.Schedule.Jobs.Ombi _jellyfinApiFactory = jellyfinApi; _notification = notification; _mediaCacheService = mediaCacheService; + _plexApi = plexApi; } private readonly IPlexContentRepository _plexRepo; @@ -60,6 +63,7 @@ namespace Ombi.Schedule.Jobs.Ombi private readonly IJellyfinApiFactory _jellyfinApiFactory; private readonly IHubContext _notification; private readonly IMediaCacheService _mediaCacheService; + private readonly IPlexApi _plexApi; private IEmbyApi EmbyApi { get; set; } private IJellyfinApi JellyfinApi { get; set; } @@ -75,7 +79,7 @@ namespace Ombi.Schedule.Jobs.Ombi var settings = await _plexSettings.GetSettingsAsync(); if (settings.Enable) { - await StartPlex(); + await StartPlex(settings); await OmbiQuartz.TriggerJob(nameof(IPlexAvailabilityChecker), "Plex"); } @@ -112,16 +116,16 @@ namespace Ombi.Schedule.Jobs.Ombi .SendAsync(NotificationHub.NotificationEvent, "Metadata Refresh Finished"); } - private async Task StartPlex() + private async Task StartPlex(PlexSettings settings) { // Ensure we check that we have not linked this item to a request var allMovies = await _plexRepo.GetAll().Where(x => - x.Type == PlexMediaTypeEntity.Movie && x.RequestId == null && (x.TheMovieDbId == null || x.ImdbId == null)).ToListAsync(); - await StartPlexMovies(allMovies); + x.Type == MediaType.Movie && x.RequestId == null && ((x.TheMovieDbId == null || x.TheMovieDbId == string.Empty ) || (x.ImdbId == null || x.ImdbId == string.Empty))).ToListAsync(); + await StartPlexMovies(allMovies, settings); // Now Tv var allTv = await _plexRepo.GetAll().Where(x => - x.Type == PlexMediaTypeEntity.Show && x.RequestId == null && (x.TheMovieDbId == null || x.ImdbId == null || x.TvDbId == null)).ToListAsync(); + x.Type == MediaType.Series && x.RequestId == null && (x.TheMovieDbId == null || x.ImdbId == null || x.TvDbId == null)).ToListAsync(); await StartPlexTv(allTv); } @@ -178,7 +182,7 @@ namespace Ombi.Schedule.Jobs.Ombi private async Task StartEmbyTv() { var allTv = await _embyRepo.GetAll().Where(x => - x.Type == EmbyMediaType.Series && (x.TheMovieDbId == null || x.ImdbId == null || x.TvDbId == null)).ToListAsync(); + x.Type == MediaType.Series && (x.TheMovieDbId == null || x.ImdbId == null || x.TvDbId == null)).ToListAsync(); foreach (var show in allTv) { @@ -213,7 +217,7 @@ namespace Ombi.Schedule.Jobs.Ombi private async Task StartJellyfinTv() { var allTv = await _jellyfinRepo.GetAll().Where(x => - x.Type == JellyfinMediaType.Series && (x.TheMovieDbId == null || x.ImdbId == null || x.TvDbId == null)).ToListAsync(); + x.Type == MediaType.Series && (x.TheMovieDbId == null || x.ImdbId == null || x.TvDbId == null)).ToListAsync(); foreach (var show in allTv) { @@ -245,7 +249,7 @@ namespace Ombi.Schedule.Jobs.Ombi } } - private async Task StartPlexMovies(List allMovies) + private async Task StartPlexMovies(List allMovies, PlexSettings settings) { foreach (var movie in allMovies) { @@ -261,14 +265,58 @@ namespace Ombi.Schedule.Jobs.Ombi if (!hasImdb) { var imdbId = await GetImdbId(hasTheMovieDb, false, movie.Title, movie.TheMovieDbId, string.Empty, RequestType.Movie); - movie.ImdbId = imdbId; - _plexRepo.UpdateWithoutSave(movie); + if (imdbId.HasValue()) + { + movie.ImdbId = imdbId; + hasImdb = true; + _plexRepo.UpdateWithoutSave(movie); + } } if (!hasTheMovieDb) { var id = await GetTheMovieDbId(false, hasImdb, string.Empty, movie.ImdbId, movie.Title, true); - movie.TheMovieDbId = id; - _plexRepo.UpdateWithoutSave(movie); + if (id.HasValue()) + { + movie.TheMovieDbId = id; + hasTheMovieDb = true; + _plexRepo.UpdateWithoutSave(movie); + } + } + if (!hasTheMovieDb || !hasImdb) + { + // Check to see if the Plex item has anything + if (!settings.Servers.Any()) + { + continue; + } + var servers = settings.Servers[0]; + var metaData = await _plexApi.GetMetadata(servers.PlexAuthToken, settings.Servers[0].FullUri, movie.Key); + var guids = new List(); + + var meta = metaData.MediaContainer.Metadata.FirstOrDefault(); + guids.Add(meta.guid); + if (meta.Guid != null) + { + foreach (var g in meta.Guid) + { + guids.Add(g.Id); + } + } + + var providerIds = PlexHelper.GetProviderIdsFromMetadata(guids.ToArray()); + if (providerIds.Any()) + { + if (providerIds.TheMovieDb.HasValue() && !hasTheMovieDb) + { + movie.TheMovieDbId = providerIds.TheMovieDb; + _plexRepo.UpdateWithoutSave(movie); + } + if (providerIds.ImdbId.HasValue() && !hasImdb) + { + movie.ImdbId = providerIds.ImdbId; + _plexRepo.UpdateWithoutSave(movie); + } + } } await _plexRepo.SaveChangesAsync(); @@ -278,7 +326,7 @@ namespace Ombi.Schedule.Jobs.Ombi private async Task StartEmbyMovies(EmbySettings settings) { var allMovies = await _embyRepo.GetAll().Where(x => - x.Type == EmbyMediaType.Movie && (x.TheMovieDbId == null || x.ImdbId == null)).ToListAsync(); + x.Type == MediaType.Movie && (x.TheMovieDbId == null || x.ImdbId == null)).ToListAsync(); foreach (var movie in allMovies) { movie.ImdbId.HasValue(); @@ -333,7 +381,7 @@ namespace Ombi.Schedule.Jobs.Ombi private async Task StartJellyfinMovies(JellyfinSettings settings) { var allMovies = await _jellyfinRepo.GetAll().Where(x => - x.Type == JellyfinMediaType.Movie && (x.TheMovieDbId == null || x.ImdbId == null)).ToListAsync(); + x.Type == MediaType.Movie && (x.TheMovieDbId == null || x.ImdbId == null)).ToListAsync(); foreach (var movie in allMovies) { movie.ImdbId.HasValue(); @@ -447,17 +495,20 @@ namespace Ombi.Schedule.Jobs.Ombi default: break; } - + } } if (hasTvDbId && type == RequestType.TvShow) { _log.LogInformation("The show {0} has tvdbid but not ImdbId, searching for ImdbId", title); - if (int.TryParse(tvDbId, out var id)) + + var result = await _movieApi.Find(tvDbId.ToString(), ExternalSource.tvdb_id); + var movieDbId = result.tv_results.FirstOrDefault()?.id ?? 0; + if (movieDbId != 0) { - var result = await _tvApi.ShowLookupByTheTvDbId(id); - return result?.externals?.imdb; + var externalsResult = await _movieApi.GetTvExternals(movieDbId); + return externalsResult.imdb_id; } } return string.Empty; diff --git a/src/Ombi.Schedule/Jobs/Ombi/ResendFailedRequests.cs b/src/Ombi.Schedule/Jobs/Ombi/ResendFailedRequests.cs index 3a9a75835..e0df3752c 100644 --- a/src/Ombi.Schedule/Jobs/Ombi/ResendFailedRequests.cs +++ b/src/Ombi.Schedule/Jobs/Ombi/ResendFailedRequests.cs @@ -49,7 +49,9 @@ namespace Ombi.Schedule.Jobs.Ombi await _requestQueue.SaveChangesAsync(); continue; } - var result = await _movieSender.Send(movieRequest); + + // TODO probably need to add something to the request queue to better idenitfy if it's a 4k request + var result = await _movieSender.Send(movieRequest, movieRequest.Approved4K); if (result.Success) { request.Completed = DateTime.UtcNow; diff --git a/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexWatchlistImport.cs b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexWatchlistImport.cs new file mode 100644 index 000000000..2dd6d46e4 --- /dev/null +++ b/src/Ombi.Schedule/Jobs/Plex/Interfaces/IPlexWatchlistImport.cs @@ -0,0 +1,6 @@ +namespace Ombi.Schedule.Jobs.Plex +{ + public interface IPlexWatchlistImport : IBaseJob + { + } +} \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Plex/Models/ProcessedContent.cs b/src/Ombi.Schedule/Jobs/Plex/Models/ProcessedContent.cs index fc46e88b7..84748c1f7 100644 --- a/src/Ombi.Schedule/Jobs/Plex/Models/ProcessedContent.cs +++ b/src/Ombi.Schedule/Jobs/Plex/Models/ProcessedContent.cs @@ -5,7 +5,7 @@ namespace Ombi.Schedule.Jobs.Plex.Models { public class ProcessedContent { - public IEnumerable Content { get; set; } + public IEnumerable Content { get; set; } public IEnumerable Episodes { get; set; } public bool HasProcessedContent => Content?.Any() ?? false; diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs b/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs index 7a05f794b..e686c6dee 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexAvailabilityChecker.cs @@ -6,10 +6,12 @@ using Microsoft.AspNetCore.SignalR; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; using Ombi.Core; +using Ombi.Core.Services; using Ombi.Helpers; using Ombi.Hubs; using Ombi.Notifications.Models; using Ombi.Schedule.Jobs.Plex.Models; +using Ombi.Settings.Settings.Models; using Ombi.Store.Entities; using Ombi.Store.Entities.Requests; using Ombi.Store.Repository; @@ -21,7 +23,7 @@ namespace Ombi.Schedule.Jobs.Plex public class PlexAvailabilityChecker : IPlexAvailabilityChecker { public PlexAvailabilityChecker(IPlexContentRepository repo, ITvRequestRepository tvRequest, IMovieRequestRepository movies, - INotificationHelper notification, ILogger log, IHubContext hub) + INotificationHelper notification, ILogger log, IHubContext hub, IFeatureService featureService) { _tvRepo = tvRequest; _repo = repo; @@ -29,6 +31,7 @@ namespace Ombi.Schedule.Jobs.Plex _notificationService = notification; _log = log; _notification = hub; + _featureService = featureService; } private readonly ITvRequestRepository _tvRepo; @@ -37,6 +40,7 @@ namespace Ombi.Schedule.Jobs.Plex private readonly INotificationHelper _notificationService; private readonly ILogger _log; private readonly IHubContext _notification; + private readonly IFeatureService _featureService; public async Task Execute(IJobExecutionContext job) { @@ -86,7 +90,7 @@ namespace Ombi.Schedule.Jobs.Plex var tvDbId = child.ParentRequest.TvDbId; var imdbId = child.ParentRequest.ImdbId; - IQueryable seriesEpisodes = null; + IQueryable seriesEpisodes = null; if (useImdb) { seriesEpisodes = plexEpisodes.Where(x => x.Series.ImdbId == imdbId.ToString()); @@ -105,8 +109,7 @@ namespace Ombi.Schedule.Jobs.Plex { // Let's try and match the series by name seriesEpisodes = plexEpisodes.Where(x => - x.Series.Title == child.Title && - x.Series.ReleaseYear == child.ParentRequest.ReleaseDate.Year.ToString()); + x.Series.Title == child.Title); } @@ -180,17 +183,14 @@ namespace Ombi.Schedule.Jobs.Plex private async Task ProcessMovies() { + var feature4kEnabled = await _featureService.FeatureEnabled(FeatureNames.Movie4KRequests); // Get all non available - var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available); + var movies = _movieRepo.GetAll().Include(x => x.RequestedUser).Where(x => !x.Available || (!x.Available4K && x.Has4KRequest)); var itemsForAvailbility = new List(); foreach (var movie in movies) { - if (movie.Available) - { - return; - } - + var has4kRequest = movie.Has4KRequest; PlexServerContent item = null; if (movie.ImdbId.HasValue()) { @@ -209,23 +209,49 @@ namespace Ombi.Schedule.Jobs.Plex continue; } - _log.LogInformation("[PAC] - Movie request {0} is now available, sending notification", $"{movie.Title} - {movie.Id}"); - movie.Available = true; - movie.MarkedAsAvailable = DateTime.UtcNow; - itemsForAvailbility.Add(new AvailabilityModel + _log.LogInformation($"[PAC] - Movie request {movie.Title} - {movie.Id} is now available, sending notification"); + + var notify = false; + + if (has4kRequest && item.Has4K && !movie.Available4K && feature4kEnabled) { - Id = movie.Id, - RequestedUser = movie.RequestedUser != null ? movie.RequestedUser.Email : string.Empty - }); + movie.Available4K = true; + movie.Approved4K = true; + movie.MarkedAsAvailable4K = DateTime.Now; + await _movieRepo.SaveChangesAsync(); + notify = true; + } + + if (!feature4kEnabled && !movie.Available) + { + movie.Available = true; + movie.MarkedAsAvailable = DateTime.Now; + await _movieRepo.SaveChangesAsync(); + notify = true; + } + + // If we have a non-4k versison then mark as available + if (item.Quality != null && !movie.Available) + { + movie.Available = true; + movie.Approved = true; + movie.MarkedAsAvailable = DateTime.Now; + await _movieRepo.SaveChangesAsync(); + notify = true; + } + + if (notify) + { + itemsForAvailbility.Add(new AvailabilityModel + { + Id = movie.Id, + RequestedUser = movie.RequestedUser != null ? movie.RequestedUser.Email : string.Empty + }); + } } - if (itemsForAvailbility.Any()) + foreach (var i in itemsForAvailbility.DistinctBy(x => x.Id)) { - await _movieRepo.SaveChangesAsync(); - } - foreach (var i in itemsForAvailbility) - { - await _notificationService.Notify(new NotificationOptions { DateTime = DateTime.Now, @@ -235,8 +261,6 @@ namespace Ombi.Schedule.Jobs.Plex Recipient = i.RequestedUser }); } - - //await _repo.SaveChangesAsync(); } private bool _disposed; diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs index 3289c5a24..9c5a651e2 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexContentSync.cs @@ -167,7 +167,7 @@ namespace Ombi.Schedule.Jobs.Plex private async Task ProcessServer(PlexServers servers, bool recentlyAddedSearch) { var retVal = new ProcessedContent(); - var contentProcessed = new Dictionary(); + var contentProcessed = new Dictionary(); var episodesProcessed = new List(); Logger.LogDebug("Getting all content from server {0}", servers.Name); var allContent = await GetAllContent(servers, recentlyAddedSearch); @@ -226,7 +226,7 @@ namespace Ombi.Schedule.Jobs.Plex await Repo.SaveChangesAsync(); if (content.Metadata != null) { - var episodesAdded = await EpisodeSync.ProcessEpsiodes(content.Metadata, allEps); + var episodesAdded = await EpisodeSync.ProcessEpsiodes(content.Metadata, (IQueryable)allEps); episodesProcessed.AddRange(episodesAdded.Select(x => x.Id)); } } @@ -290,10 +290,10 @@ namespace Ombi.Schedule.Jobs.Plex } public async Task MovieLoop(PlexServers servers, Mediacontainer content, HashSet contentToAdd, - Dictionary contentProcessed) + Dictionary contentProcessed) { Logger.LogDebug("Processing Movies"); - foreach (var movie in content?.Metadata ?? new Metadata[] { }) + foreach (var movie in content?.Metadata ?? Array.Empty()) { // Let's check if we have this movie @@ -301,20 +301,50 @@ namespace Ombi.Schedule.Jobs.Plex { var existing = await Repo.GetFirstContentByCustom(x => x.Title == movie.title && x.ReleaseYear == movie.year.ToString() - && x.Type == PlexMediaTypeEntity.Movie); - // The rating key keeps changing - //var existing = await Repo.GetByKey(movie.ratingKey); + && x.Type == MediaType.Movie); if (existing != null) { - Logger.LogDebug("We already have movie {0}", movie.title); + // We need to see if this is a different quality, + // We want to know if this is a 4k content for example + var foundQualities = movie.Media?.Select(x => x.videoResolution); + var qualitySaved = false; + foreach (var quality in foundQualities) + { + if (qualitySaved) + { + break; + } + if (quality.Equals(existing.Quality)) + { + // We got it + continue; + } + + // We don't have this quality + if (quality.Equals("4k", StringComparison.InvariantCultureIgnoreCase)) + { + Logger.LogDebug($"We already have movie {movie.title}, But found a 4K version!"); + existing.Has4K = true; + await Repo.Update(existing); + } + else + { + qualitySaved = true; + existing.Quality = quality; + await Repo.Update(existing); + } + } + + + Logger.LogDebug($"We already have movie {movie.title}"); continue; } - var hasSameKey = await Repo.GetByKey(movie.ratingKey); - if (hasSameKey != null) - { - await Repo.Delete(hasSameKey); - } + //var hasSameKey = await Repo.GetByKey(movie.ratingKey); + //if (hasSameKey != null) + //{ + // await Repo.Delete(hasSameKey); + //} Logger.LogDebug("Adding movie {0}", movie.title); var guids = new List(); @@ -342,18 +372,34 @@ namespace Ombi.Schedule.Jobs.Plex } } + if (!guids.Any()) + { + Logger.LogWarning($"Movie {movie.title} has no relevant metadata. Skipping."); + continue; + } var providerIds = PlexHelper.GetProviderIdsFromMetadata(guids.ToArray()); + if (!providerIds.Any()) + { + Logger.LogWarning($"Movie {movie.title} has no External Ids in Plex (ImdbId, TheMovieDbId). Skipping."); + continue; + } + + var qualities = movie?.Media?.Select(x => x?.videoResolution ?? string.Empty) ?? Enumerable.Empty(); + var is4k = qualities != null && qualities.Any(x => x.Equals("4k", StringComparison.InvariantCultureIgnoreCase)); + var selectedQuality = is4k ? null : qualities?.OrderBy(x => x)?.FirstOrDefault() ?? string.Empty; + var item = new PlexServerContent { AddedAt = DateTime.Now, Key = movie.ratingKey, ReleaseYear = movie.year.ToString(), - Type = PlexMediaTypeEntity.Movie, + Type = MediaType.Movie, Title = movie.title, - Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey), + Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, movie.ratingKey, servers.ServerHostname), Seasons = new List(), - Quality = movie.Media?.FirstOrDefault()?.videoResolution ?? string.Empty + Quality = selectedQuality, + Has4K = is4k, }; if (providerIds.ImdbId.HasValue()) { @@ -391,7 +437,7 @@ namespace Ombi.Schedule.Jobs.Plex } } - private async Task ProcessTvShow(PlexServers servers, Metadata show, HashSet contentToAdd, Dictionary contentProcessed) + private async Task ProcessTvShow(PlexServers servers, Metadata show, HashSet contentToAdd, Dictionary contentProcessed) { var seasonList = await PlexApi.GetSeasons(servers.PlexAuthToken, servers.FullUri, show.ratingKey); @@ -411,7 +457,7 @@ namespace Ombi.Schedule.Jobs.Plex // Let's try and match var existingContent = await Repo.GetFirstContentByCustom(x => x.Title == show.title && x.ReleaseYear == show.year.ToString() - && x.Type == PlexMediaTypeEntity.Show); + && x.Type == MediaType.Series); // Just double check the rating key, since this is our unique constraint var existingKey = await Repo.GetByKey(show.ratingKey); @@ -463,7 +509,7 @@ namespace Ombi.Schedule.Jobs.Plex Repo.DeleteWithoutSave(existingContent); // Because we have changed the rating key, we need to change all children too - var episodeToChange = Repo.GetAllEpisodes().Where(x => x.GrandparentKey == oldKey); + var episodeToChange = Repo.GetAllEpisodes().Cast().Where(x => x.GrandparentKey == oldKey); if (episodeToChange.Any()) { foreach (var e in episodeToChange) @@ -553,9 +599,9 @@ namespace Ombi.Schedule.Jobs.Plex AddedAt = DateTime.Now, Key = show.ratingKey, ReleaseYear = show.year.ToString(), - Type = PlexMediaTypeEntity.Show, + Type = MediaType.Series, Title = show.title, - Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, show.ratingKey), + Url = PlexHelper.GetPlexMediaUrl(servers.MachineIdentifier, show.ratingKey, servers.ServerHostname), Seasons = new List() }; await GetProviderIds(showMetadata, item); @@ -567,19 +613,19 @@ namespace Ombi.Schedule.Jobs.Plex if (item.ImdbId.HasValue()) { existingImdb = await Repo.GetAll().AnyAsync(x => - x.ImdbId == item.ImdbId && x.Type == PlexMediaTypeEntity.Show); + x.ImdbId == item.ImdbId && x.Type == MediaType.Series); } if (item.TheMovieDbId.HasValue()) { existingMovieDbId = await Repo.GetAll().AnyAsync(x => - x.TheMovieDbId == item.TheMovieDbId && x.Type == PlexMediaTypeEntity.Show); + x.TheMovieDbId == item.TheMovieDbId && x.Type == MediaType.Series); } if (item.TvDbId.HasValue()) { existingTvDbId = await Repo.GetAll().AnyAsync(x => - x.TvDbId == item.TvDbId && x.Type == PlexMediaTypeEntity.Show); + x.TvDbId == item.TvDbId && x.Type == MediaType.Series); } if (existingImdb || existingTvDbId || existingMovieDbId) diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs index 50c5d1f39..c17af088c 100644 --- a/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs +++ b/src/Ombi.Schedule/Jobs/Plex/PlexEpisodeSync.cs @@ -113,7 +113,7 @@ namespace Ombi.Schedule.Jobs.Plex { var currentPosition = 0; var resultCount = settings.EpisodeBatchSize == 0 ? 150 : settings.EpisodeBatchSize; - var currentEpisodes = _repo.GetAllEpisodes(); + var currentEpisodes = _repo.GetAllEpisodes().Cast(); var episodes = await _api.GetAllEpisodes(settings.PlexAuthToken, settings.FullUri, section.key, currentPosition, resultCount); _log.LogInformation(LoggingEvents.PlexEpisodeCacher, $"Total Epsiodes found for {episodes.MediaContainer.librarySectionTitle} = {episodes.MediaContainer.totalSize}"); @@ -179,6 +179,13 @@ namespace Ombi.Schedule.Jobs.Plex episode.grandparentRatingKey = seriesExists.Key; } + // Sanity checks + if (episode.index == 0) + { + _log.LogWarning($"Episode {episode.title} has no episode number. Skipping."); + continue; + } + ep.Add(new PlexEpisode { EpisodeNumber = episode.index, diff --git a/src/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs b/src/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs new file mode 100644 index 000000000..8e6b443ef --- /dev/null +++ b/src/Ombi.Schedule/Jobs/Plex/PlexWatchlistImport.cs @@ -0,0 +1,211 @@ +using Microsoft.AspNetCore.SignalR; +using Microsoft.Extensions.Logging; +using Ombi.Api.Plex; +using Ombi.Api.Plex.Models; +using Ombi.Core.Authentication; +using Ombi.Core.Engine; +using Ombi.Core.Engine.Interfaces; +using Ombi.Core.Models.Requests; +using Ombi.Core.Settings; +using Ombi.Core.Settings.Models.External; +using Ombi.Helpers; +using Ombi.Hubs; +using Ombi.Store.Entities; +using Ombi.Store.Entities.Requests; +using Ombi.Store.Repository; +using Quartz; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace Ombi.Schedule.Jobs.Plex +{ + public class PlexWatchlistImport : IPlexWatchlistImport + { + private readonly IPlexApi _plexApi; + private readonly ISettingsService _settings; + private readonly OmbiUserManager _ombiUserManager; + private readonly IMovieRequestEngine _movieRequestEngine; + private readonly ITvRequestEngine _tvRequestEngine; + private readonly IHubContext _hub; + private readonly ILogger _logger; + private readonly IExternalRepository _watchlistRepo; + + public PlexWatchlistImport(IPlexApi plexApi, ISettingsService settings, OmbiUserManager ombiUserManager, + IMovieRequestEngine movieRequestEngine, ITvRequestEngine tvRequestEngine, IHubContext hub, + ILogger logger, IExternalRepository watchlistRepo) + { + _plexApi = plexApi; + _settings = settings; + _ombiUserManager = ombiUserManager; + _movieRequestEngine = movieRequestEngine; + _tvRequestEngine = tvRequestEngine; + _hub = hub; + _logger = logger; + _watchlistRepo = watchlistRepo; + } + + public async Task Execute(IJobExecutionContext context) + { + var settings = await _settings.GetSettingsAsync(); + if (!settings.Enable || !settings.EnableWatchlistImport) + { + _logger.LogDebug($"Not enabled. Plex Enabled: {settings.Enable}, Watchlist Enabled: {settings.EnableWatchlistImport}"); + return; + } + + var plexUsersWithTokens = _ombiUserManager.Users.Where(x => x.UserType == UserType.PlexUser && x.MediaServerToken != null).ToList(); + _logger.LogInformation($"Found {plexUsersWithTokens.Count} users with tokens"); + await NotifyClient("Starting Watchlist Import"); + + foreach (var user in plexUsersWithTokens) + { + try + { + + _logger.LogDebug($"Starting Watchlist Import for {user.UserName} with token {user.MediaServerToken}"); + var watchlist = await _plexApi.GetWatchlist(user.MediaServerToken, context?.CancellationToken ?? CancellationToken.None); + if (watchlist == null || !(watchlist.MediaContainer?.Metadata?.Any() ?? false)) + { + _logger.LogDebug($"No watchlist found for {user.UserName}"); + continue; + } + + var items = watchlist.MediaContainer.Metadata; + _logger.LogDebug($"Items found in watchlist: {watchlist.MediaContainer.totalSize}"); + foreach (var item in items) + { + _logger.LogDebug($"Processing {item.title} {item.type}"); + var providerIds = await GetProviderIds(user.MediaServerToken, item, context?.CancellationToken ?? CancellationToken.None); + if (!providerIds.TheMovieDb.HasValue()) + { + _logger.LogWarning($"No TheMovieDb Id found for {item.title}, could not import via Plex WatchList"); + // We need a MovieDbId to support this; + continue; + } + + // Check to see if we have already imported this item + var alreadyImported = _watchlistRepo.GetAll().Any(x => x.TmdbId == providerIds.TheMovieDb); + if (alreadyImported) + { + _logger.LogDebug($"{item.title} already imported via Plex WatchList, skipping"); + continue; + } + + switch (item.type) + { + case "show": + await ProcessShow(int.Parse(providerIds.TheMovieDb), user); + break; + case "movie": + await ProcessMovie(int.Parse(providerIds.TheMovieDb), user); + break; + } + } + } + catch (Exception ex) + { + _logger.LogError(ex, $"Exception thrown when importing watchlist for user {user.UserName}"); + continue; + } + } + + await NotifyClient("Finished Watchlist Import"); + } + + private async Task ProcessMovie(int theMovieDbId, OmbiUser user) + { + _movieRequestEngine.SetUser(user); + var response = await _movieRequestEngine.RequestMovie(new() { TheMovieDbId = theMovieDbId, Source = RequestSource.PlexWatchlist }); + if (response.IsError) + { + if (response.ErrorCode == ErrorCode.AlreadyRequested) + { + _logger.LogDebug($"Movie already requested for user '{user.UserName}'"); + await AddToHistory(theMovieDbId); + return; + } + _logger.LogInformation($"Error adding title from PlexWatchlist for user '{user.UserName}'. Message: '{response.ErrorMessage}'"); + } + else + { + await AddToHistory(theMovieDbId); + + _logger.LogInformation($"Added title from PlexWatchlist for user '{user.UserName}'. {response.Message}"); + } + } + + private async Task ProcessShow(int theMovieDbId, OmbiUser user) + { + _tvRequestEngine.SetUser(user); + var response = await _tvRequestEngine.RequestTvShow(new TvRequestViewModelV2 { LatestSeason = true, TheMovieDbId = theMovieDbId, Source = RequestSource.PlexWatchlist }); + if (response.IsError) + { + if (response.ErrorCode == ErrorCode.AlreadyRequested) + { + _logger.LogDebug($"Show already requested for user '{user.UserName}'"); + await AddToHistory(theMovieDbId); + return; + } + _logger.LogInformation($"Error adding title from PlexWatchlist for user '{user.UserName}'. Message: '{response.ErrorMessage}'"); + } + else + { + await AddToHistory(theMovieDbId); + _logger.LogInformation($"Added title from PlexWatchlist for user '{user.UserName}'. {response.Message}"); + } + } + private async Task AddToHistory(int theMovieDbId) + { + + // Add to the watchlist history + var history = new PlexWatchlistHistory + { + TmdbId = theMovieDbId.ToString() + }; + await _watchlistRepo.Add(history); + } + + private async Task GetProviderIds(string authToken, Metadata movie, CancellationToken cancellationToken) + { + var guids = new List(); + if (!movie.Guid.Any()) + { + var metaData = await _plexApi.GetWatchlistMetadata(movie.ratingKey, authToken, cancellationToken); + + var meta = metaData.MediaContainer.Metadata.FirstOrDefault(); + guids.Add(meta.guid); + if (meta.Guid != null) + { + foreach (var g in meta.Guid) + { + guids.Add(g.Id); + } + } + } + else + { + // Currently a Plex Pass feature only + foreach (var g in movie.Guid) + { + guids.Add(g.Id); + } + } + var providerIds = PlexHelper.GetProviderIdsFromMetadata(guids.ToArray()); + return providerIds; + } + + private async Task NotifyClient(string message) + { + if (_hub?.Clients == null) + { + return; + } + await _hub?.Clients?.Clients(NotificationHub.AdminConnectionIds)? + .SendAsync(NotificationHub.NotificationEvent, $"Plex Watchlist Import - {message}"); + } + public void Dispose() { } + } +} diff --git a/src/Ombi.Schedule/Jobs/Radarr/IRadarrSync.cs b/src/Ombi.Schedule/Jobs/Radarr/IRadarrSync.cs index 1fb191fd1..19178ca48 100644 --- a/src/Ombi.Schedule/Jobs/Radarr/IRadarrSync.cs +++ b/src/Ombi.Schedule/Jobs/Radarr/IRadarrSync.cs @@ -1,11 +1,6 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Ombi.Store.Entities; - -namespace Ombi.Schedule.Jobs.Radarr +namespace Ombi.Schedule.Jobs.Radarr { public interface IRadarrSync : IBaseJob { - Task> GetCachedContent(); } } \ No newline at end of file diff --git a/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs b/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs index 3cda06281..94970305a 100644 --- a/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs +++ b/src/Ombi.Schedule/Jobs/Radarr/RadarrSync.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Threading; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Logging; @@ -10,106 +9,112 @@ using Ombi.Helpers; using Ombi.Settings.Settings.Models.External; using Ombi.Store.Context; using Ombi.Store.Entities; +using Ombi.Store.Repository; using Quartz; -using Serilog; namespace Ombi.Schedule.Jobs.Radarr { public class RadarrSync : IRadarrSync { - public RadarrSync(ISettingsService radarr, IRadarrV3Api radarrApi, ILogger log, ExternalContext ctx) + public RadarrSync(ISettingsService radarr, ISettingsService radarr4k, IRadarrV3Api radarrApi, ILogger log, ExternalContext ctx, + IExternalRepository radarrRepo) { - RadarrSettings = radarr; - RadarrApi = radarrApi; - Logger = log; + _radarrSettings = radarr; + _radarr4kSettings = radarr4k; + _api = radarrApi; + _logger = log; _ctx = ctx; - RadarrSettings.ClearCache(); + _radarrRepo = radarrRepo; + _radarrSettings.ClearCache(); + _radarr4kSettings.ClearCache(); } - private ISettingsService RadarrSettings { get; } - private IRadarrV3Api RadarrApi { get; } - private ILogger Logger { get; } + private readonly ISettingsService _radarrSettings; + private readonly ISettingsService _radarr4kSettings; + private readonly IRadarrV3Api _api; + private readonly ILogger _logger; private readonly ExternalContext _ctx; - - private static readonly SemaphoreSlim SemaphoreSlim = new SemaphoreSlim(1, 1); + private readonly IExternalRepository _radarrRepo; public async Task Execute(IJobExecutionContext job) { - await SemaphoreSlim.WaitAsync(); try { - var settings = await RadarrSettings.GetSettingsAsync(); - if (settings.Enabled) + var strat = _ctx.Database.CreateExecutionStrategy(); + await strat.ExecuteAsync(async () => { - try - { - var movies = await RadarrApi.GetMovies(settings.ApiKey, settings.FullUri); - if (movies != null) - { - var strat = _ctx.Database.CreateExecutionStrategy(); - await strat.ExecuteAsync(async () => - { - // Let's remove the old cached data - using (var tran = await _ctx.Database.BeginTransactionAsync()) - { - await _ctx.Database.ExecuteSqlRawAsync("DELETE FROM RadarrCache"); - tran.Commit(); - } - }); + // Let's remove the old cached data + using var tran = await _ctx.Database.BeginTransactionAsync(); + await _ctx.Database.ExecuteSqlRawAsync("DELETE FROM RadarrCache"); + tran.Commit(); + }); - var movieIds = new List(); - foreach (var m in movies) + var radarrSettings = _radarrSettings.GetSettingsAsync(); + var radarr4kSettings = _radarr4kSettings.GetSettingsAsync(); + await Process(await radarrSettings); + await Process(await radarr4kSettings); + } + catch (Exception) + { + _logger.LogInformation(LoggingEvents.RadarrCacher, "Radarr is not setup, cannot cache episodes"); + } + } + + private async Task Process(RadarrSettings settings) + { + if (settings.Enabled) + { + try + { + var movies = await _api.GetMovies(settings.ApiKey, settings.FullUri); + var existingMovies = _radarrRepo.GetAll(); + if (movies != null) + { + var movieIds = new List(); + foreach (var m in movies) + { + if (m.monitored || m.hasFile) { - if (m.monitored || m.hasFile) + if (m.tmdbId > 0) { - if (m.tmdbId > 0) + var is4k = m.movieFile?.quality?.quality?.resolution >= 2160; + + // Do we have a cached movie for this already? + var existing = await existingMovies.FirstOrDefaultAsync(x => x.TheMovieDbId == m.tmdbId); + if (existing != null) + { + existing.Has4K = is4k; + existing.HasFile = m.hasFile; + } + else { movieIds.Add(new RadarrCache { TheMovieDbId = m.tmdbId, - HasFile = m.hasFile + HasFile = m.hasFile, + Has4K = is4k, + HasRegular = !is4k }); } - else - { - Logger.LogError("TMDBId is not > 0 for movie {0}", m.title); - } + } + else + { + _logger.LogError($"TMDBId is not > 0 for movie {m.title}"); } } - strat = _ctx.Database.CreateExecutionStrategy(); - await strat.ExecuteAsync(async () => - { - using (var tran = await _ctx.Database.BeginTransactionAsync()) - { - await _ctx.RadarrCache.AddRangeAsync(movieIds); - - await _ctx.SaveChangesAsync(); - tran.Commit(); - } - }); } + // Save from the updates made to the existing movies (they are in the EF Change Tracker) + await _radarrRepo.SaveChangesAsync(); + await _radarrRepo.AddRange(movieIds); + } - await OmbiQuartz.TriggerJob(nameof(IArrAvailabilityChecker), "DVR"); - } - catch (System.Exception ex) - { - Logger.LogError(LoggingEvents.Cacher, ex, "Failed caching queued items from Radarr"); - } + await OmbiQuartz.TriggerJob(nameof(IArrAvailabilityChecker), "DVR"); + } + catch (System.Exception ex) + { + _logger.LogError(LoggingEvents.Cacher, ex, "Failed caching queued items from Radarr"); } } - catch (Exception) - { - Logger.LogInformation(LoggingEvents.RadarrCacher, "Radarr is not setup, cannot cache episodes"); - } - finally - { - SemaphoreSlim.Release(); - } - } - - public async Task> GetCachedContent() - { - return await _ctx.RadarrCache.ToListAsync(); } private bool _disposed; diff --git a/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs b/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs index cf13fb037..834c45883 100644 --- a/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs +++ b/src/Ombi.Schedule/Jobs/Sonarr/SonarrSync.cs @@ -108,7 +108,7 @@ namespace Ombi.Schedule.Jobs.Sonarr foreach (var s in ids) { - if (!s.Monitored || s.EpisodeFileCount == 0) // We have files + if (!s.Monitored && s.EpisodeFileCount == 0) // We have files { continue; } diff --git a/src/Ombi.Schedule/Ombi.Schedule.csproj b/src/Ombi.Schedule/Ombi.Schedule.csproj index 51cf46f82..a972aa6bb 100644 --- a/src/Ombi.Schedule/Ombi.Schedule.csproj +++ b/src/Ombi.Schedule/Ombi.Schedule.csproj @@ -1,20 +1,19 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild - - + diff --git a/src/Ombi.Schedule/OmbiScheduler.cs b/src/Ombi.Schedule/OmbiScheduler.cs index 6c54895d6..41602f641 100644 --- a/src/Ombi.Schedule/OmbiScheduler.cs +++ b/src/Ombi.Schedule/OmbiScheduler.cs @@ -91,11 +91,13 @@ namespace Ombi.Schedule await OmbiQuartz.Instance.AddJob(nameof(IPlexUserImporter), "Plex", JobSettingsHelper.UserImporter(s)); await OmbiQuartz.Instance.AddJob(nameof(IPlexEpisodeSync), "Plex", null); await OmbiQuartz.Instance.AddJob(nameof(IPlexAvailabilityChecker), "Plex", null); + await OmbiQuartz.Instance.AddJob(nameof(IPlexWatchlistImport), "Plex", JobSettingsHelper.PlexWatchlistImport(s)); } private static async Task AddEmby(JobSettings s) { await OmbiQuartz.Instance.AddJob(nameof(IEmbyContentSync), "Emby", JobSettingsHelper.EmbyContent(s)); + await OmbiQuartz.Instance.AddJob(nameof(IEmbyContentSync) + "RecentlyAdded", "Emby", JobSettingsHelper.EmbyRecentlyAddedSync(s), new Dictionary { { JobDataKeys.EmbyRecentlyAddedSearch, "true" } }); await OmbiQuartz.Instance.AddJob(nameof(IEmbyEpisodeSync), "Emby", null); await OmbiQuartz.Instance.AddJob(nameof(IEmbyAvaliabilityChecker), "Emby", null); await OmbiQuartz.Instance.AddJob(nameof(IEmbyUserImporter), "Emby", JobSettingsHelper.UserImporter(s)); diff --git a/src/Ombi.Settings.Tests/Ombi.Settings.Tests.csproj b/src/Ombi.Settings.Tests/Ombi.Settings.Tests.csproj index d30b780c6..5f93b4b68 100644 --- a/src/Ombi.Settings.Tests/Ombi.Settings.Tests.csproj +++ b/src/Ombi.Settings.Tests/Ombi.Settings.Tests.csproj @@ -1,6 +1,6 @@  - net5.0 + net6.0 false @@ -10,7 +10,7 @@ - + diff --git a/src/Ombi.Settings/Ombi.Settings.csproj b/src/Ombi.Settings/Ombi.Settings.csproj index 377970b59..3821892f0 100644 --- a/src/Ombi.Settings/Ombi.Settings.csproj +++ b/src/Ombi.Settings/Ombi.Settings.csproj @@ -1,23 +1,24 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild - + + diff --git a/src/Ombi.Settings/Settings/Models/AuthenticationSettings.cs b/src/Ombi.Settings/Settings/Models/AuthenticationSettings.cs index f6736e7c5..ed2775480 100644 --- a/src/Ombi.Settings/Settings/Models/AuthenticationSettings.cs +++ b/src/Ombi.Settings/Settings/Models/AuthenticationSettings.cs @@ -13,5 +13,7 @@ namespace Ombi.Settings.Settings.Models public bool RequireNonAlphanumeric { get; set; } public bool RequireUppercase { get; set; } public bool EnableOAuth { get; set; } // Plex OAuth + public bool EnableHeaderAuth { get; set; } // Header SSO + public string HeaderAuthVariable { get; set; } // Header SSO } } \ No newline at end of file diff --git a/src/Ombi.Settings/Settings/Models/CustomizationSettings.cs b/src/Ombi.Settings/Settings/Models/CustomizationSettings.cs index 310748039..d0ea1bcfa 100644 --- a/src/Ombi.Settings/Settings/Models/CustomizationSettings.cs +++ b/src/Ombi.Settings/Settings/Models/CustomizationSettings.cs @@ -12,6 +12,7 @@ public bool RecentlyAddedPage { get; set; } public bool UseCustomPage { get; set; } public bool HideAvailableFromDiscover { get; set; } + public string Favicon { get; set; } public bool HideAvailableRecentlyRequested { get; set; } public string AddToUrl(string part) diff --git a/src/Ombi.Settings/Settings/Models/External/PlexSettings.cs b/src/Ombi.Settings/Settings/Models/External/PlexSettings.cs index 6cf021f7c..5917e2592 100644 --- a/src/Ombi.Settings/Settings/Models/External/PlexSettings.cs +++ b/src/Ombi.Settings/Settings/Models/External/PlexSettings.cs @@ -7,6 +7,7 @@ namespace Ombi.Core.Settings.Models.External public sealed class PlexSettings : Ombi.Settings.Settings.Models.Settings { public bool Enable { get; set; } + public bool EnableWatchlistImport { get; set; } /// /// This is the ClientId for OAuth /// diff --git a/src/Ombi.Settings/Settings/Models/External/RadarrSettings.cs b/src/Ombi.Settings/Settings/Models/External/RadarrSettings.cs index b074e28d6..1b3e0982f 100644 --- a/src/Ombi.Settings/Settings/Models/External/RadarrSettings.cs +++ b/src/Ombi.Settings/Settings/Models/External/RadarrSettings.cs @@ -10,4 +10,15 @@ public string MinimumAvailability { get; set; } public bool ScanForAvailability { get; set; } } + + public class Radarr4KSettings : RadarrSettings + { + // no additional properties needed + } + + public class RadarrCombinedModel + { + public RadarrSettings Radarr { get; set; } + public Radarr4KSettings Radarr4K { get; set; } + } } \ No newline at end of file diff --git a/src/Ombi.Settings/Settings/Models/External/TheMovieDbSettings.cs b/src/Ombi.Settings/Settings/Models/External/TheMovieDbSettings.cs index c2df1b9b3..cbb0233a0 100644 --- a/src/Ombi.Settings/Settings/Models/External/TheMovieDbSettings.cs +++ b/src/Ombi.Settings/Settings/Models/External/TheMovieDbSettings.cs @@ -11,5 +11,7 @@ namespace Ombi.Core.Settings.Models.External public List ExcludedMovieGenreIds { get; set; } public List ExcludedTvGenreIds { get; set; } + + public List OriginalLanguages { get; set; } } } diff --git a/src/Ombi.Settings/Settings/Models/FeatureSettings.cs b/src/Ombi.Settings/Settings/Models/FeatureSettings.cs new file mode 100644 index 000000000..9d0149e5d --- /dev/null +++ b/src/Ombi.Settings/Settings/Models/FeatureSettings.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Ombi.Settings.Settings.Models +{ + public class FeatureSettings : Settings + { + public List Features { get; set; } + } + + public class FeatureEnablement + { + public string Name { get; set; } + public bool Enabled { get; set; } + } + + public static class FeatureNames + { + public const string Movie4KRequests = nameof(Movie4KRequests); + public const string OldTrendingSource = nameof(OldTrendingSource); + } +} diff --git a/src/Ombi.Settings/Settings/Models/JobSettings.cs b/src/Ombi.Settings/Settings/Models/JobSettings.cs index 18bde6774..cc4ed2e23 100644 --- a/src/Ombi.Settings/Settings/Models/JobSettings.cs +++ b/src/Ombi.Settings/Settings/Models/JobSettings.cs @@ -3,6 +3,7 @@ public class JobSettings : Settings { public string EmbyContentSync { get; set; } + public string EmbyRecentlyAddedSync { get; set; } public string JellyfinContentSync { get; set; } public string SonarrSync { get; set; } public string RadarrSync { get; set; } @@ -18,5 +19,6 @@ public string RetryRequests { get; set; } public string MediaDatabaseRefresh { get; set; } public string AutoDeleteRequests { get; set; } + public string PlexWatchlistImport { get; set; } } } diff --git a/src/Ombi.Settings/Settings/Models/JobSettingsHelper.cs b/src/Ombi.Settings/Settings/Models/JobSettingsHelper.cs index fef0792d3..b80943cc5 100644 --- a/src/Ombi.Settings/Settings/Models/JobSettingsHelper.cs +++ b/src/Ombi.Settings/Settings/Models/JobSettingsHelper.cs @@ -1,5 +1,4 @@ -using System; -using Ombi.Helpers; +using Ombi.Helpers; using Quartz; namespace Ombi.Settings.Settings.Models @@ -18,7 +17,12 @@ namespace Ombi.Settings.Settings.Models public static string EmbyContent(JobSettings s) { - return ValidateCron(Get(s.EmbyContentSync, Cron.Hourly(5))); + return ValidateCron(Get(s.EmbyContentSync, Cron.Daily(2))); + } + + public static string EmbyRecentlyAddedSync(JobSettings s) + { + return ValidateCron(Get(s.EmbyRecentlyAddedSync, Cron.Hourly(30))); } public static string JellyfinContent(JobSettings s) @@ -50,6 +54,11 @@ namespace Ombi.Settings.Settings.Models { return ValidateCron(Get(s.UserImporter, Cron.Daily())); } + + public static string PlexWatchlistImport(JobSettings s) + { + return ValidateCron(Get(s.PlexWatchlistImport, Cron.Hourly(25))); + } public static string Newsletter(JobSettings s) { diff --git a/src/Ombi.Settings/Settings/Models/Notifications/EmailNotificationSettings.cs b/src/Ombi.Settings/Settings/Models/Notifications/EmailNotificationSettings.cs index 9ea8cc492..f63b77ae5 100644 --- a/src/Ombi.Settings/Settings/Models/Notifications/EmailNotificationSettings.cs +++ b/src/Ombi.Settings/Settings/Models/Notifications/EmailNotificationSettings.cs @@ -10,7 +10,6 @@ public string SenderAddress { get; set; } public string Username { get; set; } public bool Authentication { get; set; } - public string AdminEmail { get; set; } public bool DisableTLS { get; set; } public bool DisableCertificateChecking { get; set; } } diff --git a/src/Ombi.Settings/Settings/Models/OmbiSettings.cs b/src/Ombi.Settings/Settings/Models/OmbiSettings.cs index ba460a2bd..e224b5c70 100644 --- a/src/Ombi.Settings/Settings/Models/OmbiSettings.cs +++ b/src/Ombi.Settings/Settings/Models/OmbiSettings.cs @@ -1,7 +1,10 @@ -namespace Ombi.Settings.Settings.Models +using Ombi.I18n.Resources; +using System.Globalization; +namespace Ombi.Settings.Settings.Models { public class OmbiSettings : Settings { + private string defaultLanguageCode = "en"; public string BaseUrl { get; set; } public bool CollectAnalyticData { get; set; } public bool Wizard { get; set; } @@ -9,7 +12,14 @@ public bool DoNotSendNotificationsForAutoApprove { get; set; } public bool HideRequestsUsers { get; set; } public bool DisableHealthChecks { get; set; } - public string DefaultLanguageCode { get; set; } = "en"; + public string DefaultLanguageCode + { + get => defaultLanguageCode; + set { + defaultLanguageCode = value; + Texts.Culture = new CultureInfo(value); + } + } public bool AutoDeleteAvailableRequests { get; set; } public int AutoDeleteAfterDays { get; set; } public Branch Branch { get; set; } diff --git a/src/Ombi.Store/Context/ExternalContext.cs b/src/Ombi.Store/Context/ExternalContext.cs index ce121fe10..f13c1e74f 100644 --- a/src/Ombi.Store/Context/ExternalContext.cs +++ b/src/Ombi.Store/Context/ExternalContext.cs @@ -1,4 +1,5 @@ -using System.IO; +using System.Collections.Generic; +using System.IO; using Microsoft.EntityFrameworkCore; using Ombi.Helpers; using Ombi.Store.Entities; @@ -26,6 +27,7 @@ namespace Ombi.Store.Context public DbSet PlexServerContent { get; set; } public DbSet PlexSeasonsContent { get; set; } public DbSet PlexEpisode { get; set; } + public DbSet PlexWatchlistHistory { get; set; } public DbSet RadarrCache { get; set; } public DbSet CouchPotatoCache { get; set; } public DbSet EmbyContent { get; set; } @@ -42,20 +44,20 @@ namespace Ombi.Store.Context protected override void OnModelCreating(ModelBuilder builder) { - builder.Entity().HasMany(x => x.Episodes) - .WithOne(x => x.Series) + builder.Entity().HasMany(x => (ICollection) x.Episodes) + .WithOne(x => (PlexServerContent) x.Series) .HasPrincipalKey(x => x.Key) .HasForeignKey(x => x.GrandparentKey); builder.Entity() - .HasOne(p => p.Series) - .WithMany(b => b.Episodes) + .HasOne(p => (EmbyContent) p.Series) + .WithMany(b => (ICollection) b.Episodes) .HasPrincipalKey(x => x.EmbyId) .HasForeignKey(p => p.ParentId); builder.Entity() - .HasOne(p => p.Series) - .WithMany(b => b.Episodes) + .HasOne(p => (JellyfinContent) p.Series) + .WithMany(b => (ICollection) b.Episodes) .HasPrincipalKey(x => x.JellyfinId) .HasForeignKey(p => p.ParentId); diff --git a/src/Ombi.Store/Context/OmbiContext.cs b/src/Ombi.Store/Context/OmbiContext.cs index 0681d9ca0..77298e719 100644 --- a/src/Ombi.Store/Context/OmbiContext.cs +++ b/src/Ombi.Store/Context/OmbiContext.cs @@ -212,7 +212,7 @@ namespace Ombi.Store.Context notificationToAdd = new NotificationTemplates { NotificationType = notificationType, - Message = "Your TV request is now partially available! Season {PartiallyAvailableSeasonNumber} Episodes {PartiallyAvailableEpisodeNumbers}!", + Message = "Your TV request for {Title} is now partially available! Season {PartiallyAvailableSeasonNumber} Episodes {PartiallyAvailableEpisodeNumbers}!", Subject = "{ApplicationName}: Partially Available Request!", Agent = agent, Enabled = true, diff --git a/src/Ombi.Store/Context/SettingsContext.cs b/src/Ombi.Store/Context/SettingsContext.cs index 83ffa792d..39883cb92 100644 --- a/src/Ombi.Store/Context/SettingsContext.cs +++ b/src/Ombi.Store/Context/SettingsContext.cs @@ -1,5 +1,6 @@ using System.Linq; using Microsoft.EntityFrameworkCore; +using Newtonsoft.Json; using Ombi.Store.Entities; namespace Ombi.Store.Context diff --git a/src/Ombi.Store/Entities/EmbyContent.cs b/src/Ombi.Store/Entities/EmbyContent.cs index 348573f28..08118b6df 100644 --- a/src/Ombi.Store/Entities/EmbyContent.cs +++ b/src/Ombi.Store/Entities/EmbyContent.cs @@ -32,40 +32,13 @@ using System.ComponentModel.DataAnnotations.Schema; namespace Ombi.Store.Entities { [Table("EmbyContent")] - public class EmbyContent : Entity + public class EmbyContent : MediaServerContent { - public string Title { get; set; } - /// - /// OBSOLETE, Cannot delete due to DB migration issues with SQLite - /// + [Obsolete("Cannot delete due to DB migration issues with SQLite")] public string ProviderId { get; set; } public string EmbyId { get; set; } - public EmbyMediaType Type { get; set; } - public DateTime AddedAt { get; set; } - - public string ImdbId { get; set; } - public string TheMovieDbId { get; set; } - public string TvDbId { get; set; } - - public string Url { get; set; } - - public ICollection Episodes { get; set; } - - [NotMapped] - public bool HasImdb => !string.IsNullOrEmpty(ImdbId); - - [NotMapped] - public bool HasTvDb => !string.IsNullOrEmpty(TvDbId); - - [NotMapped] - public bool HasTheMovieDb => !string.IsNullOrEmpty(TheMovieDbId); + public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Emby; } - public enum EmbyMediaType - { - Movie = 0, - Series = 1, - Music = 2 - } } \ No newline at end of file diff --git a/src/Ombi.Store/Entities/EmbyEpisode.cs b/src/Ombi.Store/Entities/EmbyEpisode.cs index e4e5b6a4b..89103c580 100644 --- a/src/Ombi.Store/Entities/EmbyEpisode.cs +++ b/src/Ombi.Store/Entities/EmbyEpisode.cs @@ -26,18 +26,16 @@ #endregion using System; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; -using Microsoft.EntityFrameworkCore.Metadata; +using System.Linq; namespace Ombi.Store.Entities { [Table("EmbyEpisode")] - public class EmbyEpisode : Entity + public class EmbyEpisode : MediaServerEpisode { - public string Title { get; set; } public string EmbyId { get; set; } - public int EpisodeNumber { get; set; } - public int SeasonNumber { get; set; } public string ParentId { get; set; } /// /// NOT USED @@ -47,7 +45,17 @@ namespace Ombi.Store.Entities public string TvDbId { get; set; } public string ImdbId { get; set; } public string TheMovieDbId { get; set; } + [NotMapped] + public EmbyContent EmbySeries + { + get => (EmbyContent)Series; + set => Series = value; + } - public EmbyContent Series { get; set; } + public override IMediaServerContent SeriesIsIn(ICollection content) + { + return content.OfType().FirstOrDefault( + x => x.EmbyId == this.EmbySeries.EmbyId); + } } } \ No newline at end of file diff --git a/src/Ombi.Store/Entities/Entity.cs b/src/Ombi.Store/Entities/Entity.cs index 8e1cd2887..fac70de91 100644 --- a/src/Ombi.Store/Entities/Entity.cs +++ b/src/Ombi.Store/Entities/Entity.cs @@ -2,7 +2,7 @@ namespace Ombi.Store.Entities { - public abstract class Entity + public abstract class Entity: IEntity { [Key] public int Id { get; set; } diff --git a/src/Ombi.Store/Entities/IEntity.cs b/src/Ombi.Store/Entities/IEntity.cs new file mode 100644 index 000000000..004d214f1 --- /dev/null +++ b/src/Ombi.Store/Entities/IEntity.cs @@ -0,0 +1,10 @@ +using System.ComponentModel.DataAnnotations; + +namespace Ombi.Store.Entities +{ + public interface IEntity + { + [Key] + public int Id { get; set; } + } +} \ No newline at end of file diff --git a/src/Ombi.Store/Entities/IMediaServerContent.cs b/src/Ombi.Store/Entities/IMediaServerContent.cs new file mode 100644 index 000000000..25e4d5f50 --- /dev/null +++ b/src/Ombi.Store/Entities/IMediaServerContent.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; + +namespace Ombi.Store.Entities +{ + public interface IMediaServerContent: IEntity + { + public string Title { get; set; } + public string ImdbId { get; set; } + public string TvDbId { get; set; } + public string TheMovieDbId { get; set; } + public MediaType Type { get; set; } + public RecentlyAddedType RecentlyAddedType{ get; } + + public string Url { get; set; } + + public ICollection Episodes { get; set; } + + public DateTime AddedAt { get; set; } + + [NotMapped] + public bool HasImdb => !string.IsNullOrEmpty(ImdbId); + + [NotMapped] + public bool HasTvDb => !string.IsNullOrEmpty(TvDbId); + + [NotMapped] + public bool HasTheMovieDb => !string.IsNullOrEmpty(TheMovieDbId); + } + + public interface IMediaServerEpisode + { + public int EpisodeNumber { get; set; } + public int SeasonNumber { get; set; } + public string Title { get; set; } + /// + /// The Season key + /// + /// + /// The parent key. + /// + + + public IMediaServerContent Series { get; set; } + public IMediaServerContent SeriesIsIn(ICollection content); + public bool IsIn(IMediaServerContent content); + } + + public enum MediaType + { + Movie = 0, + Series = 1, + Music = 2, + Episode = 3 + } +} \ No newline at end of file diff --git a/src/Ombi.Store/Entities/JellyfinContent.cs b/src/Ombi.Store/Entities/JellyfinContent.cs index 857457bde..b2bb63959 100644 --- a/src/Ombi.Store/Entities/JellyfinContent.cs +++ b/src/Ombi.Store/Entities/JellyfinContent.cs @@ -32,40 +32,14 @@ using System.ComponentModel.DataAnnotations.Schema; namespace Ombi.Store.Entities { [Table("JellyfinContent")] - public class JellyfinContent : Entity + public class JellyfinContent : MediaServerContent { - public string Title { get; set; } - /// - /// OBSOLETE, Cannot delete due to DB migration issues with SQLite - /// + + [Obsolete("Cannot delete due to DB migration issues with SQLite")] public string ProviderId { get; set; } public string JellyfinId { get; set; } - public JellyfinMediaType Type { get; set; } - public DateTime AddedAt { get; set; } - - public string ImdbId { get; set; } - public string TheMovieDbId { get; set; } - public string TvDbId { get; set; } - - public string Url { get; set; } - - public ICollection Episodes { get; set; } - - [NotMapped] - public bool HasImdb => !string.IsNullOrEmpty(ImdbId); - - [NotMapped] - public bool HasTvDb => !string.IsNullOrEmpty(TvDbId); - - [NotMapped] - public bool HasTheMovieDb => !string.IsNullOrEmpty(TheMovieDbId); + public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Jellyfin; } - public enum JellyfinMediaType - { - Movie = 0, - Series = 1, - Music = 2 - } } diff --git a/src/Ombi.Store/Entities/JellyfinEpisode.cs b/src/Ombi.Store/Entities/JellyfinEpisode.cs index f2c2f820d..5b105003c 100644 --- a/src/Ombi.Store/Entities/JellyfinEpisode.cs +++ b/src/Ombi.Store/Entities/JellyfinEpisode.cs @@ -26,18 +26,17 @@ #endregion using System; +using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; using Microsoft.EntityFrameworkCore.Metadata; namespace Ombi.Store.Entities { [Table("JellyfinEpisode")] - public class JellyfinEpisode : Entity + public class JellyfinEpisode : MediaServerEpisode { - public string Title { get; set; } public string JellyfinId { get; set; } - public int EpisodeNumber { get; set; } - public int SeasonNumber { get; set; } public string ParentId { get; set; } /// /// NOT USED @@ -47,7 +46,17 @@ namespace Ombi.Store.Entities public string TvDbId { get; set; } public string ImdbId { get; set; } public string TheMovieDbId { get; set; } - - public JellyfinContent Series { get; set; } + [NotMapped] + public JellyfinContent JellyfinSeries + { + get => (JellyfinContent)Series; + set => Series = value; + } + + public override IMediaServerContent SeriesIsIn(ICollection content) + { + return content.OfType().FirstOrDefault( + x => x.JellyfinId == this.JellyfinSeries.JellyfinId); + } } } diff --git a/src/Ombi.Store/Entities/MediaServerContent.cs b/src/Ombi.Store/Entities/MediaServerContent.cs new file mode 100644 index 000000000..4f086060b --- /dev/null +++ b/src/Ombi.Store/Entities/MediaServerContent.cs @@ -0,0 +1,53 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; + +namespace Ombi.Store.Entities +{ + public abstract class MediaServerContent: Entity, IMediaServerContent + { + public string Title { get; set; } + public string ImdbId { get; set; } + public string TvDbId { get; set; } + public string TheMovieDbId { get; set; } + public MediaType Type { get; set; } + /// + /// Only populated if it's not 4k + /// + public string Quality { get; set; } + public bool Has4K { get; set; } + public string Url { get; set; } + + public ICollection Episodes { get; set; } + + public DateTime AddedAt { get; set; } + + [NotMapped] + public bool HasImdb => !string.IsNullOrEmpty(ImdbId); + + [NotMapped] + public bool HasTvDb => !string.IsNullOrEmpty(TvDbId); + + [NotMapped] + public bool HasTheMovieDb => !string.IsNullOrEmpty(TheMovieDbId); + + [NotMapped] + public abstract RecentlyAddedType RecentlyAddedType { get; } + } + + public abstract class MediaServerEpisode: Entity, IMediaServerEpisode + { + public int EpisodeNumber { get; set; } + public int SeasonNumber { get; set; } + public string Title { get; set; } + + public IMediaServerContent Series { get; set; } + + public abstract IMediaServerContent SeriesIsIn(ICollection content); + public bool IsIn(IMediaServerContent content) + { + return content.Episodes.Any(x => x.SeasonNumber == this.SeasonNumber && x.EpisodeNumber == this.EpisodeNumber); + } + } +} \ No newline at end of file diff --git a/src/Ombi.Store/Entities/OmbiUser.cs b/src/Ombi.Store/Entities/OmbiUser.cs index 1b7ea6f7c..376db28f7 100644 --- a/src/Ombi.Store/Entities/OmbiUser.cs +++ b/src/Ombi.Store/Entities/OmbiUser.cs @@ -36,6 +36,7 @@ namespace Ombi.Store.Entities public RequestLimitType? MusicRequestLimitType { get; set; } public string UserAccessToken { get; set; } + public string MediaServerToken { get; set; } public List NotificationUserIds { get; set; } public List UserNotificationPreferences { get; set; } diff --git a/src/Ombi.Store/Entities/PlexEpisode.cs b/src/Ombi.Store/Entities/PlexEpisode.cs index 3acca8f3b..a9628a13d 100644 --- a/src/Ombi.Store/Entities/PlexEpisode.cs +++ b/src/Ombi.Store/Entities/PlexEpisode.cs @@ -1,30 +1,32 @@ -using System.ComponentModel.DataAnnotations.Schema; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; namespace Ombi.Store.Entities { [Table("PlexEpisode")] - public class PlexEpisode : Entity + public class PlexEpisode : MediaServerEpisode { - public int EpisodeNumber { get; set; } - public int SeasonNumber { get; set; } - public int Key { get; set; } // RatingKey - public string Title { get; set; } - /// - /// The Season key - /// + public string Key { get; set; } // RatingKey /// /// The parent key. /// - public int ParentKey { get; set; } - /// - /// The Series key - /// + public string ParentKey { get; set; } /// /// The grandparent key. /// - public int GrandparentKey { get; set; } + public string GrandparentKey { get; set; } + [NotMapped] + public PlexServerContent PlexSeries + { + get => (PlexServerContent)Series; + set => Series = value; + } - - public PlexServerContent Series { get; set; } + public override IMediaServerContent SeriesIsIn(ICollection content) + { + return content.OfType().FirstOrDefault( + x => x.Key == this.PlexSeries.Key); + } } } \ No newline at end of file diff --git a/src/Ombi.Store/Entities/PlexServerContent.cs b/src/Ombi.Store/Entities/PlexServerContent.cs index f8e0e01d4..8af5e250e 100644 --- a/src/Ombi.Store/Entities/PlexServerContent.cs +++ b/src/Ombi.Store/Entities/PlexServerContent.cs @@ -32,51 +32,27 @@ using System.ComponentModel.DataAnnotations.Schema; namespace Ombi.Store.Entities { [Table("PlexServerContent")] - public class PlexServerContent : Entity + public class PlexServerContent : MediaServerContent { - public string Title { get; set; } public string ReleaseYear { get; set; } - public string ImdbId { get; set; } - public string TvDbId { get; set; } - public string TheMovieDbId { get; set; } - public PlexMediaTypeEntity Type { get; set; } - - public string Url { get; set; } - - public ICollection Episodes { get; set; } public ICollection Seasons { get; set; } /// /// Plex's internal ID for this item /// - public int Key { get; set; } - public DateTime AddedAt { get; set; } - public string Quality { get; set; } + public string Key { get; set; } public int? RequestId { get; set; } - - [NotMapped] - public bool HasImdb => !string.IsNullOrEmpty(ImdbId); - - [NotMapped] - public bool HasTvDb => !string.IsNullOrEmpty(TvDbId); - - [NotMapped] - public bool HasTheMovieDb => !string.IsNullOrEmpty(TheMovieDbId); + + public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Plex; } [Table("PlexSeasonsContent")] public class PlexSeasonsContent : Entity { - public int PlexContentId { get; set; } + public string PlexContentId { get; set; } public int SeasonNumber { get; set; } - public int SeasonKey { get; set; } - public int ParentKey { get; set; } - } - - public enum PlexMediaTypeEntity - { - Movie = 0, - Show = 1 + public string SeasonKey { get; set; } + public string ParentKey { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Store/Entities/PlexWatchlistHistory.cs b/src/Ombi.Store/Entities/PlexWatchlistHistory.cs new file mode 100644 index 000000000..e6aee29b4 --- /dev/null +++ b/src/Ombi.Store/Entities/PlexWatchlistHistory.cs @@ -0,0 +1,10 @@ +using System.ComponentModel.DataAnnotations.Schema; + +namespace Ombi.Store.Entities +{ + [Table(nameof(PlexWatchlistHistory))] + public class PlexWatchlistHistory : Entity + { + public string TmdbId { get; set; } + } +} diff --git a/src/Ombi.Store/Entities/RadarrCache.cs b/src/Ombi.Store/Entities/RadarrCache.cs index 4b62412fc..553e84f2b 100644 --- a/src/Ombi.Store/Entities/RadarrCache.cs +++ b/src/Ombi.Store/Entities/RadarrCache.cs @@ -7,5 +7,7 @@ namespace Ombi.Store.Entities { public int TheMovieDbId { get; set; } public bool HasFile { get; set; } + public bool Has4K { get; set; } + public bool HasRegular { get; set; } } } \ No newline at end of file diff --git a/src/Ombi.Store/Entities/Requests/BaseRequest.cs b/src/Ombi.Store/Entities/Requests/BaseRequest.cs index 596041a51..9c564376b 100644 --- a/src/Ombi.Store/Entities/Requests/BaseRequest.cs +++ b/src/Ombi.Store/Entities/Requests/BaseRequest.cs @@ -22,8 +22,10 @@ namespace Ombi.Store.Entities.Requests [ForeignKey(nameof(RequestedUserId))] public OmbiUser RequestedUser { get; set; } + public RequestSource Source { get; set; } = RequestSource.Ombi; + [NotMapped] - public bool CanApprove => !Approved && !Available; + public virtual bool CanApprove => !Approved && !Available; } } \ No newline at end of file diff --git a/src/Ombi.Store/Entities/Requests/Issues.cs b/src/Ombi.Store/Entities/Requests/Issues.cs index 082261a15..ea64365be 100644 --- a/src/Ombi.Store/Entities/Requests/Issues.cs +++ b/src/Ombi.Store/Entities/Requests/Issues.cs @@ -25,6 +25,8 @@ namespace Ombi.Store.Entities.Requests public string UserReportedId { get; set; } public OmbiUser UserReported { get; set; } public List Comments { get; set; } + [NotMapped] + public string PosterPath { get; set; } } public enum IssueStatus diff --git a/src/Ombi.Store/Entities/Requests/MovieRequests.cs b/src/Ombi.Store/Entities/Requests/MovieRequests.cs index 42b17be73..415efded2 100644 --- a/src/Ombi.Store/Entities/Requests/MovieRequests.cs +++ b/src/Ombi.Store/Entities/Requests/MovieRequests.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.ComponentModel.DataAnnotations.Schema; using Newtonsoft.Json; +using System; namespace Ombi.Store.Entities.Requests { @@ -22,9 +23,28 @@ namespace Ombi.Store.Entities.Requests [NotMapped] public bool ShowSubscribe { get; set; } + /// + /// This is only used during the request process to identify if + /// it's a regular request or a 4k + /// + [NotMapped] + public bool Is4kRequest { get; set; } + public int RootPathOverride { get; set; } public int QualityOverride { get; set; } + public bool Has4KRequest { get; set; } + + public bool Approved4K { get; set; } + public DateTime MarkedAsApproved4K { get; set; } + public DateTime RequestedDate4k { get; set; } + public bool Available4K { get; set; } + public DateTime? MarkedAsAvailable4K { get; set; } + public bool? Denied4K { get; set; } + public DateTime MarkedAsDenied4K { get; set; } + public string DeniedReason4K { get; set; } + + /// /// Only Use for setting the Language Code, Use the LanguageCode property for reading /// @@ -61,5 +81,8 @@ namespace Ombi.Store.Entities.Requests return string.Empty; } } + + [NotMapped] + public override bool CanApprove => !Approved && !Available || !Approved4K && !Available4K; } } diff --git a/src/Ombi.Store/Entities/Requests/RequestSource.cs b/src/Ombi.Store/Entities/Requests/RequestSource.cs new file mode 100644 index 000000000..44ccc20d8 --- /dev/null +++ b/src/Ombi.Store/Entities/Requests/RequestSource.cs @@ -0,0 +1,8 @@ +namespace Ombi.Store.Entities.Requests +{ + public enum RequestSource + { + Ombi = 0, + PlexWatchlist = 1 + } +} diff --git a/src/Ombi.Store/Entities/Requests/SeasonRequests.cs b/src/Ombi.Store/Entities/Requests/SeasonRequests.cs index 0d8d587a5..5de8003a1 100644 --- a/src/Ombi.Store/Entities/Requests/SeasonRequests.cs +++ b/src/Ombi.Store/Entities/Requests/SeasonRequests.cs @@ -31,6 +31,8 @@ namespace Ombi.Store.Repository.Requests public bool Requested { get; set; } [NotMapped] public bool? Denied { get; set; } + [NotMapped] + public string DeniedReason { get; set; } public int SeasonId { get; set; } [ForeignKey(nameof(SeasonId))] @@ -58,7 +60,7 @@ namespace Ombi.Store.Repository.Requests return "Common.ProcessingRequest"; } - if (!Approved && !Available) + if (Requested && !Approved && !Available) { return "Common.PendingApproval"; } diff --git a/src/Ombi.Store/MigrationHelper.cs b/src/Ombi.Store/MigrationHelper.cs new file mode 100644 index 000000000..58b6d6b68 --- /dev/null +++ b/src/Ombi.Store/MigrationHelper.cs @@ -0,0 +1,24 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using System; + +namespace Ombi.Store +{ + internal static class MigrationHelper + { + public static void InsertRole(this MigrationBuilder mb, string role) + { + mb.Sql($@" +INSERT INTO AspnetRoles(Id, ConcurrencyStamp, Name, NormalizedName) +SELECT '{Guid.NewGuid()}','{Guid.NewGuid()}','{role}', '{role.ToUpper()}' +WHERE NOT EXISTS(SELECT 1 FROM AspnetRoles WHERE Name = '{role}');"); + } + + public static void InsertRoleMySql(this MigrationBuilder mb, string role) + { + mb.Sql($@" +INSERT INTO AspNetRoles(Id, ConcurrencyStamp, Name, NormalizedName) +SELECT '{Guid.NewGuid()}','{Guid.NewGuid()}','{role}', '{role.ToUpper()}' +WHERE NOT EXISTS(SELECT 1 FROM AspNetRoles WHERE Name = '{role}');"); + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalMySql/20220211213229_MediaServerQualities.Designer.cs b/src/Ombi.Store/Migrations/ExternalMySql/20220211213229_MediaServerQualities.Designer.cs new file mode 100644 index 000000000..ab88ff30d --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalMySql/20220211213229_MediaServerQualities.Designer.cs @@ -0,0 +1,527 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.MySql; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalMySql +{ + [DbContext(typeof(ExternalMySqlContext))] + [Migration("20220211213229_MediaServerQualities")] + partial class MediaServerQualities + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("CouchPotatoCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EmbyId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("EmbyContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EmbyId") + .HasColumnType("longtext"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("ParentId") + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("JellyfinId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("JellyfinContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("JellyfinId") + .HasColumnType("longtext"); + + b.Property("ParentId") + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("JellyfinEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("ArtistId") + .HasColumnType("int"); + + b.Property("ForeignAlbumId") + .HasColumnType("longtext"); + + b.Property("Monitored") + .HasColumnType("tinyint(1)"); + + b.Property("PercentOfTracks") + .HasColumnType("decimal(65,30)"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TrackCount") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("LidarrAlbumCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ArtistId") + .HasColumnType("int"); + + b.Property("ArtistName") + .HasColumnType("longtext"); + + b.Property("ForeignArtistId") + .HasColumnType("longtext"); + + b.Property("Monitored") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("LidarrArtistCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("GrandparentKey") + .HasColumnType("int"); + + b.Property("Key") + .HasColumnType("int"); + + b.Property("ParentKey") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("GrandparentKey"); + + b.ToTable("PlexEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ParentKey") + .HasColumnType("int"); + + b.Property("PlexContentId") + .HasColumnType("int"); + + b.Property("PlexServerContentId") + .HasColumnType("int"); + + b.Property("SeasonKey") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PlexServerContentId"); + + b.ToTable("PlexSeasonsContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("Key") + .HasColumnType("int"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("ReleaseYear") + .HasColumnType("longtext"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PlexServerContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("HasFile") + .HasColumnType("tinyint(1)"); + + b.Property("HasRegular") + .HasColumnType("tinyint(1)"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("RadarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SickRageCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SickRageEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SonarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("HasFile") + .HasColumnType("tinyint(1)"); + + b.Property("MovieDbId") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SonarrEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.HasOne("Ombi.Store.Entities.JellyfinContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("JellyfinId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") + .WithMany("Episodes") + .HasForeignKey("GrandparentKey") + .HasPrincipalKey("Key") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", null) + .WithMany("Seasons") + .HasForeignKey("PlexServerContentId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Navigation("Episodes"); + + b.Navigation("Seasons"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalMySql/20220211213229_MediaServerQualities.cs b/src/Ombi.Store/Migrations/ExternalMySql/20220211213229_MediaServerQualities.cs new file mode 100644 index 000000000..add7da05e --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalMySql/20220211213229_MediaServerQualities.cs @@ -0,0 +1,59 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalMySql +{ + public partial class MediaServerQualities : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Has4K", + table: "RadarrCache", + type: "tinyint(1)", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "HasRegular", + table: "RadarrCache", + type: "tinyint(1)", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Quality", + table: "JellyfinContent", + type: "longtext", + nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddColumn( + name: "Quality", + table: "EmbyContent", + type: "longtext", + nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Has4K", + table: "RadarrCache"); + + migrationBuilder.DropColumn( + name: "HasRegular", + table: "RadarrCache"); + + migrationBuilder.DropColumn( + name: "Quality", + table: "JellyfinContent"); + + migrationBuilder.DropColumn( + name: "Quality", + table: "EmbyContent"); + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalMySql/20220212210902_MediaServer4k.Designer.cs b/src/Ombi.Store/Migrations/ExternalMySql/20220212210902_MediaServer4k.Designer.cs new file mode 100644 index 000000000..fbdc63e32 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalMySql/20220212210902_MediaServer4k.Designer.cs @@ -0,0 +1,536 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.MySql; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalMySql +{ + [DbContext(typeof(ExternalMySqlContext))] + [Migration("20220212210902_MediaServer4k")] + partial class MediaServer4k + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("CouchPotatoCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EmbyId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("EmbyContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EmbyId") + .HasColumnType("longtext"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("ParentId") + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("JellyfinId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("JellyfinContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("JellyfinId") + .HasColumnType("longtext"); + + b.Property("ParentId") + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("JellyfinEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("ArtistId") + .HasColumnType("int"); + + b.Property("ForeignAlbumId") + .HasColumnType("longtext"); + + b.Property("Monitored") + .HasColumnType("tinyint(1)"); + + b.Property("PercentOfTracks") + .HasColumnType("decimal(65,30)"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TrackCount") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("LidarrAlbumCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ArtistId") + .HasColumnType("int"); + + b.Property("ArtistName") + .HasColumnType("longtext"); + + b.Property("ForeignArtistId") + .HasColumnType("longtext"); + + b.Property("Monitored") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("LidarrArtistCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("GrandparentKey") + .HasColumnType("int"); + + b.Property("Key") + .HasColumnType("int"); + + b.Property("ParentKey") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("GrandparentKey"); + + b.ToTable("PlexEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ParentKey") + .HasColumnType("int"); + + b.Property("PlexContentId") + .HasColumnType("int"); + + b.Property("PlexServerContentId") + .HasColumnType("int"); + + b.Property("SeasonKey") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PlexServerContentId"); + + b.ToTable("PlexSeasonsContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("Key") + .HasColumnType("int"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("ReleaseYear") + .HasColumnType("longtext"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PlexServerContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("HasFile") + .HasColumnType("tinyint(1)"); + + b.Property("HasRegular") + .HasColumnType("tinyint(1)"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("RadarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SickRageCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SickRageEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SonarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("HasFile") + .HasColumnType("tinyint(1)"); + + b.Property("MovieDbId") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SonarrEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.HasOne("Ombi.Store.Entities.JellyfinContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("JellyfinId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") + .WithMany("Episodes") + .HasForeignKey("GrandparentKey") + .HasPrincipalKey("Key") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", null) + .WithMany("Seasons") + .HasForeignKey("PlexServerContentId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Navigation("Episodes"); + + b.Navigation("Seasons"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalMySql/20220212210902_MediaServer4k.cs b/src/Ombi.Store/Migrations/ExternalMySql/20220212210902_MediaServer4k.cs new file mode 100644 index 000000000..c7e1888a6 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalMySql/20220212210902_MediaServer4k.cs @@ -0,0 +1,48 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalMySql +{ + public partial class MediaServer4k : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Has4K", + table: "PlexServerContent", + type: "tinyint(1)", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Has4K", + table: "JellyfinContent", + type: "tinyint(1)", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Has4K", + table: "EmbyContent", + type: "tinyint(1)", + nullable: false, + defaultValue: false); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Has4K", + table: "PlexServerContent"); + + migrationBuilder.DropColumn( + name: "Has4K", + table: "JellyfinContent"); + + migrationBuilder.DropColumn( + name: "Has4K", + table: "EmbyContent"); + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalMySql/20220407114744_PlexIds.Designer.cs b/src/Ombi.Store/Migrations/ExternalMySql/20220407114744_PlexIds.Designer.cs new file mode 100644 index 000000000..e0ca84108 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalMySql/20220407114744_PlexIds.Designer.cs @@ -0,0 +1,535 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.MySql; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalMySql +{ + [DbContext(typeof(ExternalMySqlContext))] + [Migration("20220407114744_PlexIds")] + partial class PlexIds + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("CouchPotatoCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EmbyId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("EmbyContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EmbyId") + .HasColumnType("longtext"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("ParentId") + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("JellyfinId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("JellyfinContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("JellyfinId") + .HasColumnType("longtext"); + + b.Property("ParentId") + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("JellyfinEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("ArtistId") + .HasColumnType("int"); + + b.Property("ForeignAlbumId") + .HasColumnType("longtext"); + + b.Property("Monitored") + .HasColumnType("tinyint(1)"); + + b.Property("PercentOfTracks") + .HasColumnType("decimal(65,30)"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TrackCount") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("LidarrAlbumCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ArtistId") + .HasColumnType("int"); + + b.Property("ArtistName") + .HasColumnType("longtext"); + + b.Property("ForeignArtistId") + .HasColumnType("longtext"); + + b.Property("Monitored") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("LidarrArtistCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("GrandparentKey") + .HasColumnType("varchar(255)"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.Property("ParentKey") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("GrandparentKey"); + + b.ToTable("PlexEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ParentKey") + .HasColumnType("longtext"); + + b.Property("PlexContentId") + .HasColumnType("longtext"); + + b.Property("PlexServerContentId") + .HasColumnType("int"); + + b.Property("SeasonKey") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PlexServerContentId"); + + b.ToTable("PlexSeasonsContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("Key") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("ReleaseYear") + .HasColumnType("longtext"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PlexServerContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("HasFile") + .HasColumnType("tinyint(1)"); + + b.Property("HasRegular") + .HasColumnType("tinyint(1)"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("RadarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SickRageCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SickRageEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SonarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("HasFile") + .HasColumnType("tinyint(1)"); + + b.Property("MovieDbId") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SonarrEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.HasOne("Ombi.Store.Entities.JellyfinContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("JellyfinId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") + .WithMany("Episodes") + .HasForeignKey("GrandparentKey") + .HasPrincipalKey("Key"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", null) + .WithMany("Seasons") + .HasForeignKey("PlexServerContentId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Navigation("Episodes"); + + b.Navigation("Seasons"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalMySql/20220407114744_PlexIds.cs b/src/Ombi.Store/Migrations/ExternalMySql/20220407114744_PlexIds.cs new file mode 100644 index 000000000..826260c93 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalMySql/20220407114744_PlexIds.cs @@ -0,0 +1,176 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalMySql +{ + public partial class PlexIds : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_PlexEpisode_PlexServerContent_GrandparentKey", + table: "PlexEpisode"); + + migrationBuilder.AlterColumn( + name: "Key", + table: "PlexServerContent", + type: "varchar(255)", + nullable: false, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "SeasonKey", + table: "PlexSeasonsContent", + type: "longtext", + nullable: true, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "PlexContentId", + table: "PlexSeasonsContent", + type: "longtext", + nullable: true, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "ParentKey", + table: "PlexSeasonsContent", + type: "longtext", + nullable: true, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "ParentKey", + table: "PlexEpisode", + type: "longtext", + nullable: true, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "Key", + table: "PlexEpisode", + type: "longtext", + nullable: true, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "GrandparentKey", + table: "PlexEpisode", + type: "varchar(255)", + nullable: true, + oldClrType: typeof(int), + oldType: "int") + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddForeignKey( + name: "FK_PlexEpisode_PlexServerContent_GrandparentKey", + table: "PlexEpisode", + column: "GrandparentKey", + principalTable: "PlexServerContent", + principalColumn: "Key"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_PlexEpisode_PlexServerContent_GrandparentKey", + table: "PlexEpisode"); + + migrationBuilder.AlterColumn( + name: "Key", + table: "PlexServerContent", + type: "int", + nullable: false, + oldClrType: typeof(string), + oldType: "varchar(255)") + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "SeasonKey", + table: "PlexSeasonsContent", + type: "int", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true) + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "PlexContentId", + table: "PlexSeasonsContent", + type: "int", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true) + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "ParentKey", + table: "PlexSeasonsContent", + type: "int", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true) + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "ParentKey", + table: "PlexEpisode", + type: "int", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true) + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "Key", + table: "PlexEpisode", + type: "int", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "longtext", + oldNullable: true) + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AlterColumn( + name: "GrandparentKey", + table: "PlexEpisode", + type: "int", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "varchar(255)", + oldNullable: true) + .OldAnnotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddForeignKey( + name: "FK_PlexEpisode_PlexServerContent_GrandparentKey", + table: "PlexEpisode", + column: "GrandparentKey", + principalTable: "PlexServerContent", + principalColumn: "Key", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalMySql/20220411193943_WatchlistHistory.Designer.cs b/src/Ombi.Store/Migrations/ExternalMySql/20220411193943_WatchlistHistory.Designer.cs new file mode 100644 index 000000000..69d012d5d --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalMySql/20220411193943_WatchlistHistory.Designer.cs @@ -0,0 +1,549 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.MySql; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalMySql +{ + [DbContext(typeof(ExternalMySqlContext))] + [Migration("20220411193943_WatchlistHistory")] + partial class WatchlistHistory + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("CouchPotatoCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EmbyId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("EmbyContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EmbyId") + .HasColumnType("longtext"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("ParentId") + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("JellyfinId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("JellyfinContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("JellyfinId") + .HasColumnType("longtext"); + + b.Property("ParentId") + .HasColumnType("varchar(255)"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("JellyfinEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("ArtistId") + .HasColumnType("int"); + + b.Property("ForeignAlbumId") + .HasColumnType("longtext"); + + b.Property("Monitored") + .HasColumnType("tinyint(1)"); + + b.Property("PercentOfTracks") + .HasColumnType("decimal(65,30)"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TrackCount") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("LidarrAlbumCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ArtistId") + .HasColumnType("int"); + + b.Property("ArtistName") + .HasColumnType("longtext"); + + b.Property("ForeignArtistId") + .HasColumnType("longtext"); + + b.Property("Monitored") + .HasColumnType("tinyint(1)"); + + b.HasKey("Id"); + + b.ToTable("LidarrArtistCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("GrandparentKey") + .HasColumnType("varchar(255)"); + + b.Property("Key") + .HasColumnType("longtext"); + + b.Property("ParentKey") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("GrandparentKey"); + + b.ToTable("PlexEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ParentKey") + .HasColumnType("longtext"); + + b.Property("PlexContentId") + .HasColumnType("longtext"); + + b.Property("PlexServerContentId") + .HasColumnType("int"); + + b.Property("SeasonKey") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("PlexServerContentId"); + + b.ToTable("PlexSeasonsContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("Key") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.Property("Quality") + .HasColumnType("longtext"); + + b.Property("ReleaseYear") + .HasColumnType("longtext"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TvDbId") + .HasColumnType("longtext"); + + b.Property("Type") + .HasColumnType("int"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PlexServerContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexWatchlistHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TmdbId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PlexWatchlistHistory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + + b.Property("HasFile") + .HasColumnType("tinyint(1)"); + + b.Property("HasRegular") + .HasColumnType("tinyint(1)"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("RadarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SickRageCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SickRageEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SonarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("HasFile") + .HasColumnType("tinyint(1)"); + + b.Property("MovieDbId") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("SonarrEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.HasOne("Ombi.Store.Entities.JellyfinContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("JellyfinId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") + .WithMany("Episodes") + .HasForeignKey("GrandparentKey") + .HasPrincipalKey("Key"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", null) + .WithMany("Seasons") + .HasForeignKey("PlexServerContentId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Navigation("Episodes"); + + b.Navigation("Seasons"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalMySql/20220411193943_WatchlistHistory.cs b/src/Ombi.Store/Migrations/ExternalMySql/20220411193943_WatchlistHistory.cs new file mode 100644 index 000000000..760f40c25 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalMySql/20220411193943_WatchlistHistory.cs @@ -0,0 +1,34 @@ +using Microsoft.EntityFrameworkCore.Metadata; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalMySql +{ + public partial class WatchlistHistory : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "PlexWatchlistHistory", + columns: table => new + { + Id = table.Column(type: "int", nullable: false) + .Annotation("MySql:ValueGenerationStrategy", MySqlValueGenerationStrategy.IdentityColumn), + TmdbId = table.Column(type: "longtext", nullable: true) + .Annotation("MySql:CharSet", "utf8mb4") + }, + constraints: table => + { + table.PrimaryKey("PK_PlexWatchlistHistory", x => x.Id); + }) + .Annotation("MySql:CharSet", "utf8mb4"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "PlexWatchlistHistory"); + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalMySql/ExternalMySqlContextModelSnapshot.cs b/src/Ombi.Store/Migrations/ExternalMySql/ExternalMySqlContextModelSnapshot.cs index dbdbe6f55..1e86ddf7b 100644 --- a/src/Ombi.Store/Migrations/ExternalMySql/ExternalMySqlContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/ExternalMySql/ExternalMySqlContextModelSnapshot.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Ombi.Store.Context.MySql; +#nullable disable + namespace Ombi.Store.Migrations.ExternalMySql { [DbContext(typeof(ExternalMySqlContext))] @@ -14,8 +16,8 @@ namespace Ombi.Store.Migrations.ExternalMySql { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("Relational:MaxIdentifierLength", 64) - .HasAnnotation("ProductVersion", "5.0.1"); + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => { @@ -44,12 +46,18 @@ namespace Ombi.Store.Migrations.ExternalMySql .IsRequired() .HasColumnType("varchar(255)"); + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + b.Property("ImdbId") .HasColumnType("longtext"); b.Property("ProviderId") .HasColumnType("longtext"); + b.Property("Quality") + .HasColumnType("longtext"); + b.Property("TheMovieDbId") .HasColumnType("longtext"); @@ -122,6 +130,9 @@ namespace Ombi.Store.Migrations.ExternalMySql b.Property("AddedAt") .HasColumnType("datetime(6)"); + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + b.Property("ImdbId") .HasColumnType("longtext"); @@ -132,6 +143,9 @@ namespace Ombi.Store.Migrations.ExternalMySql b.Property("ProviderId") .HasColumnType("longtext"); + b.Property("Quality") + .HasColumnType("longtext"); + b.Property("TheMovieDbId") .HasColumnType("longtext"); @@ -262,14 +276,14 @@ namespace Ombi.Store.Migrations.ExternalMySql b.Property("EpisodeNumber") .HasColumnType("int"); - b.Property("GrandparentKey") - .HasColumnType("int"); + b.Property("GrandparentKey") + .HasColumnType("varchar(255)"); - b.Property("Key") - .HasColumnType("int"); + b.Property("Key") + .HasColumnType("longtext"); - b.Property("ParentKey") - .HasColumnType("int"); + b.Property("ParentKey") + .HasColumnType("longtext"); b.Property("SeasonNumber") .HasColumnType("int"); @@ -290,17 +304,17 @@ namespace Ombi.Store.Migrations.ExternalMySql .ValueGeneratedOnAdd() .HasColumnType("int"); - b.Property("ParentKey") - .HasColumnType("int"); + b.Property("ParentKey") + .HasColumnType("longtext"); - b.Property("PlexContentId") - .HasColumnType("int"); + b.Property("PlexContentId") + .HasColumnType("longtext"); b.Property("PlexServerContentId") .HasColumnType("int"); - b.Property("SeasonKey") - .HasColumnType("int"); + b.Property("SeasonKey") + .HasColumnType("longtext"); b.Property("SeasonNumber") .HasColumnType("int"); @@ -321,11 +335,15 @@ namespace Ombi.Store.Migrations.ExternalMySql b.Property("AddedAt") .HasColumnType("datetime(6)"); + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + b.Property("ImdbId") .HasColumnType("longtext"); - b.Property("Key") - .HasColumnType("int"); + b.Property("Key") + .IsRequired() + .HasColumnType("varchar(255)"); b.Property("Quality") .HasColumnType("longtext"); @@ -356,15 +374,35 @@ namespace Ombi.Store.Migrations.ExternalMySql b.ToTable("PlexServerContent"); }); + modelBuilder.Entity("Ombi.Store.Entities.PlexWatchlistHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("TmdbId") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("PlexWatchlistHistory"); + }); + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("int"); + b.Property("Has4K") + .HasColumnType("tinyint(1)"); + b.Property("HasFile") .HasColumnType("tinyint(1)"); + b.Property("HasRegular") + .HasColumnType("tinyint(1)"); + b.Property("TheMovieDbId") .HasColumnType("int"); @@ -475,9 +513,7 @@ namespace Ombi.Store.Migrations.ExternalMySql b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") .WithMany("Episodes") .HasForeignKey("GrandparentKey") - .HasPrincipalKey("Key") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + .HasPrincipalKey("Key"); b.Navigation("Series"); }); diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/20220211213347_MediaServerQualities.Designer.cs b/src/Ombi.Store/Migrations/ExternalSqlite/20220211213347_MediaServerQualities.Designer.cs new file mode 100644 index 000000000..4ec8422d5 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalSqlite/20220211213347_MediaServerQualities.Designer.cs @@ -0,0 +1,525 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.Sqlite; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalSqlite +{ + [DbContext(typeof(ExternalSqliteContext))] + [Migration("20220211213347_MediaServerQualities")] + partial class MediaServerQualities + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); + + modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("CouchPotatoCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EmbyId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("EmbyContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EmbyId") + .HasColumnType("TEXT"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("ParentId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("JellyfinId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("JellyfinContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("JellyfinId") + .HasColumnType("TEXT"); + + b.Property("ParentId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("JellyfinEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("ArtistId") + .HasColumnType("INTEGER"); + + b.Property("ForeignAlbumId") + .HasColumnType("TEXT"); + + b.Property("Monitored") + .HasColumnType("INTEGER"); + + b.Property("PercentOfTracks") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TrackCount") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("LidarrAlbumCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistId") + .HasColumnType("INTEGER"); + + b.Property("ArtistName") + .HasColumnType("TEXT"); + + b.Property("ForeignArtistId") + .HasColumnType("TEXT"); + + b.Property("Monitored") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("LidarrArtistCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("GrandparentKey") + .HasColumnType("INTEGER"); + + b.Property("Key") + .HasColumnType("INTEGER"); + + b.Property("ParentKey") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("GrandparentKey"); + + b.ToTable("PlexEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ParentKey") + .HasColumnType("INTEGER"); + + b.Property("PlexContentId") + .HasColumnType("INTEGER"); + + b.Property("PlexServerContentId") + .HasColumnType("INTEGER"); + + b.Property("SeasonKey") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("PlexServerContentId"); + + b.ToTable("PlexSeasonsContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("INTEGER"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("ReleaseYear") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("PlexServerContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("HasFile") + .HasColumnType("INTEGER"); + + b.Property("HasRegular") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RadarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SickRageCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SickRageEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SonarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("HasFile") + .HasColumnType("INTEGER"); + + b.Property("MovieDbId") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SonarrEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.HasOne("Ombi.Store.Entities.JellyfinContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("JellyfinId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") + .WithMany("Episodes") + .HasForeignKey("GrandparentKey") + .HasPrincipalKey("Key") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", null) + .WithMany("Seasons") + .HasForeignKey("PlexServerContentId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Navigation("Episodes"); + + b.Navigation("Seasons"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/20220211213347_MediaServerQualities.cs b/src/Ombi.Store/Migrations/ExternalSqlite/20220211213347_MediaServerQualities.cs new file mode 100644 index 000000000..b194b7845 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalSqlite/20220211213347_MediaServerQualities.cs @@ -0,0 +1,57 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalSqlite +{ + public partial class MediaServerQualities : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Has4K", + table: "RadarrCache", + type: "INTEGER", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "HasRegular", + table: "RadarrCache", + type: "INTEGER", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Quality", + table: "JellyfinContent", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "Quality", + table: "EmbyContent", + type: "TEXT", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Has4K", + table: "RadarrCache"); + + migrationBuilder.DropColumn( + name: "HasRegular", + table: "RadarrCache"); + + migrationBuilder.DropColumn( + name: "Quality", + table: "JellyfinContent"); + + migrationBuilder.DropColumn( + name: "Quality", + table: "EmbyContent"); + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/20220212210807_MediaServer4k.Designer.cs b/src/Ombi.Store/Migrations/ExternalSqlite/20220212210807_MediaServer4k.Designer.cs new file mode 100644 index 000000000..70cd280e9 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalSqlite/20220212210807_MediaServer4k.Designer.cs @@ -0,0 +1,534 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.Sqlite; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalSqlite +{ + [DbContext(typeof(ExternalSqliteContext))] + [Migration("20220212210807_MediaServer4k")] + partial class MediaServer4k + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); + + modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("CouchPotatoCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EmbyId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("EmbyContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EmbyId") + .HasColumnType("TEXT"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("ParentId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("JellyfinId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("JellyfinContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("JellyfinId") + .HasColumnType("TEXT"); + + b.Property("ParentId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("JellyfinEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("ArtistId") + .HasColumnType("INTEGER"); + + b.Property("ForeignAlbumId") + .HasColumnType("TEXT"); + + b.Property("Monitored") + .HasColumnType("INTEGER"); + + b.Property("PercentOfTracks") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TrackCount") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("LidarrAlbumCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistId") + .HasColumnType("INTEGER"); + + b.Property("ArtistName") + .HasColumnType("TEXT"); + + b.Property("ForeignArtistId") + .HasColumnType("TEXT"); + + b.Property("Monitored") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("LidarrArtistCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("GrandparentKey") + .HasColumnType("INTEGER"); + + b.Property("Key") + .HasColumnType("INTEGER"); + + b.Property("ParentKey") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("GrandparentKey"); + + b.ToTable("PlexEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ParentKey") + .HasColumnType("INTEGER"); + + b.Property("PlexContentId") + .HasColumnType("INTEGER"); + + b.Property("PlexServerContentId") + .HasColumnType("INTEGER"); + + b.Property("SeasonKey") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("PlexServerContentId"); + + b.ToTable("PlexSeasonsContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("INTEGER"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("ReleaseYear") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("PlexServerContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("HasFile") + .HasColumnType("INTEGER"); + + b.Property("HasRegular") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RadarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SickRageCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SickRageEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SonarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("HasFile") + .HasColumnType("INTEGER"); + + b.Property("MovieDbId") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SonarrEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.HasOne("Ombi.Store.Entities.JellyfinContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("JellyfinId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") + .WithMany("Episodes") + .HasForeignKey("GrandparentKey") + .HasPrincipalKey("Key") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", null) + .WithMany("Seasons") + .HasForeignKey("PlexServerContentId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Navigation("Episodes"); + + b.Navigation("Seasons"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/20220212210807_MediaServer4k.cs b/src/Ombi.Store/Migrations/ExternalSqlite/20220212210807_MediaServer4k.cs new file mode 100644 index 000000000..593465c0a --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalSqlite/20220212210807_MediaServer4k.cs @@ -0,0 +1,48 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalSqlite +{ + public partial class MediaServer4k : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Has4K", + table: "PlexServerContent", + type: "INTEGER", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Has4K", + table: "JellyfinContent", + type: "INTEGER", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Has4K", + table: "EmbyContent", + type: "INTEGER", + nullable: false, + defaultValue: false); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Has4K", + table: "PlexServerContent"); + + migrationBuilder.DropColumn( + name: "Has4K", + table: "JellyfinContent"); + + migrationBuilder.DropColumn( + name: "Has4K", + table: "EmbyContent"); + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/20220406212825_PlexIds.Designer.cs b/src/Ombi.Store/Migrations/ExternalSqlite/20220406212825_PlexIds.Designer.cs new file mode 100644 index 000000000..eb5a07394 --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalSqlite/20220406212825_PlexIds.Designer.cs @@ -0,0 +1,533 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.Sqlite; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalSqlite +{ + [DbContext(typeof(ExternalSqliteContext))] + [Migration("20220406212825_PlexIds")] + partial class PlexIds + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); + + modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("CouchPotatoCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EmbyId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("EmbyContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EmbyId") + .HasColumnType("TEXT"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("ParentId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("JellyfinId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("JellyfinContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("JellyfinId") + .HasColumnType("TEXT"); + + b.Property("ParentId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("JellyfinEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("ArtistId") + .HasColumnType("INTEGER"); + + b.Property("ForeignAlbumId") + .HasColumnType("TEXT"); + + b.Property("Monitored") + .HasColumnType("INTEGER"); + + b.Property("PercentOfTracks") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TrackCount") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("LidarrAlbumCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistId") + .HasColumnType("INTEGER"); + + b.Property("ArtistName") + .HasColumnType("TEXT"); + + b.Property("ForeignArtistId") + .HasColumnType("TEXT"); + + b.Property("Monitored") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("LidarrArtistCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("GrandparentKey") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.Property("ParentKey") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("GrandparentKey"); + + b.ToTable("PlexEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ParentKey") + .HasColumnType("TEXT"); + + b.Property("PlexContentId") + .HasColumnType("TEXT"); + + b.Property("PlexServerContentId") + .HasColumnType("INTEGER"); + + b.Property("SeasonKey") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("PlexServerContentId"); + + b.ToTable("PlexSeasonsContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("ReleaseYear") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("PlexServerContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("HasFile") + .HasColumnType("INTEGER"); + + b.Property("HasRegular") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RadarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SickRageCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SickRageEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SonarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("HasFile") + .HasColumnType("INTEGER"); + + b.Property("MovieDbId") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SonarrEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.HasOne("Ombi.Store.Entities.JellyfinContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("JellyfinId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") + .WithMany("Episodes") + .HasForeignKey("GrandparentKey") + .HasPrincipalKey("Key"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", null) + .WithMany("Seasons") + .HasForeignKey("PlexServerContentId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Navigation("Episodes"); + + b.Navigation("Seasons"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/20220406212825_PlexIds.cs b/src/Ombi.Store/Migrations/ExternalSqlite/20220406212825_PlexIds.cs new file mode 100644 index 000000000..4f3d92ece --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalSqlite/20220406212825_PlexIds.cs @@ -0,0 +1,162 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalSqlite +{ + public partial class PlexIds : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_PlexEpisode_PlexServerContent_GrandparentKey", + table: "PlexEpisode"); + + migrationBuilder.AlterColumn( + name: "Key", + table: "PlexServerContent", + type: "TEXT", + nullable: false, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "SeasonKey", + table: "PlexSeasonsContent", + type: "TEXT", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "PlexContentId", + table: "PlexSeasonsContent", + type: "TEXT", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "ParentKey", + table: "PlexSeasonsContent", + type: "TEXT", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "ParentKey", + table: "PlexEpisode", + type: "TEXT", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "Key", + table: "PlexEpisode", + type: "TEXT", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AlterColumn( + name: "GrandparentKey", + table: "PlexEpisode", + type: "TEXT", + nullable: true, + oldClrType: typeof(int), + oldType: "INTEGER"); + + migrationBuilder.AddForeignKey( + name: "FK_PlexEpisode_PlexServerContent_GrandparentKey", + table: "PlexEpisode", + column: "GrandparentKey", + principalTable: "PlexServerContent", + principalColumn: "Key"); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropForeignKey( + name: "FK_PlexEpisode_PlexServerContent_GrandparentKey", + table: "PlexEpisode"); + + migrationBuilder.AlterColumn( + name: "Key", + table: "PlexServerContent", + type: "INTEGER", + nullable: false, + oldClrType: typeof(string), + oldType: "TEXT"); + + migrationBuilder.AlterColumn( + name: "SeasonKey", + table: "PlexSeasonsContent", + type: "INTEGER", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "PlexContentId", + table: "PlexSeasonsContent", + type: "INTEGER", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ParentKey", + table: "PlexSeasonsContent", + type: "INTEGER", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "ParentKey", + table: "PlexEpisode", + type: "INTEGER", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "Key", + table: "PlexEpisode", + type: "INTEGER", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AlterColumn( + name: "GrandparentKey", + table: "PlexEpisode", + type: "INTEGER", + nullable: false, + defaultValue: 0, + oldClrType: typeof(string), + oldType: "TEXT", + oldNullable: true); + + migrationBuilder.AddForeignKey( + name: "FK_PlexEpisode_PlexServerContent_GrandparentKey", + table: "PlexEpisode", + column: "GrandparentKey", + principalTable: "PlexServerContent", + principalColumn: "Key", + onDelete: ReferentialAction.Cascade); + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/20220411193827_WatchlistHistory.Designer.cs b/src/Ombi.Store/Migrations/ExternalSqlite/20220411193827_WatchlistHistory.Designer.cs new file mode 100644 index 000000000..03da8c7eb --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalSqlite/20220411193827_WatchlistHistory.Designer.cs @@ -0,0 +1,547 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.Sqlite; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalSqlite +{ + [DbContext(typeof(ExternalSqliteContext))] + [Migration("20220411193827_WatchlistHistory")] + partial class WatchlistHistory + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); + + modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("CouchPotatoCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EmbyId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("EmbyContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EmbyId") + .HasColumnType("TEXT"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("ParentId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("EmbyEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("JellyfinId") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("JellyfinContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("JellyfinId") + .HasColumnType("TEXT"); + + b.Property("ParentId") + .HasColumnType("TEXT"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentId"); + + b.ToTable("JellyfinEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrAlbumCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("ArtistId") + .HasColumnType("INTEGER"); + + b.Property("ForeignAlbumId") + .HasColumnType("TEXT"); + + b.Property("Monitored") + .HasColumnType("INTEGER"); + + b.Property("PercentOfTracks") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TrackCount") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("LidarrAlbumCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.LidarrArtistCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ArtistId") + .HasColumnType("INTEGER"); + + b.Property("ArtistName") + .HasColumnType("TEXT"); + + b.Property("ForeignArtistId") + .HasColumnType("TEXT"); + + b.Property("Monitored") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("LidarrArtistCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("GrandparentKey") + .HasColumnType("TEXT"); + + b.Property("Key") + .HasColumnType("TEXT"); + + b.Property("ParentKey") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("GrandparentKey"); + + b.ToTable("PlexEpisode"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ParentKey") + .HasColumnType("TEXT"); + + b.Property("PlexContentId") + .HasColumnType("TEXT"); + + b.Property("PlexServerContentId") + .HasColumnType("INTEGER"); + + b.Property("SeasonKey") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("PlexServerContentId"); + + b.ToTable("PlexSeasonsContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("Quality") + .HasColumnType("TEXT"); + + b.Property("ReleaseYear") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TvDbId") + .HasColumnType("TEXT"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("PlexServerContent"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexWatchlistHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TmdbId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("PlexWatchlistHistory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Has4K") + .HasColumnType("INTEGER"); + + b.Property("HasFile") + .HasColumnType("INTEGER"); + + b.Property("HasRegular") + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RadarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SickRageCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SickRageEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SickRageEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SonarrCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.SonarrEpisodeCache", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("HasFile") + .HasColumnType("INTEGER"); + + b.Property("MovieDbId") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("SonarrEpisodeCache"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyEpisode", b => + { + b.HasOne("Ombi.Store.Entities.EmbyContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("EmbyId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinEpisode", b => + { + b.HasOne("Ombi.Store.Entities.JellyfinContent", "Series") + .WithMany("Episodes") + .HasForeignKey("ParentId") + .HasPrincipalKey("JellyfinId"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexEpisode", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") + .WithMany("Episodes") + .HasForeignKey("GrandparentKey") + .HasPrincipalKey("Key"); + + b.Navigation("Series"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexSeasonsContent", b => + { + b.HasOne("Ombi.Store.Entities.PlexServerContent", null) + .WithMany("Seasons") + .HasForeignKey("PlexServerContentId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.EmbyContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.JellyfinContent", b => + { + b.Navigation("Episodes"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.PlexServerContent", b => + { + b.Navigation("Episodes"); + + b.Navigation("Seasons"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/20220411193827_WatchlistHistory.cs b/src/Ombi.Store/Migrations/ExternalSqlite/20220411193827_WatchlistHistory.cs new file mode 100644 index 000000000..030cefa1d --- /dev/null +++ b/src/Ombi.Store/Migrations/ExternalSqlite/20220411193827_WatchlistHistory.cs @@ -0,0 +1,31 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.ExternalSqlite +{ + public partial class WatchlistHistory : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "PlexWatchlistHistory", + columns: table => new + { + Id = table.Column(type: "INTEGER", nullable: false) + .Annotation("Sqlite:Autoincrement", true), + TmdbId = table.Column(type: "TEXT", nullable: true) + }, + constraints: table => + { + table.PrimaryKey("PK_PlexWatchlistHistory", x => x.Id); + }); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "PlexWatchlistHistory"); + } + } +} diff --git a/src/Ombi.Store/Migrations/ExternalSqlite/ExternalSqliteContextModelSnapshot.cs b/src/Ombi.Store/Migrations/ExternalSqlite/ExternalSqliteContextModelSnapshot.cs index 00d4f44f4..2f5de3382 100644 --- a/src/Ombi.Store/Migrations/ExternalSqlite/ExternalSqliteContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/ExternalSqlite/ExternalSqliteContextModelSnapshot.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Ombi.Store.Context.Sqlite; +#nullable disable + namespace Ombi.Store.Migrations.ExternalSqlite { [DbContext(typeof(ExternalSqliteContext))] @@ -13,8 +15,7 @@ namespace Ombi.Store.Migrations.ExternalSqlite protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "5.0.1"); + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); modelBuilder.Entity("Ombi.Store.Entities.CouchPotatoCache", b => { @@ -43,12 +44,18 @@ namespace Ombi.Store.Migrations.ExternalSqlite .IsRequired() .HasColumnType("TEXT"); + b.Property("Has4K") + .HasColumnType("INTEGER"); + b.Property("ImdbId") .HasColumnType("TEXT"); b.Property("ProviderId") .HasColumnType("TEXT"); + b.Property("Quality") + .HasColumnType("TEXT"); + b.Property("TheMovieDbId") .HasColumnType("TEXT"); @@ -121,6 +128,9 @@ namespace Ombi.Store.Migrations.ExternalSqlite b.Property("AddedAt") .HasColumnType("TEXT"); + b.Property("Has4K") + .HasColumnType("INTEGER"); + b.Property("ImdbId") .HasColumnType("TEXT"); @@ -131,6 +141,9 @@ namespace Ombi.Store.Migrations.ExternalSqlite b.Property("ProviderId") .HasColumnType("TEXT"); + b.Property("Quality") + .HasColumnType("TEXT"); + b.Property("TheMovieDbId") .HasColumnType("TEXT"); @@ -261,14 +274,14 @@ namespace Ombi.Store.Migrations.ExternalSqlite b.Property("EpisodeNumber") .HasColumnType("INTEGER"); - b.Property("GrandparentKey") - .HasColumnType("INTEGER"); + b.Property("GrandparentKey") + .HasColumnType("TEXT"); - b.Property("Key") - .HasColumnType("INTEGER"); + b.Property("Key") + .HasColumnType("TEXT"); - b.Property("ParentKey") - .HasColumnType("INTEGER"); + b.Property("ParentKey") + .HasColumnType("TEXT"); b.Property("SeasonNumber") .HasColumnType("INTEGER"); @@ -289,17 +302,17 @@ namespace Ombi.Store.Migrations.ExternalSqlite .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); - b.Property("ParentKey") - .HasColumnType("INTEGER"); + b.Property("ParentKey") + .HasColumnType("TEXT"); - b.Property("PlexContentId") - .HasColumnType("INTEGER"); + b.Property("PlexContentId") + .HasColumnType("TEXT"); b.Property("PlexServerContentId") .HasColumnType("INTEGER"); - b.Property("SeasonKey") - .HasColumnType("INTEGER"); + b.Property("SeasonKey") + .HasColumnType("TEXT"); b.Property("SeasonNumber") .HasColumnType("INTEGER"); @@ -320,11 +333,15 @@ namespace Ombi.Store.Migrations.ExternalSqlite b.Property("AddedAt") .HasColumnType("TEXT"); + b.Property("Has4K") + .HasColumnType("INTEGER"); + b.Property("ImdbId") .HasColumnType("TEXT"); - b.Property("Key") - .HasColumnType("INTEGER"); + b.Property("Key") + .IsRequired() + .HasColumnType("TEXT"); b.Property("Quality") .HasColumnType("TEXT"); @@ -355,15 +372,35 @@ namespace Ombi.Store.Migrations.ExternalSqlite b.ToTable("PlexServerContent"); }); + modelBuilder.Entity("Ombi.Store.Entities.PlexWatchlistHistory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("TmdbId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("PlexWatchlistHistory"); + }); + modelBuilder.Entity("Ombi.Store.Entities.RadarrCache", b => { b.Property("Id") .ValueGeneratedOnAdd() .HasColumnType("INTEGER"); + b.Property("Has4K") + .HasColumnType("INTEGER"); + b.Property("HasFile") .HasColumnType("INTEGER"); + b.Property("HasRegular") + .HasColumnType("INTEGER"); + b.Property("TheMovieDbId") .HasColumnType("INTEGER"); @@ -474,9 +511,7 @@ namespace Ombi.Store.Migrations.ExternalSqlite b.HasOne("Ombi.Store.Entities.PlexServerContent", "Series") .WithMany("Episodes") .HasForeignKey("GrandparentKey") - .HasPrincipalKey("Key") - .OnDelete(DeleteBehavior.Cascade) - .IsRequired(); + .HasPrincipalKey("Key"); b.Navigation("Series"); }); diff --git a/src/Ombi.Store/Migrations/OmbiMySql/20220210195008_Radarr4kRole.Designer.cs b/src/Ombi.Store/Migrations/OmbiMySql/20220210195008_Radarr4kRole.Designer.cs new file mode 100644 index 000000000..713672bcf --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiMySql/20220210195008_Radarr4kRole.Designer.cs @@ -0,0 +1,1246 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.MySql; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiMySql +{ + [DbContext(typeof(OmbiMySqlContext))] + [Migration("20220210195008_Radarr4kRole")] + partial class Radarr4kRole + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255)"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("RoleId") + .HasColumnType("varchar(255)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Audit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AuditArea") + .HasColumnType("int"); + + b.Property("AuditType") + .HasColumnType("int"); + + b.Property("DateTime") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("User") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Audit"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("Token") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("MobileDevices"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Agent") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("Message") + .HasColumnType("longtext"); + + b.Property("NotificationType") + .HasColumnType("int"); + + b.Property("Subject") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("NotificationTemplates"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("PlayerId") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("Alias") + .HasColumnType("longtext"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("EpisodeRequestLimit") + .HasColumnType("int"); + + b.Property("EpisodeRequestLimitType") + .HasColumnType("int"); + + b.Property("Language") + .HasColumnType("longtext"); + + b.Property("LastLoggedIn") + .HasColumnType("datetime(6)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("MovieRequestLimit") + .HasColumnType("int"); + + b.Property("MovieRequestLimitType") + .HasColumnType("int"); + + b.Property("MusicRequestLimit") + .HasColumnType("int"); + + b.Property("MusicRequestLimitType") + .HasColumnType("int"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .HasColumnType("longtext"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("ProviderUserId") + .HasColumnType("longtext"); + + b.Property("SecurityStamp") + .HasColumnType("longtext"); + + b.Property("StreamingCountry") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserAccessToken") + .HasColumnType("longtext"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("UserType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("AlbumId") + .HasColumnType("longtext"); + + b.Property("ContentId") + .HasColumnType("int"); + + b.Property("ContentType") + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("RecentlyAddedLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestQueue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Completed") + .HasColumnType("datetime(6)"); + + b.Property("Dts") + .HasColumnType("datetime(6)"); + + b.Property("Error") + .HasColumnType("longtext"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RetryCount") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("RequestQueue"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("ArtistName") + .HasColumnType("longtext"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("Cover") + .HasColumnType("longtext"); + + b.Property("Denied") + .HasColumnType("tinyint(1)"); + + b.Property("DeniedReason") + .HasColumnType("longtext"); + + b.Property("Disk") + .HasColumnType("longtext"); + + b.Property("ForeignAlbumId") + .HasColumnType("longtext"); + + b.Property("ForeignArtistId") + .HasColumnType("longtext"); + + b.Property("MarkedAsApproved") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied") + .HasColumnType("datetime(6)"); + + b.Property("Rating") + .HasColumnType("decimal(65,30)"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("RequestedByAlias") + .HasColumnType("longtext"); + + b.Property("RequestedDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestedUserId") + .HasColumnType("varchar(255)"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("AlbumRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("Denied") + .HasColumnType("tinyint(1)"); + + b.Property("DeniedReason") + .HasColumnType("longtext"); + + b.Property("IssueId") + .HasColumnType("int"); + + b.Property("MarkedAsApproved") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied") + .HasColumnType("datetime(6)"); + + b.Property("ParentRequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("RequestedByAlias") + .HasColumnType("longtext"); + + b.Property("RequestedDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestedUserId") + .HasColumnType("varchar(255)"); + + b.Property("SeriesType") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentRequestId"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("IssueCategory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Comment") + .HasColumnType("longtext"); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("IssuesId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("IssuesId"); + + b.HasIndex("UserId"); + + b.ToTable("IssueComments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CreatedDate") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("IssueCategoryId") + .HasColumnType("int"); + + b.Property("IssueId") + .HasColumnType("int"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("ResovledDate") + .HasColumnType("datetime(6)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Subject") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("UserReportedId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("IssueCategoryId"); + + b.HasIndex("IssueId"); + + b.HasIndex("UserReportedId"); + + b.ToTable("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("Background") + .HasColumnType("longtext"); + + b.Property("Denied") + .HasColumnType("tinyint(1)"); + + b.Property("DeniedReason") + .HasColumnType("longtext"); + + b.Property("DigitalReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("IssueId") + .HasColumnType("int"); + + b.Property("LangCode") + .HasColumnType("longtext"); + + b.Property("MarkedAsApproved") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied") + .HasColumnType("datetime(6)"); + + b.Property("Overview") + .HasColumnType("longtext"); + + b.Property("PosterPath") + .HasColumnType("longtext"); + + b.Property("QualityOverride") + .HasColumnType("int"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("RequestedByAlias") + .HasColumnType("longtext"); + + b.Property("RequestedDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestedUserId") + .HasColumnType("varchar(255)"); + + b.Property("RootPathOverride") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("MovieRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeCount") + .HasColumnType("int"); + + b.Property("RequestDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Background") + .HasColumnType("longtext"); + + b.Property("ExternalProviderId") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("LanguageProfile") + .HasColumnType("int"); + + b.Property("Overview") + .HasColumnType("longtext"); + + b.Property("PosterPath") + .HasColumnType("longtext"); + + b.Property("QualityOverride") + .HasColumnType("int"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("RootFolder") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TotalSeasons") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("TvRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Token") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Agent") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("RadarrQualityProfile") + .HasColumnType("int"); + + b.Property("RadarrRootPath") + .HasColumnType("int"); + + b.Property("SonarrQualityProfile") + .HasColumnType("int"); + + b.Property("SonarrQualityProfileAnime") + .HasColumnType("int"); + + b.Property("SonarrRootPath") + .HasColumnType("int"); + + b.Property("SonarrRootPathAnime") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserQualityProfiles"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("tinyint(1)"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("VoteType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Votes"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AirDate") + .HasColumnType("datetime(6)"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("Requested") + .HasColumnType("tinyint(1)"); + + b.Property("SeasonId") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("EpisodeRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ChildRequestId") + .HasColumnType("int"); + + b.Property("Overview") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChildRequestId"); + + b.ToTable("SeasonRequests"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("NotificationUserIds") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest") + .WithMany("ChildRequests") + .HasForeignKey("ParentRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("ParentRequest"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues") + .WithMany("Comments") + .HasForeignKey("IssuesId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Issues"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory") + .WithMany() + .HasForeignKey("IssueCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.Requests.MovieRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported") + .WithMany() + .HasForeignKey("UserReportedId"); + + b.Navigation("IssueCategory"); + + b.Navigation("UserReported"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("UserNotificationPreferences") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest") + .WithMany("SeasonRequests") + .HasForeignKey("ChildRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChildRequest"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Navigation("NotificationUserIds"); + + b.Navigation("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Navigation("Issues"); + + b.Navigation("SeasonRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Navigation("Comments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Navigation("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Navigation("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Navigation("Episodes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiMySql/20220210195008_Radarr4kRole.cs b/src/Ombi.Store/Migrations/OmbiMySql/20220210195008_Radarr4kRole.cs new file mode 100644 index 000000000..88eeed9f2 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiMySql/20220210195008_Radarr4kRole.cs @@ -0,0 +1,20 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using Ombi.Helpers; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiMySql +{ + public partial class Radarr4kRole : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.InsertRoleMySql(OmbiRoles.Request4KMovie); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiMySql/20220210201011_MovieRequest4K.Designer.cs b/src/Ombi.Store/Migrations/OmbiMySql/20220210201011_MovieRequest4K.Designer.cs new file mode 100644 index 000000000..7a6c430bd --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiMySql/20220210201011_MovieRequest4K.Designer.cs @@ -0,0 +1,1249 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.MySql; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiMySql +{ + [DbContext(typeof(OmbiMySqlContext))] + [Migration("20220210201011_MovieRequest4K")] + partial class MovieRequest4K + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255)"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("RoleId") + .HasColumnType("varchar(255)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Audit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AuditArea") + .HasColumnType("int"); + + b.Property("AuditType") + .HasColumnType("int"); + + b.Property("DateTime") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("User") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Audit"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("Token") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("MobileDevices"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Agent") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("Message") + .HasColumnType("longtext"); + + b.Property("NotificationType") + .HasColumnType("int"); + + b.Property("Subject") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("NotificationTemplates"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("PlayerId") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("Alias") + .HasColumnType("longtext"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("EpisodeRequestLimit") + .HasColumnType("int"); + + b.Property("EpisodeRequestLimitType") + .HasColumnType("int"); + + b.Property("Language") + .HasColumnType("longtext"); + + b.Property("LastLoggedIn") + .HasColumnType("datetime(6)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("MovieRequestLimit") + .HasColumnType("int"); + + b.Property("MovieRequestLimitType") + .HasColumnType("int"); + + b.Property("MusicRequestLimit") + .HasColumnType("int"); + + b.Property("MusicRequestLimitType") + .HasColumnType("int"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .HasColumnType("longtext"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("ProviderUserId") + .HasColumnType("longtext"); + + b.Property("SecurityStamp") + .HasColumnType("longtext"); + + b.Property("StreamingCountry") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserAccessToken") + .HasColumnType("longtext"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("UserType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("AlbumId") + .HasColumnType("longtext"); + + b.Property("ContentId") + .HasColumnType("int"); + + b.Property("ContentType") + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("RecentlyAddedLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestQueue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Completed") + .HasColumnType("datetime(6)"); + + b.Property("Dts") + .HasColumnType("datetime(6)"); + + b.Property("Error") + .HasColumnType("longtext"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RetryCount") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("RequestQueue"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("ArtistName") + .HasColumnType("longtext"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("Cover") + .HasColumnType("longtext"); + + b.Property("Denied") + .HasColumnType("tinyint(1)"); + + b.Property("DeniedReason") + .HasColumnType("longtext"); + + b.Property("Disk") + .HasColumnType("longtext"); + + b.Property("ForeignAlbumId") + .HasColumnType("longtext"); + + b.Property("ForeignArtistId") + .HasColumnType("longtext"); + + b.Property("MarkedAsApproved") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied") + .HasColumnType("datetime(6)"); + + b.Property("Rating") + .HasColumnType("decimal(65,30)"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("RequestedByAlias") + .HasColumnType("longtext"); + + b.Property("RequestedDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestedUserId") + .HasColumnType("varchar(255)"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("AlbumRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("Denied") + .HasColumnType("tinyint(1)"); + + b.Property("DeniedReason") + .HasColumnType("longtext"); + + b.Property("IssueId") + .HasColumnType("int"); + + b.Property("MarkedAsApproved") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied") + .HasColumnType("datetime(6)"); + + b.Property("ParentRequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("RequestedByAlias") + .HasColumnType("longtext"); + + b.Property("RequestedDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestedUserId") + .HasColumnType("varchar(255)"); + + b.Property("SeriesType") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentRequestId"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("IssueCategory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Comment") + .HasColumnType("longtext"); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("IssuesId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("IssuesId"); + + b.HasIndex("UserId"); + + b.ToTable("IssueComments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CreatedDate") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("IssueCategoryId") + .HasColumnType("int"); + + b.Property("IssueId") + .HasColumnType("int"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("ResovledDate") + .HasColumnType("datetime(6)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Subject") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("UserReportedId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("IssueCategoryId"); + + b.HasIndex("IssueId"); + + b.HasIndex("UserReportedId"); + + b.ToTable("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("Background") + .HasColumnType("longtext"); + + b.Property("Denied") + .HasColumnType("tinyint(1)"); + + b.Property("DeniedReason") + .HasColumnType("longtext"); + + b.Property("DigitalReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("Is4KRequest") + .HasColumnType("tinyint(1)"); + + b.Property("IssueId") + .HasColumnType("int"); + + b.Property("LangCode") + .HasColumnType("longtext"); + + b.Property("MarkedAsApproved") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied") + .HasColumnType("datetime(6)"); + + b.Property("Overview") + .HasColumnType("longtext"); + + b.Property("PosterPath") + .HasColumnType("longtext"); + + b.Property("QualityOverride") + .HasColumnType("int"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("RequestedByAlias") + .HasColumnType("longtext"); + + b.Property("RequestedDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestedUserId") + .HasColumnType("varchar(255)"); + + b.Property("RootPathOverride") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("MovieRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeCount") + .HasColumnType("int"); + + b.Property("RequestDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Background") + .HasColumnType("longtext"); + + b.Property("ExternalProviderId") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("LanguageProfile") + .HasColumnType("int"); + + b.Property("Overview") + .HasColumnType("longtext"); + + b.Property("PosterPath") + .HasColumnType("longtext"); + + b.Property("QualityOverride") + .HasColumnType("int"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("RootFolder") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TotalSeasons") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("TvRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Token") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Agent") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("RadarrQualityProfile") + .HasColumnType("int"); + + b.Property("RadarrRootPath") + .HasColumnType("int"); + + b.Property("SonarrQualityProfile") + .HasColumnType("int"); + + b.Property("SonarrQualityProfileAnime") + .HasColumnType("int"); + + b.Property("SonarrRootPath") + .HasColumnType("int"); + + b.Property("SonarrRootPathAnime") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserQualityProfiles"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("tinyint(1)"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("VoteType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Votes"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AirDate") + .HasColumnType("datetime(6)"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("Requested") + .HasColumnType("tinyint(1)"); + + b.Property("SeasonId") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("EpisodeRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ChildRequestId") + .HasColumnType("int"); + + b.Property("Overview") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChildRequestId"); + + b.ToTable("SeasonRequests"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("NotificationUserIds") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest") + .WithMany("ChildRequests") + .HasForeignKey("ParentRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("ParentRequest"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues") + .WithMany("Comments") + .HasForeignKey("IssuesId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Issues"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory") + .WithMany() + .HasForeignKey("IssueCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.Requests.MovieRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported") + .WithMany() + .HasForeignKey("UserReportedId"); + + b.Navigation("IssueCategory"); + + b.Navigation("UserReported"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("UserNotificationPreferences") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest") + .WithMany("SeasonRequests") + .HasForeignKey("ChildRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChildRequest"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Navigation("NotificationUserIds"); + + b.Navigation("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Navigation("Issues"); + + b.Navigation("SeasonRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Navigation("Comments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Navigation("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Navigation("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Navigation("Episodes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiMySql/20220210201011_MovieRequest4K.cs b/src/Ombi.Store/Migrations/OmbiMySql/20220210201011_MovieRequest4K.cs new file mode 100644 index 000000000..f9d02b876 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiMySql/20220210201011_MovieRequest4K.cs @@ -0,0 +1,26 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiMySql +{ + public partial class MovieRequest4K : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Has4KRequest", + table: "MovieRequests", + type: "tinyint(1)", + nullable: false, + defaultValue: false); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Has4KRequest", + table: "MovieRequests"); + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiMySql/20220210215019_4kMovieProperties.Designer.cs b/src/Ombi.Store/Migrations/OmbiMySql/20220210215019_4kMovieProperties.Designer.cs new file mode 100644 index 000000000..240993d15 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiMySql/20220210215019_4kMovieProperties.Designer.cs @@ -0,0 +1,1273 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.MySql; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiMySql +{ + [DbContext(typeof(OmbiMySqlContext))] + [Migration("20220210215019_4kMovieProperties")] + partial class _4kMovieProperties + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255)"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("RoleId") + .HasColumnType("varchar(255)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Audit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AuditArea") + .HasColumnType("int"); + + b.Property("AuditType") + .HasColumnType("int"); + + b.Property("DateTime") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("User") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Audit"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("Token") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("MobileDevices"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Agent") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("Message") + .HasColumnType("longtext"); + + b.Property("NotificationType") + .HasColumnType("int"); + + b.Property("Subject") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("NotificationTemplates"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("PlayerId") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("Alias") + .HasColumnType("longtext"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("EpisodeRequestLimit") + .HasColumnType("int"); + + b.Property("EpisodeRequestLimitType") + .HasColumnType("int"); + + b.Property("Language") + .HasColumnType("longtext"); + + b.Property("LastLoggedIn") + .HasColumnType("datetime(6)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("MovieRequestLimit") + .HasColumnType("int"); + + b.Property("MovieRequestLimitType") + .HasColumnType("int"); + + b.Property("MusicRequestLimit") + .HasColumnType("int"); + + b.Property("MusicRequestLimitType") + .HasColumnType("int"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .HasColumnType("longtext"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("ProviderUserId") + .HasColumnType("longtext"); + + b.Property("SecurityStamp") + .HasColumnType("longtext"); + + b.Property("StreamingCountry") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserAccessToken") + .HasColumnType("longtext"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("UserType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("AlbumId") + .HasColumnType("longtext"); + + b.Property("ContentId") + .HasColumnType("int"); + + b.Property("ContentType") + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("RecentlyAddedLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestQueue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Completed") + .HasColumnType("datetime(6)"); + + b.Property("Dts") + .HasColumnType("datetime(6)"); + + b.Property("Error") + .HasColumnType("longtext"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RetryCount") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("RequestQueue"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("ArtistName") + .HasColumnType("longtext"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("Cover") + .HasColumnType("longtext"); + + b.Property("Denied") + .HasColumnType("tinyint(1)"); + + b.Property("DeniedReason") + .HasColumnType("longtext"); + + b.Property("Disk") + .HasColumnType("longtext"); + + b.Property("ForeignAlbumId") + .HasColumnType("longtext"); + + b.Property("ForeignArtistId") + .HasColumnType("longtext"); + + b.Property("MarkedAsApproved") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied") + .HasColumnType("datetime(6)"); + + b.Property("Rating") + .HasColumnType("decimal(65,30)"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("RequestedByAlias") + .HasColumnType("longtext"); + + b.Property("RequestedDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestedUserId") + .HasColumnType("varchar(255)"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("AlbumRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("Denied") + .HasColumnType("tinyint(1)"); + + b.Property("DeniedReason") + .HasColumnType("longtext"); + + b.Property("IssueId") + .HasColumnType("int"); + + b.Property("MarkedAsApproved") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied") + .HasColumnType("datetime(6)"); + + b.Property("ParentRequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("RequestedByAlias") + .HasColumnType("longtext"); + + b.Property("RequestedDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestedUserId") + .HasColumnType("varchar(255)"); + + b.Property("SeriesType") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentRequestId"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("IssueCategory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Comment") + .HasColumnType("longtext"); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("IssuesId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("IssuesId"); + + b.HasIndex("UserId"); + + b.ToTable("IssueComments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CreatedDate") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("IssueCategoryId") + .HasColumnType("int"); + + b.Property("IssueId") + .HasColumnType("int"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("ResovledDate") + .HasColumnType("datetime(6)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Subject") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("UserReportedId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("IssueCategoryId"); + + b.HasIndex("IssueId"); + + b.HasIndex("UserReportedId"); + + b.ToTable("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("Approved4K") + .HasColumnType("tinyint(1)"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("Available4K") + .HasColumnType("tinyint(1)"); + + b.Property("Background") + .HasColumnType("longtext"); + + b.Property("Denied") + .HasColumnType("tinyint(1)"); + + b.Property("Denied4K") + .HasColumnType("tinyint(1)"); + + b.Property("DeniedReason") + .HasColumnType("longtext"); + + b.Property("DeniedReason4K") + .HasColumnType("longtext"); + + b.Property("DigitalReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("Has4KRequest") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("IssueId") + .HasColumnType("int"); + + b.Property("LangCode") + .HasColumnType("longtext"); + + b.Property("MarkedAsApproved") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsApproved4K") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable4K") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied4K") + .HasColumnType("datetime(6)"); + + b.Property("Overview") + .HasColumnType("longtext"); + + b.Property("PosterPath") + .HasColumnType("longtext"); + + b.Property("QualityOverride") + .HasColumnType("int"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("RequestedByAlias") + .HasColumnType("longtext"); + + b.Property("RequestedDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestedDate4k") + .HasColumnType("datetime(6)"); + + b.Property("RequestedUserId") + .HasColumnType("varchar(255)"); + + b.Property("RootPathOverride") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("MovieRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeCount") + .HasColumnType("int"); + + b.Property("RequestDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Background") + .HasColumnType("longtext"); + + b.Property("ExternalProviderId") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("LanguageProfile") + .HasColumnType("int"); + + b.Property("Overview") + .HasColumnType("longtext"); + + b.Property("PosterPath") + .HasColumnType("longtext"); + + b.Property("QualityOverride") + .HasColumnType("int"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("RootFolder") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TotalSeasons") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("TvRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Token") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Agent") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("RadarrQualityProfile") + .HasColumnType("int"); + + b.Property("RadarrRootPath") + .HasColumnType("int"); + + b.Property("SonarrQualityProfile") + .HasColumnType("int"); + + b.Property("SonarrQualityProfileAnime") + .HasColumnType("int"); + + b.Property("SonarrRootPath") + .HasColumnType("int"); + + b.Property("SonarrRootPathAnime") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserQualityProfiles"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("tinyint(1)"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("VoteType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Votes"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AirDate") + .HasColumnType("datetime(6)"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("Requested") + .HasColumnType("tinyint(1)"); + + b.Property("SeasonId") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("EpisodeRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ChildRequestId") + .HasColumnType("int"); + + b.Property("Overview") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChildRequestId"); + + b.ToTable("SeasonRequests"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("NotificationUserIds") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest") + .WithMany("ChildRequests") + .HasForeignKey("ParentRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("ParentRequest"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues") + .WithMany("Comments") + .HasForeignKey("IssuesId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Issues"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory") + .WithMany() + .HasForeignKey("IssueCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.Requests.MovieRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported") + .WithMany() + .HasForeignKey("UserReportedId"); + + b.Navigation("IssueCategory"); + + b.Navigation("UserReported"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("UserNotificationPreferences") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest") + .WithMany("SeasonRequests") + .HasForeignKey("ChildRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChildRequest"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Navigation("NotificationUserIds"); + + b.Navigation("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Navigation("Issues"); + + b.Navigation("SeasonRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Navigation("Comments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Navigation("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Navigation("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Navigation("Episodes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiMySql/20220210215019_4kMovieProperties.cs b/src/Ombi.Store/Migrations/OmbiMySql/20220210215019_4kMovieProperties.cs new file mode 100644 index 000000000..3b599c0e0 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiMySql/20220210215019_4kMovieProperties.cs @@ -0,0 +1,102 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiMySql +{ + public partial class _4kMovieProperties : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Approved4K", + table: "MovieRequests", + type: "tinyint(1)", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Available4K", + table: "MovieRequests", + type: "tinyint(1)", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Denied4K", + table: "MovieRequests", + type: "tinyint(1)", + nullable: true); + + migrationBuilder.AddColumn( + name: "DeniedReason4K", + table: "MovieRequests", + type: "longtext", + nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddColumn( + name: "MarkedAsApproved4K", + table: "MovieRequests", + type: "datetime(6)", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "MarkedAsAvailable4K", + table: "MovieRequests", + type: "datetime(6)", + nullable: true); + + migrationBuilder.AddColumn( + name: "MarkedAsDenied4K", + table: "MovieRequests", + type: "datetime(6)", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "RequestedDate4k", + table: "MovieRequests", + type: "datetime(6)", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Approved4K", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "Available4K", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "Denied4K", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "DeniedReason4K", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "MarkedAsApproved4K", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "MarkedAsAvailable4K", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "MarkedAsDenied4K", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "RequestedDate4k", + table: "MovieRequests"); + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiMySql/20220407114619_RequestSource.Designer.cs b/src/Ombi.Store/Migrations/OmbiMySql/20220407114619_RequestSource.Designer.cs new file mode 100644 index 000000000..c4d1fd2f1 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiMySql/20220407114619_RequestSource.Designer.cs @@ -0,0 +1,1285 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.MySql; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiMySql +{ + [DbContext(typeof(OmbiMySqlContext))] + [Migration("20220407114619_RequestSource")] + partial class RequestSource + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ClaimType") + .HasColumnType("longtext"); + + b.Property("ClaimValue") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("ProviderKey") + .HasColumnType("varchar(255)"); + + b.Property("ProviderDisplayName") + .HasColumnType("longtext"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("varchar(255)"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("RoleId") + .HasColumnType("varchar(255)"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("LoginProvider") + .HasColumnType("varchar(255)"); + + b.Property("Name") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Audit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AuditArea") + .HasColumnType("int"); + + b.Property("AuditType") + .HasColumnType("int"); + + b.Property("DateTime") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("User") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("Audit"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("Token") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("MobileDevices"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Agent") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("Message") + .HasColumnType("longtext"); + + b.Property("NotificationType") + .HasColumnType("int"); + + b.Property("Subject") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("NotificationTemplates"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("PlayerId") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Property("Id") + .HasColumnType("varchar(255)"); + + b.Property("AccessFailedCount") + .HasColumnType("int"); + + b.Property("Alias") + .HasColumnType("longtext"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("longtext"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("EmailConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("EpisodeRequestLimit") + .HasColumnType("int"); + + b.Property("EpisodeRequestLimitType") + .HasColumnType("int"); + + b.Property("Language") + .HasColumnType("longtext"); + + b.Property("LastLoggedIn") + .HasColumnType("datetime(6)"); + + b.Property("LockoutEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("LockoutEnd") + .HasColumnType("datetime(6)"); + + b.Property("MediaServerToken") + .HasColumnType("longtext"); + + b.Property("MovieRequestLimit") + .HasColumnType("int"); + + b.Property("MovieRequestLimitType") + .HasColumnType("int"); + + b.Property("MusicRequestLimit") + .HasColumnType("int"); + + b.Property("MusicRequestLimitType") + .HasColumnType("int"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("PasswordHash") + .HasColumnType("longtext"); + + b.Property("PhoneNumber") + .HasColumnType("longtext"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("tinyint(1)"); + + b.Property("ProviderUserId") + .HasColumnType("longtext"); + + b.Property("SecurityStamp") + .HasColumnType("longtext"); + + b.Property("StreamingCountry") + .IsRequired() + .HasColumnType("longtext"); + + b.Property("TwoFactorEnabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserAccessToken") + .HasColumnType("longtext"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("varchar(256)"); + + b.Property("UserType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AddedAt") + .HasColumnType("datetime(6)"); + + b.Property("AlbumId") + .HasColumnType("longtext"); + + b.Property("ContentId") + .HasColumnType("int"); + + b.Property("ContentType") + .HasColumnType("int"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("RecentlyAddedLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestQueue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Completed") + .HasColumnType("datetime(6)"); + + b.Property("Dts") + .HasColumnType("datetime(6)"); + + b.Property("Error") + .HasColumnType("longtext"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RetryCount") + .HasColumnType("int"); + + b.Property("Type") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("RequestQueue"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("ArtistName") + .HasColumnType("longtext"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("Cover") + .HasColumnType("longtext"); + + b.Property("Denied") + .HasColumnType("tinyint(1)"); + + b.Property("DeniedReason") + .HasColumnType("longtext"); + + b.Property("Disk") + .HasColumnType("longtext"); + + b.Property("ForeignAlbumId") + .HasColumnType("longtext"); + + b.Property("ForeignArtistId") + .HasColumnType("longtext"); + + b.Property("MarkedAsApproved") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied") + .HasColumnType("datetime(6)"); + + b.Property("Rating") + .HasColumnType("decimal(65,30)"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("RequestedByAlias") + .HasColumnType("longtext"); + + b.Property("RequestedDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestedUserId") + .HasColumnType("varchar(255)"); + + b.Property("Source") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("AlbumRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("Denied") + .HasColumnType("tinyint(1)"); + + b.Property("DeniedReason") + .HasColumnType("longtext"); + + b.Property("IssueId") + .HasColumnType("int"); + + b.Property("MarkedAsApproved") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied") + .HasColumnType("datetime(6)"); + + b.Property("ParentRequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("RequestedByAlias") + .HasColumnType("longtext"); + + b.Property("RequestedDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestedUserId") + .HasColumnType("varchar(255)"); + + b.Property("SeriesType") + .HasColumnType("int"); + + b.Property("Source") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("ParentRequestId"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.ToTable("IssueCategory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Comment") + .HasColumnType("longtext"); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("IssuesId") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("IssuesId"); + + b.HasIndex("UserId"); + + b.ToTable("IssueComments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("CreatedDate") + .HasColumnType("datetime(6)"); + + b.Property("Description") + .HasColumnType("longtext"); + + b.Property("IssueCategoryId") + .HasColumnType("int"); + + b.Property("IssueId") + .HasColumnType("int"); + + b.Property("ProviderId") + .HasColumnType("longtext"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("ResovledDate") + .HasColumnType("datetime(6)"); + + b.Property("Status") + .HasColumnType("int"); + + b.Property("Subject") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("UserReportedId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("IssueCategoryId"); + + b.HasIndex("IssueId"); + + b.HasIndex("UserReportedId"); + + b.ToTable("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("Approved4K") + .HasColumnType("tinyint(1)"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("Available4K") + .HasColumnType("tinyint(1)"); + + b.Property("Background") + .HasColumnType("longtext"); + + b.Property("Denied") + .HasColumnType("tinyint(1)"); + + b.Property("Denied4K") + .HasColumnType("tinyint(1)"); + + b.Property("DeniedReason") + .HasColumnType("longtext"); + + b.Property("DeniedReason4K") + .HasColumnType("longtext"); + + b.Property("DigitalReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("Has4KRequest") + .HasColumnType("tinyint(1)"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("IssueId") + .HasColumnType("int"); + + b.Property("LangCode") + .HasColumnType("longtext"); + + b.Property("MarkedAsApproved") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsApproved4K") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsAvailable4K") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied") + .HasColumnType("datetime(6)"); + + b.Property("MarkedAsDenied4K") + .HasColumnType("datetime(6)"); + + b.Property("Overview") + .HasColumnType("longtext"); + + b.Property("PosterPath") + .HasColumnType("longtext"); + + b.Property("QualityOverride") + .HasColumnType("int"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("RequestedByAlias") + .HasColumnType("longtext"); + + b.Property("RequestedDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestedDate4k") + .HasColumnType("datetime(6)"); + + b.Property("RequestedUserId") + .HasColumnType("varchar(255)"); + + b.Property("RootPathOverride") + .HasColumnType("int"); + + b.Property("Source") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("longtext"); + + b.Property("TheMovieDbId") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("MovieRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("EpisodeCount") + .HasColumnType("int"); + + b.Property("RequestDate") + .HasColumnType("datetime(6)"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Background") + .HasColumnType("longtext"); + + b.Property("ExternalProviderId") + .HasColumnType("int"); + + b.Property("ImdbId") + .HasColumnType("longtext"); + + b.Property("LanguageProfile") + .HasColumnType("int"); + + b.Property("Overview") + .HasColumnType("longtext"); + + b.Property("PosterPath") + .HasColumnType("longtext"); + + b.Property("QualityOverride") + .HasColumnType("int"); + + b.Property("ReleaseDate") + .HasColumnType("datetime(6)"); + + b.Property("RootFolder") + .HasColumnType("int"); + + b.Property("Status") + .HasColumnType("longtext"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("TotalSeasons") + .HasColumnType("int"); + + b.Property("TvDbId") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.ToTable("TvRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Token") + .HasColumnType("longtext"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Agent") + .HasColumnType("int"); + + b.Property("Enabled") + .HasColumnType("tinyint(1)"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("Value") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("RadarrQualityProfile") + .HasColumnType("int"); + + b.Property("RadarrRootPath") + .HasColumnType("int"); + + b.Property("SonarrQualityProfile") + .HasColumnType("int"); + + b.Property("SonarrQualityProfileAnime") + .HasColumnType("int"); + + b.Property("SonarrRootPath") + .HasColumnType("int"); + + b.Property("SonarrRootPathAnime") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserQualityProfiles"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("Date") + .HasColumnType("datetime(6)"); + + b.Property("Deleted") + .HasColumnType("tinyint(1)"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.Property("VoteType") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Votes"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("AirDate") + .HasColumnType("datetime(6)"); + + b.Property("Approved") + .HasColumnType("tinyint(1)"); + + b.Property("Available") + .HasColumnType("tinyint(1)"); + + b.Property("EpisodeNumber") + .HasColumnType("int"); + + b.Property("Requested") + .HasColumnType("tinyint(1)"); + + b.Property("SeasonId") + .HasColumnType("int"); + + b.Property("Title") + .HasColumnType("longtext"); + + b.Property("Url") + .HasColumnType("longtext"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("EpisodeRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("ChildRequestId") + .HasColumnType("int"); + + b.Property("Overview") + .HasColumnType("longtext"); + + b.Property("SeasonNumber") + .HasColumnType("int"); + + b.HasKey("Id"); + + b.HasIndex("ChildRequestId"); + + b.ToTable("SeasonRequests"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("NotificationUserIds") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest") + .WithMany("ChildRequests") + .HasForeignKey("ParentRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("ParentRequest"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues") + .WithMany("Comments") + .HasForeignKey("IssuesId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Issues"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory") + .WithMany() + .HasForeignKey("IssueCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.Requests.MovieRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported") + .WithMany() + .HasForeignKey("UserReportedId"); + + b.Navigation("IssueCategory"); + + b.Navigation("UserReported"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("UserNotificationPreferences") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest") + .WithMany("SeasonRequests") + .HasForeignKey("ChildRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChildRequest"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Navigation("NotificationUserIds"); + + b.Navigation("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Navigation("Issues"); + + b.Navigation("SeasonRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Navigation("Comments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Navigation("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Navigation("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Navigation("Episodes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiMySql/20220407114619_RequestSource.cs b/src/Ombi.Store/Migrations/OmbiMySql/20220407114619_RequestSource.cs new file mode 100644 index 000000000..1020b4d63 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiMySql/20220407114619_RequestSource.cs @@ -0,0 +1,59 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiMySql +{ + public partial class RequestSource : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Source", + table: "MovieRequests", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "Source", + table: "ChildRequests", + type: "int", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "MediaServerToken", + table: "AspNetUsers", + type: "longtext", + nullable: true) + .Annotation("MySql:CharSet", "utf8mb4"); + + migrationBuilder.AddColumn( + name: "Source", + table: "AlbumRequests", + type: "int", + nullable: false, + defaultValue: 0); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Source", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "Source", + table: "ChildRequests"); + + migrationBuilder.DropColumn( + name: "MediaServerToken", + table: "AspNetUsers"); + + migrationBuilder.DropColumn( + name: "Source", + table: "AlbumRequests"); + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiMySql/OmbiMySqlContextModelSnapshot.cs b/src/Ombi.Store/Migrations/OmbiMySql/OmbiMySqlContextModelSnapshot.cs index 8fdebc4c2..e66e29521 100644 --- a/src/Ombi.Store/Migrations/OmbiMySql/OmbiMySqlContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/OmbiMySql/OmbiMySqlContextModelSnapshot.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Ombi.Store.Context.MySql; +#nullable disable + namespace Ombi.Store.Migrations.OmbiMySql { [DbContext(typeof(OmbiMySqlContext))] @@ -14,8 +16,8 @@ namespace Ombi.Store.Migrations.OmbiMySql { #pragma warning disable 612, 618 modelBuilder - .HasAnnotation("Relational:MaxIdentifierLength", 64) - .HasAnnotation("ProductVersion", "5.0.1"); + .HasAnnotation("ProductVersion", "6.0.0") + .HasAnnotation("Relational:MaxIdentifierLength", 64); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { @@ -40,7 +42,7 @@ namespace Ombi.Store.Migrations.OmbiMySql .IsUnique() .HasDatabaseName("RoleNameIndex"); - b.ToTable("AspNetRoles"); + b.ToTable("AspNetRoles", (string)null); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => @@ -63,7 +65,7 @@ namespace Ombi.Store.Migrations.OmbiMySql b.HasIndex("RoleId"); - b.ToTable("AspNetRoleClaims"); + b.ToTable("AspNetRoleClaims", (string)null); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => @@ -86,7 +88,7 @@ namespace Ombi.Store.Migrations.OmbiMySql b.HasIndex("UserId"); - b.ToTable("AspNetUserClaims"); + b.ToTable("AspNetUserClaims", (string)null); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => @@ -108,7 +110,7 @@ namespace Ombi.Store.Migrations.OmbiMySql b.HasIndex("UserId"); - b.ToTable("AspNetUserLogins"); + b.ToTable("AspNetUserLogins", (string)null); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => @@ -123,7 +125,7 @@ namespace Ombi.Store.Migrations.OmbiMySql b.HasIndex("RoleId"); - b.ToTable("AspNetUserRoles"); + b.ToTable("AspNetUserRoles", (string)null); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => @@ -142,7 +144,7 @@ namespace Ombi.Store.Migrations.OmbiMySql b.HasKey("UserId", "LoginProvider", "Name"); - b.ToTable("AspNetUserTokens"); + b.ToTable("AspNetUserTokens", (string)null); }); modelBuilder.Entity("Ombi.Store.Entities.Audit", b => @@ -281,6 +283,9 @@ namespace Ombi.Store.Migrations.OmbiMySql b.Property("LockoutEnd") .HasColumnType("datetime(6)"); + b.Property("MediaServerToken") + .HasColumnType("longtext"); + b.Property("MovieRequestLimit") .HasColumnType("int"); @@ -342,7 +347,7 @@ namespace Ombi.Store.Migrations.OmbiMySql .IsUnique() .HasDatabaseName("UserNameIndex"); - b.ToTable("AspNetUsers"); + b.ToTable("AspNetUsers", (string)null); }); modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => @@ -406,28 +411,6 @@ namespace Ombi.Store.Migrations.OmbiMySql b.ToTable("RequestQueue"); }); - modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("int"); - - b.Property("RequestId") - .HasColumnType("int"); - - b.Property("RequestType") - .HasColumnType("int"); - - b.Property("UserId") - .HasColumnType("varchar(255)"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("RequestSubscription"); - }); - modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => { b.Property("Id") @@ -488,6 +471,9 @@ namespace Ombi.Store.Migrations.OmbiMySql b.Property("RequestedUserId") .HasColumnType("varchar(255)"); + b.Property("Source") + .HasColumnType("int"); + b.Property("Title") .HasColumnType("longtext"); @@ -546,6 +532,9 @@ namespace Ombi.Store.Migrations.OmbiMySql b.Property("SeriesType") .HasColumnType("int"); + b.Property("Source") + .HasColumnType("int"); + b.Property("Title") .HasColumnType("longtext"); @@ -661,21 +650,36 @@ namespace Ombi.Store.Migrations.OmbiMySql b.Property("Approved") .HasColumnType("tinyint(1)"); + b.Property("Approved4K") + .HasColumnType("tinyint(1)"); + b.Property("Available") .HasColumnType("tinyint(1)"); + b.Property("Available4K") + .HasColumnType("tinyint(1)"); + b.Property("Background") .HasColumnType("longtext"); b.Property("Denied") .HasColumnType("tinyint(1)"); + b.Property("Denied4K") + .HasColumnType("tinyint(1)"); + b.Property("DeniedReason") .HasColumnType("longtext"); + b.Property("DeniedReason4K") + .HasColumnType("longtext"); + b.Property("DigitalReleaseDate") .HasColumnType("datetime(6)"); + b.Property("Has4KRequest") + .HasColumnType("tinyint(1)"); + b.Property("ImdbId") .HasColumnType("longtext"); @@ -688,12 +692,21 @@ namespace Ombi.Store.Migrations.OmbiMySql b.Property("MarkedAsApproved") .HasColumnType("datetime(6)"); + b.Property("MarkedAsApproved4K") + .HasColumnType("datetime(6)"); + b.Property("MarkedAsAvailable") .HasColumnType("datetime(6)"); + b.Property("MarkedAsAvailable4K") + .HasColumnType("datetime(6)"); + b.Property("MarkedAsDenied") .HasColumnType("datetime(6)"); + b.Property("MarkedAsDenied4K") + .HasColumnType("datetime(6)"); + b.Property("Overview") .HasColumnType("longtext"); @@ -715,12 +728,18 @@ namespace Ombi.Store.Migrations.OmbiMySql b.Property("RequestedDate") .HasColumnType("datetime(6)"); + b.Property("RequestedDate4k") + .HasColumnType("datetime(6)"); + b.Property("RequestedUserId") .HasColumnType("varchar(255)"); b.Property("RootPathOverride") .HasColumnType("int"); + b.Property("Source") + .HasColumnType("int"); + b.Property("Status") .HasColumnType("longtext"); @@ -815,6 +834,28 @@ namespace Ombi.Store.Migrations.OmbiMySql b.ToTable("TvRequests"); }); + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("int"); + + b.Property("RequestId") + .HasColumnType("int"); + + b.Property("RequestType") + .HasColumnType("int"); + + b.Property("UserId") + .HasColumnType("varchar(255)"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => { b.Property("Id") @@ -1052,15 +1093,6 @@ namespace Ombi.Store.Migrations.OmbiMySql b.Navigation("User"); }); - modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => - { - b.HasOne("Ombi.Store.Entities.OmbiUser", "User") - .WithMany() - .HasForeignKey("UserId"); - - b.Navigation("User"); - }); - modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => { b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") @@ -1145,6 +1177,15 @@ namespace Ombi.Store.Migrations.OmbiMySql b.Navigation("User"); }); + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => { b.HasOne("Ombi.Store.Entities.OmbiUser", "User") diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/20220210194758_Radarr4kRole.Designer.cs b/src/Ombi.Store/Migrations/OmbiSqlite/20220210194758_Radarr4kRole.Designer.cs new file mode 100644 index 000000000..e2c442a23 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiSqlite/20220210194758_Radarr4kRole.Designer.cs @@ -0,0 +1,1244 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.Sqlite; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiSqlite +{ + [DbContext(typeof(OmbiSqliteContext))] + [Migration("20220210194758_Radarr4kRole")] + partial class Radarr4kRole + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Audit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AuditArea") + .HasColumnType("INTEGER"); + + b.Property("AuditType") + .HasColumnType("INTEGER"); + + b.Property("DateTime") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("User") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Audit"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Token") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("MobileDevices"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Agent") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("Message") + .HasColumnType("TEXT"); + + b.Property("NotificationType") + .HasColumnType("INTEGER"); + + b.Property("Subject") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("NotificationTemplates"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("PlayerId") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("Alias") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("EpisodeRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("EpisodeRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("Language") + .HasColumnType("TEXT"); + + b.Property("LastLoggedIn") + .HasColumnType("TEXT"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("MovieRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("MovieRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("MusicRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("MusicRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("ProviderUserId") + .HasColumnType("TEXT"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("StreamingCountry") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserAccessToken") + .HasColumnType("TEXT"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("AlbumId") + .HasColumnType("TEXT"); + + b.Property("ContentId") + .HasColumnType("INTEGER"); + + b.Property("ContentType") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RecentlyAddedLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestQueue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Completed") + .HasColumnType("TEXT"); + + b.Property("Dts") + .HasColumnType("TEXT"); + + b.Property("Error") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RetryCount") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RequestQueue"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("ArtistName") + .HasColumnType("TEXT"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Cover") + .HasColumnType("TEXT"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("Disk") + .HasColumnType("TEXT"); + + b.Property("ForeignAlbumId") + .HasColumnType("TEXT"); + + b.Property("ForeignArtistId") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("Rating") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("AlbumRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("ParentRequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("SeriesType") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentRequestId"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("IssueCategory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Comment") + .HasColumnType("TEXT"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("IssuesId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IssuesId"); + + b.HasIndex("UserId"); + + b.ToTable("IssueComments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDate") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("IssueCategoryId") + .HasColumnType("INTEGER"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("ResovledDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Subject") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("UserReportedId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IssueCategoryId"); + + b.HasIndex("IssueId"); + + b.HasIndex("UserReportedId"); + + b.ToTable("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Background") + .HasColumnType("TEXT"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("DigitalReleaseDate") + .HasColumnType("TEXT"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("LangCode") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("PosterPath") + .HasColumnType("TEXT"); + + b.Property("QualityOverride") + .HasColumnType("INTEGER"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("RootPathOverride") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("MovieRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeCount") + .HasColumnType("INTEGER"); + + b.Property("RequestDate") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Background") + .HasColumnType("TEXT"); + + b.Property("ExternalProviderId") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("LanguageProfile") + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("PosterPath") + .HasColumnType("TEXT"); + + b.Property("QualityOverride") + .HasColumnType("INTEGER"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RootFolder") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TotalSeasons") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("TvRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Token") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Agent") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RadarrQualityProfile") + .HasColumnType("INTEGER"); + + b.Property("RadarrRootPath") + .HasColumnType("INTEGER"); + + b.Property("SonarrQualityProfile") + .HasColumnType("INTEGER"); + + b.Property("SonarrQualityProfileAnime") + .HasColumnType("INTEGER"); + + b.Property("SonarrRootPath") + .HasColumnType("INTEGER"); + + b.Property("SonarrRootPathAnime") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserQualityProfiles"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Deleted") + .HasColumnType("INTEGER"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VoteType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Votes"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AirDate") + .HasColumnType("TEXT"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("Requested") + .HasColumnType("INTEGER"); + + b.Property("SeasonId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("EpisodeRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChildRequestId") + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChildRequestId"); + + b.ToTable("SeasonRequests"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("NotificationUserIds") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest") + .WithMany("ChildRequests") + .HasForeignKey("ParentRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("ParentRequest"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues") + .WithMany("Comments") + .HasForeignKey("IssuesId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Issues"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory") + .WithMany() + .HasForeignKey("IssueCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.Requests.MovieRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported") + .WithMany() + .HasForeignKey("UserReportedId"); + + b.Navigation("IssueCategory"); + + b.Navigation("UserReported"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("UserNotificationPreferences") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest") + .WithMany("SeasonRequests") + .HasForeignKey("ChildRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChildRequest"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Navigation("NotificationUserIds"); + + b.Navigation("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Navigation("Issues"); + + b.Navigation("SeasonRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Navigation("Comments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Navigation("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Navigation("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Navigation("Episodes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/20220210194758_Radarr4kRole.cs b/src/Ombi.Store/Migrations/OmbiSqlite/20220210194758_Radarr4kRole.cs new file mode 100644 index 000000000..a97de9011 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiSqlite/20220210194758_Radarr4kRole.cs @@ -0,0 +1,20 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using Ombi.Helpers; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiSqlite +{ + public partial class Radarr4kRole : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.InsertRole(OmbiRoles.Request4KMovie); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/20220210200338_MovieRequest4K.Designer.cs b/src/Ombi.Store/Migrations/OmbiSqlite/20220210200338_MovieRequest4K.Designer.cs new file mode 100644 index 000000000..a2dee4283 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiSqlite/20220210200338_MovieRequest4K.Designer.cs @@ -0,0 +1,1247 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.Sqlite; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiSqlite +{ + [DbContext(typeof(OmbiSqliteContext))] + [Migration("20220210200338_MovieRequest4K")] + partial class MovieRequest4K + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Audit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AuditArea") + .HasColumnType("INTEGER"); + + b.Property("AuditType") + .HasColumnType("INTEGER"); + + b.Property("DateTime") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("User") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Audit"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Token") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("MobileDevices"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Agent") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("Message") + .HasColumnType("TEXT"); + + b.Property("NotificationType") + .HasColumnType("INTEGER"); + + b.Property("Subject") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("NotificationTemplates"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("PlayerId") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("Alias") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("EpisodeRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("EpisodeRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("Language") + .HasColumnType("TEXT"); + + b.Property("LastLoggedIn") + .HasColumnType("TEXT"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("MovieRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("MovieRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("MusicRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("MusicRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("ProviderUserId") + .HasColumnType("TEXT"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("StreamingCountry") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserAccessToken") + .HasColumnType("TEXT"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("AlbumId") + .HasColumnType("TEXT"); + + b.Property("ContentId") + .HasColumnType("INTEGER"); + + b.Property("ContentType") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RecentlyAddedLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestQueue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Completed") + .HasColumnType("TEXT"); + + b.Property("Dts") + .HasColumnType("TEXT"); + + b.Property("Error") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RetryCount") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RequestQueue"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("ArtistName") + .HasColumnType("TEXT"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Cover") + .HasColumnType("TEXT"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("Disk") + .HasColumnType("TEXT"); + + b.Property("ForeignAlbumId") + .HasColumnType("TEXT"); + + b.Property("ForeignArtistId") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("Rating") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("AlbumRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("ParentRequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("SeriesType") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentRequestId"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("IssueCategory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Comment") + .HasColumnType("TEXT"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("IssuesId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IssuesId"); + + b.HasIndex("UserId"); + + b.ToTable("IssueComments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDate") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("IssueCategoryId") + .HasColumnType("INTEGER"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("ResovledDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Subject") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("UserReportedId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IssueCategoryId"); + + b.HasIndex("IssueId"); + + b.HasIndex("UserReportedId"); + + b.ToTable("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Background") + .HasColumnType("TEXT"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("DigitalReleaseDate") + .HasColumnType("TEXT"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("Is4KRequest") + .HasColumnType("INTEGER"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("LangCode") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("PosterPath") + .HasColumnType("TEXT"); + + b.Property("QualityOverride") + .HasColumnType("INTEGER"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("RootPathOverride") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("MovieRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeCount") + .HasColumnType("INTEGER"); + + b.Property("RequestDate") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Background") + .HasColumnType("TEXT"); + + b.Property("ExternalProviderId") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("LanguageProfile") + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("PosterPath") + .HasColumnType("TEXT"); + + b.Property("QualityOverride") + .HasColumnType("INTEGER"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RootFolder") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TotalSeasons") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("TvRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Token") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Agent") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RadarrQualityProfile") + .HasColumnType("INTEGER"); + + b.Property("RadarrRootPath") + .HasColumnType("INTEGER"); + + b.Property("SonarrQualityProfile") + .HasColumnType("INTEGER"); + + b.Property("SonarrQualityProfileAnime") + .HasColumnType("INTEGER"); + + b.Property("SonarrRootPath") + .HasColumnType("INTEGER"); + + b.Property("SonarrRootPathAnime") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserQualityProfiles"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Deleted") + .HasColumnType("INTEGER"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VoteType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Votes"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AirDate") + .HasColumnType("TEXT"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("Requested") + .HasColumnType("INTEGER"); + + b.Property("SeasonId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("EpisodeRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChildRequestId") + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChildRequestId"); + + b.ToTable("SeasonRequests"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("NotificationUserIds") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest") + .WithMany("ChildRequests") + .HasForeignKey("ParentRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("ParentRequest"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues") + .WithMany("Comments") + .HasForeignKey("IssuesId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Issues"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory") + .WithMany() + .HasForeignKey("IssueCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.Requests.MovieRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported") + .WithMany() + .HasForeignKey("UserReportedId"); + + b.Navigation("IssueCategory"); + + b.Navigation("UserReported"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("UserNotificationPreferences") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest") + .WithMany("SeasonRequests") + .HasForeignKey("ChildRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChildRequest"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Navigation("NotificationUserIds"); + + b.Navigation("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Navigation("Issues"); + + b.Navigation("SeasonRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Navigation("Comments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Navigation("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Navigation("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Navigation("Episodes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/20220210200338_MovieRequest4K.cs b/src/Ombi.Store/Migrations/OmbiSqlite/20220210200338_MovieRequest4K.cs new file mode 100644 index 000000000..8d70a0358 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiSqlite/20220210200338_MovieRequest4K.cs @@ -0,0 +1,26 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiSqlite +{ + public partial class MovieRequest4K : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Has4KRequest", + table: "MovieRequests", + type: "INTEGER", + nullable: false, + defaultValue: false); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Has4KRequest", + table: "MovieRequests"); + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/20220210214920_4kMovieProperties.Designer.cs b/src/Ombi.Store/Migrations/OmbiSqlite/20220210214920_4kMovieProperties.Designer.cs new file mode 100644 index 000000000..e315e78ea --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiSqlite/20220210214920_4kMovieProperties.Designer.cs @@ -0,0 +1,1271 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.Sqlite; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiSqlite +{ + [DbContext(typeof(OmbiSqliteContext))] + [Migration("20220210214920_4kMovieProperties")] + partial class _4kMovieProperties + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Audit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AuditArea") + .HasColumnType("INTEGER"); + + b.Property("AuditType") + .HasColumnType("INTEGER"); + + b.Property("DateTime") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("User") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Audit"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Token") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("MobileDevices"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Agent") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("Message") + .HasColumnType("TEXT"); + + b.Property("NotificationType") + .HasColumnType("INTEGER"); + + b.Property("Subject") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("NotificationTemplates"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("PlayerId") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("Alias") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("EpisodeRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("EpisodeRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("Language") + .HasColumnType("TEXT"); + + b.Property("LastLoggedIn") + .HasColumnType("TEXT"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("MovieRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("MovieRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("MusicRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("MusicRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("ProviderUserId") + .HasColumnType("TEXT"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("StreamingCountry") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserAccessToken") + .HasColumnType("TEXT"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("AlbumId") + .HasColumnType("TEXT"); + + b.Property("ContentId") + .HasColumnType("INTEGER"); + + b.Property("ContentType") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RecentlyAddedLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestQueue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Completed") + .HasColumnType("TEXT"); + + b.Property("Dts") + .HasColumnType("TEXT"); + + b.Property("Error") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RetryCount") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RequestQueue"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("ArtistName") + .HasColumnType("TEXT"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Cover") + .HasColumnType("TEXT"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("Disk") + .HasColumnType("TEXT"); + + b.Property("ForeignAlbumId") + .HasColumnType("TEXT"); + + b.Property("ForeignArtistId") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("Rating") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("AlbumRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("ParentRequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("SeriesType") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentRequestId"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("IssueCategory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Comment") + .HasColumnType("TEXT"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("IssuesId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IssuesId"); + + b.HasIndex("UserId"); + + b.ToTable("IssueComments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDate") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("IssueCategoryId") + .HasColumnType("INTEGER"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("ResovledDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Subject") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("UserReportedId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IssueCategoryId"); + + b.HasIndex("IssueId"); + + b.HasIndex("UserReportedId"); + + b.ToTable("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Approved4K") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Available4K") + .HasColumnType("INTEGER"); + + b.Property("Background") + .HasColumnType("TEXT"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("Denied4K") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("DeniedReason4K") + .HasColumnType("TEXT"); + + b.Property("DigitalReleaseDate") + .HasColumnType("TEXT"); + + b.Property("Has4KRequest") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("LangCode") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved4K") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable4K") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied4K") + .HasColumnType("TEXT"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("PosterPath") + .HasColumnType("TEXT"); + + b.Property("QualityOverride") + .HasColumnType("INTEGER"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedDate4k") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("RootPathOverride") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("MovieRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeCount") + .HasColumnType("INTEGER"); + + b.Property("RequestDate") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Background") + .HasColumnType("TEXT"); + + b.Property("ExternalProviderId") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("LanguageProfile") + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("PosterPath") + .HasColumnType("TEXT"); + + b.Property("QualityOverride") + .HasColumnType("INTEGER"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RootFolder") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TotalSeasons") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("TvRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Token") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Agent") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RadarrQualityProfile") + .HasColumnType("INTEGER"); + + b.Property("RadarrRootPath") + .HasColumnType("INTEGER"); + + b.Property("SonarrQualityProfile") + .HasColumnType("INTEGER"); + + b.Property("SonarrQualityProfileAnime") + .HasColumnType("INTEGER"); + + b.Property("SonarrRootPath") + .HasColumnType("INTEGER"); + + b.Property("SonarrRootPathAnime") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserQualityProfiles"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Deleted") + .HasColumnType("INTEGER"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VoteType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Votes"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AirDate") + .HasColumnType("TEXT"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("Requested") + .HasColumnType("INTEGER"); + + b.Property("SeasonId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("EpisodeRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChildRequestId") + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChildRequestId"); + + b.ToTable("SeasonRequests"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("NotificationUserIds") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest") + .WithMany("ChildRequests") + .HasForeignKey("ParentRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("ParentRequest"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues") + .WithMany("Comments") + .HasForeignKey("IssuesId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Issues"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory") + .WithMany() + .HasForeignKey("IssueCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.Requests.MovieRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported") + .WithMany() + .HasForeignKey("UserReportedId"); + + b.Navigation("IssueCategory"); + + b.Navigation("UserReported"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("UserNotificationPreferences") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest") + .WithMany("SeasonRequests") + .HasForeignKey("ChildRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChildRequest"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Navigation("NotificationUserIds"); + + b.Navigation("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Navigation("Issues"); + + b.Navigation("SeasonRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Navigation("Comments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Navigation("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Navigation("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Navigation("Episodes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/20220210214920_4kMovieProperties.cs b/src/Ombi.Store/Migrations/OmbiSqlite/20220210214920_4kMovieProperties.cs new file mode 100644 index 000000000..38f010eae --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiSqlite/20220210214920_4kMovieProperties.cs @@ -0,0 +1,101 @@ +using System; +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiSqlite +{ + public partial class _4kMovieProperties : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Approved4K", + table: "MovieRequests", + type: "INTEGER", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Available4K", + table: "MovieRequests", + type: "INTEGER", + nullable: false, + defaultValue: false); + + migrationBuilder.AddColumn( + name: "Denied4K", + table: "MovieRequests", + type: "INTEGER", + nullable: true); + + migrationBuilder.AddColumn( + name: "DeniedReason4K", + table: "MovieRequests", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "MarkedAsApproved4K", + table: "MovieRequests", + type: "TEXT", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "MarkedAsAvailable4K", + table: "MovieRequests", + type: "TEXT", + nullable: true); + + migrationBuilder.AddColumn( + name: "MarkedAsDenied4K", + table: "MovieRequests", + type: "TEXT", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + + migrationBuilder.AddColumn( + name: "RequestedDate4k", + table: "MovieRequests", + type: "TEXT", + nullable: false, + defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified)); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Approved4K", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "Available4K", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "Denied4K", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "DeniedReason4K", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "MarkedAsApproved4K", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "MarkedAsAvailable4K", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "MarkedAsDenied4K", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "RequestedDate4k", + table: "MovieRequests"); + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/20220406213123_PlexIds.Designer.cs b/src/Ombi.Store/Migrations/OmbiSqlite/20220406213123_PlexIds.Designer.cs new file mode 100644 index 000000000..2d3d8c76c --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiSqlite/20220406213123_PlexIds.Designer.cs @@ -0,0 +1,1274 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.Sqlite; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiSqlite +{ + [DbContext(typeof(OmbiSqliteContext))] + [Migration("20220406213123_PlexIds")] + partial class PlexIds + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Audit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AuditArea") + .HasColumnType("INTEGER"); + + b.Property("AuditType") + .HasColumnType("INTEGER"); + + b.Property("DateTime") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("User") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Audit"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Token") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("MobileDevices"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Agent") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("Message") + .HasColumnType("TEXT"); + + b.Property("NotificationType") + .HasColumnType("INTEGER"); + + b.Property("Subject") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("NotificationTemplates"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("PlayerId") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("Alias") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("EpisodeRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("EpisodeRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("Language") + .HasColumnType("TEXT"); + + b.Property("LastLoggedIn") + .HasColumnType("TEXT"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("MediaServerToken") + .HasColumnType("TEXT"); + + b.Property("MovieRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("MovieRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("MusicRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("MusicRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("ProviderUserId") + .HasColumnType("TEXT"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("StreamingCountry") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserAccessToken") + .HasColumnType("TEXT"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("AlbumId") + .HasColumnType("TEXT"); + + b.Property("ContentId") + .HasColumnType("INTEGER"); + + b.Property("ContentType") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RecentlyAddedLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestQueue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Completed") + .HasColumnType("TEXT"); + + b.Property("Dts") + .HasColumnType("TEXT"); + + b.Property("Error") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RetryCount") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RequestQueue"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("ArtistName") + .HasColumnType("TEXT"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Cover") + .HasColumnType("TEXT"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("Disk") + .HasColumnType("TEXT"); + + b.Property("ForeignAlbumId") + .HasColumnType("TEXT"); + + b.Property("ForeignArtistId") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("Rating") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("AlbumRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("ParentRequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("SeriesType") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentRequestId"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("IssueCategory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Comment") + .HasColumnType("TEXT"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("IssuesId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IssuesId"); + + b.HasIndex("UserId"); + + b.ToTable("IssueComments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDate") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("IssueCategoryId") + .HasColumnType("INTEGER"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("ResovledDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Subject") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("UserReportedId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IssueCategoryId"); + + b.HasIndex("IssueId"); + + b.HasIndex("UserReportedId"); + + b.ToTable("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Approved4K") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Available4K") + .HasColumnType("INTEGER"); + + b.Property("Background") + .HasColumnType("TEXT"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("Denied4K") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("DeniedReason4K") + .HasColumnType("TEXT"); + + b.Property("DigitalReleaseDate") + .HasColumnType("TEXT"); + + b.Property("Has4KRequest") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("LangCode") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved4K") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable4K") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied4K") + .HasColumnType("TEXT"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("PosterPath") + .HasColumnType("TEXT"); + + b.Property("QualityOverride") + .HasColumnType("INTEGER"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedDate4k") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("RootPathOverride") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("MovieRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeCount") + .HasColumnType("INTEGER"); + + b.Property("RequestDate") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Background") + .HasColumnType("TEXT"); + + b.Property("ExternalProviderId") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("LanguageProfile") + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("PosterPath") + .HasColumnType("TEXT"); + + b.Property("QualityOverride") + .HasColumnType("INTEGER"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RootFolder") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TotalSeasons") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("TvRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Token") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Agent") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RadarrQualityProfile") + .HasColumnType("INTEGER"); + + b.Property("RadarrRootPath") + .HasColumnType("INTEGER"); + + b.Property("SonarrQualityProfile") + .HasColumnType("INTEGER"); + + b.Property("SonarrQualityProfileAnime") + .HasColumnType("INTEGER"); + + b.Property("SonarrRootPath") + .HasColumnType("INTEGER"); + + b.Property("SonarrRootPathAnime") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserQualityProfiles"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Deleted") + .HasColumnType("INTEGER"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VoteType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Votes"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AirDate") + .HasColumnType("TEXT"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("Requested") + .HasColumnType("INTEGER"); + + b.Property("SeasonId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("EpisodeRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChildRequestId") + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChildRequestId"); + + b.ToTable("SeasonRequests"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("NotificationUserIds") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest") + .WithMany("ChildRequests") + .HasForeignKey("ParentRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("ParentRequest"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues") + .WithMany("Comments") + .HasForeignKey("IssuesId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Issues"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory") + .WithMany() + .HasForeignKey("IssueCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.Requests.MovieRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported") + .WithMany() + .HasForeignKey("UserReportedId"); + + b.Navigation("IssueCategory"); + + b.Navigation("UserReported"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("UserNotificationPreferences") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest") + .WithMany("SeasonRequests") + .HasForeignKey("ChildRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChildRequest"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Navigation("NotificationUserIds"); + + b.Navigation("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Navigation("Issues"); + + b.Navigation("SeasonRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Navigation("Comments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Navigation("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Navigation("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Navigation("Episodes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/20220406213123_PlexIds.cs b/src/Ombi.Store/Migrations/OmbiSqlite/20220406213123_PlexIds.cs new file mode 100644 index 000000000..b83d441a0 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiSqlite/20220406213123_PlexIds.cs @@ -0,0 +1,25 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiSqlite +{ + public partial class PlexIds : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "MediaServerToken", + table: "AspNetUsers", + type: "TEXT", + nullable: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "MediaServerToken", + table: "AspNetUsers"); + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/20220407072656_RequestSource.Designer.cs b/src/Ombi.Store/Migrations/OmbiSqlite/20220407072656_RequestSource.Designer.cs new file mode 100644 index 000000000..32f92ff6c --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiSqlite/20220407072656_RequestSource.Designer.cs @@ -0,0 +1,1283 @@ +// +using System; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Ombi.Store.Context.Sqlite; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiSqlite +{ + [DbContext(typeof(OmbiSqliteContext))] + [Migration("20220407072656_RequestSource")] + partial class RequestSource + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Name") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedName") + .IsUnique() + .HasDatabaseName("RoleNameIndex"); + + b.ToTable("AspNetRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetRoleClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ClaimType") + .HasColumnType("TEXT"); + + b.Property("ClaimValue") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserClaims", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("ProviderKey") + .HasColumnType("TEXT"); + + b.Property("ProviderDisplayName") + .HasColumnType("TEXT"); + + b.Property("UserId") + .IsRequired() + .HasColumnType("TEXT"); + + b.HasKey("LoginProvider", "ProviderKey"); + + b.HasIndex("UserId"); + + b.ToTable("AspNetUserLogins", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("RoleId") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "RoleId"); + + b.HasIndex("RoleId"); + + b.ToTable("AspNetUserRoles", (string)null); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("LoginProvider") + .HasColumnType("TEXT"); + + b.Property("Name") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("UserId", "LoginProvider", "Name"); + + b.ToTable("AspNetUserTokens", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Audit", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AuditArea") + .HasColumnType("INTEGER"); + + b.Property("AuditType") + .HasColumnType("INTEGER"); + + b.Property("DateTime") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("User") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("Audit"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("Token") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("MobileDevices"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationTemplates", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Agent") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("Message") + .HasColumnType("TEXT"); + + b.Property("NotificationType") + .HasColumnType("INTEGER"); + + b.Property("Subject") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("NotificationTemplates"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("PlayerId") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("NotificationUserId"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Property("Id") + .HasColumnType("TEXT"); + + b.Property("AccessFailedCount") + .HasColumnType("INTEGER"); + + b.Property("Alias") + .HasColumnType("TEXT"); + + b.Property("ConcurrencyStamp") + .IsConcurrencyToken() + .HasColumnType("TEXT"); + + b.Property("Email") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("EmailConfirmed") + .HasColumnType("INTEGER"); + + b.Property("EpisodeRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("EpisodeRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("Language") + .HasColumnType("TEXT"); + + b.Property("LastLoggedIn") + .HasColumnType("TEXT"); + + b.Property("LockoutEnabled") + .HasColumnType("INTEGER"); + + b.Property("LockoutEnd") + .HasColumnType("TEXT"); + + b.Property("MediaServerToken") + .HasColumnType("TEXT"); + + b.Property("MovieRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("MovieRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("MusicRequestLimit") + .HasColumnType("INTEGER"); + + b.Property("MusicRequestLimitType") + .HasColumnType("INTEGER"); + + b.Property("NormalizedEmail") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("NormalizedUserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("PasswordHash") + .HasColumnType("TEXT"); + + b.Property("PhoneNumber") + .HasColumnType("TEXT"); + + b.Property("PhoneNumberConfirmed") + .HasColumnType("INTEGER"); + + b.Property("ProviderUserId") + .HasColumnType("TEXT"); + + b.Property("SecurityStamp") + .HasColumnType("TEXT"); + + b.Property("StreamingCountry") + .IsRequired() + .HasColumnType("TEXT"); + + b.Property("TwoFactorEnabled") + .HasColumnType("INTEGER"); + + b.Property("UserAccessToken") + .HasColumnType("TEXT"); + + b.Property("UserName") + .HasMaxLength(256) + .HasColumnType("TEXT"); + + b.Property("UserType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("NormalizedEmail") + .HasDatabaseName("EmailIndex"); + + b.HasIndex("NormalizedUserName") + .IsUnique() + .HasDatabaseName("UserNameIndex"); + + b.ToTable("AspNetUsers", (string)null); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AddedAt") + .HasColumnType("TEXT"); + + b.Property("AlbumId") + .HasColumnType("TEXT"); + + b.Property("ContentId") + .HasColumnType("INTEGER"); + + b.Property("ContentType") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RecentlyAddedLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestQueue", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Completed") + .HasColumnType("TEXT"); + + b.Property("Dts") + .HasColumnType("TEXT"); + + b.Property("Error") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RetryCount") + .HasColumnType("INTEGER"); + + b.Property("Type") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("RequestQueue"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("ArtistName") + .HasColumnType("TEXT"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Cover") + .HasColumnType("TEXT"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("Disk") + .HasColumnType("TEXT"); + + b.Property("ForeignAlbumId") + .HasColumnType("TEXT"); + + b.Property("ForeignArtistId") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("Rating") + .HasColumnType("TEXT"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("Source") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("AlbumRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("ParentRequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("SeriesType") + .HasColumnType("INTEGER"); + + b.Property("Source") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("ParentRequestId"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueCategory", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.ToTable("IssueCategory"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Comment") + .HasColumnType("TEXT"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("IssuesId") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IssuesId"); + + b.HasIndex("UserId"); + + b.ToTable("IssueComments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("CreatedDate") + .HasColumnType("TEXT"); + + b.Property("Description") + .HasColumnType("TEXT"); + + b.Property("IssueCategoryId") + .HasColumnType("INTEGER"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("ProviderId") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("ResovledDate") + .HasColumnType("TEXT"); + + b.Property("Status") + .HasColumnType("INTEGER"); + + b.Property("Subject") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("UserReportedId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("IssueCategoryId"); + + b.HasIndex("IssueId"); + + b.HasIndex("UserReportedId"); + + b.ToTable("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Approved4K") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("Available4K") + .HasColumnType("INTEGER"); + + b.Property("Background") + .HasColumnType("TEXT"); + + b.Property("Denied") + .HasColumnType("INTEGER"); + + b.Property("Denied4K") + .HasColumnType("INTEGER"); + + b.Property("DeniedReason") + .HasColumnType("TEXT"); + + b.Property("DeniedReason4K") + .HasColumnType("TEXT"); + + b.Property("DigitalReleaseDate") + .HasColumnType("TEXT"); + + b.Property("Has4KRequest") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("IssueId") + .HasColumnType("INTEGER"); + + b.Property("LangCode") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved") + .HasColumnType("TEXT"); + + b.Property("MarkedAsApproved4K") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable") + .HasColumnType("TEXT"); + + b.Property("MarkedAsAvailable4K") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied") + .HasColumnType("TEXT"); + + b.Property("MarkedAsDenied4K") + .HasColumnType("TEXT"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("PosterPath") + .HasColumnType("TEXT"); + + b.Property("QualityOverride") + .HasColumnType("INTEGER"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("RequestedByAlias") + .HasColumnType("TEXT"); + + b.Property("RequestedDate") + .HasColumnType("TEXT"); + + b.Property("RequestedDate4k") + .HasColumnType("TEXT"); + + b.Property("RequestedUserId") + .HasColumnType("TEXT"); + + b.Property("RootPathOverride") + .HasColumnType("INTEGER"); + + b.Property("Source") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("TEXT"); + + b.Property("TheMovieDbId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("RequestedUserId"); + + b.ToTable("MovieRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("EpisodeCount") + .HasColumnType("INTEGER"); + + b.Property("RequestDate") + .HasColumnType("TEXT"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestLog"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Background") + .HasColumnType("TEXT"); + + b.Property("ExternalProviderId") + .HasColumnType("INTEGER"); + + b.Property("ImdbId") + .HasColumnType("TEXT"); + + b.Property("LanguageProfile") + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("PosterPath") + .HasColumnType("TEXT"); + + b.Property("QualityOverride") + .HasColumnType("INTEGER"); + + b.Property("ReleaseDate") + .HasColumnType("TEXT"); + + b.Property("RootFolder") + .HasColumnType("INTEGER"); + + b.Property("Status") + .HasColumnType("TEXT"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("TotalSeasons") + .HasColumnType("INTEGER"); + + b.Property("TvDbId") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.ToTable("TvRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Token") + .HasColumnType("TEXT"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Tokens"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Agent") + .HasColumnType("INTEGER"); + + b.Property("Enabled") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("Value") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RadarrQualityProfile") + .HasColumnType("INTEGER"); + + b.Property("RadarrRootPath") + .HasColumnType("INTEGER"); + + b.Property("SonarrQualityProfile") + .HasColumnType("INTEGER"); + + b.Property("SonarrQualityProfileAnime") + .HasColumnType("INTEGER"); + + b.Property("SonarrRootPath") + .HasColumnType("INTEGER"); + + b.Property("SonarrRootPathAnime") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("UserQualityProfiles"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("Date") + .HasColumnType("TEXT"); + + b.Property("Deleted") + .HasColumnType("INTEGER"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.Property("VoteType") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Votes"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("AirDate") + .HasColumnType("TEXT"); + + b.Property("Approved") + .HasColumnType("INTEGER"); + + b.Property("Available") + .HasColumnType("INTEGER"); + + b.Property("EpisodeNumber") + .HasColumnType("INTEGER"); + + b.Property("Requested") + .HasColumnType("INTEGER"); + + b.Property("SeasonId") + .HasColumnType("INTEGER"); + + b.Property("Title") + .HasColumnType("TEXT"); + + b.Property("Url") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("SeasonId"); + + b.ToTable("EpisodeRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("ChildRequestId") + .HasColumnType("INTEGER"); + + b.Property("Overview") + .HasColumnType("TEXT"); + + b.Property("SeasonNumber") + .HasColumnType("INTEGER"); + + b.HasKey("Id"); + + b.HasIndex("ChildRequestId"); + + b.ToTable("SeasonRequests"); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => + { + b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole", null) + .WithMany() + .HasForeignKey("RoleId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", null) + .WithMany() + .HasForeignKey("UserId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Ombi.Store.Entities.MobileDevices", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.NotificationUserId", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("NotificationUserIds") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.TvRequests", "ParentRequest") + .WithMany("ChildRequests") + .HasForeignKey("ParentRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("ParentRequest"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.IssueComments", b => + { + b.HasOne("Ombi.Store.Entities.Requests.Issues", "Issues") + .WithMany("Comments") + .HasForeignKey("IssuesId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("Issues"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.HasOne("Ombi.Store.Entities.Requests.IssueCategory", "IssueCategory") + .WithMany() + .HasForeignKey("IssueCategoryId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.Requests.MovieRequests", null) + .WithMany("Issues") + .HasForeignKey("IssueId"); + + b.HasOne("Ombi.Store.Entities.OmbiUser", "UserReported") + .WithMany() + .HasForeignKey("UserReportedId"); + + b.Navigation("IssueCategory"); + + b.Navigation("UserReported"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") + .WithMany() + .HasForeignKey("RequestedUserId"); + + b.Navigation("RequestedUser"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.RequestLog", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserNotificationPreferences", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany("UserNotificationPreferences") + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.UserQualityProfiles", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Votes", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.EpisodeRequests", b => + { + b.HasOne("Ombi.Store.Repository.Requests.SeasonRequests", "Season") + .WithMany("Episodes") + .HasForeignKey("SeasonId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("Season"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.HasOne("Ombi.Store.Entities.Requests.ChildRequests", "ChildRequest") + .WithMany("SeasonRequests") + .HasForeignKey("ChildRequestId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("ChildRequest"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.OmbiUser", b => + { + b.Navigation("NotificationUserIds"); + + b.Navigation("UserNotificationPreferences"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.ChildRequests", b => + { + b.Navigation("Issues"); + + b.Navigation("SeasonRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.Issues", b => + { + b.Navigation("Comments"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.MovieRequests", b => + { + b.Navigation("Issues"); + }); + + modelBuilder.Entity("Ombi.Store.Entities.Requests.TvRequests", b => + { + b.Navigation("ChildRequests"); + }); + + modelBuilder.Entity("Ombi.Store.Repository.Requests.SeasonRequests", b => + { + b.Navigation("Episodes"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/20220407072656_RequestSource.cs b/src/Ombi.Store/Migrations/OmbiSqlite/20220407072656_RequestSource.cs new file mode 100644 index 000000000..c1a2400d0 --- /dev/null +++ b/src/Ombi.Store/Migrations/OmbiSqlite/20220407072656_RequestSource.cs @@ -0,0 +1,48 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Ombi.Store.Migrations.OmbiSqlite +{ + public partial class RequestSource : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "Source", + table: "MovieRequests", + type: "INTEGER", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "Source", + table: "ChildRequests", + type: "INTEGER", + nullable: false, + defaultValue: 0); + + migrationBuilder.AddColumn( + name: "Source", + table: "AlbumRequests", + type: "INTEGER", + nullable: false, + defaultValue: 0); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Source", + table: "MovieRequests"); + + migrationBuilder.DropColumn( + name: "Source", + table: "ChildRequests"); + + migrationBuilder.DropColumn( + name: "Source", + table: "AlbumRequests"); + } + } +} diff --git a/src/Ombi.Store/Migrations/OmbiSqlite/OmbiSqliteContextModelSnapshot.cs b/src/Ombi.Store/Migrations/OmbiSqlite/OmbiSqliteContextModelSnapshot.cs index 46a00353e..f9ce86bae 100644 --- a/src/Ombi.Store/Migrations/OmbiSqlite/OmbiSqliteContextModelSnapshot.cs +++ b/src/Ombi.Store/Migrations/OmbiSqlite/OmbiSqliteContextModelSnapshot.cs @@ -5,6 +5,8 @@ using Microsoft.EntityFrameworkCore.Infrastructure; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using Ombi.Store.Context.Sqlite; +#nullable disable + namespace Ombi.Store.Migrations.OmbiSqlite { [DbContext(typeof(OmbiSqliteContext))] @@ -13,8 +15,7 @@ namespace Ombi.Store.Migrations.OmbiSqlite protected override void BuildModel(ModelBuilder modelBuilder) { #pragma warning disable 612, 618 - modelBuilder - .HasAnnotation("ProductVersion", "5.0.1"); + modelBuilder.HasAnnotation("ProductVersion", "6.0.0"); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b => { @@ -39,7 +40,7 @@ namespace Ombi.Store.Migrations.OmbiSqlite .IsUnique() .HasDatabaseName("RoleNameIndex"); - b.ToTable("AspNetRoles"); + b.ToTable("AspNetRoles", (string)null); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim", b => @@ -62,7 +63,7 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.HasIndex("RoleId"); - b.ToTable("AspNetRoleClaims"); + b.ToTable("AspNetRoleClaims", (string)null); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim", b => @@ -85,7 +86,7 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.HasIndex("UserId"); - b.ToTable("AspNetUserClaims"); + b.ToTable("AspNetUserClaims", (string)null); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin", b => @@ -107,7 +108,7 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.HasIndex("UserId"); - b.ToTable("AspNetUserLogins"); + b.ToTable("AspNetUserLogins", (string)null); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole", b => @@ -122,7 +123,7 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.HasIndex("RoleId"); - b.ToTable("AspNetUserRoles"); + b.ToTable("AspNetUserRoles", (string)null); }); modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken", b => @@ -141,7 +142,7 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.HasKey("UserId", "LoginProvider", "Name"); - b.ToTable("AspNetUserTokens"); + b.ToTable("AspNetUserTokens", (string)null); }); modelBuilder.Entity("Ombi.Store.Entities.Audit", b => @@ -280,6 +281,9 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.Property("LockoutEnd") .HasColumnType("TEXT"); + b.Property("MediaServerToken") + .HasColumnType("TEXT"); + b.Property("MovieRequestLimit") .HasColumnType("INTEGER"); @@ -341,7 +345,7 @@ namespace Ombi.Store.Migrations.OmbiSqlite .IsUnique() .HasDatabaseName("UserNameIndex"); - b.ToTable("AspNetUsers"); + b.ToTable("AspNetUsers", (string)null); }); modelBuilder.Entity("Ombi.Store.Entities.RecentlyAddedLog", b => @@ -405,28 +409,6 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.ToTable("RequestQueue"); }); - modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => - { - b.Property("Id") - .ValueGeneratedOnAdd() - .HasColumnType("INTEGER"); - - b.Property("RequestId") - .HasColumnType("INTEGER"); - - b.Property("RequestType") - .HasColumnType("INTEGER"); - - b.Property("UserId") - .HasColumnType("TEXT"); - - b.HasKey("Id"); - - b.HasIndex("UserId"); - - b.ToTable("RequestSubscription"); - }); - modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => { b.Property("Id") @@ -487,6 +469,9 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.Property("RequestedUserId") .HasColumnType("TEXT"); + b.Property("Source") + .HasColumnType("INTEGER"); + b.Property("Title") .HasColumnType("TEXT"); @@ -545,6 +530,9 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.Property("SeriesType") .HasColumnType("INTEGER"); + b.Property("Source") + .HasColumnType("INTEGER"); + b.Property("Title") .HasColumnType("TEXT"); @@ -660,21 +648,36 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.Property("Approved") .HasColumnType("INTEGER"); + b.Property("Approved4K") + .HasColumnType("INTEGER"); + b.Property("Available") .HasColumnType("INTEGER"); + b.Property("Available4K") + .HasColumnType("INTEGER"); + b.Property("Background") .HasColumnType("TEXT"); b.Property("Denied") .HasColumnType("INTEGER"); + b.Property("Denied4K") + .HasColumnType("INTEGER"); + b.Property("DeniedReason") .HasColumnType("TEXT"); + b.Property("DeniedReason4K") + .HasColumnType("TEXT"); + b.Property("DigitalReleaseDate") .HasColumnType("TEXT"); + b.Property("Has4KRequest") + .HasColumnType("INTEGER"); + b.Property("ImdbId") .HasColumnType("TEXT"); @@ -687,12 +690,21 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.Property("MarkedAsApproved") .HasColumnType("TEXT"); + b.Property("MarkedAsApproved4K") + .HasColumnType("TEXT"); + b.Property("MarkedAsAvailable") .HasColumnType("TEXT"); + b.Property("MarkedAsAvailable4K") + .HasColumnType("TEXT"); + b.Property("MarkedAsDenied") .HasColumnType("TEXT"); + b.Property("MarkedAsDenied4K") + .HasColumnType("TEXT"); + b.Property("Overview") .HasColumnType("TEXT"); @@ -714,12 +726,18 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.Property("RequestedDate") .HasColumnType("TEXT"); + b.Property("RequestedDate4k") + .HasColumnType("TEXT"); + b.Property("RequestedUserId") .HasColumnType("TEXT"); b.Property("RootPathOverride") .HasColumnType("INTEGER"); + b.Property("Source") + .HasColumnType("INTEGER"); + b.Property("Status") .HasColumnType("TEXT"); @@ -814,6 +832,28 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.ToTable("TvRequests"); }); + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("INTEGER"); + + b.Property("RequestId") + .HasColumnType("INTEGER"); + + b.Property("RequestType") + .HasColumnType("INTEGER"); + + b.Property("UserId") + .HasColumnType("TEXT"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("RequestSubscription"); + }); + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => { b.Property("Id") @@ -1051,15 +1091,6 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.Navigation("User"); }); - modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => - { - b.HasOne("Ombi.Store.Entities.OmbiUser", "User") - .WithMany() - .HasForeignKey("UserId"); - - b.Navigation("User"); - }); - modelBuilder.Entity("Ombi.Store.Entities.Requests.AlbumRequest", b => { b.HasOne("Ombi.Store.Entities.OmbiUser", "RequestedUser") @@ -1144,6 +1175,15 @@ namespace Ombi.Store.Migrations.OmbiSqlite b.Navigation("User"); }); + modelBuilder.Entity("Ombi.Store.Entities.RequestSubscription", b => + { + b.HasOne("Ombi.Store.Entities.OmbiUser", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + modelBuilder.Entity("Ombi.Store.Entities.Tokens", b => { b.HasOne("Ombi.Store.Entities.OmbiUser", "User") diff --git a/src/Ombi.Store/Ombi.Store.csproj b/src/Ombi.Store/Ombi.Store.csproj index 99e12530f..1c145f55a 100644 --- a/src/Ombi.Store/Ombi.Store.csproj +++ b/src/Ombi.Store/Ombi.Store.csproj @@ -1,25 +1,25 @@  - net5.0 + net6.0 3.0.0.0 3.0.0.0 true - 8.0 + latest Debug;Release;NonUiBuild - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + diff --git a/src/Ombi.Store/Repository/EmbyContentRepository.cs b/src/Ombi.Store/Repository/EmbyContentRepository.cs index f8743e30f..8f9904ebb 100644 --- a/src/Ombi.Store/Repository/EmbyContentRepository.cs +++ b/src/Ombi.Store/Repository/EmbyContentRepository.cs @@ -25,7 +25,6 @@ // ************************************************************************/ #endregion -using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; @@ -35,17 +34,12 @@ using Ombi.Store.Entities; namespace Ombi.Store.Repository { - public class EmbyContentRepository : ExternalRepository, IEmbyContentRepository + public class EmbyContentRepository : MediaServerContentRepository, IEmbyContentRepository { - public EmbyContentRepository(ExternalContext db):base(db) { - Db = db; } - private ExternalContext Db { get; } - - public async Task GetByImdbId(string imdbid) { return await Db.EmbyContent.FirstOrDefaultAsync(x => x.ImdbId == imdbid); @@ -69,20 +63,20 @@ namespace Ombi.Store.Repository return await Db.EmbyContent./*Include(x => x.Seasons).*/FirstOrDefaultAsync(x => x.EmbyId == embyId); } - public async Task Update(EmbyContent existingContent) + public override async Task Update(IMediaServerContent existingContent) { - Db.EmbyContent.Update(existingContent); + Db.EmbyContent.Update((EmbyContent)existingContent); await InternalSaveChanges(); } - public IQueryable GetAllEpisodes() + public override IQueryable GetAllEpisodes() { return Db.EmbyEpisode.AsQueryable(); } - public async Task Add(EmbyEpisode content) + public override async Task Add(IMediaServerEpisode content) { - await Db.EmbyEpisode.AddAsync(content); + await Db.EmbyEpisode.AddAsync((EmbyEpisode)content); await InternalSaveChanges(); return content; } @@ -91,16 +85,30 @@ namespace Ombi.Store.Repository return await Db.EmbyEpisode.FirstOrDefaultAsync(x => x.EmbyId == key); } - public async Task AddRange(IEnumerable content) + public override async Task AddRange(IEnumerable content) { - Db.EmbyEpisode.AddRange(content); + Db.EmbyEpisode.AddRange((IEnumerable)content); await InternalSaveChanges(); } - public void UpdateWithoutSave(EmbyContent existingContent) + public override void UpdateWithoutSave(IMediaServerContent existingContent) { - Db.EmbyContent.Update(existingContent); + Db.EmbyContent.Update((EmbyContent)existingContent); } - + + public override Task UpdateRange(IEnumerable existingContent) + { + Db.EmbyContent.UpdateRange((IEnumerable)existingContent); + return InternalSaveChanges(); + } + + public override async Task DeleteTv(EmbyContent tv) + { + var episodesToDelete = GetAllEpisodes().Cast().Where(x => x.ParentId == tv.EmbyId).ToList(); + Db.EmbyEpisode.RemoveRange(episodesToDelete); + await Delete(tv); + } + + public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Emby; } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/IEmbyContentRepository.cs b/src/Ombi.Store/Repository/IEmbyContentRepository.cs index a893e9aca..c171fef20 100644 --- a/src/Ombi.Store/Repository/IEmbyContentRepository.cs +++ b/src/Ombi.Store/Repository/IEmbyContentRepository.cs @@ -6,19 +6,16 @@ using Ombi.Store.Entities; namespace Ombi.Store.Repository { - public interface IEmbyContentRepository : IRepository + public interface IEmbyContentRepository : IMediaServerContentRepository { + Task GetByEmbyId(string embyId); + Task GetEpisodeByEmbyId(string key); + + // TODO: merge these with IJellyfinContentRepository IQueryable Get(); Task GetByTheMovieDbId(string mov); Task GetByTvDbId(string tv); Task GetByImdbId(string imdbid); - Task GetByEmbyId(string embyId); - Task Update(EmbyContent existingContent); - IQueryable GetAllEpisodes(); - Task Add(EmbyEpisode content); - Task GetEpisodeByEmbyId(string key); - Task AddRange(IEnumerable content); - void UpdateWithoutSave(EmbyContent existingContent); } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/IExternalRepository.cs b/src/Ombi.Store/Repository/IExternalRepository.cs index b22cb5ea8..ec7b27769 100644 --- a/src/Ombi.Store/Repository/IExternalRepository.cs +++ b/src/Ombi.Store/Repository/IExternalRepository.cs @@ -9,7 +9,7 @@ using Ombi.Store.Entities; namespace Ombi.Store.Repository { - public interface IExternalRepository where T : Entity + public interface IExternalRepository where T : IEntity { Task Find(object key); IQueryable GetAll(); @@ -25,6 +25,5 @@ namespace Ombi.Store.Repository where TEntity : class; Task ExecuteSql(string sql); - DbSet _db { get; } } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/IJellyfinContentRepository.cs b/src/Ombi.Store/Repository/IJellyfinContentRepository.cs index ff1f2d7dc..30efa1a17 100644 --- a/src/Ombi.Store/Repository/IJellyfinContentRepository.cs +++ b/src/Ombi.Store/Repository/IJellyfinContentRepository.cs @@ -6,19 +6,16 @@ using Ombi.Store.Entities; namespace Ombi.Store.Repository { - public interface IJellyfinContentRepository : IRepository + public interface IJellyfinContentRepository : IMediaServerContentRepository { + Task GetByJellyfinId(string jellyfinId); + Task GetEpisodeByJellyfinId(string key); + + // TODO: merge these with IEmbyContentRepository IQueryable Get(); Task GetByTheMovieDbId(string mov); Task GetByTvDbId(string tv); Task GetByImdbId(string imdbid); - Task GetByJellyfinId(string jellyfinId); - Task Update(JellyfinContent existingContent); - IQueryable GetAllEpisodes(); - Task Add(JellyfinEpisode content); - Task GetEpisodeByJellyfinId(string key); - Task AddRange(IEnumerable content); - void UpdateWithoutSave(JellyfinContent existingContent); } } diff --git a/src/Ombi.Store/Repository/IMediaServerContentRepository.cs b/src/Ombi.Store/Repository/IMediaServerContentRepository.cs new file mode 100644 index 000000000..3f165b7e6 --- /dev/null +++ b/src/Ombi.Store/Repository/IMediaServerContentRepository.cs @@ -0,0 +1,20 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Ombi.Store.Entities; + +namespace Ombi.Store.Repository +{ + public interface IMediaServerContentRepository : IExternalRepository + where Content : IMediaServerContent + { + RecentlyAddedType RecentlyAddedType{ get; } + Task Update(IMediaServerContent existingContent); + Task UpdateRange(IEnumerable existingContent); + IQueryable GetAllEpisodes(); + Task Add(IMediaServerEpisode content); + Task AddRange(IEnumerable content); + Task DeleteTv(Content tv); + void UpdateWithoutSave(IMediaServerContent existingContent); + } +} \ No newline at end of file diff --git a/src/Ombi.Store/Repository/IPlexContentRepository.cs b/src/Ombi.Store/Repository/IPlexContentRepository.cs index 38c013cb1..aeb4aae0a 100644 --- a/src/Ombi.Store/Repository/IPlexContentRepository.cs +++ b/src/Ombi.Store/Repository/IPlexContentRepository.cs @@ -8,23 +8,18 @@ using Ombi.Store.Entities; namespace Ombi.Store.Repository { - public interface IPlexContentRepository : IExternalRepository + public interface IPlexContentRepository : IMediaServerContentRepository { Task ContentExists(string providerId); Task Get(string providerId, ProviderType type); - Task GetByType(string providerId, ProviderType type, PlexMediaTypeEntity plexType); - Task GetByKey(int key); - Task Update(PlexServerContent existingContent); - IQueryable GetAllEpisodes(); - Task Add(PlexEpisode content); - Task GetEpisodeByKey(int key); - Task AddRange(IEnumerable content); + Task GetByType(string providerId, ProviderType type, MediaType mediaType); + Task GetByKey(string key); + Task GetEpisodeByKey(string key); IEnumerable GetWhereContentByCustom(Expression> predicate); Task GetFirstContentByCustom(Expression> predicate); Task DeleteEpisode(PlexEpisode content); void DeleteWithoutSave(PlexServerContent content); void DeleteWithoutSave(PlexEpisode content); Task UpdateRange(IEnumerable existingContent); - void UpdateWithoutSave(PlexServerContent existingContent); } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/IRepository.cs b/src/Ombi.Store/Repository/IRepository.cs index b93b07d45..a6142462f 100644 --- a/src/Ombi.Store/Repository/IRepository.cs +++ b/src/Ombi.Store/Repository/IRepository.cs @@ -10,7 +10,7 @@ using Ombi.Store.Entities; namespace Ombi.Store.Repository { - public interface IRepository where T : Entity + public interface IRepository where T : IEntity { Task Find(object key); Task Find(object key, CancellationToken cancellationToken); @@ -27,6 +27,5 @@ namespace Ombi.Store.Repository where TEntity : class; Task ExecuteSql(string sql); - DbSet _db { get; } } } \ No newline at end of file diff --git a/src/Ombi.Store/Repository/JellyfinContentRepository.cs b/src/Ombi.Store/Repository/JellyfinContentRepository.cs index 2b84adb00..8dc729a6b 100644 --- a/src/Ombi.Store/Repository/JellyfinContentRepository.cs +++ b/src/Ombi.Store/Repository/JellyfinContentRepository.cs @@ -35,17 +35,13 @@ using Ombi.Store.Entities; namespace Ombi.Store.Repository { - public class JellyfinContentRepository : ExternalRepository, IJellyfinContentRepository + public class JellyfinContentRepository : MediaServerContentRepository, IJellyfinContentRepository { public JellyfinContentRepository(ExternalContext db):base(db) { - Db = db; } - private ExternalContext Db { get; } - - public async Task GetByImdbId(string imdbid) { return await Db.JellyfinContent.FirstOrDefaultAsync(x => x.ImdbId == imdbid); @@ -69,20 +65,20 @@ namespace Ombi.Store.Repository return await Db.JellyfinContent./*Include(x => x.Seasons).*/FirstOrDefaultAsync(x => x.JellyfinId == jellyfinId); } - public async Task Update(JellyfinContent existingContent) + public override async Task Update(IMediaServerContent existingContent) { - Db.JellyfinContent.Update(existingContent); + Db.JellyfinContent.Update((JellyfinContent)existingContent); await InternalSaveChanges(); } - public IQueryable GetAllEpisodes() + public override IQueryable GetAllEpisodes() { return Db.JellyfinEpisode.AsQueryable(); } - public async Task Add(JellyfinEpisode content) + public override async Task Add(IMediaServerEpisode content) { - await Db.JellyfinEpisode.AddAsync(content); + await Db.JellyfinEpisode.AddAsync((JellyfinEpisode)content); await InternalSaveChanges(); return content; } @@ -91,16 +87,30 @@ namespace Ombi.Store.Repository return await Db.JellyfinEpisode.FirstOrDefaultAsync(x => x.JellyfinId == key); } - public async Task AddRange(IEnumerable content) + public override async Task AddRange(IEnumerable content) { - Db.JellyfinEpisode.AddRange(content); + Db.JellyfinEpisode.AddRange((IEnumerable)content); await InternalSaveChanges(); } - public void UpdateWithoutSave(JellyfinContent existingContent) + public override void UpdateWithoutSave(IMediaServerContent existingContent) { - Db.JellyfinContent.Update(existingContent); + Db.JellyfinContent.Update((JellyfinContent)existingContent); } - + + public override Task UpdateRange(IEnumerable existingContent) + { + Db.JellyfinContent.UpdateRange((IEnumerable)existingContent); + return InternalSaveChanges(); + } + + public override async Task DeleteTv(JellyfinContent tv) + { + var episodesToDelete = GetAllEpisodes().Cast().Where(x => x.ParentId == tv.JellyfinId).ToList(); + Db.JellyfinEpisode.RemoveRange(episodesToDelete); + await Delete(tv); + } + + public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Jellyfin; } } diff --git a/src/Ombi.Store/Repository/MediaServerRepository.cs b/src/Ombi.Store/Repository/MediaServerRepository.cs new file mode 100644 index 000000000..251fe3cea --- /dev/null +++ b/src/Ombi.Store/Repository/MediaServerRepository.cs @@ -0,0 +1,27 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Ombi.Store.Context; +using Ombi.Store.Entities; + +namespace Ombi.Store.Repository +{ + public abstract class MediaServerContentRepository : ExternalRepository, IMediaServerContentRepository where T : MediaServerContent + { + protected ExternalContext Db { get; } + public abstract RecentlyAddedType RecentlyAddedType { get; } + + public MediaServerContentRepository(ExternalContext db) : base(db) + { + Db = db; + } + + public abstract Task Update(IMediaServerContent existingContent); + public abstract IQueryable GetAllEpisodes(); + public abstract Task Add(IMediaServerEpisode content); + public abstract Task AddRange(IEnumerable content); + public abstract void UpdateWithoutSave(IMediaServerContent existingContent); + public abstract Task UpdateRange(IEnumerable existingContent); + public abstract Task DeleteTv(T tv); + } +} \ No newline at end of file diff --git a/src/Ombi.Store/Repository/PlexContentRepository.cs b/src/Ombi.Store/Repository/PlexContentRepository.cs index 31b3bad11..9f34af6a1 100644 --- a/src/Ombi.Store/Repository/PlexContentRepository.cs +++ b/src/Ombi.Store/Repository/PlexContentRepository.cs @@ -37,17 +37,13 @@ using Ombi.Store.Entities; namespace Ombi.Store.Repository { - public class PlexServerContentRepository : ExternalRepository, IPlexContentRepository + public class PlexServerContentRepository : MediaServerContentRepository, IPlexContentRepository { - + public override RecentlyAddedType RecentlyAddedType => RecentlyAddedType.Plex; public PlexServerContentRepository(ExternalContext db) : base(db) { - Db = db; } - private ExternalContext Db { get; } - - public async Task ContentExists(string providerId) { var any = await Db.PlexServerContent.AnyAsync(x => x.ImdbId == providerId); @@ -79,16 +75,16 @@ namespace Ombi.Store.Repository return null; } - public async Task GetByType(string providerId, ProviderType type, PlexMediaTypeEntity plexType) + public async Task GetByType(string providerId, ProviderType type, MediaType mediaType) { switch (type) { case ProviderType.ImdbId: - return await Db.PlexServerContent.FirstOrDefaultAsync(x => x.ImdbId == providerId && x.Type == plexType); + return await Db.PlexServerContent.FirstOrDefaultAsync(x => x.ImdbId == providerId && x.Type == mediaType); case ProviderType.TheMovieDbId: - return await Db.PlexServerContent.FirstOrDefaultAsync(x => x.TheMovieDbId == providerId && x.Type == plexType); + return await Db.PlexServerContent.FirstOrDefaultAsync(x => x.TheMovieDbId == providerId && x.Type == mediaType); case ProviderType.TvDbId: - return await Db.PlexServerContent.FirstOrDefaultAsync(x => x.TvDbId == providerId && x.Type == plexType); + return await Db.PlexServerContent.FirstOrDefaultAsync(x => x.TvDbId == providerId && x.Type == mediaType); default: break; } @@ -96,7 +92,7 @@ namespace Ombi.Store.Repository return null; } - public async Task GetByKey(int key) + public async Task GetByKey(string key) { return await Db.PlexServerContent.Include(x => x.Seasons).FirstOrDefaultAsync(x => x.Key == key); } @@ -114,14 +110,14 @@ namespace Ombi.Store.Repository .FirstOrDefaultAsync(predicate); } - public async Task Update(PlexServerContent existingContent) + public override async Task Update(IMediaServerContent existingContent) { - Db.PlexServerContent.Update(existingContent); + Db.PlexServerContent.Update((PlexServerContent)existingContent); await InternalSaveChanges(); } - public void UpdateWithoutSave(PlexServerContent existingContent) + public override void UpdateWithoutSave(IMediaServerContent existingContent) { - Db.PlexServerContent.Update(existingContent); + Db.PlexServerContent.Update((PlexServerContent)existingContent); } public async Task UpdateRange(IEnumerable existingContent) @@ -130,7 +126,7 @@ namespace Ombi.Store.Repository await InternalSaveChanges(); } - public IQueryable GetAllEpisodes() + public override IQueryable GetAllEpisodes() { return Db.PlexEpisode.Include(x => x.Series).AsQueryable(); } @@ -145,9 +141,9 @@ namespace Ombi.Store.Repository Db.PlexEpisode.Remove(content); } - public async Task Add(PlexEpisode content) + public override async Task Add(IMediaServerEpisode content) { - await Db.PlexEpisode.AddAsync(content); + await Db.PlexEpisode.AddAsync((PlexEpisode)content); await InternalSaveChanges(); return content; } @@ -158,14 +154,27 @@ namespace Ombi.Store.Repository await InternalSaveChanges(); } - public async Task GetEpisodeByKey(int key) + public async Task GetEpisodeByKey(string key) { return await Db.PlexEpisode.FirstOrDefaultAsync(x => x.Key == key); } - public async Task AddRange(IEnumerable content) + public override async Task AddRange(IEnumerable content) { - Db.PlexEpisode.AddRange(content); + Db.PlexEpisode.AddRange((IEnumerable)content); await InternalSaveChanges(); } + + public override Task UpdateRange(IEnumerable existingContent) + { + Db.PlexServerContent.UpdateRange((IEnumerable)existingContent); + return InternalSaveChanges(); + } + + public override Task DeleteTv(PlexServerContent tv) + { + // not used for now + // TODO: delete episodes, then delete series + throw new NotImplementedException(); + } } } \ No newline at end of file diff --git a/src/Ombi.Test.Common/Ombi.Test.Common.csproj b/src/Ombi.Test.Common/Ombi.Test.Common.csproj index deeccf52b..512055143 100644 --- a/src/Ombi.Test.Common/Ombi.Test.Common.csproj +++ b/src/Ombi.Test.Common/Ombi.Test.Common.csproj @@ -1,8 +1,8 @@  - net5.0 - 8.0 + net6.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.Tests/Ombi.Tests.csproj b/src/Ombi.Tests/Ombi.Tests.csproj index 9153b12d1..c38756445 100644 --- a/src/Ombi.Tests/Ombi.Tests.csproj +++ b/src/Ombi.Tests/Ombi.Tests.csproj @@ -1,7 +1,7 @@  - net5.0 + net6.0 false @@ -9,12 +9,12 @@ - + - + diff --git a/src/Ombi.TheMovieDbApi/IMovieDbApi.cs b/src/Ombi.TheMovieDbApi/IMovieDbApi.cs index 6d0859cef..9b277c091 100644 --- a/src/Ombi.TheMovieDbApi/IMovieDbApi.cs +++ b/src/Ombi.TheMovieDbApi/IMovieDbApi.cs @@ -15,14 +15,16 @@ namespace Ombi.Api.TheMovieDb Task GetMovieInformation(int movieId); Task GetMovieInformationWithExtraInfo(int movieId, string langCode = "en"); Task> NowPlaying(string languageCode, int? page = null); + Task> TrendingMovies(string languageCode, int? page = null); Task> PopularMovies(string languageCode, int? page = null, CancellationToken cancellationToken = default(CancellationToken)); Task> PopularTv(string langCode, int? page = null, CancellationToken cancellationToken = default(CancellationToken)); Task> SearchMovie(string searchTerm, int? year, string languageCode); Task> GetMoviesViaKeywords(string keywordId, string langCode, CancellationToken cancellationToken, int? page = null); Task> SearchTv(string searchTerm, string year = default); Task> TopRated(string languageCode, int? page = null); - Task> Upcoming(string languageCode, int? page = null); + Task> UpcomingMovies(string languageCode, int? page = null); Task> TopRatedTv(string languageCode, int? page = null); + Task> TrendingTv(string languageCode, int? page = null); Task> UpcomingTv(string languageCode, int? page = null); Task> SimilarMovies(int movieId, string langCode); Task Find(string externalId, ExternalSource source); @@ -31,6 +33,7 @@ namespace Ombi.Api.TheMovieDb Task GetTVInfo(string themoviedbid, string langCode = "en"); Task> SearchByActor(string searchTerm, string langCode); Task GetActorMovieCredits(int actorId, string langCode); + Task GetActorTvCredits(int actorId, string langCode); Task> MultiSearch(string searchTerm, string languageCode, CancellationToken cancellationToken); Task> DiscoverMovies(string langCode, int keywordId); Task GetFullMovieInfo(int movieId, CancellationToken cancellationToken, string langCode); @@ -39,8 +42,9 @@ namespace Ombi.Api.TheMovieDb Task GetKeyword(int keywordId); Task GetMovieWatchProviders(int theMoviedbId, CancellationToken token); Task GetTvWatchProviders(int theMoviedbId, CancellationToken token); - Task> GetGenres(string media, CancellationToken cancellationToken); + Task> GetGenres(string media, CancellationToken cancellationToken, string languageCode); + Task> GetLanguages(CancellationToken cancellationToken); Task> SearchWatchProviders(string media, string searchTerm, CancellationToken cancellationToken); - Task> AdvancedSearch(DiscoverModel model, CancellationToken cancellationToken); + Task> AdvancedSearch(DiscoverModel model, int page, CancellationToken cancellationToken); } } diff --git a/src/Ombi.TheMovieDbApi/Models/Language.cs b/src/Ombi.TheMovieDbApi/Models/Language.cs new file mode 100644 index 000000000..c6b14a654 --- /dev/null +++ b/src/Ombi.TheMovieDbApi/Models/Language.cs @@ -0,0 +1,14 @@ +using Newtonsoft.Json; + +namespace Ombi.TheMovieDbApi.Models +{ + public class Language + { + [JsonProperty("iso_639_1")] + public string Id { get; set; } + [JsonProperty("english_name")] + public string EnglishName { get; set; } + [JsonProperty("name")] + public string Name { get; set; } + } +} \ No newline at end of file diff --git a/src/Ombi.TheMovieDbApi/Ombi.Api.TheMovieDb.csproj b/src/Ombi.TheMovieDbApi/Ombi.Api.TheMovieDb.csproj index 6311e948c..ddab7e3f8 100644 --- a/src/Ombi.TheMovieDbApi/Ombi.Api.TheMovieDb.csproj +++ b/src/Ombi.TheMovieDbApi/Ombi.Api.TheMovieDb.csproj @@ -1,13 +1,13 @@  - net5.0 + net6.0 Ombi.Api.TheMovieDb 3.0.0.0 3.0.0.0 - 8.0 + latest Debug;Release;NonUiBuild diff --git a/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs b/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs index aa46b0c8e..055265701 100644 --- a/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs +++ b/src/Ombi.TheMovieDbApi/TheMovieDbApi.cs @@ -70,11 +70,11 @@ namespace Ombi.Api.TheMovieDb - public async Task> AdvancedSearch(DiscoverModel model, CancellationToken cancellationToken) + public async Task> AdvancedSearch(DiscoverModel model, int page, CancellationToken cancellationToken) { var request = new Request($"discover/{model.Type}", BaseUri, HttpMethod.Get); request.FullUri = request.FullUri.AddQueryParameter("api_key", ApiToken); - if(model.ReleaseYear.HasValue && model.ReleaseYear.Value > 1900) + if (model.ReleaseYear.HasValue && model.ReleaseYear.Value > 1900) { request.FullUri = request.FullUri.AddQueryParameter("year", model.ReleaseYear.Value.ToString()); } @@ -92,6 +92,9 @@ namespace Ombi.Api.TheMovieDb } //request.FullUri = request.FullUri.AddQueryParameter("sort_by", "popularity.desc"); + request.AddQueryString("page", page.ToString()); + + var result = await Api.Request>(request, cancellationToken); return Mapper.Map>(result.results); } @@ -140,6 +143,16 @@ namespace Ombi.Api.TheMovieDb return result; } + public async Task GetActorTvCredits(int actorId, string langCode) + { + var request = new Request($"person/{actorId}/tv_credits", BaseUri, HttpMethod.Get); + request.AddQueryString("api_key", ApiToken); + request.AddQueryString("language", langCode); + + var result = await Api.Request(request); + return result; + } + public async Task> SearchTv(string searchTerm, string year = default) { var request = new Request($"search/tv", BaseUri, HttpMethod.Get); @@ -272,21 +285,38 @@ namespace Ombi.Api.TheMovieDb return Mapper.Map>(result.results); } - public Task> Upcoming(string langCode, int? page = null) + public Task> TrendingMovies(string langCode, int? page = null) { - return Upcoming("movie", langCode, page); - } - public Task> UpcomingTv(string langCode, int? page = null) - { - return Upcoming("tv", langCode, page); + return Trending("movie", langCode, page); } + public Task> TrendingTv(string langCode, int? page = null) + { + return Trending("tv", langCode, page); + } + private async Task> Trending(string type, string langCode, int? page = null) + { + // https://developers.themoviedb.org/3/trending/get-trending + var timeWindow = "week"; // another option can be 'day' + var request = new Request($"trending/{type}/{timeWindow}", BaseUri, HttpMethod.Get); + request.AddQueryString("api_key", ApiToken); + request.AddQueryString("language", langCode); + + if (page != null) + { + request.AddQueryString("page", page.ToString()); + } + + AddRetry(request); + var result = await Api.Request>(request); + return Mapper.Map>(result.results); + } /// /// Maintains filter parity with /movie/upcoming. /// - private async Task> Upcoming(string type, string langCode, int? page = null) + public async Task> UpcomingMovies(string langCode, int? page = null) { - var request = new Request($"discover/{type}", BaseUri, HttpMethod.Get); + var request = new Request($"discover/movie", BaseUri, HttpMethod.Get); request.AddQueryString("api_key", ApiToken); request.AddQueryString("language", langCode); @@ -303,7 +333,27 @@ namespace Ombi.Api.TheMovieDb request.AddQueryString("page", page.ToString()); } await AddDiscoverSettings(request); - await AddGenreFilter(request, type); + await AddGenreFilter(request, "movie"); + AddRetry(request); + var result = await Api.Request>(request); + return Mapper.Map>(result.results); + } + public async Task> UpcomingTv(string langCode, int? page = null) + { + var request = new Request($"discover/tv", BaseUri, HttpMethod.Get); + request.AddQueryString("api_key", ApiToken); + request.AddQueryString("language", langCode); + + // Search for shows that will air in the next month + var startDate = DateTime.Today.AddDays(1); + request.AddQueryString($"first_air_date.gte", startDate.ToString("yyyy-MM-dd")); + request.AddQueryString($"first_air_date.lte", startDate.AddDays(30).ToString("yyyy-MM-dd")); + if (page != null) + { + request.AddQueryString("page", page.ToString()); + } + await AddDiscoverSettings(request); + await AddGenreFilter(request, "tv"); AddRetry(request); var result = await Api.Request>(request); return Mapper.Map>(result.results); @@ -366,8 +416,8 @@ namespace Ombi.Api.TheMovieDb request.AddQueryString("language", langCode); request.AddQueryString("sort_by", "vote_average.desc"); - request.AddQueryString("with_keywords", keywordId); - + request.AddQueryString("with_keywords", keywordId); + // `vote_count` consideration isn't explicitly documented, but using only the `sort_by` filter // does not provide the same results as `/movie/top_rated`. This appears to be adequate enough // to filter out extremely high-rated movies due to very little votes @@ -417,16 +467,27 @@ namespace Ombi.Api.TheMovieDb return keyword == null || keyword.Id == 0 ? null : keyword; } - public async Task> GetGenres(string media, CancellationToken cancellationToken) + public async Task> GetGenres(string media, CancellationToken cancellationToken, string languageCode) { var request = new Request($"genre/{media}/list", BaseUri, HttpMethod.Get); request.AddQueryString("api_key", ApiToken); + request.AddQueryString("language", languageCode); AddRetry(request); var result = await Api.Request>(request, cancellationToken); return result.genres ?? new List(); } + public async Task> GetLanguages(CancellationToken cancellationToken) + { + var request = new Request($"/configuration/languages", BaseUri, HttpMethod.Get); + request.AddQueryString("api_key", ApiToken); + AddRetry(request); + + var result = await Api.Request>(request, cancellationToken); + return result ?? new List(); + } + public Task> MultiSearch(string searchTerm, string languageCode, CancellationToken cancellationToken) { var request = new Request("search/multi", BaseUri, HttpMethod.Get); @@ -461,6 +522,10 @@ namespace Ombi.Api.TheMovieDb { request.AddQueryString("without_keywords", string.Join(",", settings.ExcludedKeywordIds)); } + if (settings.OriginalLanguages?.Any() == true) + { + request.AddQueryString("with_original_language", string.Join("|", settings.OriginalLanguages)); + } } private async Task AddGenreFilter(Request request, string media_type) @@ -468,7 +533,8 @@ namespace Ombi.Api.TheMovieDb var settings = await Settings; List excludedGenres; - switch (media_type) { + switch (media_type) + { case "tv": excludedGenres = settings.ExcludedTvGenreIds; break; diff --git a/src/Ombi.Updater/Ombi.Updater.csproj b/src/Ombi.Updater/Ombi.Updater.csproj index 6c74dbe74..d31229b62 100644 --- a/src/Ombi.Updater/Ombi.Updater.csproj +++ b/src/Ombi.Updater/Ombi.Updater.csproj @@ -3,7 +3,7 @@ Exe win10-x64;win10-x86;osx-x64;ubuntu-x64;debian.8-x64;centos.7-x64;linux-x64;linux-arm;linux-arm64; - net5.0 + net6.0 3.0.0.0 3.0.0.0 @@ -13,14 +13,14 @@ - - - - - - - - + + + + + + + + diff --git a/src/Ombi.sln b/src/Ombi.sln index 5149f020b..a92df055e 100644 --- a/src/Ombi.sln +++ b/src/Ombi.sln @@ -124,6 +124,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.CloudService", "Om EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.RottenTomatoes", "Ombi.Api.RottenTomatoes\Ombi.Api.RottenTomatoes.csproj", "{8F19C701-7881-4BC7-8BBA-B068A6B954AD}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.I18n", "Ombi.I18n\Ombi.I18n.csproj", "{6A922D57-8622-4C36-8E6E-D5BA9E8DA6C0}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Ombi.Api.MediaServer", "Ombi.Api.MediaServer\Ombi.Api.MediaServer.csproj", "{AFC0BA9B-E38D-479F-825A-2F94EE4D6120}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -431,6 +435,18 @@ Global {8F19C701-7881-4BC7-8BBA-B068A6B954AD}.NonUiBuild|Any CPU.Build.0 = NonUiBuild|Any CPU {8F19C701-7881-4BC7-8BBA-B068A6B954AD}.Release|Any CPU.ActiveCfg = Release|Any CPU {8F19C701-7881-4BC7-8BBA-B068A6B954AD}.Release|Any CPU.Build.0 = Release|Any CPU + {6A922D57-8622-4C36-8E6E-D5BA9E8DA6C0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6A922D57-8622-4C36-8E6E-D5BA9E8DA6C0}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6A922D57-8622-4C36-8E6E-D5BA9E8DA6C0}.NonUiBuild|Any CPU.ActiveCfg = NonUiBuild|Any CPU + {6A922D57-8622-4C36-8E6E-D5BA9E8DA6C0}.NonUiBuild|Any CPU.Build.0 = NonUiBuild|Any CPU + {6A922D57-8622-4C36-8E6E-D5BA9E8DA6C0}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6A922D57-8622-4C36-8E6E-D5BA9E8DA6C0}.Release|Any CPU.Build.0 = Release|Any CPU + {AFC0BA9B-E38D-479F-825A-2F94EE4D6120}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {AFC0BA9B-E38D-479F-825A-2F94EE4D6120}.Debug|Any CPU.Build.0 = Debug|Any CPU + {AFC0BA9B-E38D-479F-825A-2F94EE4D6120}.NonUiBuild|Any CPU.ActiveCfg = NonUiBuild|Any CPU + {AFC0BA9B-E38D-479F-825A-2F94EE4D6120}.NonUiBuild|Any CPU.Build.0 = NonUiBuild|Any CPU + {AFC0BA9B-E38D-479F-825A-2F94EE4D6120}.Release|Any CPU.ActiveCfg = Release|Any CPU + {AFC0BA9B-E38D-479F-825A-2F94EE4D6120}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -479,6 +495,7 @@ Global {E2186FDA-D827-4781-8663-130AC382F12C} = {9293CA11-360A-4C20-A674-B9E794431BF5} {5DE40A66-B369-469E-8626-ECE23D9D8034} = {9293CA11-360A-4C20-A674-B9E794431BF5} {8F19C701-7881-4BC7-8BBA-B068A6B954AD} = {9293CA11-360A-4C20-A674-B9E794431BF5} + {AFC0BA9B-E38D-479F-825A-2F94EE4D6120} = {9293CA11-360A-4C20-A674-B9E794431BF5} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {192E9BF8-00B4-45E4-BCCC-4C215725C869} diff --git a/src/Ombi/.vscode/launch.json b/src/Ombi/.vscode/launch.json index 642e584c5..9b6838630 100644 --- a/src/Ombi/.vscode/launch.json +++ b/src/Ombi/.vscode/launch.json @@ -6,7 +6,7 @@ "type": "coreclr", "request": "launch", "preLaunchTask": "build", - "program": "${workspaceFolder}/bin/Debug/net5.0/ombi.dll", + "program": "${workspaceFolder}/bin/Debug/net6.0/ombi.dll", "args": ["--host", "http://localhost:3577"], "cwd": "${workspaceFolder}", "stopAtEntry": false, @@ -47,4 +47,4 @@ } }, ] - } \ No newline at end of file + } diff --git a/src/Ombi/.vscode/settings.json b/src/Ombi/.vscode/settings.json index 89d2dbd93..0ac92f4ba 100644 --- a/src/Ombi/.vscode/settings.json +++ b/src/Ombi/.vscode/settings.json @@ -10,13 +10,19 @@ "cSpell.words": [ "usermanagement" ], - "discord.enabled": true, "conventionalCommits.scopes": [ "discover", "request-limits", "notifications", "settings", "user-management", - "newsletter" - ] + "newsletter", + "mass-email", + "issues", + "emby", + "availability-rules", + "details", + "requests" + ], + "rpc.enabled": true } diff --git a/src/Ombi/ClientApp/.gitignore b/src/Ombi/ClientApp/.gitignore index e1f679be2..043e30f6d 100644 --- a/src/Ombi/ClientApp/.gitignore +++ b/src/Ombi/ClientApp/.gitignore @@ -17,6 +17,7 @@ *.launch .settings/ *.sublime-workspace +.angular # IDE - VSCode .vscode/* diff --git a/src/Ombi/ClientApp/.storybook/main.js b/src/Ombi/ClientApp/.storybook/main.js new file mode 100644 index 000000000..92bb57a62 --- /dev/null +++ b/src/Ombi/ClientApp/.storybook/main.js @@ -0,0 +1,16 @@ +module.exports = { + "stories": [ + "../src/**/*.stories.mdx", + "../src/**/*.stories.@(js|jsx|ts|tsx)" + ], + "addons": [ + "@storybook/addon-links", + "@storybook/addon-essentials", + "@storybook/addon-interactions" + ], + "framework": "@storybook/angular", + "core": { + "builder": "@storybook/builder-webpack5" + }, + "staticDirs": ['../../wwwroot/images'] +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/.storybook/preview-body.html b/src/Ombi/ClientApp/.storybook/preview-body.html new file mode 100644 index 000000000..2cec56444 --- /dev/null +++ b/src/Ombi/ClientApp/.storybook/preview-body.html @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/src/Ombi/ClientApp/.storybook/preview.js b/src/Ombi/ClientApp/.storybook/preview.js new file mode 100644 index 000000000..a20381a89 --- /dev/null +++ b/src/Ombi/ClientApp/.storybook/preview.js @@ -0,0 +1,14 @@ +import { setCompodocJson } from "@storybook/addon-docs/angular"; +import docJson from "../documentation.json"; +setCompodocJson(docJson); + +export const parameters = { + actions: { argTypesRegex: "^on[A-Z].*" }, + controls: { + matchers: { + color: /(background|color)$/i, + date: /Date$/, + }, + }, + docs: { inlineStories: true }, +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/.storybook/tsconfig.json b/src/Ombi/ClientApp/.storybook/tsconfig.json new file mode 100644 index 000000000..54887e29c --- /dev/null +++ b/src/Ombi/ClientApp/.storybook/tsconfig.json @@ -0,0 +1,24 @@ +{ + "extends": "../src/tsconfig.json", + "compilerOptions": { + "types": [ + "node" + ], + "typeRoots": [ + "../node_modules/@typings" + ], + "allowSyntheticDefaultImports": true + }, + "exclude": [ + "../src/test.ts", + "../src/**/*.spec.ts", + "../projects/**/*.spec.ts" + ], + "include": [ + "../src/**/*", + "../projects/**/*" + ], + "files": [ + "./typings.d.ts" + ] +} diff --git a/src/Ombi/ClientApp/.storybook/typings.d.ts b/src/Ombi/ClientApp/.storybook/typings.d.ts new file mode 100644 index 000000000..f73d61b39 --- /dev/null +++ b/src/Ombi/ClientApp/.storybook/typings.d.ts @@ -0,0 +1,4 @@ +declare module '*.md' { + const content: string; + export default content; +} diff --git a/src/Ombi/ClientApp/angular.json b/src/Ombi/ClientApp/angular.json index 76749756d..d50a19844 100644 --- a/src/Ombi/ClientApp/angular.json +++ b/src/Ombi/ClientApp/angular.json @@ -19,7 +19,7 @@ "index": "src/index.html", "main": "src/main.ts", "polyfills": "src/polyfills.ts", - "tsConfig": "src/tsconfig.app.json", + "tsConfig": "src/tsconfig.json", "assets": [ "src/assets" ], @@ -34,11 +34,8 @@ "node_modules/@fortawesome/fontawesome-free/scss/brands.scss", "node_modules/primeng/resources/primeng.min.css", "node_modules/primeicons/primeicons.css", - "node_modules/please-wait/src/please-wait.scss", "node_modules/@fullcalendar/core/main.min.css", - "node_modules/@fullcalendar/daygrid/main.min.css", - "node_modules/spinkit/scss/spinners/11-folding-cube.scss", - "node_modules/spinkit/scss/spinkit.scss" + "node_modules/@fullcalendar/daygrid/main.min.css" ], "scripts": [ "node_modules/jquery/dist/jquery.min.js", @@ -82,7 +79,13 @@ "replace": "src/environments/environment.ts", "with": "src/environments/environment.hmr.ts" } - ] + ], + "buildOptimizer": false, + "optimization": false, + "vendorChunk": true, + "extractLicenses": false, + "sourceMap": true, + "namedChunks": true } } }, @@ -111,7 +114,7 @@ "builder": "@angular-devkit/build-angular:tslint", "options": { "tsConfig": [ - "src/tsconfig.app.json" + "src/tsconfig.json" ], "exclude": [ "**/node_modules/**" @@ -121,7 +124,6 @@ } } }, - "defaultProject": "ombi", "cli": { "analytics": false } diff --git a/src/Ombi/ClientApp/documentation.json b/src/Ombi/ClientApp/documentation.json new file mode 100644 index 000000000..901f0d264 --- /dev/null +++ b/src/Ombi/ClientApp/documentation.json @@ -0,0 +1,18 @@ +{ + "pipes": [], + "interfaces": [], + "injectables": [], + "guards": [], + "interceptors": [], + "classes": [], + "directives": [], + "components": [], + "modules": [], + "miscellaneous": [], + "routes": [], + "coverage": { + "count": 0, + "status": "low", + "files": [] + } +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/package.json b/src/Ombi/ClientApp/package.json index c68ed3782..787bcc23b 100644 --- a/src/Ombi/ClientApp/package.json +++ b/src/Ombi/ClientApp/package.json @@ -4,40 +4,42 @@ "scripts": { "ng": "ng", "start": "ng serve --port 3578 --configuration hmr", - "build": "node --max_old_space_size=6144 node_modules/@angular/cli/bin/ng build --prod", - "lint": "ng lint" + "build": "node --max_old_space_size=6144 node_modules/@angular/cli/bin/ng build -c production", + "lint": "ng lint", + "docs:json": "compodoc -p ./tsconfig.json -e json -d .", + "storybook": "start-storybook -p 6006", + "chromatic": "chromatic --exit-zero-on-changes", + "storybookbuild": "yarn build-storybook" }, "private": true, "dependencies": { - "@angular/animations": "^12.2.10", - "@angular/cdk": "^12.2.9", - "@angular/common": "^12.2.10", - "@angular/compiler": "^12.2.10", - "@angular/core": "^12.2.10", - "@angular/forms": "^12.2.10", - "@angular/localize": "^12.2.10", - "@angular/material": "^12.2.9", - "@angular/platform-browser": "^12.2.10", - "@angular/platform-browser-dynamic": "^12.2.10", - "@angular/platform-server": "^12.2.10", - "@angular/router": "^12.2.10", + "@angular/animations": "^14.0.0", + "@angular/cdk": "^13.2.0", + "@angular/common": "^14.0.0", + "@angular/compiler": "^14.0.0", + "@angular/core": "^14.0.0", + "@angular/forms": "^14.0.0", + "@angular/localize": "^14.0.0", + "@angular/material": "^13.2.0", + "@angular/platform-browser": "^14.0.0", + "@angular/platform-browser-dynamic": "^14.0.0", + "@angular/platform-server": "^14.0.0", + "@angular/router": "^14.0.0", "@angularclass/hmr": "^3.0.0", - "@aspnet/signalr": "^1.1.0", + "@microsoft/signalr": "^6.0.7", "@auth0/angular-jwt": "^5.0.2", - "@fortawesome/fontawesome-free": "^5.15.4", + "@fortawesome/fontawesome-free": "^6.0.0", "@fullcalendar/core": "^4.2.0", "@fullcalendar/daygrid": "^4.4.0", "@fullcalendar/interaction": "^4.2.0", - "@ngu/carousel": "^3.0.2", - "@ngx-translate/core": "^13.0.0", - "@ngx-translate/http-loader": "^6.0.0", - "@ngxs/devtools-plugin": "^3.7.2", - "@ngxs/store": "^3.7.2", - "@types/jquery": "^3.3.29", - "@yellowspot/ng-truncate": "^1.4.0", - "angular-bootstrap-md": "^7.5.4", + "@ngx-translate/core": "^14.0.0", + "@ngx-translate/http-loader": "^7.0.0", + "@ngxs/devtools-plugin": "^3.7.3", + "@ngxs/store": "^3.7.3", + "@types/jquery": "^3.5.13", + "@yellowspot/ng-truncate": "^2.0.0", "angular-router-loader": "^0.8.5", - "angularx-qrcode": "^11.0.0", + "angularx-qrcode": "^13.0.3", "bootstrap": "^4.2.1", "chart.js": "2.9.4", "core-js": "^2.5.4", @@ -49,36 +51,51 @@ "moment": "^2.29.1", "ng2-cookies": "^1.0.12", "ngx-clipboard": "^12.1.0", - "ngx-infinite-scroll": "^9.0.0", + "ngx-infinite-scroll": "^14.0.0", "ngx-moment": "^3.0.1", - "ngx-order-pipe": "^2.1.1", - "please-wait": "^0.0.5", + "ngx-order-pipe": "^2.2.0", "popper.js": "^1.14.3", - "primeicons": "^4.1.0", - "primeng": "^12.2.0", - "rxjs": "^7.4.0", + "primeicons": "^5.0.0", + "primeng": "^13.2.0", + "rxjs": "^7.5.4", "sass-recursive-map-merge": "^1.0.1", - "spinkit": "^1.2.5", "store": "^2.0.12", "ts-md5": "^1.2.7", "tslib": "^1.10.0", "tslint-angular": "^1.1.2", - "zone.js": "~0.11.4" + "zone.js": "~0.11.4", + "protractor": "~5.4.0", + "ts-node": "~5.0.1", + "tslint": "^5.12.0" }, "devDependencies": { - "@angular-devkit/build-angular": "~12.2.10", - "@angular/cli": "~12.2.10", - "@angular/compiler-cli": "^12.2.10", - "@angular/language-service": "^12.2.10", + "@angular-devkit/build-angular": "^14.0.0", + "@angular/cli": "^14.0.0", + "@angular/compiler-cli": "^14.0.0", + "@angular/language-service": "^14.0.0", + "@babel/core": "^7.18.9", + "@compodoc/compodoc": "^1.1.19", + "@types/node": "^16.11.45", + "@storybook/addon-actions": "^6.5.9", + "@storybook/addon-essentials": "^6.5.9", + "@storybook/addon-interactions": "^6.5.9", + "@storybook/addon-links": "^6.5.9", + "@storybook/angular": "^6.5.9", + "@storybook/builder-webpack5": "^6.5.9", + "@storybook/manager-webpack5": "^6.5.9", + "@storybook/testing-library": "^0.0.13", "@types/jasmine": "~3.6.7", "@types/jasminewd2": "~2.0.8", - "@types/node": "^16.10.9", + "babel-loader": "^8.2.5", + "chromatic": "^6.7.1", "codelyzer": "^6.0.1", - "typescript": "~4.3.4" + "typescript": "~4.7.3" }, "optionalDependencies": { "protractor": "~5.4.0", "ts-node": "~5.0.1", "tslint": "^5.12.0" - } + }, + "readme": "ERROR: No README data found!", + "_id": "ombi@3.0.0" } diff --git a/src/Ombi/ClientApp/src/app/app.component.ts b/src/Ombi/ClientApp/src/app/app.component.ts index cbfcf0af0..720ec22a2 100644 --- a/src/Ombi/ClientApp/src/app/app.component.ts +++ b/src/Ombi/ClientApp/src/app/app.component.ts @@ -1,4 +1,4 @@ -import { OverlayContainer } from '@angular/cdk/overlay'; +import { OverlayContainer } from '@angular/cdk/overlay'; import { Component, OnInit, HostBinding, Inject } from "@angular/core"; import { NavigationStart, Router } from "@angular/router"; @@ -34,6 +34,7 @@ export class AppComponent implements OnInit { public userName: string; public userEmail: string; public accessToken: string; + public favicon: string; private hubConnected: boolean; @@ -50,9 +51,9 @@ export class AppComponent implements OnInit { private signalrNotification: SignalRNotificationService, private readonly snackBar: MatSnackBar, private readonly identity: IdentityService, - @Inject(DOCUMENT) private document: HTMLDocument) { + @Inject(DOCUMENT) private document: Document) { - this.translate.addLangs(["da", "de", "en", "es", "fr", "it", "hu", "nl", "no", "pl", "pt", "sk", "sv", "bg", "ru"]); + this.translate.addLangs(["da", "de", "en", "es", "fr", "it", "hu", "nl", "no", "pl", "pt", "sk", "sv", "bg", "ru", "cs", "zh"]); if (this.authService.loggedIn()) { this.identity.getAccessToken().subscribe(x => this.accessToken = x); @@ -80,7 +81,7 @@ export class AppComponent implements OnInit { // See if we can match the supported langs with the current browser lang const browserLang: string = translate.getBrowserLang(); - this.translate.use(browserLang.match(/da|de|en|es|fr|it|hu|nl|no|pl|pt|sk|sv|bg|ru/) ? browserLang : "en"); + this.translate.use(browserLang.match(/da|de|en|es|fr|it|hu|nl|no|pl|pt|sk|sv|bg|ru|cs|zh/) ? browserLang : "en"); } @@ -88,9 +89,15 @@ export class AppComponent implements OnInit { this.customizationFacade.settings$().subscribe(x => { this.customizationSettings = x; if (this.customizationSettings && this.customizationSettings.applicationName) { - this.applicationName = this.customizationSettings.applicationName; - this.document.getElementsByTagName('title')[0].innerText = this.applicationName; + this.applicationName = this.customizationSettings.applicationName; + this.document.getElementsByTagName('title')[0].innerText = this.applicationName; } + + if (this.customizationSettings && this.customizationSettings.favicon) { + this.favicon = this.customizationSettings.favicon; + this.document.getElementById('favicon').setAttribute('href', this.favicon); + } + if (this.customizationSettings && this.customizationSettings.customCss) { var dom = this.document.getElementsByTagName('head')[0]; var css = document.createElement("style"); diff --git a/src/Ombi/ClientApp/src/app/app.module.ts b/src/Ombi/ClientApp/src/app/app.module.ts index b4e78087c..24644d1df 100644 --- a/src/Ombi/ClientApp/src/app/app.module.ts +++ b/src/Ombi/ClientApp/src/app/app.module.ts @@ -1,5 +1,4 @@ import { APP_BASE_HREF, CommonModule, PlatformLocation } from "@angular/common"; -import { CardsFreeModule, MDBBootstrapModule, NavbarModule } from "angular-bootstrap-md"; import { CustomPageService, ImageService, RequestService, SettingsService } from "./services"; import { FormsModule, ReactiveFormsModule } from "@angular/forms"; import { HTTP_INTERCEPTORS, HttpClient, HttpClientModule } from "@angular/common/http"; @@ -21,6 +20,8 @@ import { CustomPageComponent } from "./custompage/custompage.component"; import { CustomizationState } from "./state/customization/customization.state"; import { DataViewModule } from "primeng/dataview"; import { DialogModule } from "primeng/dialog"; +import { FEATURES_INITIALIZER } from "./state/features/features-initializer"; +import { FeatureState } from "./state/features"; import { JwtModule } from "@auth0/angular-jwt"; import { LandingPageComponent } from "./landingpage/landingpage.component"; import { LandingPageService } from "./services"; @@ -38,6 +39,8 @@ import { MatInputModule } from "@angular/material/input"; import { MatListModule } from '@angular/material/list'; import { MatMenuModule } from "@angular/material/menu"; import { MatNativeDateModule } from '@angular/material/core'; +import { MatPaginatorI18n } from "./localization/MatPaginatorI18n"; +import { MatPaginatorIntl } from "@angular/material/paginator"; import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; import { MatSidenavModule } from '@angular/material/sidenav'; import { MatSlideToggleModule } from "@angular/material/slide-toggle"; @@ -63,7 +66,9 @@ import { StorageService } from "./shared/storage/storage-service"; import { TokenResetPasswordComponent } from "./login/tokenresetpassword.component"; import { TooltipModule } from "primeng/tooltip"; import { TranslateHttpLoader } from "@ngx-translate/http-loader"; +import { TranslateService } from "@ngx-translate/core"; import { UnauthorizedInterceptor } from "./auth/unauthorized.interceptor"; +import { ImageBackgroundComponent, ImageComponent } from "./components/"; import { environment } from "../environments/environment"; const routes: Routes = [ @@ -126,7 +131,6 @@ export function JwtTokenGetter() { MatSnackBarModule, DialogModule, MatButtonModule, - NavbarModule, MatCardModule, MatTooltipModule, MatMenuModule, @@ -140,11 +144,9 @@ export function JwtTokenGetter() { ConfirmDialogModule, OverlayPanelModule, CommonModule, - CardsFreeModule, OverlayModule, MatCheckboxModule, MatProgressSpinnerModule, - MDBBootstrapModule.forRoot(), JwtModule.forRoot({ config: { tokenGetter: JwtTokenGetter, @@ -159,13 +161,15 @@ export function JwtTokenGetter() { }), SidebarModule, MatNativeDateModule, MatIconModule, MatSidenavModule, MatListModule, MatToolbarModule, LayoutModule, MatSlideToggleModule, - NgxsModule.forRoot([CustomizationState], { + NgxsModule.forRoot([CustomizationState, FeatureState], { developmentMode: !environment.production, }), - ...environment.production ? [] : + ...environment.production ? [] : [ NgxsReduxDevtoolsPluginModule.forRoot(), - ] + ], + ImageBackgroundComponent, + ImageComponent, ], declarations: [ AppComponent, @@ -202,6 +206,7 @@ export function JwtTokenGetter() { StorageService, RequestService, SignalRNotificationService, + FEATURES_INITIALIZER, CUSTOMIZATION_INITIALIZER, { provide: APP_BASE_HREF, @@ -212,6 +217,10 @@ export function JwtTokenGetter() { useClass: UnauthorizedInterceptor, multi: true }, + { + provide: MatPaginatorIntl, deps: [TranslateService], + useFactory: (translateService: TranslateService) => new MatPaginatorI18n(translateService).getPaginatorIntl() + }, ], bootstrap: [AppComponent], }) diff --git a/src/Ombi/ClientApp/src/app/auth/auth.service.ts b/src/Ombi/ClientApp/src/app/auth/auth.service.ts index afc0a2491..ad1ff32ac 100644 --- a/src/Ombi/ClientApp/src/app/auth/auth.service.ts +++ b/src/Ombi/ClientApp/src/app/auth/auth.service.ts @@ -28,6 +28,10 @@ export class AuthService extends ServiceHelpers { return this.http.post(`${this.url}/requirePassword`, JSON.stringify(login), { headers: this.headers }); } + public headerAuth(): Observable { + return this.http.post(`${this.url}/header_auth`, {}, { headers: this.headers }); + } + public getToken() { return this.jwtHelperService.tokenGetter(); } diff --git a/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.html b/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.html new file mode 100644 index 000000000..97fff3671 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.html @@ -0,0 +1,6 @@ +
+ + +
{{name}}
+
\ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.scss b/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.scss new file mode 100644 index 000000000..177a22d01 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.scss @@ -0,0 +1,26 @@ +.login-gradient-bar{ + background: linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.6) 20.0%, rgba(0,0,0,0.6) 80.0%, transparent 60%),transparent; + height:100%; + width:100%; + position: absolute; +} + +.bg { + background-position: center center; + background-repeat: no-repeat; + background-attachment: fixed; + background-size: cover; + height: 100vh; + width: 100vw; + position: fixed; +} + +.poster-desc { + padding-left: 1%; + color: white; + height: 100vh; + width: 100vw; + display: flex; + justify-content: end; + flex-direction: column; +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.ts b/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.ts new file mode 100644 index 000000000..ebd228d85 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/components/image-background/image-background.component.ts @@ -0,0 +1,43 @@ +import { OmbiCommonModules } from "../modules"; +import { Component, OnDestroy, OnInit } from "@angular/core"; +import { DomSanitizer } from "@angular/platform-browser"; +import { BrowserAnimationsModule } from "@angular/platform-browser/animations"; +import { ImageService } from "../../services"; +import { fadeInOutAnimation } from "app/animations/fadeinout"; + +@Component({ + standalone: true, + selector: 'ombi-image-background', + templateUrl: './image-background.component.html', + styleUrls: ['./image-background.component.scss'], + imports: [...OmbiCommonModules, BrowserAnimationsModule], + providers: [ ImageService ], + animations: [ fadeInOutAnimation ], + }) + export class ImageBackgroundComponent implements OnInit, OnDestroy { + + public background: any; + public name: string; + private timer: NodeJS.Timer; + + constructor(private images: ImageService, private sanitizer: DomSanitizer) { } + + public ngOnDestroy(): void { + clearTimeout(this.timer); + } + + public ngOnInit(): void { + this.cycleBackground(); + + this.timer = setInterval(() => { + this.cycleBackground(); + }, 30000); + } + + private cycleBackground() { + this.images.getRandomBackgroundWithInfo().subscribe((x) => { + this.background = this.sanitizer.bypassSecurityTrustStyle("url(" + x.url + ")"); + this.name = x.name; + }); + } + } \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/components/image/image.component.html b/src/Ombi/ClientApp/src/app/components/image/image.component.html new file mode 100644 index 000000000..426dd1013 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/components/image/image.component.html @@ -0,0 +1 @@ + diff --git a/src/Ombi/ClientApp/src/app/components/image/image.component.stories.ts b/src/Ombi/ClientApp/src/app/components/image/image.component.stories.ts new file mode 100644 index 000000000..b6f7b21fc --- /dev/null +++ b/src/Ombi/ClientApp/src/app/components/image/image.component.stories.ts @@ -0,0 +1,73 @@ +// also exported from '@storybook/angular' if you can deal with breaking changes in 6.1 +import { APP_BASE_HREF } from '@angular/common'; +import { Story, Meta, moduleMetadata } from '@storybook/angular'; +import { RequestType } from '../../interfaces'; +import { ImageComponent } from './image.component'; + +// More on default export: https://storybook.js.org/docs/angular/writing-stories/introduction#default-export +export default { + title: 'Image Component', + component: ImageComponent, + decorators: [ + moduleMetadata({ + providers: [ + { + provide: APP_BASE_HREF, + useValue: "" + }, + ] + }) + ] +} as Meta; + +// More on component templates: https://storybook.js.org/docs/angular/writing-stories/introduction#using-args +const Template: Story = (args: ImageComponent) => ({ + props: args, +}); + +export const Primary = Template.bind({}); +// More on args: https://storybook.js.org/docs/angular/writing-stories/args +Primary.args = { + src: 'https://ombi.io/img/logo-orange-small.png', + type: RequestType.movie +}; + +export const ClassApplied = Template.bind({}); +ClassApplied.args = { + src: 'https://ombi.io/img/logo-orange-small.png', + type: RequestType.movie, + class: 'test-class' +}; + +export const StyleApplied = Template.bind({}); +StyleApplied.args = { + src: 'https://ombi.io/img/logo-orange-small.png', + type: RequestType.movie, + style: 'background-color: red;' +}; + +export const IdApplied = Template.bind({}); +IdApplied.args = { + src: 'https://ombi.io/img/logo-orange-small.png', + type: RequestType.movie, + id: 'testId123' +}; + +// export const InvalidMovieImage = Template.bind({}); +// InvalidMovieImage.args = { +// src: 'https://httpstat.us/429', +// type: RequestType.movie, +// id: 'testId123' +// }; + +// export const InvalidTvImage = Template.bind({}); +// InvalidTvImage.args = { +// src: 'https://httpstat.us/429', +// type: RequestType.tvShow, +// }; + +// export const InvalidMusicImage = Template.bind({}); +// InvalidMusicImage.args = { +// src: 'https://httpstat.us/429', +// type: RequestType.album, +// }; diff --git a/src/Ombi/ClientApp/src/app/components/image/image.component.ts b/src/Ombi/ClientApp/src/app/components/image/image.component.ts new file mode 100644 index 000000000..57099016a --- /dev/null +++ b/src/Ombi/ClientApp/src/app/components/image/image.component.ts @@ -0,0 +1,57 @@ +import { OmbiCommonModules } from "../modules"; +import { ChangeDetectionStrategy, Component, ElementRef, Inject, Input, ViewEncapsulation } from "@angular/core"; +import { RequestType } from "../../interfaces"; +import { APP_BASE_HREF } from "@angular/common"; + +@Component({ + standalone: true, + selector: 'ombi-image', + imports: [...OmbiCommonModules], + encapsulation: ViewEncapsulation.None, + changeDetection: ChangeDetectionStrategy.OnPush, + templateUrl: './image.component.html', + }) + export class ImageComponent { + + @Input() public src: string; + @Input() public type: RequestType; + + // Attributes from the parent + @Input() public class: string; + @Input() public id: string; + @Input() public alt: string; + @Input() public style: string; + + public baseUrl: string = ""; + + public defaultTv = "/images/default_tv_poster.png"; + private defaultMovie = "/images/default_movie_poster.png"; + private defaultMusic = "i/mages/default-music-placeholder.png"; + + constructor (@Inject(APP_BASE_HREF) public href: string) { + if (this.href.length > 1) { + this.baseUrl = this.href; + } + } + + public onError(event: any) { + // set to a placeholder + switch(this.type) { + case RequestType.movie: + event.target.src = this.baseUrl + this.defaultMovie; + break; + case RequestType.tvShow: + event.target.src = this.baseUrl + this.defaultTv; + break; + case RequestType.album: + event.target.src = this.baseUrl + this.defaultMusic; + break; + } + + // Retry the original image + const timeout = setTimeout(() => { + event.target.src = this.src; + clearTimeout(timeout); + }, Math.floor(Math.random() * (7000 - 1000 + 1)) + 1000); + } + } \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/components/index.ts b/src/Ombi/ClientApp/src/app/components/index.ts new file mode 100644 index 000000000..092f6504b --- /dev/null +++ b/src/Ombi/ClientApp/src/app/components/index.ts @@ -0,0 +1,2 @@ +export * from "./image-background/image-background.component"; +export * from "./image/image.component"; \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/components/modules.ts b/src/Ombi/ClientApp/src/app/components/modules.ts new file mode 100644 index 000000000..1bf5697e6 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/components/modules.ts @@ -0,0 +1,3 @@ +import { CommonModule } from "@angular/common"; + +export const OmbiCommonModules = [ CommonModule ]; \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/custompage/custompage.component.ts b/src/Ombi/ClientApp/src/app/custompage/custompage.component.ts index 61094e793..37e2dce77 100644 --- a/src/Ombi/ClientApp/src/app/custompage/custompage.component.ts +++ b/src/Ombi/ClientApp/src/app/custompage/custompage.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit, SecurityContext } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { DomSanitizer } from "@angular/platform-browser"; import { AuthService } from "../auth/auth.service"; import { CustomPageService, NotificationService } from "../services"; @@ -10,11 +10,11 @@ import { CustomPageService, NotificationService } from "../services"; }) export class CustomPageComponent implements OnInit { - public form: FormGroup; + public form: UntypedFormGroup; public isEditing: boolean; public isAdmin: boolean; - constructor(private auth: AuthService, private settings: CustomPageService, private fb: FormBuilder, + constructor(private auth: AuthService, private settings: CustomPageService, private fb: UntypedFormBuilder, private notificationService: NotificationService, private sanitizer: DomSanitizer) { } diff --git a/src/Ombi/ClientApp/src/app/discover/components/actor/discover-actor.component.html b/src/Ombi/ClientApp/src/app/discover/components/actor/discover-actor.component.html index a7f6a7847..87db00955 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/actor/discover-actor.component.html +++ b/src/Ombi/ClientApp/src/app/discover/components/actor/discover-actor.component.html @@ -1,11 +1,11 @@ -
+
- +
\ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/discover/components/actor/discover-actor.component.ts b/src/Ombi/ClientApp/src/app/discover/components/actor/discover-actor.component.ts index 8cdb90436..5c333522c 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/actor/discover-actor.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/actor/discover-actor.component.ts @@ -1,47 +1,57 @@ -import { Component } from "@angular/core"; +import { Component, OnInit } from "@angular/core"; import { ActivatedRoute } from "@angular/router"; import { SearchV2Service } from "../../../services"; -import { IActorCredits } from "../../../interfaces/ISearchTvResultV2"; +import { IActorCredits, IActorCast } from "../../../interfaces/ISearchTvResultV2"; import { IDiscoverCardResult } from "../../interfaces"; import { RequestType } from "../../../interfaces"; import { AuthService } from "../../../auth/auth.service"; +import { forkJoin } from "rxjs"; +import { FeaturesFacade } from "../../../state/features/features.facade"; @Component({ templateUrl: "./discover-actor.component.html", styleUrls: ["./discover-actor.component.scss"], }) -export class DiscoverActorComponent { +export class DiscoverActorComponent implements OnInit { public actorId: number; - public actorCredits: IActorCredits; public loadingFlag: boolean; public isAdmin: boolean; + public is4kEnabled = false; public discoverResults: IDiscoverCardResult[] = []; constructor(private searchService: SearchV2Service, private route: ActivatedRoute, - private auth: AuthService) { + private auth: AuthService, + private featureService: FeaturesFacade) { this.route.params.subscribe((params: any) => { this.actorId = params.actorId; - this.isAdmin = this.auth.isAdmin(); - this.loading(); - this.searchService.getMoviesByActor(this.actorId).subscribe(res => { - this.actorCredits = res; - this.createModel(); - }); + }); + } + ngOnInit() { + this.isAdmin = this.auth.isAdmin(); + this.is4kEnabled = this.featureService.is4kEnabled(); + this.discoverResults = []; + this.loading(); + + forkJoin([ + this.searchService.getMoviesByActor(this.actorId), + this.searchService.getTvByActor(this.actorId) + ]).subscribe(([movie, tv]) => { + this.pushDiscoverResults(movie.cast, RequestType.movie); + this.pushDiscoverResults(tv.cast, RequestType.tvShow); + this.finishLoading(); }); } - private createModel() { - this.finishLoading(); - this.discoverResults = []; - this.actorCredits.cast.forEach(m => { + pushDiscoverResults(cast: IActorCast[], type: RequestType) { + cast.forEach(m => { this.discoverResults.push({ available: false, posterPath: m.poster_path ? `https://image.tmdb.org/t/p/w300/${m.poster_path}` : "../../../images/default_movie_poster.png", requested: false, title: m.title, - type: RequestType.movie, + type: type, id: m.id, url: null, rating: 0, diff --git a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html index 5a6993e44..a479b5072 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html +++ b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.html @@ -2,15 +2,14 @@
-
+
{{ 'Common.' + RequestType[result.type] | translate }}
- {{getAvailbilityStatus()}} + {{getAvailabilityStatus()}}
- {{result.title}} +
-
- -
+ +
+ +
+ + + + + +
+
+ +
+ +
+
+ + +
-
\ No newline at end of file +
diff --git a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.scss b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.scss index 6bf6748bf..6a7911257 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.scss +++ b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.scss @@ -83,7 +83,7 @@ small { } -.image { +::ng-deep .image { border-radius: 10px; opacity: 1; display: block; @@ -201,31 +201,31 @@ small { margin-right:5px; } -.top-right.available span.indicator, span.indicator-text{ +.top-right span.indicator, span.indicator-text{ display:block; } +.top-right span.indicator:before{ + display: inline-block; +} .top-right.available span.indicator:before{ - display: inline-block; background-color: #1DE9B6; } -.top-right.approved span.indicator, span.indicator-text { - display: block; -} - .top-right.approved span.indicator:before{ - display: inline-block; - background-color: #ff5722; + background-color: #ffd740; } -.top-right.requested span.indicator, span.indicator-text { - display: block; +.top-right.denied span.indicator:before{ + background-color: #660202; +} + +.top-right.partly-available span.indicator:before{ + background-color: #ffd740; } .top-right.requested span.indicator:before{ - display: inline-block; - background-color: #ffd740; + background-color: #ff5722; } ::ng-deep a.poster-overlay{ @@ -292,4 +292,8 @@ a.poster-overlay:hover{ .btn-ombi{ background-color:#293a4c; +} + +::ng-deep .mat-menu-panel { + min-width: 190px !important; } \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts index 1bd2546bc..d5557c0b5 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/card/discover-card.component.ts @@ -1,14 +1,15 @@ -import { Component, OnInit, Input } from "@angular/core"; -import { IDiscoverCardResult } from "../../interfaces"; -import { RequestType } from "../../../interfaces"; +import { Component, Input, OnInit } from "@angular/core"; import { MessageService, RequestService, SearchV2Service } from "../../../services"; -import { TranslateService } from "@ngx-translate/core"; -import { MatDialog } from "@angular/material/dialog"; -import { ISearchTvResultV2 } from "../../../interfaces/ISearchTvResultV2"; -import { ISearchMovieResultV2 } from "../../../interfaces/ISearchMovieResultV2"; -import { EpisodeRequestComponent } from "../../../shared/episode-request/episode-request.component"; + import { AdminRequestDialogComponent } from "../../../shared/admin-request-dialog/admin-request-dialog.component"; import { DiscoverType } from "../carousel-list/carousel-list.component"; +import { EpisodeRequestComponent } from "../../../shared/episode-request/episode-request.component"; +import { IDiscoverCardResult } from "../../interfaces"; +import { ISearchMovieResultV2 } from "../../../interfaces/ISearchMovieResultV2"; +import { ISearchTvResultV2 } from "../../../interfaces/ISearchTvResultV2"; +import { MatDialog } from "@angular/material/dialog"; +import { RequestType } from "../../../interfaces"; +import { TranslateService } from "@ngx-translate/core"; @Component({ selector: "discover-card", @@ -20,10 +21,12 @@ export class DiscoverCardComponent implements OnInit { @Input() public discoverType: DiscoverType; @Input() public result: IDiscoverCardResult; @Input() public isAdmin: boolean; + @Input() public is4kEnabled: boolean = false; public RequestType = RequestType; public hide: boolean; public fullyLoaded = false; public loading: boolean; + public allow4KButton: boolean = false; public requestable: boolean; @@ -39,6 +42,7 @@ export class DiscoverCardComponent implements OnInit { this.getExtraTvInfo(); } if (this.result.type == RequestType.movie) { + this.allow4KButton = true; this.getExtraMovieInfo(); } if (this.result.type == RequestType.album) { @@ -88,29 +92,41 @@ export class DiscoverCardComponent implements OnInit { if (this.result.available) { return "available"; } + if (this.tvSearchResult?.partlyAvailable) { + return "partly-available"; + } if (this.result.approved) { return "approved"; } + if (this.result.denied) { + return "denied"; + } if (this.result.requested) { return "requested"; } return ""; } - public getAvailbilityStatus(): string { + public getAvailabilityStatus(): string { if (this.result.available) { return this.translate.instant("Common.Available"); } + if (this.tvSearchResult?.partlyAvailable) { + return this.translate.instant("Common.PartlyAvailable"); + } if (this.result.approved) { return this.translate.instant("Common.Approved"); } + if (this.result.denied) { + return this.translate.instant("Common.Denied"); + } if (this.result.requested) { return this.translate.instant("Common.Pending"); } return ""; } - public request(event: any) { + public request(event: any, is4k: boolean) { event.preventDefault(); this.loading = true; switch (this.result.type) { @@ -120,14 +136,15 @@ export class DiscoverCardComponent implements OnInit { return; case RequestType.movie: if (this.isAdmin) { - const dialog = this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.movie, id: this.result.id }, panelClass: 'modal-panel' }); + const dialog = this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.movie, id: this.result.id, }, panelClass: 'modal-panel' }); dialog.afterClosed().subscribe((result) => { if (result) { this.requestService.requestMovie({ theMovieDbId: +this.result.id, languageCode: this.translate.currentLang, qualityPathOverride: result.radarrPathId, requestOnBehalf: result.username?.id, - rootFolderOverride: result.radarrFolderId, }).subscribe(x => { + rootFolderOverride: result.radarrFolderId, + is4KRequest: is4k }).subscribe(x => { if (x.result) { this.result.requested = true; this.messageService.send(this.translate.instant("Requests.RequestAddedSuccessfully", { title: this.result.title }), "Ok"); @@ -138,7 +155,7 @@ export class DiscoverCardComponent implements OnInit { } }); } else { - this.requestService.requestMovie({ theMovieDbId: +this.result.id, languageCode: this.translate.currentLang, requestOnBehalf: null, qualityPathOverride: null, rootFolderOverride: null }).subscribe(x => { + this.requestService.requestMovie({ theMovieDbId: +this.result.id, languageCode: this.translate.currentLang, requestOnBehalf: null, qualityPathOverride: null, rootFolderOverride: null, is4KRequest: is4k }).subscribe(x => { if (x.result) { this.result.requested = true; this.messageService.send(this.translate.instant("Requests.RequestAddedSuccessfully", { title: this.result.title }), "Ok"); @@ -152,6 +169,19 @@ export class DiscoverCardComponent implements OnInit { } } + public onImageError(event: any) { + const originalSrc = event.target.src; + + // set to a placeholder + event.target.src = "../../../images/default_movie_poster.png"; + + // Retry the original image + const timeout = setTimeout(() => { + event.target.src = originalSrc; + clearTimeout(timeout); + }, Math.floor(Math.random() * (7000 - 1000 + 1)) + 1000); + } + private getExtraMovieInfo() { if (!this.result.imdbid) { this.searchService.getFullMovieDetails(+this.result.id) @@ -166,8 +196,10 @@ export class DiscoverCardComponent implements OnInit { private updateMovieItem(updated: ISearchMovieResultV2) { this.result.url = "http://www.imdb.com/title/" + updated.imdbId + "/"; - this.result.available = updated.available; - this.result.requested = updated.requested; + this.result.available = updated.available || updated.available4K; + this.result.requested = updated.requested || updated.has4KRequest; + this.result.approved = updated.approved || updated.available4K; + this.result.denied = updated.denied || updated.denied4K; this.result.rating = updated.voteAverage; this.result.overview = updated.overview; this.result.imdbid = updated.imdbId; @@ -194,6 +226,7 @@ export class DiscoverCardComponent implements OnInit { this.result.overview = updated.overview; this.result.approved = updated.approved; this.result.available = updated.fullyAvailable; + this.result.denied = updated.denied; this.fullyLoaded = true; } diff --git a/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.html b/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.html index aa9ffc5f2..5be2aa1ad 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.html +++ b/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.html @@ -8,6 +8,6 @@ - + \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts b/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts index a00146ad5..43cde5036 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/carousel-list/carousel-list.component.ts @@ -5,6 +5,7 @@ import { SearchV2Service } from "../../../services"; import { StorageService } from "../../../shared/storage/storage-service"; import { MatButtonToggleChange } from '@angular/material/button-toggle'; import { Carousel } from 'primeng/carousel'; +import { FeaturesFacade } from "../../../state/features/features.facade"; export enum DiscoverType { Upcoming, @@ -36,6 +37,7 @@ export class CarouselListComponent implements OnInit { public RequestType = RequestType; public loadingFlag: boolean; public DiscoverType = DiscoverType; + public is4kEnabled = false; get mediaTypeStorageKey() { return "DiscoverOptions" + this.discoverType.toString(); @@ -44,7 +46,9 @@ export class CarouselListComponent implements OnInit { private currentlyLoaded = 0; constructor(private searchService: SearchV2Service, - private storageService: StorageService) { + private storageService: StorageService, + private featureFacade: FeaturesFacade) { + Carousel.prototype.onTouchMove = () => { }, this.responsiveOptions = [ { breakpoint: '4000px', @@ -135,6 +139,7 @@ export class CarouselListComponent implements OnInit { } public async ngOnInit() { + this.is4kEnabled = this.featureFacade.is4kEnabled(); this.currentlyLoaded = 0; const localDiscoverOptions = +this.storageService.get(this.mediaTypeStorageKey); if (localDiscoverOptions) { diff --git a/src/Ombi/ClientApp/src/app/discover/components/collections/discover-collections.component.html b/src/Ombi/ClientApp/src/app/discover/components/collections/discover-collections.component.html index 23a7791f0..0750a12c0 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/collections/discover-collections.component.html +++ b/src/Ombi/ClientApp/src/app/discover/components/collections/discover-collections.component.html @@ -16,7 +16,7 @@
- +
\ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/discover/components/collections/discover-collections.component.ts b/src/Ombi/ClientApp/src/app/discover/components/collections/discover-collections.component.ts index 9e84ea7d0..d643c52af 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/collections/discover-collections.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/collections/discover-collections.component.ts @@ -8,6 +8,7 @@ import { IDiscoverCardResult } from "../../interfaces"; import { IMovieCollectionsViewModel } from "../../../interfaces/ISearchTvResultV2"; import { RequestServiceV2 } from "../../../services/requestV2.service"; import { RequestType } from "../../../interfaces"; +import { FeaturesFacade } from "../../../state/features/features.facade"; @Component({ templateUrl: "./discover-collections.component.html", @@ -19,6 +20,7 @@ export class DiscoverCollectionsComponent implements OnInit { public collection: IMovieCollectionsViewModel; public loadingFlag: boolean; public isAdmin: boolean; + public is4kEnabled = false; public discoverResults: IDiscoverCardResult[] = []; @@ -27,13 +29,15 @@ export class DiscoverCollectionsComponent implements OnInit { private requestServiceV2: RequestServiceV2, private messageService: MessageService, private auth: AuthService, - private translate: TranslateService) { + private translate: TranslateService, + private featureFacade: FeaturesFacade) { this.route.params.subscribe((params: any) => { this.collectionId = params.collectionId; }); } public async ngOnInit() { + this.is4kEnabled = this.featureFacade.is4kEnabled(); this.loadingFlag = true; this.isAdmin = this.auth.isAdmin(); this.collection = await this.searchService.getMovieCollections(this.collectionId); diff --git a/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.html b/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.html index 4ef9255fb..97ff038a0 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.html +++ b/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.html @@ -2,9 +2,15 @@
-
+ +
- +
diff --git a/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.ts b/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.ts index f0258b97d..295902927 100644 --- a/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.ts +++ b/src/Ombi/ClientApp/src/app/discover/components/search-results/search-results.component.ts @@ -10,6 +10,7 @@ import { SearchFilter } from "../../../my-nav/SearchFilter"; import { SearchV2Service } from "../../../services"; import { StorageService } from "../../../shared/storage/storage-service"; import { isEqual } from "lodash"; +import { FeaturesFacade } from "../../../state/features/features.facade"; @Component({ templateUrl: "./search-results.component.html", @@ -21,12 +22,14 @@ export class DiscoverSearchResultsComponent implements OnInit { public searchTerm: string; public results: IMultiSearchResult[]; public isAdmin: boolean; + public is4kEnabled = false; public discoverResults: IDiscoverCardResult[] = []; public filter: SearchFilter; private isAdvancedSearch: boolean; + private loadPosition: number = 30; constructor(private searchService: SearchV2Service, private route: ActivatedRoute, @@ -34,7 +37,8 @@ export class DiscoverSearchResultsComponent implements OnInit { private router: Router, private advancedDataService: AdvancedSearchDialogDataService, private store: StorageService, - private authService: AuthService) { + private authService: AuthService, + private featureFacade: FeaturesFacade) { this.route.params.subscribe((params: any) => { this.isAdvancedSearch = this.router.url === '/discover/advanced/search'; if (this.isAdvancedSearch) { @@ -53,6 +57,7 @@ export class DiscoverSearchResultsComponent implements OnInit { } public async ngOnInit() { + this.is4kEnabled = this.featureFacade.is4kEnabled(); this.isAdmin = this.authService.isAdmin(); this.filterService.onFilterChange.subscribe(async x => { if (!isEqual(this.filter, x)) { @@ -61,7 +66,7 @@ export class DiscoverSearchResultsComponent implements OnInit { } }); - if (this.advancedDataService) { + if (this.isAdvancedSearch) { return; } this.loadingFlag = true; @@ -175,6 +180,31 @@ export class DiscoverSearchResultsComponent implements OnInit { }); } + public onScroll() { + console.log("scrolled"); + if (this.advancedDataService) { + this.loadMoreAdvancedSearch(); + return; + } + } + + private loadMoreAdvancedSearch() { + const advancedOptions = this.advancedDataService.getOptions(); + + this.searchService.advancedSearch({ + type: advancedOptions.type == RequestType.movie ? "movie" : "tv", + companies: advancedOptions.companies, + genreIds: advancedOptions.genres, + keywordIds : advancedOptions.keywords, + releaseYear: advancedOptions.releaseYear, + watchProviders: advancedOptions.watchProviders, + }, this.loadPosition, 30).then(x => { + + this.loadPosition += 30; + this.mapAdvancedData(x); + }); + } + private async search() { this.clear(); this.results = await this.searchService diff --git a/src/Ombi/ClientApp/src/app/discover/discover.module.ts b/src/Ombi/ClientApp/src/app/discover/discover.module.ts index 414c881e6..eade4e451 100644 --- a/src/Ombi/ClientApp/src/app/discover/discover.module.ts +++ b/src/Ombi/ClientApp/src/app/discover/discover.module.ts @@ -8,6 +8,7 @@ import { PipeModule } from "../pipes/pipe.module"; import { RouterModule } from "@angular/router"; import { SharedModule } from "../shared/shared.module"; import { SkeletonModule } from 'primeng/skeleton'; +import { ImageComponent } from 'app/components'; @NgModule({ imports: [ @@ -18,6 +19,7 @@ import { SkeletonModule } from 'primeng/skeleton'; MatButtonToggleModule, InfiniteScrollModule, SkeletonModule, + ImageComponent ], declarations: [ ...fromComponents.components diff --git a/src/Ombi/ClientApp/src/app/errors/not-found.component.ts b/src/Ombi/ClientApp/src/app/errors/not-found.component.ts index f102d0449..25269ecd1 100644 --- a/src/Ombi/ClientApp/src/app/errors/not-found.component.ts +++ b/src/Ombi/ClientApp/src/app/errors/not-found.component.ts @@ -1,6 +1,6 @@ import { Component } from "@angular/core"; @Component({ - template: "

Page not found

", + template: "

{{ 'ErrorPages.NotFound' | translate }}

", }) export class PageNotFoundComponent { } diff --git a/src/Ombi/ClientApp/src/app/interfaces/IImages.ts b/src/Ombi/ClientApp/src/app/interfaces/IImages.ts index 0c73df490..baa1a9829 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/IImages.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/IImages.ts @@ -1,3 +1,7 @@ export interface IImages { url: string; } +export interface IImagesInfo { + url: string; + name: string; +} diff --git a/src/Ombi/ClientApp/src/app/interfaces/IIssues.ts b/src/Ombi/ClientApp/src/app/interfaces/IIssues.ts index 10de2a596..aac30c1e4 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/IIssues.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/IIssues.ts @@ -14,6 +14,7 @@ export interface IIssues { comments: IIssueComments[]; requestId: number | undefined; userReported: IUser | undefined; + posterPath: string; } export enum IssueStatus { diff --git a/src/Ombi/ClientApp/src/app/interfaces/IMovieDb.ts b/src/Ombi/ClientApp/src/app/interfaces/IMovieDb.ts index f82225434..77352de4b 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/IMovieDb.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/IMovieDb.ts @@ -17,3 +17,8 @@ export interface IDiscoverModel { watchProviders?: number[]; companies?: number[]; } +export interface ILanguage { + iso_639_1 : string; + english_name : string; + name : string; +} diff --git a/src/Ombi/ClientApp/src/app/interfaces/INotificationSettings.ts b/src/Ombi/ClientApp/src/app/interfaces/INotificationSettings.ts index f2efc3f6f..460a970fe 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/INotificationSettings.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/INotificationSettings.ts @@ -12,7 +12,6 @@ export interface IEmailNotificationSettings extends INotificationSettings { senderName: string; username: string; authentication: boolean; - adminEmail: string; disableTLS: boolean; disableCertificateChecking: boolean; notificationTemplates: INotificationTemplates[]; diff --git a/src/Ombi/ClientApp/src/app/interfaces/IRequestModel.ts b/src/Ombi/ClientApp/src/app/interfaces/IRequestModel.ts index 440e0d5b2..36b75adb6 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/IRequestModel.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/IRequestModel.ts @@ -16,6 +16,13 @@ export interface IMovieRequests extends IFullBaseRequest { subscribed: boolean; showSubscribe: boolean; requestStatus: string; + has4KRequest: boolean; + approved4K: boolean; + available4K: boolean; + denied4K: boolean; + deniedReason4K: string; + requestedDate4k: Date; + requestedDate: Date; // For the UI rootPathOverrideTitle: string; @@ -53,6 +60,7 @@ export interface IRequestsViewModel { export interface IMovieUpdateModel { id: number; + is4K: boolean; } export interface IDenyMovieModel extends IMovieUpdateModel { @@ -96,6 +104,13 @@ export interface IBaseRequest { canApprove: boolean; title: string; requestedByAlias: string; + source: RequestSource; +} + +export enum RequestSource +{ + Ombi = 0, + PlexWatchlist = 1 } export interface ITvRequests { @@ -176,6 +191,7 @@ export interface IEpisodesRequests { export interface IMovieRequestModel extends BaseRequestOptions { theMovieDbId: number; languageCode: string | undefined; + is4KRequest?: boolean; } export interface IFilter { diff --git a/src/Ombi/ClientApp/src/app/interfaces/ISearchMovieResultV2.ts b/src/Ombi/ClientApp/src/app/interfaces/ISearchMovieResultV2.ts index da4b27f32..937234c42 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/ISearchMovieResultV2.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/ISearchMovieResultV2.ts @@ -23,6 +23,8 @@ homepage: string; imdbId: string; approved: boolean; + denied: boolean; + deniedReason: string; requested: boolean; requestId: number; available: boolean; @@ -42,6 +44,11 @@ externalIds: IExternalIds; keywords: IKeywords; belongsToCollection: ICollectionsModel; + has4KRequest: boolean; + approved4K: boolean; + available4K: boolean; + denied4K: boolean; + deniedReason4K: string; // for the UI requestProcessing: boolean; diff --git a/src/Ombi/ClientApp/src/app/interfaces/ISearchTvResultV2.ts b/src/Ombi/ClientApp/src/app/interfaces/ISearchTvResultV2.ts index 8ea7bacc5..78958a02e 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/ISearchTvResultV2.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/ISearchTvResultV2.ts @@ -25,6 +25,8 @@ export interface ISearchTvResultV2 { seasonRequests: INewSeasonRequests[]; requestAll: boolean; approved: boolean; + denied: boolean; + deniedReason: string; requested: boolean; available: boolean; plexUrl: string; diff --git a/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts b/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts index 919e6a271..4594d2a2f 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/ISettings.ts @@ -1,4 +1,4 @@ -import { ISettings } from "./ICommon"; +import { ISettings } from "./ICommon"; import { RequestLimitType } from "."; export interface IExternalSettings extends ISettings { @@ -112,6 +112,7 @@ export interface IPublicInfo { export interface IPlexSettings extends ISettings { enable: boolean; + enableWatchlistImport: boolean; servers: IPlexServer[]; } @@ -158,6 +159,11 @@ export interface IRadarrSettings extends IExternalSettings { scanForAvailability: boolean; } +export interface IRadarrCombined { + radarr: IRadarrSettings; + radarr4K: IRadarrSettings; +} + export interface ILidarrSettings extends IExternalSettings { enabled: boolean; apiKey: string; @@ -193,6 +199,7 @@ export interface ICustomizationSettings extends ISettings { recentlyAddedPage: boolean; useCustomPage: boolean; hideAvailableFromDiscover: boolean; + favicon: string; } export interface IJobSettings { @@ -212,6 +219,8 @@ export interface IJobSettings { retryRequests: string; mediaDatabaseRefresh: string; autoDeleteRequests: string; + embyRecentlyAddedSync: string; + plexWatchlistImport: string; } export interface IIssueSettings extends ISettings { @@ -231,6 +240,8 @@ export interface IAuthenticationSettings extends ISettings { requireNonAlphanumeric: boolean; requireUppercase: boolean; enableOAuth: boolean; + enableHeaderAuth: boolean; + headerAuthVariable: string; } export interface ICustomPage extends ISettings { @@ -328,7 +339,8 @@ export interface ITheMovieDbSettings extends ISettings { showAdultMovies: boolean; excludedKeywordIds: number[]; excludedMovieGenreIds: number[]; - excludedTvGenreIds: number[] + excludedTvGenreIds: number[]; + originalLanguages: string[]; } export interface IUpdateModel diff --git a/src/Ombi/ClientApp/src/app/interfaces/IUser.ts b/src/Ombi/ClientApp/src/app/interfaces/IUser.ts index 2db5a5de2..069b1e506 100644 --- a/src/Ombi/ClientApp/src/app/interfaces/IUser.ts +++ b/src/Ombi/ClientApp/src/app/interfaces/IUser.ts @@ -121,6 +121,7 @@ export interface IMassEmailModel { subject: string; body: string; users: IUser[]; + bcc: boolean; } export interface INotificationPreferences { @@ -145,3 +146,8 @@ export enum INotificationAgent { Webhook = 9, WhatsApp = 10 } + +export interface IFeatureEnablement { + name: string; + enabled: boolean; +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/issues/components/details-group/details-group.component.html b/src/Ombi/ClientApp/src/app/issues/components/details-group/details-group.component.html index 01ddaf75e..74cc041d3 100644 --- a/src/Ombi/ClientApp/src/app/issues/components/details-group/details-group.component.html +++ b/src/Ombi/ClientApp/src/app/issues/components/details-group/details-group.component.html @@ -2,6 +2,7 @@ {{issue.subject}} {{'Issues.UserOnDate' | translate: { user: issue.userReported?.userName, date: issue.createdDate | amLocal | amUserLocale | amDateFormat: 'LL' } }} + {{issue.issueCategory.value}}

@@ -10,8 +11,8 @@ -

here is ignored
- +
+ diff --git a/src/Ombi/ClientApp/src/app/issues/components/details/details.component.html b/src/Ombi/ClientApp/src/app/issues/components/details/details.component.html index bc0e8a794..42a84171b 100644 --- a/src/Ombi/ClientApp/src/app/issues/components/details/details.component.html +++ b/src/Ombi/ClientApp/src/app/issues/components/details/details.component.html @@ -1,6 +1,6 @@
-

Issues for {{details.title}}

+

{{ 'Issues.IssuesForTitle' | translate: { title: details.title} }}

{{'Issues.Requested' | translate}} diff --git a/src/Ombi/ClientApp/src/app/issues/components/details/details.component.scss b/src/Ombi/ClientApp/src/app/issues/components/details/details.component.scss index d6dcd67de..77d4223ab 100644 --- a/src/Ombi/ClientApp/src/app/issues/components/details/details.component.scss +++ b/src/Ombi/ClientApp/src/app/issues/components/details/details.component.scss @@ -1,9 +1,5 @@ @import "~styles/variables.scss"; -::ng-deep .mat-card { - background: $ombi-background-primary-accent; -} - .top-spacing { margin-top:2%; } \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/issues/components/details/details.component.ts b/src/Ombi/ClientApp/src/app/issues/components/details/details.component.ts index 4003acd40..12ceb422e 100644 --- a/src/Ombi/ClientApp/src/app/issues/components/details/details.component.ts +++ b/src/Ombi/ClientApp/src/app/issues/components/details/details.component.ts @@ -1,13 +1,13 @@ -import { Component, Inject, OnInit, ViewEncapsulation } from "@angular/core"; -import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '@angular/material/dialog'; import { ActivatedRoute, ActivatedRouteSnapshot, Router } from "@angular/router"; -import { TranslateService } from "@ngx-translate/core"; -import { AuthService } from "../../../auth/auth.service"; -import { IIssues, IIssueSettings, IIssuesSummary, IssueStatus, RequestType } from "../../../interfaces"; +import { Component, Inject, OnInit, ViewEncapsulation } from "@angular/core"; +import { IIssueSettings, IIssues, IIssuesSummary, IssueStatus, RequestType } from "../../../interfaces"; import { IssuesService, NotificationService, SettingsService } from "../../../services"; -import { IssuesV2Service } from "../../../services/issuesv2.service"; -import { IssueChatComponent } from "../issue-chat/issue-chat.component"; +import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; +import { AuthService } from "../../../auth/auth.service"; +import { IssueChatComponent } from "../issue-chat/issue-chat.component"; +import { IssuesV2Service } from "../../../services/issuesv2.service"; +import { TranslateService } from "@ngx-translate/core"; export interface IssuesDetailsGroupData { issues: IIssues[]; @@ -77,15 +77,15 @@ export class IssuesDetailsComponent implements OnInit { const firstIssue = this.details.issues[0]; switch(firstIssue.requestType) { case RequestType.movie: - this.router.navigate(['/details/movie/', firstIssue.providerId]); + this.router.navigate(['/details/movie/', this.providerId]); return; case RequestType.album: - this.router.navigate(['/details/artist/', firstIssue.providerId]); + this.router.navigate(['/details/artist/', this.providerId]); return; case RequestType.tvShow: - this.router.navigate(['/details/tv/', firstIssue.providerId]); + this.router.navigate(['/details/tv/', this.providerId]); return; } } diff --git a/src/Ombi/ClientApp/src/app/issues/issueDetails.component.ts b/src/Ombi/ClientApp/src/app/issues/issueDetails.component.ts index 1e30f932c..70eb69aee 100644 --- a/src/Ombi/ClientApp/src/app/issues/issueDetails.component.ts +++ b/src/Ombi/ClientApp/src/app/issues/issueDetails.component.ts @@ -70,6 +70,7 @@ export class IssueDetailsComponent implements OnInit { requestId: x.requestId, providerId: x.providerId, userReported: x.userReported, + posterPath: undefined, // Poster Path is not stored in the db, will always be undefined }; this.setBackground(x); }); diff --git a/src/Ombi/ClientApp/src/app/issues/issuestable.component.html b/src/Ombi/ClientApp/src/app/issues/issuestable.component.html index 8e22d3e51..99b297b60 100644 --- a/src/Ombi/ClientApp/src/app/issues/issuestable.component.html +++ b/src/Ombi/ClientApp/src/app/issues/issuestable.component.html @@ -14,7 +14,7 @@
diff --git a/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.html b/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.html index abad6473f..3b8a46db7 100644 --- a/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.html +++ b/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.html @@ -1,5 +1,5 @@ -
-
+
+
diff --git a/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.scss b/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.scss index 7eb4a4b3c..4c6e7ea9a 100644 --- a/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.scss +++ b/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.scss @@ -26,15 +26,6 @@ div.centered { transform: translate(-50%, -50%); } -div.bg { - background-position: center center; - background-repeat: no-repeat; - background-attachment: fixed; - background-size: cover; - height: 100vh; - width: 100vw; - position: fixed; -} .online{ color:lightgreen; diff --git a/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.ts b/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.ts index 33f8873f8..e2758b146 100644 --- a/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.ts +++ b/src/Ombi/ClientApp/src/app/landingpage/landingpage.component.ts @@ -1,48 +1,34 @@ -import { PlatformLocation, APP_BASE_HREF } from "@angular/common"; -import { Component, OnDestroy, OnInit, Inject } from "@angular/core"; +import { APP_BASE_HREF } from "@angular/common"; +import { Component, OnInit, Inject } from "@angular/core"; import { IMediaServerStatus } from "../interfaces"; import { ICustomizationSettings, ILandingPageSettings } from "../interfaces"; import { LandingPageService } from "../services"; import { SettingsService } from "../services"; -import { DomSanitizer } from "@angular/platform-browser"; -import { ImageService } from "../services"; - -import { fadeInOutAnimation } from "../animations/fadeinout"; import { CustomizationFacade } from "../state/customization"; -import { ThousandShortPipe } from "../pipes/ThousandShortPipe"; @Component({ templateUrl: "./landingpage.component.html", - animations: [fadeInOutAnimation], styleUrls: ["./landingpage.component.scss"], }) -export class LandingPageComponent implements OnDestroy, OnInit { +export class LandingPageComponent implements OnInit { public customizationSettings: ICustomizationSettings; public landingPageSettings: ILandingPageSettings; - public background: any; public mediaServerStatus: IMediaServerStatus; public baseUrl: string; - private timer: any; private href: string; constructor(private settingsService: SettingsService, - private images: ImageService, private sanitizer: DomSanitizer, private landingPageService: LandingPageService, + private landingPageService: LandingPageService, private customizationFacade: CustomizationFacade, @Inject(APP_BASE_HREF) href :string) { this.href = href } public ngOnInit() { this.customizationFacade.settings$().subscribe(x => this.customizationSettings = x); this.settingsService.getLandingPage().subscribe(x => this.landingPageSettings = x); - this.images.getRandomBackground().subscribe(x => { - this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 19%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 79%, transparent 80%), url(" + x.url + ")"); - }); - this.timer = setInterval(() => { - this.cycleBackground(); - }, 30000); const base = this.href; if (base.length > 1) { @@ -53,18 +39,4 @@ export class LandingPageComponent implements OnDestroy, OnInit { this.mediaServerStatus = x; }); } - - public ngOnDestroy() { - clearInterval(this.timer); - } - - public cycleBackground() { - this.images.getRandomBackground().subscribe(x => { - this.background = ""; - }); - this.images.getRandomBackground().subscribe(x => { - this.background = this.sanitizer - .bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 80.0%, transparent 80%), url(" + x.url + ")"); - }); - } } diff --git a/src/Ombi/ClientApp/src/app/localization/MatPaginatorI18n.ts b/src/Ombi/ClientApp/src/app/localization/MatPaginatorI18n.ts new file mode 100644 index 000000000..71a86b7bd --- /dev/null +++ b/src/Ombi/ClientApp/src/app/localization/MatPaginatorI18n.ts @@ -0,0 +1,34 @@ +import { MatPaginatorIntl } from '@angular/material/paginator'; +import { TranslateService } from '@ngx-translate/core'; + +export class MatPaginatorI18n { + + constructor(private translate: TranslateService) { } + + getPaginatorIntl(): MatPaginatorIntl { + const paginatorIntl = new MatPaginatorIntl(); + paginatorIntl.itemsPerPageLabel = this.translate.instant('Paginator.itemsPerPageLabel'); + paginatorIntl.nextPageLabel = this.translate.instant('Paginator.nextPageLabel'); + paginatorIntl.previousPageLabel = this.translate.instant('Paginator.previousPageLabel'); + paginatorIntl.firstPageLabel = this.translate.instant('Paginator.firstPageLabel'); + paginatorIntl.lastPageLabel = this.translate.instant('Paginator.lastPageLabel'); + paginatorIntl.getRangeLabel = this.getRangeLabel.bind(this); + return paginatorIntl; + } + + private getRangeLabel(page: number, pageSize: number, length: number): string { + if (length == 0 || pageSize == 0) { + return this.translate.instant('Paginator.rangePageLabel1', { length }); + } + + length = Math.max(length, 0); + + const startIndex = page * pageSize; + + // If the start index exceeds the list length, do not try and fix the end index to the end. + const endIndex = + startIndex < length ? Math.min(startIndex + pageSize, length) : startIndex + pageSize; + + return this.translate.instant('Paginator.rangePageLabel2', { startIndex: startIndex + 1, endIndex, length }); + } +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/login/login.component.html b/src/Ombi/ClientApp/src/app/login/login.component.html index c0932999b..71caa80b4 100644 --- a/src/Ombi/ClientApp/src/app/login/login.component.html +++ b/src/Ombi/ClientApp/src/app/login/login.component.html @@ -1,7 +1,4 @@ -
- -
+
diff --git a/src/Ombi/ClientApp/src/app/login/login.component.scss b/src/Ombi/ClientApp/src/app/login/login.component.scss index 4ad645dd8..df368ee0c 100644 --- a/src/Ombi/ClientApp/src/app/login/login.component.scss +++ b/src/Ombi/ClientApp/src/app/login/login.component.scss @@ -11,23 +11,6 @@ img.center { max-width: 100%; } -.login-gradient-bar{ - background: linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.6) 20.0%, rgba(0,0,0,0.6) 80.0%, transparent 60%),transparent; - height:100%; - width:100%; - position: absolute; -} - -div.bg { - background-position: center center; - background-repeat: no-repeat; - background-attachment: fixed; - background-size: cover; - height: 100vh; - width: 100vw; - position: fixed; -} - .card-container.card { max-width: 500px; padding: 45px 45px; diff --git a/src/Ombi/ClientApp/src/app/login/login.component.ts b/src/Ombi/ClientApp/src/app/login/login.component.ts index 592758c9f..6e8efc00b 100644 --- a/src/Ombi/ClientApp/src/app/login/login.component.ts +++ b/src/Ombi/ClientApp/src/app/login/login.component.ts @@ -1,5 +1,5 @@ -import { Component, OnDestroy, OnInit, Inject } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { Component, OnDestroy, OnInit, Inject } from "@angular/core"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { ActivatedRoute, Router } from "@angular/router"; import { TranslateService } from "@ngx-translate/core"; @@ -10,25 +10,19 @@ import { PlexTvService } from "../services"; import { SettingsService } from "../services"; import { StatusService } from "../services"; -import { DomSanitizer } from "@angular/platform-browser"; -import { ImageService } from "../services"; - -import { fadeInOutAnimation } from "../animations/fadeinout"; import { StorageService } from "../shared/storage/storage-service"; import { MatSnackBar } from "@angular/material/snack-bar"; import { CustomizationFacade } from "../state/customization"; @Component({ templateUrl: "./login.component.html", - animations: [fadeInOutAnimation], styleUrls: ["./login.component.scss"], }) export class LoginComponent implements OnDestroy, OnInit { - public form: FormGroup; + public form: UntypedFormGroup; public customizationSettings: ICustomizationSettings; public authenticationSettings: IAuthenticationSettings; public plexEnabled: boolean; - public background: any; public landingFlag: boolean; public baseUrl: string; public loginWithOmbi: boolean; @@ -46,7 +40,6 @@ export class LoginComponent implements OnDestroy, OnInit { public get appNameTranslate(): object { return { appName: this.appName }; } - private timer: any; private clientId: string; private errorBody: string; @@ -59,11 +52,9 @@ export class LoginComponent implements OnDestroy, OnInit { private authService: AuthService, private router: Router, private status: StatusService, - private fb: FormBuilder, + private fb: UntypedFormBuilder, private settingsService: SettingsService, private customziationFacade: CustomizationFacade, - private images: ImageService, - private sanitizer: DomSanitizer, private route: ActivatedRoute, @Inject(APP_BASE_HREF) href: string, private translate: TranslateService, @@ -106,22 +97,16 @@ export class LoginComponent implements OnDestroy, OnInit { this.settingsService .getAuthentication() - .subscribe((x) => (this.authenticationSettings = x)); + .subscribe((x) => { + this.authenticationSettings = x; + this.headerAuth(); + }); this.settingsService.getClientId().subscribe((x) => (this.clientId = x)); - this.images.getRandomBackground().subscribe((x) => { - this.background = this.sanitizer.bypassSecurityTrustStyle( - "url(" + x.url + ")" - ); - }); - this.timer = setInterval(() => { - this.cycleBackground(); - }, 30000); const base = this.href; if (base.length > 1) { this.baseUrl = base; } - this.translate .get("Login.Errors.IncorrectCredentials") .subscribe((x) => (this.errorBody = x)); @@ -130,7 +115,7 @@ export class LoginComponent implements OnDestroy, OnInit { .subscribe((x) => (this.errorValidation = x)); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notify.open(this.errorValidation, "OK", { duration: 300000, @@ -177,6 +162,7 @@ export class LoginComponent implements OnDestroy, OnInit { if (this.oAuthWindow) { this.oAuthWindow.close(); } + this.oAuthWindow = window.open( window.location.toString(), "_blank", @@ -214,6 +200,11 @@ export class LoginComponent implements OnDestroy, OnInit { } public getPinResult(pinId: number) { + if (this.oAuthWindow.closed) { + if (this.pinTimer) { + clearInterval(this.pinTimer); + } + } this.authService.oAuth(pinId).subscribe( (x) => { if (x.access_token) { @@ -249,19 +240,33 @@ export class LoginComponent implements OnDestroy, OnInit { ); } - public ngOnDestroy() { - clearInterval(this.timer); - clearInterval(this.pinTimer); + public headerAuth() { + if (this.authenticationSettings.enableHeaderAuth) { + this.authService.headerAuth().subscribe({ + next: (x) => { + this.store.save("id_token", x.access_token); + + if (this.authService.loggedIn()) { + this.ngOnDestroy(); + this.router.navigate(["/"]); + } else { + this.notify.open(this.errorBody, "OK", { + duration: 3000, + }); + } + }, + error: (e) => { + this.notify.open(this.errorBody, "OK", { + duration: 3000000, + }); + console.error(e); + } + } + ); + } } - private cycleBackground() { - this.images.getRandomBackground().subscribe((x) => { - this.background = ""; - }); - this.images.getRandomBackground().subscribe((x) => { - this.background = this.sanitizer.bypassSecurityTrustStyle( - "url(" + x.url + ")" - ); - }); + public ngOnDestroy() { + clearInterval(this.pinTimer); } } diff --git a/src/Ombi/ClientApp/src/app/login/resetpassword.component.html b/src/Ombi/ClientApp/src/app/login/resetpassword.component.html index 9fbeb7eda..201223800 100644 --- a/src/Ombi/ClientApp/src/app/login/resetpassword.component.html +++ b/src/Ombi/ClientApp/src/app/login/resetpassword.component.html @@ -1,8 +1,5 @@  -
- -
+
diff --git a/src/Ombi/ClientApp/src/app/login/resetpassword.component.ts b/src/Ombi/ClientApp/src/app/login/resetpassword.component.ts index cb030b386..bd0376cb1 100644 --- a/src/Ombi/ClientApp/src/app/login/resetpassword.component.ts +++ b/src/Ombi/ClientApp/src/app/login/resetpassword.component.ts @@ -1,30 +1,27 @@ -import { PlatformLocation, APP_BASE_HREF } from "@angular/common"; +import { APP_BASE_HREF } from "@angular/common"; import { Component, OnInit, Inject } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; -import { DomSanitizer } from "@angular/platform-browser"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { fadeInOutAnimation } from "../animations/fadeinout"; import { ICustomizationSettings } from "../interfaces"; -import { IdentityService, ImageService, NotificationService, SettingsService } from "../services"; +import { IdentityService, NotificationService, SettingsService } from "../services"; import { CustomizationFacade } from "../state/customization"; @Component({ templateUrl: "./resetpassword.component.html", - animations: [fadeInOutAnimation], styleUrls: ["./login.component.scss"], }) export class ResetPasswordComponent implements OnInit { - public form: FormGroup; + public form: UntypedFormGroup; public customizationSettings: ICustomizationSettings; public emailSettingsEnabled: boolean; public baseUrl: string; - public background: any; private href: string; constructor(private identityService: IdentityService, private notify: NotificationService, - private fb: FormBuilder, private settingsService: SettingsService, @Inject(APP_BASE_HREF) href:string, - private images: ImageService, private sanitizer: DomSanitizer, private customizationFacade: CustomizationFacade) { + private fb: UntypedFormBuilder, private settingsService: SettingsService, @Inject(APP_BASE_HREF) href:string, + private customizationFacade: CustomizationFacade) { this.href = href; this.form = this.fb.group({ email: ["", [Validators.required]], @@ -32,9 +29,7 @@ export class ResetPasswordComponent implements OnInit { } public ngOnInit() { - this.images.getRandomBackground().subscribe(x => { - this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 80.0%, transparent 80%),url(" + x.url + ")"); - }); + const base = this.href; if (base.length > 1) { this.baseUrl = base; @@ -43,7 +38,7 @@ export class ResetPasswordComponent implements OnInit { this.settingsService.getEmailSettingsEnabled().subscribe(x => this.emailSettingsEnabled = x); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (this.emailSettingsEnabled) { if (form.invalid) { diff --git a/src/Ombi/ClientApp/src/app/login/tokenresetpassword.component.html b/src/Ombi/ClientApp/src/app/login/tokenresetpassword.component.html index 6a1c2567f..bd8bc3e38 100644 --- a/src/Ombi/ClientApp/src/app/login/tokenresetpassword.component.html +++ b/src/Ombi/ClientApp/src/app/login/tokenresetpassword.component.html @@ -1,11 +1,7 @@ - -
- -
+
- +
diff --git a/src/Ombi/ClientApp/src/app/login/tokenresetpassword.component.ts b/src/Ombi/ClientApp/src/app/login/tokenresetpassword.component.ts index 695a79abb..b7ef08281 100644 --- a/src/Ombi/ClientApp/src/app/login/tokenresetpassword.component.ts +++ b/src/Ombi/ClientApp/src/app/login/tokenresetpassword.component.ts @@ -1,10 +1,9 @@ import { ActivatedRoute, Params } from "@angular/router"; import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; -import { IdentityService, ImageService } from "../services"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; +import { IdentityService } from "../services"; import { CustomizationFacade } from "../state/customization"; -import { DomSanitizer } from "@angular/platform-browser"; import { ICustomizationSettings } from "../interfaces"; import { IResetPasswordToken } from "../interfaces"; import { NotificationService } from "../services"; @@ -17,15 +16,12 @@ import { Router } from "@angular/router"; }) export class TokenResetPasswordComponent implements OnInit { - public form: FormGroup; + public form: UntypedFormGroup; public customizationSettings: ICustomizationSettings; - public background: any; public baseUrl: string; constructor(private identityService: IdentityService, private router: Router, private route: ActivatedRoute, private notify: NotificationService, - private fb: FormBuilder, private location: PlatformLocation, private images: ImageService, - private sanitizer: DomSanitizer, private customizationFacade: CustomizationFacade, - ) { + private fb: UntypedFormBuilder, private location: PlatformLocation, private customizationFacade: CustomizationFacade) { this.route.queryParams .subscribe((params: Params) => { @@ -39,9 +35,6 @@ export class TokenResetPasswordComponent implements OnInit { } public ngOnInit() { - this.images.getRandomBackground().subscribe(x => { - this.background = this.sanitizer.bypassSecurityTrustStyle("linear-gradient(-10deg, transparent 20%, rgba(0,0,0,0.7) 20.0%, rgba(0,0,0,0.7) 80.0%, transparent 80%),url(" + x.url + ")"); - }); const base = this.location.getBaseHrefFromDOM(); if (base.length > 1) { this.baseUrl = base; @@ -49,7 +42,7 @@ export class TokenResetPasswordComponent implements OnInit { this.customizationFacade.settings$().subscribe(x => this.customizationSettings = x); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notify.error("Email address is required"); return; @@ -65,6 +58,5 @@ export class TokenResetPasswordComponent implements OnInit { }); } }); - } } diff --git a/src/Ombi/ClientApp/src/app/media-details/components/index.ts b/src/Ombi/ClientApp/src/app/media-details/components/index.ts index 6799a8f74..eadc8d635 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/index.ts +++ b/src/Ombi/ClientApp/src/app/media-details/components/index.ts @@ -1,26 +1,26 @@ -import { MovieDetailsComponent } from "./movie/movie-details.component"; -import { YoutubeTrailerComponent } from "./shared/youtube-trailer.component"; -import { TvDetailsComponent } from "./tv/tv-details.component"; -import { MovieInformationPanelComponent } from "./movie/panels/movie-information-panel.component"; -import { TvInformationPanelComponent } from "./tv/panels/tv-information-panel/tv-information-panel.component"; -import { TopBannerComponent } from "./shared/top-banner/top-banner.component"; -import { SocialIconsComponent } from "./shared/social-icons/social-icons.component"; -import { MediaPosterComponent } from "./shared/media-poster/media-poster.component"; -import { CastCarouselComponent } from "./shared/cast-carousel/cast-carousel.component"; -import { DenyDialogComponent } from "./shared/deny-dialog/deny-dialog.component"; -import { TvRequestsPanelComponent } from "./tv/panels/tv-requests/tv-requests-panel.component"; -import { MovieAdvancedOptionsComponent } from "./movie/panels/movie-advanced-options/movie-advanced-options.component"; -import { SearchService, RequestService, RadarrService, IssuesService, SonarrService } from "../../services"; -import { RequestServiceV2 } from "../../services/requestV2.service"; -import { NewIssueComponent } from "./shared/new-issue/new-issue.component"; +import { IssuesService, RadarrService, RequestService, SearchService, SonarrService } from "../../services"; + import { ArtistDetailsComponent } from "./artist/artist-details.component"; import { ArtistInformationPanel } from "./artist/panels/artist-information-panel/artist-information-panel.component"; import { ArtistReleasePanel } from "./artist/panels/artist-release-panel/artist-release-panel.component"; +import { CastCarouselComponent } from "./shared/cast-carousel/cast-carousel.component"; +import { DenyDialogComponent } from "./shared/deny-dialog/deny-dialog.component"; import { IssuesPanelComponent } from "./shared/issues-panel/issues-panel.component"; -import { TvAdvancedOptionsComponent } from "./tv/panels/tv-advanced-options/tv-advanced-options.component"; +import { MediaPosterComponent } from "./shared/media-poster/media-poster.component"; +import { MovieAdvancedOptionsComponent } from "./movie/panels/movie-advanced-options/movie-advanced-options.component"; +import { MovieDetailsComponent } from "./movie/movie-details.component"; +import { MovieInformationPanelComponent } from "./movie/panels/movie-information-panel.component"; +import { NewIssueComponent } from "./shared/new-issue/new-issue.component"; import { RequestBehalfComponent } from "./shared/request-behalf/request-behalf.component"; +import { RequestServiceV2 } from "../../services/requestV2.service"; +import { SocialIconsComponent } from "./shared/social-icons/social-icons.component"; +import { TopBannerComponent } from "./shared/top-banner/top-banner.component"; +import { TvAdvancedOptionsComponent } from "./tv/panels/tv-advanced-options/tv-advanced-options.component"; +import { TvDetailsComponent } from "./tv/tv-details.component"; +import { TvInformationPanelComponent } from "./tv/panels/tv-information-panel/tv-information-panel.component"; import { TvRequestGridComponent } from "./tv/panels/tv-request-grid/tv-request-grid.component"; -import { DetailsGroupComponent } from "../../issues/components/details-group/details-group.component"; +import { TvRequestsPanelComponent } from "./tv/panels/tv-requests/tv-requests-panel.component"; +import { YoutubeTrailerComponent } from "./shared/youtube-trailer.component"; export const components: any[] = [ MovieDetailsComponent, diff --git a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.html b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.html index 4e088bd69..6659e1ccb 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.html +++ b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.html @@ -4,28 +4,18 @@
- + @@ -34,73 +24,154 @@
- +
- - + + {{'Search.ViewOnPlex' | translate}} - + {{'Search.ViewOnEmby' | translate}} - + {{'Search.ViewOnJellyfin' | translate}} - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + + + + - + - - + + - - + + + + + + + - - + + + +
@@ -109,7 +180,8 @@
- + @@ -143,11 +215,16 @@
- Trailers + {{'MediaDetails.Trailers' | translate}} - + - + @@ -162,40 +239,44 @@
- + {{'MediaDetails.RecommendationsTitle' | translate}} -
+ - + {{'MediaDetails.SimilarTitle' | translate}} -
+
@@ -211,4 +292,4 @@
-
\ No newline at end of file +
diff --git a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts index d0e2fa1ef..8d1e5976b 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts +++ b/src/Ombi/ClientApp/src/app/media-details/components/movie/movie-details.component.ts @@ -1,6 +1,6 @@ -import { AfterViewInit, Component, ViewChild, ViewEncapsulation } from "@angular/core"; +import { Component, OnInit, ViewEncapsulation } from "@angular/core"; import { ImageService, SearchV2Service, RequestService, MessageService, RadarrService, SettingsStateService } from "../../../services"; -import { ActivatedRoute } from "@angular/router"; +import { ActivatedRoute, Router } from "@angular/router"; import { DomSanitizer } from "@angular/platform-browser"; import { ISearchMovieResultV2 } from "../../../interfaces/ISearchMovieResultV2"; import { MatDialog } from "@angular/material/dialog"; @@ -12,16 +12,16 @@ import { NewIssueComponent } from "../shared/new-issue/new-issue.component"; import { TranslateService } from "@ngx-translate/core"; import { MovieAdvancedOptionsComponent } from "./panels/movie-advanced-options/movie-advanced-options.component"; import { RequestServiceV2 } from "../../../services/requestV2.service"; -import { RequestBehalfComponent } from "../shared/request-behalf/request-behalf.component"; -import { forkJoin } from "rxjs"; +import { firstValueFrom, forkJoin } from "rxjs"; import { AdminRequestDialogComponent } from "../../../shared/admin-request-dialog/admin-request-dialog.component"; +import { FeaturesFacade } from "../../../state/features/features.facade"; @Component({ templateUrl: "./movie-details.component.html", styleUrls: ["../../media-details.component.scss"], encapsulation: ViewEncapsulation.None }) -export class MovieDetailsComponent { +export class MovieDetailsComponent implements OnInit{ public movie: ISearchMovieResultV2; public hasRequest: boolean; public movieRequest: IMovieRequests; @@ -29,32 +29,48 @@ export class MovieDetailsComponent { public advancedOptions: IAdvancedData; public showAdvanced: boolean; // Set on the UI public issuesEnabled: boolean; - + public roleName4k = "Request4KMovie"; + public is4KEnabled = false; public requestType = RequestType.movie; - - private theMovidDbId: number; private imdbId: string; + private snapMovieId: string; - constructor(private searchService: SearchV2Service, private route: ActivatedRoute, + + constructor(private searchService: SearchV2Service, private route: ActivatedRoute, private router: Router, private sanitizer: DomSanitizer, private imageService: ImageService, public dialog: MatDialog, private requestService: RequestService, private requestService2: RequestServiceV2, private radarrService: RadarrService, public messageService: MessageService, private auth: AuthService, private settingsState: SettingsStateService, - private translate: TranslateService) { - this.route.params.subscribe(async (params: any) => { - if (typeof params.movieDbId === 'string' || params.movieDbId instanceof String) { - if (params.movieDbId.startsWith("tt")) { - this.imdbId = params.movieDbId; - } - } - this.theMovidDbId = params.movieDbId; - await this.load(); + private translate: TranslateService, private featureFacade: FeaturesFacade) { + this.snapMovieId = this.route.snapshot.params.movieDbId; + this.route.params.subscribe(async (params: any) => { + if (typeof params.movieDbId === 'string' || params.movieDbId instanceof String) { + if (params.movieDbId.startsWith("tt")) { + this.imdbId = params.movieDbId; + // Check if we user navigated to another movie and if so reload the component + if (this.imdbId !== this.snapMovieId) { + this.reloadComponent() + } + } + } + this.theMovidDbId = params.movieDbId; + // Check if we user navigated to another movie and if so reload the component + if (params.movieDbId !== this.snapMovieId) { + this.reloadComponent() + } }); } - public async load() { + reloadComponent() { + let currentUrl = this.router.url; + this.router.routeReuseStrategy.shouldReuseRoute = () => false; + this.router.onSameUrlNavigation = 'reload'; + this.router.navigate([currentUrl]); + } + async ngOnInit() { + this.is4KEnabled = this.featureFacade.is4kEnabled(); this.issuesEnabled = this.settingsState.getIssue(); this.isAdmin = this.auth.hasRole("admin") || this.auth.hasRole("poweruser"); @@ -65,6 +81,7 @@ export class MovieDetailsComponent { if (this.imdbId) { this.searchService.getMovieByImdbId(this.imdbId).subscribe(async x => { this.movie = x; + this.checkPoster(); if (this.movie.requestId > 0) { // Load up this request this.hasRequest = true; @@ -75,6 +92,7 @@ export class MovieDetailsComponent { } else { this.searchService.getFullMovieDetails(this.theMovidDbId).subscribe(async x => { this.movie = x; + this.checkPoster(); if (this.movie.requestId > 0) { // Load up this request this.hasRequest = true; @@ -86,18 +104,26 @@ export class MovieDetailsComponent { } } - public async request(userId?: string) { + public async request(is4K: boolean, userId?: string) { + if (!this.is4KEnabled) { + is4K = false; + } if (this.isAdmin) { const dialog = this.dialog.open(AdminRequestDialogComponent, { width: "700px", data: { type: RequestType.movie, id: this.movie.id }, panelClass: 'modal-panel' }); dialog.afterClosed().subscribe(async (result) => { if (result) { - const requestResult = await this.requestService.requestMovie({ theMovieDbId: this.theMovidDbId, + const requestResult = await firstValueFrom(this.requestService.requestMovie({ theMovieDbId: this.theMovidDbId, languageCode: this.translate.currentLang, qualityPathOverride: result.radarrPathId, requestOnBehalf: result.username?.id, - rootFolderOverride: result.radarrFolderId, }).toPromise(); + rootFolderOverride: result.radarrFolderId, + is4KRequest: is4K })); if (requestResult.result) { - this.movie.requested = true; + if (is4K) { + this.movie.has4KRequest = true; + } else { + this.movie.requested = true; + } this.movie.requestId = requestResult.requestId; this.messageService.send(this.translate.instant("Requests.RequestAddedSuccessfully", { title: this.movie.title }), "Ok"); this.movieRequest = await this.requestService.getMovieRequest(this.movie.requestId); @@ -107,9 +133,13 @@ export class MovieDetailsComponent { } }); } else { - const result = await this.requestService.requestMovie({ theMovieDbId: this.theMovidDbId, languageCode: this.translate.currentLang, requestOnBehalf: userId, qualityPathOverride: undefined, rootFolderOverride: undefined }).toPromise(); + const result = await firstValueFrom(this.requestService.requestMovie({ theMovieDbId: this.theMovidDbId, languageCode: this.translate.currentLang, requestOnBehalf: userId, qualityPathOverride: undefined, rootFolderOverride: undefined, is4KRequest: is4K })); if (result.result) { - this.movie.requested = true; + if (is4K) { + this.movie.has4KRequest = true; + } else { + this.movie.requested = true; + } this.movie.requestId = result.requestId; this.movieRequest = await this.requestService.getMovieRequest(this.movie.requestId); this.messageService.send(this.translate.instant("Requests.RequestAddedSuccessfully", { title: this.movie.title }), "Ok"); @@ -145,25 +175,32 @@ export class MovieDetailsComponent { } const dialogRef = this.dialog.open(NewIssueComponent, { width: '500px', - data: { requestId: this.movieRequest ? this.movieRequest.id : null, requestType: RequestType.movie, providerId: provider, title: this.movie.title } + data: { requestId: this.movieRequest ? this.movieRequest.id : null, requestType: RequestType.movie, providerId: provider, title: this.movie.title, posterPath: this.movie.posterPath } }); } - public async approve() { - this.movie.approved = true; - const result = await this.requestService.approveMovie({ id: this.movieRequest.id }).toPromise(); + public async approve(is4K: boolean) { + const result = await firstValueFrom(this.requestService.approveMovie({ id: this.movieRequest.id, is4K })); if (result.result) { + if (is4K) { + this.movie.approved4K = true; + } else { + this.movie.approved = true; + } this.messageService.send(this.translate.instant("Requests.SuccessfullyApproved"), "Ok"); } else { - this.movie.approved = false; this.messageService.sendRequestEngineResultError(result); } } - public async markAvailable() { - const result = await this.requestService.markMovieAvailable({ id: this.movieRequest.id }).toPromise(); + public async markAvailable(is4K: boolean) { + const result = await firstValueFrom(this.requestService.markMovieAvailable({ id: this.movieRequest.id, is4K })) if (result.result) { - this.movie.available = true; + if (is4K) { + this.movie.available4K = true; + } else { + this.movie.available = true; + } this.messageService.send(this.translate.instant("Requests.NowAvailable"), "Ok"); } else { this.messageService.sendRequestEngineResultError(result); @@ -171,10 +208,14 @@ export class MovieDetailsComponent { } - public async markUnavailable() { - const result = await this.requestService.markMovieUnavailable({ id: this.movieRequest.id }).toPromise(); + public async markUnavailable(is4K: boolean) { + const result = await firstValueFrom(this.requestService.markMovieUnavailable({ id: this.movieRequest.id, is4K })); if (result.result) { - this.movie.available = false; + if (is4K) { + this.movie.available4K = false; + } else { + this.movie.available = false; + } this.messageService.send(this.translate.instant("Requests.NowUnavailable"), "Ok"); } else { this.messageService.sendRequestEngineResultError(result); @@ -203,8 +244,8 @@ export class MovieDetailsComponent { }); } - public reProcessRequest() { - this.requestService2.reprocessRequest(this.movieRequest.id, RequestType.movie).subscribe(result => { + public reProcessRequest(is4K: boolean) { + this.requestService2.reprocessRequest(this.movieRequest.id, RequestType.movie, is4K).subscribe(result => { if (result.result) { this.messageService.send(result.message ? result.message : this.translate.instant("Requests.SuccessfullyReprocessed"), "Ok"); } else { @@ -213,6 +254,28 @@ export class MovieDetailsComponent { }); } + public notify() { + this.requestService.subscribeToMovie(this.movieRequest.id).subscribe(result => { + if (result) { + this.movie.subscribed = true; + this.messageService.send(this.translate.instant("Requests.SuccessfulNotify", {title: this.movie.title}), "Ok"); + } else { + this.messageService.send(this.translate.instant("Requests.CouldntNotify", {title: this.movie.title}), "Ok"); + } + }); + } + + public unNotify() { + this.requestService.unSubscribeToMovie(this.movieRequest.id).subscribe(result => { + if (result) { + this.movie.subscribed = false; + this.messageService.send(this.translate.instant("Requests.SuccessfulUnNotify", {title: this.movie.title}), "Ok"); + } else { + this.messageService.send(this.translate.instant("Requests.CouldntNotify", {title: this.movie.title}), "Ok"); + } + }); + } + private loadBanner() { this.imageService.getMovieBanner(this.theMovidDbId.toString()).subscribe(x => { if (!this.movie.backdropPath) { @@ -224,7 +287,14 @@ export class MovieDetailsComponent { } }); } - + private checkPoster() { + if (this.movie.posterPath == null) { + this.movie.posterPath = "../../../images/default_movie_poster.png"; + } + else { + this.movie.posterPath = "https://image.tmdb.org/t/p/w300/" + this.movie.posterPath + }; + } private loadAdvancedInfo() { const profile = this.radarrService.getQualityProfilesFromSettings(); const folders = this.radarrService.getRootFoldersFromSettings(); diff --git a/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.html b/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.html index 1aafc30bf..29d2c6beb 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.html +++ b/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.html @@ -30,32 +30,50 @@ {{ this.movie.status | translateStatus }}
- {{'MediaDetails.Availability' | translate }} - {{'Common.Available' | translate}} - {{'Common.NotAvailable' | translate}} + {{'MediaDetails.Availability' | translate }} + {{'Common.Available' | translate}} + {{'Common.NotAvailable' | translate}}
-
- {{'MediaDetails.RequestStatus' | translate }} +
+ {{'MediaDetails.RequestStatus' | translate }} +
+
{{'Common.RequestDenied' | translate}}
{{'Common.ProcessingRequest' | translate}}
-
{{'Common.PendingApproval' | translate}} -
-
{{'Common.NotRequested' | translate}} -
+
{{'Common.PendingApproval' | translate}}
+ +
+
+
{{'Common.RequestDenied4K' | translate}}
+
{{'Common.ProcessingRequest4K' | translate}}
+
{{'Common.PendingApproval4K' | translate}}
+ +
- {{'MediaDetails.RequestedBy' | translate }} - {{request.requestedUser.userAlias}} + {{'MediaDetails.RequestedBy' | translate }} + {{request.requestedUser.userAlias}}
- {{'MediaDetails.RequestDate' | translate }} - {{request.requestedDate | amUserLocale | amDateFormat: 'LL'}} + {{'MediaDetails.RequestDate' | translate }} + {{request.requestedDate4k | amUserLocale | amDateFormat: 'LL'}} + {{request.requestedDate | amUserLocale | amDateFormat: 'LL'}}
-
- {{'MediaDetails.DeniedReason' | translate }} +
+ {{'MediaDetails.RequestSource' | translate }} + {{RequestSource[request.source]}} +
+ +
+ {{'MediaDetails.DeniedReason' | translate }} +
{{request.deniedReason}} +
+
+ {{request.deniedReason4K}} +
@@ -64,6 +82,11 @@
{{movie.quality | quality}}
+
+ {{'MediaDetails.Quality' | translate }}  + {{"4K" | quality}} +
+
{{'MediaDetails.RootFolderOverride' | translate }}
{{request.rootPathOverrideTitle}}
@@ -104,7 +127,7 @@
- {{'MediaDetails.Genres' | translate }} + {{'MediaDetails.GenresLabel' | translate }}
diff --git a/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.ts b/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.ts index c11a0f61c..ade256a82 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.ts +++ b/src/Ombi/ClientApp/src/app/media-details/components/movie/panels/movie-information-panel.component.ts @@ -1,6 +1,6 @@ import { Component, ViewEncapsulation, Input, OnInit, Inject } from "@angular/core"; import { ISearchMovieResultV2 } from "../../../../interfaces/ISearchMovieResultV2"; -import { IMovieRequests } from "../../../../interfaces"; +import { IMovieRequests, RequestSource } from "../../../../interfaces"; import { SearchV2Service } from "../../../../services/searchV2.service"; import { IMovieRatings } from "../../../../interfaces/IRatings"; import { APP_BASE_HREF } from "@angular/common"; @@ -21,6 +21,7 @@ export class MovieInformationPanelComponent implements OnInit { public ratings: IMovieRatings; public streams: IStreamingData[]; + public RequestSource = RequestSource; public baseUrl: string; diff --git a/src/Ombi/ClientApp/src/app/media-details/components/shared/cast-carousel/cast-carousel.component.html b/src/Ombi/ClientApp/src/app/media-details/components/shared/cast-carousel/cast-carousel.component.html index 49875514d..e14323a0e 100644 --- a/src/Ombi/ClientApp/src/app/media-details/components/shared/cast-carousel/cast-carousel.component.html +++ b/src/Ombi/ClientApp/src/app/media-details/components/shared/cast-carousel/cast-carousel.component.html @@ -6,10 +6,10 @@
diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/albums-grid/albums-grid.component.ts b/src/Ombi/ClientApp/src/app/requests-list/components/albums-grid/albums-grid.component.ts index 633ddf1c2..a58d8cd9f 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/albums-grid/albums-grid.component.ts +++ b/src/Ombi/ClientApp/src/app/requests-list/components/albums-grid/albums-grid.component.ts @@ -1,14 +1,14 @@ -import { Component, AfterViewInit, ViewChild, EventEmitter, Output, ChangeDetectorRef, OnInit } from "@angular/core"; -import { IRequestsViewModel, IAlbumRequest } from "../../../interfaces"; -import { MatPaginator } from "@angular/material/paginator"; -import { MatSort } from "@angular/material/sort"; -import { merge, Observable, of as observableOf } from 'rxjs'; +import { AfterViewInit, ChangeDetectorRef, Component, EventEmitter, OnInit, Output, ViewChild } from "@angular/core"; +import { IAlbumRequest, IRequestsViewModel } from "../../../interfaces"; +import { Observable, merge, of as observableOf } from 'rxjs'; import { catchError, map, startWith, switchMap } from 'rxjs/operators'; -import { RequestServiceV2 } from "../../../services/requestV2.service"; import { AuthService } from "../../../auth/auth.service"; -import { StorageService } from "../../../shared/storage/storage-service"; +import { MatPaginator } from "@angular/material/paginator"; +import { MatSort } from "@angular/material/sort"; import { RequestFilterType } from "../../models/RequestFilterType"; +import { RequestServiceV2 } from "../../../services/requestV2.service"; +import { StorageService } from "../../../shared/storage/storage-service"; @Component({ templateUrl: "./albums-grid.component.html", @@ -25,6 +25,8 @@ export class AlbumsGridComponent implements OnInit, AfterViewInit { public defaultSort: string = "requestedDate"; public defaultOrder: string = "desc"; public currentFilter: RequestFilterType = RequestFilterType.All; + public manageOwnRequests: boolean; + public userName: string; public RequestFilter = RequestFilterType; @@ -42,10 +44,12 @@ export class AlbumsGridComponent implements OnInit, AfterViewInit { constructor(private requestService: RequestServiceV2, private ref: ChangeDetectorRef, private auth: AuthService, private storageService: StorageService) { + this.userName = auth.claims().name; } public ngOnInit() { this.isAdmin = this.auth.hasRole("admin") || this.auth.hasRole("poweruser"); + this.manageOwnRequests = this.auth.hasRole("ManageOwnRequests") const defaultCount = this.storageService.get(this.storageKeyGridCount); const defaultSort = this.storageService.get(this.storageKey); @@ -117,16 +121,17 @@ export class AlbumsGridComponent implements OnInit, AfterViewInit { public openOptions(request: IAlbumRequest) { const filter = () => { - this.dataSource = this.dataSource.filter((req) => { - return req.id !== request.id; - }) + this.dataSource = this.dataSource.filter((req) => { + return req.id !== request.id; + }); }; const onChange = () => { this.ref.detectChanges(); }; - this.onOpenOptions.emit({ request: request, filter: filter, onChange: onChange }); + const data = { request: request, filter: filter, onChange: onChange, manageOwnRequests: this.manageOwnRequests, isAdmin: this.isAdmin, has4kRequest: false }; + this.onOpenOptions.emit(data); } public switchFilter(type: RequestFilterType) { diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.html b/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.html index 0e6e31521..26da47524 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.html +++ b/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.html @@ -58,7 +58,7 @@ - + @@ -66,6 +66,14 @@ + + + + + @@ -75,8 +83,8 @@ @@ -90,6 +98,9 @@ - - \ No newline at end of file + + + + + diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.ts b/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.ts index c033238b1..ca36a5d62 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.ts +++ b/src/Ombi/ClientApp/src/app/requests-list/components/movies-grid/movies-grid.component.ts @@ -1,10 +1,11 @@ import { AfterViewInit, ChangeDetectorRef, Component, EventEmitter, OnInit, Output, ViewChild } from "@angular/core"; import { IMovieRequests, IRequestEngineResult, IRequestsViewModel } from "../../../interfaces"; import { NotificationService, RequestService } from "../../../services"; -import { Observable, forkJoin, merge, of as observableOf } from 'rxjs'; +import { Observable, combineLatest, forkJoin, merge, of as observableOf } from 'rxjs'; import { catchError, map, startWith, switchMap } from 'rxjs/operators'; import { AuthService } from "../../../auth/auth.service"; +import { FeaturesFacade } from "../../../state/features/features.facade"; import { MatPaginator } from "@angular/material/paginator"; import { MatSort } from "@angular/material/sort"; import { MatTableDataSource } from "@angular/material/table"; @@ -26,11 +27,13 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { public displayedColumns: string[] = ['title', 'requestedUser.requestedBy', 'status', 'requestStatus','requestedDate', 'actions']; public gridCount: string = "15"; public isAdmin: boolean; + public is4kEnabled = false; public manageOwnRequests: boolean; public defaultSort: string = "requestedDate"; public defaultOrder: string = "desc"; public currentFilter: RequestFilterType = RequestFilterType.All; public selection = new SelectionModel(true, []); + public userName: string; public RequestFilter = RequestFilterType; @@ -40,16 +43,18 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { private storageKeyGridCount = "Movie_DefaultGridCount"; private storageKeyCurrentFilter = "Movie_DefaultFilter"; - @Output() public onOpenOptions = new EventEmitter<{ request: any, filter: any, onChange: any, manageOwnRequests: boolean, isAdmin: boolean }>(); + @Output() public onOpenOptions = new EventEmitter<{ request: any, filter: any, onChange: any, manageOwnRequests: boolean, isAdmin: boolean, has4kRequest: boolean, hasRegularRequest: boolean }>(); @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; constructor(private requestService: RequestServiceV2, private ref: ChangeDetectorRef, - private auth: AuthService, private storageService: StorageService, - private requestServiceV1: RequestService, private notification: NotificationService, - private translateService: TranslateService) { + private auth: AuthService, private storageService: StorageService, + private requestServiceV1: RequestService, private notification: NotificationService, + private translateService: TranslateService, + private featureFacade: FeaturesFacade) { + this.userName = auth.claims().name; } public ngOnInit() { @@ -58,6 +63,13 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { if (this.isAdmin) { this.displayedColumns.unshift('select'); } + + this.is4kEnabled = this.featureFacade.is4kEnabled(); + if ((this.isAdmin || this.auth.hasRole("Request4KMovie")) + && this.is4kEnabled) { + this.displayedColumns.splice(4, 0, 'has4kRequest'); + } + const defaultCount = this.storageService.get(this.storageKeyGridCount); const defaultSort = this.storageService.get(this.storageKey); const defaultOrder = this.storageService.get(this.storageKeyOrder); @@ -137,10 +149,20 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { this.ref.detectChanges(); }; - const data = { request: request, filter: filter, onChange: onChange, manageOwnRequests: this.manageOwnRequests, isAdmin: this.isAdmin }; + const data = { request: request, filter: filter, onChange: onChange, manageOwnRequests: this.manageOwnRequests, isAdmin: this.isAdmin, has4kRequest: request.has4KRequest, hasRegularRequest: this.checkDate(request.requestedDate) }; this.onOpenOptions.emit(data); } + private checkDate(date: Date|string): boolean { + if (typeof date === 'string') { + return new Date(date).getFullYear() > 1; + } + if (date instanceof Date) { + return date.getFullYear() > 1; + } + return false; + } + public switchFilter(type: RequestFilterType) { this.currentFilter = type; this.ngAfterViewInit(); @@ -150,37 +172,41 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { const numSelected = this.selection.selected.length; const numRows = this.dataSource.data.length; return numSelected === numRows; - } + } - public masterToggle() { + public masterToggle() { this.isAllSelected() ? this.selection.clear() : this.dataSource.data.forEach(row => this.selection.select(row)); - } + } - public async bulkDelete() { - if (this.selection.isEmpty()) { - return; - } - let tasks = new Array(); - this.selection.selected.forEach((selected) => { - tasks.push(this.requestServiceV1.removeMovieRequestAsync(selected.id)); - }); - - await Promise.all(tasks); - - this.notification.success(this.translateService.instant('Requests.RequestPanel.Deleted')) - this.selection.clear(); - this.ngAfterViewInit(); - } - - public bulkApprove() { + public async bulkDelete() { if (this.selection.isEmpty()) { return; } let tasks = new Array>(); this.selection.selected.forEach((selected) => { - tasks.push(this.requestServiceV1.approveMovie({ id: selected.id })); + tasks.push(this.requestServiceV1.removeMovieRequestAsync(selected.id)); + }); + + combineLatest(tasks).subscribe(() => { + this.notification.success(this.translateService.instant('Requests.RequestPanel.Deleted')) + this.selection.clear(); + this.ngAfterViewInit(); + }); + } + + public bulkApprove = () => this.bulkApproveInternal(false); + + public bulkApprove4K = () => this.bulkApproveInternal(true); + + private bulkApproveInternal(is4k: boolean) { + if (this.selection.isEmpty()) { + return; + } + let tasks = new Array>(); + this.selection.selected.forEach((selected) => { + tasks.push(this.requestServiceV1.approveMovie({ id: selected.id, is4K: is4k })); }); this.isLoadingResults = true; @@ -196,5 +222,45 @@ export class MoviesGridComponent implements OnInit, AfterViewInit { this.selection.clear(); this.ngAfterViewInit(); }) - } + } + + public bulkDeny = () => this.bulkDenyInternal(false); + + public bulkDeny4K = () => this.bulkDenyInternal(true); + + private bulkDenyInternal(is4k: boolean) { + if (this.selection.isEmpty()) { + return; + } + let tasks = new Array>(); + this.selection.selected.forEach((selected) => { + + tasks.push(this.requestServiceV1.denyMovie({ + id: selected.id, + is4K: is4k, + reason: `` // TOOD: reuse DenyDialog to allow for a reason to be entered + })); + }); + + this.isLoadingResults = true; + forkJoin(tasks).subscribe((result: IRequestEngineResult[]) => { + this.isLoadingResults = false; + const failed = result.filter(x => !x.result); + if (failed.length > 0) { + this.notification.error("Some requests failed to deny: " + failed[0].errorMessage); + this.selection.clear(); + return; + } + this.notification.success(this.translateService.instant('Requests.RequestPanel.Denied')); + this.selection.clear(); + this.ngAfterViewInit(); + }) + } + + public getRequestDate(request: IMovieRequests): Date { + if (new Date(request.requestedDate).getFullYear() === 1) { + return request.requestedDate4k; + } + return request.requestedDate; + } } \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/options/request-options.component.html b/src/Ombi/ClientApp/src/app/requests-list/components/options/request-options.component.html index ac974ece8..b32c872ac 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/options/request-options.component.html +++ b/src/Ombi/ClientApp/src/app/requests-list/components/options/request-options.component.html @@ -1,11 +1,20 @@ - - {{'Requests.RequestPanel.Delete' | translate}} - - + {{'Requests.RequestPanel.Approve' | translate}} + + {{'Requests.RequestPanel.Deny' | translate}} + + + {{'Requests.RequestPanel.Approve4K' | translate}} + + + {{'Requests.RequestPanel.Deny4K' | translate}} + {{'Requests.RequestPanel.ChangeAvailability' | translate}} + + {{'Requests.RequestPanel.Delete' | translate}} + \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/options/request-options.component.ts b/src/Ombi/ClientApp/src/app/requests-list/components/options/request-options.component.ts index 625efe31c..909c34544 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/options/request-options.component.ts +++ b/src/Ombi/ClientApp/src/app/requests-list/components/options/request-options.component.ts @@ -1,8 +1,12 @@ import { Component, Inject } from '@angular/core'; import { MAT_BOTTOM_SHEET_DATA, MatBottomSheetRef } from '@angular/material/bottom-sheet'; -import { RequestService } from '../../../services'; -import { RequestType } from '../../../interfaces'; +import { MessageService, RequestService } from '../../../services'; +import { IRequestEngineResult, RequestType } from '../../../interfaces'; import { UpdateType } from '../../models/UpdateType'; +import { TranslateService } from '@ngx-translate/core'; +import { firstValueFrom, Observable } from 'rxjs'; +import { DenyDialogComponent } from '../../../media-details/components/shared/deny-dialog/deny-dialog.component'; +import { MatDialog } from '@angular/material/dialog'; @Component({ selector: 'request-options', @@ -13,44 +17,83 @@ export class RequestOptionsComponent { public RequestType = RequestType; constructor(@Inject(MAT_BOTTOM_SHEET_DATA) public data: any, - private requestService: RequestService, private bottomSheetRef: MatBottomSheetRef) { } + private requestService: RequestService, + private messageService: MessageService, + public dialog: MatDialog, + private bottomSheetRef: MatBottomSheetRef, + private translate: TranslateService) { } public async delete() { + var request: Observable; if (this.data.type === RequestType.movie) { - await this.requestService.removeMovieRequestAsync(this.data.id); + request = this.requestService.removeMovieRequestAsync(this.data.id); } if (this.data.type === RequestType.tvShow) { - await this.requestService.deleteChild(this.data.id).toPromise(); + request = this.requestService.deleteChild(this.data.id); } if (this.data.type === RequestType.album) { - await this.requestService.removeAlbumRequest(this.data.id).toPromise(); + request = this.requestService.removeAlbumRequest(this.data.id); } - - this.bottomSheetRef.dismiss({type: UpdateType.Delete}); - return; + request.subscribe(result => { + if (result.result) { + this.messageService.send(this.translate.instant("Requests.SuccessfullyDeleted")); + this.bottomSheetRef.dismiss({type: UpdateType.Delete}); + return; + } else { + this.messageService.sendRequestEngineResultError(result); + } + }); } public async approve() { if (this.data.type === RequestType.movie) { - await this.requestService.approveMovie({id: this.data.id}).toPromise(); + await firstValueFrom(this.requestService.approveMovie({id: this.data.id, is4K: false})); } if (this.data.type === RequestType.tvShow) { - await this.requestService.approveChild({id: this.data.id}).toPromise(); + await firstValueFrom(this.requestService.approveChild({id: this.data.id})); } if (this.data.type === RequestType.album) { - await this.requestService.approveAlbum({id: this.data.id}).toPromise(); + await firstValueFrom(this.requestService.approveAlbum({id: this.data.id})); } this.bottomSheetRef.dismiss({type: UpdateType.Approve}); return; } + public deny = () => this.denyInternal(false); + + public deny4K = () => this.denyInternal(true); + + private async denyInternal(is4K: boolean) { + const dialogRef = this.dialog.open(DenyDialogComponent, { + width: '250px', + data: { requestId: this.data.id, is4K: is4K, requestType: this.data.type } + }); + + dialogRef.afterClosed().subscribe(result => { + if (result.denied) { + this.bottomSheetRef.dismiss({ type: UpdateType.Deny }); + + } + }); + } + + public async approve4K() { + if (this.data.type != RequestType.movie) { + return; + } + + await firstValueFrom(this.requestService.approveMovie({id: this.data.id, is4K: true})); + this.bottomSheetRef.dismiss({type: UpdateType.Approve}); + return; + } + public async changeAvailability() { if (this.data.type === RequestType.movie) { - await this.requestService.markMovieAvailable({id: this.data.id}).toPromise(); + await firstValueFrom(this.requestService.markMovieAvailable({id: this.data.id, is4K: false})) } if (this.data.type === RequestType.album) { - await this.requestService.markAlbumAvailable({id: this.data.id}).toPromise(); + await firstValueFrom(this.requestService.markAlbumAvailable({id: this.data.id})); } this.bottomSheetRef.dismiss({type: UpdateType.Availability}); diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/requests-list.component.ts b/src/Ombi/ClientApp/src/app/requests-list/components/requests-list.component.ts index 351c5a794..4ea6e4886 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/requests-list.component.ts +++ b/src/Ombi/ClientApp/src/app/requests-list/components/requests-list.component.ts @@ -1,7 +1,6 @@ import { Component, ViewChild } from "@angular/core"; import { MatBottomSheet } from "@angular/material/bottom-sheet"; -import { MoviesGridComponent } from "./movies-grid/movies-grid.component"; import { RequestOptionsComponent } from "./options/request-options.component"; import { UpdateType } from "../models/UpdateType"; @@ -13,8 +12,8 @@ export class RequestsListComponent { constructor(private bottomSheet: MatBottomSheet) { } - public onOpenOptions(event: { request: any, filter: any, onChange: any, manageOwnRequests: boolean, isAdmin: boolean }) { - const ref = this.bottomSheet.open(RequestOptionsComponent, { data: { id: event.request.id, type: event.request.requestType, canApprove: event.request.canApprove, manageOwnRequests: event.manageOwnRequests, isAdmin: event.isAdmin } }); + public onOpenOptions(event: { request: any, filter: any, onChange: any, manageOwnRequests: boolean, isAdmin: boolean, has4kRequest: boolean, hasRegularRequest: boolean }) { + const ref = this.bottomSheet.open(RequestOptionsComponent, { data: { id: event.request.id, type: event.request.requestType, canApprove: event.request.canApprove, manageOwnRequests: event.manageOwnRequests, isAdmin: event.isAdmin, has4kRequest: event.has4kRequest, hasRegularRequest: event.hasRegularRequest } }); ref.afterDismissed().subscribe((result) => { if(!result) { @@ -36,6 +35,11 @@ export class RequestsListComponent { event.onChange(); return; } + if (result.type == UpdateType.Deny) { + event.request.requestStatus = 'Common.Denied'; + event.onChange(); + return; + } }); } } diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/tv-grid/tv-grid.component.html b/src/Ombi/ClientApp/src/app/requests-list/components/tv-grid/tv-grid.component.html index 8cb00d3bb..7eb4b5634 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/tv-grid/tv-grid.component.html +++ b/src/Ombi/ClientApp/src/app/requests-list/components/tv-grid/tv-grid.component.html @@ -63,7 +63,7 @@ diff --git a/src/Ombi/ClientApp/src/app/requests-list/components/tv-grid/tv-grid.component.ts b/src/Ombi/ClientApp/src/app/requests-list/components/tv-grid/tv-grid.component.ts index 5e8521302..25c552924 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/components/tv-grid/tv-grid.component.ts +++ b/src/Ombi/ClientApp/src/app/requests-list/components/tv-grid/tv-grid.component.ts @@ -1,14 +1,14 @@ -import { Component, AfterViewInit, ViewChild, Output, EventEmitter, ChangeDetectorRef, OnInit } from "@angular/core"; -import { IRequestsViewModel, IChildRequests } from "../../../interfaces"; -import { MatPaginator } from "@angular/material/paginator"; -import { MatSort } from "@angular/material/sort"; -import { merge, of as observableOf, Observable } from 'rxjs'; +import { AfterViewInit, ChangeDetectorRef, Component, EventEmitter, OnInit, Output, ViewChild } from "@angular/core"; +import { IChildRequests, IRequestsViewModel } from "../../../interfaces"; +import { Observable, merge, of as observableOf } from 'rxjs'; import { catchError, map, startWith, switchMap } from 'rxjs/operators'; -import { RequestServiceV2 } from "../../../services/requestV2.service"; import { AuthService } from "../../../auth/auth.service"; -import { StorageService } from "../../../shared/storage/storage-service"; +import { MatPaginator } from "@angular/material/paginator"; +import { MatSort } from "@angular/material/sort"; import { RequestFilterType } from "../../models/RequestFilterType"; +import { RequestServiceV2 } from "../../../services/requestV2.service"; +import { StorageService } from "../../../shared/storage/storage-service"; @Component({ templateUrl: "./tv-grid.component.html", @@ -34,7 +34,7 @@ export class TvGridComponent implements OnInit, AfterViewInit { private storageKeyGridCount = "Tv_DefaultGridCount"; private storageKeyCurrentFilter = "Tv_DefaultFilter"; - @Output() public onOpenOptions = new EventEmitter<{request: any, filter: any, onChange: any}>(); + @Output() public onOpenOptions = new EventEmitter<{ request: any, filter: any, onChange: any, manageOwnRequests: boolean, isAdmin: boolean, has4kRequest: boolean, hasRegularRequest: boolean }>(); @ViewChild(MatPaginator) paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; @@ -108,7 +108,7 @@ export class TvGridComponent implements OnInit, AfterViewInit { this.ref.detectChanges(); }; - const data = { request: request, filter: filter, onChange: onChange, manageOwnRequests: this.manageOwnRequests, isAdmin: this.isAdmin }; + const data = { request: request, filter: filter, onChange: onChange, manageOwnRequests: this.manageOwnRequests, isAdmin: this.isAdmin, has4kRequest: false, hasRegularRequest: true }; this.onOpenOptions.emit(data); } diff --git a/src/Ombi/ClientApp/src/app/requests-list/models/UpdateType.ts b/src/Ombi/ClientApp/src/app/requests-list/models/UpdateType.ts index 3a0f690db..9e54b1114 100644 --- a/src/Ombi/ClientApp/src/app/requests-list/models/UpdateType.ts +++ b/src/Ombi/ClientApp/src/app/requests-list/models/UpdateType.ts @@ -1,5 +1,6 @@ export enum UpdateType { Delete, Approve, - Availability + Availability, + Deny } \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/requests/movierequests.component.html b/src/Ombi/ClientApp/src/app/requests/movierequests.component.html index 03c932fd8..4e7ad3628 100644 --- a/src/Ombi/ClientApp/src/app/requests/movierequests.component.html +++ b/src/Ombi/ClientApp/src/app/requests/movierequests.component.html @@ -1,6 +1,6 @@
- -
- - -
- -
-
- -
- -
-
- -
- -
- - -
-
-
- - - -
-
- - -
-
- -
- -
-
-
- -
-
-
- - -
-
-
-
- -
-
- - - - - -
-
- -
-
- -
- -
- -
-
-
- poster - -
-
-
- -

{{result.title}} ({{result.releaseDate | amLocal | amDateFormat: 'YYYY'}})

-
- - {{ - 'Search.TheatricalRelease' | translate: {date: result.releaseDate | amLocal | - amDateFormat: 'LL'} }} - {{ 'Search.DigitalDate' | translate: {date: result.digitalReleaseDate | - amLocal | amUserLocale | amDateFormat: 'LL'} }} - - - - - {{result.quality}}p - - - - - - - - - -
-
-

{{result.overview}}

-
- - -
-
- -
-
-
- - - - - - -
- - - -
- - - -
- -
-
-
-
- -
-
- - - diff --git a/src/Ombi/ClientApp/src/app/search/moviesearch.component.ts b/src/Ombi/ClientApp/src/app/search/moviesearch.component.ts deleted file mode 100644 index c8cddd499..000000000 --- a/src/Ombi/ClientApp/src/app/search/moviesearch.component.ts +++ /dev/null @@ -1,275 +0,0 @@ -import { PlatformLocation, APP_BASE_HREF } from "@angular/common"; -import { Component, Input, OnInit, Inject } from "@angular/core"; -import { DomSanitizer } from "@angular/platform-browser"; -import { TranslateService } from "@ngx-translate/core"; -import { Subject } from "rxjs"; -import { debounceTime, distinctUntilChanged } from "rxjs/operators"; - -import { AuthService } from "../auth/auth.service"; -import { IIssueCategory, ILanguageRefine, IRequestEngineResult, ISearchMovieResult } from "../interfaces"; -import { NotificationService, RequestService, SearchService, SettingsService } from "../services"; - -import * as languageData from "../../other/iso-lang.json"; - -@Component({ - selector: "movie-search", - templateUrl: "./moviesearch.component.html", - styleUrls: ["./search.component.scss"], -}) -export class MovieSearchComponent implements OnInit { - - public searchText: string; - public searchChanged: Subject = new Subject(); - public movieRequested: Subject = new Subject(); - public movieResults: ISearchMovieResult[]; - public result: IRequestEngineResult; - - public searchApplied = false; - public refineSearchEnabled = false; - public searchYear?: number; - public actorSearch: boolean; - public selectedLanguage: string; - public langauges: ILanguageRefine[]; - - @Input() public issueCategories: IIssueCategory[]; - @Input() public issuesEnabled: boolean; - public issuesBarVisible = false; - public issueRequestTitle: string; - public issueRequestId: number; - public issueProviderId: string; - public issueCategorySelected: IIssueCategory; - public defaultPoster: string; - private href: string; - - constructor( - private searchService: SearchService, private requestService: RequestService, - private notificationService: NotificationService, private authService: AuthService, - private readonly translate: TranslateService, private sanitizer: DomSanitizer, - @Inject(APP_BASE_HREF) href:string, private settingsService: SettingsService) { - this.href= href; - this.langauges = languageData; - this.searchChanged.pipe( - debounceTime(600), // Wait Xms after the last event before emitting last event - distinctUntilChanged(), // only emit if value is different from previous value - ).subscribe(x => { - this.searchText = x as string; - this.runSearch(); - }); - this.defaultPoster = "../../../images/default_movie_poster.png"; - const base = this.href; - if (base) { - this.defaultPoster = "../../.." + base + "/images/default_movie_poster.png"; - } - } - - public ngOnInit() { - this.searchText = ""; - this.movieResults = []; - this.result = { - message: "", - result: false, - errorMessage: "", - }; - this.settingsService.getDefaultLanguage().subscribe(x => this.selectedLanguage = x); - this.popularMovies(); - } - - public search(text: any) { - this.searchChanged.next(text.target.value); - } - - public request(searchResult: ISearchMovieResult) { - searchResult.requested = true; - searchResult.requestProcessing = true; - searchResult.showSubscribe = false; - if (this.authService.hasRole("admin") || this.authService.hasRole("AutoApproveMovie")) { - searchResult.approved = true; - } - - try { - const language = this.selectedLanguage && this.selectedLanguage.length > 0 ? this.selectedLanguage : "en"; - this.requestService.requestMovie({ theMovieDbId: searchResult.id, languageCode: language }) - .subscribe(x => { - this.result = x; - if (this.result.result) { - this.movieRequested.next(); - this.translate.get("Search.RequestAdded", { title: searchResult.title }).subscribe(x => { - this.notificationService.success(x); - searchResult.processed = true; - }); - } else { - if (this.result.errorMessage && this.result.message) { - this.notificationService.warning("Request Added", `${this.result.message} - ${this.result.errorMessage}`); - } else { - this.notificationService.warning("Request Added", this.result.message ? this.result.message : this.result.errorMessage); - } - searchResult.requested = false; - searchResult.approved = false; - searchResult.processed = false; - searchResult.requestProcessing = false; - - } - }); - } catch (e) { - - searchResult.processed = false; - searchResult.requestProcessing = false; - this.notificationService.error(e); - } - } - - public popularMovies() { - this.clearResults(); - this.searchService.popularMovies() - .subscribe(x => { - this.movieResults = x; - this.getExtraInfo(); - }); - } - public nowPlayingMovies() { - this.clearResults(); - this.searchService.nowPlayingMovies() - .subscribe(x => { - this.movieResults = x; - this.getExtraInfo(); - }); - } - public topRatedMovies() { - this.clearResults(); - this.searchService.topRatedMovies() - .subscribe(x => { - this.movieResults = x; - this.getExtraInfo(); - }); - } - public upcomingMovies() { - this.clearResults(); - this.searchService.upcomingMovies() - .subscribe(x => { - this.movieResults = x; - this.getExtraInfo(); - }); - } - - public reportIssue(catId: IIssueCategory, req: ISearchMovieResult) { - this.issueRequestId = req.id; - const releaseDate = new Date(req.releaseDate); - this.issueRequestTitle = req.title + ` (${releaseDate.getFullYear()})`; - this.issueCategorySelected = catId; - this.issuesBarVisible = true; - this.issueProviderId = req.id.toString(); - } - - public similarMovies(theMovieDbId: number) { - this.clearResults(); - const lang = this.selectedLanguage && this.selectedLanguage.length > 0 ? this.selectedLanguage : ""; - this.searchService.similarMovies(theMovieDbId, lang) - .subscribe(x => { - this.movieResults = x; - this.getExtraInfo(); - }); - } - - public subscribe(r: ISearchMovieResult) { - r.subscribed = true; - this.requestService.subscribeToMovie(r.requestId) - .subscribe(x => { - this.notificationService.success(`Subscribed To Movie ${r.title}!`); - }); - } - - public unSubscribe(r: ISearchMovieResult) { - r.subscribed = false; - this.requestService.unSubscribeToMovie(r.requestId) - .subscribe(x => { - this.notificationService.success("Unsubscribed Movie!"); - }); - } - - public refineOpen() { - this.refineSearchEnabled = !this.refineSearchEnabled; - if (!this.refineSearchEnabled) { - this.searchYear = undefined; - } - } - - public applyRefinedSearch() { - this.runSearch(); - } - - private getExtraInfo() { - - this.movieResults.forEach((val, index) => { - if (val.posterPath === null) { - val.posterPath = this.defaultPoster; - } else { - val.posterPath = "https://image.tmdb.org/t/p/w300/" + val.posterPath; - } - val.background = this.sanitizer.bypassSecurityTrustStyle - ("url(" + "https://image.tmdb.org/t/p/w1280" + val.backdropPath + ")"); - - if (this.applyRefinedSearch) { - this.searchService.getMovieInformationWithRefined(val.id, this.selectedLanguage) - .subscribe(m => { - this.updateItem(val, m); - }); - } else { - this.searchService.getMovieInformation(val.id) - .subscribe(m => { - this.updateItem(val, m); - }); - } - }); - } - - private updateItem(key: ISearchMovieResult, updated: ISearchMovieResult) { - const index = this.movieResults.indexOf(key, 0); - if (index > -1) { - const copy = { ...this.movieResults[index] }; - this.movieResults[index] = updated; - this.movieResults[index].background = copy.background; - this.movieResults[index].posterPath = copy.posterPath; - } - } - private clearResults() { - this.movieResults = []; - this.searchApplied = false; - } - - private runSearch() { - if (this.searchText === "") { - this.clearResults(); - return; - } - if (this.refineOpen) { - if (!this.actorSearch) { - this.searchService.searchMovieWithRefined(this.searchText, this.searchYear, this.selectedLanguage) - .subscribe(x => { - this.movieResults = x; - this.searchApplied = true; - // Now let's load some extra info including IMDB Id - // This way the search is fast at displaying results. - this.getExtraInfo(); - }); - } else { - this.searchService.searchMovieByActor(this.searchText, this.selectedLanguage) - .subscribe(x => { - this.movieResults = x; - this.searchApplied = true; - // Now let's load some extra info including IMDB Id - // This way the search is fast at displaying results. - this.getExtraInfo(); - }); - } - } else { - this.searchService.searchMovie(this.searchText) - .subscribe(x => { - this.movieResults = x; - this.searchApplied = true; - // Now let's load some extra info including IMDB Id - // This way the search is fast at displaying results. - this.getExtraInfo(); - }); - } - } -} diff --git a/src/Ombi/ClientApp/src/app/search/moviesearchgrid.component.html b/src/Ombi/ClientApp/src/app/search/moviesearchgrid.component.html deleted file mode 100644 index a6512577a..000000000 --- a/src/Ombi/ClientApp/src/app/search/moviesearchgrid.component.html +++ /dev/null @@ -1,149 +0,0 @@ - -
- -
-
- -
-
- -
Sorry, we didn't find any results!
-
- - -
-
-
-
- - poster - -
-
-
-
- - -
-
-
- -
-
-
-
- - - poster - -
-
-
- -

{{result.title}} ({{result.releaseDate | amLocal | amDateFormat: 'YYYY'}})

-
- - Release Date: {{result.releaseDate | amLocal | amUserLocale | amDateFormat: 'L'}} - - - HomePage - - - - Trailer - - {{result.quality}}p - - - Available - - - Processing Request - - - Pending Approval - - - Not Requested - - - - - -
-
-
-

{{result.overview}}

-
- - -
- -
- - -
-
-
- - View In Plex - -
-
-
-
- - - - - - -
- -
- - -
- -
-
-
- -
-
\ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/search/moviesearchgrid.component.ts b/src/Ombi/ClientApp/src/app/search/moviesearchgrid.component.ts deleted file mode 100644 index 4ff6fa986..000000000 --- a/src/Ombi/ClientApp/src/app/search/moviesearchgrid.component.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { Component, OnInit } from "@angular/core"; -import { Subject } from "rxjs"; -import { debounceTime, distinctUntilChanged } from "rxjs/operators"; - -import { AuthService } from "../auth/auth.service"; -import { IRequestEngineResult, ISearchMovieResult, ISearchMovieResultContainer } from "../interfaces"; -import { NotificationService, RequestService, SearchService } from "../services"; - -@Component({ - selector: "movie-search-grid", - templateUrl: "./moviesearchgrid.component.html", -}) -export class MovieSearchGridComponent implements OnInit { - - public searchText: string; - public searchChanged: Subject = new Subject(); - public movieResults: ISearchMovieResult[]; - public movieResultGrid: ISearchMovieResultContainer[] = []; - public result: IRequestEngineResult; - public searchApplied = false; - - constructor( - private searchService: SearchService, private requestService: RequestService, - private notificationService: NotificationService, private authService: AuthService) { - - this.searchChanged.pipe( - debounceTime(600), // Wait Xms afterthe last event before emitting last event - distinctUntilChanged(), // only emit if value is different from previous value - ).subscribe(x => { - this.searchText = x as string; - if (this.searchText === "") { - this.clearResults(); - return; - } - this.searchService.searchMovie(this.searchText) - .subscribe(x => { - this.movieResults = x; - this.searchApplied = true; - // Now let's load some exta info including IMDBId - // This way the search is fast at displaying results. - this.getExtaInfo(); - }); - }); - } - - public ngOnInit() { - this.searchText = ""; - this.movieResults = []; - this.result = { - message: "", - result: false, - errorMessage: "", - }; - } - - public search(text: any) { - this.searchChanged.next(text.target.value); - } - - public request(searchResult: ISearchMovieResult) { - searchResult.requested = true; - searchResult.requestProcessing = true; - if (this.authService.hasRole("admin") || this.authService.hasRole("AutoApproveMovie")) { - searchResult.approved = true; - } - - try { - this.requestService.requestMovie({ theMovieDbId: searchResult.id, languageCode: "en" }) - .subscribe(x => { - this.result = x; - - if (this.result.result) { - this.notificationService.success( - `Request for ${searchResult.title} has been added successfully`); - searchResult.processed = true; - } else { - if (this.result.errorMessage && this.result.message) { - this.notificationService.warning("Request Added", `${this.result.message} - ${this.result.errorMessage}`); - } else { - this.notificationService.warning("Request Added", this.result.message ? this.result.message : this.result.errorMessage); - } - searchResult.requested = false; - searchResult.approved = false; - searchResult.processed = false; - searchResult.requestProcessing = false; - } - }); - } catch (e) { - - searchResult.processed = false; - searchResult.requestProcessing = false; - this.notificationService.error(e); - } - } - - public popularMovies() { - this.clearResults(); - this.searchService.popularMovies() - .subscribe(x => { - this.movieResults = x; - this.processGrid(x); - this.getExtaInfo(); - }); - } - public nowPlayingMovies() { - this.clearResults(); - this.searchService.nowPlayingMovies() - .subscribe(x => { - this.movieResults = x; - this.getExtaInfo(); - }); - } - public topRatedMovies() { - this.clearResults(); - this.searchService.topRatedMovies() - .subscribe(x => { - this.movieResults = x; - this.getExtaInfo(); - }); - } - public upcomingMovies() { - this.clearResults(); - this.searchService.upcomingMovies() - .subscribe(x => { - this.movieResults = x; - this.getExtaInfo(); - }); - } - - private getExtaInfo() { - this.movieResults.forEach((val) => { - this.searchService.getMovieInformation(val.id) - .subscribe(m => this.updateItem(val, m)); - }); - } - - private updateItem(key: ISearchMovieResult, updated: ISearchMovieResult) { - const index = this.movieResults.indexOf(key, 0); - if (index > -1) { - this.movieResults[index] = updated; - } - } - - private clearResults() { - this.movieResults = []; - this.searchApplied = false; - } - - private processGrid(movies: ISearchMovieResult[]) { - let container = { movies: [] }; - movies.forEach((movie, i) => { - i++; - if ((i % 4) === 0) { - container.movies.push(movie); - this.movieResultGrid.push(container); - container = { movies: [] }; - } else { - container.movies.push(movie); - } - }); - this.movieResultGrid.push(container); - } - -} diff --git a/src/Ombi/ClientApp/src/app/search/music/albumsearch.component.html b/src/Ombi/ClientApp/src/app/search/music/albumsearch.component.html deleted file mode 100644 index 8c06ca297..000000000 --- a/src/Ombi/ClientApp/src/app/search/music/albumsearch.component.html +++ /dev/null @@ -1,116 +0,0 @@ -
- -
-
- - -
- poster -
- - -
- - - -
- - - - - - - - - - - - - - - - - - - - - - - - Release Date: {{result.releaseDate | amLocal | amUserLocale | amDateFormat: 'L'}} - - - {{result.rating}}/10 - - - - - -
-
- - -
- -
- -
-
-
- - - - - - -
- - - - -
- -
- - - - diff --git a/src/Ombi/ClientApp/src/app/search/music/albumsearch.component.ts b/src/Ombi/ClientApp/src/app/search/music/albumsearch.component.ts deleted file mode 100644 index 1a44e120e..000000000 --- a/src/Ombi/ClientApp/src/app/search/music/albumsearch.component.ts +++ /dev/null @@ -1,91 +0,0 @@ -import { Component, EventEmitter, Input, Output } from "@angular/core"; -import { TranslateService } from "@ngx-translate/core"; - -import { Subject } from "rxjs"; -import { AuthService } from "../../auth/auth.service"; -import { IIssueCategory, IRequestEngineResult } from "../../interfaces"; -import { ISearchAlbumResult } from "../../interfaces/ISearchMusicResult"; -import { NotificationService, RequestService } from "../../services"; - -@Component({ - selector: "album-search", - templateUrl: "./albumsearch.component.html", -}) -export class AlbumSearchComponent { - - @Input() public result: ISearchAlbumResult; - public engineResult: IRequestEngineResult; - @Input() public defaultPoster: string; - - @Input() public issueCategories: IIssueCategory[]; - @Input() public issuesEnabled: boolean; - - @Input() public musicRequested: Subject; - public issuesBarVisible = false; - public issueRequestTitle: string; - public issueRequestId: number; - public issueProviderId: string; - public issueCategorySelected: IIssueCategory; - - @Output() public setSearch = new EventEmitter(); - - constructor( - private requestService: RequestService, - private notificationService: NotificationService, private authService: AuthService, - private readonly translate: TranslateService) { - } - - public selectArtist(event: Event, artistId: string) { - event.preventDefault(); - this.setSearch.emit(artistId); - } - - public reportIssue(catId: IIssueCategory, req: ISearchAlbumResult) { - this.issueRequestId = req.id; - this.issueRequestTitle = req.title + `(${req.releaseDate.getFullYear})`; - this.issueCategorySelected = catId; - this.issuesBarVisible = true; - this.issueProviderId = req.id.toString(); - } - - public request(searchResult: ISearchAlbumResult) { - searchResult.requested = true; - searchResult.requestProcessing = true; - searchResult.showSubscribe = false; - if (this.authService.hasRole("admin") || this.authService.hasRole("AutoApproveMusic")) { - searchResult.approved = true; - } - - try { - this.requestService.requestAlbum({ foreignAlbumId: searchResult.foreignAlbumId }) - .subscribe(x => { - - this.engineResult = x; - - if (this.engineResult.result) { - this.musicRequested.next(); - this.translate.get("Search.RequestAdded", { title: searchResult.title }).subscribe(x => { - this.notificationService.success(x); - searchResult.processed = true; - }); - } else { - if (this.engineResult.errorMessage && this.engineResult.message) { - this.notificationService.warning("Request Added", `${this.engineResult.message} - ${this.engineResult.errorMessage}`); - } else { - this.notificationService.warning("Request Added", this.engineResult.message ? this.engineResult.message : this.engineResult.errorMessage); - } - searchResult.requested = false; - searchResult.approved = false; - searchResult.processed = false; - searchResult.requestProcessing = false; - - } - }); - } catch (e) { - - searchResult.processed = false; - searchResult.requestProcessing = false; - this.notificationService.error(e); - } - } -} diff --git a/src/Ombi/ClientApp/src/app/search/music/artistsearch.component.html b/src/Ombi/ClientApp/src/app/search/music/artistsearch.component.html deleted file mode 100644 index 339b498a3..000000000 --- a/src/Ombi/ClientApp/src/app/search/music/artistsearch.component.html +++ /dev/null @@ -1,65 +0,0 @@ -
- -
-
-
- poster - -
-
-
- -

{{result.artistName}}

-
- - - - - {{result.artistType}} - - - {{result.disambiguation}} - - - Monitored - - - -
-
-

{{result.overview | truncate: 350 }}

- - -
- -
-
-
- - -
-
- - -
- - -
- - - - -
\ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/search/music/artistsearch.component.ts b/src/Ombi/ClientApp/src/app/search/music/artistsearch.component.ts deleted file mode 100644 index 852e294e3..000000000 --- a/src/Ombi/ClientApp/src/app/search/music/artistsearch.component.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { Component, EventEmitter, Input, Output } from "@angular/core"; - -import { ISearchAlbumResult, ISearchArtistResult } from "../../interfaces/ISearchMusicResult"; -import { SearchService } from "../../services"; - -@Component({ - selector: "artist-search", - templateUrl: "./artistsearch.component.html", -}) -export class ArtistSearchComponent { - - @Input() public result: ISearchArtistResult; - @Input() public defaultPoster: string; - public searchingAlbums: boolean; - - @Output() public viewAlbumsResult = new EventEmitter(); - - constructor(private searchService: SearchService) { - } - - public viewAllAlbums() { - this.searchingAlbums = true; - this.searchService.getAlbumsForArtist(this.result.forignArtistId).subscribe(x => { - this.viewAlbumsResult.emit(x); - }); - } -} diff --git a/src/Ombi/ClientApp/src/app/search/music/musicsearch.component.html b/src/Ombi/ClientApp/src/app/search/music/musicsearch.component.html deleted file mode 100644 index 0014ad06b..000000000 --- a/src/Ombi/ClientApp/src/app/search/music/musicsearch.component.html +++ /dev/null @@ -1,52 +0,0 @@ - -
-
- -
- -
-
-
-
- - - - -
-
- - -
-
-
-
- -
-
-
- -
-
- - - - -
- -
-
-
-
-
- -
-
-
-
- -
-
- - - diff --git a/src/Ombi/ClientApp/src/app/search/music/musicsearch.component.ts b/src/Ombi/ClientApp/src/app/search/music/musicsearch.component.ts deleted file mode 100644 index a5157d6a6..000000000 --- a/src/Ombi/ClientApp/src/app/search/music/musicsearch.component.ts +++ /dev/null @@ -1,149 +0,0 @@ -import { PlatformLocation, APP_BASE_HREF } from "@angular/common"; -import { Component, Input, OnInit, Inject } from "@angular/core"; -import { DomSanitizer } from "@angular/platform-browser"; -import { Subject } from "rxjs"; -import { debounceTime, distinctUntilChanged } from "rxjs/operators"; -import { IIssueCategory, IRequestEngineResult } from "../../interfaces"; -import { ISearchAlbumResult, ISearchArtistResult } from "../../interfaces/ISearchMusicResult"; -import { SearchService } from "../../services"; - -@Component({ - selector: "music-search", - templateUrl: "./musicsearch.component.html", -}) -export class MusicSearchComponent implements OnInit { - - public searchText: string; - public searchChanged: Subject = new Subject(); - public artistResult: ISearchArtistResult[]; - public albumResult: ISearchAlbumResult[]; - public result: IRequestEngineResult; - public searchApplied = false; - public searchAlbum: boolean = true; - - public musicRequested: Subject = new Subject(); - @Input() public issueCategories: IIssueCategory[]; - @Input() public issuesEnabled: boolean; - public issuesBarVisible = false; - public issueRequestTitle: string; - public issueRequestId: number; - public issueProviderId: string; - public issueCategorySelected: IIssueCategory; - public defaultPoster: string; - - private href: string; - constructor( - private searchService: SearchService, private sanitizer: DomSanitizer, - @Inject(APP_BASE_HREF) href:string) { -this.href = href; - this.searchChanged.pipe( - debounceTime(600), // Wait Xms after the last event before emitting last event - distinctUntilChanged(), // only emit if value is different from previous value - ).subscribe(x => { - this.searchText = x as string; - if (this.searchText === "") { - if(this.searchAlbum) { - this.clearAlbumResults(); - } else { - this.clearArtistResults(); - } - - return; - } - if(this.searchAlbum) { - if(!this.searchText) { - this.searchText = "iowa"; // REMOVE - } - this.searchService.searchAlbum(this.searchText) - .subscribe(x => { - this.albumResult = x; - this.searchApplied = true; - this.setAlbumBackground(); - }); - } else { - this.searchService.searchArtist(this.searchText) - .subscribe(x => { - this.artistResult = x; - this.searchApplied = true; - this.setArtistBackground(); - }); - } - }); - this.defaultPoster = "../../../images/default-music-placeholder.png"; - const base = this.href; - if (base) { - this.defaultPoster = "../../.." + base + "/images/default-music-placeholder.png"; - } - } - - public ngOnInit() { - this.searchText = ""; - this.artistResult = []; - this.result = { - message: "", - result: false, - errorMessage: "", - }; - } - - public search(text: any) { - this.searchChanged.next(text.target.value); - } - - public searchMode(val: boolean) { - this.searchAlbum = val; - if(val) { - // Album - this.clearArtistResults(); - } else { - this.clearAlbumResults(); - } - } - - public setArtistSearch(artistId: string) { - this.searchAlbum = false; - this.clearAlbumResults(); - this.searchChanged.next(`lidarr:${artistId}`); - } - - public viewAlbumsForArtist(albums: ISearchAlbumResult[]) { - this.clearArtistResults(); - this.searchAlbum = true; - this.albumResult = albums; - this.setAlbumBackground(); - } - - private clearArtistResults() { - this.artistResult = []; - this.searchApplied = false; - } - - private clearAlbumResults() { - this.albumResult = []; - this.searchApplied = false; - } - - private setArtistBackground() { - this.artistResult.forEach((val, index) => { - if (val.poster === null) { - val.poster = this.defaultPoster; - } - val.background = this.sanitizer.bypassSecurityTrustStyle - ("url(" + val.banner + ")"); - }); - } - - private setAlbumBackground() { - this.albumResult.forEach((val, index) => { - if (val.disk === null) { - if(val.cover === null) { - val.disk = this.defaultPoster; - } else { - val.disk = val.cover; - } - } - val.background = this.sanitizer.bypassSecurityTrustStyle - ("url(" + val.cover + ")"); - }); - } -} diff --git a/src/Ombi/ClientApp/src/app/search/search.component.html b/src/Ombi/ClientApp/src/app/search/search.component.html deleted file mode 100644 index 03cf70d11..000000000 --- a/src/Ombi/ClientApp/src/app/search/search.component.html +++ /dev/null @@ -1,35 +0,0 @@ -

-

-
- - - - - - -
- -
- -
- -
- -
-
- -
-
- - diff --git a/src/Ombi/ClientApp/src/app/search/search.component.scss b/src/Ombi/ClientApp/src/app/search/search.component.scss deleted file mode 100644 index 52ff70f0b..000000000 --- a/src/Ombi/ClientApp/src/app/search/search.component.scss +++ /dev/null @@ -1,34 +0,0 @@ -@media (max-width: 978px) { - .top-spacing { - padding-top: 5% - } - .form-control-search { - padding-right: 165px; - } - -} -@media (min-width: 979px) { - .top-spacing { - padding-top: 2% - } - .form-control-search { - width: 90%; - } -} - -.tab-content { - margin-top: 1.5em; -} - -.search-bar-background { - background-color: #333333; -} - -.vcenter { - display: flex; - align-items: center; -} - -.refine-option { - box-shadow: inset 0 1px 5px rgba(0,0,0,1.0); -} diff --git a/src/Ombi/ClientApp/src/app/search/search.component.ts b/src/Ombi/ClientApp/src/app/search/search.component.ts deleted file mode 100644 index 43d926970..000000000 --- a/src/Ombi/ClientApp/src/app/search/search.component.ts +++ /dev/null @@ -1,47 +0,0 @@ -import { Component, OnInit } from "@angular/core"; - -import { IIssueCategory } from "../interfaces"; -import { IssuesService, SettingsService } from "../services"; - -@Component({ - templateUrl: "./search.component.html", -}) -export class SearchComponent implements OnInit { - public showTv: boolean; - public showMovie: boolean; - public showMusic: boolean; - public issueCategories: IIssueCategory[]; - public issuesEnabled = false; - public musicEnabled: boolean; - - constructor(private issuesService: IssuesService, - private settingsService: SettingsService) { - - } - - public ngOnInit() { - this.settingsService.lidarrEnabled().subscribe(x => this.musicEnabled = x); - this.showMovie = true; - this.showTv = false; - this.showMusic = false; - this.issuesService.getCategories().subscribe(x => this.issueCategories = x); - this.settingsService.getIssueSettings().subscribe(x => this.issuesEnabled = x.enabled); - } - - public selectMovieTab() { - this.showMovie = true; - this.showTv = false; - this.showMusic = false; - } - - public selectTvTab() { - this.showMovie = false; - this.showTv = true; - this.showMusic = false; - } - public selectMusicTab() { - this.showMovie = false; - this.showTv = false; - this.showMusic = true; - } -} diff --git a/src/Ombi/ClientApp/src/app/search/search.module.ts b/src/Ombi/ClientApp/src/app/search/search.module.ts deleted file mode 100644 index d0a3f0e78..000000000 --- a/src/Ombi/ClientApp/src/app/search/search.module.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { CommonModule } from "@angular/common"; -import { NgModule } from "@angular/core"; -import { FormsModule } from "@angular/forms"; -import { RouterModule, Routes } from "@angular/router"; - - -import { MovieSearchComponent } from "./moviesearch.component"; -import { MovieSearchGridComponent } from "./moviesearchgrid.component"; -import { AlbumSearchComponent } from "./music/albumsearch.component"; -import { ArtistSearchComponent } from "./music/artistsearch.component"; -import { MusicSearchComponent } from "./music/musicsearch.component"; -import { SearchComponent } from "./search.component"; -import { SeriesInformationComponent } from "./seriesinformation.component"; -import { TvSearchComponent } from "./tvsearch.component"; - -import { CardsFreeModule } from "angular-bootstrap-md"; - -import { RequestService } from "../services"; -import { SearchService } from "../services"; - -import { AuthGuard } from "../auth/auth.guard"; - -import { RemainingRequestsComponent } from "../requests/remainingrequests.component"; -import { SharedModule } from "../shared/shared.module"; - -const routes: Routes = [ - { path: "", component: SearchComponent, canActivate: [AuthGuard] }, - { path: "show/:id", component: SeriesInformationComponent, canActivate: [AuthGuard] }, -]; -@NgModule({ - imports: [ - CommonModule, - FormsModule, - RouterModule.forChild(routes), - TreeTableModule, - SharedModule, - SidebarModule, - TooltipModule, - CardsFreeModule, - ], - declarations: [ - SearchComponent, - MovieSearchComponent, - TvSearchComponent, - SeriesInformationComponent, - MovieSearchGridComponent, - RemainingRequestsComponent, - MusicSearchComponent, - ArtistSearchComponent, - AlbumSearchComponent, - ], - exports: [ - RouterModule, - ], - providers: [ - SearchService, - RequestService, - ], -}) -export class SearchModule { } diff --git a/src/Ombi/ClientApp/src/app/search/seriesinformation.component.html b/src/Ombi/ClientApp/src/app/search/seriesinformation.component.html deleted file mode 100644 index 97309e4ff..000000000 --- a/src/Ombi/ClientApp/src/app/search/seriesinformation.component.html +++ /dev/null @@ -1,71 +0,0 @@ -
- - - - -
- - -

Season: {{season.seasonNumber}}

- - -
"); sb.Append(""); sb.Append(""); - await ProcessAlbums(albums, sb); + await ProcessAlbums(albums); sb.Append(""); sb.Append("
"); sb.Append("
- + {{ 'Issues.Details' | translate}} - - + {{ 'Requests.Details' | translate}} + {{ 'Requests.RequestDate' | translate}} {{element.requestedDate | amLocal | amUserLocale | amDateFormat: 'LL'}} {{getRequestDate(element) | amLocal | amUserLocale | amDateFormat: 'LL'}} {{element.status |translateStatus }} {{ 'Requests.Has4KRequest' | translate}} + + + {{ 'Requests.RequestStatus' | translate}} - - + {{ 'Requests.Details' | translate}} + {{ 'Requests.Options' | translate}} - + {{'Requests.Details' | translate}}
- - - - - - - - - - - - - - - - - - - -
- - # - - - - Title - - - - Air Date - - - - Status - -
- {{ep.episodeNumber}} - - {{ep.title}} - - {{ep.airDate | amLocal | amUserLocale | amDateFormat: 'L' }} - - {{ep.airDateDisplay }} - - Available - Processing Request - Selected - Pending Approval - Not Requested - - - -
- - - - - - diff --git a/src/Ombi/ClientApp/src/app/search/seriesinformation.component.scss b/src/Ombi/ClientApp/src/app/search/seriesinformation.component.scss deleted file mode 100644 index c7dca5e86..000000000 --- a/src/Ombi/ClientApp/src/app/search/seriesinformation.component.scss +++ /dev/null @@ -1,25 +0,0 @@ -#requestFloatingBtn { - position: fixed; /* Fixed/sticky position */ - bottom: 20px; /* Place the button at the bottom of the page */ - right: 30px; /* Place the button 30px from the right */ - z-index: 99; /* Make sure it does not overlap */ - cursor: pointer; /* Add a mouse pointer on hover */ - padding: 15px; /* Some padding */ - border-radius: 10px; /* Rounded corners */ -} - - #requestFloatingBtn:hover { - background-color: #555; /* Add a dark-grey background on hover */ - } - - #bannerimage { - width: 758px; - height: 140px; - background-color: black; - background-position: center; - padding-bottom:30px; - } - - .content-space { - padding-top: 10px; - } \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/search/seriesinformation.component.ts b/src/Ombi/ClientApp/src/app/search/seriesinformation.component.ts deleted file mode 100644 index 6a918a69a..000000000 --- a/src/Ombi/ClientApp/src/app/search/seriesinformation.component.ts +++ /dev/null @@ -1,98 +0,0 @@ -import { Component, Input, OnInit } from "@angular/core"; - -import { NotificationService } from "../services"; -import { RequestService } from "../services"; -import { SearchService } from "../services"; - -import { INewSeasonRequests, IRequestEngineResult, ISeasonsViewModel, ITvRequestViewModel } from "../interfaces"; -import { IEpisodesRequests } from "../interfaces"; -import { ISearchTvResult } from "../interfaces"; - -import { Subject } from "rxjs"; - -@Component({ - selector: "seriesinformation", - templateUrl: "./seriesinformation.component.html", - styleUrls: ["./seriesinformation.component.scss"], -}) -export class SeriesInformationComponent implements OnInit { - - public result: IRequestEngineResult; - public series: ISearchTvResult; - public requestedEpisodes: IEpisodesRequests[] = []; - @Input() public tvRequested: Subject; - @Input() private seriesId: number; - - constructor(private searchService: SearchService, private requestService: RequestService, private notificationService: NotificationService) { } - - public ngOnInit() { - this.searchService.getShowInformation(this.seriesId) - .subscribe(x => { - this.series = x; - }); - } - - public submitRequests() { - // Make sure something has been selected - const selected = this.series.seasonRequests.some((season) => { - return season.episodes.some((ep) => { - return ep.selected; - }); - }); - - if (!selected) { - this.notificationService.error("You need to select some episodes!"); - return; - } - - this.series.requested = true; - - const viewModel = { firstSeason: this.series.firstSeason, latestSeason: this.series.latestSeason, requestAll: this.series.requestAll, tvDbId: this.series.id}; - viewModel.seasons = []; - this.series.seasonRequests.forEach((season) => { - const seasonsViewModel = {seasonNumber: season.seasonNumber, episodes: []}; - season.episodes.forEach(ep => { - if (!this.series.latestSeason || !this.series.requestAll || !this.series.firstSeason) { - if (ep.selected) { - seasonsViewModel.episodes.push({episodeNumber: ep.episodeNumber}); - } - } - }); - - viewModel.seasons.push(seasonsViewModel); - }); - - this.requestService.requestTv(viewModel) - .subscribe(x => { - this.tvRequested.next(); - this.result = x as IRequestEngineResult; - if (this.result.result) { - this.notificationService.success( - `Request for ${this.series.title} has been added successfully`); - - this.series.seasonRequests.forEach((season) => { - season.episodes.forEach((ep) => { - ep.selected = false; - }); - }); - - } else { - this.notificationService.warning("Request Added", this.result.errorMessage ? this.result.errorMessage : this.result.message); - } - }); - } - - public addRequest(episode: IEpisodesRequests) { - episode.requested = true; - episode.selected = true; - } - - public removeRequest(episode: IEpisodesRequests) { - episode.requested = false; - episode.selected = false; - } - - public addAllEpisodes(season: INewSeasonRequests) { - season.episodes.forEach((ep) => this.addRequest(ep)); - } -} diff --git a/src/Ombi/ClientApp/src/app/search/tvsearch.component.html b/src/Ombi/ClientApp/src/app/search/tvsearch.component.html deleted file mode 100644 index 51b61e0a4..000000000 --- a/src/Ombi/ClientApp/src/app/search/tvsearch.component.html +++ /dev/null @@ -1,185 +0,0 @@ - -
- - - - -
- -
-
- -
- -
-
- -
- -
- - - - -
-
- - -
- -
- -
{{ 'Search.NoResults' | translate }}
-
-
-
- -
-
- -
-
-
- - poster - -
-
-
- - -

{{node.title}} ({{node.firstAired | amLocal | amDateFormat: 'YYYY'}})

- -
- - - {{ 'Search.Movies.HomePage' | translate }} - - - - {{ 'Search.Movies.Trailer' | translate }} - - - {{node.status}} - - - {{ 'Search.TvShows.AirDate' | translate }} {{node.firstAired | amLocal | amUserLocale | amDateFormat: 'L'}} - - {{node.network}} - - - {{ 'Common.Available' | translate }} - - {{ 'Common.PartlyAvailable' | translate }} - - - - - -
-
-
-

{{node.overview}}

-
- - -
- - -
- -
-
- - - - -
-
-
-
- -
- -
-
- -
- -
- -
-
-
-
-
-
- - - diff --git a/src/Ombi/ClientApp/src/app/search/tvsearch.component.ts b/src/Ombi/ClientApp/src/app/search/tvsearch.component.ts deleted file mode 100644 index 5f65f3192..000000000 --- a/src/Ombi/ClientApp/src/app/search/tvsearch.component.ts +++ /dev/null @@ -1,238 +0,0 @@ -import { PlatformLocation, APP_BASE_HREF } from "@angular/common"; -import { Component, Input, OnInit, Inject } from "@angular/core"; -import { DomSanitizer } from "@angular/platform-browser"; -import { Subject } from "rxjs"; -import { debounceTime, distinctUntilChanged } from "rxjs/operators"; - -import { AuthService } from "../auth/auth.service"; -import { IIssueCategory, IRequestEngineResult, ISearchTvResult, ISeasonsViewModel, ITvRequestViewModel } from "../interfaces"; -import { ImageService, NotificationService, RequestService, SearchService } from "../services"; - -@Component({ - selector: "tv-search", - templateUrl: "./tvsearch.component.html", - styleUrls: ["./../requests/tvrequests.component.scss"], -}) -export class TvSearchComponent implements OnInit { - - public searchText: string; - public searchChanged = new Subject(); - public tvResults: ISearchTvResult[]; - public tvRequested: Subject = new Subject(); - public result: IRequestEngineResult; - public searchApplied = false; - public defaultPoster: string; - - @Input() public issueCategories: IIssueCategory[]; - @Input() public issuesEnabled: boolean; - public issuesBarVisible = false; - public issueRequestTitle: string; - public issueRequestId: number; - public issueProviderId: string; - public issueCategorySelected: IIssueCategory; - private href: string; - - constructor( - private searchService: SearchService, private requestService: RequestService, - private notificationService: NotificationService, private authService: AuthService, - private imageService: ImageService, private sanitizer: DomSanitizer, - @Inject(APP_BASE_HREF) href:string) { -this.href = href; - this.searchChanged.pipe( - debounceTime(600), // Wait Xms after the last event before emitting last event - distinctUntilChanged(), // only emit if value is different from previous value - ).subscribe(x => { - this.searchText = x as string; - if (this.searchText === "") { - this.clearResults(); - return; - } - this.searchService.searchTv(this.searchText) - .subscribe(x => { - this.tvResults = x; - this.searchApplied = true; - this.getExtraInfo(); - }); - }); - this.defaultPoster = "../../../images/default_tv_poster.png"; - const base = this.href; - if (base) { - this.defaultPoster = "../../.." + base + "/images/default_tv_poster.png"; - } - } - public openClosestTab(node: ISearchTvResult,el: any) { - el.preventDefault(); - node.open = !node.open; - } - - public ngOnInit() { - this.searchText = ""; - this.tvResults = []; - this.result = { - message: "", - result: false, - errorMessage: "", - }; - this.popularShows(); - } - - public search(text: any) { - this.searchChanged.next(text.target.value); - } - - public popularShows() { - this.clearResults(); - this.searchService.popularTv() - .subscribe(x => { - this.tvResults = x; - this.getExtraInfo(); - }); - } - - public trendingShows() { - this.clearResults(); - this.searchService.trendingTv() - .subscribe(x => { - this.tvResults = x; - this.getExtraInfo(); - }); - } - - public mostWatchedShows() { - this.clearResults(); - this.searchService.mostWatchedTv() - .subscribe(x => { - this.tvResults = x; - this.getExtraInfo(); - }); - } - - public anticipatedShows() { - this.clearResults(); - this.searchService.anticipatedTv() - .subscribe(x => { - this.tvResults = x; - this.getExtraInfo(); - }); - } - - public getExtraInfo() { - this.tvResults.forEach((val, index) => { - this.imageService.getTvBanner(val.id).subscribe(x => { - if (x) { - val.background = this.sanitizer. - bypassSecurityTrustStyle - ("url(" + x + ")"); - } - }); - this.searchService.getShowInformation(val.id) - .subscribe(x => { - if (x) { - this.setDefaults(x); - this.updateItem(val, x); - } else { - const index = this.tvResults.indexOf(val, 0); - if (index > -1) { - this.tvResults.splice(index, 1); - } - } - }); - }); - } - - public request(searchResult: ISearchTvResult) { - searchResult.requested = true; - if (this.authService.hasRole("admin") || this.authService.hasRole("AutoApproveMovie")) { - searchResult.approved = true; - } - - const viewModel = { firstSeason: searchResult.firstSeason, latestSeason: searchResult.latestSeason, requestAll: searchResult.requestAll, tvDbId: searchResult.id }; - viewModel.seasons = []; - searchResult.seasonRequests.forEach((season) => { - const seasonsViewModel = { seasonNumber: season.seasonNumber, episodes: [] }; - season.episodes.forEach(ep => { - if (!searchResult.latestSeason || !searchResult.requestAll || !searchResult.firstSeason) { - if (ep.requested) { - seasonsViewModel.episodes.push({ episodeNumber: ep.episodeNumber }); - } - } - }); - - viewModel.seasons.push(seasonsViewModel); - }); - - this.requestService.requestTv(viewModel) - .subscribe(x => { - this.tvRequested.next(); - this.result = x; - if (this.result.result) { - this.notificationService.success( - `Request for ${searchResult.title} has been added successfully`); - } else { - if (this.result.errorMessage && this.result.message) { - this.notificationService.warning("Request Added", `${this.result.message} - ${this.result.errorMessage}`); - } else { - this.notificationService.warning("Request Added", this.result.message ? this.result.message : this.result.errorMessage); - } - } - }); - } - - public allSeasons(searchResult: ISearchTvResult, event: any) { - event.preventDefault(); - searchResult.requestAll = true; - this.request(searchResult); - } - - public firstSeason(searchResult: ISearchTvResult, event: any) { - event.preventDefault(); - searchResult.firstSeason = true; - this.request(searchResult); - } - - public latestSeason(searchResult: ISearchTvResult, event: any) { - event.preventDefault(); - searchResult.latestSeason = true; - this.request(searchResult); - } - - public reportIssue(catId: IIssueCategory, req: ISearchTvResult) { - this.issueRequestId = req.id; - const firstAiredDate = new Date(req.firstAired); - this.issueRequestTitle = req.title + ` (${firstAiredDate.getFullYear()})`; - this.issueCategorySelected = catId; - this.issuesBarVisible = true; - this.issueProviderId = req.id.toString(); - } - - private updateItem(key: ISearchTvResult, updated: ISearchTvResult) { - const index = this.tvResults.indexOf(key, 0); - if (index > -1) { - // Update certain properties, otherwise we will loose some data - this.tvResults[index].title = updated.title; - this.tvResults[index].banner = updated.banner; - this.tvResults[index].imdbId = updated.imdbId; - this.tvResults[index].seasonRequests = updated.seasonRequests; - this.tvResults[index].seriesId = updated.seriesId; - this.tvResults[index].fullyAvailable = updated.fullyAvailable; - this.tvResults[index].background = updated.banner; - } - } - - private setDefaults(x: ISearchTvResult) { - if (x.banner === null) { - x.banner = this.defaultPoster; - } - - if (x.imdbId === null) { - x.imdbId = "https://www.tvmaze.com/shows/" + x.seriesId; - } else { - x.imdbId = "http://www.imdb.com/title/" + x.imdbId + "/"; - } - } - - private clearResults() { - this.tvResults = []; - this.searchApplied = false; - } -} diff --git a/src/Ombi/ClientApp/src/app/services/applications/plextv.service.ts b/src/Ombi/ClientApp/src/app/services/applications/plextv.service.ts index 3ce0e0a8b..4a492ccae 100644 --- a/src/Ombi/ClientApp/src/app/services/applications/plextv.service.ts +++ b/src/Ombi/ClientApp/src/app/services/applications/plextv.service.ts @@ -1,10 +1,8 @@ -import { PlatformLocation, APP_BASE_HREF } from "@angular/common"; -import { HttpClient, HttpHeaders } from "@angular/common/http"; -import { Injectable, Inject } from "@angular/core"; - -import { Observable } from "rxjs"; +import { HttpClient, HttpHeaders } from "@angular/common/http"; import { IPlexPin } from "../../interfaces"; +import { Injectable } from "@angular/core"; +import { Observable } from "rxjs"; @Injectable() export class PlexTvService { @@ -13,7 +11,7 @@ export class PlexTvService { } public GetPin(clientId: string, applicationName: string): Observable { - const headers = new HttpHeaders({"Content-Type": "application/json", + const headers = new HttpHeaders({"Content-Type": "application/json; charset=ISO-8859-1", "X-Plex-Client-Identifier": clientId, "X-Plex-Product": applicationName, "X-Plex-Version": "3", diff --git a/src/Ombi/ClientApp/src/app/services/applications/themoviedb.service.ts b/src/Ombi/ClientApp/src/app/services/applications/themoviedb.service.ts index a49fb4146..d2c5b6122 100644 --- a/src/Ombi/ClientApp/src/app/services/applications/themoviedb.service.ts +++ b/src/Ombi/ClientApp/src/app/services/applications/themoviedb.service.ts @@ -25,10 +25,6 @@ export class TheMovieDbService extends ServiceHelpers { .pipe(catchError((error: HttpErrorResponse) => error.status === 404 ? empty() : throwError(error))); } - public getGenres(media: string): Observable { - return this.http.get(`${this.url}/Genres/${media}`, { headers: this.headers }) - } - public getWatchProviders(media: string): Observable { return this.http.get(`${this.url}/WatchProviders/${media}`, {headers: this.headers}); } diff --git a/src/Ombi/ClientApp/src/app/services/feature.service.ts b/src/Ombi/ClientApp/src/app/services/feature.service.ts new file mode 100644 index 000000000..18a9cf86f --- /dev/null +++ b/src/Ombi/ClientApp/src/app/services/feature.service.ts @@ -0,0 +1,27 @@ +import { APP_BASE_HREF } from "@angular/common"; +import { Injectable, Inject } from "@angular/core"; + +import { HttpClient } from "@angular/common/http"; +import { Observable } from "rxjs"; + +import { IFeatureEnablement } from "../interfaces"; +import { ServiceHelpers } from "./service.helpers"; + +@Injectable({ providedIn: "root" }) +export class FeatureService extends ServiceHelpers { + constructor(http: HttpClient, @Inject(APP_BASE_HREF) href:string) { + super(http, "/api/v2/Features/", href); + } + + public getFeatures(): Observable { + return this.http.get(this.url, {headers: this.headers}); + } + + public enable(feature: IFeatureEnablement): Observable { + return this.http.post(`${this.url}enable`, JSON.stringify(feature), {headers: this.headers}); + } + + public disable(feature: IFeatureEnablement): Observable { + return this.http.post(`${this.url}disable`, JSON.stringify(feature), {headers: this.headers}); + } +} diff --git a/src/Ombi/ClientApp/src/app/services/filedownload.service.ts b/src/Ombi/ClientApp/src/app/services/filedownload.service.ts index 59cc00def..88e7cd441 100644 --- a/src/Ombi/ClientApp/src/app/services/filedownload.service.ts +++ b/src/Ombi/ClientApp/src/app/services/filedownload.service.ts @@ -1,3 +1,9 @@ +// https://github.com/microsoft/TypeScript/issues/45612 +declare global { + interface Navigator { + msSaveOrOpenBlob: (blob: Blob) => void + } +} import { APP_BASE_HREF } from "@angular/common"; import { Injectable, Inject } from "@angular/core"; diff --git a/src/Ombi/ClientApp/src/app/services/helpers/validation.service.ts b/src/Ombi/ClientApp/src/app/services/helpers/validation.service.ts index 7b8deec89..19ec1549a 100644 --- a/src/Ombi/ClientApp/src/app/services/helpers/validation.service.ts +++ b/src/Ombi/ClientApp/src/app/services/helpers/validation.service.ts @@ -1,5 +1,5 @@ import { Injectable } from "@angular/core"; -import { FormGroup, ValidatorFn, Validators } from "@angular/forms"; +import { UntypedFormGroup, ValidatorFn, Validators } from "@angular/forms"; @Injectable() export class ValidationService { @@ -9,7 +9,7 @@ export class ValidationService { * @param form * @param name */ - public disableValidation(form: FormGroup, name: string) { + public disableValidation(form: UntypedFormGroup, name: string) { form.controls[name].clearValidators(); form.controls[name].updateValueAndValidity(); } @@ -19,8 +19,8 @@ export class ValidationService { * @param form * @param name */ - public enableValidation(form: FormGroup, name: string): void; - public enableValidation(form: FormGroup, name: string, validators?: ValidatorFn[]) { + public enableValidation(form: UntypedFormGroup, name: string): void; + public enableValidation(form: UntypedFormGroup, name: string, validators?: ValidatorFn[]) { if (validators) { // If we provide some use them form.controls[name].setValidators(validators); diff --git a/src/Ombi/ClientApp/src/app/services/image.service.ts b/src/Ombi/ClientApp/src/app/services/image.service.ts index 521a207e3..c46876d73 100644 --- a/src/Ombi/ClientApp/src/app/services/image.service.ts +++ b/src/Ombi/ClientApp/src/app/services/image.service.ts @@ -1,10 +1,10 @@ -import { PlatformLocation, APP_BASE_HREF } from "@angular/common"; +import { APP_BASE_HREF } from "@angular/common"; import { Injectable, Inject } from "@angular/core"; import { Observable } from "rxjs"; import { HttpClient } from "@angular/common/http"; -import { IImages } from "../interfaces"; +import { IImages, IImagesInfo } from "../interfaces"; import { ServiceHelpers } from "./service.helpers"; @Injectable() @@ -17,6 +17,10 @@ export class ImageService extends ServiceHelpers { return this.http.get(`${this.url}background/`, {headers: this.headers}); } + public getRandomBackgroundWithInfo(): Observable { + return this.http.get(`${this.url}background/info`, {headers: this.headers}); + } + public getTvBanner(tvdbid: number): Observable { return this.http.get(`${this.url}tv/${tvdbid}`, {headers: this.headers}); } @@ -31,8 +35,9 @@ export class ImageService extends ServiceHelpers { public getMovieBackground(movieDbId: string): Observable { return this.http.get(`${this.url}background/movie/${movieDbId}`, { headers: this.headers }); - } - public getMovieBanner(movieDbId: string): Observable { + } + + public getMovieBanner(movieDbId: string): Observable { return this.http.get(`${this.url}banner/movie/${movieDbId}`, { headers: this.headers }); } diff --git a/src/Ombi/ClientApp/src/app/services/job.service.ts b/src/Ombi/ClientApp/src/app/services/job.service.ts index 24b5e9a52..6cece68d9 100644 --- a/src/Ombi/ClientApp/src/app/services/job.service.ts +++ b/src/Ombi/ClientApp/src/app/services/job.service.ts @@ -27,6 +27,10 @@ export class JobService extends ServiceHelpers { return this.http.post(`${this.url}plexUserImporter/`, {headers: this.headers}); } + public runPlexWatchlistImport(): Observable { + return this.http.post(`${this.url}plexwatchlist/`, {headers: this.headers}); + } + public runEmbyImporter(): Observable { return this.http.post(`${this.url}embyUserImporter/`, {headers: this.headers}); } @@ -43,6 +47,10 @@ export class JobService extends ServiceHelpers { return this.http.post(`${this.url}plexrecentlyadded/`, {headers: this.headers}); } + public runEmbyRecentlyAddedCacher(): Observable { + return this.http.post(`${this.url}embyrecentlyadded/`, {headers: this.headers}); + } + public clearMediaserverData(): Observable { return this.http.post(`${this.url}clearmediaserverdata/`, {headers: this.headers}); } diff --git a/src/Ombi/ClientApp/src/app/services/message.service.ts b/src/Ombi/ClientApp/src/app/services/message.service.ts index be1df37be..995bc0f89 100644 --- a/src/Ombi/ClientApp/src/app/services/message.service.ts +++ b/src/Ombi/ClientApp/src/app/services/message.service.ts @@ -22,11 +22,15 @@ export class MessageService { } public sendRequestEngineResultError(result: IRequestEngineResult, action: string = "Ok") { const textKey = 'Requests.ErrorCodes.' + result.errorCode; - const text = this.translate.instant(textKey); - if (text !== textKey) { - this.send(text, action); - } else { - this.send(result.errorMessage ? result.errorMessage : result.message, action); + var text = this.translate.instant(textKey); + if (text === textKey) { // Error code on backend may not exist in frontend + if (result.errorMessage || result.message) { + text = result.errorMessage ? result.errorMessage : result.message; + } else { + text = this.translate.instant('ErrorPages.SomethingWentWrong'); + } } + + this.send(text, action); } } diff --git a/src/Ombi/ClientApp/src/app/services/request.service.ts b/src/Ombi/ClientApp/src/app/services/request.service.ts index 3fe60e5f3..d850f5d83 100644 --- a/src/Ombi/ClientApp/src/app/services/request.service.ts +++ b/src/Ombi/ClientApp/src/app/services/request.service.ts @@ -73,8 +73,8 @@ export class RequestService extends ServiceHelpers { this.http.delete(`${this.url}movie/${requestId}`, {headers: this.headers}).subscribe(); } - public removeMovieRequestAsync(requestId: number) { - return this.http.delete(`${this.url}movie/${requestId}`, {headers: this.headers}).toPromise(); + public removeMovieRequestAsync(requestId: number): Observable { + return this.http.delete(`${this.url}movie/${requestId}`, {headers: this.headers}); } public updateMovieRequest(request: IMovieRequests): Observable { @@ -128,8 +128,9 @@ export class RequestService extends ServiceHelpers { public approveChild(child: ITvUpdateModel): Observable { return this.http.post(`${this.url}tv/approve`, JSON.stringify(child), {headers: this.headers}); } - public deleteChild(childId: number): Observable { - return this.http.delete(`${this.url}tv/child/${childId}`, {headers: this.headers}); + + public deleteChild(childId: number): Observable { + return this.http.delete(`${this.url}tv/child/${childId}`, {headers: this.headers}); } public subscribeToMovie(requestId: number): Observable { @@ -184,7 +185,7 @@ export class RequestService extends ServiceHelpers { return this.http.get(`${this.url}music/search/${search}`, {headers: this.headers}); } - public removeAlbumRequest(request: number): any { - return this.http.delete(`${this.url}music/${request}`, {headers: this.headers}); + public removeAlbumRequest(request: number): Observable { + return this.http.delete(`${this.url}music/${request}`, {headers: this.headers}); } } diff --git a/src/Ombi/ClientApp/src/app/services/requestV2.service.ts b/src/Ombi/ClientApp/src/app/services/requestV2.service.ts index 433547b8f..62ff11aef 100644 --- a/src/Ombi/ClientApp/src/app/services/requestV2.service.ts +++ b/src/Ombi/ClientApp/src/app/services/requestV2.service.ts @@ -93,8 +93,8 @@ export class RequestServiceV2 extends ServiceHelpers { return this.http.post(`${this.url}TV/`, JSON.stringify(tv), {headers: this.headers}); } - public reprocessRequest(requestId: number, type: RequestType): Observable { - return this.http.post(`${this.url}reprocess/${type}/${requestId}`, undefined, { headers: this.headers }); + public reprocessRequest(requestId: number, type: RequestType, is4K: boolean): Observable { + return this.http.post(`${this.url}reprocess/${type}/${requestId}/${is4K}`, undefined, { headers: this.headers }); } public requestMovieCollection(collectionId: number): Observable { diff --git a/src/Ombi/ClientApp/src/app/services/searchV2.service.ts b/src/Ombi/ClientApp/src/app/services/searchV2.service.ts index 348db936b..56b1057c6 100644 --- a/src/Ombi/ClientApp/src/app/services/searchV2.service.ts +++ b/src/Ombi/ClientApp/src/app/services/searchV2.service.ts @@ -4,7 +4,7 @@ import { Injectable, Inject } from "@angular/core"; import { HttpClient } from "@angular/common/http"; import { Observable } from "rxjs"; -import { IDiscoverModel, IMultiSearchResult, ISearchMovieResult, ISearchTvResult } from "../interfaces"; +import { IDiscoverModel, ILanguage, IMovieDbKeyword, IMultiSearchResult, ISearchMovieResult, ISearchTvResult } from "../interfaces"; import { ServiceHelpers } from "./service.helpers"; import { ISearchMovieResultV2 } from "../interfaces/ISearchMovieResultV2"; @@ -21,8 +21,17 @@ export class SearchV2Service extends ServiceHelpers { } public multiSearch(searchTerm: string, filter: SearchFilter): Observable { - return this.http.post(`${this.url}/multi/${searchTerm}`, filter); + return this.http.post(`${this.url}/multi/${encodeURIComponent(searchTerm)}`, filter); } + + public getGenres(media: string): Observable { + return this.http.get(`${this.url}/Genres/${media}`, { headers: this.headers }) + } + + public getLanguages(): Observable { + return this.http.get(`${this.url}/Languages`, { headers: this.headers }) + } + public getFullMovieDetails(theMovieDbId: number): Observable { return this.http.get(`${this.url}/Movie/${theMovieDbId}`); } @@ -132,6 +141,10 @@ export class SearchV2Service extends ServiceHelpers { return this.http.get(`${this.url}/actor/${actorId}/movie`, { headers: this.headers }); } + public getTvByActor(actorId: number): Observable { + return this.http.get(`${this.url}/actor/${actorId}/tv`, { headers: this.headers }); + } + public getArtistInformation(artistId: string): Observable { return this.http.get(`${this.url}/artist/${artistId}`); } diff --git a/src/Ombi/ClientApp/src/app/services/settings.service.ts b/src/Ombi/ClientApp/src/app/services/settings.service.ts index 3f4409d0c..4758c8382 100644 --- a/src/Ombi/ClientApp/src/app/services/settings.service.ts +++ b/src/Ombi/ClientApp/src/app/services/settings.service.ts @@ -39,6 +39,7 @@ import { IVoteSettings, ITwilioSettings, IWebhookNotificationSettings, + IRadarrCombined, } from "../interfaces"; import { ServiceHelpers } from "./service.helpers"; @@ -101,11 +102,11 @@ export class SettingsService extends ServiceHelpers { return this.http.post(`${this.url}/Sonarr`, JSON.stringify(settings), {headers: this.headers}); } - public getRadarr(): Observable { - return this.http.get(`${this.url}/Radarr`, {headers: this.headers}); + public getRadarr(): Observable { + return this.http.get(`${this.url}/Radarr`, {headers: this.headers}); } - public saveRadarr(settings: IRadarrSettings): Observable { + public saveRadarr(settings: IRadarrCombined): Observable { return this.http.post(`${this.url}/Radarr`, JSON.stringify(settings), {headers: this.headers}); } diff --git a/src/Ombi/ClientApp/src/app/services/signlarnotification.service.ts b/src/Ombi/ClientApp/src/app/services/signlarnotification.service.ts index 2597fff54..24b4e3363 100644 --- a/src/Ombi/ClientApp/src/app/services/signlarnotification.service.ts +++ b/src/Ombi/ClientApp/src/app/services/signlarnotification.service.ts @@ -1,8 +1,8 @@ import { Injectable, EventEmitter } from '@angular/core'; import { AuthService } from '../auth/auth.service'; -import { HubConnection } from '@aspnet/signalr'; -import * as signalR from '@aspnet/signalr'; +import { HubConnection } from '@microsoft/signalr'; +import * as signalR from '@microsoft/signalr'; @Injectable() export class SignalRNotificationService { diff --git a/src/Ombi/ClientApp/src/app/settings/about/about.component.html b/src/Ombi/ClientApp/src/app/settings/about/about.component.html index b823bdc7a..acbf78f43 100644 --- a/src/Ombi/ClientApp/src/app/settings/about/about.component.html +++ b/src/Ombi/ClientApp/src/app/settings/about/about.component.html @@ -1,6 +1,10 @@ +
About +
@@ -71,23 +75,23 @@
Application Base Path
{{about.applicationBasePath}}
-
- +
+
Storage Path
{{about.storagePath}}
-
- +
+
Ombi Database
{{about.ombiDatabaseType}}
-
- +
+
External Database
{{about.externalDatabaseType}}
-
- +
+
Settings Database
{{about.settingsDatabaseType}}
@@ -97,6 +101,10 @@
+
+ Get it on Google Play + Get it on App Store +

News

diff --git a/src/Ombi/ClientApp/src/app/settings/about/about.component.scss b/src/Ombi/ClientApp/src/app/settings/about/about.component.scss index daeccd03a..55d4a9765 100644 --- a/src/Ombi/ClientApp/src/app/settings/about/about.component.scss +++ b/src/Ombi/ClientApp/src/app/settings/about/about.component.scss @@ -1,4 +1,6 @@ -.mat-table { +@import "~styles/variables.scss"; + +.mat-table { display: block; } @@ -37,4 +39,13 @@ white-space: nowrap; vertical-align: baseline; border-radius: 0.25rem; - } \ No newline at end of file + } + + .container-alert { + margin-left: 3%; + margin-right: 3%; + color: white; + background-color: $ombi-background-accent; + border-color: $warn; + } + diff --git a/src/Ombi/ClientApp/src/app/settings/about/about.component.ts b/src/Ombi/ClientApp/src/app/settings/about/about.component.ts index 688669c01..fc10c5181 100644 --- a/src/Ombi/ClientApp/src/app/settings/about/about.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/about/about.component.ts @@ -1,10 +1,12 @@ -import { Component, OnInit } from "@angular/core"; +import { Component, Inject, OnInit } from "@angular/core"; +import { HubService, SettingsService, SystemService } from "../../services"; import { IAbout, IUpdateModel } from "../../interfaces/ISettings"; -import { SettingsService, HubService, SystemService } from "../../services"; + import { IConnectedUser } from "../../interfaces"; -import { UpdateService } from "../../services/update.service"; import { MatDialog } from "@angular/material/dialog"; import { UpdateDialogComponent } from "./update-dialog.component"; +import { UpdateService } from "../../services/update.service"; +import { APP_BASE_HREF } from "@angular/common"; @Component({ templateUrl: "./about.component.html", @@ -16,6 +18,16 @@ export class AboutComponent implements OnInit { public newUpdate: boolean; public connectedUsers: IConnectedUser[]; public newsHtml: string; + public appstoreImage: string; + + public get usingSqliteDatabase() { + if (this.about.ombiDatabaseType.toLowerCase() === 'sqlite' + || this.about.externalDatabaseType.toLowerCase() === 'sqlite' + || this.about.settingsDatabaseType.toLowerCase() === 'sqlite') { + return true; + } + return false; + } private update: IUpdateModel; @@ -23,9 +35,15 @@ export class AboutComponent implements OnInit { private readonly jobService: UpdateService, private readonly hubService: HubService, private readonly systemService: SystemService, - private readonly dialog: MatDialog) { } + private readonly dialog: MatDialog, + @Inject(APP_BASE_HREF) private readonly href:string) { } public async ngOnInit() { + this.appstoreImage = "../../../images/appstore.svg"; + const base = this.href; + if (base) { + this.appstoreImage = "../../.." + base + "/images/appstore.svg"; + } this.settingsService.about().subscribe(x => this.about = x); this.newsHtml = await this.systemService.getNews().toPromise(); diff --git a/src/Ombi/ClientApp/src/app/settings/authentication/authentication.component.html b/src/Ombi/ClientApp/src/app/settings/authentication/authentication.component.html index 7bc6a4e80..5960c79f7 100644 --- a/src/Ombi/ClientApp/src/app/settings/authentication/authentication.component.html +++ b/src/Ombi/ClientApp/src/app/settings/authentication/authentication.component.html @@ -1,66 +1,46 @@ - +
Authentication
-
-
- - Allow users to login without a password -
-
+
+
+ + Allow users to login without a password + +
+
-
-
- Enable Plex OAuth -
-
+
+
+ Enable Plex OAuth +
+
- - -
-
-
-
-
-
+
+
+
+
+
+
-
\ No newline at end of file + diff --git a/src/Ombi/ClientApp/src/app/settings/authentication/authentication.component.ts b/src/Ombi/ClientApp/src/app/settings/authentication/authentication.component.ts index 6f140f8af..80135b195 100644 --- a/src/Ombi/ClientApp/src/app/settings/authentication/authentication.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/authentication/authentication.component.ts @@ -1,5 +1,5 @@ -import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup } from "@angular/forms"; +import { Component, OnInit } from "@angular/core"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { NotificationService } from "../../services"; import { SettingsService } from "../../services"; @@ -10,11 +10,11 @@ import { SettingsService } from "../../services"; }) export class AuthenticationComponent implements OnInit { - public form: FormGroup; + public form: UntypedFormGroup; constructor(private settingsService: SettingsService, private notificationService: NotificationService, - private fb: FormBuilder) { } + private fb: UntypedFormBuilder) { } public ngOnInit() { this.settingsService.getAuthentication().subscribe(x => { @@ -26,11 +26,23 @@ export class AuthenticationComponent implements OnInit { requireNonAlphanumeric: [x.requireNonAlphanumeric], requireUppercase: [x.requireUppercase], enableOAuth: [x.enableOAuth], + enableHeaderAuth: [x.enableHeaderAuth], + headerAuthVariable: [x.headerAuthVariable], + }); + this.form.controls.enableHeaderAuth.valueChanges.subscribe(x => { + if (x) { + this.form.get("headerAuthVariable").setValidators(Validators.required); + } else { + this.form.get("headerAuthVariable").clearValidators(); + } + this.form.get("headerAuthVariable").updateValueAndValidity(); }); }); + + } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/couchpotato/couchpotato.component.ts b/src/Ombi/ClientApp/src/app/settings/couchpotato/couchpotato.component.ts index 112e66b5c..457baa901 100644 --- a/src/Ombi/ClientApp/src/app/settings/couchpotato/couchpotato.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/couchpotato/couchpotato.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormControl, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormControl, UntypedFormGroup, Validators } from "@angular/forms"; import { CouchPotatoService, NotificationService, SettingsService, TesterService } from "../../services"; @@ -11,13 +11,13 @@ import { ICouchPotatoProfiles } from "../../interfaces"; }) export class CouchPotatoComponent implements OnInit { - public form: FormGroup; + public form: UntypedFormGroup; public profiles: ICouchPotatoProfiles; public profilesRunning: boolean; constructor(private readonly settingsService: SettingsService, - private readonly fb: FormBuilder, + private readonly fb: UntypedFormBuilder, private readonly notificationService: NotificationService, private readonly couchPotatoService: CouchPotatoService, private readonly testerService: TesterService) { } @@ -42,7 +42,7 @@ export class CouchPotatoComponent implements OnInit { }); } - public getProfiles(form: FormGroup) { + public getProfiles(form: UntypedFormGroup) { this.profilesRunning = true; this.couchPotatoService.getProfiles(form.value).subscribe(x => { this.profiles = x; @@ -50,7 +50,7 @@ export class CouchPotatoComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; @@ -67,7 +67,7 @@ export class CouchPotatoComponent implements OnInit { }); } - public test(form: FormGroup) { + public test(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; @@ -82,10 +82,10 @@ export class CouchPotatoComponent implements OnInit { }); } - public requestToken(form: FormGroup) { + public requestToken(form: UntypedFormGroup) { this.couchPotatoService.getApiKey(form.value).subscribe(x => { if (x.success === true) { - (this.form.controls.apiKey).setValue(x.api_key); + (this.form.controls.apiKey).setValue(x.api_key); this.notificationService.success("Successfully grabbed the Api Key"); } else { this.notificationService.error("Could not get the Api Key"); diff --git a/src/Ombi/ClientApp/src/app/settings/customization/customization.component.html b/src/Ombi/ClientApp/src/app/settings/customization/customization.component.html index b2168bb72..4c8bcecb6 100644 --- a/src/Ombi/ClientApp/src/app/settings/customization/customization.component.html +++ b/src/Ombi/ClientApp/src/app/settings/customization/customization.component.html @@ -34,6 +34,15 @@ + + The favicon url should be an externally accesible URL. Leave blank for default. + +
+ + Custom Favicon + + +
Hide Available Content On The Discover Page diff --git a/src/Ombi/ClientApp/src/app/settings/dognzb/dognzb.component.ts b/src/Ombi/ClientApp/src/app/settings/dognzb/dognzb.component.ts index 16683a0e3..4d2826bcf 100644 --- a/src/Ombi/ClientApp/src/app/settings/dognzb/dognzb.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/dognzb/dognzb.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { NotificationService, SettingsService } from "../../services"; @@ -9,12 +9,12 @@ import { NotificationService, SettingsService } from "../../services"; }) export class DogNzbComponent implements OnInit { - public form: FormGroup; + public form: UntypedFormGroup; public profilesRunning: boolean; constructor(private readonly settingsService: SettingsService, - private readonly fb: FormBuilder, + private readonly fb: UntypedFormBuilder, private readonly notificationService: NotificationService) { } public ngOnInit() { @@ -28,7 +28,7 @@ export class DogNzbComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/emby/emby.component.html b/src/Ombi/ClientApp/src/app/settings/emby/emby.component.html index 14aaada64..6787fb4c9 100644 --- a/src/Ombi/ClientApp/src/app/settings/emby/emby.component.html +++ b/src/Ombi/ClientApp/src/app/settings/emby/emby.component.html @@ -105,12 +105,29 @@
+
+
+ +
+
+
+ +
+
+ +
+
@@ -118,19 +135,8 @@
-
-
-
- -
-
-
- -
-
+ +
diff --git a/src/Ombi/ClientApp/src/app/settings/emby/emby.component.ts b/src/Ombi/ClientApp/src/app/settings/emby/emby.component.ts index b50175f61..3e48f6020 100644 --- a/src/Ombi/ClientApp/src/app/settings/emby/emby.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/emby/emby.component.ts @@ -2,7 +2,7 @@ import { EmbyService, JobService, NotificationService, SettingsService, TesterService } from "../../services"; import { IEmbyLibrariesSettings, IEmbyServer, IEmbySettings } from "../../interfaces"; -import {FormControl} from '@angular/forms'; +import {UntypedFormControl} from '@angular/forms'; import { MatTabChangeEvent } from "@angular/material/tabs"; @Component({ @@ -13,7 +13,7 @@ export class EmbyComponent implements OnInit { public settings: IEmbySettings; public hasDiscoveredOrDirty: boolean; - selected = new FormControl(0); + selected = new UntypedFormControl(0); constructor(private settingsService: SettingsService, private notificationService: NotificationService, @@ -93,6 +93,14 @@ export class EmbyComponent implements OnInit { }); } + public runRecentlyAddedCacher(): void { + this.jobService.runEmbyRecentlyAddedCacher().subscribe(x => { + if (x) { + this.notificationService.success("Triggered the Emby Recently Added Sync"); + } + }); + } + public clearDataAndResync(): void { this.jobService.clearMediaserverData().subscribe(x => { if (x) { diff --git a/src/Ombi/ClientApp/src/app/settings/features/features.component.html b/src/Ombi/ClientApp/src/app/settings/features/features.component.html new file mode 100644 index 000000000..37de15a4c --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/features/features.component.html @@ -0,0 +1,20 @@ + + +
+ Features + +
+
+
+
+
+ +
+
+

{{feature.name}}

+
+
+
+
+
+
diff --git a/src/Ombi/ClientApp/src/app/settings/features/features.component.scss b/src/Ombi/ClientApp/src/app/settings/features/features.component.scss new file mode 100644 index 000000000..658d13101 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/features/features.component.scss @@ -0,0 +1,5 @@ +.small-middle-container { + margin: auto; + width: 95%; + margin-top: 10px; +} diff --git a/src/Ombi/ClientApp/src/app/settings/features/features.component.ts b/src/Ombi/ClientApp/src/app/settings/features/features.component.ts new file mode 100644 index 000000000..75a155b6c --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/features/features.component.ts @@ -0,0 +1,32 @@ +import { Component, OnInit } from "@angular/core"; + +import { FeaturesFacade } from "../../state/features"; +import { IFeatureEnablement } from "../../interfaces"; +import { MatSlideToggleChange } from "@angular/material/slide-toggle"; +import { firstValueFrom } from "rxjs"; + +@Component({ + templateUrl: "./features.component.html", + styleUrls: ["./features.component.scss"] +}) +export class FeaturesComponent implements OnInit { + + public features: IFeatureEnablement[]; + + constructor(private readonly featuresFacade: FeaturesFacade) { } + + public async ngOnInit() { + this.featuresFacade.features$().subscribe(x => { + this.features = x; + }); + + } + + public updateFeature(change: MatSlideToggleChange, feature: IFeatureEnablement) { + if (change.checked) { + firstValueFrom(this.featuresFacade.enable(feature)); + } else { + firstValueFrom(this.featuresFacade.disable(feature)); + } + } +} diff --git a/src/Ombi/ClientApp/src/app/settings/issues/issues.component.ts b/src/Ombi/ClientApp/src/app/settings/issues/issues.component.ts index cfb6ae94d..0deab57d5 100644 --- a/src/Ombi/ClientApp/src/app/settings/issues/issues.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/issues/issues.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup } from "@angular/forms"; import { IIssueCategory } from "../../interfaces"; import { IssuesService, NotificationService, SettingsService } from "../../services"; @@ -12,11 +12,11 @@ export class IssuesComponent implements OnInit { public categories: IIssueCategory[]; public categoryToAdd: IIssueCategory = {id: 0, value: ""}; - public form: FormGroup; + public form: UntypedFormGroup; constructor(private issuesService: IssuesService, private settingsService: SettingsService, - private readonly fb: FormBuilder, + private readonly fb: UntypedFormBuilder, private notificationService: NotificationService) { } public ngOnInit() { @@ -48,7 +48,7 @@ export class IssuesComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/jellyfin/jellyfin.component.ts b/src/Ombi/ClientApp/src/app/settings/jellyfin/jellyfin.component.ts index 346d23ac8..20fd9f68d 100644 --- a/src/Ombi/ClientApp/src/app/settings/jellyfin/jellyfin.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/jellyfin/jellyfin.component.ts @@ -2,7 +2,7 @@ import { IEmbyServer, IJellyfinLibrariesSettings, IJellyfinServer, IJellyfinSettings } from "../../interfaces"; import { JellyfinService, JobService, NotificationService, SettingsService, TesterService } from "../../services"; -import {FormControl} from '@angular/forms'; +import {UntypedFormControl} from '@angular/forms'; import { MatTabChangeEvent } from "@angular/material/tabs"; @Component({ @@ -13,7 +13,7 @@ export class JellyfinComponent implements OnInit { public settings: IJellyfinSettings; public hasDiscoveredOrDirty: boolean; - selected = new FormControl(0); + selected = new UntypedFormControl(0); constructor(private settingsService: SettingsService, diff --git a/src/Ombi/ClientApp/src/app/settings/jobs/jobs.component.html b/src/Ombi/ClientApp/src/app/settings/jobs/jobs.component.html index 7e25704fa..47e7ef1cd 100644 --- a/src/Ombi/ClientApp/src/app/settings/jobs/jobs.component.html +++ b/src/Ombi/ClientApp/src/app/settings/jobs/jobs.component.html @@ -77,6 +77,13 @@ The Plex Sync is required +
+ + Plex Watchlist Import + + The Plex Watchlist Import is required + +
@@ -86,6 +93,14 @@
+
+ + Emby Recently Added Sync + + The Emby Recently Added Sync is required + +
+
Jellyfin Sync diff --git a/src/Ombi/ClientApp/src/app/settings/jobs/jobs.component.ts b/src/Ombi/ClientApp/src/app/settings/jobs/jobs.component.ts index 83508e752..d2450d651 100644 --- a/src/Ombi/ClientApp/src/app/settings/jobs/jobs.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/jobs/jobs.component.ts @@ -1,7 +1,6 @@ import { Component, OnInit } from "@angular/core"; - -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; -import { NotificationService, SettingsService, JobService } from "../../services"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; +import { JobService, NotificationService, SettingsService } from "../../services"; @Component({ templateUrl: "./jobs.component.html", @@ -9,12 +8,12 @@ import { NotificationService, SettingsService, JobService } from "../../services }) export class JobsComponent implements OnInit { - public form: FormGroup; + public form: UntypedFormGroup; public profilesRunning: boolean; constructor(private readonly settingsService: SettingsService, - private readonly fb: FormBuilder, + private readonly fb: UntypedFormBuilder, private readonly notificationService: NotificationService, private readonly jobsService: JobService) { } @@ -36,7 +35,9 @@ export class JobsComponent implements OnInit { issuesPurge: [x.issuesPurge, Validators.required], retryRequests: [x.retryRequests, Validators.required], mediaDatabaseRefresh: [x.mediaDatabaseRefresh, Validators.required], - autoDeleteRequests: [x.autoDeleteRequests, Validators.required] + autoDeleteRequests: [x.autoDeleteRequests, Validators.required], + embyRecentlyAddedSync: [x.embyRecentlyAddedSync, Validators.required], + plexWatchlistImport: [x.plexWatchlistImport, Validators.required], }); }); } @@ -51,7 +52,7 @@ export class JobsComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/lidarr/lidarr.component.ts b/src/Ombi/ClientApp/src/app/settings/lidarr/lidarr.component.ts index 80420fc15..a82c3ac03 100644 --- a/src/Ombi/ClientApp/src/app/settings/lidarr/lidarr.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/lidarr/lidarr.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { ILidarrSettings, IMinimumAvailability, IProfiles, IRadarrProfile, IRadarrRootFolder } from "../../interfaces"; import { LidarrService, TesterService } from "../../services"; @@ -20,12 +20,12 @@ export class LidarrComponent implements OnInit { public rootFoldersRunning: boolean; public metadataRunning: boolean; public advanced = false; - public form: FormGroup; + public form: UntypedFormGroup; constructor(private settingsService: SettingsService, private lidarrService: LidarrService, private notificationService: NotificationService, - private fb: FormBuilder, + private fb: UntypedFormBuilder, private testerService: TesterService) { } public ngOnInit() { @@ -67,7 +67,7 @@ export class LidarrComponent implements OnInit { }); } - public getProfiles(form: FormGroup) { + public getProfiles(form: UntypedFormGroup) { this.profilesRunning = true; this.lidarrService.getQualityProfiles(form.value).subscribe(x => { this.qualities = x; @@ -78,7 +78,7 @@ export class LidarrComponent implements OnInit { }); } - public getRootFolders(form: FormGroup) { + public getRootFolders(form: UntypedFormGroup) { this.rootFoldersRunning = true; this.lidarrService.getRootFolders(form.value).subscribe(x => { this.rootFolders = x; @@ -89,7 +89,7 @@ export class LidarrComponent implements OnInit { }); } - public getMetadataProfiles(form: FormGroup) { + public getMetadataProfiles(form: UntypedFormGroup) { this.metadataRunning = true; this.lidarrService.getMetadataProfiles(form.value).subscribe(x => { this.metadataProfiles = x; @@ -100,7 +100,7 @@ export class LidarrComponent implements OnInit { }); } - public test(form: FormGroup) { + public test(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; @@ -117,7 +117,7 @@ export class LidarrComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/massemail/massemail.component.html b/src/Ombi/ClientApp/src/app/settings/massemail/massemail.component.html index 49890ac6e..fb6ab0ad0 100644 --- a/src/Ombi/ClientApp/src/app/settings/massemail/massemail.component.html +++ b/src/Ombi/ClientApp/src/app/settings/massemail/massemail.component.html @@ -3,15 +3,15 @@
Mass Email - +
Hey! We need a subject!
-
- +
+
@@ -20,7 +20,14 @@ May appear differently on email clients
+
+ This will send out the Mass email BCC'ing all of the selected users rather than sending individual messages +
+ BCC +
+
+
@@ -28,23 +35,21 @@
- - + +
-
- - -
+
+ Select All +
-
- - -
+
+ {{u.user.userName}} ({{u.user.emailAddress}}) +
- +
diff --git a/src/Ombi/ClientApp/src/app/settings/massemail/massemail.component.ts b/src/Ombi/ClientApp/src/app/settings/massemail/massemail.component.ts index 17beb5405..1ed2fe995 100644 --- a/src/Ombi/ClientApp/src/app/settings/massemail/massemail.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/massemail/massemail.component.ts @@ -12,6 +12,7 @@ export class MassEmailComponent implements OnInit { public users: IMassEmailUserModel[] = []; public message: string; public subject: string; + public bcc: boolean; public missingSubject = false; @@ -26,17 +27,19 @@ export class MassEmailComponent implements OnInit { public ngOnInit(): void { this.identityService.getUsers().subscribe(x => { x.forEach(u => { - this.users.push({ - user: u, - selected: false, - }); + if (u.emailAddress) { + this.users.push({ + user: u, + selected: false, + }); + } }); }); this.settingsService.getEmailSettingsEnabled().subscribe(x => this.emailEnabled = x); } - public selectAllUsers() { - this.users.forEach(u => u.selected = !u.selected); + public selectAllUsers(event: any) { + this.users.forEach(u => u.selected = event.checked); } public send() { @@ -44,10 +47,10 @@ export class MassEmailComponent implements OnInit { this.missingSubject = true; return; } - if(!this.emailEnabled) { - this.notification.error("You have not yet setup your email notifications, do that first!"); - return; - } + // if(!this.emailEnabled) { + // this.notification.error("You have not yet setup your email notifications, do that first!"); + // return; + // } this.missingSubject = false; // Where(x => x.selected).Select(x => x.user) const selectedUsers = this.users.filter(u => { @@ -63,6 +66,7 @@ export class MassEmailComponent implements OnInit { users: selectedUsers, subject: this.subject, body: this.message, + bcc: this.bcc, }; this.notification.info("Sending","Sending mass email... Please wait"); this.notificationMessageService.sendMassEmail(model).subscribe(x => { diff --git a/src/Ombi/ClientApp/src/app/settings/notifications/cloudmobile.coponent.ts b/src/Ombi/ClientApp/src/app/settings/notifications/cloudmobile.coponent.ts index 3708f48a5..d1ef17855 100644 --- a/src/Ombi/ClientApp/src/app/settings/notifications/cloudmobile.coponent.ts +++ b/src/Ombi/ClientApp/src/app/settings/notifications/cloudmobile.coponent.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup } from "@angular/forms"; import { IMobileNotifcationSettings, IMobileUsersViewModel, INotificationTemplates, NotificationType, ICloudMobileDevices, ICloudMobileModel } from "../../interfaces"; import { TesterService } from "../../services"; @@ -17,7 +17,7 @@ export class CloudMobileComponent implements OnInit { public NotificationType = NotificationType; public templates: INotificationTemplates[]; - public form: FormGroup; + public form: UntypedFormGroup; public devices: MatTableDataSource; public selection = new SelectionModel(true, []); displayedColumns: string[] = ['select', 'username']; @@ -25,7 +25,7 @@ export class CloudMobileComponent implements OnInit { constructor(private settingsService: SettingsService, private notificationService: NotificationService, - private fb: FormBuilder, + private fb: UntypedFormBuilder, private mobileService: CloudMobileService) { } public async ngOnInit() { @@ -42,7 +42,7 @@ export class CloudMobileComponent implements OnInit { } } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; @@ -61,7 +61,7 @@ export class CloudMobileComponent implements OnInit { } - public async sendMessage(form: FormGroup) { + public async sendMessage(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/notifications/discord.component.ts b/src/Ombi/ClientApp/src/app/settings/notifications/discord.component.ts index e2e92e55c..faadfd295 100644 --- a/src/Ombi/ClientApp/src/app/settings/notifications/discord.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/notifications/discord.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { IDiscordNotifcationSettings, INotificationTemplates, NotificationType } from "../../interfaces"; import { TesterService } from "../../services"; @@ -14,11 +14,11 @@ export class DiscordComponent implements OnInit { public NotificationType = NotificationType; public templates: INotificationTemplates[]; - public form: FormGroup; + public form: UntypedFormGroup; constructor(private settingsService: SettingsService, private notificationService: NotificationService, - private fb: FormBuilder, + private fb: UntypedFormBuilder, private testerService: TesterService) { } public ngOnInit() { @@ -36,7 +36,7 @@ export class DiscordComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; @@ -55,7 +55,7 @@ export class DiscordComponent implements OnInit { } - public test(form: FormGroup) { + public test(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/notifications/emailnotification.component.html b/src/Ombi/ClientApp/src/app/settings/notifications/emailnotification.component.html index 33aa3a06c..7e95b0dfd 100644 --- a/src/Ombi/ClientApp/src/app/settings/notifications/emailnotification.component.html +++ b/src/Ombi/ClientApp/src/app/settings/notifications/emailnotification.component.html @@ -57,21 +57,6 @@
- -
- - Admin Email - - - Admin Email is required - - - Admin Email needs to be a valid email address - - -
- -
Username diff --git a/src/Ombi/ClientApp/src/app/settings/notifications/emailnotification.component.ts b/src/Ombi/ClientApp/src/app/settings/notifications/emailnotification.component.ts index f880891a5..1eda5d2f3 100644 --- a/src/Ombi/ClientApp/src/app/settings/notifications/emailnotification.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/notifications/emailnotification.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { IEmailNotificationSettings, INotificationTemplates, NotificationType } from "../../interfaces"; import { TesterService } from "../../services"; @@ -14,11 +14,11 @@ import { SettingsService } from "../../services"; export class EmailNotificationComponent implements OnInit { public NotificationType = NotificationType; public templates: INotificationTemplates[]; - public emailForm: FormGroup; + public emailForm: UntypedFormGroup; constructor(private settingsService: SettingsService, private notificationService: NotificationService, - private fb: FormBuilder, + private fb: UntypedFormBuilder, private validationService: ValidationService, private testerService: TesterService) { } @@ -35,7 +35,6 @@ export class EmailNotificationComponent implements OnInit { senderAddress: [x.senderAddress, [Validators.required, Validators.email]], senderName: [x.senderName], username: [x.username], - adminEmail: [x.adminEmail, [Validators.required, Validators.email]], disableTLS: [x.disableTLS], disableCertificateChecking: [x.disableCertificateChecking], }); @@ -49,7 +48,7 @@ export class EmailNotificationComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; @@ -68,7 +67,7 @@ export class EmailNotificationComponent implements OnInit { } - public test(form: FormGroup) { + public test(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/notifications/gotify.component.ts b/src/Ombi/ClientApp/src/app/settings/notifications/gotify.component.ts index 94345a391..f406a8079 100644 --- a/src/Ombi/ClientApp/src/app/settings/notifications/gotify.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/notifications/gotify.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { IGotifyNotificationSettings, INotificationTemplates, NotificationType } from "../../interfaces"; import { TesterService } from "../../services"; @@ -13,11 +13,11 @@ import { SettingsService } from "../../services"; export class GotifyComponent implements OnInit { public NotificationType = NotificationType; public templates: INotificationTemplates[]; - public form: FormGroup; + public form: UntypedFormGroup; constructor(private settingsService: SettingsService, private notificationService: NotificationService, - private fb: FormBuilder, + private fb: UntypedFormBuilder, private testerService: TesterService) { } public ngOnInit() { @@ -33,7 +33,7 @@ export class GotifyComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; @@ -52,7 +52,7 @@ export class GotifyComponent implements OnInit { } - public test(form: FormGroup) { + public test(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/notifications/mattermost.component.ts b/src/Ombi/ClientApp/src/app/settings/notifications/mattermost.component.ts index cb5a85ff1..48d9badd1 100644 --- a/src/Ombi/ClientApp/src/app/settings/notifications/mattermost.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/notifications/mattermost.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { IMattermostNotifcationSettings, INotificationTemplates, NotificationType } from "../../interfaces"; import { TesterService } from "../../services"; @@ -14,11 +14,11 @@ export class MattermostComponent implements OnInit { public NotificationType = NotificationType; public templates: INotificationTemplates[]; - public form: FormGroup; + public form: UntypedFormGroup; constructor(private settingsService: SettingsService, private notificationService: NotificationService, - private fb: FormBuilder, + private fb: UntypedFormBuilder, private testerService: TesterService) { } public ngOnInit() { @@ -36,7 +36,7 @@ export class MattermostComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; @@ -55,7 +55,7 @@ export class MattermostComponent implements OnInit { } - public test(form: FormGroup) { + public test(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/notifications/mobile.component.ts b/src/Ombi/ClientApp/src/app/settings/notifications/mobile.component.ts index 983b59ef2..caa358c5e 100644 --- a/src/Ombi/ClientApp/src/app/settings/notifications/mobile.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/notifications/mobile.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup } from "@angular/forms"; import { IMobileNotifcationSettings, IMobileUsersViewModel, INotificationTemplates, NotificationType } from "../../interfaces"; import { TesterService } from "../../services"; @@ -14,13 +14,13 @@ export class MobileComponent implements OnInit { public NotificationType = NotificationType; public templates: INotificationTemplates[]; - public form: FormGroup; + public form: UntypedFormGroup; public userList: IMobileUsersViewModel[]; public testUserId: string; constructor(private settingsService: SettingsService, private notificationService: NotificationService, - private fb: FormBuilder, + private fb: UntypedFormBuilder, private testerService: TesterService, private mobileService: MobileService) { } @@ -42,7 +42,7 @@ export class MobileComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; @@ -61,7 +61,7 @@ export class MobileComponent implements OnInit { } - public test(form: FormGroup) { + public test(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/notifications/pushbullet.component.ts b/src/Ombi/ClientApp/src/app/settings/notifications/pushbullet.component.ts index 541fc3b52..5cd721115 100644 --- a/src/Ombi/ClientApp/src/app/settings/notifications/pushbullet.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/notifications/pushbullet.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { INotificationTemplates, IPushbulletNotificationSettings, NotificationType } from "../../interfaces"; import { TesterService } from "../../services"; @@ -13,11 +13,11 @@ import { SettingsService } from "../../services"; export class PushbulletComponent implements OnInit { public NotificationType = NotificationType; public templates: INotificationTemplates[]; - public form: FormGroup; + public form: UntypedFormGroup; constructor(private settingsService: SettingsService, private notificationService: NotificationService, - private fb: FormBuilder, + private fb: UntypedFormBuilder, private testerService: TesterService) { } public ngOnInit() { @@ -32,7 +32,7 @@ export class PushbulletComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; @@ -51,7 +51,7 @@ export class PushbulletComponent implements OnInit { } - public test(form: FormGroup) { + public test(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/notifications/pushover.component.ts b/src/Ombi/ClientApp/src/app/settings/notifications/pushover.component.ts index 825afc8ac..fde8bc8d6 100644 --- a/src/Ombi/ClientApp/src/app/settings/notifications/pushover.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/notifications/pushover.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { INotificationTemplates, IPushoverNotificationSettings, NotificationType } from "../../interfaces"; import { TesterService } from "../../services"; @@ -13,11 +13,11 @@ import { SettingsService } from "../../services"; export class PushoverComponent implements OnInit { public NotificationType = NotificationType; public templates: INotificationTemplates[]; - public form: FormGroup; + public form: UntypedFormGroup; constructor(private settingsService: SettingsService, private notificationService: NotificationService, - private fb: FormBuilder, + private fb: UntypedFormBuilder, private testerService: TesterService) { } public ngOnInit() { @@ -34,7 +34,7 @@ export class PushoverComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; @@ -53,7 +53,7 @@ export class PushoverComponent implements OnInit { } - public test(form: FormGroup) { + public test(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/notifications/slack.component.ts b/src/Ombi/ClientApp/src/app/settings/notifications/slack.component.ts index c32d44432..15761b6c3 100644 --- a/src/Ombi/ClientApp/src/app/settings/notifications/slack.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/notifications/slack.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { INotificationTemplates, ISlackNotificationSettings, NotificationType } from "../../interfaces"; import { TesterService } from "../../services"; @@ -13,11 +13,11 @@ import { SettingsService } from "../../services"; export class SlackComponent implements OnInit { public NotificationType = NotificationType; public templates: INotificationTemplates[]; - public form: FormGroup; + public form: UntypedFormGroup; constructor(private settingsService: SettingsService, private notificationService: NotificationService, - private fb: FormBuilder, + private fb: UntypedFormBuilder, private testerService: TesterService) { } public ngOnInit() { @@ -36,7 +36,7 @@ export class SlackComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; @@ -60,7 +60,7 @@ export class SlackComponent implements OnInit { } - public test(form: FormGroup) { + public test(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/notifications/telegram.component.ts b/src/Ombi/ClientApp/src/app/settings/notifications/telegram.component.ts index 085a7ee75..7d56135e6 100644 --- a/src/Ombi/ClientApp/src/app/settings/notifications/telegram.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/notifications/telegram.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { INotificationTemplates, ITelegramNotifcationSettings, NotificationType } from "../../interfaces"; import { TesterService } from "../../services"; @@ -14,11 +14,11 @@ export class TelegramComponent implements OnInit { public NotificationType = NotificationType; public templates: INotificationTemplates[]; - public form: FormGroup; + public form: UntypedFormGroup; constructor(private settingsService: SettingsService, private notificationService: NotificationService, - private fb: FormBuilder, + private fb: UntypedFormBuilder, private testerService: TesterService) { } public ngOnInit() { @@ -35,7 +35,7 @@ export class TelegramComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; @@ -54,7 +54,7 @@ export class TelegramComponent implements OnInit { } - public test(form: FormGroup) { + public test(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/notifications/twilio/twilio.component.ts b/src/Ombi/ClientApp/src/app/settings/notifications/twilio/twilio.component.ts index 4f2364107..f4043a8b5 100644 --- a/src/Ombi/ClientApp/src/app/settings/notifications/twilio/twilio.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/notifications/twilio/twilio.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { INotificationTemplates, ITwilioSettings, NotificationType } from "../../../interfaces"; import { TesterService } from "../../../services"; @@ -12,11 +12,11 @@ import { SettingsService } from "../../../services"; export class TwilioComponent implements OnInit { public NotificationType = NotificationType; public templates: INotificationTemplates[]; - public form: FormGroup; + public form: UntypedFormGroup; constructor(private settingsService: SettingsService, private notificationService: NotificationService, - private fb: FormBuilder, + private fb: UntypedFormBuilder, private testerService: TesterService) { } public ngOnInit() { @@ -34,7 +34,7 @@ export class TwilioComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/notifications/twilio/whatsapp.component.ts b/src/Ombi/ClientApp/src/app/settings/notifications/twilio/whatsapp.component.ts index 80222e426..3664c3b62 100644 --- a/src/Ombi/ClientApp/src/app/settings/notifications/twilio/whatsapp.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/notifications/twilio/whatsapp.component.ts @@ -1,5 +1,5 @@ import { Component, Input } from "@angular/core"; -import { FormGroup } from "@angular/forms"; +import { UntypedFormGroup } from "@angular/forms"; import { TesterService, NotificationService } from "../../../services"; import { INotificationTemplates, NotificationType } from "../../../interfaces"; @@ -13,13 +13,13 @@ export class WhatsAppComponent { public NotificationType = NotificationType; @Input() public templates: INotificationTemplates[]; - @Input() public form: FormGroup; + @Input() public form: UntypedFormGroup; constructor(private testerService: TesterService, private notificationService: NotificationService) { } - public test(form: FormGroup) { + public test(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/notifications/webhook.component.ts b/src/Ombi/ClientApp/src/app/settings/notifications/webhook.component.ts index 2a7069b4c..5e7931069 100644 --- a/src/Ombi/ClientApp/src/app/settings/notifications/webhook.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/notifications/webhook.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { INotificationTemplates, IWebhookNotificationSettings, NotificationType } from "../../interfaces"; import { TesterService } from "../../services"; @@ -13,11 +13,11 @@ import { SettingsService } from "../../services"; export class WebhookComponent implements OnInit { public NotificationType = NotificationType; public templates: INotificationTemplates[]; - public form: FormGroup; + public form: UntypedFormGroup; constructor(private settingsService: SettingsService, private notificationService: NotificationService, - private fb: FormBuilder, + private fb: UntypedFormBuilder, private testerService: TesterService) { } public ngOnInit() { @@ -30,7 +30,7 @@ export class WebhookComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; @@ -48,7 +48,7 @@ export class WebhookComponent implements OnInit { } - public test(form: FormGroup) { + public test(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/ombi/ombi.component.ts b/src/Ombi/ClientApp/src/app/settings/ombi/ombi.component.ts index f797703bc..af19e16e3 100644 --- a/src/Ombi/ClientApp/src/app/settings/ombi/ombi.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/ombi/ombi.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup } from "@angular/forms"; import { Branch, ILanguageRefine, IOmbiSettings } from "../../interfaces"; import { NotificationService } from "../../services"; @@ -13,13 +13,13 @@ import languageData from "./../../../other/iso-lang.json"; }) export class OmbiComponent implements OnInit { - public form: FormGroup; + public form: UntypedFormGroup; public langauges: ILanguageRefine[]; public Branch = Branch; constructor(private settingsService: SettingsService, private notificationService: NotificationService, - private fb: FormBuilder) { } + private fb: UntypedFormBuilder) { } public ngOnInit() { this.settingsService.getOmbi().subscribe(x => { @@ -45,7 +45,7 @@ export class OmbiComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.html b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.html index f84395043..858a94358 100644 --- a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.html +++ b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.html @@ -9,6 +9,12 @@ Enable
+
+ Enable User Watchlist Requests + +

When a Plex User adds something to their watchlist in Plex, it will turn up in Ombi as a Request if enabled. This only applies to users that are logging in with their Plex Account

+

Request limits if set are all still applied etc.

+
Advanced
@@ -183,6 +189,12 @@ Clear Data And Resync +
+ +
diff --git a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.ts b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.ts index 8d42419fe..2e9792996 100644 --- a/src/Ombi/ClientApp/src/app/settings/plex/plex.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/plex/plex.component.ts @@ -5,7 +5,7 @@ import { takeUntil } from "rxjs/operators"; import { IPlexLibrariesSettings, IPlexServer, IPlexServerResponse, IPlexServerViewModel, IPlexSettings } from "../../interfaces"; import { JobService, NotificationService, PlexService, SettingsService, TesterService } from "../../services"; import { MatTabChangeEvent, MatTabGroup } from "@angular/material/tabs"; -import {FormControl} from '@angular/forms'; +import {UntypedFormControl} from '@angular/forms'; @Component({ templateUrl: "./plex.component.html", @@ -17,7 +17,7 @@ export class PlexComponent implements OnInit, OnDestroy { public username: string; public password: string; public serversButton = false; - selected = new FormControl(0); + selected = new UntypedFormControl(0); @ViewChild("tabGroup", {static: false}) public tagGroup: MatTabGroup; public advanced = false; @@ -172,6 +172,14 @@ export class PlexComponent implements OnInit, OnDestroy { }); } + public runWatchlistImport(): void { + this.jobService.runPlexWatchlistImport().subscribe(x => { + if (x) { + this.notificationService.success("Triggered the Watchlist Import"); + } + }); + } + public ngOnDestroy() { this.subscriptions.next(); this.subscriptions.complete(); diff --git a/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.html b/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.html new file mode 100644 index 000000000..2dbf6869d --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.html @@ -0,0 +1,101 @@ +
+
+
+
+
+ Enable +
+
+ Scan for Availability +
+
+ + Do not search for Movies + +
+
+
+
+
+
+
+ +
+ + Hostname or IP + + + + Port + + + + SSL + +
+
+
+ + API key + + +
+
+ + Base URL + + +
+
+
+ +
+
+ +
+
+ + Quality Profiles + + + {{quality.name}} + + + + +
+
+
+ +
+
+ + Default Root Folder + + + {{folder.path}} + + + + +
+
+ + Default Minimum Availability + + + {{min.name}} + + + +
+
+
+
+
+
+ +
+
+
+
\ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.scss b/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.scss new file mode 100644 index 000000000..bf4c9e420 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.scss @@ -0,0 +1,21 @@ +@import "~styles/shared.scss"; +.small-middle-container { + margin: auto; + width: 95%; + margin-top: 10px; +} + +.col-8 { + display: inline-table; +} +.col-md-5 { + display: inline-table; +} + +.row { + display: block; +} + +.top-spacing { + margin-top: 10px; +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.ts b/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.ts new file mode 100644 index 000000000..1dbceead8 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/settings/radarr/components/radarr-form.component.ts @@ -0,0 +1,100 @@ +import { ChangeDetectionStrategy, Component, OnInit } from "@angular/core"; +import { ControlContainer, UntypedFormGroup, Validators } from "@angular/forms"; + +import { IMinimumAvailability, IRadarrProfile, IRadarrRootFolder, IRadarrSettings } from "../../../interfaces"; +import { TesterService, NotificationService, RadarrService } from "../../../services"; + + +@Component({ + selector: "ombi-settings-radarr-form", + templateUrl: "./radarr-form.component.html", + styleUrls: ["./radarr-form.component.scss"], + changeDetection: ChangeDetectionStrategy.OnPush +}) +export class RadarrFormComponent implements OnInit { + + public qualities: IRadarrProfile[]; + public rootFolders: IRadarrRootFolder[]; + public minimumAvailabilityOptions: IMinimumAvailability[]; + public profilesRunning: boolean; + public rootFoldersRunning: boolean; + public form: UntypedFormGroup; + + constructor(private radarrService: RadarrService, + private notificationService: NotificationService, + private testerService: TesterService, + private controlContainer: ControlContainer) { + } + + public ngOnInit() { + this.form = this.controlContainer.control; + + this.qualities = []; + this.qualities.push({ name: "Please Select", id: -1 }); + + this.rootFolders = []; + this.rootFolders.push({ path: "Please Select", id: -1 }); + this.minimumAvailabilityOptions = [ + { name: "Announced", value: "Announced" }, + { name: "In Cinemas", value: "InCinemas" }, + { name: "Physical / Web", value: "Released" }, + ]; + + if (this.form.controls.defaultQualityProfile.value) { + this.getProfiles(this.form); + } + + if (this.form.controls.defaultRootPath.value) { + this.getRootFolders(this.form); + } + } + + public toggleValidators() { + const enabled = this.form.controls.enabled.value as boolean; + this.form.controls.apiKey.setValidators(enabled ? [Validators.required] : null); + this.form.controls.defaultQualityProfile.setValidators(enabled ? [Validators.required] : null); + this.form.controls.defaultRootPath.setValidators(enabled ? [Validators.required] : null); + this.form.controls.ip.setValidators(enabled ? [Validators.required] : null); + this.form.controls.port.setValidators(enabled ? [Validators.required] : null); + this.form.controls.minimumAvailability.setValidators(enabled ? [Validators.required] : null); + } + + public getProfiles(form: UntypedFormGroup) { + this.profilesRunning = true; + this.radarrService.getQualityProfiles(form.value).subscribe(x => { + this.qualities = x; + this.qualities.unshift({ name: "Please Select", id: -1 }); + + this.profilesRunning = false; + this.notificationService.success("Successfully retrieved the Quality Profiles"); + }); + } + + public getRootFolders(form: UntypedFormGroup) { + this.rootFoldersRunning = true; + this.radarrService.getRootFolders(form.value).subscribe(x => { + this.rootFolders = x; + this.rootFolders.unshift({ path: "Please Select", id: -1 }); + + this.rootFoldersRunning = false; + this.notificationService.success("Successfully retrieved the Root Folders"); + }); + } + + public test(form: UntypedFormGroup) { + if (form.invalid) { + this.notificationService.error("Please check your entered values"); + return; + } + const settings = form.value; + this.testerService.radarrTest(settings).subscribe(result => { + if (result.isValid) { + this.notificationService.success("Successfully connected to Radarr!"); + } else if (result.expectedSubDir) { + this.notificationService.error("Your Radarr Base URL must be set to " + result.expectedSubDir); + } else { + this.notificationService.error("We could not connect to Radarr!"); + } + }); + } +} diff --git a/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.html b/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.html index b6d30998a..5a3e24e90 100644 --- a/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.html +++ b/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.html @@ -4,107 +4,32 @@ Radarr Settings
-
-
-
-
- Enable -
-
- Scan for Availability -
-
- - Do not search for Movies - -
-
-
-
-
-
-
- -
- - Hostname or IP - - - - Port - - - - SSL - -
-
-
- - API key - - -
-
- - Base URL - - -
-
-
- -
-
- -
-
- - Quality Profiles - - - {{quality.name}} - - - -
-
-
- -
-
- - Default Root Folder - - - {{folder.path}} - - - + + + + + + + + + + -
-
- - Default Minimum Availability - - - {{min.name}} - - - -
-
-
-
-
-
- -
-
- -
-
+ + +
+
diff --git a/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.ts b/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.ts index dd702eae4..2a6443074 100644 --- a/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/radarr/radarr.component.ts @@ -1,12 +1,10 @@ -import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { Component, OnInit, QueryList, ViewChild, ViewChildren } from "@angular/core"; +import { UntypedFormBuilder, UntypedFormGroup } from "@angular/forms"; -import { IMinimumAvailability, IRadarrProfile, IRadarrRootFolder } from "../../interfaces"; -import { IRadarrSettings } from "../../interfaces"; -import { RadarrService } from "../../services"; -import { TesterService } from "../../services"; -import { NotificationService } from "../../services"; -import { SettingsService } from "../../services"; +import { IMinimumAvailability, IRadarrCombined, IRadarrProfile, IRadarrRootFolder } from "../../interfaces"; +import { NotificationService, SettingsService } from "../../services"; +import { FeaturesFacade } from "../../state/features/features.facade"; +import { RadarrFormComponent } from "./components/radarr-form.component"; @Component({ templateUrl: "./radarr.component.html", @@ -19,104 +17,81 @@ export class RadarrComponent implements OnInit { public minimumAvailabilityOptions: IMinimumAvailability[]; public profilesRunning: boolean; public rootFoldersRunning: boolean; - public form: FormGroup; + public form: UntypedFormGroup; + public is4kEnabled: boolean = false; + + @ViewChildren('4kForm') public form4k: QueryList; + @ViewChildren('normalForm') public normalForm: QueryList; constructor(private settingsService: SettingsService, - private radarrService: RadarrService, private notificationService: NotificationService, - private fb: FormBuilder, - private testerService: TesterService) { } + private featureFacade: FeaturesFacade, + private fb: UntypedFormBuilder) { } + public ngOnInit() { + this.is4kEnabled = this.featureFacade.is4kEnabled(); this.settingsService.getRadarr() .subscribe(x => { - this.form = this.fb.group({ - enabled: [x.enabled], - apiKey: [x.apiKey, [Validators.required]], - defaultQualityProfile: [+x.defaultQualityProfile, [Validators.required]], - defaultRootPath: [x.defaultRootPath, [Validators.required]], - ssl: [x.ssl], - subDir: [x.subDir], - ip: [x.ip, [Validators.required]], - port: [x.port, [Validators.required]], - addOnly: [x.addOnly], - minimumAvailability: [x.minimumAvailability, [Validators.required]], - scanForAvailability: [x.scanForAvailability] + radarr: this.fb.group({ + enabled: [x.radarr.enabled], + apiKey: [x.radarr.apiKey], + defaultQualityProfile: [+x.radarr.defaultQualityProfile], + defaultRootPath: [x.radarr.defaultRootPath], + ssl: [x.radarr.ssl], + subDir: [x.radarr.subDir], + ip: [x.radarr.ip], + port: [x.radarr.port], + addOnly: [x.radarr.addOnly], + minimumAvailability: [x.radarr.minimumAvailability], + scanForAvailability: [x.radarr.scanForAvailability] + }), + radarr4K: this.fb.group({ + enabled: [x.radarr4K.enabled], + apiKey: [x.radarr4K.apiKey], + defaultQualityProfile: [+x.radarr4K.defaultQualityProfile], + defaultRootPath: [x.radarr4K.defaultRootPath], + ssl: [x.radarr4K.ssl], + subDir: [x.radarr4K.subDir], + ip: [x.radarr4K.ip], + port: [x.radarr4K.port], + addOnly: [x.radarr4K.addOnly], + minimumAvailability: [x.radarr4K.minimumAvailability], + scanForAvailability: [x.radarr4K.scanForAvailability] + }), }); - - if (x.defaultQualityProfile) { - this.getProfiles(this.form); - } - if (x.defaultRootPath) { - this.getRootFolders(this.form); + this.normalForm.changes.forEach((comp => { + comp.first.toggleValidators(); + })) + if (this.is4kEnabled) { + this.form4k.changes.forEach((comp => { + comp.first.toggleValidators(); + })) } }); - this.qualities = []; - this.qualities.push({ name: "Please Select", id: -1 }); - - this.rootFolders = []; - this.rootFolders.push({ path: "Please Select", id: -1 }); - this.minimumAvailabilityOptions = [ - { name: "Announced", value: "Announced" }, - { name: "In Cinemas", value: "InCinemas" }, - { name: "Physical / Web", value: "Released" }, - { name: "PreDb", value: "PreDb" }, - ]; - } - public getProfiles(form: FormGroup) { - this.profilesRunning = true; - this.radarrService.getQualityProfiles(form.value).subscribe(x => { - this.qualities = x; - this.qualities.unshift({ name: "Please Select", id: -1 }); - this.profilesRunning = false; - this.notificationService.success("Successfully retrieved the Quality Profiles"); - }); - } - - public getRootFolders(form: FormGroup) { - this.rootFoldersRunning = true; - this.radarrService.getRootFolders(form.value).subscribe(x => { - this.rootFolders = x; - this.rootFolders.unshift({ path: "Please Select", id: -1 }); - - this.rootFoldersRunning = false; - this.notificationService.success("Successfully retrieved the Root Folders"); - }); - } - - public test(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; } - const settings = form.value; - this.testerService.radarrTest(settings).subscribe(result => { - if (result.isValid) { - this.notificationService.success("Successfully connected to Radarr!"); - } else if (result.expectedSubDir) { - this.notificationService.error("Your Radarr Base URL must be set to " + result.expectedSubDir); - } else { - this.notificationService.error("We could not connect to Radarr!"); - } - }); - } + const radarrForm = form.controls.radarr as UntypedFormGroup; + const radarr4KForm = form.controls.radarr4K as UntypedFormGroup; -public onSubmit(form: FormGroup) { - if (form.invalid) { - this.notificationService.error("Please check your entered values"); + if (radarrForm.controls.enabled.value && (radarrForm.controls.defaultQualityProfile.value === -1 || radarrForm.controls.defaultRootPath.value === "Please Select")) { + this.notificationService.error("Please check your entered values for Radarr"); return; } - if (form.controls.defaultQualityProfile.value === "-1" || form.controls.defaultRootPath.value === "Please Select") { - this.notificationService.error("Please check your entered values"); + if (radarr4KForm.controls.enabled.value && (radarr4KForm.controls.defaultQualityProfile.value === -1 || radarr4KForm.controls.defaultRootPath.value === "Please Select")) { + this.notificationService.error("Please check your entered values for Radarr 4K"); return; } - const settings = form.value; + const settings = form.value; this.settingsService.saveRadarr(settings).subscribe(x => { if (x) { this.notificationService.success("Successfully saved Radarr settings"); diff --git a/src/Ombi/ClientApp/src/app/settings/settings.module.ts b/src/Ombi/ClientApp/src/app/settings/settings.module.ts index b486e5b26..144322194 100644 --- a/src/Ombi/ClientApp/src/app/settings/settings.module.ts +++ b/src/Ombi/ClientApp/src/app/settings/settings.module.ts @@ -1,76 +1,88 @@ -import { CommonModule } from "@angular/common"; -import { NgModule } from "@angular/core"; +import { + CouchPotatoService, + EmbyService, + FileDownloadService, + IssuesService, + JellyfinService, + JobService, + LidarrService, + MobileService, + NotificationMessageService, + PlexService, + RadarrService, + RequestRetryService, + SonarrService, + SystemService, + TesterService, + TheMovieDbService, + ValidationService +} from "../services"; import { FormsModule, ReactiveFormsModule } from "@angular/forms"; import { RouterModule, Routes } from "@angular/router"; -// import { TagInputModule } from "ngx-chips"; -import { ClipboardModule } from "ngx-clipboard"; +import { AboutComponent } from "./about/about.component"; import { AuthGuard } from "../auth/auth.guard"; import { AuthService } from "../auth/auth.service"; -import { - CouchPotatoService, EmbyService, JellyfinService, IssuesService, JobService, LidarrService, MobileService, NotificationMessageService, PlexService, RadarrService, - RequestRetryService, SonarrService, TesterService, ValidationService, SystemService, FileDownloadService, TheMovieDbService -} from "../services"; - -import { PipeModule } from "../pipes/pipe.module"; -import { AboutComponent } from "./about/about.component"; import { AuthenticationComponent } from "./authentication/authentication.component"; +import {AutoCompleteModule} from "primeng/autocomplete"; +import {CalendarModule} from "primeng/calendar"; +import { ClipboardModule } from "ngx-clipboard"; +import { CloudMobileComponent } from "./notifications/cloudmobile.coponent"; +import { CloudMobileService } from "../services/cloudmobile.service"; +import { CommonModule } from "@angular/common"; import { CouchPotatoComponent } from "./couchpotato/couchpotato.component"; import { CustomizationComponent } from "./customization/customization.component"; +import {DialogModule} from "primeng/dialog"; +import { DiscordComponent } from "./notifications/discord.component"; import { DogNzbComponent } from "./dognzb/dognzb.component"; +import { EmailNotificationComponent } from "./notifications/emailnotification.component"; import { EmbyComponent } from "./emby/emby.component"; -import { JellyfinComponent } from "./jellyfin/jellyfin.component"; import { FailedRequestsComponent } from "./failedrequests/failedrequests.component"; +import { FeaturesComponent } from "./features/features.component"; +import { GotifyComponent } from "./notifications/gotify.component"; +import { HubService } from "../services/hub.service"; +import {InputSwitchModule} from "primeng/inputswitch"; +import {InputTextModule} from "primeng/inputtext"; import { IssuesComponent } from "./issues/issues.component"; +import { JellyfinComponent } from "./jellyfin/jellyfin.component"; import { JobsComponent } from "./jobs/jobs.component"; import { LandingPageComponent } from "./landingpage/landingpage.component"; import { LidarrComponent } from "./lidarr/lidarr.component"; +import { LogsComponent } from "./logs/logs.component"; import { MassEmailComponent } from "./massemail/massemail.component"; -import { DiscordComponent } from "./notifications/discord.component"; -import { EmailNotificationComponent } from "./notifications/emailnotification.component"; -import { GotifyComponent } from "./notifications/gotify.component"; +import { MatDialogModule } from "@angular/material/dialog"; +import { MatMenuModule } from "@angular/material/menu"; import { MattermostComponent } from "./notifications/mattermost.component"; +import {MenuModule} from "primeng/menu"; import { MobileComponent } from "./notifications/mobile.component"; import { NewsletterComponent } from "./notifications/newsletter.component"; +import { NgModule } from "@angular/core"; import { NotificationTemplate } from "./notifications/notificationtemplate.component"; +import { OmbiComponent } from "./ombi/ombi.component"; +import { PipeModule } from "../pipes/pipe.module"; +import { PlexComponent } from "./plex/plex.component"; import { PushbulletComponent } from "./notifications/pushbullet.component"; import { PushoverComponent } from "./notifications/pushover.component"; -import { SlackComponent } from "./notifications/slack.component"; -import { TelegramComponent } from "./notifications/telegram.component"; -import { WebhookComponent } from "./notifications/webhook.component"; -import { OmbiComponent } from "./ombi/ombi.component"; -import { PlexComponent } from "./plex/plex.component"; import { RadarrComponent } from "./radarr/radarr.component"; +import { RadarrFormComponent } from "./radarr/components/radarr-form.component"; +import {RadioButtonModule} from "primeng/radiobutton"; +import { SettingsMenuComponent } from "./settingsmenu.component"; +import { SharedModule } from "../shared/shared.module"; import { SickRageComponent } from "./sickrage/sickrage.component"; +import { SlackComponent } from "./notifications/slack.component"; import { SonarrComponent } from "./sonarr/sonarr.component"; +import { TelegramComponent } from "./notifications/telegram.component"; import { TheMovieDbComponent } from "./themoviedb/themoviedb.component"; +import {TooltipModule} from "primeng/tooltip"; +import { TwilioComponent } from "./notifications/twilio/twilio.component"; import { UpdateComponent } from "./update/update.component"; +import { UpdateDialogComponent } from "./about/update-dialog.component"; +import { UpdateService } from "../services/update.service"; import { UserManagementComponent } from "./usermanagement/usermanagement.component"; import { VoteComponent } from "./vote/vote.component"; -import { WikiComponent } from "./wiki.component"; - -import { SettingsMenuComponent } from "./settingsmenu.component"; - -import {AutoCompleteModule } from "primeng/autocomplete"; -import {CalendarModule } from "primeng/calendar"; -import {InputSwitchModule } from "primeng/inputswitch"; -import {InputTextModule } from "primeng/inputtext"; -import {DialogModule } from "primeng/dialog"; -import {MenuModule } from "primeng/menu"; -import {RadioButtonModule } from "primeng/radiobutton"; -import {TooltipModule } from "primeng/tooltip"; - -import { MatMenuModule } from "@angular/material/menu"; -import { SharedModule } from "../shared/shared.module"; -import { HubService } from "../services/hub.service"; -import { LogsComponent } from "./logs/logs.component"; -import { TwilioComponent } from "./notifications/twilio/twilio.component"; +import { WebhookComponent } from "./notifications/webhook.component"; import { WhatsAppComponent } from "./notifications/twilio/whatsapp.component"; -import { CloudMobileComponent } from "./notifications/cloudmobile.coponent"; -import { CloudMobileService } from "../services/cloudmobile.service"; -import { UpdateService } from "../services/update.service"; -import { MatDialogModule } from "@angular/material/dialog"; -import { UpdateDialogComponent } from "./about/update-dialog.component"; +import { WikiComponent } from "./wiki.component"; const routes: Routes = [ { path: "Ombi", component: OmbiComponent, canActivate: [AuthGuard] }, @@ -109,6 +121,7 @@ const routes: Routes = [ { path: "FailedRequests", component: FailedRequestsComponent, canActivate: [AuthGuard] }, { path: "Logs", component: LogsComponent, canActivate: [AuthGuard] }, { path: "CloudMobile", component: CloudMobileComponent, canActivate: [AuthGuard] }, + { path: "Features", component: FeaturesComponent, canActivate: [AuthGuard] }, ]; @NgModule({ @@ -145,6 +158,7 @@ const routes: Routes = [ SonarrComponent, SlackComponent, RadarrComponent, + RadarrFormComponent, EmailNotificationComponent, NotificationTemplate, PushoverComponent, @@ -172,6 +186,7 @@ const routes: Routes = [ LogsComponent, TwilioComponent, WhatsAppComponent, + FeaturesComponent, CloudMobileComponent, UpdateDialogComponent, ], diff --git a/src/Ombi/ClientApp/src/app/settings/settingsmenu.component.html b/src/Ombi/ClientApp/src/app/settings/settingsmenu.component.html index bd6949ebb..bcbe7bd3a 100644 --- a/src/Ombi/ClientApp/src/app/settings/settingsmenu.component.html +++ b/src/Ombi/ClientApp/src/app/settings/settingsmenu.component.html @@ -2,6 +2,7 @@ + diff --git a/src/Ombi/ClientApp/src/app/settings/sickrage/sickrage.component.ts b/src/Ombi/ClientApp/src/app/settings/sickrage/sickrage.component.ts index 75e45fe7f..832dca806 100644 --- a/src/Ombi/ClientApp/src/app/settings/sickrage/sickrage.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/sickrage/sickrage.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { IDropDownModel, ISickRageSettings } from "../../interfaces"; import { TesterService } from "../../services"; @@ -13,12 +13,12 @@ import { SettingsService } from "../../services"; export class SickRageComponent implements OnInit { public qualities: IDropDownModel[]; - public form: FormGroup; + public form: UntypedFormGroup; constructor(private settingsService: SettingsService, private notificationService: NotificationService, private testerService: TesterService, - private fb: FormBuilder) { } + private fb: UntypedFormBuilder) { } public ngOnInit() { this.settingsService.getSickRageSettings() @@ -36,7 +36,7 @@ export class SickRageComponent implements OnInit { }); } - public test(form: FormGroup) { + public test(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; @@ -51,7 +51,7 @@ export class SickRageComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/sonarr/sonarr.component.ts b/src/Ombi/ClientApp/src/app/settings/sonarr/sonarr.component.ts index 877d9bae3..1f69b132c 100644 --- a/src/Ombi/ClientApp/src/app/settings/sonarr/sonarr.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/sonarr/sonarr.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormControl, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, FormControl, UntypedFormGroup, Validators } from "@angular/forms"; import { ILanguageProfiles, ISonarrProfile, ISonarrRootFolder } from "../../interfaces"; @@ -27,7 +27,7 @@ export class SonarrComponent implements OnInit { public profilesRunning: boolean; public rootFoldersRunning: boolean; public langRunning: boolean; - public form: FormGroup; + public form: UntypedFormGroup; public advanced = false; formErrors: any; @@ -35,7 +35,7 @@ export class SonarrComponent implements OnInit { private sonarrService: SonarrService, private notificationService: NotificationService, private testerService: TesterService, - private fb: FormBuilder){} + private fb: UntypedFormBuilder){} onFormValuesChanged() { @@ -115,7 +115,7 @@ export class SonarrComponent implements OnInit { this.qualities.push({ name: "Please Select", id: -1 }); } - public getProfiles(form: FormGroup) { + public getProfiles(form: UntypedFormGroup) { this.profilesRunning = true; this.sonarrService.getQualityProfiles(form.value) .subscribe(x => { @@ -127,7 +127,7 @@ export class SonarrComponent implements OnInit { }); } - public getRootFolders(form: FormGroup) { + public getRootFolders(form: UntypedFormGroup) { this.rootFoldersRunning = true; this.sonarrService.getRootFolders(form.value) .subscribe(x => { @@ -140,7 +140,7 @@ export class SonarrComponent implements OnInit { }); } - public getLanguageProfiles(form: FormGroup) { + public getLanguageProfiles(form: UntypedFormGroup) { this.langRunning = true; this.sonarrService.getV3LanguageProfiles(form.value) .subscribe(x => { @@ -155,7 +155,7 @@ export class SonarrComponent implements OnInit { } } - public test(form: FormGroup) { + public test(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; @@ -172,7 +172,7 @@ export class SonarrComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.html b/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.html index fb10cc142..d01768947 100644 --- a/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.html +++ b/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.html @@ -13,6 +13,14 @@
+ + Original languages + + + {{language.english_name}} + + + - +
Movie Genres @@ -51,7 +59,7 @@ {{key.name}} - +
diff --git a/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.ts b/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.ts index 008e2dfab..3f6e10ba2 100644 --- a/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/themoviedb/themoviedb.component.ts @@ -1,11 +1,11 @@ import {COMMA, ENTER} from "@angular/cdk/keycodes"; import { Component, ElementRef, OnInit, ViewChild } from "@angular/core"; -import { FormBuilder, FormGroup } from "@angular/forms"; -import { IMovieDbKeyword, ITheMovieDbSettings } from "../../interfaces"; +import { UntypedFormBuilder, UntypedFormGroup } from "@angular/forms"; +import { ILanguage, IMovieDbKeyword, ITheMovieDbSettings } from "../../interfaces"; import { debounceTime, switchMap } from "rxjs/operators"; import { MatAutocomplete } from "@angular/material/autocomplete"; -import { NotificationService } from "../../services"; +import { NotificationService, SearchV2Service } from "../../services"; import { SettingsService } from "../../services"; import { TheMovieDbService } from "../../services"; @@ -22,28 +22,48 @@ interface IKeywordTag { export class TheMovieDbComponent implements OnInit { public settings: ITheMovieDbSettings; + public originalLanguages: ILanguage[]; public excludedKeywords: IKeywordTag[]; public excludedMovieGenres: IKeywordTag[]; public excludedTvGenres: IKeywordTag[]; - public tagForm: FormGroup; + public tagForm: UntypedFormGroup; + public languages: ILanguage[]; public filteredTags: IMovieDbKeyword[]; public filteredMovieGenres: IMovieDbKeyword[]; public filteredTvGenres: IMovieDbKeyword[]; + constructor(private settingsService: SettingsService, private notificationService: NotificationService, private tmdbService: TheMovieDbService, - private fb: FormBuilder) { } + private searchService: SearchV2Service, + private fb: UntypedFormBuilder) { } public ngOnInit() { - this.tagForm = this.fb.group({ - input: null, - excludedMovieGenres: null, - excludedTvGenres: null, - }); this.settingsService.getTheMovieDbSettings().subscribe(settings => { this.settings = settings; + this.tagForm = this.fb.group({ + input: null, + originalLanguages: [this.settings.originalLanguages], + excludedMovieGenres: null, + excludedTvGenres: null, + }); + + this.tagForm + .get("input") + .valueChanges.pipe( + debounceTime(600), + switchMap((value: string) => { + if (value) { + return this.tmdbService.getKeywords(value); + } + return []; + }) + ) + .subscribe((r) => (this.filteredTags = r)); + + // Map Keyword ids -> keyword name this.excludedKeywords = settings.excludedKeywordIds ? settings.excludedKeywordIds.map(id => ({ @@ -55,9 +75,10 @@ export class TheMovieDbComponent implements OnInit { this.excludedKeywords.forEach(key => { this.tmdbService.getKeyword(key.id).subscribe(keyResult => { - this.excludedKeywords.filter((val, idx) => { - val.name = keyResult.name; - }) + var keyToUpdate = this.excludedKeywords.filter((val) => { + return val.id == key.id; + })[0]; + keyToUpdate.name = keyResult.name; }); }); @@ -70,7 +91,7 @@ export class TheMovieDbComponent implements OnInit { })) : []; - this.tmdbService.getGenres("movie").subscribe(results => { + this.searchService.getGenres("movie").subscribe(results => { this.filteredMovieGenres = results; this.excludedMovieGenres.forEach(genre => { @@ -80,8 +101,12 @@ export class TheMovieDbComponent implements OnInit { } }); }); - }); - + }); + + this.searchService.getLanguages().subscribe((results) => { + this.languages = results.sort((a: ILanguage, b: ILanguage) => (a.english_name > b.english_name) ? 1 : -1);; + }); + // Map Tv Genre ids -> genre name this.excludedTvGenres = settings.excludedTvGenreIds ? settings.excludedTvGenreIds.map(id => ({ @@ -91,7 +116,7 @@ export class TheMovieDbComponent implements OnInit { })) : []; - this.tmdbService.getGenres("tv").subscribe(results => { + this.searchService.getGenres("tv").subscribe(results => { this.filteredTvGenres = results; this.excludedTvGenres.forEach(genre => { @@ -100,21 +125,10 @@ export class TheMovieDbComponent implements OnInit { genre.name = result.name; } }); - }); + }); }); }); - this.tagForm - .get("input") - .valueChanges.pipe( - debounceTime(600), - switchMap((value: string) => { - if (value) { - return this.tmdbService.getKeywords(value); - } - }) - ) - .subscribe((r) => (this.filteredTags = r)); } public remove(tag: IKeywordTag, tag_type: string): void { @@ -159,7 +173,7 @@ export class TheMovieDbComponent implements OnInit { this.settingsService.saveTheMovieDbSettings(this.settings).subscribe(x => { if (x) { - this.notificationService.success("Successfully saved The Movie Database settings"); + this.notificationService.success("Successfully saved The Movie Database settings. Restart the server to refresh the cache."); } else { this.notificationService.success("There was an error when saving The Movie Database settings"); } diff --git a/src/Ombi/ClientApp/src/app/settings/update/update.component.ts b/src/Ombi/ClientApp/src/app/settings/update/update.component.ts index d4648b35b..e553dffbe 100644 --- a/src/Ombi/ClientApp/src/app/settings/update/update.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/update/update.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup } from "@angular/forms"; import { NotificationService } from "../../services"; import { JobService, SettingsService } from "../../services"; @@ -10,7 +10,7 @@ import { JobService, SettingsService } from "../../services"; }) export class UpdateComponent implements OnInit { - public form: FormGroup; + public form: UntypedFormGroup; public updateAvailable = false; public enableUpdateButton = false; public isWindows = false; @@ -22,7 +22,7 @@ export class UpdateComponent implements OnInit { constructor(private settingsService: SettingsService, private notificationService: NotificationService, private updateService: JobService, - private fb: FormBuilder) { } + private fb: UntypedFormBuilder) { } public ngOnInit() { this.settingsService.getUpdateSettings() @@ -59,7 +59,7 @@ export class UpdateComponent implements OnInit { this.notificationService.success("We triggered the update job"); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/settings/vote/vote.component.ts b/src/Ombi/ClientApp/src/app/settings/vote/vote.component.ts index d0804b4b2..9e9deea56 100644 --- a/src/Ombi/ClientApp/src/app/settings/vote/vote.component.ts +++ b/src/Ombi/ClientApp/src/app/settings/vote/vote.component.ts @@ -1,5 +1,5 @@ import { Component, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { NotificationService, SettingsService } from "../../services"; @@ -9,10 +9,10 @@ import { NotificationService, SettingsService } from "../../services"; }) export class VoteComponent implements OnInit { - public form: FormGroup; + public form: UntypedFormGroup; constructor(private settingsService: SettingsService, - private readonly fb: FormBuilder, + private readonly fb: UntypedFormBuilder, private notificationService: NotificationService) { } public ngOnInit() { @@ -26,7 +26,7 @@ export class VoteComponent implements OnInit { }); } - public onSubmit(form: FormGroup) { + public onSubmit(form: UntypedFormGroup) { if (form.invalid) { this.notificationService.error("Please check your entered values"); return; diff --git a/src/Ombi/ClientApp/src/app/shared/admin-request-dialog/admin-request-dialog.component.ts b/src/Ombi/ClientApp/src/app/shared/admin-request-dialog/admin-request-dialog.component.ts index acf6560b9..4372590d3 100644 --- a/src/Ombi/ClientApp/src/app/shared/admin-request-dialog/admin-request-dialog.component.ts +++ b/src/Ombi/ClientApp/src/app/shared/admin-request-dialog/admin-request-dialog.component.ts @@ -1,7 +1,7 @@ import { Component, Inject, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup } from "@angular/forms"; import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog"; -import { Observable } from "rxjs"; +import { firstValueFrom, Observable } from "rxjs"; import { startWith, map } from "rxjs/operators"; import { ILanguageProfiles, IRadarrProfile, IRadarrRootFolder, ISonarrProfile, ISonarrRootFolder, ISonarrSettings, IUserDropdown, RequestType } from "../../interfaces"; import { IdentityService, MessageService, RadarrService, RequestService, SettingsService, SonarrService } from "../../services"; @@ -25,10 +25,10 @@ export class AdminRequestDialogComponent implements OnInit { private sonarrService: SonarrService, private settingsService: SettingsService, private radarrService: RadarrService, - private fb: FormBuilder + private fb: UntypedFormBuilder ) {} - public form: FormGroup; + public form: UntypedFormGroup; public RequestType = RequestType; public options: IUserDropdown[]; @@ -55,7 +55,7 @@ export class AdminRequestDialogComponent implements OnInit { radarrFolderId: [null] }) - this.options = await this.identityService.getUsersDropdown().toPromise(); + this.options = await firstValueFrom(this.identityService.getUsersDropdown()); this.filteredOptions = this.form.controls['username'].valueChanges.pipe( startWith(""), @@ -96,7 +96,10 @@ export class AdminRequestDialogComponent implements OnInit { public displayFn(user: IUserDropdown): string { const username = user?.username ? user.username : ""; const email = user?.email ? `(${user.email})` : ""; - return `${username} ${email}`; + if (username || email) { + return `${username} ${email}`; + } + return ''; } private _filter(value: string | IUserDropdown): IUserDropdown[] { diff --git a/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog-data.service.ts b/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog-data.service.ts index c6312915a..480751e78 100644 --- a/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog-data.service.ts +++ b/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog-data.service.ts @@ -8,7 +8,9 @@ import { RequestType } from "../../interfaces"; export class AdvancedSearchDialogDataService { @Output() public onDataChange = new EventEmitter(); + @Output() public onOptionsChange = new EventEmitter(); private _data: any; + private _options: any; private _type: RequestType; setData(data: any, type: RequestType) { @@ -17,10 +19,30 @@ export class AdvancedSearchDialogDataService { this.onDataChange.emit(this._data); } + setOptions(watchProviders: number[], genres: number[], keywords: number[], releaseYear: number, type: RequestType, position: number) { + this._options = { + watchProviders, + genres, + keywords, + releaseYear, + type, + position + }; + this.onOptionsChange.emit(this._options); + } + getData(): any { return this._data; } + getOptions(): any { + return this._options; + } + + getLoaded(): number { + return this._options.loaded; + } + getType(): RequestType { return this._type; } diff --git a/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.html b/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.html index b0ff4a81e..d5bf4defc 100644 --- a/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.html +++ b/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.html @@ -33,7 +33,6 @@
- {{ "Search.YearOfRelease" | translate }}
diff --git a/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.ts b/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.ts index 614d2d103..7e58b3790 100644 --- a/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.ts +++ b/src/Ombi/ClientApp/src/app/shared/advanced-search-dialog/advanced-search-dialog.component.ts @@ -1,5 +1,5 @@ import { Component, Inject, OnInit } from "@angular/core"; -import { FormBuilder, FormGroup } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup } from "@angular/forms"; import { MatDialogRef, MAT_DIALOG_DATA } from "@angular/material/dialog"; import { RequestType } from "../../interfaces"; import { SearchV2Service } from "../../services"; @@ -13,12 +13,12 @@ import { AdvancedSearchDialogDataService } from "./advanced-search-dialog-data.s export class AdvancedSearchDialogComponent implements OnInit { constructor( public dialogRef: MatDialogRef, - private fb: FormBuilder, + private fb: UntypedFormBuilder, private searchService: SearchV2Service, private advancedSearchDialogService: AdvancedSearchDialogDataService ) {} - public form: FormGroup; + public form: UntypedFormGroup; public async ngOnInit() { @@ -49,7 +49,9 @@ export class AdvancedSearchDialogComponent implements OnInit { type: formData.type, }, 0, 30); - this.advancedSearchDialogService.setData(data, formData.type === 'movie' ? RequestType.movie : RequestType.tvShow); + const type = formData.type === 'movie' ? RequestType.movie : RequestType.tvShow; + this.advancedSearchDialogService.setData(data, type); + this.advancedSearchDialogService.setOptions(watchProviderIds, genres, keywords, formData.releaseYear, type, 30); this.dialogRef.close(true); } diff --git a/src/Ombi/ClientApp/src/app/shared/chat-box/chat-box.component.html b/src/Ombi/ClientApp/src/app/shared/chat-box/chat-box.component.html index 201c10a9f..a8fc88578 100644 --- a/src/Ombi/ClientApp/src/app/shared/chat-box/chat-box.component.html +++ b/src/Ombi/ClientApp/src/app/shared/chat-box/chat-box.component.html @@ -1,7 +1,7 @@
-

Users

+

{{ "NavigationBar.UserManagement" | translate }}

{{user}}

@@ -19,7 +19,7 @@
- - + +
\ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/shared/components/genre-select/genre-select.component.html b/src/Ombi/ClientApp/src/app/shared/components/genre-select/genre-select.component.html index 4e5bf394a..b28f7de02 100644 --- a/src/Ombi/ClientApp/src/app/shared/components/genre-select/genre-select.component.html +++ b/src/Ombi/ClientApp/src/app/shared/components/genre-select/genre-select.component.html @@ -10,7 +10,7 @@ cancel { + this.searchService.getGenres(this._mediaType).subscribe((res) => { this.genres = res; this.filteredKeywords = this.control.valueChanges.pipe( startWith(''), @@ -33,7 +33,7 @@ export class GenreSelectComponent { return this._mediaType; } public genres: IMovieDbKeyword[] = []; - public control = new FormControl(); + public control = new UntypedFormControl(); public filteredTags: IMovieDbKeyword[]; public filteredKeywords: Observable; diff --git a/src/Ombi/ClientApp/src/app/shared/components/keyword-search/keyword-search.component.html b/src/Ombi/ClientApp/src/app/shared/components/keyword-search/keyword-search.component.html index e99521c1f..6b03553f6 100644 --- a/src/Ombi/ClientApp/src/app/shared/components/keyword-search/keyword-search.component.html +++ b/src/Ombi/ClientApp/src/app/shared/components/keyword-search/keyword-search.component.html @@ -9,7 +9,7 @@ cancel ; diff --git a/src/Ombi/ClientApp/src/app/shared/components/watch-providers-select/watch-providers-select.component.html b/src/Ombi/ClientApp/src/app/shared/components/watch-providers-select/watch-providers-select.component.html index b2ea3a99c..f66f833b4 100644 --- a/src/Ombi/ClientApp/src/app/shared/components/watch-providers-select/watch-providers-select.component.html +++ b/src/Ombi/ClientApp/src/app/shared/components/watch-providers-select/watch-providers-select.component.html @@ -9,7 +9,7 @@ cancel ; diff --git a/src/Ombi/ClientApp/src/app/shared/issues-report.component.ts b/src/Ombi/ClientApp/src/app/shared/issues-report.component.ts index 498ff1757..cd5810bc1 100644 --- a/src/Ombi/ClientApp/src/app/shared/issues-report.component.ts +++ b/src/Ombi/ClientApp/src/app/shared/issues-report.component.ts @@ -1,5 +1,4 @@ import { Component, EventEmitter, Input, Output } from "@angular/core"; - import { IIssueCategory, IIssues, IssueStatus, RequestType } from "../interfaces"; import { IssuesService, NotificationService } from "../services"; @@ -44,6 +43,7 @@ export class IssuesReportComponent { title: "", providerId: "", userReported: undefined, + posterPath: undefined }; } @@ -55,6 +55,7 @@ export class IssuesReportComponent { issue.issueCategoryId = this.issueCategory.id; issue.title = this.title; issue.providerId = this.providerId; + issue.posterPath = this.posterPath; if (this.movie) { issue.requestType = RequestType.movie; } else { diff --git a/src/Ombi/ClientApp/src/app/shared/role-directive/role-directive.ts b/src/Ombi/ClientApp/src/app/shared/role-directive/role-directive.ts new file mode 100644 index 000000000..3fa4cad56 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/shared/role-directive/role-directive.ts @@ -0,0 +1,36 @@ +import { Directive, Input, OnInit, TemplateRef, ViewContainerRef } from "@angular/core"; +import { AuthService } from "../../auth/auth.service"; + +@Directive({ + selector: '[permission]', +}) +export class RoleDirective implements OnInit { + private roleName: string; + + private isHidden = true; + + @Input() public set permission(val: string) { + if (val) { + this.roleName = val; + this.updateView(); + } + } + + public constructor(private templateRef: TemplateRef, private viewContainer: ViewContainerRef, private auth: AuthService) {} + + public ngOnInit(): void { + this.updateView(); + } + + private updateView(): void { + if (this.auth.hasRole(this.roleName) || this.auth.hasRole("admin")) { + if (this.isHidden) { + this.viewContainer.createEmbeddedView(this.templateRef); + this.isHidden = false; + } + } else { + this.viewContainer.clear(); + this.isHidden = true; + } + } +} diff --git a/src/Ombi/ClientApp/src/app/shared/role-directive/role.module.ts b/src/Ombi/ClientApp/src/app/shared/role-directive/role.module.ts new file mode 100644 index 000000000..15cea8923 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/shared/role-directive/role.module.ts @@ -0,0 +1,8 @@ +import { NgModule } from '@angular/core'; +import { RoleDirective } from './role-directive'; + +@NgModule({ + declarations: [RoleDirective], + exports: [RoleDirective], +}) +export class RoleModule {} diff --git a/src/Ombi/ClientApp/src/app/shared/shared.module.ts b/src/Ombi/ClientApp/src/app/shared/shared.module.ts index 01d70f1c6..87ea0051c 100644 --- a/src/Ombi/ClientApp/src/app/shared/shared.module.ts +++ b/src/Ombi/ClientApp/src/app/shared/shared.module.ts @@ -37,9 +37,9 @@ import { MatTooltipModule } from '@angular/material/tooltip'; import { MatTreeModule } from '@angular/material/tree'; import { MomentModule } from "ngx-moment"; import { NgModule } from "@angular/core"; -import { SidebarModule } from "primeng/sidebar"; import { PipeModule } from "../pipes/pipe.module"; -import { TheMovieDbService } from "../services"; +import { RoleModule } from "./role-directive/role.module"; +import { SidebarModule } from "primeng/sidebar"; import { TranslateModule } from "@ngx-translate/core"; import { TruncateModule } from "@yellowspot/ng-truncate"; import { WatchProvidersSelectComponent } from "./components/watch-providers-select/watch-providers-select.component"; @@ -56,6 +56,7 @@ import { WatchProvidersSelectComponent } from "./components/watch-providers-sele WatchProvidersSelectComponent, ], imports: [ + RoleModule, SidebarModule, ReactiveFormsModule, FormsModule, @@ -91,6 +92,7 @@ import { WatchProvidersSelectComponent } from "./components/watch-providers-sele PipeModule, ], exports: [ + RoleModule, TranslateModule, CommonModule, FormsModule, diff --git a/src/Ombi/ClientApp/src/app/state/customization/customization.state.ts b/src/Ombi/ClientApp/src/app/state/customization/customization.state.ts index 57b3f5908..5261183c3 100644 --- a/src/Ombi/ClientApp/src/app/state/customization/customization.state.ts +++ b/src/Ombi/ClientApp/src/app/state/customization/customization.state.ts @@ -6,7 +6,6 @@ import { ICustomizationSettings } from "../../interfaces"; import { Injectable } from "@angular/core"; import { Observable } from "rxjs"; import { SettingsService } from "../../services"; -import { produce } from 'immer'; import { tap } from "rxjs/operators"; @State({ diff --git a/src/Ombi/ClientApp/src/app/state/features/features-initializer.ts b/src/Ombi/ClientApp/src/app/state/features/features-initializer.ts new file mode 100644 index 000000000..2324259f3 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/state/features/features-initializer.ts @@ -0,0 +1,10 @@ +import { APP_INITIALIZER } from "@angular/core"; +import { FeaturesFacade } from "./features.facade"; +import { Observable } from "rxjs"; + +export const FEATURES_INITIALIZER = { + provide: APP_INITIALIZER, + useFactory: (featureFacade: FeaturesFacade) => (): Observable => featureFacade.loadFeatures(), + multi: true, + deps: [FeaturesFacade], +}; \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/state/features/features.actions.ts b/src/Ombi/ClientApp/src/app/state/features/features.actions.ts new file mode 100644 index 000000000..fcb517828 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/state/features/features.actions.ts @@ -0,0 +1,15 @@ +import { IFeatureEnablement } from "../../interfaces"; + +export class LoadFeatures { + public static readonly type = '[Features] LoadAll'; +} +export class EnableFeature { + public static readonly type = '[Features] Enable'; + + constructor(public feature: IFeatureEnablement) { } +} +export class DisableFeature { + public static readonly type = '[Features] Disable'; + + constructor(public feature: IFeatureEnablement) { } +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/state/features/features.facade.ts b/src/Ombi/ClientApp/src/app/state/features/features.facade.ts new file mode 100644 index 000000000..10e229eba --- /dev/null +++ b/src/Ombi/ClientApp/src/app/state/features/features.facade.ts @@ -0,0 +1,26 @@ +import { DisableFeature, EnableFeature, LoadFeatures } from "./features.actions"; + +import { FeaturesSelectors } from "./features.selectors"; +import { IFeatureEnablement } from "../../interfaces"; +import { Injectable } from "@angular/core"; +import { Observable } from "rxjs"; +import { Store } from "@ngxs/store"; + +@Injectable({ + providedIn: 'root', +}) +export class FeaturesFacade { + + public constructor(private store: Store) {} + + public features$ = (): Observable => this.store.select(FeaturesSelectors.features); + + public enable = (feature: IFeatureEnablement): Observable => this.store.dispatch(new EnableFeature(feature)); + + public disable = (feature: IFeatureEnablement): Observable => this.store.dispatch(new DisableFeature(feature)); + + public loadFeatures = (): Observable => this.store.dispatch(new LoadFeatures()); + + public is4kEnabled = (): boolean => this.store.selectSnapshot(FeaturesSelectors.is4kEnabled); + +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/state/features/features.selectors.ts b/src/Ombi/ClientApp/src/app/state/features/features.selectors.ts new file mode 100644 index 000000000..143dfb875 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/state/features/features.selectors.ts @@ -0,0 +1,18 @@ +import { ICustomizationSettings, IFeatureEnablement } from "../../interfaces"; + +import { FEATURES_STATE_TOKEN } from "./types"; +import { Selector } from "@ngxs/store"; + +export class FeaturesSelectors { + + @Selector([FEATURES_STATE_TOKEN]) + public static features(features: IFeatureEnablement[]): IFeatureEnablement[] { + return features; + } + + @Selector([FeaturesSelectors.features]) + public static is4kEnabled(features: IFeatureEnablement[]): boolean { + return features.filter(x => x.name === "Movie4KRequests")[0].enabled; + } + +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/state/features/features.state.ts b/src/Ombi/ClientApp/src/app/state/features/features.state.ts new file mode 100644 index 000000000..4e014db7c --- /dev/null +++ b/src/Ombi/ClientApp/src/app/state/features/features.state.ts @@ -0,0 +1,40 @@ +import { Action, State, StateContext } from "@ngxs/store"; +import { DisableFeature, EnableFeature, LoadFeatures } from "./features.actions"; + +import { FEATURES_STATE_TOKEN } from "./types"; +import { FeatureService } from "../../services/feature.service"; +import { IFeatureEnablement } from "../../interfaces"; +import { Injectable } from "@angular/core"; +import { Observable } from "rxjs"; +import { tap } from "rxjs/operators"; + +@State({ + name: FEATURES_STATE_TOKEN +}) +@Injectable() +export class FeatureState { + constructor(private featuresService: FeatureService) { } + + @Action(LoadFeatures) + public load({ setState }: StateContext): Observable { + return this.featuresService.getFeatures().pipe( + tap(features => + setState(features) + ) + ); + } + + @Action(EnableFeature) + public enable({ setState }: StateContext, { feature }: EnableFeature): Observable { + return this.featuresService.enable(feature).pipe( + tap((result) => setState(result)) + ); + } + + @Action(DisableFeature) + public disable({ setState }: StateContext, { feature }: DisableFeature): Observable { + return this.featuresService.disable(feature).pipe( + tap((result) => setState(result)) + ); + } +} \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/state/features/index.ts b/src/Ombi/ClientApp/src/app/state/features/index.ts new file mode 100644 index 000000000..e0fec5274 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/state/features/index.ts @@ -0,0 +1,4 @@ +export * from './features.state'; +export * from './features.actions'; +export * from './features.facade'; +export * from './features.selectors'; diff --git a/src/Ombi/ClientApp/src/app/state/features/types.ts b/src/Ombi/ClientApp/src/app/state/features/types.ts new file mode 100644 index 000000000..d8fdc09a1 --- /dev/null +++ b/src/Ombi/ClientApp/src/app/state/features/types.ts @@ -0,0 +1,4 @@ +import { IFeatureEnablement } from "../../interfaces"; +import { StateToken } from "@ngxs/store"; + +export const FEATURES_STATE_TOKEN = new StateToken('featureEnablement'); \ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/unsubscribe/components/confirm-component/unsubscribe-confirm.component.html b/src/Ombi/ClientApp/src/app/unsubscribe/components/confirm-component/unsubscribe-confirm.component.html index 64bc89b22..c1df10a9f 100644 --- a/src/Ombi/ClientApp/src/app/unsubscribe/components/confirm-component/unsubscribe-confirm.component.html +++ b/src/Ombi/ClientApp/src/app/unsubscribe/components/confirm-component/unsubscribe-confirm.component.html @@ -1,3 +1,3 @@
-

Unsubscribed!

+

{{ 'UserPreferences.Unsubscribed' | translate }}

\ No newline at end of file diff --git a/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.ts b/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.ts index 32ba813cc..74a803161 100644 --- a/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.ts +++ b/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.component.ts @@ -5,7 +5,7 @@ import { AvailableLanguages } from "./user-preference.constants"; import { IdentityService, NotificationService, ValidationService } from "../../../services"; import { IUser, UserType } from "../../../interfaces"; import { Md5 } from "ts-md5"; -import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms"; import { APP_BASE_HREF } from "@angular/common"; import { CustomizationFacade } from "../../../state/customization"; @@ -26,7 +26,7 @@ export class UserPreferenceComponent implements OnInit { public UserType = UserType; public baseUrl: string; - public passwordForm: FormGroup; + public passwordForm: UntypedFormGroup; private user: IUser; private applicationUrl: string = this.customizationFacade.appUrl(); @@ -36,7 +36,7 @@ export class UserPreferenceComponent implements OnInit { private readonly translate: TranslateService, private readonly notification: NotificationService, private readonly identityService: IdentityService, - private readonly fb: FormBuilder, + private readonly fb: UntypedFormBuilder, private readonly validationService: ValidationService, private readonly customizationFacade: CustomizationFacade, @Inject(APP_BASE_HREF) public internalBaseUrl: string) { } diff --git a/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.constants.ts b/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.constants.ts index 21416d056..d5101fa52 100644 --- a/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.constants.ts +++ b/src/Ombi/ClientApp/src/app/user-preferences/components/user-preference/user-preference.constants.ts @@ -14,6 +14,8 @@ export const AvailableLanguages: ILanguage[] = [ { display: 'Svenska', value: 'sv' }, { display: 'Български', value: 'bg' }, { display: 'Русский', value: 'ru' }, + { display: 'čeština', value: 'cs' }, + { display: '简体中文', value: 'zh' }, ]; export interface ILanguage { diff --git a/src/Ombi/ClientApp/src/app/usermanagement/usermanagement-user.component.ts b/src/Ombi/ClientApp/src/app/usermanagement/usermanagement-user.component.ts index 9b9e8bdfd..bc6319198 100644 --- a/src/Ombi/ClientApp/src/app/usermanagement/usermanagement-user.component.ts +++ b/src/Ombi/ClientApp/src/app/usermanagement/usermanagement-user.component.ts @@ -6,6 +6,7 @@ import { IdentityService, MessageService, RadarrService, SettingsService, Sonarr import { Clipboard } from '@angular/cdk/clipboard'; import { CustomizationFacade } from "../state/customization"; import { Location } from "@angular/common"; +import { FeaturesFacade } from "../state/features/features.facade"; @Component({ templateUrl: "./usermanagement-user.component.html", @@ -36,7 +37,6 @@ export class UserManagementUserComponent implements OnInit { constructor(private identityService: IdentityService, private notificationService: MessageService, - private readonly settingsService: SettingsService, private router: Router, private route: ActivatedRoute, private sonarrService: SonarrService, @@ -44,32 +44,54 @@ export class UserManagementUserComponent implements OnInit { private clipboard: Clipboard, private location: Location, private customizationFacade: CustomizationFacade, + private featureFacade: FeaturesFacade, ) { this.route.params.subscribe((params: any) => { if(params.id) { this.userId = params.id; this.edit = true; - this.identityService.getUserById(this.userId).subscribe(x => { - this.user = x; - }); } }); } public ngOnInit() { + const is4KEnabled = this.featureFacade.is4kEnabled(); + this.identityService.getUserById(this.userId).subscribe(x => { + this.user = x; + if (!is4KEnabled) { + this.user.claims = this.user.claims.filter(x => x.value !== "Request4KMovie"); + } + }); this.requestLimitTypes = [RequestLimitType.Day, RequestLimitType.Week, RequestLimitType.Month]; this.identityService.getSupportedStreamingCountries().subscribe(x => this.countries = x); - this.identityService.getAllAvailableClaims().subscribe(x => this.availableClaims = x); + this.identityService.getAllAvailableClaims().subscribe(x => { + this.availableClaims = x; + if (!is4KEnabled) { + this.availableClaims = this.availableClaims.filter(y => y.value !== "Request4KMovie"); + } + }); if(this.edit) { this.identityService.getNotificationPreferencesForUser(this.userId).subscribe(x => this.notificationPreferences = x); } else { this.identityService.getNotificationPreferences().subscribe(x => this.notificationPreferences = x); } - this.sonarrService.getQualityProfilesWithoutSettings().subscribe(x => this.sonarrQualities = x); - this.sonarrService.getRootFoldersWithoutSettings().subscribe(x => this.sonarrRootFolders = x); - this.radarrService.getQualityProfilesFromSettings().subscribe(x => this.radarrQualities = x); - this.radarrService.getRootFoldersFromSettings().subscribe(x => this.radarrRootFolders = x); + this.sonarrService.getQualityProfilesWithoutSettings().subscribe(x => { + this.sonarrQualities = x; + this.sonarrQualities.unshift({id: 0, name: "None"}); + }); + this.sonarrService.getRootFoldersWithoutSettings().subscribe(x => { + this.sonarrRootFolders = x; + this.sonarrRootFolders.unshift({id: 0, path: "None"}); + }); + this.radarrService.getQualityProfilesFromSettings().subscribe(x => { + this.radarrQualities = x; + this.radarrQualities.unshift({id: 0, name: "None"}); + }); + this.radarrService.getRootFoldersFromSettings().subscribe(x => { + this.radarrRootFolders = x; + this.radarrRootFolders.unshift({id: 0, path: "None"}); + }); this.identityService.getUserAccessToken(this.userId).subscribe(x => this.accessToken = x); @@ -179,6 +201,7 @@ export class UserManagementUserComponent implements OnInit { return; } + this.identityService.updateUser(this.user).subscribe(x => { if (x.successful) { this.identityService.updateNotificationPreferences(this.notificationPreferences).subscribe(); diff --git a/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.html b/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.html index f79188ae9..0d5171741 100644 --- a/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.html +++ b/src/Ombi/ClientApp/src/app/usermanagement/usermanagement.component.html @@ -2,7 +2,7 @@
- + Add User To Ombi @@ -105,7 +105,7 @@
- + Edit