diff --git a/.github/labeler.yml b/.github/labeler.yml index c0c52f1d7e..d8923a3035 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -6,7 +6,6 @@ cli: documentation: - changed-files: - any-glob-to-any-file: - - docs/blob/** - docs/docs/** - docs/src/** - docs/static/** diff --git a/.github/workflows/build-mobile.yml b/.github/workflows/build-mobile.yml index 1b57731b23..0996c8eccb 100644 --- a/.github/workflows/build-mobile.yml +++ b/.github/workflows/build-mobile.yml @@ -36,7 +36,7 @@ jobs: steps: - name: Check what should run id: check - uses: immich-app/devtools/actions/pre-job@24820aa4ef67959b0dcf69a438cccf00d7c7042b # pre-job-action-v1.0.1 + uses: immich-app/devtools/actions/pre-job@5f91b52dfbb92b8d96ca411ab59c896cd59714ca # pre-job-action-v1.1.0 with: filters: | mobile: @@ -73,7 +73,7 @@ jobs: - name: Restore Gradle Cache id: cache-gradle-restore - uses: actions/cache/restore@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 + uses: actions/cache/restore@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: path: | ~/.gradle/caches @@ -130,7 +130,7 @@ jobs: - name: Save Gradle Cache id: cache-gradle-save - uses: actions/cache/save@0400d5f644dc74513175e3cd8d07132dd4860809 # v4 + uses: actions/cache/save@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 if: github.ref == 'refs/heads/main' with: path: | diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index a630d27809..09528346fc 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -24,7 +24,7 @@ jobs: steps: - name: Check what should run id: check - uses: immich-app/devtools/actions/pre-job@24820aa4ef67959b0dcf69a438cccf00d7c7042b # pre-job-action-v1.0.1 + uses: immich-app/devtools/actions/pre-job@5f91b52dfbb92b8d96ca411ab59c896cd59714ca # pre-job-action-v1.1.0 with: filters: | server: diff --git a/.github/workflows/docs-build.yml b/.github/workflows/docs-build.yml index 9a35a0ae91..0879c30386 100644 --- a/.github/workflows/docs-build.yml +++ b/.github/workflows/docs-build.yml @@ -22,7 +22,7 @@ jobs: steps: - name: Check what should run id: check - uses: immich-app/devtools/actions/pre-job@24820aa4ef67959b0dcf69a438cccf00d7c7042b # pre-job-action-v1.0.1 + uses: immich-app/devtools/actions/pre-job@5f91b52dfbb92b8d96ca411ab59c896cd59714ca # pre-job-action-v1.1.0 with: filters: | docs: diff --git a/.github/workflows/fix-format.yml b/.github/workflows/fix-format.yml index bec34c2713..849de79a47 100644 --- a/.github/workflows/fix-format.yml +++ b/.github/workflows/fix-format.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1 + uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} diff --git a/.github/workflows/merge-translations.yml b/.github/workflows/merge-translations.yml index a0329c8f73..d494460320 100644 --- a/.github/workflows/merge-translations.yml +++ b/.github/workflows/merge-translations.yml @@ -10,6 +10,11 @@ on: required: true WEBLATE_TOKEN: required: true + inputs: + skip: + description: 'Skip translations' + required: false + type: boolean permissions: {} @@ -25,6 +30,7 @@ jobs: steps: - name: Find translation PR id: find_pr + if: ${{ inputs.skip != true }} env: GH_TOKEN: ${{ github.token }} run: | @@ -51,18 +57,21 @@ jobs: - name: Generate a token id: generate_token - uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1 + if: ${{ inputs.skip != true }} + uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} - name: Lock weblate + if: ${{ inputs.skip != true }} env: WEBLATE_TOKEN: ${{ secrets.WEBLATE_TOKEN }} run: | curl --fail-with-body -X POST -H "Authorization: Token $WEBLATE_TOKEN" "$WEBLATE_HOST/api/components/$WEBLATE_COMPONENT/lock/" -d lock=true - name: Commit translations + if: ${{ inputs.skip != true }} env: WEBLATE_TOKEN: ${{ secrets.WEBLATE_TOKEN }} run: | @@ -71,6 +80,7 @@ jobs: - name: Merge PR id: merge_pr + if: ${{ inputs.skip != true }} env: GH_TOKEN: ${{ steps.generate_token.outputs.token }} PR_NUMBER: ${{ steps.find_pr.outputs.PR_NUMBER }} @@ -83,6 +93,7 @@ jobs: gh pr merge "$PR_NUMBER" --repo "$GITHUB_REPOSITORY" --auto --squash - name: Wait for PR to merge + if: ${{ inputs.skip != true }} env: GH_TOKEN: ${{ steps.generate_token.outputs.token }} PR_NUMBER: ${{ steps.find_pr.outputs.PR_NUMBER }} @@ -106,7 +117,12 @@ jobs: exit 1 - name: Unlock weblate + if: ${{ inputs.skip != true }} env: WEBLATE_TOKEN: ${{ secrets.WEBLATE_TOKEN }} run: | curl --fail-with-body -X POST -H "Authorization: Token $WEBLATE_TOKEN" "$WEBLATE_HOST/api/components/$WEBLATE_COMPONENT/lock/" -d lock=false + + - name: Report success + run: | + echo "Workflow completed successfully (or was skipped)" diff --git a/.github/workflows/prepare-release.yml b/.github/workflows/prepare-release.yml index add68ffbd7..8b6dc0af1c 100644 --- a/.github/workflows/prepare-release.yml +++ b/.github/workflows/prepare-release.yml @@ -10,12 +10,17 @@ on: type: choice options: - 'false' + - major - minor - patch mobileBump: description: 'Bump mobile build number' required: false type: boolean + skipTranslations: + description: 'Skip translations' + required: false + type: boolean concurrency: group: ${{ github.workflow }}-${{ github.ref }}-root @@ -26,6 +31,8 @@ permissions: {} jobs: merge_translations: uses: ./.github/workflows/merge-translations.yml + with: + skip: ${{ inputs.skipTranslations }} permissions: pull-requests: write secrets: @@ -35,13 +42,14 @@ jobs: bump_version: runs-on: ubuntu-latest + needs: [merge_translations] outputs: ref: ${{ steps.push-tag.outputs.commit_long_sha }} permissions: {} # No job-level permissions are needed because it uses the app-token steps: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1 + uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} @@ -51,6 +59,7 @@ jobs: with: token: ${{ steps.generate-token.outputs.token }} persist-credentials: true + ref: main - name: Install uv uses: astral-sh/setup-uv@d4b2f3b6ecc6e67c4457f6d3e41ec42d3d0fcb86 # v5.4.2 @@ -102,7 +111,7 @@ jobs: steps: - name: Generate a token id: generate-token - uses: actions/create-github-app-token@a8d616148505b5069dccd32f177bb87d7f39123b # v2.1.1 + uses: actions/create-github-app-token@67018539274d69449ef7c02e8e71183d1719ab42 # v2.1.4 with: app-id: ${{ secrets.PUSH_O_MATIC_APP_ID }} private-key: ${{ secrets.PUSH_O_MATIC_APP_KEY }} diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index f5e68fb42d..d30f95422c 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -21,7 +21,7 @@ jobs: steps: - name: Check what should run id: check - uses: immich-app/devtools/actions/pre-job@24820aa4ef67959b0dcf69a438cccf00d7c7042b # pre-job-action-v1.0.1 + uses: immich-app/devtools/actions/pre-job@5f91b52dfbb92b8d96ca411ab59c896cd59714ca # pre-job-action-v1.1.0 with: filters: | mobile: diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 773d14e171..ffc5b41f73 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,7 +18,7 @@ jobs: steps: - name: Check what should run id: check - uses: immich-app/devtools/actions/pre-job@24820aa4ef67959b0dcf69a438cccf00d7c7042b # pre-job-action-v1.0.1 + uses: immich-app/devtools/actions/pre-job@5f91b52dfbb92b8d96ca411ab59c896cd59714ca # pre-job-action-v1.1.0 with: filters: | i18n: diff --git a/.github/workflows/weblate-lock.yml b/.github/workflows/weblate-lock.yml index 36544d4eed..d7deb244f9 100644 --- a/.github/workflows/weblate-lock.yml +++ b/.github/workflows/weblate-lock.yml @@ -25,7 +25,7 @@ jobs: steps: - name: Check what should run id: check - uses: immich-app/devtools/actions/pre-job@24820aa4ef67959b0dcf69a438cccf00d7c7042b # pre-job-action-v1.0.1 + uses: immich-app/devtools/actions/pre-job@5f91b52dfbb92b8d96ca411ab59c896cd59714ca # pre-job-action-v1.1.0 with: filters: | i18n: diff --git a/cli/package.json b/cli/package.json index 5b9b2d810c..d2ae9063b4 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "@immich/cli", - "version": "2.2.90", + "version": "2.2.94", "description": "Command Line Interface (CLI) for Immich", "type": "module", "exports": "./dist/index.js", diff --git a/deployment/.env b/deployment/.env new file mode 100644 index 0000000000..f6ce050d29 --- /dev/null +++ b/deployment/.env @@ -0,0 +1,4 @@ +export CLOUDFLARE_ACCOUNT_ID="op://tf/cloudflare/account_id" +export CLOUDFLARE_API_TOKEN="op://tf/cloudflare/api_token" +export TF_STATE_POSTGRES_CONN_STR="op://tf/tf_state/postgres_conn_str" +export TF_VAR_env=$ENVIRONMENT diff --git a/deployment/modules/cloudflare/docs-release/domain.tf b/deployment/modules/cloudflare/docs-release/domain.tf index 0602045f71..3a6f479a74 100644 --- a/deployment/modules/cloudflare/docs-release/domain.tf +++ b/deployment/modules/cloudflare/docs-release/domain.tf @@ -1,11 +1,11 @@ resource "cloudflare_pages_domain" "immich_app_release_domain" { account_id = var.cloudflare_account_id project_name = data.terraform_remote_state.cloudflare_account.outputs.immich_app_archive_pages_project_name - domain = "immich.app" + domain = "docs.immich.app" } resource "cloudflare_record" "immich_app_release_domain" { - name = "immich.app" + name = "docs.immich.app" proxied = true ttl = 1 type = "CNAME" diff --git a/deployment/modules/cloudflare/docs/domain.tf b/deployment/modules/cloudflare/docs/domain.tf index a28fb4c0f8..c5f77de6b4 100644 --- a/deployment/modules/cloudflare/docs/domain.tf +++ b/deployment/modules/cloudflare/docs/domain.tf @@ -1,11 +1,11 @@ resource "cloudflare_pages_domain" "immich_app_branch_domain" { account_id = var.cloudflare_account_id project_name = local.is_release ? data.terraform_remote_state.cloudflare_account.outputs.immich_app_archive_pages_project_name : data.terraform_remote_state.cloudflare_account.outputs.immich_app_preview_pages_project_name - domain = "${var.prefix_name}.${local.deploy_domain_prefix}.immich.app" + domain = "docs.${var.prefix_name}.${local.deploy_domain_prefix}.immich.app" } resource "cloudflare_record" "immich_app_branch_subdomain" { - name = "${var.prefix_name}.${local.deploy_domain_prefix}.immich.app" + name = "docs.${var.prefix_name}.${local.deploy_domain_prefix}.immich.app" proxied = true ttl = 1 type = "CNAME" diff --git a/docker/docker-compose.dev.yml b/docker/docker-compose.dev.yml index f97cf0ca0d..bd41ed8d62 100644 --- a/docker/docker-compose.dev.yml +++ b/docker/docker-compose.dev.yml @@ -140,7 +140,7 @@ services: database: container_name: immich_postgres - image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:c44be5f2871c59362966d71eab4268170eb6f5653c0e6170184e72b38ffdf107 + image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:41eacbe83eca995561fe43814fd4891e16e39632806253848efaf04d3c8a8b84 env_file: - .env environment: diff --git a/docker/docker-compose.prod.yml b/docker/docker-compose.prod.yml index c3fb9c7736..dcdfc72c82 100644 --- a/docker/docker-compose.prod.yml +++ b/docker/docker-compose.prod.yml @@ -63,7 +63,7 @@ services: database: container_name: immich_postgres - image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:c44be5f2871c59362966d71eab4268170eb6f5653c0e6170184e72b38ffdf107 + image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:41eacbe83eca995561fe43814fd4891e16e39632806253848efaf04d3c8a8b84 env_file: - .env environment: diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 3316c17839..c3ded93ba9 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -56,7 +56,7 @@ services: database: container_name: immich_postgres - image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:c44be5f2871c59362966d71eab4268170eb6f5653c0e6170184e72b38ffdf107 + image: ghcr.io/immich-app/postgres:14-vectorchord0.4.3-pgvectors0.2.0@sha256:41eacbe83eca995561fe43814fd4891e16e39632806253848efaf04d3c8a8b84 environment: POSTGRES_PASSWORD: ${DB_PASSWORD} POSTGRES_USER: ${DB_USERNAME} diff --git a/docs/blog/2022/11-10/release-1.36.mdx b/docs/blog/2022/11-10/release-1.36.mdx deleted file mode 100644 index 5f5643196c..0000000000 --- a/docs/blog/2022/11-10/release-1.36.mdx +++ /dev/null @@ -1,110 +0,0 @@ ---- -slug: release-1-36 -title: Release v1.36.0 -authors: [alextran] -tags: [release] -date: 2022-11-10 ---- - -Hello everyone, it is my pleasure to deliver the new release of Immich to you. The team has been working hard to bring you the new features and improvements. This release includes some big features that the community has been asking since the beginning of Immich. We hope you will enjoy it. - -Some notable features are: - -- OAuth integration -- LivePhoto support on iOS -- User config system - - - -## LivePhoto iOS Support 🎉 - -LivePhoto on iOS is now supported in Immich. - -The motion part will now be uploaded and can be played on the mobile app and the web. - -:::caution - -- The server and the app has to be on version **1.36.x** for the application to work correctly. -- Previous uploaded photos will not be updated automatically, you will have to remove and reupload them if you want to keep the LivePhoto functionality. - -::: - - - -## OAuth Integration 🎉 - -I want to borrow this chance to express my gratitude to [@EnricoBilla](https://github.com/EnricoBilla), who has been the trailblazer for this feature since the beginning days of Immich. His PR has sparked ideas, suggestions, and discussion among the team member on how to integrate this feature successfully into the app. Thank you so much for your work and your time. - -OAuth is now integrated into the system. Please follow the guide [here](https://immich.app/docs/usage/oauth) to set up your OAuth integration - -After setting up the correct environment variables in the `.env` file, as shown below - -| Key | Type | Default | Description | -| ------------------- | ------- | -------------------- | ------------------------------------------------------------------------- | -| OAUTH_ENABLED | boolean | false | Enable/disable OAuth2 | -| OAUTH_ISSUER_URL | URL | (required) | Required. Self-discovery URL for client | -| OAUTH_CLIENT_ID | string | (required) | Required. Client ID | -| OAUTH_CLIENT_SECRET | string | (required) | Required. Client Secret | -| OAUTH_SCOPE | string | openid email profile | Full list of scopes to send with the request (space delimited) | -| OAUTH_AUTO_REGISTER | boolean | true | When true, will automatically register a user the first time they sign in | -| OAUTH_BUTTON_TEXT | string | Login with OAuth | Text for the OAuth button on the web | - -```bash title="Authentik Example" -OAUTH_ENABLED=true -OAUTH_ISSUER_URL=http://10.1.15.216:9000/application/o/immich-test/ -OAUTH_CLIENT_ID=30596v8f78a4b6a97d5985c3076b6b4c4d12ddc33 -OAUTH_CLIENT_SECRET=50f1eafdec353b95b1c638db390db4ab67ef035a51212dbec2f56175e2eb272b5d572c099176e6fe116ecf47ffdd544bgdb9e2edc588307ee0339d25eeccd88 -OAUTH_BUTTON_TEXT=Login with Authentik -``` - -The web will have the option to sign in with OAuth. - - - -The mobile app will check if the server has OAuth enabled before displaying the OAuth -sign-in button. - - - -## Support - - - -If you find the project helpful and it helps you in some ways, you can support the project [one time](https://github.com/sponsors/alextran1502?frequency=one-time&sponsor=alextran1502) or [monthly](https://github.com/sponsors/alextran1502) from GitHub Sponsor - -It is a great way to let me know that you want me to continue developing and working on this project for years to come. - -## Details - -For more details, please check out the [release note](https://github.com/immich-app/immich/releases/tag/v1.36.0_55-dev) diff --git a/docs/blog/2023/06-24/update.mdx b/docs/blog/2023/06-24/update.mdx deleted file mode 100644 index 464d3e44d9..0000000000 --- a/docs/blog/2023/06-24/update.mdx +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: Immich Update - June 2023 -authors: [alextran] -tags: [update] ---- - -Hello everybody, Alex here! - -I am back with another update on Immich. It has been only a month since my last update (May 18th, 2023), but it seems forever. I think the rapid releases of Immich and the amount of work make the perspective of time change in Immich’s world. We have some exciting updates that I think you will like. - -Before going into detail, on behalf of the core team, I would like to thank all of you for loving Immich and contributing to the project. Thank you for helping me make Immich an enjoyable alternative solution to Google Photos so that you have complete control of your data and privacy. I know we are still young and have a lot of work to do, but I am confident we will get there with help from the community. I appreciate all of you from the bottom of my heart! - - - -And now, to the exciting part, what is new in Immich’s world? - -- Initial support for existing gallery. -- Memory feature. -- Support XMP sidecar. -- Support more raw formats. -- Justified layout for web timeline and blurred thumbnail hash. -- Mechanism to host machine learning on a completely different machine. - -## Support for existing gallery - -I know this is the most controversial feature when it comes to Immich’s way of ingesting photos and videos. For many users, having to upload photos and videos to Immich is simply not working. We listen, discuss, and digest this feature internally more than you imagine because it is not a simple feature to tackle while keeping the performance and the user experience at the top level, which is Immich’s primary goal. - -Thankfully, we have many great contributors and developers that want to make this come true. So we came up with an initial implementation of this feature in the form of a supporting read-only gallery. - -To be concise, Immich can now read in the gallery files, register the path into the database, and then generate necessary files and put them through Immich’s machine learning pipeline so you can use all the goodness of Immich without the need to upload them. Since this is the initial implementation, some actions/behavior are not yet supported, and we aim to build toward them in future releases, namely: - -- Assets are not automatically synced and must instead be manually synced with the CLI tool. -- Only new files that are added to the gallery will be detected. -- Deleted and moved files will not be detected. - -## Memory feature - -This is considered a fun feature that the team and I wanted to build for so long, but we had to put it off because of the refactoring of the code base. The code base is now in a good enough form to circle back and add more exciting features. - -This memory feature is very much similar to GPhotos' implementation of “x years since…”. We are aiming to add more categories of memories in the future, such as “Spotlight of the day” or “Day of the Week highlights” - - - -This feature is now available on the web and will be ported to the mobile app in the near future. - -## Support XMP Sidecar - -Immich can now import/upload XMP sidecars from the CLI and use the information as the metadata of assets. - -## Support more raw formats. - -With the recent updates on the dependencies of Immich, we are now extending and hardening support for multiple raw formats. So users with DSLR or mirrorless cameras can now upload their original files to Immich and have them displayed in high-quality thumbnails on the web and mobile view. - -## Justified layout for web timeline and blurred thumbnail hash - -This is an aesthetic improvement in user experience when browsing the timeline. Photos and videos are now displayed correctly with perspective orientation, making the browsing experience more pleasurable. - -To further improve the browsing experience, we now added a blur hash to the thumbnail, so the transition is more natural with a dreamy fade in effect, similar to how our brain goes from faded to vivid memory - - - -## Hosting machine learning container on a different machine - -With more capabilities Immich is building toward, machine learning will get more powerful and therefore require more resources to run effectively. However, we understand that users might not have the best server resources where they host the Immich instance. Therefore, we changed how machine learning interacts and receives the photos and videos to run through its inference pipeline. - -The machine learning container is now a headless system that can run on any machine. As long as your Immich instance can communicate with the system running the machine learning container, it can send the files and receive the required information to make Immich powerful in terms of searching and intelligence. This helps you to utilize a more powerful machine in your home/infrastructure to perform the CPU-intensive tasks while letting Immich only handle the I/O operations for a pleasant and smooth experience. - ---- - -So, those are the highlights for the team and the community after a busy month. There are a lot more changes and improvements. I encourage you to read some release notes, starting from version [v1.57.0](https://github.com/immich-app/immich/releases/tag/v1.57.0) to now. - -Thank you, and I am asking for your support for the project. I hope to be a full-time maintainer of Immich one day to dedicate myself to the project as my life works for the community and my family. You can find the support channels below: - -- Monthly donation via [GitHub Sponsors](https://github.com/sponsors/alextran1502) -- One-time donation via [GitHub Sponsors](https://github.com/sponsors/alextran1502?frequency=one-time&sponsor=alextran1502) -- [Liberapay](https://liberapay.com/alex.tran1502/) -- [buymeacoffee](https://www.buymeacoffee.com/altran1502) -- Bitcoin: 3QVAb9dCHutquVejeNXitPqZX26Yg5kxb7 -- Give a project a star - the contributors love gazing at the stars and seeing their creations shining in the sky. - -Join our friendly [Discord](https://discord.immich.app) to talk and discuss Immich, tech, or anything - -Cheer! - -Until next time! - -Alex diff --git a/docs/blog/2023/07-29/images/web-shortcuts-panel.png b/docs/blog/2023/07-29/images/web-shortcuts-panel.png deleted file mode 100644 index 5a16c9f289..0000000000 Binary files a/docs/blog/2023/07-29/images/web-shortcuts-panel.png and /dev/null differ diff --git a/docs/blog/2023/07-29/update.mdx b/docs/blog/2023/07-29/update.mdx deleted file mode 100644 index 6d50ddfdc0..0000000000 --- a/docs/blog/2023/07-29/update.mdx +++ /dev/null @@ -1,151 +0,0 @@ ---- -title: Immich Update - July 2023 -authors: [alextran] -tags: [update, v1.64.0-v1.71.0] ---- - -Hello, Immich fans, another month, another milestone. We hope you are staying cool and safe in this scorching hot summer across the globe. - -Immich recently got some good recognition when getting to the front page of HackerNews, which helped to let more people know about the project's existence. The project will help more and more people find a solution to control the privacy of their most precious moments. And with the gain in popularity and recognition, we have gotten new users and more questions from the community than ever. - -I want to express my gratitude to all the contributors and the community who have been tremendously helpful to new users' questions and provided technical support. - -Below are the highlights of new features we added to the application over the past month, along with countless bug fixes and improvements across the board, from developer experience to resource optimization and UI/UX improvement. I hope you find these topics as exciting as I am. - -## Highlights - -- Memories feature. -- Facial recognition improvements. -- Improvements on multi selection behavior on the web. -- Shortcuts for common actions on the web. -- Support viewer for 360-panorama photos. - - - ---- - -### Memories feature - -We've added the memory feature on the mobile app, so you can reminisce about your past memories. - - - -### Facial recognition improvements - -Over the past few releases, we have added many UI improvements to the facial recognition feature to help you manage the recognized people better. Some of the highlights: - -#### Choose a new feature photo for a person. - - - -#### Hide and show faces. - -You can now select irrelevant faces to hide them. The hidden faces won’t be displayed in search results and the people section in the info panel. - -#### Merge faces. - -This is useful when you have multiple faces of the same person in your photos, and you want to merge them into one. - - - -We also added a nifty mechanism that when naming a face, similar names will prompt you a merge face option for the convenience. - - - -### Improvements on multi selection behavior on the web - -We have added a new multi selection behavior on the web to help you select multiple items easier. You can now select a range of photos and videos by holding the `Shift` key. - - - -### Shortcuts for common actions on the web. - -Some of us only navigate the world and the web with a keyboard (looking at you, Vim and Emacs users). So it would take away the sacred weapon of choice to require many clicks to perform repetitive actions. So we added quick shortcuts for the following action on the web. - -Dot Env Example - -### Support viewer for 360-panorama photos. - -Photos with the EXIF property of `ProjectionType` will now have a special viewer on the web to view all the angles of the panorama. - -The thumbnail of the 360 degrees panoramas will have a special icon on the top right of the thumbnail - -Dot Env Example - -Panorama in the detail view - -Dot Env Example - ---- - -Thank you, and I am asking for your support for the project. I hope to be a full-time maintainer of Immich one day to dedicate myself to the project as my life's work for the community and my family. You can find the support channels below: - -- Monthly donation via [GitHub Sponsors](https://github.com/sponsors/alextran1502) -- One-time donation via [GitHub Sponsors](https://github.com/sponsors/alextran1502?frequency=one-time&sponsor=alextran1502) -- [Liberapay](https://liberapay.com/alex.tran1502/) -- [buymeacoffee](https://www.buymeacoffee.com/altran1502) -- Bitcoin: 3QVAb9dCHutquVejeNXitPqZX26Yg5kxb7 -- Give a project a star - the contributors love gazing at the stars and seeing their creations shining in the sky. - -Join our friendly [Discord](https://discord.immich.app) to talk and discuss Immich, tech, or anything - -Cheer! - -Until next time! - -Alex diff --git a/docs/blog/2023/2023-recap.mdx b/docs/blog/2023/2023-recap.mdx deleted file mode 100644 index e9d93a52be..0000000000 --- a/docs/blog/2023/2023-recap.mdx +++ /dev/null @@ -1,71 +0,0 @@ ---- -title: Immich Recap 2023 -authors: [alextran] -tags: [update, recap-2023] -date: 2023-12-30T00:00 ---- - -Hi everyone, - -Alex from Immich here. - -We are entering the last few weeks of 2023, and it has been quite a year for Immich. The project has grown so much in terms of users, developers, features, maturity, and the community around it. When I started working on Immich, it was simply a challenge for myself and an opportunity to learn new technologies, crafting something fun and useful for my wife during my free time to satisfy my urge to build and create things. I never thought it would become so popular and help so many people. At the end of the day, all we have is memory. I am proud that the team and I have created something to make storing and viewing those precious memories easier without restrictions and without sacrificing our privacy. As the year closes, here’s a recap of everything the project accomplished in 2023. - -# Milestones - -- Public shared links -- Favorites page -- Immich turned 1 -- Material Design 3 on the mobile app -- Auto-link LivePhotos server-side -- iOS background backup -- Explore page -- CLIP search -- Search by metadata -- Responsive web app -- Archive page -- Asset descriptions -- 10,000 stars on GitHub -- Manage auth devices -- Map view -- Facial recognition, clustering, searching, renaming, and person management -- Partner sharing and unifying timeline between partners' users -- Custom storage label -- XMP sidecar reading -- RAW file formats -- Justified layout on the web -- Memories -- Multi-select via SHIFT -- Android Motion Photos -- 360° Photos -- Album description -- Album performance improvements (time buckets) -- Video hardware transcoding -- Slideshow mode on the web -- Configuration file -- External libraries -- Trash page -- Custom theme -- Asset Stacking -- 20,000 stars on GitHub -- Shared album activity and comments -- CLI v2 -- Down to 5 containers (from 8) - -# Fun Statistics - -- We have gone from the release version `1.41.0` to `1.90.0` at the time of writing. On average, we see a release every 7 days. -- According to GitHub's metrics, the `immich-server` container image has been pulled almost _4 million_ times. -- According to mobile app store metrics, we have 22,000 installations on Android and 6700 installation units on iOS (opt-in only). -- Immich is making around $1200/month on average from donations. (Thank you all so much!) -- We were guests on two podcasts: - - [Self-hosted](https://selfhosted.show/110) - - [The Vergecast](https://www.theverge.com/23938533/self-hosting-local-first-software-vergecast) -- There are over 4,500 members on the Discord server. -- We have over 22,000 stars on the main GitHub repository, gaining 15,000 stars since January 2023. - -Diving into the next year, the team will continue to build on the foundation we have laid out over the past year, implementing more advanced features for searching, organizing, and sharing between users. Bugs will continue to be squashed and conquered. “Shit Alex wrote'' code will continue to be replaced by beautiful, clean code from Jason, Zack, Boet, Daniel, Osorin, Mert, Fynn, Marty, Martin, and Jonathan. The team has my eternal gratitude for creating a welcoming environment for new contributors, helping, teaching, and learning from each other. I’ve realized that hardly a day has gone by where the team hasn’t been in communication about Immich related topics over the past year. - -My long-term goal is to help hone Immich into a diamond in the FOSS space, where the UI, UX, development experiences, documentation, and quality are at a high standard while remaining free for everybody to use. - -I hope you enjoy Immich and have a happy and peaceful holiday. diff --git a/docs/blog/2024/immich-core-team-goes-fulltime.mdx b/docs/blog/2024/immich-core-team-goes-fulltime.mdx deleted file mode 100644 index 0cba2b467c..0000000000 --- a/docs/blog/2024/immich-core-team-goes-fulltime.mdx +++ /dev/null @@ -1,75 +0,0 @@ ---- -title: The Immich core team goes full-time -authors: [alextran] -tags: [update, announcement, FUTO] -date: 2024-05-01T00:00 ---- - -**Immich is joining [FUTO](https://futo.org/)!** - -Since the beginning of this adventure, my goal has always been to create a better world for my children. Memories are priceless, and privacy should not be a luxury. However, building quality open source has its challenges. Over the past two years, it has taken significant dedication, time, and effort. - -Recently, a company in Austin, Texas, called FUTO contacted the team. FUTO strives to develop quality and sustainable open software. They build software alternatives that focus on giving control to users. From their mission statement: - -“Computers should belong to you, the people. We develop and fund technology to give them back.” - -FUTO loved Immich and wanted to see if we’d consider working with them to take the project to the next level. In short, FUTO offered to: - -- Pay the core team to work on Immich full-time -- Let us keep full autonomy about the project’s direction and leadership -- Continue to license Immich under AGPL -- Keep Immich’s development direction with no paywalled features -- Keep Immich “built for the people” (no ads, data mining/selling, or alternative motives) -- Provide us with financial, technical, legal, and administrative support - -After careful deliberation, the team decided that FUTO’s vision closely aligns with our own: to build a better future by providing a polished, performant, and privacy-preserving open-source software solution for photo and video management delivered in a sustainable way. - -Immich’s future has never looked brighter, and we look forward to realizing our vision for Immich as part of FUTO. - -If you have more questions, we’ll host a Q&A live stream on May 9th at 3PM UTC (10AM CST). [You can ask questions here](https://www.live-ask.com/event/01HWP2SB99A1K8EXFBDKZ5Z9CF), and the stream will be live [here on our YouTube channel](https://youtube.com/live/cwz2iZwYpgg). - -Cheers, - -The Immich Team - ---- - -## FAQs - -### What is FUTO? - -[https://futo.org/what-is-futo/](https://futo.org/what-is-futo/) - -### Will the license change? - -No. Immich will continue to be licensed under AGPL without a CLA. - -### Will Immich continue to be free? - -Yes. The Immich source code will remain freely available under the AGPL license. - -### Is Immich getting VC funding? - -No. Venture capital implies investment in a business, often with the expectation of a future payout (exit plan). Immich is neither a business that can be acquired nor comes with a money-making exit plan. - -### I am currently supporting Immich through GitHub sponsors. What will happen to my donation? - -Effective immediately, all donations to the Immich organization will be canceled. In the future, we will offer an optional, modest payment option instead. Thank you to everyone who donated to help us get this far! - -### How is funding sustainable? - -Immich and FUTO believe a sustainable future requires a model that does not rely on users-as-a-product. To this end, FUTO advocates that users pay for good, open software. In keeping with this model, we will adopt a purchase price. This means we no longer accept donations, but — _without limiting features for those who do not pay_ — we will soon allow you to purchase Immich through a modest payment. We encourage you to pay for the high-quality software you use to foster a healthy software culture where developers build great applications without hidden motives for their users. - -### When does this change take effect? - -This change takes effect immediately. - -### What will change? - -The following things will change as Immich joins FUTO: - -- The brand, logo, and other Immich trademarks will be transferred to FUTO. -- We will stop all donations to the project. -- The core team can now dedicate our full attention to Immich -- Before the end of the year, we plan to have a roadmap for what it will take to get Immich to a stable release. -- Bugs will be squashed, and features will be delivered faster. diff --git a/docs/blog/2024/immich-licensing.mdx b/docs/blog/2024/immich-licensing.mdx deleted file mode 100644 index 773abcb666..0000000000 --- a/docs/blog/2024/immich-licensing.mdx +++ /dev/null @@ -1,91 +0,0 @@ ---- -title: Licensing announcement - Purchase a license to support Immich -authors: [alextran] -tags: [update, announcement, FUTO] -date: 2024-07-18T00:00 ---- - -Hello everybody, - -Firstly, on behalf of the Immich team, I'd like to thank everybody for your continuous support of Immich since the very first day! Your contributions, encouragement, and community engagement have helped bring Immich to its current state. The team and I are forever grateful for that. - -Since our [last announcement of the core team joining FUTO to work on Immich full-time](https://immich.app/blog/2024/immich-core-team-goes-fulltime), one of the goals of our new position is to foster a healthy relationship between the developers and the users. We believe that this enables us to create great software, establish transparent policies and build trust. - -We want to build a great software application that brings value to you and your loved ones' lives. We are not using you as a product, i.e., selling or tracking your data. We are not putting annoying ads into our software. We respect your privacy. We want to be compensated for the hard work we put in to build Immich for you. - -With those notes, we have enabled a way for you to financially support the continued development of Immich, ensuring the software can move forward and will be maintained, by offering a lifetime license of the software. We think if you like and use software, you should pay for it, but _we're never going to force anyone to pay or try to limit Immich for those who don't._ - -There are two types of license that you can choose to purchase: **Server License** and **Individual License**. - -### Server License - -This is a lifetime license costing **$99.99**. The license is applied to the whole server. You and all users that use your server are licensed. - -### Individual License - -This is a lifetime license costing **$24.99**. The license is applied to a single user, and can be used on any server they choose to connect to. - -license-social-gh - -You can purchase the license on [our page - https://buy.immich.app](https://buy.immich.app). - -Starting with release `v1.109.0` you can purchase and enter your purchased license key directly in the app. - -license-page-gh - -## Thank you - -Thank you again for your support, this will help create a strong foundation and stability for the Immich team to continue developing and maintaining the project that you love to use. - -

- -

- -
-
- -Cheers! 🎉 - -Immich team - -# FAQ - -### 1. Where can I purchase a license? - -There are several places where you can purchase the license from - -- [https://buy.immich.app](https://buy.immich.app) -- [https://pay.futo.org](https://pay.futo.org/) -- or directly from the app. - -### 2. Do I need both _Individual License_ and _Server License_? - -No, - -If you are the admin and the sole user, or your instance has less than a total of 4 users, you can buy the **Individual License** for each user. - -If your instance has more than 4 users, it is more cost-effective to buy the **Server License**, which will license all the users on your instance. - -### 3. What do I do if I don't pay? - -You can continue using Immich without any restriction. - -### 4. Will there be any paywalled features? - -No, there will never be any paywalled features. - -### 5. Where can I get support regarding payment issues? - -You can email us with your `orderId` and your email address `billing@futo.org` or on our Discord server. diff --git a/docs/blog/2024/update-july-2024.mdx b/docs/blog/2024/update-july-2024.mdx deleted file mode 100644 index cbe99177e7..0000000000 --- a/docs/blog/2024/update-july-2024.mdx +++ /dev/null @@ -1,78 +0,0 @@ ---- -title: Immich Update - July 2024 -authors: [alextran] -date: 2024-07-01T00:00 -tags: [update, v1.106.0] ---- - -Hello everybody! Alex from Immich here and I am back with another development progress update for the project. - -Summer has returned once again, and the night sky is filled with stars, thank you for **38_000 shining stars** you have sent to our [GitHub repo](https://github.com/immich-app/immich)! Since the last announcement several core contributors have started full time. Everything is going great with development, PRs get merged with _brrrrrrr_ rate, conversation exchange between team members is on a new high, we met and are working with the great engineers at FUTO. The spirit is high and we have a lot of things brewing that we think you will like. - -Let's go over some of the updates we had since the last post. - -### Container consolidation - -Reduced the number of total containers from 5 to 4 by making the microservices thread get spawned directly in the server container. Woohoo, remember when Immich had 7 containers? - -### Email notifications - -![smtp](https://github.com/immich-app/immich/assets/27055614/949cba85-d3f1-4cd3-b246-a6f5fb5d3ae8) - -We added email notifications to the app with SMTP settings that you can configure for the following events - -- A new account is created for you. -- You are added to a shared album. -- New media is added to an album. - -### Versioned docs - -You can now jump back into the past or take a peek at the unreleased version of the documentation by selecting the version on the website. - -![version-doc](https://github.com/immich-app/immich/assets/27055614/6d22898a-5093-41ad-b416-4573d7ce6e03) - -### Similarity deduplication - -With more machine learning and CLIP magic, we now have similarity deduplication built into the application where it will search for closely similar images and let you decide what to do with them; i.e keep or trash. - -![similarity-deduplication](https://github.com/immich-app/immich/assets/27055614/3cac8478-fbf7-47ea-acb6-0146901dc67e) - -### Permanent URL for asset on the web - -The detail view for an asset now has a permanent URL so you can easily share them with your loved ones. - -### Web app translations - -We now have a public Weblate project which the community can use to translate the webapp to their native languages. We are planning to port the mobile app translation to this platform as well. If you would like to contribute, you can take a look [here](https://hosted.weblate.org/projects/immich/immich/). We're already close to 50% translations -- we really appreciate everyone contributing to that! - -![web-translation](https://github.com/immich-app/immich/assets/27055614/363df2ed-656c-4584-bd82-0708a693c5bc) - -### Read-only/Editor mode on shared album - -As the owner of the album, you can choose if the shared user can edit the album or to only view the content of the album without any modification. - -![read-only-album](https://github.com/immich-app/immich/assets/27055614/c6f66375-b869-495a-9a86-3e87b316d109) - -### Better video thumbnails - -Immich now tries to find a descriptive video thumbnail instead of simply using the first frame. No more black images for thumbnails! - -### Public Roadmap - -We now have a [public roadmap](https://immich.app/roadmap), giving you a high-level overview of things the team is working on. The first goal of this roadmap is to bring Immich to a stable release, which is expected sometime later this year. Some of the highlights include - -- Auto stacking - Auto stacking of burst photos -- Basic editor - Basic photo editing capabilities -- Workflows - Automate tasks with workflows -- Fine grained access controls - Granular access controls for users and api keys -- Better background backups - Rework background backups to be more reliable -- Private/locked photos - Private assets with extra protections - -Beyond the items in the roadmap, we have _many many_ more ideas for Immich. The team and I hope that you are enjoying the application, find it helpful in your life and we have nothing but the intention of building out great software for you all! - -Have an amazing Summer or Winter for those in the southern hemisphere! :D - -Until next time, - -Cheers! -Alex diff --git a/docs/blog/authors.yml b/docs/blog/authors.yml deleted file mode 100644 index f331efa927..0000000000 --- a/docs/blog/authors.yml +++ /dev/null @@ -1,5 +0,0 @@ -alextran: - name: Alex Tran - title: Maintainer of Immich - url: https://github.com/alextran1502 - image_url: https://github.com/alextran1502.png diff --git a/docs/docs/FAQ.mdx b/docs/docs/FAQ.mdx index b2f2e85775..14ac1de298 100644 --- a/docs/docs/FAQ.mdx +++ b/docs/docs/FAQ.mdx @@ -30,11 +30,11 @@ When in doubt or if you have an edge case scenario, we encourage you to contact ### How can I reset the admin password? -The admin password can be reset by running the [reset-admin-password](/docs/administration/server-commands.md) command on the immich-server. +The admin password can be reset by running the [reset-admin-password](/administration/server-commands.md) command on the immich-server. ### How can I see a list of all users in Immich? -You can see the list of all users by running [list-users](/docs/administration/server-commands.md) Command on the Immich-server. +You can see the list of all users by running [list-users](/administration/server-commands.md) Command on the Immich-server. --- @@ -106,20 +106,20 @@ However, Immich will delete original files that have been trashed when the trash When Storage Template is off (default) Immich saves the file names in a random string (also known as random UUIDs) to prevent duplicate file names. To retrieve the original file names, you must enable the Storage Template and then run the STORAGE TEMPLATE MIGRATION job. -It is recommended to read about [Storage Template](https://immich.app/docs/administration/storage-template) before activation. +It is recommended to read about [Storage Template](/administration/storage-template) before activation. ### Can I add my existing photo library? -Yes, with an [External Library](/docs/features/libraries.md). +Yes, with an [External Library](/features/libraries.md). -### What happens to existing files after I choose a new [Storage Template](/docs/administration/storage-template.mdx)? +### What happens to existing files after I choose a new [Storage Template](/administration/storage-template.mdx)? -Template changes will only apply to _new_ assets. To retroactively apply the template to previously uploaded assets, run the Storage Migration Job, available on the [Jobs](/docs/administration/jobs-workers/#jobs) page. +Template changes will only apply to _new_ assets. To retroactively apply the template to previously uploaded assets, run the Storage Migration Job, available on the [Jobs](/administration/jobs-workers/#jobs) page. ### Why are only photos and not videos being uploaded to Immich? This often happens when using a reverse proxy in front of Immich. -Make sure to [set your reverse proxy](/docs/administration/reverse-proxy/) to allow large requests. +Make sure to [set your reverse proxy](/administration/reverse-proxy/) to allow large requests. Also, check the disk space of your reverse proxy. In some cases, proxies cache requests to disk before passing them on, and if disk space runs out, the request fails. @@ -139,7 +139,7 @@ You can _archive_ them. ### How can I backup data from Immich? -See [Backup and Restore](/docs/administration/backup-and-restore.md). +See [Backup and Restore](/administration/backup-and-restore.md). ### Does Immich support reading existing face tag metadata? @@ -225,7 +225,7 @@ volumes: ### Can I keep my existing album structure while importing assets into Immich? -Yes, by using the [Immich CLI](/docs/features/command-line-interface) along with the `--album` flag. +Yes, by using the [Immich CLI](/features/command-line-interface) along with the `--album` flag. ### Is there a way to reorder photos within an album? @@ -266,7 +266,7 @@ Immich uses CLIP models. An ML model converts each image to an "embedding", whic ### How does facial recognition work? -See [How Facial Recognition Works](/docs/features/facial-recognition#how-facial-recognition-works) for details. +See [How Facial Recognition Works](/features/facial-recognition#how-facial-recognition-works) for details. ### How can I disable machine learning? @@ -288,7 +288,7 @@ No, this is not supported. Only models listed in the [Hugging Face][huggingface] ### I want to be able to search in other languages besides English. How can I do that? -You can change to a multilingual CLIP model. See [here](/docs/features/searching#clip-models) for instructions. +You can change to a multilingual CLIP model. See [here](/features/searching#clip-models) for instructions. ### Does Immich support Facial Recognition for videos? @@ -299,7 +299,7 @@ Scanning the entire video for faces may be implemented in the future. No. :::tip -You can use [Smart Search](/docs/features/searching.md) for this to some extent. For example, if you have a Golden Retriever and a Chihuahua, type these words in the smart search and watch the results. +You can use [Smart Search](/features/searching.md) for this to some extent. For example, if you have a Golden Retriever and a Chihuahua, type these words in the smart search and watch the results. ::: ### I'm getting a lot of "faces" that aren't faces, what can I do? @@ -329,7 +329,7 @@ ls clip/ facial-recognition/ ### Why is Immich slow on low-memory systems like the Raspberry Pi? -Immich optionally uses transcoding and machine learning for several features. However, it can be too heavy to run on a Raspberry Pi. You can [mitigate](/docs/FAQ#can-i-lower-cpu-and-ram-usage) this or host Immich's machine-learning container on a [more powerful system](/docs/guides/remote-machine-learning), or [disable](/docs/FAQ#how-can-i-disable-machine-learning) machine learning entirely. +Immich optionally uses transcoding and machine learning for several features. However, it can be too heavy to run on a Raspberry Pi. You can [mitigate](/FAQ#can-i-lower-cpu-and-ram-usage) this or host Immich's machine-learning container on a [more powerful system](/guides/remote-machine-learning), or [disable](/FAQ#how-can-i-disable-machine-learning) machine learning entirely. ### Can I lower CPU and RAM usage? @@ -339,9 +339,9 @@ The initial backup is the most intensive due to the number of jobs running. The - Under Settings > Transcoding Settings > Threads, set the number of threads to a low number like 1 or 2. - Under Settings > Machine Learning Settings > Facial Recognition > Model Name, you can change the facial recognition model to `buffalo_s` instead of `buffalo_l`. The former is a smaller and faster model, albeit not as good. - For facial recognition on new images to work properly, You must re-run the Face Detection job for all images after this. -- At the container level, you can [set resource constraints](/docs/FAQ#can-i-limit-cpu-and-ram-usage) to lower usage further. +- At the container level, you can [set resource constraints](/FAQ#can-i-limit-cpu-and-ram-usage) to lower usage further. - It's recommended to only apply these constraints _after_ taking some of the measures here for best performance. -- If these changes are not enough, see [above](/docs/FAQ#how-can-i-disable-machine-learning) for instructions on how to disable machine learning. +- If these changes are not enough, see [above](/FAQ#how-can-i-disable-machine-learning) for instructions on how to disable machine learning. ### Can I limit CPU and RAM usage? @@ -383,7 +383,7 @@ Do not exaggerate with the job concurrency because you're probably thoroughly ov ### My server shows Server Status Offline | Version Unknown. What can I do? -You need to [enable WebSockets](/docs/administration/reverse-proxy/) on your reverse proxy. +You need to [enable WebSockets](/administration/reverse-proxy/) on your reverse proxy. --- @@ -391,7 +391,7 @@ You need to [enable WebSockets](/docs/administration/reverse-proxy/) on your rev ### How can I see Immich logs? -Immich components are typically deployed using docker. To see logs for deployed docker containers, you can use the [Docker CLI](https://docs.docker.com/engine/reference/commandline/cli/), specifically the `docker logs` command. For examples, see [Docker Help](/docs/guides/docker-help.md). +Immich components are typically deployed using docker. To see logs for deployed docker containers, you can use the [Docker CLI](https://docs.docker.com/engine/reference/commandline/cli/), specifically the `docker logs` command. For examples, see [Docker Help](/guides/docker-help.md). ### How can I reduce the log verbosity of Redis? @@ -435,7 +435,7 @@ cap_drop: Data for Immich comes in two forms: 1. **Metadata** stored in a Postgres database, stored in the `DB_DATA_LOCATION` folder (previously `pg_data` Docker volume). -2. **Files** (originals, thumbs, profile, etc.), stored in the `UPLOAD_LOCATION` folder, more [info](/docs/administration/backup-and-restore#asset-types-and-storage-locations). +2. **Files** (originals, thumbs, profile, etc.), stored in the `UPLOAD_LOCATION` folder, more [info](/administration/backup-and-restore#asset-types-and-storage-locations). :::warning This will destroy your database and reset your instance, meaning that you start from scratch. @@ -473,7 +473,7 @@ If it mentions SIGILL (note the lack of a K) or error code 132, it most likely m ### Why am I getting database ownership errors? If you get database errors such as `FATAL: data directory "/var/lib/postgresql/data" has wrong ownership` upon database startup, this is likely due to an issue with your filesystem. -NTFS and ex/FAT/32 filesystems are not supported. See [here](/docs/install/requirements#special-requirements-for-windows-users) for more details. +NTFS and ex/FAT/32 filesystems are not supported. See [here](/install/requirements#special-requirements-for-windows-users) for more details. ### How can I verify the integrity of my database? diff --git a/docs/docs/administration/backup-and-restore.md b/docs/docs/administration/backup-and-restore.md index deeefa5635..f9c00c7df7 100644 --- a/docs/docs/administration/backup-and-restore.md +++ b/docs/docs/administration/backup-and-restore.md @@ -3,7 +3,7 @@ import Tabs from '@theme/Tabs'; import TabItem from '@theme/TabItem'; -A [3-2-1 backup strategy](https://www.backblaze.com/blog/the-3-2-1-backup-strategy/) is recommended to protect your data. You should keep copies of your uploaded photos/videos as well as the Immich database for a comprehensive backup solution. This page provides an overview on how to backup the database and the location of user-uploaded pictures and videos. A template bash script that can be run as a cron job is provided [here](/docs/guides/template-backup-script.md) +A [3-2-1 backup strategy](https://www.backblaze.com/blog/the-3-2-1-backup-strategy/) is recommended to protect your data. You should keep copies of your uploaded photos/videos as well as the Immich database for a comprehensive backup solution. This page provides an overview on how to backup the database and the location of user-uploaded pictures and videos. A template bash script that can be run as a cron job is provided [here](/guides/template-backup-script.md) :::danger The instructions on this page show you how to prepare your Immich instance to be backed up, and which files to take a backup of. You still need to take care of using an actual backup tool to make a backup yourself. @@ -160,7 +160,7 @@ for more info read the [release notes](https://github.com/immich-app/immich/rele :::danger A backup of this folder does not constitute a backup of your database! - Follow the instructions listed [here](/docs/administration/backup-and-restore#database) to learn how to perform a proper backup. + Follow the instructions listed [here](/administration/backup-and-restore#database) to learn how to perform a proper backup. ::: @@ -205,7 +205,7 @@ When you turn off the storage template engine, it will leave the assets in `UPLO :::danger A backup of this folder does not constitute a backup of your database! - Follow the instructions listed [here](/docs/administration/backup-and-restore#database) to learn how to perform a proper backup. + Follow the instructions listed [here](/administration/backup-and-restore#database) to learn how to perform a proper backup. ::: diff --git a/docs/docs/administration/email-notification.mdx b/docs/docs/administration/email-notification.mdx index 2ad4fba2be..0da132161f 100644 --- a/docs/docs/administration/email-notification.mdx +++ b/docs/docs/administration/email-notification.mdx @@ -12,7 +12,7 @@ You can access the settings panel from the web at `Administration -> Settings -> Under Email, enter the required details to connect with an SMTP server. -You can use [this guide](/docs/guides/smtp-gmail) to use Gmail's SMTP server. +You can use [this guide](/guides/smtp-gmail) to use Gmail's SMTP server. ## User's notifications settings diff --git a/docs/docs/administration/jobs-workers.md b/docs/docs/administration/jobs-workers.md index 4634151b9a..75f50599a0 100644 --- a/docs/docs/administration/jobs-workers.md +++ b/docs/docs/administration/jobs-workers.md @@ -11,7 +11,7 @@ The `immich-server` container contains multiple workers: ## Split workers -If you prefer to throttle or distribute the workers, you can do this using the [environment variables](/docs/install/environment-variables) to specify which container should pick up which tasks. +If you prefer to throttle or distribute the workers, you can do this using the [environment variables](/install/environment-variables) to specify which container should pick up which tasks. For example, for a simple setup with one container for the Web/API and one for all other microservices, you can do the following: @@ -53,5 +53,5 @@ Additionally, some jobs (such as memories generation) run on a schedule, which i :::note -Some jobs ([External Libraries](/docs/features/libraries) scanning, Database Dump) are configured in their own sections in System Settings. +Some jobs ([External Libraries](/features/libraries) scanning, Database Dump) are configured in their own sections in System Settings. ::: diff --git a/docs/docs/administration/oauth.md b/docs/docs/administration/oauth.md index 55a0ce9469..47f4a96c6a 100644 --- a/docs/docs/administration/oauth.md +++ b/docs/docs/administration/oauth.md @@ -28,7 +28,7 @@ Before enabling OAuth in Immich, a new client application needs to be configured 2. Configure Redirect URIs/Origins The **Sign-in redirect URIs** should include: - - `app.immich:///oauth-callback` - for logging in with OAuth from the [Mobile App](/docs/features/mobile-app.mdx) + - `app.immich:///oauth-callback` - for logging in with OAuth from the [Mobile App](/features/mobile-app.mdx) - `http://DOMAIN:PORT/auth/login` - for logging in with OAuth from the Web Client - `http://DOMAIN:PORT/user-settings` - for manually linking OAuth in the Web Client @@ -98,7 +98,7 @@ The redirect URI for the mobile app is `app.immich:///oauth-callback`, which is 2. Whitelist the new endpoint as a valid redirect URI with your provider. 3. Specify the new endpoint as the `Mobile Redirect URI Override`, in the OAuth settings. -With these steps in place, you should be able to use OAuth from the [Mobile App](/docs/features/mobile-app.mdx) without a custom scheme redirect URI. +With these steps in place, you should be able to use OAuth from the [Mobile App](/features/mobile-app.mdx) without a custom scheme redirect URI. :::info Immich has a route (`/api/oauth/mobile-redirect`) that is already configured to forward requests to `app.immich:///oauth-callback`, and can be used for step 1. diff --git a/docs/docs/administration/server-commands.md b/docs/docs/administration/server-commands.md index a25673abf2..3838635c24 100644 --- a/docs/docs/administration/server-commands.md +++ b/docs/docs/administration/server-commands.md @@ -16,7 +16,7 @@ The `immich-server` docker image comes preinstalled with an administrative CLI ( ## How to run a command -To run a command, [connect](/docs/guides/docker-help.md#attach-to-a-container) to the `immich_server` container and then execute the command via `immich-admin `. +To run a command, [connect](/guides/docker-help.md#attach-to-a-container) to the `immich_server` container and then execute the command via `immich-admin `. ## Examples diff --git a/docs/docs/administration/system-settings.md b/docs/docs/administration/system-settings.md index f241050136..fdfdad29ea 100644 --- a/docs/docs/administration/system-settings.md +++ b/docs/docs/administration/system-settings.md @@ -12,14 +12,14 @@ Manage password, OAuth, and other authentication settings ### OAuth Authentication -Immich supports OAuth Authentication. Read more about this feature and its configuration [here](/docs/administration/oauth). +Immich supports OAuth Authentication. Read more about this feature and its configuration [here](/administration/oauth). ### Password Authentication -The administrator can choose to disable login with username and password for the entire instance. This means that **no one**, including the system administrator, will be able to log using this method. If [OAuth Authentication](/docs/administration/oauth) is also disabled, no users will be able to login using **any** method. Changing this setting does not affect existing sessions, just new login attempts. +The administrator can choose to disable login with username and password for the entire instance. This means that **no one**, including the system administrator, will be able to log using this method. If [OAuth Authentication](/administration/oauth) is also disabled, no users will be able to login using **any** method. Changing this setting does not affect existing sessions, just new login attempts. :::tip -You can always use the [Server CLI](/docs/administration/server-commands) to re-enable password login. +You can always use the [Server CLI](/administration/server-commands) to re-enable password login. ::: ## Image Settings (thumbnails and previews) @@ -108,7 +108,7 @@ If more than one URL is provided, each server will be attempted one-at-a-time un ### Smart Search -The [smart search](/docs/features/searching) settings allow you to change the [CLIP model](https://openai.com/research/clip). Larger models will typically provide [more accurate search results](https://github.com/immich-app/immich/discussions/11862) but consume more processing power and RAM. When [changing the CLIP model](/docs/FAQ#can-i-use-a-custom-clip-model) it is mandatory to re-run the Smart Search job on all images to fully apply the change. +The [smart search](/features/searching) settings allow you to change the [CLIP model](https://openai.com/research/clip). Larger models will typically provide [more accurate search results](https://github.com/immich-app/immich/discussions/11862) but consume more processing power and RAM. When [changing the CLIP model](/FAQ#can-i-use-a-custom-clip-model) it is mandatory to re-run the Smart Search job on all images to fully apply the change. :::info Internet connection Changing models requires a connection to the Internet to download the model. @@ -132,7 +132,7 @@ Editable settings: - **Max Recognition Distance** - **Min Recognized Faces** -You can learn more about these options on the [Facial Recognition page](/docs/features/facial-recognition#how-face-detection-works) +You can learn more about these options on the [Facial Recognition page](/features/facial-recognition#how-face-detection-works) :::info When changing the values in Min Detection Score, Max Recognition Distance, and Min Recognized Faces. @@ -154,15 +154,15 @@ The map can be adjusted via [OpenMapTiles](https://openmaptiles.org/styles/) for ### Reverse Geocoding Settings -Immich supports [Reverse Geocoding](/docs/features/reverse-geocoding) using data from the [GeoNames](https://www.geonames.org/) geographical database. +Immich supports [Reverse Geocoding](/features/reverse-geocoding) using data from the [GeoNames](https://www.geonames.org/) geographical database. ## Notification Settings -SMTP server setup, for user creation notifications, new albums, etc. More information can be found [here](/docs/administration/email-notification) +SMTP server setup, for user creation notifications, new albums, etc. More information can be found [here](/administration/email-notification) ## Notification Templates -Override the default notifications text with notification templates. More information can be found [here](/docs/administration/email-notification) +Override the default notifications text with notification templates. More information can be found [here](/administration/email-notification) ## Server Settings @@ -176,7 +176,7 @@ The administrator can set a custom message on the login screen (the message will ## Storage Template -Immich supports a custom [Storage Template](/docs/administration/storage-template). Learn more about this feature and its configuration [here](/docs/administration/storage-template). +Immich supports a custom [Storage Template](/administration/storage-template). Learn more about this feature and its configuration [here](/administration/storage-template). ## Theme Settings diff --git a/docs/docs/developer/architecture.mdx b/docs/docs/developer/architecture.mdx index a8d38ba5c1..42d9c1b974 100644 --- a/docs/docs/developer/architecture.mdx +++ b/docs/docs/developer/architecture.mdx @@ -44,7 +44,7 @@ The web app is a [TypeScript](https://www.typescriptlang.org/) project that uses ### CLI -The Immich CLI is an [npm](https://www.npmjs.com/) package that lets users control their Immich instance from the command line. It uses the API to perform various tasks, especially uploading assets. See the [CLI documentation](/docs/features/command-line-interface.md) for more information. +The Immich CLI is an [npm](https://www.npmjs.com/) package that lets users control their Immich instance from the command line. It uses the API to perform various tasks, especially uploading assets. See the [CLI documentation](/features/command-line-interface.md) for more information. ## Server @@ -83,11 +83,11 @@ Immich uses a [worker](https://github.com/immich-app/immich/blob/main/server/src - Smart Search - Facial Recognition - Storage Template Migration -- Sidecar (see [XMP Sidecars](/docs/features/xmp-sidecars.md)) +- Sidecar (see [XMP Sidecars](/features/xmp-sidecars.md)) - Background jobs (file deletion, user deletion) :::info -This list closely matches what is available on the [Administration > Jobs](/docs/administration/jobs-workers/#jobs) page, which provides some remote queue management capabilities. +This list closely matches what is available on the [Administration > Jobs](/administration/jobs-workers/#jobs) page, which provides some remote queue management capabilities. ::: ### Machine Learning diff --git a/docs/docs/developer/devcontainers.md b/docs/docs/developer/devcontainers.md index c7c48acf2b..0a1946e6c1 100644 --- a/docs/docs/developer/devcontainers.md +++ b/docs/docs/developer/devcontainers.md @@ -431,7 +431,7 @@ While the Dev Container focuses on server and web development, you can connect m - Server URL: `http://YOUR_IP:2283/api` - Ensure firewall allows port 2283 -3. **For full mobile development**, see the [mobile development guide](/docs/developer/setup) which covers: +3. **For full mobile development**, see the [mobile development guide](/developer/setup) which covers: - Flutter setup - Running on simulators/devices - Mobile-specific debugging @@ -474,7 +474,7 @@ Recommended minimums: ## Next Steps -- Read the [architecture overview](/docs/developer/architecture) -- Learn about [database migrations](/docs/developer/database-migrations) -- Explore [API documentation](/docs/api) +- Read the [architecture overview](/developer/architecture) +- Learn about [database migrations](/developer/database-migrations) +- Explore [API documentation](https://api.immich.app/) - Join `#immich` on [Discord](https://discord.immich.app) diff --git a/docs/docs/developer/open-api.md b/docs/docs/developer/open-api.md index 2c29c7365b..f627b2c459 100644 --- a/docs/docs/developer/open-api.md +++ b/docs/docs/developer/open-api.md @@ -1,6 +1,6 @@ # OpenAPI -Immich uses the [OpenAPI](https://swagger.io/specification/) standard to generate API documentation. To view the published docs see [here](/docs/api). +Immich uses the [OpenAPI](https://swagger.io/specification/) standard to generate API documentation. To view the published docs see [here](https://api.immich.app/). ## Generator diff --git a/docs/docs/developer/pr-checklist.md b/docs/docs/developer/pr-checklist.md index ea44367742..f855e854c4 100644 --- a/docs/docs/developer/pr-checklist.md +++ b/docs/docs/developer/pr-checklist.md @@ -53,8 +53,8 @@ You can use `dart fix --apply` and `dcm fix lib` to potentially correct some iss ## OpenAPI -The OpenAPI client libraries need to be regenerated whenever there are changes to the `immich-openapi-specs.json` file. Note that you should not modify this file directly as it is auto-generated. See [OpenAPI](/docs/developer/open-api.md) for more details. +The OpenAPI client libraries need to be regenerated whenever there are changes to the `immich-openapi-specs.json` file. Note that you should not modify this file directly as it is auto-generated. See [OpenAPI](/developer/open-api.md) for more details. ## Database Migrations -A database migration needs to be generated whenever there are changes to `server/src/infra/src/entities`. See [Database Migration](/docs/developer/database-migrations.md) for more details. +A database migration needs to be generated whenever there are changes to `server/src/infra/src/entities`. See [Database Migration](/developer/database-migrations.md) for more details. diff --git a/docs/docs/features/automatic-backup.md b/docs/docs/features/automatic-backup.md index 8fcbedaa6e..30d132cef8 100644 --- a/docs/docs/features/automatic-backup.md +++ b/docs/docs/features/automatic-backup.md @@ -16,7 +16,7 @@ If foreground backup is enabled: whenever the app is opened or resumed, it will ## Background backup -This feature is intended for everyday use. For initial bulk uploading, please use the foreground upload feature. For more information on why background upload is not working as expected, please refer to the [FAQ](/docs/FAQ#why-does-foreground-backup-stop-when-i-navigate-away-from-the-app-shouldnt-it-transfer-the-job-to-background-backup). +This feature is intended for everyday use. For initial bulk uploading, please use the foreground upload feature. For more information on why background upload is not working as expected, please refer to the [FAQ](/FAQ#why-does-foreground-backup-stop-when-i-navigate-away-from-the-app-shouldnt-it-transfer-the-job-to-background-backup). If background backup is enabled. The app will periodically check if there are any new photos or videos in the selected album(s) to be uploaded to the server. If there are, it will upload them to the cloud in the background. diff --git a/docs/docs/features/facial-recognition.md b/docs/docs/features/facial-recognition.md index f0dec55484..85712ef5f6 100644 --- a/docs/docs/features/facial-recognition.md +++ b/docs/docs/features/facial-recognition.md @@ -70,7 +70,7 @@ Navigating to Administration > Settings > Machine Learning Settings > Facial Rec :::tip It's better to only tweak the parameters here than to set them to something very different unless you're ready to test a variety of options. If you do need to set a parameter to a strict setting, relaxing other settings can be a good option to compensate, and vice versa. -You can learn how the tune the result in this [Guide](/docs/guides/better-facial-clusters) +You can learn how the tune the result in this [Guide](/guides/better-facial-clusters) ::: ### Facial recognition model diff --git a/docs/docs/features/libraries.md b/docs/docs/features/libraries.md index e68bcdc272..08f37c6821 100644 --- a/docs/docs/features/libraries.md +++ b/docs/docs/features/libraries.md @@ -103,7 +103,7 @@ The `immich-server` container will need access to the gallery. Modify your docke :::tip The `ro` flag at the end only gives read-only access to the volumes. -This will disallow the images from being deleted in the web UI, or adding metadata to the library ([XMP sidecars](/docs/features/xmp-sidecars)). +This will disallow the images from being deleted in the web UI, or adding metadata to the library ([XMP sidecars](/features/xmp-sidecars)). ::: :::info diff --git a/docs/docs/features/ml-hardware-acceleration.md b/docs/docs/features/ml-hardware-acceleration.md index a94f8c8c64..086f93a000 100644 --- a/docs/docs/features/ml-hardware-acceleration.md +++ b/docs/docs/features/ml-hardware-acceleration.md @@ -35,7 +35,7 @@ You do not need to redo any machine learning jobs after enabling hardware accele - Where and how you can get this file depends on device and vendor, but typically, the device vendor also supplies these - The `hwaccel.ml.yml` file assumes the path to it is `/usr/lib/libmali.so`, so update accordingly if it is elsewhere - The `hwaccel.ml.yml` file assumes an additional file `/lib/firmware/mali_csffw.bin`, so update accordingly if your device's driver does not require this file -- Optional: Configure your `.env` file, see [environment variables](/docs/install/environment-variables) for ARM NN specific settings +- Optional: Configure your `.env` file, see [environment variables](/install/environment-variables) for ARM NN specific settings - In particular, the `MACHINE_LEARNING_ANN_FP16_TURBO` can significantly improve performance at the cost of very slightly lower accuracy #### CUDA @@ -49,7 +49,7 @@ You do not need to redo any machine learning jobs after enabling hardware accele - The GPU must be supported by ROCm. If it isn't officially supported, you can attempt to use the `HSA_OVERRIDE_GFX_VERSION` environmental variable: `HSA_OVERRIDE_GFX_VERSION=`. If this doesn't work, you might need to also set `HSA_USE_SVM=0`. - The ROCm image is quite large and requires at least 35GiB of free disk space. However, pulling later updates to the service through Docker will generally only amount to a few hundred megabytes as the rest will be cached. -- This backend is new and may experience some issues. For example, GPU power consumption can be higher than usual after running inference, even if the machine learning service is idle. In this case, it will only go back to normal after being idle for 5 minutes (configurable with the [MACHINE_LEARNING_MODEL_TTL](/docs/install/environment-variables) setting). +- This backend is new and may experience some issues. For example, GPU power consumption can be higher than usual after running inference, even if the machine learning service is idle. In this case, it will only go back to normal after being idle for 5 minutes (configurable with the [MACHINE_LEARNING_MODEL_TTL](/install/environment-variables) setting). #### OpenVINO @@ -64,7 +64,7 @@ You do not need to redo any machine learning jobs after enabling hardware accele - This is usually pre-installed on the device vendor's Linux images - RKNPU driver V0.9.8 or later must be available in the host server - You may confirm this by running `cat /sys/kernel/debug/rknpu/version` to check the version -- Optional: Configure your `.env` file, see [environment variables](/docs/install/environment-variables) for RKNN specific settings +- Optional: Configure your `.env` file, see [environment variables](/install/environment-variables) for RKNN specific settings - In particular, setting `MACHINE_LEARNING_RKNN_THREADS` to 2 or 3 can _dramatically_ improve performance for RK3576 and RK3588 compared to the default of 1, at the expense of multiplying the amount of RAM each model uses by that amount. ## Setup diff --git a/docs/docs/features/mobile-app.mdx b/docs/docs/features/mobile-app.mdx index cd837741f1..82a2976b41 100644 --- a/docs/docs/features/mobile-app.mdx +++ b/docs/docs/features/mobile-app.mdx @@ -28,7 +28,7 @@ The beta release channel allows users to test upcoming changes before they are o :::info -You can enable automatic backup on supported devices. For more information see [Automatic Backup](/docs/features/automatic-backup.md). +You can enable automatic backup on supported devices. For more information see [Automatic Backup](/features/automatic-backup.md). ::: ## Sync only selected photos @@ -75,7 +75,7 @@ You can sync or mirror an album from your phone to the Immich server on your acc - **User-Specific Sync:** Album synchronization is unique to each server user and does not sync between different users or partners. -- **Mobile-Only Feature:** Album synchronization is currently only available on mobile. For similar options on a computer, refer to [Libraries](/docs/features/libraries) for further details. +- **Mobile-Only Feature:** Album synchronization is currently only available on mobile. For similar options on a computer, refer to [Libraries](/features/libraries) for further details. ### Synchronizing albums from the past diff --git a/docs/docs/features/monitoring.md b/docs/docs/features/monitoring.md index c80f66902b..f087a3306f 100644 --- a/docs/docs/features/monitoring.md +++ b/docs/docs/features/monitoring.md @@ -28,7 +28,7 @@ The metrics in immich are grouped into API (endpoint calls and response times), Immich will not expose an endpoint for metrics by default. To enable this endpoint, you can add the `IMMICH_TELEMETRY_INCLUDE=all` environmental variable to your `.env` file. Note that only the server container currently use this variable. :::tip -`IMMICH_TELEMETRY_INCLUDE=all` enables all metrics. For a more granular configuration you can enumerate the telemetry metrics that should be included as a comma separated list (e.g. `IMMICH_TELEMETRY_INCLUDE=repo,api`). Alternatively, you can also exclude specific metrics with `IMMICH_TELEMETRY_EXCLUDE`. For more information refer to the [environment section](/docs/install/environment-variables.md#prometheus). +`IMMICH_TELEMETRY_INCLUDE=all` enables all metrics. For a more granular configuration you can enumerate the telemetry metrics that should be included as a comma separated list (e.g. `IMMICH_TELEMETRY_INCLUDE=repo,api`). Alternatively, you can also exclude specific metrics with `IMMICH_TELEMETRY_EXCLUDE`. For more information refer to the [environment section](/install/environment-variables.md#prometheus). ::: The next step is to configure a new or existing Prometheus instance to scrape this endpoint. The following steps assume that you do not have an existing Prometheus instance, but the steps will be similar either way. @@ -68,7 +68,7 @@ After bringing down the containers with `docker compose down` and back up with ` :::note To see exactly what metrics are made available, you can additionally add `8081:8081` (API metrics) and `8082:8082` (microservices metrics) to the immich_server container's ports. Visiting the `/metrics` endpoint for these services will show the same raw data that Prometheus collects. -To configure these ports see [`IMMICH_API_METRICS_PORT` & `IMMICH_MICROSERVICES_METRICS_PORT`](/docs/install/environment-variables/#general). +To configure these ports see [`IMMICH_API_METRICS_PORT` & `IMMICH_MICROSERVICES_METRICS_PORT`](/install/environment-variables/#general). ::: ### Usage diff --git a/docs/docs/features/reverse-geocoding.md b/docs/docs/features/reverse-geocoding.md index 399bdd9b48..b1aee74a99 100644 --- a/docs/docs/features/reverse-geocoding.md +++ b/docs/docs/features/reverse-geocoding.md @@ -8,7 +8,7 @@ During Exif Extraction, assets with latitudes and longitudes are reverse geocode ## Usage -Data from a reverse geocode is displayed in the image details, and used in [Smart Search](/docs/features/searching.md). +Data from a reverse geocode is displayed in the image details, and used in [Smart Search](/features/searching.md). diff --git a/docs/docs/features/sharing.md b/docs/docs/features/sharing.md index ff0a03beea..9ba7470407 100644 --- a/docs/docs/features/sharing.md +++ b/docs/docs/features/sharing.md @@ -24,7 +24,7 @@ After creating an album, you can access the sharing options by clicking on the s Partner sharing allows you to share your _entire_ library with other users of your choice. They can then view your library and download the assets. -You can read this guide to learn more about [partner sharing](/docs/features/partner-sharing). +You can read this guide to learn more about [partner sharing](/features/partner-sharing). ## Public sharing diff --git a/docs/docs/features/tags.md b/docs/docs/features/tags.md index a5b6752c81..79a9696d9a 100644 --- a/docs/docs/features/tags.md +++ b/docs/docs/features/tags.md @@ -1,6 +1,6 @@ # Tags -Immich supports hierarchical tags, with the ability to read existing tags from the XMP `TagsList` field and IPTC `Keywords` field. Any changes to tags made through Immich are also written back to a [sidecar](/docs/features/xmp-sidecars) file. You can re-run the metadata extraction jobs for all assets to import your existing tags. +Immich supports hierarchical tags, with the ability to read existing tags from the XMP `TagsList` field and IPTC `Keywords` field. Any changes to tags made through Immich are also written back to a [sidecar](/features/xmp-sidecars) file. You can re-run the metadata extraction jobs for all assets to import your existing tags. ## Enable tags feature diff --git a/docs/docs/features/user-settings.md b/docs/docs/features/user-settings.md index a2d0308541..402105cd43 100644 --- a/docs/docs/features/user-settings.md +++ b/docs/docs/features/user-settings.md @@ -15,9 +15,9 @@ You can access the [user settings](https://my.immich.app/user-settings) by click --- :::tip Reset Password -The admin can reset a user password through the [User Management](/docs/administration/user-management.mdx) screen. +The admin can reset a user password through the [User Management](/administration/user-management.mdx) screen. ::: :::tip Reset Admin Password -The admin password can be reset using a [Server Command](/docs/administration/server-commands.md) +The admin password can be reset using a [Server Command](/administration/server-commands.md) ::: diff --git a/docs/docs/guides/better-facial-clusters.md b/docs/docs/guides/better-facial-clusters.md index f4409b441c..40796983a5 100644 --- a/docs/docs/guides/better-facial-clusters.md +++ b/docs/docs/guides/better-facial-clusters.md @@ -10,7 +10,7 @@ This guide explains how to optimize facial recognition in systems with large ima - **Best Suited For:** Large image libraries after importing a significant number of images. - **Warning:** This method deletes all previously assigned names. -- **Tip:** **Always take a [backup](/docs/administration/backup-and-restore#database) before proceeding!** +- **Tip:** **Always take a [backup](/administration/backup-and-restore#database) before proceeding!** --- diff --git a/docs/docs/guides/custom-locations.md b/docs/docs/guides/custom-locations.md index af8ca438e7..e0274d3bd9 100644 --- a/docs/docs/guides/custom-locations.md +++ b/docs/docs/guides/custom-locations.md @@ -9,7 +9,7 @@ It is important to remember to update the backup settings after following the gu In our `.env` file, we will define the paths we want to use. Note that you don't have to define all of these: UPLOAD_LOCATION will be the base folder that files are stored in by default, with the other paths acting as overrides. ```diff title=".env" -# You can find documentation for all the supported environment variables [here](/docs/install/environment-variables) +# You can find documentation for all the supported environment variables [here](/install/environment-variables) # Custom location where your uploaded, thumbnails, and transcoded video files are stored - UPLOAD_LOCATION=./library diff --git a/docs/docs/guides/database-queries.md b/docs/docs/guides/database-queries.md index 1a5c2ed193..5cdcdc04c4 100644 --- a/docs/docs/guides/database-queries.md +++ b/docs/docs/guides/database-queries.md @@ -7,7 +7,7 @@ Keep in mind that mucking around in the database might set the Moon on fire. Avo :::tip Run `docker exec -it immich_postgres psql --dbname= --username=` to connect to the database via the container directly. -(Replace `` and `` with the values from your [`.env` file](/docs/install/environment-variables#database)). +(Replace `` and `` with the values from your [`.env` file](/install/environment-variables#database)). ::: ## Assets @@ -142,7 +142,7 @@ DELETE FROM "person" WHERE "name" = 'PersonNameHere'; SELECT "key", "value" FROM "system_metadata" WHERE "key" = 'system-config'; ``` -(Only used when not using the [config file](/docs/install/config-file)) +(Only used when not using the [config file](/install/config-file)) ### File properties diff --git a/docs/docs/guides/external-library.md b/docs/docs/guides/external-library.md index 7921843297..ef467159e7 100644 --- a/docs/docs/guides/external-library.md +++ b/docs/docs/guides/external-library.md @@ -1,13 +1,13 @@ # External Library -This guide walks you through adding an [External Library](/docs/features/libraries). +This guide walks you through adding an [External Library](/features/libraries). This guide assumes you are running Immich in Docker and that the files you wish to access are stored in a directory on the same machine. # Mount the directory into the containers. Edit `docker-compose.yml` to add one or more new mount points in the section `immich-server:` under `volumes:`. -If you want Immich to be able to delete the images in the external library or add metadata ([XMP sidecars](/docs/features/xmp-sidecars)), remove `:ro` from the end of the mount point. +If you want Immich to be able to delete the images in the external library or add metadata ([XMP sidecars](/features/xmp-sidecars)), remove `:ro` from the end of the mount point. ```diff immich-server: diff --git a/docs/docs/guides/remote-access.md b/docs/docs/guides/remote-access.md index 6f401dfc5a..518b003c3a 100644 --- a/docs/docs/guides/remote-access.md +++ b/docs/docs/guides/remote-access.md @@ -46,7 +46,7 @@ You can learn how to set up Tailscale together with Immich with the [tutorial vi A reverse proxy is a service that sits between web servers and clients. A reverse proxy can either be hosted on the server itself or remotely. Clients can connect to the reverse proxy via https, and the proxy relays data to Immich. This setup makes most sense if you have your own domain and want to access your Immich instance just like any other website, from outside your LAN. You can also use a DDNS provider like DuckDNS or no-ip if you don't have a domain. This configuration allows the Immich Android and iphone apps to connect to your server without a VPN or tailscale app on the client side. -If you're hosting your own reverse proxy, [Nginx](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/) is a great option. An example configuration for Nginx is provided [here](/docs/administration/reverse-proxy.md). +If you're hosting your own reverse proxy, [Nginx](https://docs.nginx.com/nginx/admin-guide/web-server/reverse-proxy/) is a great option. An example configuration for Nginx is provided [here](/administration/reverse-proxy.md). You'll also need your own certificate to authenticate https connections. If you're making Immich publicly accessible, [Let's Encrypt](https://letsencrypt.org/) can provide a free certificate for your domain and is the recommended option. Alternatively, a [self-signed certificate](https://en.wikipedia.org/wiki/Self-signed_certificate) allows you to encrypt your connection to Immich, but it raises a security warning on the client's browser. diff --git a/docs/docs/guides/remote-machine-learning.md b/docs/docs/guides/remote-machine-learning.md index 72ae0e3fa1..0a8ddf2577 100644 --- a/docs/docs/guides/remote-machine-learning.md +++ b/docs/docs/guides/remote-machine-learning.md @@ -1,6 +1,6 @@ # Remote Machine Learning -To alleviate [performance issues on low-memory systems](/docs/FAQ.mdx#why-is-immich-slow-on-low-memory-systems-like-the-raspberry-pi) like the Raspberry Pi, you may also host Immich's machine learning container on a more powerful system, such as your laptop or desktop computer. The server container will send requests containing the image preview to the remote machine learning container for processing. The machine learning container does not persist this data or associate it with a particular user. +To alleviate [performance issues on low-memory systems](/FAQ.mdx#why-is-immich-slow-on-low-memory-systems-like-the-raspberry-pi) like the Raspberry Pi, you may also host Immich's machine learning container on a more powerful system, such as your laptop or desktop computer. The server container will send requests containing the image preview to the remote machine learning container for processing. The machine learning container does not persist this data or associate it with a particular user. :::info Smart Search and Face Detection will use this feature, but Facial Recognition will not. This is because Facial Recognition uses the _outputs_ of these models that have already been saved to the database. As such, its processing is between the server container and the database. @@ -14,7 +14,7 @@ Image previews are sent to the remote machine learning container. Use this optio 2. Copy the following `docker-compose.yml` to the remote server :::info -If using hardware acceleration, the [hwaccel.ml.yml](https://github.com/immich-app/immich/releases/latest/download/hwaccel.ml.yml) file also needs to be added and the `docker-compose.yml` needs to be configured as described in the [hardware acceleration documentation](/docs/features/ml-hardware-acceleration) +If using hardware acceleration, the [hwaccel.ml.yml](https://github.com/immich-app/immich/releases/latest/download/hwaccel.ml.yml) file also needs to be added and the `docker-compose.yml` needs to be configured as described in the [hardware acceleration documentation](/features/ml-hardware-acceleration) ::: ```yaml diff --git a/docs/docs/guides/template-backup-script.md b/docs/docs/guides/template-backup-script.md index 34381dd0ee..19647d4ae1 100644 --- a/docs/docs/guides/template-backup-script.md +++ b/docs/docs/guides/template-backup-script.md @@ -7,7 +7,7 @@ This script assumes you have a second hard drive connected to your server for on The database is saved to your Immich upload folder in the `database-backup` subdirectory. The database is then backed up and versioned with your assets by Borg. This ensures that the database backup is in sync with your assets in every snapshot. :::info -This script makes backups of your database along with your photo/video library. This is redundant with the [automatic database backup tool](https://immich.app/docs/administration/backup-and-restore#automatic-database-backups) built into Immich. Using this script to backup your database has two advantages over the built-in backup tool: +This script makes backups of your database along with your photo/video library. This is redundant with the [automatic database backup tool](/administration/backup-and-restore#automatic-database-dumps) built into Immich. Using this script to backup your database has two advantages over the built-in backup tool: - This script uses storage more efficiently by versioning your backups instead of making multiple copies. - The database backups are performed at the same time as the library backup, ensuring that the backups of your database and the library are always in sync. diff --git a/docs/docs/install/config-file.md b/docs/docs/install/config-file.md index 54d7c61bb3..3fb0687e4a 100644 --- a/docs/docs/install/config-file.md +++ b/docs/docs/install/config-file.md @@ -209,7 +209,7 @@ So you can just grab it from there, paste it into a file and you're pretty much ### Step 2 - Specify the file location In your `.env` file, set the variable `IMMICH_CONFIG_FILE` to the path of your config. -For more information, refer to the [Environment Variables](/docs/install/environment-variables.md) section. +For more information, refer to the [Environment Variables](/install/environment-variables.md) section. :::tip YAML-formatted config files are also supported. diff --git a/docs/docs/install/docker-compose.mdx b/docs/docs/install/docker-compose.mdx index 7a0b566f5d..46b144eb4a 100644 --- a/docs/docs/install/docker-compose.mdx +++ b/docs/docs/install/docker-compose.mdx @@ -29,4 +29,4 @@ If you get an error `can't set healthcheck.start_interval as feature require Doc ## Next Steps -Read the [Post Installation](/docs/install/post-install.mdx) steps and [upgrade instructions](/docs/install/upgrading.md). +Read the [Post Installation](/install/post-install.mdx) steps and [upgrade instructions](/install/upgrading.md). diff --git a/docs/docs/install/environment-variables.md b/docs/docs/install/environment-variables.md index 928e0b26e5..e606d03dee 100644 --- a/docs/docs/install/environment-variables.md +++ b/docs/docs/install/environment-variables.md @@ -42,7 +42,7 @@ These environment variables are used by the `docker-compose.yml` file and do **N | `IMMICH_MICROSERVICES_METRICS_PORT` | Port for the OTEL metrics | `8082` | server | microservices | | `IMMICH_PROCESS_INVALID_IMAGES` | When `true`, generate thumbnails for invalid images | | server | microservices | | `IMMICH_TRUSTED_PROXIES` | List of comma-separated IPs set as trusted proxies | | server | api | -| `IMMICH_IGNORE_MOUNT_CHECK_ERRORS` | See [System Integrity](/docs/administration/system-integrity) | | server | api, microservices | +| `IMMICH_IGNORE_MOUNT_CHECK_ERRORS` | See [System Integrity](/administration/system-integrity) | | server | api, microservices | \*1: `TZ` should be set to a `TZ identifier` from [this list][tz-list]. For example, `TZ="Etc/UTC"`. `TZ` is used by `exiftool` as a fallback in case the timezone cannot be determined from the image metadata. It is also used for logfile timestamps and cron job execution. @@ -57,7 +57,7 @@ These environment variables are used by the `docker-compose.yml` file and do **N | `IMMICH_WORKERS_EXCLUDE` | Do not run these workers. Matches against default workers, or `IMMICH_WORKERS_INCLUDE` if specified. | | server | :::info -Information on the current workers can be found [here](/docs/administration/jobs-workers). +Information on the current workers can be found [here](/administration/jobs-workers). ::: ## Ports @@ -169,8 +169,6 @@ Redis (Sentinel) URL example JSON before encoding: | `MACHINE_LEARNING_ANN_TUNING_LEVEL` | ARM-NN GPU tuning level (1: rapid, 2: normal, 3: exhaustive) | `2` | machine learning | | `MACHINE_LEARNING_DEVICE_IDS`\*4 | Device IDs to use in multi-GPU environments | `0` | machine learning | | `MACHINE_LEARNING_MAX_BATCH_SIZE__FACIAL_RECOGNITION` | Set the maximum number of faces that will be processed at once by the facial recognition model | None (`1` if using OpenVINO) | machine learning | -| `MACHINE_LEARNING_PING_TIMEOUT` | How long (ms) to wait for a PING response when checking if an ML server is available | `2000` | server | -| `MACHINE_LEARNING_AVAILABILITY_BACKOFF_TIME` | How long to ignore ML servers that are offline before trying again | `30000` | server | | `MACHINE_LEARNING_RKNN` | Enable RKNN hardware acceleration if supported | `True` | machine learning | | `MACHINE_LEARNING_RKNN_THREADS` | How many threads of RKNN runtime should be spinned up while inferencing. | `1` | machine learning | diff --git a/docs/docs/install/portainer.md b/docs/docs/install/portainer.md index 916d89a0d5..07fd255292 100644 --- a/docs/docs/install/portainer.md +++ b/docs/docs/install/portainer.md @@ -45,5 +45,5 @@ alt="Dot Env Example" 11. Click on "**Deploy the stack**". :::tip -For more information on how to use the application, please refer to the [Post Installation](/docs/install/post-install.mdx) guide. +For more information on how to use the application, please refer to the [Post Installation](/install/post-install.mdx) guide. ::: diff --git a/docs/docs/install/post-install.mdx b/docs/docs/install/post-install.mdx index 636274aaea..b30e91f3cd 100644 --- a/docs/docs/install/post-install.mdx +++ b/docs/docs/install/post-install.mdx @@ -44,6 +44,6 @@ A list of common steps to take after installing Immich include: ## Setting up optional features -- [External Libraries](/docs/features/libraries.md): Adding your existing photo library to Immich -- [Hardware Transcoding](/docs/features/hardware-transcoding.md): Speeding up video transcoding -- [Hardware-Accelerated Machine Learning](/docs/features/ml-hardware-acceleration.md): Speeding up various machine learning tasks in Immich +- [External Libraries](/features/libraries.md): Adding your existing photo library to Immich +- [Hardware Transcoding](/features/hardware-transcoding.md): Speeding up video transcoding +- [Hardware-Accelerated Machine Learning](/features/ml-hardware-acceleration.md): Speeding up various machine learning tasks in Immich diff --git a/docs/docs/install/script.md b/docs/docs/install/script.md index 93d1fb166c..ce05dc82d9 100644 --- a/docs/docs/install/script.md +++ b/docs/docs/install/script.md @@ -5,12 +5,12 @@ sidebar_position: 20 # Install script [Experimental] :::caution -This method is experimental and not currently recommended for production use. For production, please refer to installing with [Docker Compose](/docs/install/docker-compose.mdx). +This method is experimental and not currently recommended for production use. For production, please refer to installing with [Docker Compose](/install/docker-compose.mdx). ::: ## Requirements -Follow the [requirements page](/docs/install/requirements) to get started. +Follow the [requirements page](/install/requirements) to get started. The install script only supports Linux operating systems and requires Docker to be already installed on the system. @@ -32,5 +32,5 @@ The web application and mobile app will be available at `http:// These are used to add custom configuration options or to enable specific features. -More information on available environment variables can be found in the **[environment variables documentation](/docs/install/environment-variables/)**. +More information on available environment variables can be found in the **[environment variables documentation](/install/environment-variables/)**. :::info Some environment variables are not available for the TrueNAS Community Edition app as they can be configured through GUI options in the [Edit Immich screen](#edit-app-settings). @@ -242,7 +242,7 @@ alt="Add External Libraries with Additional Storage" className="border rounded-xl" /> -You may configure [external libraries](/docs/features/libraries) by mounting them using **Additional Storage**. +You may configure [external libraries](/features/libraries) by mounting them using **Additional Storage**. The dataset that contains your external library files must at least give **read** access to the user running Immich (Default: `apps` (UID 568), `apps` (GID 568)). If you want to be able to delete files or edit metadata in the external library using Immich, you will need to give the **modify** permission to the user running Immich. @@ -266,7 +266,7 @@ A general recommendation is to mount any external libraries to a path beginning This feature should only be used by advanced users. ::: -Immich can use multiple datasets for its storage, allowing you to manage your data more granularly, similar to the old storage configuration. This is useful if you want to separate your data into different datasets for performance or organizational reasons. There is a general guide for this [here](/docs/guides/custom-locations), but read on for the TrueNAS guide. +Immich can use multiple datasets for its storage, allowing you to manage your data more granularly, similar to the old storage configuration. This is useful if you want to separate your data into different datasets for performance or organizational reasons. There is a general guide for this [here](/guides/custom-locations), but read on for the TrueNAS guide. Each additional dataset has to give the permission **_modify_** to the user who will run Immich (Default: `apps` (UID 568), `apps` (GID 568)) As described in the [Setting up Storage Datasets](#setting-up-storage-datasets) section above, you have to create the datasets with the **Apps** preset to ensure the correct permissions are set, or you can set the permissions manually after creating the datasets. @@ -309,7 +309,7 @@ className="border rounded-xl" Both **CPU** and **Memory** are limits, not reservations. This means that Immich can use up to the specified amount of CPU threads and RAM, but it will not reserve that amount of resources at all times. The system will allocate resources as needed, and Immich will use less than the specified amount most of the time. -- Enable **GPU Configuration** options if you have a GPU or CPU with integrated graphics that you will use for [Hardware Transcoding](/docs/features/hardware-transcoding) and/or [Hardware-Accelerated Machine Learning](/docs/features/ml-hardware-acceleration.md). +- Enable **GPU Configuration** options if you have a GPU or CPU with integrated graphics that you will use for [Hardware Transcoding](/features/hardware-transcoding) and/or [Hardware-Accelerated Machine Learning](/features/ml-hardware-acceleration.md). The process for NVIDIA GPU passthrough requires additional steps. More details here: [GPU Passthrough Docs for TrueNAS Apps](https://apps.truenas.com/managing-apps/installing-apps/#gpu-passthrough) @@ -332,7 +332,7 @@ Click **Web Portal** on the **Application Info** widget, or go to the URL `http: After that, you can start using Immich to upload and manage your photos and videos. :::tip -For more information on how to use the application once installed, please refer to the [Post Install](/docs/install/post-install.mdx) guide. +For more information on how to use the application once installed, please refer to the [Post Install](/install/post-install.mdx) guide. ::: ## Edit App Settings @@ -347,7 +347,7 @@ For more information on how to use the application once installed, please refer ## Updating the App :::danger -Make sure to read the general [upgrade instructions](/docs/install/upgrading.md). +Make sure to read the general [upgrade instructions](/install/upgrading.md). ::: When updates become available, TrueNAS alerts and provides easy updates. diff --git a/docs/docs/install/unraid.md b/docs/docs/install/unraid.md index efb493f267..ca7263a1e8 100644 --- a/docs/docs/install/unraid.md +++ b/docs/docs/install/unraid.md @@ -125,13 +125,13 @@ alt="Go to Docker Tab and visit the address listed next to immich-web" :::tip -For more information on how to use the application once installed, please refer to the [Post Install](/docs/install/post-install.mdx) guide. +For more information on how to use the application once installed, please refer to the [Post Install](/install/post-install.mdx) guide. ::: ## Updating Steps :::danger -Make sure to read the general [upgrade instructions](/docs/install/upgrading.md). +Make sure to read the general [upgrade instructions](/install/upgrading.md). ::: Updating is extremely easy however it's important to be aware that containers managed via the Docker Compose Manager plugin do not integrate with Unraid's native dockerman UI, the label "_update ready_" will always be present on containers installed via the Docker Compose Manager. diff --git a/docs/docs/install/upgrading.md b/docs/docs/install/upgrading.md index d638a6f7d1..305e61af57 100644 --- a/docs/docs/install/upgrading.md +++ b/docs/docs/install/upgrading.md @@ -40,7 +40,7 @@ If you do not deploy Immich using Docker Compose and see a deprecation warning f Immich has migrated off of the deprecated pgvecto.rs database extension to its successor, [VectorChord](https://github.com/tensorchord/VectorChord), which comes with performance improvements in almost every aspect. This section will guide you on how to make this change in a Docker Compose setup. -Before making any changes, please [back up your database](/docs/administration/backup-and-restore). While every effort has been made to make this migration as smooth as possible, there’s always a chance that something can go wrong. +Before making any changes, please [back up your database](/administration/backup-and-restore). While every effort has been made to make this migration as smooth as possible, there’s always a chance that something can go wrong. After making a backup, please modify your `docker-compose.yml` file with the following information. @@ -101,7 +101,7 @@ Please don’t hesitate to contact us on [GitHub](https://github.com/immich-app/ #### I have a separate PostgreSQL instance shared with multiple services. How can I switch to VectorChord? -Please see the [standalone PostgreSQL documentation](/docs/administration/postgres-standalone#migrating-to-vectorchord) for migration instructions. The migration path will be different depending on whether you’re currently using pgvecto.rs or pgvector, as well as whether Immich has superuser DB permissions. +Please see the [standalone PostgreSQL documentation](/administration/postgres-standalone#migrating-to-vectorchord) for migration instructions. The migration path will be different depending on whether you’re currently using pgvecto.rs or pgvector, as well as whether Immich has superuser DB permissions. #### Why are so many lines removed from the `docker-compose.yml` file? Does this mean the health check is removed? diff --git a/docs/docs/overview/help.md b/docs/docs/overview/help.md index f38ecde168..e6523547fa 100644 --- a/docs/docs/overview/help.md +++ b/docs/docs/overview/help.md @@ -6,7 +6,7 @@ sidebar_position: 6 Running into an issue or have a question? Try the following: -1. Check the [FAQs](/docs/FAQ.mdx). +1. Check the [FAQs](/FAQ.mdx). 2. Read through the [Release Notes][github-releases]. 3. Search through existing [GitHub Issues][github-issues]. 4. Open a help ticket on [Discord][discord-link]. diff --git a/docs/docs/overview/img/social-preview-light.webp b/docs/docs/overview/img/social-preview-light.webp deleted file mode 100644 index 3d088f6522..0000000000 Binary files a/docs/docs/overview/img/social-preview-light.webp and /dev/null differ diff --git a/docs/docs/overview/quick-start.mdx b/docs/docs/overview/quick-start.mdx index 28cee15007..d80a194ad2 100644 --- a/docs/docs/overview/quick-start.mdx +++ b/docs/docs/overview/quick-start.mdx @@ -13,7 +13,7 @@ to install and use it. - A system with at least 4GB of RAM and 2 CPU cores. - [Docker](https://docs.docker.com/engine/install/) -> For a more detailed list of requirements, see the [requirements page](/docs/install/requirements). +> For a more detailed list of requirements, see the [requirements page](/install/requirements). --- @@ -61,7 +61,7 @@ import MobileAppBackup from '/docs/partials/_mobile-app-backup.md'; The backup time differs depending on how many photos are on your mobile device. Large uploads may take quite a while. -To quickly get going, you can selectively upload few photos first, by following this [guide](/docs/features/mobile-app#sync-only-selected-photos). +To quickly get going, you can selectively upload few photos first, by following this [guide](/features/mobile-app#sync-only-selected-photos). You can select the **Jobs** tab to see Immich processing your photos. @@ -72,7 +72,7 @@ You can select the **Jobs** tab to see Immich processing your photos. ## Review the database backup and restore process Immich has built-in database backups. You can refer to the -[database backup](/docs/administration/backup-and-restore) for more information. +[database backup](/administration/backup-and-restore) for more information. :::danger The database only contains metadata and user information. You must setup manual backups of the images and videos stored in `UPLOAD_LOCATION`. @@ -86,8 +86,8 @@ You may decide you'd like to install the server a different way; the Install cat You may decide you'd like to add the _rest_ of your photos from Google Photos, even those not on your mobile device, via Google Takeout. You can use [immich-go](https://github.com/simulot/immich-go) for this. -You may want to [upload photos from your own archive](/docs/features/command-line-interface). +You may want to [upload photos from your own archive](/features/command-line-interface). -You may want to incorporate a pre-existing archive of photos from an [External Library](/docs/features/libraries); there's a [guide](/docs/guides/external-library) for that. +You may want to incorporate a pre-existing archive of photos from an [External Library](/features/libraries); there's a [guide](/guides/external-library) for that. -You may want your mobile device to [back photos up to your server automatically](/docs/features/automatic-backup). +You may want your mobile device to [back photos up to your server automatically](/features/automatic-backup). diff --git a/docs/docs/overview/support-the-project.md b/docs/docs/overview/support-the-project.md index a439893a7e..ae24a3f1ce 100644 --- a/docs/docs/overview/support-the-project.md +++ b/docs/docs/overview/support-the-project.md @@ -10,11 +10,11 @@ By far the easiest way to help make Immich better it to use it and report issues ## Translations -Support the project by localizing on [Weblate](https://hosted.weblate.org/projects/immich/immich/). For more information, see the [Translations](/docs/developer/translations) section. +Support the project by localizing on [Weblate](https://hosted.weblate.org/projects/immich/immich/). For more information, see the [Translations](/developer/translations) section. ## Development -If you are a programmer or developer, take a look at Immich's [technology stack](/docs/developer/architecture.mdx) and consider fixing bugs or building new features. The team and I are always looking for new contributors. For information about how to contribute as a developer, see the [Developer](/docs/developer/architecture.mdx) section. +If you are a programmer or developer, take a look at Immich's [technology stack](/developer/architecture.mdx) and consider fixing bugs or building new features. The team and I are always looking for new contributors. For information about how to contribute as a developer, see the [Developer](/developer/architecture.mdx) section. ## Purchase Immich diff --git a/docs/docs/overview/welcome.mdx b/docs/docs/overview/welcome.mdx deleted file mode 100644 index 93ce705369..0000000000 --- a/docs/docs/overview/welcome.mdx +++ /dev/null @@ -1,27 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Welcome to Immich - -Immich - Self-hosted photos and videos backup tool - -## Welcome! - -Hello, I am glad you are here. - -My name is Alex. I am an Electrical Engineer by schooling, then turned into a Software Engineer by trade and the pure love of problem solving. - -We were lying in bed with our newborn, and my wife said, "We are starting to accumulate a lot of photos and videos of our baby, and I don't want to pay for **_App-Which-Must-Not-Be-Named_** anymore. You always want to build something for me, so why don't you build me an app which can do that?" - -That was how the idea started to grow in my head. After that, I began to find existing solutions in the self-hosting space with similar backup functionality and the performance level of the **_App-Which-Must-Not-Be-Named_**. I found that the current solutions mainly focus on the gallery-type application. However, I want a simple-to-use backup tool with a native mobile app that can view photos and videos efficiently. So I set sail on this journey as a hungry engineer on the hunt. - -Another motivation that pushed me to deliver my execution of the **_App-Which-Must-Not-Be-Named_** alternative or replacement is for contributing back to the open source community that I have greatly benefited from over the years. - -I'm proud to share this creation with you, which values privacy, memories, and the joy of looking back at those moments in an easy-to-use and friendly interface. - -If you like the application or it helps you in some way, please consider [supporting](./support-the-project.md) the project. It will help me to continue to develop and maintain the application. diff --git a/docs/docs/partials/_server-backup.md b/docs/docs/partials/_server-backup.md index b9479600aa..34c93d78a1 100644 --- a/docs/docs/partials/_server-backup.md +++ b/docs/docs/partials/_server-backup.md @@ -1,5 +1,5 @@ Now that you have imported some pictures, you should setup server backups to preserve your memories. -You can do so by following our [backup guide](/docs/administration/backup-and-restore.md). +You can do so by following our [backup guide](/administration/backup-and-restore.md). :::danger Immich is still under heavy development _and_ handles very important data. diff --git a/docs/docs/partials/_storage-template.md b/docs/docs/partials/_storage-template.md index 20e9caac43..84236e0ac1 100644 --- a/docs/docs/partials/_storage-template.md +++ b/docs/docs/partials/_storage-template.md @@ -1,7 +1,7 @@ -Immich allows the admin user to set the uploaded filename pattern at the directory and filename level as well as the [storage label for a user](/docs/administration/user-management/#set-storage-label-for-user). +Immich allows the admin user to set the uploaded filename pattern at the directory and filename level as well as the [storage label for a user](/administration/user-management/#set-storage-label-for-user). :::tip -You can read more about the differences between storage template engine on and off [here](/docs/administration/backup-and-restore#asset-types-and-storage-locations) +You can read more about the differences between storage template engine on and off [here](/administration/backup-and-restore#asset-types-and-storage-locations) ::: The admin user can set the template by using the template builder in the `Administration -> Settings -> Storage Template`. Immich provides a set of variables that you can use in constructing the template, along with additional custom text. If the template produces [multiple files with the same filename, they won't be overwritten](https://github.com/immich-app/immich/discussions/3324) as a sequence number is appended to the filename. diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index d612dda253..fd550806f8 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -42,26 +42,19 @@ const config = { ], presets: [ [ - 'docusaurus-preset-openapi', - /** @type {import('docusaurus-preset-openapi').Options} */ + 'classic', + /** @type {import('@docusaurus/preset-classic').Options} */ ({ docs: { showLastUpdateAuthor: true, showLastUpdateTime: true, + routeBasePath: '/', sidebarPath: require.resolve('./sidebars.js'), // Please change this to your repo. // Remove this to remove the "edit this page" links. editUrl: 'https://github.com/immich-app/immich/tree/main/docs/', }, - api: { - path: '../open-api/immich-openapi-specs.json', - routeBasePath: '/docs/api', - }, - // blog: { - // showReadingTime: true, - // editUrl: "https://github.com/immich-app/immich/tree/main/docs/", - // }, theme: { customCss: require.resolve('./src/css/custom.css'), }, @@ -95,17 +88,17 @@ const config = { position: 'right', }, { - to: '/docs/overview/welcome', + to: '/overview/quick-start', position: 'right', label: 'Docs', }, { - to: '/roadmap', + href: 'https://immich.app/roadmap', position: 'right', label: 'Roadmap', }, { - to: '/docs/api', + href: 'https://api.immich.app/', position: 'right', label: 'API', }, @@ -139,16 +132,16 @@ const config = { title: 'Overview', items: [ { - label: 'Welcome', - to: '/docs/overview/welcome', + label: 'Quick start', + to: '/overview/quick-start', }, { label: 'Installation', - to: '/docs/install/requirements', + to: '/install/requirements', }, { label: 'Contributing', - to: '/docs/overview/support-the-project', + to: '/overview/support-the-project', }, { label: 'Privacy Policy', @@ -161,15 +154,15 @@ const config = { items: [ { label: 'Roadmap', - to: '/roadmap', + href: 'https://immich.app/roadmap', }, { label: 'API', - to: '/docs/api', + href: 'https://api.immich.app/', }, { label: 'Cursed Knowledge', - to: '/cursed-knowledge', + href: 'https://immich.app/cursed-knowledge', }, ], }, diff --git a/docs/package.json b/docs/package.json index 1a1dbcf84c..151fe42e25 100644 --- a/docs/package.json +++ b/docs/package.json @@ -25,7 +25,6 @@ "@mdx-js/react": "^3.0.0", "autoprefixer": "^10.4.17", "docusaurus-lunr-search": "^3.3.2", - "docusaurus-preset-openapi": "^0.7.5", "lunr": "^2.3.9", "postcss": "^8.4.25", "prism-react-renderer": "^2.3.1", diff --git a/docs/src/components/version-switcher.tsx b/docs/src/components/version-switcher.tsx index 5cb23891aa..739d7bd001 100644 --- a/docs/src/components/version-switcher.tsx +++ b/docs/src/components/version-switcher.tsx @@ -11,7 +11,7 @@ export default function VersionSwitcher(): JSX.Element { useEffect(() => { async function getVersions() { try { - let baseUrl = 'https://immich.app'; + let baseUrl = 'https://docs.immich.app'; if (window.location.origin === 'http://localhost:3005') { baseUrl = window.location.origin; } @@ -21,12 +21,13 @@ export default function VersionSwitcher(): JSX.Element { const archiveVersions = await response.json(); const allVersions = [ - { label: 'Next', url: 'https://main.preview.immich.app' }, - { label: 'Latest', url: 'https://immich.app' }, + { label: 'Next', url: 'https://docs.main.preview.immich.app' }, + { label: 'Latest', url: 'https://docs.immich.app' }, ...archiveVersions, - ].map(({ label, url }) => ({ + ].map(({ label, url, rootPath }) => ({ label, url: new URL(url), + rootPath, })); setVersions(allVersions); @@ -50,12 +51,18 @@ export default function VersionSwitcher(): JSX.Element { className="version-switcher-34ab39" label={activeLabel} mobile={windowSize === 'mobile'} - items={versions.map(({ label, url }) => ({ - label, - to: new URL(location.pathname + location.search + location.hash, url).href, - target: '_self', - className: label === activeLabel ? 'dropdown__link--active menu__link--active' : '', // workaround because React Router `` only supports using URL path for checking if active: https://v5.reactrouter.com/web/api/NavLink/isactive-func - }))} + items={versions.map(({ label, url, rootPath }) => { + let path = location.pathname + location.search + location.hash; + if (rootPath && !path.startsWith(rootPath)) { + path = rootPath + path; + } + return { + label, + to: new URL(path, url).href, + target: '_self', + className: label === activeLabel ? 'dropdown__link--active menu__link--active' : '', // workaround because React Router `` only supports using URL path for checking if active: https://v5.reactrouter.com/web/api/NavLink/isactive-func + }; + })} /> ) ); diff --git a/docs/src/pages/cursed-knowledge.tsx b/docs/src/pages/cursed-knowledge.tsx deleted file mode 100644 index f3dacc2ce6..0000000000 --- a/docs/src/pages/cursed-knowledge.tsx +++ /dev/null @@ -1,273 +0,0 @@ -import { - mdiBug, - mdiCalendarToday, - mdiCrosshairsOff, - mdiCrop, - mdiDatabase, - mdiLeadPencil, - mdiLockOff, - mdiLockOutline, - mdiMicrosoftWindows, - mdiSecurity, - mdiSpeedometerSlow, - mdiTrashCan, - mdiWeb, - mdiWrap, - mdiCloudKeyOutline, - mdiRegex, - mdiCodeJson, - mdiClockOutline, - mdiAccountOutline, - mdiRestart, -} from '@mdi/js'; -import Layout from '@theme/Layout'; -import React from 'react'; -import { Timeline, Item as TimelineItem } from '../components/timeline'; - -const withLanguage = (date: Date) => (language: string) => date.toLocaleDateString(language); - -type Item = Omit & { date: Date }; - -const items: Item[] = [ - { - icon: mdiClockOutline, - iconColor: 'gray', - title: 'setTimeout is cursed', - description: - 'The setTimeout method in JavaScript is cursed when used with small values because the implementation may or may not actually wait the specified time.', - link: { - url: 'https://github.com/immich-app/immich/pull/20655', - text: '#20655', - }, - date: new Date(2025, 7, 4), - }, - { - icon: mdiAccountOutline, - iconColor: '#DAB1DA', - title: 'PostgreSQL USER is cursed', - description: - 'The USER keyword in PostgreSQL is cursed because you can select from it like a table, which leads to confusion if you have a table name user as well.', - link: { - url: 'https://github.com/immich-app/immich/pull/19891', - text: '#19891', - }, - date: new Date(2025, 7, 4), - }, - { - icon: mdiRestart, - iconColor: '#8395e3', - title: 'PostgreSQL RESET is cursed', - description: - 'PostgreSQL RESET is cursed because it is impossible to RESET a PostgreSQL extension parameter if the extension has been uninstalled.', - link: { - url: 'https://github.com/immich-app/immich/pull/19363', - text: '#19363', - }, - date: new Date(2025, 5, 20), - }, - { - icon: mdiRegex, - iconColor: 'purple', - title: 'Zitadel Actions are cursed', - description: - "Zitadel is cursed because its custom scripting feature is executed with a JS engine that doesn't support regex named capture groups.", - link: { - url: 'https://github.com/dop251/goja', - text: 'Go JS engine', - }, - date: new Date(2025, 5, 4), - }, - { - icon: mdiCloudKeyOutline, - iconColor: '#0078d4', - title: 'Entra is cursed', - description: - "Microsoft Entra supports PKCE, but doesn't include it in its OpenID discovery document. This leads to clients thinking PKCE isn't available.", - link: { - url: 'https://github.com/immich-app/immich/pull/18725', - text: '#18725', - }, - date: new Date(2025, 4, 30), - }, - { - icon: mdiCrop, - iconColor: 'tomato', - title: 'Image dimensions in EXIF metadata are cursed', - description: - 'The dimensions in EXIF metadata can be different from the actual dimensions of the image, causing issues with cropping and resizing.', - link: { - url: 'https://github.com/immich-app/immich/pull/17974', - text: '#17974', - }, - date: new Date(2025, 4, 5), - }, - { - icon: mdiCodeJson, - iconColor: 'yellow', - title: 'YAML whitespace is cursed', - description: 'YAML whitespaces are often handled in unintuitive ways.', - link: { - url: 'https://github.com/immich-app/immich/pull/17309', - text: '#17309', - }, - date: new Date(2025, 3, 1), - }, - { - icon: mdiMicrosoftWindows, - iconColor: '#357EC7', - title: 'Hidden files in Windows are cursed', - description: - 'Hidden files in Windows cannot be opened with the "w" flag. That, combined with SMB option "hide dot files" leads to a lot of confusion.', - link: { - url: 'https://github.com/immich-app/immich/pull/12812', - text: '#12812', - }, - date: new Date(2024, 8, 20), - }, - { - icon: mdiWrap, - iconColor: 'gray', - title: 'Carriage returns in bash scripts are cursed', - description: 'Git can be configured to automatically convert LF to CRLF on checkout and CRLF breaks bash scripts.', - link: { - url: 'https://github.com/immich-app/immich/pull/11613', - text: '#11613', - }, - date: new Date(2024, 7, 7), - }, - { - icon: mdiLockOff, - iconColor: 'red', - title: 'Fetch inside Cloudflare Workers is cursed', - description: - 'Fetch requests in Cloudflare Workers use http by default, even if you explicitly specify https, which can often cause redirect loops.', - link: { - url: 'https://community.cloudflare.com/t/does-cloudflare-worker-allow-secure-https-connection-to-fetch-even-on-flexible-ssl/68051/5', - text: 'Cloudflare', - }, - date: new Date(2024, 7, 7), - }, - { - icon: mdiCrosshairsOff, - iconColor: 'gray', - title: 'GPS sharing on mobile is cursed', - description: - 'Some phones will silently strip GPS data from images when apps without location permission try to access them.', - link: { - url: 'https://github.com/immich-app/immich/discussions/11268', - text: '#11268', - }, - date: new Date(2024, 6, 21), - }, - { - icon: mdiLeadPencil, - iconColor: 'gold', - title: 'PostgreSQL NOTIFY is cursed', - description: - 'PostgreSQL does everything in a transaction, including NOTIFY. This means using the socket.io postgres-adapter writes to WAL every 5 seconds.', - link: { url: 'https://github.com/immich-app/immich/pull/10801', text: '#10801' }, - date: new Date(2024, 6, 3), - }, - { - icon: mdiWeb, - iconColor: 'lightskyblue', - title: 'npm scripts are cursed', - description: - 'npm scripts make a http call to the npm registry each time they run, which means they are a terrible way to execute a health check.', - link: { url: 'https://github.com/immich-app/immich/issues/10796', text: '#10796' }, - date: new Date(2024, 6, 3), - }, - { - icon: mdiSpeedometerSlow, - iconColor: 'brown', - title: '50 extra packages are cursed', - description: - 'There is a user in the JavaScript community who goes around adding "backwards compatibility" to projects. They do this by adding 50 extra package dependencies to your project, which are maintained by them.', - link: { url: 'https://github.com/immich-app/immich/pull/10690', text: '#10690' }, - date: new Date(2024, 5, 28), - }, - { - icon: mdiLockOutline, - iconColor: 'gold', - title: 'Long passwords are cursed', - description: - 'The bcrypt implementation only uses the first 72 bytes of a string. Any characters after that are ignored.', - // link: GHSA-4p64-9f7h-3432 - date: new Date(2024, 5, 25), - }, - { - icon: mdiCalendarToday, - iconColor: 'greenyellow', - title: 'JavaScript Date objects are cursed', - description: 'JavaScript date objects are 1 indexed for years and days, but 0 indexed for months.', - link: { url: 'https://github.com/immich-app/immich/pull/6787', text: '#6787' }, - date: new Date(2024, 0, 31), - }, - { - icon: mdiBug, - iconColor: 'green', - title: 'ESM imports are cursed', - description: - 'Prior to Node.js v20.8 using --experimental-vm-modules in a CommonJS project that imported an ES module that imported a CommonJS modules would create a segfault and crash Node.js', - link: { - url: 'https://github.com/immich-app/immich/pull/6719', - text: '#6179', - }, - date: new Date(2024, 0, 9), - }, - { - icon: mdiDatabase, - iconColor: 'gray', - title: 'PostgreSQL parameters are cursed', - description: `PostgresSQL has a limit of ${Number(65535).toLocaleString()} parameters, so bulk inserts can fail with large datasets.`, - link: { - url: 'https://github.com/immich-app/immich/pull/6034', - text: '#6034', - }, - date: new Date(2023, 11, 28), - }, - { - icon: mdiSecurity, - iconColor: 'gold', - title: 'Secure contexts are cursed', - description: `Some web features like the clipboard API only work in "secure contexts" (ie. https or localhost)`, - link: { - url: 'https://github.com/immich-app/immich/issues/2981', - text: '#2981', - }, - date: new Date(2023, 5, 26), - }, - { - icon: mdiTrashCan, - iconColor: 'gray', - title: 'TypeORM deletes are cursed', - description: `The remove implementation in TypeORM mutates the input, deleting the id property from the original object.`, - link: { - url: 'https://github.com/typeorm/typeorm/issues/7024#issuecomment-948519328', - text: 'typeorm#6034', - }, - date: new Date(2023, 1, 23), - }, -]; - -export default function CursedKnowledgePage(): JSX.Element { - return ( - -
-

- Cursed Knowledge -

-

- Cursed knowledge we have learned as a result of building Immich that we wish we never knew. -

-
- b.date.getTime() - a.date.getTime()) - .map((item) => ({ ...item, getDateLabel: withLanguage(item.date) }))} - /> -
-
-
- ); -} diff --git a/docs/src/pages/index.tsx b/docs/src/pages/index.tsx index 277a1d0b46..37455cde16 100644 --- a/docs/src/pages/index.tsx +++ b/docs/src/pages/index.tsx @@ -1,123 +1,5 @@ -import React from 'react'; -import Link from '@docusaurus/Link'; -import Layout from '@theme/Layout'; -import { discordPath, discordViewBox } from '@site/src/components/svg-paths'; -import ThemedImage from '@theme/ThemedImage'; -import Icon from '@mdi/react'; - -function HomepageHeader() { - return ( -
-
- Immich logo -
-
-
- - - - -
-

- Self-hosted{' '} - - photo and - video management{' '} - - solution -

- -

- Easily back up, organize, and manage your photos on your own server. Immich helps you - browse, search and organize your photos and videos with ease, without - sacrificing your privacy. -

-
-
- - Get Started - - - - Open Demo - -
- -
- - Join our Discord -
- -
-
-
- -
-

Download the mobile app

-

- Download the Immich app and start backing up your photos and videos securely to your own server -

-
-
-
- - Get it on Google Play - -
- -
- - Download on the App Store - -
- -
- - Download APK - -
-
- -
-
- ); -} +import { Redirect } from '@docusaurus/router'; export default function Home(): JSX.Element { - return ( - - -
-

This project is available under GNU AGPL v3 license.

-

Privacy should not be a luxury

-
-
- ); + return ; } diff --git a/docs/src/pages/roadmap.tsx b/docs/src/pages/roadmap.tsx deleted file mode 100644 index e002c4d032..0000000000 --- a/docs/src/pages/roadmap.tsx +++ /dev/null @@ -1,944 +0,0 @@ -import { - mdiAccountGroup, - mdiAccountGroupOutline, - mdiAndroid, - mdiAppleIos, - mdiArchiveOutline, - mdiBash, - mdiBookSearchOutline, - mdiBookmark, - mdiCakeVariant, - mdiCameraBurst, - mdiChartBoxMultipleOutline, - mdiCheckAll, - mdiCheckboxMarked, - mdiCloudUploadOutline, - mdiCollage, - mdiContentDuplicate, - mdiCrop, - mdiDevices, - mdiEmailOutline, - mdiExpansionCard, - mdiEyeOutline, - mdiEyeRefreshOutline, - mdiFaceMan, - mdiFaceManOutline, - mdiFile, - mdiFileSearch, - mdiFlash, - mdiFolder, - mdiFolderMultiple, - mdiForum, - mdiHandshakeOutline, - mdiHeart, - mdiHistory, - mdiImage, - mdiImageAlbum, - mdiImageEdit, - mdiImageMultipleOutline, - mdiImageSearch, - mdiKeyboardSettingsOutline, - mdiLicense, - mdiLockOutline, - mdiMagnify, - mdiMagnifyScan, - mdiMap, - mdiMaterialDesign, - mdiMatrix, - mdiMerge, - mdiMonitor, - mdiMotionPlayOutline, - mdiPalette, - mdiPanVertical, - mdiPartyPopper, - mdiPencil, - mdiRaw, - mdiRocketLaunch, - mdiRotate360, - mdiScaleBalance, - mdiSecurity, - mdiServer, - mdiShare, - mdiShareAll, - mdiShareCircle, - mdiStar, - mdiStarOutline, - mdiTableKey, - mdiTag, - mdiTagMultiple, - mdiText, - mdiThemeLightDark, - mdiTrashCanOutline, - mdiVectorCombine, - mdiFolderSync, - mdiFaceRecognition, - mdiVideo, - mdiWeb, - mdiDatabaseOutline, - mdiLinkEdit, - mdiTagFaces, - mdiMovieOpenPlayOutline, - mdiCast, -} from '@mdi/js'; -import Layout from '@theme/Layout'; -import React from 'react'; -import { Item, Timeline } from '../components/timeline'; - -const releases = { - 'v1.135.0': new Date(2025, 5, 18), - 'v1.133.0': new Date(2025, 4, 21), - 'v1.130.0': new Date(2025, 2, 25), - 'v1.127.0': new Date(2025, 1, 26), - 'v1.122.0': new Date(2024, 11, 5), - 'v1.120.0': new Date(2024, 10, 6), - 'v1.114.0': new Date(2024, 8, 6), - 'v1.113.0': new Date(2024, 7, 30), - 'v1.112.0': new Date(2024, 7, 14), - 'v1.111.0': new Date(2024, 6, 26), - 'v1.110.0': new Date(2024, 5, 11), - 'v1.109.0': new Date(2024, 6, 18), - 'v1.106.1': new Date(2024, 5, 11), - 'v1.104.0': new Date(2024, 4, 13), - 'v1.103.0': new Date(2024, 3, 29), - 'v1.102.0': new Date(2024, 3, 15), - 'v1.99.0': new Date(2024, 2, 20), - 'v1.98.0': new Date(2024, 2, 7), - 'v1.95.0': new Date(2024, 1, 20), - 'v1.94.0': new Date(2024, 0, 31), - 'v1.93.0': new Date(2024, 0, 19), - 'v1.91.0': new Date(2023, 11, 15), - 'v1.90.0': new Date(2023, 11, 7), - 'v1.88.0': new Date(2023, 10, 20), - 'v1.84.0': new Date(2023, 10, 1), - 'v1.83.0': new Date(2023, 9, 28), - 'v1.82.0': new Date(2023, 9, 17), - 'v1.79.0': new Date(2023, 8, 21), - 'v1.76.0': new Date(2023, 7, 29), - 'v1.75.0': new Date(2023, 7, 26), - 'v1.72.0': new Date(2023, 7, 6), - 'v1.71.0': new Date(2023, 6, 29), - 'v1.69.0': new Date(2023, 6, 23), - 'v1.68.0': new Date(2023, 6, 20), - 'v1.67.0': new Date(2023, 6, 14), - 'v1.66.0': new Date(2023, 6, 4), - 'v1.65.0': new Date(2023, 5, 30), - 'v1.63.0': new Date(2023, 5, 24), - 'v1.61.0': new Date(2023, 5, 16), - 'v1.58.0': new Date(2023, 4, 28), - 'v1.57.0': new Date(2023, 4, 23), - 'v1.56.0': new Date(2023, 4, 18), - 'v1.55.0': new Date(2023, 4, 9), - 'v1.54.0': new Date(2023, 3, 18), - 'v1.52.0': new Date(2023, 2, 29), - 'v1.51.0': new Date(2023, 2, 20), - 'v1.48.0': new Date(2023, 1, 21), - 'v1.47.0': new Date(2023, 1, 13), - 'v1.46.0': new Date(2023, 1, 9), - 'v1.43.0': new Date(2023, 1, 3), - 'v1.41.0': new Date(2023, 0, 10), - 'v1.39.0': new Date(2022, 11, 19), - 'v1.36.0': new Date(2022, 10, 20), - 'v1.33.1': new Date(2022, 9, 26), - 'v1.32.0': new Date(2022, 9, 14), - 'v1.27.0': new Date(2022, 8, 6), - 'v1.24.0': new Date(2022, 7, 19), - 'v1.10.0': new Date(2022, 4, 29), - 'v1.7.0': new Date(2022, 3, 24), - 'v1.3.0': new Date(2022, 2, 22), - 'v1.2.0': new Date(2022, 1, 8), -} as const; - -const weirdTags = { - 'v1.41.0': 'v1.41.1_64-dev', - 'v1.39.0': 'v1.39.0_61-dev', - 'v1.36.0': 'v1.36.0_55-dev', - 'v1.33.1': 'v1.33.0_52-dev', - 'v1.32.0': 'v1.32.0_50-dev', - 'v1.27.0': 'v1.27.0_37-dev', - 'v1.24.0': 'v1.24.0_34-dev', - 'v1.10.0': 'v1.10.0_15-dev', - 'v1.7.0': 'v1.7.0_11-dev ', - 'v1.3.0': 'v1.3.0-dev ', - 'v1.2.0': 'v0.2-dev ', -}; - -const title = 'Roadmap'; -const description = 'A list of future plans and goals, as well as past achievements and milestones.'; - -const withLanguage = (date: Date) => (language: string) => date.toLocaleDateString(language); - -type Base = { icon: string; iconColor?: React.CSSProperties['color']; title: string; description: string }; -const withRelease = ({ - icon, - iconColor, - title, - description, - release: version, -}: Base & { release: keyof typeof releases }) => { - return { - icon, - iconColor: iconColor ?? 'gray', - title, - description, - link: { - url: `https://github.com/immich-app/immich/releases/tag/${weirdTags[version] ?? version}`, - text: version, - }, - getDateLabel: withLanguage(releases[version]), - }; -}; - -const roadmap: Item[] = [ - { - done: false, - icon: mdiFlash, - iconColor: 'gold', - title: 'Workflows', - description: 'Automate tasks with workflows', - getDateLabel: () => 'Planned for 2025', - }, - { - done: false, - icon: mdiImageEdit, - iconColor: 'rebeccapurple', - title: 'Basic editor', - description: 'Basic photo editing capabilities', - getDateLabel: () => 'Planned for 2025', - }, - { - done: false, - icon: mdiRocketLaunch, - iconColor: 'indianred', - title: 'Stable release', - description: 'Immich goes stable', - getDateLabel: () => 'Planned for 2025', - }, - { - done: false, - icon: mdiCloudUploadOutline, - iconColor: 'cornflowerblue', - title: 'Better background backups', - description: 'Rework background backups to be more reliable', - getDateLabel: () => 'Planned for 2025', - }, - { - done: false, - icon: mdiCameraBurst, - iconColor: 'rebeccapurple', - title: 'Auto stacking', - description: 'Auto stack burst photos', - getDateLabel: () => 'Planned for 2025', - }, -]; - -const milestones: Item[] = [ - { - icon: mdiStar, - iconColor: 'gold', - title: '70,000 Stars', - description: 'Reached 70K Stars on GitHub!', - getDateLabel: withLanguage(new Date(2025, 6, 9)), - }, - withRelease({ - icon: mdiTableKey, - iconColor: 'gray', - title: 'Fine grained access controls', - description: 'Granular access controls for api keys', - release: 'v1.135.0', - }), - withRelease({ - icon: mdiCast, - iconColor: 'aqua', - title: 'Google Cast (web and mobile)', - description: 'Cast assets to Google Cast/Chromecast compatible devices', - release: 'v1.135.0', - }), - withRelease({ - icon: mdiLockOutline, - iconColor: 'sandybrown', - title: 'Private/locked photos', - description: 'Private assets with extra protections', - release: 'v1.133.0', - }), - withRelease({ - icon: mdiFolderMultiple, - iconColor: 'brown', - title: 'Folders view in the mobile app', - description: 'Browse your photos and videos in their folder structure inside the mobile app', - release: 'v1.130.0', - }), - { - icon: mdiStar, - iconColor: 'gold', - title: '60,000 Stars', - description: 'Reached 60K Stars on GitHub!', - getDateLabel: withLanguage(new Date(2025, 2, 4)), - }, - withRelease({ - icon: mdiTagFaces, - iconColor: 'teal', - title: 'Manual face tagging', - description: - 'Manually tag or remove faces in photos and videos, even when automatic detection misses or misidentifies them.', - release: 'v1.127.0', - }), - withRelease({ - icon: mdiLinkEdit, - iconColor: 'crimson', - title: 'Automatic URL switching', - description: 'The mobile app now supports automatic switching between different server URLs', - release: 'v1.122.0', - }), - withRelease({ - icon: mdiMovieOpenPlayOutline, - iconColor: 'darksalmon', - title: 'Native video player', - description: 'HDR videos are now fully supported using the Immich native video player', - release: 'v1.122.0', - }), - withRelease({ - icon: mdiDatabaseOutline, - iconColor: 'brown', - title: 'Automatic database dumps', - description: 'Database dumps are now integrated into the Immich server', - release: 'v1.120.0', - }), - { - icon: mdiStar, - iconColor: 'gold', - title: '50,000 Stars', - description: 'Reached 50K Stars on GitHub!', - getDateLabel: withLanguage(new Date(2024, 10, 1)), - }, - withRelease({ - icon: mdiFaceRecognition, - title: 'Metadata Face Import', - description: 'Read face metadata in Digikam format during import', - release: 'v1.114.0', - }), - withRelease({ - icon: mdiTagMultiple, - iconColor: 'orange', - title: 'Tags', - description: 'Tag your photos and videos', - release: 'v1.113.0', - }), - withRelease({ - icon: mdiFolderSync, - iconColor: 'green', - title: 'Album sync (mobile)', - description: 'Sync or mirror an album from your phone to the Immich server', - release: 'v1.113.0', - }), - withRelease({ - icon: mdiFolderMultiple, - iconColor: 'brown', - title: 'Folders view', - description: 'Browse your photos and videos in their folder structure', - release: 'v1.113.0', - }), - withRelease({ - icon: mdiPalette, - title: 'Theming (mobile)', - description: 'Pick a primary color for the mobile app', - release: 'v1.112.0', - }), - withRelease({ - icon: mdiStarOutline, - iconColor: 'gold', - title: 'Star rating', - description: 'Rate your photos and videos', - release: 'v1.112.0', - }), - withRelease({ - icon: mdiCrop, - iconColor: 'royalblue', - title: 'Editor (mobile)', - description: 'Crop and rotate on mobile', - release: 'v1.111.0', - }), - withRelease({ - icon: mdiMap, - iconColor: 'green', - title: 'Deploy tiles.immich.cloud', - description: 'Dedicated tile server for Immich', - release: 'v1.111.0', - }), - { - icon: mdiStar, - iconColor: 'gold', - title: '40,000 Stars', - description: 'Reached 40K Stars on GitHub!', - getDateLabel: withLanguage(new Date(2024, 6, 21)), - }, - withRelease({ - icon: mdiShare, - title: 'Deploy my.immich.app', - description: 'Url router for immich links', - release: 'v1.109.0', - }), - withRelease({ - icon: mdiLicense, - iconColor: 'gold', - title: 'Supporter Badge', - description: 'The option to buy Immich to support its development!', - release: 'v1.109.0', - }), - withRelease({ - icon: mdiHistory, - title: 'Versioned documentation', - description: 'View documentation as it was at the time of past releases', - release: 'v1.106.1', - }), - withRelease({ - icon: mdiWeb, - iconColor: 'royalblue', - title: 'Web translations', - description: 'Translate the web application to multiple languages', - release: 'v1.106.1', - }), - withRelease({ - icon: mdiContentDuplicate, - title: 'Similar image detection', - description: "Detect duplicate assets that aren't exactly identical", - release: 'v1.106.1', - }), - withRelease({ - icon: mdiVectorCombine, - title: 'Container consolidation', - description: - 'The microservices container can be run as a worker within the server image, allowing us to remove it from the default stack.', - release: 'v1.106.1', - }), - withRelease({ - icon: mdiPencil, - iconColor: 'saddlebrown', - title: 'Read-write external libraries', - description: 'Edit, update, and delete files in external libraries', - release: 'v1.104.0', - }), - withRelease({ - icon: mdiEmailOutline, - iconColor: 'crimson', - title: 'Email notifications', - description: 'Send emails for important events', - release: 'v1.104.0', - }), - { - icon: mdiHandshakeOutline, - iconColor: 'magenta', - title: 'Immich joins FUTO!', - description: 'Joined Futo and Immich core team goes full-time', - getDateLabel: withLanguage(new Date(2024, 4, 1)), - }, - withRelease({ - icon: mdiEyeOutline, - iconColor: 'darkslategray', - title: 'Read-only albums', - description: 'Share albums with other users as read-only', - release: 'v1.103.0', - }), - withRelease({ - icon: mdiBookmark, - iconColor: 'orangered', - title: 'Permanent URLs (Web)', - description: 'Assets on the web now have permanent URLs', - release: 'v1.103.0', - }), - withRelease({ - icon: mdiStar, - iconColor: 'gold', - title: '30,000 Stars', - description: 'Reached 30K Stars on GitHub!', - release: 'v1.102.0', - }), - withRelease({ - icon: mdiChartBoxMultipleOutline, - iconColor: 'mediumvioletred', - title: 'OpenTelemetry metrics', - description: 'OpenTelemetry metrics for local evaluation and advanced debugging', - release: 'v1.99.0', - }), - withRelease({ - icon: 'immich', - title: 'New logo', - description: 'Immich got its new logo', - release: 'v1.98.0', - }), - withRelease({ - icon: mdiMagnifyScan, - title: 'Search enhancement with advanced filters', - description: 'Advanced search with filters by date, location and more', - release: 'v1.95.0', - }), - withRelease({ - icon: mdiScaleBalance, - iconColor: 'gold', - title: 'AGPL License', - description: 'Immich switches to AGPLv3 license', - release: 'v1.95.0', - }), - withRelease({ - icon: mdiEyeRefreshOutline, - title: 'Library watching', - description: 'Automatically import files in external libraries when the operating system detects changes.', - release: 'v1.94.0', - }), - withRelease({ - icon: mdiExpansionCard, - iconColor: 'green', - title: 'GPU acceleration for machine-learning', - description: 'Hardware acceleration support for Nvidia and Intel devices through CUDA and OpenVINO.', - release: 'v1.94.0', - }), - withRelease({ - icon: mdiAccountGroupOutline, - iconColor: 'gray', - title: '250 unique contributors', - description: '250 amazing people contributed to Immich', - release: 'v1.93.0', - }), - withRelease({ - icon: mdiMatrix, - title: 'Search improvement with pgvecto.rs', - description: 'Moved the search from typesense to pgvecto.rs', - release: 'v1.91.0', - }), - withRelease({ - icon: mdiPencil, - iconColor: 'saddlebrown', - title: 'Edit metadata', - description: "Edit a photo or video's date, time, hours, timezone, and GPS information", - release: 'v1.90.0', - }), - withRelease({ - icon: mdiVectorCombine, - title: 'Container consolidation', - description: - 'The serving of the web app is merged into the server image, allowing us to remove two containers from the stack.', - release: 'v1.88.0', - }), - withRelease({ - icon: mdiBash, - iconColor: 'gray', - title: 'CLI v2', - description: 'Version 2 of the Immich CLI is released, replacing the legacy v1 CLI.', - release: 'v1.88.0', - }), - withRelease({ - icon: mdiForum, - iconColor: 'dodgerblue', - title: 'Activity', - description: 'Comment a photo or a video in a shared album', - release: 'v1.84.0', - }), - withRelease({ - icon: mdiStar, - iconColor: 'gold', - title: '20,000 Stars', - description: 'Reached 20K Stars on GitHub!', - release: 'v1.83.0', - }), - withRelease({ - icon: mdiCameraBurst, - iconColor: 'rebeccapurple', - title: 'Stack assets', - description: 'Manual asset stacking for grouping and hiding related assets in the main timeline.', - release: 'v1.83.0', - }), - withRelease({ - icon: mdiPalette, - iconColor: 'magenta', - title: 'Custom theme', - description: 'Apply your custom CSS for modifying fonts, colors, and styles in the web application.', - release: 'v1.83.0', - }), - withRelease({ - icon: mdiTrashCanOutline, - iconColor: 'brown', - title: 'Trash feature', - description: 'Trash, restore from trash, and automatically empty the recycle bin after 30 days.', - release: 'v1.82.0', - }), - withRelease({ - icon: mdiBookSearchOutline, - title: 'External libraries', - description: 'Automatically import media into Immich based on imports paths and ignore patterns.', - release: 'v1.79.0', - }), - withRelease({ - icon: mdiMap, - iconColor: 'darksalmon', - title: 'Map view (mobile)', - description: 'Heat map implementation in the mobile app.', - release: 'v1.76.0', - }), - withRelease({ - icon: mdiFile, - iconColor: 'lightblue', - title: 'Configuration file', - description: 'Auto-configure an Immich installation via a configuration file.', - release: 'v1.75.0', - }), - withRelease({ - icon: mdiMonitor, - iconColor: 'darkcyan', - title: 'Slideshow mode (web)', - description: 'Start a full-screen slideshow from an Album on the web.', - release: 'v1.75.0', - }), - withRelease({ - icon: mdiServer, - iconColor: 'lightskyblue', - title: 'Hardware transcoding', - description: 'Support hardware acceleration (QuickSync, VAAPI, and Nvidia) for video transcoding.', - release: 'v1.72.0', - }), - withRelease({ - icon: mdiImageAlbum, - iconColor: 'olivedrab', - title: 'View albums via time buckets', - description: 'Upgrade albums to use time buckets, an optimized virtual viewport.', - release: 'v1.72.0', - }), - withRelease({ - icon: mdiImageAlbum, - iconColor: 'olivedrab', - title: 'Album description', - description: 'Save an album description.', - release: 'v1.72.0', - }), - withRelease({ - icon: mdiRotate360, - title: '360° Photos (web)', - description: 'View 360° Photos on the web.', - release: 'v1.71.0', - }), - withRelease({ - icon: mdiMotionPlayOutline, - title: 'Android motion photos', - description: 'Add support for Android Motion Photos.', - release: 'v1.69.0', - }), - withRelease({ - icon: mdiFaceManOutline, - iconColor: 'mistyrose', - title: 'Show/hide faces', - description: 'Add the options to show or hide faces.', - release: 'v1.68.0', - }), - withRelease({ - icon: mdiMerge, - iconColor: 'forestgreen', - title: 'Merge faces', - description: 'Add the ability to merge multiple faces together.', - release: 'v1.67.0', - }), - withRelease({ - icon: mdiImage, - iconColor: 'rebeccapurple', - title: 'Feature photo', - description: 'Add the option to change the feature photo for a person.', - release: 'v1.66.0', - }), - withRelease({ - icon: mdiKeyboardSettingsOutline, - iconColor: 'darkslategray', - title: 'Multi-select via SHIFT', - description: 'Add the option to multi-select while holding SHIFT.', - release: 'v1.66.0', - }), - withRelease({ - icon: mdiImageMultipleOutline, - iconColor: 'rebeccapurple', - title: 'Memories (mobile)', - description: 'View "On this day..." memories in the mobile app.', - release: 'v1.65.0', - }), - withRelease({ - icon: mdiFaceMan, - iconColor: 'mistyrose', - title: 'Facial recognition (mobile)', - description: 'View detected faces in the mobile app.', - release: 'v1.63.0', - }), - withRelease({ - icon: mdiImageMultipleOutline, - iconColor: 'rebeccapurple', - title: 'Memories (web)', - description: 'View pictures taken in past years on this day on the web.', - release: 'v1.61.0', - }), - withRelease({ - icon: mdiCollage, - iconColor: 'deeppink', - title: 'Justified layout (web)', - description: 'Implement justified layout (collage) on the web.', - release: 'v1.61.0', - }), - withRelease({ - icon: mdiRaw, - title: 'RAW file formats', - description: 'Support for RAW file formats.', - release: 'v1.61.0', - }), - withRelease({ - icon: mdiShareAll, - iconColor: 'darkturquoise', - title: 'Partner sharing (mobile)', - description: 'View shared partner photos in the mobile app.', - release: 'v1.58.0', - }), - withRelease({ - icon: mdiFile, - iconColor: 'lightblue', - title: 'XMP sidecar', - description: 'Attach XMP sidecar files to assets.', - release: 'v1.58.0', - }), - withRelease({ - icon: mdiFolder, - iconColor: 'brown', - title: 'Custom storage label', - description: 'Replace the user UUID in the storage template with a custom label.', - release: 'v1.57.0', - }), - withRelease({ - icon: mdiShareCircle, - title: 'Partner sharing', - description: 'Share your entire collection with another user.', - release: 'v1.56.0', - }), - withRelease({ - icon: mdiFaceMan, - iconColor: 'mistyrose', - title: 'Facial recognition', - description: 'Detect faces in pictures and cluster them together as people, which can be named.', - release: 'v1.56.0', - }), - withRelease({ - icon: mdiMap, - iconColor: 'darksalmon', - title: 'Map view (web)', - description: 'View a global map, with clusters of photos based on corresponding GPS data.', - release: 'v1.55.0', - }), - withRelease({ - icon: mdiDevices, - iconColor: 'slategray', - title: 'Manage auth devices', - description: 'Manage logged-in devices and revoke access from User Settings.', - release: 'v1.55.0', - }), - withRelease({ - icon: mdiStar, - iconColor: 'gold', - title: '10,000 Stars', - description: 'Reached 10K stars on GitHub!', - release: 'v1.54.0', - }), - withRelease({ - icon: mdiText, - title: 'Asset descriptions', - description: 'Save an asset description', - release: 'v1.54.0', - }), - withRelease({ - icon: mdiArchiveOutline, - title: 'Archiving', - description: 'Remove assets from the main timeline by archiving them.', - release: 'v1.54.0', - }), - withRelease({ - icon: mdiDevices, - iconColor: 'slategray', - title: 'Responsive web app', - description: 'Optimize the web app for small screen.', - release: 'v1.54.0', - }), - withRelease({ - icon: mdiFileSearch, - iconColor: 'brown', - title: 'Search by metadata', - description: 'Search images by filename, description, tagged people, make, model, and other metadata.', - release: 'v1.52.0', - }), - withRelease({ - icon: mdiImageSearch, - iconColor: 'rebeccapurple', - title: 'CLIP search', - description: 'Search images with free-form text like "Sunset at the beach".', - release: 'v1.51.0', - }), - withRelease({ - icon: mdiMagnify, - iconColor: 'lightblue', - title: 'Explore page', - description: 'View tagged places, object, and people.', - release: 'v1.51.0', - }), - withRelease({ - icon: mdiAppleIos, - title: 'iOS background uploads', - description: 'Automatically backup pictures in the background on iOS.', - release: 'v1.48.0', - }), - withRelease({ - icon: mdiMotionPlayOutline, - title: 'Auto-Link live photos', - description: 'Automatically link live photos, even when uploaded as separate files.', - release: 'v1.48.0', - }), - withRelease({ - icon: mdiMaterialDesign, - iconColor: 'blue', - title: 'Material design 3 (mobile)', - description: 'Upgrade the mobile app to Material Design 3.', - release: 'v1.47.0', - }), - withRelease({ - icon: mdiHeart, - iconColor: 'red', - title: 'Favorites (mobile)', - description: 'Show favorites on the mobile app.', - release: 'v1.46.0', - }), - withRelease({ - icon: mdiCakeVariant, - iconColor: 'deeppink', - title: 'Immich turns 1', - description: 'Immich is officially one year old.', - release: 'v1.43.0', - }), - withRelease({ - icon: mdiHeart, - iconColor: 'red', - title: 'Favorites page (web)', - description: 'Favorite and view favorites on the web.', - release: 'v1.43.0', - }), - withRelease({ - icon: mdiShareCircle, - title: 'Public share links', - description: 'Share photos and albums publicly via a shared link.', - release: 'v1.41.0', - }), - withRelease({ - icon: mdiFolder, - iconColor: 'lightblue', - title: 'User-defined storage structure', - description: 'Support custom storage structures.', - release: 'v1.39.0', - }), - withRelease({ - icon: mdiMotionPlayOutline, - title: 'iOS live photos', - description: 'Backup and display iOS Live Photos.', - release: 'v1.36.0', - }), - withRelease({ - icon: mdiSecurity, - iconColor: 'green', - title: 'OAuth integration', - description: 'Support OAuth2 and OIDC capable identity providers.', - release: 'v1.36.0', - }), - withRelease({ - icon: mdiWeb, - iconColor: 'royalblue', - title: 'Documentation site', - description: 'Release an official documentation website.', - release: 'v1.33.1', - }), - withRelease({ - icon: mdiThemeLightDark, - iconColor: 'slategray', - title: 'Dark mode (web)', - description: 'Dark mode on the web.', - release: 'v1.32.0', - }), - withRelease({ - icon: mdiPanVertical, - title: 'Virtual scrollbar (web)', - description: 'View the main timeline with a virtual scrollbar, allowing to jump to any point in time, instantly.', - release: 'v1.27.0', - }), - withRelease({ - icon: mdiCheckAll, - iconColor: 'green', - title: 'Checksum duplication check', - description: 'Enforce per user sha1 checksum uniqueness.', - release: 'v1.27.0', - }), - withRelease({ - icon: mdiAndroid, - iconColor: 'greenyellow', - title: 'Android background backup', - description: 'Automatic backup in the background on Android.', - release: 'v1.24.0', - }), - withRelease({ - icon: mdiAccountGroup, - iconColor: 'gray', - title: 'Admin portal', - description: 'Manage users and admin settings from the web.', - release: 'v1.10.0', - }), - withRelease({ - icon: mdiShareCircle, - title: 'Album sharing', - description: 'Share albums with other users.', - release: 'v1.7.0', - }), - withRelease({ - icon: mdiTag, - iconColor: 'coral', - title: 'Image tagging', - description: 'Tag images with custom values.', - release: 'v1.7.0', - }), - withRelease({ - icon: mdiImage, - iconColor: 'rebeccapurple', - title: 'View exif', - description: 'View metadata about assets.', - release: 'v1.3.0', - }), - withRelease({ - icon: mdiCheckboxMarked, - iconColor: 'green', - title: 'Multi select', - description: 'Select and execute actions on multiple assets at the same time.', - release: 'v1.2.0', - }), - withRelease({ - icon: mdiVideo, - iconColor: 'slategray', - title: 'Video player', - description: 'Play videos in the web and on mobile.', - release: 'v1.2.0', - }), - { - icon: mdiPartyPopper, - iconColor: 'deeppink', - title: 'First commit', - description: 'First commit on GitHub, Immich is born.', - getDateLabel: withLanguage(new Date(2022, 1, 3)), - }, -]; - -export default function MilestonePage(): JSX.Element { - return ( - -
-

- {title} -

-

{description}

-
- -
-
-
- ); -} diff --git a/docs/static/.well-known/security.txt b/docs/static/.well-known/security.txt deleted file mode 100644 index 5a8414c3e2..0000000000 --- a/docs/static/.well-known/security.txt +++ /dev/null @@ -1,5 +0,0 @@ -Policy: https://github.com/immich-app/immich/blob/main/SECURITY.md -Contact: mailto:security@immich.app -Preferred-Languages: en -Expires: 2026-05-01T23:59:00.000Z -Canonical: https://immich.app/.well-known/security.txt diff --git a/docs/static/_redirects b/docs/static/_redirects index 7b01d1e3bb..ecbdf19303 100644 --- a/docs/static/_redirects +++ b/docs/static/_redirects @@ -1,34 +1,34 @@ -/docs /docs/overview/welcome 307 -/docs/ /docs/overview/welcome 307 -/docs/mobile-app-beta-program /docs/features/mobile-app 307 -/docs/contribution-guidelines /docs/overview/support-the-project#contributing 307 -/docs/install /docs/install/docker-compose 307 -/docs/installation/one-step-installation /docs/install/script 307 -/docs/installation/portainer-installation /docs/install/portainer 307 -/docs/installation/recommended-installation /docs/install/docker-compose 307 -/docs/installation/unraid /docs/install/unraid 307 -/docs/installation/requirements /docs/install/requirements 307 -/docs/overview/logo-meaning /docs/overview/logo 307 -/docs/overview/technology-stack /docs/developer/architecture 307 -/docs/usage/automatic-backup /docs/features/automatic-backup 307 -/docs/usage/bulk-upload /docs/features/command-line-interface 307 -/docs/features/bulk-upload /docs/features/command-line-interface 307 -/docs/usage/oauth /docs/administration/oauth 307 -/docs/usage/post-installation /docs/install/post-install 307 -/docs/usage/update /docs/install/docker-compose#step-4---upgrading 307 -/docs/usage/server-commands /docs/administration/server-commands 307 -/docs/features/jobs /docs/administration/jobs 307 -/docs/features/oauth /docs/administration/oauth 307 -/docs/features/password-login /docs/administration/password-login 307 -/docs/features/server-commands /docs/administration/server-commands 307 -/docs/features/storage-template /docs/administration/storage-template 307 -/docs/features/user-management /docs/administration/user-management 307 -/docs/developer/contributing /docs/developer/pr-checklist 307 -/docs/guides/machine-learning /docs/guides/remote-machine-learning 307 -/docs/administration/password-login /docs/administration/system-settings 307 -/docs/features/search /docs/features/searching 307 -/docs/features/smart-search /docs/features/searching 307 -/docs/guides/api-album-sync /docs/community-projects 307 -/docs/guides/remove-offline-files /docs/community-projects 307 -/milestones /roadmap 307 -/docs/overview/introduction /docs/overview/welcome 307 +/ /overview/quick-start 307 +/mobile-app-beta-program /features/mobile-app 307 +/contribution-guidelines /overview/support-the-project#contributing 307 +/install /install/docker-compose 307 +/installation/one-step-installation /install/script 307 +/installation/portainer-installation /install/portainer 307 +/installation/recommended-installation /install/docker-compose 307 +/installation/unraid /install/unraid 307 +/installation/requirements /install/requirements 307 +/overview/logo-meaning /overview/logo 307 +/overview/technology-stack /developer/architecture 307 +/usage/automatic-backup /features/automatic-backup 307 +/usage/bulk-upload /features/command-line-interface 307 +/features/bulk-upload /features/command-line-interface 307 +/usage/oauth /administration/oauth 307 +/usage/post-installation /install/post-install 307 +/usage/update /install/docker-compose#step-4---upgrading 307 +/usage/server-commands /administration/server-commands 307 +/features/jobs /administration/jobs 307 +/features/oauth /administration/oauth 307 +/features/password-login /administration/password-login 307 +/features/server-commands /administration/server-commands 307 +/features/storage-template /administration/storage-template 307 +/features/user-management /administration/user-management 307 +/developer/contributing /developer/pr-checklist 307 +/guides/machine-learning /guides/remote-machine-learning 307 +/administration/password-login /administration/system-settings 307 +/features/search /features/searching 307 +/features/smart-search /features/searching 307 +/guides/api-album-sync /community-projects 307 +/guides/remove-offline-files /community-projects 307 +/overview/introduction /overview/quick-start 307 +/overview/welcome /overview/quick-start 307 +/docs/* /:splat 307 diff --git a/docs/static/archived-versions.json b/docs/static/archived-versions.json index 8edce0be2d..cd3d8e079a 100644 --- a/docs/static/archived-versions.json +++ b/docs/static/archived-versions.json @@ -1,226 +1,229 @@ [ { - "label": "v1.142.1", - "url": "https://v1.142.1.archive.immich.app" + "label": "v1.144.1", + "url": "https://docs.v1.144.1.archive.immich.app" }, { - "label": "v1.142.0", - "url": "https://v1.142.0.archive.immich.app" + "label": "v1.144.0", + "url": "https://docs.v1.144.0.archive.immich.app" + }, + { + "label": "v1.143.1", + "url": "https://docs.v1.143.1.archive.immich.app" + }, + { + "label": "v1.142.1", + "url": "https://v1.142.1.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.141.1", - "url": "https://v1.141.1.archive.immich.app" - }, - { - "label": "v1.141.0", - "url": "https://v1.141.0.archive.immich.app" + "url": "https://v1.141.1.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.140.1", - "url": "https://v1.140.1.archive.immich.app" - }, - { - "label": "v1.140.0", - "url": "https://v1.140.0.archive.immich.app" + "url": "https://v1.140.1.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.139.4", - "url": "https://v1.139.4.archive.immich.app" - }, - { - "label": "v1.139.3", - "url": "https://v1.139.3.archive.immich.app" - }, - { - "label": "v1.139.2", - "url": "https://v1.139.2.archive.immich.app" + "url": "https://v1.139.4.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.138.1", - "url": "https://v1.138.1.archive.immich.app" - }, - { - "label": "v1.138.0", - "url": "https://v1.138.0.archive.immich.app" + "url": "https://v1.138.1.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.137.3", - "url": "https://v1.137.3.archive.immich.app" - }, - { - "label": "v1.137.2", - "url": "https://v1.137.2.archive.immich.app" - }, - { - "label": "v1.137.1", - "url": "https://v1.137.1.archive.immich.app" - }, - { - "label": "v1.137.0", - "url": "https://v1.137.0.archive.immich.app" + "url": "https://v1.137.3.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.136.0", - "url": "https://v1.136.0.archive.immich.app" + "url": "https://v1.136.0.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.135.3", - "url": "https://v1.135.3.archive.immich.app" - }, - { - "label": "v1.135.2", - "url": "https://v1.135.2.archive.immich.app" - }, - { - "label": "v1.135.1", - "url": "https://v1.135.1.archive.immich.app" - }, - { - "label": "v1.135.0", - "url": "https://v1.135.0.archive.immich.app" + "url": "https://v1.135.3.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.134.0", - "url": "https://v1.134.0.archive.immich.app" + "url": "https://v1.134.0.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.133.1", - "url": "https://v1.133.1.archive.immich.app" - }, - { - "label": "v1.133.0", - "url": "https://v1.133.0.archive.immich.app" + "url": "https://v1.133.1.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.132.3", - "url": "https://v1.132.3.archive.immich.app" + "url": "https://v1.132.3.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.131.3", - "url": "https://v1.131.3.archive.immich.app" + "url": "https://v1.131.3.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.130.3", - "url": "https://v1.130.3.archive.immich.app" + "url": "https://v1.130.3.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.129.0", - "url": "https://v1.129.0.archive.immich.app" + "url": "https://v1.129.0.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.128.0", - "url": "https://v1.128.0.archive.immich.app" + "url": "https://v1.128.0.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.127.0", - "url": "https://v1.127.0.archive.immich.app" + "url": "https://v1.127.0.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.126.1", - "url": "https://v1.126.1.archive.immich.app" + "url": "https://v1.126.1.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.125.7", - "url": "https://v1.125.7.archive.immich.app" + "url": "https://v1.125.7.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.124.2", - "url": "https://v1.124.2.archive.immich.app" + "url": "https://v1.124.2.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.123.0", - "url": "https://v1.123.0.archive.immich.app" + "url": "https://v1.123.0.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.122.3", - "url": "https://v1.122.3.archive.immich.app" + "url": "https://v1.122.3.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.121.0", - "url": "https://v1.121.0.archive.immich.app" + "url": "https://v1.121.0.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.120.2", - "url": "https://v1.120.2.archive.immich.app" + "url": "https://v1.120.2.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.119.1", - "url": "https://v1.119.1.archive.immich.app" + "url": "https://v1.119.1.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.118.2", - "url": "https://v1.118.2.archive.immich.app" + "url": "https://v1.118.2.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.117.0", - "url": "https://v1.117.0.archive.immich.app" + "url": "https://v1.117.0.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.116.2", - "url": "https://v1.116.2.archive.immich.app" + "url": "https://v1.116.2.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.115.0", - "url": "https://v1.115.0.archive.immich.app" + "url": "https://v1.115.0.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.114.0", - "url": "https://v1.114.0.archive.immich.app" + "url": "https://v1.114.0.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.113.1", - "url": "https://v1.113.1.archive.immich.app" + "url": "https://v1.113.1.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.112.1", - "url": "https://v1.112.1.archive.immich.app" + "url": "https://v1.112.1.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.111.0", - "url": "https://v1.111.0.archive.immich.app" + "url": "https://v1.111.0.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.110.0", - "url": "https://v1.110.0.archive.immich.app" + "url": "https://v1.110.0.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.109.2", - "url": "https://v1.109.2.archive.immich.app" + "url": "https://v1.109.2.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.108.0", - "url": "https://v1.108.0.archive.immich.app" + "url": "https://v1.108.0.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.107.2", - "url": "https://v1.107.2.archive.immich.app" + "url": "https://v1.107.2.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.106.4", - "url": "https://v1.106.4.archive.immich.app" + "url": "https://v1.106.4.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.105.1", - "url": "https://v1.105.1.archive.immich.app" + "url": "https://v1.105.1.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.104.0", - "url": "https://v1.104.0.archive.immich.app" + "url": "https://v1.104.0.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.103.1", - "url": "https://v1.103.1.archive.immich.app" + "url": "https://v1.103.1.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.102.3", - "url": "https://v1.102.3.archive.immich.app" + "url": "https://v1.102.3.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.101.0", - "url": "https://v1.101.0.archive.immich.app" + "url": "https://v1.101.0.archive.immich.app", + "rootPath": "/docs" }, { "label": "v1.100.0", - "url": "https://v1.100.0.archive.immich.app" + "url": "https://v1.100.0.archive.immich.app", + "rootPath": "/docs" } ] diff --git a/e2e/package.json b/e2e/package.json index 737f488a50..38b9ac949a 100644 --- a/e2e/package.json +++ b/e2e/package.json @@ -1,6 +1,6 @@ { "name": "immich-e2e", - "version": "1.142.1", + "version": "1.144.1", "description": "", "main": "index.js", "type": "module", diff --git a/i18n/af.json b/i18n/af.json index b3729903ec..fce944504b 100644 --- a/i18n/af.json +++ b/i18n/af.json @@ -14,6 +14,7 @@ "add_a_location": "Voeg 'n ligging by", "add_a_name": "Voeg 'n naam by", "add_a_title": "Voeg 'n titel by", + "add_birthday": "Voeg 'n verjaarsdag by", "add_endpoint": "Voeg Koppelvlakpunt by", "add_exclusion_pattern": "Voeg uitsgluitingspatrone by", "add_import_path": "Voeg invoerpad by", @@ -27,6 +28,8 @@ "add_to_album": "Voeg na album", "add_to_album_bottom_sheet_added": "By {album} bygevoeg", "add_to_album_bottom_sheet_already_exists": "Reeds in {album}", + "add_to_albums": "Voeg by albums", + "add_to_albums_count": "Voeg by ({count}) albums", "add_to_shared_album": "Voeg toe aan gedeelde album", "add_url": "Voeg URL by", "added_to_archive": "By argief toegevoegd", @@ -44,6 +47,11 @@ "backup_database": "Skep Datastortlêer", "backup_database_enable_description": "Aktiveer databasisrugsteun", "backup_keep_last_amount": "Aantal vorige rugsteune om te hou", + "backup_onboarding_3_description": "totale kopieë van jou data, insluitende die oorspronklikke lêers. Dit sluit in 1 kopie op 'n ander perseel en 2 kopieë om die huidige rekenaar.", + "backup_onboarding_description": "'N 3-2-1 rugsteun strategie word sterk aanbeveel om jou data veilig te hou. Hou kopieë van jou fotos/videos so wel as die Immich databasis vir 'n volledige rugsteun oplossing.", + "backup_onboarding_footer": "Vir meer inligting oor hoe om 'n rugsteun kopie van Immich te maak, gaan lees asseblief hierdie dokument.", + "backup_onboarding_parts_title": "'N 3-2-1 rugsteun sluit in:", + "backup_onboarding_title": "Rugsteun kopieë", "backup_settings": "Rugsteun instellings", "backup_settings_description": "Bestuur databasis rugsteun instellings.", "cleared_jobs": "Poste gevee vir: {job}", @@ -62,8 +70,8 @@ "duplicate_detection_job_description": "Begin masjienleer op bates om soortgelyke beelde op te spoor. Maak staat op Smart Search", "exclusion_pattern_description": "Met uitsluitingspatrone kan jy lêers en vouers ignoreer wanneer jy jou biblioteek skandeer. Dit is nuttig as jy vouers het wat lêers bevat wat jy nie wil invoer nie, soos RAW-lêers.", "external_library_management": "Eksterne Biblioteekbestuur", - "face_detection": "Gesig deteksie", - "face_detection_description": "Detecteer die gesigte in media deur middel van masjienleer. Vir videos word slegs die duimnaelskets oorweeg. “Herlaai” (ver)werk al die media weer. “Stel terug” verwyder boonop alle huidige gesigdata. “Onverwerk” plaas bates in die tou wat nog nie verwerk is nie. Gedekte gesigte sal ná voltooiing van Gesigdetectie vir Gesigherkenning in die tou geplaas word, om hulle in bestaande of nuwe persone te groepeer.", + "face_detection": "Gesig herkenning", + "face_detection_description": "Identifiseer die gesigte in media deur middel van masjienleer. Vir videos word slegs die duimnaelskets oorweeg. “Herlaai” (ver)werk al die media weer. “Stel terug” verwyder alle huidige gesigdata. “Onverwerk” plaas bates in die tou wat nog nie verwerk is nie. Geidentifiseerde gesigte sal ná voltooiing van Gesigidentifikasie vir Gesigherkenning in die tou geplaas word, om hulle in bestaande of nuwe persone te groepeer.", "facial_recognition_job_description": "Groepeer gesigte in mense in. Die stap is vinniger nadat Gesig Deteksie klaar is. \"Herstel\" (her-)groepeer alle gesigte. \"Vermiste\" plaas gesigte in ry wat nie 'n persoon gekoppel het nie.", "failed_job_command": "Opdrag {command} het misluk vir werk: {job}", "force_delete_user_warning": "WAARSKUWING: Dit sal onmiddellik die gebruiker en alle bates verwyder. Dit kan nie ontdoen word nie en die lêers kan nie herstel word nie.", @@ -93,15 +101,33 @@ "job_status": "Werkstatus", "library_created": "Biblioteek geskep: {library}", "library_deleted": "Biblioteek verwyder", - "library_import_path_description": "Spesifiseer 'n leer om in te neem. Hierdie leer, en al die sub leers, gaan geskandeer for vir prente en videos.", - "library_scanning": "Periodieke Skandering", - "library_scanning_description": "Stel periodieke skandering van biblioteek in", + "library_import_path_description": "Spesifiseer 'n leer om in te neem. Hierdie leer, en al die sub leers, gaan deursoek word vir prente en videos.", + "library_scanning": "Periodieke Soek", + "library_scanning_description": "Stel periodieke deursoek van biblioteek in", "library_scanning_enable_description": "Aktiveer periodieke biblioteekskandering", "library_settings": "Eksterne Biblioteek", + "library_settings_description": "Eksterne biblioteek verstellings", + "library_tasks_description": "Deursoek eksterne biblioteke vir nuwe of veranderde bates", + "library_watching_enable_description": "Hou eksterne biblioteke dop vir leer veranderinge", + "library_watching_settings": "Biblioteek dop hou (EKSPERIMENTEEL)", + "library_watching_settings_description": "Hou automaties dop vir veranderinge", + "logging_enable_description": "Aktifeer \"logging\"", + "logging_level_description": "Wanneer aktief, watter vlak van \"logs\" om te skep.", + "logging_settings": "\"Logs\"", + "machine_learning_clip_model": "CLIP model", + "machine_learning_duplicate_detection": "Duplikaat herkenning", + "machine_learning_duplicate_detection_enabled": "Aktifeer duplikaat herkenning", + "machine_learning_enabled": "Aktifeer masjienleer", + "machine_learning_facial_recognition": "Gesigsherkenning", + "machine_learning_facial_recognition_description": "Herken, identifiseer en groepeer gesigte in fotos", + "machine_learning_facial_recognition_model": "Gesigsherkennings model", + "machine_learning_facial_recognition_setting": "Aktifeer gesigsherkenning", + "machine_learning_max_detection_distance": "Maksimum herkennings afstand", "map_settings": "Kaart", "migration_job": "Migrasie", "oauth_settings": "OAuth", - "transcoding_acceleration_vaapi": "VAAPI" + "transcoding_acceleration_vaapi": "VAAPI", + "transcoding_preferred_hardware_device": "Verkiesde hardeware" }, "administration": "Administrasie", "advanced": "Gevorderde", diff --git a/i18n/ar.json b/i18n/ar.json index 8a436deba5..5d43f61777 100644 --- a/i18n/ar.json +++ b/i18n/ar.json @@ -123,6 +123,13 @@ "logging_enable_description": "تفعيل تسجيل الأحداث", "logging_level_description": "عند التفعيل، أي مستوى تسجيل سيستخدم.", "logging_settings": "تسجيل الاحداث", + "machine_learning_availability_checks": "تحقق من التوفر", + "machine_learning_availability_checks_description": "تحديد خوادم التعلم الآلي المتاحة تلقائيًا وإعطاءها الأولوية", + "machine_learning_availability_checks_enabled": "تفعيل عمليات فحص التوفر", + "machine_learning_availability_checks_interval": "فترة التحقق", + "machine_learning_availability_checks_interval_description": "الفترة الزمنية بالمللي ثانية بين عمليات فحص التوفر", + "machine_learning_availability_checks_timeout": "انتهت مدة انتظار الطلب", + "machine_learning_availability_checks_timeout_description": "مدة انتظار (بالمللي ثانية) لاختبارات توفر الخدمة", "machine_learning_clip_model": "نموذج CLIP", "machine_learning_clip_model_description": "اسم نموذج CLIP مدرجٌ هنا. يرجى ملاحظة أنه يجب إعادة تشغيل وظيفة \"البحث الذكي\" لجميع الصور بعد تغيير النموذج.", "machine_learning_duplicate_detection": "كشف التكرار", @@ -387,8 +394,6 @@ "admin_password": "كلمة سر المشرف", "administration": "الإدارة", "advanced": "متقدم", - "advanced_settings_beta_timeline_subtitle": "جرب تجربة التطبيق الجديدة", - "advanced_settings_beta_timeline_title": "الجدول الزمني التجريبي", "advanced_settings_enable_alternate_media_filter_subtitle": "استخدم هذا الخيار لتصفية الوسائط اثناء المزامنه بناء على معايير بديلة. جرب هذا الخيار فقط كان لديك مشاكل مع التطبيق بالكشف عن جميع الالبومات.", "advanced_settings_enable_alternate_media_filter_title": "[تجريبي] استخدم جهاز تصفية مزامنه البومات بديل", "advanced_settings_log_level_title": "مستوى السجل: {level}", @@ -396,6 +401,7 @@ "advanced_settings_prefer_remote_title": "تفضل الصور البعيدة", "advanced_settings_proxy_headers_subtitle": "عرف عناوين الوكيل التي يستخدمها Immich لارسال كل طلب شبكي", "advanced_settings_proxy_headers_title": "عناوين الوكيل", + "advanced_settings_readonly_mode_subtitle": "تتيح هذه الميزة وضع العرض فقط، حيث يمكن للمستخدم معاينة الصور فقط، بينما يتم تعطيل جميع الخيارات الأخرى مثل تحديد عدة صور، أو مشاركتها، أو بثها، أو حذفها. يمكن تفعيل/تعطيل وضع العرض فقط من خلال صورة المستخدم في الشاشة الرئيسية", "advanced_settings_readonly_mode_title": "وضع القراءة فقط", "advanced_settings_self_signed_ssl_subtitle": "تخطي التحقق من شهادة SSL لخادم النقطة النهائي. مكلوب للشهادات الموقعة ذاتيا.", "advanced_settings_self_signed_ssl_title": "السماح بشهادات SSL الموقعة ذاتيًا", @@ -424,6 +430,7 @@ "album_remove_user_confirmation": "هل أنت متأكد أنك تريد إزالة {user}؟", "album_search_not_found": "لم يتم ايجاد البوم مطابق لبحثك", "album_share_no_users": "يبدو أنك قمت بمشاركة هذا الألبوم مع جميع المستخدمين أو ليس لديك أي مستخدم للمشاركة معه.", + "album_summary": "ملخص الألبوم", "album_updated": "تم تحديث الألبوم", "album_updated_setting_description": "تلقي إشعارًا عبر البريد الإلكتروني عندما يحتوي الألبوم المشترك على محتويات جديدة", "album_user_left": "تم ترك {album}", @@ -462,6 +469,7 @@ "app_bar_signout_dialog_title": "خروج", "app_settings": "إعدادات التطبيق", "appears_in": "يظهر في", + "apply_count": "تطبيق ({count, number})", "archive": "الأرشيف", "archive_action_prompt": "{count} اضيف إلى الارشيف", "archive_or_unarchive_photo": "أرشفة الصورة أو إلغاء أرشفتها", @@ -494,6 +502,8 @@ "asset_restored_successfully": "تم استعادة الاصل بنجاح", "asset_skipped": "تم تخطيه", "asset_skipped_in_trash": "في سلة المهملات", + "asset_trashed": "اصول محذوفة", + "asset_troubleshoot": "استكشاف مشاكل الأصول", "asset_uploaded": "تم الرفع", "asset_uploading": "جارٍ الرفع…", "asset_viewer_settings_subtitle": "إدارة إعدادات عارض المعرض الخاص بك", @@ -501,7 +511,9 @@ "assets": "المحتويات", "assets_added_count": "تمت إضافة {count, plural, one {# محتوى} other {# محتويات}}", "assets_added_to_album_count": "تمت إضافة {count, plural, one {# الأصل} other {# الأصول}} إلى الألبوم", + "assets_added_to_albums_count": "تمت اضافة {assetTotal, plural, one {# اصل} other {# اصول}} to {albumTotal, plural, one {# البوم} other {# البومات}}", "assets_cannot_be_added_to_album_count": "{count, plural, one {Asset} other {Assets}} لايمكن اضافته الى الالبوم", + "assets_cannot_be_added_to_albums": "{count, plural, one {اصل} other {اصول}} لا يمكن إضافته إلى أي من الألبومات", "assets_count": "{count, plural, one {# محتوى} other {# محتويات}}", "assets_deleted_permanently": "{count} الاص(و)ل المحذوف(ه) بشكل دائم", "assets_deleted_permanently_from_server": "{count} الاص(و)ل المحذوف(ه) بشكل دائمي من خادم Immich", @@ -518,14 +530,17 @@ "assets_trashed_count": "تم إرسال {count, plural, one {# محتوى} other {# محتويات}} إلى سلة المهملات", "assets_trashed_from_server": "{count} الاص(و)ل المنقولة الى سلة المهملات من خادم Immich", "assets_were_part_of_album_count": "{count, plural, one {هذا المحتوى} other {هذه المحتويات}} في الألبوم بالفعل", + "assets_were_part_of_albums_count": "{count, plural, one {اصل هو} other {اصول هي}}بالفعل جزء من الألبومات", "authorized_devices": "الأجهزه المخولة", "automatic_endpoint_switching_subtitle": "اتصل محليا من خلال شبكه Wi-Fi عند توفرها و استخدم اتصالات بديله في الاماكن الاخرى", "automatic_endpoint_switching_title": "تبديل URL تلقائي", "autoplay_slideshow": "تشغيل تلقائي لعرض الشرائح", "back": "خلف", "back_close_deselect": "الرجوع أو الإغلاق أو إلغاء التحديد", + "background_backup_running_error": "يتم تشغيل النسخ الاحتياطي في الخلفية حاليًا، ولا يمكن بدء النسخ الاحتياطي اليدوي", "background_location_permission": "اذن الوصول للموقع في الخلفية", "background_location_permission_content": "للتمكن من تبديل الشبكه بالخلفية، Immich يحتاج*دائما* للحصول على موقع دقيق ليتمكن التطبيق من قرائة اسم شبكة الWi-Fi", + "background_options": "خيارات الخلفية", "backup": "نسخ احتياطي", "backup_album_selection_page_albums_device": "الالبومات على الجهاز ({count})", "backup_album_selection_page_albums_tap": "انقر للتضمين، وانقر نقرًا مزدوجًا للاستثناء", @@ -533,6 +548,7 @@ "backup_album_selection_page_select_albums": "حدد الألبومات", "backup_album_selection_page_selection_info": "معلومات الاختيار", "backup_album_selection_page_total_assets": "إجمالي الأصول الفريدة", + "backup_albums_sync": "مزامنة ألبومات النسخ الاحتياطي", "backup_all": "الجميع", "backup_background_service_backup_failed_message": "فشل في النسخ الاحتياطي للأصول. جارٍ إعادة المحاولة…", "backup_background_service_connection_failed_message": "فشل في الاتصال بالخادم. جارٍ إعادة المحاولة…", @@ -649,6 +665,8 @@ "change_pin_code": "تغيير رمز PIN", "change_your_password": "غير كلمة المرور الخاصة بك", "changed_visibility_successfully": "تم تغيير الرؤية بنجاح", + "charging": "الشحن", + "charging_requirement_mobile_backup": "يتطلب النسخ الاحتياطي في الخلفية أن يكون الجهاز قيد الشحن", "check_corrupt_asset_backup": "التحقق من وجود نسخ احتياطية فاسدة للاصول", "check_corrupt_asset_backup_button": "اجراء فحص", "check_corrupt_asset_backup_description": "قم بإجراء هذا الفحص فقط عبر شبكة Wi-Fi وبعد نسخ جميع الأصول احتياطيًا. قد يستغرق الإجراء بضع دقائق.", @@ -735,6 +753,7 @@ "create_user": "إنشاء مستخدم", "created": "تم الإنشاء", "created_at": "مخلوق", + "creating_linked_albums": "جاري إنشاء الألبومات المرتبطة...", "crop": "قص", "curated_object_page_title": "أشياء", "current_device": "الجهاز الحالي", @@ -884,7 +903,9 @@ "error": "خطأ", "error_change_sort_album": "فشل في تغيير ترتيب الألبوم", "error_delete_face": "حدث خطأ في حذف الوجه من الأصول", + "error_getting_places": "خطأ أثناء استرجاع بيانات المواقع", "error_loading_image": "حدث خطأ أثناء تحميل الصورة", + "error_loading_partners": "خطأ بتحميل بيانات الشركاء: {error}", "error_saving_image": "خطأ: {error}", "error_tag_face_bounding_box": "خطأ في وضع علامة على الوجه - لا يمكن الحصول على إحداثيات المربع المحيط", "error_title": "خطأ - حدث خللٌ ما", @@ -1049,6 +1070,7 @@ "favorites_page_no_favorites": "لم يتم العثور على الأصول المفضلة", "feature_photo_updated": "تم تحديث الصورة المميزة", "features": "الميزات", + "features_in_development": "الميزات قيد التطوير", "features_setting_description": "إدارة ميزات التطبيق", "file_name": "إسم الملف", "file_name_or_extension": "اسم الملف أو امتداده", @@ -1069,12 +1091,15 @@ "gcast_enabled": "كوكل كاست", "gcast_enabled_description": "تقوم هذه الميزة بتحميل الموارد الخارجية من Google حتى تعمل.", "general": "عام", + "geolocation_instruction_location": "انقر على الاصل الذي يحتوي على إحداثيات نظام تحديد المواقع لاستخدام موقعه، أو اختر الموقع مباشرة من الخريطة", "get_help": "الحصول على المساعدة", "get_wifiname_error": "تعذر الحصول على اسم شبكة Wi-Fi. تأكد من منح الأذونات اللازمة واتصالك بشبكة Wi-Fi", "getting_started": "البدء", "go_back": "الرجوع للخلف", "go_to_folder": "اذهب إلى المجلد", "go_to_search": "اذهب إلى البحث", + "gps": "نظام تحديد المواقع", + "gps_missing": "لا يوجد نظام تحديد المواقع", "grant_permission": "منح الاذن", "group_albums_by": "تجميع الألبومات حسب...", "group_country": "مجموعة البلد", @@ -1210,6 +1235,7 @@ "local": "محلّي", "local_asset_cast_failed": "غير قادر على بث أصل لم يتم تحميله إلى الخادم", "local_assets": "أُصول (ملفات) محلية", + "local_media_summary": "ملخص الملفات المحلية", "local_network": "شبكة محلية", "local_network_sheet_info": "سيتصل التطبيق بالخادم من خلال عنوان URL هذا عند استخدام شبكة Wi-Fi المحددة", "location_permission": "اذن الموقع", @@ -1221,6 +1247,7 @@ "location_picker_longitude_hint": "أدخل خط الطول هنا", "lock": "قفل", "locked_folder": "مجلد مقفول", + "log_detail_title": "تفاصيل السجل", "log_out": "تسجيل خروج", "log_out_all_devices": "تسجيل الخروج من كافة الأجهزة", "logged_in_as": "تم تسجيل الدخول باسم {user}", @@ -1251,6 +1278,7 @@ "login_password_changed_success": "تم تحديث كلمة السر بنجاح", "logout_all_device_confirmation": "هل أنت متأكد أنك تريد تسجيل الخروج من جميع الأجهزة؟", "logout_this_device_confirmation": "هل أنت متأكد أنك تريد تسجيل الخروج من هذا الجهاز؟", + "logs": "السجلات", "longitude": "خط الطول", "look": "الشكل", "loop_videos": "تكرار مقاطع الفيديو", @@ -1258,6 +1286,7 @@ "main_branch_warning": "أنت تستخدم إصداراً قيد التطوير؛ ونحن نوصي بشدة باستخدام إصدار النشر!", "main_menu": "القائمة الرئيسية", "make": "صنع", + "manage_geolocation": "إدارة الموقع", "manage_shared_links": "إدارة الروابط المشتركة", "manage_sharing_with_partners": "إدارة المشاركة مع الشركاء", "manage_the_app_settings": "إدارة إعدادات التطبيق", @@ -1292,6 +1321,7 @@ "mark_as_read": "تحديد كمقروء", "marked_all_as_read": "تم تحديد الكل كمقروء", "matches": "تطابقات", + "matching_assets": "‏الاصول المطابقة", "media_type": "نوع الوسائط", "memories": "الذكريات", "memories_all_caught_up": "كل شيء محدث", @@ -1332,6 +1362,7 @@ "name_or_nickname": "الاسم أو اللقب", "network_requirement_photos_upload": "استخدام بيانات الهاتف المحمول لعمل نسخة احتياطية للصور", "network_requirement_videos_upload": "استخدام بيانات الهاتف المحمول لعمل نسخة احتياطية لمقاطع الفيديو", + "network_requirements": "متطلبات الشبكة", "network_requirements_updated": "تم تغيير متطلبات الشبكة، يتم إعادة تعيين قائمة انتظار النسخ الاحتياطي", "networking_settings": "الشبكات", "networking_subtitle": "إدارة إعدادات نقطة الخادم النهائية", @@ -1342,6 +1373,7 @@ "new_person": "شخص جديد", "new_pin_code": "رمز PIN الجديد", "new_pin_code_subtitle": "هذه أول مرة تدخل فيها إلى المجلد المقفل. أنشئ رمزًا PIN للوصول بامان إلى هذه الصفحة", + "new_timeline": "الخط الزمني الجديد", "new_user_created": "تم إنشاء مستخدم جديد", "new_version_available": "إصدار جديد متاح", "newest_first": "الأحدث أولاً", @@ -1355,20 +1387,25 @@ "no_assets_message": "انقر لتحميل صورتك الأولى", "no_assets_to_show": "لا توجد أصول لعرضها", "no_cast_devices_found": "لم يتم ايجاد جهاز بث", + "no_checksum_local": "لا توجد بيانات تحقق متاحة - يتعذر تحميل الاصول المحلية", + "no_checksum_remote": "لا يوجد رمز تحقق متاح - يتعذر تحميل الاصل من الموقع البعيد", "no_duplicates_found": "لم يتم العثور على أي تكرارات.", "no_exif_info_available": "لا تتوفر معلومات exif", "no_explore_results_message": "قم برفع المزيد من الصور لاستكشاف مجموعتك.", "no_favorites_message": "أضف المفضلة للعثور بسرعة على أفضل الصور ومقاطع الفيديو", "no_libraries_message": "إنشاء مكتبة خارجية لعرض الصور ومقاطع الفيديو الخاصة بك", + "no_local_assets_found": "لم يتم العثور على أي اصول محلية تتطابق مع قيمة التحقق هذه", "no_locked_photos_message": "الصور والفديوهات في المجلد المقفل مخفية ولن تصهر في التصفح او البحث في مكتبتك.", "no_name": "لا اسم", "no_notifications": "لا توجد تنبيهات", "no_people_found": "لم يتم العثور على اشخاص مطابقين", "no_places": "لا أماكن", + "no_remote_assets_found": "لم يتم العثور على أي اصول بعيدة تتطابق مع رمز التحقق هذل", "no_results": "لا يوجد نتائج", "no_results_description": "جرب كلمة رئيسية مرادفة أو أكثر عمومية", "no_shared_albums_message": "قم بإنشاء ألبوم لمشاركة الصور ومقاطع الفيديو مع الأشخاص في شبكتك", "no_uploads_in_progress": "لا يوجد اي ملفات قيد الرفع", + "not_available": "غير متاح", "not_in_any_album": "ليست في أي ألبوم", "not_selected": "لم يختار", "note_apply_storage_label_to_previously_uploaded assets": "ملاحظة: لتطبيق سمة التخزين على المحتويات التي تم رفعها مسبقًا، قم بتشغيل", @@ -1403,6 +1440,8 @@ "open_the_search_filters": "افتح مرشحات البحث", "options": "خيارات", "or": "أو", + "organize_into_albums": "ترتيب في ألبومات", + "organize_into_albums_description": "أضف الصور الموجودة إلى الألبومات باستخدام إعدادات النسخ المتزامن الحالية", "organize_your_library": "تنظيم مكتبتك", "original": "أصلي", "other": "أخرى", @@ -1488,6 +1527,7 @@ "port": "المنفذ", "preferences_settings_subtitle": "ادارة تفضيلات التطبيق", "preferences_settings_title": "التفضيلات", + "preparing": "قيد التحضير", "preset": "الإعداد المسبق", "preview": "معاينة", "previous": "السابق", @@ -1504,6 +1544,7 @@ "profile_drawer_client_out_of_date_minor": "تطبيق الهاتف المحمول قديم.يرجى التحديث إلى أحدث إصدار صغير.", "profile_drawer_client_server_up_to_date": "العميل والخادم محدثان", "profile_drawer_github": "Github", + "profile_drawer_readonly_mode": "تم تفعيل وضع القراءة فقط. اضغط مطولا على رمز صورة المستخدم للخروج.", "profile_drawer_server_out_of_date_major": "الخادم قديم.يرجى التحديث إلى أحدث إصدار رئيسي.", "profile_drawer_server_out_of_date_minor": "الخادم قديم.يرجى التحديث إلى أحدث إصدار صغير.", "profile_image_of_user": "صورة الملف الشخصي لـ {user}", @@ -1542,6 +1583,7 @@ "purchase_server_description_2": "حالة الداعم", "purchase_server_title": "الخادم", "purchase_settings_server_activated": "يتم إدارة مفتاح منتج الخادم من قبل مدير النظام", + "query_asset_id": "استعلام عن معرف الأصل", "queue_status": "يتم الاضافة الى قائمة انتظار النسخ الاحتياطي {count}/{total}", "rating": "تقييم نجمي", "rating_clear": "مسح التقييم", @@ -1549,6 +1591,9 @@ "rating_description": "‫‌اعرض تقييم EXIF في لوحة المعلومات", "reaction_options": "خيارات رد الفعل", "read_changelog": "قراءة سجل التغيير", + "readonly_mode_disabled": "تم تعطيل وضع القراءة فقط", + "readonly_mode_enabled": "تم تفعيل وضع القراءة فقط", + "ready_for_upload": "جاهز للرفع", "reassign": "إعادة التعيين", "reassigned_assets_to_existing_person": "تمت إعادة تعيين {count, plural, one {# الأصل} other {# الاصول}} إلى {name, select, null {شخص موجود } other {{name}}}", "reassigned_assets_to_new_person": "تمت إعادة تعيين {count, plural, one {# المحتوى} other {# المحتويات}} إلى شخص جديد", @@ -1573,6 +1618,7 @@ "regenerating_thumbnails": "جارٍ تجديد الصور المصغرة", "remote": "بعيد", "remote_assets": "الأُصول البعيدة", + "remote_media_summary": "ملخص الملفات البعيدة", "remove": "إزالة", "remove_assets_album_confirmation": "هل أنت متأكد أنك تريد إزالة {count, plural, one {# المحتوى} other {# المحتويات}} من الألبوم ؟", "remove_assets_shared_link_confirmation": "هل أنت متأكد أنك تريد إزالة {count, plural, one {# المحتوى} other {# المحتويات}} من رابط المشاركة هذا؟", @@ -1625,6 +1671,7 @@ "restore_user": "استعادة المستخدم", "restored_asset": "المحتويات المستعادة", "resume": "استئناف", + "resume_paused_jobs": "استكمال {count, plural, one {# وظيفة معلقة} other {# وظائف معلقة}}", "retry_upload": "أعد محاولة الرفع", "review_duplicates": "مراجعة التكرارات", "review_large_files": "مراجعة الملفات الكبيرة", @@ -1718,6 +1765,7 @@ "select_user_for_sharing_page_err_album": "فشل في إنشاء ألبوم", "selected": "التحديد", "selected_count": "{count, plural, other {# محددة }}", + "selected_gps_coordinates": "إحداثيات نظام تحديد المواقع المختارة", "send_message": "‏إرسال رسالة", "send_welcome_email": "إرسال بريدًا إلكترونيًا ترحيبيًا", "server_endpoint": "نقطة نهاية الخادم", @@ -1846,6 +1894,7 @@ "show_slideshow_transition": "إظهار انتقال عرض الشرائح", "show_supporter_badge": "شارة المؤيد", "show_supporter_badge_description": "إظهار شارة المؤيد", + "show_text_search_menu": "عرض قائمة خيارات البحث في النص", "shuffle": "خلط", "sidebar": "الشريط الجانبي", "sidebar_display_description": "عرض رابط للعرض في الشريط الجانبي", @@ -1876,6 +1925,7 @@ "stacktrace": "تتّبُع التكديس", "start": "ابدأ", "start_date": "تاريخ البدء", + "start_date_before_end_date": "يجب أن يكون تاريخ بدء الفترة قبل تاريخ نهايتها", "state": "الولاية", "status": "الحالة", "stop_casting": "ايقاف البث", @@ -1900,6 +1950,8 @@ "sync_albums_manual_subtitle": "مزامنة جميع الفديوهات والصور المرفوعة الى البومات الخزن الاحتياطي المختارة", "sync_local": "مزامنة الملفات المحلية", "sync_remote": "مزامنة الملفات البعيدة", + "sync_status": "حالة النسخ المتزامن", + "sync_status_subtitle": "عرض وإدارة نظام النسخ المتزامن", "sync_upload_album_setting_subtitle": "انشئ و ارفع صورك و فديوهاتك الالبومات المختارة في Immich", "tag": "العلامة", "tag_assets": "أصول العلامة", @@ -1937,7 +1989,9 @@ "to_change_password": "تغيير كلمة المرور", "to_favorite": "تفضيل", "to_login": "تسجيل الدخول", + "to_multi_select": "للتحديد المتعدد", "to_parent": "انتقل إلى الوالد", + "to_select": "للتحديد", "to_trash": "حذف", "toggle_settings": "الإعدادات", "total": "الإجمالي", @@ -1957,6 +2011,7 @@ "trash_page_select_assets_btn": "اختر الأصول", "trash_page_title": "سلة المهملات ({count})", "trashed_items_will_be_permanently_deleted_after": "سيتم حذفُ العناصر المحذوفة نِهائيًا بعد {days, plural, one {# يوم} other {# أيام }}.", + "troubleshoot": "استكشاف المشاكل", "type": "النوع", "unable_to_change_pin_code": "تفيير رمز PIN غير ممكن", "unable_to_setup_pin_code": "انشاء رمز PIN غير ممكن", @@ -1987,6 +2042,7 @@ "unstacked_assets_count": "تم إخراج {count, plural, one {# الأصل} other {# الأصول}} من التكديس", "untagged": "غير مُعَلَّم", "up_next": "التالي", + "update_location_action_prompt": "تحديث موقع {count} عناصر محددة على النحو التالي:", "updated_at": "تم التحديث", "updated_password": "تم تحديث كلمة المرور", "upload": "رفع", @@ -2053,6 +2109,7 @@ "view_next_asset": "عرض المحتوى التالي", "view_previous_asset": "عرض المحتوى السابق", "view_qr_code": "­عرض رمز الاستجابة السريعة", + "view_similar_photos": "عرض صور مشابهة", "view_stack": "عرض التكديس", "view_user": "عرض المستخدم", "viewer_remove_from_stack": "حذف من الكومه أو المجموعة", @@ -2071,5 +2128,6 @@ "yes": "نعم", "you_dont_have_any_shared_links": "ليس لديك أي روابط مشتركة", "your_wifi_name": "اسم شبكة Wi-Fi الخاص بك", - "zoom_image": "تكبير الصورة" + "zoom_image": "تكبير الصورة", + "zoom_to_bounds": "تكبير حتى حدود المنطقة" } diff --git a/i18n/az.json b/i18n/az.json index 0449289735..d0e97ca356 100644 --- a/i18n/az.json +++ b/i18n/az.json @@ -2,7 +2,7 @@ "about": "Haqqında", "account": "Hesab", "account_settings": "Hesab parametrləri", - "acknowledge": "Təsdiq et", + "acknowledge": "Aydındır", "action": "Əməliyyat", "action_common_update": "Yenilə", "actions": "Əməliyyatlar", @@ -48,8 +48,15 @@ "backup_database": "Verilənlər bazasının dump-ını yaradın", "backup_database_enable_description": "Verilənlər bazasının artıq nüsxələrini aktiv et", "backup_keep_last_amount": "Tutulması gərəkən nüsxələrin sayı", - "backup_settings": "Ehtiyat Nüsxə Parametrləri", + "backup_onboarding_1_description": "buludda və ya başqa fiziki yerdə saytdan kənar surət.", + "backup_onboarding_2_description": "müxtəlif cihazlarda yerli nüsxələr. Bura əsas fayllar və həmin faylların ehtiyat lokal nüsxəsi daxildir.", + "backup_onboarding_3_description": "orijinal fayllar da daxil olmaqla məlumatlarınızın ümumi surətləri. Buraya 1 kənar nüsxə və 2 lokal nüsxə daxildir.", + "backup_onboarding_footer": "Immich-in ehtiyat nüsxəsini çıxarmaq haqqında ətraflı məlumat üçün sənədlərə müraciət edin.", + "backup_onboarding_parts_title": "3-2-1 ehtiyat nüsxəsinə aşağıdakılar daxildir:", + "backup_onboarding_title": "Ehtiyat surətlər", + "backup_settings": "Bazanın Dump Parametrləri", "backup_settings_description": "Verilənlər bazasının ehtiyat nüsxə parametrlərini idarə et", + "cleared_jobs": "{job} üçün tapşırıqlar silindi", "config_set_by_file": "Konfiqurasiya hal-hazırda konfiqurasiya faylı ilə təyin olunub", "confirm_delete_library": "{library} kitabxanasını silmək istədiyinizdən əminmisiniz?", "confirm_email_below": "Təsdiqləmək üçün aşağıya {email} yazın", diff --git a/i18n/be.json b/i18n/be.json index f98609b84b..7298e904c1 100644 --- a/i18n/be.json +++ b/i18n/be.json @@ -28,6 +28,8 @@ "add_to_album": "Дадаць у альбом", "add_to_album_bottom_sheet_added": "Дададзена да {album}", "add_to_album_bottom_sheet_already_exists": "Ужо знаходзіцца ў {album}", + "add_to_album_bottom_sheet_some_local_assets": "Некаторыя лакальныя актывы не могуць быць дададзены ў альбом", + "add_to_album_toggle": "Пераключыць выбар для {album}", "add_to_albums": "Дадаць у альбомы", "add_to_albums_count": "Дадаць у альбомы ({count})", "add_to_shared_album": "Дадаць у агульны альбом", diff --git a/i18n/bg.json b/i18n/bg.json index 8d9727e492..e78b139d7b 100644 --- a/i18n/bg.json +++ b/i18n/bg.json @@ -123,6 +123,13 @@ "logging_enable_description": "Включване на запис (логове)", "logging_level_description": "Когато е включено, какво ниво на записване да се използва.", "logging_settings": "Записване", + "machine_learning_availability_checks": "Проверки за наличност", + "machine_learning_availability_checks_description": "Автоматично откриване и предпочитане на налични сървъри за машинно обучение", + "machine_learning_availability_checks_enabled": "Активиране на проверки за наличност", + "machine_learning_availability_checks_interval": "Интервал на проверяване", + "machine_learning_availability_checks_interval_description": "Време в милисекунди между проверките за наличност", + "machine_learning_availability_checks_timeout": "Време за изчакване на отговор", + "machine_learning_availability_checks_timeout_description": "Време за изчакване на отговор в милисекунди при проверка на наличност", "machine_learning_clip_model": "CLIP модел", "machine_learning_clip_model_description": "Името на CLIP модела, посочен тук. Имайте предвид, че при промяна на модела трябва да стартирате отново задачата \"Интелигентно Търсене\" за всички изображения.", "machine_learning_duplicate_detection": "Откриване на дубликати", @@ -387,8 +394,6 @@ "admin_password": "Администраторска парола", "administration": "Администрация", "advanced": "Разширено", - "advanced_settings_beta_timeline_subtitle": "Опитайте новите функции на приложението", - "advanced_settings_beta_timeline_title": "Бета версия на времевата линия", "advanced_settings_enable_alternate_media_filter_subtitle": "При синхронизация, използвайте тази опция като филтър, основан на промяна на даден критерии. Опитайте само в случай, че приложението има проблем с откриване на всички албуми.", "advanced_settings_enable_alternate_media_filter_title": "[ЕКСПЕРИМЕНТАЛНО] Използвай филтъра на алтернативното устройство за синхронизация на албуми", "advanced_settings_log_level_title": "Ниво на запис в дневника: {level}", @@ -404,7 +409,7 @@ "advanced_settings_sync_remote_deletions_title": "Синхронизация на дистанционни изтривания [ЕКСПЕРИМЕНТАЛНО]", "advanced_settings_tile_subtitle": "Разширени потребителски настройки", "advanced_settings_troubleshooting_subtitle": "Разреши допълнителни възможности за отстраняване на проблеми", - "advanced_settings_troubleshooting_title": "Отстраняване на проблеми", + "advanced_settings_troubleshooting_title": "Отстраняванe на проблеми", "age_months": "Възраст {months, plural, one {# месец} other {# месеци}}", "age_year_months": "Възраст 1 година, {months, plural, one {# месец} other {# месеци}}", "age_years": "{years, plural, other {Година #}}", @@ -425,6 +430,7 @@ "album_remove_user_confirmation": "Сигурни ли сте, че искате да премахнете {user}?", "album_search_not_found": "Няма намерени албуми, отговарящи на търсенето ви", "album_share_no_users": "Изглежда, че сте споделили този албум с всички потребители или нямате друг потребител, с когото да го споделите.", + "album_summary": "Обобщение на албума", "album_updated": "Албумът е актуализиран", "album_updated_setting_description": "Получавайте известие по имейл, когато споделен албум има нови файлове", "album_user_left": "Напусна {album}", @@ -496,6 +502,8 @@ "asset_restored_successfully": "Успешно възстановен обект", "asset_skipped": "Пропуснато", "asset_skipped_in_trash": "В кошчето", + "asset_trashed": "Обектът е изхвърлен", + "asset_troubleshoot": "Поправка на грешки с обекта", "asset_uploaded": "Качено", "asset_uploading": "Качване…", "asset_viewer_settings_subtitle": "Управление на настройките за изглед", @@ -529,8 +537,10 @@ "autoplay_slideshow": "Автоматична смяна на слайдовете", "back": "Назад", "back_close_deselect": "Назад, затваряне или премахване на избора", + "background_backup_running_error": "Стартирано е фоново архивиране, не може да се пусне ръчно архивиране", "background_location_permission": "Разрешение за достъп до местоположението във фонов режим", "background_location_permission_content": "За да може да чете имената на Wi-Fi мрежите и да ги превключва при работа във фонов режим, Immich трябва *винаги* да има достъп до точното местоположение", + "background_options": "Опции за фоновите задачи", "backup": "Архивиране", "backup_album_selection_page_albums_device": "Албуми на устройството ({count})", "backup_album_selection_page_albums_tap": "Натисни за да включиш, двойно за да изключиш", @@ -538,6 +548,7 @@ "backup_album_selection_page_select_albums": "Избор на албуми", "backup_album_selection_page_selection_info": "Информация за избраното", "backup_album_selection_page_total_assets": "Уникални обекти общо", + "backup_albums_sync": "Синхронизиране на архивите", "backup_all": "Всичко", "backup_background_service_backup_failed_message": "Неуспешно архивиране. Нов опит…", "backup_background_service_connection_failed_message": "Неуспешно свързване към сървъра. Нов опит…", @@ -587,7 +598,7 @@ "backup_controller_page_turn_on": "Включи архивиране в активен режим", "backup_controller_page_uploading_file_info": "Инфо за архивирания файл", "backup_err_only_album": "Не може да се премахне единствения албум", - "backup_info_card_assets": "обекти", + "backup_info_card_assets": "обекта", "backup_manual_cancelled": "Отменено", "backup_manual_in_progress": "Върви архивиране. Опитай след малко", "backup_manual_success": "Успешно", @@ -654,6 +665,8 @@ "change_pin_code": "Смени PIN кода", "change_your_password": "Променете паролата си", "changed_visibility_successfully": "Видимостта е променена успешно", + "charging": "При зареждане", + "charging_requirement_mobile_backup": "Фоново архивиране само при зареждане на устройството", "check_corrupt_asset_backup": "Провери за повредени архивни копия", "check_corrupt_asset_backup_button": "Провери", "check_corrupt_asset_backup_description": "Изпълни тази проверка само при Wi-Fi и след архивиране на всички обекти. Процедурата може да продължи няколко минути.", @@ -740,6 +753,7 @@ "create_user": "Създай потребител", "created": "Създадено", "created_at": "Създаден", + "creating_linked_albums": "Създаване на свързани албуми...", "crop": "Изрежи", "curated_object_page_title": "Неща", "current_device": "Текущо устройство", @@ -889,7 +903,9 @@ "error": "Грешка", "error_change_sort_album": "Неуспешна промяна на реда на сортиране на албум", "error_delete_face": "Грешка при изтриване на лице от актива", + "error_getting_places": "Грешка при събиране на местата", "error_loading_image": "Грешка при зареждане на изображението", + "error_loading_partners": "Грешка при зареждане на партньори: {error}", "error_saving_image": "Грешка: {error}", "error_tag_face_bounding_box": "Грешка при отбелязване на лице - неуспешно получаване на координати на рамката", "error_title": "Грешка - нещо се обърка", @@ -1054,6 +1070,7 @@ "favorites_page_no_favorites": "Не са намерени любими обекти", "feature_photo_updated": "Представителната снимка е променена", "features": "Функции", + "features_in_development": "Функции в процес на разработка", "features_setting_description": "Управление на функциите на приложението", "file_name": "Име на файла", "file_name_or_extension": "Име на файл или разширение", @@ -1218,6 +1235,7 @@ "local": "Локално", "local_asset_cast_failed": "Не може да се предава обект, който още не е качен на сървъра", "local_assets": "Локални обекти", + "local_media_summary": "Обобщение на локалните медийни файлове", "local_network": "Локална мрежа", "local_network_sheet_info": "Приложението ще се свърже със сървъра на този URL, когато устройството е свързано към зададената Wi-Fi мрежа", "location_permission": "Разрешение за местоположение", @@ -1229,6 +1247,7 @@ "location_picker_longitude_hint": "Въведете географска дължина тук", "lock": "Заключи", "locked_folder": "Заключена папка", + "log_detail_title": "Подробности от дневника", "log_out": "Излизане", "log_out_all_devices": "Излизане с всички устройства", "logged_in_as": "Вписан като {user}", @@ -1259,6 +1278,7 @@ "login_password_changed_success": "Успешно обновена парола", "logout_all_device_confirmation": "Сигурни ли сте, че искате да излезете от всички устройства?", "logout_this_device_confirmation": "Сигурни ли сте, че искате да излезете от това устройство?", + "logs": "Дневник", "longitude": "Дължина", "look": "Изглед", "loop_videos": "Повтаряне на видеата", @@ -1301,6 +1321,7 @@ "mark_as_read": "Маркирай като четено", "marked_all_as_read": "Всички маркирани като прочетени", "matches": "Съвпадения", + "matching_assets": "Съвпадащи обекти", "media_type": "Вид медия", "memories": "Спомени", "memories_all_caught_up": "Това е всичко за днес", @@ -1341,6 +1362,7 @@ "name_or_nickname": "Име или прякор", "network_requirement_photos_upload": "Използвай мобилни данни за архивиране на снимки", "network_requirement_videos_upload": "Използвай мобилни данни за архивиране на видео", + "network_requirements": "Изисквания към мрежата", "network_requirements_updated": "Мрежовите настройки са променени, нулиране на опашката за архивиране", "networking_settings": "Мрежа", "networking_subtitle": "Управление на настройките за връзка със сървъра", @@ -1351,6 +1373,7 @@ "new_person": "Нов човек", "new_pin_code": "Нов PIN код", "new_pin_code_subtitle": "Това е първи достъп до заключена папка. Създайте PIN код за защитен достъп до тази страница", + "new_timeline": "Нова времева линия", "new_user_created": "Създаден нов потребител", "new_version_available": "НАЛИЧНА НОВА ВЕРСИЯ", "newest_first": "Най-новите първи", @@ -1364,20 +1387,25 @@ "no_assets_message": "КЛИКНЕТЕ, ЗА ДА КАЧИТЕ ПЪРВАТА СИ СНИМКА", "no_assets_to_show": "Няма обекти за показване", "no_cast_devices_found": "Няма намерени устройства за предаване", + "no_checksum_local": "Липсват контролни суми - не може да се получат локални обекти", + "no_checksum_remote": "Липсват контролни суми - не може да се получат обекти от сървъра", "no_duplicates_found": "Не бяха открити дубликати.", "no_exif_info_available": "Няма exif информация", "no_explore_results_message": "Качете още снимки, за да разгледате колекцията си.", "no_favorites_message": "Добавете в любими, за да намирате бързо най-добрите си снимки и видеоклипове", "no_libraries_message": "Създайте външна библиотека за да разглеждате снимки и видеоклипове", + "no_local_assets_found": "Не е намерен локален обект с такава контролна сума", "no_locked_photos_message": "Снимките и видеата в заключената папка са скрити и не се показват при разглеждане на библиотеката.", "no_name": "Без име", "no_notifications": "Няма известия", "no_people_found": "Не са намерени съответстващи хора", "no_places": "Няма места", + "no_remote_assets_found": "Не е намерен обект на сървъра с такава контролна сума", "no_results": "Няма резултати", "no_results_description": "Опитайте със синоним или по-обща ключова дума", "no_shared_albums_message": "Създайте албум, за да споделяте снимки и видеоклипове с хората в мрежата си", "no_uploads_in_progress": "Няма качване в момента", + "not_available": "Неналично", "not_in_any_album": "Не е в никой албум", "not_selected": "Не е избрано", "note_apply_storage_label_to_previously_uploaded assets": "Забележка: За да приложите етикета за съхранение към предварително качени активи, стартирайте", @@ -1499,6 +1527,7 @@ "port": "Порт", "preferences_settings_subtitle": "Управление на предпочитанията на приложението", "preferences_settings_title": "Предпочитания", + "preparing": "Подготовка", "preset": "Шаблон", "preview": "Прегледи", "previous": "Предишно", @@ -1511,13 +1540,13 @@ "privacy": "Поверителност", "profile": "Профил", "profile_drawer_app_logs": "Дневник", - "profile_drawer_client_out_of_date_major": "Мобилното приложение е остаряло. Моля, актуализирай до най-новата основна версия.", - "profile_drawer_client_out_of_date_minor": "Мобилното приложение е остаряло. Моля, актуализирай до най-новата версия.", + "profile_drawer_client_out_of_date_major": "Мобилното приложение е остаряло. Моля, актуализирайте до най-новата основна версия.", + "profile_drawer_client_out_of_date_minor": "Мобилното приложение е остаряло. Моля, актуализирайте до най-новата версия.", "profile_drawer_client_server_up_to_date": "Клиента и сървъра са обновени", "profile_drawer_github": "GitHub", - "profile_drawer_readonly_mode": "Режима само за четене е активиран. С двоен клик върху картиката-аватар на потребителя ще деактивирате само за четене.", - "profile_drawer_server_out_of_date_major": "Версията на сървъра е остаряла. Моля, актуализирай поне до последната главна версия.", - "profile_drawer_server_out_of_date_minor": "Версията на сървъра е остаряла. Моля, актуализирай до последната версия.", + "profile_drawer_readonly_mode": "Режима само за четене е активиран. С дълго натискане върху картиката-аватар на потребителя ще деактивирате само за четене.", + "profile_drawer_server_out_of_date_major": "Версията на сървъра е остаряла. Моля, актуализирайте поне до последната главна версия.", + "profile_drawer_server_out_of_date_minor": "Версията на сървъра е остаряла. Моля, актуализирайте до последната версия.", "profile_image_of_user": "Профилна снимка на {user}", "profile_picture_set": "Профилната снимка е сложена.", "public_album": "Публичен албум", @@ -1564,6 +1593,7 @@ "read_changelog": "Прочети промените", "readonly_mode_disabled": "Режима само за четене е деактивиран", "readonly_mode_enabled": "Режима само за четене е активиран", + "ready_for_upload": "Готово за качване", "reassign": "Преназначаване", "reassigned_assets_to_existing_person": "Преназначени {count, plural, one {# елемент} other {# елемента}} на {name, select, null {съществуващ човек} other {{name}}}", "reassigned_assets_to_new_person": "Преназначени {count, plural, one {# елемент} other {# елемента}} на нов човек", @@ -1588,6 +1618,7 @@ "regenerating_thumbnails": "Пресъздаване на миниатюрите", "remote": "На сървъра", "remote_assets": "Обекти на сървъра", + "remote_media_summary": "Обобщение на медийните файлове на сървъра", "remove": "Премахни", "remove_assets_album_confirmation": "Сигурни ли сте, че искате да премахнете {count, plural, one {# елемент} other {# елемента}} от албума?", "remove_assets_shared_link_confirmation": "Сигурни ли сте, че искате да премахнете {count, plural, one {# елемент} other {# елемента}} от този споеделен линк?", @@ -1640,6 +1671,7 @@ "restore_user": "Възстанови потребител", "restored_asset": "Възстановен елемент", "resume": "Продължаване", + "resume_paused_jobs": "Продължи изпълнението на {count, plural, one {# задача} other {# задачи}}", "retry_upload": "Опитай качването отново", "review_duplicates": "Разгледай дубликатите", "review_large_files": "Преглед на големи файлове", @@ -1862,6 +1894,7 @@ "show_slideshow_transition": "Покажи прехода на слайдшоуто", "show_supporter_badge": "Значка поддръжник", "show_supporter_badge_description": "Покажи значка поддръжник", + "show_text_search_menu": "Покажи менюто за търсене на текст", "shuffle": "Разбъркване", "sidebar": "Странична лента", "sidebar_display_description": "Показване на връзка към изгледа в страничната лента", @@ -1892,6 +1925,7 @@ "stacktrace": "Следа на събраните", "start": "Старт", "start_date": "Начална дата", + "start_date_before_end_date": "Началната дата трябва да бъде преди крайната дата", "state": "Щат", "status": "Статус", "stop_casting": "Спри предаването", @@ -1916,6 +1950,8 @@ "sync_albums_manual_subtitle": "Синхронизирай всички заредени видеа и снимки в избраните архивни албуми", "sync_local": "Локална синхронизация", "sync_remote": "Синхронизация със сървъра", + "sync_status": "Състояние на синхронизацията", + "sync_status_subtitle": "Преглед и управление на системата за синхронизация", "sync_upload_album_setting_subtitle": "Създавайте и зареждайте снимки и видеа в избрани албуми в Immich", "tag": "Таг", "tag_assets": "Тагни елементи", @@ -1975,6 +2011,7 @@ "trash_page_select_assets_btn": "Избери обекти", "trash_page_title": "В коша ({count})", "trashed_items_will_be_permanently_deleted_after": "Изхвърлените в кошчето елементи ще бъдат изтрити за постоянно след {days, plural, one {# ден} other {# дни}}.", + "troubleshoot": "Отстраняване на проблеми", "type": "Тип", "unable_to_change_pin_code": "Невъзможна промяна на PIN кода", "unable_to_setup_pin_code": "Неуспешно задаване на PIN кода", @@ -2091,5 +2128,6 @@ "yes": "Да", "you_dont_have_any_shared_links": "Нямате споделени връзки", "your_wifi_name": "Вашата Wi-Fi мрежа", - "zoom_image": "Увеличаване на изображението" + "zoom_image": "Увеличаване на изображението", + "zoom_to_bounds": "Приближи до събиране в границите" } diff --git a/i18n/ca.json b/i18n/ca.json index 4d532e0476..0e3d674557 100644 --- a/i18n/ca.json +++ b/i18n/ca.json @@ -28,6 +28,7 @@ "add_to_album": "Afegir a un l'àlbum", "add_to_album_bottom_sheet_added": "Afegit a {album}", "add_to_album_bottom_sheet_already_exists": "Ja està a {album}", + "add_to_album_bottom_sheet_some_local_assets": "Alguns recursos locals no s'han pogut afegir a l'àlbum", "add_to_album_toggle": "Commutar selecció de {album}", "add_to_albums": "Afegir als àlbums", "add_to_albums_count": "Afegir als àlbums ({count})", @@ -84,10 +85,10 @@ "image_fullsize_enabled": "Activa la generació d'imatges a tamany complet", "image_fullsize_enabled_description": "Genera imatges a tamany complet per formats no compatibles amb la web. Quan \"Prefereix vista prèvia incrustada\" està activat, les vistes prèvies incrustades s'utilitzen directament sense conversió. No afecta els formats compatibles amb la web com JPEG.", "image_fullsize_quality_description": "De 1 a 100, qualitat de l'imatge a tamany complet. Un valor més alt és millor, però resulta en fitxers de major tamany.", - "image_fullsize_title": "Configuració d'imatges a tamany complet", + "image_fullsize_title": "Configuració de les imatges a tamany complet", "image_prefer_embedded_preview": "Prefereix vista prèvia incrustada", "image_prefer_embedded_preview_setting_description": "Empra vista prèvia incrustada en les fotografies RAW com a entrada per al processament d'imatge, quan sigui possible. Aquesta acció pot produir colors més acurats en algunes imatges, però la qualitat de la vista prèvia depèn de la càmera i la imatge pot tenir més artefactes de compressió.", - "image_prefer_wide_gamut": "Prefereix àmplia gamma", + "image_prefer_wide_gamut": "Prefereix la gamma àmplia", "image_prefer_wide_gamut_setting_description": "Uitlitza Display P3 per a les miniatures. Això preserva més bé la vitalitat de les imatges amb espais de color àmplis, però les imatges es poden veure diferent en aparells antics amb una versió antiga del navegador. Les imatges sRGB romandran com a sRGB per a evitar canvis de color.", "image_preview_description": "Imatge de mida mitjana amb metadades eliminades, que s'utilitza quan es visualitza un sol recurs i per a l'aprenentatge automàtic", "image_preview_quality_description": "Vista prèvia de la qualitat de l'1 al 100. Més alt és millor, però produeix fitxers més grans i pot reduir la capacitat de resposta de l'aplicació. Establir un valor baix pot afectar la qualitat de l'aprenentatge automàtic.", @@ -95,11 +96,11 @@ "image_quality": "Qualitat", "image_resolution": "Resolució", "image_resolution_description": "Les resolucions més altes poden conservar més detalls però triguen més a codificar-se, tenen mides de fitxer més grans i poden reduir la capacitat de resposta de l'aplicació.", - "image_settings": "Configuració d'imatges", + "image_settings": "Configuració de les imatges", "image_settings_description": "Gestiona la qualitat i resolució de les imatges generades", "image_thumbnail_description": "Miniatura petita amb metadades eliminades, que s'utilitza quan es visualitzen grups de fotos com la línia de temps principal", "image_thumbnail_quality_description": "Qualitat de miniatura d'1 a 100. Més alt és millor, però produeix fitxers més grans i pot reduir la capacitat de resposta de l'aplicació.", - "image_thumbnail_title": "Configuració de miniatures", + "image_thumbnail_title": "Configuració de les miniatures", "job_concurrency": "{job} simultàniament", "job_created": "Tasca creada", "job_not_concurrency_safe": "Aquesta tasca no és segura per a la conconcurrència.", @@ -123,6 +124,13 @@ "logging_enable_description": "Habilitar el registrament", "logging_level_description": "Quan està habilitat, quin nivell de registre es vol emprar.", "logging_settings": "Registre", + "machine_learning_availability_checks": "Comprovacions de disponibilitat", + "machine_learning_availability_checks_description": "Detectar i preferir automàticament els servidors d'aprenentatge automàtic disponibles", + "machine_learning_availability_checks_enabled": "Habilita les comprovacions de disponibilitat", + "machine_learning_availability_checks_interval": "Interval de comprovació", + "machine_learning_availability_checks_interval_description": "Interval en mil·lisegons entre comprovacions de disponibilitat", + "machine_learning_availability_checks_timeout": "Temps d'espera de la sol·licitud", + "machine_learning_availability_checks_timeout_description": "Temps d'espera en mil·lisegons per a les comprovacions de disponibilitat", "machine_learning_clip_model": "Model CLIP", "machine_learning_clip_model_description": "El nom d'un model CLIP que apareix a aquí. Tingues en compte que has de tornar a executar la cerca intel·ligent per a totes les imatges quan es canvia de model.", "machine_learning_duplicate_detection": "Detecció de duplicats", @@ -387,8 +395,6 @@ "admin_password": "Contrasenya de l'administrador", "administration": "Administració", "advanced": "Avançat", - "advanced_settings_beta_timeline_subtitle": "Prova la nova experiència de l'aplicació", - "advanced_settings_beta_timeline_title": "Cronologia beta", "advanced_settings_enable_alternate_media_filter_subtitle": "Feu servir aquesta opció per filtrar els continguts multimèdia durant la sincronització segons criteris alternatius. Només proveu-ho si teniu problemes amb l'aplicació per detectar tots els àlbums.", "advanced_settings_enable_alternate_media_filter_title": "Utilitza el filtre de sincronització d'àlbums de dispositius alternatius", "advanced_settings_log_level_title": "Nivell de registre: {level}", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "Esteu segurs que voleu eliminar {user}?", "album_search_not_found": "No s'ha trobat cap àlbum que coincideixi amb la teva cerca", "album_share_no_users": "Sembla que has compartit aquest àlbum amb tots els usuaris o no tens cap usuari amb qui compartir-ho.", + "album_summary": "Resum de l'àlbum", "album_updated": "Àlbum actualitzat", "album_updated_setting_description": "Rep una notificació per correu electrònic quan un àlbum compartit tingui recursos nous", "album_user_left": "Surt de {album}", @@ -496,6 +503,8 @@ "asset_restored_successfully": "Element recuperat correctament", "asset_skipped": "Saltat", "asset_skipped_in_trash": "A la paperera", + "asset_trashed": "Recurs a la paperera", + "asset_troubleshoot": "Diagnòstic de l'element", "asset_uploaded": "Carregat", "asset_uploading": "S'està carregant…", "asset_viewer_settings_subtitle": "Gestiona la configuració del visualitzador de la galeria", @@ -529,8 +538,10 @@ "autoplay_slideshow": "Reprodueix automàticament les diapositives", "back": "Enrere", "back_close_deselect": "Tornar, tancar o anul·lar la selecció", + "background_backup_running_error": "La còpia de seguretat en segon pla s'està executant actualment, no es pot iniciar la còpia de seguretat manual", "background_location_permission": "Permís d'ubicació en segon pla", "background_location_permission_content": "Per canviar de xarxa quan s'executa en segon pla, Immich ha de *sempre* tenir accés a la ubicació precisa perquè l'aplicació pugui llegir el nom de la xarxa Wi-Fi", + "background_options": "Opcions en segon pla", "backup": "Còpia", "backup_album_selection_page_albums_device": "Àlbums al dispositiu ({count})", "backup_album_selection_page_albums_tap": "Un toc per incloure, doble toc per excloure", @@ -538,6 +549,7 @@ "backup_album_selection_page_select_albums": "Selecciona àlbums", "backup_album_selection_page_selection_info": "Informació de la selecció", "backup_album_selection_page_total_assets": "Total d'elements únics", + "backup_albums_sync": "Sincronització d'àlbums de còpia de seguretat", "backup_all": "Tots", "backup_background_service_backup_failed_message": "No s'ha pogut copiar els elements. Tornant a intentar…", "backup_background_service_connection_failed_message": "No s'ha pogut connectar al servidor. Tornant a intentar…", @@ -654,6 +666,8 @@ "change_pin_code": "Canviar el codi PIN", "change_your_password": "Canvia la teva contrasenya", "changed_visibility_successfully": "Visibilitat canviada amb èxit", + "charging": "Carregant", + "charging_requirement_mobile_backup": "La còpia de seguretat en segon pla requereix que el dispositiu estigui carregant", "check_corrupt_asset_backup": "Comprovar les còpies de seguretat corruptes", "check_corrupt_asset_backup_button": "Realitzar comprovació", "check_corrupt_asset_backup_description": "Executeu aquesta comprovació només mitjançant Wi-Fi i un cop s'hagi fet una còpia de seguretat de tots els actius. El procediment pot trigar uns minuts.", @@ -740,6 +754,7 @@ "create_user": "Crea un usuari", "created": "Creat", "created_at": "Creat", + "creating_linked_albums": "Creant àlbums enllaçats...", "crop": "Retalla", "curated_object_page_title": "Coses", "current_device": "Dispositiu actual", @@ -878,7 +893,7 @@ "empty_trash": "Buidar la paperera", "empty_trash_confirmation": "Esteu segur que voleu buidar la paperera? Això eliminarà tots els recursos a la paperera permanentment d'Immich.\nNo podeu desfer aquesta acció!", "enable": "Activar", - "enable_backup": "Habilitar Còpia de Seguretat", + "enable_backup": "Còpia de Seguretat", "enable_biometric_auth_description": "Introduïu el codi PIN per a habilitar l'autenticació biomètrica", "enabled": "Activat", "end_date": "Data final", @@ -889,7 +904,9 @@ "error": "Error", "error_change_sort_album": "No s'ha pogut canviar l'ordre d'ordenació dels àlbums", "error_delete_face": "Error esborrant cara de les cares reconegudes", + "error_getting_places": "S'ha produït un error en obtenir els llocs", "error_loading_image": "Error carregant la imatge", + "error_loading_partners": "No s'han pogut carregar les parelles: {error}", "error_saving_image": "Error: {error}", "error_tag_face_bounding_box": "Error a l'etiquetar la cara - no s'han pogut obtenir les coordenades de l'àrea", "error_title": "Error - Quelcom ha anat malament", @@ -1054,6 +1071,7 @@ "favorites_page_no_favorites": "No s'han trobat preferits", "feature_photo_updated": "Foto destacada actualitzada", "features": "Característiques", + "features_in_development": "Funcions en desenvolupament", "features_setting_description": "Administrar les funcions de l'aplicació", "file_name": "Nom de l'arxiu", "file_name_or_extension": "Nom de l'arxiu o extensió", @@ -1095,7 +1113,7 @@ "has_quota": "Quota", "hash_asset": "Hash del recurs", "hashed_assets": "Recursos amb hash", - "hashing": "Hashing", + "hashing": "Generant el hash", "header_settings_add_header_tip": "Afegeix Capçalera", "header_settings_field_validator_msg": "El valor no pot estar buit", "header_settings_header_name_input": "Nom de la capçalera", @@ -1218,6 +1236,7 @@ "local": "Local", "local_asset_cast_failed": "No es pot convertir un actiu que no s'ha penjat al servidor", "local_assets": "Recursos Locals", + "local_media_summary": "Resum de Mitjans Locals", "local_network": "Xarxa local", "local_network_sheet_info": "L'aplicació es connectarà al servidor mitjançant aquest URL quan utilitzeu la xarxa Wi-Fi especificada", "location_permission": "Permís d'ubicació", @@ -1229,6 +1248,7 @@ "location_picker_longitude_hint": "Introdueix aquí la longitud", "lock": "Bloqueja", "locked_folder": "Carpeta bloquejada", + "log_detail_title": "Detall de Registres", "log_out": "Tanca la sessió", "log_out_all_devices": "Tanqueu la sessió de tots els dispositius", "logged_in_as": "Sessió iniciada com a {user}", @@ -1259,6 +1279,7 @@ "login_password_changed_success": "La contrasenya s'ha canviat correctament", "logout_all_device_confirmation": "Esteu segur que voleu tancar la sessió de tots els dispositius?", "logout_this_device_confirmation": "Esteu segur que voleu tancar la sessió d'aquest dispositiu?", + "logs": "Registres", "longitude": "Longitud", "look": "Aspecte", "loop_videos": "Vídeos en bucle", @@ -1301,6 +1322,7 @@ "mark_as_read": "Marcar com ha llegit", "marked_all_as_read": "Marcat tot com a llegit", "matches": "Coincidències", + "matching_assets": "Recursos Coincidents", "media_type": "Tipus de mitjà", "memories": "Records", "memories_all_caught_up": "Posat al dia", @@ -1341,6 +1363,7 @@ "name_or_nickname": "Nom o sobrenom", "network_requirement_photos_upload": "Fes servir dades mòbils per a còpies de seguretat de fotos", "network_requirement_videos_upload": "Fes servir dades mòbils per a còpies de seguretat de videos", + "network_requirements": "Requeriments de Xarxa", "network_requirements_updated": "Han canviat els requeriments de xarxa, reiniciant la cua", "networking_settings": "Xarxes", "networking_subtitle": "Gestiona la configuració del endpoint del servidor", @@ -1351,6 +1374,7 @@ "new_person": "Persona nova", "new_pin_code": "Nou codi PIN", "new_pin_code_subtitle": "Aquesta és la primera vegada que accedeixes a la carpeta bloquejada. Crea una codi PIN i accedeix de manera segura a aquesta pàgina", + "new_timeline": "Nova Línia de Temps", "new_user_created": "Nou usuari creat", "new_version_available": "NOVA VERSIÓ DISPONIBLE", "newest_first": "El més nou primer", @@ -1364,20 +1388,25 @@ "no_assets_message": "FEU CLIC PER PUJAR LA VOSTRA PRIMERA FOTO", "no_assets_to_show": "No hi ha elements per mostrar", "no_cast_devices_found": "No s'han trobat dispositius per transmetre", + "no_checksum_local": "Cap checksum disponible - no s'han pogut carregar els recursos locals", + "no_checksum_remote": "Cap checksum disponible - no s'ha pogut obtenir el recurs remot", "no_duplicates_found": "No s'han trobat duplicats.", "no_exif_info_available": "No hi ha informació d'exif disponible", "no_explore_results_message": "Penja més fotos per explorar la teva col·lecció.", "no_favorites_message": "Afegiu preferits per trobar les millors fotos i vídeos a l'instant", "no_libraries_message": "Creeu una llibreria externa per veure les vostres fotos i vídeos", + "no_local_assets_found": "No s'ha trobat cap recurs local amb aquest checksum", "no_locked_photos_message": "Les fotos i vídeos d'aquesta carpeta estan ocultes, i no es mostraran a mesura que navegues o cerques a la teva biblioteca.", "no_name": "Sense nom", "no_notifications": "No hi ha notificacions", "no_people_found": "No s'han trobat coincidències de persones", "no_places": "No hi ha llocs", + "no_remote_assets_found": "No s'ha trobat cap recurs remot amb aquest checksum", "no_results": "Sense resultats", "no_results_description": "Proveu un sinònim o una paraula clau més general", "no_shared_albums_message": "Creeu un àlbum per compartir fotos i vídeos amb persones a la vostra xarxa", "no_uploads_in_progress": "Cap pujada en progrés", + "not_available": "N/A", "not_in_any_album": "En cap àlbum", "not_selected": "No seleccionat", "note_apply_storage_label_to_previously_uploaded assets": "Nota: per aplicar l'etiqueta d'emmagatzematge als actius penjats anteriorment, executeu el", @@ -1499,6 +1528,7 @@ "port": "Port", "preferences_settings_subtitle": "Gestiona les preferències de l'aplicació", "preferences_settings_title": "Preferències", + "preparing": "Preparant", "preset": "Preestablert", "preview": "Previsualització", "previous": "Anterior", @@ -1513,9 +1543,9 @@ "profile_drawer_app_logs": "Registres", "profile_drawer_client_out_of_date_major": "L'aplicació mòbil està desactualitzada. Si us plau, actualitzeu a l'última versió major.", "profile_drawer_client_out_of_date_minor": "L'aplicació mòbil està desactualitzada. Si us plau, actualitzeu a l'última versió menor.", - "profile_drawer_client_server_up_to_date": "El Client i el Servidor estan actualitzats", + "profile_drawer_client_server_up_to_date": "El client i el servidor estan actualitzats", "profile_drawer_github": "GitHub", - "profile_drawer_readonly_mode": "Manera de només lectura activada. Feu doble click a la icona de l'avatar de l'usuari per sortir.", + "profile_drawer_readonly_mode": "Mode només lectura. Feu pulsació llarga a la icona de l'avatar d'usuari per sortir.", "profile_drawer_server_out_of_date_major": "El servidor està desactualitzat. Si us plau, actualitzeu a l'última versió major.", "profile_drawer_server_out_of_date_minor": "El servidor està desactualitzat. Si us plau, actualitzeu a l'última versió menor.", "profile_image_of_user": "Imatge de perfil de {user}", @@ -1564,6 +1594,7 @@ "read_changelog": "Llegeix el registre de canvis", "readonly_mode_disabled": "Mode de només lectura desactivat", "readonly_mode_enabled": "Mode de només lectura activat", + "ready_for_upload": "Llest per a pujar", "reassign": "Reassignar", "reassigned_assets_to_existing_person": "{count, plural, one {S'ha reassignat # recurs} other {S'han reassignat # recursos}} a {name, select, null {una persona existent} other {{name}}}", "reassigned_assets_to_new_person": "{count, plural, one {S'ha reassignat # recurs} other {S'han reassignat # recursos}} a una persona nova", @@ -1588,6 +1619,7 @@ "regenerating_thumbnails": "Regenerant les miniatures", "remote": "Remot", "remote_assets": "Recursos Remots", + "remote_media_summary": "Resum de Mitjans Remots", "remove": "Eliminar", "remove_assets_album_confirmation": "Confirmes que vols eliminar {count, plural, one {# recurs} other {# recursos}} de l'àlbum?", "remove_assets_shared_link_confirmation": "Esteu segur que voleu eliminar {count, plural, one {# recurs} other {# recursos}} d'aquest enllaç compartit?", @@ -1640,6 +1672,7 @@ "restore_user": "Restaurar l'usuari", "restored_asset": "Element restaurat", "resume": "Reprendre", + "resume_paused_jobs": "Reprèn {count, plural, one {# treball pausat} other {# treballs pausats}}", "retry_upload": "Torna a provar de pujar", "review_duplicates": "Revisar duplicats", "review_large_files": "Revisar fitxers grans", @@ -1862,6 +1895,7 @@ "show_slideshow_transition": "Mostra la transició de la presentació de diapositives", "show_supporter_badge": "Insígnia de contribuent", "show_supporter_badge_description": "Mostra una insígnia de contributor", + "show_text_search_menu": "Mostra el menú de cerca amb text", "shuffle": "Mescla", "sidebar": "Barra lateral", "sidebar_display_description": "Mostra un enllaç a la vista a la barra lateral", @@ -1892,6 +1926,7 @@ "stacktrace": "Traça de pila", "start": "Inicia", "start_date": "Data inicial", + "start_date_before_end_date": "La data d'inici ha de ser abans de la data de fi", "state": "Regió", "status": "Estat", "stop_casting": "Atura la transmisió", @@ -1916,6 +1951,8 @@ "sync_albums_manual_subtitle": "Sincronitza tots els vídeos i fotos penjats amb els àlbums de còpia de seguretat seleccionats", "sync_local": "Sincronitza Local", "sync_remote": "Sincronitza Remot", + "sync_status": "Estat de sincronització", + "sync_status_subtitle": "Observa i administra el sistema de sincronització", "sync_upload_album_setting_subtitle": "Creeu i pugeu les seves fotos i vídeos als àlbums seleccionats a Immich", "tag": "Etiqueta", "tag_assets": "Etiquetar actius", @@ -1975,6 +2012,7 @@ "trash_page_select_assets_btn": "Selecciona elements", "trash_page_title": "Paperera ({count})", "trashed_items_will_be_permanently_deleted_after": "Els elements que s'enviïn a la paperera s'eliminaran permanentment després de {days, plural, one {# dia} other {# dies}}.", + "troubleshoot": "Solució de problemes", "type": "Tipus", "unable_to_change_pin_code": "No es pot canviar el codi PIN", "unable_to_setup_pin_code": "No s'ha pogut configurar el codi PIN", @@ -2091,5 +2129,6 @@ "yes": "Sí", "you_dont_have_any_shared_links": "No tens cap enllaç compartit", "your_wifi_name": "Nom del teu Wi-Fi", - "zoom_image": "Ampliar Imatge" + "zoom_image": "Ampliar Imatge", + "zoom_to_bounds": "Amplia als límits" } diff --git a/i18n/cs.json b/i18n/cs.json index e97d7f4211..ceebc9f401 100644 --- a/i18n/cs.json +++ b/i18n/cs.json @@ -28,6 +28,7 @@ "add_to_album": "Přidat do alba", "add_to_album_bottom_sheet_added": "Přidáno do {album}", "add_to_album_bottom_sheet_already_exists": "Je již v {album}", + "add_to_album_bottom_sheet_some_local_assets": "Některá místní aktiva nebylo možné přidat do alba", "add_to_album_toggle": "Přepnout výběr pro {album}", "add_to_albums": "Přidat do alb", "add_to_albums_count": "Přidat do alb ({count})", @@ -123,6 +124,13 @@ "logging_enable_description": "Povolit protokolování", "logging_level_description": "Když je povoleno, jakou úroveň protokolu použít.", "logging_settings": "Protokolování", + "machine_learning_availability_checks": "Kontroly dostupnosti", + "machine_learning_availability_checks_description": "Automaticky zvolit a preferovat dostupné servery strojového učení", + "machine_learning_availability_checks_enabled": "Povolit kontroly dostupnosti", + "machine_learning_availability_checks_interval": "Interval kontrol", + "machine_learning_availability_checks_interval_description": "Interval v milisekundách mezi kontrolami dostupnosti", + "machine_learning_availability_checks_timeout": "Vypršení požadavku", + "machine_learning_availability_checks_timeout_description": "Časové vypršení požadavku v milisekundách u kontrol dostupnosti", "machine_learning_clip_model": "Model CLIP", "machine_learning_clip_model_description": "Název CLIP modelu je uvedený zde. Pamatujte, že při změně modelu je nutné znovu spustit úlohu 'Chytré vyhledávání' pro všechny obrázky.", "machine_learning_duplicate_detection": "Kontrola duplicit", @@ -387,8 +395,6 @@ "admin_password": "Heslo správce", "administration": "Administrace", "advanced": "Pokročilé", - "advanced_settings_beta_timeline_subtitle": "Vyzkoušejte nové prostředí aplikace", - "advanced_settings_beta_timeline_title": "Časová osa (beta)", "advanced_settings_enable_alternate_media_filter_subtitle": "Tuto možnost použijte k filtrování médií během synchronizace na základě alternativních kritérií. Tuto možnost vyzkoušejte pouze v případě, že máte problémy s detekcí všech alb v aplikaci.", "advanced_settings_enable_alternate_media_filter_title": "[EXPERIMENTÁLNÍ] Použít alternativní filtr pro synchronizaci alb zařízení", "advanced_settings_log_level_title": "Úroveň protokolování: {level}", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "Opravdu chcete odebrat uživatele {user}?", "album_search_not_found": "Nebyla nalezena žádná alba odpovídající vašemu hledání", "album_share_no_users": "Zřejmě jste toto album sdíleli se všemi uživateli, nebo nemáte žádného uživatele, se kterým byste ho mohli sdílet.", + "album_summary": "Souhrn alba", "album_updated": "Album aktualizováno", "album_updated_setting_description": "Dostávat e-mailová oznámení o nových položkách sdíleného alba", "album_user_left": "Opustil {album}", @@ -496,6 +503,8 @@ "asset_restored_successfully": "Položka úspěšně obnovena", "asset_skipped": "Přeskočeno", "asset_skipped_in_trash": "V koši", + "asset_trashed": "Položka vyhozena", + "asset_troubleshoot": "Řešení problémů s položkami", "asset_uploaded": "Nahráno", "asset_uploading": "Nahrávání…", "asset_viewer_settings_subtitle": "Správa nastavení prohlížeče galerie", @@ -529,8 +538,10 @@ "autoplay_slideshow": "Automatické přehrávání prezentace", "back": "Zpět", "back_close_deselect": "Zpět, zavřít nebo zrušit výběr", + "background_backup_running_error": "Právě probíhá zálohování na pozadí, nelze spustit ruční zálohování", "background_location_permission": "Povolení polohy na pozadí", "background_location_permission_content": "Aby bylo možné přepínat sítě při běhu na pozadí, musí mít Immich *vždy* přístup k přesné poloze, aby mohl zjistit název Wi-Fi sítě", + "background_options": "Možnosti běhu na pozadí", "backup": "Záloha", "backup_album_selection_page_albums_device": "Alba v zařízení ({count})", "backup_album_selection_page_albums_tap": "Klepnutím na položku ji zahrnete, opětovným klepnutím ji vyloučíte", @@ -538,6 +549,7 @@ "backup_album_selection_page_select_albums": "Vybraná alba", "backup_album_selection_page_selection_info": "Informace o výběru", "backup_album_selection_page_total_assets": "Celkový počet jedinečných položek", + "backup_albums_sync": "Synchronizace zálohovaných alb", "backup_all": "Vše", "backup_background_service_backup_failed_message": "Zálohování médií selhalo. Zkouším to znovu…", "backup_background_service_connection_failed_message": "Nepodařilo se připojit k serveru. Zkouším to znovu…", @@ -654,6 +666,8 @@ "change_pin_code": "Změnit PIN kód", "change_your_password": "Změna vašeho hesla", "changed_visibility_successfully": "Změna viditelnosti proběhla úspěšně", + "charging": "Nabíjení", + "charging_requirement_mobile_backup": "Zálohování na pozadí vyžaduje, aby bylo zařízení nabíjeno", "check_corrupt_asset_backup": "Kontrola poškozených záloh položek", "check_corrupt_asset_backup_button": "Provést kontrolu", "check_corrupt_asset_backup_description": "Tuto kontrolu provádějte pouze přes Wi-Fi a po zálohování všech prostředků. Takto operace může trvat několik minut.", @@ -740,6 +754,7 @@ "create_user": "Vytvořit uživatele", "created": "Vytvořeno", "created_at": "Vytvořeno", + "creating_linked_albums": "Vytváření propojených alb...", "crop": "Oříznout", "curated_object_page_title": "Věci", "current_device": "Současné zařízení", @@ -889,7 +904,9 @@ "error": "Chyba", "error_change_sort_album": "Nepodařilo se změnit pořadí alba", "error_delete_face": "Chyba při odstraňování obličeje z položky", + "error_getting_places": "Chyba při zjišťování míst", "error_loading_image": "Chyba při načítání obrázku", + "error_loading_partners": "Chyba při načítání partnerů: {error}", "error_saving_image": "Chyba: {error}", "error_tag_face_bounding_box": "Chyba při označování obličeje - nelze získat souřadnice ohraničujícího rámečku", "error_title": "Chyba - Něco se pokazilo", @@ -1054,6 +1071,7 @@ "favorites_page_no_favorites": "Nebyla nalezena žádná oblíbená média", "feature_photo_updated": "Hlavní fotka aktualizována", "features": "Funkce", + "features_in_development": "Funkce ve vývoji", "features_setting_description": "Správa funkcí aplikace", "file_name": "Název souboru", "file_name_or_extension": "Název nebo přípona souboru", @@ -1218,6 +1236,7 @@ "local": "Místní", "local_asset_cast_failed": "Nelze odeslat položku, která není nahraná na serveru", "local_assets": "Místní položky", + "local_media_summary": "Souhrn místních médií", "local_network": "Místní síť", "local_network_sheet_info": "Aplikace se při použití zadané sítě Wi-Fi připojí k serveru prostřednictvím tohoto URL", "location_permission": "Oprávnění polohy", @@ -1229,6 +1248,7 @@ "location_picker_longitude_hint": "Zadejte vlastní zeměpisnou délku", "lock": "Zamknout", "locked_folder": "Uzamčená složka", + "log_detail_title": "Podrobnosti protokolu", "log_out": "Odhlásit", "log_out_all_devices": "Odhlásit všechna zařízení", "logged_in_as": "Přihlášen jako {user}", @@ -1259,6 +1279,7 @@ "login_password_changed_success": "Heslo bylo úspěšně aktualizováno", "logout_all_device_confirmation": "Opravdu chcete odhlásit všechna zařízení?", "logout_this_device_confirmation": "Opravdu chcete odhlásit toto zařízení?", + "logs": "Protokoly", "longitude": "Zeměpisná délka", "look": "Zobrazení", "loop_videos": "Videa ve smyčce", @@ -1301,6 +1322,7 @@ "mark_as_read": "Označit jako přečtené", "marked_all_as_read": "Vše označeno jako přečtené", "matches": "Shody", + "matching_assets": "Odpovídající položky", "media_type": "Typ média", "memories": "Vzpomínky", "memories_all_caught_up": "To je všechno", @@ -1341,6 +1363,7 @@ "name_or_nickname": "Jméno nebo přezdívka", "network_requirement_photos_upload": "Pro zálohování fotografií používat mobilní data", "network_requirement_videos_upload": "Pro zálohování videí používat mobilní data", + "network_requirements": "Požadavky na síť", "network_requirements_updated": "Požadavky na síť se změnily, fronta zálohování se vytvoří znovu", "networking_settings": "Síť", "networking_subtitle": "Správa nastavení koncového bodu serveru", @@ -1351,6 +1374,7 @@ "new_person": "Nová osoba", "new_pin_code": "Nový PIN kód", "new_pin_code_subtitle": "Poprvé přistupujete k uzamčené složce. Vytvořte si kód PIN pro bezpečný přístup na tuto stránku", + "new_timeline": "Nová časová osa", "new_user_created": "Vytvořen nový uživatel", "new_version_available": "NOVÁ VERZE K DISPOZICI", "newest_first": "Nejnovější první", @@ -1364,20 +1388,25 @@ "no_assets_message": "KLIKNĚTE PRO NAHRÁNÍ PRVNÍ FOTOGRAFIE", "no_assets_to_show": "Žádné položky k zobrazení", "no_cast_devices_found": "Nebyla nalezena žádná zařízení", + "no_checksum_local": "Není k dispozici kontrolní součet - nelze načíst místní položky", + "no_checksum_remote": "Není k dispozici kontrolní součet - nelze načíst vzdálenou položku", "no_duplicates_found": "Nebyly nalezeny žádné duplicity.", "no_exif_info_available": "Exif není k dispozici", "no_explore_results_message": "Nahrajte další fotografie a prozkoumejte svou sbírku.", "no_favorites_message": "Přidejte si oblíbené položky a rychle najděte své nejlepší obrázky a videa", "no_libraries_message": "Vytvořte si externí knihovnu pro zobrazení fotografií a videí", + "no_local_assets_found": "Nebyly nalezeny žádné místní položky s tímto kontrolním součtem", "no_locked_photos_message": "Fotky a videa v uzamčené složce jsou skryté a při procházení nebo vyhledávání v knihovně se nezobrazují.", "no_name": "Bez jména", "no_notifications": "Žádná oznámení", "no_people_found": "Nebyli nalezeni žádní odpovídající lidé", "no_places": "Žádná místa", + "no_remote_assets_found": "Nebyly nalezeny žádné vzdálené položky s tímto kontrolním součtem", "no_results": "Žádné výsledky", "no_results_description": "Zkuste použít synonymum nebo obecnější klíčové slovo", "no_shared_albums_message": "Vytvořte si album a sdílejte fotografie a videa s lidmi ve své síti", "no_uploads_in_progress": "Neprobíhá žádné nahrávání", + "not_available": "Není k dispozici", "not_in_any_album": "Bez alba", "not_selected": "Není vybráno", "note_apply_storage_label_to_previously_uploaded assets": "Upozornění: Chcete-li použít štítek úložiště na dříve nahrané položky, spusťte příkaz", @@ -1499,6 +1528,7 @@ "port": "Port", "preferences_settings_subtitle": "Správa předvoleb aplikace", "preferences_settings_title": "Předvolby", + "preparing": "Příprava", "preset": "Přednastavení", "preview": "Náhled", "previous": "Předchozí", @@ -1564,6 +1594,7 @@ "read_changelog": "Přečtěte si seznam změn", "readonly_mode_disabled": "Režim pouze pro čtení je deaktivován", "readonly_mode_enabled": "Režim pouze pro čtení povolen", + "ready_for_upload": "Připraveno k nahrání", "reassign": "Přeřadit", "reassigned_assets_to_existing_person": "Přeřadit {count, plural, one {# položku} few {# položky} other {# položek}} na {name, select, null {existující osobu} other {{name}}}", "reassigned_assets_to_new_person": "{count, plural, one {Přeřazena # položka} few {Přeřazeny # položky} other {Přeřazeno # položek}} na novou osobu", @@ -1588,6 +1619,7 @@ "regenerating_thumbnails": "Regenerace miniatur", "remote": "Vzdálený", "remote_assets": "Vzdálené položky", + "remote_media_summary": "Souhrn vzdálených médií", "remove": "Odstranit", "remove_assets_album_confirmation": "Opravdu chcete z alba odstranit {count, plural, one {# položku} few {# položky} other {# položek}}?", "remove_assets_shared_link_confirmation": "Opravdu chcete ze sdíleného odkazu odstranit {count, plural, one {# položku} few {# položky} other {# položek}}?", @@ -1653,7 +1685,7 @@ "saved_api_key": "API klíč uložen", "saved_profile": "Profil uložen", "saved_settings": "Nastavení uloženo", - "say_something": "Řekněte něco", + "say_something": "Napište něco", "scaffold_body_error_occurred": "Došlo k chybě", "scan_all_libraries": "Prohledat všechny knihovny", "scan_library": "Prohledat", @@ -1863,6 +1895,7 @@ "show_slideshow_transition": "Zobrazit přechod prezentace", "show_supporter_badge": "Odznak podporovatele", "show_supporter_badge_description": "Zobrazit odznak podporovatele", + "show_text_search_menu": "Zobrazit nabídku pro vyhledávání textu", "shuffle": "Náhodný výběr", "sidebar": "Postranní panel", "sidebar_display_description": "Zobrazení odkazu na zobrazení v postranním panelu", @@ -1893,6 +1926,7 @@ "stacktrace": "Výpis zásobníku", "start": "Start", "start_date": "Počáteční datum", + "start_date_before_end_date": "Počáteční datum se musí nacházet před konečným datem", "state": "Stát", "status": "Stav", "stop_casting": "Zastavit odesílání", @@ -2095,5 +2129,6 @@ "yes": "Ano", "you_dont_have_any_shared_links": "Nemáte žádné sdílené odkazy", "your_wifi_name": "Název vaší Wi-Fi", - "zoom_image": "Zvětšit obrázek" + "zoom_image": "Zvětšit obrázek", + "zoom_to_bounds": "Přiblížit na okraje" } diff --git a/i18n/da.json b/i18n/da.json index c45cf4000d..61891e7ef8 100644 --- a/i18n/da.json +++ b/i18n/da.json @@ -2,7 +2,7 @@ "about": "Om os", "account": "Konto", "account_settings": "Kontoindstillinger", - "acknowledge": "Anerkendelse", + "acknowledge": "Accepter", "action": "Handling", "action_common_update": "Opdater", "actions": "Handlinger", @@ -123,6 +123,13 @@ "logging_enable_description": "Aktiver logning", "logging_level_description": "Når slået til, hvilket logniveau, der skal bruges.", "logging_settings": "Logning", + "machine_learning_availability_checks": "Tilgængelighedstjek", + "machine_learning_availability_checks_description": "Opdag og foretræk automatisk tilgængelige maskinlæringsservere", + "machine_learning_availability_checks_enabled": "Aktivér tilgængelighedstjek", + "machine_learning_availability_checks_interval": "Kontroller interval", + "machine_learning_availability_checks_interval_description": "Interval i millisekunder mellem tilgængelighedstjeks", + "machine_learning_availability_checks_timeout": "Timeout på anmodning", + "machine_learning_availability_checks_timeout_description": "Timeout i millisekunder på tilgængelighedstjeks", "machine_learning_clip_model": "CLIP-model", "machine_learning_clip_model_description": "Navnet på CLIP-modellen på listen her. Bemærk at du skal genkøre \"Smart Søgning\"-jobbet for alle billeder, hvis du skifter model.", "machine_learning_duplicate_detection": "Dubletdetektion", @@ -387,8 +394,6 @@ "admin_password": "Administratoradgangskode", "administration": "Administration", "advanced": "Avanceret", - "advanced_settings_beta_timeline_subtitle": "Prøv den nye app-oplevelse", - "advanced_settings_beta_timeline_title": "Beta-tidslinje", "advanced_settings_enable_alternate_media_filter_subtitle": "Brug denne valgmulighed for at filtrere media under synkronisering baseret på alternative kriterier. Prøv kun denne hvis du har problemer med at appen ikke opdager alle albums.", "advanced_settings_enable_alternate_media_filter_title": "[EKSPERIMENTEL] Brug alternativ enheds album synkroniserings filter", "advanced_settings_log_level_title": "Logniveau: {level}", @@ -425,6 +430,7 @@ "album_remove_user_confirmation": "Er du sikker på at du vil fjerne {user}?", "album_search_not_found": "Ingen album fundet som matcher din søgning", "album_share_no_users": "Det ser ud til at du har delt denne album med alle brugere, eller du har ikke nogen brugere til at dele med.", + "album_summary": "Albumoversigt", "album_updated": "Album opdateret", "album_updated_setting_description": "Modtag en emailnotifikation når et delt album får nye mediefiler", "album_user_left": "Forlod {album}", @@ -496,6 +502,8 @@ "asset_restored_successfully": "Elementet blev gendannet succesfuldt", "asset_skipped": "Sprunget over", "asset_skipped_in_trash": "I skraldespand", + "asset_trashed": "Objekt kasseret", + "asset_troubleshoot": "Fejlsøg på objekt", "asset_uploaded": "Uploadet", "asset_uploading": "Uploader…", "asset_viewer_settings_subtitle": "Administrer indstillinger for gallerifremviser", @@ -529,8 +537,10 @@ "autoplay_slideshow": "Afspil slideshow automatisk", "back": "Tilbage", "back_close_deselect": "Tilbage, luk eller fravælg", + "background_backup_running_error": "Backup kører lige nu i baggrund; kan ikke starte manuel backup", "background_location_permission": "Tilladelse til baggrundsplacering", "background_location_permission_content": "For at skifte netværk, når appen kører i baggrunden, skal Immich *altid* have præcis placeringsadgang, så appen kan læse WiFi-netværkets navn", + "background_options": "Baggrundsmuligheder", "backup": "Sikkerhedskopier", "backup_album_selection_page_albums_device": "Albummer på enheden ({count})", "backup_album_selection_page_albums_tap": "Tryk en gang for at inkludere, tryk to gange for at ekskludere", @@ -538,6 +548,7 @@ "backup_album_selection_page_select_albums": "Vælg albummer", "backup_album_selection_page_selection_info": "Oplysninger om valgte", "backup_album_selection_page_total_assets": "Samlede unikke elementer", + "backup_albums_sync": "Synkronisering af backupalbums", "backup_all": "Alt", "backup_background_service_backup_failed_message": "Sikkerhedskopiering af elementer fejlede. Forsøger igen…", "backup_background_service_connection_failed_message": "Forbindelsen til serveren blev tabt. Forsøger igen…", @@ -635,7 +646,7 @@ "cannot_merge_people": "Kan ikke sammenflette personer", "cannot_undo_this_action": "Du kan ikke fortryde denne handling!", "cannot_update_the_description": "Kan ikke opdatere beskrivelsen", - "cast": "Cast", + "cast": "Caste", "cast_description": "Konfigurer tilgængelige cast destinationer", "change_date": "Ændr dato", "change_description": "Beskrivelse af ændringer", @@ -654,6 +665,8 @@ "change_pin_code": "Skift PIN kode", "change_your_password": "Skift dit kodeord", "changed_visibility_successfully": "Synlighed blev ændret", + "charging": "Lader", + "charging_requirement_mobile_backup": "Baggrundsbackup kræver, at enheden er tilsluttet oplader", "check_corrupt_asset_backup": "Tjek for korrupte sikkerhedskopier af elementer", "check_corrupt_asset_backup_button": "Foretag kontrol", "check_corrupt_asset_backup_description": "Kør kun denne kontrol via Wi-Fi, og når alle elementer er blevet sikkerhedskopieret. Proceduren kan tage et par minutter.", @@ -740,6 +753,7 @@ "create_user": "Opret bruger", "created": "Oprettet", "created_at": "Oprettet", + "creating_linked_albums": "Opretter sammenkædede albums...", "crop": "Beskær", "curated_object_page_title": "Ting", "current_device": "Nuværende enhed", @@ -889,7 +903,9 @@ "error": "Fejl", "error_change_sort_album": "Ændring af sorteringsrækkefølgen mislykkedes", "error_delete_face": "Fejl ved sletning af ansigt fra mediefil", + "error_getting_places": "Fejl ved hentning af steder", "error_loading_image": "Fejl ved indlæsning af billede", + "error_loading_partners": "Fejl ved indlæsning af partnere: {error}", "error_saving_image": "Fejl: {error}", "error_tag_face_bounding_box": "Fejl ved tagging af ansigt - kan ikke finde koordinator for afgrænsningskasse", "error_title": "Fejl - Noget gik galt", @@ -1054,6 +1070,7 @@ "favorites_page_no_favorites": "Ingen favoritter blev fundet", "feature_photo_updated": "Forsidebillede uploadet", "features": "Funktioner", + "features_in_development": "Funktioner under udvikling", "features_setting_description": "Administrer app-funktioner", "file_name": "Filnavn", "file_name_or_extension": "Filnavn eller filtype", @@ -1218,6 +1235,7 @@ "local": "Lokal", "local_asset_cast_failed": "Kan ikke caste et aktiv, der ikke er uploadet til serveren", "local_assets": "Lokale objekter", + "local_media_summary": "Opsummering af lokale media", "local_network": "Lokalt netværk", "local_network_sheet_info": "Appen vil oprette forbindelse til serveren via denne URL, når du bruger det angivne WiFi-netværk", "location_permission": "Tilladelse til placering", @@ -1229,6 +1247,7 @@ "location_picker_longitude_hint": "Indtast din længdegrad her", "lock": "Lås", "locked_folder": "Låst mappe", + "log_detail_title": "Logdetaljer", "log_out": "Log ud", "log_out_all_devices": "Log ud af alle enheder", "logged_in_as": "Logget ind som {user}", @@ -1259,6 +1278,7 @@ "login_password_changed_success": "Kodeordet blev opdateret", "logout_all_device_confirmation": "Er du sikker på, at du vil logge ud af alle enheder?", "logout_this_device_confirmation": "Er du sikker på, at du vil logge denne enhed ud?", + "logs": "Logs", "longitude": "Længdegrad", "look": "Kig", "loop_videos": "Gentag videoer", @@ -1301,6 +1321,7 @@ "mark_as_read": "Marker som læst", "marked_all_as_read": "Markerede alle som læst", "matches": "Parringer", + "matching_assets": "Matchende objekter", "media_type": "Medietype", "memories": "Minder", "memories_all_caught_up": "Ajour", @@ -1341,6 +1362,7 @@ "name_or_nickname": "Navn eller kælenavn", "network_requirement_photos_upload": "Benyt mobildatanettet for at sikkerhedskopiere dine fotos", "network_requirement_videos_upload": "Benyt mobildatanettet for at sikkerhedskopiere dine videoer", + "network_requirements": "Netværkskrav", "network_requirements_updated": "Netværkskravene er ændret, backup-køen nulstilles", "networking_settings": "Netværk", "networking_subtitle": "Administrer serverens endepunktindstillinger", @@ -1351,6 +1373,7 @@ "new_person": "Ny person", "new_pin_code": "Ny PIN kode", "new_pin_code_subtitle": "Dette er første gang du tilgår den låste mappe. Lav en PIN kode for sikkert at tilgå denne side", + "new_timeline": "Ny tidslinje", "new_user_created": "Ny bruger oprettet", "new_version_available": "NY VERSION TILGÆNGELIG", "newest_first": "Nyeste først", @@ -1364,20 +1387,25 @@ "no_assets_message": "KLIK FOR AT UPLOADE DIT FØRSTE BILLEDE", "no_assets_to_show": "Ingen elementer at vise", "no_cast_devices_found": "Ingen Cast-enheder fundet", + "no_checksum_local": "Ingen checksum tilgængelig – kan ikke hente lokale objekter", + "no_checksum_remote": "Ingen checksum tilgængelig – kan ikke hente eksterne objekter", "no_duplicates_found": "Ingen duplikater fundet.", "no_exif_info_available": "Ingen tilgængelig exif information", "no_explore_results_message": "Upload flere billeder for at udforske din samling.", "no_favorites_message": "Tilføj favoritter for hurtigt at finde dine bedst billeder og videoer", "no_libraries_message": "Opret et eksternt bibliotek for at se dine billeder og videoer", + "no_local_assets_found": "Ingen lokale objekter fundet med denne checksum", "no_locked_photos_message": "Billeder og videoer i den låste mappe er skjulte og vil ikke blive vist i dit bibliotek.", "no_name": "Intet navn", "no_notifications": "Ingen notifikationer", "no_people_found": "Ingen tilsvarende personer fundet", "no_places": "Ingen steder", + "no_remote_assets_found": "Ingen eksterne objekter fundet med denne checksum", "no_results": "Ingen resultater", "no_results_description": "Prøv et synonym eller et mere generelt søgeord", "no_shared_albums_message": "Opret et album for at dele billeder og videoer med personer i dit netværk", "no_uploads_in_progress": "Ingen upload i gang", + "not_available": "ikke tilgængelig", "not_in_any_album": "Ikke i noget album", "not_selected": "Ikke valgt", "note_apply_storage_label_to_previously_uploaded assets": "Bemærk: For at anvende Lagringsmærkat på tidligere uploadede medier, kør", @@ -1499,6 +1527,7 @@ "port": "Port", "preferences_settings_subtitle": "Administrer app-præferencer", "preferences_settings_title": "Præferencer", + "preparing": "Forberedelse", "preset": "Forudindstilling", "preview": "Forhåndsvisning", "previous": "Forrige", @@ -1564,6 +1593,7 @@ "read_changelog": "Læs ændringslog", "readonly_mode_disabled": "Skrivebeskyttet tilstand deaktiveret", "readonly_mode_enabled": "Skrivebeskyttet tilstand aktiveret", + "ready_for_upload": "Klar til upload", "reassign": "Gentildel", "reassigned_assets_to_existing_person": "{count, plural, one {# mediefil} other {# mediefiler}} er blevet gentildelt til {name, select, null {en eksisterende person} other {{name}}}", "reassigned_assets_to_new_person": "Gentildelt {count, plural, one {# aktiv} other {# aktiver}} til en ny person", @@ -1588,6 +1618,7 @@ "regenerating_thumbnails": "Regenererer forhåndsvisninger", "remote": "Eksternt", "remote_assets": "Eksterne objekter", + "remote_media_summary": "Oversigt over eksterne media", "remove": "Fjern", "remove_assets_album_confirmation": "Er du sikker på, at du vil fjerne {count, plural, one {# aktiv} other {# aktiver}} fra albummet?", "remove_assets_shared_link_confirmation": "Er du sikker på, at du vil fjerne {count, plural, one {# aktiv} other {# aktiver}} fra dette delte link?", @@ -1863,6 +1894,7 @@ "show_slideshow_transition": "Vis overgang til diasshow", "show_supporter_badge": "Supportermærke", "show_supporter_badge_description": "Vis et supportermærke", + "show_text_search_menu": "Vis tekstsøgningsmenu", "shuffle": "Bland", "sidebar": "Sidebjælke", "sidebar_display_description": "Vis et link til visningen i sidebjælken", @@ -1893,6 +1925,7 @@ "stacktrace": "Stacktrace", "start": "Start", "start_date": "Startdato", + "start_date_before_end_date": "Startdato skal ligge før slutdato", "state": "Stat", "status": "Status", "stop_casting": "Stop støbning", @@ -2095,5 +2128,6 @@ "yes": "Ja", "you_dont_have_any_shared_links": "Du har ikke nogen delte links", "your_wifi_name": "Dit Wi-Fi navn", - "zoom_image": "Zoom billede" + "zoom_image": "Zoom billede", + "zoom_to_bounds": "Zoom til grænserne" } diff --git a/i18n/de.json b/i18n/de.json index c6317a25bb..4af1675ffc 100644 --- a/i18n/de.json +++ b/i18n/de.json @@ -28,6 +28,7 @@ "add_to_album": "Zu Album hinzufügen", "add_to_album_bottom_sheet_added": "Zu {album} hinzugefügt", "add_to_album_bottom_sheet_already_exists": "Bereits in {album}", + "add_to_album_bottom_sheet_some_local_assets": "Einige lokale Dateien konnten nicht zum Album hinzugefügt werden", "add_to_album_toggle": "Auswahl umschalten für {album}", "add_to_albums": "Zu Alben hinzufügen", "add_to_albums_count": "Zu Alben hinzufügen ({count})", @@ -123,6 +124,13 @@ "logging_enable_description": "Aktiviere Logging", "logging_level_description": "Wenn aktiviert, welches Log-Level genutzt wird.", "logging_settings": "Protokollierung", + "machine_learning_availability_checks": "Verfügbarkeitschecks", + "machine_learning_availability_checks_description": "Erkenne und bevorzuge verfügbare Machine Learning Servers", + "machine_learning_availability_checks_enabled": "Verfügbarkeitschecks einschalten", + "machine_learning_availability_checks_interval": "Überprüfungsinterval", + "machine_learning_availability_checks_interval_description": "Interval in Millisekunden zwischen Verfügbarkeitschecks", + "machine_learning_availability_checks_timeout": "Anfragenzeitüberschreitung", + "machine_learning_availability_checks_timeout_description": "Zeitüberschreitung in Millisekunden für Verfügbarkeitschecks", "machine_learning_clip_model": "CLIP-Modell", "machine_learning_clip_model_description": "Der Name eines CLIP-Modells, welches hier aufgeführt ist. Beachte, dass du die Aufgabe \"Intelligente Suche\" für alle Bilder erneut ausführen musst, wenn du das Modell wechselst.", "machine_learning_duplicate_detection": "Duplikaterkennung", @@ -387,8 +395,6 @@ "admin_password": "Administrator Passwort", "administration": "Verwaltung", "advanced": "Erweitert", - "advanced_settings_beta_timeline_subtitle": "Probier die neue App-Erfahrung aus", - "advanced_settings_beta_timeline_title": "Beta-Timeline", "advanced_settings_enable_alternate_media_filter_subtitle": "Verwende diese Option, um Medien während der Synchronisierung nach anderen Kriterien zu filtern. Versuchen dies nur, wenn Probleme mit der Erkennung aller Alben durch die App auftreten.", "advanced_settings_enable_alternate_media_filter_title": "[EXPERIMENTELL] Benutze alternativen Filter für Synchronisierung der Gerätealben", "advanced_settings_log_level_title": "Log-Level: {level}", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "Bist du sicher, dass du {user} entfernen willst?", "album_search_not_found": "Keine Alben gefunden, die zur Suche passen", "album_share_no_users": "Es sieht so aus, als hättest du dieses Album mit allen Benutzern geteilt oder du hast keine Benutzer, mit denen du teilen kannst.", + "album_summary": "Album Zusammenfassung", "album_updated": "Album aktualisiert", "album_updated_setting_description": "Erhalte eine E-Mail-Benachrichtigung, wenn ein freigegebenes Album neue Dateien enthält", "album_user_left": "{album} verlassen", @@ -496,6 +503,8 @@ "asset_restored_successfully": "Datei erfolgreich wiederhergestellt", "asset_skipped": "Übersprungen", "asset_skipped_in_trash": "Im Papierkorb", + "asset_trashed": "Datei Gelöscht", + "asset_troubleshoot": "Datei Fehlerbehebung", "asset_uploaded": "Hochgeladen", "asset_uploading": "Hochladen…", "asset_viewer_settings_subtitle": "Verwaltung der Einstellungen für die Fotoanzeige", @@ -529,8 +538,10 @@ "autoplay_slideshow": "Automatische Diashow", "back": "Zurück", "back_close_deselect": "Zurück, Schließen oder Abwählen", + "background_backup_running_error": "Hintergrund Sicherung läuft, kann manuelle Sicherung nicht starten", "background_location_permission": "Hintergrund Standortfreigabe", "background_location_permission_content": "Um im Hintergrund zwischen den Netzwerken wechseln zu können, muss Immich *immer* Zugriff auf den genauen Standort haben, damit die App den Namen des WLAN-Netzwerks ermitteln kann", + "background_options": "Hintergrund Optionen", "backup": "Sicherung", "backup_album_selection_page_albums_device": "Alben auf dem Gerät ({count})", "backup_album_selection_page_albums_tap": "Einmalig das Album antippen um es zu sichern, doppelt antippen um es nicht mehr zu sichern", @@ -538,6 +549,7 @@ "backup_album_selection_page_select_albums": "Alben auswählen", "backup_album_selection_page_selection_info": "Information", "backup_album_selection_page_total_assets": "Elemente", + "backup_albums_sync": "Synchronisation von Alben beim Backup", "backup_all": "Alle", "backup_background_service_backup_failed_message": "Es trat ein Fehler bei der Sicherung auf. Erneuter Versuch…", "backup_background_service_connection_failed_message": "Es konnte keine Verbindung zum Server hergestellt werden. Erneuter Versuch…", @@ -654,6 +666,8 @@ "change_pin_code": "PIN Code ändern", "change_your_password": "Ändere dein Passwort", "changed_visibility_successfully": "Die Sichtbarkeit wurde erfolgreich geändert", + "charging": "Aufladen", + "charging_requirement_mobile_backup": "Backup im Hintergrund erfordert Aufladen des Geräts", "check_corrupt_asset_backup": "Auf beschädigte Asset-Backups überprüfen", "check_corrupt_asset_backup_button": "Überprüfung durchführen", "check_corrupt_asset_backup_description": "Führe diese Prüfung nur mit aktivierten WLAN durch, nachdem alle Dateien gesichert worden sind. Dieser Vorgang kann ein paar Minuten dauern.", @@ -740,6 +754,7 @@ "create_user": "Nutzer erstellen", "created": "Erstellt", "created_at": "Erstellt", + "creating_linked_albums": "Erstelle verknüpfte Alben...", "crop": "Zuschneiden", "curated_object_page_title": "Dinge", "current_device": "Aktuelles Gerät", @@ -889,7 +904,9 @@ "error": "Fehler", "error_change_sort_album": "Ändern der Anzeigereihenfolge fehlgeschlagen", "error_delete_face": "Fehler beim Löschen des Gesichts", + "error_getting_places": "Fehler beim Abrufen der Orte", "error_loading_image": "Fehler beim Laden des Bildes", + "error_loading_partners": "Fehler beim Laden der Partner: {error}", "error_saving_image": "Fehler: {error}", "error_tag_face_bounding_box": "Fehler beim Markieren des Gesichts - Begrenzungen können nicht abgerufen werden", "error_title": "Fehler - Etwas ist schief gelaufen", @@ -1054,6 +1071,7 @@ "favorites_page_no_favorites": "Keine favorisierten Inhalte gefunden", "feature_photo_updated": "Profilbild aktualisiert", "features": "Funktionen", + "features_in_development": "Feature in Entwicklung", "features_setting_description": "Funktionen der App verwalten", "file_name": "Dateiname", "file_name_or_extension": "Dateiname oder -erweiterung", @@ -1190,7 +1208,7 @@ "large_files": "Große Dateien", "last": "Letzte", "last_seen": "Zuletzt gesehen", - "latest_version": "Aktuellste Version", + "latest_version": "Aktuelle Version", "latitude": "Breitengrad", "leave": "Verlassen", "leave_album": "Album verlassen", @@ -1218,6 +1236,7 @@ "local": "Lokal", "local_asset_cast_failed": "Eine Datei, die nicht auf den Server hochgeladen wurde, kann nicht gecastet werden", "local_assets": "Lokale Dateien", + "local_media_summary": "Zusammenfassung der lokalen Medien", "local_network": "Lokales Netzwerk", "local_network_sheet_info": "Die App stellt über diese URL eine Verbindung zum Server her, wenn sie das angegebene WLAN-Netzwerk verwendet", "location_permission": "Standort Genehmigung", @@ -1229,6 +1248,7 @@ "location_picker_longitude_hint": "Längengrad eingeben", "lock": "Sperren", "locked_folder": "Gesperrter Ordner", + "log_detail_title": "Protokoll Details", "log_out": "Abmelden", "log_out_all_devices": "Alle Geräte abmelden", "logged_in_as": "Angemeldet als {user}", @@ -1259,6 +1279,7 @@ "login_password_changed_success": "Passwort erfolgreich geändert", "logout_all_device_confirmation": "Bist du sicher, dass du alle Geräte abmelden willst?", "logout_this_device_confirmation": "Bist du sicher, dass du dieses Gerät abmelden willst?", + "logs": "Protokolle", "longitude": "Längengrad", "look": "Erscheinungsbild", "loop_videos": "Loop-Videos", @@ -1301,6 +1322,7 @@ "mark_as_read": "Als gelesen markieren", "marked_all_as_read": "Alle als gelesen markiert", "matches": "Treffer", + "matching_assets": "Passende Dateien", "media_type": "Medientyp", "memories": "Erinnerungen", "memories_all_caught_up": "Alles aufgeholt", @@ -1339,8 +1361,9 @@ "my_albums": "Meine Alben", "name": "Name", "name_or_nickname": "Name oder Nickname", - "network_requirement_photos_upload": "Mobiles Datennetz verwenden, um Fotos zu sichern", - "network_requirement_videos_upload": "Mobiles Datennetz verwenden, um Videos zu sichern", + "network_requirement_photos_upload": "Mobile Daten verwenden, um Fotos zu sichern", + "network_requirement_videos_upload": "Mobile Daten verwenden, um Videos zu sichern", + "network_requirements": "Anforderungen ans Netzwerk", "network_requirements_updated": "Netzwerk-Abhängigkeiten haben sich geändert, Backup-Warteschlange wird zurückgesetzt", "networking_settings": "Netzwerk", "networking_subtitle": "Verwaltung von Server-Endpunkt-Einstellungen", @@ -1351,6 +1374,7 @@ "new_person": "Neue Person", "new_pin_code": "Neuer PIN Code", "new_pin_code_subtitle": "Dies ist dein erster Zugriff auf den gesperrten Ordner. Erstelle einen PIN Code für den sicheren Zugriff auf diese Seite", + "new_timeline": "Neue Zeitleiste", "new_user_created": "Neuer Benutzer wurde erstellt", "new_version_available": "NEUE VERSION VERFÜGBAR", "newest_first": "Neueste zuerst", @@ -1364,20 +1388,25 @@ "no_assets_message": "KLICKE, UM DEIN ERSTES FOTO HOCHZULADEN", "no_assets_to_show": "Keine Vorschau vorhanden", "no_cast_devices_found": "Keine Geräte zum Übertragen gefunden", + "no_checksum_local": "Prüfsumme nicht verfügbar - kann lokale Datei/en nicht laden", + "no_checksum_remote": "Prüfsumme nicht verfügbar - kann entfernte Datei/en nicht laden", "no_duplicates_found": "Es wurden keine Duplikate gefunden.", "no_exif_info_available": "Keine EXIF-Informationen vorhanden", "no_explore_results_message": "Lade weitere Fotos hoch, um deine Sammlung zu erkunden.", "no_favorites_message": "Füge Favoriten hinzu, um deine besten Bilder und Videos schnell zu finden", "no_libraries_message": "Eine externe Bibliothek erstellen, um deine Fotos und Videos anzusehen", + "no_local_assets_found": "Keine lokale Datei mit dieser Prüfsumme gefunden", "no_locked_photos_message": "Fotos und Videos im gesperrten Ordner sind versteckt und werden nicht angezeigt, wenn du deine Bibliothek durchsuchst.", "no_name": "Kein Name", "no_notifications": "Keine Benachrichtigungen", "no_people_found": "Keine passenden Personen gefunden", "no_places": "Keine Orte", + "no_remote_assets_found": "Keine entfernten Dateien mit dieser Prüfsumme gefunden", "no_results": "Keine Ergebnisse", "no_results_description": "Versuche es mit einem Synonym oder einem allgemeineren Stichwort", "no_shared_albums_message": "Erstelle ein Album, um Fotos und Videos mit Personen in deinem Netzwerk zu teilen", "no_uploads_in_progress": "Kein Upload in Bearbeitung", + "not_available": "N/A", "not_in_any_album": "In keinem Album", "not_selected": "Nicht ausgewählt", "note_apply_storage_label_to_previously_uploaded assets": "Hinweis: Um eine Speicherpfadbezeichnung anzuwenden, starte den", @@ -1475,7 +1504,7 @@ "person": "Person", "person_age_months": "{months, plural, one {# month} other {# months}} alt", "person_age_year_months": "1 Jahr, {months, plural, one {# month} other {# months}} alt", - "person_age_years": "{years, plural, other {# years}} alt", + "person_age_years": "{years, plural, one {# Jahr} other {# Jahre}} alt", "person_birthdate": "Geboren am {date}", "person_hidden": "{name}{hidden, select, true { (verborgen)} other {}}", "photo_shared_all_users": "Es sieht so aus, als hättest du deine Fotos mit allen Benutzern geteilt oder du hast keine Benutzer, mit denen du teilen kannst.", @@ -1499,6 +1528,7 @@ "port": "Port", "preferences_settings_subtitle": "App-Einstellungen verwalten", "preferences_settings_title": "Voreinstellungen", + "preparing": "Vorbereiten", "preset": "Voreinstellung", "preview": "Vorschau", "previous": "Vorherige", @@ -1541,7 +1571,7 @@ "purchase_license_subtitle": "Kaufe Immich, um die fortlaufende Entwicklung zu unterstützen", "purchase_lifetime_description": "Lebenslange Gültigkeit", "purchase_option_title": "KAUFOPTIONEN", - "purchase_panel_info_1": "Die Entwicklung von Immich erfordert viel Zeit und Mühe, und wir haben Vollzeit-Entwickler, die daran arbeiten es möglichst perfekt zu machen. Unser Ziel ist es, dass Open-Source-Software und moralische Geschäftsmethoden zu einer nachhaltigen Einkommensquelle für Entwickler werden und ein datenschutzfreundliches Ökosystem mit echten Alternativen zu ausbeuterischen Cloud-Diensten geschaffen wird.", + "purchase_panel_info_1": "Die Entwicklung von Immich erfordert viel Zeit und Mühe und wir haben Vollzeit-Entwickler, die daran arbeiten Immich möglichst perfekt zu machen. Unser Ziel ist es, Open-Source-Software und ethische Geschäftspraktiken zu einer verlässlichen Einkommensquelle für Entwickler zu machen und ein datenschutzfreundliches Ökosystem mit echten Alternativen zu ausbeuterischen Cloud-Diensten zu schaffen.", "purchase_panel_info_2": "Weil wir uns dagegen entschieden haben, eine Bezahlschranke einzusetzen, wird dieser Kauf keine zusätzlichen Funktionen in Immich freischalten. Wir verlassen uns auf Nutzende wie dich, um die Entwicklung von Immich zu unterstützen.", "purchase_panel_title": "Das Projekt unterstützen", "purchase_per_server": "Pro Server", @@ -1564,6 +1594,7 @@ "read_changelog": "Changelog lesen", "readonly_mode_disabled": "Schreibgeschützter Modus deaktiviert", "readonly_mode_enabled": "Schreibgeschützter Modus aktiviert", + "ready_for_upload": "Bereit zum Hochladen", "reassign": "Neu zuweisen", "reassigned_assets_to_existing_person": "{count, plural, one {# Datei wurde} other {# Dateien wurden}} {name, select, null {einer vorhandenen Person} other {{name}}} zugewiesen", "reassigned_assets_to_new_person": "{count, plural, one {# Datei wurde} other {# Dateien wurden}} einer neuen Person zugewiesen", @@ -1588,6 +1619,7 @@ "regenerating_thumbnails": "Miniaturansichten werden neu erstellt", "remote": "Server", "remote_assets": "Server-Dateien", + "remote_media_summary": "Zusammenfassung der entfernten Medien", "remove": "Entfernen", "remove_assets_album_confirmation": "Bist du sicher, dass du {count, plural, one {# Datei} other {# Dateien}} aus dem Album entfernen willst?", "remove_assets_shared_link_confirmation": "Bist du sicher, dass du {count, plural, one {# Datei} other {# Dateien}} von diesem geteilten Link entfernen willst?", @@ -1863,6 +1895,7 @@ "show_slideshow_transition": "Slideshow-Übergang anzeigen", "show_supporter_badge": "Unterstützerabzeichen", "show_supporter_badge_description": "Zeige Unterstützerabzeichen", + "show_text_search_menu": "Zeige Menü für Textsuche", "shuffle": "Durchmischen", "sidebar": "Seitenleiste", "sidebar_display_description": "Zeige einen Link zu der Ansicht in der Seitenleiste an", @@ -1893,6 +1926,7 @@ "stacktrace": "Stapelaufgaben", "start": "Starten", "start_date": "Anfangsdatum", + "start_date_before_end_date": "Anfangsdatum muss vor dem Enddatum liegen", "state": "Bundesland / Provinz", "status": "Status", "stop_casting": "Übertragung stoppen", @@ -2095,5 +2129,6 @@ "yes": "Ja", "you_dont_have_any_shared_links": "Du hast keine geteilten Links", "your_wifi_name": "Dein WLAN-Name", - "zoom_image": "Bild vergrößern" + "zoom_image": "Bild vergrößern", + "zoom_to_bounds": "In die Grenzen zoomen" } diff --git a/i18n/el.json b/i18n/el.json index 2dff77a48f..6e2f543c1f 100644 --- a/i18n/el.json +++ b/i18n/el.json @@ -123,6 +123,13 @@ "logging_enable_description": "Ενεργοποίηση καταγραφής συμβάντων", "logging_level_description": "Το επίπεδο καταγραφής συμβάντων που θα εφαρμοστεί, όταν αυτή είναι ενεργοποιημένη.", "logging_settings": "Καταγραφή Συμβάντων", + "machine_learning_availability_checks": "Έλεγχοι διαθεσιμότητας", + "machine_learning_availability_checks_description": "Αυτόματος ανίχνευση και προτίμηση διαθέσιμων διακομιστών μηχανικής μάθησης", + "machine_learning_availability_checks_enabled": "Ενεργοποίηση ελέγχων διαθεσιμότητας", + "machine_learning_availability_checks_interval": "Διάστημα ελέγχου", + "machine_learning_availability_checks_interval_description": "Διάστημα σε χιλιοστά δευτερολέπτου μεταξύ των ελέγχων διαθεσιμότητας", + "machine_learning_availability_checks_timeout": "Αίτημα χρονικού ορίου λήξης", + "machine_learning_availability_checks_timeout_description": "Χρονικό όριο σε χιλιοστά δευτερολέπτου για ελέγχους διαθεσιμότητας", "machine_learning_clip_model": "Μοντέλο CLIP", "machine_learning_clip_model_description": "Το όνομα ενός μοντέλου CLIP που αναφέρεται εδώ. Σημειώστε ότι πρέπει να επανεκτελέσετε την εργασία 'Έξυπνη Αναζήτηση' για όλες τις εικόνες μετά την αλλαγή μοντέλου.", "machine_learning_duplicate_detection": "Εντοπισμός Διπλότυπων", @@ -387,8 +394,6 @@ "admin_password": "Κωδικός πρόσβασης Διαχειριστή", "administration": "Διαχείριση", "advanced": "Για προχωρημένους", - "advanced_settings_beta_timeline_subtitle": "Δοκίμασε τη νέα εμπειρία της εφαρμογής", - "advanced_settings_beta_timeline_title": "Δοκιμαστικό χρονολόγιο", "advanced_settings_enable_alternate_media_filter_subtitle": "Χρησιμοποιήστε αυτήν την επιλογή για να φιλτράρετε τα μέσα ενημέρωσης κατά τον συγχρονισμό με βάση εναλλακτικά κριτήρια. Δοκιμάστε αυτή τη δυνατότητα μόνο αν έχετε προβλήματα με την εφαρμογή που εντοπίζει όλα τα άλμπουμ.", "advanced_settings_enable_alternate_media_filter_title": "[ΠΕΙΡΑΜΑΤΙΚΟ] Χρήση εναλλακτικού φίλτρου συγχρονισμού άλμπουμ συσκευής", "advanced_settings_log_level_title": "Επίπεδο σύνδεσης: {level}", @@ -396,6 +401,8 @@ "advanced_settings_prefer_remote_title": "Προτίμηση απομακρυσμένων εικόνων", "advanced_settings_proxy_headers_subtitle": "Καθορισμός κεφαλίδων διακομιστή μεσολάβησης που το Immich πρέπει να στέλνει με κάθε αίτημα δικτύου", "advanced_settings_proxy_headers_title": "Κεφαλίδες διακομιστή μεσολάβησης", + "advanced_settings_readonly_mode_subtitle": "Ενεργοποιεί τη λειτουργία μόνο-για-ανάγνωση, όπου οι φωτογραφίες μπορούν μόνο να προβληθούν. Ενέργειες όπως επιλογή πολλών εικόνων, κοινή χρήση, αποστολή (casting) και διαγραφή είναι απενεργοποιημένες. Η ενεργοποίηση/απενεργοποίηση της λειτουργίας μόνο-για-ανάγνωση γίνεται μέσω της εικόνας του χρήστη από την κεντρική οθόνη", + "advanced_settings_readonly_mode_title": "Λειτουργία μόνο-για-ανάγνωση", "advanced_settings_self_signed_ssl_subtitle": "Παρακάμπτει τον έλεγχο πιστοποιητικού SSL του διακομιστή. Απαραίτητο για αυτο-υπογεγραμμένα πιστοποιητικά.", "advanced_settings_self_signed_ssl_title": "Να επιτρέπονται αυτο-υπογεγραμμένα πιστοποιητικά SSL", "advanced_settings_sync_remote_deletions_subtitle": "Αυτόματη διαγραφή ή επαναφορά ενός περιουσιακού στοιχείου σε αυτή τη συσκευή, όταν η ενέργεια αυτή πραγματοποιείται στο διαδίκτυο", @@ -423,6 +430,7 @@ "album_remove_user_confirmation": "Είστε σίγουροι ότι θέλετε να αφαιρέσετε τον/την {user};", "album_search_not_found": "Δε βρέθηκαν άλμπουμ που να ταιριάζουν με την αναζήτησή σας", "album_share_no_users": "Φαίνεται ότι έχετε κοινοποιήσει αυτό το άλμπουμ σε όλους τους χρήστες ή δεν έχετε χρήστες για να το κοινοποιήσετε.", + "album_summary": "Περίληψη άλμπουμ", "album_updated": "Το άλμπουμ, ενημερώθηκε", "album_updated_setting_description": "Λάβετε ειδοποίηση μέσω email όταν ένα κοινόχρηστο άλμπουμ έχει νέα αρχεία", "album_user_left": "Αποχωρήσατε από το {album}", @@ -461,6 +469,7 @@ "app_bar_signout_dialog_title": "Αποσύνδεση", "app_settings": "Ρυθμίσεις εφαρμογής", "appears_in": "Εμφανίζεται σε", + "apply_count": "Εφαρμογή ({count, number})", "archive": "Αρχείο", "archive_action_prompt": "Προστέθηκαν {count} στο Αρχείο", "archive_or_unarchive_photo": "Αρχειοθέτηση ή αποαρχειοθέτηση φωτογραφίας", @@ -493,6 +502,8 @@ "asset_restored_successfully": "Το στοιχείο αποκαταστάθηκε με επιτυχία", "asset_skipped": "Παραλείφθηκε", "asset_skipped_in_trash": "Στον κάδο απορριμμάτων", + "asset_trashed": "Το στοιχείο διαγράφηκε", + "asset_troubleshoot": "Αντιμετώπιση προβλήματος στοιχείου", "asset_uploaded": "Ανεβάστηκε", "asset_uploading": "Ανεβάζεται…", "asset_viewer_settings_subtitle": "Διαχείριση ρυθμίσεων προβολής συλλογής", @@ -526,8 +537,10 @@ "autoplay_slideshow": "Αυτόματη αναπαραγωγή παρουσίασης", "back": "Πίσω", "back_close_deselect": "Πίσω, κλείσιμο ή αποεπιλογή", + "background_backup_running_error": "Η δημιουργία αντιγράφων ασφάλειας στο παρασκήνιο εκτελείται ήδη, δεν μπορεί να ξεκινήσετε χειροκίνητο αντίγραφο ασφάλειας", "background_location_permission": "Άδεια τοποθεσίας στο παρασκήνιο", "background_location_permission_content": "Το Immich για να μπορεί να αλλάζει δίκτυα όταν τρέχει στο παρασκήνιο, πρέπει *πάντα* να έχει πρόσβαση στην ακριβή τοποθεσία ώστε η εφαρμογή να μπορεί να διαβάζει το όνομα του δικτύου Wi-Fi", + "background_options": "Επιλογές παρασκηνίου", "backup": "Αντίγραφο ασφαλείας", "backup_album_selection_page_albums_device": "Άλμπουμ στη συσκευή ({count})", "backup_album_selection_page_albums_tap": "Πάτημα για συμπερίληψη, διπλό πάτημα για εξαίρεση", @@ -535,6 +548,7 @@ "backup_album_selection_page_select_albums": "Επιλογή άλμπουμ", "backup_album_selection_page_selection_info": "Πληροφορίες επιλογής", "backup_album_selection_page_total_assets": "Συνολικά μοναδικά στοιχεία", + "backup_albums_sync": "Συγχρονισμός αντιγράφων ασφαλείας άλμπουμ", "backup_all": "Όλα", "backup_background_service_backup_failed_message": "Αποτυχία δημιουργίας αντιγράφων ασφαλείας. Επανάληψη…", "backup_background_service_connection_failed_message": "Αποτυχία σύνδεσης με το διακομιστή. Επανάληψη…", @@ -651,6 +665,8 @@ "change_pin_code": "Αλλαγή κωδικού PIN", "change_your_password": "Αλλάξτε τον κωδικό σας", "changed_visibility_successfully": "Η προβολή, άλλαξε με επιτυχία", + "charging": "Φόρτιση", + "charging_requirement_mobile_backup": "Η δημιουργία αντιγράφων ασφάλειας στο παρασκήνιο απαιτεί η συσκευή να φορτίζει", "check_corrupt_asset_backup": "Έλεγχος για κατεστραμμένα αντίγραφα ασφαλείας στοιχείων", "check_corrupt_asset_backup_button": "Εκτέλεση ελέγχου", "check_corrupt_asset_backup_description": "Εκτέλεσε αυτόν τον έλεγχο μόνο μέσω Wi-Fi και αφού έχουν αποθηκευτεί όλα τα αντίγραφα ασφαλείας των στοιχείων. Η διαδικασία μπορεί να διαρκέσει μερικά λεπτά.", @@ -737,6 +753,7 @@ "create_user": "Δημιουργία χρήστη", "created": "Δημιουργήθηκε", "created_at": "Δημιουργήθηκε", + "creating_linked_albums": "Δημιουργία συνδεδεμένων άλμπουμ...", "crop": "Αποκοπή", "curated_object_page_title": "Πράγματα", "current_device": "Τρέχουσα συσκευή", @@ -886,7 +903,9 @@ "error": "Σφάλμα", "error_change_sort_album": "Απέτυχε η αλλαγή σειράς του άλμπουμ", "error_delete_face": "Σφάλμα διαγραφής προσώπου από το στοιχείο", + "error_getting_places": "Σφάλμα κατά την ανάκτηση τοποθεσιών", "error_loading_image": "Σφάλμα κατά τη φόρτωση της εικόνας", + "error_loading_partners": "Σφάλμα κατά τη φόρτωση συνεργατών: {error}", "error_saving_image": "Σφάλμα: {error}", "error_tag_face_bounding_box": "Σφάλμα επισήμανσης προσώπου - δεν μπορούν να ληφθούν οι συντεταγμένες του πλαισίου οριοθέτησης", "error_title": "Σφάλμα - Κάτι πήγε στραβά", @@ -1051,6 +1070,7 @@ "favorites_page_no_favorites": "Δεν βρέθηκαν αγαπημένα στοιχεία", "feature_photo_updated": "Η φωτογραφία προβολής ενημερώθηκε", "features": "Χαρακτηριστικά", + "features_in_development": "Λειτουργίες υπό Ανάπτυξη", "features_setting_description": "Διαχειριστείτε τα χαρακτηριστικά της εφαρμογής", "file_name": "Όνομα αρχείου", "file_name_or_extension": "Όνομα αρχείου ή επέκταση", @@ -1071,12 +1091,15 @@ "gcast_enabled": "Μετάδοση περιεχομένου Google Cast", "gcast_enabled_description": "Αυτό το χαρακτηριστικό φορτώνει εξωτερικούς πόρους από τη Google για να λειτουργήσει.", "general": "Γενικά", + "geolocation_instruction_location": "Κάνε κλικ σε ένα στοιχείο με συντεταγμένες GPS για να χρησιμοποιήσεις την τοποθεσία του, ή επίλεξε απευθείας μια τοποθεσία από τον χάρτη", "get_help": "Ζητήστε βοήθεια", "get_wifiname_error": "Δεν ήταν δυνατή η λήψη του ονόματος Wi-Fi. Βεβαιωθείτε ότι έχετε δώσει τις απαραίτητες άδειες και ότι είστε συνδεδεμένοι σε δίκτυο Wi-Fi", "getting_started": "Ξεκινώντας", "go_back": "Πηγαίνετε πίσω", "go_to_folder": "Μετάβαση στο φάκελο", "go_to_search": "Πηγαίνετε στην αναζήτηση", + "gps": "GPS", + "gps_missing": "Χωρίς GPS", "grant_permission": "Επιτρέψτε την άδεια", "group_albums_by": "Ομαδοποίηση άλμπουμ κατά...", "group_country": "Ομαδοποίηση κατά χώρα", @@ -1212,6 +1235,7 @@ "local": "Τοπικά", "local_asset_cast_failed": "Αδυναμία μετάδοσης στοιχείου που δεν έχει ανέβει στον διακομιστή", "local_assets": "Τοπικά στοιχεία", + "local_media_summary": "Περίληψη τοπικών πολυμέσων", "local_network": "Τοπικό δίκτυο", "local_network_sheet_info": "Η εφαρμογή θα συνδεθεί με τον διακομιστή μέσω αυτού του URL όταν χρησιμοποιείται το καθορισμένο δίκτυο Wi-Fi", "location_permission": "Άδεια τοποθεσίας", @@ -1223,6 +1247,7 @@ "location_picker_longitude_hint": "Εισαγάγετε εδώ το γεωγραφικό σας μήκος", "lock": "Κλείδωμα", "locked_folder": "Κλειδωμένος φάκελος", + "log_detail_title": "Λεπτομέρεια καταγραφής", "log_out": "Αποσύνδεση", "log_out_all_devices": "Αποσύνδεση από Όλες τις Συσκευές", "logged_in_as": "Συνδεδεμένος ως {user}", @@ -1253,6 +1278,7 @@ "login_password_changed_success": "Ο κωδικός πρόσβασης ενημερώθηκε με επιτυχία", "logout_all_device_confirmation": "Είστε βέβαιοι ότι θέλετε να αποσυνδεθείτε από όλες τις συσκευές;", "logout_this_device_confirmation": "Είστε βέβαιοι ότι θέλετε να αποσυνδεθείτε από αυτήν τη συσκευή;", + "logs": "Καταγραφές", "longitude": "Γεωγραφικό μήκος", "look": "Εμφάνιση", "loop_videos": "Επανάληψη βίντεο", @@ -1260,6 +1286,7 @@ "main_branch_warning": "Χρησιμοποιείτε μια έκδοση σε ανάπτυξη· συνιστούμε ανεπιφύλακτα τη χρήση μιας τελικής έκδοσης!", "main_menu": "Κύριο μενού", "make": "Κατασκευαστής", + "manage_geolocation": "Διαχείριση τοποθεσίας", "manage_shared_links": "Διαχείριση κοινόχρηστων συνδέσμων", "manage_sharing_with_partners": "Διαχειριστείτε την κοινή χρήση με συνεργάτες", "manage_the_app_settings": "Διαχειριστείτε τις ρυθμίσεις της εφαρμογής", @@ -1294,6 +1321,7 @@ "mark_as_read": "Επισήμανση ως αναγνωσμένο", "marked_all_as_read": "Όλα επισημάνθηκαν ως αναγνωσμένα", "matches": "Αντιστοιχίες", + "matching_assets": "Αντιστοιχία στοιχείων", "media_type": "Τύπος πολυμέσου", "memories": "Αναμνήσεις", "memories_all_caught_up": "Συγχρονισμένα", @@ -1334,6 +1362,7 @@ "name_or_nickname": "Όνομα ή ψευδώνυμο", "network_requirement_photos_upload": "Χρήση δεδομένων κινητής τηλεφωνίας για τη δημιουργία αντιγράφων ασφαλείας των φωτογραφιών", "network_requirement_videos_upload": "Χρήση δεδομένων κινητής τηλεφωνίας για τη δημιουργία αντιγράφων ασφαλείας των βίντεο", + "network_requirements": "Απαιτήσεις Δυκτίου", "network_requirements_updated": "Οι απαιτήσεις δικτύου άλλαξαν, γίνεται επαναφορά της ουράς αντιγράφων ασφαλείας", "networking_settings": "Δικτύωση", "networking_subtitle": "Διαχείριση ρυθμίσεων τελικών σημείων διακομιστή", @@ -1344,6 +1373,7 @@ "new_person": "Νέο άτομο", "new_pin_code": "Νέος κωδικός PIN", "new_pin_code_subtitle": "Αυτή είναι η πρώτη φορά που αποκτάτε πρόσβαση στον κλειδωμένο φάκελο. Δημιουργήστε έναν κωδικό PIN για ασφαλή πρόσβαση σε αυτή τη σελίδα", + "new_timeline": "Νέο Χρονολόγιο", "new_user_created": "Ο νέος χρήστης δημιουργήθηκε", "new_version_available": "ΔΙΑΘΕΣΙΜΗ ΝΕΑ ΕΚΔΟΣΗ", "newest_first": "Τα νεότερα πρώτα", @@ -1357,20 +1387,25 @@ "no_assets_message": "ΚΑΝΤΕ ΚΛΙΚ ΓΙΑ ΝΑ ΑΝΕΒΑΣΕΤΕ ΤΗΝ ΠΡΩΤΗ ΣΑΣ ΦΩΤΟΓΡΑΦΙΑ", "no_assets_to_show": "Δεν υπάρχουν στοιχεία προς εμφάνιση", "no_cast_devices_found": "Δε βρέθηκαν συσκευές μετάδοσης", + "no_checksum_local": "Δεν υπάρχει διαθέσιμο checksum για έλεγχο ακεραιότητας – δεν μπορούν να ανακτηθούν τα τοπικά στοιχεία", + "no_checksum_remote": "Δεν υπάρχει διαθέσιμο checksum για έλεγχο ακεραιότητας – δεν μπορούν να ανακτηθούν τα απομακρυσμένα στοιχεία", "no_duplicates_found": "Δεν βρέθηκαν διπλότυπα.", "no_exif_info_available": "Καμία πληροφορία exif διαθέσιμη", "no_explore_results_message": "Ανεβάστε περισσότερες φωτογραφίες για να περιηγηθείτε στη συλλογή σας.", "no_favorites_message": "Προσθέστε αγαπημένα για να βρείτε γρήγορα τις καλύτερες φωτογραφίες και τα βίντεό σας", "no_libraries_message": "Δημιουργήστε μια εξωτερική βιβλιοθήκη για να προβάλετε τις φωτογραφίες και τα βίντεό σας", + "no_local_assets_found": "Δεν βρέθηκαν τοπικά στοιχεία με αυτό το checksum", "no_locked_photos_message": "Οι φωτογραφίες και τα βίντεο στον κλειδωμένο φάκελο, είναι κρυμμένες και δεν θα εμφανίζονται κατά την περιήγηση ή την αναζήτηση στη βιβλιοθήκη σας.", "no_name": "Χωρίς Όνομα", "no_notifications": "Καμία ειδοποίηση", "no_people_found": "Δεν βρέθηκαν άτομα που να ταιριάζουν", "no_places": "Καμία τοποθεσία", + "no_remote_assets_found": "Δεν βρέθηκαν απομακρυσμένα στοιχεία με αυτό το checksum", "no_results": "Κανένα αποτέλεσμα", "no_results_description": "Δοκιμάστε ένα συνώνυμο ή πιο γενική λέξη-κλειδί", "no_shared_albums_message": "Δημιουργήστε ένα άλμπουμ για να μοιράζεστε φωτογραφίες και βίντεο με άτομα στο δίκτυό σας", "no_uploads_in_progress": "Καμία μεταφόρτωση σε εξέλιξη", + "not_available": "Μ/Δ (Μη Διαθέσιμο)", "not_in_any_album": "Σε κανένα άλμπουμ", "not_selected": "Δεν επιλέχθηκε", "note_apply_storage_label_to_previously_uploaded assets": "Σημείωση: Για να εφαρμόσετε την Ετικέτα Αποθήκευσης σε στοιχεία που έχουν μεταφορτωθεί προηγουμένως, εκτελέστε το", @@ -1405,6 +1440,8 @@ "open_the_search_filters": "Ανοίξτε τα φίλτρα αναζήτησης", "options": "Επιλογές", "or": "ή", + "organize_into_albums": "Οργάνωση σε άλμπουμ", + "organize_into_albums_description": "Τοποθετείστε τις υπάρχουσες φωτογραφίες σε άλμπουμ χρησιμοποιώντας τις τρέχουσες ρυθμίσεις συγχρονισμού", "organize_your_library": "Οργανώστε τη βιβλιοθήκη σας", "original": "πρωτότυπο", "other": "Άλλες", @@ -1490,6 +1527,7 @@ "port": "Θύρα", "preferences_settings_subtitle": "Διαχειριστείτε τις προτιμήσεις της εφαρμογής", "preferences_settings_title": "Προτιμήσεις", + "preparing": "Προετοιμασία", "preset": "Προκαθορισμένη ρύθμιση", "preview": "Προεπισκόπηση", "previous": "Προηγούμενο", @@ -1506,6 +1544,7 @@ "profile_drawer_client_out_of_date_minor": "Παρακαλώ ενημερώστε την εφαρμογή στην πιο πρόσφατη δευτερεύουσα έκδοση.", "profile_drawer_client_server_up_to_date": "Ο πελάτης και ο διακομιστής είναι ενημερωμένοι", "profile_drawer_github": "GitHub", + "profile_drawer_readonly_mode": "Η λειτουργία μόνο-για-ανάγνωση ενεργοποιήθηκε. Κρατήστε πατημένο το εικονίδιο του χρήστη για απενεργοποίηση.", "profile_drawer_server_out_of_date_major": "Παρακαλώ ενημερώστε τον διακομιστή στην πιο πρόσφατη κύρια έκδοση.", "profile_drawer_server_out_of_date_minor": "Παρακαλώ ενημερώστε τον διακομιστή στην πιο πρόσφατη δευτερεύουσα έκδοση.", "profile_image_of_user": "Εικόνα προφίλ του χρήστη {user}", @@ -1544,6 +1583,7 @@ "purchase_server_description_2": "Κατάσταση υποστηρικτή", "purchase_server_title": "Διακομιστής", "purchase_settings_server_activated": "Η διαχείριση του κλειδιού προϊόντος του διακομιστή γίνεται από τον διαχειριστή", + "query_asset_id": "Αναζήτηση ID Στοιχείου", "queue_status": "Τοποθέτηση στη ουρά {count} από {total}", "rating": "Αξιολόγηση με αστέρια", "rating_clear": "Εκκαθάριση αξιολόγησης", @@ -1551,6 +1591,9 @@ "rating_description": "Εμφάνιση της αξιολόγησης EXIF στον πίνακα πληροφοριών", "reaction_options": "Επιλογές αντίδρασης", "read_changelog": "Διαβάστε το Αρχείο Καταγραφής Αλλαγών", + "readonly_mode_disabled": "Η λειτουργία μόνο-για-ανάγνωση απενεργοποιήθηκε", + "readonly_mode_enabled": "Η λειτουργία μόνο-για-ανάγνωση ενεργοποιήθηκε", + "ready_for_upload": "Έτοιμο για μεταφόρτωση", "reassign": "Ανάθεση", "reassigned_assets_to_existing_person": "Η ανάθεση {count, plural, one {# αρχείου} other {# αρχείων}} στον/στην {name, select, null {έναν/μία υπάρχοντα/ουσα χρήστη} other {{name}}}", "reassigned_assets_to_new_person": "Η ανάθεση {count, plural, one {# αρχείου} other {# αρχείων}} σε νέο άτομο", @@ -1575,6 +1618,7 @@ "regenerating_thumbnails": "Οι μικρογραφίες αναγεννώνται", "remote": "Απομακρυσμένος", "remote_assets": "Απομακρυσμένα στοιχεία", + "remote_media_summary": "Περίληψη απομακρυσμένων πολυμέσων", "remove": "Αφαίρεση", "remove_assets_album_confirmation": "Είστε σίγουροι ότι θέλετε να αφαιρέσετε {count, plural, one {# στοιχείο} other {# στοιχεία}} από το άλμπουμ;", "remove_assets_shared_link_confirmation": "Είστε σίγουροι ότι θέλετε να αφαιρέσετε {count, plural, one {# στοιχείο} other {# στοιχεία}} από αυτόν τον κοινόχρηστο σύνδεσμο;", @@ -1627,6 +1671,7 @@ "restore_user": "Επαναφορά χρήστη", "restored_asset": "Ανακτήθηκε το αρχείο", "resume": "Συνέχιση", + "resume_paused_jobs": "Συνέχιση {count, plural, one {# σε παύση εργασία} other {# σε παύση εργασίες}}", "retry_upload": "Επανάληψη ανεβάσματος", "review_duplicates": "Προβολή διπλότυπων", "review_large_files": "Επισκόπηση μεγάλων αρχείων", @@ -1720,6 +1765,7 @@ "select_user_for_sharing_page_err_album": "Αποτυχία δημιουργίας άλπουμ", "selected": "Επιλεγμένοι", "selected_count": "{count, plural, other {# επιλεγμένοι}}", + "selected_gps_coordinates": "Επιλεγμένες συντεταγμένες GPS", "send_message": "Αποστολή μηνύματος", "send_welcome_email": "Αποστολή email καλωσορίσματος", "server_endpoint": "Τελικό σημείο Διακομιστή", @@ -1848,6 +1894,7 @@ "show_slideshow_transition": "Εμφάνιση μετάβασης παρουσίασης", "show_supporter_badge": "Σήμα υποστηρικτή", "show_supporter_badge_description": "Εμφάνιση σήματος υποστηρικτή", + "show_text_search_menu": "Εμφάνιση μενού αναζήτησης κειμένου", "shuffle": "Ανάμειξη", "sidebar": "Πλαϊνή μπάρα", "sidebar_display_description": "Εμφάνιση συνδέσμου για προβολή στην πλαϊνή μπάρα", @@ -1878,6 +1925,7 @@ "stacktrace": "Καταγραφή στοίβας", "start": "Έναρξη", "start_date": "Από", + "start_date_before_end_date": "Η ημερομηνία έναρξης πρέπει να είναι πριν από την ημερομηνία λήξης", "state": "Νομός", "status": "Κατάσταση", "stop_casting": "Διακοπή μετάδοσης", @@ -1902,6 +1950,8 @@ "sync_albums_manual_subtitle": "Συγχρονίστε όλα τα μεταφορτωμένα βίντεο και φωτογραφίες με τα επιλεγμένα εφεδρικά άλμπουμ", "sync_local": "Τοπικός Συγχρονισμός", "sync_remote": "Απομακρυσμένος Συγχρονισμός", + "sync_status": "Κατάσταση συγχρονισμού", + "sync_status_subtitle": "Προβολή και διαχείριση του συστήματος συγχρονισμού", "sync_upload_album_setting_subtitle": "Δημιουργήστε και ανεβάστε τις φωτογραφίες και τα βίντεό σας στα επιλεγμένα άλμπουμ στο Immich", "tag": "Ετικέτα", "tag_assets": "Ετικετοποίηση στοιχείων", @@ -1939,7 +1989,9 @@ "to_change_password": "Αλλαγή κωδικού πρόσβασης", "to_favorite": "Αγαπημένο", "to_login": "Είσοδος", + "to_multi_select": "για πολλαπλή επιλογή", "to_parent": "Μεταβείτε στο γονικό φάκελο", + "to_select": "για επιλογή", "to_trash": "Κάδος απορριμμάτων", "toggle_settings": "Εναλλαγή ρυθμίσεων", "total": "Σύνολο", @@ -1959,6 +2011,7 @@ "trash_page_select_assets_btn": "Επιλέξτε στοιχεία", "trash_page_title": "Κάδος Απορριμμάτων ({count})", "trashed_items_will_be_permanently_deleted_after": "Τα στοιχεία που βρίσκονται στον κάδο απορριμμάτων θα διαγραφούν οριστικά μετά από {days, plural, one {# ημέρα} other {# ημέρες}}.", + "troubleshoot": "Επίλυση προβλημάτων", "type": "Τύπος", "unable_to_change_pin_code": "Αδυναμία αλλαγής κωδικού PIN", "unable_to_setup_pin_code": "Αδυναμία ρύθμισης κωδικού PIN", @@ -1989,6 +2042,7 @@ "unstacked_assets_count": "Αποστοιβάξατε {count, plural, one {# στοιχείο} other {# στοιχεία}}", "untagged": "Χωρίς ετικέτα", "up_next": "Ακολουθεί", + "update_location_action_prompt": "Ενημέρωση τοποθεσίας για {count} επιλεγμένα στοιχεία με:", "updated_at": "Ενημερωμένο", "updated_password": "Ο κωδικός πρόσβασης ενημερώθηκε", "upload": "Μεταφόρτωση", @@ -2055,6 +2109,7 @@ "view_next_asset": "Προβολή επόμενου στοιχείου", "view_previous_asset": "Προβολή προηγούμενου στοιχείου", "view_qr_code": "Προβολή κωδικού QR", + "view_similar_photos": "Προβολή παρόμοιων φωτογραφιών", "view_stack": "Προβολή της στοίβας", "view_user": "Προβολή Χρήστη", "viewer_remove_from_stack": "Κατάργηση από τη Στοίβα", @@ -2073,5 +2128,6 @@ "yes": "Ναι", "you_dont_have_any_shared_links": "Δεν έχετε κοινόχρηστους συνδέσμους", "your_wifi_name": "Το όνομα του Wi-Fi σας", - "zoom_image": "Ζουμ Εικόνας" + "zoom_image": "Ζουμ Εικόνας", + "zoom_to_bounds": "Εστίαση στα όρια" } diff --git a/i18n/en.json b/i18n/en.json index b5fd0955d1..12c29686aa 100644 --- a/i18n/en.json +++ b/i18n/en.json @@ -28,6 +28,7 @@ "add_to_album": "Add to album", "add_to_album_bottom_sheet_added": "Added to {album}", "add_to_album_bottom_sheet_already_exists": "Already in {album}", + "add_to_album_bottom_sheet_some_local_assets": "Some local assets could not be added to album", "add_to_album_toggle": "Toggle selection for {album}", "add_to_albums": "Add to albums", "add_to_albums_count": "Add to albums ({count})", @@ -123,6 +124,13 @@ "logging_enable_description": "Enable logging", "logging_level_description": "When enabled, what log level to use.", "logging_settings": "Logging", + "machine_learning_availability_checks": "Availability checks", + "machine_learning_availability_checks_description": "Automatically detect and prefer available machine learning servers", + "machine_learning_availability_checks_enabled": "Enable availability checks", + "machine_learning_availability_checks_interval": "Check interval", + "machine_learning_availability_checks_interval_description": "Interval in milliseconds between availability checks", + "machine_learning_availability_checks_timeout": "Request timeout", + "machine_learning_availability_checks_timeout_description": "Timeout in milliseconds for availability checks", "machine_learning_clip_model": "CLIP model", "machine_learning_clip_model_description": "The name of a CLIP model listed here. Note that you must re-run the 'Smart Search' job for all images upon changing a model.", "machine_learning_duplicate_detection": "Duplicate Detection", @@ -591,6 +599,7 @@ "backup_controller_page_turn_on": "Turn on foreground backup", "backup_controller_page_uploading_file_info": "Uploading file info", "backup_err_only_album": "Cannot remove the only album", + "backup_error_sync_failed": "Sync failed. Cannot process backup.", "backup_info_card_assets": "assets", "backup_manual_cancelled": "Cancelled", "backup_manual_in_progress": "Upload already in progress. Try after sometime", @@ -1520,6 +1529,7 @@ "port": "Port", "preferences_settings_subtitle": "Manage the app's preferences", "preferences_settings_title": "Preferences", + "preparing": "Preparing", "preset": "Preset", "preview": "Preview", "previous": "Previous", @@ -1585,6 +1595,7 @@ "read_changelog": "Read Changelog", "readonly_mode_disabled": "Read-only mode disabled", "readonly_mode_enabled": "Read-only mode enabled", + "ready_for_upload": "Ready for upload", "reassign": "Reassign", "reassigned_assets_to_existing_person": "Re-assigned {count, plural, one {# asset} other {# assets}} to {name, select, null {an existing person} other {{name}}}", "reassigned_assets_to_new_person": "Re-assigned {count, plural, one {# asset} other {# assets}} to a new person", @@ -1917,6 +1928,7 @@ "stacktrace": "Stacktrace", "start": "Start", "start_date": "Start date", + "start_date_before_end_date": "Start date must be before end date", "state": "State", "status": "Status", "stop_casting": "Stop casting", diff --git a/i18n/es.json b/i18n/es.json index cd37c89315..d2cd6924c4 100644 --- a/i18n/es.json +++ b/i18n/es.json @@ -28,6 +28,7 @@ "add_to_album": "Incluir en álbum", "add_to_album_bottom_sheet_added": "Agregado a {album}", "add_to_album_bottom_sheet_already_exists": "Ya se encuentra en {album}", + "add_to_album_bottom_sheet_some_local_assets": "Algunos recursos locales no se pudieron añadir al álbum", "add_to_album_toggle": "Alternar selección para el {album}", "add_to_albums": "Incluir en álbumes", "add_to_albums_count": "Incluir en {count} álbumes", @@ -123,6 +124,13 @@ "logging_enable_description": "Habilitar registro", "logging_level_description": "Indica el nivel de registro a utilizar cuando está habilitado.", "logging_settings": "Registro", + "machine_learning_availability_checks": "Comprobaciones de disponibilidad", + "machine_learning_availability_checks_description": "Automáticamente detectar y preferir servidores de machine learning disponibles", + "machine_learning_availability_checks_enabled": "Habilitar comprobaciones de disponibilidad", + "machine_learning_availability_checks_interval": "Intervalo de comprobación", + "machine_learning_availability_checks_interval_description": "Intervalo en milisegundos entre las comprobaciones de disponibilidad", + "machine_learning_availability_checks_timeout": "Tiempo de espera de solicitud", + "machine_learning_availability_checks_timeout_description": "Tiempo de espera en milisegundos para comprobaciones de disponibilidad", "machine_learning_clip_model": "Modelo CLIP (Contrastive Language-Image Pre-Training)", "machine_learning_clip_model_description": "El nombre de un modelo CLIP listado aquí. Tendrás que relanzar el trabajo 'Búsqueda Inteligente' para todos los elementos al cambiar de modelo.", "machine_learning_duplicate_detection": "Detección de duplicados", @@ -387,8 +395,6 @@ "admin_password": "Contraseña del administrador", "administration": "Administración", "advanced": "Avanzada", - "advanced_settings_beta_timeline_subtitle": "Prueba la nueva experiencia de la aplicación", - "advanced_settings_beta_timeline_title": "Cronología beta", "advanced_settings_enable_alternate_media_filter_subtitle": "Usa esta opción para filtrar medios durante la sincronización según criterios alternativos. Intenta esto solo si tienes problemas con que la aplicación detecte todos los álbumes.", "advanced_settings_enable_alternate_media_filter_title": "[EXPERIMENTAL] Usar filtro alternativo de sincronización de álbumes del dispositivo", "advanced_settings_log_level_title": "Nivel de registro: {level}", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "¿Estás seguro de que quieres eliminar a {user}?", "album_search_not_found": "No se encontraron álbumes que coincidan con tu búsqueda", "album_share_no_users": "Parece que has compartido este álbum con todos los usuarios o no tienes ningún usuario con quien compartirlo.", + "album_summary": "Resumen del álbum", "album_updated": "Album actualizado", "album_updated_setting_description": "Reciba una notificación por correo electrónico cuando un álbum compartido tenga nuevos archivos", "album_user_left": "Salida {album}", @@ -496,6 +503,8 @@ "asset_restored_successfully": "Elementos restaurados exitosamente", "asset_skipped": "Omitido", "asset_skipped_in_trash": "En la papelera", + "asset_trashed": "Elemento eliminado", + "asset_troubleshoot": "Diagnóstico del elemento", "asset_uploaded": "Subido", "asset_uploading": "Subiendo…", "asset_viewer_settings_subtitle": "Administra las configuracioens de tu visor de fotos", @@ -529,8 +538,10 @@ "autoplay_slideshow": "Presentación con reproducción automática", "back": "Atrás", "back_close_deselect": "Atrás, cerrar o anular la selección", + "background_backup_running_error": "Ya se está ejecutando la copia de seguridad en segundo plano, no se puede iniciar la copia de seguridad manual", "background_location_permission": "Permiso de ubicación en segundo plano", "background_location_permission_content": "Para poder cambiar de red mientras se ejecuta en segundo plano, Immich debe tener *siempre* acceso a la ubicación precisa para que la aplicación pueda leer el nombre de la red Wi-Fi", + "background_options": "Opciones de segundo plano", "backup": "Copia de Seguridad", "backup_album_selection_page_albums_device": "Álbumes en el dispositivo ({count})", "backup_album_selection_page_albums_tap": "Toque para incluir, doble toque para excluir", @@ -538,6 +549,7 @@ "backup_album_selection_page_select_albums": "Seleccionar álbumes", "backup_album_selection_page_selection_info": "Información sobre la Selección", "backup_album_selection_page_total_assets": "Total de elementos únicos", + "backup_albums_sync": "Sincronización de álbumes de respaldo", "backup_all": "Todos", "backup_background_service_backup_failed_message": "Error al copiar elementos. Reintentando…", "backup_background_service_connection_failed_message": "Error al conectar con el servidor. Reintentando…", @@ -654,6 +666,8 @@ "change_pin_code": "Cambiar PIN", "change_your_password": "Cambia tu contraseña", "changed_visibility_successfully": "Visibilidad cambiada correctamente", + "charging": "Cargando", + "charging_requirement_mobile_backup": "La copia de seguridad en segundo plano requiere que el dispositivo se esté cargando", "check_corrupt_asset_backup": "Comprobar copias de seguridad de archivos corruptos", "check_corrupt_asset_backup_button": "Realizar comprobación", "check_corrupt_asset_backup_description": "Ejecutar esta comprobación solo por Wi-Fi y una vez que todos los archivos hayan sido respaldados. El procedimiento puede tardar unos minutos.", @@ -685,7 +699,7 @@ "comments_and_likes": "Comentarios y me gusta", "comments_are_disabled": "Los comentarios están deshabilitados", "common_create_new_album": "Crear nuevo álbum", - "common_server_error": "Por favor, verifica tu conexión de red, asegúrate de que el servidor esté accesible y las versiones de la aplicación y del servidor sean compatibles.", + "common_server_error": "Por favor, comprueba tu conexión de red, asegúrate de que el servidor esté accesible y las versiones de la aplicación y del servidor sean compatibles.", "completed": "Completado", "confirm": "Confirmar", "confirm_admin_password": "Confirmar contraseña del administrador", @@ -740,6 +754,7 @@ "create_user": "Crear usuario", "created": "Creado", "created_at": "Creado", + "creating_linked_albums": "Creando álbumes vinculados...", "crop": "Recortar", "curated_object_page_title": "Objetos", "current_device": "Dispositivo actual", @@ -798,7 +813,7 @@ "deletes_missing_assets": "Elimina archivos que faltan en el disco duro", "description": "Descripción", "description_input_hint_text": "Agregar descripción...", - "description_input_submit_error": "Error al actualizar la descripción, verifica el registro para obtener más detalles", + "description_input_submit_error": "Error al actualizar la descripción, comprueba el registro para obtener más detalles", "deselect_all": "Deseleccionar Todo", "details": "Detalles", "direction": "Dirección", @@ -889,7 +904,9 @@ "error": "Error", "error_change_sort_album": "No se pudo cambiar el orden de visualización del álbum", "error_delete_face": "Error al eliminar la cara del archivo", + "error_getting_places": "Error obteniendo lugares", "error_loading_image": "Error al cargar la imagen", + "error_loading_partners": "Error al cargar compañeros: {error}", "error_saving_image": "Error: {error}", "error_tag_face_bounding_box": "Error al etiquetar la cara: no se pueden obtener las coordenadas del marco", "error_title": "Error: algo salió mal", @@ -1054,6 +1071,7 @@ "favorites_page_no_favorites": "No se encontraron elementos marcados como favoritos", "feature_photo_updated": "Foto destacada actualizada", "features": "Características", + "features_in_development": "Funciones en Desarrollo", "features_setting_description": "Administrar las funciones de la aplicación", "file_name": "Nombre de archivo", "file_name_or_extension": "Nombre del archivo o extensión", @@ -1218,6 +1236,7 @@ "local": "Local", "local_asset_cast_failed": "No es posible transmitir un recurso que no está subido al servidor", "local_assets": "Archivos Locales", + "local_media_summary": "Resumen de Medios Locales", "local_network": "Red local", "local_network_sheet_info": "La aplicación se conectará al servidor a través de esta URL cuando utilice la red Wi-Fi especificada", "location_permission": "Permiso de ubicación", @@ -1229,6 +1248,7 @@ "location_picker_longitude_hint": "Introduce tu longitud aquí", "lock": "Bloquear", "locked_folder": "Carpeta protegida", + "log_detail_title": "Detalle del registro", "log_out": "Cerrar sesión", "log_out_all_devices": "Cerrar sesión en todos los dispositivos", "logged_in_as": "Sesión iniciada como {user}", @@ -1236,7 +1256,7 @@ "logged_out_device": "Dispositivo desconectado", "login": "Inicio de sesión", "login_disabled": "El inicio de sesión ha sido desactivado", - "login_form_api_exception": "Excepción producida por API. Por favor, verifica el URL del servidor e inténtalo de nuevo.", + "login_form_api_exception": "Excepción producida por API. Por favor, comprueba el URL del servidor e inténtalo de nuevo.", "login_form_back_button_text": "Atrás", "login_form_email_hint": "tucorreo@correo.com", "login_form_endpoint_hint": "http://tu-ip-de-servidor:puerto", @@ -1246,7 +1266,7 @@ "login_form_err_invalid_url": "URL no válida", "login_form_err_leading_whitespace": "Espacio en blanco inicial", "login_form_err_trailing_whitespace": "Espacio en blanco al final", - "login_form_failed_get_oauth_server_config": "Error al iniciar sesión con OAuth, verifica la URL del servidor", + "login_form_failed_get_oauth_server_config": "Error al iniciar sesión con OAuth, comprueba la URL del servidor", "login_form_failed_get_oauth_server_disable": "La función de OAuth no está disponible en este servidor", "login_form_failed_login": "Error al iniciar sesión, comprueba la URL del servidor, el correo electrónico y la contraseña", "login_form_handshake_exception": "Hubo una excepción de handshake con el servidor. Activa la compatibilidad con certificados autofirmados en la configuración si estás utilizando un certificado autofirmado.", @@ -1259,6 +1279,7 @@ "login_password_changed_success": "Contraseña cambiado con éxito", "logout_all_device_confirmation": "¿Estás seguro de que quieres cerrar sesión en todos los dispositivos?", "logout_this_device_confirmation": "¿Estás seguro de que quieres cerrar sesión en este dispositivo?", + "logs": "Registros", "longitude": "Longitud", "look": "Mirar", "loop_videos": "Vídeos en bucle", @@ -1301,6 +1322,7 @@ "mark_as_read": "Marcar como leído", "marked_all_as_read": "Todos marcados como leídos", "matches": "Coincidencias", + "matching_assets": "Elementos Coincidentes", "media_type": "Tipo de medio", "memories": "Recuerdos", "memories_all_caught_up": "Puesto al día", @@ -1341,6 +1363,7 @@ "name_or_nickname": "Nombre o apodo", "network_requirement_photos_upload": "Usar datos móviles para crear una copia de seguridad de las fotos", "network_requirement_videos_upload": "Usar datos móviles para crear una copia de seguridad de los videos", + "network_requirements": "Requisitos de red", "network_requirements_updated": "Los requisitos de red han cambiado, reiniciando la cola de copias de seguridad", "networking_settings": "Red", "networking_subtitle": "Configuraciones de acceso por URL al servidor", @@ -1351,6 +1374,7 @@ "new_person": "Nueva persona", "new_pin_code": "Nuevo PIN", "new_pin_code_subtitle": "Esta es la primera vez que accedes a la carpeta protegida. Crea un código PIN seguro para acceder a esta página", + "new_timeline": "Nueva Línea de tiempo", "new_user_created": "Nuevo usuario creado", "new_version_available": "NUEVA VERSIÓN DISPONIBLE", "newest_first": "El más reciente primero", @@ -1364,20 +1388,25 @@ "no_assets_message": "HAZ CLIC PARA SUBIR TU PRIMERA FOTO", "no_assets_to_show": "No hay elementos a mostrar", "no_cast_devices_found": "No se encontraron dispositivos de transmisión", + "no_checksum_local": "Suma de verificación no disponible. No se pueden obtener los elementos locales", + "no_checksum_remote": "Suma de verificación no disponible. No se puede obtener el elemento remoto", "no_duplicates_found": "No se encontraron duplicados.", "no_exif_info_available": "No hay información exif disponible", "no_explore_results_message": "Sube más fotos para explorar tu colección.", "no_favorites_message": "Agregue favoritos para encontrar rápidamente sus mejores fotos y videos", "no_libraries_message": "Crea una biblioteca externa para ver tus fotos y vídeos", + "no_local_assets_found": "No se encontraron elementos locales con esta suma de comprobación", "no_locked_photos_message": "Las fotos y los vídeos de la carpeta protegida se mantienen ocultos; no aparecerán cuando veas o busques elementos en tu biblioteca.", "no_name": "Sin nombre", "no_notifications": "Ninguna notificación", "no_people_found": "No se encontraron personas coincidentes", "no_places": "Sin lugares", + "no_remote_assets_found": "No se encontraron elementos remotos con esta suma de comprobación", "no_results": "Sin resultados", "no_results_description": "Pruebe con un sinónimo o una palabra clave más general", "no_shared_albums_message": "Crea un álbum para compartir fotos y vídeos con personas de tu red", "no_uploads_in_progress": "No hay cargas en progreso", + "not_available": "N/D", "not_in_any_album": "Sin álbum", "not_selected": "No seleccionado", "note_apply_storage_label_to_previously_uploaded assets": "Nota: Para aplicar la etiqueta de almacenamiento a los archivos que ya se subieron, ejecute la", @@ -1499,6 +1528,7 @@ "port": "Puerto", "preferences_settings_subtitle": "Configuraciones de la aplicación", "preferences_settings_title": "Preferencias", + "preparing": "Preparando", "preset": "Preestablecido", "preview": "Posterior", "previous": "Anterior", @@ -1564,6 +1594,7 @@ "read_changelog": "Leer registro de cambios", "readonly_mode_disabled": "Modo Solo lectura deshabilitado", "readonly_mode_enabled": "Modo Solo lectura habilitado", + "ready_for_upload": "Listo para subir", "reassign": "Reasignar", "reassigned_assets_to_existing_person": "Reasignado {count, plural, one {# elemento} other {# elementos}} a {name, select, null {una persona existente} other {{name}}}", "reassigned_assets_to_new_person": "Reasignado {count, plural, one {# elemento} other {# elementos}} a un nuevo usuario", @@ -1588,6 +1619,7 @@ "regenerating_thumbnails": "Recargando miniaturas", "remote": "Remoto", "remote_assets": "Elementos remotos", + "remote_media_summary": "Resumen de Medios Remotos", "remove": "Eliminar", "remove_assets_album_confirmation": "¿Estás seguro que quieres eliminar {count, plural, one {# elemento} other {# elementos}} del álbum?", "remove_assets_shared_link_confirmation": "¿Estás seguro que quieres eliminar {count, plural, one {# elemento} other {# elementos}} del enlace compartido?", @@ -1863,6 +1895,7 @@ "show_slideshow_transition": "Mostrar la transición de las diapositivas", "show_supporter_badge": "Insignia de colaborador", "show_supporter_badge_description": "Mostrar una insignia de colaborador", + "show_text_search_menu": "Mostrar el menú de búsqueda", "shuffle": "Modo aleatorio", "sidebar": "Barra lateral", "sidebar_display_description": "Muestra un enlace a la vista en la barra lateral", @@ -1893,6 +1926,7 @@ "stacktrace": "Seguimiento de pila", "start": "Inicio", "start_date": "Fecha de inicio", + "start_date_before_end_date": "Fecha de inicio debe ser antes de fecha final", "state": "Estado", "status": "Estado", "stop_casting": "Detener transmisión", @@ -2095,5 +2129,6 @@ "yes": "Sí", "you_dont_have_any_shared_links": "No tienes ningún enlace compartido", "your_wifi_name": "El nombre de tu Wi-Fi", - "zoom_image": "Acercar Imagen" + "zoom_image": "Acercar Imagen", + "zoom_to_bounds": "Ajustar a los límites" } diff --git a/i18n/et.json b/i18n/et.json index 33a003bd54..d451606dae 100644 --- a/i18n/et.json +++ b/i18n/et.json @@ -28,6 +28,7 @@ "add_to_album": "Lisa albumisse", "add_to_album_bottom_sheet_added": "Lisatud albumisse {album}", "add_to_album_bottom_sheet_already_exists": "On juba albumis {album}", + "add_to_album_bottom_sheet_some_local_assets": "Kõiki lokaalseid üksuseid ei õnnestunud albumisse lisada", "add_to_album_toggle": "Muuda albumi {album} valikut", "add_to_albums": "Lisa albumitesse", "add_to_albums_count": "Lisa albumitesse ({count})", @@ -123,6 +124,13 @@ "logging_enable_description": "Luba logimine", "logging_level_description": "Kui lubatud, millist logimistaset kasutada.", "logging_settings": "Logimine", + "machine_learning_availability_checks": "Saadavuskontrollid", + "machine_learning_availability_checks_description": "Tuvasta ja eelista automaatselt saadavalolevaid masinõppeservereid", + "machine_learning_availability_checks_enabled": "Luba saadavuskontrollid", + "machine_learning_availability_checks_interval": "Kontrolli intervall", + "machine_learning_availability_checks_interval_description": "Saadavuskontrollide intervall millisekundites", + "machine_learning_availability_checks_timeout": "Päringu ajalõpp", + "machine_learning_availability_checks_timeout_description": "Saadavuskontrollide ajalõpp millisekundites", "machine_learning_clip_model": "CLIP mudel", "machine_learning_clip_model_description": "CLIP mudeli nimi, mis on loetletud siin. Pane tähele, et mudeli muutmisel pead kõigi piltide peal nutiotsingu tööte uuesti käivitama.", "machine_learning_duplicate_detection": "Duplikaatide leidmine", @@ -387,8 +395,6 @@ "admin_password": "Administraatori parool", "administration": "Administratsioon", "advanced": "Täpsemad valikud", - "advanced_settings_beta_timeline_subtitle": "Koge uut rakendust", - "advanced_settings_beta_timeline_title": "Beeta ajajoon", "advanced_settings_enable_alternate_media_filter_subtitle": "Kasuta seda valikut, et filtreerida sünkroonimise ajal üksuseid alternatiivsete kriteeriumite alusel. Proovi seda ainult siis, kui rakendusel on probleeme kõigi albumite tuvastamisega.", "advanced_settings_enable_alternate_media_filter_title": "[EKSPERIMENTAALNE] Kasuta alternatiivset seadme albumi sünkroonimise filtrit", "advanced_settings_log_level_title": "Logimistase: {level}", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "Kas oled kindel, et soovid kasutaja {user} eemaldada?", "album_search_not_found": "Otsingule vastavaid albumeid ei leitud", "album_share_no_users": "Paistab, et oled seda albumit kõikide kasutajatega jaganud, või pole ühtegi kasutajat, kellega jagada.", + "album_summary": "Albumi kokkuvõte", "album_updated": "Album muudetud", "album_updated_setting_description": "Saa teavitus e-posti teel, kui jagatud albumis on uusi üksuseid", "album_user_left": "Lahkutud albumist {album}", @@ -496,6 +503,8 @@ "asset_restored_successfully": "Üksus edukalt taastatud", "asset_skipped": "Vahele jäetud", "asset_skipped_in_trash": "Prügikastis", + "asset_trashed": "Üksus liigutatud prügikasti", + "asset_troubleshoot": "Üksuse tõrkeotsing", "asset_uploaded": "Üleslaaditud", "asset_uploading": "Üleslaadimine…", "asset_viewer_settings_subtitle": "Halda galeriivaaturi seadeid", @@ -529,8 +538,10 @@ "autoplay_slideshow": "Esita slaidiesitlus automaatselt", "back": "Tagasi", "back_close_deselect": "Tagasi, sulge või tühista valik", + "background_backup_running_error": "Taustvarundus on käimas, ei saa käsitsi varundust alustada", "background_location_permission": "Taustal asukoha luba", "background_location_permission_content": "Et taustal töötades võrguühendust vahetada, peab Immich'il *alati* olema täpse asukoha luba, et rakendus saaks WiFi-võrgu nime lugeda", + "background_options": "Taustavalikud", "backup": "Varundamine", "backup_album_selection_page_albums_device": "Albumid seadmel ({count})", "backup_album_selection_page_albums_tap": "Puuduta kaasamiseks, topeltpuuduta välistamiseks", @@ -538,6 +549,7 @@ "backup_album_selection_page_select_albums": "Vali albumid", "backup_album_selection_page_selection_info": "Valiku info", "backup_album_selection_page_total_assets": "Unikaalseid üksuseid kokku", + "backup_albums_sync": "Varundusalbumite sünkroniseerimine", "backup_all": "Kõik", "backup_background_service_backup_failed_message": "Üksuste varundamine ebaõnnestus. Uuesti proovimine…", "backup_background_service_connection_failed_message": "Serveriga ühendumine ebaõnnestus. Uuesti proovimine…", @@ -654,6 +666,8 @@ "change_pin_code": "Muuda PIN-koodi", "change_your_password": "Muuda oma parooli", "changed_visibility_successfully": "Nähtavus muudetud", + "charging": "Laadimine", + "charging_requirement_mobile_backup": "Taustal varundus vajab, et seade oleks laadimas", "check_corrupt_asset_backup": "Otsi riknenud üksuste varukoopiaid", "check_corrupt_asset_backup_button": "Teosta kontroll", "check_corrupt_asset_backup_description": "Käivita see kontroll ainult WiFi-võrgus ja siis, kui kõik üksused on varundatud. See protseduur võib kesta mõne minuti.", @@ -740,6 +754,7 @@ "create_user": "Lisa kasutaja", "created": "Lisatud", "created_at": "Lisatud", + "creating_linked_albums": "Lingitud albumite loomine...", "crop": "Kärpimine", "curated_object_page_title": "Asjad", "current_device": "Praegune seade", @@ -832,11 +847,11 @@ "download_settings_description": "Halda üksuste allalaadimise seadeid", "download_started": "Allalaadimine alustatud", "download_sucess": "Allalaadimine õnnestus", - "download_sucess_android": "Meediumid laaditi alla kataloogi DCIM/Immich", + "download_sucess_android": "Üksused laaditi alla kataloogi DCIM/Immich", "download_waiting_to_retry": "Uuesti proovimise ootel", "downloading": "Allalaadimine", "downloading_asset_filename": "Üksuse {filename} allalaadimine", - "downloading_media": "Meediumi allalaadimine", + "downloading_media": "Üksuste allalaadimine", "drop_files_to_upload": "Failide üleslaadimiseks sikuta need ükskõik kuhu", "duplicates": "Duplikaadid", "duplicates_description": "Lahenda iga grupp, valides duplikaadid, kui neid on", @@ -889,7 +904,9 @@ "error": "Viga", "error_change_sort_album": "Albumi sorteerimisjärjestuse muutmine ebaõnnestus", "error_delete_face": "Viga näo kustutamisel", + "error_getting_places": "Viga kohtade pärimisel", "error_loading_image": "Viga pildi laadimisel", + "error_loading_partners": "Viga partnerite laadimisel: {error}", "error_saving_image": "Viga: {error}", "error_tag_face_bounding_box": "Viga näo sildistamisel - ümbritseva kasti koordinaate ei õnnestunud leida", "error_title": "Viga - midagi läks valesti", @@ -1054,6 +1071,7 @@ "favorites_page_no_favorites": "Lemmikuid üksuseid ei leitud", "feature_photo_updated": "Esiletõstetud foto muudetud", "features": "Funktsioonid", + "features_in_development": "Arendusjärgus olevad funktsioonid", "features_setting_description": "Halda rakenduse funktsioone", "file_name": "Failinimi", "file_name_or_extension": "Failinimi või -laiend", @@ -1218,6 +1236,7 @@ "local": "Lokaalsed", "local_asset_cast_failed": "Ei saa edastada üksust, mis pole serverisse üles laaditud", "local_assets": "Lokaalsed üksused", + "local_media_summary": "Lokaalsete üksuste kokkuvõte", "local_network": "Kohalik võrk", "local_network_sheet_info": "Rakendus ühendub valitud Wi-Fi võrgus olles serveriga selle URL-i kaudu", "location_permission": "Asukoha luba", @@ -1229,6 +1248,7 @@ "location_picker_longitude_hint": "Sisesta pikkuskraad siia", "lock": "Lukusta", "locked_folder": "Lukustatud kaust", + "log_detail_title": "Logi detailid", "log_out": "Logi välja", "log_out_all_devices": "Logi kõigist seadmetest välja", "logged_in_as": "Logitud sisse kasutajana {user}", @@ -1259,6 +1279,7 @@ "login_password_changed_success": "Parool edukalt uuendatud", "logout_all_device_confirmation": "Kas oled kindel, et soovid kõigist seadmetest välja logida?", "logout_this_device_confirmation": "Kas oled kindel, et soovid sellest seadmest välja logida?", + "logs": "Logid", "longitude": "Pikkuskraad", "look": "Välimus", "loop_videos": "Taasesita videod", @@ -1301,6 +1322,7 @@ "mark_as_read": "Märgi loetuks", "marked_all_as_read": "Kõik märgiti loetuks", "matches": "Ühtivad failid", + "matching_assets": "Ühtivad üksused", "media_type": "Meediumi tüüp", "memories": "Mälestused", "memories_all_caught_up": "Ongi kõik", @@ -1341,6 +1363,7 @@ "name_or_nickname": "Nimi või hüüdnimi", "network_requirement_photos_upload": "Kasuta fotode varundamiseks mobiilset andmesidet", "network_requirement_videos_upload": "Kasuta videote varundamiseks mobiilset andmesidet", + "network_requirements": "Võrgu nõuded", "network_requirements_updated": "Võrgu nõuded muutusid, varundamise järjekord lähtestatakse", "networking_settings": "Võrguühendus", "networking_subtitle": "Halda serveri lõpp-punkti seadeid", @@ -1351,6 +1374,7 @@ "new_person": "Uus isik", "new_pin_code": "Uus PIN-kood", "new_pin_code_subtitle": "See on sul esimene kord lukustatud kausta kasutada. Turvaliseks ligipääsuks loo PIN-kood", + "new_timeline": "Uus ajajoon", "new_user_created": "Uus kasutaja lisatud", "new_version_available": "UUS VERSIOON SAADAVAL", "newest_first": "Uuemad eespool", @@ -1364,16 +1388,20 @@ "no_assets_message": "KLIKI ESIMESE FOTO ÜLESLAADIMISEKS", "no_assets_to_show": "Pole üksuseid, mida kuvada", "no_cast_devices_found": "Edastamise seadmeid ei leitud", + "no_checksum_local": "Kontrollsumma pole saadaval - lokaalse üksuse pärimine ebaõnnestus", + "no_checksum_remote": "Kontrollsumma pole saadaval - kaugüksuse pärimine ebaõnnestus", "no_duplicates_found": "Ühtegi duplikaati ei leitud.", "no_exif_info_available": "Exif info pole saadaval", "no_explore_results_message": "Oma kogu avastamiseks laadi üles rohkem fotosid.", "no_favorites_message": "Lisa lemmikud, et oma parimaid fotosid ja videosid kiiresti leida", "no_libraries_message": "Lisa väline kogu oma fotode ja videote vaatamiseks", + "no_local_assets_found": "Selle kontrollsummaga lokaalseid üksuseid ei leitud", "no_locked_photos_message": "Lukustatud kaustas olevad fotod ja videod on peidetud ning need pole kogu sirvimisel ja otsimisel nähtavad.", "no_name": "Nimetu", "no_notifications": "Teavitusi pole", "no_people_found": "Kattuvaid isikuid ei leitud", "no_places": "Kohti ei ole", + "no_remote_assets_found": "Selle kontrollsummaga kaugüksuseid ei leitud", "no_results": "Vasteid pole", "no_results_description": "Proovi sünonüümi või üldisemat märksõna", "no_shared_albums_message": "Lisa album, et fotosid ja videosid teistega jagada", @@ -1499,6 +1527,7 @@ "port": "Port", "preferences_settings_subtitle": "Halda rakenduse eelistusi", "preferences_settings_title": "Eelistused", + "preparing": "Ettevalmistamine", "preset": "Eelseadistus", "preview": "Eelvaade", "previous": "Eelmine", @@ -1563,6 +1592,7 @@ "read_changelog": "Vaata muudatuste ülevaadet", "readonly_mode_disabled": "Kirjutuskaitserežiim välja lülitatud", "readonly_mode_enabled": "Kirjutuskaitserežiim sisse lülitatud", + "ready_for_upload": "Valmis üleslaadimiseks", "reassign": "Määra uuesti", "reassigned_assets_to_existing_person": "{count, plural, one {# üksus} other {# üksust}} seostatud {name, select, null {olemasoleva isikuga} other {isikuga {name}}}", "reassigned_assets_to_new_person": "{count, plural, one {# üksus} other {# üksust}} seostatud uue isikuga", @@ -1587,6 +1617,7 @@ "regenerating_thumbnails": "Pisipiltide uuesti genereerimine", "remote": "Serveris", "remote_assets": "Kaugüksused", + "remote_media_summary": "Kaugüksuste kokkuvõte", "remove": "Eemalda", "remove_assets_album_confirmation": "Kas oled kindel, et soovid {count, plural, one {# üksuse} other {# üksust}} albumist eemaldada?", "remove_assets_shared_link_confirmation": "Kas oled kindel, et soovid eemaldada {count, plural, one {# üksuse} other {# üksust}} sellelt jagatud lingilt?", @@ -1862,6 +1893,7 @@ "show_slideshow_transition": "Kuva slaidiesitluse üleminekud", "show_supporter_badge": "Toetaja märk", "show_supporter_badge_description": "Kuva toetaja märki", + "show_text_search_menu": "Kuva tekstiotsingu menüüd", "shuffle": "Juhuslik", "sidebar": "Külgmenüü", "sidebar_display_description": "Kuva külgmenüüs linki vaatele", @@ -1892,6 +1924,7 @@ "stacktrace": "Pinujälg", "start": "Alusta", "start_date": "Alguskuupäev", + "start_date_before_end_date": "Alguskuupäev peab olema varasem kui lõppkuupäev", "state": "Osariik", "status": "Staatus", "stop_casting": "Lõpeta edastamine", @@ -2027,7 +2060,7 @@ "upload_success": "Üleslaadimine õnnestus, uute üksuste nägemiseks värskenda lehte.", "upload_to_immich": "Laadi Immich'isse ({count})", "uploading": "Üleslaadimine", - "uploading_media": "Meediumi üleslaadimine", + "uploading_media": "Üksuste üleslaadimine", "url": "URL", "usage": "Kasutus", "use_biometric": "Kasuta biomeetriat", @@ -2094,5 +2127,6 @@ "yes": "Jah", "you_dont_have_any_shared_links": "Sul pole ühtegi jagatud linki", "your_wifi_name": "Sinu WiFi-võrgu nimi", - "zoom_image": "Suumi pilti" + "zoom_image": "Suumi pilti", + "zoom_to_bounds": "Suumi piiridesse" } diff --git a/i18n/fa.json b/i18n/fa.json index 3b0be9a9b1..76f8d956fc 100644 --- a/i18n/fa.json +++ b/i18n/fa.json @@ -13,6 +13,7 @@ "add_a_location": "افزودن یک مکان", "add_a_name": "افزودن نام", "add_a_title": "افزودن عنوان", + "add_birthday": "افزودن تاریخ تولد", "add_exclusion_pattern": "افزودن الگوی استثنا", "add_import_path": "افزودن مسیر ورودی", "add_location": "افزودن مکان", @@ -22,10 +23,13 @@ "add_photos": "افزودن عکس ها", "add_to": "افزودن به …", "add_to_album": "افزودن به آلبوم", + "add_to_album_bottom_sheet_added": "به آلبوم {album} اضافه شد", + "add_to_album_bottom_sheet_already_exists": "قبلا در آلبوم {album} موجود است", + "add_to_album_bottom_sheet_some_local_assets": "برخی از محتواهای محلی را نشد به آلبوم اضافه کرد", "add_to_shared_album": "افزودن به آلبوم اشتراکی", "added_to_archive": "به آرشیو اضافه شد", "added_to_favorites": "به علاقه مندی ها اضافه شد", - "added_to_favorites_count": "{count} تا اضافه شد به علاقه مندی ها", + "added_to_favorites_count": "{count, number} تا به علاقه مندی ها اضافه شد", "admin": { "add_exclusion_pattern_description": "الگوهای استثنا را اضافه کنید. پشتیبانی از گلابینگ با استفاده از *, ** و ? وجود دارد. برای نادیده گرفتن تمام فایل‌ها در هر دایرکتوری با نام \"Raw\"، از \"**/Raw/**\" استفاده کنید. برای نادیده گرفتن تمام فایل‌هایی که با \".tif\" پایان می‌یابند، از \"**/*.tif\" استفاده کنید. برای نادیده گرفتن یک مسیر مطلق، از \"/path/to/ignore/**\" استفاده کنید.", "authentication_settings": "تنظیمات احراز هویت", diff --git a/i18n/fi.json b/i18n/fi.json index 2451b30a4b..769b528f4c 100644 --- a/i18n/fi.json +++ b/i18n/fi.json @@ -123,6 +123,13 @@ "logging_enable_description": "Ota lokikirjaus käyttöön", "logging_level_description": "Kun käytössä, mitä lokituksen tasoa käytetään.", "logging_settings": "Lokit", + "machine_learning_availability_checks": "Saatavuustarkastukset", + "machine_learning_availability_checks_description": "Automaattisesti havaitse ja suosi vapaita koneoppimisen palvelimia", + "machine_learning_availability_checks_enabled": "Laita päälle saatavuus tarkistukset", + "machine_learning_availability_checks_interval": "Tarkastusväli", + "machine_learning_availability_checks_interval_description": "Aikaväli millisekunneissa saavutettavuus tarkistuksille", + "machine_learning_availability_checks_timeout": "Pyynnön aikakatkaisu", + "machine_learning_availability_checks_timeout_description": "Aikakatkaisu aika millisekunneissa saatavuus tarkistuksille", "machine_learning_clip_model": "CLIP-malli", "machine_learning_clip_model_description": "Käytettävän CLIP-mallin nimi toimivien mallien listasta. Huomaa että sinun täytyy suorittaa \"Älykäs etsintä\"-työ uudelleen vaihdettuasi käytettävää mallia.", "machine_learning_duplicate_detection": "Kaksoiskappaleiden tunnistus", @@ -387,8 +394,6 @@ "admin_password": "Ylläpitäjän salasana", "administration": "Ylläpito", "advanced": "Edistyneet", - "advanced_settings_beta_timeline_subtitle": "Kokeile uutta sovelluskokemusta", - "advanced_settings_beta_timeline_title": "Beta-aikajana", "advanced_settings_enable_alternate_media_filter_subtitle": "Käytä tätä vaihtoehtoa suodattaaksesi mediaa synkronoinnin aikana vaihtoehtoisten kriteerien perusteella. Kokeile tätä vain, jos sovelluksessa on ongelmia kaikkien albumien tunnistamisessa.", "advanced_settings_enable_alternate_media_filter_title": "[KOKEELLINEN] Käytä vaihtoehtoisen laitteen albumin synkronointisuodatinta", "advanced_settings_log_level_title": "Kirjaustaso: {level}", @@ -425,6 +430,7 @@ "album_remove_user_confirmation": "Oletko varma että haluat poistaa {user}?", "album_search_not_found": "Haullasi ei löytynyt yhtään albumia", "album_share_no_users": "Näyttää että olet jakanut tämän albumin kaikkien kanssa, tai sinulla ei ole käyttäjiä joille jakaa.", + "album_summary": "Albumi tiivistelmä", "album_updated": "Albumi päivitetty", "album_updated_setting_description": "Saa sähköpostia kun jaetussa albumissa on uutta sisältöä", "album_user_left": "Poistuttiin albumista {album}", @@ -496,6 +502,7 @@ "asset_restored_successfully": "Kohde palautettu onnistuneesti", "asset_skipped": "Ohitettu", "asset_skipped_in_trash": "Roskakorissa", + "asset_trashed": "Kohde poistettu", "asset_uploaded": "Lähetetty", "asset_uploading": "Ladataan…", "asset_viewer_settings_subtitle": "Galleriakatseluohjelman asetusten hallinta", @@ -529,8 +536,10 @@ "autoplay_slideshow": "Toista diaesitys automaattisesti", "back": "Takaisin", "back_close_deselect": "Palaa, sulje tai poista valinnat", + "background_backup_running_error": "Tausta varmuuskopiointi on aktiivinen, ei voida aloittaa manuaalista varmuuskopiointia", "background_location_permission": "Taustasijainnin käyttöoikeus", "background_location_permission_content": "Jotta sovellus voi vaihtaa verkkoa taustalla toimiessaan, Immichillä on *aina* oltava pääsy tarkkaan sijaintiin, jotta se voi lukea Wi-Fi-verkon nimen", + "background_options": "Tausta valinnat", "backup": "Varmuuskopiointi", "backup_album_selection_page_albums_device": "Laitteen albumit ({count})", "backup_album_selection_page_albums_tap": "Napauta sisällyttääksesi, kaksoisnapauta jättääksesi pois", diff --git a/i18n/fr.json b/i18n/fr.json index 29f9025516..d5b6e10ba8 100644 --- a/i18n/fr.json +++ b/i18n/fr.json @@ -28,6 +28,7 @@ "add_to_album": "Ajouter à l'album", "add_to_album_bottom_sheet_added": "Ajouté à {album}", "add_to_album_bottom_sheet_already_exists": "Déjà dans {album}", + "add_to_album_bottom_sheet_some_local_assets": "Certains médias n'ont pas pu être ajoutés à l'album", "add_to_album_toggle": "Basculer la sélection pour {album}", "add_to_albums": "Ajouter aux albums", "add_to_albums_count": "Ajouter aux albums ({count})", @@ -123,6 +124,13 @@ "logging_enable_description": "Activer la journalisation", "logging_level_description": "Niveau de journalisation lorsque cette option est activée.", "logging_settings": "Journalisation", + "machine_learning_availability_checks": "Vérifications de disponibilité", + "machine_learning_availability_checks_description": "Détecte automatiquement et choisit les serveurs d'apprentissage machine disponibles", + "machine_learning_availability_checks_enabled": "Activer les vérifications de disponibilité", + "machine_learning_availability_checks_interval": "Intervalle de vérification", + "machine_learning_availability_checks_interval_description": "Intervalle en millisecondes entre les vérifications de disponibilité", + "machine_learning_availability_checks_timeout": "Délai d'expiration de la requête", + "machine_learning_availability_checks_timeout_description": "Délai d'expiration en millisecondes pour les vérifications de disponibilité", "machine_learning_clip_model": "Modèle de langage CLIP", "machine_learning_clip_model_description": "Le nom d'un modèle CLIP listé ici. Notez que vous devez réexécuter la tâche 'Recherche intelligente' pour toutes les images après avoir changé de modèle.", "machine_learning_duplicate_detection": "Détection des doublons", @@ -387,8 +395,6 @@ "admin_password": "Mot de passe Admin", "administration": "Administration", "advanced": "Avancé", - "advanced_settings_beta_timeline_subtitle": "Essayer la nouvelle application", - "advanced_settings_beta_timeline_title": "Timeline de la béta", "advanced_settings_enable_alternate_media_filter_subtitle": "Utilisez cette option pour filtrer les média durant la synchronisation avec des critères alternatifs. N'utilisez cela que lorsque l'application n'arrive pas à détecter tous les albums.", "advanced_settings_enable_alternate_media_filter_title": "[EXPÉRIMENTAL] Utiliser le filtre de synchronisation d'album alternatif", "advanced_settings_log_level_title": "Niveau de journalisation : {level}", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "Êtes-vous sûr de vouloir supprimer {user} ?", "album_search_not_found": "Aucun album trouvé ne correspond à votre recherche", "album_share_no_users": "Il semble que vous ayez partagé cet album avec tous les utilisateurs ou que vous n'ayez aucun utilisateur avec lequel le partager.", + "album_summary": "Résumé de l'album", "album_updated": "Album mis à jour", "album_updated_setting_description": "Recevoir une notification par courriel lorsqu'un album partagé a de nouveaux médias", "album_user_left": "{album} quitté", @@ -496,6 +503,8 @@ "asset_restored_successfully": "Élément restauré avec succès", "asset_skipped": "Sauté", "asset_skipped_in_trash": "À la corbeille", + "asset_trashed": "Média mis à la corbeille", + "asset_troubleshoot": "Dépannage de média", "asset_uploaded": "Envoyé", "asset_uploading": "Envoi…", "asset_viewer_settings_subtitle": "Modifier les paramètres du visualiseur photos", @@ -529,8 +538,10 @@ "autoplay_slideshow": "Lecture automatique d'un diaporama", "back": "Retour", "back_close_deselect": "Retournez en arrière, fermez ou désélectionnez", + "background_backup_running_error": "La sauvegarde en tâche de fond est actuellement en cours, impossible de démarrer une sauvegarde manuelle", "background_location_permission": "Permission de localisation en arrière plan", "background_location_permission_content": "Afin de pouvoir changer d'adresse en arrière plan, Immich doit avoir *en permanence* accès à la localisation précise, afin d'accéder au le nom du réseau Wi-Fi utilisé", + "background_options": "Options d'arrière-plan", "backup": "Sauvegarde", "backup_album_selection_page_albums_device": "Albums sur l'appareil ({count})", "backup_album_selection_page_albums_tap": "Tapez pour inclure, tapez deux fois pour exclure", @@ -538,6 +549,7 @@ "backup_album_selection_page_select_albums": "Sélectionner les albums", "backup_album_selection_page_selection_info": "Informations sur la sélection", "backup_album_selection_page_total_assets": "Total des éléments uniques", + "backup_albums_sync": "Sauvegarde de la synchronisation des albums", "backup_all": "Tout", "backup_background_service_backup_failed_message": "Échec de la sauvegarde des médias. Nouvelle tentative…", "backup_background_service_connection_failed_message": "Impossible de se connecter au serveur. Nouvelle tentative…", @@ -587,6 +599,7 @@ "backup_controller_page_turn_on": "Activer la sauvegarde au premier plan", "backup_controller_page_uploading_file_info": "Envoi des informations du fichier", "backup_err_only_album": "Impossible de retirer le seul album", + "backup_error_sync_failed": "Échec de la synchronisation. Impossible de démarrer la sauvegarde.", "backup_info_card_assets": "éléments", "backup_manual_cancelled": "Annulé", "backup_manual_in_progress": "Envoi déjà en cours. Réessayez plus tard", @@ -654,6 +667,8 @@ "change_pin_code": "Changer le code PIN", "change_your_password": "Changer votre mot de passe", "changed_visibility_successfully": "Visibilité modifiée avec succès", + "charging": "En charge", + "charging_requirement_mobile_backup": "La sauvegarde en tâche de fond nécessite que l'appareil soit en charge", "check_corrupt_asset_backup": "Vérifier la corruption des éléments enregistrés", "check_corrupt_asset_backup_button": "Vérifier", "check_corrupt_asset_backup_description": "Lancer cette vérification uniquement lorsque connecté à un réseau Wi-Fi et que tout le contenu a été enregistré. Cette procédure peut durer plusieurs minutes.", @@ -740,6 +755,7 @@ "create_user": "Créer un utilisateur", "created": "Créé", "created_at": "Créé à", + "creating_linked_albums": "Création des albums liés...", "crop": "Recadrer", "curated_object_page_title": "Objets", "current_device": "Appareil actuel", @@ -889,7 +905,9 @@ "error": "Erreur", "error_change_sort_album": "Impossible de modifier l'ordre de tri des albums", "error_delete_face": "Erreur lors de la suppression du visage pour le média", + "error_getting_places": "Erreur à la récupération des lieux", "error_loading_image": "Erreur de chargement de l'image", + "error_loading_partners": "Erreur de récupération des partenaires : {error}", "error_saving_image": "Erreur : {error}", "error_tag_face_bounding_box": "Erreur lors de l'identification de visage - impossible de récupérer les coordonnées du cadre entourant le visage", "error_title": "Erreur - Quelque chose s'est mal passé", @@ -1054,6 +1072,7 @@ "favorites_page_no_favorites": "Aucun élément favori n'a été trouvé", "feature_photo_updated": "Photo de la personne mise à jour", "features": "Fonctionnalités", + "features_in_development": "Fonctionnalités en développement", "features_setting_description": "Gérer les fonctionnalités de l'application", "file_name": "Nom du fichier", "file_name_or_extension": "Nom du fichier ou extension", @@ -1218,6 +1237,7 @@ "local": "Local", "local_asset_cast_failed": "Impossible de caster un média qui n'a pas envoyé vers le serveur", "local_assets": "Média locaux", + "local_media_summary": "Résumé du média local", "local_network": "Réseau local", "local_network_sheet_info": "L'application va se connecter au serveur via cette URL quand l'appareil est connecté à ce réseau Wi-Fi", "location_permission": "Autorisation de localisation", @@ -1229,6 +1249,7 @@ "location_picker_longitude_hint": "Saisir la longitude ici", "lock": "Verrouiller", "locked_folder": "Dossier verrouillé", + "log_detail_title": "Niveau de journalisation", "log_out": "Se déconnecter", "log_out_all_devices": "Déconnecter tous les appareils", "logged_in_as": "Connecté en tant que {user}", @@ -1259,6 +1280,7 @@ "login_password_changed_success": "Mot de passe mis à jour avec succès", "logout_all_device_confirmation": "Êtes-vous sûr de vouloir déconnecter tous les appareils ?", "logout_this_device_confirmation": "Êtes-vous sûr de vouloir déconnecter cet appareil ?", + "logs": "Journaux", "longitude": "Longitude", "look": "Regarder", "loop_videos": "Vidéos en boucle", @@ -1301,6 +1323,7 @@ "mark_as_read": "Marquer comme lu", "marked_all_as_read": "Tout a été marqué comme lu", "matches": "Correspondances", + "matching_assets": "Médias correspondants", "media_type": "Type de média", "memories": "Souvenirs", "memories_all_caught_up": "Vous avez tout vu", @@ -1341,6 +1364,7 @@ "name_or_nickname": "Nom ou surnom", "network_requirement_photos_upload": "Utiliser les données mobile pour sauvegarder les photos", "network_requirement_videos_upload": "Utiliser les données mobile pour sauvegarder les vidéos", + "network_requirements": "Prérequis réseau", "network_requirements_updated": "Contraintes réseau modifiées, file d'attente de sauvegarde réinitialisée", "networking_settings": "Réseau", "networking_subtitle": "Gérer les adresses du serveur", @@ -1351,6 +1375,7 @@ "new_person": "Nouvelle personne", "new_pin_code": "Nouveau code PIN", "new_pin_code_subtitle": "C'est votre premier accès au dossier verrouillé. Créez un code PIN pour sécuriser l'accès à cette page", + "new_timeline": "Nouvelle vue chronologique", "new_user_created": "Nouvel utilisateur créé", "new_version_available": "NOUVELLE VERSION DISPONIBLE", "newest_first": "Récents en premier", @@ -1364,20 +1389,25 @@ "no_assets_message": "CLIQUEZ POUR ENVOYER VOTRE PREMIÈRE PHOTO", "no_assets_to_show": "Aucun élément à afficher", "no_cast_devices_found": "Aucun appareil de diffusion trouvé", + "no_checksum_local": "Aucune empreinte numerique disponible - impossible de récupérer les médias locaux", + "no_checksum_remote": "Aucune empreinte numérique disponible - impossible de récupérer les médias distants", "no_duplicates_found": "Aucun doublon n'a été trouvé.", "no_exif_info_available": "Aucune information exif disponible", "no_explore_results_message": "Envoyez plus de photos pour explorer votre bibliothèque.", "no_favorites_message": "Ajouter des photos et vidéos à vos favoris pour les retrouver plus rapidement", "no_libraries_message": "Créer une bibliothèque externe pour voir vos photos et vidéos dans un autre espace de stockage", + "no_local_assets_found": "Aucun média local trouvé avec cette empreinte numerique", "no_locked_photos_message": "Les photos et vidéos du dossier verrouillé sont masqués et ne s'afficheront pas dans votre galerie ou la recherche.", "no_name": "Pas de nom", "no_notifications": "Pas de notification", "no_people_found": "Aucune personne correspondante trouvée", "no_places": "Pas de lieu", + "no_remote_assets_found": "Aucun média distant trouvé avec cette empreinte numerique", "no_results": "Aucun résultat", "no_results_description": "Essayez un synonyme ou un mot-clé plus général", "no_shared_albums_message": "Créer un album pour partager vos photos et vidéos avec les personnes de votre réseau", "no_uploads_in_progress": "Pas d'envoi en cours", + "not_available": "N/A", "not_in_any_album": "Dans aucun album", "not_selected": "Non sélectionné", "note_apply_storage_label_to_previously_uploaded assets": "Note : Pour appliquer l'étiquette de stockage aux médias précédemment envoyés, exécutez", @@ -1499,6 +1529,7 @@ "port": "Port", "preferences_settings_subtitle": "Gérer les préférences de l'application", "preferences_settings_title": "Préférences", + "preparing": "Préparation", "preset": "Préréglage", "preview": "Aperçu", "previous": "Précédent", @@ -1564,6 +1595,7 @@ "read_changelog": "Lire les changements", "readonly_mode_disabled": "Mode lecture seule désactivé", "readonly_mode_enabled": "Mode lecture seule activé", + "ready_for_upload": "Téléchargement prêt", "reassign": "Réattribuer", "reassigned_assets_to_existing_person": "{count, plural, one {# média réattribué} other {# médias réattribués}} à {name, select, null {une personne existante} other {{name}}}", "reassigned_assets_to_new_person": "{count, plural, one {# média réattribué} other {# médias réattribués}} à une nouvelle personne", @@ -1588,6 +1620,7 @@ "regenerating_thumbnails": "Regénération des miniatures", "remote": "À distance", "remote_assets": "Média à distance", + "remote_media_summary": "Résumé du média distant", "remove": "Supprimer", "remove_assets_album_confirmation": "Êtes-vous sûr de vouloir supprimer {count, plural, one {# média} other {# médias}} de l'album ?", "remove_assets_shared_link_confirmation": "Êtes-vous sûr de vouloir supprimer {count, plural, one {# média} other {# médias}} de ce lien partagé ?", @@ -1863,6 +1896,7 @@ "show_slideshow_transition": "Afficher la transition du diaporama", "show_supporter_badge": "Badge de contributeur", "show_supporter_badge_description": "Afficher le badge de contributeur", + "show_text_search_menu": "Afficher le menu de recherche de texte", "shuffle": "Mélanger", "sidebar": "Barre latérale", "sidebar_display_description": "Afficher un lien vers la vue dans la barre latérale", @@ -1893,6 +1927,7 @@ "stacktrace": "Trace de la pile", "start": "Commencer", "start_date": "Date de début", + "start_date_before_end_date": "La date de début doit être avant la date de fin", "state": "Région", "status": "Statut", "stop_casting": "Arrêter la diffusion", @@ -2095,5 +2130,6 @@ "yes": "Oui", "you_dont_have_any_shared_links": "Vous n'avez aucun lien partagé", "your_wifi_name": "Nom du réseau wifi", - "zoom_image": "Zoomer" + "zoom_image": "Zoomer", + "zoom_to_bounds": "Zoom sur la zone" } diff --git a/i18n/gl.json b/i18n/gl.json index 6851b8e7c2..b6a59fadc7 100644 --- a/i18n/gl.json +++ b/i18n/gl.json @@ -45,11 +45,18 @@ "authentication_settings_disable_all": "Estás seguro de que queres desactivar todos os métodos de inicio de sesión? O inicio de sesión desactivarase completamente.", "authentication_settings_reenable": "Para reactivalo, use un Comando de servidor.", "background_task_job": "Tarefas en segundo plano", - "backup_database": "Copia de seguridade da base de datos", - "backup_database_enable_description": "Activar copias de seguridade da base de datos", + "backup_database": "Crear un vertedoiro de base de datos", + "backup_database_enable_description": "Activar o vertedoiro de copias de seguridade da base de datos", "backup_keep_last_amount": "Cantidade de copias de seguridade anteriores a conservar", + "backup_onboarding_1_description": "Copia no exterior na nube ou noutra localización física.", + "backup_onboarding_2_description": "Copias locais en diferentes dispositivos. Isto inclue os arquivos principais e as copias de esos arquivos localmente.", + "backup_onboarding_3_description": "copias totais da tua información, incluindo os arquivos orixinais. Isto inclue 1 copia externa e 2 copias locais.", + "backup_onboarding_description": "Unha estratexia de copia 3-2-1 é recomendada para protexer os teus datos. Deberías gardar copias das túas fotos/videos subidas así como da base de datos de Immich como unha solución de seguridade.", + "backup_onboarding_footer": "Pra máis información sobre copias de seguridade de Immich, por favor use a seguinte ligazón de documentación.", + "backup_onboarding_parts_title": "Unha copia de seguridade 3-2-1 inclue:", + "backup_onboarding_title": "Copia de seguridade", "backup_settings": "Configuración da copia de seguridade", - "backup_settings_description": "Xestionar a configuración da copia de seguridade da base de datos", + "backup_settings_description": "Xestionar a configuración do volcado da base de datos", "cleared_jobs": "Traballos borrados para: {job}", "config_set_by_file": "A configuración establécese actualmente mediante un ficheiro de configuración", "confirm_delete_library": "Estás seguro de que queres eliminar a biblioteca {library}?", @@ -116,6 +123,13 @@ "logging_enable_description": "Activar rexistro", "logging_level_description": "Cando estea activado, que nivel de rexistro usar.", "logging_settings": "Rexistro", + "machine_learning_availability_checks": "Comprobacións de dispoñibilidade", + "machine_learning_availability_checks_description": "Detectar automáticamente e preferir servidores de aprendizaxe profunda dispoñibles", + "machine_learning_availability_checks_enabled": "Activar comprobacións de dispoñibilidade", + "machine_learning_availability_checks_interval": "Intervalo de comprobación", + "machine_learning_availability_checks_interval_description": "Intervalo en milisegundos entre comprobacións de dispoñibilidade", + "machine_learning_availability_checks_timeout": "Tempo de espera da solicitude", + "machine_learning_availability_checks_timeout_description": "Tempo de espera en milisegundos para as comprobación de dispoñibilidade", "machine_learning_clip_model": "Modelo CLIP", "machine_learning_clip_model_description": "O nome dun modelo CLIP listado aquí. Ten en conta que debe volver executar o traballo 'Busca Intelixente' para todas as imaxes ao cambiar un modelo.", "machine_learning_duplicate_detection": "Detección de duplicados", @@ -170,6 +184,19 @@ "metadata_settings_description": "Xestionar a configuración de metadatos", "migration_job": "Migración", "migration_job_description": "Migrar miniaturas de activos e caras á última estrutura de cartafoles", + "nightly_tasks_cluster_faces_setting_description": "Executar recoñecemento facial nas novas caras detectadas", + "nightly_tasks_cluster_new_faces_setting": "Agrupar novas caras", + "nightly_tasks_database_cleanup_setting": "Tarefas de limpeza da base de datos", + "nightly_tasks_database_cleanup_setting_description": "Limpar información vella e obsoleta da base de datos", + "nightly_tasks_generate_memories_setting": "Xerar memorias", + "nightly_tasks_generate_memories_setting_description": "Crear novas memorias dende os recursos", + "nightly_tasks_missing_thumbnails_setting": "Xerar as miniaturas que faltan", + "nightly_tasks_missing_thumbnails_setting_description": "Encolar arquivos sin miniaturas para a xeración das miniaturas", + "nightly_tasks_settings": "Configuración das tarefas nocturnas", + "nightly_tasks_settings_description": "Administrar as tarefas nocturnas", + "nightly_tasks_start_time_setting": "Tempo de inicio", + "nightly_tasks_start_time_setting_description": "O tempo no que o servidor comeza a executar as tarefas nocturnas", + "nightly_tasks_sync_quota_usage_setting": "Sincronizar uso de cuota", "no_paths_added": "Non se engadiron rutas", "no_pattern_added": "Non se engadiu ningún padrón", "note_apply_storage_label_previous_assets": "Nota: Para aplicar a Etiqueta de Almacenamento a activos cargados previamente, execute o", diff --git a/i18n/he.json b/i18n/he.json index d8529413a0..5f71e2c8a8 100644 --- a/i18n/he.json +++ b/i18n/he.json @@ -123,6 +123,13 @@ "logging_enable_description": "אפשר רישום ביומן", "logging_level_description": "כאשר פועל, באיזה רמת יומן לתעד.", "logging_settings": "רישום ביומן", + "machine_learning_availability_checks": "בדיקת זמינות", + "machine_learning_availability_checks_description": "זהה ותעדף אוטומטית שרתי למידת מכונה זמינים", + "machine_learning_availability_checks_enabled": "הפעלת בדיקות זמינות", + "machine_learning_availability_checks_interval": "תזמון בדיקה", + "machine_learning_availability_checks_interval_description": "מרווח זמן במילישניות בין בדיקות זמינות", + "machine_learning_availability_checks_timeout": "פסק זמן לבקשה", + "machine_learning_availability_checks_timeout_description": "פסק זמן במילישניות עבור בדיקות זמינות", "machine_learning_clip_model": "מודל CLIP", "machine_learning_clip_model_description": "שמו של מודל CLIP רשום כאן. שים לב שעליך להפעיל מחדש את המשימה 'חיפוש חכם' עבור כל התמונות בעת שינוי מודל.", "machine_learning_duplicate_detection": "איתור כפילויות", @@ -387,8 +394,6 @@ "admin_password": "סיסמת מנהל", "administration": "ניהול", "advanced": "מתקדם", - "advanced_settings_beta_timeline_subtitle": "נסה את חווית האפליקציה החדשה", - "advanced_settings_beta_timeline_title": "ציר זמן (בטא)", "advanced_settings_enable_alternate_media_filter_subtitle": "השתמש באפשרות זו כדי לסנן מדיה במהלך הסנכרון לפי קריטריונים חלופיים. מומלץ להשתמש בזה רק אם יש בעיה בזיהוי כל האלבומים באפליקציה.", "advanced_settings_enable_alternate_media_filter_title": "[ניסיוני] השתמש במסנן סנכרון אלבום חלופי שמבכשיר", "advanced_settings_log_level_title": "רמת רישום ביומן: {level}", @@ -425,6 +430,7 @@ "album_remove_user_confirmation": "האם באמת ברצונך להסיר את {user}?", "album_search_not_found": "לא נמצאו אלבומים התואמים לחיפוש שלך", "album_share_no_users": "נראה ששיתפת את האלבום הזה עם כל המשתמשים או שאין לך אף משתמש לשתף איתו.", + "album_summary": "תקציר אלבום", "album_updated": "אלבום עודכן", "album_updated_setting_description": "קבל הודעת דוא\"ל כאשר לאלבום משותף יש תמונות חדשות", "album_user_left": "עזב את {album}", @@ -496,6 +502,8 @@ "asset_restored_successfully": "תמונה שוחזרה בהצלחה", "asset_skipped": "דילג", "asset_skipped_in_trash": "באשפה", + "asset_trashed": "התמונה הועברה לאשפה", + "asset_troubleshoot": "פתרון בעיות בתמונות", "asset_uploaded": "הועלה", "asset_uploading": "מעלה…", "asset_viewer_settings_subtitle": "ניהול הגדרות מציג הגלריה שלך", @@ -529,8 +537,10 @@ "autoplay_slideshow": "מצגת תמונות אוטומטית", "back": "חזרה", "back_close_deselect": "חזור, סגור, או בטל בחירה", + "background_backup_running_error": "גיבוי ברקע פועל כעת, לא ניתן להפעיל גיבוי ידני", "background_location_permission": "הרשאת מיקום ברקע", "background_location_permission_content": "כדי להחליף רשתות בעת ריצה ברקע, היישום צריך *תמיד* גישה למיקום מדויק על מנת לקרוא את השם של רשת האינטרנט האלחוטי", + "background_options": "אפשרויות רקע", "backup": "גיבוי", "backup_album_selection_page_albums_device": "({count}) אלבומים במכשיר", "backup_album_selection_page_albums_tap": "הקש כדי לכלול, הקש פעמיים כדי להחריג", @@ -538,6 +548,7 @@ "backup_album_selection_page_select_albums": "בחירת אלבומים", "backup_album_selection_page_selection_info": "פרטי בחירה", "backup_album_selection_page_total_assets": "סה״כ תמונות ייחודיות", + "backup_albums_sync": "סנכרון אלבומי גיבוי", "backup_all": "הכל", "backup_background_service_backup_failed_message": "נכשל בגיבוי תמונות. מנסה שוב…", "backup_background_service_connection_failed_message": "נכשל בהתחברות לשרת. מנסה שוב…", @@ -654,6 +665,8 @@ "change_pin_code": "שנה קוד PIN", "change_your_password": "החלף את הסיסמה שלך", "changed_visibility_successfully": "הנראות שונתה בהצלחה", + "charging": "טוען", + "charging_requirement_mobile_backup": "גיבוי ברקע דורש טעינה של המכשיר", "check_corrupt_asset_backup": "בדוק גיבויים פגומים של תמונות", "check_corrupt_asset_backup_button": "בצע בדיקה", "check_corrupt_asset_backup_description": "הרץ בדיקה זו רק על Wi-Fi ולאחר שכל התמונות גובו. ההליך עשוי לקחת כמה דקות.", @@ -889,7 +902,9 @@ "error": "שגיאה", "error_change_sort_album": "שינוי סדר מיון אלבום נכשל", "error_delete_face": "שגיאה במחיקת פנים מתמונה", + "error_getting_places": "שגיאה בקבלת מקומות", "error_loading_image": "שגיאה בטעינת התמונה", + "error_loading_partners": "שגיאה בטעינת שותפים: {error}", "error_saving_image": "שגיאה: {error}", "error_tag_face_bounding_box": "שגיאה בתיוג הפנים – לא ניתן לקבל את קואורדינטות המסגרת", "error_title": "שגיאה - משהו השתבש", @@ -1054,6 +1069,7 @@ "favorites_page_no_favorites": "לא נמצאו תמונות מועדפים", "feature_photo_updated": "תמונה מייצגת עודכנה", "features": "תכונות", + "features_in_development": "תכונות בפיתוח", "features_setting_description": "ניהול תכונות היישום", "file_name": "שם הקובץ", "file_name_or_extension": "שם קובץ או סיומת", @@ -1218,6 +1234,7 @@ "local": "מקומי", "local_asset_cast_failed": "לא ניתן לשדר תמונה שלא הועלתה לשרת", "local_assets": "תמונות מקומיות", + "local_media_summary": "סיכום של מדיה מקומית", "local_network": "רשת מקומית", "local_network_sheet_info": "היישום יתחבר לשרת דרך הכתובת הזאת כאשר משתמשים ברשת האינטרנט האלחוטי שמצוינת", "location_permission": "הרשאת מיקום", @@ -1229,6 +1246,7 @@ "location_picker_longitude_hint": "הזן את קו האורך שלך כאן", "lock": "נעל", "locked_folder": "תיקיה נעולה", + "log_detail_title": "פרטי יומן", "log_out": "התנתק", "log_out_all_devices": "התנתק מכל המכשירים", "logged_in_as": "מחובר כ {user}", @@ -1259,6 +1277,7 @@ "login_password_changed_success": "סיסמה עודכנה בהצלחה", "logout_all_device_confirmation": "האם באמת ברצונך להתנתק מכל המכשירים?", "logout_this_device_confirmation": "האם באמת ברצונך להתנתק מהמכשיר הזה?", + "logs": "יומנים", "longitude": "קו אורך", "look": "מראה", "loop_videos": "הפעלה חוזרת של סרטונים", @@ -1301,6 +1320,7 @@ "mark_as_read": "סמן כנקרא", "marked_all_as_read": "כל ההתראות סומנו כנקראו", "matches": "התאמות", + "matching_assets": "תמונות תואמות", "media_type": "סוג מדיה", "memories": "זכרונות", "memories_all_caught_up": "ראית הכל", @@ -1341,6 +1361,7 @@ "name_or_nickname": "שם או כינוי", "network_requirement_photos_upload": "השתמש בנתונים ניידים לגיבוי תמונות", "network_requirement_videos_upload": "השתמש בנתונים ניידים לגיבוי סרטונים", + "network_requirements": "דרישות רשת", "network_requirements_updated": "דרישות הרשת השתנו, תור הגיבוי אופס", "networking_settings": "רשת", "networking_subtitle": "ניהול הגדרות נקודת קצה שרת", @@ -1351,6 +1372,7 @@ "new_person": "אדם חדש", "new_pin_code": "קוד PIN חדש", "new_pin_code_subtitle": "זאת הפעם הראשונה שנכנסת לתיקיה הנעולה. צור קוד PIN כדי לאבטח את הגישה לדף זה", + "new_timeline": "ציר הזמן החדש", "new_user_created": "משתמש חדש נוצר", "new_version_available": "גרסה חדשה זמינה", "newest_first": "החדש ביותר ראשון", @@ -1364,20 +1386,25 @@ "no_assets_message": "לחץ כדי להעלות את התמונה הראשונה שלך", "no_assets_to_show": "אין תמונות להצגה", "no_cast_devices_found": "לא נמצאו מכשירי שידור", + "no_checksum_local": "אין Checksum זמין - לא ניתן לאחזר תמונות מקומיות", + "no_checksum_remote": "אין Checksum זמין - לא ניתן לאחזר תמונות מהשרת", "no_duplicates_found": "לא נמצאו כפילויות.", "no_exif_info_available": "אין מידע זמין על מטא-נתונים (exif)", "no_explore_results_message": "העלה תמונות נוספות כדי לחקור את האוסף שלך.", "no_favorites_message": "הוסף מועדפים כדי למצוא במהירות את התמונות והסרטונים הכי טובים שלך", "no_libraries_message": "צור ספרייה חיצונית כדי לראות את התמונות והסרטונים שלך", + "no_local_assets_found": "לא נמצאו תמונות עם Checksum זהה", "no_locked_photos_message": "תמונות וסרטונים בתיקייה הנעולה מוסתרים ולא יופיעו בזמן הגלישה או החיפוש בספרייה שלך.", "no_name": "אין שם", "no_notifications": "אין התראות", "no_people_found": "לא נמצאו אנשים תואמים", "no_places": "אין מקומות", + "no_remote_assets_found": "לא נמצאו תמונות בשרת עם Checksum זהה", "no_results": "אין תוצאות", "no_results_description": "נסה להשתמש במילה נרדפת או במילת מפתח יותר כללית", "no_shared_albums_message": "צור אלבום כדי לשתף תמונות וסרטונים עם אנשים ברשת שלך", "no_uploads_in_progress": "אין העלאות בתהליך", + "not_available": "לא רלוונטי", "not_in_any_album": "לא בשום אלבום", "not_selected": "לא נבחרו", "note_apply_storage_label_to_previously_uploaded assets": "הערה: כדי להחיל את תווית האחסון על תמונות שהועלו בעבר, הפעל את", @@ -1499,6 +1526,7 @@ "port": "יציאה", "preferences_settings_subtitle": "ניהול העדפות יישום", "preferences_settings_title": "העדפות", + "preparing": "בהכנה", "preset": "הגדרות קבועות מראש", "preview": "תצוגה מקדימה", "previous": "הקודם", @@ -1564,10 +1592,11 @@ "read_changelog": "קרא את יומן השינויים", "readonly_mode_disabled": "מצב לקריאה בלבד מושבת", "readonly_mode_enabled": "מצב לקריאה בלבד מופעל", - "reassign": "הקצה מחדש", + "ready_for_upload": "מוכן להעלאה", + "reassign": "הקצאה מחדש", "reassigned_assets_to_existing_person": "{count, plural, one {תמונה # הוקצתה} other {# תמונות הוקצו}} מחדש אל {name, select, null {אדם קיים} other {{name}}}", "reassigned_assets_to_new_person": "{count, plural, one {תמונה # הוקצתה} other {# תמונות הוקצו}} מחדש לאדם חדש", - "reassing_hint": "הקצה תמונות שנבחרו לאדם קיים", + "reassing_hint": "הקצאת תמונות שנבחרו לאדם קיים", "recent": "חדש", "recent-albums": "אלבומים אחרונים", "recent_searches": "חיפושים אחרונים", @@ -1575,11 +1604,11 @@ "recently_added_page_title": "נוסף לאחרונה", "recently_taken": "צולם לאחרונה", "recently_taken_page_title": "צולם לאחרונה", - "refresh": "רענן", - "refresh_encoded_videos": "רענן סרטונים מקודדים", - "refresh_faces": "רענן פנים", - "refresh_metadata": "רענן מטא-נתונים", - "refresh_thumbnails": "רענן תמונות ממוזערות", + "refresh": "רענון", + "refresh_encoded_videos": "רענון סרטונים מקודדים", + "refresh_faces": "רענון פנים", + "refresh_metadata": "רענון מטא-נתונים", + "refresh_thumbnails": "רענון תמונות ממוזערות", "refreshed": "רוענן", "refreshes_every_file": "קורא מחדש את כל הקבצים הקיימים והחדשים", "refreshing_encoded_video": "מרענן סרטון מקודד", @@ -1588,15 +1617,16 @@ "regenerating_thumbnails": "מחדש תמונות ממוזערות", "remote": "מרוחק", "remote_assets": "תמונות מרוחקות", - "remove": "הסר", + "remote_media_summary": "תקציר תמונות מרוחקות", + "remove": "הסרה", "remove_assets_album_confirmation": "האם באמת ברצונך להסיר {count, plural, one {תמונה #} other {# תמונות}} מהאלבום?", - "remove_assets_shared_link_confirmation": "האם אתה בטוח שברצונך להסיר {count, plural, one {תמונה #} other {# תמונות}} מהקישור המשותף הזה?", + "remove_assets_shared_link_confirmation": "האם ברצונך להסיר {count, plural, one {תמונה #} other {# תמונות}} מהקישור המשותף הזה?", "remove_assets_title": "להסיר תמונות?", - "remove_custom_date_range": "הסר טווח תאריכים מותאם", - "remove_deleted_assets": "הסר קבצים לא מקוונים", - "remove_from_album": "הסר מאלבום", + "remove_custom_date_range": "הסרת טווח תאריכים מותאם", + "remove_deleted_assets": "הסרת קבצים לא מקוונים", + "remove_from_album": "הסרה מאלבום", "remove_from_album_action_prompt": "{count} הוסרו מהאלבום", - "remove_from_favorites": "הסר מהמועדפים", + "remove_from_favorites": "הסרה מהמועדפים", "remove_from_lock_folder_action_prompt": "{count} הוסרו מהתיקייה הנעולה", "remove_from_locked_folder": "הסר מהתיקייה הנעולה", "remove_from_locked_folder_confirmation": "האם אתה בטוח שברצונך להעביר את התמונות והסרטונים האלה מחוץ לתיקייה הנעולה? הם יהיו מוצגים בספרייה שלך.", @@ -1863,6 +1893,7 @@ "show_slideshow_transition": "הצג מעבר מצגת", "show_supporter_badge": "תג תומך", "show_supporter_badge_description": "הצג תג תומך", + "show_text_search_menu": "הצג תפריט חיפוש טקסט", "shuffle": "ערבוב", "sidebar": "סרגל צד", "sidebar_display_description": "הצג קישור לתצוגה בסרגל הצד", @@ -1893,6 +1924,7 @@ "stacktrace": "Stack trace", "start": "התחל", "start_date": "תאריך התחלה", + "start_date_before_end_date": "תאריך ההתחלה חייב להיות לפני תאריך הסיום", "state": "מדינה", "status": "מצב", "stop_casting": "הפסקת שידור", @@ -2095,5 +2127,6 @@ "yes": "כן", "you_dont_have_any_shared_links": "אין לך קישורים משותפים", "your_wifi_name": "שם אינטרנט אלחוטי שלך", - "zoom_image": "זום לתמונה" + "zoom_image": "זום לתמונה", + "zoom_to_bounds": "התמקד באזור" } diff --git a/i18n/hi.json b/i18n/hi.json index 90795e7330..385a85c2e2 100644 --- a/i18n/hi.json +++ b/i18n/hi.json @@ -381,8 +381,6 @@ "admin_password": "व्यवस्थापक पासवर्ड", "administration": "प्रशासन", "advanced": "विकसित", - "advanced_settings_beta_timeline_subtitle": "नए ऐप अनुभव को आज़माएँ", - "advanced_settings_beta_timeline_title": "बीटा टाइमलाइन", "advanced_settings_enable_alternate_media_filter_subtitle": "सिंक के दौरान वैकल्पिक मानदंडों के आधार पर मीडिया को फ़िल्टर करने के लिए इस विकल्प का उपयोग करें। इसे केवल तभी आज़माएँ जब आपको ऐप द्वारा सभी एल्बमों का पता लगाने में समस्या हो।", "advanced_settings_enable_alternate_media_filter_title": "[प्रयोगात्मक] वैकल्पिक डिवाइस एल्बम सिंक फ़िल्टर का उपयोग करें", "advanced_settings_log_level_title": "लॉग स्तर:{level}", @@ -1548,6 +1546,7 @@ "year": "वर्ष", "yes": "हाँ", "you_dont_have_any_shared_links": "आपके पास कोई साझा लिंक नहीं है", - "your_wifi_name": "Your WiFi name", - "zoom_image": "छवि ज़ूम करें" + "your_wifi_name": "आपके वाईफाई का नाम", + "zoom_image": "छवि ज़ूम करें", + "zoom_to_bounds": "सीमा तक ज़ूम करें" } diff --git a/i18n/hr.json b/i18n/hr.json index 329ff1438d..32331976c1 100644 --- a/i18n/hr.json +++ b/i18n/hr.json @@ -387,8 +387,6 @@ "admin_password": "Admin lozinka", "administration": "Administracija", "advanced": "Napredno", - "advanced_settings_beta_timeline_subtitle": "Isprobaj novo iskustvo aplikacije", - "advanced_settings_beta_timeline_title": "Beta vremenska crta", "advanced_settings_enable_alternate_media_filter_subtitle": "Koristite ovu opciju za filtriranje medija tijekom sinkronizacije na temelju alternativnih kriterija. Pokušajte ovo samo ako imate problema s aplikacijom koja ne prepoznaje sve albume.", "advanced_settings_enable_alternate_media_filter_title": "[EKSPERIMENTALNO] Koristite alternativni filter za sinkronizaciju albuma na uređaju", "advanced_settings_log_level_title": "Razina zapisivanja: {level}", diff --git a/i18n/hu.json b/i18n/hu.json index 598910789d..f000e89517 100644 --- a/i18n/hu.json +++ b/i18n/hu.json @@ -123,6 +123,13 @@ "logging_enable_description": "Naplózás engedélyezése", "logging_level_description": "Ha be van kapcsolva, milyen részletességű legyen a naplózás.", "logging_settings": "Naplózás", + "machine_learning_availability_checks": "Elérhetőség ellenőrzése", + "machine_learning_availability_checks_description": "Automatikusan keressen és válasszon elérhető gépi tanulás szervereket", + "machine_learning_availability_checks_enabled": "Elérhetőség ellenőrzésének bekapcsolása", + "machine_learning_availability_checks_interval": "Ellenőrzési intervallum", + "machine_learning_availability_checks_interval_description": "Elérhetőség-ellenőrzések közötti késleltetés milliszekundumban", + "machine_learning_availability_checks_timeout": "Kérések időkorlátja", + "machine_learning_availability_checks_timeout_description": "Elérhetőség-ellenőrzések időkorlátja milliszekundumban", "machine_learning_clip_model": "CLIP modell", "machine_learning_clip_model_description": "Egy CLIP modell neve az itt felsoroltak közül. A modell megváltoztatása után újra kell futtatni az 'Okos Keresés' feladatot minden képre.", "machine_learning_duplicate_detection": "Duplikációk Keresése", @@ -387,8 +394,6 @@ "admin_password": "Admin Jelszó", "administration": "Adminisztráció", "advanced": "Haladó", - "advanced_settings_beta_timeline_subtitle": "Próbáld ki az új alkalmazást", - "advanced_settings_beta_timeline_title": "Béta Idővonal", "advanced_settings_enable_alternate_media_filter_subtitle": "Ezzel a beállítással a szinkronizálás során alternatív kritériumok alapján szűrheted a fájlokat. Csak akkor próbáld ki, ha problémáid vannak azzal, hogy az alkalmazás nem ismeri fel az összes albumot.", "advanced_settings_enable_alternate_media_filter_title": "[KÍSÉRLETI] Alternatív eszköz album szinkronizálási szűrő használata", "advanced_settings_log_level_title": "Naplózás szintje: {level}", @@ -396,6 +401,8 @@ "advanced_settings_prefer_remote_title": "Távoli képek előnyben részesítése", "advanced_settings_proxy_headers_subtitle": "Add meg azokat a proxy fejléceket, amiket az app elküldjön minden hálózati kérésnél", "advanced_settings_proxy_headers_title": "Proxy Fejlécek", + "advanced_settings_readonly_mode_subtitle": "Bekapcsol egy írásvédett módot ahol csak fotókat nézni lehetséges, egyebek, mint több kép kiválasztása, megosztás, kivetítés és törlés ki vannak kapcsolva. Ki/bekapcsolható a felhasználó ikonjáról a fő képernyőn", + "advanced_settings_readonly_mode_title": "Írásvédett Mód", "advanced_settings_self_signed_ssl_subtitle": "Nem ellenőrzi a szerver SSL tanúsítványát. Önaláírt tanúsítvány esetén szükséges beállítás.", "advanced_settings_self_signed_ssl_title": "Önaláírt SSL tanúsítványok engedélyezése", "advanced_settings_sync_remote_deletions_subtitle": "Automatikusan törölni vagy visszaállítani egy elemet ezen az eszközön, ha az adott műveletet a weben hajtották végre", @@ -423,6 +430,7 @@ "album_remove_user_confirmation": "Biztos, hogy el szeretnéd távolítani {user} felhasználót?", "album_search_not_found": "Nem található a keresésnek megfelelő album", "album_share_no_users": "Úgy tűnik, hogy már minden felhasználóval megosztottad ezt az albumot, vagy nincs senki, akivel meg tudnád osztani.", + "album_summary": "Album összefogalaló", "album_updated": "Album frissült", "album_updated_setting_description": "Küldjön email értesítőt, amikor egy megosztott albumhoz új elemeket adnak hozzá", "album_user_left": "Kiléptél a(z) {album} albumból", @@ -461,6 +469,7 @@ "app_bar_signout_dialog_title": "Kijelentkezés", "app_settings": "Alkalmazás Beállítások", "appears_in": "Itt szerepel", + "apply_count": "Alkalmaz ({count, number})", "archive": "Archívum", "archive_action_prompt": "{count} elem hozzáadva az Archívumhoz", "archive_or_unarchive_photo": "Fotó archiválása vagy archiválásának visszavonása", @@ -493,6 +502,8 @@ "asset_restored_successfully": "Elem sikeresen helyreállítva", "asset_skipped": "Kihagyva", "asset_skipped_in_trash": "Lomtárban", + "asset_trashed": "Elem lomtárba helyezve", + "asset_troubleshoot": "Hibajavítás", "asset_uploaded": "Feltöltve", "asset_uploading": "Feltöltés…", "asset_viewer_settings_subtitle": "A képnézegető beállításainak kezelése", @@ -500,7 +511,7 @@ "assets": "Elemek", "assets_added_count": "{count, plural, other {# elem}} hozzáadva", "assets_added_to_album_count": "{count, plural, other {# elem}} hozzáadva az albumhoz", - "assets_added_to_albums_count": "Az {assetTotal, plural, one {elem} other {elemek}} hozzáadva {albumTotal} albumhoz", + "assets_added_to_albums_count": "{assetTotal, plural, one {# elem} other {# elemek}} hozzáadva {albumTotal, plural, one {# albumhoz} other {# albumokhoz}}", "assets_cannot_be_added_to_album_count": "{count, plural, one {Az elem} other {Az elemek}} nem adhatóak hozzá az albumhoz", "assets_cannot_be_added_to_albums": "Az {count, plural, one {elemet} other {elemeket}} nem lehet hozzáadni egy albumhoz sem", "assets_count": "{count, plural, other {# elem}}", @@ -526,8 +537,10 @@ "autoplay_slideshow": "Automatikus diavetítés", "back": "Vissza", "back_close_deselect": "Vissza, bezárás, vagy kijelölés törlése", + "background_backup_running_error": "Háttérben futó mentés folyamatban, kézi mentés nem indítható", "background_location_permission": "Háttérben történő helymeghatározási engedély", "background_location_permission_content": "Hálózatok automatikus váltásához az Immich-nek *mindenképpen* hozzá kell férnie a pontos helyzethez, hogy az alkalmazás le tudja kérni a Wi-Fi hálózat nevét", + "background_options": "Háttérbeli futás beállításai", "backup": "Mentés", "backup_album_selection_page_albums_device": "Ezen az eszközön lévő albumok ({count})", "backup_album_selection_page_albums_tap": "Koppints a hozzáadáshoz, duplán koppints az eltávolításhoz", @@ -535,6 +548,7 @@ "backup_album_selection_page_select_albums": "Válassz albumokat", "backup_album_selection_page_selection_info": "Összegzés", "backup_album_selection_page_total_assets": "Összes egyedi elem", + "backup_albums_sync": "Backup albumok szinkronizálása", "backup_all": "Összes", "backup_background_service_backup_failed_message": "Az elemek mentése sikertelen. Újrapróbálkozás…", "backup_background_service_connection_failed_message": "A szerverhez csatlakozás sikertelen. Újrapróbálkozás…", @@ -651,6 +665,8 @@ "change_pin_code": "PIN kód megváltoztatása", "change_your_password": "Jelszavad megváltoztatása", "changed_visibility_successfully": "Láthatóság sikeresen megváltoztatva", + "charging": "Töltés", + "charging_requirement_mobile_backup": "Háttérben mentéshez szükséges, hogy az eszköz töltőn legyen", "check_corrupt_asset_backup": "Sérült elemek keresése a mentésben", "check_corrupt_asset_backup_button": "Ellenőrzés", "check_corrupt_asset_backup_description": "Ezt az ellenőtzést csak Wi-Fi hálózaton futtasd és csak akkot, ha már az összes elem feltöltésre került. A folyamat néhány percig is eltarthat.", @@ -737,6 +753,7 @@ "create_user": "Felhasználó létrehozása", "created": "Készült", "created_at": "Létrehozva", + "creating_linked_albums": "Kapcsolt albumok létrehozása...", "crop": "Kivágás", "curated_object_page_title": "Dolgok", "current_device": "Ez az eszköz", @@ -886,7 +903,9 @@ "error": "Hiba", "error_change_sort_album": "Album sorbarendezésének megváltoztatása sikertelen", "error_delete_face": "Hiba az arc törlése során", + "error_getting_places": "Hiba a helyek betöltésekor", "error_loading_image": "Hiba a kép betöltése közben", + "error_loading_partners": "Hiba a partnerek betöltésénél: {error}", "error_saving_image": "Hiba: {error}", "error_tag_face_bounding_box": "Hiba az arc megjelölése közben - nem elérhetőek a határoló koordináták", "error_title": "Hiba - valami félresikerült", @@ -1051,6 +1070,7 @@ "favorites_page_no_favorites": "Nem található kedvencnek jelölt elem", "feature_photo_updated": "Címlapkép frissítve", "features": "Jellemzők", + "features_in_development": "Folyamatban lévő fejlesztések", "features_setting_description": "Az alkalmazás jellemzőinek kezelése", "file_name": "Fájlnév", "file_name_or_extension": "Fájlnév vagy kiterjesztés", @@ -1071,12 +1091,15 @@ "gcast_enabled": "Google Cast", "gcast_enabled_description": "Ez a funkció a Google-től tölti be a működéséhez szükséges külső adatokat.", "general": "Általános", + "geolocation_instruction_location": "Kattints egy elemre, amelynek ismert a helyszíne a pozíció kiválasztásához, vagy válassz a térképen", "get_help": "Segítségkérés", "get_wifiname_error": "Nem sikerült lekérni a Wi-Fi nevét. Győződj meg róla, hogy megadtad a szükséges engedélyeket és csatlakoztál egy Wi-Fi hálózathoz", "getting_started": "Kezdő Lépések", "go_back": "Visszalépés", "go_to_folder": "Ugrás a mappához", "go_to_search": "Ugrás a kereséshez", + "gps": "GPS", + "gps_missing": "Nincs GPS", "grant_permission": "Engedély megadása", "group_albums_by": "Albumok csoportosítása...", "group_country": "Csoportosítás ország szerint", @@ -1212,6 +1235,7 @@ "local": "Helyi", "local_asset_cast_failed": "Nem lehet olyan elemet vetíteni, ami nincs a szerverre feltöltve", "local_assets": "Helyi Elemek", + "local_media_summary": "Helyi média összegzés", "local_network": "Helyi hálózat", "local_network_sheet_info": "Az alkalmazés ezen az URL címen fogja elérni a szervert, ha a megadott WiFi hálózathoz van csatlankozva", "location_permission": "Helymeghatározási engedély", @@ -1223,6 +1247,7 @@ "location_picker_longitude_hint": "Ide írd a hosszúsági kört", "lock": "Zárolás", "locked_folder": "Zárolt mappa", + "log_detail_title": "Naplók részletei", "log_out": "Kijelentkezés", "log_out_all_devices": "Kijelentkezés Minden Eszközön", "logged_in_as": "Belépve: {user} néven", @@ -1253,6 +1278,7 @@ "login_password_changed_success": "Jelszó sikeresen módosítva", "logout_all_device_confirmation": "Biztos, hogy minden eszközön ki szeretnél jelentkezni?", "logout_this_device_confirmation": "Biztos, hogy ki szeretnél jelentkezni ezen az eszközön?", + "logs": "Naplók", "longitude": "Hosszúság", "look": "Megjelenítés", "loop_videos": "Videók ismétlése", @@ -1260,6 +1286,7 @@ "main_branch_warning": "Fejlesztői verziót használsz. Javasoljuk a stabil verzió használatát!", "main_menu": "Főmenü", "make": "Gyártó", + "manage_geolocation": "Helyadatok kezelése", "manage_shared_links": "Megosztási linkek kezelése", "manage_sharing_with_partners": "Partnerekkel való megosztás kezelése", "manage_the_app_settings": "Alkalmazás beállításainak kezelése", @@ -1294,6 +1321,7 @@ "mark_as_read": "Megjelölés olvasottként", "marked_all_as_read": "Összes megjelölve olvasottként", "matches": "Azonosak", + "matching_assets": "Kapcsolódó elemek", "media_type": "Médiatípus", "memories": "Emlékek", "memories_all_caught_up": "Naprakész vagy", @@ -1334,6 +1362,7 @@ "name_or_nickname": "Név vagy becenév", "network_requirement_photos_upload": "Mobil adatforgalmat használjon a fényképek biztonsági mentéséhez", "network_requirement_videos_upload": "Mobil adatforgalmat használjon a videók biztonsági mentéséhez", + "network_requirements": "Hálózati követelmények", "network_requirements_updated": "A hálózat megváltozott, a biztonsági mentési sor visszaállítása", "networking_settings": "Hálózat", "networking_subtitle": "Szerver végpont beállítások kezelése", @@ -1344,6 +1373,7 @@ "new_person": "Új személy", "new_pin_code": "Új PIN kód", "new_pin_code_subtitle": "Ez az első alkalom hogy megnyitod a zárolt mappát. Hozz létre egy jelszót a mappa biztonságos eléréséhez", + "new_timeline": "Új idővonal", "new_user_created": "Új felhasználó létrehozva", "new_version_available": "ÚJ VERZIÓ ÉRHETŐ EL", "newest_first": "Legújabb először", @@ -1357,20 +1387,25 @@ "no_assets_message": "KATTINTS AZ ELSŐ FÉNYKÉP FELTÖLTÉSÉHEZ", "no_assets_to_show": "Nincs megjeleníthető elem", "no_cast_devices_found": "Nem található eszköz vetítéshez", + "no_checksum_local": "Nincs elérhető ellenőrzőösszeg - a helyi eszközök nem kérhetők le", + "no_checksum_remote": "Nincs elérhető ellenőrzőösszeg - a távoli eszköz nem kérhető le", "no_duplicates_found": "Nem találhatók duplikátumok.", "no_exif_info_available": "Nincs elérhető Exif információ", "no_explore_results_message": "Tölts fel több képet, hogy böngészhesd a gyűjteményed.", "no_favorites_message": "Add hozzá a kedvencekhez, hogy gyorsan megtaláld a legjobb képeidet és videóidat", "no_libraries_message": "Hozz létre külső képtárat a fényképeid és videóid megtekintéséhez", + "no_local_assets_found": "Nem találhatók helyi eszközök ezzel az ellenőrzőösszeggel", "no_locked_photos_message": "A zárolt mappában elhelyezett fotók és videók rejtettek, és nem jelennek meg a könyvtárad böngészése vagy keresése közben sem.", "no_name": "Nincs Név", "no_notifications": "Nincsenek értesítések", "no_people_found": "Nem található személy", "no_places": "Nincsenek helyek", + "no_remote_assets_found": "Nem találhatók távoli eszközök ezzel az ellenőrzőösszeggel", "no_results": "Nincs találat", "no_results_description": "Próbálkozz szinonimákkal vagy általánosabb kulcsszavakkal", "no_shared_albums_message": "Hozz létre egy új albumot, hogy megoszthasd fényképeid és videóid másokkal", "no_uploads_in_progress": "Nincs folyamatban lévő feltöltés", + "not_available": "N/A", "not_in_any_album": "Nincs albumban", "not_selected": "Nincs kiválasztva", "note_apply_storage_label_to_previously_uploaded assets": "Megjegyzés: a korábban feltöltött elemek Tárhely Címkézéséhez futtasd a(z)", @@ -1405,6 +1440,8 @@ "open_the_search_filters": "Keresési szűrők megnyitása", "options": "Beállítások", "or": "vagy", + "organize_into_albums": "Albumokba rendezés", + "organize_into_albums_description": "Meglévő fotók albumokba helyezése, a jelenlegi szinkronizációs beállítások alapján", "organize_your_library": "Rendszerezd a képtáradat", "original": "eredeti", "other": "Egyéb", @@ -1490,6 +1527,7 @@ "port": "Port", "preferences_settings_subtitle": "Alkalmazásbeállítások kezelése", "preferences_settings_title": "Beállítások", + "preparing": "Előkészítés", "preset": "Sablon", "preview": "Előnézet", "previous": "Előző", @@ -1506,6 +1544,7 @@ "profile_drawer_client_out_of_date_minor": "A mobilalkalmazás elavult. Kérjük, frissítsd a legfrisebb alverzióra.", "profile_drawer_client_server_up_to_date": "A Kliens és a Szerver is naprakész", "profile_drawer_github": "GitHub", + "profile_drawer_readonly_mode": "Csak olvasható mód engedélyezve. A kilépéshez hosszan nyomja meg a felhasználói avatar ikont.", "profile_drawer_server_out_of_date_major": "A szerver elavult. Kérjük, frissítsd a legfrisebb főverzióra.", "profile_drawer_server_out_of_date_minor": "A szerver elavult. Kérjük, frissítsd a legfrisebb alverzióra.", "profile_image_of_user": "{user} profilképe", @@ -1544,6 +1583,7 @@ "purchase_server_description_2": "Támogató státusz", "purchase_server_title": "Szerver", "purchase_settings_server_activated": "A szerver termékkulcsot az admin kezeli", + "query_asset_id": "Lekérdezési eszköz azonosítója", "queue_status": "Feldolgozva {count}/{total}", "rating": "Értékelés csillagokkal", "rating_clear": "Értékelés törlése", @@ -1551,6 +1591,9 @@ "rating_description": "Exif értékelés megjelenítése az infópanelen", "reaction_options": "Reakció lehetőségek", "read_changelog": "Változásnapló Elolvasása", + "readonly_mode_disabled": "Csak olvasható mód kikapcsolva", + "readonly_mode_enabled": "Csak olvasható mód bekapcsolva", + "ready_for_upload": "Készen áll a feltöltésre", "reassign": "Hozzárendel", "reassigned_assets_to_existing_person": "{count, plural, other {# elem}} hozzárendelve{name, select, null { egy létező személyhez} other {: {name}}}", "reassigned_assets_to_new_person": "{count, plural, other {# elem}} hozzárendelve egy új személyhez", @@ -1575,6 +1618,7 @@ "regenerating_thumbnails": "Bélyegképek újragenerálása folyamatban", "remote": "Távoli", "remote_assets": "Távoli Elemek", + "remote_media_summary": "Távoli médiaösszefoglaló", "remove": "Eltávolítás", "remove_assets_album_confirmation": "Biztosan el szeretnél távolítani {count, plural, one {# elemet} other {# elemet}} az albumból?", "remove_assets_shared_link_confirmation": "Biztosan el szeretnél távolítani {count, plural, one {# elemet} other {# elemet}} ebből a megosztott linkből?", @@ -1627,6 +1671,7 @@ "restore_user": "Felhasználó visszaállítása", "restored_asset": "Visszaállított elem", "resume": "Folytatás", + "resume_paused_jobs": "Folytatás {count, plural, one {# paused job} other {# paused jobs}}", "retry_upload": "Feltöltés újrapróbálása", "review_duplicates": "Duplikátumok áttekintése", "review_large_files": "Nagy fájlok áttekintése", @@ -1720,6 +1765,7 @@ "select_user_for_sharing_page_err_album": "Az album létrehozása sikertelen", "selected": "Kiválasztott", "selected_count": "{count, plural, other {# kiválasztva}}", + "selected_gps_coordinates": "Kiválasztott GPS Kordináták", "send_message": "Üzenet küldése", "send_welcome_email": "Üdvözlő email küldése", "server_endpoint": "Szerver Végpont", @@ -1848,6 +1894,7 @@ "show_slideshow_transition": "Vetítés áttűnési effekt mutatása", "show_supporter_badge": "Támogató jelvény", "show_supporter_badge_description": "Támogató jelvény mutatása", + "show_text_search_menu": "Mutasd a szövegkeresési menüt", "shuffle": "Véletlenszerű", "sidebar": "Oldalsáv", "sidebar_display_description": "Nézet link megjelenítése az oldalsávban", @@ -1878,6 +1925,7 @@ "stacktrace": "Hiba leírása", "start": "Elindít", "start_date": "Kezdő dátum", + "start_date_before_end_date": "A kezdeti dátumnak a befejezési dátum előtt kell lennie", "state": "Megye/Állam", "status": "Állapot", "stop_casting": "Vetítés megszüntetése", @@ -1902,6 +1950,8 @@ "sync_albums_manual_subtitle": "Összes fotó és videó létrehozása és szinkronizálása a kiválasztott Immich albumokba", "sync_local": "Helyi Szinkronizálása", "sync_remote": "Távoli Szinkronizálása", + "sync_status": "Szinkronizálás állapota", + "sync_status_subtitle": "Szinkronizálás megtekintése és kezelése", "sync_upload_album_setting_subtitle": "Fotók és videók létrehozása és szinkronizálása a kiválasztott Immich albumba", "tag": "Címke", "tag_assets": "Elemek címkézése", @@ -1939,7 +1989,9 @@ "to_change_password": "Jelszó megváltoztatása", "to_favorite": "Kedvenc", "to_login": "Bejelentkezés", + "to_multi_select": "több elem kiválasztásához", "to_parent": "Egy szinttel feljebb", + "to_select": "a kiválasztáshoz", "to_trash": "Lomtárba helyezés", "toggle_settings": "Beállítások átállítása", "total": "Összesen", @@ -1959,6 +2011,7 @@ "trash_page_select_assets_btn": "Elemek kiválasztása", "trash_page_title": "Lomtár ({count})", "trashed_items_will_be_permanently_deleted_after": "A lomtárban lévő elemek véglegesen törlésre kerülnek {days, plural, other {# nap}} múlva.", + "troubleshoot": "Hibaelhárítás", "type": "Típus", "unable_to_change_pin_code": "Sikertelen PIN kód változtatás", "unable_to_setup_pin_code": "Sikertelen PIN kód beállítás", @@ -1989,6 +2042,7 @@ "unstacked_assets_count": "{count, plural, other {# elemből}} álló csoport szétszedve", "untagged": "Címke eltávolítva", "up_next": "Következik", + "update_location_action_prompt": "{count} elem pozíciójának frissítése a következővel:", "updated_at": "Frissített", "updated_password": "Jelszó megváltoztatva", "upload": "Feltöltés", @@ -2055,6 +2109,7 @@ "view_next_asset": "Következő elem megtekintése", "view_previous_asset": "Előző elem megtekintése", "view_qr_code": "QR kód megtekintése", + "view_similar_photos": "Hasonló képek keresése", "view_stack": "Csoport Megtekintése", "view_user": "Felhasználó Megtekintése", "viewer_remove_from_stack": "Eltávolít a Csoportból", @@ -2073,5 +2128,6 @@ "yes": "Igen", "you_dont_have_any_shared_links": "Nincsenek megosztott linkjeid", "your_wifi_name": "A Wi-Fi hálózatod neve", - "zoom_image": "Kép Nagyítása" + "zoom_image": "Kép Nagyítása", + "zoom_to_bounds": "Nagyítás a határokhoz" } diff --git a/i18n/id.json b/i18n/id.json index abe57386ac..8dba86752e 100644 --- a/i18n/id.json +++ b/i18n/id.json @@ -123,6 +123,13 @@ "logging_enable_description": "Aktifkan log", "logging_level_description": "Ketika diaktifkan, tingkat log apa yang digunakan.", "logging_settings": "Penulisan log", + "machine_learning_availability_checks": "Pemeriksaan ketersediaan", + "machine_learning_availability_checks_description": "Secara otomatis mendeteksi dan memprioritaskan server machine learning yang tersedia", + "machine_learning_availability_checks_enabled": "Aktifkan pemeriksaan ketersediaan", + "machine_learning_availability_checks_interval": "Interval pemeriksaan", + "machine_learning_availability_checks_interval_description": "Interval dalam milidetik antar pemeriksaan ketersediaan", + "machine_learning_availability_checks_timeout": "Batas waktu permintaan", + "machine_learning_availability_checks_timeout_description": "Batas waktu dalam milidetik untuk pemeriksaan ketersediaan", "machine_learning_clip_model": "Model CLIP", "machine_learning_clip_model_description": "Nama model CLIP yang didaftarkan di sini. Anda harus menjalankan ulang tugas 'Pencarian Otomatis' untuk semua gambar ketika mengganti model.", "machine_learning_duplicate_detection": "Deteksi Duplikat", @@ -387,8 +394,6 @@ "admin_password": "Kata Sandi Admin", "administration": "Administrasi", "advanced": "Tingkat lanjut", - "advanced_settings_beta_timeline_subtitle": "Coba pengalaman aplikasi baru", - "advanced_settings_beta_timeline_title": "Garis waktu Beta", "advanced_settings_enable_alternate_media_filter_subtitle": "Gunakan opsi ini untuk menyaring media saat sinkronisasi berdasarkan kriteria alternatif. Hanya coba ini dengan aplikasi mendeteksi semua album.", "advanced_settings_enable_alternate_media_filter_title": "[EKSPERIMENTAL] Gunakan saringan sinkronisasi album perangkat alternatif", "advanced_settings_log_level_title": "Tingkat log: {level}", @@ -425,6 +430,7 @@ "album_remove_user_confirmation": "Apakah Anda yakin ingin mengeluarkan {user}?", "album_search_not_found": "Tidak ada album yang ditemukan sesuai pencarian Anda", "album_share_no_users": "Sepertinya Anda telah membagikan album ini dengan semua pengguna atau tidak memiliki pengguna siapa pun untuk dibagikan.", + "album_summary": "Ringkasan album", "album_updated": "Album diperbarui", "album_updated_setting_description": "Terima notifikasi surel ketika album terbagi memiliki aset baru", "album_user_left": "Keluar dari {album}", @@ -496,6 +502,8 @@ "asset_restored_successfully": "Aset telah berhasil dipulihkan", "asset_skipped": "Dilewati", "asset_skipped_in_trash": "Dalam sampah", + "asset_trashed": "Aset dibuang", + "asset_troubleshoot": "Troubleshoot Aset", "asset_uploaded": "Sudah diunggah", "asset_uploading": "Mengunggah…", "asset_viewer_settings_subtitle": "Kelola pengaturan penampil galeri Anda", @@ -529,8 +537,10 @@ "autoplay_slideshow": "Putar otomatis tayangan slide", "back": "Kembali", "back_close_deselect": "Kembali, tutup, atau batalkan pemilihan", + "background_backup_running_error": "Cadangan latar belakang sedang berjalan, tidak dapat memulai cadangan manual", "background_location_permission": "Izin lokasi latar belakang", "background_location_permission_content": "Untuk beralih jaringan saat berjalan di latar belakang, Immich harus selalu memiliki akses lokasi akurat agar aplikasi dapat membaca nama jaringan Wi-Fi", + "background_options": "Opsi Latar Belakang", "backup": "Cadangkan", "backup_album_selection_page_albums_device": "Album di perangkat ({count})", "backup_album_selection_page_albums_tap": "Sentuh untuk memilih, sentuh 2x untuk mengecualikan", @@ -538,6 +548,7 @@ "backup_album_selection_page_select_albums": "Pilih album", "backup_album_selection_page_selection_info": "Info Pilihan", "backup_album_selection_page_total_assets": "Total aset unik", + "backup_albums_sync": "Sinkronisasi cadangan album", "backup_all": "Semua", "backup_background_service_backup_failed_message": "Gagal mencadangkan aset. Mencoba lagi…", "backup_background_service_connection_failed_message": "Koneksi ke server gagal. Mencoba ulang…", @@ -654,6 +665,8 @@ "change_pin_code": "Ubah kode PIN", "change_your_password": "Ubah kata sandi Anda", "changed_visibility_successfully": "Keterlihatan berhasil diubah", + "charging": "Mengisi daya", + "charging_requirement_mobile_backup": "Cadangan latar belakang memerlukan perangkat dalam keadaan mengisi daya", "check_corrupt_asset_backup": "Periksa cadangan aset yang rusak", "check_corrupt_asset_backup_button": "Lakukan pemeriksaan", "check_corrupt_asset_backup_description": "Jalankan pemeriksaan ini hanya melalui Wi-Fi dan setelah semua aset dicadangkan. Prosedur ini mungkin memerlukan waktu beberapa menit.", @@ -740,6 +753,7 @@ "create_user": "Buat pengguna", "created": "Dibuat", "created_at": "Dibuat", + "creating_linked_albums": "Membuat album tertaut...", "crop": "Pangkas", "curated_object_page_title": "Benda", "current_device": "Perangkat saat ini", @@ -889,7 +903,9 @@ "error": "Eror", "error_change_sort_album": "Gagal mengubah urutan album", "error_delete_face": "Terjadi kesalahan menghapus wajah dari aset", + "error_getting_places": "Kesalahan saat mengambil lokasi", "error_loading_image": "Terjadi eror memuat gambar", + "error_loading_partners": "Kesalahan saat memuat partner: {error}", "error_saving_image": "Kesalahan: {error}", "error_tag_face_bounding_box": "Galat saat memberi tag wajah – tidak dapat memperoleh koordinat kotak pembatas", "error_title": "Eror - Ada yang salah", @@ -1054,6 +1070,7 @@ "favorites_page_no_favorites": "Tidak ada aset favorit", "feature_photo_updated": "Foto terfitur diperbarui", "features": "Fitur", + "features_in_development": "Fitur dalam Pengembangan", "features_setting_description": "Kelola fitur aplikasi", "file_name": "Nama berkas", "file_name_or_extension": "Nama berkas atau ekstensi", @@ -1218,6 +1235,7 @@ "local": "Lokal", "local_asset_cast_failed": "Tidak dapat melakukan cast aset yang belum diunggah ke server", "local_assets": "Aset Lokal", + "local_media_summary": "Ringkasan Media Lokal", "local_network": "Jaringan Lokal", "local_network_sheet_info": "Aplikasi akan terhubung ke server melalui URL ini saat menggunakan jaringan Wi-Fi yang ditentukan", "location_permission": "Izin lokasi", @@ -1229,6 +1247,7 @@ "location_picker_longitude_hint": "Masukkan bujur di sini", "lock": "Kunci", "locked_folder": "Folder Terkunci", + "log_detail_title": "Detail Log", "log_out": "Log keluar", "log_out_all_devices": "Keluar dari Semua Perangkat", "logged_in_as": "Masuk sebagai {user}", @@ -1259,6 +1278,7 @@ "login_password_changed_success": "Sandi berhasil diperbarui", "logout_all_device_confirmation": "Apakah Anda yakin ingin keluar dari semua perangkat?", "logout_this_device_confirmation": "Apakah Anda yakin ingin mengeluarkan perangkat ini?", + "logs": "Log", "longitude": "Bujur", "look": "Tampilan", "loop_videos": "Ulangi video", @@ -1301,6 +1321,7 @@ "mark_as_read": "Tandai sebagai telah dibaca", "marked_all_as_read": "Semua telah ditandai sebagai telah dibaca", "matches": "Cocokan", + "matching_assets": "Aset yang Cocok", "media_type": "Jenis media", "memories": "Kenangan", "memories_all_caught_up": "Semua telah dilihat", @@ -1341,6 +1362,7 @@ "name_or_nickname": "Nama atau nama panggilan", "network_requirement_photos_upload": "Gunakan data seluler untuk cadangkan foto", "network_requirement_videos_upload": "Gunakan data seluler untuk cadangkan video", + "network_requirements": "Persyaratan Jaringan", "network_requirements_updated": "Persyaratan jaringan telah berubah, antrean pencadangan diatur ulang", "networking_settings": "Jaringan", "networking_subtitle": "Kelola pengaturan Endpoint server", @@ -1351,6 +1373,7 @@ "new_person": "Orang baru", "new_pin_code": "Kode PIN baru", "new_pin_code_subtitle": "Ini adalah akses pertama Anda ke folder terkunci. Buat kode PIN untuk mengamankan akses ke halaman ini", + "new_timeline": "Linimasa Baru", "new_user_created": "Pengguna baru dibuat", "new_version_available": "VERSI BARU TERSEDIA", "newest_first": "Terkini dahulu", @@ -1364,20 +1387,25 @@ "no_assets_message": "KLIK UNTUK MENGUNGGAH FOTO PERTAMA ANDA", "no_assets_to_show": "Tidak ada aset", "no_cast_devices_found": "Tidak ada perangkat cast yang ditemukan", + "no_checksum_local": "Tidak ada checksum yang tersedia - tidak dapat mengambil aset lokal", + "no_checksum_remote": "Tidak ada checksum yang tersedia - tidak dapat mengambil aset jarak jauh", "no_duplicates_found": "Tidak ada duplikat yang ditemukan.", "no_exif_info_available": "Tidak ada info EXIF yang tersedia", "no_explore_results_message": "Unggah lebih banyak foto untuk menjelajahi koleksi Anda.", "no_favorites_message": "Tambahkan favorit untuk mencari foto dan video terbaik Anda dengan cepat", "no_libraries_message": "Buat pustaka eksternal untuk menampilkan foto dan video Anda", + "no_local_assets_found": "Tidak ada aset lokal yang ditemukan dengan checksum ini", "no_locked_photos_message": "Foto dan video di folder terkunci disembunyikan dan tidak akan muncul saat Anda menelusuri atau mencari di pustaka.", "no_name": "Tidak Ada Nama", "no_notifications": "Tidak ada notifikasi", "no_people_found": "Orang tidak ditemukan", "no_places": "Tidak ada tempat", + "no_remote_assets_found": "Tidak ada aset jarak jauh yang ditemukan dengan checksum ini", "no_results": "Tidak ada hasil", "no_results_description": "Coba sinonim atau kata kunci yang lebih umum", "no_shared_albums_message": "Buat sebuah album untuk membagikan foto dan video dengan orang-orang dalam jaringan Anda", "no_uploads_in_progress": "Tidak ada unggahan yang sedang berlangsung", + "not_available": "T/T", "not_in_any_album": "Tidak ada dalam album apa pun", "not_selected": "Belum dipilih", "note_apply_storage_label_to_previously_uploaded assets": "Catatan: Untuk menerapkan Label Penyimpanan pada aset yang sebelumnya telah diunggah, jalankan", @@ -1499,6 +1527,7 @@ "port": "Porta", "preferences_settings_subtitle": "Kelola preferensi aplikasi", "preferences_settings_title": "Preferensi", + "preparing": "Mempersiapkan", "preset": "Prasetel", "preview": "Pratinjau", "previous": "Sebelumnya", @@ -1515,7 +1544,7 @@ "profile_drawer_client_out_of_date_minor": "Versi app seluler ini sudah kedaluwarsa. Silakan perbarui ke versi minor terbaru.", "profile_drawer_client_server_up_to_date": "Klien dan server menjalankan versi terbaru", "profile_drawer_github": "GitHub", - "profile_drawer_readonly_mode": "Mode baca-saja aktif. Ketuk dua kali ikon avatar pengguna untuk keluar.", + "profile_drawer_readonly_mode": "Mode baca-saja aktif. Tekan lama ikon avatar pengguna untuk keluar.", "profile_drawer_server_out_of_date_major": "Versi server ini telah kedaluwarsa. Silakan perbarui ke versi major terbaru.", "profile_drawer_server_out_of_date_minor": "Versi server ini telah kedaluwarsa. Silakan perbarui ke versi minor terbaru.", "profile_image_of_user": "Foto profil dari {user}", @@ -1564,6 +1593,7 @@ "read_changelog": "Baca Log Perubahan", "readonly_mode_disabled": "Mode baca-saja dimatikan", "readonly_mode_enabled": "Mode baca-saja diaktifkan", + "ready_for_upload": "Siap untuk mengunggah", "reassign": "Tetapkan ulang", "reassigned_assets_to_existing_person": "Menetapkan ulang {count, plural, one {# aset} other {# aset}} kepada {name, select, null {orang yang sudah ada} other {{name}}}", "reassigned_assets_to_new_person": "Menetapkan ulang {count, plural, one {# aset} other {# aset}} kepada orang baru", @@ -1588,6 +1618,7 @@ "regenerating_thumbnails": "Membuat ulang gambar kecil", "remote": "Jarak Jauh", "remote_assets": "Aset Jarak Jauh", + "remote_media_summary": "Ringkasan Media Jarak Jauh", "remove": "Hapus", "remove_assets_album_confirmation": "Apakah Anda yakin ingin menghapus {count, plural, one {# aset} other {# aset}} dari album?", "remove_assets_shared_link_confirmation": "Apakah Anda yakin ingin menghapus {count, plural, one {# aset} other {# aset}} dari tautan terbagi ini?", @@ -1640,6 +1671,7 @@ "restore_user": "Pulihkan pengguna", "restored_asset": "Aset dipulihkan", "resume": "Lanjutkan", + "resume_paused_jobs": "Lanjutkan {count, plural, one {# pekerjaan yang dijeda} other {# pekerjaan yang dijeda}}", "retry_upload": "Ulangi pengunggahan", "review_duplicates": "Pratinjau duplikat", "review_large_files": "Meninjau berkas berukuran besar", @@ -1862,6 +1894,7 @@ "show_slideshow_transition": "Tampilkan transisi salindia", "show_supporter_badge": "Lencana suporter", "show_supporter_badge_description": "Tampilkan lencana suporter", + "show_text_search_menu": "Tampilkan menu pencarian teks", "shuffle": "Acak", "sidebar": "Bilah sisi", "sidebar_display_description": "Menampilkan tautan ke tampilan di bilah sisi", @@ -1892,6 +1925,7 @@ "stacktrace": "Jejak tumpukan", "start": "Mulai", "start_date": "Tanggal mulai", + "start_date_before_end_date": "Tanggal mulai harus sebelum tanggal akhir", "state": "Keadaan", "status": "Status", "stop_casting": "Hentikan cast", @@ -1916,6 +1950,8 @@ "sync_albums_manual_subtitle": "Melakukan sinkronisasi semua video dan foto yang telah diunggah ke album cadangan yang dipilih", "sync_local": "Sinkronkan lokal", "sync_remote": "Sinkronkan jarak jauh", + "sync_status": "Status Sinkronisasi", + "sync_status_subtitle": "Lihat dan atur sistem sinkronisasi", "sync_upload_album_setting_subtitle": "Membuat dan mengunggah foto serta video Anda ke album yang telah dipilih pada Immich", "tag": "Label", "tag_assets": "Tag aset", @@ -1975,6 +2011,7 @@ "trash_page_select_assets_btn": "Pilih aset", "trash_page_title": "Sampah ({count})", "trashed_items_will_be_permanently_deleted_after": "Item yang dibuang akan dihapus secara permanen setelah {days, plural, one {# hari} other {# hari}}.", + "troubleshoot": "Pemecahan Masalah", "type": "Jenis", "unable_to_change_pin_code": "Tidak dapat mengubah kode PIN", "unable_to_setup_pin_code": "Tidak dapat memasang kode PIN", @@ -2091,5 +2128,6 @@ "yes": "Ya", "you_dont_have_any_shared_links": "Anda tidak memiliki tautan terbagi", "your_wifi_name": "Nama Wi-Fi Anda", - "zoom_image": "Perbesar Gambar" + "zoom_image": "Perbesar Gambar", + "zoom_to_bounds": "Perbesar ke batas" } diff --git a/i18n/it.json b/i18n/it.json index eca0ebf644..a86dd78ca6 100644 --- a/i18n/it.json +++ b/i18n/it.json @@ -28,6 +28,7 @@ "add_to_album": "Aggiungi all'album", "add_to_album_bottom_sheet_added": "Aggiunto in {album}", "add_to_album_bottom_sheet_already_exists": "Già presente in {album}", + "add_to_album_bottom_sheet_some_local_assets": "Alcune risorse locali non possono essere aggiunte all'album", "add_to_album_toggle": "Attiva/disattiva selezione per {album}", "add_to_albums": "Aggiungi ad album", "add_to_albums_count": "Aggiungi ad album ({count})", @@ -123,6 +124,13 @@ "logging_enable_description": "Attiva il logging", "logging_level_description": "Quando attivato, che livello di log utilizzare.", "logging_settings": "Registro dei Log", + "machine_learning_availability_checks": "Verifiche di disponibilità", + "machine_learning_availability_checks_description": "Rileva automaticamente e usa i server di machine learning disponibili", + "machine_learning_availability_checks_enabled": "Attiva verifiche di disponibilità", + "machine_learning_availability_checks_interval": "Intervallo di verifica", + "machine_learning_availability_checks_interval_description": "Intervallo (ms) tra le verifiche di disponibilità", + "machine_learning_availability_checks_timeout": "Timeout richiesta", + "machine_learning_availability_checks_timeout_description": "Timeout (ms) per le verifiche di disponibilità", "machine_learning_clip_model": "Modello CLIP", "machine_learning_clip_model_description": "Il nome del modello CLIP mostrato qui. Nota che devi rieseguire il processo 'Ricerca Intelligente' per tutte le immagini al cambio del modello.", "machine_learning_duplicate_detection": "Rilevamento Duplicati", @@ -387,8 +395,6 @@ "admin_password": "Password Amministratore", "administration": "Amministrazione", "advanced": "Avanzate", - "advanced_settings_beta_timeline_subtitle": "Prova la nuova esperienza dell'app", - "advanced_settings_beta_timeline_title": "Timeline beta", "advanced_settings_enable_alternate_media_filter_subtitle": "Usa questa opzione per filtrare i contenuti multimediali durante la sincronizzazione in base a criteri alternativi. Prova questa opzione solo se riscontri problemi con il rilevamento di tutti gli album da parte dell'app.", "advanced_settings_enable_alternate_media_filter_title": "[SPERIMENTALE] Usa un filtro alternativo per la sincronizzazione degli album del dispositivo", "advanced_settings_log_level_title": "Livello log: {level}", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "Sicuro di voler rimuovere l'utente {user}?", "album_search_not_found": "Nessun album trovato corrispondente alla tua ricerca", "album_share_no_users": "Sembra che tu abbia condiviso questo album con tutti gli utenti oppure non hai nessun utente con cui condividere.", + "album_summary": "Sommario Album", "album_updated": "Album aggiornato", "album_updated_setting_description": "Ricevi una notifica email quando un album condiviso ha nuovi media", "album_user_left": "{album} abbandonato", @@ -496,6 +503,8 @@ "asset_restored_successfully": "Elemento ripristinato con successo", "asset_skipped": "Saltato", "asset_skipped_in_trash": "Nel cestino", + "asset_trashed": "Asset cestinato", + "asset_troubleshoot": "Risoluzione dei problemi dell'asset", "asset_uploaded": "Caricato", "asset_uploading": "Caricamento…", "asset_viewer_settings_subtitle": "Gestisci le impostazioni del visualizzatore della galleria", @@ -529,8 +538,10 @@ "autoplay_slideshow": "Avvio automatico presentazione", "back": "Indietro", "back_close_deselect": "Indietro, chiudi o deseleziona", + "background_backup_running_error": "Il backup in background è attualmente in esecuzione, impossibile avviare il backup manuale", "background_location_permission": "Permesso di localizzazione in background", "background_location_permission_content": "Per fare in modo che sia possibile cambiare rete quando è in esecuzione in background, Immich deve *sempre* avere accesso alla tua posizione precisa in modo da poter leggere il nome della rete Wi-Fi", + "background_options": "Opzioni sfondo", "backup": "Backup", "backup_album_selection_page_albums_device": "Album sul dispositivo ({count})", "backup_album_selection_page_albums_tap": "Tap per includere, doppio tap per escludere", @@ -538,6 +549,7 @@ "backup_album_selection_page_select_albums": "Seleziona gli album", "backup_album_selection_page_selection_info": "Informazioni sulla selezione", "backup_album_selection_page_total_assets": "Numero totale delle risorse", + "backup_albums_sync": "Sincronizzazione album di backup", "backup_all": "Tutti", "backup_background_service_backup_failed_message": "È stato impossibile fare il backup dei contenuti. Riprovo…", "backup_background_service_connection_failed_message": "Impossibile connettersi al server. Riprovo…", @@ -606,7 +618,7 @@ "blurred_background": "Sfondo sfocato", "bugs_and_feature_requests": "Bug & Richieste di nuove funzionalità", "build": "Compilazione", - "build_image": "Compila Immagine", + "build_image": "Immagine Compilata", "bulk_delete_duplicates_confirmation": "Sei sicuro di voler cancellare {count, plural, one {# asset duplicato} other {# assets duplicati}}? Questa operazione manterrà l'asset più pesante di ogni gruppo e cancellerà permanentemente tutti gli altri duplicati. Non puoi annullare questa operazione!", "bulk_keep_duplicates_confirmation": "Sei sicuro di voler tenere {count, plural, one {# asset duplicato} other {# assets duplicati}}? Questa operazione risolverà tutti i gruppi duplicati senza cancellare nulla.", "bulk_trash_duplicates_confirmation": "Sei davvero sicuro di voler cancellare {count, plural, one {# asset duplicato} other {# assets duplicati}}? Questa operazione manterrà l'asset più pesante di ogni gruppo e cancellerà permanentemente tutti gli altri duplicati.", @@ -654,6 +666,8 @@ "change_pin_code": "Cambia il codice PIN", "change_your_password": "Modifica la tua password", "changed_visibility_successfully": "Visibilità modificata con successo", + "charging": "In carica", + "charging_requirement_mobile_backup": "Il backup in background richiede che il dispositivo sia in carica", "check_corrupt_asset_backup": "Verifica la presenza di backup di asset corrotti", "check_corrupt_asset_backup_button": "Effettua controllo", "check_corrupt_asset_backup_description": "Effettua questo controllo solo sotto rete Wi-Fi e quando tutti gli asset sono stati sottoposti a backup. La procedura potrebbe impiegare qualche minuto.", @@ -720,7 +734,7 @@ "copy_to_clipboard": "Copia negli appunti", "country": "Nazione", "cover": "Riempi la finestra", - "covers": "Copre", + "covers": "Copertine", "create": "Crea", "create_album": "Crea album", "create_album_page_untitled": "Senza titolo", @@ -740,6 +754,7 @@ "create_user": "Crea utente", "created": "Creato", "created_at": "Creato il", + "creating_linked_albums": "Creazione di album collegati...", "crop": "Ritaglia", "curated_object_page_title": "Oggetti", "current_device": "Dispositivo attuale", @@ -752,9 +767,9 @@ "daily_title_text_date_year": "E, dd MMM, yyyy", "dark": "Scuro", "dark_theme": "Imposta tema scuro", - "date_after": "Data dopo", + "date_after": "Dopo la data", "date_and_time": "Data e ora", - "date_before": "Data prima", + "date_before": "Prima della data", "date_format": "E, d LLL, y • hh:mm", "date_of_birth_saved": "Data di nascita salvata con successo", "date_range": "Intervallo di date", @@ -889,7 +904,9 @@ "error": "Errore", "error_change_sort_album": "Errore nel cambiare l'ordine di degli album", "error_delete_face": "Errore nel cancellare la faccia dalla foto", + "error_getting_places": "Errore durante il recupero dei luoghi", "error_loading_image": "Errore nel caricamento dell'immagine", + "error_loading_partners": "Errore durante il caricamento dei partner: {error}", "error_saving_image": "Errore: {error}", "error_tag_face_bounding_box": "Errore durante il tag del volto - impossibile ricavare le coordinate del riquadro", "error_title": "Errore - Qualcosa è andato storto", @@ -1054,6 +1071,7 @@ "favorites_page_no_favorites": "Nessun preferito", "feature_photo_updated": "Foto in evidenza aggiornata", "features": "Funzionalità", + "features_in_development": "Funzionalità in fase di sviluppo", "features_setting_description": "Gestisci le funzionalità dell'app", "file_name": "Nome file", "file_name_or_extension": "Nome file o estensione", @@ -1155,7 +1173,7 @@ "in_archive": "In archivio", "include_archived": "Includi Archiviati", "include_shared_albums": "Includi album condivisi", - "include_shared_partner_assets": "Includi asset condivisi del compagno", + "include_shared_partner_assets": "Includi elementi condivisi dai compagni", "individual_share": "Condivisione individuale", "individual_shares": "Condivisioni individuali", "info": "Info", @@ -1218,6 +1236,7 @@ "local": "Locale", "local_asset_cast_failed": "Impossibile trasmettere una risorsa che non è caricata sul server", "local_assets": "Risorsa locale", + "local_media_summary": "Riepilogo dei Media Locali", "local_network": "Rete locale", "local_network_sheet_info": "L'app si collegherà al server tramite questo URL quando è in uso la rete Wi-Fi specificata", "location_permission": "Permesso di localizzazione", @@ -1229,6 +1248,7 @@ "location_picker_longitude_hint": "Inserisci la longitudine qui", "lock": "Rendi privato", "locked_folder": "Cartella Privata", + "log_detail_title": "Dettaglio dei Log", "log_out": "Esci", "log_out_all_devices": "Disconnetti tutti i dispositivi", "logged_in_as": "Effettuato l'accesso come {user}", @@ -1259,6 +1279,7 @@ "login_password_changed_success": "Password aggiornata con successo", "logout_all_device_confirmation": "Sei sicuro di volerti disconnettere da tutti i dispositivi?", "logout_this_device_confirmation": "Sei sicuro di volerti disconnettere da questo dispositivo?", + "logs": "Logs", "longitude": "Longitudine", "look": "Guarda", "loop_videos": "Riproduci video in loop", @@ -1301,6 +1322,7 @@ "mark_as_read": "Segna come letto", "marked_all_as_read": "Segnato tutto come letto", "matches": "Corrispondenze", + "matching_assets": "Assets Corrispondenti", "media_type": "Tipo Media", "memories": "Ricordi", "memories_all_caught_up": "Tutto a posto", @@ -1341,6 +1363,7 @@ "name_or_nickname": "Nome o soprannome", "network_requirement_photos_upload": "Utilizza la connessione dati per il backup delle foto", "network_requirement_videos_upload": "Utilizza la connessione dati per il backup dei video", + "network_requirements": "Requisiti di rete", "network_requirements_updated": "Requisiti di rete modificati, coda di backup reimpostata", "networking_settings": "Rete", "networking_subtitle": "Gestisci le impostazioni riguardanti gli endpoint del server", @@ -1351,6 +1374,7 @@ "new_person": "Nuova persona", "new_pin_code": "Nuovo codice PIN", "new_pin_code_subtitle": "Questa è la prima volta che accedi alla cartella privata. Crea un codice PIN per accedere in modo sicuro a questa pagina", + "new_timeline": "Nuova Timeline", "new_user_created": "Nuovo utente creato", "new_version_available": "NUOVA VERSIONE DISPONIBILE", "newest_first": "Prima recenti", @@ -1364,20 +1388,25 @@ "no_assets_message": "CLICCA PER CARICARE LA TUA PRIMA FOTO", "no_assets_to_show": "Nessuna risorsa da mostrare", "no_cast_devices_found": "Nessun dispositivo di trasmissione trovato", + "no_checksum_local": "Nessun checksum disponibile: impossibile recuperare gli assets locali", + "no_checksum_remote": "Nessun checksum disponibile: impossibile recuperare l'asset remoto", "no_duplicates_found": "Nessun duplicato trovato.", "no_exif_info_available": "Nessuna informazione exif disponibile", "no_explore_results_message": "Carica più foto per esplorare la tua collezione.", "no_favorites_message": "Aggiungi preferiti per trovare facilmente le tue migliori foto e video", "no_libraries_message": "Crea una libreria esterna per vedere le tue foto e i tuoi video", + "no_local_assets_found": "Nessun asset locale trovato con questo checksum", "no_locked_photos_message": "Le foto e i video nella cartella privata sono nascosti e non vengono visualizzati mentre navighi o cerchi nella tua libreria.", "no_name": "Nessun nome", "no_notifications": "Nessuna notifica", "no_people_found": "Nessuna persona trovata", "no_places": "Nessun posto", + "no_remote_assets_found": "Nessun asset remoto trovato con questo checksum", "no_results": "Nessun risultato", "no_results_description": "Prova ad usare un sinonimo oppure una parola chiave più generica", "no_shared_albums_message": "Crea un album per condividere foto e video con le persone nella tua rete", "no_uploads_in_progress": "Nessun upload in corso", + "not_available": "N/A", "not_in_any_album": "In nessun album", "not_selected": "Non selezionato", "note_apply_storage_label_to_previously_uploaded assets": "Nota: Per aggiungere l'etichetta dell'archiviazione agli asset caricati in precedenza, esegui", @@ -1499,6 +1528,7 @@ "port": "Porta", "preferences_settings_subtitle": "Gestisci le preferenze dell'app", "preferences_settings_title": "Preferenze", + "preparing": "Preparando", "preset": "Preimpostazione", "preview": "Anteprima", "previous": "Precedente", @@ -1564,6 +1594,7 @@ "read_changelog": "Leggi Riepilogo Modifiche", "readonly_mode_disabled": "Modalità di sola lettura disabilitata", "readonly_mode_enabled": "Modalità di sola lettura abilitata", + "ready_for_upload": "Pronto per il caricamento", "reassign": "Riassegna", "reassigned_assets_to_existing_person": "{count, plural, one {Riassegnato # asset} other {Riassegnati # assets}} {name, select, null {ad una persona esistente} other {a {name}}}", "reassigned_assets_to_new_person": "{count, plural, one {Riassegnato # asset} other {Riassegnati # assets}} ad una nuova persona", @@ -1588,6 +1619,7 @@ "regenerating_thumbnails": "Rigenerando le anteprime", "remote": "Remoto", "remote_assets": "Risorse remote", + "remote_media_summary": "Riepilogo dei Media Remoti", "remove": "Rimuovi", "remove_assets_album_confirmation": "Sei sicuro di voler rimuovere {count, plural, one {# asset} other {# asset}} dall'album?", "remove_assets_shared_link_confirmation": "Sei sicuro di voler rimuovere {count, plural, one {# asset} other {# asset}} da questo link condiviso?", @@ -1689,11 +1721,11 @@ "search_no_people": "Nessuna persona", "search_no_people_named": "Nessuna persona chiamate \"{name}\"", "search_no_result": "Nessun risultato trovato, prova con un termine o combinazione diversi", - "search_options": "Opzioni Ricerca", + "search_options": "Opzioni di ricerca", "search_page_categories": "Categoria", "search_page_motion_photos": "Foto in movimento", - "search_page_no_objects": "Nessuna informazione relativa all'oggetto disponibile", - "search_page_no_places": "Nessun informazione sul luogo disponibile", + "search_page_no_objects": "Nessuna informazione sugli oggetti disponibile", + "search_page_no_places": "Nessuna informazione sui luoghi disponibile", "search_page_screenshots": "Screenshot", "search_page_search_photos_videos": "Ricerca le tue foto e i tuoi video", "search_page_selfies": "Selfie", @@ -1863,6 +1895,7 @@ "show_slideshow_transition": "Mostra la transizione della presentazione", "show_supporter_badge": "Medaglia di Contributore", "show_supporter_badge_description": "Mostra la medaglia di contributore", + "show_text_search_menu": "Mostra il menu di ricerca del testo", "shuffle": "Casuale", "sidebar": "Barra laterale", "sidebar_display_description": "Visualizzare un link alla vista nella barra laterale", @@ -1888,11 +1921,12 @@ "stack_action_prompt": "{count} elementi raggruppati", "stack_duplicates": "Raggruppa i duplicati", "stack_select_one_photo": "Seleziona una foto principale per il gruppo", - "stack_selected_photos": "Impila foto selezionate", + "stack_selected_photos": "Raggruppa foto selezionate", "stacked_assets_count": "{count, plural, one {Raggruppato # asset} other {Raggruppati # asset}}", "stacktrace": "Traccia dell'errore", "start": "Avvia", "start_date": "Data di inizio", + "start_date_before_end_date": "La data di inizio deve essere precedente alla data di fine", "state": "Provincia", "status": "Stato", "stop_casting": "Interrompi trasmissione", @@ -1917,6 +1951,8 @@ "sync_albums_manual_subtitle": "Sincronizza tutti i video e le foto caricati con gli album di backup selezionati", "sync_local": "Sincronizza gli elementi locali", "sync_remote": "Sincronizza gli elementi remoti", + "sync_status": "Stato di Sincronizzazione", + "sync_status_subtitle": "Visualizza e gestisci il sistema di sincronizzazione", "sync_upload_album_setting_subtitle": "Crea e carica le tue foto e video sull'album selezionato in Immich", "tag": "Tag", "tag_assets": "Tagga risorse", @@ -1976,6 +2012,7 @@ "trash_page_select_assets_btn": "Seleziona elemento", "trash_page_title": "Cestino ({count})", "trashed_items_will_be_permanently_deleted_after": "Gli elementi cestinati saranno eliminati definitivamente dopo {days, plural, one {# giorno} other {# giorni}}.", + "troubleshoot": "Risoluzione dei problemi", "type": "Tipo", "unable_to_change_pin_code": "Impossibile cambiare il codice PIN", "unable_to_setup_pin_code": "Impossibile configurare il codice PIN", @@ -2001,7 +2038,7 @@ "unselect_all": "Deseleziona tutto", "unselect_all_duplicates": "Deseleziona tutti i duplicati", "unselect_all_in": "Deseleziona tutto in {group}", - "unstack": "Rimuovi dal gruppo", + "unstack": "Separa dal gruppo", "unstack_action_prompt": "{count} separati", "unstacked_assets_count": "{count, plural, one {Separato # asset} other {Separati # asset}}", "untagged": "Senza tag", @@ -2076,9 +2113,9 @@ "view_similar_photos": "Visualizza le foto simili", "view_stack": "Visualizza Raggruppamento", "view_user": "Visualizza Utente", - "viewer_remove_from_stack": "Rimuovi dalla pila", + "viewer_remove_from_stack": "Rimuovi dal gruppo", "viewer_stack_use_as_main_asset": "Usa come risorsa principale", - "viewer_unstack": "Rimuovi dal gruppo", + "viewer_unstack": "Separa dal gruppo", "visibility_changed": "Visibilità modificata per {count, plural, one {# persona} other {# persone}}", "waiting": "In Attesa", "warning": "Attenzione", @@ -2089,8 +2126,9 @@ "wrong_pin_code": "Codice PIN errato", "year": "Anno", "years_ago": "{years, plural, one {# anno} other {# anni}} fa", - "yes": "Si", - "you_dont_have_any_shared_links": "Non è presente alcun link condiviso", + "yes": "Sì", + "you_dont_have_any_shared_links": "Non hai nessun link condiviso", "your_wifi_name": "Nome della tua rete Wi-Fi", - "zoom_image": "Ingrandisci immagine" + "zoom_image": "Ingrandisci immagine", + "zoom_to_bounds": "Ingrandisci fino ai bordi" } diff --git a/i18n/ja.json b/i18n/ja.json index 29e1a6a760..b03614d65c 100644 --- a/i18n/ja.json +++ b/i18n/ja.json @@ -123,6 +123,13 @@ "logging_enable_description": "ログの有効化", "logging_level_description": "有効な場合に使用されるログ レベル。", "logging_settings": "ログ", + "machine_learning_availability_checks": "可用性の確認", + "machine_learning_availability_checks_description": "利用可能な機械学習のサーバーを自動で検知し優先的に使用します", + "machine_learning_availability_checks_enabled": "可用性チェックを有効にする", + "machine_learning_availability_checks_interval": "チェックの間隔", + "machine_learning_availability_checks_interval_description": "可用性チェックの間隔(ミリ秒単位)", + "machine_learning_availability_checks_timeout": "リクエストタイムアウト", + "machine_learning_availability_checks_timeout_description": "可用性チェックのタイムアウト時間(ミリ秒単位)", "machine_learning_clip_model": "Clipモデル", "machine_learning_clip_model_description": "CLIP モデルの名前はここにリストされています。モデルを変更した場合は、すべてのイメージに対して「スマート検索」ジョブを再実行する必要があります。", "machine_learning_duplicate_detection": "重複検出", @@ -387,8 +394,6 @@ "admin_password": "管理者パスワード", "administration": "管理", "advanced": "詳細設定", - "advanced_settings_beta_timeline_subtitle": "新しいアプリを体験してみましょう", - "advanced_settings_beta_timeline_title": "試験運用のタイムライン", "advanced_settings_enable_alternate_media_filter_subtitle": "別の基準に従ってメディアファイルにフィルターをかけて、同期を行います。アプリがすべてのアルバムを読み込んでくれない場合にのみ、この機能を試してください。", "advanced_settings_enable_alternate_media_filter_title": "[試験運用] 別のデバイスのアルバム同期フィルターを使用する", "advanced_settings_log_level_title": "ログレベル: {level}", @@ -425,6 +430,7 @@ "album_remove_user_confirmation": "本当に{user}を削除しますか?", "album_search_not_found": "検索に一致するアルバムがありません", "album_share_no_users": "このアルバムを全てのユーザーと共有したか、共有するユーザーがいないようです。", + "album_summary": "アルバムのまとめ", "album_updated": "アルバム更新", "album_updated_setting_description": "共有アルバムに新しいアセットが追加されたとき通知を受け取る", "album_user_left": "{album} を去りました", @@ -496,6 +502,8 @@ "asset_restored_successfully": "復元できました", "asset_skipped": "スキップ済", "asset_skipped_in_trash": "ゴミ箱の中", + "asset_trashed": "項目が削除されました", + "asset_troubleshoot": "項目をトラブルシューㇳ", "asset_uploaded": "アップロード済", "asset_uploading": "アップロード中…", "asset_viewer_settings_subtitle": "ギャラリービューアーに関する設定", @@ -529,8 +537,10 @@ "autoplay_slideshow": "スライドショーを自動再生", "back": "戻る", "back_close_deselect": "戻る、閉じる、選択解除", + "background_backup_running_error": "バックグラウンドのバックアップがすでに行われている最中です。そのため、マニュアルでのバックアップを開始することはできません。", "background_location_permission": "バックグラウンド位置情報アクセス", "background_location_permission_content": "正常にWi-Fiの名前(SSID)を獲得するにはアプリが常に詳細な位置情報にアクセスできる必要があります", + "background_options": "バックグラウンドの動作オプション", "backup": "バックアップ", "backup_album_selection_page_albums_device": "デバイス上のアルバム({count})", "backup_album_selection_page_albums_tap": "タップで選択、ダブルタップで除外", @@ -538,6 +548,7 @@ "backup_album_selection_page_select_albums": "アルバムを選択", "backup_album_selection_page_selection_info": "選択・除外中のアルバム", "backup_album_selection_page_total_assets": "選択されたアルバムの写真と動画の数", + "backup_albums_sync": "アルバム同期状態をバックアップ", "backup_all": "すべて", "backup_background_service_backup_failed_message": "アップロードに失敗しました。リトライ中…", "backup_background_service_connection_failed_message": "サーバーに接続できません。リトライ中…", @@ -654,6 +665,8 @@ "change_pin_code": "PINコードを変更", "change_your_password": "パスワードを変更します", "changed_visibility_successfully": "非表示設定を正常に変更しました", + "charging": "充電中", + "charging_requirement_mobile_backup": "バックグラウンドでのバックアップを行うためには、デバイスが充電中である必要があります", "check_corrupt_asset_backup": "破損されている項目を探す", "check_corrupt_asset_backup_button": "チェックを行う", "check_corrupt_asset_backup_description": "写真や動画などが全てアップロードし終えてからWi-Fiに接続時のみチェックを行なってください。作業が完了するには数分かかる場合があります", @@ -740,6 +753,7 @@ "create_user": "ユーザーを作成", "created": "作成", "created_at": "作成:", + "creating_linked_albums": "リンクされたアルバムを作成中・・・", "crop": "クロップ", "curated_object_page_title": "被写体", "current_device": "現在のデバイス", @@ -889,7 +903,9 @@ "error": "エラー", "error_change_sort_album": "アルバムの表示順の変更に失敗しました", "error_delete_face": "アセットから顔の削除ができませんでした", + "error_getting_places": "場所の取得に失敗しました", "error_loading_image": "画像の読み込みエラー", + "error_loading_partners": "パートナーの読み込みに失敗しました: {error}", "error_saving_image": "エラー: {error}", "error_tag_face_bounding_box": "顔の登録に失敗しました - 顔を囲む四角形の座標取得に失敗", "error_title": "エラー - 問題が発生しました", @@ -1054,6 +1070,7 @@ "favorites_page_no_favorites": "お気に入り登録された項目がありません", "feature_photo_updated": "人物画像が更新されました", "features": "機能", + "features_in_development": "開発中の機能", "features_setting_description": "アプリの機能を管理する", "file_name": "ファイル名", "file_name_or_extension": "ファイル名または拡張子", @@ -1218,6 +1235,7 @@ "local": "ローカル", "local_asset_cast_failed": "サーバーにアップロードされていない項目はキャストできません", "local_assets": "ローカルの項目", + "local_media_summary": "ローカルメディアのまとめ", "local_network": "ローカルネットワーク", "local_network_sheet_info": "アプリは指定されたWi-Fiに繋がっている時サーバーへの接続を下記のURLで行います", "location_permission": "位置情報権限", @@ -1229,6 +1247,7 @@ "location_picker_longitude_hint": "経度を入力", "lock": "ロック", "locked_folder": "鍵付きフォルダー", + "log_detail_title": "ログの詳細", "log_out": "ログアウト", "log_out_all_devices": "全てのデバイスからログアウト", "logged_in_as": "{user}としてログイン中", @@ -1259,6 +1278,7 @@ "login_password_changed_success": "パスワードの変更に成功", "logout_all_device_confirmation": "本当に全てのデバイスからログアウトしますか?", "logout_this_device_confirmation": "本当にこのデバイスからログアウトしますか?", + "logs": "ログ", "longitude": "経度", "look": "見た目", "loop_videos": "動画をループ", @@ -1301,6 +1321,7 @@ "mark_as_read": "既読にする", "marked_all_as_read": "すべて既読にしました", "matches": "マッチ", + "matching_assets": "一致する項目", "media_type": "メディアタイプ", "memories": "メモリー", "memories_all_caught_up": "これで全部です", @@ -1341,6 +1362,7 @@ "name_or_nickname": "名前またはニックネーム", "network_requirement_photos_upload": "モバイル通信を使用して写真のバックアップを行う", "network_requirement_videos_upload": "モバイル通信を使用して動画のバックアップを行う", + "network_requirements": "ネットワークの要件", "network_requirements_updated": "ネットワークの条件が変更されたため、バックアップの順番待ちをリセットします", "networking_settings": "ネットワーク", "networking_subtitle": "サーバーエンドポイントに関する設定", @@ -1351,6 +1373,7 @@ "new_person": "新しい人物", "new_pin_code": "新しいPINコード", "new_pin_code_subtitle": "鍵付きフォルダーを利用するのが初めてのようです。PINコードを作成してください", + "new_timeline": "新たなタイムライン", "new_user_created": "新しいユーザーが作成されました", "new_version_available": "新しいバージョンが利用可能", "newest_first": "最新順", @@ -1364,20 +1387,25 @@ "no_assets_message": "クリックして最初の写真をアップロード", "no_assets_to_show": "表示する項目がありません", "no_cast_devices_found": "キャスト先のデバイスが見つかりません", + "no_checksum_local": "チェックサムが見つかりません - デバイス上の項目を取得できないようです", + "no_checksum_remote": "チェックサムが見つかりません - サーバー上の項目を取得できないようです", "no_duplicates_found": "重複は見つかりませんでした。", "no_exif_info_available": "exif情報が利用できません", "no_explore_results_message": "コレクションを探索するにはさらに写真をアップロードしてください。", "no_favorites_message": "お気に入り登録すると好きな写真や動画をすぐに見つけられます", "no_libraries_message": "あなたの写真や動画を表示するための外部ライブラリを作成しましょう", + "no_local_assets_found": "このチェックサムの項目はデバイス上に存在しません", "no_locked_photos_message": "鍵付きフォルダー内の写真や動画は通常のライブラリに表示されなくなります。", "no_name": "名前なし", "no_notifications": "通知なし", "no_people_found": "一致する人物が見つかりません", "no_places": "場所なし", + "no_remote_assets_found": "このチェックサムの項目はサーバー上に存在しません", "no_results": "結果がありません", "no_results_description": "同義語やより一般的なキーワードを試してください", "no_shared_albums_message": "アルバムを作成して写真や動画を共有しましょう", "no_uploads_in_progress": "アップロードは行われていません", + "not_available": "適用なし", "not_in_any_album": "どのアルバムにも入っていない", "not_selected": "選択なし", "note_apply_storage_label_to_previously_uploaded assets": "注意: 以前にアップロードしたアセットにストレージラベルを適用するには以下を実行してください", @@ -1499,6 +1527,7 @@ "port": "ポートレート", "preferences_settings_subtitle": "アプリに関する設定", "preferences_settings_title": "設定", + "preparing": "準備中", "preset": "プリセット", "preview": "プレビュー", "previous": "前", @@ -1564,6 +1593,7 @@ "read_changelog": "変更履歴を読む", "readonly_mode_disabled": "読み取り専用モード無効", "readonly_mode_enabled": "読み取り専用モード有効", + "ready_for_upload": "アップロード準備完了", "reassign": "再割り当て", "reassigned_assets_to_existing_person": "{count, plural, one {#個} other {#個}}のアセットを{name, select, null {既存の人物} other {{name}}}に再割り当てしました", "reassigned_assets_to_new_person": "{count, plural, one {#個} other {#個}}のアセットを新しい人物に割り当てました", @@ -1588,6 +1618,7 @@ "regenerating_thumbnails": "サムネイルを再生成中", "remote": "リモート", "remote_assets": "リモートの項目", + "remote_media_summary": "サーバー上のメディアまとめ", "remove": "削除", "remove_assets_album_confirmation": "本当に{count, plural, one {#個} other {#個}}のアセットをアルバムから削除しますか?", "remove_assets_shared_link_confirmation": "本当にこの共有リンクから{count, plural, one {#個} other {#個}}のアセットを削除しますか?", @@ -1863,6 +1894,7 @@ "show_slideshow_transition": "スライドショーのトランジションを表示", "show_supporter_badge": "サポーターバッジ", "show_supporter_badge_description": "サポーターバッジを表示", + "show_text_search_menu": "テキスト検索メニューを表示", "shuffle": "ランダム", "sidebar": "サイドバー", "sidebar_display_description": "サイドバーにビューへのリンクを表示", @@ -1893,6 +1925,7 @@ "stacktrace": "スタックトレース", "start": "開始", "start_date": "開始日", + "start_date_before_end_date": "開始日は終了日より前でなければなりません", "state": "都道府県", "status": "ステータス", "stop_casting": "キャストを停止", @@ -2095,5 +2128,6 @@ "yes": "はい", "you_dont_have_any_shared_links": "共有リンクはありません", "your_wifi_name": "Wi-Fiの名前(SSID)", - "zoom_image": "画像を拡大" + "zoom_image": "画像を拡大", + "zoom_to_bounds": "画面端までズーム" } diff --git a/i18n/ko.json b/i18n/ko.json index 09d215c2a3..3707501ec8 100644 --- a/i18n/ko.json +++ b/i18n/ko.json @@ -28,6 +28,7 @@ "add_to_album": "앨범에 추가", "add_to_album_bottom_sheet_added": "{album}에 추가됨", "add_to_album_bottom_sheet_already_exists": "이미 {album}에 있음", + "add_to_album_bottom_sheet_some_local_assets": "몇 개의 로컬 항목이 앨범에 추가되지 않았습니다", "add_to_album_toggle": "{album} 선택/해제", "add_to_albums": "여러 앨범에 추가", "add_to_albums_count": "여러 앨범에 추가 ({count})", @@ -123,6 +124,13 @@ "logging_enable_description": "로그 기록 활성화", "logging_level_description": "활성화 시 사용할 로그 레벨을 선택합니다.", "logging_settings": "로깅", + "machine_learning_availability_checks": "가용성 확인", + "machine_learning_availability_checks_description": "사용 가능한 머신 러닝 서버를 자동으로 감지하고 우선적으로 선택합니다", + "machine_learning_availability_checks_enabled": "가용성 확인 활성화", + "machine_learning_availability_checks_interval": "확인 주기", + "machine_learning_availability_checks_interval_description": "가용성 확인 주기 (밀리초 단위)", + "machine_learning_availability_checks_timeout": "요청 타임아웃", + "machine_learning_availability_checks_timeout_description": "가용성 확인 요청 타임아웃 (밀리초 단위)", "machine_learning_clip_model": "CLIP 모델", "machine_learning_clip_model_description": "CLIP 모델의 종류는 이곳을 참조하세요. 한국어 등 여러 언어로 검색하려면 Multilingual CLIP 모델을 선택하세요. 모델을 변경한 경우 모든 이미지의 '스마트 검색' 작업을 다시 실행해야 합니다.", "machine_learning_duplicate_detection": "비슷한 항목 감지", @@ -387,8 +395,6 @@ "admin_password": "관리자 비밀번호", "administration": "관리", "advanced": "고급", - "advanced_settings_beta_timeline_subtitle": "새로운 앱 경험 사용해보기", - "advanced_settings_beta_timeline_title": "베타 타임라인", "advanced_settings_enable_alternate_media_filter_subtitle": "이 옵션을 사용하면 동기화 중 미디어를 대체 기준으로 필터링할 수 있습니다. 앱이 모든 앨범을 제대로 감지하지 못할 때만 사용하세요.", "advanced_settings_enable_alternate_media_filter_title": "대체 기기 앨범 동기화 필터 사용 (실험적)", "advanced_settings_log_level_title": "로그 레벨: {level}", @@ -396,6 +402,7 @@ "advanced_settings_prefer_remote_title": "서버 이미지 선호", "advanced_settings_proxy_headers_subtitle": "Immich가 네트워크 요청 시 사용할 프록시 헤더를 정의합니다.", "advanced_settings_proxy_headers_title": "프록시 헤더", + "advanced_settings_readonly_mode_subtitle": "읽기 전용 모드를 활성화하면 여러 이미지 선택, 공유, 캐스트, 삭제 동작이 모두 비활성화됩니다. 메인 화면에서 사용자 프로필을 통해 읽기 전용 모드의 활성 상태를 전환하세요", "advanced_settings_readonly_mode_title": "읽기 전용 모드", "advanced_settings_self_signed_ssl_subtitle": "서버 엔드포인트의 SSL 인증서 검증을 건너뜁니다. 자체 서명 인증서를 사용하는 경우 활성화하세요.", "advanced_settings_self_signed_ssl_title": "자체 서명된 SSL 인증서 허용", @@ -424,6 +431,7 @@ "album_remove_user_confirmation": "{user}님을 앨범에서 제거하시겠습니까?", "album_search_not_found": "검색 결과에 해당하는 앨범이 없습니다.", "album_share_no_users": "이미 모든 사용자와 앨범을 공유했거나 공유할 사용자가 없습니다.", + "album_summary": "앨범 요약", "album_updated": "항목 추가 알림", "album_updated_setting_description": "공유 앨범에 항목이 추가된 경우 이메일 알림 받기", "album_user_left": "{album} 앨범에서 나옴", @@ -495,6 +503,8 @@ "asset_restored_successfully": "항목이 복원되었습니다.", "asset_skipped": "건너뜀", "asset_skipped_in_trash": "휴지통의 항목", + "asset_trashed": "항목 삭제됨", + "asset_troubleshoot": "항목 트러블슈팅", "asset_uploaded": "업로드 완료", "asset_uploading": "업로드 중…", "asset_viewer_settings_subtitle": "갤러리 보기 설정을 관리합니다.", @@ -528,8 +538,10 @@ "autoplay_slideshow": "슬라이드 쇼 자동 재생", "back": "뒤로", "back_close_deselect": "뒤로, 닫기 또는 선택 해제", + "background_backup_running_error": "백그라운드 백업이 현재 진행 중이므로 수동 백업을 시작할 수 없습니다", "background_location_permission": "백그라운드 위치 권한", "background_location_permission_content": "Immich가 백그라운드에서 실행 중일 때 네트워크를 전환하려면 Wi-Fi 네트워크 이름을 확인해야 하며, 이를 위해 '정확한 위치' 권한을 항상 허용해야 합니다.", + "background_options": "백그라운드 옵션", "backup": "백업", "backup_album_selection_page_albums_device": "기기의 앨범 ({count})", "backup_album_selection_page_albums_tap": "탭하여 포함, 두 번 탭하여 제외", @@ -537,6 +549,7 @@ "backup_album_selection_page_select_albums": "앨범 선택", "backup_album_selection_page_selection_info": "선택한 앨범", "backup_album_selection_page_total_assets": "전체 항목", + "backup_albums_sync": "앨범 동기화 백업", "backup_all": "모두", "backup_background_service_backup_failed_message": "항목 백업에 실패했습니다. 다시 시도하는 중…", "backup_background_service_connection_failed_message": "서버 연결에 실패했습니다. 다시 시도하는 중…", @@ -653,6 +666,8 @@ "change_pin_code": "PIN 코드 변경", "change_your_password": "사용자 계정의 비밀번호를 변경합니다.", "changed_visibility_successfully": "숨김 여부가 변경되었습니다.", + "charging": "충전 중", + "charging_requirement_mobile_backup": "백그라운드 백업은 기기 충전 상태에서 가능합니다", "check_corrupt_asset_backup": "백업된 항목의 손상 여부 확인", "check_corrupt_asset_backup_button": "확인 수행", "check_corrupt_asset_backup_description": "이 검사는 모든 항목이 백업된 후 Wi-Fi가 연결된 상태에서만 실행하세요. 이 작업은 몇 분 정도 소요될 수 있습니다.", @@ -739,6 +754,7 @@ "create_user": "사용자 계정 생성", "created": "생성됨", "created_at": "생성됨", + "creating_linked_albums": "링크 연결된 앨범 생성 중...", "crop": "자르기", "curated_object_page_title": "사물", "current_device": "현재 기기", @@ -888,7 +904,9 @@ "error": "오류", "error_change_sort_album": "앨범 표시 순서 변경 실패", "error_delete_face": "항목에서 얼굴 삭제 중 오류 발생", + "error_getting_places": "장소 정보 입력 실패", "error_loading_image": "이미지를 불러오는 중 오류 발생", + "error_loading_partners": "파트너 불러오기 실패: {error}", "error_saving_image": "오류: {error}", "error_tag_face_bounding_box": "얼굴 태그 실패 - 얼굴의 위치를 가져올 수 없습니다.", "error_title": "오류 - 문제가 발생했습니다", @@ -1053,6 +1071,7 @@ "favorites_page_no_favorites": "즐겨찾기된 항목 없음", "feature_photo_updated": "대표 사진 업데이트됨", "features": "기능", + "features_in_development": "개발 중인 기능", "features_setting_description": "사진 및 동영상 관리 기능을 설정합니다.", "file_name": "파일 이름", "file_name_or_extension": "파일명 또는 확장자", @@ -1216,6 +1235,7 @@ "local": "로컬", "local_asset_cast_failed": "서버에 업로드되지 않은 항목을 캐스팅할 수 없음", "local_assets": "로컬 항목", + "local_media_summary": "로컬 미디어 요약", "local_network": "로컬 네트워크", "local_network_sheet_info": "지정된 Wi-Fi를 사용할 때 앱이 아래 URL로 서버에 연결합니다.", "location_permission": "위치 권한", @@ -1227,6 +1247,7 @@ "location_picker_longitude_hint": "여기에 경도를 입력하세요", "lock": "잠금", "locked_folder": "잠금 폴더", + "log_detail_title": "상세 로그", "log_out": "로그아웃", "log_out_all_devices": "모든 기기에서 로그아웃", "logged_in_as": "{user}로 로그인됨", @@ -1257,6 +1278,7 @@ "login_password_changed_success": "비밀번호가 변경되었습니다.", "logout_all_device_confirmation": "모든 기기에서 로그아웃하시겠습니까?", "logout_this_device_confirmation": "이 기기에서 로그아웃하시겠습니까?", + "logs": "로그", "longitude": "경도", "look": "보기", "loop_videos": "동영상 반복", @@ -1299,6 +1321,7 @@ "mark_as_read": "읽음으로 표시", "marked_all_as_read": "모두 읽음으로 표시했습니다.", "matches": "일치", + "matching_assets": "일치하는 항목", "media_type": "미디어 종류", "memories": "추억", "memories_all_caught_up": "모두 확인함", @@ -1339,6 +1362,7 @@ "name_or_nickname": "이름 또는 닉네임", "network_requirement_photos_upload": "사진 백업에 모바일 데이터 사용", "network_requirement_videos_upload": "동영상 백업에 모바일 데이터 사용", + "network_requirements": "네트워크 요구사항", "network_requirements_updated": "네트워크 상태가 변경되었습니다. 백업 대기열을 초기화합니다.", "networking_settings": "연결", "networking_subtitle": "서버 엔드포인트 설정을 관리합니다.", @@ -1349,6 +1373,7 @@ "new_person": "새 인물 생성", "new_pin_code": "새 PIN 코드", "new_pin_code_subtitle": "잠금 폴더에 처음 접근하셨습니다. 이곳에 안전하게 접근하기 위한 PIN 코드를 설정하세요.", + "new_timeline": "새 타임라인", "new_user_created": "사용자 계정이 생성되었습니다.", "new_version_available": "새 버전 사용 가능", "newest_first": "최신순", @@ -1495,6 +1520,7 @@ "port": "포트", "preferences_settings_subtitle": "앱 개인 설정을 관리합니다.", "preferences_settings_title": "개인 설정", + "preparing": "준비 중", "preset": "프리셋", "preview": "미리 보기", "previous": "이전", @@ -1511,6 +1537,7 @@ "profile_drawer_client_out_of_date_minor": "모바일 앱이 최신 버전이 아닙니다. 최신 버전으로 업데이트하세요.", "profile_drawer_client_server_up_to_date": "클라이언트와 서버가 최신 상태입니다.", "profile_drawer_github": "Github", + "profile_drawer_readonly_mode": "읽기 전용 모드 활성화. 유저 아바타 아이콘을 길게 눌러 해제할 수 있습니다.", "profile_drawer_server_out_of_date_major": "서버 버전이 최신이 아닙니다. 최신 버전으로 업데이트하세요.", "profile_drawer_server_out_of_date_minor": "서버 버전이 최신이 아닙니다. 최신 버전으로 업데이트하세요.", "profile_image_of_user": "{user}님의 프로필 이미지", @@ -1556,6 +1583,9 @@ "rating_description": "상세 정보 패널에 EXIF 등급 태그 표시", "reaction_options": "반응 옵션", "read_changelog": "변경 내역 보기", + "readonly_mode_disabled": "읽기 전용 모드 비활성화", + "readonly_mode_enabled": "읽기 전용 모드 활성화", + "ready_for_upload": "업로드 준비 완료", "reassign": "다시 할당", "reassigned_assets_to_existing_person": "{count, plural, one {항목 #개} other {항목 #개}}를 {name, select, null {기존 인물} other {기존 인물 {name}}}에게 재지정했습니다.", "reassigned_assets_to_new_person": "{count, plural, one {항목 #개} other {항목 #개}}를 새 인물에게 재지정했습니다.", @@ -1580,6 +1610,7 @@ "regenerating_thumbnails": "섬네일을 다시 생성하는 중...", "remote": "원격", "remote_assets": "원격 항목", + "remote_media_summary": "원격 미디어 요약", "remove": "제거", "remove_assets_album_confirmation": "앨범에서 항목 {count, plural, one {#개} other {#개}}를 제거하시겠습니까?", "remove_assets_shared_link_confirmation": "공유 링크에서 항목 {count, plural, one {#개} other {#개}}를 제거하시겠습니까?", @@ -1853,6 +1884,7 @@ "show_slideshow_transition": "슬라이드 전환 표시", "show_supporter_badge": "서포터 배지", "show_supporter_badge_description": "서포터 배지 표시", + "show_text_search_menu": "텍스트 검색 메뉴 표시", "shuffle": "셔플", "sidebar": "사이드바", "sidebar_display_description": "보기 링크를 사이드바에 표시", @@ -1883,6 +1915,7 @@ "stacktrace": "스택 추적", "start": "시작", "start_date": "시작일", + "start_date_before_end_date": "시작일은 종료일보다 이전이어야 합니다", "state": "지역", "status": "상태", "stop_casting": "캐스팅 중단", @@ -1907,6 +1940,8 @@ "sync_albums_manual_subtitle": "업로드한 모든 동영상과 사진을 선택한 백업 앨범에 동기화", "sync_local": "로컬 동기화", "sync_remote": "원격 동기화", + "sync_status": "동기화 상태", + "sync_status_subtitle": "동기화 시스템 확인 및 관리", "sync_upload_album_setting_subtitle": "선택한 앨범을 Immich에 생성하고 사진 및 동영상 업로드", "tag": "태그", "tag_assets": "항목 태그", @@ -1966,6 +2001,7 @@ "trash_page_select_assets_btn": "항목 선택", "trash_page_title": "휴지통 ({count})", "trashed_items_will_be_permanently_deleted_after": "휴지통으로 이동된 항목은 {days, plural, one {#일} other {#일}} 후 영구적으로 삭제됩니다.", + "troubleshoot": "트러블슈팅", "type": "형식", "unable_to_change_pin_code": "PIN 코드를 변경할 수 없음", "unable_to_setup_pin_code": "PIN 코드를 설정할 수 없음", @@ -1996,6 +2032,7 @@ "unstacked_assets_count": "항목 {count, plural, one {#개} other {#개}}의 스택을 풀었습니다.", "untagged": "태그 해제됨", "up_next": "다음", + "update_location_action_prompt": "선택한 {count}개 항목 위치 업데이트:", "updated_at": "업데이트됨", "updated_password": "비밀번호가 변경되었습니다.", "upload": "업로드", @@ -2062,6 +2099,7 @@ "view_next_asset": "다음 항목 보기", "view_previous_asset": "이전 항목 보기", "view_qr_code": "QR 코드 보기", + "view_similar_photos": "비슷한 사진 보기", "view_stack": "스택 보기", "view_user": "사용자 보기", "viewer_remove_from_stack": "스택에서 제거", @@ -2080,5 +2118,6 @@ "yes": "네", "you_dont_have_any_shared_links": "공유 링크가 없습니다.", "your_wifi_name": "Wi-Fi 네트워크 이름", - "zoom_image": "이미지 확대" + "zoom_image": "이미지 확대", + "zoom_to_bounds": "화면에 맞춰 확대" } diff --git a/i18n/lt.json b/i18n/lt.json index 4392fdb944..b849d335a4 100644 --- a/i18n/lt.json +++ b/i18n/lt.json @@ -123,6 +123,13 @@ "logging_enable_description": "Įjungti žurnalo vedimą", "logging_level_description": "Įjungus, kokį žurnalo vedimo lygį naudot.", "logging_settings": "Žurnalo vedimas", + "machine_learning_availability_checks": "Prieinamumo patikrinimai", + "machine_learning_availability_checks_description": "Automatiškai aptikti ir teikti pirmenybę prieinamiems mašininio mokymosi serveriams", + "machine_learning_availability_checks_enabled": "Įjungti prieinamumo patikrinimus", + "machine_learning_availability_checks_interval": "Patikros intervalas", + "machine_learning_availability_checks_interval_description": "Intervalas milisekundėmis tarp prieinamumo patikrinimų", + "machine_learning_availability_checks_timeout": "Užklausos laiko limitas", + "machine_learning_availability_checks_timeout_description": "Laiko limitas milisekundėmis prieinamumo patikrinimams", "machine_learning_clip_model": "CLIP modelis", "machine_learning_clip_model_description": "Pavadinimas CLIP modelio įvardintio here. Dėmesio, keičiant modelį jūs privalote iš naujo paleisti 'Išmaniosios Paieškos' užduotį visiems vaizdams.", "machine_learning_duplicate_detection": "Dublikatų aptikimas", @@ -264,8 +271,8 @@ "storage_template_date_time_description": "Elemento sukūrimo laiko žymė yra naudojama laiko informacijai", "storage_template_date_time_sample": "Pavyzdinis laikas {date}", "storage_template_enable_description": "Aktyvuoti saugyklos šabloną", - "storage_template_hash_verification_enabled": "Aktyvuoti Hash tikrinimą", - "storage_template_hash_verification_enabled_description": "Aktyvuojamas Hash tikrinimas, neišjungti nebent gerai suprantate galimas pasekmes", + "storage_template_hash_verification_enabled": "Aktyvuoti failo parašo tikrinimą", + "storage_template_hash_verification_enabled_description": "Aktyvuojamas failo parašo tikrinimas, neišjungti nebent gerai suprantate galimas pasekmes", "storage_template_migration": "Saugyklos tvarkymas pagal šabloną", "storage_template_migration_description": "Taikyti dabartinį {template} anksčiau įkeltiems duomenims", "storage_template_migration_info": "Saugyklos tvarkyklė konvertuos visus plėtinius mažosiomis raidėmis. Šablonas bus taikomas tik naujiems duomenims. Taikyti šabloną retroaktyviai anksčiau įkeltiems duomenims, paleiskite šią {job}.", @@ -387,8 +394,6 @@ "admin_password": "Administratoriaus slaptažodis", "administration": "Administravimas", "advanced": "Sudėtingesnis", - "advanced_settings_beta_timeline_subtitle": "Išbandykite naujos programos patirtį", - "advanced_settings_beta_timeline_title": "Beta laiko juosta", "advanced_settings_enable_alternate_media_filter_subtitle": "Naudokite šį nustatymą medijos filtravimui sinchronizuojant remiantis alternatyviais kriterijais. Naudokite tik jei programa turi problemų su visų albumų aptikimu.", "advanced_settings_enable_alternate_media_filter_title": "[EKSPERIMENTINIS] Naudokite alternatyvų įrenginio albumų sinchronizavimo filtrą", "advanced_settings_log_level_title": "Žurnalo įrašų lygis: {level}", @@ -425,6 +430,7 @@ "album_remove_user_confirmation": "Ar tikrai norite pašalinti naudotoją {user}?", "album_search_not_found": "Pagal jūsų paiešką albumų nerasta", "album_share_no_users": "Atrodo, kad bendrinate šį albumą su visais naudotojais, arba neturite naudotojų, su kuriais galėtumėte bendrinti.", + "album_summary": "Albumo santrauka", "album_updated": "Albumas atnaujintas", "album_updated_setting_description": "Gauti pranešimą el. paštu, kai bendrinamas albumas turi naujų elementų", "album_user_left": "Paliko {album}", @@ -482,7 +488,7 @@ "asset_description_updated": "Elemento aprašymas buvo atnaujintas", "asset_filename_is_offline": "Elementas {filename} nepasiekiamas", "asset_has_unassigned_faces": "Elementas turi nepriskirtų veidų", - "asset_hashing": "Maišoma…", + "asset_hashing": "Kuriami bylų parašai…", "asset_list_group_by_sub_title": "Grupuoti pagal", "asset_list_layout_settings_dynamic_layout_title": "Dinaminis išdėstymas", "asset_list_layout_settings_group_automatically": "Automatiškai", @@ -496,6 +502,8 @@ "asset_restored_successfully": "Elementas atkurtas sėkmingai", "asset_skipped": "Praleista", "asset_skipped_in_trash": "Šiukšliadėžėje", + "asset_trashed": "Elementai ištrinti", + "asset_troubleshoot": "Elementų trikčių šalinimas", "asset_uploaded": "Įkelta", "asset_uploading": "Įkeliama…", "asset_viewer_settings_subtitle": "Tvarkykite savo galerijos peržiūros nustatymus", @@ -529,8 +537,10 @@ "autoplay_slideshow": "Automatiškai rodyti skaidrių demonstraciją", "back": "Atgal", "back_close_deselect": "Atgal, uždaryti arba atžymėti", + "background_backup_running_error": "Vyksta foninis atsarginis kopijavimas, negalima pradėti rankinio kopijavimo", "background_location_permission": "Foninis vietovės leidimas", "background_location_permission_content": "Veikiant fone tinklo perjungimui Immich privalo *visada* turėti prieigą prie tikslios vietovės, kad programa galėtų perskaityti Wi-Fi tinklo pavadinimą", + "background_options": "Fono nuostatos", "backup": "Atsarginė kopija", "backup_album_selection_page_albums_device": "Albumų įrenginyje ({count})", "backup_album_selection_page_albums_tap": "Palieskite įtraukti, du kart palieskite neįtraukti", @@ -538,6 +548,7 @@ "backup_album_selection_page_select_albums": "Pažymėti albumai", "backup_album_selection_page_selection_info": "Pažymėjimo informacija", "backup_album_selection_page_total_assets": "Viso unikalių elementų", + "backup_albums_sync": "Atsarginio kopijavimo albumų sinchronizacija", "backup_all": "Visi", "backup_background_service_backup_failed_message": "Nepavyko sukurti atsarginių kopijų. Bandoma dar kartą…", "backup_background_service_connection_failed_message": "Nepavyko prisijungti prie serverio. Bandoma dar kartą…", @@ -651,6 +662,8 @@ "change_pin_code": "Pakeisti PIN kodą", "change_your_password": "Pakeisti slaptažodį", "changed_visibility_successfully": "Matomumas pakeistas sėkmingai", + "charging": "Kraunasi", + "charging_requirement_mobile_backup": "Foninis kopijavimas reikalauja, kad įrenginys būtų prijungtas pakrovimui", "check_corrupt_asset_backup": "Patikrinti sugadintų elementų atsarginę kopiją", "check_corrupt_asset_backup_button": "Atlikti patikrinimą", "check_corrupt_asset_backup_description": "Paleiskite šį patikrinimą tik per Wi-Fi ir tik kai visi elementai buvo perkopijuoti. Ši procedūra užtruks kelias minutes.", @@ -683,7 +696,7 @@ "comments_are_disabled": "Komentarai yra išjungti", "common_create_new_album": "Sukurti naują albumą", "common_server_error": "Prašome patikrinti tinklo prisijungimą ir įsitikinti, kad serveris pasiekiamas ir programos/serverio versija sutampa.", - "completed": "Atlikta", + "completed": "Užbaigta", "confirm": "Patvirtinti", "confirm_admin_password": "Patvirtinti administratoriaus slaptažodį", "confirm_delete_face": "Ar tikrai norite ištrinti {name} veidą iš elementų?", @@ -737,6 +750,7 @@ "create_user": "Sukurti naudotoją", "created": "Sukurta", "created_at": "Sukurta", + "creating_linked_albums": "Kuriami susieti albumai...", "crop": "Apkirpti", "curated_object_page_title": "Daiktai", "current_device": "Dabartinis įrenginys", @@ -886,7 +900,9 @@ "error": "Klaida", "error_change_sort_album": "Nepavyko pakeisti albumo rūšiavimo tvarkos", "error_delete_face": "Klaida trinant veidą iš elementų", + "error_getting_places": "Klaida gaunant vietoves", "error_loading_image": "Klaida įkeliant vaizdą", + "error_loading_partners": "Klaida užkraunant partnerius: {error}", "error_saving_image": "Klaida: {error}", "error_tag_face_bounding_box": "Klaida aprašant veidą - nepavyko gauti veido vietos koordinačių", "error_title": "Klaida - Kažkas nutiko ne taip", @@ -1051,6 +1067,7 @@ "favorites_page_no_favorites": "Nerasta mėgstamiausių elementų", "feature_photo_updated": "Pageidaujama nuotrauka atnaujinta", "features": "Funkcijos", + "features_in_development": "Kūrimo funkcijos", "features_setting_description": "Valdyti aplikacijos funkcijas", "file_name": "Failo pavadinimas", "file_name_or_extension": "Failo pavadinimas arba plėtinys", @@ -1090,9 +1107,9 @@ "haptic_feedback_switch": "Įjungti haptinį grįžtamąjį ryšį", "haptic_feedback_title": "Haptinis grįžtamasis ryšys", "has_quota": "Turi kvotą", - "hash_asset": "Maišymo elementas", - "hashed_assets": "Sumaišyti elementai", - "hashing": "Maišoma", + "hash_asset": "Kurti bylos parašą elementui", + "hashed_assets": "Elementai su bylų parašais", + "hashing": "Bylų parašo kūrimas", "header_settings_add_header_tip": "Pridėti antraštę", "header_settings_field_validator_msg": "Reikšmė negali būti tuščia", "header_settings_header_name_input": "Antraštės pavadinimas", @@ -1115,64 +1132,158 @@ "home_page_building_timeline": "Kuriama laiko juosta", "home_page_delete_err_partner": "Negalima ištrinti partnerio elementų, praleidžiama", "home_page_delete_remote_err_local": "Vietiniai elementai ištrinant nuotolinį pasirinkimą, praleidžiami", - "home_page_favorite_err_local": "Kol kad negalima priskirti mėgstamiausių vietinių elementų, praleidžiama", + "home_page_favorite_err_local": "Kol kas negalima priskirti mėgstamiausių vietinių elementų, praleidžiama", + "home_page_favorite_err_partner": "Kol kas negalima priskirti mėgstamiausių partnerio elementų, praleidžiama", "home_page_first_time_notice": "Jei jūs naudojate programą pirmą kartą, tai prašome pasirinkti atsarginės kopijos albumą, kad laiko juosta galėtų tvarkyti albumo nuotraukas ir vaizdo įrašus", "home_page_locked_error_local": "Nepavyko perkelti lokalių failų į užrakintą aplanką, praleidžiama", "home_page_locked_error_partner": "Nepavyko perkelti partnerio failų į užrakintą aplanką, praleidžiama", + "home_page_share_err_local": "Negalima dalinti vietinių elementų per nuorodą, praleidžiama", + "home_page_upload_err_limit": "Galima įkelti tik iki 30 elementų vienu metu, praleidžiama", + "host": "Šeimininkas", "hour": "Valanda", + "hours": "Valandos", + "id": "ID", + "idle": "Laisva", + "ignore_icloud_photos": "Ignoruoti iCloud nuotraukas", + "ignore_icloud_photos_description": "Nuotraukos laikomos iCloud nebus įkeltos į Immich serverį", "image": "Nuotrauka", + "image_alt_text_date": "{isVideo, select, true {Filmuota} other {Fotografuota}} {date}", + "image_alt_text_date_1_person": "{isVideo, select, true {Filmuota} other {Fotografuota}} su {person1} {date}", + "image_alt_text_date_2_people": "{isVideo, select, true {Filmuota} other {Fotografuota}} su {person1} ir {person2} {date}", + "image_alt_text_date_3_people": "{isVideo, select, true {Filmuota} other {Fotografuota}} {date} su {person1}, {person2} ir{person3}", + "image_alt_text_date_4_or_more_people": "{isVideo, select, true {Filmuota} other {Fotografuota}} {date} su {person1}, {person2} ir {additionalCount, number} kitais", + "image_alt_text_date_place": "{isVideo, select, true {Filmuota} other {Fotografuota}} {city}, {country} {date}", + "image_alt_text_date_place_1_person": "{isVideo, select, true {Filmuota} other {Fotografuota}} su {person1} - {city}, {country} {date}", + "image_alt_text_date_place_2_people": "{isVideo, select, true {Filmuota} other {Fotografuota}} su {person1} ir {person2} - {city}, {country} {date}", + "image_alt_text_date_place_3_people": "{isVideo, select, true {Filmuota} other {Fotografuota}} su {person1}, {person2}, ir {person3} - {city}, {country} {date}", + "image_alt_text_date_place_4_or_more_people": "{isVideo, select, true {Filmuota} other {Fotografuota}} su {person1}, {person2}, ir {additionalCount, number} kitais - {city}, {country} {date}", + "image_saved_successfully": "Nuotrauka išsaugota", + "image_viewer_page_state_provider_download_started": "Atsisiuntimas pradėtas", + "image_viewer_page_state_provider_download_success": "Atsisiuntimas pavyko", + "image_viewer_page_state_provider_share_error": "Dalinimosi klaida", "immich_logo": "Immich logotipas", + "immich_web_interface": "Immich Web sąsaja", "import_from_json": "Importuoti iš JSON", "import_path": "Importavimo kelias", + "in_albums": "{count, plural, one {# Albume} few {#Albumuose} other {# Albumų}}", "in_archive": "Archyve", "include_archived": "Įtraukti archyvuotus", "include_shared_albums": "Įtraukti bendrinamus albumus", "include_shared_partner_assets": "Įtraukti partnerio pasidalintus elementus", + "individual_share": "Pavienis pasidalinimas", + "individual_shares": "Pavieniai pasidalinimai", "info": "Informacija", "interval": { "day_at_onepm": "Kiekvieną dieną 13:00", + "hours": "Kas{hours, plural, one {valandą} few {#valandas} other {{hours, number} valandų}}", "night_at_midnight": "Kiekvieną vidurnaktį", "night_at_twoam": "Kiekvieną naktį 02:00" }, + "invalid_date": "Netinkama data", + "invalid_date_format": "Netinkamas datos formatas", "invite_people": "Kviesti žmones", "invite_to_album": "Pakviesti į albumą", + "ios_debug_info_fetch_ran_at": "Užkrovimas vyko {dateTime}", + "ios_debug_info_last_sync_at": "Paskutinė sinchronizacija {dateTime}", + "ios_debug_info_no_processes_queued": "Eilėje nėra foninių procesų", "ios_debug_info_no_sync_yet": "Jokia background sync užduotis dar nebuvo paleista", + "ios_debug_info_processes_queued": "{count, plural, one {Eilėje {count} foninis procesas} few {Eilėje {count} foniniai procesai} other {Eilėje {count} foninių procesų}}", + "ios_debug_info_processing_ran_at": "Apdorojimas vyko {dateTime}", "items_count": "{count, plural, one {# elementas} few {# elementai} other {# elementų}}", "jobs": "Užduotys", "keep": "Palikti", "keep_all": "Palikti visus", + "keep_this_delete_others": "Išsaugoti šį, kitus ištrinti", + "kept_this_deleted_others": "Išsaugotas šis elementas ir {count, plural, one {ištrintas # elementas} few {ištrinti # elementai} other {ištrinta # elementų}}", "keyboard_shortcuts": "Spartieji klaviatūros klavišai", "language": "Kalba", + "language_no_results_subtitle": "Bandykite pakoreguoti paieškos terminą", + "language_no_results_title": "Kalbos nerastos", + "language_search_hint": "Ieškoti kalbų...", "language_setting_description": "Pasirinkti pageidaujamą kalbą", + "large_files": "Dideli failai", + "last": "Paskutinis", "last_seen": "Paskutinį kartą matytas", "latest_version": "Naujausia versija", "latitude": "Platuma", "leave": "Išeiti", + "leave_album": "Palikti albumą", + "lens_model": "Lęšių modelis", "let_others_respond": "Leisti kitiems reaguoti", "level": "Lygis", "library": "Biblioteka", "library_options": "Bibliotekos pasirinktys", + "library_page_device_albums": "Albumai įrenginyje", + "library_page_new_album": "Naujas albumas", "library_page_sort_asset_count": "Elementų skaičius", "library_page_sort_created": "Kūrimo data", "library_page_sort_last_modified": "Paskutinį kartą modifikuota", "library_page_sort_title": "Albumo pavadinimas", + "licenses": "Licencijos", + "light": "Šviesi", + "like": "Kaip", + "like_deleted": "Kaip ištrintas", + "link_motion_video": "Susieti judesio vaizdo įrašą", "link_to_oauth": "Susieti su OAuth", "linked_oauth_account": "Susieta OAuth paskyra", "list": "Sąrašas", "loading": "Kraunama", "loading_search_results_failed": "Nepavyko užkrauti paieškos rezultatų", + "local": "Vietinis", + "local_asset_cast_failed": "Negalima transliuoti elemento kuris neįkeltas į serverį", + "local_assets": "Vietiniai elementai", + "local_media_summary": "Vietinės medijos santrauka", + "local_network": "Vietinis tinklas", + "local_network_sheet_info": "Programa jungsis prie serverio per šį URL kai naudos pasirinktą Wi-Fi tinklą", + "location_permission": "Vietovės leidimai", "location_permission_content": "Norint naudoti automatinio persijungimo opciją, Immich reikia tikslios vietovės leidimo, kad galėtų nuskaityti Wi-Fi tinklo pavadinimą", + "location_picker_choose_on_map": "Pasirinkite žemėlapyje", + "location_picker_latitude_error": "Įveskite tinkamą platumą", + "location_picker_latitude_hint": "Įveskite platumą čia", + "location_picker_longitude_error": "Įveskite tinkamą ilgumą", + "location_picker_longitude_hint": "Įveskite ilgumą čia", + "lock": "Užrakinti", "locked_folder": "Užrakintas aplankas", + "log_detail_title": "Žurnalo detalės", "log_out": "Atsijungti", "log_out_all_devices": "Atsijungti iš visų įrenginių", + "logged_in_as": "Prisijungta kaip {user}", "logged_out_all_devices": "Atsijungta iš visų įrenginių", + "logged_out_device": "Atsijungta nuo įrenginio", "login": "Prisijungti", + "login_disabled": "Prisijungimas neįgalintas", + "login_form_api_exception": "API išimtis. Patikrinkite serverio URL ir bandykite dar kartą.", + "login_form_back_button_text": "Atgal", + "login_form_email_hint": "jusupastas@email.com", + "login_form_endpoint_hint": "http://jusu-serverio-ip:port", + "login_form_endpoint_url": "Serverio galutinio taško URL", + "login_form_err_http": "Prašome nurodyti http:// arba https://", + "login_form_err_invalid_email": "Neteisingas el. paštas", + "login_form_err_invalid_url": "Neteisingas URL", + "login_form_err_leading_whitespace": "Pradinis tarpas", + "login_form_err_trailing_whitespace": "Galinis tarpas", + "login_form_failed_get_oauth_server_config": "Klaida prisijungiant su OAuth, patikrinkite serverio URL", + "login_form_failed_get_oauth_server_disable": "Serveryje OAuth funkcija negalima", + "login_form_failed_login": "Klaida prisijungiant, patikrinkite serverio URL, el. paštą ir slaptažodį", + "login_form_handshake_exception": "Įvyko serverio patvirtinimo išimtis. Jei naudojate savarankiškai pasirašytą sertifikatą, nustatymuose įjunkite savarankiškai pasirašyto sertifikato palaikymą.", + "login_form_password_hint": "slaptažodis", + "login_form_save_login": "Likti prisijungus", + "login_form_server_empty": "Įveskite serverio URL.", + "login_form_server_error": "Nepavyko prisijungti prie serverio.", "login_has_been_disabled": "Prisijungimas išjungtas.", + "login_password_changed_error": "Įvyko klaida atnaujinant jūsų slaptažodį", + "login_password_changed_success": "Slaptažodis sėkmingai atnaujintas", "logout_all_device_confirmation": "Ar tikrai norite atsijungti iš visų įrenginių?", "logout_this_device_confirmation": "Ar tikrai norite atsijungti iš šio prietaiso?", + "logs": "Žurnalas", "longitude": "Ilguma", + "look": "Išvaizda", "loop_videos": "Kartoti vaizdo įrašus", + "loop_videos_description": "Įgalinti automatinį vaizdo įrašo rodymą iš naujo detalių peržiūroje.", + "main_branch_warning": "Jūs naudojate kūrėjo versiją, mes stipriai rekomenduojame naudoti galutinę versiją!", + "main_menu": "Pagrindinis meniu", "make": "Gamintojas", + "manage_geolocation": "Tvarkyti vietovę", "manage_shared_links": "Bendrinimo nuorodų tvarkymas", "manage_sharing_with_partners": "Valdyti dalijimąsi su partneriais", "manage_the_app_settings": "Valdyti programos nustatymus", @@ -1182,15 +1293,41 @@ "manage_your_oauth_connection": "Tvarkyti OAuth prisijungimą", "map": "Žemėlapis", "map_assets_in_bounds": "{count, plural, =0 {Nuotraukų nėra} one {# nuotrauka} other {# nuotraukos}}", + "map_cannot_get_user_location": "Negalime gauti naudotojo vietovės", + "map_location_dialog_yes": "Taip", + "map_location_picker_page_use_location": "Naudoti šią vietovę", + "map_location_service_disabled_content": "Vietovės servisas turi būti įjungtas, kad rodytų elementus iš dabartinės vietovės. Įjungti vietovės servisą?", + "map_location_service_disabled_title": "Vietovės servisas išjungtas", + "map_marker_for_images": "Žemėlapio žymeklis nuotraukoms yra {city}, {country}", + "map_marker_with_image": "Žemėlapio žymeklis su nuotrauka", + "map_no_location_permission_content": "Reikalingas vietovės leidimas, kad rodytų elementus iš dabartinės vietovės. Ar norite suteikti leidimą?", + "map_no_location_permission_title": "Vietovės leidimas atmestas", "map_settings": "Žemėlapio nustatymai", + "map_settings_dark_mode": "Tamsi tema", + "map_settings_date_range_option_day": "Pastarosios 24 valandos", "map_settings_date_range_option_days": "Pastarąsias {days} dienas", + "map_settings_date_range_option_year": "Pastarieji metai", "map_settings_date_range_option_years": "Pastaruosius {years} metus", + "map_settings_dialog_title": "Žemėlapio nustatymai", "map_settings_include_show_archived": "Įtraukti archyvuotus", + "map_settings_include_show_partners": "Pridėti partneriai", + "map_settings_only_show_favorites": "Rodyti tik mėgstamiausius", + "map_settings_theme_settings": "Žemėlapio tema", + "map_zoom_to_see_photos": "Atitolinkite, kad matytumėte nuotraukas", + "mark_all_as_read": "Pažymėti viską kaip perskaitytą", + "mark_as_read": "Pažymėti kaip perskaitytą", + "marked_all_as_read": "Viskas pažymėta kaip perskaityta", "matches": "Atitikmenys", + "matching_assets": "Atitinkantys elementai", "media_type": "Laikmenos tipas", "memories": "Atsiminimai", + "memories_all_caught_up": "Jau viskas peržiūrėta", + "memories_check_back_tomorrow": "Užsukite rytoj, kad pamatytumėte daugiau prisiminimų", "memories_setting_description": "Valdyti tai, ką matote savo prisiminimuose", - "memory": "Atmintis", + "memories_start_over": "Pradėti iš naujo", + "memories_swipe_to_close": "Perbraukite į viršų norėdami uždaryti", + "memory": "Prisiminimai", + "memory_lane_title": "Prisiminimų juosta {title}", "menu": "Meniu", "merge": "Sujungti", "merge_people": "Sujungti asmenis", @@ -1200,24 +1337,40 @@ "merged_people_count": "{count, plural, one {Sujungtas # asmuo} few {Sujungti # asmenys} other {Sujungta # asmenų}}", "minimize": "Sumažinti", "minute": "Minutė", + "minutes": "Minutės", "missing": "Trūkstami", "model": "Modelis", "month": "Mėnesis", + "monthly_title_text_date_format": "MMMM y", "more": "Daugiau", + "move": "Perkelti", "move_off_locked_folder": "Ištraukti iš užrakinto aplanko", "move_to_lock_folder_action_prompt": "{count} įkelta į užrakintą aplanką", "move_to_locked_folder": "Įtraukti į užrakintą aplanką", "move_to_locked_folder_confirmation": "Šios nuotraukos ir vaizdo įrašai bus pašalinti iš visų albumų ir bus matomi tik užrakintame aplanke", + "moved_to_archive": "{count, plural, one {# Elementas perkeltas} few {# Elementai perkelti} other {# Elementų perkelta}} į archyvą", + "moved_to_library": "{count, plural, one {# Elementas perkeltas} few {# Elementai perkelti} other {# Elementų perkelta}} į biblioteką", "moved_to_trash": "Perkelta į šiukšliadėžę", + "multiselect_grid_edit_date_time_err_read_only": "Negalima redaguoti tik skaitomo elemento datos, praleidžiama", + "multiselect_grid_edit_gps_err_read_only": "Negalima redaguoti tik skaitomo elemento vietovės, praleidžiama", + "mute_memories": "Užtildyti prisiminimus", "my_albums": "Mano albumai", "name": "Vardas", "name_or_nickname": "Vardas arba slapyvardis", + "network_requirement_photos_upload": "Naudoti mobilų internetą atsarginėms nuotraukų kopijoms", + "network_requirement_videos_upload": "Naudoti mobilų internetą atsarginėms vaizdo įrašų kopijoms", + "network_requirements": "Tinklo reikalavimai", + "network_requirements_updated": "Tinklo reikalavimai pakeisti, atstatoma atsarginio kopijavimo eilė", + "networking_settings": "Tinklai", + "networking_subtitle": "Tvarkyti serverio galutinio taško nustatymus", "never": "Niekada", "new_album": "Naujas albumas", "new_api_key": "Naujas API raktas", "new_password": "Naujas slaptažodis", "new_person": "Naujas asmuo", + "new_pin_code": "Naujas PIN kodas", "new_pin_code_subtitle": "Tai pirmas kartas, kai naudojate užrakinto aplanko funkciją. Nustatykite PIN kodą savo užrakintam aplankui", + "new_timeline": "Nauja laiko juosta", "new_user_created": "Naujas naudotojas sukurtas", "new_version_available": "PRIEINAMA NAUJA VERSIJA", "newest_first": "Pirmiausia naujausi", @@ -1229,33 +1382,68 @@ "no_albums_yet": "Atrodo, kad dar neturite albumų.", "no_archived_assets_message": "Suarchyvuokite nuotraukas ir vaizdo įrašus, kad jie nebūtų rodomi nuotraukų rodinyje", "no_assets_message": "SPUSTELĖKITE NORĖDAMI ĮKELTI PIRMĄJĄ NUOTRAUKĄ", + "no_assets_to_show": "Nėra rodomų elementų", + "no_cast_devices_found": "Nerasta transliavimo įrenginių", + "no_checksum_local": "Kontrolinė suma nepasiekiama – negalima gauti vietinių elementų", + "no_checksum_remote": "Kontrolinė suma nepasiekiama – negalima gauti nuotolinių elementų", "no_duplicates_found": "Dublikatų nerasta.", + "no_exif_info_available": "Nėra Exif informacijos", "no_explore_results_message": "Įkelkite daugiau nuotraukų ir tyrinėkite savo kolekciją.", + "no_favorites_message": "Pridėti į mėgstamiausius, kad greitai rastum geriausias nuotraukas ir vaizdo įrašus", "no_libraries_message": "Sukurkite išorinę biblioteką nuotraukoms ir vaizdo įrašams peržiūrėti", + "no_local_assets_found": "Nerasta jokių vietinių elementų su šia kontroline suma", "no_locked_photos_message": "Užrakintame aplanke esančios nuotraukos ir vaizdo įrašai yra paslėpti ir nematomi naršant ir ieškant.", "no_name": "Be vardo", - "no_results": "Nerasta", + "no_notifications": "Pranešimų nėra", + "no_people_found": "Ieškomų žmonių nerasta", + "no_places": "Vietovių nėra", + "no_remote_assets_found": "Nerasta jokių nuotolinių elementų su šia kontroline suma", + "no_results": "Rezultatų nerasta", "no_results_description": "Pabandykite sinonimą arba bendresnį raktažodį", + "no_shared_albums_message": "Sukurkite nuotraukų ar vaizdo įrašų albumą dalinimuisi su žmonėmis jūsų tinkle", + "no_uploads_in_progress": "Nėra vykstančių įkėlimų", + "not_available": "Nepasiekiamas", "not_in_any_album": "Nė viename albume", - "note_apply_storage_label_to_previously_uploaded assets": "Pastaba: Priskirti Saugyklos Žymą prie ankčiau įkeltų ištekliu, paleiskite šį", + "not_selected": "Nepasirinkta", + "note_apply_storage_label_to_previously_uploaded assets": "Pastaba: Priskirti Saugyklos Žymą prie anksčiau įkeltų ištekliu, paleiskite šį", "notes": "Pastabos", + "nothing_here_yet": "Kol kas tuščia", + "notification_permission_dialog_content": "Pranešimų įgalinimui eikite į Nustatymus ir pasirinkite Leisti.", + "notification_permission_list_tile_content": "Suteikti leidimą pranešimų įgalinimui.", + "notification_permission_list_tile_enable_button": "Įgalinti pranešimus", + "notification_permission_list_tile_title": "Pranešimų leidimai", "notification_toggle_setting_description": "Įjungti el. pašto pranešimus", "notifications": "Pranešimai", "notifications_setting_description": "Tvarkyti pranešimus", "oauth": "OAuth", "official_immich_resources": "Oficialūs Immich ištekliai", "offline": "Neprisijungęs", + "offset": "Ofsetas", + "ok": "Ok", "oldest_first": "Seniausias pirmas", "on_this_device": "Šiame įrenginyje", + "onboarding": "Įdarbinimas", + "onboarding_locale_description": "Pasirinkite pageidaujamą kalbą. Vėliau ją galėsite pakeisti nustatymuose.", + "onboarding_privacy_description": "Sekančios (neprivalomos) funkcijos remiasi išorinėmis paslaugomis ir gali būti bet kada išjungtos nustatymuose.", + "onboarding_server_welcome_description": "Nustatykime jūsų programą su dažniausiai naudojamais nustatymais.", + "onboarding_theme_description": "Pasirinkite temos spalvą. Vėliau galite pasikeisti ją nustatymuose.", + "onboarding_user_welcome_description": "Pradėkime!", "onboarding_welcome_user": "Sveiki atvykę, {user}", "online": "Prisijungęs", "only_favorites": "Tik mėgstamiausi", + "open": "Atverti", + "open_in_map_view": "Atverti žemėlapio peržiūroje", + "open_in_openstreetmap": "Atverti per OpenStreetMap", "open_the_search_filters": "Atidaryti paieškos filtrus", "options": "Pasirinktys", "or": "arba", + "organize_into_albums": "Sutvarkyti į albumus", + "organize_into_albums_description": "Sukelti egzistuojančias nuotraukas į albumus naudojant dabartinius sinchronizavimo nustatymus", "organize_your_library": "Tvarkykite savo biblioteką", "original": "Originalas", + "other": "Kiti", "other_devices": "Kiti įrenginiai", + "other_entities": "Kiti subjektai", "other_variables": "Kiti kintamieji", "owned": "Nuosavi", "owner": "Savininkas", @@ -1263,13 +1451,27 @@ "partner_can_access": "{partner} gali naudotis", "partner_can_access_assets": "Visos jūsų nuotraukos ir vaizdo įrašai, išskyrus archyvuotus ir ištrintus", "partner_can_access_location": "Vieta, kurioje darytos nuotraukos", + "partner_list_user_photos": "{user} nuotraukos", + "partner_list_view_all": "Žiūrėti viską", + "partner_page_empty_message": "Jūsų nuotraukomis dar nesidalinama su jokiu partneriu.", + "partner_page_no_more_users": "Nėra daugiau naudotojų pridėjimui", + "partner_page_partner_add_failed": "Nepavyko pridėti partnerio", + "partner_page_select_partner": "Pasirinkite partnerį", + "partner_page_shared_to_title": "Dalinamasi su", "partner_page_stop_sharing_content": "{partner} daugiau nebegalės pasiekti jūsų nuotraukų.", + "partner_sharing": "Dalinimasis su partneriu", "partners": "Partneriai", "password": "Slaptažodis", "password_does_not_match": "Slaptažodis nesutampa", "password_required": "Reikalingas slaptažodis", "password_reset_success": "Slaptažodis sėkmingai atkurtas", + "past_durations": { + "days": "Per {days, plural, one {pastarąją dieną} few {# pastarąsias dienas} other {# pastarųjų dienų}}", + "hours": "Per {hours, plural, one {pastarąją valandą} few{# pastarąsias valandas} other {# pastarųjų valandų}}", + "years": "Per {years, plural, one {pastaruosius metus} few{# pastaruosius metus} other {# pastarųjų metų}}" + }, "path": "Kelias", + "pattern": "Raštas", "pause": "Sustabdyti", "pause_memories": "Pristabdyti atsiminimus", "paused": "Sustabdyta", @@ -1278,27 +1480,73 @@ "people_edits_count": "{count, plural, one {Redaguotas # asmuo} few {Redaguoti # asmenys} other {Redaguota # asmenų}}", "people_feature_description": "Peržiūrėkite nuotraukas ir vaizdo įrašus sugrupuotus pagal asmenis", "people_sidebar_description": "Rodyti asmenų rodinio nuorodą šoninėje juostoje", + "permanent_deletion_warning": "Ištrynimo visam laikui perspėjimas", + "permanent_deletion_warning_setting_description": "Rodyti perspėjimą kai elementas ištrinamas visam laikui", "permanently_delete": "Ištrinti visam laikui", "permanently_delete_assets_count": "Visam laikui ištrinti {count, plural, one {# elementą} few {# elementus} other {# elementų}}", + "permanently_delete_assets_prompt": "Ar tikrai norite visam laikui ištrinti {count, plural, one {šitą elementą?} few {šituos # elementus?} other {šitų # elementų?}} Tuo pačiu {count, plural, one {jis bus pašalintas} other {jie bus pašalinti}} iš albumo.", + "permanently_deleted_asset": "Visiškai ištrinti elementai", "permanently_deleted_assets_count": "Visam laikui {count, plural, one {ištrintas # elementas} few {ištrinti # elementai} other {ištrinta # elementų}}", + "permission": "Leidimas", + "permission_empty": "Jūsų leidimas neturėtų būti tuščias", + "permission_onboarding_back": "Atgal", + "permission_onboarding_continue_anyway": "Vis tiek tęsti", + "permission_onboarding_get_started": "Pradėkite", + "permission_onboarding_go_to_settings": "Eiti į nustatymus", + "permission_onboarding_permission_denied": "Leidimas nesuteiktas. Norėdami naudoti Immich, suteikite nuotraukų ir vaizdo įrašų leidimus nustatymuose.", + "permission_onboarding_permission_granted": "Leidimas suteiktas! jūs pasiruošę.", + "permission_onboarding_permission_limited": "Leidimai apriboti. Norėdami leisti Immich kurti atsargines kopijas ir tvarkyti visą jūsų galerijos kolekciją, suteikite nuotraukų ir vaizdo įrašų leidimus nustatymuose.", + "permission_onboarding_request": "Immich reikalingas leidimas peržiūrėti jūsų nuotraukas ir vaizdo įrašus.", + "person": "Asmuo", + "person_age_months": "{months, plural, one {# mėnesio} other {# mėnesių}} amžiaus", + "person_age_year_months": "1 metų ir {months, plural, one {# mėnesio} other {# mėnesių}} amžiaus", + "person_age_years": "{years, plural, other {# metų}} amžiaus", + "person_birthdate": "Gimė {date}", + "person_hidden": "{name}{hidden, select, true { (paslėptas)} other {}}", + "photo_shared_all_users": "Panašu, kad savo nuotraukomis pasidalijote su visais naudotojais arba neturite naudotojų, su kuriais galėtumėte jomis pasidalyti.", "photos": "Nuotraukos", "photos_and_videos": "Nuotraukos ir vaizdo įrašai", "photos_count": "{count, plural, one {{count, number} nuotrauka} few {{count, number} nuotraukos} other {{count, number} nuotraukų}}", "photos_from_previous_years": "Ankstesnių metų nuotraukos", + "pick_a_location": "Išsirinkite vietovę", + "pin_code_changed_successfully": "PIN kodas pakeistas sėkmingai", + "pin_code_reset_successfully": "PIN kodas sėkmingai atstatytas", + "pin_code_setup_successfully": "PIN kodas sėkmingai nustatytas", + "pin_verification": "PIN kodo patvirtinimas", "place": "Vieta", "places": "Vietos", + "places_count": "{count, plural, one {{count, number} Vieta} few{{count, number} Vietos} other {{count, number} Vietų}}", + "play": "Paleisti", "play_memories": "Leisti atsiminimus", + "play_motion_photo": "Rodyti judančias nuotraukas", + "play_or_pause_video": "Rodyti arba sustabdyti vaizdo įrašą", + "please_auth_to_access": "Prašome patvirtinti prisijungimą", + "port": "Portas", + "preferences_settings_subtitle": "Tvarkyti programos nuostatas", + "preferences_settings_title": "Nuostatos", + "preset": "Šablonas", + "preview": "Peržiūra", + "previous": "Buvęs", + "previous_memory": "Buvęs prisiminimas", + "previous_or_next_day": "Dieną pirmyn/atgal", + "previous_or_next_month": "Mėnesį pirmyn/atgal", + "previous_or_next_photo": "Nuotrauką pirmyn/atgal", + "previous_or_next_year": "Metus pirmyn/atgal", + "primary": "Pirminis", + "privacy": "Privatumas", "profile": "Profilis", "profile_drawer_app_logs": "Logai", "profile_drawer_client_out_of_date_major": "Mobili aplikacija jau pasenusios versijos. Prašome atsinaujinti į paskutinę didžiąją versiją.", "profile_drawer_client_out_of_date_minor": "Mobili aplikacija jau pasenusios versijos. Prašome atsinaujinti į paskutinę mažąją versiją.", "profile_drawer_client_server_up_to_date": "Klientas ir Serveris yra atnaujinti", "profile_drawer_github": "GitHub", + "profile_drawer_readonly_mode": "Tik skaitymo rėžimas įgalintas. Ilgai paspauskite vartotojo ikoną išėjimui.", "profile_drawer_server_out_of_date_major": "Serveris jau yra pasenusios versijos. Prašome atsinaujinti į paskutinę didžiąją versiją.", "profile_drawer_server_out_of_date_minor": "Serveris jau yra pasenusios versijos. Prašome atsinaujinti į paskutinę mažąją versiją.", "profile_image_of_user": "{user} profilio nuotrauka", "profile_picture_set": "Profilio nuotrauka nustatyta.", "public_album": "Viešas albumas", + "public_share": "Viešas dilinimasis", "purchase_account_info": "Rėmėjas", "purchase_activated_subtitle": "Dėkojame, kad remiate Immich ir atviro kodo programinę įrangą", "purchase_activated_time": "Suaktyvinta {date}", @@ -1313,6 +1561,7 @@ "purchase_failed_activation": "Nepavyko suaktyvinti! Patikrinkite el. paštą, ar turite teisingo produkto koda!", "purchase_individual_description_1": "Asmeniui", "purchase_individual_description_2": "Rėmėjo statusas", + "purchase_individual_title": "Asmeninis", "purchase_input_suggestion": "Turite produkto raktą? Įveskite jį žemiau", "purchase_license_subtitle": "Įsigykite „Immich“, kad palaikytumėte tolesnį paslaugos vystymą", "purchase_lifetime_description": "Pirkimas visam gyvenimui", diff --git a/i18n/lv.json b/i18n/lv.json index b0c77998b3..941d1c59f7 100644 --- a/i18n/lv.json +++ b/i18n/lv.json @@ -44,7 +44,7 @@ "authentication_settings_description": "Paroļu, OAuth un citu autentifikācijas iestatījumu pārvaldība", "authentication_settings_disable_all": "Vai tiešām vēlaties atspējot visas pieteikšanās metodes? Pieteikšanās tiks pilnībā atspējota.", "authentication_settings_reenable": "Lai atkārtoti iespējotu, izmantojiet Servera Komandu.", - "background_task_job": "Fona Uzdevumi", + "background_task_job": "Fona uzdevumi", "backup_database": "Izveidot datu bāzes izrakstu", "backup_database_enable_description": "Iespējot datu bāzes izrakstus", "backup_keep_last_amount": "Iepriekšējo izrakstu daudzums, kas jāsaglabā", @@ -62,7 +62,7 @@ "create_job": "Izveidot uzdevumu", "cron_expression": "Cron izteiksme", "disable_login": "Atspējot pieteikšanos", - "duplicate_detection_job_description": "Palaidiet mašīnmācīšanos uz failiem, lai noteiktu līdzīgus attēlus. Paļaujas uz viedo meklēšanu", + "duplicate_detection_job_description": "Analizēt failus ar mašīnmācīšanos, lai noteiktu līdzīgus attēlus. Šī funkcija izmanto viedo meklēšanu", "external_library_management": "Ārējo bibliotēku pārvaldība", "face_detection": "Seju noteikšana", "image_format": "Formāts", @@ -176,6 +176,7 @@ "server_settings_description": "Servera iestatījumu pārvaldība", "server_welcome_message": "Sveiciena ziņa", "server_welcome_message_description": "Ziņojums, kas tiek parādīts pieslēgšanās lapā.", + "smart_search_job_description": "Analizēt failus ar mašīnmācīšanos lai sagatavotu datus viedajai meklēšanai", "storage_template_date_time_sample": "Laika paraugs {date}", "storage_template_migration": "Krātuves veidņu migrācija", "storage_template_migration_job": "Krātuves veidņu migrācijas uzdevums", @@ -225,16 +226,15 @@ "user_settings_description": "Lietotāju iestatījumu pārvaldība", "version_check_enabled_description": "Ieslēgt versijas pārbaudi", "version_check_implications": "Versiju pārbaudes funkcija ir atkarīga no periodiskas saziņas ar github.com", - "version_check_settings": "Versijas pārbaude" + "version_check_settings": "Versijas pārbaude", + "version_check_settings_description": "Ieslēgt/izslēgt paziņojumus par jaunu versiju" }, "admin_email": "Administratora e-pasts", "admin_password": "Administratora parole", "administration": "Administrēšana", "advanced": "Papildu", - "advanced_settings_beta_timeline_subtitle": "Izmēģini jauno lietotnes pieredzi", - "advanced_settings_beta_timeline_title": "Bēta laika skala", "advanced_settings_log_level_title": "Žurnalēšanas līmenis: {level}", - "advanced_settings_prefer_remote_subtitle": "Dažās ierīcēs sīktēli no ierīcē esošajiem resursiem tiek ielādēti ļoti lēni. Aktivizējiet šo iestatījumu, lai tā vietā ielādētu attālus attēlus.", + "advanced_settings_prefer_remote_subtitle": "Dažās ierīcēs sīktēli no ierīces atmiņas ielādējas ļoti lēni. Aktivizējiet šo iestatījumu, lai tā vietā ielādētu attālus attēlus.", "advanced_settings_prefer_remote_title": "Dot priekšroku attāliem attēliem", "advanced_settings_proxy_headers_title": "Starpniekservera galvenes", "advanced_settings_self_signed_ssl_subtitle": "Izlaiž servera galapunkta SSL sertifikātu verifikāciju. Nepieciešams pašparakstītajiem sertifikātiem.", @@ -272,7 +272,7 @@ "albums_default_sort_order_description": "Sākotnējā failu kārtošanas secība, veidojot jaunus albumus.", "albums_feature_description": "Failu kolekcijas, kuras var koplietot ar citiem lietotājiem.", "albums_on_device_count": "Albumi ierīcē ({count})", - "all": "Viss", + "all": "Visi", "all_albums": "Visi albumi", "all_people": "Visas personas", "all_videos": "Visi video", @@ -305,7 +305,7 @@ "asset_list_group_by_sub_title": "Grupēt pēc", "asset_list_layout_settings_dynamic_layout_title": "Dinamiskais izkārtojums", "asset_list_layout_settings_group_automatically": "Automātiski", - "asset_list_layout_settings_group_by": "Grupēt aktīvus pēc", + "asset_list_layout_settings_group_by": "Grupēt failus pēc", "asset_list_layout_settings_group_by_month_day": "Mēnesis + diena", "asset_list_layout_sub_title": "Izvietojums", "asset_list_settings_subtitle": "Fotorežģa izkārtojuma iestatījumi", @@ -314,7 +314,7 @@ "asset_skipped_in_trash": "Atkritnē", "asset_uploaded": "Augšupielādēts", "asset_uploading": "Augšupielādē…", - "asset_viewer_settings_title": "Aktīvu Skatītājs", + "asset_viewer_settings_title": "Failu skatītājs", "assets": "Faili", "assets_added_count": "Pievienoja {count, plural, one {# failu} other {# failus}}", "assets_added_to_album_count": "Pievienoja albumam {count, plural, one {# failu} other {# failus}}", @@ -328,6 +328,7 @@ "automatic_endpoint_switching_title": "Automātiska URL pārslēgšana", "autoplay_slideshow": "Automātiska slaidrādes atskaņošana", "back": "Atpakaļ", + "background_options": "Fona opcijas", "backup": "Dublēšana", "backup_album_selection_page_albums_device": "Albumi ierīcē ({count})", "backup_album_selection_page_albums_tap": "Pieskarieties, lai iekļautu, veiciet dubultskārienu, lai izslēgtu", @@ -335,6 +336,7 @@ "backup_album_selection_page_select_albums": "Atlasīt albumus", "backup_album_selection_page_selection_info": "Atlases informācija", "backup_album_selection_page_total_assets": "Unikālo failu kopsumma", + "backup_albums_sync": "Dublēšanas albumu sinhronizācija", "backup_all": "Viss", "backup_background_service_backup_failed_message": "Neizdevās dublēt līdzekļus. Notiek atkārtota mēģināšana…", "backup_background_service_connection_failed_message": "Neizdevās izveidot savienojumu ar serveri. Notiek atkārtota mēģināšana…", @@ -436,6 +438,8 @@ "change_password_form_password_mismatch": "Paroles nesakrīt", "change_password_form_reenter_new_password": "Atkārtoti ievadīt jaunu paroli", "change_pin_code": "Nomainīt PIN kodu", + "charging": "Lādē", + "charging_requirement_mobile_backup": "Fona dublēšanai nepieciešams, lai ierīce tiktu lādēta", "check_corrupt_asset_backup_button": "Veikt pārbaudi", "choose_matching_people_to_merge": "Izvēlies atbilstošas personas apvienošanai", "city": "Pilsēta", @@ -471,11 +475,12 @@ "control_bottom_app_bar_create_new_album": "Izveidot jaunu albumu", "control_bottom_app_bar_delete_from_immich": "Dzēst no Immich", "control_bottom_app_bar_delete_from_local": "Dzēst no ierīces", - "control_bottom_app_bar_edit_location": "Rediģēt Atrašanās Vietu", - "control_bottom_app_bar_edit_time": "Rediģēt Datumu un Laiku", - "control_bottom_app_bar_share_to": "Kopīgot Uz", + "control_bottom_app_bar_edit_location": "Rediģēt atrašanās vietu", + "control_bottom_app_bar_edit_time": "Rediģēt datumu un laiku", + "control_bottom_app_bar_share_to": "Kopīgot uz", "control_bottom_app_bar_trash_from_immich": "Pārvietot uz Atkritni", "copy_error": "Kopēšanas kļūda", + "copy_to_clipboard": "Kopēt starpliktuvē", "country": "Valsts", "create": "Izveidot", "create_album": "Izveidot albumu", @@ -497,6 +502,7 @@ "custom_locale_description": "Formatēt datumus un skaitļus atbilstoši valodai un reģionam", "custom_url": "Pielāgots URL", "daily_title_text_date_year": "E, MMM dd, gggg", + "dark_theme": "Pārslēgt tumšo tēmu", "date_after": "Datums pēc", "date_and_time": "Datums un Laiks", "date_before": "Datums pirms", @@ -601,6 +607,7 @@ "enter_your_pin_code_subtitle": "Ievadi savu PIN kodu, lai piekļūtu slēgtajai mapei", "error": "Kļūda", "error_change_sort_album": "Neizdevās nomainīt albuma kārtošanas secību", + "error_loading_partners": "Kļūda, ielādējot partnerus: {error}", "error_saving_image": "Kļūda: {error}", "errors": { "cant_get_faces": "Nevar iegūt sejas", @@ -650,12 +657,14 @@ "expired": "Derīguma termiņš beidzās", "explore": "Izpētīt", "export": "Eksportēt", + "export_as_json": "Eksportēt kā JSON", "export_database": "Eksportēt datubāzi", "export_database_description": "Eksportēt SQLite datubāzi", "extension": "Paplašinājums", "external": "Ārējs", + "external_libraries": "Ārējas bibliotēkas", "external_network": "Ārējs tīkls", - "external_network_sheet_info": "When not on the preferred WiFi network, the app will connect to the server through the first of the below URLs it can reach, starting from top to bottom", + "external_network_sheet_info": "Kad nav pieejams izvēlētais Wi-Fi tīkls, aplikācija pieslēgsies serverim lietojot pirmo strādājošo URL no saraksta, sākot ar augšējo", "face_unassigned": "Nepiešķirts", "failed": "Neizdevās", "failed_to_authenticate": "Neizdevās autentificēties", @@ -664,6 +673,7 @@ "favorite": "Izlase", "favorites": "Izlase", "favorites_page_no_favorites": "Nav atrasti iecienītākie faili", + "features_in_development": "Izstrādes stadijā esošas funkcijas", "features_setting_description": "Lietotnes funkciju pārvaldība", "file_name": "Faila nosaukums", "file_name_or_extension": "Faila nosaukums vai paplašinājums", @@ -695,11 +705,11 @@ "group_owner": "Grupēt pēc īpašnieka", "group_places_by": "Grupēt vietas pēc...", "group_year": "Grupēt pēc gada", - "haptic_feedback_switch": "Iestatīt haptisku reakciju", + "haptic_feedback_switch": "Iespējot haptisku reakciju", "haptic_feedback_title": "Haptiska Reakcija", - "has_quota": "Ir kvota", + "has_quota": "Kvota", "hash_asset": "Veidot faila jaucējvērtību", - "hashed_assets": "Faili ar izveidotām jaucējvērtībām", + "hashed_assets": "Faili ar jaucējvērtībām", "hashing": "Veido jaucējvērtības", "header_settings_field_validator_msg": "Vērtība nevar būt tukša", "hide_all_people": "Paslēpt visas personas", @@ -743,6 +753,7 @@ "in_archive": "Arhīvā", "include_archived": "Iekļaut arhivētos", "include_shared_albums": "Iekļaut koplietotos albumus", + "include_shared_partner_assets": "Iekļaut partneru koplietotos failus", "info": "Informācija", "interval": { "day_at_onepm": "Katru dienu 13.00", @@ -757,6 +768,7 @@ "ios_debug_info_last_sync_at": "Pēdējā sinhronizācija {dateTime}", "ios_debug_info_no_processes_queued": "Nav ierindotu fona procesu", "ios_debug_info_processing_ran_at": "Apstrāde notika {dateTime}", + "items_count": "{count, plural, one {# vienums} other {# vienumi}}", "jobs": "Uzdevumi", "keep": "Paturēt", "keep_all": "Paturēt visus", @@ -790,6 +802,7 @@ "linked_oauth_account": "Piesaistītais OAuth konts", "list": "Saraksts", "loading": "Ielādē", + "local": "Lokāli", "local_network": "Lokālais tīkls", "location_permission": "Atrašanās vietas atļauja", "location_permission_content": "Lai izmantotu automātiskās pārslēgšanās funkciju, Immich ir nepieciešama precīzas atrašanās vietas atļauja, lai varētu nolasīt pašreizējā Wi-Fi tīkla nosaukumu", @@ -845,11 +858,11 @@ "map_marker_with_image": "Kartes marķieris ar attēlu", "map_no_location_permission_content": "Atrašanās vietas atļauja ir nepieciešama, lai parādītu jūsu pašreizējās atrašanās vietas aktīvus. Vai vēlaties to atļaut tagad?", "map_no_location_permission_title": "Atrašanās vietas Atļaujas liegtas", - "map_settings": "Kartes Iestatījumi", + "map_settings": "Kartes iestatījumi", "map_settings_dark_mode": "Tumšais režīms", "map_settings_date_range_option_day": "Pēdējās 24 stundas", "map_settings_date_range_option_days": "Pēdējās {days} dienas", - "map_settings_date_range_option_year": "Pēdējo gadu", + "map_settings_date_range_option_year": "Pēdējais gads", "map_settings_date_range_option_years": "Pēdējie {years} gadi", "map_settings_dialog_title": "Kartes Iestatījumi", "map_settings_include_show_archived": "Iekļaut Arhivētos", @@ -858,7 +871,7 @@ "map_settings_theme_settings": "Kartes Dizains", "map_zoom_to_see_photos": "Attāliniet, lai redzētu fotoattēlus", "matches": "Atbilstības", - "media_type": "Multivides veids", + "media_type": "Faila veids", "memories": "Atmiņas", "memories_all_caught_up": "Šobrīd, tas arī viss", "memories_check_back_tomorrow": "Atgriezies rīt, lai skatītu vairāk atmiņu", @@ -894,6 +907,8 @@ "name_or_nickname": "Vārds vai iesauka", "network_requirement_photos_upload": "Izmantot mobilo datu pārraidi, lai dublētu fotoattēlus", "network_requirement_videos_upload": "Izmantot mobilo datu pārraidi, lai dublētu video", + "network_requirements": "Tīkla prasības", + "networking_settings": "Tīkla iestatījumi", "networking_subtitle": "Pārvaldīt servera galapunktu iestatījumus", "never": "nekad", "new_album": "Jauns albums", @@ -901,6 +916,7 @@ "new_password": "Jaunā parole", "new_person": "Jauna persona", "new_pin_code": "Jaunais PIN kods", + "new_timeline": "Jaunā laikjosla", "new_user_created": "Izveidots jauns lietotājs", "new_version_available": "PIEEJAMA JAUNA VERSIJA", "next": "Nākamais", @@ -925,8 +941,8 @@ "nothing_here_yet": "Šeit vēl nekā nav", "notification_permission_dialog_content": "Lai iespējotu paziņojumus, atveriet Iestatījumi un atlasiet Atļaut.", "notification_permission_list_tile_content": "Piešķirt atļauju, lai iespējotu paziņojumus.", - "notification_permission_list_tile_enable_button": "Iespējot Paziņojumus", - "notification_permission_list_tile_title": "Paziņojumu Atļaujas", + "notification_permission_list_tile_enable_button": "Iespējot paziņojumus", + "notification_permission_list_tile_title": "Paziņojumu atļaujas", "notification_toggle_setting_description": "Ieslēgt e-pasta paziņojumus", "notifications": "Paziņojumi", "notifications_setting_description": "Paziņojumu pārvaldība", @@ -967,6 +983,7 @@ "partner_page_select_partner": "Izvēlēties partneri", "partner_page_shared_to_title": "Kopīgots uz", "partner_page_stop_sharing_content": "{partner} vairs nevarēs piekļūt jūsu fotoattēliem.", + "partner_sharing": "Koplietošana ar partneriem", "partners": "Partneri", "password": "Parole", "password_does_not_match": "Parole nesakrīt", @@ -1054,6 +1071,7 @@ "rating_description": "Rādīt EXIF vērtējumu informācijas panelī", "reaction_options": "Reakcijas iespējas", "read_changelog": "Lasīt izmaiņu sarakstu", + "ready_for_upload": "Gatavs augšupielādei", "recently_added_page_title": "Nesen Pievienotais", "refresh": "Atsvaidzināt", "refresh_faces": "Atsvaidzināt sejas", @@ -1063,8 +1081,10 @@ "refreshes_every_file": "Vēlreiz nolasa esošos un jaunos failus", "refreshing_faces": "Atsvaidzina sejas", "refreshing_metadata": "Atsvaidzina metadatus", + "remote": "Attāli", "remove": "Noņemt", "remove_assets_title": "Izņemt failus?", + "remove_custom_date_range": "Novākt pielāgoto datuma intervālu", "remove_deleted_assets": "Izņemt dzēstos failus", "remove_from_album": "Noņemt no albuma", "remove_from_album_action_prompt": "No albuma izņemti {count} faili", @@ -1079,6 +1099,8 @@ "removed_from_archive": "Noņēma no arhīva", "removed_from_favorites": "Noņēma no izlases", "removed_from_favorites_count": "{count, plural, other {Izņēma #}} no izlases", + "removed_memory": "Noņēma atmiņu", + "removed_photo_from_memory": "Noņēma fotogrāfiju no atmiņas", "rename": "Pārsaukt", "repair": "Remonts", "replace_with_upload": "Aizstāt ar augšupielādi", @@ -1089,6 +1111,7 @@ "reset_password": "Atiestatīt paroli", "reset_people_visibility": "Atiestatīt personu redzamību", "reset_pin_code": "Atiestatīt PIN kodu", + "reset_sqlite": "Atiestatīt SQLite datubāzi", "reset_to_default": "Atiestatīt noklusējuma iestatījumus", "resolve_duplicates": "Atrisināt dublēšanās gadījumus", "resolved_all_duplicates": "Visi dublikāti ir atrisināti", @@ -1137,6 +1160,7 @@ "search_for_existing_person": "Meklēt esošu personu", "search_no_people": "Nav personu", "search_no_people_named": "Nav personas ar vārdu \"{name}\"", + "search_options": "Meklēšanas iespējas", "search_page_categories": "Kategorijas", "search_page_motion_photos": "Kustību Fotoattēli", "search_page_no_objects": "Informācija par Objektiem nav pieejama", @@ -1149,6 +1173,8 @@ "search_page_your_map": "Jūsu Karte", "search_people": "Meklēt personas", "search_result_page_new_search_hint": "Jauns Meklējums", + "search_settings": "Meklēt iestatījumos", + "search_state": "Meklēt pēc štata...", "search_suggestion_list_smart_search_hint_1": "Viedā meklēšana pēc noklusējuma ir iespējota, lai meklētu metadatos, izmanto sintaksi ", "search_suggestion_list_smart_search_hint_2": "m:jūsu-meklēšanas-frāze", "search_type": "Meklēšanas veids", @@ -1188,13 +1214,14 @@ "setting_notifications_notify_minutes": "{count} minūtes", "setting_notifications_notify_never": "nekad", "setting_notifications_notify_seconds": "{count} sekundes", - "setting_notifications_single_progress_subtitle": "Detalizēta augšupielādes progresa informācija par katru aktīvu", + "setting_notifications_single_progress_subtitle": "Detalizēta augšupielādes progresa informācija par katru failu", "setting_notifications_single_progress_title": "Rādīt fona dublējuma detalizēto progresu", "setting_notifications_subtitle": "Paziņojumu preferenču pielāgošana", "setting_notifications_total_progress_subtitle": "Kopējais augšupielādes progress (pabeigti/kopējie faili)", "setting_notifications_total_progress_title": "Rādīt fona dublējuma kopējo progresu", "setting_video_viewer_looping_title": "Cikliski", "setting_video_viewer_original_video_subtitle": "Straumējot video no servera, izmantot oriģinālu, pat ja ir pieejama pārkodēšana. Tas var izraisīt buferēšanu. Lokāli pieejamie video tiek atskaņoti oriģinālajā kvalitātē, neatkarīgi no šīs iestatījuma.", + "setting_video_viewer_original_video_title": "Vienmēr izmantot oriģinālo video", "settings": "Iestatījumi", "settings_require_restart": "Lūdzu, restartējiet Immich, lai lietotu šo iestatījumu", "setup_pin_code": "Uzstādīt PIN kodu", @@ -1268,6 +1295,7 @@ "show_slideshow_transition": "Rādīt slīdrādes pāreju", "show_supporter_badge": "Atbalstītāja nozīmīte", "show_supporter_badge_description": "Rādīt atbalstītāja nozīmīti", + "show_text_search_menu": "Rādīt teksta meklēšanas izvēlni", "shuffle": "Jaukta", "sidebar": "Sānu josla", "sidebar_display_description": "Parādīt saiti uz skatu sānu joslā", @@ -1280,7 +1308,7 @@ "slideshow_settings": "Slīdrādes iestatījumi", "sort_albums_by": "Kārtot albumus pēc...", "sort_created": "Izveides datums", - "sort_items": "Vienību skaits", + "sort_items": "Vienumu skaits", "sort_modified": "Izmaiņu datums", "sort_newest": "Jaunākā fotogrāfija", "sort_oldest": "Vecākā fotogrāfija", @@ -1306,7 +1334,7 @@ "sync_status": "Sinhronizācijas statuss", "sync_status_subtitle": "Skatīt un pārvaldīt sinhronizācijas sistēmu", "theme": "Dizains", - "theme_setting_asset_list_storage_indicator_title": "Rādīt krātuves indikatoru uz aktīvu elementiem", + "theme_setting_asset_list_storage_indicator_title": "Rādīt krātuves indikatoru uz attēliem režga skatā", "theme_setting_asset_list_tiles_per_row_title": "Failu skaits rindā ({count})", "theme_setting_colorful_interface_subtitle": "Piemērot pamatkrāsu fona virsmām.", "theme_setting_colorful_interface_title": "Krāsaina saskarne", @@ -1338,7 +1366,7 @@ "trash_emptied": "Atkritne iztukšota", "trash_no_results_message": "Šeit parādīsies uz atkritni pārvietotās fotogrāfijas un video.", "trash_page_delete_all": "Dzēst Visu", - "trash_page_empty_trash_dialog_content": "Vai vēlaties iztukšot savus izmestos aktīvus? Tie tiks neatgriezeniski izņemti no Immich", + "trash_page_empty_trash_dialog_content": "Vai vēlaties iztukšot savus izmestos failus? Tie tiks neatgriezeniski izņemti no Immich", "trash_page_info": "Atkritnes vienumi tiks neatgriezeniski dzēsti pēc {days} dienām", "trash_page_no_assets": "Atkritnē nav aktīvu", "trash_page_restore_all": "Atjaunot Visu", diff --git a/i18n/mk.json b/i18n/mk.json index 75951405e8..8430ae117e 100644 --- a/i18n/mk.json +++ b/i18n/mk.json @@ -14,6 +14,8 @@ "add_a_location": "Додади локација", "add_a_name": "Додади име", "add_a_title": "Додади наслов", + "add_birthday": "Додади роденден", + "add_endpoint": "Додади крајна точка", "add_exclusion_pattern": "Додади шаблон за исклучување", "add_import_path": "Додади патека за импортирање", "add_location": "Додади локација", @@ -21,8 +23,15 @@ "add_partner": "Додади партнер", "add_path": "Додади патека", "add_photos": "Додади слики", + "add_tag": "Додади ознака", "add_to": "Додади во…", "add_to_album": "Додади во албум", + "add_to_album_bottom_sheet_added": "Додадено во {album}", + "add_to_album_bottom_sheet_already_exists": "Веќе во {album}", + "add_to_album_bottom_sheet_some_local_assets": "Некои локални ресурси не можеа да се додадат во албумот", + "add_to_album_toggle": "Промени ја селекцијата за {album}", + "add_to_albums": "Додади во албуми", + "add_to_albums_count": "Додади во албуми ({count})", "add_to_shared_album": "Додади во споделен албум", "add_url": "Додади URL", "added_to_archive": "Додадено во архива", @@ -30,17 +39,25 @@ "added_to_favorites_count": "Додадени {count, number} во омилени", "admin": { "add_exclusion_pattern_description": "Додади шаблони за исклучување. Поддржано е користење на glob со *, **, и ?. За да се игнорираат сите датотеки во кој било директориум именуван \"Raw\", користи \"**/Raw/**\". За да се игнорираат сите датотеки што завршуваат со \".tif\", користи \"**/*.tif\". За да се игнорира апсолутна патека, користи \"/path/to/ignore/**\".", + "admin_user": "Административен Корисник", "asset_offline_description": "Ова средство од екстерна библиотека веќе не е пронајдено на дискот и е преместено во ѓубре. Ако датотеката била преместена во рамките на библиотеката, проверете ја вашата временска линија за новото соодветно средство. За да го вратите ова средство, осигурајте се дека долунаведената патека може да биде пристапена од Immich и скенирајте ја библиотеката.", "authentication_settings": "Поставки за автентикација", "authentication_settings_description": "Управувај со лозинки, OAuth, и други поставки за автентикација", "authentication_settings_disable_all": "Дали сте сигурни дека сакате да ги исклучите сите методи за најава? Целосно ќе биде оневозможено најавување.", "authentication_settings_reenable": "За повторно да овозможите, искористете Сервер команда.", "background_task_job": "Позадински задачи", - "backup_database": "Резервна копија од базата на податоци", + "backup_database": "Креирај резервна копија од базата на податоци", "backup_database_enable_description": "Овозможи резервни копии од базата на податоци", "backup_keep_last_amount": "Количина на претходни резервни копии за чување", - "backup_settings": "Поставки за резервни копии", - "backup_settings_description": "Управувај со поставки за резервни копии на базата на податоци", + "backup_onboarding_1_description": "надворешна копија во облакот или на друга физичка локација.", + "backup_onboarding_2_description": "локални копии на различни уреди. Ова ги вклучува и основните фјалови и резервна копија од истите фајлови локално.", + "backup_onboarding_3_description": "сите копии од твоите податоци, вклучувајќи и оргиналните фајлови. Ова вклучува и 1 надворешна копија и 2 локални копии.", + "backup_onboarding_description": "3-2-1 стратегија за резервна копија е препорачано за да ги заштити твоите податоци. Потребно е да чуваш резервни копии од твоите прикачени фотографии/видеа како и базата за податоци на Immich за целосно решение за зачувување на резервна копија", + "backup_onboarding_footer": "Повеќе информации околу правење резервни копии за Immich, ве молам да се референцирате на документацијата", + "backup_onboarding_parts_title": "3-2-1 резервна копија вклучува:", + "backup_onboarding_title": "Резервни копии", + "backup_settings": "Поставки извезување база на податоци", + "backup_settings_description": "Управувај со поставки за извезување на базата на податоци", "cleared_jobs": "Исчистени задачи за: {job}", "config_set_by_file": "Конгигурацијата е моментално поставена од конфигурациска датотека", "confirm_delete_library": "Дали сте сигурни дека сакате да ја избришете библиотеката {library}?", @@ -48,19 +65,40 @@ "confirm_email_below": "За да потврдите, внесете \"{email}\" доле", "confirm_reprocess_all_faces": "Дали сте сигурни дека сакате да се обработат одново сите лица? Ова ќе ги избрише и сите именувани луѓе.", "confirm_user_password_reset": "Дали сте сигурни дека сакате да се поништи лозинката на {user}?", + "confirm_user_pin_code_reset": "Дали сигурно сакаш да го смените ПИН кодот за {user}", "create_job": "Создади задача", "cron_expression": "Cron израз", "cron_expression_description": "Подеси го интервалот на скенирање користејќи го cron форматот. За повеќе информации погледнете на пр. Crontab Guru", "cron_expression_presets": "Предефинирани Cron изрази", "disable_login": "Оневозможи најава", "duplicate_detection_job_description": "Пушти машинско учење на средствата за да се откријат слични слики. Се потпира на Smart Search", + "external_library_management": "Менаџмент на Надворешна Библиотека", + "face_detection": "Детекција на лице", "force_delete_user_warning": "ПРЕДУПРЕДУВАЊЕ: Ова веднаш ќе го отстрани корисникот и сите средства. Оваа акција не може да се поништи и датотеките нема да може да се вратат назад.", "image_format": "Формат", + "image_format_description": "WebP создава помали фајлви отколку JPEG, но е по спор при енкодирање.", + "image_fullsize_enabled": "Овозможи целосна-големина на генерирање на слика", + "image_fullsize_quality_description": "Целосна-големина на слика со квалитет од 1-100. Повисокто е подобро, но создава поголеми фајлови.", + "image_fullsize_title": "Поставки за Целосна-големина на Слика", + "image_prefer_embedded_preview": "Претпочитан вграден преглед", + "image_preview_title": "Поставки за Преглед", "image_quality": "Квалитет", "image_resolution": "Резолуција", "image_settings": "Поставки за слики", + "job_concurrency": "{job} конкурентност", + "job_created": "Креирана задача", + "job_not_concurrency_safe": "Оваа задача не е конкуретно-безбедна.", + "job_settings": "Поставки за задача", + "job_settings_description": "Управувај со конкурентност на задачи", + "job_status": "Статус на задачи", + "library_created": "Креирана библиотека: {library}", + "library_deleted": "Библиотеката е избришана", + "library_import_path_description": "Предложи папка за внес. Оваа папка, вклучува и под папки, ќе биде скенирана за слики и видеа.", "library_scanning": "Периодично скенирање", + "library_scanning_description": "Подеси периодично скениранје на библиотеката", + "library_scanning_enable_description": "Овозможи периодично скениранје на библиотеката", "library_settings": "Екстерна библиотека", + "library_settings_description": "Управувај со подесувањата за надворешната библиотека", "logging_enable_description": "Вклучи евидентирање", "logging_settings": "Евидентирање", "map_dark_style": "Темен стил", diff --git a/i18n/mr.json b/i18n/mr.json index 33a3dc5c93..dbc2e3d114 100644 --- a/i18n/mr.json +++ b/i18n/mr.json @@ -383,8 +383,6 @@ "admin_password": "प्रशासक पासवर्ड", "administration": "प्रशासन", "advanced": "प्रगत", - "advanced_settings_beta_timeline_subtitle": "नवीन ॲप अनुभव वापरून पहा", - "advanced_settings_beta_timeline_title": "बीटा टाईमलाईन", "advanced_settings_enable_alternate_media_filter_subtitle": "सिंक दरम्यान वैकल्पिक निकषांवर आधारित मीडिया फिल्टर करण्यासाठी हा पर्याय वापरा. ॲप सर्व अल्बम ओळखण्यात समस्या येत असल्यासच वापरा.", "advanced_settings_enable_alternate_media_filter_title": "[प्रयोगात्मक] उपकरण-आधारित अल्बम सिंक फिल्टर वापरा", "advanced_settings_log_level_title": "लॉग पातळी: {level}", diff --git a/i18n/ms.json b/i18n/ms.json index e7e0432a4c..c72b1ff688 100644 --- a/i18n/ms.json +++ b/i18n/ms.json @@ -14,6 +14,7 @@ "add_a_location": "Tambah lokasi", "add_a_name": "Tambah nama", "add_a_title": "Tambah tajuk", + "add_birthday": "Tambah hari jadi", "add_endpoint": "Tambah titik akhir", "add_exclusion_pattern": "Tambahkan corak pengecualian", "add_import_path": "Tambahkan laluan import", @@ -27,6 +28,8 @@ "add_to_album": "Tambah ke album", "add_to_album_bottom_sheet_added": "Dimasukkan ke {album}", "add_to_album_bottom_sheet_already_exists": "Sudah ada di {album}", + "add_to_albums": "Tambah pada album", + "add_to_albums_count": "Tambah pada album ({count})", "add_to_shared_album": "Tambah ke album yang dikongsi", "add_url": "Tambah URL", "added_to_archive": "Tambah ke arkib", @@ -44,6 +47,9 @@ "backup_database": "Buat Salinan Pangkalan Data", "backup_database_enable_description": "Dayakan salinan pangkalan data", "backup_keep_last_amount": "Jumlah salinan pangkalan data sebelumnya untuk disimpan", + "backup_onboarding_1_description": "salinan luar tapak di awan atau di lokasi fizikal lain", + "backup_onboarding_2_description": "salinan tempatan pada peranti yang berbeza. Ini termasuk fail utama dan sandaran fail tersebut secara setempat.", + "backup_onboarding_3_description": "jumlah salinan data anda, termasuk fail asal. Ini termasuk 1 salinan luar tapak dan 2 salinan tempatan.", "backup_settings": "Tetapan Salinan Pangkalan Data", "backup_settings_description": "Urus tetapan salinan pangkalan data.", "cleared_jobs": "Kerja telah dibersihkan untuk: {job}", @@ -373,8 +379,6 @@ "admin_password": "Kata laluan Pentadbir", "administration": "Pentadbiran", "advanced": "Lanjutan", - "advanced_settings_beta_timeline_subtitle": "Cuba pengalaman aplikasi baharu", - "advanced_settings_beta_timeline_title": "Garis masa beta", "advanced_settings_enable_alternate_media_filter_subtitle": "Gunakan pilihan ini untuk menapis media semasa penyegerakan berdasarkan kriteria alternatif. Hanya cuba jika anda menghadapi masalah dengan aplikasi mengesan semua album.", "advanced_settings_enable_alternate_media_filter_title": "[EKSPERIMENTAL] Gunakan penapis penyelarasan album peranti alternatif", "advanced_settings_log_level_title": "Tahap log: {level}", diff --git a/i18n/nb_NO.json b/i18n/nb_NO.json index 37c5c3011e..4162170885 100644 --- a/i18n/nb_NO.json +++ b/i18n/nb_NO.json @@ -122,7 +122,14 @@ "library_watching_settings_description": "Se automatisk etter endrede filer", "logging_enable_description": "Aktiver logging", "logging_level_description": "Hvis aktivert, hvilket loggnivå som skal brukes.", - "logging_settings": "Logger", + "logging_settings": "Loggføring", + "machine_learning_availability_checks": "Tilgjengelighetssjekk", + "machine_learning_availability_checks_description": "Automatisk oppdag og velg tilgjengelige maskinlæring-servere", + "machine_learning_availability_checks_enabled": "Aktiver tilgjengelighetssjekk", + "machine_learning_availability_checks_interval": "Sjekkintervall", + "machine_learning_availability_checks_interval_description": "Interval i millisekunder mellom tilgjengelighetssjekk", + "machine_learning_availability_checks_timeout": "Forespørselstimeout", + "machine_learning_availability_checks_timeout_description": "Tidsavbrudd i millisekunder for tilgjengelighetssjekk", "machine_learning_clip_model": "Clip-modell", "machine_learning_clip_model_description": "Navnet på en CLIP-modell finnes her. Merk at du må kjøre 'Smart Søk'-jobben på nytt for alle bilder etter at du har endret modell.", "machine_learning_duplicate_detection": "Duplikatsøk", @@ -387,8 +394,6 @@ "admin_password": "Administrator Passord", "administration": "Administrasjon", "advanced": "Avansert", - "advanced_settings_beta_timeline_subtitle": "Prøv den nye app opplevelsen", - "advanced_settings_beta_timeline_title": "Beta tidslinje", "advanced_settings_enable_alternate_media_filter_subtitle": "Bruk denne innstillingen for å filtrere mediefiler under synkronisering basert på alternative kriterier. Bruk kun denne innstillingen dersom man opplever problemer med at applikasjonen ikke oppdager alle album.", "advanced_settings_enable_alternate_media_filter_title": "[EKSPERIMENTELT] Bruk alternativ enhet album synk filter", "advanced_settings_log_level_title": "Loggnivå: {level}", @@ -425,6 +430,7 @@ "album_remove_user_confirmation": "Er du sikker på at du vil fjerne {user}?", "album_search_not_found": "Ingen album ble funnet som traff ditt søk", "album_share_no_users": "Ser ut til at du har delt dette albumet med alle brukere, eller du ikke har noen brukere å dele det med.", + "album_summary": "Oppsummering av album", "album_updated": "Album oppdatert", "album_updated_setting_description": "Motta e-postvarsling når et delt album får nye filer", "album_user_left": "Forlot {album}", @@ -496,6 +502,8 @@ "asset_restored_successfully": "Objekt(er) gjenopprettet", "asset_skipped": "Hoppet over", "asset_skipped_in_trash": "I søppelbøtten", + "asset_trashed": "Objekt slettet", + "asset_troubleshoot": "Feilsøk objekt", "asset_uploaded": "Lastet opp", "asset_uploading": "Laster opp…", "asset_viewer_settings_subtitle": "Endre dine visningsinnstillinger for galleriet", @@ -529,8 +537,10 @@ "autoplay_slideshow": "Autoavspilling av lysbildefremvisning", "back": "Tilbake", "back_close_deselect": "Tilbake, lukk eller fjern merking", + "background_backup_running_error": "Bakgrunnsbackup kjører, kan ikke starte manuell backup", "background_location_permission": "Bakgrunnstillatelse for plassering", "background_location_permission_content": "For å bytte nettverk når du kjører i bakgrunnen, må Immich *alltid* ha presis posisjonstilgang slik at appen kan lese Wi-Fi-nettverkets navn", + "background_options": "Bakgrunnsinnstillinger", "backup": "Sikkerhetskopiering", "backup_album_selection_page_albums_device": "Album på enhet ({count})", "backup_album_selection_page_albums_tap": "Trykk for å inkludere, dobbelttrykk for å ekskludere", @@ -538,6 +548,7 @@ "backup_album_selection_page_select_albums": "Velg album", "backup_album_selection_page_selection_info": "Valginformasjon", "backup_album_selection_page_total_assets": "Totalt antall unike objekter", + "backup_albums_sync": "Synkronisering av sikkerhetskopialbum", "backup_all": "Alle", "backup_background_service_backup_failed_message": "Sikkerhetskopiering av objekter feilet. Prøver på nytt…", "backup_background_service_connection_failed_message": "Tilkobling til server feilet. Prøver på nytt…", @@ -654,6 +665,8 @@ "change_pin_code": "Endre PIN kode", "change_your_password": "Endre passordet ditt", "changed_visibility_successfully": "Endret synlighet vellykket", + "charging": "Lading", + "charging_requirement_mobile_backup": "Bakgrunnsbackup krever at enheten lader", "check_corrupt_asset_backup": "Sjekk etter korrupte backupobjekter", "check_corrupt_asset_backup_button": "Utfør sjekk", "check_corrupt_asset_backup_description": "Kjør denne sjekken kun over Wi-Fi og når alle objekter har blitt lastet opp. Denne sjekken kan ta noen minutter.", @@ -740,6 +753,7 @@ "create_user": "Opprett Bruker", "created": "Opprettet", "created_at": "Laget", + "creating_linked_albums": "Oppretter sammenkoblede albumer...", "crop": "Beskjær", "curated_object_page_title": "Ting", "current_device": "Nåværende enhet", @@ -889,7 +903,9 @@ "error": "Feil", "error_change_sort_album": "Feilet ved endring av sorteringsrekkefølge på albumer", "error_delete_face": "Feil ved sletting av ansikt fra aktivia", + "error_getting_places": "Feil ved henting av steder", "error_loading_image": "Feil ved lasting av bilde", + "error_loading_partners": "Feil ved lasting av partnere: {error}", "error_saving_image": "Feil: {error}", "error_tag_face_bounding_box": "Feil ved merking av ansikt - klarte ikke å få koordinatene på omrisset", "error_title": "Feil - Noe gikk galt", @@ -1054,6 +1070,7 @@ "favorites_page_no_favorites": "Ingen favorittobjekter funnet", "feature_photo_updated": "Fremhevet bilde oppdatert", "features": "Funksjoner", + "features_in_development": "Funksjoner under utvikling", "features_setting_description": "Administrerer funksjoner for appen", "file_name": "Filnavn", "file_name_or_extension": "Filnavn eller filtype", @@ -1218,6 +1235,7 @@ "local": "Lokal", "local_asset_cast_failed": "Kan ikke caste et bilde som ikke er lastet opp til serveren", "local_assets": "Lokale objekter", + "local_media_summary": "Oppsummering av lokale media", "local_network": "Lokalt nettverk", "local_network_sheet_info": "Appen vil koble til serveren via denne URL-en når du bruker det angitte Wi-Fi-nettverket", "location_permission": "Stedstillatelse", @@ -1229,6 +1247,7 @@ "location_picker_longitude_hint": "Skriv inn lengdegrad her", "lock": "Lås", "locked_folder": "Låst mappe", + "log_detail_title": "Loggdetaljer", "log_out": "Logg ut", "log_out_all_devices": "Logg ut fra alle enheter", "logged_in_as": "Logget inn som {user}", @@ -1259,6 +1278,7 @@ "login_password_changed_success": "Passord oppdatert", "logout_all_device_confirmation": "Er du sikker på at du vil logge ut av alle enheter?", "logout_this_device_confirmation": "Er du sikker på at du vil logge ut av denne enheten?", + "logs": "Logger", "longitude": "Lengdegrad", "look": "Se", "loop_videos": "Gjenta Videoer", @@ -1301,6 +1321,7 @@ "mark_as_read": "Merk som lest", "marked_all_as_read": "Merket alle som lest", "matches": "Samsvarende", + "matching_assets": "Matchende objekter", "media_type": "Mediatype", "memories": "Minner", "memories_all_caught_up": "Alt utført", @@ -1341,6 +1362,7 @@ "name_or_nickname": "Navn eller kallenavn", "network_requirement_photos_upload": "Bruk mobildata for backup av bilder", "network_requirement_videos_upload": "Bruk mobildata for backup av videoer", + "network_requirements": "Nettverkskrav", "network_requirements_updated": "Nettverkskrav endret, resetter backupkø", "networking_settings": "Nettverk", "networking_subtitle": "Administrer serverendepunkt-innstillinger", @@ -1351,6 +1373,7 @@ "new_person": "Ny person", "new_pin_code": "Ny PIN-kode", "new_pin_code_subtitle": "Dette er første gang du åpner den låste mappen. Lag en PIN-kode for å sikre tilgangen til denne siden", + "new_timeline": "Ny tidslinje", "new_user_created": "Ny bruker opprettet", "new_version_available": "NY VERSJON TILGJENGELIG", "newest_first": "Nyeste først", @@ -1364,20 +1387,25 @@ "no_assets_message": "KLIKK FOR Å LASTE OPP DITT FØRSTE BILDE", "no_assets_to_show": "Ingen objekter å vise", "no_cast_devices_found": "Ingen caste-enheter oppdaget", + "no_checksum_local": "Ingen sjekksum tilgjengelig - Kan ikke hente lokale objekter", + "no_checksum_remote": "Ingen sjekksum tilgjengelig - Kan ikke hente eksterne objekter", "no_duplicates_found": "Ingen duplikater ble funnet.", "no_exif_info_available": "Ingen EXIF-informasjon tilgjengelig", "no_explore_results_message": "Last opp flere bilder for å utforske samlingen din.", "no_favorites_message": "Legg til favoritter for å finne dine beste bilder og videoer raskt", "no_libraries_message": "Opprett et eksternt bibliotek for å se bildene og videoene dine", + "no_local_assets_found": "Ingen lokale objekter funnet med denne sjekksummen", "no_locked_photos_message": "Bilder og videoer i den låste mappen er skjult og vil ikke vises når du blar i biblioteket.", "no_name": "Ingen navn", "no_notifications": "Ingen varsler", "no_people_found": "Ingen samsvarende personer funnet", "no_places": "Ingen steder", + "no_remote_assets_found": "Ingen eksterne objekter funnet med denne sjekksummen", "no_results": "Ingen resultater", "no_results_description": "Prøv et synonym eller mer generelt søkeord", "no_shared_albums_message": "Opprett et album for å dele bilder og videoer med personer i nettverket ditt", "no_uploads_in_progress": "Ingen opplasting pågår", + "not_available": "Ikke tilgjengelig", "not_in_any_album": "Ikke i noe album", "not_selected": "Ikke valgt", "note_apply_storage_label_to_previously_uploaded assets": "Merk: For å bruke lagringsetiketten på tidligere opplastede filer, kjør", @@ -1499,6 +1527,7 @@ "port": "Port", "preferences_settings_subtitle": "Administrer appens preferanser", "preferences_settings_title": "Innstillinger", + "preparing": "Forbereder", "preset": "Forhåndsinstilling", "preview": "Forhåndsvis", "previous": "Forrige", @@ -1564,6 +1593,7 @@ "read_changelog": "Les endringslogg", "readonly_mode_disabled": "Skrivebeskyttet modus deaktivert", "readonly_mode_enabled": "Skrivebeskyttet modus aktivert", + "ready_for_upload": "Klar for opplasting", "reassign": "Tilordne på nytt", "reassigned_assets_to_existing_person": "Flyttet {count, plural, one {# objekt} other {# objekter}} to {name, select, null {en eksisterende person} other {{name}}}", "reassigned_assets_to_new_person": "Flyttet {count, plural, one {# objekt} other {# objekter}} til en ny person", @@ -1588,6 +1618,7 @@ "regenerating_thumbnails": "Regenererer miniatyrbilder", "remote": "Eksternt", "remote_assets": "Eksterne objekter", + "remote_media_summary": "Oppsummering av eksterne media", "remove": "Fjern", "remove_assets_album_confirmation": "Er du sikker på at du fil slette {count, plural, one {# objekt} other {# objekter}} fra albumet?", "remove_assets_shared_link_confirmation": "Er du sikker på at du vil slette {count, plural, one {# objekt} other {# objekter}} fra den delte lenken?", @@ -1863,6 +1894,7 @@ "show_slideshow_transition": "Vis overgang til lysbildefremvisning", "show_supporter_badge": "Supportermerke", "show_supporter_badge_description": "Vis et supportermerke", + "show_text_search_menu": "Vis tekstsøk meny", "shuffle": "Bland", "sidebar": "Sidefelt", "sidebar_display_description": "Vis en lenke for visningen i sidefeltet", @@ -1893,6 +1925,7 @@ "stacktrace": "Stakkspor", "start": "Start", "start_date": "Startdato", + "start_date_before_end_date": "Startdato må være før sluttdato", "state": "Fylke", "status": "Status", "stop_casting": "Stopp casting", @@ -2095,5 +2128,6 @@ "yes": "Ja", "you_dont_have_any_shared_links": "Du har ingen delte lenker", "your_wifi_name": "Ditt Wi-Fi-navn", - "zoom_image": "Zoom Bilde" + "zoom_image": "Zoom Bilde", + "zoom_to_bounds": "Zoom til grensene" } diff --git a/i18n/nl.json b/i18n/nl.json index cfd8ffca98..82846668d8 100644 --- a/i18n/nl.json +++ b/i18n/nl.json @@ -28,6 +28,7 @@ "add_to_album": "Aan album toevoegen", "add_to_album_bottom_sheet_added": "Toegevoegd aan {album}", "add_to_album_bottom_sheet_already_exists": "Staat al in {album}", + "add_to_album_bottom_sheet_some_local_assets": "Sommige lokale items konden niet aan album toegevoegd worden", "add_to_album_toggle": "Selectie inschakelen voor {album}", "add_to_albums": "Toevoegen aan albums", "add_to_albums_count": "Toevoegen aan albums ({count})", @@ -123,6 +124,13 @@ "logging_enable_description": "Logboek inschakelen", "logging_level_description": "Indien ingeschakeld, welk logniveau er wordt gebruikt.", "logging_settings": "Logging", + "machine_learning_availability_checks": "Beschikbaarheid", + "machine_learning_availability_checks_description": "Automatisch detecteren en selecteren van beschikbare machine learning servers", + "machine_learning_availability_checks_enabled": "Activeer beschikbaarheid controles", + "machine_learning_availability_checks_interval": "Controleinterval", + "machine_learning_availability_checks_interval_description": "Interval in milliseconden tussen beschikbaarheid checks", + "machine_learning_availability_checks_timeout": "Verzoek time-out", + "machine_learning_availability_checks_timeout_description": "Time-out in milliseconden voor beschikbaarheidschecks", "machine_learning_clip_model": "CLIP model", "machine_learning_clip_model_description": "De naam van een CLIP-model dat hier is vermeld. Let op: je moet de 'Slim Zoeken -taak opnieuw uitvoeren voor alle afbeeldingen wanneer je een model wijzigt.", "machine_learning_duplicate_detection": "Duplicaat detectie", @@ -387,8 +395,6 @@ "admin_password": "Beheerder wachtwoord", "administration": "Beheer", "advanced": "Geavanceerd", - "advanced_settings_beta_timeline_subtitle": "Probeer de nieuwe app-ervaring", - "advanced_settings_beta_timeline_title": "Beta tijdlijn", "advanced_settings_enable_alternate_media_filter_subtitle": "Gebruik deze optie om media te filteren tijdens de synchronisatie op basis van alternatieve criteria. Gebruik dit enkel als de app problemen heeft met het detecteren van albums.", "advanced_settings_enable_alternate_media_filter_title": "[EXPERIMENTEEL] Gebruik een alternatieve album synchronisatie filter", "advanced_settings_log_level_title": "Logniveau: {level}", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "Weet je zeker dat je {user} wilt verwijderen?", "album_search_not_found": "Geen albums gevonden die aan je zoekopdracht voldoen", "album_share_no_users": "Het lijkt erop dat je dit album met alle gebruikers hebt gedeeld, of dat je geen gebruikers hebt om mee te delen.", + "album_summary": "Album samenvatting", "album_updated": "Album bijgewerkt", "album_updated_setting_description": "Ontvang een e-mailmelding wanneer een gedeeld album nieuwe items heeft", "album_user_left": "{album} verlaten", @@ -496,6 +503,8 @@ "asset_restored_successfully": "Item succesvol hersteld", "asset_skipped": "Overgeslagen", "asset_skipped_in_trash": "In prullenbak", + "asset_trashed": "Asset verwijderd", + "asset_troubleshoot": "Asset probleemoplossing", "asset_uploaded": "Geüpload", "asset_uploading": "Uploaden…", "asset_viewer_settings_subtitle": "Beheer je instellingen voor galerijweergave", @@ -529,8 +538,10 @@ "autoplay_slideshow": "Diavoorstelling automatisch afspelen", "back": "Terug", "back_close_deselect": "Terug, sluiten of deselecteren", + "background_backup_running_error": "Achtergrond backup draait, handmatige backup kan niet worden gestart", "background_location_permission": "Achtergrond locatie toestemming", "background_location_permission_content": "Om van netwerk te wisselen terwijl de app op de achtergrond draait, heeft Immich *altijd* toegang tot de exacte locatie nodig om de naam van het WiFi-netwerk te kunnen lezen", + "background_options": "Achtergrond opties", "backup": "Back-up", "backup_album_selection_page_albums_device": "Albums op apparaat ({count})", "backup_album_selection_page_albums_tap": "Tik om op te nemen, dubbel tik om uit te sluiten", @@ -538,6 +549,7 @@ "backup_album_selection_page_select_albums": "Selecteer albums", "backup_album_selection_page_selection_info": "Selectie info", "backup_album_selection_page_total_assets": "Totaal unieke items", + "backup_albums_sync": "Backup albums synchronisatie", "backup_all": "Alle", "backup_background_service_backup_failed_message": "Fout bij het back-uppen van de items. Opnieuw proberen…", "backup_background_service_connection_failed_message": "Fout bij het verbinden met de server. Opnieuw proberen…", @@ -654,6 +666,8 @@ "change_pin_code": "Wijzig PIN code", "change_your_password": "Wijzig je wachtwoord", "changed_visibility_successfully": "Zichtbaarheid succesvol gewijzigd", + "charging": "Opladen", + "charging_requirement_mobile_backup": "Achtergrond backup vereist dat het apparaat wordt opgeladen", "check_corrupt_asset_backup": "Controleer op corrupte back-ups van items", "check_corrupt_asset_backup_button": "Controle uitvoeren", "check_corrupt_asset_backup_description": "Voer deze controle alleen uit via WiFi en nadat alle items zijn geback-upt. De procedure kan een paar minuten duren.", @@ -740,6 +754,7 @@ "create_user": "Gebruiker aanmaken", "created": "Aangemaakt", "created_at": "Aangemaakt", + "creating_linked_albums": "Gekoppelde albums worden aangemaakt...", "crop": "Bijsnijden", "curated_object_page_title": "Dingen", "current_device": "Huidig apparaat", @@ -835,7 +850,7 @@ "download_sucess_android": "Het bestand is gedownload naar DCIM/Immich", "download_waiting_to_retry": "Wachten om opnieuw te proberen", "downloading": "Downloaden", - "downloading_asset_filename": "Downloading asset {filename}", + "downloading_asset_filename": "Downloaden asset {filename}", "downloading_media": "Media aan het downloaden", "drop_files_to_upload": "Zet bestanden ergens neer om ze te uploaden", "duplicates": "Duplicaten", @@ -889,7 +904,9 @@ "error": "Fout", "error_change_sort_album": "Sorteervolgorde van album wijzigen mislukt", "error_delete_face": "Fout bij verwijderen van gezicht uit het item", + "error_getting_places": "Fout bij ophalen plaatsen", "error_loading_image": "Fout bij laden afbeelding", + "error_loading_partners": "Fout bij ophalen partners: {error}", "error_saving_image": "Fout: {error}", "error_tag_face_bounding_box": "Fout bij taggen van gezicht - kan coördinaten van omvattend kader niet ophalen", "error_title": "Fout - Er is iets misgegaan", @@ -1054,6 +1071,7 @@ "favorites_page_no_favorites": "Geen favoriete items gevonden", "feature_photo_updated": "Uitgelichte afbeelding bijgewerkt", "features": "Functies", + "features_in_development": "Functies in ontwikkeling", "features_setting_description": "Beheer de app functies", "file_name": "Bestandsnaam", "file_name_or_extension": "Bestandsnaam of extensie", @@ -1218,6 +1236,7 @@ "local": "Lokaal", "local_asset_cast_failed": "Kan geen item casten die nog niet geüpload is naar de server", "local_assets": "Lokale Items", + "local_media_summary": "Lokale media samenvatting", "local_network": "Lokaal netwerk", "local_network_sheet_info": "De app maakt verbinding met de server via deze URL wanneer het opgegeven WiFi-netwerk wordt gebruikt", "location_permission": "Locatietoestemming", @@ -1229,6 +1248,7 @@ "location_picker_longitude_hint": "Voer hier je lengtegraad in", "lock": "Vergrendel", "locked_folder": "Vergrendelde map", + "log_detail_title": "Log details", "log_out": "Uitloggen", "log_out_all_devices": "Uitloggen op alle apparaten", "logged_in_as": "Ingelogd als {user}", @@ -1259,6 +1279,7 @@ "login_password_changed_success": "Wachtwoord succesvol bijgewerkt", "logout_all_device_confirmation": "Weet je zeker dat je wilt uitloggen op alle apparaten?", "logout_this_device_confirmation": "Weet je zeker dat je wilt uitloggen op dit apparaat?", + "logs": "Logs", "longitude": "Lengtegraad", "look": "Uiterlijk", "loop_videos": "Video's herhalen", @@ -1301,6 +1322,7 @@ "mark_as_read": "Markeren als gelezen", "marked_all_as_read": "Allen gemarkeerd als gelezen", "matches": "Overeenkomsten", + "matching_assets": "Overeenkomende assets", "media_type": "Mediatype", "memories": "Herinneringen", "memories_all_caught_up": "Je bent helemaal bij", @@ -1341,6 +1363,7 @@ "name_or_nickname": "Naam of gebruikersnaam", "network_requirement_photos_upload": "Gebruik mobiele data voor de backup van foto's", "network_requirement_videos_upload": "Gebruik mobiele data voor de backups van video's", + "network_requirements": "Netwerk vereisten", "network_requirements_updated": "Netwerkeisen zijn gewijzigd, back-upwachtrij wordt opnieuw ingesteld", "networking_settings": "Netwerk", "networking_subtitle": "Beheer de instellingen voor de server-URL", @@ -1351,6 +1374,7 @@ "new_person": "Nieuw persoon", "new_pin_code": "Nieuwe PIN code", "new_pin_code_subtitle": "Dit is de eerste keer dat u de vergrendelde map opent. Stel een pincode in om deze pagina veilig te openen", + "new_timeline": "Nieuwe tijdlijn", "new_user_created": "Nieuwe gebruiker aangemaakt", "new_version_available": "NIEUWE VERSIE BESCHIKBAAR", "newest_first": "Nieuwste eerst", @@ -1364,20 +1388,25 @@ "no_assets_message": "KLIK HIER OM JE EERSTE FOTO TE UPLOADEN", "no_assets_to_show": "Geen foto's om te laten zien", "no_cast_devices_found": "Geen cast-apparaten gevonden", + "no_checksum_local": "Geen checksum beschikbaar - kan lokale assets niet ophalen", + "no_checksum_remote": "Geen checksum beschikbaar - kan online assets niet ophalen", "no_duplicates_found": "Er zijn geen duplicaten gevonden.", "no_exif_info_available": "Geen exif info beschikbaar", "no_explore_results_message": "Upload meer foto's om je verzameling te verkennen.", "no_favorites_message": "Voeg favorieten toe om snel je beste foto's en video's te vinden", "no_libraries_message": "Maak een externe bibliotheek om je foto's en video's te bekijken", + "no_local_assets_found": "Geen lokale assets gevonden met deze checksum", "no_locked_photos_message": "Foto’s en video’s in de vergrendelde map zijn verborgen en worden niet weergegeven wanneer je door je bibliotheek bladert of zoekt.", "no_name": "Geen naam", "no_notifications": "Geen meldingen", "no_people_found": "Geen mensen gevonden", "no_places": "Geen plaatsen", + "no_remote_assets_found": "Geen online assets gevonden met deze checksum", "no_results": "Geen resultaten", "no_results_description": "Probeer een synoniem of een algemener zoekwoord", "no_shared_albums_message": "Maak een album om foto's en video's te delen met mensen in je netwerk", "no_uploads_in_progress": "Geen uploads bezig", + "not_available": "N.B.", "not_in_any_album": "Niet in een album", "not_selected": "Niet geselecteerd", "note_apply_storage_label_to_previously_uploaded assets": "Opmerking: om het opslaglabel toe te passen op eerder geüploade items, voer de volgende taak uit", @@ -1499,6 +1528,7 @@ "port": "Poort", "preferences_settings_subtitle": "Beheer de voorkeuren van de app", "preferences_settings_title": "Voorkeuren", + "preparing": "Voorbereiden", "preset": "Voorinstelling", "preview": "Voorbeeld", "previous": "Vorige", @@ -1564,6 +1594,7 @@ "read_changelog": "Lees wijzigingen", "readonly_mode_disabled": "Alleen-lezen modus uitgeschakeld", "readonly_mode_enabled": "Alleen-lezen modus ingeschakeld", + "ready_for_upload": "Klaar voor upload", "reassign": "Opnieuw toewijzen", "reassigned_assets_to_existing_person": "{count, plural, one {# item} other {# items}} opnieuw toegewezen aan {name, select, null {een bestaand persoon} other {{name}}}", "reassigned_assets_to_new_person": "{count, plural, one {# item} other {# items}} opnieuw toegewezen aan een nieuw persoon", @@ -1588,6 +1619,7 @@ "regenerating_thumbnails": "Thumbnails opnieuw aan het genereren", "remote": "Externe", "remote_assets": "Externe Items", + "remote_media_summary": "Online media samenvatting", "remove": "Verwijderen", "remove_assets_album_confirmation": "Weet je zeker dat je {count, plural, one {# item} other {# items}} uit het album wilt verwijderen?", "remove_assets_shared_link_confirmation": "Weet je zeker dat je {count, plural, one {# item} other {# items}} uit deze gedeelde link wilt verwijderen?", @@ -1863,6 +1895,7 @@ "show_slideshow_transition": "Diavoorstellingsovergang tonen", "show_supporter_badge": "Supportersbadge", "show_supporter_badge_description": "Toon een supportersbadge", + "show_text_search_menu": "Laat tekst zoek menu zien", "shuffle": "Willekeurig", "sidebar": "Zijbalk", "sidebar_display_description": "Toon een link naar deze pagina in de zijbalk", @@ -1893,6 +1926,7 @@ "stacktrace": "Stacktrace", "start": "Start", "start_date": "Startdatum", + "start_date_before_end_date": "Startdatum moet voor einddatum liggen", "state": "Staat", "status": "Status", "stop_casting": "Stop met casten", @@ -2073,14 +2107,14 @@ "view_link": "Bekijk link", "view_links": "Links bekijken", "view_name": "Bekijken", - "view_next_asset": "Bekijk volgende item", - "view_previous_asset": "Bekijk vorige item", + "view_next_asset": "Bekijk volgend item", + "view_previous_asset": "Bekijk vorig item", "view_qr_code": "QR-code bekijken", "view_similar_photos": "Bekijk vergelijkbare foto's", "view_stack": "Bekijk stapel", "view_user": "Bekijk gebruiker", - "viewer_remove_from_stack": "Verwijder van Stapel", - "viewer_stack_use_as_main_asset": "Gebruik als Hoofd Item", + "viewer_remove_from_stack": "Verwijder van stapel", + "viewer_stack_use_as_main_asset": "Zet bovenaan de stapel", "viewer_unstack": "Ontstapel", "visibility_changed": "Zichtbaarheid gewijzigd voor {count, plural, one {# persoon} other {# mensen}}", "waiting": "Wachtend", @@ -2095,5 +2129,6 @@ "yes": "Ja", "you_dont_have_any_shared_links": "Je hebt geen gedeelde links", "your_wifi_name": "Je WiFi-naam", - "zoom_image": "Inzoomen" + "zoom_image": "Inzoomen", + "zoom_to_bounds": "Zoom naar randen" } diff --git a/i18n/nn.json b/i18n/nn.json index 01f76f528b..7b2f256c94 100644 --- a/i18n/nn.json +++ b/i18n/nn.json @@ -28,6 +28,8 @@ "add_to_album": "Legg til i album", "add_to_album_bottom_sheet_added": "Lagt til i {album}", "add_to_album_bottom_sheet_already_exists": "Allereie i {album}", + "add_to_albums": "Legg til i album", + "add_to_albums_count": "Legg til i album ({count})", "add_to_shared_album": "Legg til i delt album", "add_url": "Legg til URL", "added_to_archive": "Lagt til i arkiv", @@ -45,6 +47,7 @@ "backup_database": "Lag tryggingskopi av database", "backup_database_enable_description": "Aktiver tryggingskopiering av database", "backup_keep_last_amount": "Antal tryggingskopiar å behalde", + "backup_onboarding_1_description": "sikkerheitskopi i skya eller på eit anna fysisk sted.", "backup_onboarding_2_description": "lokale kopiar på andre einingar. Dette inkluderer hovudfilene og backup av desse filene lokalt.", "backup_onboarding_3_description": "fullstendige kopiar av dine data, inkludert originalfilene. Dette inkluderer 1 utomhus kopi og 2 lokale kopiar.", "backup_onboarding_description": "Ein 3-2-1 backup-strategi tilrådast for å verne dataa dine. Du bør ha kopiar av dei opplasta bileta/videoane dine samt Immich-databasen, slik at du har ei fleirdelt backup-løysing.", @@ -78,6 +81,7 @@ "image_format_description": "WebP gjev mindre filstorleik enn JPEG, men er treigare å lage.", "image_fullsize_description": "Bilete i full storleik utan metadata, i bruk når zooma inn", "image_fullsize_enabled": "Skru på generering av bilete i full storleik", + "image_fullsize_enabled_description": "Generer bilete i full storleik for ikkje web-tilpassa formatar. Når \"Foretrekk", "image_fullsize_quality_description": "Kvalitet på bilete i full storleik frå 1-100. Høgare er betre, men gjev større filer.", "image_fullsize_title": "Innstillingar for bilete i full storleik", "image_prefer_embedded_preview": "Bruk helst innebygd førehandsvisning", @@ -118,6 +122,9 @@ "logging_enable_description": "Aktiver loggføring", "logging_level_description": "Når aktivert, kva loggnivå å bruke.", "logging_settings": "Logging", + "machine_learning_availability_checks_description": "Automatiser oppdaging og prioritet av tilgjengelege maskinlærings-serverar", + "machine_learning_availability_checks_interval": "Sjekk intervall", + "machine_learning_availability_checks_timeout_description": "Utløpstid i millisekund for tilgjengelegheitssjekk", "machine_learning_clip_model": "CLIP modell", "machine_learning_clip_model_description": "Namnet på ein CLIP modell finst her. Merk at du må køyre 'Smart Søk'-jobben på nytt for alle bilete etter du har forandra modell.", "machine_learning_duplicate_detection": "Duplikatdeteksjon", @@ -139,6 +146,7 @@ "machine_learning_min_detection_score": "Minimum deteksjonsresultat", "machine_learning_min_detection_score_description": "Minimum tillitspoeng for at eit ansikt skal bli oppdaga, på ein skala frå 0 til 1. Lågare verdiar vil oppdage fleire ansikt, men kan føre til feilaktige treff.", "machine_learning_min_recognized_faces": "Minimum gjenkjende ansikt", + "machine_learning_min_recognized_faces_description": "Minste tal på gjenkjende fjes for å opprette ein person. Aukar ein dette, vert ansiktsgjenkjenninga meir presis, på bekostning av auka sjanse for at ansikt ikkje vert tileigna ein person.", "machine_learning_settings": "Innstillingar for maskinlæring", "machine_learning_settings_description": "Administrer maskinlæringsfunksjonar og innstillingar", "machine_learning_smart_search": "Smart Søk", @@ -154,6 +162,7 @@ "map_settings": "Kart", "map_settings_description": "Endre kartinnstillingar", "map_style_description": "URL til eit style.json-karttema", + "memory_generate_job": "Minne-generering", "metadata_extraction_job": "Hent ut metadata", "metadata_extraction_job_description": "Hent ut metadata frå kvart bilete, slik som GPS, ansikt og oppløysing", "metadata_faces_import_setting": "Skru på import av ansikt", @@ -161,6 +170,17 @@ "metadata_settings": "Metadata Innstillinger", "metadata_settings_description": "Endre metadata-innstillingar", "migration_job": "Migrasjon", + "migration_job_description": "Overfør miniatyrbilete for bilete og ansikt til den nyaste mappestrukturen", + "nightly_tasks_cluster_faces_setting_description": "Køyr ansiktsgjenkjenning på nyleg identifiserte ansikt", + "nightly_tasks_database_cleanup_setting_description": "Fjern gamal, utgått data frå databasen", + "nightly_tasks_generate_memories_setting": "Generer minner", + "nightly_tasks_generate_memories_setting_description": "Lag nye minner frå bilete", + "nightly_tasks_missing_thumbnails_setting": "Generer manglande miniatyrbilete", + "nightly_tasks_missing_thumbnails_setting_description": "Set bilete utan miniatyrbilete i kø for generering av miniatyrbilete", + "nightly_tasks_settings": "Innstillingar for nattlege jobbar", + "nightly_tasks_settings_description": "Handsam nattlege jobbar", + "nightly_tasks_start_time_setting": "Starttid", + "nightly_tasks_start_time_setting_description": "Tidspunktet serveren køyrer nattlege jobbar", "notification_email_from_address": "Frå adresse", "notification_email_test_email_failed": "Mislukka sending av test-e-post, sjekk konfigurasjonen din", "notification_email_test_email_sent": "Det vart sendt ei test-melding til {email}. Sjekk e-posten din.", diff --git a/i18n/pl.json b/i18n/pl.json index dd0ba8cd4d..f2016bd1ce 100644 --- a/i18n/pl.json +++ b/i18n/pl.json @@ -28,6 +28,7 @@ "add_to_album": "Dodaj do albumu", "add_to_album_bottom_sheet_added": "Dodano do {album}", "add_to_album_bottom_sheet_already_exists": "Już jest w {album}", + "add_to_album_bottom_sheet_some_local_assets": "Niektóre lokalne zasoby nie mogły zostać dodane do albumu", "add_to_album_toggle": "Przełącz wybieranie dla {album}", "add_to_albums": "Dodaj do albumów", "add_to_albums_count": "Dodaj do albumów ({count})", @@ -123,6 +124,13 @@ "logging_enable_description": "Uruchom zapisywanie logów", "logging_level_description": "Kiedy włączone, jakiego poziomu użyć.", "logging_settings": "Rejestrowanie logów", + "machine_learning_availability_checks": "Sprawdzanie dostępności", + "machine_learning_availability_checks_description": "Automatyczne wykrywaj i preferuj dostępne serwery uczenia maszynowego", + "machine_learning_availability_checks_enabled": "Włącz sprawdzanie dostępności", + "machine_learning_availability_checks_interval": "Częstotliwość sprawdzania", + "machine_learning_availability_checks_interval_description": "Odstęp czasu w milisekundach między sprawdzeniami dostępności", + "machine_learning_availability_checks_timeout": "Upłynął czas żądania", + "machine_learning_availability_checks_timeout_description": "Limit czasu żądania w milisekundach dla sprawdzania dostępności", "machine_learning_clip_model": "Model CLIP", "machine_learning_clip_model_description": "Nazwa modelu CLIP jest wymieniona tutaj. Zwróć uwagę, że po zmianie modelu musisz ponownie uruchomić zadanie 'Smart Search' dla wszystkich obrazów.", "machine_learning_duplicate_detection": "Wykrywanie Duplikatów", @@ -233,7 +241,7 @@ "oauth_storage_quota_default": "Domyślna ilość miejsca w magazynie (GiB)", "oauth_storage_quota_default_description": "Limit w GiB do wykorzystania, gdy nie podano żadnej wartości.", "oauth_timeout": "Upłynął czas żądania", - "oauth_timeout_description": "Limit czasu żądania (w milisekundach)", + "oauth_timeout_description": "Limit czasu żądania w milisekundach", "password_enable_description": "Zaloguj używając e-mail i hasła", "password_settings": "Logowanie Hasłem", "password_settings_description": "Zarządzaj ustawieniami logowania hasłem", @@ -387,8 +395,6 @@ "admin_password": "Hasło Administratora", "administration": "Administracja", "advanced": "Zaawansowane", - "advanced_settings_beta_timeline_subtitle": "Wypróbuj nową funkcjonalność aplikacji", - "advanced_settings_beta_timeline_title": "Beta-Timeline", "advanced_settings_enable_alternate_media_filter_subtitle": "Użyj tej opcji do filtrowania mediów podczas synchronizacji alternatywnych kryteriów. Używaj tylko wtedy gdy aplikacja ma problemy z wykrywaniem wszystkich albumów.", "advanced_settings_enable_alternate_media_filter_title": "[EKSPERYMENTALNE] Użyj alternatywnego filtra synchronizacji albumu", "advanced_settings_log_level_title": "Poziom szczegółowości dziennika: {level}", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "Na pewno chcesz usunąć {user}?", "album_search_not_found": "Nie znaleziono albumów pasujących do Twojego wyszukiwania", "album_share_no_users": "Wygląda na to, że ten album albo udostępniono wszystkim użytkownikom, albo nie ma komu go udostępnić.", + "album_summary": "Podsumowanie albumu", "album_updated": "Album zaktualizowany", "album_updated_setting_description": "Otrzymaj powiadomienie e-mail, gdy do udostępnionego Ci albumu zostaną dodane nowe zasoby", "album_user_left": "Opuszczono {album}", @@ -496,6 +503,8 @@ "asset_restored_successfully": "Zasób został pomyślnie przywrócony", "asset_skipped": "Pominięto", "asset_skipped_in_trash": "W koszu", + "asset_trashed": "Zasób wrzucono do kosza", + "asset_troubleshoot": "Rozwiązywanie problemów z zasobami", "asset_uploaded": "Przesłano", "asset_uploading": "Przesyłanie…", "asset_viewer_settings_subtitle": "Zarządzaj ustawieniami przeglądarki galerii", @@ -529,8 +538,10 @@ "autoplay_slideshow": "Automatyczne odtwarzanie pokazu slajdów", "back": "Wstecz", "back_close_deselect": "Wróć, zamknij lub odznacz", + "background_backup_running_error": "Tworzenie kopii zapasowej w tle jest obecnie w toku, nie można rozpocząć ręcznego tworzenia kopii zapasowej", "background_location_permission": "Uprawnienia do lokalizacji w tle", "background_location_permission_content": "Aby móc przełączać sieć podczas pracy w tle, Immich musi *zawsze* mieć dostęp do dokładnej lokalizacji, aby aplikacja mogła odczytać nazwę sieci Wi-Fi", + "background_options": "Opcje w tle", "backup": "Kopia zapasowa", "backup_album_selection_page_albums_device": "Albumy na urządzeniu ({count})", "backup_album_selection_page_albums_tap": "Stuknij, aby włączyć, stuknij dwukrotnie, aby wykluczyć", @@ -538,6 +549,7 @@ "backup_album_selection_page_select_albums": "Wybierz albumy", "backup_album_selection_page_selection_info": "Info o wyborze", "backup_album_selection_page_total_assets": "Łącznie unikalnych plików", + "backup_albums_sync": "Synchronizacja kopii zapasowych albumów", "backup_all": "Wszystkie", "backup_background_service_backup_failed_message": "Nie udało się wykonać kopii zapasowej zasobów. Ponowna próba…", "backup_background_service_connection_failed_message": "Nie udało się połączyć z serwerem. Ponowna próba…", @@ -654,6 +666,8 @@ "change_pin_code": "Zmień kod PIN", "change_your_password": "Zmień swoje hasło", "changed_visibility_successfully": "Pomyślnie zmieniono widoczność", + "charging": "Ładowanie", + "charging_requirement_mobile_backup": "Tworzenie kopii zapasowej w tle wymaga by urządzenie było podłączone do ładowania", "check_corrupt_asset_backup": "Sprawdź, czy kopie zapasowe zasobów nie są uszkodzone", "check_corrupt_asset_backup_button": "Wykonaj sprawdzenie", "check_corrupt_asset_backup_description": "Uruchom sprawdzenie tylko przez Wi-Fi i po utworzeniu kopii zapasowej wszystkich zasobów. Procedura może potrwać kilka minut.", @@ -740,6 +754,7 @@ "create_user": "Stwórz użytkownika", "created": "Utworzono", "created_at": "Utworzony", + "creating_linked_albums": "Tworzenie połączonych albumów...", "crop": "Przytnij", "curated_object_page_title": "Rzeczy", "current_device": "Obecne urządzenie", @@ -888,8 +903,10 @@ "enter_your_pin_code_subtitle": "Wprowadź twój kod PIN, aby uzyskać dostęp do folderu zablokowanego", "error": "Błąd", "error_change_sort_album": "Nie udało się zmienić kolejności sortowania albumów", - "error_delete_face": "Wystąpił błąd podczas usuwania twarzy z zasobów", + "error_delete_face": "Błąd podczas usuwania twarzy z zasobów", + "error_getting_places": "Błąd podczas pozyskiwania lokalizacji", "error_loading_image": "Błąd podczas ładowania zdjęcia", + "error_loading_partners": "Błąd podczas ładowania partnerów: {error}", "error_saving_image": "Błąd: {error}", "error_tag_face_bounding_box": "Błąd przy dodawaniu etykiety dla tej twarzy - nie może uzyskać współrzędnych granicznych", "error_title": "Błąd - Coś poszło nie tak", @@ -1054,6 +1071,7 @@ "favorites_page_no_favorites": "Nie znaleziono ulubionych zasobów", "feature_photo_updated": "Zdjęcie główne zaktualizowane pomyślnie", "features": "Funkcje", + "features_in_development": "Funkcje w fazie rozwoju", "features_setting_description": "Zarządzaj funkcjami aplikacji", "file_name": "Nazwa pliku", "file_name_or_extension": "Nazwie lub rozszerzeniu pliku", @@ -1218,6 +1236,7 @@ "local": "Lokalny", "local_asset_cast_failed": "Nie można strumieniować zasobu, który nie został przesłany na serwer", "local_assets": "Zasoby lokalne", + "local_media_summary": "Podsumowanie lokalnych mediów", "local_network": "Sieć lokalna", "local_network_sheet_info": "Aplikacja połączy się z serwerem za pośrednictwem tego adresu URL podczas korzystania z określonej sieci Wi-Fi", "location_permission": "Zezwolenie na lokalizację", @@ -1229,6 +1248,7 @@ "location_picker_longitude_hint": "Wpisz tutaj swoją długość geograficzną", "lock": "Zablokuj", "locked_folder": "Folder zablokowany", + "log_detail_title": "Szczegóły dziennika", "log_out": "Wyloguj", "log_out_all_devices": "Wyloguj ze Wszystkich Urządzeń", "logged_in_as": "Zalogowano jako {user}", @@ -1259,6 +1279,7 @@ "login_password_changed_success": "Hasło zostało zmienione", "logout_all_device_confirmation": "Czy na pewno chcesz wylogować się ze wszystkich urządzeń?", "logout_this_device_confirmation": "Czy na pewno chcesz wylogować to urządzenie?", + "logs": "Logi", "longitude": "Długość geograficzna", "look": "Wygląd", "loop_videos": "Powtarzaj filmy", @@ -1301,6 +1322,7 @@ "mark_as_read": "Zaznacz jako odczytane", "marked_all_as_read": "Zaznaczono wszystkie jako przeczytane", "matches": "Powiązania", + "matching_assets": "Pasujące zasoby", "media_type": "Typ zasobu", "memories": "Wspomnienia", "memories_all_caught_up": "Wszystko złapane", @@ -1341,6 +1363,7 @@ "name_or_nickname": "Nazwa lub pseudonim", "network_requirement_photos_upload": "Używaj danych komórkowych do tworzenia kopii zapasowych zdjęć", "network_requirement_videos_upload": "Używaj danych komórkowych do tworzenia kopii zapasowych filmów", + "network_requirements": "Wymagania sieciowe", "network_requirements_updated": "Zmieniono wymagania sieciowe, resetowanie kolejki kopii zapasowych", "networking_settings": "Sieć", "networking_subtitle": "Zarządzaj ustawieniami punktu końcowego serwera", @@ -1351,6 +1374,7 @@ "new_person": "Nowa osoba", "new_pin_code": "Nowy kod PIN", "new_pin_code_subtitle": "Jest to pierwszy raz, kiedy wchodzisz do folderu zablokowanego. Utwórz kod PIN, aby bezpiecznie korzystać z tej strony", + "new_timeline": "Nowa oś czasu", "new_user_created": "Pomyślnie stworzono nowego użytkownika", "new_version_available": "NOWA WERSJA DOSTĘPNA", "newest_first": "Od najnowszych", @@ -1364,20 +1388,25 @@ "no_assets_message": "KLIKNIJ, ABY WYSŁAĆ PIERWSZE ZDJĘCIE", "no_assets_to_show": "Brak zasobów do pokazania", "no_cast_devices_found": "Nie znaleziono urządzeń do przesyłania strumieniowego", + "no_checksum_local": "Brak sumy kontrolnej - nie można pobrać lokalnych zasobów", + "no_checksum_remote": "Brak sumy kontrolnej - nie można pobrać zdalnego zasobu", "no_duplicates_found": "Nie znaleziono duplikatów.", "no_exif_info_available": "Nie znaleziono informacji exif", "no_explore_results_message": "Prześlij więcej zdjęć, aby przeglądać swój zbiór.", "no_favorites_message": "Dodaj ulubione aby szybko znaleźć swoje najlepsze zdjęcia i filmy", "no_libraries_message": "Stwórz bibliotekę zewnętrzną, aby przeglądać swoje zdjęcia i filmy", + "no_local_assets_found": "Nie znaleziono żadnych lokalnych zasobów o tej sumie kontrolnej", "no_locked_photos_message": "Zdjęcia i filmy w folderze zablokowanym są ukryte i nie będą wyświetlane podczas przeglądania biblioteki.", "no_name": "Brak Nazwy", "no_notifications": "Brak powiadomień", "no_people_found": "Brak pasujących osób", "no_places": "Brak miejsc", + "no_remote_assets_found": "Nie znaleziono żadnych zdalnych zasobów o tej sumie kontrolnej", "no_results": "Brak wyników", "no_results_description": "Spróbuj użyć synonimu lub bardziej ogólnego słowa kluczowego", "no_shared_albums_message": "Stwórz album aby udostępnić zdjęcia i filmy osobom w Twojej sieci", "no_uploads_in_progress": "Brak przesyłań w toku", + "not_available": "Nie dotyczy", "not_in_any_album": "Bez albumu", "not_selected": "Nie wybrano", "note_apply_storage_label_to_previously_uploaded assets": "Uwaga: Aby przypisać etykietę magazynowania do wcześniej przesłanych zasobów, uruchom", @@ -1499,6 +1528,7 @@ "port": "Port", "preferences_settings_subtitle": "Zarządzaj preferencjami aplikacji", "preferences_settings_title": "Ustawienia", + "preparing": "Przygotowywanie", "preset": "Ustawienie", "preview": "Podgląd", "previous": "Poprzedni", @@ -1564,6 +1594,7 @@ "read_changelog": "Zobacz Zmiany", "readonly_mode_disabled": "Tryb tylko do odczytu wyłączony", "readonly_mode_enabled": "Tryb tylko do odczytu włączony", + "ready_for_upload": "Gotowe do przesłania", "reassign": "Przypisz ponownie", "reassigned_assets_to_existing_person": "Przypisano ponownie {count, plural, one {# zasób} other {# zasobów}} do {name, select, null {istniejącej osoby} other {{name}}}", "reassigned_assets_to_new_person": "Przypisano ponownie {count, plural, one {# zasób} other {# zasobów}} do nowej osoby", @@ -1588,6 +1619,7 @@ "regenerating_thumbnails": "Regenerowanie miniatur", "remote": "Zdalny", "remote_assets": "Zasoby zdalne", + "remote_media_summary": "Podsumowanie mediów zdalnych", "remove": "Usuń", "remove_assets_album_confirmation": "Czy na pewno chcesz usunąć {count, plural, one {# zasób} few {# zasoby} other {# zasobów}} z albumu?", "remove_assets_shared_link_confirmation": "Czy na pewno chcesz usunąć {count, plural, one {# zasób} other {# zasoby}} z tego udostępnionego linku?", @@ -1601,8 +1633,8 @@ "remove_from_locked_folder": "Usuń z folderu zablokowanego", "remove_from_locked_folder_confirmation": "Czy na pewno chcesz przenieść te zdjęcia i filmy z folderu zablokowanego? Będą one widoczne w bibliotece.", "remove_from_shared_link": "Usuń z udostępnionego linku", - "remove_memory": "Usuń pamięć", - "remove_photo_from_memory": "Usuń zdjęcia z tej pamięci", + "remove_memory": "Usuń wspomnienie", + "remove_photo_from_memory": "Usuń zdjęcia z tych wspomnień", "remove_tag": "Usuń tag", "remove_url": "Usuń URL", "remove_user": "Usuń użytkownika", @@ -1610,15 +1642,15 @@ "removed_from_archive": "Usunięto z archiwum", "removed_from_favorites": "Usunięto z ulubionych", "removed_from_favorites_count": "{count, plural, other {Usunięto #}} z ulubionych", - "removed_memory": "Pamięć została usunięta", - "removed_photo_from_memory": "Usunięto zdjęcie z pamięci", + "removed_memory": "Wspomnienie usunięte", + "removed_photo_from_memory": "Usunięto zdjęcie ze wspomnień", "removed_tagged_assets": "Usunięto etykietę z {count, plural, one {# zasobu} other {# zasobów}}", "rename": "Zmień nazwę", "repair": "Napraw", "repair_no_results_message": "Tutaj pojawią się nieśledzone i brakujące pliki", "replace_with_upload": "Prześlij nową wersję", "repository": "Repozytorium", - "require_password": "Wymagaj hasło", + "require_password": "Wymagaj hasła", "require_user_to_change_password_on_first_login": "Zmuś użytkownika do zmiany hasła podczas następnego logowania", "rescan": "Ponowne skanowanie", "reset": "Reset", @@ -1663,7 +1695,7 @@ "search_albums": "Przeszukaj albumy", "search_by_context": "Wyszukaj według treści", "search_by_description": "Wyszukaj według opisu", - "search_by_description_example": "Jednodniowa wycieczka górska w Bieszczady", + "search_by_description_example": "Całodniowa wycieczka w Bieszczady", "search_by_filename": "Szukaj według nazwy pliku lub rozszerzenia", "search_by_filename_example": "np. IMG_1234.JPG lub PNG", "search_camera_make": "Wyszukaj markę aparatu...", @@ -1863,6 +1895,7 @@ "show_slideshow_transition": "Pokaż przejście pokazu slajdów", "show_supporter_badge": "Odznaka wspierającego", "show_supporter_badge_description": "Pokaż odznakę wspierającego", + "show_text_search_menu": "Pokaż menu wyszukiwania tekstowego", "shuffle": "Losuj", "sidebar": "Panel boczny", "sidebar_display_description": "Wyświetl link do widoku w pasku bocznym", @@ -1893,6 +1926,7 @@ "stacktrace": "Ślad stosu", "start": "Start", "start_date": "Od dnia", + "start_date_before_end_date": "Data początkowa musi być wcześniejsza niż data końcowa", "state": "Województwo", "status": "Status", "stop_casting": "Zatrzymaj strumieniowanie", @@ -2095,5 +2129,6 @@ "yes": "Tak", "you_dont_have_any_shared_links": "Nie masz żadnych udostępnionych linków", "your_wifi_name": "Twoja nazwa Wi-Fi", - "zoom_image": "Powiększ obraz" + "zoom_image": "Powiększ obraz", + "zoom_to_bounds": "Powiększ do krawędzi" } diff --git a/i18n/pt.json b/i18n/pt.json index 97673bb7a5..b05c9288a8 100644 --- a/i18n/pt.json +++ b/i18n/pt.json @@ -28,6 +28,7 @@ "add_to_album": "Adicionar ao álbum", "add_to_album_bottom_sheet_added": "Adicionado a {album}", "add_to_album_bottom_sheet_already_exists": "Já existe em {album}", + "add_to_album_bottom_sheet_some_local_assets": "Alguns conteúdos locais não puderam ser adicionados no álbum", "add_to_album_toggle": "Alternar seleção para {album}", "add_to_albums": "Adicionar aos álbuns", "add_to_albums_count": "Adicionar aos álbuns ({count})", @@ -123,6 +124,13 @@ "logging_enable_description": "Ativar registo", "logging_level_description": "Quando ativado, qual o nível de log a usar.", "logging_settings": "Registo", + "machine_learning_availability_checks": "Verificação de disponibilidade", + "machine_learning_availability_checks_description": "Detectar automaticamente e dar preferência aos servidores de aprendizagem automática disponíveis", + "machine_learning_availability_checks_enabled": "Ativar confirmações de disponibilidade", + "machine_learning_availability_checks_interval": "Confirmação de intervalo", + "machine_learning_availability_checks_interval_description": "Intervalo, em milisegundos, entre confirmações de disponibilidade", + "machine_learning_availability_checks_timeout": "Tempo limite para requisição", + "machine_learning_availability_checks_timeout_description": "Tempo limite em milissegundos para verificações de disponibilidade", "machine_learning_clip_model": "Modelo CLIP", "machine_learning_clip_model_description": "O nome do modelo CLIP definido aqui. Tome nota de que é necessário voltar a executar a tarefa de \"Pesquisa Inteligente\" para todas as imagens depois de alterar o modelo.", "machine_learning_duplicate_detection": "Deteção de Itens Duplicados", @@ -387,8 +395,6 @@ "admin_password": "Palavra-passe do administrador", "administration": "Administração", "advanced": "Avançado", - "advanced_settings_beta_timeline_subtitle": "Experimente as novas funcionalidades da aplicação", - "advanced_settings_beta_timeline_title": "Linha temporal da versão Beta", "advanced_settings_enable_alternate_media_filter_subtitle": "Utilize esta definição para filtrar ficheiros durante a sincronização baseada em critérios alternativos. Utilize apenas se a aplicação estiver com problemas a detetar todos os álbuns.", "advanced_settings_enable_alternate_media_filter_title": "[EXPERIMENTAL] Utilizar um filtro alternativo de sincronização de álbuns em dispositivos", "advanced_settings_log_level_title": "Nível de registo: {level}", @@ -396,7 +402,7 @@ "advanced_settings_prefer_remote_title": "Preferir imagens do servidor", "advanced_settings_proxy_headers_subtitle": "Defina os cabeçalhos do proxy que o Immich deve enviar em todas comunicações com a rede", "advanced_settings_proxy_headers_title": "Cabeçalhos do Proxy", - "advanced_settings_readonly_mode_subtitle": "Activa o modo somente leitura, onde as fotos podem ser visualizadas. Recursos como selecionar várias imagens, partilhar, transmitir e excluir ficam deactivados. Activar/Desactivar o modo somente leitura via avatar do utilizador na janela principal", + "advanced_settings_readonly_mode_subtitle": "Ativa o modo somente leitura, onde as fotos podem ser visualizadas. Recursos como selecionar várias imagens, partilhar, transmitir e excluir ficam deactivados. Ativar/Desativar o modo somente leitura via avatar do utilizador na janela principal", "advanced_settings_readonly_mode_title": "Modo somente leitura", "advanced_settings_self_signed_ssl_subtitle": "Não validar o certificado SSL com o endereço do servidor. Isto é necessário para certificados auto-assinados.", "advanced_settings_self_signed_ssl_title": "Permitir certificados SSL auto-assinados", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "Tem a certeza de que quer remover {user}?", "album_search_not_found": "Nenhum álbum encontrado segundo a pesquisa", "album_share_no_users": "Parece que tem este álbum partilhado com todos os utilizadores ou que não existem utilizadores com quem o partilhar.", + "album_summary": "Resumo do álbum", "album_updated": "Álbum atualizado", "album_updated_setting_description": "Receber uma notificação por e-mail quando um álbum partilhado tiver novos ficheiros", "album_user_left": "Saíu do {album}", @@ -496,6 +503,8 @@ "asset_restored_successfully": "Arquivo restaurado com sucesso", "asset_skipped": "Ignorado", "asset_skipped_in_trash": "Na reciclagem", + "asset_trashed": "Ficheiro apagado", + "asset_troubleshoot": "Resolução de problemas com conteúdos", "asset_uploaded": "Enviado", "asset_uploading": "A enviar…", "asset_viewer_settings_subtitle": "Gerenciar as configurações do visualizador da galeria", @@ -529,8 +538,10 @@ "autoplay_slideshow": "Apresentação automática de diapositivos", "back": "Voltar", "back_close_deselect": "Voltar, fechar ou desmarcar", + "background_backup_running_error": "Com a cópia de segurança de fundo em execução, não é possível inicar uma manual", "background_location_permission": "Permissão de localização em segundo plano", "background_location_permission_content": "Para que seja possível trocar a URL quando estiver executando em segundo plano, o Immich deve *sempre* ter a permissão de localização precisa para que o aplicativo consiga ler o nome da rede Wi-Fi", + "background_options": "Opções de fundo", "backup": "Cópia de segurança", "backup_album_selection_page_albums_device": "Álbuns no dispositivo ({count})", "backup_album_selection_page_albums_tap": "Toque para incluir, duplo toque para excluir", @@ -538,6 +549,7 @@ "backup_album_selection_page_select_albums": "Selecione Álbuns", "backup_album_selection_page_selection_info": "Informações da Seleção", "backup_album_selection_page_total_assets": "Total de arquivos únicos", + "backup_albums_sync": "Cópia de segurança de sincronização de álbuns", "backup_all": "Tudo", "backup_background_service_backup_failed_message": "Ocorreu um erro ao efetuar cópia de segurança dos ficheiros. A tentar de novo…", "backup_background_service_connection_failed_message": "Ocorreu um erro na ligação ao servidor. A tentar de novo…", @@ -654,6 +666,8 @@ "change_pin_code": "Alterar código PIN", "change_your_password": "Alterar a sua palavra-passe", "changed_visibility_successfully": "Visibilidade alterada com sucesso", + "charging": "A carregar", + "charging_requirement_mobile_backup": "Cópia de segurança de fundo necesssita que o dispositivo esteja a carregar", "check_corrupt_asset_backup": "Verificar por backups corrompidos", "check_corrupt_asset_backup_button": "Verificar", "check_corrupt_asset_backup_description": "Execute esta verificação somente em uma rede Wi-Fi e quando o backup de todos os arquivos já estiver concluído. O processo demora alguns minutos.", @@ -740,6 +754,7 @@ "create_user": "Criar utilizador", "created": "Criado", "created_at": "Criado a", + "creating_linked_albums": "A criar albuns ligados...", "crop": "Cortar", "curated_object_page_title": "Objetos", "current_device": "Dispositivo atual", @@ -889,7 +904,9 @@ "error": "Erro", "error_change_sort_album": "Ocorreu um erro ao mudar a ordem de exibição", "error_delete_face": "Falha ao remover rosto do ficheiro", + "error_getting_places": "Erro ao obter locais", "error_loading_image": "Erro ao carregar a imagem", + "error_loading_partners": "Erro a carregar parceiros: {error}", "error_saving_image": "Erro: {error}", "error_tag_face_bounding_box": "Erro ao marcar o rosto - não foi possível localizar o rosto", "error_title": "Erro - Algo correu mal", @@ -1054,6 +1071,7 @@ "favorites_page_no_favorites": "Nenhum favorito encontrado", "feature_photo_updated": "Foto principal atualizada", "features": "Funcionalidades", + "features_in_development": "Funcionalidades em Desenvolvimento", "features_setting_description": "Configurar as funcionalidades da aplicação", "file_name": "Nome do ficheiro", "file_name_or_extension": "Nome do ficheiro ou extensão", @@ -1218,6 +1236,7 @@ "local": "Local", "local_asset_cast_failed": "Não é possível transmitir um ficheiro que não tenha sido enviado antes para o servidor", "local_assets": "Ficheiros Locais", + "local_media_summary": "Sumário de conteúdo local", "local_network": "Rede local", "local_network_sheet_info": "O aplicativo irá se conectar ao servidor através desta URL quando estiver na rede Wi-Fi especificada", "location_permission": "Permissão de localização", @@ -1229,6 +1248,7 @@ "location_picker_longitude_hint": "Digite a longitude", "lock": "Trancar", "locked_folder": "Pasta Trancada", + "log_detail_title": "Detalhes de registo", "log_out": "Sair", "log_out_all_devices": "Terminar a sessão de todos os dispositivos", "logged_in_as": "Utilizador atual: {user}", @@ -1243,7 +1263,7 @@ "login_form_endpoint_url": "URL do servidor", "login_form_err_http": "Por favor especifique http:// ou https://", "login_form_err_invalid_email": "Email Inválido", - "login_form_err_invalid_url": "URL inválida", + "login_form_err_invalid_url": "URL inválido", "login_form_err_leading_whitespace": "Espaço em branco no início", "login_form_err_trailing_whitespace": "Espaço em branco no fim", "login_form_failed_get_oauth_server_config": "Ocorreu um erro ao iniciar sessão com o OAuth, verifique o URL do servidor", @@ -1259,6 +1279,7 @@ "login_password_changed_success": "Palavra-passe atualizada com sucesso", "logout_all_device_confirmation": "Tem a certeza de que deseja terminar a sessão em todos os dispositivos?", "logout_this_device_confirmation": "Tem a certeza de que deseja terminar a sessão deste dispositivo?", + "logs": "Logs", "longitude": "Longitude", "look": "Estilo", "loop_videos": "Repetir vídeos", @@ -1301,6 +1322,7 @@ "mark_as_read": "Marcar como lido", "marked_all_as_read": "Tudo marcado como lido", "matches": "Correspondências", + "matching_assets": "Conteúdos coincidentes", "media_type": "Tipo de média", "memories": "Memórias", "memories_all_caught_up": "Finalizamos por hoje", @@ -1341,6 +1363,7 @@ "name_or_nickname": "Nome ou alcunha", "network_requirement_photos_upload": "Usar dados móveis para fazer backup de fotos", "network_requirement_videos_upload": "Usar dados móveis para fazer backup de vídeos", + "network_requirements": "Requisitos de rede", "network_requirements_updated": "Requisitos de rede alterados, redefinindo fila de backup", "networking_settings": "Conexões", "networking_subtitle": "Gerencie a conexão do servidor", @@ -1351,6 +1374,7 @@ "new_person": "Nova Pessoa", "new_pin_code": "Novo código PIN", "new_pin_code_subtitle": "Esta é a primeira vez que acede à pasta trancada. Crie um código PIN para aceder a esta página de forma segura", + "new_timeline": "Nova Linha do Tempo", "new_user_created": "Novo utilizador criado", "new_version_available": "NOVA VERSÃO DISPONÍVEL", "newest_first": "Mais recente primeiro", @@ -1364,6 +1388,7 @@ "no_assets_message": "FAÇA CLIQUE PARA CARREGAR A SUA PRIMEIRA FOTO", "no_assets_to_show": "Não há arquivos para exibir", "no_cast_devices_found": "Nenhum dispositivo de transmissão encontrado", + "no_checksum_local": "Sem cálculo de verificação disponível - não pode capturar conteúdos locais", "no_duplicates_found": "Nenhum item duplicado foi encontrado.", "no_exif_info_available": "Sem informações exif disponíveis", "no_explore_results_message": "Carregue mais fotos para explorar a sua coleção.", @@ -1378,6 +1403,7 @@ "no_results_description": "Tente um sinónimo ou uma palavra-chave mais comum", "no_shared_albums_message": "Crie um álbum para partilhar fotos e vídeos com pessoas na sua rede", "no_uploads_in_progress": "Nenhum carregamento em curso", + "not_available": "N/A", "not_in_any_album": "Não está em nenhum álbum", "not_selected": "Não selecionado", "note_apply_storage_label_to_previously_uploaded assets": "Nota: Para aplicar o Rótulo de Armazenamento a ficheiros carregados anteriormente, execute o", @@ -1499,6 +1525,7 @@ "port": "Porta", "preferences_settings_subtitle": "Gerenciar preferências do aplicativo", "preferences_settings_title": "Preferências", + "preparing": "A Preparar", "preset": "Predefinição", "preview": "Pré-visualizar", "previous": "Anterior", @@ -1562,8 +1589,9 @@ "rating_description": "Mostrar a classificação EXIF no painel de informações", "reaction_options": "Opções de reação", "read_changelog": "Ler Novidades", - "readonly_mode_disabled": "Modo somente leitura desactivado", - "readonly_mode_enabled": "Modo somente leitura activado", + "readonly_mode_disabled": "Modo somente leitura desativado", + "readonly_mode_enabled": "Modo somente leitura ativado", + "ready_for_upload": "Pronto para upload", "reassign": "Reatribuir", "reassigned_assets_to_existing_person": "Reatribuir {count, plural, one {# ficheiro} other {# ficheiros}} para {name, select, null {uma pessoa existente} other {{name}}}", "reassigned_assets_to_new_person": "Reatribuído {count, plural, one {# ficheiro} other {# ficheiros}} a uma nova pessoa", @@ -1863,6 +1891,7 @@ "show_slideshow_transition": "Mostrar transições no Modo de Apresentação", "show_supporter_badge": "Emblema de apoiante", "show_supporter_badge_description": "Mostrar um emblema de apoiante", + "show_text_search_menu": "Mostrar menu de pesquisa de texto", "shuffle": "Aleatório", "sidebar": "Barra lateral", "sidebar_display_description": "Mostrar um link para a vista na barra lateral", @@ -1893,6 +1922,7 @@ "stacktrace": "Stacktrace", "start": "Iniciar", "start_date": "Data de início", + "start_date_before_end_date": "A data de início deve ser anterior à data de fim", "state": "Estado/Distrito", "status": "Estado", "stop_casting": "Parar transmissão", @@ -2009,7 +2039,7 @@ "unstacked_assets_count": "Desempilhados {count, plural, one {# ficheiro} other {# ficheiros}}", "untagged": "Marcador removido", "up_next": "A seguir", - "update_location_action_prompt": "Actualize a localização de {count} activos seleccionados com:", + "update_location_action_prompt": "Atualize a localização de {count} ficheiros selecionados com:", "updated_at": "Atualizado a", "updated_password": "Palavra-passe atualizada", "upload": "Carregar", diff --git a/i18n/pt_BR.json b/i18n/pt_BR.json index 5115f9ff6a..03471cef46 100644 --- a/i18n/pt_BR.json +++ b/i18n/pt_BR.json @@ -28,6 +28,7 @@ "add_to_album": "Adicionar ao álbum", "add_to_album_bottom_sheet_added": "Adicionado ao {album}", "add_to_album_bottom_sheet_already_exists": "Já existe em {album}", + "add_to_album_bottom_sheet_some_local_assets": "Alguns arquivos / mídias não puderam ser adicionados ao álbum", "add_to_album_toggle": "Alternar a seleção de {album}", "add_to_albums": "Adicionar aos álbuns", "add_to_albums_count": "Adicionar aos álbuns ({count})", @@ -123,6 +124,13 @@ "logging_enable_description": "Habilitar logs", "logging_level_description": "Quando ativado, qual nível de log usar.", "logging_settings": "Logs", + "machine_learning_availability_checks": "Verficações de disponibilidade", + "machine_learning_availability_checks_description": "Automaticamente detectar e preferir servidores de machine learning disponíveis", + "machine_learning_availability_checks_enabled": "Habilitar verificações de disponibilidade", + "machine_learning_availability_checks_interval": "Intervalo de verificação", + "machine_learning_availability_checks_interval_description": "Intervalo em milisegundos entre verificações de disponibilidade", + "machine_learning_availability_checks_timeout": "Tempo limite da solicitação", + "machine_learning_availability_checks_timeout_description": "Tempo limite em milisegundos para verificações de disponibilidade", "machine_learning_clip_model": "Modelo CLIP", "machine_learning_clip_model_description": "O nome de um modelo CLIP listado aqui. Lembre-se de executar novamente a tarefa de 'Pesquisa Inteligente' para todas as imagens após alterar o modelo.", "machine_learning_duplicate_detection": "Detecção de duplicidade", @@ -387,8 +395,6 @@ "admin_password": "Senha do administrador", "administration": "Administração", "advanced": "Avançado", - "advanced_settings_beta_timeline_subtitle": "Teste a nova interface do aplicativo", - "advanced_settings_beta_timeline_title": "Linha do tempo Beta", "advanced_settings_enable_alternate_media_filter_subtitle": "Use esta opção para filtrar mídias durante a sincronização com base em critérios alternativos. Tente esta opção somente se o aplicativo estiver com problemas para detectar todos os álbuns.", "advanced_settings_enable_alternate_media_filter_title": "[EXPERIMENTAL] Utilizar filtro alternativo de sincronização de álbum de dispositivo", "advanced_settings_log_level_title": "Nível de log: {level}", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "Tem certeza de que deseja remover {user}?", "album_search_not_found": "Não há álbum que corresponda à sua pesquisa", "album_share_no_users": "Parece que você já compartilhou este álbum com todos os usuários ou não há nenhum usuário para compartilhar.", + "album_summary": "Resumo do álbum", "album_updated": "Álbum atualizado", "album_updated_setting_description": "Receba uma notificação por e-mail quando um álbum compartilhado tiver novos recursos", "album_user_left": "Saiu do álbum {album}", @@ -496,6 +503,8 @@ "asset_restored_successfully": "Arquivo restaurado", "asset_skipped": "Ignorado", "asset_skipped_in_trash": "Na lixeira", + "asset_trashed": "Arquivo enviado para a lixeira", + "asset_troubleshoot": "Diagnóstico do arquivo", "asset_uploaded": "Enviado", "asset_uploading": "Enviando…", "asset_viewer_settings_subtitle": "Gerenciar as configurações do visualizador da galeria", @@ -529,8 +538,10 @@ "autoplay_slideshow": "Apresentação de slides automática", "back": "Voltar", "back_close_deselect": "Voltar, fechar ou desmarcar", + "background_backup_running_error": "Não é possível iniciar o backup manual agora pois o backup em segundo plano já está sendo executado", "background_location_permission": "Permissão de localização em segundo plano", "background_location_permission_content": "Para que seja possível trocar o endereço quando estiver executando em segundo plano, o Immich deve *sempre* ter a permissão de localização precisa para que o aplicativo consiga ler o nome da rede Wi-Fi", + "background_options": "Opções de Plano de Fundo", "backup": "Backup", "backup_album_selection_page_albums_device": "Álbuns no dispositivo ({count})", "backup_album_selection_page_albums_tap": "Toque para incluir, toque duas vezes para excluir", @@ -538,6 +549,7 @@ "backup_album_selection_page_select_albums": "Selecionar álbuns", "backup_album_selection_page_selection_info": "Informações da Seleção", "backup_album_selection_page_total_assets": "Total de recursos exclusivos", + "backup_albums_sync": "Backup de sincronização de álbuns", "backup_all": "Todos", "backup_background_service_backup_failed_message": "Falha ao fazer backup. Tentando novamente…", "backup_background_service_connection_failed_message": "Falha na conexão com o servidor. Tentando novamente…", @@ -654,6 +666,8 @@ "change_pin_code": "Alterar código PIN", "change_your_password": "Alterar sua senha", "changed_visibility_successfully": "Visibilidade alterada com sucesso", + "charging": "Carregando", + "charging_requirement_mobile_backup": "Backups em plano de fundo requerem que o dispositivo esteja sendo carregado", "check_corrupt_asset_backup": "Verifique se há backups corrompidos", "check_corrupt_asset_backup_button": "Verificar", "check_corrupt_asset_backup_description": "Execute esta verificação somente em uma rede Wi-Fi e quando o backup de todos os arquivos já estiver concluído. O processo demora alguns minutos.", @@ -740,6 +754,7 @@ "create_user": "Criar usuário", "created": "Criado", "created_at": "Criado em", + "creating_linked_albums": "Criando álbuns relacionados...", "crop": "Cortar", "curated_object_page_title": "Objetos", "current_device": "Dispositivo atual", @@ -889,7 +904,9 @@ "error": "Erro", "error_change_sort_album": "Falha ao alterar a ordem de exibição", "error_delete_face": "Erro ao remover face do arquivo", + "error_getting_places": "Erro ao buscar os locais", "error_loading_image": "Erro ao carregar a página", + "error_loading_partners": "Erro ao carregar parceiros: {error}", "error_saving_image": "Erro: {error}", "error_tag_face_bounding_box": "Erro ao marcar o rosto - não foi possível localizar o rosto", "error_title": "Erro - Algo deu errado", @@ -1054,6 +1071,7 @@ "favorites_page_no_favorites": "Nenhuma mídia favorita encontrada", "feature_photo_updated": "Foto principal atualizada", "features": "Funcionalidades", + "features_in_development": "Funções em desenvolvimento", "features_setting_description": "Gerenciar as funcionalidades da aplicação", "file_name": "Nome do arquivo", "file_name_or_extension": "Nome do arquivo ou extensão", @@ -1218,6 +1236,7 @@ "local": "Local", "local_asset_cast_failed": "Não é possível transmitir um arquivo que não foi enviado ao servidor", "local_assets": "Arquivos no dispositivo", + "local_media_summary": "Resumo das mídias locais", "local_network": "Rede local", "local_network_sheet_info": "O aplicativo irá se conectar ao servidor através deste endereço quando estiver na rede Wi-Fi especificada", "location_permission": "Permissão de localização", @@ -1229,6 +1248,7 @@ "location_picker_longitude_hint": "Digite a longitude", "lock": "Trancar", "locked_folder": "Pasta com senha", + "log_detail_title": "Detalhes do Log", "log_out": "Sair", "log_out_all_devices": "Sair de todos dispositivos", "logged_in_as": "Usuário atual: {user}", @@ -1259,6 +1279,7 @@ "login_password_changed_success": "Senha atualizada com sucesso", "logout_all_device_confirmation": "Tem certeza de que deseja sair de todos os dispositivos?", "logout_this_device_confirmation": "Tem certeza de que deseja sair deste dispositivo?", + "logs": "Logs", "longitude": "Longitude", "look": "Estilo", "loop_videos": "Repetir vídeos", @@ -1301,6 +1322,7 @@ "mark_as_read": "Marcar como lido", "marked_all_as_read": "Tudo marcado como lido", "matches": "Correspondências", + "matching_assets": "Arquivos encontrados", "media_type": "Tipo de mídia", "memories": "Memórias", "memories_all_caught_up": "Finalizamos por hoje", @@ -1341,6 +1363,7 @@ "name_or_nickname": "Nome ou apelido", "network_requirement_photos_upload": "Use a rede móvel para enviar fotos", "network_requirement_videos_upload": "Use a rede móvel para enviar vídeos", + "network_requirements": "Requerimentos de Rede", "network_requirements_updated": "Requerimentos de rede alterados, reiniciando a fila de envio", "networking_settings": "Conexões", "networking_subtitle": "Gerencie as conexões ao servidor", @@ -1351,6 +1374,7 @@ "new_person": "Nova Pessoa", "new_pin_code": "Novo código PIN", "new_pin_code_subtitle": "Esta é a primeira vez que está acessando a pasta com senha. Crie um código PIN para acessar esta página de forma segura", + "new_timeline": "Nova Linha do Tempo", "new_user_created": "Novo usuário criado", "new_version_available": "NOVA VERSÃO DISPONÍVEL", "newest_first": "Mais recente primeiro", @@ -1364,20 +1388,25 @@ "no_assets_message": "CLIQUE PARA ENVIAR SUA PRIMEIRA FOTO", "no_assets_to_show": "Não há arquivos para exibir", "no_cast_devices_found": "Nenhum dispositivo encontrado", + "no_checksum_local": "Nenhum checksum disponível - não foi possível carregar os arquivos locais", + "no_checksum_remote": "Nenhum checksum disponível - não foi possível carregar os arquivos remotos", "no_duplicates_found": "Nenhuma duplicidade foi encontrada.", "no_exif_info_available": "Sem informações exif disponíveis", "no_explore_results_message": "Envie mais fotos para explorar sua coleção.", "no_favorites_message": "Adicione aos favoritos para encontrar suas melhores fotos e vídeos rapidamente", "no_libraries_message": "Crie uma biblioteca externa para ver suas fotos e vídeos", + "no_local_assets_found": "Nenhum arquivo local foi encontrado com este checksum", "no_locked_photos_message": "Fotos e vídeos na pasta com senha são ocultos e não serão exibidos enquanto explora ou pesquisa na biblioteca.", "no_name": "Sem Nome", "no_notifications": "Nenhuma notificação", "no_people_found": "Nenhuma pessoa encontrada", "no_places": "Sem lugares", + "no_remote_assets_found": "Nenhum arquivo remoto foi encontrado com este checksum", "no_results": "Sem resultados", "no_results_description": "Tente um sinônimo ou uma palavra-chave mais geral", "no_shared_albums_message": "Crie um álbum para compartilhar fotos e vídeos com pessoas em sua rede", "no_uploads_in_progress": "Nenhum envio em progresso", + "not_available": "N/A", "not_in_any_album": "Fora de álbum", "not_selected": "Não selecionado", "note_apply_storage_label_to_previously_uploaded assets": "Nota: Para aplicar o rótulo de armazenamento a arquivos enviados anteriormente, execute o", @@ -1499,6 +1528,7 @@ "port": "Porta", "preferences_settings_subtitle": "Gerenciar as preferências do aplicativo", "preferences_settings_title": "Preferências", + "preparing": "Preparando", "preset": "Predefinição", "preview": "Pré-visualizar", "previous": "Anterior", @@ -1564,6 +1594,7 @@ "read_changelog": "Ler Novidades", "readonly_mode_disabled": "Modo apenas visualização desativado", "readonly_mode_enabled": "Modo apenas visualização ativado", + "ready_for_upload": "Pronto para upload", "reassign": "Reatribuir", "reassigned_assets_to_existing_person": "{count, plural, one {# arquivo reatribuído} other {# arquivos reatribuídos}} a {name, select, null {uma pessoa} other {{name}}}", "reassigned_assets_to_new_person": "{count, plural, one {# arquivo reatribuído} other {# arquivos reatribuídos}} a uma nova pessoa", @@ -1588,6 +1619,7 @@ "regenerating_thumbnails": "Regenerando miniaturas", "remote": "Remoto", "remote_assets": "Arquivos Remotos", + "remote_media_summary": "Resumo das mídias remotas", "remove": "Remover", "remove_assets_album_confirmation": "Tem certeza de que deseja remover {count, plural, one {# arquivo} other {# arquivos}} do álbum?", "remove_assets_shared_link_confirmation": "Tem certeza de que deseja remover {count, plural, one {# arquivo} other {# arquivos}} desse link compartilhado?", @@ -1863,6 +1895,7 @@ "show_slideshow_transition": "Usar transições no modo de apresentação", "show_supporter_badge": "Insígnia de apoiador", "show_supporter_badge_description": "Mostrar uma insígnia de apoiador", + "show_text_search_menu": "Mostrar menu de pesquisa por texto", "shuffle": "Aleatório", "sidebar": "Barra lateral", "sidebar_display_description": "Exibir um link para a visualização na barra lateral", @@ -1893,6 +1926,7 @@ "stacktrace": "Stacktrace", "start": "Início", "start_date": "Data inicial", + "start_date_before_end_date": "A data de início deve ser antes da data final", "state": "Estado", "status": "Status", "stop_casting": "Parar transmissão", @@ -2095,5 +2129,6 @@ "yes": "Sim", "you_dont_have_any_shared_links": "Não há links compartilhados", "your_wifi_name": "Nome do seu Wi-Fi", - "zoom_image": "Ampliar imagem" + "zoom_image": "Ampliar imagem", + "zoom_to_bounds": "Ampliar para preencher" } diff --git a/i18n/ro.json b/i18n/ro.json index fc2ca444c6..76e87c0cb6 100644 --- a/i18n/ro.json +++ b/i18n/ro.json @@ -1,12 +1,12 @@ { "about": "Despre", "account": "Cont", - "account_settings": "Setări Cont", + "account_settings": "Setări cont", "acknowledge": "Văzut", "action": "Acţiune", "action_common_update": "Actualizează", "actions": "Acţiuni", - "active": "Activ", + "active": "Active", "activity": "Activitate", "activity_changed": "Activitatea este {enabled, select, true {activată} other {dezactivată}}", "add": "Adaugă", @@ -28,6 +28,7 @@ "add_to_album": "Adaugă în album", "add_to_album_bottom_sheet_added": "Adăugat în {album}", "add_to_album_bottom_sheet_already_exists": "Deja în {album}", + "add_to_album_bottom_sheet_some_local_assets": "Unele resurse locale nu au putut fi adăugate la album", "add_to_album_toggle": "Selectează/deselectează {album}", "add_to_albums": "Adaugă la albume", "add_to_albums_count": "Adaugă la albume ({count})", @@ -40,12 +41,12 @@ "add_exclusion_pattern_description": "Adăugați modele de excludere. Globing folosind *, ** și ? este suportat. Pentru a ignora toate fișierele din orice director numit „Raw”, utilizați „**/Raw/**”. Pentru a ignora toate fișierele care se termină în „.tif”, utilizați „**/*.tif”. Pentru a ignora o cale absolută, utilizați „/path/to/ignore/**”.", "admin_user": "Utilizator admin", "asset_offline_description": "Acest material din biblioteca externă nu se mai găsește pe disc și a fost mutat în coșul de gunoi. Dacă fișierul a fost mutat în bibliotecă, verificați cronologia pentru noul material corespunzător. Pentru a restabili acest material, asigurați-vă că calea fișierului de mai jos poate fi accesată de Immich și scanați biblioteca.", - "authentication_settings": "Setări de Autentificare", + "authentication_settings": "Setări de autentificare", "authentication_settings_description": "Gestionează parola, OAuth și alte setări de autentificare", "authentication_settings_disable_all": "Ești sigur că vrei sa dezactivezi toate metodele de autentificare? Autentificarea va fi complet dezactivată.", "authentication_settings_reenable": "Pentru a reactiva, folosește Comandă Server.", "background_task_job": "Activități de Fundal", - "backup_database": "Salvare Bază de Date", + "backup_database": "Salvare bază de date", "backup_database_enable_description": "Activare salvarea bazei de date", "backup_keep_last_amount": "Număr de copii de rezervă anterioare de păstrat", "backup_onboarding_1_description": "copie externă în cloud sau într-o altă locație fizică.", @@ -72,9 +73,9 @@ "disable_login": "Dezactivați autentificarea", "duplicate_detection_job_description": "Rulați învățarea automată pe materiale pentru a detecta imagini similare. Se bazează pe Căutare Inteligentă", "exclusion_pattern_description": "Modelele de excludere vă permit să ignorați fișierele și folderele atunci când vă scanați biblioteca. Acest lucru este util dacă aveți foldere care conțin fișiere pe care nu doriți să le importați, cum ar fi fișierele RAW.", - "external_library_management": "Managementul Bibliotecii Externe", + "external_library_management": "Gestionarea bibliotecilor externe", "face_detection": "Detecție facială", - "face_detection_description": "Detectează fețele din fișiere folosind învățare automată. Pentru videoclipuri, este luată în considerare doar miniatura. „Reînprospătează” (re)procesează toate fișierele. „Resetează” adaugă în coadă fișierele care nu au fost încă procesate. Fețele detectate vor fi puse în coadă pentru recunoașterea facială după finalizarea detectării feței, grupându-le în persoane existente sau noi.", + "face_detection_description": "Detectează fețele din fișiere folosind învățare automată. Pentru videoclipuri, este luată în considerare doar miniatura. „Reîmprospătează” (re)procesează toate fișierele. „Resetează” adaugă în coadă fișierele care nu au fost încă procesate. Fețele detectate vor fi puse în coadă pentru recunoașterea facială după finalizarea detectării feței, grupându-le în persoane existente sau noi.", "facial_recognition_job_description": "Grupați fețele detectate în persoane. Acest pas rulează după ce Detectarea Feței este finalizată. „Resetează” (re)grupează toate fețele. „Lipsă” adaugă în coadă fețe care nu au o persoană desemnată.", "failed_job_command": "Comanda {command} a eșuat pentru jobul: {job}", "force_delete_user_warning": "AVERTISMENT: Acest lucru va elimina imediat utilizatorul și toate activele sale. Acest lucru nu poate fi anulat și fișierele nu pot fi recuperate.", @@ -91,30 +92,30 @@ "image_prefer_wide_gamut_setting_description": "Utilizați Display P3 pentru miniaturi. Acest lucru păstrează mai bine vibrația imaginilor cu spații de culoare largi, dar imaginile pot apărea diferit pe dispozitivele cu o versiune mai veche de browser. Imaginile sRGB sunt păstrate ca sRGB pentru a evita schimbările de culoare.", "image_preview_description": "Imagine de dimensiune medie cu metadate eliminate, utilizată la vizualizarea unui singur element și pentru învățarea automată", "image_preview_quality_description": "Calitatea previzualizării de la 1 la 100. O valoare mai mare oferă o calitate mai bună, dar produce fișiere mai mari și poate reduce receptivitatea aplicației. Setarea unei valori scăzute poate afecta calitatea învățării automate.", - "image_preview_title": "Previzualizați Setările", + "image_preview_title": "Previzualizați setările", "image_quality": "Calitate", "image_resolution": "Rezolutie", "image_resolution_description": "Rezoluțiile mai mari pot păstra mai multe detalii, dar necesită mai mult timp pentru a fi codificate, au dimensiuni mai mari ale fișierelor și pot reduce răspunsul aplicației.", - "image_settings": "Setări Imagine", + "image_settings": "Setări imagine", "image_settings_description": "Gestionează calitatea și rezoluția imaginilor generate", "image_thumbnail_description": "Miniatură mică cu metadate eliminate, utilizată la vizualizarea grupurilor de fotografii, cum ar fi în cronologia principală", "image_thumbnail_quality_description": "Calitatea miniaturii de la 1 la 100. O valoare mai mare oferă o calitate mai bună, dar produce fișiere mai mari și poate reduce receptivitatea aplicației.", - "image_thumbnail_title": "Setari Miniaturi", + "image_thumbnail_title": "Setari miniaturi", "job_concurrency": "Concurență {job}", "job_created": "Sarcină creată", "job_not_concurrency_safe": "Această sarcină nu este sigură pentru a rula în concurență.", - "job_settings": "Setări Sarcină", + "job_settings": "Setări sarcină", "job_settings_description": "Administrează concurența sarcinilor", - "job_status": "Starea Sarcinii", + "job_status": "Starea sarcinii", "jobs_delayed": "{jobCount, plural, other {# întârziat}}", "jobs_failed": "{jobCount, plural, other {# eșuat}}", - "library_created": "Librărie creată:{library}", + "library_created": "Librărie creată: {library}", "library_deleted": "Bibliotecă ștearsă", "library_import_path_description": "Specificați un folder pentru a îl importa. Acest folder, inclusiv sub-folderele, vor fi scanate pentru imagini și videoclipuri.", - "library_scanning": "Scanare Periodică", + "library_scanning": "Scanare periodică", "library_scanning_description": "Configurează scanarea periodică pentru bibliotecă", "library_scanning_enable_description": "Activează scanarea periodică pentru bibliotecă", - "library_settings": "Bibliotecă Externă", + "library_settings": "Bibliotecă externă", "library_settings_description": "Administrează setările pentru biblioteci externe", "library_tasks_description": "Scanează bibliotecile externe de active noi sau modificate", "library_watching_enable_description": "Urmărește bibliotecile externe pentru schimbări ale fișierelor", @@ -123,9 +124,16 @@ "logging_enable_description": "Activează înregistrarea log-urilor", "logging_level_description": "Dacă setarea este activată, înregistrează evenimentele cu nivelul de utilizat.", "logging_settings": "Înregistrare", + "machine_learning_availability_checks": "Verificări disponibilitate", + "machine_learning_availability_checks_description": "Detectează automat si preferă serverele cu învațare automată", + "machine_learning_availability_checks_enabled": "Activează verificare disponibilitate", + "machine_learning_availability_checks_interval": "Interval verificare", + "machine_learning_availability_checks_interval_description": "Interval in milisecunde între verificările de disponibilitate", + "machine_learning_availability_checks_timeout": "Timp de expirare cerere", + "machine_learning_availability_checks_timeout_description": "Timp de așteptare în milisecunde pentru verificările de disponibilitate", "machine_learning_clip_model": "Model CLIP", "machine_learning_clip_model_description": "Numele unui model CLIP listat aici. Rețineți că trebuie să rulați din nou funcția „Smart Search” pentru toate imaginile la schimbarea unui model.", - "machine_learning_duplicate_detection": "Detectare Duplicate", + "machine_learning_duplicate_detection": "Detectare duplicate", "machine_learning_duplicate_detection_enabled": "Activează detectarea duplicatelor", "machine_learning_duplicate_detection_enabled_description": "Dacă este dezactivată, elementele identice vor fi în continuare de-duplicate.", "machine_learning_duplicate_detection_setting_description": "Utilizați încorporările CLIP pentru a găsi dubluri probabile", @@ -152,11 +160,11 @@ "machine_learning_smart_search_enabled": "Activați căutarea inteligentă", "machine_learning_smart_search_enabled_description": "Dacă este dezactivată, imaginile nu vor fi codificate pentru căutarea inteligentă.", "machine_learning_url_description": "URL-ul serverului de învățare automată. Dacă sunt furnizate mai multe URL-uri, fiecare server va fi încercat pe rând, până când unul răspunde cu succes, în ordine de la primul până la ultimul. Serverele care nu răspund vor fi ignorate temporar până revin online.", - "manage_concurrency": "Gestionarea Simultaneității", + "manage_concurrency": "Gestionarea simultaneității", "manage_log_settings": "Administrați setările jurnalului", "map_dark_style": "Mod întunecat", "map_enable_description": "Activați funcțiile hărții", - "map_gps_settings": "Setări Hartă & GPS", + "map_gps_settings": "Setări hartă & GPS", "map_gps_settings_description": "Gestionare setări Hartă & GPS (localizare inversă)", "map_implications": "Caracteristica hărții se bazează pe un serviciu extern de planșe (tiles.immich.cloud)", "map_light_style": "Mod deschis", @@ -173,7 +181,7 @@ "metadata_extraction_job_description": "Extragere informații metadate din fiecare fișier cum ar fi localizare GPS, fețe și rezoluție,", "metadata_faces_import_setting": "Activare import fețe", "metadata_faces_import_setting_description": "Importă fețe din datele EXIF ale imaginii și din fișiere tip \"sidecar\"", - "metadata_settings": "Setări Metadate", + "metadata_settings": "Setări metadate", "metadata_settings_description": "Gestionează setările pentru metadate", "migration_job": "Migrare", "migration_job_description": "Migrați miniaturile pentru elemente și fețe la cea mai recentă structură de foldere", @@ -251,7 +259,7 @@ "send_welcome_email": "Trimite email de bun-venit", "server_external_domain_settings": "Domeniu extern", "server_external_domain_settings_description": "Domeniu pentru distribuire publicǎ a scurtǎturilor, incluzând http(s)://", - "server_public_users": "Utilizatori Publici", + "server_public_users": "Utilizatori publici", "server_public_users_description": "Toți utilizatorii (nume și e-mail) sunt listați atunci când adăugați un utilizator la albumele partajate. Când este dezactivată, lista de utilizatori va fi disponibilă numai pentru utilizatorii admin.", "server_settings": "Setǎri Server", "server_settings_description": "Gestioneazǎ setǎrile serverului", @@ -273,7 +281,7 @@ "storage_template_more_details": "Pentru mai multe detalii despre aceasta caracteristică, accesați Șablon stocare si implicațiile", "storage_template_onboarding_description_v2": "Când este activată, această funcție va organiza automat fișierele pe baza șablonului definit de către utilizator. Pentru mai multe informații, accesează documentația.", "storage_template_path_length": "Limita de lungime pentru calea aproximativă: {length, number}/{limit, number}", - "storage_template_settings": "Șablon Stocare", + "storage_template_settings": "Șablon stocare", "storage_template_settings_description": "Gestionează structura folderelor și numele fișierelor pentru elementele încărcate", "storage_template_user_label": "{label} este eticheta de stocare a utilizatorului", "system_settings": "Setǎri de Sistem", @@ -289,9 +297,9 @@ "template_settings_description": "Gestionați șabloanele personalizate pentru notificări", "theme_custom_css_settings": "CSS personalizat", "theme_custom_css_settings_description": "Foile de stil în cascadă (CSS) permit personalizarea designului Immich.", - "theme_settings": "Setări Temă", + "theme_settings": "Setări temă", "theme_settings_description": "Gestionează personalizarea interfeței web Immich", - "thumbnail_generation_job": "Generare Miniaturi", + "thumbnail_generation_job": "Generare miniaturi", "thumbnail_generation_job_description": "Generează miniaturi mari, mici și estompate pentru fiecare resursă, precum și miniaturi pentru fiecare persoană", "transcoding_acceleration_api": "API de accelerare", "transcoding_acceleration_api_description": "API-ul care va interacționa cu dispozitivul tău pentru a accelera transcodarea. Această setare este 'cel mai bun efort': va reveni la transcodarea software în caz de eșec. VP9 poate funcționa sau nu, în funcție de hardware-ul tău.", @@ -317,7 +325,7 @@ "transcoding_disabled_description": "Nu transcodifică niciun videoclip; acest lucru poate afecta redarea pe anumite dispozitive", "transcoding_encoding_options": "Opțiuni codificare", "transcoding_encoding_options_description": "Setează codecuri , calitatea, rezoluția și alte opțiuni pentru videoclipuri codificare", - "transcoding_hardware_acceleration": "Accelerare Hardware", + "transcoding_hardware_acceleration": "Accelerare hardware", "transcoding_hardware_acceleration_description": "Experimental: transcodare mai rapidă, dar poate reduce calitatea la aceeași rată de biți", "transcoding_hardware_decoding": "Decodare hardware", "transcoding_hardware_decoding_setting_description": "Se aplică doar pentru NVENC, QSV și RKMPP. Activează accelerarea completă în loc de doar accelerarea codificării. S-ar putea să nu funcționeze pentru toate videoclipurile.", @@ -337,7 +345,7 @@ "transcoding_reference_frames": "Cadre de referință", "transcoding_reference_frames_description": "Numărul de cadre de referință atunci când se comprimă un cadru dat. Valorile mai mari îmbunătățesc eficiența compresiei, dar încetinesc codarea. 0 setează această valoare automat.", "transcoding_required_description": "Numai videoclipuri care nu sunt într-un format acceptat", - "transcoding_settings": "Setări de Transcodare Video", + "transcoding_settings": "Setări de transcodare video", "transcoding_settings_description": "Gestionează care videoclipuri să transcodam și cum să le procesam", "transcoding_target_resolution": "Rezoluția țintă", "transcoding_target_resolution_description": "Rezoluțiile mai mari pot păstra mai multe detalii, dar necesită mai mult timp pentru codare, au dimensiuni mai mari ale fișierelor și pot reduce răspunsul aplicației.", @@ -368,27 +376,25 @@ "user_delete_immediately": "Contul și resursele utilizatorului {user} vor fi puse în coadă pentru ștergere permanentă imediat.", "user_delete_immediately_checkbox": "Pune utilizatorul și resursele în coadă pentru ștergere imediată", "user_details": "Detalii utilizator", - "user_management": "Gestionarea Utilizatorilor", + "user_management": "Gestionarea utilizatorilor", "user_password_has_been_reset": "Parola utilizatorului a fost resetată:", "user_password_reset_description": "Vă rugăm să furnizați utilizatorului parola temporară și să îi informați că va trebui să o schimbe la următoarea autentificare.", "user_restore_description": "Contul utilizatorului {user} va fi restaurat.", "user_restore_scheduled_removal": "Restaurare utilizator - ștergere programată pe {date, date, long}", - "user_settings": "Setǎri Utilizator", + "user_settings": "Setǎri utilizator", "user_settings_description": "Gestioneazǎ setǎrile utilizatorului", "user_successfully_removed": "Utilizatorul {email} a fost eliminat cu succes.", "version_check_enabled_description": "Activează verificarea versiunii", "version_check_implications": "Funcția de verificare a versiunii se bazează pe comunicarea periodică cu github.com", - "version_check_settings": "Verificare Versiune", + "version_check_settings": "Verificare versiune", "version_check_settings_description": "Activeazǎ/dezactiveazǎ notificarea unei noi versiuni", "video_conversion_job": "Transcodați videoclipuri", "video_conversion_job_description": "Transcodați videoclipurile pentru o compatibilitate mai mare cu browserele și dispozitivele" }, - "admin_email": "E-mail Administrator", - "admin_password": "Parolă Administrator", + "admin_email": "E-mail administrator", + "admin_password": "Parolă administrator", "administration": "Administrare", "advanced": "Avansat", - "advanced_settings_beta_timeline_subtitle": "Încearcă noua experiență în aplicație", - "advanced_settings_beta_timeline_title": "Cronologie beta", "advanced_settings_enable_alternate_media_filter_subtitle": "Utilizați această opțiune pentru a filtra conținutul media în timpul sincronizării pe baza unor criterii alternative. Încercați numai dacă întâmpinați probleme cu aplicația la detectarea tuturor albumelor.", "advanced_settings_enable_alternate_media_filter_title": "[EXPERIMENTAL] Utilizați filtrul alternativ de sincronizare a albumelor de pe dispozitiv", "advanced_settings_log_level_title": "Nivel log: {level}", @@ -396,7 +402,7 @@ "advanced_settings_prefer_remote_title": "Preferă fotografii la distanță", "advanced_settings_proxy_headers_subtitle": "Definește antetele proxy pe care Immich ar trebui să le trimită cu fiecare solicitare de rețea", "advanced_settings_proxy_headers_title": "Antete Proxy", - "advanced_settings_readonly_mode_subtitle": "Activează modul doar-citire, în care fotografiile pot fi doar vizualizate, iar acțiuni precum selectarea mai multor imagini, partajarea, redarea pe alt dispozitiv sau ștergerea sunt dezactivate. Activează/Dezactivează modul doar-citire din avatarul utilizatorului de pe ecranul principal.", + "advanced_settings_readonly_mode_subtitle": "Activează modul doar-citire, în care fotografiile pot fi doar vizualizate, iar acțiuni precum selectarea mai multor imagini, partajarea, redarea pe alt dispozitiv sau ștergerea sunt dezactivate. Activează/Dezactivează modul doar-citire din avatarul utilizatorului de pe ecranul principal", "advanced_settings_readonly_mode_title": "Mod doar-citire", "advanced_settings_self_signed_ssl_subtitle": "Omite verificare certificate SSL pentru distinația server-ului, necesar pentru certificate auto-semnate.", "advanced_settings_self_signed_ssl_title": "Permite certificate SSL auto-semnate", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "Ești sigur că dorești eliminarea {user}?", "album_search_not_found": "Nu s-au găsit albume care să corespundă căutării dumneavoastră", "album_share_no_users": "Se pare că ai partajat acest album cu toți utilizatorii sau nu ai niciun utilizator cu care să-l partajezi.", + "album_summary": "Rezumat album", "album_updated": "Album actualizat", "album_updated_setting_description": "Primiți o notificare prin e-mail când un album partajat are elemente noi", "album_user_left": "A părăsit {album}", @@ -482,7 +489,7 @@ "asset_description_updated": "Descrierea resursei a fost actualizată", "asset_filename_is_offline": "Resursa {filename} este offline", "asset_has_unassigned_faces": "Resursa are fețe neatribuite", - "asset_hashing": "Calculare amprentă digitală", + "asset_hashing": "Calculare amprentă digitală…", "asset_list_group_by_sub_title": "Grupare după", "asset_list_layout_settings_dynamic_layout_title": "Aspect dinamic", "asset_list_layout_settings_group_automatically": "Automat", @@ -496,6 +503,8 @@ "asset_restored_successfully": "Date restaurate cu succes", "asset_skipped": "Sărit", "asset_skipped_in_trash": "În coșul de gunoi", + "asset_trashed": "Resursă ștearsă", + "asset_troubleshoot": "Depanare resursă", "asset_uploaded": "Încărcat", "asset_uploading": "Se incarcă…", "asset_viewer_settings_subtitle": "Gestionați setările de vizualizare a galeriei", @@ -522,14 +531,17 @@ "assets_trashed_count": "Mutat în coșul de gunoi {count, plural, one {# resursă} other {# resurse}}", "assets_trashed_from_server": "{count} resursă(e) eliminate de pe serverul Immich", "assets_were_part_of_album_count": "{count, plural, one {Resursa era} other {Resursele erau}} deja parte din album", + "assets_were_part_of_albums_count": "{count, plural, one {Asset was} other {Assets were}} deja parte din albume", "authorized_devices": "Dispozitive Autorizate", "automatic_endpoint_switching_subtitle": "Conectează-te local prin rețeaua Wi‐Fi configurată când este valabilă și prin rețele alternative în caz contrar", "automatic_endpoint_switching_title": "Alternare URL automată", "autoplay_slideshow": "Derulare slideshow automat", "back": "Înapoi", "back_close_deselect": "Înapoi, închidere sau deselectare", + "background_backup_running_error": "Procesul de backup în fundal este activ, nu se poate porni backup manual", "background_location_permission": "Permisiune locație în fundal", "background_location_permission_content": "Pentru a putea schimba rețeaua activă în fundal, Immich are nevoie de acces *permanent* la locația precisă pentru a citi numele rețelei Wi-Fi", + "background_options": "Opțiuni de fundal", "backup": "Backup", "backup_album_selection_page_albums_device": "Albume în dispozitiv ({count})", "backup_album_selection_page_albums_tap": "Apasă odata pentru a include, de două ori pentru a exclude", @@ -537,6 +549,7 @@ "backup_album_selection_page_select_albums": "Selectează albume", "backup_album_selection_page_selection_info": "Informații selecție", "backup_album_selection_page_total_assets": "Total resurse unice", + "backup_albums_sync": "Sincronizarea albumelor de backup", "backup_all": "Toate", "backup_background_service_backup_failed_message": "Eșuare backup resurse. Reîncercare…", "backup_background_service_connection_failed_message": "Conectare la server eșuată. Reîncercare…", @@ -576,7 +589,7 @@ "backup_controller_page_remainder": "Rămas(e)", "backup_controller_page_remainder_sub": "Fotografii și videoclipuri din selecție rămase pentru backup", "backup_controller_page_server_storage": "Stocare server", - "backup_controller_page_start_backup": "Începe backup", + "backup_controller_page_start_backup": "Începe copia de rezervă", "backup_controller_page_status_off": "Backup-ul automat în prim-plan este oprit", "backup_controller_page_status_on": "Backup-ul automat în prim-plan este pornit", "backup_controller_page_storage_format": "{used} din {total} folosit", @@ -591,7 +604,8 @@ "backup_manual_in_progress": "Încărcarea este deja în curs. Încearcă din nou mai târziu", "backup_manual_success": "Succes", "backup_manual_title": "Status încărcare", - "backup_options_page_title": "Opțiuni Backup", + "backup_options": "Opțiuni copie de rezervă", + "backup_options_page_title": "Opțiuni copie de rezervă", "backup_setting_subtitle": "Schimbă opțiuni pentru backup în prim-plan și în fundal", "backup_settings_subtitle": "Gestionați setările de încărcare", "backward": "În sens invers", @@ -602,7 +616,7 @@ "birthdate_saved": "Data nașterii salvată cu succes", "birthdate_set_description": "Data nașterii este utilizată pentru a calcula vârsta acestei persoane la momentul realizării fotografiei.", "blurred_background": "Fundal neclar", - "bugs_and_feature_requests": "Erori și Solicitări de Caracteristici", + "bugs_and_feature_requests": "Erori și solicitări de caracteristici", "build": "Versiunea", "build_image": "Versiune Imagine", "bulk_delete_duplicates_confirmation": "Ești sigur că vrei să ștergi în masă {count, plural, one {# resursă duplicată} other {# resurse duplicate}}? Aceasta va păstra cea mai mare resursă din fiecare grup și va șterge permanent toate celelalte duplicate. Nu poți anula această acțiune!", @@ -652,6 +666,8 @@ "change_pin_code": "Schimbă codul PIN", "change_your_password": "Schimbă-ți parola", "changed_visibility_successfully": "Schimbare vizibilitate cu succes", + "charging": "Încărcare", + "charging_requirement_mobile_backup": "Pentru copia de rezervă în fundal, dispozitivul trebuie să fie în curs de încărcare", "check_corrupt_asset_backup": "Verifică copii de rezervă a resurselor corupte", "check_corrupt_asset_backup_button": "Efectuează verificarea", "check_corrupt_asset_backup_description": "Rulează această verificare doar prin Wi-Fi și doar după ce toate resursele au fost salvate în copia de rezerva. Procedura poate dura câteva minute.", @@ -703,7 +719,7 @@ "control_bottom_app_bar_delete_from_immich": "Șterge din Immich", "control_bottom_app_bar_delete_from_local": "Șterge din dispozitiv", "control_bottom_app_bar_edit_location": "Editează locație", - "control_bottom_app_bar_edit_time": "Editează Data și Ora", + "control_bottom_app_bar_edit_time": "Editează data și ora", "control_bottom_app_bar_share_link": "Partajează linkul", "control_bottom_app_bar_share_to": "Distribuire către", "control_bottom_app_bar_trash_from_immich": "Mută în coș", @@ -738,6 +754,7 @@ "create_user": "Creează utilizator", "created": "Creat", "created_at": "Creat", + "creating_linked_albums": "Crearea albumelor cu link...", "crop": "Decupează", "curated_object_page_title": "Obiecte", "current_device": "Dispozitiv curent", @@ -757,6 +774,7 @@ "date_of_birth_saved": "Data nașterii salvată cu succes", "date_range": "Interval de date", "day": "Zi", + "days": "Zile", "deduplicate_all": "Deduplicați Toate", "deduplication_criteria_1": "Marimea imagini în octeți", "deduplication_criteria_2": "Numărul de date EXIF", @@ -841,10 +859,12 @@ "edit": "Editare", "edit_album": "Editare album", "edit_avatar": "Editare avatar", - "edit_birthday": "Editează ziua de naștere", + "edit_birthday": "Modifică ziua de naștere", "edit_date": "Editare dată", "edit_date_and_time": "Editare dată și oră", "edit_date_and_time_action_prompt": "{count} data și ora modificării", + "edit_date_and_time_by_offset": "Schimbă data prin decalaj", + "edit_date_and_time_by_offset_interval": "Noul interval de date: {from} - {to}", "edit_description": "Editează descrierea", "edit_description_prompt": "Vă rugăm să selectați o descriere nouă:", "edit_exclusion_pattern": "Editarea modelului de excludere", @@ -854,7 +874,7 @@ "edit_key": "Tastă de editare", "edit_link": "Editare link", "edit_location": "Editare locație", - "edit_location_action_prompt": "{count} locație(i) editată(e)", + "edit_location_action_prompt": "{count} locație(i) modificată(e)", "edit_location_dialog_title": "Locație", "edit_name": "Editare nume", "edit_people": "Editare persoane", @@ -884,7 +904,9 @@ "error": "Eroare", "error_change_sort_album": "Nu s-a putut modifica ordinea de sortare a albumului", "error_delete_face": "Eroare la ștergerea feței din activ", + "error_getting_places": "Eroare la obținerea locațiilor", "error_loading_image": "Eroare la încărcarea imaginii", + "error_loading_partners": "Eroare la încărcarea partenerilor: {error}", "error_saving_image": "Eroare: {error}", "error_tag_face_bounding_box": "Eroare la etichetarea feței - nu se pot obține coordonatele casetei de delimitare", "error_title": "Eroare - ceva nu a mers", @@ -917,6 +939,7 @@ "failed_to_load_notifications": "Nu s-au putut încărca notificările", "failed_to_load_people": "Eșec la încărcarea persoanelor", "failed_to_remove_product_key": "Eșec la eliminarea cheii de produs", + "failed_to_reset_pin_code": "Nu s-a reușit resetarea codului PIN", "failed_to_stack_assets": "Eșec la combinarea resurselor", "failed_to_unstack_assets": "Eșec la desfășurarea resurselor", "failed_to_update_notification_status": "Nu s-a putut actualiza starea notificării", @@ -925,6 +948,7 @@ "paths_validation_failed": "{paths, plural, one {# cale} other {# căi}} nu a trecut validarea", "profile_picture_transparent_pixels": "Pozele de profil nu pot avea pixeli transparenți. Te rugăm să mărești imaginea și/sau să o muți.", "quota_higher_than_disk_size": "Ați stabilit o valoare a spațiului de stocare mai mare decât dimensiunea discului", + "something_went_wrong": "Ceva nu a mers bine", "unable_to_add_album_users": "Imposibil de adăugat utilizatori în album", "unable_to_add_assets_to_shared_link": "Imposibil de adăugat resurse la link-ul partajat", "unable_to_add_comment": "Imposibil de adăugat comentariu", @@ -1032,7 +1056,7 @@ "export_database_description": "Exportați baza de date SQLite", "extension": "Extensie", "external": "Extern", - "external_libraries": "Biblioteci Externe", + "external_libraries": "Biblioteci externe", "external_network": "Rețea externă", "external_network_sheet_info": "Când nu se află în rețeaua Wi-Fi preferată, aplicația se va conecta la server prin prima dintre adresele URL de mai jos pe care o poate accesa, începând de sus în jos", "face_unassigned": "Nealocat", @@ -1047,6 +1071,7 @@ "favorites_page_no_favorites": "Nu au fost găsite resurse favorite", "feature_photo_updated": "Fotografie caracteristică actualizată", "features": "Caracteristici", + "features_in_development": "Funcții în dezvoltare", "features_setting_description": "Gestionați funcțiile aplicației", "file_name": "Nume de fișier", "file_name_or_extension": "Numele sau extensia fișierului", @@ -1056,21 +1081,26 @@ "filter_people": "Filtrați persoanele", "filter_places": "Filtrează locurile", "find_them_fast": "Găsiți-le rapid prin căutare după nume", + "first": "Primul", "fix_incorrect_match": "Remediați potrivirea incorectă", "folder": "Dosar", "folder_not_found": "Dosar negăsit", "folders": "Foldere", "folders_feature_description": "Răsfoire în conținutul folderului pentru fotografiile și videoclipurile din sistemul de fișiere", + "forgot_pin_code_question": "Ai uitat codul PIN?", "forward": "Redirecționare", "gcast_enabled": "Google Cast", "gcast_enabled_description": "Această funcție încarcă resurse externe de la Google pentru a funcționa.", "general": "General", + "geolocation_instruction_location": "Apasă pe o resursă cu coordonate GPS pentru a folosi locația sa, sau selectează direct o locație de pe hartă", "get_help": "Obțineți Ajutor", "get_wifiname_error": "Nu s-a putut obține numele rețelei Wi-Fi. Asigurați-vă că ați acordat permisiunile necesare și că sunteți conectat la o rețea Wi-Fi", "getting_started": "Noțiuni de Bază", "go_back": "Întoarcere", "go_to_folder": "Accesați folderul", "go_to_search": "Spre căutare", + "gps": "GPS", + "gps_missing": "Fără GPS", "grant_permission": "Acordați permisiunea", "group_albums_by": "Grupați albume de...", "group_country": "Grupare după țară", @@ -1081,6 +1111,9 @@ "haptic_feedback_switch": "Activează feedback-ul haptic", "haptic_feedback_title": "Feedback haptic", "has_quota": "Are spațiu de stocare", + "hash_asset": "Hash-ul resursei", + "hashed_assets": "Resurse hashed", + "hashing": "Generare hash", "header_settings_add_header_tip": "Adăugați antet", "header_settings_field_validator_msg": "Valoarea nu poate fi goală", "header_settings_header_name_input": "Numele antetului", @@ -1107,11 +1140,12 @@ "home_page_favorite_err_partner": "Momentan nu se pot adăuga fișierele partenerului la favorite, omitere", "home_page_first_time_notice": "Dacă este prima dată când utilizezi aplicația, te rugăm să te asiguri că alegi unul sau mai multe albume de backup, astfel încât cronologia să poată fi populată cu fotografiile și videoclipurile din aceste albume", "home_page_locked_error_local": "Nu se pot muta resursele locale în folderul blocat, se omit", - "home_page_locked_error_partner": "Nu se pot muta materialele partenerului în folderul blocat, se omit.", + "home_page_locked_error_partner": "Nu se pot muta resursele partenerului în folderul blocat, se omit.", "home_page_share_err_local": "Nu se pot distribui fișiere locale prin link, omitere", "home_page_upload_err_limit": "Se pot încărca maxim 30 de resurse odată, omitere", "host": "Gazdă", "hour": "Oră", + "hours": "Ore", "id": "ID", "idle": "Inactiv", "ignore_icloud_photos": "Ignoră fotografiile din iCloud", @@ -1171,10 +1205,13 @@ "language_no_results_title": "Nu au fost găsite limbi", "language_search_hint": "Căutați limbi...", "language_setting_description": "Selectați limba preferată", + "large_files": "Fișiere mari", + "last": "Ultimul", "last_seen": "Văzut ultima dată", "latest_version": "Ultima Versiune", "latitude": "Latitudine", "leave": "Părăsiți", + "leave_album": "Părăsește albumul", "lens_model": "Model obiectiv", "let_others_respond": "Permite altora să răspundă", "level": "Nivel", @@ -1188,6 +1225,7 @@ "library_page_sort_title": "Titlu album", "licenses": "Licențe", "light": "Lumină", + "like": "Îmi place", "like_deleted": "Preferat șters", "link_motion_video": "Link video în mișcare", "link_to_oauth": "Link către OAuth", @@ -1198,6 +1236,7 @@ "local": "Local", "local_asset_cast_failed": "Nu se poate converti un element care nu este încărcat pe server", "local_assets": "Asset-uri locale", + "local_media_summary": "Rezumatul fișierelor media locale", "local_network": "Rețea locală", "local_network_sheet_info": "Aplicația se va conecta la server prin intermediul acestei adrese URL atunci când utilizează rețeaua Wi-Fi specificată", "location_permission": "Permisiunea de locație", @@ -1209,6 +1248,7 @@ "location_picker_longitude_hint": "Introdu longitudinea aici", "lock": "Blocare", "locked_folder": "Dosar blocat", + "log_detail_title": "Detalii jurnal", "log_out": "Deconectare", "log_out_all_devices": "Deconectați-vă de la toate dispozitivele", "logged_in_as": "Conectat ca {user}", @@ -1239,6 +1279,7 @@ "login_password_changed_success": "Parola a fost actualizată cu succes", "logout_all_device_confirmation": "Sigur doriți să deconectați toate dispozitivele?", "logout_this_device_confirmation": "Sigur doriți să deconectați acest dispozitiv?", + "logs": "Jurnale", "longitude": "Longitudine", "look": "Examinare", "loop_videos": "Buclă videoclipuri", @@ -1246,6 +1287,7 @@ "main_branch_warning": "Utilizați o versiune de dezvoltare; vă recomandăm insistent să utilizați o versiune de lansare!", "main_menu": "Meniu principal", "make": "Face", + "manage_geolocation": "Gestionați locația", "manage_shared_links": "Administrați link-urile distribuite", "manage_sharing_with_partners": "Gestionați partajarea cu partenerii", "manage_the_app_settings": "Gestionați setările aplicației", @@ -1254,7 +1296,7 @@ "manage_your_devices": "Gestionați-vă dispozitivele conectate", "manage_your_oauth_connection": "Gestionați-vă conexiunea OAuth", "map": "Hartă", - "map_assets_in_bounds": "{count, plural, one {# poză} other {# poze}}", + "map_assets_in_bounds": "{count, plural, =0 {Nu există fotografii în această zonă} one {# fotografie} other {# fotografii}}", "map_cannot_get_user_location": "Nu se poate obține locația utilizatorului", "map_location_dialog_yes": "Da", "map_location_picker_page_use_location": "Folosește această locație", @@ -1280,6 +1322,7 @@ "mark_as_read": "Marchează ca citit", "marked_all_as_read": "Marcate toate ca citite", "matches": "Corespunde", + "matching_assets": "Resurse similare", "media_type": "Tip media", "memories": "Amintiri", "memories_all_caught_up": "Sunteți la zi", @@ -1297,7 +1340,8 @@ "merge_people_successfully": "Persoane îmbinate cu succes", "merged_people_count": "Imbinate {count, plural, one {# persoană} other {# persoane}}", "minimize": "Minimizare", - "minute": "Minute", + "minute": "Minut", + "minutes": "Minute", "missing": "Lipsă", "model": "Model", "month": "Lună", @@ -1317,6 +1361,10 @@ "my_albums": "Albumele mele", "name": "Nume", "name_or_nickname": "Nume sau poreclǎ", + "network_requirement_photos_upload": "Utilizați datele mobile pentru a face copii de rezervă ale fotografiilor", + "network_requirement_videos_upload": "Utilizați datele mobile pentru a face copii de rezervă ale videoclipurilor", + "network_requirements": "Cerințe privind rețeaua", + "network_requirements_updated": "Cerințele rețelei s-au modificat, resetarea cozii copiei de rezervă", "networking_settings": "Rețele", "networking_subtitle": "Gestionați setările endpoint-ului serverului", "never": "Niciodată", @@ -1326,6 +1374,7 @@ "new_person": "Persoanǎ nouǎ", "new_pin_code": "Cod PIN nou", "new_pin_code_subtitle": "Aceasta este prima dată când accesați folderul blocat. Creați un cod PIN pentru a accesa în siguranță această pagină", + "new_timeline": "Noua cronologie", "new_user_created": "Utilizator nou creat", "new_version_available": "VERSIUNE NOUĂ DISPONIBILĂ", "newest_first": "Cel mai nou primul", @@ -1339,20 +1388,25 @@ "no_assets_message": "CLICK PENTRU A ÎNCĂRCA PRIMA TA FOTOGRAFIE", "no_assets_to_show": "Nicio resursă de afișat", "no_cast_devices_found": "Nu s-au găsit dispozitive de difuzare", + "no_checksum_local": "Nu există checksum – nu se pot prelua resursele locale", + "no_checksum_remote": "Nu există checksum – nu se pot prelua resursele la distanță", "no_duplicates_found": "Nu au fost găsite duplicate.", "no_exif_info_available": "Nu există informații exif disponibile", "no_explore_results_message": "Încarcați mai multe fotografii pentru a vă explora colecția.", "no_favorites_message": "Adăugați favorite pentru a găsi rapid cele mai bune fotografii și videoclipuri", "no_libraries_message": "Creați o bibliotecă externă pentru a vă vizualiza fotografiile și videoclipurile", + "no_local_assets_found": "Nicio resursă locală găsită cu acest checksum", "no_locked_photos_message": "Fotografiile și videoclipurile din folderul blocat sunt ascunse și nu vor apărea atunci când răsfoiți sau căutați în bibliotecă.", "no_name": "Fără Nume", "no_notifications": "Nicio notificare", "no_people_found": "Nu au fost găsite persoane potrivite căutării", "no_places": "Nu există locuri", + "no_remote_assets_found": "Nicio resursă de la distanță găsită cu acest checksum", "no_results": "Fără rezultate", "no_results_description": "Încercați un sinonim sau un cuvânt cheie mai general", "no_shared_albums_message": "Creați un album pentru a partaja fotografii și videoclipuri cu persoanele din rețeaua dvs", "no_uploads_in_progress": "Nicio încărcare în curs", + "not_available": "N/A", "not_in_any_album": "Nu există în niciun album", "not_selected": "Neselectat", "note_apply_storage_label_to_previously_uploaded assets": "Notă: Pentru a aplica eticheta de stocare la resursele încărcate anterior, rulați", @@ -1368,6 +1422,7 @@ "oauth": "OAuth", "official_immich_resources": "Resurse Oficiale Immich", "offline": "Offline", + "offset": "Decalaj", "ok": "Bine", "oldest_first": "Cel mai vechi mai întâi", "on_this_device": "Pe acest dispozitiv", @@ -1386,6 +1441,8 @@ "open_the_search_filters": "Deschideți filtrele de căutare", "options": "Opțiuni", "or": "sau", + "organize_into_albums": "Organizați în albume", + "organize_into_albums_description": "Pune fotografiile existente în albume folosind setările curente de sincronizare", "organize_your_library": "Organizează-ți biblioteca", "original": "original", "other": "Alte", @@ -1445,6 +1502,9 @@ "permission_onboarding_permission_limited": "Permisiune limitată. Pentru a permite Immich să facă copii de siguranță și să gestioneze întreaga colecție de galerii, acordă permisiuni pentru fotografii și videoclipuri în Setări.", "permission_onboarding_request": "Immich necesită permisiunea de a vizualiza fotografiile și videoclipurile tale.", "person": "Persoanǎ", + "person_age_months": "{months, plural, one {# month} other {# months}} vechime", + "person_age_year_months": "1 year, {months, plural, one {# month} other {# months}} vechime", + "person_age_years": "{years, plural, other {# years}} vechime", "person_birthdate": "Născut pe {date}", "person_hidden": "{name}{hidden, select, true { (ascuns)} other {}}", "photo_shared_all_users": "Se pare că ți-ai partajat fotografiile tuturor utilizatorilor sau că nu ai niciun utilizator căruia să le distribui.", @@ -1468,6 +1528,7 @@ "port": "Port", "preferences_settings_subtitle": "Gestionați preferințele aplicației", "preferences_settings_title": "Preferințe", + "preparing": "Se prepară", "preset": "Presetat", "preview": "Previzualizare", "previous": "Anterior", @@ -1484,6 +1545,7 @@ "profile_drawer_client_out_of_date_minor": "Aplicația nu folosește ultima versiune. Te rugăm să actualizezi la ultima versiune minoră.", "profile_drawer_client_server_up_to_date": "Aplicația client și server-ul sunt actualizate", "profile_drawer_github": "GitHub", + "profile_drawer_readonly_mode": "Mod doar citire activat. Ține apăsat pe pictograma avatarului utilizatorului pentru a ieși.", "profile_drawer_server_out_of_date_major": "Server-ul nu folosește ultima versiune. Te rugăm să actualizezi la ultima versiune majoră.", "profile_drawer_server_out_of_date_minor": "Server-ul nu folosește ultima versiune. Te rugăm să actulizezi la ultima versiune minoră.", "profile_image_of_user": "Imagine de profil a lui {user}", @@ -1522,6 +1584,7 @@ "purchase_server_description_2": "Statutul de suporter", "purchase_server_title": "Server", "purchase_settings_server_activated": "Cheia de produs a serverului este gestionată de administrator", + "query_asset_id": "Interoghează ID-ul resursei", "queue_status": "Se pun în coadă {count}/{total}", "rating": "Evaluare cu stele", "rating_clear": "Anulați evaluarea", @@ -1529,6 +1592,9 @@ "rating_description": "Afișați evaluarea EXIF în panoul de informații", "reaction_options": "Opțiuni de reacție", "read_changelog": "Citiți Jurnalul de Modificări", + "readonly_mode_disabled": "Modul doar citire dezactivat", + "readonly_mode_enabled": "Modul doar citire activat", + "ready_for_upload": "Pregătit pentru încărcare", "reassign": "Reatribuiți", "reassigned_assets_to_existing_person": "Re-alocat {count, plural, one {# resursă} other {# resurse}} to {name, select, null {unei persoane existente} other {{name}}}", "reassigned_assets_to_new_person": "Re-alocat {count, plural, one {# resursă} other {# resurse}} unei noi persoane", @@ -1553,6 +1619,7 @@ "regenerating_thumbnails": "Se regenerează miniaturile", "remote": "De la distanță", "remote_assets": "Elemente la distanță", + "remote_media_summary": "Rezumat media de la distanță", "remove": "Eliminați", "remove_assets_album_confirmation": "Sigur doriți să eliminați {count, plural, one {# resursă} other {# resurse}} din album?", "remove_assets_shared_link_confirmation": "Sigur doriți să eliminați {count, plural, one {# resursă} other {# resurse}} din acest link comun?", @@ -1590,6 +1657,9 @@ "reset_password": "Resetare parolă", "reset_people_visibility": "Resetați vizibilitatea persoanelor", "reset_pin_code": "Resetare cod PIN", + "reset_pin_code_description": "Dacă ți-ai uitat codul PIN, poți contacta administratorul serverului pentru a-l reseta", + "reset_pin_code_success": "Codul PIN a fost resetat cu succes", + "reset_pin_code_with_password": "Puteți reseta oricând codul PIN cu ajutorul parolei", "reset_sqlite": "Resetare bază de date SQLite", "reset_sqlite_confirmation": "Sigur doriți să resetați baza de date SQLite? Va trebui să vă deconectați și să vă conectați din nou pentru a resincroniza datele", "reset_sqlite_success": "Resetarea cu succes a bazei de date SQLite", @@ -1602,8 +1672,10 @@ "restore_user": "Restabiliți utilizatorul", "restored_asset": "Resursă restaurată", "resume": "Reluare", + "resume_paused_jobs": "Reluați {count, plural, one {# paused job} other {# paused jobs}}", "retry_upload": "Reîncercați încărcarea", "review_duplicates": "Examinați duplicatele", + "review_large_files": "Revizuirea fișierelor mari", "role": "Rol", "role_editor": "Editor", "role_viewer": "Vizualizator", @@ -1615,7 +1687,7 @@ "saved_settings": "Setări salvate", "say_something": "Spuneți ceva", "scaffold_body_error_occurred": "A apărut o eroare", - "scan_all_libraries": "Scanați Toate Bibliotecile", + "scan_all_libraries": "Scanați toate bibliotecile", "scan_library": "Scanare", "scan_settings": "Setări Scanare", "scanning_for_album": "Se scanează după album...", @@ -1694,6 +1766,7 @@ "select_user_for_sharing_page_err_album": "Creare album eșuată", "selected": "Selectat", "selected_count": "{count, plural, other {# selectat}}", + "selected_gps_coordinates": "Coordonate GPS selectate", "send_message": "Trimiteți mesaj", "send_welcome_email": "Trimiteți email de bun venit", "server_endpoint": "Endpoint server", @@ -1702,7 +1775,7 @@ "server_offline": "Serverul este offline", "server_online": "Server online", "server_privacy": "Confidențialitatea serverului", - "server_stats": "Statistici Server", + "server_stats": "Statistici server", "server_version": "Versiune Server", "set": "Setați", "set_as_album_cover": "Setați ca și copertă a albumului", @@ -1761,6 +1834,7 @@ "shared_link_clipboard_copied_massage": "Copiat în clipboard", "shared_link_clipboard_text": "Link: {link}\nParolă: {password}", "shared_link_create_error": "Eroare în timpul creării linkului de distribuire", + "shared_link_custom_url_description": "Accesează acest link partajat cu un URL personalizat", "shared_link_edit_description_hint": "Introdu descrierea distribuirii", "shared_link_edit_expire_after_option_day": "1 zi", "shared_link_edit_expire_after_option_days": "{count} zile", @@ -1786,6 +1860,7 @@ "shared_link_info_chip_metadata": "EXIF", "shared_link_manage_links": "Administrează link-urile distribuite", "shared_link_options": "Opțiuni de link partajat", + "shared_link_password_description": "Solicită o parolă pentru a accesa acest link partajat", "shared_links": "Link-uri distribuite", "shared_links_description": "Partajare imagini și clipuri printr-un link", "shared_photos_and_videos_count": "{assetCount, plural, other {# fotografii și videoclipuri partajate.}}", @@ -1820,6 +1895,7 @@ "show_slideshow_transition": "Afișați tranziția de prezentare", "show_supporter_badge": "Insigna suporterului", "show_supporter_badge_description": "Arată o insignă de suporter", + "show_text_search_menu": "Afișează meniul de căutare text", "shuffle": "Amestecați", "sidebar": "Bara laterală", "sidebar_display_description": "Afișați un link către vizualizare în bara laterală", @@ -1835,6 +1911,7 @@ "sort_created": "Data creării", "sort_items": "Numărul de articole", "sort_modified": "Data modificării", + "sort_newest": "Cea mai nouă fotografie", "sort_oldest": "Cea mai veche fotografie", "sort_people_by_similarity": "Sortează oameni după asemanare", "sort_recent": "Cea mai recentă fotografie", @@ -1849,6 +1926,7 @@ "stacktrace": "Urmă stivă", "start": "Început", "start_date": "Data de începere", + "start_date_before_end_date": "Data de început trebuie să fie înainte de data de sfârșit", "state": "Situaţie", "status": "Stare", "stop_casting": "Opriți difuzarea", @@ -1873,6 +1951,8 @@ "sync_albums_manual_subtitle": "Sincronizează toate videoclipurile și fotografiile încărcate cu albumele de rezervă selectate", "sync_local": "Sincronizare locală", "sync_remote": "Sincronizare la distanță", + "sync_status": "Status-ul sincronizării", + "sync_status_subtitle": "Vizualizează și gestionează sistemul de sincronizare", "sync_upload_album_setting_subtitle": "Creează și încarcă fotografiile și videoclipurile tale în albumele selectate de pe Immich", "tag": "Etichetă", "tag_assets": "Eticheta resurselor", @@ -1910,7 +1990,9 @@ "to_change_password": "Schimbaţi parola", "to_favorite": "Favorit", "to_login": "Conectare", + "to_multi_select": "pentru selecție multiplă", "to_parent": "Du-te la părinte", + "to_select": "a selecta", "to_trash": "Coș de gunoi", "toggle_settings": "Activați setările", "total": "Total", @@ -1930,6 +2012,7 @@ "trash_page_select_assets_btn": "Selectează resurse", "trash_page_title": "Coș ({count})", "trashed_items_will_be_permanently_deleted_after": "Elementele din coșul de gunoi vor fi șterse definitiv după {days, plural, one {# zi} other {# zile}}.", + "troubleshoot": "Depanați", "type": "Tip", "unable_to_change_pin_code": "Nu se poate schimba codul PIN", "unable_to_setup_pin_code": "Nu se poate configura codul PIN", @@ -1956,10 +2039,11 @@ "unselect_all_duplicates": "Deselectați toate duplicatele", "unselect_all_in": "Deselectați toate din {group}", "unstack": "Dezasamblați", - "unstack_action_prompt": "{count} unstacked", + "unstack_action_prompt": "{count} neîmpachetate", "unstacked_assets_count": "Nestivuit {count, plural, one {# resursă} other {# resurse}}", "untagged": "Neetichetat", "up_next": "Mai departe", + "update_location_action_prompt": "Actualizează locația pentru {count} resurse selectate cu:", "updated_at": "Actualizat", "updated_password": "Parolă actualizată", "upload": "Încărcați", @@ -2026,13 +2110,14 @@ "view_next_asset": "Vizualizați următoarea resursă", "view_previous_asset": "Vizualizați resursa anterioară", "view_qr_code": "Vezi cod QR", + "view_similar_photos": "Vizualizați poze similare", "view_stack": "Vizualizați Stiva", "view_user": "Vizualizare utilizator", "viewer_remove_from_stack": "Șterge din grup", "viewer_stack_use_as_main_asset": "Folosește ca resursă principală", "viewer_unstack": "Anulează grup", "visibility_changed": "Vizibilitatea schimbată pentru {count, plural, one {# persoană} other {# persoane}}", - "waiting": "Așteptați", + "waiting": "În așteptare", "warning": "Avertisment", "week": "Sǎptǎmânǎ", "welcome": "Bun venit", @@ -2044,5 +2129,6 @@ "yes": "Da", "you_dont_have_any_shared_links": "Nu aveți linkuri partajate", "your_wifi_name": "Numele rețelei tale WiFi", - "zoom_image": "Măriți Imaginea" + "zoom_image": "Măriți Imaginea", + "zoom_to_bounds": "Mărește la margini" } diff --git a/i18n/ru.json b/i18n/ru.json index 287f0288bd..f17b5ce364 100644 --- a/i18n/ru.json +++ b/i18n/ru.json @@ -7,7 +7,7 @@ "action_common_update": "Обновить", "actions": "Действия", "active": "Выполняется", - "activity": "Активность", + "activity": "Действия", "activity_changed": "Активность {enabled, select, true {включена} other {отключена}}", "add": "Добавить", "add_a_description": "Добавить описание", @@ -26,8 +26,9 @@ "add_tag": "Добавить тег", "add_to": "Добавить в…", "add_to_album": "Добавить в альбом", - "add_to_album_bottom_sheet_added": "Добавлено в {album}", - "add_to_album_bottom_sheet_already_exists": "Уже в {album}", + "add_to_album_bottom_sheet_added": "Добавлено в альбом {album}", + "add_to_album_bottom_sheet_already_exists": "Уже в альбоме {album}", + "add_to_album_bottom_sheet_some_local_assets": "Некоторые объекты не добавлены в альбом, поскольку еще не загружены на сервер", "add_to_album_toggle": "Переключить выделение для альбома {album}", "add_to_albums": "Добавить в альбомы", "add_to_albums_count": "Добавить в альбомы ({count})", @@ -39,7 +40,7 @@ "admin": { "add_exclusion_pattern_description": "Добавьте шаблоны исключений. Поддерживаются символы подстановки *, ** и ?. Чтобы игнорировать все файлы в любом каталоге с именем \"Raw\", укажите \"**/Raw/**\". Чтобы игнорировать все файлы, заканчивающиеся на \".tif\", используйте \"**/*.tif\". Чтобы игнорировать путь целиком, укажите \"/path/to/ignore/**\".", "admin_user": "Администратор", - "asset_offline_description": "Этот файл внешней библиотеки не был найден на диске и был перемещён в корзину. Если файл был перемещён внутри библиотеки, проверьте временную шкалу, чтобы найти новый соответствующий ресурс. Чтобы восстановить файл, убедитесь, что путь ниже доступен для Immich и выполните сканирование библиотеки.", + "asset_offline_description": "Этот объект из внешней библиотеки не был обнаружен на диске и поэтому перемещён в корзину. Если файл объекта был перемещён внутри библиотеки, проверьте временную шкалу, чтобы найти новый соответствующий объект. Чтобы восстановить файл, убедитесь, что следующий путь доступен для Immich, и выполните сканирование библиотеки.", "authentication_settings": "Настройки аутентификации", "authentication_settings_description": "Управление паролями, OAuth и другими настройками аутентификации", "authentication_settings_disable_all": "Вы уверены, что хотите отключить все методы входа? Вход будет полностью отключен.", @@ -65,9 +66,9 @@ "confirm_reprocess_all_faces": "Вы уверены, что хотите повторно определить все лица? Будут также удалены имена со всех лиц.", "confirm_user_password_reset": "Вы действительно хотите сбросить пароль пользователя {user}?", "confirm_user_pin_code_reset": "Вы действительно хотите сбросить PIN-код пользователя {user}?", - "create_job": "Создать задание", + "create_job": "Создать задачу", "cron_expression": "Расписание (выражение планировщика cron)", - "cron_expression_description": "Частота и время выполнения задания в формате планировщика cron. Воспользуйтесь при необходимости визуальным редактором Crontab Guru", + "cron_expression_description": "Частота и время выполнения задачи в формате планировщика cron. Воспользуйтесь при необходимости визуальным редактором Crontab Guru", "cron_expression_presets": "Расписание (предустановленные варианты)", "disable_login": "Отключить вход", "duplicate_detection_job_description": "Запускает определение похожих изображений при помощи машинного зрения (зависит от умного поиска)", @@ -77,7 +78,7 @@ "face_detection_description": "Обнаруживает лица на объектах с использованием машинного обучения. Для видео анализируется только миниатюра. Кнопка \"Обновить\" запускает повторную обработку всех объектов. \"Сброс\" — дополнительно удаляет все имеющиеся данные о лицах. \"Отсутствующие\" — ставит в очередь объекты, которые ещё не были обработаны. Обнаруженные лица помещаются в очередь для задачи Распознавание лиц и последующей их привязки к существующим или новым людям.", "facial_recognition_job_description": "Группирует и назначает обнаруженные лица людям. Выполняется после завершения задачи Обнаружение лиц. Кнопка \"Сброс\" (пере)назначает все лица. \"Отсутствующие\" — добавляет в очередь обработки лица, не привязанные к человеку.", "failed_job_command": "Команда {command} не выполнена для задачи: {job}", - "force_delete_user_warning": "ПРЕДУПРЕЖДЕНИЕ: Это приведет к немедленному удалению пользователя и его ресурсов. Это действие невозможно отменить, и файлы не могут быть восстановлены.", + "force_delete_user_warning": "ПРЕДУПРЕЖДЕНИЕ: Это приведет к немедленному удалению пользователя и всех его объектов. Это действие невозможно отменить, файлы не смогут быть восстановлены.", "image_format": "Формат", "image_format_description": "WebP создает файлы меньшего размера, чем JPEG, но кодирует медленнее.", "image_fullsize_description": "Полноразмерное изображение без метаданных, используется при увеличении", @@ -100,11 +101,11 @@ "image_thumbnail_description": "Маленькая миниатюра с удаленными метаданными, используемая при просмотре групп фотографий, таких как основная временная шкала", "image_thumbnail_quality_description": "Качество миниатюр от 1 до 100. Чем выше качество, тем лучше, но при этом создаются файлы большего размера и может снизиться скорость отклика приложения.", "image_thumbnail_title": "Настройки миниатюр", - "job_concurrency": "Параллельная обработка задания - {job}", - "job_created": "Задание создано", + "job_concurrency": "Число параллельных потоков задачи {job}", + "job_created": "Задача создана", "job_not_concurrency_safe": "Эта задача не обеспечивает безопасность параллельности выполнения.", - "job_settings": "Настройки заданий", - "job_settings_description": "Управление параллельной обработкой заданий", + "job_settings": "Настройки задач", + "job_settings_description": "Управление параллельностью выполнения задач", "job_status": "Состояние выполнения задач", "jobs_delayed": "{jobCount, plural, one {# отложена} other {# отложено}}", "jobs_failed": "{jobCount, plural, other {# не удалось выполнить}}", @@ -123,20 +124,27 @@ "logging_enable_description": "Включить ведение журнала", "logging_level_description": "Если включено, выберите желаемый уровень журналирования.", "logging_settings": "Ведение журнала", + "machine_learning_availability_checks": "Проверка доступности", + "machine_learning_availability_checks_description": "Автоматически определять и использовать доступные серверы машинного обучения", + "machine_learning_availability_checks_enabled": "Включить проверку доступности", + "machine_learning_availability_checks_interval": "Интервал проверки", + "machine_learning_availability_checks_interval_description": "Интервал в миллисекундах между проверками", + "machine_learning_availability_checks_timeout": "Тайм-аут запроса", + "machine_learning_availability_checks_timeout_description": "Время ожидания ответа сервера в миллисекундах для определения доступности", "machine_learning_clip_model": "CLIP модель", - "machine_learning_clip_model_description": "Названия моделей CLIP размещены здесь. Обратите внимание, что при изменении модели необходимо заново запустить задачу «Интеллектуальный поиск» для всех изображений.", + "machine_learning_clip_model_description": "Названия доступных CLIP моделей размещены здесь.\nПри изменении модели необходимо заново запустить задачу «Интеллектуальный поиск» для всех объектов.", "machine_learning_duplicate_detection": "Поиск дубликатов", "machine_learning_duplicate_detection_enabled": "Включить обнаружение дубликатов", - "machine_learning_duplicate_detection_enabled_description": "Если этот параметр отключен, абсолютно идентичные файлы всё равно будут удалены из дубликатов.", - "machine_learning_duplicate_detection_setting_description": "Используйте встраивания CLIP для поиска вероятных дубликатов", - "machine_learning_enabled": "Включите машинное обучение", - "machine_learning_enabled_description": "При отключении, все функции ML будут отключены независимо от следующих параметров.", + "machine_learning_duplicate_detection_enabled_description": "Если этот параметр отключён, абсолютно идентичные файлы всё равно не будут загружаться.", + "machine_learning_duplicate_detection_setting_description": "Использование CLIP моделей для выявления возможных дубликатов", + "machine_learning_enabled": "Включить машинное обучение", + "machine_learning_enabled_description": "При выключении будут отключены все функции ML независимо от следующих параметров.", "machine_learning_facial_recognition": "Распознавание лиц", "machine_learning_facial_recognition_description": "Обнаруживать, распознавать и группировать лица на изображениях", "machine_learning_facial_recognition_model": "Модель для распознавания лиц", - "machine_learning_facial_recognition_model_description": "Модели перечислены в порядке убывания размера. Большие модели работают медленнее и используют больше памяти, но дают лучшие результаты. Обратите внимание, что при смене модели необходимо повторно запустить задание распознавания лиц для всех изображений.", + "machine_learning_facial_recognition_model_description": "Модели перечислены в порядке убывания их размера. Большие модели работают медленнее и используют больше памяти, но дают лучшие результаты. При смене модели необходимо повторно запустить задачу распознавания лиц для всех изображений.", "machine_learning_facial_recognition_setting": "Включить функцию распознавания лиц", - "machine_learning_facial_recognition_setting_description": "Если отключить эту функцию, изображения не будут кодироваться для распознавания лиц и не будут заполнять раздел Люди на обзорной странице.", + "machine_learning_facial_recognition_setting_description": "При отключении этой функции изображения не будут кодироваться для распознавания лиц, и не будет заполняться раздел Люди.", "machine_learning_max_detection_distance": "Максимальное различие изображений", "machine_learning_max_detection_distance_description": "Максимальное различие между двумя изображениями, чтобы считать их дубликатами, в диапазоне 0,001-0,1. Более высокие значения позволяют обнаружить больше дубликатов, но могут привести к ложным срабатываниям.", "machine_learning_max_recognition_distance": "Порог распознавания", @@ -146,13 +154,13 @@ "machine_learning_min_recognized_faces": "Минимум распознанных лиц", "machine_learning_min_recognized_faces_description": "Минимальное количество распознанных лиц для создания человека. Увеличение этого параметра делает распознавание лиц более точным, но при этом увеличивается вероятность того, что лицо не будет присвоено человеку.", "machine_learning_settings": "Настройки машинного обучения", - "machine_learning_settings_description": "Управление функциями и настройками машинного обучения", + "machine_learning_settings_description": "Управление функциями и настройками машинного обучения (ML)", "machine_learning_smart_search": "Интеллектуальный поиск", - "machine_learning_smart_search_description": "Семантический поиск изображений с использованием вложений CLIP", + "machine_learning_smart_search_description": "Семантический (контекстный) поиск объектов с использованием CLIP моделей", "machine_learning_smart_search_enabled": "Включить интеллектуальный поиск", - "machine_learning_smart_search_enabled_description": "Если этот параметр отключен, изображения не будут кодироваться для интеллектуального поиска.", + "machine_learning_smart_search_enabled_description": "При отключении этой функции изображения не будут кодироваться для интеллектуального поиска.", "machine_learning_url_description": "URL-адрес сервера машинного обучения. Если указано несколько, запросы будут отправляться по очереди на каждый, пока от одного из них не будет получен успешный ответ. Серверы, которые не отвечают, будут временно игнорироваться до тех пор, пока не станут снова доступны.", - "manage_concurrency": "Управление параллельностью заданий", + "manage_concurrency": "Управление параллельностью", "manage_log_settings": "Управление настройками журнала", "map_dark_style": "Тёмный стиль", "map_enable_description": "Включить функции карты", @@ -170,9 +178,9 @@ "memory_cleanup_job": "Очистка воспоминаний", "memory_generate_job": "Создание воспоминаний", "metadata_extraction_job": "Извлечение метаданных", - "metadata_extraction_job_description": "Извлекает метаданные из каждого файла, такие как местоположение, лица и разрешение", + "metadata_extraction_job_description": "Извлечение метаданных из файлов, таких как местоположение, лица и разрешение", "metadata_faces_import_setting": "Включить импорт лиц", - "metadata_faces_import_setting_description": "Импорт лиц из изображений EXIF-данных и файлов sidecar", + "metadata_faces_import_setting_description": "Импорт лиц из EXIF-данных и файлов sidecar", "metadata_settings": "Настройки метаданных", "metadata_settings_description": "Управление настройками метаданных", "migration_job": "Миграция", @@ -247,7 +255,7 @@ "reset_settings_to_default": "Сброс настроек до значений по умолчанию", "reset_settings_to_recent_saved": "Не сохранённые изменения сброшены к последним сохраненным значениям", "scanning_library": "Сканирование библиотеки", - "search_jobs": "Поиск заданий…", + "search_jobs": "Поиск задач…", "send_welcome_email": "Отправить приветственное письмо", "server_external_domain_settings": "Внешний домен", "server_external_domain_settings_description": "Домен для публичных ссылок, включая http(s)://", @@ -268,8 +276,8 @@ "storage_template_hash_verification_enabled_description": "Включает проверку хеша, не отключайте её, если не уверены в последствиях", "storage_template_migration": "Применение шаблона хранилища", "storage_template_migration_description": "Применяет текущий {template} к ранее загруженным объектам", - "storage_template_migration_info": "Расширения файлов всегда будут сохраняться в нижнем регистре. Изменения в шаблоне будут применяться только к новым ресурсам. Чтобы применить шаблон к ранее загруженным ресурсам, запустите {job}.", - "storage_template_migration_job": "Задание по применению шаблона хранилища", + "storage_template_migration_info": "Расширения файлов всегда будут сохраняться в нижнем регистре. Изменения в шаблоне будут применяться только к новым объектам. Чтобы применить шаблон к ранее загруженным объектам, запустите {job}.", + "storage_template_migration_job": "Задача по применению шаблона хранилища", "storage_template_more_details": "Для получения дополнительной информации об этой функции обратитесь к разделам документации Шаблон хранилища и Структура хранения файлов", "storage_template_onboarding_description_v2": "Если эта функция включена, она автоматически организует файлы на основе заданного пользователем шаблона. Для получения дополнительной информации обратитесь к документации.", "storage_template_path_length": "Примерный предел длины пути: {length, number}/{limit, number}", @@ -364,7 +372,7 @@ "user_cleanup_job": "Очистка пользователя", "user_delete_delay": "Аккаунт и файлы пользователя {user} будут отложены до окончательного удаления через {delay, plural, one {# день} few {# дня} many {# дней} other {# дня}}.", "user_delete_delay_settings": "Отложенное удаление", - "user_delete_delay_settings_description": "Срок в днях, по истечение которого происходит окончательное удаление учетной записи пользователя и его ресурсов. Задача по удалению пользователей выполняется в полночь. Изменения этой настройки будут учтены при следующем запуске задачи.", + "user_delete_delay_settings_description": "Срок в днях, по истечении которого происходит окончательное удаление учётной записи пользователя и всех его объектов. Задача по удалению пользователей выполняется в полночь. Изменение этой настройки будет учтено при следующем запуске задачи.", "user_delete_immediately": "Аккаунт и файлы пользователя {user} будут немедленно поставлены в очередь для окончательного удаления.", "user_delete_immediately_checkbox": "Поместить пользователя и его файлы в очередь для немедленного удаления", "user_details": "Данные пользователя", @@ -387,8 +395,6 @@ "admin_password": "Пароль администратора", "administration": "Управление сервером", "advanced": "Расширенные", - "advanced_settings_beta_timeline_subtitle": "Попробуйте новый функционал приложения", - "advanced_settings_beta_timeline_title": "Бета-версия временной шкалы", "advanced_settings_enable_alternate_media_filter_subtitle": "Подбор объектов для синхронизации на основе альтернативных критериев. Пробуйте включать только в том случае, если в приложении есть проблемы с обнаружением всех альбомов.", "advanced_settings_enable_alternate_media_filter_title": "[ЭКСПЕРИМЕНТАЛЬНО] Использование альтернативного способа синхронизации альбомов на устройстве", "advanced_settings_log_level_title": "Уровень логирования: {level}", @@ -403,8 +409,8 @@ "advanced_settings_sync_remote_deletions_subtitle": "Автоматически удалять или восстанавливать объекты на этом устройстве, когда это действие выполняется через веб-интерфейс", "advanced_settings_sync_remote_deletions_title": "[ЭКСПЕРИМЕНТАЛЬНО] Синхронизация удаления объектов", "advanced_settings_tile_subtitle": "Расширенные настройки", - "advanced_settings_troubleshooting_subtitle": "Включить расширенные возможности для решения проблем", - "advanced_settings_troubleshooting_title": "Решение проблем", + "advanced_settings_troubleshooting_subtitle": "Включить расширенные возможности для диагностики и решения проблем", + "advanced_settings_troubleshooting_title": "Режим диагностики", "age_months": "{months, plural, one {# месяц} many {# месяцев} other {# месяца}}", "age_year_months": "1 год {months, plural, one {# месяц} many {# месяцев} other {# месяца}}", "age_years": "{years, plural, one {# год} many {# лет} other {# года}}", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "Вы уверены, что хотите удалить пользователя {user}?", "album_search_not_found": "Не найдено альбомов по вашему запросу", "album_share_no_users": "Нет доступных пользователей, с которыми можно поделиться альбомом.", + "album_summary": "Информация об альбоме", "album_updated": "Альбом обновлён", "album_updated_setting_description": "Получать уведомление по электронной почте при добавлении новых объектов в общий альбом", "album_user_left": "Вы покинули {album}", @@ -496,10 +503,12 @@ "asset_restored_successfully": "Объект успешно восстановлен", "asset_skipped": "Пропущено", "asset_skipped_in_trash": "В корзине", + "asset_trashed": "Объект удалён", + "asset_troubleshoot": "Данные для диагностики", "asset_uploaded": "Загружено", "asset_uploading": "Загрузка…", - "asset_viewer_settings_subtitle": "Настройка параметров отображения", - "asset_viewer_settings_title": "Просмотр изображений", + "asset_viewer_settings_subtitle": "Параметры отображения", + "asset_viewer_settings_title": "Просмотр объектов", "assets": "Объекты", "assets_added_count": "{count, plural, one {Добавлен # объект} many {Добавлено # объектов} other {Добавлено # объекта}}", "assets_added_to_album_count": "В альбом {count, plural, one {добавлен # объект} many {добавлено # объектов} other {добавлено # объекта}}", @@ -529,8 +538,10 @@ "autoplay_slideshow": "Автовоспроизведение слайдшоу", "back": "Назад", "back_close_deselect": "Назад, закрыть или отменить выбор", + "background_backup_running_error": "Выполняется фоновое резервное копирование, запуск вручную пока невозможен", "background_location_permission": "Доступ к местоположению в фоне", "background_location_permission_content": "Чтобы считывать имя Wi-Fi сети в фоне, приложению *всегда* необходим доступ к точному местоположению устройства", + "background_options": "Выполнение фоновых задач", "backup": "Резервное копирование", "backup_album_selection_page_albums_device": "Альбомы на устройстве ({count})", "backup_album_selection_page_albums_tap": "Нажмите, чтобы включить, дважды, чтобы исключить", @@ -538,6 +549,7 @@ "backup_album_selection_page_select_albums": "Выбор альбомов", "backup_album_selection_page_selection_info": "Выбранные альбомы", "backup_album_selection_page_total_assets": "Всего уникальных объектов", + "backup_albums_sync": "Синхронизация альбомов", "backup_all": "Все", "backup_background_service_backup_failed_message": "Не удалось выполнить резервное копирование. Повторная попытка…", "backup_background_service_connection_failed_message": "Не удалось подключиться к серверу. Повторная попытка…", @@ -556,7 +568,7 @@ "backup_controller_page_background_battery_info_title": "Оптимизация батареи", "backup_controller_page_background_charging": "Только во время зарядки", "backup_controller_page_background_configure_error": "Не удалось настроить фоновую службу", - "backup_controller_page_background_delay": "Отложить резервное копирование новых объектов: {duration}", + "backup_controller_page_background_delay": "Задержка перед загрузкой новых объектов: {duration}", "backup_controller_page_background_description": "Включите фоновую службу для автоматического резервного копирования любых новых объектов без необходимости открывать приложение", "backup_controller_page_background_is_off": "Автоматическое резервное копирование в фоновом режиме отключено", "backup_controller_page_background_is_on": "Автоматическое резервное копирование в фоновом режиме включено", @@ -573,7 +585,7 @@ "backup_controller_page_filename": "Имя файла: {filename} [{size}]", "backup_controller_page_id": "ID: {id}", "backup_controller_page_info": "Информация о резервном копировании", - "backup_controller_page_none_selected": "Ничего не выбрано", + "backup_controller_page_none_selected": "Не выбрано", "backup_controller_page_remainder": "Осталось", "backup_controller_page_remainder_sub": "Фото и видео для загрузки", "backup_controller_page_server_storage": "Хранилище на сервере", @@ -587,6 +599,7 @@ "backup_controller_page_turn_on": "Включить", "backup_controller_page_uploading_file_info": "Информация о загружаемом файле", "backup_err_only_album": "Невозможно удалить единственный альбом", + "backup_error_sync_failed": "Сбой синхронизации. Невозможно запустить резервное копирование.", "backup_info_card_assets": "объектов", "backup_manual_cancelled": "Отменено", "backup_manual_in_progress": "Загрузка в процессе. Попробуйте позже", @@ -654,6 +667,8 @@ "change_pin_code": "Изменить PIN-код", "change_your_password": "Изменить свой пароль", "changed_visibility_successfully": "Видимость успешно изменена", + "charging": "При зарядке", + "charging_requirement_mobile_backup": "Запускать резервное копирование только во время зарядки", "check_corrupt_asset_backup": "Проверка поврежденных резервных копий", "check_corrupt_asset_backup_button": "Проверить", "check_corrupt_asset_backup_description": "Запускайте проверку только через Wi-Fi и после создания резервной копии всех объектов. Операция может занять несколько минут.", @@ -681,8 +696,8 @@ "color": "Цвет", "color_theme": "Цветовая тема", "comment_deleted": "Комментарий удалён", - "comment_options": "Параметры комментариев", - "comments_and_likes": "Комментарии и лайки", + "comment_options": "Действия с комментарием", + "comments_and_likes": "Комментарии и отметки \"нравится\"", "comments_are_disabled": "Комментарии отключены", "common_create_new_album": "Создать новый альбом", "common_server_error": "Пожалуйста, проверьте подключение к сети и убедитесь, что ваш сервер доступен, а версии приложения и сервера — совместимы.", @@ -690,7 +705,7 @@ "confirm": "Подтвердить", "confirm_admin_password": "Подтвердите пароль администратора", "confirm_delete_face": "Удалить лицо человека {name} из этого объекта?", - "confirm_delete_shared_link": "Вы уверены, что хотите удалить эту публичную ссылку?", + "confirm_delete_shared_link": "Вы действительно хотите удалить эту публичную ссылку?", "confirm_keep_this_delete_others": "Все остальные объекты в группе будут удалены, кроме этого объекта. Вы уверены, что хотите продолжить?", "confirm_new_pin_code": "Подтвердите новый PIN-код", "confirm_password": "Подтвердите пароль", @@ -706,12 +721,12 @@ "control_bottom_app_bar_delete_from_local": "Удалить с устройства", "control_bottom_app_bar_edit_location": "Изменить место", "control_bottom_app_bar_edit_time": "Изменить дату", - "control_bottom_app_bar_share_link": "Поделиться ссылкой", + "control_bottom_app_bar_share_link": "Создать ссылку", "control_bottom_app_bar_share_to": "Поделиться с", "control_bottom_app_bar_trash_from_immich": "В корзину", "copied_image_to_clipboard": "Изображение скопировано в буфер обмена.", "copied_to_clipboard": "Скопировано в буфер обмена!", - "copy_error": "Ошибка копирования", + "copy_error": "Скопировать ошибку", "copy_file_path": "Копировать путь к файлу", "copy_image": "Копировать", "copy_link": "Копировать ссылку", @@ -727,7 +742,7 @@ "create_library": "Создать библиотеку", "create_link": "Создать ссылку", "create_link_to_share": "Создать ссылку общего доступа", - "create_link_to_share_description": "Разрешить всем, у кого есть ссылка, просмотреть выбранные фотографии", + "create_link_to_share_description": "Разрешить всем, у кого есть ссылка, просматривать выбранные фотографии", "create_new": "СОЗДАТЬ НОВЫЙ", "create_new_person": "Добавить нового человека", "create_new_person_hint": "Назначить выбранные объекты на нового человека", @@ -740,6 +755,7 @@ "create_user": "Создать пользователя", "created": "Создан", "created_at": "Создан", + "creating_linked_albums": "Создание связанных альбомов...", "crop": "Обрезать", "curated_object_page_title": "Предметы", "current_device": "Текущее устройство", @@ -751,7 +767,7 @@ "daily_title_text_date": "E, MMM dd", "daily_title_text_date_year": "E, MMM dd, yyyy", "dark": "Тёмная", - "dark_theme": "Тёмная тема", + "dark_theme": "Включить/выключить тёмную тему", "date_after": "Дата после", "date_and_time": "Дата и Время", "date_before": "Дата до", @@ -809,7 +825,7 @@ "discovered_devices": "Обнаруженные устройства", "dismiss_all_errors": "Сбросить все ошибки", "dismiss_error": "Сбросить ошибку", - "display_options": "Настройки отображения", + "display_options": "Дополнительно", "display_order": "Порядок отображения", "display_original_photos": "Отображение оригинальных фотографий", "display_original_photos_setting_description": "Открывать при просмотре оригинал фотографии вместо миниатюры, если исходный формат поддерживается браузером. Возможно снижение скорости отображения фотографий.", @@ -841,11 +857,11 @@ "duplicates": "Дубликаты", "duplicates_description": "Просмотрите найденные дубликаты и в каждой группе укажите, какие объекты оставить, а какие удалить", "duration": "Продолжительность", - "edit": "Редактировать", - "edit_album": "Редактировать альбом", + "edit": "Изменить", + "edit_album": "Изменить альбом", "edit_avatar": "Изменить аватар", "edit_birthday": "Изменить дату рождения", - "edit_date": "редактировать дату", + "edit_date": "Изменить дату", "edit_date_and_time": "Изменить дату и время", "edit_date_and_time_action_prompt": "Дата и время изменены у {count} объектов", "edit_date_and_time_by_offset": "Изменить дату по смещению", @@ -857,14 +873,14 @@ "edit_import_path": "Изменить путь импорта", "edit_import_paths": "Изменить путь импорта", "edit_key": "Изменить ключ", - "edit_link": "Редактировать ссылку", - "edit_location": "Редактировать местоположение", + "edit_link": "Изменить ссылку", + "edit_location": "Изменить местоположение", "edit_location_action_prompt": "Места изменены ({count} шт.)", "edit_location_dialog_title": "Местоположение", - "edit_name": "Редактировать имя", - "edit_people": "Редактировать людей", + "edit_name": "Изменить имя", + "edit_people": "Изменить людей", "edit_tag": "Изменить тег", - "edit_title": "Редактировать Заголовок", + "edit_title": "Изменить заголовок", "edit_user": "Изменить пользователя", "edited": "Отредактировано", "editor": "Редактор", @@ -878,7 +894,7 @@ "empty_trash": "Очистить корзину", "empty_trash_confirmation": "Вы действительно хотите очистить корзину? Все объекты в ней будут навсегда удалены из Immich.\nВы не сможете отменить это действие!", "enable": "Включить", - "enable_backup": "Включить резервное копирование", + "enable_backup": "Активировать", "enable_biometric_auth_description": "Введите свой PIN-код для включения биометрической аутентификации", "enabled": "Включено", "end_date": "Дата окончания", @@ -889,28 +905,30 @@ "error": "Ошибка", "error_change_sort_album": "Не удалось изменить порядок сортировки альбома", "error_delete_face": "Ошибка при удалении лица из объекта", + "error_getting_places": "Ошибка получения мест", "error_loading_image": "Ошибка при загрузке изображения", + "error_loading_partners": "Ошибка загрузки партнёров: {error}", "error_saving_image": "Ошибка: {error}", "error_tag_face_bounding_box": "Ошибка при добавлении отметки - не удалось получить координаты рамки лица", "error_title": "Ошибка - Что-то пошло не так", "errors": { "cannot_navigate_next_asset": "Не удалось перейти к следующему объекту", - "cannot_navigate_previous_asset": "Не удалось перейти к предыдущему ресурсу", + "cannot_navigate_previous_asset": "Не удалось перейти к предыдущему объекту", "cant_apply_changes": "Не удается применить изменения", "cant_change_activity": "Не удается {enabled, select, true {отключить} other {включить}} активность", - "cant_change_asset_favorite": "Не удалось изменить статус \"избранное\" для ресурса", + "cant_change_asset_favorite": "Не удалось изменить статус \"Избранное\" для объекта", "cant_change_metadata_assets_count": "Не удалось изменить метаданные у {count, plural, one {# объекта} other {# объектов}}", "cant_get_faces": "Не удается получить лица", "cant_get_number_of_comments": "Не удается получить количество комментариев", "cant_search_people": "Не удается выполнить поиск людей", "cant_search_places": "Не удается выполнить поиск мест", - "error_adding_assets_to_album": "Ошибка при добавлении ресурсов в альбом", + "error_adding_assets_to_album": "Ошибка при добавлении объектов в альбом", "error_adding_users_to_album": "Ошибка при добавлении пользователей в альбом", "error_deleting_shared_user": "Ошибка при удалении пользователя с общим доступом", "error_downloading": "Ошибка при загрузке {filename}", "error_hiding_buy_button": "Ошибка скрытия кнопки", - "error_removing_assets_from_album": "Ошибка при удалении ресурсов из альбома, проверьте консоль для получения дополнительной информации", - "error_selecting_all_assets": "Ошибка при выборе всех ресурсов", + "error_removing_assets_from_album": "Ошибка при удалении объектов из альбома, проверьте консоль для получения дополнительной информации", + "error_selecting_all_assets": "Ошибка при выборе всех объектов", "exclusion_pattern_already_exists": "Такая модель исключения уже существует.", "failed_to_create_album": "Не удалось создать альбом", "failed_to_create_shared_link": "Не удалось создать публичную ссылку", @@ -1002,7 +1020,7 @@ "unable_to_scan_library": "Не удалось просканировать библиотеку", "unable_to_set_feature_photo": "Не удалось установить фотографию на обложку", "unable_to_set_profile_picture": "Не удалось установить фото профиля", - "unable_to_submit_job": "Не удалось отправить задание", + "unable_to_submit_job": "Не удалось отправить задачу на выполнение", "unable_to_trash_asset": "Не удалось переместить объект в корзину", "unable_to_unlink_account": "Не удалось отсоединить учётную запись", "unable_to_unlink_motion_video": "Не удалось отсоединить движущееся видео", @@ -1054,6 +1072,7 @@ "favorites_page_no_favorites": "В избранном сейчас пусто", "feature_photo_updated": "Избранное фото обновлено", "features": "Дополнительные возможности", + "features_in_development": "Функции в разработке", "features_setting_description": "Управление дополнительными возможностями приложения", "file_name": "Имя файла", "file_name_or_extension": "Имя файла или расширение", @@ -1167,7 +1186,7 @@ }, "invalid_date": "Неверная дата", "invalid_date_format": "Неверный формат даты", - "invite_people": "Пригласить", + "invite_people": "Пригласить участника", "invite_to_album": "Пригласить в альбом", "ios_debug_info_fetch_ran_at": "Выборка запущена {dateTime}", "ios_debug_info_last_sync_at": "Последняя синхронизация {dateTime}", @@ -1185,7 +1204,7 @@ "language": "Язык", "language_no_results_subtitle": "Попробуйте скорректировать поисковый запрос", "language_no_results_title": "Языков не найдено", - "language_search_hint": "Поиск языков...", + "language_search_hint": "Поиск языка...", "language_setting_description": "Выберите предпочитаемый вами язык", "large_files": "Файлы наибольшего размера", "last": "Последний", @@ -1195,10 +1214,10 @@ "leave": "Покинуть", "leave_album": "Покинуть альбом", "lens_model": "Модель объектива", - "let_others_respond": "Позволять другим откликаться", + "let_others_respond": "Разрешить другим пользователям добавлять комментарии и отметки \"нравится\"", "level": "Уровень", "library": "Библиотека", - "library_options": "Опции библиотеки", + "library_options": "Действия с библиотекой", "library_page_device_albums": "Альбомы на устройстве", "library_page_new_album": "Новый альбом", "library_page_sort_asset_count": "Количество объектов", @@ -1218,6 +1237,7 @@ "local": "На устройстве", "local_asset_cast_failed": "Невозможна трансляция объектов, которые ещё не загружены на сервер", "local_assets": "Объекты на устройстве", + "local_media_summary": "Информация об объекте на устройстве", "local_network": "Локальная сеть", "local_network_sheet_info": "Приложение будет подключаться к серверу по этому адресу, когда устройство подключено к указанной Wi-Fi сети", "location_permission": "Доступ к местоположению", @@ -1229,6 +1249,7 @@ "location_picker_longitude_hint": "Введите долготу", "lock": "Заблокировать", "locked_folder": "Личная папка", + "log_detail_title": "Детали события", "log_out": "Выйти", "log_out_all_devices": "Завершить сеансы на всех устройствах", "logged_in_as": "Авторизован как {user}", @@ -1259,6 +1280,7 @@ "login_password_changed_success": "Пароль успешно обновлен", "logout_all_device_confirmation": "Вы действительно хотите завершить все сеансы, кроме текущего?", "logout_this_device_confirmation": "Вы действительно хотите завершить сеанс на этом устройстве?", + "logs": "Журнал событий", "longitude": "Долгота", "look": "Просмотр", "loop_videos": "Циклическое воспроизведение видео", @@ -1268,7 +1290,7 @@ "make": "Производитель", "manage_geolocation": "Управление местами съёмки", "manage_shared_links": "Управление публичными ссылками", - "manage_sharing_with_partners": "Функция совместного доступа к фото и видео, позволяющая видеть все объекты партнёров, а также предоставлять доступ к своим", + "manage_sharing_with_partners": "Функция совместного доступа к фото и видео, позволяющая видеть объекты партнёров, а также предоставлять доступ к своим", "manage_the_app_settings": "Управление настройками приложения", "manage_your_account": "Управление учётной записью", "manage_your_api_keys": "Управление API ключами для взаимодействия с другими программами", @@ -1301,6 +1323,7 @@ "mark_as_read": "Отметить как прочитанное", "marked_all_as_read": "Отмечены как прочитанные", "matches": "Совпадения", + "matching_assets": "Соответствующие объекты", "media_type": "Тип медиа", "memories": "Воспоминания", "memories_all_caught_up": "Это всё на сегодня", @@ -1312,7 +1335,7 @@ "memory_lane_title": "Воспоминание {title}", "menu": "Меню", "merge": "Объединить", - "merge_people": "Объединить людей", + "merge_people": "Объединить с другим", "merge_people_limit": "Вы можете объединять до 5 лиц за один раз", "merge_people_prompt": "Вы хотите объединить этих людей? Это действие необратимо.", "merge_people_successfully": "Лица людей успешно объединены", @@ -1324,11 +1347,11 @@ "model": "Модель", "month": "Месяц", "monthly_title_text_date_format": "MMMM y", - "more": "Больше", + "more": "Дополнительные действия", "move": "Переместить", - "move_off_locked_folder": "Переместить из личной папки", + "move_off_locked_folder": "Убрать из личной папки", "move_to_lock_folder_action_prompt": "Объекты добавлены в личную папку ({count} шт.)", - "move_to_locked_folder": "Переместить в личную папку", + "move_to_locked_folder": "В личную папку", "move_to_locked_folder_confirmation": "Эти фото и видео будут удалены из всех альбомов и будут доступны только в личной папке", "moved_to_archive": "{count, plural, one {# объект перемещён} many {# объектов перемещены} other {# объекта перемещены}} в архив", "moved_to_library": "{count, plural, one {# объект перемещён} many {# объектов перемещены} other {# объекта перемещены}} в библиотеку", @@ -1341,6 +1364,7 @@ "name_or_nickname": "Имя или ник", "network_requirement_photos_upload": "Использовать мобильный интернет для загрузки фото", "network_requirement_videos_upload": "Использовать мобильный интернет для загрузки видео", + "network_requirements": "Требования к сети", "network_requirements_updated": "Требования к сети изменились, сброс очереди загрузки", "networking_settings": "Сеть", "networking_subtitle": "Настройка подключения к серверу", @@ -1351,6 +1375,7 @@ "new_person": "Новый человек", "new_pin_code": "Новый PIN-код", "new_pin_code_subtitle": "Это ваш первый доступ к личной папке. Создайте PIN-код для защищенного доступа к этой странице.", + "new_timeline": "Новая лента", "new_user_created": "Новый пользователь создан", "new_version_available": "ДОСТУПНА НОВАЯ ВЕРСИЯ", "newest_first": "Сначала новые", @@ -1364,23 +1389,28 @@ "no_assets_message": "НАЖМИТЕ ДЛЯ ЗАГРУЗКИ ВАШЕГО ПЕРВОГО ФОТО", "no_assets_to_show": "Медиа отсутствуют", "no_cast_devices_found": "Не найдено устройств для трансляции", + "no_checksum_local": "Контрольные суммы отсутствуют - невозможно получить объекты на устройстве", + "no_checksum_remote": "Контрольные суммы отсутствуют - невозможно получить объекты с сервера", "no_duplicates_found": "Дубликатов не обнаружено.", "no_exif_info_available": "Нет доступной информации exif", "no_explore_results_message": "Загружайте больше фотографий, чтобы наслаждаться вашей коллекцией.", "no_favorites_message": "Добавляйте объекты в избранное, чтобы быстрее находить свои лучшие фото и видео", "no_libraries_message": "Создайте внешнюю библиотеку для просмотра в Immich сторонних фотографий и видео", + "no_local_assets_found": "На устройстве не найдено объектов с такой контрольной суммой", "no_locked_photos_message": "Фото и видео, перемещенные в личную папку, скрыты и не отображаются при просмотре библиотеки.", "no_name": "Нет имени", "no_notifications": "Нет уведомлений", "no_people_found": "Никого не найдено", "no_places": "Нет мест", + "no_remote_assets_found": "На сервере не найдено объектов с такой контрольной суммой", "no_results": "Нет результатов", "no_results_description": "Попробуйте использовать синоним или более общее ключевое слово", "no_shared_albums_message": "Создайте альбом для обмена фотографиями и видеозаписями с людьми в вашей сети", "no_uploads_in_progress": "Нет активных загрузок", + "not_available": "Нет данных", "not_in_any_album": "Ни в одном альбоме", "not_selected": "Не выбрано", - "note_apply_storage_label_to_previously_uploaded assets": "Примечание: Чтобы применить метку хранилища к ранее загруженным ресурсам, запустите", + "note_apply_storage_label_to_previously_uploaded assets": "Примечание: Чтобы применить метку хранилища к ранее загруженным объектам, запустите", "notes": "Примечание", "nothing_here_yet": "Здесь пока ничего нет", "notification_permission_dialog_content": "Чтобы включить уведомления, перейдите в «Настройки» и выберите «Разрешить».", @@ -1410,7 +1440,7 @@ "open_in_map_view": "Открыть в режиме просмотра карты", "open_in_openstreetmap": "Открыть в OpenStreetMap", "open_the_search_filters": "Открыть фильтры поиска", - "options": "Опции", + "options": "Параметры", "or": "или", "organize_into_albums": "Распределить по альбомам", "organize_into_albums_description": "Добавить уже существующие объекты в альбомы, используя текущие настройки синхронизации", @@ -1499,6 +1529,7 @@ "port": "Порт", "preferences_settings_subtitle": "Настройка внешнего вида", "preferences_settings_title": "Параметры", + "preparing": "Подготовка", "preset": "Предустановленные варианты", "preview": "Предварительный просмотр", "previous": "Предыдущее", @@ -1510,7 +1541,7 @@ "primary": "Главное", "privacy": "Конфиденциальность", "profile": "Профиль", - "profile_drawer_app_logs": "Журнал", + "profile_drawer_app_logs": "Журнал событий", "profile_drawer_client_out_of_date_major": "Версия мобильного приложения устарела. Пожалуйста, обновите его.", "profile_drawer_client_out_of_date_minor": "Версия мобильного приложения устарела. Пожалуйста, обновите его.", "profile_drawer_client_server_up_to_date": "Клиент и сервер обновлены", @@ -1560,14 +1591,15 @@ "rating_clear": "Очистить рейтинг", "rating_count": "{count, plural, one {# звезда} many {# звезд} other {# звезды}}", "rating_description": "Система оценки объектов в панели информации", - "reaction_options": "Опции реакций", - "read_changelog": "Прочитать список изменений", + "reaction_options": "Действия с отметкой", + "read_changelog": "История релизов", "readonly_mode_disabled": "Режим «только просмотр» отключён", "readonly_mode_enabled": "Режим «только просмотр» включён", + "ready_for_upload": "Готово к загрузке", "reassign": "Переназначить", "reassigned_assets_to_existing_person": "Лица на {count, plural, one {# объекте} other {# объектах}} переназначены на {name, select, null {другого человека} other {человека с именем {name}}}", "reassigned_assets_to_new_person": "Лица на {count, plural, one {# объекте} other {# объектах}} переназначены на нового человека", - "reassing_hint": "Назначить выбранные ресурсы указанному человеку", + "reassing_hint": "Назначить выбранные объекты указанному человеку", "recent": "Недавние", "recent-albums": "Недавние альбомы", "recent_searches": "Недавние поисковые запросы", @@ -1588,6 +1620,7 @@ "regenerating_thumbnails": "Восстановление миниатюр", "remote": "На сервере", "remote_assets": "Объекты на сервере", + "remote_media_summary": "Информация об объекте на сервере", "remove": "Удалить", "remove_assets_album_confirmation": "Вы действительно хотите удалить {count, plural, one {# объект} many {# объектов} other {# объекта}} из альбома?", "remove_assets_shared_link_confirmation": "Вы действительно хотите удалить {count, plural, one {# объект} many {# объектов} other {# объекта}} из публичного доступа по этой ссылке?", @@ -1599,7 +1632,7 @@ "remove_from_favorites": "Удалить из избранного", "remove_from_lock_folder_action_prompt": "Объекты удалены из личной папки ({count} шт.)", "remove_from_locked_folder": "Удалить из личной папки", - "remove_from_locked_folder_confirmation": "Вы действительно хотите переместить эти фото и видео из личной папки? Они станут доступны в вашей библиотеке.", + "remove_from_locked_folder_confirmation": "Вы хотите убрать выделенные объекты из личной папки? Они снова станут доступны в вашей библиотеке.", "remove_from_shared_link": "Удалить из публичной ссылки", "remove_memory": "Удалить воспоминание", "remove_photo_from_memory": "Удалить фото из воспоминания", @@ -1653,7 +1686,7 @@ "saved_api_key": "API ключ изменён", "saved_profile": "Профиль сохранён", "saved_settings": "Настройки сохранены", - "say_something": "Скажите что-нибудь", + "say_something": "Напишите что-нибудь", "scaffold_body_error_occurred": "Возникла ошибка", "scan_all_libraries": "Сканировать все библиотеки", "scan_library": "Сканировать", @@ -1674,7 +1707,7 @@ "search_filter_camera_title": "Выберите тип камеры", "search_filter_date": "Дата", "search_filter_date_interval": "{start} — {end}", - "search_filter_date_title": "Выберите промежуток", + "search_filter_date_title": "Выберите период", "search_filter_display_option_not_in_album": "Не в альбоме", "search_filter_display_options": "Настройки отображения", "search_filter_filename": "Поиск по имени файла", @@ -1727,7 +1760,7 @@ "select_from_computer": "Выбрать с компьютера", "select_keep_all": "Выбрать все для сохранения", "select_library_owner": "Выберите владельца библиотеки", - "select_new_face": "Выбрать другое лицо", + "select_new_face": "Выбрать другого человека", "select_person_to_tag": "Выделите лицо человека, которого хотите отметить", "select_photos": "Выберите фотографии", "select_trash_all": "Выбрать все для удаления", @@ -1740,7 +1773,7 @@ "server_endpoint": "Адрес сервера", "server_info_box_app_version": "Версия приложения", "server_info_box_server_url": "URL сервера", - "server_offline": "Сервер не в сети", + "server_offline": "Оффлайн", "server_online": "Сервер в сети", "server_privacy": "Конфиденциальность сервера", "server_stats": "Статистика сервера", @@ -1760,7 +1793,7 @@ "setting_image_viewer_preview_title": "Загружать уменьшенное изображение", "setting_image_viewer_title": "Изображения", "setting_languages_apply": "Применить", - "setting_languages_subtitle": "Изменить язык приложения", + "setting_languages_subtitle": "Изменение языка приложения", "setting_notifications_notify_failures_grace_period": "Уведомлять об ошибках фонового резервного копирования: {duration}", "setting_notifications_notify_hours": "{count} ч.", "setting_notifications_notify_immediately": "немедленно", @@ -1769,7 +1802,7 @@ "setting_notifications_notify_seconds": "{count} сек.", "setting_notifications_single_progress_subtitle": "Подробная информация о ходе загрузки для каждого объекта", "setting_notifications_single_progress_title": "Показать ход выполнения фонового резервного копирования", - "setting_notifications_subtitle": "Настройка параметров уведомлений", + "setting_notifications_subtitle": "Параметры уведомлений", "setting_notifications_total_progress_subtitle": "Общий прогресс загрузки (выполнено/всего объектов)", "setting_notifications_total_progress_title": "Показать общий прогресс фонового резервного копирования", "setting_video_viewer_looping_title": "Циклическое воспроизведение", @@ -1802,17 +1835,17 @@ "shared_link_clipboard_copied_massage": "Скопировано в буфер обмена", "shared_link_clipboard_text": "Ссылка: {link}\nПароль: {password}", "shared_link_create_error": "Ошибка при создании публичной ссылки", - "shared_link_custom_url_description": "Доступ к этой общей ссылке с помощью заданного пользователем URL-адреса", - "shared_link_edit_description_hint": "Введите описание публичного доступа", + "shared_link_custom_url_description": "Пользовательский URL-адрес общего доступа", + "shared_link_edit_description_hint": "Введите описание", "shared_link_edit_expire_after_option_day": "1 день", "shared_link_edit_expire_after_option_days": "{count} дней", "shared_link_edit_expire_after_option_hour": "1 час", "shared_link_edit_expire_after_option_hours": "{count} часов", "shared_link_edit_expire_after_option_minute": "1 минуту", "shared_link_edit_expire_after_option_minutes": "{count} минут", - "shared_link_edit_expire_after_option_months": "{count} месяцев", + "shared_link_edit_expire_after_option_months": "{count} месяца", "shared_link_edit_expire_after_option_year": "{count} лет", - "shared_link_edit_password_hint": "Введите пароль для публичного доступа", + "shared_link_edit_password_hint": "Защитите доступ паролем", "shared_link_edit_submit_button": "Обновить ссылку", "shared_link_error_server_url_fetch": "Невозможно запросить URL с сервера", "shared_link_expires_day": "Истечёт через {count} день", @@ -1827,8 +1860,8 @@ "shared_link_individual_shared": "Индивидуальный общий доступ", "shared_link_info_chip_metadata": "EXIF", "shared_link_manage_links": "Управление публичными ссылками", - "shared_link_options": "Параметры публичных ссылок", - "shared_link_password_description": "Требовать пароль для доступа к этой общей ссылке", + "shared_link_options": "Действия со ссылкой", + "shared_link_password_description": "Требовать пароль для доступа к объектам", "shared_links": "Публичные ссылки", "shared_links_description": "Делитесь фотографиями и видео по ссылке", "shared_photos_and_videos_count": "{assetCount, plural, other {# фото и видео.}}", @@ -1843,7 +1876,7 @@ "sharing_silver_appbar_create_shared_album": "Создать общий альбом", "sharing_silver_appbar_share_partner": "Поделиться с партнёром", "shift_to_permanent_delete": "нажмите ⇧ чтобы удалить объект навсегда", - "show_album_options": "Показать параметры альбома", + "show_album_options": "Действия с альбомом", "show_albums": "Показать альбомы", "show_all_people": "Показать всех людей", "show_and_hide_people": "Показать и скрыть людей", @@ -1856,13 +1889,14 @@ "show_metadata": "Показывать метаданные", "show_or_hide_info": "Показать или скрыть информацию", "show_password": "Показать пароль", - "show_person_options": "Показать опции персоны", + "show_person_options": "Действия с человеком", "show_progress_bar": "Показать Индикатор Выполнения", "show_search_options": "Показать параметры поиска", "show_shared_links": "Показать публичные ссылки", "show_slideshow_transition": "Показать слайд-шоу переход", "show_supporter_badge": "Значок поддержки", "show_supporter_badge_description": "Показать значок поддержки", + "show_text_search_menu": "Показать меню текстового поиска", "shuffle": "Перемешать", "sidebar": "Боковая панель", "sidebar_display_description": "Отображать раздел на боковой панели", @@ -1893,6 +1927,7 @@ "stacktrace": "Трассировка стека", "start": "Старт", "start_date": "Дата начала", + "start_date_before_end_date": "Дата начала должна быть меньше даты окончания", "state": "Регион", "status": "Состояние", "stop_casting": "Остановить трансляцию", @@ -1978,7 +2013,7 @@ "trash_page_select_assets_btn": "Выбранные объекты", "trash_page_title": "Корзина ({count})", "trashed_items_will_be_permanently_deleted_after": "Объекты, хранящиеся в корзине более {days, plural, one {# дня} other {# дней}}, удаляются автоматически.", - "troubleshoot": "Решение проблем", + "troubleshoot": "Диагностика", "type": "Тип", "unable_to_change_pin_code": "Ошибка при изменении PIN-кода", "unable_to_setup_pin_code": "Ошибка при создании PIN-кода", @@ -2037,7 +2072,7 @@ "user": "Пользователь", "user_has_been_deleted": "Этот пользователь был удалён.", "user_id": "ID пользователя", - "user_liked": "{user} отметил(а) {type, select, photo {это фото} video {это видео} asset {этот ресурс} other {этот альбом}}", + "user_liked": "Пользователю {user} нравится {type, select, photo {это фото} video {это видео} asset {этот объект} other {этот альбом}}", "user_pin_code_settings": "PIN-код", "user_pin_code_settings_description": "Настройка PIN-кода для доступа к личной папке", "user_privacy": "Конфиденциальность пользователя", @@ -2095,5 +2130,6 @@ "yes": "Да", "you_dont_have_any_shared_links": "У вас нет публичных ссылок", "your_wifi_name": "Имя вашей Wi-Fi сети", - "zoom_image": "Приблизить" + "zoom_image": "Изменить масштаб", + "zoom_to_bounds": "Увеличить до границ" } diff --git a/i18n/sk.json b/i18n/sk.json index 3113ce788d..2fdd6ca07a 100644 --- a/i18n/sk.json +++ b/i18n/sk.json @@ -28,6 +28,7 @@ "add_to_album": "Pridať do albumu", "add_to_album_bottom_sheet_added": "Pridané do {album}", "add_to_album_bottom_sheet_already_exists": "Už je v {album}", + "add_to_album_bottom_sheet_some_local_assets": "Niektoré lokálne súbory nebolo možné pridať do albumu", "add_to_album_toggle": "Prepnúť výber pre {album}", "add_to_albums": "Pridať do albumov", "add_to_albums_count": "Pridať do albumov ({count})", @@ -123,6 +124,13 @@ "logging_enable_description": "Povoliť ukladanie záznamov", "logging_level_description": "Ak je povolené, akú úroveň záznamov použiť.", "logging_settings": "Ukladanie záznamov", + "machine_learning_availability_checks": "Kontroly dostupnosti", + "machine_learning_availability_checks_description": "Automaticky zistiť a uprednostniť dostupné servery strojového učenia", + "machine_learning_availability_checks_enabled": "Povoliť kontroly dostupnosti", + "machine_learning_availability_checks_interval": "Interval kontroly", + "machine_learning_availability_checks_interval_description": "Interval v milisekundách medzi kontrolami dostupnosti", + "machine_learning_availability_checks_timeout": "Časový limit požiadavky", + "machine_learning_availability_checks_timeout_description": "Časový limit v milisekundách pre kontroly dostupnosti", "machine_learning_clip_model": "Model CLIP", "machine_learning_clip_model_description": "Názov modelu CLIP je uvedený tu. Pamätajte, že pri zmene modelu je nutné znovu spustiť úlohu 'Inteligentné vyhľadávanie' pre všetky obrázky.", "machine_learning_duplicate_detection": "Detekcia duplikátov", @@ -387,8 +395,6 @@ "admin_password": "Administrátorské heslo", "administration": "Administrácia", "advanced": "Pokročilé", - "advanced_settings_beta_timeline_subtitle": "Vyskúšajte prostredie novej aplikácie", - "advanced_settings_beta_timeline_title": "Beta verzia časovej osi", "advanced_settings_enable_alternate_media_filter_subtitle": "Túto možnosť použite na filtrovanie médií počas synchronizácie na základe alternatívnych kritérií. Túto možnosť vyskúšajte len vtedy, ak máte problémy s detekciou všetkých albumov v aplikácii.", "advanced_settings_enable_alternate_media_filter_title": "[EXPERIMENTÁLNE] Použiť alternatívny filter synchronizácie albumu zariadenia", "advanced_settings_log_level_title": "Úroveň ukladania záznamov: {level}", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "Ste si istý, že chcete odstrániť používateľa {user}?", "album_search_not_found": "Neboli nájdené žiadne albumy zodpovedajúce vášmu hľadaniu", "album_share_no_users": "Vyzerá to, že ste tento album zdieľali so všetkými používateľmi alebo nemáte žiadneho používateľa, s ktorým by ste ho mohli zdieľať.", + "album_summary": "Súhrn albumu", "album_updated": "Album bol aktualizovaný", "album_updated_setting_description": "Obdržať e-mailové upozornenie, keď v zdieľanom albume pribudnú nové položky", "album_user_left": "Opustil {album}", @@ -496,6 +503,8 @@ "asset_restored_successfully": "Položky boli úspešne obnovené", "asset_skipped": "Preskočené", "asset_skipped_in_trash": "V koši", + "asset_trashed": "Položka bola vyhodená", + "asset_troubleshoot": "Riešenie problémov s položkami", "asset_uploaded": "Nahrané", "asset_uploading": "Nahráva sa…", "asset_viewer_settings_subtitle": "Spravujte nastavenia prehliadača galérie", @@ -529,8 +538,10 @@ "autoplay_slideshow": "Automatické prehrávanie prezentácie", "back": "Späť", "back_close_deselect": "Späť, zavrieť alebo zrušiť výber", + "background_backup_running_error": "V súčasnosti prebieha zálohovanie na pozadí, nie je možné spustiť ručné zálohovanie", "background_location_permission": "Povolenie na určenie polohy na pozadí", "background_location_permission_content": "Aby bolo možné prepínať siete pri spustení na pozadí, musí mať aplikácia Immich *vždy* presný prístup k polohe, aby mohla prečítať názov siete Wi-Fi", + "background_options": "Možnosti pozadia", "backup": "Zálohovanie", "backup_album_selection_page_albums_device": "Albumy v zariadení ({count})", "backup_album_selection_page_albums_tap": "Ťuknutím na položku ju zahrniete, dvojitým ťuknutím ju vylúčite", @@ -538,6 +549,7 @@ "backup_album_selection_page_select_albums": "Vybrať albumy", "backup_album_selection_page_selection_info": "Informácie o výbere", "backup_album_selection_page_total_assets": "Celkový počet jedinečných súborov", + "backup_albums_sync": "Synchronizácia zálohovaných albumov", "backup_all": "Všetko", "backup_background_service_backup_failed_message": "Zálohovanie médií zlyhalo. Skúšam to znova…", "backup_background_service_connection_failed_message": "Nepodarilo sa pripojiť k serveru. Skúšam to znova…", @@ -654,6 +666,8 @@ "change_pin_code": "Zmeniť PIN kód", "change_your_password": "Zmeniť heslo", "changed_visibility_successfully": "Viditeľnosť bola úspešne zmenená", + "charging": "Nabíja sa", + "charging_requirement_mobile_backup": "Zálohovanie na pozadí vyžaduje, aby bolo zariadenie nabíjané", "check_corrupt_asset_backup": "Skontrolovať, či nie sú poškodené zálohy položiek", "check_corrupt_asset_backup_button": "Vykonať kontrolu", "check_corrupt_asset_backup_description": "Spustiť túto kontrolu len cez Wi-Fi a po zálohovaní všetkých položiek. Tento postup môže trvať niekoľko minút.", @@ -740,6 +754,7 @@ "create_user": "Vytvoriť používateľa", "created": "Vytvorené", "created_at": "Vytvorené", + "creating_linked_albums": "Vytváranie prepojených albumov...", "crop": "Orezať", "curated_object_page_title": "Veci", "current_device": "Súčasné zariadenie", @@ -889,7 +904,9 @@ "error": "Chyba", "error_change_sort_album": "Nepodarilo sa zmeniť poradie albumu", "error_delete_face": "Chyba pri odstraňovaní tváre z položky", + "error_getting_places": "Chyba pri získavaní polôh", "error_loading_image": "Nepodarilo sa načítať obrázok", + "error_loading_partners": "Chyba pri načítaní partnerov: {error}", "error_saving_image": "Chyba: {error}", "error_tag_face_bounding_box": "Chyba pri označovaní tváre - nemožno získať súradnice ohraničujúceho poľa", "error_title": "Chyba - niečo sa pokazilo", @@ -1054,6 +1071,7 @@ "favorites_page_no_favorites": "Žiadne obľúbené médiá", "feature_photo_updated": "Hlavný obrázok bol aktualizovaný", "features": "Funkcie", + "features_in_development": "Funkcie vo vývoji", "features_setting_description": "Spravovať funkcie aplikácie", "file_name": "Názov súboru", "file_name_or_extension": "Názov alebo prípona súboru", @@ -1218,6 +1236,7 @@ "local": "Lokálne", "local_asset_cast_failed": "Nie je možné preniesť médium, ktoré nie je nahrané na serveri", "local_assets": "Lokálne položky", + "local_media_summary": "Súhrn lokálnych médií", "local_network": "Miestna sieť", "local_network_sheet_info": "Pri použití zadanej siete Wi-Fi sa aplikácia pripojí k serveru prostredníctvom tejto URL adresy", "location_permission": "Povolenie na určenie polohy", @@ -1229,6 +1248,7 @@ "location_picker_longitude_hint": "Zadajte platnú zemepisnú dĺžku", "lock": "Zamknúť", "locked_folder": "Zamknutý priečinok", + "log_detail_title": "Podrobnosti o zázname", "log_out": "Odhlásiť sa", "log_out_all_devices": "Odhlásiť všetky zariadenia", "logged_in_as": "Prihlásený ako {user}", @@ -1259,6 +1279,7 @@ "login_password_changed_success": "Aktualizácia hesla prebehla úspešne", "logout_all_device_confirmation": "Ste si istý, že sa chcete odhlásiť zo všetkých zariadení?", "logout_this_device_confirmation": "Ste si istý, že sa chcete odhlásiť z tohoto zariadenia?", + "logs": "Záznamy", "longitude": "Zemepisná dĺžka", "look": "Vzhľad", "loop_videos": "Opakovať videá", @@ -1301,6 +1322,7 @@ "mark_as_read": "Označiť ako prečítané", "marked_all_as_read": "Označené všetko ako prečítané", "matches": "Zhody", + "matching_assets": "Vyhovujúce položky", "media_type": "Typ média", "memories": "Spomienky", "memories_all_caught_up": "Na dnes to je všetko", @@ -1341,6 +1363,7 @@ "name_or_nickname": "Meno alebo prezývka", "network_requirement_photos_upload": "Použiť mobilné dáta na zálohovanie fotografií", "network_requirement_videos_upload": "Použiť mobilné dáta na zálohovanie videí", + "network_requirements": "Požiadavky na sieť", "network_requirements_updated": "Požiadavky na sieť sa zmenili, obnovuje sa poradie zálohovania", "networking_settings": "Sieť", "networking_subtitle": "Spravovať nastavenia koncového bodu servera", @@ -1351,6 +1374,7 @@ "new_person": "Nová osoba", "new_pin_code": "Nový PIN kód", "new_pin_code_subtitle": "Toto je váš prvý prístup k zamknutému priečinku. Vytvorte si PIN kód na bezpečný prístup k tejto stránke", + "new_timeline": "Nová časová os", "new_user_created": "Nový používateľ vytvorený", "new_version_available": "JE DOSTUPNÁ NOVÁ VERZIA", "newest_first": "Najprv najnovšie", @@ -1364,20 +1388,25 @@ "no_assets_message": "KLIKNITE A NAHRAJTE SVOJU PRVÚ FOTKU", "no_assets_to_show": "Žiadne položky", "no_cast_devices_found": "Nenašli sa žiadne zariadenia na prenos", + "no_checksum_local": "Kontrola súčtu nie je k dispozícii – nie je možné načítať lokálne položky", + "no_checksum_remote": "Kontrola súčtu nie je k dispozícii – nie je možné načítať vzdialené položky", "no_duplicates_found": "Nenašli sa žiadne duplicity.", "no_exif_info_available": "Nie sú dostupné exif údaje", "no_explore_results_message": "Nahrajte viac fotiek na objavovanie vašej zbierky.", "no_favorites_message": "Pridajte si obľúbené, aby ste rýchlo našli svoje najlepšie obrázky a videá", "no_libraries_message": "Vytvorí externú knižnicu na prezeranie fotiek a videí", + "no_local_assets_found": "Neboli nájdené žiadne lokálne položky s touto kontrolnou sumou", "no_locked_photos_message": "Fotografie a videá v zamknutom priečinku sú skryté a nezobrazujú sa pri prehľadávaní alebo vyhľadávaní v knižnici.", "no_name": "Bez mena", "no_notifications": "Žiadne oznámenia", "no_people_found": "Nenašli sa žiadni vyhovujúci ľudia", "no_places": "Bez miesta", + "no_remote_assets_found": "Neboli nájdené žiadne vzdialené položky s touto kontrolnou sumou", "no_results": "Žiadne výsledky", "no_results_description": "Skúste synonymum alebo všeobecnejší výraz", "no_shared_albums_message": "Vytvorí album na zdieľanie fotiek a videí s ľuďmi vo vašej sieti", "no_uploads_in_progress": "Žiadne prebiehajúce nahrávanie", + "not_available": "Nedostupné", "not_in_any_album": "Nie je v žiadnom albume", "not_selected": "Nevybrané", "note_apply_storage_label_to_previously_uploaded assets": "Poznámka: Ak chcete použiť Štítok úložiska na predtým nahrané médiá, spustite príkaz", @@ -1499,6 +1528,7 @@ "port": "Port", "preferences_settings_subtitle": "Spravovať predvoľby aplikácie", "preferences_settings_title": "Predvoľby", + "preparing": "Pripravuje sa", "preset": "Predvoľba", "preview": "Náhľad", "previous": "Predošlé", @@ -1564,6 +1594,7 @@ "read_changelog": "Prečítať zoznam zmien", "readonly_mode_disabled": "Režim iba na čítanie je vypnutý", "readonly_mode_enabled": "Režim iba na čítanie je zapnutý", + "ready_for_upload": "Pripravené na nahratie", "reassign": "Preradiť", "reassigned_assets_to_existing_person": "Opätovne {count, plural, one {priradená # položka} few {priradené # položky} other {priradených # položiek}} k {name, select, null {existujúcej osobe} other {{name}}}", "reassigned_assets_to_new_person": "Opätovne {count, plural, one {priradená # položka} few {priradené # položky} other {priradených # položiek}} novej osobe", @@ -1588,6 +1619,7 @@ "regenerating_thumbnails": "Pregenerovanie náhľadov", "remote": "Vzdialené", "remote_assets": "Vzdialené položky", + "remote_media_summary": "Súhrn vzdialených médií", "remove": "Odstrániť", "remove_assets_album_confirmation": "Naozaj chcete odstrániť {count, plural, one {# položku} few {# položky} other {# položiek}} z albumu?", "remove_assets_shared_link_confirmation": "Naozaj chcete odstrániť {count, plural, one {# položku} few {# položky} other {# položiek}} z tohoto zdieľaného odkazu?", @@ -1863,6 +1895,7 @@ "show_slideshow_transition": "Zobraziť prechody v prezentácii", "show_supporter_badge": "Odznak podporovateľa", "show_supporter_badge_description": "Zobraziť odznak podporovateľa", + "show_text_search_menu": "Zobraziť ponuku vyhľadávania textu", "shuffle": "Náhodné poradie", "sidebar": "Bočný panel", "sidebar_display_description": "Zobraziť odkaz na zobrazenie v bočnom paneli", @@ -1893,6 +1926,7 @@ "stacktrace": "Výpis zásobníku", "start": "Spustiť", "start_date": "Počiatočný dátum", + "start_date_before_end_date": "Dátum začiatku musí byť pred dátumom ukončenia", "state": "Štát", "status": "Stav", "stop_casting": "Zastaviť prenos", @@ -2095,5 +2129,6 @@ "yes": "Áno", "you_dont_have_any_shared_links": "Nemáte žiadne zdielané odkazy", "your_wifi_name": "Váš názov siete Wi-Fi", - "zoom_image": "Priblížiť obrázok" + "zoom_image": "Priblížiť obrázok", + "zoom_to_bounds": "Zväčšiť na okraje" } diff --git a/i18n/sl.json b/i18n/sl.json index f67a6b08b7..7a1aef509a 100644 --- a/i18n/sl.json +++ b/i18n/sl.json @@ -8,7 +8,7 @@ "actions": "Dejanja", "active": "Aktivno", "activity": "Aktivnost", - "activity_changed": "Aktivnost {enabled, select, true {omogočena} other {onemogočena}}", + "activity_changed": "Aktivnost je {enabled, select, true {omogočena} other {onemogočena}}", "add": "Dodaj", "add_a_description": "Dodaj opis", "add_a_location": "Dodaj lokacijo", @@ -28,6 +28,7 @@ "add_to_album": "Dodaj v album", "add_to_album_bottom_sheet_added": "Dodano v {album}", "add_to_album_bottom_sheet_already_exists": "Že v {album}", + "add_to_album_bottom_sheet_some_local_assets": "Nekaterih lokalnih sredstev ni bilo mogoče dodati v album", "add_to_album_toggle": "Preklopi izbiro za {album}", "add_to_albums": "Dodaj v albume", "add_to_albums_count": "Dodaj v albume ({count})", @@ -39,15 +40,15 @@ "admin": { "add_exclusion_pattern_description": "Dodajte vzorec izključitev. Globiranje z uporabo *, ** in ? je podprto. Če želite prezreti vse datoteke v katerem koli imeniku z imenom \"Raw\", uporabite \"**/Raw/**\". Če želite prezreti vse datoteke, ki se končajo na \".tif\", uporabite \"**/*.tif\". Če želite prezreti absolutno pot, uporabite \"/pot/za/ignoriranje/**\".", "admin_user": "Skrbniški uporabnik", - "asset_offline_description": "Sredstva zunanje knjižnice ni več mogoče najti na disku in je bilo premaknjeno v koš. Če je bila datoteka premaknjena znotraj knjižnice, preverite svojo časovnico za novo ustrezno sredstvo. Če želite obnoviti to sredstvo, zagotovite, da ima Immich dostop do spodnje poti datoteke, in skenirajte knjižnico.", + "asset_offline_description": "Tega sredstva zunanje knjižnice ni več mogoče najti na disku in je bilo premaknjeno v koš. Če je bila datoteka premaknjena znotraj knjižnice, preverite svojo časovnico za novo ustrezno sredstvo. Če želite obnoviti to sredstvo, zagotovite, da ima Immich dostop do spodnje poti datoteke, in skenirajte knjižnico.", "authentication_settings": "Nastavitve preverjanja pristnosti", "authentication_settings_description": "Upravljanje gesel, OAuth in drugih nastavitev preverjanja pristnosti", "authentication_settings_disable_all": "Ali zares želite onemogočiti vse prijavne metode? Prijava bo popolnoma onemogočena.", - "authentication_settings_reenable": "Ponovno omogoči z uporabo strežniškega ukaza.", + "authentication_settings_reenable": "Za ponovno omogočanje uporabite strežniški ukaz.", "background_task_job": "Opravila v ozadju", "backup_database": "Ustvari izpis baze podatkov", "backup_database_enable_description": "Omogoči izpise baze podatkov", - "backup_keep_last_amount": "Število prejšnjih odlagališč, ki jih je treba obdržati", + "backup_keep_last_amount": "Število prejšnjih izpisov baze podatkov, ki jih je treba obdržati", "backup_onboarding_1_description": "kopijo zunaj lokacije v oblaku ali na drugi fizični lokaciji.", "backup_onboarding_2_description": "lokalne kopije na različnih napravah. To vključuje glavne datoteke in lokalno varnostno kopijo teh datotek.", "backup_onboarding_3_description": "skupno število kopij vaših podatkov, vključno z izvirnimi datotekami. To vključuje 1 kopijo zunaj lokacije in 2 lokalni kopiji.", @@ -57,7 +58,7 @@ "backup_onboarding_title": "Varnostne kopije", "backup_settings": "Nastavitve izpisa baze podatkov", "backup_settings_description": "Upravljanje nastavitev izpisa podatkovne baze.", - "cleared_jobs": "Razčiščeno opravilo za: {job}", + "cleared_jobs": "Razčiščena opravila za: {job}", "config_set_by_file": "Konfiguracija je trenutno nastavljena s konfiguracijsko datoteko", "confirm_delete_library": "Ali ste prepričani, da želite izbrisati knjižnico {library}?", "confirm_delete_library_assets": "Ali ste prepričani, da želite izbrisati to knjižnico? To bo iz Immicha izbrisalo {count, plural, one {# vsebovani vir} two {# vsebovana vira} few {# vsebovane vire} other {vseh # vsebovanih virov}} in tega ni možno razveljaviti. Datoteke bodo ostale na disku.", @@ -72,10 +73,10 @@ "disable_login": "Onemogoči prijavo", "duplicate_detection_job_description": "Zaženite strojno učenje na sredstvih, da zaznate podobne slike. Zanaša se na Pametno Iskanje", "exclusion_pattern_description": "Vzorci izključitev vam omogočajo, da prezrete datoteke in mape pri skeniranju knjižnice. To je uporabno, če imate mape z datotekami, ki jih ne želite uvoziti, na primer datoteke RAW.", - "external_library_management": "Upravljanje zunanje knjižnice", + "external_library_management": "Upravljanje zunanjih knjižnic", "face_detection": "Zaznavanje obrazov", - "face_detection_description": "Zaznajte obraze v sredstvih s pomočjo strojnega učenja. Pri videoposnetkih se upošteva samo sličica. \"Vse\" (ponovno) obdela vsa sredstva. \"Manjkajoče\" postavi v čakalno vrsto sredstva, ki še niso bila obdelana. Zaznani obrazi bodo postavljeni v čakalno vrsto za prepoznavanje obrazov, ko bo zaznavanje obrazov končano, in jih bodo združili v obstoječe ali nove osebe.", - "facial_recognition_job_description": "Združi zaznane obraze v osebe. Ta korak se izvede po končanem zaznavanju obrazov. \"Vse\" (ponovno) združuje vse obraze. \"Manjkajoče\", doda v čakalno vrsto obraze, ki nimajo dodeljene osebe.", + "face_detection_description": "Zaznavanje obrazov v sredstvih z uporabo strojnega učenja. Pri videoposnetkih se upošteva samo sličica. »Osveži« (ponovno) obdela vsa sredstva. »Ponastavi« dodatno izbriše vse trenutne podatke o obrazih. »Manjkajoča« uvrsti sredstva, ki še niso bila obdelana, v čakalno vrsto. Zaznani obrazi bodo po končanem zaznavanju obrazov uvrščeni v čakalno vrsto za prepoznavanje obrazov, pri čemer bodo združeni v obstoječe ali nove osebe.", + "facial_recognition_job_description": "Združi zaznane obraze v osebe. Ta korak se izvede po končanem zaznavanju obrazov. »Ponastavi« (ponovno) združi vse obraze. »Manjkajoča« uvrsti obraze, ki jim ni dodeljena oseba, v čakalno vrsto.", "failed_job_command": "Za opravilo {job} ukaz {command} ni uspel", "force_delete_user_warning": "OPOZORILO: S tem boste takoj odstranili uporabnika in vsa sredstva. Tega ni mogoče razveljaviti in datotek ni mogoče obnoviti.", "image_format": "Format", @@ -102,12 +103,12 @@ "image_thumbnail_title": "Nastavitve sličic", "job_concurrency": "{job} sočasnost", "job_created": "Opravilo ustvarjeno", - "job_not_concurrency_safe": "To opravilo ni sočasno-varno.", + "job_not_concurrency_safe": "To delo ni varno za sočasnost.", "job_settings": "Nastavitve opravil", "job_settings_description": "Upravljaj sočasnost opravil", "job_status": "Status opravila", - "jobs_delayed": "{jobCount, plural, other {# zadržan}}", - "jobs_failed": "{jobCount, plural, other {# neuspešen}}", + "jobs_delayed": "{jobCount, plural, other {# zadržani}}", + "jobs_failed": "{jobCount, plural, other {# neuspešni}}", "library_created": "Ustvarjena knjižnica: {library}", "library_deleted": "Knjižnica izbrisana", "library_import_path_description": "Določi mapo za uvoz. Ta mapa in njene podmape bodo pregledane za slike in video posnetke.", @@ -123,6 +124,13 @@ "logging_enable_description": "Omogoči dnevnik", "logging_level_description": "Nivo dnevnika, ko je le-ta omogočen.", "logging_settings": "Dnevnik", + "machine_learning_availability_checks": "Preverjanja razpoložljivosti", + "machine_learning_availability_checks_description": "Samodejno zaznavanje in dajanje prednosti razpoložljivim strežnikom strojnega učenja", + "machine_learning_availability_checks_enabled": "Omogoči preverjanja razpoložljivosti", + "machine_learning_availability_checks_interval": "Interval preverjanja", + "machine_learning_availability_checks_interval_description": "Interval v milisekundah med preverjanji razpoložljivosti", + "machine_learning_availability_checks_timeout": "Zahteva za časovno omejitev", + "machine_learning_availability_checks_timeout_description": "Časovna omejitev v milisekundah za preverjanje razpoložljivosti", "machine_learning_clip_model": "model CLIP", "machine_learning_clip_model_description": "Ime CLIP modela iz seznama tukaj. Vedite, da boste morali po menjavi modela ponovno zagnati opravilo za 'Pametno iskanje' za vse slike.", "machine_learning_duplicate_detection": "Zaznavanje dvojnikov", @@ -131,7 +139,7 @@ "machine_learning_duplicate_detection_setting_description": "Za iskanje verjetnih dvojnikov uporabite vdelave CLIP", "machine_learning_enabled": "Omogoči strojno učenje", "machine_learning_enabled_description": "Če je onemogočeno, bodo vse funkcije strojnega učenja onemogočene ne glede na spodnje nastavitve.", - "machine_learning_facial_recognition": "Zaznavanje obrazov", + "machine_learning_facial_recognition": "Prepoznavanje obrazov", "machine_learning_facial_recognition_description": "Zaznavanje, prepoznavanje in združevanje obrazov na slikah", "machine_learning_facial_recognition_model": "Model za prepoznavanje obraza", "machine_learning_facial_recognition_model_description": "Modeli so navedeni v padajočem vrstnem redu glede na velikost. Večji modeli so počasnejši in uporabljajo več pomnilnika, vendar dajejo boljše rezultate. Upoštevajte, da morate po spremembi modela znova zagnati opravilo zaznavanja obrazov za vse slike.", @@ -144,7 +152,7 @@ "machine_learning_min_detection_score": "Najmanjši rezultat zaznavanja", "machine_learning_min_detection_score_description": "Najmanjši rezultat zaupanja za zaznavanje obraza od 0-1. Nižje vrednosti bodo zaznale več obrazov, vendar lahko povzročijo lažne pozitivne rezultate.", "machine_learning_min_recognized_faces": "Najmanjše število prepoznanih obrazov", - "machine_learning_min_recognized_faces_description": "Najmanjše število prepoznanih obrazov za osebo, ki se ustvari. Če to povečate, postane prepoznavanje obraza natančnejše na račun večje možnosti, da obraz ni dodeljen osebi.", + "machine_learning_min_recognized_faces_description": "Najmanjše število prepoznanih obrazov za osebo, da se ustvari. Če to povečate, postane prepoznavanje obraza natančnejše na račun večje možnosti, da obraz ni dodeljen osebi.", "machine_learning_settings": "Nastavitve strojnega učenja", "machine_learning_settings_description": "Upravljajte funkcije in nastavitve strojnega učenja", "machine_learning_smart_search": "Pametno iskanje", @@ -176,41 +184,41 @@ "metadata_settings": "Nastavitve metapodatkov", "metadata_settings_description": "Upravljanje nastavitev metapodatkov", "migration_job": "Migracija", - "migration_job_description": "Preselite sličice za sredstva in obraze v najnovejšo strukturo map", + "migration_job_description": "Prenesite sličice za sredstva in obraze v najnovejšo strukturo map", "nightly_tasks_cluster_faces_setting_description": "Zaženi prepoznavanje obrazov na novo zaznanih obrazih", "nightly_tasks_cluster_new_faces_setting": "Združite nove obraze", "nightly_tasks_database_cleanup_setting": "Naloge čiščenja baze podatkov", "nightly_tasks_database_cleanup_setting_description": "Očistite stare, potekle podatke iz baze podatkov", - "nightly_tasks_generate_memories_setting": "Ustvarjajte spomine", - "nightly_tasks_generate_memories_setting_description": "Ustvarite nove spomine iz sredstev", + "nightly_tasks_generate_memories_setting": "Ustvari spomine", + "nightly_tasks_generate_memories_setting_description": "Ustvari nove spomine iz sredstev", "nightly_tasks_missing_thumbnails_setting": "Ustvari manjkajoče sličice", "nightly_tasks_missing_thumbnails_setting_description": "Sredstva brez sličic postavite v čakalno vrsto za ustvarjanje sličic", "nightly_tasks_settings": "Nastavitve nočnih opravil", "nightly_tasks_settings_description": "Upravljajte nočne naloge", "nightly_tasks_start_time_setting": "Začetni čas", "nightly_tasks_start_time_setting_description": "Čas, ko strežnik začne izvajati nočne naloge", - "nightly_tasks_sync_quota_usage_setting": "Poraba kvote za sinhronizacijo", + "nightly_tasks_sync_quota_usage_setting": "Posodobi kvoto porabljenega prostora", "nightly_tasks_sync_quota_usage_setting_description": "Posodobi kvoto shrambe uporabnikov glede na trenutno uporabo", "no_paths_added": "Ni dodanih poti", - "no_pattern_added": "Brez dodanega vzorca", + "no_pattern_added": "Nobenega dodanega vzorca", "note_apply_storage_label_previous_assets": "Opomba: Če želite oznako za shranjevanje uporabiti za predhodno naložena sredstva, zaženite", "note_cannot_be_changed_later": "OPOMBA: Tega pozneje ni mogoče spremeniti!", - "notification_email_from_address": "Iz naslova", - "notification_email_from_address_description": "E-poštni naslov pošiljatelja, na primer: \"Immich Photo Server \". Uporabite naslov, s katerega lahko pošiljate e-pošto.", + "notification_email_from_address": "Od naslova", + "notification_email_from_address_description": "Pošiljateljev e-poštni naslov, na primer: \"Immich Photo Server \". Uporabite naslov, s katerega lahko pošiljate e-pošto.", "notification_email_host_description": "Gostitelj e-poštnega strežnika (npr. smtp.immich.app)", "notification_email_ignore_certificate_errors": "Prezri napake potrdil", "notification_email_ignore_certificate_errors_description": "Prezri napake pri preverjanju potrdila TLS (ni priporočljivo)", "notification_email_password_description": "Geslo za uporabo pri preverjanju pristnosti z e-poštnim strežnikom", "notification_email_port_description": "Vrata e-poštnega strežnika (npr. 25, 465 ali 587)", - "notification_email_sent_test_email_button": "Pošljite testno e-pošto in shranite", + "notification_email_sent_test_email_button": "Pošljite testno e-pošto in shrani", "notification_email_setting_description": "Nastavitve za pošiljanje e-poštnih obvestil", "notification_email_test_email": "Pošlji testno e-pošto", - "notification_email_test_email_failed": "Pošiljanje testnega e-poštnega sporočila ni uspelo, preverite svoje vrednosti", + "notification_email_test_email_failed": "Pošiljanje testnega e-poštnega sporočila ni uspelo, preverite svoje podatke", "notification_email_test_email_sent": "Testno e-poštno sporočilo je bilo poslano na {email}. Prosimo, preverite svoj nabiralnik.", "notification_email_username_description": "Uporabniško ime za uporabo pri preverjanju pristnosti z e-poštnim strežnikom", "notification_enable_email_notifications": "Omogoči e-poštna obvestila", "notification_settings": "Nastavitve obvestil", - "notification_settings_description": "Upravljajte nastavitve obvestil, vključno z e-pošto", + "notification_settings_description": "Upravljaj z nastavitvami obvestil, vključno z e-pošto", "oauth_auto_launch": "Samodejni zagon", "oauth_auto_launch_description": "Samodejno zaženite tok prijave OAuth, ko obiščete stran za prijavo", "oauth_auto_register": "Samodejna registracija", @@ -221,7 +229,7 @@ "oauth_mobile_redirect_uri": "Mobilni preusmeritveni URI", "oauth_mobile_redirect_uri_override": "Preglasitev URI preusmeritve za mobilne naprave", "oauth_mobile_redirect_uri_override_description": "Omogoči, ko ponudnik OAuth ne dovoli mobilnega URI-ja, kot je ''{callback}''", - "oauth_role_claim": "Zahteva vloge", + "oauth_role_claim": "Zahteva za vlogo", "oauth_role_claim_description": "Samodejno dodeli skrbniški dostop na podlagi prisotnosti tega zahtevka. Zahtevek ima lahko »uporabnik« ali »skrbnik«.", "oauth_settings": "OAuth", "oauth_settings_description": "Upravljanje nastavitev prijave OAuth", @@ -241,13 +249,13 @@ "person_cleanup_job": "Čiščenje osebe", "quota_size_gib": "Velikost kvote (GiB)", "refreshing_all_libraries": "Osveževanje vseh knjižnic", - "registration": "Administratorska registracija", + "registration": "Registracija administratorja", "registration_description": "Ker ste prvi uporabnik v sistemu, boste dodeljeni kot skrbnik in ste odgovorni za skrbniška opravila, dodatne uporabnike pa boste ustvarili sami.", "require_password_change_on_login": "Od uporabnika zahtevajte spremembo gesla ob prvi prijavi", "reset_settings_to_default": "Ponastavi nastavitve na privzete", "reset_settings_to_recent_saved": "Ponastavite nastavitve na nedavno shranjene nastavitve", "scanning_library": "Pregledovanje knjižnice", - "search_jobs": "Iskanje opravil…", + "search_jobs": "Išči opravila…", "send_welcome_email": "Pošlji pozdravno e-pošto", "server_external_domain_settings": "Zunanja domena", "server_external_domain_settings_description": "Domena za javne skupne povezave, vključno s http(s)://", @@ -256,7 +264,7 @@ "server_settings": "Nastavitve strežnika", "server_settings_description": "Upravljanje nastavitev strežnika", "server_welcome_message": "Pozdravno sporočilo", - "server_welcome_message_description": "Sporočilo, ki se prikaže na strani za prijavo.", + "server_welcome_message_description": "Sporočilo prikazano na prijavni strani.", "sidecar_job": "Stranski metapodatki", "sidecar_job_description": "Odkrijte ali sinhronizirajte stranske metapodatke iz datotečnega sistema", "slideshow_duration_description": "Število sekund za prikaz posamezne slike", @@ -264,7 +272,7 @@ "storage_template_date_time_description": "Časovni žig ustvarjanja sredstva se uporablja za informacije o datumu in času", "storage_template_date_time_sample": "Vzorec časa {date}", "storage_template_enable_description": "Omogoči mehanizem predloge za shranjevanje", - "storage_template_hash_verification_enabled": "Preverjanje zgoščevanja je omogočeno", + "storage_template_hash_verification_enabled": "Omogočeno preverjanje zgoščene vrednosti", "storage_template_hash_verification_enabled_description": "Omogoči preverjanje zgoščene vrednosti, tega ne onemogočite, razen če niste prepričani o posledicah", "storage_template_migration": "Selitev predloge za shranjevanje", "storage_template_migration_description": "Uporabi trenutno {template} za predhodno naložena sredstva", @@ -283,7 +291,7 @@ "template_email_invite_album": "Predloga povabila v album", "template_email_preview": "Predogled", "template_email_settings": "E-poštne predloge", - "template_email_update_album": "Predloga posodobitve albuma", + "template_email_update_album": "Posodobi predlogo albuma", "template_email_welcome": "Predloga pozdravnega e-poštnega sporočila", "template_settings": "Predloge obvestil", "template_settings_description": "Upravljanje predlog po meri za obvestila", @@ -299,14 +307,14 @@ "transcoding_acceleration_qsv": "Hitra sinhronizacija (zahteva procesor Intel 7. generacije ali novejši)", "transcoding_acceleration_rkmpp": "RKMPP (samo na Rockchip SOC)", "transcoding_acceleration_vaapi": "VAAPI", - "transcoding_accepted_audio_codecs": "Sprejeti zvočni kodeki", + "transcoding_accepted_audio_codecs": "Dovoljeni zvočni kodeki", "transcoding_accepted_audio_codecs_description": "Izberite, katerih zvočnih kodekov ni treba prekodirati. Uporablja se samo za določene politike prekodiranja.", "transcoding_accepted_containers": "Sprejeti zabojniki", "transcoding_accepted_containers_description": "Izberite, katerih formatov zabojnika ni treba ponovno muksirati v MP4. Uporablja se samo za določene politike prekodiranja.", "transcoding_accepted_video_codecs": "Podprti video kodeki", "transcoding_accepted_video_codecs_description": "Izberite, katerih video kodekov ni treba prekodirati. Uporablja se samo za določene politike prekodiranja.", - "transcoding_advanced_options_description": "Možnosti večini uporabnikov ne bi bilo treba spreminjati", - "transcoding_audio_codec": "Avdio kodek", + "transcoding_advanced_options_description": "Možnosti, ki jih večini uporabnikov ne treba spreminjati", + "transcoding_audio_codec": "Zvočni kodek", "transcoding_audio_codec_description": "Opus je najbolj kakovostna možnost, vendar ima slabšo združljivost s starimi napravami ali programsko opremo.", "transcoding_bitrate_description": "Videoposnetki, ki presegajo največjo bitno hitrost ali niso v sprejemljivem formatu", "transcoding_codecs_learn_more": "Če želite izvedeti več o tukaj uporabljeni terminologiji, glejte dokumentacijo FFmpeg za kodek H.264, kodek HEVC in VP9 kodek.", @@ -387,8 +395,6 @@ "admin_password": "Skrbniško geslo", "administration": "Administracija", "advanced": "Napredno", - "advanced_settings_beta_timeline_subtitle": "Preizkusite novo izkušnjo aplikacije", - "advanced_settings_beta_timeline_title": "Časovnica beta različice", "advanced_settings_enable_alternate_media_filter_subtitle": "Uporabite to možnost za filtriranje medijev med sinhronizacijo na podlagi alternativnih meril. To poskusite le, če imate težave z aplikacijo, ki zaznava vse albume.", "advanced_settings_enable_alternate_media_filter_title": "[EKSPERIMENTALNO] Uporabite alternativni filter za sinhronizacijo albuma v napravi", "advanced_settings_log_level_title": "Nivo dnevnika: {level}", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "Ali ste prepričani, da želite odstraniti {user}?", "album_search_not_found": "Ni najdenih albumov, ki bi ustrezali vašemu iskanju", "album_share_no_users": "Videti je, da ste ta album dali v skupno rabo z vsemi uporabniki ali pa nimate nobenega uporabnika, s katerim bi ga lahko delili.", + "album_summary": "Povzetek albuma", "album_updated": "Album posodobljen", "album_updated_setting_description": "Prejmite e-poštno obvestilo, ko ima album v skupni rabi nova sredstva", "album_user_left": "Zapustil {album}", @@ -496,6 +503,8 @@ "asset_restored_successfully": "Sredstvo uspešno obnovljeno", "asset_skipped": "Preskočeno", "asset_skipped_in_trash": "V smetnjak", + "asset_trashed": "Sredstvo je bilo premaknjeno v koš", + "asset_troubleshoot": "Odpravljanje težav s sredstvi", "asset_uploaded": "Naloženo", "asset_uploading": "Nalaganje…", "asset_viewer_settings_subtitle": "Upravljaj nastavitve pregledovalnika galerije", @@ -529,8 +538,10 @@ "autoplay_slideshow": "Samodejno predvajanje diaprojekcije", "back": "Nazaj", "back_close_deselect": "Nazaj, zaprite ali prekličite izbiro", + "background_backup_running_error": "Varnostno kopiranje v ozadju se trenutno izvaja, ročnega varnostnega kopiranja ni mogoče zagnati", "background_location_permission": "Dovoljenje za iskanje lokacije v ozadju", "background_location_permission_content": "Ko deluje v ozadju mora imeti Immich za zamenjavo omrežij, *vedno* dostop do natančne lokacije, da lahko aplikacija prebere ime omrežja Wi-Fi", + "background_options": "Možnosti ozadja", "backup": "Varnostna kopija", "backup_album_selection_page_albums_device": "Albumi v napravi ({count})", "backup_album_selection_page_albums_tap": "Tapnite za vključitev, dvakrat tapnite za izključitev", @@ -538,6 +549,7 @@ "backup_album_selection_page_select_albums": "Izberi albume", "backup_album_selection_page_selection_info": "Informacije o izbiri", "backup_album_selection_page_total_assets": "Skupaj unikatnih sredstev", + "backup_albums_sync": "Sinhronizacija varnostnih kopij albumov", "backup_all": "Vse", "backup_background_service_backup_failed_message": "Varnostno kopiranje sredstev ni uspelo. Ponovno poskušam…", "backup_background_service_connection_failed_message": "Povezava s strežnikom ni uspela. Ponovno poskušam…", @@ -654,6 +666,8 @@ "change_pin_code": "Spremeni PIN kodo", "change_your_password": "Spremenite geslo", "changed_visibility_successfully": "Uspešno spremenjena vidnost", + "charging": "Polnjenje", + "charging_requirement_mobile_backup": "Za varnostno kopiranje v ozadju je potrebno polnjenje naprave", "check_corrupt_asset_backup": "Preverite poškodovane varnostne kopije sredstev", "check_corrupt_asset_backup_button": "Izvedi preverjanje", "check_corrupt_asset_backup_description": "To preverjanje zaženite samo prek omrežja Wi-Fi in potem, ko so vsa sredstva varnostno kopirana. Postopek lahko traja nekaj minut.", @@ -740,6 +754,7 @@ "create_user": "Ustvari uporabnika", "created": "Ustvarjeno", "created_at": "Ustvarjeno", + "creating_linked_albums": "Ustvarjanje povezanih albumov ...", "crop": "Obrezovanje", "curated_object_page_title": "Stvari", "current_device": "Trenutna naprava", @@ -889,7 +904,9 @@ "error": "Napaka", "error_change_sort_album": "Vrstnega reda albuma ni bilo mogoče spremeniti", "error_delete_face": "Napaka pri brisanju obraza iz sredstva", + "error_getting_places": "Napaka pri pridobivanju mest", "error_loading_image": "Napaka pri nalaganju slike", + "error_loading_partners": "Napaka pri nalaganju partnerjev: {error}", "error_saving_image": "Napaka: {error}", "error_tag_face_bounding_box": "Napaka pri označevanju obraza - ni mogoče pridobiti koordinat omejevalnega okvirja", "error_title": "Napaka - nekaj je šlo narobe", @@ -1054,6 +1071,7 @@ "favorites_page_no_favorites": "Ni priljubljenih sredstev", "feature_photo_updated": "Funkcijska fotografija je posodobljena", "features": "Funkcije", + "features_in_development": "Funkcije v razvoju", "features_setting_description": "Upravljaj funkcije aplikacije", "file_name": "Ime datoteke", "file_name_or_extension": "Ime ali končnica datoteke", @@ -1218,6 +1236,7 @@ "local": "Lokalno", "local_asset_cast_failed": "Sredstva, ki niso naložena na strežnik, ni mogoče predvajati", "local_assets": "Lokalna sredstva", + "local_media_summary": "Povzetek lokalnih medijev", "local_network": "Lokalno omrežje", "local_network_sheet_info": "Aplikacija se bo povezala s strežnikom prek tega URL-ja, ko bo uporabljala navedeno omrežje Wi-Fi", "location_permission": "Dovoljenje za lokacijo", @@ -1229,6 +1248,7 @@ "location_picker_longitude_hint": "Tukaj vnesi svojo zemljepisno dolžino", "lock": "Zaklepanje", "locked_folder": "Zaklenjena mapa", + "log_detail_title": "Podrobnosti dnevnika", "log_out": "Odjava", "log_out_all_devices": "Odjava vseh naprav", "logged_in_as": "Prijavljen kot {user}", @@ -1259,6 +1279,7 @@ "login_password_changed_success": "Geslo je bilo uspešno posodobljeno", "logout_all_device_confirmation": "Ali ste prepričani, da želite odjaviti vse naprave?", "logout_this_device_confirmation": "Ali ste prepričani, da se želite odjaviti iz te naprave?", + "logs": "Dnevniki", "longitude": "Zemljepisna dolžina", "look": "Izgled", "loop_videos": "Zanka videoposnetkov", @@ -1301,6 +1322,7 @@ "mark_as_read": "Označi kot prebrano", "marked_all_as_read": "Označeno vse kot prebrano", "matches": "Ujemanja", + "matching_assets": "Ujemajoča se sredstva", "media_type": "Vrsta medija", "memories": "Spomini", "memories_all_caught_up": "Vse dohiteno", @@ -1341,6 +1363,7 @@ "name_or_nickname": "Ime ali vzdevek", "network_requirement_photos_upload": "Uporaba mobilnih podatkov za varnostno kopiranje fotografij", "network_requirement_videos_upload": "Uporaba mobilnih podatkov za varnostno kopiranje videoposnetkov", + "network_requirements": "Omrežne zahteve", "network_requirements_updated": "Omrežne zahteve so se spremenile, ponastavitev čakalne vrste za varnostno kopiranje", "networking_settings": "Omrežje", "networking_subtitle": "Upravljaj nastavitve končne točke strežnika", @@ -1351,6 +1374,7 @@ "new_person": "Nova oseba", "new_pin_code": "Nova PIN koda", "new_pin_code_subtitle": "To je vaš prvi dostop do zaklenjene mape. Ustvarite PIN kodo za varen dostop do te strani", + "new_timeline": "Nova časovnica", "new_user_created": "Nov uporabnik ustvarjen", "new_version_available": "NA VOLJO JE NOVA RAZLIČICA", "newest_first": "Najprej najnovejše", @@ -1364,20 +1388,25 @@ "no_assets_message": "KLIKNITE ZA NALOŽITEV SVOJE PRVE FOTOGRAFIJE", "no_assets_to_show": "Ni sredstev za prikaz", "no_cast_devices_found": "Naprav za predvajanje ni bilo mogoče najti", + "no_checksum_local": "Kontrolna vsota ni na voljo – lokalnih sredstev ni mogoče pridobiti", + "no_checksum_remote": "Kontrolna vsota ni na voljo – oddaljenega sredstva ni mogoče pridobiti", "no_duplicates_found": "Najden ni bil noben dvojnik.", "no_exif_info_available": "Podatki o exif niso na voljo", "no_explore_results_message": "Naložite več fotografij, da raziščete svojo zbirko.", "no_favorites_message": "Dodajte priljubljene, da hitreje najdete svoje najboljše slike in videoposnetke", "no_libraries_message": "Ustvarite zunanjo knjižnico za ogled svojih fotografij in videoposnetkov", + "no_local_assets_found": "S to kontrolno vsoto ni bilo najdenih lokalnih sredstev", "no_locked_photos_message": "Fotografije in videoposnetki v zaklenjeni mapi so skriti in se ne bodo prikazali med brskanjem ali iskanjem po knjižnici.", "no_name": "Brez imena", "no_notifications": "Ni obvestil", "no_people_found": "Ni najdenih ustreznih oseb", "no_places": "Ni krajev", + "no_remote_assets_found": "S to kontrolno vsoto ni bilo najdenih oddaljenih sredstev", "no_results": "Brez rezultatov", "no_results_description": "Poskusite s sinonimom ali bolj splošno ključno besedo", "no_shared_albums_message": "Ustvarite album za skupno rabo fotografij in videoposnetkov z osebami v vašem omrežju", "no_uploads_in_progress": "Ni nalaganj v teku", + "not_available": "Ni na voljo", "not_in_any_album": "Ni v nobenem albumu", "not_selected": "Ni izbrano", "note_apply_storage_label_to_previously_uploaded assets": "Opomba: Če želite oznako za shranjevanje uporabiti za predhodno naložena sredstva, zaženite", @@ -1499,6 +1528,7 @@ "port": "Vrata", "preferences_settings_subtitle": "Upravljaj nastavitve aplikacije", "preferences_settings_title": "Nastavitve", + "preparing": "Priprava", "preset": "Prednastavitev", "preview": "Predogled", "previous": "Prejšnj-a/-i", @@ -1564,6 +1594,7 @@ "read_changelog": "Preberi dnevnik sprememb", "readonly_mode_disabled": "Način samo za branje je onemogočen", "readonly_mode_enabled": "Način samo za branje je omogočen", + "ready_for_upload": "Pripravljeno za nalaganje", "reassign": "Prerazporedi", "reassigned_assets_to_existing_person": "Ponovno dodeljeno {count, plural, one {# sredstvo} two {# sredstvi} few {# sredstva} other {# sredstev}} za {name, select, null {an existing person} other {{name}}}", "reassigned_assets_to_new_person": "Ponovno dodeljeno {count, plural, one {# sredstvo} two {# sredstvi} few {# sredstva} other {# sredstev}} za novo osebo", @@ -1588,6 +1619,7 @@ "regenerating_thumbnails": "Obnavljanje sličic", "remote": "Oddaljeno", "remote_assets": "Oddaljena sredstva", + "remote_media_summary": "Povzetek oddaljenih medijev", "remove": "Odstrani", "remove_assets_album_confirmation": "Ali ste prepričani, da želite odstraniti {count, plural, one {# sredstvo} two {# sredstvi} few {# sredstva} other {# sredstev}} iz albuma?", "remove_assets_shared_link_confirmation": "Ali ste prepričani, da želite odstraniti {count, plural, one {# sredstvo} two {# sredstvi} few {# sredstva} other {# sredstev}} iz te skupne povezave?", @@ -1863,6 +1895,7 @@ "show_slideshow_transition": "Prikaži prehod diaprojekcije", "show_supporter_badge": "Značka podpornika", "show_supporter_badge_description": "Prikaži značko podpornika", + "show_text_search_menu": "Prikaži meni za iskanje po besedilu", "shuffle": "Naključno", "sidebar": "Stranska vrstica", "sidebar_display_description": "Prikaži povezavo do pogleda v stranski vrstici", @@ -1893,6 +1926,7 @@ "stacktrace": "Sled nabora", "start": "Začetek", "start_date": "Datum začetka", + "start_date_before_end_date": "Začetni datum mora biti pred končnim datumom", "state": "Dežela", "status": "Status", "stop_casting": "Ustavi predvajanje", @@ -2095,5 +2129,6 @@ "yes": "Da", "you_dont_have_any_shared_links": "Nimate nobenih skupnih povezav", "your_wifi_name": "Vaše ime Wi-Fi", - "zoom_image": "Povečava slike" + "zoom_image": "Povečava slike", + "zoom_to_bounds": "Povečaj do meja" } diff --git a/i18n/sv.json b/i18n/sv.json index 2e1d394bdd..6acee96f66 100644 --- a/i18n/sv.json +++ b/i18n/sv.json @@ -123,6 +123,13 @@ "logging_enable_description": "Aktivera loggning", "logging_level_description": "Vilken loggnivå som ska användas vid aktivering.", "logging_settings": "Loggning", + "machine_learning_availability_checks": "Tillgänglighetskontroller", + "machine_learning_availability_checks_description": "Upptäck och föredrar automatiskt tillgängliga maskininlärningsservrar", + "machine_learning_availability_checks_enabled": "Aktivera tillgänglighetskontroller", + "machine_learning_availability_checks_interval": "Kontrollera intervall", + "machine_learning_availability_checks_interval_description": "Intervall i millisekunder mellan tillgänglighetskontroller", + "machine_learning_availability_checks_timeout": "Begär timeout", + "machine_learning_availability_checks_timeout_description": "Timeout i millisekunder för tillgänglighetskontroller", "machine_learning_clip_model": "CLIP-modell", "machine_learning_clip_model_description": "Namnet på en CLIP-modell listad här . Observera att du måste köra ett \"Smart Sökning\" jobb för alla bilder när du ändrar modell.", "machine_learning_duplicate_detection": "Dubblettdetektering", @@ -387,8 +394,6 @@ "admin_password": "Admin Lösenord", "administration": "Administration", "advanced": "Avancerat", - "advanced_settings_beta_timeline_subtitle": "Testa den nya appupplevelsen", - "advanced_settings_beta_timeline_title": "Tidslinje(BETA)", "advanced_settings_enable_alternate_media_filter_subtitle": "Använd det här alternativet för att filtrera media under synkronisering baserat på alternativa kriterier. Prova detta endast om du har problem med att appen inte hittar alla album.", "advanced_settings_enable_alternate_media_filter_title": "[EXPERIMENTELLT] Använd alternativ enhetsalbum-synkroniseringsfilter", "advanced_settings_log_level_title": "Loggnivå: {level}", @@ -425,6 +430,7 @@ "album_remove_user_confirmation": "Är du säker på att du vill ta bort {user}?", "album_search_not_found": "Inga album hittades som matchade din sökning", "album_share_no_users": "Det verkar som att du har delat det här albumet med alla användare eller så har du inte någon användare att dela med.", + "album_summary": "Albumsammanfattning", "album_updated": "Albumet uppdaterat", "album_updated_setting_description": "Få ett e-postmeddelande när ett delat album har nya tillgångar", "album_user_left": "Lämnade {album}", @@ -496,6 +502,8 @@ "asset_restored_successfully": "Objekt återställt", "asset_skipped": "Överhoppad", "asset_skipped_in_trash": "I papperskorgen", + "asset_trashed": "Tillgång kasserad", + "asset_troubleshoot": "Felsökning av tillgångar", "asset_uploaded": "Uppladdad", "asset_uploading": "Laddar upp...…", "asset_viewer_settings_subtitle": "Hantera inställningar för gallerivisare", @@ -529,8 +537,10 @@ "autoplay_slideshow": "Spela upp bildspel automatiskt", "back": "Bakåt", "back_close_deselect": "Tillbaka, stäng eller avmarkera", + "background_backup_running_error": "Bakgrundssäkerhetskopiering körs för närvarande, kan inte starta manuell säkerhetskopiering", "background_location_permission": "Tillåtelse för bakgrundsplats", "background_location_permission_content": "För att kunna byta nätverk när appen körs i bakgrunden måste Immich *alltid* ha åtkomst till exakt plats så att appen kan läsa av Wi-Fi-nätverkets namn", + "background_options": "Bakgrundsalternativ", "backup": "Säkerhetskopiera", "backup_album_selection_page_albums_device": "Album på enhet ({count})", "backup_album_selection_page_albums_tap": "Tryck en gång för att inkludera, tryck två gånger för att exkludera", @@ -538,6 +548,7 @@ "backup_album_selection_page_select_albums": "Välj album", "backup_album_selection_page_selection_info": "Info om valda objekt", "backup_album_selection_page_total_assets": "Antal unika objekt", + "backup_albums_sync": "Säkerhetskopiera album synkronisering", "backup_all": "Allt", "backup_background_service_backup_failed_message": "Säkerhetskopiering av foton och videor misslyckades. Försöker igen…", "backup_background_service_connection_failed_message": "Anslutning till servern misslyckades. Försöker igen…", @@ -654,6 +665,8 @@ "change_pin_code": "Ändra PIN-kod", "change_your_password": "Ändra ditt lösenord", "changed_visibility_successfully": "Synligheten har ändrats", + "charging": "Laddar", + "charging_requirement_mobile_backup": "Bakgrundssäkerhetskopiering kräver att enheten laddas", "check_corrupt_asset_backup": "Kontrollera om det finns korrupta säkerhetskopior av objekt", "check_corrupt_asset_backup_button": "Kontrollera", "check_corrupt_asset_backup_description": "Kör kontrollen endast över Wi-Fi och när alla objekt har säkerhetskopierats. Det kan ta några minuter.", @@ -740,6 +753,7 @@ "create_user": "Skapa användare", "created": "Skapad", "created_at": "Skapad", + "creating_linked_albums": "Skapar länkade album...", "crop": "Beskär", "curated_object_page_title": "Objekt", "current_device": "Aktuell enhet", @@ -871,7 +885,7 @@ "editor_close_without_save_prompt": "Ändringarna kommer inte att sparas", "editor_close_without_save_title": "Stäng redigeraren?", "editor_crop_tool_h2_aspect_ratios": "Bildförhållande", - "editor_crop_tool_h2_rotation": "Rotation", + "editor_crop_tool_h2_rotation": "Vridning", "email": "Epost", "email_notifications": "E-postaviseringar", "empty_folder": "Mappen är tom", @@ -889,7 +903,9 @@ "error": "Fel", "error_change_sort_album": "Kunde inte ändra sorteringsordning för album", "error_delete_face": "Fel uppstod när ansikte skulle tas bort från objektet", + "error_getting_places": "Det gick inte att hämta platser", "error_loading_image": "Fel vid bildladdning", + "error_loading_partners": "Fel vid inläsning av partner: {error}", "error_saving_image": "Fel: {error}", "error_tag_face_bounding_box": "Fel vid taggning av ansikte – kan inte hämta koordinater för begränsningsruta", "error_title": "Fel – något gick fel", @@ -1015,7 +1031,7 @@ "unable_to_update_user": "Kunde inte uppdatera användare", "unable_to_upload_file": "Det går inte att ladda upp filen" }, - "exif": "Exif", + "exif": "EXIF", "exif_bottom_sheet_description": "Lägg till beskrivning...", "exif_bottom_sheet_description_error": "Fel vid uppdatering av beskrivningen", "exif_bottom_sheet_details": "DETALJER", @@ -1054,6 +1070,7 @@ "favorites_page_no_favorites": "Inga favoritobjekt hittades", "feature_photo_updated": "Funktionsfoto uppdaterad", "features": "Funktioner", + "features_in_development": "Funktioner i utveckling", "features_setting_description": "Hantera appens funktioner", "file_name": "Filnamn", "file_name_or_extension": "Filnamn eller -tillägg", @@ -1071,7 +1088,7 @@ "folders_feature_description": "Bläddra i mappvyn för foton och videoklipp i filsystemet", "forgot_pin_code_question": "Glömt din pinkod?", "forward": "Framåt", - "gcast_enabled": "Google Cast", + "gcast_enabled": "Google-Cast", "gcast_enabled_description": "Denna funktion läser in externa resurser från Google för att fungera.", "general": "Allmänt", "geolocation_instruction_location": "Klicka på en tillgång med GPS-koordinater för att använda dess plats, eller välj en plats direkt från kartan", @@ -1213,11 +1230,12 @@ "link_to_oauth": "Länk till OAuth", "linked_oauth_account": "Länkat OAuth konto", "list": "Lista", - "loading": "Laddar", + "loading": "Inläsning", "loading_search_results_failed": "Det gick inte att läsa in sökresultat", "local": "Lokalt", "local_asset_cast_failed": "Det går inte att casta en tillgång som inte har laddats upp till servern", "local_assets": "Lokala tillgångar", + "local_media_summary": "Sammanfattning av lokala medier", "local_network": "Lokalt nätverk", "local_network_sheet_info": "Appen kommer ansluta till servern via denna URL när det specificerade WiFi-nätverket används", "location_permission": "Plats-rättighet", @@ -1229,6 +1247,7 @@ "location_picker_longitude_hint": "Ange din longitud här", "lock": "Lås", "locked_folder": "Låst Mapp", + "log_detail_title": "Loggdetalj", "log_out": "Logga ut", "log_out_all_devices": "Logga ut alla enheter", "logged_in_as": "Inloggad som {user}", @@ -1259,6 +1278,7 @@ "login_password_changed_success": "Uppdatering av lösenord lyckades", "logout_all_device_confirmation": "Är du säker på att du vill logga ut från alla enheter?", "logout_this_device_confirmation": "Är du säker på att du vill logga ut från denna enhet?", + "logs": "Loggar", "longitude": "Longitud", "look": "Titta", "loop_videos": "Loopa videor", @@ -1301,6 +1321,7 @@ "mark_as_read": "Markera som läst", "marked_all_as_read": "Markerade alla som lästa", "matches": "Matchar", + "matching_assets": "Matchande tillgångar", "media_type": "Mediatyp", "memories": "Minnen", "memories_all_caught_up": "Du är ikapp", @@ -1341,6 +1362,7 @@ "name_or_nickname": "Namn eller smeknamn", "network_requirement_photos_upload": "Använd mobildata för att säkerhetskopiera foton", "network_requirement_videos_upload": "Använd mobildata för att säkerhetskopiera videor", + "network_requirements": "Nätverkskrav", "network_requirements_updated": "Nätverkskraven har ändrats, återställer säkerhetskopieringskön", "networking_settings": "Nätverk", "networking_subtitle": "Hantera inställningar för server-endpointen", @@ -1351,6 +1373,7 @@ "new_person": "Ny person", "new_pin_code": "Ny PIN-kod", "new_pin_code_subtitle": "Det här är första gången du öppnar den låsta mappen. Skapa en PIN-kod för att säkert få åtkomst till den här sidan", + "new_timeline": "Ny tidslinje", "new_user_created": "Ny användare skapad", "new_version_available": "NY VERSION TILLGÄNGLIG", "newest_first": "Nyast först", @@ -1364,20 +1387,25 @@ "no_assets_message": "KLICKA FÖR ATT LADDA UPP DIN FÖRSTA BILD", "no_assets_to_show": "Inga objekt att visa", "no_cast_devices_found": "Inga Cast-enheter hittades", + "no_checksum_local": "Ingen kontrollsumma tillgänglig - kan inte hämta lokala tillgångar", + "no_checksum_remote": "Ingen kontrollsumma tillgänglig - kan inte hämta fjärrtillgång", "no_duplicates_found": "Inga dubbletter hittades.", "no_exif_info_available": "EXIF-information ej tillgänglig", "no_explore_results_message": "Ladda upp fler bilder för att utforska din samling.", "no_favorites_message": "Lägg till favoriter för att snabbt hitta dina bästa bilder och videor", "no_libraries_message": "Skapa ett externt bibliotek för att se dina bilder och videor", + "no_local_assets_found": "Inga lokala tillgångar hittades med denna kontrollsumma", "no_locked_photos_message": "Foton och videor i den låsta mappen är dolda och visas inte när du bläddrar eller söker i ditt bibliotek.", "no_name": "Inget namn", "no_notifications": "Inga aviseringar", "no_people_found": "Inga matchande personer hittade", "no_places": "Inga platser", + "no_remote_assets_found": "Inga fjärrtillgångar hittades med denna kontrollsumma", "no_results": "Inga resultat", "no_results_description": "Pröva en synonym eller ett annat mer allmänt sökord", "no_shared_albums_message": "Skapa ett album för att dela bilder och videor med andra personer", "no_uploads_in_progress": "Inga uppladdningar pågår", + "not_available": "N/A", "not_in_any_album": "Inte i något album", "not_selected": "Ej vald", "note_apply_storage_label_to_previously_uploaded assets": "Obs: Om du vill använda lagringsetiketten på tidigare uppladdade tillgångar kör du", @@ -1499,6 +1527,7 @@ "port": "Port", "preferences_settings_subtitle": "Hantera appens inställningar", "preferences_settings_title": "Inställningar", + "preparing": "Förbereder", "preset": "Förinställt värde", "preview": "Förhandsvisning", "previous": "Föregående", @@ -1515,14 +1544,14 @@ "profile_drawer_client_out_of_date_minor": "Mobilappen är föråldrad. Uppdatera till senaste versionen.", "profile_drawer_client_server_up_to_date": "Klient och server är uppdaterade", "profile_drawer_github": "GitHub", - "profile_drawer_readonly_mode": "Skrivskyddat läge aktiverat. Håll in användaravatarikonen för att avsluta", + "profile_drawer_readonly_mode": "Skrivskyddat läge aktiverat. Långtryck användaravatarikonen för att avsluta.", "profile_drawer_server_out_of_date_major": "Servern har en föråldrad mjukvara. Uppdatera till senaste versionen.", "profile_drawer_server_out_of_date_minor": "Servern har en föråldrad mjukvara. Uppdatera till senaste versionen.", "profile_image_of_user": "{user} profilbild", "profile_picture_set": "Profilbild vald.", "public_album": "Publikt album", "public_share": "Offentlig delning", - "purchase_account_info": "Supporter", + "purchase_account_info": "Anhängare", "purchase_activated_subtitle": "Tack för att du stödjer Immich och open source-mjukvara", "purchase_activated_time": "Aktiverad {date}", "purchase_activated_title": "Aktiveringan av din nyckel lyckades", @@ -1564,6 +1593,7 @@ "read_changelog": "Läs ändringslogg", "readonly_mode_disabled": "Skrivskyddat läge inaktiverat", "readonly_mode_enabled": "Skrivskyddat läge aktiverat", + "ready_for_upload": "Redo för uppladdning", "reassign": "Omfördela", "reassigned_assets_to_existing_person": "Tilldelade om {count, plural, one {# objekt} other {# objekt}} till {name, select, null {an existing person} other {{name}}}", "reassigned_assets_to_new_person": "Tilldelade om {count, plural, one {# objekt} other {# objekt}} till en ny persson", @@ -1588,6 +1618,7 @@ "regenerating_thumbnails": "Uppdaterar miniatyrer", "remote": "Fjärrr", "remote_assets": "Fjärrtillgångar", + "remote_media_summary": "Sammanfattning av fjärrmedia", "remove": "Ta bort", "remove_assets_album_confirmation": "Är du säker på att du vill ta bort {count, plural, one {# asset} other {# assets}} från albumet?", "remove_assets_shared_link_confirmation": "Är du säker på att du vill ta bort {count, plural, one {# asset} other {# assets}} från denna delade länk?", @@ -1863,6 +1894,7 @@ "show_slideshow_transition": "Visa bildspelsövergång", "show_supporter_badge": "Supporteremblem", "show_supporter_badge_description": "Visa supporteremblem", + "show_text_search_menu": "Visa textsökningsmeny", "shuffle": "Blanda", "sidebar": "Sidopanel", "sidebar_display_description": "Visa en länk till vyn i sidofältet", @@ -1893,6 +1925,7 @@ "stacktrace": "Stapelspårning", "start": "Starta", "start_date": "Startdatum", + "start_date_before_end_date": "Startdatumet måste vara före slutdatumet", "state": "Stat", "status": "Status", "stop_casting": "Sluta casta", @@ -1909,7 +1942,7 @@ "suggestions": "Förslag", "sunrise_on_the_beach": "Soluppgång på stranden", "support": "Support", - "support_and_feedback": "Support & Feedback", + "support_and_feedback": "Support och Feedback", "support_third_party_description": "Din Immich-installation paketerades av en tredje part. Problem som du upplever kan orsakas av det paketet, så vänligen ta upp problem med dem i första hand med hjälp av länkarna nedan.", "swap_merge_direction": "Byt sammanfogningsriktning", "sync": "Synka", @@ -2095,5 +2128,6 @@ "yes": "Ja", "you_dont_have_any_shared_links": "Du har inga delade länkar", "your_wifi_name": "Ditt Wi-Fi-namn", - "zoom_image": "Zooma bild" + "zoom_image": "Zooma bild", + "zoom_to_bounds": "Zooma till gränser" } diff --git a/i18n/ta.json b/i18n/ta.json index 96bec1f2f0..f8996ad44b 100644 --- a/i18n/ta.json +++ b/i18n/ta.json @@ -8,7 +8,7 @@ "actions": "செயல்கள்", "active": "செயல்பாட்டில்", "activity": "செயல்பாடுகள்", - "activity_changed": "செயல்பாடு {இயக்கப்பட்டது, தேர்ந்தெடு, சரி {enabled} மற்றது {disabled}}", + "activity_changed": "செயல்பாடு {enabled, select, true {இயக்கப்பட்டது} other {முடக்கப்பட்டது}}", "add": "சேர்", "add_a_description": "விவரம் சேர்", "add_a_location": "இடத்தை சேர்க்கவும்", @@ -24,7 +24,7 @@ "add_path": "பாதை (பாத்) சேர்க்கவும்", "add_photos": "புகைப்படங்களை சேர்க்கவும்", "add_tag": "குறியைச் சேர்க்க", - "add_to": "சேர்க்க…", + "add_to": "சேர்க்கவும்…", "add_to_album": "ஆல்பமில் சேர்க்க", "add_to_album_bottom_sheet_added": "{album}-இல் சேர்க்கப்பட்டது", "add_to_album_bottom_sheet_already_exists": "ஏற்கனவே {album}-இல் உள்ளது", @@ -35,7 +35,7 @@ "add_url": "URL ஐச் சேர்க்கவும்", "added_to_archive": "காப்பகத்தில் சேர்க்கப்பட்டது", "added_to_favorites": "விருப்பங்களில் (பேவரிட்ஸ்) சேர்க்கப்பட்டது", - "added_to_favorites_count": "விருப்பங்களில் (பேவரிட்ஸ்) {count} சேர்க்கப்பட்டது", + "added_to_favorites_count": "விருப்பங்களில் {count, number} சேர்க்கப்பட்டது", "admin": { "add_exclusion_pattern_description": "விலக்கு வடிவங்களைச் சேர்க்கவும். *, **, மற்றும் ? ஆதரிக்கப்படுகிறது. \"Raw\" என்ற பெயரிடப்பட்ட எந்த கோப்பகத்திலும் உள்ள எல்லா கோப்புகளையும் புறக்கணிக்க, \"**/Raw/**\" ஐப் பயன்படுத்தவும். \".tif\" இல் முடியும் எல்லா கோப்புகளையும் புறக்கணிக்க, \"**/*.tif\" ஐப் பயன்படுத்தவும். ஒரு முழுமையான பாதையை புறக்கணிக்க, \"/path/to/ignore/**\" ஐப் பயன்படுத்தவும்.", "admin_user": "நிர்வாக பயனர்", @@ -46,17 +46,17 @@ "authentication_settings_reenable": "மீண்டும் இயக்க, சர்வர் கட்டளை பயன்படுத்தவும்.", "background_task_job": "பின்னணி பணிகள்", "backup_database": "தரவுத்தள காப்புப்பிரதியை உருவாக்கு", - "backup_database_enable_description": "தரவுத்தள காப்புப்பிரதிகளை இயக்கவும்", - "backup_keep_last_amount": "வைத்திருக்க முந்தைய காப்புப்பிரதிகளின் அளவு", - "backup_onboarding_1_description": "கிளவுட் அல்லது வேறு இடத்தில் ஆஃப்சைட் நகல்.", + "backup_database_enable_description": "தரவுத்தள திணிப்புகள் இயக்கவும்", + "backup_keep_last_amount": "வைத்திருக்க முந்தைய திணிப்புகள் அளவு", + "backup_onboarding_1_description": "மேகக்கட்டத்தில் அல்லது மற்றொரு உடல் இடத்தில் ஆஃப்சைட் நகல்.", "backup_onboarding_2_description": "வெவ்வேறு சாதனங்களில் உள்ள நகல் பிரதிகள். இதில் முக்கிய கோப்புகள் மற்றும் அந்தக் கோப்புகளின் நகல் காப்புப்பிரதி ஆகியவை அடங்கும்.", "backup_onboarding_3_description": "உங்கள் தரவின் மொத்த கோப்புகள் அசல் மற்றும் நகல்கள் உட்பட. இதில் 1 வெளிப்புற நகல் மற்றும் 2 சாதனப் பிரதிகள் அடங்கும்.", "backup_onboarding_description": "உங்கள் தரவை பாதுகாப்பதற்காக ஒரு 3-2-1 காப்புப் பிரதி பரிந்துரைக்கப்படுகிறது. முழுமையான காப்பு பாதுகாப்பு தீர்விற்காக, நீங்கள் பதிவேற்றிய புகைப்படங்கள்/வீடியோக்கள் மற்றும் Immich தரவுத்தளத்தின் நகல்களையும் வைத்திருக்க வேண்டும்.", "backup_onboarding_footer": "Immich-ஐ தரவு நகல் காப்பு எடுப்பது பற்றிய மேலும் தகவலுக்கு, தயவுசெய்து ஆவணத்தை பார்க்கவும்.", "backup_onboarding_parts_title": "3-2-1 காப்புப்பிரதியில் பின்வருவன அடங்கும்:", "backup_onboarding_title": "காப்புப்பிரதிகள்", - "backup_settings": "காப்பு அமைப்புகள்", - "backup_settings_description": "தரவுத்தள காப்புப்பிரதி அமைப்புகளை நிர்வகிக்கவும்", + "backup_settings": "தரவுத்தள திணிப்பு அமைப்புகள்", + "backup_settings_description": "தரவுத்தள திணிப்பு அமைப்புகளை நிர்வகிக்கவும்", "cleared_jobs": "முடித்த வேலைகள்: {job}", "config_set_by_file": "கட்டமைப்பு, தற்போது ஒரு கட்டமைப்பு கோப்பு மூலம் அமைக்கப்பட்டுள்ளது", "confirm_delete_library": "{library} படங்கள் நூலகத்தை நிச்சயமாக நீக்க விரும்புகிறீர்களா?", @@ -86,7 +86,7 @@ "image_fullsize_quality_description": "முழு அளவிலான படத் தரம் 1-100 வரை. அதிகமான எண் சிறந்தது, ஆனால் பெரிய கோப்புகளை உருவாக்கும்.", "image_fullsize_title": "முழு அளவிலான பட அமைப்புகள்", "image_prefer_embedded_preview": "உட்பொதிந்த படத்தை முன்னிடு", - "image_prefer_embedded_preview_setting_description": "கிடைக்கும்போது பட செயலாக்கத்திற்கான உள்ளீடாக மூல புகைப்படங்களில் உட்பொதிக்கப்பட்ட மாதிரிக்காட்சிகளைப் பயன்படுத்தவும். இது சில படங்களுக்கு மிகவும் துல்லியமான வண்ணங்களை உருவாக்க முடியும், ஆனால் முன்னோட்டத்தின் தகுதி கேமரா சார்ந்தது மற்றும் படத்தில் அதிக சுருக்க கலைப்பொருட்கள் இருக்கலாம்.", + "image_prefer_embedded_preview_setting_description": "பட செயலாக்கத்திற்கான உள்ளீடாக மூல புகைப்படங்களில் உட்பொதிக்கப்பட்ட முன்னோட்டங்களை பயன்படுத்தவும், கிடைக்கும்போது. இது சில படங்களுக்கு மிகவும் துல்லியமான வண்ணங்களை உருவாக்க முடியும், ஆனால் முன்னோட்டத்தின் தகுதி கேமரா சார்ந்தது மற்றும் படத்தில் அதிக சுருக்க கலைப்பொருட்கள் இருக்கலாம்.", "image_prefer_wide_gamut": "அகன்ற வண்ணவரம்பு தேர்வு", "image_prefer_wide_gamut_setting_description": "சிறு உருவங்களுக்கு காட்சி பி 3 ஐப் பயன்படுத்தவும். இது பரந்த வண்ணங்களைக் கொண்ட படங்களின் அதிர்வுகளை சிறப்பாக பாதுகாக்கிறது, ஆனால் பழைய உலாவி பதிப்பைக் கொண்ட பழைய சாதனங்களில் படங்கள் வித்தியாசமாக தோன்றக்கூடும். வண்ண மாற்றங்களைத் தவிர்க்க SRGB படங்கள் SRGB ஆக வைக்கப்படுகின்றன.", "image_preview_description": "அகற்றப்பட்ட மெட்டாடேட்டாவுடன் நடுத்தர அளவிலான படம், ஒற்றை சொத்தைப் பார்க்கும்போது மற்றும் இயந்திர கற்றலுக்காகப் பயன்படுத்தப்படுகிறது", @@ -106,8 +106,8 @@ "job_settings": "வேலை அமைப்புகள்", "job_settings_description": "வேலை ஒத்திசைவை நிர்வகிக்கவும்", "job_status": "வேலை நிலை", - "jobs_delayed": "{JobCount, பன்மை, பிற {# தாமதமானது}}", - "jobs_failed": "{JobCount, பன்மை, பிற {# தோல்வியுற்றது}}", + "jobs_delayed": "{jobCount, plural, other {# தாமதமானது}}", + "jobs_failed": "{jobCount, plural, other {# தோல்வியுற்றது}}", "library_created": "உருவாக்கப்பட்ட புகைப்பட நூலகம்: {library}", "library_deleted": "புகைப்பட நூலகம் நீக்கப்பட்டது", "library_import_path_description": "இறக்குமதி செய்ய ஒரு கோப்புறையைக் குறிப்பிடவும். துணைக் கோப்புறைகள் உட்பட இந்தக் கோப்புறை படங்கள் மற்றும் வீடியோக்களுக்காக ஸ்கேன் செய்யப்படும்.", @@ -116,13 +116,20 @@ "library_scanning_enable_description": "நியமிக்கப்பட்ட புகைப்பட நூலக ஸ்கேனிங்கை இயக்கு", "library_settings": "வெளிப்புற புகைப்பட நூலகம்", "library_settings_description": "வெளிப்புற புகைப்பட நூலக அமைப்புகளை மேலாண்மை செய்யவும்", - "library_tasks_description": "நூலக பணிகளைச் செய்யுங்கள்", + "library_tasks_description": "புதிய மற்றும்/அல்லது மாற்றப்பட்ட சொத்துக்களுக்கு வெளிப்புற நூலகங்களை ஸ்கேன் செய்யவும்.", "library_watching_enable_description": "கோப்பு மாற்றங்களுக்கு வெளிப்புற நூலகங்களைப் பாருங்கள்", "library_watching_settings": "நூலகப் பார்ப்பது (சோதனை)", "library_watching_settings_description": "மாற்றப்பட்ட புகைப்படங்களைத் தானாகவே பார்க்கவும்", "logging_enable_description": "பதிவு செய்வதை இயக்கு", "logging_level_description": "இயக்கப்பட்டால், எந்தப் பதிவு நிலை பயன்படுத்த வேண்டும்.", "logging_settings": "பதிவு செய்தல்", + "machine_learning_availability_checks": "கிடைக்கும் காசோலைகள்", + "machine_learning_availability_checks_description": "கிடைக்கக்கூடிய இயந்திர கற்றல் சேவையகங்களை தானாக கண்டறிந்து விரும்புங்கள்", + "machine_learning_availability_checks_enabled": "கிடைக்கும் காசோலைகளை இயக்கவும்", + "machine_learning_availability_checks_interval": "இடைவெளியை சரிபார்க்கவும்", + "machine_learning_availability_checks_interval_description": "கிடைக்கும் காசோலைகளுக்கு இடையில் மில்லி விநாடிகளில் இடைவெளி", + "machine_learning_availability_checks_timeout": "நேரம் முடிந்தது", + "machine_learning_availability_checks_timeout_description": "கிடைக்கும் காசோலைகளுக்கு மில்லி விநாடிகளில் நேரம் முடிந்தது", "machine_learning_clip_model": "கிளிப் மாடல்", "machine_learning_clip_model_description": "CLIP மாடல் பெயர் இங்கே பட்டியலிடப்பட்டுள்ளது. ஒரு மாடயலை மாற்றியவுடன் அனைத்து படங்களுக்கும் 'ஸ்மார்ட் தேடல்' வேலையை மீண்டும் இயக்க வேண்டும் என்பதை நினைவில் கொள்ளவும்.", "machine_learning_duplicate_detection": "நகல் (டூப்ளிகேட்) கண்டறிதல்", @@ -151,7 +158,7 @@ "machine_learning_smart_search_description": "CLIP மாடெலைப் பயன்படுத்தி சொற்பொருளில் படங்களைத் தேடுங்கள்", "machine_learning_smart_search_enabled": "ஸ்மார்ட் தேடலை இயக்கு", "machine_learning_smart_search_enabled_description": "முடக்கப்பட்டிருந்தால், ஸ்மார்ட் தேடலுக்காக படங்கள் குறியாக்கம் செய்யப்படாது.", - "machine_learning_url_description": "இயந்திர கற்றல் சேவையகத்தின் முகவரி. ஒன்றுக்கு மேற்பட்ட முகவரி வழங்கப்பட்டால், ஒவ்வொரு சேவையகமும் வெற்றிகரமாக பதிலளிக்கும் வரை, முதல் முதல் கடைசி வரை முயற்சிக்கும்.", + "machine_learning_url_description": "இயந்திர கற்றல் சேவையகத்தின் முகவரி. ஒன்றுக்கு மேற்பட்ட முகவரி வழங்கப்பட்டால், ஒவ்வொரு சேவையகமும் ஒவ்வொன்றாக வெற்றிகரமாக பதிலளிக்கும் வரை, முதலில் இருந்து கடைசி வரை முயற்சிக்கப்படும். பதிலளிக்காத சேவையகங்கள் மீண்டும் ஆன்லைனில் வரும் வரை தற்காலிகமாகப் புறக்கணிக்கப்படும்.", "manage_concurrency": "ஒத்திசைவை நிர்வகிக்கவும்", "manage_log_settings": "பதிவு அமைப்புகளை நிர்வகிக்கவும்", "map_dark_style": "இருண்ட தீம்", @@ -196,7 +203,7 @@ "note_apply_storage_label_previous_assets": "குறிப்பு: முன்பு பதிவேற்றிய படங்களுக்கு சேமிப்பக லேபிளைப் பயன்படுத்த, இதை இயக்கவும்", "note_cannot_be_changed_later": "குறிப்பு: இதை பின்னர் மாற்ற முடியாது!", "notification_email_from_address": "முகவரியிலிருந்து", - "notification_email_from_address_description": "அனுப்புநரின் மின்னஞ்சல் முகவரி, எடுத்துக்காட்டாக: \"இம்மிச் புகைப்பட சேவையகம் \"", + "notification_email_from_address_description": "அனுப்புநரின் மின்னஞ்சல் முகவரி, எடுத்துக்காட்டாக: \"இம்மிச் புகைப்பட சேவையகம் \". மின்னஞ்சல்களை அனுப்ப அனுமதிக்கப்பட்ட முகவரியைப் பயன்படுத்துவதை உறுதிசெய்து கொள்ளுங்கள்.", "notification_email_host_description": "மின்னஞ்சல் சேவையகத்தின் ஹோஸ்ட் (எடுத்துக்காட்டாக: smtp.immich.app)", "notification_email_ignore_certificate_errors": "சான்றிதழ் பிழைகளை புறக்கணிக்கவும்", "notification_email_ignore_certificate_errors_description": "TLS சான்றிதழ் சரிபார்ப்பு பிழைகளை புறக்கணிக்கவும் (பரிந்துரைக்கப்படவில்லை)", @@ -247,7 +254,7 @@ "reset_settings_to_default": "அமைப்புகளை இயல்புநிலைக்கு மீட்டமைக்கவும்", "reset_settings_to_recent_saved": "அண்மையில் சேமிக்கப்பட்ட அமைப்புகளுக்கு அமைப்புகளை மீட்டமைக்கவும்", "scanning_library": "ச்கேனிங் நூலகம்", - "search_jobs": "வேலைகளைத் தேடுங்கள் ...", + "search_jobs": "வேலைகளைத் தேடுங்கள்…", "send_welcome_email": "வரவேற்பு மின்னஞ்சலை அனுப்பவும்", "server_external_domain_settings": "வெளிப்புற களம்", "server_external_domain_settings_description": "HTTP (கள்) உட்பட பொது பகிரப்பட்ட இணைப்புகளுக்கான டொமைன்: //", @@ -268,7 +275,7 @@ "storage_template_hash_verification_enabled_description": "ஹாஷ் சரிபார்ப்பை இயக்குகிறது, தாக்கங்கள் குறித்து உறுதியாக தெரியாவிட்டால் இதை முடக்க வேண்டாம்", "storage_template_migration": "ஸ்டோரேஜ் டெம்ப்ளேட் இடம்பெயர்வு", "storage_template_migration_description": "ஏற்கனவே பதிவேற்றிய புகைப்படங்களுக்கு தற்போதைய {template} ஐப் பயன்படுத்தவும்", - "storage_template_migration_info": "டெம்ப்ளேட் மாற்றங்கள் புதிய படங்களுக்கு மட்டுமே பொருந்தும். முன்பு பதிவேற்றிய படங்களுக்கு டெம்ப்ளேட்டைப் பயன்படுத்த, {job} ஐ இயக்கவும்.", + "storage_template_migration_info": "சேமிப்பக வார்ப்புரு அனைத்து நீட்டிப்புகளையும் சிறிய எழுத்துக்களுக்கு மாற்றும். டெம்ப்ளேட் மாற்றங்கள் புதிய படங்களுக்கு மட்டுமே பொருந்தும். முன்பு பதிவேற்றிய படங்களுக்கு டெம்ப்ளேட்டைப் பயன்படுத்த, {job} ஐ இயக்கவும்.", "storage_template_migration_job": "ஸ்டோரேஜ் டெம்ப்ளேட் இடம்பெயர்வு வேலை", "storage_template_more_details": "இந்த அம்சத்தைப் பற்றிய கூடுதல் விவரங்களுக்கு, Storage Template மற்றும் அதன் தாக்கங்கள் ஐப் பார்க்கவும்", "storage_template_onboarding_description_v2": "இயக்கப்பட்டால், இந்த அம்சம் பயனர் வரையறுக்கப்பட்ட டெம்ப்ளேட்டின் அடிப்படையில் கோப்புகளை தானாக ஒழுங்கமைக்கும். மேலும் தகவலுக்கு, ஆவணங்கள் ஐப் பார்க்கவும்.", @@ -286,7 +293,7 @@ "template_email_update_album": "ஆல்பம் வார்ப்புருவைப் புதுப்பிக்கவும்", "template_email_welcome": "மின்னஞ்சல் வார்ப்புருவை வரவேற்கிறோம்", "template_settings": "அறிவிப்பு வார்ப்புருக்கள்", - "template_settings_description": "அறிவிப்புகளுக்கு தனிப்பயன் வார்ப்புருக்கள் நிர்வகிக்கவும்.", + "template_settings_description": "அறிவிப்புகளுக்கு தனிப்பயன் வார்ப்புருக்கள் நிர்வகிக்கவும்", "theme_custom_css_settings": "தனிப்பயன் CSS", "theme_custom_css_settings_description": "CSS அம்சம் Immich வடிவமைப்பை தனிப்பயனாக்க அனுமதிக்கிறது.", "theme_settings": "தீம் அமைப்புகள்", @@ -318,7 +325,7 @@ "transcoding_encoding_options": "குறியீட்டு விருப்பங்கள்", "transcoding_encoding_options_description": "குறியிடப்பட்ட வீடியோக்களுக்கான கோடெக்குகள், தெளிவுத்திறன், தரம் மற்றும் பிற விருப்பங்களை அமைக்கவும்", "transcoding_hardware_acceleration": "வன்பொருள் முடுக்கம்", - "transcoding_hardware_acceleration_description": "சோதனை; மிக வேகமாக, ஆனால் அதே பிட்ரேட்டில் குறைந்த தகுதி இருக்கும்", + "transcoding_hardware_acceleration_description": "பரிசோதனை: வேகமான டிரான்ஸ்கோடிங் ஆனால் அதே பிட்ரேட்டில் தரத்தைக் குறைக்கலாம்.", "transcoding_hardware_decoding": "வன்பொருள் டிகோடிங்", "transcoding_hardware_decoding_setting_description": "குறியாக்கத்தை விரைவுபடுத்துவதற்கு பதிலாக இறுதி முதல் இறுதி முடுக்கம் ஆகியவற்றை செயல்படுத்துகிறது. எல்லா வீடியோக்களிலும் வேலை செய்யக்கூடாது.", "transcoding_max_b_frames": "அதிகபட்ச பி-பிரேம்கள்", @@ -362,7 +369,7 @@ "unlink_all_oauth_accounts_description": "புதிய வழங்குநருக்கு மாறுவதற்கு முன், அனைத்து OAuth கணக்குகளின் இணைப்பையும் நீக்க நினைவில் கொள்ளுங்கள்.", "unlink_all_oauth_accounts_prompt": "எல்லா OAuth கணக்குகளின் இணைப்பையும் நீக்க விரும்புகிறீர்களா? இது ஒவ்வொரு பயனருக்கும் OAuth ஐடியை மீட்டமைக்கும், மேலும் இதை திரும்பப் பெறு முடியாது.", "user_cleanup_job": "பயனர் தூய்மைப்படுத்துதல்", - "user_delete_delay": " {user} இன் கணக்கு மற்றும் சொத்துக்கள் {தாமதம், பன்மை, ஒன்று {# நாள்} மற்ற {# நாட்கள்}} இல் நிரந்தர நீக்க திட்டமிடப்படும்.", + "user_delete_delay": "{user}இன் கணக்கு மற்றும் சொத்துக்கள் {delay, plural, one {# நாள்} other {# நாள்கள்}}இல் நிரந்தர நீக்கத் திட்டமிடப்படும்.", "user_delete_delay_settings": "தாமதத்தை நீக்கு", "user_delete_delay_settings_description": "எண் of days after நீக்கும் பெறுநர் permanently நீக்கு a user's account and assets. நீக்குவதற்கு தயாராக இருக்கும் பயனர்களைச் சரிபார்க்க பயனர் நீக்குதல் வேலை நள்ளிரவில் இயங்குகிறது. இந்த அமைப்பில் மாற்றங்கள் அடுத்த மரணதண்டனையில் மதிப்பீடு செய்யப்படும்.", "user_delete_immediately": " {user} இன் கணக்கு மற்றும் சொத்துக்கள் நிரந்தர நீக்குதலுக்காக வரிசையில் நிற்கப்படும் உடனடியாக .", @@ -372,7 +379,7 @@ "user_password_has_been_reset": "பயனரின் கடவுச்சொல் மீட்டமைக்கப்பட்டுள்ளது:", "user_password_reset_description": "தயவுசெய்து தற்காலிக கடவுச்சொல்லை பயனருக்கு வழங்கவும், அவர்களின் அடுத்த உள்நுழைவில் கடவுச்சொல்லை மாற்ற வேண்டும் என்று அவர்களுக்குத் தெரிவிக்கவும்.", "user_restore_description": " {user} இன் கணக்கு மீட்டெடுக்கப்படும்.", - "user_restore_scheduled_removal": "பயனரை மீட்டமை - {தேதி, தேதி, நீண்ட} இல் திட்டமிடப்பட்ட நீக்குதல்", + "user_restore_scheduled_removal": "பயனரை மீட்டமை - {date, date, long} இல் திட்டமிடப்பட்ட நீக்குதல்", "user_settings": "பயனர் அமைப்புகள்", "user_settings_description": "பயனர் அமைப்புகளை நிர்வகிக்கவும்", "user_successfully_removed": "பயனர் {email} வெற்றிகரமாக அகற்றப்பட்டது.", @@ -387,41 +394,62 @@ "admin_password": "நிர்வாகி கடவுச்சொல்", "administration": "நிர்வாகம்", "advanced": "மேம்பட்ட", - "advanced_settings_beta_timeline_subtitle": "புதிய பயன்பாட்டு அனுபவத்தை முயற்சிக்கவும்", - "advanced_settings_beta_timeline_title": "பீட்டா காலவரிசை", "advanced_settings_enable_alternate_media_filter_subtitle": "மாற்று அளவுகோல்களின் அடிப்படையில் ஒத்திசைவின் போது மீடியாவை வடிகட்ட இந்த விருப்பத்தைப் பயன்படுத்தவும். எல்லா ஆல்பங்களையும் ஆப்ஸ் கண்டறிவதில் சிக்கல்கள் இருந்தால் மட்டுமே இதை முயற்சிக்கவும்.", "advanced_settings_enable_alternate_media_filter_title": "[பரிசோதனைக்கு உட்பட்டது] மாற்று சாதன ஆல்ப ஒத்திசைவு வடிப்பானைப் பயன்படுத்தவும்", "advanced_settings_log_level_title": "பதிவு நிலை: {level}", "advanced_settings_prefer_remote_subtitle": "சில சாதனங்கள் உள் சொத்துக்களிலிருந்து சிறுபடங்களை ஏற்றுவதில் மிகவும் மெதுவாக இருக்கும். அதற்கு பதிலாக சர்வர் படங்களை ஏற்ற இந்த அமைப்பைச் செயல்படுத்தவும்.", "advanced_settings_prefer_remote_title": "ரிமோட் படங்களுக்கு முன்னுரிமை கொடு", + "advanced_settings_proxy_headers_subtitle": "ஒவ்வொரு நெட்வொர்க் கோரிக்கையுடனும் இம்மிச் அனுப்ப வேண்டிய ப்ராக்ஸி தலைப்புகளை வரையறுக்கவும்", "advanced_settings_proxy_headers_title": "ப்ராக்ஸி தலைப்புகள்", - "advanced_settings_readonly_mode_subtitle": "புகைப்படங்களை மட்டும் பார்க்கக்கூடிய படிக்க மட்டும் பயன்முறையை இயக்குகிறது, பல படங்களைத் தேர்ந்தெடுப்பது, பகிர்தல், அனுப்புதல், நீக்குதல் போன்ற அனைத்தும் முடக்கப்பட்டுள்ளன. பிரதான திரையில் இருந்து பயனர் அவதார் வழியாக படிக்க மட்டும் என்பதை இயக்கு/முடக்கு", + "advanced_settings_readonly_mode_subtitle": "புகைப்படங்களை பார்ப்பதற்கு மட்டுமே அனுமதிக்கும் படிப்பதற்கு மட்டும் பயன்முறையை இயக்குகிறது, பல படங்களைத் தேர்ந்தெடுப்பது, பகிர்தல், அனுப்புதல், நீக்குதல் போன்ற அனைத்தும் முடக்கப்பட்டுள்ளன. பிரதான திரையில் இருந்து பயனர் அவதார் வழியாக படிக்க மட்டும் என்பதை இயக்கு/முடக்கு", "advanced_settings_readonly_mode_title": "படிக்க மட்டுமேயான பயன்முறை", + "advanced_settings_self_signed_ssl_subtitle": "சர்வர் எண்ட்பாயிண்டிற்கான SSL சான்றிதழ் சரிபார்ப்பை தவிர்க்கிறது. சுய கையொப்பமிட்ட சான்றிதழ்களுக்கு இது தேவையானது.", "advanced_settings_self_signed_ssl_title": "சுய கையொப்பமிட்ட SSL சான்றிதழ்களை அனுமதி", "advanced_settings_sync_remote_deletions_subtitle": "இணையத்தில் நடவடிக்கை எடுக்கப்படும்போது, இந்தச் சாதனத்தில் உள்ள ஒரு சொத்தை தானாகவே நீக்கவும் அல்லது மீட்டெடுக்கவும்", - "age_months": "அகவை {மாதங்கள், பன்மை, ஒன்று {# மாதம்} மற்ற {# மாதங்கள்}}", - "age_year_months": "அகவை 1 அகவை, {மாதங்கள், பன்மை, ஒன்று {# மாதம்} மற்ற {# மாதங்கள்}}", - "age_years": "{ஆண்டுகள், பன்மை, பிற {வயது #}}", + "advanced_settings_sync_remote_deletions_title": "தொலைநிலை நீக்குதல்களை ஒத்திசைக்கவும் [பரிசோதனைக்கு உட்பட்டது]", + "advanced_settings_tile_subtitle": "மேம்பட்ட பயனர் அமைப்புகள்", + "advanced_settings_troubleshooting_subtitle": "சரிசெய்தலுக்கு கூடுதல் அம்சங்களை இயக்கவும்", + "advanced_settings_troubleshooting_title": "சரிசெய்தல்", + "age_months": "அகவை {months, plural, one {# திங்கள்} other {# திங்கள்கள்}}", + "age_year_months": "அகவை 1 ஆண்டு, {months, plural, one {# திங்கள்} other {# திங்கள்கள்}}", + "age_years": "{years, plural, other {அகவை #}}", "album_added": "ஆல்பம் சேர்க்கப்பட்டது", "album_added_notification_setting_description": "பகிரப்பட்ட ஆல்பத்தில் நீங்கள் சேர்க்கப்படும்போது மின்னஞ்சல் அறிவிப்பைப் பெறுங்கள்", "album_cover_updated": "ஆல்பம் கவர் புதுப்பிக்கப்பட்டது", "album_delete_confirmation": "{album} ஆல்பத்தை நீக்க விரும்புகிறீர்களா?", "album_delete_confirmation_description": "இந்த ஆல்பம் பகிரப்பட்டால், மற்ற பயனர்களால் இதை அணுக முடியாது.", + "album_deleted": "ஆல்பம் நீக்கப்பட்டது", + "album_info_card_backup_album_excluded": "விலக்கப்பட்டது", + "album_info_card_backup_album_included": "சேர்க்கப்பட்டுள்ளது", "album_info_updated": "ஆல்பம் செய்தி புதுப்பிக்கப்பட்டது", "album_leave": "ஆல்பத்தை விடுங்கள்?", - "album_leave_confirmation": "நீங்கள் நிச்சயமாக {ஆல்பத்தை விட்டு வெளியேற விரும்புகிறீர்களா?", + "album_leave_confirmation": "நீங்கள் நிச்சயமாக {album}ஐ விட்டு வெளியேற விரும்புகிறீர்களா?", "album_name": "ஆல்பத்தின் பெயர்", "album_options": "ஆல்பம் விருப்பங்கள்", "album_remove_user": "பயனரை அகற்றவா?", "album_remove_user_confirmation": "{user} ஐ அகற்ற விரும்புகிறீர்களா?", + "album_search_not_found": "உங்கள் தேடலுடன் பொருந்தக்கூடிய ஆல்பங்கள் எதுவும் இல்லை", "album_share_no_users": "இந்த ஆல்பத்தை நீங்கள் எல்லா பயனர்களுடனும் பகிர்ந்து கொண்டதாகத் தெரிகிறது அல்லது பகிர்வதற்கு உங்களிடம் எந்த பயனரும் இல்லை.", + "album_summary": "ஆல்பம் சுருக்கம்", "album_updated": "ஆல்பம் புதுப்பிக்கப்பட்டது", "album_updated_setting_description": "பகிரப்பட்ட ஆல்பத்தில் புதிய சொத்துக்கள் இருக்கும்போது மின்னஞ்சல் அறிவிப்பைப் பெறுங்கள்", "album_user_left": "இடது {album}", "album_user_removed": "அகற்றப்பட்டது {user}", + "album_viewer_appbar_delete_confirm": "இந்த ஆல்பத்தை உங்கள் கணக்கிலிருந்து நீக்க விரும்புகிறீர்களா?", + "album_viewer_appbar_share_err_delete": "ஆல்பம் நீக்க முடியவில்லை", + "album_viewer_appbar_share_err_leave": "ஆல்பம் விட்டு வெளியேற முடியவில்லை", + "album_viewer_appbar_share_err_remove": "ஆல்பத்திலிருந்து சொத்துக்களை அகற்றுவதில் சிக்கல்கள் உள்ளன", + "album_viewer_appbar_share_err_title": "ஆல்பத்தின் தலைப்பை மாற்ற முடியவில்லை", + "album_viewer_appbar_share_leave": "ஆல்பத்தை விட்டு வெளியேறு", + "album_viewer_appbar_share_to": "பகிரு", + "album_viewer_page_share_add_users": "பயனர்களைச் சேர்க்கவும்", "album_with_link_access": "இணைப்பு உள்ள எவரும் இந்த ஆல்பத்தில் புகைப்படங்களையும் நபர்களையும் பார்க்கட்டும்.", "albums": "ஆல்பம்", - "albums_count": "{எண்ணிக்கை, பன்மை, ஒன்று {{எண்ணிக்கை, எண்} ஆல்பம்} பிற {{எண்ணிக்கை, எண்} ஆல்பங்கள்}}", + "albums_count": "{count, plural, one {{count, number} தொகுப்பு} other {{count, number} தொகுப்புகள்}}", + "albums_default_sort_order": "இயல்புநிலை ஆல்பம் வரிசையாக்கம்", + "albums_default_sort_order_description": "புதிய ஆல்பங்களை உருவாக்கும்போது ஆரம்ப சொத்து வரிசைப்படுத்தல் வரிசை.", + "albums_feature_description": "பிற பயனர்களுடன் பகிர்ந்து கொள்ளக்கூடிய சொத்துக்களின் தொகுப்புகள்.", + "albums_on_device_count": "சாதனத்தில் ஆல்பங்கள் ({count})", "all": "அனைத்தும்", "all_albums": "அனைத்து ஆல்பங்களும்", "all_people": "அனைத்து மக்களும்", @@ -430,47 +458,160 @@ "allow_edits": "திருத்தங்களை அனுமதிக்கவும்", "allow_public_user_to_download": "பொது பயனரை பதிவிறக்கம் செய்ய அனுமதிக்கவும்", "allow_public_user_to_upload": "பொது பயனரை பதிவேற்ற அனுமதிக்கவும்", + "alt_text_qr_code": "QR குறியீடு படம்", "anti_clockwise": "கடிகார எதிர்ப்பு", "api_key": "பநிஇ விசை", "api_key_description": "இந்த மதிப்பு ஒரு முறை மட்டுமே காண்பிக்கப்படும். சாளரத்தை மூடுவதற்கு முன் அதை நகலெடுக்க மறக்காதீர்கள்.", "api_key_empty": "உங்கள் பநிஇ விசை பெயர் காலியாக இருக்கக்கூடாது", "api_keys": "பநிஇ விசைகள்", + "app_bar_signout_dialog_content": "நீங்கள் நிச்சயமாக வெளியேற விரும்புகிறீர்களா?", + "app_bar_signout_dialog_ok": "ஆம்", + "app_bar_signout_dialog_title": "வெளியேறு", "app_settings": "பயன்பாட்டு அமைப்புகள்", "appears_in": "தோன்றும்", + "apply_count": "போடு ({count, number})", "archive": "காப்பகம்", + "archive_action_prompt": "{count} காப்பகத்தில் சேர்க்கப்பட்டது", "archive_or_unarchive_photo": "காப்பகம் அல்லது செயலற்ற புகைப்படம்", + "archive_page_no_archived_assets": "காப்பகப்படுத்தப்பட்ட சொத்துக்கள் எதுவும் கிடைக்கவில்லை", + "archive_page_title": "காப்பகம் ({count})", "archive_size": "காப்பக அளவு", "archive_size_description": "பதிவிறக்கங்களுக்கான காப்பக அளவை உள்ளமைக்கவும் (கிபில்)", - "archived_count": "{எண்ணிக்கை, பன்மை, பிற {காப்பகப்படுத்தப்பட்ட #}}", + "archived": "காப்பகப்படுத்தப்பட்டது", + "archived_count": "{count, plural, other {காப்பகப்படுத்தப்பட்டது #}}", "are_these_the_same_person": "இவர்கள் ஒரே நபரா?", "are_you_sure_to_do_this": "இதை நீங்கள் செய்ய விரும்புகிறீர்களா?", + "asset_action_delete_err_read_only": "சொத்து (களை) மட்டுமே படிக்க முடியாது", + "asset_action_share_err_offline": "இணைப்பில்லாத சொத்து (களை) பெற முடியாது, தவிர்க்கவும்", "asset_added_to_album": "ஆல்பத்தில் சேர்க்கப்பட்டது", - "asset_adding_to_album": "ஆல்பத்தில் சேர்க்கிறது ...", + "asset_adding_to_album": "ஆல்பத்தில் சேர்க்கிறது…", "asset_description_updated": "சொத்து விளக்கம் புதுப்பிக்கப்பட்டுள்ளது", "asset_filename_is_offline": "சொத்து {filename} ஆஃப்லைனில் உள்ளது", "asset_has_unassigned_faces": "சொத்து ஒதுக்கப்படாத முகங்களைக் கொண்டுள்ளது", - "asset_hashing": "ஏசிங் ...", + "asset_hashing": "ஏசிங்…", + "asset_list_group_by_sub_title": "குழு", + "asset_list_layout_settings_dynamic_layout_title": "மாறும் தளவமைப்பு", + "asset_list_layout_settings_group_automatically": "தானியங்கி", + "asset_list_layout_settings_group_by": "மூலம் குழு சொத்துக்கள்", + "asset_list_layout_settings_group_by_month_day": "மாதம் + நாள்", + "asset_list_layout_sub_title": "மனையமைவு", + "asset_list_settings_subtitle": "புகைப்பட கட்டம் தளவமைப்பு அமைப்புகள்", + "asset_list_settings_title": "புகைப்பட கட்டம்", "asset_offline": "சொத்து ஆஃப்லைனில்", "asset_offline_description": "இந்த வெளிப்புற சொத்து இனி வட்டில் காணப்படவில்லை. உதவிக்கு உங்கள் இம்மிச் நிர்வாகியை தொடர்பு கொள்ளவும்.", + "asset_restored_successfully": "சொத்து வெற்றிகரமாக மீட்டெடுக்கப்பட்டது", "asset_skipped": "தவிர்க்கப்பட்டது", "asset_skipped_in_trash": "குப்பையில்", + "asset_trashed": "சொத்து குப்பை", + "asset_troubleshoot": "சொத்து சரிசெய்தல்", "asset_uploaded": "பதிவேற்றப்பட்டது", - "asset_uploading": "பதிவேற்றுதல் ...", + "asset_uploading": "பதிவேற்றுதல்…", + "asset_viewer_settings_subtitle": "உங்கள் கேலரி பார்வையாளர் அமைப்புகளை நிர்வகிக்கவும்", + "asset_viewer_settings_title": "சொத்து பார்வையாளர்", "assets": "சொத்துக்கள்", - "assets_added_count": "சேர்க்கப்பட்டது {எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} மற்ற {# சொத்துக்கள்}}", - "assets_added_to_album_count": "ஆல்பத்தில் {எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} மற்ற {# சொத்துக்கள்}}", - "assets_count": "{எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} மற்ற {# சொத்துக்கள்}}", - "assets_moved_to_trash_count": "நகர்த்தப்பட்டது {எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} மற்ற {# சொத்துக்கள்}}}", - "assets_permanently_deleted_count": "நிரந்தரமாக நீக்கப்பட்டது {எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} பிற {# சொத்துக்கள்}}", - "assets_removed_count": "அகற்றப்பட்டது {எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} மற்ற {# சொத்துக்கள்}}", + "assets_added_count": "சேர்க்கப்பட்டது {count, plural, one {# சொத்து} other {# சொத்துக்கள்}}", + "assets_added_to_album_count": "தொகுப்பில் {count, plural, one {# சொத்து} other {# சொத்துக்கள்}} சேர்க்கப்பட்டது", + "assets_added_to_albums_count": "Added {assetTotal, plural, one {# சொத்து} other {# சொத்துக்கள்}} to {albumTotal, plural, one {# தொகுப்பு} other {# தொகுப்புகள்}}சேர்க்கப்பட்டது", + "assets_cannot_be_added_to_album_count": "{count, plural, one {சொத்து} other {சொத்துக்கள்}} செருகேட்டில் சேர்க்க முடியாது", + "assets_cannot_be_added_to_albums": "{count, plural, one {Asset} other {Assets}} எந்தச் செருகேட்டிலும் சேர்க்க முடியாது", + "assets_count": "{count, plural, one {# சொத்து} other {# சொத்துக்கள்}}", + "assets_deleted_permanently": "{count} சொத்து (கள்) நிரந்தரமாக நீக்கப்பட்டது", + "assets_deleted_permanently_from_server": "{count} சொத்து (கள்) இம்மிச் சேவையகத்திலிருந்து நிரந்தரமாக நீக்கப்பட்டது", + "assets_downloaded_failed": "{count, plural, one {# கோப்பு பதிவிறக்கப்பட்டது - {error} கோப்பு தோல்வியடைந்தது} other {# கோப்புகள் பதிவிறக்கப்பட்டன - {error} கோப்புகள் தோல்வியடைந்தன}}", + "assets_downloaded_successfully": "{count, plural, one {# கோப்பு வெற்றிகரமாகப் பதிவிறக்கம்} other {# கோப்புகள் வெற்றிகரமாகப் பதிவிறக்கம்}}", + "assets_moved_to_trash_count": "குப்பைக்கு {count, plural, one {# சொத்து} other {# சொத்துக்கள்}} நகர்த்தப்பட்டது", + "assets_permanently_deleted_count": "{count, plural, one {# சொத்து} other {# சொத்துக்கள்}} நிரந்தரமாக நீக்கப்பட்டது", + "assets_removed_count": "{count, plural, one {# சொத்து} other {# சொத்துக்கள்}}அகற்றப்பட்டது", + "assets_removed_permanently_from_device": "{count} சொத்து (கள்) உங்கள் சாதனத்திலிருந்து நிரந்தரமாக அகற்றப்பட்டது", "assets_restore_confirmation": "உங்கள் குப்பைத் தொட்டிகள் அனைத்தையும் மீட்டெடுக்க விரும்புகிறீர்களா? இந்த செயலை நீங்கள் செயல்தவிர்க்க முடியாது! எந்தவொரு இணைப்பில்லாத சொத்துக்களையும் இந்த வழியில் மீட்டெடுக்க முடியாது என்பதை நினைவில் கொள்க.", - "assets_restored_count": "மீட்டெடுக்கப்பட்டது {எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} மற்ற {# சொத்துக்கள்}}", - "assets_trashed_count": "குப்பைத்தொட்டியான {எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} மற்ற {# சொத்துக்கள்}}", - "assets_were_part_of_album_count": "{எண்ணிக்கை, பன்மை, ஒரு {Asset was} மற்ற {Assets were}} ஏற்கனவே ஆல்பத்தின் ஒரு பகுதி", + "assets_restored_count": "{count, plural, one {# சொத்து} other {# சொத்துக்கள்}}மீட்டெடுக்கப்பட்டது", + "assets_restored_successfully": "{count} சொத்து (கள்) வெற்றிகரமாக மீட்டெடுக்கப்பட்டது", + "assets_trashed": "{count} சொத்து (கள்) குப்பை", + "assets_trashed_count": "{count, plural, one {# சொத்து} other {# சொத்துக்கள்}} குப்பையாகப்பட்டது", + "assets_trashed_from_server": "{count} சொத்து (கள்) இம்மிச் சேவையகத்திலிருந்து குப்பைத் தொட்டியில்", + "assets_were_part_of_album_count": "{count, plural, one {சொத்து} other {சொத்துக்கள்}} ஏற்கனவே தொகுப்பின் ஒரு பகுதி", + "assets_were_part_of_albums_count": "{count, plural, one {சொத்து} other {சொத்துக்கள்}} ஏற்கனவே தொகுப்புகளின் ஒரு பகுதி", "authorized_devices": "அங்கீகரிக்கப்பட்ட சாதனங்கள்", + "automatic_endpoint_switching_subtitle": "கிடைக்கும்போது நியமிக்கப்பட்ட வைஃபை மீது உள்ளூரில் இணைக்கவும், வேறு இடங்களில் மாற்று இணைப்புகளைப் பயன்படுத்தவும்", + "automatic_endpoint_switching_title": "தானியங்கி முகவரி மாறுதல்", + "autoplay_slideshow": "ஆட்டோபிளே ச்லைடுசோ", "back": "பின்", "back_close_deselect": "பின், மூடு அல்லது தேர்வுநீக்கம்", + "background_backup_running_error": "பின்னணி காப்புப்பிரதி தற்போது இயங்குகிறது, கைமுறை காப்புப்பிரதியைத் தொடங்க முடியாது", + "background_location_permission": "பின்னணி இருப்பிட இசைவு", + "background_location_permission_content": "பின்னணியில் இயங்கும் போது நெட்வொர்க்குகளை மாற்ற, இம்மிச் *எப்போதும்* துல்லியமான இருப்பிட அணுகலைக் கொண்டிருக்க வேண்டும், எனவே பயன்பாடு வைஃபை நெட்வொர்க்கின் பெயரைப் படிக்க முடியும்", + "background_options": "பின்னணி விருப்பங்கள்", + "backup": "காப்புப்பிரதி", + "backup_album_selection_page_albums_device": "சாதனத்தில் ஆல்பங்கள் ({count})", + "backup_album_selection_page_albums_tap": "சேர்க்க தட்டவும், விலக்க இரட்டை தட்டவும்", + "backup_album_selection_page_assets_scatter": "சொத்துக்கள் பல ஆல்பங்களில் சிதறக்கூடும். எனவே, காப்பு செயல்பாட்டின் போது ஆல்பங்கள் சேர்க்கப்படலாம் அல்லது விலக்கப்படலாம்.", + "backup_album_selection_page_select_albums": "ஆல்பங்களைத் தேர்ந்தெடுக்கவும்", + "backup_album_selection_page_selection_info": "தேர்வு செய்தி", + "backup_album_selection_page_total_assets": "மொத்த தனித்துவமான சொத்துக்கள்", + "backup_albums_sync": "காப்புப்பிரதி ஆல்பங்கள் ஒத்திசைவு", + "backup_all": "அனைத்தும்", + "backup_background_service_backup_failed_message": "சொத்துக்களை காப்புப்பிரதி எடுக்கத் தவறிவிட்டது. மீண்டும் முயற்சிப்பது…", + "backup_background_service_connection_failed_message": "சேவையகத்துடன் இணைக்கத் தவறிவிட்டது. மீண்டும் முயற்சிப்பது…", + "backup_background_service_current_upload_notification": "பதிவேற்றுதல் {filename}", + "backup_background_service_default_notification": "புதிய சொத்துக்களைச் சரிபார்க்கிறது…", + "backup_background_service_error_title": "காப்பு பிழை", + "backup_background_service_in_progress_notification": "உங்கள் சொத்துக்களை காப்புப் பிரதி எடுக்கிறது…", + "backup_background_service_upload_failure_notification": "{filename} பதிவேற்றுவதில் தோல்வி", + "backup_controller_page_albums": "காப்புப்பிரதி ஆல்பங்கள்", + "backup_controller_page_background_app_refresh_disabled_content": "பின்னணி காப்புப்பிரதியைப் பயன்படுத்துவதற்காக அமைப்புகளில் பின்னணி பயன்பாட்டு புதுப்பிப்புகளை இயக்கவும்> பொது> பின்னணி பயன்பாட்டு புதுப்பிப்பு.", + "backup_controller_page_background_app_refresh_disabled_title": "பின்னணி பயன்பாட்டு புதுப்பிப்பு முடக்கப்பட்டது", + "backup_controller_page_background_app_refresh_enable_button_text": "அமைப்புகளுக்குச் செல்லுங்கள்", + "backup_controller_page_background_battery_info_link": "எப்படி என்று எனக்குக் காட்டு", + "backup_controller_page_background_battery_info_message": "சிறந்த பின்னணி காப்புப்பிரதி அனுபவத்திற்கு, இம்மிச்சிற்கான பின்னணி செயல்பாட்டைக் கட்டுப்படுத்தும் எந்த பேட்டரி மேம்படுத்தல்களையும் முடக்கவும். \n\nஇது சாதனம் சார்ந்ததாக இருப்பதால், உங்கள் சாதன உற்பத்தியாளருக்கு தேவையான தகவல்களைத் தேடுங்கள்.", + "backup_controller_page_background_battery_info_ok": "சரி", + "backup_controller_page_background_battery_info_title": "பேட்டரி மேம்படுத்தல்கள்", + "backup_controller_page_background_charging": "கட்டணம் வசூலிக்கும் போது மட்டுமே", + "backup_controller_page_background_configure_error": "பின்னணி சேவையை உள்ளமைக்கத் தவறிவிட்டது", + "backup_controller_page_background_delay": "புதிய சொத்துக்களை தாமதப்படுத்துங்கள்: {duration}", + "backup_controller_page_background_description": "பயன்பாட்டைத் திறக்கத் தேவையில்லாமல் எந்த புதிய சொத்துக்களையும் தானாக காப்புப் பிரதி எடுக்க பின்னணி சேவையை இயக்கவும்", + "backup_controller_page_background_is_off": "தானியங்கி பின்னணி காப்புப்பிரதி முடக்கப்பட்டுள்ளது", + "backup_controller_page_background_is_on": "தானியங்கி பின்னணி காப்புப்பிரதி இயக்கத்தில் உள்ளது", + "backup_controller_page_background_turn_off": "பின்னணி சேவையை அணைக்கவும்", + "backup_controller_page_background_turn_on": "பின்னணி சேவையை இயக்கவும்", + "backup_controller_page_background_wifi": "வைஃபை மட்டுமே", + "backup_controller_page_backup": "காப்புப்பிரதி", + "backup_controller_page_backup_selected": "தேர்ந்தெடுக்கப்பட்டது: ", + "backup_controller_page_backup_sub": "புகைப்படங்கள் மற்றும் வீடியோக்களை காப்புப் பிரதி எடுக்கவும்", + "backup_controller_page_created": "உருவாக்கப்பட்டது: {date}", + "backup_controller_page_desc_backup": "பயன்பாட்டைத் திறக்கும்போது புதிய சொத்துக்களை சேவையகத்தில் தானாக பதிவேற்ற முன்புற காப்புப்பிரதியை இயக்கவும்.", + "backup_controller_page_excluded": "விலக்கப்பட்டது: ", + "backup_controller_page_failed": "தோல்வியுற்றது ({count})", + "backup_controller_page_filename": "கோப்பு பெயர்: {filename} [{size}]", + "backup_controller_page_id": "ஐடி: {id}", + "backup_controller_page_info": "காப்புப்பிரதி செய்தி", + "backup_controller_page_none_selected": "எதுவும் தேர்ந்தெடுக்கப்படவில்லை", + "backup_controller_page_remainder": "மீதமுள்ள", + "backup_controller_page_remainder_sub": "தேர்விலிருந்து காப்புப் பிரதி எடுக்க மீதமுள்ள புகைப்படங்கள் மற்றும் வீடியோக்கள்", + "backup_controller_page_server_storage": "சேவையக சேமிப்பு", + "backup_controller_page_start_backup": "காப்புப்பிரதியைத் தொடங்கவும்", + "backup_controller_page_status_off": "தானியங்கி முன்புற காப்புப்பிரதி முடக்கப்பட்டுள்ளது", + "backup_controller_page_status_on": "தானியங்கி முன்புற காப்புப்பிரதி இயக்கத்தில் உள்ளது", + "backup_controller_page_storage_format": "{total} இல் {used} பயன்படுத்தப்பட்டது", + "backup_controller_page_to_backup": "ஆதரிக்கப்பட வேண்டிய ஆல்பங்கள்", + "backup_controller_page_total_sub": "தேர்ந்தெடுக்கப்பட்ட ஆல்பங்களிலிருந்து அனைத்து தனித்துவமான புகைப்படங்கள் மற்றும் வீடியோக்கள்", + "backup_controller_page_turn_off": "முன்புற காப்புப்பிரதியை அணைக்கவும்", + "backup_controller_page_turn_on": "முன்புற காப்புப்பிரதியை இயக்கவும்", + "backup_controller_page_uploading_file_info": "கோப்பு தகவலைப் பதிவேற்றுகிறது", + "backup_err_only_album": "ஒரே ஆல்பத்தை அகற்ற முடியாது", + "backup_info_card_assets": "சொத்துக்கள்", + "backup_manual_cancelled": "ரத்து செய்யப்பட்டது", + "backup_manual_in_progress": "ஏற்கனவே முன்னேற்றத்தில் பதிவேற்றவும். சிறிது நேரம் கழித்து முயற்சிக்கவும்", + "backup_manual_success": "செய்", + "backup_manual_title": "நிலை பதிவேற்றும் நிலை", + "backup_options": "காப்பு விருப்பங்கள்", + "backup_options_page_title": "காப்பு விருப்பங்கள்", + "backup_setting_subtitle": "பின்னணி மற்றும் முன்புற பதிவேற்ற அமைப்புகளை நிர்வகிக்கவும்", + "backup_settings_subtitle": "பதிவேற்ற அமைப்புகளை நிர்வகிக்கவும்", "backward": "பின்னோக்கு", + "biometric_auth_enabled": "பயோமெட்ரிக் ஏற்பு இயக்கப்பட்டது", + "biometric_locked_out": "நீங்கள் பயோமெட்ரிக் அங்கீகாரத்திலிருந்து பூட்டப்பட்டிருக்கிறீர்கள்", + "biometric_no_options": "பயோமெட்ரிக் விருப்பங்கள் எதுவும் கிடைக்கவில்லை", + "biometric_not_available": "இந்த சாதனத்தில் பயோமெட்ரிக் ஏற்பு கிடைக்கவில்லை", "birthdate_saved": "பிறந்த தேதி வெற்றிகரமாக சேமிக்கப்பட்டது", "birthdate_set_description": "ஒரு புகைப்படத்தின் போது இந்த நபரின் வயதைக் கணக்கிட பிறந்த தேதி பயன்படுத்தப்படுகிறது.", "blurred_background": "மங்கலான பின்னணி", @@ -481,31 +622,71 @@ "bulk_keep_duplicates_confirmation": "நீங்கள் {எண்ணிக்கை, பன்மை, ஒன்று {# நகல் சொத்து} பிற {# நகல் சொத்துக்கள்} be வைக்க விரும்புகிறீர்களா? இது எதையும் நீக்காமல் அனைத்து நகல் குழுக்களையும் தீர்க்கும்.", "bulk_trash_duplicates_confirmation": "நீங்கள் மொத்தமாக குப்பை {எண்ணிக்கை, பன்மை, ஒன்று {# நகல் சொத்து} பிற {# நகல் சொத்துக்கள்}}}} செய்ய விரும்புகிறீர்களா? இது ஒவ்வொரு குழுவின் மிகப்பெரிய சொத்தை வைத்திருக்கும் மற்றும் மற்ற அனைத்து நகல்களையும் குப்பைத் தொட்டியாக இருக்கும்.", "buy": "இம்மியை வாங்கவும்", + "cache_settings_clear_cache_button": "தெளிவான தற்காலிக சேமிப்பு", + "cache_settings_clear_cache_button_title": "பயன்பாட்டின் தற்காலிக சேமிப்பை அழிக்கிறது. கேச் மீண்டும் கட்டப்படும் வரை இது பயன்பாட்டின் செயல்திறனை கணிசமாக பாதிக்கும்.", + "cache_settings_duplicated_assets_clear_button": "தெளிவான", + "cache_settings_duplicated_assets_subtitle": "பயன்பாட்டால் பட்டியலிடப்பட்ட புறக்கணிக்கப்பட்ட புகைப்படங்கள் மற்றும் வீடியோக்கள்", + "cache_settings_duplicated_assets_title": "நகல் சொத்துக்கள் ({count})", + "cache_settings_statistics_album": "நூலக சிறு உருவங்கள்", + "cache_settings_statistics_full": "முழு படங்கள்", + "cache_settings_statistics_shared": "பகிரப்பட்ட ஆல்பம் சிறுபடம்", + "cache_settings_statistics_thumbnail": "சிறு உருவங்கள்", + "cache_settings_statistics_title": "கேச் பயன்பாடு", + "cache_settings_subtitle": "இம்மிச் மொபைல் பயன்பாட்டின் தற்காலிக சேமிப்பு நடத்தையை கட்டுப்படுத்தவும்", + "cache_settings_tile_subtitle": "உள்ளக சேமிப்பக நடத்தையை கட்டுப்படுத்தவும்", + "cache_settings_tile_title": "உள்ளக சேமிப்பு", + "cache_settings_title": "தேக்கக அமைப்புகள்", "camera": "கேமரா", "camera_brand": "கேமரா சூட்டுக்குறி", "camera_model": "கேமரா மாதிரி", "cancel": "ரத்துசெய்", "cancel_search": "தேடலை ரத்துசெய்", + "canceled": "ரத்து செய்யப்பட்டது", + "canceling": "ரத்துசெய்யும்", "cannot_merge_people": "மக்களை ஒன்றிணைக்க முடியாது", "cannot_undo_this_action": "இந்த செயலை நீங்கள் செயல்தவிர்க்க முடியாது!", "cannot_update_the_description": "விளக்கத்தை புதுப்பிக்க முடியாது", + "cast": "நடிகர்கள்", + "cast_description": "கிடைக்கக்கூடிய வார்ப்பு இடங்களை உள்ளமைக்கவும்", "change_date": "தேதியை மாற்றவும்", + "change_description": "விளக்கத்தை மாற்றவும்", + "change_display_order": "காட்சி வரிசையை மாற்றவும்", "change_expiration_time": "காலாவதி நேரத்தை மாற்றவும்", "change_location": "இருப்பிடத்தை மாற்றவும்", "change_name": "பெயரை மாற்றவும்", - "change_name_successfully": "பெயரை வெற்றிகரமாக மாற்றவும்", + "change_name_successfully": "பெயர் வெற்றிகரமாக மாற்றப்பட்டது", "change_password": "கடவுச்சொல்லை மாற்றவும்", "change_password_description": "நீங்கள் கணினியில் கையொப்பமிடுவது இதுவே முதல் முறை அல்லது உங்கள் கடவுச்சொல்லை மாற்றுவதற்கான கோரிக்கை செய்யப்பட்டுள்ளது. கீழே புதிய கடவுச்சொல்லை உள்ளிடவும்.", + "change_password_form_confirm_password": "கடவுச்சொல்லை உறுதிப்படுத்தவும்", + "change_password_form_description": "ஆய் {name}, \n\nநீங்கள் கணினியில் கையொப்பமிடுவது இதுவே முதல் முறை அல்லது உங்கள் கடவுச்சொல்லை மாற்றுவதற்கான கோரிக்கை செய்யப்பட்டுள்ளது. கீழே புதிய கடவுச்சொல்லை உள்ளிடவும்.", + "change_password_form_new_password": "புதிய கடவுச்சொல்", + "change_password_form_password_mismatch": "கடவுச்சொற்கள் பொருந்தவில்லை", + "change_password_form_reenter_new_password": "புதிய கடவுச்சொல்லை மீண்டும் உள்ளிடவும்", + "change_pin_code": "முள் குறியீட்டை மாற்றவும்", "change_your_password": "உங்கள் கடவுச்சொல்லை மாற்றவும்", "changed_visibility_successfully": "தெரிவுநிலை வெற்றிகரமாக மாற்றப்பட்டது", + "charging": "சார்சிங்", + "charging_requirement_mobile_backup": "பின்னணி காப்புப்பிரதிக்கு சாதனம் சார்ச் செய்ய வேண்டும்", + "check_corrupt_asset_backup": "ஊழல் சொத்து காப்புப்பிரதிகளை சரிபார்க்கவும்", + "check_corrupt_asset_backup_button": "காசோலை செய்யுங்கள்", + "check_corrupt_asset_backup_description": "இந்த காசோலையை வைஃபை மீது மட்டுமே இயக்கவும், அனைத்து சொத்துக்களும் காப்புப் பிரதி எடுக்கப்பட்டவுடன். செயல்முறை சில நிமிடங்கள் ஆகலாம்.", "check_logs": "பதிவுகளை சரிபார்க்கவும்", "choose_matching_people_to_merge": "ஒன்றிணைக்க பொருந்தக்கூடிய நபர்களைத் தேர்வுசெய்க", "city": "நகரம்", "clear": "தெளிவான", "clear_all": "அனைத்தையும் அழிக்கவும்", "clear_all_recent_searches": "அண்மைக் கால அனைத்து தேடல்களையும் அழிக்கவும்", + "clear_file_cache": "கோப்பு தற்காலிக சேமிப்பை அழிக்கவும்", "clear_message": "தெளிவான செய்தி", "clear_value": "தெளிவான மதிப்பு", + "client_cert_dialog_msg_confirm": "சரி", + "client_cert_enter_password": "கடவுச்சொல்லை உள்ளிடவும்", + "client_cert_import": "இறக்குமதி", + "client_cert_import_success_msg": "கிளையன்ட் சான்றிதழ் இறக்குமதி செய்யப்படுகிறது", + "client_cert_invalid_msg": "தவறான சான்றிதழ் கோப்பு அல்லது தவறான கடவுச்சொல்", + "client_cert_remove_msg": "கிளையன்ட் சான்றிதழ் அகற்றப்பட்டது", + "client_cert_subtitle": "PKCS12 (.p12, .pfx) வடிவமைப்பை மட்டுமே ஆதரிக்கிறது. சான்றிதழ் இறக்குமதி/அகற்றுதல் உள்நுழைவதற்கு முன்புதான் கிடைக்கும்", + "client_cert_title": "எச்எச்எல் கிளையன்ட் சான்றிதழ்", "clockwise": "Locklowsy", "close": "மூடு", "collapse": "சரிவு", @@ -516,14 +697,31 @@ "comment_options": "கருத்து விருப்பங்கள்", "comments_and_likes": "கருத்துகள் மற்றும் விருப்பங்கள்", "comments_are_disabled": "கருத்துகள் முடக்கப்பட்டுள்ளன", + "common_create_new_album": "புதிய ஆல்பத்தை உருவாக்கவும்", + "common_server_error": "தயவுசெய்து உங்கள் பிணைய இணைப்பைச் சரிபார்க்கவும், சேவையகம் அடையக்கூடியது மற்றும் பயன்பாடு/சேவையக பதிப்புகள் இணக்கமானவை என்பதை உறுதிப்படுத்தவும்.", + "completed": "முடிந்தது", "confirm": "உறுதிப்படுத்தவும்", "confirm_admin_password": "நிர்வாகி கடவுச்சொல்லை உறுதிப்படுத்தவும்", + "confirm_delete_face": "சொத்திலிருந்து {name} முகத்தை நீக்க விரும்புகிறீர்களா?", "confirm_delete_shared_link": "இந்த பகிரப்பட்ட இணைப்பை நீக்க விரும்புகிறீர்களா?", "confirm_keep_this_delete_others": "இந்த சொத்தைத் தவிர அடுக்கில் உள்ள மற்ற அனைத்து சொத்துகளும் நீக்கப்படும். நீங்கள் தொடர விரும்புகிறீர்களா?", + "confirm_new_pin_code": "புதிய முள் குறியீட்டை உறுதிப்படுத்தவும்", "confirm_password": "கடவுச்சொல்லை உறுதிப்படுத்தவும்", + "confirm_tag_face": "இந்த முகத்தை {பெயர் அச் எனக் குறிக்க விரும்புகிறீர்களா?", + "confirm_tag_face_unnamed": "இந்த முகத்தை குறிக்க விரும்புகிறீர்களா?", + "connected_device": "இணைக்கப்பட்ட சாதனம்", + "connected_to": "இணைக்கப்பட்டுள்ளது", "contain": "கட்டுப்படுத்தவும்", "context": "சூழல்", "continue": "தொடரவும்", + "control_bottom_app_bar_create_new_album": "புதிய ஆல்பத்தை உருவாக்கவும்", + "control_bottom_app_bar_delete_from_immich": "இம்மிச்சிலிருந்து நீக்கு", + "control_bottom_app_bar_delete_from_local": "சாதனத்திலிருந்து நீக்கு", + "control_bottom_app_bar_edit_location": "இருப்பிடத்தைத் திருத்தவும்", + "control_bottom_app_bar_edit_time": "தேதி & நேரத்தைத் திருத்தவும்", + "control_bottom_app_bar_share_link": "இணைப்பைப் பகிரவும்", + "control_bottom_app_bar_share_to": "பகிர்ந்து கொள்ளுங்கள்", + "control_bottom_app_bar_trash_from_immich": "குப்பைக்கு நகர்த்தவும்", "copied_image_to_clipboard": "இடைநிலைப்பலகைக்கு படத்தை நகலெடுத்தது.", "copied_to_clipboard": "இடைநிலைப்பலகைக்கு நகலெடுக்கப்பட்டது!", "copy_error": "நகல் பிழை", @@ -538,51 +736,91 @@ "covers": "மறையம்", "create": "உருவாக்கு", "create_album": "ஆல்பத்தை உருவாக்கவும்", + "create_album_page_untitled": "தலைப்பிடப்படாத", "create_library": "நூலகத்தை உருவாக்கவும்", "create_link": "இணைப்பை உருவாக்கவும்", "create_link_to_share": "பகிர்வுக்கு இணைப்பை உருவாக்கவும்", "create_link_to_share_description": "இணைப்பு உள்ள எவரும் தேர்ந்தெடுக்கப்பட்ட புகைப்படங்களைக் காணட்டும்)", + "create_new": "புதியதை உருவாக்கவும்", "create_new_person": "புதிய நபரை உருவாக்கவும்", "create_new_person_hint": "தேர்ந்தெடுக்கப்பட்ட சொத்துக்களை புதிய நபருக்கு ஒதுக்கவும்", "create_new_user": "புதிய பயனரை உருவாக்கவும்", + "create_shared_album_page_share_add_assets": "சொத்துக்களைச் சேர்க்கவும்", + "create_shared_album_page_share_select_photos": "புகைப்படங்களைத் தேர்ந்தெடுக்கவும்", + "create_shared_link": "பகிரப்பட்ட இணைப்பை உருவாக்கவும்", "create_tag": "குறிச்சொல்லை உருவாக்கவும்", "create_tag_description": "புதிய குறிச்சொல்லை உருவாக்கவும். உள்ளமைக்கப்பட்ட குறிச்சொற்களுக்கு, முன்னோக்கி ச்லாச்கள் உட்பட குறிச்சொல்லின் முழு பாதையையும் உள்ளிடவும்.", "create_user": "பயனரை உருவாக்கு", "created": "உருவாக்கப்பட்டது", + "created_at": "உருவாக்கப்பட்டது", + "creating_linked_albums": "இணைக்கப்பட்ட ஆல்பங்களை உருவாக்குதல் ...", + "crop": "பயிர்", + "curated_object_page_title": "விசயங்கள்", "current_device": "தற்போதைய சாதனம்", + "current_pin_code": "தற்போதைய முள் குறியீடு", + "current_server_address": "தற்போதைய சேவையக முகவரி", "custom_locale": "தனிப்பயன் இடம்", "custom_locale_description": "மொழி மற்றும் பிராந்தியத்தின் அடிப்படையில் வடிவமைப்பு தேதிகள் மற்றும் எண்கள்", + "custom_url": "தனிப்பயன் முகவரி", + "daily_title_text_date": "E, mmm dd", + "daily_title_text_date_year": "E, mmm dd, yyyy", "dark": "இருண்ட", + "dark_theme": "இருண்ட கருப்பொருளை மாற்றவும்", "date_after": "தேதி", "date_and_time": "தேதி மற்றும் நேரம்", "date_before": "முன் தேதி", + "date_format": "E, lll d, ஒய் • h: mm a", "date_of_birth_saved": "பிறந்த தேதி வெற்றிகரமாக சேமிக்கப்பட்டது", "date_range": "தேதி வரம்பு", "day": "நாள்", + "days": "நாட்கள்", "deduplicate_all": "அனைத்தையும் கழித்தல்", + "deduplication_criteria_1": "பைட்டுகளில் பட அளவு", + "deduplication_criteria_2": "EXIF தரவின் எண்ணிக்கை", + "deduplication_info": "கழித்தல் செய்தி", + "deduplication_info_description": "சொத்துக்களை தானாக முன்னெடுத்துச் செல்லவும், மொத்தமாக நகல்களை அகற்றவும், நாங்கள் பார்க்கிறோம்:", "default_locale": "இயல்புநிலை இடம்", "default_locale_description": "உங்கள் உலாவி இருப்பிடத்தின் அடிப்படையில் வடிவமைப்பு தேதிகள் மற்றும் எண்கள்", "delete": "நீக்கு", + "delete_action_confirmation_message": "இந்த சொத்தை நீக்க விரும்புகிறீர்களா? இந்த நடவடிக்கை சொத்தை சேவையகத்தின் குப்பைக்கு நகர்த்தும், மேலும் நீங்கள் அதை உள்நாட்டில் நீக்க விரும்பினால் கேட்கும்", + "delete_action_prompt": "{count} நீக்கப்பட்டது", "delete_album": "ஆல்பத்தை நீக்கு", "delete_api_key_prompt": "இந்த பநிஇ விசையை நீக்க விரும்புகிறீர்களா?", + "delete_dialog_alert": "இந்த உருப்படிகள் இம்மிச்சிலிருந்தும் உங்கள் சாதனத்திலிருந்தும் நிரந்தரமாக நீக்கப்படும்", + "delete_dialog_alert_local": "இந்த உருப்படிகள் உங்கள் சாதனத்திலிருந்து நிரந்தரமாக அகற்றப்படும், ஆனால் இன்னும் இம்மிச் சேவையகத்தில் கிடைக்கும்", + "delete_dialog_alert_local_non_backed_up": "சில உருப்படிகள் இம்மிச் வரை ஆதரிக்கப்படவில்லை, மேலும் அவை உங்கள் சாதனத்திலிருந்து நிரந்தரமாக அகற்றப்படும்", + "delete_dialog_alert_remote": "இந்த உருப்படிகள் இம்மிச் சேவையகத்திலிருந்து நிரந்தரமாக நீக்கப்படும்", + "delete_dialog_ok_force": "எப்படியும் நீக்கு", + "delete_dialog_title": "நிரந்தரமாக நீக்கு", "delete_duplicates_confirmation": "இந்த நகல்களை நிரந்தரமாக நீக்க விரும்புகிறீர்களா?", + "delete_face": "முகத்தை நீக்கு", "delete_key": "விசையை நீக்கு", "delete_library": "நூலகத்தை நீக்கு", "delete_link": "இணைப்பை நீக்கு", + "delete_local_action_prompt": "{count} உள்நாட்டில் நீக்கப்பட்டது", + "delete_local_dialog_ok_backed_up_only": "நீக்கு மட்டுமே காப்புப்பிரதி எடுக்கவும்", + "delete_local_dialog_ok_force": "எப்படியும் நீக்கு", "delete_others": "மற்றவர்களை நீக்கு", + "delete_permanently": "நிரந்தரமாக நீக்கு", + "delete_permanently_action_prompt": "{count} நிரந்தரமாக நீக்கப்பட்டது", "delete_shared_link": "பகிரப்பட்ட இணைப்பை நீக்கு", + "delete_shared_link_dialog_title": "பகிரப்பட்ட இணைப்பை நீக்கு", "delete_tag": "குறிச்சொல்லை நீக்கு", "delete_tag_confirmation_prompt": "{tagName} குறிச்சொல்லை நீக்க விரும்புகிறீர்களா?", "delete_user": "பயனரை நீக்கு", "deleted_shared_link": "பகிரப்பட்ட இணைப்பை நீக்கியது", "deletes_missing_assets": "வட்டில் இருந்து காணாமல் போன சொத்துக்களை நீக்குகிறது", "description": "விவரம்", + "description_input_hint_text": "விளக்கத்தைச் சேர்க்கவும் ...", + "description_input_submit_error": "விளக்கத்தை புதுப்பிப்பதில் பிழை, மேலும் விவரங்களுக்கு பதிவைச் சரிபார்க்கவும்", + "deselect_all": "அனைத்தையும் தேர்வு செய்யுங்கள்", "details": "விவரங்கள்", "direction": "திசை", "disabled": "முடக்கப்பட்டது", "disallow_edits": "திருத்தங்களை அனுமதிக்கவும்", "discord": "முரண்பாடு", "discover": "கண்டுபிடி", + "discovered_devices": "கண்டுபிடிக்கப்பட்ட சாதனங்கள்", "dismiss_all_errors": "அனைத்து பிழைகளையும் நிராகரிக்கவும்", "dismiss_error": "பிழையை நிராகரிக்கவும்", "display_options": "காட்சி விருப்பங்கள்", @@ -593,12 +831,26 @@ "documentation": "ஆவணப்படுத்துதல்", "done": "முடிந்தது", "download": "பதிவிறக்கம்", + "download_action_prompt": "பதிவிறக்கம் {count} சொத்துக்கள்", + "download_canceled": "பதிவிறக்கம் ரத்து செய்யப்பட்டது", + "download_complete": "முழுமையான பதிவிறக்கம்", + "download_enqueue": "Enqueuted பதிவிறக்க", + "download_error": "பிழையைப் பதிவிறக்கவும்", + "download_failed": "பதிவிறக்கம் தோல்வியடைந்தது", + "download_finished": "பதிவிறக்கம் முடிந்தது", "download_include_embedded_motion_videos": "உட்பொதிக்கப்பட்ட வீடியோக்கள்", "download_include_embedded_motion_videos_description": "மோசன் புகைப்படங்களில் உட்பொதிக்கப்பட்ட வீடியோக்களை தனி கோப்பாக சேர்க்கவும்", + "download_notfound": "பதிவிறக்கம் கிடைக்கவில்லை", + "download_paused": "இடைநிறுத்தப்பட்டது", "download_settings": "பதிவிறக்கம்", "download_settings_description": "சொத்து பதிவிறக்கம் தொடர்பான அமைப்புகளை நிர்வகிக்கவும்", + "download_started": "பதிவிறக்கம் தொடங்கியது", + "download_sucess": "வெற்றியைப் பதிவிறக்கவும்", + "download_sucess_android": "ஊடகங்கள் DCIM/IMMich க்கு பதிவிறக்கம் செய்யப்பட்டுள்ளன", + "download_waiting_to_retry": "மீண்டும் முயற்சிக்க காத்திருக்கிறது", "downloading": "பதிவிறக்குகிறது", "downloading_asset_filename": "சொத்து பதிவிறக்கம் {filename}", + "downloading_media": "ஊடகங்களைப் பதிவிறக்குகிறது", "drop_files_to_upload": "பதிவேற்ற எங்கும் கோப்புகளை விடுங்கள்", "duplicates": "நகல்கள்", "duplicates_description": "ஒவ்வொரு குழுவையும் எந்த நகல்களிலும் குறிப்பிடுவதன் மூலம் தீர்க்கவும்", @@ -606,8 +858,14 @@ "edit": "தொகு", "edit_album": "ஆல்பத்தைத் திருத்து", "edit_avatar": "அவதாரத்தைத் திருத்து", + "edit_birthday": "பிறந்தநாளைத் திருத்தவும்", "edit_date": "தேதியைத் திருத்து", "edit_date_and_time": "தேதி மற்றும் நேரத்தைத் திருத்தவும்", + "edit_date_and_time_action_prompt": "{count} தேதி மற்றும் நேரம் திருத்தப்பட்டது", + "edit_date_and_time_by_offset": "ஆஃப்செட் மூலம் தேதியை மாற்றவும்", + "edit_date_and_time_by_offset_interval": "புதிய தேதி வரம்பு: {from} - {to}", + "edit_description": "விளக்கத்தைத் திருத்து", + "edit_description_prompt": "புதிய விளக்கத்தைத் தேர்ந்தெடுக்கவும்:", "edit_exclusion_pattern": "விலக்கு முறையைத் திருத்தவும்", "edit_faces": "முகங்களைத் திருத்தவும்", "edit_import_path": "இறக்குமதி பாதையைத் திருத்து", @@ -615,6 +873,8 @@ "edit_key": "திறனைத் திருத்து", "edit_link": "இணைப்பைத் திருத்து", "edit_location": "இருப்பிடத்தைத் திருத்தவும்", + "edit_location_action_prompt": "{count} இருப்பிடம் திருத்தப்பட்டது", + "edit_location_dialog_title": "இடம்", "edit_name": "பெயரைத் திருத்து", "edit_people": "மக்களைத் திருத்தவும்", "edit_tag": "குறிச்சொல்லைத் திருத்து", @@ -627,13 +887,27 @@ "editor_crop_tool_h2_aspect_ratios": "அம்ச விகிதங்கள்", "editor_crop_tool_h2_rotation": "சுழற்சி", "email": "மின்னஞ்சல்", + "email_notifications": "மின்னஞ்சல் அறிவிப்புகள்", + "empty_folder": "இந்த கோப்புறை காலியாக உள்ளது", "empty_trash": "வெற்று குப்பை", "empty_trash_confirmation": "நீங்கள் குப்பைகளை வெறுமை செய்ய விரும்புகிறீர்களா? இது குப்பையில் உள்ள அனைத்து சொத்துக்களையும் நிரந்தரமாக இம்மிச்சிலிருந்து அகற்றும்.\n இந்த செயலை நீங்கள் செயல்தவிர்க்க முடியாது!", "enable": "இயக்கு", + "enable_backup": "காப்புப்பிரதியை இயக்கவும்", + "enable_biometric_auth_description": "பயோமெட்ரிக் அங்கீகாரத்தை இயக்க உங்கள் முள் குறியீட்டை உள்ளிடவும்", "enabled": "இயக்கப்பட்டது", "end_date": "இறுதி தேதி", + "enqueued": "Enqueuted", + "enter_wifi_name": "வைஃபை பெயரை உள்ளிடவும்", + "enter_your_pin_code": "உங்கள் முள் குறியீட்டை உள்ளிடவும்", + "enter_your_pin_code_subtitle": "பூட்டப்பட்ட கோப்புறையை அணுக உங்கள் முள் குறியீட்டை உள்ளிடவும்", "error": "பிழை", + "error_change_sort_album": "ஆல்பம் வரிசை வரிசையை மாற்றத் தவறிவிட்டது", + "error_delete_face": "சொத்தில் இருந்து முகத்தை நீக்குவதில் பிழை", + "error_getting_places": "இடங்களைப் பெறுவதில் பிழை", "error_loading_image": "படத்தை ஏற்றுவதில் பிழை", + "error_loading_partners": "கூட்டாளர்களை ஏற்றுவதில் பிழை: {error}", + "error_saving_image": "பிழை: {error}", + "error_tag_face_bounding_box": "முகத்தை குறிக்கவும் பிழை - எல்லை பெட்டி ஆயத்தொலைவுகளைப் பெற முடியாது", "error_title": "பிழை - ஏதோ தவறு நடந்தது", "errors": { "cannot_navigate_next_asset": "அடுத்த சொத்துக்கு செல்ல முடியாது", @@ -661,15 +935,19 @@ "failed_to_keep_this_delete_others": "இந்த சொத்தை வைத்து மற்ற சொத்துக்களை நீக்குவதில் தோல்வி", "failed_to_load_asset": "சொத்தை ஏற்றுவதில் தோல்வி", "failed_to_load_assets": "சொத்துக்களை ஏற்றுவதில் தோல்வி", + "failed_to_load_notifications": "அறிவிப்புகளை ஏற்றுவதில் தோல்வி", "failed_to_load_people": "மக்களை ஏற்றுவதில் தோல்வி", "failed_to_remove_product_key": "தயாரிப்பு விசையை அகற்றுவதில் தோல்வி", + "failed_to_reset_pin_code": "முள் குறியீட்டை மீட்டமைக்கத் தவறிவிட்டது", "failed_to_stack_assets": "சொத்துக்களை அடுக்கி வைப்பதில் தோல்வி", "failed_to_unstack_assets": "அன்-ச்டாக் சொத்துக்களில் தோல்வியுற்றது", + "failed_to_update_notification_status": "அறிவிப்பு நிலையைப் புதுப்பிக்கத் தவறிவிட்டது", "import_path_already_exists": "இந்த இறக்குமதி பாதை ஏற்கனவே உள்ளது.", "incorrect_email_or_password": "தவறான மின்னஞ்சல் அல்லது கடவுச்சொல்", "paths_validation_failed": "{பாதைகள், பன்மை, ஒன்று {# பாதை} மற்ற {# பாதைகள்}} தோல்வியுற்ற சரிபார்ப்பு", "profile_picture_transparent_pixels": "சுயவிவரப் படங்களுக்கு வெளிப்படையான படப்புள்ளிகள் இருக்க முடியாது. தயவுசெய்து பெரிதாக்கவும்/அல்லது படத்தை நகர்த்தவும்.", "quota_higher_than_disk_size": "வட்டு அளவை விட அதிகமாக ஒதுக்கீட்டை அமைத்துள்ளீர்கள்", + "something_went_wrong": "ஏதோ தவறு நடந்தது", "unable_to_add_album_users": "ஆல்பத்தில் பயனர்களைச் சேர்க்க முடியவில்லை", "unable_to_add_assets_to_shared_link": "பகிரப்பட்ட இணைப்புக்கு சொத்துக்களைச் சேர்க்க முடியவில்லை", "unable_to_add_comment": "கருத்து சேர்க்க முடியவில்லை", @@ -681,6 +959,7 @@ "unable_to_archive_unarchive": "{காப்பகப்படுத்த முடியவில்லை, தேர்ந்தெடுக்க முடியவில்லை, உண்மை {archive} பிற {unarchive}}", "unable_to_change_album_user_role": "ஆல்பத்தின் பயனரின் பாத்திரத்தை மாற்ற முடியவில்லை", "unable_to_change_date": "தேதியை மாற்ற முடியவில்லை", + "unable_to_change_description": "விளக்கத்தை மாற்ற முடியவில்லை", "unable_to_change_favorite": "சொத்துக்கு பிடித்ததை மாற்ற முடியவில்லை", "unable_to_change_location": "இருப்பிடத்தை மாற்ற முடியவில்லை", "unable_to_change_password": "கடவுச்சொல்லை மாற்ற முடியவில்லை", @@ -724,6 +1003,7 @@ "unable_to_remove_partner": "கூட்டாளரை அகற்ற முடியவில்லை", "unable_to_remove_reaction": "எதிர்வினையை அகற்ற முடியவில்லை", "unable_to_reset_password": "கடவுச்சொல்லை மீட்டமைக்க முடியவில்லை", + "unable_to_reset_pin_code": "முள் குறியீட்டை மீட்டமைக்க முடியவில்லை", "unable_to_resolve_duplicate": "நகல் தீர்க்க முடியவில்லை", "unable_to_restore_assets": "சொத்துக்களை மீட்டெடுக்க முடியவில்லை", "unable_to_restore_trash": "குப்பைகளை மீட்டெடுக்க முடியவில்லை", @@ -751,8 +1031,19 @@ "unable_to_update_user": "பயனரைப் புதுப்பிக்க முடியவில்லை", "unable_to_upload_file": "கோப்பைப் பதிவேற்ற முடியவில்லை" }, + "exif": "Exif", + "exif_bottom_sheet_description": "விளக்கத்தைச் சேர்க்கவும் ...", + "exif_bottom_sheet_description_error": "விளக்கத்தை புதுப்பிப்பதில் பிழை", + "exif_bottom_sheet_details": "விவரங்கள்", + "exif_bottom_sheet_location": "இடம்", + "exif_bottom_sheet_people": "மக்கள்", + "exif_bottom_sheet_person_add_person": "பெயரைச் சேர்க்கவும்", "exit_slideshow": "ச்லைடுசோவிலிருந்து வெளியேறவும்", "expand_all": "அனைத்தையும் விரிவாக்குங்கள்", + "experimental_settings_new_asset_list_subtitle": "வேலை முன்னேற்றத்தில் உள்ளது", + "experimental_settings_new_asset_list_title": "சோதனை புகைப்பட கட்டத்தை இயக்கவும்", + "experimental_settings_subtitle": "உங்கள் சொந்த ஆபத்தில் பயன்படுத்தவும்!", + "experimental_settings_title": "சோதனை", "expire_after": "பின்னர் காலாவதியாகுங்கள்", "expired": "காலாவதியான", "expires_date": "{date} காலாவதியாகிறது", @@ -760,37 +1051,74 @@ "explorer": "எக்ச்ப்ளோரர்", "export": "ஏற்றுமதி", "export_as_json": "சாதொபொகு ஆக ஏற்றுமதி", + "export_database": "ஏற்றுமதி தரவுத்தளம்", + "export_database_description": "SQLITE தரவுத்தளத்தை ஏற்றுமதி செய்யுங்கள்", "extension": "நீட்டிப்பு", "external": "வெளிப்புறம்", "external_libraries": "வெளிப்புற நூலகங்கள்", + "external_network": "வெளிப்புற பிணையம்", + "external_network_sheet_info": "விருப்பமான வைஃபை நெட்வொர்க்கில் இல்லாதபோது, பயன்பாடு சேவையகத்துடன் கீழே உள்ள முகவரி களின் முதல் வழியாக இணைக்கப்படும், இது மேலே இருந்து கீழே தொடங்குகிறது", "face_unassigned": "ஒதுக்கப்படாதது", + "failed": "தோல்வியுற்றது", + "failed_to_authenticate": "அங்கீகரிக்கத் தவறிவிட்டது", "failed_to_load_assets": "சொத்துக்களை ஏற்றுவதில் தோல்வி", + "failed_to_load_folder": "கோப்புறையை ஏற்றுவதில் தோல்வி", "favorite": "பிடித்த", + "favorite_action_prompt": "{எண்ணிக்கை the பிடித்தவைகளில் சேர்க்கப்பட்டது", "favorite_or_unfavorite_photo": "பிடித்த அல்லது சாதகமற்ற புகைப்படம்", "favorites": "பிடித்தவை", + "favorites_page_no_favorites": "பிடித்த சொத்துக்கள் எதுவும் கிடைக்கவில்லை", "feature_photo_updated": "அம்ச புகைப்படம் புதுப்பிக்கப்பட்டது", "features": "நற்பொருத்தங்கள்", + "features_in_development": "வளர்ச்சியில் நற்பொருத்தங்கள்", "features_setting_description": "பயன்பாட்டு அம்சங்களை நிர்வகிக்கவும்", "file_name": "கோப்பு பெயர்", "file_name_or_extension": "கோப்பு பெயர் அல்லது நீட்டிப்பு", "filename": "கோப்புப்பெயர்", "filetype": "பைல்டைப்", + "filter": "வடிப்பி", "filter_people": "மக்களை வடிகட்டவும்", + "filter_places": "இடங்களை வடிகட்டவும்", "find_them_fast": "தேடலுடன் பெயரால் வேகமாக அவற்றைக் கண்டறியவும்", + "first": "முதல்", "fix_incorrect_match": "தவறான போட்டியை சரிசெய்யவும்", + "folder": "கோப்புறை", + "folder_not_found": "கோப்புறை கிடைக்கவில்லை", "folders": "கோப்புறைகள்", "folders_feature_description": "கோப்பு முறைமையில் உள்ள புகைப்படங்கள் மற்றும் வீடியோக்களுக்கான கோப்புறை காட்சியை உலாவுதல்", + "forgot_pin_code_question": "உங்கள் முள் மறந்துவிட்டீர்களா?", "forward": "முன்னோக்கி", + "gcast_enabled": "கூகிள் நடிகர்கள்", + "gcast_enabled_description": "இந்த நற்பொருத்தம் வேலை செய்வதற்காக Google இலிருந்து வெளிப்புற வளங்களை ஏற்றுகிறது.", "general": "பொது", + "geolocation_instruction_location": "அதன் இருப்பிடத்தைப் பயன்படுத்த சி.பி.எச் ஆயத்தொலைவுகளுடன் ஒரு சொத்தில் சொடுக்கு செய்க அல்லது வரைபடத்திலிருந்து நேரடியாக ஒரு இடத்தைத் தேர்ந்தெடுக்கவும்", "get_help": "உதவி பெறு", + "get_wifiname_error": "வைஃபை பெயரைப் பெற முடியவில்லை. நீங்கள் தேவையான அனுமதிகளை வழங்கியுள்ளீர்கள் என்பதை உறுதிப்படுத்திக் கொள்ளுங்கள் மற்றும் வைஃபை நெட்வொர்க்குடன் இணைக்கப்பட்டுள்ளீர்கள்", "getting_started": "தொடங்குதல்", "go_back": "திரும்பிச் செல்லுங்கள்", + "go_to_folder": "கோப்புறைக்குச் செல்லுங்கள்", "go_to_search": "தேடச் செல்லவும்", + "gps": "உலக இடம் காட்டும் அமைப்பு (இடம் காட்டி)", + "gps_missing": "சி.பி.எச் இல்லை", + "grant_permission": "இசைவு வழங்கவும்", "group_albums_by": "குழு ஆல்பங்கள் வழங்கியவர் ...", + "group_country": "நாடு மூலம் குழு", "group_no": "குழு இல்லை", "group_owner": "உரிமையாளரால் குழு", + "group_places_by": "குழு இடங்கள் ...", "group_year": "ஆண்டுக்கு குழு", + "haptic_feedback_switch": "ஆப்டிக் பின்னூட்டத்தை இயக்கவும்", + "haptic_feedback_title": "ஆப்டிக் கருத்து", "has_quota": "ஒதுக்கீடு உள்ளது", + "hash_asset": "ஆச் சொத்து", + "hashed_assets": "சொத்துக்கள்", + "hashing": "ஏசிங்", + "header_settings_add_header_tip": "தலைப்புச் சேர்க்கவும்", + "header_settings_field_validator_msg": "மதிப்பு காலியாக இருக்க முடியாது", + "header_settings_header_name_input": "தலைப்பு பெயர்", + "header_settings_header_value_input": "தலைப்பு மதிப்பு", + "headers_settings_tile_subtitle": "ஒவ்வொரு பிணைய கோரிக்கையுடனும் பயன்பாடு அனுப்ப வேண்டிய பதிலாள் தலைப்புகளை வரையறுக்கவும்", + "headers_settings_tile_title": "தனிப்பயன் பதிலாள் தலைப்புகள்", "hi_user": "ஆய் {name} ({email})", "hide_all_people": "எல்லா மக்களையும் மறைக்கவும்", "hide_gallery": "கேலரியை மறைக்கவும்", @@ -798,8 +1126,29 @@ "hide_password": "கடவுச்சொல்லை மறைக்கவும்", "hide_person": "நபரை மறைக்க", "hide_unnamed_people": "பெயரிடப்படாதவர்களை மறைக்கவும்", + "home_page_add_to_album_conflicts": "சேர்க்கப்பட்டது {ஆல்பம் {added} சொத்துக்கள் {ஆல்பம். {album} சொத்துக்கள் ஏற்கனவே ஆல்பத்தில் உள்ளன.", + "home_page_add_to_album_err_local": "ஆல்பங்களில் உள்ளக சொத்துக்களை இன்னும் சேர்க்க முடியாது, தவிர்க்கவும்", + "home_page_add_to_album_success": "சேர்க்கப்பட்டது {ஆல்பம் {added} சொத்துக்கள் {ஆல்பம்.", + "home_page_album_err_partner": "ஒரு ஆல்பத்திற்கு இன்னும் கூட்டாளர் சொத்துக்களைச் சேர்க்க முடியவில்லை, தவிர்க்கவும்", + "home_page_archive_err_local": "உள்ளக சொத்துக்களை இன்னும் காப்பகப்படுத்த முடியாது, தவிர்க்கவும்", + "home_page_archive_err_partner": "கூட்டாளர் சொத்துக்களை காப்பகப்படுத்த முடியாது, தவிர்க்கவும்", + "home_page_building_timeline": "காலவரிசையை உருவாக்குதல்", + "home_page_delete_err_partner": "கூட்டாளர் சொத்துக்களை நீக்க முடியாது, தவிர்க்கவும்", + "home_page_delete_remote_err_local": "தொலைநிலை தேர்வை நீக்கு, தவிர்ப்பதில் உள்ளக சொத்துக்கள்", + "home_page_favorite_err_local": "உள்ளக சொத்துக்களை இன்னும் பிடித்திருக்க முடியாது, தவிர்க்கவும்", + "home_page_favorite_err_partner": "இன்னும் பிடித்த கூட்டாளர் சொத்துக்களைத் தவிர்த்து, தவிர்க்க முடியாது", + "home_page_first_time_notice": "பயன்பாட்டைப் பயன்படுத்துவது இது உங்கள் முதல் முறையாக இருந்தால், தயவுசெய்து காப்புப்பிரதி ஆல்பத்தைத் தேர்வுசெய்க, இதன் மூலம் காலவரிசை அதில் உள்ள புகைப்படங்களையும் வீடியோக்களையும் விரிவுபடுத்த முடியும்", + "home_page_locked_error_local": "உள்ளக சொத்துக்களை பூட்டிய கோப்புறைக்கு நகர்த்த முடியாது, தவிர்க்கிறது", + "home_page_locked_error_partner": "பங்குதாரர் சொத்துக்களை பூட்டிய கோப்புறையில் நகர்த்த முடியாது, தவிர்க்கவும்", + "home_page_share_err_local": "இணைப்பு, ச்கிப்பிங் வழியாக உள்ளக சொத்துக்களை பகிர முடியாது", + "home_page_upload_err_limit": "ஒரு நேரத்தில் அதிகபட்சம் 30 சொத்துக்களை மட்டுமே பதிவேற்ற முடியும், தவிர்க்கவும்", "host": "விருந்தோம்பி", "hour": "மணி", + "hours": "மணி", + "id": "ஐடி", + "idle": "நிலையிக்கம்", + "ignore_icloud_photos": "ICloud புகைப்படங்களை புறக்கணிக்கவும்", + "ignore_icloud_photos_description": "ICloud இல் சேமிக்கப்படும் புகைப்படங்கள் இம்மிச் சேவையகத்தில் பதிவேற்றப்படாது", "image": "படம்", "image_alt_text_date": "{isvideo, தேர்ந்தெடு, உண்மை {Video} பிற {Image}} {date} இல் எடுக்கப்பட்டது", "image_alt_text_date_1_person": "{isvideo, தேர்ந்தெடு, உண்மை {Video} பிற {Image}} {{person1} இல் {date}", @@ -810,7 +1159,11 @@ "image_alt_text_date_place_1_person": "{isvideo, தேர்ந்தெடு, உண்மை {Video} பிற {Image}} {city}, {country} {person1} உடன் {date}", "image_alt_text_date_place_2_people": "{isvideo, தேர்ந்தெடு, உண்மை {Video} பிற {Image}} {city}, {country} உடன் {person1} மற்றும் {person2} {date}", "image_alt_text_date_place_3_people": "{isvideo, தேர்ந்தெடு, உண்மை {Video} பிற {Image}} {city}, {country} {person1}, {person2}, மற்றும் {person3} இல் எடுக்கப்பட்டது {date}", - "image_alt_text_date_place_4_or_more_people": "{isvideo, தேர்ந்தெடு, உண்மை {Video} பிற {Image}} {city}, {country} {person1}, {person2}, மற்றும் {கூடுதல் கவுன்ட், எண்} மற்றவர்கள் {date}", + "image_alt_text_date_place_4_or_more_people": "{isvideo, தேர்ந்தெடு, உண்மை {Video} பிற {Image}} {city}, {country} {person1}, {person2}, மற்றும் {கூடுதல் அக்கவுண்ட், எண்} மற்றவர்கள் {date}", + "image_saved_successfully": "படம் சேமிக்கப்பட்டது", + "image_viewer_page_state_provider_download_started": "பதிவிறக்கம் தொடங்கியது", + "image_viewer_page_state_provider_download_success": "வெற்றியைப் பதிவிறக்கவும்", + "image_viewer_page_state_provider_share_error": "பிழை பகிர்வு", "immich_logo": "இம்மிச் லோகோ", "immich_web_interface": "இம்ரிச் வலை இடைமுகம்", "import_from_json": "சாதொபொகு இலிருந்து இறக்குமதி", @@ -821,6 +1174,7 @@ "include_shared_albums": "பகிரப்பட்ட ஆல்பங்களைச் சேர்க்கவும்", "include_shared_partner_assets": "பகிரப்பட்ட கூட்டாளர் சொத்துக்களைச் சேர்க்கவும்", "individual_share": "தனிப்பட்ட பங்கு", + "individual_shares": "தனிப்பட்ட பங்குகள்", "info": "தகவல்", "interval": { "day_at_onepm": "ஒவ்வொரு நாளும் மதியம் 1 மணிக்கு", @@ -828,8 +1182,16 @@ "night_at_midnight": "ஒவ்வொரு இரவும் நள்ளிரவில்", "night_at_twoam": "ஒவ்வொரு இரவும் அதிகாலை 2 மணிக்கு" }, + "invalid_date": "தவறான தேதி", + "invalid_date_format": "தவறான தேதி வடிவம்", "invite_people": "மக்களை அழைக்கவும்", "invite_to_album": "ஆல்பத்திற்கு அழைக்கவும்", + "ios_debug_info_fetch_ran_at": "ஓடியது {dateTime}", + "ios_debug_info_last_sync_at": "கடைசி ஒத்திசைவு {dateTime}", + "ios_debug_info_no_processes_queued": "பின்னணி செயல்முறைகள் வரிசையில் இல்லை", + "ios_debug_info_no_sync_yet": "பின்னணி ஒத்திசைவு வேலை இன்னும் இயங்கவில்லை", + "ios_debug_info_processes_queued": "{எண்ணிக்கை, பன்மை, ஒன்று {{count} பின்னணி செயல்முறை வரிசையில் வரிசைப்படுத்தப்பட்டது} பிற {{count} பின்னணி செயல்முறைகள் வரிசைப்படுத்தப்பட்டன", + "ios_debug_info_processing_ran_at": "செயலாக்கம் {dateTime}", "items_count": "{எண்ணிக்கை, பன்மை, ஒன்று {# உருப்படி} பிற {# உருப்படிகள்}}", "jobs": "வேலைகள்", "keep": "வைத்திருங்கள்", @@ -838,16 +1200,31 @@ "kept_this_deleted_others": "இந்த சொத்தை வைத்து நீக்கப்பட்டது {எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} பிற {# சொத்துக்கள்}}", "keyboard_shortcuts": "விசைப்பலகை குறுக்குவழிகள்", "language": "மொழி", + "language_no_results_subtitle": "உங்கள் தேடல் காலத்தை சரிசெய்ய முயற்சிக்கவும்", + "language_no_results_title": "எந்த மொழிகளும் கிடைக்கவில்லை", + "language_search_hint": "மொழிகளைத் தேடுங்கள் ...", "language_setting_description": "உங்களுக்கு விருப்பமான மொழியைத் தேர்ந்தெடுக்கவும்", + "large_files": "பெரிய கோப்புகள்", + "last": "கடைசி", "last_seen": "கடைசியாக பார்த்தேன்", "latest_version": "அண்மைக் கால பதிப்பு", "latitude": "அகலாங்கு", "leave": "விடுப்பு", + "leave_album": "விடுப்பு ஆல்பம்", + "lens_model": "லென்ச் மாதிரி", "let_others_respond": "மற்றவர்கள் பதிலளிக்கட்டும்", "level": "நிலை", "library": "நூலகம்", "library_options": "நூலக விருப்பங்கள்", + "library_page_device_albums": "சாதனத்தில் ஆல்பங்கள்", + "library_page_new_album": "புதிய ஆல்பம்", + "library_page_sort_asset_count": "சொத்துக்களின் எண்ணிக்கை", + "library_page_sort_created": "உருவாக்கப்பட்ட தேதி", + "library_page_sort_last_modified": "கடைசியாக மாற்றப்பட்டது", + "library_page_sort_title": "ஆல்பம் தலைப்பு", + "licenses": "உரிமங்கள்", "light": "ஒளி", + "like": "போன்ற", "like_deleted": "நீக்கப்பட்டதைப் போல", "link_motion_video": "இணைப்பு இயக்க வீடியோ", "link_to_oauth": "OAUTH உடன் இணைப்பு", @@ -855,20 +1232,61 @@ "list": "பட்டியல்", "loading": "ஏற்றுகிறது", "loading_search_results_failed": "தேடல் முடிவுகளை ஏற்றுவது தோல்வியடைந்தது", + "local": "உள்ளக", + "local_asset_cast_failed": "சேவையகத்தில் பதிவேற்றப்படாத ஒரு சொத்தை அனுப்ப முடியவில்லை", + "local_assets": "உள்ளக சொத்துக்கள்", + "local_media_summary": "உள்ளக ஊடக சுருக்கம்", + "local_network": "உள்ளக பிணையம்", + "local_network_sheet_info": "குறிப்பிட்ட வைஃபை நெட்வொர்க்கைப் பயன்படுத்தும் போது பயன்பாடு இந்த முகவரி மூலம் சேவையகத்துடன் இணைக்கப்படும்", + "location_permission": "இருப்பிட இசைவு", + "location_permission_content": "ஆட்டோ-ச்விட்சிங் அம்சத்தைப் பயன்படுத்த, இம்மிக்கு துல்லியமான இருப்பிட இசைவு தேவை, எனவே இது தற்போதைய வைஃபை நெட்வொர்க்கின் பெயரைப் படிக்க முடியும்", + "location_picker_choose_on_map": "வரைபடத்தில் தேர்வு செய்யவும்", + "location_picker_latitude_error": "செல்லுபடியாகும் அட்சரேகை உள்ளிடவும்", + "location_picker_latitude_hint": "உங்கள் அட்சரேகையை இங்கே உள்ளிடவும்", + "location_picker_longitude_error": "செல்லுபடியாகும் தீர்க்கரேகையை உள்ளிடவும்", + "location_picker_longitude_hint": "உங்கள் தீர்க்கரேகையை இங்கே உள்ளிடவும்", + "lock": "பூட்டு", + "locked_folder": "பூட்டப்பட்ட கோப்புறை", + "log_detail_title": "பதிவு விவரம்", "log_out": "விடுபதிகை", "log_out_all_devices": "எல்லா சாதனங்களையும் விட்டு வெளியேறவும்", + "logged_in_as": "{user}", "logged_out_all_devices": "எல்லா சாதனங்களையும் வெளியேற்றினேன்", "logged_out_device": "உள்நுழைந்த சாதனம்", "login": "புகுபதிவு", + "login_disabled": "உள்நுழைவு முடக்கப்பட்டுள்ளது", + "login_form_api_exception": "பநிஇ விதிவிலக்கு. சேவையக முகவரி ஐ சரிபார்த்து மீண்டும் முயற்சிக்கவும்.", + "login_form_back_button_text": "பின்", + "login_form_email_hint": "youremail@email.com", + "login_form_endpoint_hint": "http: // your-server-ip: துறைமுகம்", + "login_form_endpoint_url": "சேவையக எண்ட்பாயிண்ட் முகவரி", + "login_form_err_http": "Http: // அல்லது https: // ஐக் குறிப்பிடவும்", + "login_form_err_invalid_email": "தவறான மின்னஞ்சல்", + "login_form_err_invalid_url": "தவறான முகவரி", + "login_form_err_leading_whitespace": "முன்னணி விட்ச்பேச்", + "login_form_err_trailing_whitespace": "பின்திங் வைட்ச்பேச்", + "login_form_failed_get_oauth_server_config": "OAuth ஐப் பயன்படுத்தி பதிவுசெய்தல், சேவையக முகவரி ஐ சரிபார்க்கவும்", + "login_form_failed_get_oauth_server_disable": "இந்த சேவையகத்தில் OAuth நற்பொருத்தம் கிடைக்கவில்லை", + "login_form_failed_login": "உங்களை உள்நுழைவதில் பிழை, சேவையக URL, மின்னஞ்சல் மற்றும் கடவுச்சொல்லை சரிபார்க்கவும்", + "login_form_handshake_exception": "சேவையகத்துடன் ஏண்ட்சேக் விதிவிலக்கு இருந்தது. நீங்கள் தன்வய கையொப்பமிடப்பட்ட சான்றிதழைப் பயன்படுத்துகிறீர்கள் என்றால் அமைப்புகளில் தன்வய கையொப்பமிடப்பட்ட சான்றிதழ் ஆதரவை இயக்கவும்.", + "login_form_password_hint": "கடவுச்சொல்", + "login_form_save_login": "உள்நுழைந்திருங்கள்", + "login_form_server_empty": "சேவையக முகவரி ஐ உள்ளிடவும்.", + "login_form_server_error": "சேவையகத்துடன் இணைக்க முடியவில்லை.", "login_has_been_disabled": "உள்நுழைவு முடக்கப்பட்டுள்ளது.", + "login_password_changed_error": "உங்கள் கடவுச்சொல்லைப் புதுப்பிப்பதில் பிழை ஏற்பட்டது", + "login_password_changed_success": "கடவுச்சொல் வெற்றிகரமாக புதுப்பிக்கப்பட்டது", "logout_all_device_confirmation": "எல்லா சாதனங்களையும் விட்டு வெளியேற விரும்புகிறீர்களா?", "logout_this_device_confirmation": "இந்த சாதனத்தை விட்டு வெளியேற விரும்புகிறீர்களா?", + "logs": "பதிவுகள்", "longitude": "நெட்டாங்கு", "look": "பார்", "loop_videos": "லூப் வீடியோக்கள்", "loop_videos_description": "விரிவான பார்வையாளரில் ஒரு வீடியோவை தானாக வளையப்படுத்தவும்.", - "main_branch_warning": "நீங்கள் மேம்பாட்டு பதிப்பைப் பயன்படுத்துகிறீர்கள்; வெளியீட்டு பதிப்பைப் பயன்படுத்த நாங்கள் கடுமையாக பரிந்துரைக்கிறோம்!", + "main_branch_warning": "நீங்கள் ஒரு மேம்பாட்டு பதிப்பைப் பயன்படுத்துகிறீர்கள்; வெளியீட்டு பதிப்பைப் பயன்படுத்த நாங்கள் கடுமையாக பரிந்துரைக்கிறோம்!", + "main_menu": "பட்டியல் விளையாடுங்கள்", "make": "உருவாக்கு", + "manage_geolocation": "இருப்பிடத்தை நிர்வகிக்கவும்", "manage_shared_links": "பகிரப்பட்ட இணைப்புகளை நிர்வகிக்கவும்", "manage_sharing_with_partners": "கூட்டாளர்களுடன் பகிர்வை நிர்வகிக்கவும்", "manage_the_app_settings": "பயன்பாட்டு அமைப்புகளை நிர்வகிக்கவும்", @@ -877,13 +1295,40 @@ "manage_your_devices": "உங்கள் உள்நுழைந்த சாதனங்களை நிர்வகிக்கவும்", "manage_your_oauth_connection": "உங்கள் OAuth இணைப்பை நிர்வகிக்கவும்", "map": "வரைபடம்", + "map_assets_in_bounds": "{எண்ணிக்கை, பன்மை, = 0 {No photos in this area} ஒன்று {# புகைப்படம்} மற்ற {# புகைப்படங்கள்}}", + "map_cannot_get_user_location": "பயனரின் இருப்பிடத்தைப் பெற முடியாது", + "map_location_dialog_yes": "ஆம்", + "map_location_picker_page_use_location": "இந்த இருப்பிடத்தைப் பயன்படுத்தவும்", + "map_location_service_disabled_content": "உங்கள் தற்போதைய இருப்பிடத்திலிருந்து சொத்துக்களைக் காட்ட இருப்பிட பணி இயக்கப்பட வேண்டும். இப்போது அதை இயக்க விரும்புகிறீர்களா?", + "map_location_service_disabled_title": "இருப்பிட பணி முடக்கப்பட்டது", "map_marker_for_images": "{city}, {country}", "map_marker_with_image": "படத்துடன் வரைபட மார்க்கர்", + "map_no_location_permission_content": "உங்கள் தற்போதைய இருப்பிடத்திலிருந்து சொத்துக்களைக் காட்ட இருப்பிட இசைவு தேவை. இப்போது அதை அனுமதிக்க விரும்புகிறீர்களா?", + "map_no_location_permission_title": "இருப்பிட இசைவு மறுக்கப்பட்டது", "map_settings": "வரைபட அமைப்புகள்", + "map_settings_dark_mode": "இருண்ட முறை", + "map_settings_date_range_option_day": "கடந்த 24 மணி நேரம்", + "map_settings_date_range_option_days": "கடந்த {days} நாட்கள்", + "map_settings_date_range_option_year": "கடந்த ஆண்டு", + "map_settings_date_range_option_years": "கடந்த {years} ஆண்டுகள்", + "map_settings_dialog_title": "வரைபட அமைப்புகள்", + "map_settings_include_show_archived": "காப்பகப்படுத்தப்பட்டவர்", + "map_settings_include_show_partners": "கூட்டாளர்களைச் சேர்க்கவும்", + "map_settings_only_show_favorites": "பிடித்ததை மட்டும் காட்டு", + "map_settings_theme_settings": "வரைபட கருப்பொருள்", + "map_zoom_to_see_photos": "புகைப்படங்களைக் காண பெரிதாக்கவும்", + "mark_all_as_read": "அனைத்தையும் படித்தபடி குறிக்கவும்", + "mark_as_read": "படித்தபடி குறி", + "marked_all_as_read": "அனைத்தையும் வாசிப்பதாக குறிக்கப்பட்டுள்ளது", "matches": "போட்டிகள்", + "matching_assets": "பொருந்தும் சொத்துக்கள்", "media_type": "ஊடக வகை", "memories": "நினைவுகள்", + "memories_all_caught_up": "அனைவரும் பிடிபட்டனர்", + "memories_check_back_tomorrow": "மேலும் நினைவுகளுக்கு நாளை மீண்டும் பார்க்கவும்", "memories_setting_description": "உங்கள் நினைவுகளில் நீங்கள் பார்ப்பதை நிர்வகிக்கவும்", + "memories_start_over": "தொடக்க", + "memories_swipe_to_close": "மூடுவதற்கு ச்வைப் செய்யவும்", "memory": "நினைவகம்", "memory_lane_title": "நினைவக லேன் {title}", "menu": "பட்டியல்", @@ -895,19 +1340,40 @@ "merged_people_count": "ஒன்றிணைக்கப்பட்ட {எண்ணிக்கை, பன்மை, ஒன்று {# நபர்} மற்ற {# மக்கள்}}", "minimize": "குறைக்கவும்", "minute": "நிமிடங்கள்", + "minutes": "நிமிடங்கள்", "missing": "இல்லை", "model": "மாதிரியுரு", "month": "மாதம்", + "monthly_title_text_date_format": "Mmmm ஒய்", "more": "மேலும்", + "move": "நகர்த்தவும்", + "move_off_locked_folder": "பூட்டப்பட்ட கோப்புறையிலிருந்து வெளியேறவும்", + "move_to_lock_folder_action_prompt": "{எண்ணிக்கை the பூட்டப்பட்ட கோப்புறையில் சேர்க்கப்பட்டுள்ளது", + "move_to_locked_folder": "பூட்டப்பட்ட கோப்புறையில் செல்லுங்கள்", + "move_to_locked_folder_confirmation": "இந்த புகைப்படங்கள் மற்றும் வீடியோ அனைத்து ஆல்பங்களிலிருந்தும் அகற்றப்படும், மேலும் பூட்டப்பட்ட கோப்புறையிலிருந்து மட்டுமே பார்க்க முடியும்", + "moved_to_archive": "நகர்த்தப்பட்டது", + "moved_to_library": "நகர்த்தப்பட்டது", "moved_to_trash": "குப்பைக்கு நகர்த்தப்பட்டது", + "multiselect_grid_edit_date_time_err_read_only": "சொத்து (களை) மட்டுமே படித்த தேதியைத் திருத்த முடியாது, தவிர்க்கவும்", + "multiselect_grid_edit_gps_err_read_only": "சொத்து (களை) மட்டுமே படிக்க, ச்கிப்பிங் ஆகியவற்றைத் திருத்த முடியாது", + "mute_memories": "முடக்கு நினைவுகள்", "my_albums": "எனது ஆல்பங்கள்", "name": "பெயர்", "name_or_nickname": "பெயர் அல்லது புனைப்பெயர்", + "network_requirement_photos_upload": "காப்புப்பிரதி புகைப்படங்களுக்கு செல்லுலார் தரவைப் பயன்படுத்தவும்", + "network_requirement_videos_upload": "காப்புப்பிரதி வீடியோக்களுக்கு செல்லுலார் தரவைப் பயன்படுத்தவும்", + "network_requirements": "பிணைய தேவைகள்", + "network_requirements_updated": "பிணையம் தேவைகள் மாற்றப்பட்டன, காப்புப்பிரதி வரிசையை மீட்டமைக்கிறது", + "networking_settings": "நெட்வொர்க்கிங்", + "networking_subtitle": "சேவையக இறுதிப்புள்ளி அமைப்புகளை நிர்வகிக்கவும்", "never": "ஒருபோதும்", "new_album": "புதிய ஆல்பம்", "new_api_key": "புதிய பநிஇ விசை", "new_password": "புதிய கடவுச்சொல்", "new_person": "புதிய நபர்", + "new_pin_code": "புதிய முள் குறியீடு", + "new_pin_code_subtitle": "பூட்டப்பட்ட கோப்புறையை அணுக இது உங்கள் முதல் முறையாகும். இந்த பக்கத்தை பாதுகாப்பாக அணுக ஒரு முள் குறியீட்டை உருவாக்கவும்", + "new_timeline": "புதிய காலவரிசை", "new_user_created": "புதிய பயனர் உருவாக்கப்பட்டது", "new_version_available": "புதிய பதிப்பு கிடைக்கிறது", "newest_first": "புதிய முதல்", @@ -919,42 +1385,68 @@ "no_albums_yet": "உங்களிடம் இதுவரை எந்த ஆல்பங்களும் இல்லை என்று தெரிகிறது.", "no_archived_assets_message": "உங்கள் புகைப்படக் காட்சியில் இருந்து அவற்றை மறைக்க புகைப்படங்கள் மற்றும் வீடியோக்களை காப்பகப்படுத்தவும்", "no_assets_message": "உங்கள் முதல் புகைப்படத்தை பதிவேற்ற சொடுக்கு செய்க", + "no_assets_to_show": "காட்ட சொத்துக்கள் இல்லை", + "no_cast_devices_found": "நடிகர்கள் சாதனங்கள் எதுவும் கிடைக்கவில்லை", + "no_checksum_local": "செக்சம் எதுவும் கிடைக்கவில்லை - உள்ளக சொத்துக்களைப் பெற முடியாது", + "no_checksum_remote": "செக்சம் எதுவும் கிடைக்கவில்லை - தொலை சொத்து பெற முடியாது", "no_duplicates_found": "நகல்கள் எதுவும் காணப்படவில்லை.", "no_exif_info_available": "EXIF செய்தி எதுவும் கிடைக்கவில்லை", "no_explore_results_message": "உங்கள் தொகுப்பை ஆராய கூடுதல் புகைப்படங்களை பதிவேற்றவும்.", "no_favorites_message": "உங்கள் சிறந்த படங்கள் மற்றும் வீடியோக்களை விரைவாகக் கண்டுபிடிக்க பிடித்தவைகளைச் சேர்க்கவும்", "no_libraries_message": "உங்கள் புகைப்படங்கள் மற்றும் வீடியோக்களைக் காண வெளிப்புற நூலகத்தை உருவாக்கவும்", + "no_local_assets_found": "இந்த செக்சம் மூலம் உள்ளக சொத்துக்கள் எதுவும் காணப்படவில்லை", + "no_locked_photos_message": "பூட்டப்பட்ட கோப்புறையில் உள்ள புகைப்படங்கள் மற்றும் வீடியோக்கள் மறைக்கப்பட்டுள்ளன, மேலும் நீங்கள் உங்கள் நூலகத்தை உலாவும்போது அல்லது தேடும்போது காண்பிக்கப்படாது.", "no_name": "பெயர் இல்லை", + "no_notifications": "அறிவிப்புகள் இல்லை", + "no_people_found": "பொருந்தக்கூடிய நபர்கள் எதுவும் கிடைக்கவில்லை", "no_places": "இடங்கள் இல்லை", + "no_remote_assets_found": "இந்த செக்சம் மூலம் தொலைநிலை சொத்துக்கள் எதுவும் காணப்படவில்லை", "no_results": "முடிவுகள் இல்லை", "no_results_description": "ஒரு ஒத்த அல்லது பொதுவான முக்கிய சொல்லை முயற்சிக்கவும்", "no_shared_albums_message": "உங்கள் நெட்வொர்க்கில் உள்ளவர்களுடன் புகைப்படங்களையும் வீடியோக்களையும் பகிர்ந்து கொள்ள ஒரு ஆல்பத்தை உருவாக்கவும்", + "no_uploads_in_progress": "பதிவேற்றங்கள் முன்னேற்றத்தில் இல்லை", + "not_available": "இதற்கில்லை", "not_in_any_album": "எந்த ஆல்பத்திலும் இல்லை", + "not_selected": "தேர்ந்தெடுக்கப்படவில்லை", "note_apply_storage_label_to_previously_uploaded assets": "குறிப்பு: முன்னர் பதிவேற்றப்பட்ட சொத்துக்களுக்கு சேமிப்பக லேபிளை பயன்படுத்த, இயக்கவும்", "notes": "குறிப்புகள்", + "nothing_here_yet": "இன்னும் இங்கே எதுவும் இல்லை", + "notification_permission_dialog_content": "அறிவிப்புகளை இயக்க, அமைப்புகளுக்குச் சென்று இசைவு என்பதைத் தேர்ந்தெடுக்கவும்.", + "notification_permission_list_tile_content": "அறிவிப்புகளை இயக்க இசைவு வழங்கவும்.", + "notification_permission_list_tile_enable_button": "அறிவிப்புகளை இயக்கவும்", + "notification_permission_list_tile_title": "அறிவிப்பு இசைவு", "notification_toggle_setting_description": "மின்னஞ்சல் அறிவிப்புகளை இயக்கவும்", "notifications": "அறிவிப்புகள்", "notifications_setting_description": "அறிவிப்புகளை நிர்வகிக்கவும்", "oauth": "Oauth", "official_immich_resources": "உத்தியோகபூர்வ இம்மா வளங்கள்", "offline": "இணையமில்லாமல்", + "offset": "ஈடுசெய்யும்", "ok": "சரி", "oldest_first": "முதலில் பழமையானது", + "on_this_device": "இந்த சாதனத்தில்", "onboarding": "ஆன் போர்டிங்", - "onboarding_privacy_description": "பின்வரும் (விரும்பினால்) நற்பொருத்தங்கள் வெளிப்புற சேவைகளை நம்பியுள்ளன, மேலும் நிர்வாக அமைப்புகளில் எந்த நேரத்திலும் முடக்கப்படலாம்.", + "onboarding_locale_description": "உங்களுக்கு விருப்பமான மொழியைத் தேர்ந்தெடுக்கவும். இதை உங்கள் அமைப்புகளில் பின்னர் மாற்றலாம்.", + "onboarding_privacy_description": "பின்வரும் (விரும்பினால்) நற்பொருத்தங்கள் வெளிப்புற சேவைகளை நம்பியுள்ளன, மேலும் அமைப்புகளில் எந்த நேரத்திலும் முடக்கப்படலாம்.", + "onboarding_server_welcome_description": "சில பொதுவான அமைப்புகளுடன் உங்கள் நிகழ்வை அமைப்போம்.", "onboarding_theme_description": "உங்கள் உதாரணத்திற்கு வண்ண கருப்பொருளைத் தேர்வுசெய்க. இதை உங்கள் அமைப்புகளில் பின்னர் மாற்றலாம்.", + "onboarding_user_welcome_description": "நீங்கள் தொடங்குவோம்!", "onboarding_welcome_user": "வரவேற்கிறோம், {user}", "online": "ஆன்லைனில்", "only_favorites": "பிடித்தவை மட்டுமே", + "open": "திற", "open_in_map_view": "வரைபடக் காட்சியில் திறந்திருக்கும்", "open_in_openstreetmap": "OpenStreetMap இல் திறந்திருக்கும்", "open_the_search_filters": "தேடல் வடிப்பான்களைத் திறக்கவும்", "options": "விருப்பங்கள்", "or": "அல்லது", + "organize_into_albums": "ஆல்பங்களாக ஒழுங்கமைக்கவும்", + "organize_into_albums_description": "தற்போதைய ஒத்திசைவு அமைப்புகளைப் பயன்படுத்தி ஏற்கனவே உள்ள புகைப்படங்களை ஆல்பங்களில் வைக்கவும்", "organize_your_library": "உங்கள் நூலகத்தை ஒழுங்கமைக்கவும்", "original": "அசல்", "other": "மற்றொன்று", "other_devices": "பிற சாதனங்கள்", + "other_entities": "பிற நிறுவனங்கள்", "other_variables": "பிற மாறிகள்", "owned": "சொந்தமானது", "owner": "உரிமையாளர்", @@ -962,6 +1454,14 @@ "partner_can_access": "{partner} அணுகலாம்", "partner_can_access_assets": "காப்பகப்படுத்தப்பட்ட மற்றும் நீக்கப்பட்டவை தவிர உங்கள் புகைப்படங்கள் மற்றும் வீடியோக்கள் அனைத்தும்", "partner_can_access_location": "உங்கள் புகைப்படங்கள் எடுக்கப்பட்ட இடம்", + "partner_list_user_photos": "{பயனரின் புகைப்படங்கள்", + "partner_list_view_all": "அனைத்தையும் காண்க", + "partner_page_empty_message": "உங்கள் புகைப்படங்கள் இன்னும் எந்த கூட்டாளருடனும் பகிரப்படவில்லை.", + "partner_page_no_more_users": "சேர்க்க இனி பயனர்கள் இல்லை", + "partner_page_partner_add_failed": "கூட்டாளரைச் சேர்க்கத் தவறிவிட்டது", + "partner_page_select_partner": "கூட்டாளரைத் தேர்ந்தெடுக்கவும்", + "partner_page_shared_to_title": "பகிரப்பட்டது", + "partner_page_stop_sharing_content": "{கூட்டாளர் your இனி உங்கள் புகைப்படங்களை அணுக முடியாது.", "partner_sharing": "கூட்டாளர் பகிர்வு", "partners": "கூட்டாளர்கள்", "password": "கடவுச்சொல்", @@ -987,10 +1487,24 @@ "permanent_deletion_warning_setting_description": "சொத்துக்களை நிரந்தரமாக நீக்கும்போது ஒரு எச்சரிக்கையைக் காட்டுங்கள்", "permanently_delete": "நிரந்தரமாக நீக்கு", "permanently_delete_assets_count": "நிரந்தரமாக நீக்கு {எண்ணிக்கை, பன்மை, ஒன்று {asset} மற்ற {assets}}", - "permanently_delete_assets_prompt": "நீங்கள் நிச்சயமாக {எண்ணிக்கை, பன்மை, ஒன்று {இந்த சொத்து?} மற்ற {இந்த # சொத்துக்கள்? } அவர்களின்}} ஆல்பம் (கள்) இலிருந்து.", + "permanently_delete_assets_prompt": "நீங்கள் நிச்சயமாக {எண்ணிக்கை, பன்மை, ஒன்று {இந்த சொத்து?} மற்ற {இந்த # சொத்துக்கள்?", "permanently_deleted_asset": "நிரந்தரமாக நீக்கப்பட்ட சொத்து", "permanently_deleted_assets_count": "நிரந்தரமாக நீக்கப்பட்டது {எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} பிற {# சொத்துக்கள்}}", + "permission": "இசைவு", + "permission_empty": "உங்கள் இசைவு காலியாக இருக்கக்கூடாது", + "permission_onboarding_back": "பின்", + "permission_onboarding_continue_anyway": "எப்படியும் தொடரவும்", + "permission_onboarding_get_started": "தொடங்கவும்", + "permission_onboarding_go_to_settings": "அமைப்புகளுக்குச் செல்லுங்கள்", + "permission_onboarding_permission_denied": "இசைவு மறுக்கப்பட்டது. இம்மிச்சைப் பயன்படுத்த, அமைப்புகளில் புகைப்படம் மற்றும் வீடியோ அனுமதிகளை வழங்கவும்.", + "permission_onboarding_permission_granted": "இசைவு வழங்கப்பட்டது! நீங்கள் அனைவரும் அமைக்கப்பட்டிருக்கிறீர்கள்.", + "permission_onboarding_permission_limited": "இசைவு லிமிடெட். உங்கள் முழு கேலரி சேகரிப்பையும் நிர்வகிக்கவும் நிர்வகிக்கவும், அமைப்புகளில் புகைப்படம் மற்றும் வீடியோ அனுமதிகளை வழங்கவும்.", + "permission_onboarding_request": "உங்கள் புகைப்படங்கள் மற்றும் வீடியோக்களைக் காண இம்மிச்சுக்கு இசைவு தேவை.", "person": "ஆள்", + "person_age_months": "{மாதங்கள், பன்மை, ஒன்று {# மாதம்} மற்ற {# மாதங்கள்}} பழையது", + "person_age_year_months": "1 ஆண்டு, {மாதங்கள், பன்மை, ஒன்று {# மாதம்} மற்ற {# மாதங்கள்}} பழையது", + "person_age_years": "{ஆண்டுகள், பன்மை, பிற {# ஆண்டுகள்}} பழையது", + "person_birthdate": "{date} இல் பிறந்தார்", "person_hidden": "{name} {மறைக்கப்பட்ட, தேர்ந்தெடு, உண்மை {(மறைக்கப்பட்ட)} பிற {}}", "photo_shared_all_users": "உங்கள் புகைப்படங்களை எல்லா பயனர்களுடனும் பகிர்ந்து கொண்டதாகத் தெரிகிறது அல்லது பகிர்வதற்கு உங்களிடம் எந்த பயனரும் இல்லை.", "photos": "புகைப்படங்கள்", @@ -998,20 +1512,41 @@ "photos_count": "{எண்ணிக்கை, பன்மை, ஒன்று {{எண்ணிக்கை, எண்} புகைப்படம்} பிற {{எண்ணிக்கை, எண்} புகைப்படங்கள்}}", "photos_from_previous_years": "முந்தைய ஆண்டுகளின் புகைப்படங்கள்", "pick_a_location": "ஒரு இடத்தைத் தேர்ந்தெடுங்கள்", + "pin_code_changed_successfully": "முள் குறியீட்டை வெற்றிகரமாக மாற்றியது", + "pin_code_reset_successfully": "முள் குறியீட்டை வெற்றிகரமாக மீட்டமைக்கவும்", + "pin_code_setup_successfully": "முள் குறியீட்டை வெற்றிகரமாக அமைக்கவும்", + "pin_verification": "குறியீடு சரிபார்ப்பு", "place": "இடம்", "places": "இடங்கள்", + "places_count": "{எண்ணிக்கை, பன்மை, ஒன்று {{எண்ணிக்கை, எண்} இடம்} பிற {{எண்ணிக்கை, எண்} இடங்கள்}}", "play": "விளையாடுங்கள்", "play_memories": "பிளேமெமரிகள்", "play_motion_photo": "இயக்க புகைப்படத்தை விளையாடுங்கள்", "play_or_pause_video": "வீடியோவை இயக்கவும் அல்லது இடைநிறுத்தவும்", + "please_auth_to_access": "அணுகலை அங்கீகரிக்கவும்", "port": "துறைமுகம்", + "preferences_settings_subtitle": "பயன்பாட்டின் விருப்பங்களை நிர்வகிக்கவும்", + "preferences_settings_title": "விருப்பத்தேர்வுகள்", + "preparing": "தயாராகிறது", "preset": "முன்னமைவு", "preview": "முன்னோட்டம்", "previous": "முந்தைய", "previous_memory": "முந்தைய நினைவகம்", - "previous_or_next_photo": "முந்தைய அல்லது அடுத்த புகைப்படம்", + "previous_or_next_day": "நாள் முன்னோக்கி/பின்னோக்கி", + "previous_or_next_month": "மாதம் முன்னோக்கி/பின்னோக்கி", + "previous_or_next_photo": "புகைப்படம் முன்னோக்கி/பின்னோக்கி", + "previous_or_next_year": "ஆண்டு முன்னோக்கி/பின்னோக்கி", "primary": "முதன்மை", "privacy": "தனியுரிமை", + "profile": "சுயவிவரம்", + "profile_drawer_app_logs": "பதிவுகள்", + "profile_drawer_client_out_of_date_major": "மொபைல் பயன்பாடு காலாவதியானது. தயவு செய்து சமீபத்திய முக்கிய பதிப்பிற்கு புதுப்பிக்கவும்.", + "profile_drawer_client_out_of_date_minor": "மொபைல் பயன்பாடு காலாவதியானது. தயவு செய்து சமீபத்திய சிறிய பதிப்பிற்கு புதுப்பிக்கவும்.", + "profile_drawer_client_server_up_to_date": "வாங்கி மற்றும் சேவையகம் புதுப்பித்த நிலையில் உள்ளன", + "profile_drawer_github": "கிட்ஹப்", + "profile_drawer_readonly_mode": "படிக்க மட்டும் பயன்முறை இயக்கப்பட்டது. வெளியேற பயனர் அவதார் ஐகானை நீண்ட நேரம் அழுத்தவும்.", + "profile_drawer_server_out_of_date_major": "சேவையகம் காலாவதியானது. அண்மைக் கால முக்கிய பதிப்பிற்கு புதுப்பிக்கவும்.", + "profile_drawer_server_out_of_date_minor": "சேவையகம் காலாவதியானது. அண்மைக் கால சிறிய பதிப்பிற்கு புதுப்பிக்கவும்.", "profile_image_of_user": "{பயனரின் சுயவிவரப் படம்", "profile_picture_set": "சுயவிவரப் பட தொகுப்பு.", "public_album": "பொது ஆல்பம்", @@ -1036,7 +1571,7 @@ "purchase_lifetime_description": "வாழ்நாள் கொள்முதல்", "purchase_option_title": "விருப்பங்களை வாங்கவும்", "purchase_panel_info_1": "இம்மியை உருவாக்குவதற்கு நிறைய நேரமும் முயற்சியும் தேவைப்படுகிறது, மேலும் முழுநேர பொறியியலாளர்கள் அதை எங்களால் முடிந்தவரை சிறப்பாகச் செய்ய வேலை செய்கிறார்கள். எங்கள் நோக்கம் திறந்த மூல மென்பொருள் மற்றும் நெறிமுறை வணிக நடைமுறைகள் டெவலப்பர்களுக்கான நிலையான வருமான ஆதாரமாக மாறுவதும், சுரண்டல் முகில் சேவைகளுக்கு உண்மையான மாற்றுகளுடன் தனியுரிமை-மரியாதைக்குரிய சுற்றுச்சூழல் அமைப்பை உருவாக்குவதும் ஆகும்.", - "purchase_panel_info_2": "பேவால்களைச் சேர்க்காமல் இருப்பதில் நாங்கள் கடமைப்பட்டுள்ளதால், இந்த கொள்முதல் இம்மிச்சில் கூடுதல் அம்சங்களை உங்களுக்கு வழங்காது. இம்மிச்சின் தற்போதைய வளர்ச்சியை ஆதரிக்க உங்களைப் போன்ற பயனர்களை நாங்கள் நம்பியுள்ளோம்.", + "purchase_panel_info_2": "பேவால்களைச் சேர்க்காமல் இருப்பதில் நாங்கள் உறுதியாக இருப்பதால், இந்த கொள்முதல் இம்மிச்சில் கூடுதல் அம்சங்களை உங்களுக்கு வழங்காது. இம்மிச்சின் தற்போதைய வளர்ச்சியை ஆதரிக்க உங்களைப் போன்ற பயனர்களை நாங்கள் நம்பியுள்ளோம்.", "purchase_panel_title": "திட்டத்தை ஆதரிக்கவும்", "purchase_per_server": "ஒரு சேவையகத்திற்கு", "purchase_per_user": "ஒரு பயனருக்கு", @@ -1048,19 +1583,28 @@ "purchase_server_description_2": "ஆதரவாளர் நிலை", "purchase_server_title": "சேவையகம்", "purchase_settings_server_activated": "சேவையக தயாரிப்பு விசை நிர்வாகியால் நிர்வகிக்கப்படுகிறது", + "query_asset_id": "வினவல் சொத்து அடையாளம்", + "queue_status": "வரிசை {count}/{total}", "rating": "நட்சத்திர மதிப்பீடு", "rating_clear": "தெளிவான மதிப்பீடு", "rating_count": "{எண்ணிக்கை, பன்மை, ஒன்று {# நட்சத்திரம்} மற்ற {# நட்சத்திரங்கள்}}", "rating_description": "செய்தி குழுவில் EXIF மதிப்பீட்டைக் காண்பி", "reaction_options": "எதிர்வினை விருப்பங்கள்", "read_changelog": "சேஞ்ச்லாக் படிக்கவும்", - "reassign": "மீண்டும் இணைக்கவும்", + "readonly_mode_disabled": "படிக்க மட்டும் பயன்முறை முடக்கப்பட்டுள்ளது", + "readonly_mode_enabled": "படிக்க மட்டும் பயன்முறை இயக்கப்பட்டது", + "ready_for_upload": "பதிவேற்றத் தயார்", + "reassign": "மீண்டும் ஒதுக்கு", "reassigned_assets_to_existing_person": "மீண்டும் ஒதுக்கப்பட்ட {எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} பிற {# சொத்துக்கள்}} பெறுநர் {பெயருக்கு, தேர்ந்தெடுக்கவும், சுழிய {an existing person} பிற {{name}}}", "reassigned_assets_to_new_person": "மீண்டும் ஒதுக்கப்பட்ட {எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} பிற {# சொத்துக்கள்}} ஒரு புதிய நபருக்கு", "reassing_hint": "தேர்ந்தெடுக்கப்பட்ட சொத்துக்களை ஏற்கனவே இருக்கும் நபருக்கு ஒதுக்குங்கள்", "recent": "அண்மைக் கால", "recent-albums": "அண்மைக் கால ஆல்பங்கள்", "recent_searches": "அண்மைக் கால தேடல்கள்", + "recently_added": "அண்மைக் காலத்தில் சேர்க்கப்பட்டது", + "recently_added_page_title": "அண்மைக் காலத்தில் சேர்க்கப்பட்டது", + "recently_taken": "அண்மைக் காலத்தில் எடுக்கப்பட்டது", + "recently_taken_page_title": "அண்மைக் காலத்தில் எடுக்கப்பட்டது", "refresh": "புதுப்பிப்பு", "refresh_encoded_videos": "குறியிடப்பட்ட வீடியோக்களை புதுப்பிக்கவும்", "refresh_faces": "முகங்களைப் புதுப்பிக்கவும்", @@ -1072,6 +1616,9 @@ "refreshing_faces": "புத்துணர்ச்சியூட்டும் முகங்கள்", "refreshing_metadata": "புத்துணர்ச்சியூட்டும் மேனிலை தரவு", "regenerating_thumbnails": "சிறுபடங்களை மீண்டும் உருவாக்குகிறது", + "remote": "தொலைநிலை", + "remote_assets": "தொலை சொத்துக்கள்", + "remote_media_summary": "தொலை ஊடக சுருக்கம்", "remove": "அகற்று", "remove_assets_album_confirmation": "ஆல்பத்திலிருந்து {எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} பிற {# சொத்துக்கள்} your ஐ அகற்ற விரும்புகிறீர்களா?", "remove_assets_shared_link_confirmation": "இந்த பகிரப்பட்ட இணைப்பிலிருந்து {எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} பிற {# சொத்துக்கள்} your ஐ அகற்ற விரும்புகிறீர்களா?", @@ -1079,14 +1626,23 @@ "remove_custom_date_range": "தனிப்பயன் தேதி வரம்பை அகற்று", "remove_deleted_assets": "நீக்கப்பட்ட சொத்துக்களை அகற்றவும்", "remove_from_album": "ஆல்பத்திலிருந்து அகற்று", + "remove_from_album_action_prompt": "{எண்ணிக்கை the ஆல்பத்திலிருந்து அகற்றப்பட்டது", "remove_from_favorites": "பிடித்தவைகளிலிருந்து அகற்று", + "remove_from_lock_folder_action_prompt": "{எண்ணிக்கை the பூட்டப்பட்ட கோப்புறையிலிருந்து அகற்றப்பட்டது", + "remove_from_locked_folder": "பூட்டப்பட்ட கோப்புறையிலிருந்து அகற்று", + "remove_from_locked_folder_confirmation": "பூட்டப்பட்ட கோப்புறையிலிருந்து இந்த புகைப்படங்களையும் வீடியோக்களையும் நகர்த்த விரும்புகிறீர்களா? அவை உங்கள் நூலகத்தில் தெரியும்.", "remove_from_shared_link": "பகிரப்பட்ட இணைப்பிலிருந்து அகற்று", + "remove_memory": "நினைவகத்தை அகற்று", + "remove_photo_from_memory": "இந்த நினைவிலிருந்து புகைப்படத்தை அகற்று", + "remove_tag": "குறிச்சொல்லை அகற்று", "remove_url": "முகவரி ஐ அகற்று", "remove_user": "பயனரை அகற்று", "removed_api_key": "அகற்றப்பட்ட பநிஇ விசை: {name}", "removed_from_archive": "காப்பகத்திலிருந்து அகற்றப்பட்டது", "removed_from_favorites": "பிடித்தவைகளிலிருந்து அகற்றப்பட்டது", "removed_from_favorites_count": "{எண்ணிக்கை, பன்மை, பிற {பிடித்தவைகளிலிருந்து #}} அகற்றப்பட்டது", + "removed_memory": "அகற்றப்பட்ட நினைவகம்", + "removed_photo_from_memory": "நினைவிலிருந்து புகைப்படத்தை அகற்றியது", "removed_tagged_assets": "{எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} பிற {# சொத்துக்கள்} இருந்து இலிருந்து அகற்றப்பட்ட குறிச்சொல்", "rename": "மறுபெயரிடுங்கள்", "repair": "பழுது", @@ -1095,27 +1651,41 @@ "repository": "களஞ்சியம்", "require_password": "கடவுச்சொல் தேவை", "require_user_to_change_password_on_first_login": "முதல் உள்நுழைவில் கடவுச்சொல்லை மாற்ற பயனர் தேவை", + "rescan": "ரெச்கான்", "reset": "மீட்டமை", "reset_password": "கடவுச்சொல்லை மீட்டமைக்கவும்", "reset_people_visibility": "மக்களின் தெரிவுநிலையை மீட்டமைக்கவும்", + "reset_pin_code": "முள் குறியீட்டை மீட்டமைக்கவும்", + "reset_pin_code_description": "உங்கள் முள் குறியீட்டை மறந்துவிட்டால், அதை மீட்டமைக்க சேவையக நிர்வாகியை தொடர்பு கொள்ளலாம்", + "reset_pin_code_success": "முள் குறியீட்டை வெற்றிகரமாக மீட்டமைக்கவும்", + "reset_pin_code_with_password": "உங்கள் கடவுச்சொல் மூலம் உங்கள் முள் குறியீட்டை எப்போதும் மீட்டமைக்கலாம்", + "reset_sqlite": "SQLite தரவுத்தளத்தை மீட்டமைக்கவும்", + "reset_sqlite_confirmation": "SQLITE தரவுத்தளத்தை மீட்டமைக்க விரும்புகிறீர்களா? தரவை மீண்டும் ஒத்திசைக்க நீங்கள் வெளியேறி மீண்டும் உள்நுழைய வேண்டும்", + "reset_sqlite_success": "SQLITE தரவுத்தளத்தை வெற்றிகரமாக மீட்டமைக்கவும்", "reset_to_default": "இயல்புநிலைக்கு மீட்டமைக்கவும்", "resolve_duplicates": "நகல்களைத் தீர்க்கவும்", "resolved_all_duplicates": "அனைத்து நகல்களையும் தீர்க்கும்", "restore": "மீட்டமை", "restore_all": "அனைத்தையும் மீட்டெடுக்கவும்", + "restore_trash_action_prompt": "{எண்ணிக்கை the குப்பைகளிலிருந்து மீட்டெடுக்கப்பட்டது", "restore_user": "பயனரை மீட்டமைக்கவும்", "restored_asset": "மீட்டெடுக்கப்பட்ட சொத்து", "resume": "மீண்டும் தொடங்குங்கள்", + "resume_paused_jobs": "மீண்டும் தொடங்குங்கள் {எண்ணிக்கை, பன்மை, ஒன்று {# இடைநிறுத்தப்பட்ட வேலை} மற்ற {# இடைநிறுத்தப்பட்ட வேலைகள்}}", "retry_upload": "பதிவேற்ற முயற்சிக்கவும்", "review_duplicates": "நகல்களை மதிப்பாய்வு செய்யவும்", + "review_large_files": "பெரிய கோப்புகளை மதிப்பாய்வு செய்யவும்", "role": "பங்கு", "role_editor": "திருத்தி", "role_viewer": "பார்வையாளர்", + "running": "இயங்கும்", "save": "சேமி", + "save_to_gallery": "கேலரியில் சேமிக்கவும்", "saved_api_key": "சேமித்த பநிஇ விசை", "saved_profile": "சேமித்த சுயவிவரம்", "saved_settings": "சேமித்த அமைப்புகள்", "say_something": "ஏதாவது சொல்லுங்கள்", + "scaffold_body_error_occurred": "பிழை ஏற்பட்டது", "scan_all_libraries": "அனைத்து நூலகங்களையும் ச்கேன் செய்யுங்கள்", "scan_library": "ச்கேன்", "scan_settings": "அமைப்புகளை ச்கேன் செய்யுங்கள்", @@ -1123,20 +1693,53 @@ "search": "தேடல்", "search_albums": "ஆல்பங்களைத் தேடுங்கள்", "search_by_context": "சூழலால் தேடுங்கள்", + "search_by_description": "விளக்கத்தின் மூலம் தேடுங்கள்", + "search_by_description_example": "சப்பாவில் நடைபயணம்", "search_by_filename": "கோப்பு பெயர் அல்லது நீட்டிப்பு மூலம் தேடுங்கள்", "search_by_filename_example": "I.E. IMG_1234.JPG அல்லது PNG", "search_camera_make": "தேடல் கேமரா செய்யுங்கள் ...", "search_camera_model": "கேமரா மாதிரியைத் தேடுங்கள் ...", "search_city": "தேடல் நகரம் ...", "search_country": "தேடல் நாடு ...", + "search_filter_apply": "வடிகட்டியைப் பயன்படுத்துங்கள்", + "search_filter_camera_title": "கேமரா வகையைத் தேர்ந்தெடுக்கவும்", + "search_filter_date": "திகதி", + "search_filter_date_interval": "{start} பெறுநர் {end}", + "search_filter_date_title": "தேதி வரம்பைத் தேர்ந்தெடுக்கவும்", + "search_filter_display_option_not_in_album": "ஆல்பத்தில் இல்லை", + "search_filter_display_options": "காட்சி விருப்பங்கள்", + "search_filter_filename": "கோப்பு பெயர் மூலம் தேடுங்கள்", + "search_filter_location": "இடம்", + "search_filter_location_title": "இருப்பிடத்தைத் தேர்ந்தெடுக்கவும்", + "search_filter_media_type": "ஊடக வகை", + "search_filter_media_type_title": "மீடியா வகையைத் தேர்ந்தெடுக்கவும்", + "search_filter_people_title": "மக்களைத் தேர்ந்தெடுக்கவும்", + "search_for": "தேடுங்கள்", "search_for_existing_person": "இருக்கும் நபரைத் தேடுங்கள்", + "search_no_more_result": "மேலும் முடிவுகள் இல்லை", "search_no_people": "மக்கள் இல்லை", "search_no_people_named": "\"{name}\" என்று பெயரிடப்பட்டவர்கள் யாரும் இல்லை", + "search_no_result": "முடிவுகள் எதுவும் கிடைக்கவில்லை, வேறு தேடல் காலத்தை அல்லது கலவையை முயற்சிக்கவும்", "search_options": "தேடல் விருப்பங்கள்", + "search_page_categories": "வகைகள்", + "search_page_motion_photos": "இயக்க புகைப்படங்கள்", + "search_page_no_objects": "பொருள் செய்தி எதுவும் கிடைக்கவில்லை", + "search_page_no_places": "இடங்கள் செய்தி கிடைக்கவில்லை", + "search_page_screenshots": "திரைக்காட்சிகள்", + "search_page_search_photos_videos": "உங்கள் புகைப்படங்கள் மற்றும் வீடியோக்களைத் தேடுங்கள்", + "search_page_selfies": "செல்ஃபிகள்", + "search_page_things": "விசயங்கள்", + "search_page_view_all_button": "அனைத்தையும் காண்க", + "search_page_your_activity": "உங்கள் செயல்பாடு", + "search_page_your_map": "உங்கள் வரைபடம்", "search_people": "மக்களைத் தேடுங்கள்", "search_places": "இடங்களைத் தேடுங்கள்", + "search_rating": "மதிப்பீட்டின் மூலம் தேடுங்கள் ...", + "search_result_page_new_search_hint": "புதிய தேடல்", "search_settings": "அமைப்புகளைத் தேடுங்கள்", "search_state": "தேடல் நிலை ...", + "search_suggestion_list_smart_search_hint_1": "மெட்டாடேட்டாவைத் தேட, நிகழ்வைப் பயன்படுத்த, அறிவுள்ள தேடல் இயல்புநிலையாக இயக்கப்பட்டது ", + "search_suggestion_list_smart_search_hint_2": "எம்: உங்கள் தேடல்-காலநிலை", "search_tags": "குறிச்சொற்களைத் தேடுங்கள் ...", "search_timezone": "நேர மண்டலத்தைத் தேடுங்கள் ...", "search_type": "தேடல் வகை", @@ -1144,9 +1747,11 @@ "searching_locales": "இடங்களைத் தேடுகிறது ...", "second": "இரண்டாவது", "see_all_people": "எல்லா மக்களையும் பாருங்கள்", + "select": "தேர்ந்தெடு", "select_album_cover": "ஆல்பம் அட்டையைத் தேர்ந்தெடுக்கவும்", "select_all": "அனைத்தையும் தெரிவுசெய்", "select_all_duplicates": "அனைத்து நகல்களையும் தேர்ந்தெடுக்கவும்", + "select_all_in": "{குழுவில் அனைத்தையும் தேர்ந்தெடுக்கவும்", "select_avatar_color": "அவதார் நிறத்தைத் தேர்ந்தெடுக்கவும்", "select_face": "முகத்தைத் தேர்ந்தெடுக்கவும்", "select_featured_photo": "பிரத்யேக புகைப்படத்தைத் தேர்ந்தெடுக்கவும்", @@ -1154,14 +1759,21 @@ "select_keep_all": "அனைத்தையும் வைத்திருங்கள் என்பதைத் தேர்ந்தெடுக்கவும்", "select_library_owner": "நூலக உரிமையாளரைத் தேர்ந்தெடுக்கவும்", "select_new_face": "புதிய முகத்தைத் தேர்ந்தெடுக்கவும்", + "select_person_to_tag": "குறிக்க ஒரு நபரைத் தேர்ந்தெடுக்கவும்", "select_photos": "புகைப்படங்களைத் தேர்ந்தெடுக்கவும்", "select_trash_all": "குப்பைத் தொட்டியைத் தேர்ந்தெடுக்கவும்", + "select_user_for_sharing_page_err_album": "ஆல்பத்தை உருவாக்கத் தவறிவிட்டது", "selected": "தேர்ந்தெடுக்கப்பட்டது", "selected_count": "{எண்ணிக்கை, பன்மை, பிற {# தேர்ந்தெடுக்கப்பட்ட}}", + "selected_gps_coordinates": "தேர்ந்தெடுக்கப்பட்ட சி.பி.எச் ஆயத்தொலைவுகள்", "send_message": "செய்தி அனுப்பவும்", "send_welcome_email": "வரவேற்பு மின்னஞ்சலை அனுப்பவும்", + "server_endpoint": "சேவையக இறுதிப்புள்ளி", + "server_info_box_app_version": "பயன்பாட்டு பதிப்பு", + "server_info_box_server_url": "சேவையக முகவரி", "server_offline": "சேவையகம் இணைப்பில்லாத", "server_online": "ஆன்லைனில் சேவையகம்", + "server_privacy": "சேவையக தனியுரிமை", "server_stats": "சேவையக புள்ளிவிவரங்கள்", "server_version": "சேவையக பதிப்பு", "set": "கணம்", @@ -1171,21 +1783,96 @@ "set_date_of_birth": "பிறந்த தேதியை அமைக்கவும்", "set_profile_picture": "சுயவிவரப் படத்தை அமைக்கவும்", "set_slideshow_to_fullscreen": "ச்லைடுசோவை முழுமைக்கு அமைக்கவும்", + "set_stack_primary_asset": "முதன்மை சொத்தாக அமைக்கவும்", + "setting_image_viewer_help": "விவரம் பார்வையாளர் முதலில் சிறிய சிறு உருவத்தை ஏற்றுகிறார், பின்னர் நடுத்தர அளவிலான முன்னோட்டத்தை ஏற்றுகிறார் (இயக்கப்பட்டால்), இறுதியாக அசலை ஏற்றுகிறது (இயக்கப்பட்டால்).", + "setting_image_viewer_original_subtitle": "அசல் முழு தெளிவுத்திறன் படத்தை ஏற்றவும் (பெரியது!). தரவு பயன்பாட்டைக் குறைக்க முடக்கு (பிணையம் மற்றும் சாதன தற்காலிக சேமிப்பு இரண்டும்).", + "setting_image_viewer_original_title": "அசல் படத்தை ஏற்றவும்", + "setting_image_viewer_preview_subtitle": "நடுத்தர-தெளிவுத்திறன் படத்தை ஏற்றவும். அசலை நேரடியாக ஏற்ற முடக்கவும் அல்லது சிறுபடத்தை மட்டுமே பயன்படுத்தவும்.", + "setting_image_viewer_preview_title": "முன்னோட்டம் படத்தை ஏற்றவும்", + "setting_image_viewer_title": "படங்கள்", + "setting_languages_apply": "இடு", + "setting_languages_subtitle": "பயன்பாட்டின் மொழியை மாற்றவும்", + "setting_notifications_notify_failures_grace_period": "பின்னணி காப்புப்பிரதி தோல்விகளை அறிவிக்கவும்: {duration}", + "setting_notifications_notify_hours": "{count} மணிநேரம்", + "setting_notifications_notify_immediately": "உடனடியாக", + "setting_notifications_notify_minutes": "{count} நிமிடங்கள்", + "setting_notifications_notify_never": "ஒருபோதும்", + "setting_notifications_notify_seconds": "{count} விநாடிகள்", + "setting_notifications_single_progress_subtitle": "விரிவான பதிவேற்றும் முன்னேற்ற செய்தி ஒரு சொத்துக்கு", + "setting_notifications_single_progress_title": "பின்னணி காப்புப்பிரதி விவரம் முன்னேற்றத்தைக் காட்டு", + "setting_notifications_subtitle": "உங்கள் அறிவிப்பு விருப்பங்களை சரிசெய்யவும்", + "setting_notifications_total_progress_subtitle": "ஒட்டுமொத்த பதிவேற்ற முன்னேற்றம் (முடிந்தது/மொத்த சொத்துக்கள்)", + "setting_notifications_total_progress_title": "பின்னணி காப்புப்பிரதி மொத்த முன்னேற்றத்தைக் காட்டு", + "setting_video_viewer_looping_title": "லூப்பிங்", + "setting_video_viewer_original_video_subtitle": "சேவையகத்திலிருந்து ஒரு வீடியோவை ச்ட்ரீமிங் செய்யும் போது, ஒரு டிரான்ச்கோடு கிடைக்கும்போது கூட அசலை இயக்கவும். இடையகத்திற்கு வழிவகுக்கும். இந்த அமைப்பைப் பொருட்படுத்தாமல் உள்நாட்டில் கிடைக்கும் வீடியோக்கள் அசல் தரத்தில் இயக்கப்படுகின்றன.", + "setting_video_viewer_original_video_title": "அசல் வீடியோவை கட்டாயப்படுத்துங்கள்", "settings": "அமைப்புகள்", + "settings_require_restart": "இந்த அமைப்பைப் பயன்படுத்த இம்மியை மறுதொடக்கம் செய்யுங்கள்", "settings_saved": "அமைப்புகள் சேமிக்கப்பட்டன", + "setup_pin_code": "முள் குறியீட்டை அமைக்கவும்", "share": "பங்கு", + "share_action_prompt": "பகிரப்பட்ட {count} சொத்துக்கள்", + "share_add_photos": "புகைப்படங்களைச் சேர்க்கவும்", + "share_assets_selected": "{count} தேர்ந்தெடுக்கப்பட்டது", + "share_dialog_preparing": "தயாரித்தல் ...", + "share_link": "இணைப்பைப் பகிரவும்", "shared": "பகிரப்பட்டது", + "shared_album_activities_input_disable": "கருத்து முடக்கப்பட்டுள்ளது", + "shared_album_activity_remove_content": "இந்தச் செயல்பாட்டை நீக்க விரும்புகிறீர்களா?", + "shared_album_activity_remove_title": "செயல்பாட்டை நீக்கு", + "shared_album_section_people_action_error": "ஆல்பத்திலிருந்து வெளியேறுதல்/நீக்குதல்", + "shared_album_section_people_action_leave": "ஆல்பத்திலிருந்து பயனரை அகற்று", + "shared_album_section_people_action_remove_user": "ஆல்பத்திலிருந்து பயனரை அகற்று", + "shared_album_section_people_title": "மக்கள்", "shared_by": "பகிரப்பட்டது", "shared_by_user": "{பயனரால் பகிரப்பட்டது", "shared_by_you": "நீங்கள் பகிர்ந்து கொண்டார்", "shared_from_partner": "{partner} இலிருந்து புகைப்படங்கள்", + "shared_intent_upload_button_progress_text": "{current} / {total} பதிவேற்றப்பட்டது", + "shared_link_app_bar_title": "பகிரப்பட்ட இணைப்புகள்", + "shared_link_clipboard_copied_massage": "இடைநிலைப்பலகைக்கு நகலெடுக்கப்பட்டது", + "shared_link_clipboard_text": "இணைப்பு: {link} \nகடவுச்சொல்: {password}", + "shared_link_create_error": "பகிரப்பட்ட இணைப்பை உருவாக்கும் போது பிழை", + "shared_link_custom_url_description": "தனிப்பயன் முகவரி உடன் இந்த பகிரப்பட்ட இணைப்பை அணுகவும்", + "shared_link_edit_description_hint": "பங்கு விளக்கத்தை உள்ளிடவும்", + "shared_link_edit_expire_after_option_day": "1 நாள்", + "shared_link_edit_expire_after_option_days": "{count} நாட்கள்", + "shared_link_edit_expire_after_option_hour": "1 மணி நேரம்", + "shared_link_edit_expire_after_option_hours": "{count} மணிநேரம்", + "shared_link_edit_expire_after_option_minute": "1 மணித்துளி", + "shared_link_edit_expire_after_option_minutes": "{count} நிமிடங்கள்", + "shared_link_edit_expire_after_option_months": "{count} மாதங்கள்", + "shared_link_edit_expire_after_option_year": "{count} ஆண்டு", + "shared_link_edit_password_hint": "பகிர்வு கடவுச்சொல்லை உள்ளிடவும்", + "shared_link_edit_submit_button": "இணைப்பைப் புதுப்பிக்கவும்", + "shared_link_error_server_url_fetch": "சேவையக முகவரி ஐப் பெற முடியாது", + "shared_link_expires_day": "{count} நாள் காலாவதியாகிறது", + "shared_link_expires_days": "{count} நாட்களில் காலாவதியாகிறது", + "shared_link_expires_hour": "{count} மணிநேரத்தில் காலாவதியாகிறது", + "shared_link_expires_hours": "{count} மணிநேரத்தில் காலாவதியாகிறது", + "shared_link_expires_minute": "{count} நிமிடத்தில் காலாவதியாகிறது", + "shared_link_expires_minutes": "{count} நிமிடங்களில் காலாவதியாகிறது", + "shared_link_expires_never": "காலாவதியாகிறது", + "shared_link_expires_second": "{count} இரண்டாவதாக காலாவதியாகிறது", + "shared_link_expires_seconds": "{count} விநாடிகளில் காலாவதியாகிறது", + "shared_link_individual_shared": "தனிநபர் பகிரப்பட்டவர்", + "shared_link_info_chip_metadata": "Exif", + "shared_link_manage_links": "பகிரப்பட்ட இணைப்புகளை நிர்வகிக்கவும்", "shared_link_options": "பகிரப்பட்ட இணைப்பு விருப்பங்கள்", + "shared_link_password_description": "இந்த பகிரப்பட்ட இணைப்பை அணுக கடவுச்சொல் தேவை", "shared_links": "பகிரப்பட்ட இணைப்புகள்", + "shared_links_description": "புகைப்படங்கள் மற்றும் வீடியோக்களை இணைப்புடன் பகிரவும்", "shared_photos_and_videos_count": "{ASSETCOUNT, பன்மை, பிற {# பகிரப்பட்ட புகைப்படங்கள் மற்றும் வீடியோக்கள்.}}", + "shared_with_me": "என்னுடன் பகிரப்பட்டது", "shared_with_partner": "{கூட்டாளர் with உடன் பகிரப்பட்டது", "sharing": "பகிர்வு", "sharing_enter_password": "இந்த பக்கத்தைக் காண கடவுச்சொல்லை உள்ளிடவும்.", + "sharing_page_album": "பகிரப்பட்ட ஆல்பங்கள்", + "sharing_page_description": "உங்கள் நெட்வொர்க்கில் உள்ளவர்களுடன் புகைப்படங்களையும் வீடியோக்களையும் பகிர்ந்து கொள்ள பகிரப்பட்ட ஆல்பங்களை உருவாக்கவும்.", + "sharing_page_empty_list": "வெற்று பட்டியல்", "sharing_sidebar_description": "பக்கப்பட்டியில் பகிர்வதற்கான இணைப்பைக் காண்பி", + "sharing_silver_appbar_create_shared_album": "புதிய பகிரப்பட்ட ஆல்பம்", + "sharing_silver_appbar_share_partner": "கூட்டாளருடன் பகிர்ந்து கொள்ளுங்கள்", "shift_to_permanent_delete": "சொத்தை நிரந்தரமாக நீக்க ⇧ ஐ அழுத்தவும்", "show_album_options": "ஆல்பம் விருப்பங்களைக் காட்டு", "show_albums": "ஆல்பங்களைக் காட்டு", @@ -1203,9 +1890,11 @@ "show_person_options": "நபர் விருப்பங்களைக் காட்டு", "show_progress_bar": "முன்னேற்றப் பட்டியைக் காட்டு", "show_search_options": "தேடல் விருப்பங்களைக் காட்டு", + "show_shared_links": "பகிரப்பட்ட இணைப்புகளைக் காட்டு", "show_slideshow_transition": "ச்லைடுசோ மாற்றத்தைக் காட்டு", "show_supporter_badge": "ஆதரவாளர் ஒட்டு", "show_supporter_badge_description": "ஒரு ஆதரவாளர் பேட்சைக் காட்டு", + "show_text_search_menu": "உரை தேடல் மெனுவைக் காட்டு", "shuffle": "கலக்கு", "sidebar": "பக்கப்பட்டி", "sidebar_display_description": "பக்கப்பட்டியில் பார்வைக்கு ஒரு இணைப்பைக் காண்பி", @@ -1221,12 +1910,14 @@ "sort_created": "தேதி உருவாக்கப்பட்டது", "sort_items": "பொருட்களின் எண்ணிக்கை", "sort_modified": "தேதி மாற்றியமைக்கப்பட்டது", + "sort_newest": "புதிய புகைப்படம்", "sort_oldest": "பழமையான புகைப்படம்", "sort_people_by_similarity": "ஒற்றுமையால் மக்களை வரிசைப்படுத்துங்கள்", "sort_recent": "மிக அண்மைக் கால புகைப்படம்", "sort_title": "தலைப்பு", "source": "மூலம்", "stack": "அடுக்கு", + "stack_action_prompt": "{count} அடுக்கி வைக்கப்பட்டுள்ளது", "stack_duplicates": "அடுக்கு நகல்கள்", "stack_select_one_photo": "அடுக்குக்கு ஒரு முக்கிய புகைப்படத்தைத் தேர்ந்தெடுக்கவும்", "stack_selected_photos": "தேர்ந்தெடுக்கப்பட்ட புகைப்படங்களை அடுக்கி வைக்கவும்", @@ -1234,16 +1925,20 @@ "stacktrace": "ச்டாக் ட்ரேச்", "start": "தொடங்கு", "start_date": "தொடக்க தேதி", + "start_date_before_end_date": "தொடக்க தேதி இறுதி தேதிக்கு முன் இருக்க வேண்டும்", "state": "மாநிலம்", "status": "நிலை", + "stop_casting": "வார்ப்பதை நிறுத்துங்கள்", "stop_motion_photo": "இயக்க புகைப்படத்தை நிறுத்து", "stop_photo_sharing": "உங்கள் புகைப்படங்களைப் பகிர்வதை நிறுத்தவா?", "stop_photo_sharing_description": "{கூட்டாளர் your இனி உங்கள் புகைப்படங்களை அணுக முடியாது.", "stop_sharing_photos_with_user": "இந்த பயனருடன் உங்கள் புகைப்படங்களைப் பகிர்வதை நிறுத்துங்கள்", "storage": "சேமிப்பக இடம்", "storage_label": "சேமிப்பக சிட்டை", + "storage_quota": "சேமிப்பக ஒதுக்கீடு", "storage_usage": "{used} பயன்படுத்தப்படுகிறது", "submit": "சமர்ப்பிக்கவும்", + "success": "செய்", "suggestions": "பரிந்துரைகள்", "sunrise_on_the_beach": "கடற்கரையில் சூரிய தோன்றுகை", "support": "உதவி", @@ -1251,18 +1946,40 @@ "support_third_party_description": "உங்கள் இம்மிச் நிறுவல் மூன்றாம் தரப்பினரால் தொகுக்கப்பட்டது. நீங்கள் அனுபவிக்கும் சிக்கல்கள் அந்த தொகுப்பால் ஏற்படலாம், எனவே கீழேயுள்ள இணைப்புகளைப் பயன்படுத்தி முதல் சந்தர்ப்பத்தில் அவர்களுடன் சிக்கல்களை எழுப்புங்கள்.", "swap_merge_direction": "ஒன்றிணைக்கும் திசையை மாற்றவும்", "sync": "ஒத்திசைவு", + "sync_albums": "ஆல்பங்களை ஒத்திசைக்கவும்", + "sync_albums_manual_subtitle": "பதிவேற்றிய அனைத்து வீடியோக்களையும் புகைப்படங்களையும் தேர்ந்தெடுக்கப்பட்ட காப்பு ஆல்பங்களில் ஒத்திசைக்கவும்", + "sync_local": "உள்ளக ஒத்திசைக்கவும்", + "sync_remote": "தொலைதூரத்தை ஒத்திசைக்கவும்", + "sync_status": "நிலையை ஒத்திசைக்கவும்", + "sync_status_subtitle": "ஒத்திசைவு அமைப்பை பார்வையிடவும் மற்றும் நிர்வகிக்கவும்", + "sync_upload_album_setting_subtitle": "உங்கள் புகைப்படங்களையும் வீடியோக்களையும் இம்மிச்சில் தேர்ந்தெடுக்கப்பட்ட ஆல்பங்களுக்கு உருவாக்கி பதிவேற்றவும்", "tag": "குறிச்சொல்", "tag_assets": "குறிச்சொல் சொத்துக்கள்", "tag_created": "உருவாக்கப்பட்ட குறிச்சொல்: {tag}", "tag_feature_description": "தர்க்கரீதியான குறிச்சொல் தலைப்புகளால் தொகுக்கப்பட்ட புகைப்படங்கள் மற்றும் வீடியோக்களை உலாவுதல்", "tag_not_found_question": "குறிச்சொல்லைக் கண்டுபிடிக்க முடியவில்லையா? <இணைப்பு> புதிய குறிச்சொல்லை உருவாக்கவும். ", + "tag_people": "மக்களை குறிக்கவும்", "tag_updated": "புதுப்பிக்கப்பட்ட குறிச்சொல்: {tag}", "tagged_assets": "குறித்துள்ளார் {எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} மற்ற {# சொத்துக்கள்}}", "tags": "குறிச்சொற்கள்", + "tap_to_run_job": "வேலையை இயக்க தட்டவும்", "template": "வார்ப்புரு", "theme": "கருப்பொருள்", "theme_selection": "கருப்பொருள் தேர்வு", "theme_selection_description": "உங்கள் உலாவியின் கணினி விருப்பத்தின் அடிப்படையில் தானாகவே கருப்பொருள் ஒளி அல்லது இருட்டாக அமைக்கவும்", + "theme_setting_asset_list_storage_indicator_title": "சொத்து ஓடுகளில் சேமிப்பக குறிகாட்டியைக் காட்டு", + "theme_setting_asset_list_tiles_per_row_title": "ஒரு வரிசையில் சொத்துக்களின் எண்ணிக்கை ({count})", + "theme_setting_colorful_interface_subtitle": "பின்னணி மேற்பரப்புகளுக்கு முதன்மை வண்ணத்தைப் பயன்படுத்துங்கள்.", + "theme_setting_colorful_interface_title": "வண்ணமயமான இடைமுகம்", + "theme_setting_image_viewer_quality_subtitle": "விவரம் பட பார்வையாளரின் தரத்தை சரிசெய்யவும்", + "theme_setting_image_viewer_quality_title": "பட பார்வையாளர் தகுதி", + "theme_setting_primary_color_subtitle": "முதன்மை செயல்கள் மற்றும் உச்சரிப்புகளுக்கு ஒரு வண்ணத்தைத் தேர்ந்தெடுங்கள்.", + "theme_setting_primary_color_title": "முதன்மை நிறம்", + "theme_setting_system_primary_color_title": "கணினி நிறத்தைப் பயன்படுத்துங்கள்", + "theme_setting_system_theme_switch": "தானியங்கி (கணினி அமைப்பைப் பின்பற்றவும்)", + "theme_setting_theme_subtitle": "பயன்பாட்டின் கருப்பொருள் அமைப்பைத் தேர்வுசெய்க", + "theme_setting_three_stage_loading_subtitle": "மூன்று-நிலை ஏற்றுதல் ஏற்றுதல் செயல்திறனை அதிகரிக்கக்கூடும், ஆனால் கணிசமாக அதிக பிணைய சுமையை ஏற்படுத்துகிறது", + "theme_setting_three_stage_loading_title": "மூன்று-நிலை ஏற்றுதலை இயக்கவும்", "they_will_be_merged_together": "அவர்கள் ஒன்றாக இணைக்கப்படுவார்கள்", "third_party_resources": "மூன்றாம் தரப்பு வளங்கள்", "time_based_memories": "நேர அடிப்படையிலான நினைவுகள்", @@ -1272,41 +1989,70 @@ "to_change_password": "கடவுச்சொல்லை மாற்றவும்", "to_favorite": "பிடித்த", "to_login": "புகுபதிவு", + "to_multi_select": "பல-தேர்ந்தெடுக்கப்பட்ட", "to_parent": "பெற்றோரிடம் செல்லுங்கள்", + "to_select": "தேர்ந்தெடுக்க", "to_trash": "குப்பை", "toggle_settings": "அமைப்புகளை மாற்றவும்", "total": "மொத்தம்", "total_usage": "மொத்த பயன்பாடு", "trash": "குப்பை", + "trash_action_prompt": "{count} குப்பைக்கு நகர்த்தப்பட்டது", "trash_all": "அனைத்தையும் குப்பை", "trash_count": "குப்பை {எண்ணிக்கை, எண்}", "trash_delete_asset": "குப்பை/சொத்தை நீக்கு", + "trash_emptied": "காலியாக குப்பை", "trash_no_results_message": "குப்பைத் தொட்டிகள் மற்றும் வீடியோக்கள் இங்கே காண்பிக்கப்படும்.", + "trash_page_delete_all": "அனைத்தையும் நீக்கு", + "trash_page_empty_trash_dialog_content": "உங்கள் குப்பை சொத்துக்களை வெறுமை செய்ய விரும்புகிறீர்களா? இந்த உருப்படிகள் இம்மிச்சிலிருந்து நிரந்தரமாக அகற்றப்படும்", + "trash_page_info": "குப்பைத் தொட்டிகள் {days} நாட்களுக்குப் பிறகு நிரந்தரமாக நீக்கப்படும்", + "trash_page_no_assets": "குப்பை சொத்துக்கள் இல்லை", + "trash_page_restore_all": "அனைத்தையும் மீட்டெடுக்கவும்", + "trash_page_select_assets_btn": "சொத்துக்களைத் தேர்ந்தெடுக்கவும்", + "trash_page_title": "({count})", "trashed_items_will_be_permanently_deleted_after": "{நாட்கள், பன்மை, ஒன்று {# நாள்} பிற {# நாட்கள்}} க்குப் பிறகு குப்பைத் தொட்டிகள் நிரந்தரமாக நீக்கப்படும்.", + "troubleshoot": "சரிசெய்தல்", "type": "வகை", + "unable_to_change_pin_code": "முள் குறியீட்டை மாற்ற முடியவில்லை", + "unable_to_setup_pin_code": "முள் குறியீட்டை அமைக்க முடியவில்லை", "unarchive": "அன்கான்", + "unarchive_action_prompt": "{எண்ணிக்கை the காப்பகத்திலிருந்து அகற்றப்பட்டது", "unarchived_count": "{எண்ணிக்கை, பன்மை, பிற {அல்லாத #}}", + "undo": "செயல்தவிர்", "unfavorite": "மாறாத", + "unfavorite_action_prompt": "{எண்ணிக்கை the பிடித்தவைகளிலிருந்து அகற்றப்பட்டது", "unhide_person": "அருவருப்பான நபர்", "unknown": "தெரியவில்லை", + "unknown_country": "தெரியாத நாடு", "unknown_year": "தெரியாத ஆண்டு", "unlimited": "வரம்பற்றது", "unlink_motion_video": "இயக்க வீடியோவை இணைக்கவும்", "unlink_oauth": "OAUTH ஐ இணைக்கவும்", "unlinked_oauth_account": "இணைக்கப்படாத OAUTH கணக்கு", + "unmute_memories": "ஊடுருவல் நினைவுகள்", "unnamed_album": "பெயரிடப்படாத ஆல்பம்", "unnamed_album_delete_confirmation": "இந்த ஆல்பத்தை நீக்க விரும்புகிறீர்களா?", "unnamed_share": "பெயரிடப்படாத பங்கு", "unsaved_change": "சேமிக்கப்படாத மாற்றம்", "unselect_all": "அனைத்தையும் தேர்வு செய்யுங்கள்", "unselect_all_duplicates": "அனைத்து நகல்களையும் தேர்ந்தெடுக்கவும்", + "unselect_all_in": "{group}", "unstack": "அன்-ச்டாக்", + "unstack_action_prompt": "{count} தடையின்றி", "unstacked_assets_count": "அன்-ச்டாக் {எண்ணிக்கை, பன்மை, ஒன்று {# சொத்து} பிற {# சொத்துக்கள்}}", + "untagged": "அவிழ்க்கப்படாதது", "up_next": "அடுத்து", + "update_location_action_prompt": "{count} தேர்ந்தெடுக்கப்பட்ட சொத்துக்களின் இருப்பிடத்தைப் புதுப்பிக்கவும்:", + "updated_at": "புதுப்பிக்கப்பட்டது", "updated_password": "புதுப்பிக்கப்பட்ட கடவுச்சொல்", "upload": "பதிவேற்றும்", + "upload_action_prompt": "{count} பதிவேற்றுவதற்கு வரிசையில் நிற்கப்பட்டது", "upload_concurrency": "ஒத்திசைவைப் பதிவேற்றவும்", + "upload_details": "விவரங்களை பதிவேற்றவும்", + "upload_dialog_info": "தேர்ந்தெடுக்கப்பட்ட சொத்து (களை) சேவையகத்திற்கு காப்புப் பிரதி எடுக்க விரும்புகிறீர்களா?", + "upload_dialog_title": "சொத்தை பதிவேற்றவும்", "upload_errors": "பதிவேற்றம் {எண்ணிக்கை, பன்மை, ஒன்று {# பிழை} மற்ற {# பிழைகள்}} உடன் முடிக்கப்பட்டது, புதிய பதிவேற்ற சொத்துக்களைக் காண பக்கத்தைப் புதுப்பிக்கவும்.", + "upload_finished": "பதிவேற்றம் முடிந்தது", "upload_progress": "மீதமுள்ள {மீதமுள்ள, எண்} - செயலாக்கப்பட்ட {செயலாக்கப்பட்டது, எண்}/{மொத்தம், எண்}", "upload_skipped_duplicates": "{எண்ணிக்கை, பன்மை, ஒன்று {# நகல் சொத்து} பிற {# நகல் சொத்துக்கள்}}", "upload_status_duplicates": "நகல்கள்", @@ -1336,7 +2082,7 @@ "user_usage_stats_description": "கணக்கு உபயோகப் புள்ளிவிவரங்களைப் பார்க்க", "username": "பயனர்பெயர்", "users": "பயனர்கள்", - "users_added_to_album_count": "ஆல்பத்தில் {எண்ணிக்கை, பன்மை, ஒன்று{# user} மற்றவை{# users}} சேர்க்கப்பட்டது", + "users_added_to_album_count": "{எண்ணிக்கை, பன்மை, ஒன்று {# பயனர்} மற்ற {# பயனர்கள்}} ஆல்பத்தில் சேர்க்கப்பட்டது", "utilities": "பயன்பாடுகள்", "validate": "சரிபார்க்கவும்", "validate_endpoint_error": "தயவுசெய்து ஒரு செல்லுபடியாகும் URL ஐ உள்ளிடவும்", @@ -1378,9 +2124,10 @@ "wifi_name": "வைஃபை பெயர்", "wrong_pin_code": "தவறான பின் குறியீடு", "year": "ஆண்டு", - "years_ago": "{ஆண்டுகள், பன்மை, ஒன்று {# ஆண்டு} மற்ற {# ஆண்டுகள்}}} முன்பு", + "years_ago": "{years, plural, one {# ஆண்டு} other {# ஆண்டுகள்}} முன்பு", "yes": "ஆம்", "you_dont_have_any_shared_links": "உங்களிடம் பகிரப்பட்ட இணைப்புகள் எதுவும் இல்லை", "your_wifi_name": "உங்கள் வைஃபை பெயர்", - "zoom_image": "பெரிதாக்க படம்" + "zoom_image": "பெரிதாக்க படம்", + "zoom_to_bounds": "எல்லைக்கு பெரிதாக்கு" } diff --git a/i18n/tr.json b/i18n/tr.json index 9e3486d231..38d1a4c227 100644 --- a/i18n/tr.json +++ b/i18n/tr.json @@ -11,16 +11,16 @@ "activity_changed": "Etkinlik {enabled, select, true {etkin} other {devre dışı}}", "add": "Ekle", "add_a_description": "Açıklama ekle", - "add_a_location": "Konum ekle", + "add_a_location": "Bir konum ekle", "add_a_name": "İsim ekle", "add_a_title": "Başlık ekle", "add_birthday": "Doğum günü ekle", "add_endpoint": "Uç nokta ekle", "add_exclusion_pattern": "Hariç tutma deseni ekle", "add_import_path": "İçe aktarma yolu ekle", - "add_location": "Lokasyon ekle", + "add_location": "Konum ekle", "add_more_users": "Daha fazla kullanıcı ekle", - "add_partner": "Partner ekle", + "add_partner": "Ortak ekle", "add_path": "Yol ekle", "add_photos": "Fotoğraf ekle", "add_tag": "Etiket ekle", @@ -38,7 +38,7 @@ "added_to_favorites_count": "{count, number} fotoğraf favorilere eklendi", "admin": { "add_exclusion_pattern_description": "Hariç tutma desenleri ekleyin. *, ** ve ? kullanılarak Globbing (temsili yer doldurucu karakter) desteklenir. Farzedelim \"Raw\" adlı bir dizininiz var, içinde ki tüm dosyaları yoksaymak için \"**/Raw/**\" şeklinde yazabilirsiniz. \".tif\" ile biten tüm dosyaları yoksaymak için \"**/*.tif\" yazabilirsiniz. Mutlak yolu yoksaymak için \"/yoksayılacak/olan/yol/**\" şeklinde yazabilirsiniz.", - "admin_user": "Yönetici kullanıcısı", + "admin_user": "Yönetici Kullanıcı", "asset_offline_description": "Bu harici kütüphane öğesi artık diskte bulunmuyor ve çöp kutusuna taşındı. Dosya kütüphane içinde taşındıysa, yeni karşılık gelen öğe için zaman çizelgenizi kontrol edin. Bu öğeyi geri yüklemek için lütfen aşağıdaki dosya yolunun Immich tarafından erişilebilir olduğundan emin olun ve kütüphaneyi tarayın.", "authentication_settings": "Yetkilendirme Ayarları", "authentication_settings_description": "Şifre, OAuth, ve diğer yetkilendirme ayarlarını yönet", @@ -66,9 +66,9 @@ "confirm_user_password_reset": "{user} adlı kullanıcının şifresini sıfırlamak istediğinize emin misiniz?", "confirm_user_pin_code_reset": "{user} adlı kullanıcının PIN kodunu sıfırlamak istediğinize emin misiniz?", "create_job": "Görev oluştur", - "cron_expression": "Cron İfadesi", + "cron_expression": "Cron ifadesi", "cron_expression_description": "Cron formatını kullanarak tarama aralığını belirle. Daha fazla bilgi için örneğin Crontab Guru’ya bakın", - "cron_expression_presets": "Cron İfadesi Önayarları", + "cron_expression_presets": "Cron ifadesi ön ayarları", "disable_login": "Girişi devre dışı bırak", "duplicate_detection_job_description": "Benzer fotoğrafları bulmak için makine öğrenmesini çalıştır. Bu işlem Akıllı Arama'ya bağlıdır", "exclusion_pattern_description": "Kütüphaneyi tararken dosya ve klasörleri görmezden gelmek için dışlama desenlerini kullanabilirsiniz. RAW dosyaları gibi bazı dosya ve klasörleri içe aktarmak istemediğinizde bu seçeneği kullanabilirsiniz.", @@ -84,18 +84,18 @@ "image_fullsize_enabled": "Tam boyutlu görüntü üretimini etkinleştir", "image_fullsize_enabled_description": "Yerleşik önizlemeyi tercih et” seçeneği etkinleştirildiğinde, yerleşik önizlemeler dönüştürme yapılmadan doğrudan kullanılır. JPEG gibi web dostu formatlar bu ayardan etkilenmez.", "image_fullsize_quality_description": "1-100 arasında tam boyutlu görüntü kalitesi. Daha yüksek kalitelidir, ancak daha büyük dosyalar üretir.", - "image_fullsize_title": "Tam boyutlu görüntü ayarları", - "image_prefer_embedded_preview": "Gömülü önizlemeyi tercih et", - "image_prefer_embedded_preview_setting_description": "RAtoğrafları için mümkün olduğunda gömülü önizlemeyi kullan. Bu, bazı fotoğraflarda daha gerçekçi renkler n kameraya bağlıdır ve fotoğrafta normalden daha fazla görüntü bozukluklarına sebep olabilir.", + "image_fullsize_title": "Tam Boyutlu Görüntü Ayarları", + "image_prefer_embedded_preview": "Gömülü ön izlemeyi tercih et", + "image_prefer_embedded_preview_setting_description": "RAW fotoğrafları için mümkün olduğunda gömülü ön izlemeyi kullan. Bu, bazı fotoğraflarda daha gerçekçi renkler n kameraya bağlıdır ve fotoğrafta normalden daha fazla görüntü bozukluklarına sebep olabilir.", "image_prefer_wide_gamut": "Geniş renk aralığını tercih et", "image_prefer_wide_gamut_setting_description": "Önizleme görseli için P3 renk paletini tercih et. Bu, geniş renk paletli fotoğraflarda renk canlılığını daha iyi korur, fakat fotoğraflar eski tarayıcılarda ve eski cihazlarda daha farklı görünebilir. sRGB fotoğraflar renk paletini korumak için sRGB olarak tutulur.", "image_preview_description": "Orta boyutlu görüntü, meta verisi çıkarılmış, tekil bir öğe görüntülenirken ve makine öğrenimi için kullanılır", "image_preview_quality_description": "Ön izleme kalitesi 1-100 arasıdır. Yüksek değerler daha iyi kalite sağlar, ancak daha büyük dosyalar üretir ve uygulama yanıt verme hızını düşürebilir. Düşük bir değer belirlemek, makine öğrenimi kalitesini etkileyebilir.", - "image_preview_title": "Ön izleme Ayarları", + "image_preview_title": "Ön İzleme Ayarları", "image_quality": "Kalite", "image_resolution": "Çözünürlük", "image_resolution_description": "Daha yüksek çözünürlükle, daha fazla detayı koruyabilir ancak kodlanması daha uzun sürer, daha büyük dosya boyutlarına sahip olur ve uygulamanın yanıt verme hızını azaltabilir.", - "image_settings": "Fotoğraf ayarları", + "image_settings": "Fotoğraf Ayarları", "image_settings_description": "Oluşturulan fotoğrafların kalite ve çözünürlüklerini yönet", "image_thumbnail_description": "Meta verisi çıkarılmış küçük boyutlu küçük resim, ana zaman çizelgesi gibi fotoğraf gruplarını görüntülerken kullanılır", "image_thumbnail_quality_description": "Küçük resim kalitesi 1-100 arasında. Daha yüksek değerler daha iyidir, ancak daha büyük dosyalar üretir ve uygulamanın yanıt hızını azaltabilir.", @@ -105,27 +105,34 @@ "job_not_concurrency_safe": "Bu işlem eşzamanlama için uygun değil.", "job_settings": "Görev Ayarları", "job_settings_description": "Aynı anda çalışacak görevleri yönet", - "job_status": "Görev Statüleri", + "job_status": "Görev Durumu", "jobs_delayed": "{jobCount, plural, other {# gecikmeli}}", "jobs_failed": "{jobCount, plural, other {# Başarısız}}", - "library_created": "{library} kütüphanesi oluşturuldu", + "library_created": "Oluşturulan kütüphane : {library}", "library_deleted": "Kütüphane silindi", "library_import_path_description": "Belirtilecek klasörü içe aktarın. Bu klasör, alt klasörler dahil olmak üzere, görüntüler ve videolar için taranacaktır.", "library_scanning": "Periyodik Tarama", "library_scanning_description": "Periyodik kütüphane taramasını yönet", "library_scanning_enable_description": "Periyodik kütüphane taramasını etkinleştir", - "library_settings": "Harici kütüphane", + "library_settings": "Harici Kütüphane", "library_settings_description": "Harici kütüphane ayarlarını yönet", "library_tasks_description": "Yeni yada değiştirilmiş öğeler için dış kütüphaneleri tara", "library_watching_enable_description": "Harici kütüphanelerdeki dosya değişikliklerini izle", "library_watching_settings": "Kütüphane izleme (DENEYSEL)", "library_watching_settings_description": "Değişen dosyalar için otomatik olarak izle", - "logging_enable_description": "Günlüğü aktifleştir", + "logging_enable_description": "Günlüğü etkinleştir", "logging_level_description": "Etkinleştirildiğinde hangi günlük seviyesi kullanılır.", - "logging_settings": "Günlük tutma", + "logging_settings": "Günlük Tutma", + "machine_learning_availability_checks": "Kullanılabilirlik kontrolleri", + "machine_learning_availability_checks_description": "Kullanılabilir makine öğrenimi sunucularını otomatik olarak algılayın ve tercih edin", + "machine_learning_availability_checks_enabled": "Kullanılabilirlik kontrollerini etkinleştir", + "machine_learning_availability_checks_interval": "Kontrol aralığı", + "machine_learning_availability_checks_interval_description": "Kullanılabilirlik kontrolleri arasındaki milisaniye cinsinden aralık", + "machine_learning_availability_checks_timeout": "İstek zaman aşımı", + "machine_learning_availability_checks_timeout_description": "Kullanılabilirlik kontrolleri için milisaniye cinsinden zaman aşımı", "machine_learning_clip_model": "CLIP modeli", "machine_learning_clip_model_description": "Link burada listelenen CLIP modelinin adı. Bu özelliği değiştirdikten sonra \"Akıllı Arama\" işini tüm fotoğraflar için tekrardan çalıştırmalısınız.", - "machine_learning_duplicate_detection": "Kopya fotoğraf tespiti", + "machine_learning_duplicate_detection": "Kopya Fotoğraf Tespiti", "machine_learning_duplicate_detection_enabled": "Kopya fotoğraf tespitini etkinleştir", "machine_learning_duplicate_detection_enabled_description": "Devre dışı bırakılırsa aynı öğeler yine de temizlenecek.", "machine_learning_duplicate_detection_setting_description": "Birbirinin kopyası olan varlıkları bulmak için CLIP kullan", @@ -133,9 +140,9 @@ "machine_learning_enabled_description": "Eğer devre dışı bırakılırsa bütün Makine Öğrenmesi özellikleri devre dışı bırakılacak.", "machine_learning_facial_recognition": "Yüz Tanıma", "machine_learning_facial_recognition_description": "Fotoğraflardaki yüzleri tara, tanı ve gruplandır", - "machine_learning_facial_recognition_model": "Yüz Tanıma Modeli", + "machine_learning_facial_recognition_model": "Yüz tanıma modeli", "machine_learning_facial_recognition_model_description": "Modeller, azalan boyut sırasına göre listelenmiştir. Daha büyük modeller daha yavaştır ve daha fazla bellek kullanır, ancak daha iyi sonuçlar üretir. Bir modeli değiştirdikten sonra tüm görüntüler için yüz algılama işini yeniden çalıştırmanız gerektiğini unutmayın.", - "machine_learning_facial_recognition_setting": "Yüz Tanımayı etkinleştir", + "machine_learning_facial_recognition_setting": "Yüz tanımayı etkinleştir", "machine_learning_facial_recognition_setting_description": "Devre dışı bırakıldığında fotoğraflar yüz tanıma için işlenmeyecek ve Keşfet sayfasındaki Kişiler sekmesini doldurmayacak.", "machine_learning_max_detection_distance": "Maksimum tespit uzaklığı", "machine_learning_max_detection_distance_description": "Resimleri birbirinin çifti saymak için hesap edilecek azami benzerlik ölçüsü, 0.001-0.1 aralığında. Daha yüksek değer daha hassas olup daha fazla çift tespit eder ancak çift olmayan resimleri birbirinin çifti sayabilir.", @@ -209,7 +216,7 @@ "notification_email_test_email_sent": "Test emaili {email} adresine yollandı. Lütfen gelen kutunuzu kontrol edin.", "notification_email_username_description": "Email sunucu doğrulamasında kullanılacak olan kullanıcı adı", "notification_enable_email_notifications": "Email bildirimlerini etkinleştir", - "notification_settings": "Bildirim ayarları", + "notification_settings": "Bildirim Ayarları", "notification_settings_description": "Email ve bildirim ayarlarını yönet", "oauth_auto_launch": "Otomatik başlat", "oauth_auto_launch_description": "Giriş sayfasına girildiğinde OAuth akışını otomatik olarak başlat", @@ -232,16 +239,16 @@ "oauth_storage_quota_claim_description": "Kullanıcıya depolama kotası koymak için kullanılacak değer (en: OAuth claim).", "oauth_storage_quota_default": "Varsayılan depolama kotası (GiB)", "oauth_storage_quota_default_description": "Değer (en: OAuth claim) mevcut değilse GiB cinsinden konulacak kota.", - "oauth_timeout": "İstek zaman aşımı", + "oauth_timeout": "İstek Zaman Aşımı", "oauth_timeout_description": "Milisaniye cinsinden istek zaman aşımı", "password_enable_description": "E-posta ve şifre ile giriş yapın", "password_settings": "Şifre ile Giriş", "password_settings_description": "Şifre giriş ayarlarını yönet", "paths_validated_successfully": "Tüm yollar başarıyla doğrulandı", "person_cleanup_job": "Kişi temizleme", - "quota_size_gib": "Kota boyutu (GiB)", + "quota_size_gib": "Kota Boyutu (GiB)", "refreshing_all_libraries": "Tüm kütüphaneler yenileniyor", - "registration": "Yönetici kaydı", + "registration": "Yönetici Kaydı", "registration_description": "Sistemdeki ilk kullanıcı olduğunuz için hesabınız Yönetici olarak ayarlandı. Yeni oluşturulan üyeliklerin, ve yönetici görevlerinin sorumlusu olarak atandınız.", "require_password_change_on_login": "Kullanıcının ilk girişinde şifre değiştirmesini zorunlu kıl", "reset_settings_to_default": "Ayarları varsayılana sıfırla", @@ -253,7 +260,7 @@ "server_external_domain_settings_description": "Paylaşılan fotoğraflar için domain, http(s):// dahil", "server_public_users": "Harici Kullanıcılar", "server_public_users_description": "Paylaşılan albümlere bir kullanıcı eklenirken tüm kullanıcılar (ad ve e-posta) listelenir. Devre dışı bırakıldığında, kullanıcı listesi yalnızca yönetici kullanıcılar tarafından kullanılabilir.", - "server_settings": "Sunucu ayarları", + "server_settings": "Sunucu Ayarları", "server_settings_description": "Sunucu ayarlarını yönet", "server_welcome_message": "Hoş geldin mesajı", "server_welcome_message_description": "Giriş sayfasında gösterilen mesaj.", @@ -289,7 +296,7 @@ "template_settings_description": "Bildirim şablonlarını yönet", "theme_custom_css_settings": "Özel CSS", "theme_custom_css_settings_description": "CSS (Cascading Style Sheets) kullanılarak Immich'in tasarımı değiştirilebilir.", - "theme_settings": "Tema ayarları", + "theme_settings": "Tema Ayarları", "theme_settings_description": "Immich web arayüzünün özelleştirilmesi ayarlarını yönet", "thumbnail_generation_job": "Önizlemeleri oluştur", "thumbnail_generation_job_description": "Her bir öğe için büyük, küçük ve bulanık küçük resimler ile her kişi için küçük resimler oluşturun", @@ -356,8 +363,8 @@ "trash_enabled_description": "Çöp özelliklerini etkinleştir", "trash_number_of_days": "Gün sayısı", "trash_number_of_days_description": "Öğeleri kalıcı olarak silmeden önce çöp kutusunda tutma süresi (gün)", - "trash_settings": "Çöp ayarları", - "trash_settings_description": "Çöp ayarlarını yönet", + "trash_settings": "Çöp Kutusu Ayarları", + "trash_settings_description": "Çöp kutusu ayarlarını yönet", "unlink_all_oauth_accounts": "Tüm OAuth hesaplarının bağlantısını kaldır", "unlink_all_oauth_accounts_description": "Yeni bir sağlayıcıya geçmeden önce tüm OAuth hesaplarını kaldırılmayı unutmayın.", "unlink_all_oauth_accounts_prompt": "Tüm OAuth hesaplarını kaldırmak istediğinizden emin misiniz? Bu, her kullanıcı için OAuth kimliğini sıfırlar ve geri alınamaz.", @@ -374,7 +381,7 @@ "user_restore_description": "{user} kullanıcısı geri yüklenecek.", "user_restore_scheduled_removal": "Kullanıcıyı geri yükle - {date, date, long} tarihinde planlanan kaldırma", "user_settings": "Kullanıcı Ayarları", - "user_settings_description": "Kullanıcı Ayarlarını Yönet", + "user_settings_description": "Kullanıcı ayarlarını yönet", "user_successfully_removed": "Kullanıcı {email} başarıyla kaldırıldı.", "version_check_enabled_description": "Sürüm kontrolü etkin", "version_check_implications": "Sürüm kontrol özelliği, github.com ile periyodik iletişime dayanır", @@ -383,12 +390,10 @@ "video_conversion_job": "Videoları dönüştür", "video_conversion_job_description": "Tarayıcılar ve cihazlarla daha geniş uyumluluk için videoları dönüştür" }, - "admin_email": "Yönetici Emaili", + "admin_email": "Yönetici E-postası", "admin_password": "Yönetici Şifresi", "administration": "Yönetim", "advanced": "Gelişmiş", - "advanced_settings_beta_timeline_subtitle": "Yeni uygulama deneyimini deneyin", - "advanced_settings_beta_timeline_title": "Beta Zaman Çizelgesi", "advanced_settings_enable_alternate_media_filter_subtitle": "Eşzamanlama sırasında medyayı alternatif ölçütlere göre süzgeçten geçirmek için bu seçeneği kullanın. Uygulamanın tüm albümleri algılamasında sorun yaşıyorsanız yalnızca bu durumda deneyin.", "advanced_settings_enable_alternate_media_filter_title": "[DENEYSEL] Alternatif cihaz albüm eşzamanlama süzgeci kullanın", "advanced_settings_log_level_title": "Günlük düzeyi: {level}", @@ -425,6 +430,7 @@ "album_remove_user_confirmation": "{user} kullanıcısını kaldırmak istediğinize emin misiniz?", "album_search_not_found": "Aramanızla eşleşen albüm bulunamadı", "album_share_no_users": "Görünüşe göre bu albümü tüm kullanıcılarla paylaştınız veya paylaşacak herhangi bir başka kullanıcınız yok.", + "album_summary": "Albüm özeti", "album_updated": "Albüm güncellendi", "album_updated_setting_description": "Paylaşılan bir albüme yeni bir öğe eklendiğinde e-posta bildirimi alın", "album_user_left": "{album}den ayrıldınız", @@ -491,11 +497,13 @@ "asset_list_layout_sub_title": "Düzen", "asset_list_settings_subtitle": "Fotoğraf ızgara düzeni ayarları", "asset_list_settings_title": "Fotoğraf Izgarası", - "asset_offline": "Varlık Çevrim Dışı", + "asset_offline": "Öğe Çevrim Dışı", "asset_offline_description": "Bu harici öğe artık diskte bulunmuyor. Yardım için lütfen Immich yöneticinizle iletişime geçin.", "asset_restored_successfully": "Öğe başarıyla geri yüklendi", "asset_skipped": "Atlandı", "asset_skipped_in_trash": "Çöpte", + "asset_trashed": "Öğe çöpe atıldı", + "asset_troubleshoot": "Öğe Sorun Giderme", "asset_uploaded": "Yüklendi", "asset_uploading": "Yükleniyor…", "asset_viewer_settings_subtitle": "Galeri görüntüleyici ayarlarını düzenle", @@ -529,8 +537,10 @@ "autoplay_slideshow": "Otomatik slayt gösterisi", "back": "Geri", "back_close_deselect": "Geri, kapat veya seçimi kaldır", + "background_backup_running_error": "Arka plan yedekleme şu anda çalışıyor, manuel yedekleme başlatılamıyor", "background_location_permission": "Arka plan konum izni", "background_location_permission_content": "Arka planda çalışırken ağ değiştirmek için Immich'in *her zaman* tam konum erişimine sahip olması gerekir, böylece uygulama Wi-Fi ağının adını okuyabilir", + "background_options": "Arka Plan Seçenekleri", "backup": "Yedekle", "backup_album_selection_page_albums_device": "Cihazdaki albümler ({count})", "backup_album_selection_page_albums_tap": "Seçmek için dokunun, hariç tutmak için çift dokunun", @@ -538,6 +548,7 @@ "backup_album_selection_page_select_albums": "Albüm seç", "backup_album_selection_page_selection_info": "Seçim Bilgileri", "backup_album_selection_page_total_assets": "Toplam eşsiz öğeler", + "backup_albums_sync": "Yedekleme albümlerinin senkronizasyonu", "backup_all": "Tümü", "backup_background_service_backup_failed_message": "Yedekleme başarısız. Tekrar deneniyor…", "backup_background_service_connection_failed_message": "Sunucuya bağlanılamadı. Tekrar deneniyor…", @@ -654,6 +665,8 @@ "change_pin_code": "PIN kodunu değiştirin", "change_your_password": "Şifreni değiştir", "changed_visibility_successfully": "Görünürlük başarıyla değiştirildi", + "charging": "Şarj oluyor", + "charging_requirement_mobile_backup": "Arka plan yedekleme için cihazın şarjda olması gerekir", "check_corrupt_asset_backup": "Bozuk öğe yedeklemelerini kontrol et", "check_corrupt_asset_backup_button": "Kontrol et", "check_corrupt_asset_backup_description": "Bu kontrolü yalnızca Wi-Fi üzerinden ve tüm öğeler yedeklendikten sonra çalıştırın. İşlem birkaç dakika sürebilir.", @@ -740,6 +753,7 @@ "create_user": "Kullanıcı oluştur", "created": "Oluşturuldu", "created_at": "Oluşturuldu", + "creating_linked_albums": "Bağlantılı albümler oluşturuluyor...", "crop": "Kes", "curated_object_page_title": "Nesneler", "current_device": "Mevcut cihaz", @@ -889,7 +903,9 @@ "error": "Hata", "error_change_sort_album": "Albüm sıralama düzeni değiştirilemedi", "error_delete_face": "Öğeden yüz silme hatası", + "error_getting_places": "Konum bilgisi alınırken hata oluştu", "error_loading_image": "Resim yüklenirken hata oluştu", + "error_loading_partners": "Ortakları yükleme hatası: {error}", "error_saving_image": "Hata: {error}", "error_tag_face_bounding_box": "Yüz etiketleme hatası – sınırlayıcı kutu koordinatları alınamadı", "error_title": "Bir Hata Oluştu - Bir şeyler ters gitti", @@ -1054,6 +1070,7 @@ "favorites_page_no_favorites": "Favori öğe bulunamadı", "feature_photo_updated": "Öne çıkan fotoğraf güncellendi", "features": "Özellikler", + "features_in_development": "Geliştirme Aşamasındaki Özellikler", "features_setting_description": "Uygulamanın özelliklerini yönet", "file_name": "Dosya adı", "file_name_or_extension": "Dosya adı veya uzantı", @@ -1093,14 +1110,14 @@ "haptic_feedback_switch": "Dokunsal geri bildirimi aç", "haptic_feedback_title": "Dokunsal Geri Bildirim (Haptic Feedback)", "has_quota": "Kota var", - "hash_asset": "Hash varlığı", - "hashed_assets": "Hashlenmiş varlıklar", + "hash_asset": "Karma öğe", + "hashed_assets": "Karma öğeler", "hashing": "Hashleme", "header_settings_add_header_tip": "Header Ekle", "header_settings_field_validator_msg": "Değer boş olamaz", "header_settings_header_name_input": "Header adı", "header_settings_header_value_input": "Header değeri", - "headers_settings_tile_subtitle": "Uygulamanın her ağ isteğiyle birlikte göndermesi gereken proxy header'ları tanımlayın", + "headers_settings_tile_subtitle": "Uygulamanın her ağ isteğinde göndermesi gereken proxy başlıklarını tanımlayın", "headers_settings_tile_title": "Özel proxy headers", "hi_user": "Merhaba {name} {email}", "hide_all_people": "Tüm kişileri gizle", @@ -1112,11 +1129,11 @@ "home_page_add_to_album_conflicts": "{album} albümüne {added} öğe eklendi. {failed} öğe zaten albümdeydi.", "home_page_add_to_album_err_local": "Yerel öğeler henüz albümlere eklenemiyor, atlanıyor", "home_page_add_to_album_success": "{album} albümüne {added} öğe eklendi.", - "home_page_album_err_partner": "Partner öğeler henüz bir albüme eklenemiyor, atlanıyor", + "home_page_album_err_partner": "Ortak öğeler henüz bir albüme eklenemiyor, atlanıyor", "home_page_archive_err_local": "Yerel öğeler henüz arşivlenemiyor, atlanıyor", - "home_page_archive_err_partner": "Partner öğeler henüz arşivlenemiyor, atlanıyor", + "home_page_archive_err_partner": "Ortak öğeler henüz arşivlenemiyor, atlanıyor", "home_page_building_timeline": "Zaman çizelgesi oluşturuluyor", - "home_page_delete_err_partner": "Partner öğeler silinemez, atlanıyor", + "home_page_delete_err_partner": "Ortak öğeler silinemez, atlanıyor", "home_page_delete_remote_err_local": "Uzaktan silme seçimindeki yerel öğeler atlanıyor", "home_page_favorite_err_local": "Yerel öğeler henüz favorilere eklenemiyor, atlanıyor", "home_page_favorite_err_partner": "Ortak öğeler henüz favorilere eklenemiyor, atlanıyor", @@ -1218,7 +1235,8 @@ "local": "Yerel", "local_asset_cast_failed": "Sunucuya yüklenmemiş bir öğe yansıtılamaz", "local_assets": "Yerel Öğeler", - "local_network": "Yerel Wi-Fi", + "local_media_summary": "Yerel Medya Özeti", + "local_network": "Yerel ağ", "local_network_sheet_info": "Uygulama belirlenmiş Wi-Fi ağını kullanırken bu URL üzerinden sunucuya bağlanacaktır", "location_permission": "Konum izni", "location_permission_content": "Otomatik geçiş özelliğinin çalışabilmesi için Immich'in mevcut Wi-Fi ağının adını bilmesi, bunu sağlamak için de tam konum iznine ihtiyacı vardır", @@ -1229,6 +1247,7 @@ "location_picker_longitude_hint": "Buraya boylam yazın", "lock": "Kilitle", "locked_folder": "Kilitli Klasör", + "log_detail_title": "Günlük Ayrıntıları", "log_out": "Oturumu kapat", "log_out_all_devices": "Tüm Cihazlarda Oturumu Kapat", "logged_in_as": "{user} olarak oturum açıldı", @@ -1259,6 +1278,7 @@ "login_password_changed_success": "Şifre başarıyla güncellendi", "logout_all_device_confirmation": "Tüm cihazlarda oturum kapatmak istediğinizden emin misiniz?", "logout_this_device_confirmation": "Bu cihazda oturum kapatmak istediğinizden emin misiniz?", + "logs": "Kayıtlar", "longitude": "Boylam", "look": "Görünüm", "loop_videos": "Videoları döngüye al", @@ -1293,7 +1313,7 @@ "map_settings_date_range_option_years": "Son {years} yıl", "map_settings_dialog_title": "Harita Ayarları", "map_settings_include_show_archived": "Arşivdekileri dahil et", - "map_settings_include_show_partners": "Partnerleri Dahil Et", + "map_settings_include_show_partners": "Ortakları Dahil Et", "map_settings_only_show_favorites": "Sadece Favorileri Göster", "map_settings_theme_settings": "Harita Teması", "map_zoom_to_see_photos": "Fotoğrafları görmek için uzaklaştırın", @@ -1301,6 +1321,7 @@ "mark_as_read": "Okundu olarak işaretle", "marked_all_as_read": "Tümü okundu olarak işaretlendi", "matches": "Eşleşenler", + "matching_assets": "Eşleşen Öğeler", "media_type": "Medya türü", "memories": "Anılar", "memories_all_caught_up": "Tümü görüldü", @@ -1341,6 +1362,7 @@ "name_or_nickname": "İsim veya takma isim", "network_requirement_photos_upload": "Fotoğrafları yedeklemek için mobil veriyi kullan", "network_requirement_videos_upload": "Videoları yedeklemek için mobil veriyi kullan", + "network_requirements": "Ağ Gereksinimleri", "network_requirements_updated": "Ağ durumu değişti, yedekleme kuyruğu sıfırlandı", "networking_settings": "Ağ Ayarları", "networking_subtitle": "Sunucu uç nokta ayarlarını düzenle", @@ -1351,6 +1373,7 @@ "new_person": "Yeni kişi", "new_pin_code": "Yeni PIN kodu", "new_pin_code_subtitle": "Kilitli klasöre ilk kez erişiyorsunuz. Bu sayfaya güvenli erişim için bir PIN kodu oluşturun", + "new_timeline": "Yeni Zaman Çizelgesi", "new_user_created": "Yeni kullanıcı oluşturuldu", "new_version_available": "YENİ SÜRÜM MEVCUT", "newest_first": "Önce en yeniler", @@ -1364,20 +1387,25 @@ "no_assets_message": "İLK FOTOĞRAFINIZI YÜKLEMEK İÇİN TIKLAYIN", "no_assets_to_show": "Gösterilecek öğe yok", "no_cast_devices_found": "Yansıtılacak cihaz bulunamadı", + "no_checksum_local": "Sağlama toplamı mevcut değil - yerel varlıkları alamıyor", + "no_checksum_remote": "Sağlama toplamı mevcut değil - uzak varlık alınamıyor", "no_duplicates_found": "Çift bulunamadı.", "no_exif_info_available": "EXIF bilgisi mevcut değil", "no_explore_results_message": "Koleksiyonunuzu keşfetmek için daha fazla fotoğraf yükleyin.", "no_favorites_message": "En sevdiğiniz fotoğraf ve videoları hızlıca bulmak için favorilere ekleyin", "no_libraries_message": "Fotoğraf ve videolarınızı görmek için bir harici kütüphane oluşturun", + "no_local_assets_found": "Bu sağlama toplamı ile yerel varlık bulunamadı", "no_locked_photos_message": "Kilitli klasördeki fotoğraf ve videolar gizlidir; kitaplığınızda gezinirken veya arama yaparken görünmezler.", "no_name": "İsim yok", "no_notifications": "Bildirim yok", "no_people_found": "Eşleşen kişi bulunamadı", "no_places": "Yer yok", + "no_remote_assets_found": "Bu sağlama toplamı ile uzaktaki varlık bulunamadı", "no_results": "Sonuç bulunamadı", "no_results_description": "Eş anlamlı ya da daha genel anlamlı bir kelime deneyin", "no_shared_albums_message": "Fotoğrafları ve videoları ağınızdaki kişilerle paylaşmak için bir albüm oluşturun", "no_uploads_in_progress": "Yükleme işlemi yok", + "not_available": "YOK", "not_in_any_album": "Hiçbir albümde değil", "not_selected": "Seçilmedi", "note_apply_storage_label_to_previously_uploaded assets": "Not: Daha önce yüklenen öğeler için bir depolama yolu etiketi uygulamak üzere şunu başlatın", @@ -1428,13 +1456,13 @@ "partner_can_access_location": "Fotoğraf ve videolarınızın çekildiği konum", "partner_list_user_photos": "{user} fotoğrafları", "partner_list_view_all": "Tümünü gör", - "partner_page_empty_message": "Fotoğraflarınız henüz hiçbir partnerle paylaşılmadı.", + "partner_page_empty_message": "Fotoğraflarınız henüz hiçbir ortakla paylaşılmadı.", "partner_page_no_more_users": "Eklenecek başka kullanıcı yok", - "partner_page_partner_add_failed": "Partner eklenemedi", - "partner_page_select_partner": "Partner seç", + "partner_page_partner_add_failed": "Ortak eklenemedi", + "partner_page_select_partner": "Ortak seç", "partner_page_shared_to_title": "Paylaşıldı", "partner_page_stop_sharing_content": "{partner} artık fotoğraflarınıza erişemeyecek.", - "partner_sharing": "Ortak paylaşımı", + "partner_sharing": "Ortak Paylaşımı", "partners": "Ortaklar", "password": "Şifre", "password_does_not_match": "Şifre eşleşmiyor", @@ -1493,12 +1521,13 @@ "places_count": "{count, plural, one {{count, number} yer} other {{count, number} yer}}", "play": "Oynat", "play_memories": "Anıları oynat", - "play_motion_photo": "Hareketli fotoğrafı oynat", + "play_motion_photo": "Hareketli Fotoğrafı Oynat", "play_or_pause_video": "Videoyu oynat ya da durdur", "please_auth_to_access": "Erişim için lütfen kimliğinizi doğrulayın", "port": "Port", "preferences_settings_subtitle": "Uygulama tercihlerini düzenle", "preferences_settings_title": "Tercihler", + "preparing": "Hazırlanıyor", "preset": "Ön ayar", "preview": "Önizleme", "previous": "Önceki", @@ -1564,6 +1593,7 @@ "read_changelog": "Değişiklik günlüğünü oku", "readonly_mode_disabled": "Salt okunur mod devre dışı", "readonly_mode_enabled": "Salt okunur mod etkin", + "ready_for_upload": "Yüklemeye hazır", "reassign": "Yeniden ata", "reassigned_assets_to_existing_person": "{count, plural, one {# öğe} other {# öğeler}} {name, select, null {mevcut bir kişiye} other {{name}}} atandı", "reassigned_assets_to_new_person": "{count, plural, one {# öğe} other {# öğeler}} yeni bir kişiye atandı", @@ -1588,6 +1618,7 @@ "regenerating_thumbnails": "Küçük resimler yeniden oluşturuluyor", "remote": "Uzaktan", "remote_assets": "Uzak Öğeler", + "remote_media_summary": "Uzaktan Medya Özeti", "remove": "Kaldır", "remove_assets_album_confirmation": "{count, plural, one {# öğeyi} other {# öğeleri}} albümden çıkarmak istediğinizden emin misiniz?", "remove_assets_shared_link_confirmation": "{count, plural, one {# öğeyi} other {# öğeleri}} bu paylaşılan bağlantıdan çıkarmak istediğinizden emin misiniz?", @@ -1754,7 +1785,7 @@ "set_slideshow_to_fullscreen": "Slayt gösterisini tam ekran yap", "set_stack_primary_asset": "Birincil öğe olarak ayarla", "setting_image_viewer_help": "Görüntüleyici önce küçük resmi gösterir, ardından orta boy önizlemeyi (etkinleştirilmişse) ve son olarak orijinali (etkinleştirilmişse) gösterir.", - "setting_image_viewer_original_subtitle": "Orijinal tam çözünürlüklü görüntüyü göstermek için etkinleştirin. Veri kullanımını azaltmak için devre dışı bırakın (hem ağ hem de cihaz önbelleği).", + "setting_image_viewer_original_subtitle": "Orijinal tam çözünürlüklü görüntüyü (büyük!) yüklemek için etkinleştirin. Veri kullanımını azaltmak için devre dışı bırakın (hem ağ hem de cihaz önbelleği).", "setting_image_viewer_original_title": "Orijinal görüntüyü göster", "setting_image_viewer_preview_subtitle": "Orta çözünürlüklü bir görüntü göstermek için etkinleştirin. Orijinali doğrudan göstermek veya yalnızca küçük resmi kullanmak için devre dışı bırakın.", "setting_image_viewer_preview_title": "Önizleme görüntüsü göster", @@ -1841,7 +1872,7 @@ "sharing_page_empty_list": "LİSTEYİ BOŞALT", "sharing_sidebar_description": "Yan panelde paylaşılanlara kısa yol göster", "sharing_silver_appbar_create_shared_album": "Yeni paylaşılan albüm", - "sharing_silver_appbar_share_partner": "Partnerle paylaş", + "sharing_silver_appbar_share_partner": "Ortakla paylaş", "shift_to_permanent_delete": "Öğeyi kalıcı olarak silmek için ⇧ tuşuna basın", "show_album_options": "Albüm ayarlarını göster", "show_albums": "Albümleri göster", @@ -1863,6 +1894,7 @@ "show_slideshow_transition": "Slayt geçişini göster", "show_supporter_badge": "Destekçi rozeti", "show_supporter_badge_description": "Destekçi rozetini göster", + "show_text_search_menu": "Metin arama menüsünü göster", "shuffle": "Karıştır", "sidebar": "Yan panel", "sidebar_display_description": "Yan panelde görünüme kısa yol göster", @@ -1893,6 +1925,7 @@ "stacktrace": "Yığın izi", "start": "Başlat", "start_date": "Başlangıç tarihi", + "start_date_before_end_date": "Başlangıç tarihi bitiş tarihinden önce olmalıdır", "state": "Eyalet/İl", "status": "Durum", "stop_casting": "Yansıtmayı durdur", @@ -1945,7 +1978,7 @@ "theme_setting_system_primary_color_title": "Sistem rengini kullan", "theme_setting_system_theme_switch": "Otomatik (sistem ayarına göre)", "theme_setting_theme_subtitle": "Uygulama teması seç", - "theme_setting_three_stage_loading_subtitle": "Üç aşamalı yükleme, yükleme performansını artırabilir ancak önemli ölçüde daha yüksek ağ yüküne sebep olur", + "theme_setting_three_stage_loading_subtitle": "Üç aşamalı yükleme, yükleme performansını artırabilir ancak ağ yükünü önemli ölçüde artırır", "theme_setting_three_stage_loading_title": "Üç aşamalı yüklemeyi etkinleştir", "they_will_be_merged_together": "Birlikte birleştirilecekler", "third_party_resources": "Üçüncü taraf kaynaklar", @@ -1974,7 +2007,7 @@ "trash_page_empty_trash_dialog_content": "Çöp kutusuna atılmış öğeleri silmek istediğinize emin misiniz? Bu öğeler Immich'ten kalıcı olarak silinecek", "trash_page_info": "Çöp kutusuna atılan öğeler {days} gün sonra kalıcı olarak silinecektir", "trash_page_no_assets": "Çöp kutusuna atılmış öğe yok", - "trash_page_restore_all": "Tümünü geri yükle", + "trash_page_restore_all": "Tümünü Geri Yükle", "trash_page_select_assets_btn": "Öğeleri seç", "trash_page_title": "Çöp Kutusu ({count})", "trashed_items_will_be_permanently_deleted_after": "Silinen öğeler {days, plural, one {# gün} other {# gün}} sonra kalıcı olarak silinecek.", @@ -1990,16 +2023,16 @@ "unfavorite_action_prompt": "{count} Favorilerden kaldırıldı", "unhide_person": "Kişiyi göster", "unknown": "Bilinmeyen", - "unknown_country": "Bilinmeyen ülke", - "unknown_year": "Bilinmeyen YIl", + "unknown_country": "Bilinmeyen Ülke", + "unknown_year": "Bilinmeyen Yıl", "unlimited": "Sınırsız", "unlink_motion_video": "Hareketli video bağlantısını kaldır", "unlink_oauth": "OAuth bağlantısını kaldır", "unlinked_oauth_account": "Bağlantısı kaldırılmış OAuth hesabı", - "unmute_memories": "Anıların sesini aç", + "unmute_memories": "Anıların Sesini Aç", "unnamed_album": "İsimsiz Albüm", "unnamed_album_delete_confirmation": "Bu albümü silmek istediğinizden emin misiniz?", - "unnamed_share": "İsimsiz paylaşım", + "unnamed_share": "İsimsiz Paylaşım", "unsaved_change": "Kaydedilmemiş değişiklik", "unselect_all": "Tümünü seçimini kaldır", "unselect_all_duplicates": "Tüm çiftlerin seçimini kaldır", @@ -2046,11 +2079,11 @@ "user_role_set": "{user}, {role} olarak ayarlandı", "user_usage_detail": "Kullanıcı kullanım detayı", "user_usage_stats": "Hesap kullanım istatistikleri", - "user_usage_stats_description": "hesap kullanım istatistiklerini göster", + "user_usage_stats_description": "Hesap kullanım istatistiklerini göster", "username": "Kullanıcı adı", "users": "Kullanıcılar", "users_added_to_album_count": "Albüme {count, plural, one {# user} other {# users}} eklendi", - "utilities": "Yardımcılar", + "utilities": "Yardımcı Programlar", "validate": "Doğrula", "validate_endpoint_error": "Lütfen geçerli bir URL girin", "variables": "Değişkenler", @@ -2060,7 +2093,7 @@ "version_history": "Sürüm Geçmişi", "version_history_item": "{version}, {date} tarihinde kuruldu", "video": "Video", - "video_hover_setting": "Üzerinde durulduğunda video önizlemesi oynat", + "video_hover_setting": "Üzerinde durulduğunda video ön izlemesi oynat", "video_hover_setting_description": "Öğe üzerinde fareyle durulduğunda video küçük resmini oynatır. Bu özellik devre dışıyken, oynatma simgesine fareyle gidilerek oynatma başlatılabilir.", "videos": "Videolar", "videos_count": "{count, plural, one {# video} other {# video}}", @@ -2095,5 +2128,6 @@ "yes": "Evet", "you_dont_have_any_shared_links": "Herhangi bir paylaşılan bağlantınız yok", "your_wifi_name": "Wi-Fi Adınız", - "zoom_image": "Görüntüyü yakınlaştır" + "zoom_image": "Görüntüyü yakınlaştır", + "zoom_to_bounds": "Sınırlara yakınlaştır" } diff --git a/i18n/uk.json b/i18n/uk.json index c87ef4b752..a664fc9aa0 100644 --- a/i18n/uk.json +++ b/i18n/uk.json @@ -28,6 +28,7 @@ "add_to_album": "Додати у альбом", "add_to_album_bottom_sheet_added": "Додано до {album}", "add_to_album_bottom_sheet_already_exists": "Вже є в {album}", + "add_to_album_bottom_sheet_some_local_assets": "Деякі локальні ресурси не вдалося додати до альбому", "add_to_album_toggle": "Перемикання вибору для {album}", "add_to_albums": "Додати до альбомів", "add_to_albums_count": "Додати до альбомів ({count})", @@ -123,6 +124,13 @@ "logging_enable_description": "Увімкнути ведення журналу", "logging_level_description": "Коли увімкнено, який рівень журналювання використовувати.", "logging_settings": "Журналювання", + "machine_learning_availability_checks": "Перевірки доступності", + "machine_learning_availability_checks_description": "Автоматично виявляти та надавати перевагу доступним серверам машинного навчання", + "machine_learning_availability_checks_enabled": "Увімкнути перевірки доступності", + "machine_learning_availability_checks_interval": "Інтервал перевірки", + "machine_learning_availability_checks_interval_description": "Інтервал у мілісекундах між перевірками доступності", + "machine_learning_availability_checks_timeout": "Тайм-аут запиту", + "machine_learning_availability_checks_timeout_description": "Тайм-аут у мілісекундах для перевірки доступності", "machine_learning_clip_model": "Модель CLIP", "machine_learning_clip_model_description": "Ім'я однієї з моделей CLIP, яка перерахована тут. Зауважте, що потрібно знову запустити завдання «Розумний пошук» для всіх зображень після зміни моделі.", "machine_learning_duplicate_detection": "Виявлення дублікатів", @@ -258,7 +266,7 @@ "server_welcome_message": "Вітальне повідомлення", "server_welcome_message_description": "Повідомлення, яке відображається на сторінці входу.", "sidecar_job": "Метадані з sidecar-файлів", - "sidecar_job_description": "Виявлення або синхронізація метаданих додатків з файлової системи", + "sidecar_job_description": "Пошук або синхронізація сайдкар-метаданих з файлової системи", "slideshow_duration_description": "Кількість секунд для відображення кожного зображення", "smart_search_job_description": "Запуск машинного навчання для ресурсів для підтримки розумного пошуку", "storage_template_date_time_description": "Позначка часу створення ресурсу використовується для інформації про дату й час", @@ -340,7 +348,7 @@ "transcoding_settings": "Налаштування транскодування відео", "transcoding_settings_description": "Керування які відео транскодувати і як їх обробляти", "transcoding_target_resolution": "Роздільна здатність", - "transcoding_target_resolution_description": "Вищі роздільні здатності можуть зберігати більше деталей, але займають більше часу на кодування, мають більші розміри файлів і можуть зменшити швидкість роботи додатку.", + "transcoding_target_resolution_description": "Вищі роздільні здатності можуть зберігати більше деталей, але займають більше часу на кодування, мають більші розміри файлів і можуть зменшити швидкість роботи застосунку.", "transcoding_temporal_aq": "Тимчасове AQ", "transcoding_temporal_aq_description": "Це застосовується лише до NVENC. Підвищує якість сцен з великою деталізацією та низьким рухом. Може бути несумісним зі старими пристроями.", "transcoding_threads": "Потоки", @@ -387,8 +395,6 @@ "admin_password": "Пароль адміністратора", "administration": "Адміністрування", "advanced": "Розширені", - "advanced_settings_beta_timeline_subtitle": "Випробуйте новий інтерфейс застосунку", - "advanced_settings_beta_timeline_title": "Бета-версія стрічки", "advanced_settings_enable_alternate_media_filter_subtitle": "Використовуйте цей варіант для фільтрації медіафайлів під час синхронізації за альтернативними критеріями. Спробуйте це, якщо у вас виникають проблеми з тим, що застосунок не виявляє всі альбоми.", "advanced_settings_enable_alternate_media_filter_title": "[ЕКСПЕРИМЕНТАЛЬНИЙ] Використовуйте альтернативний фільтр синхронізації альбомів пристрою", "advanced_settings_log_level_title": "Рівень логування: {level}", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "Ви впевнені, що хочете видалити {user}?", "album_search_not_found": "Альбомів, що відповідають вашому запиту, не знайдено", "album_share_no_users": "Схоже, ви поділилися цим альбомом з усіма користувачами або у вас немає жодного користувача, з яким можна було б поділитися.", + "album_summary": "Короткий опис альбому", "album_updated": "Альбом оновлено", "album_updated_setting_description": "Отримуйте сповіщення на електронну пошту, коли у спільному альбомі з'являються нові ресурси", "album_user_left": "Ви покинули {album}", @@ -496,6 +503,8 @@ "asset_restored_successfully": "Елемент успішно відновлено", "asset_skipped": "Пропущено", "asset_skipped_in_trash": "У кошику", + "asset_trashed": "Об'єкт видалено з кошика", + "asset_troubleshoot": "Вирішення проблем з активами", "asset_uploaded": "Завантажено", "asset_uploading": "Завантаження…", "asset_viewer_settings_subtitle": "Керуйте налаштуваннями переглядача галереї", @@ -529,8 +538,10 @@ "autoplay_slideshow": "Автоматичне відтворення слайдшоу", "back": "Назад", "back_close_deselect": "Повернутися, закрити або скасувати вибір", + "background_backup_running_error": "Наразі виконується фонове резервне копіювання, неможливо розпочати резервне копіювання вручну", "background_location_permission": "Дозвіл до місцезнаходження у фоні", "background_location_permission_content": "Щоб перемикати мережі у фоновому режимі, Immich має *завжди* мати доступ до точної геолокації, щоб зчитувати назву Wi-Fi мережі", + "background_options": "Параметри фону", "backup": "Резервне копіювання", "backup_album_selection_page_albums_device": "Альбоми на пристрої ({count})", "backup_album_selection_page_albums_tap": "Торкніться, щоб включити, двічі, щоб виключити", @@ -538,6 +549,7 @@ "backup_album_selection_page_select_albums": "Оберіть альбоми", "backup_album_selection_page_selection_info": "Інформація про обране", "backup_album_selection_page_total_assets": "Загальна кількість унікальних елементів", + "backup_albums_sync": "Синхронізація резервних копій альбомів", "backup_all": "Усі", "backup_background_service_backup_failed_message": "Не вдалося зробити резервну копію елементів. Повторюю…", "backup_background_service_connection_failed_message": "Не вдалося зв'язатися із сервером. Повторюю…", @@ -587,6 +599,7 @@ "backup_controller_page_turn_on": "Увімкнути резервне копіювання в активному режимі", "backup_controller_page_uploading_file_info": "Завантажую інформацію про файл", "backup_err_only_album": "Не можу видалити єдиний альбом", + "backup_error_sync_failed": "Помилка синхронізації. Не вдається обробити резервну копію.", "backup_info_card_assets": "елементи", "backup_manual_cancelled": "Скасовано", "backup_manual_in_progress": "Завантаження вже відбувається. Спробуйте згодом", @@ -654,6 +667,8 @@ "change_pin_code": "Змінити PIN-код", "change_your_password": "Змініть свій пароль", "changed_visibility_successfully": "Видимість успішно змінено", + "charging": "Зарядка", + "charging_requirement_mobile_backup": "Для фонового резервного копіювання пристрій повинен заряджатися", "check_corrupt_asset_backup": "Перевірити на пошкоджені резервні копії ресурсів", "check_corrupt_asset_backup_button": "Виконати перевірку", "check_corrupt_asset_backup_description": "Запустити цю перевірку лише через Wi-Fi та після того, як всі ресурси будуть завантажені на сервер. Процес може зайняти кілька хвилин.", @@ -740,6 +755,7 @@ "create_user": "Створити користувача", "created": "Створено", "created_at": "Створено", + "creating_linked_albums": "Створення пов’язаних альбомів...", "crop": "Кадрувати", "curated_object_page_title": "Речі", "current_device": "Поточний пристрій", @@ -889,7 +905,9 @@ "error": "Помилка", "error_change_sort_album": "Не вдалося змінити порядок сортування альбому", "error_delete_face": "Помилка при видаленні обличчя з елементу", + "error_getting_places": "Помилка отримання місць", "error_loading_image": "Помилка завантаження зображення", + "error_loading_partners": "Помилка завантаження партнерів: {error}", "error_saving_image": "Помилка: {error}", "error_tag_face_bounding_box": "Помилка під час позначення обличчя – не вдалося отримати координати рамки", "error_title": "Помилка: щось пішло не так", @@ -1054,7 +1072,8 @@ "favorites_page_no_favorites": "Немає улюблених елементів", "feature_photo_updated": "Вибране фото оновлено", "features": "Додаткові можливості", - "features_setting_description": "Керування додатковими можливостями додатка", + "features_in_development": "Функції в розробці", + "features_setting_description": "Керування додатковими можливостями застосунку", "file_name": "Ім'я файлу", "file_name_or_extension": "Ім'я файлу або розширення", "filename": "Ім'я файлу", @@ -1120,7 +1139,7 @@ "home_page_delete_remote_err_local": "Локальні елемент(и) вже в процесі видалення з сервера, пропущено", "home_page_favorite_err_local": "Поки що не можна додати до улюблених локальні елементи, пропущено", "home_page_favorite_err_partner": "Поки що не можна додати до улюблених елементи партнера, пропущено", - "home_page_first_time_notice": "Якщо ви користуєтеся додатком вперше, будь ласка, оберіть альбом для резервного копіювання, щоб на шкалі часу з’явилися фото та відео", + "home_page_first_time_notice": "Якщо ви користуєтеся застосунком вперше, будь ласка, оберіть альбом для резервного копіювання, щоб на шкалі часу з’явилися фото та відео", "home_page_locked_error_local": "Не вдається перемістити локальні файли до особистої папки, пропускається", "home_page_locked_error_partner": "Не вдається перемістити партнерські файли до особистої папки, пропускається", "home_page_share_err_local": "Неможливо поділитися локальними елементами через посилання, пропущено", @@ -1218,6 +1237,7 @@ "local": "На пристрої", "local_asset_cast_failed": "Неможливо транслювати ресурс, який не завантажено на сервер", "local_assets": "Локальні фото та відео", + "local_media_summary": "Зведення місцевих ЗМІ", "local_network": "Локальна мережа", "local_network_sheet_info": "Застосунок підключатиметься до сервера через цей URL, коли використовується вказана Wi-Fi мережа", "location_permission": "Дозвіл до місцезнаходження", @@ -1229,6 +1249,7 @@ "location_picker_longitude_hint": "Вкажіть довготу", "lock": "Заблокувати", "locked_folder": "Особиста папка", + "log_detail_title": "Деталі журналу", "log_out": "Вийти", "log_out_all_devices": "Вийти з усіх пристроїв", "logged_in_as": "Вхід виконано як {user}", @@ -1259,6 +1280,7 @@ "login_password_changed_success": "Пароль оновлено успішно", "logout_all_device_confirmation": "Ви впевнені, що хочете вийти з усіх пристроїв?", "logout_this_device_confirmation": "Ви впевнені, що хочете вийти з цього пристрою?", + "logs": "Журнали", "longitude": "Довгота", "look": "Дивитися", "loop_videos": "Циклічні відео", @@ -1301,6 +1323,7 @@ "mark_as_read": "Позначити як прочитане", "marked_all_as_read": "Позначено всі як прочитані", "matches": "Збіги", + "matching_assets": "Відповідні активи", "media_type": "Тип медіа", "memories": "Спогади", "memories_all_caught_up": "Це все на сьогодні", @@ -1341,6 +1364,7 @@ "name_or_nickname": "Ім'я або псевдонім", "network_requirement_photos_upload": "Використовувати стільникові дані для резервного копіювання фото", "network_requirement_videos_upload": "Використовувати стільникові дані для резервного копіювання відео", + "network_requirements": "Вимоги до мережі", "network_requirements_updated": "Вимоги до мережі змінилися, черга резервного копіювання очищена", "networking_settings": "Мережеві налаштування", "networking_subtitle": "Керування налаштуваннями кінцевої точки сервера", @@ -1351,6 +1375,7 @@ "new_person": "Нова людина", "new_pin_code": "Новий PIN-код", "new_pin_code_subtitle": "Ви вперше отримуєте доступ до особистої папки. Створіть PIN-код для безпечного доступу до цієї сторінки", + "new_timeline": "Нова хронологія", "new_user_created": "Створено нового користувача", "new_version_available": "ДОСТУПНА НОВА ВЕРСІЯ", "newest_first": "Спочатку нові", @@ -1364,20 +1389,25 @@ "no_assets_message": "НАТИСНІТЬ, ЩОБ ЗАВАНТАЖИТИ ВАШЕ ПЕРШЕ ФОТО", "no_assets_to_show": "Елементи відсутні", "no_cast_devices_found": "Пристрої для трансляції не знайдено", + "no_checksum_local": "Контрольна сума недоступна – неможливо отримати локальні ресурси", + "no_checksum_remote": "Контрольна сума недоступна – неможливо отримати віддалений ресурс", "no_duplicates_found": "Дублікатів не виявлено.", "no_exif_info_available": "Відсутня інформація про exif", "no_explore_results_message": "Завантажуйте більше фотографій, щоб насолоджуватися вашою колекцією.", "no_favorites_message": "Додавайте улюблені файли, щоб швидко знаходити ваші найкращі зображення та відео", "no_libraries_message": "Створіть зовнішню бібліотеку для перегляду фотографій і відео", + "no_local_assets_found": "З цією контрольною сумою не знайдено локальних ресурсів", "no_locked_photos_message": "Фото та відео в особистій папці приховані і не відображаються під час перегляду чи пошуку у вашій бібліотеці.", "no_name": "Без імені", "no_notifications": "Немає сповіщень", "no_people_found": "Людей, що відповідають запиту, не знайдено", "no_places": "Місць немає", + "no_remote_assets_found": "З цією контрольною сумою не знайдено віддалених ресурсів", "no_results": "Немає результатів", "no_results_description": "Спробуйте використовувати синонім або більш загальне ключове слово", "no_shared_albums_message": "Створіть альбом, щоб ділитися фотографіями та відео з людьми у вашій мережі", "no_uploads_in_progress": "Немає активних завантажень", + "not_available": "Немає даних", "not_in_any_album": "У жодному альбомі", "not_selected": "Не вибрано", "note_apply_storage_label_to_previously_uploaded assets": "Примітка: Щоб застосувати мітку сховища до раніше завантажених ресурсів, виконайте команду", @@ -1471,7 +1501,7 @@ "permission_onboarding_permission_denied": "Доступ заборонено. Для використання Immich надайте дозволи до \"Фото та відео\" в налаштуваннях.", "permission_onboarding_permission_granted": "Доступ надано! Все готово.", "permission_onboarding_permission_limited": "Доступ обмежено. Щоби дозволити Immich створювати резервні копії та керувати всією галереєю, надайте дозволи на фото й відео в налаштуваннях.", - "permission_onboarding_request": "Додатку Immich потрібен дозвіл для перегляду ваших фото та відео.", + "permission_onboarding_request": "Застосунку Immich потрібен дозвіл для перегляду ваших фото та відео.", "person": "Людина", "person_age_months": "{months, plural, one {# місяць} other {# місяці}}", "person_age_year_months": "1 year , {months, plural, one {# місяць} other {# місяці}}", @@ -1497,8 +1527,9 @@ "play_or_pause_video": "Відтворення або призупинення відео", "please_auth_to_access": "Будь ласка, пройдіть автентифікацію", "port": "Порт", - "preferences_settings_subtitle": "Керування налаштуваннями додатку", + "preferences_settings_subtitle": "Керування налаштуваннями застосунку", "preferences_settings_title": "Параметри", + "preparing": "Підготовка", "preset": "Передвстановлення", "preview": "Прев'ю", "previous": "Попереднє", @@ -1564,6 +1595,7 @@ "read_changelog": "Прочитати зміни в оновленні", "readonly_mode_disabled": "Режим лише для читання вимкнено", "readonly_mode_enabled": "Режим лише для читання ввімкнено", + "ready_for_upload": "Готово до завантаження", "reassign": "Перепризначити", "reassigned_assets_to_existing_person": "Перепризначено {count, plural, one {# ресурс} few {# ресурси} many {# ресурсів} other {# ресурсів}} {name, select, null {існуючій особі} other {{name}}}", "reassigned_assets_to_new_person": "Перепризначено {count, plural, one {# ресурс} other {# ресурси}} новій особі", @@ -1588,6 +1620,7 @@ "regenerating_thumbnails": "Відновлення мініатюр", "remote": "На сервері", "remote_assets": "Віддалені фото та відео", + "remote_media_summary": "Зведення віддалених медіафайлів", "remove": "Вилучити", "remove_assets_album_confirmation": "Ви впевнені, що хочете видалити {count, plural, one {# ресурс} few {# ресурси} many {# ресурсів} other {# ресурсів}} з альбому?", "remove_assets_shared_link_confirmation": "Ви впевнені, що хочете видалити {count, plural, one {# ресурс} few {# ресурси} many {# ресурсів} other {# ресурсів}} з цього спільного посилання?", @@ -1738,7 +1771,7 @@ "send_message": "Надіслати повідомлення", "send_welcome_email": "Надішліть вітальний лист", "server_endpoint": "Кінцева точка сервера", - "server_info_box_app_version": "Версія додатка", + "server_info_box_app_version": "Версія застосунку", "server_info_box_server_url": "URL сервера", "server_offline": "Сервер офлайн", "server_online": "Сервер онлайн", @@ -1760,7 +1793,7 @@ "setting_image_viewer_preview_title": "Завантажувати зображення попереднього перегляду", "setting_image_viewer_title": "Зображення", "setting_languages_apply": "Застосувати", - "setting_languages_subtitle": "Змінити мову додатку", + "setting_languages_subtitle": "Змінити мову застосунку", "setting_notifications_notify_failures_grace_period": "Повідомити про помилки фонового резервного копіювання: {duration}", "setting_notifications_notify_hours": "{count} годин", "setting_notifications_notify_immediately": "негайно", @@ -1863,6 +1896,7 @@ "show_slideshow_transition": "Показати перехід слайд-шоу", "show_supporter_badge": "Значок підтримки", "show_supporter_badge_description": "Показати значок підтримки", + "show_text_search_menu": "Показати меню текстового пошуку", "shuffle": "Перемішати", "sidebar": "Бічна панель", "sidebar_display_description": "Відобразити посилання на перегляд у бічній панелі", @@ -1893,6 +1927,7 @@ "stacktrace": "Стек викликів", "start": "Старт", "start_date": "Дата початку", + "start_date_before_end_date": "Дата початку має бути раніше дати завершення", "state": "Регіон", "status": "Стан", "stop_casting": "Зупинити трансляцію", @@ -1944,7 +1979,7 @@ "theme_setting_primary_color_title": "Основний колір", "theme_setting_system_primary_color_title": "Використовувати колір системи", "theme_setting_system_theme_switch": "Автоматично (як у системі)", - "theme_setting_theme_subtitle": "Налаштування теми додатка", + "theme_setting_theme_subtitle": "Налаштування теми застосунку", "theme_setting_three_stage_loading_subtitle": "Триетапне завантаження може підвищити продуктивність завантаження, але спричинить значно більше навантаження на мережу", "theme_setting_three_stage_loading_title": "Увімкнути триетапне завантаження", "they_will_be_merged_together": "Вони будуть об'єднані разом", @@ -2095,5 +2130,6 @@ "yes": "Так", "you_dont_have_any_shared_links": "У вас немає спільних посилань", "your_wifi_name": "Назва вашої Wi-Fi мережі", - "zoom_image": "Збільшити зображення" + "zoom_image": "Збільшити зображення", + "zoom_to_bounds": "Збільшити масштаб до меж" } diff --git a/i18n/vi.json b/i18n/vi.json index fe25f7dab8..b9ee8cfcc9 100644 --- a/i18n/vi.json +++ b/i18n/vi.json @@ -360,8 +360,6 @@ "admin_password": "Mật khẩu Quản trị viên", "administration": "Quản trị", "advanced": "Nâng cao", - "advanced_settings_beta_timeline_subtitle": "Trải nghiệm giao diện app mới", - "advanced_settings_beta_timeline_title": "Timeline Beta", "advanced_settings_enable_alternate_media_filter_subtitle": "Dùng tùy chọn này để lọc phương tiện khi đồng bộ theo tiêu chí khác. Chỉ thử khi ứng dụng không nhận diện được tất cả các album.", "advanced_settings_enable_alternate_media_filter_title": "[THỬ NGHIỆM] Dùng bộ lọc đồng bộ album thay thế", "advanced_settings_log_level_title": "Phân loại nhật ký: {level}", diff --git a/i18n/zh_Hant.json b/i18n/zh_Hant.json index 7e273faa0b..fe9108c116 100644 --- a/i18n/zh_Hant.json +++ b/i18n/zh_Hant.json @@ -28,6 +28,7 @@ "add_to_album": "加入到相簿", "add_to_album_bottom_sheet_added": "新增到 {album}", "add_to_album_bottom_sheet_already_exists": "已在 {album} 中", + "add_to_album_bottom_sheet_some_local_assets": "無法將某些本地資產添加到相册", "add_to_album_toggle": "選擇相簿{album}", "add_to_albums": "加入相簿", "add_to_albums_count": "將({count})個項目加入相簿", @@ -123,6 +124,13 @@ "logging_enable_description": "啟用日誌記錄", "logging_level_description": "啟用時的日誌層級。", "logging_settings": "日誌", + "machine_learning_availability_checks": "可用性檢查", + "machine_learning_availability_checks_description": "自動檢測並優先選擇可用的機器學習服務器", + "machine_learning_availability_checks_enabled": "啟用可用性檢查", + "machine_learning_availability_checks_interval": "檢查間隔", + "machine_learning_availability_checks_interval_description": "可用性檢查之間的間隔(毫秒)", + "machine_learning_availability_checks_timeout": "請求超時", + "machine_learning_availability_checks_timeout_description": "可用性檢查超時(毫秒)", "machine_learning_clip_model": "CLIP 模型", "machine_learning_clip_model_description": "這裡有份 CLIP 模型名單。注意:更換模型後須對所有圖片重新執行「智慧搜尋」任務。", "machine_learning_duplicate_detection": "重複項目偵測", @@ -387,8 +395,6 @@ "admin_password": "管理員密碼", "administration": "管理", "advanced": "進階", - "advanced_settings_beta_timeline_subtitle": "試用全新的應用程式體驗", - "advanced_settings_beta_timeline_title": "測試版時間軸", "advanced_settings_enable_alternate_media_filter_subtitle": "使用此選項可在同步時依其他條件篩選媒體。僅在應用程式無法偵測到所有相簿時再嘗試使用。", "advanced_settings_enable_alternate_media_filter_title": "[實驗性] 使用替代的裝置相簿同步篩選器", "advanced_settings_log_level_title": "日誌等級:{level}", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "確定要移除 {user} 嗎?", "album_search_not_found": "找不到符合搜尋條件的相簿", "album_share_no_users": "看來您與所有使用者共享了這本相簿,或沒有其他使用者可供分享。", + "album_summary": "相册摘要", "album_updated": "更新相簿時", "album_updated_setting_description": "當共享相簿有新項目時用電子郵件通知我", "album_user_left": "離開 {album}", @@ -463,6 +470,7 @@ "app_bar_signout_dialog_title": "登出", "app_settings": "應用程式設定", "appears_in": "出現於", + "apply_count": "應用({count, number})", "archive": "封存", "archive_action_prompt": "已將 ({count}) 個加入進封存", "archive_or_unarchive_photo": "封存或取消封存照片", @@ -495,6 +503,8 @@ "asset_restored_successfully": "媒體復原成功", "asset_skipped": "已跳過", "asset_skipped_in_trash": "已在垃圾桶", + "asset_trashed": "資產被丟棄", + "asset_troubleshoot": "資產故障排除", "asset_uploaded": "已上傳", "asset_uploading": "上傳中…", "asset_viewer_settings_subtitle": "管理您的媒體庫檢視器設定", @@ -528,8 +538,10 @@ "autoplay_slideshow": "自動播放幻燈片", "back": "返回", "back_close_deselect": "返回、關閉及取消選取", + "background_backup_running_error": "後臺備份當前正在運行,無法啟動手動備份", "background_location_permission": "背景存取位置權限", "background_location_permission_content": "為了在背景執行時切換網路,Immich 必須始終具有精確位置存取權限,才能讀取 Wi-Fi 網路名稱", + "background_options": "背景選項", "backup": "備份", "backup_album_selection_page_albums_device": "裝置上的相簿({count})", "backup_album_selection_page_albums_tap": "點一下以選取,點兩下以排除", @@ -537,6 +549,7 @@ "backup_album_selection_page_select_albums": "選取相簿", "backup_album_selection_page_selection_info": "選取資訊", "backup_album_selection_page_total_assets": "總不重複媒體數", + "backup_albums_sync": "備份相册同步", "backup_all": "全部", "backup_background_service_backup_failed_message": "備份媒體失敗。正在重試…", "backup_background_service_connection_failed_message": "連線伺服器失敗。正在重試…", @@ -653,6 +666,8 @@ "change_pin_code": "變更 PIN 碼", "change_your_password": "變更您的密碼", "changed_visibility_successfully": "已成功變更可見性", + "charging": "充電", + "charging_requirement_mobile_backup": "後臺備份要求設備正在充電", "check_corrupt_asset_backup": "檢查損毀的備份項目", "check_corrupt_asset_backup_button": "執行檢查", "check_corrupt_asset_backup_description": "僅在連接 Wi-Fi 且所有媒體已完成備份後執行此檢查。此程序可能需要數分鐘。", @@ -739,6 +754,7 @@ "create_user": "建立使用者", "created": "建立於", "created_at": "建立於", + "creating_linked_albums": "創建連結相册 ...", "crop": "裁剪", "curated_object_page_title": "事物", "current_device": "目前裝置", @@ -888,7 +904,9 @@ "error": "錯誤", "error_change_sort_album": "變更相簿排序失敗", "error_delete_face": "從媒體刪除臉孔時失敗", + "error_getting_places": "獲取位置時出錯", "error_loading_image": "圖片載入錯誤", + "error_loading_partners": "加載合作夥伴時出錯:{error}", "error_saving_image": "錯誤:{error}", "error_tag_face_bounding_box": "標記臉部錯誤 - 無法取得邊界框坐標", "error_title": "錯誤 - 發生錯誤", @@ -1053,6 +1071,7 @@ "favorites_page_no_favorites": "未找到收藏項目", "feature_photo_updated": "特色照片已更新", "features": "功能", + "features_in_development": "發展中的特點", "features_setting_description": "管理應用程式功能", "file_name": "檔案名稱", "file_name_or_extension": "檔案名稱或副檔名", @@ -1080,6 +1099,8 @@ "go_back": "返回", "go_to_folder": "前往資料夾", "go_to_search": "前往搜尋", + "gps": "GPS", + "gps_missing": "無GPS", "grant_permission": "授予權限", "group_albums_by": "分類群組的方式...", "group_country": "按照國家分類", @@ -1215,6 +1236,7 @@ "local": "本地", "local_asset_cast_failed": "無法轉換未上傳至伺服器的項目", "local_assets": "本地項目", + "local_media_summary": "當地媒體摘要", "local_network": "本地網路", "local_network_sheet_info": "當使用指定的 Wi-Fi 網路時,應用程式將透過此網址連線至伺服器", "location_permission": "位置權限", @@ -1226,6 +1248,7 @@ "location_picker_longitude_hint": "請在此處輸入您的經度值", "lock": "鎖定", "locked_folder": "鎖定的資料夾", + "log_detail_title": "日誌詳細資訊", "log_out": "登出", "log_out_all_devices": "登出所有裝置", "logged_in_as": "以{user}身分登入", @@ -1256,6 +1279,7 @@ "login_password_changed_success": "密碼更新成功", "logout_all_device_confirmation": "您確定要登出所有裝置嗎?", "logout_this_device_confirmation": "要登出這臺裝置嗎?", + "logs": "日誌", "longitude": "經度", "look": "樣貌", "loop_videos": "重播影片", @@ -1298,6 +1322,7 @@ "mark_as_read": "標記為已讀", "marked_all_as_read": "已全部標記為已讀", "matches": "相符", + "matching_assets": "匹配資產", "media_type": "媒體類型", "memories": "回憶", "memories_all_caught_up": "已全部看完", @@ -1338,6 +1363,7 @@ "name_or_nickname": "名稱或暱稱", "network_requirement_photos_upload": "使用行動網路流量備份照片", "network_requirement_videos_upload": "使用行動網路流量備份影片", + "network_requirements": "網絡要求", "network_requirements_updated": "網絡需求已變更,現重置備份佇列", "networking_settings": "網路", "networking_subtitle": "管理伺服器端點設定", @@ -1348,6 +1374,7 @@ "new_person": "新的人物", "new_pin_code": "新 PIN 碼", "new_pin_code_subtitle": "這是您第一次存取鎖定的資料夾。建立 PIN 碼以安全存取此頁面", + "new_timeline": "新時間軸", "new_user_created": "已建立新使用者", "new_version_available": "新版本已發布", "newest_first": "最新優先", @@ -1361,20 +1388,25 @@ "no_assets_message": "按這裡上傳您的第一張照片", "no_assets_to_show": "無項目展示", "no_cast_devices_found": "沒有找到 Google Cast 裝置", + "no_checksum_local": "沒有可用的校驗和-無法獲取本地資產", + "no_checksum_remote": "沒有可用的校驗和-無法獲取遠程資產", "no_duplicates_found": "沒發現重複項目。", "no_exif_info_available": "沒有可用的 Exif 資訊", "no_explore_results_message": "上傳更多照片以利探索。", "no_favorites_message": "加入收藏,加速尋找影像", "no_libraries_message": "建立外部媒體庫以查看您的照片和影片", + "no_local_assets_found": "未找到具有此校驗和的本地資產", "no_locked_photos_message": "鎖定的資料夾中的照片和影片會被隱藏,當您瀏覽或搜尋圖庫時不會顯示。", "no_name": "無名", "no_notifications": "沒有通知", "no_people_found": "找不到符合的人物", "no_places": "沒有地點", + "no_remote_assets_found": "未找到具有此校驗和的遠程資產", "no_results": "沒有結果", "no_results_description": "試試同義詞或更通用的關鍵字吧", "no_shared_albums_message": "建立相簿分享照片和影片", "no_uploads_in_progress": "沒有正在上傳的項目", + "not_available": "不適用", "not_in_any_album": "不在任何相簿中", "not_selected": "未選擇", "note_apply_storage_label_to_previously_uploaded assets": "*註:執行套用儲存標籤前先上傳項目", @@ -1409,6 +1441,8 @@ "open_the_search_filters": "開啟搜尋篩選器", "options": "選項", "or": "或", + "organize_into_albums": "整理成相册", + "organize_into_albums_description": "使用當前同步設定將現有照片放入相册", "organize_your_library": "整理您的圖庫", "original": "原圖", "other": "其他", @@ -1494,6 +1528,7 @@ "port": "埠口", "preferences_settings_subtitle": "管理應用程式偏好設定", "preferences_settings_title": "偏好設定", + "preparing": "準備", "preset": "預設", "preview": "預覽", "previous": "上一張", @@ -1559,6 +1594,7 @@ "read_changelog": "閱覽變更日誌", "readonly_mode_disabled": "唯讀模式已關閉", "readonly_mode_enabled": "唯讀模式已開啟", + "ready_for_upload": "已準備好上傳", "reassign": "重新指定", "reassigned_assets_to_existing_person": "已將 {count, plural, other {# 個檔案}}重新指定給{name, select, null {現有的人} other {{name}}}", "reassigned_assets_to_new_person": "已將 {count, plural, other {# 個檔案}}重新指定給一位新人物", @@ -1583,6 +1619,7 @@ "regenerating_thumbnails": "重新產生縮圖中", "remote": "遠端", "remote_assets": "遠端項目", + "remote_media_summary": "遠程媒體摘要", "remove": "移除", "remove_assets_album_confirmation": "確定要從相簿中移除 {count, plural, other {# 個檔案}}嗎?", "remove_assets_shared_link_confirmation": "確定刪除共享連結中{count, plural, other {# 個項目}}嗎?", @@ -1729,7 +1766,7 @@ "select_user_for_sharing_page_err_album": "新增相簿失敗", "selected": "已選擇", "selected_count": "{count, plural, other {選了 # 項}}", - "selected_gps_coordinates": "已選擇的 GPS 座標", + "selected_gps_coordinates": "選定的GPS座標", "send_message": "傳訊息", "send_welcome_email": "傳送歡迎電子郵件", "server_endpoint": "伺服器端點", @@ -1858,6 +1895,7 @@ "show_slideshow_transition": "顯示幻燈片轉場", "show_supporter_badge": "擁護者徽章", "show_supporter_badge_description": "顯示擁護者徽章", + "show_text_search_menu": "顯示文字蒐索選單", "shuffle": "隨機排序", "sidebar": "側邊欄", "sidebar_display_description": "在側邊欄中顯示鏈結", @@ -1888,6 +1926,7 @@ "stacktrace": "堆疊追蹤", "start": "開始", "start_date": "開始日期", + "start_date_before_end_date": "開始日期必須早於結束日期", "state": "地區", "status": "狀態", "stop_casting": "停止casting", @@ -2090,5 +2129,6 @@ "yes": "是", "you_dont_have_any_shared_links": "您沒有任何共享連結", "your_wifi_name": "您的 Wi-Fi 名稱", - "zoom_image": "縮放圖片" + "zoom_image": "縮放圖片", + "zoom_to_bounds": "縮放到邊界" } diff --git a/i18n/zh_SIMPLIFIED.json b/i18n/zh_SIMPLIFIED.json index df9ca98e85..1f1455aa19 100644 --- a/i18n/zh_SIMPLIFIED.json +++ b/i18n/zh_SIMPLIFIED.json @@ -28,6 +28,7 @@ "add_to_album": "添加到相册", "add_to_album_bottom_sheet_added": "添加到相册 “{album}”", "add_to_album_bottom_sheet_already_exists": "已在相册“ {album} ” 中", + "add_to_album_bottom_sheet_some_local_assets": "某些本地资产无法添加到相册", "add_to_album_toggle": "选择相册 {album}", "add_to_albums": "添加到相册", "add_to_albums_count": "添加到相册({count}个)", @@ -123,6 +124,13 @@ "logging_enable_description": "启用日志记录", "logging_level_description": "启用时,要使用的日志级别。", "logging_settings": "日志", + "machine_learning_availability_checks": "可用性检查", + "machine_learning_availability_checks_description": "自动检测并优先选择可用的机器学习服务器", + "machine_learning_availability_checks_enabled": "启用可用性检查", + "machine_learning_availability_checks_interval": "检查间隔", + "machine_learning_availability_checks_interval_description": "两次可用性检查之间的间隔(毫秒)", + "machine_learning_availability_checks_timeout": "请求超时", + "machine_learning_availability_checks_timeout_description": "用于可用性检查的超时时间(毫秒)", "machine_learning_clip_model": "CLIP 模型", "machine_learning_clip_model_description": "请于 此处查看支持的 CLIP 模型名称。注意,更换模型后需要对所有图片重新运行“智能搜索”任务。", "machine_learning_duplicate_detection": "重复项检测", @@ -387,8 +395,6 @@ "admin_password": "管理员密码", "administration": "系统管理", "advanced": "高级", - "advanced_settings_beta_timeline_subtitle": "体验全新的应用程序", - "advanced_settings_beta_timeline_title": "测试版时间线", "advanced_settings_enable_alternate_media_filter_subtitle": "使用此选项可在同步过程中根据备用条件筛选项目。仅当您在应用程序检测所有相册均遇到问题时才尝试此功能。", "advanced_settings_enable_alternate_media_filter_title": "[实验] 使用备用的设备相册同步筛选条件", "advanced_settings_log_level_title": "日志等级: {level}", @@ -425,6 +431,7 @@ "album_remove_user_confirmation": "确定要移除“{user}”吗?", "album_search_not_found": "未找到符合搜索条件的相册", "album_share_no_users": "看起来您已与所有用户共享了此相册,或者您根本没有任何用户可共享。", + "album_summary": "相册摘要", "album_updated": "相册有更新", "album_updated_setting_description": "当共享相册有新项目时接收邮件通知", "album_user_left": "离开“{album}”", @@ -458,7 +465,7 @@ "api_key_description": "该应用密钥只会显示一次。请确保在关闭窗口前复制下来。", "api_key_empty": "API 密钥名称不可为空", "api_keys": "API 密钥", - "app_bar_signout_dialog_content": "确定退出登录?", + "app_bar_signout_dialog_content": "是否确定退出登录?", "app_bar_signout_dialog_ok": "是", "app_bar_signout_dialog_title": "退出登录", "app_settings": "应用设置", @@ -496,6 +503,8 @@ "asset_restored_successfully": "已成功恢复所有项目", "asset_skipped": "已跳过", "asset_skipped_in_trash": "已回收", + "asset_trashed": "资产已被删除", + "asset_troubleshoot": "资产故障排除", "asset_uploaded": "已上传", "asset_uploading": "上传中…", "asset_viewer_settings_subtitle": "管理图库浏览器设置", @@ -529,8 +538,10 @@ "autoplay_slideshow": "自动播放幻灯片", "back": "返回", "back_close_deselect": "返回、关闭或反选", + "background_backup_running_error": "后台备份正在运行,无法启动手动备份", "background_location_permission": "后台定位权限", "background_location_permission_content": "为确保后台运行时自动切换网络,需授予 Immich *始终允许精确定位* 权限,以识别 Wi-Fi 网络名称", + "background_options": "背景选项", "backup": "备份", "backup_album_selection_page_albums_device": "设备上的相册({count})", "backup_album_selection_page_albums_tap": "单击选中,双击取消", @@ -538,6 +549,7 @@ "backup_album_selection_page_select_albums": "选择相册", "backup_album_selection_page_selection_info": "选择信息", "backup_album_selection_page_total_assets": "总计", + "backup_albums_sync": "备份相册同步", "backup_all": "全部", "backup_background_service_backup_failed_message": "备份失败,正在重试…", "backup_background_service_connection_failed_message": "连接服务器失败,正在重试…", @@ -654,6 +666,8 @@ "change_pin_code": "修改PIN码", "change_your_password": "修改您的密码", "changed_visibility_successfully": "更改可见性成功", + "charging": "充电", + "charging_requirement_mobile_backup": "后台备份需要设备处于充电状态", "check_corrupt_asset_backup": "检查备份是否损坏", "check_corrupt_asset_backup_button": "执行检查", "check_corrupt_asset_backup_description": "仅在连接到 Wi-Fi 并完成所有项目备份后执行此检查。该过程可能需要几分钟。", @@ -740,6 +754,7 @@ "create_user": "创建用户", "created": "已创建", "created_at": "已创建", + "creating_linked_albums": "正在创建相册链接…", "crop": "裁剪", "curated_object_page_title": "事物", "current_device": "当前设备", @@ -889,7 +904,9 @@ "error": "错误", "error_change_sort_album": "更改相册排序失败", "error_delete_face": "删除人脸失败", + "error_getting_places": "获取位置时出错", "error_loading_image": "加载图片时出错", + "error_loading_partners": "加载同伴时出错:{error}", "error_saving_image": "错误:{error}", "error_tag_face_bounding_box": "标记人脸出错 - 无法获取人脸框坐标", "error_title": "错误 - 好像出了问题", @@ -1054,6 +1071,7 @@ "favorites_page_no_favorites": "未找到收藏项目", "feature_photo_updated": "人物头像已更新", "features": "功能", + "features_in_development": "开发中的功能", "features_setting_description": "管理 App 功能", "file_name": "文件名", "file_name_or_extension": "文件名", @@ -1218,6 +1236,7 @@ "local": "本地", "local_asset_cast_failed": "无法投放未上传至服务器的项目", "local_assets": "本地项目", + "local_media_summary": "本地媒体摘要", "local_network": "本地网络", "local_network_sheet_info": "当使用指定的 Wi-Fi 网络时,应用程序将通过此 URL 访问服务器", "location_permission": "定位权限", @@ -1229,6 +1248,7 @@ "location_picker_longitude_hint": "请在此处输入经度", "lock": "锁定", "locked_folder": "锁定文件夹", + "log_detail_title": "日志详细信息", "log_out": "注销", "log_out_all_devices": "注销所有设备", "logged_in_as": "以 {user} 身份登录", @@ -1259,6 +1279,7 @@ "login_password_changed_success": "密码更新成功", "logout_all_device_confirmation": "确定要从所有设备注销?", "logout_this_device_confirmation": "确定要从本设备注销?", + "logs": "日志", "longitude": "经度", "look": "样式", "loop_videos": "循环视频", @@ -1293,7 +1314,7 @@ "map_settings_date_range_option_years": "{years} 年前", "map_settings_dialog_title": "地图设置", "map_settings_include_show_archived": "包括已归档项目", - "map_settings_include_show_partners": "包含伙伴", + "map_settings_include_show_partners": "包含同伴", "map_settings_only_show_favorites": "仅显示收藏的项目", "map_settings_theme_settings": "地图主题", "map_zoom_to_see_photos": "缩小以查看项目", @@ -1301,6 +1322,7 @@ "mark_as_read": "标记为已读", "marked_all_as_read": "已全部标记为已读", "matches": "匹配", + "matching_assets": "匹配资产", "media_type": "媒体类型", "memories": "回忆", "memories_all_caught_up": "已全部看完", @@ -1341,6 +1363,7 @@ "name_or_nickname": "名称或昵称", "network_requirement_photos_upload": "使用蜂窝数据备份照片", "network_requirement_videos_upload": "使用蜂窝数据备份视频", + "network_requirements": "网络要求", "network_requirements_updated": "网络要求发生变化,正在重置备份队列", "networking_settings": "网络", "networking_subtitle": "管理服务器接口设置", @@ -1351,6 +1374,7 @@ "new_person": "新人物", "new_pin_code": "新的PIN码", "new_pin_code_subtitle": "这是您第一次访问此锁定文件夹。创建一个PIN码以安全访问此页面", + "new_timeline": "新建时间轴", "new_user_created": "已创建新用户", "new_version_available": "有新版本发布啦", "newest_first": "最新优先", @@ -1364,20 +1388,25 @@ "no_assets_message": "点击上传您的第一张照片", "no_assets_to_show": "没有要显示的资产", "no_cast_devices_found": "未找到投放设备", + "no_checksum_local": "没有可用的校验和-无法获取本地资产", + "no_checksum_remote": "没有可用的校验和-无法获取远程资产", "no_duplicates_found": "未发现重复项。", "no_exif_info_available": "没有可用的 EXIF 信息", "no_explore_results_message": "上传更多照片来探索。", "no_favorites_message": "添加到收藏夹,快速查找最佳图片和视频", "no_libraries_message": "创建外部图库来查看您的照片和视频", + "no_local_assets_found": "未找到具有此校验和的本地资产", "no_locked_photos_message": "锁定文件夹中的照片和视频将被隐藏,不会在您浏览、搜索图库时出现。", "no_name": "未命名", "no_notifications": "没有通知", "no_people_found": "未找到匹配的人物", "no_places": "无位置", + "no_remote_assets_found": "未找到具有此校验和的远程资产", "no_results": "无结果", "no_results_description": "尝试使用同义词或更通用的关键词", "no_shared_albums_message": "创建相册以共享照片和视频", "no_uploads_in_progress": "没有正在进行的上传", + "not_available": "不适用", "not_in_any_album": "不在任何相册中", "not_selected": "未选择", "note_apply_storage_label_to_previously_uploaded assets": "提示:要将存储标签应用于之前上传的项目,需要运行", @@ -1499,6 +1528,7 @@ "port": "端口", "preferences_settings_subtitle": "管理应用的偏好设置", "preferences_settings_title": "偏好设置", + "preparing": "准备中", "preset": "预设", "preview": "预览", "previous": "上一个", @@ -1564,6 +1594,7 @@ "read_changelog": "阅读更新日志", "readonly_mode_disabled": "只读模式已禁用", "readonly_mode_enabled": "只读模式已启用", + "ready_for_upload": "准备上传", "reassign": "重新指派", "reassigned_assets_to_existing_person": "重新指派{count, plural, one {#个项目} other {#个项目}}到{name, select, null {已存在的人物} other {{name}}}", "reassigned_assets_to_new_person": "重新指派{count, plural, one {#个项目} other {#个项目}}到新的人物", @@ -1588,6 +1619,7 @@ "regenerating_thumbnails": "正在重新生成缩略图", "remote": "远程", "remote_assets": "远程项目", + "remote_media_summary": "远程媒体摘要", "remove": "移除", "remove_assets_album_confirmation": "确定要从图库中移除{count, plural, one {#个项目} other {#个项目}}?", "remove_assets_shared_link_confirmation": "确定要从共享链接中移除{count, plural, one {#个项目} other {#个项目}}?", @@ -1863,10 +1895,11 @@ "show_slideshow_transition": "显示幻灯片过渡效果", "show_supporter_badge": "支持者徽章", "show_supporter_badge_description": "展示支持者徽章", + "show_text_search_menu": "显示文本搜索菜单", "shuffle": "随机", "sidebar": "侧边栏", "sidebar_display_description": "在侧边栏中显示链接", - "sign_out": "注销", + "sign_out": "退出登录", "sign_up": "注册", "size": "大小", "skip_to_content": "跳转到内容", @@ -1893,6 +1926,7 @@ "stacktrace": "堆栈跟踪", "start": "开始", "start_date": "开始日期", + "start_date_before_end_date": "开始日期必须在结束日期之前", "state": "省份", "status": "状态", "stop_casting": "停止投放", @@ -2095,5 +2129,6 @@ "yes": "是", "you_dont_have_any_shared_links": "您没有任何共享链接", "your_wifi_name": "您的 Wi-Fi 名称", - "zoom_image": "缩放图像" + "zoom_image": "缩放图像", + "zoom_to_bounds": "缩放到边界" } diff --git a/machine-learning/pyproject.toml b/machine-learning/pyproject.toml index f0f08b20b6..3eee4a5e2d 100644 --- a/machine-learning/pyproject.toml +++ b/machine-learning/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "immich-ml" -version = "1.129.0" +version = "1.144.1" description = "" authors = [{ name = "Hau Tran", email = "alex.tran1502@gmail.com" }] requires-python = ">=3.10,<4.0" diff --git a/machine-learning/uv.lock b/machine-learning/uv.lock index 393dabe319..c30120a40b 100644 --- a/machine-learning/uv.lock +++ b/machine-learning/uv.lock @@ -507,61 +507,87 @@ wheels = [ [[package]] name = "coverage" -version = "7.6.4" +version = "7.10.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/52/12/3669b6382792783e92046730ad3327f53b2726f0603f4c311c4da4824222/coverage-7.6.4.tar.gz", hash = "sha256:29fc0f17b1d3fea332f8001d4558f8214af7f1d87a345f3a133c901d60347c73", size = 798716, upload-time = "2024-10-20T22:57:39.682Z" } +sdist = { url = "https://files.pythonhosted.org/packages/14/70/025b179c993f019105b79575ac6edb5e084fb0f0e63f15cdebef4e454fb5/coverage-7.10.6.tar.gz", hash = "sha256:f644a3ae5933a552a29dbb9aa2f90c677a875f80ebea028e5a52a4f429044b90", size = 823736, upload-time = "2025-08-29T15:35:16.668Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/93/4ad92f71e28ece5c0326e5f4a6630aa4928a8846654a65cfff69b49b95b9/coverage-7.6.4-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f8ae553cba74085db385d489c7a792ad66f7f9ba2ee85bfa508aeb84cf0ba07", size = 206713, upload-time = "2024-10-20T22:56:03.877Z" }, - { url = "https://files.pythonhosted.org/packages/01/ae/747a580b1eda3f2e431d87de48f0604bd7bc92e52a1a95185a4aa585bc47/coverage-7.6.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8165b796df0bd42e10527a3f493c592ba494f16ef3c8b531288e3d0d72c1f6f0", size = 207149, upload-time = "2024-10-20T22:56:06.511Z" }, - { url = "https://files.pythonhosted.org/packages/07/1a/1f573f8a6145f6d4c9130bbc120e0024daf1b24cf2a78d7393fa6eb6aba7/coverage-7.6.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7c8b95bf47db6d19096a5e052ffca0a05f335bc63cef281a6e8fe864d450a72", size = 235584, upload-time = "2024-10-20T22:56:07.678Z" }, - { url = "https://files.pythonhosted.org/packages/40/42/c8523f2e4db34aa9389caee0d3688b6ada7a84fcc782e943a868a7f302bd/coverage-7.6.4-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ed9281d1b52628e81393f5eaee24a45cbd64965f41857559c2b7ff19385df51", size = 233486, upload-time = "2024-10-20T22:56:09.496Z" }, - { url = "https://files.pythonhosted.org/packages/8d/95/565c310fffa16ede1a042e9ea1ca3962af0d8eb5543bc72df6b91dc0c3d5/coverage-7.6.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0809082ee480bb8f7416507538243c8863ac74fd8a5d2485c46f0f7499f2b491", size = 234649, upload-time = "2024-10-20T22:56:11.326Z" }, - { url = "https://files.pythonhosted.org/packages/d5/81/3b550674d98968ec29c92e3e8650682be6c8b1fa7581a059e7e12e74c431/coverage-7.6.4-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d541423cdd416b78626b55f123412fcf979d22a2c39fce251b350de38c15c15b", size = 233744, upload-time = "2024-10-20T22:56:12.481Z" }, - { url = "https://files.pythonhosted.org/packages/0d/70/d66c7f51b3e33aabc5ea9f9624c1c9d9655472962270eb5e7b0d32707224/coverage-7.6.4-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:58809e238a8a12a625c70450b48e8767cff9eb67c62e6154a642b21ddf79baea", size = 232204, upload-time = "2024-10-20T22:56:14.236Z" }, - { url = "https://files.pythonhosted.org/packages/23/2d/2b3a2dbed7a5f40693404c8a09e779d7c1a5fbed089d3e7224c002129ec8/coverage-7.6.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c9b8e184898ed014884ca84c70562b4a82cbc63b044d366fedc68bc2b2f3394a", size = 233335, upload-time = "2024-10-20T22:56:15.521Z" }, - { url = "https://files.pythonhosted.org/packages/5a/4f/92d1d2ad720d698a4e71c176eacf531bfb8e0721d5ad560556f2c484a513/coverage-7.6.4-cp310-cp310-win32.whl", hash = "sha256:6bd818b7ea14bc6e1f06e241e8234508b21edf1b242d49831831a9450e2f35fa", size = 209435, upload-time = "2024-10-20T22:56:17.309Z" }, - { url = "https://files.pythonhosted.org/packages/c7/b9/cdf158e7991e2287bcf9082670928badb73d310047facac203ff8dcd5ff3/coverage-7.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:06babbb8f4e74b063dbaeb74ad68dfce9186c595a15f11f5d5683f748fa1d172", size = 210243, upload-time = "2024-10-20T22:56:18.366Z" }, - { url = "https://files.pythonhosted.org/packages/87/31/9c0cf84f0dfcbe4215b7eb95c31777cdc0483c13390e69584c8150c85175/coverage-7.6.4-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:73d2b73584446e66ee633eaad1a56aad577c077f46c35ca3283cd687b7715b0b", size = 206819, upload-time = "2024-10-20T22:56:20.132Z" }, - { url = "https://files.pythonhosted.org/packages/53/ed/a38401079ad320ad6e054a01ec2b61d270511aeb3c201c80e99c841229d5/coverage-7.6.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:51b44306032045b383a7a8a2c13878de375117946d68dcb54308111f39775a25", size = 207263, upload-time = "2024-10-20T22:56:21.88Z" }, - { url = "https://files.pythonhosted.org/packages/20/e7/c3ad33b179ab4213f0d70da25a9c214d52464efa11caeab438592eb1d837/coverage-7.6.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b3fb02fe73bed561fa12d279a417b432e5b50fe03e8d663d61b3d5990f29546", size = 239205, upload-time = "2024-10-20T22:56:23.03Z" }, - { url = "https://files.pythonhosted.org/packages/36/91/fc02e8d8e694f557752120487fd982f654ba1421bbaa5560debf96ddceda/coverage-7.6.4-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed8fe9189d2beb6edc14d3ad19800626e1d9f2d975e436f84e19efb7fa19469b", size = 236612, upload-time = "2024-10-20T22:56:24.882Z" }, - { url = "https://files.pythonhosted.org/packages/cc/57/cb08f0eda0389a9a8aaa4fc1f9fec7ac361c3e2d68efd5890d7042c18aa3/coverage-7.6.4-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b369ead6527d025a0fe7bd3864e46dbee3aa8f652d48df6174f8d0bac9e26e0e", size = 238479, upload-time = "2024-10-20T22:56:26.749Z" }, - { url = "https://files.pythonhosted.org/packages/d5/c9/2c7681a9b3ca6e6f43d489c2e6653a53278ed857fd6e7010490c307b0a47/coverage-7.6.4-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ade3ca1e5f0ff46b678b66201f7ff477e8fa11fb537f3b55c3f0568fbfe6e718", size = 237405, upload-time = "2024-10-20T22:56:27.958Z" }, - { url = "https://files.pythonhosted.org/packages/b5/4e/ebfc6944b96317df8b537ae875d2e57c27b84eb98820bc0a1055f358f056/coverage-7.6.4-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:27fb4a050aaf18772db513091c9c13f6cb94ed40eacdef8dad8411d92d9992db", size = 236038, upload-time = "2024-10-20T22:56:29.816Z" }, - { url = "https://files.pythonhosted.org/packages/13/f2/3a0bf1841a97c0654905e2ef531170f02c89fad2555879db8fe41a097871/coverage-7.6.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f704f0998911abf728a7783799444fcbbe8261c4a6c166f667937ae6a8aa522", size = 236812, upload-time = "2024-10-20T22:56:31.654Z" }, - { url = "https://files.pythonhosted.org/packages/b9/9c/66bf59226b52ce6ed9541b02d33e80a6e816a832558fbdc1111a7bd3abd4/coverage-7.6.4-cp311-cp311-win32.whl", hash = "sha256:29155cd511ee058e260db648b6182c419422a0d2e9a4fa44501898cf918866cf", size = 209400, upload-time = "2024-10-20T22:56:33.569Z" }, - { url = "https://files.pythonhosted.org/packages/2a/a0/b0790934c04dfc8d658d4a62acb8f7ca0efdf3818456fcad757b11c6479d/coverage-7.6.4-cp311-cp311-win_amd64.whl", hash = "sha256:8902dd6a30173d4ef09954bfcb24b5d7b5190cf14a43170e386979651e09ba19", size = 210243, upload-time = "2024-10-20T22:56:34.863Z" }, - { url = "https://files.pythonhosted.org/packages/7d/e7/9291de916d084f41adddfd4b82246e68d61d6a75747f075f7e64628998d2/coverage-7.6.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:12394842a3a8affa3ba62b0d4ab7e9e210c5e366fbac3e8b2a68636fb19892c2", size = 207013, upload-time = "2024-10-20T22:56:36.034Z" }, - { url = "https://files.pythonhosted.org/packages/27/03/932c2c5717a7fa80cd43c6a07d3177076d97b79f12f40f882f9916db0063/coverage-7.6.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2b6b4c83d8e8ea79f27ab80778c19bc037759aea298da4b56621f4474ffeb117", size = 207251, upload-time = "2024-10-20T22:56:38.054Z" }, - { url = "https://files.pythonhosted.org/packages/d5/3f/0af47dcb9327f65a45455fbca846fe96eb57c153af46c4754a3ba678938a/coverage-7.6.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1d5b8007f81b88696d06f7df0cb9af0d3b835fe0c8dbf489bad70b45f0e45613", size = 240268, upload-time = "2024-10-20T22:56:40.051Z" }, - { url = "https://files.pythonhosted.org/packages/8a/3c/37a9d81bbd4b23bc7d46ca820e16174c613579c66342faa390a271d2e18b/coverage-7.6.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b57b768feb866f44eeed9f46975f3d6406380275c5ddfe22f531a2bf187eda27", size = 237298, upload-time = "2024-10-20T22:56:41.929Z" }, - { url = "https://files.pythonhosted.org/packages/c0/70/6b0627e5bd68204ee580126ed3513140b2298995c1233bd67404b4e44d0e/coverage-7.6.4-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5915fcdec0e54ee229926868e9b08586376cae1f5faa9bbaf8faf3561b393d52", size = 239367, upload-time = "2024-10-20T22:56:43.141Z" }, - { url = "https://files.pythonhosted.org/packages/3c/eb/634d7dfab24ac3b790bebaf9da0f4a5352cbc125ce6a9d5c6cf4c6cae3c7/coverage-7.6.4-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b58c672d14f16ed92a48db984612f5ce3836ae7d72cdd161001cc54512571f2", size = 238853, upload-time = "2024-10-20T22:56:44.33Z" }, - { url = "https://files.pythonhosted.org/packages/d9/0d/8e3ed00f1266ef7472a4e33458f42e39492e01a64281084fb3043553d3f1/coverage-7.6.4-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2fdef0d83a2d08d69b1f2210a93c416d54e14d9eb398f6ab2f0a209433db19e1", size = 237160, upload-time = "2024-10-20T22:56:46.258Z" }, - { url = "https://files.pythonhosted.org/packages/ce/9c/4337f468ef0ab7a2e0887a9c9da0e58e2eada6fc6cbee637a4acd5dfd8a9/coverage-7.6.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cf717ee42012be8c0cb205dbbf18ffa9003c4cbf4ad078db47b95e10748eec5", size = 238824, upload-time = "2024-10-20T22:56:48.666Z" }, - { url = "https://files.pythonhosted.org/packages/5e/09/3e94912b8dd37251377bb02727a33a67ee96b84bbbe092f132b401ca5dd9/coverage-7.6.4-cp312-cp312-win32.whl", hash = "sha256:7bb92c539a624cf86296dd0c68cd5cc286c9eef2d0c3b8b192b604ce9de20a17", size = 209639, upload-time = "2024-10-20T22:56:50.664Z" }, - { url = "https://files.pythonhosted.org/packages/01/69/d4f3a4101171f32bc5b3caec8ff94c2c60f700107a6aaef7244b2c166793/coverage-7.6.4-cp312-cp312-win_amd64.whl", hash = "sha256:1032e178b76a4e2b5b32e19d0fd0abbce4b58e77a1ca695820d10e491fa32b08", size = 210428, upload-time = "2024-10-20T22:56:52.468Z" }, - { url = "https://files.pythonhosted.org/packages/c2/4d/2dede4f7cb5a70fb0bb40a57627fddf1dbdc6b9c1db81f7c4dcdcb19e2f4/coverage-7.6.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:023bf8ee3ec6d35af9c1c6ccc1d18fa69afa1cb29eaac57cb064dbb262a517f9", size = 207039, upload-time = "2024-10-20T22:56:53.656Z" }, - { url = "https://files.pythonhosted.org/packages/3f/f9/d86368ae8c79e28f1fb458ebc76ae9ff3e8bd8069adc24e8f2fed03c58b7/coverage-7.6.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:b0ac3d42cb51c4b12df9c5f0dd2f13a4f24f01943627120ec4d293c9181219ba", size = 207298, upload-time = "2024-10-20T22:56:54.979Z" }, - { url = "https://files.pythonhosted.org/packages/64/c5/b4cc3c3f64622c58fbfd4d8b9a7a8ce9d355f172f91fcabbba1f026852f6/coverage-7.6.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f8fe4984b431f8621ca53d9380901f62bfb54ff759a1348cd140490ada7b693c", size = 239813, upload-time = "2024-10-20T22:56:56.209Z" }, - { url = "https://files.pythonhosted.org/packages/8a/86/14c42e60b70a79b26099e4d289ccdfefbc68624d096f4481163085aa614c/coverage-7.6.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5fbd612f8a091954a0c8dd4c0b571b973487277d26476f8480bfa4b2a65b5d06", size = 236959, upload-time = "2024-10-20T22:56:58.06Z" }, - { url = "https://files.pythonhosted.org/packages/7f/f8/4436a643631a2fbab4b44d54f515028f6099bfb1cd95b13cfbf701e7f2f2/coverage-7.6.4-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dacbc52de979f2823a819571f2e3a350a7e36b8cb7484cdb1e289bceaf35305f", size = 238950, upload-time = "2024-10-20T22:56:59.329Z" }, - { url = "https://files.pythonhosted.org/packages/49/50/1571810ddd01f99a0a8be464a4ac8b147f322cd1e8e296a1528984fc560b/coverage-7.6.4-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:dab4d16dfef34b185032580e2f2f89253d302facba093d5fa9dbe04f569c4f4b", size = 238610, upload-time = "2024-10-20T22:57:00.645Z" }, - { url = "https://files.pythonhosted.org/packages/f3/8c/6312d241fe7cbd1f0cade34a62fea6f333d1a261255d76b9a87074d8703c/coverage-7.6.4-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:862264b12ebb65ad8d863d51f17758b1684560b66ab02770d4f0baf2ff75da21", size = 236697, upload-time = "2024-10-20T22:57:01.944Z" }, - { url = "https://files.pythonhosted.org/packages/ce/5f/fef33dfd05d87ee9030f614c857deb6df6556b8f6a1c51bbbb41e24ee5ac/coverage-7.6.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5beb1ee382ad32afe424097de57134175fea3faf847b9af002cc7895be4e2a5a", size = 238541, upload-time = "2024-10-20T22:57:03.848Z" }, - { url = "https://files.pythonhosted.org/packages/a9/64/6a984b6e92e1ea1353b7ffa08e27f707a5e29b044622445859200f541e8c/coverage-7.6.4-cp313-cp313-win32.whl", hash = "sha256:bf20494da9653f6410213424f5f8ad0ed885e01f7e8e59811f572bdb20b8972e", size = 209707, upload-time = "2024-10-20T22:57:05.123Z" }, - { url = "https://files.pythonhosted.org/packages/5c/60/ce5a9e942e9543783b3db5d942e0578b391c25cdd5e7f342d854ea83d6b7/coverage-7.6.4-cp313-cp313-win_amd64.whl", hash = "sha256:182e6cd5c040cec0a1c8d415a87b67ed01193ed9ad458ee427741c7d8513d963", size = 210439, upload-time = "2024-10-20T22:57:06.35Z" }, - { url = "https://files.pythonhosted.org/packages/78/53/6719677e92c308207e7f10561a1b16ab8b5c00e9328efc9af7cfd6fb703e/coverage-7.6.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a181e99301a0ae128493a24cfe5cfb5b488c4e0bf2f8702091473d033494d04f", size = 207784, upload-time = "2024-10-20T22:57:07.857Z" }, - { url = "https://files.pythonhosted.org/packages/fa/dd/7054928930671fcb39ae6a83bb71d9ab5f0afb733172543ced4b09a115ca/coverage-7.6.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:df57bdbeffe694e7842092c5e2e0bc80fff7f43379d465f932ef36f027179806", size = 208058, upload-time = "2024-10-20T22:57:09.845Z" }, - { url = "https://files.pythonhosted.org/packages/b5/7d/fd656ddc2b38301927b9eb3aae3fe827e7aa82e691923ed43721fd9423c9/coverage-7.6.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bcd1069e710600e8e4cf27f65c90c7843fa8edfb4520fb0ccb88894cad08b11", size = 250772, upload-time = "2024-10-20T22:57:11.147Z" }, - { url = "https://files.pythonhosted.org/packages/90/d0/eb9a3cc2100b83064bb086f18aedde3afffd7de6ead28f69736c00b7f302/coverage-7.6.4-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:99b41d18e6b2a48ba949418db48159d7a2e81c5cc290fc934b7d2380515bd0e3", size = 246490, upload-time = "2024-10-20T22:57:13.02Z" }, - { url = "https://files.pythonhosted.org/packages/45/44/3f64f38f6faab8a0cfd2c6bc6eb4c6daead246b97cf5f8fc23bf3788f841/coverage-7.6.4-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a6b1e54712ba3474f34b7ef7a41e65bd9037ad47916ccb1cc78769bae324c01a", size = 248848, upload-time = "2024-10-20T22:57:14.927Z" }, - { url = "https://files.pythonhosted.org/packages/5d/11/4c465a5f98656821e499f4b4619929bd5a34639c466021740ecdca42aa30/coverage-7.6.4-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:53d202fd109416ce011578f321460795abfe10bb901b883cafd9b3ef851bacfc", size = 248340, upload-time = "2024-10-20T22:57:16.246Z" }, - { url = "https://files.pythonhosted.org/packages/f1/96/ebecda2d016cce9da812f404f720ca5df83c6b29f65dc80d2000d0078741/coverage-7.6.4-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c48167910a8f644671de9f2083a23630fbf7a1cb70ce939440cd3328e0919f70", size = 246229, upload-time = "2024-10-20T22:57:17.546Z" }, - { url = "https://files.pythonhosted.org/packages/16/d9/3d820c00066ae55d69e6d0eae11d6149a5ca7546de469ba9d597f01bf2d7/coverage-7.6.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:cc8ff50b50ce532de2fa7a7daae9dd12f0a699bfcd47f20945364e5c31799fef", size = 247510, upload-time = "2024-10-20T22:57:18.925Z" }, - { url = "https://files.pythonhosted.org/packages/8f/c3/4fa1eb412bb288ff6bfcc163c11700ff06e02c5fad8513817186e460ed43/coverage-7.6.4-cp313-cp313t-win32.whl", hash = "sha256:b8d3a03d9bfcaf5b0141d07a88456bb6a4c3ce55c080712fec8418ef3610230e", size = 210353, upload-time = "2024-10-20T22:57:20.891Z" }, - { url = "https://files.pythonhosted.org/packages/7e/77/03fc2979d1538884d921c2013075917fc927f41cd8526909852fe4494112/coverage-7.6.4-cp313-cp313t-win_amd64.whl", hash = "sha256:f3ddf056d3ebcf6ce47bdaf56142af51bb7fad09e4af310241e9db7a3a8022e1", size = 211502, upload-time = "2024-10-20T22:57:22.21Z" }, - { url = "https://files.pythonhosted.org/packages/cc/56/e1d75e8981a2a92c2a777e67c26efa96c66da59d645423146eb9ff3a851b/coverage-7.6.4-pp39.pp310-none-any.whl", hash = "sha256:3c65d37f3a9ebb703e710befdc489a38683a5b152242664b973a7b7b22348a4e", size = 198954, upload-time = "2024-10-20T22:57:38.28Z" }, + { url = "https://files.pythonhosted.org/packages/a8/1d/2e64b43d978b5bd184e0756a41415597dfef30fcbd90b747474bd749d45f/coverage-7.10.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:70e7bfbd57126b5554aa482691145f798d7df77489a177a6bef80de78860a356", size = 217025, upload-time = "2025-08-29T15:32:57.169Z" }, + { url = "https://files.pythonhosted.org/packages/23/62/b1e0f513417c02cc10ef735c3ee5186df55f190f70498b3702d516aad06f/coverage-7.10.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e41be6f0f19da64af13403e52f2dec38bbc2937af54df8ecef10850ff8d35301", size = 217419, upload-time = "2025-08-29T15:32:59.908Z" }, + { url = "https://files.pythonhosted.org/packages/e7/16/b800640b7a43e7c538429e4d7223e0a94fd72453a1a048f70bf766f12e96/coverage-7.10.6-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c61fc91ab80b23f5fddbee342d19662f3d3328173229caded831aa0bd7595460", size = 244180, upload-time = "2025-08-29T15:33:01.608Z" }, + { url = "https://files.pythonhosted.org/packages/fb/6f/5e03631c3305cad187eaf76af0b559fff88af9a0b0c180d006fb02413d7a/coverage-7.10.6-cp310-cp310-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10356fdd33a7cc06e8051413140bbdc6f972137508a3572e3f59f805cd2832fd", size = 245992, upload-time = "2025-08-29T15:33:03.239Z" }, + { url = "https://files.pythonhosted.org/packages/eb/a1/f30ea0fb400b080730125b490771ec62b3375789f90af0bb68bfb8a921d7/coverage-7.10.6-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:80b1695cf7c5ebe7b44bf2521221b9bb8cdf69b1f24231149a7e3eb1ae5fa2fb", size = 247851, upload-time = "2025-08-29T15:33:04.603Z" }, + { url = "https://files.pythonhosted.org/packages/02/8e/cfa8fee8e8ef9a6bb76c7bef039f3302f44e615d2194161a21d3d83ac2e9/coverage-7.10.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:2e4c33e6378b9d52d3454bd08847a8651f4ed23ddbb4a0520227bd346382bbc6", size = 245891, upload-time = "2025-08-29T15:33:06.176Z" }, + { url = "https://files.pythonhosted.org/packages/93/a9/51be09b75c55c4f6c16d8d73a6a1d46ad764acca0eab48fa2ffaef5958fe/coverage-7.10.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:c8a3ec16e34ef980a46f60dc6ad86ec60f763c3f2fa0db6d261e6e754f72e945", size = 243909, upload-time = "2025-08-29T15:33:07.74Z" }, + { url = "https://files.pythonhosted.org/packages/e9/a6/ba188b376529ce36483b2d585ca7bdac64aacbe5aa10da5978029a9c94db/coverage-7.10.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7d79dabc0a56f5af990cc6da9ad1e40766e82773c075f09cc571e2076fef882e", size = 244786, upload-time = "2025-08-29T15:33:08.965Z" }, + { url = "https://files.pythonhosted.org/packages/d0/4c/37ed872374a21813e0d3215256180c9a382c3f5ced6f2e5da0102fc2fd3e/coverage-7.10.6-cp310-cp310-win32.whl", hash = "sha256:86b9b59f2b16e981906e9d6383eb6446d5b46c278460ae2c36487667717eccf1", size = 219521, upload-time = "2025-08-29T15:33:10.599Z" }, + { url = "https://files.pythonhosted.org/packages/8e/36/9311352fdc551dec5b973b61f4e453227ce482985a9368305880af4f85dd/coverage-7.10.6-cp310-cp310-win_amd64.whl", hash = "sha256:e132b9152749bd33534e5bd8565c7576f135f157b4029b975e15ee184325f528", size = 220417, upload-time = "2025-08-29T15:33:11.907Z" }, + { url = "https://files.pythonhosted.org/packages/d4/16/2bea27e212c4980753d6d563a0803c150edeaaddb0771a50d2afc410a261/coverage-7.10.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c706db3cabb7ceef779de68270150665e710b46d56372455cd741184f3868d8f", size = 217129, upload-time = "2025-08-29T15:33:13.575Z" }, + { url = "https://files.pythonhosted.org/packages/2a/51/e7159e068831ab37e31aac0969d47b8c5ee25b7d307b51e310ec34869315/coverage-7.10.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8e0c38dc289e0508ef68ec95834cb5d2e96fdbe792eaccaa1bccac3966bbadcc", size = 217532, upload-time = "2025-08-29T15:33:14.872Z" }, + { url = "https://files.pythonhosted.org/packages/e7/c0/246ccbea53d6099325d25cd208df94ea435cd55f0db38099dd721efc7a1f/coverage-7.10.6-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:752a3005a1ded28f2f3a6e8787e24f28d6abe176ca64677bcd8d53d6fe2ec08a", size = 247931, upload-time = "2025-08-29T15:33:16.142Z" }, + { url = "https://files.pythonhosted.org/packages/7d/fb/7435ef8ab9b2594a6e3f58505cc30e98ae8b33265d844007737946c59389/coverage-7.10.6-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:689920ecfd60f992cafca4f5477d55720466ad2c7fa29bb56ac8d44a1ac2b47a", size = 249864, upload-time = "2025-08-29T15:33:17.434Z" }, + { url = "https://files.pythonhosted.org/packages/51/f8/d9d64e8da7bcddb094d511154824038833c81e3a039020a9d6539bf303e9/coverage-7.10.6-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec98435796d2624d6905820a42f82149ee9fc4f2d45c2c5bc5a44481cc50db62", size = 251969, upload-time = "2025-08-29T15:33:18.822Z" }, + { url = "https://files.pythonhosted.org/packages/43/28/c43ba0ef19f446d6463c751315140d8f2a521e04c3e79e5c5fe211bfa430/coverage-7.10.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b37201ce4a458c7a758ecc4efa92fa8ed783c66e0fa3c42ae19fc454a0792153", size = 249659, upload-time = "2025-08-29T15:33:20.407Z" }, + { url = "https://files.pythonhosted.org/packages/79/3e/53635bd0b72beaacf265784508a0b386defc9ab7fad99ff95f79ce9db555/coverage-7.10.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:2904271c80898663c810a6b067920a61dd8d38341244a3605bd31ab55250dad5", size = 247714, upload-time = "2025-08-29T15:33:21.751Z" }, + { url = "https://files.pythonhosted.org/packages/4c/55/0964aa87126624e8c159e32b0bc4e84edef78c89a1a4b924d28dd8265625/coverage-7.10.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5aea98383463d6e1fa4e95416d8de66f2d0cb588774ee20ae1b28df826bcb619", size = 248351, upload-time = "2025-08-29T15:33:23.105Z" }, + { url = "https://files.pythonhosted.org/packages/eb/ab/6cfa9dc518c6c8e14a691c54e53a9433ba67336c760607e299bfcf520cb1/coverage-7.10.6-cp311-cp311-win32.whl", hash = "sha256:e3fb1fa01d3598002777dd259c0c2e6d9d5e10e7222976fc8e03992f972a2cba", size = 219562, upload-time = "2025-08-29T15:33:24.717Z" }, + { url = "https://files.pythonhosted.org/packages/5b/18/99b25346690cbc55922e7cfef06d755d4abee803ef335baff0014268eff4/coverage-7.10.6-cp311-cp311-win_amd64.whl", hash = "sha256:f35ed9d945bece26553d5b4c8630453169672bea0050a564456eb88bdffd927e", size = 220453, upload-time = "2025-08-29T15:33:26.482Z" }, + { url = "https://files.pythonhosted.org/packages/d8/ed/81d86648a07ccb124a5cf1f1a7788712b8d7216b593562683cd5c9b0d2c1/coverage-7.10.6-cp311-cp311-win_arm64.whl", hash = "sha256:99e1a305c7765631d74b98bf7dbf54eeea931f975e80f115437d23848ee8c27c", size = 219127, upload-time = "2025-08-29T15:33:27.777Z" }, + { url = "https://files.pythonhosted.org/packages/26/06/263f3305c97ad78aab066d116b52250dd316e74fcc20c197b61e07eb391a/coverage-7.10.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5b2dd6059938063a2c9fee1af729d4f2af28fd1a545e9b7652861f0d752ebcea", size = 217324, upload-time = "2025-08-29T15:33:29.06Z" }, + { url = "https://files.pythonhosted.org/packages/e9/60/1e1ded9a4fe80d843d7d53b3e395c1db3ff32d6c301e501f393b2e6c1c1f/coverage-7.10.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:388d80e56191bf846c485c14ae2bc8898aa3124d9d35903fef7d907780477634", size = 217560, upload-time = "2025-08-29T15:33:30.748Z" }, + { url = "https://files.pythonhosted.org/packages/b8/25/52136173c14e26dfed8b106ed725811bb53c30b896d04d28d74cb64318b3/coverage-7.10.6-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:90cb5b1a4670662719591aa92d0095bb41714970c0b065b02a2610172dbf0af6", size = 249053, upload-time = "2025-08-29T15:33:32.041Z" }, + { url = "https://files.pythonhosted.org/packages/cb/1d/ae25a7dc58fcce8b172d42ffe5313fc267afe61c97fa872b80ee72d9515a/coverage-7.10.6-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:961834e2f2b863a0e14260a9a273aff07ff7818ab6e66d2addf5628590c628f9", size = 251802, upload-time = "2025-08-29T15:33:33.625Z" }, + { url = "https://files.pythonhosted.org/packages/f5/7a/1f561d47743710fe996957ed7c124b421320f150f1d38523d8d9102d3e2a/coverage-7.10.6-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf9a19f5012dab774628491659646335b1928cfc931bf8d97b0d5918dd58033c", size = 252935, upload-time = "2025-08-29T15:33:34.909Z" }, + { url = "https://files.pythonhosted.org/packages/6c/ad/8b97cd5d28aecdfde792dcbf646bac141167a5cacae2cd775998b45fabb5/coverage-7.10.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:99c4283e2a0e147b9c9cc6bc9c96124de9419d6044837e9799763a0e29a7321a", size = 250855, upload-time = "2025-08-29T15:33:36.922Z" }, + { url = "https://files.pythonhosted.org/packages/33/6a/95c32b558d9a61858ff9d79580d3877df3eb5bc9eed0941b1f187c89e143/coverage-7.10.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:282b1b20f45df57cc508c1e033403f02283adfb67d4c9c35a90281d81e5c52c5", size = 248974, upload-time = "2025-08-29T15:33:38.175Z" }, + { url = "https://files.pythonhosted.org/packages/0d/9c/8ce95dee640a38e760d5b747c10913e7a06554704d60b41e73fdea6a1ffd/coverage-7.10.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8cdbe264f11afd69841bd8c0d83ca10b5b32853263ee62e6ac6a0ab63895f972", size = 250409, upload-time = "2025-08-29T15:33:39.447Z" }, + { url = "https://files.pythonhosted.org/packages/04/12/7a55b0bdde78a98e2eb2356771fd2dcddb96579e8342bb52aa5bc52e96f0/coverage-7.10.6-cp312-cp312-win32.whl", hash = "sha256:a517feaf3a0a3eca1ee985d8373135cfdedfbba3882a5eab4362bda7c7cf518d", size = 219724, upload-time = "2025-08-29T15:33:41.172Z" }, + { url = "https://files.pythonhosted.org/packages/36/4a/32b185b8b8e327802c9efce3d3108d2fe2d9d31f153a0f7ecfd59c773705/coverage-7.10.6-cp312-cp312-win_amd64.whl", hash = "sha256:856986eadf41f52b214176d894a7de05331117f6035a28ac0016c0f63d887629", size = 220536, upload-time = "2025-08-29T15:33:42.524Z" }, + { url = "https://files.pythonhosted.org/packages/08/3a/d5d8dc703e4998038c3099eaf77adddb00536a3cec08c8dcd556a36a3eb4/coverage-7.10.6-cp312-cp312-win_arm64.whl", hash = "sha256:acf36b8268785aad739443fa2780c16260ee3fa09d12b3a70f772ef100939d80", size = 219171, upload-time = "2025-08-29T15:33:43.974Z" }, + { url = "https://files.pythonhosted.org/packages/bd/e7/917e5953ea29a28c1057729c1d5af9084ab6d9c66217523fd0e10f14d8f6/coverage-7.10.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ffea0575345e9ee0144dfe5701aa17f3ba546f8c3bb48db62ae101afb740e7d6", size = 217351, upload-time = "2025-08-29T15:33:45.438Z" }, + { url = "https://files.pythonhosted.org/packages/eb/86/2e161b93a4f11d0ea93f9bebb6a53f113d5d6e416d7561ca41bb0a29996b/coverage-7.10.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:95d91d7317cde40a1c249d6b7382750b7e6d86fad9d8eaf4fa3f8f44cf171e80", size = 217600, upload-time = "2025-08-29T15:33:47.269Z" }, + { url = "https://files.pythonhosted.org/packages/0e/66/d03348fdd8df262b3a7fb4ee5727e6e4936e39e2f3a842e803196946f200/coverage-7.10.6-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3e23dd5408fe71a356b41baa82892772a4cefcf758f2ca3383d2aa39e1b7a003", size = 248600, upload-time = "2025-08-29T15:33:48.953Z" }, + { url = "https://files.pythonhosted.org/packages/73/dd/508420fb47d09d904d962f123221bc249f64b5e56aa93d5f5f7603be475f/coverage-7.10.6-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0f3f56e4cb573755e96a16501a98bf211f100463d70275759e73f3cbc00d4f27", size = 251206, upload-time = "2025-08-29T15:33:50.697Z" }, + { url = "https://files.pythonhosted.org/packages/e9/1f/9020135734184f439da85c70ea78194c2730e56c2d18aee6e8ff1719d50d/coverage-7.10.6-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:db4a1d897bbbe7339946ffa2fe60c10cc81c43fab8b062d3fcb84188688174a4", size = 252478, upload-time = "2025-08-29T15:33:52.303Z" }, + { url = "https://files.pythonhosted.org/packages/a4/a4/3d228f3942bb5a2051fde28c136eea23a761177dc4ff4ef54533164ce255/coverage-7.10.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d8fd7879082953c156d5b13c74aa6cca37f6a6f4747b39538504c3f9c63d043d", size = 250637, upload-time = "2025-08-29T15:33:53.67Z" }, + { url = "https://files.pythonhosted.org/packages/36/e3/293dce8cdb9a83de971637afc59b7190faad60603b40e32635cbd15fbf61/coverage-7.10.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:28395ca3f71cd103b8c116333fa9db867f3a3e1ad6a084aa3725ae002b6583bc", size = 248529, upload-time = "2025-08-29T15:33:55.022Z" }, + { url = "https://files.pythonhosted.org/packages/90/26/64eecfa214e80dd1d101e420cab2901827de0e49631d666543d0e53cf597/coverage-7.10.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:61c950fc33d29c91b9e18540e1aed7d9f6787cc870a3e4032493bbbe641d12fc", size = 250143, upload-time = "2025-08-29T15:33:56.386Z" }, + { url = "https://files.pythonhosted.org/packages/3e/70/bd80588338f65ea5b0d97e424b820fb4068b9cfb9597fbd91963086e004b/coverage-7.10.6-cp313-cp313-win32.whl", hash = "sha256:160c00a5e6b6bdf4e5984b0ef21fc860bc94416c41b7df4d63f536d17c38902e", size = 219770, upload-time = "2025-08-29T15:33:58.063Z" }, + { url = "https://files.pythonhosted.org/packages/a7/14/0b831122305abcc1060c008f6c97bbdc0a913ab47d65070a01dc50293c2b/coverage-7.10.6-cp313-cp313-win_amd64.whl", hash = "sha256:628055297f3e2aa181464c3808402887643405573eb3d9de060d81531fa79d32", size = 220566, upload-time = "2025-08-29T15:33:59.766Z" }, + { url = "https://files.pythonhosted.org/packages/83/c6/81a83778c1f83f1a4a168ed6673eeedc205afb562d8500175292ca64b94e/coverage-7.10.6-cp313-cp313-win_arm64.whl", hash = "sha256:df4ec1f8540b0bcbe26ca7dd0f541847cc8a108b35596f9f91f59f0c060bfdd2", size = 219195, upload-time = "2025-08-29T15:34:01.191Z" }, + { url = "https://files.pythonhosted.org/packages/d7/1c/ccccf4bf116f9517275fa85047495515add43e41dfe8e0bef6e333c6b344/coverage-7.10.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:c9a8b7a34a4de3ed987f636f71881cd3b8339f61118b1aa311fbda12741bff0b", size = 218059, upload-time = "2025-08-29T15:34:02.91Z" }, + { url = "https://files.pythonhosted.org/packages/92/97/8a3ceff833d27c7492af4f39d5da6761e9ff624831db9e9f25b3886ddbca/coverage-7.10.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8dd5af36092430c2b075cee966719898f2ae87b636cefb85a653f1d0ba5d5393", size = 218287, upload-time = "2025-08-29T15:34:05.106Z" }, + { url = "https://files.pythonhosted.org/packages/92/d8/50b4a32580cf41ff0423777a2791aaf3269ab60c840b62009aec12d3970d/coverage-7.10.6-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b0353b0f0850d49ada66fdd7d0c7cdb0f86b900bb9e367024fd14a60cecc1e27", size = 259625, upload-time = "2025-08-29T15:34:06.575Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7e/6a7df5a6fb440a0179d94a348eb6616ed4745e7df26bf2a02bc4db72c421/coverage-7.10.6-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d6b9ae13d5d3e8aeca9ca94198aa7b3ebbc5acfada557d724f2a1f03d2c0b0df", size = 261801, upload-time = "2025-08-29T15:34:08.006Z" }, + { url = "https://files.pythonhosted.org/packages/3a/4c/a270a414f4ed5d196b9d3d67922968e768cd971d1b251e1b4f75e9362f75/coverage-7.10.6-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:675824a363cc05781b1527b39dc2587b8984965834a748177ee3c37b64ffeafb", size = 264027, upload-time = "2025-08-29T15:34:09.806Z" }, + { url = "https://files.pythonhosted.org/packages/9c/8b/3210d663d594926c12f373c5370bf1e7c5c3a427519a8afa65b561b9a55c/coverage-7.10.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:692d70ea725f471a547c305f0d0fc6a73480c62fb0da726370c088ab21aed282", size = 261576, upload-time = "2025-08-29T15:34:11.585Z" }, + { url = "https://files.pythonhosted.org/packages/72/d0/e1961eff67e9e1dba3fc5eb7a4caf726b35a5b03776892da8d79ec895775/coverage-7.10.6-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:851430a9a361c7a8484a36126d1d0ff8d529d97385eacc8dfdc9bfc8c2d2cbe4", size = 259341, upload-time = "2025-08-29T15:34:13.159Z" }, + { url = "https://files.pythonhosted.org/packages/3a/06/d6478d152cd189b33eac691cba27a40704990ba95de49771285f34a5861e/coverage-7.10.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d9369a23186d189b2fc95cc08b8160ba242057e887d766864f7adf3c46b2df21", size = 260468, upload-time = "2025-08-29T15:34:14.571Z" }, + { url = "https://files.pythonhosted.org/packages/ed/73/737440247c914a332f0b47f7598535b29965bf305e19bbc22d4c39615d2b/coverage-7.10.6-cp313-cp313t-win32.whl", hash = "sha256:92be86fcb125e9bda0da7806afd29a3fd33fdf58fba5d60318399adf40bf37d0", size = 220429, upload-time = "2025-08-29T15:34:16.394Z" }, + { url = "https://files.pythonhosted.org/packages/bd/76/b92d3214740f2357ef4a27c75a526eb6c28f79c402e9f20a922c295c05e2/coverage-7.10.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6b3039e2ca459a70c79523d39347d83b73f2f06af5624905eba7ec34d64d80b5", size = 221493, upload-time = "2025-08-29T15:34:17.835Z" }, + { url = "https://files.pythonhosted.org/packages/fc/8e/6dcb29c599c8a1f654ec6cb68d76644fe635513af16e932d2d4ad1e5ac6e/coverage-7.10.6-cp313-cp313t-win_arm64.whl", hash = "sha256:3fb99d0786fe17b228eab663d16bee2288e8724d26a199c29325aac4b0319b9b", size = 219757, upload-time = "2025-08-29T15:34:19.248Z" }, + { url = "https://files.pythonhosted.org/packages/d3/aa/76cf0b5ec00619ef208da4689281d48b57f2c7fde883d14bf9441b74d59f/coverage-7.10.6-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:6008a021907be8c4c02f37cdc3ffb258493bdebfeaf9a839f9e71dfdc47b018e", size = 217331, upload-time = "2025-08-29T15:34:20.846Z" }, + { url = "https://files.pythonhosted.org/packages/65/91/8e41b8c7c505d398d7730206f3cbb4a875a35ca1041efc518051bfce0f6b/coverage-7.10.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5e75e37f23eb144e78940b40395b42f2321951206a4f50e23cfd6e8a198d3ceb", size = 217607, upload-time = "2025-08-29T15:34:22.433Z" }, + { url = "https://files.pythonhosted.org/packages/87/7f/f718e732a423d442e6616580a951b8d1ec3575ea48bcd0e2228386805e79/coverage-7.10.6-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0f7cb359a448e043c576f0da00aa8bfd796a01b06aa610ca453d4dde09cc1034", size = 248663, upload-time = "2025-08-29T15:34:24.425Z" }, + { url = "https://files.pythonhosted.org/packages/e6/52/c1106120e6d801ac03e12b5285e971e758e925b6f82ee9b86db3aa10045d/coverage-7.10.6-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c68018e4fc4e14b5668f1353b41ccf4bc83ba355f0e1b3836861c6f042d89ac1", size = 251197, upload-time = "2025-08-29T15:34:25.906Z" }, + { url = "https://files.pythonhosted.org/packages/3d/ec/3a8645b1bb40e36acde9c0609f08942852a4af91a937fe2c129a38f2d3f5/coverage-7.10.6-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cd4b2b0707fc55afa160cd5fc33b27ccbf75ca11d81f4ec9863d5793fc6df56a", size = 252551, upload-time = "2025-08-29T15:34:27.337Z" }, + { url = "https://files.pythonhosted.org/packages/a1/70/09ecb68eeb1155b28a1d16525fd3a9b65fbe75337311a99830df935d62b6/coverage-7.10.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4cec13817a651f8804a86e4f79d815b3b28472c910e099e4d5a0e8a3b6a1d4cb", size = 250553, upload-time = "2025-08-29T15:34:29.065Z" }, + { url = "https://files.pythonhosted.org/packages/c6/80/47df374b893fa812e953b5bc93dcb1427a7b3d7a1a7d2db33043d17f74b9/coverage-7.10.6-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f2a6a8e06bbda06f78739f40bfb56c45d14eb8249d0f0ea6d4b3d48e1f7c695d", size = 248486, upload-time = "2025-08-29T15:34:30.897Z" }, + { url = "https://files.pythonhosted.org/packages/4a/65/9f98640979ecee1b0d1a7164b589de720ddf8100d1747d9bbdb84be0c0fb/coverage-7.10.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:081b98395ced0d9bcf60ada7661a0b75f36b78b9d7e39ea0790bb4ed8da14747", size = 249981, upload-time = "2025-08-29T15:34:32.365Z" }, + { url = "https://files.pythonhosted.org/packages/1f/55/eeb6603371e6629037f47bd25bef300387257ed53a3c5fdb159b7ac8c651/coverage-7.10.6-cp314-cp314-win32.whl", hash = "sha256:6937347c5d7d069ee776b2bf4e1212f912a9f1f141a429c475e6089462fcecc5", size = 220054, upload-time = "2025-08-29T15:34:34.124Z" }, + { url = "https://files.pythonhosted.org/packages/15/d1/a0912b7611bc35412e919a2cd59ae98e7ea3b475e562668040a43fb27897/coverage-7.10.6-cp314-cp314-win_amd64.whl", hash = "sha256:adec1d980fa07e60b6ef865f9e5410ba760e4e1d26f60f7e5772c73b9a5b0713", size = 220851, upload-time = "2025-08-29T15:34:35.651Z" }, + { url = "https://files.pythonhosted.org/packages/ef/2d/11880bb8ef80a45338e0b3e0725e4c2d73ffbb4822c29d987078224fd6a5/coverage-7.10.6-cp314-cp314-win_arm64.whl", hash = "sha256:a80f7aef9535442bdcf562e5a0d5a5538ce8abe6bb209cfbf170c462ac2c2a32", size = 219429, upload-time = "2025-08-29T15:34:37.16Z" }, + { url = "https://files.pythonhosted.org/packages/83/c0/1f00caad775c03a700146f55536ecd097a881ff08d310a58b353a1421be0/coverage-7.10.6-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:0de434f4fbbe5af4fa7989521c655c8c779afb61c53ab561b64dcee6149e4c65", size = 218080, upload-time = "2025-08-29T15:34:38.919Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c4/b1c5d2bd7cc412cbeb035e257fd06ed4e3e139ac871d16a07434e145d18d/coverage-7.10.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6e31b8155150c57e5ac43ccd289d079eb3f825187d7c66e755a055d2c85794c6", size = 218293, upload-time = "2025-08-29T15:34:40.425Z" }, + { url = "https://files.pythonhosted.org/packages/3f/07/4468d37c94724bf6ec354e4ec2f205fda194343e3e85fd2e59cec57e6a54/coverage-7.10.6-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:98cede73eb83c31e2118ae8d379c12e3e42736903a8afcca92a7218e1f2903b0", size = 259800, upload-time = "2025-08-29T15:34:41.996Z" }, + { url = "https://files.pythonhosted.org/packages/82/d8/f8fb351be5fee31690cd8da768fd62f1cfab33c31d9f7baba6cd8960f6b8/coverage-7.10.6-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f863c08f4ff6b64fa8045b1e3da480f5374779ef187f07b82e0538c68cb4ff8e", size = 261965, upload-time = "2025-08-29T15:34:43.61Z" }, + { url = "https://files.pythonhosted.org/packages/e8/70/65d4d7cfc75c5c6eb2fed3ee5cdf420fd8ae09c4808723a89a81d5b1b9c3/coverage-7.10.6-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2b38261034fda87be356f2c3f42221fdb4171c3ce7658066ae449241485390d5", size = 264220, upload-time = "2025-08-29T15:34:45.387Z" }, + { url = "https://files.pythonhosted.org/packages/98/3c/069df106d19024324cde10e4ec379fe2fb978017d25e97ebee23002fbadf/coverage-7.10.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0e93b1476b79eae849dc3872faeb0bf7948fd9ea34869590bc16a2a00b9c82a7", size = 261660, upload-time = "2025-08-29T15:34:47.288Z" }, + { url = "https://files.pythonhosted.org/packages/fc/8a/2974d53904080c5dc91af798b3a54a4ccb99a45595cc0dcec6eb9616a57d/coverage-7.10.6-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:ff8a991f70f4c0cf53088abf1e3886edcc87d53004c7bb94e78650b4d3dac3b5", size = 259417, upload-time = "2025-08-29T15:34:48.779Z" }, + { url = "https://files.pythonhosted.org/packages/30/38/9616a6b49c686394b318974d7f6e08f38b8af2270ce7488e879888d1e5db/coverage-7.10.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ac765b026c9f33044419cbba1da913cfb82cca1b60598ac1c7a5ed6aac4621a0", size = 260567, upload-time = "2025-08-29T15:34:50.718Z" }, + { url = "https://files.pythonhosted.org/packages/76/16/3ed2d6312b371a8cf804abf4e14895b70e4c3491c6e53536d63fd0958a8d/coverage-7.10.6-cp314-cp314t-win32.whl", hash = "sha256:441c357d55f4936875636ef2cfb3bee36e466dcf50df9afbd398ce79dba1ebb7", size = 220831, upload-time = "2025-08-29T15:34:52.653Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e5/d38d0cb830abede2adb8b147770d2a3d0e7fecc7228245b9b1ae6c24930a/coverage-7.10.6-cp314-cp314t-win_amd64.whl", hash = "sha256:073711de3181b2e204e4870ac83a7c4853115b42e9cd4d145f2231e12d670930", size = 221950, upload-time = "2025-08-29T15:34:54.212Z" }, + { url = "https://files.pythonhosted.org/packages/f4/51/e48e550f6279349895b0ffcd6d2a690e3131ba3a7f4eafccc141966d4dea/coverage-7.10.6-cp314-cp314t-win_arm64.whl", hash = "sha256:137921f2bac5559334ba66122b753db6dc5d1cf01eb7b64eb412bb0d064ef35b", size = 219969, upload-time = "2025-08-29T15:34:55.83Z" }, + { url = "https://files.pythonhosted.org/packages/44/0c/50db5379b615854b5cf89146f8f5bd1d5a9693d7f3a987e269693521c404/coverage-7.10.6-py3-none-any.whl", hash = "sha256:92c4ecf6bf11b2e85fd4d8204814dc26e6a19f0c9d938c207c5cb0eadfcabbe3", size = 208986, upload-time = "2025-08-29T15:35:14.506Z" }, ] [package.optional-dependencies] @@ -2236,16 +2262,16 @@ wheels = [ [[package]] name = "pytest-cov" -version = "6.2.1" +version = "7.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "coverage", extra = ["toml"] }, { name = "pluggy" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/18/99/668cade231f434aaa59bbfbf49469068d2ddd945000621d3d165d2e7dd7b/pytest_cov-6.2.1.tar.gz", hash = "sha256:25cc6cc0a5358204b8108ecedc51a9b57b34cc6b8c967cc2c01a4e00d8a67da2", size = 69432, upload-time = "2025-06-12T10:47:47.684Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/f7/c933acc76f5208b3b00089573cf6a2bc26dc80a8aece8f52bb7d6b1855ca/pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1", size = 54328, upload-time = "2025-09-09T10:57:02.113Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/16/4ea354101abb1287856baa4af2732be351c7bee728065aed451b678153fd/pytest_cov-6.2.1-py3-none-any.whl", hash = "sha256:f5bc4c23f42f1cdd23c70b1dab1bbaef4fc505ba950d53e0081d0730dd7e86d5", size = 24644, upload-time = "2025-06-12T10:47:45.932Z" }, + { url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424, upload-time = "2025-09-09T10:57:00.695Z" }, ] [[package]] diff --git a/misc/release/archive-version.js b/misc/release/archive-version.js index 3ef4f58b1e..1a66963dad 100755 --- a/misc/release/archive-version.js +++ b/misc/release/archive-version.js @@ -10,7 +10,7 @@ if (!nextVersion) { const filename = './docs/static/archived-versions.json'; const oldVersions = JSON.parse(readFileSync(filename)); const newVersions = [ - { label: `v${nextVersion}`, url: `https://v${nextVersion}.archive.immich.app` }, + { label: `v${nextVersion}`, url: `https://docs.v${nextVersion}.archive.immich.app` }, ...oldVersions, ]; diff --git a/misc/release/pump-version.sh b/misc/release/pump-version.sh index 35ce9a1f33..65a2e70e50 100755 --- a/misc/release/pump-version.sh +++ b/misc/release/pump-version.sh @@ -80,7 +80,7 @@ if [ "$CURRENT_SERVER" != "$NEXT_SERVER" ]; then jq --arg version "$NEXT_SERVER" '.version = $version' e2e/package.json > e2e/package.json.tmp && mv e2e/package.json.tmp e2e/package.json pnpm install --frozen-lockfile --prefix e2e - uvx --from=toml-cli toml set --toml-path=pyproject.toml project.version "$SERVER_PUMP" + uvx --from=toml-cli toml set --toml-path=machine-learning/pyproject.toml project.version "$NEXT_SERVER" fi if [ "$CURRENT_MOBILE" != "$NEXT_MOBILE" ]; then diff --git a/mise.toml b/mise.toml index 7d4824de57..2f98f2e9d5 100644 --- a/mise.toml +++ b/mise.toml @@ -1,11 +1,10 @@ [tools] node = "22.19.0" flutter = "3.35.4" -pnpm = "10.14.0" -dart = "3.8.2" +pnpm = "10.15.1" [tools."github:CQLabs/homebrew-dcm"] -version = "1.31.4" +version = "1.30.0" bin = "dcm" postinstall = "chmod +x $MISE_TOOL_INSTALL_PATH/dcm" @@ -309,3 +308,205 @@ run = [ "mise run web:test --run", "mise run web:lint", ] + + +# mobile +[tasks."mobile:codegen:dart"] +alias = "mobile:codegen" +description = "Execute build_runner to auto-generate dart code" +dir = "mobile" +sources = [ + "pubspec.yaml", + "build.yaml", + "lib/**/*.dart", + "infrastructure/**/*.drift", +] +outputs = { auto = true } +run = "dart run build_runner build --delete-conflicting-outputs" + +[tasks."mobile:codegen:pigeon"] +alias = "mobile:pigeon" +description = "Generate pigeon platform code" +dir = "mobile" +depends = [ + "mobile:pigeon:native-sync", + "mobile:pigeon:thumbnail", + "mobile:pigeon:background-worker", + "mobile:pigeon:background-worker-lock", + "mobile:pigeon:connectivity", +] + +[tasks."mobile:codegen:translation"] +alias = "mobile:translation" +description = "Generate translations from i18n JSONs" +dir = "mobile" +run = [ + { task = "i18n:format-fix" }, + { tasks = [ + "mobile:i18n:loader", + "mobile:i18n:keys", + ] }, +] + +[tasks."mobile:codegen:app-icon"] +description = "Generate app icons" +dir = "mobile" +run = "flutter pub run flutter_launcher_icons:main" + +[tasks."mobile:codegen:splash"] +description = "Generate splash screen" +dir = "mobile" +run = "flutter pub run flutter_native_splash:create" + +[tasks."mobile:test"] +description = "Run mobile tests" +dir = "mobile" +run = "flutter test" + +[tasks."mobile:lint"] +description = "Analyze Dart code" +dir = "mobile" +depends = ["mobile:analyze:dart", "mobile:analyze:dcm"] + +[tasks."mobile:lint-fix"] +description = "Auto-fix Dart code" +dir = "mobile" +depends = ["mobile:analyze:fix:dart", "mobile:analyze:fix:dcm"] + +[tasks."mobile:format"] +description = "Format Dart code" +dir = "mobile" +run = "dart format --set-exit-if-changed $(find lib -name '*.dart' -not \\( -name '*.g.dart' -o -name '*.drift.dart' -o -name '*.gr.dart' \\))" + +[tasks."mobile:build:android"] +description = "Build Android release" +dir = "mobile" +run = "flutter build appbundle" + +[tasks."mobile:drift:migration"] +alias = "mobile:migration" +description = "Generate database migrations" +dir = "mobile" +run = "dart run drift_dev make-migrations" + + +# mobile internal tasks +[tasks."mobile:pigeon:native-sync"] +description = "Generate native sync API pigeon code" +dir = "mobile" +hide = true +sources = ["pigeon/native_sync_api.dart"] +outputs = [ + "lib/platform/native_sync_api.g.dart", + "ios/Runner/Sync/Messages.g.swift", + "android/app/src/main/kotlin/app/alextran/immich/sync/Messages.g.kt", +] +run = [ + "dart run pigeon --input pigeon/native_sync_api.dart", + "dart format lib/platform/native_sync_api.g.dart", +] + +[tasks."mobile:pigeon:thumbnail"] +description = "Generate thumbnail API pigeon code" +dir = "mobile" +hide = true +sources = ["pigeon/thumbnail_api.dart"] +outputs = [ + "lib/platform/thumbnail_api.g.dart", + "ios/Runner/Images/Thumbnails.g.swift", + "android/app/src/main/kotlin/app/alextran/immich/images/Thumbnails.g.kt", +] +run = [ + "dart run pigeon --input pigeon/thumbnail_api.dart", + "dart format lib/platform/thumbnail_api.g.dart", +] + +[tasks."mobile:pigeon:background-worker"] +description = "Generate background worker API pigeon code" +dir = "mobile" +hide = true +sources = ["pigeon/background_worker_api.dart"] +outputs = [ + "lib/platform/background_worker_api.g.dart", + "ios/Runner/Background/BackgroundWorker.g.swift", + "android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorker.g.kt", +] +run = [ + "dart run pigeon --input pigeon/background_worker_api.dart", + "dart format lib/platform/background_worker_api.g.dart", +] + +[tasks."mobile:pigeon:background-worker-lock"] +description = "Generate background worker lock API pigeon code" +dir = "mobile" +hide = true +sources = ["pigeon/background_worker_lock_api.dart"] +outputs = [ + "lib/platform/background_worker_lock_api.g.dart", + "android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorkerLock.g.kt", +] +run = [ + "dart run pigeon --input pigeon/background_worker_lock_api.dart", + "dart format lib/platform/background_worker_lock_api.g.dart", +] + +[tasks."mobile:pigeon:connectivity"] +description = "Generate connectivity API pigeon code" +dir = "mobile" +hide = true +sources = ["pigeon/connectivity_api.dart"] +outputs = [ + "lib/platform/connectivity_api.g.dart", + "ios/Runner/Connectivity/Connectivity.g.swift", + "android/app/src/main/kotlin/app/alextran/immich/connectivity/Connectivity.g.kt", +] +run = [ + "dart run pigeon --input pigeon/connectivity_api.dart", + "dart format lib/platform/connectivity_api.g.dart", +] + +[tasks."mobile:i18n:loader"] +description = "Generate i18n loader" +dir = "mobile" +hide = true +sources = ["i18n/"] +outputs = "lib/generated/codegen_loader.g.dart" +run = [ + "dart run easy_localization:generate -S ../i18n", + "dart format lib/generated/codegen_loader.g.dart", +] + +[tasks."mobile:i18n:keys"] +description = "Generate i18n keys" +dir = "mobile" +hide = true +sources = ["i18n/en.json"] +outputs = "lib/generated/intl_keys.g.dart" +run = [ + "dart run bin/generate_keys.dart", + "dart format lib/generated/intl_keys.g.dart", +] + +[tasks."mobile:analyze:dart"] +description = "Run Dart analysis" +dir = "mobile" +hide = true +run = "dart analyze --fatal-infos" + +[tasks."mobile:analyze:dcm"] +description = "Run Dart Code Metrics" +dir = "mobile" +hide = true +run = "dcm analyze lib --fatal-style --fatal-warnings" + +[tasks."mobile:analyze:fix:dart"] +description = "Auto-fix Dart analysis" +dir = "mobile" +hide = true +run = "dart fix --apply" + +[tasks."mobile:analyze:fix:dcm"] +description = "Auto-fix Dart Code Metrics" +dir = "mobile" +hide = true +run = "dcm fix lib" diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/MainActivity.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/MainActivity.kt index 4e811c8dfc..034f5ee72e 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/MainActivity.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/MainActivity.kt @@ -6,6 +6,7 @@ import android.os.ext.SdkExtensions import app.alextran.immich.background.BackgroundEngineLock import app.alextran.immich.background.BackgroundWorkerApiImpl import app.alextran.immich.background.BackgroundWorkerFgHostApi +import app.alextran.immich.background.BackgroundWorkerLockApi import app.alextran.immich.connectivity.ConnectivityApi import app.alextran.immich.connectivity.ConnectivityApiImpl import app.alextran.immich.images.ThumbnailApi @@ -24,11 +25,9 @@ class MainActivity : FlutterFragmentActivity() { companion object { fun registerPlugins(ctx: Context, flutterEngine: FlutterEngine) { - flutterEngine.plugins.add(BackgroundServicePlugin()) - flutterEngine.plugins.add(HttpSSLOptionsPlugin()) - flutterEngine.plugins.add(BackgroundEngineLock()) - val messenger = flutterEngine.dartExecutor.binaryMessenger + val backgroundEngineLockImpl = BackgroundEngineLock(ctx) + BackgroundWorkerLockApi.setUp(messenger, backgroundEngineLockImpl) val nativeSyncApiImpl = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R || SdkExtensions.getExtensionVersion(Build.VERSION_CODES.R) < 1) { NativeSyncApiImpl26(ctx) @@ -39,6 +38,10 @@ class MainActivity : FlutterFragmentActivity() { ThumbnailApi.setUp(messenger, ThumbnailsImpl(ctx)) BackgroundWorkerFgHostApi.setUp(messenger, BackgroundWorkerApiImpl(ctx)) ConnectivityApi.setUp(messenger, ConnectivityApiImpl(ctx)) + + flutterEngine.plugins.add(BackgroundServicePlugin()) + flutterEngine.plugins.add(HttpSSLOptionsPlugin()) + flutterEngine.plugins.add(backgroundEngineLockImpl) } } } diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundEngineLock.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundEngineLock.kt index 6d6f45a708..d8afe32b5c 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundEngineLock.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundEngineLock.kt @@ -1,33 +1,50 @@ package app.alextran.immich.background +import android.content.Context import android.util.Log -import androidx.work.WorkManager -import io.flutter.embedding.engine.FlutterEngineCache import io.flutter.embedding.engine.plugins.FlutterPlugin import java.util.concurrent.atomic.AtomicInteger private const val TAG = "BackgroundEngineLock" -class BackgroundEngineLock : FlutterPlugin { - companion object { - const val ENGINE_CACHE_KEY = "immich::background_worker::engine" - var engineCount = AtomicInteger(0) - } +class BackgroundEngineLock(context: Context) : BackgroundWorkerLockApi, FlutterPlugin { + private val ctx: Context = context.applicationContext - override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { - // work manager task is running while the main app is opened, cancel the worker - if (engineCount.incrementAndGet() > 1 && FlutterEngineCache.getInstance() - .get(ENGINE_CACHE_KEY) != null - ) { - WorkManager.getInstance(binding.applicationContext) - .cancelUniqueWork(BackgroundWorkerApiImpl.BACKGROUND_WORKER_NAME) - FlutterEngineCache.getInstance().remove(ENGINE_CACHE_KEY) + companion object { + + private var engineCount = AtomicInteger(0) + + private fun checkAndEnforceBackgroundLock(ctx: Context) { + // work manager task is running while the main app is opened, cancel the worker + if (BackgroundWorkerPreferences(ctx).isLocked() && + engineCount.get() > 1 && + BackgroundWorkerApiImpl.isBackgroundWorkerRunning() + ) { + Log.i(TAG, "Background worker is locked, cancelling the background worker") + BackgroundWorkerApiImpl.cancelBackgroundWorker(ctx) + } + } } - Log.i(TAG, "Flutter engine attached. Attached Engines count: $engineCount") - } - override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { - engineCount.decrementAndGet() - Log.i(TAG, "Flutter engine detached. Attached Engines count: $engineCount") - } + override fun lock() { + BackgroundWorkerPreferences(ctx).setLocked(true) + checkAndEnforceBackgroundLock(ctx) + Log.i(TAG, "Background worker is locked") + } + + override fun unlock() { + BackgroundWorkerPreferences(ctx).setLocked(false) + Log.i(TAG, "Background worker is unlocked") + } + + override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) { + checkAndEnforceBackgroundLock(binding.applicationContext) + engineCount.incrementAndGet() + Log.i(TAG, "Flutter engine attached. Attached Engines count: $engineCount") + } + + override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) { + engineCount.decrementAndGet() + Log.i(TAG, "Flutter engine detached. Attached Engines count: $engineCount") + } } diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorker.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorker.kt index 7d30319af4..71d9f5ffe3 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorker.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorker.kt @@ -76,9 +76,7 @@ class BackgroundWorker(context: Context, params: WorkerParameters) : loader.ensureInitializationCompleteAsync(ctx, null, Handler(Looper.getMainLooper())) { engine = FlutterEngine(ctx) - FlutterEngineCache.getInstance().remove(BackgroundEngineLock.ENGINE_CACHE_KEY); - FlutterEngineCache.getInstance() - .put(BackgroundEngineLock.ENGINE_CACHE_KEY, engine!!) + FlutterEngineCache.getInstance().put(BackgroundWorkerApiImpl.ENGINE_CACHE_KEY, engine!!) // Register custom plugins MainActivity.registerPlugins(ctx, engine!!) @@ -192,9 +190,9 @@ class BackgroundWorker(context: Context, params: WorkerParameters) : isComplete = true engine?.destroy() engine = null - FlutterEngineCache.getInstance().remove(BackgroundEngineLock.ENGINE_CACHE_KEY); flutterApi = null notificationManager.cancel(NOTIFICATION_ID) + FlutterEngineCache.getInstance().remove(BackgroundWorkerApiImpl.ENGINE_CACHE_KEY) waitForForegroundPromotion() completionHandler.set(success) } diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorkerApiImpl.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorkerApiImpl.kt index 259e3244bc..78f2e9e461 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorkerApiImpl.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorkerApiImpl.kt @@ -1,7 +1,6 @@ package app.alextran.immich.background import android.content.Context -import android.content.SharedPreferences import android.provider.MediaStore import android.util.Log import androidx.work.BackoffPolicy @@ -9,6 +8,7 @@ import androidx.work.Constraints import androidx.work.ExistingWorkPolicy import androidx.work.OneTimeWorkRequest import androidx.work.WorkManager +import io.flutter.embedding.engine.FlutterEngineCache import java.util.concurrent.TimeUnit private const val TAG = "BackgroundWorkerApiImpl" @@ -34,8 +34,10 @@ class BackgroundWorkerApiImpl(context: Context) : BackgroundWorkerFgHostApi { } companion object { - const val BACKGROUND_WORKER_NAME = "immich/BackgroundWorkerV1" + private const val BACKGROUND_WORKER_NAME = "immich/BackgroundWorkerV1" private const val OBSERVER_WORKER_NAME = "immich/MediaObserverV1" + const val ENGINE_CACHE_KEY = "immich::background_worker::engine" + fun enqueueMediaObserver(ctx: Context) { val settings = BackgroundWorkerPreferences(ctx).getSettings() @@ -45,7 +47,7 @@ class BackgroundWorkerApiImpl(context: Context) : BackgroundWorkerFgHostApi { addContentUriTrigger(MediaStore.Video.Media.INTERNAL_CONTENT_URI, true) addContentUriTrigger(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, true) setTriggerContentUpdateDelay(settings.minimumDelaySeconds, TimeUnit.SECONDS) - setTriggerContentMaxDelay(settings.minimumDelaySeconds * 10, TimeUnit.MINUTES) + setTriggerContentMaxDelay(settings.minimumDelaySeconds * 10, TimeUnit.SECONDS) setRequiresCharging(settings.requiresCharging) }.build() @@ -73,35 +75,18 @@ class BackgroundWorkerApiImpl(context: Context) : BackgroundWorkerFgHostApi { Log.i(TAG, "Enqueued background worker with name: $BACKGROUND_WORKER_NAME") } - } -} -private class BackgroundWorkerPreferences(private val ctx: Context) { - companion object { - private const val SHARED_PREF_NAME = "Immich::BackgroundWorker" - private const val SHARED_PREF_MIN_DELAY_KEY = "BackgroundWorker::minDelaySeconds" - private const val SHARED_PREF_REQUIRE_CHARGING_KEY = "BackgroundWorker::requireCharging" + fun isBackgroundWorkerRunning(): Boolean { + // Easier to check if the engine is cached as we always cache the engine when starting the worker + // and remove it when the worker is finished + return FlutterEngineCache.getInstance().get(ENGINE_CACHE_KEY) != null + } - private const val DEFAULT_MIN_DELAY_SECONDS = 30L - private const val DEFAULT_REQUIRE_CHARGING = false - } + fun cancelBackgroundWorker(ctx: Context) { + WorkManager.getInstance(ctx).cancelUniqueWork(BACKGROUND_WORKER_NAME) + FlutterEngineCache.getInstance().remove(ENGINE_CACHE_KEY) - private val sp: SharedPreferences by lazy { - ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE) - } - - fun updateSettings(settings: BackgroundWorkerSettings) { - sp.edit().apply { - putLong(SHARED_PREF_MIN_DELAY_KEY, settings.minimumDelaySeconds) - putBoolean(SHARED_PREF_REQUIRE_CHARGING_KEY, settings.requiresCharging) - apply() + Log.i(TAG, "Cancelled background upload task") } } - - fun getSettings(): BackgroundWorkerSettings { - return BackgroundWorkerSettings( - minimumDelaySeconds = sp.getLong(SHARED_PREF_MIN_DELAY_KEY, DEFAULT_MIN_DELAY_SECONDS), - requiresCharging = sp.getBoolean(SHARED_PREF_REQUIRE_CHARGING_KEY, DEFAULT_REQUIRE_CHARGING), - ) - } } diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorkerLock.g.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorkerLock.g.kt new file mode 100644 index 0000000000..3d00bafba2 --- /dev/null +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorkerLock.g.kt @@ -0,0 +1,95 @@ +// Autogenerated from Pigeon (v26.0.0), do not edit directly. +// See also: https://pub.dev/packages/pigeon +@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass") + +package app.alextran.immich.background + +import android.util.Log +import io.flutter.plugin.common.BasicMessageChannel +import io.flutter.plugin.common.BinaryMessenger +import io.flutter.plugin.common.EventChannel +import io.flutter.plugin.common.MessageCodec +import io.flutter.plugin.common.StandardMethodCodec +import io.flutter.plugin.common.StandardMessageCodec +import java.io.ByteArrayOutputStream +import java.nio.ByteBuffer +private object BackgroundWorkerLockPigeonUtils { + + fun wrapResult(result: Any?): List { + return listOf(result) + } + + fun wrapError(exception: Throwable): List { + return if (exception is FlutterError) { + listOf( + exception.code, + exception.message, + exception.details + ) + } else { + listOf( + exception.javaClass.simpleName, + exception.toString(), + "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception) + ) + } + } +} +private open class BackgroundWorkerLockPigeonCodec : StandardMessageCodec() { + override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { + return super.readValueOfType(type, buffer) + } + override fun writeValue(stream: ByteArrayOutputStream, value: Any?) { + super.writeValue(stream, value) + } +} + +/** Generated interface from Pigeon that represents a handler of messages from Flutter. */ +interface BackgroundWorkerLockApi { + fun lock() + fun unlock() + + companion object { + /** The codec used by BackgroundWorkerLockApi. */ + val codec: MessageCodec by lazy { + BackgroundWorkerLockPigeonCodec() + } + /** Sets up an instance of `BackgroundWorkerLockApi` to handle messages through the `binaryMessenger`. */ + @JvmOverloads + fun setUp(binaryMessenger: BinaryMessenger, api: BackgroundWorkerLockApi?, messageChannelSuffix: String = "") { + val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.BackgroundWorkerLockApi.lock$separatedMessageChannelSuffix", codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + val wrapped: List = try { + api.lock() + listOf(null) + } catch (exception: Throwable) { + BackgroundWorkerLockPigeonUtils.wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.immich_mobile.BackgroundWorkerLockApi.unlock$separatedMessageChannelSuffix", codec) + if (api != null) { + channel.setMessageHandler { _, reply -> + val wrapped: List = try { + api.unlock() + listOf(null) + } catch (exception: Throwable) { + BackgroundWorkerLockPigeonUtils.wrapError(exception) + } + reply.reply(wrapped) + } + } else { + channel.setMessageHandler(null) + } + } + } + } +} diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorkerPreferences.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorkerPreferences.kt new file mode 100644 index 0000000000..cfceb06c1d --- /dev/null +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorkerPreferences.kt @@ -0,0 +1,51 @@ +package app.alextran.immich.background + +import android.content.Context +import android.content.SharedPreferences +import androidx.core.content.edit + +class BackgroundWorkerPreferences(private val ctx: Context) { + companion object { + const val SHARED_PREF_NAME = "Immich::BackgroundWorker" + private const val SHARED_PREF_MIN_DELAY_KEY = "BackgroundWorker::minDelaySeconds" + private const val SHARED_PREF_REQUIRE_CHARGING_KEY = "BackgroundWorker::requireCharging" + private const val SHARED_PREF_LOCK_KEY = "BackgroundWorker::isLocked" + + private const val DEFAULT_MIN_DELAY_SECONDS = 30L + private const val DEFAULT_REQUIRE_CHARGING = false + } + + private val sp: SharedPreferences by lazy { + ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE) + } + + fun updateSettings(settings: BackgroundWorkerSettings) { + sp.edit { + putLong(SHARED_PREF_MIN_DELAY_KEY, settings.minimumDelaySeconds) + putBoolean(SHARED_PREF_REQUIRE_CHARGING_KEY, settings.requiresCharging) + } + } + + fun getSettings(): BackgroundWorkerSettings { + val delaySeconds = sp.getLong(SHARED_PREF_MIN_DELAY_KEY, DEFAULT_MIN_DELAY_SECONDS) + + return BackgroundWorkerSettings( + minimumDelaySeconds = if (delaySeconds >= 1000) delaySeconds / 1000 else delaySeconds, + requiresCharging = sp.getBoolean( + SHARED_PREF_REQUIRE_CHARGING_KEY, + DEFAULT_REQUIRE_CHARGING + ), + ) + } + + fun setLocked(paused: Boolean) { + sp.edit { + putBoolean(SHARED_PREF_LOCK_KEY, paused) + } + } + + fun isLocked(): Boolean { + return sp.getBoolean(SHARED_PREF_LOCK_KEY, true) + } +} + diff --git a/mobile/android/app/src/main/kotlin/app/alextran/immich/images/ThumbnailsImpl.kt b/mobile/android/app/src/main/kotlin/app/alextran/immich/images/ThumbnailsImpl.kt index 1ccd742d67..a9d602c19c 100644 --- a/mobile/android/app/src/main/kotlin/app/alextran/immich/images/ThumbnailsImpl.kt +++ b/mobile/android/app/src/main/kotlin/app/alextran/immich/images/ThumbnailsImpl.kt @@ -17,6 +17,7 @@ import java.util.concurrent.Executors import com.bumptech.glide.Glide import com.bumptech.glide.Priority import com.bumptech.glide.load.DecodeFormat +import com.bumptech.glide.request.target.Target.SIZE_ORIGINAL import java.util.Base64 import java.util.concurrent.CancellationException import java.util.concurrent.ConcurrentHashMap @@ -120,15 +121,14 @@ class ThumbnailsImpl(context: Context) : ThumbnailApi { signal: CancellationSignal ) { signal.throwIfCanceled() - val targetWidth = width.toInt() - val targetHeight = height.toInt() + val size = Size(width.toInt(), height.toInt()) val id = assetId.toLong() signal.throwIfCanceled() val bitmap = if (isVideo) { - decodeVideoThumbnail(id, targetWidth, targetHeight, signal) + decodeVideoThumbnail(id, size, signal) } else { - decodeImage(id, targetWidth, targetHeight, signal) + decodeImage(id, size, signal) } processBitmap(bitmap, callback, signal) @@ -151,9 +151,7 @@ class ThumbnailsImpl(context: Context) : ThumbnailApi { bitmap.recycle() signal.throwIfCanceled() val res = mapOf( - "pointer" to pointer, - "width" to actualWidth.toLong(), - "height" to actualHeight.toLong() + "pointer" to pointer, "width" to actualWidth.toLong(), "height" to actualHeight.toLong() ) callback(Result.success(res)) } catch (e: Exception) { @@ -162,55 +160,54 @@ class ThumbnailsImpl(context: Context) : ThumbnailApi { } } - private fun decodeImage( - id: Long, targetWidth: Int, targetHeight: Int, signal: CancellationSignal - ): Bitmap { + private fun decodeImage(id: Long, size: Size, signal: CancellationSignal): Bitmap { signal.throwIfCanceled() val uri = ContentUris.withAppendedId(Images.Media.EXTERNAL_CONTENT_URI, id) - if (targetHeight > 768 || targetWidth > 768) { - return decodeSource(uri, targetWidth, targetHeight, signal) + if (size.width <= 0 || size.height <= 0 || size.width > 768 || size.height > 768) { + return decodeSource(uri, size, signal) } return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - resolver.loadThumbnail(uri, Size(targetWidth, targetHeight), signal) + resolver.loadThumbnail(uri, size, signal) } else { signal.setOnCancelListener { Images.Thumbnails.cancelThumbnailRequest(resolver, id) } Images.Thumbnails.getThumbnail(resolver, id, Images.Thumbnails.MINI_KIND, OPTIONS) } } - private fun decodeVideoThumbnail( - id: Long, targetWidth: Int, targetHeight: Int, signal: CancellationSignal - ): Bitmap { + private fun decodeVideoThumbnail(id: Long, target: Size, signal: CancellationSignal): Bitmap { signal.throwIfCanceled() return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { val uri = ContentUris.withAppendedId(Video.Media.EXTERNAL_CONTENT_URI, id) - resolver.loadThumbnail(uri, Size(targetWidth, targetHeight), signal) + // ensure a valid resolution as the thumbnail is used for videos even when no scaling is needed + val size = if (target.width > 0 && target.height > 0) target else Size(768, 768) + resolver.loadThumbnail(uri, size, signal) } else { signal.setOnCancelListener { Video.Thumbnails.cancelThumbnailRequest(resolver, id) } Video.Thumbnails.getThumbnail(resolver, id, Video.Thumbnails.MINI_KIND, OPTIONS) } } - private fun decodeSource( - uri: Uri, targetWidth: Int, targetHeight: Int, signal: CancellationSignal - ): Bitmap { + private fun decodeSource(uri: Uri, target: Size, signal: CancellationSignal): Bitmap { signal.throwIfCanceled() return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { val source = ImageDecoder.createSource(resolver, uri) signal.throwIfCanceled() ImageDecoder.decodeBitmap(source) { decoder, info, _ -> - if (targetWidth > 0 && targetHeight > 0) { - val sample = max(1, min(info.size.width / targetWidth, info.size.height / targetHeight)) + if (target.width > 0 && target.height > 0) { + val sample = max(1, min(info.size.width / target.width, info.size.height / target.height)) decoder.setTargetSampleSize(sample) } decoder.allocator = ImageDecoder.ALLOCATOR_SOFTWARE decoder.setTargetColorSpace(ColorSpace.get(ColorSpace.Named.SRGB)) } } else { - val ref = Glide.with(ctx).asBitmap().priority(Priority.IMMEDIATE).load(uri) - .disallowHardwareConfig().format(DecodeFormat.PREFER_ARGB_8888) - .submit(targetWidth, targetHeight) + val ref = + Glide.with(ctx).asBitmap().priority(Priority.IMMEDIATE).load(uri).disallowHardwareConfig() + .format(DecodeFormat.PREFER_ARGB_8888).submit( + if (target.width > 0) target.width else SIZE_ORIGINAL, + if (target.height > 0) target.height else SIZE_ORIGINAL, + ) signal.setOnCancelListener { Glide.with(ctx).clear(ref) } ref.get() } diff --git a/mobile/android/build.gradle b/mobile/android/build.gradle index bcf3daa1c8..719c946bd6 100644 --- a/mobile/android/build.gradle +++ b/mobile/android/build.gradle @@ -1,5 +1,5 @@ allprojects { - ext.kotlin_version = '2.0.20' + ext.kotlin_version = '2.2.20' repositories { google() @@ -16,8 +16,8 @@ subprojects { if (project.plugins.hasPlugin("com.android.application") || project.plugins.hasPlugin("com.android.library")) { project.android { - compileSdkVersion 35 - buildToolsVersion "35.0.0" + compileSdkVersion 36 + buildToolsVersion "36.0.0" } } } diff --git a/mobile/android/fastlane/Fastfile b/mobile/android/fastlane/Fastfile index 011658d09a..25a366957e 100644 --- a/mobile/android/fastlane/Fastfile +++ b/mobile/android/fastlane/Fastfile @@ -35,8 +35,8 @@ platform :android do task: 'bundle', build_type: 'Release', properties: { - "android.injected.version.code" => 3015, - "android.injected.version.name" => "1.142.1", + "android.injected.version.code" => 3019, + "android.injected.version.name" => "1.144.1", } ) upload_to_play_store(skip_upload_apk: true, skip_upload_images: true, skip_upload_screenshots: true, aab: '../build/app/outputs/bundle/release/app-release.aab') diff --git a/mobile/android/gradle/wrapper/gradle-wrapper.properties b/mobile/android/gradle/wrapper/gradle-wrapper.properties index dedd5d1e69..ed4c299adb 100644 --- a/mobile/android/gradle/wrapper/gradle-wrapper.properties +++ b/mobile/android/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-all.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/mobile/android/settings.gradle b/mobile/android/settings.gradle index 29c3a7c056..fbed55a3e3 100644 --- a/mobile/android/settings.gradle +++ b/mobile/android/settings.gradle @@ -18,10 +18,10 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version '8.7.2' apply false - id "org.jetbrains.kotlin.android" version "2.0.20" apply false + id "com.android.application" version '8.11.2' apply false + id "org.jetbrains.kotlin.android" version "2.2.20" apply false id 'org.jetbrains.kotlin.plugin.serialization' version '1.9.22' apply false - id 'com.google.devtools.ksp' version '2.0.20-1.0.24' apply false + id 'com.google.devtools.ksp' version '2.2.20-2.0.3' apply false } include ":app" diff --git a/mobile/drift_schemas/main/drift_schema_v12.json b/mobile/drift_schemas/main/drift_schema_v12.json new file mode 100644 index 0000000000..1c100ab37f --- /dev/null +++ b/mobile/drift_schemas/main/drift_schema_v12.json @@ -0,0 +1 @@ +{"_meta":{"description":"This file contains a serialized version of schema entities for drift.","version":"1.2.0"},"options":{"store_date_time_values_as_text":true},"entities":[{"id":0,"references":[],"type":"table","data":{"name":"user_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"email","getter_name":"email","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"has_profile_image","getter_name":"hasProfileImage","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"has_profile_image\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"has_profile_image\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"profile_changed_at","getter_name":"profileChangedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"avatar_color","getter_name":"avatarColor","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AvatarColor.values)","dart_type_name":"AvatarColor"}}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":1,"references":[0],"type":"table","data":{"name":"remote_asset_entity","was_declared_in_moor":false,"columns":[{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"type","getter_name":"type","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AssetType.values)","dart_type_name":"AssetType"}},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"width","getter_name":"width","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"height","getter_name":"height","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"duration_in_seconds","getter_name":"durationInSeconds","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"checksum","getter_name":"checksum","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_favorite","getter_name":"isFavorite","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_favorite\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_favorite\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"owner_id","getter_name":"ownerId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"local_date_time","getter_name":"localDateTime","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"thumb_hash","getter_name":"thumbHash","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"deleted_at","getter_name":"deletedAt","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"live_photo_video_id","getter_name":"livePhotoVideoId","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"visibility","getter_name":"visibility","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AssetVisibility.values)","dart_type_name":"AssetVisibility"}},{"name":"stack_id","getter_name":"stackId","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"library_id","getter_name":"libraryId","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":2,"references":[0],"type":"table","data":{"name":"stack_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"owner_id","getter_name":"ownerId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"primary_asset_id","getter_name":"primaryAssetId","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":3,"references":[],"type":"table","data":{"name":"local_asset_entity","was_declared_in_moor":false,"columns":[{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"type","getter_name":"type","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AssetType.values)","dart_type_name":"AssetType"}},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"width","getter_name":"width","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"height","getter_name":"height","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"duration_in_seconds","getter_name":"durationInSeconds","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"checksum","getter_name":"checksum","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_favorite","getter_name":"isFavorite","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_favorite\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_favorite\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"orientation","getter_name":"orientation","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":4,"references":[0,1],"type":"table","data":{"name":"remote_album_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"description","getter_name":"description","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('\\'\\'')","default_client_dart":null,"dsl_features":[]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"owner_id","getter_name":"ownerId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"thumbnail_asset_id","getter_name":"thumbnailAssetId","moor_type":"string","nullable":true,"customConstraints":null,"defaultConstraints":"REFERENCES remote_asset_entity (id) ON DELETE SET NULL","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_asset_entity (id) ON DELETE SET NULL"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"is_activity_enabled","getter_name":"isActivityEnabled","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_activity_enabled\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_activity_enabled\" IN (0, 1))"},"default_dart":"const CustomExpression('1')","default_client_dart":null,"dsl_features":[]},{"name":"order","getter_name":"order","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AlbumAssetOrder.values)","dart_type_name":"AlbumAssetOrder"}}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":5,"references":[4],"type":"table","data":{"name":"local_album_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"backup_selection","getter_name":"backupSelection","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(BackupSelection.values)","dart_type_name":"BackupSelection"}},{"name":"is_ios_shared_album","getter_name":"isIosSharedAlbum","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_ios_shared_album\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_ios_shared_album\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"linked_remote_album_id","getter_name":"linkedRemoteAlbumId","moor_type":"string","nullable":true,"customConstraints":null,"defaultConstraints":"REFERENCES remote_album_entity (id) ON DELETE SET NULL","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_album_entity (id) ON DELETE SET NULL"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"marker","getter_name":"marker_","moor_type":"bool","nullable":true,"customConstraints":null,"defaultConstraints":"CHECK (\"marker\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"marker\" IN (0, 1))"},"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":6,"references":[3,5],"type":"table","data":{"name":"local_album_asset_entity","was_declared_in_moor":false,"columns":[{"name":"asset_id","getter_name":"assetId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES local_asset_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES local_asset_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"album_id","getter_name":"albumId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES local_album_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES local_album_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"marker","getter_name":"marker_","moor_type":"bool","nullable":true,"customConstraints":null,"defaultConstraints":"CHECK (\"marker\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"marker\" IN (0, 1))"},"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["asset_id","album_id"]}},{"id":7,"references":[3],"type":"index","data":{"on":3,"name":"idx_local_asset_checksum","sql":"CREATE INDEX IF NOT EXISTS idx_local_asset_checksum ON local_asset_entity (checksum)","unique":false,"columns":[]}},{"id":8,"references":[1],"type":"index","data":{"on":1,"name":"idx_remote_asset_owner_checksum","sql":"CREATE INDEX IF NOT EXISTS idx_remote_asset_owner_checksum ON remote_asset_entity (owner_id, checksum)","unique":false,"columns":[]}},{"id":9,"references":[1],"type":"index","data":{"on":1,"name":"UQ_remote_assets_owner_checksum","sql":"CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_checksum\nON remote_asset_entity (owner_id, checksum)\nWHERE (library_id IS NULL);\n","unique":true,"columns":[]}},{"id":10,"references":[1],"type":"index","data":{"on":1,"name":"UQ_remote_assets_owner_library_checksum","sql":"CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_library_checksum\nON remote_asset_entity (owner_id, library_id, checksum)\nWHERE (library_id IS NOT NULL);\n","unique":true,"columns":[]}},{"id":11,"references":[1],"type":"index","data":{"on":1,"name":"idx_remote_asset_checksum","sql":"CREATE INDEX IF NOT EXISTS idx_remote_asset_checksum ON remote_asset_entity (checksum)","unique":false,"columns":[]}},{"id":12,"references":[],"type":"table","data":{"name":"auth_user_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"email","getter_name":"email","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_admin","getter_name":"isAdmin","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_admin\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_admin\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"has_profile_image","getter_name":"hasProfileImage","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"has_profile_image\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"has_profile_image\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"profile_changed_at","getter_name":"profileChangedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"avatar_color","getter_name":"avatarColor","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AvatarColor.values)","dart_type_name":"AvatarColor"}},{"name":"quota_size_in_bytes","getter_name":"quotaSizeInBytes","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"quota_usage_in_bytes","getter_name":"quotaUsageInBytes","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"pin_code","getter_name":"pinCode","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":13,"references":[0],"type":"table","data":{"name":"user_metadata_entity","was_declared_in_moor":false,"columns":[{"name":"user_id","getter_name":"userId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"key","getter_name":"key","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(UserMetadataKey.values)","dart_type_name":"UserMetadataKey"}},{"name":"value","getter_name":"value","moor_type":"blob","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"userMetadataConverter","dart_type_name":"Map"}}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["user_id","key"]}},{"id":14,"references":[0],"type":"table","data":{"name":"partner_entity","was_declared_in_moor":false,"columns":[{"name":"shared_by_id","getter_name":"sharedById","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"shared_with_id","getter_name":"sharedWithId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"in_timeline","getter_name":"inTimeline","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"in_timeline\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"in_timeline\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["shared_by_id","shared_with_id"]}},{"id":15,"references":[1],"type":"table","data":{"name":"remote_exif_entity","was_declared_in_moor":false,"columns":[{"name":"asset_id","getter_name":"assetId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"city","getter_name":"city","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"state","getter_name":"state","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"country","getter_name":"country","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"date_time_original","getter_name":"dateTimeOriginal","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"description","getter_name":"description","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"height","getter_name":"height","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"width","getter_name":"width","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"exposure_time","getter_name":"exposureTime","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"f_number","getter_name":"fNumber","moor_type":"double","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"file_size","getter_name":"fileSize","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"focal_length","getter_name":"focalLength","moor_type":"double","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"latitude","getter_name":"latitude","moor_type":"double","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"longitude","getter_name":"longitude","moor_type":"double","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"iso","getter_name":"iso","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"make","getter_name":"make","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"model","getter_name":"model","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"lens","getter_name":"lens","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"orientation","getter_name":"orientation","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"time_zone","getter_name":"timeZone","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"rating","getter_name":"rating","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"projection_type","getter_name":"projectionType","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["asset_id"]}},{"id":16,"references":[1,4],"type":"table","data":{"name":"remote_album_asset_entity","was_declared_in_moor":false,"columns":[{"name":"asset_id","getter_name":"assetId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"album_id","getter_name":"albumId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_album_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_album_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["asset_id","album_id"]}},{"id":17,"references":[4,0],"type":"table","data":{"name":"remote_album_user_entity","was_declared_in_moor":false,"columns":[{"name":"album_id","getter_name":"albumId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_album_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_album_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"user_id","getter_name":"userId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"role","getter_name":"role","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(AlbumUserRole.values)","dart_type_name":"AlbumUserRole"}}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["album_id","user_id"]}},{"id":18,"references":[0],"type":"table","data":{"name":"memory_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"deleted_at","getter_name":"deletedAt","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"owner_id","getter_name":"ownerId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"type","getter_name":"type","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[],"type_converter":{"dart_expr":"const EnumIndexConverter(MemoryTypeEnum.values)","dart_type_name":"MemoryTypeEnum"}},{"name":"data","getter_name":"data","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_saved","getter_name":"isSaved","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_saved\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_saved\" IN (0, 1))"},"default_dart":"const CustomExpression('0')","default_client_dart":null,"dsl_features":[]},{"name":"memory_at","getter_name":"memoryAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"seen_at","getter_name":"seenAt","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"show_at","getter_name":"showAt","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"hide_at","getter_name":"hideAt","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":19,"references":[1,18],"type":"table","data":{"name":"memory_asset_entity","was_declared_in_moor":false,"columns":[{"name":"asset_id","getter_name":"assetId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"memory_id","getter_name":"memoryId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES memory_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES memory_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["asset_id","memory_id"]}},{"id":20,"references":[0],"type":"table","data":{"name":"person_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"created_at","getter_name":"createdAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"updated_at","getter_name":"updatedAt","moor_type":"dateTime","nullable":false,"customConstraints":null,"default_dart":"const CustomExpression('CURRENT_TIMESTAMP')","default_client_dart":null,"dsl_features":[]},{"name":"owner_id","getter_name":"ownerId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES user_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES user_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"name","getter_name":"name","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"face_asset_id","getter_name":"faceAssetId","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_favorite","getter_name":"isFavorite","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_favorite\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_favorite\" IN (0, 1))"},"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"is_hidden","getter_name":"isHidden","moor_type":"bool","nullable":false,"customConstraints":null,"defaultConstraints":"CHECK (\"is_hidden\" IN (0, 1))","dialectAwareDefaultConstraints":{"sqlite":"CHECK (\"is_hidden\" IN (0, 1))"},"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"color","getter_name":"color","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"birth_date","getter_name":"birthDate","moor_type":"dateTime","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":21,"references":[1,20],"type":"table","data":{"name":"asset_face_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"asset_id","getter_name":"assetId","moor_type":"string","nullable":false,"customConstraints":null,"defaultConstraints":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES remote_asset_entity (id) ON DELETE CASCADE"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"person_id","getter_name":"personId","moor_type":"string","nullable":true,"customConstraints":null,"defaultConstraints":"REFERENCES person_entity (id) ON DELETE SET NULL","dialectAwareDefaultConstraints":{"sqlite":"REFERENCES person_entity (id) ON DELETE SET NULL"},"default_dart":null,"default_client_dart":null,"dsl_features":["unknown"]},{"name":"image_width","getter_name":"imageWidth","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"image_height","getter_name":"imageHeight","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"bounding_box_x1","getter_name":"boundingBoxX1","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"bounding_box_y1","getter_name":"boundingBoxY1","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"bounding_box_x2","getter_name":"boundingBoxX2","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"bounding_box_y2","getter_name":"boundingBoxY2","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"source_type","getter_name":"sourceType","moor_type":"string","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":22,"references":[],"type":"table","data":{"name":"store_entity","was_declared_in_moor":false,"columns":[{"name":"id","getter_name":"id","moor_type":"int","nullable":false,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"string_value","getter_name":"stringValue","moor_type":"string","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]},{"name":"int_value","getter_name":"intValue","moor_type":"int","nullable":true,"customConstraints":null,"default_dart":null,"default_client_dart":null,"dsl_features":[]}],"is_virtual":false,"without_rowid":true,"constraints":[],"strict":true,"explicit_pk":["id"]}},{"id":23,"references":[15],"type":"index","data":{"on":15,"name":"idx_lat_lng","sql":"CREATE INDEX IF NOT EXISTS idx_lat_lng ON remote_exif_entity (latitude, longitude)","unique":false,"columns":[]}}]} \ No newline at end of file diff --git a/mobile/ios/Runner.xcodeproj/project.pbxproj b/mobile/ios/Runner.xcodeproj/project.pbxproj index 48826a20f1..09f749bcd2 100644 --- a/mobile/ios/Runner.xcodeproj/project.pbxproj +++ b/mobile/ios/Runner.xcodeproj/project.pbxproj @@ -705,7 +705,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/RunnerProfile.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 224; + CURRENT_PROJECT_VERSION = 227; CUSTOM_GROUP_ID = group.app.immich.share; DEVELOPMENT_TEAM = 2F67MQ8R79; ENABLE_BITCODE = NO; @@ -849,7 +849,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 224; + CURRENT_PROJECT_VERSION = 227; CUSTOM_GROUP_ID = group.app.immich.share; DEVELOPMENT_TEAM = 2F67MQ8R79; ENABLE_BITCODE = NO; @@ -879,7 +879,7 @@ CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 224; + CURRENT_PROJECT_VERSION = 227; CUSTOM_GROUP_ID = group.app.immich.share; DEVELOPMENT_TEAM = 2F67MQ8R79; ENABLE_BITCODE = NO; @@ -913,7 +913,7 @@ CODE_SIGN_ENTITLEMENTS = WidgetExtension/WidgetExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 224; + CURRENT_PROJECT_VERSION = 227; DEVELOPMENT_TEAM = 2F67MQ8R79; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -956,7 +956,7 @@ CODE_SIGN_ENTITLEMENTS = WidgetExtension/WidgetExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 224; + CURRENT_PROJECT_VERSION = 227; DEVELOPMENT_TEAM = 2F67MQ8R79; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -996,7 +996,7 @@ CODE_SIGN_ENTITLEMENTS = WidgetExtension/WidgetExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 224; + CURRENT_PROJECT_VERSION = 227; DEVELOPMENT_TEAM = 2F67MQ8R79; ENABLE_USER_SCRIPT_SANDBOXING = YES; GCC_C_LANGUAGE_STANDARD = gnu17; @@ -1035,7 +1035,7 @@ CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 224; + CURRENT_PROJECT_VERSION = 227; CUSTOM_GROUP_ID = group.app.immich.share; DEVELOPMENT_TEAM = 2F67MQ8R79; ENABLE_USER_SCRIPT_SANDBOXING = YES; @@ -1079,7 +1079,7 @@ CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 224; + CURRENT_PROJECT_VERSION = 227; CUSTOM_GROUP_ID = group.app.immich.share; DEVELOPMENT_TEAM = 2F67MQ8R79; ENABLE_USER_SCRIPT_SANDBOXING = YES; @@ -1120,7 +1120,7 @@ CODE_SIGN_ENTITLEMENTS = ShareExtension/ShareExtension.entitlements; CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 224; + CURRENT_PROJECT_VERSION = 227; CUSTOM_GROUP_ID = group.app.immich.share; DEVELOPMENT_TEAM = 2F67MQ8R79; ENABLE_USER_SCRIPT_SANDBOXING = YES; diff --git a/mobile/ios/Runner/Info.plist b/mobile/ios/Runner/Info.plist index c1e6ec212d..f32980bb38 100644 --- a/mobile/ios/Runner/Info.plist +++ b/mobile/ios/Runner/Info.plist @@ -80,7 +80,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.142.1 + 1.144.0 CFBundleSignature ???? CFBundleURLTypes @@ -107,7 +107,7 @@ CFBundleVersion - 224 + 227 FLTEnableImpeller ITSAppUsesNonExemptEncryption diff --git a/mobile/ios/fastlane/Fastfile b/mobile/ios/fastlane/Fastfile index 3f0edf6ae4..cd3310e9a2 100644 --- a/mobile/ios/fastlane/Fastfile +++ b/mobile/ios/fastlane/Fastfile @@ -22,7 +22,7 @@ platform :ios do path: "./Runner.xcodeproj", ) increment_version_number( - version_number: "1.142.1" + version_number: "1.144.1" ) increment_build_number( build_number: latest_testflight_build_number + 1, diff --git a/mobile/lib/domain/services/background_worker.service.dart b/mobile/lib/domain/services/background_worker.service.dart index 78dd1e980f..0548a45bf7 100644 --- a/mobile/lib/domain/services/background_worker.service.dart +++ b/mobile/lib/domain/services/background_worker.service.dart @@ -10,11 +10,13 @@ import 'package:immich_mobile/constants/constants.dart'; import 'package:immich_mobile/domain/services/log.service.dart'; import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/extensions/network_capability_extensions.dart'; +import 'package:immich_mobile/extensions/platform_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/generated/intl_keys.g.dart'; import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/logger_db.repository.dart'; import 'package:immich_mobile/platform/background_worker_api.g.dart'; +import 'package:immich_mobile/platform/background_worker_lock_api.g.dart'; import 'package:immich_mobile/providers/app_settings.provider.dart'; import 'package:immich_mobile/providers/background_sync.provider.dart'; import 'package:immich_mobile/providers/backup/drift_backup.provider.dart'; @@ -26,7 +28,6 @@ import 'package:immich_mobile/repositories/file_media.repository.dart'; import 'package:immich_mobile/services/app_settings.service.dart'; import 'package:immich_mobile/services/auth.service.dart'; import 'package:immich_mobile/services/localization.service.dart'; -import 'package:immich_mobile/services/server_info.service.dart'; import 'package:immich_mobile/services/upload.service.dart'; import 'package:immich_mobile/utils/bootstrap.dart'; import 'package:immich_mobile/utils/debug_print.dart'; @@ -58,7 +59,7 @@ class BackgroundWorkerFgService { } class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi { - late final ProviderContainer _ref; + ProviderContainer? _ref; final Isar _isar; final Drift _drift; final DriftLogger _driftLogger; @@ -83,36 +84,38 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi { BackgroundWorkerFlutterApi.setUp(this); } - bool get _isBackupEnabled => _ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableBackup); + bool get _isBackupEnabled => _ref?.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableBackup) ?? false; Future init() async { try { HttpSSLOptions.apply(applyNative: false); - await Future.wait([ - loadTranslations(), - workerManager.init(dynamicSpawning: true), - _ref.read(authServiceProvider).setOpenApiServiceEndpoint(), - // Initialize the file downloader - FileDownloader().configure( - globalConfig: [ - // maxConcurrent: 6, maxConcurrentByHost(server):6, maxConcurrentByGroup: 3 - (Config.holdingQueue, (6, 6, 3)), - // On Android, if files are larger than 256MB, run in foreground service - (Config.runInForegroundIfFileLargerThan, 256), - ], - ), - FileDownloader().trackTasksInGroup(kDownloadGroupLivePhoto, markDownloadedComplete: false), - FileDownloader().trackTasks(), - _ref.read(fileMediaRepositoryProvider).enableBackgroundAccess(), - ]); + await Future.wait( + [ + loadTranslations(), + workerManager.init(dynamicSpawning: true), + _ref?.read(authServiceProvider).setOpenApiServiceEndpoint(), + // Initialize the file downloader + FileDownloader().configure( + globalConfig: [ + // maxConcurrent: 6, maxConcurrentByHost(server):6, maxConcurrentByGroup: 3 + (Config.holdingQueue, (6, 6, 3)), + // On Android, if files are larger than 256MB, run in foreground service + (Config.runInForegroundIfFileLargerThan, 256), + ], + ), + FileDownloader().trackTasksInGroup(kDownloadGroupLivePhoto, markDownloadedComplete: false), + FileDownloader().trackTasks(), + _ref?.read(fileMediaRepositoryProvider).enableBackgroundAccess(), + ].nonNulls, + ); configureFileDownloaderNotifications(); if (Platform.isAndroid) { await _backgroundHostApi.showNotification( IntlKeys.uploading_media.t(), - IntlKeys.backup_background_service_in_progress_notification.t(), + IntlKeys.backup_background_service_default_notification.t(), ); } @@ -126,30 +129,33 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi { @override Future onAndroidUpload() async { + _logger.info('Android background processing started'); + final sw = Stopwatch()..start(); try { - _logger.info('Android background processing started'); - final sw = Stopwatch()..start(); - - await _syncAssets(hashTimeout: Duration(minutes: _isBackupEnabled ? 3 : 6)); + if (!await _syncAssets(hashTimeout: Duration(minutes: _isBackupEnabled ? 3 : 6))) { + _logger.warning("Remote sync did not complete successfully, skipping backup"); + return; + } await _handleBackup(); - - sw.stop(); - _logger.info("Android background processing completed in ${sw.elapsed.inSeconds}s"); } catch (error, stack) { _logger.severe("Failed to complete Android background processing", error, stack); } finally { + sw.stop(); + _logger.info("Android background processing completed in ${sw.elapsed.inSeconds}s"); await _cleanup(); } } @override Future onIosUpload(bool isRefresh, int? maxSeconds) async { + _logger.info('iOS background upload started with maxSeconds: ${maxSeconds}s'); + final sw = Stopwatch()..start(); try { - _logger.info('iOS background upload started with maxSeconds: ${maxSeconds}s'); - final sw = Stopwatch()..start(); - final timeout = isRefresh ? const Duration(seconds: 5) : Duration(minutes: _isBackupEnabled ? 3 : 6); - await _syncAssets(hashTimeout: timeout); + if (!await _syncAssets(hashTimeout: timeout)) { + _logger.warning("Remote sync did not complete successfully, skipping backup"); + return; + } final backupFuture = _handleBackup(); if (maxSeconds != null) { @@ -157,12 +163,11 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi { } else { await backupFuture; } - - sw.stop(); - _logger.info("iOS background upload completed in ${sw.elapsed.inSeconds}s"); } catch (error, stack) { _logger.severe("Failed to complete iOS background upload", error, stack); } finally { + sw.stop(); + _logger.info("iOS background upload completed in ${sw.elapsed.inSeconds}s"); await _cleanup(); } } @@ -178,15 +183,17 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi { } Future _cleanup() async { - if (_isCleanedUp) { + // If ref is null, it means the service was never initialized properly + if (_isCleanedUp || _ref == null) { return; } try { - final backgroundSyncManager = _ref.read(backgroundSyncProvider); - final nativeSyncApi = _ref.read(nativeSyncApiProvider); _isCleanedUp = true; - _ref.dispose(); + final backgroundSyncManager = _ref?.read(backgroundSyncProvider); + final nativeSyncApi = _ref?.read(nativeSyncApiProvider); + _ref?.dispose(); + _ref = null; _cancellationToken.cancel(); _logger.info("Cleaning up background worker"); @@ -199,14 +206,14 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi { Store.dispose(), _drift.close(), _driftLogger.close(), - backgroundSyncManager.cancel(), - nativeSyncApi.cancelHashing(), + backgroundSyncManager?.cancel(), + nativeSyncApi?.cancelHashing(), ]; if (_isar.isOpen) { cleanupFutures.add(_isar.close()); } - await Future.wait(cleanupFutures); + await Future.wait(cleanupFutures.nonNulls); _logger.info("Background worker resources cleaned up"); } catch (error, stack) { dPrint(() => 'Failed to cleanup background worker: $error with stack: $stack'); @@ -216,34 +223,28 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi { Future _handleBackup() async { await runZonedGuarded( () async { - if (!_isBackupEnabled || _isCleanedUp) { - _logger.info("[_handleBackup 1] Backup is disabled. Skipping backup routine"); + if (_isCleanedUp) { return; } - _logger.info("[_handleBackup 2] Enqueuing assets for backup from the background service"); + if (!_isBackupEnabled) { + _logger.info("Backup is disabled. Skipping backup routine"); + return; + } - final currentUser = _ref.read(currentUserProvider); + final currentUser = _ref?.read(currentUserProvider); if (currentUser == null) { - _logger.warning("[_handleBackup 3] No current user found. Skipping backup from background"); + _logger.warning("No current user found. Skipping backup from background"); return; } - _logger.info("[_handleBackup 4] Resume backup from background"); if (Platform.isIOS) { - return _ref.read(driftBackupProvider.notifier).handleBackupResume(currentUser.id); + return _ref?.read(driftBackupProvider.notifier).handleBackupResume(currentUser.id); } - final canPing = await _ref.read(serverInfoServiceProvider).ping(); - if (!canPing) { - _logger.warning("[_handleBackup 5] Server is not reachable. Skipping backup from background"); - return; - } - - final networkCapabilities = await _ref.read(connectivityApiProvider).getCapabilities(); - + final networkCapabilities = await _ref?.read(connectivityApiProvider).getCapabilities() ?? []; return _ref - .read(uploadServiceProvider) + ?.read(uploadServiceProvider) .startBackupWithHttpClient(currentUser.id, networkCapabilities.hasWifi, _cancellationToken); }, (error, stack) { @@ -252,19 +253,19 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi { ); } - Future _syncAssets({Duration? hashTimeout}) async { - await _ref.read(backgroundSyncProvider).syncLocal(); + Future _syncAssets({Duration? hashTimeout}) async { + await _ref?.read(backgroundSyncProvider).syncLocal(); if (_isCleanedUp) { - return; + return false; } - await _ref.read(backgroundSyncProvider).syncRemote(); + final isSuccess = await _ref?.read(backgroundSyncProvider).syncRemote() ?? false; if (_isCleanedUp) { - return; + return isSuccess; } - var hashFuture = _ref.read(backgroundSyncProvider).hashAssets(); - if (hashTimeout != null) { + var hashFuture = _ref?.read(backgroundSyncProvider).hashAssets(); + if (hashTimeout != null && hashFuture != null) { hashFuture = hashFuture.timeout( hashTimeout, onTimeout: () { @@ -274,6 +275,24 @@ class BackgroundWorkerBgService extends BackgroundWorkerFlutterApi { } await hashFuture; + return isSuccess; + } +} + +class BackgroundWorkerLockService { + final BackgroundWorkerLockApi _hostApi; + const BackgroundWorkerLockService(this._hostApi); + + Future lock() async { + if (CurrentPlatform.isAndroid) { + return _hostApi.lock(); + } + } + + Future unlock() async { + if (CurrentPlatform.isAndroid) { + return _hostApi.unlock(); + } } } diff --git a/mobile/lib/domain/services/local_sync.service.dart b/mobile/lib/domain/services/local_sync.service.dart index d333af7481..ca356c80d8 100644 --- a/mobile/lib/domain/services/local_sync.service.dart +++ b/mobile/lib/domain/services/local_sync.service.dart @@ -281,7 +281,7 @@ extension on Iterable { (e) => LocalAlbum( id: e.id, name: e.name, - updatedAt: tryFromSecondsSinceEpoch(e.updatedAt) ?? DateTime.now(), + updatedAt: tryFromSecondsSinceEpoch(e.updatedAt, isUtc: true) ?? DateTime.timestamp(), assetCount: e.assetCount, ), ).toList(); @@ -296,8 +296,8 @@ extension on Iterable { name: e.name, checksum: null, type: AssetType.values.elementAtOrNull(e.type) ?? AssetType.other, - createdAt: tryFromSecondsSinceEpoch(e.createdAt) ?? DateTime.now(), - updatedAt: tryFromSecondsSinceEpoch(e.updatedAt) ?? DateTime.now(), + createdAt: tryFromSecondsSinceEpoch(e.createdAt, isUtc: true) ?? DateTime.timestamp(), + updatedAt: tryFromSecondsSinceEpoch(e.updatedAt, isUtc: true) ?? DateTime.timestamp(), width: e.width, height: e.height, durationInSeconds: e.durationInSeconds, diff --git a/mobile/lib/domain/services/sync_linked_album.service.dart b/mobile/lib/domain/services/sync_linked_album.service.dart index 78750c9bd0..b61ca1c965 100644 --- a/mobile/lib/domain/services/sync_linked_album.service.dart +++ b/mobile/lib/domain/services/sync_linked_album.service.dart @@ -4,8 +4,8 @@ import 'package:immich_mobile/infrastructure/repositories/local_album.repository import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.dart'; import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; import 'package:immich_mobile/repositories/drift_album_api_repository.dart'; -import 'package:logging/logging.dart'; import 'package:immich_mobile/utils/debug_print.dart'; +import 'package:logging/logging.dart'; final syncLinkedAlbumServiceProvider = Provider( (ref) => SyncLinkedAlbumService( @@ -31,17 +31,19 @@ class SyncLinkedAlbumService { selectedAlbums.map((localAlbum) async { final linkedRemoteAlbumId = localAlbum.linkedRemoteAlbumId; if (linkedRemoteAlbumId == null) { + _log.warning("No linked remote album ID found for local album: ${localAlbum.name}"); return; } final remoteAlbum = await _remoteAlbumRepository.get(linkedRemoteAlbumId); if (remoteAlbum == null) { + _log.warning("Linked remote album not found for ID: $linkedRemoteAlbumId"); return; } // get assets that are uploaded but not in the remote album final assetIds = await _remoteAlbumRepository.getLinkedAssetIds(userId, localAlbum.id, linkedRemoteAlbumId); - + _log.fine("Syncing ${assetIds.length} assets to remote album: ${remoteAlbum.name}"); if (assetIds.isNotEmpty) { final album = await _albumApiRepository.addAssets(remoteAlbum.id, assetIds); await _remoteAlbumRepository.addAssets(remoteAlbum.id, album.added); diff --git a/mobile/lib/domain/services/sync_stream.service.dart b/mobile/lib/domain/services/sync_stream.service.dart index 6c8e444d50..bec7e6afda 100644 --- a/mobile/lib/domain/services/sync_stream.service.dart +++ b/mobile/lib/domain/services/sync_stream.service.dart @@ -23,7 +23,7 @@ class SyncStreamService { bool get isCancelled => _cancelChecker?.call() ?? false; - Future sync() async { + Future sync() async { _logger.info("Remote sync request for user"); // Start the sync stream and handle events bool shouldReset = false; @@ -32,6 +32,7 @@ class SyncStreamService { _logger.info("Resetting sync state as requested by server"); await _syncApiRepository.streamChanges(_handleEvents); } + return true; } Future _handleEvents(List events, Function() abort, Function() reset) async { diff --git a/mobile/lib/domain/utils/background_sync.dart b/mobile/lib/domain/utils/background_sync.dart index ffbb020345..b2f2fe54e1 100644 --- a/mobile/lib/domain/utils/background_sync.dart +++ b/mobile/lib/domain/utils/background_sync.dart @@ -21,7 +21,7 @@ class BackgroundSyncManager { final SyncCallback? onHashingComplete; final SyncErrorCallback? onHashingError; - Cancelable? _syncTask; + Cancelable? _syncTask; Cancelable? _syncWebsocketTask; Cancelable? _deviceAlbumSyncTask; Cancelable? _linkedAlbumSyncTask; @@ -144,9 +144,9 @@ class BackgroundSyncManager { }); } - Future syncRemote() { + Future syncRemote() { if (_syncTask != null) { - return _syncTask!.future; + return _syncTask!.future.then((result) => result ?? false).catchError((_) => false); } onRemoteSyncStart?.call(); @@ -156,6 +156,7 @@ class BackgroundSyncManager { debugLabel: 'remote-sync', ); return _syncTask! + .then((result) => result ?? false) .whenComplete(() { onRemoteSyncComplete?.call(); _syncTask = null; @@ -163,6 +164,7 @@ class BackgroundSyncManager { .catchError((error) { onRemoteSyncError?.call(error.toString()); _syncTask = null; + return false; }); } diff --git a/mobile/lib/domain/utils/sync_linked_album.dart b/mobile/lib/domain/utils/sync_linked_album.dart index d4094f74cc..7bfadc96e7 100644 --- a/mobile/lib/domain/utils/sync_linked_album.dart +++ b/mobile/lib/domain/utils/sync_linked_album.dart @@ -2,10 +2,12 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/domain/services/sync_linked_album.service.dart'; import 'package:immich_mobile/entities/store.entity.dart'; +import 'package:logging/logging.dart'; Future syncLinkedAlbumsIsolated(ProviderContainer ref) { final user = Store.tryGet(StoreKey.currentUser); if (user == null) { + Logger("SyncLinkedAlbum").warning("No user logged in, skipping linked album sync"); return Future.value(); } return ref.read(syncLinkedAlbumServiceProvider).syncLinkedAlbums(user.id); diff --git a/mobile/lib/extensions/string_extensions.dart b/mobile/lib/extensions/string_extensions.dart index 6cd6e1e4b4..ae31565044 100644 --- a/mobile/lib/extensions/string_extensions.dart +++ b/mobile/lib/extensions/string_extensions.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + extension StringExtension on String { String capitalize() { return split(" ").map((str) => str.isEmpty ? str : str[0].toUpperCase() + str.substring(1)).join(" "); @@ -23,3 +25,11 @@ extension DurationExtension on String { return int.parse(this); } } + +Map? tryJsonDecode(dynamic json) { + try { + return jsonDecode(json) as Map; + } catch (e) { + return null; + } +} diff --git a/mobile/lib/infrastructure/entities/local_asset.entity.dart b/mobile/lib/infrastructure/entities/local_asset.entity.dart index 337a6d728d..8b253f83a3 100644 --- a/mobile/lib/infrastructure/entities/local_asset.entity.dart +++ b/mobile/lib/infrastructure/entities/local_asset.entity.dart @@ -21,7 +21,7 @@ class LocalAssetEntity extends Table with DriftDefaultsMixin, AssetEntityMixin { } extension LocalAssetEntityDataDomainExtension on LocalAssetEntityData { - LocalAsset toDto() => LocalAsset( + LocalAsset toDto({String? remoteId}) => LocalAsset( id: id, name: name, checksum: checksum, @@ -32,7 +32,7 @@ extension LocalAssetEntityDataDomainExtension on LocalAssetEntityData { isFavorite: isFavorite, height: height, width: width, - remoteId: null, + remoteId: remoteId, orientation: orientation, ); } diff --git a/mobile/lib/infrastructure/entities/remote_asset.entity.dart b/mobile/lib/infrastructure/entities/remote_asset.entity.dart index 4426974413..dcc885a2a9 100644 --- a/mobile/lib/infrastructure/entities/remote_asset.entity.dart +++ b/mobile/lib/infrastructure/entities/remote_asset.entity.dart @@ -49,7 +49,7 @@ class RemoteAssetEntity extends Table with DriftDefaultsMixin, AssetEntityMixin } extension RemoteAssetEntityDataDomainEx on RemoteAssetEntityData { - RemoteAsset toDto() => RemoteAsset( + RemoteAsset toDto({String? localId}) => RemoteAsset( id: id, name: name, ownerId: ownerId, @@ -64,7 +64,7 @@ extension RemoteAssetEntityDataDomainEx on RemoteAssetEntityData { thumbHash: thumbHash, visibility: visibility, livePhotoVideoId: livePhotoVideoId, - localId: null, + localId: localId, stackId: stackId, ); } diff --git a/mobile/lib/infrastructure/repositories/backup.repository.dart b/mobile/lib/infrastructure/repositories/backup.repository.dart index 1e9f69147c..0241711d4b 100644 --- a/mobile/lib/infrastructure/repositories/backup.repository.dart +++ b/mobile/lib/infrastructure/repositories/backup.repository.dart @@ -29,85 +29,59 @@ class DriftBackupRepository extends DriftDatabaseRepository { ..where(_db.localAlbumEntity.backupSelection.equalsValue(BackupSelection.excluded)); } - Future getTotalCount() async { - final query = _db.localAlbumAssetEntity.selectOnly(distinct: true) - ..addColumns([_db.localAlbumAssetEntity.assetId]) - ..join([ - innerJoin( - _db.localAlbumEntity, - _db.localAlbumAssetEntity.albumId.equalsExp(_db.localAlbumEntity.id), - useColumns: false, - ), - ]) - ..where( - _db.localAlbumEntity.backupSelection.equalsValue(BackupSelection.selected) & - _db.localAlbumAssetEntity.assetId.isNotInQuery(_getExcludedSubquery()), - ); + /// Returns all backup-related counts in a single query. + /// + /// - total: number of distinct assets in selected albums, excluding those that are also in excluded albums + /// - backup: number of those assets that already exist on the server for [userId] + /// - remainder: number of those assets that do not yet exist on the server for [userId] + /// (includes processing) + /// - processing: number of those assets that are still preparing/have a null checksum + Future<({int total, int remainder, int processing})> getAllCounts(String userId) async { + const sql = ''' + SELECT + COUNT(*) AS total_count, + COUNT(*) FILTER (WHERE lae.checksum IS NULL) AS processing_count, + COUNT(*) FILTER (WHERE rae.id IS NULL) AS remainder_count + FROM local_asset_entity lae + LEFT JOIN main.remote_asset_entity rae + ON lae.checksum = rae.checksum AND rae.owner_id = ?1 + WHERE EXISTS ( + SELECT 1 + FROM local_album_asset_entity laa + INNER JOIN main.local_album_entity la on laa.album_id = la.id + WHERE laa.asset_id = lae.id + AND la.backup_selection = ?2 + ) + AND NOT EXISTS ( + SELECT 1 + FROM local_album_asset_entity laa + INNER JOIN main.local_album_entity la on laa.album_id = la.id + WHERE laa.asset_id = lae.id + AND la.backup_selection = ?3 + ); + '''; - return query.get().then((rows) => rows.length); + final row = await _db + .customSelect( + sql, + variables: [ + Variable.withString(userId), + Variable.withInt(BackupSelection.selected.index), + Variable.withInt(BackupSelection.excluded.index), + ], + readsFrom: {_db.localAlbumAssetEntity, _db.localAlbumEntity, _db.localAssetEntity, _db.remoteAssetEntity}, + ) + .getSingle(); + + final data = row.data; + return ( + total: (data['total_count'] as int?) ?? 0, + remainder: (data['remainder_count'] as int?) ?? 0, + processing: (data['processing_count'] as int?) ?? 0, + ); } - Future getRemainderCount(String userId) async { - final query = _db.localAlbumAssetEntity.selectOnly(distinct: true) - ..addColumns([_db.localAlbumAssetEntity.assetId]) - ..join([ - innerJoin( - _db.localAlbumEntity, - _db.localAlbumAssetEntity.albumId.equalsExp(_db.localAlbumEntity.id), - useColumns: false, - ), - innerJoin( - _db.localAssetEntity, - _db.localAlbumAssetEntity.assetId.equalsExp(_db.localAssetEntity.id), - useColumns: false, - ), - leftOuterJoin( - _db.remoteAssetEntity, - _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum) & - _db.remoteAssetEntity.ownerId.equals(userId), - useColumns: false, - ), - ]) - ..where( - _db.localAlbumEntity.backupSelection.equalsValue(BackupSelection.selected) & - _db.remoteAssetEntity.id.isNull() & - _db.localAlbumAssetEntity.assetId.isNotInQuery(_getExcludedSubquery()), - ); - - return query.get().then((rows) => rows.length); - } - - Future getBackupCount(String userId) async { - final query = _db.localAlbumAssetEntity.selectOnly(distinct: true) - ..addColumns([_db.localAlbumAssetEntity.assetId]) - ..join([ - innerJoin( - _db.localAlbumEntity, - _db.localAlbumAssetEntity.albumId.equalsExp(_db.localAlbumEntity.id), - useColumns: false, - ), - innerJoin( - _db.localAssetEntity, - _db.localAlbumAssetEntity.assetId.equalsExp(_db.localAssetEntity.id), - useColumns: false, - ), - innerJoin( - _db.remoteAssetEntity, - _db.localAssetEntity.checksum.equalsExp(_db.remoteAssetEntity.checksum), - useColumns: false, - ), - ]) - ..where( - _db.localAlbumEntity.backupSelection.equalsValue(BackupSelection.selected) & - _db.remoteAssetEntity.id.isNotNull() & - _db.remoteAssetEntity.ownerId.equals(userId) & - _db.localAlbumAssetEntity.assetId.isNotInQuery(_getExcludedSubquery()), - ); - - return query.get().then((rows) => rows.length); - } - - Future> getCandidates(String userId) async { + Future> getCandidates(String userId, {bool onlyHashed = true}) async { final selectedAlbumIds = _db.localAlbumEntity.selectOnly(distinct: true) ..addColumns([_db.localAlbumEntity.id]) ..where(_db.localAlbumEntity.backupSelection.equalsValue(BackupSelection.selected)); @@ -115,7 +89,6 @@ class DriftBackupRepository extends DriftDatabaseRepository { final query = _db.localAssetEntity.select() ..where( (lae) => - lae.checksum.isNotNull() & existsQuery( _db.localAlbumAssetEntity.selectOnly() ..addColumns([_db.localAlbumAssetEntity.assetId]) @@ -135,6 +108,10 @@ class DriftBackupRepository extends DriftDatabaseRepository { ) ..orderBy([(localAsset) => OrderingTerm.desc(localAsset.createdAt)]); + if (onlyHashed) { + query.where((lae) => lae.checksum.isNotNull()); + } + return query.map((localAsset) => localAsset.toDto()).get(); } } diff --git a/mobile/lib/infrastructure/repositories/db.repository.dart b/mobile/lib/infrastructure/repositories/db.repository.dart index 65d26d9747..7291c3a97b 100644 --- a/mobile/lib/infrastructure/repositories/db.repository.dart +++ b/mobile/lib/infrastructure/repositories/db.repository.dart @@ -93,7 +93,7 @@ class Drift extends $Drift implements IDatabaseRepository { } @override - int get schemaVersion => 11; + int get schemaVersion => 12; @override MigrationStrategy get migration => MigrationStrategy( @@ -159,6 +159,25 @@ class Drift extends $Drift implements IDatabaseRepository { from10To11: (m, v11) async { await m.addColumn(v11.localAlbumAssetEntity, v11.localAlbumAssetEntity.marker_); }, + from11To12: (m, v12) async { + final localToUTCMapping = { + v12.localAssetEntity: [v12.localAssetEntity.createdAt, v12.localAssetEntity.updatedAt], + v12.localAlbumEntity: [v12.localAlbumEntity.updatedAt], + }; + + for (final entry in localToUTCMapping.entries) { + final table = entry.key; + await m.alterTable( + TableMigration( + table, + columnTransformer: { + for (final column in entry.value) + column: column.modify(const DateTimeModifier.utc()).strftime('%Y-%m-%dT%H:%M:%fZ'), + }, + ), + ); + } + }, ), ); diff --git a/mobile/lib/infrastructure/repositories/db.repository.steps.dart b/mobile/lib/infrastructure/repositories/db.repository.steps.dart index 7910d9fcee..c973cd6f13 100644 --- a/mobile/lib/infrastructure/repositories/db.repository.steps.dart +++ b/mobile/lib/infrastructure/repositories/db.repository.steps.dart @@ -4659,6 +4659,384 @@ class Shape22 extends i0.VersionedTable { columnsByName['marker']! as i1.GeneratedColumn; } +final class Schema12 extends i0.VersionedSchema { + Schema12({required super.database}) : super(version: 12); + @override + late final List entities = [ + userEntity, + remoteAssetEntity, + stackEntity, + localAssetEntity, + remoteAlbumEntity, + localAlbumEntity, + localAlbumAssetEntity, + idxLocalAssetChecksum, + idxRemoteAssetOwnerChecksum, + uQRemoteAssetsOwnerChecksum, + uQRemoteAssetsOwnerLibraryChecksum, + idxRemoteAssetChecksum, + authUserEntity, + userMetadataEntity, + partnerEntity, + remoteExifEntity, + remoteAlbumAssetEntity, + remoteAlbumUserEntity, + memoryEntity, + memoryAssetEntity, + personEntity, + assetFaceEntity, + storeEntity, + idxLatLng, + ]; + late final Shape20 userEntity = Shape20( + source: i0.VersionedTable( + entityName: 'user_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_0, + _column_1, + _column_3, + _column_84, + _column_85, + _column_91, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape17 remoteAssetEntity = Shape17( + source: i0.VersionedTable( + entityName: 'remote_asset_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_1, + _column_8, + _column_9, + _column_5, + _column_10, + _column_11, + _column_12, + _column_0, + _column_13, + _column_14, + _column_15, + _column_16, + _column_17, + _column_18, + _column_19, + _column_20, + _column_21, + _column_86, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape3 stackEntity = Shape3( + source: i0.VersionedTable( + entityName: 'stack_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [_column_0, _column_9, _column_5, _column_15, _column_75], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape2 localAssetEntity = Shape2( + source: i0.VersionedTable( + entityName: 'local_asset_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_1, + _column_8, + _column_9, + _column_5, + _column_10, + _column_11, + _column_12, + _column_0, + _column_22, + _column_14, + _column_23, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape9 remoteAlbumEntity = Shape9( + source: i0.VersionedTable( + entityName: 'remote_album_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_0, + _column_1, + _column_56, + _column_9, + _column_5, + _column_15, + _column_57, + _column_58, + _column_59, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape19 localAlbumEntity = Shape19( + source: i0.VersionedTable( + entityName: 'local_album_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_0, + _column_1, + _column_5, + _column_31, + _column_32, + _column_90, + _column_33, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape22 localAlbumAssetEntity = Shape22( + source: i0.VersionedTable( + entityName: 'local_album_asset_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(asset_id, album_id)'], + columns: [_column_34, _column_35, _column_33], + attachedDatabase: database, + ), + alias: null, + ); + final i1.Index idxLocalAssetChecksum = i1.Index( + 'idx_local_asset_checksum', + 'CREATE INDEX IF NOT EXISTS idx_local_asset_checksum ON local_asset_entity (checksum)', + ); + final i1.Index idxRemoteAssetOwnerChecksum = i1.Index( + 'idx_remote_asset_owner_checksum', + 'CREATE INDEX IF NOT EXISTS idx_remote_asset_owner_checksum ON remote_asset_entity (owner_id, checksum)', + ); + final i1.Index uQRemoteAssetsOwnerChecksum = i1.Index( + 'UQ_remote_assets_owner_checksum', + 'CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_checksum ON remote_asset_entity (owner_id, checksum) WHERE(library_id IS NULL)', + ); + final i1.Index uQRemoteAssetsOwnerLibraryChecksum = i1.Index( + 'UQ_remote_assets_owner_library_checksum', + 'CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_library_checksum ON remote_asset_entity (owner_id, library_id, checksum) WHERE(library_id IS NOT NULL)', + ); + final i1.Index idxRemoteAssetChecksum = i1.Index( + 'idx_remote_asset_checksum', + 'CREATE INDEX IF NOT EXISTS idx_remote_asset_checksum ON remote_asset_entity (checksum)', + ); + late final Shape21 authUserEntity = Shape21( + source: i0.VersionedTable( + entityName: 'auth_user_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_0, + _column_1, + _column_3, + _column_2, + _column_84, + _column_85, + _column_92, + _column_93, + _column_7, + _column_94, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape4 userMetadataEntity = Shape4( + source: i0.VersionedTable( + entityName: 'user_metadata_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(user_id, "key")'], + columns: [_column_25, _column_26, _column_27], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape5 partnerEntity = Shape5( + source: i0.VersionedTable( + entityName: 'partner_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(shared_by_id, shared_with_id)'], + columns: [_column_28, _column_29, _column_30], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape8 remoteExifEntity = Shape8( + source: i0.VersionedTable( + entityName: 'remote_exif_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(asset_id)'], + columns: [ + _column_36, + _column_37, + _column_38, + _column_39, + _column_40, + _column_41, + _column_11, + _column_10, + _column_42, + _column_43, + _column_44, + _column_45, + _column_46, + _column_47, + _column_48, + _column_49, + _column_50, + _column_51, + _column_52, + _column_53, + _column_54, + _column_55, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape7 remoteAlbumAssetEntity = Shape7( + source: i0.VersionedTable( + entityName: 'remote_album_asset_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(asset_id, album_id)'], + columns: [_column_36, _column_60], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape10 remoteAlbumUserEntity = Shape10( + source: i0.VersionedTable( + entityName: 'remote_album_user_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(album_id, user_id)'], + columns: [_column_60, _column_25, _column_61], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape11 memoryEntity = Shape11( + source: i0.VersionedTable( + entityName: 'memory_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_0, + _column_9, + _column_5, + _column_18, + _column_15, + _column_8, + _column_62, + _column_63, + _column_64, + _column_65, + _column_66, + _column_67, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape12 memoryAssetEntity = Shape12( + source: i0.VersionedTable( + entityName: 'memory_asset_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(asset_id, memory_id)'], + columns: [_column_36, _column_68], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape14 personEntity = Shape14( + source: i0.VersionedTable( + entityName: 'person_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_0, + _column_9, + _column_5, + _column_15, + _column_1, + _column_69, + _column_71, + _column_72, + _column_73, + _column_74, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape15 assetFaceEntity = Shape15( + source: i0.VersionedTable( + entityName: 'asset_face_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [ + _column_0, + _column_36, + _column_76, + _column_77, + _column_78, + _column_79, + _column_80, + _column_81, + _column_82, + _column_83, + ], + attachedDatabase: database, + ), + alias: null, + ); + late final Shape18 storeEntity = Shape18( + source: i0.VersionedTable( + entityName: 'store_entity', + withoutRowId: true, + isStrict: true, + tableConstraints: ['PRIMARY KEY(id)'], + columns: [_column_87, _column_88, _column_89], + attachedDatabase: database, + ), + alias: null, + ); + final i1.Index idxLatLng = i1.Index( + 'idx_lat_lng', + 'CREATE INDEX IF NOT EXISTS idx_lat_lng ON remote_exif_entity (latitude, longitude)', + ); +} + i0.MigrationStepWithVersion migrationSteps({ required Future Function(i1.Migrator m, Schema2 schema) from1To2, required Future Function(i1.Migrator m, Schema3 schema) from2To3, @@ -4670,6 +5048,7 @@ i0.MigrationStepWithVersion migrationSteps({ required Future Function(i1.Migrator m, Schema9 schema) from8To9, required Future Function(i1.Migrator m, Schema10 schema) from9To10, required Future Function(i1.Migrator m, Schema11 schema) from10To11, + required Future Function(i1.Migrator m, Schema12 schema) from11To12, }) { return (currentVersion, database) async { switch (currentVersion) { @@ -4723,6 +5102,11 @@ i0.MigrationStepWithVersion migrationSteps({ final migrator = i1.Migrator(database, schema); await from10To11(migrator, schema); return 11; + case 11: + final schema = Schema12(database: database); + final migrator = i1.Migrator(database, schema); + await from11To12(migrator, schema); + return 12; default: throw ArgumentError.value('Unknown migration from $currentVersion'); } @@ -4740,6 +5124,7 @@ i1.OnUpgrade stepByStep({ required Future Function(i1.Migrator m, Schema9 schema) from8To9, required Future Function(i1.Migrator m, Schema10 schema) from9To10, required Future Function(i1.Migrator m, Schema11 schema) from10To11, + required Future Function(i1.Migrator m, Schema12 schema) from11To12, }) => i0.VersionedSchema.stepByStepHelper( step: migrationSteps( from1To2: from1To2, @@ -4752,5 +5137,6 @@ i1.OnUpgrade stepByStep({ from8To9: from8To9, from9To10: from9To10, from10To11: from10To11, + from11To12: from11To12, ), ); diff --git a/mobile/lib/infrastructure/repositories/sync_api.repository.dart b/mobile/lib/infrastructure/repositories/sync_api.repository.dart index 3969286d28..8bf2e80579 100644 --- a/mobile/lib/infrastructure/repositories/sync_api.repository.dart +++ b/mobile/lib/infrastructure/repositories/sync_api.repository.dart @@ -110,7 +110,6 @@ class SyncApiRepository { await onData(_parseLines(lines), abort, reset); } } catch (error, stack) { - _logger.severe("Error processing stream", error, stack); return Future.error(error, stack); } finally { client.close(); diff --git a/mobile/lib/infrastructure/repositories/timeline.repository.dart b/mobile/lib/infrastructure/repositories/timeline.repository.dart index 86f68c397e..14ffafa646 100644 --- a/mobile/lib/infrastructure/repositories/timeline.repository.dart +++ b/mobile/lib/infrastructure/repositories/timeline.repository.dart @@ -43,7 +43,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository { } return _db.mergedAssetDrift.mergedBucket(userIds: userIds, groupBy: groupBy.index).map((row) { - final date = row.bucketDate.dateFmt(groupBy); + final date = row.bucketDate.truncateDate(groupBy); return TimeBucket(date: date, assetCount: row.assetCount); }).watch(); } @@ -123,7 +123,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository { ..orderBy([OrderingTerm.desc(dateExp)]); return query.map((row) { - final timeline = row.read(dateExp)!.dateFmt(groupBy); + final timeline = row.read(dateExp)!.truncateDate(groupBy); final assetCount = row.read(assetCountExp)!; return TimeBucket(date: timeline, assetCount: assetCount); }).watch(); @@ -148,10 +148,9 @@ class DriftTimelineRepository extends DriftDatabaseRepository { ..orderBy([OrderingTerm.desc(_db.localAssetEntity.createdAt)]) ..limit(count, offset: offset); - return query.map((row) { - final asset = row.readTable(_db.localAssetEntity).toDto(); - return asset.copyWith(remoteId: row.read(_db.remoteAssetEntity.id)); - }).get(); + return query + .map((row) => row.readTable(_db.localAssetEntity).toDto(remoteId: row.read(_db.remoteAssetEntity.id))) + .get(); } TimelineQuery remoteAlbum(String albumId, GroupAssetsBy groupBy) => ( @@ -165,17 +164,15 @@ class DriftTimelineRepository extends DriftDatabaseRepository { .count(where: (row) => row.albumId.equals(albumId)) .map(_generateBuckets) .watch() - .map((results) => results.isNotEmpty ? results.first : []) - .handleError((error) { - return []; - }); + .map((results) => results.isNotEmpty ? results.first : const []) + .handleError((error) => const []); } return (_db.remoteAlbumEntity.select()..where((row) => row.id.equals(albumId))) .watch() .switchMap((albums) { if (albums.isEmpty) { - return Stream.value([]); + return Stream.value(const []); } final album = albums.first; @@ -202,15 +199,13 @@ class DriftTimelineRepository extends DriftDatabaseRepository { } return query.map((row) { - final timeline = row.read(dateExp)!.dateFmt(groupBy); + final timeline = row.read(dateExp)!.truncateDate(groupBy); final assetCount = row.read(assetCountExp)!; return TimeBucket(date: timeline, assetCount: assetCount); }).watch(); }) - .handleError((error) { - // If there's an error (e.g., album was deleted), return empty buckets - return []; - }); + // If there's an error (e.g., album was deleted), return empty buckets + .handleError((error) => const []); } Future> _getRemoteAlbumBucketAssets(String albumId, {required int offset, required int count}) async { @@ -218,17 +213,22 @@ class DriftTimelineRepository extends DriftDatabaseRepository { // If album doesn't exist (was deleted), return empty list if (albumData == null) { - return []; + return const []; } final isAscending = albumData.order == AlbumAssetOrder.asc; - final query = _db.remoteAssetEntity.select().join([ + final query = _db.remoteAssetEntity.select().addColumns([_db.localAssetEntity.id]).join([ innerJoin( _db.remoteAlbumAssetEntity, _db.remoteAlbumAssetEntity.assetId.equalsExp(_db.remoteAssetEntity.id), useColumns: false, ), + leftOuterJoin( + _db.localAssetEntity, + _db.remoteAssetEntity.checksum.equalsExp(_db.localAssetEntity.checksum), + useColumns: false, + ), ])..where(_db.remoteAssetEntity.deletedAt.isNull() & _db.remoteAlbumAssetEntity.albumId.equals(albumId)); if (isAscending) { @@ -239,12 +239,14 @@ class DriftTimelineRepository extends DriftDatabaseRepository { query.limit(count, offset: offset); - return query.map((row) => row.readTable(_db.remoteAssetEntity).toDto()).get(); + return query + .map((row) => row.readTable(_db.remoteAssetEntity).toDto(localId: row.read(_db.localAssetEntity.id))) + .get(); } TimelineQuery fromAssets(List assets) => ( bucketSource: () => Stream.value(_generateBuckets(assets.length)), - assetSource: (offset, count) => Future.value(assets.skip(offset).take(count).toList()), + assetSource: (offset, count) => Future.value(assets.skip(offset).take(count).toList(growable: false)), ); TimelineQuery remote(String ownerId, GroupAssetsBy groupBy) => _remoteQueryBuilder( @@ -326,7 +328,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository { ..orderBy([OrderingTerm.desc(dateExp)]); return query.map((row) { - final timeline = row.read(dateExp)!.dateFmt(groupBy); + final timeline = row.read(dateExp)!.truncateDate(groupBy); final assetCount = row.read(assetCountExp)!; return TimeBucket(date: timeline, assetCount: assetCount); }).watch(); @@ -397,7 +399,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository { ..orderBy([OrderingTerm.desc(dateExp)]); return query.map((row) { - final timeline = row.read(dateExp)!.dateFmt(groupBy); + final timeline = row.read(dateExp)!.truncateDate(groupBy); final assetCount = row.read(assetCountExp)!; return TimeBucket(date: timeline, assetCount: assetCount); }).watch(); @@ -461,7 +463,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository { ..orderBy([OrderingTerm.desc(dateExp)]); return query.map((row) { - final timeline = row.read(dateExp)!.dateFmt(groupBy); + final timeline = row.read(dateExp)!.truncateDate(groupBy); final assetCount = row.read(assetCountExp)!; return TimeBucket(date: timeline, assetCount: assetCount); }).watch(); @@ -486,6 +488,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository { return query.map((row) => row.readTable(_db.remoteAssetEntity).toDto()).get(); } + @pragma('vm:prefer-inline') TimelineQuery _remoteQueryBuilder({ required Expression Function($RemoteAssetEntityTable row) filter, GroupAssetsBy groupBy = GroupAssetsBy.day, @@ -517,12 +520,13 @@ class DriftTimelineRepository extends DriftDatabaseRepository { ..orderBy([OrderingTerm.desc(dateExp)]); return query.map((row) { - final timeline = row.read(dateExp)!.dateFmt(groupBy); + final timeline = row.read(dateExp)!.truncateDate(groupBy); final assetCount = row.read(assetCountExp)!; return TimeBucket(date: timeline, assetCount: assetCount); }).watch(); } + @pragma('vm:prefer-inline') Future> _getRemoteAssets({ required Expression Function($RemoteAssetEntityTable row) filter, required int offset, @@ -543,11 +547,9 @@ class DriftTimelineRepository extends DriftDatabaseRepository { ..orderBy([OrderingTerm.desc(_db.remoteAssetEntity.createdAt)]) ..limit(count, offset: offset); - return query.map((row) { - final asset = row.readTable(_db.remoteAssetEntity).toDto(); - final localId = row.read(_db.localAssetEntity.id); - return asset.copyWith(localId: localId); - }).get(); + return query + .map((row) => row.readTable(_db.remoteAssetEntity).toDto(localId: row.read(_db.localAssetEntity.id))) + .get(); } else { final query = _db.remoteAssetEntity.select() ..where(filter) @@ -560,12 +562,12 @@ class DriftTimelineRepository extends DriftDatabaseRepository { } List _generateBuckets(int count) { - final buckets = List.generate( - (count / kTimelineNoneSegmentSize).floor(), - (_) => const Bucket(assetCount: kTimelineNoneSegmentSize), + final buckets = List.filled( + (count / kTimelineNoneSegmentSize).ceil(), + const Bucket(assetCount: kTimelineNoneSegmentSize), ); if (count % kTimelineNoneSegmentSize != 0) { - buckets.add(Bucket(assetCount: count % kTimelineNoneSegmentSize)); + buckets[buckets.length - 1] = Bucket(assetCount: count % kTimelineNoneSegmentSize); } return buckets; } @@ -584,16 +586,12 @@ extension on Expression { } extension on String { - DateTime dateFmt(GroupAssetsBy groupBy) { + DateTime truncateDate(GroupAssetsBy groupBy) { final format = switch (groupBy) { GroupAssetsBy.day || GroupAssetsBy.auto => "y-M-d", GroupAssetsBy.month => "y-M", GroupAssetsBy.none => throw ArgumentError("GroupAssetsBy.none is not supported for date formatting"), }; - try { - return DateFormat(format, 'en').parse(this); - } catch (e) { - throw FormatException("Invalid date format: $this", e); - } + return DateFormat(format, 'en').parse(this); } } diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart index 7d944c54ce..712ee0bd83 100644 --- a/mobile/lib/main.dart +++ b/mobile/lib/main.dart @@ -12,9 +12,11 @@ import 'package:flutter_displaymode/flutter_displaymode.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/constants.dart'; import 'package:immich_mobile/constants/locales.dart'; +import 'package:immich_mobile/domain/services/background_worker.service.dart'; import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/generated/codegen_loader.g.dart'; +import 'package:immich_mobile/platform/background_worker_lock_api.g.dart'; import 'package:immich_mobile/providers/app_life_cycle.provider.dart'; import 'package:immich_mobile/providers/asset_viewer/share_intent_upload.provider.dart'; import 'package:immich_mobile/providers/db.provider.dart'; @@ -32,6 +34,7 @@ import 'package:immich_mobile/theme/dynamic_theme.dart'; import 'package:immich_mobile/theme/theme_data.dart'; import 'package:immich_mobile/utils/bootstrap.dart'; import 'package:immich_mobile/utils/cache/widgets_binding.dart'; +import 'package:immich_mobile/utils/debug_print.dart'; import 'package:immich_mobile/utils/http_ssl_options.dart'; import 'package:immich_mobile/utils/licenses.dart'; import 'package:immich_mobile/utils/migration.dart'; @@ -39,10 +42,10 @@ import 'package:intl/date_symbol_data_local.dart'; import 'package:logging/logging.dart'; import 'package:timezone/data/latest.dart'; import 'package:worker_manager/worker_manager.dart'; -import 'package:immich_mobile/utils/debug_print.dart'; void main() async { ImmichWidgetsBinding(); + unawaited(BackgroundWorkerLockService(BackgroundWorkerLockApi()).lock()); final (isar, drift, logDb) = await Bootstrap.initDB(); await Bootstrap.initDomain(isar, drift, logDb); await initApp(); diff --git a/mobile/lib/pages/backup/drift_backup.page.dart b/mobile/lib/pages/backup/drift_backup.page.dart index 8578506ced..5a2cab8dd6 100644 --- a/mobile/lib/pages/backup/drift_backup.page.dart +++ b/mobile/lib/pages/backup/drift_backup.page.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:auto_route/auto_route.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; @@ -8,6 +10,7 @@ import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/theme_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; +import 'package:immich_mobile/generated/intl_keys.g.dart'; import 'package:immich_mobile/presentation/widgets/backup/backup_toggle_button.widget.dart'; import 'package:immich_mobile/providers/background_sync.provider.dart'; import 'package:immich_mobile/providers/backup/backup_album.provider.dart'; @@ -16,6 +19,8 @@ import 'package:immich_mobile/providers/sync_status.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/widgets/backup/backup_info_card.dart'; +import 'package:logging/logging.dart'; +import 'package:wakelock_plus/wakelock_plus.dart'; @RoutePage() class DriftBackupPage extends ConsumerStatefulWidget { @@ -26,9 +31,14 @@ class DriftBackupPage extends ConsumerStatefulWidget { } class _DriftBackupPageState extends ConsumerState { + bool? syncSuccess; + @override void initState() { super.initState(); + + WakelockPlus.enable(); + final currentUser = ref.read(currentUserProvider); if (currentUser == null) { return; @@ -36,7 +46,13 @@ class _DriftBackupPageState extends ConsumerState { WidgetsBinding.instance.addPostFrameCallback((_) async { await ref.read(driftBackupProvider.notifier).getBackupStatus(currentUser.id); - await ref.read(backgroundSyncProvider).syncRemote(); + + ref.read(driftBackupProvider.notifier).updateSyncing(true); + syncSuccess = await ref.read(backgroundSyncProvider).syncRemote(); + ref + .read(driftBackupProvider.notifier) + .updateError(syncSuccess == true ? BackupError.none : BackupError.syncFailed); + ref.read(driftBackupProvider.notifier).updateSyncing(false); if (mounted) { await ref.read(driftBackupProvider.notifier).getBackupStatus(currentUser.id); @@ -44,6 +60,12 @@ class _DriftBackupPageState extends ConsumerState { }); } + @override + dispose() { + super.dispose(); + WakelockPlus.disable(); + } + @override Widget build(BuildContext context) { final selectedAlbum = ref @@ -51,7 +73,10 @@ class _DriftBackupPageState extends ConsumerState { .where((album) => album.backupSelection == BackupSelection.selected) .toList(); + final error = ref.watch(driftBackupProvider.select((p) => p.error)); + final backupNotifier = ref.read(driftBackupProvider.notifier); + final backupSyncManager = ref.read(backgroundSyncProvider); Future startBackup() async { final currentUser = Store.tryGet(StoreKey.currentUser); @@ -59,7 +84,19 @@ class _DriftBackupPageState extends ConsumerState { return; } + if (syncSuccess == null) { + ref.read(driftBackupProvider.notifier).updateSyncing(true); + syncSuccess = await backupSyncManager.syncRemote(); + ref.read(driftBackupProvider.notifier).updateSyncing(false); + } + await backupNotifier.getBackupStatus(currentUser.id); + + if (syncSuccess == false) { + Logger("DriftBackupPage").warning("Remote sync did not complete successfully, skipping backup"); + backupNotifier.updateError(BackupError.syncFailed); + return; + } await backupNotifier.startBackup(currentUser.id); } @@ -101,7 +138,33 @@ class _DriftBackupPageState extends ConsumerState { const _BackupCard(), const _RemainderCard(), const Divider(), - BackupToggleButton(onStart: () async => await startBackup(), onStop: () async => await stopBackup()), + BackupToggleButton( + onStart: () async => await startBackup(), + onStop: () async { + syncSuccess = null; + await stopBackup(); + }, + ), + switch (error) { + BackupError.none => const SizedBox.shrink(), + BackupError.syncFailed => Padding( + padding: const EdgeInsets.only(top: 10), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + children: [ + Icon(Icons.warning_rounded, color: context.colorScheme.error, fill: 1), + const SizedBox(width: 8), + Text( + IntlKeys.backup_error_sync_failed.t(), + style: context.textTheme.bodyMedium?.copyWith(color: context.colorScheme.error), + textAlign: TextAlign.center, + ), + ], + ), + ), + }, TextButton.icon( icon: const Icon(Icons.info_outline_rounded), onPressed: () => context.pushRoute(const DriftUploadDetailRoute()), @@ -260,12 +323,205 @@ class _RemainderCard extends ConsumerWidget { final remainderCount = ref.watch(driftBackupProvider.select((p) => p.remainderCount)); final syncStatus = ref.watch(syncStatusProvider); - return BackupInfoCard( - title: "backup_controller_page_remainder".tr(), - subtitle: "backup_controller_page_remainder_sub".tr(), - info: remainderCount.toString(), - isLoading: syncStatus.isRemoteSyncing, - onTap: () => context.pushRoute(const DriftBackupAssetDetailRoute()), + return Card( + shape: RoundedRectangleBorder( + borderRadius: const BorderRadius.all(Radius.circular(20)), + side: BorderSide(color: context.colorScheme.outlineVariant, width: 1), + ), + elevation: 0, + borderOnForeground: false, + child: Column( + children: [ + ListTile( + minVerticalPadding: 18, + isThreeLine: true, + title: Text("backup_controller_page_remainder".t(context: context), style: context.textTheme.titleMedium), + subtitle: Padding( + padding: const EdgeInsets.only(top: 4.0, right: 18.0), + child: Text( + "backup_controller_page_remainder_sub".t(context: context), + style: context.textTheme.bodyMedium?.copyWith(color: context.colorScheme.onSurfaceSecondary), + ), + ), + trailing: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Stack( + children: [ + Text( + remainderCount.toString(), + style: context.textTheme.titleLarge?.copyWith( + color: context.colorScheme.onSurface.withAlpha(syncStatus.isRemoteSyncing ? 50 : 255), + ), + ), + if (syncStatus.isRemoteSyncing) + Positioned.fill( + child: Align( + alignment: Alignment.center, + child: SizedBox( + width: 16, + height: 16, + child: CircularProgressIndicator( + strokeWidth: 2, + color: context.colorScheme.onSurface.withAlpha(150), + ), + ), + ), + ), + ], + ), + Text( + "backup_info_card_assets", + style: context.textTheme.labelLarge?.copyWith( + color: context.colorScheme.onSurface.withAlpha(syncStatus.isRemoteSyncing ? 50 : 255), + ), + ).tr(), + ], + ), + ), + const Divider(height: 0), + const _PreparingStatus(), + const Divider(height: 0), + + ListTile( + enableFeedback: true, + visualDensity: VisualDensity.compact, + contentPadding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 0.0), + shape: const RoundedRectangleBorder( + borderRadius: BorderRadius.only(bottomLeft: Radius.circular(20), bottomRight: Radius.circular(20)), + ), + onTap: () => context.pushRoute(const DriftBackupAssetDetailRoute()), + title: Text( + "view_details".t(context: context), + style: context.textTheme.labelLarge?.copyWith(color: context.colorScheme.onSurface.withAlpha(200)), + ), + trailing: Icon(Icons.arrow_forward_ios, size: 16, color: context.colorScheme.onSurfaceVariant), + ), + ], + ), + ); + } +} + +class _PreparingStatus extends ConsumerStatefulWidget { + const _PreparingStatus(); + + @override + _PreparingStatusState createState() => _PreparingStatusState(); +} + +class _PreparingStatusState extends ConsumerState { + Timer? _pollingTimer; + + @override + void dispose() { + _pollingTimer?.cancel(); + super.dispose(); + } + + void _startPollingIfNeeded() { + if (_pollingTimer != null) return; + + _pollingTimer = Timer.periodic(const Duration(seconds: 3), (timer) async { + final currentUser = ref.read(currentUserProvider); + if (currentUser != null && mounted) { + await ref.read(driftBackupProvider.notifier).getBackupStatus(currentUser.id); + + // Stop polling if processing count reaches 0 + final updatedProcessingCount = ref.read(driftBackupProvider.select((p) => p.processingCount)); + if (updatedProcessingCount == 0) { + timer.cancel(); + _pollingTimer = null; + } + } else { + timer.cancel(); + _pollingTimer = null; + } + }); + } + + @override + Widget build(BuildContext context) { + final syncStatus = ref.watch(syncStatusProvider); + final remainderCount = ref.watch(driftBackupProvider.select((p) => p.remainderCount)); + final processingCount = ref.watch(driftBackupProvider.select((p) => p.processingCount)); + final readyForUploadCount = remainderCount - processingCount; + + ref.listen(driftBackupProvider.select((p) => p.processingCount), (previous, next) { + if (next > 0 && _pollingTimer == null) { + _startPollingIfNeeded(); + } else if (next == 0 && _pollingTimer != null) { + _pollingTimer?.cancel(); + _pollingTimer = null; + } + }); + + if (!syncStatus.isHashing) { + return const SizedBox.shrink(); + } + + return Row( + children: [ + Expanded( + child: Padding( + padding: const EdgeInsets.only(left: 1.0), + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8), + decoration: BoxDecoration( + color: context.colorScheme.surfaceContainerHigh.withValues(alpha: 0.5), + shape: BoxShape.rectangle, + ), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + Text( + "preparing".t(context: context), + style: context.textTheme.labelLarge?.copyWith( + color: context.colorScheme.onSurface.withAlpha(200), + ), + ), + const SizedBox(width: 18, height: 18, child: CircularProgressIndicator(strokeWidth: 1.5)), + ], + ), + const SizedBox(height: 2), + Text( + processingCount.toString(), + style: context.textTheme.titleMedium?.copyWith( + color: context.colorScheme.primary, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + ), + ), + Expanded( + child: Container( + padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8), + decoration: BoxDecoration(color: context.colorScheme.primary.withValues(alpha: 0.1)), + child: Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + "ready_for_upload".t(context: context), + style: context.textTheme.labelLarge?.copyWith(color: context.colorScheme.onSurface.withAlpha(200)), + ), + const SizedBox(height: 2), + Text( + readyForUploadCount.toString(), + style: context.textTheme.titleMedium?.copyWith( + color: context.primaryColor, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ), + ), + ], ); } } diff --git a/mobile/lib/pages/backup/drift_backup_album_selection.page.dart b/mobile/lib/pages/backup/drift_backup_album_selection.page.dart index 368341f24a..d49f71ce52 100644 --- a/mobile/lib/pages/backup/drift_backup_album_selection.page.dart +++ b/mobile/lib/pages/backup/drift_backup_album_selection.page.dart @@ -18,6 +18,7 @@ import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/services/app_settings.service.dart'; import 'package:immich_mobile/widgets/backup/drift_album_info_list_tile.dart'; import 'package:immich_mobile/widgets/common/search_field.dart'; +import 'package:logging/logging.dart'; @RoutePage() class DriftBackupAlbumSelectionPage extends ConsumerStatefulWidget { @@ -112,7 +113,18 @@ class _DriftBackupAlbumSelectionPageState extends ConsumerState backgroundSync.hashAssets())); if (isBackupEnabled) { - unawaited(backupNotifier.cancel().whenComplete(() => backupNotifier.startBackup(user.id))); + unawaited( + backupNotifier.cancel().whenComplete( + () => backgroundSync.syncRemote().then((success) { + if (success) { + return backupNotifier.startBackup(user.id); + } else { + Logger('DriftBackupAlbumSelectionPage').warning('Background sync failed, not starting backup'); + backupNotifier.updateError(BackupError.syncFailed); + } + }), + ), + ); } } diff --git a/mobile/lib/pages/backup/drift_backup_options.page.dart b/mobile/lib/pages/backup/drift_backup_options.page.dart index 92f911ae1e..f18dc48dca 100644 --- a/mobile/lib/pages/backup/drift_backup_options.page.dart +++ b/mobile/lib/pages/backup/drift_backup_options.page.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -5,10 +7,12 @@ import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/providers/app_settings.provider.dart'; +import 'package:immich_mobile/providers/background_sync.provider.dart'; import 'package:immich_mobile/providers/backup/drift_backup.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/services/app_settings.service.dart'; import 'package:immich_mobile/widgets/settings/backup_settings/drift_backup_settings.dart'; +import 'package:logging/logging.dart'; @RoutePage() class DriftBackupOptionsPage extends ConsumerWidget { @@ -54,9 +58,19 @@ class DriftBackupOptionsPage extends ConsumerWidget { ); final backupNotifier = ref.read(driftBackupProvider.notifier); - backupNotifier.cancel().then((_) { - backupNotifier.startBackup(currentUser.id); - }); + final backgroundSync = ref.read(backgroundSyncProvider); + unawaited( + backupNotifier.cancel().whenComplete( + () => backgroundSync.syncRemote().then((success) { + if (success) { + return backupNotifier.startBackup(currentUser.id); + } else { + Logger('DriftBackupOptionsPage').warning('Background sync failed, not starting backup'); + backupNotifier.updateError(BackupError.syncFailed); + } + }), + ), + ); } }, child: Scaffold( diff --git a/mobile/lib/pages/backup/drift_upload_detail.page.dart b/mobile/lib/pages/backup/drift_upload_detail.page.dart index bececddc7f..80956b708f 100644 --- a/mobile/lib/pages/backup/drift_upload_detail.page.dart +++ b/mobile/lib/pages/backup/drift_upload_detail.page.dart @@ -1,12 +1,12 @@ import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; -import 'package:immich_mobile/providers/backup/drift_backup.provider.dart'; -import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; -import 'package:immich_mobile/providers/infrastructure/asset.provider.dart'; import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart'; +import 'package:immich_mobile/providers/backup/drift_backup.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/asset.provider.dart'; import 'package:immich_mobile/utils/bytes_units.dart'; import 'package:path/path.dart' as path; @@ -82,6 +82,7 @@ class DriftUploadDetailPage extends ConsumerWidget { Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, + spacing: 4, children: [ Text( path.basename(item.filename), @@ -89,7 +90,13 @@ class DriftUploadDetailPage extends ConsumerWidget { maxLines: 1, overflow: TextOverflow.ellipsis, ), - const SizedBox(height: 4), + if (item.error != null) + Text( + item.error!, + style: context.textTheme.bodySmall?.copyWith( + color: context.colorScheme.onErrorContainer.withValues(alpha: 0.6), + ), + ), Text( 'Tap for more details', style: context.textTheme.bodySmall?.copyWith( diff --git a/mobile/lib/pages/common/change_experience.page.dart b/mobile/lib/pages/common/change_experience.page.dart index 2e78b79232..2cc3dede1e 100644 --- a/mobile/lib/pages/common/change_experience.page.dart +++ b/mobile/lib/pages/common/change_experience.page.dart @@ -18,6 +18,7 @@ import 'package:immich_mobile/providers/infrastructure/db.provider.dart'; import 'package:immich_mobile/providers/infrastructure/platform.provider.dart'; import 'package:immich_mobile/providers/infrastructure/readonly_mode.provider.dart'; import 'package:immich_mobile/providers/websocket.provider.dart'; +import 'package:immich_mobile/services/app_settings.service.dart'; import 'package:immich_mobile/services/background.service.dart'; import 'package:immich_mobile/utils/migration.dart'; import 'package:logging/logging.dart'; @@ -93,6 +94,10 @@ class _ChangeExperiencePageState extends ConsumerState { await ref.read(driftProvider).reset(); await Store.put(StoreKey.shouldResetSync, true); + final delay = Store.get(StoreKey.backupTriggerDelay, AppSettingsEnum.backupTriggerDelay.defaultValue); + if (delay >= 1000) { + await Store.put(StoreKey.backupTriggerDelay, (delay / 1000).toInt()); + } final permission = await ref.read(galleryPermissionNotifier.notifier).requestGalleryPermission(); if (permission.isGranted) { diff --git a/mobile/lib/pages/common/splash_screen.page.dart b/mobile/lib/pages/common/splash_screen.page.dart index f288464c42..5147ba8f45 100644 --- a/mobile/lib/pages/common/splash_screen.page.dart +++ b/mobile/lib/pages/common/splash_screen.page.dart @@ -1,3 +1,5 @@ +import 'dart:async'; + import 'package:auto_route/auto_route.dart'; import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; @@ -60,14 +62,24 @@ class SplashScreenPageState extends ConsumerState { infoProvider.getServerInfo(); if (Store.isBetaTimelineEnabled) { - await Future.wait([backgroundManager.syncLocal(), backgroundManager.syncRemote()]); + bool syncSuccess = false; await Future.wait([ - backgroundManager.hashAssets().then((_) { - _resumeBackup(backupProvider); - }), - _resumeBackup(backupProvider), + backgroundManager.syncLocal(full: true), + backgroundManager.syncRemote().then((success) => syncSuccess = success), ]); + if (syncSuccess) { + await Future.wait([ + backgroundManager.hashAssets().then((_) { + _resumeBackup(backupProvider); + }), + _resumeBackup(backupProvider), + ]); + } else { + backupProvider.updateError(BackupError.syncFailed); + await backgroundManager.hashAssets(); + } + if (Store.get(StoreKey.syncAlbums, false)) { await backgroundManager.syncLinkedAlbum(); } diff --git a/mobile/lib/platform/background_worker_lock_api.g.dart b/mobile/lib/platform/background_worker_lock_api.g.dart new file mode 100644 index 0000000000..9f00017dc8 --- /dev/null +++ b/mobile/lib/platform/background_worker_lock_api.g.dart @@ -0,0 +1,97 @@ +// Autogenerated from Pigeon (v26.0.0), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +PlatformException _createConnectionError(String channelName) { + return PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel: "$channelName".', + ); +} + +class _PigeonCodec extends StandardMessageCodec { + const _PigeonCodec(); + @override + void writeValue(WriteBuffer buffer, Object? value) { + if (value is int) { + buffer.putUint8(4); + buffer.putInt64(value); + } else { + super.writeValue(buffer, value); + } + } + + @override + Object? readValueOfType(int type, ReadBuffer buffer) { + switch (type) { + default: + return super.readValueOfType(type, buffer); + } + } +} + +class BackgroundWorkerLockApi { + /// Constructor for [BackgroundWorkerLockApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + BackgroundWorkerLockApi({BinaryMessenger? binaryMessenger, String messageChannelSuffix = ''}) + : pigeonVar_binaryMessenger = binaryMessenger, + pigeonVar_messageChannelSuffix = messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; + final BinaryMessenger? pigeonVar_binaryMessenger; + + static const MessageCodec pigeonChannelCodec = _PigeonCodec(); + + final String pigeonVar_messageChannelSuffix; + + Future lock() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.immich_mobile.BackgroundWorkerLockApi.lock$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); + final List? pigeonVar_replyList = await pigeonVar_sendFuture as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } + + Future unlock() async { + final String pigeonVar_channelName = + 'dev.flutter.pigeon.immich_mobile.BackgroundWorkerLockApi.unlock$pigeonVar_messageChannelSuffix'; + final BasicMessageChannel pigeonVar_channel = BasicMessageChannel( + pigeonVar_channelName, + pigeonChannelCodec, + binaryMessenger: pigeonVar_binaryMessenger, + ); + final Future pigeonVar_sendFuture = pigeonVar_channel.send(null); + final List? pigeonVar_replyList = await pigeonVar_sendFuture as List?; + if (pigeonVar_replyList == null) { + throw _createConnectionError(pigeonVar_channelName); + } else if (pigeonVar_replyList.length > 1) { + throw PlatformException( + code: pigeonVar_replyList[0]! as String, + message: pigeonVar_replyList[1] as String?, + details: pigeonVar_replyList[2], + ); + } else { + return; + } + } +} diff --git a/mobile/lib/presentation/pages/drift_map.page.dart b/mobile/lib/presentation/pages/drift_map.page.dart index 30da6410b5..de8dde7714 100644 --- a/mobile/lib/presentation/pages/drift_map.page.dart +++ b/mobile/lib/presentation/pages/drift_map.page.dart @@ -25,9 +25,10 @@ class DriftMapPage extends StatelessWidget { onPressed: () => context.pop(), icon: const Icon(Icons.arrow_back_ios_new_rounded), style: IconButton.styleFrom( - shape: const CircleBorder(side: BorderSide(width: 1, color: Colors.black26)), padding: const EdgeInsets.all(8), - backgroundColor: Colors.indigo.withValues(alpha: 0.7), + backgroundColor: Colors.indigo, + shadowColor: Colors.black26, + elevation: 4, ), ), ), diff --git a/mobile/lib/presentation/widgets/action_buttons/share_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/share_action_button.widget.dart index 3c943f0501..740ac528b0 100644 --- a/mobile/lib/presentation/widgets/action_buttons/share_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/share_action_button.widget.dart @@ -42,7 +42,7 @@ class ShareActionButton extends ConsumerWidget { showDialog( context: context, builder: (BuildContext buildContext) { - ref.read(actionProvider.notifier).shareAssets(source).then((ActionResult result) { + ref.read(actionProvider.notifier).shareAssets(source, context).then((ActionResult result) { ref.read(multiSelectProvider.notifier).reset(); if (!context.mounted) { diff --git a/mobile/lib/presentation/widgets/action_buttons/unstack_action_button.widget.dart b/mobile/lib/presentation/widgets/action_buttons/unstack_action_button.widget.dart index ecc8a39c74..a07803ace5 100644 --- a/mobile/lib/presentation/widgets/action_buttons/unstack_action_button.widget.dart +++ b/mobile/lib/presentation/widgets/action_buttons/unstack_action_button.widget.dart @@ -36,7 +36,7 @@ class UnStackActionButton extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { return BaseActionButton( - iconData: Icons.filter_none_rounded, + iconData: Icons.layers_clear_outlined, label: "unstack".t(context: context), onPressed: () => _onTap(context, ref), ); diff --git a/mobile/lib/presentation/widgets/asset_viewer/bottom_sheet.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/bottom_sheet.widget.dart index 7431290ad8..2586789beb 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/bottom_sheet.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/bottom_sheet.widget.dart @@ -51,6 +51,7 @@ class AssetDetailBottomSheet extends ConsumerWidget { isArchived: isArchived, isTrashEnabled: isTrashEnable, isInLockedView: isInLockedView, + isStacked: asset.hasRemote && (asset as RemoteAsset).stackId != null, currentAlbum: currentAlbum, advancedTroubleshooting: advancedTroubleshooting, source: ActionSource.viewer, diff --git a/mobile/lib/presentation/widgets/asset_viewer/top_app_bar.widget.dart b/mobile/lib/presentation/widgets/asset_viewer/top_app_bar.widget.dart index 0159e04c4e..10c9821eb0 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/top_app_bar.widget.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/top_app_bar.widget.dart @@ -57,7 +57,7 @@ class ViewerTopAppBar extends ConsumerWidget implements PreferredSizeWidget { final isCasting = ref.watch(castProvider.select((c) => c.isCasting)); final actions = [ - if (asset.hasRemote) const DownloadActionButton(source: ActionSource.viewer, menuItem: true), + if (asset.isRemoteOnly) const DownloadActionButton(source: ActionSource.viewer, menuItem: true), if (isCasting || (asset.hasRemote)) const CastActionButton(menuItem: true), if (album != null && album.isActivityEnabled && album.isShared) IconButton( diff --git a/mobile/lib/presentation/widgets/backup/backup_toggle_button.widget.dart b/mobile/lib/presentation/widgets/backup/backup_toggle_button.widget.dart index a74c169224..8d374f74ff 100644 --- a/mobile/lib/presentation/widgets/backup/backup_toggle_button.widget.dart +++ b/mobile/lib/presentation/widgets/backup/backup_toggle_button.widget.dart @@ -65,7 +65,9 @@ class BackupToggleButtonState extends ConsumerState with Sin final uploadTasks = ref.watch(driftBackupProvider.select((state) => state.uploadItems)); - final isUploading = uploadTasks.isNotEmpty; + final isSyncing = ref.watch(driftBackupProvider.select((state) => state.isSyncing)); + + final isProcessing = uploadTasks.isNotEmpty || isSyncing; return AnimatedBuilder( animation: _animationController, @@ -129,7 +131,7 @@ class BackupToggleButtonState extends ConsumerState with Sin ], ), ), - child: isUploading + child: isProcessing ? const SizedBox(width: 24, height: 24, child: CircularProgressIndicator(strokeWidth: 2)) : Icon(Icons.cloud_upload_outlined, color: context.primaryColor, size: 24), ), diff --git a/mobile/lib/presentation/widgets/bottom_sheet/archive_bottom_sheet.widget.dart b/mobile/lib/presentation/widgets/bottom_sheet/archive_bottom_sheet.widget.dart index 558df4e496..f40e189e18 100644 --- a/mobile/lib/presentation/widgets/bottom_sheet/archive_bottom_sheet.widget.dart +++ b/mobile/lib/presentation/widgets/bottom_sheet/archive_bottom_sheet.widget.dart @@ -13,6 +13,7 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/share_link_act import 'package:immich_mobile/presentation/widgets/action_buttons/stack_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/trash_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/unarchive_action_button.widget.dart'; +import 'package:immich_mobile/presentation/widgets/action_buttons/unstack_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/upload_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart'; import 'package:immich_mobile/providers/server_info.provider.dart'; @@ -44,6 +45,7 @@ class ArchiveBottomSheet extends ConsumerWidget { const EditLocationActionButton(source: ActionSource.timeline), const MoveToLockFolderActionButton(source: ActionSource.timeline), if (multiselect.selectedAssets.length > 1) const StackActionButton(source: ActionSource.timeline), + if (multiselect.hasStacked) const UnStackActionButton(source: ActionSource.timeline), ], if (multiselect.hasLocal) ...[ const DeleteLocalActionButton(source: ActionSource.timeline), diff --git a/mobile/lib/presentation/widgets/bottom_sheet/favorite_bottom_sheet.widget.dart b/mobile/lib/presentation/widgets/bottom_sheet/favorite_bottom_sheet.widget.dart index a162dbbfb2..c7a0fbab40 100644 --- a/mobile/lib/presentation/widgets/bottom_sheet/favorite_bottom_sheet.widget.dart +++ b/mobile/lib/presentation/widgets/bottom_sheet/favorite_bottom_sheet.widget.dart @@ -13,6 +13,7 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/share_link_act import 'package:immich_mobile/presentation/widgets/action_buttons/stack_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/trash_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/unfavorite_action_button.widget.dart'; +import 'package:immich_mobile/presentation/widgets/action_buttons/unstack_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/upload_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart'; import 'package:immich_mobile/providers/server_info.provider.dart'; @@ -44,6 +45,7 @@ class FavoriteBottomSheet extends ConsumerWidget { const EditLocationActionButton(source: ActionSource.timeline), const MoveToLockFolderActionButton(source: ActionSource.timeline), if (multiselect.selectedAssets.length > 1) const StackActionButton(source: ActionSource.timeline), + if (multiselect.hasStacked) const UnStackActionButton(source: ActionSource.timeline), ], if (multiselect.hasLocal) ...[ const DeleteLocalActionButton(source: ActionSource.timeline), diff --git a/mobile/lib/presentation/widgets/bottom_sheet/general_bottom_sheet.widget.dart b/mobile/lib/presentation/widgets/bottom_sheet/general_bottom_sheet.widget.dart index 73ebf60067..9436707c84 100644 --- a/mobile/lib/presentation/widgets/bottom_sheet/general_bottom_sheet.widget.dart +++ b/mobile/lib/presentation/widgets/bottom_sheet/general_bottom_sheet.widget.dart @@ -5,6 +5,7 @@ import 'package:immich_mobile/constants/enums.dart'; import 'package:immich_mobile/domain/models/album/album.model.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/setting.model.dart'; +import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/advanced_info_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/archive_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/delete_action_button.widget.dart'; @@ -19,6 +20,7 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/share_action_b import 'package:immich_mobile/presentation/widgets/action_buttons/share_link_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/stack_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/trash_action_button.widget.dart'; +import 'package:immich_mobile/presentation/widgets/action_buttons/unstack_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/upload_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/album/album_selector.widget.dart'; import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart'; @@ -62,11 +64,19 @@ class _GeneralBottomSheetState extends ConsumerState { return; } + final remoteAssets = selectedAssets.whereType(); final addedCount = await ref .read(remoteAlbumProvider.notifier) - .addAssets(album.id, selectedAssets.map((e) => (e as RemoteAsset).id).toList()); + .addAssets(album.id, remoteAssets.map((e) => e.id).toList()); - if (addedCount != selectedAssets.length) { + if (selectedAssets.length != remoteAssets.length) { + ImmichToast.show( + context: context, + msg: 'add_to_album_bottom_sheet_some_local_assets'.t(context: context), + ); + } + + if (addedCount != remoteAssets.length) { ImmichToast.show( context: context, msg: 'add_to_album_bottom_sheet_already_exists'.tr(namedArgs: {"album": album.name}), @@ -108,15 +118,18 @@ class _GeneralBottomSheetState extends ConsumerState { const EditLocationActionButton(source: ActionSource.timeline), const MoveToLockFolderActionButton(source: ActionSource.timeline), if (multiselect.selectedAssets.length > 1) const StackActionButton(source: ActionSource.timeline), + if (multiselect.hasStacked) const UnStackActionButton(source: ActionSource.timeline), const DeleteActionButton(source: ActionSource.timeline), ], if (multiselect.hasLocal || multiselect.hasMerged) const DeleteLocalActionButton(source: ActionSource.timeline), if (multiselect.hasLocal) const UploadActionButton(source: ActionSource.timeline), ], - slivers: [ - const AddToAlbumHeader(), - AlbumSelector(onAlbumSelected: addAssetsToAlbum, onKeyboardExpanded: onKeyboardExpand), - ], + slivers: multiselect.hasRemote + ? [ + const AddToAlbumHeader(), + AlbumSelector(onAlbumSelected: addAssetsToAlbum, onKeyboardExpanded: onKeyboardExpand), + ] + : [], ); } } diff --git a/mobile/lib/presentation/widgets/bottom_sheet/map_bottom_sheet.widget.dart b/mobile/lib/presentation/widgets/bottom_sheet/map_bottom_sheet.widget.dart index 19cce3392f..dc5fdbe78d 100644 --- a/mobile/lib/presentation/widgets/bottom_sheet/map_bottom_sheet.widget.dart +++ b/mobile/lib/presentation/widgets/bottom_sheet/map_bottom_sheet.widget.dart @@ -1,5 +1,6 @@ import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart'; import 'package:immich_mobile/presentation/widgets/map/map.state.dart'; import 'package:immich_mobile/presentation/widgets/timeline/timeline.widget.dart'; @@ -10,13 +11,14 @@ class MapBottomSheet extends StatelessWidget { @override Widget build(BuildContext context) { - return const BaseBottomSheet( + return BaseBottomSheet( initialChildSize: 0.25, maxChildSize: 0.9, shouldCloseOnMinExtent: false, resizeOnScroll: false, actions: [], - slivers: [SliverFillRemaining(hasScrollBody: false, child: _ScopedMapTimeline())], + backgroundColor: context.themeData.colorScheme.surface, + slivers: [const SliverFillRemaining(hasScrollBody: false, child: _ScopedMapTimeline())], ); } } diff --git a/mobile/lib/presentation/widgets/bottom_sheet/remote_album_bottom_sheet.widget.dart b/mobile/lib/presentation/widgets/bottom_sheet/remote_album_bottom_sheet.widget.dart index 1dcc52f349..0ab419a56b 100644 --- a/mobile/lib/presentation/widgets/bottom_sheet/remote_album_bottom_sheet.widget.dart +++ b/mobile/lib/presentation/widgets/bottom_sheet/remote_album_bottom_sheet.widget.dart @@ -17,6 +17,7 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/share_action_b import 'package:immich_mobile/presentation/widgets/action_buttons/share_link_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/stack_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/trash_action_button.widget.dart'; +import 'package:immich_mobile/presentation/widgets/action_buttons/unstack_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/upload_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/album/album_selector.widget.dart'; import 'package:immich_mobile/presentation/widgets/bottom_sheet/base_bottom_sheet.widget.dart'; @@ -102,6 +103,7 @@ class _RemoteAlbumBottomSheetState extends ConsumerState const EditLocationActionButton(source: ActionSource.timeline), const MoveToLockFolderActionButton(source: ActionSource.timeline), if (multiselect.selectedAssets.length > 1) const StackActionButton(source: ActionSource.timeline), + if (multiselect.hasStacked) const UnStackActionButton(source: ActionSource.timeline), ], if (multiselect.hasLocal) ...[ const DeleteLocalActionButton(source: ActionSource.timeline), diff --git a/mobile/lib/presentation/widgets/images/image_provider.dart b/mobile/lib/presentation/widgets/images/image_provider.dart index ab5ead5ca5..810340aeb8 100644 --- a/mobile/lib/presentation/widgets/images/image_provider.dart +++ b/mobile/lib/presentation/widgets/images/image_provider.dart @@ -123,28 +123,14 @@ ImageProvider getFullImageProvider(BaseAsset asset, {Size size = const Size(1080 return provider; } -ImageProvider getThumbnailImageProvider({BaseAsset? asset, String? remoteId, Size size = kThumbnailResolution}) { - assert(asset != null || remoteId != null, 'Either asset or remoteId must be provided'); - - if (remoteId != null) { - return RemoteThumbProvider(assetId: remoteId); - } - - if (_shouldUseLocalAsset(asset!)) { +ImageProvider? getThumbnailImageProvider(BaseAsset asset, {Size size = kThumbnailResolution}) { + if (_shouldUseLocalAsset(asset)) { final id = asset is LocalAsset ? asset.id : (asset as RemoteAsset).localId!; return LocalThumbProvider(id: id, size: size, assetType: asset.type); } - final String assetId; - if (asset is LocalAsset && asset.hasRemote) { - assetId = asset.remoteId!; - } else if (asset is RemoteAsset) { - assetId = asset.id; - } else { - throw ArgumentError("Unsupported asset type: ${asset.runtimeType}"); - } - - return RemoteThumbProvider(assetId: assetId); + final assetId = asset is RemoteAsset ? asset.id : (asset as LocalAsset).remoteId; + return assetId != null ? RemoteThumbProvider(assetId: assetId) : null; } bool _shouldUseLocalAsset(BaseAsset asset) => diff --git a/mobile/lib/presentation/widgets/images/thumbnail.widget.dart b/mobile/lib/presentation/widgets/images/thumbnail.widget.dart index 3832029702..92b1bb2544 100644 --- a/mobile/lib/presentation/widgets/images/thumbnail.widget.dart +++ b/mobile/lib/presentation/widgets/images/thumbnail.widget.dart @@ -5,7 +5,6 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/theme_extensions.dart'; import 'package:immich_mobile/presentation/widgets/images/image_provider.dart'; -import 'package:immich_mobile/presentation/widgets/images/local_image_provider.dart'; import 'package:immich_mobile/presentation/widgets/images/remote_image_provider.dart'; import 'package:immich_mobile/presentation/widgets/images/thumb_hash_provider.dart'; import 'package:immich_mobile/presentation/widgets/timeline/constants.dart'; @@ -39,14 +38,7 @@ class Thumbnail extends StatefulWidget { ), _ => null, }, - imageProvider = switch (asset) { - RemoteAsset() => - asset.localId == null - ? RemoteThumbProvider(assetId: asset.id) - : LocalThumbProvider(id: asset.localId!, size: size, assetType: asset.type), - LocalAsset() => LocalThumbProvider(id: asset.id, size: size, assetType: asset.type), - _ => null, - }; + imageProvider = asset == null ? null : getThumbnailImageProvider(asset, size: size); @override State createState() => _ThumbnailState(); diff --git a/mobile/lib/presentation/widgets/images/thumbnail_tile.widget.dart b/mobile/lib/presentation/widgets/images/thumbnail_tile.widget.dart index cfcb7a8985..a0163a7220 100644 --- a/mobile/lib/presentation/widgets/images/thumbnail_tile.widget.dart +++ b/mobile/lib/presentation/widgets/images/thumbnail_tile.widget.dart @@ -54,8 +54,6 @@ class ThumbnailTile extends ConsumerWidget { ) : const BoxDecoration(); - final hasStack = asset is RemoteAsset && asset.stackId != null; - final bool storageIndicator = showStorageIndicator ?? ref.watch(settingsProvider.select((s) => s.get(Setting.showStorageIndicator))); @@ -77,21 +75,10 @@ class ThumbnailTile extends ConsumerWidget { child: Thumbnail.fromAsset(asset: asset, size: size), ), ), - if (hasStack) + if (asset != null) Align( alignment: Alignment.topRight, - child: Padding( - padding: EdgeInsets.only(right: 10.0, top: asset.isVideo ? 24.0 : 6.0), - child: const _TileOverlayIcon(Icons.burst_mode_rounded), - ), - ), - if (asset != null && asset.isVideo) - Align( - alignment: Alignment.topRight, - child: Padding( - padding: const EdgeInsets.only(right: 10.0, top: 6.0), - child: _VideoIndicator(asset.duration), - ), + child: _AssetTypeIcons(asset: asset), ), if (storageIndicator && asset != null) switch (asset.storage) { @@ -214,3 +201,34 @@ class _TileOverlayIcon extends StatelessWidget { ); } } + +class _AssetTypeIcons extends StatelessWidget { + final BaseAsset asset; + + const _AssetTypeIcons({required this.asset}); + + @override + Widget build(BuildContext context) { + final hasStack = asset is RemoteAsset && (asset as RemoteAsset).stackId != null; + final isLivePhoto = asset is RemoteAsset && asset.livePhotoVideoId != null; + + return Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + if (asset.isVideo) + Padding(padding: const EdgeInsets.only(right: 10.0, top: 6.0), child: _VideoIndicator(asset.duration)), + if (hasStack) + const Padding( + padding: EdgeInsets.only(right: 10.0, top: 6.0), + child: _TileOverlayIcon(Icons.burst_mode_rounded), + ), + if (isLivePhoto) + const Padding( + padding: EdgeInsets.only(right: 10.0, top: 6.0), + child: _TileOverlayIcon(Icons.motion_photos_on_rounded), + ), + ], + ); + } +} diff --git a/mobile/lib/presentation/widgets/map/map.widget.dart b/mobile/lib/presentation/widgets/map/map.widget.dart index 0c3b37a3b4..1d285f0441 100644 --- a/mobile/lib/presentation/widgets/map/map.widget.dart +++ b/mobile/lib/presentation/widgets/map/map.widget.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:io'; +import 'dart:math'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; @@ -9,8 +10,8 @@ import 'package:immich_mobile/extensions/asyncvalue_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/translate_extensions.dart'; import 'package:immich_mobile/presentation/widgets/bottom_sheet/map_bottom_sheet.widget.dart'; -import 'package:immich_mobile/presentation/widgets/map/map_utils.dart'; import 'package:immich_mobile/presentation/widgets/map/map.state.dart'; +import 'package:immich_mobile/presentation/widgets/map/map_utils.dart'; import 'package:immich_mobile/utils/async_mutex.dart'; import 'package:immich_mobile/utils/debounce.dart'; import 'package:immich_mobile/widgets/common/immich_toast.dart'; @@ -187,6 +188,8 @@ class _Map extends StatelessWidget { styleString: style, onMapCreated: onMapCreated, onStyleLoadedCallback: onMapReady, + attributionButtonPosition: AttributionButtonPosition.topRight, + attributionButtonMargins: Platform.isIOS ? const Point(40, 12) : const Point(40, 72), ), ), ); diff --git a/mobile/lib/presentation/widgets/timeline/timeline.widget.dart b/mobile/lib/presentation/widgets/timeline/timeline.widget.dart index 98831403f6..83e679b8c1 100644 --- a/mobile/lib/presentation/widgets/timeline/timeline.widget.dart +++ b/mobile/lib/presentation/widgets/timeline/timeline.widget.dart @@ -107,7 +107,7 @@ class _SliverTimeline extends ConsumerStatefulWidget { } class _SliverTimelineState extends ConsumerState<_SliverTimeline> { - final _scrollController = ScrollController(); + late final ScrollController _scrollController; StreamSubscription? _eventSubscription; // Drag selection state @@ -119,10 +119,12 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> { int _perRow = 4; double _scaleFactor = 3.0; double _baseScaleFactor = 3.0; + int? _scaleRestoreAssetIndex; @override void initState() { super.initState(); + _scrollController = ScrollController(onAttach: _restoreScalePosition); _eventSubscription = EventStream.shared.listen(_onEvent); final currentTilesPerRow = ref.read(settingsProvider).get(Setting.tilesPerRow); @@ -154,6 +156,28 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> { EventStream.shared.emit(MultiSelectToggleEvent(isEnabled)); } + void _restoreScalePosition(_) { + if (_scaleRestoreAssetIndex == null) return; + + final asyncSegments = ref.read(timelineSegmentProvider); + asyncSegments.whenData((segments) { + final targetSegment = segments.lastWhereOrNull((segment) => segment.firstAssetIndex <= _scaleRestoreAssetIndex!); + if (targetSegment != null) { + final assetIndexInSegment = _scaleRestoreAssetIndex! - targetSegment.firstAssetIndex; + final newColumnCount = ref.read(timelineArgsProvider).columnCount; + final rowIndexInSegment = (assetIndexInSegment / newColumnCount).floor(); + final targetRowIndex = targetSegment.firstIndex + 1 + rowIndexInSegment; + final targetOffset = targetSegment.indexToLayoutOffset(targetRowIndex); + WidgetsBinding.instance.addPostFrameCallback((_) { + if (mounted) { + _scrollController.jumpTo(targetOffset.clamp(0.0, _scrollController.position.maxScrollExtent)); + } + }); + } + }); + _scaleRestoreAssetIndex = null; + } + @override void dispose() { _scrollController.dispose(); @@ -188,11 +212,14 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> { if (fallbackSegment != null) { // Scroll to the segment with a small offset to show the header final targetOffset = fallbackSegment.startOffset - 50; - _scrollController.animateTo( - targetOffset.clamp(0.0, _scrollController.position.maxScrollExtent), - duration: const Duration(milliseconds: 500), - curve: Curves.easeInOut, - ); + ref.read(timelineStateProvider.notifier).setScrubbing(true); + _scrollController + .animateTo( + targetOffset.clamp(0.0, _scrollController.position.maxScrollExtent), + duration: const Duration(milliseconds: 500), + curve: Curves.easeInOut, + ) + .whenComplete(() => ref.read(timelineStateProvider.notifier).setScrubbing(false)); } }); } @@ -345,9 +372,28 @@ class _SliverTimelineState extends ConsumerState<_SliverTimeline> { final newPerRow = 7 - newScaleFactor.toInt(); if (newPerRow != _perRow) { + final currentOffset = _scrollController.offset.clamp( + 0.0, + _scrollController.position.maxScrollExtent, + ); + final segment = segments.findByOffset(currentOffset) ?? segments.lastOrNull; + int? targetAssetIndex; + if (segment != null) { + final rowIndex = segment.getMinChildIndexForScrollOffset(currentOffset); + if (rowIndex > segment.firstIndex) { + final rowIndexInSegment = rowIndex - (segment.firstIndex + 1); + final assetsPerRow = ref.read(timelineArgsProvider).columnCount; + final assetIndexInSegment = rowIndexInSegment * assetsPerRow; + targetAssetIndex = segment.firstAssetIndex + assetIndexInSegment; + } else { + targetAssetIndex = segment.firstAssetIndex; + } + } + setState(() { _scaleFactor = newScaleFactor; _perRow = newPerRow; + _scaleRestoreAssetIndex = targetAssetIndex; }); ref.read(settingsProvider.notifier).set(Setting.tilesPerRow, _perRow); diff --git a/mobile/lib/providers/app_life_cycle.provider.dart b/mobile/lib/providers/app_life_cycle.provider.dart index b7f1b9ebb2..29de09fd33 100644 --- a/mobile/lib/providers/app_life_cycle.provider.dart +++ b/mobile/lib/providers/app_life_cycle.provider.dart @@ -15,6 +15,7 @@ import 'package:immich_mobile/providers/backup/drift_backup.provider.dart'; import 'package:immich_mobile/providers/backup/ios_background_settings.provider.dart'; import 'package:immich_mobile/providers/backup/manual_upload.provider.dart'; import 'package:immich_mobile/providers/gallery_permission.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/platform.provider.dart'; import 'package:immich_mobile/providers/memory.provider.dart'; import 'package:immich_mobile/providers/notification_permission.provider.dart'; import 'package:immich_mobile/providers/server_info.provider.dart'; @@ -138,6 +139,7 @@ class AppLifeCycleNotifier extends StateNotifier { Future _handleBetaTimelineResume() async { _ref.read(backupProvider.notifier).cancelBackup(); + unawaited(_ref.read(backgroundWorkerLockServiceProvider).lock()); // Give isolates time to complete any ongoing database transactions await Future.delayed(const Duration(milliseconds: 500)); @@ -146,17 +148,22 @@ class AppLifeCycleNotifier extends StateNotifier { final isAlbumLinkedSyncEnable = _ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.syncAlbums); try { + bool syncSuccess = false; await Future.wait([ _safeRun(backgroundManager.syncLocal(), "syncLocal"), - _safeRun(backgroundManager.syncRemote(), "syncRemote"), - ]); - - await Future.wait([ - _safeRun(backgroundManager.hashAssets(), "hashAssets").then((_) { - _resumeBackup(); - }), - _resumeBackup(), + _safeRun(backgroundManager.syncRemote().then((success) => syncSuccess = success), "syncRemote"), ]); + if (syncSuccess) { + await Future.wait([ + _safeRun(backgroundManager.hashAssets(), "hashAssets").then((_) { + _resumeBackup(); + }), + _resumeBackup(), + ]); + } else { + _ref.read(driftBackupProvider.notifier).updateError(BackupError.syncFailed); + await _safeRun(backgroundManager.hashAssets(), "hashAssets"); + } if (isAlbumLinkedSyncEnable) { await _safeRun(backgroundManager.syncLinkedAlbum(), "syncLinkedAlbum"); @@ -209,6 +216,9 @@ class AppLifeCycleNotifier extends StateNotifier { _pauseOperation = Completer(); try { + if (Store.isBetaTimelineEnabled) { + unawaited(_ref.read(backgroundWorkerLockServiceProvider).unlock()); + } await _performPause(); } catch (e, stackTrace) { _log.severe("Error during app pause", e, stackTrace); @@ -240,6 +250,10 @@ class AppLifeCycleNotifier extends StateNotifier { Future handleAppDetached() async { state = AppLifeCycleEnum.detached; + if (Store.isBetaTimelineEnabled) { + unawaited(_ref.read(backgroundWorkerLockServiceProvider).unlock()); + } + // Flush logs before closing database try { LogService.I.flush(); diff --git a/mobile/lib/providers/backup/drift_backup.provider.dart b/mobile/lib/providers/backup/drift_backup.provider.dart index 4069cef13f..f52fc654f2 100644 --- a/mobile/lib/providers/backup/drift_backup.provider.dart +++ b/mobile/lib/providers/backup/drift_backup.provider.dart @@ -1,6 +1,5 @@ // ignore_for_file: public_member_api_docs, sort_constructors_first import 'dart:async'; -import 'dart:convert'; import 'package:background_downloader/background_downloader.dart'; import 'package:collection/collection.dart'; @@ -8,12 +7,13 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/constants.dart'; import 'package:immich_mobile/domain/models/album/local_album.model.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; +import 'package:immich_mobile/extensions/string_extensions.dart'; import 'package:immich_mobile/infrastructure/repositories/backup.repository.dart'; import 'package:immich_mobile/providers/infrastructure/asset.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; import 'package:immich_mobile/services/upload.service.dart'; -import 'package:logging/logging.dart'; import 'package:immich_mobile/utils/debug_print.dart'; +import 'package:logging/logging.dart'; class EnqueueStatus { final int enqueueCount; @@ -36,6 +36,7 @@ class DriftUploadStatus { final int fileSize; final String networkSpeedAsString; final bool? isFailed; + final String? error; const DriftUploadStatus({ required this.taskId, @@ -44,6 +45,7 @@ class DriftUploadStatus { required this.fileSize, required this.networkSpeedAsString, this.isFailed, + this.error, }); DriftUploadStatus copyWith({ @@ -53,6 +55,7 @@ class DriftUploadStatus { int? fileSize, String? networkSpeedAsString, bool? isFailed, + String? error, }) { return DriftUploadStatus( taskId: taskId ?? this.taskId, @@ -61,12 +64,13 @@ class DriftUploadStatus { fileSize: fileSize ?? this.fileSize, networkSpeedAsString: networkSpeedAsString ?? this.networkSpeedAsString, isFailed: isFailed ?? this.isFailed, + error: error ?? this.error, ); } @override String toString() { - return 'DriftUploadStatus(taskId: $taskId, filename: $filename, progress: $progress, fileSize: $fileSize, networkSpeedAsString: $networkSpeedAsString, isFailed: $isFailed)'; + return 'DriftUploadStatus(taskId: $taskId, filename: $filename, progress: $progress, fileSize: $fileSize, networkSpeedAsString: $networkSpeedAsString, isFailed: $isFailed, error: $error)'; } @override @@ -78,7 +82,8 @@ class DriftUploadStatus { other.progress == progress && other.fileSize == fileSize && other.networkSpeedAsString == networkSpeedAsString && - other.isFailed == isFailed; + other.isFailed == isFailed && + other.error == error; } @override @@ -88,46 +93,25 @@ class DriftUploadStatus { progress.hashCode ^ fileSize.hashCode ^ networkSpeedAsString.hashCode ^ - isFailed.hashCode; + isFailed.hashCode ^ + error.hashCode; } - - Map toMap() { - return { - 'taskId': taskId, - 'filename': filename, - 'progress': progress, - 'fileSize': fileSize, - 'networkSpeedAsString': networkSpeedAsString, - 'isFailed': isFailed, - }; - } - - factory DriftUploadStatus.fromMap(Map map) { - return DriftUploadStatus( - taskId: map['taskId'] as String, - filename: map['filename'] as String, - progress: map['progress'] as double, - fileSize: map['fileSize'] as int, - networkSpeedAsString: map['networkSpeedAsString'] as String, - isFailed: map['isFailed'] != null ? map['isFailed'] as bool : null, - ); - } - - String toJson() => json.encode(toMap()); - - factory DriftUploadStatus.fromJson(String source) => - DriftUploadStatus.fromMap(json.decode(source) as Map); } +enum BackupError { none, syncFailed } + class DriftBackupState { final int totalCount; final int backupCount; final int remainderCount; + final int processingCount; final int enqueueCount; final int enqueueTotalCount; + final bool isSyncing; final bool isCanceling; + final BackupError error; final Map uploadItems; @@ -135,35 +119,44 @@ class DriftBackupState { required this.totalCount, required this.backupCount, required this.remainderCount, + required this.processingCount, required this.enqueueCount, required this.enqueueTotalCount, required this.isCanceling, + required this.isSyncing, required this.uploadItems, + this.error = BackupError.none, }); DriftBackupState copyWith({ int? totalCount, int? backupCount, int? remainderCount, + int? processingCount, int? enqueueCount, int? enqueueTotalCount, bool? isCanceling, + bool? isSyncing, Map? uploadItems, + BackupError? error, }) { return DriftBackupState( totalCount: totalCount ?? this.totalCount, backupCount: backupCount ?? this.backupCount, remainderCount: remainderCount ?? this.remainderCount, + processingCount: processingCount ?? this.processingCount, enqueueCount: enqueueCount ?? this.enqueueCount, enqueueTotalCount: enqueueTotalCount ?? this.enqueueTotalCount, isCanceling: isCanceling ?? this.isCanceling, + isSyncing: isSyncing ?? this.isSyncing, uploadItems: uploadItems ?? this.uploadItems, + error: error ?? this.error, ); } @override String toString() { - return 'DriftBackupState(totalCount: $totalCount, backupCount: $backupCount, remainderCount: $remainderCount, enqueueCount: $enqueueCount, enqueueTotalCount: $enqueueTotalCount, isCanceling: $isCanceling, uploadItems: $uploadItems)'; + return 'DriftBackupState(totalCount: $totalCount, backupCount: $backupCount, remainderCount: $remainderCount, processingCount: $processingCount, enqueueCount: $enqueueCount, enqueueTotalCount: $enqueueTotalCount, isCanceling: $isCanceling, isSyncing: $isSyncing, uploadItems: $uploadItems, error: $error)'; } @override @@ -174,10 +167,13 @@ class DriftBackupState { return other.totalCount == totalCount && other.backupCount == backupCount && other.remainderCount == remainderCount && + other.processingCount == processingCount && other.enqueueCount == enqueueCount && other.enqueueTotalCount == enqueueTotalCount && other.isCanceling == isCanceling && - mapEquals(other.uploadItems, uploadItems); + other.isSyncing == isSyncing && + mapEquals(other.uploadItems, uploadItems) && + other.error == error; } @override @@ -185,10 +181,13 @@ class DriftBackupState { return totalCount.hashCode ^ backupCount.hashCode ^ remainderCount.hashCode ^ + processingCount.hashCode ^ enqueueCount.hashCode ^ enqueueTotalCount.hashCode ^ isCanceling.hashCode ^ - uploadItems.hashCode; + isSyncing.hashCode ^ + uploadItems.hashCode ^ + error.hashCode; } } @@ -203,10 +202,13 @@ class DriftBackupNotifier extends StateNotifier { totalCount: 0, backupCount: 0, remainderCount: 0, + processingCount: 0, enqueueCount: 0, enqueueTotalCount: 0, isCanceling: false, + isSyncing: false, uploadItems: {}, + error: BackupError.none, ), ) { { @@ -259,7 +261,24 @@ class DriftBackupNotifier extends StateNotifier { return; } - state = state.copyWith(uploadItems: {...state.uploadItems, taskId: currentItem.copyWith(isFailed: true)}); + String? error; + final exception = update.exception; + if (exception != null && exception is TaskHttpException) { + final message = tryJsonDecode(exception.description)?['message'] as String?; + if (message != null) { + final responseCode = exception.httpResponseCode; + error = "${exception.exceptionType}, response code $responseCode: $message"; + } + } + error ??= update.exception?.toString(); + + state = state.copyWith( + uploadItems: { + ...state.uploadItems, + taskId: currentItem.copyWith(isFailed: true, error: error), + }, + ); + _logger.fine("Upload failed for taskId: $taskId, exception: ${update.exception}"); break; case TaskStatus.canceled: @@ -313,16 +332,26 @@ class DriftBackupNotifier extends StateNotifier { } Future getBackupStatus(String userId) async { - final [totalCount, backupCount, remainderCount] = await Future.wait([ - _uploadService.getBackupTotalCount(), - _uploadService.getBackupFinishedCount(userId), - _uploadService.getBackupRemainderCount(userId), - ]); + final counts = await _uploadService.getBackupCounts(userId); - state = state.copyWith(totalCount: totalCount, backupCount: backupCount, remainderCount: remainderCount); + state = state.copyWith( + totalCount: counts.total, + backupCount: counts.total - counts.remainder, + remainderCount: counts.remainder, + processingCount: counts.processing, + ); + } + + void updateError(BackupError error) async { + state = state.copyWith(error: error); + } + + void updateSyncing(bool isSyncing) async { + state = state.copyWith(isSyncing: isSyncing); } Future startBackup(String userId) { + state = state.copyWith(error: BackupError.none); return _uploadService.startBackup(userId, _updateEnqueueCount); } @@ -332,7 +361,7 @@ class DriftBackupNotifier extends StateNotifier { Future cancel() async { dPrint(() => "Canceling backup tasks..."); - state = state.copyWith(enqueueCount: 0, enqueueTotalCount: 0, isCanceling: true); + state = state.copyWith(enqueueCount: 0, enqueueTotalCount: 0, isCanceling: true, error: BackupError.none); final activeTaskCount = await _uploadService.cancelBackup(); @@ -348,6 +377,7 @@ class DriftBackupNotifier extends StateNotifier { Future handleBackupResume(String userId) async { _logger.info("Resuming backup tasks..."); + state = state.copyWith(error: BackupError.none); final tasks = await _uploadService.getActiveTasks(kBackupGroup); _logger.info("Found ${tasks.length} tasks"); @@ -375,7 +405,7 @@ final driftBackupCandidateProvider = FutureProvider.autoDispose return []; } - return ref.read(backupRepositoryProvider).getCandidates(user.id); + return ref.read(backupRepositoryProvider).getCandidates(user.id, onlyHashed: false); }); final driftCandidateBackupAlbumInfoProvider = FutureProvider.autoDispose.family, String>(( diff --git a/mobile/lib/providers/infrastructure/action.provider.dart b/mobile/lib/providers/infrastructure/action.provider.dart index f62791fb57..77ac6595a7 100644 --- a/mobile/lib/providers/infrastructure/action.provider.dart +++ b/mobile/lib/providers/infrastructure/action.provider.dart @@ -3,7 +3,10 @@ import 'package:background_downloader/background_downloader.dart'; import 'package:flutter/material.dart'; import 'package:immich_mobile/constants/enums.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; +import 'package:immich_mobile/domain/services/asset.service.dart'; import 'package:immich_mobile/models/download/livephotos_medatada.model.dart'; +import 'package:immich_mobile/presentation/widgets/asset_viewer/asset_viewer.state.dart'; +import 'package:immich_mobile/providers/infrastructure/asset.provider.dart'; import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; import 'package:immich_mobile/providers/user.provider.dart'; @@ -36,6 +39,7 @@ class ActionNotifier extends Notifier { late ActionService _service; late UploadService _uploadService; late DownloadService _downloadService; + late AssetService _assetService; ActionNotifier() : super(); @@ -43,6 +47,7 @@ class ActionNotifier extends Notifier { void build() { _uploadService = ref.watch(uploadServiceProvider); _service = ref.watch(actionServiceProvider); + _assetService = ref.watch(assetServiceProvider); _downloadService = ref.watch(downloadServiceProvider); _downloadService.onImageDownloadStatus = _downloadImageCallback; _downloadService.onVideoDownloadStatus = _downloadVideoCallback; @@ -335,6 +340,14 @@ class ActionNotifier extends Notifier { final assets = _getOwnedRemoteAssetsForSource(source); try { await _service.unStack(assets.map((e) => e.stackId).nonNulls.toList()); + if (source == ActionSource.viewer) { + final updatedParent = await _assetService.getRemoteAsset(assets.first.id); + if (updatedParent != null) { + ref.read(currentAssetNotifier.notifier).setAsset(updatedParent); + ref.read(assetViewerProvider.notifier).setAsset(updatedParent); + } + } + return ActionResult(count: assets.length, success: true); } catch (error, stack) { _logger.severe('Failed to unstack assets', error, stack); @@ -342,11 +355,11 @@ class ActionNotifier extends Notifier { } } - Future shareAssets(ActionSource source) async { + Future shareAssets(ActionSource source, BuildContext context) async { final ids = _getAssets(source).toList(growable: false); try { - await _service.shareAssets(ids); + await _service.shareAssets(ids, context); return ActionResult(count: ids.length, success: true); } catch (error, stack) { _logger.severe('Failed to share assets', error, stack); diff --git a/mobile/lib/providers/infrastructure/platform.provider.dart b/mobile/lib/providers/infrastructure/platform.provider.dart index dec5c6905e..11c5280c02 100644 --- a/mobile/lib/providers/infrastructure/platform.provider.dart +++ b/mobile/lib/providers/infrastructure/platform.provider.dart @@ -1,12 +1,17 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/domain/services/background_worker.service.dart'; import 'package:immich_mobile/platform/background_worker_api.g.dart'; +import 'package:immich_mobile/platform/background_worker_lock_api.g.dart'; import 'package:immich_mobile/platform/connectivity_api.g.dart'; import 'package:immich_mobile/platform/native_sync_api.g.dart'; import 'package:immich_mobile/platform/thumbnail_api.g.dart'; final backgroundWorkerFgServiceProvider = Provider((_) => BackgroundWorkerFgService(BackgroundWorkerFgHostApi())); +final backgroundWorkerLockServiceProvider = Provider( + (_) => BackgroundWorkerLockService(BackgroundWorkerLockApi()), +); + final nativeSyncApiProvider = Provider((_) => NativeSyncApi()); final connectivityApiProvider = Provider((_) => ConnectivityApi()); diff --git a/mobile/lib/providers/timeline/multiselect.provider.dart b/mobile/lib/providers/timeline/multiselect.provider.dart index e225e0c98d..6949413cd9 100644 --- a/mobile/lib/providers/timeline/multiselect.provider.dart +++ b/mobile/lib/providers/timeline/multiselect.provider.dart @@ -28,6 +28,8 @@ class MultiSelectState { bool get hasRemote => selectedAssets.any((asset) => asset.storage == AssetState.remote || asset.storage == AssetState.merged); + bool get hasStacked => selectedAssets.any((asset) => asset is RemoteAsset && asset.stackId != null); + bool get hasLocal => selectedAssets.any((asset) => asset.storage == AssetState.local); bool get hasMerged => selectedAssets.any((asset) => asset.storage == AssetState.merged); diff --git a/mobile/lib/repositories/asset_media.repository.dart b/mobile/lib/repositories/asset_media.repository.dart index 83b5dfb9fd..bfcf7060e0 100644 --- a/mobile/lib/repositories/asset_media.repository.dart +++ b/mobile/lib/repositories/asset_media.repository.dart @@ -1,17 +1,19 @@ import 'dart:io'; +import 'package:flutter/widgets.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; +import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/exif.model.dart'; import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/entities/asset.entity.dart' as asset_entity; import 'package:immich_mobile/entities/store.entity.dart'; +import 'package:immich_mobile/extensions/build_context_extensions.dart'; +import 'package:immich_mobile/extensions/response_extensions.dart'; import 'package:immich_mobile/repositories/asset_api.repository.dart'; import 'package:immich_mobile/utils/hash.dart'; import 'package:logging/logging.dart'; import 'package:path_provider/path_provider.dart'; import 'package:photo_manager/photo_manager.dart'; -import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; -import 'package:immich_mobile/extensions/response_extensions.dart'; import 'package:share_plus/share_plus.dart'; final assetMediaRepositoryProvider = Provider((ref) => AssetMediaRepository(ref.watch(assetApiRepositoryProvider))); @@ -68,7 +70,7 @@ class AssetMediaRepository { } // TODO: make this more efficient - Future shareAssets(List assets) async { + Future shareAssets(List assets, BuildContext context) async { final downloadedXFiles = []; for (var asset in assets) { @@ -105,8 +107,12 @@ class AssetMediaRepository { } // we dont want to await the share result since the - // "preparing" dialog will not disappear unti - Share.shareXFiles(downloadedXFiles).then((result) async { + // "preparing" dialog will not disappear until + final size = context.sizeData; + Share.shareXFiles( + downloadedXFiles, + sharePositionOrigin: Rect.fromPoints(Offset.zero, Offset(size.width / 3, size.height)), + ).then((result) async { for (var file in downloadedXFiles) { try { await File(file.path).delete(); diff --git a/mobile/lib/services/action.service.dart b/mobile/lib/services/action.service.dart index 4edd49fec2..9c3768080b 100644 --- a/mobile/lib/services/action.service.dart +++ b/mobile/lib/services/action.service.dart @@ -224,8 +224,8 @@ class ActionService { await _assetApiRepository.unStack(stackIds); } - Future shareAssets(List assets) { - return _assetMediaRepository.shareAssets(assets); + Future shareAssets(List assets, BuildContext context) { + return _assetMediaRepository.shareAssets(assets, context); } Future> downloadAll(List assets) { diff --git a/mobile/lib/services/server_info.service.dart b/mobile/lib/services/server_info.service.dart index 0bce9366d2..460e135421 100644 --- a/mobile/lib/services/server_info.service.dart +++ b/mobile/lib/services/server_info.service.dart @@ -14,15 +14,6 @@ class ServerInfoService { const ServerInfoService(this._apiService); - Future ping() async { - try { - await _apiService.serverInfoApi.pingServer().timeout(const Duration(seconds: 5)); - return true; - } catch (e) { - return false; - } - } - Future getDiskInfo() async { try { final dto = await _apiService.serverInfoApi.getStorage(); diff --git a/mobile/lib/services/upload.service.dart b/mobile/lib/services/upload.service.dart index 9e9c81076b..e8e98562f7 100644 --- a/mobile/lib/services/upload.service.dart +++ b/mobile/lib/services/upload.service.dart @@ -9,6 +9,7 @@ import 'package:immich_mobile/constants/constants.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/entities/store.entity.dart'; +import 'package:immich_mobile/extensions/platform_extensions.dart'; import 'package:immich_mobile/infrastructure/repositories/backup.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/storage.repository.dart'; @@ -19,9 +20,9 @@ import 'package:immich_mobile/providers/infrastructure/storage.provider.dart'; import 'package:immich_mobile/repositories/upload.repository.dart'; import 'package:immich_mobile/services/api.service.dart'; import 'package:immich_mobile/services/app_settings.service.dart'; +import 'package:immich_mobile/utils/debug_print.dart'; import 'package:logging/logging.dart'; import 'package:path/path.dart' as p; -import 'package:immich_mobile/utils/debug_print.dart'; final uploadServiceProvider = Provider((ref) { final service = UploadService( @@ -89,16 +90,8 @@ class UploadService { return _uploadRepository.getActiveTasks(group); } - Future getBackupTotalCount() { - return _backupRepository.getTotalCount(); - } - - Future getBackupRemainderCount(String userId) { - return _backupRepository.getRemainderCount(userId); - } - - Future getBackupFinishedCount(String userId) { - return _backupRepository.getBackupCount(userId); + Future<({int total, int remainder, int processing})> getBackupCounts(String userId) { + return _backupRepository.getAllCounts(userId); } Future manualBackup(List localAssets) async { @@ -213,10 +206,20 @@ class UploadService { return _uploadRepository.start(); } - void _handleTaskStatusUpdate(TaskStatusUpdate update) { + void _handleTaskStatusUpdate(TaskStatusUpdate update) async { switch (update.status) { case TaskStatus.complete: _handleLivePhoto(update); + + if (CurrentPlatform.isIOS) { + try { + final path = await update.task.filePath(); + await File(path).delete(); + } catch (e) { + _logger.severe('Error deleting file path for iOS: $e'); + } + } + break; default: diff --git a/mobile/lib/utils/action_button.utils.dart b/mobile/lib/utils/action_button.utils.dart index 090aeeeaa7..c5a2583531 100644 --- a/mobile/lib/utils/action_button.utils.dart +++ b/mobile/lib/utils/action_button.utils.dart @@ -16,6 +16,7 @@ import 'package:immich_mobile/presentation/widgets/action_buttons/share_action_b import 'package:immich_mobile/presentation/widgets/action_buttons/share_link_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/trash_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/unarchive_action_button.widget.dart'; +import 'package:immich_mobile/presentation/widgets/action_buttons/unstack_action_button.widget.dart'; import 'package:immich_mobile/presentation/widgets/action_buttons/upload_action_button.widget.dart'; class ActionButtonContext { @@ -24,6 +25,7 @@ class ActionButtonContext { final bool isArchived; final bool isTrashEnabled; final bool isInLockedView; + final bool isStacked; final RemoteAlbum? currentAlbum; final bool advancedTroubleshooting; final ActionSource source; @@ -33,6 +35,7 @@ class ActionButtonContext { required this.isOwner, required this.isArchived, required this.isTrashEnabled, + required this.isStacked, required this.isInLockedView, required this.currentAlbum, required this.advancedTroubleshooting, @@ -55,6 +58,7 @@ enum ActionButtonType { deleteLocal, upload, removeFromAlbum, + unstack, likeActivity; bool shouldShow(ActionButtonContext context) { @@ -110,6 +114,10 @@ enum ActionButtonType { context.isOwner && // !context.isInLockedView && // context.currentAlbum != null, + ActionButtonType.unstack => + context.isOwner && // + !context.isInLockedView && // + context.isStacked, ActionButtonType.likeActivity => !context.isInLockedView && context.currentAlbum != null && @@ -138,28 +146,13 @@ enum ActionButtonType { source: context.source, ), ActionButtonType.likeActivity => const LikeActivityActionButton(), + ActionButtonType.unstack => UnStackActionButton(source: context.source), }; } } class ActionButtonBuilder { - static const List _actionTypes = [ - ActionButtonType.advancedInfo, - ActionButtonType.share, - ActionButtonType.shareLink, - ActionButtonType.likeActivity, - ActionButtonType.archive, - ActionButtonType.unarchive, - ActionButtonType.download, - ActionButtonType.trash, - ActionButtonType.deletePermanent, - ActionButtonType.delete, - ActionButtonType.moveToLockFolder, - ActionButtonType.removeFromLockFolder, - ActionButtonType.deleteLocal, - ActionButtonType.upload, - ActionButtonType.removeFromAlbum, - ]; + static const List _actionTypes = ActionButtonType.values; static List build(ActionButtonContext context) { return _actionTypes.where((type) => type.shouldShow(context)).map((type) => type.buildButton(context)).toList(); diff --git a/mobile/lib/utils/datetime_helpers.dart b/mobile/lib/utils/datetime_helpers.dart index 829f71c37e..c13c8ca312 100644 --- a/mobile/lib/utils/datetime_helpers.dart +++ b/mobile/lib/utils/datetime_helpers.dart @@ -1,7 +1,7 @@ const int _maxMillisecondsSinceEpoch = 8640000000000000; // 275760-09-13 const int _minMillisecondsSinceEpoch = -62135596800000; // 0001-01-01 -DateTime? tryFromSecondsSinceEpoch(int? secondsSinceEpoch) { +DateTime? tryFromSecondsSinceEpoch(int? secondsSinceEpoch, {bool isUtc = false}) { if (secondsSinceEpoch == null) { return null; } @@ -12,7 +12,7 @@ DateTime? tryFromSecondsSinceEpoch(int? secondsSinceEpoch) { } try { - return DateTime.fromMillisecondsSinceEpoch(milliSeconds); + return DateTime.fromMillisecondsSinceEpoch(milliSeconds, isUtc: isUtc); } catch (e) { return null; } diff --git a/mobile/lib/utils/isolate.dart b/mobile/lib/utils/isolate.dart index e8b7d410f4..1ccf00d58b 100644 --- a/mobile/lib/utils/isolate.dart +++ b/mobile/lib/utils/isolate.dart @@ -32,6 +32,7 @@ Cancelable runInIsolateGentle({ } return workerManager.executeGentle((cancelledChecker) async { + T? result; await runZonedGuarded( () async { BackgroundIsolateBinaryMessenger.ensureInitialized(token); @@ -53,7 +54,7 @@ Cancelable runInIsolateGentle({ try { HttpSSLOptions.apply(applyNative: false); - return await computation(ref); + result = await computation(ref); } on CanceledError { log.warning("Computation cancelled ${debugLabel == null ? '' : ' for $debugLabel'}"); } catch (error, stack) { @@ -83,12 +84,11 @@ Cancelable runInIsolateGentle({ await Future.delayed(const Duration(seconds: 2)); } } - return null; }, (error, stack) { dPrint(() => "Error in isolate $debugLabel zone: $error, $stack"); }, ); - return null; + return result; }); } diff --git a/mobile/lib/utils/migration.dart b/mobile/lib/utils/migration.dart index 1be8647e3d..2ed6d9549f 100644 --- a/mobile/lib/utils/migration.dart +++ b/mobile/lib/utils/migration.dart @@ -22,13 +22,14 @@ import 'package:immich_mobile/infrastructure/entities/store.entity.drift.dart'; import 'package:immich_mobile/infrastructure/entities/user.entity.dart'; import 'package:immich_mobile/infrastructure/repositories/db.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.dart'; +import 'package:immich_mobile/services/app_settings.service.dart'; import 'package:immich_mobile/utils/debug_print.dart'; import 'package:immich_mobile/utils/diff.dart'; import 'package:isar/isar.dart'; // ignore: import_rule_photo_manager import 'package:photo_manager/photo_manager.dart'; -const int targetVersion = 16; +const int targetVersion = 17; Future migrateDatabaseIfNeeded(Isar db, Drift drift) async { final hasVersion = Store.tryGet(StoreKey.version) != null; @@ -64,6 +65,13 @@ Future migrateDatabaseIfNeeded(Isar db, Drift drift) async { await handleBetaMigration(version, await _isNewInstallation(db, drift), SyncStreamRepository(drift)); + if (version < 17 && Store.isBetaTimelineEnabled) { + final delay = Store.get(StoreKey.backupTriggerDelay, AppSettingsEnum.backupTriggerDelay.defaultValue); + if (delay >= 1000) { + await Store.put(StoreKey.backupTriggerDelay, (delay / 1000).toInt()); + } + } + if (targetVersion >= 12) { await Store.put(StoreKey.version, targetVersion); return; diff --git a/mobile/lib/widgets/common/immich_app_bar.dart b/mobile/lib/widgets/common/immich_app_bar.dart index 7eaedd27b5..28b5c535d2 100644 --- a/mobile/lib/widgets/common/immich_app_bar.dart +++ b/mobile/lib/widgets/common/immich_app_bar.dart @@ -129,19 +129,24 @@ class ImmichAppBar extends ConsumerWidget implements PreferredSizeWidget { title: Builder( builder: (BuildContext context) { return Row( + crossAxisAlignment: CrossAxisAlignment.center, children: [ - Builder( - builder: (context) { - return Padding( - padding: const EdgeInsets.only(top: 3.0), - child: SvgPicture.asset( - context.isDarkTheme - ? 'assets/immich-logo-inline-dark.svg' - : 'assets/immich-logo-inline-light.svg', - height: 40, - ), - ); - }, + Padding( + padding: const EdgeInsets.only(top: 3.0), + child: SvgPicture.asset( + context.isDarkTheme ? 'assets/immich-logo-inline-dark.svg' : 'assets/immich-logo-inline-light.svg', + height: 40, + ), + ), + const Tooltip( + triggerMode: TooltipTriggerMode.tap, + showDuration: Duration(seconds: 4), + message: + "The old timeline is deprecated and will be removed in a future release. Kindly switch to the new timeline under Advanced Settings.", + child: Padding( + padding: EdgeInsets.only(top: 3.0), + child: Icon(Icons.error_rounded, fill: 1, color: Colors.amber, size: 20), + ), ), ], ); diff --git a/mobile/lib/widgets/common/immich_sliver_app_bar.dart b/mobile/lib/widgets/common/immich_sliver_app_bar.dart index 09c0518a23..23d64ecfcd 100644 --- a/mobile/lib/widgets/common/immich_sliver_app_bar.dart +++ b/mobile/lib/widgets/common/immich_sliver_app_bar.dart @@ -9,8 +9,8 @@ import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/models/server_info/server_info.model.dart'; import 'package:immich_mobile/providers/backup/drift_backup.provider.dart'; import 'package:immich_mobile/providers/cast.provider.dart'; -import 'package:immich_mobile/providers/infrastructure/setting.provider.dart'; import 'package:immich_mobile/providers/infrastructure/readonly_mode.provider.dart'; +import 'package:immich_mobile/providers/infrastructure/setting.provider.dart'; import 'package:immich_mobile/providers/server_info.provider.dart'; import 'package:immich_mobile/providers/sync_status.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; @@ -168,8 +168,16 @@ class _BackupIndicator extends ConsumerWidget { @override Widget build(BuildContext context, WidgetRef ref) { const widgetSize = 30.0; - final indicatorIcon = _getBackupBadgeIcon(context, ref); - final badgeBackground = context.colorScheme.surfaceContainer; + final hasError = ref.watch(driftBackupProvider.select((state) => state.error != BackupError.none)); + final indicatorIcon = hasError + ? Icon( + Icons.warning_rounded, + size: 12, + color: context.colorScheme.error, + semanticLabel: 'backup_controller_page_backup'.tr(), + ) + : _getBackupBadgeIcon(context, ref); + final badgeBackground = hasError ? context.colorScheme.errorContainer : context.colorScheme.surfaceContainer; return InkWell( onTap: () => context.pushRoute(const DriftBackupRoute()), diff --git a/mobile/lib/widgets/forms/login/login_form.dart b/mobile/lib/widgets/forms/login/login_form.dart index 7b5d31544a..f100b58649 100644 --- a/mobile/lib/widgets/forms/login/login_form.dart +++ b/mobile/lib/widgets/forms/login/login_form.dart @@ -19,6 +19,7 @@ import 'package:immich_mobile/providers/backup/backup.provider.dart'; import 'package:immich_mobile/providers/gallery_permission.provider.dart'; import 'package:immich_mobile/providers/oauth.provider.dart'; import 'package:immich_mobile/providers/server_info.provider.dart'; +import 'package:immich_mobile/providers/websocket.provider.dart'; import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/utils/provider_utils.dart'; import 'package:immich_mobile/utils/url_helper.dart'; @@ -193,6 +194,7 @@ class LoginForm extends HookConsumerWidget { if (isBeta) { await ref.read(galleryPermissionNotifier.notifier).requestGalleryPermission(); handleSyncFlow(); + ref.read(websocketProvider.notifier).connect(); context.replaceRoute(const TabShellRoute()); return; } diff --git a/mobile/lib/widgets/settings/beta_sync_settings/sync_status_and_actions.dart b/mobile/lib/widgets/settings/beta_sync_settings/sync_status_and_actions.dart index 56506072c5..a5bca24f81 100644 --- a/mobile/lib/widgets/settings/beta_sync_settings/sync_status_and_actions.dart +++ b/mobile/lib/widgets/settings/beta_sync_settings/sync_status_and_actions.dart @@ -42,7 +42,12 @@ class SyncStatusAndActions extends HookConsumerWidget { await dbFile.copy(exportFile.path); - await Share.shareXFiles([XFile(exportFile.path)], text: 'Immich Database Export'); + final size = MediaQuery.of(context).size; + await Share.shareXFiles( + [XFile(exportFile.path)], + text: 'Immich Database Export', + sharePositionOrigin: Rect.fromPoints(Offset.zero, Offset(size.width / 3, size.height)), + ); Future.delayed(const Duration(seconds: 30), () async { if (await exportFile.exists()) { diff --git a/mobile/makefile b/mobile/makefile index 61854830d9..b90e95c902 100644 --- a/mobile/makefile +++ b/mobile/makefile @@ -9,10 +9,12 @@ pigeon: dart run pigeon --input pigeon/native_sync_api.dart dart run pigeon --input pigeon/thumbnail_api.dart dart run pigeon --input pigeon/background_worker_api.dart + dart run pigeon --input pigeon/background_worker_lock_api.dart dart run pigeon --input pigeon/connectivity_api.dart dart format lib/platform/native_sync_api.g.dart dart format lib/platform/thumbnail_api.g.dart dart format lib/platform/background_worker_api.g.dart + dart format lib/platform/background_worker_lock_api.g.dart dart format lib/platform/connectivity_api.g.dart watch: diff --git a/mobile/openapi/README.md b/mobile/openapi/README.md index 239c62449f..84140a882d 100644 --- a/mobile/openapi/README.md +++ b/mobile/openapi/README.md @@ -3,7 +3,7 @@ Immich API This Dart package is automatically generated by the [OpenAPI Generator](https://openapi-generator.tech) project: -- API version: 1.142.1 +- API version: 1.144.1 - Generator version: 7.8.0 - Build package: org.openapitools.codegen.languages.DartClientCodegen @@ -393,6 +393,7 @@ Class | Method | HTTP request | Description - [LoginCredentialDto](doc//LoginCredentialDto.md) - [LoginResponseDto](doc//LoginResponseDto.md) - [LogoutResponseDto](doc//LogoutResponseDto.md) + - [MachineLearningAvailabilityChecksDto](doc//MachineLearningAvailabilityChecksDto.md) - [ManualJobName](doc//ManualJobName.md) - [MapMarkerResponseDto](doc//MapMarkerResponseDto.md) - [MapReverseGeocodeResponseDto](doc//MapReverseGeocodeResponseDto.md) diff --git a/mobile/openapi/lib/api.dart b/mobile/openapi/lib/api.dart index e87c160d96..df2c2226b1 100644 --- a/mobile/openapi/lib/api.dart +++ b/mobile/openapi/lib/api.dart @@ -164,6 +164,7 @@ part 'model/log_level.dart'; part 'model/login_credential_dto.dart'; part 'model/login_response_dto.dart'; part 'model/logout_response_dto.dart'; +part 'model/machine_learning_availability_checks_dto.dart'; part 'model/manual_job_name.dart'; part 'model/map_marker_response_dto.dart'; part 'model/map_reverse_geocode_response_dto.dart'; diff --git a/mobile/openapi/lib/api_client.dart b/mobile/openapi/lib/api_client.dart index ae5fd9227b..06d27593c9 100644 --- a/mobile/openapi/lib/api_client.dart +++ b/mobile/openapi/lib/api_client.dart @@ -382,6 +382,8 @@ class ApiClient { return LoginResponseDto.fromJson(value); case 'LogoutResponseDto': return LogoutResponseDto.fromJson(value); + case 'MachineLearningAvailabilityChecksDto': + return MachineLearningAvailabilityChecksDto.fromJson(value); case 'ManualJobName': return ManualJobNameTypeTransformer().decode(value); case 'MapMarkerResponseDto': diff --git a/mobile/openapi/lib/model/machine_learning_availability_checks_dto.dart b/mobile/openapi/lib/model/machine_learning_availability_checks_dto.dart new file mode 100644 index 0000000000..84b3181426 --- /dev/null +++ b/mobile/openapi/lib/model/machine_learning_availability_checks_dto.dart @@ -0,0 +1,115 @@ +// +// AUTO-GENERATED FILE, DO NOT MODIFY! +// +// @dart=2.18 + +// ignore_for_file: unused_element, unused_import +// ignore_for_file: always_put_required_named_parameters_first +// ignore_for_file: constant_identifier_names +// ignore_for_file: lines_longer_than_80_chars + +part of openapi.api; + +class MachineLearningAvailabilityChecksDto { + /// Returns a new [MachineLearningAvailabilityChecksDto] instance. + MachineLearningAvailabilityChecksDto({ + required this.enabled, + required this.interval, + required this.timeout, + }); + + bool enabled; + + num interval; + + num timeout; + + @override + bool operator ==(Object other) => identical(this, other) || other is MachineLearningAvailabilityChecksDto && + other.enabled == enabled && + other.interval == interval && + other.timeout == timeout; + + @override + int get hashCode => + // ignore: unnecessary_parenthesis + (enabled.hashCode) + + (interval.hashCode) + + (timeout.hashCode); + + @override + String toString() => 'MachineLearningAvailabilityChecksDto[enabled=$enabled, interval=$interval, timeout=$timeout]'; + + Map toJson() { + final json = {}; + json[r'enabled'] = this.enabled; + json[r'interval'] = this.interval; + json[r'timeout'] = this.timeout; + return json; + } + + /// Returns a new [MachineLearningAvailabilityChecksDto] instance and imports its values from + /// [value] if it's a [Map], null otherwise. + // ignore: prefer_constructors_over_static_methods + static MachineLearningAvailabilityChecksDto? fromJson(dynamic value) { + upgradeDto(value, "MachineLearningAvailabilityChecksDto"); + if (value is Map) { + final json = value.cast(); + + return MachineLearningAvailabilityChecksDto( + enabled: mapValueOfType(json, r'enabled')!, + interval: num.parse('${json[r'interval']}'), + timeout: num.parse('${json[r'timeout']}'), + ); + } + return null; + } + + static List listFromJson(dynamic json, {bool growable = false,}) { + final result = []; + if (json is List && json.isNotEmpty) { + for (final row in json) { + final value = MachineLearningAvailabilityChecksDto.fromJson(row); + if (value != null) { + result.add(value); + } + } + } + return result.toList(growable: growable); + } + + static Map mapFromJson(dynamic json) { + final map = {}; + if (json is Map && json.isNotEmpty) { + json = json.cast(); // ignore: parameter_assignments + for (final entry in json.entries) { + final value = MachineLearningAvailabilityChecksDto.fromJson(entry.value); + if (value != null) { + map[entry.key] = value; + } + } + } + return map; + } + + // maps a json object with a list of MachineLearningAvailabilityChecksDto-objects as value to a dart map + static Map> mapListFromJson(dynamic json, {bool growable = false,}) { + final map = >{}; + if (json is Map && json.isNotEmpty) { + // ignore: parameter_assignments + json = json.cast(); + for (final entry in json.entries) { + map[entry.key] = MachineLearningAvailabilityChecksDto.listFromJson(entry.value, growable: growable,); + } + } + return map; + } + + /// The list of required keys that must be present in a JSON. + static const requiredKeys = { + 'enabled', + 'interval', + 'timeout', + }; +} + diff --git a/mobile/openapi/lib/model/system_config_machine_learning_dto.dart b/mobile/openapi/lib/model/system_config_machine_learning_dto.dart index a4a9ca7d82..d7b2566d59 100644 --- a/mobile/openapi/lib/model/system_config_machine_learning_dto.dart +++ b/mobile/openapi/lib/model/system_config_machine_learning_dto.dart @@ -13,14 +13,16 @@ part of openapi.api; class SystemConfigMachineLearningDto { /// Returns a new [SystemConfigMachineLearningDto] instance. SystemConfigMachineLearningDto({ + required this.availabilityChecks, required this.clip, required this.duplicateDetection, required this.enabled, required this.facialRecognition, - this.url, this.urls = const [], }); + MachineLearningAvailabilityChecksDto availabilityChecks; + CLIPConfig clip; DuplicateDetectionConfig duplicateDetection; @@ -29,50 +31,37 @@ class SystemConfigMachineLearningDto { FacialRecognitionConfig facialRecognition; - /// This property was deprecated in v1.122.0 - /// - /// Please note: This property should have been non-nullable! Since the specification file - /// does not include a default value (using the "default:" property), however, the generated - /// source code must fall back to having a nullable type. - /// Consider adding a "default:" property in the specification file to hide this note. - /// - String? url; - List urls; @override bool operator ==(Object other) => identical(this, other) || other is SystemConfigMachineLearningDto && + other.availabilityChecks == availabilityChecks && other.clip == clip && other.duplicateDetection == duplicateDetection && other.enabled == enabled && other.facialRecognition == facialRecognition && - other.url == url && _deepEquality.equals(other.urls, urls); @override int get hashCode => // ignore: unnecessary_parenthesis + (availabilityChecks.hashCode) + (clip.hashCode) + (duplicateDetection.hashCode) + (enabled.hashCode) + (facialRecognition.hashCode) + - (url == null ? 0 : url!.hashCode) + (urls.hashCode); @override - String toString() => 'SystemConfigMachineLearningDto[clip=$clip, duplicateDetection=$duplicateDetection, enabled=$enabled, facialRecognition=$facialRecognition, url=$url, urls=$urls]'; + String toString() => 'SystemConfigMachineLearningDto[availabilityChecks=$availabilityChecks, clip=$clip, duplicateDetection=$duplicateDetection, enabled=$enabled, facialRecognition=$facialRecognition, urls=$urls]'; Map toJson() { final json = {}; + json[r'availabilityChecks'] = this.availabilityChecks; json[r'clip'] = this.clip; json[r'duplicateDetection'] = this.duplicateDetection; json[r'enabled'] = this.enabled; json[r'facialRecognition'] = this.facialRecognition; - if (this.url != null) { - json[r'url'] = this.url; - } else { - // json[r'url'] = null; - } json[r'urls'] = this.urls; return json; } @@ -86,11 +75,11 @@ class SystemConfigMachineLearningDto { final json = value.cast(); return SystemConfigMachineLearningDto( + availabilityChecks: MachineLearningAvailabilityChecksDto.fromJson(json[r'availabilityChecks'])!, clip: CLIPConfig.fromJson(json[r'clip'])!, duplicateDetection: DuplicateDetectionConfig.fromJson(json[r'duplicateDetection'])!, enabled: mapValueOfType(json, r'enabled')!, facialRecognition: FacialRecognitionConfig.fromJson(json[r'facialRecognition'])!, - url: mapValueOfType(json, r'url'), urls: json[r'urls'] is Iterable ? (json[r'urls'] as Iterable).cast().toList(growable: false) : const [], @@ -141,6 +130,7 @@ class SystemConfigMachineLearningDto { /// The list of required keys that must be present in a JSON. static const requiredKeys = { + 'availabilityChecks', 'clip', 'duplicateDetection', 'enabled', diff --git a/mobile/pigeon/background_worker_lock_api.dart b/mobile/pigeon/background_worker_lock_api.dart new file mode 100644 index 0000000000..44c5220367 --- /dev/null +++ b/mobile/pigeon/background_worker_lock_api.dart @@ -0,0 +1,17 @@ +import 'package:pigeon/pigeon.dart'; + +@ConfigurePigeon( + PigeonOptions( + dartOut: 'lib/platform/background_worker_lock_api.g.dart', + kotlinOut: 'android/app/src/main/kotlin/app/alextran/immich/background/BackgroundWorkerLock.g.kt', + kotlinOptions: KotlinOptions(package: 'app.alextran.immich.background', includeErrorClass: false), + dartOptions: DartOptions(), + dartPackageName: 'immich_mobile', + ), +) +@HostApi() +abstract class BackgroundWorkerLockApi { + void lock(); + + void unlock(); +} diff --git a/mobile/pubspec.lock b/mobile/pubspec.lock index d0dc8e64d3..e5f972743c 100644 --- a/mobile/pubspec.lock +++ b/mobile/pubspec.lock @@ -1208,8 +1208,8 @@ packages: dependency: "direct main" description: path: "." - ref: "5459d54" - resolved-ref: "5459d54cdc1cf4d99e2193b310052f1ebb5dcf43" + ref: "893894b" + resolved-ref: "893894b98b832be8a995a8d5d4c2289d0ad2d246" url: "https://github.com/immich-app/native_video_player" source: git version: "1.3.1" diff --git a/mobile/pubspec.yaml b/mobile/pubspec.yaml index 91f937125f..b0b6399b67 100644 --- a/mobile/pubspec.yaml +++ b/mobile/pubspec.yaml @@ -2,7 +2,7 @@ name: immich_mobile description: Immich - selfhosted backup media file on mobile phone publish_to: 'none' -version: 1.142.1+3015 +version: 1.144.1+3019 environment: sdk: '>=3.8.0 <4.0.0' @@ -77,7 +77,7 @@ dependencies: native_video_player: git: url: https://github.com/immich-app/native_video_player - ref: '5459d54' + ref: '893894b' openapi: path: openapi isar: diff --git a/mobile/test/drift/main/generated/schema.dart b/mobile/test/drift/main/generated/schema.dart index 1d78a44317..073a86078f 100644 --- a/mobile/test/drift/main/generated/schema.dart +++ b/mobile/test/drift/main/generated/schema.dart @@ -14,6 +14,7 @@ import 'schema_v8.dart' as v8; import 'schema_v9.dart' as v9; import 'schema_v10.dart' as v10; import 'schema_v11.dart' as v11; +import 'schema_v12.dart' as v12; class GeneratedHelper implements SchemaInstantiationHelper { @override @@ -41,10 +42,12 @@ class GeneratedHelper implements SchemaInstantiationHelper { return v10.DatabaseAtV10(db); case 11: return v11.DatabaseAtV11(db); + case 12: + return v12.DatabaseAtV12(db); default: throw MissingSchemaException(version, versions); } } - static const versions = const [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]; + static const versions = const [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]; } diff --git a/mobile/test/drift/main/generated/schema_v12.dart b/mobile/test/drift/main/generated/schema_v12.dart new file mode 100644 index 0000000000..c42df284ec --- /dev/null +++ b/mobile/test/drift/main/generated/schema_v12.dart @@ -0,0 +1,7198 @@ +// dart format width=80 +// GENERATED CODE, DO NOT EDIT BY HAND. +// ignore_for_file: type=lint +import 'package:drift/drift.dart'; + +class UserEntity extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + UserEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn email = GeneratedColumn( + 'email', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn hasProfileImage = GeneratedColumn( + 'has_profile_image', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("has_profile_image" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn profileChangedAt = + GeneratedColumn( + 'profile_changed_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn avatarColor = GeneratedColumn( + 'avatar_color', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultValue: const CustomExpression('0'), + ); + @override + List get $columns => [ + id, + name, + email, + hasProfileImage, + profileChangedAt, + avatarColor, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'user_entity'; + @override + Set get $primaryKey => {id}; + @override + UserEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return UserEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + email: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}email'], + )!, + hasProfileImage: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}has_profile_image'], + )!, + profileChangedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}profile_changed_at'], + )!, + avatarColor: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}avatar_color'], + )!, + ); + } + + @override + UserEntity createAlias(String alias) { + return UserEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class UserEntityData extends DataClass implements Insertable { + final String id; + final String name; + final String email; + final bool hasProfileImage; + final DateTime profileChangedAt; + final int avatarColor; + const UserEntityData({ + required this.id, + required this.name, + required this.email, + required this.hasProfileImage, + required this.profileChangedAt, + required this.avatarColor, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['name'] = Variable(name); + map['email'] = Variable(email); + map['has_profile_image'] = Variable(hasProfileImage); + map['profile_changed_at'] = Variable(profileChangedAt); + map['avatar_color'] = Variable(avatarColor); + return map; + } + + factory UserEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return UserEntityData( + id: serializer.fromJson(json['id']), + name: serializer.fromJson(json['name']), + email: serializer.fromJson(json['email']), + hasProfileImage: serializer.fromJson(json['hasProfileImage']), + profileChangedAt: serializer.fromJson(json['profileChangedAt']), + avatarColor: serializer.fromJson(json['avatarColor']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'name': serializer.toJson(name), + 'email': serializer.toJson(email), + 'hasProfileImage': serializer.toJson(hasProfileImage), + 'profileChangedAt': serializer.toJson(profileChangedAt), + 'avatarColor': serializer.toJson(avatarColor), + }; + } + + UserEntityData copyWith({ + String? id, + String? name, + String? email, + bool? hasProfileImage, + DateTime? profileChangedAt, + int? avatarColor, + }) => UserEntityData( + id: id ?? this.id, + name: name ?? this.name, + email: email ?? this.email, + hasProfileImage: hasProfileImage ?? this.hasProfileImage, + profileChangedAt: profileChangedAt ?? this.profileChangedAt, + avatarColor: avatarColor ?? this.avatarColor, + ); + UserEntityData copyWithCompanion(UserEntityCompanion data) { + return UserEntityData( + id: data.id.present ? data.id.value : this.id, + name: data.name.present ? data.name.value : this.name, + email: data.email.present ? data.email.value : this.email, + hasProfileImage: data.hasProfileImage.present + ? data.hasProfileImage.value + : this.hasProfileImage, + profileChangedAt: data.profileChangedAt.present + ? data.profileChangedAt.value + : this.profileChangedAt, + avatarColor: data.avatarColor.present + ? data.avatarColor.value + : this.avatarColor, + ); + } + + @override + String toString() { + return (StringBuffer('UserEntityData(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('email: $email, ') + ..write('hasProfileImage: $hasProfileImage, ') + ..write('profileChangedAt: $profileChangedAt, ') + ..write('avatarColor: $avatarColor') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + name, + email, + hasProfileImage, + profileChangedAt, + avatarColor, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is UserEntityData && + other.id == this.id && + other.name == this.name && + other.email == this.email && + other.hasProfileImage == this.hasProfileImage && + other.profileChangedAt == this.profileChangedAt && + other.avatarColor == this.avatarColor); +} + +class UserEntityCompanion extends UpdateCompanion { + final Value id; + final Value name; + final Value email; + final Value hasProfileImage; + final Value profileChangedAt; + final Value avatarColor; + const UserEntityCompanion({ + this.id = const Value.absent(), + this.name = const Value.absent(), + this.email = const Value.absent(), + this.hasProfileImage = const Value.absent(), + this.profileChangedAt = const Value.absent(), + this.avatarColor = const Value.absent(), + }); + UserEntityCompanion.insert({ + required String id, + required String name, + required String email, + this.hasProfileImage = const Value.absent(), + this.profileChangedAt = const Value.absent(), + this.avatarColor = const Value.absent(), + }) : id = Value(id), + name = Value(name), + email = Value(email); + static Insertable custom({ + Expression? id, + Expression? name, + Expression? email, + Expression? hasProfileImage, + Expression? profileChangedAt, + Expression? avatarColor, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (name != null) 'name': name, + if (email != null) 'email': email, + if (hasProfileImage != null) 'has_profile_image': hasProfileImage, + if (profileChangedAt != null) 'profile_changed_at': profileChangedAt, + if (avatarColor != null) 'avatar_color': avatarColor, + }); + } + + UserEntityCompanion copyWith({ + Value? id, + Value? name, + Value? email, + Value? hasProfileImage, + Value? profileChangedAt, + Value? avatarColor, + }) { + return UserEntityCompanion( + id: id ?? this.id, + name: name ?? this.name, + email: email ?? this.email, + hasProfileImage: hasProfileImage ?? this.hasProfileImage, + profileChangedAt: profileChangedAt ?? this.profileChangedAt, + avatarColor: avatarColor ?? this.avatarColor, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (email.present) { + map['email'] = Variable(email.value); + } + if (hasProfileImage.present) { + map['has_profile_image'] = Variable(hasProfileImage.value); + } + if (profileChangedAt.present) { + map['profile_changed_at'] = Variable(profileChangedAt.value); + } + if (avatarColor.present) { + map['avatar_color'] = Variable(avatarColor.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('UserEntityCompanion(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('email: $email, ') + ..write('hasProfileImage: $hasProfileImage, ') + ..write('profileChangedAt: $profileChangedAt, ') + ..write('avatarColor: $avatarColor') + ..write(')')) + .toString(); + } +} + +class RemoteAssetEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + RemoteAssetEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn type = GeneratedColumn( + 'type', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn width = GeneratedColumn( + 'width', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn height = GeneratedColumn( + 'height', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn durationInSeconds = GeneratedColumn( + 'duration_in_seconds', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn checksum = GeneratedColumn( + 'checksum', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn isFavorite = GeneratedColumn( + 'is_favorite', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_favorite" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn ownerId = GeneratedColumn( + 'owner_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn localDateTime = + GeneratedColumn( + 'local_date_time', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + late final GeneratedColumn thumbHash = GeneratedColumn( + 'thumb_hash', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn deletedAt = GeneratedColumn( + 'deleted_at', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + late final GeneratedColumn livePhotoVideoId = GeneratedColumn( + 'live_photo_video_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn visibility = GeneratedColumn( + 'visibility', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn stackId = GeneratedColumn( + 'stack_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn libraryId = GeneratedColumn( + 'library_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + @override + List get $columns => [ + name, + type, + createdAt, + updatedAt, + width, + height, + durationInSeconds, + id, + checksum, + isFavorite, + ownerId, + localDateTime, + thumbHash, + deletedAt, + livePhotoVideoId, + visibility, + stackId, + libraryId, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'remote_asset_entity'; + @override + Set get $primaryKey => {id}; + @override + RemoteAssetEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return RemoteAssetEntityData( + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + type: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}type'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}updated_at'], + )!, + width: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}width'], + ), + height: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}height'], + ), + durationInSeconds: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}duration_in_seconds'], + ), + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + checksum: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}checksum'], + )!, + isFavorite: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_favorite'], + )!, + ownerId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}owner_id'], + )!, + localDateTime: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}local_date_time'], + ), + thumbHash: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}thumb_hash'], + ), + deletedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}deleted_at'], + ), + livePhotoVideoId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}live_photo_video_id'], + ), + visibility: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}visibility'], + )!, + stackId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}stack_id'], + ), + libraryId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}library_id'], + ), + ); + } + + @override + RemoteAssetEntity createAlias(String alias) { + return RemoteAssetEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class RemoteAssetEntityData extends DataClass + implements Insertable { + final String name; + final int type; + final DateTime createdAt; + final DateTime updatedAt; + final int? width; + final int? height; + final int? durationInSeconds; + final String id; + final String checksum; + final bool isFavorite; + final String ownerId; + final DateTime? localDateTime; + final String? thumbHash; + final DateTime? deletedAt; + final String? livePhotoVideoId; + final int visibility; + final String? stackId; + final String? libraryId; + const RemoteAssetEntityData({ + required this.name, + required this.type, + required this.createdAt, + required this.updatedAt, + this.width, + this.height, + this.durationInSeconds, + required this.id, + required this.checksum, + required this.isFavorite, + required this.ownerId, + this.localDateTime, + this.thumbHash, + this.deletedAt, + this.livePhotoVideoId, + required this.visibility, + this.stackId, + this.libraryId, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['name'] = Variable(name); + map['type'] = Variable(type); + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); + if (!nullToAbsent || width != null) { + map['width'] = Variable(width); + } + if (!nullToAbsent || height != null) { + map['height'] = Variable(height); + } + if (!nullToAbsent || durationInSeconds != null) { + map['duration_in_seconds'] = Variable(durationInSeconds); + } + map['id'] = Variable(id); + map['checksum'] = Variable(checksum); + map['is_favorite'] = Variable(isFavorite); + map['owner_id'] = Variable(ownerId); + if (!nullToAbsent || localDateTime != null) { + map['local_date_time'] = Variable(localDateTime); + } + if (!nullToAbsent || thumbHash != null) { + map['thumb_hash'] = Variable(thumbHash); + } + if (!nullToAbsent || deletedAt != null) { + map['deleted_at'] = Variable(deletedAt); + } + if (!nullToAbsent || livePhotoVideoId != null) { + map['live_photo_video_id'] = Variable(livePhotoVideoId); + } + map['visibility'] = Variable(visibility); + if (!nullToAbsent || stackId != null) { + map['stack_id'] = Variable(stackId); + } + if (!nullToAbsent || libraryId != null) { + map['library_id'] = Variable(libraryId); + } + return map; + } + + factory RemoteAssetEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return RemoteAssetEntityData( + name: serializer.fromJson(json['name']), + type: serializer.fromJson(json['type']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + width: serializer.fromJson(json['width']), + height: serializer.fromJson(json['height']), + durationInSeconds: serializer.fromJson(json['durationInSeconds']), + id: serializer.fromJson(json['id']), + checksum: serializer.fromJson(json['checksum']), + isFavorite: serializer.fromJson(json['isFavorite']), + ownerId: serializer.fromJson(json['ownerId']), + localDateTime: serializer.fromJson(json['localDateTime']), + thumbHash: serializer.fromJson(json['thumbHash']), + deletedAt: serializer.fromJson(json['deletedAt']), + livePhotoVideoId: serializer.fromJson(json['livePhotoVideoId']), + visibility: serializer.fromJson(json['visibility']), + stackId: serializer.fromJson(json['stackId']), + libraryId: serializer.fromJson(json['libraryId']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'name': serializer.toJson(name), + 'type': serializer.toJson(type), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'width': serializer.toJson(width), + 'height': serializer.toJson(height), + 'durationInSeconds': serializer.toJson(durationInSeconds), + 'id': serializer.toJson(id), + 'checksum': serializer.toJson(checksum), + 'isFavorite': serializer.toJson(isFavorite), + 'ownerId': serializer.toJson(ownerId), + 'localDateTime': serializer.toJson(localDateTime), + 'thumbHash': serializer.toJson(thumbHash), + 'deletedAt': serializer.toJson(deletedAt), + 'livePhotoVideoId': serializer.toJson(livePhotoVideoId), + 'visibility': serializer.toJson(visibility), + 'stackId': serializer.toJson(stackId), + 'libraryId': serializer.toJson(libraryId), + }; + } + + RemoteAssetEntityData copyWith({ + String? name, + int? type, + DateTime? createdAt, + DateTime? updatedAt, + Value width = const Value.absent(), + Value height = const Value.absent(), + Value durationInSeconds = const Value.absent(), + String? id, + String? checksum, + bool? isFavorite, + String? ownerId, + Value localDateTime = const Value.absent(), + Value thumbHash = const Value.absent(), + Value deletedAt = const Value.absent(), + Value livePhotoVideoId = const Value.absent(), + int? visibility, + Value stackId = const Value.absent(), + Value libraryId = const Value.absent(), + }) => RemoteAssetEntityData( + name: name ?? this.name, + type: type ?? this.type, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + width: width.present ? width.value : this.width, + height: height.present ? height.value : this.height, + durationInSeconds: durationInSeconds.present + ? durationInSeconds.value + : this.durationInSeconds, + id: id ?? this.id, + checksum: checksum ?? this.checksum, + isFavorite: isFavorite ?? this.isFavorite, + ownerId: ownerId ?? this.ownerId, + localDateTime: localDateTime.present + ? localDateTime.value + : this.localDateTime, + thumbHash: thumbHash.present ? thumbHash.value : this.thumbHash, + deletedAt: deletedAt.present ? deletedAt.value : this.deletedAt, + livePhotoVideoId: livePhotoVideoId.present + ? livePhotoVideoId.value + : this.livePhotoVideoId, + visibility: visibility ?? this.visibility, + stackId: stackId.present ? stackId.value : this.stackId, + libraryId: libraryId.present ? libraryId.value : this.libraryId, + ); + RemoteAssetEntityData copyWithCompanion(RemoteAssetEntityCompanion data) { + return RemoteAssetEntityData( + name: data.name.present ? data.name.value : this.name, + type: data.type.present ? data.type.value : this.type, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + width: data.width.present ? data.width.value : this.width, + height: data.height.present ? data.height.value : this.height, + durationInSeconds: data.durationInSeconds.present + ? data.durationInSeconds.value + : this.durationInSeconds, + id: data.id.present ? data.id.value : this.id, + checksum: data.checksum.present ? data.checksum.value : this.checksum, + isFavorite: data.isFavorite.present + ? data.isFavorite.value + : this.isFavorite, + ownerId: data.ownerId.present ? data.ownerId.value : this.ownerId, + localDateTime: data.localDateTime.present + ? data.localDateTime.value + : this.localDateTime, + thumbHash: data.thumbHash.present ? data.thumbHash.value : this.thumbHash, + deletedAt: data.deletedAt.present ? data.deletedAt.value : this.deletedAt, + livePhotoVideoId: data.livePhotoVideoId.present + ? data.livePhotoVideoId.value + : this.livePhotoVideoId, + visibility: data.visibility.present + ? data.visibility.value + : this.visibility, + stackId: data.stackId.present ? data.stackId.value : this.stackId, + libraryId: data.libraryId.present ? data.libraryId.value : this.libraryId, + ); + } + + @override + String toString() { + return (StringBuffer('RemoteAssetEntityData(') + ..write('name: $name, ') + ..write('type: $type, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('width: $width, ') + ..write('height: $height, ') + ..write('durationInSeconds: $durationInSeconds, ') + ..write('id: $id, ') + ..write('checksum: $checksum, ') + ..write('isFavorite: $isFavorite, ') + ..write('ownerId: $ownerId, ') + ..write('localDateTime: $localDateTime, ') + ..write('thumbHash: $thumbHash, ') + ..write('deletedAt: $deletedAt, ') + ..write('livePhotoVideoId: $livePhotoVideoId, ') + ..write('visibility: $visibility, ') + ..write('stackId: $stackId, ') + ..write('libraryId: $libraryId') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + name, + type, + createdAt, + updatedAt, + width, + height, + durationInSeconds, + id, + checksum, + isFavorite, + ownerId, + localDateTime, + thumbHash, + deletedAt, + livePhotoVideoId, + visibility, + stackId, + libraryId, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is RemoteAssetEntityData && + other.name == this.name && + other.type == this.type && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && + other.width == this.width && + other.height == this.height && + other.durationInSeconds == this.durationInSeconds && + other.id == this.id && + other.checksum == this.checksum && + other.isFavorite == this.isFavorite && + other.ownerId == this.ownerId && + other.localDateTime == this.localDateTime && + other.thumbHash == this.thumbHash && + other.deletedAt == this.deletedAt && + other.livePhotoVideoId == this.livePhotoVideoId && + other.visibility == this.visibility && + other.stackId == this.stackId && + other.libraryId == this.libraryId); +} + +class RemoteAssetEntityCompanion + extends UpdateCompanion { + final Value name; + final Value type; + final Value createdAt; + final Value updatedAt; + final Value width; + final Value height; + final Value durationInSeconds; + final Value id; + final Value checksum; + final Value isFavorite; + final Value ownerId; + final Value localDateTime; + final Value thumbHash; + final Value deletedAt; + final Value livePhotoVideoId; + final Value visibility; + final Value stackId; + final Value libraryId; + const RemoteAssetEntityCompanion({ + this.name = const Value.absent(), + this.type = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.width = const Value.absent(), + this.height = const Value.absent(), + this.durationInSeconds = const Value.absent(), + this.id = const Value.absent(), + this.checksum = const Value.absent(), + this.isFavorite = const Value.absent(), + this.ownerId = const Value.absent(), + this.localDateTime = const Value.absent(), + this.thumbHash = const Value.absent(), + this.deletedAt = const Value.absent(), + this.livePhotoVideoId = const Value.absent(), + this.visibility = const Value.absent(), + this.stackId = const Value.absent(), + this.libraryId = const Value.absent(), + }); + RemoteAssetEntityCompanion.insert({ + required String name, + required int type, + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.width = const Value.absent(), + this.height = const Value.absent(), + this.durationInSeconds = const Value.absent(), + required String id, + required String checksum, + this.isFavorite = const Value.absent(), + required String ownerId, + this.localDateTime = const Value.absent(), + this.thumbHash = const Value.absent(), + this.deletedAt = const Value.absent(), + this.livePhotoVideoId = const Value.absent(), + required int visibility, + this.stackId = const Value.absent(), + this.libraryId = const Value.absent(), + }) : name = Value(name), + type = Value(type), + id = Value(id), + checksum = Value(checksum), + ownerId = Value(ownerId), + visibility = Value(visibility); + static Insertable custom({ + Expression? name, + Expression? type, + Expression? createdAt, + Expression? updatedAt, + Expression? width, + Expression? height, + Expression? durationInSeconds, + Expression? id, + Expression? checksum, + Expression? isFavorite, + Expression? ownerId, + Expression? localDateTime, + Expression? thumbHash, + Expression? deletedAt, + Expression? livePhotoVideoId, + Expression? visibility, + Expression? stackId, + Expression? libraryId, + }) { + return RawValuesInsertable({ + if (name != null) 'name': name, + if (type != null) 'type': type, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, + if (width != null) 'width': width, + if (height != null) 'height': height, + if (durationInSeconds != null) 'duration_in_seconds': durationInSeconds, + if (id != null) 'id': id, + if (checksum != null) 'checksum': checksum, + if (isFavorite != null) 'is_favorite': isFavorite, + if (ownerId != null) 'owner_id': ownerId, + if (localDateTime != null) 'local_date_time': localDateTime, + if (thumbHash != null) 'thumb_hash': thumbHash, + if (deletedAt != null) 'deleted_at': deletedAt, + if (livePhotoVideoId != null) 'live_photo_video_id': livePhotoVideoId, + if (visibility != null) 'visibility': visibility, + if (stackId != null) 'stack_id': stackId, + if (libraryId != null) 'library_id': libraryId, + }); + } + + RemoteAssetEntityCompanion copyWith({ + Value? name, + Value? type, + Value? createdAt, + Value? updatedAt, + Value? width, + Value? height, + Value? durationInSeconds, + Value? id, + Value? checksum, + Value? isFavorite, + Value? ownerId, + Value? localDateTime, + Value? thumbHash, + Value? deletedAt, + Value? livePhotoVideoId, + Value? visibility, + Value? stackId, + Value? libraryId, + }) { + return RemoteAssetEntityCompanion( + name: name ?? this.name, + type: type ?? this.type, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + width: width ?? this.width, + height: height ?? this.height, + durationInSeconds: durationInSeconds ?? this.durationInSeconds, + id: id ?? this.id, + checksum: checksum ?? this.checksum, + isFavorite: isFavorite ?? this.isFavorite, + ownerId: ownerId ?? this.ownerId, + localDateTime: localDateTime ?? this.localDateTime, + thumbHash: thumbHash ?? this.thumbHash, + deletedAt: deletedAt ?? this.deletedAt, + livePhotoVideoId: livePhotoVideoId ?? this.livePhotoVideoId, + visibility: visibility ?? this.visibility, + stackId: stackId ?? this.stackId, + libraryId: libraryId ?? this.libraryId, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (name.present) { + map['name'] = Variable(name.value); + } + if (type.present) { + map['type'] = Variable(type.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (width.present) { + map['width'] = Variable(width.value); + } + if (height.present) { + map['height'] = Variable(height.value); + } + if (durationInSeconds.present) { + map['duration_in_seconds'] = Variable(durationInSeconds.value); + } + if (id.present) { + map['id'] = Variable(id.value); + } + if (checksum.present) { + map['checksum'] = Variable(checksum.value); + } + if (isFavorite.present) { + map['is_favorite'] = Variable(isFavorite.value); + } + if (ownerId.present) { + map['owner_id'] = Variable(ownerId.value); + } + if (localDateTime.present) { + map['local_date_time'] = Variable(localDateTime.value); + } + if (thumbHash.present) { + map['thumb_hash'] = Variable(thumbHash.value); + } + if (deletedAt.present) { + map['deleted_at'] = Variable(deletedAt.value); + } + if (livePhotoVideoId.present) { + map['live_photo_video_id'] = Variable(livePhotoVideoId.value); + } + if (visibility.present) { + map['visibility'] = Variable(visibility.value); + } + if (stackId.present) { + map['stack_id'] = Variable(stackId.value); + } + if (libraryId.present) { + map['library_id'] = Variable(libraryId.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('RemoteAssetEntityCompanion(') + ..write('name: $name, ') + ..write('type: $type, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('width: $width, ') + ..write('height: $height, ') + ..write('durationInSeconds: $durationInSeconds, ') + ..write('id: $id, ') + ..write('checksum: $checksum, ') + ..write('isFavorite: $isFavorite, ') + ..write('ownerId: $ownerId, ') + ..write('localDateTime: $localDateTime, ') + ..write('thumbHash: $thumbHash, ') + ..write('deletedAt: $deletedAt, ') + ..write('livePhotoVideoId: $livePhotoVideoId, ') + ..write('visibility: $visibility, ') + ..write('stackId: $stackId, ') + ..write('libraryId: $libraryId') + ..write(')')) + .toString(); + } +} + +class StackEntity extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + StackEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn ownerId = GeneratedColumn( + 'owner_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn primaryAssetId = GeneratedColumn( + 'primary_asset_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + @override + List get $columns => [ + id, + createdAt, + updatedAt, + ownerId, + primaryAssetId, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'stack_entity'; + @override + Set get $primaryKey => {id}; + @override + StackEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return StackEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}updated_at'], + )!, + ownerId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}owner_id'], + )!, + primaryAssetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}primary_asset_id'], + )!, + ); + } + + @override + StackEntity createAlias(String alias) { + return StackEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class StackEntityData extends DataClass implements Insertable { + final String id; + final DateTime createdAt; + final DateTime updatedAt; + final String ownerId; + final String primaryAssetId; + const StackEntityData({ + required this.id, + required this.createdAt, + required this.updatedAt, + required this.ownerId, + required this.primaryAssetId, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); + map['owner_id'] = Variable(ownerId); + map['primary_asset_id'] = Variable(primaryAssetId); + return map; + } + + factory StackEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return StackEntityData( + id: serializer.fromJson(json['id']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + ownerId: serializer.fromJson(json['ownerId']), + primaryAssetId: serializer.fromJson(json['primaryAssetId']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'ownerId': serializer.toJson(ownerId), + 'primaryAssetId': serializer.toJson(primaryAssetId), + }; + } + + StackEntityData copyWith({ + String? id, + DateTime? createdAt, + DateTime? updatedAt, + String? ownerId, + String? primaryAssetId, + }) => StackEntityData( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ownerId: ownerId ?? this.ownerId, + primaryAssetId: primaryAssetId ?? this.primaryAssetId, + ); + StackEntityData copyWithCompanion(StackEntityCompanion data) { + return StackEntityData( + id: data.id.present ? data.id.value : this.id, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + ownerId: data.ownerId.present ? data.ownerId.value : this.ownerId, + primaryAssetId: data.primaryAssetId.present + ? data.primaryAssetId.value + : this.primaryAssetId, + ); + } + + @override + String toString() { + return (StringBuffer('StackEntityData(') + ..write('id: $id, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('ownerId: $ownerId, ') + ..write('primaryAssetId: $primaryAssetId') + ..write(')')) + .toString(); + } + + @override + int get hashCode => + Object.hash(id, createdAt, updatedAt, ownerId, primaryAssetId); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is StackEntityData && + other.id == this.id && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && + other.ownerId == this.ownerId && + other.primaryAssetId == this.primaryAssetId); +} + +class StackEntityCompanion extends UpdateCompanion { + final Value id; + final Value createdAt; + final Value updatedAt; + final Value ownerId; + final Value primaryAssetId; + const StackEntityCompanion({ + this.id = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.ownerId = const Value.absent(), + this.primaryAssetId = const Value.absent(), + }); + StackEntityCompanion.insert({ + required String id, + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + required String ownerId, + required String primaryAssetId, + }) : id = Value(id), + ownerId = Value(ownerId), + primaryAssetId = Value(primaryAssetId); + static Insertable custom({ + Expression? id, + Expression? createdAt, + Expression? updatedAt, + Expression? ownerId, + Expression? primaryAssetId, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, + if (ownerId != null) 'owner_id': ownerId, + if (primaryAssetId != null) 'primary_asset_id': primaryAssetId, + }); + } + + StackEntityCompanion copyWith({ + Value? id, + Value? createdAt, + Value? updatedAt, + Value? ownerId, + Value? primaryAssetId, + }) { + return StackEntityCompanion( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ownerId: ownerId ?? this.ownerId, + primaryAssetId: primaryAssetId ?? this.primaryAssetId, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (ownerId.present) { + map['owner_id'] = Variable(ownerId.value); + } + if (primaryAssetId.present) { + map['primary_asset_id'] = Variable(primaryAssetId.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('StackEntityCompanion(') + ..write('id: $id, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('ownerId: $ownerId, ') + ..write('primaryAssetId: $primaryAssetId') + ..write(')')) + .toString(); + } +} + +class LocalAssetEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + LocalAssetEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn type = GeneratedColumn( + 'type', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn width = GeneratedColumn( + 'width', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn height = GeneratedColumn( + 'height', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn durationInSeconds = GeneratedColumn( + 'duration_in_seconds', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn checksum = GeneratedColumn( + 'checksum', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn isFavorite = GeneratedColumn( + 'is_favorite', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_favorite" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn orientation = GeneratedColumn( + 'orientation', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultValue: const CustomExpression('0'), + ); + @override + List get $columns => [ + name, + type, + createdAt, + updatedAt, + width, + height, + durationInSeconds, + id, + checksum, + isFavorite, + orientation, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'local_asset_entity'; + @override + Set get $primaryKey => {id}; + @override + LocalAssetEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return LocalAssetEntityData( + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + type: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}type'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}updated_at'], + )!, + width: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}width'], + ), + height: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}height'], + ), + durationInSeconds: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}duration_in_seconds'], + ), + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + checksum: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}checksum'], + ), + isFavorite: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_favorite'], + )!, + orientation: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}orientation'], + )!, + ); + } + + @override + LocalAssetEntity createAlias(String alias) { + return LocalAssetEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class LocalAssetEntityData extends DataClass + implements Insertable { + final String name; + final int type; + final DateTime createdAt; + final DateTime updatedAt; + final int? width; + final int? height; + final int? durationInSeconds; + final String id; + final String? checksum; + final bool isFavorite; + final int orientation; + const LocalAssetEntityData({ + required this.name, + required this.type, + required this.createdAt, + required this.updatedAt, + this.width, + this.height, + this.durationInSeconds, + required this.id, + this.checksum, + required this.isFavorite, + required this.orientation, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['name'] = Variable(name); + map['type'] = Variable(type); + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); + if (!nullToAbsent || width != null) { + map['width'] = Variable(width); + } + if (!nullToAbsent || height != null) { + map['height'] = Variable(height); + } + if (!nullToAbsent || durationInSeconds != null) { + map['duration_in_seconds'] = Variable(durationInSeconds); + } + map['id'] = Variable(id); + if (!nullToAbsent || checksum != null) { + map['checksum'] = Variable(checksum); + } + map['is_favorite'] = Variable(isFavorite); + map['orientation'] = Variable(orientation); + return map; + } + + factory LocalAssetEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return LocalAssetEntityData( + name: serializer.fromJson(json['name']), + type: serializer.fromJson(json['type']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + width: serializer.fromJson(json['width']), + height: serializer.fromJson(json['height']), + durationInSeconds: serializer.fromJson(json['durationInSeconds']), + id: serializer.fromJson(json['id']), + checksum: serializer.fromJson(json['checksum']), + isFavorite: serializer.fromJson(json['isFavorite']), + orientation: serializer.fromJson(json['orientation']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'name': serializer.toJson(name), + 'type': serializer.toJson(type), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'width': serializer.toJson(width), + 'height': serializer.toJson(height), + 'durationInSeconds': serializer.toJson(durationInSeconds), + 'id': serializer.toJson(id), + 'checksum': serializer.toJson(checksum), + 'isFavorite': serializer.toJson(isFavorite), + 'orientation': serializer.toJson(orientation), + }; + } + + LocalAssetEntityData copyWith({ + String? name, + int? type, + DateTime? createdAt, + DateTime? updatedAt, + Value width = const Value.absent(), + Value height = const Value.absent(), + Value durationInSeconds = const Value.absent(), + String? id, + Value checksum = const Value.absent(), + bool? isFavorite, + int? orientation, + }) => LocalAssetEntityData( + name: name ?? this.name, + type: type ?? this.type, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + width: width.present ? width.value : this.width, + height: height.present ? height.value : this.height, + durationInSeconds: durationInSeconds.present + ? durationInSeconds.value + : this.durationInSeconds, + id: id ?? this.id, + checksum: checksum.present ? checksum.value : this.checksum, + isFavorite: isFavorite ?? this.isFavorite, + orientation: orientation ?? this.orientation, + ); + LocalAssetEntityData copyWithCompanion(LocalAssetEntityCompanion data) { + return LocalAssetEntityData( + name: data.name.present ? data.name.value : this.name, + type: data.type.present ? data.type.value : this.type, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + width: data.width.present ? data.width.value : this.width, + height: data.height.present ? data.height.value : this.height, + durationInSeconds: data.durationInSeconds.present + ? data.durationInSeconds.value + : this.durationInSeconds, + id: data.id.present ? data.id.value : this.id, + checksum: data.checksum.present ? data.checksum.value : this.checksum, + isFavorite: data.isFavorite.present + ? data.isFavorite.value + : this.isFavorite, + orientation: data.orientation.present + ? data.orientation.value + : this.orientation, + ); + } + + @override + String toString() { + return (StringBuffer('LocalAssetEntityData(') + ..write('name: $name, ') + ..write('type: $type, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('width: $width, ') + ..write('height: $height, ') + ..write('durationInSeconds: $durationInSeconds, ') + ..write('id: $id, ') + ..write('checksum: $checksum, ') + ..write('isFavorite: $isFavorite, ') + ..write('orientation: $orientation') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + name, + type, + createdAt, + updatedAt, + width, + height, + durationInSeconds, + id, + checksum, + isFavorite, + orientation, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is LocalAssetEntityData && + other.name == this.name && + other.type == this.type && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && + other.width == this.width && + other.height == this.height && + other.durationInSeconds == this.durationInSeconds && + other.id == this.id && + other.checksum == this.checksum && + other.isFavorite == this.isFavorite && + other.orientation == this.orientation); +} + +class LocalAssetEntityCompanion extends UpdateCompanion { + final Value name; + final Value type; + final Value createdAt; + final Value updatedAt; + final Value width; + final Value height; + final Value durationInSeconds; + final Value id; + final Value checksum; + final Value isFavorite; + final Value orientation; + const LocalAssetEntityCompanion({ + this.name = const Value.absent(), + this.type = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.width = const Value.absent(), + this.height = const Value.absent(), + this.durationInSeconds = const Value.absent(), + this.id = const Value.absent(), + this.checksum = const Value.absent(), + this.isFavorite = const Value.absent(), + this.orientation = const Value.absent(), + }); + LocalAssetEntityCompanion.insert({ + required String name, + required int type, + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.width = const Value.absent(), + this.height = const Value.absent(), + this.durationInSeconds = const Value.absent(), + required String id, + this.checksum = const Value.absent(), + this.isFavorite = const Value.absent(), + this.orientation = const Value.absent(), + }) : name = Value(name), + type = Value(type), + id = Value(id); + static Insertable custom({ + Expression? name, + Expression? type, + Expression? createdAt, + Expression? updatedAt, + Expression? width, + Expression? height, + Expression? durationInSeconds, + Expression? id, + Expression? checksum, + Expression? isFavorite, + Expression? orientation, + }) { + return RawValuesInsertable({ + if (name != null) 'name': name, + if (type != null) 'type': type, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, + if (width != null) 'width': width, + if (height != null) 'height': height, + if (durationInSeconds != null) 'duration_in_seconds': durationInSeconds, + if (id != null) 'id': id, + if (checksum != null) 'checksum': checksum, + if (isFavorite != null) 'is_favorite': isFavorite, + if (orientation != null) 'orientation': orientation, + }); + } + + LocalAssetEntityCompanion copyWith({ + Value? name, + Value? type, + Value? createdAt, + Value? updatedAt, + Value? width, + Value? height, + Value? durationInSeconds, + Value? id, + Value? checksum, + Value? isFavorite, + Value? orientation, + }) { + return LocalAssetEntityCompanion( + name: name ?? this.name, + type: type ?? this.type, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + width: width ?? this.width, + height: height ?? this.height, + durationInSeconds: durationInSeconds ?? this.durationInSeconds, + id: id ?? this.id, + checksum: checksum ?? this.checksum, + isFavorite: isFavorite ?? this.isFavorite, + orientation: orientation ?? this.orientation, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (name.present) { + map['name'] = Variable(name.value); + } + if (type.present) { + map['type'] = Variable(type.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (width.present) { + map['width'] = Variable(width.value); + } + if (height.present) { + map['height'] = Variable(height.value); + } + if (durationInSeconds.present) { + map['duration_in_seconds'] = Variable(durationInSeconds.value); + } + if (id.present) { + map['id'] = Variable(id.value); + } + if (checksum.present) { + map['checksum'] = Variable(checksum.value); + } + if (isFavorite.present) { + map['is_favorite'] = Variable(isFavorite.value); + } + if (orientation.present) { + map['orientation'] = Variable(orientation.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('LocalAssetEntityCompanion(') + ..write('name: $name, ') + ..write('type: $type, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('width: $width, ') + ..write('height: $height, ') + ..write('durationInSeconds: $durationInSeconds, ') + ..write('id: $id, ') + ..write('checksum: $checksum, ') + ..write('isFavorite: $isFavorite, ') + ..write('orientation: $orientation') + ..write(')')) + .toString(); + } +} + +class RemoteAlbumEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + RemoteAlbumEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn description = GeneratedColumn( + 'description', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: false, + defaultValue: const CustomExpression('\'\''), + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn ownerId = GeneratedColumn( + 'owner_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn thumbnailAssetId = GeneratedColumn( + 'thumbnail_asset_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_asset_entity (id) ON DELETE SET NULL', + ), + ); + late final GeneratedColumn isActivityEnabled = GeneratedColumn( + 'is_activity_enabled', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_activity_enabled" IN (0, 1))', + ), + defaultValue: const CustomExpression('1'), + ); + late final GeneratedColumn order = GeneratedColumn( + 'order', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + @override + List get $columns => [ + id, + name, + description, + createdAt, + updatedAt, + ownerId, + thumbnailAssetId, + isActivityEnabled, + order, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'remote_album_entity'; + @override + Set get $primaryKey => {id}; + @override + RemoteAlbumEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return RemoteAlbumEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + description: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}description'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}updated_at'], + )!, + ownerId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}owner_id'], + )!, + thumbnailAssetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}thumbnail_asset_id'], + ), + isActivityEnabled: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_activity_enabled'], + )!, + order: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}order'], + )!, + ); + } + + @override + RemoteAlbumEntity createAlias(String alias) { + return RemoteAlbumEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class RemoteAlbumEntityData extends DataClass + implements Insertable { + final String id; + final String name; + final String description; + final DateTime createdAt; + final DateTime updatedAt; + final String ownerId; + final String? thumbnailAssetId; + final bool isActivityEnabled; + final int order; + const RemoteAlbumEntityData({ + required this.id, + required this.name, + required this.description, + required this.createdAt, + required this.updatedAt, + required this.ownerId, + this.thumbnailAssetId, + required this.isActivityEnabled, + required this.order, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['name'] = Variable(name); + map['description'] = Variable(description); + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); + map['owner_id'] = Variable(ownerId); + if (!nullToAbsent || thumbnailAssetId != null) { + map['thumbnail_asset_id'] = Variable(thumbnailAssetId); + } + map['is_activity_enabled'] = Variable(isActivityEnabled); + map['order'] = Variable(order); + return map; + } + + factory RemoteAlbumEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return RemoteAlbumEntityData( + id: serializer.fromJson(json['id']), + name: serializer.fromJson(json['name']), + description: serializer.fromJson(json['description']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + ownerId: serializer.fromJson(json['ownerId']), + thumbnailAssetId: serializer.fromJson(json['thumbnailAssetId']), + isActivityEnabled: serializer.fromJson(json['isActivityEnabled']), + order: serializer.fromJson(json['order']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'name': serializer.toJson(name), + 'description': serializer.toJson(description), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'ownerId': serializer.toJson(ownerId), + 'thumbnailAssetId': serializer.toJson(thumbnailAssetId), + 'isActivityEnabled': serializer.toJson(isActivityEnabled), + 'order': serializer.toJson(order), + }; + } + + RemoteAlbumEntityData copyWith({ + String? id, + String? name, + String? description, + DateTime? createdAt, + DateTime? updatedAt, + String? ownerId, + Value thumbnailAssetId = const Value.absent(), + bool? isActivityEnabled, + int? order, + }) => RemoteAlbumEntityData( + id: id ?? this.id, + name: name ?? this.name, + description: description ?? this.description, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ownerId: ownerId ?? this.ownerId, + thumbnailAssetId: thumbnailAssetId.present + ? thumbnailAssetId.value + : this.thumbnailAssetId, + isActivityEnabled: isActivityEnabled ?? this.isActivityEnabled, + order: order ?? this.order, + ); + RemoteAlbumEntityData copyWithCompanion(RemoteAlbumEntityCompanion data) { + return RemoteAlbumEntityData( + id: data.id.present ? data.id.value : this.id, + name: data.name.present ? data.name.value : this.name, + description: data.description.present + ? data.description.value + : this.description, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + ownerId: data.ownerId.present ? data.ownerId.value : this.ownerId, + thumbnailAssetId: data.thumbnailAssetId.present + ? data.thumbnailAssetId.value + : this.thumbnailAssetId, + isActivityEnabled: data.isActivityEnabled.present + ? data.isActivityEnabled.value + : this.isActivityEnabled, + order: data.order.present ? data.order.value : this.order, + ); + } + + @override + String toString() { + return (StringBuffer('RemoteAlbumEntityData(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('description: $description, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('ownerId: $ownerId, ') + ..write('thumbnailAssetId: $thumbnailAssetId, ') + ..write('isActivityEnabled: $isActivityEnabled, ') + ..write('order: $order') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + name, + description, + createdAt, + updatedAt, + ownerId, + thumbnailAssetId, + isActivityEnabled, + order, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is RemoteAlbumEntityData && + other.id == this.id && + other.name == this.name && + other.description == this.description && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && + other.ownerId == this.ownerId && + other.thumbnailAssetId == this.thumbnailAssetId && + other.isActivityEnabled == this.isActivityEnabled && + other.order == this.order); +} + +class RemoteAlbumEntityCompanion + extends UpdateCompanion { + final Value id; + final Value name; + final Value description; + final Value createdAt; + final Value updatedAt; + final Value ownerId; + final Value thumbnailAssetId; + final Value isActivityEnabled; + final Value order; + const RemoteAlbumEntityCompanion({ + this.id = const Value.absent(), + this.name = const Value.absent(), + this.description = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.ownerId = const Value.absent(), + this.thumbnailAssetId = const Value.absent(), + this.isActivityEnabled = const Value.absent(), + this.order = const Value.absent(), + }); + RemoteAlbumEntityCompanion.insert({ + required String id, + required String name, + this.description = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + required String ownerId, + this.thumbnailAssetId = const Value.absent(), + this.isActivityEnabled = const Value.absent(), + required int order, + }) : id = Value(id), + name = Value(name), + ownerId = Value(ownerId), + order = Value(order); + static Insertable custom({ + Expression? id, + Expression? name, + Expression? description, + Expression? createdAt, + Expression? updatedAt, + Expression? ownerId, + Expression? thumbnailAssetId, + Expression? isActivityEnabled, + Expression? order, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (name != null) 'name': name, + if (description != null) 'description': description, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, + if (ownerId != null) 'owner_id': ownerId, + if (thumbnailAssetId != null) 'thumbnail_asset_id': thumbnailAssetId, + if (isActivityEnabled != null) 'is_activity_enabled': isActivityEnabled, + if (order != null) 'order': order, + }); + } + + RemoteAlbumEntityCompanion copyWith({ + Value? id, + Value? name, + Value? description, + Value? createdAt, + Value? updatedAt, + Value? ownerId, + Value? thumbnailAssetId, + Value? isActivityEnabled, + Value? order, + }) { + return RemoteAlbumEntityCompanion( + id: id ?? this.id, + name: name ?? this.name, + description: description ?? this.description, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ownerId: ownerId ?? this.ownerId, + thumbnailAssetId: thumbnailAssetId ?? this.thumbnailAssetId, + isActivityEnabled: isActivityEnabled ?? this.isActivityEnabled, + order: order ?? this.order, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (description.present) { + map['description'] = Variable(description.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (ownerId.present) { + map['owner_id'] = Variable(ownerId.value); + } + if (thumbnailAssetId.present) { + map['thumbnail_asset_id'] = Variable(thumbnailAssetId.value); + } + if (isActivityEnabled.present) { + map['is_activity_enabled'] = Variable(isActivityEnabled.value); + } + if (order.present) { + map['order'] = Variable(order.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('RemoteAlbumEntityCompanion(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('description: $description, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('ownerId: $ownerId, ') + ..write('thumbnailAssetId: $thumbnailAssetId, ') + ..write('isActivityEnabled: $isActivityEnabled, ') + ..write('order: $order') + ..write(')')) + .toString(); + } +} + +class LocalAlbumEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + LocalAlbumEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn backupSelection = GeneratedColumn( + 'backup_selection', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn isIosSharedAlbum = GeneratedColumn( + 'is_ios_shared_album', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_ios_shared_album" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn linkedRemoteAlbumId = + GeneratedColumn( + 'linked_remote_album_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_album_entity (id) ON DELETE SET NULL', + ), + ); + late final GeneratedColumn marker_ = GeneratedColumn( + 'marker', + aliasedName, + true, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("marker" IN (0, 1))', + ), + ); + @override + List get $columns => [ + id, + name, + updatedAt, + backupSelection, + isIosSharedAlbum, + linkedRemoteAlbumId, + marker_, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'local_album_entity'; + @override + Set get $primaryKey => {id}; + @override + LocalAlbumEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return LocalAlbumEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}updated_at'], + )!, + backupSelection: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}backup_selection'], + )!, + isIosSharedAlbum: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_ios_shared_album'], + )!, + linkedRemoteAlbumId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}linked_remote_album_id'], + ), + marker_: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}marker'], + ), + ); + } + + @override + LocalAlbumEntity createAlias(String alias) { + return LocalAlbumEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class LocalAlbumEntityData extends DataClass + implements Insertable { + final String id; + final String name; + final DateTime updatedAt; + final int backupSelection; + final bool isIosSharedAlbum; + final String? linkedRemoteAlbumId; + final bool? marker_; + const LocalAlbumEntityData({ + required this.id, + required this.name, + required this.updatedAt, + required this.backupSelection, + required this.isIosSharedAlbum, + this.linkedRemoteAlbumId, + this.marker_, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['name'] = Variable(name); + map['updated_at'] = Variable(updatedAt); + map['backup_selection'] = Variable(backupSelection); + map['is_ios_shared_album'] = Variable(isIosSharedAlbum); + if (!nullToAbsent || linkedRemoteAlbumId != null) { + map['linked_remote_album_id'] = Variable(linkedRemoteAlbumId); + } + if (!nullToAbsent || marker_ != null) { + map['marker'] = Variable(marker_); + } + return map; + } + + factory LocalAlbumEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return LocalAlbumEntityData( + id: serializer.fromJson(json['id']), + name: serializer.fromJson(json['name']), + updatedAt: serializer.fromJson(json['updatedAt']), + backupSelection: serializer.fromJson(json['backupSelection']), + isIosSharedAlbum: serializer.fromJson(json['isIosSharedAlbum']), + linkedRemoteAlbumId: serializer.fromJson( + json['linkedRemoteAlbumId'], + ), + marker_: serializer.fromJson(json['marker_']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'name': serializer.toJson(name), + 'updatedAt': serializer.toJson(updatedAt), + 'backupSelection': serializer.toJson(backupSelection), + 'isIosSharedAlbum': serializer.toJson(isIosSharedAlbum), + 'linkedRemoteAlbumId': serializer.toJson(linkedRemoteAlbumId), + 'marker_': serializer.toJson(marker_), + }; + } + + LocalAlbumEntityData copyWith({ + String? id, + String? name, + DateTime? updatedAt, + int? backupSelection, + bool? isIosSharedAlbum, + Value linkedRemoteAlbumId = const Value.absent(), + Value marker_ = const Value.absent(), + }) => LocalAlbumEntityData( + id: id ?? this.id, + name: name ?? this.name, + updatedAt: updatedAt ?? this.updatedAt, + backupSelection: backupSelection ?? this.backupSelection, + isIosSharedAlbum: isIosSharedAlbum ?? this.isIosSharedAlbum, + linkedRemoteAlbumId: linkedRemoteAlbumId.present + ? linkedRemoteAlbumId.value + : this.linkedRemoteAlbumId, + marker_: marker_.present ? marker_.value : this.marker_, + ); + LocalAlbumEntityData copyWithCompanion(LocalAlbumEntityCompanion data) { + return LocalAlbumEntityData( + id: data.id.present ? data.id.value : this.id, + name: data.name.present ? data.name.value : this.name, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + backupSelection: data.backupSelection.present + ? data.backupSelection.value + : this.backupSelection, + isIosSharedAlbum: data.isIosSharedAlbum.present + ? data.isIosSharedAlbum.value + : this.isIosSharedAlbum, + linkedRemoteAlbumId: data.linkedRemoteAlbumId.present + ? data.linkedRemoteAlbumId.value + : this.linkedRemoteAlbumId, + marker_: data.marker_.present ? data.marker_.value : this.marker_, + ); + } + + @override + String toString() { + return (StringBuffer('LocalAlbumEntityData(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('updatedAt: $updatedAt, ') + ..write('backupSelection: $backupSelection, ') + ..write('isIosSharedAlbum: $isIosSharedAlbum, ') + ..write('linkedRemoteAlbumId: $linkedRemoteAlbumId, ') + ..write('marker_: $marker_') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + name, + updatedAt, + backupSelection, + isIosSharedAlbum, + linkedRemoteAlbumId, + marker_, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is LocalAlbumEntityData && + other.id == this.id && + other.name == this.name && + other.updatedAt == this.updatedAt && + other.backupSelection == this.backupSelection && + other.isIosSharedAlbum == this.isIosSharedAlbum && + other.linkedRemoteAlbumId == this.linkedRemoteAlbumId && + other.marker_ == this.marker_); +} + +class LocalAlbumEntityCompanion extends UpdateCompanion { + final Value id; + final Value name; + final Value updatedAt; + final Value backupSelection; + final Value isIosSharedAlbum; + final Value linkedRemoteAlbumId; + final Value marker_; + const LocalAlbumEntityCompanion({ + this.id = const Value.absent(), + this.name = const Value.absent(), + this.updatedAt = const Value.absent(), + this.backupSelection = const Value.absent(), + this.isIosSharedAlbum = const Value.absent(), + this.linkedRemoteAlbumId = const Value.absent(), + this.marker_ = const Value.absent(), + }); + LocalAlbumEntityCompanion.insert({ + required String id, + required String name, + this.updatedAt = const Value.absent(), + required int backupSelection, + this.isIosSharedAlbum = const Value.absent(), + this.linkedRemoteAlbumId = const Value.absent(), + this.marker_ = const Value.absent(), + }) : id = Value(id), + name = Value(name), + backupSelection = Value(backupSelection); + static Insertable custom({ + Expression? id, + Expression? name, + Expression? updatedAt, + Expression? backupSelection, + Expression? isIosSharedAlbum, + Expression? linkedRemoteAlbumId, + Expression? marker_, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (name != null) 'name': name, + if (updatedAt != null) 'updated_at': updatedAt, + if (backupSelection != null) 'backup_selection': backupSelection, + if (isIosSharedAlbum != null) 'is_ios_shared_album': isIosSharedAlbum, + if (linkedRemoteAlbumId != null) + 'linked_remote_album_id': linkedRemoteAlbumId, + if (marker_ != null) 'marker': marker_, + }); + } + + LocalAlbumEntityCompanion copyWith({ + Value? id, + Value? name, + Value? updatedAt, + Value? backupSelection, + Value? isIosSharedAlbum, + Value? linkedRemoteAlbumId, + Value? marker_, + }) { + return LocalAlbumEntityCompanion( + id: id ?? this.id, + name: name ?? this.name, + updatedAt: updatedAt ?? this.updatedAt, + backupSelection: backupSelection ?? this.backupSelection, + isIosSharedAlbum: isIosSharedAlbum ?? this.isIosSharedAlbum, + linkedRemoteAlbumId: linkedRemoteAlbumId ?? this.linkedRemoteAlbumId, + marker_: marker_ ?? this.marker_, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (backupSelection.present) { + map['backup_selection'] = Variable(backupSelection.value); + } + if (isIosSharedAlbum.present) { + map['is_ios_shared_album'] = Variable(isIosSharedAlbum.value); + } + if (linkedRemoteAlbumId.present) { + map['linked_remote_album_id'] = Variable( + linkedRemoteAlbumId.value, + ); + } + if (marker_.present) { + map['marker'] = Variable(marker_.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('LocalAlbumEntityCompanion(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('updatedAt: $updatedAt, ') + ..write('backupSelection: $backupSelection, ') + ..write('isIosSharedAlbum: $isIosSharedAlbum, ') + ..write('linkedRemoteAlbumId: $linkedRemoteAlbumId, ') + ..write('marker_: $marker_') + ..write(')')) + .toString(); + } +} + +class LocalAlbumAssetEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + LocalAlbumAssetEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn assetId = GeneratedColumn( + 'asset_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES local_asset_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn albumId = GeneratedColumn( + 'album_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES local_album_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn marker_ = GeneratedColumn( + 'marker', + aliasedName, + true, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("marker" IN (0, 1))', + ), + ); + @override + List get $columns => [assetId, albumId, marker_]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'local_album_asset_entity'; + @override + Set get $primaryKey => {assetId, albumId}; + @override + LocalAlbumAssetEntityData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return LocalAlbumAssetEntityData( + assetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}asset_id'], + )!, + albumId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}album_id'], + )!, + marker_: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}marker'], + ), + ); + } + + @override + LocalAlbumAssetEntity createAlias(String alias) { + return LocalAlbumAssetEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class LocalAlbumAssetEntityData extends DataClass + implements Insertable { + final String assetId; + final String albumId; + final bool? marker_; + const LocalAlbumAssetEntityData({ + required this.assetId, + required this.albumId, + this.marker_, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['asset_id'] = Variable(assetId); + map['album_id'] = Variable(albumId); + if (!nullToAbsent || marker_ != null) { + map['marker'] = Variable(marker_); + } + return map; + } + + factory LocalAlbumAssetEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return LocalAlbumAssetEntityData( + assetId: serializer.fromJson(json['assetId']), + albumId: serializer.fromJson(json['albumId']), + marker_: serializer.fromJson(json['marker_']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'assetId': serializer.toJson(assetId), + 'albumId': serializer.toJson(albumId), + 'marker_': serializer.toJson(marker_), + }; + } + + LocalAlbumAssetEntityData copyWith({ + String? assetId, + String? albumId, + Value marker_ = const Value.absent(), + }) => LocalAlbumAssetEntityData( + assetId: assetId ?? this.assetId, + albumId: albumId ?? this.albumId, + marker_: marker_.present ? marker_.value : this.marker_, + ); + LocalAlbumAssetEntityData copyWithCompanion( + LocalAlbumAssetEntityCompanion data, + ) { + return LocalAlbumAssetEntityData( + assetId: data.assetId.present ? data.assetId.value : this.assetId, + albumId: data.albumId.present ? data.albumId.value : this.albumId, + marker_: data.marker_.present ? data.marker_.value : this.marker_, + ); + } + + @override + String toString() { + return (StringBuffer('LocalAlbumAssetEntityData(') + ..write('assetId: $assetId, ') + ..write('albumId: $albumId, ') + ..write('marker_: $marker_') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(assetId, albumId, marker_); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is LocalAlbumAssetEntityData && + other.assetId == this.assetId && + other.albumId == this.albumId && + other.marker_ == this.marker_); +} + +class LocalAlbumAssetEntityCompanion + extends UpdateCompanion { + final Value assetId; + final Value albumId; + final Value marker_; + const LocalAlbumAssetEntityCompanion({ + this.assetId = const Value.absent(), + this.albumId = const Value.absent(), + this.marker_ = const Value.absent(), + }); + LocalAlbumAssetEntityCompanion.insert({ + required String assetId, + required String albumId, + this.marker_ = const Value.absent(), + }) : assetId = Value(assetId), + albumId = Value(albumId); + static Insertable custom({ + Expression? assetId, + Expression? albumId, + Expression? marker_, + }) { + return RawValuesInsertable({ + if (assetId != null) 'asset_id': assetId, + if (albumId != null) 'album_id': albumId, + if (marker_ != null) 'marker': marker_, + }); + } + + LocalAlbumAssetEntityCompanion copyWith({ + Value? assetId, + Value? albumId, + Value? marker_, + }) { + return LocalAlbumAssetEntityCompanion( + assetId: assetId ?? this.assetId, + albumId: albumId ?? this.albumId, + marker_: marker_ ?? this.marker_, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (assetId.present) { + map['asset_id'] = Variable(assetId.value); + } + if (albumId.present) { + map['album_id'] = Variable(albumId.value); + } + if (marker_.present) { + map['marker'] = Variable(marker_.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('LocalAlbumAssetEntityCompanion(') + ..write('assetId: $assetId, ') + ..write('albumId: $albumId, ') + ..write('marker_: $marker_') + ..write(')')) + .toString(); + } +} + +class AuthUserEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + AuthUserEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn email = GeneratedColumn( + 'email', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn isAdmin = GeneratedColumn( + 'is_admin', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_admin" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn hasProfileImage = GeneratedColumn( + 'has_profile_image', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("has_profile_image" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn profileChangedAt = + GeneratedColumn( + 'profile_changed_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn avatarColor = GeneratedColumn( + 'avatar_color', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn quotaSizeInBytes = GeneratedColumn( + 'quota_size_in_bytes', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn quotaUsageInBytes = GeneratedColumn( + 'quota_usage_in_bytes', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: false, + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn pinCode = GeneratedColumn( + 'pin_code', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + @override + List get $columns => [ + id, + name, + email, + isAdmin, + hasProfileImage, + profileChangedAt, + avatarColor, + quotaSizeInBytes, + quotaUsageInBytes, + pinCode, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'auth_user_entity'; + @override + Set get $primaryKey => {id}; + @override + AuthUserEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return AuthUserEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + email: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}email'], + )!, + isAdmin: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_admin'], + )!, + hasProfileImage: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}has_profile_image'], + )!, + profileChangedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}profile_changed_at'], + )!, + avatarColor: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}avatar_color'], + )!, + quotaSizeInBytes: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}quota_size_in_bytes'], + )!, + quotaUsageInBytes: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}quota_usage_in_bytes'], + )!, + pinCode: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}pin_code'], + ), + ); + } + + @override + AuthUserEntity createAlias(String alias) { + return AuthUserEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class AuthUserEntityData extends DataClass + implements Insertable { + final String id; + final String name; + final String email; + final bool isAdmin; + final bool hasProfileImage; + final DateTime profileChangedAt; + final int avatarColor; + final int quotaSizeInBytes; + final int quotaUsageInBytes; + final String? pinCode; + const AuthUserEntityData({ + required this.id, + required this.name, + required this.email, + required this.isAdmin, + required this.hasProfileImage, + required this.profileChangedAt, + required this.avatarColor, + required this.quotaSizeInBytes, + required this.quotaUsageInBytes, + this.pinCode, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['name'] = Variable(name); + map['email'] = Variable(email); + map['is_admin'] = Variable(isAdmin); + map['has_profile_image'] = Variable(hasProfileImage); + map['profile_changed_at'] = Variable(profileChangedAt); + map['avatar_color'] = Variable(avatarColor); + map['quota_size_in_bytes'] = Variable(quotaSizeInBytes); + map['quota_usage_in_bytes'] = Variable(quotaUsageInBytes); + if (!nullToAbsent || pinCode != null) { + map['pin_code'] = Variable(pinCode); + } + return map; + } + + factory AuthUserEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return AuthUserEntityData( + id: serializer.fromJson(json['id']), + name: serializer.fromJson(json['name']), + email: serializer.fromJson(json['email']), + isAdmin: serializer.fromJson(json['isAdmin']), + hasProfileImage: serializer.fromJson(json['hasProfileImage']), + profileChangedAt: serializer.fromJson(json['profileChangedAt']), + avatarColor: serializer.fromJson(json['avatarColor']), + quotaSizeInBytes: serializer.fromJson(json['quotaSizeInBytes']), + quotaUsageInBytes: serializer.fromJson(json['quotaUsageInBytes']), + pinCode: serializer.fromJson(json['pinCode']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'name': serializer.toJson(name), + 'email': serializer.toJson(email), + 'isAdmin': serializer.toJson(isAdmin), + 'hasProfileImage': serializer.toJson(hasProfileImage), + 'profileChangedAt': serializer.toJson(profileChangedAt), + 'avatarColor': serializer.toJson(avatarColor), + 'quotaSizeInBytes': serializer.toJson(quotaSizeInBytes), + 'quotaUsageInBytes': serializer.toJson(quotaUsageInBytes), + 'pinCode': serializer.toJson(pinCode), + }; + } + + AuthUserEntityData copyWith({ + String? id, + String? name, + String? email, + bool? isAdmin, + bool? hasProfileImage, + DateTime? profileChangedAt, + int? avatarColor, + int? quotaSizeInBytes, + int? quotaUsageInBytes, + Value pinCode = const Value.absent(), + }) => AuthUserEntityData( + id: id ?? this.id, + name: name ?? this.name, + email: email ?? this.email, + isAdmin: isAdmin ?? this.isAdmin, + hasProfileImage: hasProfileImage ?? this.hasProfileImage, + profileChangedAt: profileChangedAt ?? this.profileChangedAt, + avatarColor: avatarColor ?? this.avatarColor, + quotaSizeInBytes: quotaSizeInBytes ?? this.quotaSizeInBytes, + quotaUsageInBytes: quotaUsageInBytes ?? this.quotaUsageInBytes, + pinCode: pinCode.present ? pinCode.value : this.pinCode, + ); + AuthUserEntityData copyWithCompanion(AuthUserEntityCompanion data) { + return AuthUserEntityData( + id: data.id.present ? data.id.value : this.id, + name: data.name.present ? data.name.value : this.name, + email: data.email.present ? data.email.value : this.email, + isAdmin: data.isAdmin.present ? data.isAdmin.value : this.isAdmin, + hasProfileImage: data.hasProfileImage.present + ? data.hasProfileImage.value + : this.hasProfileImage, + profileChangedAt: data.profileChangedAt.present + ? data.profileChangedAt.value + : this.profileChangedAt, + avatarColor: data.avatarColor.present + ? data.avatarColor.value + : this.avatarColor, + quotaSizeInBytes: data.quotaSizeInBytes.present + ? data.quotaSizeInBytes.value + : this.quotaSizeInBytes, + quotaUsageInBytes: data.quotaUsageInBytes.present + ? data.quotaUsageInBytes.value + : this.quotaUsageInBytes, + pinCode: data.pinCode.present ? data.pinCode.value : this.pinCode, + ); + } + + @override + String toString() { + return (StringBuffer('AuthUserEntityData(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('email: $email, ') + ..write('isAdmin: $isAdmin, ') + ..write('hasProfileImage: $hasProfileImage, ') + ..write('profileChangedAt: $profileChangedAt, ') + ..write('avatarColor: $avatarColor, ') + ..write('quotaSizeInBytes: $quotaSizeInBytes, ') + ..write('quotaUsageInBytes: $quotaUsageInBytes, ') + ..write('pinCode: $pinCode') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + name, + email, + isAdmin, + hasProfileImage, + profileChangedAt, + avatarColor, + quotaSizeInBytes, + quotaUsageInBytes, + pinCode, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is AuthUserEntityData && + other.id == this.id && + other.name == this.name && + other.email == this.email && + other.isAdmin == this.isAdmin && + other.hasProfileImage == this.hasProfileImage && + other.profileChangedAt == this.profileChangedAt && + other.avatarColor == this.avatarColor && + other.quotaSizeInBytes == this.quotaSizeInBytes && + other.quotaUsageInBytes == this.quotaUsageInBytes && + other.pinCode == this.pinCode); +} + +class AuthUserEntityCompanion extends UpdateCompanion { + final Value id; + final Value name; + final Value email; + final Value isAdmin; + final Value hasProfileImage; + final Value profileChangedAt; + final Value avatarColor; + final Value quotaSizeInBytes; + final Value quotaUsageInBytes; + final Value pinCode; + const AuthUserEntityCompanion({ + this.id = const Value.absent(), + this.name = const Value.absent(), + this.email = const Value.absent(), + this.isAdmin = const Value.absent(), + this.hasProfileImage = const Value.absent(), + this.profileChangedAt = const Value.absent(), + this.avatarColor = const Value.absent(), + this.quotaSizeInBytes = const Value.absent(), + this.quotaUsageInBytes = const Value.absent(), + this.pinCode = const Value.absent(), + }); + AuthUserEntityCompanion.insert({ + required String id, + required String name, + required String email, + this.isAdmin = const Value.absent(), + this.hasProfileImage = const Value.absent(), + this.profileChangedAt = const Value.absent(), + required int avatarColor, + this.quotaSizeInBytes = const Value.absent(), + this.quotaUsageInBytes = const Value.absent(), + this.pinCode = const Value.absent(), + }) : id = Value(id), + name = Value(name), + email = Value(email), + avatarColor = Value(avatarColor); + static Insertable custom({ + Expression? id, + Expression? name, + Expression? email, + Expression? isAdmin, + Expression? hasProfileImage, + Expression? profileChangedAt, + Expression? avatarColor, + Expression? quotaSizeInBytes, + Expression? quotaUsageInBytes, + Expression? pinCode, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (name != null) 'name': name, + if (email != null) 'email': email, + if (isAdmin != null) 'is_admin': isAdmin, + if (hasProfileImage != null) 'has_profile_image': hasProfileImage, + if (profileChangedAt != null) 'profile_changed_at': profileChangedAt, + if (avatarColor != null) 'avatar_color': avatarColor, + if (quotaSizeInBytes != null) 'quota_size_in_bytes': quotaSizeInBytes, + if (quotaUsageInBytes != null) 'quota_usage_in_bytes': quotaUsageInBytes, + if (pinCode != null) 'pin_code': pinCode, + }); + } + + AuthUserEntityCompanion copyWith({ + Value? id, + Value? name, + Value? email, + Value? isAdmin, + Value? hasProfileImage, + Value? profileChangedAt, + Value? avatarColor, + Value? quotaSizeInBytes, + Value? quotaUsageInBytes, + Value? pinCode, + }) { + return AuthUserEntityCompanion( + id: id ?? this.id, + name: name ?? this.name, + email: email ?? this.email, + isAdmin: isAdmin ?? this.isAdmin, + hasProfileImage: hasProfileImage ?? this.hasProfileImage, + profileChangedAt: profileChangedAt ?? this.profileChangedAt, + avatarColor: avatarColor ?? this.avatarColor, + quotaSizeInBytes: quotaSizeInBytes ?? this.quotaSizeInBytes, + quotaUsageInBytes: quotaUsageInBytes ?? this.quotaUsageInBytes, + pinCode: pinCode ?? this.pinCode, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (email.present) { + map['email'] = Variable(email.value); + } + if (isAdmin.present) { + map['is_admin'] = Variable(isAdmin.value); + } + if (hasProfileImage.present) { + map['has_profile_image'] = Variable(hasProfileImage.value); + } + if (profileChangedAt.present) { + map['profile_changed_at'] = Variable(profileChangedAt.value); + } + if (avatarColor.present) { + map['avatar_color'] = Variable(avatarColor.value); + } + if (quotaSizeInBytes.present) { + map['quota_size_in_bytes'] = Variable(quotaSizeInBytes.value); + } + if (quotaUsageInBytes.present) { + map['quota_usage_in_bytes'] = Variable(quotaUsageInBytes.value); + } + if (pinCode.present) { + map['pin_code'] = Variable(pinCode.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('AuthUserEntityCompanion(') + ..write('id: $id, ') + ..write('name: $name, ') + ..write('email: $email, ') + ..write('isAdmin: $isAdmin, ') + ..write('hasProfileImage: $hasProfileImage, ') + ..write('profileChangedAt: $profileChangedAt, ') + ..write('avatarColor: $avatarColor, ') + ..write('quotaSizeInBytes: $quotaSizeInBytes, ') + ..write('quotaUsageInBytes: $quotaUsageInBytes, ') + ..write('pinCode: $pinCode') + ..write(')')) + .toString(); + } +} + +class UserMetadataEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + UserMetadataEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn userId = GeneratedColumn( + 'user_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn key = GeneratedColumn( + 'key', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn value = GeneratedColumn( + 'value', + aliasedName, + false, + type: DriftSqlType.blob, + requiredDuringInsert: true, + ); + @override + List get $columns => [userId, key, value]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'user_metadata_entity'; + @override + Set get $primaryKey => {userId, key}; + @override + UserMetadataEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return UserMetadataEntityData( + userId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}user_id'], + )!, + key: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}key'], + )!, + value: attachedDatabase.typeMapping.read( + DriftSqlType.blob, + data['${effectivePrefix}value'], + )!, + ); + } + + @override + UserMetadataEntity createAlias(String alias) { + return UserMetadataEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class UserMetadataEntityData extends DataClass + implements Insertable { + final String userId; + final int key; + final Uint8List value; + const UserMetadataEntityData({ + required this.userId, + required this.key, + required this.value, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['user_id'] = Variable(userId); + map['key'] = Variable(key); + map['value'] = Variable(value); + return map; + } + + factory UserMetadataEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return UserMetadataEntityData( + userId: serializer.fromJson(json['userId']), + key: serializer.fromJson(json['key']), + value: serializer.fromJson(json['value']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'userId': serializer.toJson(userId), + 'key': serializer.toJson(key), + 'value': serializer.toJson(value), + }; + } + + UserMetadataEntityData copyWith({ + String? userId, + int? key, + Uint8List? value, + }) => UserMetadataEntityData( + userId: userId ?? this.userId, + key: key ?? this.key, + value: value ?? this.value, + ); + UserMetadataEntityData copyWithCompanion(UserMetadataEntityCompanion data) { + return UserMetadataEntityData( + userId: data.userId.present ? data.userId.value : this.userId, + key: data.key.present ? data.key.value : this.key, + value: data.value.present ? data.value.value : this.value, + ); + } + + @override + String toString() { + return (StringBuffer('UserMetadataEntityData(') + ..write('userId: $userId, ') + ..write('key: $key, ') + ..write('value: $value') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(userId, key, $driftBlobEquality.hash(value)); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is UserMetadataEntityData && + other.userId == this.userId && + other.key == this.key && + $driftBlobEquality.equals(other.value, this.value)); +} + +class UserMetadataEntityCompanion + extends UpdateCompanion { + final Value userId; + final Value key; + final Value value; + const UserMetadataEntityCompanion({ + this.userId = const Value.absent(), + this.key = const Value.absent(), + this.value = const Value.absent(), + }); + UserMetadataEntityCompanion.insert({ + required String userId, + required int key, + required Uint8List value, + }) : userId = Value(userId), + key = Value(key), + value = Value(value); + static Insertable custom({ + Expression? userId, + Expression? key, + Expression? value, + }) { + return RawValuesInsertable({ + if (userId != null) 'user_id': userId, + if (key != null) 'key': key, + if (value != null) 'value': value, + }); + } + + UserMetadataEntityCompanion copyWith({ + Value? userId, + Value? key, + Value? value, + }) { + return UserMetadataEntityCompanion( + userId: userId ?? this.userId, + key: key ?? this.key, + value: value ?? this.value, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (userId.present) { + map['user_id'] = Variable(userId.value); + } + if (key.present) { + map['key'] = Variable(key.value); + } + if (value.present) { + map['value'] = Variable(value.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('UserMetadataEntityCompanion(') + ..write('userId: $userId, ') + ..write('key: $key, ') + ..write('value: $value') + ..write(')')) + .toString(); + } +} + +class PartnerEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + PartnerEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn sharedById = GeneratedColumn( + 'shared_by_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn sharedWithId = GeneratedColumn( + 'shared_with_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn inTimeline = GeneratedColumn( + 'in_timeline', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("in_timeline" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + @override + List get $columns => [sharedById, sharedWithId, inTimeline]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'partner_entity'; + @override + Set get $primaryKey => {sharedById, sharedWithId}; + @override + PartnerEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return PartnerEntityData( + sharedById: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}shared_by_id'], + )!, + sharedWithId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}shared_with_id'], + )!, + inTimeline: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}in_timeline'], + )!, + ); + } + + @override + PartnerEntity createAlias(String alias) { + return PartnerEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class PartnerEntityData extends DataClass + implements Insertable { + final String sharedById; + final String sharedWithId; + final bool inTimeline; + const PartnerEntityData({ + required this.sharedById, + required this.sharedWithId, + required this.inTimeline, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['shared_by_id'] = Variable(sharedById); + map['shared_with_id'] = Variable(sharedWithId); + map['in_timeline'] = Variable(inTimeline); + return map; + } + + factory PartnerEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return PartnerEntityData( + sharedById: serializer.fromJson(json['sharedById']), + sharedWithId: serializer.fromJson(json['sharedWithId']), + inTimeline: serializer.fromJson(json['inTimeline']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'sharedById': serializer.toJson(sharedById), + 'sharedWithId': serializer.toJson(sharedWithId), + 'inTimeline': serializer.toJson(inTimeline), + }; + } + + PartnerEntityData copyWith({ + String? sharedById, + String? sharedWithId, + bool? inTimeline, + }) => PartnerEntityData( + sharedById: sharedById ?? this.sharedById, + sharedWithId: sharedWithId ?? this.sharedWithId, + inTimeline: inTimeline ?? this.inTimeline, + ); + PartnerEntityData copyWithCompanion(PartnerEntityCompanion data) { + return PartnerEntityData( + sharedById: data.sharedById.present + ? data.sharedById.value + : this.sharedById, + sharedWithId: data.sharedWithId.present + ? data.sharedWithId.value + : this.sharedWithId, + inTimeline: data.inTimeline.present + ? data.inTimeline.value + : this.inTimeline, + ); + } + + @override + String toString() { + return (StringBuffer('PartnerEntityData(') + ..write('sharedById: $sharedById, ') + ..write('sharedWithId: $sharedWithId, ') + ..write('inTimeline: $inTimeline') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(sharedById, sharedWithId, inTimeline); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is PartnerEntityData && + other.sharedById == this.sharedById && + other.sharedWithId == this.sharedWithId && + other.inTimeline == this.inTimeline); +} + +class PartnerEntityCompanion extends UpdateCompanion { + final Value sharedById; + final Value sharedWithId; + final Value inTimeline; + const PartnerEntityCompanion({ + this.sharedById = const Value.absent(), + this.sharedWithId = const Value.absent(), + this.inTimeline = const Value.absent(), + }); + PartnerEntityCompanion.insert({ + required String sharedById, + required String sharedWithId, + this.inTimeline = const Value.absent(), + }) : sharedById = Value(sharedById), + sharedWithId = Value(sharedWithId); + static Insertable custom({ + Expression? sharedById, + Expression? sharedWithId, + Expression? inTimeline, + }) { + return RawValuesInsertable({ + if (sharedById != null) 'shared_by_id': sharedById, + if (sharedWithId != null) 'shared_with_id': sharedWithId, + if (inTimeline != null) 'in_timeline': inTimeline, + }); + } + + PartnerEntityCompanion copyWith({ + Value? sharedById, + Value? sharedWithId, + Value? inTimeline, + }) { + return PartnerEntityCompanion( + sharedById: sharedById ?? this.sharedById, + sharedWithId: sharedWithId ?? this.sharedWithId, + inTimeline: inTimeline ?? this.inTimeline, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (sharedById.present) { + map['shared_by_id'] = Variable(sharedById.value); + } + if (sharedWithId.present) { + map['shared_with_id'] = Variable(sharedWithId.value); + } + if (inTimeline.present) { + map['in_timeline'] = Variable(inTimeline.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('PartnerEntityCompanion(') + ..write('sharedById: $sharedById, ') + ..write('sharedWithId: $sharedWithId, ') + ..write('inTimeline: $inTimeline') + ..write(')')) + .toString(); + } +} + +class RemoteExifEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + RemoteExifEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn assetId = GeneratedColumn( + 'asset_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_asset_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn city = GeneratedColumn( + 'city', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn state = GeneratedColumn( + 'state', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn country = GeneratedColumn( + 'country', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn dateTimeOriginal = + GeneratedColumn( + 'date_time_original', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + late final GeneratedColumn description = GeneratedColumn( + 'description', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn height = GeneratedColumn( + 'height', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn width = GeneratedColumn( + 'width', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn exposureTime = GeneratedColumn( + 'exposure_time', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn fNumber = GeneratedColumn( + 'f_number', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + ); + late final GeneratedColumn fileSize = GeneratedColumn( + 'file_size', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn focalLength = GeneratedColumn( + 'focal_length', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + ); + late final GeneratedColumn latitude = GeneratedColumn( + 'latitude', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + ); + late final GeneratedColumn longitude = GeneratedColumn( + 'longitude', + aliasedName, + true, + type: DriftSqlType.double, + requiredDuringInsert: false, + ); + late final GeneratedColumn iso = GeneratedColumn( + 'iso', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn make = GeneratedColumn( + 'make', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn model = GeneratedColumn( + 'model', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn lens = GeneratedColumn( + 'lens', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn orientation = GeneratedColumn( + 'orientation', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn timeZone = GeneratedColumn( + 'time_zone', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn rating = GeneratedColumn( + 'rating', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + late final GeneratedColumn projectionType = GeneratedColumn( + 'projection_type', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + @override + List get $columns => [ + assetId, + city, + state, + country, + dateTimeOriginal, + description, + height, + width, + exposureTime, + fNumber, + fileSize, + focalLength, + latitude, + longitude, + iso, + make, + model, + lens, + orientation, + timeZone, + rating, + projectionType, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'remote_exif_entity'; + @override + Set get $primaryKey => {assetId}; + @override + RemoteExifEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return RemoteExifEntityData( + assetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}asset_id'], + )!, + city: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}city'], + ), + state: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}state'], + ), + country: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}country'], + ), + dateTimeOriginal: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}date_time_original'], + ), + description: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}description'], + ), + height: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}height'], + ), + width: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}width'], + ), + exposureTime: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}exposure_time'], + ), + fNumber: attachedDatabase.typeMapping.read( + DriftSqlType.double, + data['${effectivePrefix}f_number'], + ), + fileSize: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}file_size'], + ), + focalLength: attachedDatabase.typeMapping.read( + DriftSqlType.double, + data['${effectivePrefix}focal_length'], + ), + latitude: attachedDatabase.typeMapping.read( + DriftSqlType.double, + data['${effectivePrefix}latitude'], + ), + longitude: attachedDatabase.typeMapping.read( + DriftSqlType.double, + data['${effectivePrefix}longitude'], + ), + iso: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}iso'], + ), + make: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}make'], + ), + model: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}model'], + ), + lens: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}lens'], + ), + orientation: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}orientation'], + ), + timeZone: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}time_zone'], + ), + rating: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}rating'], + ), + projectionType: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}projection_type'], + ), + ); + } + + @override + RemoteExifEntity createAlias(String alias) { + return RemoteExifEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class RemoteExifEntityData extends DataClass + implements Insertable { + final String assetId; + final String? city; + final String? state; + final String? country; + final DateTime? dateTimeOriginal; + final String? description; + final int? height; + final int? width; + final String? exposureTime; + final double? fNumber; + final int? fileSize; + final double? focalLength; + final double? latitude; + final double? longitude; + final int? iso; + final String? make; + final String? model; + final String? lens; + final String? orientation; + final String? timeZone; + final int? rating; + final String? projectionType; + const RemoteExifEntityData({ + required this.assetId, + this.city, + this.state, + this.country, + this.dateTimeOriginal, + this.description, + this.height, + this.width, + this.exposureTime, + this.fNumber, + this.fileSize, + this.focalLength, + this.latitude, + this.longitude, + this.iso, + this.make, + this.model, + this.lens, + this.orientation, + this.timeZone, + this.rating, + this.projectionType, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['asset_id'] = Variable(assetId); + if (!nullToAbsent || city != null) { + map['city'] = Variable(city); + } + if (!nullToAbsent || state != null) { + map['state'] = Variable(state); + } + if (!nullToAbsent || country != null) { + map['country'] = Variable(country); + } + if (!nullToAbsent || dateTimeOriginal != null) { + map['date_time_original'] = Variable(dateTimeOriginal); + } + if (!nullToAbsent || description != null) { + map['description'] = Variable(description); + } + if (!nullToAbsent || height != null) { + map['height'] = Variable(height); + } + if (!nullToAbsent || width != null) { + map['width'] = Variable(width); + } + if (!nullToAbsent || exposureTime != null) { + map['exposure_time'] = Variable(exposureTime); + } + if (!nullToAbsent || fNumber != null) { + map['f_number'] = Variable(fNumber); + } + if (!nullToAbsent || fileSize != null) { + map['file_size'] = Variable(fileSize); + } + if (!nullToAbsent || focalLength != null) { + map['focal_length'] = Variable(focalLength); + } + if (!nullToAbsent || latitude != null) { + map['latitude'] = Variable(latitude); + } + if (!nullToAbsent || longitude != null) { + map['longitude'] = Variable(longitude); + } + if (!nullToAbsent || iso != null) { + map['iso'] = Variable(iso); + } + if (!nullToAbsent || make != null) { + map['make'] = Variable(make); + } + if (!nullToAbsent || model != null) { + map['model'] = Variable(model); + } + if (!nullToAbsent || lens != null) { + map['lens'] = Variable(lens); + } + if (!nullToAbsent || orientation != null) { + map['orientation'] = Variable(orientation); + } + if (!nullToAbsent || timeZone != null) { + map['time_zone'] = Variable(timeZone); + } + if (!nullToAbsent || rating != null) { + map['rating'] = Variable(rating); + } + if (!nullToAbsent || projectionType != null) { + map['projection_type'] = Variable(projectionType); + } + return map; + } + + factory RemoteExifEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return RemoteExifEntityData( + assetId: serializer.fromJson(json['assetId']), + city: serializer.fromJson(json['city']), + state: serializer.fromJson(json['state']), + country: serializer.fromJson(json['country']), + dateTimeOriginal: serializer.fromJson( + json['dateTimeOriginal'], + ), + description: serializer.fromJson(json['description']), + height: serializer.fromJson(json['height']), + width: serializer.fromJson(json['width']), + exposureTime: serializer.fromJson(json['exposureTime']), + fNumber: serializer.fromJson(json['fNumber']), + fileSize: serializer.fromJson(json['fileSize']), + focalLength: serializer.fromJson(json['focalLength']), + latitude: serializer.fromJson(json['latitude']), + longitude: serializer.fromJson(json['longitude']), + iso: serializer.fromJson(json['iso']), + make: serializer.fromJson(json['make']), + model: serializer.fromJson(json['model']), + lens: serializer.fromJson(json['lens']), + orientation: serializer.fromJson(json['orientation']), + timeZone: serializer.fromJson(json['timeZone']), + rating: serializer.fromJson(json['rating']), + projectionType: serializer.fromJson(json['projectionType']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'assetId': serializer.toJson(assetId), + 'city': serializer.toJson(city), + 'state': serializer.toJson(state), + 'country': serializer.toJson(country), + 'dateTimeOriginal': serializer.toJson(dateTimeOriginal), + 'description': serializer.toJson(description), + 'height': serializer.toJson(height), + 'width': serializer.toJson(width), + 'exposureTime': serializer.toJson(exposureTime), + 'fNumber': serializer.toJson(fNumber), + 'fileSize': serializer.toJson(fileSize), + 'focalLength': serializer.toJson(focalLength), + 'latitude': serializer.toJson(latitude), + 'longitude': serializer.toJson(longitude), + 'iso': serializer.toJson(iso), + 'make': serializer.toJson(make), + 'model': serializer.toJson(model), + 'lens': serializer.toJson(lens), + 'orientation': serializer.toJson(orientation), + 'timeZone': serializer.toJson(timeZone), + 'rating': serializer.toJson(rating), + 'projectionType': serializer.toJson(projectionType), + }; + } + + RemoteExifEntityData copyWith({ + String? assetId, + Value city = const Value.absent(), + Value state = const Value.absent(), + Value country = const Value.absent(), + Value dateTimeOriginal = const Value.absent(), + Value description = const Value.absent(), + Value height = const Value.absent(), + Value width = const Value.absent(), + Value exposureTime = const Value.absent(), + Value fNumber = const Value.absent(), + Value fileSize = const Value.absent(), + Value focalLength = const Value.absent(), + Value latitude = const Value.absent(), + Value longitude = const Value.absent(), + Value iso = const Value.absent(), + Value make = const Value.absent(), + Value model = const Value.absent(), + Value lens = const Value.absent(), + Value orientation = const Value.absent(), + Value timeZone = const Value.absent(), + Value rating = const Value.absent(), + Value projectionType = const Value.absent(), + }) => RemoteExifEntityData( + assetId: assetId ?? this.assetId, + city: city.present ? city.value : this.city, + state: state.present ? state.value : this.state, + country: country.present ? country.value : this.country, + dateTimeOriginal: dateTimeOriginal.present + ? dateTimeOriginal.value + : this.dateTimeOriginal, + description: description.present ? description.value : this.description, + height: height.present ? height.value : this.height, + width: width.present ? width.value : this.width, + exposureTime: exposureTime.present ? exposureTime.value : this.exposureTime, + fNumber: fNumber.present ? fNumber.value : this.fNumber, + fileSize: fileSize.present ? fileSize.value : this.fileSize, + focalLength: focalLength.present ? focalLength.value : this.focalLength, + latitude: latitude.present ? latitude.value : this.latitude, + longitude: longitude.present ? longitude.value : this.longitude, + iso: iso.present ? iso.value : this.iso, + make: make.present ? make.value : this.make, + model: model.present ? model.value : this.model, + lens: lens.present ? lens.value : this.lens, + orientation: orientation.present ? orientation.value : this.orientation, + timeZone: timeZone.present ? timeZone.value : this.timeZone, + rating: rating.present ? rating.value : this.rating, + projectionType: projectionType.present + ? projectionType.value + : this.projectionType, + ); + RemoteExifEntityData copyWithCompanion(RemoteExifEntityCompanion data) { + return RemoteExifEntityData( + assetId: data.assetId.present ? data.assetId.value : this.assetId, + city: data.city.present ? data.city.value : this.city, + state: data.state.present ? data.state.value : this.state, + country: data.country.present ? data.country.value : this.country, + dateTimeOriginal: data.dateTimeOriginal.present + ? data.dateTimeOriginal.value + : this.dateTimeOriginal, + description: data.description.present + ? data.description.value + : this.description, + height: data.height.present ? data.height.value : this.height, + width: data.width.present ? data.width.value : this.width, + exposureTime: data.exposureTime.present + ? data.exposureTime.value + : this.exposureTime, + fNumber: data.fNumber.present ? data.fNumber.value : this.fNumber, + fileSize: data.fileSize.present ? data.fileSize.value : this.fileSize, + focalLength: data.focalLength.present + ? data.focalLength.value + : this.focalLength, + latitude: data.latitude.present ? data.latitude.value : this.latitude, + longitude: data.longitude.present ? data.longitude.value : this.longitude, + iso: data.iso.present ? data.iso.value : this.iso, + make: data.make.present ? data.make.value : this.make, + model: data.model.present ? data.model.value : this.model, + lens: data.lens.present ? data.lens.value : this.lens, + orientation: data.orientation.present + ? data.orientation.value + : this.orientation, + timeZone: data.timeZone.present ? data.timeZone.value : this.timeZone, + rating: data.rating.present ? data.rating.value : this.rating, + projectionType: data.projectionType.present + ? data.projectionType.value + : this.projectionType, + ); + } + + @override + String toString() { + return (StringBuffer('RemoteExifEntityData(') + ..write('assetId: $assetId, ') + ..write('city: $city, ') + ..write('state: $state, ') + ..write('country: $country, ') + ..write('dateTimeOriginal: $dateTimeOriginal, ') + ..write('description: $description, ') + ..write('height: $height, ') + ..write('width: $width, ') + ..write('exposureTime: $exposureTime, ') + ..write('fNumber: $fNumber, ') + ..write('fileSize: $fileSize, ') + ..write('focalLength: $focalLength, ') + ..write('latitude: $latitude, ') + ..write('longitude: $longitude, ') + ..write('iso: $iso, ') + ..write('make: $make, ') + ..write('model: $model, ') + ..write('lens: $lens, ') + ..write('orientation: $orientation, ') + ..write('timeZone: $timeZone, ') + ..write('rating: $rating, ') + ..write('projectionType: $projectionType') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hashAll([ + assetId, + city, + state, + country, + dateTimeOriginal, + description, + height, + width, + exposureTime, + fNumber, + fileSize, + focalLength, + latitude, + longitude, + iso, + make, + model, + lens, + orientation, + timeZone, + rating, + projectionType, + ]); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is RemoteExifEntityData && + other.assetId == this.assetId && + other.city == this.city && + other.state == this.state && + other.country == this.country && + other.dateTimeOriginal == this.dateTimeOriginal && + other.description == this.description && + other.height == this.height && + other.width == this.width && + other.exposureTime == this.exposureTime && + other.fNumber == this.fNumber && + other.fileSize == this.fileSize && + other.focalLength == this.focalLength && + other.latitude == this.latitude && + other.longitude == this.longitude && + other.iso == this.iso && + other.make == this.make && + other.model == this.model && + other.lens == this.lens && + other.orientation == this.orientation && + other.timeZone == this.timeZone && + other.rating == this.rating && + other.projectionType == this.projectionType); +} + +class RemoteExifEntityCompanion extends UpdateCompanion { + final Value assetId; + final Value city; + final Value state; + final Value country; + final Value dateTimeOriginal; + final Value description; + final Value height; + final Value width; + final Value exposureTime; + final Value fNumber; + final Value fileSize; + final Value focalLength; + final Value latitude; + final Value longitude; + final Value iso; + final Value make; + final Value model; + final Value lens; + final Value orientation; + final Value timeZone; + final Value rating; + final Value projectionType; + const RemoteExifEntityCompanion({ + this.assetId = const Value.absent(), + this.city = const Value.absent(), + this.state = const Value.absent(), + this.country = const Value.absent(), + this.dateTimeOriginal = const Value.absent(), + this.description = const Value.absent(), + this.height = const Value.absent(), + this.width = const Value.absent(), + this.exposureTime = const Value.absent(), + this.fNumber = const Value.absent(), + this.fileSize = const Value.absent(), + this.focalLength = const Value.absent(), + this.latitude = const Value.absent(), + this.longitude = const Value.absent(), + this.iso = const Value.absent(), + this.make = const Value.absent(), + this.model = const Value.absent(), + this.lens = const Value.absent(), + this.orientation = const Value.absent(), + this.timeZone = const Value.absent(), + this.rating = const Value.absent(), + this.projectionType = const Value.absent(), + }); + RemoteExifEntityCompanion.insert({ + required String assetId, + this.city = const Value.absent(), + this.state = const Value.absent(), + this.country = const Value.absent(), + this.dateTimeOriginal = const Value.absent(), + this.description = const Value.absent(), + this.height = const Value.absent(), + this.width = const Value.absent(), + this.exposureTime = const Value.absent(), + this.fNumber = const Value.absent(), + this.fileSize = const Value.absent(), + this.focalLength = const Value.absent(), + this.latitude = const Value.absent(), + this.longitude = const Value.absent(), + this.iso = const Value.absent(), + this.make = const Value.absent(), + this.model = const Value.absent(), + this.lens = const Value.absent(), + this.orientation = const Value.absent(), + this.timeZone = const Value.absent(), + this.rating = const Value.absent(), + this.projectionType = const Value.absent(), + }) : assetId = Value(assetId); + static Insertable custom({ + Expression? assetId, + Expression? city, + Expression? state, + Expression? country, + Expression? dateTimeOriginal, + Expression? description, + Expression? height, + Expression? width, + Expression? exposureTime, + Expression? fNumber, + Expression? fileSize, + Expression? focalLength, + Expression? latitude, + Expression? longitude, + Expression? iso, + Expression? make, + Expression? model, + Expression? lens, + Expression? orientation, + Expression? timeZone, + Expression? rating, + Expression? projectionType, + }) { + return RawValuesInsertable({ + if (assetId != null) 'asset_id': assetId, + if (city != null) 'city': city, + if (state != null) 'state': state, + if (country != null) 'country': country, + if (dateTimeOriginal != null) 'date_time_original': dateTimeOriginal, + if (description != null) 'description': description, + if (height != null) 'height': height, + if (width != null) 'width': width, + if (exposureTime != null) 'exposure_time': exposureTime, + if (fNumber != null) 'f_number': fNumber, + if (fileSize != null) 'file_size': fileSize, + if (focalLength != null) 'focal_length': focalLength, + if (latitude != null) 'latitude': latitude, + if (longitude != null) 'longitude': longitude, + if (iso != null) 'iso': iso, + if (make != null) 'make': make, + if (model != null) 'model': model, + if (lens != null) 'lens': lens, + if (orientation != null) 'orientation': orientation, + if (timeZone != null) 'time_zone': timeZone, + if (rating != null) 'rating': rating, + if (projectionType != null) 'projection_type': projectionType, + }); + } + + RemoteExifEntityCompanion copyWith({ + Value? assetId, + Value? city, + Value? state, + Value? country, + Value? dateTimeOriginal, + Value? description, + Value? height, + Value? width, + Value? exposureTime, + Value? fNumber, + Value? fileSize, + Value? focalLength, + Value? latitude, + Value? longitude, + Value? iso, + Value? make, + Value? model, + Value? lens, + Value? orientation, + Value? timeZone, + Value? rating, + Value? projectionType, + }) { + return RemoteExifEntityCompanion( + assetId: assetId ?? this.assetId, + city: city ?? this.city, + state: state ?? this.state, + country: country ?? this.country, + dateTimeOriginal: dateTimeOriginal ?? this.dateTimeOriginal, + description: description ?? this.description, + height: height ?? this.height, + width: width ?? this.width, + exposureTime: exposureTime ?? this.exposureTime, + fNumber: fNumber ?? this.fNumber, + fileSize: fileSize ?? this.fileSize, + focalLength: focalLength ?? this.focalLength, + latitude: latitude ?? this.latitude, + longitude: longitude ?? this.longitude, + iso: iso ?? this.iso, + make: make ?? this.make, + model: model ?? this.model, + lens: lens ?? this.lens, + orientation: orientation ?? this.orientation, + timeZone: timeZone ?? this.timeZone, + rating: rating ?? this.rating, + projectionType: projectionType ?? this.projectionType, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (assetId.present) { + map['asset_id'] = Variable(assetId.value); + } + if (city.present) { + map['city'] = Variable(city.value); + } + if (state.present) { + map['state'] = Variable(state.value); + } + if (country.present) { + map['country'] = Variable(country.value); + } + if (dateTimeOriginal.present) { + map['date_time_original'] = Variable(dateTimeOriginal.value); + } + if (description.present) { + map['description'] = Variable(description.value); + } + if (height.present) { + map['height'] = Variable(height.value); + } + if (width.present) { + map['width'] = Variable(width.value); + } + if (exposureTime.present) { + map['exposure_time'] = Variable(exposureTime.value); + } + if (fNumber.present) { + map['f_number'] = Variable(fNumber.value); + } + if (fileSize.present) { + map['file_size'] = Variable(fileSize.value); + } + if (focalLength.present) { + map['focal_length'] = Variable(focalLength.value); + } + if (latitude.present) { + map['latitude'] = Variable(latitude.value); + } + if (longitude.present) { + map['longitude'] = Variable(longitude.value); + } + if (iso.present) { + map['iso'] = Variable(iso.value); + } + if (make.present) { + map['make'] = Variable(make.value); + } + if (model.present) { + map['model'] = Variable(model.value); + } + if (lens.present) { + map['lens'] = Variable(lens.value); + } + if (orientation.present) { + map['orientation'] = Variable(orientation.value); + } + if (timeZone.present) { + map['time_zone'] = Variable(timeZone.value); + } + if (rating.present) { + map['rating'] = Variable(rating.value); + } + if (projectionType.present) { + map['projection_type'] = Variable(projectionType.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('RemoteExifEntityCompanion(') + ..write('assetId: $assetId, ') + ..write('city: $city, ') + ..write('state: $state, ') + ..write('country: $country, ') + ..write('dateTimeOriginal: $dateTimeOriginal, ') + ..write('description: $description, ') + ..write('height: $height, ') + ..write('width: $width, ') + ..write('exposureTime: $exposureTime, ') + ..write('fNumber: $fNumber, ') + ..write('fileSize: $fileSize, ') + ..write('focalLength: $focalLength, ') + ..write('latitude: $latitude, ') + ..write('longitude: $longitude, ') + ..write('iso: $iso, ') + ..write('make: $make, ') + ..write('model: $model, ') + ..write('lens: $lens, ') + ..write('orientation: $orientation, ') + ..write('timeZone: $timeZone, ') + ..write('rating: $rating, ') + ..write('projectionType: $projectionType') + ..write(')')) + .toString(); + } +} + +class RemoteAlbumAssetEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + RemoteAlbumAssetEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn assetId = GeneratedColumn( + 'asset_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_asset_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn albumId = GeneratedColumn( + 'album_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_album_entity (id) ON DELETE CASCADE', + ), + ); + @override + List get $columns => [assetId, albumId]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'remote_album_asset_entity'; + @override + Set get $primaryKey => {assetId, albumId}; + @override + RemoteAlbumAssetEntityData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return RemoteAlbumAssetEntityData( + assetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}asset_id'], + )!, + albumId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}album_id'], + )!, + ); + } + + @override + RemoteAlbumAssetEntity createAlias(String alias) { + return RemoteAlbumAssetEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class RemoteAlbumAssetEntityData extends DataClass + implements Insertable { + final String assetId; + final String albumId; + const RemoteAlbumAssetEntityData({ + required this.assetId, + required this.albumId, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['asset_id'] = Variable(assetId); + map['album_id'] = Variable(albumId); + return map; + } + + factory RemoteAlbumAssetEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return RemoteAlbumAssetEntityData( + assetId: serializer.fromJson(json['assetId']), + albumId: serializer.fromJson(json['albumId']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'assetId': serializer.toJson(assetId), + 'albumId': serializer.toJson(albumId), + }; + } + + RemoteAlbumAssetEntityData copyWith({String? assetId, String? albumId}) => + RemoteAlbumAssetEntityData( + assetId: assetId ?? this.assetId, + albumId: albumId ?? this.albumId, + ); + RemoteAlbumAssetEntityData copyWithCompanion( + RemoteAlbumAssetEntityCompanion data, + ) { + return RemoteAlbumAssetEntityData( + assetId: data.assetId.present ? data.assetId.value : this.assetId, + albumId: data.albumId.present ? data.albumId.value : this.albumId, + ); + } + + @override + String toString() { + return (StringBuffer('RemoteAlbumAssetEntityData(') + ..write('assetId: $assetId, ') + ..write('albumId: $albumId') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(assetId, albumId); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is RemoteAlbumAssetEntityData && + other.assetId == this.assetId && + other.albumId == this.albumId); +} + +class RemoteAlbumAssetEntityCompanion + extends UpdateCompanion { + final Value assetId; + final Value albumId; + const RemoteAlbumAssetEntityCompanion({ + this.assetId = const Value.absent(), + this.albumId = const Value.absent(), + }); + RemoteAlbumAssetEntityCompanion.insert({ + required String assetId, + required String albumId, + }) : assetId = Value(assetId), + albumId = Value(albumId); + static Insertable custom({ + Expression? assetId, + Expression? albumId, + }) { + return RawValuesInsertable({ + if (assetId != null) 'asset_id': assetId, + if (albumId != null) 'album_id': albumId, + }); + } + + RemoteAlbumAssetEntityCompanion copyWith({ + Value? assetId, + Value? albumId, + }) { + return RemoteAlbumAssetEntityCompanion( + assetId: assetId ?? this.assetId, + albumId: albumId ?? this.albumId, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (assetId.present) { + map['asset_id'] = Variable(assetId.value); + } + if (albumId.present) { + map['album_id'] = Variable(albumId.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('RemoteAlbumAssetEntityCompanion(') + ..write('assetId: $assetId, ') + ..write('albumId: $albumId') + ..write(')')) + .toString(); + } +} + +class RemoteAlbumUserEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + RemoteAlbumUserEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn albumId = GeneratedColumn( + 'album_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_album_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn userId = GeneratedColumn( + 'user_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn role = GeneratedColumn( + 'role', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + @override + List get $columns => [albumId, userId, role]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'remote_album_user_entity'; + @override + Set get $primaryKey => {albumId, userId}; + @override + RemoteAlbumUserEntityData map( + Map data, { + String? tablePrefix, + }) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return RemoteAlbumUserEntityData( + albumId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}album_id'], + )!, + userId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}user_id'], + )!, + role: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}role'], + )!, + ); + } + + @override + RemoteAlbumUserEntity createAlias(String alias) { + return RemoteAlbumUserEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class RemoteAlbumUserEntityData extends DataClass + implements Insertable { + final String albumId; + final String userId; + final int role; + const RemoteAlbumUserEntityData({ + required this.albumId, + required this.userId, + required this.role, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['album_id'] = Variable(albumId); + map['user_id'] = Variable(userId); + map['role'] = Variable(role); + return map; + } + + factory RemoteAlbumUserEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return RemoteAlbumUserEntityData( + albumId: serializer.fromJson(json['albumId']), + userId: serializer.fromJson(json['userId']), + role: serializer.fromJson(json['role']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'albumId': serializer.toJson(albumId), + 'userId': serializer.toJson(userId), + 'role': serializer.toJson(role), + }; + } + + RemoteAlbumUserEntityData copyWith({ + String? albumId, + String? userId, + int? role, + }) => RemoteAlbumUserEntityData( + albumId: albumId ?? this.albumId, + userId: userId ?? this.userId, + role: role ?? this.role, + ); + RemoteAlbumUserEntityData copyWithCompanion( + RemoteAlbumUserEntityCompanion data, + ) { + return RemoteAlbumUserEntityData( + albumId: data.albumId.present ? data.albumId.value : this.albumId, + userId: data.userId.present ? data.userId.value : this.userId, + role: data.role.present ? data.role.value : this.role, + ); + } + + @override + String toString() { + return (StringBuffer('RemoteAlbumUserEntityData(') + ..write('albumId: $albumId, ') + ..write('userId: $userId, ') + ..write('role: $role') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(albumId, userId, role); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is RemoteAlbumUserEntityData && + other.albumId == this.albumId && + other.userId == this.userId && + other.role == this.role); +} + +class RemoteAlbumUserEntityCompanion + extends UpdateCompanion { + final Value albumId; + final Value userId; + final Value role; + const RemoteAlbumUserEntityCompanion({ + this.albumId = const Value.absent(), + this.userId = const Value.absent(), + this.role = const Value.absent(), + }); + RemoteAlbumUserEntityCompanion.insert({ + required String albumId, + required String userId, + required int role, + }) : albumId = Value(albumId), + userId = Value(userId), + role = Value(role); + static Insertable custom({ + Expression? albumId, + Expression? userId, + Expression? role, + }) { + return RawValuesInsertable({ + if (albumId != null) 'album_id': albumId, + if (userId != null) 'user_id': userId, + if (role != null) 'role': role, + }); + } + + RemoteAlbumUserEntityCompanion copyWith({ + Value? albumId, + Value? userId, + Value? role, + }) { + return RemoteAlbumUserEntityCompanion( + albumId: albumId ?? this.albumId, + userId: userId ?? this.userId, + role: role ?? this.role, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (albumId.present) { + map['album_id'] = Variable(albumId.value); + } + if (userId.present) { + map['user_id'] = Variable(userId.value); + } + if (role.present) { + map['role'] = Variable(role.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('RemoteAlbumUserEntityCompanion(') + ..write('albumId: $albumId, ') + ..write('userId: $userId, ') + ..write('role: $role') + ..write(')')) + .toString(); + } +} + +class MemoryEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + MemoryEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn deletedAt = GeneratedColumn( + 'deleted_at', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + late final GeneratedColumn ownerId = GeneratedColumn( + 'owner_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn type = GeneratedColumn( + 'type', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn data = GeneratedColumn( + 'data', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn isSaved = GeneratedColumn( + 'is_saved', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_saved" IN (0, 1))', + ), + defaultValue: const CustomExpression('0'), + ); + late final GeneratedColumn memoryAt = GeneratedColumn( + 'memory_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: true, + ); + late final GeneratedColumn seenAt = GeneratedColumn( + 'seen_at', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + late final GeneratedColumn showAt = GeneratedColumn( + 'show_at', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + late final GeneratedColumn hideAt = GeneratedColumn( + 'hide_at', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + @override + List get $columns => [ + id, + createdAt, + updatedAt, + deletedAt, + ownerId, + type, + data, + isSaved, + memoryAt, + seenAt, + showAt, + hideAt, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'memory_entity'; + @override + Set get $primaryKey => {id}; + @override + MemoryEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return MemoryEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}updated_at'], + )!, + deletedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}deleted_at'], + ), + ownerId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}owner_id'], + )!, + type: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}type'], + )!, + data: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}data'], + )!, + isSaved: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_saved'], + )!, + memoryAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}memory_at'], + )!, + seenAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}seen_at'], + ), + showAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}show_at'], + ), + hideAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}hide_at'], + ), + ); + } + + @override + MemoryEntity createAlias(String alias) { + return MemoryEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class MemoryEntityData extends DataClass + implements Insertable { + final String id; + final DateTime createdAt; + final DateTime updatedAt; + final DateTime? deletedAt; + final String ownerId; + final int type; + final String data; + final bool isSaved; + final DateTime memoryAt; + final DateTime? seenAt; + final DateTime? showAt; + final DateTime? hideAt; + const MemoryEntityData({ + required this.id, + required this.createdAt, + required this.updatedAt, + this.deletedAt, + required this.ownerId, + required this.type, + required this.data, + required this.isSaved, + required this.memoryAt, + this.seenAt, + this.showAt, + this.hideAt, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); + if (!nullToAbsent || deletedAt != null) { + map['deleted_at'] = Variable(deletedAt); + } + map['owner_id'] = Variable(ownerId); + map['type'] = Variable(type); + map['data'] = Variable(data); + map['is_saved'] = Variable(isSaved); + map['memory_at'] = Variable(memoryAt); + if (!nullToAbsent || seenAt != null) { + map['seen_at'] = Variable(seenAt); + } + if (!nullToAbsent || showAt != null) { + map['show_at'] = Variable(showAt); + } + if (!nullToAbsent || hideAt != null) { + map['hide_at'] = Variable(hideAt); + } + return map; + } + + factory MemoryEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return MemoryEntityData( + id: serializer.fromJson(json['id']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + deletedAt: serializer.fromJson(json['deletedAt']), + ownerId: serializer.fromJson(json['ownerId']), + type: serializer.fromJson(json['type']), + data: serializer.fromJson(json['data']), + isSaved: serializer.fromJson(json['isSaved']), + memoryAt: serializer.fromJson(json['memoryAt']), + seenAt: serializer.fromJson(json['seenAt']), + showAt: serializer.fromJson(json['showAt']), + hideAt: serializer.fromJson(json['hideAt']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'deletedAt': serializer.toJson(deletedAt), + 'ownerId': serializer.toJson(ownerId), + 'type': serializer.toJson(type), + 'data': serializer.toJson(data), + 'isSaved': serializer.toJson(isSaved), + 'memoryAt': serializer.toJson(memoryAt), + 'seenAt': serializer.toJson(seenAt), + 'showAt': serializer.toJson(showAt), + 'hideAt': serializer.toJson(hideAt), + }; + } + + MemoryEntityData copyWith({ + String? id, + DateTime? createdAt, + DateTime? updatedAt, + Value deletedAt = const Value.absent(), + String? ownerId, + int? type, + String? data, + bool? isSaved, + DateTime? memoryAt, + Value seenAt = const Value.absent(), + Value showAt = const Value.absent(), + Value hideAt = const Value.absent(), + }) => MemoryEntityData( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + deletedAt: deletedAt.present ? deletedAt.value : this.deletedAt, + ownerId: ownerId ?? this.ownerId, + type: type ?? this.type, + data: data ?? this.data, + isSaved: isSaved ?? this.isSaved, + memoryAt: memoryAt ?? this.memoryAt, + seenAt: seenAt.present ? seenAt.value : this.seenAt, + showAt: showAt.present ? showAt.value : this.showAt, + hideAt: hideAt.present ? hideAt.value : this.hideAt, + ); + MemoryEntityData copyWithCompanion(MemoryEntityCompanion data) { + return MemoryEntityData( + id: data.id.present ? data.id.value : this.id, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + deletedAt: data.deletedAt.present ? data.deletedAt.value : this.deletedAt, + ownerId: data.ownerId.present ? data.ownerId.value : this.ownerId, + type: data.type.present ? data.type.value : this.type, + data: data.data.present ? data.data.value : this.data, + isSaved: data.isSaved.present ? data.isSaved.value : this.isSaved, + memoryAt: data.memoryAt.present ? data.memoryAt.value : this.memoryAt, + seenAt: data.seenAt.present ? data.seenAt.value : this.seenAt, + showAt: data.showAt.present ? data.showAt.value : this.showAt, + hideAt: data.hideAt.present ? data.hideAt.value : this.hideAt, + ); + } + + @override + String toString() { + return (StringBuffer('MemoryEntityData(') + ..write('id: $id, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('deletedAt: $deletedAt, ') + ..write('ownerId: $ownerId, ') + ..write('type: $type, ') + ..write('data: $data, ') + ..write('isSaved: $isSaved, ') + ..write('memoryAt: $memoryAt, ') + ..write('seenAt: $seenAt, ') + ..write('showAt: $showAt, ') + ..write('hideAt: $hideAt') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + createdAt, + updatedAt, + deletedAt, + ownerId, + type, + data, + isSaved, + memoryAt, + seenAt, + showAt, + hideAt, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is MemoryEntityData && + other.id == this.id && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && + other.deletedAt == this.deletedAt && + other.ownerId == this.ownerId && + other.type == this.type && + other.data == this.data && + other.isSaved == this.isSaved && + other.memoryAt == this.memoryAt && + other.seenAt == this.seenAt && + other.showAt == this.showAt && + other.hideAt == this.hideAt); +} + +class MemoryEntityCompanion extends UpdateCompanion { + final Value id; + final Value createdAt; + final Value updatedAt; + final Value deletedAt; + final Value ownerId; + final Value type; + final Value data; + final Value isSaved; + final Value memoryAt; + final Value seenAt; + final Value showAt; + final Value hideAt; + const MemoryEntityCompanion({ + this.id = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.deletedAt = const Value.absent(), + this.ownerId = const Value.absent(), + this.type = const Value.absent(), + this.data = const Value.absent(), + this.isSaved = const Value.absent(), + this.memoryAt = const Value.absent(), + this.seenAt = const Value.absent(), + this.showAt = const Value.absent(), + this.hideAt = const Value.absent(), + }); + MemoryEntityCompanion.insert({ + required String id, + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.deletedAt = const Value.absent(), + required String ownerId, + required int type, + required String data, + this.isSaved = const Value.absent(), + required DateTime memoryAt, + this.seenAt = const Value.absent(), + this.showAt = const Value.absent(), + this.hideAt = const Value.absent(), + }) : id = Value(id), + ownerId = Value(ownerId), + type = Value(type), + data = Value(data), + memoryAt = Value(memoryAt); + static Insertable custom({ + Expression? id, + Expression? createdAt, + Expression? updatedAt, + Expression? deletedAt, + Expression? ownerId, + Expression? type, + Expression? data, + Expression? isSaved, + Expression? memoryAt, + Expression? seenAt, + Expression? showAt, + Expression? hideAt, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, + if (deletedAt != null) 'deleted_at': deletedAt, + if (ownerId != null) 'owner_id': ownerId, + if (type != null) 'type': type, + if (data != null) 'data': data, + if (isSaved != null) 'is_saved': isSaved, + if (memoryAt != null) 'memory_at': memoryAt, + if (seenAt != null) 'seen_at': seenAt, + if (showAt != null) 'show_at': showAt, + if (hideAt != null) 'hide_at': hideAt, + }); + } + + MemoryEntityCompanion copyWith({ + Value? id, + Value? createdAt, + Value? updatedAt, + Value? deletedAt, + Value? ownerId, + Value? type, + Value? data, + Value? isSaved, + Value? memoryAt, + Value? seenAt, + Value? showAt, + Value? hideAt, + }) { + return MemoryEntityCompanion( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + deletedAt: deletedAt ?? this.deletedAt, + ownerId: ownerId ?? this.ownerId, + type: type ?? this.type, + data: data ?? this.data, + isSaved: isSaved ?? this.isSaved, + memoryAt: memoryAt ?? this.memoryAt, + seenAt: seenAt ?? this.seenAt, + showAt: showAt ?? this.showAt, + hideAt: hideAt ?? this.hideAt, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (deletedAt.present) { + map['deleted_at'] = Variable(deletedAt.value); + } + if (ownerId.present) { + map['owner_id'] = Variable(ownerId.value); + } + if (type.present) { + map['type'] = Variable(type.value); + } + if (data.present) { + map['data'] = Variable(data.value); + } + if (isSaved.present) { + map['is_saved'] = Variable(isSaved.value); + } + if (memoryAt.present) { + map['memory_at'] = Variable(memoryAt.value); + } + if (seenAt.present) { + map['seen_at'] = Variable(seenAt.value); + } + if (showAt.present) { + map['show_at'] = Variable(showAt.value); + } + if (hideAt.present) { + map['hide_at'] = Variable(hideAt.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('MemoryEntityCompanion(') + ..write('id: $id, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('deletedAt: $deletedAt, ') + ..write('ownerId: $ownerId, ') + ..write('type: $type, ') + ..write('data: $data, ') + ..write('isSaved: $isSaved, ') + ..write('memoryAt: $memoryAt, ') + ..write('seenAt: $seenAt, ') + ..write('showAt: $showAt, ') + ..write('hideAt: $hideAt') + ..write(')')) + .toString(); + } +} + +class MemoryAssetEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + MemoryAssetEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn assetId = GeneratedColumn( + 'asset_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_asset_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn memoryId = GeneratedColumn( + 'memory_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES memory_entity (id) ON DELETE CASCADE', + ), + ); + @override + List get $columns => [assetId, memoryId]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'memory_asset_entity'; + @override + Set get $primaryKey => {assetId, memoryId}; + @override + MemoryAssetEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return MemoryAssetEntityData( + assetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}asset_id'], + )!, + memoryId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}memory_id'], + )!, + ); + } + + @override + MemoryAssetEntity createAlias(String alias) { + return MemoryAssetEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class MemoryAssetEntityData extends DataClass + implements Insertable { + final String assetId; + final String memoryId; + const MemoryAssetEntityData({required this.assetId, required this.memoryId}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['asset_id'] = Variable(assetId); + map['memory_id'] = Variable(memoryId); + return map; + } + + factory MemoryAssetEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return MemoryAssetEntityData( + assetId: serializer.fromJson(json['assetId']), + memoryId: serializer.fromJson(json['memoryId']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'assetId': serializer.toJson(assetId), + 'memoryId': serializer.toJson(memoryId), + }; + } + + MemoryAssetEntityData copyWith({String? assetId, String? memoryId}) => + MemoryAssetEntityData( + assetId: assetId ?? this.assetId, + memoryId: memoryId ?? this.memoryId, + ); + MemoryAssetEntityData copyWithCompanion(MemoryAssetEntityCompanion data) { + return MemoryAssetEntityData( + assetId: data.assetId.present ? data.assetId.value : this.assetId, + memoryId: data.memoryId.present ? data.memoryId.value : this.memoryId, + ); + } + + @override + String toString() { + return (StringBuffer('MemoryAssetEntityData(') + ..write('assetId: $assetId, ') + ..write('memoryId: $memoryId') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(assetId, memoryId); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is MemoryAssetEntityData && + other.assetId == this.assetId && + other.memoryId == this.memoryId); +} + +class MemoryAssetEntityCompanion + extends UpdateCompanion { + final Value assetId; + final Value memoryId; + const MemoryAssetEntityCompanion({ + this.assetId = const Value.absent(), + this.memoryId = const Value.absent(), + }); + MemoryAssetEntityCompanion.insert({ + required String assetId, + required String memoryId, + }) : assetId = Value(assetId), + memoryId = Value(memoryId); + static Insertable custom({ + Expression? assetId, + Expression? memoryId, + }) { + return RawValuesInsertable({ + if (assetId != null) 'asset_id': assetId, + if (memoryId != null) 'memory_id': memoryId, + }); + } + + MemoryAssetEntityCompanion copyWith({ + Value? assetId, + Value? memoryId, + }) { + return MemoryAssetEntityCompanion( + assetId: assetId ?? this.assetId, + memoryId: memoryId ?? this.memoryId, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (assetId.present) { + map['asset_id'] = Variable(assetId.value); + } + if (memoryId.present) { + map['memory_id'] = Variable(memoryId.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('MemoryAssetEntityCompanion(') + ..write('assetId: $assetId, ') + ..write('memoryId: $memoryId') + ..write(')')) + .toString(); + } +} + +class PersonEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + PersonEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn createdAt = GeneratedColumn( + 'created_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn updatedAt = GeneratedColumn( + 'updated_at', + aliasedName, + false, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + defaultValue: const CustomExpression('CURRENT_TIMESTAMP'), + ); + late final GeneratedColumn ownerId = GeneratedColumn( + 'owner_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES user_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn name = GeneratedColumn( + 'name', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn faceAssetId = GeneratedColumn( + 'face_asset_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn isFavorite = GeneratedColumn( + 'is_favorite', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_favorite" IN (0, 1))', + ), + ); + late final GeneratedColumn isHidden = GeneratedColumn( + 'is_hidden', + aliasedName, + false, + type: DriftSqlType.bool, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'CHECK ("is_hidden" IN (0, 1))', + ), + ); + late final GeneratedColumn color = GeneratedColumn( + 'color', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn birthDate = GeneratedColumn( + 'birth_date', + aliasedName, + true, + type: DriftSqlType.dateTime, + requiredDuringInsert: false, + ); + @override + List get $columns => [ + id, + createdAt, + updatedAt, + ownerId, + name, + faceAssetId, + isFavorite, + isHidden, + color, + birthDate, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'person_entity'; + @override + Set get $primaryKey => {id}; + @override + PersonEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return PersonEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + createdAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}created_at'], + )!, + updatedAt: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}updated_at'], + )!, + ownerId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}owner_id'], + )!, + name: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}name'], + )!, + faceAssetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}face_asset_id'], + ), + isFavorite: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_favorite'], + )!, + isHidden: attachedDatabase.typeMapping.read( + DriftSqlType.bool, + data['${effectivePrefix}is_hidden'], + )!, + color: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}color'], + ), + birthDate: attachedDatabase.typeMapping.read( + DriftSqlType.dateTime, + data['${effectivePrefix}birth_date'], + ), + ); + } + + @override + PersonEntity createAlias(String alias) { + return PersonEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class PersonEntityData extends DataClass + implements Insertable { + final String id; + final DateTime createdAt; + final DateTime updatedAt; + final String ownerId; + final String name; + final String? faceAssetId; + final bool isFavorite; + final bool isHidden; + final String? color; + final DateTime? birthDate; + const PersonEntityData({ + required this.id, + required this.createdAt, + required this.updatedAt, + required this.ownerId, + required this.name, + this.faceAssetId, + required this.isFavorite, + required this.isHidden, + this.color, + this.birthDate, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['created_at'] = Variable(createdAt); + map['updated_at'] = Variable(updatedAt); + map['owner_id'] = Variable(ownerId); + map['name'] = Variable(name); + if (!nullToAbsent || faceAssetId != null) { + map['face_asset_id'] = Variable(faceAssetId); + } + map['is_favorite'] = Variable(isFavorite); + map['is_hidden'] = Variable(isHidden); + if (!nullToAbsent || color != null) { + map['color'] = Variable(color); + } + if (!nullToAbsent || birthDate != null) { + map['birth_date'] = Variable(birthDate); + } + return map; + } + + factory PersonEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return PersonEntityData( + id: serializer.fromJson(json['id']), + createdAt: serializer.fromJson(json['createdAt']), + updatedAt: serializer.fromJson(json['updatedAt']), + ownerId: serializer.fromJson(json['ownerId']), + name: serializer.fromJson(json['name']), + faceAssetId: serializer.fromJson(json['faceAssetId']), + isFavorite: serializer.fromJson(json['isFavorite']), + isHidden: serializer.fromJson(json['isHidden']), + color: serializer.fromJson(json['color']), + birthDate: serializer.fromJson(json['birthDate']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'createdAt': serializer.toJson(createdAt), + 'updatedAt': serializer.toJson(updatedAt), + 'ownerId': serializer.toJson(ownerId), + 'name': serializer.toJson(name), + 'faceAssetId': serializer.toJson(faceAssetId), + 'isFavorite': serializer.toJson(isFavorite), + 'isHidden': serializer.toJson(isHidden), + 'color': serializer.toJson(color), + 'birthDate': serializer.toJson(birthDate), + }; + } + + PersonEntityData copyWith({ + String? id, + DateTime? createdAt, + DateTime? updatedAt, + String? ownerId, + String? name, + Value faceAssetId = const Value.absent(), + bool? isFavorite, + bool? isHidden, + Value color = const Value.absent(), + Value birthDate = const Value.absent(), + }) => PersonEntityData( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ownerId: ownerId ?? this.ownerId, + name: name ?? this.name, + faceAssetId: faceAssetId.present ? faceAssetId.value : this.faceAssetId, + isFavorite: isFavorite ?? this.isFavorite, + isHidden: isHidden ?? this.isHidden, + color: color.present ? color.value : this.color, + birthDate: birthDate.present ? birthDate.value : this.birthDate, + ); + PersonEntityData copyWithCompanion(PersonEntityCompanion data) { + return PersonEntityData( + id: data.id.present ? data.id.value : this.id, + createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt, + updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt, + ownerId: data.ownerId.present ? data.ownerId.value : this.ownerId, + name: data.name.present ? data.name.value : this.name, + faceAssetId: data.faceAssetId.present + ? data.faceAssetId.value + : this.faceAssetId, + isFavorite: data.isFavorite.present + ? data.isFavorite.value + : this.isFavorite, + isHidden: data.isHidden.present ? data.isHidden.value : this.isHidden, + color: data.color.present ? data.color.value : this.color, + birthDate: data.birthDate.present ? data.birthDate.value : this.birthDate, + ); + } + + @override + String toString() { + return (StringBuffer('PersonEntityData(') + ..write('id: $id, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('ownerId: $ownerId, ') + ..write('name: $name, ') + ..write('faceAssetId: $faceAssetId, ') + ..write('isFavorite: $isFavorite, ') + ..write('isHidden: $isHidden, ') + ..write('color: $color, ') + ..write('birthDate: $birthDate') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + createdAt, + updatedAt, + ownerId, + name, + faceAssetId, + isFavorite, + isHidden, + color, + birthDate, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is PersonEntityData && + other.id == this.id && + other.createdAt == this.createdAt && + other.updatedAt == this.updatedAt && + other.ownerId == this.ownerId && + other.name == this.name && + other.faceAssetId == this.faceAssetId && + other.isFavorite == this.isFavorite && + other.isHidden == this.isHidden && + other.color == this.color && + other.birthDate == this.birthDate); +} + +class PersonEntityCompanion extends UpdateCompanion { + final Value id; + final Value createdAt; + final Value updatedAt; + final Value ownerId; + final Value name; + final Value faceAssetId; + final Value isFavorite; + final Value isHidden; + final Value color; + final Value birthDate; + const PersonEntityCompanion({ + this.id = const Value.absent(), + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + this.ownerId = const Value.absent(), + this.name = const Value.absent(), + this.faceAssetId = const Value.absent(), + this.isFavorite = const Value.absent(), + this.isHidden = const Value.absent(), + this.color = const Value.absent(), + this.birthDate = const Value.absent(), + }); + PersonEntityCompanion.insert({ + required String id, + this.createdAt = const Value.absent(), + this.updatedAt = const Value.absent(), + required String ownerId, + required String name, + this.faceAssetId = const Value.absent(), + required bool isFavorite, + required bool isHidden, + this.color = const Value.absent(), + this.birthDate = const Value.absent(), + }) : id = Value(id), + ownerId = Value(ownerId), + name = Value(name), + isFavorite = Value(isFavorite), + isHidden = Value(isHidden); + static Insertable custom({ + Expression? id, + Expression? createdAt, + Expression? updatedAt, + Expression? ownerId, + Expression? name, + Expression? faceAssetId, + Expression? isFavorite, + Expression? isHidden, + Expression? color, + Expression? birthDate, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (createdAt != null) 'created_at': createdAt, + if (updatedAt != null) 'updated_at': updatedAt, + if (ownerId != null) 'owner_id': ownerId, + if (name != null) 'name': name, + if (faceAssetId != null) 'face_asset_id': faceAssetId, + if (isFavorite != null) 'is_favorite': isFavorite, + if (isHidden != null) 'is_hidden': isHidden, + if (color != null) 'color': color, + if (birthDate != null) 'birth_date': birthDate, + }); + } + + PersonEntityCompanion copyWith({ + Value? id, + Value? createdAt, + Value? updatedAt, + Value? ownerId, + Value? name, + Value? faceAssetId, + Value? isFavorite, + Value? isHidden, + Value? color, + Value? birthDate, + }) { + return PersonEntityCompanion( + id: id ?? this.id, + createdAt: createdAt ?? this.createdAt, + updatedAt: updatedAt ?? this.updatedAt, + ownerId: ownerId ?? this.ownerId, + name: name ?? this.name, + faceAssetId: faceAssetId ?? this.faceAssetId, + isFavorite: isFavorite ?? this.isFavorite, + isHidden: isHidden ?? this.isHidden, + color: color ?? this.color, + birthDate: birthDate ?? this.birthDate, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (createdAt.present) { + map['created_at'] = Variable(createdAt.value); + } + if (updatedAt.present) { + map['updated_at'] = Variable(updatedAt.value); + } + if (ownerId.present) { + map['owner_id'] = Variable(ownerId.value); + } + if (name.present) { + map['name'] = Variable(name.value); + } + if (faceAssetId.present) { + map['face_asset_id'] = Variable(faceAssetId.value); + } + if (isFavorite.present) { + map['is_favorite'] = Variable(isFavorite.value); + } + if (isHidden.present) { + map['is_hidden'] = Variable(isHidden.value); + } + if (color.present) { + map['color'] = Variable(color.value); + } + if (birthDate.present) { + map['birth_date'] = Variable(birthDate.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('PersonEntityCompanion(') + ..write('id: $id, ') + ..write('createdAt: $createdAt, ') + ..write('updatedAt: $updatedAt, ') + ..write('ownerId: $ownerId, ') + ..write('name: $name, ') + ..write('faceAssetId: $faceAssetId, ') + ..write('isFavorite: $isFavorite, ') + ..write('isHidden: $isHidden, ') + ..write('color: $color, ') + ..write('birthDate: $birthDate') + ..write(')')) + .toString(); + } +} + +class AssetFaceEntity extends Table + with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + AssetFaceEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + late final GeneratedColumn assetId = GeneratedColumn( + 'asset_id', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES remote_asset_entity (id) ON DELETE CASCADE', + ), + ); + late final GeneratedColumn personId = GeneratedColumn( + 'person_id', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + defaultConstraints: GeneratedColumn.constraintIsAlways( + 'REFERENCES person_entity (id) ON DELETE SET NULL', + ), + ); + late final GeneratedColumn imageWidth = GeneratedColumn( + 'image_width', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn imageHeight = GeneratedColumn( + 'image_height', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn boundingBoxX1 = GeneratedColumn( + 'bounding_box_x1', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn boundingBoxY1 = GeneratedColumn( + 'bounding_box_y1', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn boundingBoxX2 = GeneratedColumn( + 'bounding_box_x2', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn boundingBoxY2 = GeneratedColumn( + 'bounding_box_y2', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn sourceType = GeneratedColumn( + 'source_type', + aliasedName, + false, + type: DriftSqlType.string, + requiredDuringInsert: true, + ); + @override + List get $columns => [ + id, + assetId, + personId, + imageWidth, + imageHeight, + boundingBoxX1, + boundingBoxY1, + boundingBoxX2, + boundingBoxY2, + sourceType, + ]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'asset_face_entity'; + @override + Set get $primaryKey => {id}; + @override + AssetFaceEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return AssetFaceEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}id'], + )!, + assetId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}asset_id'], + )!, + personId: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}person_id'], + ), + imageWidth: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}image_width'], + )!, + imageHeight: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}image_height'], + )!, + boundingBoxX1: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}bounding_box_x1'], + )!, + boundingBoxY1: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}bounding_box_y1'], + )!, + boundingBoxX2: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}bounding_box_x2'], + )!, + boundingBoxY2: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}bounding_box_y2'], + )!, + sourceType: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}source_type'], + )!, + ); + } + + @override + AssetFaceEntity createAlias(String alias) { + return AssetFaceEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class AssetFaceEntityData extends DataClass + implements Insertable { + final String id; + final String assetId; + final String? personId; + final int imageWidth; + final int imageHeight; + final int boundingBoxX1; + final int boundingBoxY1; + final int boundingBoxX2; + final int boundingBoxY2; + final String sourceType; + const AssetFaceEntityData({ + required this.id, + required this.assetId, + this.personId, + required this.imageWidth, + required this.imageHeight, + required this.boundingBoxX1, + required this.boundingBoxY1, + required this.boundingBoxX2, + required this.boundingBoxY2, + required this.sourceType, + }); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + map['asset_id'] = Variable(assetId); + if (!nullToAbsent || personId != null) { + map['person_id'] = Variable(personId); + } + map['image_width'] = Variable(imageWidth); + map['image_height'] = Variable(imageHeight); + map['bounding_box_x1'] = Variable(boundingBoxX1); + map['bounding_box_y1'] = Variable(boundingBoxY1); + map['bounding_box_x2'] = Variable(boundingBoxX2); + map['bounding_box_y2'] = Variable(boundingBoxY2); + map['source_type'] = Variable(sourceType); + return map; + } + + factory AssetFaceEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return AssetFaceEntityData( + id: serializer.fromJson(json['id']), + assetId: serializer.fromJson(json['assetId']), + personId: serializer.fromJson(json['personId']), + imageWidth: serializer.fromJson(json['imageWidth']), + imageHeight: serializer.fromJson(json['imageHeight']), + boundingBoxX1: serializer.fromJson(json['boundingBoxX1']), + boundingBoxY1: serializer.fromJson(json['boundingBoxY1']), + boundingBoxX2: serializer.fromJson(json['boundingBoxX2']), + boundingBoxY2: serializer.fromJson(json['boundingBoxY2']), + sourceType: serializer.fromJson(json['sourceType']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'assetId': serializer.toJson(assetId), + 'personId': serializer.toJson(personId), + 'imageWidth': serializer.toJson(imageWidth), + 'imageHeight': serializer.toJson(imageHeight), + 'boundingBoxX1': serializer.toJson(boundingBoxX1), + 'boundingBoxY1': serializer.toJson(boundingBoxY1), + 'boundingBoxX2': serializer.toJson(boundingBoxX2), + 'boundingBoxY2': serializer.toJson(boundingBoxY2), + 'sourceType': serializer.toJson(sourceType), + }; + } + + AssetFaceEntityData copyWith({ + String? id, + String? assetId, + Value personId = const Value.absent(), + int? imageWidth, + int? imageHeight, + int? boundingBoxX1, + int? boundingBoxY1, + int? boundingBoxX2, + int? boundingBoxY2, + String? sourceType, + }) => AssetFaceEntityData( + id: id ?? this.id, + assetId: assetId ?? this.assetId, + personId: personId.present ? personId.value : this.personId, + imageWidth: imageWidth ?? this.imageWidth, + imageHeight: imageHeight ?? this.imageHeight, + boundingBoxX1: boundingBoxX1 ?? this.boundingBoxX1, + boundingBoxY1: boundingBoxY1 ?? this.boundingBoxY1, + boundingBoxX2: boundingBoxX2 ?? this.boundingBoxX2, + boundingBoxY2: boundingBoxY2 ?? this.boundingBoxY2, + sourceType: sourceType ?? this.sourceType, + ); + AssetFaceEntityData copyWithCompanion(AssetFaceEntityCompanion data) { + return AssetFaceEntityData( + id: data.id.present ? data.id.value : this.id, + assetId: data.assetId.present ? data.assetId.value : this.assetId, + personId: data.personId.present ? data.personId.value : this.personId, + imageWidth: data.imageWidth.present + ? data.imageWidth.value + : this.imageWidth, + imageHeight: data.imageHeight.present + ? data.imageHeight.value + : this.imageHeight, + boundingBoxX1: data.boundingBoxX1.present + ? data.boundingBoxX1.value + : this.boundingBoxX1, + boundingBoxY1: data.boundingBoxY1.present + ? data.boundingBoxY1.value + : this.boundingBoxY1, + boundingBoxX2: data.boundingBoxX2.present + ? data.boundingBoxX2.value + : this.boundingBoxX2, + boundingBoxY2: data.boundingBoxY2.present + ? data.boundingBoxY2.value + : this.boundingBoxY2, + sourceType: data.sourceType.present + ? data.sourceType.value + : this.sourceType, + ); + } + + @override + String toString() { + return (StringBuffer('AssetFaceEntityData(') + ..write('id: $id, ') + ..write('assetId: $assetId, ') + ..write('personId: $personId, ') + ..write('imageWidth: $imageWidth, ') + ..write('imageHeight: $imageHeight, ') + ..write('boundingBoxX1: $boundingBoxX1, ') + ..write('boundingBoxY1: $boundingBoxY1, ') + ..write('boundingBoxX2: $boundingBoxX2, ') + ..write('boundingBoxY2: $boundingBoxY2, ') + ..write('sourceType: $sourceType') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash( + id, + assetId, + personId, + imageWidth, + imageHeight, + boundingBoxX1, + boundingBoxY1, + boundingBoxX2, + boundingBoxY2, + sourceType, + ); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is AssetFaceEntityData && + other.id == this.id && + other.assetId == this.assetId && + other.personId == this.personId && + other.imageWidth == this.imageWidth && + other.imageHeight == this.imageHeight && + other.boundingBoxX1 == this.boundingBoxX1 && + other.boundingBoxY1 == this.boundingBoxY1 && + other.boundingBoxX2 == this.boundingBoxX2 && + other.boundingBoxY2 == this.boundingBoxY2 && + other.sourceType == this.sourceType); +} + +class AssetFaceEntityCompanion extends UpdateCompanion { + final Value id; + final Value assetId; + final Value personId; + final Value imageWidth; + final Value imageHeight; + final Value boundingBoxX1; + final Value boundingBoxY1; + final Value boundingBoxX2; + final Value boundingBoxY2; + final Value sourceType; + const AssetFaceEntityCompanion({ + this.id = const Value.absent(), + this.assetId = const Value.absent(), + this.personId = const Value.absent(), + this.imageWidth = const Value.absent(), + this.imageHeight = const Value.absent(), + this.boundingBoxX1 = const Value.absent(), + this.boundingBoxY1 = const Value.absent(), + this.boundingBoxX2 = const Value.absent(), + this.boundingBoxY2 = const Value.absent(), + this.sourceType = const Value.absent(), + }); + AssetFaceEntityCompanion.insert({ + required String id, + required String assetId, + this.personId = const Value.absent(), + required int imageWidth, + required int imageHeight, + required int boundingBoxX1, + required int boundingBoxY1, + required int boundingBoxX2, + required int boundingBoxY2, + required String sourceType, + }) : id = Value(id), + assetId = Value(assetId), + imageWidth = Value(imageWidth), + imageHeight = Value(imageHeight), + boundingBoxX1 = Value(boundingBoxX1), + boundingBoxY1 = Value(boundingBoxY1), + boundingBoxX2 = Value(boundingBoxX2), + boundingBoxY2 = Value(boundingBoxY2), + sourceType = Value(sourceType); + static Insertable custom({ + Expression? id, + Expression? assetId, + Expression? personId, + Expression? imageWidth, + Expression? imageHeight, + Expression? boundingBoxX1, + Expression? boundingBoxY1, + Expression? boundingBoxX2, + Expression? boundingBoxY2, + Expression? sourceType, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (assetId != null) 'asset_id': assetId, + if (personId != null) 'person_id': personId, + if (imageWidth != null) 'image_width': imageWidth, + if (imageHeight != null) 'image_height': imageHeight, + if (boundingBoxX1 != null) 'bounding_box_x1': boundingBoxX1, + if (boundingBoxY1 != null) 'bounding_box_y1': boundingBoxY1, + if (boundingBoxX2 != null) 'bounding_box_x2': boundingBoxX2, + if (boundingBoxY2 != null) 'bounding_box_y2': boundingBoxY2, + if (sourceType != null) 'source_type': sourceType, + }); + } + + AssetFaceEntityCompanion copyWith({ + Value? id, + Value? assetId, + Value? personId, + Value? imageWidth, + Value? imageHeight, + Value? boundingBoxX1, + Value? boundingBoxY1, + Value? boundingBoxX2, + Value? boundingBoxY2, + Value? sourceType, + }) { + return AssetFaceEntityCompanion( + id: id ?? this.id, + assetId: assetId ?? this.assetId, + personId: personId ?? this.personId, + imageWidth: imageWidth ?? this.imageWidth, + imageHeight: imageHeight ?? this.imageHeight, + boundingBoxX1: boundingBoxX1 ?? this.boundingBoxX1, + boundingBoxY1: boundingBoxY1 ?? this.boundingBoxY1, + boundingBoxX2: boundingBoxX2 ?? this.boundingBoxX2, + boundingBoxY2: boundingBoxY2 ?? this.boundingBoxY2, + sourceType: sourceType ?? this.sourceType, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (assetId.present) { + map['asset_id'] = Variable(assetId.value); + } + if (personId.present) { + map['person_id'] = Variable(personId.value); + } + if (imageWidth.present) { + map['image_width'] = Variable(imageWidth.value); + } + if (imageHeight.present) { + map['image_height'] = Variable(imageHeight.value); + } + if (boundingBoxX1.present) { + map['bounding_box_x1'] = Variable(boundingBoxX1.value); + } + if (boundingBoxY1.present) { + map['bounding_box_y1'] = Variable(boundingBoxY1.value); + } + if (boundingBoxX2.present) { + map['bounding_box_x2'] = Variable(boundingBoxX2.value); + } + if (boundingBoxY2.present) { + map['bounding_box_y2'] = Variable(boundingBoxY2.value); + } + if (sourceType.present) { + map['source_type'] = Variable(sourceType.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('AssetFaceEntityCompanion(') + ..write('id: $id, ') + ..write('assetId: $assetId, ') + ..write('personId: $personId, ') + ..write('imageWidth: $imageWidth, ') + ..write('imageHeight: $imageHeight, ') + ..write('boundingBoxX1: $boundingBoxX1, ') + ..write('boundingBoxY1: $boundingBoxY1, ') + ..write('boundingBoxX2: $boundingBoxX2, ') + ..write('boundingBoxY2: $boundingBoxY2, ') + ..write('sourceType: $sourceType') + ..write(')')) + .toString(); + } +} + +class StoreEntity extends Table with TableInfo { + @override + final GeneratedDatabase attachedDatabase; + final String? _alias; + StoreEntity(this.attachedDatabase, [this._alias]); + late final GeneratedColumn id = GeneratedColumn( + 'id', + aliasedName, + false, + type: DriftSqlType.int, + requiredDuringInsert: true, + ); + late final GeneratedColumn stringValue = GeneratedColumn( + 'string_value', + aliasedName, + true, + type: DriftSqlType.string, + requiredDuringInsert: false, + ); + late final GeneratedColumn intValue = GeneratedColumn( + 'int_value', + aliasedName, + true, + type: DriftSqlType.int, + requiredDuringInsert: false, + ); + @override + List get $columns => [id, stringValue, intValue]; + @override + String get aliasedName => _alias ?? actualTableName; + @override + String get actualTableName => $name; + static const String $name = 'store_entity'; + @override + Set get $primaryKey => {id}; + @override + StoreEntityData map(Map data, {String? tablePrefix}) { + final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : ''; + return StoreEntityData( + id: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}id'], + )!, + stringValue: attachedDatabase.typeMapping.read( + DriftSqlType.string, + data['${effectivePrefix}string_value'], + ), + intValue: attachedDatabase.typeMapping.read( + DriftSqlType.int, + data['${effectivePrefix}int_value'], + ), + ); + } + + @override + StoreEntity createAlias(String alias) { + return StoreEntity(attachedDatabase, alias); + } + + @override + bool get withoutRowId => true; + @override + bool get isStrict => true; +} + +class StoreEntityData extends DataClass implements Insertable { + final int id; + final String? stringValue; + final int? intValue; + const StoreEntityData({required this.id, this.stringValue, this.intValue}); + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + map['id'] = Variable(id); + if (!nullToAbsent || stringValue != null) { + map['string_value'] = Variable(stringValue); + } + if (!nullToAbsent || intValue != null) { + map['int_value'] = Variable(intValue); + } + return map; + } + + factory StoreEntityData.fromJson( + Map json, { + ValueSerializer? serializer, + }) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return StoreEntityData( + id: serializer.fromJson(json['id']), + stringValue: serializer.fromJson(json['stringValue']), + intValue: serializer.fromJson(json['intValue']), + ); + } + @override + Map toJson({ValueSerializer? serializer}) { + serializer ??= driftRuntimeOptions.defaultSerializer; + return { + 'id': serializer.toJson(id), + 'stringValue': serializer.toJson(stringValue), + 'intValue': serializer.toJson(intValue), + }; + } + + StoreEntityData copyWith({ + int? id, + Value stringValue = const Value.absent(), + Value intValue = const Value.absent(), + }) => StoreEntityData( + id: id ?? this.id, + stringValue: stringValue.present ? stringValue.value : this.stringValue, + intValue: intValue.present ? intValue.value : this.intValue, + ); + StoreEntityData copyWithCompanion(StoreEntityCompanion data) { + return StoreEntityData( + id: data.id.present ? data.id.value : this.id, + stringValue: data.stringValue.present + ? data.stringValue.value + : this.stringValue, + intValue: data.intValue.present ? data.intValue.value : this.intValue, + ); + } + + @override + String toString() { + return (StringBuffer('StoreEntityData(') + ..write('id: $id, ') + ..write('stringValue: $stringValue, ') + ..write('intValue: $intValue') + ..write(')')) + .toString(); + } + + @override + int get hashCode => Object.hash(id, stringValue, intValue); + @override + bool operator ==(Object other) => + identical(this, other) || + (other is StoreEntityData && + other.id == this.id && + other.stringValue == this.stringValue && + other.intValue == this.intValue); +} + +class StoreEntityCompanion extends UpdateCompanion { + final Value id; + final Value stringValue; + final Value intValue; + const StoreEntityCompanion({ + this.id = const Value.absent(), + this.stringValue = const Value.absent(), + this.intValue = const Value.absent(), + }); + StoreEntityCompanion.insert({ + required int id, + this.stringValue = const Value.absent(), + this.intValue = const Value.absent(), + }) : id = Value(id); + static Insertable custom({ + Expression? id, + Expression? stringValue, + Expression? intValue, + }) { + return RawValuesInsertable({ + if (id != null) 'id': id, + if (stringValue != null) 'string_value': stringValue, + if (intValue != null) 'int_value': intValue, + }); + } + + StoreEntityCompanion copyWith({ + Value? id, + Value? stringValue, + Value? intValue, + }) { + return StoreEntityCompanion( + id: id ?? this.id, + stringValue: stringValue ?? this.stringValue, + intValue: intValue ?? this.intValue, + ); + } + + @override + Map toColumns(bool nullToAbsent) { + final map = {}; + if (id.present) { + map['id'] = Variable(id.value); + } + if (stringValue.present) { + map['string_value'] = Variable(stringValue.value); + } + if (intValue.present) { + map['int_value'] = Variable(intValue.value); + } + return map; + } + + @override + String toString() { + return (StringBuffer('StoreEntityCompanion(') + ..write('id: $id, ') + ..write('stringValue: $stringValue, ') + ..write('intValue: $intValue') + ..write(')')) + .toString(); + } +} + +class DatabaseAtV12 extends GeneratedDatabase { + DatabaseAtV12(QueryExecutor e) : super(e); + late final UserEntity userEntity = UserEntity(this); + late final RemoteAssetEntity remoteAssetEntity = RemoteAssetEntity(this); + late final StackEntity stackEntity = StackEntity(this); + late final LocalAssetEntity localAssetEntity = LocalAssetEntity(this); + late final RemoteAlbumEntity remoteAlbumEntity = RemoteAlbumEntity(this); + late final LocalAlbumEntity localAlbumEntity = LocalAlbumEntity(this); + late final LocalAlbumAssetEntity localAlbumAssetEntity = + LocalAlbumAssetEntity(this); + late final Index idxLocalAssetChecksum = Index( + 'idx_local_asset_checksum', + 'CREATE INDEX IF NOT EXISTS idx_local_asset_checksum ON local_asset_entity (checksum)', + ); + late final Index idxRemoteAssetOwnerChecksum = Index( + 'idx_remote_asset_owner_checksum', + 'CREATE INDEX IF NOT EXISTS idx_remote_asset_owner_checksum ON remote_asset_entity (owner_id, checksum)', + ); + late final Index uQRemoteAssetsOwnerChecksum = Index( + 'UQ_remote_assets_owner_checksum', + 'CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_checksum ON remote_asset_entity (owner_id, checksum) WHERE(library_id IS NULL)', + ); + late final Index uQRemoteAssetsOwnerLibraryChecksum = Index( + 'UQ_remote_assets_owner_library_checksum', + 'CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_library_checksum ON remote_asset_entity (owner_id, library_id, checksum) WHERE(library_id IS NOT NULL)', + ); + late final Index idxRemoteAssetChecksum = Index( + 'idx_remote_asset_checksum', + 'CREATE INDEX IF NOT EXISTS idx_remote_asset_checksum ON remote_asset_entity (checksum)', + ); + late final AuthUserEntity authUserEntity = AuthUserEntity(this); + late final UserMetadataEntity userMetadataEntity = UserMetadataEntity(this); + late final PartnerEntity partnerEntity = PartnerEntity(this); + late final RemoteExifEntity remoteExifEntity = RemoteExifEntity(this); + late final RemoteAlbumAssetEntity remoteAlbumAssetEntity = + RemoteAlbumAssetEntity(this); + late final RemoteAlbumUserEntity remoteAlbumUserEntity = + RemoteAlbumUserEntity(this); + late final MemoryEntity memoryEntity = MemoryEntity(this); + late final MemoryAssetEntity memoryAssetEntity = MemoryAssetEntity(this); + late final PersonEntity personEntity = PersonEntity(this); + late final AssetFaceEntity assetFaceEntity = AssetFaceEntity(this); + late final StoreEntity storeEntity = StoreEntity(this); + late final Index idxLatLng = Index( + 'idx_lat_lng', + 'CREATE INDEX IF NOT EXISTS idx_lat_lng ON remote_exif_entity (latitude, longitude)', + ); + @override + Iterable> get allTables => + allSchemaEntities.whereType>(); + @override + List get allSchemaEntities => [ + userEntity, + remoteAssetEntity, + stackEntity, + localAssetEntity, + remoteAlbumEntity, + localAlbumEntity, + localAlbumAssetEntity, + idxLocalAssetChecksum, + idxRemoteAssetOwnerChecksum, + uQRemoteAssetsOwnerChecksum, + uQRemoteAssetsOwnerLibraryChecksum, + idxRemoteAssetChecksum, + authUserEntity, + userMetadataEntity, + partnerEntity, + remoteExifEntity, + remoteAlbumAssetEntity, + remoteAlbumUserEntity, + memoryEntity, + memoryAssetEntity, + personEntity, + assetFaceEntity, + storeEntity, + idxLatLng, + ]; + @override + int get schemaVersion => 12; + @override + DriftDatabaseOptions get options => + const DriftDatabaseOptions(storeDateTimeAsText: true); +} diff --git a/mobile/test/utils/action_button_utils_test.dart b/mobile/test/utils/action_button_utils_test.dart index f8c51173d7..274176ae88 100644 --- a/mobile/test/utils/action_button_utils_test.dart +++ b/mobile/test/utils/action_button_utils_test.dart @@ -82,6 +82,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -112,6 +113,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -127,6 +129,7 @@ void main() { isInLockedView: true, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -145,6 +148,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -161,6 +165,7 @@ void main() { isInLockedView: true, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -177,6 +182,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -195,6 +201,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -211,6 +218,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -227,6 +235,7 @@ void main() { isInLockedView: true, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -243,6 +252,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -259,6 +269,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -277,6 +288,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -293,6 +305,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -309,6 +322,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -327,6 +341,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -343,6 +358,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -359,6 +375,7 @@ void main() { isInLockedView: true, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -377,6 +394,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -393,6 +411,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -411,6 +430,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -427,6 +447,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -445,6 +466,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -463,6 +485,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -481,6 +504,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -497,6 +521,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -512,6 +537,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -530,6 +556,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -548,6 +575,7 @@ void main() { isInLockedView: false, currentAlbum: album, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -563,6 +591,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -581,6 +610,7 @@ void main() { isInLockedView: false, currentAlbum: album, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -597,6 +627,7 @@ void main() { isInLockedView: false, currentAlbum: album, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -613,6 +644,7 @@ void main() { isInLockedView: false, currentAlbum: album, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -628,6 +660,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -645,6 +678,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: true, + isStacked: false, source: ActionSource.timeline, ); @@ -660,6 +694,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -668,6 +703,59 @@ void main() { }); }); + group('unstack button', () { + test('should show when owner, not locked, has remote, and is stacked', () { + final remoteAsset = createRemoteAsset(); + final context = ActionButtonContext( + asset: remoteAsset, + isOwner: true, + isArchived: false, + isTrashEnabled: true, + isInLockedView: false, + currentAlbum: null, + advancedTroubleshooting: false, + isStacked: true, + source: ActionSource.timeline, + ); + + expect(ActionButtonType.unstack.shouldShow(context), isTrue); + }); + + test('should not show when not stacked', () { + final remoteAsset = createRemoteAsset(); + final context = ActionButtonContext( + asset: remoteAsset, + isOwner: true, + isArchived: false, + isTrashEnabled: true, + isInLockedView: false, + currentAlbum: null, + advancedTroubleshooting: false, + isStacked: false, + source: ActionSource.timeline, + ); + + expect(ActionButtonType.unstack.shouldShow(context), isFalse); + }); + + test('should not show when not owner', () { + final remoteAsset = createRemoteAsset(); + final context = ActionButtonContext( + asset: remoteAsset, + isOwner: false, + isArchived: true, + isTrashEnabled: true, + isInLockedView: false, + currentAlbum: null, + advancedTroubleshooting: false, + isStacked: false, + source: ActionSource.timeline, + ); + + expect(ActionButtonType.unstack.shouldShow(context), isFalse); + }); + }); + group('ActionButtonType.buildButton', () { late BaseAsset asset; late ActionButtonContext context; @@ -682,6 +770,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); }); @@ -698,6 +787,22 @@ void main() { isInLockedView: false, currentAlbum: album, advancedTroubleshooting: false, + isStacked: false, + source: ActionSource.timeline, + ); + final widget = buttonType.buildButton(contextWithAlbum); + expect(widget, isA()); + } else if (buttonType == ActionButtonType.unstack) { + final album = createRemoteAlbum(); + final contextWithAlbum = ActionButtonContext( + asset: asset, + isOwner: true, + isArchived: false, + isTrashEnabled: true, + isInLockedView: false, + currentAlbum: album, + advancedTroubleshooting: false, + isStacked: true, source: ActionSource.timeline, ); final widget = buttonType.buildButton(contextWithAlbum); @@ -721,6 +826,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -741,6 +847,7 @@ void main() { isInLockedView: false, currentAlbum: album, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -759,6 +866,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -778,6 +886,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); @@ -791,6 +900,7 @@ void main() { isInLockedView: false, currentAlbum: null, advancedTroubleshooting: false, + isStacked: false, source: ActionSource.timeline, ); diff --git a/open-api/immich-openapi-specs.json b/open-api/immich-openapi-specs.json index b57f54564d..b3a58ff02c 100644 --- a/open-api/immich-openapi-specs.json +++ b/open-api/immich-openapi-specs.json @@ -9866,7 +9866,7 @@ "info": { "title": "Immich", "description": "Immich API", - "version": "1.142.1", + "version": "1.144.1", "contact": {} }, "tags": [], @@ -12267,6 +12267,25 @@ ], "type": "object" }, + "MachineLearningAvailabilityChecksDto": { + "properties": { + "enabled": { + "type": "boolean" + }, + "interval": { + "type": "number" + }, + "timeout": { + "type": "number" + } + }, + "required": [ + "enabled", + "interval", + "timeout" + ], + "type": "object" + }, "ManualJobName": { "enum": [ "person-cleanup", @@ -16415,6 +16434,9 @@ }, "SystemConfigMachineLearningDto": { "properties": { + "availabilityChecks": { + "$ref": "#/components/schemas/MachineLearningAvailabilityChecksDto" + }, "clip": { "$ref": "#/components/schemas/CLIPConfig" }, @@ -16427,11 +16449,6 @@ "facialRecognition": { "$ref": "#/components/schemas/FacialRecognitionConfig" }, - "url": { - "deprecated": true, - "description": "This property was deprecated in v1.122.0", - "type": "string" - }, "urls": { "format": "uri", "items": { @@ -16443,6 +16460,7 @@ } }, "required": [ + "availabilityChecks", "clip", "duplicateDetection", "enabled", diff --git a/open-api/typescript-sdk/package.json b/open-api/typescript-sdk/package.json index 8f0d44dcbb..ed568efac5 100644 --- a/open-api/typescript-sdk/package.json +++ b/open-api/typescript-sdk/package.json @@ -1,6 +1,6 @@ { "name": "@immich/sdk", - "version": "1.142.1", + "version": "1.144.1", "description": "Auto-generated TypeScript SDK for the Immich API", "type": "module", "main": "./build/index.js", diff --git a/open-api/typescript-sdk/src/fetch-client.ts b/open-api/typescript-sdk/src/fetch-client.ts index b3e5f2cdef..f182c67dff 100644 --- a/open-api/typescript-sdk/src/fetch-client.ts +++ b/open-api/typescript-sdk/src/fetch-client.ts @@ -1,6 +1,6 @@ /** * Immich - * 1.142.1 + * 1.144.1 * DO NOT MODIFY - This file has been generated using oazapfts. * See https://www.npmjs.com/package/oazapfts */ @@ -1387,6 +1387,11 @@ export type SystemConfigLoggingDto = { enabled: boolean; level: LogLevel; }; +export type MachineLearningAvailabilityChecksDto = { + enabled: boolean; + interval: number; + timeout: number; +}; export type ClipConfig = { enabled: boolean; modelName: string; @@ -1403,12 +1408,11 @@ export type FacialRecognitionConfig = { modelName: string; }; export type SystemConfigMachineLearningDto = { + availabilityChecks: MachineLearningAvailabilityChecksDto; clip: ClipConfig; duplicateDetection: DuplicateDetectionConfig; enabled: boolean; facialRecognition: FacialRecognitionConfig; - /** This property was deprecated in v1.122.0 */ - url?: string; urls: string[]; }; export type SystemConfigMapDto = { diff --git a/package.json b/package.json index a718d7ccd0..18610fe4bc 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.0.1", "description": "Monorepo for Immich", "private": true, - "packageManager": "pnpm@10.14.0+sha512.ad27a79641b49c3e481a16a805baa71817a04bbe06a38d17e60e2eaee83f6a146c6a688125f5792e48dd5ba30e7da52a5cda4c3992b9ccf333f9ce223af84748", + "packageManager": "pnpm@10.15.1+sha512.34e538c329b5553014ca8e8f4535997f96180a1d0f614339357449935350d924e22f8614682191264ec33d1462ac21561aff97f6bb18065351c162c7e8f6de67", "engines": { "pnpm": ">=10.0.0" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c0f7b987ed..75e1e5808d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -43,7 +43,7 @@ importers: devDependencies: '@eslint/js': specifier: ^9.8.0 - version: 9.33.0 + version: 9.35.0 '@immich/sdk': specifier: file:../open-api/typescript-sdk version: link:../open-api/typescript-sdk @@ -64,10 +64,10 @@ importers: version: 4.13.4 '@types/node': specifier: ^22.18.1 - version: 22.18.4 + version: 22.18.5 '@vitest/coverage-v8': specifier: ^3.0.0 - version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.5)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) byte-size: specifier: ^9.0.0 version: 9.0.1 @@ -79,19 +79,19 @@ importers: version: 12.1.0 eslint: specifier: ^9.14.0 - version: 9.33.0(jiti@2.5.1) + version: 9.35.0(jiti@2.5.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.33.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.35.0(jiti@2.5.1)) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.35.0(jiti@2.5.1)))(eslint@9.35.0(jiti@2.5.1))(prettier@3.6.2) eslint-plugin-unicorn: specifier: ^60.0.0 - version: 60.0.0(eslint@9.33.0(jiti@2.5.1)) + version: 60.0.0(eslint@9.35.0(jiti@2.5.1)) globals: specifier: ^16.0.0 - version: 16.3.0 + version: 16.4.0 mock-fs: specifier: ^5.2.0 version: 5.5.0 @@ -106,19 +106,19 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.28.0 - version: 8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) vite: specifier: ^7.0.0 - version: 7.1.5(@types/node@22.18.4)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + version: 7.1.5(@types/node@22.18.5)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) vite-tsconfig-paths: specifier: ^5.0.0 - version: 5.1.4(typescript@5.9.2)(vite@7.1.5(@types/node@22.18.4)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@7.1.5(@types/node@22.18.5)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.5)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) vitest-fetch-mock: specifier: ^0.4.0 - version: 0.4.5(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + version: 0.4.5(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.5)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) yaml: specifier: ^2.3.1 version: 2.8.1 @@ -127,13 +127,13 @@ importers: dependencies: '@docusaurus/core': specifier: ~3.8.0 - version: 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + version: 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/preset-classic': specifier: ~3.8.0 - version: 3.8.1(@algolia/client-search@5.29.0)(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(@types/react@19.1.13)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2) + version: 3.8.1(@algolia/client-search@5.29.0)(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(@types/react@19.1.13)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2) '@docusaurus/theme-common': specifier: ~3.8.0 - version: 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + version: 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@mdi/js': specifier: ^7.3.67 version: 7.4.47 @@ -142,16 +142,13 @@ importers: version: 1.6.1 '@mdx-js/react': specifier: ^3.0.0 - version: 3.1.0(@types/react@19.1.13)(react@18.3.1) + version: 3.1.1(@types/react@19.1.13)(react@18.3.1) autoprefixer: specifier: ^10.4.17 version: 10.4.21(postcss@8.5.6) docusaurus-lunr-search: specifier: ^3.3.2 - version: 3.6.0(@docusaurus/core@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - docusaurus-preset-openapi: - specifier: ^0.7.5 - version: 0.7.6(@algolia/client-search@5.29.0)(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(@types/react@19.1.13)(acorn@8.15.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1)(search-insights@2.17.3)(typescript@5.9.2) + version: 3.6.0(@docusaurus/core@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(react-dom@18.3.1(react@18.3.1))(react@18.3.1) lunr: specifier: ^2.3.9 version: 2.3.9 @@ -197,7 +194,7 @@ importers: devDependencies: '@eslint/js': specifier: ^9.8.0 - version: 9.33.0 + version: 9.35.0 '@immich/cli': specifier: file:../cli version: link:../cli @@ -206,7 +203,7 @@ importers: version: link:../open-api/typescript-sdk '@playwright/test': specifier: ^1.44.1 - version: 1.54.2 + version: 1.55.0 '@socket.io/component-emitter': specifier: ^3.1.2 version: 3.1.2 @@ -215,10 +212,10 @@ importers: version: 3.7.1 '@types/node': specifier: ^22.18.1 - version: 22.18.4 + version: 22.18.5 '@types/oidc-provider': specifier: ^9.0.0 - version: 9.1.2 + version: 9.5.0 '@types/pg': specifier: ^8.15.1 version: 8.15.5 @@ -230,31 +227,31 @@ importers: version: 6.0.3 eslint: specifier: ^9.14.0 - version: 9.33.0(jiti@2.5.1) + version: 9.35.0(jiti@2.5.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.33.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.35.0(jiti@2.5.1)) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.35.0(jiti@2.5.1)))(eslint@9.35.0(jiti@2.5.1))(prettier@3.6.2) eslint-plugin-unicorn: specifier: ^60.0.0 - version: 60.0.0(eslint@9.33.0(jiti@2.5.1)) + version: 60.0.0(eslint@9.35.0(jiti@2.5.1)) exiftool-vendored: specifier: ^28.3.1 version: 28.8.0 globals: specifier: ^16.0.0 - version: 16.3.0 + version: 16.4.0 jose: specifier: ^5.6.3 version: 5.10.0 luxon: specifier: ^3.4.4 - version: 3.7.1 + version: 3.7.2 oidc-provider: specifier: ^9.0.0 - version: 9.4.1 + version: 9.5.1 pg: specifier: ^8.11.3 version: 8.16.3 @@ -281,13 +278,13 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.28.0 - version: 8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) utimes: specifier: ^5.2.1 version: 5.2.1(encoding@0.1.13) vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.5)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) open-api/typescript-sdk: dependencies: @@ -297,7 +294,7 @@ importers: devDependencies: '@types/node': specifier: ^22.18.1 - version: 22.18.4 + version: 22.18.5 typescript: specifier: ^5.3.3 version: 5.9.2 @@ -306,7 +303,7 @@ importers: dependencies: '@nestjs/bullmq': specifier: ^11.0.1 - version: 11.0.3(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6)(bullmq@5.57.0) + version: 11.0.3(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6)(bullmq@5.58.5) '@nestjs/common': specifier: ^11.0.4 version: 11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -333,40 +330,40 @@ importers: version: 1.9.0 '@opentelemetry/context-async-hooks': specifier: ^2.0.0 - version: 2.0.1(@opentelemetry/api@1.9.0) + version: 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/exporter-prometheus': - specifier: ^0.203.0 - version: 0.203.0(@opentelemetry/api@1.9.0) + specifier: ^0.205.0 + version: 0.205.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-http': - specifier: ^0.203.0 - version: 0.203.0(@opentelemetry/api@1.9.0) + specifier: ^0.205.0 + version: 0.205.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-ioredis': + specifier: ^0.53.0 + version: 0.53.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation-nestjs-core': specifier: ^0.51.0 version: 0.51.0(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation-nestjs-core': - specifier: ^0.49.0 - version: 0.49.0(@opentelemetry/api@1.9.0) '@opentelemetry/instrumentation-pg': - specifier: ^0.56.0 - version: 0.56.0(@opentelemetry/api@1.9.0) + specifier: ^0.58.0 + version: 0.58.0(@opentelemetry/api@1.9.0) '@opentelemetry/resources': specifier: ^2.0.1 - version: 2.0.1(@opentelemetry/api@1.9.0) + version: 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-metrics': specifier: ^2.0.1 - version: 2.0.1(@opentelemetry/api@1.9.0) + version: 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/sdk-node': - specifier: ^0.203.0 - version: 0.203.0(@opentelemetry/api@1.9.0) + specifier: ^0.205.0 + version: 0.205.0(@opentelemetry/api@1.9.0) '@opentelemetry/semantic-conventions': specifier: ^1.34.0 - version: 1.36.0 + version: 1.37.0 '@react-email/components': specifier: ^0.5.0 - version: 0.5.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 0.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@react-email/render': specifier: ^1.1.2 - version: 1.2.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + version: 1.2.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@socket.io/redis-adapter': specifier: ^8.3.0 version: 8.3.0(socket.io-adapter@2.5.5) @@ -384,7 +381,7 @@ importers: version: 2.2.0 bullmq: specifier: ^5.51.0 - version: 5.57.0 + version: 5.58.5 chokidar: specifier: ^4.0.3 version: 4.0.3 @@ -444,7 +441,7 @@ importers: version: 4.17.21 luxon: specifier: ^3.4.2 - version: 3.7.1 + version: 3.7.2 mnemonist: specifier: ^0.40.3 version: 0.40.3 @@ -453,7 +450,7 @@ importers: version: 2.0.2 nest-commander: specifier: ^3.16.0 - version: 3.18.0(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6)(@types/inquirer@8.2.11)(typescript@5.9.2) + version: 3.19.1(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6)(@types/inquirer@8.2.11)(@types/node@22.18.5)(typescript@5.9.2) nestjs-cls: specifier: ^5.0.0 version: 5.4.3(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6)(reflect-metadata@0.2.2)(rxjs@7.8.2) @@ -465,10 +462,10 @@ importers: version: 7.0.1(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6) nodemailer: specifier: ^7.0.0 - version: 7.0.5 + version: 7.0.6 openid-client: specifier: ^6.3.3 - version: 6.6.4 + version: 6.8.0 pg: specifier: ^8.11.3 version: 8.16.3 @@ -489,7 +486,7 @@ importers: version: 19.1.1(react@19.1.1) react-email: specifier: ^4.0.0 - version: 4.2.8 + version: 4.2.11 reflect-metadata: specifier: ^0.2.0 version: 0.2.2 @@ -510,7 +507,7 @@ importers: version: 0.34.3 sirv: specifier: ^3.0.0 - version: 3.0.1 + version: 3.0.2 socket.io: specifier: ^4.8.1 version: 4.8.1 @@ -522,7 +519,7 @@ importers: version: 0.1.1 ua-parser-js: specifier: ^2.0.0 - version: 2.0.4(encoding@0.1.13) + version: 2.0.5 uuid: specifier: ^11.1.0 version: 11.1.0 @@ -532,10 +529,10 @@ importers: devDependencies: '@eslint/js': specifier: ^9.8.0 - version: 9.33.0 + version: 9.35.0 '@nestjs/cli': specifier: ^11.0.2 - version: 11.0.10(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.18.4) + version: 11.0.10(@swc/core@1.13.5(@swc/helpers@0.5.17))(@types/node@22.18.5) '@nestjs/schematics': specifier: ^11.0.0 version: 11.0.7(chokidar@4.0.3)(typescript@5.9.2) @@ -544,7 +541,7 @@ importers: version: 11.1.6(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6)(@nestjs/platform-express@11.1.6) '@swc/core': specifier: ^1.4.14 - version: 1.13.3(@swc/helpers@0.5.17) + version: 1.13.5(@swc/helpers@0.5.17) '@types/archiver': specifier: ^6.0.0 version: 6.0.3 @@ -586,7 +583,7 @@ importers: version: 2.0.0 '@types/node': specifier: ^22.18.1 - version: 22.18.4 + version: 22.18.5 '@types/nodemailer': specifier: ^7.0.0 version: 7.0.1 @@ -604,7 +601,7 @@ importers: version: 2.16.0 '@types/semver': specifier: ^7.5.8 - version: 7.7.0 + version: 7.7.1 '@types/supertest': specifier: ^6.0.0 version: 6.0.3 @@ -613,31 +610,31 @@ importers: version: 0.7.39 '@types/validator': specifier: ^13.15.2 - version: 13.15.2 + version: 13.15.3 '@vitest/coverage-v8': specifier: ^3.0.0 - version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.5)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) eslint: specifier: ^9.14.0 - version: 9.33.0(jiti@2.5.1) + version: 9.35.0(jiti@2.5.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.33.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.35.0(jiti@2.5.1)) eslint-plugin-prettier: specifier: ^5.1.3 - version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))(prettier@3.6.2) + version: 5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.35.0(jiti@2.5.1)))(eslint@9.35.0(jiti@2.5.1))(prettier@3.6.2) eslint-plugin-unicorn: specifier: ^60.0.0 - version: 60.0.0(eslint@9.33.0(jiti@2.5.1)) + version: 60.0.0(eslint@9.35.0(jiti@2.5.1)) globals: specifier: ^16.0.0 - version: 16.3.0 + version: 16.4.0 mock-fs: specifier: ^5.2.0 version: 5.5.0 node-gyp: specifier: ^11.2.0 - version: 11.3.0 + version: 11.4.2 pngjs: specifier: ^7.0.0 version: 7.0.0 @@ -649,7 +646,7 @@ importers: version: 4.2.0(prettier@3.6.2)(typescript@5.9.2) sql-formatter: specifier: ^15.0.0 - version: 15.6.6 + version: 15.6.9 supertest: specifier: ^7.1.0 version: 7.1.4 @@ -664,16 +661,16 @@ importers: version: 5.9.2 typescript-eslint: specifier: ^8.28.0 - version: 8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) unplugin-swc: specifier: ^1.4.5 - version: 1.5.5(@swc/core@1.13.3(@swc/helpers@0.5.17))(rollup@4.50.1) + version: 1.5.7(@swc/core@1.13.5(@swc/helpers@0.5.17))(rollup@4.50.1) vite-tsconfig-paths: specifier: ^5.0.0 - version: 5.1.4(typescript@5.9.2)(vite@7.1.5(@types/node@22.18.4)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + version: 5.1.4(typescript@5.9.2)(vite@7.1.5(@types/node@22.18.5)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.5)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) web: dependencies: @@ -685,7 +682,7 @@ importers: version: link:../open-api/typescript-sdk '@immich/ui': specifier: ^0.29.0 - version: 0.29.0(@internationalized/date@3.8.2)(svelte@5.35.5) + version: 0.29.0(@internationalized/date@3.8.2)(svelte@5.38.10) '@mapbox/mapbox-gl-rtl-text': specifier: 0.2.3 version: 0.2.3(mapbox-gl@1.13.3) @@ -694,19 +691,19 @@ importers: version: 7.4.47 '@photo-sphere-viewer/core': specifier: ^5.11.5 - version: 5.13.4 + version: 5.14.0 '@photo-sphere-viewer/equirectangular-video-adapter': specifier: ^5.11.5 - version: 5.13.4(@photo-sphere-viewer/core@5.13.4)(@photo-sphere-viewer/video-plugin@5.13.4(@photo-sphere-viewer/core@5.13.4)) + version: 5.14.0(@photo-sphere-viewer/core@5.14.0)(@photo-sphere-viewer/video-plugin@5.14.0(@photo-sphere-viewer/core@5.14.0)) '@photo-sphere-viewer/resolution-plugin': specifier: ^5.11.5 - version: 5.13.4(@photo-sphere-viewer/core@5.13.4)(@photo-sphere-viewer/settings-plugin@5.13.4(@photo-sphere-viewer/core@5.13.4)) + version: 5.14.0(@photo-sphere-viewer/core@5.14.0)(@photo-sphere-viewer/settings-plugin@5.14.0(@photo-sphere-viewer/core@5.14.0)) '@photo-sphere-viewer/settings-plugin': specifier: ^5.11.5 - version: 5.13.4(@photo-sphere-viewer/core@5.13.4) + version: 5.14.0(@photo-sphere-viewer/core@5.14.0) '@photo-sphere-viewer/video-plugin': specifier: ^5.11.5 - version: 5.13.4(@photo-sphere-viewer/core@5.13.4) + version: 5.14.0(@photo-sphere-viewer/core@5.14.0) '@types/geojson': specifier: ^7946.0.16 version: 7946.0.16 @@ -715,7 +712,7 @@ importers: version: 0.41.0 '@zoom-image/svelte': specifier: ^0.3.0 - version: 0.3.4(svelte@5.35.5) + version: 0.3.4(svelte@5.38.10) async-mutex: specifier: ^0.5.0 version: 0.5.0 @@ -748,10 +745,10 @@ importers: version: 4.17.21 luxon: specifier: ^3.4.4 - version: 3.7.1 + version: 3.7.2 maplibre-gl: specifier: ^5.6.2 - version: 5.6.2 + version: 5.7.1 pmtiles: specifier: ^4.3.0 version: 4.3.0 @@ -765,17 +762,17 @@ importers: specifier: ~4.8.0 version: 4.8.1 svelte-gestures: - specifier: ^5.1.3 - version: 5.1.4 + specifier: ^5.2.2 + version: 5.2.2 svelte-i18n: specifier: ^4.0.1 - version: 4.0.1(svelte@5.35.5) + version: 4.0.1(svelte@5.38.10) svelte-maplibre: specifier: ^1.2.0 - version: 1.2.0(svelte@5.35.5) + version: 1.2.1(svelte@5.38.10) svelte-persisted-store: specifier: ^0.12.0 - version: 0.12.0(svelte@5.35.5) + version: 0.12.0(svelte@5.38.10) tabbable: specifier: ^6.2.0 version: 6.2.0 @@ -785,37 +782,37 @@ importers: devDependencies: '@eslint/js': specifier: ^9.18.0 - version: 9.33.0 + version: 9.35.0 '@faker-js/faker': specifier: ^10.0.0 version: 10.0.0 '@koddsson/eslint-plugin-tscompat': specifier: ^0.2.0 - version: 0.2.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2) + version: 0.2.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) '@socket.io/component-emitter': specifier: ^3.1.0 version: 3.1.2 '@sveltejs/adapter-static': specifier: ^3.0.8 - version: 3.0.9(@sveltejs/kit@2.27.1(@sveltejs/vite-plugin-svelte@6.1.2(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))) + version: 3.0.9(@sveltejs/kit@2.38.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.0(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))) '@sveltejs/enhanced-img': specifier: ^0.8.0 - version: 0.8.1(@sveltejs/vite-plugin-svelte@6.1.2(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(rollup@4.50.1)(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + version: 0.8.1(@sveltejs/vite-plugin-svelte@6.2.0(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(rollup@4.50.1)(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) '@sveltejs/kit': specifier: ^2.27.1 - version: 2.27.1(@sveltejs/vite-plugin-svelte@6.1.2(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + version: 2.38.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.0(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) '@sveltejs/vite-plugin-svelte': - specifier: 6.1.2 - version: 6.1.2(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + specifier: 6.2.0 + version: 6.2.0(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) '@tailwindcss/vite': specifier: ^4.1.7 - version: 4.1.12(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + version: 4.1.13(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) '@testing-library/jest-dom': specifier: ^6.4.2 - version: 6.7.0 + version: 6.8.0 '@testing-library/svelte': specifier: ^5.2.8 - version: 5.2.8(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + version: 5.2.8(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.1)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) '@testing-library/user-event': specifier: ^14.5.2 version: 14.6.1(@testing-library/dom@10.4.0) @@ -839,34 +836,34 @@ importers: version: 1.5.5 '@vitest/coverage-v8': specifier: ^3.0.0 - version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + version: 3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.1)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) dotenv: specifier: ^17.0.0 - version: 17.2.1 + version: 17.2.2 eslint: specifier: ^9.18.0 - version: 9.33.0(jiti@2.5.1) + version: 9.35.0(jiti@2.5.1) eslint-config-prettier: specifier: ^10.1.8 - version: 10.1.8(eslint@9.33.0(jiti@2.5.1)) + version: 10.1.8(eslint@9.35.0(jiti@2.5.1)) eslint-p: - specifier: ^0.25.0 - version: 0.25.0(jiti@2.5.1) + specifier: ^0.26.0 + version: 0.26.0(jiti@2.5.1) eslint-plugin-compat: specifier: ^6.0.2 - version: 6.0.2(eslint@9.33.0(jiti@2.5.1)) + version: 6.0.2(eslint@9.35.0(jiti@2.5.1)) eslint-plugin-svelte: specifier: ^3.9.0 - version: 3.11.0(eslint@9.33.0(jiti@2.5.1))(svelte@5.35.5) + version: 3.12.3(eslint@9.35.0(jiti@2.5.1))(svelte@5.38.10) eslint-plugin-unicorn: specifier: ^60.0.0 - version: 60.0.0(eslint@9.33.0(jiti@2.5.1)) + version: 60.0.0(eslint@9.35.0(jiti@2.5.1)) factory.ts: specifier: ^1.4.1 version: 1.4.2 globals: specifier: ^16.0.0 - version: 16.3.0 + version: 16.4.0 prettier: specifier: ^3.4.2 version: 3.6.2 @@ -878,34 +875,34 @@ importers: version: 4.1.1(prettier@3.6.2) prettier-plugin-svelte: specifier: ^3.3.3 - version: 3.4.0(prettier@3.6.2)(svelte@5.35.5) + version: 3.4.0(prettier@3.6.2)(svelte@5.38.10) rollup-plugin-visualizer: specifier: ^6.0.0 version: 6.0.3(rollup@4.50.1) svelte: - specifier: 5.35.5 - version: 5.35.5 + specifier: 5.38.10 + version: 5.38.10 svelte-check: specifier: ^4.1.5 - version: 4.3.1(picomatch@4.0.3)(svelte@5.35.5)(typescript@5.9.2) + version: 4.3.1(picomatch@4.0.3)(svelte@5.38.10)(typescript@5.9.2) svelte-eslint-parser: specifier: ^1.2.0 - version: 1.3.1(svelte@5.35.5) + version: 1.3.2(svelte@5.38.10) tailwindcss: specifier: ^4.1.7 - version: 4.1.12 + version: 4.1.13 typescript: specifier: ^5.8.3 version: 5.9.2 typescript-eslint: specifier: ^8.28.0 - version: 8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2) + version: 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) vite: specifier: ^7.1.2 - version: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + version: 7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) vitest: specifier: ^3.0.0 - version: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + version: 3.2.4(@types/debug@4.1.12)(@types/node@24.5.1)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) packages: @@ -1244,8 +1241,8 @@ packages: resolution: {integrity: sha512-muE8Tt8M22638HU31A3CgfSUciwz1fhATfoVai05aPXGor//CdWDCbnlY1yvBPo07njuVOCNGCSp/GTt12lIug==} engines: {node: '>=6.9.0'} - '@babel/parser@7.28.3': - resolution: {integrity: sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==} + '@babel/parser@7.28.4': + resolution: {integrity: sha512-yZbBqeM6TkpP9du/I2pUZnJsRMGGvOuIrhjzC1AwHwW+6he4mni6Bp/m8ijn0iOuZuPI2BfkCoSRunpyjnrQKg==} engines: {node: '>=6.0.0'} hasBin: true @@ -1697,12 +1694,12 @@ packages: resolution: {integrity: sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==} engines: {node: '>=6.9.0'} - '@babel/traverse@7.28.3': - resolution: {integrity: sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==} + '@babel/traverse@7.28.4': + resolution: {integrity: sha512-YEzuboP2qvQavAcjgQNVgsvHIDv6ZpwXvcvjmyySP2DIMuByS/6ioU5G9pYrWHM6T2YDfc7xga9iNzYOs12CFQ==} engines: {node: '>=6.9.0'} - '@babel/types@7.28.2': - resolution: {integrity: sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==} + '@babel/types@7.28.4': + resolution: {integrity: sha512-bkFqkLhh3pMBUQQkpVgWDWq/lqzc2678eUyDlTBhRqhCHFguYYGM0Efga7tYk4TogG/3x0EEl66/OQ+WGbWB/Q==} engines: {node: '>=6.9.0'} '@balena/dockerignore@1.0.2': @@ -2468,8 +2465,8 @@ packages: cpu: [x64] os: [win32] - '@eslint-community/eslint-utils@4.7.0': - resolution: {integrity: sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==} + '@eslint-community/eslint-utils@4.9.0': + resolution: {integrity: sha512-ayVFHdtZ+hsq1t2Dy24wCmGXGe4q9Gu3smhLYALJrr473ZH27MsnSL+LKUlimp4BWJqMDMLmPpx/Q9R3OAlL4g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} peerDependencies: eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 @@ -2486,10 +2483,6 @@ packages: resolution: {integrity: sha512-xR93k9WhrDYpXHORXpxVL5oHj3Era7wo6k/Wd8/IsQNnZUTzkGS29lyn3nAT05v6ltUuTFVCCYDEGfy2Or/sPA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.14.0': - resolution: {integrity: sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/core@0.15.2': resolution: {integrity: sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} @@ -2498,12 +2491,8 @@ packages: resolution: {integrity: sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@eslint/js@9.30.1': - resolution: {integrity: sha512-zXhuECFlyep42KZUhWjfvsmXGX39W8K8LFb8AWXM9gSV9dQB+MrJGLKvW6Zw0Ggnbpw0VHTtrhFXYe3Gym18jg==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - - '@eslint/js@9.33.0': - resolution: {integrity: sha512-5K1/mKhWaMfreBGJTwval43JJmkip0RmM+3+IuqupeSKNC/Th2Kc7ucaq5ovTSra/OOKB9c58CGSz3QMVbWt0A==} + '@eslint/js@9.35.0': + resolution: {integrity: sha512-30iXE9whjlILfWobBkNerJo+TXYsgVM5ERQwMcMKCHckHflCmf7wXDAHlARoWnh0s1U72WqlbeyE7iAcCzuCPw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@eslint/object-schema@2.1.6': @@ -2514,17 +2503,10 @@ packages: resolution: {integrity: sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@exodus/schemasafe@1.3.0': - resolution: {integrity: sha512-5Aap/GaRupgNx/feGBwLLTVv8OQFfv3pq2lPRzPg9R+IOBnDgghTGW7l7EuVXOvg5cc/xSAlRW8rBrjIC3Nvqw==} - '@faker-js/faker@10.0.0': resolution: {integrity: sha512-UollFEUkVXutsaP+Vndjxar40Gs5JL2HeLcl8xO1QAjJgOdhc3OmBFWyEylS+RddWaaBiAzH+5/17PLQJwDiLw==} engines: {node: ^20.19.0 || ^22.13.0 || ^23.5.0 || >=24.0.0, npm: '>=10'} - '@faker-js/faker@5.5.3': - resolution: {integrity: sha512-R11tGE6yIFwqpaIqcfkcg7AICXzFg14+5h5v0TfF/9+RMDL6jhzCy/pxHVOfbALGdtVYdt6JdR21tuxEgl34dw==} - deprecated: Please update to a newer version. - '@fig/complete-commander@3.2.0': resolution: {integrity: sha512-1Holl3XtRiANVKURZwgpjCnPuV4RsHp+XC0MhgvyAX/avQwj7F2HUItYOvGi/bXjJCkEzgBZmVfCr0HBA+q+Bw==} peerDependencies: @@ -2579,18 +2561,14 @@ packages: resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} - '@humanfs/node@0.16.6': - resolution: {integrity: sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==} + '@humanfs/node@0.16.7': + resolution: {integrity: sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==} engines: {node: '>=18.18.0'} '@humanwhocodes/module-importer@1.0.1': resolution: {integrity: sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==} engines: {node: '>=12.22'} - '@humanwhocodes/retry@0.3.1': - resolution: {integrity: sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==} - engines: {node: '>=18.18'} - '@humanwhocodes/retry@0.4.3': resolution: {integrity: sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==} engines: {node: '>=18.18'} @@ -2767,8 +2745,8 @@ packages: '@types/node': optional: true - '@inquirer/external-editor@1.0.1': - resolution: {integrity: sha512-Oau4yL24d2B5IL4ma4UpbQigkVhzPDXLoqy1ggK4gnHg/stmkffJE4oOXHXF3uz0UEpywG68KcyXsyYpA1Re/Q==} + '@inquirer/external-editor@1.0.2': + resolution: {integrity: sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==} engines: {node: '>=18'} peerDependencies: '@types/node': '>=18' @@ -3010,8 +2988,8 @@ packages: '@mdx-js/mdx@3.1.0': resolution: {integrity: sha512-/QxEhPAvGwbQmy1Px8F899L5Uc2KZ6JtXwlCgJmjSTBedwOZkByYcBG4GceIGPXRDsmfxhHazuS+hlOShRLeDw==} - '@mdx-js/react@3.1.0': - resolution: {integrity: sha512-QjHtSaoameoalGnKDT3FoIl4+9RwyTmo9ZJGBdLOks/YOiWHoRDI3PUwEzOE7kEmGcV3AFcp9K6dYu9rEuKLAQ==} + '@mdx-js/react@3.1.1': + resolution: {integrity: sha512-f++rKLQgUVYDAtECQ6fn/is15GkEH9+nZPM3MS0RcxVqoTfawHvDlSCH7JbMhAM6uJ32v3eXLvLmLvjGu7PTQw==} peerDependencies: '@types/react': '>=16' react: '>=16' @@ -3019,16 +2997,6 @@ packages: '@microsoft/tsdoc@0.15.1': resolution: {integrity: sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==} - '@monaco-editor/loader@1.5.0': - resolution: {integrity: sha512-hKoGSM+7aAc7eRTRjpqAZucPmoNOC4UUbknb/VNoTkEIkCPhqV8LfbsgM1webRM7S/z21eHEx9Fkwx8Z/C/+Xw==} - - '@monaco-editor/react@4.7.0': - resolution: {integrity: sha512-cyzXQCtO47ydzxpQtCGSQGOC8Gk3ZUeBXFAxD+CWXYFo5OqZyZUonFl0DwUlTyAfRHntBfw2p3w4s9R6oe1eCA==} - peerDependencies: - monaco-editor: '>= 0.25.0 < 1' - react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 - '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': resolution: {integrity: sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==} cpu: [arm64] @@ -3230,88 +3198,88 @@ packages: '@oazapfts/runtime@1.0.4': resolution: {integrity: sha512-7t6C2shug/6tZhQgkCa532oTYBLEnbASV/i1SG1rH2GB4h3aQQujYciYSPT92hvN4IwTe8S2hPkN/6iiOyTlCg==} - '@opentelemetry/api-logs@0.203.0': - resolution: {integrity: sha512-9B9RU0H7Ya1Dx/Rkyc4stuBZSGVQF27WigitInx2QQoj6KUpEFYPKoWjdFTunJYxmXmh17HeBvbMa1EhGyPmqQ==} + '@opentelemetry/api-logs@0.205.0': + resolution: {integrity: sha512-wBlPk1nFB37Hsm+3Qy73yQSobVn28F4isnWIBvKpd5IUH/eat8bwcL02H9yzmHyyPmukeccSl2mbN5sDQZYnPg==} engines: {node: '>=8.0.0'} '@opentelemetry/api@1.9.0': resolution: {integrity: sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==} engines: {node: '>=8.0.0'} - '@opentelemetry/context-async-hooks@2.0.1': - resolution: {integrity: sha512-XuY23lSI3d4PEqKA+7SLtAgwqIfc6E/E9eAQWLN1vlpC53ybO3o6jW4BsXo1xvz9lYyyWItfQDDLzezER01mCw==} + '@opentelemetry/context-async-hooks@2.1.0': + resolution: {integrity: sha512-zOyetmZppnwTyPrt4S7jMfXiSX9yyfF0hxlA8B5oo2TtKl+/RGCy7fi4DrBfIf3lCPrkKsRBWZZD7RFojK7FDg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/core@2.0.1': - resolution: {integrity: sha512-MaZk9SJIDgo1peKevlbhP6+IwIiNPNmswNL4AF0WaQJLbHXjr9SrZMgS12+iqr9ToV4ZVosCcc0f8Rg67LXjxw==} + '@opentelemetry/core@2.1.0': + resolution: {integrity: sha512-RMEtHsxJs/GiHHxYT58IY57UXAQTuUnZVco6ymDEqTNlJKTimM4qPUPVe8InNFyBjhHBEAx4k3Q8LtNayBsbUQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/exporter-logs-otlp-grpc@0.203.0': - resolution: {integrity: sha512-g/2Y2noc/l96zmM+g0LdeuyYKINyBwN6FJySoU15LHPLcMN/1a0wNk2SegwKcxrRdE7Xsm7fkIR5n6XFe3QpPw==} + '@opentelemetry/exporter-logs-otlp-grpc@0.205.0': + resolution: {integrity: sha512-jQlw7OHbqZ8zPt+pOrW2KGN7T55P50e3NXBMr4ckPOF+DWDwSy4W7mkG09GpYWlQAQ5C9BXg5gfUlv5ldTgWsw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-logs-otlp-http@0.203.0': - resolution: {integrity: sha512-s0hys1ljqlMTbXx2XiplmMJg9wG570Z5lH7wMvrZX6lcODI56sG4HL03jklF63tBeyNwK2RV1/ntXGo3HgG4Qw==} + '@opentelemetry/exporter-logs-otlp-http@0.205.0': + resolution: {integrity: sha512-5JteMyVWiro4ghF0tHQjfE6OJcF7UBUcoEqX3UIQ5jutKP1H+fxFdyhqjjpmeHMFxzOHaYuLlNR1Bn7FOjGyJg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-logs-otlp-proto@0.203.0': - resolution: {integrity: sha512-nl/7S91MXn5R1aIzoWtMKGvqxgJgepB/sH9qW0rZvZtabnsjbf8OQ1uSx3yogtvLr0GzwD596nQKz2fV7q2RBw==} + '@opentelemetry/exporter-logs-otlp-proto@0.205.0': + resolution: {integrity: sha512-q3VS9wS+lpZ01txKxiDGBtBpTNge3YhbVEFDgem9ZQR9eI3EZ68+9tVZH9zJcSxI37nZPJ6lEEZO58yEjYZsVA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-metrics-otlp-grpc@0.203.0': - resolution: {integrity: sha512-FCCj9nVZpumPQSEI57jRAA89hQQgONuoC35Lt+rayWY/mzCAc6BQT7RFyFaZKJ2B7IQ8kYjOCPsF/HGFWjdQkQ==} + '@opentelemetry/exporter-metrics-otlp-grpc@0.205.0': + resolution: {integrity: sha512-1Vxlo4lUwqSKYX+phFkXHKYR3DolFHxCku6lVMP1H8sVE3oj4wwmwxMzDsJ7zF+sXd8M0FCr+ckK4SnNNKkV+w==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-metrics-otlp-http@0.203.0': - resolution: {integrity: sha512-HFSW10y8lY6BTZecGNpV3GpoSy7eaO0Z6GATwZasnT4bEsILp8UJXNG5OmEsz4SdwCSYvyCbTJdNbZP3/8LGCQ==} + '@opentelemetry/exporter-metrics-otlp-http@0.205.0': + resolution: {integrity: sha512-fFxNQ/HbbpLmh1pgU6HUVbFD1kNIjrkoluoKJkh88+gnmpFD92kMQ8WFNjPnSbjg2mNVnEkeKXgCYEowNW+p1w==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-metrics-otlp-proto@0.203.0': - resolution: {integrity: sha512-OZnhyd9npU7QbyuHXFEPVm3LnjZYifuKpT3kTnF84mXeEQ84pJJZgyLBpU4FSkSwUkt/zbMyNAI7y5+jYTWGIg==} + '@opentelemetry/exporter-metrics-otlp-proto@0.205.0': + resolution: {integrity: sha512-qIbNnedw9QfFjwpx4NQvdgjK3j3R2kWH/2T+7WXAm1IfMFe9fwatYxE61i7li4CIJKf8HgUC3GS8Du0C3D+AuQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-prometheus@0.203.0': - resolution: {integrity: sha512-2jLuNuw5m4sUj/SncDf/mFPabUxMZmmYetx5RKIMIQyPnl6G6ooFzfeE8aXNRf8YD1ZXNlCnRPcISxjveGJHNg==} + '@opentelemetry/exporter-prometheus@0.205.0': + resolution: {integrity: sha512-xsot/Qm9VLDTag4GEwAunD1XR1U8eBHTLAgO7IZNo2JuD/c/vL7xmDP7mQIUr6Lk3gtj/yGGIR2h3vhTeVzv4w==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-trace-otlp-grpc@0.203.0': - resolution: {integrity: sha512-322coOTf81bm6cAA8+ML6A+m4r2xTCdmAZzGNTboPXRzhwPt4JEmovsFAs+grpdarObd68msOJ9FfH3jxM6wqA==} + '@opentelemetry/exporter-trace-otlp-grpc@0.205.0': + resolution: {integrity: sha512-ZBksUk84CcQOuDJB65yu5A4PORkC4qEsskNwCrPZxDLeWjPOFZNSWt0E0jQxKCY8PskLhjNXJYo12YaqsYvGFA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-trace-otlp-http@0.203.0': - resolution: {integrity: sha512-ZDiaswNYo0yq/cy1bBLJFe691izEJ6IgNmkjm4C6kE9ub/OMQqDXORx2D2j8fzTBTxONyzusbaZlqtfmyqURPw==} + '@opentelemetry/exporter-trace-otlp-http@0.205.0': + resolution: {integrity: sha512-vr2bwwPCSc9u7rbKc74jR+DXFvyMFQo9o5zs+H/fgbK672Whw/1izUKVf+xfWOdJOvuwTnfWxy+VAY+4TSo74Q==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-trace-otlp-proto@0.203.0': - resolution: {integrity: sha512-1xwNTJ86L0aJmWRwENCJlH4LULMG2sOXWIVw+Szta4fkqKVY50Eo4HoVKKq6U9QEytrWCr8+zjw0q/ZOeXpcAQ==} + '@opentelemetry/exporter-trace-otlp-proto@0.205.0': + resolution: {integrity: sha512-bGtFzqiENO2GpJk988mOBMe0MfeNpTQjbLm/LBijas6VRyEDQarUzdBHpFlu89A25k1+BCntdWGsWTa9Ai4FyA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/exporter-zipkin@2.0.1': - resolution: {integrity: sha512-a9eeyHIipfdxzCfc2XPrE+/TI3wmrZUDFtG2RRXHSbZZULAny7SyybSvaDvS77a7iib5MPiAvluwVvbGTsHxsw==} + '@opentelemetry/exporter-zipkin@2.1.0': + resolution: {integrity: sha512-0mEI0VDZrrX9t5RE1FhAyGz+jAGt96HSuXu73leswtY3L5YZD11gtcpARY2KAx/s6Z2+rj5Mhj566JsI2C7mfA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.0.0 @@ -3322,62 +3290,62 @@ packages: peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-http@0.203.0': - resolution: {integrity: sha512-y3uQAcCOAwnO6vEuNVocmpVzG3PER6/YZqbPbbffDdJ9te5NkHEkfSMNzlC3+v7KlE+WinPGc3N7MR30G1HY2g==} + '@opentelemetry/instrumentation-http@0.205.0': + resolution: {integrity: sha512-6fOgRlV7ypBuEzCQP7vXkLQxz3UL1FhE24rAlMRbwGvPAnZLvutcG/fq9FI/n+VU23dOpYexocYsXCf5oy/AXw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-ioredis@0.51.0': - resolution: {integrity: sha512-9IUws0XWCb80NovS+17eONXsw1ZJbHwYYMXiwsfR9TSurkLV5UNbRSKb9URHO+K+pIJILy9wCxvyiOneMr91Ig==} + '@opentelemetry/instrumentation-ioredis@0.53.0': + resolution: {integrity: sha512-Ah2wU347vOJYbE563Tgm3UX2J3DAXoI8gsr8qH0OOO4uDuEv3kVS/eDCfXApt11bvvDDPlOoc60/TGn6m9IoPw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-nestjs-core@0.49.0': - resolution: {integrity: sha512-1R/JFwdmZIk3T/cPOCkVvFQeKYzbbUvDxVH3ShXamUwBlGkdEu5QJitlRMyVNZaHkKZKWgYrBarGQsqcboYgaw==} + '@opentelemetry/instrumentation-nestjs-core@0.51.0': + resolution: {integrity: sha512-Se/m4887W94OO12pjKMjI3398L7HCoWeCjcbwoPvNOWpSpMkljBOHA9vE/fyo63CaVG1XAM5xA4ad60wmJKl9A==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation-pg@0.56.0': - resolution: {integrity: sha512-A/J4SlGX8Y0Wwp7Y66fsNCFT/1h9lmBzqwTnfWW/bULtcKFqkQfqhs3G8+4cRxX02UI2z7T1aW5bsyc6QSYc1Q==} + '@opentelemetry/instrumentation-pg@0.58.0': + resolution: {integrity: sha512-WHntZAorf6CZ0n5a3oHlwGkSeu5Xa4AiCmXkNTKg24TbYSFWzJUtWvPQSkxePvQ3ku71lhAY/M20WgwHlvpZpQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/instrumentation@0.203.0': - resolution: {integrity: sha512-ke1qyM+3AK2zPuBPb6Hk/GCsc5ewbLvPNkEuELx/JmANeEp6ZjnZ+wypPAJSucTw0wvCGrUaibDSdcrGFoWxKQ==} + '@opentelemetry/instrumentation@0.205.0': + resolution: {integrity: sha512-cgvm7tvQdu9Qo7VurJP84wJ7ZV9F6WqDDGZpUc6rUEXwjV7/bXWs0kaYp9v+1Vh1+3TZCD3i6j/lUBcPhu8NhA==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/otlp-exporter-base@0.203.0': - resolution: {integrity: sha512-Wbxf7k+87KyvxFr5D7uOiSq/vHXWommvdnNE7vECO3tAhsA2GfOlpWINCMWUEPdHZ7tCXxw6Epp3vgx3jU7llQ==} + '@opentelemetry/otlp-exporter-base@0.205.0': + resolution: {integrity: sha512-2MN0C1IiKyo34M6NZzD6P9Nv9Dfuz3OJ3rkZwzFmF6xzjDfqqCTatc9v1EpNfaP55iDOCLHFyYNCgs61FFgtUQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/otlp-grpc-exporter-base@0.203.0': - resolution: {integrity: sha512-te0Ze1ueJF+N/UOFl5jElJW4U0pZXQ8QklgSfJ2linHN0JJsuaHG8IabEUi2iqxY8ZBDlSiz1Trfv5JcjWWWwQ==} + '@opentelemetry/otlp-grpc-exporter-base@0.205.0': + resolution: {integrity: sha512-AeuLfrciGYffqsp4EUTdYYc6Ee2BQS+hr08mHZk1C524SFWx0WnfcTnV0NFXbVURUNU6DZu1DhS89zRRrcx/hg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/otlp-transformer@0.203.0': - resolution: {integrity: sha512-Y8I6GgoCna0qDQ2W6GCRtaF24SnvqvA8OfeTi7fqigD23u8Jpb4R5KFv/pRvrlGagcCLICMIyh9wiejp4TXu/A==} + '@opentelemetry/otlp-transformer@0.205.0': + resolution: {integrity: sha512-KmObgqPtk9k/XTlWPJHdMbGCylRAmMJNXIRh6VYJmvlRDMfe+DonH41G7eenG8t4FXn3fxOGh14o/WiMRR6vPg==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': ^1.3.0 - '@opentelemetry/propagator-b3@2.0.1': - resolution: {integrity: sha512-Hc09CaQ8Tf5AGLmf449H726uRoBNGPBL4bjr7AnnUpzWMvhdn61F78z9qb6IqB737TffBsokGAK1XykFEZ1igw==} + '@opentelemetry/propagator-b3@2.1.0': + resolution: {integrity: sha512-yOdHmFseIChYanddMMz0mJIFQHyjwbNhoxc65fEAA8yanxcBPwoFDoh1+WBUWAO/Z0NRgk+k87d+aFIzAZhcBw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/propagator-jaeger@2.0.1': - resolution: {integrity: sha512-7PMdPBmGVH2eQNb/AtSJizQNgeNTfh6jQFqys6lfhd6P4r+m/nTh3gKPPpaCXVdRQ+z93vfKk+4UGty390283w==} + '@opentelemetry/propagator-jaeger@2.1.0': + resolution: {integrity: sha512-QYo7vLyMjrBCUTpwQBF/e+rvP7oGskrSELGxhSvLj5gpM0az9oJnu/0O4l2Nm7LEhAff80ntRYKkAcSwVgvSVQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' @@ -3386,44 +3354,44 @@ packages: resolution: {integrity: sha512-4Wc0AWURII2cfXVVoZ6vDqK+s5n4K5IssdrlVrvGsx6OEOKdghKtJZqXAHWFiZv4nTDLH2/2fldjIHY8clMOjQ==} engines: {node: ^18.19.0 || >=20.6.0} - '@opentelemetry/resources@2.0.1': - resolution: {integrity: sha512-dZOB3R6zvBwDKnHDTB4X1xtMArB/d324VsbiPkX/Yu0Q8T2xceRthoIVFhJdvgVM2QhGVUyX9tzwiNxGtoBJUw==} + '@opentelemetry/resources@2.1.0': + resolution: {integrity: sha512-1CJjf3LCvoefUOgegxi8h6r4B/wLSzInyhGP2UmIBYNlo4Qk5CZ73e1eEyWmfXvFtm1ybkmfb2DqWvspsYLrWw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/sdk-logs@0.203.0': - resolution: {integrity: sha512-vM2+rPq0Vi3nYA5akQD2f3QwossDnTDLvKbea6u/A2NZ3XDkPxMfo/PNrDoXhDUD/0pPo2CdH5ce/thn9K0kLw==} + '@opentelemetry/sdk-logs@0.205.0': + resolution: {integrity: sha512-nyqhNQ6eEzPWQU60Nc7+A5LIq8fz3UeIzdEVBQYefB4+msJZ2vuVtRuk9KxPMw1uHoHDtYEwkr2Ct0iG29jU8w==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.4.0 <1.10.0' - '@opentelemetry/sdk-metrics@2.0.1': - resolution: {integrity: sha512-wf8OaJoSnujMAHWR3g+/hGvNcsC16rf9s1So4JlMiFaFHiE4HpIA3oUh+uWZQ7CNuK8gVW/pQSkgoa5HkkOl0g==} + '@opentelemetry/sdk-metrics@2.1.0': + resolution: {integrity: sha512-J9QX459mzqHLL9Y6FZ4wQPRZG4TOpMCyPOh6mkr/humxE1W2S3Bvf4i75yiMW9uyed2Kf5rxmLhTm/UK8vNkAw==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.9.0 <1.10.0' - '@opentelemetry/sdk-node@0.203.0': - resolution: {integrity: sha512-zRMvrZGhGVMvAbbjiNQW3eKzW/073dlrSiAKPVWmkoQzah9wfynpVPeL55f9fVIm0GaBxTLcPeukWGy0/Wj7KQ==} + '@opentelemetry/sdk-node@0.205.0': + resolution: {integrity: sha512-Y4Wcs8scj/Wy1u61pX1ggqPXPtCsGaqx/UnFu7BtRQE1zCQR+b0h56K7I0jz7U2bRlPUZIFdnNLtoaJSMNzz2g==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/sdk-trace-base@2.0.1': - resolution: {integrity: sha512-xYLlvk/xdScGx1aEqvxLwf6sXQLXCjk3/1SQT9X9AoN5rXRhkdvIFShuNNmtTEPRBqcsMbS4p/gJLNI2wXaDuQ==} + '@opentelemetry/sdk-trace-base@2.1.0': + resolution: {integrity: sha512-uTX9FBlVQm4S2gVQO1sb5qyBLq/FPjbp+tmGoxu4tIgtYGmBYB44+KX/725RFDe30yBSaA9Ml9fqphe1hbUyLQ==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.3.0 <1.10.0' - '@opentelemetry/sdk-trace-node@2.0.1': - resolution: {integrity: sha512-UhdbPF19pMpBtCWYP5lHbTogLWx9N0EBxtdagvkn5YtsAnCBZzL7SjktG+ZmupRgifsHMjwUaCCaVmqGfSADmA==} + '@opentelemetry/sdk-trace-node@2.1.0': + resolution: {integrity: sha512-SvVlBFc/jI96u/mmlKm86n9BbTCbQ35nsPoOohqJX6DXH92K0kTe73zGY5r8xoI1QkjR9PizszVJLzMC966y9Q==} engines: {node: ^18.19.0 || >=20.6.0} peerDependencies: '@opentelemetry/api': '>=1.0.0 <1.10.0' - '@opentelemetry/semantic-conventions@1.36.0': - resolution: {integrity: sha512-TtxJSRD8Ohxp6bKkhrm27JRHAxPczQA7idtcTOMYI+wQRRrfgqxHv1cFbCApcSnNjtXkmzFozn6jQtFrOmbjPQ==} + '@opentelemetry/semantic-conventions@1.37.0': + resolution: {integrity: sha512-JD6DerIKdJGmRp4jQyX5FlrQjA4tjOw1cvfsPAZXfOOEErMUHjPcPSICS+6WnM0nB0efSFARh0KAZss+bvExOA==} engines: {node: '>=14'} '@opentelemetry/sql-common@0.41.0': @@ -3435,30 +3403,30 @@ packages: '@paralleldrive/cuid2@2.2.2': resolution: {integrity: sha512-ZOBkgDwEdoYVlSeRbYYXs0S9MejQofiVYoTbKzy/6GQa39/q5tQU2IX46+shYnUkpEl3wc+J6wRlar7r2EK2xA==} - '@photo-sphere-viewer/core@5.13.4': - resolution: {integrity: sha512-leVQL6gG9wTF+uvCFarHUcr8mzafCZ/GLzauksYQJfiqDVRFSAJNXnTOy7RH9otToluEdjN1hsN1f9HQy+rLYg==} + '@photo-sphere-viewer/core@5.14.0': + resolution: {integrity: sha512-V0JeDSB1D2Q60Zqn7+0FPjq8gqbKEwuxMzNdTLydefkQugVztLvdZykO+4k5XTpweZ2QAWPH/QOI1xZbsdvR9A==} - '@photo-sphere-viewer/equirectangular-video-adapter@5.13.4': - resolution: {integrity: sha512-OdTOKxFunP56FNoPR47mQp7V1WHvV4eiow3qtyJjAgLeU8T2q3kivLuH1kMZN2yTAJaXab+VBXzA/YChiHZ6mQ==} + '@photo-sphere-viewer/equirectangular-video-adapter@5.14.0': + resolution: {integrity: sha512-Ez88sZ4sj3fONpZSortnN3gLXlvV/hn5U/88LsWtxI73YwhkZ06ZtXFYLXU4MBaJvqCbMGaR6j39uVXTWFo5rw==} peerDependencies: - '@photo-sphere-viewer/core': 5.13.4 - '@photo-sphere-viewer/video-plugin': 5.13.4 + '@photo-sphere-viewer/core': 5.14.0 + '@photo-sphere-viewer/video-plugin': 5.14.0 - '@photo-sphere-viewer/resolution-plugin@5.13.4': - resolution: {integrity: sha512-HRBC5zYmpNoo/joKZzXbxn7jwoh3tdtTJFXzHxYPV51ELDclRNmzhmqEaZeVkrFHr4bRF5ow3AOjxiMtu1xQxA==} + '@photo-sphere-viewer/resolution-plugin@5.14.0': + resolution: {integrity: sha512-PvDMX1h+8FzWdySxiorQ2bSmyBGTPsZjNNFRBqIfmb5C+01aWCIE7kuXodXGHwpXQNcOojsVX9IiX0Vz4CiW4A==} peerDependencies: - '@photo-sphere-viewer/core': 5.13.4 - '@photo-sphere-viewer/settings-plugin': 5.13.4 + '@photo-sphere-viewer/core': 5.14.0 + '@photo-sphere-viewer/settings-plugin': 5.14.0 - '@photo-sphere-viewer/settings-plugin@5.13.4': - resolution: {integrity: sha512-As1nmlsfnjKBFQOWPVQLH1+dJ+s62MdEb6Jvlm16+3fUVHF4CBWRTJZyBKejLiu4xjbDxrE8v5ZHDLvG6ButiQ==} + '@photo-sphere-viewer/settings-plugin@5.14.0': + resolution: {integrity: sha512-sMLX4hFSE2PjiP2iUmH9qUAz6GV+UN2WX1zu/D58BBWzF3+8mV+FC9l50qxruO8qvWqqLwYysHUElHnmPPtpTg==} peerDependencies: - '@photo-sphere-viewer/core': 5.13.4 + '@photo-sphere-viewer/core': 5.14.0 - '@photo-sphere-viewer/video-plugin@5.13.4': - resolution: {integrity: sha512-QWbHMVAJHukLbFNn0irND/nEPtmzjbXth1ckBkT1bg8aRilFw50+IIB0Zfdl6X919R2GfGo8P0u+I/Mwxf7yfg==} + '@photo-sphere-viewer/video-plugin@5.14.0': + resolution: {integrity: sha512-jWMZBNlfwYq8Lgc8ncs3ptwHR6Yk7Wl8o1BCFYhmhoRkGZFHEjoOQj7gMPXCET+3iYXQ1TsjTh4ZCW8UUOi+pg==} peerDependencies: - '@photo-sphere-viewer/core': 5.13.4 + '@photo-sphere-viewer/core': 5.14.0 '@photostructure/tz-lookup@11.2.0': resolution: {integrity: sha512-DwrvodcXHNSdGdeSF7SBL5o8aBlsaeuCuG7633F04nYsL3hn5Hxe3z/5kCqxv61J1q7ggKZ27GPylR3x0cPNXQ==} @@ -3471,8 +3439,8 @@ packages: resolution: {integrity: sha512-QNqXyfVS2wm9hweSYD2O7F0G06uurj9kZ96TRQE5Y9hU7+tgdZwIkbAKc5Ocy1HxEY2kuDQa6cQ1WRs/O5LFKA==} engines: {node: ^12.20.0 || ^14.18.0 || >=16.0.0} - '@playwright/test@1.54.2': - resolution: {integrity: sha512-A+znathYxPf+72riFd1r1ovOLqsIIB0jKIoPjyK2kqEIe30/6jF6BC7QNluHuwUmsD2tv1XZVugN8GqfTMOxsA==} + '@playwright/test@1.55.0': + resolution: {integrity: sha512-04IXzPwHrW69XusN/SIdDdKZBzMfOT9UNT/YiJit/xpy2VuAoB8NHc8Aplb96zsWDddLnbkPL3TsmrS04ZU2xQ==} engines: {node: '>=18'} hasBin: true @@ -3550,8 +3518,8 @@ packages: peerDependencies: react: ^18.0 || ^19.0 || ^19.0.0-rc - '@react-email/components@0.5.0': - resolution: {integrity: sha512-esRbP+yMmSkNP9hcpiy2RwpDnvSmlxJcJ1HHbzSwlACGlCHTap+ma344QovvzhpVRhMccyWemdClLG822UvVpQ==} + '@react-email/components@0.5.3': + resolution: {integrity: sha512-8G5vsoMehuGOT4cDqaYLdpagtqCYPl4vThXNylClxO6SrN2w9Mh1+i2RNGj/rdqh/woamHORjlXMYCA/kzDMew==} engines: {node: '>=18.0.0'} peerDependencies: react: ^18.0 || ^19.0 || ^19.0.0-rc @@ -3615,8 +3583,8 @@ packages: peerDependencies: react: ^18.0 || ^19.0 || ^19.0.0-rc - '@react-email/render@1.2.0': - resolution: {integrity: sha512-5fpbV16VYR9Fmk8t7xiwPNAjxjdI8XzVtlx9J9OkhOsIHdr2s5DwAj8/MXzWa9qRYJyLirQ/l7rBSjjgyRAomw==} + '@react-email/render@1.2.3': + resolution: {integrity: sha512-qu3XYNkHGao3teJexVD5CrcgFkNLrzbZvpZN17a7EyQYUN3kHkTkE9saqY4VbvGx6QoNU3p8rsk/Xm++D/+pTw==} engines: {node: '>=18.0.0'} peerDependencies: react: ^18.0 || ^19.0 || ^19.0.0-rc @@ -3646,19 +3614,8 @@ packages: peerDependencies: react: ^18.0 || ^19.0 || ^19.0.0-rc - '@reduxjs/toolkit@1.9.7': - resolution: {integrity: sha512-t7v8ZPxhhKgOKtU+uyJT13lu4vL7az5aFi4IdoDs/eS548edn2M8Ik9h8fxgvMjGoAUVFSt6ZC1P5cWmQ014QQ==} - peerDependencies: - react: ^16.9.0 || ^17.0.0 || ^18 - react-redux: ^7.2.1 || ^8.0.2 - peerDependenciesMeta: - react: - optional: true - react-redux: - optional: true - - '@rollup/pluginutils@5.2.0': - resolution: {integrity: sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==} + '@rollup/pluginutils@5.3.0': + resolution: {integrity: sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==} engines: {node: '>=14.0.0'} peerDependencies: rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 @@ -4003,14 +3960,18 @@ packages: svelte: ^5.0.0 vite: ^6.3.0 || >=7.0.0 - '@sveltejs/kit@2.27.1': - resolution: {integrity: sha512-u5HbL9T4TgWZwXZM7hwdT0f5sDkGaNxsSrLYQoql+eiz2+9rcbbq4MiOAPoRtXG0dys5P5ixBmyQdqZedwZUlA==} + '@sveltejs/kit@2.38.1': + resolution: {integrity: sha512-5JJBPu3U2KXpRwc+e/D2Pl+DJM9oBcCl6XtWenrb6xc6H4lFa0XIJaSch4wMiADrhX512sVIUf13VnEp7aWO1w==} engines: {node: '>=18.13'} hasBin: true peerDependencies: + '@opentelemetry/api': ^1.0.0 '@sveltejs/vite-plugin-svelte': ^3.0.0 || ^4.0.0-next.1 || ^5.0.0 || ^6.0.0-next.0 svelte: ^4.0.0 || ^5.0.0-next.0 vite: ^5.0.3 || ^6.0.0 || ^7.0.0-beta.0 + peerDependenciesMeta: + '@opentelemetry/api': + optional: true '@sveltejs/vite-plugin-svelte-inspector@5.0.0': resolution: {integrity: sha512-iwQ8Z4ET6ZFSt/gC+tVfcsSBHwsqc6RumSaiLUkAurW3BCpJam65cmHw0oOlDMTO0u+PZi9hilBRYN+LZNHTUQ==} @@ -4020,8 +3981,8 @@ packages: svelte: ^5.0.0 vite: ^6.3.0 || ^7.0.0 - '@sveltejs/vite-plugin-svelte@6.1.2': - resolution: {integrity: sha512-7v+7OkUYelC2dhhYDAgX1qO2LcGscZ18Hi5kKzJQq7tQeXpH215dd0+J/HnX2zM5B3QKcIrTVqCGkZXAy5awYw==} + '@sveltejs/vite-plugin-svelte@6.2.0': + resolution: {integrity: sha512-nJsV36+o7rZUDlrnSduMNl11+RoDE1cKqOI0yUEBCcqFoAZOk47TwD3dPKS2WmRutke9StXnzsPBslY7prDM9w==} engines: {node: ^20.19 || ^22.12 || >=24} peerDependencies: svelte: ^5.0.0 @@ -4105,68 +4066,68 @@ packages: resolution: {integrity: sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==} engines: {node: '>=14'} - '@swc/core-darwin-arm64@1.13.3': - resolution: {integrity: sha512-ux0Ws4pSpBTqbDS9GlVP354MekB1DwYlbxXU3VhnDr4GBcCOimpocx62x7cFJkSpEBF8bmX8+/TTCGKh4PbyXw==} + '@swc/core-darwin-arm64@1.13.5': + resolution: {integrity: sha512-lKNv7SujeXvKn16gvQqUQI5DdyY8v7xcoO3k06/FJbHJS90zEwZdQiMNRiqpYw/orU543tPaWgz7cIYWhbopiQ==} engines: {node: '>=10'} cpu: [arm64] os: [darwin] - '@swc/core-darwin-x64@1.13.3': - resolution: {integrity: sha512-p0X6yhxmNUOMZrbeZ3ZNsPige8lSlSe1llllXvpCLkKKxN/k5vZt1sULoq6Nj4eQ7KeHQVm81/+AwKZyf/e0TA==} + '@swc/core-darwin-x64@1.13.5': + resolution: {integrity: sha512-ILd38Fg/w23vHb0yVjlWvQBoE37ZJTdlLHa8LRCFDdX4WKfnVBiblsCU9ar4QTMNdeTBEX9iUF4IrbNWhaF1Ng==} engines: {node: '>=10'} cpu: [x64] os: [darwin] - '@swc/core-linux-arm-gnueabihf@1.13.3': - resolution: {integrity: sha512-OmDoiexL2fVWvQTCtoh0xHMyEkZweQAlh4dRyvl8ugqIPEVARSYtaj55TBMUJIP44mSUOJ5tytjzhn2KFxFcBA==} + '@swc/core-linux-arm-gnueabihf@1.13.5': + resolution: {integrity: sha512-Q6eS3Pt8GLkXxqz9TAw+AUk9HpVJt8Uzm54MvPsqp2yuGmY0/sNaPPNVqctCX9fu/Nu8eaWUen0si6iEiCsazQ==} engines: {node: '>=10'} cpu: [arm] os: [linux] - '@swc/core-linux-arm64-gnu@1.13.3': - resolution: {integrity: sha512-STfKku3QfnuUj6k3g9ld4vwhtgCGYIFQmsGPPgT9MK/dI3Lwnpe5Gs5t1inoUIoGNP8sIOLlBB4HV4MmBjQuhw==} + '@swc/core-linux-arm64-gnu@1.13.5': + resolution: {integrity: sha512-aNDfeN+9af+y+M2MYfxCzCy/VDq7Z5YIbMqRI739o8Ganz6ST+27kjQFd8Y/57JN/hcnUEa9xqdS3XY7WaVtSw==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-arm64-musl@1.13.3': - resolution: {integrity: sha512-bc+CXYlFc1t8pv9yZJGus372ldzOVscBl7encUBlU1m/Sig0+NDJLz6cXXRcFyl6ABNOApWeR4Yl7iUWx6C8og==} + '@swc/core-linux-arm64-musl@1.13.5': + resolution: {integrity: sha512-9+ZxFN5GJag4CnYnq6apKTnnezpfJhCumyz0504/JbHLo+Ue+ZtJnf3RhyA9W9TINtLE0bC4hKpWi8ZKoETyOQ==} engines: {node: '>=10'} cpu: [arm64] os: [linux] - '@swc/core-linux-x64-gnu@1.13.3': - resolution: {integrity: sha512-dFXoa0TEhohrKcxn/54YKs1iwNeW6tUkHJgXW33H381SvjKFUV53WR231jh1sWVJETjA3vsAwxKwR23s7UCmUA==} + '@swc/core-linux-x64-gnu@1.13.5': + resolution: {integrity: sha512-WD530qvHrki8Ywt/PloKUjaRKgstQqNGvmZl54g06kA+hqtSE2FTG9gngXr3UJxYu/cNAjJYiBifm7+w4nbHbA==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-linux-x64-musl@1.13.3': - resolution: {integrity: sha512-ieyjisLB+ldexiE/yD8uomaZuZIbTc8tjquYln9Quh5ykOBY7LpJJYBWvWtm1g3pHv6AXlBI8Jay7Fffb6aLfA==} + '@swc/core-linux-x64-musl@1.13.5': + resolution: {integrity: sha512-Luj8y4OFYx4DHNQTWjdIuKTq2f5k6uSXICqx+FSabnXptaOBAbJHNbHT/06JZh6NRUouaf0mYXN0mcsqvkhd7Q==} engines: {node: '>=10'} cpu: [x64] os: [linux] - '@swc/core-win32-arm64-msvc@1.13.3': - resolution: {integrity: sha512-elTQpnaX5vESSbhCEgcwXjpMsnUbqqHfEpB7ewpkAsLzKEXZaK67ihSRYAuAx6ewRQTo7DS5iTT6X5aQD3MzMw==} + '@swc/core-win32-arm64-msvc@1.13.5': + resolution: {integrity: sha512-cZ6UpumhF9SDJvv4DA2fo9WIzlNFuKSkZpZmPG1c+4PFSEMy5DFOjBSllCvnqihCabzXzpn6ykCwBmHpy31vQw==} engines: {node: '>=10'} cpu: [arm64] os: [win32] - '@swc/core-win32-ia32-msvc@1.13.3': - resolution: {integrity: sha512-nvehQVEOdI1BleJpuUgPLrclJ0TzbEMc+MarXDmmiRFwEUGqj+pnfkTSb7RZyS1puU74IXdK/YhTirHurtbI9w==} + '@swc/core-win32-ia32-msvc@1.13.5': + resolution: {integrity: sha512-C5Yi/xIikrFUzZcyGj9L3RpKljFvKiDMtyDzPKzlsDrKIw2EYY+bF88gB6oGY5RGmv4DAX8dbnpRAqgFD0FMEw==} engines: {node: '>=10'} cpu: [ia32] os: [win32] - '@swc/core-win32-x64-msvc@1.13.3': - resolution: {integrity: sha512-A+JSKGkRbPLVV2Kwx8TaDAV0yXIXm/gc8m98hSkVDGlPBBmydgzNdWy3X7HTUBM7IDk7YlWE7w2+RUGjdgpTmg==} + '@swc/core-win32-x64-msvc@1.13.5': + resolution: {integrity: sha512-YrKdMVxbYmlfybCSbRtrilc6UA8GF5aPmGKBdPvjrarvsmf4i7ZHGCEnLtfOMd3Lwbs2WUZq3WdMbozYeLU93Q==} engines: {node: '>=10'} cpu: [x64] os: [win32] - '@swc/core@1.13.3': - resolution: {integrity: sha512-ZaDETVWnm6FE0fc+c2UE8MHYVS3Fe91o5vkmGfgwGXFbxYvAjKSqxM/j4cRc9T7VZNSJjriXq58XkfCp3Y6f+w==} + '@swc/core@1.13.5': + resolution: {integrity: sha512-WezcBo8a0Dg2rnR82zhwoR6aRNxeTGfK5QCD6TQ+kg3xx/zNT02s/0o+81h/3zhvFSB24NtqEr8FTw88O5W/JQ==} engines: {node: '>=10'} peerDependencies: '@swc/helpers': '>=0.5.17' @@ -4180,72 +4141,72 @@ packages: '@swc/helpers@0.5.17': resolution: {integrity: sha512-5IKx/Y13RsYd+sauPb2x+U/xZikHjolzfuDgTAl/Tdf3Q8rslRvC19NKDLgAJQ6wsqADk10ntlv08nPFw/gO/A==} - '@swc/types@0.1.24': - resolution: {integrity: sha512-tjTMh3V4vAORHtdTprLlfoMptu1WfTZG9Rsca6yOKyNYsRr+MUXutKmliB17orgSZk5DpnDxs8GUdd/qwYxOng==} + '@swc/types@0.1.25': + resolution: {integrity: sha512-iAoY/qRhNH8a/hBvm3zKj9qQ4oc2+3w1unPJa2XvTK3XjeLXtzcCingVPw/9e5mn1+0yPqxcBGp9Jf0pkfMb1g==} '@szmarczak/http-timer@5.0.1': resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} engines: {node: '>=14.16'} - '@tailwindcss/node@4.1.12': - resolution: {integrity: sha512-3hm9brwvQkZFe++SBt+oLjo4OLDtkvlE8q2WalaD/7QWaeM7KEJbAiY/LJZUaCs7Xa8aUu4xy3uoyX4q54UVdQ==} + '@tailwindcss/node@4.1.13': + resolution: {integrity: sha512-eq3ouolC1oEFOAvOMOBAmfCIqZBJuvWvvYWh5h5iOYfe1HFC6+GZ6EIL0JdM3/niGRJmnrOc+8gl9/HGUaaptw==} - '@tailwindcss/oxide-android-arm64@4.1.12': - resolution: {integrity: sha512-oNY5pq+1gc4T6QVTsZKwZaGpBb2N1H1fsc1GD4o7yinFySqIuRZ2E4NvGasWc6PhYJwGK2+5YT1f9Tp80zUQZQ==} + '@tailwindcss/oxide-android-arm64@4.1.13': + resolution: {integrity: sha512-BrpTrVYyejbgGo57yc8ieE+D6VT9GOgnNdmh5Sac6+t0m+v+sKQevpFVpwX3pBrM2qKrQwJ0c5eDbtjouY/+ew==} engines: {node: '>= 10'} cpu: [arm64] os: [android] - '@tailwindcss/oxide-darwin-arm64@4.1.12': - resolution: {integrity: sha512-cq1qmq2HEtDV9HvZlTtrj671mCdGB93bVY6J29mwCyaMYCP/JaUBXxrQQQm7Qn33AXXASPUb2HFZlWiiHWFytw==} + '@tailwindcss/oxide-darwin-arm64@4.1.13': + resolution: {integrity: sha512-YP+Jksc4U0KHcu76UhRDHq9bx4qtBftp9ShK/7UGfq0wpaP96YVnnjFnj3ZFrUAjc5iECzODl/Ts0AN7ZPOANQ==} engines: {node: '>= 10'} cpu: [arm64] os: [darwin] - '@tailwindcss/oxide-darwin-x64@4.1.12': - resolution: {integrity: sha512-6UCsIeFUcBfpangqlXay9Ffty9XhFH1QuUFn0WV83W8lGdX8cD5/+2ONLluALJD5+yJ7k8mVtwy3zMZmzEfbLg==} + '@tailwindcss/oxide-darwin-x64@4.1.13': + resolution: {integrity: sha512-aAJ3bbwrn/PQHDxCto9sxwQfT30PzyYJFG0u/BWZGeVXi5Hx6uuUOQEI2Fa43qvmUjTRQNZnGqe9t0Zntexeuw==} engines: {node: '>= 10'} cpu: [x64] os: [darwin] - '@tailwindcss/oxide-freebsd-x64@4.1.12': - resolution: {integrity: sha512-JOH/f7j6+nYXIrHobRYCtoArJdMJh5zy5lr0FV0Qu47MID/vqJAY3r/OElPzx1C/wdT1uS7cPq+xdYYelny1ww==} + '@tailwindcss/oxide-freebsd-x64@4.1.13': + resolution: {integrity: sha512-Wt8KvASHwSXhKE/dJLCCWcTSVmBj3xhVhp/aF3RpAhGeZ3sVo7+NTfgiN8Vey/Fi8prRClDs6/f0KXPDTZE6nQ==} engines: {node: '>= 10'} cpu: [x64] os: [freebsd] - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.12': - resolution: {integrity: sha512-v4Ghvi9AU1SYgGr3/j38PD8PEe6bRfTnNSUE3YCMIRrrNigCFtHZ2TCm8142X8fcSqHBZBceDx+JlFJEfNg5zQ==} + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.13': + resolution: {integrity: sha512-mbVbcAsW3Gkm2MGwA93eLtWrwajz91aXZCNSkGTx/R5eb6KpKD5q8Ueckkh9YNboU8RH7jiv+ol/I7ZyQ9H7Bw==} engines: {node: '>= 10'} cpu: [arm] os: [linux] - '@tailwindcss/oxide-linux-arm64-gnu@4.1.12': - resolution: {integrity: sha512-YP5s1LmetL9UsvVAKusHSyPlzSRqYyRB0f+Kl/xcYQSPLEw/BvGfxzbH+ihUciePDjiXwHh+p+qbSP3SlJw+6g==} + '@tailwindcss/oxide-linux-arm64-gnu@4.1.13': + resolution: {integrity: sha512-wdtfkmpXiwej/yoAkrCP2DNzRXCALq9NVLgLELgLim1QpSfhQM5+ZxQQF8fkOiEpuNoKLp4nKZ6RC4kmeFH0HQ==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-arm64-musl@4.1.12': - resolution: {integrity: sha512-V8pAM3s8gsrXcCv6kCHSuwyb/gPsd863iT+v1PGXC4fSL/OJqsKhfK//v8P+w9ThKIoqNbEnsZqNy+WDnwQqCA==} + '@tailwindcss/oxide-linux-arm64-musl@4.1.13': + resolution: {integrity: sha512-hZQrmtLdhyqzXHB7mkXfq0IYbxegaqTmfa1p9MBj72WPoDD3oNOh1Lnxf6xZLY9C3OV6qiCYkO1i/LrzEdW2mg==} engines: {node: '>= 10'} cpu: [arm64] os: [linux] - '@tailwindcss/oxide-linux-x64-gnu@4.1.12': - resolution: {integrity: sha512-xYfqYLjvm2UQ3TZggTGrwxjYaLB62b1Wiysw/YE3Yqbh86sOMoTn0feF98PonP7LtjsWOWcXEbGqDL7zv0uW8Q==} + '@tailwindcss/oxide-linux-x64-gnu@4.1.13': + resolution: {integrity: sha512-uaZTYWxSXyMWDJZNY1Ul7XkJTCBRFZ5Fo6wtjrgBKzZLoJNrG+WderJwAjPzuNZOnmdrVg260DKwXCFtJ/hWRQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-linux-x64-musl@4.1.12': - resolution: {integrity: sha512-ha0pHPamN+fWZY7GCzz5rKunlv9L5R8kdh+YNvP5awe3LtuXb5nRi/H27GeL2U+TdhDOptU7T6Is7mdwh5Ar3A==} + '@tailwindcss/oxide-linux-x64-musl@4.1.13': + resolution: {integrity: sha512-oXiPj5mi4Hdn50v5RdnuuIms0PVPI/EG4fxAfFiIKQh5TgQgX7oSuDWntHW7WNIi/yVLAiS+CRGW4RkoGSSgVQ==} engines: {node: '>= 10'} cpu: [x64] os: [linux] - '@tailwindcss/oxide-wasm32-wasi@4.1.12': - resolution: {integrity: sha512-4tSyu3dW+ktzdEpuk6g49KdEangu3eCYoqPhWNsZgUhyegEda3M9rG0/j1GV/JjVVsj+lG7jWAyrTlLzd/WEBg==} + '@tailwindcss/oxide-wasm32-wasi@4.1.13': + resolution: {integrity: sha512-+LC2nNtPovtrDwBc/nqnIKYh/W2+R69FA0hgoeOn64BdCX522u19ryLh3Vf3F8W49XBcMIxSe665kwy21FkhvA==} engines: {node: '>=14.0.0'} cpu: [wasm32] bundledDependencies: @@ -4256,24 +4217,24 @@ packages: - '@emnapi/wasi-threads' - tslib - '@tailwindcss/oxide-win32-arm64-msvc@4.1.12': - resolution: {integrity: sha512-iGLyD/cVP724+FGtMWslhcFyg4xyYyM+5F4hGvKA7eifPkXHRAUDFaimu53fpNg9X8dfP75pXx/zFt/jlNF+lg==} + '@tailwindcss/oxide-win32-arm64-msvc@4.1.13': + resolution: {integrity: sha512-dziTNeQXtoQ2KBXmrjCxsuPk3F3CQ/yb7ZNZNA+UkNTeiTGgfeh+gH5Pi7mRncVgcPD2xgHvkFCh/MhZWSgyQg==} engines: {node: '>= 10'} cpu: [arm64] os: [win32] - '@tailwindcss/oxide-win32-x64-msvc@4.1.12': - resolution: {integrity: sha512-NKIh5rzw6CpEodv/++r0hGLlfgT/gFN+5WNdZtvh6wpU2BpGNgdjvj6H2oFc8nCM839QM1YOhjpgbAONUb4IxA==} + '@tailwindcss/oxide-win32-x64-msvc@4.1.13': + resolution: {integrity: sha512-3+LKesjXydTkHk5zXX01b5KMzLV1xl2mcktBJkje7rhFUpUlYJy7IMOLqjIRQncLTa1WZZiFY/foAeB5nmaiTw==} engines: {node: '>= 10'} cpu: [x64] os: [win32] - '@tailwindcss/oxide@4.1.12': - resolution: {integrity: sha512-gM5EoKHW/ukmlEtphNwaGx45fGoEmP10v51t9unv55voWh6WrOL19hfuIdo2FjxIaZzw776/BUQg7Pck++cIVw==} + '@tailwindcss/oxide@4.1.13': + resolution: {integrity: sha512-CPgsM1IpGRa880sMbYmG1s4xhAy3xEt1QULgTJGQmZUeNgXFR7s1YxYygmJyBGtou4SyEosGAGEeYqY7R53bIA==} engines: {node: '>= 10'} - '@tailwindcss/vite@4.1.12': - resolution: {integrity: sha512-4pt0AMFDx7gzIrAOIYgYP0KCBuKWqyW8ayrdiLEjoJTT4pKTjrzG/e4uzWtTLDziC+66R9wbUqZBccJalSE5vQ==} + '@tailwindcss/vite@4.1.13': + resolution: {integrity: sha512-0PmqLQ010N58SbMTJ7BVJ4I2xopiQn/5i6nlb4JmxzQf8zcS5+m2Cv6tqh+sfDwtIdjoEnOvwsGQ1hkUi8QEHQ==} peerDependencies: vite: ^5.2.0 || ^6 || ^7 @@ -4281,8 +4242,8 @@ packages: resolution: {integrity: sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==} engines: {node: '>=18'} - '@testing-library/jest-dom@6.7.0': - resolution: {integrity: sha512-RI2e97YZ7MRa+vxP4UUnMuMFL2buSsf0ollxUbTgrbPLKhMn8KVTx7raS6DYjC7v1NDVrioOvaShxsguLNISCA==} + '@testing-library/jest-dom@6.8.0': + resolution: {integrity: sha512-WgXcWzVM6idy5JaftTVC8Vs83NKRmGJz4Hqs4oyOuO2J4r/y79vvKZsb+CaGyCSEbUPI6OsewfPd0G1A0/TUZQ==} engines: {node: '>=14', npm: '>=6', yarn: '>=1'} '@testing-library/svelte@5.2.8': @@ -4465,9 +4426,6 @@ packages: '@types/history@4.7.11': resolution: {integrity: sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA==} - '@types/hoist-non-react-statics@3.3.6': - resolution: {integrity: sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==} - '@types/html-minifier-terser@6.1.0': resolution: {integrity: sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==} @@ -4513,8 +4471,8 @@ packages: '@types/koa@3.0.0': resolution: {integrity: sha512-MOcVYdVYmkSutVHZZPh8j3+dAjLyR5Tl59CN0eKgpkE1h/LBSmPAsQQuWs+bKu7WtGNn+hKfJH9Gzml+PulmDg==} - '@types/leaflet@1.9.19': - resolution: {integrity: sha512-pB+n2daHcZPF2FDaWa+6B0a0mSDf4dPU35y5iTXsx7x/PzzshiX5atYiS1jlBn43X7XvM8AP+AB26lnSk0J4GA==} + '@types/leaflet@1.9.20': + resolution: {integrity: sha512-rooalPMlk61LCaLOvBF2VIf9M47HgMQqi5xQ9QRi7c8PkdIe0WrIi5IxXUXQjAdL0c+vcQ01mYWbthzmp9GHWw==} '@types/lodash-es@4.17.12': resolution: {integrity: sha512-0NgftHUcV4v34VhXm8QBSftKVXtbkBG3ViCjs6+eJ5a6y6Mi/jiFGPc1sC7QK+9BFhWrURE3EOggmWaSxL9OzQ==} @@ -4552,35 +4510,29 @@ packages: '@types/multer@2.0.0': resolution: {integrity: sha512-C3Z9v9Evij2yST3RSBktxP9STm6OdMc5uR1xF1SGr98uv8dUlAL2hqwrZ3GVB3uyMyiegnscEK6PGtYvNrjTjw==} - '@types/node-fetch@2.6.12': - resolution: {integrity: sha512-8nneRWKCg3rMtF69nLQJnOYUcbafYeFSjqkw3jCRLsqkWFlHaoQrr5mXmofFGOx3DKn7UfmBMyov8ySvLRVldA==} - '@types/node-forge@1.3.11': resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} '@types/node@17.0.45': resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==} - '@types/node@18.19.123': - resolution: {integrity: sha512-K7DIaHnh0mzVxreCR9qwgNxp3MH9dltPNIEddW9MYUlcKAzm+3grKNSTe2vCJHI1FaLpvpL5JGJrz1UZDKYvDg==} + '@types/node@18.19.126': + resolution: {integrity: sha512-8AXQlBfrGmtYJEJUPs63F/uZQqVeFiN9o6NUjbDJYfxNxFnArlZufANPw4h6dGhYGKxcyw+TapXFvEsguzIQow==} '@types/node@20.19.2': resolution: {integrity: sha512-9pLGGwdzOUBDYi0GNjM97FIA+f92fqSke6joWeBjWXllfNxZBs7qeMF7tvtOIsbY45xkWkxrdwUfUf3MnQa9gA==} - '@types/node@22.18.4': - resolution: {integrity: sha512-UJdblFqXymSBhmZf96BnbisoFIr8ooiiBRMolQgg77Ea+VM37jXw76C2LQr9n8wm9+i/OvlUlW6xSvqwzwqznw==} - '@types/node@22.18.5': resolution: {integrity: sha512-g9BpPfJvxYBXUWI9bV37j6d6LTMNQ88hPwdWWUeYZnMhlo66FIg9gCc1/DZb15QylJSKwOZjwrckvOTWpOiChg==} - '@types/node@24.3.0': - resolution: {integrity: sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==} + '@types/node@24.5.1': + resolution: {integrity: sha512-/SQdmUP2xa+1rdx7VwB9yPq8PaKej8TD5cQ+XfKDPWWC+VDJU4rvVVagXqKUzhKjtFoNA8rXDJAkCxQPAe00+Q==} '@types/nodemailer@7.0.1': resolution: {integrity: sha512-UfHAghPmGZVzaL8x9y+mKZMWyHC399+iq0MOmya5tIyenWX3lcdSb60vOmp0DocR6gCDTYTozv/ULQnREyyjkg==} - '@types/oidc-provider@9.1.2': - resolution: {integrity: sha512-JAreXkbWsZR72Gt3eigG652wq1qBcjhuy421PXU2a8PS0mM00XlG+UdXbM/QPihM3ko0YF8cwvt0H2kacXGcsg==} + '@types/oidc-provider@9.5.0': + resolution: {integrity: sha512-eEzCRVTSqIHD9Bo/qRJ4XQWQ5Z/zBcG+Z2cGJluRsSuWx1RJihqRyPxhIEpMXTwPzHYRTQkVp7hwisQOwzzSAg==} '@types/parse5@5.0.3': resolution: {integrity: sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==} @@ -4588,9 +4540,6 @@ packages: '@types/pg-pool@2.0.6': resolution: {integrity: sha512-TaAUE5rq2VQYxab5Ts7WZhKNmuN78Q6PiFonTDdpbx8a1H0M1vhy3rhiMjl+e2iHmogyMw7jZF4FrE6eJUy5HQ==} - '@types/pg@8.15.4': - resolution: {integrity: sha512-I6UNVBAoYbvuWkkU3oosC8yxqH21f4/Jc4DK71JLG3dT2mdlGe1z+ep/LQGXaKaOgcvUrsQoPRqfgtMcvZiJhg==} - '@types/pg@8.15.5': resolution: {integrity: sha512-LF7lF6zWEKxuT3/OR8wAZGzkg4ENGXFNyiV/JeOt9z5B+0ZVwbql9McqX5c/WStFq1GaGso7H1AzP/qSzmlCKQ==} @@ -4612,9 +4561,6 @@ packages: '@types/range-parser@1.2.7': resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} - '@types/react-redux@7.1.34': - resolution: {integrity: sha512-GdFaVjEbYv4Fthm2ZLvj1VSCedV7TqE5y1kNwnjSdBOTXuRSgowux6J8TAct15T3CKBr63UMk+2CO7ilRhyrAQ==} - '@types/react-router-config@5.0.11': resolution: {integrity: sha512-WmSAg7WgqW7m4x8Mt4N6ZyKz0BubSj/2tVUMsAHp+Yd2AMwcSbeFq9WympT19p5heCFmF97R9eD5uUR/t4HEqw==} @@ -4639,8 +4585,8 @@ packages: '@types/sax@1.2.7': resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==} - '@types/semver@7.7.0': - resolution: {integrity: sha512-k107IF4+Xr7UHjwDc7Cfd6PRQfbdkiRabXGRjo07b4WyPahFBZCZ1sE+BNxYIJPPg73UkfOsVOLwqVc/6ETrIA==} + '@types/semver@7.7.1': + resolution: {integrity: sha512-FmgJfu+MOcQ370SD0ev7EI8TlCAfKYU+B4m5T3yXc1CiRN94g/SZPtsCkk506aUDtlMnFZvasDwHHUcZUEaYuA==} '@types/send@0.17.5': resolution: {integrity: sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==} @@ -4687,8 +4633,8 @@ packages: '@types/uuid@9.0.8': resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} - '@types/validator@13.15.2': - resolution: {integrity: sha512-y7pa/oEJJ4iGYBxOpfAKn5b9+xuihvzDVnC/OSvlVnGxVg0pOqmjiMafiJ1KVNQEaPZf9HsEp5icEwGg8uIe5Q==} + '@types/validator@13.15.3': + resolution: {integrity: sha512-7bcUmDyS6PN3EuD9SlGGOxM77F8WLVsrwkxyWxKnxzmXoequ6c7741QBrANq6htVRGOITJ7z72mTP6Z4XyuG+Q==} '@types/whatwg-mimetype@3.0.2': resolution: {integrity: sha512-c2AKvDT8ToxLIOUlN51gTiHXflsfIFisS4pO7pDPoKouJCESkhZnEy623gwP9laCy5lnLDAw1vAzu2vM2YLOrA==} @@ -4702,63 +4648,63 @@ packages: '@types/yargs@17.0.33': resolution: {integrity: sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==} - '@typescript-eslint/eslint-plugin@8.39.1': - resolution: {integrity: sha512-yYegZ5n3Yr6eOcqgj2nJH8cH/ZZgF+l0YIdKILSDjYFRjgYQMgv/lRjV5Z7Up04b9VYUondt8EPMqg7kTWgJ2g==} + '@typescript-eslint/eslint-plugin@8.43.0': + resolution: {integrity: sha512-8tg+gt7ENL7KewsKMKDHXR1vm8tt9eMxjJBYINf6swonlWgkYn5NwyIgXpbbDxTNU5DgpDFfj95prcTq2clIQQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: - '@typescript-eslint/parser': ^8.39.1 + '@typescript-eslint/parser': ^8.43.0 eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/parser@8.39.1': - resolution: {integrity: sha512-pUXGCuHnnKw6PyYq93lLRiZm3vjuslIy7tus1lIQTYVK9bL8XBgJnCWm8a0KcTtHC84Yya1Q6rtll+duSMj0dg==} + '@typescript-eslint/parser@8.43.0': + resolution: {integrity: sha512-B7RIQiTsCBBmY+yW4+ILd6mF5h1FUwJsVvpqkrgpszYifetQ2Ke+Z4u6aZh0CblkUGIdR59iYVyXqqZGkZ3aBw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/project-service@8.39.1': - resolution: {integrity: sha512-8fZxek3ONTwBu9ptw5nCKqZOSkXshZB7uAxuFF0J/wTMkKydjXCzqqga7MlFMpHi9DoG4BadhmTkITBcg8Aybw==} + '@typescript-eslint/project-service@8.43.0': + resolution: {integrity: sha512-htB/+D/BIGoNTQYffZw4uM4NzzuolCoaA/BusuSIcC8YjmBYQioew5VUZAYdAETPjeed0hqCaW7EHg+Robq8uw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/scope-manager@8.39.1': - resolution: {integrity: sha512-RkBKGBrjgskFGWuyUGz/EtD8AF/GW49S21J8dvMzpJitOF1slLEbbHnNEtAHtnDAnx8qDEdRrULRnWVx27wGBw==} + '@typescript-eslint/scope-manager@8.43.0': + resolution: {integrity: sha512-daSWlQ87ZhsjrbMLvpuuMAt3y4ba57AuvadcR7f3nl8eS3BjRc8L9VLxFLk92RL5xdXOg6IQ+qKjjqNEimGuAg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/tsconfig-utils@8.39.1': - resolution: {integrity: sha512-ePUPGVtTMR8XMU2Hee8kD0Pu4NDE1CN9Q1sxGSGd/mbOtGZDM7pnhXNJnzW63zk/q+Z54zVzj44HtwXln5CvHA==} + '@typescript-eslint/tsconfig-utils@8.43.0': + resolution: {integrity: sha512-ALC2prjZcj2YqqL5X/bwWQmHA2em6/94GcbB/KKu5SX3EBDOsqztmmX1kMkvAJHzxk7TazKzJfFiEIagNV3qEA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/type-utils@8.39.1': - resolution: {integrity: sha512-gu9/ahyatyAdQbKeHnhT4R+y3YLtqqHyvkfDxaBYk97EcbfChSJXyaJnIL3ygUv7OuZatePHmQvuH5ru0lnVeA==} + '@typescript-eslint/type-utils@8.43.0': + resolution: {integrity: sha512-qaH1uLBpBuBBuRf8c1mLJ6swOfzCXryhKND04Igr4pckzSEW9JX5Aw9AgW00kwfjWJF0kk0ps9ExKTfvXfw4Qg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/types@8.39.1': - resolution: {integrity: sha512-7sPDKQQp+S11laqTrhHqeAbsCfMkwJMrV7oTDvtDds4mEofJYir414bYKUEb8YPUm9QL3U+8f6L6YExSoAGdQw==} + '@typescript-eslint/types@8.43.0': + resolution: {integrity: sha512-vQ2FZaxJpydjSZJKiSW/LJsabFFvV7KgLC5DiLhkBcykhQj8iK9BOaDmQt74nnKdLvceM5xmhaTF+pLekrxEkw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@typescript-eslint/typescript-estree@8.39.1': - resolution: {integrity: sha512-EKkpcPuIux48dddVDXyQBlKdeTPMmALqBUbEk38McWv0qVEZwOpVJBi7ugK5qVNgeuYjGNQxrrnoM/5+TI/BPw==} + '@typescript-eslint/typescript-estree@8.43.0': + resolution: {integrity: sha512-7Vv6zlAhPb+cvEpP06WXXy/ZByph9iL6BQRBDj4kmBsW98AqEeQHlj/13X+sZOrKSo9/rNKH4Ul4f6EICREFdw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/utils@8.39.1': - resolution: {integrity: sha512-VF5tZ2XnUSTuiqZFXCZfZs1cgkdd3O/sSYmdo2EpSyDlC86UM/8YytTmKnehOW3TGAlivqTDT6bS87B/GQ/jyg==} + '@typescript-eslint/utils@8.43.0': + resolution: {integrity: sha512-S1/tEmkUeeswxd0GGcnwuVQPFWo8NzZTOMxCvw8BX7OMxnNae+i8Tm7REQen/SwUIPoPqfKn7EaZ+YLpiB3k9g==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 typescript: '>=4.8.4 <6.0.0' - '@typescript-eslint/visitor-keys@8.39.1': - resolution: {integrity: sha512-W8FQi6kEh2e8zVhQ0eeRnxdvIoOkAp/CPAahcNio6nO9dsIwb9b34z90KOlheoyuVf6LSOEdjlkxSkapNEc+4A==} + '@typescript-eslint/visitor-keys@8.43.0': + resolution: {integrity: sha512-T+S1KqRD4sg/bHfLwrpF/K3gQLBM1n7Rp7OjjikjTEssI2YJzQpi5WXoynOaQ93ERIuq3O8RBTOUYDKszUCEHw==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} '@ungap/structured-clone@1.3.0': @@ -4928,14 +4874,6 @@ packages: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} - ajv-draft-04@1.0.0: - resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} - peerDependencies: - ajv: ^8.5.0 - peerDependenciesMeta: - ajv: - optional: true - ajv-formats@2.1.1: resolution: {integrity: sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==} peerDependencies: @@ -4965,9 +4903,6 @@ packages: ajv@6.12.6: resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - ajv@8.11.0: - resolution: {integrity: sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==} - ajv@8.17.1: resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==} @@ -5000,8 +4935,8 @@ packages: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} - ansi-regex@6.2.0: - resolution: {integrity: sha512-TKY5pyBkHyADOPYlRT9Lx6F544mPl0vS5Ew7BJ45hA08Q+t3GjbueLliBWN3sMICk6+y7HdyxSzC4bWS8baBdg==} + ansi-regex@6.2.2: + resolution: {integrity: sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==} engines: {node: '>=12'} ansi-styles@4.3.0: @@ -5012,8 +4947,8 @@ packages: resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} engines: {node: '>=10'} - ansi-styles@6.2.1: - resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} ansis@4.1.0: @@ -5104,12 +5039,6 @@ packages: async@0.2.10: resolution: {integrity: sha512-eAkdoKxU6/LkKDBzLpT+t6Ff5EtfSF4wx1WfJiPEEV7WNLnDaRXk0oVysiEPm262roaachGexwUv94WhSgN5TQ==} - async@3.2.2: - resolution: {integrity: sha512-H0E+qZaDEfx/FY4t7iLRv1W2fFI6+pyCeTw1uN20AQPiwqwM6ojPxHxdLv4z8hi2DtnW9BOckSspLucW7pIE5g==} - - async@3.2.4: - resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} - async@3.2.6: resolution: {integrity: sha512-htCUDlxyyCLMgaM3xXg0C0LW2xqfuQ6p05pCEIsXuyQ+a1koYKTuBMzRNwmybfLgvJDMd0r1LTn4+E0Ti6C2AA==} @@ -5228,8 +5157,8 @@ packages: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} - bits-ui@2.9.9: - resolution: {integrity: sha512-U8qsCQ/5rwXAzUBn8lCLFUeHBoXsA54Lb4uFuurXu6VEszVXLCedZRnhHOQsTc1I+2Js5l4iLiBtPUG7WjNbOA==} + bits-ui@2.9.8: + resolution: {integrity: sha512-oVAqdhLSuGIgEiT0yu3ShSI7AxncCxX26Gv6Lul94BuKHV2uzHoKfIodtnMQSq+udJ54svuCIRqA58whsv7vaA==} engines: {node: '>=20'} peerDependencies: '@internationalized/date': ^3.8.1 @@ -5299,8 +5228,8 @@ packages: resolution: {integrity: sha512-bkXY9WsVpY7CvMhKSR6pZilZu9Ln5WDrKVBUXf2S443etkmEO4V58heTecXcUIsNsi4Rx8JUO4NfX1IcQl4deg==} engines: {node: '>=18.20'} - bullmq@5.57.0: - resolution: {integrity: sha512-Xlh5mh6VQmHS6x5PIuYNf55Nn3T7GGN5Is+zHysN4ZUomX3RziyRFzQXeWgn3SKbaXxQ3aLWHjYDMaE5MhEXyA==} + bullmq@5.58.5: + resolution: {integrity: sha512-0A6Qjxdn8j7aOcxfRZY798vO/aMuwvoZwfE6a9EOXHb1pzpBVAogsc/OfRWeUf+5wMBoYB5nthstnJo/zrQOeQ==} busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} @@ -5355,9 +5284,6 @@ packages: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} - call-me-maybe@1.0.2: - resolution: {integrity: sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==} - callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -5402,8 +5328,8 @@ packages: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} - chalk@5.6.0: - resolution: {integrity: sha512-46QrSQFyVSEyYAgQ22hQ+zDa60YHA4fBstHmtSApj1Y5vKtG27fWowW03jCk5KcbXEWPZUIR894aARCA/G1kfQ==} + chalk@5.6.2: + resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} change-case@5.4.4: @@ -5425,16 +5351,9 @@ packages: character-reference-invalid@2.0.1: resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==} - chardet@0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - chardet@2.1.0: resolution: {integrity: sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==} - charset@1.0.1: - resolution: {integrity: sha512-6dVyOOYjpfFcL1Y4qChrAoQLRHvj2ziyhcm0QJlhOcAhykL/k1kTUPbeo+87MNRTRdk2OIIsIXbuF3x2wi5EXg==} - engines: {node: '>=4.0.0'} - check-error@2.1.1: resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} engines: {node: '>= 16'} @@ -5552,10 +5471,6 @@ packages: resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} engines: {node: '>=0.8'} - clsx@1.2.1: - resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} - engines: {node: '>=6'} - clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -5662,12 +5577,6 @@ packages: resolution: {integrity: sha512-9mAqGPHLakhCLeNyxPkK4xVo746zQ/czLH1Ky+vkitMnWfWZps8r0qXuwhwizagCRttsL4lfG4pIOvaWLpAP0w==} engines: {node: '>= 0.8.0'} - compute-gcd@1.2.1: - resolution: {integrity: sha512-TwMbxBNz0l71+8Sc4czv13h4kEqnchV9igQZBi6QUaz09dnz13juGnnaWWJTRsP3brxOoxeB4SA2WELLw1hCtg==} - - compute-lcm@1.1.2: - resolution: {integrity: sha512-OFNPdQAXnQhDSKioX8/XYT6sdUlXwpeMjfd6ApxMJfyZ4GxmLR1xvMERctlYhlHwIiz6CSpBc2+qYKjHGZw4TQ==} - concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -5809,9 +5718,6 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} - crypto-js@4.2.0: - resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} - crypto-random-string@4.0.0: resolution: {integrity: sha512-x8dy3RnvYdlUcPOjkEHqozhiwzKNSq7GcPuXFbnyMOCHxX8V3OgIg/pYuabl2sbUPfIJaeAQB7PMOK8DFIdoRA==} engines: {node: '>=12'} @@ -6001,8 +5907,8 @@ packages: supports-color: optional: true - debug@4.4.1: - resolution: {integrity: sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==} + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} peerDependencies: supports-color: '*' @@ -6099,24 +6005,20 @@ packages: detect-europe-js@0.1.2: resolution: {integrity: sha512-lgdERlL3u0aUdHocoouzT10d9I89VVhk0qNRmll7mXdGfJT1/wqZ2ZLA4oJAjeACPY5fT1wsbq2AT+GkuInsow==} - detect-libc@2.0.4: - resolution: {integrity: sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==} + detect-libc@2.1.0: + resolution: {integrity: sha512-vEtk+OcP7VBRtQZ1EJ3bdgzSfBjgnEalLTp5zjJrS+2Z1w2KZly4SBdac/WDU3hhsNAZ9E8SC96ME4Ey8MZ7cg==} engines: {node: '>=8'} detect-node@2.1.0: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} - detect-package-manager@3.0.2: - resolution: {integrity: sha512-8JFjJHutStYrfWwzfretQoyNGoZVW1Fsrp4JO9spa7h/fBfwgTMEIy4/LBzRDGsxwVPHU0q+T9YvwLDJoOApLQ==} - engines: {node: '>=12'} - detect-port@1.6.1: resolution: {integrity: sha512-CmnVc+Hek2egPx1PeTFVta2W78xy2K/9Rkf6cC4T59S50tVnzKj+tnx5mmx5lwvCkujZ4uRrpRSuV+IVs3f90Q==} engines: {node: '>= 4.0.0'} hasBin: true - devalue@5.1.1: - resolution: {integrity: sha512-maua5KUiapvEwiEAe+XnlZ3Rh0GD+qI1J/nb9vrJc3muPXvcF/8gXYTWF76+5DAqHyDUtOIImEuo0YKE9mshVw==} + devalue@5.3.2: + resolution: {integrity: sha512-UDsjUbpQn9kvm68slnrs+mfxwFkIflOhkanmyabZ8zOYk8SMEIbJ3TK+88g70hSIeytu4y18f0z/hYHMTrXIWw==} devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} @@ -6171,31 +6073,6 @@ packages: react: ^16.8.4 || ^17 || ^18 || ^19 react-dom: ^16.8.4 || ^17 || ^18 || ^19 - docusaurus-plugin-openapi@0.7.6: - resolution: {integrity: sha512-LR8DI0gO9WFy8K+r0xrVgqDkKKA9zQtDgOnX9CatP3I3Oz5lKegfTJM2fVUIp5m25elzHL+vVKNHS12Jg7sWVA==} - engines: {node: '>=18'} - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - - docusaurus-plugin-proxy@0.7.6: - resolution: {integrity: sha512-MgjzMEsQOHMljwQGglXXoGjQvs0v1DklhRgzqNLKFwpHB9xLWJZ0KQ3GgbPerW/2vy8tWGJeVhKHy5cPrmweUw==} - engines: {node: '>=14'} - - docusaurus-preset-openapi@0.7.6: - resolution: {integrity: sha512-QnArH/3X0lePB7667FyNK3EeTS8ZP8V2PQxz5m+3BMO2kIzdXDwfTIQ37boB0BTqsDfUE0yCWTVjB0W/BA1UXA==} - engines: {node: '>=18'} - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - - docusaurus-theme-openapi@0.7.6: - resolution: {integrity: sha512-euoEh8tYX/ssQcMQxBOxt3wPttz3zvPu0l5lSe6exiIwMrORB4O2b8XRB7fVa/awF7xzdIkKHMH55uc5zVOKYA==} - engines: {node: '>=18'} - peerDependencies: - react: ^18.0.0 - react-dom: ^18.0.0 - dom-accessibility-api@0.5.16: resolution: {integrity: sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==} @@ -6243,8 +6120,8 @@ packages: resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} engines: {node: '>=10'} - dotenv@17.2.1: - resolution: {integrity: sha512-kQhDYKZecqnM0fCnzI5eIv5L4cAe/iRI+HqMbO/hbRdTAeXDG+M9FjipUxNfbARuEg4iHIbhnhs78BCHNbSxEQ==} + dotenv@17.2.2: + resolution: {integrity: sha512-Sf2LSQP+bOlhKWWyhFsn0UsfdK/kCWRv1iuA2gXAwt3dyNabr6QSj00I2V10pidqz69soatm9ZwZvpQMTIOd5Q==} engines: {node: '>=12'} dunder-proto@1.0.1: @@ -6269,8 +6146,8 @@ packages: electron-to-chromium@1.5.207: resolution: {integrity: sha512-mryFrrL/GXDTmAtIVMVf+eIXM09BBPlO5IQ7lUyKmK8d+A4VpRGG+M3ofoVef6qyF8s60rJei8ymlJxjUA8Faw==} - emoji-regex@10.4.0: - resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==} + emoji-regex@10.5.0: + resolution: {integrity: sha512-lb49vf1Xzfx080OKA0o6l8DQQpV+6Vg95zyCJX9VB/BqKYlhG7N4wgROUUHRA+ZPUefLnteQOad7z1kT2bV7bg==} emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} @@ -6335,8 +6212,8 @@ packages: err-code@2.0.3: resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} - error-ex@1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + error-ex@1.3.4: + resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} @@ -6364,9 +6241,6 @@ packages: es6-iterator@2.0.3: resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} - es6-promise@3.3.1: - resolution: {integrity: sha512-SOp9Phqvqn7jtEUxPWdWfWoLmyt2VaJ6MpvP9Comy1MceMXqE6bxvaTu4iaxpYYPzhny28Lc+M87/c2cPK6lDg==} - es6-symbol@3.1.4: resolution: {integrity: sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==} engines: {node: '>=0.12'} @@ -6424,8 +6298,8 @@ packages: peerDependencies: eslint: '>=7.0.0' - eslint-p@0.25.0: - resolution: {integrity: sha512-e7oYgXN/tgtoaR3tZ0R2dKyPJtf5J41hYKsgpsBtwpi0t2Cxjf3l8G2QwrXCDwQTFVXW1hmD55hAqQZxiId1XA==} + eslint-p@0.26.0: + resolution: {integrity: sha512-Y5bDWKIFEUE7dZrbBbq5SiHWadYC4h3+Q+xBAUNNAqU1VMokleoGGfK92Qsmi+EBOLUBbxrtOCND5BSqQn8NaQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} deprecated: ESLint has built-in support for multithread linting now. This package is no longer needed. hasBin: true @@ -6450,8 +6324,8 @@ packages: eslint-config-prettier: optional: true - eslint-plugin-svelte@3.11.0: - resolution: {integrity: sha512-KliWlkieHyEa65aQIkRwUFfHzT5Cn4u3BQQsu3KlkJOs7c1u7ryn84EWaOjEzilbKgttT4OfBURA8Uc4JBSQIw==} + eslint-plugin-svelte@3.12.3: + resolution: {integrity: sha512-YVNhKsHZeXVvsjZcSMjnce9gO31frICu453p5JjFiXNszHoG9k8WvsA/LAoLi4K8T69G7DIrgg1AqasDJLpgoQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.1 || ^9.0.0 @@ -6482,18 +6356,8 @@ packages: resolution: {integrity: sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - eslint@9.30.1: - resolution: {integrity: sha512-zmxXPNMOXmwm9E0yQLi5uqXHs7uq2UIiqEKo3Gq+3fwo1XrJ+hijAZImyF7hclW3E6oHz43Yk3RP8at6OTKflQ==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - peerDependencies: - jiti: '*' - peerDependenciesMeta: - jiti: - optional: true - - eslint@9.33.0: - resolution: {integrity: sha512-TS9bTNIryDzStCpJN93aC5VRSW3uTx9sClUn4B87pwiCaJh220otoI0X8mJKr+VcPtniMdN8GKjlwgWGUv5ZKA==} + eslint@9.35.0: + resolution: {integrity: sha512-QePbBFMJFjgmlE+cXAlbHZbHpdFVS2E/6vzCy7aKlebddvl1vadiC4JFV5u/wqTkNUwEV8WrQi257jf5f06hrg==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} hasBin: true peerDependencies: @@ -6641,10 +6505,6 @@ packages: extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - external-editor@3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - fabric@6.7.1: resolution: {integrity: sha512-dLxSmIvN4InJf4xOjbl1LFWh8WGOUIYtcuDIGs2IN0Z9lI0zGobfesDauyEhI1+owMLTPCCiEv01rpYXm7g2EQ==} engines: {node: '>=16.20.0'} @@ -6732,10 +6592,6 @@ packages: resolution: {integrity: sha512-ek5xNX2YBYlXhiUXui3D/BXa3LdqPmoLJ7rqEx2bKJ7EAUEfmXgW0Das7Dc6Nr9MvqaOnIqiPV0mZk/r/UpNAg==} engines: {node: '>=20'} - file-type@3.9.0: - resolution: {integrity: sha512-RLoqTXE8/vPmMuTI88DAzhMYC99I8BWv7zYP4A1puo5HIjEJ5EX48ighy4ZyKMG9EDXxBgW6e++cn7d1xuFghA==} - engines: {node: '>=0.10.0'} - fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -6793,9 +6649,6 @@ packages: debug: optional: true - foreach@2.0.6: - resolution: {integrity: sha512-k6GAGDyqLe9JaebCsFCoudPPWfihKu8pylYXRlqP1J7ms39iPoTtk2fviNglIeQEwdh0bQeKJ01ZPyuyQvKzwg==} - foreground-child@3.3.1: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} @@ -6819,9 +6672,6 @@ packages: resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==} engines: {node: '>=0.4.x'} - formidable@2.1.5: - resolution: {integrity: sha512-Oz5Hwvwak/DCaXVVUtPn4oLMLLy1CdclLKO1LFgU7XzDpVMUU5UjlSLpGMocyQNNk8F6IJW9M/YdooSn2MRI+Q==} - formidable@3.5.4: resolution: {integrity: sha512-YikH+7CUTOtP44ZTnUhR7Ic2UASBPOqmaRkRKxRbywPTe5VxF7RRCck4af9wutiZ/QKM5nME9Bie2fFaPz5Gug==} engines: {node: '>=14.0.0'} @@ -6916,8 +6766,8 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.3.0: - resolution: {integrity: sha512-vpeMIQKxczTD/0s2CdEWHcb0eeJe6TFjxb+J5xgX7hScxqrGuyjmv4c1D4A/gelKfyox0gJJwIHF+fLjeaM8kQ==} + get-east-asian-width@1.4.0: + resolution: {integrity: sha512-QZjmEOC+IT1uk6Rx0sX22V6uHWVwbdbxf1faPqJ1QhLdGgsRGCZoyaQBm/piRdJy/D2um6hM1UP7ZEeQ4EkP+Q==} engines: {node: '>=18'} get-intrinsic@1.3.0: @@ -6935,10 +6785,6 @@ packages: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} - get-stdin@5.0.1: - resolution: {integrity: sha512-jZV7n6jGE3Gt7fgSTJoz91Ak5MuTLwMwkoYdjxuJ/AmjIsE1UC03y/IWkZCQGEvVNS9qoRNwy5BCqxImv0FVeA==} - engines: {node: '>=0.12.0'} - get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -6989,8 +6835,8 @@ packages: resolution: {integrity: sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg==} engines: {node: '>=18'} - globals@16.3.0: - resolution: {integrity: sha512-bqWEnJ1Nt3neqx2q5SFfGS8r/ahumIakg3HcwtNlrVlwXIeNumWn/c7Pn/wKzGhf6SaW6H6uWXLqC30STCMchQ==} + globals@16.4.0: + resolution: {integrity: sha512-ob/2LcVVaVGCYN+r14cnwnoDPUufjiYgSqRhiFD0Q1iI4Odora5RE8Iv1D24hAz5oMophRGkGz+yuvQmmUMnMw==} engines: {node: '>=18'} globalyzer@0.1.0: @@ -7024,9 +6870,6 @@ packages: graphemer@1.4.0: resolution: {integrity: sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==} - graphlib@2.1.8: - resolution: {integrity: sha512-jcLLfkpoVGmH7/InMC/1hIvOPSUh38oJtGhvrOFGzioE1DZ+0YW16RgmOJhHiuWTvGiJQ9Z1Ik43JvkRPRvE+A==} - gray-matter@4.0.3: resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==} engines: {node: '>=6.0'} @@ -7095,9 +6938,6 @@ packages: hast-util-parse-selector@2.2.5: resolution: {integrity: sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==} - hast-util-parse-selector@3.1.1: - resolution: {integrity: sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==} - hast-util-parse-selector@4.0.0: resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==} @@ -7131,9 +6971,6 @@ packages: hastscript@6.0.0: resolution: {integrity: sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==} - hastscript@7.2.0: - resolution: {integrity: sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==} - hastscript@9.0.1: resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} @@ -7253,12 +7090,6 @@ packages: resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} engines: {node: '>=8.0.0'} - http-reasons@0.1.0: - resolution: {integrity: sha512-P6kYh0lKZ+y29T2Gqz+RlC9WBLhKe8kDmcJ+A+611jFfxdPsbMRQ5aNmFRM3lENqFkK+HTTL+tlQviAiv0AbLQ==} - - http2-client@1.3.5: - resolution: {integrity: sha512-EC2utToWl4RKfs5zd36Mxq7nzHHBuomZboI0yYL6Y0RmBgT7Sgkq4rQ0ezFTYoIsSs7Tm9SJe+o2FcAg6GBhGA==} - http2-wrapper@2.2.1: resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} engines: {node: '>=10.19.0'} @@ -7287,6 +7118,10 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + iconv-lite@0.7.0: + resolution: {integrity: sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==} + engines: {node: '>=0.10.0'} + icss-utils@5.1.0: resolution: {integrity: sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==} engines: {node: ^10 || ^12 || >= 14} @@ -7316,9 +7151,6 @@ packages: immediate@3.3.0: resolution: {integrity: sha512-HR7EVodfFUdQCTIeySw+WDRFJlPcLOJbXfwwZ7Oom6tjsvZ3bOkCDJHehQC3nxJrv7+f9XecwazynjU8e4Vw3Q==} - immer@9.0.21: - resolution: {integrity: sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==} - import-fresh@3.3.1: resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==} engines: {node: '>=6'} @@ -7366,18 +7198,14 @@ packages: inline-style-parser@0.2.4: resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} - inquirer@8.2.6: - resolution: {integrity: sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==} + inquirer@8.2.7: + resolution: {integrity: sha512-UjOaSel/iddGZJ5xP/Eixh6dY1XghiBw4XK13rCCIJcJfyhhoul/7KhLLUGtebEj6GDYM6Vnx/mVsjx2L/mFIA==} engines: {node: '>=12.0.0'} internmap@2.0.3: resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==} engines: {node: '>=12'} - interpret@1.4.0: - resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} - engines: {node: '>= 0.10'} - intl-messageformat@10.7.16: resolution: {integrity: sha512-UmdmHUmp5CIKKjSoE10la5yfU+AYJAaiYLsodbjL4lji83JNvgOQUjGaGhGrpFCb0Uh7sl7qfP1IyILa8Z40ug==} @@ -7631,8 +7459,8 @@ packages: jose@5.10.0: resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} - jose@6.0.12: - resolution: {integrity: sha512-T8xypXs8CpmiIi78k0E+Lk7T2zlK4zDyg+o1CZ4AkOHgDg98ogdP2BeZ61lTFKFyoEwJ9RgAgN+SdM3iPgNonQ==} + jose@6.1.0: + resolution: {integrity: sha512-TTQJyoEoKcC1lscpVDCSsVgYzUDg/0Bt3WE//WiTPK6uOCQC2KZS4MpugbMWt/zyjkopgZoXhZuCi00gLudfUA==} js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} @@ -7682,25 +7510,6 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - json-pointer@0.6.2: - resolution: {integrity: sha512-vLWcKbOaXlO+jvRy4qNd+TI1QUPZzfJj1tpJ3vAXDych5XJf93ftpUKe5pKCrzyIIwgBJcOcCVRUfqQP25afBw==} - - json-refs@3.0.15: - resolution: {integrity: sha512-0vOQd9eLNBL18EGl5yYaO44GhixmImes2wiYn9Z3sag3QnehWrYWlB9AFtMxCL2Bj3fyxgDYkxGFEU/chlYssw==} - engines: {node: '>=0.8'} - hasBin: true - - json-schema-compare@0.2.2: - resolution: {integrity: sha512-c4WYmDKyJXhs7WWvAWm3uIYnfyWFoIp+JEoX34rctVvEkMYCPGhXtvmFFXiffBbxfZsvQ0RNnV5H7GvDF5HCqQ==} - - json-schema-merge-allof@0.8.1: - resolution: {integrity: sha512-CTUKmIlPJbsWfzRRnOXz+0MjIqvnleIXwFTzz+t9T86HnYX/Rozria6ZVGLktAU9e+NygNljveP+yxqtQp/Q4w==} - engines: {node: '>=12.0.0'} - - json-schema-resolve-allof@1.5.0: - resolution: {integrity: sha512-Jgn6BQGSLDp3D7bTYrmCbP/p7SRFz5BfpeEJ9A7sXuVADMc14aaDN1a49zqk9D26wwJlcNvjRpT63cz1VgFZeg==} - hasBin: true - json-schema-traverse@0.4.1: resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} @@ -7875,10 +7684,6 @@ packages: lines-and-columns@1.2.4: resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - liquid-json@0.3.1: - resolution: {integrity: sha512-wUayTU8MS827Dam6MxgD72Ui+KOSF+u/eIqpatOtjnvgJ0+mnDq33uC2M7J0tPK+upe/DpUAuK4JUU89iBoNKQ==} - engines: {node: '>=4'} - load-esm@1.0.2: resolution: {integrity: sha512-nVAvWk/jeyrWyXEAs84mpQCYccxRqgKY4OznLuJhJCa0XsPSfdOIr2zvBZEj3IHEHbX97jjscKRRV539bW0Gpw==} engines: {node: '>=13.2.0'} @@ -7972,8 +7777,8 @@ packages: lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} - lru-cache@11.1.0: - resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==} + lru-cache@11.2.1: + resolution: {integrity: sha512-r8LA6i4LP4EeWOhqBaZZjDWwehd1xUJPCJd9Sv300H0ZmcUER4+JPh7bqqZeqs1o5pgtgvXm+d9UGrB5zZGDiQ==} engines: {node: 20 || >=22} lru-cache@5.1.1: @@ -7992,8 +7797,8 @@ packages: resolution: {integrity: sha512-tJLxrKJhO2ukZ5z0gyjY1zPh3Rh88Ej9P7jNrZiHMUXHae1yvI2imgOZtL1TO8TW6biMMKfTtAOoEJANgtWBMQ==} engines: {node: '>=12'} - luxon@3.7.1: - resolution: {integrity: sha512-RkRWjA926cTvz5rAb1BqyWkKbbjzCGchDUIKMCUvNi17j6f6j8uHGDV82Aqcqtzd+icoYpELmG3ksgGiFNNcNg==} + luxon@3.7.2: + resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==} engines: {node: '>=12'} lz-string@1.5.0: @@ -8003,6 +7808,9 @@ packages: magic-string@0.30.17: resolution: {integrity: sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==} + magic-string@0.30.19: + resolution: {integrity: sha512-2N21sPY9Ws53PZvsEpVtNuSW+ScYbQdp4b9qUaL+9QkHUrGFKo56Lg9Emg5s9V/qrtNBmiR01sYhUOwu3H+VOw==} + magicast@0.3.5: resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==} @@ -8022,8 +7830,8 @@ packages: resolution: {integrity: sha512-p8lJFEiqmEQlyv+DQxFAOG/XPWN0Wp7j/Psq93Zywz7qt9CcUKFYDBOoOEKzqe6gudHVJY8/Bhqw6VDpX2lSBg==} engines: {node: '>=6.4.0'} - maplibre-gl@5.6.2: - resolution: {integrity: sha512-SEqYThhUCFf6Lm0TckpgpKnto5u4JsdPYdFJb6g12VtuaFsm3nYdBO+fOmnUYddc8dXihgoGnuXvPPooUcRv5w==} + maplibre-gl@5.7.1: + resolution: {integrity: sha512-iCOQB6W/EGgQx8aU4SyfU5a5/GR2E+ELF92NMsqYfs3x+vnY+8mARmz4gor6XZHCz3tv19mnotVDRlRTMNKyGw==} engines: {node: '>=16.14.0', npm: '>=8.1.0'} mark.js@8.11.1: @@ -8039,11 +7847,6 @@ packages: markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} - marked@11.2.0: - resolution: {integrity: sha512-HR0m3bvu0jAPYiIvLUUQtdg1g6D247//lvcekpHO1WMvbwDlwSkZAX9Lw4F4YHE1T0HaaNve0tuAWuV1UJ6vtw==} - engines: {node: '>= 18'} - hasBin: true - marked@7.0.4: resolution: {integrity: sha512-t8eP0dXRJMtMvBojtkcsA7n48BkauktUKzfkPSCq85ZMTJ0v76Rke4DYz01omYpPTUh4p/f7HePgRo3ebG8+QQ==} engines: {node: '>= 16'} @@ -8291,9 +8094,6 @@ packages: resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} engines: {node: '>= 0.6'} - mime-format@2.0.1: - resolution: {integrity: sha512-XxU3ngPbEnrYnNbIX+lYSaYg0M01v6p2ntd2YaFksTu0vayaw5OJvbdRyWs07EYRlLED5qadUZ+xo+XhOvFhwg==} - mime-types@2.1.18: resolution: {integrity: sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==} engines: {node: '>= 0.6'} @@ -8438,9 +8238,6 @@ packages: module-details-from-path@1.0.4: resolution: {integrity: sha512-EGWKgxALGMgzvxYF1UyGTy0HXX/2vHLkw6+NvDKW2jypWbHpjQuj4UMcqQWXHERJhVGKikolT06G3bcKe4fi7w==} - monaco-editor@0.31.1: - resolution: {integrity: sha512-FYPwxGZAeP6mRRyrr5XTGHD9gRXVjy7GUzF4IPChnyt3fS5WrNxIkS8DNujWf6EQy0Zlzpxw8oTVE+mWI2/D1Q==} - moo@0.5.2: resolution: {integrity: sha512-iSAJLHYKnX41mKcJKjqvnAN9sf0LMDTXDEvFv+ffuRR9a1MIuXLjMNL6EsnDHSkKLTWNqQQ5uo61P4EbU4NU+Q==} @@ -8499,9 +8296,6 @@ packages: engines: {node: ^18 || >=20} hasBin: true - native-promise-only@0.8.1: - resolution: {integrity: sha512-zkVhZUA3y8mbz652WrL5x0fB0ehrBkulWT3TomAQ9iDtyXZvzKeEA6GPxAItBYeNYl5yngKRX612qHOhvMkDeg==} - natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} @@ -8524,12 +8318,8 @@ packages: neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - neotraverse@0.6.15: - resolution: {integrity: sha512-HZpdkco+JeXq0G+WWpMJ4NsX3pqb5O7eR9uGz3FfoFt+LYzU8iRWp49nJtud6hsDoywM8tIrDo3gjgmOqJA8LA==} - engines: {node: '>= 10'} - - nest-commander@3.18.0: - resolution: {integrity: sha512-NWtodOl2aStnApWp9oajCoJW71lqN0CCjf9ygOWxpXnG3o4nQ8ZO5CgrExfVw2+0CVC877hr0rFR7FSu2rypGg==} + nest-commander@3.19.1: + resolution: {integrity: sha512-Pn6xcMeSnidlzZozNLnbe7P4TqXL7g0JuxqTAtJ89KT4S63ntJZKtRU6g/56h/aHUQa+m98j/c9OxBSduK7EPg==} peerDependencies: '@nestjs/common': ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 '@nestjs/core': ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 @@ -8582,10 +8372,6 @@ packages: resolution: {integrity: sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==} engines: {node: '>=18'} - node-fetch-h2@2.3.0: - resolution: {integrity: sha512-ofRW94Ab0T4AOh5Fk8t0h8OBWrmjb0SSB20xh1H8YnPV9EJ+f5AMoYSUQ2zgJ4Iq2HAK0I2l5/Nequ8YzFS3Hg==} - engines: {node: 4.x || >=6.0.0} - node-fetch@2.7.0: resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} engines: {node: 4.x || >=6.0.0} @@ -8607,19 +8393,16 @@ packages: resolution: {integrity: sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ==} hasBin: true - node-gyp@11.3.0: - resolution: {integrity: sha512-9J0+C+2nt3WFuui/mC46z2XCZ21/cKlFDuywULmseD/LlmnOrSeEAE4c/1jw6aybXLmpZnQY3/LmOJfgyHIcng==} + node-gyp@11.4.2: + resolution: {integrity: sha512-3gD+6zsrLQH7DyYOUIutaauuXrcyxeTPyQuZQCQoNPZMHMMS5m4y0xclNpvYzoK3VNzuyxT6eF4mkIL4WSZ1eQ==} engines: {node: ^18.17.0 || >=20.5.0} hasBin: true - node-readfiles@0.2.0: - resolution: {integrity: sha512-SU00ZarexNlE4Rjdm83vglt5Y9yiQ+XI1XpflWlb7q7UTN1JUItm69xMeiQCTxtTfnzt+83T8Cx+vI2ED++VDA==} - node-releases@2.0.19: resolution: {integrity: sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==} - nodemailer@7.0.5: - resolution: {integrity: sha512-nsrh2lO3j4GkLLXoeEksAMgAOqxOv6QumNRVQTJwKH4nuiww6iC2y7GyANs9kRAxCexg3+lTWM3PZ91iLlVjfg==} + nodemailer@7.0.6: + resolution: {integrity: sha512-F44uVzgwo49xboqbFgBGkRaiMgtoBrBEWCVincJPK9+S9Adkzt/wXCLKbf7dxucmxfTI5gHGB+bEmdyzN6QKjw==} engines: {node: '>=6.0.0'} nopt@1.0.10: @@ -8682,28 +8465,8 @@ packages: engines: {node: ^14.16.0 || >=16.10.0} hasBin: true - oas-kit-common@1.0.8: - resolution: {integrity: sha512-pJTS2+T0oGIwgjGpw7sIRU8RQMcUoKCDWFLdBqKB2BNmGpbBMH2sdqAaOXUg8OzonZHU0L7vfJu1mJFEiYDWOQ==} - - oas-linter@3.2.2: - resolution: {integrity: sha512-KEGjPDVoU5K6swgo9hJVA/qYGlwfbFx+Kg2QB/kd7rzV5N8N5Mg6PlsoCMohVnQmo+pzJap/F610qTodKzecGQ==} - - oas-resolver-browser@2.5.6: - resolution: {integrity: sha512-Jw5elT/kwUJrnGaVuRWe1D7hmnYWB8rfDDjBnpQ+RYY/dzAewGXeTexXzt4fGEo6PUE4eqKqPWF79MZxxvMppA==} - hasBin: true - - oas-resolver@2.5.6: - resolution: {integrity: sha512-Yx5PWQNZomfEhPPOphFbZKi9W93CocQj18NlD2Pa4GWZzdZpSJvYwoiuurRI7m3SpcChrnO08hkuQDL3FGsVFQ==} - hasBin: true - - oas-schema-walker@1.1.5: - resolution: {integrity: sha512-2yucenq1a9YPmeNExoUa9Qwrt9RFkjqaMAA1X+U7sbb0AqBeTIdMHky9SQQ6iN94bO5NW0W4TRYXerG+BdAvAQ==} - - oas-validator@5.0.8: - resolution: {integrity: sha512-cu20/HE5N5HKqVygs3dt94eYJfBi0TsZvPVXDhbXQHiEityDN+RROTleefoKRKKJ9dFAF2JBkDHgvWj0sjKGmw==} - - oauth4webapi@3.7.0: - resolution: {integrity: sha512-Q52wTPUWPsVLVVmTViXPQFMW2h2xv2jnDGxypjpelCFKaOjLsm7AxYuOk1oQgFm95VNDbuggasu9htXrz6XwKw==} + oauth4webapi@3.8.1: + resolution: {integrity: sha512-olkZDELNycOWQf9LrsELFq8n05LwJgV8UkrS0cburk6FOwf8GvLam+YB+Uj5Qvryee+vwWOfQVeI5Vm0MVg7SA==} object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} @@ -8731,8 +8494,8 @@ packages: obuf@1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - oidc-provider@9.4.1: - resolution: {integrity: sha512-luNQK3MBTN6oRliEm+sWVzne8UR+e+Zo0qCWzsY7mhdUNOcjjoe5joFgJrW4i/6mEMYdeWUAPiTGrvggCsyMgQ==} + oidc-provider@9.5.1: + resolution: {integrity: sha512-19Wa4bfz3reoudxrY7sF5SeQKxe5b3dY8hWzQdnBGS87rH0BoYoDDUDRTYciJMN3oI6S02C9xM6vuaHtoZ48eA==} on-finished@2.4.1: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} @@ -8757,17 +8520,12 @@ packages: resolution: {integrity: sha512-7x81NCL719oNbsq/3mh+hVrAWmFuEYUqrq/Iw3kUzH8ReypT9QQ0BLoJS7/G9k6N81XjW4qHWtjWwe/9eLy1EQ==} engines: {node: '>=12'} - openapi-to-postmanv2@4.25.0: - resolution: {integrity: sha512-sIymbkQby0gzxt2Yez8YKB6hoISEel05XwGwNrAhr6+vxJWXNxkmssQc/8UEtVkuJ9ZfUXLkip9PYACIpfPDWg==} - engines: {node: '>=8'} - hasBin: true - opener@1.5.2: resolution: {integrity: sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==} hasBin: true - openid-client@6.6.4: - resolution: {integrity: sha512-PLWVhRksRnNH05sqeuCX/PR+1J70NyZcAcPske+FeF732KKONd3v0p5Utx1ro1iLfCglH8B3/+dA1vqIHDoIiA==} + openid-client@6.8.0: + resolution: {integrity: sha512-oG1d1nAVhIIE+JSjLS+7E9wY1QOJpZltkzlJdbZ7kEn7Hp3hqur2TEeQ8gLOHoHkhbRAGZJKoOnEQcLOQJuIyg==} optionator@0.9.4: resolution: {integrity: sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==} @@ -8781,10 +8539,6 @@ packages: resolution: {integrity: sha512-weP+BZ8MVNnlCm8c0Qdc1WSWq4Qn7I+9CJGm7Qali6g44e/PUzbjNqJX5NJ9ljlNMosfJvg1fKEGILklK9cwnw==} engines: {node: '>=18'} - os-tmpdir@1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - p-cancelable@3.0.0: resolution: {integrity: sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==} engines: {node: '>=12.20'} @@ -8887,9 +8641,6 @@ packages: pascal-case@3.1.2: resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} - path-browserify@1.0.1: - resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} - path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -8909,9 +8660,6 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - path-loader@1.0.12: - resolution: {integrity: sha512-n7oDG8B+k/p818uweWrOixY9/Dsr89o2TkCm6tOTex3fpdo2+BFDgR+KpB37mGKBRsBAlR8CIJMFN0OEy/7hIQ==} - path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -8939,13 +8687,13 @@ packages: resolution: {integrity: sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==} engines: {node: '>=16'} + path-to-regexp@8.3.0: + resolution: {integrity: sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} - path@0.12.7: - resolution: {integrity: sha512-aXXC6s+1w7otVF9UletFkFcDsJeO7lSZBPUQhtb5O0xJe8LtYhj/GxldoL09bBj9+ZmE2hNoHqQSFMN5fikh4Q==} - pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -9025,16 +8773,16 @@ packages: resolution: {integrity: sha512-Ie9z/WINcxxLp27BKOCHGde4ITq9UklYKDzVo1nhk5sqGEXU3FpkwP5GM2voTGJkGd9B3Otl+Q4uwSOeSUtOBA==} engines: {node: '>=14.16'} - pkg-types@2.2.0: - resolution: {integrity: sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ==} + pkg-types@2.3.0: + resolution: {integrity: sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==} - playwright-core@1.54.2: - resolution: {integrity: sha512-n5r4HFbMmWsB4twG7tJLDN9gmBUeSPcsBZiWSE4DnYz9mJMAFqr2ID7+eGC9kpEnxExJ1epttwR59LEWCk8mtA==} + playwright-core@1.55.0: + resolution: {integrity: sha512-GvZs4vU3U5ro2nZpeiwyb0zuFaqb9sUiAJuyrWpcGouD8y9/HLgGbNRjIph7zU9D3hnPaisMl9zG9CgFi/biIg==} engines: {node: '>=18'} hasBin: true - playwright@1.54.2: - resolution: {integrity: sha512-Hu/BMoA1NAdRUuulyvQC0pEqZ4vQbGfn8f7wPXcnqQmM+zct9UliKxsIkLNmz/ku7LElUNqmaiv1TG/aL5ACsw==} + playwright@1.55.0: + resolution: {integrity: sha512-sdCWStblvV1YU909Xqx0DhOjPZE4/5lJsIS84IfN9dAZfcl/CIZ5O8l3o0j7hPMjDvqoTF8ZUcc+i/GL5erstA==} engines: {node: '>=18'} hasBin: true @@ -9202,8 +8950,8 @@ packages: peerDependencies: postcss: ^8.0.0 - postcss-js@4.0.1: - resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==} + postcss-js@4.1.0: + resolution: {integrity: sha512-oIAOTqgIo7q2EOwbhb8UalYePMvYoIeRY2YKntdpFQXNosSu3vLrniGgmH9OKs/qAkfoj5oB3le/7mINW1LCfw==} engines: {node: ^12 || ^14 || >= 16} peerDependencies: postcss: ^8.4.21 @@ -9524,18 +9272,6 @@ packages: resolution: {integrity: sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw==} engines: {node: '>=12'} - postman-code-generators@1.14.2: - resolution: {integrity: sha512-qZAyyowfQAFE4MSCu2KtMGGQE/+oG1JhMZMJNMdZHYCSfQiVVeKxgk3oI4+KJ3d1y5rrm2D6C6x+Z+7iyqm+fA==} - engines: {node: '>=12'} - - postman-collection@4.5.0: - resolution: {integrity: sha512-152JSW9pdbaoJihwjc7Q8lc3nPg/PC9lPTHdMk7SHnHhu/GBJB7b2yb9zG7Qua578+3PxkQ/HYBuXpDSvsf7GQ==} - engines: {node: '>=10'} - - postman-url-encoder@3.0.5: - resolution: {integrity: sha512-jOrdVvzUXBC7C+9gkIkpDJ3HIxOHTIqjpQ4C1EMt1ZGeMvSEpbFCKq23DEfgsj46vMnDgyQf+1ZLp2Wm+bKSsA==} - engines: {node: '>=10'} - potpack@1.0.2: resolution: {integrity: sha512-choctRBIV9EMT9WGAZHn3V7t0Z2pMQyl0EZE6pFc/6ml3ssw7Dlf/oAOvFwjm1HVsqfQN8GfeFyJ+d8tRzqueQ==} @@ -9689,8 +9425,8 @@ packages: resolution: {integrity: sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==} engines: {node: '>=10'} - quick-lru@7.0.1: - resolution: {integrity: sha512-kLjThirJMkWKutUKbZ8ViqFc09tDQhlbQo2MNuVeLWbRauqYP96Sm6nzlQ24F0HFjUNZ4i9+AgldJ9H6DZXi7g==} + quick-lru@7.2.0: + resolution: {integrity: sha512-fG4L8TlD1CacJiGMGPxM1/K8l/GaKL2eFQZ6DWAjxZYxSf07DkumbC/Mhh+u/NHvxkfQVL25By0pxBS8QE9ZrQ==} engines: {node: '>=18'} quickselect@2.0.0: @@ -9721,9 +9457,9 @@ packages: resolution: {integrity: sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==} engines: {node: '>= 0.8'} - raw-body@3.0.0: - resolution: {integrity: sha512-RmkhL8CAyCRPXCE28MMH0z2PNWQBNk2Q09ZdxM9IOOXwxwZbN+qbWaatPkdkWIKL2ZVDImrN/pK5HTRz2PcS4g==} - engines: {node: '>= 0.8'} + raw-body@3.0.1: + resolution: {integrity: sha512-9G8cA+tuMS75+6G/TzW8OtLzmBDMo8p1JRxN5AZ+LAp8uxGA8V8GZm4GQ4/N5QNQEnLmg6SS7wyuSmbKepiKqA==} + engines: {node: '>= 0.10'} raw-loader@4.0.2: resolution: {integrity: sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA==} @@ -9745,8 +9481,8 @@ packages: peerDependencies: react: ^19.1.1 - react-email@4.2.8: - resolution: {integrity: sha512-Eqzs/xZnS881oghPO/4CQ1cULyESuUhEjfYboXmYNOokXnJ6QP5GKKJZ6zjkg9SnKXxSrIxSo5PxzCI5jReJMA==} + react-email@4.2.11: + resolution: {integrity: sha512-/7TXRgsTrXcV1u7kc5ZXDVlPvZqEBaYcflMhE2FgWIJh3OHLjj2FqctFTgYcp0iwzbR59a7gzJLmSKyD0wYJEQ==} engines: {node: '>=18.0.0'} hasBin: true @@ -9772,24 +9508,9 @@ packages: react-loadable: '*' webpack: '>=4.41.1 || 5.x' - react-magic-dropzone@1.0.1: - resolution: {integrity: sha512-0BIROPARmXHpk4AS3eWBOsewxoM5ndk2psYP/JmbCq8tz3uR2LIV1XiroZ9PKrmDRMctpW+TvsBCtWasuS8vFA==} - react-promise-suspense@0.3.4: resolution: {integrity: sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ==} - react-redux@7.2.9: - resolution: {integrity: sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==} - peerDependencies: - react: ^16.8.3 || ^17 || ^18 - react-dom: '*' - react-native: '*' - peerDependenciesMeta: - react-dom: - optional: true - react-native: - optional: true - react-router-config@5.1.1: resolution: {integrity: sha512-DuanZjaD8mQp1ppHjgnnUnyOlqYXZVjnov/JzFhjLEwd3Z4dYjMSnqrEzzGThH47vpCOqPPwJM2FtthLeJ8Pbg==} peerDependencies: @@ -9839,10 +9560,6 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} - rechoir@0.6.2: - resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} - engines: {node: '>= 0.10'} - recma-build-jsx@1.0.0: resolution: {integrity: sha512-8GtdyqaBcDfva+GUKDr3nev3VpKAhup1+RvkMvUxURHpW7QyIvk9F5wz7Vzo06CEMSilw6uArgRqhpiUcWp8ew==} @@ -9867,29 +9584,9 @@ packages: resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} engines: {node: '>=4'} - redux-devtools-extension@2.13.9: - resolution: {integrity: sha512-cNJ8Q/EtjhQaZ71c8I9+BPySIBVEKssbPpskBfsXqb8HJ002A3KRVHfeRzwRo6mGPqsm7XuHTqNSNeS1Khig0A==} - deprecated: Package moved to @redux-devtools/extension. - peerDependencies: - redux: ^3.1.0 || ^4.0.0 - - redux-thunk@2.4.2: - resolution: {integrity: sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==} - peerDependencies: - redux: ^4 - - redux@4.2.1: - resolution: {integrity: sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==} - reflect-metadata@0.2.2: resolution: {integrity: sha512-urBwgfrvVP/eAyXx4hluJivBKzuEbSQs9rKWCrCkbSxNv8mxPcUZKeuoF3Uy4mJl3Lwprp6yy5/39VWigZ4K6Q==} - refractor@4.9.0: - resolution: {integrity: sha512-nEG1SPXFoGGx+dcjftjv8cAjEusIh6ED1xhf5DG3C0x/k+rmZ2duKnc3QLpt6qeHv5fPb8uwN3VWN2BT7fr3Og==} - - reftools@1.1.9: - resolution: {integrity: sha512-OVede/NQE13xBQ+ob5CKd5KyeJYU2YInb1bmV4nRoOfquZPkAkxuOXicSe1PvqIuZZ4kD13sPKBbR7UFDmli6w==} - regenerate-unicode-properties@10.2.0: resolution: {integrity: sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA==} engines: {node: '>=4'} @@ -9986,9 +9683,6 @@ packages: requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - reselect@4.1.8: - resolution: {integrity: sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==} - resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} @@ -10166,11 +9860,6 @@ packages: resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==} hasBin: true - semver@7.6.3: - resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==} - engines: {node: '>=10'} - hasBin: true - semver@7.7.2: resolution: {integrity: sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==} engines: {node: '>=10'} @@ -10245,29 +9934,6 @@ packages: resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==} engines: {node: '>= 0.4'} - shelljs@0.8.5: - resolution: {integrity: sha512-TiwcRcrkhHvbrZbnRcFYMLl30Dfov3HKqzp5tO5b4pt6G/SezKcYhmDg15zXVBswHmctSAQKznqNW2LO5tTDow==} - engines: {node: '>=4'} - hasBin: true - - should-equal@2.0.0: - resolution: {integrity: sha512-ZP36TMrK9euEuWQYBig9W55WPC7uo37qzAEmbjHz4gfyuXrEUgF8cUvQVO+w+d3OMfPvSRQJ22lSm8MQJ43LTA==} - - should-format@3.0.3: - resolution: {integrity: sha512-hZ58adtulAk0gKtua7QxevgUaXTTXxIi8t41L3zo9AHvjXO1/7sdLECuHeIN2SRtYXpNkmhoUP2pdeWgricQ+Q==} - - should-type-adaptors@1.1.0: - resolution: {integrity: sha512-JA4hdoLnN+kebEp2Vs8eBe9g7uy0zbRo+RMcU0EsNy+R+k049Ki+N5tT5Jagst2g7EAja+euFuoXFCa8vIklfA==} - - should-type@1.4.0: - resolution: {integrity: sha512-MdAsTu3n25yDbIe1NeN69G4n6mUnJGtSJHygX3+oN0ZbO3DTiATnf7XnYJdGT42JCXurTb1JI0qOBR65shvhPQ==} - - should-util@1.0.1: - resolution: {integrity: sha512-oXF8tfxx5cDk8r2kYqlkUJzZpDBqVY/II2WhvU0n9Y3XYvAYRmeaf1PvvIvTgPnv4KJ+ES5M0PyDq5Jp+Ygy2g==} - - should@13.2.3: - resolution: {integrity: sha512-ggLesLtu2xp+ZxI+ysJTmNjh2U0TsC+rQ/pfED9bUZZ4DKefP27D+7YJVVTvKsmjLpIi9jAa7itwDGkDDmt1GQ==} - side-channel-list@1.0.0: resolution: {integrity: sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==} engines: {node: '>= 0.4'} @@ -10311,8 +9977,8 @@ packages: resolution: {integrity: sha512-94Bdh3cC2PKrbgSOUqTiGPWVZeSiXfKOVZNJniWoqrWrRkB1CJzBU3NEbiTsPcYy1lDsANA/THzS+9WBiy5nfQ==} engines: {node: '>= 10'} - sirv@3.0.1: - resolution: {integrity: sha512-FoqMu0NCGBLCcAkS1qA+XJIQTR6/JHfQXl+uGteNCQ76T91DMUjPa9xfmeqMY3z80nLSg9yQmNjK0Px6RWsH/A==} + sirv@3.0.2: + resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} engines: {node: '>=18'} sisteransi@1.0.5: @@ -10413,8 +10079,8 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - sql-formatter@15.6.6: - resolution: {integrity: sha512-bZydXEXhaNDQBr8xYHC3a8thwcaMuTBp0CkKGjwGYDsIB26tnlWeWPwJtSQ0TEwiJcz9iJJON5mFPkx7XroHcg==} + sql-formatter@15.6.9: + resolution: {integrity: sha512-r9VKnkRfKW7jbhTgytwbM+JqmFclQYN9L58Z3UTktuy9V1f1Y+rGK3t70Truh2wIOJzvZkzobAQ2PwGjjXsr6Q==} hasBin: true srcset@4.0.0: @@ -10438,9 +10104,6 @@ packages: standard-as-callback@2.1.0: resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} - state-local@1.0.7: - resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==} - statuses@1.5.0: resolution: {integrity: sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==} engines: {node: '>= 0.6'} @@ -10499,8 +10162,8 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - strip-ansi@7.1.0: - resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==} + strip-ansi@7.1.2: + resolution: {integrity: sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==} engines: {node: '>=12'} strip-bom-string@1.0.0: @@ -10534,9 +10197,6 @@ packages: strip-literal@3.0.0: resolution: {integrity: sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==} - striptags@3.2.0: - resolution: {integrity: sha512-g45ZOGzHDMe2bdYMdIvdAfCQkCTDMGBazSw1ypMowwGIee7ZQ5dU0rBJ8Jqgl+jAKIv4dbeE1jscZq9wid1Tkw==} - strnum@2.1.1: resolution: {integrity: sha512-7ZvoFTiCnGxBtDqJ//Cu6fWtZtc7Y3x+QOirG15wztbdngGSkht27o2pyGWrVy0b4WAy3jbKmnoK6g5VlVNUUw==} @@ -10565,11 +10225,6 @@ packages: resolution: {integrity: sha512-y/hkYGeXAj7wUMjxRbB21g/l6aAEituGXM9Rwl4o20+SX3e8YOSV6BxFXl+dL3Uk0mjSL3kCbNkwURm8/gEDig==} engines: {node: '>=14.18.0'} - superagent@7.1.6: - resolution: {integrity: sha512-gZkVCQR1gy/oUXr+kxJMLDjla434KmSOKbx5iGD30Ql+AkJQ/YlPKECJy2nhqOsHLjGHzoDTXNSjhnvWhzKk7g==} - engines: {node: '>=6.4.0 <13 || >=14'} - deprecated: Please upgrade to superagent v10.2.2+, see release notes at https://github.com/forwardemail/superagent/releases/tag/v10.2.2 - maintenance is supported by Forward Email @ https://forwardemail.net - supercluster@7.1.5: resolution: {integrity: sha512-EulshI3pGUM66o6ZdH3ReiFcvHpM3vAigyK+vcxdjpJyEbIIrtbmBdY23mGgnI24uXiGFvrGq9Gkum/8U7vJWg==} @@ -10600,8 +10255,8 @@ packages: svelte: ^4.0.0 || ^5.0.0-next.0 typescript: '>=5.0.0' - svelte-eslint-parser@1.3.1: - resolution: {integrity: sha512-0Iztj5vcOVOVkhy1pbo5uA9r+d3yaVoE5XPc9eABIWDOSJZ2mOsZ4D+t45rphWCOr0uMw3jtSG2fh2e7GvKnPg==} + svelte-eslint-parser@1.3.2: + resolution: {integrity: sha512-whla4VlUbwJidn/bNyC3Ho3pBrXnR2CBEkuJwtaURW+wfwgKHPaYtZAmwAkp6HWWKCw1ILZL6iKsFdVY11rpDA==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: svelte: ^3.37.0 || ^4.0.0 || ^5.0.0 @@ -10609,8 +10264,8 @@ packages: svelte: optional: true - svelte-gestures@5.1.4: - resolution: {integrity: sha512-gfSO/GqWLu9nRMCz12jqdyA0+NTsojYcIBcRqZjwWrpQbqMXr0zWPFpZBtzfYbRHtuFxZImMZp9MrVaFCYbhDg==} + svelte-gestures@5.2.2: + resolution: {integrity: sha512-Y+chXPaSx8OsPoFppUwPk8PJzgrZ7xoDJKXeiEc7JBqyKKzXer9hlf8F9O34eFuAWB4/WQEvccACvyBplESL7A==} svelte-i18n@4.0.1: resolution: {integrity: sha512-jaykGlGT5PUaaq04JWbJREvivlCnALtT+m87Kbm0fxyYHynkQaxQMnIKHLm2WeIuBRoljzwgyvz0Z6/CMwfdmQ==} @@ -10619,8 +10274,8 @@ packages: peerDependencies: svelte: ^3 || ^4 || ^5 - svelte-maplibre@1.2.0: - resolution: {integrity: sha512-JKYzL0glnqCJ7LwkdDAMb3jdZdFl8ZDHEZyc043BV624kG9ZVaXlIPgjb8sNktqx1D0rQBNrYNt5rR4XszNCiQ==} + svelte-maplibre@1.2.1: + resolution: {integrity: sha512-IVkbc54hQXznyaiFN69RIdjqbLHriNYPVEo1DQMtWSm1kLovrt/aZuhV4eOoZKn6wIvY2Vz34jXPS33f/d/GNw==} peerDependencies: '@deck.gl/core': ^9 '@deck.gl/layers': ^9 @@ -10651,8 +10306,8 @@ packages: peerDependencies: svelte: ^5.30.2 - svelte@5.35.5: - resolution: {integrity: sha512-KuRvI82rhh0RMz1EKsUJD96gZyHJ+h2+8zrwO8iqE/p/CmcNKvIItDUAeUePhuCDgtegDJmF8IKThbHIfmTgTA==} + svelte@5.38.10: + resolution: {integrity: sha512-UY+OhrWK7WI22bCZ00P/M3HtyWgwJPi9IxSRkoAE2MeAy6kl7ZlZWJZ8RaB+X4KD/G+wjis+cGVnVYaoqbzBqg==} engines: {node: '>=18'} svg-parser@2.0.4: @@ -10666,10 +10321,6 @@ packages: swagger-ui-dist@5.21.0: resolution: {integrity: sha512-E0K3AB6HvQd8yQNSMR7eE5bk+323AUxjtCz/4ZNKiahOlPhPJxqn3UPIGs00cyY/dhrTDJ61L7C/a8u6zhGrZg==} - swagger2openapi@7.0.8: - resolution: {integrity: sha512-upi/0ZGkYgEcLeGieoz8gT74oWHA0E7JivX7aN9mAf+Tc7BQoRBvnIGHoPDw+f9TXTW4s6kGYCZJtauP6OYp7g==} - hasBin: true - symbol-observable@4.0.0: resolution: {integrity: sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==} engines: {node: '>=0.10'} @@ -10725,8 +10376,8 @@ packages: engines: {node: '>=14.0.0'} hasBin: true - tailwindcss@4.1.12: - resolution: {integrity: sha512-DzFtxOi+7NsFf7DBtI3BJsynR+0Yp6etH+nRPTbpWnS2pZBaSksv/JGctNwSWzbFjp0vxSqknaUylseZqMDGrA==} + tailwindcss@4.1.13: + resolution: {integrity: sha512-i+zidfmTqtwquj4hMEwdjshYYgMbOrPzb9a0M3ZgNa0JMoZeFC6bxZvO8yr8ozS6ix2SDz0+mvryPeBs2TFE+w==} tapable@2.2.2: resolution: {integrity: sha512-Re10+NauLTMCudc7T5WLFLAwDhQ0JWdrMK+9B2M8zR5hRExKmsRDCBA7/aV/pNJFltmBFO5BAMlQFi/vq3nKOg==} @@ -10795,12 +10446,12 @@ packages: thenify@3.3.1: resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==} - three@0.175.0: - resolution: {integrity: sha512-nNE3pnTHxXN/Phw768u0Grr7W4+rumGg/H6PgeseNJojkJtmeHJfZWi41Gp2mpXl1pg1pf1zjwR4McM1jTqkpg==} - three@0.179.1: resolution: {integrity: sha512-5y/elSIQbrvKOISxpwXCR4sQqHtGiOI+MKLc3SsBdDXA2hz3Mdp3X59aUp8DyybMa34aeBwbFTpdoLJaUDEWSw==} + three@0.180.0: + resolution: {integrity: sha512-o+qycAMZrh+TsE01GqWUxUIKR1AL0S8pq7zDkYOQw8GqfX8b8VoCKYUoHbhiX5j+7hr8XsuHDVU6+gkQJQKg9w==} + through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} @@ -10858,10 +10509,6 @@ packages: resolution: {integrity: sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==} hasBin: true - tmp@0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - tmp@0.2.5: resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} engines: {node: '>=14.14'} @@ -10990,8 +10637,8 @@ packages: typedarray@0.0.6: resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - typescript-eslint@8.39.1: - resolution: {integrity: sha512-GDUv6/NDYngUlNvwaHM1RamYftxf782IyEDbdj3SeaIHHv8fNQVRC++fITT7kUJV/5rIA/tkoRSSskt6osEfqg==} + typescript-eslint@8.43.0: + resolution: {integrity: sha512-FyRGJKUGvcFekRRcBKFBlAhnp4Ng8rhe8tuvvkR9OiU0gfd4vyvTRQHEckO6VDlH57jbeUQem2IpqPq9kLJH+w==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} peerDependencies: eslint: ^8.57.0 || ^9.0.0 @@ -11010,8 +10657,8 @@ packages: ua-is-frozen@0.1.2: resolution: {integrity: sha512-RwKDW2p3iyWn4UbaxpP2+VxwqXh0jpvdxsYpZ5j/MLLiQOfbsV5shpgQiw93+KMYQPcteeMQ289MaAFzs3G9pw==} - ua-parser-js@2.0.4: - resolution: {integrity: sha512-XiBOnM/UpUq21ZZ91q2AVDOnGROE6UQd37WrO9WBgw4u2eGvUCNOheMmZ3EfEUj7DLHr8tre+Um/436Of/Vwzg==} + ua-parser-js@2.0.5: + resolution: {integrity: sha512-sZErtx3rhpvZQanWW5umau4o/snfoLqRcQwQIZ54377WtRzIecnIKvjpkd5JwPcSUMglGnbIgcsQBGAbdi3S9Q==} hasBin: true uglify-js@3.19.3: @@ -11037,11 +10684,11 @@ packages: undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} - undici-types@7.10.0: - resolution: {integrity: sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==} + undici-types@7.12.0: + resolution: {integrity: sha512-goOacqME2GYyOZZfb5Lgtu+1IDmAlAEu5xnD3+xTzS10hT0vzpf0SPjkXwAw9Jm+4n/mQGDP3LO8CPbYROeBfQ==} - undici@7.14.0: - resolution: {integrity: sha512-Vqs8HTzjpQXZeXdpsfChQTlafcMQaaIwnGwLam1wudSSjlJeQ3bw1j+TLPePgrCnCpUXx7Ba5Pdpf5OBih62NQ==} + undici@7.16.0: + resolution: {integrity: sha512-QEg3HPMll0o3t2ourKwOeUAZ159Kn9mx5pnzHRQO8+Wixmh88YdZRiIwat0iNzNNXn0yoEtXJqFpyW7eM8BV7g==} engines: {node: '>=20.18.1'} unicode-canonical-property-names-ecmascript@2.0.1: @@ -11127,13 +10774,13 @@ packages: resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} engines: {node: '>= 0.8'} - unplugin-swc@1.5.5: - resolution: {integrity: sha512-BahYtYvQ/KSgOqHoy5FfQgp/oZNAB7jwERxNeFVeN/PtJhg4fpK/ybj9OwKtqGPseOadS7+TGbq6tH2DmDAYvA==} + unplugin-swc@1.5.7: + resolution: {integrity: sha512-Ng4uuLAodZToA0kQk3+oY8b0C/Q9oV0ohRMixH2nqWMhCF/wNuMYZXZznYpwRLmF7wC36TFIOywBAxCLOReoeg==} peerDependencies: '@swc/core': ^1.2.108 - unplugin@2.3.5: - resolution: {integrity: sha512-RyWSb5AHmGtjjNQ6gIlA67sHOsWpsbWpwDokLwTcejVdOjEkJZh7QKu14J00gDDVSh8kGH4KYC/TNBceXFZhtw==} + unplugin@2.3.10: + resolution: {integrity: sha512-6NCPkv1ClwH+/BGE9QeoTIl09nuiAt0gS28nn1PvYXsGKRwM2TCbFA2QiilmehPDTXIe684k4rZI1yl3A1PCUw==} engines: {node: '>=18.12.0'} update-browserslist-db@1.1.3: @@ -11172,9 +10819,6 @@ packages: util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - util@0.10.4: - resolution: {integrity: sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==} - utila@0.4.0: resolution: {integrity: sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA==} @@ -11206,21 +10850,6 @@ packages: resolution: {integrity: sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==} hasBin: true - validate.io-array@1.0.6: - resolution: {integrity: sha512-DeOy7CnPEziggrOO5CZhVKJw6S3Yi7e9e65R1Nl/RTN1vTQKnzjfvks0/8kQ40FP/dsjRAOd4hxmJ7uLa6vxkg==} - - validate.io-function@1.0.2: - resolution: {integrity: sha512-LlFybRJEriSuBnUhQyG5bwglhh50EpTL2ul23MPIuR1odjO7XaMLFV8vHGwp7AZciFxtYOeiSCT5st+XSPONiQ==} - - validate.io-integer-array@1.0.0: - resolution: {integrity: sha512-mTrMk/1ytQHtCY0oNO3dztafHYyGU88KL+jRxWuzfOmQb+4qqnWmI+gykvGp8usKZOM0H7keJHEbRaFiYA0VrA==} - - validate.io-integer@1.0.5: - resolution: {integrity: sha512-22izsYSLojN/P6bppBqhgUDjCkr5RY2jd+N2a3DCAUey8ydvrZ/OkGvFPR7qfOpwR2LC5p4Ngzxz36g5Vgr/hQ==} - - validate.io-number@1.0.3: - resolution: {integrity: sha512-kRAyotcbNaSYoDnXvb4MHg/0a1egJdLwS6oJ38TJY7aw9n93Fl/3blIXdyYvPOp55CNxywooG/3BcrwNrBpcSg==} - validator@13.15.15: resolution: {integrity: sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==} engines: {node: '>= 0.10'} @@ -11651,8 +11280,8 @@ packages: resolution: {integrity: sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==} engines: {node: '>=18'} - yoctocolors@2.1.1: - resolution: {integrity: sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==} + yoctocolors@2.1.2: + resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} zimmerframe@1.1.2: @@ -11797,11 +11426,11 @@ snapshots: optionalDependencies: chokidar: 4.0.3 - '@angular-devkit/schematics-cli@19.2.15(@types/node@22.18.4)(chokidar@4.0.3)': + '@angular-devkit/schematics-cli@19.2.15(@types/node@22.18.5)(chokidar@4.0.3)': dependencies: '@angular-devkit/core': 19.2.15(chokidar@4.0.3) '@angular-devkit/schematics': 19.2.15(chokidar@4.0.3) - '@inquirer/prompts': 7.3.2(@types/node@22.18.4) + '@inquirer/prompts': 7.3.2(@types/node@22.18.5) ansi-colors: 4.1.3 symbol-observable: 4.0.0 yargs-parser: 21.1.1 @@ -12230,12 +11859,12 @@ snapshots: '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.7) '@babel/helpers': 7.27.6 - '@babel/parser': 7.28.3 + '@babel/parser': 7.28.4 '@babel/template': 7.27.2 - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 convert-source-map: 2.0.0 - debug: 4.4.1 + debug: 4.4.3 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -12244,15 +11873,15 @@ snapshots: '@babel/generator@7.28.3': dependencies: - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 '@jridgewell/gen-mapping': 0.3.13 '@jridgewell/trace-mapping': 0.3.30 jsesc: 3.1.0 '@babel/helper-annotate-as-pure@7.27.3': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 '@babel/helper-compilation-targets@7.27.2': dependencies: @@ -12270,7 +11899,7 @@ snapshots: '@babel/helper-optimise-call-expression': 7.27.1 '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.7) '@babel/helper-skip-transparent-expression-wrappers': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 semver: 6.3.1 transitivePeerDependencies: - supports-color @@ -12287,7 +11916,7 @@ snapshots: '@babel/core': 7.27.7 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 - debug: 4.4.1 + debug: 4.4.3 lodash.debounce: 4.0.8 resolve: 1.22.10 transitivePeerDependencies: @@ -12297,15 +11926,15 @@ snapshots: '@babel/helper-member-expression-to-functions@7.27.1': dependencies: - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color '@babel/helper-module-imports@7.27.1': dependencies: - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color @@ -12314,13 +11943,13 @@ snapshots: '@babel/core': 7.27.7 '@babel/helper-module-imports': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color '@babel/helper-optimise-call-expression@7.27.1': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 '@babel/helper-plugin-utils@7.27.1': {} @@ -12329,7 +11958,7 @@ snapshots: '@babel/core': 7.27.7 '@babel/helper-annotate-as-pure': 7.27.3 '@babel/helper-wrap-function': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color @@ -12338,14 +11967,14 @@ snapshots: '@babel/core': 7.27.7 '@babel/helper-member-expression-to-functions': 7.27.1 '@babel/helper-optimise-call-expression': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color '@babel/helper-skip-transparent-expression-wrappers@7.27.1': dependencies: - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color @@ -12358,25 +11987,25 @@ snapshots: '@babel/helper-wrap-function@7.27.1': dependencies: '@babel/template': 7.27.2 - '@babel/traverse': 7.28.3 - '@babel/types': 7.28.2 + '@babel/traverse': 7.28.4 + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color '@babel/helpers@7.27.6': dependencies: '@babel/template': 7.27.2 - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 - '@babel/parser@7.28.3': + '@babel/parser@7.28.4': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 '@babel/plugin-bugfix-firefox-class-in-computed-class-key@7.27.1(@babel/core@7.27.7)': dependencies: '@babel/core': 7.27.7 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color @@ -12403,7 +12032,7 @@ snapshots: dependencies: '@babel/core': 7.27.7 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color @@ -12452,7 +12081,7 @@ snapshots: '@babel/core': 7.27.7 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-remap-async-to-generator': 7.27.1(@babel/core@7.27.7) - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color @@ -12498,7 +12127,7 @@ snapshots: '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-replace-supers': 7.27.1(@babel/core@7.27.7) - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -12513,7 +12142,7 @@ snapshots: dependencies: '@babel/core': 7.27.7 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color @@ -12562,7 +12191,7 @@ snapshots: '@babel/core': 7.27.7 '@babel/helper-compilation-targets': 7.27.2 '@babel/helper-plugin-utils': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color @@ -12608,7 +12237,7 @@ snapshots: '@babel/helper-module-transforms': 7.27.3(@babel/core@7.27.7) '@babel/helper-plugin-utils': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color @@ -12648,7 +12277,7 @@ snapshots: '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-transform-destructuring': 7.27.7(@babel/core@7.27.7) '@babel/plugin-transform-parameters': 7.27.7(@babel/core@7.27.7) - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 transitivePeerDependencies: - supports-color @@ -12724,7 +12353,7 @@ snapshots: '@babel/helper-module-imports': 7.27.1 '@babel/helper-plugin-utils': 7.27.1 '@babel/plugin-syntax-jsx': 7.27.1(@babel/core@7.27.7) - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 transitivePeerDependencies: - supports-color @@ -12903,7 +12532,7 @@ snapshots: dependencies: '@babel/core': 7.27.7 '@babel/helper-plugin-utils': 7.27.1 - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 esutils: 2.0.3 '@babel/preset-react@7.27.1(@babel/core@7.27.7)': @@ -12938,22 +12567,22 @@ snapshots: '@babel/template@7.27.2': dependencies: '@babel/code-frame': 7.27.1 - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 - '@babel/traverse@7.28.3': + '@babel/traverse@7.28.4': dependencies: '@babel/code-frame': 7.27.1 '@babel/generator': 7.28.3 '@babel/helper-globals': 7.28.0 - '@babel/parser': 7.28.3 + '@babel/parser': 7.28.4 '@babel/template': 7.27.2 - '@babel/types': 7.28.2 - debug: 4.4.1 + '@babel/types': 7.28.4 + debug: 4.4.3 transitivePeerDependencies: - supports-color - '@babel/types@7.28.2': + '@babel/types@7.28.4': dependencies: '@babel/helper-string-parser': 7.27.1 '@babel/helper-validator-identifier': 7.27.1 @@ -13257,7 +12886,7 @@ snapshots: '@babel/preset-typescript': 7.27.1(@babel/core@7.27.7) '@babel/runtime': 7.28.4 '@babel/runtime-corejs3': 7.27.6 - '@babel/traverse': 7.28.3 + '@babel/traverse': 7.28.4 '@docusaurus/logger': 3.8.1 '@docusaurus/utils': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) babel-plugin-dynamic-import-node: 2.3.3 @@ -13315,7 +12944,7 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/core@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': + '@docusaurus/core@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: '@docusaurus/babel': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/bundler': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) @@ -13324,7 +12953,7 @@ snapshots: '@docusaurus/utils': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-common': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mdx-js/react': 3.1.0(@types/react@19.1.13)(react@18.3.1) + '@mdx-js/react': 3.1.1(@types/react@19.1.13)(react@18.3.1) boxen: 6.2.1 chalk: 4.1.2 chokidar: 3.6.0 @@ -13447,13 +13076,13 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/plugin-content-blog@3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': + '@docusaurus/plugin-content-blog@3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/logger': 3.8.1 '@docusaurus/mdx-loader': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-docs': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-docs': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/types': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-common': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -13489,13 +13118,13 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': + '@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/logger': 3.8.1 '@docusaurus/mdx-loader': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/module-type-aliases': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/types': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-common': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -13530,9 +13159,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-content-pages@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': + '@docusaurus/plugin-content-pages@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/mdx-loader': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/types': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -13561,9 +13190,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-css-cascade-layers@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': + '@docusaurus/plugin-css-cascade-layers@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/types': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -13589,9 +13218,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-debug@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': + '@docusaurus/plugin-debug@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/types': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) fs-extra: 11.3.0 @@ -13618,9 +13247,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-analytics@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': + '@docusaurus/plugin-google-analytics@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/types': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 @@ -13645,9 +13274,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-gtag@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': + '@docusaurus/plugin-google-gtag@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/types': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/gtag.js': 0.0.12 @@ -13673,9 +13302,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-google-tag-manager@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': + '@docusaurus/plugin-google-tag-manager@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/types': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 @@ -13700,9 +13329,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-sitemap@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': + '@docusaurus/plugin-sitemap@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/logger': 3.8.1 '@docusaurus/types': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -13732,9 +13361,9 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/plugin-svgr@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': + '@docusaurus/plugin-svgr@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/types': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -13763,22 +13392,22 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/preset-classic@3.8.1(@algolia/client-search@5.29.0)(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(@types/react@19.1.13)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2)': + '@docusaurus/preset-classic@3.8.1(@algolia/client-search@5.29.0)(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(@types/react@19.1.13)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/plugin-content-blog': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/plugin-content-docs': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/plugin-content-pages': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/plugin-css-cascade-layers': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/plugin-debug': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/plugin-google-analytics': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/plugin-google-gtag': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/plugin-google-tag-manager': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/plugin-sitemap': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/plugin-svgr': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-content-blog': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-content-docs': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-content-pages': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-css-cascade-layers': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-debug': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-google-analytics': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-google-gtag': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-google-tag-manager': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-sitemap': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-svgr': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/theme-classic': 3.8.1(@types/react@19.1.13)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/theme-search-algolia': 3.8.1(@algolia/client-search@5.29.0)(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(@types/react@19.1.13)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2) + '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/theme-search-algolia': 3.8.1(@algolia/client-search@5.29.0)(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(@types/react@19.1.13)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2) '@docusaurus/types': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) react: 18.3.1 react-dom: 18.3.1(react@18.3.1) @@ -13811,20 +13440,20 @@ snapshots: '@docusaurus/theme-classic@3.8.1(@types/react@19.1.13)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2)': dependencies: - '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/logger': 3.8.1 '@docusaurus/mdx-loader': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/module-type-aliases': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-blog': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/plugin-content-docs': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/plugin-content-pages': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-blog': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-content-docs': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-content-pages': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/theme-translations': 3.8.1 '@docusaurus/types': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-common': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mdx-js/react': 3.1.0(@types/react@19.1.13)(react@18.3.1) + '@mdx-js/react': 3.1.1(@types/react@19.1.13)(react@18.3.1) clsx: 2.1.1 copy-text-to-clipboard: 3.2.0 infima: 0.2.0-alpha.45 @@ -13858,11 +13487,11 @@ snapshots: - utf-8-validate - webpack-cli - '@docusaurus/theme-common@3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': + '@docusaurus/theme-common@3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': dependencies: '@docusaurus/mdx-loader': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/module-type-aliases': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-docs': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/plugin-content-docs': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/utils': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-common': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@types/history': 4.7.11 @@ -13883,13 +13512,13 @@ snapshots: - uglify-js - webpack-cli - '@docusaurus/theme-search-algolia@3.8.1(@algolia/client-search@5.29.0)(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(@types/react@19.1.13)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2)': + '@docusaurus/theme-search-algolia@3.8.1(@algolia/client-search@5.29.0)(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(@types/react@19.1.13)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2)': dependencies: '@docsearch/react': 3.9.0(@algolia/client-search@5.29.0)(@types/react@19.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3) - '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) '@docusaurus/logger': 3.8.1 - '@docusaurus/plugin-content-docs': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + '@docusaurus/plugin-content-docs': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/theme-translations': 3.8.1 '@docusaurus/utils': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) '@docusaurus/utils-validation': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) @@ -14172,14 +13801,9 @@ snapshots: '@esbuild/win32-x64@0.25.9': optional: true - '@eslint-community/eslint-utils@4.7.0(eslint@9.30.1(jiti@2.5.1))': + '@eslint-community/eslint-utils@4.9.0(eslint@9.35.0(jiti@2.5.1))': dependencies: - eslint: 9.30.1(jiti@2.5.1) - eslint-visitor-keys: 3.4.3 - - '@eslint-community/eslint-utils@4.7.0(eslint@9.33.0(jiti@2.5.1))': - dependencies: - eslint: 9.33.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) eslint-visitor-keys: 3.4.3 '@eslint-community/regexpp@4.12.1': {} @@ -14187,17 +13811,13 @@ snapshots: '@eslint/config-array@0.21.0': dependencies: '@eslint/object-schema': 2.1.6 - debug: 4.4.1 + debug: 4.4.3 minimatch: 3.1.2 transitivePeerDependencies: - supports-color '@eslint/config-helpers@0.3.1': {} - '@eslint/core@0.14.0': - dependencies: - '@types/json-schema': 7.0.15 - '@eslint/core@0.15.2': dependencies: '@types/json-schema': 7.0.15 @@ -14205,7 +13825,7 @@ snapshots: '@eslint/eslintrc@3.3.1': dependencies: ajv: 6.12.6 - debug: 4.4.1 + debug: 4.4.3 espree: 10.4.0 globals: 14.0.0 ignore: 5.3.2 @@ -14216,9 +13836,7 @@ snapshots: transitivePeerDependencies: - supports-color - '@eslint/js@9.30.1': {} - - '@eslint/js@9.33.0': {} + '@eslint/js@9.35.0': {} '@eslint/object-schema@2.1.6': {} @@ -14227,12 +13845,8 @@ snapshots: '@eslint/core': 0.15.2 levn: 0.4.1 - '@exodus/schemasafe@1.3.0': {} - '@faker-js/faker@10.0.0': {} - '@faker-js/faker@5.5.3': {} - '@fig/complete-commander@3.2.0(commander@11.1.0)': dependencies: commander: 11.1.0 @@ -14301,15 +13915,13 @@ snapshots: '@humanfs/core@0.19.1': {} - '@humanfs/node@0.16.6': + '@humanfs/node@0.16.7': dependencies: '@humanfs/core': 0.19.1 - '@humanwhocodes/retry': 0.3.1 + '@humanwhocodes/retry': 0.4.3 '@humanwhocodes/module-importer@1.0.1': {} - '@humanwhocodes/retry@0.3.1': {} - '@humanwhocodes/retry@0.4.3': {} '@img/sharp-darwin-arm64@0.34.3': @@ -14398,39 +14010,39 @@ snapshots: '@img/sharp-win32-x64@0.34.3': optional: true - '@immich/ui@0.29.0(@internationalized/date@3.8.2)(svelte@5.35.5)': + '@immich/ui@0.29.0(@internationalized/date@3.8.2)(svelte@5.38.10)': dependencies: '@mdi/js': 7.4.47 - bits-ui: 2.9.9(@internationalized/date@3.8.2)(svelte@5.35.5) + bits-ui: 2.9.8(@internationalized/date@3.8.2)(svelte@5.38.10) simple-icons: 15.15.0 - svelte: 5.35.5 + svelte: 5.38.10 tailwind-merge: 3.3.1 - tailwind-variants: 3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.12) - tailwindcss: 4.1.12 + tailwind-variants: 3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.13) + tailwindcss: 4.1.13 transitivePeerDependencies: - '@internationalized/date' - '@inquirer/checkbox@4.2.1(@types/node@22.18.4)': + '@inquirer/checkbox@4.2.1(@types/node@22.18.5)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.18.4) + '@inquirer/core': 10.1.15(@types/node@22.18.5) '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@22.18.4) + '@inquirer/type': 3.0.8(@types/node@22.18.5) ansi-escapes: 4.3.2 yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 - '@inquirer/confirm@5.1.15(@types/node@22.18.4)': + '@inquirer/confirm@5.1.15(@types/node@22.18.5)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.18.4) - '@inquirer/type': 3.0.8(@types/node@22.18.4) + '@inquirer/core': 10.1.15(@types/node@22.18.5) + '@inquirer/type': 3.0.8(@types/node@22.18.5) optionalDependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 - '@inquirer/core@10.1.15(@types/node@22.18.4)': + '@inquirer/core@10.1.15(@types/node@22.18.5)': dependencies: '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@22.18.4) + '@inquirer/type': 3.0.8(@types/node@22.18.5) ansi-escapes: 4.3.2 cli-width: 4.1.0 mute-stream: 2.0.0 @@ -14438,115 +14050,115 @@ snapshots: wrap-ansi: 6.2.0 yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 - '@inquirer/editor@4.2.17(@types/node@22.18.4)': + '@inquirer/editor@4.2.17(@types/node@22.18.5)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.18.4) - '@inquirer/external-editor': 1.0.1(@types/node@22.18.4) - '@inquirer/type': 3.0.8(@types/node@22.18.4) + '@inquirer/core': 10.1.15(@types/node@22.18.5) + '@inquirer/external-editor': 1.0.2(@types/node@22.18.5) + '@inquirer/type': 3.0.8(@types/node@22.18.5) optionalDependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 - '@inquirer/expand@4.0.17(@types/node@22.18.4)': + '@inquirer/expand@4.0.17(@types/node@22.18.5)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.18.4) - '@inquirer/type': 3.0.8(@types/node@22.18.4) + '@inquirer/core': 10.1.15(@types/node@22.18.5) + '@inquirer/type': 3.0.8(@types/node@22.18.5) yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 - '@inquirer/external-editor@1.0.1(@types/node@22.18.4)': + '@inquirer/external-editor@1.0.2(@types/node@22.18.5)': dependencies: chardet: 2.1.0 - iconv-lite: 0.6.3 + iconv-lite: 0.7.0 optionalDependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@inquirer/figures@1.0.13': {} - '@inquirer/input@4.2.1(@types/node@22.18.4)': + '@inquirer/input@4.2.1(@types/node@22.18.5)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.18.4) - '@inquirer/type': 3.0.8(@types/node@22.18.4) + '@inquirer/core': 10.1.15(@types/node@22.18.5) + '@inquirer/type': 3.0.8(@types/node@22.18.5) optionalDependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 - '@inquirer/number@3.0.17(@types/node@22.18.4)': + '@inquirer/number@3.0.17(@types/node@22.18.5)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.18.4) - '@inquirer/type': 3.0.8(@types/node@22.18.4) + '@inquirer/core': 10.1.15(@types/node@22.18.5) + '@inquirer/type': 3.0.8(@types/node@22.18.5) optionalDependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 - '@inquirer/password@4.0.17(@types/node@22.18.4)': + '@inquirer/password@4.0.17(@types/node@22.18.5)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.18.4) - '@inquirer/type': 3.0.8(@types/node@22.18.4) + '@inquirer/core': 10.1.15(@types/node@22.18.5) + '@inquirer/type': 3.0.8(@types/node@22.18.5) ansi-escapes: 4.3.2 optionalDependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 - '@inquirer/prompts@7.3.2(@types/node@22.18.4)': + '@inquirer/prompts@7.3.2(@types/node@22.18.5)': dependencies: - '@inquirer/checkbox': 4.2.1(@types/node@22.18.4) - '@inquirer/confirm': 5.1.15(@types/node@22.18.4) - '@inquirer/editor': 4.2.17(@types/node@22.18.4) - '@inquirer/expand': 4.0.17(@types/node@22.18.4) - '@inquirer/input': 4.2.1(@types/node@22.18.4) - '@inquirer/number': 3.0.17(@types/node@22.18.4) - '@inquirer/password': 4.0.17(@types/node@22.18.4) - '@inquirer/rawlist': 4.1.5(@types/node@22.18.4) - '@inquirer/search': 3.1.0(@types/node@22.18.4) - '@inquirer/select': 4.3.1(@types/node@22.18.4) + '@inquirer/checkbox': 4.2.1(@types/node@22.18.5) + '@inquirer/confirm': 5.1.15(@types/node@22.18.5) + '@inquirer/editor': 4.2.17(@types/node@22.18.5) + '@inquirer/expand': 4.0.17(@types/node@22.18.5) + '@inquirer/input': 4.2.1(@types/node@22.18.5) + '@inquirer/number': 3.0.17(@types/node@22.18.5) + '@inquirer/password': 4.0.17(@types/node@22.18.5) + '@inquirer/rawlist': 4.1.5(@types/node@22.18.5) + '@inquirer/search': 3.1.0(@types/node@22.18.5) + '@inquirer/select': 4.3.1(@types/node@22.18.5) optionalDependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 - '@inquirer/prompts@7.8.0(@types/node@22.18.4)': + '@inquirer/prompts@7.8.0(@types/node@22.18.5)': dependencies: - '@inquirer/checkbox': 4.2.1(@types/node@22.18.4) - '@inquirer/confirm': 5.1.15(@types/node@22.18.4) - '@inquirer/editor': 4.2.17(@types/node@22.18.4) - '@inquirer/expand': 4.0.17(@types/node@22.18.4) - '@inquirer/input': 4.2.1(@types/node@22.18.4) - '@inquirer/number': 3.0.17(@types/node@22.18.4) - '@inquirer/password': 4.0.17(@types/node@22.18.4) - '@inquirer/rawlist': 4.1.5(@types/node@22.18.4) - '@inquirer/search': 3.1.0(@types/node@22.18.4) - '@inquirer/select': 4.3.1(@types/node@22.18.4) + '@inquirer/checkbox': 4.2.1(@types/node@22.18.5) + '@inquirer/confirm': 5.1.15(@types/node@22.18.5) + '@inquirer/editor': 4.2.17(@types/node@22.18.5) + '@inquirer/expand': 4.0.17(@types/node@22.18.5) + '@inquirer/input': 4.2.1(@types/node@22.18.5) + '@inquirer/number': 3.0.17(@types/node@22.18.5) + '@inquirer/password': 4.0.17(@types/node@22.18.5) + '@inquirer/rawlist': 4.1.5(@types/node@22.18.5) + '@inquirer/search': 3.1.0(@types/node@22.18.5) + '@inquirer/select': 4.3.1(@types/node@22.18.5) optionalDependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 - '@inquirer/rawlist@4.1.5(@types/node@22.18.4)': + '@inquirer/rawlist@4.1.5(@types/node@22.18.5)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.18.4) - '@inquirer/type': 3.0.8(@types/node@22.18.4) + '@inquirer/core': 10.1.15(@types/node@22.18.5) + '@inquirer/type': 3.0.8(@types/node@22.18.5) yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 - '@inquirer/search@3.1.0(@types/node@22.18.4)': + '@inquirer/search@3.1.0(@types/node@22.18.5)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.18.4) + '@inquirer/core': 10.1.15(@types/node@22.18.5) '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@22.18.4) + '@inquirer/type': 3.0.8(@types/node@22.18.5) yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 - '@inquirer/select@4.3.1(@types/node@22.18.4)': + '@inquirer/select@4.3.1(@types/node@22.18.5)': dependencies: - '@inquirer/core': 10.1.15(@types/node@22.18.4) + '@inquirer/core': 10.1.15(@types/node@22.18.5) '@inquirer/figures': 1.0.13 - '@inquirer/type': 3.0.8(@types/node@22.18.4) + '@inquirer/type': 3.0.8(@types/node@22.18.5) ansi-escapes: 4.3.2 yoctocolors-cjs: 2.1.2 optionalDependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 - '@inquirer/type@3.0.8(@types/node@22.18.4)': + '@inquirer/type@3.0.8(@types/node@22.18.5)': optionalDependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@internationalized/date@3.8.2': dependencies: @@ -14564,7 +14176,7 @@ snapshots: dependencies: string-width: 5.1.2 string-width-cjs: string-width@4.2.3 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 strip-ansi-cjs: strip-ansi@6.0.1 wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 @@ -14584,7 +14196,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/yargs': 17.0.33 chalk: 4.1.2 @@ -14620,18 +14232,18 @@ snapshots: '@koa/router@14.0.0': dependencies: - debug: 4.4.1 + debug: 4.4.3 http-errors: 2.0.0 koa-compose: 4.1.0 - path-to-regexp: 8.2.0 + path-to-regexp: 8.3.0 transitivePeerDependencies: - supports-color - '@koddsson/eslint-plugin-tscompat@0.2.0(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2)': + '@koddsson/eslint-plugin-tscompat@0.2.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: '@mdn/browser-compat-data': 6.0.27 - '@typescript-eslint/type-utils': 8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2) - '@typescript-eslint/utils': 8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/type-utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) browserslist: 4.25.3 transitivePeerDependencies: - eslint @@ -14661,7 +14273,7 @@ snapshots: '@mapbox/node-pre-gyp@1.0.11': dependencies: - detect-libc: 2.0.4 + detect-libc: 2.1.0 https-proxy-agent: 5.0.1 make-dir: 3.1.0 node-fetch: 2.7.0 @@ -14677,7 +14289,7 @@ snapshots: '@mapbox/node-pre-gyp@1.0.11(encoding@0.1.13)': dependencies: - detect-libc: 2.0.4 + detect-libc: 2.1.0 https-proxy-agent: 5.0.1 make-dir: 3.1.0 node-fetch: 2.7.0(encoding@0.1.13) @@ -14774,7 +14386,7 @@ snapshots: - acorn - supports-color - '@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1)': + '@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1)': dependencies: '@types/mdx': 2.0.13 '@types/react': 19.1.13 @@ -14782,17 +14394,6 @@ snapshots: '@microsoft/tsdoc@0.15.1': {} - '@monaco-editor/loader@1.5.0': - dependencies: - state-local: 1.0.7 - - '@monaco-editor/react@4.7.0(monaco-editor@0.31.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)': - dependencies: - '@monaco-editor/loader': 1.5.0 - monaco-editor: 0.31.1 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - '@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.3': optional: true @@ -14819,26 +14420,26 @@ snapshots: '@nestjs/core': 11.1.6(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.6)(@nestjs/websockets@11.1.6)(reflect-metadata@0.2.2)(rxjs@7.8.2) tslib: 2.8.1 - '@nestjs/bullmq@11.0.3(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6)(bullmq@5.57.0)': + '@nestjs/bullmq@11.0.3(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6)(bullmq@5.58.5)': dependencies: '@nestjs/bull-shared': 11.0.3(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6) '@nestjs/common': 11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2) '@nestjs/core': 11.1.6(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@11.1.6)(@nestjs/websockets@11.1.6)(reflect-metadata@0.2.2)(rxjs@7.8.2) - bullmq: 5.57.0 + bullmq: 5.58.5 tslib: 2.8.1 - '@nestjs/cli@11.0.10(@swc/core@1.13.3(@swc/helpers@0.5.17))(@types/node@22.18.4)': + '@nestjs/cli@11.0.10(@swc/core@1.13.5(@swc/helpers@0.5.17))(@types/node@22.18.5)': dependencies: '@angular-devkit/core': 19.2.15(chokidar@4.0.3) '@angular-devkit/schematics': 19.2.15(chokidar@4.0.3) - '@angular-devkit/schematics-cli': 19.2.15(@types/node@22.18.4)(chokidar@4.0.3) - '@inquirer/prompts': 7.8.0(@types/node@22.18.4) + '@angular-devkit/schematics-cli': 19.2.15(@types/node@22.18.5)(chokidar@4.0.3) + '@inquirer/prompts': 7.8.0(@types/node@22.18.5) '@nestjs/schematics': 11.0.7(chokidar@4.0.3)(typescript@5.8.3) ansis: 4.1.0 chokidar: 4.0.3 cli-table3: 0.6.5 commander: 4.1.1 - fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.8.3)(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + fork-ts-checker-webpack-plugin: 9.1.0(typescript@5.8.3)(webpack@5.100.2(@swc/core@1.13.5(@swc/helpers@0.5.17))) glob: 11.0.3 node-emoji: 1.11.0 ora: 5.4.1 @@ -14846,10 +14447,10 @@ snapshots: tsconfig-paths: 4.2.0 tsconfig-paths-webpack-plugin: 4.2.0 typescript: 5.8.3 - webpack: 5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17)) + webpack: 5.100.2(@swc/core@1.13.5(@swc/helpers@0.5.17)) webpack-node-externals: 3.0.0 optionalDependencies: - '@swc/core': 1.13.3(@swc/helpers@0.5.17) + '@swc/core': 1.13.5(@swc/helpers@0.5.17) transitivePeerDependencies: - '@types/node' - esbuild @@ -15015,311 +14616,311 @@ snapshots: '@oazapfts/runtime@1.0.4': {} - '@opentelemetry/api-logs@0.203.0': + '@opentelemetry/api-logs@0.205.0': dependencies: '@opentelemetry/api': 1.9.0 '@opentelemetry/api@1.9.0': {} - '@opentelemetry/context-async-hooks@2.0.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/context-async-hooks@2.1.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core@2.0.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/core@2.1.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 - '@opentelemetry/exporter-logs-otlp-grpc@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-logs-otlp-grpc@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@grpc/grpc-js': 1.13.4 '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-grpc-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.205.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-http@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-logs-otlp-http@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.203.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/api-logs': 0.205.0 + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.205.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-proto@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-logs-otlp-proto@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.203.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/api-logs': 0.205.0 + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-grpc@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-metrics-otlp-grpc@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@grpc/grpc-js': 1.13.4 '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-http': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-grpc-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.1.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-http@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-metrics-otlp-http@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.1.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-proto@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-metrics-otlp-proto@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-http': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.1.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-prometheus@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-prometheus@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.1.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-grpc@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-trace-otlp-grpc@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@grpc/grpc-js': 1.13.4 '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-grpc-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-grpc-exporter-base': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-http@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-trace-otlp-http@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-proto@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-trace-otlp-proto@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-zipkin@2.0.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/exporter-zipkin@2.1.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 '@opentelemetry/host-metrics@0.36.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 systeminformation: 5.23.8 - '@opentelemetry/instrumentation-http@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-http@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 forwarded-parse: 2.1.2 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-ioredis@0.51.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-ioredis@0.53.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.205.0(@opentelemetry/api@1.9.0) '@opentelemetry/redis-common': 0.38.0 - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-nestjs-core@0.49.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-nestjs-core@0.51.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/instrumentation': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation-pg@0.56.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation-pg@0.58.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 '@opentelemetry/sql-common': 0.41.0(@opentelemetry/api@1.9.0) - '@types/pg': 8.15.4 + '@types/pg': 8.15.5 '@types/pg-pool': 2.0.6 transitivePeerDependencies: - supports-color - '@opentelemetry/instrumentation@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/instrumentation@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.203.0 + '@opentelemetry/api-logs': 0.205.0 import-in-the-middle: 1.14.2 require-in-the-middle: 7.5.2 transitivePeerDependencies: - supports-color - '@opentelemetry/otlp-exporter-base@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/otlp-exporter-base@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.205.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-grpc-exporter-base@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/otlp-grpc-exporter-base@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@grpc/grpc-js': 1.13.4 '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-exporter-base': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer': 0.203.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-exporter-base': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/otlp-transformer': 0.205.0(@opentelemetry/api@1.9.0) - '@opentelemetry/otlp-transformer@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/otlp-transformer@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.203.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/api-logs': 0.205.0 + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) protobufjs: 7.5.4 - '@opentelemetry/propagator-b3@2.0.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/propagator-b3@2.1.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) - '@opentelemetry/propagator-jaeger@2.0.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/propagator-jaeger@2.1.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@opentelemetry/redis-common@0.38.0': {} - '@opentelemetry/resources@2.0.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/resources@2.1.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 - '@opentelemetry/sdk-logs@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-logs@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.203.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/api-logs': 0.205.0 + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics@2.0.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-metrics@2.1.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-node@0.203.0(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-node@0.205.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/api-logs': 0.203.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-grpc': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-http': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-logs-otlp-proto': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-grpc': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-http': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-metrics-otlp-proto': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-prometheus': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-grpc': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-http': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-trace-otlp-proto': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/exporter-zipkin': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/instrumentation': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/propagator-b3': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/propagator-jaeger': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-logs': 0.203.0(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-metrics': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-node': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/api-logs': 0.205.0 + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-grpc': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-http': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-logs-otlp-proto': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-grpc': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-http': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-metrics-otlp-proto': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-prometheus': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-grpc': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-http': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-trace-otlp-proto': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/exporter-zipkin': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/instrumentation': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-b3': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/propagator-jaeger': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-logs': 0.205.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-metrics': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-node': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 transitivePeerDependencies: - supports-color - '@opentelemetry/sdk-trace-base@2.0.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-trace-base@2.1.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/resources': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions': 1.36.0 + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/resources': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/semantic-conventions': 1.37.0 - '@opentelemetry/sdk-trace-node@2.0.1(@opentelemetry/api@1.9.0)': + '@opentelemetry/sdk-trace-node@2.1.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/context-async-hooks': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) - '@opentelemetry/sdk-trace-base': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/context-async-hooks': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) + '@opentelemetry/sdk-trace-base': 2.1.0(@opentelemetry/api@1.9.0) - '@opentelemetry/semantic-conventions@1.36.0': {} + '@opentelemetry/semantic-conventions@1.37.0': {} '@opentelemetry/sql-common@0.41.0(@opentelemetry/api@1.9.0)': dependencies: '@opentelemetry/api': 1.9.0 - '@opentelemetry/core': 2.0.1(@opentelemetry/api@1.9.0) + '@opentelemetry/core': 2.1.0(@opentelemetry/api@1.9.0) '@paralleldrive/cuid2@2.2.2': dependencies: '@noble/hashes': 1.8.0 - '@photo-sphere-viewer/core@5.13.4': + '@photo-sphere-viewer/core@5.14.0': dependencies: - three: 0.175.0 - - '@photo-sphere-viewer/equirectangular-video-adapter@5.13.4(@photo-sphere-viewer/core@5.13.4)(@photo-sphere-viewer/video-plugin@5.13.4(@photo-sphere-viewer/core@5.13.4))': - dependencies: - '@photo-sphere-viewer/core': 5.13.4 - '@photo-sphere-viewer/video-plugin': 5.13.4(@photo-sphere-viewer/core@5.13.4) three: 0.179.1 - '@photo-sphere-viewer/resolution-plugin@5.13.4(@photo-sphere-viewer/core@5.13.4)(@photo-sphere-viewer/settings-plugin@5.13.4(@photo-sphere-viewer/core@5.13.4))': + '@photo-sphere-viewer/equirectangular-video-adapter@5.14.0(@photo-sphere-viewer/core@5.14.0)(@photo-sphere-viewer/video-plugin@5.14.0(@photo-sphere-viewer/core@5.14.0))': dependencies: - '@photo-sphere-viewer/core': 5.13.4 - '@photo-sphere-viewer/settings-plugin': 5.13.4(@photo-sphere-viewer/core@5.13.4) + '@photo-sphere-viewer/core': 5.14.0 + '@photo-sphere-viewer/video-plugin': 5.14.0(@photo-sphere-viewer/core@5.14.0) + three: 0.180.0 - '@photo-sphere-viewer/settings-plugin@5.13.4(@photo-sphere-viewer/core@5.13.4)': + '@photo-sphere-viewer/resolution-plugin@5.14.0(@photo-sphere-viewer/core@5.14.0)(@photo-sphere-viewer/settings-plugin@5.14.0(@photo-sphere-viewer/core@5.14.0))': dependencies: - '@photo-sphere-viewer/core': 5.13.4 + '@photo-sphere-viewer/core': 5.14.0 + '@photo-sphere-viewer/settings-plugin': 5.14.0(@photo-sphere-viewer/core@5.14.0) - '@photo-sphere-viewer/video-plugin@5.13.4(@photo-sphere-viewer/core@5.13.4)': + '@photo-sphere-viewer/settings-plugin@5.14.0(@photo-sphere-viewer/core@5.14.0)': dependencies: - '@photo-sphere-viewer/core': 5.13.4 - three: 0.179.1 + '@photo-sphere-viewer/core': 5.14.0 + + '@photo-sphere-viewer/video-plugin@5.14.0(@photo-sphere-viewer/core@5.14.0)': + dependencies: + '@photo-sphere-viewer/core': 5.14.0 + three: 0.180.0 '@photostructure/tz-lookup@11.2.0': {} @@ -15328,9 +14929,9 @@ snapshots: '@pkgr/core@0.2.9': {} - '@playwright/test@1.54.2': + '@playwright/test@1.55.0': dependencies: - playwright: 1.54.2 + playwright: 1.55.0 '@pnpm/config.env-replace@1.1.0': {} @@ -15390,7 +14991,7 @@ snapshots: dependencies: react: 19.1.1 - '@react-email/components@0.5.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@react-email/components@0.5.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: '@react-email/body': 0.1.0(react@19.1.1) '@react-email/button': 0.2.0(react@19.1.1) @@ -15407,7 +15008,7 @@ snapshots: '@react-email/link': 0.0.12(react@19.1.1) '@react-email/markdown': 0.0.15(react@19.1.1) '@react-email/preview': 0.0.13(react@19.1.1) - '@react-email/render': 1.2.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1) + '@react-email/render': 1.2.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1) '@react-email/row': 0.0.12(react@19.1.1) '@react-email/section': 0.0.16(react@19.1.1) '@react-email/tailwind': 1.2.2(react@19.1.1) @@ -15457,7 +15058,7 @@ snapshots: dependencies: react: 19.1.1 - '@react-email/render@1.2.0(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': + '@react-email/render@1.2.3(react-dom@19.1.1(react@19.1.1))(react@19.1.1)': dependencies: html-to-text: 9.0.5 prettier: 3.6.2 @@ -15481,17 +15082,7 @@ snapshots: dependencies: react: 19.1.1 - '@reduxjs/toolkit@1.9.7(react-redux@7.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)': - dependencies: - immer: 9.0.21 - redux: 4.2.1 - redux-thunk: 2.4.2(redux@4.2.1) - reselect: 4.1.8 - optionalDependencies: - react: 18.3.1 - react-redux: 7.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - - '@rollup/pluginutils@5.2.0(rollup@4.50.1)': + '@rollup/pluginutils@5.3.0(rollup@4.50.1)': dependencies: '@types/estree': 1.0.8 estree-walker: 2.0.2 @@ -15888,62 +15479,63 @@ snapshots: dependencies: acorn: 8.15.0 - '@sveltejs/adapter-static@3.0.9(@sveltejs/kit@2.27.1(@sveltejs/vite-plugin-svelte@6.1.2(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))': + '@sveltejs/adapter-static@3.0.9(@sveltejs/kit@2.38.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.0(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))': dependencies: - '@sveltejs/kit': 2.27.1(@sveltejs/vite-plugin-svelte@6.1.2(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + '@sveltejs/kit': 2.38.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.0(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) - '@sveltejs/enhanced-img@0.8.1(@sveltejs/vite-plugin-svelte@6.1.2(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(rollup@4.50.1)(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': + '@sveltejs/enhanced-img@0.8.1(@sveltejs/vite-plugin-svelte@6.2.0(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(rollup@4.50.1)(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.1.2(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) - magic-string: 0.30.17 + '@sveltejs/vite-plugin-svelte': 6.2.0(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + magic-string: 0.30.19 sharp: 0.34.3 - svelte: 5.35.5 - svelte-parse-markup: 0.1.5(svelte@5.35.5) - vite: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + svelte: 5.38.10 + svelte-parse-markup: 0.1.5(svelte@5.38.10) + vite: 7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) vite-imagetools: 8.0.0(rollup@4.50.1) zimmerframe: 1.1.2 transitivePeerDependencies: - rollup - supports-color - '@sveltejs/kit@2.27.1(@sveltejs/vite-plugin-svelte@6.1.2(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': + '@sveltejs/kit@2.38.1(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.0(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': dependencies: '@standard-schema/spec': 1.0.0 '@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0) - '@sveltejs/vite-plugin-svelte': 6.1.2(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + '@sveltejs/vite-plugin-svelte': 6.2.0(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) '@types/cookie': 0.6.0 acorn: 8.15.0 cookie: 0.6.0 - devalue: 5.1.1 + devalue: 5.3.2 esm-env: 1.2.2 kleur: 4.1.5 - magic-string: 0.30.17 + magic-string: 0.30.19 mrmime: 2.0.1 sade: 1.8.1 set-cookie-parser: 2.7.1 - sirv: 3.0.1 - svelte: 5.35.5 - vite: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + sirv: 3.0.2 + svelte: 5.38.10 + vite: 7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + optionalDependencies: + '@opentelemetry/api': 1.9.0 - '@sveltejs/vite-plugin-svelte-inspector@5.0.0(@sveltejs/vite-plugin-svelte@6.1.2(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': + '@sveltejs/vite-plugin-svelte-inspector@5.0.0(@sveltejs/vite-plugin-svelte@6.2.0(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte': 6.1.2(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) - debug: 4.4.1 - svelte: 5.35.5 - vite: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + '@sveltejs/vite-plugin-svelte': 6.2.0(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + debug: 4.4.3 + svelte: 5.38.10 + vite: 7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) transitivePeerDependencies: - supports-color - '@sveltejs/vite-plugin-svelte@6.1.2(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': + '@sveltejs/vite-plugin-svelte@6.2.0(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': dependencies: - '@sveltejs/vite-plugin-svelte-inspector': 5.0.0(@sveltejs/vite-plugin-svelte@6.1.2(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) - debug: 4.4.1 + '@sveltejs/vite-plugin-svelte-inspector': 5.0.0(@sveltejs/vite-plugin-svelte@6.2.0(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)))(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + debug: 4.4.3 deepmerge: 4.3.1 - kleur: 4.1.5 - magic-string: 0.30.17 - svelte: 5.35.5 - vite: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) - vitefu: 1.1.1(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + magic-string: 0.30.19 + svelte: 5.38.10 + vite: 7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vitefu: 1.1.1(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) transitivePeerDependencies: - supports-color @@ -16004,7 +15596,7 @@ snapshots: '@svgr/hast-util-to-babel-ast@8.0.0': dependencies: - '@babel/types': 7.28.2 + '@babel/types': 7.28.4 entities: 4.5.0 '@svgr/plugin-jsx@8.1.0(@svgr/core@8.1.0(typescript@5.9.2))': @@ -16040,51 +15632,51 @@ snapshots: - supports-color - typescript - '@swc/core-darwin-arm64@1.13.3': + '@swc/core-darwin-arm64@1.13.5': optional: true - '@swc/core-darwin-x64@1.13.3': + '@swc/core-darwin-x64@1.13.5': optional: true - '@swc/core-linux-arm-gnueabihf@1.13.3': + '@swc/core-linux-arm-gnueabihf@1.13.5': optional: true - '@swc/core-linux-arm64-gnu@1.13.3': + '@swc/core-linux-arm64-gnu@1.13.5': optional: true - '@swc/core-linux-arm64-musl@1.13.3': + '@swc/core-linux-arm64-musl@1.13.5': optional: true - '@swc/core-linux-x64-gnu@1.13.3': + '@swc/core-linux-x64-gnu@1.13.5': optional: true - '@swc/core-linux-x64-musl@1.13.3': + '@swc/core-linux-x64-musl@1.13.5': optional: true - '@swc/core-win32-arm64-msvc@1.13.3': + '@swc/core-win32-arm64-msvc@1.13.5': optional: true - '@swc/core-win32-ia32-msvc@1.13.3': + '@swc/core-win32-ia32-msvc@1.13.5': optional: true - '@swc/core-win32-x64-msvc@1.13.3': + '@swc/core-win32-x64-msvc@1.13.5': optional: true - '@swc/core@1.13.3(@swc/helpers@0.5.17)': + '@swc/core@1.13.5(@swc/helpers@0.5.17)': dependencies: '@swc/counter': 0.1.3 - '@swc/types': 0.1.24 + '@swc/types': 0.1.25 optionalDependencies: - '@swc/core-darwin-arm64': 1.13.3 - '@swc/core-darwin-x64': 1.13.3 - '@swc/core-linux-arm-gnueabihf': 1.13.3 - '@swc/core-linux-arm64-gnu': 1.13.3 - '@swc/core-linux-arm64-musl': 1.13.3 - '@swc/core-linux-x64-gnu': 1.13.3 - '@swc/core-linux-x64-musl': 1.13.3 - '@swc/core-win32-arm64-msvc': 1.13.3 - '@swc/core-win32-ia32-msvc': 1.13.3 - '@swc/core-win32-x64-msvc': 1.13.3 + '@swc/core-darwin-arm64': 1.13.5 + '@swc/core-darwin-x64': 1.13.5 + '@swc/core-linux-arm-gnueabihf': 1.13.5 + '@swc/core-linux-arm64-gnu': 1.13.5 + '@swc/core-linux-arm64-musl': 1.13.5 + '@swc/core-linux-x64-gnu': 1.13.5 + '@swc/core-linux-x64-musl': 1.13.5 + '@swc/core-win32-arm64-msvc': 1.13.5 + '@swc/core-win32-ia32-msvc': 1.13.5 + '@swc/core-win32-x64-msvc': 1.13.5 '@swc/helpers': 0.5.17 '@swc/counter@0.1.3': {} @@ -16093,7 +15685,7 @@ snapshots: dependencies: tslib: 2.8.1 - '@swc/types@0.1.24': + '@swc/types@0.1.25': dependencies: '@swc/counter': 0.1.3 @@ -16101,76 +15693,76 @@ snapshots: dependencies: defer-to-connect: 2.0.1 - '@tailwindcss/node@4.1.12': + '@tailwindcss/node@4.1.13': dependencies: '@jridgewell/remapping': 2.3.5 enhanced-resolve: 5.18.3 jiti: 2.5.1 lightningcss: 1.30.1 - magic-string: 0.30.17 + magic-string: 0.30.19 source-map-js: 1.2.1 - tailwindcss: 4.1.12 + tailwindcss: 4.1.13 - '@tailwindcss/oxide-android-arm64@4.1.12': + '@tailwindcss/oxide-android-arm64@4.1.13': optional: true - '@tailwindcss/oxide-darwin-arm64@4.1.12': + '@tailwindcss/oxide-darwin-arm64@4.1.13': optional: true - '@tailwindcss/oxide-darwin-x64@4.1.12': + '@tailwindcss/oxide-darwin-x64@4.1.13': optional: true - '@tailwindcss/oxide-freebsd-x64@4.1.12': + '@tailwindcss/oxide-freebsd-x64@4.1.13': optional: true - '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.12': + '@tailwindcss/oxide-linux-arm-gnueabihf@4.1.13': optional: true - '@tailwindcss/oxide-linux-arm64-gnu@4.1.12': + '@tailwindcss/oxide-linux-arm64-gnu@4.1.13': optional: true - '@tailwindcss/oxide-linux-arm64-musl@4.1.12': + '@tailwindcss/oxide-linux-arm64-musl@4.1.13': optional: true - '@tailwindcss/oxide-linux-x64-gnu@4.1.12': + '@tailwindcss/oxide-linux-x64-gnu@4.1.13': optional: true - '@tailwindcss/oxide-linux-x64-musl@4.1.12': + '@tailwindcss/oxide-linux-x64-musl@4.1.13': optional: true - '@tailwindcss/oxide-wasm32-wasi@4.1.12': + '@tailwindcss/oxide-wasm32-wasi@4.1.13': optional: true - '@tailwindcss/oxide-win32-arm64-msvc@4.1.12': + '@tailwindcss/oxide-win32-arm64-msvc@4.1.13': optional: true - '@tailwindcss/oxide-win32-x64-msvc@4.1.12': + '@tailwindcss/oxide-win32-x64-msvc@4.1.13': optional: true - '@tailwindcss/oxide@4.1.12': + '@tailwindcss/oxide@4.1.13': dependencies: - detect-libc: 2.0.4 + detect-libc: 2.1.0 tar: 7.4.3 optionalDependencies: - '@tailwindcss/oxide-android-arm64': 4.1.12 - '@tailwindcss/oxide-darwin-arm64': 4.1.12 - '@tailwindcss/oxide-darwin-x64': 4.1.12 - '@tailwindcss/oxide-freebsd-x64': 4.1.12 - '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.12 - '@tailwindcss/oxide-linux-arm64-gnu': 4.1.12 - '@tailwindcss/oxide-linux-arm64-musl': 4.1.12 - '@tailwindcss/oxide-linux-x64-gnu': 4.1.12 - '@tailwindcss/oxide-linux-x64-musl': 4.1.12 - '@tailwindcss/oxide-wasm32-wasi': 4.1.12 - '@tailwindcss/oxide-win32-arm64-msvc': 4.1.12 - '@tailwindcss/oxide-win32-x64-msvc': 4.1.12 + '@tailwindcss/oxide-android-arm64': 4.1.13 + '@tailwindcss/oxide-darwin-arm64': 4.1.13 + '@tailwindcss/oxide-darwin-x64': 4.1.13 + '@tailwindcss/oxide-freebsd-x64': 4.1.13 + '@tailwindcss/oxide-linux-arm-gnueabihf': 4.1.13 + '@tailwindcss/oxide-linux-arm64-gnu': 4.1.13 + '@tailwindcss/oxide-linux-arm64-musl': 4.1.13 + '@tailwindcss/oxide-linux-x64-gnu': 4.1.13 + '@tailwindcss/oxide-linux-x64-musl': 4.1.13 + '@tailwindcss/oxide-wasm32-wasi': 4.1.13 + '@tailwindcss/oxide-win32-arm64-msvc': 4.1.13 + '@tailwindcss/oxide-win32-x64-msvc': 4.1.13 - '@tailwindcss/vite@4.1.12(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': + '@tailwindcss/vite@4.1.13(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': dependencies: - '@tailwindcss/node': 4.1.12 - '@tailwindcss/oxide': 4.1.12 - tailwindcss: 4.1.12 - vite: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + '@tailwindcss/node': 4.1.13 + '@tailwindcss/oxide': 4.1.13 + tailwindcss: 4.1.13 + vite: 7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) '@testing-library/dom@10.4.0': dependencies: @@ -16183,7 +15775,7 @@ snapshots: lz-string: 1.5.0 pretty-format: 27.5.1 - '@testing-library/jest-dom@6.7.0': + '@testing-library/jest-dom@6.8.0': dependencies: '@adobe/css-tools': 4.4.4 aria-query: 5.3.2 @@ -16192,13 +15784,13 @@ snapshots: picocolors: 1.1.1 redent: 3.0.0 - '@testing-library/svelte@5.2.8(svelte@5.35.5)(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': + '@testing-library/svelte@5.2.8(svelte@5.38.10)(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.1)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': dependencies: '@testing-library/dom': 10.4.0 - svelte: 5.35.5 + svelte: 5.38.10 optionalDependencies: - vite: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vite: 7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.5.1)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) '@testing-library/user-event@14.6.1(@testing-library/dom@10.4.0)': dependencies: @@ -16206,7 +15798,7 @@ snapshots: '@tokenizer/inflate@0.2.7': dependencies: - debug: 4.4.1 + debug: 4.4.3 fflate: 0.8.2 token-types: 6.1.1 transitivePeerDependencies: @@ -16240,7 +15832,7 @@ snapshots: '@types/accepts@1.3.7': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/archiver@6.0.3': dependencies: @@ -16252,16 +15844,16 @@ snapshots: '@types/bcrypt@6.0.0': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/body-parser@1.19.6': dependencies: '@types/connect': 3.4.38 - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/bonjour@3.5.13': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/braces@3.0.5': {} @@ -16282,21 +15874,21 @@ snapshots: '@types/cli-progress@3.11.6': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/compression@1.8.1': dependencies: '@types/express': 5.0.3 - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/connect-history-api-fallback@1.5.4': dependencies: '@types/express-serve-static-core': 5.0.6 - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/connect@3.4.38': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/content-disposition@0.5.9': {} @@ -16313,11 +15905,11 @@ snapshots: '@types/connect': 3.4.38 '@types/express': 5.0.3 '@types/keygrip': 1.0.6 - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/cors@2.8.19': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/debug@4.1.12': dependencies: @@ -16327,13 +15919,13 @@ snapshots: '@types/docker-modem@3.0.6': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/ssh2': 1.15.5 '@types/dockerode@3.3.42': dependencies: '@types/docker-modem': 3.0.6 - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/ssh2': 1.15.5 '@types/dom-to-image@2.6.7': {} @@ -16356,14 +15948,14 @@ snapshots: '@types/express-serve-static-core@4.19.6': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 0.17.5 '@types/express-serve-static-core@5.0.6': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/qs': 6.14.0 '@types/range-parser': 1.2.7 '@types/send': 0.17.5 @@ -16389,7 +15981,7 @@ snapshots: '@types/fluent-ffmpeg@2.1.27': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/geojson-vt@3.2.5': dependencies: @@ -16411,11 +16003,6 @@ snapshots: '@types/history@4.7.11': {} - '@types/hoist-non-react-statics@3.3.6': - dependencies: - '@types/react': 19.1.13 - hoist-non-react-statics: 3.3.2 - '@types/html-minifier-terser@6.1.0': {} '@types/http-assert@1.5.6': {} @@ -16426,7 +16013,7 @@ snapshots: '@types/http-proxy@1.17.16': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/inquirer@8.2.11': dependencies: @@ -16464,9 +16051,9 @@ snapshots: '@types/http-errors': 2.0.5 '@types/keygrip': 1.0.6 '@types/koa-compose': 3.2.8 - '@types/node': 22.18.4 + '@types/node': 22.18.5 - '@types/leaflet@1.9.19': + '@types/leaflet@1.9.20': dependencies: '@types/geojson': 7946.0.16 @@ -16496,7 +16083,7 @@ snapshots: '@types/mock-fs@4.13.4': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/ms@2.1.0': {} @@ -16504,18 +16091,13 @@ snapshots: dependencies: '@types/express': 5.0.3 - '@types/node-fetch@2.6.12': - dependencies: - '@types/node': 22.18.4 - form-data: 4.0.4 - '@types/node-forge@1.3.11': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/node@17.0.45': {} - '@types/node@18.19.123': + '@types/node@18.19.126': dependencies: undici-types: 5.26.5 @@ -16523,31 +16105,27 @@ snapshots: dependencies: undici-types: 6.21.0 - '@types/node@22.18.4': - dependencies: - undici-types: 6.21.0 - '@types/node@22.18.5': dependencies: undici-types: 6.21.0 - '@types/node@24.3.0': + '@types/node@24.5.1': dependencies: - undici-types: 7.10.0 + undici-types: 7.12.0 optional: true '@types/nodemailer@7.0.1': dependencies: '@aws-sdk/client-sesv2': 3.890.0 - '@types/node': 22.18.4 + '@types/node': 22.18.5 transitivePeerDependencies: - aws-crt - '@types/oidc-provider@9.1.2': + '@types/oidc-provider@9.5.0': dependencies: '@types/keygrip': 1.0.6 '@types/koa': 3.0.0 - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/parse5@5.0.3': {} @@ -16555,15 +16133,9 @@ snapshots: dependencies: '@types/pg': 8.15.5 - '@types/pg@8.15.4': - dependencies: - '@types/node': 22.18.4 - pg-protocol: 1.10.3 - pg-types: 2.2.0 - '@types/pg@8.15.5': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 pg-protocol: 1.10.3 pg-types: 2.2.0 @@ -16571,25 +16143,18 @@ snapshots: '@types/pngjs@6.0.5': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/prismjs@1.26.5': {} '@types/qrcode@1.5.5': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/qs@6.14.0': {} '@types/range-parser@1.2.7': {} - '@types/react-redux@7.1.34': - dependencies: - '@types/hoist-non-react-statics': 3.3.6 - '@types/react': 19.1.13 - hoist-non-react-statics: 3.3.2 - redux: 4.2.1 - '@types/react-router-config@5.0.11': dependencies: '@types/history': 4.7.11 @@ -16613,7 +16178,7 @@ snapshots: '@types/readdir-glob@1.1.5': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/retry@0.12.0': {} @@ -16623,14 +16188,14 @@ snapshots: '@types/sax@1.2.7': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 - '@types/semver@7.7.0': {} + '@types/semver@7.7.1': {} '@types/send@0.17.5': dependencies: '@types/mime': 1.3.5 - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/serve-index@1.9.4': dependencies: @@ -16639,31 +16204,31 @@ snapshots: '@types/serve-static@1.15.8': dependencies: '@types/http-errors': 2.0.5 - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/send': 0.17.5 '@types/sockjs@0.3.36': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/ssh2-streams@0.1.12': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/ssh2@0.5.52': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/ssh2-streams': 0.1.12 '@types/ssh2@1.15.5': dependencies: - '@types/node': 18.19.123 + '@types/node': 18.19.126 '@types/superagent@8.1.9': dependencies: '@types/cookiejar': 2.1.5 '@types/methods': 1.1.4 - '@types/node': 22.18.4 + '@types/node': 22.18.5 form-data: 4.0.4 '@types/supercluster@7.1.3': @@ -16687,13 +16252,13 @@ snapshots: '@types/uuid@9.0.8': {} - '@types/validator@13.15.2': {} + '@types/validator@13.15.3': {} '@types/whatwg-mimetype@3.0.2': {} '@types/ws@8.18.1': dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 '@types/yargs-parser@21.0.3': {} @@ -16701,15 +16266,15 @@ snapshots: dependencies: '@types/yargs-parser': 21.0.3 - '@typescript-eslint/eslint-plugin@8.39.1(@typescript-eslint/parser@8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2)': + '@typescript-eslint/eslint-plugin@8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: '@eslint-community/regexpp': 4.12.1 - '@typescript-eslint/parser': 8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2) - '@typescript-eslint/scope-manager': 8.39.1 - '@typescript-eslint/type-utils': 8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2) - '@typescript-eslint/utils': 8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.39.1 - eslint: 9.33.0(jiti@2.5.1) + '@typescript-eslint/parser': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/scope-manager': 8.43.0 + '@typescript-eslint/type-utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.43.0 + eslint: 9.35.0(jiti@2.5.1) graphemer: 1.4.0 ignore: 7.0.5 natural-compare: 1.4.0 @@ -16718,57 +16283,57 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/parser@8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2)': + '@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: - '@typescript-eslint/scope-manager': 8.39.1 - '@typescript-eslint/types': 8.39.1 - '@typescript-eslint/typescript-estree': 8.39.1(typescript@5.9.2) - '@typescript-eslint/visitor-keys': 8.39.1 - debug: 4.4.1 - eslint: 9.33.0(jiti@2.5.1) + '@typescript-eslint/scope-manager': 8.43.0 + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2) + '@typescript-eslint/visitor-keys': 8.43.0 + debug: 4.4.3 + eslint: 9.35.0(jiti@2.5.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/project-service@8.39.1(typescript@5.9.2)': + '@typescript-eslint/project-service@8.43.0(typescript@5.9.2)': dependencies: - '@typescript-eslint/tsconfig-utils': 8.39.1(typescript@5.9.2) - '@typescript-eslint/types': 8.39.1 - debug: 4.4.1 + '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.9.2) + '@typescript-eslint/types': 8.43.0 + debug: 4.4.3 typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/scope-manager@8.39.1': + '@typescript-eslint/scope-manager@8.43.0': dependencies: - '@typescript-eslint/types': 8.39.1 - '@typescript-eslint/visitor-keys': 8.39.1 + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/visitor-keys': 8.43.0 - '@typescript-eslint/tsconfig-utils@8.39.1(typescript@5.9.2)': + '@typescript-eslint/tsconfig-utils@8.43.0(typescript@5.9.2)': dependencies: typescript: 5.9.2 - '@typescript-eslint/type-utils@8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2)': + '@typescript-eslint/type-utils@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: - '@typescript-eslint/types': 8.39.1 - '@typescript-eslint/typescript-estree': 8.39.1(typescript@5.9.2) - '@typescript-eslint/utils': 8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2) - debug: 4.4.1 - eslint: 9.33.0(jiti@2.5.1) + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2) + '@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + debug: 4.4.3 + eslint: 9.35.0(jiti@2.5.1) ts-api-utils: 2.1.0(typescript@5.9.2) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/types@8.39.1': {} + '@typescript-eslint/types@8.43.0': {} - '@typescript-eslint/typescript-estree@8.39.1(typescript@5.9.2)': + '@typescript-eslint/typescript-estree@8.43.0(typescript@5.9.2)': dependencies: - '@typescript-eslint/project-service': 8.39.1(typescript@5.9.2) - '@typescript-eslint/tsconfig-utils': 8.39.1(typescript@5.9.2) - '@typescript-eslint/types': 8.39.1 - '@typescript-eslint/visitor-keys': 8.39.1 - debug: 4.4.1 + '@typescript-eslint/project-service': 8.43.0(typescript@5.9.2) + '@typescript-eslint/tsconfig-utils': 8.43.0(typescript@5.9.2) + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/visitor-keys': 8.43.0 + debug: 4.4.3 fast-glob: 3.3.3 is-glob: 4.0.3 minimatch: 9.0.5 @@ -16778,78 +16343,59 @@ snapshots: transitivePeerDependencies: - supports-color - '@typescript-eslint/utils@8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2)': + '@typescript-eslint/utils@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2)': dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.33.0(jiti@2.5.1)) - '@typescript-eslint/scope-manager': 8.39.1 - '@typescript-eslint/types': 8.39.1 - '@typescript-eslint/typescript-estree': 8.39.1(typescript@5.9.2) - eslint: 9.33.0(jiti@2.5.1) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) + '@typescript-eslint/scope-manager': 8.43.0 + '@typescript-eslint/types': 8.43.0 + '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2) + eslint: 9.35.0(jiti@2.5.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color - '@typescript-eslint/visitor-keys@8.39.1': + '@typescript-eslint/visitor-keys@8.43.0': dependencies: - '@typescript-eslint/types': 8.39.1 + '@typescript-eslint/types': 8.43.0 eslint-visitor-keys: 4.2.1 '@ungap/structured-clone@1.3.0': {} - '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.5)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 ast-v8-to-istanbul: 0.3.3 - debug: 4.4.1 + debug: 4.4.3 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 istanbul-reports: 3.1.7 - magic-string: 0.30.17 + magic-string: 0.30.19 magicast: 0.3.5 std-env: 3.9.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.5)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) transitivePeerDependencies: - supports-color - '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': + '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.1)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 1.0.2 ast-v8-to-istanbul: 0.3.3 - debug: 4.4.1 + debug: 4.4.3 istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 5.0.6 istanbul-reports: 3.1.7 - magic-string: 0.30.17 + magic-string: 0.30.19 magicast: 0.3.5 std-env: 3.9.0 test-exclude: 7.0.1 tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) - transitivePeerDependencies: - - supports-color - - '@vitest/coverage-v8@3.2.4(vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': - dependencies: - '@ampproject/remapping': 2.3.0 - '@bcoe/v8-coverage': 1.0.2 - ast-v8-to-istanbul: 0.3.3 - debug: 4.4.1 - istanbul-lib-coverage: 3.2.2 - istanbul-lib-report: 3.0.1 - istanbul-lib-source-maps: 5.0.6 - istanbul-reports: 3.1.7 - magic-string: 0.30.17 - magicast: 0.3.5 - std-env: 3.9.0 - test-exclude: 7.0.1 - tinyrainbow: 2.0.0 - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@24.5.1)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) transitivePeerDependencies: - supports-color @@ -16861,21 +16407,21 @@ snapshots: chai: 5.2.0 tinyrainbow: 2.0.0 - '@vitest/mocker@3.2.4(vite@7.1.5(@types/node@22.18.4)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': + '@vitest/mocker@3.2.4(vite@7.1.5(@types/node@22.18.5)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 - magic-string: 0.30.17 + magic-string: 0.30.19 optionalDependencies: - vite: 7.1.5(@types/node@22.18.4)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vite: 7.1.5(@types/node@22.18.5)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) - '@vitest/mocker@3.2.4(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': + '@vitest/mocker@3.2.4(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1))': dependencies: '@vitest/spy': 3.2.4 estree-walker: 3.0.3 - magic-string: 0.30.17 + magic-string: 0.30.19 optionalDependencies: - vite: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vite: 7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) '@vitest/pretty-format@3.2.4': dependencies: @@ -16890,7 +16436,7 @@ snapshots: '@vitest/snapshot@3.2.4': dependencies: '@vitest/pretty-format': 3.2.4 - magic-string: 0.30.17 + magic-string: 0.30.19 pathe: 2.0.3 '@vitest/spy@3.2.4': @@ -16987,10 +16533,10 @@ snapshots: dependencies: '@namnode/store': 0.1.0 - '@zoom-image/svelte@0.3.4(svelte@5.35.5)': + '@zoom-image/svelte@0.3.4(svelte@5.38.10)': dependencies: '@zoom-image/core': 0.41.0 - svelte: 5.35.5 + svelte: 5.38.10 abab@2.0.6: optional: true @@ -17041,7 +16587,7 @@ snapshots: agent-base@6.0.2: dependencies: - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -17052,14 +16598,6 @@ snapshots: clean-stack: 2.2.0 indent-string: 4.0.0 - ajv-draft-04@1.0.0(ajv@8.11.0): - optionalDependencies: - ajv: 8.11.0 - - ajv-formats@2.1.1(ajv@8.11.0): - optionalDependencies: - ajv: 8.11.0 - ajv-formats@2.1.1(ajv@8.17.1): optionalDependencies: ajv: 8.17.1 @@ -17084,13 +16622,6 @@ snapshots: json-schema-traverse: 0.4.1 uri-js: 4.4.1 - ajv@8.11.0: - dependencies: - fast-deep-equal: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - uri-js: 4.4.1 - ajv@8.17.1: dependencies: fast-deep-equal: 3.1.3 @@ -17133,7 +16664,7 @@ snapshots: ansi-regex@5.0.1: {} - ansi-regex@6.2.0: {} + ansi-regex@6.2.2: {} ansi-styles@4.3.0: dependencies: @@ -17141,7 +16672,7 @@ snapshots: ansi-styles@5.2.0: {} - ansi-styles@6.2.1: {} + ansi-styles@6.2.3: {} ansis@4.1.0: {} @@ -17231,10 +16762,6 @@ snapshots: async@0.2.10: {} - async@3.2.2: {} - - async@3.2.4: {} - async@3.2.6: {} asynckit@0.4.0: {} @@ -17346,15 +16873,15 @@ snapshots: binary-extensions@2.3.0: {} - bits-ui@2.9.9(@internationalized/date@3.8.2)(svelte@5.35.5): + bits-ui@2.9.8(@internationalized/date@3.8.2)(svelte@5.38.10): dependencies: '@floating-ui/core': 1.7.3 '@floating-ui/dom': 1.7.4 '@internationalized/date': 3.8.2 esm-env: 1.2.2 - runed: 0.29.2(svelte@5.35.5) - svelte: 5.35.5 - svelte-toolbelt: 0.9.3(svelte@5.35.5) + runed: 0.29.2(svelte@5.38.10) + svelte: 5.38.10 + svelte-toolbelt: 0.9.3(svelte@5.38.10) tabbable: 6.2.0 bl@4.1.0: @@ -17384,12 +16911,12 @@ snapshots: dependencies: bytes: 3.1.2 content-type: 1.0.5 - debug: 4.4.1 + debug: 4.4.3 http-errors: 2.0.0 iconv-lite: 0.6.3 on-finished: 2.4.1 qs: 6.14.0 - raw-body: 3.0.0 + raw-body: 3.0.1 type-is: 2.0.1 transitivePeerDependencies: - supports-color @@ -17418,7 +16945,7 @@ snapshots: dependencies: ansi-align: 3.0.1 camelcase: 7.0.1 - chalk: 5.6.0 + chalk: 5.6.2 cli-boxes: 3.0.0 string-width: 5.1.2 type-fest: 2.19.0 @@ -17464,7 +16991,7 @@ snapshots: builtin-modules@5.0.0: {} - bullmq@5.57.0: + bullmq@5.58.5: dependencies: cron-parser: 4.9.0 ioredis: 5.7.0 @@ -17534,8 +17061,6 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 - call-me-maybe@1.0.2: {} - callsites@3.1.0: {} camel-case@4.1.2: @@ -17595,7 +17120,7 @@ snapshots: ansi-styles: 4.3.0 supports-color: 7.2.0 - chalk@5.6.0: {} + chalk@5.6.2: {} change-case@5.4.4: {} @@ -17609,12 +17134,8 @@ snapshots: character-reference-invalid@2.0.1: {} - chardet@0.7.0: {} - chardet@2.1.0: {} - charset@1.0.1: {} - check-error@2.1.1: {} cheerio-select@2.1.0: @@ -17674,7 +17195,7 @@ snapshots: class-validator@0.14.2: dependencies: - '@types/validator': 13.15.2 + '@types/validator': 13.15.3 libphonenumber-js: 1.12.9 validator: 13.15.15 @@ -17742,8 +17263,6 @@ snapshots: clone@1.0.4: {} - clsx@1.2.1: {} - clsx@2.1.1: {} cluster-key-slot@1.1.2: {} @@ -17836,19 +17355,6 @@ snapshots: transitivePeerDependencies: - supports-color - compute-gcd@1.2.1: - dependencies: - validate.io-array: 1.0.6 - validate.io-function: 1.0.2 - validate.io-integer-array: 1.0.0 - - compute-lcm@1.1.2: - dependencies: - compute-gcd: 1.2.1 - validate.io-array: 1.0.6 - validate.io-function: 1.0.2 - validate.io-integer-array: 1.0.0 - concat-map@0.0.1: {} concat-stream@2.0.0: @@ -17977,7 +17483,7 @@ snapshots: cron-parser@4.9.0: dependencies: - luxon: 3.7.1 + luxon: 3.7.2 cron@4.3.0: dependencies: @@ -17990,8 +17496,6 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 - crypto-js@4.2.0: {} - crypto-random-string@4.0.0: dependencies: type-fest: 1.4.0 @@ -18195,7 +17699,7 @@ snapshots: dependencies: ms: 2.1.3 - debug@4.4.1: + debug@4.4.3: dependencies: ms: 2.1.3 @@ -18266,22 +17770,18 @@ snapshots: detect-europe-js@0.1.2: {} - detect-libc@2.0.4: {} + detect-libc@2.1.0: {} detect-node@2.1.0: {} - detect-package-manager@3.0.2: - dependencies: - execa: 5.1.1 - detect-port@1.6.1: dependencies: address: 1.2.2 - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color - devalue@5.1.1: {} + devalue@5.3.2: {} devlop@1.1.0: dependencies: @@ -18318,7 +17818,7 @@ snapshots: docker-modem@5.0.6: dependencies: - debug: 4.4.1 + debug: 4.4.3 readable-stream: 3.6.2 split-ca: 1.0.1 ssh2: 1.16.0 @@ -18337,9 +17837,9 @@ snapshots: transitivePeerDependencies: - supports-color - docusaurus-lunr-search@3.6.0(@docusaurus/core@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + docusaurus-lunr-search@3.6.0(@docusaurus/core@3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(react-dom@18.3.1(react@18.3.1))(react@18.3.1): dependencies: - '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) + '@docusaurus/core': 3.8.1(@mdx-js/react@3.1.1(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) autocomplete.js: 0.37.1 clsx: 2.1.1 gauge: 3.0.2 @@ -18357,129 +17857,6 @@ snapshots: unified: 9.2.2 unist-util-is: 4.1.0 - docusaurus-plugin-openapi@0.7.6(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2): - dependencies: - '@docusaurus/mdx-loader': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/plugin-content-docs': 3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - '@docusaurus/utils': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-common': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@docusaurus/utils-validation': 3.8.1(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - chalk: 4.1.2 - clsx: 1.2.1 - js-yaml: 4.1.0 - json-refs: 3.0.15 - json-schema-resolve-allof: 1.5.0 - lodash: 4.17.21 - openapi-to-postmanv2: 4.25.0(encoding@0.1.13) - postman-collection: 4.5.0 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - webpack: 5.100.2 - transitivePeerDependencies: - - '@docusaurus/faster' - - '@mdx-js/react' - - '@parcel/css' - - '@rspack/core' - - '@swc/core' - - '@swc/css' - - acorn - - bufferutil - - csso - - debug - - encoding - - esbuild - - lightningcss - - supports-color - - typescript - - uglify-js - - utf-8-validate - - webpack-cli - - docusaurus-plugin-proxy@0.7.6: {} - - docusaurus-preset-openapi@0.7.6(@algolia/client-search@5.29.0)(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(@types/react@19.1.13)(acorn@8.15.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1)(search-insights@2.17.3)(typescript@5.9.2): - dependencies: - '@docusaurus/preset-classic': 3.8.1(@algolia/client-search@5.29.0)(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(@types/react@19.1.13)(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.3)(typescript@5.9.2) - docusaurus-plugin-openapi: 0.7.6(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - docusaurus-plugin-proxy: 0.7.6 - docusaurus-theme-openapi: 0.7.6(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@types/react@19.1.13)(acorn@8.15.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1)(typescript@5.9.2) - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - transitivePeerDependencies: - - '@algolia/client-search' - - '@docusaurus/faster' - - '@docusaurus/plugin-content-docs' - - '@mdx-js/react' - - '@parcel/css' - - '@rspack/core' - - '@swc/core' - - '@swc/css' - - '@types/react' - - acorn - - bufferutil - - csso - - debug - - encoding - - esbuild - - lightningcss - - react-native - - redux - - search-insights - - supports-color - - typescript - - uglify-js - - utf-8-validate - - webpack-cli - - docusaurus-theme-openapi@0.7.6(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(@types/react@19.1.13)(acorn@8.15.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(redux@4.2.1)(typescript@5.9.2): - dependencies: - '@docusaurus/theme-common': 3.8.1(@docusaurus/plugin-content-docs@3.8.1(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2))(acorn@8.15.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@mdx-js/react': 3.1.0(@types/react@19.1.13)(react@18.3.1) - '@monaco-editor/react': 4.7.0(monaco-editor@0.31.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - '@reduxjs/toolkit': 1.9.7(react-redux@7.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1) - buffer: 6.0.3 - clsx: 1.2.1 - crypto-js: 4.2.0 - docusaurus-plugin-openapi: 0.7.6(@mdx-js/react@3.1.0(@types/react@19.1.13)(react@18.3.1))(acorn@8.15.0)(encoding@0.1.13)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(typescript@5.9.2) - immer: 9.0.21 - lodash: 4.17.21 - marked: 11.2.0 - monaco-editor: 0.31.1 - postman-code-generators: 1.14.2 - postman-collection: 4.5.0 - prism-react-renderer: 2.4.1(react@18.3.1) - process: 0.11.10 - react: 18.3.1 - react-dom: 18.3.1(react@18.3.1) - react-magic-dropzone: 1.0.1 - react-redux: 7.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1) - redux-devtools-extension: 2.13.9(redux@4.2.1) - refractor: 4.9.0 - striptags: 3.2.0 - webpack: 5.100.2 - transitivePeerDependencies: - - '@docusaurus/faster' - - '@docusaurus/plugin-content-docs' - - '@parcel/css' - - '@rspack/core' - - '@swc/core' - - '@swc/css' - - '@types/react' - - acorn - - bufferutil - - csso - - debug - - encoding - - esbuild - - lightningcss - - react-native - - redux - - supports-color - - typescript - - uglify-js - - utf-8-validate - - webpack-cli - dom-accessibility-api@0.5.16: {} dom-accessibility-api@0.6.3: {} @@ -18538,7 +17915,7 @@ snapshots: dependencies: is-obj: 2.0.0 - dotenv@17.2.1: {} + dotenv@17.2.2: {} dunder-proto@1.0.1: dependencies: @@ -18558,7 +17935,7 @@ snapshots: electron-to-chromium@1.5.207: {} - emoji-regex@10.4.0: {} + emoji-regex@10.5.0: {} emoji-regex@8.0.0: {} @@ -18600,7 +17977,7 @@ snapshots: engine.io@6.6.4: dependencies: '@types/cors': 2.8.19 - '@types/node': 22.18.4 + '@types/node': 22.18.5 accepts: 1.3.8 base64id: 2.0.0 cookie: 0.7.2 @@ -18628,7 +18005,7 @@ snapshots: err-code@2.0.3: {} - error-ex@1.3.2: + error-ex@1.3.4: dependencies: is-arrayish: 0.2.1 @@ -18662,8 +18039,6 @@ snapshots: es5-ext: 0.10.64 es6-symbol: 3.1.4 - es6-promise@3.3.1: {} - es6-symbol@3.1.4: dependencies: d: 1.0.2 @@ -18766,70 +18141,70 @@ snapshots: source-map: 0.6.1 optional: true - eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@2.5.1)): + eslint-config-prettier@10.1.8(eslint@9.35.0(jiti@2.5.1)): dependencies: - eslint: 9.33.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) - eslint-p@0.25.0(jiti@2.5.1): + eslint-p@0.26.0(jiti@2.5.1): dependencies: - eslint: 9.30.1(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) transitivePeerDependencies: - jiti - supports-color - eslint-plugin-compat@6.0.2(eslint@9.33.0(jiti@2.5.1)): + eslint-plugin-compat@6.0.2(eslint@9.35.0(jiti@2.5.1)): dependencies: '@mdn/browser-compat-data': 5.7.6 ast-metadata-inferer: 0.8.1 browserslist: 4.25.3 caniuse-lite: 1.0.30001735 - eslint: 9.33.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) find-up: 5.0.0 globals: 15.15.0 lodash.memoize: 4.1.2 semver: 7.7.2 - eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.33.0(jiti@2.5.1)))(eslint@9.33.0(jiti@2.5.1))(prettier@3.6.2): + eslint-plugin-prettier@5.5.4(@types/eslint@9.6.1)(eslint-config-prettier@10.1.8(eslint@9.35.0(jiti@2.5.1)))(eslint@9.35.0(jiti@2.5.1))(prettier@3.6.2): dependencies: - eslint: 9.33.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) prettier: 3.6.2 prettier-linter-helpers: 1.0.0 synckit: 0.11.11 optionalDependencies: '@types/eslint': 9.6.1 - eslint-config-prettier: 10.1.8(eslint@9.33.0(jiti@2.5.1)) + eslint-config-prettier: 10.1.8(eslint@9.35.0(jiti@2.5.1)) - eslint-plugin-svelte@3.11.0(eslint@9.33.0(jiti@2.5.1))(svelte@5.35.5): + eslint-plugin-svelte@3.12.3(eslint@9.35.0(jiti@2.5.1))(svelte@5.38.10): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.33.0(jiti@2.5.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) '@jridgewell/sourcemap-codec': 1.5.5 - eslint: 9.33.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) esutils: 2.0.3 - globals: 16.3.0 + globals: 16.4.0 known-css-properties: 0.37.0 postcss: 8.5.6 postcss-load-config: 3.1.4(postcss@8.5.6) postcss-safe-parser: 7.0.1(postcss@8.5.6) semver: 7.7.2 - svelte-eslint-parser: 1.3.1(svelte@5.35.5) + svelte-eslint-parser: 1.3.2(svelte@5.38.10) optionalDependencies: - svelte: 5.35.5 + svelte: 5.38.10 transitivePeerDependencies: - ts-node - eslint-plugin-unicorn@60.0.0(eslint@9.33.0(jiti@2.5.1)): + eslint-plugin-unicorn@60.0.0(eslint@9.35.0(jiti@2.5.1)): dependencies: '@babel/helper-validator-identifier': 7.27.1 - '@eslint-community/eslint-utils': 4.7.0(eslint@9.33.0(jiti@2.5.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) '@eslint/plugin-kit': 0.3.5 change-case: 5.4.4 ci-info: 4.3.0 clean-regexp: 1.0.0 core-js-compat: 3.45.0 - eslint: 9.33.0(jiti@2.5.1) + eslint: 9.35.0(jiti@2.5.1) esquery: 1.6.0 find-up-simple: 1.0.1 - globals: 16.3.0 + globals: 16.4.0 indent-string: 5.0.0 is-builtin-module: 5.0.0 jsesc: 3.1.0 @@ -18853,59 +18228,17 @@ snapshots: eslint-visitor-keys@4.2.1: {} - eslint@9.30.1(jiti@2.5.1): + eslint@9.35.0(jiti@2.5.1): dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.30.1(jiti@2.5.1)) - '@eslint-community/regexpp': 4.12.1 - '@eslint/config-array': 0.21.0 - '@eslint/config-helpers': 0.3.1 - '@eslint/core': 0.14.0 - '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.30.1 - '@eslint/plugin-kit': 0.3.5 - '@humanfs/node': 0.16.6 - '@humanwhocodes/module-importer': 1.0.1 - '@humanwhocodes/retry': 0.4.3 - '@types/estree': 1.0.8 - '@types/json-schema': 7.0.15 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.6 - debug: 4.4.1 - escape-string-regexp: 4.0.0 - eslint-scope: 8.4.0 - eslint-visitor-keys: 4.2.1 - espree: 10.4.0 - esquery: 1.6.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 8.0.0 - find-up: 5.0.0 - glob-parent: 6.0.2 - ignore: 5.3.2 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - json-stable-stringify-without-jsonify: 1.0.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.4 - optionalDependencies: - jiti: 2.5.1 - transitivePeerDependencies: - - supports-color - - eslint@9.33.0(jiti@2.5.1): - dependencies: - '@eslint-community/eslint-utils': 4.7.0(eslint@9.33.0(jiti@2.5.1)) + '@eslint-community/eslint-utils': 4.9.0(eslint@9.35.0(jiti@2.5.1)) '@eslint-community/regexpp': 4.12.1 '@eslint/config-array': 0.21.0 '@eslint/config-helpers': 0.3.1 '@eslint/core': 0.15.2 '@eslint/eslintrc': 3.3.1 - '@eslint/js': 9.33.0 + '@eslint/js': 9.35.0 '@eslint/plugin-kit': 0.3.5 - '@humanfs/node': 0.16.6 + '@humanfs/node': 0.16.7 '@humanwhocodes/module-importer': 1.0.1 '@humanwhocodes/retry': 0.4.3 '@types/estree': 1.0.8 @@ -18913,7 +18246,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.6 - debug: 4.4.1 + debug: 4.4.3 escape-string-regexp: 4.0.0 eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -19019,7 +18352,7 @@ snapshots: eval@0.1.8: dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 require-like: 0.1.2 event-emitter@0.3.5: @@ -19057,7 +18390,7 @@ snapshots: batch-cluster: 13.0.0 exiftool-vendored.pl: 13.0.1 he: 1.2.0 - luxon: 3.7.1 + luxon: 3.7.2 optionalDependencies: exiftool-vendored.exe: 13.0.0 @@ -19109,7 +18442,7 @@ snapshots: content-type: 1.0.5 cookie: 0.7.2 cookie-signature: 1.2.2 - debug: 4.4.1 + debug: 4.4.3 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 @@ -19145,12 +18478,6 @@ snapshots: extend@3.0.2: {} - external-editor@3.1.0: - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - fabric@6.7.1: optionalDependencies: canvas: 2.11.2 @@ -19243,8 +18570,6 @@ snapshots: transitivePeerDependencies: - supports-color - file-type@3.9.0: {} - fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 @@ -19263,7 +18588,7 @@ snapshots: finalhandler@2.1.0: dependencies: - debug: 4.4.1 + debug: 4.4.3 encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 @@ -19310,14 +18635,12 @@ snapshots: follow-redirects@1.15.9: {} - foreach@2.0.6: {} - foreground-child@3.3.1: dependencies: cross-spawn: 7.0.6 signal-exit: 4.1.0 - fork-ts-checker-webpack-plugin@9.1.0(typescript@5.8.3)(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))): + fork-ts-checker-webpack-plugin@9.1.0(typescript@5.8.3)(webpack@5.100.2(@swc/core@1.13.5(@swc/helpers@0.5.17))): dependencies: '@babel/code-frame': 7.27.1 chalk: 4.1.2 @@ -19332,7 +18655,7 @@ snapshots: semver: 7.7.2 tapable: 2.2.2 typescript: 5.8.3 - webpack: 5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17)) + webpack: 5.100.2(@swc/core@1.13.5(@swc/helpers@0.5.17)) form-data-encoder@2.1.4: {} @@ -19346,13 +18669,6 @@ snapshots: format@0.2.2: {} - formidable@2.1.5: - dependencies: - '@paralleldrive/cuid2': 2.2.2 - dezalgo: 1.0.4 - once: 1.4.0 - qs: 6.14.0 - formidable@3.5.4: dependencies: '@paralleldrive/cuid2': 2.2.2 @@ -19440,7 +18756,7 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.3.0: {} + get-east-asian-width@1.4.0: {} get-intrinsic@1.3.0: dependencies: @@ -19464,8 +18780,6 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 - get-stdin@5.0.1: {} - get-stream@6.0.1: {} github-slugger@1.5.0: {} @@ -19519,7 +18833,7 @@ snapshots: globals@15.15.0: {} - globals@16.3.0: {} + globals@16.4.0: {} globalyzer@0.1.0: {} @@ -19564,10 +18878,6 @@ snapshots: graphemer@1.4.0: {} - graphlib@2.1.8: - dependencies: - lodash: 4.17.21 - gray-matter@4.0.3: dependencies: js-yaml: 3.14.1 @@ -19646,10 +18956,6 @@ snapshots: hast-util-parse-selector@2.2.5: {} - hast-util-parse-selector@3.1.1: - dependencies: - '@types/hast': 2.3.10 - hast-util-parse-selector@4.0.0: dependencies: '@types/hast': 3.0.4 @@ -19760,14 +19066,6 @@ snapshots: property-information: 5.6.0 space-separated-tokens: 1.1.5 - hastscript@7.2.0: - dependencies: - '@types/hast': 2.3.10 - comma-separated-tokens: 2.0.3 - hast-util-parse-selector: 3.1.1 - property-information: 6.5.0 - space-separated-tokens: 2.0.2 - hastscript@9.0.1: dependencies: '@types/hast': 3.0.4 @@ -19911,7 +19209,7 @@ snapshots: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color optional: true @@ -19919,7 +19217,7 @@ snapshots: http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.4 - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -19943,10 +19241,6 @@ snapshots: transitivePeerDependencies: - debug - http-reasons@0.1.0: {} - - http2-client@1.3.5: {} - http2-wrapper@2.2.1: dependencies: quick-lru: 5.1.1 @@ -19955,14 +19249,14 @@ snapshots: https-proxy-agent@5.0.1: dependencies: agent-base: 6.0.2 - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color https-proxy-agent@7.0.6: dependencies: agent-base: 7.1.4 - debug: 4.4.1 + debug: 4.4.3 transitivePeerDependencies: - supports-color @@ -19980,6 +19274,10 @@ snapshots: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.7.0: + dependencies: + safer-buffer: 2.1.2 + icss-utils@5.1.0(postcss@8.5.6): dependencies: postcss: 8.5.6 @@ -19996,8 +19294,6 @@ snapshots: immediate@3.3.0: {} - immer@9.0.21: {} - import-fresh@3.3.1: dependencies: parent-module: 1.0.1 @@ -20035,13 +19331,13 @@ snapshots: inline-style-parser@0.2.4: {} - inquirer@8.2.6: + inquirer@8.2.7(@types/node@22.18.5): dependencies: + '@inquirer/external-editor': 1.0.2(@types/node@22.18.5) ansi-escapes: 4.3.2 chalk: 4.1.2 cli-cursor: 3.1.0 cli-width: 3.0.0 - external-editor: 3.1.0 figures: 3.2.0 lodash: 4.17.21 mute-stream: 0.0.8 @@ -20052,11 +19348,11 @@ snapshots: strip-ansi: 6.0.1 through: 2.3.8 wrap-ansi: 6.2.0 + transitivePeerDependencies: + - '@types/node' internmap@2.0.3: {} - interpret@1.4.0: {} - intl-messageformat@10.7.16: dependencies: '@formatjs/ecma402-abstract': 2.3.4 @@ -20072,7 +19368,7 @@ snapshots: dependencies: '@ioredis/commands': 1.3.0 cluster-key-slot: 1.1.2 - debug: 4.4.1 + debug: 4.4.3 denque: 2.1.0 lodash.defaults: 4.2.0 lodash.isarguments: 3.1.0 @@ -20216,7 +19512,7 @@ snapshots: istanbul-lib-source-maps@5.0.6: dependencies: '@jridgewell/trace-mapping': 0.3.30 - debug: 4.4.1 + debug: 4.4.3 istanbul-lib-coverage: 3.2.2 transitivePeerDependencies: - supports-color @@ -20241,7 +19537,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.18.4 + '@types/node': 22.18.5 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -20249,13 +19545,13 @@ snapshots: jest-worker@27.5.1: dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 merge-stream: 2.0.0 supports-color: 8.1.1 jest-worker@29.7.0: dependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -20276,7 +19572,7 @@ snapshots: jose@5.10.0: {} - jose@6.0.12: {} + jose@6.1.0: {} js-tokens@4.0.0: {} @@ -20395,38 +19691,6 @@ snapshots: json-parse-even-better-errors@2.3.1: {} - json-pointer@0.6.2: - dependencies: - foreach: 2.0.6 - - json-refs@3.0.15: - dependencies: - commander: 4.1.1 - graphlib: 2.1.8 - js-yaml: 3.14.1 - lodash: 4.17.21 - native-promise-only: 0.8.1 - path-loader: 1.0.12 - slash: 3.0.0 - uri-js: 4.4.1 - transitivePeerDependencies: - - supports-color - - json-schema-compare@0.2.2: - dependencies: - lodash: 4.17.21 - - json-schema-merge-allof@0.8.1: - dependencies: - compute-lcm: 1.1.2 - json-schema-compare: 0.2.2 - lodash: 4.17.21 - - json-schema-resolve-allof@1.5.0: - dependencies: - get-stdin: 5.0.1 - lodash: 4.17.21 - json-schema-traverse@0.4.1: {} json-schema-traverse@1.0.0: {} @@ -20555,7 +19819,7 @@ snapshots: lightningcss@1.30.1: dependencies: - detect-libc: 2.0.4 + detect-libc: 2.1.0 optionalDependencies: lightningcss-darwin-arm64: 1.30.1 lightningcss-darwin-x64: 1.30.1 @@ -20574,8 +19838,6 @@ snapshots: lines-and-columns@1.2.4: {} - liquid-json@0.3.1: {} - load-esm@1.0.2: {} load-tsconfig@0.2.5: {} @@ -20627,13 +19889,13 @@ snapshots: log-symbols@6.0.0: dependencies: - chalk: 5.6.0 + chalk: 5.6.2 is-unicode-supported: 1.3.0 log-symbols@7.0.1: dependencies: is-unicode-supported: 2.1.0 - yoctocolors: 2.1.1 + yoctocolors: 2.1.2 long@5.3.2: {} @@ -20653,7 +19915,7 @@ snapshots: lru-cache@10.4.3: {} - lru-cache@11.1.0: {} + lru-cache@11.2.1: {} lru-cache@5.1.1: dependencies: @@ -20669,7 +19931,7 @@ snapshots: luxon@3.6.1: {} - luxon@3.7.1: {} + luxon@3.7.2: {} lz-string@1.5.0: {} @@ -20677,10 +19939,14 @@ snapshots: dependencies: '@jridgewell/sourcemap-codec': 1.5.5 + magic-string@0.30.19: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + magicast@0.3.5: dependencies: - '@babel/parser': 7.28.3 - '@babel/types': 7.28.2 + '@babel/parser': 7.28.4 + '@babel/types': 7.28.4 source-map-js: 1.2.1 make-dir@3.1.0: @@ -20732,7 +19998,7 @@ snapshots: tinyqueue: 2.0.3 vt-pbf: 3.1.3 - maplibre-gl@5.6.2: + maplibre-gl@5.7.1: dependencies: '@mapbox/geojson-rewind': 0.5.2 '@mapbox/jsonlint-lines-primitives': 2.0.2 @@ -20767,8 +20033,6 @@ snapshots: markdown-table@3.0.4: {} - marked@11.2.0: {} - marked@7.0.4: {} math-intrinsics@1.1.0: {} @@ -21275,7 +20539,7 @@ snapshots: micromark@4.0.2: dependencies: '@types/debug': 4.1.12 - debug: 4.4.1 + debug: 4.4.3 decode-named-character-reference: 1.2.0 devlop: 1.1.0 micromark-core-commonmark: 2.0.3 @@ -21305,10 +20569,6 @@ snapshots: mime-db@1.54.0: {} - mime-format@2.0.1: - dependencies: - charset: 1.0.1 - mime-types@2.1.18: dependencies: mime-db: 1.33.0 @@ -21425,8 +20685,6 @@ snapshots: module-details-from-path@1.0.4: {} - monaco-editor@0.31.1: {} - moo@0.5.2: {} mri@1.2.0: {} @@ -21487,8 +20745,6 @@ snapshots: nanoid@5.1.5: {} - native-promise-only@0.8.1: {} - natural-compare@1.4.0: {} nearley@2.20.1: @@ -21506,9 +20762,7 @@ snapshots: neo-async@2.6.2: {} - neotraverse@0.6.15: {} - - nest-commander@3.18.0(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6)(@types/inquirer@8.2.11)(typescript@5.9.2): + nest-commander@3.19.1(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6)(@types/inquirer@8.2.11)(@types/node@22.18.5)(typescript@5.9.2): dependencies: '@fig/complete-commander': 3.2.0(commander@11.1.0) '@golevelup/nestjs-discovery': 4.0.3(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6) @@ -21517,8 +20771,9 @@ snapshots: '@types/inquirer': 8.2.11 commander: 11.1.0 cosmiconfig: 8.3.6(typescript@5.9.2) - inquirer: 8.2.6 + inquirer: 8.2.7(@types/node@22.18.5) transitivePeerDependencies: + - '@types/node' - typescript nestjs-cls@5.4.3(@nestjs/common@11.1.6(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.6)(reflect-metadata@0.2.2)(rxjs@7.8.2): @@ -21569,10 +20824,6 @@ snapshots: emojilib: 2.4.0 skin-tone: 2.0.0 - node-fetch-h2@2.3.0: - dependencies: - http2-client: 1.3.5 - node-fetch@2.7.0: dependencies: whatwg-url: 5.0.0 @@ -21588,12 +20839,12 @@ snapshots: node-gyp-build-optional-packages@5.2.2: dependencies: - detect-libc: 2.0.4 + detect-libc: 2.1.0 optional: true node-gyp-build@4.8.4: {} - node-gyp@11.3.0: + node-gyp@11.4.2: dependencies: env-paths: 2.2.1 exponential-backoff: 3.1.2 @@ -21608,13 +20859,9 @@ snapshots: transitivePeerDependencies: - supports-color - node-readfiles@0.2.0: - dependencies: - es6-promise: 3.3.1 - node-releases@2.0.19: {} - nodemailer@7.0.5: {} + nodemailer@7.0.6: {} nopt@1.0.10: dependencies: @@ -21669,50 +20916,10 @@ snapshots: citty: 0.1.6 consola: 3.4.2 pathe: 2.0.3 - pkg-types: 2.2.0 + pkg-types: 2.3.0 tinyexec: 0.3.2 - oas-kit-common@1.0.8: - dependencies: - fast-safe-stringify: 2.1.1 - - oas-linter@3.2.2: - dependencies: - '@exodus/schemasafe': 1.3.0 - should: 13.2.3 - yaml: 1.10.2 - - oas-resolver-browser@2.5.6: - dependencies: - node-fetch-h2: 2.3.0 - oas-kit-common: 1.0.8 - path-browserify: 1.0.1 - reftools: 1.1.9 - yaml: 1.10.2 - yargs: 17.7.2 - - oas-resolver@2.5.6: - dependencies: - node-fetch-h2: 2.3.0 - oas-kit-common: 1.0.8 - reftools: 1.1.9 - yaml: 1.10.2 - yargs: 17.7.2 - - oas-schema-walker@1.1.5: {} - - oas-validator@5.0.8: - dependencies: - call-me-maybe: 1.0.2 - oas-kit-common: 1.0.8 - oas-linter: 3.2.2 - oas-resolver: 2.5.6 - oas-schema-walker: 1.1.5 - reftools: 1.1.9 - should: 13.2.3 - yaml: 1.10.2 - - oauth4webapi@3.7.0: {} + oauth4webapi@3.8.1: {} object-assign@4.1.1: {} @@ -21735,18 +20942,18 @@ snapshots: obuf@1.1.2: {} - oidc-provider@9.4.1: + oidc-provider@9.5.1: dependencies: '@koa/cors': 5.0.0 '@koa/router': 14.0.0 - debug: 4.4.1 + debug: 4.4.3 eta: 3.5.0 - jose: 6.0.12 + jose: 6.1.0 jsesc: 3.1.0 koa: 3.0.1 nanoid: 5.1.5 - quick-lru: 7.0.1 - raw-body: 3.0.0 + quick-lru: 7.2.0 + raw-body: 3.0.1 transitivePeerDependencies: - supports-color @@ -21774,34 +20981,12 @@ snapshots: is-docker: 2.2.1 is-wsl: 2.2.0 - openapi-to-postmanv2@4.25.0(encoding@0.1.13): - dependencies: - ajv: 8.11.0 - ajv-draft-04: 1.0.0(ajv@8.11.0) - ajv-formats: 2.1.1(ajv@8.11.0) - async: 3.2.4 - commander: 2.20.3 - graphlib: 2.1.8 - js-yaml: 4.1.0 - json-pointer: 0.6.2 - json-schema-merge-allof: 0.8.1 - lodash: 4.17.21 - neotraverse: 0.6.15 - oas-resolver-browser: 2.5.6 - object-hash: 3.0.0 - path-browserify: 1.0.1 - postman-collection: 4.5.0 - swagger2openapi: 7.0.8(encoding@0.1.13) - yaml: 1.10.2 - transitivePeerDependencies: - - encoding - opener@1.5.2: {} - openid-client@6.6.4: + openid-client@6.8.0: dependencies: - jose: 6.0.12 - oauth4webapi: 3.7.0 + jose: 6.1.0 + oauth4webapi: 3.8.1 optionator@0.9.4: dependencies: @@ -21826,7 +21011,7 @@ snapshots: ora@8.2.0: dependencies: - chalk: 5.6.0 + chalk: 5.6.2 cli-cursor: 5.0.0 cli-spinners: 2.9.2 is-interactive: 2.0.0 @@ -21834,9 +21019,7 @@ snapshots: log-symbols: 6.0.0 stdin-discarder: 0.2.2 string-width: 7.2.0 - strip-ansi: 7.1.0 - - os-tmpdir@1.0.2: {} + strip-ansi: 7.1.2 p-cancelable@3.0.0: {} @@ -21919,7 +21102,7 @@ snapshots: parse-json@5.2.0: dependencies: '@babel/code-frame': 7.27.1 - error-ex: 1.3.2 + error-ex: 1.3.4 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -21950,8 +21133,6 @@ snapshots: no-case: 3.0.4 tslib: 2.8.1 - path-browserify@1.0.1: {} - path-exists@4.0.0: {} path-exists@5.0.0: {} @@ -21962,13 +21143,6 @@ snapshots: path-key@3.1.1: {} - path-loader@1.0.12: - dependencies: - native-promise-only: 0.8.1 - superagent: 7.1.6 - transitivePeerDependencies: - - supports-color - path-parse@1.0.7: {} path-scurry@1.11.1: @@ -21978,7 +21152,7 @@ snapshots: path-scurry@2.0.0: dependencies: - lru-cache: 11.1.0 + lru-cache: 11.2.1 minipass: 7.1.2 path-source@0.1.3: @@ -21996,12 +21170,9 @@ snapshots: path-to-regexp@8.2.0: {} - path-type@4.0.0: {} + path-to-regexp@8.3.0: {} - path@0.12.7: - dependencies: - process: 0.11.10 - util: 0.10.4 + path-type@4.0.0: {} pathe@2.0.3: {} @@ -22069,17 +21240,17 @@ snapshots: dependencies: find-up: 6.3.0 - pkg-types@2.2.0: + pkg-types@2.3.0: dependencies: confbox: 0.2.2 exsolve: 1.0.7 pathe: 2.0.3 - playwright-core@1.54.2: {} + playwright-core@1.55.0: {} - playwright@1.54.2: + playwright@1.55.0: dependencies: - playwright-core: 1.54.2 + playwright-core: 1.55.0 optionalDependencies: fsevents: 2.3.2 @@ -22087,7 +21258,7 @@ snapshots: pmtiles@3.2.1: dependencies: - '@types/leaflet': 1.9.19 + '@types/leaflet': 1.9.20 fflate: 0.8.2 pmtiles@4.3.0: @@ -22242,7 +21413,7 @@ snapshots: read-cache: 1.0.0 resolve: 1.22.10 - postcss-js@4.0.1(postcss@8.5.6): + postcss-js@4.1.0(postcss@8.5.6): dependencies: camelcase-css: 2.0.1 postcss: 8.5.6 @@ -22587,33 +21758,6 @@ snapshots: postgres@3.4.7: {} - postman-code-generators@1.14.2: - dependencies: - async: 3.2.2 - detect-package-manager: 3.0.2 - lodash: 4.17.21 - path: 0.12.7 - postman-collection: 4.5.0 - shelljs: 0.8.5 - - postman-collection@4.5.0: - dependencies: - '@faker-js/faker': 5.5.3 - file-type: 3.9.0 - http-reasons: 0.1.0 - iconv-lite: 0.6.3 - liquid-json: 0.3.1 - lodash: 4.17.21 - mime-format: 2.0.1 - mime-types: 2.1.35 - postman-url-encoder: 3.0.5 - semver: 7.6.3 - uuid: 8.3.2 - - postman-url-encoder@3.0.5: - dependencies: - punycode: 2.3.1 - potpack@1.0.2: {} potpack@2.1.0: {} @@ -22633,10 +21777,10 @@ snapshots: dependencies: prettier: 3.6.2 - prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@5.35.5): + prettier-plugin-svelte@3.4.0(prettier@3.6.2)(svelte@5.38.10): dependencies: prettier: 3.6.2 - svelte: 5.35.5 + svelte: 5.38.10 prettier@3.6.2: {} @@ -22715,7 +21859,7 @@ snapshots: '@protobufjs/path': 1.1.2 '@protobufjs/pool': 1.1.0 '@protobufjs/utf8': 1.1.0 - '@types/node': 22.18.4 + '@types/node': 22.18.5 long: 5.3.2 protocol-buffers-schema@3.6.0: {} @@ -22764,7 +21908,7 @@ snapshots: quick-lru@5.1.1: {} - quick-lru@7.0.1: {} + quick-lru@7.2.0: {} quickselect@2.0.0: {} @@ -22792,11 +21936,11 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 - raw-body@3.0.0: + raw-body@3.0.1: dependencies: bytes: 3.1.2 http-errors: 2.0.0 - iconv-lite: 0.6.3 + iconv-lite: 0.7.0 unpipe: 1.0.0 raw-loader@4.0.2(webpack@5.100.2): @@ -22823,11 +21967,10 @@ snapshots: react: 19.1.1 scheduler: 0.26.0 - react-email@4.2.8: + react-email@4.2.11: dependencies: - '@babel/parser': 7.28.3 - '@babel/traverse': 7.28.3 - chalk: 5.6.0 + '@babel/parser': 7.28.4 + '@babel/traverse': 7.28.4 chokidar: 4.0.3 commander: 13.1.0 debounce: 2.2.0 @@ -22863,24 +22006,10 @@ snapshots: react-loadable: '@docusaurus/react-loadable@6.0.0(react@18.3.1)' webpack: 5.100.2 - react-magic-dropzone@1.0.1: {} - react-promise-suspense@0.3.4: dependencies: fast-deep-equal: 2.0.1 - react-redux@7.2.9(react-dom@18.3.1(react@18.3.1))(react@18.3.1): - dependencies: - '@babel/runtime': 7.28.4 - '@types/react-redux': 7.1.34 - hoist-non-react-statics: 3.3.2 - loose-envify: 1.4.0 - prop-types: 15.8.1 - react: 18.3.1 - react-is: 17.0.2 - optionalDependencies: - react-dom: 18.3.1(react@18.3.1) - react-router-config@5.1.1(react-router@5.3.4(react@18.3.1))(react@18.3.1): dependencies: '@babel/runtime': 7.28.4 @@ -22955,10 +22084,6 @@ snapshots: readdirp@4.1.2: {} - rechoir@0.6.2: - dependencies: - resolve: 1.22.10 - recma-build-jsx@1.0.0: dependencies: '@types/estree': 1.0.8 @@ -23000,29 +22125,8 @@ snapshots: dependencies: redis-errors: 1.2.0 - redux-devtools-extension@2.13.9(redux@4.2.1): - dependencies: - redux: 4.2.1 - - redux-thunk@2.4.2(redux@4.2.1): - dependencies: - redux: 4.2.1 - - redux@4.2.1: - dependencies: - '@babel/runtime': 7.28.4 - reflect-metadata@0.2.2: {} - refractor@4.9.0: - dependencies: - '@types/hast': 2.3.10 - '@types/prismjs': 1.26.5 - hastscript: 7.2.0 - parse-entities: 4.0.2 - - reftools@1.1.9: {} - regenerate-unicode-properties@10.2.0: dependencies: regenerate: 1.4.2 @@ -23158,7 +22262,7 @@ snapshots: require-in-the-middle@7.5.2: dependencies: - debug: 4.4.1 + debug: 4.4.3 module-details-from-path: 1.0.4 resolve: 1.22.10 transitivePeerDependencies: @@ -23170,8 +22274,6 @@ snapshots: requires-port@1.0.0: {} - reselect@4.1.8: {} - resolve-alpn@1.2.1: {} resolve-from@4.0.0: {} @@ -23259,11 +22361,11 @@ snapshots: router@2.2.0: dependencies: - debug: 4.4.1 + debug: 4.4.3 depd: 2.0.0 is-promise: 4.0.0 parseurl: 1.3.3 - path-to-regexp: 8.2.0 + path-to-regexp: 8.3.0 transitivePeerDependencies: - supports-color @@ -23283,10 +22385,10 @@ snapshots: dependencies: queue-microtask: 1.2.3 - runed@0.29.2(svelte@5.35.5): + runed@0.29.2(svelte@5.38.10): dependencies: esm-env: 1.2.2 - svelte: 5.35.5 + svelte: 5.38.10 rw@1.3.3: {} @@ -23373,8 +22475,6 @@ snapshots: semver@6.3.1: {} - semver@7.6.3: {} - semver@7.7.2: {} send@0.19.0: @@ -23397,7 +22497,7 @@ snapshots: send@1.2.0: dependencies: - debug: 4.4.1 + debug: 4.4.3 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 @@ -23490,9 +22590,9 @@ snapshots: sharp@0.34.3: dependencies: color: 4.2.3 - detect-libc: 2.0.4 + detect-libc: 2.1.0 node-addon-api: 8.5.0 - node-gyp: 11.3.0 + node-gyp: 11.4.2 semver: 7.7.2 optionalDependencies: '@img/sharp-darwin-arm64': 0.34.3 @@ -23528,38 +22628,6 @@ snapshots: shell-quote@1.8.3: {} - shelljs@0.8.5: - dependencies: - glob: 7.2.3 - interpret: 1.4.0 - rechoir: 0.6.2 - - should-equal@2.0.0: - dependencies: - should-type: 1.4.0 - - should-format@3.0.3: - dependencies: - should-type: 1.4.0 - should-type-adaptors: 1.1.0 - - should-type-adaptors@1.1.0: - dependencies: - should-type: 1.4.0 - should-util: 1.0.1 - - should-type@1.4.0: {} - - should-util@1.0.1: {} - - should@13.2.3: - dependencies: - should-equal: 2.0.0 - should-format: 3.0.3 - should-type: 1.4.0 - should-type-adaptors: 1.1.0 - should-util: 1.0.1 - side-channel-list@1.0.0: dependencies: es-errors: 1.3.0 @@ -23616,7 +22684,7 @@ snapshots: mrmime: 2.0.1 totalist: 3.0.1 - sirv@3.0.1: + sirv@3.0.2: dependencies: '@polka/url': 1.0.0-next.29 mrmime: 2.0.1 @@ -23698,7 +22766,7 @@ snapshots: socks-proxy-agent@8.0.5: dependencies: agent-base: 7.1.4 - debug: 4.4.1 + debug: 4.4.3 socks: 2.8.7 transitivePeerDependencies: - supports-color @@ -23727,7 +22795,7 @@ snapshots: spdy-transport@3.0.0: dependencies: - debug: 4.4.1 + debug: 4.4.3 detect-node: 2.1.0 hpack.js: 2.1.6 obuf: 1.1.2 @@ -23738,7 +22806,7 @@ snapshots: spdy@4.0.2: dependencies: - debug: 4.4.1 + debug: 4.4.3 handle-thing: 2.0.1 http-deceiver: 1.2.7 select-hose: 2.0.0 @@ -23752,7 +22820,7 @@ snapshots: sprintf-js@1.0.3: {} - sql-formatter@15.6.6: + sql-formatter@15.6.9: dependencies: argparse: 2.0.1 nearley: 2.20.1 @@ -23780,8 +22848,6 @@ snapshots: standard-as-callback@2.1.0: {} - state-local@1.0.7: {} - statuses@1.5.0: {} statuses@2.0.1: {} @@ -23813,13 +22879,13 @@ snapshots: dependencies: eastasianwidth: 0.2.0 emoji-regex: 9.2.2 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 string-width@7.2.0: dependencies: - emoji-regex: 10.4.0 - get-east-asian-width: 1.3.0 - strip-ansi: 7.1.0 + emoji-regex: 10.5.0 + get-east-asian-width: 1.4.0 + strip-ansi: 7.1.2 string_decoder@1.1.1: dependencies: @@ -23844,9 +22910,9 @@ snapshots: dependencies: ansi-regex: 5.0.1 - strip-ansi@7.1.0: + strip-ansi@7.1.2: dependencies: - ansi-regex: 6.2.0 + ansi-regex: 6.2.2 strip-bom-string@1.0.0: {} @@ -23870,8 +22936,6 @@ snapshots: dependencies: js-tokens: 9.0.1 - striptags@3.2.0: {} - strnum@2.1.1: {} strtok3@10.3.4: @@ -23906,7 +22970,7 @@ snapshots: dependencies: component-emitter: 1.3.1 cookiejar: 2.1.4 - debug: 4.4.1 + debug: 4.4.3 fast-safe-stringify: 2.1.1 form-data: 4.0.4 formidable: 3.5.4 @@ -23916,22 +22980,6 @@ snapshots: transitivePeerDependencies: - supports-color - superagent@7.1.6: - dependencies: - component-emitter: 1.3.1 - cookiejar: 2.1.4 - debug: 4.4.1 - fast-safe-stringify: 2.1.1 - form-data: 4.0.4 - formidable: 2.1.5 - methods: 1.1.2 - mime: 2.6.0 - qs: 6.14.0 - readable-stream: 3.6.2 - semver: 7.7.2 - transitivePeerDependencies: - - supports-color - supercluster@7.1.5: dependencies: kdbush: 3.0.0 @@ -23957,19 +23005,19 @@ snapshots: supports-preserve-symlinks-flag@1.0.0: {} - svelte-check@4.3.1(picomatch@4.0.3)(svelte@5.35.5)(typescript@5.9.2): + svelte-check@4.3.1(picomatch@4.0.3)(svelte@5.38.10)(typescript@5.9.2): dependencies: '@jridgewell/trace-mapping': 0.3.30 chokidar: 4.0.3 fdir: 6.5.0(picomatch@4.0.3) picocolors: 1.1.1 sade: 1.8.1 - svelte: 5.35.5 + svelte: 5.38.10 typescript: 5.9.2 transitivePeerDependencies: - picomatch - svelte-eslint-parser@1.3.1(svelte@5.35.5): + svelte-eslint-parser@1.3.2(svelte@5.38.10): dependencies: eslint-scope: 8.4.0 eslint-visitor-keys: 4.2.1 @@ -23978,11 +23026,11 @@ snapshots: postcss-scss: 4.0.9(postcss@8.5.6) postcss-selector-parser: 7.1.0 optionalDependencies: - svelte: 5.35.5 + svelte: 5.38.10 - svelte-gestures@5.1.4: {} + svelte-gestures@5.2.2: {} - svelte-i18n@4.0.1(svelte@5.35.5): + svelte-i18n@4.0.1(svelte@5.38.10): dependencies: cli-color: 2.0.4 deepmerge: 4.3.1 @@ -23990,36 +23038,36 @@ snapshots: estree-walker: 2.0.2 intl-messageformat: 10.7.16 sade: 1.8.1 - svelte: 5.35.5 + svelte: 5.38.10 tiny-glob: 0.2.9 - svelte-maplibre@1.2.0(svelte@5.35.5): + svelte-maplibre@1.2.1(svelte@5.38.10): dependencies: d3-geo: 3.1.1 dequal: 2.0.3 just-compare: 2.3.0 - maplibre-gl: 5.6.2 + maplibre-gl: 5.7.1 pmtiles: 3.2.1 - svelte: 5.35.5 + svelte: 5.38.10 - svelte-parse-markup@0.1.5(svelte@5.35.5): + svelte-parse-markup@0.1.5(svelte@5.38.10): dependencies: - svelte: 5.35.5 + svelte: 5.38.10 - svelte-persisted-store@0.12.0(svelte@5.35.5): + svelte-persisted-store@0.12.0(svelte@5.38.10): dependencies: - svelte: 5.35.5 + svelte: 5.38.10 - svelte-toolbelt@0.9.3(svelte@5.35.5): + svelte-toolbelt@0.9.3(svelte@5.38.10): dependencies: clsx: 2.1.1 - runed: 0.29.2(svelte@5.35.5) + runed: 0.29.2(svelte@5.38.10) style-to-object: 1.0.9 - svelte: 5.35.5 + svelte: 5.38.10 - svelte@5.35.5: + svelte@5.38.10: dependencies: - '@ampproject/remapping': 2.3.0 + '@jridgewell/remapping': 2.3.5 '@jridgewell/sourcemap-codec': 1.5.5 '@sveltejs/acorn-typescript': 1.0.5(acorn@8.15.0) '@types/estree': 1.0.8 @@ -24031,7 +23079,7 @@ snapshots: esrap: 2.1.0 is-reference: 3.0.3 locate-character: 3.0.0 - magic-string: 0.30.17 + magic-string: 0.30.19 zimmerframe: 1.1.2 svg-parser@2.0.4: {} @@ -24050,22 +23098,6 @@ snapshots: dependencies: '@scarf/scarf': 1.4.0 - swagger2openapi@7.0.8(encoding@0.1.13): - dependencies: - call-me-maybe: 1.0.2 - node-fetch: 2.7.0(encoding@0.1.13) - node-fetch-h2: 2.3.0 - node-readfiles: 0.2.0 - oas-kit-common: 1.0.8 - oas-resolver: 2.5.6 - oas-schema-walker: 1.1.5 - oas-validator: 5.0.8 - reftools: 1.1.9 - yaml: 1.10.2 - yargs: 17.7.2 - transitivePeerDependencies: - - encoding - symbol-observable@4.0.0: {} symbol-tree@3.2.4: @@ -24081,9 +23113,9 @@ snapshots: tailwind-merge@3.3.1: {} - tailwind-variants@3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.12): + tailwind-variants@3.1.1(tailwind-merge@3.3.1)(tailwindcss@4.1.13): dependencies: - tailwindcss: 4.1.12 + tailwindcss: 4.1.13 optionalDependencies: tailwind-merge: 3.3.1 @@ -24119,7 +23151,7 @@ snapshots: picocolors: 1.1.1 postcss: 8.5.6 postcss-import: 15.1.0(postcss@8.5.6) - postcss-js: 4.0.1(postcss@8.5.6) + postcss-js: 4.1.0(postcss@8.5.6) postcss-load-config: 4.0.2(postcss@8.5.6) postcss-nested: 6.2.0(postcss@8.5.6) postcss-selector-parser: 6.1.2 @@ -24128,7 +23160,7 @@ snapshots: transitivePeerDependencies: - ts-node - tailwindcss@4.1.12: {} + tailwindcss@4.1.13: {} tapable@2.2.2: {} @@ -24181,16 +23213,16 @@ snapshots: mkdirp: 3.0.1 yallist: 5.0.0 - terser-webpack-plugin@5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))): + terser-webpack-plugin@5.3.14(@swc/core@1.13.5(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.5(@swc/helpers@0.5.17))): dependencies: '@jridgewell/trace-mapping': 0.3.30 jest-worker: 27.5.1 schema-utils: 4.3.2 serialize-javascript: 6.0.2 terser: 5.43.1 - webpack: 5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17)) + webpack: 5.100.2(@swc/core@1.13.5(@swc/helpers@0.5.17)) optionalDependencies: - '@swc/core': 1.13.3(@swc/helpers@0.5.17) + '@swc/core': 1.13.5(@swc/helpers@0.5.17) terser-webpack-plugin@5.3.14(webpack@5.100.2): dependencies: @@ -24221,7 +23253,7 @@ snapshots: archiver: 7.0.1 async-lock: 1.4.1 byline: 5.0.0 - debug: 4.4.1 + debug: 4.4.3 docker-compose: 1.2.0 dockerode: 4.0.7 get-port: 7.1.0 @@ -24230,7 +23262,7 @@ snapshots: ssh-remote-port-forward: 1.0.4 tar-fs: 3.1.0 tmp: 0.2.5 - undici: 7.14.0 + undici: 7.16.0 transitivePeerDependencies: - bare-buffer - supports-color @@ -24249,10 +23281,10 @@ snapshots: dependencies: any-promise: 1.3.0 - three@0.175.0: {} - three@0.179.1: {} + three@0.180.0: {} + through@2.3.8: {} thumbhash@0.1.1: {} @@ -24300,10 +23332,6 @@ snapshots: tldts-core: 6.1.86 optional: true - tmp@0.0.33: - dependencies: - os-tmpdir: 1.0.2 - tmp@0.2.5: {} to-regex-range@5.0.1: @@ -24420,13 +23448,13 @@ snapshots: typedarray@0.0.6: {} - typescript-eslint@8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2): + typescript-eslint@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2): dependencies: - '@typescript-eslint/eslint-plugin': 8.39.1(@typescript-eslint/parser@8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2) - '@typescript-eslint/parser': 8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2) - '@typescript-eslint/typescript-estree': 8.39.1(typescript@5.9.2) - '@typescript-eslint/utils': 8.39.1(eslint@9.33.0(jiti@2.5.1))(typescript@5.9.2) - eslint: 9.33.0(jiti@2.5.1) + '@typescript-eslint/eslint-plugin': 8.43.0(@typescript-eslint/parser@8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2))(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/parser': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + '@typescript-eslint/typescript-estree': 8.43.0(typescript@5.9.2) + '@typescript-eslint/utils': 8.43.0(eslint@9.35.0(jiti@2.5.1))(typescript@5.9.2) + eslint: 9.35.0(jiti@2.5.1) typescript: 5.9.2 transitivePeerDependencies: - supports-color @@ -24437,15 +23465,12 @@ snapshots: ua-is-frozen@0.1.2: {} - ua-parser-js@2.0.4(encoding@0.1.13): + ua-parser-js@2.0.5: dependencies: - '@types/node-fetch': 2.6.12 detect-europe-js: 0.1.2 is-standalone-pwa: 0.1.1 - node-fetch: 2.7.0(encoding@0.1.13) ua-is-frozen: 0.1.2 - transitivePeerDependencies: - - encoding + undici: 7.16.0 uglify-js@3.19.3: optional: true @@ -24462,10 +23487,10 @@ snapshots: undici-types@6.21.0: {} - undici-types@7.10.0: + undici-types@7.12.0: optional: true - undici@7.14.0: {} + undici@7.16.0: {} unicode-canonical-property-names-ecmascript@2.0.1: {} @@ -24567,17 +23592,18 @@ snapshots: unpipe@1.0.0: {} - unplugin-swc@1.5.5(@swc/core@1.13.3(@swc/helpers@0.5.17))(rollup@4.50.1): + unplugin-swc@1.5.7(@swc/core@1.13.5(@swc/helpers@0.5.17))(rollup@4.50.1): dependencies: - '@rollup/pluginutils': 5.2.0(rollup@4.50.1) - '@swc/core': 1.13.3(@swc/helpers@0.5.17) + '@rollup/pluginutils': 5.3.0(rollup@4.50.1) + '@swc/core': 1.13.5(@swc/helpers@0.5.17) load-tsconfig: 0.2.5 - unplugin: 2.3.5 + unplugin: 2.3.10 transitivePeerDependencies: - rollup - unplugin@2.3.5: + unplugin@2.3.10: dependencies: + '@jridgewell/remapping': 2.3.5 acorn: 8.15.0 picomatch: 4.0.3 webpack-virtual-modules: 0.6.2 @@ -24591,7 +23617,7 @@ snapshots: update-notifier@6.0.2: dependencies: boxen: 7.1.1 - chalk: 5.6.0 + chalk: 5.6.2 configstore: 6.0.0 has-yarn: 3.0.0 import-lazy: 4.0.0 @@ -24633,10 +23659,6 @@ snapshots: util-deprecate@1.0.2: {} - util@0.10.4: - dependencies: - inherits: 2.0.3 - utila@0.4.0: {} utility-types@3.11.0: {} @@ -24659,21 +23681,6 @@ snapshots: uuid@9.0.1: {} - validate.io-array@1.0.6: {} - - validate.io-function@1.0.2: {} - - validate.io-integer-array@1.0.0: - dependencies: - validate.io-array: 1.0.6 - validate.io-integer: 1.0.5 - - validate.io-integer@1.0.5: - dependencies: - validate.io-number: 1.0.3 - - validate.io-number@1.0.3: {} - validator@13.15.15: {} value-equal@1.0.1: {} @@ -24711,20 +23718,20 @@ snapshots: vite-imagetools@8.0.0(rollup@4.50.1): dependencies: - '@rollup/pluginutils': 5.2.0(rollup@4.50.1) + '@rollup/pluginutils': 5.3.0(rollup@4.50.1) imagetools-core: 8.0.0 sharp: 0.34.3 transitivePeerDependencies: - rollup - supports-color - vite-node@3.2.4(@types/node@22.18.4)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1): + vite-node@3.2.4(@types/node@22.18.5)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1): dependencies: cac: 6.7.14 - debug: 4.4.1 + debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.5(@types/node@22.18.4)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vite: 7.1.5(@types/node@22.18.5)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - jiti @@ -24739,13 +23746,13 @@ snapshots: - tsx - yaml - vite-node@3.2.4(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1): + vite-node@3.2.4(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1): dependencies: cac: 6.7.14 - debug: 4.4.1 + debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vite: 7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) transitivePeerDependencies: - '@types/node' - jiti @@ -24760,18 +23767,18 @@ snapshots: - tsx - yaml - vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@7.1.5(@types/node@22.18.4)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)): + vite-tsconfig-paths@5.1.4(typescript@5.9.2)(vite@7.1.5(@types/node@22.18.5)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)): dependencies: - debug: 4.4.1 + debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@5.9.2) optionalDependencies: - vite: 7.1.5(@types/node@22.18.4)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vite: 7.1.5(@types/node@22.18.5)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) transitivePeerDependencies: - supports-color - typescript - vite@7.1.5(@types/node@22.18.4)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1): + vite@7.1.5(@types/node@22.18.5)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1): dependencies: esbuild: 0.25.9 fdir: 6.5.0(picomatch@4.0.3) @@ -24780,14 +23787,14 @@ snapshots: rollup: 4.50.1 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 22.18.4 + '@types/node': 22.18.5 fsevents: 2.3.3 jiti: 2.5.1 lightningcss: 1.30.1 terser: 5.43.1 yaml: 2.8.1 - vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1): + vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1): dependencies: esbuild: 0.25.9 fdir: 6.5.0(picomatch@4.0.3) @@ -24796,35 +23803,35 @@ snapshots: rollup: 4.50.1 tinyglobby: 0.2.15 optionalDependencies: - '@types/node': 24.3.0 + '@types/node': 24.5.1 fsevents: 2.3.3 jiti: 2.5.1 lightningcss: 1.30.1 terser: 5.43.1 yaml: 2.8.1 - vitefu@1.1.1(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)): + vitefu@1.1.1(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)): optionalDependencies: - vite: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vite: 7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) - vitest-fetch-mock@0.4.5(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)): + vitest-fetch-mock@0.4.5(vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.5)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)): dependencies: - vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vitest: 3.2.4(@types/debug@4.1.12)(@types/node@22.18.5)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) - vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.5)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2(encoding@0.1.13)))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.5(@types/node@22.18.4)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + '@vitest/mocker': 3.2.4(vite@7.1.5(@types/node@22.18.5)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 chai: 5.2.0 - debug: 4.4.1 + debug: 4.4.3 expect-type: 1.2.1 - magic-string: 0.30.17 + magic-string: 0.30.19 pathe: 2.0.3 picomatch: 4.0.3 std-env: 3.9.0 @@ -24833,12 +23840,12 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.5(@types/node@22.18.4)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@22.18.4)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vite: 7.1.5(@types/node@22.18.5)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vite-node: 3.2.4(@types/node@22.18.5)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 22.18.4 + '@types/node': 22.18.5 happy-dom: 18.0.1 jsdom: 26.1.0(canvas@2.11.2(encoding@0.1.13)) transitivePeerDependencies: @@ -24855,20 +23862,20 @@ snapshots: - tsx - yaml - vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.4)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@22.18.5)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.5(@types/node@22.18.4)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + '@vitest/mocker': 3.2.4(vite@7.1.5(@types/node@22.18.5)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 chai: 5.2.0 - debug: 4.4.1 + debug: 4.4.3 expect-type: 1.2.1 - magic-string: 0.30.17 + magic-string: 0.30.19 pathe: 2.0.3 picomatch: 4.0.3 std-env: 3.9.0 @@ -24877,12 +23884,12 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.5(@types/node@22.18.4)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@22.18.4)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vite: 7.1.5(@types/node@22.18.5)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vite-node: 3.2.4(@types/node@22.18.5)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 22.18.4 + '@types/node': 22.18.5 happy-dom: 18.0.1 jsdom: 26.1.0(canvas@2.11.2) transitivePeerDependencies: @@ -24899,20 +23906,20 @@ snapshots: - tsx - yaml - vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.3.0)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1): + vitest@3.2.4(@types/debug@4.1.12)(@types/node@24.5.1)(happy-dom@18.0.1)(jiti@2.5.1)(jsdom@26.1.0(canvas@2.11.2))(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1): dependencies: '@types/chai': 5.2.2 '@vitest/expect': 3.2.4 - '@vitest/mocker': 3.2.4(vite@7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) + '@vitest/mocker': 3.2.4(vite@7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1)) '@vitest/pretty-format': 3.2.4 '@vitest/runner': 3.2.4 '@vitest/snapshot': 3.2.4 '@vitest/spy': 3.2.4 '@vitest/utils': 3.2.4 chai: 5.2.0 - debug: 4.4.1 + debug: 4.4.3 expect-type: 1.2.1 - magic-string: 0.30.17 + magic-string: 0.30.19 pathe: 2.0.3 picomatch: 4.0.3 std-env: 3.9.0 @@ -24921,12 +23928,12 @@ snapshots: tinyglobby: 0.2.15 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 7.1.5(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) - vite-node: 3.2.4(@types/node@24.3.0)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vite: 7.1.5(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) + vite-node: 3.2.4(@types/node@24.5.1)(jiti@2.5.1)(lightningcss@1.30.1)(terser@5.43.1)(yaml@2.8.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/debug': 4.1.12 - '@types/node': 24.3.0 + '@types/node': 24.5.1 happy-dom: 18.0.1 jsdom: 26.1.0(canvas@2.11.2) transitivePeerDependencies: @@ -25098,7 +24105,7 @@ snapshots: - esbuild - uglify-js - webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17)): + webpack@5.100.2(@swc/core@1.13.5(@swc/helpers@0.5.17)): dependencies: '@types/eslint-scope': 3.7.7 '@types/estree': 1.0.8 @@ -25122,7 +24129,7 @@ snapshots: neo-async: 2.6.2 schema-utils: 4.3.2 tapable: 2.2.2 - terser-webpack-plugin: 5.3.14(@swc/core@1.13.3(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.3(@swc/helpers@0.5.17))) + terser-webpack-plugin: 5.3.14(@swc/core@1.13.5(@swc/helpers@0.5.17))(webpack@5.100.2(@swc/core@1.13.5(@swc/helpers@0.5.17))) watchpack: 2.4.4 webpack-sources: 3.3.3 transitivePeerDependencies: @@ -25229,9 +24236,9 @@ snapshots: wrap-ansi@8.1.0: dependencies: - ansi-styles: 6.2.1 + ansi-styles: 6.2.3 string-width: 5.1.2 - strip-ansi: 7.1.0 + strip-ansi: 7.1.2 wrappy@1.0.2: {} @@ -25318,7 +24325,7 @@ snapshots: yoctocolors-cjs@2.1.2: {} - yoctocolors@2.1.1: {} + yoctocolors@2.1.2: {} zimmerframe@1.1.2: {} diff --git a/server/Dockerfile b/server/Dockerfile index e95eca7c12..6702b338c5 100644 --- a/server/Dockerfile +++ b/server/Dockerfile @@ -1,4 +1,4 @@ -FROM ghcr.io/immich-app/base-server-dev:202509091104@sha256:4f9275330f1e49e7ce9840758ea91839052fe6ed40972d5bb97a9af857fa956a AS builder +FROM ghcr.io/immich-app/base-server-dev:202509210934@sha256:b5ce2d7eaf379d4cf15efd4bab180d8afc8a80d20b36c9800f4091aca6ae267e AS builder ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \ CI=1 \ COREPACK_HOME=/tmp @@ -33,7 +33,7 @@ RUN pnpm --filter @immich/sdk --filter @immich/cli --frozen-lockfile install && pnpm --filter @immich/sdk --filter @immich/cli build && \ pnpm --filter @immich/cli --prod --no-optional deploy /output/cli-pruned -FROM ghcr.io/immich-app/base-server-prod:202509091104@sha256:d1ccbac24c84f2f8277cf85281edfca62d85d7daed6a62b8efd3a81bcd3c5e0e +FROM ghcr.io/immich-app/base-server-prod:202509210934@sha256:0c7eacf0ba88ca52e1a267cfc62d20d07792ea2c604818c2cbd37dc7dcefdac9 WORKDIR /usr/src/app ENV NODE_ENV=production \ diff --git a/server/Dockerfile.dev b/server/Dockerfile.dev index 86624998f6..dd2e931745 100644 --- a/server/Dockerfile.dev +++ b/server/Dockerfile.dev @@ -1,5 +1,5 @@ # dev build -FROM ghcr.io/immich-app/base-server-dev:202509091104@sha256:4f9275330f1e49e7ce9840758ea91839052fe6ed40972d5bb97a9af857fa956a AS dev +FROM ghcr.io/immich-app/base-server-dev:202509210934@sha256:b5ce2d7eaf379d4cf15efd4bab180d8afc8a80d20b36c9800f4091aca6ae267e AS dev ENV COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \ CI=1 \ diff --git a/server/bin/start.sh b/server/bin/start.sh index 15390ae158..dc34e8f0bc 100755 --- a/server/bin/start.sh +++ b/server/bin/start.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash echo "Initializing Immich $IMMICH_SOURCE_REF" -lib_path="/usr/lib/$(arch)-linux-gnu/libmimalloc.so.2" +lib_path="/usr/lib/$(arch)-linux-gnu/libmimalloc.so.3" if [ -f "$lib_path" ]; then export LD_PRELOAD="$lib_path" else diff --git a/server/package.json b/server/package.json index ac3b0f3c1f..e503989eac 100644 --- a/server/package.json +++ b/server/package.json @@ -1,6 +1,6 @@ { "name": "immich", - "version": "1.142.1", + "version": "1.144.1", "description": "", "author": "", "private": true, @@ -44,14 +44,14 @@ "@nestjs/websockets": "^11.0.4", "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-async-hooks": "^2.0.0", - "@opentelemetry/exporter-prometheus": "^0.203.0", - "@opentelemetry/instrumentation-http": "^0.203.0", - "@opentelemetry/instrumentation-ioredis": "^0.51.0", - "@opentelemetry/instrumentation-nestjs-core": "^0.49.0", - "@opentelemetry/instrumentation-pg": "^0.56.0", + "@opentelemetry/exporter-prometheus": "^0.205.0", + "@opentelemetry/instrumentation-http": "^0.205.0", + "@opentelemetry/instrumentation-ioredis": "^0.53.0", + "@opentelemetry/instrumentation-nestjs-core": "^0.51.0", + "@opentelemetry/instrumentation-pg": "^0.58.0", "@opentelemetry/resources": "^2.0.1", "@opentelemetry/sdk-metrics": "^2.0.1", - "@opentelemetry/sdk-node": "^0.203.0", + "@opentelemetry/sdk-node": "^0.205.0", "@opentelemetry/semantic-conventions": "^1.34.0", "@react-email/components": "^0.5.0", "@react-email/render": "^1.1.2", diff --git a/server/src/bin/sync-sql.ts b/server/src/bin/sync-sql.ts index 6d3cb42fae..b632332069 100644 --- a/server/src/bin/sync-sql.ts +++ b/server/src/bin/sync-sql.ts @@ -15,6 +15,7 @@ import { repositories } from 'src/repositories'; import { AccessRepository } from 'src/repositories/access.repository'; import { ConfigRepository } from 'src/repositories/config.repository'; import { LoggingRepository } from 'src/repositories/logging.repository'; +import { MachineLearningRepository } from 'src/repositories/machine-learning.repository'; import { SyncRepository } from 'src/repositories/sync.repository'; import { AuthService } from 'src/services/auth.service'; import { getKyselyConfig } from 'src/utils/database'; @@ -57,7 +58,7 @@ class SqlGenerator { try { await this.setup(); for (const Repository of repositories) { - if (Repository === LoggingRepository) { + if (Repository === LoggingRepository || Repository === MachineLearningRepository) { continue; } await this.process(Repository); diff --git a/server/src/config.ts b/server/src/config.ts index 0d1e293be8..66c03450fa 100644 --- a/server/src/config.ts +++ b/server/src/config.ts @@ -54,6 +54,11 @@ export interface SystemConfig { machineLearning: { enabled: boolean; urls: string[]; + availabilityChecks: { + enabled: boolean; + timeout: number; + interval: number; + }; clip: { enabled: boolean; modelName: string; @@ -176,6 +181,8 @@ export interface SystemConfig { }; } +export type MachineLearningConfig = SystemConfig['machineLearning']; + export const defaults = Object.freeze({ backup: { database: { @@ -227,6 +234,11 @@ export const defaults = Object.freeze({ machineLearning: { enabled: process.env.IMMICH_MACHINE_LEARNING_ENABLED !== 'false', urls: [process.env.IMMICH_MACHINE_LEARNING_URL || 'http://immich-machine-learning:3003'], + availabilityChecks: { + enabled: true, + timeout: Number(process.env.IMMICH_MACHINE_LEARNING_PING_TIMEOUT) || 2000, + interval: 30_000, + }, clip: { enabled: true, modelName: 'ViT-B-32__openai', diff --git a/server/src/constants.ts b/server/src/constants.ts index b47640c4ae..1bae521a9f 100644 --- a/server/src/constants.ts +++ b/server/src/constants.ts @@ -51,11 +51,6 @@ export const serverVersion = new SemVer(version); export const AUDIT_LOG_MAX_DURATION = Duration.fromObject({ days: 100 }); export const ONE_HOUR = Duration.fromObject({ hours: 1 }); -export const MACHINE_LEARNING_PING_TIMEOUT = Number(process.env.MACHINE_LEARNING_PING_TIMEOUT || 2000); -export const MACHINE_LEARNING_AVAILABILITY_BACKOFF_TIME = Number( - process.env.MACHINE_LEARNING_AVAILABILITY_BACKOFF_TIME || 30_000, -); - export const citiesFile = 'cities500.txt'; export const reverseGeocodeMaxDistance = 25_000; diff --git a/server/src/dtos/search.dto.ts b/server/src/dtos/search.dto.ts index 65914ebf99..e967d906fe 100644 --- a/server/src/dtos/search.dto.ts +++ b/server/src/dtos/search.dto.ts @@ -6,7 +6,7 @@ import { PropertyLifecycle } from 'src/decorators'; import { AlbumResponseDto } from 'src/dtos/album.dto'; import { AssetResponseDto } from 'src/dtos/asset-response.dto'; import { AssetOrder, AssetType, AssetVisibility } from 'src/enum'; -import { Optional, ValidateBoolean, ValidateDate, ValidateEnum, ValidateUUID } from 'src/validation'; +import { Optional, ValidateBoolean, ValidateDate, ValidateEnum, ValidateString, ValidateUUID } from 'src/validation'; class BaseSearchDto { @ValidateUUID({ optional: true, nullable: true }) @@ -147,9 +147,7 @@ export class MetadataSearchDto extends RandomSearchDto { @Optional() deviceAssetId?: string; - @IsString() - @IsNotEmpty() - @Optional() + @ValidateString({ optional: true, trim: true }) description?: string; @IsString() @@ -157,9 +155,7 @@ export class MetadataSearchDto extends RandomSearchDto { @Optional() checksum?: string; - @IsString() - @IsNotEmpty() - @Optional() + @ValidateString({ optional: true, trim: true }) originalFileName?: string; @IsString() @@ -193,16 +189,12 @@ export class MetadataSearchDto extends RandomSearchDto { } export class StatisticsSearchDto extends BaseSearchDto { - @IsString() - @IsNotEmpty() - @Optional() + @ValidateString({ optional: true, trim: true }) description?: string; } export class SmartSearchDto extends BaseSearchWithResultsDto { - @IsString() - @IsNotEmpty() - @Optional() + @ValidateString({ optional: true, trim: true }) query?: string; @ValidateUUID({ optional: true }) diff --git a/server/src/dtos/system-config.dto.ts b/server/src/dtos/system-config.dto.ts index 8a58995de7..1facc6c331 100644 --- a/server/src/dtos/system-config.dto.ts +++ b/server/src/dtos/system-config.dto.ts @@ -1,5 +1,5 @@ import { ApiProperty } from '@nestjs/swagger'; -import { Exclude, Transform, Type } from 'class-transformer'; +import { Type } from 'class-transformer'; import { ArrayMinSize, IsInt, @@ -15,7 +15,6 @@ import { ValidateNested, } from 'class-validator'; import { SystemConfig } from 'src/config'; -import { PropertyLifecycle } from 'src/decorators'; import { CLIPConfig, DuplicateDetectionConfig, FacialRecognitionConfig } from 'src/dtos/model-config.dto'; import { AudioCodec, @@ -257,21 +256,32 @@ class SystemConfigLoggingDto { level!: LogLevel; } +class MachineLearningAvailabilityChecksDto { + @ValidateBoolean() + enabled!: boolean; + + @IsInt() + timeout!: number; + + @IsInt() + interval!: number; +} + class SystemConfigMachineLearningDto { @ValidateBoolean() enabled!: boolean; - @PropertyLifecycle({ deprecatedAt: 'v1.122.0' }) - @Exclude() - url?: string; - @IsUrl({ require_tld: false, allow_underscores: true }, { each: true }) @ArrayMinSize(1) - @Transform(({ obj, value }) => (obj.url ? [obj.url] : value)) @ValidateIf((dto) => dto.enabled) @ApiProperty({ type: 'array', items: { type: 'string', format: 'uri' }, minItems: 1 }) urls!: string[]; + @Type(() => MachineLearningAvailabilityChecksDto) + @ValidateNested() + @IsObject() + availabilityChecks!: MachineLearningAvailabilityChecksDto; + @Type(() => CLIPConfig) @ValidateNested() @IsObject() diff --git a/server/src/repositories/logging.repository.ts b/server/src/repositories/logging.repository.ts index 939ecb718f..576ee6c810 100644 --- a/server/src/repositories/logging.repository.ts +++ b/server/src/repositories/logging.repository.ts @@ -142,6 +142,10 @@ export class LoggingRepository { this.handleMessage(LogLevel.Fatal, message, details); } + deprecate(message: string) { + this.warn(`[Deprecated] ${message}`); + } + private handleFunction(level: LogLevel, message: LogFunction, details: LogDetails[]) { if (this.logger.isLevelEnabled(level)) { this.handleMessage(level, message(), details); diff --git a/server/src/repositories/machine-learning.repository.ts b/server/src/repositories/machine-learning.repository.ts index f880ed1298..d148dc782b 100644 --- a/server/src/repositories/machine-learning.repository.ts +++ b/server/src/repositories/machine-learning.repository.ts @@ -1,6 +1,7 @@ import { Injectable } from '@nestjs/common'; +import { Duration } from 'luxon'; import { readFile } from 'node:fs/promises'; -import { MACHINE_LEARNING_AVAILABILITY_BACKOFF_TIME, MACHINE_LEARNING_PING_TIMEOUT } from 'src/constants'; +import { MachineLearningConfig } from 'src/config'; import { CLIPConfig } from 'src/dtos/model-config.dto'; import { LoggingRepository } from 'src/repositories/logging.repository'; @@ -57,82 +58,100 @@ export type TextEncodingOptions = ModelOptions & { language?: string }; @Injectable() export class MachineLearningRepository { - // Note that deleted URL's are not removed from this map (ie: they're leaked) - // Cleaning them up is low priority since there should be very few over a - // typical server uptime cycle - private urlAvailability: { - [url: string]: - | { - active: boolean; - lastChecked: number; - } - | undefined; - }; + private healthyMap: Record = {}; + private interval?: ReturnType; + private _config?: MachineLearningConfig; + + private get config(): MachineLearningConfig { + if (!this._config) { + throw new Error('Machine learning repository not been setup'); + } + + return this._config; + } constructor(private logger: LoggingRepository) { this.logger.setContext(MachineLearningRepository.name); - this.urlAvailability = {}; } - private setUrlAvailability(url: string, active: boolean) { - const current = this.urlAvailability[url]; - if (current?.active !== active) { - this.logger.verbose(`Setting ${url} ML server to ${active ? 'active' : 'inactive'}.`); + setup(config: MachineLearningConfig) { + this._config = config; + this.teardown(); + + // delete old servers + for (const url of Object.keys(this.healthyMap)) { + if (!config.urls.includes(url)) { + delete this.healthyMap[url]; + } } - this.urlAvailability[url] = { - active, - lastChecked: Date.now(), - }; + + if (!config.availabilityChecks.enabled) { + return; + } + + this.tick(); + this.interval = setInterval( + () => this.tick(), + Duration.fromObject({ milliseconds: config.availabilityChecks.interval }).as('milliseconds'), + ); } - private async checkAvailability(url: string) { - let active = false; + teardown() { + if (this.interval) { + clearInterval(this.interval); + } + } + + private tick() { + for (const url of this.config.urls) { + void this.check(url); + } + } + + private async check(url: string) { + let healthy = false; try { const response = await fetch(new URL('/ping', url), { - signal: AbortSignal.timeout(MACHINE_LEARNING_PING_TIMEOUT), + signal: AbortSignal.timeout(this.config.availabilityChecks.timeout), }); - active = response.ok; + if (response.ok) { + healthy = true; + } } catch { // nothing to do here } - this.setUrlAvailability(url, active); - return active; + + this.setHealthy(url, healthy); } - private async shouldSkipUrl(url: string) { - const availability = this.urlAvailability[url]; - if (availability === undefined) { - // If this is a new endpoint, then check inline and skip if it fails - if (!(await this.checkAvailability(url))) { - return true; - } - return false; + private setHealthy(url: string, healthy: boolean) { + if (this.healthyMap[url] !== healthy) { + this.logger.log(`Machine learning server became ${healthy ? 'healthy' : 'unhealthy'} (${url}).`); } - if (!availability.active && Date.now() - availability.lastChecked < MACHINE_LEARNING_AVAILABILITY_BACKOFF_TIME) { - // If this is an old inactive endpoint that hasn't been checked in a - // while then check but don't wait for the result, just skip it - // This avoids delays on every search whilst allowing higher priority - // ML servers to recover over time. - void this.checkAvailability(url); + + this.healthyMap[url] = healthy; + } + + private isHealthy(url: string) { + if (!this.config.availabilityChecks.enabled) { return true; } - return false; + + return this.healthyMap[url]; } - private async predict(urls: string[], payload: ModelPayload, config: MachineLearningRequest): Promise { + private async predict(payload: ModelPayload, config: MachineLearningRequest): Promise { const formData = await this.getFormData(payload, config); - let urlCounter = 0; - for (const url of urls) { - urlCounter++; - const isLast = urlCounter >= urls.length; - if (!isLast && (await this.shouldSkipUrl(url))) { - continue; - } + for (const url of [ + // try healthy servers first + ...this.config.urls.filter((url) => this.isHealthy(url)), + ...this.config.urls.filter((url) => !this.isHealthy(url)), + ]) { try { const response = await fetch(new URL('/predict', url), { method: 'POST', body: formData }); if (response.ok) { - this.setUrlAvailability(url, true); + this.setHealthy(url, true); return response.json(); } @@ -144,20 +163,21 @@ export class MachineLearningRepository { `Machine learning request to "${url}" failed: ${error instanceof Error ? error.message : error}`, ); } - this.setUrlAvailability(url, false); + + this.setHealthy(url, false); } throw new Error(`Machine learning request '${JSON.stringify(config)}' failed for all URLs`); } - async detectFaces(urls: string[], imagePath: string, { modelName, minScore }: FaceDetectionOptions) { + async detectFaces(imagePath: string, { modelName, minScore }: FaceDetectionOptions) { const request = { [ModelTask.FACIAL_RECOGNITION]: { [ModelType.DETECTION]: { modelName, options: { minScore } }, [ModelType.RECOGNITION]: { modelName }, }, }; - const response = await this.predict(urls, { imagePath }, request); + const response = await this.predict({ imagePath }, request); return { imageHeight: response.imageHeight, imageWidth: response.imageWidth, @@ -165,15 +185,15 @@ export class MachineLearningRepository { }; } - async encodeImage(urls: string[], imagePath: string, { modelName }: CLIPConfig) { + async encodeImage(imagePath: string, { modelName }: CLIPConfig) { const request = { [ModelTask.SEARCH]: { [ModelType.VISUAL]: { modelName } } }; - const response = await this.predict(urls, { imagePath }, request); + const response = await this.predict({ imagePath }, request); return response[ModelTask.SEARCH]; } - async encodeText(urls: string[], text: string, { language, modelName }: TextEncodingOptions) { + async encodeText(text: string, { language, modelName }: TextEncodingOptions) { const request = { [ModelTask.SEARCH]: { [ModelType.TEXTUAL]: { modelName, options: { language } } } }; - const response = await this.predict(urls, { text }, request); + const response = await this.predict({ text }, request); return response[ModelTask.SEARCH]; } diff --git a/server/src/services/person.service.spec.ts b/server/src/services/person.service.spec.ts index 13c3128317..41c44ea476 100644 --- a/server/src/services/person.service.spec.ts +++ b/server/src/services/person.service.spec.ts @@ -729,7 +729,6 @@ describe(PersonService.name, () => { mocks.assetJob.getForDetectFacesJob.mockResolvedValue({ ...assetStub.image, files: [assetStub.image.files[1]] }); await sut.handleDetectFaces({ id: assetStub.image.id }); expect(mocks.machineLearning.detectFaces).toHaveBeenCalledWith( - ['http://immich-machine-learning:3003'], '/uploads/user-id/thumbs/path.jpg', expect.objectContaining({ minScore: 0.7, modelName: 'buffalo_l' }), ); diff --git a/server/src/services/person.service.ts b/server/src/services/person.service.ts index 344b69efde..6fa9b3fdd2 100644 --- a/server/src/services/person.service.ts +++ b/server/src/services/person.service.ts @@ -316,7 +316,6 @@ export class PersonService extends BaseService { } const { imageHeight, imageWidth, faces } = await this.machineLearningRepository.detectFaces( - machineLearning.urls, previewFile.path, machineLearning.facialRecognition, ); diff --git a/server/src/services/search.service.spec.ts b/server/src/services/search.service.spec.ts index d87ccbde1d..b6e09add19 100644 --- a/server/src/services/search.service.spec.ts +++ b/server/src/services/search.service.spec.ts @@ -211,7 +211,6 @@ describe(SearchService.name, () => { await sut.searchSmart(authStub.user1, { query: 'test' }); expect(mocks.machineLearning.encodeText).toHaveBeenCalledWith( - [expect.any(String)], 'test', expect.objectContaining({ modelName: expect.any(String) }), ); @@ -225,7 +224,6 @@ describe(SearchService.name, () => { await sut.searchSmart(authStub.user1, { query: 'test', page: 2, size: 50 }); expect(mocks.machineLearning.encodeText).toHaveBeenCalledWith( - [expect.any(String)], 'test', expect.objectContaining({ modelName: expect.any(String) }), ); @@ -243,7 +241,6 @@ describe(SearchService.name, () => { await sut.searchSmart(authStub.user1, { query: 'test' }); expect(mocks.machineLearning.encodeText).toHaveBeenCalledWith( - [expect.any(String)], 'test', expect.objectContaining({ modelName: 'ViT-B-16-SigLIP__webli' }), ); @@ -253,7 +250,6 @@ describe(SearchService.name, () => { await sut.searchSmart(authStub.user1, { query: 'test', language: 'de' }); expect(mocks.machineLearning.encodeText).toHaveBeenCalledWith( - [expect.any(String)], 'test', expect.objectContaining({ language: 'de' }), ); diff --git a/server/src/services/search.service.ts b/server/src/services/search.service.ts index 51a2c94338..fea1670e27 100644 --- a/server/src/services/search.service.ts +++ b/server/src/services/search.service.ts @@ -118,7 +118,7 @@ export class SearchService extends BaseService { const key = machineLearning.clip.modelName + dto.query + dto.language; embedding = this.embeddingCache.get(key); if (!embedding) { - embedding = await this.machineLearningRepository.encodeText(machineLearning.urls, dto.query, { + embedding = await this.machineLearningRepository.encodeText(dto.query, { modelName: machineLearning.clip.modelName, language: dto.language, }); diff --git a/server/src/services/smart-info.service.spec.ts b/server/src/services/smart-info.service.spec.ts index edd9f4663a..b3af5cd15f 100644 --- a/server/src/services/smart-info.service.spec.ts +++ b/server/src/services/smart-info.service.spec.ts @@ -205,7 +205,6 @@ describe(SmartInfoService.name, () => { expect(await sut.handleEncodeClip({ id: assetStub.image.id })).toEqual(JobStatus.Success); expect(mocks.machineLearning.encodeImage).toHaveBeenCalledWith( - ['http://immich-machine-learning:3003'], '/uploads/user-id/thumbs/path.jpg', expect.objectContaining({ modelName: 'ViT-B-32__openai' }), ); @@ -242,7 +241,6 @@ describe(SmartInfoService.name, () => { expect(mocks.database.wait).toHaveBeenCalledWith(512); expect(mocks.machineLearning.encodeImage).toHaveBeenCalledWith( - ['http://immich-machine-learning:3003'], '/uploads/user-id/thumbs/path.jpg', expect.objectContaining({ modelName: 'ViT-B-32__openai' }), ); diff --git a/server/src/services/smart-info.service.ts b/server/src/services/smart-info.service.ts index 3b8e2d1fc3..eff16fea45 100644 --- a/server/src/services/smart-info.service.ts +++ b/server/src/services/smart-info.service.ts @@ -108,11 +108,7 @@ export class SmartInfoService extends BaseService { return JobStatus.Skipped; } - const embedding = await this.machineLearningRepository.encodeImage( - machineLearning.urls, - asset.files[0].path, - machineLearning.clip, - ); + const embedding = await this.machineLearningRepository.encodeImage(asset.files[0].path, machineLearning.clip); if (this.databaseRepository.isBusy(DatabaseLock.CLIPDimSize)) { this.logger.verbose(`Waiting for CLIP dimension size to be updated`); diff --git a/server/src/services/system-config.service.spec.ts b/server/src/services/system-config.service.spec.ts index 486945546f..5a9c7f4df3 100644 --- a/server/src/services/system-config.service.spec.ts +++ b/server/src/services/system-config.service.spec.ts @@ -82,6 +82,11 @@ const updatedConfig = Object.freeze({ machineLearning: { enabled: true, urls: ['http://immich-machine-learning:3003'], + availabilityChecks: { + enabled: true, + interval: 30_000, + timeout: 2000, + }, clip: { enabled: true, modelName: 'ViT-B-32__openai', diff --git a/server/src/services/system-config.service.ts b/server/src/services/system-config.service.ts index d046b0317a..ea95b4df24 100644 --- a/server/src/services/system-config.service.ts +++ b/server/src/services/system-config.service.ts @@ -16,6 +16,20 @@ export class SystemConfigService extends BaseService { async onBootstrap() { const config = await this.getConfig({ withCache: false }); await this.eventRepository.emit('ConfigInit', { newConfig: config }); + + if ( + process.env.IMMICH_MACHINE_LEARNING_PING_TIMEOUT || + process.env.IMMICH_MACHINE_LEARNING_AVAILABILITY_BACKOFF_TIME + ) { + this.logger.deprecate( + 'IMMICH_MACHINE_LEARNING_PING_TIMEOUT and MACHINE_LEARNING_AVAILABILITY_BACKOFF_TIME have been moved to system config(`machineLearning.availabilityChecks`) and will be removed in a future release.', + ); + } + } + + @OnEvent({ name: 'AppShutdown' }) + onShutdown() { + this.machineLearningRepository.teardown(); } async getSystemConfig(): Promise { @@ -28,12 +42,14 @@ export class SystemConfigService extends BaseService { } @OnEvent({ name: 'ConfigInit', priority: -100 }) - onConfigInit({ newConfig: { logging } }: ArgOf<'ConfigInit'>) { + onConfigInit({ newConfig: { logging, machineLearning } }: ArgOf<'ConfigInit'>) { const { logLevel: envLevel } = this.configRepository.getEnv(); const configLevel = logging.enabled ? logging.level : false; const level = envLevel ?? configLevel; this.logger.setLogLevel(level); this.logger.log(`LogLevel=${level} ${envLevel ? '(set via IMMICH_LOG_LEVEL)' : '(set via system config)'}`); + + this.machineLearningRepository.setup(machineLearning); } @OnEvent({ name: 'ConfigUpdate', server: true }) diff --git a/server/src/validation.ts b/server/src/validation.ts index e583f6a44e..6d4bbfbe36 100644 --- a/server/src/validation.ts +++ b/server/src/validation.ts @@ -211,6 +211,18 @@ export const ValidateDate = (options?: DateOptions & ApiPropertyOptions) => { return applyDecorators(...decorators); }; +type StringOptions = { optional?: boolean; nullable?: boolean; trim?: boolean }; +export const ValidateString = (options?: StringOptions & ApiPropertyOptions) => { + const { optional, nullable, trim, ...apiPropertyOptions } = options || {}; + const decorators = [ApiProperty(apiPropertyOptions), IsString(), optional ? Optional({ nullable }) : IsNotEmpty()]; + + if (trim) { + decorators.push(Transform(({ value }: { value: string }) => value?.trim())); + } + + return applyDecorators(...decorators); +}; + type BooleanOptions = { optional?: boolean; nullable?: boolean }; export const ValidateBoolean = (options?: BooleanOptions & ApiPropertyOptions) => { const { optional, nullable, ...apiPropertyOptions } = options || {}; diff --git a/web/eslint.config.js b/web/eslint.config.js index 54337ea78f..d2ef7631e7 100644 --- a/web/eslint.config.js +++ b/web/eslint.config.js @@ -127,6 +127,7 @@ export default typescriptEslint.config( '@typescript-eslint/no-misused-promises': 'error', '@typescript-eslint/require-await': 'error', 'object-shorthand': ['error', 'always'], + 'svelte/no-navigation-without-resolve': 'off', }, }, { diff --git a/web/package.json b/web/package.json index 6ce2640966..4b9a301e8b 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "immich-web", - "version": "1.142.1", + "version": "1.144.1", "license": "GNU Affero General Public License version 3", "type": "module", "scripts": { @@ -55,7 +55,7 @@ "qrcode": "^1.5.4", "simple-icons": "^15.15.0", "socket.io-client": "~4.8.0", - "svelte-gestures": "^5.1.3", + "svelte-gestures": "^5.2.2", "svelte-i18n": "^4.0.1", "svelte-maplibre": "^1.2.0", "svelte-persisted-store": "^0.12.0", @@ -70,7 +70,7 @@ "@sveltejs/adapter-static": "^3.0.8", "@sveltejs/enhanced-img": "^0.8.0", "@sveltejs/kit": "^2.27.1", - "@sveltejs/vite-plugin-svelte": "6.1.2", + "@sveltejs/vite-plugin-svelte": "6.2.0", "@tailwindcss/vite": "^4.1.7", "@testing-library/jest-dom": "^6.4.2", "@testing-library/svelte": "^5.2.8", @@ -85,7 +85,7 @@ "dotenv": "^17.0.0", "eslint": "^9.18.0", "eslint-config-prettier": "^10.1.8", - "eslint-p": "^0.25.0", + "eslint-p": "^0.26.0", "eslint-plugin-compat": "^6.0.2", "eslint-plugin-svelte": "^3.9.0", "eslint-plugin-unicorn": "^60.0.0", @@ -97,7 +97,7 @@ "prettier-plugin-sort-json": "^4.1.1", "prettier-plugin-svelte": "^3.3.3", "rollup-plugin-visualizer": "^6.0.0", - "svelte": "5.35.5", + "svelte": "5.38.10", "svelte-check": "^4.1.5", "svelte-eslint-parser": "^1.2.0", "tailwindcss": "^4.1.7", diff --git a/web/src/lib/components/admin-settings/MachineLearningSettings.svelte b/web/src/lib/components/admin-settings/MachineLearningSettings.svelte index 59bd058606..bb1aa04ecd 100644 --- a/web/src/lib/components/admin-settings/MachineLearningSettings.svelte +++ b/web/src/lib/components/admin-settings/MachineLearningSettings.svelte @@ -9,7 +9,7 @@ import { featureFlags } from '$lib/stores/server-config.store'; import type { SystemConfigDto } from '@immich/sdk'; import { Button, IconButton } from '@immich/ui'; - import { mdiMinusCircle } from '@mdi/js'; + import { mdiPlus, mdiTrashCanOutline } from '@mdi/js'; import { isEqual } from 'lodash-es'; import { t } from 'svelte-i18n'; import { fade } from 'svelte/transition'; @@ -46,19 +46,6 @@
{#each config.machineLearning.urls as _, i (i)} - {#snippet removeButton()} - {#if config.machineLearning.urls.length > 1} - config.machineLearning.urls.splice(i, 1)} - icon={mdiMinusCircle} - /> - {/if} - {/snippet} - + > + {#snippet trailingSnippet()} + {#if config.machineLearning.urls.length > 1} + config.machineLearning.urls.splice(i, 1)} + icon={mdiTrashCanOutline} + color="danger" + /> + {/if} + {/snippet} + {/each}
- +
+ +
+ +
+ + +
+ + + + +
+
+ + import { resolve } from '$app/paths'; import SupportedDatetimePanel from '$lib/components/admin-settings/SupportedDatetimePanel.svelte'; import SupportedVariablesPanel from '$lib/components/admin-settings/SupportedVariablesPanel.svelte'; import SettingButtonsRow from '$lib/components/shared-components/settings/setting-buttons-row.svelte'; @@ -262,7 +263,7 @@ values={{ job: $t('admin.storage_template_migration_job') }} > {#snippet children({ message })} - + {message} {/snippet} diff --git a/web/src/lib/components/album-page/album-card-group.svelte b/web/src/lib/components/album-page/album-card-group.svelte index 726e1d6812..bfb642b82c 100644 --- a/web/src/lib/components/album-page/album-card-group.svelte +++ b/web/src/lib/components/album-page/album-card-group.svelte @@ -1,4 +1,5 @@ - ({ touchAction: 'pan-x' })} onswipedown={showControlBar} /> +{/* @ts-expect-error https://github.com/Rezi/svelte-gestures/issues/38#issuecomment-3315953573 */ null} + {#if showControls}
({})} - onswipe={onSwipe} + {...useSwipe(onSwipe)} oncanplay={(e) => handleCanPlay(e.currentTarget)} onended={onVideoEnded} onvolumechange={(e) => ($videoViewerMuted = e.currentTarget.muted)} diff --git a/web/src/lib/components/shared-components/search-bar/search-date-section.svelte b/web/src/lib/components/shared-components/search-bar/search-date-section.svelte index 62867805b6..ffb7816e8d 100644 --- a/web/src/lib/components/shared-components/search-bar/search-date-section.svelte +++ b/web/src/lib/components/shared-components/search-bar/search-date-section.svelte @@ -7,6 +7,7 @@ -
- +
+
+ - + +
+ {#if invalid} + {$t('start_date_before_end_date')} + {/if}
diff --git a/web/src/lib/components/shared-components/settings/setting-input-field.svelte b/web/src/lib/components/shared-components/settings/setting-input-field.svelte index 23b95a24a8..db70ba59d7 100644 --- a/web/src/lib/components/shared-components/settings/setting-input-field.svelte +++ b/web/src/lib/components/shared-components/settings/setting-input-field.svelte @@ -105,7 +105,7 @@ {/if} {#if inputType !== SettingInputFieldType.PASSWORD} -
+
{#if inputType === SettingInputFieldType.COLOR} { render(RecentAlbums); expect(sdkMock.getAllAlbums).toBeCalledTimes(1); + + // wtf + await tick(); await tick(); const links = screen.getAllByRole('link'); diff --git a/web/src/lib/utils/asset-utils.ts b/web/src/lib/utils/asset-utils.ts index 1e6295242a..25e045c8a1 100644 --- a/web/src/lib/utils/asset-utils.ts +++ b/web/src/lib/utils/asset-utils.ts @@ -620,12 +620,7 @@ const imgToBlob = async (imageElement: HTMLImageElement) => { throw new Error('Canvas context is null'); }; -const urlToBlob = async (imageSource: string) => { - const response = await fetch(imageSource); - return await response.blob(); -}; - -export const copyImageToClipboard = async (source: HTMLImageElement | string) => { - const blob = source instanceof HTMLImageElement ? await imgToBlob(source) : await urlToBlob(source); - await navigator.clipboard.write([new ClipboardItem({ [blob.type]: blob })]); +export const copyImageToClipboard = async (source: HTMLImageElement) => { + // do not await, so the Safari clipboard write happens in the context of the user gesture + await navigator.clipboard.write([new ClipboardItem({ ['image/png']: imgToBlob(source) })]); };